Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: GlasgowEmbedded/glasgow
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: eca2cb278478
Choose a base ref
...
head repository: GlasgowEmbedded/glasgow
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 2f48a32a8e12
Choose a head ref
  • 6 commits
  • 4 files changed
  • 1 contributor

Commits on Sep 26, 2021

  1. Copy the full SHA
    c30036a View commit details
  2. Copy the full SHA
    cbfc640 View commit details
  3. Copy the full SHA
    3472d4d View commit details
  4. Copy the full SHA
    53b65d9 View commit details
  5. Copy the full SHA
    5e0cc6e View commit details
  6. Copy the full SHA
    2f48a32 View commit details
5 changes: 4 additions & 1 deletion software/glasgow/applet/program/avr/__init__.py
Original file line number Diff line number Diff line change
@@ -231,6 +231,9 @@ async def interact(self, device, args, avr_iface):
"{:02x} {:02x} {:02x}".format(*signature),
"unknown" if device is None else device.name)

if device.erase_time is not None:
avr_iface.erase_time = device.erase_time

if args.operation not in (None, "identify") and device is None:
raise ProgramAVRError("cannot operate on unknown device")

@@ -318,7 +321,7 @@ async def interact(self, device, args, avr_iface):
for address, chunk in data:
chunk = bytes(chunk)
await avr_iface.write_program_memory_range(address, chunk, device.program_page)
written = await avr_iface.read_program_memory_range(range(address, len(chunk)))
written = await avr_iface.read_program_memory_range(range(address, address + len(chunk)))
if written != chunk:
raise ProgramAVRError("verification failed at address %#06x: %s != %s" %
(address, written.hex(), chunk.hex()))
15 changes: 15 additions & 0 deletions software/glasgow/applet/program/avr/spi/__init__.py
Original file line number Diff line number Diff line change
@@ -16,6 +16,8 @@ def __init__(self, interface, logger, addr_dut_reset):
self._logger = logger
self._level = logging.DEBUG if self._logger.name == __name__ else logging.TRACE
self._addr_dut_reset = addr_dut_reset
self._extended_addr = None
self.erase_time = None

def _log(self, message, *args):
self._logger.log(self._level, "AVR SPI: " + message, *args)
@@ -46,6 +48,10 @@ async def programming_disable(self):
await self.lower.delay_ms(20)

async def _is_busy(self):
if self.erase_time is not None:
self._log("wait for completion")
await self.lower.delay_ms(self.erase_time)
return False
self._log("poll ready/busy flag")
_, _, _, busy = await self._command(0b1111_0000, 0b0000_0000, 0, 0)
return bool(busy & 1)
@@ -104,7 +110,15 @@ async def read_calibration(self, address):
_, _, _, data = await self._command(0b0011_1000, 0b0000_0000, address, 0)
return data

async def load_extended_address_byte(self, address):
extended_addr = (address >> 17) & 0xff
if self._extended_addr != extended_addr:
self._log("load extended address %#02x", extended_addr)
await self._command(0b0100_1101, 0, extended_addr, 0)
self._extended_addr = extended_addr

async def read_program_memory(self, address):
await self.load_extended_address_byte(address)
self._log("read program memory address %#06x", address)
_, _, _, data = await self._command(
0b0010_0000 | (address & 1) << 3,
@@ -122,6 +136,7 @@ async def load_program_memory_page(self, address, data):
data)

