All tabs to spaces

pull/7/head
Robert Fisk 9 years ago
parent 08e6846cc5
commit 1262c5337a

@ -867,7 +867,7 @@ static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum)
else if((hhcd->hc[chnum].state == HC_XACTERR) ||
(hhcd->hc[chnum].state == HC_DATATGLERR) ||
(hhcd->hc[chnum].state == HC_NAK))
(hhcd->hc[chnum].state == HC_NAK))
{
if(hhcd->hc[chnum].ErrCnt++ > 3)
{
@ -899,7 +899,7 @@ static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum)
}
else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_NAK)
{
hhcd->hc[chnum].ErrCnt = 0;
hhcd->hc[chnum].ErrCnt = 0;
// if(hhcd->hc[chnum].ep_type == EP_TYPE_INTR)
// {
__HAL_HCD_UNMASK_HALT_HC_INT(chnum);
@ -1090,7 +1090,7 @@ static void HCD_RXQLVL_IRQHandler(HCD_HandleTypeDef *hhcd)
if ((pktcnt > 0) && (hhcd->hc[channelnum].xfer_buff != (void *)0))
{
USB_ReadPacket(hhcd->Instance, hhcd->hc[channelnum].xfer_buff, pktcnt); //Todo: buffer overflow here!
USB_ReadPacket(hhcd->Instance, hhcd->hc[channelnum].xfer_buff, pktcnt); //Todo: buffer overflow here!
/*manage multiple Xfer */
hhcd->hc[channelnum].xfer_buff += pktcnt;

@ -2101,9 +2101,9 @@ static void SPI_DMAEndTransmitReceive(SPI_HandleTypeDef *hspi)
/* Wait until Busy flag is reset before disabling SPI */
if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_BSY, SET, SPI_TIMEOUT_VALUE) != HAL_OK)
{
//The Busy flag occasionally fails to reset within timeout. No idea why.
//But in this case WaitOnFlagUntilTimeout disables the SPI for us,
//so we can ignore the error and carry on.
//The Busy flag occasionally fails to reset within timeout. No idea why.
//But in this case WaitOnFlagUntilTimeout disables the SPI for us,
//so we can ignore the error and carry on.
//hspi->ErrorCode |= HAL_SPI_ERROR_FLAG;
}

@ -14,49 +14,49 @@
#define INC_BOARD_CONFIG_H_
#define BSRR_SHIFT_HIGH 0
#define BSRR_SHIFT_LOW 16
#define PA_JTMS GPIO_PIN_13
#define PA_JTCK GPIO_PIN_14
#define PA_JTDI GPIO_PIN_15
#define PB_JTDO GPIO_PIN_3
#define PB_NJTRST GPIO_PIN_4
#define USB_FS_VBUS_PIN GPIO_PIN_9
#define USB_FS_VBUS_PORT GPIOA
#define USB_FS_VBUSON_PIN GPIO_PIN_10
#define USB_FS_VBUSON_PORT GPIOA
#define USB_FS_FAULT_PIN GPIO_PIN_6
#define USB_FS_FAULT_PORT GPIOB
#define USB_HS_VBUS_PIN GPIO_PIN_13
#define USB_HS_VBUS_PORT GPIOB
#define USB_HS_VBUSON_PIN GPIO_PIN_8
#define USB_HS_VBUSON_PORT GPIOA
#define FAULT_LED_PIN GPIO_PIN_13
#define FAULT_LED_PORT GPIOC
#define FAULT_LED_ON (FAULT_LED_PORT->BSRR = (FAULT_LED_PIN << BSRR_SHIFT_LOW)) //Fault LED is active-low
#define FAULT_LED_OFF (FAULT_LED_PORT->BSRR = (FAULT_LED_PIN << BSRR_SHIFT_HIGH))
#define H405_FAULT_LED_PIN GPIO_PIN_12 //Fault LED on Olimex H405 board
#define H405_FAULT_LED_ON (FAULT_LED_PORT->BSRR = (H405_FAULT_LED_PIN << BSRR_SHIFT_LOW))
#define INT_ACTIVE_PIN GPIO_PIN_2 //Temporary indicator of SPI (or whatever) activity
#define INT_ACTIVE_PORT GPIOA
#define INT_ACTIVE_ON INT_ACTIVE_PORT->BSRR = (INT_ACTIVE_PIN << BSRR_SHIFT_HIGH)
#define INT_ACTIVE_OFF INT_ACTIVE_PORT->BSRR = (INT_ACTIVE_PIN << BSRR_SHIFT_LOW)
//#define SPI1_NSS_PIN GPIO_PIN_4
//#define SPI1_NSS_PORT GPIOA
#define UPSTREAM_TX_REQUEST_PIN GPIO_PIN_3
#define UPSTREAM_TX_REQUEST_PORT GPIOA
#define UPSTREAM_TX_REQUEST_ASSERT (UPSTREAM_TX_REQUEST_PORT->BSRR = (UPSTREAM_TX_REQUEST_PIN << BSRR_SHIFT_LOW))
#define UPSTREAM_TX_REQUEST_DEASSERT (UPSTREAM_TX_REQUEST_PORT->BSRR = (UPSTREAM_TX_REQUEST_PIN << BSRR_SHIFT_HIGH))
#define DBGMCU_IDCODE_DEV_ID_405_407_415_417 0x413
#define BSRR_SHIFT_HIGH 0
#define BSRR_SHIFT_LOW 16
#define PA_JTMS GPIO_PIN_13
#define PA_JTCK GPIO_PIN_14
#define PA_JTDI GPIO_PIN_15
#define PB_JTDO GPIO_PIN_3
#define PB_NJTRST GPIO_PIN_4
#define USB_FS_VBUS_PIN GPIO_PIN_9
#define USB_FS_VBUS_PORT GPIOA
#define USB_FS_VBUSON_PIN GPIO_PIN_10
#define USB_FS_VBUSON_PORT GPIOA
#define USB_FS_FAULT_PIN GPIO_PIN_6
#define USB_FS_FAULT_PORT GPIOB
#define USB_HS_VBUS_PIN GPIO_PIN_13
#define USB_HS_VBUS_PORT GPIOB
#define USB_HS_VBUSON_PIN GPIO_PIN_8
#define USB_HS_VBUSON_PORT GPIOA
#define FAULT_LED_PIN GPIO_PIN_13
#define FAULT_LED_PORT GPIOC
#define FAULT_LED_ON (FAULT_LED_PORT->BSRR = (FAULT_LED_PIN << BSRR_SHIFT_LOW)) //Fault LED is active-low
#define FAULT_LED_OFF (FAULT_LED_PORT->BSRR = (FAULT_LED_PIN << BSRR_SHIFT_HIGH))
#define H405_FAULT_LED_PIN GPIO_PIN_12 //Fault LED on Olimex H405 board
#define H405_FAULT_LED_ON (FAULT_LED_PORT->BSRR = (H405_FAULT_LED_PIN << BSRR_SHIFT_LOW))
#define INT_ACTIVE_PIN GPIO_PIN_2 //Temporary indicator of SPI (or whatever) activity
#define INT_ACTIVE_PORT GPIOA
#define INT_ACTIVE_ON INT_ACTIVE_PORT->BSRR = (INT_ACTIVE_PIN << BSRR_SHIFT_HIGH)
#define INT_ACTIVE_OFF INT_ACTIVE_PORT->BSRR = (INT_ACTIVE_PIN << BSRR_SHIFT_LOW)
//#define SPI1_NSS_PIN GPIO_PIN_4
//#define SPI1_NSS_PORT GPIOA
#define UPSTREAM_TX_REQUEST_PIN GPIO_PIN_3
#define UPSTREAM_TX_REQUEST_PORT GPIOA
#define UPSTREAM_TX_REQUEST_ASSERT (UPSTREAM_TX_REQUEST_PORT->BSRR = (UPSTREAM_TX_REQUEST_PIN << BSRR_SHIFT_LOW))
#define UPSTREAM_TX_REQUEST_DEASSERT (UPSTREAM_TX_REQUEST_PORT->BSRR = (UPSTREAM_TX_REQUEST_PIN << BSRR_SHIFT_HIGH))
#define DBGMCU_IDCODE_DEV_ID_405_407_415_417 0x413
#endif /* INC_BOARD_CONFIG_H_ */

@ -21,42 +21,42 @@
#define COMMAND_CLASS_DATA_FLAG 0x80
#define COMMAND_CLASS_MASK ((uint8_t)(~COMMAND_CLASS_DATA_FLAG))
#define COMMAND_CLASS_DATA_FLAG 0x80
#define COMMAND_CLASS_MASK ((uint8_t)(~COMMAND_CLASS_DATA_FLAG))
typedef enum
{
COMMAND_CLASS_INTERFACE,
COMMAND_CLASS_MASS_STORAGE,
//...
COMMAND_CLASS_ERROR
COMMAND_CLASS_INTERFACE,
COMMAND_CLASS_MASS_STORAGE,
//...
COMMAND_CLASS_ERROR
}
InterfaceCommandClassTypeDef;
typedef enum
{
COMMAND_INTERFACE_ECHO, //Returns echo packet including all data
COMMAND_INTERFACE_NOTIFY_DEVICE //Returns COMMAND_CLASS_*** byte when downstream USB device is connected
COMMAND_INTERFACE_ECHO, //Returns echo packet including all data
COMMAND_INTERFACE_NOTIFY_DEVICE //Returns COMMAND_CLASS_*** byte when downstream USB device is connected
}
InterfaceCommandInterfaceTypeDef;
typedef enum
{
COMMAND_MSC_TEST_UNIT_READY, //Returns HAL_StatusTypeDef result
COMMAND_MSC_GET_CAPACITY, //Returns uint32_t blk_nbr, uint32_t blk_size
COMMAND_MSC_READ, //Returns HAL_StatusTypeDef result, then data stream
COMMAND_MSC_WRITE, //Returns HAL_OK, HAL_ERROR if medium not present, HAL_BUSY if write-protected result, then waits for data stream
COMMAND_MSC_TEST_UNIT_READY, //Returns HAL_StatusTypeDef result
COMMAND_MSC_GET_CAPACITY, //Returns uint32_t blk_nbr, uint32_t blk_size
COMMAND_MSC_READ, //Returns HAL_StatusTypeDef result, then data stream
COMMAND_MSC_WRITE, //Returns HAL_OK, HAL_ERROR if medium not present, HAL_BUSY if write-protected result, then waits for data stream
}
InterfaceCommandMscTypeDef;
typedef enum
{
COMMAND_ERROR_GENERIC,
COMMAND_ERROR_DEVICE_DISCONNECTED,
COMMAND_ERROR_GENERIC,
COMMAND_ERROR_DEVICE_DISCONNECTED,
}
InterfaceCommandErrorTypeDef;

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

@ -16,50 +16,50 @@
#include "usbh_config.h"
#define DOWNSTREAM_PACKET_HEADER_LEN (2) //Min length = CommandClass & Command bytes
#define DOWNSTREAM_PACKET_LEN (DOWNSTREAM_PACKET_HEADER_LEN + USBH_MAX_DATA_BUFFER)
#define DOWNSTREAM_PACKET_LEN_MIN (DOWNSTREAM_PACKET_HEADER_LEN)
#define DOWNSTREAM_PACKET_HEADER_LEN (2) //Min length = CommandClass & Command bytes
#define DOWNSTREAM_PACKET_LEN (DOWNSTREAM_PACKET_HEADER_LEN + USBH_MAX_DATA_BUFFER)
#define DOWNSTREAM_PACKET_LEN_MIN (DOWNSTREAM_PACKET_HEADER_LEN)
#define DOWNSTREAM_PACKET_HEADER_LEN_16 (DOWNSTREAM_PACKET_HEADER_LEN / 2)
#define DOWNSTREAM_PACKET_LEN_16 (DOWNSTREAM_PACKET_LEN / 2)
#define DOWNSTREAM_PACKET_LEN_MIN_16 (DOWNSTREAM_PACKET_LEN_MIN / 2)
#define DOWNSTREAM_PACKET_HEADER_LEN_16 (DOWNSTREAM_PACKET_HEADER_LEN / 2)
#define DOWNSTREAM_PACKET_LEN_16 (DOWNSTREAM_PACKET_LEN / 2)
#define DOWNSTREAM_PACKET_LEN_MIN_16 (DOWNSTREAM_PACKET_LEN_MIN / 2)
#define DOWNSTREAM_SPI_FREAKOUT \
do { \
Downstream_PacketProcessor_FreakOut(); \
DownstreamInterfaceState = DOWNSTREAM_INTERFACE_ERROR; \
while (1); \
} while (0);
#define DOWNSTREAM_SPI_FREAKOUT \
do { \
Downstream_PacketProcessor_FreakOut(); \
DownstreamInterfaceState = DOWNSTREAM_INTERFACE_ERROR; \
while (1); \
} while (0);
typedef enum
{
DOWNSTREAM_INTERFACE_IDLE,
DOWNSTREAM_INTERFACE_RX_SIZE_WAIT,
DOWNSTREAM_INTERFACE_RX_PACKET_WAIT,
DOWNSTREAM_INTERFACE_TX_SIZE_WAIT,
DOWNSTREAM_INTERFACE_TX_PACKET_WAIT,
DOWNSTREAM_INTERFACE_ERROR
DOWNSTREAM_INTERFACE_IDLE,
DOWNSTREAM_INTERFACE_RX_SIZE_WAIT,
DOWNSTREAM_INTERFACE_RX_PACKET_WAIT,
DOWNSTREAM_INTERFACE_TX_SIZE_WAIT,
DOWNSTREAM_INTERFACE_TX_PACKET_WAIT,
DOWNSTREAM_INTERFACE_ERROR
}
InterfaceStateTypeDef;
typedef enum
{
NOT_BUSY,
BUSY
NOT_BUSY,
BUSY
}
PacketBusyTypeDef;
typedef struct
{
PacketBusyTypeDef Busy; //Everything after Busy should be word-aligned
uint16_t Length16 __ALIGN_END; //Packet length includes CommandClass, Command, and Data
uint8_t CommandClass;
uint8_t Command;
uint8_t Data[USBH_MAX_DATA_BUFFER]; //Should (must?) be word-aligned, for USB copy routine
PacketBusyTypeDef Busy; //Everything after Busy should be word-aligned
uint16_t Length16 __ALIGN_END; //Packet length includes CommandClass, Command, and Data
uint8_t CommandClass;
uint8_t Command;
uint8_t Data[USBH_MAX_DATA_BUFFER]; //Should (must?) be word-aligned, for USB copy routine
}
DownstreamPacketTypeDef;

@ -20,21 +20,21 @@
typedef enum
{
STATE_DEVICE_NOT_READY,
STATE_DEVICE_READY, //Go here if HOST_USER_CLASS_ACTIVE callback arrives first
STATE_WAIT_DEVICE_READY, //Go here if COMMAND_INTERFACE_NOTIFY_DEVICE message arrives first
STATE_ACTIVE,
STATE_ERROR
STATE_DEVICE_NOT_READY,
STATE_DEVICE_READY, //Go here if HOST_USER_CLASS_ACTIVE callback arrives first
STATE_WAIT_DEVICE_READY, //Go here if COMMAND_INTERFACE_NOTIFY_DEVICE message arrives first
STATE_ACTIVE,
STATE_ERROR
} DownstreamStateTypeDef;
#define DOWNSTREAM_STATEMACHINE_FREAKOUT \
do { \
USB_Host_Disconnect(); \
LED_Fault_SetBlinkRate(LED_FAST_BLINK_RATE); \
DownstreamState = STATE_ERROR; \
while (1); \
#define DOWNSTREAM_STATEMACHINE_FREAKOUT \
do { \
USB_Host_Disconnect(); \
LED_Fault_SetBlinkRate(LED_FAST_BLINK_RATE); \
DownstreamState = STATE_ERROR; \
while (1); \
} while (0);

@ -102,23 +102,23 @@ typedef void (*MSC_RdWrCompleteCallback)(USBH_StatusTypeDef result);
/* Structure for MSC process */
typedef struct _MSC_Process
{
uint32_t max_lun;
uint8_t InPipe;
uint8_t OutPipe;
uint8_t OutEp;
uint8_t InEp;
uint16_t OutEpSize;
uint16_t InEpSize;
MSC_StateTypeDef state;
MSC_ErrorTypeDef error;
MSC_ReqStateTypeDef req_state;
MSC_ReqStateTypeDef prev_req_state;
BOT_HandleTypeDef hbot;
MSC_LUNTypeDef unit[MAX_SUPPORTED_LUN];
uint16_t current_lun;
uint16_t rw_lun;
uint32_t timeout;
MSC_RdWrCompleteCallback RdWrCompleteCallback;
uint32_t max_lun;
uint8_t InPipe;
uint8_t OutPipe;
uint8_t OutEp;
uint8_t InEp;
uint16_t OutEpSize;
uint16_t InEpSize;
MSC_StateTypeDef state;
MSC_ErrorTypeDef error;
MSC_ReqStateTypeDef req_state;
MSC_ReqStateTypeDef prev_req_state;
BOT_HandleTypeDef hbot;
MSC_LUNTypeDef unit[MAX_SUPPORTED_LUN];
uint16_t current_lun;
uint16_t rw_lun;
uint32_t timeout;
MSC_RdWrCompleteCallback RdWrCompleteCallback;
}
MSC_HandleTypeDef;
@ -136,7 +136,7 @@ MSC_HandleTypeDef;
#define USB_REQ_BOT_RESET 0xFF
#define USB_REQ_GET_MAX_LUN 0xFE
#define MSC_TIMEOUT_FRAMES_PER_BLOCK 1000
#define MSC_TIMEOUT_FRAMES_PER_BLOCK 1000
/* MSC Class Codes */
#define USB_MSC_CLASS 0x08
@ -183,13 +183,13 @@ USBH_StatusTypeDef USBH_MSC_Read(USBH_HandleTypeDef *phost,
uint8_t lun,
uint32_t address,
uint32_t length,
MSC_RdWrCompleteCallback callback);
MSC_RdWrCompleteCallback callback);
USBH_StatusTypeDef USBH_MSC_Write(USBH_HandleTypeDef *phost,
uint8_t lun,
uint32_t address,
uint32_t length,
MSC_RdWrCompleteCallback callback);
MSC_RdWrCompleteCallback callback);
/**
* @}
*/

@ -146,10 +146,10 @@ typedef struct
BOT_CSWTypeDef csw;
uint8_t Reserved2[3];
uint8_t* pbuf;
DownstreamPacketTypeDef* bot_packet;
uint8_t* bot_packet_pbuf;
uint16_t bot_packet_bytes_remaining;
uint16_t this_URB_size;
DownstreamPacketTypeDef* bot_packet;
uint8_t* bot_packet_pbuf;
uint16_t bot_packet_bytes_remaining;
uint16_t this_URB_size;
}
BOT_HandleTypeDef;

@ -483,35 +483,35 @@ static USBH_StatusTypeDef USBH_MSC_Process(USBH_HandleTypeDef *phost)
}
else
{
MSC_Handle->current_lun = 0;
MSC_Handle->state = MSC_IDLE;
MSC_Handle->current_lun = 0;
MSC_Handle->state = MSC_IDLE;
phost->pUser(phost, HOST_USER_CLASS_ACTIVE);
phost->pUser(phost, HOST_USER_CLASS_ACTIVE);
}
break;
case MSC_IDLE:
error = USBH_OK;
break;
error = USBH_OK;
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;
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:
break;
@ -719,13 +719,13 @@ USBH_StatusTypeDef USBH_MSC_Read(USBH_HandleTypeDef *phost,
uint8_t lun,
uint32_t address,
uint32_t length,
MSC_RdWrCompleteCallback callback)
MSC_RdWrCompleteCallback callback)
{
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
if ((phost->device.is_connected == 0) ||
(phost->gState != HOST_CLASS) ||
(MSC_Handle->state != MSC_IDLE) ||
(MSC_Handle->state != MSC_IDLE) ||
(MSC_Handle->unit[lun].state != MSC_IDLE))
{
return USBH_FAIL;
@ -760,13 +760,13 @@ USBH_StatusTypeDef USBH_MSC_Write(USBH_HandleTypeDef *phost,
uint8_t lun,
uint32_t address,
uint32_t length,
MSC_RdWrCompleteCallback callback)
MSC_RdWrCompleteCallback callback)
{
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
if ((phost->device.is_connected == 0) ||
(phost->gState != HOST_CLASS) ||
(MSC_Handle->state != MSC_IDLE) ||
(MSC_Handle->state != MSC_IDLE) ||
(MSC_Handle->unit[lun].state != MSC_IDLE))
{
return USBH_FAIL;

@ -42,7 +42,7 @@ static BOT_CSWStatusTypeDef USBH_MSC_DecodeCSW(USBH_HandleTypeDef *phost);
void USBH_MSC_BOT_Read_Multipacket_FreePacketCallback(DownstreamPacketTypeDef* freePacket);
void USBH_MSC_BOT_Read_Multipacket_PrepareURB(USBH_HandleTypeDef *phost);
void USBH_MSC_BOT_Write_Multipacket_ReceivePacketCallback(DownstreamPacketTypeDef* receivedPacket,
uint16_t dataLength);
uint16_t dataLength);
void USBH_MSC_BOT_Write_Multipacket_PrepareURB(USBH_HandleTypeDef *phost);
@ -180,88 +180,88 @@ USBH_StatusTypeDef USBH_MSC_BOT_Process (USBH_HandleTypeDef *phost, uint8_t lun)
break;
case BOT_DATA_IN:
if (MSC_Handle->hbot.pbuf != NULL)
{
//Simple single-buffer operation
MSC_Handle->hbot.state = BOT_DATA_IN_WAIT;
MSC_Handle->hbot.this_URB_size = MIN(MSC_Handle->hbot.cbw.field.DataTransferLength,
MSC_Handle->InEpSize);
USBH_BulkReceiveData (phost,
MSC_Handle->hbot.pbuf,
MSC_Handle->hbot.this_URB_size,
MSC_Handle->InPipe);
}
else
{
//Asynchronous multi-packet operation: get first packet
MSC_Handle->hbot.state = BOT_DATA_IN_WAIT_FREE_PACKET;
Callback_MSC_phost = phost;
if (Downstream_GetFreePacket(USBH_MSC_BOT_Read_Multipacket_FreePacketCallback) != HAL_OK)
{
MSC_Handle->hbot.state = BOT_ERROR_IN;
}
}
break;
if (MSC_Handle->hbot.pbuf != NULL)
{
//Simple single-buffer operation
MSC_Handle->hbot.state = BOT_DATA_IN_WAIT;
MSC_Handle->hbot.this_URB_size = MIN(MSC_Handle->hbot.cbw.field.DataTransferLength,
MSC_Handle->InEpSize);
USBH_BulkReceiveData (phost,
MSC_Handle->hbot.pbuf,
MSC_Handle->hbot.this_URB_size,
MSC_Handle->InPipe);
}
else
{
//Asynchronous multi-packet operation: get first packet
MSC_Handle->hbot.state = BOT_DATA_IN_WAIT_FREE_PACKET;
Callback_MSC_phost = phost;
if (Downstream_GetFreePacket(USBH_MSC_BOT_Read_Multipacket_FreePacketCallback) != HAL_OK)
{
MSC_Handle->hbot.state = BOT_ERROR_IN;
}
}
break;
case BOT_DATA_IN_WAIT_FREE_PACKET:
break;
break;
case BOT_DATA_IN_WAIT:
URB_Status = USBH_LL_GetURBState(phost, MSC_Handle->InPipe);
if (URB_Status == USBH_URB_DONE)
{
if (USBH_LL_GetLastXferSize(phost, MSC_Handle->InPipe) != MSC_Handle->hbot.this_URB_size)
{
while(1);
}
MSC_Handle->hbot.cbw.field.DataTransferLength -= MSC_Handle->hbot.this_URB_size;
if (MSC_Handle->hbot.pbuf != NULL)
{
//Simple single-buffer operation: everything must fit in one URB
MSC_Handle->hbot.state = BOT_RECEIVE_CSW;
}
else
{
//Asynchronous multi-packet operation
MSC_Handle->hbot.bot_packet_bytes_remaining -= MSC_Handle->hbot.this_URB_size;
MSC_Handle->hbot.bot_packet_pbuf += MSC_Handle->hbot.this_URB_size;
if (MSC_Handle->hbot.cbw.field.DataTransferLength == 0)
{
//End of reception: dispatch last packet
MSC_Handle->hbot.state = BOT_RECEIVE_CSW;
Downstream_MSC_PutStreamDataPacket(MSC_Handle->hbot.bot_packet,
(BOT_PAGE_LENGTH - MSC_Handle->hbot.bot_packet_bytes_remaining));
}
else
{
//Still more data to receive
if (MSC_Handle->hbot.bot_packet_bytes_remaining == 0)
{
//Dispatch current bot_packet, then get a new one
if (Downstream_MSC_PutStreamDataPacket(MSC_Handle->hbot.bot_packet,
(BOT_PAGE_LENGTH - MSC_Handle->hbot.bot_packet_bytes_remaining)) != HAL_OK)
{
MSC_Handle->hbot.state = BOT_ERROR_IN;
break;
}
MSC_Handle->hbot.state = BOT_DATA_IN_WAIT_FREE_PACKET;
if (Downstream_GetFreePacket(USBH_MSC_BOT_Read_Multipacket_FreePacketCallback) != HAL_OK)
{
MSC_Handle->hbot.state = BOT_ERROR_IN;
break;
}
}
else
{
//Continue filling the current bot_packet
USBH_MSC_BOT_Read_Multipacket_PrepareURB(phost);
}
}
}
if (USBH_LL_GetLastXferSize(phost, MSC_Handle->InPipe) != MSC_Handle->hbot.this_URB_size)
{
while(1);
}
MSC_Handle->hbot.cbw.field.DataTransferLength -= MSC_Handle->hbot.this_URB_size;
if (MSC_Handle->hbot.pbuf != NULL)
{
//Simple single-buffer operation: everything must fit in one URB
MSC_Handle->hbot.state = BOT_RECEIVE_CSW;
}
else
{
//Asynchronous multi-packet operation
MSC_Handle->hbot.bot_packet_bytes_remaining -= MSC_Handle->hbot.this_URB_size;
MSC_Handle->hbot.bot_packet_pbuf += MSC_Handle->hbot.this_URB_size;
if (MSC_Handle->hbot.cbw.field.DataTransferLength == 0)
{
//End of reception: dispatch last packet
MSC_Handle->hbot.state = BOT_RECEIVE_CSW;
Downstream_MSC_PutStreamDataPacket(MSC_Handle->hbot.bot_packet,
(BOT_PAGE_LENGTH - MSC_Handle->hbot.bot_packet_bytes_remaining));
}
else
{
//Still more data to receive
if (MSC_Handle->hbot.bot_packet_bytes_remaining == 0)
{
//Dispatch current bot_packet, then get a new one
if (Downstream_MSC_PutStreamDataPacket(MSC_Handle->hbot.bot_packet,
(BOT_PAGE_LENGTH - MSC_Handle->hbot.bot_packet_bytes_remaining)) != HAL_OK)
{
MSC_Handle->hbot.state = BOT_ERROR_IN;
break;
}
MSC_Handle->hbot.state = BOT_DATA_IN_WAIT_FREE_PACKET;
if (Downstream_GetFreePacket(USBH_MSC_BOT_Read_Multipacket_FreePacketCallback) != HAL_OK)
{
MSC_Handle->hbot.state = BOT_ERROR_IN;
break;
}
}
else
{
//Continue filling the current bot_packet
USBH_MSC_BOT_Read_Multipacket_PrepareURB(phost);
}
}
}
}
else if (URB_Status == USBH_URB_STALL)
@ -279,89 +279,89 @@ USBH_StatusTypeDef USBH_MSC_BOT_Process (USBH_HandleTypeDef *phost, uint8_t lun)
break;
case BOT_DATA_OUT:
if (MSC_Handle->hbot.pbuf != NULL)
{
//Simple single-buffer operation
MSC_Handle->hbot.state = BOT_DATA_OUT_WAIT;
MSC_Handle->hbot.this_URB_size = MIN(MSC_Handle->hbot.cbw.field.DataTransferLength,
MSC_Handle->OutEpSize);
USBH_BulkSendData (phost,
MSC_Handle->hbot.pbuf,
MSC_Handle->hbot.this_URB_size,
MSC_Handle->OutPipe,
1);
}
else
{
//Asynchronous multi-packet operation: get first packet
MSC_Handle->hbot.state = BOT_DATA_OUT_WAIT_RECEIVE_PACKET;
Callback_MSC_phost = phost;
if (Downstream_MSC_GetStreamDataPacket(USBH_MSC_BOT_Write_Multipacket_ReceivePacketCallback) != HAL_OK)
{
MSC_Handle->hbot.state = BOT_ERROR_OUT;
}
}
break;
if (MSC_Handle->hbot.pbuf != NULL)
{
//Simple single-buffer operation
MSC_Handle->hbot.state = BOT_DATA_OUT_WAIT;
MSC_Handle->hbot.this_URB_size = MIN(MSC_Handle->hbot.cbw.field.DataTransferLength,
MSC_Handle->OutEpSize);
USBH_BulkSendData (phost,
MSC_Handle->hbot.pbuf,
MSC_Handle->hbot.this_URB_size,
MSC_Handle->OutPipe,
1);
}
else
{
//Asynchronous multi-packet operation: get first packet
MSC_Handle->hbot.state = BOT_DATA_OUT_WAIT_RECEIVE_PACKET;
Callback_MSC_phost = phost;
if (Downstream_MSC_GetStreamDataPacket(USBH_MSC_BOT_Write_Multipacket_ReceivePacketCallback) != HAL_OK)
{
MSC_Handle->hbot.state = BOT_ERROR_OUT;
}
}
break;
case BOT_DATA_OUT_WAIT_RECEIVE_PACKET:
break;
break;
case BOT_DATA_OUT_WAIT:
URB_Status = USBH_LL_GetURBState(phost, MSC_Handle->OutPipe);
if(URB_Status == USBH_URB_DONE)
{
MSC_Handle->hbot.cbw.field.DataTransferLength -= MSC_Handle->hbot.this_URB_size;
if (MSC_Handle->hbot.pbuf != NULL)
{
//Simple single-buffer operation: everything must fit in one URB
MSC_Handle->hbot.state = BOT_RECEIVE_CSW;
}
else
{
//Asynchronous multi-packet operation
MSC_Handle->hbot.bot_packet_bytes_remaining -= MSC_Handle->hbot.this_URB_size;
MSC_Handle->hbot.bot_packet_pbuf += MSC_Handle->hbot.this_URB_size;
if (MSC_Handle->hbot.cbw.field.DataTransferLength == 0)
{
//End of transmission
Downstream_ReleasePacket(MSC_Handle->hbot.bot_packet);
MSC_Handle->hbot.state = BOT_RECEIVE_CSW;
}
else
{
//Still more data to send
if (MSC_Handle->hbot.bot_packet_bytes_remaining == 0)
{
//Get next bot_packet
Downstream_ReleasePacket(MSC_Handle->hbot.bot_packet);
MSC_Handle->hbot.state = BOT_DATA_OUT_WAIT_RECEIVE_PACKET;
if (Downstream_MSC_GetStreamDataPacket(USBH_MSC_BOT_Write_Multipacket_ReceivePacketCallback) != HAL_OK)
{
MSC_Handle->hbot.state = BOT_ERROR_OUT;
}
}
else
{
//Continue writing the current bot_packet
USBH_MSC_BOT_Write_Multipacket_PrepareURB(phost);
}
}
}
MSC_Handle->hbot.cbw.field.DataTransferLength -= MSC_Handle->hbot.this_URB_size;
if (MSC_Handle->hbot.pbuf != NULL)
{
//Simple single-buffer operation: everything must fit in one URB
MSC_Handle->hbot.state = BOT_RECEIVE_CSW;
}
else
{
//Asynchronous multi-packet operation
MSC_Handle->hbot.bot_packet_bytes_remaining -= MSC_Handle->hbot.this_URB_size;
MSC_Handle->hbot.bot_packet_pbuf += MSC_Handle->hbot.this_URB_size;
if (MSC_Handle->hbot.cbw.field.DataTransferLength == 0)
{
//End of transmission
Downstream_ReleasePacket(MSC_Handle->hbot.bot_packet);
MSC_Handle->hbot.state = BOT_RECEIVE_CSW;
}
else
{
//Still more data to send
if (MSC_Handle->hbot.bot_packet_bytes_remaining == 0)
{
//Get next bot_packet
Downstream_ReleasePacket(MSC_Handle->hbot.bot_packet);
MSC_Handle->hbot.state = BOT_DATA_OUT_WAIT_RECEIVE_PACKET;
if (Downstream_MSC_GetStreamDataPacket(USBH_MSC_BOT_Write_Multipacket_ReceivePacketCallback) != HAL_OK)
{
MSC_Handle->hbot.state = BOT_ERROR_OUT;
}
}
else
{
//Continue writing the current bot_packet
USBH_MSC_BOT_Write_Multipacket_PrepareURB(phost);
}
}
}
}
else if(URB_Status == USBH_URB_NOTREADY)
{
/* Resend same data */
if (MSC_Handle->hbot.pbuf != NULL)
{
MSC_Handle->hbot.state = BOT_DATA_OUT;
}
else
{
USBH_MSC_BOT_Write_Multipacket_PrepareURB(phost);
}
if (MSC_Handle->hbot.pbuf != NULL)
{
MSC_Handle->hbot.state = BOT_DATA_OUT;
}
else
{
USBH_MSC_BOT_Write_Multipacket_PrepareURB(phost);
}
}
else if(URB_Status == USBH_URB_STALL)
@ -462,85 +462,85 @@ USBH_StatusTypeDef USBH_MSC_BOT_Process (USBH_HandleTypeDef *phost, uint8_t lun)
void USBH_MSC_BOT_Read_Multipacket_FreePacketCallback(DownstreamPacketTypeDef* freePacket)
{
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) Callback_MSC_phost->pActiveClass->pData;
if (MSC_Handle->hbot.state != BOT_DATA_IN_WAIT_FREE_PACKET)
{
Downstream_PacketProcessor_FreakOut();
return;
}
MSC_Handle->hbot.state = BOT_DATA_IN_WAIT;
MSC_Handle->hbot.bot_packet = freePacket;
MSC_Handle->hbot.bot_packet_pbuf = freePacket->Data;
MSC_Handle->hbot.bot_packet_bytes_remaining = BOT_PAGE_LENGTH;
USBH_MSC_BOT_Read_Multipacket_PrepareURB(Callback_MSC_phost);
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) Callback_MSC_phost->pActiveClass->pData;
if (MSC_Handle->hbot.state != BOT_DATA_IN_WAIT_FREE_PACKET)
{
Downstream_PacketProcessor_FreakOut();
return;
}
MSC_Handle->hbot.state = BOT_DATA_IN_WAIT;
MSC_Handle->hbot.bot_packet = freePacket;
MSC_Handle->hbot.bot_packet_pbuf = freePacket->Data;
MSC_Handle->hbot.bot_packet_bytes_remaining = BOT_PAGE_LENGTH;
USBH_MSC_BOT_Read_Multipacket_PrepareURB(Callback_MSC_phost);
}
void USBH_MSC_BOT_Read_Multipacket_PrepareURB(USBH_HandleTypeDef *phost)
{
uint32_t temp_URB_size;
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
temp_URB_size = MSC_Handle->hbot.cbw.field.DataTransferLength;
if (temp_URB_size > MSC_Handle->hbot.bot_packet_bytes_remaining)
{
temp_URB_size = MSC_Handle->hbot.bot_packet_bytes_remaining;
}
if (temp_URB_size > MSC_Handle->InEpSize)
{
temp_URB_size = MSC_Handle->InEpSize;
}
MSC_Handle->hbot.this_URB_size = (uint16_t)temp_URB_size;
USBH_BulkReceiveData(phost,
MSC_Handle->hbot.bot_packet_pbuf,
MSC_Handle->hbot.this_URB_size,
MSC_Handle->InPipe);
uint32_t temp_URB_size;
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
temp_URB_size = MSC_Handle->hbot.cbw.field.DataTransferLength;
if (temp_URB_size > MSC_Handle->hbot.bot_packet_bytes_remaining)
{
temp_URB_size = MSC_Handle->hbot.bot_packet_bytes_remaining;
}
if (temp_URB_size > MSC_Handle->InEpSize)
{
temp_URB_size = MSC_Handle->InEpSize;
}
MSC_Handle->hbot.this_URB_size = (uint16_t)temp_URB_size;
USBH_BulkReceiveData(phost,
MSC_Handle->hbot.bot_packet_pbuf,
MSC_Handle->hbot.this_URB_size,
MSC_Handle->InPipe);
}
void USBH_MSC_BOT_Write_Multipacket_ReceivePacketCallback(DownstreamPacketTypeDef* receivedPacket,
uint16_t dataLength)
uint16_t dataLength)
{
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) Callback_MSC_phost->pActiveClass->pData;
if (MSC_Handle->hbot.state != BOT_DATA_OUT_WAIT_RECEIVE_PACKET)
{
Downstream_PacketProcessor_FreakOut();
return;
}
MSC_Handle->hbot.state = BOT_DATA_OUT_WAIT;
MSC_Handle->hbot.bot_packet = receivedPacket;
MSC_Handle->hbot.bot_packet_pbuf = receivedPacket->Data;
MSC_Handle->hbot.bot_packet_bytes_remaining = dataLength;
USBH_MSC_BOT_Write_Multipacket_PrepareURB(Callback_MSC_phost);
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) Callback_MSC_phost->pActiveClass->pData;
if (MSC_Handle->hbot.state != BOT_DATA_OUT_WAIT_RECEIVE_PACKET)
{
Downstream_PacketProcessor_FreakOut();
return;
}
MSC_Handle->hbot.state = BOT_DATA_OUT_WAIT;
MSC_Handle->hbot.bot_packet = receivedPacket;
MSC_Handle->hbot.bot_packet_pbuf = receivedPacket->Data;
MSC_Handle->hbot.bot_packet_bytes_remaining = dataLength;
USBH_MSC_BOT_Write_Multipacket_PrepareURB(Callback_MSC_phost);
}
void USBH_MSC_BOT_Write_Multipacket_PrepareURB(USBH_HandleTypeDef *phost)
{
uint32_t temp_URB_size;
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
temp_URB_size = MSC_Handle->hbot.cbw.field.DataTransferLength;
if (temp_URB_size > MSC_Handle->hbot.bot_packet_bytes_remaining)
{
temp_URB_size = MSC_Handle->hbot.bot_packet_bytes_remaining;
}
if (temp_URB_size > MSC_Handle->OutEpSize)
{
temp_URB_size = MSC_Handle->OutEpSize;
}
MSC_Handle->hbot.this_URB_size = (uint16_t)temp_URB_size;
USBH_BulkSendData (phost,
MSC_Handle->hbot.bot_packet_pbuf,
MSC_Handle->hbot.this_URB_size,
MSC_Handle->OutPipe,
1);
uint32_t temp_URB_size;
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
temp_URB_size = MSC_Handle->hbot.cbw.field.DataTransferLength;
if (temp_URB_size > MSC_Handle->hbot.bot_packet_bytes_remaining)
{
temp_URB_size = MSC_Handle->hbot.bot_packet_bytes_remaining;
}
if (temp_URB_size > MSC_Handle->OutEpSize)
{
temp_URB_size = MSC_Handle->OutEpSize;
}
MSC_Handle->hbot.this_URB_size = (uint16_t)temp_URB_size;
USBH_BulkSendData (phost,
MSC_Handle->hbot.bot_packet_pbuf,
MSC_Handle->hbot.this_URB_size,
MSC_Handle->OutPipe,
1);
}

