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) || else if((hhcd->hc[chnum].state == HC_XACTERR) ||
(hhcd->hc[chnum].state == HC_DATATGLERR) || (hhcd->hc[chnum].state == HC_DATATGLERR) ||
(hhcd->hc[chnum].state == HC_NAK)) (hhcd->hc[chnum].state == HC_NAK))
{ {
if(hhcd->hc[chnum].ErrCnt++ > 3) 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) 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) // if(hhcd->hc[chnum].ep_type == EP_TYPE_INTR)
// { // {
__HAL_HCD_UNMASK_HALT_HC_INT(chnum); __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)) 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 */ /*manage multiple Xfer */
hhcd->hc[channelnum].xfer_buff += pktcnt; 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 */ /* Wait until Busy flag is reset before disabling SPI */
if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_BSY, SET, SPI_TIMEOUT_VALUE) != HAL_OK) 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. //The Busy flag occasionally fails to reset within timeout. No idea why.
//But in this case WaitOnFlagUntilTimeout disables the SPI for us, //But in this case WaitOnFlagUntilTimeout disables the SPI for us,
//so we can ignore the error and carry on. //so we can ignore the error and carry on.
//hspi->ErrorCode |= HAL_SPI_ERROR_FLAG; //hspi->ErrorCode |= HAL_SPI_ERROR_FLAG;
} }

@ -14,49 +14,49 @@
#define INC_BOARD_CONFIG_H_ #define INC_BOARD_CONFIG_H_
#define BSRR_SHIFT_HIGH 0 #define BSRR_SHIFT_HIGH 0
#define BSRR_SHIFT_LOW 16 #define BSRR_SHIFT_LOW 16
#define PA_JTMS GPIO_PIN_13 #define PA_JTMS GPIO_PIN_13
#define PA_JTCK GPIO_PIN_14 #define PA_JTCK GPIO_PIN_14
#define PA_JTDI GPIO_PIN_15 #define PA_JTDI GPIO_PIN_15
#define PB_JTDO GPIO_PIN_3 #define PB_JTDO GPIO_PIN_3
#define PB_NJTRST GPIO_PIN_4 #define PB_NJTRST GPIO_PIN_4
#define USB_FS_VBUS_PIN GPIO_PIN_9 #define USB_FS_VBUS_PIN GPIO_PIN_9
#define USB_FS_VBUS_PORT GPIOA #define USB_FS_VBUS_PORT GPIOA
#define USB_FS_VBUSON_PIN GPIO_PIN_10 #define USB_FS_VBUSON_PIN GPIO_PIN_10
#define USB_FS_VBUSON_PORT GPIOA #define USB_FS_VBUSON_PORT GPIOA
#define USB_FS_FAULT_PIN GPIO_PIN_6 #define USB_FS_FAULT_PIN GPIO_PIN_6
#define USB_FS_FAULT_PORT GPIOB #define USB_FS_FAULT_PORT GPIOB
#define USB_HS_VBUS_PIN GPIO_PIN_13 #define USB_HS_VBUS_PIN GPIO_PIN_13
#define USB_HS_VBUS_PORT GPIOB #define USB_HS_VBUS_PORT GPIOB
#define USB_HS_VBUSON_PIN GPIO_PIN_8 #define USB_HS_VBUSON_PIN GPIO_PIN_8
#define USB_HS_VBUSON_PORT GPIOA #define USB_HS_VBUSON_PORT GPIOA
#define FAULT_LED_PIN GPIO_PIN_13 #define FAULT_LED_PIN GPIO_PIN_13
#define FAULT_LED_PORT GPIOC #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_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_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_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 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_PIN GPIO_PIN_2 //Temporary indicator of SPI (or whatever) activity
#define INT_ACTIVE_PORT GPIOA #define INT_ACTIVE_PORT GPIOA
#define INT_ACTIVE_ON INT_ACTIVE_PORT->BSRR = (INT_ACTIVE_PIN << BSRR_SHIFT_HIGH) #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_OFF INT_ACTIVE_PORT->BSRR = (INT_ACTIVE_PIN << BSRR_SHIFT_LOW)
//#define SPI1_NSS_PIN GPIO_PIN_4 //#define SPI1_NSS_PIN GPIO_PIN_4
//#define SPI1_NSS_PORT GPIOA //#define SPI1_NSS_PORT GPIOA
#define UPSTREAM_TX_REQUEST_PIN GPIO_PIN_3 #define UPSTREAM_TX_REQUEST_PIN GPIO_PIN_3
#define UPSTREAM_TX_REQUEST_PORT GPIOA #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_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 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 DBGMCU_IDCODE_DEV_ID_405_407_415_417 0x413
#endif /* INC_BOARD_CONFIG_H_ */ #endif /* INC_BOARD_CONFIG_H_ */

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

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

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

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

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

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

