Skip to content

STM32WB: enable USB Device #12751

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
* AHBCLK (MHz) | 32
* APB1CLK (MHz) | 32
* APB2CLK (MHz) | 32
* USB capable | NO // todo
* USB capable | YES
*-----------------------------------------------------------------------------
**/

Expand Down Expand Up @@ -97,13 +97,14 @@ void SetSysClock(void)
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.AHBCLK2Divider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.AHBCLK4Divider = RCC_SYSCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK) {
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK) {
error("HAL_RCC_ClockConfig error\n");
}

/** Initializes the peripherals clocks
*/
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SMPS | RCC_PERIPHCLK_RFWAKEUP | RCC_PERIPHCLK_RNG;
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SMPS | RCC_PERIPHCLK_RFWAKEUP | RCC_PERIPHCLK_RNG | RCC_PERIPHCLK_USB;
PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_HSI48;
PeriphClkInitStruct.RngClockSelection = RCC_RNGCLKSOURCE_HSI48;
PeriphClkInitStruct.RFWakeUpClockSelection = RCC_RFWKPCLKSOURCE_LSE;
PeriphClkInitStruct.SmpsClockSelection = RCC_SMPSCLKSOURCE_HSE;
Expand Down
4 changes: 2 additions & 2 deletions targets/TARGET_STM/USBPhyHw.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
#if MBED_CONF_TARGET_USB_SPEED == USE_USB_NO_OTG

#if defined(TARGET_STM32F3) || defined(TARGET_STM32WB)
#define USBHAL_IRQn USB_HP_IRQn
#define USBHAL_IRQn USB_LP_IRQn
#else
#define USBHAL_IRQn USB_IRQn
#endif
Expand All @@ -50,7 +50,7 @@

#endif

#define NB_ENDPOINT 16
#define NB_ENDPOINT 8

// #define MAXTRANSFER_SIZE 0x200
#define MAX_PACKET_SIZE_SETUP (48)
Expand Down
56 changes: 56 additions & 0 deletions targets/TARGET_STM/USBPhy_STM32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ static const uint32_t tx_ep_sizes[NUM_ENDPOINTS] = {
MAX_PACKET_SIZE_ISO
};

#if (MBED_CONF_TARGET_USB_SPEED != USE_USB_NO_OTG)
uint32_t HAL_PCDEx_GetTxFiFo(PCD_HandleTypeDef *hpcd, uint8_t fifo)
{
uint32_t len;
Expand All @@ -49,15 +50,23 @@ uint32_t HAL_PCDEx_GetTxFiFo(PCD_HandleTypeDef *hpcd, uint8_t fifo)
}
return len * 4;
}
#endif

/* weak function redefinition */
void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
{
USBPhyHw *priv = ((USBPhyHw *)(hpcd->pData));
#if (MBED_CONF_TARGET_USB_SPEED == USE_USB_NO_OTG)
if (priv->sof_enabled) {
priv->events->sof((hpcd->Instance->FNR) & USB_FNR_FN);
}
#else
USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
uint32_t USBx_BASE = (uint32_t)USBx;
if (priv->sof_enabled) {
priv->events->sof((USBx_DEVICE->DSTS & USB_OTG_DSTS_FNSOF) >> 8);
}
#endif
}

/* this call at device reception completion on a Out Enpoint */
Expand Down Expand Up @@ -244,7 +253,37 @@ void USBPhyHw::init(USBPhyEvents *events)
HAL_StatusTypeDef ret = HAL_PCD_Init(&hpcd);
MBED_ASSERT(ret == HAL_OK);

// Configure FIFOs
#if (MBED_CONF_TARGET_USB_SPEED == USE_USB_NO_OTG)

// EP0
#define PMA_EP0_OUT_ADDR (8 * 4)
#define PMA_EP0_IN_ADDR (PMA_EP0_OUT_ADDR + MAX_PACKET_SIZE_EP0)
HAL_PCDEx_PMAConfig(&hpcd, LOG_OUT_TO_EP(0), PCD_SNG_BUF, PMA_EP0_OUT_ADDR); // HAL_PCDEx_PMAConfig always returns HAL_OK
HAL_PCDEx_PMAConfig(&hpcd, LOG_IN_TO_EP(0), PCD_SNG_BUF, PMA_EP0_IN_ADDR); // HAL_PCDEx_PMAConfig always returns HAL_OK
// EP1
#define PMA_EP1_OUT_BASE (PMA_EP0_IN_ADDR + MAX_PACKET_SIZE_EP0)
#define PMA_EP1_OUT_ADDR ((PMA_EP1_OUT_BASE + MAX_PACKET_SIZE_NON_ISO) | (PMA_EP1_OUT_BASE << 16U))
#define PMA_EP1_IN_ADDR (PMA_EP1_OUT_BASE + MAX_PACKET_SIZE_NON_ISO)
#define PMA_EP1_CMD_ADDR (PMA_EP1_IN_ADDR + MAX_PACKET_SIZE_NON_ISO)
HAL_PCDEx_PMAConfig(&hpcd, LOG_OUT_TO_EP(1), PCD_SNG_BUF, PMA_EP1_OUT_ADDR); // HAL_PCDEx_PMAConfig always returns HAL_OK
HAL_PCDEx_PMAConfig(&hpcd, LOG_IN_TO_EP(1), PCD_SNG_BUF, PMA_EP1_CMD_ADDR); // HAL_PCDEx_PMAConfig always returns HAL_OK
// EP2
#define PMA_EP2_OUT_BASE (PMA_EP1_IN_ADDR + MAX_PACKET_SIZE_NON_ISO)
#define PMA_EP2_OUT_ADDR ((PMA_EP2_OUT_BASE + MAX_PACKET_SIZE_NON_ISO) | (PMA_EP2_OUT_BASE << 16U))
#define PMA_EP2_IN_ADDR (PMA_EP2_OUT_BASE + MAX_PACKET_SIZE_NON_ISO * 2)
#define PMA_EP2_CMD_ADDR (PMA_EP2_IN_ADDR + MAX_PACKET_SIZE_NON_ISO)
HAL_PCDEx_PMAConfig(&hpcd, LOG_OUT_TO_EP(2), PCD_DBL_BUF, PMA_EP2_OUT_ADDR); // HAL_PCDEx_PMAConfig always returns HAL_OK
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like we have a bug here causing endpoint wrong RAM buffer address
Shouldn't be PCD_SNG_BUF here ? @jeromecoutant
@donatieng

Copy link
Collaborator Author

@jeromecoutant jeromecoutant Aug 27, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you meet some issue with STM32WB target?
or it is a question during review ?

I checked this commit: 4b29c4f
Tests are still OK, no regression.
Can you check it in your application ?

Copy link
Contributor

@maciejbocianski maciejbocianski Aug 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was implementing two interface HID device and noticed that on EP2_OUT the driver read other RAM location than expected causing wrong data to be send to host. Changing to SNG_BUF fixes this problem.

HAL_PCDEx_PMAConfig(&hpcd, LOG_IN_TO_EP(2), PCD_SNG_BUF, PMA_EP2_CMD_ADDR); // HAL_PCDEx_PMAConfig always returns HAL_OK
// EP3
#define PMA_EP3_OUT_BASE (PMA_EP2_IN_ADDR + MAX_PACKET_SIZE_NON_ISO)
#define PMA_EP3_OUT_ADDR ((PMA_EP3_OUT_BASE + MAX_PACKET_SIZE_ISO) | (PMA_EP3_OUT_BASE << 16U))
#define PMA_EP3_IN_ADDR (PMA_EP3_OUT_BASE + MAX_PACKET_SIZE_ISO)
#define PMA_EP3_CMD_ADDR (PMA_EP3_IN_ADDR + MAX_PACKET_SIZE_ISO)
HAL_PCDEx_PMAConfig(&hpcd, LOG_OUT_TO_EP(3), PCD_SNG_BUF, PMA_EP3_OUT_ADDR); // HAL_PCDEx_PMAConfig always returns HAL_OK
HAL_PCDEx_PMAConfig(&hpcd, LOG_IN_TO_EP(3), PCD_SNG_BUF, PMA_EP3_CMD_ADDR); // HAL_PCDEx_PMAConfig always returns HAL_OK

