📄 bot_driver.c
字号:
pBot->sCommandState.bState = 0;
pBot->sCommandState.bCase = 0;
pBot->sCommandState.dLength = 0;
pBot->sCommandState.sTransfer.bSemaphore = 0;
// LUNs
pBot->pLun = pLun;
pBot->bMaxLun = (unsigned char) (bNumLun - 1);
// Reset BOT driver
BOT_Reset(pBot);
// Init the USB driver
USB_Init(pUsb);
}
//------------------------------------------------------------------------------
//! \brief Handler for incoming SETUP requests on default Control endpoint 0.
//!
//! Standard requests are forwarded to the STD_RequestHandler method.
//! \param pBot Pointer to a S_bot instance
//------------------------------------------------------------------------------
void BOT_RequestHandler(S_bot *pBot)
{
const S_usb *pUsb = pBot->sClass.pUsb;
S_usb_request *pSetup = USB_GetSetup(pUsb);
TRACE_DEBUG_M("NewReq ");
// Handle requests
switch (pSetup->bRequest) {
//---------------------
case USB_CLEAR_FEATURE:
//---------------------
TRACE_DEBUG_M("ClrFeat ");
switch (pSetup->wValue) {
//---------------------
case USB_ENDPOINT_HALT:
//---------------------
TRACE_DEBUG_M("Hlt ");
// Do not clear the endpoint halt status if the device is waiting
// for a reset recovery sequence
if (!pBot->isWaitResetRecovery) {
// Forward the request to the standard handler
STD_RequestHandler(&(pBot->sClass));
}
else {
TRACE_DEBUG_M("No ");
}
USB_SendZLP0(pUsb, 0, 0);
break;
//------
default:
//------
// Forward the request to the standard handler
STD_RequestHandler(&(pBot->sClass));
}
break;
//-------------------
case MSD_GET_MAX_LUN:
//-------------------
TRACE_DEBUG_M("gMaxLun ");
// Check request parameters
if ((pSetup->wValue == 0)
&& (pSetup->wIndex == 0)
&& (pSetup->wLength == 1)) {
USB_Write(pUsb, 0, &(pBot->bMaxLun), 1, 0, 0);
}
else {
TRACE_WARNING("W: BOT_RequestHandler: GetMaxLUN(%d,%d,%d)\n\r",
pSetup->wValue, pSetup->wIndex, pSetup->wLength);
USB_Stall(pUsb, 0);
}
break;
//-----------------------
case MSD_BULK_ONLY_RESET:
//-----------------------
TRACE_DEBUG_M("Rst ");
// Check parameters
if ((pSetup->wValue == 0)
&& (pSetup->wIndex == 0)
&& (pSetup->wLength == 0)) {
// Reset the MSD driver
BOT_Reset(pBot);
USB_SendZLP0(pUsb, 0, 0);
}
else {
TRACE_WARNING("W: BOT_RequestHandler: Reset(%d,%d,%d)\n\r",
pSetup->wValue, pSetup->wIndex, pSetup->wLength);
USB_Stall(pUsb, 0);
}
break;
//------
default:
//------
// Forward request to standard handler
STD_RequestHandler(&(pBot->sClass));
break;
}
#if !defined(TR_DEBUG_L)
TRACE_DEBUG_M("\n\r");
#endif
}
//------------------------------------------------------------------------------
//! \brief State machine for the BOT driver
//! \param pBot Pointer to a S_bot instance
//------------------------------------------------------------------------------
void BOT_StateMachine(S_bot *pBot)
{
const S_usb *pUsb = pBot->sClass.pUsb;
S_bot_command_state *pCommandState = &(pBot->sCommandState);
S_msd_cbw *pCbw = &(pCommandState->sCbw);
S_msd_csw *pCsw = &(pCommandState->sCsw);
S_bot_transfer *pTransfer = &(pCommandState->sTransfer);
unsigned char bStatus;
// Identify current driver state
switch (pBot->bState) {
//----------------------
case BOT_STATE_READ_CBW:
//----------------------
// Start the CBW read operation
pTransfer->bSemaphore = 0;
bStatus = USB_Read(pUsb,
BOT_EPT_BULK_OUT,
pCbw,
MSD_CBW_SIZE,
(Callback_f) BOT_Callback,
(void *) pTransfer);
// Check operation result code
if (bStatus == USB_STATUS_SUCCESS) {
// If the command was successful, wait for transfer
pBot->bState = BOT_STATE_WAIT_CBW;
}
break;
//----------------------
case BOT_STATE_WAIT_CBW:
//----------------------
// Check transfer semaphore
if (pTransfer->bSemaphore > 0) {
// Take semaphore and terminate transfer
pTransfer->bSemaphore--;
// Check if transfer was successful
if (pTransfer->bStatus == USB_STATUS_SUCCESS) {
#if !defined(TR_DEBUG_L)
TRACE_DEBUG_M("\n\r");
#endif
TRACE_DEBUG_M("------------------------------\n\r");
// Process received command
pBot->bState = BOT_STATE_PROCESS_CBW;
}
else if (pTransfer->bStatus == USB_STATUS_RESET) {
TRACE_INFO("I: BOT_StateMachine: Endpoint resetted\n\r");
pBot->bState = BOT_STATE_READ_CBW;
}
else {
TRACE_WARNING("W: BOT_StateMachine: Failed to read CBW\n\r");
pBot->bState = BOT_STATE_READ_CBW;
}
}
break;
//-------------------------
case BOT_STATE_PROCESS_CBW:
//-------------------------
// Check if this is a new command
if (pCommandState->bState == 0) {
// Copy the CBW tag
pCsw->dCSWTag = pCbw->dCBWTag;
// Check that the CBW is 31 bytes long
if ((pTransfer->dBytesTransferred != MSD_CBW_SIZE) ||
(pTransfer->dBytesRemaining != 0)) {
TRACE_WARNING("W: BOT_StateMachine: Invalid CBW (too short or too long)\n\r");
// Wait for a reset recovery
pBot->isWaitResetRecovery = true;
// Halt the Bulk-IN and Bulk-OUT pipes
USB_Halt(pUsb, BOT_EPT_BULK_OUT, USB_SET_FEATURE);
USB_Halt(pUsb, BOT_EPT_BULK_IN, USB_SET_FEATURE);
pCsw->bCSWStatus = MSD_CSW_COMMAND_FAILED;
pBot->bState = BOT_STATE_READ_CBW;
}
// Check the CBW Signature
else if (pCbw->dCBWSignature != MSD_CBW_SIGNATURE) {
TRACE_WARNING("W: MSD_BOTStateMachine: Invalid CBW (Bad signature)\n\r");
// Wait for a reset recovery
pBot->isWaitResetRecovery = true;
// Halt the Bulk-IN and Bulk-OUT pipes
USB_Halt(pUsb, BOT_EPT_BULK_OUT, USB_SET_FEATURE);
USB_Halt(pUsb, BOT_EPT_BULK_IN, USB_SET_FEATURE);
pCsw->bCSWStatus = MSD_CSW_COMMAND_FAILED;
pBot->bState = BOT_STATE_READ_CBW;
}
else {
// Pre-process command
BOT_PreProcessCommand(pBot);
}
}
// Process command
if (pCsw->bCSWStatus == BOT_STATUS_SUCCESS) {
if (BOT_ProcessCommand(pBot)) {
// Post-process command if it is finished
BOT_PostProcessCommand(pBot);
pBot->bState = BOT_STATE_SEND_CSW;
}
TRACE_DEBUG_M("\n\r");
}
break;
//----------------------
case BOT_STATE_SEND_CSW:
//----------------------
// Set signature
pCsw->dCSWSignature = MSD_CSW_SIGNATURE;
// Start the CSW write operation
bStatus = USB_Write(pUsb,
BOT_EPT_BULK_IN,
pCsw,
MSD_CSW_SIZE,
(Callback_f) BOT_Callback,
(void *) pTransfer);
// Check operation result code
if (bStatus == USB_STATUS_SUCCESS) {
TRACE_DEBUG_M("SendCSW ");
// Wait for end of transfer
pBot->bState = BOT_STATE_WAIT_CSW;
}
break;
//----------------------
case BOT_STATE_WAIT_CSW:
//----------------------
// Check transfer semaphore
if (pTransfer->bSemaphore > 0) {
// Take semaphore and terminate transfer
pTransfer->bSemaphore--;
// Check if transfer was successful
if (bStatus == USB_STATUS_RESET) {
TRACE_INFO("I: BOT_StateMachine: Endpoint resetted\n\r");
}
else if (bStatus == USB_STATUS_ABORTED) {
TRACE_WARNING("W: BOT_StateMachine: Failed to send CSW\n\r");
}
else {
TRACE_DEBUG_M("ok");
}
// Read new CBW
pBot->bState = BOT_STATE_READ_CBW;
}
break;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -