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)
This commit is contained in:
Olaf Rempel 2006-05-20 00:06:27 +02:00
parent b29674a1f2
commit b253baf838
2 changed files with 122 additions and 111 deletions

View File

@ -13,6 +13,12 @@
#define APP_END (FLASHEND - (BOOTSIZE * 2)) #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__) #if defined(__AVR_ATmega169__)
#include "mega169.h" #include "mega169.h"

171
main.c
View File

@ -94,14 +94,7 @@
#include "chipdef.h" #include "chipdef.h"
#define UART_RX_BUFFER_SIZE SPM_PAGESIZE uint8_t gBuffer[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;
void sendchar(uint8_t data) void sendchar(uint8_t data)
{ {
@ -115,105 +108,106 @@ uint8_t recvchar(void)
return UART_DATA; return UART_DATA;
} }
uint8_t BufferLoad(uint16_t size, uint8_t mem) static inline void eraseFlash(void)
{ {
uint16_t data, cnt; // erase only main section (bootloader protection)
uint32_t tempaddress; 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) if (cnt < size)
gBuffer[cnt] = recvchar(); gBuffer[cnt] = recvchar();
else else
gBuffer[cnt] = 0xFF; gBuffer[cnt] = 0xFF;
} }
cnt = 0; }
tempaddress = address; // Store address in page static inline uint16_t writeFlashPage(uint16_t waddr, pagebuf_t size)
{
uint32_t pagestart = waddr<<1;
uint32_t baddr = pagestart;
uint16_t data;
pagebuf_t cnt = 0;
my_eeprom_busy_wait();
if (device == DEVTYPE) {
// Flash
if (mem == 'F') {
do { do {
data = gBuffer[cnt++]; data = gBuffer[cnt++];
data |= (gBuffer[cnt++] << 8); data |= gBuffer[cnt++] << 8;
boot_page_fill(address, data); // call asm routine. boot_page_fill(baddr, data); // call asm routine.
address = address +2; // Select next word in memory baddr += 2; // Select next word in memory
size -= 2; // Reduce number of bytes to write by two size -= 2; // Reduce number of bytes to write by two
} while (size); // Loop until all bytes written } while (size); // Loop until all bytes written
/* commented out since not compatible with mega8 - boot_page_write(pagestart);
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_spm_busy_wait();
boot_rww_enable(); // Re-enable the RWW section boot_rww_enable(); // Re-enable the RWW section
/* commented out since not compatible with mega8 return baddr>>1;
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 static inline uint16_t writeEEpromPage(uint16_t address, pagebuf_t size)
if (mem == 'E') { {
address >>= 1; pagebuf_t cnt = 0;
do { do {
EEARL = address; // Setup EEPROM address EEARL = address; // Setup EEPROM address
EEARH = (address >> 8); EEARH = (address >> 8);
address++; // Select next byte
EEDR = gBuffer[cnt++]; EEDR = gBuffer[cnt++];
address++; // Select next byte
EECR |= (1<<EEMWE); // Write data into EEPROM EECR |= (1<<EEMWE); // Write data into EEPROM
EECR |= (1<<EEWE); EECR |= (1<<EEWE);
eeprom_busy_wait();
while (EECR & (1<<EEWE)); // Wait for EEPROM write to finish
size--; // Decreas number of bytes to write size--; // Decreas number of bytes to write
} while (size); // Loop until all bytes written } while (size); // Loop until all bytes written
}
return '\r'; // Report programming OK return address;
}
return 0; // Report programming failed
} }
void BlockRead(uint16_t size, uint16_t mem) static inline uint16_t readFlashPage(uint16_t waddr, pagebuf_t size)
{ {
uint32_t baddr = waddr<<1;
uint16_t data; uint16_t data;
my_eeprom_busy_wait(); do {
#if defined(RAMPZ)
data = pgm_read_word_far(baddr);
#else
data = pgm_read_word_near(baddr);
#endif
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
// Read EEPROM return baddr>>1;
if (mem == 'E') { }
// address>>=1; // not needed here - hmm, somehow inconsistant TODO
static inline uint16_t readEEpromPage(uint16_t address, pagebuf_t size)
{
do { do {
EEARL = address; // Setup EEPROM address EEARL = address; // Setup EEPROM address
EEARH = (address >> 8); EEARH = (address >> 8);
address++; // Select next EEPROM byte
EECR |= (1<<EERE); // Read EEPROM EECR |= (1<<EERE); // Read EEPROM
address++; // Select next EEPROM byte
sendchar(EEDR); // Transmit EEPROM data to PC sendchar(EEDR); // Transmit EEPROM data to PC
size--; // Decrease number of bytes to read size--; // Decrease number of bytes to read
} while (size); // Repeat until all block has been read } while (size); // Repeat until all block has been read
// Read Flash
} else { return address;
do {
#if defined(RAMPZ)
data = pgm_read_word_far(address);
#else
data = pgm_read_word_near((uint16_t)address);
#endif
sendchar((unsigned char)data); //send LSB
sendchar((unsigned char)(data >> 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
}
} }
uint8_t read_fuse_lock(uint16_t addr, uint8_t mode) uint8_t read_fuse_lock(uint16_t addr, uint8_t mode)
@ -250,7 +244,8 @@ void (*jump_to_app)(void) = 0x0000;
int main(void) int main(void)
{ {
uint8_t val; uint16_t address = 0;
uint8_t device = 0, val;
#ifdef START_POWERSAVE #ifdef START_POWERSAVE
uint8_t OK = 1; uint8_t OK = 1;
@ -368,44 +363,54 @@ int main(void)
} else if (val == 'A') { } else if (val == 'A') {
address = recvchar(); //read address 8 MSB address = recvchar(); //read address 8 MSB
address = (address<<8) | recvchar(); address = (address<<8) | recvchar();
address = address<<1; // !! convert from word address to byte address
sendchar('\r'); sendchar('\r');
// Buffer load support // Buffer load support
} else if (val == 'b') { } else if (val == 'b') {
sendchar('Y'); // Report buffer load supported sendchar('Y'); // Report buffer load supported
sendchar((UART_RX_BUFFER_SIZE >> 8) & 0xFF); // Report buffer size in bytes sendchar((sizeof(gBuffer) >> 8) & 0xFF); // Report buffer size in bytes
sendchar(UART_RX_BUFFER_SIZE & 0xFF); sendchar(sizeof(gBuffer) & 0xFF);
// Start buffer load // Start buffer load
} else if (val == 'B') { } else if (val == 'B') {
uint16_t size; pagebuf_t size;
size = recvchar() << 8; // Load high byte of buffersize size = recvchar() << 8; // Load high byte of buffersize
size |= recvchar(); // Load low byte of buffersize size |= recvchar(); // Load low byte of buffersize
val = recvchar(); // Load memory type ('E' or 'F') 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 // Block read
} else if (val == 'g') { } else if (val == 'g') {
uint16_t size; pagebuf_t size;
size = recvchar() << 8; // Load high byte of buffersize size = recvchar() << 8; // Load high byte of buffersize
size |= recvchar(); // Load low byte of buffersize size |= recvchar(); // Load low byte of buffersize
val = recvchar(); // Get memtype 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 // Chip erase
} else if (val == 'e') { } else if (val == 'e') {
if (device == DEVTYPE) { if (device == DEVTYPE)
// erase only main section (bootloader protection) eraseFlash();
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();
sendchar('\r'); sendchar('\r');
// Exit upgrade // Exit upgrade