@ -67,7 +67,7 @@
#define HOST_USER_CONNECTION 4
#define HOST_USER_DISCONNECTION 5
#define HOST_USER_UNRECOVERED_ERROR 6
#define HOST_USER_CLASS_FAILED 7
#define HOST_USER_CLASS_FAILED 7
/**
* @}

@ -541,7 +541,7 @@ USBH_StatusTypeDef USBH_Process(USBH_HandleTypeDef *phost)
}
else
{
phost->pUser(phost, HOST_USER_CLASS_FAILED);
phost->pUser(phost, HOST_USER_CLASS_FAILED);
phost->gState = HOST_ABORT_STATE;
USBH_UsrLog ("No registered class for this device.");
}

@ -146,14 +146,14 @@ USBH_StatusTypeDef USBH_Get_CfgDesc(USBH_HandleTypeDef *phost,
if (length > USBH_MAX_SIZE_CONFIGURATION)
{
length = USBH_MAX_SIZE_CONFIGURATION;
length = USBH_MAX_SIZE_CONFIGURATION;
}
#else
pData = phost->device.Data;
if (length > USBH_MAX_DATA_BUFFER)
{
length = USBH_MAX_DATA_BUFFER;
length = USBH_MAX_DATA_BUFFER;
}
#endif
if((status = USBH_GetDescriptor(phost,
@ -601,8 +601,8 @@ static USBH_StatusTypeDef USBH_HandleControl (USBH_HandleTypeDef *phost)
case CTRL_SETUP:
/* send a SETUP packet */
USBH_CtlSendSetup (phost,
(uint8_t *)phost->Control.setup.d8 ,
phost->Control.pipe_out);
(uint8_t *)phost->Control.setup.d8 ,
phost->Control.pipe_out);
phost->Control.state = CTRL_SETUP_WAIT;
break;

@ -143,7 +143,7 @@ uint8_t USBH_AllocPipe (USBH_HandleTypeDef *phost, uint8_t ep_addr)
if (pipe != 0xFFFF)
{
phost->Pipes[pipe] = 0x8000 | ep_addr;
phost->Pipes[pipe] = 0x8000 | ep_addr;
}
return pipe;
}
@ -159,7 +159,7 @@ USBH_StatusTypeDef USBH_FreePipe (USBH_HandleTypeDef *phost, uint8_t idx)
{
if(idx < 11)
{
phost->Pipes[idx] &= 0x7FFF;
phost->Pipes[idx] &= 0x7FFF;
}
return USBH_OK;
}
@ -176,10 +176,10 @@ static uint16_t USBH_GetFreePipe (USBH_HandleTypeDef *phost)
for (idx = 0 ; idx < 11 ; idx++)
{
if ((phost->Pipes[idx] & 0x8000) == 0)
{
return idx;
}
if ((phost->Pipes[idx] & 0x8000) == 0)
{
return idx;
}
}
return 0xFFFF;
}

@ -17,14 +17,14 @@
#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;
DownstreamMSCCallbackPacketTypeDef GetStreamDataCallback;
uint32_t ByteCount;
DownstreamPacketTypeDef* ReadStreamPacket;
uint8_t ReadStreamBusy;
void Downstream_MSC_PacketProcessor_TestUnitReady(DownstreamPacketTypeDef* receivedPacket);
@ -39,248 +39,248 @@ void Downstream_MSC_GetStreamDataPacketCallback(DownstreamPacketTypeDef* receive
//configured device to bomb our USB stack, accidentally or otherwise.
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[MSC_FIXED_LUN].error != MSC_OK)
{
return HAL_ERROR;
}
if (MSC_Handle->unit[MSC_FIXED_LUN].error != MSC_OK)
{
return HAL_ERROR;
}
if ((MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr == 0) ||
(MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr == UINT32_MAX))
{
return HAL_ERROR;
}
if ((MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr == 0) ||
(MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr == UINT32_MAX))
{
return HAL_ERROR;
}
if (MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_size != MSC_SUPPORTED_BLOCK_SIZE)
{
return HAL_ERROR;
}
if (MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_size != MSC_SUPPORTED_BLOCK_SIZE)
{
return HAL_ERROR;
}
return HAL_OK;
return HAL_OK;
}
void Downstream_MSC_PacketProcessor(DownstreamPacketTypeDef* receivedPacket)
{
switch (receivedPacket->Command)
{
case COMMAND_MSC_TEST_UNIT_READY:
Downstream_MSC_PacketProcessor_TestUnitReady(receivedPacket);
break;
switch (receivedPacket->Command)
{
case COMMAND_MSC_TEST_UNIT_READY:
Downstream_MSC_PacketProcessor_TestUnitReady(receivedPacket);
break;
case COMMAND_MSC_GET_CAPACITY:
Downstream_MSC_PacketProcessor_GetCapacity(receivedPacket);
break;
case COMMAND_MSC_GET_CAPACITY:
Downstream_MSC_PacketProcessor_GetCapacity(receivedPacket);
break;
case COMMAND_MSC_READ:
Downstream_MSC_PacketProcessor_BeginRead(receivedPacket);
break;
case COMMAND_MSC_READ:
Downstream_MSC_PacketProcessor_BeginRead(receivedPacket);
break;
case COMMAND_MSC_WRITE:
Downstream_MSC_PacketProcessor_BeginWrite(receivedPacket);
break;
case COMMAND_MSC_WRITE:
Downstream_MSC_PacketProcessor_BeginWrite(receivedPacket);
break;
default:
Downstream_PacketProcessor_FreakOut();
}
default:
Downstream_PacketProcessor_FreakOut();
}
}
void Downstream_MSC_PacketProcessor_TestUnitReady(DownstreamPacketTypeDef* receivedPacket)
{
if (USBH_MSC_UnitIsReady(&hUsbHostFS, MSC_FIXED_LUN))
{
receivedPacket->Data[0] = HAL_OK;
}
else
{
receivedPacket->Data[0] = HAL_ERROR;
}
receivedPacket->Length16 = DOWNSTREAM_PACKET_HEADER_LEN_16 + 1;
Downstream_PacketProcessor_ClassReply(receivedPacket);
if (USBH_MSC_UnitIsReady(&hUsbHostFS, MSC_FIXED_LUN))
{
receivedPacket->Data[0] = HAL_OK;
}
else
{
receivedPacket->Data[0] = HAL_ERROR;
}
receivedPacket->Length16 = DOWNSTREAM_PACKET_HEADER_LEN_16 + 1;
Downstream_PacketProcessor_ClassReply(receivedPacket);
}
void Downstream_MSC_PacketProcessor_GetCapacity(DownstreamPacketTypeDef* receivedPacket)
{
MSC_HandleTypeDef* MSC_Handle = (MSC_HandleTypeDef*)hUsbHostFS.pActiveClass->pData;
MSC_HandleTypeDef* MSC_Handle = (MSC_HandleTypeDef*)hUsbHostFS.pActiveClass->pData;
receivedPacket->Length16 = DOWNSTREAM_PACKET_HEADER_LEN_16 + (8 / 2);
*(uint32_t*)&(receivedPacket->Data[0]) = MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr;
*(uint32_t*)&(receivedPacket->Data[4]) = (uint32_t)MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_size;
Downstream_PacketProcessor_ClassReply(receivedPacket);
receivedPacket->Length16 = DOWNSTREAM_PACKET_HEADER_LEN_16 + (8 / 2);
*(uint32_t*)&(receivedPacket->Data[0]) = MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr;
*(uint32_t*)&(receivedPacket->Data[4]) = (uint32_t)MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_size;
Downstream_PacketProcessor_ClassReply(receivedPacket);
}
void Downstream_MSC_PacketProcessor_BeginRead(DownstreamPacketTypeDef* receivedPacket)
{
uint64_t readBlockAddress;
uint32_t readBlockCount;
uint64_t readByteCount;
MSC_HandleTypeDef* MSC_Handle = (MSC_HandleTypeDef*)hUsbHostFS.pActiveClass->pData;
if (receivedPacket->Length16 != (DOWNSTREAM_PACKET_HEADER_LEN_16 + ((4 * 3) / 2)))
{
Downstream_PacketProcessor_FreakOut();
return;
}
readBlockAddress = *(uint64_t*)&(receivedPacket->Data[0]);
readBlockCount = *(uint32_t*)&(receivedPacket->Data[8]);
readByteCount = readBlockCount * MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_size;
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))
{
Downstream_PacketProcessor_FreakOut();
return;
}
receivedPacket->Data[0] = HAL_ERROR;
receivedPacket->Length16 = DOWNSTREAM_PACKET_HEADER_LEN_16 + 1;
if (USBH_MSC_UnitIsReady(&hUsbHostFS, MSC_FIXED_LUN))
{
if (USBH_MSC_Read(&hUsbHostFS,
MSC_FIXED_LUN,
(uint32_t)readBlockAddress,
readBlockCount,
Downstream_MSC_PacketProcessor_RdWrCompleteCallback) == USBH_OK)
{
receivedPacket->Data[0] = HAL_OK;
}
}
Downstream_TransmitPacket(receivedPacket);
uint64_t readBlockAddress;
uint32_t readBlockCount;
uint64_t readByteCount;
MSC_HandleTypeDef* MSC_Handle = (MSC_HandleTypeDef*)hUsbHostFS.pActiveClass->pData;
if (receivedPacket->Length16 != (DOWNSTREAM_PACKET_HEADER_LEN_16 + ((4 * 3) / 2)))
{
Downstream_PacketProcessor_FreakOut();
return;
}
readBlockAddress = *(uint64_t*)&(receivedPacket->Data[0]);
readBlockCount = *(uint32_t*)&(receivedPacket->Data[8]);
readByteCount = readBlockCount * MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_size;
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))
{
Downstream_PacketProcessor_FreakOut();
return;
}
receivedPacket->Data[0] = HAL_ERROR;
receivedPacket->Length16 = DOWNSTREAM_PACKET_HEADER_LEN_16 + 1;
if (USBH_MSC_UnitIsReady(&hUsbHostFS, MSC_FIXED_LUN))
{
if (USBH_MSC_Read(&hUsbHostFS,
MSC_FIXED_LUN,
(uint32_t)readBlockAddress,
readBlockCount,
Downstream_MSC_PacketProcessor_RdWrCompleteCallback) == USBH_OK)
{
receivedPacket->Data[0] = HAL_OK;
}
}
Downstream_TransmitPacket(receivedPacket);
}
void Downstream_MSC_PacketProcessor_RdWrCompleteCallback(USBH_StatusTypeDef result)
{
if (result != USBH_OK)
{
Downstream_GetFreePacket(Downstream_PacketProcessor_GenericErrorReply);
return;
}
Downstream_ReceivePacket(Downstream_PacketProcessor);
if (result != USBH_OK)
{
Downstream_GetFreePacket(Downstream_PacketProcessor_GenericErrorReply);
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->Length16 != (DOWNSTREAM_PACKET_HEADER_LEN_16 + ((4 * 3) / 2)))
{
Downstream_PacketProcessor_FreakOut();
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))
{
Downstream_PacketProcessor_FreakOut();
return;
}
ReadStreamPacket = NULL; //Prepare for GetStreamDataPacket's use
ReadStreamBusy = 0;
ByteCount = (uint32_t)writeByteCount;
receivedPacket->Data[0] = HAL_ERROR;
receivedPacket->Length16 = DOWNSTREAM_PACKET_HEADER_LEN_16 + 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);
uint64_t writeBlockAddress;
uint32_t writeBlockCount;
uint64_t writeByteCount;
MSC_HandleTypeDef* MSC_Handle = (MSC_HandleTypeDef*)hUsbHostFS.pActiveClass->pData;
if (receivedPacket->Length16 != (DOWNSTREAM_PACKET_HEADER_LEN_16 + ((4 * 3) / 2)))
{
Downstream_PacketProcessor_FreakOut();
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))
{
Downstream_PacketProcessor_FreakOut();
return;
}
ReadStreamPacket = NULL; //Prepare for GetStreamDataPacket's use
ReadStreamBusy = 0;
ByteCount = (uint32_t)writeByteCount;
receivedPacket->Data[0] = HAL_ERROR;
receivedPacket->Length16 = DOWNSTREAM_PACKET_HEADER_LEN_16 + 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);
}
//Used by USB MSC host driver
HAL_StatusTypeDef Downstream_MSC_PutStreamDataPacket(DownstreamPacketTypeDef* packetToSend,
uint32_t dataLength8)
uint32_t dataLength8)
{
if ((dataLength8 % 2) != 0)
{
return HAL_ERROR;
}
packetToSend->Length16 = (dataLength8 / 2) + DOWNSTREAM_PACKET_HEADER_LEN_16;
packetToSend->CommandClass = COMMAND_CLASS_MASS_STORAGE | COMMAND_CLASS_DATA_FLAG;
packetToSend->Command = COMMAND_MSC_READ;
return Downstream_TransmitPacket(packetToSend);
if ((dataLength8 % 2) != 0)
{
return HAL_ERROR;
}
packetToSend->Length16 = (dataLength8 / 2) + DOWNSTREAM_PACKET_HEADER_LEN_16;
packetToSend->CommandClass = COMMAND_CLASS_MASS_STORAGE | COMMAND_CLASS_DATA_FLAG;
packetToSend->Command = COMMAND_MSC_READ;
return Downstream_TransmitPacket(packetToSend);
}
//Used by USB MSC host driver
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);
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* receivedPacket)
{
uint16_t dataLength8;
ReadStreamBusy = 0;
if (GetStreamDataCallback == NULL)
{
ReadStreamPacket = receivedPacket; //We used up our callback already, so save this one for later.
return;
}
dataLength8 = (receivedPacket->Length16 - DOWNSTREAM_PACKET_HEADER_LEN_16) * 2;
if ((receivedPacket->CommandClass != (COMMAND_CLASS_MASS_STORAGE | COMMAND_CLASS_DATA_FLAG)) || //Must be MSC command with data flag set
(receivedPacket->Command != COMMAND_MSC_WRITE) || //Must be write command
(receivedPacket->Length16 <= DOWNSTREAM_PACKET_HEADER_LEN_16) || //Should be at least one data byte in the packet.
(dataLength8 > ByteCount))
{
Downstream_PacketProcessor_FreakOut();
return;
}
ByteCount -= dataLength8;
GetStreamDataCallback(receivedPacket, dataLength8); //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
}
uint16_t dataLength8;
ReadStreamBusy = 0;
if (GetStreamDataCallback == NULL)
{
ReadStreamPacket = receivedPacket; //We used up our callback already, so save this one for later.
return;
}
dataLength8 = (receivedPacket->Length16 - DOWNSTREAM_PACKET_HEADER_LEN_16) * 2;
if ((receivedPacket->CommandClass != (COMMAND_CLASS_MASS_STORAGE | COMMAND_CLASS_DATA_FLAG)) || //Must be MSC command with data flag set
(receivedPacket->Command != COMMAND_MSC_WRITE) || //Must be write command
(receivedPacket->Length16 <= DOWNSTREAM_PACKET_HEADER_LEN_16) || //Should be at least one data byte in the packet.
(dataLength8 > ByteCount))
{
Downstream_PacketProcessor_FreakOut();
return;
}
ByteCount -= dataLength8;
GetStreamDataCallback(receivedPacket, dataLength8); //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
}
}

@ -17,18 +17,18 @@
#include "led.h"
SPI_HandleTypeDef Hspi1;
DownstreamPacketTypeDef DownstreamPacket0;
DownstreamPacketTypeDef DownstreamPacket1;
DownstreamPacketTypeDef* CurrentWorkingPacket;
DownstreamPacketTypeDef* NextTxPacket = NULL;
SPI_HandleTypeDef Hspi1;
DownstreamPacketTypeDef DownstreamPacket0;
DownstreamPacketTypeDef DownstreamPacket1;
DownstreamPacketTypeDef* CurrentWorkingPacket;
DownstreamPacketTypeDef* NextTxPacket = NULL;
InterfaceStateTypeDef DownstreamInterfaceState = DOWNSTREAM_INTERFACE_IDLE;
FreePacketCallbackTypeDef PendingFreePacketCallback = NULL; //Indicates someone is waiting for a packet buffer to become available
SpiPacketReceivedCallbackTypeDef ReceivePacketCallback = NULL; //Indicates someone is waiting for a received packet
InterfaceStateTypeDef DownstreamInterfaceState = DOWNSTREAM_INTERFACE_IDLE;
FreePacketCallbackTypeDef PendingFreePacketCallback = NULL; //Indicates someone is waiting for a packet buffer to become available
SpiPacketReceivedCallbackTypeDef ReceivePacketCallback = NULL; //Indicates someone is waiting for a received packet
uint32_t TemporaryIncomingPacketLength = 0;
uint8_t SpiInterruptCompleted = 0;
uint32_t TemporaryIncomingPacketLength = 0;
uint8_t SpiInterruptCompleted = 0;
HAL_StatusTypeDef Downstream_CheckPreparePacketReception(void);
@ -38,87 +38,87 @@ void Downstream_PrepareReceivePacketSize(DownstreamPacketTypeDef* freePacket);
void Downstream_InitSPI(void)
{
DownstreamPacket0.Busy = NOT_BUSY;
DownstreamPacket1.Busy = NOT_BUSY;
Hspi1.Instance = SPI1;
Hspi1.Init.Mode = SPI_MODE_SLAVE;
Hspi1.Init.Direction = SPI_DIRECTION_2LINES;
Hspi1.Init.DataSize = SPI_DATASIZE_16BIT;
Hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
Hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
Hspi1.Init.NSS = SPI_NSS_HARD_INPUT;
Hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
Hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
Hspi1.Init.TIMode = SPI_TIMODE_DISABLED;
Hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_ENABLE;
Hspi1.Init.CRCPolynomial = SPI_CRC_DEFAULTPOLYNOMIAL;
HAL_SPI_Init(&Hspi1);
DownstreamPacket0.Busy = NOT_BUSY;
DownstreamPacket1.Busy = NOT_BUSY;
Hspi1.Instance = SPI1;
Hspi1.Init.Mode = SPI_MODE_SLAVE;
Hspi1.Init.Direction = SPI_DIRECTION_2LINES;
Hspi1.Init.DataSize = SPI_DATASIZE_16BIT;
Hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
Hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
Hspi1.Init.NSS = SPI_NSS_HARD_INPUT;
Hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
Hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
Hspi1.Init.TIMode = SPI_TIMODE_DISABLED;
Hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_ENABLE;
Hspi1.Init.CRCPolynomial = SPI_CRC_DEFAULTPOLYNOMIAL;
HAL_SPI_Init(&Hspi1);
}
//Used by downstream state machine and USB host classes.
HAL_StatusTypeDef Downstream_GetFreePacket(FreePacketCallbackTypeDef callback)
{
if (DownstreamInterfaceState >= DOWNSTREAM_INTERFACE_ERROR)
{
return HAL_ERROR;
}
//Do we already have a queued callback?
if (PendingFreePacketCallback != NULL)
{
DOWNSTREAM_SPI_FREAKOUT;
return HAL_ERROR;
}
//Check if there is a free buffer now
if (DownstreamPacket0.Busy == NOT_BUSY)
{
DownstreamPacket0.Busy = BUSY;
callback(&DownstreamPacket0);
return HAL_OK;
}
if (DownstreamPacket1.Busy == NOT_BUSY)
{
DownstreamPacket1.Busy = BUSY;
callback(&DownstreamPacket1);
return HAL_OK;
}
//Otherwise save requested address for when a buffer becomes free in the future
PendingFreePacketCallback = callback;
return HAL_OK;
if (DownstreamInterfaceState >= DOWNSTREAM_INTERFACE_ERROR)
{
return HAL_ERROR;
}
//Do we already have a queued callback?
if (PendingFreePacketCallback != NULL)
{
DOWNSTREAM_SPI_FREAKOUT;
return HAL_ERROR;
}
//Check if there is a free buffer now
if (DownstreamPacket0.Busy == NOT_BUSY)
{
DownstreamPacket0.Busy = BUSY;
callback(&DownstreamPacket0);
return HAL_OK;
}
if (DownstreamPacket1.Busy == NOT_BUSY)
{
DownstreamPacket1.Busy = BUSY;
callback(&DownstreamPacket1);
return HAL_OK;
}
//Otherwise save requested address for when a buffer becomes free in the future
PendingFreePacketCallback = callback;
return HAL_OK;
}
//Used by Downstream state machine and USB host classes.
void Downstream_ReleasePacket(DownstreamPacketTypeDef* packetToRelease)
{
FreePacketCallbackTypeDef tempCallback;
if (DownstreamInterfaceState >= DOWNSTREAM_INTERFACE_ERROR)
{
return;
}
if ((packetToRelease != &DownstreamPacket0) &&
(packetToRelease != &DownstreamPacket1))
{
DOWNSTREAM_SPI_FREAKOUT;
return;
}
if (PendingFreePacketCallback != NULL)
{
tempCallback = PendingFreePacketCallback; //In extreme situations, running this callback can trigger another request for a free packet,
PendingFreePacketCallback = NULL; //thereby causing GetFreePacket to freak out. So we need to clear the callback indicator first.
tempCallback(packetToRelease);
}
else
{
packetToRelease->Busy = NOT_BUSY;
}
FreePacketCallbackTypeDef tempCallback;
if (DownstreamInterfaceState >= DOWNSTREAM_INTERFACE_ERROR)
{
return;
}
if ((packetToRelease != &DownstreamPacket0) &&
(packetToRelease != &DownstreamPacket1))
{
DOWNSTREAM_SPI_FREAKOUT;
return;
}
if (PendingFreePacketCallback != NULL)
{
tempCallback = PendingFreePacketCallback; //In extreme situations, running this callback can trigger another request for a free packet,
PendingFreePacketCallback = NULL; //thereby causing GetFreePacket to freak out. So we need to clear the callback indicator first.
tempCallback(packetToRelease);
}
else
{
packetToRelease->Busy = NOT_BUSY;
}
}
@ -127,66 +127,66 @@ void Downstream_ReleasePacket(DownstreamPacketTypeDef* packetToRelease)
//Not OK to call when receiving or awaiting reception.
HAL_StatusTypeDef Downstream_ReceivePacket(SpiPacketReceivedCallbackTypeDef callback)
{
if (DownstreamInterfaceState >= DOWNSTREAM_INTERFACE_ERROR)
{
return HAL_ERROR;
}
if ((DownstreamInterfaceState == DOWNSTREAM_INTERFACE_RX_SIZE_WAIT) ||
(DownstreamInterfaceState == DOWNSTREAM_INTERFACE_RX_PACKET_WAIT) ||
(ReceivePacketCallback != NULL))
{
DOWNSTREAM_SPI_FREAKOUT;
return HAL_ERROR;
}
ReceivePacketCallback = callback;
return Downstream_CheckPreparePacketReception();
if (DownstreamInterfaceState >= DOWNSTREAM_INTERFACE_ERROR)
{
return HAL_ERROR;
}
if ((DownstreamInterfaceState == DOWNSTREAM_INTERFACE_RX_SIZE_WAIT) ||
(DownstreamInterfaceState == DOWNSTREAM_INTERFACE_RX_PACKET_WAIT) ||
(ReceivePacketCallback != NULL))
{
DOWNSTREAM_SPI_FREAKOUT;
return HAL_ERROR;
}
ReceivePacketCallback = callback;
return Downstream_CheckPreparePacketReception();
}
//Internal use only
HAL_StatusTypeDef Downstream_CheckPreparePacketReception(void)
{
if (DownstreamInterfaceState >= DOWNSTREAM_INTERFACE_ERROR)
{
return HAL_ERROR;
}
if (DownstreamInterfaceState == DOWNSTREAM_INTERFACE_IDLE)
{
DownstreamInterfaceState = DOWNSTREAM_INTERFACE_RX_SIZE_WAIT;
return Downstream_GetFreePacket(Downstream_PrepareReceivePacketSize);
}
return HAL_OK;
if (DownstreamInterfaceState >= DOWNSTREAM_INTERFACE_ERROR)
{
return HAL_ERROR;
}
if (DownstreamInterfaceState == DOWNSTREAM_INTERFACE_IDLE)
{
DownstreamInterfaceState = DOWNSTREAM_INTERFACE_RX_SIZE_WAIT;
return Downstream_GetFreePacket(Downstream_PrepareReceivePacketSize);
}
return HAL_OK;
}
//Internal use only
void Downstream_PrepareReceivePacketSize(DownstreamPacketTypeDef* freePacket)
{
if (DownstreamInterfaceState >= DOWNSTREAM_INTERFACE_ERROR)
{
return;
}
if (DownstreamInterfaceState != DOWNSTREAM_INTERFACE_RX_SIZE_WAIT)
{
DOWNSTREAM_SPI_FREAKOUT;
return;
}
CurrentWorkingPacket = freePacket;
CurrentWorkingPacket->Length16 = 0;
if (HAL_SPI_TransmitReceive_DMA(&Hspi1,
(uint8_t*)&CurrentWorkingPacket->Length16,
(uint8_t*)&CurrentWorkingPacket->Length16,
2) != HAL_OK) //We only need to read one word, but the peripheral library freaks out...
{
DOWNSTREAM_SPI_FREAKOUT;
return;
}
UPSTREAM_TX_REQUEST_ASSERT;
if (DownstreamInterfaceState >= DOWNSTREAM_INTERFACE_ERROR)
{
return;
}
if (DownstreamInterfaceState != DOWNSTREAM_INTERFACE_RX_SIZE_WAIT)
{
DOWNSTREAM_SPI_FREAKOUT;
return;
}
CurrentWorkingPacket = freePacket;
CurrentWorkingPacket->Length16 = 0;
if (HAL_SPI_TransmitReceive_DMA(&Hspi1,
(uint8_t*)&CurrentWorkingPacket->Length16,
(uint8_t*)&CurrentWorkingPacket->Length16,
2) != HAL_OK) //We only need to read one word, but the peripheral library freaks out...
{
DOWNSTREAM_SPI_FREAKOUT;
return;
}
UPSTREAM_TX_REQUEST_ASSERT;
}
@ -196,59 +196,59 @@ void Downstream_PrepareReceivePacketSize(DownstreamPacketTypeDef* freePacket)
//It doesn't make sense to call when receiving or awaiting reception.
HAL_StatusTypeDef Downstream_TransmitPacket(DownstreamPacketTypeDef* packetToWrite)
{
if (DownstreamInterfaceState >= DOWNSTREAM_INTERFACE_ERROR)
{
return HAL_ERROR;
}
//Sanity checks
if ((packetToWrite != &DownstreamPacket0) &&
(packetToWrite != &DownstreamPacket1))
{
DOWNSTREAM_SPI_FREAKOUT;
return HAL_ERROR;
}
if ((packetToWrite->Busy != BUSY) ||
(packetToWrite->Length16 < DOWNSTREAM_PACKET_LEN_MIN_16) ||
(packetToWrite->Length16 > DOWNSTREAM_PACKET_LEN_16))
{
DOWNSTREAM_SPI_FREAKOUT;
return HAL_ERROR;
}
if (NextTxPacket != NULL)
{
DOWNSTREAM_SPI_FREAKOUT;
return HAL_ERROR;
}
switch (DownstreamInterfaceState)
{
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->Length16,
(uint8_t*)&TemporaryIncomingPacketLength,
2) != HAL_OK) //We only need to write one word, but the peripheral library freaks out...
{
DOWNSTREAM_SPI_FREAKOUT;
return HAL_ERROR;
}
UPSTREAM_TX_REQUEST_ASSERT;
break;
default:
DOWNSTREAM_SPI_FREAKOUT;
return HAL_ERROR;
}
return HAL_OK;
if (DownstreamInterfaceState >= DOWNSTREAM_INTERFACE_ERROR)
{
return HAL_ERROR;
}
//Sanity checks
if ((packetToWrite != &DownstreamPacket0) &&
(packetToWrite != &DownstreamPacket1))
{
DOWNSTREAM_SPI_FREAKOUT;
return HAL_ERROR;
}
if ((packetToWrite->Busy != BUSY) ||
(packetToWrite->Length16 < DOWNSTREAM_PACKET_LEN_MIN_16) ||
(packetToWrite->Length16 > DOWNSTREAM_PACKET_LEN_16))
{
DOWNSTREAM_SPI_FREAKOUT;
return HAL_ERROR;
}
if (NextTxPacket != NULL)
{
DOWNSTREAM_SPI_FREAKOUT;
return HAL_ERROR;
}
switch (DownstreamInterfaceState)
{
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->Length16,
(uint8_t*)&TemporaryIncomingPacketLength,
2) != HAL_OK) //We only need to write one word, but the peripheral library freaks out...
{
DOWNSTREAM_SPI_FREAKOUT;
return HAL_ERROR;
}
UPSTREAM_TX_REQUEST_ASSERT;
break;
default:
DOWNSTREAM_SPI_FREAKOUT;
return HAL_ERROR;
}
return HAL_OK;
}
@ -256,118 +256,118 @@ HAL_StatusTypeDef Downstream_TransmitPacket(DownstreamPacketTypeDef* packetToWri
//Do stuff at main loop priority after SPI transaction is complete
void Downstream_SPIProcess(void)
{
SpiPacketReceivedCallbackTypeDef tempPacketCallback;
if (SpiInterruptCompleted == 0)
{
return;
}
SpiInterruptCompleted = 0;
UPSTREAM_TX_REQUEST_DEASSERT;
if (DownstreamInterfaceState >= DOWNSTREAM_INTERFACE_ERROR)
{
return;
}
//Finished transmitting packet size
if (DownstreamInterfaceState == DOWNSTREAM_INTERFACE_TX_SIZE_WAIT)
{
if ((uint16_t)TemporaryIncomingPacketLength != 0)
{
//Currently we just freak out if Upstream sends us an unexpected command.
//Theoretically we could reset our downstream state machine and accept the new command...
DOWNSTREAM_SPI_FREAKOUT;
return;
}
DownstreamInterfaceState = DOWNSTREAM_INTERFACE_TX_PACKET_WAIT;
if (HAL_SPI_TransmitReceive_DMA(&Hspi1,
&CurrentWorkingPacket->CommandClass,
&CurrentWorkingPacket->CommandClass,
((CurrentWorkingPacket->Length16 < 2) ? 2 : CurrentWorkingPacket->Length16)) != HAL_OK)
{
DOWNSTREAM_SPI_FREAKOUT;
return;
}
UPSTREAM_TX_REQUEST_ASSERT;
return;
}
//Finished transmitting packet body
if (DownstreamInterfaceState == DOWNSTREAM_INTERFACE_TX_PACKET_WAIT)
{
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->Length16,
(uint8_t*)&TemporaryIncomingPacketLength,
2) != HAL_OK) //We only need to write one word, but the peripheral library freaks out...
{
DOWNSTREAM_SPI_FREAKOUT;
return;
}
UPSTREAM_TX_REQUEST_ASSERT;
return;
}
DownstreamInterfaceState = DOWNSTREAM_INTERFACE_IDLE;
if (ReceivePacketCallback != NULL)
{
Downstream_CheckPreparePacketReception();
}
return;
}
if (DownstreamInterfaceState == DOWNSTREAM_INTERFACE_RX_SIZE_WAIT)
{
if ((CurrentWorkingPacket->Length16 < DOWNSTREAM_PACKET_LEN_MIN_16) ||
(CurrentWorkingPacket->Length16 > DOWNSTREAM_PACKET_LEN_16))
{
DOWNSTREAM_SPI_FREAKOUT;
return;
}
DownstreamInterfaceState = DOWNSTREAM_INTERFACE_RX_PACKET_WAIT;
if (HAL_SPI_TransmitReceive_DMA(&Hspi1,
&CurrentWorkingPacket->CommandClass,
&CurrentWorkingPacket->CommandClass,
((CurrentWorkingPacket->Length16 < 2) ? 2 : CurrentWorkingPacket->Length16)) != HAL_OK)
{
DOWNSTREAM_SPI_FREAKOUT;
return;
}
UPSTREAM_TX_REQUEST_ASSERT;
return;
}
if (DownstreamInterfaceState == DOWNSTREAM_INTERFACE_RX_PACKET_WAIT)
{
DownstreamInterfaceState = DOWNSTREAM_INTERFACE_IDLE;
if (ReceivePacketCallback == NULL)
{
DOWNSTREAM_SPI_FREAKOUT;
return;
}
//Packet processor may want to receive another packet immediately,
//so clear ReceivePacketCallback before the call.
//It is the callback's responsibility to release the packet buffer we are passing to it!
tempPacketCallback = ReceivePacketCallback;
ReceivePacketCallback = NULL;
tempPacketCallback(CurrentWorkingPacket);
return;
}
//case default:
DOWNSTREAM_SPI_FREAKOUT;
SpiPacketReceivedCallbackTypeDef tempPacketCallback;
if (SpiInterruptCompleted == 0)
{
return;
}
SpiInterruptCompleted = 0;
UPSTREAM_TX_REQUEST_DEASSERT;
if (DownstreamInterfaceState >= DOWNSTREAM_INTERFACE_ERROR)
{
return;
}
//Finished transmitting packet size
if (DownstreamInterfaceState == DOWNSTREAM_INTERFACE_TX_SIZE_WAIT)
{
if ((uint16_t)TemporaryIncomingPacketLength != 0)
{
//Currently we just freak out if Upstream sends us an unexpected command.
//Theoretically we could reset our downstream state machine and accept the new command...
DOWNSTREAM_SPI_FREAKOUT;
return;
}
DownstreamInterfaceState = DOWNSTREAM_INTERFACE_TX_PACKET_WAIT;
if (HAL_SPI_TransmitReceive_DMA(&Hspi1,
&CurrentWorkingPacket->CommandClass,
&CurrentWorkingPacket->CommandClass,
((CurrentWorkingPacket->Length16 < 2) ? 2 : CurrentWorkingPacket->Length16)) != HAL_OK)
{
DOWNSTREAM_SPI_FREAKOUT;
return;
}
UPSTREAM_TX_REQUEST_ASSERT;
return;
}
//Finished transmitting packet body
if (DownstreamInterfaceState == DOWNSTREAM_INTERFACE_TX_PACKET_WAIT)
{
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->Length16,
(uint8_t*)&TemporaryIncomingPacketLength,
2) != HAL_OK) //We only need to write one word, but the peripheral library freaks out...
{
DOWNSTREAM_SPI_FREAKOUT;
return;
}
UPSTREAM_TX_REQUEST_ASSERT;
return;
}
DownstreamInterfaceState = DOWNSTREAM_INTERFACE_IDLE;
if (ReceivePacketCallback != NULL)
{
Downstream_CheckPreparePacketReception();
}
return;
}
if (DownstreamInterfaceState == DOWNSTREAM_INTERFACE_RX_SIZE_WAIT)
{
if ((CurrentWorkingPacket->Length16 < DOWNSTREAM_PACKET_LEN_MIN_16) ||
(CurrentWorkingPacket->Length16 > DOWNSTREAM_PACKET_LEN_16))
{
DOWNSTREAM_SPI_FREAKOUT;
return;
}
DownstreamInterfaceState = DOWNSTREAM_INTERFACE_RX_PACKET_WAIT;
if (HAL_SPI_TransmitReceive_DMA(&Hspi1,
&CurrentWorkingPacket->CommandClass,
&CurrentWorkingPacket->CommandClass,
((CurrentWorkingPacket->Length16 < 2) ? 2 : CurrentWorkingPacket->Length16)) != HAL_OK)
{
DOWNSTREAM_SPI_FREAKOUT;
return;
}
UPSTREAM_TX_REQUEST_ASSERT;
return;
}
if (DownstreamInterfaceState == DOWNSTREAM_INTERFACE_RX_PACKET_WAIT)
{
DownstreamInterfaceState = DOWNSTREAM_INTERFACE_IDLE;
if (ReceivePacketCallback == NULL)
{
DOWNSTREAM_SPI_FREAKOUT;
return;
}
//Packet processor may want to receive another packet immediately,
//so clear ReceivePacketCallback before the call.
//It is the callback's responsibility to release the packet buffer we are passing to it!
tempPacketCallback = ReceivePacketCallback;
ReceivePacketCallback = NULL;
tempPacketCallback(CurrentWorkingPacket);
return;
}
//case default:
DOWNSTREAM_SPI_FREAKOUT;
}
@ -380,7 +380,7 @@ void Downstream_SPIProcess(void)
//a transmit-only DMA transfer with CRC! (it does not clear RXNE flag on request)
void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)
{
SpiInterruptCompleted = 1;
SpiInterruptCompleted = 1;
}
@ -388,6 +388,6 @@ void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)
//Something bad happened! Possibly CRC error...
void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi)
{
DOWNSTREAM_SPI_FREAKOUT;
DOWNSTREAM_SPI_FREAKOUT;
}

