diff options
Diffstat (limited to 'wirish')
-rw-r--r-- | wirish/boards.cpp | 12 | ||||
-rw-r--r-- | wirish/ext_interrupts.cpp | 26 | ||||
-rw-r--r-- | wirish/include/wirish/ext_interrupts.h | 22 | ||||
-rw-r--r-- | wirish/syscalls.c | 18 | ||||
-rw-r--r-- | wirish/usb_serial.cpp | 13 |
5 files changed, 68 insertions, 23 deletions
diff --git a/wirish/boards.cpp b/wirish/boards.cpp index dbc308e..a693fa6 100644 --- a/wirish/boards.cpp +++ b/wirish/boards.cpp @@ -143,13 +143,10 @@ static void setup_clocks(void) { * These addresses are where usercode starts when a bootloader is * present. If no bootloader is present, the user NVIC usually starts * at the Flash base address, 0x08000000. - * - * FIXME Let the build specify the vector table address numerically to - * avoid having these magic values -- some people have been fixing up - * the bootloader so it uses less space. */ #define USER_ADDR_ROM 0x08005000 #define USER_ADDR_RAM 0x20000C00 +extern char __text_start__; static void setup_nvic(void) { #ifdef VECT_TAB_FLASH @@ -158,8 +155,13 @@ static void setup_nvic(void) { nvic_init(USER_ADDR_RAM, 0); #elif defined VECT_TAB_BASE nvic_init((uint32)0x08000000, 0); +#elif defined VECT_TAB_ADDR + // A numerically supplied value + nvic_init((uint32)VECT_TAB_ADDR, 0); #else -#error "You must select a base address for the vector table." + // Use the __text_start__ value from the linker script; this + // should be the start of the vector table. + nvic_init((uint32)&__text_start__, 0); #endif } diff --git a/wirish/ext_interrupts.cpp b/wirish/ext_interrupts.cpp index a3e61fd..1195ea9 100644 --- a/wirish/ext_interrupts.cpp +++ b/wirish/ext_interrupts.cpp @@ -39,13 +39,6 @@ static inline exti_trigger_mode exti_out_mode(ExtIntTriggerMode mode); -/** - * @brief Attach an interrupt handler to a pin, triggering on the given mode. - * @param pin Pin to attach an interrupt handler onto. - * @param handler Function to call when the external interrupt is triggered. - * @param mode Trigger mode for the given interrupt. - * @see ExtIntTriggerMode - */ void attachInterrupt(uint8 pin, voidFuncPtr handler, ExtIntTriggerMode mode) { if (pin >= BOARD_NR_GPIO_PINS || !handler) { return; @@ -59,10 +52,21 @@ void attachInterrupt(uint8 pin, voidFuncPtr handler, ExtIntTriggerMode mode) { outMode); } -/** - * @brief Disable any external interrupt attached to a pin. - * @param pin Pin number to detach any interrupt from. - */ +void attachInterrupt(uint8 pin, voidArgumentFuncPtr handler, void *arg, + ExtIntTriggerMode mode) { + if (pin >= BOARD_NR_GPIO_PINS || !handler) { + return; + } + + exti_trigger_mode outMode = exti_out_mode(mode); + + exti_attach_callback((exti_num)(PIN_MAP[pin].gpio_bit), + gpio_exti_port(PIN_MAP[pin].gpio_device), + handler, + arg, + outMode); +} + void detachInterrupt(uint8 pin) { if (pin >= BOARD_NR_GPIO_PINS) { return; diff --git a/wirish/include/wirish/ext_interrupts.h b/wirish/include/wirish/ext_interrupts.h index 933be04..ce1ca03 100644 --- a/wirish/include/wirish/ext_interrupts.h +++ b/wirish/include/wirish/ext_interrupts.h @@ -69,6 +69,28 @@ typedef enum ExtIntTriggerMode { void attachInterrupt(uint8 pin, voidFuncPtr handler, ExtIntTriggerMode mode); /** + * @brief Registers an interrupt handler on a pin. + * + * The interrupt will be triggered on a given transition on the pin, + * as specified by the mode parameter. The handler runs in interrupt + * context. The new handler will replace whatever handler is + * currently registered for the pin, if any. + * + * @param pin Pin number + * @param handler Static class member function to run upon external interrupt + * trigger. The handler should take 1 argument and return void + * @param arg Argument that the handler will be passed when it's called. One + * use of this is to pass the specific instance of the class that + * will handle the interrupt. + * @param mode Type of transition to trigger on, e.g. falling, rising, etc. + * + * @sideeffect Registers a handler + * @see detachInterrupt() + */ +void attachInterrupt(uint8 pin, voidArgumentFuncPtr handler, void *arg, + ExtIntTriggerMode mode); + +/** * @brief Disable any registered external interrupt. * @param pin Maple pin number * @sideeffect unregisters external interrupt handler diff --git a/wirish/syscalls.c b/wirish/syscalls.c index 1e62d51..d5f2d9f 100644 --- a/wirish/syscalls.c +++ b/wirish/syscalls.c @@ -37,17 +37,18 @@ #include <sys/stat.h> #include <errno.h> +#include <stddef.h> /* If CONFIG_HEAP_START (or CONFIG_HEAP_END) isn't defined, then * assume _lm_heap_start (resp. _lm_heap_end) is appropriately set by * the linker */ #ifndef CONFIG_HEAP_START extern char _lm_heap_start; -#define CONFIG_HEAP_START ((caddr_t)&_lm_heap_start) +#define CONFIG_HEAP_START ((void *)&_lm_heap_start) #endif #ifndef CONFIG_HEAP_END extern char _lm_heap_end; -#define CONFIG_HEAP_END ((caddr_t)&_lm_heap_end) +#define CONFIG_HEAP_END ((void *)&_lm_heap_end) #endif /* @@ -56,9 +57,9 @@ extern char _lm_heap_end; * Get incr bytes more RAM (for use by the heap). malloc() and * friends call this function behind the scenes. */ -caddr_t _sbrk(int incr) { - static caddr_t pbreak = NULL; /* current program break */ - caddr_t ret; +void *_sbrk(int incr) { + static void * pbreak = NULL; /* current program break */ + void * ret; if (pbreak == NULL) { pbreak = CONFIG_HEAP_START; @@ -67,7 +68,7 @@ caddr_t _sbrk(int incr) { if ((CONFIG_HEAP_END - pbreak < incr) || (pbreak - CONFIG_HEAP_START < -incr)) { errno = ENOMEM; - return (caddr_t)-1; + return (void *)-1; } ret = pbreak; @@ -168,3 +169,8 @@ __weak char *fgets(char *s, int bufsize, void *f) { cgets(s, bufsize); return s; } + +__weak void _exit(int exitcode) { + while (1) + ; +} diff --git a/wirish/usb_serial.cpp b/wirish/usb_serial.cpp index 380f197..d21766f 100644 --- a/wirish/usb_serial.cpp +++ b/wirish/usb_serial.cpp @@ -92,13 +92,24 @@ void USBSerial::write(const void *buf, uint32 len) { uint32 old_txed = 0; uint32 start = millis(); + uint32 sent = 0; + while (txed < len && (millis() - start < USB_TIMEOUT)) { - txed += usb_cdcacm_tx((const uint8*)buf + txed, len - txed); + sent = usb_cdcacm_tx((const uint8*)buf + txed, len - txed); + txed += sent; if (old_txed != txed) { start = millis(); } old_txed = txed; } + + + if (sent == USB_CDCACM_TX_EPSIZE) { + while (usb_cdcacm_is_transmitting() != 0) { + } + /* flush out to avoid having the pc wait for more data */ + usb_cdcacm_tx(NULL, 0); + } } uint32 USBSerial::available(void) { |