From b253baf8382e085600ac72087ff6fc85c9c4874f Mon Sep 17 00:00:00 2001 From: Olaf Rempel Date: Sat, 20 May 2006 00:06:27 +0200 Subject: [PATCH] optimize functions - split BlockLoad() into recvBuffer(), writeFlashPage() and writeEEpromPage() - split BlockRead() into readFlashPage() and readEEpromPage() - make eraseFlash() a inline too - remove global variables - fix byte/word addressing - use typedef for buffer index (results in uint8_t on most cpus) --- chipdef.h | 6 ++ main.c | 227 ++++++++++++++++++++++++++++-------------------------- 2 files changed, 122 insertions(+), 111 deletions(-) diff --git a/chipdef.h b/chipdef.h index a27d98f..a6197fd 100644 --- a/chipdef.h +++ b/chipdef.h @@ -13,6 +13,12 @@ #define APP_END (FLASHEND - (BOOTSIZE * 2)) +#if (SPM_PAGESIZE > UINT8_MAX) +typedef uint16_t pagebuf_t; +#else +typedef uint8_t pagebuf_t; +#endif + #if defined(__AVR_ATmega169__) #include "mega169.h" diff --git a/main.c b/main.c index dbd1174..8e0c39c 100644 --- a/main.c +++ b/main.c @@ -94,14 +94,7 @@ #include "chipdef.h" -#define UART_RX_BUFFER_SIZE SPM_PAGESIZE -uint8_t gBuffer[UART_RX_BUFFER_SIZE]; - -#define eeprom_is_ready() bit_is_clear(EECR, EEWE) -#define my_eeprom_busy_wait() do{}while(!eeprom_is_ready()) - -uint32_t address; -uint8_t device; +uint8_t gBuffer[SPM_PAGESIZE]; void sendchar(uint8_t data) { @@ -115,105 +108,106 @@ uint8_t recvchar(void) return UART_DATA; } -uint8_t BufferLoad(uint16_t size, uint8_t mem) +static inline void eraseFlash(void) { - uint16_t data, cnt; - uint32_t tempaddress; + // erase only main section (bootloader protection) + uint32_t addr = 0; + while (APP_END > addr) { + boot_page_erase(addr); // Perform page erase + boot_spm_busy_wait(); // Wait until the memory is erased. + addr += SPM_PAGESIZE; + } + boot_rww_enable(); +} - for (cnt = 0; cnt < UART_RX_BUFFER_SIZE; cnt++) { +static inline void recvBuffer(pagebuf_t size) +{ + pagebuf_t cnt; + for (cnt = 0; cnt < sizeof(gBuffer); cnt++) { if (cnt < size) gBuffer[cnt] = recvchar(); else gBuffer[cnt] = 0xFF; } - cnt = 0; - - tempaddress = address; // Store address in page - - my_eeprom_busy_wait(); - - if (device == DEVTYPE) { - // Flash - if (mem == 'F') { - do { - data = gBuffer[cnt++]; - data |= (gBuffer[cnt++] << 8); - boot_page_fill(address, data); // call asm routine. - - address = address +2; // Select next word in memory - size -= 2; // Reduce number of bytes to write by two - } while(size); // Loop until all bytes written - - /* commented out since not compatible with mega8 - - secondary benefit: saves memory - tempaddress &= 0xFF80; // Ensure the address points to the first byte in the page - */ - - boot_page_write(tempaddress); - boot_spm_busy_wait(); - boot_rww_enable(); // Re-enable the RWW section - - /* commented out since not compatible with mega8 - if (address != (address & 0xFF80)) - { // Ensure that the address points to the beginning of the next page - address &= 0xFF80; - address += SPM_PAGESIZE; - } - */ - } // End FLASH - - // Start EEPROM - if (mem == 'E') { - address >>= 1; - do { - EEARL = address; // Setup EEPROM address - EEARH = (address >> 8); - address++; // Select next byte - EEDR = gBuffer[cnt++]; - - EECR |= (1<>1; +} + +static inline uint16_t writeEEpromPage(uint16_t address, pagebuf_t size) +{ + pagebuf_t cnt = 0; + + do { + EEARL = address; // Setup EEPROM address + EEARH = (address >> 8); + EEDR = gBuffer[cnt++]; + address++; // Select next byte + + EECR |= (1<>=1; // not needed here - hmm, somehow inconsistant TODO - do { - EEARL = address; // Setup EEPROM address - EEARH = (address >> 8); - address++; // Select next EEPROM byte - EECR |= (1<> 8)); //send MSB - address += 2; // Select next word in memory - size -= 2; // Subtract two bytes from number of bytes to read - } while (size); // Repeat until all block has been read - } + sendchar(data); // send LSB + sendchar((data >> 8)); // send MSB + baddr += 2; // Select next word in memory + size -= 2; // Subtract two bytes from number of bytes to read + } while (size); // Repeat until all block has been read + + return baddr>>1; +} + +static inline uint16_t readEEpromPage(uint16_t address, pagebuf_t size) +{ + do { + EEARL = address; // Setup EEPROM address + EEARH = (address >> 8); + EECR |= (1<> 8) & 0xFF); // Report buffer size in bytes - sendchar(UART_RX_BUFFER_SIZE & 0xFF); + sendchar((sizeof(gBuffer) >> 8) & 0xFF); // Report buffer size in bytes + sendchar(sizeof(gBuffer) & 0xFF); // Start buffer load } else if (val == 'B') { - uint16_t size; + pagebuf_t size; size = recvchar() << 8; // Load high byte of buffersize size |= recvchar(); // Load low byte of buffersize val = recvchar(); // Load memory type ('E' or 'F') - sendchar(BufferLoad(size, val)); // Start downloading of buffer + recvBuffer(size); + + if (device == DEVTYPE) { + if (val == 'F') { + address = writeFlashPage(address, size); + + } else if (val == 'E') { + address = writeEEpromPage(address, size); + } + sendchar('\r'); + + } else { + sendchar(0); + } // Block read } else if (val == 'g') { - uint16_t size; + pagebuf_t size; size = recvchar() << 8; // Load high byte of buffersize size |= recvchar(); // Load low byte of buffersize val = recvchar(); // Get memtype - BlockRead(size, val); // Perform the block read + + if (val == 'F') { + address = readFlashPage(address, size); + + } else if (val == 'E') { + address = readEEpromPage(address, size); + } // Chip erase } else if (val == 'e') { - if (device == DEVTYPE) { - // erase only main section (bootloader protection) - uint32_t addr = 0; - while (APP_END > addr) { - boot_page_erase(addr); // Perform page erase - boot_spm_busy_wait(); // Wait until the memory is erased. - addr += SPM_PAGESIZE; - } - } - boot_rww_enable(); + if (device == DEVTYPE) + eraseFlash(); + sendchar('\r'); // Exit upgrade