stmhal: Fix escape sequences in USB CDC input.
This commit is contained in:
parent
e285511a23
commit
07174c6fca
@ -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);
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 ------------------------------------------------------------*/
|
||||
|
Loading…
Reference in New Issue
Block a user