@ -20,8 +20,8 @@
DownstreamStateTypeDef DownstreamState = STATE_DEVICE_NOT_READY;
InterfaceCommandClassTypeDef ConfiguredDeviceClass = COMMAND_CLASS_INTERFACE;
DownstreamStateTypeDef DownstreamState = STATE_DEVICE_NOT_READY;
InterfaceCommandClassTypeDef ConfiguredDeviceClass = COMMAND_CLASS_INTERFACE;
void Downstream_PacketProcessor_Interface(DownstreamPacketTypeDef* receivedPacket);
@ -31,61 +31,61 @@ void Downstream_PacketProcessor_Interface_ReplyNotifyDevice(DownstreamPacketType
void Downstream_InitStateMachine(void)
{
Downstream_InitSPI();
Downstream_InitSPI();
//Prepare to receive our first packet from Upstream!
Downstream_ReceivePacket(Downstream_PacketProcessor);
//Prepare to receive our first packet from Upstream!
Downstream_ReceivePacket(Downstream_PacketProcessor);
}
void Downstream_PacketProcessor(DownstreamPacketTypeDef* receivedPacket)
{
if (DownstreamState >= STATE_ERROR)
{
Downstream_ReleasePacket(receivedPacket);
return;
}
if (receivedPacket->CommandClass == COMMAND_CLASS_INTERFACE)
{
if (DownstreamState > STATE_DEVICE_READY)
{
DOWNSTREAM_STATEMACHINE_FREAKOUT;
return;
}
Downstream_PacketProcessor_Interface(receivedPacket);
return;
}
//If we get a class-specific message when our device is disconnected,
//we need to tell Upstream of the fact (and not freak out).
if (DownstreamState == STATE_DEVICE_NOT_READY)
{
receivedPacket->Length16 = DOWNSTREAM_PACKET_HEADER_LEN_16;
receivedPacket->CommandClass = COMMAND_CLASS_ERROR;
receivedPacket->Command = COMMAND_ERROR_DEVICE_DISCONNECTED;
Downstream_PacketProcessor_ClassReply(receivedPacket);
return;
}
//We should only receive class-specific messages when we are in the Active state.
if (DownstreamState != STATE_ACTIVE)
{
DOWNSTREAM_STATEMACHINE_FREAKOUT;
return;
}
switch (receivedPacket->CommandClass)
{
case COMMAND_CLASS_MASS_STORAGE:
Downstream_MSC_PacketProcessor(receivedPacket);
break;
//Add other classes here...
default:
DOWNSTREAM_STATEMACHINE_FREAKOUT;
}
if (DownstreamState >= STATE_ERROR)
{
Downstream_ReleasePacket(receivedPacket);
return;
}
if (receivedPacket->CommandClass == COMMAND_CLASS_INTERFACE)
{
if (DownstreamState > STATE_DEVICE_READY)
{
DOWNSTREAM_STATEMACHINE_FREAKOUT;
return;
}
Downstream_PacketProcessor_Interface(receivedPacket);
return;
}
//If we get a class-specific message when our device is disconnected,
//we need to tell Upstream of the fact (and not freak out).
if (DownstreamState == STATE_DEVICE_NOT_READY)
{
receivedPacket->Length16 = DOWNSTREAM_PACKET_HEADER_LEN_16;
receivedPacket->CommandClass = COMMAND_CLASS_ERROR;
receivedPacket->Command = COMMAND_ERROR_DEVICE_DISCONNECTED;
Downstream_PacketProcessor_ClassReply(receivedPacket);
return;
}
//We should only receive class-specific messages when we are in the Active state.
if (DownstreamState != STATE_ACTIVE)
{
DOWNSTREAM_STATEMACHINE_FREAKOUT;
return;
}
switch (receivedPacket->CommandClass)
{
case COMMAND_CLASS_MASS_STORAGE:
Downstream_MSC_PacketProcessor(receivedPacket);
break;
//Add other classes here...
default:
DOWNSTREAM_STATEMACHINE_FREAKOUT;
}
}
@ -93,73 +93,73 @@ void Downstream_PacketProcessor(DownstreamPacketTypeDef* receivedPacket)
//Used by downstream class interfaces, and SPI interface
void Downstream_PacketProcessor_FreakOut(void)
{
DOWNSTREAM_STATEMACHINE_FREAKOUT;
DOWNSTREAM_STATEMACHINE_FREAKOUT;
}
void Downstream_PacketProcessor_Interface(DownstreamPacketTypeDef* receivedPacket)
{
switch (receivedPacket->Command)
{
case COMMAND_INTERFACE_ECHO:
Downstream_TransmitPacket(receivedPacket);
Downstream_ReceivePacket(Downstream_PacketProcessor);
break;
case COMMAND_INTERFACE_NOTIFY_DEVICE:
if (DownstreamState == STATE_DEVICE_READY)
{
Downstream_PacketProcessor_Interface_ReplyNotifyDevice(receivedPacket);
return;
}
if (DownstreamState == STATE_DEVICE_NOT_READY)
{
DownstreamState = STATE_WAIT_DEVICE_READY;
Downstream_ReleasePacket(receivedPacket);
return;
}
DOWNSTREAM_STATEMACHINE_FREAKOUT;
break;
default:
DOWNSTREAM_STATEMACHINE_FREAKOUT;
}
switch (receivedPacket->Command)
{
case COMMAND_INTERFACE_ECHO:
Downstream_TransmitPacket(receivedPacket);
Downstream_ReceivePacket(Downstream_PacketProcessor);
break;
case COMMAND_INTERFACE_NOTIFY_DEVICE:
if (DownstreamState == STATE_DEVICE_READY)
{
Downstream_PacketProcessor_Interface_ReplyNotifyDevice(receivedPacket);
return;
}
if (DownstreamState == STATE_DEVICE_NOT_READY)
{
DownstreamState = STATE_WAIT_DEVICE_READY;
Downstream_ReleasePacket(receivedPacket);
return;
}
DOWNSTREAM_STATEMACHINE_FREAKOUT;
break;
default:
DOWNSTREAM_STATEMACHINE_FREAKOUT;
}
}
void Downstream_PacketProcessor_Interface_ReplyNotifyDevice(DownstreamPacketTypeDef* replyPacket)
{
replyPacket->Length16 = DOWNSTREAM_PACKET_HEADER_LEN_16 + 1;
replyPacket->CommandClass = COMMAND_CLASS_INTERFACE;
replyPacket->Command = COMMAND_INTERFACE_NOTIFY_DEVICE;
replyPacket->Data[0] = ConfiguredDeviceClass;
if (Downstream_TransmitPacket(replyPacket) == HAL_OK)
{
DownstreamState = STATE_ACTIVE;
Downstream_ReceivePacket(Downstream_PacketProcessor);
}
replyPacket->Length16 = DOWNSTREAM_PACKET_HEADER_LEN_16 + 1;
replyPacket->CommandClass = COMMAND_CLASS_INTERFACE;
replyPacket->Command = COMMAND_INTERFACE_NOTIFY_DEVICE;
replyPacket->Data[0] = ConfiguredDeviceClass;
if (Downstream_TransmitPacket(replyPacket) == HAL_OK)
{
DownstreamState = STATE_ACTIVE;
Downstream_ReceivePacket(Downstream_PacketProcessor);
}
}
void Downstream_PacketProcessor_GenericErrorReply(DownstreamPacketTypeDef* replyPacket)
{
replyPacket->Length16 = DOWNSTREAM_PACKET_HEADER_LEN_16;
replyPacket->CommandClass = COMMAND_CLASS_ERROR;
replyPacket->Command = COMMAND_ERROR_GENERIC;
replyPacket->Length16 = DOWNSTREAM_PACKET_HEADER_LEN_16;
replyPacket->CommandClass = COMMAND_CLASS_ERROR;
replyPacket->Command = COMMAND_ERROR_GENERIC;
Downstream_TransmitPacket(replyPacket);
Downstream_ReceivePacket(Downstream_PacketProcessor);
Downstream_TransmitPacket(replyPacket);
Downstream_ReceivePacket(Downstream_PacketProcessor);
}
void Downstream_PacketProcessor_ClassReply(DownstreamPacketTypeDef* replyPacket)
{
Downstream_TransmitPacket(replyPacket);
Downstream_ReceivePacket(Downstream_PacketProcessor);
Downstream_TransmitPacket(replyPacket);
Downstream_ReceivePacket(Downstream_PacketProcessor);
}
@ -167,94 +167,94 @@ void Downstream_PacketProcessor_ClassReply(DownstreamPacketTypeDef* replyPacket)
//either at INT_PRIORITY_OTG_FS or from main().
void Downstream_HostUserCallback(USBH_HandleTypeDef *phost, uint8_t id)
{
InterfaceCommandClassTypeDef newActiveClass = COMMAND_CLASS_INTERFACE;
if (DownstreamState >= STATE_ERROR)
{
return;
}
//Called from USB interrupt.
//Simple function shouldn't need to worry about preempting anything important.
if (id == HOST_USER_DISCONNECTION)
{
DownstreamState = STATE_DEVICE_NOT_READY;
return;
}
//Called from main()
if (id == HOST_USER_UNRECOVERED_ERROR)
{
DOWNSTREAM_STATEMACHINE_FREAKOUT;
return;
}
//Called from main()
if (id == HOST_USER_CLASS_ACTIVE)
{
switch (phost->pActiveClass->ClassCode)
{
case USB_MSC_CLASS:
if (Downstream_MSC_ApproveConnectedDevice() == HAL_OK)
{
newActiveClass = COMMAND_CLASS_MASS_STORAGE;
}
break;
//Add other classes here...
//Unsupported device classes will cause a slow fault flash.
//This is distinct from the fast freakout flash caused by internal errors or attacks.
default:
USB_Host_Disconnect();
LED_Fault_SetBlinkRate(LED_SLOW_BLINK_RATE);
DownstreamState = STATE_ERROR;
return;
}
//If the new device has failed its 'approval' checks, we are sufficiently freaked out.
if (newActiveClass == COMMAND_CLASS_INTERFACE)
{
DOWNSTREAM_STATEMACHINE_FREAKOUT;
return;
}
//If we already configured a device class, we cannot change to a different one without rebooting.
//This blocks some BadUSB attacks.
if ((ConfiguredDeviceClass != COMMAND_CLASS_INTERFACE) &&
(ConfiguredDeviceClass != newActiveClass))
{
DOWNSTREAM_STATEMACHINE_FREAKOUT;
return;
}
ConfiguredDeviceClass = newActiveClass;
if (DownstreamState == STATE_WAIT_DEVICE_READY)
{
Downstream_GetFreePacket(Downstream_PacketProcessor_Interface_ReplyNotifyDevice);
return;
}
if (DownstreamState == STATE_DEVICE_NOT_READY)
{
DownstreamState = STATE_DEVICE_READY;
return;
}
DOWNSTREAM_STATEMACHINE_FREAKOUT;
return;
}
//Called from main():
if (id == HOST_USER_CLASS_FAILED)
{
//Unsupported device classes will cause a slow fault flash.
//This is distinct from the fast freakout flash caused by internal errors or attacks.
USB_Host_Disconnect();
LED_Fault_SetBlinkRate(LED_SLOW_BLINK_RATE);
DownstreamState = STATE_ERROR;
return;
}
InterfaceCommandClassTypeDef newActiveClass = COMMAND_CLASS_INTERFACE;
if (DownstreamState >= STATE_ERROR)
{
return;
}
//Called from USB interrupt.
//Simple function shouldn't need to worry about preempting anything important.
if (id == HOST_USER_DISCONNECTION)
{
DownstreamState = STATE_DEVICE_NOT_READY;
return;
}
//Called from main()
if (id == HOST_USER_UNRECOVERED_ERROR)
{
DOWNSTREAM_STATEMACHINE_FREAKOUT;
return;
}
//Called from main()
if (id == HOST_USER_CLASS_ACTIVE)
{
switch (phost->pActiveClass->ClassCode)
{
case USB_MSC_CLASS:
if (Downstream_MSC_ApproveConnectedDevice() == HAL_OK)
{
newActiveClass = COMMAND_CLASS_MASS_STORAGE;
}
break;
//Add other classes here...
//Unsupported device classes will cause a slow fault flash.
//This is distinct from the fast freakout flash caused by internal errors or attacks.
default:
USB_Host_Disconnect();
LED_Fault_SetBlinkRate(LED_SLOW_BLINK_RATE);
DownstreamState = STATE_ERROR;
return;
}
//If the new device has failed its 'approval' checks, we are sufficiently freaked out.
if (newActiveClass == COMMAND_CLASS_INTERFACE)
{
DOWNSTREAM_STATEMACHINE_FREAKOUT;
return;
}
//If we already configured a device class, we cannot change to a different one without rebooting.
//This blocks some BadUSB attacks.
if ((ConfiguredDeviceClass != COMMAND_CLASS_INTERFACE) &&
(ConfiguredDeviceClass != newActiveClass))
{
DOWNSTREAM_STATEMACHINE_FREAKOUT;
return;
}
ConfiguredDeviceClass = newActiveClass;
if (DownstreamState == STATE_WAIT_DEVICE_READY)
{
Downstream_GetFreePacket(Downstream_PacketProcessor_Interface_ReplyNotifyDevice);
return;
}
if (DownstreamState == STATE_DEVICE_NOT_READY)
{
DownstreamState = STATE_DEVICE_READY;
return;
}
DOWNSTREAM_STATEMACHINE_FREAKOUT;
return;
}
//Called from main():
if (id == HOST_USER_CLASS_FAILED)
{
//Unsupported device classes will cause a slow fault flash.
//This is distinct from the fast freakout flash caused by internal errors or attacks.
USB_Host_Disconnect();
LED_Fault_SetBlinkRate(LED_SLOW_BLINK_RATE);
DownstreamState = STATE_ERROR;
return;
}
}

@ -84,9 +84,9 @@ void DMA2_Stream3_IRQHandler(void)
void OTG_FS_IRQHandler(void)
{
INT_ACTIVE_ON;
HAL_HCD_IRQHandler(&hhcd_USB_OTG_FS);
INT_ACTIVE_OFF;
INT_ACTIVE_ON;
HAL_HCD_IRQHandler(&hhcd_USB_OTG_FS);
INT_ACTIVE_OFF;
}

@ -15,51 +15,51 @@
uint16_t FaultLedBlinkRate = 0;
uint16_t FaultLedBlinkCounter = 0;
uint8_t FaultLedState = 0;
uint16_t FaultLedBlinkRate = 0;
uint16_t FaultLedBlinkCounter = 0;
uint8_t FaultLedState = 0;
void LED_Init(void)
{
//RUN_LED_ON;
FAULT_LED_ON;
HAL_Delay(STARTUP_FLASH_DELAY);
//RUN_LED_OFF;
FAULT_LED_OFF;
//RUN_LED_ON;
FAULT_LED_ON;
HAL_Delay(STARTUP_FLASH_DELAY);
//RUN_LED_OFF;
FAULT_LED_OFF;
}
void LED_Fault_SetBlinkRate(uint16_t newBlinkRate)
{
FaultLedBlinkRate = newBlinkRate;
if (newBlinkRate == 0)
{
FaultLedState = 0;
FAULT_LED_OFF;
}
FaultLedBlinkRate = newBlinkRate;
if (newBlinkRate == 0)
{
FaultLedState = 0;
FAULT_LED_OFF;
}
}
void LED_DoBlinks(void)
{
if (FaultLedBlinkRate > 0)
{
FaultLedBlinkCounter++;
if (FaultLedBlinkCounter >= FaultLedBlinkRate)
{
FaultLedBlinkCounter = 0;
if (FaultLedState)
{
FaultLedState = 0;
FAULT_LED_OFF;
}
else
{
FaultLedState = 1;
FAULT_LED_ON;
}
}
}
if (FaultLedBlinkRate > 0)
{
FaultLedBlinkCounter++;
if (FaultLedBlinkCounter >= FaultLedBlinkRate)
{
FaultLedBlinkCounter = 0;
if (FaultLedState)
{
FaultLedState = 0;
FAULT_LED_OFF;
}
else
{
FaultLedState = 1;
FAULT_LED_ON;
}
}
}
}

@ -51,67 +51,67 @@ void CheckFirmwareMatchesHardware(void);
int main(void)
{
//First things first!
CheckFirmwareMatchesHardware();
//First things first!
CheckFirmwareMatchesHardware();
/* Configure the system clock */
SystemClock_Config();
/* Configure the system clock */
SystemClock_Config();
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Initialize all configured peripherals */
GPIO_Init();
LED_Init();
USB_Host_Init();
/* Initialize all configured peripherals */
GPIO_Init();
LED_Init();
USB_Host_Init();
Downstream_InitStateMachine();
Downstream_InitStateMachine();
while (1)
{
USB_Host_Process();
Downstream_SPIProcess();
}
while (1)
{
USB_Host_Process();
Downstream_SPIProcess();
}
}
void CheckFirmwareMatchesHardware(void)
{
//Check we are running on the expected hardware:
//STM32F407 on an Olimex dev board
GPIO_InitTypeDef GPIO_InitStruct;
if ((*(uint32_t*)DBGMCU_BASE & DBGMCU_IDCODE_DEV_ID) == DBGMCU_IDCODE_DEV_ID_405_407_415_417)
{
//The H407 board has a STAT LED on PC13. If there is no pullup on this pin,
//then we are probably running on another board.
__HAL_RCC_GPIOC_CLK_ENABLE();
GPIO_InitStruct.Pin = FAULT_LED_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
GPIO_InitStruct.Alternate = 0;
HAL_GPIO_Init(FAULT_LED_PORT, &GPIO_InitStruct);
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(FAULT_LED_PORT, &GPIO_InitStruct);
if (FAULT_LED_PORT->IDR & FAULT_LED_PIN)
{
//Pin pulls up, so this is an H407 board :)
return;
}
}
//This is not the hardware we expected, so turn on our fault LED(s) and die in a heap.
GPIO_InitStruct.Pin = FAULT_LED_PIN | H405_FAULT_LED_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(FAULT_LED_PORT, &GPIO_InitStruct);
FAULT_LED_ON;
H405_FAULT_LED_ON;
while (1);
//Check we are running on the expected hardware:
//STM32F407 on an Olimex dev board
GPIO_InitTypeDef GPIO_InitStruct;
if ((*(uint32_t*)DBGMCU_BASE & DBGMCU_IDCODE_DEV_ID) == DBGMCU_IDCODE_DEV_ID_405_407_415_417)
{
//The H407 board has a STAT LED on PC13. If there is no pullup on this pin,
//then we are probably running on another board.
__HAL_RCC_GPIOC_CLK_ENABLE();
GPIO_InitStruct.Pin = FAULT_LED_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
GPIO_InitStruct.Alternate = 0;
HAL_GPIO_Init(FAULT_LED_PORT, &GPIO_InitStruct);
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(FAULT_LED_PORT, &GPIO_InitStruct);
if (FAULT_LED_PORT->IDR & FAULT_LED_PIN)
{
//Pin pulls up, so this is an H407 board :)
return;
}
}
//This is not the hardware we expected, so turn on our fault LED(s) and die in a heap.
GPIO_InitStruct.Pin = FAULT_LED_PIN | H405_FAULT_LED_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(FAULT_LED_PORT, &GPIO_InitStruct);
FAULT_LED_ON;
H405_FAULT_LED_ON;
while (1);
}
@ -138,9 +138,9 @@ void SystemClock_Config(void)
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) while (1);
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK |
RCC_CLOCKTYPE_HCLK |
RCC_CLOCKTYPE_PCLK1 |
RCC_CLOCKTYPE_PCLK2;
RCC_CLOCKTYPE_HCLK |
RCC_CLOCKTYPE_PCLK1 |
RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
@ -155,63 +155,63 @@ void SystemClock_Config(void)
void GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
/* GPIO Ports Clock Enable */
//__GPIOH_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
__HAL_RCC_GPIOF_CLK_ENABLE();
__HAL_RCC_GPIOG_CLK_ENABLE();
//Bulk initialise all ports as inputs with pullups active,
//excluding JTAG pins which must remain as AF0!
GPIO_InitStruct.Pin = (GPIO_PIN_All & ~(PA_JTMS | PA_JTCK | PA_JTDI));
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
GPIO_InitStruct.Alternate = 0;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = (GPIO_PIN_All & ~(PB_JTDO | PB_NJTRST));
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_All;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
//USB VBUS pins are analog input
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pin = USB_FS_VBUS_PIN;
HAL_GPIO_Init(USB_FS_VBUS_PORT, &GPIO_InitStruct);
GPIO_InitStruct.Pin = USB_HS_VBUS_PIN;
HAL_GPIO_Init(USB_HS_VBUS_PORT, &GPIO_InitStruct);
//Enable USB_FS power
USB_FS_VBUSON_PORT->BSRR = (USB_FS_VBUSON_PIN << BSRR_SHIFT_HIGH);
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Pin = USB_FS_VBUSON_PIN;
HAL_GPIO_Init(USB_FS_VBUSON_PORT, &GPIO_InitStruct);
//Disable USB_HS power
USB_HS_VBUSON_PORT->BSRR = (USB_HS_VBUSON_PIN << BSRR_SHIFT_LOW);
GPIO_InitStruct.Pin = USB_HS_VBUSON_PIN;
HAL_GPIO_Init(USB_HS_VBUSON_PORT, &GPIO_InitStruct);
//STAT_LED is output
FAULT_LED_OFF;
GPIO_InitStruct.Pin = FAULT_LED_PIN;
HAL_GPIO_Init(FAULT_LED_PORT, &GPIO_InitStruct);
//SPI_INT_ACTIVE indicator
GPIO_InitStruct.Pin = INT_ACTIVE_PIN;
HAL_GPIO_Init(INT_ACTIVE_PORT, &GPIO_InitStruct);
INT_ACTIVE_OFF;
GPIO_InitTypeDef GPIO_InitStruct;
/* GPIO Ports Clock Enable */
//__GPIOH_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
__HAL_RCC_GPIOF_CLK_ENABLE();
__HAL_RCC_GPIOG_CLK_ENABLE();
//Bulk initialise all ports as inputs with pullups active,
//excluding JTAG pins which must remain as AF0!
GPIO_InitStruct.Pin = (GPIO_PIN_All & ~(PA_JTMS | PA_JTCK | PA_JTDI));
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
GPIO_InitStruct.Alternate = 0;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = (GPIO_PIN_All & ~(PB_JTDO | PB_NJTRST));
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_All;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
//USB VBUS pins are analog input
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pin = USB_FS_VBUS_PIN;
HAL_GPIO_Init(USB_FS_VBUS_PORT, &GPIO_InitStruct);
GPIO_InitStruct.Pin = USB_HS_VBUS_PIN;
HAL_GPIO_Init(USB_HS_VBUS_PORT, &GPIO_InitStruct);
//Enable USB_FS power
USB_FS_VBUSON_PORT->BSRR = (USB_FS_VBUSON_PIN << BSRR_SHIFT_HIGH);
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Pin = USB_FS_VBUSON_PIN;
HAL_GPIO_Init(USB_FS_VBUSON_PORT, &GPIO_InitStruct);
//Disable USB_HS power
USB_HS_VBUSON_PORT->BSRR = (USB_HS_VBUSON_PIN << BSRR_SHIFT_LOW);
GPIO_InitStruct.Pin = USB_HS_VBUSON_PIN;
HAL_GPIO_Init(USB_HS_VBUSON_PORT, &GPIO_InitStruct);
//STAT_LED is output
FAULT_LED_OFF;
GPIO_InitStruct.Pin = FAULT_LED_PIN;
HAL_GPIO_Init(FAULT_LED_PORT, &GPIO_InitStruct);
//SPI_INT_ACTIVE indicator
GPIO_InitStruct.Pin = INT_ACTIVE_PIN;
HAL_GPIO_Init(INT_ACTIVE_PORT, &GPIO_InitStruct);
INT_ACTIVE_OFF;
}

@ -61,7 +61,7 @@ void USB_Host_Init(void)
void USB_Host_Process()
{
/* USB Host Background task */
USBH_Process(&hUsbHostFS);
USBH_Process(&hUsbHostFS);
}
@ -69,7 +69,7 @@ void USB_Host_Process()
//Called when Downstream Statemachine or SPI freaks out.
void USB_Host_Disconnect()
{
USBH_DeInit(&hUsbHostFS);
USBH_DeInit(&hUsbHostFS);
}

@ -379,21 +379,21 @@ USBH_URBStateTypeDef USBH_LL_GetURBState (USBH_HandleTypeDef *phost, uint8_t pi
*/
USBH_StatusTypeDef USBH_LL_DriverVBUS (USBH_HandleTypeDef *phost, uint8_t state)
{
//Our VBUS is permanently on, so don't bother with this...
// if (phost->id == HOST_FS)
// {
// if(state == 0)
// {
// //VBUS off
// }
// else
// {
// //VBUS on
// }
// }
// HAL_Delay(200);
return USBH_OK;
//Our VBUS is permanently on, so don't bother with this...
// if (phost->id == HOST_FS)
// {
// if(state == 0)
// {
// //VBUS off
// }
// else
// {
// //VBUS on
// }
// }
// HAL_Delay(200);
return USBH_OK;
}
/**

@ -273,7 +273,7 @@ typedef struct __SPI_HandleTypeDef
#define SPI_CRCCALCULATION_DISABLE ((uint32_t)0x00000000)
#define SPI_CRCCALCULATION_ENABLE SPI_CR1_CRCEN
#define SPI_CRC_DEFAULTPOLYNOMIAL 0x07
#define SPI_CRC_DEFAULTPOLYNOMIAL 0x07
/**
* @}
*/

@ -1133,11 +1133,11 @@ static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t
ep->xfer_count < ep->xfer_len &&
ep->xfer_len != 0)
{
/* Write the FIFO */
USB_WritePacket(USBx, ep->xfer_buff, epnum, len, hpcd->Init.dma_enable);
/* Write the FIFO */
USB_WritePacket(USBx, ep->xfer_buff, epnum, len, hpcd->Init.dma_enable);
ep->xfer_buff += len;
ep->xfer_count += len;
ep->xfer_buff += len;
ep->xfer_count += len;
len = ep->xfer_len - ep->xfer_count;
if (len > ep->maxpacket)

@ -283,7 +283,7 @@ HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)
/* When the HSE is used as system clock or clock source for PLL in these cases HSE will not disabled */
if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSE) || ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLL) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSE)))
{
// *** Even if our new HSE state is ON, we cannot configure it when it is used as the system clock source!
// *** Even if our new HSE state is ON, we cannot configure it when it is used as the system clock source!
// if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET) && (RCC_OscInitStruct->HSEState == RCC_HSE_OFF))
// {
return HAL_ERROR;
@ -352,7 +352,7 @@ HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)
if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSI) || ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLL) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSI)))
{
/* When HSI is used as system clock it will not disabled */
//*** Why are we checking the HSIRDY flag here? If the clock source is currently HSI then it must be stable!
//*** Why are we checking the HSIRDY flag here? If the clock source is currently HSI then it must be stable!
if(/*(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) &&*/ (RCC_OscInitStruct->HSIState != RCC_HSI_ON))
{
return HAL_ERROR;
@ -521,57 +521,57 @@ HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)
{
/* Check if the PLL is used as system clock or not */
if (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_CFGR_SWS_PLL)
{
/* Disable the main PLL. */
__HAL_RCC_PLL_DISABLE();
/* Get Start Tick*/
tickstart = HAL_GetTick ();
/* Wait till PLL is ready */
while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET)
{
if ((HAL_GetTick () - tickstart) > PLL_TIMEOUT_VALUE)
{
return HAL_TIMEOUT;
}
}
if ((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_ON)
{
/* Check the parameters */
assert_param(IS_RCC_PLLSOURCE(RCC_OscInitStruct->PLL.PLLSource));
assert_param(IS_RCC_PLLM_VALUE(RCC_OscInitStruct->PLL.PLLM));
assert_param(IS_RCC_PLLN_VALUE(RCC_OscInitStruct->PLL.PLLN));
assert_param(IS_RCC_PLLP_VALUE(RCC_OscInitStruct->PLL.PLLP));
assert_param(IS_RCC_PLLQ_VALUE(RCC_OscInitStruct->PLL.PLLQ));
/* Configure the main PLL clock source, multiplication and division factors. */
__HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource,
RCC_OscInitStruct->PLL.PLLM,
RCC_OscInitStruct->PLL.PLLN,
RCC_OscInitStruct->PLL.PLLP,
RCC_OscInitStruct->PLL.PLLQ);
/* Enable the main PLL. */
__HAL_RCC_PLL_ENABLE();
/* Get Start Tick*/
tickstart = HAL_GetTick ();
/* Wait till PLL is ready */
while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET)
{
if ((HAL_GetTick () - tickstart) > PLL_TIMEOUT_VALUE)
{
return HAL_TIMEOUT;
}
}
}
}
{
/* Disable the main PLL. */
__HAL_RCC_PLL_DISABLE();
/* Get Start Tick*/
tickstart = HAL_GetTick ();
/* Wait till PLL is ready */
while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET)
{
if ((HAL_GetTick () - tickstart) > PLL_TIMEOUT_VALUE)
{
return HAL_TIMEOUT;
}
}
if ((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_ON)
{
/* Check the parameters */
assert_param(IS_RCC_PLLSOURCE(RCC_OscInitStruct->PLL.PLLSource));
assert_param(IS_RCC_PLLM_VALUE(RCC_OscInitStruct->PLL.PLLM));
assert_param(IS_RCC_PLLN_VALUE(RCC_OscInitStruct->PLL.PLLN));
assert_param(IS_RCC_PLLP_VALUE(RCC_OscInitStruct->PLL.PLLP));
assert_param(IS_RCC_PLLQ_VALUE(RCC_OscInitStruct->PLL.PLLQ));
/* Configure the main PLL clock source, multiplication and division factors. */
__HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource,
RCC_OscInitStruct->PLL.PLLM,
RCC_OscInitStruct->PLL.PLLN,
RCC_OscInitStruct->PLL.PLLP,
RCC_OscInitStruct->PLL.PLLQ);
/* Enable the main PLL. */
__HAL_RCC_PLL_ENABLE();
/* Get Start Tick*/
tickstart = HAL_GetTick ();
/* Wait till PLL is ready */
while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET)
{
if ((HAL_GetTick () - tickstart) > PLL_TIMEOUT_VALUE)
{
return HAL_TIMEOUT;
}
}
}
}
else
{
return HAL_ERROR;
}
{
return HAL_ERROR;
}
}
return HAL_OK;
}

@ -256,7 +256,7 @@ HAL_StatusTypeDef USB_DevInit (USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef c
/* Clear all pending Device Interrupts */
USBx_DEVICE->DIEPMSK = 0;
USBx_DEVICE->DOEPMSK = 0;
USBx_DEVICE->DAINT = 0xFFFFFFFF; //*** Uh, this register is read-only???
USBx_DEVICE->DAINT = 0xFFFFFFFF; //*** Uh, this register is read-only???
USBx_DEVICE->DAINTMSK = 0;
for (i = 0; i < cfg.dev_endpoints; i++)

@ -13,41 +13,41 @@
#define INC_BOARD_CONFIG_H_
#define BSRR_SHIFT_HIGH 0
#define BSRR_SHIFT_LOW 16
#define BSRR_SHIFT_HIGH 0
#define BSRR_SHIFT_LOW 16
#define PA_JTMS GPIO_PIN_13
#define PA_JTCK GPIO_PIN_14
#define PA_JTDI GPIO_PIN_15
#define PB_JTDO GPIO_PIN_3
#define PB_NJTRST GPIO_PIN_4
#define PA_JTMS GPIO_PIN_13
#define PA_JTCK GPIO_PIN_14
#define PA_JTDI GPIO_PIN_15
#define PB_JTDO GPIO_PIN_3
#define PB_NJTRST GPIO_PIN_4
#define USB_P_PIN GPIO_PIN_4
#define USB_P_PORT GPIOC
#define USB_P_PIN GPIO_PIN_4
#define USB_P_PORT GPIOC
#define FAULT_LED_PIN GPIO_PIN_12
#define FAULT_LED_PORT GPIOC
#define FAULT_LED_ON (FAULT_LED_PORT->BSRR = (FAULT_LED_PIN << BSRR_SHIFT_LOW)) //Fault LED is active-low
#define FAULT_LED_OFF (FAULT_LED_PORT->BSRR = (FAULT_LED_PIN << BSRR_SHIFT_HIGH))
#define FAULT_LED_PIN GPIO_PIN_12
#define FAULT_LED_PORT GPIOC
#define FAULT_LED_ON (FAULT_LED_PORT->BSRR = (FAULT_LED_PIN << BSRR_SHIFT_LOW)) //Fault LED is active-low
#define FAULT_LED_OFF (FAULT_LED_PORT->BSRR = (FAULT_LED_PIN << BSRR_SHIFT_HIGH))
#define OTHER_BOARDS_FAULT_LED_PIN GPIO_PIN_13 //Fault LED on Olimex H407 board, and USG v1.0
#define OTHER_BOARDS_FAULT_LED_ON (FAULT_LED_PORT->BSRR = (OTHER_BOARDS_FAULT_LED_PIN << BSRR_SHIFT_LOW))
#define OTHER_BOARDS_FAULT_LED_PIN GPIO_PIN_13 //Fault LED on Olimex H407 board, and USG v1.0
#define OTHER_BOARDS_FAULT_LED_ON (FAULT_LED_PORT->BSRR = (OTHER_BOARDS_FAULT_LED_PIN << BSRR_SHIFT_LOW))
#define INT_ACTIVE_PIN GPIO_PIN_5 //Temporary indicator of SPI (or whatever) activity
#define INT_ACTIVE_PORT GPIOB
#define INT_ACTIVE_ON INT_ACTIVE_PORT->BSRR = (INT_ACTIVE_PIN << BSRR_SHIFT_HIGH)
#define INT_ACTIVE_OFF INT_ACTIVE_PORT->BSRR = (INT_ACTIVE_PIN << BSRR_SHIFT_LOW)
#define INT_ACTIVE_PIN GPIO_PIN_5 //Temporary indicator of SPI (or whatever) activity
#define INT_ACTIVE_PORT GPIOB
#define INT_ACTIVE_ON INT_ACTIVE_PORT->BSRR = (INT_ACTIVE_PIN << BSRR_SHIFT_HIGH)
#define INT_ACTIVE_OFF INT_ACTIVE_PORT->BSRR = (INT_ACTIVE_PIN << BSRR_SHIFT_LOW)
#define SPI1_NSS_PIN GPIO_PIN_4
#define SPI1_NSS_PORT GPIOA
#define SPI1_NSS_ASSERT SPI1_NSS_PORT->BSRR = (SPI1_NSS_PIN << BSRR_SHIFT_LOW)
#define SPI1_NSS_DEASSERT SPI1_NSS_PORT->BSRR = (SPI1_NSS_PIN << BSRR_SHIFT_HIGH)
#define SPI1_NSS_PIN GPIO_PIN_4
#define SPI1_NSS_PORT GPIOA
#define SPI1_NSS_ASSERT SPI1_NSS_PORT->BSRR = (SPI1_NSS_PIN << BSRR_SHIFT_LOW)
#define SPI1_NSS_DEASSERT SPI1_NSS_PORT->BSRR = (SPI1_NSS_PIN << BSRR_SHIFT_HIGH)
#define DOWNSTREAM_TX_OK_PIN GPIO_PIN_3
#define DOWNSTREAM_TX_OK_PORT GPIOA
#define DOWNSTREAM_TX_OK_ACTIVE (!(DOWNSTREAM_TX_OK_PORT->IDR & DOWNSTREAM_TX_OK_PIN))
#define DOWNSTREAM_TX_OK_PIN GPIO_PIN_3
#define DOWNSTREAM_TX_OK_PORT GPIOA
#define DOWNSTREAM_TX_OK_ACTIVE (!(DOWNSTREAM_TX_OK_PORT->IDR & DOWNSTREAM_TX_OK_PIN))
#define DBGMCU_IDCODE_DEV_ID_405_407_415_417 0x413
#define DBGMCU_IDCODE_DEV_ID_405_407_415_417 0x413
#endif /* INC_BOARD_CONFIG_H_ */

@ -141,7 +141,7 @@
* @brief This is the HAL system configuration section
*/
#define VDD_VALUE ((uint32_t)3300) /*!< Value of VDD in mv */
#define VDD_VALUE ((uint32_t)3300) /*!< Value of VDD in mv */
#define TICK_INT_PRIORITY ((uint32_t)0) /*!< tick interrupt priority */
#define USE_RTOS 0
#define PREFETCH_ENABLE 1

@ -50,10 +50,10 @@
* This parameter can be a value between 0 and 15
* A lower priority value indicates a higher priority. */
#define INT_PRIORITY_SYSTICK 2
#define INT_PRIORITY_SPI_DMA 10 //SPI is more important than USB now!
#define INT_PRIORITY_USB 10
#define INT_PRIORITY_EXT3I INT_PRIORITY_USB
#define INT_PRIORITY_SYSTICK 2
#define INT_PRIORITY_SPI_DMA 10 //SPI and USB should be equal, no pre-emption allowed
#define INT_PRIORITY_USB 10
#define INT_PRIORITY_EXT3I INT_PRIORITY_USB
/* Exported macro ------------------------------------------------------------*/

@ -22,11 +22,11 @@ void LED_DoBlinks(void);
#define STARTUP_FLASH_DELAY 500 //units = ticks = ms
#define STARTUP_FLASH_DELAY 500 //units = ticks = ms
//LEDs are on for BLINK_RATE ticks, then off for BLINK_RATE ticks
#define LED_FAST_BLINK_RATE 100
#define LED_SLOW_BLINK_RATE 500
#define LED_FAST_BLINK_RATE 100
#define LED_SLOW_BLINK_RATE 500

@ -22,43 +22,43 @@
//Upstream only supports one LUN.
//Downstream may support > 1 LUN and only report the first active one to upstream.
#define UPSTREAM_LUN_NBR 1
#define COMMAND_CLASS_DATA_FLAG 0x80
#define COMMAND_CLASS_MASK ((uint8_t)(~COMMAND_CLASS_DATA_FLAG))
#define UPSTREAM_LUN_NBR 1
#define COMMAND_CLASS_DATA_FLAG 0x80
#define COMMAND_CLASS_MASK ((uint8_t)(~COMMAND_CLASS_DATA_FLAG))
typedef enum
{
COMMAND_CLASS_INTERFACE,
COMMAND_CLASS_MASS_STORAGE,
//...
COMMAND_CLASS_ERROR
COMMAND_CLASS_INTERFACE,
COMMAND_CLASS_MASS_STORAGE,
//...
COMMAND_CLASS_ERROR
}
InterfaceCommandClassTypeDef;
typedef enum
{
COMMAND_INTERFACE_ECHO, //Returns echo packet including all data
COMMAND_INTERFACE_NOTIFY_DEVICE //Returns COMMAND_CLASS_*** byte when downstream USB device is connected
COMMAND_INTERFACE_ECHO, //Returns echo packet including all data
COMMAND_INTERFACE_NOTIFY_DEVICE //Returns COMMAND_CLASS_*** byte when downstream USB device is connected
}
InterfaceCommandInterfaceTypeDef;
typedef enum
{
COMMAND_MSC_TEST_UNIT_READY, //Returns HAL_StatusTypeDef result
COMMAND_MSC_GET_CAPACITY, //Returns uint32_t blk_nbr, uint32_t blk_size
COMMAND_MSC_READ, //Returns HAL_StatusTypeDef result, then data stream
COMMAND_MSC_WRITE, //Returns HAL_OK, HAL_ERROR if medium not present, HAL_BUSY if write-protected result, then waits for data stream
COMMAND_MSC_TEST_UNIT_READY, //Returns HAL_StatusTypeDef result
COMMAND_MSC_GET_CAPACITY, //Returns uint32_t blk_nbr, uint32_t blk_size
COMMAND_MSC_READ, //Returns HAL_StatusTypeDef result, then data stream
COMMAND_MSC_WRITE, //Returns HAL_OK, HAL_ERROR if medium not present, HAL_BUSY if write-protected result, then waits for data stream
}
InterfaceCommandMscTypeDef;
typedef enum
{
COMMAND_ERROR_GENERIC,
COMMAND_ERROR_DEVICE_DISCONNECTED,
COMMAND_ERROR_GENERIC,
COMMAND_ERROR_DEVICE_DISCONNECTED,
}
InterfaceCommandErrorTypeDef;

@ -18,24 +18,24 @@
typedef void (*UpstreamMSCCallbackTypeDef)(HAL_StatusTypeDef result);
typedef void (*UpstreamMSCCallbackPacketTypeDef)(UpstreamPacketTypeDef* upstreamPacket,
uint16_t dataLength8);
uint16_t dataLength8);
typedef void (*UpstreamMSCCallbackUintPacketTypeDef)(UpstreamPacketTypeDef* upstreamPacket,
uint32_t result_uint1,
uint32_t result_uint2);
uint32_t result_uint1,
uint32_t result_uint2);
HAL_StatusTypeDef Upstream_MSC_TestReady(UpstreamMSCCallbackTypeDef callback);
HAL_StatusTypeDef Upstream_MSC_GetCapacity(UpstreamMSCCallbackUintPacketTypeDef callback);
HAL_StatusTypeDef Upstream_MSC_BeginRead(UpstreamMSCCallbackTypeDef callback,
uint64_t readBlockStart,
uint32_t readBlockCount,
uint32_t readByteCount);
uint64_t readBlockStart,
uint32_t readBlockCount,
uint32_t readByteCount);
HAL_StatusTypeDef Upstream_MSC_GetStreamDataPacket(UpstreamMSCCallbackPacketTypeDef callback);
HAL_StatusTypeDef Upstream_MSC_BeginWrite(UpstreamMSCCallbackTypeDef callback,
uint64_t writeBlockStart,
uint32_t writeBlockCount);
uint64_t writeBlockStart,
uint32_t writeBlockCount);
HAL_StatusTypeDef Upstream_MSC_PutStreamDataPacket(UpstreamPacketTypeDef* packetToSend,
uint32_t dataLength8);
uint32_t dataLength8);

@ -16,56 +16,56 @@
#include "usbd_config.h"
#define UPSTREAM_PACKET_HEADER_LEN (2) //Min length = CommandClass & Command bytes
#define UPSTREAM_PACKET_LEN (UPSTREAM_PACKET_HEADER_LEN + MSC_MEDIA_PACKET)
#define UPSTREAM_PACKET_LEN_MIN (UPSTREAM_PACKET_HEADER_LEN)
#define UPSTREAM_PACKET_HEADER_LEN (2) //Min length = CommandClass & Command bytes
#define UPSTREAM_PACKET_LEN (UPSTREAM_PACKET_HEADER_LEN + MSC_MEDIA_PACKET)
#define UPSTREAM_PACKET_LEN_MIN (UPSTREAM_PACKET_HEADER_LEN)
#define UPSTREAM_PACKET_HEADER_LEN_16 (UPSTREAM_PACKET_HEADER_LEN / 2)
#define UPSTREAM_PACKET_LEN_16 (UPSTREAM_PACKET_LEN / 2)
#define UPSTREAM_PACKET_LEN_MIN_16 (UPSTREAM_PACKET_LEN_MIN / 2)
#define UPSTREAM_PACKET_HEADER_LEN_16 (UPSTREAM_PACKET_HEADER_LEN / 2)
#define UPSTREAM_PACKET_LEN_16 (UPSTREAM_PACKET_LEN / 2)
#define UPSTREAM_PACKET_LEN_MIN_16 (UPSTREAM_PACKET_LEN_MIN / 2)
#define UPSTREAM_SPI_FREAKOUT \
do { \
LED_Fault_SetBlinkRate(LED_FAST_BLINK_RATE); \
/*UpstreamInterfaceState = UPSTREAM_INTERFACE_ERROR; */ \
Upstream_StateMachine_SetErrorState(); \
while (1); \
#define UPSTREAM_SPI_FREAKOUT \
do { \
LED_Fault_SetBlinkRate(LED_FAST_BLINK_RATE); \
/*UpstreamInterfaceState = UPSTREAM_INTERFACE_ERROR; */ \
Upstream_StateMachine_SetErrorState(); \
while (1); \
} while (0);
typedef enum
{
UPSTREAM_INTERFACE_IDLE,
UPSTREAM_INTERFACE_TX_SIZE_WAIT,
UPSTREAM_INTERFACE_TX_SIZE,
UPSTREAM_INTERFACE_TX_PACKET_WAIT,
UPSTREAM_INTERFACE_TX_PACKET,
UPSTREAM_INTERFACE_RX_SIZE_WAIT,
UPSTREAM_INTERFACE_RX_SIZE,
UPSTREAM_INTERFACE_RX_PACKET_WAIT,
UPSTREAM_INTERFACE_RX_PACKET,
UPSTREAM_INTERFACE_ERROR
UPSTREAM_INTERFACE_IDLE,
UPSTREAM_INTERFACE_TX_SIZE_WAIT,
UPSTREAM_INTERFACE_TX_SIZE,
UPSTREAM_INTERFACE_TX_PACKET_WAIT,
UPSTREAM_INTERFACE_TX_PACKET,
UPSTREAM_INTERFACE_RX_SIZE_WAIT,
UPSTREAM_INTERFACE_RX_SIZE,
UPSTREAM_INTERFACE_RX_PACKET_WAIT,
UPSTREAM_INTERFACE_RX_PACKET,
UPSTREAM_INTERFACE_ERROR
}
InterfaceStateTypeDef;
typedef enum
{
NOT_BUSY,
BUSY
NOT_BUSY,
BUSY
}
PacketBusyTypeDef;
typedef struct
{
PacketBusyTypeDef Busy; //Everything after Busy should be word-aligned
uint16_t Length16 __ALIGN_END; //Packet length includes CommandClass, Command, and Data
uint8_t CommandClass;
uint8_t Command;
uint8_t Data[MSC_MEDIA_PACKET]; //Should (must?) be word-aligned, for USB copy routine
PacketBusyTypeDef Busy; //Everything after Busy should be word-aligned
uint16_t Length16 __ALIGN_END; //Packet length includes CommandClass, Command, and Data
uint8_t CommandClass;
uint8_t Command;
uint8_t Data[MSC_MEDIA_PACKET]; //Should (must?) be word-aligned, for USB copy routine
}
UpstreamPacketTypeDef;

@ -18,19 +18,19 @@
typedef enum
{
STATE_TEST_INTERFACE,
STATE_WAIT_DEVICE,
STATE_DEVICE_ACTIVE,
STATE_ERROR
STATE_TEST_INTERFACE,
STATE_WAIT_DEVICE,
STATE_DEVICE_ACTIVE,
STATE_ERROR
} UpstreamStateTypeDef;
#define UPSTREAM_STATEMACHINE_FREAKOUT \
do { \
LED_Fault_SetBlinkRate(LED_FAST_BLINK_RATE); \
Upstream_StateMachine_SetErrorState(); \
while (1); \
#define UPSTREAM_STATEMACHINE_FREAKOUT \
do { \
LED_Fault_SetBlinkRate(LED_FAST_BLINK_RATE); \
Upstream_StateMachine_SetErrorState(); \
while (1); \
} while (0);

@ -71,8 +71,8 @@
#define MSC_MEDIA_PACKET 512
/****************************************/
/* #define for FS and HS identification */
#define DEVICE_FS 0
#define DEVICE_HS 1
#define DEVICE_FS 0
#define DEVICE_HS 1
/** @defgroup USBD_Exported_Macros
* @{

@ -82,7 +82,7 @@ typedef struct
uint8_t bot_status;
uint16_t bot_data_length;
uint8_t* bot_data;
UpstreamPacketTypeDef* bot_packet; //Not NULL indicates we currently own an upstream packet buffer, and should free it when we are done.
UpstreamPacketTypeDef* bot_packet; //Not NULL indicates we currently own an upstream packet buffer, and should free it when we are done.
USBD_MSC_BOT_CBWTypeDef cbw;
USBD_MSC_BOT_CSWTypeDef csw;
@ -90,11 +90,11 @@ typedef struct
uint8_t scsi_sense_head;
uint8_t scsi_sense_tail;
uint16_t scsi_blk_size; //LOGICAL BLOCK LENGTH IN BYTES: Number of bytes of user data in a logical block [SBC-4]
uint32_t scsi_blk_nbr; //This is total block count = LOGICAL BLOCK ADDRESS + 1. LOGICAL BLOCK ADDRESS: LBA of the last logical block on the direct access block device [SBC-4]
uint16_t scsi_blk_size; //LOGICAL BLOCK LENGTH IN BYTES: Number of bytes of user data in a logical block [SBC-4]
uint32_t scsi_blk_nbr; //This is total block count = LOGICAL BLOCK ADDRESS + 1. LOGICAL BLOCK ADDRESS: LBA of the last logical block on the direct access block device [SBC-4]
uint32_t scsi_blk_addr; //LOGICAL BLOCK ADDRESS: Starting with the logical block referenced [SBC-4]
uint16_t scsi_blk_len; //TRANSFER LENGTH: Number of contiguous logical blocks of data that shall be read [SBC-4]
uint32_t scsi_blk_addr; //LOGICAL BLOCK ADDRESS: Starting with the logical block referenced [SBC-4]
uint16_t scsi_blk_len; //TRANSFER LENGTH: Number of contiguous logical blocks of data that shall be read [SBC-4]
}
USBD_MSC_BOT_HandleTypeDef;

@ -48,10 +48,10 @@
/** @defgroup USB_INFO_Exported_Defines
* @{
*/
#define MODE_SENSE6_LEN 8
#define MODE_SENSE10_LEN 8
#define LENGTH_INQUIRY_PAGE00 7
#define LENGTH_FORMAT_CAPACITIES 20
#define MODE_SENSE6_LEN 8
#define MODE_SENSE10_LEN 8
#define LENGTH_INQUIRY_PAGE00 7
#define LENGTH_FORMAT_CAPACITIES 20
/**
* @}

@ -141,7 +141,7 @@ typedef struct _SENSE_ITEM {
char ASC;
char ASCQ;
}b;
unsigned int ASC;
unsigned int ASC;
char *pData;
} w;
} USBD_SCSI_SenseTypeDef;
@ -174,7 +174,7 @@ typedef void (*SCSI_ProcessCmdCallbackTypeDef)(int8_t result);
void SCSI_ProcessCmd(USBD_HandleTypeDef *pdev,
uint8_t lun,
uint8_t *cmd,
SCSI_ProcessCmdCallbackTypeDef process_cmd_callback);
SCSI_ProcessCmdCallbackTypeDef process_cmd_callback);
void SCSI_SenseCode(USBD_HandleTypeDef *pdev,
uint8_t lun,

@ -540,15 +540,15 @@ uint8_t USBD_MSC_DataOut (USBD_HandleTypeDef *pdev,
uint8_t USBD_MSC_BufferFreed(USBD_HandleTypeDef *pdev)
{
if (((USBD_MSC_BOT_HandleTypeDef*)pdev->pClassData) != NULL)
{
if (((USBD_MSC_BOT_HandleTypeDef*)pdev->pClassData)->bot_packet != NULL)
{
Upstream_ReleasePacket(((USBD_MSC_BOT_HandleTypeDef*)pdev->pClassData)->bot_packet);
((USBD_MSC_BOT_HandleTypeDef*)pdev->pClassData)->bot_packet = NULL;
}
}
return 0;
if (((USBD_MSC_BOT_HandleTypeDef*)pdev->pClassData) != NULL)
{
if (((USBD_MSC_BOT_HandleTypeDef*)pdev->pClassData)->bot_packet != NULL)
{
Upstream_ReleasePacket(((USBD_MSC_BOT_HandleTypeDef*)pdev->pClassData)->bot_packet);
((USBD_MSC_BOT_HandleTypeDef*)pdev->pClassData)->bot_packet = NULL;
}
}
return 0;
}

@ -72,8 +72,8 @@
* @{
*/
USBD_HandleTypeDef *MSC_BOT_pdev;
USBD_MSC_BOT_HandleTypeDef *MSC_BOT_hmsc;
USBD_HandleTypeDef *MSC_BOT_pdev;
USBD_MSC_BOT_HandleTypeDef *MSC_BOT_hmsc;
/**
* @}
@ -174,11 +174,11 @@ void MSC_BOT_DataIn (USBD_HandleTypeDef *pdev,
switch (hmsc->bot_state)
{
case USBD_BOT_DATA_IN:
MSC_BOT_pdev = pdev;
MSC_BOT_pdev = pdev;
SCSI_ProcessCmd(pdev,
hmsc->cbw.bLUN,
&hmsc->cbw.CB[0],
MSC_BOT_DataIn_Callback);
hmsc->cbw.bLUN,
&hmsc->cbw.CB[0],
MSC_BOT_DataIn_Callback);
break;
case USBD_BOT_SEND_DATA:
@ -194,10 +194,10 @@ void MSC_BOT_DataIn (USBD_HandleTypeDef *pdev,
void MSC_BOT_DataIn_Callback(int8_t result)
{
if (result < 0)
{
MSC_BOT_SendCSW (MSC_BOT_pdev, USBD_CSW_CMD_FAILED);
}
if (result < 0)
{
MSC_BOT_SendCSW (MSC_BOT_pdev, USBD_CSW_CMD_FAILED);
}
}
/**
@ -224,7 +224,7 @@ void MSC_BOT_DataOut (USBD_HandleTypeDef *pdev,
SCSI_ProcessCmd(pdev,
hmsc->cbw.bLUN,
&hmsc->cbw.CB[0],
MSC_BOT_DataOut_Callback);
MSC_BOT_DataOut_Callback);
break;
default:
@ -235,10 +235,10 @@ void MSC_BOT_DataOut (USBD_HandleTypeDef *pdev,
void MSC_BOT_DataOut_Callback(int8_t result)
{
if (result < 0)
{
MSC_BOT_SendCSW (MSC_BOT_pdev, USBD_CSW_CMD_FAILED);
}
if (result < 0)
{
MSC_BOT_SendCSW (MSC_BOT_pdev, USBD_CSW_CMD_FAILED);
}
}
/**
@ -272,47 +272,47 @@ static void MSC_BOT_CBW_Decode (USBD_HandleTypeDef *pdev)
}
else
{
MSC_BOT_pdev = pdev;
MSC_BOT_hmsc = hmsc;
MSC_BOT_pdev = pdev;
MSC_BOT_hmsc = hmsc;
SCSI_ProcessCmd(pdev,
hmsc->cbw.bLUN,
&hmsc->cbw.CB[0],
MSC_BOT_CBW_Decode_Callback);
hmsc->cbw.bLUN,
&hmsc->cbw.CB[0],
MSC_BOT_CBW_Decode_Callback);
}
}
void MSC_BOT_CBW_Decode_Callback(int8_t result)
{
if (result < 0)
{
if(MSC_BOT_hmsc->bot_state == USBD_BOT_NO_DATA)
{
MSC_BOT_SendCSW (MSC_BOT_pdev,
USBD_CSW_CMD_FAILED);
}
else
{
MSC_BOT_Abort(MSC_BOT_pdev);
}
}
/*Burst xfer handled internally*/
else if ((MSC_BOT_hmsc->bot_state != USBD_BOT_DATA_IN) &&
(MSC_BOT_hmsc->bot_state != USBD_BOT_DATA_OUT) &&
(MSC_BOT_hmsc->bot_state != USBD_BOT_LAST_DATA_IN))
{
if (MSC_BOT_hmsc->bot_data_length > 0)
{
MSC_BOT_SendData(MSC_BOT_pdev,
MSC_BOT_hmsc->bot_data,
MSC_BOT_hmsc->bot_data_length);
}
else if (MSC_BOT_hmsc->bot_data_length == 0)
{
MSC_BOT_SendCSW (MSC_BOT_pdev,
USBD_CSW_CMD_PASSED);
}
}
if (result < 0)
{
if(MSC_BOT_hmsc->bot_state == USBD_BOT_NO_DATA)
{
MSC_BOT_SendCSW (MSC_BOT_pdev,
USBD_CSW_CMD_FAILED);
}
else
{
MSC_BOT_Abort(MSC_BOT_pdev);
}
}
/*Burst xfer handled internally*/
else if ((MSC_BOT_hmsc->bot_state != USBD_BOT_DATA_IN) &&
(MSC_BOT_hmsc->bot_state != USBD_BOT_DATA_OUT) &&
(MSC_BOT_hmsc->bot_state != USBD_BOT_LAST_DATA_IN))
{
if (MSC_BOT_hmsc->bot_data_length > 0)
{
MSC_BOT_SendData(MSC_BOT_pdev,
MSC_BOT_hmsc->bot_data,
MSC_BOT_hmsc->bot_data_length);
}
else if (MSC_BOT_hmsc->bot_data_length == 0)
{
MSC_BOT_SendCSW (MSC_BOT_pdev,
USBD_CSW_CMD_PASSED);
}
}
}

@ -70,35 +70,35 @@
/* USB Mass storage Page 0 Inquiry Data */
const uint8_t MSC_Page00_Inquiry_Data[] = {//7
0x00,
0x00,
0x00,
(LENGTH_INQUIRY_PAGE00 - 4),
0x00,
0x80,
0x83
0x00,
0x00,
0x00,
(LENGTH_INQUIRY_PAGE00 - 4),
0x00,
0x80,
0x83
};
/* USB Mass storage sense 6 Data */
const uint8_t MSC_Mode_Sense6_data[] = {
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00
};
/* USB Mass storage sense 10 Data */
const uint8_t MSC_Mode_Sense10_data[] = {
0x00,
0x06,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00
0x00,
0x06,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00
};
/**
* @}

@ -77,11 +77,11 @@
* @{
*/
USBD_HandleTypeDef *SCSI_ProcessCmd_pdev;
uint8_t SCSI_ProcessCmd_lun;
uint8_t *SCSI_ProcessCmd_params;
SCSI_ProcessCmdCallbackTypeDef SCSI_ProcessCmd_callback;
USBD_MSC_BOT_HandleTypeDef *SCSI_ProcessCmd_hmsc;
USBD_HandleTypeDef *SCSI_ProcessCmd_pdev;
uint8_t SCSI_ProcessCmd_lun;
uint8_t *SCSI_ProcessCmd_params;
SCSI_ProcessCmdCallbackTypeDef SCSI_ProcessCmd_callback;
USBD_MSC_BOT_HandleTypeDef *SCSI_ProcessCmd_hmsc;
/**
@ -107,14 +107,14 @@ static int8_t SCSI_CheckAddressRange (uint32_t blk_offset , uint16_t blk_nbr);
void SCSI_TestUnitReadyCallback(HAL_StatusTypeDef result);
void SCSI_ReadCapacity10Callback(UpstreamPacketTypeDef* upstreamPacket,
uint32_t result_uint1,
uint32_t result_uint2);
uint32_t result_uint1,
uint32_t result_uint2);
void SCSI_ReadFormatCapacityCallback(UpstreamPacketTypeDef* upstreamPacket,
uint32_t result_uint1,
uint32_t result_uint2);
uint32_t result_uint1,
uint32_t result_uint2);
void SCSI_Read10BeginCallback(HAL_StatusTypeDef result);
void SCSI_Read10ReplyCallback(UpstreamPacketTypeDef* upstreamPacket,
uint16_t dataLength);
uint16_t dataLength);
void SCSI_Write10BeginCallback(HAL_StatusTypeDef result);
void SCSI_Write10FreePacketCallback(UpstreamPacketTypeDef* freePacket);
@ -140,14 +140,14 @@ void SCSI_Write10FreePacketCallback(UpstreamPacketTypeDef* freePacket);
void SCSI_ProcessCmd(USBD_HandleTypeDef *pdev,
uint8_t lun,
uint8_t *params,
SCSI_ProcessCmdCallbackTypeDef callback)
SCSI_ProcessCmdCallbackTypeDef callback)
{
//Save all our parameters for easy access in callback routines
SCSI_ProcessCmd_pdev = pdev;
SCSI_ProcessCmd_params = params;
SCSI_ProcessCmd_lun = lun;
SCSI_ProcessCmd_callback = callback;
SCSI_ProcessCmd_hmsc = (USBD_MSC_BOT_HandleTypeDef*)pdev->pClassData;
//Save all our parameters for easy access in callback routines
SCSI_ProcessCmd_pdev = pdev;
SCSI_ProcessCmd_params = params;
SCSI_ProcessCmd_lun = lun;
SCSI_ProcessCmd_callback = callback;
SCSI_ProcessCmd_hmsc = (USBD_MSC_BOT_HandleTypeDef*)pdev->pClassData;
switch (params[0])
{
@ -222,7 +222,7 @@ void SCSI_TestUnitReady(void)
if (SCSI_ProcessCmd_hmsc->cbw.dDataLength != 0)
{
SCSI_SenseCode(SCSI_ProcessCmd_pdev,
SCSI_ProcessCmd_lun,
SCSI_ProcessCmd_lun,
ILLEGAL_REQUEST,
INVALID_CDB);
SCSI_ProcessCmd_callback(-1);
@ -231,33 +231,33 @@ void SCSI_TestUnitReady(void)
if (SCSI_ProcessCmd_lun >= UPSTREAM_LUN_NBR)
{
SCSI_TestUnitReadyCallback(HAL_ERROR);
return;
SCSI_TestUnitReadyCallback(HAL_ERROR);
return;
}
if (Upstream_MSC_TestReady(SCSI_TestUnitReadyCallback) != HAL_OK)
{
SCSI_TestUnitReadyCallback(HAL_ERROR);
SCSI_TestUnitReadyCallback(HAL_ERROR);
}
}
void SCSI_TestUnitReadyCallback(HAL_StatusTypeDef result)
{
if (result != HAL_OK)
{
SCSI_SenseCode(SCSI_ProcessCmd_pdev,
SCSI_ProcessCmd_lun,
NOT_READY,
MEDIUM_NOT_PRESENT);
SCSI_ProcessCmd_hmsc->bot_state = USBD_BOT_NO_DATA;
SCSI_ProcessCmd_callback(-1);
return;
}
//Success!
SCSI_ProcessCmd_hmsc->bot_data_length = 0;
SCSI_ProcessCmd_callback(0);
if (result != HAL_OK)
{
SCSI_SenseCode(SCSI_ProcessCmd_pdev,
SCSI_ProcessCmd_lun,
NOT_READY,
MEDIUM_NOT_PRESENT);
SCSI_ProcessCmd_hmsc->bot_state = USBD_BOT_NO_DATA;
SCSI_ProcessCmd_callback(-1);
return;
}
//Success!
SCSI_ProcessCmd_hmsc->bot_data_length = 0;
SCSI_ProcessCmd_callback(0);
}
@ -272,39 +272,39 @@ void SCSI_TestUnitReadyCallback(HAL_StatusTypeDef result)
*/
static void SCSI_Inquiry(void)
{
uint8_t* pPage;
uint16_t len;
UpstreamPacketTypeDef* freePacket;
freePacket = Upstream_GetFreePacketImmediately();
SCSI_ProcessCmd_hmsc->bot_packet = freePacket;
SCSI_ProcessCmd_hmsc->bot_data = freePacket->Data;
if (SCSI_ProcessCmd_params[1] & 0x01)/*Evpd is set*/
{
pPage = (uint8_t *)MSC_Page00_Inquiry_Data;
len = LENGTH_INQUIRY_PAGE00;
}
else
{
//Standard INQUIRY data
//Return the same info for any LUN requested
pPage = (uint8_t *)&STORAGE_Inquirydata_FS;
len = pPage[4] + 5;
if (SCSI_ProcessCmd_params[4] <= len)
{
len = SCSI_ProcessCmd_params[4];
}
}
SCSI_ProcessCmd_hmsc->bot_data_length = len;
while (len)
{
len--;
SCSI_ProcessCmd_hmsc->bot_data[len] = pPage[len];
}
SCSI_ProcessCmd_callback(0);
uint8_t* pPage;
uint16_t len;
UpstreamPacketTypeDef* freePacket;
freePacket = Upstream_GetFreePacketImmediately();
SCSI_ProcessCmd_hmsc->bot_packet = freePacket;
SCSI_ProcessCmd_hmsc->bot_data = freePacket->Data;
if (SCSI_ProcessCmd_params[1] & 0x01)/*Evpd is set*/
{
pPage = (uint8_t *)MSC_Page00_Inquiry_Data;
len = LENGTH_INQUIRY_PAGE00;
}
else
{
//Standard INQUIRY data
//Return the same info for any LUN requested
pPage = (uint8_t *)&STORAGE_Inquirydata_FS;
len = pPage[4] + 5;
if (SCSI_ProcessCmd_params[4] <= len)
{
len = SCSI_ProcessCmd_params[4];
}
}
SCSI_ProcessCmd_hmsc->bot_data_length = len;
while (len)
{
len--;
SCSI_ProcessCmd_hmsc->bot_data[len] = pPage[len];
}
SCSI_ProcessCmd_callback(0);
}
/**
@ -316,45 +316,45 @@ static void SCSI_Inquiry(void)
*/
static void SCSI_ReadCapacity10(void)
{
if (Upstream_MSC_GetCapacity(SCSI_ReadCapacity10Callback) != HAL_OK)
{
SCSI_ReadCapacity10Callback(NULL, 0, 0);
}
if (Upstream_MSC_GetCapacity(SCSI_ReadCapacity10Callback) != HAL_OK)
{
SCSI_ReadCapacity10Callback(NULL, 0, 0);
}
}
void SCSI_ReadCapacity10Callback(UpstreamPacketTypeDef* upstreamPacket,
uint32_t result_uint1,
uint32_t result_uint2)
uint32_t result_uint1,
uint32_t result_uint2)
{
if (upstreamPacket == NULL)
{
SCSI_SenseCode(SCSI_ProcessCmd_pdev,
SCSI_ProcessCmd_lun,
NOT_READY,
MEDIUM_NOT_PRESENT);
SCSI_ProcessCmd_callback(-1);
return;
}
SCSI_ProcessCmd_hmsc->bot_packet = upstreamPacket;
SCSI_ProcessCmd_hmsc->bot_data = upstreamPacket->Data;
SCSI_ProcessCmd_hmsc->scsi_blk_nbr = result_uint1;
SCSI_ProcessCmd_hmsc->scsi_blk_size = result_uint2;
SCSI_ProcessCmd_hmsc->bot_data[0] = (uint8_t)((SCSI_ProcessCmd_hmsc->scsi_blk_nbr - 1) >> 24);
SCSI_ProcessCmd_hmsc->bot_data[1] = (uint8_t)((SCSI_ProcessCmd_hmsc->scsi_blk_nbr - 1) >> 16);
SCSI_ProcessCmd_hmsc->bot_data[2] = (uint8_t)((SCSI_ProcessCmd_hmsc->scsi_blk_nbr - 1) >> 8);
SCSI_ProcessCmd_hmsc->bot_data[3] = (uint8_t)(SCSI_ProcessCmd_hmsc->scsi_blk_nbr - 1);
SCSI_ProcessCmd_hmsc->bot_data[4] = (uint8_t)(SCSI_ProcessCmd_hmsc->scsi_blk_size >> 24);
SCSI_ProcessCmd_hmsc->bot_data[5] = (uint8_t)(SCSI_ProcessCmd_hmsc->scsi_blk_size >> 16);
SCSI_ProcessCmd_hmsc->bot_data[6] = (uint8_t)(SCSI_ProcessCmd_hmsc->scsi_blk_size >> 8);
SCSI_ProcessCmd_hmsc->bot_data[7] = (uint8_t)(SCSI_ProcessCmd_hmsc->scsi_blk_size);
SCSI_ProcessCmd_hmsc->bot_data_length = 8;
SCSI_ProcessCmd_callback(0);
if (upstreamPacket == NULL)
{
SCSI_SenseCode(SCSI_ProcessCmd_pdev,
SCSI_ProcessCmd_lun,
NOT_READY,
MEDIUM_NOT_PRESENT);
SCSI_ProcessCmd_callback(-1);
return;
}
SCSI_ProcessCmd_hmsc->bot_packet = upstreamPacket;
SCSI_ProcessCmd_hmsc->bot_data = upstreamPacket->Data;
SCSI_ProcessCmd_hmsc->scsi_blk_nbr = result_uint1;
SCSI_ProcessCmd_hmsc->scsi_blk_size = result_uint2;
SCSI_ProcessCmd_hmsc->bot_data[0] = (uint8_t)((SCSI_ProcessCmd_hmsc->scsi_blk_nbr - 1) >> 24);
SCSI_ProcessCmd_hmsc->bot_data[1] = (uint8_t)((SCSI_ProcessCmd_hmsc->scsi_blk_nbr - 1) >> 16);
SCSI_ProcessCmd_hmsc->bot_data[2] = (uint8_t)((SCSI_ProcessCmd_hmsc->scsi_blk_nbr - 1) >> 8);
SCSI_ProcessCmd_hmsc->bot_data[3] = (uint8_t)(SCSI_ProcessCmd_hmsc->scsi_blk_nbr - 1);
SCSI_ProcessCmd_hmsc->bot_data[4] = (uint8_t)(SCSI_ProcessCmd_hmsc->scsi_blk_size >> 24);
SCSI_ProcessCmd_hmsc->bot_data[5] = (uint8_t)(SCSI_ProcessCmd_hmsc->scsi_blk_size >> 16);
SCSI_ProcessCmd_hmsc->bot_data[6] = (uint8_t)(SCSI_ProcessCmd_hmsc->scsi_blk_size >> 8);
SCSI_ProcessCmd_hmsc->bot_data[7] = (uint8_t)(SCSI_ProcessCmd_hmsc->scsi_blk_size);
SCSI_ProcessCmd_hmsc->bot_data_length = 8;
SCSI_ProcessCmd_callback(0);
}
/**
@ -366,45 +366,45 @@ void SCSI_ReadCapacity10Callback(UpstreamPacketTypeDef* upstreamPacket,
*/
static void SCSI_ReadFormatCapacity(void)
{
if (Upstream_MSC_GetCapacity(SCSI_ReadFormatCapacityCallback) != HAL_OK)
{
SCSI_ReadFormatCapacityCallback(NULL, 0, 0);
}
if (Upstream_MSC_GetCapacity(SCSI_ReadFormatCapacityCallback) != HAL_OK)
{
SCSI_ReadFormatCapacityCallback(NULL, 0, 0);
}
}
void SCSI_ReadFormatCapacityCallback(UpstreamPacketTypeDef* upstreamPacket,
uint32_t result_uint1,
uint32_t result_uint2)
uint32_t result_uint1,
uint32_t result_uint2)
{
if (upstreamPacket == NULL)
{
SCSI_SenseCode(SCSI_ProcessCmd_pdev,
SCSI_ProcessCmd_lun,
NOT_READY,
MEDIUM_NOT_PRESENT);
SCSI_ProcessCmd_callback(-1);
return;
}
SCSI_ProcessCmd_hmsc->bot_packet = upstreamPacket;
SCSI_ProcessCmd_hmsc->bot_data = upstreamPacket->Data;
SCSI_ProcessCmd_hmsc->bot_data[0] = 0;
SCSI_ProcessCmd_hmsc->bot_data[1] = 0;
SCSI_ProcessCmd_hmsc->bot_data[2] = 0;
SCSI_ProcessCmd_hmsc->bot_data[3] = 0x08;
SCSI_ProcessCmd_hmsc->bot_data[4] = (uint8_t)((result_uint1 - 1) >> 24);
SCSI_ProcessCmd_hmsc->bot_data[5] = (uint8_t)((result_uint1 - 1) >> 16);
SCSI_ProcessCmd_hmsc->bot_data[6] = (uint8_t)((result_uint1 - 1) >> 8);
SCSI_ProcessCmd_hmsc->bot_data[7] = (uint8_t)(result_uint1 - 1);
SCSI_ProcessCmd_hmsc->bot_data[8] = 0x02;
SCSI_ProcessCmd_hmsc->bot_data[9] = (uint8_t)(result_uint2 >> 16);
SCSI_ProcessCmd_hmsc->bot_data[10] = (uint8_t)(result_uint2 >> 8);
SCSI_ProcessCmd_hmsc->bot_data[11] = (uint8_t)(result_uint2);
SCSI_ProcessCmd_hmsc->bot_data_length = 12;
if (upstreamPacket == NULL)
{
SCSI_SenseCode(SCSI_ProcessCmd_pdev,
SCSI_ProcessCmd_lun,
NOT_READY,
MEDIUM_NOT_PRESENT);
SCSI_ProcessCmd_callback(-1);
return;
}
SCSI_ProcessCmd_hmsc->bot_packet = upstreamPacket;
SCSI_ProcessCmd_hmsc->bot_data = upstreamPacket->Data;
SCSI_ProcessCmd_hmsc->bot_data[0] = 0;
SCSI_ProcessCmd_hmsc->bot_data[1] = 0;
SCSI_ProcessCmd_hmsc->bot_data[2] = 0;
SCSI_ProcessCmd_hmsc->bot_data[3] = 0x08;
SCSI_ProcessCmd_hmsc->bot_data[4] = (uint8_t)((result_uint1 - 1) >> 24);
SCSI_ProcessCmd_hmsc->bot_data[5] = (uint8_t)((result_uint1 - 1) >> 16);
SCSI_ProcessCmd_hmsc->bot_data[6] = (uint8_t)((result_uint1 - 1) >> 8);
SCSI_ProcessCmd_hmsc->bot_data[7] = (uint8_t)(result_uint1 - 1);
SCSI_ProcessCmd_hmsc->bot_data[8] = 0x02;
SCSI_ProcessCmd_hmsc->bot_data[9] = (uint8_t)(result_uint2 >> 16);
SCSI_ProcessCmd_hmsc->bot_data[10] = (uint8_t)(result_uint2 >> 8);
SCSI_ProcessCmd_hmsc->bot_data[11] = (uint8_t)(result_uint2);
SCSI_ProcessCmd_hmsc->bot_data_length = 12;
SCSI_ProcessCmd_callback(0);
}
@ -417,21 +417,21 @@ void SCSI_ReadFormatCapacityCallback(UpstreamPacketTypeDef* upstreamPacket,
*/
static void SCSI_ModeSense6 (void)
{
uint16_t len = 8;
UpstreamPacketTypeDef* freePacket;
uint16_t len = 8;
UpstreamPacketTypeDef* freePacket;
freePacket = Upstream_GetFreePacketImmediately();
SCSI_ProcessCmd_hmsc->bot_packet = freePacket;
SCSI_ProcessCmd_hmsc->bot_data = freePacket->Data;
freePacket = Upstream_GetFreePacketImmediately();
SCSI_ProcessCmd_hmsc->bot_packet = freePacket;
SCSI_ProcessCmd_hmsc->bot_data = freePacket->Data;
SCSI_ProcessCmd_hmsc->bot_data_length = len;
SCSI_ProcessCmd_hmsc->bot_data_length = len;
while (len)
{
len--;
SCSI_ProcessCmd_hmsc->bot_data[len] = MSC_Mode_Sense6_data[len];
}
SCSI_ProcessCmd_callback(0);
while (len)
{
len--;
SCSI_ProcessCmd_hmsc->bot_data[len] = MSC_Mode_Sense6_data[len];
}
SCSI_ProcessCmd_callback(0);
}
/**
@ -443,21 +443,21 @@ static void SCSI_ModeSense6 (void)
*/
static void SCSI_ModeSense10(void)
{
uint16_t len = 8;
UpstreamPacketTypeDef* freePacket;
uint16_t len = 8;
UpstreamPacketTypeDef* freePacket;
freePacket = Upstream_GetFreePacketImmediately();
SCSI_ProcessCmd_hmsc->bot_packet = freePacket;
SCSI_ProcessCmd_hmsc->bot_data = freePacket->Data;
freePacket = Upstream_GetFreePacketImmediately();
SCSI_ProcessCmd_hmsc->bot_packet = freePacket;
SCSI_ProcessCmd_hmsc->bot_data = freePacket->Data;
SCSI_ProcessCmd_hmsc->bot_data_length = len;
SCSI_ProcessCmd_hmsc->bot_data_length = len;
while (len)
{
len--;
SCSI_ProcessCmd_hmsc->bot_data[len] = MSC_Mode_Sense10_data[len];
}
SCSI_ProcessCmd_callback(0);
while (len)
{
len--;
SCSI_ProcessCmd_hmsc->bot_data[len] = MSC_Mode_Sense10_data[len];
}
SCSI_ProcessCmd_callback(0);
}
/**
@ -470,39 +470,39 @@ static void SCSI_ModeSense10(void)
static void SCSI_RequestSense(void)
{
uint8_t i;
UpstreamPacketTypeDef* freePacket;
freePacket = Upstream_GetFreePacketImmediately();
SCSI_ProcessCmd_hmsc->bot_packet = freePacket;
SCSI_ProcessCmd_hmsc->bot_data = freePacket->Data;
for (i=0 ; i < REQUEST_SENSE_DATA_LEN ; i++)
{
SCSI_ProcessCmd_hmsc->bot_data[i] = 0;
}
SCSI_ProcessCmd_hmsc->bot_data[0] = 0x70;
SCSI_ProcessCmd_hmsc->bot_data[7] = REQUEST_SENSE_DATA_LEN - 6;
if((SCSI_ProcessCmd_hmsc->scsi_sense_head != SCSI_ProcessCmd_hmsc->scsi_sense_tail))
{
SCSI_ProcessCmd_hmsc->bot_data[2] = SCSI_ProcessCmd_hmsc->scsi_sense[SCSI_ProcessCmd_hmsc->scsi_sense_head].Skey;
SCSI_ProcessCmd_hmsc->bot_data[12] = SCSI_ProcessCmd_hmsc->scsi_sense[SCSI_ProcessCmd_hmsc->scsi_sense_head].w.b.ASCQ;
SCSI_ProcessCmd_hmsc->bot_data[13] = SCSI_ProcessCmd_hmsc->scsi_sense[SCSI_ProcessCmd_hmsc->scsi_sense_head].w.b.ASC;
SCSI_ProcessCmd_hmsc->scsi_sense_head++;
uint8_t i;
UpstreamPacketTypeDef* freePacket;
freePacket = Upstream_GetFreePacketImmediately();
SCSI_ProcessCmd_hmsc->bot_packet = freePacket;
SCSI_ProcessCmd_hmsc->bot_data = freePacket->Data;
for (i=0 ; i < REQUEST_SENSE_DATA_LEN ; i++)
{
SCSI_ProcessCmd_hmsc->bot_data[i] = 0;
}
SCSI_ProcessCmd_hmsc->bot_data[0] = 0x70;
SCSI_ProcessCmd_hmsc->bot_data[7] = REQUEST_SENSE_DATA_LEN - 6;
if((SCSI_ProcessCmd_hmsc->scsi_sense_head != SCSI_ProcessCmd_hmsc->scsi_sense_tail))
{
SCSI_ProcessCmd_hmsc->bot_data[2] = SCSI_ProcessCmd_hmsc->scsi_sense[SCSI_ProcessCmd_hmsc->scsi_sense_head].Skey;
SCSI_ProcessCmd_hmsc->bot_data[12] = SCSI_ProcessCmd_hmsc->scsi_sense[SCSI_ProcessCmd_hmsc->scsi_sense_head].w.b.ASCQ;
SCSI_ProcessCmd_hmsc->bot_data[13] = SCSI_ProcessCmd_hmsc->scsi_sense[SCSI_ProcessCmd_hmsc->scsi_sense_head].w.b.ASC;
SCSI_ProcessCmd_hmsc->scsi_sense_head++;
if (SCSI_ProcessCmd_hmsc->scsi_sense_head == SENSE_LIST_DEPTH)
{
SCSI_ProcessCmd_hmsc->scsi_sense_head = 0;
}
}
SCSI_ProcessCmd_hmsc->bot_data_length = REQUEST_SENSE_DATA_LEN;
if (SCSI_ProcessCmd_params[4] <= REQUEST_SENSE_DATA_LEN)
{
SCSI_ProcessCmd_hmsc->bot_data_length = SCSI_ProcessCmd_params[4];
}
SCSI_ProcessCmd_callback(0);
{
SCSI_ProcessCmd_hmsc->scsi_sense_head = 0;
}
}
SCSI_ProcessCmd_hmsc->bot_data_length = REQUEST_SENSE_DATA_LEN;
if (SCSI_ProcessCmd_params[4] <= REQUEST_SENSE_DATA_LEN)
{
SCSI_ProcessCmd_hmsc->bot_data_length = SCSI_ProcessCmd_params[4];
}
SCSI_ProcessCmd_callback(0);
}
/**
@ -548,118 +548,118 @@ static void SCSI_StartStopUnit(void)
*/
static void SCSI_Read10(void)
{
if (SCSI_ProcessCmd_hmsc->bot_state == USBD_BOT_IDLE) /* Idle */
{
/* case 10 : Ho <> Di */
if ((SCSI_ProcessCmd_hmsc->cbw.bmFlags & 0x80) != 0x80)
{
SCSI_SenseCode(SCSI_ProcessCmd_pdev,
SCSI_ProcessCmd_hmsc->cbw.bLUN,
ILLEGAL_REQUEST,
INVALID_CDB);
SCSI_ProcessCmd_callback(-1);
return;
}
SCSI_ProcessCmd_hmsc->scsi_blk_addr = (SCSI_ProcessCmd_params[2] << 24) | \
(SCSI_ProcessCmd_params[3] << 16) | \
(SCSI_ProcessCmd_params[4] << 8) | \
SCSI_ProcessCmd_params[5];
SCSI_ProcessCmd_hmsc->scsi_blk_len = (SCSI_ProcessCmd_params[7] << 8) | \
SCSI_ProcessCmd_params[8];
if (SCSI_CheckAddressRange(SCSI_ProcessCmd_hmsc->scsi_blk_addr,
SCSI_ProcessCmd_hmsc->scsi_blk_len) < 0)
{
SCSI_SenseCode(SCSI_ProcessCmd_pdev,
SCSI_ProcessCmd_hmsc->cbw.bLUN,
ILLEGAL_REQUEST,
INVALID_CDB);
SCSI_ProcessCmd_callback(-1); /* error */
return;
}
/* cases 4,5 : Hi <> Dn */
if (SCSI_ProcessCmd_hmsc->cbw.dDataLength != (uint32_t)(SCSI_ProcessCmd_hmsc->scsi_blk_len * SCSI_ProcessCmd_hmsc->scsi_blk_size))
{
SCSI_SenseCode(SCSI_ProcessCmd_pdev,
SCSI_ProcessCmd_hmsc->cbw.bLUN,
ILLEGAL_REQUEST,
INVALID_CDB);
SCSI_ProcessCmd_callback(-1);
return;
}
if (Upstream_MSC_BeginRead(SCSI_Read10BeginCallback,
SCSI_ProcessCmd_hmsc->scsi_blk_addr,
SCSI_ProcessCmd_hmsc->scsi_blk_len,
SCSI_ProcessCmd_hmsc->cbw.dDataLength) != HAL_OK)
{
SCSI_Read10BeginCallback(HAL_ERROR);
}
return;
}
//hmsc->bot_state is already USBD_BOT_DATA_IN
if (Upstream_MSC_GetStreamDataPacket(SCSI_Read10ReplyCallback) != HAL_OK)
{
SCSI_Read10ReplyCallback(NULL, 0);
}
if (SCSI_ProcessCmd_hmsc->bot_state == USBD_BOT_IDLE) /* Idle */
{
/* case 10 : Ho <> Di */
if ((SCSI_ProcessCmd_hmsc->cbw.bmFlags & 0x80) != 0x80)
{
SCSI_SenseCode(SCSI_ProcessCmd_pdev,
SCSI_ProcessCmd_hmsc->cbw.bLUN,
ILLEGAL_REQUEST,
INVALID_CDB);
SCSI_ProcessCmd_callback(-1);
return;
}
SCSI_ProcessCmd_hmsc->scsi_blk_addr = (SCSI_ProcessCmd_params[2] << 24) | \
(SCSI_ProcessCmd_params[3] << 16) | \
(SCSI_ProcessCmd_params[4] << 8) | \
SCSI_ProcessCmd_params[5];
SCSI_ProcessCmd_hmsc->scsi_blk_len = (SCSI_ProcessCmd_params[7] << 8) | \
SCSI_ProcessCmd_params[8];
if (SCSI_CheckAddressRange(SCSI_ProcessCmd_hmsc->scsi_blk_addr,
SCSI_ProcessCmd_hmsc->scsi_blk_len) < 0)
{
SCSI_SenseCode(SCSI_ProcessCmd_pdev,
SCSI_ProcessCmd_hmsc->cbw.bLUN,
ILLEGAL_REQUEST,
INVALID_CDB);
SCSI_ProcessCmd_callback(-1); /* error */
return;
}
/* cases 4,5 : Hi <> Dn */
if (SCSI_ProcessCmd_hmsc->cbw.dDataLength != (uint32_t)(SCSI_ProcessCmd_hmsc->scsi_blk_len * SCSI_ProcessCmd_hmsc->scsi_blk_size))
{
SCSI_SenseCode(SCSI_ProcessCmd_pdev,
SCSI_ProcessCmd_hmsc->cbw.bLUN,
ILLEGAL_REQUEST,
INVALID_CDB);
SCSI_ProcessCmd_callback(-1);
return;
}
if (Upstream_MSC_BeginRead(SCSI_Read10BeginCallback,
SCSI_ProcessCmd_hmsc->scsi_blk_addr,
SCSI_ProcessCmd_hmsc->scsi_blk_len,
SCSI_ProcessCmd_hmsc->cbw.dDataLength) != HAL_OK)
{
SCSI_Read10BeginCallback(HAL_ERROR);
}
return;
}
//hmsc->bot_state is already USBD_BOT_DATA_IN
if (Upstream_MSC_GetStreamDataPacket(SCSI_Read10ReplyCallback) != HAL_OK)
{
SCSI_Read10ReplyCallback(NULL, 0);
}
}
void SCSI_Read10BeginCallback(HAL_StatusTypeDef result)
{
if (result != HAL_OK)
{
SCSI_SenseCode(SCSI_ProcessCmd_pdev,
SCSI_ProcessCmd_lun,
NOT_READY,
MEDIUM_NOT_PRESENT);
SCSI_ProcessCmd_callback(-1);
return;
}
SCSI_ProcessCmd_hmsc->bot_state = USBD_BOT_DATA_IN;
if (Upstream_MSC_GetStreamDataPacket(SCSI_Read10ReplyCallback) != HAL_OK)
{
SCSI_Read10ReplyCallback(NULL, 0);
}
if (result != HAL_OK)
{
SCSI_SenseCode(SCSI_ProcessCmd_pdev,
SCSI_ProcessCmd_lun,
NOT_READY,
MEDIUM_NOT_PRESENT);
SCSI_ProcessCmd_callback(-1);
return;
}
SCSI_ProcessCmd_hmsc->bot_state = USBD_BOT_DATA_IN;
if (Upstream_MSC_GetStreamDataPacket(SCSI_Read10ReplyCallback) != HAL_OK)
{
SCSI_Read10ReplyCallback(NULL, 0);
}
}
void SCSI_Read10ReplyCallback(UpstreamPacketTypeDef* upstreamPacket,
uint16_t dataLength)
uint16_t dataLength)
{
if (upstreamPacket == NULL)
{
SCSI_SenseCode(SCSI_ProcessCmd_pdev,
SCSI_ProcessCmd_lun,
HARDWARE_ERROR,
UNRECOVERED_READ_ERROR);
SCSI_ProcessCmd_callback(-1);
return;
}
if (SCSI_ProcessCmd_hmsc->bot_packet != NULL)
while (1); /////////////////////////////////////////!
SCSI_ProcessCmd_hmsc->bot_packet = upstreamPacket;
SCSI_ProcessCmd_hmsc->bot_data = upstreamPacket->Data;
USBD_LL_Transmit (SCSI_ProcessCmd_pdev,
MSC_EPIN_ADDR,
SCSI_ProcessCmd_hmsc->bot_data,
dataLength);
/* case 6 : Hi = Di */
SCSI_ProcessCmd_hmsc->csw.dDataResidue -= dataLength;
if (SCSI_ProcessCmd_hmsc->csw.dDataResidue == 0)
{
SCSI_ProcessCmd_hmsc->bot_state = USBD_BOT_LAST_DATA_IN;
}
SCSI_ProcessCmd_callback(0);
if (upstreamPacket == NULL)
{
SCSI_SenseCode(SCSI_ProcessCmd_pdev,
SCSI_ProcessCmd_lun,
HARDWARE_ERROR,
UNRECOVERED_READ_ERROR);
SCSI_ProcessCmd_callback(-1);
return;
}
if (SCSI_ProcessCmd_hmsc->bot_packet != NULL)
while (1); /////////////////////////////////////////!
SCSI_ProcessCmd_hmsc->bot_packet = upstreamPacket;
SCSI_ProcessCmd_hmsc->bot_data = upstreamPacket->Data;
USBD_LL_Transmit (SCSI_ProcessCmd_pdev,
MSC_EPIN_ADDR,
SCSI_ProcessCmd_hmsc->bot_data,
dataLength);
/* case 6 : Hi = Di */
SCSI_ProcessCmd_hmsc->csw.dDataResidue -= dataLength;
if (SCSI_ProcessCmd_hmsc->csw.dDataResidue == 0)
{
SCSI_ProcessCmd_hmsc->bot_state = USBD_BOT_LAST_DATA_IN;
}
SCSI_ProcessCmd_callback(0);
}
@ -672,137 +672,137 @@ void SCSI_Read10ReplyCallback(UpstreamPacketTypeDef* upstreamPacket,
*/
static void SCSI_Write10(void)
{
uint32_t dataLength;
if (SCSI_ProcessCmd_hmsc->bot_state == USBD_BOT_IDLE) /* Idle */
{
/* case 8 : Hi <> Do */
if ((SCSI_ProcessCmd_hmsc->cbw.bmFlags & 0x80) == 0x80)
{
SCSI_SenseCode(SCSI_ProcessCmd_pdev,
SCSI_ProcessCmd_hmsc->cbw.bLUN,
ILLEGAL_REQUEST,
INVALID_CDB);
SCSI_ProcessCmd_callback(-1);
return;
}
SCSI_ProcessCmd_hmsc->scsi_blk_addr = (SCSI_ProcessCmd_params[2] << 24) | \
(SCSI_ProcessCmd_params[3] << 16) | \
(SCSI_ProcessCmd_params[4] << 8) | \
SCSI_ProcessCmd_params[5];
SCSI_ProcessCmd_hmsc->scsi_blk_len = (SCSI_ProcessCmd_params[7] << 8) | \
SCSI_ProcessCmd_params[8];
if (SCSI_CheckAddressRange(SCSI_ProcessCmd_hmsc->scsi_blk_addr,
SCSI_ProcessCmd_hmsc->scsi_blk_len) < 0)
{
SCSI_SenseCode(SCSI_ProcessCmd_pdev,
SCSI_ProcessCmd_hmsc->cbw.bLUN,
ILLEGAL_REQUEST,
INVALID_CDB);
SCSI_ProcessCmd_callback(-1); /* error */
return;
}
/* cases 3,11,13 : Hn,Ho <> D0 */
if (SCSI_ProcessCmd_hmsc->cbw.dDataLength != (uint32_t)(SCSI_ProcessCmd_hmsc->scsi_blk_len * SCSI_ProcessCmd_hmsc->scsi_blk_size))
{
SCSI_SenseCode(SCSI_ProcessCmd_pdev,
SCSI_ProcessCmd_hmsc->cbw.bLUN,
ILLEGAL_REQUEST,
INVALID_CDB);
SCSI_ProcessCmd_callback(-1);
return;
}
if (Upstream_MSC_BeginWrite(SCSI_Write10BeginCallback,
SCSI_ProcessCmd_hmsc->scsi_blk_addr,
SCSI_ProcessCmd_hmsc->scsi_blk_len) != HAL_OK)
{
SCSI_Write10BeginCallback(HAL_ERROR);
}
return;
}
//hmsc->bot_state is already USBD_BOT_DATA_OUT
dataLength = MIN(SCSI_ProcessCmd_hmsc->csw.dDataResidue, MSC_MEDIA_PACKET);
if (Upstream_MSC_PutStreamDataPacket(SCSI_ProcessCmd_hmsc->bot_packet,
dataLength) != HAL_OK)
{
SCSI_SenseCode(SCSI_ProcessCmd_pdev,
SCSI_ProcessCmd_lun,
HARDWARE_ERROR,
WRITE_FAULT);
SCSI_ProcessCmd_callback(-1);
return;
}
SCSI_ProcessCmd_hmsc->csw.dDataResidue -= dataLength;
if (SCSI_ProcessCmd_hmsc->csw.dDataResidue == 0)
{
MSC_BOT_SendCSW (SCSI_ProcessCmd_pdev, USBD_CSW_CMD_PASSED);
SCSI_ProcessCmd_callback(0);
return;
}
/* Prepare EP to Receive next packet */
if (Upstream_GetFreePacket(SCSI_Write10FreePacketCallback) != HAL_OK)
{
SCSI_SenseCode(SCSI_ProcessCmd_pdev,
SCSI_ProcessCmd_lun,
NOT_READY,
MEDIUM_NOT_PRESENT);
SCSI_ProcessCmd_callback(-1);
}
uint32_t dataLength;
if (SCSI_ProcessCmd_hmsc->bot_state == USBD_BOT_IDLE) /* Idle */
{
/* case 8 : Hi <> Do */
if ((SCSI_ProcessCmd_hmsc->cbw.bmFlags & 0x80) == 0x80)
{
SCSI_SenseCode(SCSI_ProcessCmd_pdev,
SCSI_ProcessCmd_hmsc->cbw.bLUN,
ILLEGAL_REQUEST,
INVALID_CDB);
SCSI_ProcessCmd_callback(-1);
return;
}
SCSI_ProcessCmd_hmsc->scsi_blk_addr = (SCSI_ProcessCmd_params[2] << 24) | \
(SCSI_ProcessCmd_params[3] << 16) | \
(SCSI_ProcessCmd_params[4] << 8) | \
SCSI_ProcessCmd_params[5];
SCSI_ProcessCmd_hmsc->scsi_blk_len = (SCSI_ProcessCmd_params[7] << 8) | \
SCSI_ProcessCmd_params[8];
if (SCSI_CheckAddressRange(SCSI_ProcessCmd_hmsc->scsi_blk_addr,
SCSI_ProcessCmd_hmsc->scsi_blk_len) < 0)
{
SCSI_SenseCode(SCSI_ProcessCmd_pdev,
SCSI_ProcessCmd_hmsc->cbw.bLUN,
ILLEGAL_REQUEST,
INVALID_CDB);
SCSI_ProcessCmd_callback(-1); /* error */
return;
}
/* cases 3,11,13 : Hn,Ho <> D0 */
if (SCSI_ProcessCmd_hmsc->cbw.dDataLength != (uint32_t)(SCSI_ProcessCmd_hmsc->scsi_blk_len * SCSI_ProcessCmd_hmsc->scsi_blk_size))
{
SCSI_SenseCode(SCSI_ProcessCmd_pdev,
SCSI_ProcessCmd_hmsc->cbw.bLUN,
ILLEGAL_REQUEST,
INVALID_CDB);
SCSI_ProcessCmd_callback(-1);
return;
}
if (Upstream_MSC_BeginWrite(SCSI_Write10BeginCallback,
SCSI_ProcessCmd_hmsc->scsi_blk_addr,
SCSI_ProcessCmd_hmsc->scsi_blk_len) != HAL_OK)
{
SCSI_Write10BeginCallback(HAL_ERROR);
}
return;
}
//hmsc->bot_state is already USBD_BOT_DATA_OUT
dataLength = MIN(SCSI_ProcessCmd_hmsc->csw.dDataResidue, MSC_MEDIA_PACKET);
if (Upstream_MSC_PutStreamDataPacket(SCSI_ProcessCmd_hmsc->bot_packet,
dataLength) != HAL_OK)
{
SCSI_SenseCode(SCSI_ProcessCmd_pdev,
SCSI_ProcessCmd_lun,
HARDWARE_ERROR,
WRITE_FAULT);
SCSI_ProcessCmd_callback(-1);
return;
}
SCSI_ProcessCmd_hmsc->csw.dDataResidue -= dataLength;
if (SCSI_ProcessCmd_hmsc->csw.dDataResidue == 0)
{
MSC_BOT_SendCSW (SCSI_ProcessCmd_pdev, USBD_CSW_CMD_PASSED);
SCSI_ProcessCmd_callback(0);
return;
}
/* Prepare EP to Receive next packet */
if (Upstream_GetFreePacket(SCSI_Write10FreePacketCallback) != HAL_OK)
{
SCSI_SenseCode(SCSI_ProcessCmd_pdev,
SCSI_ProcessCmd_lun,
NOT_READY,
MEDIUM_NOT_PRESENT);
SCSI_ProcessCmd_callback(-1);
}
}
void SCSI_Write10BeginCallback(HAL_StatusTypeDef result)
{
if (result == HAL_BUSY)
{
SCSI_SenseCode(SCSI_ProcessCmd_pdev,
SCSI_ProcessCmd_lun,
NOT_READY,
WRITE_PROTECTED);
SCSI_ProcessCmd_callback(-1);
return;
}
if (result != HAL_OK)
{
SCSI_SenseCode(SCSI_ProcessCmd_pdev,
SCSI_ProcessCmd_lun,
NOT_READY,
MEDIUM_NOT_PRESENT);
SCSI_ProcessCmd_callback(-1);
return;
}
/* Prepare EP to receive first data packet */
SCSI_ProcessCmd_hmsc->bot_state = USBD_BOT_DATA_OUT;
if (Upstream_GetFreePacket(SCSI_Write10FreePacketCallback) != HAL_OK)
{
SCSI_SenseCode(SCSI_ProcessCmd_pdev,
SCSI_ProcessCmd_lun,
NOT_READY,
MEDIUM_NOT_PRESENT);
SCSI_ProcessCmd_callback(-1);
}
if (result == HAL_BUSY)
{
SCSI_SenseCode(SCSI_ProcessCmd_pdev,
SCSI_ProcessCmd_lun,
NOT_READY,
WRITE_PROTECTED);
SCSI_ProcessCmd_callback(-1);
return;
}
if (result != HAL_OK)
{
SCSI_SenseCode(SCSI_ProcessCmd_pdev,
SCSI_ProcessCmd_lun,
NOT_READY,
MEDIUM_NOT_PRESENT);
SCSI_ProcessCmd_callback(-1);
return;
}
/* Prepare EP to receive first data packet */
SCSI_ProcessCmd_hmsc->bot_state = USBD_BOT_DATA_OUT;
if (Upstream_GetFreePacket(SCSI_Write10FreePacketCallback) != HAL_OK)
{
SCSI_SenseCode(SCSI_ProcessCmd_pdev,
SCSI_ProcessCmd_lun,
NOT_READY,
MEDIUM_NOT_PRESENT);
SCSI_ProcessCmd_callback(-1);
}
}
void SCSI_Write10FreePacketCallback(UpstreamPacketTypeDef* freePacket)
{
SCSI_ProcessCmd_hmsc->bot_packet = freePacket;
SCSI_ProcessCmd_hmsc->bot_data = freePacket->Data;
USBD_LL_PrepareReceive (SCSI_ProcessCmd_pdev,
MSC_EPOUT_ADDR,
SCSI_ProcessCmd_hmsc->bot_data,
MIN(SCSI_ProcessCmd_hmsc->csw.dDataResidue, MSC_MEDIA_PACKET));
SCSI_ProcessCmd_callback(0); //Report eventual success!
SCSI_ProcessCmd_hmsc->bot_packet = freePacket;
SCSI_ProcessCmd_hmsc->bot_data = freePacket->Data;
USBD_LL_PrepareReceive (SCSI_ProcessCmd_pdev,
MSC_EPOUT_ADDR,
SCSI_ProcessCmd_hmsc->bot_data,
MIN(SCSI_ProcessCmd_hmsc->csw.dDataResidue, MSC_MEDIA_PACKET));
SCSI_ProcessCmd_callback(0); //Report eventual success!
}
@ -819,18 +819,18 @@ static void SCSI_Verify10(void)
if ((SCSI_ProcessCmd_params[1]& 0x02) == 0x02)
{
SCSI_SenseCode (SCSI_ProcessCmd_pdev,
SCSI_ProcessCmd_lun,
SCSI_ProcessCmd_lun,
ILLEGAL_REQUEST,
INVALID_FIELD_IN_COMMAND);
SCSI_ProcessCmd_callback(-1); /* Error, Verify Mode Not supported*/
SCSI_ProcessCmd_callback(-1); /* Error, Verify Mode Not supported*/
return;
}
if(SCSI_CheckAddressRange(SCSI_ProcessCmd_hmsc->scsi_blk_addr,
SCSI_ProcessCmd_hmsc->scsi_blk_len) < 0)
SCSI_ProcessCmd_hmsc->scsi_blk_len) < 0)
{
SCSI_ProcessCmd_callback(-1); /* error */
return;
SCSI_ProcessCmd_callback(-1); /* error */
return;
}
SCSI_ProcessCmd_hmsc->bot_data_length = 0;
SCSI_ProcessCmd_callback(0);
@ -846,11 +846,11 @@ static void SCSI_Verify10(void)
*/
static int8_t SCSI_CheckAddressRange (uint32_t blk_offset , uint16_t blk_nbr)
{
if ((blk_offset > SCSI_ProcessCmd_hmsc->scsi_blk_nbr) ||
((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_ProcessCmd_lun,
SCSI_ProcessCmd_lun,
ILLEGAL_REQUEST,
ADDRESS_OUT_OF_RANGE);
return -1;

@ -171,7 +171,7 @@ typedef struct _Device_cb
uint8_t (*IsoINIncomplete) (struct _USBD_HandleTypeDef *pdev , uint8_t epnum);
uint8_t (*IsoOUTIncomplete) (struct _USBD_HandleTypeDef *pdev , uint8_t epnum);
uint8_t (*FreeDataBuffer) (struct _USBD_HandleTypeDef *pdev);
uint8_t (*FreeDataBuffer) (struct _USBD_HandleTypeDef *pdev);
uint8_t *(*GetHSConfigDescriptor)(uint16_t *length);
uint8_t *(*GetFSConfigDescriptor)(uint16_t *length);

@ -548,8 +548,8 @@ USBD_StatusTypeDef USBD_DevDisconnected(USBD_HandleTypeDef *pdev)
USBD_StatusTypeDef USBD_BufferFreed(USBD_HandleTypeDef *pdev)
{
pdev->pClass->FreeDataBuffer(pdev);
return USBD_OK;
pdev->pClass->FreeDataBuffer(pdev);
return USBD_OK;
}
/**
* @}

@ -41,8 +41,8 @@
#include "board_config.h"
DMA_HandleTypeDef spiTxDmaHandle;
DMA_HandleTypeDef spiRxDmaHandle;
DMA_HandleTypeDef spiTxDmaHandle;
DMA_HandleTypeDef spiRxDmaHandle;
/**
@ -65,8 +65,8 @@ void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
if(hspi->Instance==SPI1)
{
/* Peripheral clock enable */
__HAL_RCC_SPI1_CLK_ENABLE();
__HAL_RCC_DMA2_CLK_ENABLE();
__HAL_RCC_SPI1_CLK_ENABLE();
__HAL_RCC_DMA2_CLK_ENABLE();
/**SPI1 GPIO Configuration
PA4 ------> GPIO manual slave select
@ -87,47 +87,47 @@ void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(SPI1_NSS_PORT, &GPIO_InitStruct);
//Configure downstream request pin and interrupt
GPIO_InitStruct.Pin = DOWNSTREAM_TX_OK_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT | GPIO_MODE_IT_FALLING;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(DOWNSTREAM_TX_OK_PORT, &GPIO_InitStruct);
HAL_NVIC_SetPriority(EXTI3_IRQn, INT_PRIORITY_EXT3I, 0);
HAL_NVIC_EnableIRQ(EXTI3_IRQn);
//Prepare Tx DMA stream
hspi->hdmatx = &spiTxDmaHandle;
spiTxDmaHandle.Instance = DMA2_Stream3;
spiTxDmaHandle.Parent = hspi;
spiTxDmaHandle.Init.Channel = DMA_CHANNEL_3;
spiTxDmaHandle.Init.Direction = DMA_MEMORY_TO_PERIPH;
spiTxDmaHandle.Init.PeriphInc = DMA_PINC_DISABLE;
spiTxDmaHandle.Init.MemInc = DMA_MINC_ENABLE;
spiTxDmaHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
spiTxDmaHandle.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
spiTxDmaHandle.Init.Mode = DMA_NORMAL;
spiTxDmaHandle.Init.Priority = DMA_PRIORITY_MEDIUM;
spiTxDmaHandle.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
HAL_DMA_Init(&spiTxDmaHandle);
HAL_NVIC_SetPriority(DMA2_Stream3_IRQn, INT_PRIORITY_SPI_DMA, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream3_IRQn);
//Prepare Rx DMA stream
hspi->hdmarx = &spiRxDmaHandle;
spiRxDmaHandle.Instance = DMA2_Stream2;
spiRxDmaHandle.Parent = hspi;
spiRxDmaHandle.Init.Channel = DMA_CHANNEL_3;
spiRxDmaHandle.Init.Direction = DMA_PERIPH_TO_MEMORY;
spiRxDmaHandle.Init.PeriphInc = DMA_PINC_DISABLE;
spiRxDmaHandle.Init.MemInc = DMA_MINC_ENABLE;
spiRxDmaHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
spiRxDmaHandle.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
spiRxDmaHandle.Init.Mode = DMA_NORMAL;
spiRxDmaHandle.Init.Priority = DMA_PRIORITY_MEDIUM;
spiRxDmaHandle.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
HAL_DMA_Init(&spiRxDmaHandle);
HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, INT_PRIORITY_SPI_DMA, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn);
//Configure downstream request pin and interrupt
GPIO_InitStruct.Pin = DOWNSTREAM_TX_OK_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT | GPIO_MODE_IT_FALLING;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(DOWNSTREAM_TX_OK_PORT, &GPIO_InitStruct);
HAL_NVIC_SetPriority(EXTI3_IRQn, INT_PRIORITY_EXT3I, 0);
HAL_NVIC_EnableIRQ(EXTI3_IRQn);
//Prepare Tx DMA stream
hspi->hdmatx = &spiTxDmaHandle;
spiTxDmaHandle.Instance = DMA2_Stream3;
spiTxDmaHandle.Parent = hspi;
spiTxDmaHandle.Init.Channel = DMA_CHANNEL_3;
spiTxDmaHandle.Init.Direction = DMA_MEMORY_TO_PERIPH;
spiTxDmaHandle.Init.PeriphInc = DMA_PINC_DISABLE;
spiTxDmaHandle.Init.MemInc = DMA_MINC_ENABLE;
spiTxDmaHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
spiTxDmaHandle.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
spiTxDmaHandle.Init.Mode = DMA_NORMAL;
spiTxDmaHandle.Init.Priority = DMA_PRIORITY_MEDIUM;
spiTxDmaHandle.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
HAL_DMA_Init(&spiTxDmaHandle);
HAL_NVIC_SetPriority(DMA2_Stream3_IRQn, INT_PRIORITY_SPI_DMA, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream3_IRQn);
//Prepare Rx DMA stream
hspi->hdmarx = &spiRxDmaHandle;
spiRxDmaHandle.Instance = DMA2_Stream2;
spiRxDmaHandle.Parent = hspi;
spiRxDmaHandle.Init.Channel = DMA_CHANNEL_3;
spiRxDmaHandle.Init.Direction = DMA_PERIPH_TO_MEMORY;
spiRxDmaHandle.Init.PeriphInc = DMA_PINC_DISABLE;
spiRxDmaHandle.Init.MemInc = DMA_MINC_ENABLE;
spiRxDmaHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
spiRxDmaHandle.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
spiRxDmaHandle.Init.Mode = DMA_NORMAL;
spiRxDmaHandle.Init.Priority = DMA_PRIORITY_MEDIUM;
spiRxDmaHandle.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
HAL_DMA_Init(&spiRxDmaHandle);
HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, INT_PRIORITY_SPI_DMA, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn);
}
}
@ -148,10 +148,10 @@ void HAL_SPI_MspDeInit(SPI_HandleTypeDef* hspi)
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7);
HAL_DMA_DeInit(&spiTxDmaHandle);
HAL_DMA_DeInit(&spiRxDmaHandle);
HAL_DMA_DeInit(&spiRxDmaHandle);
HAL_NVIC_DisableIRQ(DMA2_Stream3_IRQn);
HAL_NVIC_DisableIRQ(DMA2_Stream2_IRQn);
HAL_NVIC_DisableIRQ(DMA2_Stream3_IRQn);
HAL_NVIC_DisableIRQ(DMA2_Stream2_IRQn);
}
}

@ -47,9 +47,9 @@
/* USER CODE END 0 */
/* External variables --------------------------------------------------------*/
extern PCD_HandleTypeDef hpcd_USB_OTG_FS;
extern DMA_HandleTypeDef spiTxDmaHandle;
extern DMA_HandleTypeDef spiRxDmaHandle;
extern PCD_HandleTypeDef hpcd_USB_OTG_FS;
extern DMA_HandleTypeDef spiTxDmaHandle;
extern DMA_HandleTypeDef spiRxDmaHandle;
/******************************************************************************/
@ -69,27 +69,27 @@ void SysTick_Handler(void)
/////////////////////////
void OTG_FS_IRQHandler(void)
{
HAL_PCD_IRQHandler(&hpcd_USB_OTG_FS);
HAL_PCD_IRQHandler(&hpcd_USB_OTG_FS);
}
void DMA2_Stream2_IRQHandler(void)
{
INT_ACTIVE_ON;
HAL_DMA_IRQHandler(&spiRxDmaHandle);
INT_ACTIVE_OFF;
INT_ACTIVE_ON;
HAL_DMA_IRQHandler(&spiRxDmaHandle);
INT_ACTIVE_OFF;
}
void DMA2_Stream3_IRQHandler(void)
{
INT_ACTIVE_ON;
HAL_DMA_IRQHandler(&spiTxDmaHandle);
INT_ACTIVE_OFF;
INT_ACTIVE_ON;
HAL_DMA_IRQHandler(&spiTxDmaHandle);
INT_ACTIVE_OFF;
}
void EXTI3_IRQHandler(void)
{
__HAL_GPIO_EXTI_CLEAR_IT(DOWNSTREAM_TX_OK_PIN);
Upstream_TxOkInterrupt();
__HAL_GPIO_EXTI_CLEAR_IT(DOWNSTREAM_TX_OK_PIN);
Upstream_TxOkInterrupt();
}
/////////////////////////
/////////////////////////

@ -15,51 +15,51 @@
uint16_t FaultLedBlinkRate = 0;
uint16_t FaultLedBlinkCounter = 0;
uint8_t FaultLedState = 0;
uint16_t FaultLedBlinkRate = 0;
uint16_t FaultLedBlinkCounter = 0;
uint8_t FaultLedState = 0;
void LED_Init(void)
{
//RUN_LED_ON;
FAULT_LED_ON;
HAL_Delay(STARTUP_FLASH_DELAY);
//RUN_LED_OFF;
FAULT_LED_OFF;
//RUN_LED_ON;
FAULT_LED_ON;
HAL_Delay(STARTUP_FLASH_DELAY);
//RUN_LED_OFF;
FAULT_LED_OFF;
}
void LED_Fault_SetBlinkRate(uint16_t newBlinkRate)
{
FaultLedBlinkRate = newBlinkRate;
if (newBlinkRate == 0)
{
FaultLedState = 0;
FAULT_LED_OFF;
}
FaultLedBlinkRate = newBlinkRate;
if (newBlinkRate == 0)
{
FaultLedState = 0;
FAULT_LED_OFF;
}
}
void LED_DoBlinks(void)
{
if (FaultLedBlinkRate > 0)
{
FaultLedBlinkCounter++;
if (FaultLedBlinkCounter >= FaultLedBlinkRate)
{
FaultLedBlinkCounter = 0;
if (FaultLedState)
{
FaultLedState = 0;
FAULT_LED_OFF;
}
else
{
FaultLedState = 1;
FAULT_LED_ON;
}
}
}
if (FaultLedBlinkRate > 0)
{
FaultLedBlinkCounter++;
if (FaultLedBlinkCounter >= FaultLedBlinkRate)
{
FaultLedBlinkCounter = 0;
if (FaultLedState)
{
FaultLedState = 0;
FAULT_LED_OFF;
}
else
{
FaultLedState = 1;
FAULT_LED_ON;
}
}
}
}

@ -56,67 +56,67 @@ void CheckFirmwareMatchesHardware(void);
int main(void)
{
//First things first!
CheckFirmwareMatchesHardware();
//First things first!
CheckFirmwareMatchesHardware();
/* Configure the system clock */
SystemClock_Config();
/* Configure the system clock */
SystemClock_Config();
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Initialize all configured peripherals */
GPIO_Init();
LED_Init();
USB_Device_Init();
/* Initialize all configured peripherals */
GPIO_Init();
LED_Init();
USB_Device_Init();
Upstream_InitStateMachine();
Upstream_InitStateMachine();
while (1)
{
while (1)
{
}
}
}
void CheckFirmwareMatchesHardware(void)
{
//Check we are running on the expected hardware:
//STM32F405 on an Olimex dev board
GPIO_InitTypeDef GPIO_InitStruct;
if ((*(uint32_t*)DBGMCU_BASE & DBGMCU_IDCODE_DEV_ID) == DBGMCU_IDCODE_DEV_ID_405_407_415_417)
{
//The H405 board has a STAT LED on PC12. If there is no pullup on this pin,
//then we are probably running on another board.
__HAL_RCC_GPIOC_CLK_ENABLE();
GPIO_InitStruct.Pin = FAULT_LED_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
GPIO_InitStruct.Alternate = 0;
HAL_GPIO_Init(FAULT_LED_PORT, &GPIO_InitStruct);
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(FAULT_LED_PORT, &GPIO_InitStruct);
if (FAULT_LED_PORT->IDR & FAULT_LED_PIN)
{
//Pin pulls up, so this is an H405 board :)
return;
}
}
//This is not the hardware we expected, so turn on our fault LED(s) and die in a heap.
GPIO_InitStruct.Pin = FAULT_LED_PIN | OTHER_BOARDS_FAULT_LED_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(FAULT_LED_PORT, &GPIO_InitStruct);
FAULT_LED_ON;
OTHER_BOARDS_FAULT_LED_ON;
while (1);
//Check we are running on the expected hardware:
//STM32F405 on an Olimex dev board
GPIO_InitTypeDef GPIO_InitStruct;
if ((*(uint32_t*)DBGMCU_BASE & DBGMCU_IDCODE_DEV_ID) == DBGMCU_IDCODE_DEV_ID_405_407_415_417)
{
//The H405 board has a STAT LED on PC12. If there is no pullup on this pin,
//then we are probably running on another board.
__HAL_RCC_GPIOC_CLK_ENABLE();
GPIO_InitStruct.Pin = FAULT_LED_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
GPIO_InitStruct.Alternate = 0;
HAL_GPIO_Init(FAULT_LED_PORT, &GPIO_InitStruct);
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(FAULT_LED_PORT, &GPIO_InitStruct);
if (FAULT_LED_PORT->IDR & FAULT_LED_PIN)
{
//Pin pulls up, so this is an H405 board :)
return;
}
}
//This is not the hardware we expected, so turn on our fault LED(s) and die in a heap.
GPIO_InitStruct.Pin = FAULT_LED_PIN | OTHER_BOARDS_FAULT_LED_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(FAULT_LED_PORT, &GPIO_InitStruct);
FAULT_LED_ON;
OTHER_BOARDS_FAULT_LED_ON;
while (1);
}
@ -144,9 +144,9 @@ void SystemClock_Config(void)
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) while (1);
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK |
RCC_CLOCKTYPE_HCLK |
RCC_CLOCKTYPE_PCLK1 |
RCC_CLOCKTYPE_PCLK2;
RCC_CLOCKTYPE_HCLK |
RCC_CLOCKTYPE_PCLK1 |
RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
@ -167,47 +167,47 @@ void SystemClock_Config(void)
*/
void GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitTypeDef GPIO_InitStruct;
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
//__HAL_RCC_GPIOH_CLK_ENABLE(); //HS oscillator on port H
//Bulk initialise all ports as inputs with pullups active,
//excluding JTAG pins which must remain as AF0!
GPIO_InitStruct.Pin = (GPIO_PIN_All & ~(PA_JTMS | PA_JTCK | PA_JTDI));
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
GPIO_InitStruct.Alternate = 0;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = (GPIO_PIN_All & ~(PB_JTDO | PB_NJTRST));
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_All;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
//USB_P is analog input
GPIO_InitStruct.Pin = USB_P_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
HAL_GPIO_Init(USB_P_PORT, &GPIO_InitStruct);
//STAT_LED is output
GPIO_InitStruct.Pin = FAULT_LED_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(FAULT_LED_PORT, &GPIO_InitStruct);
FAULT_LED_OFF;
//SPI_INT_ACTIVE indicator
GPIO_InitStruct.Pin = INT_ACTIVE_PIN;
//GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
//GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(INT_ACTIVE_PORT, &GPIO_InitStruct);
INT_ACTIVE_OFF;
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
//__HAL_RCC_GPIOH_CLK_ENABLE(); //HS oscillator on port H
//Bulk initialise all ports as inputs with pullups active,
//excluding JTAG pins which must remain as AF0!
GPIO_InitStruct.Pin = (GPIO_PIN_All & ~(PA_JTMS | PA_JTCK | PA_JTDI));
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
GPIO_InitStruct.Alternate = 0;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = (GPIO_PIN_All & ~(PB_JTDO | PB_NJTRST));
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_All;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
//USB_P is analog input
GPIO_InitStruct.Pin = USB_P_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
HAL_GPIO_Init(USB_P_PORT, &GPIO_InitStruct);
//STAT_LED is output
GPIO_InitStruct.Pin = FAULT_LED_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(FAULT_LED_PORT, &GPIO_InitStruct);
FAULT_LED_OFF;
//SPI_INT_ACTIVE indicator
GPIO_InitStruct.Pin = INT_ACTIVE_PIN;
//GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
//GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(INT_ACTIVE_PORT, &GPIO_InitStruct);
INT_ACTIVE_OFF;
}
/* USER CODE BEGIN 4 */

@ -18,15 +18,15 @@
//Stuff we need to save for our callbacks to use:
UpstreamMSCCallbackTypeDef TestReadyCallback;
UpstreamMSCCallbackUintPacketTypeDef GetCapacityCallback;
UpstreamMSCCallbackPacketTypeDef GetStreamDataCallback;
uint64_t BlockStart;
uint32_t BlockCount;
uint32_t ByteCount;
UpstreamMSCCallbackTypeDef TestReadyCallback;
UpstreamMSCCallbackUintPacketTypeDef GetCapacityCallback;
UpstreamMSCCallbackPacketTypeDef GetStreamDataCallback;
uint64_t BlockStart;
uint32_t BlockCount;
uint32_t ByteCount;
UpstreamPacketTypeDef* ReadStreamPacket;
uint8_t ReadStreamBusy;
UpstreamPacketTypeDef* ReadStreamPacket;
uint8_t ReadStreamBusy;
static void Upstream_MSC_TestReadyFreePacketCallback(UpstreamPacketTypeDef* freePacket);
@ -41,325 +41,325 @@ static void Upstream_MSC_BeginWriteReplyCallback(UpstreamPacketTypeDef* replyPac
HAL_StatusTypeDef Upstream_MSC_TestReady(UpstreamMSCCallbackTypeDef callback)
{
if (Upstream_StateMachine_CheckClassOperationOk() != HAL_OK)
{
return HAL_ERROR;
}
if (Upstream_StateMachine_CheckClassOperationOk() != HAL_OK)
{
return HAL_ERROR;
}
TestReadyCallback = callback;
return Upstream_GetFreePacket(Upstream_MSC_TestReadyFreePacketCallback);
TestReadyCallback = callback;
return Upstream_GetFreePacket(Upstream_MSC_TestReadyFreePacketCallback);
}
void Upstream_MSC_TestReadyFreePacketCallback(UpstreamPacketTypeDef* freePacket)
{
freePacket->Length16 = UPSTREAM_PACKET_HEADER_LEN_16;
freePacket->CommandClass = COMMAND_CLASS_MASS_STORAGE;
freePacket->Command = COMMAND_MSC_TEST_UNIT_READY;
if (Upstream_TransmitPacket(freePacket) == HAL_OK)
{
Upstream_ReleasePacket(freePacket);
if (Upstream_ReceivePacket(Upstream_MSC_TestReadyReplyCallback) != HAL_OK)
{
TestReadyCallback(HAL_ERROR);
}
return;
}
//else:
Upstream_ReleasePacket(freePacket);
TestReadyCallback(HAL_ERROR);
freePacket->Length16 = UPSTREAM_PACKET_HEADER_LEN_16;
freePacket->CommandClass = COMMAND_CLASS_MASS_STORAGE;
freePacket->Command = COMMAND_MSC_TEST_UNIT_READY;
if (Upstream_TransmitPacket(freePacket) == HAL_OK)
{
Upstream_ReleasePacket(freePacket);
if (Upstream_ReceivePacket(Upstream_MSC_TestReadyReplyCallback) != HAL_OK)
{
TestReadyCallback(HAL_ERROR);
}
return;
}
//else:
Upstream_ReleasePacket(freePacket);
TestReadyCallback(HAL_ERROR);
}
void Upstream_MSC_TestReadyReplyCallback(UpstreamPacketTypeDef* replyPacket)
{
if (Upstream_StateMachine_CheckClassOperationOk() != HAL_OK)
{
return;
}
if (replyPacket == NULL)
{
TestReadyCallback(HAL_ERROR);
return;
}
if ((replyPacket->Length16 != (UPSTREAM_PACKET_HEADER_LEN_16 + 1)) ||
(replyPacket->Data[0] != HAL_OK))
{
Upstream_ReleasePacket(replyPacket);
TestReadyCallback(HAL_ERROR);
return;
}
Upstream_ReleasePacket(replyPacket);
TestReadyCallback(HAL_OK);
if (Upstream_StateMachine_CheckClassOperationOk() != HAL_OK)
{
return;
}
if (replyPacket == NULL)
{
TestReadyCallback(HAL_ERROR);
return;
}
if ((replyPacket->Length16 != (UPSTREAM_PACKET_HEADER_LEN_16 + 1)) ||
(replyPacket->Data[0] != HAL_OK))
{
Upstream_ReleasePacket(replyPacket);
TestReadyCallback(HAL_ERROR);
return;
}
Upstream_ReleasePacket(replyPacket);
TestReadyCallback(HAL_OK);
}
HAL_StatusTypeDef Upstream_MSC_GetCapacity(UpstreamMSCCallbackUintPacketTypeDef callback)
{
UpstreamPacketTypeDef* freePacket;
if (Upstream_StateMachine_CheckClassOperationOk() != HAL_OK)
{
return HAL_ERROR;
}
GetCapacityCallback = callback;
freePacket = Upstream_GetFreePacketImmediately();
if (freePacket == NULL)
{
return HAL_ERROR;
}
freePacket->Length16 = UPSTREAM_PACKET_HEADER_LEN_16;
freePacket->CommandClass = COMMAND_CLASS_MASS_STORAGE;
freePacket->Command = COMMAND_MSC_GET_CAPACITY;
if (Upstream_TransmitPacket(freePacket) == HAL_OK)
{
return Upstream_ReceivePacket(Upstream_MSC_GetCapacityReplyCallback);
}
//else:
return HAL_ERROR;
UpstreamPacketTypeDef* freePacket;
if (Upstream_StateMachine_CheckClassOperationOk() != HAL_OK)
{
return HAL_ERROR;
}
GetCapacityCallback = callback;
freePacket = Upstream_GetFreePacketImmediately();
if (freePacket == NULL)
{
return HAL_ERROR;
}
freePacket->Length16 = UPSTREAM_PACKET_HEADER_LEN_16;
freePacket->CommandClass = COMMAND_CLASS_MASS_STORAGE;
freePacket->Command = COMMAND_MSC_GET_CAPACITY;
if (Upstream_TransmitPacket(freePacket) == HAL_OK)
{
return Upstream_ReceivePacket(Upstream_MSC_GetCapacityReplyCallback);
}
//else:
return HAL_ERROR;
}
void Upstream_MSC_GetCapacityReplyCallback(UpstreamPacketTypeDef* replyPacket)
{
uint32_t uint1;
uint32_t uint2;
if (Upstream_StateMachine_CheckClassOperationOk() != HAL_OK)
{
return;
}
if (replyPacket == NULL)
{
GetCapacityCallback(NULL, 0, 0);
return;
}
if (replyPacket->Length16 != (UPSTREAM_PACKET_HEADER_LEN_16 + (8 / 2)))
{
GetCapacityCallback(NULL, 0, 0);
return;
}
uint1 = *(uint32_t*)&(replyPacket->Data[0]);
uint2 = *(uint32_t*)&(replyPacket->Data[4]);
GetCapacityCallback(replyPacket, uint1, uint2); //usb_msc_scsi will use this packet, so don't release now
uint32_t uint1;
uint32_t uint2;
if (Upstream_StateMachine_CheckClassOperationOk() != HAL_OK)
{
return;
}
if (replyPacket == NULL)
{
GetCapacityCallback(NULL, 0, 0);
return;
}
if (replyPacket->Length16 != (UPSTREAM_PACKET_HEADER_LEN_16 + (8 / 2)))
{
GetCapacityCallback(NULL, 0, 0);
return;
}
uint1 = *(uint32_t*)&(replyPacket->Data[0]);
uint2 = *(uint32_t*)&(replyPacket->Data[4]);
GetCapacityCallback(replyPacket, uint1, uint2); //usb_msc_scsi will use this packet, so don't release now
}
HAL_StatusTypeDef Upstream_MSC_BeginRead(UpstreamMSCCallbackTypeDef callback,
uint64_t readBlockStart,
uint32_t readBlockCount,
uint32_t readByteCount)
uint64_t readBlockStart,
uint32_t readBlockCount,
uint32_t readByteCount)
{
if (Upstream_StateMachine_CheckClassOperationOk() != HAL_OK)
{
return HAL_ERROR;
}
BlockStart = readBlockStart;
BlockCount = readBlockCount;
ByteCount = readByteCount;
ReadStreamPacket = NULL; //Prepare for GetStreamDataPacket's use
ReadStreamBusy = 0;
TestReadyCallback = callback;
return Upstream_GetFreePacket(Upstream_MSC_BeginReadFreePacketCallback);
if (Upstream_StateMachine_CheckClassOperationOk() != HAL_OK)
{
return HAL_ERROR;
}
BlockStart = readBlockStart;
BlockCount = readBlockCount;
ByteCount = readByteCount;
ReadStreamPacket = NULL; //Prepare for GetStreamDataPacket's use
ReadStreamBusy = 0;
TestReadyCallback = callback;
return Upstream_GetFreePacket(Upstream_MSC_BeginReadFreePacketCallback);
}
void Upstream_MSC_BeginReadFreePacketCallback(UpstreamPacketTypeDef* freePacket)
{
freePacket->Length16 = UPSTREAM_PACKET_HEADER_LEN_16 + ((4 * 3) / 2);
freePacket->CommandClass = COMMAND_CLASS_MASS_STORAGE;
freePacket->Command = COMMAND_MSC_READ;
*(uint64_t*)&(freePacket->Data[0]) = BlockStart;
*(uint32_t*)&(freePacket->Data[8]) = BlockCount;
if (Upstream_TransmitPacket(freePacket) == HAL_OK)
{
if (Upstream_ReceivePacket(Upstream_MSC_TestReadyReplyCallback) != HAL_OK) //Re-use TestReadyReplyCallback because it does exactly what we want!
{
TestReadyCallback(HAL_ERROR);
}
return;
}
//else:
Upstream_ReleasePacket(freePacket);
TestReadyCallback(HAL_ERROR);
freePacket->Length16 = UPSTREAM_PACKET_HEADER_LEN_16 + ((4 * 3) / 2);
freePacket->CommandClass = COMMAND_CLASS_MASS_STORAGE;
freePacket->Command = COMMAND_MSC_READ;
*(uint64_t*)&(freePacket->Data[0]) = BlockStart;
*(uint32_t*)&(freePacket->Data[8]) = BlockCount;
if (Upstream_TransmitPacket(freePacket) == HAL_OK)
{
if (Upstream_ReceivePacket(Upstream_MSC_TestReadyReplyCallback) != HAL_OK) //Re-use TestReadyReplyCallback because it does exactly what we want!
{
TestReadyCallback(HAL_ERROR);
}
return;
}
//else:
Upstream_ReleasePacket(freePacket);
TestReadyCallback(HAL_ERROR);
}
HAL_StatusTypeDef Upstream_MSC_GetStreamDataPacket(UpstreamMSCCallbackPacketTypeDef callback)
{
if (Upstream_StateMachine_CheckClassOperationOk() != HAL_OK)
{
return HAL_ERROR;
}
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?
{
Upstream_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 Upstream_ReceivePacket(Upstream_MSC_GetStreamDataPacketCallback);
if (Upstream_StateMachine_CheckClassOperationOk() != HAL_OK)
{
return HAL_ERROR;
}
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?
{
Upstream_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 Upstream_ReceivePacket(Upstream_MSC_GetStreamDataPacketCallback);
}
void Upstream_MSC_GetStreamDataPacketCallback(UpstreamPacketTypeDef* replyPacket)
{
uint16_t dataLength8;
ReadStreamBusy = 0;
if (Upstream_StateMachine_CheckClassOperationOk() != HAL_OK)
{
return;
}
if (GetStreamDataCallback == NULL)
{
ReadStreamPacket = replyPacket; //We used up our callback already, so save this one for later.
return;
}
if (replyPacket == NULL)
{
GetStreamDataCallback(NULL, 0);
return;
}
dataLength8 = (replyPacket->Length16 - UPSTREAM_PACKET_HEADER_LEN_16) * 2;
if (((replyPacket->CommandClass & COMMAND_CLASS_DATA_FLAG) == 0) || //Any 'command' reply (as opposed to 'data' reply) is an automatic fail here
(replyPacket->Length16 <= UPSTREAM_PACKET_HEADER_LEN_16) || //Should be at least one data byte in the reply.
(dataLength8 > ByteCount)) //No more data than expected transfer length
{
GetStreamDataCallback(NULL, 0);
return;
}
ByteCount -= dataLength8;
GetStreamDataCallback(replyPacket, dataLength8); //usb_msc_scsi will use this packet, so don't release now
if (ByteCount > 0)
{
Upstream_MSC_GetStreamDataPacket(NULL); //Try to get the next packet now, before USB asks for it
}
uint16_t dataLength8;
ReadStreamBusy = 0;
if (Upstream_StateMachine_CheckClassOperationOk() != HAL_OK)
{
return;
}
if (GetStreamDataCallback == NULL)
{
ReadStreamPacket = replyPacket; //We used up our callback already, so save this one for later.
return;
}
if (replyPacket == NULL)
{
GetStreamDataCallback(NULL, 0);
return;
}
dataLength8 = (replyPacket->Length16 - UPSTREAM_PACKET_HEADER_LEN_16) * 2;
if (((replyPacket->CommandClass & COMMAND_CLASS_DATA_FLAG) == 0) || //Any 'command' reply (as opposed to 'data' reply) is an automatic fail here
(replyPacket->Length16 <= UPSTREAM_PACKET_HEADER_LEN_16) || //Should be at least one data byte in the reply.
(dataLength8 > ByteCount)) //No more data than expected transfer length
{
GetStreamDataCallback(NULL, 0);
return;
}
ByteCount -= dataLength8;
GetStreamDataCallback(replyPacket, dataLength8); //usb_msc_scsi will use this packet, so don't release now
if (ByteCount > 0)
{
Upstream_MSC_GetStreamDataPacket(NULL); //Try to get the next packet now, before USB asks for it
}
}
HAL_StatusTypeDef Upstream_MSC_BeginWrite(UpstreamMSCCallbackTypeDef callback,
uint64_t writeBlockStart,
uint32_t writeBlockCount)
uint64_t writeBlockStart,
uint32_t writeBlockCount)
{
if (Upstream_StateMachine_CheckClassOperationOk() != HAL_OK)
{
return HAL_ERROR;
}
BlockStart = writeBlockStart;
BlockCount = writeBlockCount;
TestReadyCallback = callback;
return Upstream_GetFreePacket(Upstream_MSC_BeginWriteFreePacketCallback);
if (Upstream_StateMachine_CheckClassOperationOk() != HAL_OK)
{
return HAL_ERROR;
}
BlockStart = writeBlockStart;
BlockCount = writeBlockCount;
TestReadyCallback = callback;
return Upstream_GetFreePacket(Upstream_MSC_BeginWriteFreePacketCallback);
}
void Upstream_MSC_BeginWriteFreePacketCallback(UpstreamPacketTypeDef* freePacket)
{
freePacket->Length16 = UPSTREAM_PACKET_HEADER_LEN_16 + ((4 * 3) / 2);
freePacket->CommandClass = COMMAND_CLASS_MASS_STORAGE;
freePacket->Command = COMMAND_MSC_WRITE;
*(uint64_t*)&(freePacket->Data[0]) = BlockStart;
*(uint32_t*)&(freePacket->Data[8]) = BlockCount;
if (Upstream_TransmitPacket(freePacket) == HAL_OK)
{
if (Upstream_ReceivePacket(Upstream_MSC_BeginWriteReplyCallback) != HAL_OK)
{
TestReadyCallback(HAL_ERROR);
}
return;
}
//else:
Upstream_ReleasePacket(freePacket);
TestReadyCallback(HAL_ERROR);
freePacket->Length16 = UPSTREAM_PACKET_HEADER_LEN_16 + ((4 * 3) / 2);
freePacket->CommandClass = COMMAND_CLASS_MASS_STORAGE;
freePacket->Command = COMMAND_MSC_WRITE;
*(uint64_t*)&(freePacket->Data[0]) = BlockStart;
*(uint32_t*)&(freePacket->Data[8]) = BlockCount;
if (Upstream_TransmitPacket(freePacket) == HAL_OK)
{
if (Upstream_ReceivePacket(Upstream_MSC_BeginWriteReplyCallback) != HAL_OK)
{
TestReadyCallback(HAL_ERROR);
}
return;
}
//else:
Upstream_ReleasePacket(freePacket);
TestReadyCallback(HAL_ERROR);
}
void Upstream_MSC_BeginWriteReplyCallback(UpstreamPacketTypeDef* replyPacket)
{
uint8_t tempResult;
if (Upstream_StateMachine_CheckClassOperationOk() != HAL_OK)
{
return;
}
if (replyPacket == NULL)
{
TestReadyCallback(HAL_ERROR);
return;
}
if ((replyPacket->Length16 != (UPSTREAM_PACKET_HEADER_LEN_16 + 1)) ||
((replyPacket->Data[0] != HAL_OK) && (replyPacket->Data[0] != HAL_BUSY)))
{
Upstream_ReleasePacket(replyPacket);
TestReadyCallback(HAL_ERROR);
return;
}
tempResult = replyPacket->Data[0];
Upstream_ReleasePacket(replyPacket);
TestReadyCallback(tempResult);
uint8_t tempResult;
if (Upstream_StateMachine_CheckClassOperationOk() != HAL_OK)
{
return;
}
if (replyPacket == NULL)
{
TestReadyCallback(HAL_ERROR);
return;
}
if ((replyPacket->Length16 != (UPSTREAM_PACKET_HEADER_LEN_16 + 1)) ||
((replyPacket->Data[0] != HAL_OK) && (replyPacket->Data[0] != HAL_BUSY)))
{
Upstream_ReleasePacket(replyPacket);
TestReadyCallback(HAL_ERROR);
return;
}
tempResult = replyPacket->Data[0];
Upstream_ReleasePacket(replyPacket);
TestReadyCallback(tempResult);
}
HAL_StatusTypeDef Upstream_MSC_PutStreamDataPacket(UpstreamPacketTypeDef* packetToSend,
uint32_t dataLength8)
uint32_t dataLength8)
{
if (Upstream_StateMachine_CheckClassOperationOk() != HAL_OK)
{
return HAL_ERROR;
}
if ((dataLength8 % 2) != 0)
{
return HAL_ERROR;
}
packetToSend->Length16 = (dataLength8 / 2) + UPSTREAM_PACKET_HEADER_LEN_16;
packetToSend->CommandClass = COMMAND_CLASS_MASS_STORAGE | COMMAND_CLASS_DATA_FLAG;
packetToSend->Command = COMMAND_MSC_WRITE;
return Upstream_TransmitPacket(packetToSend);
if (Upstream_StateMachine_CheckClassOperationOk() != HAL_OK)
{
return HAL_ERROR;
}
if ((dataLength8 % 2) != 0)
{
return HAL_ERROR;
}
packetToSend->Length16 = (dataLength8 / 2) + UPSTREAM_PACKET_HEADER_LEN_16;
packetToSend->CommandClass = COMMAND_CLASS_MASS_STORAGE | COMMAND_CLASS_DATA_FLAG;
packetToSend->Command = COMMAND_MSC_WRITE;
return Upstream_TransmitPacket(packetToSend);
}

@ -21,12 +21,12 @@
//Stuff we need to save for our callbacks to use:
UpstreamMSCCallbackTypeDef TestReadyCallback;
UpstreamMSCCallbackUintPacketTypeDef GetCapacityCallback;
UpstreamMSCCallbackPacketTypeDef GetStreamDataCallback;
uint32_t ByteCount;
UpstreamPacketTypeDef* ReadStreamPacket;
uint8_t ReadStreamBusy;
UpstreamMSCCallbackTypeDef TestReadyCallback;
UpstreamMSCCallbackUintPacketTypeDef GetCapacityCallback;
UpstreamMSCCallbackPacketTypeDef GetStreamDataCallback;
uint32_t ByteCount;
UpstreamPacketTypeDef* ReadStreamPacket;
uint8_t ReadStreamBusy;
static void Upstream_MSC_TestReadyReplyCallback(UpstreamPacketTypeDef* replyPacket);
@ -38,216 +38,216 @@ static void Upstream_MSC_BeginWriteReplyCallback(UpstreamPacketTypeDef* replyPac
HAL_StatusTypeDef Upstream_MSC_TestReady(UpstreamMSCCallbackTypeDef callback)
{
UpstreamPacketTypeDef* freePacket;
HAL_StatusTypeDef tempResult;
TestReadyCallback = callback;
freePacket = Upstream_GetFreePacketImmediately();
freePacket->Length = UPSTREAM_PACKET_HEADER_LEN;
freePacket->CommandClass = COMMAND_CLASS_MASS_STORAGE;
freePacket->Command = COMMAND_MSC_TEST_UNIT_READY;
tempResult = Upstream_TransmitPacket(freePacket);
if (tempResult != HAL_OK)
{
return tempResult;
}
//return Upstream_GetPacket(Upstream_MSC_TestReadyReplyCallback);
return Upstream_GetFreePacket(Upstream_MSC_TestReadyReplyCallback);
UpstreamPacketTypeDef* freePacket;
HAL_StatusTypeDef tempResult;
TestReadyCallback = callback;
freePacket = Upstream_GetFreePacketImmediately();
freePacket->Length = UPSTREAM_PACKET_HEADER_LEN;
freePacket->CommandClass = COMMAND_CLASS_MASS_STORAGE;
freePacket->Command = COMMAND_MSC_TEST_UNIT_READY;
tempResult = Upstream_TransmitPacket(freePacket);
if (tempResult != HAL_OK)
{
return tempResult;
}
//return Upstream_GetPacket(Upstream_MSC_TestReadyReplyCallback);
return Upstream_GetFreePacket(Upstream_MSC_TestReadyReplyCallback);
}
void Upstream_MSC_TestReadyReplyCallback(UpstreamPacketTypeDef* replyPacket)
{
// if ((replyPacket->Length != (UPSTREAM_PACKET_HEADER_LEN + 1)) ||
// (replyPacket->CommandClass & COMMAND_CLASS_DATA_FLAG) ||
// (replyPacket->Data[0] != HAL_OK))
// {
// Upstream_ReleasePacket(replyPacket);
// TestReadyCallback(HAL_ERROR);
// return;
// }
Upstream_ReleasePacket(replyPacket);
TestReadyCallback(HAL_OK);
// if ((replyPacket->Length != (UPSTREAM_PACKET_HEADER_LEN + 1)) ||
// (replyPacket->CommandClass & COMMAND_CLASS_DATA_FLAG) ||
// (replyPacket->Data[0] != HAL_OK))
// {
// Upstream_ReleasePacket(replyPacket);
// TestReadyCallback(HAL_ERROR);
// return;
// }
Upstream_ReleasePacket(replyPacket);
TestReadyCallback(HAL_OK);
}
HAL_StatusTypeDef Upstream_MSC_GetCapacity(UpstreamMSCCallbackUintPacketTypeDef callback)
{
UpstreamPacketTypeDef* freePacket;
HAL_StatusTypeDef tempResult;
GetCapacityCallback = callback;
freePacket = Upstream_GetFreePacketImmediately();
freePacket->Length = UPSTREAM_PACKET_HEADER_LEN;
freePacket->CommandClass = COMMAND_CLASS_MASS_STORAGE;
freePacket->Command = COMMAND_MSC_GET_CAPACITY;
tempResult = Upstream_TransmitPacket(freePacket);
if (tempResult != HAL_OK)
{
return tempResult;
}
//return Upstream_GetPacket(Upstream_MSC_GetCapacityReplyCallback);
return Upstream_GetFreePacket(Upstream_MSC_GetCapacityReplyCallback);
UpstreamPacketTypeDef* freePacket;
HAL_StatusTypeDef tempResult;
GetCapacityCallback = callback;
freePacket = Upstream_GetFreePacketImmediately();
freePacket->Length = UPSTREAM_PACKET_HEADER_LEN;
freePacket->CommandClass = COMMAND_CLASS_MASS_STORAGE;
freePacket->Command = COMMAND_MSC_GET_CAPACITY;
tempResult = Upstream_TransmitPacket(freePacket);
if (tempResult != HAL_OK)
{
return tempResult;
}
//return Upstream_GetPacket(Upstream_MSC_GetCapacityReplyCallback);
return Upstream_GetFreePacket(Upstream_MSC_GetCapacityReplyCallback);
}
void Upstream_MSC_GetCapacityReplyCallback(UpstreamPacketTypeDef* replyPacket)
{
uint32_t uint[2];
uint32_t uint[2];
// if ((replyPacket->Length != (UPSTREAM_PACKET_HEADER_LEN + 8) ||
// (replyPacket->CommandClass & COMMAND_CLASS_DATA_FLAG)))
// {
// GetCapacityCallback(HAL_ERROR, NULL, NULL);
// }
// if ((replyPacket->Length != (UPSTREAM_PACKET_HEADER_LEN + 8) ||
// (replyPacket->CommandClass & COMMAND_CLASS_DATA_FLAG)))
// {
// GetCapacityCallback(HAL_ERROR, NULL, NULL);
// }
*(uint32_t*)&(replyPacket->Data[0]) = 262144; //* 512B = 128MB
*(uint32_t*)&(replyPacket->Data[4]) = 512;
*(uint32_t*)&(replyPacket->Data[0]) = 262144; //* 512B = 128MB
*(uint32_t*)&(replyPacket->Data[4]) = 512;
uint[0] = *(uint32_t*)&(replyPacket->Data[0]);
uint[1] = *(uint32_t*)&(replyPacket->Data[4]);
GetCapacityCallback(HAL_OK, uint, replyPacket); //usb_msc_scsi will use this packet, so don't release now
uint[0] = *(uint32_t*)&(replyPacket->Data[0]);
uint[1] = *(uint32_t*)&(replyPacket->Data[4]);
GetCapacityCallback(HAL_OK, uint, replyPacket); //usb_msc_scsi will use this packet, so don't release now
}
HAL_StatusTypeDef Upstream_MSC_BeginRead(UpstreamMSCCallbackTypeDef callback,
uint64_t readBlockStart,
uint32_t readBlockCount,
uint32_t readByteCount)
uint64_t readBlockStart,
uint32_t readBlockCount,
uint32_t readByteCount)
{
UpstreamPacketTypeDef* freePacket;
HAL_StatusTypeDef tempResult;
ReadStreamPacket = NULL; //Prepare for GetStreamDataPacket's use
ReadStreamBusy = 0;
TestReadyCallback = callback;
ByteCount = readByteCount;
freePacket = Upstream_GetFreePacketImmediately();
freePacket->Length = UPSTREAM_PACKET_HEADER_LEN + (4 * 3);
freePacket->CommandClass = COMMAND_CLASS_MASS_STORAGE;
freePacket->Command = COMMAND_MSC_BEGIN_READ;
*(uint64_t*)&(freePacket->Data[0]) = readBlockStart;
*(uint32_t*)&(freePacket->Data[8]) = readBlockCount;
tempResult = Upstream_TransmitPacket(freePacket);
if (tempResult != HAL_OK)
{
TestReadyCallback(tempResult);
}
//return Upstream_GetPacket(Upstream_MSC_TestReadyReplyCallback); //Re-use TestReadyReplyCallback because it does exactly what we want!
return Upstream_GetFreePacket(Upstream_MSC_TestReadyReplyCallback);
UpstreamPacketTypeDef* freePacket;
HAL_StatusTypeDef tempResult;
ReadStreamPacket = NULL; //Prepare for GetStreamDataPacket's use
ReadStreamBusy = 0;
TestReadyCallback = callback;
ByteCount = readByteCount;
freePacket = Upstream_GetFreePacketImmediately();
freePacket->Length = UPSTREAM_PACKET_HEADER_LEN + (4 * 3);
freePacket->CommandClass = COMMAND_CLASS_MASS_STORAGE;
freePacket->Command = COMMAND_MSC_BEGIN_READ;
*(uint64_t*)&(freePacket->Data[0]) = readBlockStart;
*(uint32_t*)&(freePacket->Data[8]) = readBlockCount;
tempResult = Upstream_TransmitPacket(freePacket);
if (tempResult != HAL_OK)
{
TestReadyCallback(tempResult);
}
//return Upstream_GetPacket(Upstream_MSC_TestReadyReplyCallback); //Re-use TestReadyReplyCallback because it does exactly what we want!
return Upstream_GetFreePacket(Upstream_MSC_TestReadyReplyCallback);
}
HAL_StatusTypeDef Upstream_MSC_GetStreamDataPacket(UpstreamMSCCallbackPacketTypeDef 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?
{
Upstream_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 Upstream_GetPacket(Upstream_MSC_GetStreamDataPacketCallback);
return Upstream_GetFreePacket(Upstream_MSC_GetStreamDataPacketCallback);
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?
{
Upstream_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 Upstream_GetPacket(Upstream_MSC_GetStreamDataPacketCallback);
return Upstream_GetFreePacket(Upstream_MSC_GetStreamDataPacketCallback);
}
void Upstream_MSC_GetStreamDataPacketCallback(UpstreamPacketTypeDef* 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 '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 > ByteCount))
// {
// GetStreamDataCallback(HAL_ERROR, NULL);
// return;
// }
replyPacket->Length = MIN((ByteCount + UPSTREAM_PACKET_HEADER_LEN), (MSC_MEDIA_PACKET + UPSTREAM_PACKET_HEADER_LEN));
dataLength = replyPacket->Length - UPSTREAM_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)
{
Upstream_MSC_GetStreamDataPacket(NULL); //Try to get the next packet now, before USB asks for it
}
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 '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 > ByteCount))
// {
// GetStreamDataCallback(HAL_ERROR, NULL);
// return;
// }
replyPacket->Length = MIN((ByteCount + UPSTREAM_PACKET_HEADER_LEN), (MSC_MEDIA_PACKET + UPSTREAM_PACKET_HEADER_LEN));
dataLength = replyPacket->Length - UPSTREAM_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)
{
Upstream_MSC_GetStreamDataPacket(NULL); //Try to get the next packet now, before USB asks for it
}
}
HAL_StatusTypeDef Upstream_MSC_BeginWrite(UpstreamMSCCallbackTypeDef callback,
uint64_t readBlockStart,
uint32_t readBlockCount)
uint64_t readBlockStart,
uint32_t readBlockCount)
{
UpstreamPacketTypeDef* freePacket;
HAL_StatusTypeDef tempResult;
TestReadyCallback = callback;
freePacket = Upstream_GetFreePacketImmediately();
freePacket->Length = UPSTREAM_PACKET_HEADER_LEN + (4 * 3);
freePacket->CommandClass = COMMAND_CLASS_MASS_STORAGE;
freePacket->Command = COMMAND_MSC_BEGIN_WRITE;
*(uint64_t*)&(freePacket->Data[0]) = readBlockStart;
*(uint32_t*)&(freePacket->Data[8]) = readBlockCount;
tempResult = Upstream_TransmitPacket(freePacket);
if (tempResult != HAL_OK)
{
TestReadyCallback(tempResult);
}
//return Upstream_GetPacket(Upstream_MSC_BeginWriteReplyCallback);
return Upstream_GetFreePacket(Upstream_MSC_BeginWriteReplyCallback);
UpstreamPacketTypeDef* freePacket;
HAL_StatusTypeDef tempResult;
TestReadyCallback = callback;
freePacket = Upstream_GetFreePacketImmediately();
freePacket->Length = UPSTREAM_PACKET_HEADER_LEN + (4 * 3);
freePacket->CommandClass = COMMAND_CLASS_MASS_STORAGE;
freePacket->Command = COMMAND_MSC_BEGIN_WRITE;
*(uint64_t*)&(freePacket->Data[0]) = readBlockStart;
*(uint32_t*)&(freePacket->Data[8]) = readBlockCount;
tempResult = Upstream_TransmitPacket(freePacket);
if (tempResult != HAL_OK)
{
TestReadyCallback(tempResult);
}
//return Upstream_GetPacket(Upstream_MSC_BeginWriteReplyCallback);
return Upstream_GetFreePacket(Upstream_MSC_BeginWriteReplyCallback);
}
void Upstream_MSC_BeginWriteReplyCallback(UpstreamPacketTypeDef* replyPacket)
{
// if ((replyPacket->Length != (UPSTREAM_PACKET_HEADER_LEN + 1)) ||
// (replyPacket->CommandClass & COMMAND_CLASS_DATA_FLAG) ||
// ((replyPacket->Data[0] != HAL_OK) && (replyPacket->Data[0] != HAL_BUSY)))
// {
// Upstream_ReleasePacket(replyPacket);
// TestReadyCallback(HAL_ERROR);
// return;
// }
Upstream_ReleasePacket(replyPacket);
TestReadyCallback(replyPacket->Data[0]);
// if ((replyPacket->Length != (UPSTREAM_PACKET_HEADER_LEN + 1)) ||
// (replyPacket->CommandClass & COMMAND_CLASS_DATA_FLAG) ||
// ((replyPacket->Data[0] != HAL_OK) && (replyPacket->Data[0] != HAL_BUSY)))
// {
// Upstream_ReleasePacket(replyPacket);
// TestReadyCallback(HAL_ERROR);
// return;
// }
Upstream_ReleasePacket(replyPacket);
TestReadyCallback(replyPacket->Data[0]);
}
HAL_StatusTypeDef Upstream_MSC_PutStreamDataPacket(UpstreamPacketTypeDef* packetToSend,
uint32_t dataLength)
uint32_t dataLength)
{
packetToSend->Length = dataLength + UPSTREAM_PACKET_HEADER_LEN;
packetToSend->CommandClass = COMMAND_CLASS_MASS_STORAGE | COMMAND_CLASS_DATA_FLAG;
packetToSend->Command = COMMAND_MSC_BEGIN_WRITE;
return Upstream_TransmitPacket(packetToSend);
packetToSend->Length = dataLength + UPSTREAM_PACKET_HEADER_LEN;
packetToSend->CommandClass = COMMAND_CLASS_MASS_STORAGE | COMMAND_CLASS_DATA_FLAG;
packetToSend->Command = COMMAND_MSC_BEGIN_WRITE;
return Upstream_TransmitPacket(packetToSend);
}

@ -19,20 +19,20 @@
SPI_HandleTypeDef Hspi1;
UpstreamPacketTypeDef UpstreamPacket0;
UpstreamPacketTypeDef UpstreamPacket1;
UpstreamPacketTypeDef* CurrentWorkingPacket;
UpstreamPacketTypeDef* NextTxPacket = NULL; //Indicates we have a pending TX packet
SPI_HandleTypeDef Hspi1;
UpstreamPacketTypeDef UpstreamPacket0;
UpstreamPacketTypeDef UpstreamPacket1;
UpstreamPacketTypeDef* CurrentWorkingPacket;
UpstreamPacketTypeDef* NextTxPacket = NULL; //Indicates we have a pending TX packet
InterfaceStateTypeDef UpstreamInterfaceState = UPSTREAM_INTERFACE_IDLE;
FreePacketCallbackTypeDef PendingFreePacketCallback = NULL; //Indicates someone is waiting for a packet buffer to become available
SpiPacketReceivedCallbackTypeDef ReceivePacketCallback = NULL; //Indicates someone is waiting for a received packet
InterfaceStateTypeDef UpstreamInterfaceState = UPSTREAM_INTERFACE_IDLE;
FreePacketCallbackTypeDef PendingFreePacketCallback = NULL; //Indicates someone is waiting for a packet buffer to become available
SpiPacketReceivedCallbackTypeDef ReceivePacketCallback = NULL; //Indicates someone is waiting for a received packet
uint32_t TemporaryIncomingPacketLength; //We don't actually care about what Downstream sends us when we are transmitting. We just need somewhere to put it so that our own packet length is not overwritten.
uint8_t TxOkInterruptReceived = 0;
uint8_t SentCommandClass;
uint8_t SentCommand;
uint32_t TemporaryIncomingPacketLength; //We don't actually care about what Downstream sends us when we are transmitting. We just need somewhere to put it so that our own packet length is not overwritten.
uint8_t TxOkInterruptReceived = 0;
uint8_t SentCommandClass;
uint8_t SentCommand;
void Upstream_BeginTransmitPacketSize(void);
@ -45,28 +45,28 @@ void Upstream_BeginReceivePacketBody(void);
void Upstream_InitSPI(void)
{
UpstreamPacket0.Busy = NOT_BUSY;
UpstreamPacket1.Busy = NOT_BUSY;
Hspi1.Instance = SPI1;
Hspi1.State = HAL_SPI_STATE_RESET;
Hspi1.Init.Mode = SPI_MODE_MASTER;
Hspi1.Init.Direction = SPI_DIRECTION_2LINES;
Hspi1.Init.DataSize = SPI_DATASIZE_16BIT;
Hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
Hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
Hspi1.Init.NSS = SPI_NSS_SOFT;
Hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4; //42MHz APB2 / 4 = 10.5Mbaud
Hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
Hspi1.Init.TIMode = SPI_TIMODE_DISABLED;
Hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_ENABLED;
Hspi1.Init.CRCPolynomial = SPI_CRC_DEFAULTPOLYNOMIAL;
HAL_SPI_Init(&Hspi1);
if (DOWNSTREAM_TX_OK_ACTIVE)
{
TxOkInterruptReceived = 1;
}
UpstreamPacket0.Busy = NOT_BUSY;
UpstreamPacket1.Busy = NOT_BUSY;
Hspi1.Instance = SPI1;
Hspi1.State = HAL_SPI_STATE_RESET;
Hspi1.Init.Mode = SPI_MODE_MASTER;
Hspi1.Init.Direction = SPI_DIRECTION_2LINES;
Hspi1.Init.DataSize = SPI_DATASIZE_16BIT;
Hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
Hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
Hspi1.Init.NSS = SPI_NSS_SOFT;
Hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4; //42MHz APB2 / 4 = 10.5Mbaud
Hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
Hspi1.Init.TIMode = SPI_TIMODE_DISABLED;
Hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_ENABLED;
Hspi1.Init.CRCPolynomial = SPI_CRC_DEFAULTPOLYNOMIAL;
HAL_SPI_Init(&Hspi1);
if (DOWNSTREAM_TX_OK_ACTIVE)
{
TxOkInterruptReceived = 1;
}
}
@ -74,90 +74,90 @@ void Upstream_InitSPI(void)
//Used by USB interface classes, and by our internal RX code.
HAL_StatusTypeDef Upstream_GetFreePacket(FreePacketCallbackTypeDef callback)
{
if (UpstreamInterfaceState >= UPSTREAM_INTERFACE_ERROR)
{
return HAL_ERROR;
}
//Do we already have a queued callback?
if (PendingFreePacketCallback != NULL)
{
UPSTREAM_SPI_FREAKOUT;
return HAL_ERROR;
}
//Check if there is a free buffer now
if (UpstreamPacket0.Busy == NOT_BUSY)
{
UpstreamPacket0.Busy = BUSY;
callback(&UpstreamPacket0);
return HAL_OK;
}
if (UpstreamPacket1.Busy == NOT_BUSY)
{
UpstreamPacket1.Busy = BUSY;
callback(&UpstreamPacket1);
return HAL_OK;
}
//Otherwise save requested address for when a buffer becomes free in the future
PendingFreePacketCallback = callback;
return HAL_OK;
if (UpstreamInterfaceState >= UPSTREAM_INTERFACE_ERROR)
{
return HAL_ERROR;
}
//Do we already have a queued callback?
if (PendingFreePacketCallback != NULL)
{
UPSTREAM_SPI_FREAKOUT;
return HAL_ERROR;
}
//Check if there is a free buffer now
if (UpstreamPacket0.Busy == NOT_BUSY)
{
UpstreamPacket0.Busy = BUSY;
callback(&UpstreamPacket0);
return HAL_OK;
}
if (UpstreamPacket1.Busy == NOT_BUSY)
{
UpstreamPacket1.Busy = BUSY;
callback(&UpstreamPacket1);
return HAL_OK;
}
//Otherwise save requested address for when a buffer becomes free in the future
PendingFreePacketCallback = callback;
return HAL_OK;
}
UpstreamPacketTypeDef* Upstream_GetFreePacketImmediately(void)
{
if (UpstreamInterfaceState >= UPSTREAM_INTERFACE_ERROR)
{
return NULL;
}
//We are expecting a free buffer now
if (UpstreamPacket0.Busy == NOT_BUSY)
{
UpstreamPacket0.Busy = BUSY;
return &UpstreamPacket0;
}
if (UpstreamPacket1.Busy == NOT_BUSY)
{
UpstreamPacket1.Busy = BUSY;
return &UpstreamPacket1;
}
//Should not happen:
UPSTREAM_SPI_FREAKOUT;
return NULL;
if (UpstreamInterfaceState >= UPSTREAM_INTERFACE_ERROR)
{
return NULL;
}
//We are expecting a free buffer now
if (UpstreamPacket0.Busy == NOT_BUSY)
{
UpstreamPacket0.Busy = BUSY;
return &UpstreamPacket0;
}
if (UpstreamPacket1.Busy == NOT_BUSY)
{
UpstreamPacket1.Busy = BUSY;
return &UpstreamPacket1;
}
//Should not happen:
UPSTREAM_SPI_FREAKOUT;
return NULL;
}
//Used by USB interface classes, and by our internal RX code.
void Upstream_ReleasePacket(UpstreamPacketTypeDef* packetToRelease)
{
FreePacketCallbackTypeDef tempCallback;
if (UpstreamInterfaceState >= UPSTREAM_INTERFACE_ERROR)
{
return;
}
if ((packetToRelease != &UpstreamPacket0) &&
(packetToRelease != &UpstreamPacket1))
{
UPSTREAM_SPI_FREAKOUT;
return;
}
if (PendingFreePacketCallback != NULL)
{
tempCallback = PendingFreePacketCallback; //In extreme situations, running this callback can trigger another request for a free packet,
PendingFreePacketCallback = NULL; //thereby causing GetFreePacket to freak out. So we need to clear the callback indicator first.
tempCallback(packetToRelease);
}
else
{
packetToRelease->Busy = NOT_BUSY;
}
FreePacketCallbackTypeDef tempCallback;
if (UpstreamInterfaceState >= UPSTREAM_INTERFACE_ERROR)
{
return;
}
if ((packetToRelease != &UpstreamPacket0) &&
(packetToRelease != &UpstreamPacket1))
{
UPSTREAM_SPI_FREAKOUT;
return;
}
if (PendingFreePacketCallback != NULL)
{
tempCallback = PendingFreePacketCallback; //In extreme situations, running this callback can trigger another request for a free packet,
PendingFreePacketCallback = NULL; //thereby causing GetFreePacket to freak out. So we need to clear the callback indicator first.
tempCallback(packetToRelease);
}
else
{
packetToRelease->Busy = NOT_BUSY;
}
}
@ -167,60 +167,60 @@ void Upstream_ReleasePacket(UpstreamPacketTypeDef* packetToRelease)
//as we can't let the size/packet sequence get out of sync.
HAL_StatusTypeDef Upstream_TransmitPacket(UpstreamPacketTypeDef* packetToWrite)
{
if (UpstreamInterfaceState >= UPSTREAM_INTERFACE_ERROR)
{
return HAL_ERROR;
}
//Sanity checks
if ((packetToWrite != &UpstreamPacket0) &&
(packetToWrite != &UpstreamPacket1))
{
UPSTREAM_SPI_FREAKOUT;
return HAL_ERROR;
}
if ((packetToWrite->Busy != BUSY) ||
(packetToWrite->Length16 < UPSTREAM_PACKET_LEN_MIN_16) ||
(packetToWrite->Length16 > UPSTREAM_PACKET_LEN_16))
{
UPSTREAM_SPI_FREAKOUT;
return HAL_ERROR;
}
if (NextTxPacket != NULL)
{
UPSTREAM_SPI_FREAKOUT;
return HAL_ERROR;
}
switch (UpstreamInterfaceState)
{
case UPSTREAM_INTERFACE_TX_SIZE_WAIT:
case UPSTREAM_INTERFACE_TX_SIZE:
case UPSTREAM_INTERFACE_TX_PACKET_WAIT:
case UPSTREAM_INTERFACE_TX_PACKET:
NextTxPacket = packetToWrite;
break;
case UPSTREAM_INTERFACE_IDLE:
UpstreamInterfaceState = UPSTREAM_INTERFACE_TX_SIZE_WAIT;
CurrentWorkingPacket = packetToWrite;
SentCommandClass = CurrentWorkingPacket->CommandClass;
SentCommand = CurrentWorkingPacket->Command;
//Downstream may have set TxOk pin before we wanted to transmit.
//In this case we can go ahead and transmit now.
if (TxOkInterruptReceived)
{
TxOkInterruptReceived = 0;
Upstream_BeginTransmitPacketSize();
}
break;
default:
UPSTREAM_SPI_FREAKOUT;
return HAL_ERROR;
}
return HAL_OK;
if (UpstreamInterfaceState >= UPSTREAM_INTERFACE_ERROR)
{
return HAL_ERROR;
}
//Sanity checks
if ((packetToWrite != &UpstreamPacket0) &&
(packetToWrite != &UpstreamPacket1))
{
UPSTREAM_SPI_FREAKOUT;
return HAL_ERROR;
}
if ((packetToWrite->Busy != BUSY) ||
(packetToWrite->Length16 < UPSTREAM_PACKET_LEN_MIN_16) ||
(packetToWrite->Length16 > UPSTREAM_PACKET_LEN_16))
{
UPSTREAM_SPI_FREAKOUT;
return HAL_ERROR;
}
if (NextTxPacket != NULL)
{
UPSTREAM_SPI_FREAKOUT;
return HAL_ERROR;
}
switch (UpstreamInterfaceState)
{
case UPSTREAM_INTERFACE_TX_SIZE_WAIT:
case UPSTREAM_INTERFACE_TX_SIZE:
case UPSTREAM_INTERFACE_TX_PACKET_WAIT:
case UPSTREAM_INTERFACE_TX_PACKET:
NextTxPacket = packetToWrite;
break;
case UPSTREAM_INTERFACE_IDLE:
UpstreamInterfaceState = UPSTREAM_INTERFACE_TX_SIZE_WAIT;
CurrentWorkingPacket = packetToWrite;
SentCommandClass = CurrentWorkingPacket->CommandClass;
SentCommand = CurrentWorkingPacket->Command;
//Downstream may have set TxOk pin before we wanted to transmit.
//In this case we can go ahead and transmit now.
if (TxOkInterruptReceived)
{
TxOkInterruptReceived = 0;
Upstream_BeginTransmitPacketSize();
}
break;
default:
UPSTREAM_SPI_FREAKOUT;
return HAL_ERROR;
}
return HAL_OK;
}
@ -230,126 +230,126 @@ HAL_StatusTypeDef Upstream_TransmitPacket(UpstreamPacketTypeDef* packetToWrite)
//We TxRx our outgoing packet because the SPI hardware freaks out if we only Tx it :-/
void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)
{
SpiPacketReceivedCallbackTypeDef tempPacketCallback;
UpstreamPacketTypeDef* tempPacketToFree;
SPI1_NSS_DEASSERT;
if (UpstreamInterfaceState >= UPSTREAM_INTERFACE_ERROR)
{
return;
}
//Finished transmitting packet size
if (UpstreamInterfaceState == UPSTREAM_INTERFACE_TX_SIZE)
{
UpstreamInterfaceState = UPSTREAM_INTERFACE_TX_PACKET_WAIT;
if (TxOkInterruptReceived)
{
TxOkInterruptReceived = 0;
Upstream_BeginTransmitPacketBody();
}
return;
}
//Finished transmitting packet body
if (UpstreamInterfaceState == UPSTREAM_INTERFACE_TX_PACKET)
{
if ((PendingFreePacketCallback != NULL) && (NextTxPacket == NULL))
{
UPSTREAM_SPI_FREAKOUT;
return;
}
tempPacketToFree = CurrentWorkingPacket;
if (NextTxPacket != NULL)
{
//NextTxPacket has already passed the checks in Upstream_TransmitPacket.
//So we just need to pass it to HAL_SPI_Transmit_DMA.
UpstreamInterfaceState = UPSTREAM_INTERFACE_TX_SIZE_WAIT;
CurrentWorkingPacket = NextTxPacket;
NextTxPacket = NULL;
SentCommandClass = CurrentWorkingPacket->CommandClass;
SentCommand = CurrentWorkingPacket->Command;
if (TxOkInterruptReceived)
{
TxOkInterruptReceived = 0;
Upstream_BeginTransmitPacketSize();
}
}
else
{
//No packet queued for transmission:
UpstreamInterfaceState = UPSTREAM_INTERFACE_IDLE;
if (ReceivePacketCallback != NULL)
{
Upstream_CheckBeginPacketReception();
}
}
//Release old packet after moving Next to Current
Upstream_ReleasePacket(tempPacketToFree);
return;
}
if (UpstreamInterfaceState == UPSTREAM_INTERFACE_RX_SIZE)
{
if ((CurrentWorkingPacket->Length16 < UPSTREAM_PACKET_LEN_MIN_16) ||
(CurrentWorkingPacket->Length16 > UPSTREAM_PACKET_LEN_16))
{
UPSTREAM_SPI_FREAKOUT;
return;
}
UpstreamInterfaceState = UPSTREAM_INTERFACE_RX_PACKET_WAIT;
if (TxOkInterruptReceived)
{
TxOkInterruptReceived = 0;
Upstream_BeginReceivePacketBody();
}
return;
}
if (UpstreamInterfaceState == UPSTREAM_INTERFACE_RX_PACKET)
{
UpstreamInterfaceState = UPSTREAM_INTERFACE_IDLE;
if (ReceivePacketCallback == NULL)
{
UPSTREAM_SPI_FREAKOUT;
return;
}
if ((CurrentWorkingPacket->CommandClass == COMMAND_CLASS_ERROR) &&
(CurrentWorkingPacket->Command == COMMAND_ERROR_DEVICE_DISCONNECTED))
{
Upstream_ReleasePacket(CurrentWorkingPacket);
ReceivePacketCallback = NULL;
Upstream_StateMachine_DeviceDisconnected();
return;
}
if (((CurrentWorkingPacket->CommandClass & COMMAND_CLASS_MASK) != (SentCommandClass & COMMAND_CLASS_MASK)) ||
(CurrentWorkingPacket->Command != SentCommand))
{
UPSTREAM_SPI_FREAKOUT;
Upstream_ReleasePacket(CurrentWorkingPacket);
CurrentWorkingPacket = NULL; //Call back with a NULL packet to indicate error
}
//USB interface may want to receive another packet immediately,
//so clear ReceivePacketCallback before the call.
//It is the callback's responsibility to release the packet buffer we are passing to it!
tempPacketCallback = ReceivePacketCallback;
ReceivePacketCallback = NULL;
tempPacketCallback(CurrentWorkingPacket);
return;
}
//case default:
UPSTREAM_SPI_FREAKOUT;
SpiPacketReceivedCallbackTypeDef tempPacketCallback;
UpstreamPacketTypeDef* tempPacketToFree;
SPI1_NSS_DEASSERT;
if (UpstreamInterfaceState >= UPSTREAM_INTERFACE_ERROR)
{
return;
}
//Finished transmitting packet size
if (UpstreamInterfaceState == UPSTREAM_INTERFACE_TX_SIZE)
{
UpstreamInterfaceState = UPSTREAM_INTERFACE_TX_PACKET_WAIT;
if (TxOkInterruptReceived)
{
TxOkInterruptReceived = 0;
Upstream_BeginTransmitPacketBody();
}
return;
}
//Finished transmitting packet body
if (UpstreamInterfaceState == UPSTREAM_INTERFACE_TX_PACKET)
{
if ((PendingFreePacketCallback != NULL) && (NextTxPacket == NULL))
{
UPSTREAM_SPI_FREAKOUT;
return;
}
tempPacketToFree = CurrentWorkingPacket;
if (NextTxPacket != NULL)
{
//NextTxPacket has already passed the checks in Upstream_TransmitPacket.
//So we just need to pass it to HAL_SPI_Transmit_DMA.
UpstreamInterfaceState = UPSTREAM_INTERFACE_TX_SIZE_WAIT;
CurrentWorkingPacket = NextTxPacket;
NextTxPacket = NULL;
SentCommandClass = CurrentWorkingPacket->CommandClass;
SentCommand = CurrentWorkingPacket->Command;
if (TxOkInterruptReceived)
{
TxOkInterruptReceived = 0;
Upstream_BeginTransmitPacketSize();
}
}
else
{
//No packet queued for transmission:
UpstreamInterfaceState = UPSTREAM_INTERFACE_IDLE;
if (ReceivePacketCallback != NULL)
{
Upstream_CheckBeginPacketReception();
}
}
//Release old packet after moving Next to Current
Upstream_ReleasePacket(tempPacketToFree);
return;
}
if (UpstreamInterfaceState == UPSTREAM_INTERFACE_RX_SIZE)
{
if ((CurrentWorkingPacket->Length16 < UPSTREAM_PACKET_LEN_MIN_16) ||
(CurrentWorkingPacket->Length16 > UPSTREAM_PACKET_LEN_16))
{
UPSTREAM_SPI_FREAKOUT;
return;
}
UpstreamInterfaceState = UPSTREAM_INTERFACE_RX_PACKET_WAIT;
if (TxOkInterruptReceived)
{
TxOkInterruptReceived = 0;
Upstream_BeginReceivePacketBody();
}
return;
}
if (UpstreamInterfaceState == UPSTREAM_INTERFACE_RX_PACKET)
{
UpstreamInterfaceState = UPSTREAM_INTERFACE_IDLE;
if (ReceivePacketCallback == NULL)
{
UPSTREAM_SPI_FREAKOUT;
return;
}
if ((CurrentWorkingPacket->CommandClass == COMMAND_CLASS_ERROR) &&
(CurrentWorkingPacket->Command == COMMAND_ERROR_DEVICE_DISCONNECTED))
{
Upstream_ReleasePacket(CurrentWorkingPacket);
ReceivePacketCallback = NULL;
Upstream_StateMachine_DeviceDisconnected();
return;
}
if (((CurrentWorkingPacket->CommandClass & COMMAND_CLASS_MASK) != (SentCommandClass & COMMAND_CLASS_MASK)) ||
(CurrentWorkingPacket->Command != SentCommand))
{
UPSTREAM_SPI_FREAKOUT;
Upstream_ReleasePacket(CurrentWorkingPacket);
CurrentWorkingPacket = NULL; //Call back with a NULL packet to indicate error
}
//USB interface may want to receive another packet immediately,
//so clear ReceivePacketCallback before the call.
//It is the callback's responsibility to release the packet buffer we are passing to it!
tempPacketCallback = ReceivePacketCallback;
ReceivePacketCallback = NULL;
tempPacketCallback(CurrentWorkingPacket);
return;
}
//case default:
UPSTREAM_SPI_FREAKOUT;
}
@ -358,46 +358,46 @@ void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)
//Not OK to call when receiving or waiting for downstream reply.
HAL_StatusTypeDef Upstream_ReceivePacket(SpiPacketReceivedCallbackTypeDef callback)
{
if (UpstreamInterfaceState >= UPSTREAM_INTERFACE_ERROR)
{
return HAL_ERROR;
}
if (ReceivePacketCallback != NULL)
{
UPSTREAM_SPI_FREAKOUT;
return HAL_ERROR;
}
ReceivePacketCallback = callback;
return Upstream_CheckBeginPacketReception();
if (UpstreamInterfaceState >= UPSTREAM_INTERFACE_ERROR)
{
return HAL_ERROR;
}
if (ReceivePacketCallback != NULL)
{
UPSTREAM_SPI_FREAKOUT;
return HAL_ERROR;
}
ReceivePacketCallback = callback;
return Upstream_CheckBeginPacketReception();
}
//Internal use only.
HAL_StatusTypeDef Upstream_CheckBeginPacketReception(void)
{
if (UpstreamInterfaceState >= UPSTREAM_INTERFACE_ERROR)
{
return HAL_ERROR;
}
if (UpstreamInterfaceState >= UPSTREAM_INTERFACE_RX_SIZE_WAIT)
{
UPSTREAM_SPI_FREAKOUT;
return HAL_ERROR;
}
if (UpstreamInterfaceState == UPSTREAM_INTERFACE_IDLE)
{
UpstreamInterfaceState = UPSTREAM_INTERFACE_RX_SIZE_WAIT;
if (TxOkInterruptReceived)
{
TxOkInterruptReceived = 0;
Upstream_GetFreePacket(Upstream_BeginReceivePacketSize);
}
}
return HAL_OK;
if (UpstreamInterfaceState >= UPSTREAM_INTERFACE_ERROR)
{
return HAL_ERROR;
}
if (UpstreamInterfaceState >= UPSTREAM_INTERFACE_RX_SIZE_WAIT)
{
UPSTREAM_SPI_FREAKOUT;
return HAL_ERROR;
}
if (UpstreamInterfaceState == UPSTREAM_INTERFACE_IDLE)
{
UpstreamInterfaceState = UPSTREAM_INTERFACE_RX_SIZE_WAIT;
if (TxOkInterruptReceived)
{
TxOkInterruptReceived = 0;
Upstream_GetFreePacket(Upstream_BeginReceivePacketSize);
}
}
return HAL_OK;
}
@ -405,65 +405,65 @@ HAL_StatusTypeDef Upstream_CheckBeginPacketReception(void)
//indicating that downstream is ready for the next transaction.
void Upstream_TxOkInterrupt(void)
{
if (UpstreamInterfaceState >= UPSTREAM_INTERFACE_ERROR)
{
return;
}
switch (UpstreamInterfaceState)
{
case UPSTREAM_INTERFACE_IDLE:
TxOkInterruptReceived = 1;
break;
case UPSTREAM_INTERFACE_TX_SIZE_WAIT:
Upstream_BeginTransmitPacketSize();
break;
case UPSTREAM_INTERFACE_TX_PACKET_WAIT:
Upstream_BeginTransmitPacketBody();
break;
case UPSTREAM_INTERFACE_RX_SIZE_WAIT:
Upstream_GetFreePacket(Upstream_BeginReceivePacketSize);
break;
case UPSTREAM_INTERFACE_RX_PACKET_WAIT:
Upstream_BeginReceivePacketBody();
break;
default:
UPSTREAM_SPI_FREAKOUT;
}
if (UpstreamInterfaceState >= UPSTREAM_INTERFACE_ERROR)
{
return;
}
switch (UpstreamInterfaceState)
{
case UPSTREAM_INTERFACE_IDLE:
TxOkInterruptReceived = 1;
break;
case UPSTREAM_INTERFACE_TX_SIZE_WAIT:
Upstream_BeginTransmitPacketSize();
break;
case UPSTREAM_INTERFACE_TX_PACKET_WAIT:
Upstream_BeginTransmitPacketBody();
break;
case UPSTREAM_INTERFACE_RX_SIZE_WAIT:
Upstream_GetFreePacket(Upstream_BeginReceivePacketSize);
break;
case UPSTREAM_INTERFACE_RX_PACKET_WAIT:
Upstream_BeginReceivePacketBody();
break;
default:
UPSTREAM_SPI_FREAKOUT;
}
}
void Upstream_BeginTransmitPacketSize(void)
{
UpstreamInterfaceState = UPSTREAM_INTERFACE_TX_SIZE;
SPI1_NSS_ASSERT;
if (HAL_SPI_TransmitReceive_DMA(&Hspi1,
(uint8_t*)&CurrentWorkingPacket->Length16,
(uint8_t*)&TemporaryIncomingPacketLength,
2) != HAL_OK) //We only need to write one word, but the peripheral library freaks out...
{
UPSTREAM_SPI_FREAKOUT;
}
UpstreamInterfaceState = UPSTREAM_INTERFACE_TX_SIZE;
SPI1_NSS_ASSERT;
if (HAL_SPI_TransmitReceive_DMA(&Hspi1,
(uint8_t*)&CurrentWorkingPacket->Length16,
(uint8_t*)&TemporaryIncomingPacketLength,
2) != HAL_OK) //We only need to write one word, but the peripheral library freaks out...
{
UPSTREAM_SPI_FREAKOUT;
}
}
void Upstream_BeginTransmitPacketBody(void)
{
UpstreamInterfaceState = UPSTREAM_INTERFACE_TX_PACKET;
SPI1_NSS_ASSERT;
if (HAL_SPI_TransmitReceive_DMA(&Hspi1,
&CurrentWorkingPacket->CommandClass,
&CurrentWorkingPacket->CommandClass,
((CurrentWorkingPacket->Length16 < 2) ? 2 : CurrentWorkingPacket->Length16)) != HAL_OK)
{
UPSTREAM_SPI_FREAKOUT;
}
UpstreamInterfaceState = UPSTREAM_INTERFACE_TX_PACKET;
SPI1_NSS_ASSERT;
if (HAL_SPI_TransmitReceive_DMA(&Hspi1,
&CurrentWorkingPacket->CommandClass,
&CurrentWorkingPacket->CommandClass,
((CurrentWorkingPacket->Length16 < 2) ? 2 : CurrentWorkingPacket->Length16)) != HAL_OK)
{
UPSTREAM_SPI_FREAKOUT;
}
}
@ -471,41 +471,41 @@ void Upstream_BeginTransmitPacketBody(void)
//Called when we want to receive downstream packet, and a packet buffer has become free.
void Upstream_BeginReceivePacketSize(UpstreamPacketTypeDef* freePacket)
{
if (UpstreamInterfaceState >= UPSTREAM_INTERFACE_ERROR)
{
return;
}
if (UpstreamInterfaceState != UPSTREAM_INTERFACE_RX_SIZE_WAIT)
{
UPSTREAM_SPI_FREAKOUT;
return;
}
UpstreamInterfaceState = UPSTREAM_INTERFACE_RX_SIZE;
CurrentWorkingPacket = freePacket;
CurrentWorkingPacket->Length16 = 0; //Our RX buffer is used by HAL_SPI_TransmitReceive_DMA as dummy TX data, we set Length to 0 so downstream will know this is a dummy packet.
SPI1_NSS_ASSERT;
if (HAL_SPI_TransmitReceive_DMA(&Hspi1,
(uint8_t*)&CurrentWorkingPacket->Length16,
(uint8_t*)&CurrentWorkingPacket->Length16,
2) != HAL_OK) //We only need to write one word, but the peripheral library freaks out...
{
UPSTREAM_SPI_FREAKOUT;
}
if (UpstreamInterfaceState >= UPSTREAM_INTERFACE_ERROR)
{
return;
}
if (UpstreamInterfaceState != UPSTREAM_INTERFACE_RX_SIZE_WAIT)
{
UPSTREAM_SPI_FREAKOUT;
return;
}
UpstreamInterfaceState = UPSTREAM_INTERFACE_RX_SIZE;
CurrentWorkingPacket = freePacket;
CurrentWorkingPacket->Length16 = 0; //Our RX buffer is used by HAL_SPI_TransmitReceive_DMA as dummy TX data, we set Length to 0 so downstream will know this is a dummy packet.
SPI1_NSS_ASSERT;
if (HAL_SPI_TransmitReceive_DMA(&Hspi1,
(uint8_t*)&CurrentWorkingPacket->Length16,
(uint8_t*)&CurrentWorkingPacket->Length16,
2) != HAL_OK) //We only need to write one word, but the peripheral library freaks out...
{
UPSTREAM_SPI_FREAKOUT;
}
}
void Upstream_BeginReceivePacketBody(void)
{
UpstreamInterfaceState = UPSTREAM_INTERFACE_RX_PACKET;
SPI1_NSS_ASSERT;
if (HAL_SPI_TransmitReceive_DMA(&Hspi1,
&CurrentWorkingPacket->CommandClass,
&CurrentWorkingPacket->CommandClass,
((CurrentWorkingPacket->Length16 < 2) ? 2 : CurrentWorkingPacket->Length16)) != HAL_OK)
{
UPSTREAM_SPI_FREAKOUT;
}
UpstreamInterfaceState = UPSTREAM_INTERFACE_RX_PACKET;
SPI1_NSS_ASSERT;
if (HAL_SPI_TransmitReceive_DMA(&Hspi1,
&CurrentWorkingPacket->CommandClass,
&CurrentWorkingPacket->CommandClass,
((CurrentWorkingPacket->Length16 < 2) ? 2 : CurrentWorkingPacket->Length16)) != HAL_OK)
{
UPSTREAM_SPI_FREAKOUT;
}
}
@ -513,21 +513,21 @@ void Upstream_BeginReceivePacketBody(void)
//Something bad happened! Possibly CRC error...
void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi)
{
SpiPacketReceivedCallbackTypeDef tempPacketCallback;
SpiPacketReceivedCallbackTypeDef tempPacketCallback;
if (UpstreamInterfaceState >= UPSTREAM_INTERFACE_ERROR)
{
return;
}
if (UpstreamInterfaceState >= UPSTREAM_INTERFACE_ERROR)
{
return;
}
UPSTREAM_SPI_FREAKOUT;
UPSTREAM_SPI_FREAKOUT;
if (ReceivePacketCallback != NULL)
{
tempPacketCallback = ReceivePacketCallback;
ReceivePacketCallback = NULL;
tempPacketCallback(NULL); //Call back with a NULL packet to indicate error
}
if (ReceivePacketCallback != NULL)
{
tempPacketCallback = ReceivePacketCallback;
ReceivePacketCallback = NULL;
tempPacketCallback(NULL); //Call back with a NULL packet to indicate error
}
}

