From 0b2e3b7775cb4a01e1b6ac605cf18a91d58a662d Mon Sep 17 00:00:00 2001 From: drowe67 Date: Thu, 4 Sep 2014 06:26:36 +0000 Subject: [PATCH] moved USB VCP into a module git-svn-id: https://svn.code.sf.net/p/freetel/code@1824 01035d8c-6547-0410-b346-abe4f91aad63 --- codec2-dev/stm32/Makefile | 2 + codec2-dev/stm32/inc/sm1000_leds_switches.h | 2 + codec2-dev/stm32/inc/stm32f4_usb_vcp.h | 23 +++ codec2-dev/stm32/src/sm1000_leds_switches.c | 31 +++ codec2-dev/stm32/src/stm32f4_usb_vcp.c | 94 ++++++++++ codec2-dev/stm32/src/usb_vcp_ut.c | 198 ++++---------------- codec2-dev/stm32/src/usb_vsp_ut.c | 192 +++++++++++++++++++ 7 files changed, 377 insertions(+), 165 deletions(-) create mode 100644 codec2-dev/stm32/inc/stm32f4_usb_vcp.h create mode 100644 codec2-dev/stm32/src/stm32f4_usb_vcp.c create mode 100644 codec2-dev/stm32/src/usb_vsp_ut.c diff --git a/codec2-dev/stm32/Makefile b/codec2-dev/stm32/Makefile index f86e28de..05c0e2ce 100644 --- a/codec2-dev/stm32/Makefile +++ b/codec2-dev/stm32/Makefile @@ -305,6 +305,8 @@ freedv_rx_profile.elf: $(FREEDV_RX_PROFILE_SRCS) USB_VCP_UT=\ src/usb_vcp_ut.c \ +src/stm32f4_usb_vcp.c \ +src/sm1000_leds_switches.c \ usb_conf/usb_bsp.c \ usb_conf/usbd_desc.c \ usb_conf/usbd_usr.c \ diff --git a/codec2-dev/stm32/inc/sm1000_leds_switches.h b/codec2-dev/stm32/inc/sm1000_leds_switches.h index b6207d03..9b259c77 100644 --- a/codec2-dev/stm32/inc/sm1000_leds_switches.h +++ b/codec2-dev/stm32/inc/sm1000_leds_switches.h @@ -39,4 +39,6 @@ int switch_ptt(void); int switch_select(void); int switch_back(void); +void ColorfulRingOfDeath(void); + #endif diff --git a/codec2-dev/stm32/inc/stm32f4_usb_vcp.h b/codec2-dev/stm32/inc/stm32f4_usb_vcp.h new file mode 100644 index 00000000..384f3f0b --- /dev/null +++ b/codec2-dev/stm32/inc/stm32f4_usb_vcp.h @@ -0,0 +1,23 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: stm32f4_usb_vcp.h + AUTHOR......: David Rowe + DATE CREATED: 4 Sep 2014 + + USB Virtual COM Port (VCP) module. + +\*---------------------------------------------------------------------------*/ + +#ifndef __STM32F4_USB_VCP__ +#define __STM32F4_USB_VCP__ + +#include + +void usb_vcp_init(void); + +int VCP_get_char(uint8_t *buf); +int VCP_get_string(uint8_t *buf); +void VCP_put_char(uint8_t buf); +void VCP_send_str(uint8_t* buf); + +#endif diff --git a/codec2-dev/stm32/src/sm1000_leds_switches.c b/codec2-dev/stm32/src/sm1000_leds_switches.c index ae68525a..13ac803c 100644 --- a/codec2-dev/stm32/src/sm1000_leds_switches.c +++ b/codec2-dev/stm32/src/sm1000_leds_switches.c @@ -99,3 +99,34 @@ int switch_select(void) { int switch_back(void) { return GPIOD->IDR & (1 << 1); } + +/* + FUNCTION: ColorfulRingOfDeath() + AUTHOR..: xenovacivus + + Colourful ring of death, blink LEDs like crazy forever if something + really nasty happens. Adapted from USB Virtual COM Port (VCP) + module adapted from code I found here: + + https://github.com/xenovacivus/STM32DiscoveryVCP + + Call this to indicate a failure. Blinks the STM32F4 discovery LEDs + in sequence. At 168Mhz, the blinking will be very fast - about 5 + Hz. Keep that in mind when debugging, knowing the clock speed + might help with debugging. +*/ + +void ColorfulRingOfDeath(void) { + uint16_t ring = 1; + while (1) { + uint32_t count = 0; + while (count++ < 500000); + + GPIOD->BSRRH = (ring << 12); + ring = ring << 1; + if (ring >= 1<<4) { + ring = 1; + } + GPIOD->BSRRL = (ring << 12); + } +} diff --git a/codec2-dev/stm32/src/stm32f4_usb_vcp.c b/codec2-dev/stm32/src/stm32f4_usb_vcp.c new file mode 100644 index 00000000..4ee7314f --- /dev/null +++ b/codec2-dev/stm32/src/stm32f4_usb_vcp.c @@ -0,0 +1,94 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: stm32f4_usb_vcp.c + AUTHOR......: xenovacivus + DATE CREATED: 3 Sep 2014 + + USB Virtual COM Port (VCP) module adapted from code I found here: + + https://github.com/xenovacivus/STM32DiscoveryVCP + +\*---------------------------------------------------------------------------*/ + +#include "stm32f4xx_conf.h" +#include "stm32f4xx.h" +#include "stm32f4xx_gpio.h" +#include "stm32f4xx_rcc.h" +#include "stm32f4xx_exti.h" +#include "usbd_cdc_core.h" +#include "usbd_usr.h" +#include "usbd_desc.h" +#include "usbd_cdc_vcp.h" +#include "usb_dcd_int.h" +#include "sm1000_leds_switches.h" +#include "stm32f4_usb_vcp.h" + +/* + * The USB data must be 4 byte aligned if DMA is enabled. This macro handles + * the alignment, if necessary (it's actually magic, but don't tell anyone). + */ +__ALIGN_BEGIN USB_OTG_CORE_HANDLE USB_OTG_dev __ALIGN_END; + + +/* + * Define prototypes for interrupt handlers here. The conditional "extern" + * ensures the weak declarations from startup_stm32f4xx.c are overridden. + */ +#ifdef __cplusplus + extern "C" { +#endif + +void NMI_Handler(void); +void HardFault_Handler(void); +void MemManage_Handler(void); +void BusFault_Handler(void); +void UsageFault_Handler(void); +void SVC_Handler(void); +void DebugMon_Handler(void); +void PendSV_Handler(void); +void OTG_FS_IRQHandler(void); +void OTG_FS_WKUP_IRQHandler(void); + +#ifdef __cplusplus +} +#endif + + +void usb_vcp_init() { + /* Setup USB */ + USBD_Init(&USB_OTG_dev, + USB_OTG_FS_CORE_ID, + &USR_desc, + &USBD_CDC_cb, + &USR_cb); +} + + +/* + * Interrupt Handlers + */ + +void NMI_Handler(void) {} +void HardFault_Handler(void) { ColorfulRingOfDeath(); } +void MemManage_Handler(void) { ColorfulRingOfDeath(); } +void BusFault_Handler(void) { ColorfulRingOfDeath(); } +void UsageFault_Handler(void){ ColorfulRingOfDeath(); } +void SVC_Handler(void) {} +void DebugMon_Handler(void) {} +void PendSV_Handler(void) {} + +void OTG_FS_IRQHandler(void) +{ + USBD_OTG_ISR_Handler (&USB_OTG_dev); +} + +void OTG_FS_WKUP_IRQHandler(void) +{ + if(USB_OTG_dev.cfg.low_power) + { + *(uint32_t *)(0xE000ED10) &= 0xFFFFFFF9 ; + SystemInit(); + USB_OTG_UngateClock(&USB_OTG_dev); + } + EXTI_ClearITPendingBit(EXTI_Line18); +} diff --git a/codec2-dev/stm32/src/usb_vcp_ut.c b/codec2-dev/stm32/src/usb_vcp_ut.c index a9e816d0..74aa59e4 100644 --- a/codec2-dev/stm32/src/usb_vcp_ut.c +++ b/codec2-dev/stm32/src/usb_vcp_ut.c @@ -17,162 +17,54 @@ \*---------------------------------------------------------------------------*/ -#define HSE_VALUE ((uint32_t)8000000) /* STM32 discovery uses a 8Mhz external crystal */ - -#include "stm32f4xx_conf.h" -#include "stm32f4xx.h" -#include "stm32f4xx_gpio.h" -#include "stm32f4xx_rcc.h" -#include "stm32f4xx_exti.h" -#include "usbd_cdc_core.h" -#include "usbd_usr.h" -#include "usbd_desc.h" -#include "usbd_cdc_vcp.h" -#include "usb_dcd_int.h" +#include +#include +#include "stm32f4_usb_vcp.h" +#include "sm1000_leds_switches.h" volatile uint32_t ticker, downTicker; -/* - * The USB data must be 4 byte aligned if DMA is enabled. This macro handles - * the alignment, if necessary (it's actually magic, but don't tell anyone). - */ -__ALIGN_BEGIN USB_OTG_CORE_HANDLE USB_OTG_dev __ALIGN_END; +int main(void) { + sm1000_leds_switches_init(); + usb_vcp_init(); + SysTick_Config(SystemCoreClock/1000); -void init(); -void ColorfulRingOfDeath(void); + while (1) { -/* - * Define prototypes for interrupt handlers here. The conditional "extern" - * ensures the weak declarations from startup_stm32f4xx.c are overridden. - */ -#ifdef __cplusplus - extern "C" { -#endif - -void SysTick_Handler(void); -void NMI_Handler(void); -void HardFault_Handler(void); -void MemManage_Handler(void); -void BusFault_Handler(void); -void UsageFault_Handler(void); -void SVC_Handler(void); -void DebugMon_Handler(void); -void PendSV_Handler(void); -void OTG_FS_IRQHandler(void); -void OTG_FS_WKUP_IRQHandler(void); - -#ifdef __cplusplus -} -#endif + /* Blink the orange LED at 1Hz */ + if (500 == ticker) { + GPIOD->BSRRH = GPIO_Pin_13; + } + else if (1000 == ticker) { + ticker = 0; + GPIOD->BSRRL = GPIO_Pin_13; + } -int main(void) -{ - /* Set up the system clocks */ - SystemInit(); - - /* Initialize USB, IO, SysTick, and all those other things you do in the morning */ - init(); + /* If there's data on the virtual serial port: + * - Echo it back + * - Turn the green LED on for 10ms + */ + uint8_t theByte; + if (VCP_get_char(&theByte)) { + VCP_put_char(theByte); - while (1) - { - /* Blink the orange LED at 1Hz */ - if (500 == ticker) - { - GPIOD->BSRRH = GPIO_Pin_13; - } - else if (1000 == ticker) - { - ticker = 0; - GPIOD->BSRRL = GPIO_Pin_13; - } - - - /* If there's data on the virtual serial port: - * - Echo it back - * - Turn the green LED on for 10ms - */ - uint8_t theByte; - if (VCP_get_char(&theByte)) - { - VCP_put_char(theByte); - - - GPIOD->BSRRL = GPIO_Pin_12; - downTicker = 10; - } - if (0 == downTicker) - { - GPIOD->BSRRH = GPIO_Pin_12; - } - } + GPIOD->BSRRL = GPIO_Pin_12; + downTicker = 10; + } + if (0 == downTicker) { + GPIOD->BSRRH = GPIO_Pin_12; + } + } - return 0; -} - - -void init() -{ - /* STM32F4 discovery LEDs */ - GPIO_InitTypeDef LED_Config; - - /* Always remember to turn on the peripheral clock... If not, you may be up till 3am debugging... */ - RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); - LED_Config.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13| GPIO_Pin_14| GPIO_Pin_15; - LED_Config.GPIO_Mode = GPIO_Mode_OUT; - LED_Config.GPIO_OType = GPIO_OType_PP; - LED_Config.GPIO_Speed = GPIO_Speed_25MHz; - LED_Config.GPIO_PuPd = GPIO_PuPd_NOPULL; - GPIO_Init(GPIOD, &LED_Config); - - - - /* Setup SysTick or CROD! */ - if (SysTick_Config(SystemCoreClock / 1000)) - { - ColorfulRingOfDeath(); - } - - - /* Setup USB */ - USBD_Init(&USB_OTG_dev, - USB_OTG_FS_CORE_ID, - &USR_desc, - &USBD_CDC_cb, - &USR_cb); - - return; + return 0; } /* - * Call this to indicate a failure. Blinks the STM32F4 discovery LEDs - * in sequence. At 168Mhz, the blinking will be very fast - about 5 Hz. - * Keep that in mind when debugging, knowing the clock speed might help - * with debugging. - */ -void ColorfulRingOfDeath(void) -{ - uint16_t ring = 1; - while (1) - { - uint32_t count = 0; - while (count++ < 500000); - - GPIOD->BSRRH = (ring << 12); - ring = ring << 1; - if (ring >= 1<<4) - { - ring = 1; - } - GPIOD->BSRRL = (ring << 12); - } -} - -/* - * Interrupt Handlers + * Interrupt Handler */ void SysTick_Handler(void) @@ -184,27 +76,3 @@ void SysTick_Handler(void) } } -void NMI_Handler(void) {} -void HardFault_Handler(void) { ColorfulRingOfDeath(); } -void MemManage_Handler(void) { ColorfulRingOfDeath(); } -void BusFault_Handler(void) { ColorfulRingOfDeath(); } -void UsageFault_Handler(void){ ColorfulRingOfDeath(); } -void SVC_Handler(void) {} -void DebugMon_Handler(void) {} -void PendSV_Handler(void) {} - -void OTG_FS_IRQHandler(void) -{ - USBD_OTG_ISR_Handler (&USB_OTG_dev); -} - -void OTG_FS_WKUP_IRQHandler(void) -{ - if(USB_OTG_dev.cfg.low_power) - { - *(uint32_t *)(0xE000ED10) &= 0xFFFFFFF9 ; - SystemInit(); - USB_OTG_UngateClock(&USB_OTG_dev); - } - EXTI_ClearITPendingBit(EXTI_Line18); -} diff --git a/codec2-dev/stm32/src/usb_vsp_ut.c b/codec2-dev/stm32/src/usb_vsp_ut.c new file mode 100644 index 00000000..8f0c9f4d --- /dev/null +++ b/codec2-dev/stm32/src/usb_vsp_ut.c @@ -0,0 +1,192 @@ + +#define HSE_VALUE ((uint32_t)8000000) /* STM32 discovery uses a 8Mhz external crystal */ + +#include "stm32f4xx_conf.h" +#include "stm32f4xx.h" +#include "stm32f4xx_gpio.h" +#include "stm32f4xx_rcc.h" +#include "stm32f4xx_exti.h" +#include "usbd_cdc_core.h" +#include "usbd_usr.h" +#include "usbd_desc.h" +#include "usbd_cdc_vcp.h" +#include "usb_dcd_int.h" + +volatile uint32_t ticker, downTicker; + +/* + * The USB data must be 4 byte aligned if DMA is enabled. This macro handles + * the alignment, if necessary (it's actually magic, but don't tell anyone). + */ +__ALIGN_BEGIN USB_OTG_CORE_HANDLE USB_OTG_dev __ALIGN_END; + + +void init(); +void ColorfulRingOfDeath(void); + +/* + * Define prototypes for interrupt handlers here. The conditional "extern" + * ensures the weak declarations from startup_stm32f4xx.c are overridden. + */ +#ifdef __cplusplus + extern "C" { +#endif + +void SysTick_Handler(void); +void NMI_Handler(void); +void HardFault_Handler(void); +void MemManage_Handler(void); +void BusFault_Handler(void); +void UsageFault_Handler(void); +void SVC_Handler(void); +void DebugMon_Handler(void); +void PendSV_Handler(void); +void OTG_FS_IRQHandler(void); +void OTG_FS_WKUP_IRQHandler(void); + +#ifdef __cplusplus +} +#endif + + + +int main(void) +{ + /* Set up the system clocks */ + SystemInit(); + + /* Initialize USB, IO, SysTick, and all those other things you do in the morning */ + init(); + + + while (1) + { + /* Blink the orange LED at 1Hz */ + if (500 == ticker) + { + GPIOD->BSRRH = GPIO_Pin_13; + } + else if (1000 == ticker) + { + ticker = 0; + GPIOD->BSRRL = GPIO_Pin_13; + } + + + /* If there's data on the virtual serial port: + * - Echo it back + * - Turn the green LED on for 10ms + */ + uint8_t theByte; + if (VCP_get_char(&theByte)) + { + VCP_put_char(theByte); + + + GPIOD->BSRRL = GPIO_Pin_12; + downTicker = 10; + } + if (0 == downTicker) + { + GPIOD->BSRRH = GPIO_Pin_12; + } + } + + return 0; +} + + +void init() +{ + /* STM32F4 discovery LEDs */ + GPIO_InitTypeDef LED_Config; + + /* Always remember to turn on the peripheral clock... If not, you may be up till 3am debugging... */ + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); + LED_Config.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13| GPIO_Pin_14| GPIO_Pin_15; + LED_Config.GPIO_Mode = GPIO_Mode_OUT; + LED_Config.GPIO_OType = GPIO_OType_PP; + LED_Config.GPIO_Speed = GPIO_Speed_25MHz; + LED_Config.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_Init(GPIOD, &LED_Config); + + + + /* Setup SysTick or CROD! */ + if (SysTick_Config(SystemCoreClock / 1000)) + { + ColorfulRingOfDeath(); + } + + + /* Setup USB */ + USBD_Init(&USB_OTG_dev, + USB_OTG_FS_CORE_ID, + &USR_desc, + &USBD_CDC_cb, + &USR_cb); + + return; +} + +/* + * Call this to indicate a failure. Blinks the STM32F4 discovery LEDs + * in sequence. At 168Mhz, the blinking will be very fast - about 5 Hz. + * Keep that in mind when debugging, knowing the clock speed might help + * with debugging. + */ +void ColorfulRingOfDeath(void) +{ + uint16_t ring = 1; + while (1) + { + uint32_t count = 0; + while (count++ < 500000); + + GPIOD->BSRRH = (ring << 12); + ring = ring << 1; + if (ring >= 1<<4) + { + ring = 1; + } + GPIOD->BSRRL = (ring << 12); + } +} + +/* + * Interrupt Handlers + */ + +void SysTick_Handler(void) +{ + ticker++; + if (downTicker > 0) + { + downTicker--; + } +} + +void NMI_Handler(void) {} +void HardFault_Handler(void) { ColorfulRingOfDeath(); } +void MemManage_Handler(void) { ColorfulRingOfDeath(); } +void BusFault_Handler(void) { ColorfulRingOfDeath(); } +void UsageFault_Handler(void){ ColorfulRingOfDeath(); } +void SVC_Handler(void) {} +void DebugMon_Handler(void) {} +void PendSV_Handler(void) {} + +void OTG_FS_IRQHandler(void) +{ + USBD_OTG_ISR_Handler (&USB_OTG_dev); +} + +void OTG_FS_WKUP_IRQHandler(void) +{ + if(USB_OTG_dev.cfg.low_power) + { + *(uint32_t *)(0xE000ED10) &= 0xFFFFFFF9 ; + SystemInit(); + USB_OTG_UngateClock(&USB_OTG_dev); + } + EXTI_ClearITPendingBit(EXTI_Line18); +} -- 2.25.1