#else
uint32_t total_bytes = 0;

/* Reserve space in the RX buffer for:
Expand All @@ -266,6 +305,7 @@ void USBPhyHw::init(USBPhyEvents *events)

/* 1.25 kbytes */
MBED_ASSERT(total_bytes <= 1280);
#endif

// Configure interrupt vector
NVIC_SetVector(USBHAL_IRQn, (uint32_t)&_usbisr);
Expand Down Expand Up @@ -293,8 +333,21 @@ bool USBPhyHw::powered()

void USBPhyHw::connect()
{
#if (MBED_CONF_TARGET_USB_SPEED == USE_USB_NO_OTG)
DigitalOut usb_disc_pin(USB_DP, 1) ;
wait_ns(1000);
usb_disc_pin = 0;

uint32_t wInterrupt_Mask = USB_CNTR_CTRM | USB_CNTR_WKUPM | USB_CNTR_SUSPM | USB_CNTR_ERRM |
USB_CNTR_SOFM | USB_CNTR_ESOFM | USB_CNTR_RESETM;
/*Set interrupt mask*/
hpcd.Instance->CNTR = wInterrupt_Mask;
HAL_PCD_DevConnect(&hpcd); // HAL_PCD_DevConnect always return HAL_OK
wait_us(10000);
#else
HAL_StatusTypeDef ret = HAL_PCD_Start(&hpcd);
MBED_ASSERT(ret == HAL_OK);
#endif
}

void USBPhyHw::disconnect()
Expand Down Expand Up @@ -405,6 +458,7 @@ void USBPhyHw::ep0_stall()

bool USBPhyHw::endpoint_add(usb_ep_t endpoint, uint32_t max_packet, usb_ep_type_t type)
{
#if (MBED_CONF_TARGET_USB_SPEED != USE_USB_NO_OTG)
uint32_t len;

/*
Expand All @@ -415,6 +469,8 @@ bool USBPhyHw::endpoint_add(usb_ep_t endpoint, uint32_t max_packet, usb_ep_type_
len = HAL_PCDEx_GetTxFiFo(&hpcd, endpoint & 0x7f);
MBED_ASSERT(len >= max_packet);
}
#endif

HAL_StatusTypeDef ret = HAL_PCD_EP_Open(&hpcd, endpoint, max_packet, type);
MBED_ASSERT(ret != HAL_BUSY);
return (ret == HAL_OK) ? true : false;
Expand Down
8 changes: 7 additions & 1 deletion targets/targets.json
Original file line number Diff line number Diff line change
Expand Up @@ -2161,6 +2161,10 @@
"value": "PA_7",
"macro_name": "STM32_D11_SPI_ETHERNET_PIN"
},
"usb_speed": {
"help": "USE_USB_OTG_FS or USE_USB_OTG_HS or USE_USB_HS_IN_FS",
"value": "USE_USB_OTG_FS"
},
"clock_source": {
"help": "Mask value : USE_PLL_HSE_EXTC | USE_PLL_HSE_XTAL (need HW patch) | USE_PLL_HSI",
"value": "USE_PLL_HSE_EXTC|USE_PLL_HSI",
Expand All @@ -2182,7 +2186,8 @@
"SERIAL_ASYNCH",
"TRNG",
"FLASH",
"MPU"
"MPU",
"USBDEVICE"
],
"detect_code": [
"0797"
Expand Down Expand Up @@ -4121,6 +4126,7 @@
"SERIAL_FC",
"TRNG",
"FLASH",
"USBDEVICE",
"MPU"
],
"device_name": "STM32WB55RGVx",
Expand Down