@ -151,7 +151,7 @@ USBH_ClassTypeDef USBH_msc =
* @retval USBH Status * @retval USBH Status
*/ */
static USBH_StatusTypeDef USBH_MSC_InterfaceInit (USBH_HandleTypeDef *phost) static USBH_StatusTypeDef USBH_MSC_InterfaceInit (USBH_HandleTypeDef *phost)
{ {
uint8_t interface = 0; uint8_t interface = 0;
USBH_StatusTypeDef status = USBH_FAIL ; USBH_StatusTypeDef status = USBH_FAIL ;
MSC_HandleTypeDef *MSC_Handle; MSC_HandleTypeDef *MSC_Handle;
@ -483,35 +483,35 @@ static USBH_StatusTypeDef USBH_MSC_Process(USBH_HandleTypeDef *phost)
} }
else else
{ {
MSC_Handle->current_lun = 0; MSC_Handle->current_lun = 0;
MSC_Handle->state = MSC_IDLE; MSC_Handle->state = MSC_IDLE;
phost->pUser(phost, HOST_USER_CLASS_ACTIVE); phost->pUser(phost, HOST_USER_CLASS_ACTIVE);
} }
break; break;
case MSC_IDLE: case MSC_IDLE:
error = USBH_OK; error = USBH_OK;
break; break;
case MSC_READ: case MSC_READ:
case MSC_WRITE: case MSC_WRITE:
error = USBH_MSC_RdWrProcess(phost, MSC_Handle->rw_lun); error = USBH_MSC_RdWrProcess(phost, MSC_Handle->rw_lun);
if(((int32_t)(phost->Timer - MSC_Handle->timeout) > 0) || (phost->device.is_connected == 0)) if(((int32_t)(phost->Timer - MSC_Handle->timeout) > 0) || (phost->device.is_connected == 0))
{ {
error = USBH_FAIL; error = USBH_FAIL;
} }
if (error != USBH_BUSY) if (error != USBH_BUSY)
{ {
MSC_Handle->state = MSC_IDLE; MSC_Handle->state = MSC_IDLE;
if (MSC_Handle->RdWrCompleteCallback != NULL) if (MSC_Handle->RdWrCompleteCallback != NULL)
{ {
MSC_Handle->RdWrCompleteCallback(error); MSC_Handle->RdWrCompleteCallback(error);
MSC_Handle->RdWrCompleteCallback = NULL; MSC_Handle->RdWrCompleteCallback = NULL;
} }
} }
break; break;
default: default:
break; break;
@ -719,13 +719,13 @@ USBH_StatusTypeDef USBH_MSC_Read(USBH_HandleTypeDef *phost,
uint8_t lun, uint8_t lun,
uint32_t address, uint32_t address,
uint32_t length, uint32_t length,
MSC_RdWrCompleteCallback callback) MSC_RdWrCompleteCallback callback)
{ {
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData; MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
if ((phost->device.is_connected == 0) || if ((phost->device.is_connected == 0) ||
(phost->gState != HOST_CLASS) || (phost->gState != HOST_CLASS) ||
(MSC_Handle->state != MSC_IDLE) || (MSC_Handle->state != MSC_IDLE) ||
(MSC_Handle->unit[lun].state != MSC_IDLE)) (MSC_Handle->unit[lun].state != MSC_IDLE))
{ {
return USBH_FAIL; return USBH_FAIL;
@ -760,13 +760,13 @@ USBH_StatusTypeDef USBH_MSC_Write(USBH_HandleTypeDef *phost,
uint8_t lun, uint8_t lun,
uint32_t address, uint32_t address,
uint32_t length, uint32_t length,
MSC_RdWrCompleteCallback callback) MSC_RdWrCompleteCallback callback)
{ {
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData; MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
if ((phost->device.is_connected == 0) || if ((phost->device.is_connected == 0) ||
(phost->gState != HOST_CLASS) || (phost->gState != HOST_CLASS) ||
(MSC_Handle->state != MSC_IDLE) || (MSC_Handle->state != MSC_IDLE) ||
(MSC_Handle->unit[lun].state != MSC_IDLE)) (MSC_Handle->unit[lun].state != MSC_IDLE))
{ {
return USBH_FAIL; 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_FreePacketCallback(DownstreamPacketTypeDef* freePacket);
void USBH_MSC_BOT_Read_Multipacket_PrepareURB(USBH_HandleTypeDef *phost); void USBH_MSC_BOT_Read_Multipacket_PrepareURB(USBH_HandleTypeDef *phost);
void USBH_MSC_BOT_Write_Multipacket_ReceivePacketCallback(DownstreamPacketTypeDef* receivedPacket, 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); 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; break;
case BOT_DATA_IN: case BOT_DATA_IN:
if (MSC_Handle->hbot.pbuf != NULL) if (MSC_Handle->hbot.pbuf != NULL)
{ {
//Simple single-buffer operation //Simple single-buffer operation
MSC_Handle->hbot.state = BOT_DATA_IN_WAIT; MSC_Handle->hbot.state = BOT_DATA_IN_WAIT;
MSC_Handle->hbot.this_URB_size = MIN(MSC_Handle->hbot.cbw.field.DataTransferLength, MSC_Handle->hbot.this_URB_size = MIN(MSC_Handle->hbot.cbw.field.DataTransferLength,
MSC_Handle->InEpSize); MSC_Handle->InEpSize);
USBH_BulkReceiveData (phost, USBH_BulkReceiveData (phost,
MSC_Handle->hbot.pbuf, MSC_Handle->hbot.pbuf,
MSC_Handle->hbot.this_URB_size, MSC_Handle->hbot.this_URB_size,
MSC_Handle->InPipe); MSC_Handle->InPipe);
} }
else else
{ {
//Asynchronous multi-packet operation: get first packet //Asynchronous multi-packet operation: get first packet
MSC_Handle->hbot.state = BOT_DATA_IN_WAIT_FREE_PACKET; MSC_Handle->hbot.state = BOT_DATA_IN_WAIT_FREE_PACKET;
Callback_MSC_phost = phost; Callback_MSC_phost = phost;
if (Downstream_GetFreePacket(USBH_MSC_BOT_Read_Multipacket_FreePacketCallback) != HAL_OK) if (Downstream_GetFreePacket(USBH_MSC_BOT_Read_Multipacket_FreePacketCallback) != HAL_OK)
{ {
MSC_Handle->hbot.state = BOT_ERROR_IN; MSC_Handle->hbot.state = BOT_ERROR_IN;
} }
} }
break; break;
case BOT_DATA_IN_WAIT_FREE_PACKET: case BOT_DATA_IN_WAIT_FREE_PACKET:
break; break;
case BOT_DATA_IN_WAIT: case BOT_DATA_IN_WAIT:
URB_Status = USBH_LL_GetURBState(phost, MSC_Handle->InPipe); URB_Status = USBH_LL_GetURBState(phost, MSC_Handle->InPipe);
if (URB_Status == USBH_URB_DONE) if (URB_Status == USBH_URB_DONE)
{ {
if (USBH_LL_GetLastXferSize(phost, MSC_Handle->InPipe) != MSC_Handle->hbot.this_URB_size) if (USBH_LL_GetLastXferSize(phost, MSC_Handle->InPipe) != MSC_Handle->hbot.this_URB_size)
{ {
while(1); while(1);
} }
MSC_Handle->hbot.cbw.field.DataTransferLength -= MSC_Handle->hbot.this_URB_size; MSC_Handle->hbot.cbw.field.DataTransferLength -= MSC_Handle->hbot.this_URB_size;
if (MSC_Handle->hbot.pbuf != NULL) if (MSC_Handle->hbot.pbuf != NULL)
{ {
//Simple single-buffer operation: everything must fit in one URB //Simple single-buffer operation: everything must fit in one URB
MSC_Handle->hbot.state = BOT_RECEIVE_CSW; MSC_Handle->hbot.state = BOT_RECEIVE_CSW;
} }
else else
{ {
//Asynchronous multi-packet operation //Asynchronous multi-packet operation
MSC_Handle->hbot.bot_packet_bytes_remaining -= MSC_Handle->hbot.this_URB_size; 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; MSC_Handle->hbot.bot_packet_pbuf += MSC_Handle->hbot.this_URB_size;
if (MSC_Handle->hbot.cbw.field.DataTransferLength == 0) if (MSC_Handle->hbot.cbw.field.DataTransferLength == 0)
{ {
//End of reception: dispatch last packet //End of reception: dispatch last packet
MSC_Handle->hbot.state = BOT_RECEIVE_CSW; MSC_Handle->hbot.state = BOT_RECEIVE_CSW;
Downstream_MSC_PutStreamDataPacket(MSC_Handle->hbot.bot_packet, Downstream_MSC_PutStreamDataPacket(MSC_Handle->hbot.bot_packet,
(BOT_PAGE_LENGTH - MSC_Handle->hbot.bot_packet_bytes_remaining)); (BOT_PAGE_LENGTH - MSC_Handle->hbot.bot_packet_bytes_remaining));
} }
else else
{ {
//Still more data to receive //Still more data to receive
if (MSC_Handle->hbot.bot_packet_bytes_remaining == 0) if (MSC_Handle->hbot.bot_packet_bytes_remaining == 0)
{ {
//Dispatch current bot_packet, then get a new one //Dispatch current bot_packet, then get a new one
if (Downstream_MSC_PutStreamDataPacket(MSC_Handle->hbot.bot_packet, if (Downstream_MSC_PutStreamDataPacket(MSC_Handle->hbot.bot_packet,
(BOT_PAGE_LENGTH - MSC_Handle->hbot.bot_packet_bytes_remaining)) != HAL_OK) (BOT_PAGE_LENGTH - MSC_Handle->hbot.bot_packet_bytes_remaining)) != HAL_OK)
{ {
MSC_Handle->hbot.state = BOT_ERROR_IN; MSC_Handle->hbot.state = BOT_ERROR_IN;
break; break;
} }
MSC_Handle->hbot.state = BOT_DATA_IN_WAIT_FREE_PACKET; MSC_Handle->hbot.state = BOT_DATA_IN_WAIT_FREE_PACKET;
if (Downstream_GetFreePacket(USBH_MSC_BOT_Read_Multipacket_FreePacketCallback) != HAL_OK) if (Downstream_GetFreePacket(USBH_MSC_BOT_Read_Multipacket_FreePacketCallback) != HAL_OK)
{ {
MSC_Handle->hbot.state = BOT_ERROR_IN; MSC_Handle->hbot.state = BOT_ERROR_IN;
break; break;
} }
} }
else else
{ {
//Continue filling the current bot_packet //Continue filling the current bot_packet
USBH_MSC_BOT_Read_Multipacket_PrepareURB(phost); USBH_MSC_BOT_Read_Multipacket_PrepareURB(phost);
} }
} }
} }
} }
else if (URB_Status == USBH_URB_STALL) else if (URB_Status == USBH_URB_STALL)
@ -279,89 +279,89 @@ USBH_StatusTypeDef USBH_MSC_BOT_Process (USBH_HandleTypeDef *phost, uint8_t lun)
break; break;
case BOT_DATA_OUT: case BOT_DATA_OUT:
if (MSC_Handle->hbot.pbuf != NULL) if (MSC_Handle->hbot.pbuf != NULL)
{ {
//Simple single-buffer operation //Simple single-buffer operation
MSC_Handle->hbot.state = BOT_DATA_OUT_WAIT; MSC_Handle->hbot.state = BOT_DATA_OUT_WAIT;
MSC_Handle->hbot.this_URB_size = MIN(MSC_Handle->hbot.cbw.field.DataTransferLength, MSC_Handle->hbot.this_URB_size = MIN(MSC_Handle->hbot.cbw.field.DataTransferLength,
MSC_Handle->OutEpSize); MSC_Handle->OutEpSize);
USBH_BulkSendData (phost, USBH_BulkSendData (phost,
MSC_Handle->hbot.pbuf, MSC_Handle->hbot.pbuf,
MSC_Handle->hbot.this_URB_size, MSC_Handle->hbot.this_URB_size,
MSC_Handle->OutPipe, MSC_Handle->OutPipe,
1); 1);
} }
else else
{ {
//Asynchronous multi-packet operation: get first packet //Asynchronous multi-packet operation: get first packet
MSC_Handle->hbot.state = BOT_DATA_OUT_WAIT_RECEIVE_PACKET; MSC_Handle->hbot.state = BOT_DATA_OUT_WAIT_RECEIVE_PACKET;
Callback_MSC_phost = phost; Callback_MSC_phost = phost;
if (Downstream_MSC_GetStreamDataPacket(USBH_MSC_BOT_Write_Multipacket_ReceivePacketCallback) != HAL_OK) if (Downstream_MSC_GetStreamDataPacket(USBH_MSC_BOT_Write_Multipacket_ReceivePacketCallback) != HAL_OK)
{ {
MSC_Handle->hbot.state = BOT_ERROR_OUT; MSC_Handle->hbot.state = BOT_ERROR_OUT;
} }
} }
break; break;
case BOT_DATA_OUT_WAIT_RECEIVE_PACKET: case BOT_DATA_OUT_WAIT_RECEIVE_PACKET:
break; break;
case BOT_DATA_OUT_WAIT: case BOT_DATA_OUT_WAIT:
URB_Status = USBH_LL_GetURBState(phost, MSC_Handle->OutPipe); URB_Status = USBH_LL_GetURBState(phost, MSC_Handle->OutPipe);
if(URB_Status == USBH_URB_DONE) if(URB_Status == USBH_URB_DONE)
{ {
MSC_Handle->hbot.cbw.field.DataTransferLength -= MSC_Handle->hbot.this_URB_size; MSC_Handle->hbot.cbw.field.DataTransferLength -= MSC_Handle->hbot.this_URB_size;
if (MSC_Handle->hbot.pbuf != NULL) if (MSC_Handle->hbot.pbuf != NULL)
{ {
//Simple single-buffer operation: everything must fit in one URB //Simple single-buffer operation: everything must fit in one URB
MSC_Handle->hbot.state = BOT_RECEIVE_CSW; MSC_Handle->hbot.state = BOT_RECEIVE_CSW;
} }
else else
{ {
//Asynchronous multi-packet operation //Asynchronous multi-packet operation
MSC_Handle->hbot.bot_packet_bytes_remaining -= MSC_Handle->hbot.this_URB_size; 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; MSC_Handle->hbot.bot_packet_pbuf += MSC_Handle->hbot.this_URB_size;
if (MSC_Handle->hbot.cbw.field.DataTransferLength == 0) if (MSC_Handle->hbot.cbw.field.DataTransferLength == 0)
{ {
//End of transmission //End of transmission
Downstream_ReleasePacket(MSC_Handle->hbot.bot_packet); Downstream_ReleasePacket(MSC_Handle->hbot.bot_packet);
MSC_Handle->hbot.state = BOT_RECEIVE_CSW; MSC_Handle->hbot.state = BOT_RECEIVE_CSW;
} }
else else
{ {
//Still more data to send //Still more data to send
if (MSC_Handle->hbot.bot_packet_bytes_remaining == 0) if (MSC_Handle->hbot.bot_packet_bytes_remaining == 0)
{ {
//Get next bot_packet //Get next bot_packet
Downstream_ReleasePacket(MSC_Handle->hbot.bot_packet); Downstream_ReleasePacket(MSC_Handle->hbot.bot_packet);
MSC_Handle->hbot.state = BOT_DATA_OUT_WAIT_RECEIVE_PACKET; MSC_Handle->hbot.state = BOT_DATA_OUT_WAIT_RECEIVE_PACKET;
if (Downstream_MSC_GetStreamDataPacket(USBH_MSC_BOT_Write_Multipacket_ReceivePacketCallback) != HAL_OK) if (Downstream_MSC_GetStreamDataPacket(USBH_MSC_BOT_Write_Multipacket_ReceivePacketCallback) != HAL_OK)
{ {
MSC_Handle->hbot.state = BOT_ERROR_OUT; MSC_Handle->hbot.state = BOT_ERROR_OUT;
} }
} }
else else
{ {
//Continue writing the current bot_packet //Continue writing the current bot_packet
USBH_MSC_BOT_Write_Multipacket_PrepareURB(phost); USBH_MSC_BOT_Write_Multipacket_PrepareURB(phost);
} }
} }
} }
} }
else if(URB_Status == USBH_URB_NOTREADY) else if(URB_Status == USBH_URB_NOTREADY)
{ {
/* Resend same data */ /* Resend same data */
if (MSC_Handle->hbot.pbuf != NULL) if (MSC_Handle->hbot.pbuf != NULL)
{ {
MSC_Handle->hbot.state = BOT_DATA_OUT; MSC_Handle->hbot.state = BOT_DATA_OUT;
} }
else else
{ {
USBH_MSC_BOT_Write_Multipacket_PrepareURB(phost); USBH_MSC_BOT_Write_Multipacket_PrepareURB(phost);
} }
} }
else if(URB_Status == USBH_URB_STALL) 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) void USBH_MSC_BOT_Read_Multipacket_FreePacketCallback(DownstreamPacketTypeDef* freePacket)
{ {
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) Callback_MSC_phost->pActiveClass->pData; MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) Callback_MSC_phost->pActiveClass->pData;
if (MSC_Handle->hbot.state != BOT_DATA_IN_WAIT_FREE_PACKET) if (MSC_Handle->hbot.state != BOT_DATA_IN_WAIT_FREE_PACKET)
{ {
Downstream_PacketProcessor_FreakOut(); Downstream_PacketProcessor_FreakOut();
return; return;
} }
MSC_Handle->hbot.state = BOT_DATA_IN_WAIT; MSC_Handle->hbot.state = BOT_DATA_IN_WAIT;
MSC_Handle->hbot.bot_packet = freePacket; MSC_Handle->hbot.bot_packet = freePacket;
MSC_Handle->hbot.bot_packet_pbuf = freePacket->Data; MSC_Handle->hbot.bot_packet_pbuf = freePacket->Data;
MSC_Handle->hbot.bot_packet_bytes_remaining = BOT_PAGE_LENGTH; MSC_Handle->hbot.bot_packet_bytes_remaining = BOT_PAGE_LENGTH;
USBH_MSC_BOT_Read_Multipacket_PrepareURB(Callback_MSC_phost); USBH_MSC_BOT_Read_Multipacket_PrepareURB(Callback_MSC_phost);
} }
void USBH_MSC_BOT_Read_Multipacket_PrepareURB(USBH_HandleTypeDef *phost) void USBH_MSC_BOT_Read_Multipacket_PrepareURB(USBH_HandleTypeDef *phost)
{ {
uint32_t temp_URB_size; uint32_t temp_URB_size;
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData; MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
temp_URB_size = MSC_Handle->hbot.cbw.field.DataTransferLength; temp_URB_size = MSC_Handle->hbot.cbw.field.DataTransferLength;
if (temp_URB_size > MSC_Handle->hbot.bot_packet_bytes_remaining) if (temp_URB_size > MSC_Handle->hbot.bot_packet_bytes_remaining)
{ {
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) if (temp_URB_size > MSC_Handle->InEpSize)
{ {
temp_URB_size = MSC_Handle->InEpSize; temp_URB_size = MSC_Handle->InEpSize;
} }
MSC_Handle->hbot.this_URB_size = (uint16_t)temp_URB_size; MSC_Handle->hbot.this_URB_size = (uint16_t)temp_URB_size;
USBH_BulkReceiveData(phost, USBH_BulkReceiveData(phost,
MSC_Handle->hbot.bot_packet_pbuf, MSC_Handle->hbot.bot_packet_pbuf,
MSC_Handle->hbot.this_URB_size, MSC_Handle->hbot.this_URB_size,
MSC_Handle->InPipe); MSC_Handle->InPipe);
} }
void USBH_MSC_BOT_Write_Multipacket_ReceivePacketCallback(DownstreamPacketTypeDef* receivedPacket, 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; MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) Callback_MSC_phost->pActiveClass->pData;
if (MSC_Handle->hbot.state != BOT_DATA_OUT_WAIT_RECEIVE_PACKET) if (MSC_Handle->hbot.state != BOT_DATA_OUT_WAIT_RECEIVE_PACKET)
{ {
Downstream_PacketProcessor_FreakOut(); Downstream_PacketProcessor_FreakOut();
return; return;
} }
MSC_Handle->hbot.state = BOT_DATA_OUT_WAIT; MSC_Handle->hbot.state = BOT_DATA_OUT_WAIT;
MSC_Handle->hbot.bot_packet = receivedPacket; MSC_Handle->hbot.bot_packet = receivedPacket;
MSC_Handle->hbot.bot_packet_pbuf = receivedPacket->Data; MSC_Handle->hbot.bot_packet_pbuf = receivedPacket->Data;
MSC_Handle->hbot.bot_packet_bytes_remaining = dataLength; MSC_Handle->hbot.bot_packet_bytes_remaining = dataLength;
USBH_MSC_BOT_Write_Multipacket_PrepareURB(Callback_MSC_phost); USBH_MSC_BOT_Write_Multipacket_PrepareURB(Callback_MSC_phost);
} }
void USBH_MSC_BOT_Write_Multipacket_PrepareURB(USBH_HandleTypeDef *phost) void USBH_MSC_BOT_Write_Multipacket_PrepareURB(USBH_HandleTypeDef *phost)
{ {
uint32_t temp_URB_size; uint32_t temp_URB_size;
MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData; MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData;
temp_URB_size = MSC_Handle->hbot.cbw.field.DataTransferLength; temp_URB_size = MSC_Handle->hbot.cbw.field.DataTransferLength;
if (temp_URB_size > MSC_Handle->hbot.bot_packet_bytes_remaining) if (temp_URB_size > MSC_Handle->hbot.bot_packet_bytes_remaining)
{ {
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) if (temp_URB_size > MSC_Handle->OutEpSize)
{ {
temp_URB_size = MSC_Handle->OutEpSize; temp_URB_size = MSC_Handle->OutEpSize;
} }
MSC_Handle->hbot.this_URB_size = (uint16_t)temp_URB_size; MSC_Handle->hbot.this_URB_size = (uint16_t)temp_URB_size;
USBH_BulkSendData (phost, USBH_BulkSendData (phost,
MSC_Handle->hbot.bot_packet_pbuf, MSC_Handle->hbot.bot_packet_pbuf,
MSC_Handle->hbot.this_URB_size, MSC_Handle->hbot.this_URB_size,
MSC_Handle->OutPipe, MSC_Handle->OutPipe,
1); 1);
} }

@ -67,7 +67,7 @@
#define HOST_USER_CONNECTION 4 #define HOST_USER_CONNECTION 4
#define HOST_USER_DISCONNECTION 5 #define HOST_USER_DISCONNECTION 5
#define HOST_USER_UNRECOVERED_ERROR 6 #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 else
{ {
phost->pUser(phost, HOST_USER_CLASS_FAILED); phost->pUser(phost, HOST_USER_CLASS_FAILED);
phost->gState = HOST_ABORT_STATE; phost->gState = HOST_ABORT_STATE;
USBH_UsrLog ("No registered class for this device."); 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) if (length > USBH_MAX_SIZE_CONFIGURATION)
{ {
length = USBH_MAX_SIZE_CONFIGURATION; length = USBH_MAX_SIZE_CONFIGURATION;
} }
#else #else
pData = phost->device.Data; pData = phost->device.Data;
if (length > USBH_MAX_DATA_BUFFER) if (length > USBH_MAX_DATA_BUFFER)
{ {
length = USBH_MAX_DATA_BUFFER; length = USBH_MAX_DATA_BUFFER;
} }
#endif #endif
if((status = USBH_GetDescriptor(phost, if((status = USBH_GetDescriptor(phost,
@ -601,8 +601,8 @@ static USBH_StatusTypeDef USBH_HandleControl (USBH_HandleTypeDef *phost)
case CTRL_SETUP: case CTRL_SETUP:
/* send a SETUP packet */ /* send a SETUP packet */
USBH_CtlSendSetup (phost, USBH_CtlSendSetup (phost,
(uint8_t *)phost->Control.setup.d8 , (uint8_t *)phost->Control.setup.d8 ,
phost->Control.pipe_out); phost->Control.pipe_out);
phost->Control.state = CTRL_SETUP_WAIT; phost->Control.state = CTRL_SETUP_WAIT;
break; break;

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

@ -17,14 +17,14 @@
#include "usbh_msc.h" #include "usbh_msc.h"
extern USBH_HandleTypeDef hUsbHostFS; //Hard-link ourselves to usb_host.c extern USBH_HandleTypeDef hUsbHostFS; //Hard-link ourselves to usb_host.c
//Stuff we need to save for our callbacks to use: //Stuff we need to save for our callbacks to use:
DownstreamMSCCallbackPacketTypeDef GetStreamDataCallback; DownstreamMSCCallbackPacketTypeDef GetStreamDataCallback;
uint32_t ByteCount; uint32_t ByteCount;
DownstreamPacketTypeDef* ReadStreamPacket; DownstreamPacketTypeDef* ReadStreamPacket;
uint8_t ReadStreamBusy; uint8_t ReadStreamBusy;
void Downstream_MSC_PacketProcessor_TestUnitReady(DownstreamPacketTypeDef* receivedPacket); 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. //configured device to bomb our USB stack, accidentally or otherwise.
HAL_StatusTypeDef Downstream_MSC_ApproveConnectedDevice(void) 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) if (MSC_Handle->unit[MSC_FIXED_LUN].error != MSC_OK)
{ {
return HAL_ERROR; return HAL_ERROR;
} }
if ((MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr == 0) || if ((MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr == 0) ||
(MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr == UINT32_MAX)) (MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr == UINT32_MAX))
{ {
return HAL_ERROR; return HAL_ERROR;
} }
if (MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_size != MSC_SUPPORTED_BLOCK_SIZE) if (MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_size != MSC_SUPPORTED_BLOCK_SIZE)
{ {
return HAL_ERROR; return HAL_ERROR;
} }
return HAL_OK; return HAL_OK;
} }
void Downstream_MSC_PacketProcessor(DownstreamPacketTypeDef* receivedPacket) void Downstream_MSC_PacketProcessor(DownstreamPacketTypeDef* receivedPacket)
{ {
switch (receivedPacket->Command) switch (receivedPacket->Command)
{ {
case COMMAND_MSC_TEST_UNIT_READY: case COMMAND_MSC_TEST_UNIT_READY:
Downstream_MSC_PacketProcessor_TestUnitReady(receivedPacket); Downstream_MSC_PacketProcessor_TestUnitReady(receivedPacket);
break; break;
case COMMAND_MSC_GET_CAPACITY: case COMMAND_MSC_GET_CAPACITY:
Downstream_MSC_PacketProcessor_GetCapacity(receivedPacket); Downstream_MSC_PacketProcessor_GetCapacity(receivedPacket);
break; break;
case COMMAND_MSC_READ: case COMMAND_MSC_READ:
Downstream_MSC_PacketProcessor_BeginRead(receivedPacket); Downstream_MSC_PacketProcessor_BeginRead(receivedPacket);
break; break;
case COMMAND_MSC_WRITE: case COMMAND_MSC_WRITE:
Downstream_MSC_PacketProcessor_BeginWrite(receivedPacket); Downstream_MSC_PacketProcessor_BeginWrite(receivedPacket);
break; break;
default: default:
Downstream_PacketProcessor_FreakOut(); Downstream_PacketProcessor_FreakOut();
} }
} }
void Downstream_MSC_PacketProcessor_TestUnitReady(DownstreamPacketTypeDef* receivedPacket) void Downstream_MSC_PacketProcessor_TestUnitReady(DownstreamPacketTypeDef* receivedPacket)
{ {
if (USBH_MSC_UnitIsReady(&hUsbHostFS, MSC_FIXED_LUN)) if (USBH_MSC_UnitIsReady(&hUsbHostFS, MSC_FIXED_LUN))
{ {
receivedPacket->Data[0] = HAL_OK; receivedPacket->Data[0] = HAL_OK;
} }
else else
{ {
receivedPacket->Data[0] = HAL_ERROR; receivedPacket->Data[0] = HAL_ERROR;
} }
receivedPacket->Length16 = DOWNSTREAM_PACKET_HEADER_LEN_16 + 1; receivedPacket->Length16 = DOWNSTREAM_PACKET_HEADER_LEN_16 + 1;
Downstream_PacketProcessor_ClassReply(receivedPacket); Downstream_PacketProcessor_ClassReply(receivedPacket);
} }
void Downstream_MSC_PacketProcessor_GetCapacity(DownstreamPacketTypeDef* 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); 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[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; *(uint32_t*)&(receivedPacket->Data[4]) = (uint32_t)MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_size;
Downstream_PacketProcessor_ClassReply(receivedPacket); Downstream_PacketProcessor_ClassReply(receivedPacket);
} }
void Downstream_MSC_PacketProcessor_BeginRead(DownstreamPacketTypeDef* receivedPacket) void Downstream_MSC_PacketProcessor_BeginRead(DownstreamPacketTypeDef* receivedPacket)
{ {
uint64_t readBlockAddress; uint64_t readBlockAddress;
uint32_t readBlockCount; uint32_t readBlockCount;
uint64_t readByteCount; uint64_t readByteCount;
MSC_HandleTypeDef* MSC_Handle = (MSC_HandleTypeDef*)hUsbHostFS.pActiveClass->pData; MSC_HandleTypeDef* MSC_Handle = (MSC_HandleTypeDef*)hUsbHostFS.pActiveClass->pData;
if (receivedPacket->Length16 != (DOWNSTREAM_PACKET_HEADER_LEN_16 + ((4 * 3) / 2))) if (receivedPacket->Length16 != (DOWNSTREAM_PACKET_HEADER_LEN_16 + ((4 * 3) / 2)))
{ {
Downstream_PacketProcessor_FreakOut(); Downstream_PacketProcessor_FreakOut();
return; return;
} }
readBlockAddress = *(uint64_t*)&(receivedPacket->Data[0]); readBlockAddress = *(uint64_t*)&(receivedPacket->Data[0]);
readBlockCount = *(uint32_t*)&(receivedPacket->Data[8]); readBlockCount = *(uint32_t*)&(receivedPacket->Data[8]);
readByteCount = readBlockCount * MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_size; readByteCount = readBlockCount * MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_size;
if ((readBlockAddress >= (uint64_t)MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr) || if ((readBlockAddress >= (uint64_t)MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr) ||
((readBlockAddress + readBlockCount - 1) >= (uint64_t)MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr) || ((readBlockAddress + readBlockCount - 1) >= (uint64_t)MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr) ||
(readByteCount > UINT32_MAX)) (readByteCount > UINT32_MAX))
{ {
Downstream_PacketProcessor_FreakOut(); Downstream_PacketProcessor_FreakOut();
return; return;
} }
receivedPacket->Data[0] = HAL_ERROR; receivedPacket->Data[0] = HAL_ERROR;
receivedPacket->Length16 = DOWNSTREAM_PACKET_HEADER_LEN_16 + 1; receivedPacket->Length16 = DOWNSTREAM_PACKET_HEADER_LEN_16 + 1;
if (USBH_MSC_UnitIsReady(&hUsbHostFS, MSC_FIXED_LUN)) if (USBH_MSC_UnitIsReady(&hUsbHostFS, MSC_FIXED_LUN))
{ {
if (USBH_MSC_Read(&hUsbHostFS, if (USBH_MSC_Read(&hUsbHostFS,
MSC_FIXED_LUN, MSC_FIXED_LUN,
(uint32_t)readBlockAddress, (uint32_t)readBlockAddress,
readBlockCount, readBlockCount,
Downstream_MSC_PacketProcessor_RdWrCompleteCallback) == USBH_OK) Downstream_MSC_PacketProcessor_RdWrCompleteCallback) == USBH_OK)
{ {
receivedPacket->Data[0] = HAL_OK; receivedPacket->Data[0] = HAL_OK;
} }
} }
Downstream_TransmitPacket(receivedPacket); Downstream_TransmitPacket(receivedPacket);
} }
void Downstream_MSC_PacketProcessor_RdWrCompleteCallback(USBH_StatusTypeDef result) void Downstream_MSC_PacketProcessor_RdWrCompleteCallback(USBH_StatusTypeDef result)
{ {
if (result != USBH_OK) if (result != USBH_OK)
{ {
Downstream_GetFreePacket(Downstream_PacketProcessor_GenericErrorReply); Downstream_GetFreePacket(Downstream_PacketProcessor_GenericErrorReply);
return; return;
} }
Downstream_ReceivePacket(Downstream_PacketProcessor); Downstream_ReceivePacket(Downstream_PacketProcessor);
} }
void Downstream_MSC_PacketProcessor_BeginWrite(DownstreamPacketTypeDef* receivedPacket) void Downstream_MSC_PacketProcessor_BeginWrite(DownstreamPacketTypeDef* receivedPacket)
{ {
uint64_t writeBlockAddress; uint64_t writeBlockAddress;
uint32_t writeBlockCount; uint32_t writeBlockCount;
uint64_t writeByteCount; uint64_t writeByteCount;
MSC_HandleTypeDef* MSC_Handle = (MSC_HandleTypeDef*)hUsbHostFS.pActiveClass->pData; MSC_HandleTypeDef* MSC_Handle = (MSC_HandleTypeDef*)hUsbHostFS.pActiveClass->pData;
if (receivedPacket->Length16 != (DOWNSTREAM_PACKET_HEADER_LEN_16 + ((4 * 3) / 2))) if (receivedPacket->Length16 != (DOWNSTREAM_PACKET_HEADER_LEN_16 + ((4 * 3) / 2)))
{ {
Downstream_PacketProcessor_FreakOut(); Downstream_PacketProcessor_FreakOut();
return; return;
} }
writeBlockAddress = *(uint64_t*)&(receivedPacket->Data[0]); writeBlockAddress = *(uint64_t*)&(receivedPacket->Data[0]);
writeBlockCount = *(uint32_t*)&(receivedPacket->Data[8]); writeBlockCount = *(uint32_t*)&(receivedPacket->Data[8]);
writeByteCount = writeBlockCount * MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_size; writeByteCount = writeBlockCount * MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_size;
if ((writeBlockAddress >= (uint64_t)MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr) || 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) || ((writeBlockAddress + writeBlockCount - 1) >= (uint64_t)MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr) ||
(writeByteCount > UINT32_MAX)) (writeByteCount > UINT32_MAX))
{ {
Downstream_PacketProcessor_FreakOut(); Downstream_PacketProcessor_FreakOut();
return; return;
} }
ReadStreamPacket = NULL; //Prepare for GetStreamDataPacket's use ReadStreamPacket = NULL; //Prepare for GetStreamDataPacket's use
ReadStreamBusy = 0; ReadStreamBusy = 0;
ByteCount = (uint32_t)writeByteCount; ByteCount = (uint32_t)writeByteCount;
receivedPacket->Data[0] = HAL_ERROR; receivedPacket->Data[0] = HAL_ERROR;
receivedPacket->Length16 = DOWNSTREAM_PACKET_HEADER_LEN_16 + 1; receivedPacket->Length16 = DOWNSTREAM_PACKET_HEADER_LEN_16 + 1;
//Our host stack has no way to detect if write-protection is enabled. //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. //So currently we can't return HAL_BUSY to Upstream in this situation.
if (USBH_MSC_UnitIsReady(&hUsbHostFS, MSC_FIXED_LUN)) if (USBH_MSC_UnitIsReady(&hUsbHostFS, MSC_FIXED_LUN))
{ {
if (USBH_MSC_Write(&hUsbHostFS, if (USBH_MSC_Write(&hUsbHostFS,
MSC_FIXED_LUN, MSC_FIXED_LUN,
(uint32_t)writeBlockAddress, (uint32_t)writeBlockAddress,
writeBlockCount, writeBlockCount,
Downstream_MSC_PacketProcessor_RdWrCompleteCallback) == USBH_OK) Downstream_MSC_PacketProcessor_RdWrCompleteCallback) == USBH_OK)
{ {
receivedPacket->Data[0] = HAL_OK; receivedPacket->Data[0] = HAL_OK;
} }
} }
Downstream_TransmitPacket(receivedPacket); Downstream_TransmitPacket(receivedPacket);
} }
//Used by USB MSC host driver //Used by USB MSC host driver
HAL_StatusTypeDef Downstream_MSC_PutStreamDataPacket(DownstreamPacketTypeDef* packetToSend, HAL_StatusTypeDef Downstream_MSC_PutStreamDataPacket(DownstreamPacketTypeDef* packetToSend,
uint32_t dataLength8) uint32_t dataLength8)
{ {
if ((dataLength8 % 2) != 0) if ((dataLength8 % 2) != 0)
{ {
return HAL_ERROR; return HAL_ERROR;
} }
packetToSend->Length16 = (dataLength8 / 2) + DOWNSTREAM_PACKET_HEADER_LEN_16; packetToSend->Length16 = (dataLength8 / 2) + DOWNSTREAM_PACKET_HEADER_LEN_16;
packetToSend->CommandClass = COMMAND_CLASS_MASS_STORAGE | COMMAND_CLASS_DATA_FLAG; packetToSend->CommandClass = COMMAND_CLASS_MASS_STORAGE | COMMAND_CLASS_DATA_FLAG;
packetToSend->Command = COMMAND_MSC_READ; packetToSend->Command = COMMAND_MSC_READ;
return Downstream_TransmitPacket(packetToSend); return Downstream_TransmitPacket(packetToSend);
} }
//Used by USB MSC host driver //Used by USB MSC host driver
HAL_StatusTypeDef Downstream_MSC_GetStreamDataPacket(DownstreamMSCCallbackPacketTypeDef callback) HAL_StatusTypeDef Downstream_MSC_GetStreamDataPacket(DownstreamMSCCallbackPacketTypeDef callback)
{ {
GetStreamDataCallback = callback; GetStreamDataCallback = callback;
if (ReadStreamBusy != 0) if (ReadStreamBusy != 0)
{ {
return HAL_OK; return HAL_OK;
} }
ReadStreamBusy = 1; ReadStreamBusy = 1;
if (ReadStreamPacket && GetStreamDataCallback) //Do we have a stored packet and an address to send it? if (ReadStreamPacket && GetStreamDataCallback) //Do we have a stored packet and an address to send it?
{ {
Downstream_MSC_GetStreamDataPacketCallback(ReadStreamPacket); //Send it now! Downstream_MSC_GetStreamDataPacketCallback(ReadStreamPacket); //Send it now!
ReadStreamPacket = NULL; ReadStreamPacket = NULL;
return HAL_OK; //Our callback will call us again, so we don't need to get a packet in this case. 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); return Downstream_ReceivePacket(Downstream_MSC_GetStreamDataPacketCallback);
} }
void Downstream_MSC_GetStreamDataPacketCallback(DownstreamPacketTypeDef* receivedPacket) void Downstream_MSC_GetStreamDataPacketCallback(DownstreamPacketTypeDef* receivedPacket)
{ {
uint16_t dataLength8; uint16_t dataLength8;
ReadStreamBusy = 0; ReadStreamBusy = 0;
if (GetStreamDataCallback == NULL) if (GetStreamDataCallback == NULL)
{ {
ReadStreamPacket = receivedPacket; //We used up our callback already, so save this one for later. ReadStreamPacket = receivedPacket; //We used up our callback already, so save this one for later.
return; return;
} }
dataLength8 = (receivedPacket->Length16 - DOWNSTREAM_PACKET_HEADER_LEN_16) * 2; 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 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->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. (receivedPacket->Length16 <= DOWNSTREAM_PACKET_HEADER_LEN_16) || //Should be at least one data byte in the packet.
(dataLength8 > ByteCount)) (dataLength8 > ByteCount))
{ {
Downstream_PacketProcessor_FreakOut(); Downstream_PacketProcessor_FreakOut();
return; return;
} }
ByteCount -= dataLength8; ByteCount -= dataLength8;
GetStreamDataCallback(receivedPacket, dataLength8); //usb_msc_scsi will use this packet, so don't release now GetStreamDataCallback(receivedPacket, dataLength8); //usb_msc_scsi will use this packet, so don't release now
if (ByteCount > 0) if (ByteCount > 0)
{ {
Downstream_MSC_GetStreamDataPacket(NULL); //Try to get the next packet now, before USB asks for it Downstream_MSC_GetStreamDataPacket(NULL); //Try to get the next packet now, before USB asks for it
} }
} }

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

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

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

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

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

@ -44,7 +44,7 @@
USBH_HandleTypeDef hUsbHostFS; USBH_HandleTypeDef hUsbHostFS;
/* init function */ /* init function */
void USB_Host_Init(void) void USB_Host_Init(void)
{ {
/* Init Host Library,Add Supported Class and Start the library*/ /* Init Host Library,Add Supported Class and Start the library*/
@ -61,7 +61,7 @@ void USB_Host_Init(void)
void USB_Host_Process() void USB_Host_Process()
{ {
/* USB Host Background task */ /* 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. //Called when Downstream Statemachine or SPI freaks out.
void USB_Host_Disconnect() void USB_Host_Disconnect()
{ {
USBH_DeInit(&hUsbHostFS); USBH_DeInit(&hUsbHostFS);
} }

@ -223,7 +223,7 @@ USBH_SpeedTypeDef USBH_LL_GetSpeed (USBH_HandleTypeDef *phost)
case 2 : case 2 :
speed = USBH_SPEED_LOW; speed = USBH_SPEED_LOW;
break; break;
// default: // default:
// speed = USBH_SPEED_FULL; // speed = USBH_SPEED_FULL;
// break; // break;
@ -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) USBH_StatusTypeDef USBH_LL_DriverVBUS (USBH_HandleTypeDef *phost, uint8_t state)
{ {
//Our VBUS is permanently on, so don't bother with this... //Our VBUS is permanently on, so don't bother with this...
// if (phost->id == HOST_FS) // if (phost->id == HOST_FS)
// { // {
// if(state == 0) // if(state == 0)
// { // {
// //VBUS off // //VBUS off
// } // }
// else // else
// { // {
// //VBUS on // //VBUS on
// } // }
// } // }
// HAL_Delay(200); // HAL_Delay(200);
return USBH_OK; return USBH_OK;
} }
/** /**

@ -273,7 +273,7 @@ typedef struct __SPI_HandleTypeDef
#define SPI_CRCCALCULATION_DISABLE ((uint32_t)0x00000000) #define SPI_CRCCALCULATION_DISABLE ((uint32_t)0x00000000)
#define SPI_CRCCALCULATION_ENABLE SPI_CR1_CRCEN #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_count < ep->xfer_len &&
ep->xfer_len != 0) ep->xfer_len != 0)
{ {
/* Write the FIFO */ /* Write the FIFO */
USB_WritePacket(USBx, ep->xfer_buff, epnum, len, hpcd->Init.dma_enable); USB_WritePacket(USBx, ep->xfer_buff, epnum, len, hpcd->Init.dma_enable);
ep->xfer_buff += len; ep->xfer_buff += len;
ep->xfer_count += len; ep->xfer_count += len;
len = ep->xfer_len - ep->xfer_count; len = ep->xfer_len - ep->xfer_count;
if (len > ep->maxpacket) 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 */ /* 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))) 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)) // if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET) && (RCC_OscInitStruct->HSEState == RCC_HSE_OFF))
// { // {
return HAL_ERROR; 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))) 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 */ /* 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)) if(/*(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) &&*/ (RCC_OscInitStruct->HSIState != RCC_HSI_ON))
{ {
return HAL_ERROR; 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 */ /* Check if the PLL is used as system clock or not */
if (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_CFGR_SWS_PLL) if (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_CFGR_SWS_PLL)
{ {
/* Disable the main PLL. */ /* Disable the main PLL. */
__HAL_RCC_PLL_DISABLE(); __HAL_RCC_PLL_DISABLE();
/* Get Start Tick*/ /* Get Start Tick*/
tickstart = HAL_GetTick (); tickstart = HAL_GetTick ();
/* Wait till PLL is ready */ /* Wait till PLL is ready */
while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET) while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET)
{ {
if ((HAL_GetTick () - tickstart) > PLL_TIMEOUT_VALUE) if ((HAL_GetTick () - tickstart) > PLL_TIMEOUT_VALUE)
{ {
return HAL_TIMEOUT; return HAL_TIMEOUT;
} }
} }
if ((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_ON) if ((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_ON)
{ {
/* Check the parameters */ /* Check the parameters */
assert_param(IS_RCC_PLLSOURCE(RCC_OscInitStruct->PLL.PLLSource)); assert_param(IS_RCC_PLLSOURCE(RCC_OscInitStruct->PLL.PLLSource));
assert_param(IS_RCC_PLLM_VALUE(RCC_OscInitStruct->PLL.PLLM)); assert_param(IS_RCC_PLLM_VALUE(RCC_OscInitStruct->PLL.PLLM));
assert_param(IS_RCC_PLLN_VALUE(RCC_OscInitStruct->PLL.PLLN)); assert_param(IS_RCC_PLLN_VALUE(RCC_OscInitStruct->PLL.PLLN));
assert_param(IS_RCC_PLLP_VALUE(RCC_OscInitStruct->PLL.PLLP)); assert_param(IS_RCC_PLLP_VALUE(RCC_OscInitStruct->PLL.PLLP));
assert_param(IS_RCC_PLLQ_VALUE(RCC_OscInitStruct->PLL.PLLQ)); assert_param(IS_RCC_PLLQ_VALUE(RCC_OscInitStruct->PLL.PLLQ));
/* Configure the main PLL clock source, multiplication and division factors. */ /* Configure the main PLL clock source, multiplication and division factors. */
__HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource, __HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource,
RCC_OscInitStruct->PLL.PLLM, RCC_OscInitStruct->PLL.PLLM,
RCC_OscInitStruct->PLL.PLLN, RCC_OscInitStruct->PLL.PLLN,
RCC_OscInitStruct->PLL.PLLP, RCC_OscInitStruct->PLL.PLLP,
RCC_OscInitStruct->PLL.PLLQ); RCC_OscInitStruct->PLL.PLLQ);
/* Enable the main PLL. */ /* Enable the main PLL. */
__HAL_RCC_PLL_ENABLE(); __HAL_RCC_PLL_ENABLE();
/* Get Start Tick*/ /* Get Start Tick*/
tickstart = HAL_GetTick (); tickstart = HAL_GetTick ();
/* Wait till PLL is ready */ /* Wait till PLL is ready */
while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET) while (__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET)
{ {
if ((HAL_GetTick () - tickstart) > PLL_TIMEOUT_VALUE) if ((HAL_GetTick () - tickstart) > PLL_TIMEOUT_VALUE)
{ {
return HAL_TIMEOUT; return HAL_TIMEOUT;
} }
} }
} }
} }
else else
{ {
return HAL_ERROR; return HAL_ERROR;
} }
} }
return HAL_OK; return HAL_OK;
} }

@ -256,7 +256,7 @@ HAL_StatusTypeDef USB_DevInit (USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef c
/* Clear all pending Device Interrupts */ /* Clear all pending Device Interrupts */
USBx_DEVICE->DIEPMSK = 0; USBx_DEVICE->DIEPMSK = 0;
USBx_DEVICE->DOEPMSK = 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; USBx_DEVICE->DAINTMSK = 0;
for (i = 0; i < cfg.dev_endpoints; i++) for (i = 0; i < cfg.dev_endpoints; i++)

@ -13,41 +13,41 @@
#define INC_BOARD_CONFIG_H_ #define INC_BOARD_CONFIG_H_
#define BSRR_SHIFT_HIGH 0 #define BSRR_SHIFT_HIGH 0
#define BSRR_SHIFT_LOW 16 #define BSRR_SHIFT_LOW 16
#define PA_JTMS GPIO_PIN_13 #define PA_JTMS GPIO_PIN_13
#define PA_JTCK GPIO_PIN_14 #define PA_JTCK GPIO_PIN_14
#define PA_JTDI GPIO_PIN_15 #define PA_JTDI GPIO_PIN_15
#define PB_JTDO GPIO_PIN_3 #define PB_JTDO GPIO_PIN_3
#define PB_NJTRST GPIO_PIN_4 #define PB_NJTRST GPIO_PIN_4
#define USB_P_PIN GPIO_PIN_4 #define USB_P_PIN GPIO_PIN_4
#define USB_P_PORT GPIOC #define USB_P_PORT GPIOC
#define FAULT_LED_PIN GPIO_PIN_12 #define FAULT_LED_PIN GPIO_PIN_12
#define FAULT_LED_PORT GPIOC #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_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_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_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_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_PIN GPIO_PIN_5 //Temporary indicator of SPI (or whatever) activity
#define INT_ACTIVE_PORT GPIOB #define INT_ACTIVE_PORT GPIOB
#define INT_ACTIVE_ON INT_ACTIVE_PORT->BSRR = (INT_ACTIVE_PIN << BSRR_SHIFT_HIGH) #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_OFF INT_ACTIVE_PORT->BSRR = (INT_ACTIVE_PIN << BSRR_SHIFT_LOW)
#define SPI1_NSS_PIN GPIO_PIN_4 #define SPI1_NSS_PIN GPIO_PIN_4
#define SPI1_NSS_PORT GPIOA #define SPI1_NSS_PORT GPIOA
#define SPI1_NSS_ASSERT SPI1_NSS_PORT->BSRR = (SPI1_NSS_PIN << BSRR_SHIFT_LOW) #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_DEASSERT SPI1_NSS_PORT->BSRR = (SPI1_NSS_PIN << BSRR_SHIFT_HIGH)
#define DOWNSTREAM_TX_OK_PIN GPIO_PIN_3 #define DOWNSTREAM_TX_OK_PIN GPIO_PIN_3
#define DOWNSTREAM_TX_OK_PORT GPIOA #define DOWNSTREAM_TX_OK_PORT GPIOA
#define DOWNSTREAM_TX_OK_ACTIVE (!(DOWNSTREAM_TX_OK_PORT->IDR & DOWNSTREAM_TX_OK_PIN)) #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_ */ #endif /* INC_BOARD_CONFIG_H_ */

@ -141,7 +141,7 @@
* @brief This is the HAL system configuration section * @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 TICK_INT_PRIORITY ((uint32_t)0) /*!< tick interrupt priority */
#define USE_RTOS 0 #define USE_RTOS 0
#define PREFETCH_ENABLE 1 #define PREFETCH_ENABLE 1

@ -50,10 +50,10 @@
* This parameter can be a value between 0 and 15 * This parameter can be a value between 0 and 15
* A lower priority value indicates a higher priority. */ * A lower priority value indicates a higher priority. */
#define INT_PRIORITY_SYSTICK 2 #define INT_PRIORITY_SYSTICK 2
#define INT_PRIORITY_SPI_DMA 10 //SPI is more important than USB now! #define INT_PRIORITY_SPI_DMA 10 //SPI and USB should be equal, no pre-emption allowed
#define INT_PRIORITY_USB 10 #define INT_PRIORITY_USB 10
#define INT_PRIORITY_EXT3I INT_PRIORITY_USB #define INT_PRIORITY_EXT3I INT_PRIORITY_USB
/* Exported macro ------------------------------------------------------------*/ /* 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 //LEDs are on for BLINK_RATE ticks, then off for BLINK_RATE ticks
#define LED_FAST_BLINK_RATE 100 #define LED_FAST_BLINK_RATE 100
#define LED_SLOW_BLINK_RATE 500 #define LED_SLOW_BLINK_RATE 500

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

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

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

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

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

@ -82,7 +82,7 @@ typedef struct
uint8_t bot_status; uint8_t bot_status;
uint16_t bot_data_length; uint16_t bot_data_length;
uint8_t* bot_data; 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_CBWTypeDef cbw;
USBD_MSC_BOT_CSWTypeDef csw; USBD_MSC_BOT_CSWTypeDef csw;
@ -90,11 +90,11 @@ typedef struct
uint8_t scsi_sense_head; uint8_t scsi_sense_head;
uint8_t scsi_sense_tail; 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] 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_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] 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] uint16_t scsi_blk_len; //TRANSFER LENGTH: Number of contiguous logical blocks of data that shall be read [SBC-4]
} }
USBD_MSC_BOT_HandleTypeDef; USBD_MSC_BOT_HandleTypeDef;

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

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

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

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

@ -69,36 +69,36 @@
/* USB Mass storage Page 0 Inquiry Data */ /* USB Mass storage Page 0 Inquiry Data */
const uint8_t MSC_Page00_Inquiry_Data[] = {//7 const uint8_t MSC_Page00_Inquiry_Data[] = {//7
0x00, 0x00,
0x00, 0x00,
0x00, 0x00,
(LENGTH_INQUIRY_PAGE00 - 4), (LENGTH_INQUIRY_PAGE00 - 4),
0x00, 0x00,
0x80, 0x80,
0x83 0x83
}; };
/* USB Mass storage sense 6 Data */ /* USB Mass storage sense 6 Data */
const uint8_t MSC_Mode_Sense6_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 */ /* USB Mass storage sense 10 Data */
const uint8_t MSC_Mode_Sense10_data[] = { const uint8_t MSC_Mode_Sense10_data[] = {
0x00, 0x00,
0x06, 0x06,
0x00, 0x00,
0x00, 0x00,
0x00, 0x00,
0x00, 0x00,
0x00, 0x00,
0x00 0x00
}; };
/** /**
* @} * @}

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

@ -68,13 +68,13 @@ int8_t STORAGE_GetMaxLun (void);
int8_t STORAGE_Inquirydata[] = {//36 int8_t STORAGE_Inquirydata[] = {//36
/* LUN 0 */ /* LUN 0 */
0x00, 0x00,
0x80, 0x80,
0x02, 0x02,
0x02, 0x02,
(STANDARD_INQUIRY_DATA_LEN - 5), (STANDARD_INQUIRY_DATA_LEN - 5),
0x00, 0x00,
0x00, 0x00,
0x00, 0x00,
'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', /* Manufacturer : 8 bytes */ 'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', /* Manufacturer : 8 bytes */
'P', 'r', 'o', 'd', 'u', 'c', 't', ' ', /* Product : 16 Bytes */ 'P', 'r', 'o', 'd', 'u', 'c', 't', ' ', /* Product : 16 Bytes */

@ -171,7 +171,7 @@ typedef struct _Device_cb
uint8_t (*IsoINIncomplete) (struct _USBD_HandleTypeDef *pdev , uint8_t epnum); uint8_t (*IsoINIncomplete) (struct _USBD_HandleTypeDef *pdev , uint8_t epnum);
uint8_t (*IsoOUTIncomplete) (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 *(*GetHSConfigDescriptor)(uint16_t *length);
uint8_t *(*GetFSConfigDescriptor)(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) USBD_StatusTypeDef USBD_BufferFreed(USBD_HandleTypeDef *pdev)
{ {
pdev->pClass->FreeDataBuffer(pdev); pdev->pClass->FreeDataBuffer(pdev);
return USBD_OK; return USBD_OK;
} }
/** /**
* @} * @}

@ -232,7 +232,7 @@ USBD_StatusTypeDef USBD_StdEPReq (USBD_HandleTypeDef *pdev , USBD_SetupReqTyped
{ {
USBD_LL_StallEP(pdev , ep_addr); USBD_LL_StallEP(pdev , ep_addr);
} }
break; break;
case USBD_STATE_CONFIGURED: case USBD_STATE_CONFIGURED:
if (req->wValue == USB_FEATURE_EP_HALT) if (req->wValue == USB_FEATURE_EP_HALT)
@ -263,7 +263,7 @@ USBD_StatusTypeDef USBD_StdEPReq (USBD_HandleTypeDef *pdev , USBD_SetupReqTyped
{ {
USBD_LL_StallEP(pdev , ep_addr); USBD_LL_StallEP(pdev , ep_addr);
} }
break; break;
case USBD_STATE_CONFIGURED: case USBD_STATE_CONFIGURED:
if (req->wValue == USB_FEATURE_EP_HALT) if (req->wValue == USB_FEATURE_EP_HALT)
@ -291,7 +291,7 @@ USBD_StatusTypeDef USBD_StdEPReq (USBD_HandleTypeDef *pdev , USBD_SetupReqTyped
{ {
USBD_LL_StallEP(pdev , ep_addr); USBD_LL_StallEP(pdev , ep_addr);
} }
break; break;
case USBD_STATE_CONFIGURED: case USBD_STATE_CONFIGURED:
pep = ((ep_addr & 0x80) == 0x80) ? &pdev->ep_in[ep_addr & 0x7F]:\ pep = ((ep_addr & 0x80) == 0x80) ? &pdev->ep_in[ep_addr & 0x7F]:\
@ -506,7 +506,7 @@ static void USBD_SetConfig(USBD_HandleTypeDef *pdev ,
{ {
case USBD_STATE_ADDRESSED: case USBD_STATE_ADDRESSED:
if (cfgidx) if (cfgidx)
{ {
pdev->dev_config = cfgidx; pdev->dev_config = cfgidx;
pdev->dev_state = USBD_STATE_CONFIGURED; pdev->dev_state = USBD_STATE_CONFIGURED;
if(USBD_SetClassConfig(pdev , cfgidx) == USBD_FAIL) if(USBD_SetClassConfig(pdev , cfgidx) == USBD_FAIL)
@ -551,7 +551,7 @@ static void USBD_SetConfig(USBD_HandleTypeDef *pdev ,
} }
break; break;
default: default:
USBD_CtlError(pdev , req); USBD_CtlError(pdev , req);
break; break;
} }

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

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

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

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

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

@ -21,12 +21,12 @@
//Stuff we need to save for our callbacks to use: //Stuff we need to save for our callbacks to use:
UpstreamMSCCallbackTypeDef TestReadyCallback; UpstreamMSCCallbackTypeDef TestReadyCallback;
UpstreamMSCCallbackUintPacketTypeDef GetCapacityCallback; UpstreamMSCCallbackUintPacketTypeDef GetCapacityCallback;
UpstreamMSCCallbackPacketTypeDef GetStreamDataCallback; UpstreamMSCCallbackPacketTypeDef GetStreamDataCallback;
uint32_t ByteCount; uint32_t ByteCount;
UpstreamPacketTypeDef* ReadStreamPacket; UpstreamPacketTypeDef* ReadStreamPacket;
uint8_t ReadStreamBusy; uint8_t ReadStreamBusy;
static void Upstream_MSC_TestReadyReplyCallback(UpstreamPacketTypeDef* replyPacket); 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) HAL_StatusTypeDef Upstream_MSC_TestReady(UpstreamMSCCallbackTypeDef callback)
{ {
UpstreamPacketTypeDef* freePacket; UpstreamPacketTypeDef* freePacket;
HAL_StatusTypeDef tempResult; HAL_StatusTypeDef tempResult;
TestReadyCallback = callback; TestReadyCallback = callback;
freePacket = Upstream_GetFreePacketImmediately(); freePacket = Upstream_GetFreePacketImmediately();
freePacket->Length = UPSTREAM_PACKET_HEADER_LEN; freePacket->Length = UPSTREAM_PACKET_HEADER_LEN;
freePacket->CommandClass = COMMAND_CLASS_MASS_STORAGE; freePacket->CommandClass = COMMAND_CLASS_MASS_STORAGE;
freePacket->Command = COMMAND_MSC_TEST_UNIT_READY; freePacket->Command = COMMAND_MSC_TEST_UNIT_READY;
tempResult = Upstream_TransmitPacket(freePacket); tempResult = Upstream_TransmitPacket(freePacket);
if (tempResult != HAL_OK) if (tempResult != HAL_OK)
{ {
return tempResult; return tempResult;
} }
//return Upstream_GetPacket(Upstream_MSC_TestReadyReplyCallback); //return Upstream_GetPacket(Upstream_MSC_TestReadyReplyCallback);
return Upstream_GetFreePacket(Upstream_MSC_TestReadyReplyCallback); return Upstream_GetFreePacket(Upstream_MSC_TestReadyReplyCallback);
} }
void Upstream_MSC_TestReadyReplyCallback(UpstreamPacketTypeDef* replyPacket) void Upstream_MSC_TestReadyReplyCallback(UpstreamPacketTypeDef* replyPacket)
{ {
// if ((replyPacket->Length != (UPSTREAM_PACKET_HEADER_LEN + 1)) || // if ((replyPacket->Length != (UPSTREAM_PACKET_HEADER_LEN + 1)) ||
// (replyPacket->CommandClass & COMMAND_CLASS_DATA_FLAG) || // (replyPacket->CommandClass & COMMAND_CLASS_DATA_FLAG) ||
// (replyPacket->Data[0] != HAL_OK)) // (replyPacket->Data[0] != HAL_OK))
// { // {
// Upstream_ReleasePacket(replyPacket); // Upstream_ReleasePacket(replyPacket);
// TestReadyCallback(HAL_ERROR); // TestReadyCallback(HAL_ERROR);
// return; // return;
// } // }
Upstream_ReleasePacket(replyPacket); Upstream_ReleasePacket(replyPacket);
TestReadyCallback(HAL_OK); TestReadyCallback(HAL_OK);
} }
HAL_StatusTypeDef Upstream_MSC_GetCapacity(UpstreamMSCCallbackUintPacketTypeDef callback) HAL_StatusTypeDef Upstream_MSC_GetCapacity(UpstreamMSCCallbackUintPacketTypeDef callback)
{ {
UpstreamPacketTypeDef* freePacket; UpstreamPacketTypeDef* freePacket;
HAL_StatusTypeDef tempResult; HAL_StatusTypeDef tempResult;
GetCapacityCallback = callback; GetCapacityCallback = callback;
freePacket = Upstream_GetFreePacketImmediately(); freePacket = Upstream_GetFreePacketImmediately();
freePacket->Length = UPSTREAM_PACKET_HEADER_LEN; freePacket->Length = UPSTREAM_PACKET_HEADER_LEN;
freePacket->CommandClass = COMMAND_CLASS_MASS_STORAGE; freePacket->CommandClass = COMMAND_CLASS_MASS_STORAGE;
freePacket->Command = COMMAND_MSC_GET_CAPACITY; freePacket->Command = COMMAND_MSC_GET_CAPACITY;
tempResult = Upstream_TransmitPacket(freePacket); tempResult = Upstream_TransmitPacket(freePacket);
if (tempResult != HAL_OK) if (tempResult != HAL_OK)
{ {
return tempResult; return tempResult;
} }
//return Upstream_GetPacket(Upstream_MSC_GetCapacityReplyCallback); //return Upstream_GetPacket(Upstream_MSC_GetCapacityReplyCallback);
return Upstream_GetFreePacket(Upstream_MSC_GetCapacityReplyCallback); return Upstream_GetFreePacket(Upstream_MSC_GetCapacityReplyCallback);
} }
void Upstream_MSC_GetCapacityReplyCallback(UpstreamPacketTypeDef* replyPacket) void Upstream_MSC_GetCapacityReplyCallback(UpstreamPacketTypeDef* replyPacket)
{ {
uint32_t uint[2]; uint32_t uint[2];
// if ((replyPacket->Length != (UPSTREAM_PACKET_HEADER_LEN + 8) || // if ((replyPacket->Length != (UPSTREAM_PACKET_HEADER_LEN + 8) ||
// (replyPacket->CommandClass & COMMAND_CLASS_DATA_FLAG))) // (replyPacket->CommandClass & COMMAND_CLASS_DATA_FLAG)))
// { // {
// GetCapacityCallback(HAL_ERROR, NULL, NULL); // GetCapacityCallback(HAL_ERROR, NULL, NULL);
// } // }
*(uint32_t*)&(replyPacket->Data[0]) = 262144; //* 512B = 128MB *(uint32_t*)&(replyPacket->Data[0]) = 262144; //* 512B = 128MB
*(uint32_t*)&(replyPacket->Data[4]) = 512; *(uint32_t*)&(replyPacket->Data[4]) = 512;
uint[0] = *(uint32_t*)&(replyPacket->Data[0]); uint[0] = *(uint32_t*)&(replyPacket->Data[0]);
uint[1] = *(uint32_t*)&(replyPacket->Data[4]); uint[1] = *(uint32_t*)&(replyPacket->Data[4]);
GetCapacityCallback(HAL_OK, uint, replyPacket); //usb_msc_scsi will use this packet, so don't release now GetCapacityCallback(HAL_OK, uint, replyPacket); //usb_msc_scsi will use this packet, so don't release now
} }
HAL_StatusTypeDef Upstream_MSC_BeginRead(UpstreamMSCCallbackTypeDef callback, HAL_StatusTypeDef Upstream_MSC_BeginRead(UpstreamMSCCallbackTypeDef callback,
uint64_t readBlockStart, uint64_t readBlockStart,
uint32_t readBlockCount, uint32_t readBlockCount,
uint32_t readByteCount) uint32_t readByteCount)
{ {
UpstreamPacketTypeDef* freePacket; UpstreamPacketTypeDef* freePacket;
HAL_StatusTypeDef tempResult; HAL_StatusTypeDef tempResult;
ReadStreamPacket = NULL; //Prepare for GetStreamDataPacket's use ReadStreamPacket = NULL; //Prepare for GetStreamDataPacket's use
ReadStreamBusy = 0; ReadStreamBusy = 0;
TestReadyCallback = callback; TestReadyCallback = callback;
ByteCount = readByteCount; ByteCount = readByteCount;
freePacket = Upstream_GetFreePacketImmediately(); freePacket = Upstream_GetFreePacketImmediately();
freePacket->Length = UPSTREAM_PACKET_HEADER_LEN + (4 * 3); freePacket->Length = UPSTREAM_PACKET_HEADER_LEN + (4 * 3);
freePacket->CommandClass = COMMAND_CLASS_MASS_STORAGE; freePacket->CommandClass = COMMAND_CLASS_MASS_STORAGE;
freePacket->Command = COMMAND_MSC_BEGIN_READ; freePacket->Command = COMMAND_MSC_BEGIN_READ;
*(uint64_t*)&(freePacket->Data[0]) = readBlockStart; *(uint64_t*)&(freePacket->Data[0]) = readBlockStart;
*(uint32_t*)&(freePacket->Data[8]) = readBlockCount; *(uint32_t*)&(freePacket->Data[8]) = readBlockCount;
tempResult = Upstream_TransmitPacket(freePacket); tempResult = Upstream_TransmitPacket(freePacket);
if (tempResult != HAL_OK) if (tempResult != HAL_OK)
{ {
TestReadyCallback(tempResult); TestReadyCallback(tempResult);
} }
//return Upstream_GetPacket(Upstream_MSC_TestReadyReplyCallback); //Re-use TestReadyReplyCallback because it does exactly what we want! //return Upstream_GetPacket(Upstream_MSC_TestReadyReplyCallback); //Re-use TestReadyReplyCallback because it does exactly what we want!
return Upstream_GetFreePacket(Upstream_MSC_TestReadyReplyCallback); return Upstream_GetFreePacket(Upstream_MSC_TestReadyReplyCallback);
} }
HAL_StatusTypeDef Upstream_MSC_GetStreamDataPacket(UpstreamMSCCallbackPacketTypeDef callback) HAL_StatusTypeDef Upstream_MSC_GetStreamDataPacket(UpstreamMSCCallbackPacketTypeDef callback)
{ {
GetStreamDataCallback = callback; GetStreamDataCallback = callback;
if (ReadStreamBusy != 0) if (ReadStreamBusy != 0)
{ {
return HAL_OK; return HAL_OK;
} }
ReadStreamBusy = 1; ReadStreamBusy = 1;
if (ReadStreamPacket && GetStreamDataCallback) //Do we have a stored packet and an address to send it? if (ReadStreamPacket && GetStreamDataCallback) //Do we have a stored packet and an address to send it?
{ {
Upstream_MSC_GetStreamDataPacketCallback(ReadStreamPacket); //Send it now! Upstream_MSC_GetStreamDataPacketCallback(ReadStreamPacket); //Send it now!
ReadStreamPacket = NULL; ReadStreamPacket = NULL;
return HAL_OK; //Our callback will call us again, so we don't need to get a packet in this case. 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_GetPacket(Upstream_MSC_GetStreamDataPacketCallback);
return Upstream_GetFreePacket(Upstream_MSC_GetStreamDataPacketCallback); return Upstream_GetFreePacket(Upstream_MSC_GetStreamDataPacketCallback);
} }
void Upstream_MSC_GetStreamDataPacketCallback(UpstreamPacketTypeDef* replyPacket) void Upstream_MSC_GetStreamDataPacketCallback(UpstreamPacketTypeDef* replyPacket)
{ {
uint16_t dataLength; uint16_t dataLength;
ReadStreamBusy = 0; ReadStreamBusy = 0;
if (GetStreamDataCallback == NULL) if (GetStreamDataCallback == NULL)
{ {
ReadStreamPacket = replyPacket; //We used up our callback already, so save this one for later. ReadStreamPacket = replyPacket; //We used up our callback already, so save this one for later.
return; return;
} }
// if (((replyPacket->CommandClass & COMMAND_CLASS_DATA_FLAG) == 0) || //Any 'command' reply (as opposed to 'data' reply) is an automatic fail here // if (((replyPacket->CommandClass & COMMAND_CLASS_DATA_FLAG) == 0) || //Any 'command' reply (as opposed to 'data' reply) is an automatic fail here
// (replyPacket->Length <= UPSTREAM_PACKET_HEADER_LEN) || //Should be at least one data byte in the reply. // (replyPacket->Length <= UPSTREAM_PACKET_HEADER_LEN) || //Should be at least one data byte in the reply.
// (replyPacket->Length > ByteCount)) // (replyPacket->Length > ByteCount))
// { // {
// GetStreamDataCallback(HAL_ERROR, NULL); // GetStreamDataCallback(HAL_ERROR, NULL);
// return; // return;
// } // }
replyPacket->Length = MIN((ByteCount + UPSTREAM_PACKET_HEADER_LEN), (MSC_MEDIA_PACKET + UPSTREAM_PACKET_HEADER_LEN)); replyPacket->Length = MIN((ByteCount + UPSTREAM_PACKET_HEADER_LEN), (MSC_MEDIA_PACKET + UPSTREAM_PACKET_HEADER_LEN));
dataLength = replyPacket->Length - UPSTREAM_PACKET_HEADER_LEN; dataLength = replyPacket->Length - UPSTREAM_PACKET_HEADER_LEN;
ByteCount -= dataLength; ByteCount -= dataLength;
GetStreamDataCallback(HAL_OK, replyPacket, dataLength); //usb_msc_scsi will use this packet, so don't release now GetStreamDataCallback(HAL_OK, replyPacket, dataLength); //usb_msc_scsi will use this packet, so don't release now
if (ByteCount > 0) if (ByteCount > 0)
{ {
Upstream_MSC_GetStreamDataPacket(NULL); //Try to get the next packet now, before USB asks for it Upstream_MSC_GetStreamDataPacket(NULL); //Try to get the next packet now, before USB asks for it
} }
} }
HAL_StatusTypeDef Upstream_MSC_BeginWrite(UpstreamMSCCallbackTypeDef callback, HAL_StatusTypeDef Upstream_MSC_BeginWrite(UpstreamMSCCallbackTypeDef callback,
uint64_t readBlockStart, uint64_t readBlockStart,
uint32_t readBlockCount) uint32_t readBlockCount)
{ {
UpstreamPacketTypeDef* freePacket; UpstreamPacketTypeDef* freePacket;
HAL_StatusTypeDef tempResult; HAL_StatusTypeDef tempResult;
TestReadyCallback = callback; TestReadyCallback = callback;
freePacket = Upstream_GetFreePacketImmediately(); freePacket = Upstream_GetFreePacketImmediately();
freePacket->Length = UPSTREAM_PACKET_HEADER_LEN + (4 * 3); freePacket->Length = UPSTREAM_PACKET_HEADER_LEN + (4 * 3);
freePacket->CommandClass = COMMAND_CLASS_MASS_STORAGE; freePacket->CommandClass = COMMAND_CLASS_MASS_STORAGE;
freePacket->Command = COMMAND_MSC_BEGIN_WRITE; freePacket->Command = COMMAND_MSC_BEGIN_WRITE;
*(uint64_t*)&(freePacket->Data[0]) = readBlockStart; *(uint64_t*)&(freePacket->Data[0]) = readBlockStart;
*(uint32_t*)&(freePacket->Data[8]) = readBlockCount; *(uint32_t*)&(freePacket->Data[8]) = readBlockCount;
tempResult = Upstream_TransmitPacket(freePacket); tempResult = Upstream_TransmitPacket(freePacket);
if (tempResult != HAL_OK) if (tempResult != HAL_OK)
{ {
TestReadyCallback(tempResult); TestReadyCallback(tempResult);
} }
//return Upstream_GetPacket(Upstream_MSC_BeginWriteReplyCallback); //return Upstream_GetPacket(Upstream_MSC_BeginWriteReplyCallback);
return Upstream_GetFreePacket(Upstream_MSC_BeginWriteReplyCallback); return Upstream_GetFreePacket(Upstream_MSC_BeginWriteReplyCallback);
} }
void Upstream_MSC_BeginWriteReplyCallback(UpstreamPacketTypeDef* replyPacket) void Upstream_MSC_BeginWriteReplyCallback(UpstreamPacketTypeDef* replyPacket)
{ {
// if ((replyPacket->Length != (UPSTREAM_PACKET_HEADER_LEN + 1)) || // if ((replyPacket->Length != (UPSTREAM_PACKET_HEADER_LEN + 1)) ||
// (replyPacket->CommandClass & COMMAND_CLASS_DATA_FLAG) || // (replyPacket->CommandClass & COMMAND_CLASS_DATA_FLAG) ||
// ((replyPacket->Data[0] != HAL_OK) && (replyPacket->Data[0] != HAL_BUSY))) // ((replyPacket->Data[0] != HAL_OK) && (replyPacket->Data[0] != HAL_BUSY)))
// { // {
// Upstream_ReleasePacket(replyPacket); // Upstream_ReleasePacket(replyPacket);
// TestReadyCallback(HAL_ERROR); // TestReadyCallback(HAL_ERROR);
// return; // return;
// } // }
Upstream_ReleasePacket(replyPacket); Upstream_ReleasePacket(replyPacket);
TestReadyCallback(replyPacket->Data[0]); TestReadyCallback(replyPacket->Data[0]);
} }
HAL_StatusTypeDef Upstream_MSC_PutStreamDataPacket(UpstreamPacketTypeDef* packetToSend, HAL_StatusTypeDef Upstream_MSC_PutStreamDataPacket(UpstreamPacketTypeDef* packetToSend,
uint32_t dataLength) uint32_t dataLength)
{ {
packetToSend->Length = dataLength + UPSTREAM_PACKET_HEADER_LEN; packetToSend->Length = dataLength + UPSTREAM_PACKET_HEADER_LEN;
packetToSend->CommandClass = COMMAND_CLASS_MASS_STORAGE | COMMAND_CLASS_DATA_FLAG; packetToSend->CommandClass = COMMAND_CLASS_MASS_STORAGE | COMMAND_CLASS_DATA_FLAG;
packetToSend->Command = COMMAND_MSC_BEGIN_WRITE; packetToSend->Command = COMMAND_MSC_BEGIN_WRITE;
return Upstream_TransmitPacket(packetToSend); return Upstream_TransmitPacket(packetToSend);
} }

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

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

@ -47,7 +47,7 @@ USBD_HandleTypeDef hUsbDeviceFS;
void USB_Device_Init(void) 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_RegisterClass(&hUsbDeviceFS, &USBD_MSC);
// USBD_Start(&hUsbDeviceFS); // USBD_Start(&hUsbDeviceFS);

@ -172,7 +172,7 @@ void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
case PCD_SPEED_FULL: case PCD_SPEED_FULL:
speed = USBD_SPEED_FULL; speed = USBD_SPEED_FULL;
break; break;
default: default:
speed = USBD_SPEED_FULL; speed = USBD_SPEED_FULL;
break; break;
@ -267,7 +267,7 @@ void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
void HAL_PCD_BufferFreedCallBack(PCD_HandleTypeDef *hpcd) void HAL_PCD_BufferFreedCallBack(PCD_HandleTypeDef *hpcd)
{ {
USBD_BufferFreed(hpcd->pData); USBD_BufferFreed(hpcd->pData);
} }
/******************************************************************************* /*******************************************************************************
@ -282,7 +282,7 @@ USBD_StatusTypeDef USBD_LL_Init (USBD_HandleTypeDef *pdev)
{ {
/* Init USB_IP */ /* Init USB_IP */
if (pdev->id == DEVICE_FS) { if (pdev->id == DEVICE_FS) {
/* Link The driver to the stack */ /* Link The driver to the stack */
hpcd_USB_OTG_FS.pData = pdev; hpcd_USB_OTG_FS.pData = pdev;
pdev->pData = &hpcd_USB_OTG_FS; pdev->pData = &hpcd_USB_OTG_FS;

Loading…
Cancel
Save