Skip to content

Commit

Permalink
Replace hand-crafted dicts for AVRMEM and AVRPART by SWIG structs
Browse files Browse the repository at this point in the history
This requires a bit of Python helpers for pretty-printing, but
otherwise simplifies many things later on.
  • Loading branch information
dl8dtl committed Mar 12, 2024
1 parent fd8704d commit f9b9593
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 54 deletions.
62 changes: 27 additions & 35 deletions src/libavrdude.i
Original file line number Diff line number Diff line change
Expand Up @@ -167,41 +167,33 @@ typedef struct avrmem AVRMEM;
// libavrdude itself, so only map things to the Python level that are
// needed there.

%typemap(out) AVRPART* {
if ($1 == NULL) {
$result = Py_None;
} else {
PyObject* dict = PyDict_New();
PyDict_SetItem(dict, PyUnicode_FromString("desc"),
PyUnicode_FromString($1->desc));
PyDict_SetItem(dict, PyUnicode_FromString("id"),
PyUnicode_FromString($1->id));
PyDict_SetItem(dict, PyUnicode_FromString("signature"),
PyBytes_FromStringAndSize((const char *)($1->signature), 3));
PyDict_SetItem(dict, PyUnicode_FromString("prog_modes"),
PyLong_FromLong($1->prog_modes));
PyDict_SetItem(dict, PyUnicode_FromString("mem"),
SWIG_NewPointerObj($1->mem, SWIGTYPE_p_avrmem, 0));
$result = dict;
}
}

%typemap(out) AVRMEM* {
if ($1 == NULL) {
$result = Py_None;
} else {
PyObject* dict = PyDict_New();
PyDict_SetItem(dict, PyUnicode_FromString("desc"),
PyUnicode_FromString($1->desc));
PyDict_SetItem(dict, PyUnicode_FromString("paged"),
PyBool_FromLong($1->paged));
PyDict_SetItem(dict, PyUnicode_FromString("size"),
PyLong_FromLong($1->size));
PyDict_SetItem(dict, PyUnicode_FromString("page_size"),
PyLong_FromLong($1->page_size));
$result = dict;
}
}
typedef struct avrpart {
const char * desc; /* long part name */
const char * id; /* short part name */
LISTID variants; /* String with variant name and chip properties */
const char * parent_id; /* Used by developer options */
const char * family_id; /* family id in the SIB (avr8x) */
int prog_modes; /* Programming interfaces, see #define PM_... */
unsigned char signature[3]; /* expected value of signature bytes */
unsigned short usbpid; /* USB DFU product ID (0 = none) */
LISTID mem; /* avr memory definitions */
LISTID mem_alias; /* memory alias definitions */
const char * config_file; /* config file where defined */
int lineno; /* config file line number */
} AVRPART;

typedef unsigned int memtype_t;
typedef struct avrmem {
const char *desc; /* memory description ("flash", "eeprom", etc) */
memtype_t type; /* internally used type, cannot be set in conf files */
bool paged; /* 16-bit page addressed, e.g., ATmega flash but not EEPROM */
int size; /* total memory size in bytes */
int page_size; /* size of memory page (if page addressed) */
int num_pages; /* number of pages (if page addressed) */
int initval; /* factory setting of fuses and lock bits */
int bitmask; /* bits used in fuses and lock bits */
unsigned char * buf; /* pointer to memory buffer */
} AVRMEM;

// Config file handling
int init_config(void);
Expand Down
71 changes: 52 additions & 19 deletions src/swigtest.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@
# then run the interactive interpreter.

# Example:
# a=search_avrpart('m328')
# print(a)
# show_avrmem(a['mem'])
# getavr("m128")

import sys
import os
Expand Down Expand Up @@ -49,26 +47,61 @@
print("Sorry, no avrdude.conf could be found.")
sys.exit(1)

def search_avrpart(name):
'''Search list of AVR parts from config for matching "desc" or "id"'''
def avrpart_to_dict(avrpart):

partlist = ad.cvar.part_list
if str(type(avrpart)).find('AVRPART') < 0:
raise Exception(f"wrong argument: {type(avrpart)}, expecting swig_avrdude.AVRPART")

part = ad.lfirst(partlist)
while part:
d = ad.ldata(part)
avrpart = ad.cast_avrpart(d)
if avrpart['desc'] == name or avrpart['id'] == name:
return avrpart
part = ad.lnext(part)
d = {}
d['desc'] = avrpart.desc
d['id'] = avrpart.id
d['family_id'] = avrpart.family_id
d['config_file'] = avrpart.config_file
d['lineno'] = avrpart.lineno
d['mem'] = avrpart.mem

return None
return d

def show_avrmem(mem):
'''List all memories defined at avrpart["mem"]'''
def avrmem_to_dict(mem):

m = ad.lfirst(mem)
if str(type(mem)).find('AVRMEM') < 0:
raise Exception(f"wrong argument: {type(mem)}, expecting swig_avrdude.AVRMEM")

d = {}
d['desc'] = mem.desc
d['size'] = mem.size
d['paged'] = mem.paged
d['page_size'] = mem.page_size
d['num_pages'] = mem.num_pages

return d

def avrpart_to_mem(avrpart):

if str(type(avrpart)).find('AVRPART') < 0:
raise Exception(f"wrong argument: {type(avrpart)}, expecting swig_avrdude.AVRPART")

res = []
m = ad.lfirst(avrpart.mem)
while m:
d = ad.ldata(m)
print(ad.cast_avrmem(d))
mm = ad.cast_avrmem(ad.ldata(m))
res.append(avrmem_to_dict(mm))
m = ad.lnext(m)

return res

def getavr(name: str):

p = ad.locate_part(ad.cvar.part_list, name)
if not p:
print(f"No part named {name} found")
return
pp = avrpart_to_dict(p)
mm = avrpart_to_mem(p)
print(f"AVR part {name} found as {pp['desc']}, or {pp['id']}")
print(f"Definition in {pp['config_file']}, line {pp['lineno']}")
print("Memory overview:")
print( "Name size paged page_size num_pages")
for m in mm:
print(f"{m['desc']:11s} {m['size']:6d} {str(m['paged']):5s} {m['page_size']:4d} {m['num_pages']:3d}")
print("")

0 comments on commit f9b9593

Please sign in to comment.