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:
parent
b29674a1f2
commit
b253baf838
@ -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
227
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<<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
|
||||
|
Loading…
Reference in New Issue
Block a user