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

stmhal: Get USB enumerating a CDC device.

Enumerates CDC device over USB, but doesn't transmit/receive yet.
parent 536dde25
...@@ -8,9 +8,8 @@ include ../py/py.mk ...@@ -8,9 +8,8 @@ include ../py/py.mk
CMSIS_DIR=cmsis CMSIS_DIR=cmsis
HAL_DIR=hal HAL_DIR=hal
#STMUSB_DIR=stmusb USBDEV_DIR=usbdev
#STMUSBD_DIR=stmusbd #USBHOST_DIR=usbhost
#STMUSBH_DIR=stmusbh
#FATFS_DIR=fatfs #FATFS_DIR=fatfs
#CC3K_DIR=cc3k #CC3K_DIR=cc3k
DFU=../tools/dfu.py DFU=../tools/dfu.py
...@@ -22,9 +21,8 @@ INC += -I$(PY_SRC) ...@@ -22,9 +21,8 @@ INC += -I$(PY_SRC)
INC += -I$(CMSIS_DIR)/inc INC += -I$(CMSIS_DIR)/inc
INC += -I$(CMSIS_DIR)/devinc INC += -I$(CMSIS_DIR)/devinc
INC += -I$(HAL_DIR)/inc INC += -I$(HAL_DIR)/inc
#INC += -I$(STMUSB_DIR) INC += -I$(USBDEV_DIR)/core/inc -I$(USBDEV_DIR)/class/cdc/inc
#INC += -I$(STMUSBD_DIR) #INC += -I$(USBHOST_DIR)
#INC += -I$(STMUSBH_DIR)
#INC += -I$(FATFS_DIR) #INC += -I$(FATFS_DIR)
#INC += -I$(CC3K_DIR) #INC += -I$(CC3K_DIR)
...@@ -57,10 +55,15 @@ SRC_C = \ ...@@ -57,10 +55,15 @@ SRC_C = \
system_stm32f4xx.c \ system_stm32f4xx.c \
stm32f4xx_it.c \ stm32f4xx_it.c \
stm32f4xx_hal_msp.c \ stm32f4xx_hal_msp.c \
usbd_conf.c \
usbd_desc.c \
usbd_cdc_interface.c \
pendsv.c \
systick.c \ systick.c \
led.c \ led.c \
pin.c \ pin.c \
usart.c \ usart.c \
usb.c \
printf.c \ printf.c \
math.c \ math.c \
malloc0.c \ malloc0.c \
...@@ -70,14 +73,12 @@ SRC_C = \ ...@@ -70,14 +73,12 @@ SRC_C = \
import.c \ import.c \
lexerfatfs.c \ lexerfatfs.c \
# pendsv.c \
# gpio.c \ # gpio.c \
# lcd.c \ # lcd.c \
# servo.c \ # servo.c \
# flash.c \ # flash.c \
# storage.c \ # storage.c \
# accel.c \ # accel.c \
# usb.c \
# timer.c \ # timer.c \
# audio.c \ # audio.c \
# sdcard.c \ # sdcard.c \
...@@ -100,8 +101,10 @@ SRC_HAL = $(addprefix $(HAL_DIR)/src/,\ ...@@ -100,8 +101,10 @@ SRC_HAL = $(addprefix $(HAL_DIR)/src/,\
stm32f4xx_hal_cortex.c \ stm32f4xx_hal_cortex.c \
stm32f4xx_hal_dma.c \ stm32f4xx_hal_dma.c \
stm32f4xx_hal_gpio.c \ stm32f4xx_hal_gpio.c \
stm32f4xx_hal_pcd.c \
stm32f4xx_hal_rcc.c \ stm32f4xx_hal_rcc.c \
stm32f4xx_hal_uart.c \ stm32f4xx_hal_uart.c \
stm32f4xx_ll_usb.c \
) )
SRC_STMPERIPH = $(addprefix $(STMPERIPH_DIR)/,\ SRC_STMPERIPH = $(addprefix $(STMPERIPH_DIR)/,\
...@@ -136,8 +139,14 @@ SRC_STMUSB = $(addprefix $(STMUSB_DIR)/,\ ...@@ -136,8 +139,14 @@ SRC_STMUSB = $(addprefix $(STMUSB_DIR)/,\
) )
# usb_otg.c \ # usb_otg.c \
SRC_STMUSBD = $(addprefix $(STMUSBD_DIR)/,\ SRC_USBDEV = $(addprefix $(USBDEV_DIR)/,\
usbd_core.c \ core/src/usbd_core.c \
core/src/usbd_ctlreq.c \
core/src/usbd_ioreq.c \
class/cdc/src/usbd_cdc.c \
)
# usbd_core.c \
usbd_ioreq.c \ usbd_ioreq.c \
usbd_req.c \ usbd_req.c \
usbd_usr.c \ usbd_usr.c \
...@@ -186,7 +195,7 @@ OBJ += $(PY_O) ...@@ -186,7 +195,7 @@ OBJ += $(PY_O)
OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o))
OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o))
OBJ += $(addprefix $(BUILD)/, $(SRC_HAL:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_HAL:.c=.o))
#OBJ += $(addprefix $(BUILD)/, $(SRC_STMUSB:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_USBDEV:.c=.o))
#OBJ += $(addprefix $(BUILD)/, $(SRC_STMUSBD:.c=.o)) #OBJ += $(addprefix $(BUILD)/, $(SRC_STMUSBD:.c=.o))
#OBJ += $(addprefix $(BUILD)/, $(SRC_STMUSBH:.c=.o)) #OBJ += $(addprefix $(BUILD)/, $(SRC_STMUSBH:.c=.o))
#OBJ += $(addprefix $(BUILD)/, $(SRC_FATFS:.c=.o)) #OBJ += $(addprefix $(BUILD)/, $(SRC_FATFS:.c=.o))
......
...@@ -47,6 +47,7 @@ ...@@ -47,6 +47,7 @@
/* Exported constants --------------------------------------------------------*/ /* Exported constants --------------------------------------------------------*/
#define STM32F405xx #define STM32F405xx
#define USE_USB_FS
/* ########################## Module Selection ############################## */ /* ########################## Module Selection ############################## */
/** /**
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "misc.h" #include "misc.h"
#include "systick.h" #include "systick.h"
#include "pendsv.h"
#include "led.h" #include "led.h"
#include "usart.h" #include "usart.h"
#include "mpconfig.h" #include "mpconfig.h"
...@@ -37,16 +38,15 @@ ...@@ -37,16 +38,15 @@
#include "gccollect.h" #include "gccollect.h"
#include "pyexec.h" #include "pyexec.h"
#include "pybmodule.h" #include "pybmodule.h"
#include "usb.h"
#if 0 #if 0
#include "ff.h" #include "ff.h"
#include "lexerfatfs.h" #include "lexerfatfs.h"
#include "pendsv.h"
#include "servo.h" #include "servo.h"
#include "lcd.h" #include "lcd.h"
#include "storage.h" #include "storage.h"
#include "sdcard.h" #include "sdcard.h"
#include "accel.h" #include "accel.h"
#include "usb.h"
#include "timer.h" #include "timer.h"
#include "pybwlan.h" #include "pybwlan.h"
#include "usrsw.h" #include "usrsw.h"
...@@ -82,8 +82,10 @@ void flash_error(int n) { ...@@ -82,8 +82,10 @@ void flash_error(int n) {
void __fatal_error(const char *msg) { void __fatal_error(const char *msg) {
#if MICROPY_HW_HAS_LCD #if MICROPY_HW_HAS_LCD
#if 0
lcd_print_strn("\nFATAL ERROR:\n", 14); lcd_print_strn("\nFATAL ERROR:\n", 14);
lcd_print_strn(msg, strlen(msg)); lcd_print_strn(msg, strlen(msg));
#endif
#endif #endif
for (;;) { for (;;) {
flash_error(1); flash_error(1);
...@@ -116,6 +118,9 @@ void fatality(void) { ...@@ -116,6 +118,9 @@ void fatality(void) {
led_state(PYB_LED_G1, 1); led_state(PYB_LED_G1, 1);
led_state(PYB_LED_R2, 1); led_state(PYB_LED_R2, 1);
led_state(PYB_LED_G2, 1); led_state(PYB_LED_G2, 1);
for (;;) {
flash_error(1);
}
} }
static const char fresh_boot_py[] = static const char fresh_boot_py[] =
...@@ -244,9 +249,7 @@ int main(void) { ...@@ -244,9 +249,7 @@ int main(void) {
// basic sub-system init // basic sub-system init
sys_tick_init(); sys_tick_init();
#if 0
pendsv_init(); pendsv_init();
#endif
led_init(); led_init();
#if 0 #if 0
...@@ -469,6 +472,7 @@ soft_reset: ...@@ -469,6 +472,7 @@ soft_reset:
} }
} }
#endif #endif
#endif
#ifdef USE_HOST_MODE #ifdef USE_HOST_MODE
// USB host // USB host
...@@ -478,6 +482,22 @@ soft_reset: ...@@ -478,6 +482,22 @@ 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
// run main script // run main script
{ {
vstr_t *vstr = vstr_new(); vstr_t *vstr = vstr_new();
......
#include <stdlib.h>
#include <stm32f4xx_hal.h>
#include "misc.h"
#include "mpconfig.h"
#include "qstr.h"
#include "obj.h"
#include "pendsv.h"
static void *pendsv_object = NULL;
void pendsv_init(void) {
// set PendSV interrupt at lowest priority
HAL_NVIC_SetPriority(PendSV_IRQn, 0xf, 0xf);
}
// call this function to raise a pending exception during an interrupt
// it will wait until all interrupts are finished then raise the given
// exception object using nlr_jump in the context of the top-level thread
void pendsv_nlr_jump(void *o) {
pendsv_object = o;
SCB->ICSR = SCB_ICSR_PENDSVSET_Msk;
}
// since we play tricks with the stack, the compiler must not generate a
// prelude for this function
void pendsv_isr_handler(void) __attribute__((naked));
void pendsv_isr_handler(void) {
// re-jig the stack so that when we return from this interrupt handler
// it returns instead to nlr_jump with argument pendsv_object
// note that stack has a different layout if DEBUG is enabled
//
// on entry to this (naked) function, stack has the following layout:
//
// stack layout with DEBUG disabled:
// sp[6]: pc
// sp[5]: ?
// sp[4]: ?
// sp[3]: ?
// sp[2]: ?
// sp[1]: ?
// sp[0]: r0
//
// stack layout with DEBUG enabled:
// sp[8]: pc
// sp[7]: lr
// sp[6]: ?
// sp[5]: ?
// sp[4]: ?
// sp[3]: ?
// sp[2]: r0
// sp[1]: 0xfffffff9
// sp[0]: ?
__asm volatile (
"ldr r0, pendsv_object_ptr\n"
"ldr r0, [r0]\n"
#if defined(PENDSV_DEBUG)
"str r0, [sp, #8]\n"
#else
"str r0, [sp, #0]\n"
#endif
"ldr r0, nlr_jump_ptr\n"
#if defined(PENDSV_DEBUG)
"str r0, [sp, #32]\n"
#else
"str r0, [sp, #24]\n"
#endif
"bx lr\n"
".align 2\n"
"pendsv_object_ptr: .word pendsv_object\n"
"nlr_jump_ptr: .word nlr_jump\n"
);
/*
uint32_t x[2] = {0x424242, 0xdeaddead};
printf("PendSV: %p\n", x);
for (uint32_t *p = (uint32_t*)(((uint32_t)x - 15) & 0xfffffff0), i = 64; i > 0; p += 4, i -= 4) {
printf(" %p: %08x %08x %08x %08x\n", p, (uint)p[0], (uint)p[1], (uint)p[2], (uint)p[3]);
}
*/
}
void pendsv_init(void);
void pendsv_nlr_jump(void *val);
void pendsv_isr_handler(void);
...@@ -56,6 +56,9 @@ ...@@ -56,6 +56,9 @@
/* Private macro -------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/
extern void fatality();
extern PCD_HandleTypeDef hpcd;
/* Private function prototypes -----------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/ /* Private functions ---------------------------------------------------------*/
...@@ -82,6 +85,7 @@ void HardFault_Handler(void) ...@@ -82,6 +85,7 @@ void HardFault_Handler(void)
/* Go to infinite loop when Hard Fault exception occurs */ /* Go to infinite loop when Hard Fault exception occurs */
while (1) while (1)
{ {
fatality();
} }
} }
...@@ -95,6 +99,7 @@ void MemManage_Handler(void) ...@@ -95,6 +99,7 @@ void MemManage_Handler(void)
/* Go to infinite loop when Memory Manage exception occurs */ /* Go to infinite loop when Memory Manage exception occurs */
while (1) while (1)
{ {
fatality();
} }
} }
...@@ -108,6 +113,7 @@ void BusFault_Handler(void) ...@@ -108,6 +113,7 @@ void BusFault_Handler(void)
/* Go to infinite loop when Bus Fault exception occurs */ /* Go to infinite loop when Bus Fault exception occurs */
while (1) while (1)
{ {
fatality();
} }
} }
...@@ -121,6 +127,7 @@ void UsageFault_Handler(void) ...@@ -121,6 +127,7 @@ void UsageFault_Handler(void)
/* Go to infinite loop when Usage Fault exception occurs */ /* Go to infinite loop when Usage Fault exception occurs */
while (1) while (1)
{ {
fatality();
} }
} }
...@@ -149,6 +156,8 @@ void DebugMon_Handler(void) ...@@ -149,6 +156,8 @@ void DebugMon_Handler(void)
*/ */
void PendSV_Handler(void) void PendSV_Handler(void)
{ {
extern void pendsv_isr_handler(void);
pendsv_isr_handler();
} }
/** /**
...@@ -158,7 +167,7 @@ void PendSV_Handler(void) ...@@ -158,7 +167,7 @@ void PendSV_Handler(void)
*/ */
void SysTick_Handler(void) void SysTick_Handler(void)
{ {
HAL_IncTick(); HAL_IncTick();
} }
/******************************************************************************/ /******************************************************************************/
...@@ -168,6 +177,72 @@ void SysTick_Handler(void) ...@@ -168,6 +177,72 @@ void SysTick_Handler(void)
/* file (startup_stm32f4xx.s). */ /* file (startup_stm32f4xx.s). */
/******************************************************************************/ /******************************************************************************/
/**
* @brief This function handles USB-On-The-Go FS global interrupt request.
* @param None
* @retval None
*/
#ifdef USE_USB_FS
void OTG_FS_IRQHandler(void)
#elif defined(USE_USB_HS)
void OTG_HS_IRQHandler(void)
#endif
{
HAL_PCD_IRQHandler(&hpcd);
}
/**
* @brief This function handles USB OTG FS or HS Wakeup IRQ Handler.
* @param None
* @retval None
*/
#ifdef USE_USB_FS
void OTG_FS_WKUP_IRQHandler(void)
#elif defined(USE_USB_HS)
void OTG_HS_WKUP_IRQHandler(void)
#endif
{
if((&hpcd)->Init.low_power_enable)
{
/* Reset SLEEPDEEP bit of Cortex System Control Register */
SCB->SCR &= (uint32_t)~((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk));
/* Configures system clock after wake-up from STOP: enable HSE, PLL and select
PLL as system clock source (HSE and PLL are disabled in STOP mode) */
__HAL_RCC_HSE_CONFIG(RCC_HSE_ON);
/* Wait till HSE is ready */
while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET)
{}
/* Enable the main PLL. */
__HAL_RCC_PLL_ENABLE();
/* Wait till PLL is ready */
while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET)
{}
/* Select PLL as SYSCLK */
MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_SYSCLKSOURCE_PLLCLK);
while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_CFGR_SWS_PLL)
{}
/* ungate PHY clock */
__HAL_PCD_UNGATE_PHYCLOCK((&hpcd));
}
#ifdef USE_USB_FS
/* Clear EXTI pending Bit*/
__HAL_USB_FS_EXTI_CLEAR_FLAG();
#elif defined(USE_USB_HS)
/* Clear EXTI pending Bit*/
__HAL_USB_HS_EXTI_CLEAR_FLAG();
#endif
}
/** /**
* @brief This function handles PPP interrupt request. * @brief This function handles PPP interrupt request.
* @param None * @param None
......
...@@ -58,6 +58,11 @@ void SVC_Handler(void); ...@@ -58,6 +58,11 @@ void SVC_Handler(void);
void DebugMon_Handler(void); void DebugMon_Handler(void);
void PendSV_Handler(void); void PendSV_Handler(void);
void SysTick_Handler(void); void SysTick_Handler(void);
#ifdef USE_USB_FS
void OTG_FS_IRQHandler(void);
#elif defined(USE_USB_HS)
void OTG_HS_IRQHandler(void);
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }
......
#include <string.h>
/*
#include "usb_core.h"
#include "usbd_cdc_core.h"
#include "usbd_pyb_core.h"
#include "usbd_usr.h"
*/
#include "usbd_core.h"
#include "usbd_desc.h"
#include "usbd_cdc.h"
#include "usbd_cdc_interface.h"
#include "misc.h"
#include "mpconfig.h"
#include "qstr.h"
#include "obj.h"
#include "pendsv.h"
#include "usb.h"
#ifdef USE_DEVICE_MODE
//extern CDC_IF_Prop_TypeDef VCP_fops;
USBD_HandleTypeDef hUSBDDevice;
#endif
static int dev_is_enabled = 0;
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;
void pyb_usb_dev_init(int usb_dev_type) {
#ifdef USE_DEVICE_MODE
if (!dev_is_enabled) {
// only init USB once in the device's power-lifetime
switch (usb_dev_type) {
case PYB_USB_DEV_VCP_MSC:
// XXX USBD_CDC_Init (called by one of these functions below) uses malloc,
// so the memory is invalid after a soft reset (which resets the GC).
USBD_Init(&hUSBDDevice, &VCP_Desc, 0);
USBD_RegisterClass(&hUSBDDevice, &USBD_CDC);
USBD_CDC_RegisterInterface(&hUSBDDevice, &USBD_CDC_fops);
USBD_Start(&hUSBDDevice);
//USBD_Init(&USB_OTG_Core, USB_OTG_FS_CORE_ID, &USR_desc, &USBD_PYB_cb, &USR_cb);
break;
case PYB_USB_DEV_HID:
//USBD_Init(&USB_OTG_Core, USB_OTG_FS_CORE_ID, &USR_desc, &USBD_PYB_HID_cb, &USR_cb);
// TODO
break;
}
}
rx_buf_in = 0;
rx_buf_out = 0;
interrupt_char = VCP_CHAR_NONE;
dev_is_enabled = 1;
// create an exception object for interrupting by VCP
mp_const_vcp_interrupt = mp_obj_new_exception_msg(&mp_type_OSError, "VCPInterrupt");
#endif
}
bool usb_vcp_is_enabled(void) {
return dev_is_enabled;
}
bool usb_vcp_is_connected(void) {
return APP_dev_is_connected;
}
void usb_vcp_set_interrupt_char(int c) {
if (dev_is_enabled) {
interrupt_char = c;
}
}
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;
}
}
}
}
}