2018-03-28 17:30:53 +00:00
|
|
|
/* mbed Microcontroller Library
|
2019-10-21 12:51:13 +00:00
|
|
|
* Copyright (c) 2018-2019 ARM Limited
|
|
|
|
* Copyright (c) 2018-2019 STMicroelectronics
|
2018-03-28 17:30:53 +00:00
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
2019-10-21 12:51:13 +00:00
|
|
|
#if DEVICE_USBDEVICE
|
2018-03-28 17:30:53 +00:00
|
|
|
|
|
|
|
#include "USBPhyHw.h"
|
|
|
|
#include "pinmap.h"
|
|
|
|
|
|
|
|
/* endpoint conversion macros */
|
2019-10-21 12:51:13 +00:00
|
|
|
#define EP_TO_LOG(ep) ((ep) & 0xF)
|
|
|
|
#define LOG_IN_TO_EP(log) ((log) | 0x80)
|
|
|
|
#define LOG_OUT_TO_EP(log) ((log) | 0x00)
|
|
|
|
#define EP_TO_IDX(ep) ((EP_TO_LOG(ep) << 1) | ((ep) & 0x80 ? 1 : 0))
|
|
|
|
#define IDX_TO_EP(idx) (((idx) >> 1)|((idx) & 1) << 7)
|
2018-03-28 17:30:53 +00:00
|
|
|
|
2018-06-25 22:55:03 +00:00
|
|
|
/* endpoint defines */
|
|
|
|
#define NUM_ENDPOINTS 4
|
2019-10-21 12:51:13 +00:00
|
|
|
#define MAX_PACKET_SIZE_NON_ISO 64
|
|
|
|
#define MAX_PACKET_SIZE_ISO (256 + 128) // Spec can go up to 1023, only ram for this though
|
2018-06-25 22:55:03 +00:00
|
|
|
|
|
|
|
static const uint32_t tx_ep_sizes[NUM_ENDPOINTS] = {
|
2019-10-21 12:51:13 +00:00
|
|
|
MAX_PACKET_SIZE_NON_ISO,
|
|
|
|
MAX_PACKET_SIZE_NON_ISO,
|
|
|
|
MAX_PACKET_SIZE_NON_ISO,
|
|
|
|
MAX_PACKET_SIZE_ISO
|
2018-06-25 22:55:03 +00:00
|
|
|
};
|
|
|
|
|
2018-03-28 17:30:53 +00:00
|
|
|
uint32_t HAL_PCDEx_GetTxFiFo(PCD_HandleTypeDef *hpcd, uint8_t fifo)
|
|
|
|
{
|
|
|
|
uint32_t len;
|
|
|
|
if (fifo == 0) {
|
|
|
|
len = hpcd->Instance->DIEPTXF0_HNPTXFSIZ >> 16;
|
2019-03-19 22:10:32 +00:00
|
|
|
} else {
|
2018-03-28 17:30:53 +00:00
|
|
|
len = hpcd->Instance->DIEPTXF[fifo - 1] >> 16;
|
|
|
|
}
|
|
|
|
return len * 4;
|
|
|
|
}
|
|
|
|
|
|
|
|
void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
|
|
|
|
{
|
2019-03-19 22:10:32 +00:00
|
|
|
USBPhyHw *priv = ((USBPhyHw *)(hpcd->pData));
|
2018-03-28 17:30:53 +00:00
|
|
|
USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
|
2019-09-03 12:14:08 +00:00
|
|
|
uint32_t USBx_BASE = (uint32_t)USBx;
|
2018-03-28 17:30:53 +00:00
|
|
|
if (priv->sof_enabled) {
|
|
|
|
priv->events->sof((USBx_DEVICE->DSTS & USB_OTG_DSTS_FNSOF) >> 8);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* this call at device reception completion on a Out Enpoint */
|
2019-10-21 12:51:13 +00:00
|
|
|
/* weak function redefinition */
|
2018-03-28 17:30:53 +00:00
|
|
|
void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
|
|
|
|
{
|
2019-03-19 22:10:32 +00:00
|
|
|
USBPhyHw *priv = ((USBPhyHw *)(hpcd->pData));
|
2018-03-28 17:30:53 +00:00
|
|
|
uint8_t endpoint = LOG_OUT_TO_EP(epnum);
|
|
|
|
priv->epComplete[EP_TO_IDX(endpoint)] = 1;
|
2019-10-21 12:51:13 +00:00
|
|
|
|
2018-03-28 17:30:53 +00:00
|
|
|
if (epnum) {
|
|
|
|
priv->events->out(endpoint);
|
|
|
|
} else {
|
|
|
|
priv->events->ep0_out();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* this is call at device transmission completion on In endpoint */
|
2019-10-21 12:51:13 +00:00
|
|
|
/* weak function redefinition */
|
2018-03-28 17:30:53 +00:00
|
|
|
void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
|
|
|
|
{
|
2019-03-19 22:10:32 +00:00
|
|
|
USBPhyHw *priv = ((USBPhyHw *)(hpcd->pData));
|
2018-03-28 17:30:53 +00:00
|
|
|
uint8_t endpoint = LOG_IN_TO_EP(epnum);
|
|
|
|
priv->epComplete[EP_TO_IDX(endpoint)] = 1;
|
2019-10-21 12:51:13 +00:00
|
|
|
|
2018-03-28 17:30:53 +00:00
|
|
|
if (epnum) {
|
|
|
|
priv->events->in(endpoint);
|
|
|
|
} else {
|
|
|
|
priv->events->ep0_in();
|
|
|
|
}
|
|
|
|
}
|
2019-10-21 12:51:13 +00:00
|
|
|
|
2018-03-28 17:30:53 +00:00
|
|
|
/* This is call at device set up reception */
|
2019-10-21 12:51:13 +00:00
|
|
|
/* weak function redefinition */
|
2018-03-28 17:30:53 +00:00
|
|
|
void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
|
|
|
|
{
|
2019-03-19 22:10:32 +00:00
|
|
|
USBPhyHw *priv = ((USBPhyHw *)(hpcd->pData));
|
2018-03-28 17:30:53 +00:00
|
|
|
priv->events->ep0_setup();
|
|
|
|
}
|
|
|
|
|
2019-10-21 12:51:13 +00:00
|
|
|
/* weak function redefinition */
|
2018-03-28 17:30:53 +00:00
|
|
|
void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
|
|
|
|
{
|
2019-03-19 22:10:32 +00:00
|
|
|
USBPhyHw *priv = ((USBPhyHw *)(hpcd->pData));
|
2018-03-28 17:30:53 +00:00
|
|
|
priv->events->suspend(1);
|
|
|
|
}
|
|
|
|
|
2019-10-21 12:51:13 +00:00
|
|
|
/* weak function redefinition */
|
2018-03-28 17:30:53 +00:00
|
|
|
void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
|
|
|
|
{
|
2019-03-19 22:10:32 +00:00
|
|
|
USBPhyHw *priv = ((USBPhyHw *)(hpcd->pData));
|
2018-03-28 17:30:53 +00:00
|
|
|
priv->events->suspend(0);
|
|
|
|
}
|
|
|
|
|
2019-10-21 12:51:13 +00:00
|
|
|
/* weak function redefinition */
|
2018-03-28 17:30:53 +00:00
|
|
|
void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
|
|
|
|
{
|
|
|
|
// Nothing to do
|
|
|
|
}
|
|
|
|
|
2019-10-21 12:51:13 +00:00
|
|
|
/* weak function redefinition */
|
2018-03-28 17:30:53 +00:00
|
|
|
void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
|
|
|
|
{
|
|
|
|
// Nothing to do
|
|
|
|
}
|
|
|
|
|
2019-10-21 12:51:13 +00:00
|
|
|
/* weak function redefinition */
|
2018-03-28 17:30:53 +00:00
|
|
|
void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
|
|
|
|
{
|
2019-03-19 22:10:32 +00:00
|
|
|
USBPhyHw *obj = ((USBPhyHw *)(hpcd->pData));
|
2018-03-28 17:30:53 +00:00
|
|
|
unsigned int i;
|
2019-10-21 12:51:13 +00:00
|
|
|
for (i = 0; i < NB_ENDPOINT; i++) {
|
2019-03-19 22:10:32 +00:00
|
|
|
obj->epComplete[2 * i] = 0;
|
|
|
|
HAL_PCD_EP_Close(hpcd, IDX_TO_EP(2 * i));
|
|
|
|
HAL_PCD_EP_Flush(hpcd, IDX_TO_EP(2 * i));
|
|
|
|
obj->epComplete[2 * i + 1] = 0;
|
|
|
|
HAL_PCD_EP_Close(hpcd, IDX_TO_EP(2 * i + 1));
|
|
|
|
HAL_PCD_EP_Flush(hpcd, IDX_TO_EP(2 * i + 1));
|
2018-03-28 17:30:53 +00:00
|
|
|
|
|
|
|
}
|
2019-10-21 12:51:13 +00:00
|
|
|
obj->endpoint_add(0x80, MAX_PACKET_SIZE_EP0, USB_EP_TYPE_CTRL);
|
|
|
|
obj->endpoint_add(0x00, MAX_PACKET_SIZE_EP0, USB_EP_TYPE_CTRL);
|
2018-03-28 17:30:53 +00:00
|
|
|
obj->events->reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* hal pcd handler , used for STM32 HAL PCD Layer */
|
|
|
|
|
|
|
|
static USBPhyHw *instance;
|
|
|
|
|
|
|
|
USBPhy *get_usb_phy()
|
|
|
|
{
|
|
|
|
static USBPhyHw usbphy;
|
|
|
|
return &usbphy;
|
|
|
|
}
|
|
|
|
|
|
|
|
USBPhyHw::USBPhyHw(): events(NULL), sof_enabled(false)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
USBPhyHw::~USBPhyHw()
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void USBPhyHw::init(USBPhyEvents *events)
|
|
|
|
{
|
2019-10-21 12:51:13 +00:00
|
|
|
const PinMap *map = NULL;
|
|
|
|
|
2018-03-28 17:30:53 +00:00
|
|
|
NVIC_DisableIRQ(USBHAL_IRQn);
|
|
|
|
|
2019-02-28 20:47:05 +00:00
|
|
|
if (this->events == NULL) {
|
|
|
|
sleep_manager_lock_deep_sleep();
|
|
|
|
}
|
2018-03-28 17:30:53 +00:00
|
|
|
this->events = events;
|
|
|
|
sof_enabled = false;
|
|
|
|
memset(epComplete, 0, sizeof(epComplete));
|
|
|
|
memset(&hpcd.Init, 0, sizeof(hpcd.Init));
|
|
|
|
|
2019-10-21 12:51:13 +00:00
|
|
|
hpcd.Init.dev_endpoints = NB_ENDPOINT;
|
|
|
|
hpcd.Init.ep0_mps = MAX_PACKET_SIZE_EP0;
|
|
|
|
hpcd.Init.low_power_enable = DISABLE;
|
|
|
|
#if !defined(TARGET_STM32F2)
|
|
|
|
hpcd.Init.lpm_enable = DISABLE;
|
|
|
|
hpcd.Init.battery_charging_enable = DISABLE;
|
|
|
|
#endif
|
|
|
|
#if (MBED_CONF_TARGET_USB_SPEED == USE_USB_OTG_HS)
|
2018-03-28 17:30:53 +00:00
|
|
|
hpcd.Instance = USB_OTG_HS;
|
|
|
|
hpcd.Init.phy_itface = PCD_PHY_ULPI;
|
|
|
|
hpcd.Init.Sof_enable = 1;
|
2019-10-21 12:51:13 +00:00
|
|
|
hpcd.Init.dma_enable = DISABLE;
|
|
|
|
hpcd.Init.vbus_sensing_enable = ENABLE;
|
|
|
|
hpcd.Init.use_external_vbus = DISABLE;
|
2018-03-28 17:30:53 +00:00
|
|
|
hpcd.Init.speed = PCD_SPEED_HIGH;
|
2019-10-21 12:51:13 +00:00
|
|
|
__HAL_RCC_USB_OTG_HS_CLK_ENABLE();
|
|
|
|
__HAL_RCC_USB_OTG_HS_ULPI_CLK_ENABLE();
|
|
|
|
map = PinMap_USB_HS;
|
|
|
|
#elif (MBED_CONF_TARGET_USB_SPEED == USE_USB_OTG_HS)
|
2018-03-28 17:30:53 +00:00
|
|
|
hpcd.Instance = USB_OTG_HS;
|
|
|
|
hpcd.Init.phy_itface = PCD_PHY_EMBEDDED;
|
|
|
|
hpcd.Init.Sof_enable = 1;
|
|
|
|
hpcd.Init.speed = PCD_SPEED_HIGH;
|
2019-10-21 12:51:13 +00:00
|
|
|
#elif (MBED_CONF_TARGET_USB_SPEED == USE_USB_OTG_FS)
|
|
|
|
|
2018-03-28 17:30:53 +00:00
|
|
|
hpcd.Instance = USB_OTG_FS;
|
|
|
|
hpcd.Init.phy_itface = PCD_PHY_EMBEDDED;
|
|
|
|
hpcd.Init.Sof_enable = 1;
|
|
|
|
hpcd.Init.speed = PCD_SPEED_FULL;
|
2019-10-21 12:51:13 +00:00
|
|
|
__HAL_RCC_USB_OTG_FS_CLK_ENABLE();
|
|
|
|
map = PinMap_USB_FS;
|
|
|
|
#elif (MBED_CONF_TARGET_USB_SPEED == USE_USB_NO_OTG)
|
|
|
|
hpcd.Instance = USB;
|
|
|
|
hpcd.Init.phy_itface = PCD_PHY_EMBEDDED;
|
|
|
|
hpcd.Init.speed = PCD_SPEED_FULL;
|
|
|
|
|
|
|
|
__HAL_RCC_USB_CLK_ENABLE();
|
|
|
|
map = PinMap_USB_FS;
|
2018-03-28 17:30:53 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
// Pass instance for usage inside call back
|
|
|
|
instance = this;
|
|
|
|
|
|
|
|
// Configure USB pins and other clocks
|
|
|
|
|
2019-10-21 12:51:13 +00:00
|
|
|
while (map->pin != NC) {
|
|
|
|
pin_function(map->pin, map->function);
|
|
|
|
map++;
|
|
|
|
}
|
2018-10-31 12:15:56 +00:00
|
|
|
|
2019-10-22 09:24:47 +00:00
|
|
|
__HAL_RCC_PWR_CLK_ENABLE();
|
|
|
|
|
2019-10-21 12:51:13 +00:00
|
|
|
#if !defined(TARGET_STM32WB)
|
|
|
|
__HAL_RCC_SYSCFG_CLK_ENABLE();
|
2018-03-28 17:30:53 +00:00
|
|
|
#endif
|
|
|
|
|
2019-10-21 12:51:13 +00:00
|
|
|
#if defined(PWR_CR2_USV)
|
|
|
|
HAL_PWREx_EnableVddUSB();
|
2018-03-28 17:30:53 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
// Configure PCD and FIFOs
|
2019-03-19 22:10:32 +00:00
|
|
|
hpcd.pData = (void *)this;
|
2018-03-28 17:30:53 +00:00
|
|
|
hpcd.State = HAL_PCD_STATE_RESET;
|
2019-11-06 13:57:59 +00:00
|
|
|
HAL_StatusTypeDef ret = HAL_PCD_Init(&hpcd);
|
|
|
|
MBED_ASSERT(ret == HAL_OK);
|
2018-03-28 17:30:53 +00:00
|
|
|
|
2018-06-25 22:55:03 +00:00
|
|
|
|
|
|
|
uint32_t total_bytes = 0;
|
|
|
|
|
|
|
|
/* Reserve space in the RX buffer for:
|
|
|
|
* - 1 isochonous packet
|
|
|
|
* - 2 max sized non-isochonous packets
|
|
|
|
* - setup buffer - 10 words as specified by Reference Manual
|
|
|
|
* - global nak out - 1 words as specified by Reference Manual
|
|
|
|
*/
|
2019-10-21 12:51:13 +00:00
|
|
|
uint32_t fifo_size = (MAX_PACKET_SIZE_ISO + 4) + (MAX_PACKET_SIZE_NON_ISO + 4) * 2 + (10 * 4) + (1 * 4);
|
2018-06-25 22:55:03 +00:00
|
|
|
HAL_PCDEx_SetRxFiFo(&hpcd, (fifo_size / 4));
|
|
|
|
total_bytes += fifo_size;
|
|
|
|
|
|
|
|
/* Reserve Tx space up front */
|
|
|
|
for (int i = 0; i < NUM_ENDPOINTS; i++) {
|
|
|
|
fifo_size = tx_ep_sizes[i] + 4;
|
|
|
|
HAL_PCDEx_SetTxFiFo(&hpcd, i, fifo_size / 4);
|
|
|
|
total_bytes += fifo_size;
|
|
|
|
}
|
|
|
|
|
2018-03-28 17:30:53 +00:00
|
|
|
/* 1.25 kbytes */
|
2018-06-25 22:55:03 +00:00
|
|
|
MBED_ASSERT(total_bytes <= 1280);
|
2018-03-28 17:30:53 +00:00
|
|
|
|
|
|
|
// Configure interrupt vector
|
|
|
|
NVIC_SetVector(USBHAL_IRQn, (uint32_t)&_usbisr);
|
|
|
|
NVIC_SetPriority(USBHAL_IRQn, 1);
|
|
|
|
NVIC_EnableIRQ(USBHAL_IRQn);
|
|
|
|
}
|
|
|
|
|
|
|
|
void USBPhyHw::deinit()
|
|
|
|
{
|
2019-11-06 13:57:59 +00:00
|
|
|
HAL_StatusTypeDef ret = HAL_PCD_DeInit(&hpcd);
|
|
|
|
MBED_ASSERT(ret == HAL_OK);
|
|
|
|
|
2018-03-28 17:30:53 +00:00
|
|
|
NVIC_DisableIRQ(USBHAL_IRQn);
|
2019-02-28 20:47:05 +00:00
|
|
|
|
|
|
|
if (events != NULL) {
|
|
|
|
sleep_manager_unlock_deep_sleep();
|
|
|
|
}
|
|
|
|
events = NULL;
|
2018-03-28 17:30:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool USBPhyHw::powered()
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void USBPhyHw::connect()
|
|
|
|
{
|
2019-11-06 13:57:59 +00:00
|
|
|
HAL_StatusTypeDef ret = HAL_PCD_Start(&hpcd);
|
|
|
|
MBED_ASSERT(ret == HAL_OK);
|
2018-03-28 17:30:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void USBPhyHw::disconnect()
|
|
|
|
{
|
2019-11-06 13:57:59 +00:00
|
|
|
HAL_StatusTypeDef ret = HAL_PCD_Stop(&hpcd);
|
|
|
|
MBED_ASSERT(ret == HAL_OK);
|
2018-03-28 17:30:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void USBPhyHw::configure()
|
|
|
|
{
|
|
|
|
// Not needed
|
|
|
|
}
|
|
|
|
|
|
|
|
void USBPhyHw::unconfigure()
|
|
|
|
{
|
|
|
|
// Not needed
|
|
|
|
}
|
|
|
|
|
|
|
|
void USBPhyHw::sof_enable()
|
|
|
|
{
|
|
|
|
sof_enabled = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void USBPhyHw::sof_disable()
|
|
|
|
{
|
|
|
|
sof_enabled = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void USBPhyHw::set_address(uint8_t address)
|
|
|
|
{
|
2019-11-06 13:57:59 +00:00
|
|
|
HAL_StatusTypeDef ret = HAL_PCD_SetAddress(&hpcd, address);
|
|
|
|
MBED_ASSERT(ret == HAL_OK);
|
2018-03-28 17:30:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void USBPhyHw::remote_wakeup()
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
const usb_ep_table_t *USBPhyHw::endpoint_table()
|
|
|
|
{
|
|
|
|
static const usb_ep_table_t table = {
|
2018-06-25 22:55:03 +00:00
|
|
|
1280, // 1.25K for endpoint buffers but space is allocated up front
|
2018-03-28 17:30:53 +00:00
|
|
|
{
|
2019-10-21 12:51:13 +00:00
|
|
|
{USB_EP_ATTR_ALLOW_CTRL | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0},
|
|
|
|
{USB_EP_ATTR_ALLOW_BULK | USB_EP_ATTR_ALLOW_INT | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0}, // NON ISO
|
|
|
|
{USB_EP_ATTR_ALLOW_BULK | USB_EP_ATTR_ALLOW_INT | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0}, // NON ISO
|
|
|
|
{USB_EP_ATTR_ALLOW_ALL | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0},
|
2018-06-25 22:55:03 +00:00
|
|
|
{0 | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0},
|
|
|
|
{0 | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0},
|
|
|
|
{0 | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0},
|
|
|
|
{0 | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0},
|
|
|
|
{0 | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0},
|
|
|
|
{0 | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0},
|
|
|
|
{0 | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0},
|
|
|
|
{0 | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0},
|
|
|
|
{0 | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0},
|
|
|
|
{0 | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0},
|
|
|
|
{0 | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0},
|
|
|
|
{0 | USB_EP_ATTR_DIR_IN_AND_OUT, 0, 0}
|
2018-03-28 17:30:53 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
return &table;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t USBPhyHw::ep0_set_max_packet(uint32_t max_packet)
|
|
|
|
{
|
|
|
|
// FUTURE - set endpoint 0 size and return this size
|
|
|
|
return MAX_PACKET_SIZE_EP0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// read setup packet
|
|
|
|
void USBPhyHw::ep0_setup_read_result(uint8_t *buffer, uint32_t size)
|
|
|
|
{
|
|
|
|
if (size > MAX_PACKET_SIZE_SETUP) {
|
|
|
|
size = MAX_PACKET_SIZE_SETUP;
|
|
|
|
}
|
|
|
|
memcpy(buffer, hpcd.Setup, size);
|
2019-03-19 22:10:32 +00:00
|
|
|
memset(hpcd.Setup, 0, MAX_PACKET_SIZE_SETUP);
|
2018-03-28 17:30:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void USBPhyHw::ep0_read(uint8_t *data, uint32_t size)
|
|
|
|
{
|
|
|
|
HAL_StatusTypeDef ret;
|
2019-10-21 12:51:13 +00:00
|
|
|
epComplete[EP_TO_IDX(0x00)] = 2;
|
|
|
|
ret = HAL_PCD_EP_Receive(&hpcd, 0x00, data, size > MAX_PACKET_SIZE_EP0 ? MAX_PACKET_SIZE_EP0 : size);
|
2019-03-19 22:10:32 +00:00
|
|
|
MBED_ASSERT(ret != HAL_BUSY);
|
2018-03-28 17:30:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t USBPhyHw::ep0_read_result()
|
|
|
|
{
|
2019-10-21 12:51:13 +00:00
|
|
|
epComplete[EP_TO_IDX(0x00)] = 0;
|
2018-05-03 16:12:15 +00:00
|
|
|
return HAL_PCD_EP_GetRxCount(&hpcd, 0);
|
2018-03-28 17:30:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void USBPhyHw::ep0_write(uint8_t *buffer, uint32_t size)
|
|
|
|
{
|
|
|
|
/* check that endpoint maximum size is not exceeding TX fifo */
|
|
|
|
MBED_ASSERT(hpcd.IN_ep[0].maxpacket >= size);
|
2019-10-21 12:51:13 +00:00
|
|
|
endpoint_write(0x80, buffer, size);
|
2018-03-28 17:30:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void USBPhyHw::ep0_stall()
|
|
|
|
{
|
2019-10-21 12:51:13 +00:00
|
|
|
endpoint_stall(0x80);
|
|
|
|
endpoint_stall(0x00);
|
2018-03-28 17:30:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool USBPhyHw::endpoint_add(usb_ep_t endpoint, uint32_t max_packet, usb_ep_type_t type)
|
|
|
|
{
|
|
|
|
uint32_t len;
|
2018-06-25 22:55:03 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Endpoints are configured in init since re-configuring
|
|
|
|
* fifos when endpoints are added or removed causes tests to fail.
|
|
|
|
*/
|
2018-03-28 17:30:53 +00:00
|
|
|
if (endpoint & 0x80) {
|
2019-03-19 22:10:32 +00:00
|
|
|
len = HAL_PCDEx_GetTxFiFo(&hpcd, endpoint & 0x7f);
|
2018-03-28 17:30:53 +00:00
|
|
|
MBED_ASSERT(len >= max_packet);
|
|
|
|
}
|
|
|
|
HAL_StatusTypeDef ret = HAL_PCD_EP_Open(&hpcd, endpoint, max_packet, type);
|
2019-03-19 22:10:32 +00:00
|
|
|
MBED_ASSERT(ret != HAL_BUSY);
|
|
|
|
return (ret == HAL_OK) ? true : false;
|
2018-03-28 17:30:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void USBPhyHw::endpoint_remove(usb_ep_t endpoint)
|
|
|
|
{
|
|
|
|
HAL_StatusTypeDef ret = HAL_PCD_EP_Close(&hpcd, endpoint);
|
|
|
|
MBED_ASSERT(ret == HAL_OK);
|
|
|
|
}
|
|
|
|
|
|
|
|
void USBPhyHw::endpoint_stall(usb_ep_t endpoint)
|
|
|
|
{
|
|
|
|
HAL_StatusTypeDef ret;
|
|
|
|
ret = HAL_PCD_EP_SetStall(&hpcd, endpoint);
|
2019-03-19 22:10:32 +00:00
|
|
|
MBED_ASSERT(ret != HAL_BUSY);
|
2018-03-28 17:30:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void USBPhyHw::endpoint_unstall(usb_ep_t endpoint)
|
|
|
|
{
|
|
|
|
HAL_StatusTypeDef ret;
|
|
|
|
ret = HAL_PCD_EP_ClrStall(&hpcd, endpoint);
|
2019-03-19 22:10:32 +00:00
|
|
|
MBED_ASSERT(ret != HAL_BUSY);
|
2018-03-28 17:30:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool USBPhyHw::endpoint_read(usb_ep_t endpoint, uint8_t *data, uint32_t size)
|
|
|
|
{
|
|
|
|
// clean reception end flag before requesting reception
|
2018-05-03 16:12:15 +00:00
|
|
|
HAL_StatusTypeDef ret = HAL_PCD_EP_Receive(&hpcd, endpoint, data, size);
|
2019-03-19 22:10:32 +00:00
|
|
|
MBED_ASSERT(ret != HAL_BUSY);
|
2018-03-28 17:30:53 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t USBPhyHw::endpoint_read_result(usb_ep_t endpoint)
|
|
|
|
{
|
2019-03-19 22:10:32 +00:00
|
|
|
if (epComplete[EP_TO_IDX(endpoint)] == 0) {
|
2018-03-28 17:30:53 +00:00
|
|
|
/* no reception possible !!! */
|
|
|
|
return 0;
|
2019-03-19 22:10:32 +00:00
|
|
|
} else if ((epComplete[EP_TO_IDX(endpoint)] != 1)) {
|
2018-03-28 17:30:53 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2019-03-19 22:10:32 +00:00
|
|
|
epComplete[EP_TO_IDX(endpoint)] = 0;
|
2018-05-03 16:12:15 +00:00
|
|
|
return HAL_PCD_EP_GetRxCount(&hpcd, endpoint);;
|
2018-03-28 17:30:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool USBPhyHw::endpoint_write(usb_ep_t endpoint, uint8_t *data, uint32_t size)
|
|
|
|
{
|
|
|
|
HAL_StatusTypeDef ret;
|
|
|
|
// clean transmission end flag before requesting transmission
|
|
|
|
epComplete[EP_TO_IDX(endpoint)] = 2;
|
|
|
|
ret = HAL_PCD_EP_Transmit(&hpcd, endpoint, data, size);
|
2019-03-19 22:10:32 +00:00
|
|
|
MBED_ASSERT(ret != HAL_BUSY);
|
2018-03-28 17:30:53 +00:00
|
|
|
// update the status
|
2019-03-19 22:10:32 +00:00
|
|
|
if (ret != HAL_OK) {
|
|
|
|
return false;
|
|
|
|
}
|
2018-03-28 17:30:53 +00:00
|
|
|
// fix me return is too simple
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void USBPhyHw::endpoint_abort(usb_ep_t endpoint)
|
|
|
|
{
|
2019-10-21 12:51:13 +00:00
|
|
|
#if (TARGET_STM32F4) || (TARGET_STM32F2)
|
|
|
|
HAL_StatusTypeDef ret = HAL_PCD_EP_Abort(&hpcd, endpoint); // fix me: ST driver should not be modified
|
|
|
|
#else
|
|
|
|
HAL_StatusTypeDef ret = HAL_PCD_EP_Close(&hpcd, endpoint); // fix me: implementation not correct
|
2019-09-03 12:14:08 +00:00
|
|
|
#endif
|
2019-10-21 12:51:13 +00:00
|
|
|
MBED_ASSERT(ret == HAL_OK);
|
2018-03-28 17:30:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void USBPhyHw::process()
|
|
|
|
{
|
|
|
|
HAL_PCD_IRQHandler(&instance->hpcd);
|
|
|
|
// Re-enable interrupt
|
|
|
|
NVIC_ClearPendingIRQ(USBHAL_IRQn);
|
|
|
|
NVIC_EnableIRQ(USBHAL_IRQn);
|
|
|
|
}
|
|
|
|
|
2019-03-19 22:10:32 +00:00
|
|
|
void USBPhyHw::_usbisr(void)
|
|
|
|
{
|
2018-03-28 17:30:53 +00:00
|
|
|
NVIC_DisableIRQ(USBHAL_IRQn);
|
|
|
|
instance->events->start_process();
|
|
|
|
}
|
|
|
|
|
2019-10-21 12:51:13 +00:00
|
|
|
#endif /* DEVICE_USBDEVICE */
|