📄 msdnotworking.c
字号:
memcpypgm2ram((byte *)&msd_buffer[0],(byte *)&inq_resp,sizeof(InquiryResponse));
msd_csw.dCSWDataResidue=sizeof(InquiryResponse);
msd_csw.bCSWStatus=0x00; // success
return;
}
void ResetSenseData(void) {
gblSenseData.ResponseCode=S_CURRENT;
gblSenseData.VALID=0; // no data in the information field
gblSenseData.Obsolete=0x0;
gblSenseData.SenseKey=S_NO_SENSE;
gblSenseData.Resv;
gblSenseData.ILI=0;
gblSenseData.EOM=0;
gblSenseData.FILEMARK=0;
gblSenseData.Information._dword=0x00;
gblSenseData.AddSenseLen=0x0a; // n-7 (n=17 (0..17))
gblSenseData.CmdSpecificInfo._dword=0x0;
gblSenseData.ASC=0x0;
gblSenseData.ASCQ=0x0;
gblSenseData.FRUC=0x0;
gblSenseData.SenseKeySpecific[0]=0x0;
gblSenseData.SenseKeySpecific[1]=0x0;
gblSenseData.SenseKeySpecific[2]=0x0;
}
/*
void MSDReadFormatCapacityHandler(void)
{
// ep1Bo.Stat._byte = _USIE|_BSTALL;
// check if owner is _CPU
// ep1Bi.Stat._byte = _USIE|_BSTALL;
// UEP1bits.EPSTALL=1;
ResetSenseData();
gblSenseData.SenseKey=S_ILLEGAL_REQUEST;
gblSenseData.ASC=ASC_INVALID_COMMAND_OPCODE;
gblSenseData.ASCQ=ASCQ_INVALID_COMMAND_OPCODE;
msd_csw.bCSWStatus=0x01;
msd_csw.dCSWDataResidue=0x00;
return;
}
*/
void MSDReadCapacityHandler()
{
dword one=0x1, C_size, C_mult, Mult, C_size_U, C_size_H, C_size_L, C_mult_H, C_mult_L;
dword C_Read_Bl_Len;
// Get the block length
C_Read_Bl_Len=gblCSDReg._byte[5]&0x0f;
gblBLKLen._dword=one<<C_Read_Bl_Len;
// Get the number of blocks using C_size and C_mult
C_size_U=gblCSDReg._byte[6]&0x03; // 2 LSB bits
C_size_H=gblCSDReg._byte[7];
C_size_L=(gblCSDReg._byte[8]&0xC0)>>6; // 2 MSB, right shift by 6places to get in LSB
C_size=(C_size_U<<10)|(C_size_H<<2)|(C_size_L);
C_mult_H=gblCSDReg._byte[9]&0x03;
C_mult_L=(gblCSDReg._byte[10]&0x80)>>7;
C_mult=(C_mult_H<<1)|C_mult_L;
Mult = one<<(C_mult+2);
gblNumBLKS._dword=Mult*(C_size+1)-1; // last LBA is noLBAs-1
// prepare the data response
msd_buffer[0]=gblNumBLKS.v[3];
msd_buffer[1]=gblNumBLKS.v[2];
msd_buffer[2]=gblNumBLKS.v[1];
msd_buffer[3]=gblNumBLKS.v[0];
msd_buffer[4]=gblBLKLen.v[3];
msd_buffer[5]=gblBLKLen.v[2];
msd_buffer[6]=gblBLKLen.v[1];
msd_buffer[7]=gblBLKLen.v[0];
msd_csw.dCSWDataResidue=0x08; // size of response
msd_csw.bCSWStatus=0x00; // success
}
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 {
//sectorNumber=ConvertLBASector(LBA._dword);
while (TransferLength._word > 0) {
TransferLength._word--; // we have read 1 LBA
status = SECTORread(LBA._dword, (byte*)&msd_buffer[0]);
//status = SECTORread(sectorNumber, (byte*)&msd_buffer[0]);
LBA._dword++; // read the next LBA
//sectorNumber++;
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 BOT specifications
msd_csw.dCSWDataResidue=0x0;
// mLED_4_On();
// prepare sense data read error
break; // break the loop
}
}
}
}
void MSDWriteHandler()
{
SDC_Error status=sdcValid;
WORD TransferLength;
DWORD LBA;
// read the LBA field from Command Block
// Note we cannot use structure dword because the 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];
// read the transfer length
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; // in order to read 512 bytes of data from MSD_BD_OUT
/*
while (msd_csw.dCSWDataResidue>0) {
while(mMSDRxIsBusy());
// We can only read 64 bytes at a time;
gblCBW.dCBWDataTransferLength-=MSD_BD_OUT.Cnt;
msd_csw.dCSWDataResidue-=MSD_BD_OUT.Cnt;
MSD_BD_OUT.ADR+=MSD_BD_OUT.Cnt;
dataLen+=MSD_BD_OUT.Cnt;
mUSBBufferReady(MSD_BD_OUT);
USBDriverService();
}
while(mMSDRxIsBusy());
MSD_BD_OUT.ADR=(byte*)&msd_buffer[0];
MSD_BD_OUT.Cnt=MSD_OUT_EP_SIZE;
TransferLength._word--;
*/
//while(mMSDRxIsBusy());
//MSD_BD_OUT.ADR=(byte*)&msd_buffer[0];
//MSD_BD_OUT.Cnt=MSD_OUT_EP_SIZE;
//mUSBBufferReady(MSD_BD_OUT); // call after every read or write on nonEP0 EP,
// toggles DTS and gives ownership to SIE
//USBDriverService(); // clears the TRNIF
while(mMSDRxIsBusy());
gblCBW.dCBWDataTransferLength-=MSD_BD_OUT.Cnt;
msd_csw.dCSWDataResidue-=MSD_BD_OUT.Cnt;
while (msd_csw.dCSWDataResidue>0) {
//while(mMSDRxIsBusy()); // change address only if we are the owner
MSD_BD_OUT.ADR+=MSD_BD_OUT.Cnt;
MSD_BD_OUT.Cnt=MSD_OUT_EP_SIZE;
mUSBBufferReady(MSD_BD_OUT); // call after every read or write on nonEP0 EP,
// toggles DTS and gives ownership to SIE
USBDriverService(); // clears the TRNIF
while(mMSDRxIsBusy()); // if we have read the data
gblCBW.dCBWDataTransferLength-=MSD_BD_OUT.Cnt;
msd_csw.dCSWDataResidue-=MSD_BD_OUT.Cnt;
}
MSD_BD_OUT.ADR=(byte*)&msd_buffer[0];
MSD_BD_OUT.Cnt=MSD_OUT_EP_SIZE;
status = SECTORwrite(gblLBA++, (byte*)&msd_buffer[0]);
if (status) {
//msd_csw.bCSWStatus=0x01;
mLED_4_On();
}
TransferLength._word--;
}
msd_csw.dCSWDataResidue=0x0;
return;
}
dword ConvertLBASector(dword LBA)
{
BS BootSec;
dword TotSec, sectorNumber;
BootSec=(BS)gblDisk.buffer;
if(BootSec->FAT.FAT_16.BPB_TotSec16 != 0)
{
TotSec = BootSec->FAT.FAT_16.BPB_TotSec16;
}
else
{
TotSec = BootSec->FAT.FAT_16.BPB_TotSec32;
}
sectorNumber=(LBA%TotSec)+1;
return LBA-61;
}
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;
}
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;
}
void MSDMediumRemovalHandler()
{
msd_csw.bCSWStatus=0x00;
msd_csw.dCSWDataResidue=0x00;
return;
}
void MSDTestUnitReadyHandler()
{
msd_csw.bCSWStatus=0x0;
ResetSenseData();
if(StartupCard((DISK*)&gblDisk, (byte *)&msd_buffer[0], (CARDSTATUS *)&gblCardStatus)!=CE_GOOD)
{
//mLED_1_On();
/*
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(gblFlag.isWP) {
gblSenseData.SenseKey=S_NOT_READY;
gblSenseData.ASC=ASC_LOGICAL_UNIT_NOT_READY_INTERVENTION_REQD;
gblSenseData.ASCQ=ASCQ_LOGICAL_UNIT_NOT_READY_INTERVENTION_REQD;
msd_csw.bCSWStatus=0x01;
mLED_3_On();
}
}
msd_csw.dCSWDataResidue=0x00;
//sendCSW();
return;
}
void MSDVerifyHandler()
{
msd_csw.bCSWStatus=0x0;
msd_csw.dCSWDataResidue=0x00;
return;
}
void MSDStopStartHandler()
{
msd_csw.bCSWStatus=0x0;
msd_csw.dCSWDataResidue=0x00;
return;
}
void MSDSuccessCSW(dword residue)
{
//mLED_Both_On();
//msd_cbw_csw.dCSWTag=msd_cbw_csw.dCBWTag;
//msd_cbw_csw.dCSWSignature._dword=0x53425355;
//msd_cbw_csw.dCSWDataResidue._dword = 0x0;
//msd_cbw_csw.bCSWStatus._byte=0x0;
msd_csw.dCSWTag=msd_cbw.dCBWTag;
msd_csw.dCSWSignature=0x53425355;
msd_csw.dCSWDataResidue = residue;
msd_csw.bCSWStatus=0x0;
while(mMSDTxIsBusy());
MSD_BD_IN.ADR=(byte*)&msd_csw;
MSD_BD_IN.Cnt=0x0d;
mUSBBufferReady(MSD_BD_IN);
USBDriverService();
}
void MSDErrorCSW(void)
{
//mLED_1_On();
msd_csw.dCSWTag=msd_cbw.dCBWTag;
msd_csw.dCSWSignature=0x53425355;
msd_csw.dCSWDataResidue=msd_cbw.dCBWDataTransferLength;
msd_csw.bCSWStatus=0x1;
while(mMSDTxIsBusy());
MSD_BD_IN.ADR=(byte*)&msd_csw;
MSD_BD_IN.Cnt=0x0d;
mUSBBufferReady(MSD_BD_IN);
USBDriverService();
}
void MSDInHandler(void)
{
return;
}
void MSDTxPkt(char *buffer, byte len)
{
byte i;
/*
* Value of len should be equal to or smaller than MSD_INT_IN_EP_SIZE.
* This check forces the value of len to meet the precondition.
*/
if(len > MSD_IN_EP_SIZE)
len = MSD_IN_EP_SIZE;
/*
* Copy data from user's buffer to dual-ram buffer
*/
for (i = 0; i < len; i++)
msd_buffer[i] = buffer[i];
MSD_BD_IN.ADR=(byte*)&msd_buffer;
MSD_BD_IN.Cnt = len;
mUSBBufferReady(MSD_BD_IN);
}//end MSDTxPkt
void MSDInitEP(void)
{
mInitAllLEDs();
MSD_UEP = EP_OUT_IN|HSHK_EN; // Enable 2 data pipes
MSD_BD_OUT.Cnt=sizeof(msd_cbw);
MSD_BD_OUT.ADR=(byte*)&msd_cbw;
MSD_BD_OUT.Stat._byte = _USIE|_DAT0|_DTSEN; //usbmmap.h owner SIE, DAT0 expected next, data toggle sunc enable
/*
* Do not have to init Cnt of IN pipes here.
* Reason: Number of bytes to send to the host
* varies from one transaction to
* another. Cnt should equal the exact
* number of bytes to transmit for
* a given IN transaction.
* This number of bytes will only
* be known right before the data is
* sent.
*/
MSD_BD_IN.ADR = (byte*)&msd_buffer[0]; // Set buffer address
MSD_BD_IN.Stat._byte = _UCPU|_DAT1; // Set status CPU owns Data1 expected next
}//end MSDInitEP
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -