diff --git a/stmhal/pyexec.c b/stmhal/pyexec.c index 75709bb6a9..ecdd4d8c6d 100644 --- a/stmhal/pyexec.c +++ b/stmhal/pyexec.c @@ -49,7 +49,7 @@ int stdin_rx_chr(void) { } #endif #endif - if (usb_vcp_rx_any() != 0) { + if (usb_vcp_rx_num() != 0) { return usb_vcp_rx_get(); } else if (pyb_usart_global_debug != PYB_USART_NONE && usart_rx_any(pyb_usart_global_debug)) { return usart_rx_char(pyb_usart_global_debug); @@ -78,14 +78,16 @@ static const char *readline_hist[READLINE_HIST_SIZE] = {NULL, NULL, NULL, NULL, int readline(vstr_t *line, const char *prompt) { stdout_tx_str(prompt); int len = vstr_len(line); - int escape = 0; + int escape_seq = 0; int hist_num = 0; for (;;) { int c = stdin_rx_chr(); - if (escape == 0) { + if (escape_seq == 0) { if (VCP_CHAR_CTRL_A <= c && c <= VCP_CHAR_CTRL_D && vstr_len(line) == len) { + // control character with empty line return c; } else if (c == '\r') { + // newline stdout_tx_str("\r\n"); for (int i = READLINE_HIST_SIZE - 1; i > 0; i--) { readline_hist[i] = readline_hist[i - 1]; @@ -93,24 +95,27 @@ int readline(vstr_t *line, const char *prompt) { readline_hist[0] = str_dup(vstr_str(line)); return 0; } else if (c == 27) { - escape = true; + // escape sequence + escape_seq = 1; } else if (c == 127) { + // backspace if (vstr_len(line) > len) { vstr_cut_tail(line, 1); stdout_tx_str("\b \b"); } } else if (32 <= c && c <= 126) { + // printable character vstr_add_char(line, c); stdout_tx_str(line->buf + line->len - 1); } - } else if (escape == 1) { + } else if (escape_seq == 1) { if (c == '[') { - escape = 2; + escape_seq = 2; } else { - escape = 0; + escape_seq = 0; } - } else if (escape == 2) { - escape = 0; + } else if (escape_seq == 2) { + escape_seq = 0; if (c == 'A') { // up arrow if (hist_num < READLINE_HIST_SIZE && readline_hist[hist_num] != NULL) { @@ -128,7 +133,7 @@ int readline(vstr_t *line, const char *prompt) { } } } else { - escape = 0; + escape_seq = 0; } HAL_Delay(1); } diff --git a/stmhal/usb.c b/stmhal/usb.c index e6e994a0fa..21b88f9a1c 100644 --- a/stmhal/usb.c +++ b/stmhal/usb.c @@ -71,8 +71,8 @@ void usb_vcp_set_interrupt_char(int c) { } } -int usb_vcp_rx_any(void) { - return USBD_CDC_RxAny(); +int usb_vcp_rx_num(void) { + return USBD_CDC_RxNum(); } char usb_vcp_rx_get(void) { diff --git a/stmhal/usb.h b/stmhal/usb.h index a0fb153240..3e6bdccec2 100644 --- a/stmhal/usb.h +++ b/stmhal/usb.h @@ -11,7 +11,7 @@ void pyb_usb_dev_init(int usb_dev_type); bool usb_vcp_is_enabled(void); bool usb_vcp_is_connected(void); void usb_vcp_set_interrupt_char(int c); -int usb_vcp_rx_any(void); +int usb_vcp_rx_num(void); char usb_vcp_rx_get(void); void usb_vcp_send_str(const char* str); void usb_vcp_send_strn(const char* str, int len); diff --git a/stmhal/usbd_cdc_interface.c b/stmhal/usbd_cdc_interface.c index 49f108ffd3..e441c0b512 100644 --- a/stmhal/usbd_cdc_interface.c +++ b/stmhal/usbd_cdc_interface.c @@ -44,28 +44,23 @@ /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ -#define APP_RX_DATA_SIZE 2048 // I think this must be at least CDC_DATA_FS_OUT_PACKET_SIZE -#define APP_TX_DATA_SIZE 2048 // I think this can be any value +#define APP_RX_DATA_SIZE 1024 // I think this must be at least CDC_DATA_FS_OUT_PACKET_SIZE (was 2048) +#define APP_TX_DATA_SIZE 1024 // I think this can be any value (was 2048) /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ -uint8_t UserRxBuffer[APP_RX_DATA_SIZE];/* Received Data over USB are stored in this buffer */ -uint32_t UserRxBufLen; // counts number of valid characters in UserRxBuffer +static uint8_t UserRxBuffer[APP_RX_DATA_SIZE]; // received data from USB OUT endpoint is stored in this buffer +static uint16_t UserRxBufCur = 0; // points to next available character in UserRxBuffer +static uint16_t UserRxBufLen = 0; // counts number of valid characters in UserRxBuffer -uint8_t UserTxBuffer[APP_TX_DATA_SIZE];/* Received Data over UART (CDC interface) are stored in this buffer */ -uint32_t UserTxBufPtrIn = 0;/* Increment this pointer or roll it back to - start address when data are received over USART */ -uint32_t UserTxBufPtrOut = 0; /* Increment this pointer or roll it back to - start address when data are sent over USB */ +static uint8_t UserTxBuffer[APP_TX_DATA_SIZE]; // data for USB IN endpoind is stored in this buffer +static uint16_t UserTxBufPtrIn = 0; // increment this pointer modulo APP_TX_DATA_SIZE when new data is available +static uint16_t UserTxBufPtrOut = 0; // increment this pointer modulo APP_TX_DATA_SIZE when data is drained static int user_interrupt_char = VCP_CHAR_NONE; static void *user_interrupt_data = NULL; -#if 0 -/* UART handler declaration */ -UART_HandleTypeDef UartHandle; -#endif /* TIM handler declaration */ TIM_HandleTypeDef USBD_CDC_TimHandle; /* USB handler declaration */ @@ -145,7 +140,9 @@ static int8_t CDC_Itf_Init(void) /*##-5- Set Application Buffers ############################################*/ USBD_CDC_SetTxBuffer(&hUSBDDevice, UserTxBuffer, 0); USBD_CDC_SetRxBuffer(&hUSBDDevice, UserRxBuffer); - UserRxBufLen = 0; + + UserRxBufCur = 0; + UserRxBufLen = 0; user_interrupt_char = VCP_CHAR_NONE; user_interrupt_data = NULL; @@ -357,6 +354,9 @@ static int8_t CDC_Itf_Receive(uint8_t* Buf, uint32_t *Len) { } } + // there are new characters at the start of the buffer, so point there + UserRxBufCur = 0; + if (UserRxBufLen == 0) { // initiate next USB packet transfer now that UserRxBuffer has been drained USBD_CDC_ReceivePacket(&hUSBDDevice); @@ -377,16 +377,19 @@ void USBD_CDC_Tx(const char *str, uint32_t len) { } } -int USBD_CDC_RxAny(void) { - return UserRxBufLen; +int USBD_CDC_RxNum(void) { + return UserRxBufLen - UserRxBufCur; } int USBD_CDC_RxGet(void) { - while (UserRxBufLen == 0) { + // wait for buffer to have at least 1 character in it + while (USBD_CDC_RxNum() == 0) { __WFI(); } - int c = UserRxBuffer[--UserRxBufLen]; - if (UserRxBufLen == 0) { + + // get next character + int c = UserRxBuffer[UserRxBufCur++]; + if (UserRxBufCur >= UserRxBufLen) { // initiate next USB packet transfer now that UserRxBuffer has been drained USBD_CDC_ReceivePacket(&hUSBDDevice); } diff --git a/stmhal/usbd_cdc_interface.h b/stmhal/usbd_cdc_interface.h index cabd68c1e0..3411893ae9 100644 --- a/stmhal/usbd_cdc_interface.h +++ b/stmhal/usbd_cdc_interface.h @@ -51,7 +51,7 @@ extern USBD_CDC_ItfTypeDef USBD_CDC_fops; void USBD_CDC_SetInterrupt(int chr, void *data); void USBD_CDC_Tx(const char *str, uint32_t len); -int USBD_CDC_RxAny(void); +int USBD_CDC_RxNum(void); int USBD_CDC_RxGet(void); /* Exported macro ------------------------------------------------------------*/