stmhal: Enable two USB phys to be supported together.

This is refactoring to enable support for the two USB PHYs available on
some STM32F4 processors to be used at the same time. The F405/7 & F429
have two USB PHYs, others such as the F411 only have one PHY.

This has been tested separately on a pyb10 (USB_FS PHY) and F429DISC
(USB_HS PHY) to be able to invoke a REPL/USB.  I have modified a PYBV10
to support two PHYs.

The long term objective is to support a 2nd USB PHY to be brought up as a
USB HOST, and possibly a single USB PHY to be OTG.
This commit is contained in:
neilh10 2015-12-08 14:02:34 -08:00 committed by Damien George
parent 0891cf7d2d
commit 1be0fde45c
7 changed files with 123 additions and 80 deletions

View File

@ -47,6 +47,7 @@
/* Exported constants --------------------------------------------------------*/
#define USE_USB_FS
//#define USE_USB_HS
/* ########################## Module Selection ############################## */
/**

View File

@ -234,6 +234,8 @@ static inline mp_uint_t disable_irq(void) {
#define free gc_free
#define realloc gc_realloc
// see stm32f4XX_hal_conf.h USE_USB_FS & USE_USB_HS
// at the moment only USB_FS is supported
#define USE_DEVICE_MODE
//#define USE_HOST_MODE

View File

@ -80,8 +80,8 @@
#include "dma.h"
extern void __fatal_error(const char*);
extern PCD_HandleTypeDef pcd_handle;
extern PCD_HandleTypeDef pcd_fs_handle;
extern PCD_HandleTypeDef pcd_hs_handle;
/******************************************************************************/
/* Cortex-M4 Processor Exceptions Handlers */
/******************************************************************************/
@ -305,28 +305,25 @@ void SysTick_Handler(void) {
* @retval None
*/
#if defined(USE_USB_FS)
#define OTG_XX_IRQHandler OTG_FS_IRQHandler
#define OTG_XX_WKUP_IRQHandler OTG_FS_WKUP_IRQHandler
#elif defined(USE_USB_HS)
#define OTG_XX_IRQHandler OTG_HS_IRQHandler
#define OTG_XX_WKUP_IRQHandler OTG_HS_WKUP_IRQHandler
void OTG_FS_IRQHandler(void) {
HAL_PCD_IRQHandler(&pcd_fs_handle);
}
#endif
#if defined(OTG_XX_IRQHandler)
void OTG_XX_IRQHandler(void) {
HAL_PCD_IRQHandler(&pcd_handle);
#if defined(USE_USB_HS)
void OTG_HS_IRQHandler(void) {
HAL_PCD_IRQHandler(&pcd_hs_handle);
}
#endif
#if defined(USE_USB_FS) || defined(USE_USB_HS)
/**
* @brief This function handles USB OTG FS or HS Wakeup IRQ Handler.
* @param None
* @brief This function handles USB OTG Common FS/HS Wakeup functions.
* @param *pcd_handle for FS or HS
* @retval None
*/
#if defined(OTG_XX_WKUP_IRQHandler)
void OTG_XX_WKUP_IRQHandler(void) {
STATIC void OTG_CMD_WKUP_Handler(PCD_HandleTypeDef *pcd_handle) {
if ((&pcd_handle)->Init.low_power_enable) {
if (pcd_handle->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));
@ -353,16 +350,41 @@ void OTG_XX_WKUP_IRQHandler(void) {
{}
/* ungate PHY clock */
__HAL_PCD_UNGATE_PHYCLOCK((&pcd_handle));
__HAL_PCD_UNGATE_PHYCLOCK(pcd_handle);
}
#ifdef USE_USB_FS
}
#endif
#if defined(USE_USB_FS)
/**
* @brief This function handles USB OTG FS Wakeup IRQ Handler.
* @param None
* @retval None
*/
void OTG_FS_WKUP_IRQHandler(void) {
OTG_CMD_WKUP_Handler(&pcd_fs_handle);
/* 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
#if defined(USE_USB_HS)
/**
* @brief This function handles USB OTG HS Wakeup IRQ Handler.
* @param None
* @retval None
*/
void OTG_HS_WKUP_IRQHandler(void) {
OTG_CMD_WKUP_Handler(&pcd_hs_handle);
/* Clear EXTI pending Bit*/
__HAL_USB_HS_EXTI_CLEAR_FLAG();
}
#endif

View File

@ -74,6 +74,7 @@ void PendSV_Handler(void);
void SysTick_Handler(void);
#ifdef USE_USB_FS
void OTG_FS_IRQHandler(void);
#elif defined(USE_USB_HS)
#endif
#ifdef USE_USB_HS
void OTG_HS_IRQHandler(void);
#endif

View File

@ -102,7 +102,7 @@ bool pyb_usb_dev_init(uint16_t vid, uint16_t pid, usb_device_mode_t mode, USBD_H
if (USBD_SelectMode(mode, hid_info) != 0) {
return false;
}
USBD_Init(&hUSBDDevice, (USBD_DescriptorsTypeDef*)&USBD_Descriptors, 0);
USBD_Init(&hUSBDDevice, (USBD_DescriptorsTypeDef*)&USBD_Descriptors, USB_PHY_FS_ID);
USBD_RegisterClass(&hUSBDDevice, &USBD_CDC_MSC_HID);
USBD_CDC_RegisterInterface(&hUSBDDevice, (USBD_CDC_ItfTypeDef*)&USBD_CDC_fops);
switch (pyb_usb_storage_medium) {

View File

@ -41,6 +41,11 @@ typedef enum {
PYB_USB_STORAGE_MEDIUM_SDCARD,
} pyb_usb_storage_medium_t;
typedef enum {
USB_PHY_FS_ID = 0,
USB_PHY_HS_ID = 1,
} USB_PHY_ID;
extern mp_uint_t pyb_usb_flags;
extern struct _USBD_HandleTypeDef hUSBDDevice;
extern pyb_usb_storage_medium_t pyb_usb_storage_medium;

View File

@ -34,13 +34,18 @@
#include "usbd_core.h"
#include "py/obj.h"
#include "irq.h"
#include "usb.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
PCD_HandleTypeDef pcd_handle;
#ifdef USE_USB_FS
PCD_HandleTypeDef pcd_fs_handle;
#endif
#ifdef USE_USB_HS
PCD_HandleTypeDef pcd_hs_handle;
#endif
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
@ -379,90 +384,97 @@ void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
USBD_StatusTypeDef USBD_LL_Init (USBD_HandleTypeDef *pdev)
{
#if defined(USE_USB_FS)
if (pdev->id == USB_PHY_FS_ID)
{
/*Set LL Driver parameters */
pcd_handle.Instance = USB_OTG_FS;
pcd_handle.Init.dev_endpoints = 4;
pcd_handle.Init.use_dedicated_ep1 = 0;
pcd_handle.Init.ep0_mps = 0x40;
pcd_handle.Init.dma_enable = 0;
pcd_handle.Init.low_power_enable = 0;
pcd_handle.Init.phy_itface = PCD_PHY_EMBEDDED;
pcd_handle.Init.Sof_enable = 0;
pcd_handle.Init.speed = PCD_SPEED_FULL;
pcd_fs_handle.Instance = USB_OTG_FS;
pcd_fs_handle.Init.dev_endpoints = 4;
pcd_fs_handle.Init.use_dedicated_ep1 = 0;
pcd_fs_handle.Init.ep0_mps = 0x40;
pcd_fs_handle.Init.dma_enable = 0;
pcd_fs_handle.Init.low_power_enable = 0;
pcd_fs_handle.Init.phy_itface = PCD_PHY_EMBEDDED;
pcd_fs_handle.Init.Sof_enable = 0;
pcd_fs_handle.Init.speed = PCD_SPEED_FULL;
#if !defined(MICROPY_HW_USB_VBUS_DETECT_PIN)
pcd_handle.Init.vbus_sensing_enable = 0; // No VBUS Sensing on USB0
pcd_fs_handle.Init.vbus_sensing_enable = 0; // No VBUS Sensing on USB0
#else
pcd_handle.Init.vbus_sensing_enable = 1;
pcd_fs_handle.Init.vbus_sensing_enable = 1;
#endif
/* Link The driver to the stack */
pcd_handle.pData = pdev;
pdev->pData = &pcd_handle;
pcd_fs_handle.pData = pdev;
pdev->pData = &pcd_fs_handle;
/*Initialize LL Driver */
HAL_PCD_Init(&pcd_handle);
HAL_PCD_Init(&pcd_fs_handle);
HAL_PCD_SetRxFiFo(&pcd_handle, 0x80);
HAL_PCD_SetTxFiFo(&pcd_handle, 0, 0x20);
HAL_PCD_SetTxFiFo(&pcd_handle, 1, 0x40);
HAL_PCD_SetTxFiFo(&pcd_handle, 2, 0x20);
HAL_PCD_SetTxFiFo(&pcd_handle, 3, 0x40);
#elif defined(USE_USB_HS)
HAL_PCD_SetRxFiFo(&pcd_fs_handle, 0x80);
HAL_PCD_SetTxFiFo(&pcd_fs_handle, 0, 0x20);
HAL_PCD_SetTxFiFo(&pcd_fs_handle, 1, 0x40);
HAL_PCD_SetTxFiFo(&pcd_fs_handle, 2, 0x20);
HAL_PCD_SetTxFiFo(&pcd_fs_handle, 3, 0x40);
}
#endif
#if defined(USE_USB_HS)
if (pdev->id == USB_PHY_HS_ID)
{
#if defined(USE_USB_HS_IN_FS)
/*Set LL Driver parameters */
pcd_handle.Instance = USB_OTG_HS;
pcd_handle.Init.dev_endpoints = 4;
pcd_handle.Init.use_dedicated_ep1 = 0;
pcd_handle.Init.ep0_mps = 0x40;
pcd_handle.Init.dma_enable = 0;
pcd_handle.Init.low_power_enable = 0;
pcd_handle.Init.phy_itface = PCD_PHY_EMBEDDED;
pcd_handle.Init.Sof_enable = 0;
pcd_handle.Init.speed = PCD_SPEED_HIGH_IN_FULL;
pcd_hs_handle.Instance = USB_OTG_HS;
pcd_hs_handle.Init.dev_endpoints = 4;
pcd_hs_handle.Init.use_dedicated_ep1 = 0;
pcd_hs_handle.Init.ep0_mps = 0x40;
pcd_hs_handle.Init.dma_enable = 0;
pcd_hs_handle.Init.low_power_enable = 0;
pcd_hs_handle.Init.phy_itface = PCD_PHY_EMBEDDED;
pcd_hs_handle.Init.Sof_enable = 0;
pcd_hs_handle.Init.speed = PCD_SPEED_HIGH_IN_FULL;
#if !defined(MICROPY_HW_USB_VBUS_DETECT_PIN)
pcd_handle.Init.vbus_sensing_enable = 0; // No VBUS Sensing on USB0
pcd_hs_handle.Init.vbus_sensing_enable = 0; // No VBUS Sensing on USB0
#else
pcd_handle.Init.vbus_sensing_enable = 1;
pcd_hs_handle.Init.vbus_sensing_enable = 1;
#endif
/* Link The driver to the stack */
pcd_handle.pData = pdev;
pdev->pData = &pcd_handle;
pcd_hs_handle.pData = pdev;
pdev->pData = &pcd_hs_handle;
/*Initialize LL Driver */
HAL_PCD_Init(&pcd_handle);
HAL_PCD_Init(&pcd_hs_handle);
HAL_PCD_SetRxFiFo(&pcd_handle, 0x80);
HAL_PCD_SetTxFiFo(&pcd_handle, 0, 0x20);
HAL_PCD_SetTxFiFo(&pcd_handle, 1, 0x40);
HAL_PCD_SetTxFiFo(&pcd_handle, 2, 0x20);
HAL_PCD_SetTxFiFo(&pcd_handle, 3, 0x40);
HAL_PCD_SetRxFiFo(&pcd_hs_handle, 0x80);
HAL_PCD_SetTxFiFo(&pcd_hs_handle, 0, 0x20);
HAL_PCD_SetTxFiFo(&pcd_hs_handle, 1, 0x40);
HAL_PCD_SetTxFiFo(&pcd_hs_handle, 2, 0x20);
HAL_PCD_SetTxFiFo(&pcd_hs_handle, 3, 0x40);
#else // !defined(USE_USB_HS_IN_FS)
/*Set LL Driver parameters */
pcd_handle.Instance = USB_OTG_HS;
pcd_handle.Init.dev_endpoints = 6;
pcd_handle.Init.use_dedicated_ep1 = 0;
pcd_handle.Init.ep0_mps = 0x40;
pcd_hs_handle.Instance = USB_OTG_HS;
pcd_hs_handle.Init.dev_endpoints = 6;
pcd_hs_handle.Init.use_dedicated_ep1 = 0;
pcd_hs_handle.Init.ep0_mps = 0x40;
/* Be aware that enabling USB-DMA mode will result in data being sent only by
multiple of 4 packet sizes. This is due to the fact that USB-DMA does
not allow sending data from non word-aligned addresses.
For this specific application, it is advised to not enable this option
unless required. */
pcd_handle.Init.dma_enable = 0;
pcd_hs_handle.Init.dma_enable = 0;
pcd_handle.Init.low_power_enable = 0;
pcd_handle.Init.phy_itface = PCD_PHY_ULPI;
pcd_handle.Init.Sof_enable = 0;
pcd_handle.Init.speed = PCD_SPEED_HIGH;
pcd_handle.Init.vbus_sensing_enable = 1;
pcd_hs_handle.Init.low_power_enable = 0;
pcd_hs_handle.Init.phy_itface = PCD_PHY_ULPI;
pcd_hs_handle.Init.Sof_enable = 0;
pcd_hs_handle.Init.speed = PCD_SPEED_HIGH;
pcd_hs_handle.Init.vbus_sensing_enable = 1;
/* Link The driver to the stack */
pcd_handle.pData = pdev;
pdev->pData = &pcd_handle;
pcd_hs_handle.pData = pdev;
pdev->pData = &pcd_hs_handle;
/*Initialize LL Driver */
HAL_PCD_Init(&pcd_handle);
HAL_PCD_Init(&pcd_hs_handle);
HAL_PCD_SetRxFiFo(&pcd_handle, 0x200);
HAL_PCD_SetTxFiFo(&pcd_handle, 0, 0x80);
HAL_PCD_SetTxFiFo(&pcd_handle, 1, 0x174);
HAL_PCD_SetRxFiFo(&pcd_hs_handle, 0x200);
HAL_PCD_SetTxFiFo(&pcd_hs_handle, 0, 0x80);
HAL_PCD_SetTxFiFo(&pcd_hs_handle, 1, 0x174);
#endif // !USE_USB_HS_IN_FS
}
#endif // USE_USB_HS
return USBD_OK;
}