summaryrefslogtreecommitdiffstats
path: root/firmware/main.c
diff options
context:
space:
mode:
authorcpldcpu <cpldcpu@gmail.com>2014-01-05 21:50:58 +0100
committercpldcpu <cpldcpu@gmail.com>2014-01-05 21:50:58 +0100
commit05b30e380da988ae39bcc14ebf299aac4ef4cec4 (patch)
treeb61c672255ea14f0cc61349f3606dbcc2cfaecff /firmware/main.c
parentaa6bb7aba69bf6820fb8b2c013eff37378a2809b (diff)
downloadmicronucleus-05b30e380da988ae39bcc14ebf299aac4ef4cec4.tar.gz
micronucleus-05b30e380da988ae39bcc14ebf299aac4ef4cec4.tar.bz2
micronucleus-05b30e380da988ae39bcc14ebf299aac4ef4cec4.zip
firmware: clean up of main.c
Diffstat (limited to 'firmware/main.c')
-rw-r--r--firmware/main.c63
1 files changed, 34 insertions, 29 deletions
diff --git a/firmware/main.c b/firmware/main.c
index 246b2f9..6bcc642 100644
--- a/firmware/main.c
+++ b/firmware/main.c
@@ -1,9 +1,8 @@
/*
* Project: Micronucleus - v2.0
*
- * Micronucleus V2.0 (c) 2014 Tim Bo"scke - cpldcpu@gmail.com
- * V2.0 (c) 2014 Shay Green
- *
+ * Micronucleus V2.0 (c) 2014 Tim Bo"scke - cpldcpu@gmail.com
+ * (c) 2014 Shay Green
* Original Micronucleus (c) 2012 Jenna Fox
*
* Based on USBaspLoader-tiny85 (c) 2012 Louis Beaudoin
@@ -14,11 +13,6 @@
#define MICRONUCLEUS_VERSION_MAJOR 2
#define MICRONUCLEUS_VERSION_MINOR 0
-// how many milliseconds should host wait till it sends another erase or write?
-// needs to be above 4.5 (and a whole integer) as avr freezes for 4.5ms
-#define MICRONUCLEUS_WRITE_SLEEP 5
-// Use the old delay routines without NOP padding. This saves memory.
-#define __DELAY_BACKWARD_COMPATIBLE__
#include <avr/io.h>
#include <avr/pgmspace.h>
@@ -29,6 +23,10 @@
#include "bootloaderconfig.h"
#include "usbdrv/usbdrv.c"
+// how many milliseconds should host wait till it sends another erase or write?
+// needs to be above 4.5 (and a whole integer) as avr freezes for 4.5ms
+#define MICRONUCLEUS_WRITE_SLEEP 5
+
// verify the bootloader address aligns with page size
#if BOOTLOADER_ADDRESS % SPM_PAGESIZE != 0
#error "BOOTLOADER_ADDRESS in makefile must be a multiple of chip's pagesize"
@@ -38,15 +36,28 @@
#error "Micronucleus only supports pagesizes up to 256 bytes"
#endif
-// command system schedules functions to run in the main loop
-register uint8_t command asm("r3"); // bind command to r3
-register uint16_union_t currentAddress asm("r4"); // r4/r5 current progmem address, used for erasing and writing
-register uint16_union_t idlePolls asm("r6"); // r6/r7 idlecounter
+// Device configuration reply
+// Length: 4 bytes
+// Byte 0: User program memory size, high byte
+// Byte 1: User program memory size, low byte
+// Byte 2: Flash Pagesize in bytes
+// Byte 3: Page write timing in ms
+
+PROGMEM const uint8_t configurationReply[4] = {
+ (((uint16_t)PROGMEM_SIZE) >> 8) & 0xff,
+ ((uint16_t)PROGMEM_SIZE) & 0xff,
+ SPM_PAGESIZE,
+ MICRONUCLEUS_WRITE_SLEEP
+};
#if OSCCAL_RESTORE
register uint8_t osccal_default asm("r2");
#endif
+register uint16_union_t currentAddress asm("r4"); // r4/r5 current progmem address, used for erasing and writing
+register uint16_union_t idlePolls asm("r6"); // r6/r7 idlecounter
+
+// command system schedules functions to run in the main loop
enum {
cmd_local_nop=0, // also: get device info
cmd_device_info=0,
@@ -56,12 +67,16 @@ enum {
cmd_exit=4,
cmd_write_page=64, // internal commands start at 64
};
+register uint8_t command asm("r3"); // bind command to r3
// Definition of sei and cli without memory barrier keyword to prevent reloading of memory variables
#define sei() asm volatile("sei")
#define cli() asm volatile("cli")
#define nop() asm volatile("nop")
+// Use the old delay routines without NOP padding. This saves memory.
+#define __DELAY_BACKWARD_COMPATIBLE__
+
/* ------------------------------------------------------------------------ */
static inline void eraseApplication(void);
static void writeFlashPage(void);
@@ -69,6 +84,9 @@ static void writeWordToPageBuffer(uint16_t data);
static uint8_t usbFunctionSetup(uint8_t data[8]);
static inline void leaveBootloader(void);
+// This function is never called, it is just here to suppress a compiler warning.
+USB_PUBLIC usbMsgLen_t usbFunctionDescriptor(struct usbRequest *rq) { return 0; }
+
// clear memory which stores data to be written by next writeFlashPage call
#define __boot_page_fill_clear() \
(__extension__({ \
@@ -108,16 +126,15 @@ static inline void eraseApplication(void) {
currentAddress.w = 0;
writeWordToPageBuffer(0xffff);
command=cmd_write_page;
- }
-
+}
// simply write currently stored page in to already erased flash memory
static inline void writeFlashPage(void) {
if (currentAddress.w<=BOOTLOADER_ADDRESS)
- boot_page_write(currentAddress.w - 2); // will halt CPU, no waiting required
+ boot_page_write(currentAddress.w - 2); // will halt CPU, no waiting required
}
-// write a word in to the page buffer, doing interrupt table modifications where they're required
+// write a word into the page buffer, doing interrupt table modifications where they're required
static void writeWordToPageBuffer(uint16_t data) {
// Patch the bootloader reset vector into the main vectortable to ensure
@@ -136,21 +153,9 @@ static void writeWordToPageBuffer(uint16_t data) {
#endif
boot_page_fill(currentAddress.w, data);
-
currentAddress.w += 2;
}
-// This function is never called, it is just here to suppress a compiler warning.
-USB_PUBLIC usbMsgLen_t usbFunctionDescriptor(struct usbRequest *rq) { return 0; }
-
- PROGMEM const uint8_t replyBuffer[4] = {
- (((uint16_t)PROGMEM_SIZE) >> 8) & 0xff,
- ((uint16_t)PROGMEM_SIZE) & 0xff,
- SPM_PAGESIZE,
- MICRONUCLEUS_WRITE_SLEEP
- };
-
-
/* ------------------------------------------------------------------------ */
static uint8_t usbFunctionSetup(uint8_t data[8]) {
usbRequest_t *rq = (void *)data;
@@ -158,7 +163,7 @@ static uint8_t usbFunctionSetup(uint8_t data[8]) {
idlePolls.b[1]=0; // reset idle polls when we get usb traffic
if (rq->bRequest == cmd_device_info) { // get device info
- usbMsgPtr = (usbMsgPtr_t)replyBuffer;
+ usbMsgPtr = (usbMsgPtr_t)configurationReply;
return 4;
} else if (rq->bRequest == cmd_transfer_page) { // initialize write page
currentAddress.w = rq->wIndex.word;