return l;\r
}\r
\r
+char* strncat(char *dest, const char *src, unsigned int n)\r
+{\r
+ unsigned int dest_len = strlen(dest);\r
+ unsigned int i;\r
+ \r
+ for (i = 0 ; i < n && src[i] != '\0' ; i++)\r
+ dest[dest_len + i] = src[i];\r
+ dest[dest_len + i] = '\0';\r
+ \r
+ return dest;\r
+}\r
+\r
+void num_to_bytes(uint64_t n, size_t len, byte_t* dest)\r
+{\r
+ while (len--) {\r
+ dest[len] = (byte_t) n;\r
+ n >>= 8;\r
+ }\r
+}\r
+\r
+uint64_t bytes_to_num(byte_t* src, size_t len)\r
+{\r
+ uint64_t num = 0;\r
+ while (len--)\r
+ {\r
+ num = (num << 8) | (*src);\r
+ src++;\r
+ }\r
+ return num;\r
+}\r
+\r
void LEDsoff()\r
{\r
LED_A_OFF();\r
if (led & LED_RED2)\r
LED_D_OFF();\r
}\r
- \r
+\r
\r
// Determine if a button is double clicked, single clicked,\r
// not clicked, or held down (for ms || 1sec)\r
return BUTTON_NO_CLICK;\r
\r
// Borrow a PWM unit for my real-time clock\r
- PWM_ENABLE = PWM_CHANNEL(0);\r
+ AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0);\r
// 48 MHz / 1024 gives 46.875 kHz\r
- PWM_CH_MODE(0) = PWM_CH_MODE_PRESCALER(10);\r
- PWM_CH_DUTY_CYCLE(0) = 0;\r
- PWM_CH_PERIOD(0) = 0xffff;\r
- \r
- WORD start = (WORD)PWM_CH_COUNTER(0);\r
- \r
+ AT91C_BASE_PWMC_CH0->PWMC_CMR = PWM_CH_MODE_PRESCALER(10);\r
+ AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 0;\r
+ AT91C_BASE_PWMC_CH0->PWMC_CPRDR = 0xffff;\r
+\r
+ WORD start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;\r
+\r
int letoff = 0;\r
for(;;)\r
{\r
- WORD now = (WORD)PWM_CH_COUNTER(0);\r
- \r
+ WORD now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;\r
+\r
// We haven't let off the button yet\r
if (!letoff)\r
{\r
letoff = 1;\r
\r
// reset our timer for 500ms\r
- start = (WORD)PWM_CH_COUNTER(0);\r
+ start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;\r
ticks = (48000 * (500)) >> 10;\r
}\r
\r
// If we're not even pressed, forget about it!\r
if (!BUTTON_PRESS())\r
return BUTTON_NO_CLICK;\r
- \r
+\r
// Borrow a PWM unit for my real-time clock\r
- PWM_ENABLE = PWM_CHANNEL(0);\r
+ AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0);\r
// 48 MHz / 1024 gives 46.875 kHz\r
- PWM_CH_MODE(0) = PWM_CH_MODE_PRESCALER(10);\r
- PWM_CH_DUTY_CYCLE(0) = 0;\r
- PWM_CH_PERIOD(0) = 0xffff;\r
- \r
- WORD start = (WORD)PWM_CH_COUNTER(0);\r
- \r
+ AT91C_BASE_PWMC_CH0->PWMC_CMR = PWM_CH_MODE_PRESCALER(10);\r
+ AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 0;\r
+ AT91C_BASE_PWMC_CH0->PWMC_CPRDR = 0xffff;\r
+\r
+ WORD start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;\r
+\r
for(;;)\r
{\r
- WORD now = (WORD)PWM_CH_COUNTER(0);\r
- \r
+ WORD now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;\r
+\r
// As soon as our button let go, we didn't hold long enough\r
if (!BUTTON_PRESS())\r
return BUTTON_SINGLE_CLICK;\r
else\r
if (now == (WORD)(start + ticks))\r
return BUTTON_HOLD;\r
- \r
+\r
WDT_HIT();\r
}\r
\r
return BUTTON_ERROR;\r
}\r
\r
+// attempt at high resolution microsecond timer\r
+// beware: timer counts in 21.3uS increments (1024/48Mhz)\r
void SpinDelayUs(int us)\r
{\r
int ticks = (48*us) >> 10;\r
- \r
+\r
// Borrow a PWM unit for my real-time clock\r
- PWM_ENABLE = PWM_CHANNEL(0);\r
+ AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0);\r
// 48 MHz / 1024 gives 46.875 kHz\r
- PWM_CH_MODE(0) = PWM_CH_MODE_PRESCALER(10);\r
- PWM_CH_DUTY_CYCLE(0) = 0;\r
- PWM_CH_PERIOD(0) = 0xffff;\r
- \r
- WORD start = (WORD)PWM_CH_COUNTER(0);\r
- \r
+ AT91C_BASE_PWMC_CH0->PWMC_CMR = PWM_CH_MODE_PRESCALER(10);\r
+ AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 0;\r
+ AT91C_BASE_PWMC_CH0->PWMC_CPRDR = 0xffff;\r
+\r
+ WORD start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;\r
+\r
for(;;) {\r
- WORD now = (WORD)PWM_CH_COUNTER(0);\r
- if(now == (WORD)(start + ticks)) {\r
+ WORD now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;\r
+ if (now == (WORD)(start + ticks))\r
return;\r
- }\r
+\r
WDT_HIT();\r
}\r
}\r
\r
void SpinDelay(int ms)\r
{\r
- int ticks = (48000*ms) >> 10;\r
-\r
- // Borrow a PWM unit for my real-time clock\r
- PWM_ENABLE = PWM_CHANNEL(0);\r
- // 48 MHz / 1024 gives 46.875 kHz\r
- PWM_CH_MODE(0) = PWM_CH_MODE_PRESCALER(10);\r
- PWM_CH_DUTY_CYCLE(0) = 0;\r
- PWM_CH_PERIOD(0) = 0xffff;\r
-\r
- WORD start = (WORD)PWM_CH_COUNTER(0);\r
-\r
- for(;;)\r
- {\r
- WORD now = (WORD)PWM_CH_COUNTER(0);\r
- if (now == (WORD)(start + ticks))\r
- return;\r
+ // convert to uS and call microsecond delay function\r
+ SpinDelayUs(ms*1000);\r
+}\r
\r
- WDT_HIT();\r
+/* Similar to FpgaGatherVersion this formats stored version information\r
+ * into a string representation. It takes a pointer to the struct version_information,\r
+ * verifies the magic properties, then stores a formatted string, prefixed by\r
+ * prefix in dst.\r
+ */\r
+void FormatVersionInformation(char *dst, int len, const char *prefix, void *version_information)\r
+{\r
+ struct version_information *v = (struct version_information*)version_information;\r
+ dst[0] = 0;\r
+ strncat(dst, prefix, len);\r
+ if(v->magic != VERSION_INFORMATION_MAGIC) {\r
+ strncat(dst, "Missing/Invalid version information", len);\r
+ return;\r
}\r
+ if(v->versionversion != 1) {\r
+ strncat(dst, "Version information not understood", len);\r
+ return;\r
+ }\r
+ if(!v->present) {\r
+ strncat(dst, "Version information not available", len);\r
+ return;\r
+ }\r
+ \r
+ strncat(dst, v->svnversion, len);\r
+ if(v->clean == 0) {\r
+ strncat(dst, "-unclean", len);\r
+ } else if(v->clean == 2) {\r
+ strncat(dst, "-suspect", len);\r
+ }\r
+ \r
+ strncat(dst, " ", len);\r
+ strncat(dst, v->buildtime, len);\r
}\r