Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Diff: targets/TARGET_STM/USBHAL_STM32.cpp
- Revision:
- 71:53949e6131f6
diff -r 2c525a50f1b6 -r 53949e6131f6 targets/TARGET_STM/USBHAL_STM32.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/targets/TARGET_STM/USBHAL_STM32.cpp Thu Jul 27 12:14:04 2017 +0100
@@ -0,0 +1,332 @@
+/* Copyright (c) 2010-2011 mbed.org, MIT License
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+* and associated documentation files (the "Software"), to deal in the Software without
+* restriction, including without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all copies or
+* substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+/* TARGET NOT STM does not support this HAL */
+#ifndef TARGET_STM
+#define USBSTM_HAL_UNSUPPORTED
+#endif
+/* F4 famlily wihtout USB_STM_HAL use another HAL*/
+#if defined(TARGET_STM) && defined(TARGET_STM32F4) && !defined(USB_STM_HAL)
+#define USBSTM_HAL_UNSUPPORTED
+#endif
+
+#ifndef USBSTM_HAL_UNSUPPORTED
+#include "USBHAL.h"
+#include "pinmap.h"
+/* mbed endpoint definition to hal definition */
+#define EP_ADDR(ep) (((ep) >> 1)|((ep) & 1) << 7)
+/* from hal definition to mbed definition */
+#define ADDR_EPIN(ep) (((ep) << 1) | 1)
+#define ADDR_EPOUT(ep) (((ep) << 1))
+/* id to detect if rx buffer is used or not */
+
+#include "USBHAL_STM_TARGET.h"
+
+
+/* this call at device reception completion on a Out Enpoint */
+void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
+{
+ USBHAL_Private_t *priv=((USBHAL_Private_t *)(hpcd->pData));
+ USBHAL *obj= priv->inst;
+ uint8_t endpoint = ADDR_EPOUT(epnum);
+ priv->epComplete[endpoint] = 1;
+ /* -2 endpoint 0 In out are not in call back list */
+ if (epnum) {
+ bool (USBHAL::*func)(void) = priv->epCallback[endpoint-2];
+ (obj->*func)();
+ } else {
+ void (USBHAL::*func)(void) = priv->ep0_out;
+ (obj->*func)();
+ }
+}
+
+/* this is call at device transmission completion on In endpoint */
+void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
+{
+ USBHAL_Private_t *priv=((USBHAL_Private_t *)(hpcd->pData));
+ USBHAL *obj= priv->inst;
+ uint8_t endpoint = ADDR_EPIN(epnum);
+ priv->epComplete[endpoint] = 1;
+ /* -2 endpoint 0 In out are not in call back list */
+ if (epnum) {
+ bool (USBHAL::*func)(void) = priv->epCallback[endpoint-2];
+ (obj->*func)();
+ } else {
+ void (USBHAL::*func)(void) = priv->ep0_in;
+ (obj->*func)();
+ }
+}
+/* This is call at device set up reception */
+void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
+{
+ USBHAL_Private_t *priv=((USBHAL_Private_t *)(hpcd->pData));
+ USBHAL *obj= priv->inst;
+ void (USBHAL::*func)(void)=priv->ep0_setup;
+ void (USBHAL::*func1)(void)=priv->ep0_read;
+ (obj->*func)();
+ (obj->*func1)();
+}
+
+void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
+{
+ USBHAL_Private_t *priv=((USBHAL_Private_t *)(hpcd->pData));
+ USBHAL *obj= priv->inst;
+ void (USBHAL::*func)(unsigned int suspended) = priv->suspend_change;
+ (obj->*func)(1);
+}
+
+void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
+{
+ USBHAL_Private_t *priv=((USBHAL_Private_t *)(hpcd->pData));
+ USBHAL *obj= priv->inst;
+ void (USBHAL::*func)(unsigned int suspended) = priv->suspend_change;
+ (obj->*func)(0);
+}
+
+void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
+{
+ USBHAL_Private_t *priv=((USBHAL_Private_t *)(hpcd->pData));
+ USBHAL *obj= priv->inst;
+ void (USBHAL::*func)(unsigned int suspended) = priv->connect_change;
+ (obj->*func)(1);
+}
+
+void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
+{
+ USBHAL_Private_t *priv=((USBHAL_Private_t *)(hpcd->pData));
+ USBHAL *obj= priv->inst;
+ void (USBHAL::*func)(unsigned int suspended) = priv->connect_change;
+ (obj->*func)(0);
+}
+
+void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
+{
+ USBHAL_Private_t *priv=((USBHAL_Private_t *)(hpcd->pData));
+ USBHAL *obj= priv->inst;
+ unsigned int i;
+ for(i=0;i<hpcd->Init.dev_endpoints;i++) {
+ priv->epComplete[2*i]=0;
+ HAL_PCD_EP_Close(hpcd,EP_ADDR(2*i));
+ HAL_PCD_EP_Flush(hpcd,EP_ADDR(2*i));
+ priv->epComplete[2*i+1]=0;
+ HAL_PCD_EP_Close(hpcd,EP_ADDR(2*i+1));
+ HAL_PCD_EP_Flush(hpcd,EP_ADDR(2*i+1));
+
+ }
+ void (USBHAL::*func)(void)=priv->bus_reset;
+ bool (USBHAL::*ep_realise)(uint8_t endpoint, uint32_t maxPacket, uint32_t flags) = priv->ep_realise;
+ (obj->*func)();
+ (obj->*ep_realise)(EP0IN, MAX_PACKET_SIZE_EP0,0);
+ (obj->*ep_realise)(EP0OUT, MAX_PACKET_SIZE_EP0,0);
+}
+
+
+/* hal pcd handler , used for STM32 HAL PCD Layer */
+
+uint32_t USBHAL::endpointReadcore(uint8_t endpoint, uint8_t *buffer) {
+ return 0;
+}
+
+USBHAL::~USBHAL(void) {
+ USBHAL_Private_t *HALPriv = (USBHAL_Private_t *)(hpcd.pData);
+ HAL_PCD_DeInit(&hpcd);
+ delete HALPriv;
+}
+
+void USBHAL::connect(void) {
+ NVIC_EnableIRQ(USBHAL_IRQn);
+}
+
+void USBHAL::disconnect(void) {
+ NVIC_DisableIRQ(USBHAL_IRQn);
+}
+
+void USBHAL::configureDevice(void) {
+ // Not needed
+}
+
+void USBHAL::unconfigureDevice(void) {
+ // Not needed
+}
+
+void USBHAL::setAddress(uint8_t address) {
+ HAL_PCD_SetAddress(&hpcd, address);
+ EP0write(0, 0);
+}
+
+bool USBHAL::realiseEndpoint(uint8_t endpoint, uint32_t maxPacket, uint32_t flags) {
+ uint32_t epIndex = EP_ADDR(endpoint);
+ uint32_t type;
+ uint32_t len;
+ HAL_StatusTypeDef ret;
+ switch (endpoint) {
+ case EP0IN:
+ case EP0OUT:
+ type = 0;
+ break;
+ case EPISO_IN:
+ case EPISO_OUT:
+ type = 1;
+ break;
+ case EPBULK_IN:
+ case EPBULK_OUT:
+ type = 2;
+ break;
+ case EPINT_IN:
+ case EPINT_OUT:
+ type = 3;
+ break;
+ }
+ if (maxPacket > MAXTRANSFER_SIZE) return false;
+ if (epIndex & 0x80) {
+ len = HAL_PCDEx_GetTxFiFo(&hpcd,epIndex & 0x7f);
+ MBED_ASSERT(len >= maxPacket);
+ }
+ ret = HAL_PCD_EP_Open(&hpcd, epIndex, maxPacket, type);
+ MBED_ASSERT(ret!=HAL_BUSY);
+ return (ret == HAL_OK) ? true:false;
+}
+
+// read setup packet
+void USBHAL::EP0setup(uint8_t *buffer) {
+ memcpy(buffer, hpcd.Setup, MAX_PACKET_SIZE_SETUP);
+ memset(hpcd.Setup,0,MAX_PACKET_SIZE_SETUP);
+}
+
+void USBHAL::EP0readStage(void) {
+}
+
+void USBHAL::EP0read(void) {
+ USBHAL_Private_t *HALPriv = (USBHAL_Private_t *)hpcd.pData;
+ uint32_t epIndex = EP_ADDR(EP0OUT);
+ uint8_t *pBuf = (uint8_t *)HALPriv->pBufRx0;
+ HAL_StatusTypeDef ret;
+ HALPriv->epComplete[EP0OUT] = 2;
+ ret = HAL_PCD_EP_Receive(&hpcd, epIndex, pBuf, MAX_PACKET_SIZE_EP0 );
+ MBED_ASSERT(ret!=HAL_BUSY);
+
+}
+
+uint32_t USBHAL::EP0getReadResult(uint8_t *buffer) {
+ USBHAL_Private_t *HALPriv = (USBHAL_Private_t *)hpcd.pData;
+ uint32_t length = (uint32_t) HAL_PCD_EP_GetRxCount(&hpcd, 0);
+ HALPriv->epComplete[EP0OUT] = 0;
+ if (length) {
+ uint8_t *buff = (uint8_t *)HALPriv->pBufRx0;
+ memcpy(buffer, buff, length);
+ }
+ return length;
+}
+
+void USBHAL::EP0write(uint8_t *buffer, uint32_t size) {
+ /* check that endpoint maximum size is not exceeding TX fifo */
+ MBED_ASSERT(hpcd.IN_ep[0].maxpacket >= size);
+ endpointWrite(EP0IN, buffer, size);
+}
+
+void USBHAL::EP0getWriteResult(void) {
+
+}
+
+void USBHAL::EP0stall(void) {
+ stallEndpoint(EP0IN);
+}
+
+EP_STATUS USBHAL::endpointRead(uint8_t endpoint, uint32_t maximumSize) {
+ USBHAL_Private_t *HALPriv = (USBHAL_Private_t *)(hpcd.pData);
+ uint32_t epIndex = EP_ADDR(endpoint);
+ uint8_t* pBuf = (uint8_t *)HALPriv->pBufRx;
+ HAL_StatusTypeDef ret;
+ // clean reception end flag before requesting reception
+ HALPriv->epComplete[endpoint] = 2;
+ ret = HAL_PCD_EP_Receive(&hpcd, epIndex, pBuf, maximumSize);
+ MBED_ASSERT(ret!=HAL_BUSY);
+ return EP_PENDING;
+}
+
+EP_STATUS USBHAL::endpointReadResult(uint8_t endpoint, uint8_t * buffer, uint32_t *bytesRead) {
+ USBHAL_Private_t *HALPriv = (USBHAL_Private_t *)(hpcd.pData);
+ if (HALPriv->epComplete[endpoint]==0) {
+ /* no reception possible !!! */
+ bytesRead = 0;
+ return EP_COMPLETED;
+ }else if ((HALPriv->epComplete[endpoint]!=1))
+ return EP_PENDING;
+ uint32_t epIndex = EP_ADDR(endpoint);
+ uint8_t *buff = (uint8_t *)HALPriv->pBufRx;
+ uint32_t length = (uint32_t) HAL_PCD_EP_GetRxCount(&hpcd, epIndex);
+ memcpy(buffer, buff, length);
+ *bytesRead = length;
+ HALPriv->epComplete[endpoint]= 0;
+ return EP_COMPLETED;
+}
+
+EP_STATUS USBHAL::endpointWrite(uint8_t endpoint, uint8_t *data, uint32_t size) {
+ USBHAL_Private_t *HALPriv = (USBHAL_Private_t *)(hpcd.pData);
+ uint32_t epIndex = EP_ADDR(endpoint);
+ HAL_StatusTypeDef ret;
+ // clean transmission end flag before requesting transmission
+ HALPriv->epComplete[endpoint] = 2;
+ ret = HAL_PCD_EP_Transmit(&hpcd, epIndex, data, size);
+ MBED_ASSERT(ret!=HAL_BUSY);
+ // update the status
+ if (ret != HAL_OK) return EP_INVALID;
+ // fix me return is too simple
+ return EP_PENDING;
+}
+
+EP_STATUS USBHAL::endpointWriteResult(uint8_t endpoint) {
+ USBHAL_Private_t *HALPriv = (USBHAL_Private_t *)(hpcd.pData);
+ if (HALPriv->epComplete[endpoint] == 1)
+ return EP_COMPLETED;
+ return EP_PENDING;
+}
+
+void USBHAL::stallEndpoint(uint8_t endpoint) {
+ USBHAL_Private_t *HALPriv = (USBHAL_Private_t *)(hpcd.pData);
+ HAL_StatusTypeDef ret;
+ HALPriv->epComplete[endpoint] = 0;
+ ret = HAL_PCD_EP_SetStall(&hpcd, EP_ADDR(endpoint));
+ MBED_ASSERT(ret!=HAL_BUSY);
+}
+
+void USBHAL::unstallEndpoint(uint8_t endpoint) {
+ HAL_StatusTypeDef ret;
+ ret = HAL_PCD_EP_ClrStall(&hpcd, EP_ADDR(endpoint));
+ MBED_ASSERT(ret!=HAL_BUSY);
+
+}
+
+bool USBHAL::getEndpointStallState(uint8_t endpoint) {
+ return false;
+}
+
+void USBHAL::remoteWakeup(void) {
+}
+
+
+void USBHAL::_usbisr(void) {
+ instance->usbisr();
+}
+
+
+void USBHAL::usbisr(void) {
+
+ HAL_PCD_IRQHandler(&instance->hpcd);
+}
+#endif
+