async def write_program_memory_page(self, address):
await self.load_extended_address_byte(address)
self._log("write program memory page at %#06x", address)
await self._command(
0b0100_1100,
Original file line number Diff line number Diff line change
@@ -70,6 +70,7 @@
{"method": "transfer", "async": true, "args": [[72, 0, 62, 61]], "kwargs": {}, "result": {"__class__": "bytes", "hex": "3c48003e"}}
{"method": "transfer", "async": true, "args": [[64, 0, 63, 62]], "kwargs": {}, "result": {"__class__": "bytes", "hex": "3d40003f"}}
{"method": "transfer", "async": true, "args": [[72, 0, 63, 63]], "kwargs": {}, "result": {"__class__": "bytes", "hex": "3e48003f"}}
{"method": "transfer", "async": true, "args": [[77, 0, 0, 0]], "kwargs": {}, "result": {"__class__": "bytes", "hex": "00000000"}}
{"method": "transfer", "async": true, "args": [[76, 0, 0, 0]], "kwargs": {}, "result": {"__class__": "bytes", "hex": "3f4c0000"}}
{"method": "transfer", "async": true, "args": [[240, 0, 0, 0]], "kwargs": {}, "result": {"__class__": "bytes", "hex": "00f000ff"}}
{"method": "transfer", "async": true, "args": [[240, 0, 0, 0]], "kwargs": {}, "result": {"__class__": "bytes", "hex": "00f000ff"}}
17 changes: 13 additions & 4 deletions software/glasgow/database/microchip/avr.py
Original file line number Diff line number Diff line change
@@ -10,26 +10,30 @@
"calibration_size", "fuses_size",
"program_size", "program_page",
"eeprom_size", "eeprom_page",
"erase_time", # None indicates to use polling, otherwise give worst-case duration in ms
))

def ATtiny(name, signature, program_size, program_page, eeprom_size, fuses_size=2):
def ATtiny(name, signature, program_size, program_page, eeprom_size, fuses_size=2, erase_time=None):
return AVRDevice("ATtiny{}".format(name), signature=signature,
calibration_size=2, fuses_size=fuses_size,
program_size=program_size, program_page=program_page,
eeprom_size=eeprom_size, eeprom_page=4)
eeprom_size=eeprom_size, eeprom_page=4,
erase_time=erase_time)

def ATmega(name, signature, program_size, program_page, eeprom_size):
def ATmega(name, signature, program_size, program_page, eeprom_size, eeprom_page=4, erase_time=None):
return AVRDevice("ATmega{}".format(name), signature=signature,
calibration_size=1, fuses_size=3,
program_size=program_size, program_page=program_page,
eeprom_size=eeprom_size, eeprom_page=4)
eeprom_size=eeprom_size, eeprom_page=eeprom_page,
erase_time=erase_time)


devices = [
# ATtiny series
ATtiny("13a", (0x1e, 0x90, 0x07), program_size=1024, program_page=32, eeprom_size=64,
fuses_size=2),
ATtiny("25", (0x1e, 0x91, 0x08), program_size=1024, program_page=32, eeprom_size=128),
ATtiny("26", (0x1e, 0x91, 0x09), program_size=2048, program_page=32, eeprom_size=128, erase_time=15),
ATtiny("45", (0x1e, 0x92, 0x06), program_size=2048, program_page=64, eeprom_size=256),
ATtiny("85", (0x1e, 0x93, 0x0B), program_size=4096, program_page=64, eeprom_size=512),
# ATmega series
@@ -43,6 +47,11 @@ def ATmega(name, signature, program_size, program_page, eeprom_size):
ATmega("328P", (0x1e, 0x95, 0x0f), program_size=32768, program_page=128, eeprom_size=1024),
ATmega("16U4", (0x1e, 0x94, 0x88), program_size=16384, program_page=128, eeprom_size=512),
ATmega("32U4", (0x1e, 0x95, 0x87), program_size=32768, program_page=128, eeprom_size=1024),
ATmega("640", (0x1e, 0x96, 0x08), program_size=65536, program_page=256, eeprom_size=4096, eeprom_page=8),
ATmega("1280", (0x1e, 0x97, 0x03), program_size=131072, program_page=256, eeprom_size=4096, eeprom_page=8),
ATmega("1281", (0x1e, 0x97, 0x04), program_size=131072, program_page=256, eeprom_size=4096, eeprom_page=8),
ATmega("2560", (0x1e, 0x98, 0x01), program_size=262144, program_page=256, eeprom_size=4096, eeprom_page=8),
ATmega("2561", (0x1e, 0x98, 0x02), program_size=262144, program_page=256, eeprom_size=4096, eeprom_page=8),
]

devices_by_signature = defaultdict(lambda: None,