📄 usbhost_ms.c
字号:
Fill_MSCommand(0, 0, 0, MS_DATA_DIR_NONE, SCSI_CMD_TEST_UNIT_READY, 6);
rc = Host_ProcessTD(EDBulkOut, TD_OUT, TDBuffer, CBW_SIZE);
if (rc == OK) {
rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, CSW_SIZE);
if (rc == OK) {
if (TDBuffer[12] != 0) {
rc = ERR_MS_CMD_FAILED;
}
}
}
return (rc);
}
/*
**************************************************************************************************************
* READ CAPACITY
*
* Description: This function is used to read the capacity of the mass storage device
*
* Arguments : None
*
* Returns : OK if Success
* ERROR if Failed
*
**************************************************************************************************************
*/
int32_t MS_ReadCapacity (uint32_t *numBlks, uint32_t *blkSize)
{
int32_t rc;
Fill_MSCommand(0, 0, 0, MS_DATA_DIR_IN, SCSI_CMD_READ_CAPACITY, 10);
rc = Host_ProcessTD(EDBulkOut, TD_OUT, TDBuffer, CBW_SIZE);
if (rc == OK) {
rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, 8);
if (rc == OK) {
if (numBlks)
*numBlks = ReadBE32U(&TDBuffer[0]);
if (blkSize)
*blkSize = ReadBE32U(&TDBuffer[4]);
rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, CSW_SIZE);
if (rc == OK) {
if (TDBuffer[12] != 0) {
rc = ERR_MS_CMD_FAILED;
}
}
}
}
return (rc);
}
int32_t MS_Inquire (uint8_t *response)
{
int32_t rc;
uint32_t i;
Fill_MSCommand(0, 0, 0, MS_DATA_DIR_IN, SCSI_CMD_INQUIRY, 6);
rc = Host_ProcessTD(EDBulkOut, TD_OUT, TDBuffer, CBW_SIZE);
if (rc == OK) {
rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, INQUIRY_LENGTH);
if (rc == OK) {
if (response) {
for ( i = 0; i < INQUIRY_LENGTH; i++ )
*response++ = *TDBuffer++;
#if 0
MemCpy (response, TDBuffer, INQUIRY_LENGTH);
StrNullTrailingSpace (response->vendorID, SCSI_INQUIRY_VENDORCHARS);
StrNullTrailingSpace (response->productID, SCSI_INQUIRY_PRODUCTCHARS);
StrNullTrailingSpace (response->productRev, SCSI_INQUIRY_REVCHARS);
#endif
}
rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, CSW_SIZE);
if (rc == OK) {
if (TDBuffer[12] != 0) { // bCSWStatus byte
rc = ERR_MS_CMD_FAILED;
}
}
}
}
return (rc);
}
/*
**************************************************************************************************************
* RECEIVE THE BULK DATA
*
* Description: This function is used to receive the bulk data
*
* Arguments : None
*
* Returns : OK if Success
* ERR_INVALID_BOOTSIG if Failed
*
**************************************************************************************************************
*/
int32_t MS_BulkRecv ( uint32_t block_number,
uint16_t num_blocks,
volatile uint8_t *user_buffer)
{
int32_t rc;
int i;
volatile uint8_t *c = user_buffer;
for (i=0;i<MS_BlkSize*num_blocks;i++)
*c++ = 0;
Fill_MSCommand(block_number, MS_BlkSize, num_blocks, MS_DATA_DIR_IN, SCSI_CMD_READ_10, 10);
rc = Host_ProcessTD(EDBulkOut, TD_OUT, TDBuffer, CBW_SIZE);
if (rc == OK) {
rc = Host_ProcessTD(EDBulkIn, TD_IN, user_buffer, MS_BlkSize * num_blocks);
if (rc == OK) {
rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, CSW_SIZE);
if (rc == OK) {
if (TDBuffer[12] != 0) {
rc = ERR_MS_CMD_FAILED;
}
}
}
}
return (rc);
}
/*
**************************************************************************************************************
* SEND BULK DATA
*
* Description: This function is used to send the bulk data
*
* Arguments : None
*
* Returns : OK if Success
* ERR_INVALID_BOOTSIG if Failed
*
**************************************************************************************************************
*/
int32_t MS_BulkSend ( uint32_t block_number,
uint16_t num_blocks,
volatile uint8_t *user_buffer)
{
int32_t rc;
Fill_MSCommand(block_number, MS_BlkSize, num_blocks, MS_DATA_DIR_OUT, SCSI_CMD_WRITE_10, 10);
rc = Host_ProcessTD(EDBulkOut, TD_OUT, TDBuffer, CBW_SIZE);
if (rc == OK) {
rc = Host_ProcessTD(EDBulkOut, TD_OUT, user_buffer, MS_BlkSize * num_blocks);
if (rc == OK) {
rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, CSW_SIZE);
if (rc == OK) {
if (TDBuffer[12] != 0) {
rc = ERR_MS_CMD_FAILED;
}
}
}
}
return (rc);
}
/*
**************************************************************************************************************
* FILL MASS STORAGE COMMAND
*
* Description: This function is used to fill the mass storage command
*
* Arguments : None
*
* Returns : OK if Success
* ERR_INVALID_BOOTSIG if Failed
*
**************************************************************************************************************
*/
void Fill_MSCommand (uint32_t block_number,
uint32_t block_size,
uint16_t num_blocks,
MS_DATA_DIR direction,
uint8_t scsi_cmd,
uint8_t scsi_cmd_len)
{
uint32_t data_len;
static uint32_t tag_cnt = 0;
uint32_t cnt;
for (cnt = 0; cnt < CBW_SIZE; cnt++) {
TDBuffer[cnt] = 0;
}
switch(scsi_cmd) {
case SCSI_CMD_TEST_UNIT_READY:
data_len = 0;
break;
case SCSI_CMD_READ_CAPACITY:
data_len = 8;
break;
case SCSI_CMD_REQUEST_SENSE:
data_len = 18;
break;
case SCSI_CMD_INQUIRY:
data_len = 36;
break;
default:
data_len = block_size * num_blocks;
break;
}
WriteLE32U(TDBuffer, CBW_SIGNATURE);
WriteLE32U(&TDBuffer[4], tag_cnt);
WriteLE32U(&TDBuffer[8], data_len);
TDBuffer[12] = (direction == MS_DATA_DIR_NONE) ? 0 : direction;
TDBuffer[14] = scsi_cmd_len; /* Length of the CBW */
TDBuffer[15] = scsi_cmd;
if ((scsi_cmd == SCSI_CMD_REQUEST_SENSE)
|| (scsi_cmd == SCSI_CMD_INQUIRY)) {
TDBuffer[19] = (uint8_t)data_len;
} else {
WriteBE32U(&TDBuffer[17], block_number);
}
WriteBE16U(&TDBuffer[22], num_blocks);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -