Skip to content

TARGET_STM :USB device FS #3062

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 8 commits into from
Nov 29, 2016
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
6 changes: 4 additions & 2 deletions features/unsupported/USBDevice/USBAudio/USBAudio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,8 @@ void USBAudio::USBCallback_requestCompleted(uint8_t * buf, uint32_t length) {
switch (transfer->setup.bRequest) {
case REQUEST_SET_CUR:
mute = data & 0xff;
updateVol.call();
if (updateVol)
updateVol.call();
break;
default:
break;
Expand All @@ -324,7 +325,8 @@ void USBAudio::USBCallback_requestCompleted(uint8_t * buf, uint32_t length) {
case REQUEST_SET_CUR:
volCur = data;
volume = (float)volCur/(float)volMax;
updateVol.call();
if (updateVol)
updateVol.call();
break;
default:
break;
Expand Down
325 changes: 325 additions & 0 deletions features/unsupported/USBDevice/USBDevice/TARGET_STM/USBHAL_STM32.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,325 @@
/* 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.
*/
#if (defined (USB_STM_HAL) && defined(TARGET_STM32F4)) \
|| defined(TARGET_STM32F2) || defined (TARGET_STM32F7) || defined (TARGET_STM32F3) || defined (TARGET_STM32L4)

#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

Loading