diff options
author | Damien George <damien.p.george@gmail.com> | 2014-02-01 16:04:34 +0000 |
---|---|---|
committer | Damien George <damien.p.george@gmail.com> | 2014-02-01 16:04:34 +0000 |
commit | 01156d510c728408be4fd3100bcee18e8985ac00 (patch) | |
tree | 00474b76a63214870d88c82249db9d17c64f2f71 /stm/usb.c | |
parent | 532f2c30f66c9ff1e4f2aded29b98ba0db5ec341 (diff) | |
download | micropython-01156d510c728408be4fd3100bcee18e8985ac00.tar.gz micropython-01156d510c728408be4fd3100bcee18e8985ac00.zip |
stm: Add support for ctrl-C to interrupt running Python.
Using PendSV interrupt at lowest priority, code can now raise an
exception during an interrupt by calling pendsv_nlr_jump. The exception
will be raised when all interrupts are finished. This is used to trap
ctrl-C from the USB VCP to break out of running Python code.
Diffstat (limited to 'stm/usb.c')
-rw-r--r-- | stm/usb.c | 22 |
1 files changed, 22 insertions, 0 deletions
@@ -11,6 +11,7 @@ #include "mpconfig.h" #include "qstr.h" #include "obj.h" +#include "pendsv.h" #include "usb.h" #ifdef USE_DEVICE_MODE @@ -23,6 +24,8 @@ static int dev_is_enabled = 0; static char rx_buf[64]; static int rx_buf_in; static int rx_buf_out; +static int interrupt_char = VCP_CHAR_NONE; +mp_obj_t mp_const_vcp_interrupt = MP_OBJ_NULL; void pyb_usb_dev_init(void) { #ifdef USE_DEVICE_MODE @@ -33,7 +36,11 @@ void pyb_usb_dev_init(void) { } rx_buf_in = 0; rx_buf_out = 0; + interrupt_char = VCP_CHAR_NONE; dev_is_enabled = 1; + + // create an exception object for interrupting by VCP + mp_const_vcp_interrupt = mp_obj_new_exception(qstr_from_str("VCPInterrupt")); #endif } @@ -41,9 +48,24 @@ bool usb_vcp_is_enabled(void) { return dev_is_enabled; } +void usb_vcp_set_interrupt_char(int c) { + if (dev_is_enabled) { + interrupt_char = c; + } +} + void usb_vcp_receive(const char *buf, uint32_t len) { if (dev_is_enabled) { for (int i = 0; i < len; i++) { + + // catch special interrupt character + if (buf[i] == interrupt_char) { + // raise exception when interrupts are finished + pendsv_nlr_jump(mp_const_vcp_interrupt); + interrupt_char = VCP_CHAR_NONE; + continue; + } + rx_buf[rx_buf_in++] = buf[i]; if (rx_buf_in >= sizeof(rx_buf)) { rx_buf_in = 0; |