@ -18,8 +18,8 @@
#include "usbd_msc.h"
UpstreamStateTypeDef UpstreamState = STATE_TEST_INTERFACE;
InterfaceCommandClassTypeDef ConfiguredDeviceClass = COMMAND_CLASS_INTERFACE;
UpstreamStateTypeDef UpstreamState = STATE_TEST_INTERFACE;
InterfaceCommandClassTypeDef ConfiguredDeviceClass = COMMAND_CLASS_INTERFACE;
void Upstream_StateMachine_TestInterfaceReplyCallback(UpstreamPacketTypeDef* replyPacket);
@ -30,189 +30,189 @@ void Upstream_StateMachine_NotifyDeviceReplyCallback(UpstreamPacketTypeDef* repl
void Upstream_InitStateMachine(void)
{
UpstreamPacketTypeDef* freePacket;
uint16_t i;
uint8_t testDataValue;
Upstream_InitSPI();
//Prepare SPI test packet
freePacket = Upstream_GetFreePacketImmediately();
if (freePacket == NULL)
{
UpstreamState = STATE_ERROR;
return;
}
freePacket->Length16 = UPSTREAM_PACKET_LEN_16;
freePacket->CommandClass = COMMAND_CLASS_INTERFACE;
freePacket->Command = COMMAND_INTERFACE_ECHO;
//Fill our test packet with some junk
testDataValue = 0xFF;
for (i = 0; i < MSC_MEDIA_PACKET; i++)
{
freePacket->Data[i] = testDataValue;
testDataValue += 39;
}
if (Upstream_TransmitPacket(freePacket) == HAL_OK)
{
Upstream_ReceivePacket(Upstream_StateMachine_TestInterfaceReplyCallback);
}
UpstreamPacketTypeDef* freePacket;
uint16_t i;
uint8_t testDataValue;
Upstream_InitSPI();
//Prepare SPI test packet
freePacket = Upstream_GetFreePacketImmediately();
if (freePacket == NULL)
{
UpstreamState = STATE_ERROR;
return;
}
freePacket->Length16 = UPSTREAM_PACKET_LEN_16;
freePacket->CommandClass = COMMAND_CLASS_INTERFACE;
freePacket->Command = COMMAND_INTERFACE_ECHO;
//Fill our test packet with some junk
testDataValue = 0xFF;
for (i = 0; i < MSC_MEDIA_PACKET; i++)
{
freePacket->Data[i] = testDataValue;
testDataValue += 39;
}
if (Upstream_TransmitPacket(freePacket) == HAL_OK)
{
Upstream_ReceivePacket(Upstream_StateMachine_TestInterfaceReplyCallback);
}
}
//Used by upstream_spi freakout macro, indicates we should stop everything.
void Upstream_StateMachine_SetErrorState(void)
{
UpstreamState = STATE_ERROR;
if ((ConfiguredDeviceClass > COMMAND_CLASS_INTERFACE) &&
(ConfiguredDeviceClass < COMMAND_CLASS_ERROR))
{
USBD_Stop(&hUsbDeviceFS);
}
UpstreamState = STATE_ERROR;
if ((ConfiguredDeviceClass > COMMAND_CLASS_INTERFACE) &&
(ConfiguredDeviceClass < COMMAND_CLASS_ERROR))
{
USBD_Stop(&hUsbDeviceFS);
}
}
HAL_StatusTypeDef Upstream_StateMachine_CheckClassOperationOk(void)
{
if (UpstreamState == STATE_ERROR)
{
return HAL_ERROR;
}
if (UpstreamState != STATE_DEVICE_ACTIVE)
{
UPSTREAM_STATEMACHINE_FREAKOUT;
return HAL_ERROR;
}
return HAL_OK;
if (UpstreamState == STATE_ERROR)
{
return HAL_ERROR;
}
if (UpstreamState != STATE_DEVICE_ACTIVE)
{
UPSTREAM_STATEMACHINE_FREAKOUT;
return HAL_ERROR;
}
return HAL_OK;
}
void Upstream_StateMachine_TestInterfaceReplyCallback(UpstreamPacketTypeDef* replyPacket)
{
uint16_t i;
uint8_t testDataValue;
if (UpstreamState >= STATE_ERROR)
{
return;
}
if ((UpstreamState != STATE_TEST_INTERFACE) ||
(replyPacket == NULL))
{
UPSTREAM_STATEMACHINE_FREAKOUT;
return;
}
if (replyPacket->Length16 != UPSTREAM_PACKET_LEN_16)
{
UPSTREAM_STATEMACHINE_FREAKOUT;
return;
}
testDataValue = 0xFF;
for (i = 0; i < MSC_MEDIA_PACKET; i++)
{
if (replyPacket->Data[i] != testDataValue)
{
UPSTREAM_STATEMACHINE_FREAKOUT;
return;
}
testDataValue += 39;
}
//SPI interface passed checks. Now we wait for a device to be attached to downstream.
Upstream_StateMachine_NotifyDevice(replyPacket);
uint16_t i;
uint8_t testDataValue;
if (UpstreamState >= STATE_ERROR)
{
return;
}
if ((UpstreamState != STATE_TEST_INTERFACE) ||
(replyPacket == NULL))
{
UPSTREAM_STATEMACHINE_FREAKOUT;
return;
}
if (replyPacket->Length16 != UPSTREAM_PACKET_LEN_16)
{
UPSTREAM_STATEMACHINE_FREAKOUT;
return;
}
testDataValue = 0xFF;
for (i = 0; i < MSC_MEDIA_PACKET; i++)
{
if (replyPacket->Data[i] != testDataValue)
{
UPSTREAM_STATEMACHINE_FREAKOUT;
return;
}
testDataValue += 39;
}
//SPI interface passed checks. Now we wait for a device to be attached to downstream.
Upstream_StateMachine_NotifyDevice(replyPacket);
}
void Upstream_StateMachine_NotifyDevice(UpstreamPacketTypeDef* freePacket)
{
UpstreamState = STATE_WAIT_DEVICE;
freePacket->Length16 = UPSTREAM_PACKET_HEADER_LEN_16;
freePacket->CommandClass = COMMAND_CLASS_INTERFACE;
freePacket->Command = COMMAND_INTERFACE_NOTIFY_DEVICE;
if (Upstream_TransmitPacket(freePacket) == HAL_OK)
{
Upstream_ReceivePacket(Upstream_StateMachine_NotifyDeviceReplyCallback);
}
UpstreamState = STATE_WAIT_DEVICE;
freePacket->Length16 = UPSTREAM_PACKET_HEADER_LEN_16;
freePacket->CommandClass = COMMAND_CLASS_INTERFACE;
freePacket->Command = COMMAND_INTERFACE_NOTIFY_DEVICE;
if (Upstream_TransmitPacket(freePacket) == HAL_OK)
{
Upstream_ReceivePacket(Upstream_StateMachine_NotifyDeviceReplyCallback);
}
}
void Upstream_StateMachine_NotifyDeviceReplyCallback(UpstreamPacketTypeDef* replyPacket)
{
InterfaceCommandClassTypeDef newActiveClass = COMMAND_CLASS_INTERFACE;
USBD_ClassTypeDef* newClassPointer;
if (UpstreamState >= STATE_ERROR)
{
return;
}
if ((UpstreamState != STATE_WAIT_DEVICE) ||
(replyPacket == NULL))
{
UPSTREAM_STATEMACHINE_FREAKOUT;
return;
}
if (replyPacket->Length16 != (UPSTREAM_PACKET_HEADER_LEN_16 + 1))
{
UPSTREAM_STATEMACHINE_FREAKOUT;
return;
}
switch (replyPacket->Data[0])
{
case COMMAND_CLASS_MASS_STORAGE:
newActiveClass = COMMAND_CLASS_MASS_STORAGE;
newClassPointer = &USBD_MSC;
break;
//Add other supported classes here...
}
Upstream_ReleasePacket(replyPacket);
if (newActiveClass == COMMAND_CLASS_INTERFACE)
{
UPSTREAM_STATEMACHINE_FREAKOUT;
return;
}
//Downstream should never change the active device class without rebooting!
if ((ConfiguredDeviceClass != COMMAND_CLASS_INTERFACE) &&
(ConfiguredDeviceClass != newActiveClass))
{
UPSTREAM_STATEMACHINE_FREAKOUT;
return;
}
UpstreamState = STATE_DEVICE_ACTIVE;
ConfiguredDeviceClass = newActiveClass;
USBD_RegisterClass(&hUsbDeviceFS, newClassPointer);
USBD_Start(&hUsbDeviceFS);
//The USB device stack will now receive commands from our host.
//All we need to do is monitor for downstream device disconnection.
InterfaceCommandClassTypeDef newActiveClass = COMMAND_CLASS_INTERFACE;
USBD_ClassTypeDef* newClassPointer;
if (UpstreamState >= STATE_ERROR)
{
return;
}
if ((UpstreamState != STATE_WAIT_DEVICE) ||
(replyPacket == NULL))
{
UPSTREAM_STATEMACHINE_FREAKOUT;
return;
}
if (replyPacket->Length16 != (UPSTREAM_PACKET_HEADER_LEN_16 + 1))
{
UPSTREAM_STATEMACHINE_FREAKOUT;
return;
}
switch (replyPacket->Data[0])
{
case COMMAND_CLASS_MASS_STORAGE:
newActiveClass = COMMAND_CLASS_MASS_STORAGE;
newClassPointer = &USBD_MSC;
break;
//Add other supported classes here...
}
Upstream_ReleasePacket(replyPacket);
if (newActiveClass == COMMAND_CLASS_INTERFACE)
{
UPSTREAM_STATEMACHINE_FREAKOUT;
return;
}
//Downstream should never change the active device class without rebooting!
if ((ConfiguredDeviceClass != COMMAND_CLASS_INTERFACE) &&
(ConfiguredDeviceClass != newActiveClass))
{
UPSTREAM_STATEMACHINE_FREAKOUT;
return;
}
UpstreamState = STATE_DEVICE_ACTIVE;
ConfiguredDeviceClass = newActiveClass;
USBD_RegisterClass(&hUsbDeviceFS, newClassPointer);
USBD_Start(&hUsbDeviceFS);
//The USB device stack will now receive commands from our host.
//All we need to do is monitor for downstream device disconnection.
}
void Upstream_StateMachine_DeviceDisconnected(void)
{
if ((ConfiguredDeviceClass == COMMAND_CLASS_INTERFACE) ||
(ConfiguredDeviceClass >= COMMAND_CLASS_ERROR))
{
UPSTREAM_STATEMACHINE_FREAKOUT;
return;
}
USBD_Stop(&hUsbDeviceFS);
Upstream_GetFreePacket(Upstream_StateMachine_NotifyDevice);
if ((ConfiguredDeviceClass == COMMAND_CLASS_INTERFACE) ||
(ConfiguredDeviceClass >= COMMAND_CLASS_ERROR))
{
UPSTREAM_STATEMACHINE_FREAKOUT;
return;
}
USBD_Stop(&hUsbDeviceFS);
Upstream_GetFreePacket(Upstream_StateMachine_NotifyDevice);
}

@ -47,7 +47,7 @@ USBD_HandleTypeDef hUsbDeviceFS;
void USB_Device_Init(void)
{
USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS);
USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS);
// USBD_RegisterClass(&hUsbDeviceFS, &USBD_MSC);
// USBD_Start(&hUsbDeviceFS);

@ -267,7 +267,7 @@ void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
void HAL_PCD_BufferFreedCallBack(PCD_HandleTypeDef *hpcd)
{
USBD_BufferFreed(hpcd->pData);
USBD_BufferFreed(hpcd->pData);
}
/*******************************************************************************

Loading…
Cancel
Save