From 5cbc9e0db0f01e1e643e8c091a536b54372df5bd Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 27 Nov 2014 16:58:31 +0000 Subject: [PATCH] stmhal: Reduce coupling between USB driver and readline. This makes it easier to re-use readline.c and pyexec.c from stmhal in other ports. --- stmhal/input.c | 2 +- stmhal/mphal.c | 5 +++++ stmhal/mphal.h | 1 + stmhal/pyexec.c | 34 ++++++++++++++++------------------ stmhal/readline.c | 9 ++++----- stmhal/readline.h | 6 ++++++ stmhal/usb.c | 4 ++-- stmhal/usb.h | 7 ------- stmhal/usbd_cdc_interface.c | 12 +++--------- teensy/teensy_hal.c | 6 ++++++ teensy/teensy_hal.h | 1 + teensy/usb.c | 6 ------ 12 files changed, 45 insertions(+), 48 deletions(-) diff --git a/stmhal/input.c b/stmhal/input.c index 7f3b17c6fe..9b67b641c6 100644 --- a/stmhal/input.c +++ b/stmhal/input.c @@ -41,7 +41,7 @@ STATIC mp_obj_t mp_builtin_input(uint n_args, const mp_obj_t *args) { vstr_t line; vstr_init(&line, 16); int ret = readline(&line, ""); - if (line.len == 0 && ret == VCP_CHAR_CTRL_D) { + if (line.len == 0 && ret == CHAR_CTRL_D) { nlr_raise(mp_obj_new_exception(&mp_type_EOFError)); } mp_obj_t o = mp_obj_new_str(line.buf, line.len, false); diff --git a/stmhal/mphal.c b/stmhal/mphal.c index 7fcd982dcb..43e1b9ba36 100644 --- a/stmhal/mphal.c +++ b/stmhal/mphal.c @@ -5,6 +5,7 @@ #include "misc.h" #include "qstr.h" #include "obj.h" +#include "usb.h" #include "mphal.h" // this table converts from HAL_StatusTypeDef to POSIX errno @@ -18,3 +19,7 @@ const byte mp_hal_status_to_errno_table[4] = { NORETURN void mp_hal_raise(HAL_StatusTypeDef status) { nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(mp_hal_status_to_errno_table[status]))); } + +void mp_hal_set_interrupt_char(int c) { + usb_vcp_set_interrupt_char(c); +} diff --git a/stmhal/mphal.h b/stmhal/mphal.h index 4b43cf886d..fb567d1411 100644 --- a/stmhal/mphal.h +++ b/stmhal/mphal.h @@ -10,3 +10,4 @@ extern const byte mp_hal_status_to_errno_table[4]; NORETURN void mp_hal_raise(HAL_StatusTypeDef status); +void mp_hal_set_interrupt_char(int c); // -1 to disable diff --git a/stmhal/pyexec.c b/stmhal/pyexec.c index 3fd797c0d3..6bf8009a19 100644 --- a/stmhal/pyexec.c +++ b/stmhal/pyexec.c @@ -46,8 +46,6 @@ #include "systick.h" #include "readline.h" #include "pyexec.h" -#include "usb.h" -#include "uart.h" #include "pybstdio.h" #include "genhdr/py-version.h" @@ -97,9 +95,9 @@ STATIC int parse_compile_execute(mp_lexer_t *lex, mp_parse_input_kind_t input_ki nlr_buf_t nlr; uint32_t start = HAL_GetTick(); if (nlr_push(&nlr) == 0) { - usb_vcp_set_interrupt_char(VCP_CHAR_CTRL_C); // allow ctrl-C to interrupt us + mp_hal_set_interrupt_char(CHAR_CTRL_C); // allow ctrl-C to interrupt us mp_call_function_0(module_fun); - usb_vcp_set_interrupt_char(VCP_CHAR_NONE); // disable interrupt + mp_hal_set_interrupt_char(-1); // disable interrupt nlr_pop(); ret = 1; if (exec_flags & EXEC_FLAG_PRINT_EOF) { @@ -108,7 +106,7 @@ STATIC int parse_compile_execute(mp_lexer_t *lex, mp_parse_input_kind_t input_ki } else { // uncaught exception // FIXME it could be that an interrupt happens just before we disable it here - usb_vcp_set_interrupt_char(VCP_CHAR_NONE); // disable interrupt + mp_hal_set_interrupt_char(-1); // disable interrupt // print EOF after normal output if (exec_flags & EXEC_FLAG_PRINT_EOF) { stdout_tx_strn("\x04", 1); @@ -125,8 +123,8 @@ STATIC int parse_compile_execute(mp_lexer_t *lex, mp_parse_input_kind_t input_ki // display debugging info if wanted if ((exec_flags & EXEC_FLAG_ALLOW_DEBUGGING) && repl_display_debugging_info) { - uint32_t ticks = HAL_GetTick() - start; // TODO implement a function that does this properly - printf("took %lu ms\n", ticks); + mp_uint_t ticks = HAL_GetTick() - start; // TODO implement a function that does this properly + printf("took " UINT_FMT " ms\n", ticks); gc_collect(); // qstr info { @@ -166,19 +164,19 @@ raw_repl_reset: stdout_tx_str(">"); for (;;) { char c = stdin_rx_chr(); - if (c == VCP_CHAR_CTRL_A) { + if (c == CHAR_CTRL_A) { // reset raw REPL goto raw_repl_reset; - } else if (c == VCP_CHAR_CTRL_B) { + } else if (c == CHAR_CTRL_B) { // change to friendly REPL stdout_tx_str("\r\n"); vstr_clear(&line); pyexec_mode_kind = PYEXEC_MODE_FRIENDLY_REPL; return 0; - } else if (c == VCP_CHAR_CTRL_C) { + } else if (c == CHAR_CTRL_C) { // clear line vstr_reset(&line); - } else if (c == VCP_CHAR_CTRL_D) { + } else if (c == CHAR_CTRL_D) { // input finished break; } else if (c <= 127) { @@ -230,7 +228,7 @@ friendly_repl_reset: for (;;) { nlr_buf_t nlr; printf("pyexec_repl: %p\n", x); - usb_vcp_set_interrupt_char(VCP_CHAR_CTRL_C); + mp_hal_set_interrupt_char(CHAR_CTRL_C); if (nlr_push(&nlr) == 0) { for (;;) { } @@ -246,21 +244,21 @@ friendly_repl_reset: vstr_reset(&line); int ret = readline(&line, ">>> "); - if (ret == VCP_CHAR_CTRL_A) { + if (ret == CHAR_CTRL_A) { // change to raw REPL stdout_tx_str("\r\n"); vstr_clear(&line); pyexec_mode_kind = PYEXEC_MODE_RAW_REPL; return 0; - } else if (ret == VCP_CHAR_CTRL_B) { + } else if (ret == CHAR_CTRL_B) { // reset friendly REPL stdout_tx_str("\r\n"); goto friendly_repl_reset; - } else if (ret == VCP_CHAR_CTRL_C) { + } else if (ret == CHAR_CTRL_C) { // break stdout_tx_str("\r\n"); continue; - } else if (ret == VCP_CHAR_CTRL_D) { + } else if (ret == CHAR_CTRL_D) { // exit for a soft reset stdout_tx_str("\r\n"); vstr_clear(&line); @@ -272,11 +270,11 @@ friendly_repl_reset: while (mp_repl_continue_with_input(vstr_str(&line))) { vstr_add_char(&line, '\n'); int ret = readline(&line, "... "); - if (ret == VCP_CHAR_CTRL_C) { + if (ret == CHAR_CTRL_C) { // cancel everything stdout_tx_str("\r\n"); goto input_restart; - } else if (ret == VCP_CHAR_CTRL_D) { + } else if (ret == CHAR_CTRL_D) { // stop entering compound statement break; } diff --git a/stmhal/readline.c b/stmhal/readline.c index 4b1f48baae..b49156b852 100644 --- a/stmhal/readline.c +++ b/stmhal/readline.c @@ -36,7 +36,6 @@ #include MICROPY_HAL_H #include "readline.h" #include "usb.h" -#include "uart.h" #include "pybstdio.h" #if 0 // print debugging info @@ -80,16 +79,16 @@ int readline(vstr_t *line, const char *prompt) { bool redraw_from_cursor = false; int redraw_step_forward = 0; if (escape_seq == ESEQ_NONE) { - if (VCP_CHAR_CTRL_A <= c && c <= VCP_CHAR_CTRL_D && vstr_len(line) == orig_line_len) { + if (CHAR_CTRL_A <= c && c <= CHAR_CTRL_D && vstr_len(line) == orig_line_len) { // control character with empty line return c; - } else if (c == VCP_CHAR_CTRL_A) { + } else if (c == CHAR_CTRL_A) { // CTRL-A with non-empty line is go-to-start-of-line goto home_key; - } else if (c == VCP_CHAR_CTRL_C) { + } else if (c == CHAR_CTRL_C) { // CTRL-C with non-empty line is cancel return c; - } else if (c == VCP_CHAR_CTRL_E) { + } else if (c == CHAR_CTRL_E) { // CTRL-E is go-to-end-of-line goto end_key; } else if (c == '\r') { diff --git a/stmhal/readline.h b/stmhal/readline.h index 8bbc43b435..d5ce4704ea 100644 --- a/stmhal/readline.h +++ b/stmhal/readline.h @@ -24,5 +24,11 @@ * THE SOFTWARE. */ +#define CHAR_CTRL_A (1) +#define CHAR_CTRL_B (2) +#define CHAR_CTRL_C (3) +#define CHAR_CTRL_D (4) +#define CHAR_CTRL_E (5) + void readline_init0(void); int readline(vstr_t *line, const char *prompt); diff --git a/stmhal/usb.c b/stmhal/usb.c index 2dc7898944..0499aaa8d6 100644 --- a/stmhal/usb.c +++ b/stmhal/usb.c @@ -54,7 +54,7 @@ STATIC mp_obj_t mp_const_vcp_interrupt = MP_OBJ_NULL; void pyb_usb_init0(void) { // create an exception object for interrupting by VCP mp_const_vcp_interrupt = mp_obj_new_exception(&mp_type_KeyboardInterrupt); - USBD_CDC_SetInterrupt(VCP_CHAR_NONE, mp_const_vcp_interrupt); + USBD_CDC_SetInterrupt(-1, mp_const_vcp_interrupt); } void pyb_usb_dev_init(usb_device_mode_t mode, usb_storage_medium_t medium) { @@ -105,7 +105,7 @@ bool usb_vcp_is_connected(void) { void usb_vcp_set_interrupt_char(int c) { if (dev_is_enabled) { - if (c != VCP_CHAR_NONE) { + if (c != -1) { mp_obj_exception_clear_traceback(mp_const_vcp_interrupt); } USBD_CDC_SetInterrupt(c, mp_const_vcp_interrupt); diff --git a/stmhal/usb.h b/stmhal/usb.h index 168bfbd5fe..e0bfe9a76e 100644 --- a/stmhal/usb.h +++ b/stmhal/usb.h @@ -24,13 +24,6 @@ * THE SOFTWARE. */ -#define VCP_CHAR_NONE (0) -#define VCP_CHAR_CTRL_A (1) -#define VCP_CHAR_CTRL_B (2) -#define VCP_CHAR_CTRL_C (3) -#define VCP_CHAR_CTRL_D (4) -#define VCP_CHAR_CTRL_E (5) - typedef enum { USB_DEVICE_MODE_CDC_MSC, USB_DEVICE_MODE_CDC_HID, diff --git a/stmhal/usbd_cdc_interface.c b/stmhal/usbd_cdc_interface.c index 7f1eef5b3e..c09c970f67 100644 --- a/stmhal/usbd_cdc_interface.c +++ b/stmhal/usbd_cdc_interface.c @@ -41,12 +41,6 @@ #include "usbd_cdc_interface.h" #include "pendsv.h" -#include "mpconfig.h" -#include "misc.h" -#include "qstr.h" -#include "obj.h" -#include "usb.h" - // CDC control commands #define CDC_SEND_ENCAPSULATED_COMMAND 0x00 #define CDC_GET_ENCAPSULATED_RESPONSE 0x01 @@ -79,7 +73,7 @@ static uint16_t UserTxBufPtrOutShadow = 0; // shadow of above static uint8_t UserTxBufPtrWaitCount = 0; // used to implement a timeout waiting for low-level USB driver static uint8_t UserTxNeedEmptyPacket = 0; // used to flush the USB IN endpoint if the last packet was exactly the endpoint packet size -static int user_interrupt_char = VCP_CHAR_NONE; +static int user_interrupt_char = -1; static void *user_interrupt_data = NULL; /* USB handler declaration */ @@ -159,7 +153,7 @@ static int8_t CDC_Itf_Init(void) * may be called before this init function to set these values. * This can happen if the USB enumeration occurs after the call to * USBD_CDC_SetInterrupt. - user_interrupt_char = VCP_CHAR_NONE; + user_interrupt_char = -1; user_interrupt_data = NULL; */ @@ -351,7 +345,7 @@ static int8_t CDC_Itf_Receive(uint8_t* Buf, uint32_t *Len) { uint32_t delta_len; - if (user_interrupt_char == VCP_CHAR_NONE) { + if (user_interrupt_char == -1) { // no special interrupt character delta_len = *Len; diff --git a/teensy/teensy_hal.c b/teensy/teensy_hal.c index 39f41ad8ad..6e9a27c30d 100644 --- a/teensy/teensy_hal.c +++ b/teensy/teensy_hal.c @@ -14,3 +14,9 @@ uint32_t HAL_GetTick(void) { void HAL_Delay(uint32_t Delay) { delay(Delay); } + +void mp_hal_set_interrupt_char(int c) { + // The teensy 3.1 usb stack doesn't currently have the notion of generating + // an exception when a certain character is received. That just means that + // you can't press Control-C and get your python script to stop. +} diff --git a/teensy/teensy_hal.h b/teensy/teensy_hal.h index d27116d415..ee434fd209 100644 --- a/teensy/teensy_hal.h +++ b/teensy/teensy_hal.h @@ -114,6 +114,7 @@ __attribute__(( always_inline )) static inline void __WFI(void) { uint32_t HAL_GetTick(void); void HAL_Delay(uint32_t Delay); +void mp_hal_set_interrupt_char(int c); void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *init); diff --git a/teensy/usb.c b/teensy/usb.c index 9fb50967db..d1601c32d3 100644 --- a/teensy/usb.c +++ b/teensy/usb.c @@ -22,12 +22,6 @@ bool usb_vcp_is_enabled(void) return true; } -void usb_vcp_set_interrupt_char(int c) { - // The teensy 3.1 usb stack doesn't currently have the notion of generating - // an exception when a certain character is received. That just means that - // you can't press Control-C and get your python script to stop. -} - int usb_vcp_rx_num(void) { return usb_serial_available(); }