dfu: Add ChipID quirks for various XMEGA parts

This also adds an *almost* throw-away python script to import the chip-ids from
the default conf file from the avrdude project. I've imported it here in case we
have to start caring about different page sizes or application offsets.
This commit is contained in:
Richard Hughes 2017-11-06 17:59:36 +00:00
parent 8517464eac
commit 21852821c5
2 changed files with 286 additions and 0 deletions

View File

@ -0,0 +1,178 @@
#!/usr/bin/env python3
""" This parses avrdude.conf and generates quirks for fwupd """
# pylint: disable=wrong-import-position,pointless-string-statement
"""
Licensed under the GNU General Public License Version 2
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, see <http://www.gnu.org/licenses/>.
"""
import sys
from difflib import SequenceMatcher
# finds a part using the ID
def _find_part_by_id(parts, part_id):
for part in parts:
if 'id' not in part:
continue
if part['id'] == part_id:
return part
return None
# finds a memory layout for a part, climbing up the tree to the parent if reqd.
def _find_mem_layout(parts, part):
if 'memory-application' in part:
memory_flash = part['memory-application']
if memory_flash:
return memory_flash
#look at the parent
if 'parent' in part:
parent = _find_part_by_id(parts, part['parent'])
if parent:
return _find_mem_layout(parts, parent)
print('no parent ', part['parent'], 'found for', part['id'])
return None
# parses the weird syntax of avrdude.conf and makes lots of nested dictionaries
def _parse_parts(fn_source):
print("reading", fn_source)
part = None
memory_id = None
parts = []
for line in open(fn_source).readlines():
# try to clean up crazy syntax
line = line.replace('\n', '')
if line.endswith(';'):
line = line[:-1]
# ignore blank lines
line = line.rstrip()
if not line:
continue
# count how many spaces deep this is
lvl = 0
for char in line:
if char != ' ':
break
lvl = lvl + 1
# ignore comments
line = line.strip()
if line[0] == '#':
continue
# level 0 of hell
if lvl == 0:
if line.startswith('part'):
memory_id = None
part = {}
parts.append(part)
if line.startswith('part parent '):
part['parent'] = line[13:].replace('"', '')
continue
# level 4 of hell
if lvl == 4:
if line.startswith('memory'):
memory_id = 'memory-' + line[7:].replace('"', '')
part[memory_id] = {}
continue
split = line.split('=')
if len(split) != 2:
print('ignoring', line)
continue
part[split[0].strip()] = split[1].strip().replace('"', '')
continue
# level 8 of hell
if lvl == 8:
if memory_id:
split = line.split('=')
if len(split) != 2:
continue
memory = part[memory_id]
memory[split[0].strip()] = split[1].strip()
continue
return parts
def _get_longest_substring(s1, s2):
match = SequenceMatcher(None, s1, s2).find_longest_match(0, len(s1), 0, len(s2))
return s2[match.b: match.b + match.size]
# writes important data to the quirks file
def _write_quirks(parts, fn_destination):
outp = []
results = {}
for part in parts:
# ignore meta parts with deprecated names
if 'desc' not in part:
continue
if 'signature' not in part:
continue
# find the layout
mem_part = _find_mem_layout(parts, part)
if not mem_part:
print("no memory layout for", part['desc'])
continue
if not 'size' in mem_part:
print("no memory size for", part['desc'])
continue
if mem_part['size'].startswith('0x'):
size = int(mem_part['size'], 16)
else:
size = int(mem_part['size'], 10)
# output the line for the quirk
chip_id = '0x' + part['signature'].replace('0x', '').replace(' ', '')
mem_layout = '@Flash/0x0/1*%.0iKg' % int(size / 1024)
# merge duplicate quirks
if chip_id in results:
result = results[chip_id]
result['desc'] = _get_longest_substring(result['desc'], part['desc'])
else:
result = {}
result['desc'] = part['desc']
result['size'] = size
result['mem_layout'] = mem_layout
results[chip_id] = result
for chip_id in results:
result = results[chip_id]
outp.append('# ' + result['desc'] + ' size:0x%x' % result['size'] + '\n')
outp.append(chip_id + '=' + result['mem_layout'] + '\n\n')
# write file
print("writing", fn_destination)
open(fn_destination, 'w').writelines(outp)
if __name__ == '__main__':
if len(sys.argv) != 3:
print("USAGE: %s avrdude.conf tmp.quirk" % sys.argv[0])
sys.exit(1)
all_parts = _parse_parts(sys.argv[1])
_write_quirks(all_parts, sys.argv[2])

