0
mirror of https://gitlab.com/hyperglitch/jellyfish.git synced 2025-12-26 07:06:47 +00:00

241 lines
6.2 KiB
C

/**
******************************************************************************
* @file usbd_bulk.c
* @brief This file provides all the BULK core functions.
******************************************************************************
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usbd_bulk.h"
uint8_t USBD_BULK_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
uint8_t USBD_BULK_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
uint8_t USBD_BULK_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
uint8_t USBD_BULK_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum);
uint8_t USBD_BULK_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum);
volatile bool is_bulk_initialized = false;
USBD_ClassTypeDef USBD_BULK =
{
USBD_BULK_Init,
USBD_BULK_DeInit,
USBD_BULK_Setup,
NULL, /*EP0_TxSent*/
NULL, /*EP0_RxReady*/
USBD_BULK_DataIn,
USBD_BULK_DataOut,
NULL, /*SOF */
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
};
uint8_t BULKInEpAdd = BULK_EPIN_ADDR;
uint8_t BULKOutEpAdd = BULK_EPOUT_ADDR;
usb_bulk_txcplt_callback_t tx_done_cb = NULL;
void USBD_BULK_Register_TxCplt_Callback(usb_bulk_txcplt_callback_t callback) {
tx_done_cb = callback;
}
/**
* @}
*/
/** @defgroup BULK_CORE_Private_Functions
* @{
*/
/**
* @brief USBD_BULK_Init
* Initialize the mass storage configuration
* @param pdev: device instance
* @param cfgidx: configuration index
* @retval status
*/
uint8_t USBD_BULK_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
{
UNUSED(cfgidx);
pdev->pClassData = pdev->pClassDataCmsit[pdev->classId];
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
BULKInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
BULKOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
/* Open EP OUT */
(void)USBD_LL_OpenEP(pdev, BULKOutEpAdd, USBD_EP_TYPE_BULK, BULK_MAX_HS_PACKET);
pdev->ep_out[BULKOutEpAdd & 0xFU].is_used = 1U;
/* Open EP IN */
(void)USBD_LL_OpenEP(pdev, BULKInEpAdd, USBD_EP_TYPE_BULK, BULK_MAX_HS_PACKET);
pdev->ep_in[BULKInEpAdd & 0xFU].is_used = 1U;
is_bulk_initialized = true;
return (uint8_t)USBD_OK;
}
bool USBD_BULK_Is_Initialized() {
return is_bulk_initialized;
}
/**
* @brief USBD_BULK_DeInit
* DeInitialize the mass storage configuration
* @param pdev: device instance
* @param cfgidx: configuration index
* @retval status
*/
uint8_t USBD_BULK_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
{
UNUSED(cfgidx);
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
BULKInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
BULKOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
/* Close BULK EPs */
(void)USBD_LL_CloseEP(pdev, BULKOutEpAdd);
pdev->ep_out[BULKOutEpAdd & 0xFU].is_used = 0U;
/* Close EP IN */
(void)USBD_LL_CloseEP(pdev, BULKInEpAdd);
pdev->ep_in[BULKInEpAdd & 0xFU].is_used = 0U;
/* Free BULK Class Resources */
if (pdev->pClassDataCmsit[pdev->classId] != NULL)
{
(void)USBD_free(pdev->pClassDataCmsit[pdev->classId]);
pdev->pClassDataCmsit[pdev->classId] = NULL;
pdev->pClassData = NULL;
}
return (uint8_t)USBD_OK;
}
/**
* @brief USBD_BULK_Setup
* Handle the BULK specific requests
* @param pdev: device instance
* @param req: USB request
* @retval status
*/
uint8_t USBD_BULK_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
{
USBD_StatusTypeDef ret = USBD_OK;
uint16_t status_info = 0U;
#ifdef USE_USBD_COMPOSITE
/* Get the Endpoints addresses allocated for this class instance */
BULKInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
BULKOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
#endif /* USE_USBD_COMPOSITE */
switch (req->bmRequest & USB_REQ_TYPE_MASK)
{
/* Interface & Endpoint request */
case USB_REQ_TYPE_STANDARD:
switch (req->bRequest)
{
case USB_REQ_GET_STATUS:
if (pdev->dev_state == USBD_STATE_CONFIGURED)
{
(void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U);
}
else
{
USBD_CtlError(pdev, req);
ret = USBD_FAIL;
}
break;
case USB_REQ_CLEAR_FEATURE:
if (pdev->dev_state == USBD_STATE_CONFIGURED)
{
if (req->wValue == USB_FEATURE_EP_HALT)
{
/* Flush the FIFO */
(void)USBD_LL_FlushEP(pdev, (uint8_t)req->wIndex);
}
}
break;
default:
USBD_CtlError(pdev, req);
ret = USBD_FAIL;
break;
}
break;
default:
USBD_CtlError(pdev, req);
ret = USBD_FAIL;
break;
}
return (uint8_t)ret;
}
/**
* @brief USBD_BULK_DataIn
* handle data IN Stage
* @param pdev: device instance
* @param epnum: endpoint index
* @retval status
*/
uint8_t USBD_BULK_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
{
if (tx_done_cb!=NULL && epnum == (BULK_EPIN_ADDR & 0x7F)) {
tx_done_cb();
}
return (uint8_t)USBD_OK;
}
/**
* @brief USBD_BULK_DataOut
* handle data OUT Stage
* @param pdev: device instance
* @param epnum: endpoint index
* @retval status
*/
uint8_t USBD_BULK_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
{
return (uint8_t)USBD_OK;
}
/**
* @brief USBD_BULK_RegisterInterface
* @param fops: storage callback
* @retval status
*/
uint8_t USBD_BULK_RegisterInterface(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *fops)
{
if (fops == NULL)
{
return (uint8_t)USBD_FAIL;
}
pdev->pUserData[pdev->classId] = fops;
return (uint8_t)USBD_OK;
}