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

📄 msd.c

📁 PIC18F4550 SD CARD USB
💻 C
📖 第 1 页 / 共 3 页
字号:
		    MSDReadCapacityHandler();            
        break;
		case READ_10:
        	MSDReadHandler();
	    break;
    	case WRITE_10:
    	   	MSDWriteHandler();
		break;
        case REQUEST_SENSE:
		   	MSDRequestSenseHandler();
        break;
	    case MODE_SENSE:
	    	MSDModeSenseHandler();
    	break;
		case PREVENT_ALLOW_MEDIUM_REMOVAL:
		   	MSDMediumRemovalHandler();
        break;
		case TEST_UNIT_READY:
		   	MSDTestUnitReadyHandler();
        break;
		case VERIFY:
		   	MSDVerifyHandler();
        break;
		case STOP_START:
		   	MSDStopStartHandler();
        break;
		default:
        	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;
 		break;
	} // end switch	
	
	ptrNextData=(byte*)&msd_buffer[0];
}

/******************************************************************************
 * Function:        void SendCSW(void)
 *
 * PreCondition:    None 
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        This function sends the CSW and sets the State to MSD_WAIT
 *                  It also changes MSD_BD_OUT to point to msd_csw (structure
 *                  for reading CSW) Note that this was changed in
 *                  MSD_DATA_OUT state to point to msd_buffer in order to
 *                  read data from host
 *
 * Note:            None
 *****************************************************************************/	
	
void SendCSW(void)
{
	while(mMSDTxIsBusy());
	MSD_BD_IN.ADR=(byte*)&msd_csw;
	MSD_BD_IN.Cnt=MSD_CSW_SIZE;
	mUSBBufferReady(MSD_BD_IN);
	USBDriverService();	
	MSD_BD_OUT.Cnt=sizeof(msd_cbw);		
    MSD_BD_OUT.ADR=(byte*)&msd_cbw;			// in MSD_DATA_OUT state the address
                                            // was changed to point tomsd_buffer
   	MSD_State=MSD_WAIT;
}


/******************************************************************************
 * Function:        void SendData(byte* dataAddr, byte dataSize)
 *
 * PreCondition:    None 
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        This function sends "dataSize" bytes of data
 *                  (< MSD_EP_IN_SIZE) starting at address "dataAddr".
 *
 * Note:            None
 *****************************************************************************/	
	
void SendData(byte* dataAddr, byte dataSize)
{
	while(mMSDTxIsBusy());
	MSD_BD_IN.ADR=dataAddr;
	MSD_BD_IN.Cnt=dataSize;
	mUSBBufferReady(MSD_BD_IN);
	USBDriverService();
}

/******************************************************************************
 * Function:        void MSDDataIn(void)
 *
 * PreCondition:    None 
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        This function sends 512B of data in msd_buffer to the
 *                  host in 64B chunks using MSD_BD_IN.Various conditions
 *                  when data to be sent is less than MSD_IN_EP_SIZE and
 *                  error condition bCSWStatus = 0x01 are checked. As per
 *                  specifications, in case of error 0 filled data of the size 
 *                  expected by the host dCBWDataTransferLength is sent.
 *
 * Note:            None
 *****************************************************************************/	
void MSDDataIn(void)
{
	byte i;
	dword size;
	/* Case (status==0) and (data to be sent > MSD_IN_EP_SIZE)*/
	if ((msd_csw.bCSWStatus==0x00)&&(msd_csw.dCSWDataResidue>=MSD_IN_EP_SIZE)) {
		/* Write next chunk of data to EP Buffer and send */
		SendData(ptrNextData,MSD_IN_EP_SIZE);
		gblCBW.dCBWDataTransferLength-=	MSD_IN_EP_SIZE;
		msd_csw.dCSWDataResidue-=MSD_IN_EP_SIZE;
		ptrNextData+=MSD_IN_EP_SIZE;
	} else {
		if (msd_csw.bCSWStatus!=0x0) { // error path status!=0
			size=mMin(MSD_IN_EP_SIZE,gblCBW.dCBWDataTransferLength);
			for (i=0;i<size;i++) msd_buffer[i]=0;	// prepare 0 data
			if (gblCBW.dCBWDataTransferLength > MSD_IN_EP_SIZE) {	
				/* Case (status!=0) and (data to be sent > MSD_IN_EP_SIZE)*/
				/* write next chunk of data to EP Buffer and send */
				SendData((byte*)&msd_buffer[0],MSD_IN_EP_SIZE);
				gblCBW.dCBWDataTransferLength -= MSD_IN_EP_SIZE;
				msd_csw.dCSWDataResidue-=MSD_IN_EP_SIZE;
			} else {				
				/* Case (status!=0) and (data to be sent < MSD_IN_EP_SIZE) */
				/* write next chunk of data to EP Buffer and send*/
				SendData((byte*)&msd_buffer[0],gblCBW.dCBWDataTransferLength);
				gblCBW.dCBWDataTransferLength = 0;			
				/* we have sent 0s for what was expected by host*/
				msd_csw.dCSWDataResidue -= gblCBW.dCBWDataTransferLength;
			}
		} else { 					
			/* Case (status ==0) and (data to be sent < MSD_IN_EP_SIZE) */
			/* write next chunk of data to EP Buffer and send */
			SendData(ptrNextData,msd_csw.dCSWDataResidue);
			/* we have sent all the data that was expected by host */
			gblCBW.dCBWDataTransferLength -= msd_csw.dCSWDataResidue ;	
			msd_csw.dCSWDataResidue = gblCBW.dCBWDataTransferLength;
			/* In case the host expected more than what we had to send */
			/* Setting DataTransferLength=0 so that CSW is sent after this*/
			gblCBW.dCBWDataTransferLength = 0;							
													
		}
	}
}
	
/******************************************************************************
 * Function:        void IsValidCBW()
 *
 * PreCondition:    None 
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        This checks if the received CBW is valid
 *                  According to the Mass Storage Class Specifications, 
 *		    a CSW is considered to be valid if 
 *                  1. It was received in MS_WAIT State 
 *                  2. CBW length is 1Fh bytes (MSD_CBW_SIZE)
 *                  3. dCBWSignature is equal to 0x43425355h		
 *
 * Note:            None
 *****************************************************************************/	
	
byte IsValidCBW() 
{
	if ((gblCBWLength!=MSD_CBW_SIZE)||(gblCBW.dCBWSignature!=0x43425355))return FALSE;
    else return TRUE;
}

/******************************************************************************
 * Function:        void IsMeaningfulCBW()
 *
 * PreCondition:    None 
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        This checks if the received CBW is meaningful
 *                  According to the Mass Storage Class Specifications, 
 *		    a CSW is considered to be meaningful if 
 *                  1. No reserved bits are set
 *                  2. bCBWLUN contains a valid LUN supported by device
 *		    3. bCBWCBLength and CBWCB are in accordance with
 *                     bInterfaceSubClass
 * Note:            None
 *****************************************************************************/	
	
byte IsMeaningfulCBW()
{
	/*  3msb bits of CBWCBLength are reserved and must be 0,
     *  4msb bits of CBWLUN	are reserved and must be 0
	 *  valid CBWCBLength is between 1 and 16B
	 *  In bCBWFlags only msb indicates data direction rest must be 0
	 */  
	if((gblCBW.bCBWLUN<=0x0f)&&(gblCBW.bCBWCBLength<=0x10)&&(gblCBW.bCBWCBLength>=0x01)&&(gblCBW.bCBWFlags==0x00|gblCBW.bCBWFlags==0x80)) 
		return TRUE;
	else return FALSE;	
	
}

/******************************************************************************
 * Function:        void PrepareCSWData()
 *
 * PreCondition:    None 
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        This prepares the Status data of CSW by copying the
 *                  dCSWTag from CBWTage and sets the signature 
 *                  of valid CSW=53425355h
 *
 * Note:            None
 *****************************************************************************/	
void PrepareCSWData()
{ 
	/* Residue and Status fields are set after
       decoding and executing the command  */
	msd_csw.dCSWTag=gblCBW.dCBWTag;
	msd_csw.dCSWSignature=0x53425355;
}


/******************************************************************************
 * Function:        void MSDInquiryHandler(void)
 *
 * PreCondition:    None 
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        This function prepares the response of the Inquiry command
 *                  A fixed Inquiry response is copied from ROM to the
 *		    msd_buffer and CSWStatus, CSWDataResidue values are set
 *
 * Note:            None
 *****************************************************************************/	
	
void MSDInquiryHandler(void)
{
	byte i;
	byte *buffer;
	memcpypgm2ram((byte *)&msd_buffer[0],(byte *)&inq_resp,sizeof(InquiryResponse));
	msd_csw.dCSWDataResidue=sizeof(InquiryResponse);
	msd_csw.bCSWStatus=0x00;			// success
	return;
}


/******************************************************************************
 * Function:        void ResetSenseData(void)
 *
 * PreCondition:    None 
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        This routine resets the Sense Data, initializing the
 *                  structure RequestSenseResponse gblSenseData.
 *                  
 *
 * Note:            None
 *****************************************************************************/
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;
}

/******************************************************************************
 * Function:        void MSDReadCapacityHandler()
 *
 * PreCondition:    None 
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        This function processes the data from CSD register
 *                  (read during intiailization of sdcard)to find the number
 *                  of blocks (gblNumBLKS) and block length (gblBLKLen)
 *                  This data is then copied to msd_buffer and a response
 *                  for Read Capacity Command is prepared
 * Note:            None
 *****************************************************************************/	
	
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
}

/******************************************************************************
 * Function:        void MSDReadHandler(void)
 *
 * PreCondition:    None 
 *

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -