⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 msdnotworking.c

📁 PIC18F4550 SD CARD USB
💻 C
📖 第 1 页 / 共 2 页
字号:
	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 + -