📄 msd.c
字号:
* Input: None
*
* Output: None
*
* Side Effects: None
*
* Overview: Decodes the CBWCB of READ(10) command to calculate
* the starting LBA and the Transfer length
* (number of blocks to be read). Reads a block of 512B data
* from SD Card in msd_buffer (by calling SectorRead).
* If successfully read (sdcValid), the data is sent to the
* host in 64B chunks (MSD_IN_EP_SIZE) (see MSDDataIn()).
* This is repeated for TransferLength number of blocks.
* In case of error bCSWStatus is set to 0x01 and sense data
* with sense key NOT READY and appropriate ASC,
* ASCQ codes is prepared.
*
* Note: None
*****************************************************************************/
void MSDReadHandler()
{
word i;
SDC_Error status;
WORD TransferLength;
DWORD LBA;
byte Flags;
dword sectorNumber;
LBA.v[3]=gblCBW.CBWCB[2];
LBA.v[2]=gblCBW.CBWCB[3];
LBA.v[1]=gblCBW.CBWCB[4];
LBA.v[0]=gblCBW.CBWCB[5];
TransferLength.v[1]=gblCBW.CBWCB[7];
TransferLength.v[0]=gblCBW.CBWCB[8];
Flags=gblCBW.CBWCB[1];
msd_csw.bCSWStatus=0x0;
msd_csw.dCSWDataResidue=0x0;
if (LBA._dword + TransferLength._word > gblNumBLKS._dword) {
msd_csw.bCSWStatus=0x01;
// prepare sense data See page 51 SBC-2
gblSenseData.SenseKey=S_ILLEGAL_REQUEST;
gblSenseData.ASC=ASC_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
gblSenseData.ASCQ=ASCQ_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
} else {
while (TransferLength._word > 0) {
TransferLength._word--; // we have read 1 LBA
status = SectorRead(LBA._dword, (byte*)&msd_buffer[0]);
LBA._dword++; // read the next LBA
if (status==sdcValid) {
msd_csw.bCSWStatus=0x00; // success
msd_csw.dCSWDataResidue=BLOCKLEN_512;//in order to send the
//512 bytes of data read
ptrNextData=(byte *)&msd_buffer[0];
while (msd_csw.dCSWDataResidue>0)
MSDDataIn(); // send the data
msd_csw.dCSWDataResidue=0x0; // for next time
} else {
msd_csw.bCSWStatus=0x01; // Error 0x01 Refer page#18
// of BOT specifications
/* Don't read any more data*/
msd_csw.dCSWDataResidue=0x0;
break; // break the loop
}
}
}
}
/******************************************************************************
* Function: void MSDDataOut(void)
*
* PreCondition: None
*
* Input: None
*
* Output: None
*
* Side Effects: MSD_BD_OUT.ADR is incremented by MSD_OUT_EP_SIZE
* (to read next 64B into msd_buffer)
*
* Overview: This function reads 64B (MSD_OUT_EP_SIZE)
* from EP1 OUT MSD_BD_OUT
* Note: None
*****************************************************************************/
void MSDDataOut(void)
{
mUSBBufferReady(MSD_BD_OUT);
USBDriverService();
while(mMSDRxIsBusy());
gblCBW.dCBWDataTransferLength-=MSD_BD_OUT.Cnt; // 64B read
msd_csw.dCSWDataResidue-=MSD_BD_OUT.Cnt;
MSD_BD_OUT.Cnt=MSD_OUT_EP_SIZE;
MSD_BD_OUT.ADR+=MSD_OUT_EP_SIZE;
}
/******************************************************************************
* Function: void MSDWriteHandler()
*
* PreCondition: None
*
* Input: None
*
* Output: None
*
* Side Effects: None
*
* Overview: Decodes the CBWCB of WRITE(10) command to calculate
* the starting LBA and theTransfer length (number of
* blocks to be written). Reads TransferLength blocks
* of data, 1 block=512B at a time in msd_buffer.
* The data from the host, 64B in MSD_BD_OUT, is received
* in the msd_buffer (see MSDDataOut()).
* The MSD_BD_OUT.ADR pointer is manipulated to fill the 512B
* msd_buffer and when full the data is written to the SD Card
* by calling the function SectorWrite(...) (see sdcard.c)
* In case of error bCSWStatus is set to 0x01 and sense
* data with sense key NOT READY and appropriate ASC,
* ASCQ codes is prepared.
*
* Note: None
*****************************************************************************/
void MSDWriteHandler()
{
word i;
byte* adr;
SDC_Error status=sdcValid;
WORD TransferLength;
DWORD LBA;
byte Flags;
dword sectorNumber;
/* Read the LBA, TransferLength fields from Command Block
NOTE: CB is Big-Endian */
LBA.v[3]=gblCBW.CBWCB[2];
LBA.v[2]=gblCBW.CBWCB[3];
LBA.v[1]=gblCBW.CBWCB[4];
LBA.v[0]=gblCBW.CBWCB[5];
TransferLength.v[1]=gblCBW.CBWCB[7];
TransferLength.v[0]=gblCBW.CBWCB[8];
msd_csw.bCSWStatus=0x0;
while (TransferLength._word > 0) {
msd_csw.dCSWDataResidue=BLOCKLEN_512;
/* Read 512B into msd_buffer*/
while (msd_csw.dCSWDataResidue>0)
MSDDataOut();
if(IsWriteProtected()) {
gblSenseData.SenseKey=S_NOT_READY;
gblSenseData.ASC=ASC_WRITE_PROTECTED;
gblSenseData.ASCQ=ASCQ_WRITE_PROTECTED;
msd_csw.bCSWStatus=0x01;
} else {
status = SectorWrite((LBA._dword), (byte*)&msd_buffer[0]);
}
if (status) {
msd_csw.bCSWStatus=0x01;
/* add some sense keys here*/
}
LBA._dword++; // One LBA is written. Write the next LBA
TransferLength._word--;
/* Point MSD_BD_OUT to msd_cbw after
done reading the WRITE data from host*/
if (TransferLength._word>0){
MSD_BD_OUT.Cnt=MSD_OUT_EP_SIZE;
MSD_BD_OUT.ADR=(byte*)&msd_buffer[0];
} else {
MSD_BD_OUT.Cnt=sizeof(msd_cbw);
MSD_BD_OUT.ADR=(byte*)&msd_cbw;
}
} // end of while
return;
}
/******************************************************************************
* Function: void MSDRequestSenseHandler(void)
*
* PreCondition: None
*
* Input: None
*
* Output: None
*
* Side Effects: None
*
* Overview: This function prepares the Sense Data in response
* to the Request Sense Command The contents of structure
* RequestSenseResponse are copied to msd_buffer and a
* success bCSWStatus=0x00 is set.
*
* Note: None
*****************************************************************************/
void MSDRequestSenseHandler(void)
{
byte i;
for(i=0;i<sizeof(RequestSenseResponse);i++)
msd_buffer[i]=gblSenseData._byte[i];
msd_csw.dCSWDataResidue=sizeof(RequestSenseResponse);
msd_csw.bCSWStatus=0x0; // success
return;
}
/******************************************************************************
* Function: void MSDModeSenseHandler()
*
* PreCondition: None
*
* Input: None
*
* Output: None
*
* Side Effects: None
*
* Overview: This function prepares response to the Mode Sense command
* a basic response is implemented in this version of the code
* 00h imples no other mode pages and 0x03 is the size of the
* data (in bytes) that follows.
*
* Note: None
*****************************************************************************/
void MSDModeSenseHandler()
{
msd_buffer[0]=0x03;
msd_buffer[1]=0x00;
msd_buffer[2]=0x00;
msd_buffer[3]=0x00;
msd_csw.bCSWStatus=0x0;
msd_csw.dCSWDataResidue=0x04;
return;
}
/******************************************************************************
* Function: void MSDMediumRemovalHandler()
*
* PreCondition: None
*
* Input: None
*
* Output: None
*
* Side Effects: None
*
* Overview: This function prepares response to Prevent Allow
* Medium Removal Command No data response is expect only
* a CSW with command execution status is expected
* Since we cannot control the removal of media,
* we respond by a Success CSW
* Note: None
*****************************************************************************/
void MSDMediumRemovalHandler()
{
if(DetectSDCard()) {
msd_csw.bCSWStatus=0x00;
msd_csw.dCSWDataResidue=0x00;
} else {
gblSenseData.SenseKey=S_NOT_READY;
gblSenseData.ASC=ASC_MEDIUM_NOT_PRESENT;
gblSenseData.ASCQ=ASCQ_MEDIUM_NOT_PRESENT;
msd_csw.bCSWStatus=0x01;
}
return;
}
/******************************************************************************
* Function: void MSDTestUnitReadyHandler()
*
* PreCondition: None
*
* Input: None
*
* Output: None
*
* Side Effects: None
*
* Overview: This function prepares response to Test Unit Ready Command
* No data response is expected, only a CSW is to be sent
* Based on the current state of the SDCard an error or
* success status value is set
*
* Note: None
*****************************************************************************/
void MSDTestUnitReadyHandler()
{
msd_csw.bCSWStatus=0x0;
ResetSenseData();
/*
if(!gblFlag.isSDMMC) {
gblSenseData.SenseKey=S_NOT_READY;
gblSenseData.ASC=ASC_LOGICAL_UNIT_NOT_SUPPORTED;
gblSenseData.ASCQ=ASC_LOGICAL_UNIT_NOT_SUPPORTED;
msd_csw.bCSWStatus=0x01;
mLED_2_On();
}
*/
if(!DetectSDCard()) {
gblSenseData.SenseKey=S_UNIT_ATTENTION;
gblSenseData.ASC=ASC_MEDIUM_NOT_PRESENT;
gblSenseData.ASCQ=ASCQ_MEDIUM_NOT_PRESENT;
msd_csw.bCSWStatus=0x01;
gblFlag.isSDMMC=0;
} else {
ToggleRUNLED();
}
//}
msd_csw.dCSWDataResidue=0x00;
//SendCSW();
return;
}
/******************************************************************************
* Function: void MSDVerifyHandler()
*
* PreCondition: None
*
* Input: None
*
* Output: None
*
* Side Effects: None
*
* Overview: This function prepares response to Verify Command
* No data response is expected, we reply by a success CSW
* The command is not being processed in this version of code
*
* Note: None
*****************************************************************************/
void MSDVerifyHandler()
{
msd_csw.bCSWStatus=0x0;
msd_csw.dCSWDataResidue=0x00;
return;
}
/******************************************************************************
* Function: void MSDStopStartHandler()
*
* PreCondition: None
*
* Input: None
*
* Output: None
*
* Side Effects: None
*
* Overview: This function prepares response to Start Stop Unit Command
* No data response is expected, we reply by a success CSW
* The command is not being processed in this version of code
*
* Note: None
*****************************************************************************/
void MSDStopStartHandler()
{
msd_csw.bCSWStatus=0x0;
msd_csw.dCSWDataResidue=0x00;
return;
}
#endif //def USB_USE_MSD
/** EOF msd.c ***************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -