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...).
This commit is contained in:
parent
87e423b866
commit
e285511a23
@ -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) {
|
|||||||
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:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 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:
|
|||||||
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 @@
|
|||||||
#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) {
|
|||||||
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 @@
|
|||||||
#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) {
|
|||||||
#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) {
|
|||||||
}
|
}
|
||||||
#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) {
|
|||||||
|
|
||||||
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
|
|||||||
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 @@
|
|||||||
|
|
||||||
/* 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 @@
|
|||||||
* @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)
|
|||||||
* @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 @@
|
|||||||
|
|
||||||
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) {
|
|||||||
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****/
|
||||||
|
88
stmhal/usb.c
88
stmhal/usb.c
@ -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) {
|
|||||||
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) {
|
|||||||
|
|
||||||
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) {
|
|||||||
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 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* 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 @@
|
|||||||
|
|
||||||
/* 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);
|
|||||||
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)
|
|||||||
/* 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)
|
|||||||
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)
|
|||||||
|
|
||||||
/* Set the new configuration */
|
/* Set the new configuration */
|
||||||
ComPort_Config();
|
ComPort_Config();
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CDC_GET_LINE_CODING:
|
case CDC_GET_LINE_CODING:
|
||||||
|
#if 0
|
||||||
pbuf[0] = (uint8_t)(LineCoding.bitrate);
|
pbuf[0] = (uint8_t)(LineCoding.bitrate);
|
||||||
pbuf[1] = (uint8_t)(LineCoding.bitrate >> 8);
|
pbuf[1] = (uint8_t)(LineCoding.bitrate >> 8);
|
||||||
pbuf[2] = (uint8_t)(LineCoding.bitrate >> 16);
|
pbuf[2] = (uint8_t)(LineCoding.bitrate >> 16);
|
||||||
@ -216,8 +226,16 @@ static int8_t CDC_Itf_Control (uint8_t cmd, uint8_t* pbuf, uint16_t length)
|
|||||||
pbuf[4] = LineCoding.format;
|
pbuf[4] = LineCoding.format;
|
||||||
pbuf[5] = LineCoding.paritytype;
|
pbuf[5] = LineCoding.paritytype;
|
||||||
pbuf[6] = LineCoding.datatype;
|
pbuf[6] = LineCoding.datatype;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Add your code here */
|
/* Add your code here */
|
||||||
|
pbuf[0] = (uint8_t)(115200);
|
||||||
|
pbuf[1] = (uint8_t)(115200 >> 8);
|
||||||
|
pbuf[2] = (uint8_t)(115200 >> 16);
|
||||||
|
pbuf[3] = (uint8_t)(115200 >> 24);
|
||||||
|
pbuf[4] = 0; // stop bits (1)
|
||||||
|
pbuf[5] = 0; // parity (none)
|
||||||
|
pbuf[6] = 8; // number of bits (8)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CDC_SET_CONTROL_LINE_STATE:
|
case CDC_SET_CONTROL_LINE_STATE:
|
||||||
@ -271,6 +289,7 @@ void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
/**
|
/**
|
||||||
* @brief Rx Transfer completed callback
|
* @brief Rx Transfer completed callback
|
||||||
* @param huart: UART handle
|
* @param huart: UART handle
|
||||||
@ -290,21 +309,91 @@ void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
|
|||||||
/* Start another reception: provide the buffer pointer with offset and the buffer size */
|
/* Start another reception: provide the buffer pointer with offset and the buffer size */
|
||||||
HAL_UART_Receive_IT(huart, (uint8_t *)(UserTxBuffer + UserTxBufPtrIn), 1);
|
HAL_UART_Receive_IT(huart, (uint8_t *)(UserTxBuffer + UserTxBufPtrIn), 1);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief CDC_Itf_DataRx
|
* @brief CDC_Itf_DataRx
|
||||||
* Data received over USB OUT endpoint are sent over CDC interface
|
* Data received over USB OUT endpoint is processed here.
|
||||||
* through this function.
|
* @param Buf: Buffer of data received
|
||||||
* @param Buf: Buffer of data to be transmitted
|
|
||||||
* @param Len: Number of data received (in bytes)
|
* @param Len: Number of data received (in bytes)
|
||||||
* @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL
|
* @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL
|
||||||
|
* @note The buffer we are passed here is just UserRxBuffer, so we are
|
||||||
|
* free to modify it.
|
||||||
*/
|
*/
|
||||||
static int8_t CDC_Itf_Receive(uint8_t* Buf, uint32_t *Len)
|
static int8_t CDC_Itf_Receive(uint8_t* Buf, uint32_t *Len) {
|
||||||
{
|
#if 0
|
||||||
HAL_UART_Transmit_DMA(&UartHandle, Buf, *Len);
|
// this sends the data over the UART using DMA
|
||||||
return (USBD_OK);
|
HAL_UART_Transmit_DMA(&UartHandle, Buf, *Len);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (user_interrupt_char == VCP_CHAR_NONE) {
|
||||||
|
// no special interrupt character
|
||||||
|
UserRxBufLen = *Len;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// filter out sepcial interrupt character from the buffer
|
||||||
|
bool char_found = false;
|
||||||
|
uint8_t *dest = Buf;
|
||||||
|
uint8_t *src = Buf;
|
||||||
|
uint8_t *buf_top = Buf + *Len;
|
||||||
|
for (; src < buf_top; src++) {
|
||||||
|
if (*src == user_interrupt_char) {
|
||||||
|
char_found = true;
|
||||||
|
} else {
|
||||||
|
if (char_found) {
|
||||||
|
*dest = *src;
|
||||||
|
}
|
||||||
|
dest++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// set length of remaining characters
|
||||||
|
UserRxBufLen = dest - Buf;
|
||||||
|
|
||||||
|
if (char_found) {
|
||||||
|
// raise exception when interrupts are finished
|
||||||
|
user_interrupt_char = VCP_CHAR_NONE;
|
||||||
|
pendsv_nlr_jump(user_interrupt_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UserRxBufLen == 0) {
|
||||||
|
// initiate next USB packet transfer now that UserRxBuffer has been drained
|
||||||
|
USBD_CDC_ReceivePacket(&hUSBDDevice);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (USBD_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void USBD_CDC_SetInterrupt(int chr, void *data) {
|
||||||
|
user_interrupt_char = chr;
|
||||||
|
user_interrupt_data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void USBD_CDC_Tx(const char *str, uint32_t len) {
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
UserTxBuffer[UserTxBufPtrIn] = str[i];
|
||||||
|
UserTxBufPtrIn = (UserTxBufPtrIn + 1) & (APP_TX_DATA_SIZE - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int USBD_CDC_RxAny(void) {
|
||||||
|
return UserRxBufLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
int USBD_CDC_RxGet(void) {
|
||||||
|
while (UserRxBufLen == 0) {
|
||||||
|
__WFI();
|
||||||
|
}
|
||||||
|
int c = UserRxBuffer[--UserRxBufLen];
|
||||||
|
if (UserRxBufLen == 0) {
|
||||||
|
// initiate next USB packet transfer now that UserRxBuffer has been drained
|
||||||
|
USBD_CDC_ReceivePacket(&hUSBDDevice);
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
/**
|
/**
|
||||||
* @brief Tx Transfer completed callback
|
* @brief Tx Transfer completed callback
|
||||||
* @param huart: UART handle
|
* @param huart: UART handle
|
||||||
@ -398,17 +487,17 @@ static void ComPort_Config(void)
|
|||||||
/* Start reception: provide the buffer pointer with offset and the buffer size */
|
/* Start reception: provide the buffer pointer with offset and the buffer size */
|
||||||
HAL_UART_Receive_IT(&UartHandle, (uint8_t *)(UserTxBuffer + UserTxBufPtrIn), 1);
|
HAL_UART_Receive_IT(&UartHandle, (uint8_t *)(UserTxBuffer + UserTxBufPtrIn), 1);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief TIM_Config: Configure TIMx timer
|
* @brief TIM_Config: Configure TIMx timer
|
||||||
* @param None.
|
* @param None.
|
||||||
* @retval None.
|
* @retval None.
|
||||||
*/
|
*/
|
||||||
#if 0
|
|
||||||
static void TIM_Config(void)
|
static void TIM_Config(void)
|
||||||
{
|
{
|
||||||
/* Set TIMx instance */
|
/* Set TIMx instance */
|
||||||
TimHandle.Instance = TIMx;
|
USBD_CDC_TimHandle.Instance = USBD_CDC_TIMx;
|
||||||
|
|
||||||
/* Initialize TIM3 peripheral as follow:
|
/* Initialize TIM3 peripheral as follow:
|
||||||
+ Period = 10000 - 1
|
+ Period = 10000 - 1
|
||||||
@ -416,18 +505,18 @@ static void TIM_Config(void)
|
|||||||
+ ClockDivision = 0
|
+ ClockDivision = 0
|
||||||
+ Counter direction = Up
|
+ Counter direction = Up
|
||||||
*/
|
*/
|
||||||
TimHandle.Init.Period = (CDC_POLLING_INTERVAL*1000) - 1;
|
USBD_CDC_TimHandle.Init.Period = (USBD_CDC_POLLING_INTERVAL*1000) - 1;
|
||||||
TimHandle.Init.Prescaler = 84-1;
|
USBD_CDC_TimHandle.Init.Prescaler = 84-1;
|
||||||
TimHandle.Init.ClockDivision = 0;
|
USBD_CDC_TimHandle.Init.ClockDivision = 0;
|
||||||
TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
|
USBD_CDC_TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
|
||||||
if(HAL_TIM_Base_Init(&TimHandle) != HAL_OK)
|
if(HAL_TIM_Base_Init(&USBD_CDC_TimHandle) != HAL_OK)
|
||||||
{
|
{
|
||||||
/* Initialization Error */
|
/* Initialization Error */
|
||||||
Error_Handler();
|
Error_Handler();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
/**
|
/**
|
||||||
* @brief UART error callbacks
|
* @brief UART error callbacks
|
||||||
* @param UartHandle: UART handle
|
* @param UartHandle: UART handle
|
||||||
@ -438,6 +527,7 @@ void HAL_UART_ErrorCallback(UART_HandleTypeDef *UartHandle)
|
|||||||
/* Transfer error occured in reception and/or transmission process */
|
/* Transfer error occured in reception and/or transmission process */
|
||||||
Error_Handler();
|
Error_Handler();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function is executed in case of error occurrence.
|
* @brief This function is executed in case of error occurrence.
|
||||||
|
@ -30,55 +30,29 @@
|
|||||||
#define __USBD_CDC_IF_H
|
#define __USBD_CDC_IF_H
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
/* Includes ------------------------------------------------------------------*/
|
||||||
#include "usbd_cdc.h"
|
|
||||||
|
|
||||||
/* Exported types ------------------------------------------------------------*/
|
/* Exported types ------------------------------------------------------------*/
|
||||||
/* Exported constants --------------------------------------------------------*/
|
/* Exported constants --------------------------------------------------------*/
|
||||||
/* User can use this section to tailor USARTx/UARTx instance used and associated
|
|
||||||
resources */
|
|
||||||
/* Definition for USARTx clock resources */
|
|
||||||
#define USARTx USART3
|
|
||||||
#define USARTx_CLK_ENABLE() __USART3_CLK_ENABLE();
|
|
||||||
#define DMAx_CLK_ENABLE() __DMA1_CLK_ENABLE()
|
|
||||||
#define USARTx_RX_GPIO_CLK_ENABLE() __GPIOC_CLK_ENABLE()
|
|
||||||
#define USARTx_TX_GPIO_CLK_ENABLE() __GPIOC_CLK_ENABLE()
|
|
||||||
|
|
||||||
#define USARTx_FORCE_RESET() __USART3_FORCE_RESET()
|
|
||||||
#define USARTx_RELEASE_RESET() __USART3_RELEASE_RESET()
|
|
||||||
|
|
||||||
/* Definition for USARTx Pins */
|
|
||||||
#define USARTx_TX_PIN GPIO_PIN_10
|
|
||||||
#define USARTx_TX_GPIO_PORT GPIOC
|
|
||||||
#define USARTx_TX_AF GPIO_AF7_USART3
|
|
||||||
#define USARTx_RX_PIN GPIO_PIN_11
|
|
||||||
#define USARTx_RX_GPIO_PORT GPIOC
|
|
||||||
#define USARTx_RX_AF GPIO_AF7_USART3
|
|
||||||
|
|
||||||
/* Definition for USARTx's NVIC: used for receiving data over Rx pin */
|
|
||||||
#define USARTx_IRQn USART3_IRQn
|
|
||||||
#define USARTx_IRQHandler USART3_IRQHandler
|
|
||||||
|
|
||||||
/* Definition for USARTx's DMA: used for transmitting data over Tx pin */
|
|
||||||
#define USARTx_TX_DMA_CHANNEL DMA_CHANNEL_4
|
|
||||||
#define USARTx_TX_DMA_STREAM DMA1_Stream3
|
|
||||||
#define USARTx_DMA_TX_IRQHandler DMA1_Stream3_IRQHandler
|
|
||||||
#define USARTx_DMA_TX_IRQn DMA1_Stream3_IRQn
|
|
||||||
|
|
||||||
/* Definition for TIMx clock resources */
|
/* Definition for TIMx clock resources */
|
||||||
#define TIMx TIM3
|
#define USBD_CDC_TIMx TIM3
|
||||||
#define TIMx_CLK_ENABLE __TIM3_CLK_ENABLE
|
#define USBD_CDC_TIMx_CLK_ENABLE __TIM3_CLK_ENABLE
|
||||||
#define TIMx_FORCE_RESET() __USART3_FORCE_RESET()
|
#define USBD_CDC_TIMx_FORCE_RESET() __USART3_FORCE_RESET()
|
||||||
#define TIMx_RELEASE_RESET() __USART3_RELEASE_RESET()
|
#define USBD_CDC_TIMx_RELEASE_RESET() __USART3_RELEASE_RESET()
|
||||||
|
|
||||||
/* Definition for TIMx's NVIC */
|
/* Definition for TIMx's NVIC */
|
||||||
#define TIMx_IRQn TIM3_IRQn
|
#define USBD_CDC_TIMx_IRQn TIM3_IRQn
|
||||||
#define TIMx_IRQHandler TIM3_IRQHandler
|
//#define USBD_CDC_TIMx_IRQHandler TIM3_IRQHandler // this is hard coded in stm32f4xx_it.c
|
||||||
|
|
||||||
/* Periodically, the state of the buffer "UserTxBuffer" is checked.
|
/* Periodically, the state of the buffer "UserTxBuffer" is checked.
|
||||||
The period depends on CDC_POLLING_INTERVAL */
|
The period depends on USBD_CDC_POLLING_INTERVAL */
|
||||||
#define CDC_POLLING_INTERVAL 5 /* in ms. The max is 65 and the min is 1 */
|
#define USBD_CDC_POLLING_INTERVAL 10 /* in ms. The max is 65 and the min is 1 */
|
||||||
|
|
||||||
extern USBD_CDC_ItfTypeDef USBD_CDC_fops;
|
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_RxGet(void);
|
||||||
|
|
||||||
/* Exported macro ------------------------------------------------------------*/
|
/* Exported macro ------------------------------------------------------------*/
|
||||||
/* Exported functions ------------------------------------------------------- */
|
/* Exported functions ------------------------------------------------------- */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user