ChameleonMini RevG or Tiny - ATxmega128A4U
Work In Progress
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 |
It seems that the definition for
XMEGA_A1Uis incorrect,ISP_PORT_PINis0:ISP_PORT_PINCTRLshould bePORTF_PIN0CTRL(notPORTF_PIN5CTRL).
In addition, documentation is about a non existentPF10(Table 5-1).
We are not concerned about it here, as we’re working on
ATxmega128A4U, usingPC3by default to switch to DFU mode.
From 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
And from previous definitions with /lib/avr/include/avr/iox32a4u.h:
$ 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 firmwares related to PC3, with values:
0x640-PORTC_DIR/ISP_PORT_DIR0x653-PORTC_PIN3CTRL(2x) /ISP_PORT_PINCTRL0x648-PORTC_IN/ISP_PORT_IN0x3- bit position for pin #3 /ISP_PORT_PIN
ATxmega32A4U
Official firmware is for PC3:
> 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.
For Chameleon Mini revE, we need a bootloader for 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)
0x600-PORTA_DIR0x616-PORTA_PIN6CTRL(2x)0x608-PORTA_IN0x6- bit position for pin #6
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
128
> srec_info atxmega128a4u_104.hex -intel
Format: Intel Hexadecimal (MCS-86)
Execution Start Address: 00020000
Data: 020000 - 0201E5
0201F4 - 0215E1
> srec_cat atxmega128a4u_104.hex -intel -crop 0x2000c 0x2000e 0x20012 0x20014 0x2001e 0x20020 0x20020 0x20021 0x20090 0x20092 -o - -hex_dump
00020000: 40 06 # @.
00020010: 53 06 48 06 # S. H.
00020020: 03 #.
00020090: 53 06 #S.
srec_cat atxmega128a4u_104.hex -intel -exclude 0x2000c 0x2000e 0x20012 0x20014 0x2001e 0x20020 0x20020 0x20021 0x20090 0x20092 ^
-generate 0x2000c 0x2000e -constant_little_endian 0x600 2 ^
-generate 0x20012 0x20014 0x20090 0x20092 -constant_little_endian 0x616 2 ^
-generate 0x2001e 0x20020 -constant_little_endian 0x608 2 ^
-generate 0x20020 0x20021 -constant_little_endian 0x6 1 ^
-o atxmega128a4u_104_PA6.hex -intel
srec_cat atxmega128a4u_104.hex -intel -exclude 0x2000c 0x2000e 0x20012 0x20014 0x2001e 0x20020 0x20020 0x20021 0x20090 0x20092 ^
-generate 0x2000c 0x2000e -constant_little_endian 0x600 2 ^
-generate 0x20012 0x20014 0x20090 0x20092 -constant_little_endian 0x616 2 ^
-generate 0x2001e 0x20020 -constant_little_endian 0x608 2 ^
-generate 0x20020 0x20021 -constant_little_endian 0x6 1 ^
..\..\..\..\..\atmel\test.hex -intel -offset 0x21fe0 ^
-o atxmega128a4u_104_PA6_SPM.hex -intel
srec_cmp -v original\bootloader-atxmega128a4u-104-PA6-SPM.hex -intel -crop 0x21fe0 ..\..\..\..\atmel\test.hex -intel -offset 0x21fe0
gentilkiwi@rog-k:/mnt/c/security/code/atmel$ cat test.sx
#include <avr/io.h>
#define CCP_SPM_gc (0x9D<<0) /* SPM instruction protection # TB3262 */
movw ZL, r24 ; Load R25:R24 into Z.
sts NVM_CMD, r20 ; Load prepared command into NVM Command register.
ldi r18, CCP_SPM_gc ; Prepare Protect SPM signature in R18
sts CCP, r18 ; Enable SPM operation (this disables interrupts for 4 cycles).
spm ; Self-program.
clr r1 ; Clear R1 for GCC _zero_reg_ to function properly.
out RAMPZ, r19 ; Restore RAMPZ register.
ret
gentilkiwi@rog-k:/mnt/c/security/code/atmel$ avr-gcc -mmcu=atxmega128a4u -nostartfiles -Ttext=0x21fe0 -o test.elf test.sx
gentilkiwi@rog-k:/mnt/c/security/code/atmel$ avr-objcopy -O ihex test.elf test.hex
gentilkiwi@rog-k:/mnt/c/security/code/atmel$ srec_cat test.hex -intel -o - -hex_dump
00021FE0: FC 01 40 93 CA 01 2D E9 20 93 34 00 E8 95 11 24 #|.@.J.-i .4.h..$
00021FF0: 3B BF 08 95 #;?..
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
128
> srec_info atxmega128a4u_104.hex -intel
Format: Intel Hexadecimal (MCS-86)
Execution Start Address: 00020000
Data: 020000 - 0201E5
0201F4 - 0215E1
> srec_cat atxmega128a4u_104.hex -intel -crop 0x2000c 0x2000e 0x20012 0x20014 0x2001e 0x20020 0x20020 0x20021 0x20090 0x20092 -o - -hex_dump
00020000: 40 06 # @.
00020010: 53 06 48 06 # S. H.
00020020: 03 #.
00020090: 53 06 #S.
srec_cat atxmega128a4u_104.hex -intel -exclude 0x2000c 0x2000e 0x20012 0x20014 0x2001e 0x20020 0x20020 0x20021 0x20090 0x20092 ^
-generate 0x2000c 0x2000e -constant_little_endian 0x600 2 ^
-generate 0x20012 0x20014 0x20090 0x20092 -constant_little_endian 0x616 2 ^
-generate 0x2001e 0x20020 -constant_little_endian 0x608 2 ^
-generate 0x20020 0x20021 -constant_little_endian 0x6 1 ^
-o atxmega128a4u_104_PA6.hex -intel
srec_cat atxmega128a4u_104.hex -intel -exclude 0x2000c 0x2000e 0x20012 0x20014 0x2001e 0x20020 0x20020 0x20021 0x20090 0x20092 ^
-generate 0x2000c 0x2000e -constant_little_endian 0x600 2 ^
-generate 0x20012 0x20014 0x20090 0x20092 -constant_little_endian 0x616 2 ^
-generate 0x2001e 0x20020 -constant_little_endian 0x608 2 ^
-generate 0x20020 0x20021 -constant_little_endian 0x6 1 ^
..\..\..\..\..\atmel\test.hex -intel -offset 0x21fe0 ^
-o atxmega128a4u_104_PA6_SPM.hex -intel
srec_cmp -v original\bootloader-atxmega128a4u-104-PA6-SPM.hex -intel -crop 0x21fe0 ..\..\..\..\atmel\test.hex -intel -offset 0x21fe0
gentilkiwi@rog-k:/mnt/c/security/code/atmel$ cat test.sx
#include <avr/io.h>
#define CCP_SPM_gc (0x9D<<0) /* SPM instruction protection # TB3262 */
movw ZL, r24 ; Load R25:R24 into Z.
sts NVM_CMD, r20 ; Load prepared command into NVM Command register.
ldi r18, CCP_SPM_gc ; Prepare Protect SPM signature in R18
sts CCP, r18 ; Enable SPM operation (this disables interrupts for 4 cycles).
spm ; Self-program.
clr r1 ; Clear R1 for GCC _zero_reg_ to function properly.
out RAMPZ, r19 ; Restore RAMPZ register.
ret
gentilkiwi@rog-k:/mnt/c/security/code/atmel$ avr-gcc -mmcu=atxmega128a4u -nostartfiles -Ttext=0x21fe0 -o test.elf test.sx
gentilkiwi@rog-k:/mnt/c/security/code/atmel$ avr-objcopy -O ihex test.elf test.hex
gentilkiwi@rog-k:/mnt/c/security/code/atmel$ srec_cat test.hex -intel -o - -hex_dump
00021FE0: FC 01 40 93 CA 01 2D E9 20 93 34 00 E8 95 11 24 #|.@.J.-i .4.h..$
00021FF0: 3B BF 08 95 #;?..