Full implementation of Downstream MSC interface, including significant

modifications to USB host MSC.

Also, minor tweaks to Upstream.
pull/7/head
Robert Fisk 9 years ago
parent b9b6123642
commit 0e1fed6047

@ -12,8 +12,20 @@
#include "downstream_spi.h" #include "downstream_spi.h"
#define MSC_SUPPORTED_BLOCK_SIZE 512
#define MSC_FIXED_LUN 0
typedef void (*DownstreamMSCCallbackPacketTypeDef)(HAL_StatusTypeDef result,
DownstreamPacketTypeDef* receivedPacket,
uint16_t dataLength);
HAL_StatusTypeDef Downstream_MSC_ApproveConnectedDevice(void); HAL_StatusTypeDef Downstream_MSC_ApproveConnectedDevice(void);
void Downstream_MSC_PacketProcessor(DownstreamPacketTypeDef* receivedPacket); void Downstream_MSC_PacketProcessor(DownstreamPacketTypeDef* receivedPacket);
HAL_StatusTypeDef Downstream_MSC_PutStreamDataPacket(DownstreamPacketTypeDef* packetToSend,
uint32_t dataLength);
HAL_StatusTypeDef Downstream_MSC_GetStreamDataPacket(DownstreamMSCCallbackPacketTypeDef callback);

@ -26,6 +26,7 @@ typedef enum
void Downstream_InitStateMachine(void); void Downstream_InitStateMachine(void);
void Downstream_HostUserCallback(USBH_HandleTypeDef *phost, uint8_t id); void Downstream_HostUserCallback(USBH_HandleTypeDef *phost, uint8_t id);
void Downstream_PacketProcessor(DownstreamPacketTypeDef* receivedPacket);
void Downstream_PacketProcessor_ErrorReply(DownstreamPacketTypeDef* replyPacket); void Downstream_PacketProcessor_ErrorReply(DownstreamPacketTypeDef* replyPacket);
void Downstream_PacketProcessor_ClassReply(DownstreamPacketTypeDef* replyPacket); void Downstream_PacketProcessor_ClassReply(DownstreamPacketTypeDef* replyPacket);

