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))
|
#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
171
main.c
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user