summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJenna Fox <a@creativepony.com>2012-09-23 16:24:36 +1000
committerJenna Fox <a@creativepony.com>2012-09-23 16:24:36 +1000
commitf31bab682d6e73f2b76e8f2ce4caf41884681a7e (patch)
treeea107306276106d094247baa170497bae38bca0c
parent5630437df41b8d2f52f115e3ee21706f8d6648f4 (diff)
downloadmicronucleus-f31bab682d6e73f2b76e8f2ce4caf41884681a7e.tar.gz
micronucleus-f31bab682d6e73f2b76e8f2ce4caf41884681a7e.tar.bz2
micronucleus-f31bab682d6e73f2b76e8f2ce4caf41884681a7e.zip
cleaned up main loop area (untested)
-rw-r--r--firmware/main.c249
1 files changed, 108 insertions, 141 deletions
diff --git a/firmware/main.c b/firmware/main.c
index a9e5b8b..d28b743 100644
--- a/firmware/main.c
+++ b/firmware/main.c
@@ -23,18 +23,6 @@ static void leaveBootloader() __attribute__((__noreturn__));
#include "bootloaderconfig.h"
#include "usbdrv/usbdrv.c"
-/* ------------------------------------------------------------------------ */
-
-/* Request constants used by USBasp */
-#define USBASP_FUNC_CONNECT 1
-#define USBASP_FUNC_DISCONNECT 2
-#define USBASP_FUNC_TRANSMIT 3
-#define USBASP_FUNC_READFLASH 4
-#define USBASP_FUNC_ENABLEPROG 5
-#define USBASP_FUNC_WRITEFLASH 6
-#define USBASP_FUNC_READEEPROM 7
-#define USBASP_FUNC_WRITEEEPROM 8
-#define USBASP_FUNC_SETLONGADDRESS 9
/* ------------------------------------------------------------------------ */
@@ -45,13 +33,6 @@ static void leaveBootloader() __attribute__((__noreturn__));
# define uint unsigned int
#endif
-/* defaults if not in config file: */
-#ifndef HAVE_EEPROM_PAGED_ACCESS
-# define HAVE_EEPROM_PAGED_ACCESS 0
-#endif
-#ifndef HAVE_EEPROM_BYTE_ACCESS
-# define HAVE_EEPROM_BYTE_ACCESS 0
-#endif
#ifndef BOOTLOADER_CAN_EXIT
# define BOOTLOADER_CAN_EXIT 0
#endif
@@ -72,76 +53,76 @@ static void leaveBootloader() __attribute__((__noreturn__));
/* ------------------------------------------------------------------------ */
-#if (FLASHEND) > 0xffff /* we need long addressing */
-# define CURRENT_ADDRESS currentAddress.l
-# define addr_t ulong
-#else
-# define CURRENT_ADDRESS currentAddress.w[0]
-# define addr_t uint
-#endif
+#define addr_t uint
typedef union longConverter{
addr_t l;
uint w[sizeof(addr_t)/2];
uchar b[sizeof(addr_t)];
-}longConverter_t;
-
-#ifdef TINY85MODE
-static uchar flashPageLoaded = 0;
-#if HAVE_CHIP_ERASE
-static uchar eraseRequested = 0;
-#endif
-static uchar appWriteComplete = 0;
+} longConverter_t;
+
+// outstanding events for the mainloop to deal with
+static uchar events = 0;
+#define EVENT_ERASE_APPLICATION 1
+#define EVENT_WRITE_PAGE 2
+#define EVENT_EXIT_BOOTLOADER 4
+
+//static uchar flashPageLoaded = 0;
+//#if HAVE_CHIP_ERASE
+//static uchar eraseRequested = 0;
+//#endif
+//static uchar appWriteComplete = 0;
static uint16_t writeSize;
static uint16_t vectorTemp[2];
-static uchar needToErase = 0;
-#endif
+//static uchar needToErase = 0;
+//#endif
-#ifdef APPCHECKSUM
-static uchar connectedToPc = 0;
-static uint16_t checksum = 0;
-#endif
+// #ifdef APPCHECKSUM
+// static uchar connectedToPc = 0;
+// static uint16_t checksum = 0;
+// #endif
-static uchar requestBootLoaderExit;
+//static uchar requestBootLoaderExit;
static longConverter_t currentAddress; /* in bytes */
static uchar bytesRemaining;
static uchar isLastPage;
-#if HAVE_EEPROM_PAGED_ACCESS
-static uchar currentRequest;
-#else
+//#if HAVE_EEPROM_PAGED_ACCESS
+//static uchar currentRequest;
+//#else
static const uchar currentRequest = 0;
-#endif
-
-static const uchar signatureBytes[4] = {
-#ifdef SIGNATURE_BYTES
- SIGNATURE_BYTES
-#elif defined (__AVR_ATmega8__) || defined (__AVR_ATmega8HVA__)
- 0x1e, 0x93, 0x07, 0
-#elif defined (__AVR_ATmega48__) || defined (__AVR_ATmega48P__)
- 0x1e, 0x92, 0x05, 0
-#elif defined (__AVR_ATmega88__) || defined (__AVR_ATmega88P__)
- 0x1e, 0x93, 0x0a, 0
-#elif defined (__AVR_ATmega168__) || defined (__AVR_ATmega168P__)
- 0x1e, 0x94, 0x06, 0
-#elif defined (__AVR_ATmega328P__)
- 0x1e, 0x95, 0x0f, 0
-#else
-# error "Device signature is not known, please edit main.c!"
-#endif
-};
+//#endif
+
+// static const uchar signatureBytes[4] = {
+// #ifdef SIGNATURE_BYTES
+// SIGNATURE_BYTES
+// #elif defined (__AVR_ATmega8__) || defined (__AVR_ATmega8HVA__)
+// 0x1e, 0x93, 0x07, 0
+// #elif defined (__AVR_ATmega48__) || defined (__AVR_ATmega48P__)
+// 0x1e, 0x92, 0x05, 0
+// #elif defined (__AVR_ATmega88__) || defined (__AVR_ATmega88P__)
+// 0x1e, 0x93, 0x0a, 0
+// #elif defined (__AVR_ATmega168__) || defined (__AVR_ATmega168P__)
+// 0x1e, 0x94, 0x06, 0
+// #elif defined (__AVR_ATmega328P__)
+// 0x1e, 0x95, 0x0f, 0
+// #else
+// # error "Device signature is not known, please edit main.c!"
+// #endif
+// };
+
+#define fireEvent(event) events |= (event)
+#define isEvent(event) (events & (event))
+#define clearEvents() events = 0
/* ------------------------------------------------------------------------ */
-#ifdef TINY85MODE
-static void writeFlashPage(void)
-{
- if(needToErase)
- {
- boot_page_erase(CURRENT_ADDRESS - 2);
+static void writeFlashPage(void) {
+ if (needToErase) {
+ boot_page_erase(currentAddress - 2);
boot_spm_busy_wait();
}
- boot_page_write(CURRENT_ADDRESS - 2);
+ boot_page_write(currentAddress - 2);
boot_spm_busy_wait(); // Wait until the memory is written.
needToErase = 0;
@@ -162,19 +143,19 @@ static void writeFlashPage(void)
static void writeWordToPageBuffer(uint16_t data)
{
// first two interrupt vectors get replaced with a jump to the bootloader vector table
- if(CURRENT_ADDRESS == (RESET_VECTOR_OFFSET * 2) || CURRENT_ADDRESS == (USBPLUS_VECTOR_OFFSET * 2))
+ if(currentAddress == (RESET_VECTOR_OFFSET * 2) || currentAddress == (USBPLUS_VECTOR_OFFSET * 2))
data = 0xC000 + (BOOTLOADER_ADDRESS/2) - 1;
// write 2's complement of checksum
#ifdef APPCHECKSUM
- if(CURRENT_ADDRESS == BOOTLOADER_ADDRESS - APPCHECKSUM_POSITION)
+ if(currentAddress == BOOTLOADER_ADDRESS - APPCHECKSUM_POSITION)
data = (uint8_t)(~checksum + 1);
#endif
- if(CURRENT_ADDRESS == BOOTLOADER_ADDRESS - TINYVECTOR_RESET_OFFSET)
+ if(currentAddress == BOOTLOADER_ADDRESS - TINYVECTOR_RESET_OFFSET)
data = vectorTemp[0] + ((FLASHEND + 1) - BOOTLOADER_ADDRESS)/2 + 2 + RESET_VECTOR_OFFSET;
- if(CURRENT_ADDRESS == BOOTLOADER_ADDRESS - TINYVECTOR_USBPLUS_OFFSET)
+ if(currentAddress == BOOTLOADER_ADDRESS - TINYVECTOR_USBPLUS_OFFSET)
data = vectorTemp[1] + ((FLASHEND + 1) - BOOTLOADER_ADDRESS)/2 + 1 + USBPLUS_VECTOR_OFFSET;
#ifdef APPCHECKSUM
@@ -184,27 +165,27 @@ static void writeWordToPageBuffer(uint16_t data)
// clear page buffer as a precaution before filling the buffer on the first page
// TODO: maybe clear on the first byte of every page?
- if(CURRENT_ADDRESS == 0x0000)
+ if(currentAddress == 0x0000)
__boot_page_fill_clear();
cli();
- boot_page_fill(CURRENT_ADDRESS, data);
+ boot_page_fill(currentAddress, data);
sei();
// only need to erase if there is data already in the page that doesn't match what we're programming
- if(pgm_read_word(CURRENT_ADDRESS) != data && pgm_read_word(CURRENT_ADDRESS) != 0xFFFF)
+ if(pgm_read_word(currentAddress) != data && pgm_read_word(currentAddress) != 0xFFFF)
needToErase = 1;
- CURRENT_ADDRESS += 2;
+ currentAddress += 2;
}
static void fillFlashWithVectors(void)
{
int16_t i;
- // fill all or remainder of page starting at CURRENT_ADDRESS with 0xFFs, unless we're
+ // fill all or remainder of page starting at currentAddress with 0xFFs, unless we're
// at a special address that needs a vector replaced
- for (i = CURRENT_ADDRESS % SPM_PAGESIZE; i < SPM_PAGESIZE; i += 2)
+ for (i = currentAddress % SPM_PAGESIZE; i < SPM_PAGESIZE; i += 2)
{
writeWordToPageBuffer(0xFFFF);
}
@@ -216,13 +197,13 @@ static void fillFlashWithVectors(void)
static void eraseApplication(void)
{
// erase all pages starting from end of application section down to page 1 (leaving page 0)
- CURRENT_ADDRESS = BOOTLOADER_ADDRESS - SPM_PAGESIZE;
- while(CURRENT_ADDRESS != 0x0000)
+ currentAddress = BOOTLOADER_ADDRESS - SPM_PAGESIZE;
+ while(currentAddress != 0x0000)
{
- boot_page_erase(CURRENT_ADDRESS);
+ boot_page_erase(currentAddress);
boot_spm_busy_wait();
- CURRENT_ADDRESS -= SPM_PAGESIZE;
+ currentAddress -= SPM_PAGESIZE;
}
// erase and load page 0 with vectors
@@ -259,7 +240,7 @@ static void (*nullVector)(void) __attribute__((__noreturn__));
static inline __attribute__((noreturn)) void leaveBootloader(void)
{
- DBG1(0x01, 0, 0);
+ //DBG1(0x01, 0, 0);
bootLoaderExit();
cli();
USB_INTR_ENABLE = 0;
@@ -269,8 +250,8 @@ static inline __attribute__((noreturn)) void leaveBootloader(void)
// make sure remainder of flash is erased and write checksum and application reset vectors
if(appWriteComplete)
{
- CURRENT_ADDRESS = writeSize;
- while(CURRENT_ADDRESS < BOOTLOADER_ADDRESS)
+ currentAddress = writeSize;
+ while(currentAddress < BOOTLOADER_ADDRESS)
{
fillFlashWithVectors();
}
@@ -338,7 +319,7 @@ static uchar replyBuffer[4];
addr_t addr;
for(addr = 0; addr < FLASHEND + 1 - 2048; addr += SPM_PAGESIZE) {
/* wait and erase page */
- DBG1(0x33, 0, 0);
+ //DBG1(0x33, 0, 0);
# ifndef NO_FLASH_WRITE
boot_spm_busy_wait();
cli();
@@ -385,7 +366,7 @@ uchar usbFunctionWrite(uchar *data, uchar len)
{
uchar isLast;
- DBG1(0x31, (void *)&currentAddress.l, 4);
+ //DBG1(0x31, (void *)&currentAddress.l, 4);
if(len > bytesRemaining)
len = bytesRemaining;
bytesRemaining -= len;
@@ -402,27 +383,27 @@ uchar usbFunctionWrite(uchar *data, uchar len)
for(i = 0; i < len;){
#ifdef TINY85MODE
#if 1
- if(CURRENT_ADDRESS == RESET_VECTOR_OFFSET * 2)
+ if(currentAddress == RESET_VECTOR_OFFSET * 2)
{
vectorTemp[0] = *(short *)data;
}
- if(CURRENT_ADDRESS == USBPLUS_VECTOR_OFFSET * 2)
+ if(currentAddress == USBPLUS_VECTOR_OFFSET * 2)
{
vectorTemp[1] = *(short *)data;
}
#else
- if(CURRENT_ADDRESS == RESET_VECTOR_OFFSET * 2 || CURRENT_ADDRESS == USBPLUS_VECTOR_OFFSET * 2)
+ if(currentAddress == RESET_VECTOR_OFFSET * 2 || currentAddress == USBPLUS_VECTOR_OFFSET * 2)
{
- vectorTemp[CURRENT_ADDRESS ? 1:0] = *(short *)data;
+ vectorTemp[currentAddress ? 1:0] = *(short *)data;
}
#endif
#else
# if !HAVE_CHIP_ERASE
if((currentAddress.w[0] & (SPM_PAGESIZE - 1)) == 0){ /* if page start: erase */
- DBG1(0x33, 0, 0);
+ //DBG1(0x33, 0, 0);
# ifndef NO_FLASH_WRITE
cli();
- boot_page_erase(CURRENT_ADDRESS); /* erase page */
+ boot_page_erase(currentAddress); /* erase page */
sei();
boot_spm_busy_wait(); /* wait until page is erased */
# endif
@@ -430,9 +411,9 @@ uchar usbFunctionWrite(uchar *data, uchar len)
#endif
i += 2;
- DBG1(0x32, 0, 0);
+ //DBG1(0x32, 0, 0);
#ifdef TINY85MODE
- if(CURRENT_ADDRESS >= BOOTLOADER_ADDRESS - 6)
+ if(currentAddress >= BOOTLOADER_ADDRESS - 6)
{
// stop writing data to flash if the application is too big, and clear any leftover data in the page buffer
__boot_page_fill_clear();
@@ -442,20 +423,20 @@ uchar usbFunctionWrite(uchar *data, uchar len)
writeWordToPageBuffer(*(short *)data);
#else
cli();
- boot_page_fill(CURRENT_ADDRESS, *(short *)data);
+ boot_page_fill(currentAddress, *(short *)data);
sei();
- CURRENT_ADDRESS += 2;
+ currentAddress += 2;
#endif
data += 2;
/* write page when we cross page boundary or we have the last partial page */
if((currentAddress.w[0] & (SPM_PAGESIZE - 1)) == 0 || (isLast && i >= len && isLastPage)){
- DBG1(0x34, 0, 0);
+ //DBG1(0x34, 0, 0);
#ifdef TINY85MODE
flashPageLoaded = 1;
#else
# ifndef NO_FLASH_WRITE
cli();
- boot_page_write(CURRENT_ADDRESS - 2);
+ boot_page_write(currentAddress - 2);
sei();
boot_spm_busy_wait();
cli();
@@ -465,7 +446,7 @@ uchar usbFunctionWrite(uchar *data, uchar len)
#endif
}
}
- DBG1(0x35, (void *)&currentAddress.l, 4);
+ //DBG1(0x35, (void *)&currentAddress.l, 4);
#if HAVE_EEPROM_PAGED_ACCESS
}
#endif
@@ -485,25 +466,25 @@ uchar usbFunctionRead(uchar *data, uchar len)
*data = eeprom_read_byte((void *)currentAddress.w[0]);
}else{
#endif
- *data = pgm_read_byte((void *)CURRENT_ADDRESS);
+ *data = pgm_read_byte((void *)currentAddress);
// read back original vectors
#ifdef TINY85MODE
#if 1
- if(CURRENT_ADDRESS == RESET_VECTOR_OFFSET * 2)
+ if(currentAddress == RESET_VECTOR_OFFSET * 2)
*data = vectorTemp[0];
- if(CURRENT_ADDRESS == (RESET_VECTOR_OFFSET * 2) + 1)
+ if(currentAddress == (RESET_VECTOR_OFFSET * 2) + 1)
*data = vectorTemp[0]/256;
- if(CURRENT_ADDRESS == (USBPLUS_VECTOR_OFFSET * 2))
+ if(currentAddress == (USBPLUS_VECTOR_OFFSET * 2))
*data = vectorTemp[1];
- if(CURRENT_ADDRESS == (USBPLUS_VECTOR_OFFSET * 2) + 1)
+ if(currentAddress == (USBPLUS_VECTOR_OFFSET * 2) + 1)
*data = vectorTemp[1]/256;
#else
- if(CURRENT_ADDRESS == RESET_VECTOR_OFFSET * 2 || CURRENT_ADDRESS == USBPLUS_VECTOR_OFFSET * 2)
+ if(currentAddress == RESET_VECTOR_OFFSET * 2 || currentAddress == USBPLUS_VECTOR_OFFSET * 2)
{
- *(short *)data = vectorTemp[CURRENT_ADDRESS ? 1:0];
+ *(short *)data = vectorTemp[currentAddress ? 1:0];
data++;
- CURRENT_ADDRESS++;
+ currentAddress++;
}
#endif
#endif
@@ -511,7 +492,7 @@ uchar usbFunctionRead(uchar *data, uchar len)
}
#endif
data++;
- CURRENT_ADDRESS++;
+ currentAddress++;
}
return len;
}
@@ -558,8 +539,8 @@ static inline void tiny85FlashInit(void)
# endif
}
- // TODO: necessary to reset CURRENT_ADDRESS?
- CURRENT_ADDRESS = 0;
+ // TODO: necessary to reset currentAddress?
+ currentAddress = 0;
# ifdef APPCHECKSUM
checksum = 0;
# endif
@@ -587,7 +568,7 @@ static inline void tiny85FlashWrites(void)
// write page to flash, interrupts will be disabled for several milliseconds
cli();
- if(CURRENT_ADDRESS % SPM_PAGESIZE)
+ if(currentAddress % SPM_PAGESIZE)
fillFlashWithVectors();
else
writeFlashPage();
@@ -598,58 +579,44 @@ static inline void tiny85FlashWrites(void)
if(isLastPage)
{
// store number of bytes written so rest of flash can be filled later
- writeSize = CURRENT_ADDRESS;
+ writeSize = currentAddress;
appWriteComplete = 1;
}
}
}
#endif
-int __attribute__((noreturn)) main(void)
-{
+int __attribute__((noreturn)) main(void) {
uint16_t idlePolls = 0;
-#ifdef APPCHECKSUM
- int validApp = 0;
-#endif
/* initialize */
wdt_disable(); /* main app may have enabled watchdog */
-#ifdef TINY85MODE
tiny85FlashInit();
-#endif
bootLoaderInit();
- odDebugInit();
- DBG1(0x00, 0, 0);
+ //odDebugInit();
+ ////DBG1(0x00, 0, 0);
-#ifdef APPCHECKSUM
- validApp = testForValidApplication();
-#endif
-#ifndef TINY85MODE
-# ifndef NO_FLASH_WRITE
- GICR = (1 << IVCE); /* enable change of interrupt vectors */
- GICR = (1 << IVSEL); /* move interrupts to boot flash section */
-# endif
-#endif
-
- if(bootLoaderCondition()){
+ if (bootLoaderCondition()){
initForUsbConnectivity();
- do{
+ do {
usbPoll();
_delay_us(100);
idlePolls++;
-#ifdef TINY85MODE
- tiny85FlashWrites();
-#endif
+
+ if (isEvent(EVENT_ERASE_APPLICATION)) eraseApplication();
+ if (isEvent(EVENT_WRITE_PAGE)) tiny85FlashWrites();
#if BOOTLOADER_CAN_EXIT
// exit if requested by the programming app, or if we timeout waiting for the pc with a valid app
- if(requestBootLoaderExit || AUTO_EXIT_CONDITION()){
+ if (isEvent(EVENT_EXIT_BOOTLOADER) || AUTO_EXIT_CONDITION()) {
_delay_ms(10);
break;
}
#endif
- }while(bootLoaderCondition()); /* main event loop */
+ clearEvents();
+
+ } while(bootLoaderCondition()); /* main event loop */
}
leaveBootloader();
}