@ -38,28 +38,9 @@
#include "usbh_msc_bot.h" #include "usbh_msc_bot.h"
#include "usbh_msc_scsi.h" #include "usbh_msc_scsi.h"
/** @addtogroup USBH_LIB
* @{
*/
/** @addtogroup USBH_CLASS
* @{
*/
/** @addtogroup USBH_MSC_CLASS
* @{
*/
/** @defgroup USBH_MSC_CORE
* @brief This file is the Header file for usbh_msc.c
* @{
*/
/** @defgroup USBH_MSC_CORE_Exported_Types
* @{
*/
typedef enum typedef enum
{ {
MSC_INIT = 0, MSC_INIT = 0,
@ -112,25 +93,29 @@ typedef struct
} }
MSC_LUNTypeDef; MSC_LUNTypeDef;
typedef void (*MSC_RdWrCompleteCallback)(USBH_StatusTypeDef result);
/* Structure for MSC process */ /* Structure for MSC process */
typedef struct _MSC_Process typedef struct _MSC_Process
{ {
uint32_t max_lun; uint32_t max_lun;
uint8_t InPipe; uint8_t InPipe;
uint8_t OutPipe; uint8_t OutPipe;
uint8_t OutEp; uint8_t OutEp;
uint8_t InEp; uint8_t InEp;
uint16_t OutEpSize; uint16_t OutEpSize;
uint16_t InEpSize; uint16_t InEpSize;
MSC_StateTypeDef state; MSC_StateTypeDef state;
MSC_ErrorTypeDef error; MSC_ErrorTypeDef error;
MSC_ReqStateTypeDef req_state; MSC_ReqStateTypeDef req_state;
MSC_ReqStateTypeDef prev_req_state; MSC_ReqStateTypeDef prev_req_state;
BOT_HandleTypeDef hbot; BOT_HandleTypeDef hbot;
MSC_LUNTypeDef unit[MAX_SUPPORTED_LUN]; MSC_LUNTypeDef unit[MAX_SUPPORTED_LUN];
uint16_t current_lun; uint16_t current_lun;
uint16_t rw_lun; uint16_t rw_lun;
uint32_t timer; uint32_t timeout;
MSC_RdWrCompleteCallback RdWrCompleteCallback;
} }
MSC_HandleTypeDef; MSC_HandleTypeDef;
@ -147,7 +132,8 @@ MSC_HandleTypeDef;
#define USB_REQ_BOT_RESET 0xFF #define USB_REQ_BOT_RESET 0xFF
#define USB_REQ_GET_MAX_LUN 0xFE #define USB_REQ_GET_MAX_LUN 0xFE
#define MSC_TIMEOUT_FRAMES_PER_BLOCK 1000
/* MSC Class Codes */ /* MSC Class Codes */
#define USB_MSC_CLASS 0x08 #define USB_MSC_CLASS 0x08
@ -193,14 +179,14 @@ USBH_StatusTypeDef USBH_MSC_GetLUNInfo(USBH_HandleTypeDef *phost, uint8_t lun, M
USBH_StatusTypeDef USBH_MSC_Read(USBH_HandleTypeDef *phost, USBH_StatusTypeDef USBH_MSC_Read(USBH_HandleTypeDef *phost,
uint8_t lun, uint8_t lun,
uint32_t address, uint32_t address,
uint8_t *pbuf, uint32_t length,
uint32_t length); MSC_RdWrCompleteCallback callback);
USBH_StatusTypeDef USBH_MSC_Write(USBH_HandleTypeDef *phost, USBH_StatusTypeDef USBH_MSC_Write(USBH_HandleTypeDef *phost,
uint8_t lun, uint8_t lun,
uint32_t address, uint32_t address,
uint8_t *pbuf, uint32_t length,
uint32_t length); MSC_RdWrCompleteCallback callback);
/** /**
* @} * @}
*/ */

@ -36,6 +36,8 @@
/* Includes ------------------------------------------------------------------*/ /* Includes ------------------------------------------------------------------*/
#include "usbh_core.h" #include "usbh_core.h"
#include "usbh_msc_bot.h" #include "usbh_msc_bot.h"
#include "downstream_spi.h"
/** @addtogroup USBH_LIB /** @addtogroup USBH_LIB
* @{ * @{
@ -137,8 +139,11 @@ typedef struct
BOT_CBWTypeDef cbw; BOT_CBWTypeDef cbw;
uint8_t Reserved1; uint8_t Reserved1;
BOT_CSWTypeDef csw; BOT_CSWTypeDef csw;
uint8_t Reserved2[3]; uint8_t Reserved2[3];
uint8_t *pbuf; uint8_t* pbuf;
DownstreamPacketTypeDef* bot_packet;
uint16_t bot_packet_bytes_remaining;
uint16_t this_URB_size;
} }
BOT_HandleTypeDef; BOT_HandleTypeDef;

@ -185,13 +185,11 @@ USBH_StatusTypeDef USBH_MSC_SCSI_RequestSense (USBH_HandleTypeDef *phost,
USBH_StatusTypeDef USBH_MSC_SCSI_Write(USBH_HandleTypeDef *phost, USBH_StatusTypeDef USBH_MSC_SCSI_Write(USBH_HandleTypeDef *phost,
uint8_t lun, uint8_t lun,
uint32_t address, uint32_t address,
uint8_t *pbuf,
uint32_t length); uint32_t length);
USBH_StatusTypeDef USBH_MSC_SCSI_Read(USBH_HandleTypeDef *phost, USBH_StatusTypeDef USBH_MSC_SCSI_Read(USBH_HandleTypeDef *phost,
uint8_t lun, uint8_t lun,
uint32_t address, uint32_t address,
uint8_t *pbuf,
uint32_t length); uint32_t length);

@ -195,6 +195,7 @@ static USBH_StatusTypeDef USBH_MSC_InterfaceInit (USBH_HandleTypeDef *phost)
MSC_Handle->req_state = MSC_REQ_IDLE; MSC_Handle->req_state = MSC_REQ_IDLE;
MSC_Handle->OutPipe = USBH_AllocPipe(phost, MSC_Handle->OutEp); MSC_Handle->OutPipe = USBH_AllocPipe(phost, MSC_Handle->OutEp);
MSC_Handle->InPipe = USBH_AllocPipe(phost, MSC_Handle->InEp); MSC_Handle->InPipe = USBH_AllocPipe(phost, MSC_Handle->InEp);
MSC_Handle->RdWrCompleteCallback = NULL;
USBH_MSC_BOT_Init(phost); USBH_MSC_BOT_Init(phost);
@ -343,7 +344,7 @@ static USBH_StatusTypeDef USBH_MSC_Process(USBH_HandleTypeDef *phost)
case MSC_INIT: case MSC_INIT:
USBH_UsrLog ("LUN #%d: ", MSC_Handle->current_lun); USBH_UsrLog ("LUN #%d: ", MSC_Handle->current_lun);
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_READ_INQUIRY; MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_READ_INQUIRY;
MSC_Handle->timer = phost->Timer; MSC_Handle->timeout = phost->Timer;
case MSC_READ_INQUIRY: case MSC_READ_INQUIRY:
scsi_status = USBH_MSC_SCSI_Inquiry(phost, MSC_Handle->current_lun, &MSC_Handle->unit[MSC_Handle->current_lun].inquiry); scsi_status = USBH_MSC_SCSI_Inquiry(phost, MSC_Handle->current_lun, &MSC_Handle->unit[MSC_Handle->current_lun].inquiry);
@ -443,7 +444,7 @@ static USBH_StatusTypeDef USBH_MSC_Process(USBH_HandleTypeDef *phost)
(MSC_Handle->unit[MSC_Handle->current_lun].sense.key == SCSI_SENSE_KEY_NOT_READY) ) (MSC_Handle->unit[MSC_Handle->current_lun].sense.key == SCSI_SENSE_KEY_NOT_READY) )
{ {
if((phost->Timer - MSC_Handle->timer) > 10000) if((phost->Timer - MSC_Handle->timeout) > 10000)
{ {
MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_TEST_UNIT_READY; MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_TEST_UNIT_READY;
break; break;
@ -492,9 +493,28 @@ static USBH_StatusTypeDef USBH_MSC_Process(USBH_HandleTypeDef *phost)
break; break;
case MSC_IDLE: case MSC_IDLE:
error = USBH_OK; error = USBH_OK;
break; break;
case MSC_READ:
case MSC_WRITE:
error = USBH_MSC_RdWrProcess(phost, MSC_Handle->rw_lun);
if(((int32_t)(phost->Timer - MSC_Handle->timeout) > 0) || (phost->device.is_connected == 0))
{
error = USBH_FAIL;
}
if (error != USBH_BUSY)
{
MSC_Handle->state = MSC_IDLE;
if (MSC_Handle->RdWrCompleteCallback != NULL)
{
MSC_Handle->RdWrCompleteCallback(error);
MSC_Handle->RdWrCompleteCallback = NULL;
}
}
break;
default: default:
break; break;
} }
@ -531,12 +551,12 @@ static USBH_StatusTypeDef USBH_MSC_RdWrProcess(USBH_HandleTypeDef *phost, uint8_
{ {
case MSC_READ: case MSC_READ:
scsi_status = USBH_MSC_SCSI_Read(phost,lun, 0, NULL, 0) ; scsi_status = USBH_MSC_SCSI_Read(phost,lun, 0, 0) ;
if(scsi_status == USBH_OK) if(scsi_status == USBH_OK)
{ {
MSC_Handle->unit[lun].state = MSC_IDLE; MSC_Handle->unit[lun].state = MSC_IDLE;
error = USBH_OK; error = USBH_OK;
} }
else if( scsi_status == USBH_FAIL) else if( scsi_status == USBH_FAIL)
{ {
@ -545,7 +565,7 @@ static USBH_StatusTypeDef USBH_MSC_RdWrProcess(USBH_HandleTypeDef *phost, uint8_
else if(scsi_status == USBH_UNRECOVERED_ERROR) else if(scsi_status == USBH_UNRECOVERED_ERROR)
{ {
MSC_Handle->unit[lun].state = MSC_UNRECOVERED_ERROR; MSC_Handle->unit[lun].state = MSC_UNRECOVERED_ERROR;
error = USBH_FAIL; error = USBH_FAIL;
} }
#if (USBH_USE_OS == 1) #if (USBH_USE_OS == 1)
osMessagePut ( phost->os_event, USBH_CLASS_EVENT, 0); osMessagePut ( phost->os_event, USBH_CLASS_EVENT, 0);
@ -553,7 +573,7 @@ static USBH_StatusTypeDef USBH_MSC_RdWrProcess(USBH_HandleTypeDef *phost, uint8_
break; break;
case MSC_WRITE: case MSC_WRITE:
scsi_status = USBH_MSC_SCSI_Write(phost,lun, 0, NULL, 0) ; scsi_status = USBH_MSC_SCSI_Write(phost,lun, 0, 0) ;
if(scsi_status == USBH_OK) if(scsi_status == USBH_OK)
{ {
@ -567,7 +587,7 @@ static USBH_StatusTypeDef USBH_MSC_RdWrProcess(USBH_HandleTypeDef *phost, uint8_
else if(scsi_status == USBH_UNRECOVERED_ERROR) else if(scsi_status == USBH_UNRECOVERED_ERROR)
{ {
MSC_Handle->unit[lun].state = MSC_UNRECOVERED_ERROR; MSC_Handle->unit[lun].state = MSC_UNRECOVERED_ERROR;
error = USBH_FAIL; error = USBH_FAIL;
} }
#if (USBH_USE_OS == 1) #if (USBH_USE_OS == 1)
osMessagePut ( phost->os_event, USBH_CLASS_EVENT, 0); osMessagePut ( phost->os_event, USBH_CLASS_EVENT, 0);
@ -584,7 +604,6 @@ static USBH_StatusTypeDef USBH_MSC_RdWrProcess(USBH_HandleTypeDef *phost, uint8_
USBH_UsrLog ("Additional Sense Code Qualifier: %x", MSC_Handle->unit[lun].sense.ascq); USBH_UsrLog ("Additional Sense Code Qualifier: %x", MSC_Handle->unit[lun].sense.ascq);
MSC_Handle->unit[lun].state = MSC_IDLE; MSC_Handle->unit[lun].state = MSC_IDLE;
MSC_Handle->unit[lun].error = MSC_ERROR; MSC_Handle->unit[lun].error = MSC_ERROR;
error = USBH_FAIL; error = USBH_FAIL;
} }
if( scsi_status == USBH_FAIL) if( scsi_status == USBH_FAIL)
@ -593,8 +612,8 @@ static USBH_StatusTypeDef USBH_MSC_RdWrProcess(USBH_HandleTypeDef *phost, uint8_
} }
else if(scsi_status == USBH_UNRECOVERED_ERROR) else if(scsi_status == USBH_UNRECOVERED_ERROR)
{ {
MSC_Handle->unit[lun].state = MSC_UNRECOVERED_ERROR; MSC_Handle->unit[lun].state = MSC_UNRECOVERED_ERROR;
error = USBH_FAIL; error = USBH_FAIL;
} }
#if (USBH_USE_OS == 1) #if (USBH_USE_OS == 1)
osMessagePut ( phost->os_event, USBH_CLASS_EVENT, 0); osMessagePut ( phost->os_event, USBH_CLASS_EVENT, 0);
@ -608,6 +627,7 @@ static USBH_StatusTypeDef USBH_MSC_RdWrProcess(USBH_HandleTypeDef *phost, uint8_
return error; return error;
} }
/** /**
* @brief USBH_MSC_IsReady * @brief USBH_MSC_IsReady
* The function check if the MSC function is ready * The function check if the MSC function is ready
@ -700,41 +720,34 @@ USBH_StatusTypeDef USBH_MSC_GetLUNInfo(USBH_HandleTypeDef *phost, uint8_t lun, M
USBH_StatusTypeDef USBH_MSC_Read(USBH_HandleTypeDef *phost, USBH_StatusTypeDef USBH_MSC_Read(USBH_HandleTypeDef *phost,
uint8_t lun, uint8_t lun,
uint32_t address, uint32_t address,
uint8_t *pbuf, uint32_t length,
uint32_t length) MSC_RdWrCompleteCallback callback)
{ {
uint32_t timeout;
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData; MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
if ((phost->device.is_connected == 0) || if ((phost->device.is_connected == 0) ||
(phost->gState != HOST_CLASS) || (phost->gState != HOST_CLASS) ||
(MSC_Handle->state != MSC_IDLE) ||
(MSC_Handle->unit[lun].state != MSC_IDLE)) (MSC_Handle->unit[lun].state != MSC_IDLE))
{ {
return USBH_FAIL; return USBH_FAIL;
} }
MSC_Handle->state = MSC_READ; MSC_Handle->state = MSC_READ;
MSC_Handle->unit[lun].state = MSC_READ; MSC_Handle->unit[lun].state = MSC_READ;
MSC_Handle->rw_lun = lun; MSC_Handle->rw_lun = lun;
MSC_Handle->RdWrCompleteCallback = callback;
MSC_Handle->timeout = phost->Timer + (length * MSC_TIMEOUT_FRAMES_PER_BLOCK);
USBH_MSC_SCSI_Read(phost, USBH_MSC_SCSI_Read(phost,
lun, lun,
address, address,
pbuf,
length); length);
timeout = phost->Timer;
while (USBH_MSC_RdWrProcess(phost, lun) == USBH_BUSY)
{
if(((phost->Timer - timeout) > (10000 * length)) || (phost->device.is_connected == 0))
{
MSC_Handle->state = MSC_IDLE;
return USBH_FAIL;
}
}
MSC_Handle->state = MSC_IDLE;
return USBH_OK; return USBH_OK;
} }
/** /**
* @brief USBH_MSC_Write * @brief USBH_MSC_Write
* The function performs a Write operation * The function performs a Write operation
@ -748,37 +761,29 @@ USBH_StatusTypeDef USBH_MSC_Read(USBH_HandleTypeDef *phost,
USBH_StatusTypeDef USBH_MSC_Write(USBH_HandleTypeDef *phost, USBH_StatusTypeDef USBH_MSC_Write(USBH_HandleTypeDef *phost,
uint8_t lun, uint8_t lun,
uint32_t address, uint32_t address,
uint8_t *pbuf, uint32_t length,
uint32_t length) MSC_RdWrCompleteCallback callback)
{ {
uint32_t timeout;
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData; MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
if ((phost->device.is_connected == 0) || if ((phost->device.is_connected == 0) ||
(phost->gState != HOST_CLASS) || (phost->gState != HOST_CLASS) ||
(MSC_Handle->state != MSC_IDLE) ||
(MSC_Handle->unit[lun].state != MSC_IDLE)) (MSC_Handle->unit[lun].state != MSC_IDLE))
{ {
return USBH_FAIL; return USBH_FAIL;
} }
MSC_Handle->state = MSC_WRITE; MSC_Handle->state = MSC_WRITE;
MSC_Handle->unit[lun].state = MSC_WRITE; MSC_Handle->unit[lun].state = MSC_WRITE;
MSC_Handle->rw_lun = lun; MSC_Handle->rw_lun = lun;
MSC_Handle->RdWrCompleteCallback = callback;
MSC_Handle->timeout = phost->Timer + (length * MSC_TIMEOUT_FRAMES_PER_BLOCK);
USBH_MSC_SCSI_Write(phost, USBH_MSC_SCSI_Write(phost,
lun, lun,
address, address,
pbuf,
length); length);
timeout = phost->Timer;
while (USBH_MSC_RdWrProcess(phost, lun) == USBH_BUSY)
{
if(((phost->Timer - timeout) > (10000 * length)) || (phost->device.is_connected == 0))
{
MSC_Handle->state = MSC_IDLE;
return USBH_FAIL;
}
}
MSC_Handle->state = MSC_IDLE;
return USBH_OK; return USBH_OK;
} }

@ -28,77 +28,23 @@
/* Includes ------------------------------------------------------------------*/ /* Includes ------------------------------------------------------------------*/
#include "usbh_msc_bot.h" #include "usbh_msc_bot.h"
#include "usbh_msc.h" #include "usbh_msc.h"
#include "downstream_spi.h"
/** @addtogroup USBH_LIB #include "downstream_msc.h"
* @{
*/
/** @addtogroup USBH_CLASS
* @{
*/
/** @addtogroup USBH_MSC_CLASS
* @{
*/
/** @defgroup USBH_MSC_BOT
* @brief This file includes the mass storage related functions
* @{
*/
/** @defgroup USBH_MSC_BOT_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MSC_BOT_Private_Defines
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MSC_BOT_Private_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MSC_BOT_Private_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBH_MSC_BOT_Private_FunctionPrototypes
* @{
*/
static USBH_StatusTypeDef USBH_MSC_BOT_Abort(USBH_HandleTypeDef *phost, uint8_t lun, uint8_t dir); static USBH_StatusTypeDef USBH_MSC_BOT_Abort(USBH_HandleTypeDef *phost, uint8_t lun, uint8_t dir);
static BOT_CSWStatusTypeDef USBH_MSC_DecodeCSW(USBH_HandleTypeDef *phost); static BOT_CSWStatusTypeDef USBH_MSC_DecodeCSW(USBH_HandleTypeDef *phost);
/** void USBH_MSC_BOT_Read_FreePacketCallback(DownstreamPacketTypeDef* freePacket);
* @} void USBH_MSC_BOT_Read_PrepareURB(USBH_HandleTypeDef *phost);
*/ void USBH_MSC_BOT_Write_ReceivePacketCallback(HAL_StatusTypeDef result,
DownstreamPacketTypeDef* receivedPacket,
uint16_t dataLength);
void USBH_MSC_BOT_Write_PrepareURB(USBH_HandleTypeDef *phost);
/** @defgroup USBH_MSC_BOT_Exported_Variables
* @{
*/
/**
* @}
*/
USBH_HandleTypeDef *Callback_MSC_phost;
/** @defgroup USBH_MSC_BOT_Private_Functions
* @{
*/
/** /**
* @brief USBH_MSC_BOT_REQ_Reset * @brief USBH_MSC_BOT_REQ_Reset
@ -189,7 +135,6 @@ USBH_StatusTypeDef USBH_MSC_BOT_Process (USBH_HandleTypeDef *phost, uint8_t lun)
BOT_CBW_LENGTH, BOT_CBW_LENGTH,
MSC_Handle->OutPipe, MSC_Handle->OutPipe,
1); 1);
break; break;
case BOT_SEND_CBW_WAIT: case BOT_SEND_CBW_WAIT:
@ -217,75 +162,68 @@ USBH_StatusTypeDef USBH_MSC_BOT_Process (USBH_HandleTypeDef *phost, uint8_t lun)
{/* If there is NO Data Transfer Stage */ {/* If there is NO Data Transfer Stage */
MSC_Handle->hbot.state = BOT_RECEIVE_CSW; MSC_Handle->hbot.state = BOT_RECEIVE_CSW;
} }
#if (USBH_USE_OS == 1)
osMessagePut ( phost->os_event, USBH_URB_EVENT, 0);
#endif
} }
else if(URB_Status == USBH_URB_NOTREADY) else if(URB_Status == USBH_URB_NOTREADY)
{ {
/* Re-send CBW */ /* Re-send CBW */
MSC_Handle->hbot.state = BOT_SEND_CBW; MSC_Handle->hbot.state = BOT_SEND_CBW;
#if (USBH_USE_OS == 1)
osMessagePut ( phost->os_event, USBH_URB_EVENT, 0);
#endif
} }
else if(URB_Status == USBH_URB_STALL) else if(URB_Status == USBH_URB_STALL)
{ {
MSC_Handle->hbot.state = BOT_ERROR_OUT; MSC_Handle->hbot.state = BOT_ERROR_OUT;
#if (USBH_USE_OS == 1)
osMessagePut ( phost->os_event, USBH_URB_EVENT, 0);
#endif
} }
break; break;
case BOT_DATA_IN: case BOT_DATA_IN:
/* Get first packet */ /* Get first packet */
USBH_BulkReceiveData (phost, Callback_MSC_phost = phost;
MSC_Handle->hbot.pbuf, Downstream_GetFreePacket(USBH_MSC_BOT_Read_FreePacketCallback);
MSC_Handle->InEpSize , //Todo: Possible buffer overflow here? MSC_Handle->hbot.state = BOT_DATA_IN_WAIT;
MSC_Handle->InPipe); break;
MSC_Handle->hbot.state = BOT_DATA_IN_WAIT;
break;
case BOT_DATA_IN_WAIT: case BOT_DATA_IN_WAIT:
URB_Status = USBH_LL_GetURBState(phost, MSC_Handle->InPipe); URB_Status = USBH_LL_GetURBState(phost, MSC_Handle->InPipe);
if(URB_Status == USBH_URB_DONE) if (URB_Status == USBH_URB_DONE)
{ {
/* Adjust Data pointer and data length */ MSC_Handle->hbot.cbw.field.DataTransferLength -= MSC_Handle->hbot.this_URB_size;
if(MSC_Handle->hbot.cbw.field.DataTransferLength > MSC_Handle->InEpSize) MSC_Handle->hbot.bot_packet_bytes_remaining -= MSC_Handle->hbot.this_URB_size;
{
MSC_Handle->hbot.pbuf += MSC_Handle->InEpSize; if (MSC_Handle->hbot.cbw.field.DataTransferLength == 0)
MSC_Handle->hbot.cbw.field.DataTransferLength -= MSC_Handle->InEpSize; {
} //End of reception: dispatch last packet
else MSC_Handle->hbot.state = BOT_RECEIVE_CSW;
{ Downstream_MSC_PutStreamDataPacket(MSC_Handle->hbot.bot_packet,
MSC_Handle->hbot.cbw.field.DataTransferLength = 0; (BOT_PAGE_LENGTH - MSC_Handle->hbot.bot_packet_bytes_remaining));
} }
else
/* More Data To be Received */ {
if(MSC_Handle->hbot.cbw.field.DataTransferLength > 0) //Still more data to receive
{ if (MSC_Handle->hbot.bot_packet_bytes_remaining == 0)
/* Get next packet */ {
USBH_BulkReceiveData (phost, //Dispatch current bot_packet, then get a new one
MSC_Handle->hbot.pbuf, if (Downstream_MSC_PutStreamDataPacket(MSC_Handle->hbot.bot_packet,
MSC_Handle->InEpSize , //Todo: Possible buffer overflow here? (BOT_PAGE_LENGTH - MSC_Handle->hbot.bot_packet_bytes_remaining)) != HAL_OK)
MSC_Handle->InPipe); {
MSC_Handle->hbot.state = BOT_ERROR_IN;
} break;
else }
{ if (Downstream_GetFreePacket(USBH_MSC_BOT_Read_FreePacketCallback) != HAL_OK)
/* If value was 0, and successful transfer, then change the state */ {
MSC_Handle->hbot.state = BOT_RECEIVE_CSW; MSC_Handle->hbot.state = BOT_ERROR_IN;
#if (USBH_USE_OS == 1) break;
osMessagePut ( phost->os_event, USBH_URB_EVENT, 0); }
#endif }
} else
{
//Continue filling the current bot_packet
MSC_Handle->hbot.pbuf += MSC_Handle->hbot.this_URB_size;
USBH_MSC_BOT_Read_PrepareURB(phost);
}
}
} }
else if(URB_Status == USBH_URB_STALL) else if(URB_Status == USBH_URB_STALL)
{ {
/* This is Data IN Stage STALL Condition */ /* This is Data IN Stage STALL Condition */
@ -297,67 +235,56 @@ USBH_StatusTypeDef USBH_MSC_BOT_Process (USBH_HandleTypeDef *phost, uint8_t lun)
The host shall accept the data received. The host shall accept the data received.
The host shall clear the Bulk-In pipe. The host shall clear the Bulk-In pipe.
4. The host shall attempt to receive a CSW.*/ 4. The host shall attempt to receive a CSW.*/
#if (USBH_USE_OS == 1)
osMessagePut ( phost->os_event, USBH_URB_EVENT, 0);
#endif
} }
break; break;
case BOT_DATA_OUT: case BOT_DATA_OUT:
Callback_MSC_phost = phost;
USBH_BulkSendData (phost, MSC_Handle->hbot.state = BOT_DATA_OUT_WAIT;
MSC_Handle->hbot.pbuf, if (Downstream_MSC_GetStreamDataPacket(USBH_MSC_BOT_Write_ReceivePacketCallback) != HAL_OK)
MSC_Handle->OutEpSize , //?????????? {
MSC_Handle->OutPipe, MSC_Handle->hbot.state = BOT_ERROR_OUT;
1); }
break;
MSC_Handle->hbot.state = BOT_DATA_OUT_WAIT;
break;
case BOT_DATA_OUT_WAIT: case BOT_DATA_OUT_WAIT:
URB_Status = USBH_LL_GetURBState(phost, MSC_Handle->OutPipe); URB_Status = USBH_LL_GetURBState(phost, MSC_Handle->OutPipe);
if(URB_Status == USBH_URB_DONE) if(URB_Status == USBH_URB_DONE)
{ {
/* Adjust Data pointer and data length */ MSC_Handle->hbot.cbw.field.DataTransferLength -= MSC_Handle->hbot.this_URB_size;
if(MSC_Handle->hbot.cbw.field.DataTransferLength > MSC_Handle->OutEpSize) MSC_Handle->hbot.bot_packet_bytes_remaining -= MSC_Handle->hbot.this_URB_size;
{
MSC_Handle->hbot.pbuf += MSC_Handle->OutEpSize; if (MSC_Handle->hbot.cbw.field.DataTransferLength == 0)
MSC_Handle->hbot.cbw.field.DataTransferLength -= MSC_Handle->OutEpSize; {
} //End of reception
else MSC_Handle->hbot.state = BOT_RECEIVE_CSW;
{ }
MSC_Handle->hbot.cbw.field.DataTransferLength = 0; else
} {
//Still more data to receive
/* More Data To be Sent */ if (MSC_Handle->hbot.bot_packet_bytes_remaining == 0)
if(MSC_Handle->hbot.cbw.field.DataTransferLength > 0) {
{ //Get next bot_packet
USBH_BulkSendData (phost, if (Downstream_MSC_GetStreamDataPacket(USBH_MSC_BOT_Write_ReceivePacketCallback) != HAL_OK)
MSC_Handle->hbot.pbuf, {
MSC_Handle->OutEpSize , //????????????? MSC_Handle->hbot.state = BOT_ERROR_IN;
MSC_Handle->OutPipe, break;
1); }
} }
else else
{ {
/* If value was 0, and successful transfer, then change the state */ //Continue reading the current bot_packet
MSC_Handle->hbot.state = BOT_RECEIVE_CSW; MSC_Handle->hbot.pbuf += MSC_Handle->hbot.this_URB_size;
} USBH_MSC_BOT_Write_PrepareURB(phost);
#if (USBH_USE_OS == 1) }
osMessagePut ( phost->os_event, USBH_URB_EVENT, 0); }
#endif
} }
else if(URB_Status == USBH_URB_NOTREADY) else if(URB_Status == USBH_URB_NOTREADY)
{ {
/* Resend same data */ /* Resend same data */
MSC_Handle->hbot.state = BOT_DATA_OUT; MSC_Handle->hbot.state = BOT_DATA_OUT;
#if (USBH_USE_OS == 1)
osMessagePut ( phost->os_event, USBH_URB_EVENT, 0);
#endif
} }
else if(URB_Status == USBH_URB_STALL) else if(URB_Status == USBH_URB_STALL)
@ -369,10 +296,7 @@ USBH_StatusTypeDef USBH_MSC_BOT_Process (USBH_HandleTypeDef *phost, uint8_t lun)
3. On a STALL condition sending data, then: 3. On a STALL condition sending data, then:
" The host shall clear the Bulk-Out pipe. " The host shall clear the Bulk-Out pipe.
4. The host shall attempt to receive a CSW. 4. The host shall attempt to receive a CSW.
*/ */
#if (USBH_USE_OS == 1)
osMessagePut ( phost->os_event, USBH_URB_EVENT, 0);
#endif
} }
break; break;
@ -405,16 +329,10 @@ USBH_StatusTypeDef USBH_MSC_BOT_Process (USBH_HandleTypeDef *phost, uint8_t lun)
{ {
status = USBH_FAIL; status = USBH_FAIL;
} }
#if (USBH_USE_OS == 1)
osMessagePut ( phost->os_event, USBH_URB_EVENT, 0);
#endif
} }
else if(URB_Status == USBH_URB_STALL) else if(URB_Status == USBH_URB_STALL)
{ {
MSC_Handle->hbot.state = BOT_ERROR_IN; MSC_Handle->hbot.state = BOT_ERROR_IN;
#if (USBH_USE_OS == 1)
osMessagePut ( phost->os_event, USBH_URB_EVENT, 0);
#endif
} }
break; break;
@ -464,6 +382,79 @@ USBH_StatusTypeDef USBH_MSC_BOT_Process (USBH_HandleTypeDef *phost, uint8_t lun)
return status; return status;
} }
void USBH_MSC_BOT_Read_FreePacketCallback(DownstreamPacketTypeDef* freePacket)
{
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) Callback_MSC_phost->pActiveClass->pData;
MSC_Handle->hbot.bot_packet = freePacket;
MSC_Handle->hbot.pbuf = freePacket->Data;
MSC_Handle->hbot.bot_packet_bytes_remaining = BOT_PAGE_LENGTH;
USBH_MSC_BOT_Read_PrepareURB(Callback_MSC_phost);
}
void USBH_MSC_BOT_Read_PrepareURB(USBH_HandleTypeDef *phost)
{
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
MSC_Handle->hbot.this_URB_size = MSC_Handle->hbot.cbw.field.DataTransferLength;
if (MSC_Handle->hbot.this_URB_size > MSC_Handle->hbot.bot_packet_bytes_remaining)
{
MSC_Handle->hbot.this_URB_size = MSC_Handle->hbot.bot_packet_bytes_remaining;
}
if (MSC_Handle->hbot.this_URB_size > MSC_Handle->InEpSize)
{
MSC_Handle->hbot.this_URB_size = MSC_Handle->InEpSize;
}
USBH_BulkReceiveData(phost,
MSC_Handle->hbot.pbuf,
MSC_Handle->hbot.this_URB_size,
MSC_Handle->InPipe);
}
void USBH_MSC_BOT_Write_ReceivePacketCallback(HAL_StatusTypeDef result,
DownstreamPacketTypeDef* receivedPacket,
uint16_t dataLength)
{
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) Callback_MSC_phost->pActiveClass->pData;
if (result != HAL_OK)
{
MSC_Handle->hbot.state = BOT_ERROR_OUT;
return;
}
MSC_Handle->hbot.bot_packet = receivedPacket;
MSC_Handle->hbot.pbuf = receivedPacket->Data;
MSC_Handle->hbot.bot_packet_bytes_remaining = dataLength;
USBH_MSC_BOT_Write_PrepareURB(Callback_MSC_phost);
}
void USBH_MSC_BOT_Write_PrepareURB(USBH_HandleTypeDef *phost)
{
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
MSC_Handle->hbot.this_URB_size = MSC_Handle->hbot.cbw.field.DataTransferLength;
if (MSC_Handle->hbot.this_URB_size > MSC_Handle->hbot.bot_packet_bytes_remaining)
{
MSC_Handle->hbot.this_URB_size = MSC_Handle->hbot.bot_packet_bytes_remaining;
}
if (MSC_Handle->hbot.this_URB_size > MSC_Handle->OutEpSize)
{
MSC_Handle->hbot.this_URB_size = MSC_Handle->OutEpSize;
}
USBH_BulkSendData (phost,
MSC_Handle->hbot.pbuf,
MSC_Handle->hbot.this_URB_size,
MSC_Handle->OutPipe,
1);
}
/** /**
* @brief USBH_MSC_BOT_Abort * @brief USBH_MSC_BOT_Abort
* The function handle the BOT Abort process. * The function handle the BOT Abort process.

@ -292,10 +292,9 @@ USBH_StatusTypeDef USBH_MSC_SCSI_RequestSense (USBH_HandleTypeDef *phost,
break; break;
case BOT_CMD_WAIT: case BOT_CMD_WAIT:
error = USBH_MSC_BOT_Process(phost, lun); error = USBH_MSC_BOT_Process(phost, lun);
if (error == USBH_OK)
if(error == USBH_OK)
{ {
sense_data->key = MSC_Handle->hbot.pbuf[2] & 0x0F; sense_data->key = MSC_Handle->hbot.pbuf[2] & 0x0F;
sense_data->asc = MSC_Handle->hbot.pbuf[12]; sense_data->asc = MSC_Handle->hbot.pbuf[12];
@ -323,7 +322,6 @@ USBH_StatusTypeDef USBH_MSC_SCSI_RequestSense (USBH_HandleTypeDef *phost,
USBH_StatusTypeDef USBH_MSC_SCSI_Write(USBH_HandleTypeDef *phost, USBH_StatusTypeDef USBH_MSC_SCSI_Write(USBH_HandleTypeDef *phost,
uint8_t lun, uint8_t lun,
uint32_t address, uint32_t address,
uint8_t *pbuf,
uint32_t length) uint32_t length)
{ {
USBH_StatusTypeDef error = USBH_FAIL ; USBH_StatusTypeDef error = USBH_FAIL ;
@ -335,7 +333,7 @@ USBH_StatusTypeDef USBH_MSC_SCSI_Write(USBH_HandleTypeDef *phost,
case BOT_CMD_SEND: case BOT_CMD_SEND:
/*Prepare the CBW and relevent field*/ /*Prepare the CBW and relevent field*/
MSC_Handle->hbot.cbw.field.DataTransferLength = length * 512; MSC_Handle->hbot.cbw.field.DataTransferLength = length * MSC_Handle->unit[lun].capacity.block_size;
MSC_Handle->hbot.cbw.field.Flags = USB_EP_DIR_OUT; MSC_Handle->hbot.cbw.field.Flags = USB_EP_DIR_OUT;
MSC_Handle->hbot.cbw.field.CBLength = CBW_LENGTH; MSC_Handle->hbot.cbw.field.CBLength = CBW_LENGTH;
@ -348,15 +346,12 @@ USBH_StatusTypeDef USBH_MSC_SCSI_Write(USBH_HandleTypeDef *phost,
MSC_Handle->hbot.cbw.field.CB[4] = (((uint8_t*)&address)[1]); MSC_Handle->hbot.cbw.field.CB[4] = (((uint8_t*)&address)[1]);
MSC_Handle->hbot.cbw.field.CB[5] = (((uint8_t*)&address)[0]); MSC_Handle->hbot.cbw.field.CB[5] = (((uint8_t*)&address)[0]);
/*Transfer length */ /*Transfer length */
MSC_Handle->hbot.cbw.field.CB[7] = (((uint8_t *)&length)[1]) ; MSC_Handle->hbot.cbw.field.CB[7] = (((uint8_t *)&length)[1]) ;
MSC_Handle->hbot.cbw.field.CB[8] = (((uint8_t *)&length)[0]) ; MSC_Handle->hbot.cbw.field.CB[8] = (((uint8_t *)&length)[0]) ;
MSC_Handle->hbot.state = BOT_SEND_CBW; MSC_Handle->hbot.state = BOT_SEND_CBW;
MSC_Handle->hbot.cmd_state = BOT_CMD_WAIT; MSC_Handle->hbot.cmd_state = BOT_CMD_WAIT;
MSC_Handle->hbot.pbuf = pbuf;
error = USBH_BUSY; error = USBH_BUSY;
break; break;
@ -384,7 +379,6 @@ USBH_StatusTypeDef USBH_MSC_SCSI_Write(USBH_HandleTypeDef *phost,
USBH_StatusTypeDef USBH_MSC_SCSI_Read(USBH_HandleTypeDef *phost, USBH_StatusTypeDef USBH_MSC_SCSI_Read(USBH_HandleTypeDef *phost,
uint8_t lun, uint8_t lun,
uint32_t address, uint32_t address,
uint8_t *pbuf,
uint32_t length) uint32_t length)
{ {
USBH_StatusTypeDef error = USBH_FAIL ; USBH_StatusTypeDef error = USBH_FAIL ;
@ -395,7 +389,7 @@ USBH_StatusTypeDef USBH_MSC_SCSI_Read(USBH_HandleTypeDef *phost,
case BOT_CMD_SEND: case BOT_CMD_SEND:
/*Prepare the CBW and relevent field*/ /*Prepare the CBW and relevent field*/
MSC_Handle->hbot.cbw.field.DataTransferLength = length * 512; MSC_Handle->hbot.cbw.field.DataTransferLength = length * MSC_Handle->unit[lun].capacity.block_size;;
MSC_Handle->hbot.cbw.field.Flags = USB_EP_DIR_IN; MSC_Handle->hbot.cbw.field.Flags = USB_EP_DIR_IN;
MSC_Handle->hbot.cbw.field.CBLength = CBW_LENGTH; MSC_Handle->hbot.cbw.field.CBLength = CBW_LENGTH;
@ -408,15 +402,12 @@ USBH_StatusTypeDef USBH_MSC_SCSI_Read(USBH_HandleTypeDef *phost,
MSC_Handle->hbot.cbw.field.CB[4] = (((uint8_t*)&address)[1]); MSC_Handle->hbot.cbw.field.CB[4] = (((uint8_t*)&address)[1]);
MSC_Handle->hbot.cbw.field.CB[5] = (((uint8_t*)&address)[0]); MSC_Handle->hbot.cbw.field.CB[5] = (((uint8_t*)&address)[0]);
/*Transfer length */ /*Transfer length */
MSC_Handle->hbot.cbw.field.CB[7] = (((uint8_t *)&length)[1]) ; MSC_Handle->hbot.cbw.field.CB[7] = (((uint8_t *)&length)[1]) ;
MSC_Handle->hbot.cbw.field.CB[8] = (((uint8_t *)&length)[0]) ; MSC_Handle->hbot.cbw.field.CB[8] = (((uint8_t *)&length)[0]) ;
MSC_Handle->hbot.state = BOT_SEND_CBW; MSC_Handle->hbot.state = BOT_SEND_CBW;
MSC_Handle->hbot.cmd_state = BOT_CMD_WAIT; MSC_Handle->hbot.cmd_state = BOT_CMD_WAIT;
MSC_Handle->hbot.pbuf = pbuf;
error = USBH_BUSY; error = USBH_BUSY;
break; break;

@ -9,16 +9,26 @@
#include "downstream_msc.h" #include "downstream_msc.h"
#include "downstream_interface_def.h" #include "downstream_interface_def.h"
#include "downstream_statemachine.h" #include "downstream_statemachine.h"
#include "downstream_spi.h"
#include "usbh_msc.h" #include "usbh_msc.h"
extern USBH_HandleTypeDef hUsbHostFS; //Hard-link ourselves to usb_host.c extern USBH_HandleTypeDef hUsbHostFS; //Hard-link ourselves to usb_host.c
//Stuff we need to save for our callbacks to use:
DownstreamMSCCallbackPacketTypeDef GetStreamDataCallback;
uint32_t ByteCount;
DownstreamPacketTypeDef* ReadStreamPacket;
uint8_t ReadStreamBusy;
void Downstream_MSC_PacketProcessor_TestUnitReady(DownstreamPacketTypeDef* receivedPacket); void Downstream_MSC_PacketProcessor_TestUnitReady(DownstreamPacketTypeDef* receivedPacket);
void Downstream_MSC_PacketProcessor_GetCapacity(DownstreamPacketTypeDef* receivedPacket); void Downstream_MSC_PacketProcessor_GetCapacity(DownstreamPacketTypeDef* receivedPacket);
void Downstream_MSC_PacketProcessor_BeginRead(DownstreamPacketTypeDef* receivedPacket); void Downstream_MSC_PacketProcessor_BeginRead(DownstreamPacketTypeDef* receivedPacket);
void Downstream_MSC_PacketProcessor_BeginWrite(DownstreamPacketTypeDef* receivedPacket);
void Downstream_MSC_PacketProcessor_RdWrCompleteCallback(USBH_StatusTypeDef result);
void Downstream_MSC_GetStreamDataPacketCallback(DownstreamPacketTypeDef* replyPacket);
//High-level checks on the connected device. We don't want some weirdly //High-level checks on the connected device. We don't want some weirdly
@ -27,14 +37,16 @@ HAL_StatusTypeDef Downstream_MSC_ApproveConnectedDevice(void)
{ {
MSC_HandleTypeDef* MSC_Handle = (MSC_HandleTypeDef*)hUsbHostFS.pActiveClass->pData; MSC_HandleTypeDef* MSC_Handle = (MSC_HandleTypeDef*)hUsbHostFS.pActiveClass->pData;
if ((MSC_Handle->unit[0].capacity.block_nbr == 0) || if ((MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr == 0) ||
(MSC_Handle->unit[0].capacity.block_nbr == UINT32_MAX)) (MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr == UINT32_MAX))
{ {
//FreakOut?????
return HAL_ERROR; return HAL_ERROR;
} }
if (MSC_Handle->unit[0].capacity.block_size != 512) if (MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_size != MSC_SUPPORTED_BLOCK_SIZE)
{ {
//FreakOut?????
return HAL_ERROR; return HAL_ERROR;
} }
@ -58,7 +70,12 @@ void Downstream_MSC_PacketProcessor(DownstreamPacketTypeDef* receivedPacket)
Downstream_MSC_PacketProcessor_BeginRead(receivedPacket); Downstream_MSC_PacketProcessor_BeginRead(receivedPacket);
break; break;
case COMMAND_MSC_BEGIN_WRITE:
Downstream_MSC_PacketProcessor_BeginWrite(receivedPacket);
break;
default: default:
//FreakOut?????
Downstream_PacketProcessor_ErrorReply(receivedPacket); Downstream_PacketProcessor_ErrorReply(receivedPacket);
} }
@ -67,7 +84,7 @@ void Downstream_MSC_PacketProcessor(DownstreamPacketTypeDef* receivedPacket)
void Downstream_MSC_PacketProcessor_TestUnitReady(DownstreamPacketTypeDef* receivedPacket) void Downstream_MSC_PacketProcessor_TestUnitReady(DownstreamPacketTypeDef* receivedPacket)
{ {
if (USBH_MSC_UnitIsReady(&hUsbHostFS, 0)) if (USBH_MSC_UnitIsReady(&hUsbHostFS, MSC_FIXED_LUN))
{ {
receivedPacket->Data[0] = HAL_OK; receivedPacket->Data[0] = HAL_OK;
} }
@ -85,8 +102,8 @@ void Downstream_MSC_PacketProcessor_GetCapacity(DownstreamPacketTypeDef* receive
MSC_HandleTypeDef* MSC_Handle = (MSC_HandleTypeDef*)hUsbHostFS.pActiveClass->pData; MSC_HandleTypeDef* MSC_Handle = (MSC_HandleTypeDef*)hUsbHostFS.pActiveClass->pData;
receivedPacket->Length = DOWNSTREAM_PACKET_HEADER_LEN + 8; receivedPacket->Length = DOWNSTREAM_PACKET_HEADER_LEN + 8;
*(uint32_t*)&(receivedPacket->Data[0]) = MSC_Handle->unit[0].capacity.block_nbr; *(uint32_t*)&(receivedPacket->Data[0]) = MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr;
*(uint32_t*)&(receivedPacket->Data[4]) = (uint32_t)MSC_Handle->unit[0].capacity.block_size; *(uint32_t*)&(receivedPacket->Data[4]) = (uint32_t)MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_size;
Downstream_PacketProcessor_ClassReply(receivedPacket); Downstream_PacketProcessor_ClassReply(receivedPacket);
} }
@ -94,39 +111,167 @@ void Downstream_MSC_PacketProcessor_GetCapacity(DownstreamPacketTypeDef* receive
void Downstream_MSC_PacketProcessor_BeginRead(DownstreamPacketTypeDef* receivedPacket) void Downstream_MSC_PacketProcessor_BeginRead(DownstreamPacketTypeDef* receivedPacket)
{ {
uint64_t address; uint64_t readBlockAddress;
uint32_t count; uint32_t readBlockCount;
uint64_t readByteCount;
MSC_HandleTypeDef* MSC_Handle = (MSC_HandleTypeDef*)hUsbHostFS.pActiveClass->pData; MSC_HandleTypeDef* MSC_Handle = (MSC_HandleTypeDef*)hUsbHostFS.pActiveClass->pData;
if (receivedPacket->Length != (DOWNSTREAM_PACKET_HEADER_LEN + (4 * 3))) if (receivedPacket->Length != (DOWNSTREAM_PACKET_HEADER_LEN + (4 * 3)))
{ {
//FreakOut?????
Downstream_PacketProcessor_ErrorReply(receivedPacket); Downstream_PacketProcessor_ErrorReply(receivedPacket);
return; return;
} }
address = *(uint64_t*)&(receivedPacket->Data[0]); readBlockAddress = *(uint64_t*)&(receivedPacket->Data[0]);
count = *(uint32_t*)&(receivedPacket->Data[8]); readBlockCount = *(uint32_t*)&(receivedPacket->Data[8]);
if ((address >= (uint64_t)MSC_Handle->unit[0].capacity.block_nbr) || readByteCount = readBlockCount * MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_size;
((address + count - 1) >= (uint64_t)MSC_Handle->unit[0].capacity.block_nbr)) if ((readBlockAddress >= (uint64_t)MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr) ||
((readBlockAddress + readBlockCount - 1) >= (uint64_t)MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr) ||
(readByteCount > UINT32_MAX))
{ {
//FreakOut?????
Downstream_PacketProcessor_ErrorReply(receivedPacket); Downstream_PacketProcessor_ErrorReply(receivedPacket);
return; return;
} }
if (USBH_MSC_UnitIsReady(&hUsbHostFS, 0)) receivedPacket->Data[0] = HAL_ERROR;
receivedPacket->Length = DOWNSTREAM_PACKET_HEADER_LEN + 1;
if (USBH_MSC_UnitIsReady(&hUsbHostFS, MSC_FIXED_LUN))
{ {
receivedPacket->Data[0] = HAL_OK; if (USBH_MSC_Read(&hUsbHostFS,
MSC_FIXED_LUN,
(uint32_t)readBlockAddress,
readBlockCount,
Downstream_MSC_PacketProcessor_RdWrCompleteCallback) == USBH_OK)
{
receivedPacket->Data[0] = HAL_OK;
}
} }
else Downstream_TransmitPacket(receivedPacket);
}
void Downstream_MSC_PacketProcessor_RdWrCompleteCallback(USBH_StatusTypeDef result)
{
if (result != USBH_OK)
{ {
receivedPacket->Data[0] = HAL_ERROR; Downstream_GetFreePacket(Downstream_PacketProcessor_ErrorReply);
return;
}
Downstream_ReceivePacket(Downstream_PacketProcessor);
}
void Downstream_MSC_PacketProcessor_BeginWrite(DownstreamPacketTypeDef* receivedPacket)
{
uint64_t writeBlockAddress;
uint32_t writeBlockCount;
uint64_t writeByteCount;
MSC_HandleTypeDef* MSC_Handle = (MSC_HandleTypeDef*)hUsbHostFS.pActiveClass->pData;
if (receivedPacket->Length != (DOWNSTREAM_PACKET_HEADER_LEN + (4 * 3)))
{
//FreakOut?????
Downstream_PacketProcessor_ErrorReply(receivedPacket);
return;
}
writeBlockAddress = *(uint64_t*)&(receivedPacket->Data[0]);
writeBlockCount = *(uint32_t*)&(receivedPacket->Data[8]);
writeByteCount = writeBlockCount * MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_size;
if ((writeBlockAddress >= (uint64_t)MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr) ||
((writeBlockAddress + writeBlockCount - 1) >= (uint64_t)MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr) ||
(writeByteCount > UINT32_MAX))
{
//FreakOut?????
Downstream_PacketProcessor_ErrorReply(receivedPacket);
return;
} }
ReadStreamPacket = NULL; //Prepare for GetStreamDataPacket's use
ReadStreamBusy = 0;
ByteCount = (uint32_t)writeByteCount;
receivedPacket->Data[0] = HAL_ERROR;
receivedPacket->Length = DOWNSTREAM_PACKET_HEADER_LEN + 1; receivedPacket->Length = DOWNSTREAM_PACKET_HEADER_LEN + 1;
//Our host stack has no way to detect if write-protection is enabled.
//So currently we can't return HAL_BUSY to Upstream in this situation.
if (USBH_MSC_UnitIsReady(&hUsbHostFS, MSC_FIXED_LUN))
{
if (USBH_MSC_Write(&hUsbHostFS,
MSC_FIXED_LUN,
(uint32_t)writeBlockAddress,
writeBlockCount,
Downstream_MSC_PacketProcessor_RdWrCompleteCallback) == USBH_OK)
{
receivedPacket->Data[0] = HAL_OK;
}
}
Downstream_TransmitPacket(receivedPacket); Downstream_TransmitPacket(receivedPacket);
}
HAL_StatusTypeDef Downstream_MSC_PutStreamDataPacket(DownstreamPacketTypeDef* packetToSend,
uint32_t dataLength)
{
packetToSend->Length = dataLength + DOWNSTREAM_PACKET_HEADER_LEN;
packetToSend->CommandClass = COMMAND_CLASS_MASS_STORAGE | COMMAND_CLASS_DATA_FLAG;
packetToSend->Command = COMMAND_MSC_BEGIN_WRITE;
return Downstream_TransmitPacket(packetToSend);
}
HAL_StatusTypeDef Downstream_MSC_GetStreamDataPacket(DownstreamMSCCallbackPacketTypeDef callback)
{
GetStreamDataCallback = callback;
if (ReadStreamBusy != 0)
{
return HAL_OK;
}
ReadStreamBusy = 1;
if (ReadStreamPacket && GetStreamDataCallback) //Do we have a stored packet and an address to send it?
{
Downstream_MSC_GetStreamDataPacketCallback(ReadStreamPacket); //Send it now!
ReadStreamPacket = NULL;
return HAL_OK; //Our callback will call us again, so we don't need to get a packet in this case.
}
return Downstream_ReceivePacket(Downstream_MSC_GetStreamDataPacketCallback);
}
void Downstream_MSC_GetStreamDataPacketCallback(DownstreamPacketTypeDef* replyPacket)
{
uint16_t dataLength;
ReadStreamBusy = 0;
if (GetStreamDataCallback == NULL)
{
ReadStreamPacket = replyPacket; //We used up our callback already, so save this one for later.
return;
}
if (((replyPacket->CommandClass & COMMAND_CLASS_DATA_FLAG) == 0) || //Any incoming 'command' (as opposed to incoming 'data') is an automatic fail here
(replyPacket->Length <= DOWNSTREAM_PACKET_HEADER_LEN) || //Should be at least one data byte in the packet.
(replyPacket->Length > ByteCount))
{
//FreakOut?????
GetStreamDataCallback(HAL_ERROR, NULL, NULL);
return;
}
dataLength = replyPacket->Length - DOWNSTREAM_PACKET_HEADER_LEN;
ByteCount -= dataLength;
GetStreamDataCallback(HAL_OK, replyPacket, dataLength); //usb_msc_scsi will use this packet, so don't release now
if (ByteCount > 0)
{
Downstream_MSC_GetStreamDataPacket(NULL); //Try to get the next packet now, before USB asks for it
}
USBH_MSC_Read(&hUsbHostFS,
0,
(uint32_t)address,
count);
} }

@ -15,6 +15,7 @@ SPI_HandleTypeDef Hspi1;
DownstreamPacketTypeDef DownstreamPacket0; DownstreamPacketTypeDef DownstreamPacket0;
DownstreamPacketTypeDef DownstreamPacket1; DownstreamPacketTypeDef DownstreamPacket1;
DownstreamPacketTypeDef* CurrentWorkingPacket; DownstreamPacketTypeDef* CurrentWorkingPacket;
DownstreamPacketTypeDef* NextTxPacket;
InterfaceStateTypeDef DownstreamInterfaceState; InterfaceStateTypeDef DownstreamInterfaceState;
FreePacketCallbackTypeDef PendingFreePacketCallback; //Indicates someone is waiting for a packet buffer to become available FreePacketCallbackTypeDef PendingFreePacketCallback; //Indicates someone is waiting for a packet buffer to become available
@ -34,7 +35,7 @@ void Downstream_InitSPI(void)
DownstreamPacket0.Busy = NOT_BUSY; DownstreamPacket0.Busy = NOT_BUSY;
DownstreamPacket1.Busy = NOT_BUSY; DownstreamPacket1.Busy = NOT_BUSY;
//NextTxPacket = NULL; NextTxPacket = NULL;
PendingFreePacketCallback = NULL; PendingFreePacketCallback = NULL;
ReceivePacketCallback = NULL; ReceivePacketCallback = NULL;
@ -147,7 +148,7 @@ void Downstream_ReleasePacket(DownstreamPacketTypeDef* packetToRelease)
//Used by Downstream state machine (and USB classes?). //Used by Downstream state machine (and USB classes?).
//Ok to call when idle or transmitting. //Ok to call when idle or transmitting.
//Not OK to call when receiving or waiting for downstream reply. //Not OK to call when receiving or awaiting reception.
HAL_StatusTypeDef Downstream_ReceivePacket(SpiPacketReceivedCallbackTypeDef callback) HAL_StatusTypeDef Downstream_ReceivePacket(SpiPacketReceivedCallbackTypeDef callback)
{ {
if (ReceivePacketCallback != NULL) if (ReceivePacketCallback != NULL)
@ -248,7 +249,8 @@ void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
//Used by Downstream state machine (and USB classes?). //Used by Downstream state machine (and USB classes?).
//Call when idle only. //Call when idle or transmitting.
//It doesn't make sense to call when receiving or awaiting reception.
HAL_StatusTypeDef Downstream_TransmitPacket(DownstreamPacketTypeDef* packetToWrite) HAL_StatusTypeDef Downstream_TransmitPacket(DownstreamPacketTypeDef* packetToWrite)
{ {
//Sanity checks //Sanity checks
@ -263,30 +265,42 @@ HAL_StatusTypeDef Downstream_TransmitPacket(DownstreamPacketTypeDef* packetToWri
{ {
SPI_INTERFACE_FREAKOUT_RETURN_HAL_ERROR; SPI_INTERFACE_FREAKOUT_RETURN_HAL_ERROR;
} }
if (NextTxPacket != NULL)
if (DownstreamInterfaceState != DOWNSTREAM_INTERFACE_IDLE)
{ {
SPI_INTERFACE_FREAKOUT_RETURN_HAL_ERROR; SPI_INTERFACE_FREAKOUT_RETURN_HAL_ERROR;
} }
DownstreamInterfaceState = DOWNSTREAM_INTERFACE_TX_SIZE_WAIT; switch (DownstreamInterfaceState)
CurrentWorkingPacket = packetToWrite;
if (HAL_SPI_TransmitReceive_DMA(&Hspi1,
(uint8_t*)&CurrentWorkingPacket->Length,
(uint8_t*)&CurrentWorkingPacket->Length,
2 + 1) != HAL_OK) //"When the CRC feature is enabled the pRxData Length must be Size + 1"
{ {
SPI_INTERFACE_FREAKOUT_RETURN_VOID; case DOWNSTREAM_INTERFACE_TX_SIZE_WAIT:
case DOWNSTREAM_INTERFACE_TX_PACKET_WAIT:
NextTxPacket = packetToWrite;
break;
case DOWNSTREAM_INTERFACE_IDLE:
DownstreamInterfaceState = DOWNSTREAM_INTERFACE_TX_SIZE_WAIT;
CurrentWorkingPacket = packetToWrite;
if (HAL_SPI_TransmitReceive_DMA(&Hspi1,
(uint8_t*)&CurrentWorkingPacket->Length,
(uint8_t*)&CurrentWorkingPacket->Length,
2 + 1) != HAL_OK) //"When the CRC feature is enabled the pRxData Length must be Size + 1"
{
SPI_INTERFACE_FREAKOUT_RETURN_VOID;
}
UPSTREAM_TX_REQUEST_ASSERT;
break;
default:
SPI_INTERFACE_FREAKOUT_RETURN_HAL_ERROR;
} }
UPSTREAM_TX_REQUEST_ASSERT;
return HAL_OK; return HAL_OK;
} }
//Called at the end of the SPI TxRx DMA transfer, //Called at the end of the SPI TxRx DMA transfer,
//at DMA2 interrupt priority. Assume *hspi points to our hspi1. //at DMA2 interrupt priority. Assume *hspi points to our hspi1.
//We use TxRx while sending our reply packet to check if Upstream was trying //We use TxRx to send our reply packet to check if Upstream was trying
//to send us a packet at the same time. //to send us a packet at the same time.
void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi) void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)
{ {
@ -326,8 +340,26 @@ void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
SPI_INTERFACE_FREAKOUT_RETURN_VOID; SPI_INTERFACE_FREAKOUT_RETURN_VOID;
} }
DownstreamInterfaceState = DOWNSTREAM_INTERFACE_IDLE;
Downstream_ReleasePacket(CurrentWorkingPacket); Downstream_ReleasePacket(CurrentWorkingPacket);
if (NextTxPacket != NULL)
{
//NextTxPacket has already passed the checks in Downstream_TransmitPacket.
//So we just need to pass it to HAL_SPI_Transmit_DMA.
DownstreamInterfaceState = DOWNSTREAM_INTERFACE_TX_SIZE_WAIT;
CurrentWorkingPacket = NextTxPacket;
NextTxPacket = NULL;
if (HAL_SPI_TransmitReceive_DMA(&Hspi1,
(uint8_t*)&CurrentWorkingPacket->Length,
(uint8_t*)&CurrentWorkingPacket->Length,
2 + 1) != HAL_OK) //"When the CRC feature is enabled the pRxData Length must be Size + 1"
{
SPI_INTERFACE_FREAKOUT_RETURN_VOID;
}
UPSTREAM_TX_REQUEST_ASSERT;
return;
}
DownstreamInterfaceState = DOWNSTREAM_INTERFACE_IDLE;
if (ReceivePacketCallback != NULL) if (ReceivePacketCallback != NULL)
{ {
Downstream_CheckPreparePacketReception(); Downstream_CheckPreparePacketReception();

@ -19,7 +19,6 @@ DownstreamStateTypeDef DownstreamState;
InterfaceCommandClassTypeDef ConfiguredDeviceClass; InterfaceCommandClassTypeDef ConfiguredDeviceClass;
void Downstream_PacketProcessor(DownstreamPacketTypeDef* receivedPacket);
void Downstream_PacketProcessor_Interface(DownstreamPacketTypeDef* receivedPacket); void Downstream_PacketProcessor_Interface(DownstreamPacketTypeDef* receivedPacket);
void Downstream_PacketProcessor_Interface_ReplyNotifyDevice(DownstreamPacketTypeDef* replyPacket); void Downstream_PacketProcessor_Interface_ReplyNotifyDevice(DownstreamPacketTypeDef* replyPacket);

@ -846,7 +846,8 @@ static void SCSI_Verify10(void)
*/ */
static int8_t SCSI_CheckAddressRange (uint32_t blk_offset , uint16_t blk_nbr) static int8_t SCSI_CheckAddressRange (uint32_t blk_offset , uint16_t blk_nbr)
{ {
if ((blk_offset + blk_nbr) > SCSI_ProcessCmd_hmsc->scsi_blk_nbr ) if ((blk_offset > SCSI_ProcessCmd_hmsc->scsi_blk_nbr) ||
((blk_offset + blk_nbr) > SCSI_ProcessCmd_hmsc->scsi_blk_nbr))
{ {
SCSI_SenseCode(SCSI_ProcessCmd_pdev, SCSI_SenseCode(SCSI_ProcessCmd_pdev,
SCSI_ProcessCmd_lun, SCSI_ProcessCmd_lun,

@ -51,7 +51,7 @@ HAL_StatusTypeDef Upstream_MSC_TestReady(UpstreamMSCCallbackTypeDef callback)
void Upstream_MSC_TestReadyReplyCallback(UpstreamPacketTypeDef* replyPacket) void Upstream_MSC_TestReadyReplyCallback(UpstreamPacketTypeDef* replyPacket)
{ {
if ((replyPacket->Length != (UPSTREAM_PACKET_HEADER_LEN + 1)) || if ((replyPacket->Length != (UPSTREAM_PACKET_HEADER_LEN + 1)) ||
(replyPacket->CommandClass & COMMAND_CLASS_DATA_FLAG) || (replyPacket->CommandClass != COMMAND_CLASS_MASS_STORAGE) ||
(replyPacket->Data[0] != HAL_OK)) (replyPacket->Data[0] != HAL_OK))
{ {
Upstream_ReleasePacket(replyPacket); Upstream_ReleasePacket(replyPacket);
@ -90,7 +90,7 @@ void Upstream_MSC_GetCapacityReplyCallback(UpstreamPacketTypeDef* replyPacket)
uint32_t uint[2]; uint32_t uint[2];
if ((replyPacket->Length != (UPSTREAM_PACKET_HEADER_LEN + 8) || if ((replyPacket->Length != (UPSTREAM_PACKET_HEADER_LEN + 8) ||
(replyPacket->CommandClass & COMMAND_CLASS_DATA_FLAG))) (replyPacket->CommandClass != COMMAND_CLASS_MASS_STORAGE)))
{ {
GetCapacityCallback(HAL_ERROR, NULL, NULL); GetCapacityCallback(HAL_ERROR, NULL, NULL);
return; return;
@ -113,9 +113,9 @@ HAL_StatusTypeDef Upstream_MSC_BeginRead(UpstreamMSCCallbackTypeDef callback,
ReadStreamPacket = NULL; //Prepare for GetStreamDataPacket's use ReadStreamPacket = NULL; //Prepare for GetStreamDataPacket's use
ReadStreamBusy = 0; ReadStreamBusy = 0;
ByteCount = readByteCount;
TestReadyCallback = callback; TestReadyCallback = callback;
ByteCount = readByteCount;
freePacket = Upstream_GetFreePacketImmediately(); freePacket = Upstream_GetFreePacketImmediately();
freePacket->Length = UPSTREAM_PACKET_HEADER_LEN + (4 * 3); freePacket->Length = UPSTREAM_PACKET_HEADER_LEN + (4 * 3);
@ -165,20 +165,21 @@ void Upstream_MSC_GetStreamDataPacketCallback(UpstreamPacketTypeDef* replyPacket
return; return;
} }
dataLength = replyPacket->Length - UPSTREAM_PACKET_HEADER_LEN;
if (((replyPacket->CommandClass & COMMAND_CLASS_DATA_FLAG) == 0) || //Any 'command' reply (as opposed to 'data' reply) is an automatic fail here if (((replyPacket->CommandClass & COMMAND_CLASS_DATA_FLAG) == 0) || //Any 'command' reply (as opposed to 'data' reply) is an automatic fail here
(replyPacket->Length <= UPSTREAM_PACKET_HEADER_LEN) || //Should be at least one data byte in the reply. (replyPacket->Length <= UPSTREAM_PACKET_HEADER_LEN) || //Should be at least one data byte in the reply.
(replyPacket->Length > ByteCount)) (dataLength > ByteCount)) //No more data than expected transfer length
{ {
GetStreamDataCallback(HAL_ERROR, NULL, NULL); GetStreamDataCallback(HAL_ERROR, NULL, NULL);
return; return;
} }
dataLength = replyPacket->Length - UPSTREAM_PACKET_HEADER_LEN;
ByteCount -= dataLength; ByteCount -= dataLength;
GetStreamDataCallback(HAL_OK, replyPacket, dataLength); //usb_msc_scsi will use this packet, so don't release now GetStreamDataCallback(HAL_OK, replyPacket, dataLength); //usb_msc_scsi will use this packet, so don't release now
if (ByteCount > 0) if (ByteCount > 0)
{ {
Upstream_MSC_GetStreamDataPacket(NULL); //Try to get the next packet now, before USB asks for it Upstream_MSC_GetStreamDataPacket(NULL); //Try to get the next packet now, before USB asks for it
} }
} }
@ -212,7 +213,7 @@ HAL_StatusTypeDef Upstream_MSC_BeginWrite(UpstreamMSCCallbackTypeDef callback,
void Upstream_MSC_BeginWriteReplyCallback(UpstreamPacketTypeDef* replyPacket) void Upstream_MSC_BeginWriteReplyCallback(UpstreamPacketTypeDef* replyPacket)
{ {
if ((replyPacket->Length != (UPSTREAM_PACKET_HEADER_LEN + 1)) || if ((replyPacket->Length != (UPSTREAM_PACKET_HEADER_LEN + 1)) ||
(replyPacket->CommandClass & COMMAND_CLASS_DATA_FLAG) || (replyPacket->CommandClass != COMMAND_CLASS_MASS_STORAGE) ||
((replyPacket->Data[0] != HAL_OK) && (replyPacket->Data[0] != HAL_BUSY))) ((replyPacket->Data[0] != HAL_OK) && (replyPacket->Data[0] != HAL_BUSY)))
{ {
Upstream_ReleasePacket(replyPacket); Upstream_ReleasePacket(replyPacket);

@ -5,7 +5,7 @@
* Author: Robert Fisk * Author: Robert Fisk
* *
* This file replaces upstream_msc.c to allow operational testing of Upstream, * This file replaces upstream_msc.c to allow operational testing of Upstream,
* without Upstream in place and communicating over SPI. * without Downstream in place and communicating over SPI.
* It still attempts to write downstream packets out the SPI port. * It still attempts to write downstream packets out the SPI port.
*/ */

@ -159,7 +159,8 @@ void Upstream_ReleasePacket(UpstreamPacketTypeDef* packetToRelease)
//Used by USB interface classes only. //Used by USB interface classes only.
//OK to call when still transmitting another packet. //OK to call when still transmitting another packet.
//Not OK to call when receiving or waiting for downstream reply. //Not OK to call when receiving or waiting for downstream reply,
//as we can't let the size/packet sequence get out of sync.
HAL_StatusTypeDef Upstream_TransmitPacket(UpstreamPacketTypeDef* packetToWrite) HAL_StatusTypeDef Upstream_TransmitPacket(UpstreamPacketTypeDef* packetToWrite)
{ {
//Sanity checks //Sanity checks
@ -188,13 +189,6 @@ HAL_StatusTypeDef Upstream_TransmitPacket(UpstreamPacketTypeDef* packetToWrite)
NextTxPacket = packetToWrite; NextTxPacket = packetToWrite;
break; break;
case UPSTREAM_INTERFACE_RX_SIZE_WAIT:
case UPSTREAM_INTERFACE_RX_SIZE:
case UPSTREAM_INTERFACE_RX_PACKET_WAIT:
case UPSTREAM_INTERFACE_RX_PACKET:
//We can't let the size/packet sequence get out of sync.
SPI_INTERFACE_FREAKOUT_RETURN_HAL_ERROR;
case UPSTREAM_INTERFACE_IDLE: case UPSTREAM_INTERFACE_IDLE:
UpstreamInterfaceState = UPSTREAM_INTERFACE_TX_SIZE_WAIT; UpstreamInterfaceState = UPSTREAM_INTERFACE_TX_SIZE_WAIT;
CurrentWorkingPacket = packetToWrite; CurrentWorkingPacket = packetToWrite;
@ -238,7 +232,7 @@ void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
Upstream_ReleasePacket(CurrentWorkingPacket); Upstream_ReleasePacket(CurrentWorkingPacket);
if (NextTxPacket != NULL) if (NextTxPacket != NULL)
{ {
//NextTxPacket has already passed the checks in SendUpstreamPacket. //NextTxPacket has already passed the checks in Upstream_TransmitPacket.
//So we just need to pass it to HAL_SPI_Transmit_DMA. //So we just need to pass it to HAL_SPI_Transmit_DMA.
UpstreamInterfaceState = UPSTREAM_INTERFACE_TX_SIZE_WAIT; UpstreamInterfaceState = UPSTREAM_INTERFACE_TX_SIZE_WAIT;
CurrentWorkingPacket = NextTxPacket; CurrentWorkingPacket = NextTxPacket;
@ -385,7 +379,8 @@ void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
if (UpstreamInterfaceState == UPSTREAM_INTERFACE_RX_PACKET) if (UpstreamInterfaceState == UPSTREAM_INTERFACE_RX_PACKET)
{ {
UpstreamInterfaceState = UPSTREAM_INTERFACE_IDLE; UpstreamInterfaceState = UPSTREAM_INTERFACE_IDLE;
if ((SentCommandClass != (CurrentWorkingPacket->CommandClass & COMMAND_CLASS_MASK)) || if (((SentCommandClass != (CurrentWorkingPacket->CommandClass & COMMAND_CLASS_MASK)) &&
(SentCommandClass != COMMAND_CLASS_ERROR)) ||
(SentCommand != CurrentWorkingPacket->Command)) (SentCommand != CurrentWorkingPacket->Command))
{ {
SPI_INTERFACE_FREAKOUT_RETURN_VOID; SPI_INTERFACE_FREAKOUT_RETURN_VOID;

Loading…
Cancel
Save