Commit e285511a authored by Damien George's avatar Damien George
Browse files

stmhal: Get USB CDC REPL working.

New USB HAL is quite a bit improved over previous one.  Now has better
callbacks and flow control.

REPL over USB CDC now works as before, except for soft-reset (since USB
driver uses malloc...).
parent 87e423b8
...@@ -103,6 +103,8 @@ SRC_HAL = $(addprefix $(HAL_DIR)/src/,\ ...@@ -103,6 +103,8 @@ SRC_HAL = $(addprefix $(HAL_DIR)/src/,\
stm32f4xx_hal_gpio.c \ stm32f4xx_hal_gpio.c \
stm32f4xx_hal_pcd.c \ stm32f4xx_hal_pcd.c \
stm32f4xx_hal_rcc.c \ stm32f4xx_hal_rcc.c \
stm32f4xx_hal_tim.c \
stm32f4xx_hal_tim_ex.c \
stm32f4xx_hal_uart.c \ stm32f4xx_hal_uart.c \
stm32f4xx_ll_usb.c \ stm32f4xx_ll_usb.c \
) )
......
...@@ -251,15 +251,15 @@ int main(void) { ...@@ -251,15 +251,15 @@ int main(void) {
pendsv_init(); pendsv_init();
led_init(); led_init();
// turn on LED to indicate bootup
led_state(PYB_LED_GREEN, 1);
#if 0 #if 0
#if MICROPY_HW_ENABLE_RTC #if MICROPY_HW_ENABLE_RTC
rtc_init(); rtc_init();
#endif #endif
#endif #endif
// turn on LED to indicate bootup
led_state(PYB_LED_G1, 1);
#if 0 #if 0
// more sub-system init // more sub-system init
#if MICROPY_HW_HAS_SDCARD #if MICROPY_HW_HAS_SDCARD
...@@ -454,7 +454,7 @@ soft_reset: ...@@ -454,7 +454,7 @@ soft_reset:
} }
// turn boot-up LED off // turn boot-up LED off
led_state(PYB_LED_G1, 0); led_state(PYB_LED_GREEN, 0);
#if 0 #if 0
#if MICROPY_HW_HAS_SDCARD #if MICROPY_HW_HAS_SDCARD
...@@ -481,21 +481,6 @@ soft_reset: ...@@ -481,21 +481,6 @@ soft_reset:
pyb_usb_dev_init(PYB_USB_DEV_VCP_MSC); pyb_usb_dev_init(PYB_USB_DEV_VCP_MSC);
#endif #endif
#if 0
// test USB CDC
extern uint8_t UserTxBuffer[];/* Received Data over UART (CDC interface) are stored in this buffer */
extern uint32_t UserTxBufPtrOut; /* Increment this pointer or roll it back to
start address when data are sent over USB */
for (;;) {
UserTxBuffer[UserTxBufPtrOut++] = 'a';
UserTxBuffer[UserTxBufPtrOut++] = 'b';
UserTxBuffer[UserTxBufPtrOut++] = 'c';
UserTxBuffer[UserTxBufPtrOut++] = 'd';
HAL_Delay(500);
led_toggle(PYB_LED_BLUE);
}
#endif
#if 0 #if 0
// run main script // run main script
{ {
......
...@@ -12,9 +12,7 @@ ...@@ -12,9 +12,7 @@
#include "lcd.h" #include "lcd.h"
#endif #endif
#include "usart.h" #include "usart.h"
#if 0
#include "usb.h" #include "usb.h"
#endif
#if MICROPY_ENABLE_FLOAT #if MICROPY_ENABLE_FLOAT
#include "formatfloat.h" #include "formatfloat.h"
...@@ -273,12 +271,10 @@ void stdout_print_strn(void *data, const char *str, unsigned int len) { ...@@ -273,12 +271,10 @@ void stdout_print_strn(void *data, const char *str, unsigned int len) {
usart_tx_strn_cooked(pyb_usart_global_debug, str, len); usart_tx_strn_cooked(pyb_usart_global_debug, str, len);
any = true; any = true;
} }
#if 0
if (usb_vcp_is_enabled()) { if (usb_vcp_is_enabled()) {
usb_vcp_send_strn_cooked(str, len); usb_vcp_send_strn_cooked(str, len);
any = true; any = true;
} }
#endif
if (!any) { if (!any) {
#if 0 #if 0
#if MICROPY_HW_HAS_LCD #if MICROPY_HW_HAS_LCD
......
...@@ -22,8 +22,8 @@ ...@@ -22,8 +22,8 @@
#include "pyexec.h" #include "pyexec.h"
#if 0 #if 0
#include "storage.h" #include "storage.h"
#include "usb.h"
#endif #endif
#include "usb.h"
#include "usart.h" #include "usart.h"
static bool repl_display_debugging_info = 0; static bool repl_display_debugging_info = 0;
...@@ -35,9 +35,7 @@ void stdout_tx_str(const char *str) { ...@@ -35,9 +35,7 @@ void stdout_tx_str(const char *str) {
#if defined(USE_HOST_MODE) && MICROPY_HW_HAS_LCD #if defined(USE_HOST_MODE) && MICROPY_HW_HAS_LCD
lcd_print_str(str); lcd_print_str(str);
#endif #endif
#if 0
usb_vcp_send_str(str); usb_vcp_send_str(str);
#endif
} }
int stdin_rx_chr(void) { int stdin_rx_chr(void) {
...@@ -51,12 +49,9 @@ int stdin_rx_chr(void) { ...@@ -51,12 +49,9 @@ int stdin_rx_chr(void) {
} }
#endif #endif
#endif #endif
#if 0
if (usb_vcp_rx_any() != 0) { if (usb_vcp_rx_any() != 0) {
return usb_vcp_rx_get(); return usb_vcp_rx_get();
} else } else if (pyb_usart_global_debug != PYB_USART_NONE && usart_rx_any(pyb_usart_global_debug)) {
#endif
if (pyb_usart_global_debug != PYB_USART_NONE && usart_rx_any(pyb_usart_global_debug)) {
return usart_rx_char(pyb_usart_global_debug); return usart_rx_char(pyb_usart_global_debug);
} }
HAL_Delay(1); HAL_Delay(1);
...@@ -80,13 +75,6 @@ char *str_dup(const char *str) { ...@@ -80,13 +75,6 @@ char *str_dup(const char *str) {
static const char *readline_hist[READLINE_HIST_SIZE] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; static const char *readline_hist[READLINE_HIST_SIZE] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
#if 0
#else
#define VCP_CHAR_CTRL_A (1)
#define VCP_CHAR_CTRL_C (3)
#define VCP_CHAR_CTRL_D (4)
#endif
int readline(vstr_t *line, const char *prompt) { int readline(vstr_t *line, const char *prompt) {
stdout_tx_str(prompt); stdout_tx_str(prompt);
int len = vstr_len(line); int len = vstr_len(line);
...@@ -173,21 +161,15 @@ bool parse_compile_execute(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, bo ...@@ -173,21 +161,15 @@ bool parse_compile_execute(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, bo
bool ret; bool ret;
uint32_t start = HAL_GetTick(); uint32_t start = HAL_GetTick();
if (nlr_push(&nlr) == 0) { if (nlr_push(&nlr) == 0) {
#if 0
usb_vcp_set_interrupt_char(VCP_CHAR_CTRL_C); // allow ctrl-C to interrupt us usb_vcp_set_interrupt_char(VCP_CHAR_CTRL_C); // allow ctrl-C to interrupt us
#endif
rt_call_function_0(module_fun); rt_call_function_0(module_fun);
#if 0
usb_vcp_set_interrupt_char(VCP_CHAR_NONE); // disable interrupt usb_vcp_set_interrupt_char(VCP_CHAR_NONE); // disable interrupt
#endif
nlr_pop(); nlr_pop();
ret = true; ret = true;
} else { } else {
// uncaught exception // uncaught exception
// FIXME it could be that an interrupt happens just before we disable it here // FIXME it could be that an interrupt happens just before we disable it here
#if 0
usb_vcp_set_interrupt_char(VCP_CHAR_NONE); // disable interrupt usb_vcp_set_interrupt_char(VCP_CHAR_NONE); // disable interrupt
#endif
mp_obj_print_exception((mp_obj_t)nlr.ret_val); mp_obj_print_exception((mp_obj_t)nlr.ret_val);
ret = false; ret = false;
} }
......
...@@ -47,6 +47,8 @@ ...@@ -47,6 +47,8 @@
/* Includes ------------------------------------------------------------------*/ /* Includes ------------------------------------------------------------------*/
#include "stm32f4xx_hal.h" #include "stm32f4xx_hal.h"
#include "usbd_cdc.h"
#include "usbd_cdc_interface.h"
/** @addtogroup STM32F4xx_HAL_Driver /** @addtogroup STM32F4xx_HAL_Driver
* @{ * @{
...@@ -73,11 +75,11 @@ ...@@ -73,11 +75,11 @@
* @param None * @param None
* @retval None * @retval None
*/ */
void HAL_MspInit(void) void HAL_MspInit(void) {
{ // set up the timer for USBD CDC
/* NOTE : This function is generated automatically by MicroXplorer and eventually USBD_CDC_TIMx_CLK_ENABLE();
modified by the user HAL_NVIC_SetPriority(USBD_CDC_TIMx_IRQn, 6, 0);
*/ HAL_NVIC_EnableIRQ(USBD_CDC_TIMx_IRQn);
} }
/** /**
...@@ -85,11 +87,10 @@ void HAL_MspInit(void) ...@@ -85,11 +87,10 @@ void HAL_MspInit(void)
* @param None * @param None
* @retval None * @retval None
*/ */
void HAL_MspDeInit(void) void HAL_MspDeInit(void) {
{ // reset USBD CDC timer
/* NOTE : This function is generated automatically by MicroXplorer and eventually USBD_CDC_TIMx_FORCE_RESET();
modified by the user USBD_CDC_TIMx_RELEASE_RESET();
*/
} }
/** /**
......
...@@ -64,6 +64,7 @@ ...@@ -64,6 +64,7 @@
extern void fatality(); extern void fatality();
extern PCD_HandleTypeDef hpcd; extern PCD_HandleTypeDef hpcd;
extern TIM_HandleTypeDef USBD_CDC_TimHandle;
/* Private function prototypes -----------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/ /* Private functions ---------------------------------------------------------*/
...@@ -348,4 +349,9 @@ void RTC_WKUP_IRQHandler(void) { ...@@ -348,4 +349,9 @@ void RTC_WKUP_IRQHandler(void) {
Handle_EXTI_Irq(EXTI_RTC_WAKEUP); Handle_EXTI_Irq(EXTI_RTC_WAKEUP);
} }
void TIM3_IRQHandler(void) {
// USBD CDC timer is TIM3
HAL_TIM_IRQHandler(&USBD_CDC_TimHandle);
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
...@@ -15,20 +15,15 @@ ...@@ -15,20 +15,15 @@
#include "mpconfig.h" #include "mpconfig.h"
#include "qstr.h" #include "qstr.h"
#include "obj.h" #include "obj.h"
#include "pendsv.h" //#include "pendsv.h"
#include "usb.h" #include "usb.h"
#ifdef USE_DEVICE_MODE #ifdef USE_DEVICE_MODE
//extern CDC_IF_Prop_TypeDef VCP_fops;
USBD_HandleTypeDef hUSBDDevice; USBD_HandleTypeDef hUSBDDevice;
#endif #endif
static int dev_is_enabled = 0; static int dev_is_enabled = 0;
uint32_t APP_dev_is_connected = 0; /* used by usbd_cdc_vcp */ uint32_t APP_dev_is_connected = 0; /* used by usbd_cdc_vcp */
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; mp_obj_t mp_const_vcp_interrupt = MP_OBJ_NULL;
void pyb_usb_dev_init(int usb_dev_type) { void pyb_usb_dev_init(int usb_dev_type) {
...@@ -52,9 +47,6 @@ void pyb_usb_dev_init(int usb_dev_type) { ...@@ -52,9 +47,6 @@ void pyb_usb_dev_init(int usb_dev_type) {
break; break;
} }
} }
rx_buf_in = 0;
rx_buf_out = 0;
interrupt_char = VCP_CHAR_NONE;
dev_is_enabled = 1; dev_is_enabled = 1;
// create an exception object for interrupting by VCP // create an exception object for interrupting by VCP
...@@ -72,54 +64,19 @@ bool usb_vcp_is_connected(void) { ...@@ -72,54 +64,19 @@ bool usb_vcp_is_connected(void) {
void usb_vcp_set_interrupt_char(int c) { void usb_vcp_set_interrupt_char(int c) {
if (dev_is_enabled) { if (dev_is_enabled) {
interrupt_char = c; if (c != VCP_CHAR_NONE) {
} mp_obj_exception_clear_traceback(mp_const_vcp_interrupt);
}
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
mp_obj_exception_clear_traceback(mp_const_vcp_interrupt);
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;
}
if (rx_buf_in == rx_buf_out) {
rx_buf_out = rx_buf_in + 1;
if (rx_buf_out >= sizeof(rx_buf)) {
rx_buf_out = 0;
}
}
} }
USBD_CDC_SetInterrupt(c, mp_const_vcp_interrupt);
} }
} }
int usb_vcp_rx_any(void) { int usb_vcp_rx_any(void) {
if (rx_buf_in >= rx_buf_out) { return USBD_CDC_RxAny();
return rx_buf_in - rx_buf_out;
} else {
return rx_buf_in + sizeof(rx_buf) - rx_buf_out;
}
} }
char usb_vcp_rx_get(void) { char usb_vcp_rx_get(void) {
while (rx_buf_out == rx_buf_in) { return USBD_CDC_RxGet();
}
char c = rx_buf[rx_buf_out];
rx_buf_out += 1;
if (rx_buf_out >= sizeof(rx_buf)) {
rx_buf_out = 0;
}
return c;
} }
void usb_vcp_send_str(const char *str) { void usb_vcp_send_str(const char *str) {
...@@ -129,39 +86,22 @@ void usb_vcp_send_str(const char *str) { ...@@ -129,39 +86,22 @@ void usb_vcp_send_str(const char *str) {
void usb_vcp_send_strn(const char *str, int len) { void usb_vcp_send_strn(const char *str, int len) {
#ifdef USE_DEVICE_MODE #ifdef USE_DEVICE_MODE
if (dev_is_enabled) { if (dev_is_enabled) {
#if 0 USBD_CDC_Tx(str, len);
USBD_CDC_fops.pIf_DataTx((const uint8_t*)str, len);
#endif
} }
#endif #endif
} }
#include "usbd_conf.h"
/* These are external variables imported from CDC core to be used for IN
transfer management. */
#ifdef USE_DEVICE_MODE
extern uint8_t UserRxBuffer[];/* Received Data over USB are stored in this buffer */
extern uint8_t UserTxBuffer[];/* Received Data over UART (CDC interface) are stored in this buffer */
extern uint32_t BuffLength;
extern uint32_t UserTxBufPtrIn;/* Increment this pointer or roll it back to
start address when data are received over USART */
extern uint32_t UserTxBufPtrOut; /* Increment this pointer or roll it back to
start address when data are sent over USB */
#endif
void usb_vcp_send_strn_cooked(const char *str, int len) { void usb_vcp_send_strn_cooked(const char *str, int len) {
#ifdef USE_DEVICE_MODE #ifdef USE_DEVICE_MODE
#if 0 if (dev_is_enabled) {
for (const char *top = str + len; str < top; str++) { for (const char *top = str + len; str < top; str++) {
if (*str == '\n') { if (*str == '\n') {
APP_Rx_Buffer[APP_Rx_ptr_in] = '\r'; USBD_CDC_Tx("\r\n", 2);
APP_Rx_ptr_in = (APP_Rx_ptr_in + 1) & (APP_RX_DATA_SIZE - 1); } else {
USBD_CDC_Tx(str, 1);
}
} }
APP_Rx_Buffer[APP_Rx_ptr_in] = *str;
APP_Rx_ptr_in = (APP_Rx_ptr_in + 1) & (APP_RX_DATA_SIZE - 1);
} }
#endif
#endif #endif
} }
......
...@@ -26,8 +26,12 @@ ...@@ -26,8 +26,12 @@
*/ */
/* Includes ------------------------------------------------------------------*/ /* Includes ------------------------------------------------------------------*/
#include <stdbool.h>
#include "stm32f4xx_hal.h" #include "stm32f4xx_hal.h"
#include "usbd_cdc.h"
#include "usbd_cdc_interface.h" #include "usbd_cdc_interface.h"
#include "pendsv.h"
#include "usb.h"
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY /** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
* @{ * @{
...@@ -40,33 +44,32 @@ ...@@ -40,33 +44,32 @@
/* Private typedef -----------------------------------------------------------*/ /* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/
#define APP_RX_DATA_SIZE 2048 #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 #define APP_TX_DATA_SIZE 2048 // I think this can be any value
/* Private macro -------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/
USBD_CDC_LineCodingTypeDef LineCoding =
{
115200, /* baud rate*/
0x00, /* stop bits-1*/
0x00, /* parity - none*/
0x08 /* nb. of bits 8*/
};
uint8_t UserRxBuffer[APP_RX_DATA_SIZE];/* Received Data over USB are stored in this buffer */ 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
uint8_t UserTxBuffer[APP_TX_DATA_SIZE];/* Received Data over UART (CDC interface) are stored in this buffer */ uint8_t UserTxBuffer[APP_TX_DATA_SIZE];/* Received Data over UART (CDC interface) are stored in this buffer */
uint32_t BuffLength;
uint32_t UserTxBufPtrIn = 0;/* Increment this pointer or roll it back to uint32_t UserTxBufPtrIn = 0;/* Increment this pointer or roll it back to
start address when data are received over USART */ start address when data are received over USART */
uint32_t UserTxBufPtrOut = 0; /* Increment this pointer or roll it back to uint32_t UserTxBufPtrOut = 0; /* Increment this pointer or roll it back to
start address when data are sent over USB */ start address when data are sent over USB */
static int user_interrupt_char = VCP_CHAR_NONE;
static void *user_interrupt_data = NULL;
#if 0
/* UART handler declaration */ /* UART handler declaration */
UART_HandleTypeDef UartHandle; UART_HandleTypeDef UartHandle;
#endif
/* TIM handler declaration */ /* TIM handler declaration */
TIM_HandleTypeDef TimHandle; TIM_HandleTypeDef USBD_CDC_TimHandle;
/* USB handler declaration */ /* USB handler declaration */
extern USBD_HandleTypeDef hUSBDDevice; extern USBD_HandleTypeDef hUSBDDevice;
/* Private function prototypes -----------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/
static int8_t CDC_Itf_Init (void); static int8_t CDC_Itf_Init (void);
...@@ -75,8 +78,8 @@ static int8_t CDC_Itf_Control (uint8_t cmd, uint8_t* pbuf, uint16_t length); ...@@ -75,8 +78,8 @@ static int8_t CDC_Itf_Control (uint8_t cmd, uint8_t* pbuf, uint16_t length);
static int8_t CDC_Itf_Receive (uint8_t* pbuf, uint32_t *Len); static int8_t CDC_Itf_Receive (uint8_t* pbuf, uint32_t *Len);
static void Error_Handler(void); static void Error_Handler(void);
static void ComPort_Config(void); //static void ComPort_Config(void);
//static void TIM_Config(void); static void TIM_Config(void);
USBD_CDC_ItfTypeDef USBD_CDC_fops = USBD_CDC_ItfTypeDef USBD_CDC_fops =
{ {
...@@ -126,23 +129,27 @@ static int8_t CDC_Itf_Init(void) ...@@ -126,23 +129,27 @@ static int8_t CDC_Itf_Init(void)
/* Transfer error in reception process */ /* Transfer error in reception process */
Error_Handler(); Error_Handler();
} }
#endif
/*##-3- Configure the TIM Base generation #################################*/ /*##-3- Configure the TIM Base generation #################################*/
TIM_Config(); TIM_Config();
/*##-4- Start the TIM Base generation in interrupt mode ####################*/ /*##-4- Start the TIM Base generation in interrupt mode ####################*/
/* Start Channel1 */ /* Start Channel1 */
if(HAL_TIM_Base_Start_IT(&TimHandle) != HAL_OK) if(HAL_TIM_Base_Start_IT(&USBD_CDC_TimHandle) != HAL_OK)
{ {
/* Starting Error */ /* Starting Error */
Error_Handler(); Error_Handler();
} }
#endif
/*##-5- Set Application Buffers ############################################*/ /*##-5- Set Application Buffers ############################################*/
USBD_CDC_SetTxBuffer(&hUSBDDevice, UserTxBuffer, 0); USBD_CDC_SetTxBuffer(&hUSBDDevice, UserTxBuffer, 0);
USBD_CDC_SetRxBuffer(&hUSBDDevice, UserRxBuffer); USBD_CDC_SetRxBuffer(&hUSBDDevice, UserRxBuffer);
UserRxBufLen = 0;
user_interrupt_char = VCP_CHAR_NONE;
user_interrupt_data = NULL;
return (USBD_OK); return (USBD_OK);
} }
...@@ -198,6 +205,7 @@ static int8_t CDC_Itf_Control (uint8_t cmd, uint8_t* pbuf, uint16_t length) ...@@ -198,6 +205,7 @@ static int8_t CDC_Itf_Control (uint8_t cmd, uint8_t* pbuf, uint16_t length)
break; break;
case CDC_SET_LINE_CODING: case CDC_SET_LINE_CODING:
#if 0
LineCoding.bitrate = (uint32_t)(pbuf[0] | (pbuf[1] << 8) |\ LineCoding.bitrate = (uint32_t)(pbuf[0] | (pbuf[1] << 8) |\
(pbuf[2] << 16) | (pbuf[3] << 24)); (pbuf[2] << 16) | (pbuf[3] << 24));
LineCoding.format = pbuf[4]; LineCoding.format = pbuf[4];
...@@ -206,9 +214,11 @@ static int8_t CDC_Itf_Control (uint8_t cmd, uint8_t* pbuf, uint16_t length) ...@@ -206,9 +214,11 @@ static int8_t CDC_Itf_Control (uint8_t cmd, uint8_t* pbuf, uint16_t length)
/* Set the new configuration */ /* Set the new configuration */
ComPort_Config(); ComPort_Config();
#endif
break; break;