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))
#if (SPM_PAGESIZE > UINT8_MAX)
typedef uint16_t pagebuf_t;
#else
typedef uint8_t pagebuf_t;
#endif
#if defined(__AVR_ATmega169__)
#include "mega169.h"

227
main.c
View File

@ -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<<EEMWE); // Write data into EEPROM
EECR |= (1<<EEWE);
while (EECR & (1<<EEWE)); // Wait for EEPROM write to finish
size--; // Decreas number of bytes to write
} while(size); // Loop until all bytes written
}
return '\r'; // Report programming OK
}
return 0; // Report programming failed
}
void BlockRead(uint16_t size, uint16_t mem)
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;
do {
data = gBuffer[cnt++];
data |= gBuffer[cnt++] << 8;
boot_page_fill(baddr, data); // call asm routine.
baddr += 2; // Select next word in memory
size -= 2; // Reduce number of bytes to write by two
} while (size); // Loop until all bytes written
boot_page_write(pagestart);
boot_spm_busy_wait();
boot_rww_enable(); // Re-enable the RWW section
return baddr>>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<<EEMWE); // Write data into EEPROM
EECR |= (1<<EEWE);
eeprom_busy_wait();
size--; // Decreas number of bytes to write
} while (size); // Loop until all bytes written
return address;
}
static inline uint16_t readFlashPage(uint16_t waddr, pagebuf_t size)
{
uint32_t baddr = waddr<<1;
uint16_t data;
my_eeprom_busy_wait();
// Read EEPROM
if (mem == 'E') {
// address>>=1; // not needed here - hmm, somehow inconsistant TODO
do {
EEARL = address; // Setup EEPROM address
EEARH = (address >> 8);
address++; // Select next EEPROM byte
EECR |= (1<<EERE); // Read EEPROM
sendchar(EEDR); // Transmit EEPROM data to PC
size--; // Decrease number of bytes to read
} while (size); // Repeat until all block has been read
// Read Flash
} else {
do {
do {
#if defined(RAMPZ)
data = pgm_read_word_far(address);
data = pgm_read_word_far(baddr);
#else
data = pgm_read_word_near((uint16_t)address);
data = pgm_read_word_near(baddr);
#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
}
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<<EERE); // Read EEPROM
address++; // Select next EEPROM byte
sendchar(EEDR); // Transmit EEPROM data to PC
size--; // Decrease number of bytes to read
} while (size); // Repeat until all block has been read
return address;
}
uint8_t read_fuse_lock(uint16_t addr, uint8_t mode)
@ -250,7 +244,8 @@ void (*jump_to_app)(void) = 0x0000;
int main(void)
{
uint8_t val;
uint16_t address = 0;
uint8_t device = 0, val;
#ifdef START_POWERSAVE
uint8_t OK = 1;
@ -368,44 +363,54 @@ int main(void)
} else if (val == 'A') {
address = recvchar(); //read address 8 MSB
address = (address<<8) | recvchar();
address = address<<1; // !! convert from word address to byte address
sendchar('\r');
// Buffer load support
} else if (val == 'b') {
sendchar('Y'); // Report buffer load supported
sendchar((UART_RX_BUFFER_SIZE >> 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