summaryrefslogtreecommitdiffstats
path: root/firmware
diff options
context:
space:
mode:
authorcpldcpu <cpldcpu@gmail.com>2013-12-28 14:44:31 +0100
committercpldcpu <cpldcpu@gmail.com>2013-12-28 14:44:31 +0100
commitfefbff026f6ab8e3b5bc7d7a317a86c901057124 (patch)
tree8ec76b3e869593bb521c0be4106c76787feff4c3 /firmware
parent26b1c45b1145f9b96c4ec90e93a61a3da63e2473 (diff)
downloadmicronucleus-fefbff026f6ab8e3b5bc7d7a317a86c901057124.tar.gz
micronucleus-fefbff026f6ab8e3b5bc7d7a317a86c901057124.tar.bz2
micronucleus-fefbff026f6ab8e3b5bc7d7a317a86c901057124.zip
firmware: fix tabs
Diffstat (limited to 'firmware')
-rw-r--r--firmware/main.c246
1 files changed, 122 insertions, 124 deletions
diff --git a/firmware/main.c b/firmware/main.c
index 48ac399..bec0305 100644
--- a/firmware/main.c
+++ b/firmware/main.c
@@ -70,7 +70,7 @@ static uint16_t vectorTemp[2]; // remember data to create tinyVector table befor
static uint16_t currentAddress; // current progmem address, used for erasing and writing
#if OSCCAL_RESTORE
- static uint8_t osccal_default; // due to compiler insanity, having this as global actually saves memory
+ static uint8_t osccal_default; // due to compiler insanity, having this as global actually saves memory
#endif
/* ------------------------------------------------------------------------ */
@@ -86,142 +86,140 @@ static inline void leaveBootloader(void);
// - vectors in now, and write in the application stuff around them later.
// - if vectors weren't written back in immediately, usb would fail.
static inline void eraseApplication(void) {
- // erase all pages until bootloader, in reverse order (so our vectors stay in place for as long as possible)
- // while the vectors don't matter for usb comms as interrupts are disabled during erase, it's important
- // to minimise the chance of leaving the device in a state where the bootloader wont run, if there's power failure
- // during upload
-
- uint8_t i;
- uint16_t ptr = BOOTLOADER_ADDRESS;
- cli();
- while (ptr) {
- ptr -= SPM_PAGESIZE;
- boot_page_erase(ptr);
- }
+ // erase all pages until bootloader, in reverse order (so our vectors stay in place for as long as possible)
+ // while the vectors don't matter for usb comms as interrupts are disabled during erase, it's important
+ // to minimise the chance of leaving the device in a state where the bootloader wont run, if there's power failure
+ // during upload
+
+ uint8_t i;
+ uint16_t ptr = BOOTLOADER_ADDRESS;
+ cli();
+
+ while (ptr) {
+ ptr -= SPM_PAGESIZE;
+ boot_page_erase(ptr);
+ }
currentAddress = 0;
- for (i=0; i<8; i++) writeWordToPageBuffer(0xFFFF); // Write first 8 words to fill in vectors.
- writeFlashPage(); // enables interrupts
+ for (i=0; i<8; i++) writeWordToPageBuffer(0xFFFF); // Write first 8 words to fill in vectors.
+ writeFlashPage(); // enables interrupts
}
// simply write currently stored page in to already erased flash memory
static void writeFlashPage(void) {
- cli();
- boot_page_write(currentAddress - 2); // will halt CPU, no waiting required
- sei();
+ cli();
+ boot_page_write(currentAddress - 2); // will halt CPU, no waiting required
+ sei();
}
// clear memory which stores data to be written by next writeFlashPage call
#define __boot_page_fill_clear() \
(__extension__({ \
- __asm__ __volatile__ \
- ( \
- "sts %0, %1\n\t" \
- "spm\n\t" \
- : \
- : "i" (_SFR_MEM_ADDR(__SPM_REG)), \
- "r" ((uint8_t)(__BOOT_PAGE_FILL | (1 << CTPB))) \
- ); \
+ __asm__ __volatile__ \
+ ( \
+ "sts %0, %1\n\t" \
+ "spm\n\t" \
+ : \
+ : "i" (_SFR_MEM_ADDR(__SPM_REG)), \
+ "r" ((uint8_t)(__BOOT_PAGE_FILL | (1 << CTPB))) \
+ ); \
}))
// write a word in to the page buffer, doing interrupt table modifications where they're required
static void writeWordToPageBuffer(uint16_t data) {
- uint8_t previous_sreg;
+ uint8_t previous_sreg;
+
+ // first two interrupt vectors get replaced with a jump to the bootloader's vector table
+ // remember vectors or the tinyvector table
+ if (currentAddress == RESET_VECTOR_OFFSET * 2) {
+ vectorTemp[0] = data;
+ data = 0xC000 + (BOOTLOADER_ADDRESS/2) - 1;
+ }
+
+ if (currentAddress == USBPLUS_VECTOR_OFFSET * 2) {
+ vectorTemp[1] = data;
+ data = 0xC000 + (BOOTLOADER_ADDRESS/2) - 1;
+ }
- // first two interrupt vectors get replaced with a jump to the bootloader's vector table
- // remember vectors or the tinyvector table
- if (currentAddress == RESET_VECTOR_OFFSET * 2) {
- vectorTemp[0] = data;
- data = 0xC000 + (BOOTLOADER_ADDRESS/2) - 1;
- }
-
- if (currentAddress == USBPLUS_VECTOR_OFFSET * 2) {
- vectorTemp[1] = data;
- data = 0xC000 + (BOOTLOADER_ADDRESS/2) - 1;
- }
-
- // at end of page just before bootloader, write in tinyVector table
- // see http://embedded-creations.com/projects/attiny85-usb-bootloader-overview/avr-jtag-programmer/
- // for info on how the tiny vector table works
- if (currentAddress == BOOTLOADER_ADDRESS - TINYVECTOR_RESET_OFFSET) {
- data = vectorTemp[0] + ((FLASHEND + 1) - BOOTLOADER_ADDRESS)/2 + 2 + RESET_VECTOR_OFFSET;
- } else if (currentAddress == BOOTLOADER_ADDRESS - TINYVECTOR_USBPLUS_OFFSET) {
- data = vectorTemp[1] + ((FLASHEND + 1) - BOOTLOADER_ADDRESS)/2 + 1 + USBPLUS_VECTOR_OFFSET;
+ // at end of page just before bootloader, write in tinyVector table
+ // see http://embedded-creations.com/projects/attiny85-usb-bootloader-overview/avr-jtag-programmer/
+ // for info on how the tiny vector table works
+ if (currentAddress == BOOTLOADER_ADDRESS - TINYVECTOR_RESET_OFFSET) {
+ data = vectorTemp[0] + ((FLASHEND + 1) - BOOTLOADER_ADDRESS)/2 + 2 + RESET_VECTOR_OFFSET;
+ } else if (currentAddress == BOOTLOADER_ADDRESS - TINYVECTOR_USBPLUS_OFFSET) {
+ data = vectorTemp[1] + ((FLASHEND + 1) - BOOTLOADER_ADDRESS)/2 + 1 + USBPLUS_VECTOR_OFFSET;
#if (!OSCCAL_RESTORE) && OSCCAL_16_5MHz
- } else if (currentAddress == BOOTLOADER_ADDRESS - TINYVECTOR_OSCCAL_OFFSET) {
- data = OSCCAL;
+ } else if (currentAddress == BOOTLOADER_ADDRESS - TINYVECTOR_OSCCAL_OFFSET) {
+ data = OSCCAL;
#endif
- }
+ }
- previous_sreg=SREG;
- cli(); // ensure interrupts are disabled
-
- boot_page_fill(currentAddress, data);
-
- // increment progmem address by one word
- currentAddress += 2;
- SREG=previous_sreg;
+ previous_sreg=SREG;
+ cli(); // ensure interrupts are disabled
+
+ boot_page_fill(currentAddress, data);
+
+ // increment progmem address by one word
+ currentAddress += 2;
+ SREG=previous_sreg;
}
/* ------------------------------------------------------------------------ */
static uint8_t usbFunctionSetup(uint8_t data[8]) {
- usbRequest_t *rq = (void *)data;
- ((uint8_t*)&idlePolls)[1] = 0; // reset idle polls when we get usb traffic
-
- static uint8_t replyBuffer[4] = {
- (((uint16_t)PROGMEM_SIZE) >> 8) & 0xff,
- ((uint16_t)PROGMEM_SIZE) & 0xff,
- SPM_PAGESIZE,
- MICRONUCLEUS_WRITE_SLEEP
- };
+ usbRequest_t *rq = (void *)data;
+ ((uint8_t*)&idlePolls)[1] = 0; // reset idle polls when we get usb traffic
+
+ static uint8_t replyBuffer[4] = {
+ (((uint16_t)PROGMEM_SIZE) >> 8) & 0xff,
+ ((uint16_t)PROGMEM_SIZE) & 0xff,
+ SPM_PAGESIZE,
+ MICRONUCLEUS_WRITE_SLEEP
+ };
- if (rq->bRequest == 0) { // get device info
- usbMsgPtr = replyBuffer;
- return 4;
-
- } else if (rq->bRequest == 1) { // write page
-
- // clear page buffer as a precaution before filling the buffer in case
- // a previous write operation failed and there is still something in the buffer.
- __boot_page_fill_clear();
- currentAddress = rq->wIndex.word;
- return USB_NO_MSG; // hands off work to usbFunctionWrite
-
- } else if (rq->bRequest == 2) { // erase application
- fireEvent(EVENT_ERASE_APPLICATION);
-
- } else { // exit bootloader
-# if BOOTLOADER_CAN_EXIT
- fireEvent(EVENT_EXECUTE);
-# endif
- }
+ if (rq->bRequest == 0) { // get device info
+ usbMsgPtr = replyBuffer;
+ return 4;
+ } else if (rq->bRequest == 1) { // write page
+
+ // clear page buffer as a precaution before filling the buffer in case
+ // a previous write operation failed and there is still something in the buffer.
+ __boot_page_fill_clear();
+ currentAddress = rq->wIndex.word;
+ return USB_NO_MSG; // hands off work to usbFunctionWrite
- return 0;
+ } else if (rq->bRequest == 2) { // erase application
+ fireEvent(EVENT_ERASE_APPLICATION);
+
+ } else { // exit bootloader
+ fireEvent(EVENT_EXECUTE);
+ }
+
+ return 0;
}
// read in a page over usb, and write it in to the flash write buffer
static uint8_t usbFunctionWrite(uint8_t *data, uint8_t length) {
- do {
- // make sure we don't write over the bootloader!
- if (currentAddress >= BOOTLOADER_ADDRESS) break;
-
- writeWordToPageBuffer(*(uint16_t *) data);
- data += 2; // advance data pointer
- length -= 2;
- } while(length);
+ do {
+ // make sure we don't write over the bootloader!
+ if (currentAddress >= BOOTLOADER_ADDRESS) break;
- // if we have now reached another page boundary, we're done
+ writeWordToPageBuffer(*(uint16_t *) data);
+ data += 2; // advance data pointer
+ length -= 2;
+ } while(length);
+
+ // if we have now reached another page boundary, we're done
#if SPM_PAGESIZE<256
// Hack to reduce code size
- uint8_t isLast = ((((uint8_t)currentAddress) % SPM_PAGESIZE) == 0);
+ uint8_t isLast = ((((uint8_t)currentAddress) % SPM_PAGESIZE) == 0);
#else
- uint8_t isLast = ((currentAddress % SPM_PAGESIZE) == 0);
+ uint8_t isLast = ((currentAddress % SPM_PAGESIZE) == 0);
#endif
- // definitely need this if! seems usbFunctionWrite gets called again in future usbPoll's in the runloop!
- if (isLast) fireEvent(EVENT_WRITE_PAGE); // ask runloop to write our page
-
- return isLast; // let vusb know we're done with this request
+ // definitely need this if! seems usbFunctionWrite gets called again in future usbPoll's in the runloop!
+ if (isLast) fireEvent(EVENT_WRITE_PAGE); // ask runloop to write our page
+
+ return isLast; // let vusb know we're done with this request
}
/* ------------------------------------------------------------------------ */
@@ -229,10 +227,10 @@ void PushMagicWord (void) __attribute__ ((naked)) __attribute__ ((section (".ini
// put the word "B007" at the bottom of the stack (RAMEND - RAMEND-1)
void PushMagicWord (void) {
- asm volatile("ldi r16, 0xB0"::);
- asm volatile("push r16"::);
- asm volatile("ldi r16, 0x07"::);
- asm volatile("push r16"::);
+ asm volatile("ldi r16, 0xB0"::);
+ asm volatile("push r16"::);
+ asm volatile("ldi r16, 0x07"::);
+ asm volatile("push r16"::);
}
static void initHardware (void)
@@ -252,29 +250,29 @@ static void initHardware (void)
// reset system to a normal state and launch user program
static void leaveBootloader(void) __attribute__((__noreturn__));
static inline void leaveBootloader(void) {
- _delay_ms(10); // removing delay causes USB errors
-
- bootLoaderExit();
- cli();
+ _delay_ms(10); // removing delay causes USB errors
+
+ bootLoaderExit();
+ cli();
usbDeviceDisconnect(); /* Disconnect micronucleus */
-
- USB_INTR_ENABLE = 0;
- USB_INTR_CFG = 0; /* also reset config bits */
- // clear magic word from bottom of stack before jumping to the app
- *(uint8_t*)(RAMEND) = 0x00; // A single write is sufficient to invalidate magic word
+ USB_INTR_ENABLE = 0;
+ USB_INTR_CFG = 0; /* also reset config bits */
+
+ // clear magic word from bottom of stack before jumping to the app
+ *(uint8_t*)(RAMEND) = 0x00; // A single write is sufficient to invalidate magic word
#if (!OSCCAL_RESTORE) && OSCCAL_16_5MHz
- // adjust clock to previous calibration value, so user program always starts with same calibration
- // as when it was uploaded originally
- unsigned char stored_osc_calibration = pgm_read_byte(BOOTLOADER_ADDRESS - TINYVECTOR_OSCCAL_OFFSET);
- if (stored_osc_calibration != 0xFF && stored_osc_calibration != 0x00) {
- OSCCAL=stored_osc_calibration;
- nop();
- }
+ // adjust clock to previous calibration value, so user program always starts with same calibration
+ // as when it was uploaded originally
+ unsigned char stored_osc_calibration = pgm_read_byte(BOOTLOADER_ADDRESS - TINYVECTOR_OSCCAL_OFFSET);
+ if (stored_osc_calibration != 0xFF && stored_osc_calibration != 0x00) {
+ OSCCAL=stored_osc_calibration;
+ nop();
+ }
#endif
- // jump to application reset vector at end of flash
- asm volatile ("rjmp __vectors - 4");
+ // jump to application reset vector at end of flash
+ asm volatile ("rjmp __vectors - 4");
}
int main(void) {