View File

@ -78,3 +78,111 @@ USB\VID_0B0E&PID_2456=0B0E0971
# AT32UC3A3 is BL @0x2000, Size: 0x40000
0x58200204=@Flash/0x2000/1*248Kg
# ATxmega16A4 size:0x4000
0x1e9441=@Flash/0x0/1*16Kg
# ATxmega16C4 size:0x4000
0x1e9544=@Flash/0x0/1*16Kg
# ATxmega16D4 size:0x4000
0x1e9442=@Flash/0x0/1*16Kg
# ATxmega32A4 size:0x8000
0x1e9541=@Flash/0x0/1*32Kg
# ATxmega32C4 size:0x8000
0x1e9443=@Flash/0x0/1*32Kg
# ATxmega32D4 size:0x8000
0x1e9542=@Flash/0x0/1*32Kg
# ATxmega64A4 size:0x10000
0x1e9646=@Flash/0x0/1*64Kg
# ATxmega64C3 size:0x10000
0x1e9649=@Flash/0x0/1*64Kg
# ATxmega64D3 size:0x10000
0x1e964a=@Flash/0x0/1*64Kg
# ATxmega64D4 size:0x10000
0x1e9647=@Flash/0x0/1*64Kg
# ATxmega64A1 size:0x10000
0x1e964e=@Flash/0x0/1*64Kg
# ATxmega64A3 size:0x10000
0x1e9642=@Flash/0x0/1*64Kg
# ATxmega64B1 size:0x10000
0x1e9652=@Flash/0x0/1*64Kg
# ATxmega64B3 size:0x10000
0x1e9651=@Flash/0x0/1*64Kg
# ATxmega128C3 size:0x20000
0x1e9752=@Flash/0x0/1*128Kg
# ATxmega128D3 size:0x20000
0x1e9748=@Flash/0x0/1*128Kg
# ATxmega128D4 size:0x20000
0x1e9747=@Flash/0x0/1*128Kg
# ATxmega128A1 size:0x20000
0x1e974c=@Flash/0x0/1*128Kg
# ATxmega128A1revD size:0x20000
0x1e9741=@Flash/0x0/1*128Kg
# ATxmega128A3 size:0x20000
0x1e9742=@Flash/0x0/1*128Kg
# ATxmega128A4 size:0x20000
0x1e9746=@Flash/0x0/1*128Kg
# ATxmega128B1 size:0x20000
0x1e974d=@Flash/0x0/1*128Kg
# ATxmega128B3 size:0x20000
0x1e974b=@Flash/0x0/1*128Kg
# ATxmega192C3 size:0x30000
0x1e9751=@Flash/0x0/1*192Kg
# ATxmega192D3 size:0x30000
0x1e9749=@Flash/0x0/1*192Kg
# ATxmega192A1 size:0x30000
0x1e974e=@Flash/0x0/1*192Kg
# ATxmega192A3 size:0x30000
0x1e9744=@Flash/0x0/1*192Kg
# ATxmega256 size:0x40000
0x1e9846=@Flash/0x0/1*256Kg
# ATxmega256D3 size:0x40000
0x1e9844=@Flash/0x0/1*256Kg
# ATxmega256A3 size:0x40000
0x1e9842=@Flash/0x0/1*256Kg
# ATxmega256A3B size:0x40000
0x1e9843=@Flash/0x0/1*256Kg
# ATxmega384C3 size:0x60000
0x1e9845=@Flash/0x0/1*384Kg
# ATxmega384D3 size:0x60000
0x1e9847=@Flash/0x0/1*384Kg
# ATxmega8E5 size:0x2000
0x1e9341=@Flash/0x0/1*8Kg
# ATxmega16E5 size:0x4000
0x1e9445=@Flash/0x0/1*16Kg
# ATxmega32E5 size:0x8000
0x1e954c=@Flash/0x0/1*32Kg