aboutsummaryrefslogtreecommitdiffstats
path: root/wirish
diff options
context:
space:
mode:
Diffstat (limited to 'wirish')
-rw-r--r--wirish/boards.cpp12
-rw-r--r--wirish/ext_interrupts.cpp26
-rw-r--r--wirish/include/wirish/ext_interrupts.h22
-rw-r--r--wirish/syscalls.c18
-rw-r--r--wirish/usb_serial.cpp13
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) {