First write-up of firmware copy routine- totally untested!
This commit is contained in:
parent
1ae24e5378
commit
3fb2977ff0
|
|
@ -36,8 +36,8 @@ CC = $(ARCH)gcc
|
||||||
OBJDUMP = $(ARCH)objdump
|
OBJDUMP = $(ARCH)objdump
|
||||||
OBJCOPY = $(ARCH)objcopy
|
OBJCOPY = $(ARCH)objcopy
|
||||||
|
|
||||||
OPTIMIZE = -Os -ffunction-sections -finline-functions-called-once -DDEBUG=1
|
# OPTIMIZE = -Os -ffunction-sections -finline-functions-called-once -DDEBUG=1
|
||||||
# OPTIMIZE = -O0
|
OPTIMIZE = -O0
|
||||||
CFLAGS = -g -Wall -Wstrict-prototypes $(OPTIMIZE) -mmcu=$(MCU_TARGET) -DF_CPU=$(F_CPU) $(DEFS) -std=gnu99 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -save-temps
|
CFLAGS = -g -Wall -Wstrict-prototypes $(OPTIMIZE) -mmcu=$(MCU_TARGET) -DF_CPU=$(F_CPU) $(DEFS) -std=gnu99 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -save-temps
|
||||||
LDFLAGS = -Wl,--as-needed -Wl,--gc-sections
|
LDFLAGS = -Wl,--as-needed -Wl,--gc-sections
|
||||||
|
|
||||||
|
|
@ -72,6 +72,7 @@ clean:
|
||||||
rm -rf *.o *.elf *.lst *.map *.sym *.lss *.eep *.srec *.bin *.hex *.al *.i *.s *~
|
rm -rf *.o *.elf *.lst *.map *.sym *.lss *.eep *.srec *.bin *.hex *.al *.i *.s *~
|
||||||
|
|
||||||
size: $(PROGRAM).hex
|
size: $(PROGRAM).hex
|
||||||
|
@echo -n " SIZE "
|
||||||
@objdump -h mendel.elf | perl -ne '/.(data|text)\s+([0-9a-f]+)/ && do { $$a += eval "0x$$2" }; END { printf "%d bytes (%d%% of %dkb)\n", $$a, $$a * 100 / 16384, 16 }'
|
@objdump -h mendel.elf | perl -ne '/.(data|text)\s+([0-9a-f]+)/ && do { $$a += eval "0x$$2" }; END { printf "%d bytes (%d%% of %dkb)\n", $$a, $$a * 100 / 16384, 16 }'
|
||||||
|
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,94 @@
|
||||||
|
#include "copier.h"
|
||||||
|
|
||||||
|
#include <avr/pgmspace.h>
|
||||||
|
|
||||||
|
#include "arduino.h"
|
||||||
|
#include "timer.h"
|
||||||
|
#include "serial.h"
|
||||||
|
|
||||||
|
uint32_t copier_xchange(uint32_t cmd) {
|
||||||
|
uint32_t r = 0, c = cmd;
|
||||||
|
uint8_t i = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < 32; i++) {
|
||||||
|
WRITE(COPIER_MOSI, c & 0x80000000); delay_us(5);
|
||||||
|
c <<= 1;
|
||||||
|
WRITE(COPIER_SCK, 1); delay_us(5);
|
||||||
|
r = (r << 1) | (READ(COPIER_MISO)?1:0);
|
||||||
|
WRITE(COPIER_SCK, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
delay_us(5);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_chip(void);
|
||||||
|
void init_chip() {
|
||||||
|
do {
|
||||||
|
WRITE(COPIER_SCK, 0);
|
||||||
|
// power up
|
||||||
|
WRITE(COPIER_RESET, 1);
|
||||||
|
delay_ms(10);
|
||||||
|
WRITE(COPIER_RESET, 0);
|
||||||
|
delay_ms(10);
|
||||||
|
// hopefully enter programming mode
|
||||||
|
} while ((copier_xchange(CMD_PROGRAMMING_ENABLE) & (CMD_PROGRAMMING_ENABLE >> 8)) != (CMD_PROGRAMMING_ENABLE >> 8));
|
||||||
|
}
|
||||||
|
|
||||||
|
void copy() {
|
||||||
|
// initialise
|
||||||
|
WRITE(COPIER_RESET, 0); SET_OUTPUT(COPIER_RESET);
|
||||||
|
WRITE(COPIER_SCK, 0); SET_OUTPUT(COPIER_SCK);
|
||||||
|
WRITE(COPIER_MOSI, 0); SET_OUTPUT(COPIER_MOSI);
|
||||||
|
SET_INPUT(COPIER_MISO); WRITE(COPIER_MISO, 1);
|
||||||
|
|
||||||
|
delay_ms(50);
|
||||||
|
|
||||||
|
init_chip();
|
||||||
|
|
||||||
|
// verify device signature- should be same as current chip since we haven't the space for the functionality necessary to program anything else
|
||||||
|
if ((copier_xchange(CMD_READ_SIGNATURE | 0x00) & 0xFF) != SIGNATURE_0)
|
||||||
|
return;
|
||||||
|
if ((copier_xchange(CMD_READ_SIGNATURE | 0x01) & 0xFF) != SIGNATURE_1)
|
||||||
|
return;
|
||||||
|
if ((copier_xchange(CMD_READ_SIGNATURE | 0x02) & 0xFF) != SIGNATURE_2)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// erase chip
|
||||||
|
copier_xchange(CMD_CHIP_ERASE);
|
||||||
|
delay_ms(15); //minimum is 9.0ms
|
||||||
|
|
||||||
|
// re-initialise
|
||||||
|
init_chip();
|
||||||
|
|
||||||
|
uint8_t f;
|
||||||
|
// copy fuses
|
||||||
|
// first low byte
|
||||||
|
SPMCSR |= MASK(BLBSET) | MASK(SELFPRGEN);
|
||||||
|
f = pgm_read_byte_near(0);
|
||||||
|
copier_xchange(CMD_WRITE_FUSE_BITS | f);
|
||||||
|
|
||||||
|
// high byte
|
||||||
|
SPMCSR |= MASK(BLBSET) | MASK(SELFPRGEN);
|
||||||
|
f = pgm_read_byte_near(3);
|
||||||
|
copier_xchange(CMD_WRITE_FUSE_HIGH_BITS | f);
|
||||||
|
|
||||||
|
// extended byte
|
||||||
|
SPMCSR |= MASK(BLBSET) | MASK(SELFPRGEN);
|
||||||
|
f = pgm_read_byte_near(2);
|
||||||
|
copier_xchange(CMD_WRITE_FUSE_EXTENDED_BITS | f);
|
||||||
|
|
||||||
|
// start copying flash
|
||||||
|
uint16_t i;
|
||||||
|
for (i = 0; i < (FLASHEND / 2); i += (SPM_PAGESIZE / 2)) {
|
||||||
|
uint8_t j;
|
||||||
|
for (j = 0; j < (SPM_PAGESIZE / 2); j++) {
|
||||||
|
uint16_t w = pgm_read_word_near((i | j) << 1);
|
||||||
|
copier_xchange(CMD_LOAD_PROGMEM_LOW_BYTE | (j << 8) | (w & 0xFF));
|
||||||
|
copier_xchange(CMD_LOAD_PROGMEM_HIGH_BYTE | (j << 8) | (w >> 8));
|
||||||
|
}
|
||||||
|
copier_xchange(CMD_WRITE_PROGMEM_PAGE | ((i / (SPM_PAGESIZE / 2)) << 8));
|
||||||
|
delay_ms(10); //minimum is 4.5ms
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
#ifndef _COPIER_H
|
||||||
|
#define _COPIER_H
|
||||||
|
|
||||||
|
// operation instructions
|
||||||
|
#define CMD_PROGRAMMING_ENABLE 0xAC530000
|
||||||
|
#define CMD_CHIP_ERASE 0xAC800000
|
||||||
|
#define CMD_POLL 0xF0000000
|
||||||
|
|
||||||
|
// load instructions
|
||||||
|
#define CMD_LOAD_EXTENDED_ADDRESS 0x4D000000
|
||||||
|
#define CMD_LOAD_PROGMEM_HIGH_BYTE 0x48000000
|
||||||
|
#define CMD_LOAD_PROGMEM_LOW_BYTE 0x40000000
|
||||||
|
#define CMD_LOAD_EEPROM_PAGE 0xC1000000
|
||||||
|
|
||||||
|
// read instructions
|
||||||
|
#define CMD_READ_PROGMEM_HIGH_BYTE 0x28000000
|
||||||
|
#define CMD_READ_PROGMEM_LOW_BYTE 0x20000000
|
||||||
|
#define CMD_READ_EEPROM 0xA0000000
|
||||||
|
#define CMD_READ_LOCK_BITS 0x58000000
|
||||||
|
#define CMD_READ_SIGNATURE 0x30000000
|
||||||
|
#define CMD_READ_FUSE_BITS 0x50000000
|
||||||
|
#define CMD_READ_FUSE_HIGH_BITS 0x58080000
|
||||||
|
#define CMD_READ_FUSE_EXTENDED_BITS 0x50080000
|
||||||
|
#define CMD_READ_CALIBRATION_BYTE 0x38000000
|
||||||
|
|
||||||
|
// write instructions
|
||||||
|
#define CMD_WRITE_PROGMEM_PAGE 0x4C000000
|
||||||
|
#define CMD_WRITE_EEPROM 0xC0000000
|
||||||
|
#define CMD_WRITE_EEPROM_PAGE 0xC2000000
|
||||||
|
#define CMD_WRITE_LOCK_BITS 0xACE00000
|
||||||
|
#define CMD_WRITE_FUSE_BITS 0xACA00000
|
||||||
|
#define CMD_WRITE_FUSE_HIGH_BITS 0xACA80000
|
||||||
|
#define CMD_WRITE_FUSE_EXTENDED_BITS 0xACA40000
|
||||||
|
|
||||||
|
//pinout
|
||||||
|
#define COPIER_RESET AIO1
|
||||||
|
#define COPIER_SCK AIO2
|
||||||
|
#define COPIER_MOSI AIO3
|
||||||
|
#define COPIER_MISO AIO4
|
||||||
|
|
||||||
|
//functions
|
||||||
|
|
||||||
|
void copy(void);
|
||||||
|
|
||||||
|
#endif /* _COPIER_H */
|
||||||
Loading…
Reference in New Issue