## Normal flashing _Work In Progress_ ## DFU ### Patching firmware Official documentation, sources & pre-compiled bootloaders for DFU modes for the `XMEGA` family, including our `ATxmega32A4U`, is available at https://www.microchip.com/en-us/application-notes/an8429. In the application note, `PC3` is the default pin for `ATxmega32A4U` used to detect if DFU must be enabled at startup. Unfortunately, ChameleonMini is not using `PC3`, but `PA6`. Instead of rebuilding it (project is for IAR compiler, not free), we can _patch_ the official binary file `atxmega32a4u_104.hex` #### Values From: `common/services/usb/class/dfu_flip/device/bootloader/xmega/conf/conf_isp.h`: | Model | ISP_PORT_DIR | ISP_PORT_PINCTRL | ISP_PORT_IN | ISP_PORT_PIN | Friendly Name | |---------------------------------|--------------|------------------|-------------|--------------|---------------| | XMEGA_A1U | PORTF_DIR | PORTF_PIN5CTRL | PORTF_IN | 0 | PF0 | | XMEGA_A3U, XMEGA_A3BU, XMEGA_C3 | PORTE_DIR | PORTE_PIN5CTRL | PORTE_IN | 5 | PE5 | | XMEGA_A4U, XMEGA_C4 | PORTC_DIR | PORTC_PIN3CTRL | PORTC_IN | 3 | PC3 | | XMEGA_B | PORTC_DIR | PORTC_PIN6CTRL | PORTC_IN | 6 | PC6 | > [!bug] > It seems that the definition for `XMEGA_A1U` is incorrect, `ISP_PORT_PIN` is set to `0` : `ISP_PORT_PINCTRL` should be `PORTF_PIN0CTRL` (not `PORTF_PIN5CTRL`). > In addition, documentation is about a non existent default pin `PF10` (Table 5-1), it should be `PF0` ( https://microchip.my.site.com/s/article/AVR1916---Default-pin-configuration-for-boot-loader--ATxmega128A1U ) We are not concerned about it here, as we're working on a `ATxmega32A4U`, using `PC3` by default to switch to DFU mode - confirmed by the `conf_isp.h` header. `ISP_PORT_*` definitions will be used in the firmware project, only in the file `common/services/isp/flip/xmega/cstartup.s90`: ``` $ grep ISP_PORT_ common/services/isp/flip/xmega/cstartup.s90 STS ISP_PORT_DIR, R15 STS ISP_PORT_PINCTRL, R16 LDS R16,ISP_PORT_IN SBRS R16,ISP_PORT_PIN // test ISP pin active STS ISP_PORT_PINCTRL, R15 ``` 5 references to `ISP_PORT_*` to find and replace, but we need to use values and not symbols with the compiled file. ##### Original With our MCU header `/lib/avr/include/avr/iox32a4u.h`, for `PC3`: ``` $ grep '#define PORTC_' /lib/avr/include/avr/iox32a4u.h [...] #define PORTC_DIR _SFR_MEM8(0x0640) #define PORTC_IN _SFR_MEM8(0x0648) #define PORTC_PIN3CTRL _SFR_MEM8(0x0653) ``` We know we have at least 5 places in the firmware related to `PC3`, with values: - `0x640` - `PORTC_DIR` / `ISP_PORT_DIR` - `0x653` - `PORTC_PIN3CTRL` (2x) / `ISP_PORT_PINCTRL` - `0x648` - `PORTC_IN` / `ISP_PORT_IN` - `0x3` - _bit position for pin \#3_ / `ISP_PORT_PIN` ##### New With our MCU header `/lib/avr/include/avr/iox32a4u.h`, for new `PA6`: ``` $ grep '#define PORTA_' /lib/avr/include/avr/iox32a4u.h [...] #define PORTA_DIR _SFR_MEM8(0x0600) #define PORTA_IN _SFR_MEM8(0x0608) #define PORTA_PIN6CTRL _SFR_MEM8(0x0616) ``` We know we have at least 5 places in the firmware to replace for `PA6`, with values: - `0x600` - `PORTA_DIR` / `ISP_PORT_DIR` - `0x616` - `PORTA_PIN6CTRL` (2x) / `ISP_PORT_PINCTRL` - `0x608` - `PORTA_IN` / `ISP_PORT_IN` - `0x6` - _bit position for pin \#6_ / `ISP_PORT_PIN` #### Patch Let's check values from the original firmware binary before: ``` $ srec_info atxmega32a4u_104.hex -intel Format: Intel Hexadecimal (MCS-86) Execution Start Address: 00008000 Data: 8000 - 81A5 81F4 - 8FB5 $ srec_cat atxmega32a4u_104.hex -intel -crop 0x800c 0x800e 0x8012 0x8014 0x801e 0x8020 0x8020 0x8021 0x80e0 0x80e2 -o - -hex_dump 00008000: 40 06 # @. 00008010: 53 06 48 06 # S. H. 00008020: 03 #. 000080E0: 53 06 #S. ``` Then we can replace them: ``` srec_cat atxmega32a4u_104.hex -intel -exclude 0x800c 0x800e 0x8012 0x8014 0x801e 0x8020 0x8020 0x8021 0x80e0 0x80e2 \ -generate 0x800c 0x800e -constant_little_endian 0x600 2 \ -generate 0x8012 0x8014 0x80e0 0x80e2 -constant_little_endian 0x616 2 \ -generate 0x801e 0x8020 -constant_little_endian 0x608 2 \ -generate 0x8020 0x8021 -constant_little_endian 0x6 1 \ -o atxmega32a4u_104_PA6.hex -intel ``` Patched DFU bootloader firmware is: `atxmega32a4u_104_PA6.hex` ## Programming ### `flip2` (dfu) #### Check connection ``` > avrdude -c flip2 -p ATxmega32A4U -v [...] Using port : usb Using programmer : flip2 AVR part : ATxmega32A4U Programming modes : SPM, PDI Programmer type : flip2 Description : FLIP bootloader using USB DFU v2 (AVR4023) USB Vendor : 0x03EB USB Product : 0x2FE4 USB Release : 0.0.4 Part signature : 0x1E9541 Part revision : E Bootloader version : 2.0.4 USB max packet size : 64 AVR device initialized and ready to accept instructions Device signature = 1E 95 41 (ATxmega32A4U, ATxmega32A4) ``` ### `pickit4_isp` or `avrispmkII` > [!note] > Original fuses > > | Fuse Name | Value | > |-----------|-------| > | FUSE0 | 0xff | > | FUSE1 | 0x00 | > | FUSE2 | 0xbe | > | FUSE4 | 0xfe | > | FUSE5 | 0xec | > | LOCK | 0xff | > > You can check them with: > - version < 8.0: `avrdude -c avrispmkii -p ATxmega32A4U -U fuse0:r:-:h -U fuse1:r:-:h -U fuse2:r:-:h -U fuse4:r:-:h -U fuse5:r:-:h -U lock:r:-:h` > - version >= 8.0: `avrdude -c avrispmkii -p ATxmega32A4U -U fuse0,fuse1,fuse2,fuse4,fuse5,lock:r:-:h` #### Check connection ``` > avrdude -c avrispmkii -p ATxmega32A4U -v [...] Using port : usb Using programmer : avrispmkII Usbdev_open(): found AVRISP mkII, serno: 001D2C990079 AVR part : ATxmega32A4U Programming modes : SPM, PDI Programmer type : STK500V2 Description : USB Atmel AVR ISP mkII Programmer model : AVRISP mkII HW version : 1 Serial number : 001D2C990079 FW Version Controller : 1.24 Vtarget : 3.2 V SCK period : 8.0 us Silicon revision: 0.4 AVR device initialized and ready to accept instructions Device signature = 1E 95 41 (ATxmega32A4U, ATxmega32A4) ``` #### Before flashing > [!danger] > Make backup before any write operation: `avrdude -c avrispmkii -p ATxmega32A4U -U flash:r:backup_flash.hex:i -U eeprom:r:backup_eeprom.hex:i` > You can restore the flash by: `avrdude -c avrispmkii -p ATxmega32A4U -e -U flash:w:backup_flash.hex:i -U eeprom:w:backup_flash.hex:i` > [!note] > The `-e` will erase the `eeprom` too (if previous fuses values were wrong, it may be not erased, feel free to check with: `avrdude -c avrispmkii -p ATxmega32A4U -U eeprom:r:-:h` before trying again) #### Flash new firmware ``` avrdude -c avrispmkii -p ATxmega32A4U -e -U flash:w:ChameleonMini.hex:i -U flash:w:atxmega32a4u_104_PA6.hex:i -U eeprom:w:ChameleonMini.eep:i -U fuse0:w:0xff:m -U fuse1:w:0x00:m -U fuse2:w:0xbe:m -U fuse4:w:0xfe:m -U fuse5:w:0xec:m -U lock:w:0xff:m ``` or with all combined (`avrdude` version >= 8.0): ``` avrdude -c avrispmkii -p ATxmega32A4U -e -U flash,eeprom,fuse0,fuse1,fuse2,fuse4,fuse5,lock:w:ChameleonMini-bootloaderdfu_eeprom_fuses_lock.hex:i ``` > [!tip] > You can produce this combined file (`ChameleonMini-bootloaderdfu_eeprom_fuses_lock.hex`) with eeprom, fuses & lock with: > - From the patched DFU firmware (`atxmega32a4u_104_PA6.hex`) > ``` > srec_cat -output ChameleonMini-bootloaderdfu_eeprom_fuses_lock.hex -intel \ > ChameleonMini.hex -intel \ > atxmega32a4u_104_PA6.hex -intel \ > ChameleonMini.eep -intel -offset 0x810000 \ > -generate 0x820000 0x820003 -repeat_data 0xff 0x00 0xbe \ > -generate 0x820004 0x820006 -repeat_data 0xfe 0xec \ > -generate 0x830000 0x830001 -constant 0xff > ``` > - From the unpatched DFU firmware (`atxmega32a4u_104.hex`) > ``` > srec_cat -output ChameleonMini-bootloaderdfu_eeprom_fuses_lock.hex -intel \ > ChameleonMini.hex -intel \ > atxmega32a4u_104.hex -intel -exclude 0x800c 0x800e 0x8012 0x8014 0x801e 0x8020 0x8020 0x8021 0x80e0 0x80e2 \ > -generate 0x800c 0x800e -constant_little_endian 0x600 2 \ > -generate 0x8012 0x8014 0x80e0 0x80e2 -constant_little_endian 0x616 2 \ > -generate 0x801e 0x8020 -constant_little_endian 0x608 2 \ > -generate 0x8020 0x8021 -constant_little_endian 0x6 1 \ > ChameleonMini.eep -intel -offset 0x810000 \ > -generate 0x820000 0x820003 -repeat_data 0xff 0x00 0xbe \ > -generate 0x820004 0x820006 -repeat_data 0xfe 0xec \ > -generate 0x830000 0x830001 -constant 0xff > ``` ## References - https://www.microchip.com/en-us/product/atxmega32a4u - https://www.microchip.com/en-us/application-notes/an8429 - https://github.com/iceman1001/ChameleonMini-rebooted - https://github.com/emsec/ChameleonMini - https://github.com/RfidResearchGroup/ChameleonMini