reduce sizae and compat work
- current firmware need more space -> reduce bootloader size from 4K => 2K - remove timer ISR - remove interrupt vectors from linked binary - make avr910 bootloader entry command more robust (old: 'S', new: { 0x1B, 'S'} ) - add compat bootloader entry command (rx: { 0x1B, 0xAA } -> tx: 'MKBL') - do not leave bootloader after upgrading twiboot slave - do not erase local flash when upgrading twiboot slave - remove readable chipinfo output from twiboot slaves
This commit is contained in:
parent
a7fcfaf7b9
commit
125bdc1729
1
.gitignore
vendored
1
.gitignore
vendored
@ -4,3 +4,4 @@
|
|||||||
*.hex
|
*.hex
|
||||||
*.lst
|
*.lst
|
||||||
*.map
|
*.map
|
||||||
|
ldscript-no-vectors.x
|
||||||
|
18
Makefile
18
Makefile
@ -6,23 +6,33 @@ OPTIMIZE = -Os
|
|||||||
DEFS =
|
DEFS =
|
||||||
LIBS =
|
LIBS =
|
||||||
|
|
||||||
|
LDSCRIPT_SRC := /usr/lib/ldscripts/avr5.x
|
||||||
|
LDSCRIPT_DST := ldscript-no-vectors.x
|
||||||
|
|
||||||
# Override is only needed by avr-lib build system.
|
# Override is only needed by avr-lib build system.
|
||||||
override CFLAGS = -g -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) $(DEFS)
|
override CFLAGS = -g -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) $(DEFS)
|
||||||
override LDFLAGS = -Wl,-Map,$(PRG).map,--section-start=.text=0xF000
|
override LDFLAGS = -Wl,-Map,$(PRG).map,--section-start=.text=0xF800,-T$(LDSCRIPT_DST)
|
||||||
|
|
||||||
CC = avr-gcc
|
CC = avr-gcc
|
||||||
OBJCOPY = avr-objcopy
|
OBJCOPY = avr-objcopy
|
||||||
OBJDUMP = avr-objdump
|
OBJDUMP = avr-objdump
|
||||||
SIZE = avr-size
|
SIZE = avr-size
|
||||||
|
|
||||||
|
#LDSCRIPT_SRC := $(shell LANG=C $(CC) $(CFLAGS) -Wl,--verbose 2> /dev/null | awk '/^opened script file (.*)$$/{ print $$4 }')
|
||||||
|
|
||||||
all: $(PRG).elf lst text
|
all: $(PRG).elf lst text
|
||||||
$(SIZE) -x -A $(PRG).elf
|
$(SIZE) -x -A $(PRG).elf
|
||||||
|
|
||||||
$(PRG).elf: $(OBJ)
|
$(PRG).elf: $(OBJ) | $(LDSCRIPT_DST)
|
||||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)
|
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||||
|
|
||||||
|
$(LDSCRIPT_DST): $(LDSCRIPT_SRC)
|
||||||
|
# remove all lines with *vectors* and insert DISCARD line above .text declaration
|
||||||
|
sed -e '/.*vectors.*/d' -e 's/\(^[ \t]*\)\(.text[ \t]*\:\)$$/\1\/DISCARD\/ : { *(.vectors) }\n\1\2/g' $^ > $@
|
||||||
|
# -diff -uNr $^ $@ > $@.diff
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf *.o $(PRG).lst $(PRG).map $(PRG).elf $(PRG).hex $(PRG).bin
|
rm -rf *.o $(PRG).lst $(PRG).map $(PRG).elf $(PRG).hex $(PRG).bin $(LDSCRIPT_DST)
|
||||||
|
|
||||||
lst: $(PRG).lst
|
lst: $(PRG).lst
|
||||||
|
|
||||||
@ -41,4 +51,4 @@ bin: $(PRG).bin
|
|||||||
$(OBJCOPY) -j .text -j .data -O binary $< $@
|
$(OBJCOPY) -j .text -j .data -O binary $< $@
|
||||||
|
|
||||||
install: text
|
install: text
|
||||||
avrdude -c dragon_isp -P usb -p m644p -B0.3 -V -U flash:w:$(PRG).hex
|
avrdude -c dragon_isp -P usb -p m644p -V -U flash:w:$(PRG).hex
|
||||||
|
25
README
Normal file
25
README
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
1) Flash FC firmware:
|
||||||
|
# reset running firmware (MCU will execute bootloader only for ~1s!)
|
||||||
|
$ echo -e -n "#aR@S\r" > /dev/ttyUSB1
|
||||||
|
|
||||||
|
# flash new firmware
|
||||||
|
$ avrdude -p m644p -c butterfly -b 57600 -P /dev/ttyUSB1 -U flash:w:/tmp/Flight-Ctrl_MEGA644_V0_82a.hex
|
||||||
|
|
||||||
|
|
||||||
|
2) Flash BLMC firmware (via twiboot):
|
||||||
|
# enter bootloader (0x1B, 'S'), select first twi-slave ('1'):
|
||||||
|
$ echo -e -n "\x1BS1" > /dev/ttyUSB1
|
||||||
|
|
||||||
|
# flash new firmware
|
||||||
|
$ avrdude -p m8 -c butterfly -b 57600 -P /dev/ttyUSB1 -U flash:w:/tmp/blmc.hex
|
||||||
|
|
||||||
|
# select next twi-slave (bootloader is still active)
|
||||||
|
$ echo -e -n "2" > /dev/ttyUSB1
|
||||||
|
|
||||||
|
|
||||||
|
3) Other Commands:
|
||||||
|
'0' => select FC internal flash/eeprom
|
||||||
|
'1' - '4' => select twi-slave 1-4, print bootloader version
|
||||||
|
'I' => start application on selected twi-slave, print application version
|
||||||
|
'l' => start selected motor
|
||||||
|
'k' => stop selected motor
|
329
main.c
329
main.c
@ -25,7 +25,7 @@
|
|||||||
/*
|
/*
|
||||||
* ATMega 644P:
|
* ATMega 644P:
|
||||||
* Fuse E: 0xFD (2.7V BOD)
|
* Fuse E: 0xFD (2.7V BOD)
|
||||||
* Fuse H: 0xDA (2048 words bootloader)
|
* Fuse H: 0xDC (1024 words bootloader)
|
||||||
* Fuse L: 0xFF (ext. Crystal)
|
* Fuse L: 0xFF (ext. Crystal)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -35,15 +35,15 @@
|
|||||||
#define BAUDRATE 57600
|
#define BAUDRATE 57600
|
||||||
#define UART_CALC_BAUDRATE(baudRate) ((uint32_t)(F_CPU) / ((uint32_t)(baudRate)*16) -1)
|
#define UART_CALC_BAUDRATE(baudRate) ((uint32_t)(F_CPU) / ((uint32_t)(baudRate)*16) -1)
|
||||||
|
|
||||||
#define APP_END 0xF000
|
#define APP_END 0xF7FF
|
||||||
|
|
||||||
#define LED_RT (1<<PORTB0) /* low active */
|
#define LED_RT (1<<PORTB0) /* low active */
|
||||||
#define LED_GN (1<<PORTB1) /* high active */
|
#define LED_GN (1<<PORTB1) /* high active */
|
||||||
|
|
||||||
#define TWI_CLK 100000
|
#define TWI_CLK 100000
|
||||||
#define TWI_ADDRESS_BASE 0x20 /* 0x21 - 0x24 */
|
#define TWI_ADDRESS_BASE 0x28 /* 0x29 - 0x2C */
|
||||||
|
|
||||||
#define TWI_DEVCODE 0x77 /* Mega8 */
|
#define TWI_DEVCODE 0x76 /* Mega8 */
|
||||||
#define OWN_DEVCODE 0x74 /* Mega644 */
|
#define OWN_DEVCODE 0x74 /* Mega644 */
|
||||||
#define OWN_SIGNATURE { 0x1E, 0x96, 0x0A } /* Mega644P */
|
#define OWN_SIGNATURE { 0x1E, 0x96, 0x0A } /* Mega644P */
|
||||||
|
|
||||||
@ -79,26 +79,14 @@ static uint8_t recvchar(void)
|
|||||||
return UDR0;
|
return UDR0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_byte(uint8_t val)
|
static void i2c_master_tx(uint8_t val)
|
||||||
{
|
|
||||||
uint8_t tmp = (val >> 4) & 0x0F;
|
|
||||||
sendchar((tmp < 0x0A) ? ('0' + tmp) : ('a' - 0x0A + tmp));
|
|
||||||
|
|
||||||
tmp = val & 0x0F;
|
|
||||||
sendchar((tmp < 0x0A) ? ('0' + tmp) : ('a' - 0x0A + tmp));
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint8_t i2c_master_tx(uint8_t val)
|
|
||||||
{
|
{
|
||||||
TWDR = val;
|
TWDR = val;
|
||||||
TWCR = (1<<TWINT) | (1<<TWEN);
|
TWCR = (1<<TWINT) | (1<<TWEN);
|
||||||
loop_until_bit_is_set(TWCR, TWINT);
|
loop_until_bit_is_set(TWCR, TWINT);
|
||||||
|
|
||||||
uint8_t status = TWSR & 0xF8;
|
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t i2c_master_rx(uint8_t *val, uint8_t ack)
|
static uint8_t i2c_master_rx(uint8_t ack)
|
||||||
{
|
{
|
||||||
if (ack)
|
if (ack)
|
||||||
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
|
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
|
||||||
@ -106,10 +94,7 @@ static uint8_t i2c_master_rx(uint8_t *val, uint8_t ack)
|
|||||||
TWCR = (1<<TWINT) | (1<<TWEN);
|
TWCR = (1<<TWINT) | (1<<TWEN);
|
||||||
|
|
||||||
loop_until_bit_is_set(TWCR, TWINT);
|
loop_until_bit_is_set(TWCR, TWINT);
|
||||||
*val = TWDR;
|
return TWDR;
|
||||||
|
|
||||||
uint8_t status = TWSR & 0xF8;
|
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void i2c_stop(void)
|
static void i2c_stop(void)
|
||||||
@ -125,7 +110,8 @@ static void i2c_start_address(uint8_t addr)
|
|||||||
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
|
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
|
||||||
loop_until_bit_is_set(TWCR, TWINT);
|
loop_until_bit_is_set(TWCR, TWINT);
|
||||||
|
|
||||||
uint8_t status = i2c_master_tx(addr);
|
i2c_master_tx(addr);
|
||||||
|
uint8_t status = (TWSR & 0xF8);
|
||||||
if (status == 0x18 || status == 0x40)
|
if (status == 0x18 || status == 0x40)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -134,66 +120,64 @@ static void i2c_start_address(uint8_t addr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* wait 100x 10ms */
|
static void i2c_switch_app(uint8_t i2c_dev, uint8_t app)
|
||||||
volatile static uint8_t boot_timeout = 100;
|
|
||||||
|
|
||||||
ISR(TIMER0_OVF_vect)
|
|
||||||
{
|
{
|
||||||
static uint8_t cnt;
|
i2c_start_address(i2c_dev);
|
||||||
|
i2c_master_tx(CMD_SWITCH_APPLICATION);
|
||||||
|
i2c_master_tx(app);
|
||||||
|
i2c_stop();
|
||||||
|
|
||||||
/* come back in 10ms (@20MHz) */
|
_delay_ms(20);
|
||||||
TCNT0 = 0xFF - 195;
|
|
||||||
|
|
||||||
/* blink LED while running */
|
|
||||||
cnt++;
|
|
||||||
cnt &= 0x03;
|
|
||||||
if (cnt == 0x00)
|
|
||||||
PORTB ^= LED_GN;
|
|
||||||
|
|
||||||
if (boot_timeout > 0)
|
|
||||||
boot_timeout--;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint16_t address;
|
static void i2c_print_version(uint8_t i2c_dev)
|
||||||
static uint16_t page_size;
|
{
|
||||||
static uint8_t page_buf[SPM_PAGESIZE];
|
i2c_start_address(i2c_dev);
|
||||||
|
i2c_master_tx(CMD_READ_VERSION);
|
||||||
|
i2c_start_address(i2c_dev | 0x01);
|
||||||
|
|
||||||
|
uint8_t cnt = 16;
|
||||||
|
while (cnt--) {
|
||||||
|
sendchar(i2c_master_rx(cnt));
|
||||||
|
}
|
||||||
|
|
||||||
|
i2c_stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t page_buf[SPM_PAGESIZE];
|
||||||
|
|
||||||
static void eraseFlash(void)
|
static void eraseFlash(void)
|
||||||
{
|
{
|
||||||
uint32_t addr = 0;
|
uint16_t address = 0;
|
||||||
while (APP_END > addr) {
|
while (APP_END < address) {
|
||||||
boot_page_erase(addr);
|
boot_page_erase(address);
|
||||||
boot_spm_busy_wait();
|
boot_spm_busy_wait();
|
||||||
addr += SPM_PAGESIZE;
|
address += SPM_PAGESIZE;
|
||||||
}
|
}
|
||||||
boot_rww_enable();
|
boot_rww_enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint16_t writeFlashPage(uint16_t waddr, uint16_t size)
|
static void writeFlashPage(uint16_t address, uint16_t size)
|
||||||
{
|
{
|
||||||
uint32_t pagestart = (uint32_t)waddr<<1;
|
uint16_t pagestart = address;
|
||||||
uint32_t baddr = pagestart;
|
|
||||||
uint16_t data;
|
uint16_t data;
|
||||||
uint8_t *tmp = page_buf;
|
uint8_t *tmp = page_buf;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
data = *tmp++;
|
data = *tmp++;
|
||||||
data |= *tmp++ << 8;
|
data |= *tmp++ << 8;
|
||||||
boot_page_fill(baddr, data);
|
boot_page_fill(address, data);
|
||||||
|
|
||||||
baddr += 2;
|
address += 2;
|
||||||
size -= 2;
|
size -= 2;
|
||||||
} while (size);
|
} while (size);
|
||||||
|
|
||||||
boot_page_write(pagestart);
|
boot_page_write(pagestart);
|
||||||
boot_spm_busy_wait();
|
boot_spm_busy_wait();
|
||||||
boot_rww_enable();
|
boot_rww_enable();
|
||||||
|
|
||||||
return baddr>>1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint16_t writeEEpromPage(uint16_t address, uint16_t size)
|
static void writeEEpromPage(uint16_t address, uint16_t size)
|
||||||
{
|
{
|
||||||
uint8_t *tmp = page_buf;
|
uint8_t *tmp = page_buf;
|
||||||
|
|
||||||
@ -209,31 +193,22 @@ static uint16_t writeEEpromPage(uint16_t address, uint16_t size)
|
|||||||
|
|
||||||
size--;
|
size--;
|
||||||
} while (size);
|
} while (size);
|
||||||
|
|
||||||
return address;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint16_t readFlashPage(uint16_t waddr, uint16_t size)
|
static void readFlashPage(uint16_t address, uint16_t size)
|
||||||
{
|
{
|
||||||
uint32_t baddr = (uint32_t)waddr<<1;
|
|
||||||
uint16_t data;
|
uint16_t data;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
#if defined(RAMPZ)
|
data = pgm_read_word_near(address);
|
||||||
data = pgm_read_word_far(baddr);
|
|
||||||
#else
|
|
||||||
data = pgm_read_word_near(baddr);
|
|
||||||
#endif
|
|
||||||
sendchar(data);
|
sendchar(data);
|
||||||
sendchar((data >> 8));
|
sendchar((data >> 8));
|
||||||
baddr += 2;
|
address += 2;
|
||||||
size -= 2;
|
size -= 2;
|
||||||
} while (size);
|
} while (size);
|
||||||
|
|
||||||
return baddr>>1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint16_t readEEpromPage(uint16_t address, uint16_t size)
|
static void readEEpromPage(uint16_t address, uint16_t size)
|
||||||
{
|
{
|
||||||
do {
|
do {
|
||||||
EEARL = address;
|
EEARL = address;
|
||||||
@ -245,43 +220,36 @@ static uint16_t readEEpromPage(uint16_t address, uint16_t size)
|
|||||||
|
|
||||||
size--;
|
size--;
|
||||||
} while (size);
|
} while (size);
|
||||||
|
|
||||||
return address;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 0-2: signature, 3: pagesize, 4-5: flash size, 6-7: eeprom size */
|
/* 0-2: signature, 3: pagesize, 4-5: flash size, 6-7: eeprom size */
|
||||||
static uint8_t chipinfo[8];
|
static uint8_t chipinfo[8];
|
||||||
|
|
||||||
void cmd_loop(void)
|
void cmd_loop(uint8_t val)
|
||||||
{
|
{
|
||||||
|
uint16_t address = 0;
|
||||||
|
uint16_t page_size = 0;
|
||||||
uint8_t i2c_dev = 0;
|
uint8_t i2c_dev = 0;
|
||||||
|
|
||||||
sendchar('F');
|
|
||||||
sendchar('C');
|
|
||||||
sendchar('_');
|
|
||||||
sendchar('B');
|
|
||||||
sendchar('O');
|
|
||||||
sendchar('O');
|
|
||||||
sendchar('T');
|
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
uint8_t val = recvchar();
|
uint8_t response = 0xFF;
|
||||||
|
|
||||||
// Autoincrement?
|
// Autoincrement?
|
||||||
if (val == 'a') {
|
if (val == 'a') {
|
||||||
sendchar('Y');
|
response = 'Y';
|
||||||
|
|
||||||
// write address
|
// write address
|
||||||
} else if (val == 'A') {
|
} else if (val == 'A') {
|
||||||
address = recvchar();
|
address = recvchar();
|
||||||
address = (address << 8) | recvchar();
|
address = (address << 8) | recvchar();
|
||||||
sendchar('\r');
|
response = '\r';
|
||||||
|
|
||||||
// Buffer load support
|
// Buffer load support
|
||||||
} else if (val == 'b') {
|
} else if (val == 'b') {
|
||||||
sendchar('Y');
|
sendchar('Y');
|
||||||
page_size = (i2c_dev == 0) ? sizeof(page_buf) : chipinfo[3];
|
page_size = (i2c_dev == 0) ? sizeof(page_buf) : chipinfo[3];
|
||||||
sendchar((page_size >> 8) & 0xFF);
|
sendchar((page_size >> 8) & 0xFF);
|
||||||
sendchar(page_size & 0xFF);
|
response = page_size & 0Xff;
|
||||||
|
|
||||||
// Start buffer load
|
// Start buffer load
|
||||||
} else if (val == 'B') {
|
} else if (val == 'B') {
|
||||||
@ -313,12 +281,13 @@ void cmd_loop(void)
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (val == 'F') {
|
if (val == 'F') {
|
||||||
address = writeFlashPage(address, size);
|
writeFlashPage(address, size);
|
||||||
} else if (val == 'E') {
|
} else if (val == 'E') {
|
||||||
address = writeEEpromPage(address, size);
|
writeEEpromPage(address, size);
|
||||||
}
|
}
|
||||||
|
address += size;
|
||||||
}
|
}
|
||||||
sendchar('\r');
|
response = '\r';
|
||||||
|
|
||||||
// Block read
|
// Block read
|
||||||
} else if (val == 'g') {
|
} else if (val == 'g') {
|
||||||
@ -335,8 +304,7 @@ void cmd_loop(void)
|
|||||||
|
|
||||||
i2c_start_address(i2c_dev | 0x01);
|
i2c_start_address(i2c_dev | 0x01);
|
||||||
while (size--) {
|
while (size--) {
|
||||||
i2c_master_rx(&val, size > 0);
|
sendchar(i2c_master_rx(size > 0));
|
||||||
sendchar(val);
|
|
||||||
address++;
|
address++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -344,64 +312,48 @@ void cmd_loop(void)
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (val == 'F') {
|
if (val == 'F') {
|
||||||
address = readFlashPage(address, size);
|
readFlashPage(address, size);
|
||||||
} else if (val == 'E') {
|
} else if (val == 'E') {
|
||||||
address = readEEpromPage(address, size);
|
readEEpromPage(address, size);
|
||||||
}
|
}
|
||||||
|
address += size;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Chip erase
|
// Chip erase
|
||||||
} else if (val == 'e') {
|
} else if (val == 'e') {
|
||||||
eraseFlash();
|
if (i2c_dev == 0) {
|
||||||
sendchar('\r');
|
eraseFlash();
|
||||||
|
}
|
||||||
|
response = '\r';
|
||||||
|
|
||||||
// Exit upgrade
|
// Exit upgrade
|
||||||
} else if (val == 'E') {
|
} else if (val == 'E') {
|
||||||
boot_timeout = 0;
|
|
||||||
sendchar('\r');
|
sendchar('\r');
|
||||||
_delay_ms(10);
|
if (i2c_dev == 0) {
|
||||||
break;
|
return;
|
||||||
|
|
||||||
// Enter programming mode
|
|
||||||
} else if (val == 'P') {
|
|
||||||
if (i2c_dev != 0) {
|
|
||||||
i2c_start_address(i2c_dev);
|
|
||||||
i2c_master_tx(CMD_SWITCH_APPLICATION);
|
|
||||||
i2c_master_tx(BOOTTYPE_BOOTLOADER);
|
|
||||||
i2c_stop();
|
|
||||||
|
|
||||||
_delay_ms(10);
|
|
||||||
}
|
}
|
||||||
sendchar('\r');
|
|
||||||
|
|
||||||
// Leave programming mode
|
// Enter / Leave programming mode
|
||||||
} else if (val == 'L') {
|
} else if (val == 'P' || val == 'L') {
|
||||||
if (i2c_dev != 0) {
|
if (i2c_dev != 0) {
|
||||||
i2c_start_address(i2c_dev);
|
val = (val == 'P') ? BOOTTYPE_BOOTLOADER : BOOTTYPE_APPLICATION;
|
||||||
i2c_master_tx(CMD_SWITCH_APPLICATION);
|
i2c_switch_app(i2c_dev, val);
|
||||||
i2c_master_tx(BOOTTYPE_APPLICATION);
|
|
||||||
i2c_stop();
|
|
||||||
}
|
}
|
||||||
sendchar('\r');
|
response = '\r';
|
||||||
|
|
||||||
// return programmer type
|
// return programmer type
|
||||||
} else if (val == 'p') {
|
} else if (val == 'p') {
|
||||||
sendchar('S');
|
response = 'S';
|
||||||
|
|
||||||
// Return device type
|
// Return device type
|
||||||
} else if (val == 't') {
|
} else if (val == 't') {
|
||||||
sendchar((i2c_dev == 0) ? OWN_DEVCODE : TWI_DEVCODE);
|
sendchar((i2c_dev == 0) ? OWN_DEVCODE : TWI_DEVCODE);
|
||||||
sendchar(0);
|
response = '\0';
|
||||||
|
|
||||||
// clear and set LED ignored
|
// clear and set LED ignored
|
||||||
} else if ((val == 'x') || (val == 'y')) {
|
} else if ((val == 'x') || (val == 'y') || (val == 'T')) {
|
||||||
recvchar();
|
recvchar();
|
||||||
sendchar('\r');
|
response = '\r';
|
||||||
|
|
||||||
// set device
|
|
||||||
} else if (val == 'T') {
|
|
||||||
recvchar();
|
|
||||||
sendchar('\r');
|
|
||||||
|
|
||||||
// Return software identifier
|
// Return software identifier
|
||||||
} else if (val == 'S') {
|
} else if (val == 'S') {
|
||||||
@ -411,58 +363,37 @@ void cmd_loop(void)
|
|||||||
sendchar('B');
|
sendchar('B');
|
||||||
sendchar('O');
|
sendchar('O');
|
||||||
sendchar('O');
|
sendchar('O');
|
||||||
sendchar('T');
|
response = 'T';
|
||||||
|
|
||||||
// Return Software Version
|
// Return Software Version
|
||||||
} else if (val == 'V' || val == 'v') {
|
} else if (val == 'V' || val == 'v') {
|
||||||
sendchar('0');
|
sendchar('0');
|
||||||
sendchar('8');
|
response = '8';
|
||||||
|
|
||||||
// Return Signature Bytes
|
// Return Signature Bytes
|
||||||
} else if (val == 's') {
|
} else if (val == 's') {
|
||||||
if (i2c_dev != 0) {
|
if (i2c_dev != 0) {
|
||||||
sendchar(chipinfo[2]);
|
sendchar(chipinfo[2]);
|
||||||
sendchar(chipinfo[1]);
|
sendchar(chipinfo[1]);
|
||||||
sendchar(chipinfo[0]);
|
response = chipinfo[0];
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
uint8_t sig[3] = OWN_SIGNATURE;
|
uint8_t sig[3] = OWN_SIGNATURE;
|
||||||
sendchar(sig[2]);
|
sendchar(sig[2]);
|
||||||
sendchar(sig[1]);
|
sendchar(sig[1]);
|
||||||
sendchar(sig[0]);
|
response = sig[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
// set i2c target
|
// set i2c target
|
||||||
} else if (val == '0') {
|
} else if (val == '0') {
|
||||||
i2c_dev = 0;
|
i2c_dev = 0;
|
||||||
sendchar(val);
|
|
||||||
|
|
||||||
} else if (val >= '1' && val <= '4') {
|
} else if (val >= '1' && val <= '4') {
|
||||||
i2c_dev = (val - '0' + TWI_ADDRESS_BASE) << 1;
|
i2c_dev = (val - '0' + TWI_ADDRESS_BASE) << 1;
|
||||||
sendchar(val);
|
|
||||||
sendchar('<');
|
|
||||||
|
|
||||||
i2c_start_address(i2c_dev);
|
i2c_switch_app(i2c_dev, BOOTTYPE_BOOTLOADER);
|
||||||
i2c_master_tx(CMD_SWITCH_APPLICATION);
|
_delay_ms(100);
|
||||||
i2c_master_tx(BOOTTYPE_BOOTLOADER);
|
i2c_print_version(i2c_dev);
|
||||||
i2c_stop();
|
|
||||||
|
|
||||||
for (val = 0; val < 10; val++)
|
|
||||||
_delay_ms(10);
|
|
||||||
|
|
||||||
i2c_start_address(i2c_dev);
|
|
||||||
i2c_master_tx(CMD_READ_VERSION);
|
|
||||||
i2c_start_address(i2c_dev | 0x01);
|
|
||||||
|
|
||||||
uint8_t cnt;
|
|
||||||
for (cnt = 0; cnt < 16; cnt++) {
|
|
||||||
i2c_master_rx(&val, (cnt != 15));
|
|
||||||
sendchar(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
i2c_stop();
|
|
||||||
|
|
||||||
sendchar(',');
|
|
||||||
|
|
||||||
i2c_start_address(i2c_dev);
|
i2c_start_address(i2c_dev);
|
||||||
i2c_master_tx(CMD_READ_MEMORY);
|
i2c_master_tx(CMD_READ_MEMORY);
|
||||||
@ -474,12 +405,7 @@ void cmd_loop(void)
|
|||||||
uint8_t i;
|
uint8_t i;
|
||||||
for (i = 0; i < sizeof(chipinfo); i++) {
|
for (i = 0; i < sizeof(chipinfo); i++) {
|
||||||
uint8_t more = (i < (sizeof(chipinfo) -1));
|
uint8_t more = (i < (sizeof(chipinfo) -1));
|
||||||
i2c_master_rx(&chipinfo[i], more);
|
chipinfo[i] = i2c_master_rx(more);
|
||||||
|
|
||||||
sendchar('0');
|
|
||||||
sendchar('x');
|
|
||||||
print_byte(chipinfo[i]);
|
|
||||||
sendchar(more ? ',' : '>');
|
|
||||||
}
|
}
|
||||||
i2c_stop();
|
i2c_stop();
|
||||||
|
|
||||||
@ -489,39 +415,34 @@ void cmd_loop(void)
|
|||||||
i2c_start_address(i2c_dev);
|
i2c_start_address(i2c_dev);
|
||||||
i2c_master_tx(0x00 + (val - 'k') * 0x10);
|
i2c_master_tx(0x00 + (val - 'k') * 0x10);
|
||||||
i2c_stop();
|
i2c_stop();
|
||||||
|
response = val;
|
||||||
sendchar(val);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// start Application / get Version
|
// get Version
|
||||||
} else if (val == 'I') {
|
} else if (val == 'I') {
|
||||||
if (i2c_dev != 0) {
|
if (i2c_dev != 0) {
|
||||||
i2c_start_address(i2c_dev);
|
i2c_switch_app(i2c_dev, BOOTTYPE_APPLICATION);
|
||||||
i2c_master_tx(CMD_SWITCH_APPLICATION);
|
_delay_ms(100);
|
||||||
i2c_master_tx(BOOTTYPE_APPLICATION);
|
i2c_print_version(i2c_dev);
|
||||||
i2c_stop();
|
|
||||||
|
|
||||||
for (val = 0; val < 10; val++)
|
|
||||||
_delay_ms(10);
|
|
||||||
|
|
||||||
i2c_start_address(i2c_dev);
|
|
||||||
i2c_master_tx(CMD_READ_VERSION);
|
|
||||||
i2c_start_address(i2c_dev | 0x01);
|
|
||||||
|
|
||||||
sendchar('<');
|
|
||||||
uint8_t cnt;
|
|
||||||
for (cnt = 0; cnt < 16; cnt++) {
|
|
||||||
i2c_master_rx(&val, (cnt != 15));
|
|
||||||
sendchar(val);
|
|
||||||
}
|
|
||||||
sendchar('>');
|
|
||||||
i2c_stop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fake MK-TOOL specific stuff
|
||||||
|
} else if (val == 0xAA) {
|
||||||
|
sendchar('M');
|
||||||
|
sendchar('K');
|
||||||
|
sendchar('B');
|
||||||
|
response = 'L';
|
||||||
|
|
||||||
/* ESC */
|
/* ESC */
|
||||||
} else if (val != 0x1b) {
|
} else if (val != 0x1b) {
|
||||||
sendchar('?');
|
response = '?';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (response != 0xFF) {
|
||||||
|
sendchar(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
val = recvchar();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -532,7 +453,6 @@ static void (*jump_to_app)(void) __attribute__ ((noreturn)) = 0x0000;
|
|||||||
* system reset. So disable it as soon as possible.
|
* system reset. So disable it as soon as possible.
|
||||||
* automagically called on startup
|
* automagically called on startup
|
||||||
*/
|
*/
|
||||||
#if defined (__AVR_ATmega88__) || defined (__AVR_ATmega168__)
|
|
||||||
void disable_wdt_timer(void) __attribute__((naked, section(".init3")));
|
void disable_wdt_timer(void) __attribute__((naked, section(".init3")));
|
||||||
void disable_wdt_timer(void)
|
void disable_wdt_timer(void)
|
||||||
{
|
{
|
||||||
@ -540,17 +460,15 @@ void disable_wdt_timer(void)
|
|||||||
WDTCSR = (1<<WDCE) | (1<<WDE);
|
WDTCSR = (1<<WDCE) | (1<<WDE);
|
||||||
WDTCSR = (0<<WDE);
|
WDTCSR = (0<<WDE);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
/* linking without vectors, still need __vector_default */
|
||||||
|
void __vector_default(void) {}
|
||||||
|
|
||||||
int main(void) __attribute__ ((noreturn));
|
int main(void) __attribute__ ((noreturn));
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
DDRB = LED_GN | LED_RT;
|
DDRB = LED_GN | LED_RT;
|
||||||
PORTB = LED_GN | LED_RT;
|
PORTB = LED_RT;
|
||||||
|
|
||||||
/* move interrupt-vectors to bootloader */
|
|
||||||
MCUCR = (1<<IVCE);
|
|
||||||
MCUCR = (1<<IVSEL);
|
|
||||||
|
|
||||||
/* Set baudrate */
|
/* Set baudrate */
|
||||||
UBRR0H = (UART_CALC_BAUDRATE(BAUDRATE)>>8) & 0xFF;
|
UBRR0H = (UART_CALC_BAUDRATE(BAUDRATE)>>8) & 0xFF;
|
||||||
@ -560,35 +478,32 @@ int main(void)
|
|||||||
UCSR0B = (1<<TXEN0) | (1<<RXEN0);
|
UCSR0B = (1<<TXEN0) | (1<<RXEN0);
|
||||||
UCSR0C = (1<<UCSZ01) | (1<<UCSZ00);
|
UCSR0C = (1<<UCSZ01) | (1<<UCSZ00);
|
||||||
|
|
||||||
/* timer0: running with F_CPU/1024 */
|
|
||||||
TCCR0B = (1<<CS02) | (1<<CS00);
|
|
||||||
|
|
||||||
/* enable timer0 OVF interrupt */
|
|
||||||
TIMSK0 |= (1<<TOIE0);
|
|
||||||
|
|
||||||
/* enable TWI interface */
|
/* enable TWI interface */
|
||||||
TWBR = ((F_CPU/TWI_CLK)-16)/2;
|
TWBR = ((F_CPU/TWI_CLK)-16)/2;
|
||||||
TWCR = (1<<TWSTO) | (1<<TWEN);
|
TWCR = (1<<TWSTO) | (1<<TWEN);
|
||||||
|
|
||||||
sei();
|
uint8_t prev = 0x00;
|
||||||
|
uint8_t boot_timeout = 100;
|
||||||
|
|
||||||
while (boot_timeout > 0) {
|
while (boot_timeout-- > 0) {
|
||||||
if (UCSR0A & (1<<RXC0))
|
if (UCSR0A & (1<<RXC0)) {
|
||||||
if (recvchar() == 'S')
|
uint8_t val = recvchar();
|
||||||
cmd_loop();
|
|
||||||
|
if (prev == 0x1B && (val == 0xAA || val == 'S')) {
|
||||||
|
PORTB |= LED_GN;
|
||||||
|
cmd_loop(val);
|
||||||
|
boot_timeout = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
prev = val;
|
||||||
|
}
|
||||||
|
_delay_ms(10);
|
||||||
|
|
||||||
|
if (!(boot_timeout & 0x03))
|
||||||
|
PORTB ^= LED_GN;
|
||||||
}
|
}
|
||||||
|
|
||||||
cli();
|
|
||||||
|
|
||||||
/* move interrupt-vectors to applicaion */
|
|
||||||
MCUCR = (1<<IVCE);
|
|
||||||
MCUCR = (0<<IVSEL);
|
|
||||||
|
|
||||||
PORTB = LED_RT;
|
PORTB = LED_RT;
|
||||||
|
|
||||||
uint8_t i;
|
|
||||||
for (i = 0; i < 10; i++)
|
|
||||||
_delay_ms(10);
|
|
||||||
|
|
||||||
jump_to_app();
|
jump_to_app();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user