diff --git a/Makefile b/Makefile index e7243f0..7fd3702 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ BOOTLOADER_START=0x7800 AVRDUDE_MCU=m32 endif -DEFS = -DBOOTLOADER_START=$(BOOTLOADER_START) +DEFS = -DBOOTLOADER_START=$(BOOTLOADER_START) -DOSCCAL_VALUE=0xAA LIBS = # Override is only needed by avr-lib build system. diff --git a/main.c b/main.c index 6635b2e..2552431 100644 --- a/main.c +++ b/main.c @@ -42,17 +42,14 @@ /* 40 * 25ms */ #define TIMEOUT 40 -#define LED_INIT() DDRD = (1<= BOOTLOADER_START) - return; + uint16_t address = pagestart; + uint8_t pagesize = SPM_PAGESIZE; boot_page_erase(pagestart); boot_spm_busy_wait(); do { - uint16_t data = *p++; - data |= *p++ << 8; - boot_page_fill(para_address, data); + uint16_t dataword; - para_address += 2; - size -= 2; - } while (size); + dataword = (size-- != 0) ? *data++ : 0xFF; + dataword |= ((size-- != 0) ? *data++ : 0xFF) << 8; + boot_page_fill(address, dataword); + + address += 2; + pagesize -= 2; + } while (pagesize); boot_page_write(pagestart); boot_spm_busy_wait(); boot_rww_enable(); } -static uint8_t read_eeprom_byte(void) +#if (EEPROM_SUPPORT) +static uint8_t read_eeprom_byte(uint16_t address) { - EEARL = para_address; - EEARH = (para_address >> 8); + EEARL = address; + EEARH = (address >> 8); EECR |= (1<> 8); - EEDR = *val++; - para_address++; - para_size--; + while (size--) { + EEARL = address; + EEARH = (address >> 8); + address++; + EEDR = *data++; #if defined (__AVR_ATmega32__) EECR |= (1<= 3 is payload */ + } else if ((rx_bcnt -3) < rx_length) { + uint16_t pos = rx_bcnt -3; - } else if (((rx_cmd == CMD_READ_MEMORY) || (rx_cmd == CMD_WRITE_MEMORY)) && - ((rx_bcnt >= 3) && (rx_bcnt <= 7)) - ) { - switch (rx_bcnt) { - case 3: - para_memtype = data; - break; + if ((rx_cmd == CMD_SWITCH_MODE) && (pos == 0)) { + para_mode = data; - case 4: - case 5: - para_address = (para_address << 8) | data; - break; + } else if ((rx_cmd == CMD_READ_MEMORY) || (rx_cmd == CMD_WRITE_MEMORY)) { + switch (pos) { + case 0: + para_memtype = data; + break; - case 6: - case 7: - para_size = (para_size << 8) | data; - break; + case 1: + case 2: + para_address = (para_address << 8) | data; + break; - default: - break; - } + case 3: + case 4: + para_size = (para_size << 8) | data; + break; - } else if ((rx_cmd == CMD_WRITE_MEMORY) && (rx_bcnt > 7) && (rx_bcnt <= (rx_length +2))) { - if ((rx_bcnt -8) < sizeof(pagebuf)) { - pagebuf[(rx_bcnt -8)] = data; + default: + pos -= 5; + if ((rx_cmd == CMD_WRITE_MEMORY) && (pos < sizeof(pagebuf))) { + pagebuf[pos] = data; + } + break; + } } } - if (rx_bcnt == (rx_length +2)) { + /* last byte received */ + if ((rx_bcnt -2) == rx_length) { /* setup response */ tx_bcnt = 0; tx_cmd = rx_cmd; @@ -311,24 +312,28 @@ ISR(USART_RXC_vect) tx_length = 0; tx_cause = CAUSE_INVALID_PARAMETER; - /* writes must use pagesize */ + /* writes must pagesize aligned */ } else if (tx_cmd == CMD_WRITE_MEMORY) { - if (para_size == SPM_PAGESIZE) { - write_flash_page(); + if (((para_address & (SPM_PAGESIZE -1)) == 0x00) && + (para_size <= SPM_PAGESIZE) + ) { + write_flash_page(para_address, pagebuf, para_size); + para_address += para_size; } else { tx_cause = CAUSE_INVALID_PARAMETER; } } - +#if (EEPROM_SUPPORT) } else if (para_memtype == MEMTYPE_EEPROM) { if ((para_address > (E2END +1)) || ((para_address + para_size) > (E2END +1))) { tx_cause = CAUSE_INVALID_PARAMETER; } else if (tx_cmd == CMD_WRITE_MEMORY) { - write_eeprom_page(); + write_eeprom_page(para_address, pagebuf, para_size); + para_address += para_size; } - +#endif /*(EEPROM_SUPPORT) */ } else { tx_length = 0; tx_cause = CAUSE_INVALID_PARAMETER; @@ -352,7 +357,8 @@ ISR(USART_UDRE_vect) { if (tx_bcnt == 0) { /* enable RS485 transmitter */ - PORTD |= (1<