mirror of
https://github.com/avrdudes/avrdude.git
synced 2026-09-23 17:46:33 +03:00
Provide avr_get_config_value() and avr_set_config_value() functions
Example usage:
int ocden = 0;
if(avr_get_config_value(pgm, p, "ocden", &ocden) == 0 && ocden) // ocden == 1 means disabled
pmsg_warning("OCDEN fuse not programmed, single-byte EEPROM updates not possible\n");
This commit is contained in:
@@ -29,7 +29,6 @@
|
||||
|
||||
#include "avrdude.h"
|
||||
#include "libavrdude.h"
|
||||
#include "avrintel.h"
|
||||
|
||||
/*
|
||||
* Provides an API for cached bytewise access
|
||||
|
||||
102
src/avrpart.c
102
src/avrpart.c
@@ -493,6 +493,108 @@ AVRMEM_ALIAS *avr_find_memalias(const AVRPART *p, const AVRMEM *m_orig) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const Configitem_t *avr_locate_config(const Configitem_t *cfg, int nc, const char *name) {
|
||||
const Configitem_t *match = NULL;
|
||||
int matches = 0, n1;
|
||||
|
||||
if(!cfg || !name || !(n1 = *name))
|
||||
return NULL;
|
||||
|
||||
size_t l = strlen(name);
|
||||
for(int i = 0; i < nc; i++) {
|
||||
if(n1 == *cfg[i].name && !strncmp(cfg[i].name, name, l)) { // Partial initial match
|
||||
match = cfg+i;
|
||||
matches++;
|
||||
if(cfg[i].name[l] == 0) // Exact match; return straight away
|
||||
return match;
|
||||
}
|
||||
}
|
||||
|
||||
return matches == 1? match: NULL;
|
||||
}
|
||||
|
||||
// Return memory associated with config item and fill in pointer to Configitem_t record
|
||||
static AVRMEM *avr_locate_config_mem_c_value(const PROGRAMMER *pgm, const AVRPART *p,
|
||||
const char *cname, const Configitem_t **cp, int *valp) {
|
||||
|
||||
int id = p->mcuid;
|
||||
|
||||
if(id < 0 || id >= (int) (sizeof uP_table/sizeof *uP_table)) {
|
||||
pmsg_error("%s does not have a valid mcuid (%d)\n", p->desc, id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int nc = uP_table[id].nconfigs;
|
||||
const Configitem_t *cfg = uP_table[id].cfgtable;
|
||||
if(nc < 1 || !cfg) {
|
||||
pmsg_error("%s does not have config information in avrintel.c\n", p->desc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const Configitem_t *c = avr_locate_config(cfg, nc, cname);
|
||||
if(!c) {
|
||||
pmsg_error("%s does not have a unique config item matched by %s\n", p->desc, cname);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
AVRMEM *mem = str_starts(c->memstr, "lock")? avr_locate_lock(p): avr_locate_fuse_by_offset(p, c->memoffset);
|
||||
if(!mem)
|
||||
mem = avr_locate_mem(p, c->memstr);
|
||||
if(!mem) {
|
||||
pmsg_error("%s does not have the memory %s needed for config item %s\n", p->desc, c->memstr, cname);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(mem->size < 1 || mem->size > 4) {
|
||||
pmsg_error("cannot handle size %d of %s's memory %s for config item %s\n", mem->size, p->desc, c->memstr, cname);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int fusel = 0;
|
||||
for(int i = 0; i < mem->size; i++)
|
||||
if(led_read_byte(pgm, p, mem, i, (unsigned char *) &fusel + i) < 0) {
|
||||
pmsg_error("cannot read from %s's %s memory\n", p->desc, mem->desc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*cp = c;
|
||||
*valp = fusel;
|
||||
return mem;
|
||||
}
|
||||
|
||||
int avr_get_config_value(const PROGRAMMER *pgm, const AVRPART *p, const char *cname, int *valuep) {
|
||||
const Configitem_t *c;
|
||||
int fusel;
|
||||
|
||||
if(!avr_locate_config_mem_c_value(pgm, p, cname, &c, &fusel))
|
||||
return -1;
|
||||
|
||||
*valuep = (fusel & c->mask) >> c->lsh;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int avr_set_config_value(const PROGRAMMER *pgm, const AVRPART *p, const char *cname, int value) {
|
||||
AVRMEM *mem;
|
||||
const Configitem_t *c;
|
||||
int fusel;
|
||||
|
||||
if(!(mem=avr_locate_config_mem_c_value(pgm, p, cname, &c, &fusel)))
|
||||
return -1;
|
||||
|
||||
int newval = (fusel & ~c->mask) | ((value << c->lsh) & c->mask);
|
||||
|
||||
if(newval != fusel) {
|
||||
for(int i = 0; i < mem->size; i++)
|
||||
if(led_write_byte(pgm, p, mem, i, ((unsigned char *) &newval)[i]) < 0) {
|
||||
pmsg_error("cannot write to %s's %s memory\n", p->desc, mem->desc);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static char *print_num(const char *fmt, int n) {
|
||||
return str_sprintf(n<10? "%d": fmt, n);
|
||||
}
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
#include "avrdude.h"
|
||||
#include "libavrdude.h"
|
||||
#include "config.h"
|
||||
#include "avrintel.h"
|
||||
|
||||
#include "config_gram.h"
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <limits.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "avrintel.h"
|
||||
|
||||
typedef uint32_t pinmask_t;
|
||||
/*
|
||||
@@ -1419,6 +1420,10 @@ typedef struct {
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
const Configitem_t *avr_locate_config(const Configitem_t *cfg, int nc, const char *name);
|
||||
int avr_get_config_value(const PROGRAMMER *pgm, const AVRPART *p, const char *cname, int *valuep);
|
||||
int avr_set_config_value(const PROGRAMMER *pgm, const AVRPART *p, const char *cname, int value);
|
||||
|
||||
int setport_from_serialadapter(char **portp, const SERIALADAPTER *ser, const char *sernum);
|
||||
int setport_from_vid_pid(char **portp, int vid, int pid, const char *sernum);
|
||||
int list_available_serialports(LISTID programmers);
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
#include <errno.h>
|
||||
|
||||
#include "libavrdude.h"
|
||||
#include "avrintel.h"
|
||||
|
||||
#if defined(HAVE_LIBREADLINE)
|
||||
#include <readline/readline.h>
|
||||
|
||||
Reference in New Issue
Block a user