Пример #1
0
void FlashDoTX(void)
{    
	BYTE SendNow;
    USBMaskInterrupts();

	if (!USBHandleBusy(FlashDataInHandle)) {
		switch (FlashTxState) {
			case FLASH_TX_COMPLETING:
				FlashTxState = FLASH_TX_READY;
				break;
			
			case FLASH_TX_BUSY:
				SendNow = FlashTxLen > sizeof(FlashTxBuffer) ? sizeof(FlashTxBuffer) : FlashTxLen;
				
				FlashTxCBF((BYTE *) &FlashTxBuffer, SendNow);    	  
		    	FlashTxLen -= SendNow;
		        
		        if(FlashTxLen == 0)
		                FlashTxState = FLASH_TX_COMPLETING;

		        FlashDataInHandle = USBTxOnePacket(NAND_TX_EP,(BYTE*)&FlashTxBuffer, SendNow);
				break;
		}
    }

    USBUnmaskInterrupts();
}
Пример #2
0
/********************************************************************
* Function: 	UsbTasks()
*
* Precondition: 
*
* Input: 		None.
*
* Output:		None.
*
* Side Effects:	None.
*
* Overview: 	This function transmits frames and received frames to and from USB.
*
*			
* Note:		 	None.
********************************************************************/	
void UsbTasks(void)
{
	UINT TxLen;
	UINT8 *TxPtr;
	
	 #if defined(USB_POLLING)		
	//This function must be called everytime. This is a stack function.
	USBDeviceTasks();
	 #endif

	// Check if bootloader has something to send out to PC. 
	TxLen = FRAMEWORK_GetTransmitFrame(UsbTxData);

	// Initialize the transmit pointer.
	TxPtr = &UsbTxData[0];
	
	while(TxLen)	
	{
	
		while(UsbTxBusy()); // Wait for USB transmit completion.	
		
		// Send the packet (USB endpoint size is always 64 bytes)
		USBTxOnePacket(HID_EP, TxPtr, MaxUsbPacketSize);	
		
		if(TxLen > MaxUsbPacketSize)
		{
			// Send pending bytes in next loop.
			TxLen -= MaxUsbPacketSize;
			// Point to next 64bytes.
			TxPtr += MaxUsbPacketSize;
			// Probably a wait is needed here, otherwise PC app may miss frames.
			//Wait();			
		}	
		else
		{
			// No more bytes.
			TxLen = 0;
		}			
	}
	
	// Following part of the code checks if there is any data from USB.
	// If there are any data available, it just pushes the data to the frame work. 
	// Framework decodes the packet and takes necessary action like erasing/ programming etc.	
		
	if(UsbRxDataAvlbl())// Check if we have got any data from USB.	 		
    {
	    // Yes, we got a packet from HID End point.	    
	    // Pass the buffer to frame work. Framework decodes the packet and executes the Bootloder specific commands (Erasing/Programming etc).
		FRAMEWORK_BuildRxFrame(UsbRxData, MaxUsbPacketSize);
	    	    
	    // Re-arm the HID endpoint to receive next packet.(Remember! We have armed the HID endpoint for the first time in function USBCBInitEP())
	    USBOutHandle = HIDRxPacket(HID_EP,(BYTE*)UsbRxData,MaxUsbPacketSize);	    	    		
	}	
	
}	
Пример #3
0
//------------------------------PMP Handler-------------------------------------
void __ISR(_EXTERNAL_0_VECTOR, IPL6) GetSlaveData(void){
    unsigned char pitch, vel;
    PMPMasterRead();
    pitch = mPMPMasterReadByte();
    
    vel = mPMPMasterReadByte();

    if(!USBHandleBusy(USBTxHandle))
    {
        midiData.Val = 0;   //must set all unused values to 0

        midiData.CableNumber = 0;
        midiData.CodeIndexNumber = MIDI_CIN_NOTE_ON;
        midiData.DATA_0 = 0x90;                     //Note on
        midiData.DATA_1 = pitch + 60;               //pitch
        midiData.DATA_2 = vel;                      //velocity

        USBTxHandle = USBTxOnePacket(MIDI_EP,(BYTE*)&midiData,4);
    }

    mINT0ClearIntFlag();
}
Пример #4
0
void CDCTxService(void)
{
    BYTE byte_to_send;
    BYTE i;
    
    USBMaskInterrupts();
    
    CDCNotificationHandler();
    
    if(USBHandleBusy(CDCDataInHandle)) 
    {
        USBUnmaskInterrupts();
        return;
    }

    /*
     * Completing stage is necessary while [ mCDCUSartTxIsBusy()==1 ].
     * By having this stage, user can always check cdc_trf_state,
     * and not having to call mCDCUsartTxIsBusy() directly.
     */
    if(cdc_trf_state == CDC_TX_COMPLETING)
        cdc_trf_state = CDC_TX_READY;
    
    /*
     * If CDC_TX_READY state, nothing to do, just return.
     */
    if(cdc_trf_state == CDC_TX_READY)
    {
        USBUnmaskInterrupts();
        return;
    }
    
    /*
     * If CDC_TX_BUSY_ZLP state, send zero length packet
     */
    if(cdc_trf_state == CDC_TX_BUSY_ZLP)
    {
        CDCDataInHandle = USBTxOnePacket(CDC_DATA_EP,NULL,0);
        //CDC_DATA_BD_IN.CNT = 0;
        cdc_trf_state = CDC_TX_COMPLETING;
    }
    else if(cdc_trf_state == CDC_TX_BUSY)
    {
        /*
         * First, have to figure out how many byte of data to send.
         */
    	if(cdc_tx_len > sizeof(cdc_data_tx))
    	    byte_to_send = sizeof(cdc_data_tx);
    	else
    	    byte_to_send = cdc_tx_len;

        /*
         * Subtract the number of bytes just about to be sent from the total.
         */
    	cdc_tx_len = cdc_tx_len - byte_to_send;
    	  
        pCDCDst.bRam = (BYTE*)&cdc_data_tx; // Set destination pointer
        
        i = byte_to_send;
        if(cdc_mem_type == USB_EP0_ROM)            // Determine type of memory source
        {
            while(i)
            {
                *pCDCDst.bRam = *pCDCSrc.bRom;
                pCDCDst.bRam++;
                pCDCSrc.bRom++;
                i--;
            }//end while(byte_to_send)
        }
        else // _RAM
        {
            while(i)
            {
                *pCDCDst.bRam = *pCDCSrc.bRam;
                pCDCDst.bRam++;
                pCDCSrc.bRam++;
                i--;
            }//end while(byte_to_send._word)
        }//end if(cdc_mem_type...)
        
        /*
         * Lastly, determine if a zero length packet state is necessary.
         * See explanation in USB Specification 2.0: Section 5.8.3
         */
        if(cdc_tx_len == 0)
        {
            if(byte_to_send == CDC_DATA_IN_EP_SIZE)
                cdc_trf_state = CDC_TX_BUSY_ZLP;
            else
                cdc_trf_state = CDC_TX_COMPLETING;
        }//end if(cdc_tx_len...)
        CDCDataInHandle = USBTxOnePacket(CDC_DATA_EP,(BYTE*)&cdc_data_tx,byte_to_send);

    }//end if(cdc_tx_sate == CDC_TX_BUSY)
    
    USBUnmaskInterrupts();
}//end CDCTxService
BYTE MSDReadHandler(void)
{
    static BYTE MSDReadState = MSD_READ10_WAIT;
    
    switch(MSDReadState)
    {
        case MSD_READ10_WAIT:
        	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;
        	msd_csw.dCSWDataResidue=0x0;
        	
            MSDReadState = MSD_READ10_BLOCK;
            //Fall through to MSD_READ_BLOCK
        case MSD_READ10_BLOCK:
            if(TransferLength.Val == 0)
            {
                MSDReadState = MSD_READ10_WAIT;
                break;
            }
            
            TransferLength.Val--;					// we have read 1 LBA
            MSDReadState = MSD_READ10_SECTOR;
            //Fall through to MSD_READ10_SECTOR
        case MSD_READ10_SECTOR:
            //if the old data isn't completely sent yet
            if(USBHandleBusy(USBMSDInHandle) != 0)
            {
                break;
            }

    		if(LUNSectorRead(LBA.Val, (BYTE*)&msd_buffer[0]) != TRUE)
    		{
				msd_csw.bCSWStatus=0x01;			// Error 0x01 Refer page#18
                                                    // of BOT specifications
				/* Don't read any more data*/
				msd_csw.dCSWDataResidue=0x0;
              
                MSD_State = MSD_DATA_IN;
        		break;
            }

            LBA.Val++;
            
			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];
            
            MSDReadState = MSD_READ10_TX_SECTOR;
    
            //Fall through to MSD_READ10_TX_SECTOR
        case MSD_READ10_TX_SECTOR:
            if(msd_csw.dCSWDataResidue == 0)
            {
                MSDReadState = MSD_READ10_BLOCK;
                break;
            }
            
            MSDReadState = MSD_READ10_TX_PACKET;
            //Fall through to MSD_READ10_TX_PACKET
            
        case MSD_READ10_TX_PACKET:
        	if ((msd_csw.bCSWStatus==0x00)&&(msd_csw.dCSWDataResidue>=MSD_IN_EP_SIZE)) 
            {
        		/* Write next chunk of data to EP Buffer and send */
                if(USBHandleBusy(USBMSDInHandle))
                {
                    break;
                }
                
                USBMSDInHandle = USBTxOnePacket(MSD_DATA_IN_EP,ptrNextData,MSD_IN_EP_SIZE);
                
  			    MSDReadState = MSD_READ10_TX_SECTOR;

        		gblCBW.dCBWDataTransferLength-=	MSD_IN_EP_SIZE;
        		msd_csw.dCSWDataResidue-=MSD_IN_EP_SIZE;
        		ptrNextData+=MSD_IN_EP_SIZE;
        	}
            break;
    }
    
    return MSDReadState;
}
/******************************************************************************
 	Function:
 		void MSDProcessCommandMediaAbsent(void)
 		
 	Description:
 		This funtion processes a command received through the MSD
 		class driver
 		
 	PreCondition:
 		None
 		
 	Parameters:
 		None
 	
 	Return Values:
 		BYTE - the current state of the MSDProcessCommand state
 		machine.  The valid values are defined in MSD.h under the 
 		MSDProcessCommand state machine declaration section
 		
 	Remarks:
 		None
 
  *****************************************************************************/	
void MSDProcessCommandMediaAbsent(void)
{
    BYTE i;

    switch(MSDCommandState)
    {
        case MSD_REQUEST_SENSE:
        {
            ResetSenseData();
            gblSenseData[LUN_INDEX].SenseKey=S_NOT_READY;
    		gblSenseData[LUN_INDEX].ASC=ASC_MEDIUM_NOT_PRESENT;
    		gblSenseData[LUN_INDEX].ASCQ=ASCQ_MEDIUM_NOT_PRESENT;

          	for(i=0;i<sizeof(RequestSenseResponse);i++)
          	{
          		msd_buffer[i]=gblSenseData[LUN_INDEX]._byte[i];
            }
          	
            msd_csw.dCSWDataResidue=sizeof(RequestSenseResponse);
          	msd_csw.bCSWStatus=0x0;					// success
          	MSDCommandState = MSD_COMMAND_RESPONSE;
            break;
        } 
        case MSD_PREVENT_ALLOW_MEDIUM_REMOVAL:
        case MSD_TEST_UNIT_READY:
        {
    		msd_csw.bCSWStatus=0x01;
            MSDCommandState = MSD_COMMAND_WAIT;
            break;
        }
        case MSD_INQUIRY:
        {
        	memcpypgm2ram(
        	    (void *)&msd_buffer[0],
        	    (ROM void*)&inq_resp,
        	    sizeof(InquiryResponse)
        	    );
        	msd_csw.dCSWDataResidue=sizeof(InquiryResponse);
        	msd_csw.bCSWStatus=0x00;			// success
        	MSDCommandState = MSD_COMMAND_RESPONSE;
            break;
        }
        case MSD_COMMAND_WAIT:
        {
            MSDCommandState = gblCBW.CBWCB[0];
            break;
        }
        case MSD_COMMAND_RESPONSE:
            if(USBHandleBusy(USBMSDInHandle) == FALSE)
            {
                USBMSDInHandle = USBTxOnePacket(MSD_DATA_IN_EP,(BYTE*)&msd_buffer[0],msd_csw.dCSWDataResidue);
			    MSDCommandState = MSD_COMMAND_WAIT;

        		msd_csw.dCSWDataResidue=0;
            }
            break;
        default:
        {
            //Stall MSD endpoint IN
            USBStallEndpoint(MSD_DATA_IN_EP,1);
    		msd_csw.bCSWStatus=0x01;
            MSDCommandState = MSD_COMMAND_WAIT;
            break;
        }
    }
}
/******************************************************************************
 	Function:
 		void MSDProcessCommandMediaPresent(void)
 		
 	Description:
 		This funtion processes a command received through the MSD
 		class driver
 		
 	PreCondition:
 		None
 		
 	Paramters:
 		None
 	
 	Return Values:
 		BYTE - the current state of the MSDProcessCommand state
 		machine.  The valid values are defined in MSD.h under the 
 		MSDProcessCommand state machine declaration section
 		
 	Remarks:
 		None
 
 *****************************************************************************/	
void MSDProcessCommandMediaPresent(void)
{
    BYTE i; 

    switch(MSDCommandState)
    {
        case MSD_COMMAND_WAIT:
            //copy the received command to the command state machine
            MSDCommandState = gblCBW.CBWCB[0];
            break;
    	case MSD_INQUIRY:
    	{
            //copy the inquiry results from the defined ROM buffer 
            //  into the USB buffer so that it can be transmitted
        	memcpypgm2ram(
        	    (void *)&msd_buffer[0],
        	    (ROM void*)&inq_resp,
        	    sizeof(InquiryResponse)
        	    );
        	msd_csw.dCSWDataResidue=sizeof(InquiryResponse);
        	msd_csw.bCSWStatus=0x00;			// success
        	MSDCommandState = MSD_COMMAND_RESPONSE;
            break;
        }
        case MSD_READ_CAPACITY:
        {
            //If the host asked for the capacity of the device
            DWORD_VAL sectorSize;
            DWORD_VAL capacity;

        	msd_csw.bCSWStatus=0x00;			  // success
            
            //get the information from the physical media
            capacity.Val = LUNReadCapacity();
            sectorSize.Val = LUNReadSectorSize();
            
            //copy the data to the buffer
        	msd_buffer[0]=capacity.v[3];
        	msd_buffer[1]=capacity.v[2];
        	msd_buffer[2]=capacity.v[1];
        	msd_buffer[3]=capacity.v[0];
        	
        	msd_buffer[4]=sectorSize.v[3];
        	msd_buffer[5]=sectorSize.v[2];
        	msd_buffer[6]=sectorSize.v[1];
        	msd_buffer[7]=sectorSize.v[0];
        
        	msd_csw.dCSWDataResidue=0x08;		  // size of response
        	MSDCommandState = MSD_COMMAND_RESPONSE;
            break;
        }
		case MSD_READ_10:
        	if(MSDReadHandler() == MSD_READ10_WAIT)
        	{
			    MSDCommandState = MSD_COMMAND_WAIT;
            }
            break;
    	case MSD_WRITE_10:
        	if(MSDWriteHandler() == MSD_WRITE10_WAIT)
        	{
			    MSDCommandState = MSD_COMMAND_WAIT;
            }
		    break;
        case MSD_REQUEST_SENSE:    
          	for(i=0;i<sizeof(RequestSenseResponse);i++)
          	{
          		msd_buffer[i]=gblSenseData[LUN_INDEX]._byte[i];
            }
          	
            msd_csw.dCSWDataResidue=sizeof(RequestSenseResponse);
          	msd_csw.bCSWStatus=0x0;					// success
          	MSDCommandState = MSD_COMMAND_RESPONSE;
            break;
	    case MSD_MODE_SENSE:
        	msd_buffer[0]=0x02;
        	msd_buffer[1]=0x00;
        	msd_buffer[2]=0x00;
        	msd_buffer[3]=0x00;
        	
        	msd_csw.bCSWStatus=0x0;
        	msd_csw.dCSWDataResidue=0x04;
        	MSDCommandState = MSD_COMMAND_RESPONSE;
    	    break;
		case MSD_PREVENT_ALLOW_MEDIUM_REMOVAL:
            if(LUNMediaDetect())
            {
        		msd_csw.bCSWStatus=0x00;
        		msd_csw.dCSWDataResidue=0x00;
        	}
            else
            {
        		gblSenseData[LUN_INDEX].SenseKey=S_NOT_READY;
        		gblSenseData[LUN_INDEX].ASC=ASC_MEDIUM_NOT_PRESENT;
        		gblSenseData[LUN_INDEX].ASCQ=ASCQ_MEDIUM_NOT_PRESENT;
        		msd_csw.bCSWStatus=0x01;
        	}
			MSDCommandState = MSD_COMMAND_WAIT;
            break;
		case MSD_TEST_UNIT_READY:
            if((gblSenseData[LUN_INDEX].SenseKey==S_UNIT_ATTENTION) && (msd_csw.bCSWStatus==1))
            {
                MSDCommandState = MSD_COMMAND_WAIT;
            }
            else
            {
            	ResetSenseData();
            	msd_csw.dCSWDataResidue=0x00;
    			MSDCommandState = MSD_COMMAND_WAIT;
            }
            break;
		case MSD_VERIFY:
            //Fall through to STOP_START
		case MSD_STOP_START:
        	msd_csw.bCSWStatus=0x0;
        	msd_csw.dCSWDataResidue=0x00;
			MSDCommandState = MSD_COMMAND_WAIT;
            break;
        case MSD_COMMAND_RESPONSE:
            if(USBHandleBusy(USBMSDInHandle) == FALSE)
            {
                USBMSDInHandle = USBTxOnePacket(MSD_DATA_IN_EP,(BYTE*)&msd_buffer[0],msd_csw.dCSWDataResidue);
			    MSDCommandState = MSD_COMMAND_WAIT;

        		msd_csw.dCSWDataResidue=0;
            }
            break;
        case MSD_COMMAND_ERROR:
		default:
        	ResetSenseData();
			gblSenseData[LUN_INDEX].SenseKey=S_ILLEGAL_REQUEST;
			gblSenseData[LUN_INDEX].ASC=ASC_INVALID_COMMAND_OPCODE;
			gblSenseData[LUN_INDEX].ASCQ=ASCQ_INVALID_COMMAND_OPCODE;
			msd_csw.bCSWStatus=0x01;
			msd_csw.dCSWDataResidue=0x00;
			MSDCommandState = MSD_COMMAND_RESPONSE;
 		    break;
	} // end switch	
}
/*********************************************************************************
  Function:
        BYTE MSDTasks(void)
    
  Summary:
    This function runs the MSD class state machines and all of its
    sub-systems. This function should be called periodically once the
    device is in the configured state in order to keep the MSD state
    machine going.
  Description:
    This function runs the MSD class state machines and all of its
    sub-systems. This function should be called periodically once the
    device is in the configured state in order to keep the MSD state
    machine going.
    
    Typical Usage:
    <code>
    void main(void)
    {
        USBDeviceInit();
        while(1)
        {
            USBDeviceTasks();
            if((USBGetDeviceState() \< CONFIGURED_STATE) ||
               (USBIsDeviceSuspended() == TRUE))
            {
                //Either the device is not configured or we are suspended
                //  so we don't want to do execute any application code
                continue;   //go back to the top of the while loop
            }
            else
            {
                //Keep the MSD state machine going
                MSDTasks();
    
                //Run application code.
                UserApplication();
            }
        }
    }
    </code>
  Conditions:
    None
  Return Values:
    BYTE -  the current state of the MSD state machine the valid values are
            defined in MSD.h under the MSDTasks state machine declaration section.
            The possible values are the following\:
            * MSD_WAIT
            * MSD_DATA_IN
            * MSD_DATA_OUT
            * MSD_SEND_CSW
  Remarks:
    None                                                                          
  *********************************************************************************/	
BYTE MSDTasks(void)
{
    BYTE i;
    
    switch(MSD_State)
    {
        case MSD_WAIT:
        {
            //If the MSD state machine is waiting for something to happen
            if(!USBHandleBusy(USBMSDOutHandle))
            {
        		//If we received an OUT packet from the host
                //  then copy the data from the buffer to a global
                //  buffer so that we can keep the information but
                //  reuse the buffer
        		gblCBW.dCBWSignature=msd_cbw.dCBWSignature;					
        		gblCBW.dCBWTag=msd_cbw.dCBWTag;
        		gblCBW.dCBWDataTransferLength=msd_cbw.dCBWDataTransferLength;
            	gblCBW.bCBWFlags=msd_cbw.bCBWFlags;
            	gblCBW.bCBWLUN=msd_cbw.bCBWLUN;
        	    gblCBW.bCBWCBLength=msd_cbw.bCBWCBLength;		// 3 MSB are zero

            	for (i=0;i<msd_cbw.bCBWCBLength;i++)
            	{
            		gblCBW.CBWCB[i]=msd_cbw.CBWCB[i];
                }
            		
                gblCBWLength=USBHandleGetLength(USBMSDOutHandle);

        	    //If this CBW is valid?
        		if ((gblCBWLength==MSD_CBW_SIZE)&&(gblCBW.dCBWSignature==0x43425355)) 
            	{
                    //Is this CBW meaningful?	
       				if((gblCBW.bCBWLUN<=0x0f)
               		&&(gblCBW.bCBWCBLength<=0x10)
               		&&(gblCBW.bCBWCBLength>=0x01)
               		&&(gblCBW.bCBWFlags==0x00||gblCBW.bCBWFlags==0x80)) 
            		{
                		//Prepare the CSW to be sent
                    	msd_csw.dCSWTag=gblCBW.dCBWTag;
                    	msd_csw.dCSWSignature=0x53425355;
                    	
        				/* If direction is device to host*/
        				if (gblCBW.bCBWFlags==0x80)
        				{
        					MSD_State=MSD_DATA_IN;
        				}
        				else if (gblCBW.bCBWFlags==0x00) 
            			{
        					/* If direction is host to device*/
        					/* prepare to read data in msd_buffer */
            			    MSD_State=MSD_DATA_OUT;
        				}        								
        			}
        		}
            }
            break;
        }
        case MSD_DATA_IN:
            if(MSDProcessCommand() == MSD_COMMAND_WAIT)
            {
                // Done processing the command, send the status
                MSD_State = MSD_SEND_CSW;
            }
            break;
        case MSD_DATA_OUT:
            if(MSDProcessCommand() == MSD_COMMAND_WAIT)
            {
    			/* Finished receiving the data prepare and send the status */
    		  	if ((msd_csw.bCSWStatus==0x00)&&(msd_csw.dCSWDataResidue!=0)) 
    		  	{
    		  		msd_csw.bCSWStatus=0x02;
    		    }
                MSD_State = MSD_SEND_CSW;
            }
            break;
        case MSD_SEND_CSW:
            if(USBHandleBusy(USBMSDInHandle))
            {
                //The TX buffer is not ready to send the status yet.
                break;
            }
            
            USBMSDInHandle = USBTxOnePacket(MSD_DATA_IN_EP,(BYTE*)&msd_csw,MSD_CSW_SIZE);
            
            //Get ready for next command to come in
            if(!USBHandleBusy(USBMSDOutHandle))
            {
                USBMSDOutHandle = USBRxOnePacket(MSD_DATA_OUT_EP,(BYTE*)&msd_cbw,sizeof(msd_cbw));
            }
        
           	MSD_State=MSD_WAIT;
            break;
    }
    
    return MSD_State;
}
USB_HANDLE ChipKITUSBTxOnePacket(BYTE ep, BYTE* data, WORD len)
{
	return(USBTxOnePacket(ep, data, len));
}
Пример #10
0
void ProcessCCID()
{
	static WORD CardPresentVerifyCounter = 0;
	static BOOL CardON = FALSE;
	BYTE i;
	BYTE ppsData[3]; 

	////// Detect Card Insertion and removal and transmit 	/////////////
	////// the status on interrupt endpoint 				/////////////

    if( !CardON && SC_CardPresent() )
    {
	    if( CardPresentVerifyCounter > 100 )
	    {
			if(!USBHandleBusy(usbCcidInterruptInHandle))
			{
		    	usbCcidBulkInEndpoint[0] = 0x50; //Msg Type
				usbCcidBulkInEndpoint[1] = 3;	//card present, change

		    	usbCcidInterruptInHandle = USBTxOnePacket(USB_EP_INT_IN, (BYTE*)&usbCcidBulkInEndpoint, 2);
		    	CardON = TRUE;
			}
		}
		else
			CardPresentVerifyCounter++;
	}
	else if( CardON && !SC_CardPresent() )
    {
	    SC_Shutdown();	//reset SC_Lib states and turn off hardware
		if(!USBHandleBusy(usbCcidInterruptInHandle))
		{
	    	usbCcidBulkInEndpoint[0] = 0x50; //Msg Type
			usbCcidBulkInEndpoint[1] = 2;	//card not present, change
	    	usbCcidInterruptInHandle = USBTxOnePacket(USB_EP_INT_IN, (BYTE*)&usbCcidBulkInEndpoint, 2);
	    	CardON = FALSE;
		}
	}
	else
		CardPresentVerifyCounter = 0;

	///// Process commands received on Bulk Endoint 		//////////////

    if(!USBHandleBusy(usbCcidBulkOutHandle))		//Check if the endpoint has received any data from the host.
    {
		union SLOT_STATUS card_st;
		BYTE ErrCode;
		static WORD TransactionCount=0;

		card_st.Val = 0;
		ErrCode     = 0; //clear error code
		
		
	    if(usbCcidOutPacketTrack == USB_CCID_BULK_OUT_FIRST_PACKET)
		{
            memset( pUsbCcidApdu->CCID_BulkOutBuffer, 0, sizeof(pUsbCcidApdu->CCID_BulkOutBuffer)) ;
            // copy the length from the CCID packet to a 32 Bit Variable.
	        usbCcidOutPacketLength.byte.LB = usbCcidBulkOutEndpoint[1];
	        usbCcidOutPacketLength.byte.HB = usbCcidBulkOutEndpoint[2];
	        usbCcidOutPacketLength.byte.UB = usbCcidBulkOutEndpoint[3];
	        usbCcidOutPacketLength.byte.MB = usbCcidBulkOutEndpoint[4];
	        usbCcidNoOfBytesToReceive = usbCcidOutPacketLength.Val + 10; // CCID command overhead is 10 bytes.
			
    	    for (i =0;i < USB_EP_SIZE;i++) // Copy received data from host to a temperary buffer
    	        pUsbCcidApdu->CCID_BulkOutBuffer[i] = usbCcidBulkOutEndpoint[i];

    	    if (usbCcidNoOfBytesToReceive > USB_EP_SIZE) // We still have more USB transactions to receive from host
    	    {
    	        usbCcidNoOfBytesToReceive = usbCcidNoOfBytesToReceive - USB_EP_SIZE;
    	        usbCcidOutPacketTrack = USB_CCID_BULK_OUT_SUBSEQUENT_PACKET;
    	        usbCcidBulkOutHandle = USBRxOnePacket(USB_EP_BULK_OUT,(BYTE*)&usbCcidBulkOutEndpoint,USB_EP_SIZE);
    	        return;
    	    }
    	    else // We have received everything from the host.
    	    {
        	    usbCcidNoOfBytesToReceive = 0;
        	    usbCcidOutPacketTrack = USB_CCID_BULK_OUT_FIRST_PACKET;
        	    TransactionCount =0;
        	}

        }
        else if (usbCcidOutPacketTrack == USB_CCID_BULK_OUT_SUBSEQUENT_PACKET)
        {
            // copy data to the APDU[];
            TransactionCount++;	
			if (usbCcidNoOfBytesToReceive > USB_EP_SIZE)
			{
            	for (i =0 ; i< USB_EP_SIZE; i++ )
                	pUsbCcidApdu->CCID_BulkOutBuffer[USB_EP_SIZE *  TransactionCount + i] = usbCcidBulkOutEndpoint[i];
			}
			else
			{
				for (i =0 ; i< usbCcidNoOfBytesToReceive; i++ )
                	pUsbCcidApdu->CCID_BulkOutBuffer[USB_EP_SIZE*TransactionCount+i] = usbCcidBulkOutEndpoint[i];

			}
    	    if (usbCcidNoOfBytesToReceive > USB_EP_SIZE) // We still have more bytes to receive from host
    	    {
    	        usbCcidNoOfBytesToReceive = usbCcidNoOfBytesToReceive - USB_EP_SIZE;
    	        usbCcidOutPacketTrack = USB_CCID_BULK_OUT_SUBSEQUENT_PACKET;
    	        usbCcidBulkOutHandle = USBRxOnePacket(USB_EP_BULK_OUT,(BYTE*)&usbCcidBulkOutEndpoint,USB_EP_SIZE);
                return;
    	    }
    	    else // We have received everything from the host.
    	    {
        	    usbCcidNoOfBytesToReceive = 0;
        	    TransactionCount =0;
        	    usbCcidOutPacketTrack = USB_CCID_BULK_OUT_FIRST_PACKET;
        	}

        }
		
        switch(pUsbCcidApdu->CCID_BulkOutBuffer[0])		//Data arrived, check what kind of command might be in the packet of data.
		{
			////////////////////////////////////////////////////////////////////////////////////
			case USB_CCID_PC_TO_RDR_ICC_POWER_ON:
			{
				if( !SC_CardPresent() ) //if Card is not present
				{
					//Card not present. send error reply
					card_st.Val 		= 0;
					card_st.ICC_Status	= GetCardStatus();
					card_st.CmdStatus	= 1; //Command Failed Code

					pUsbCcidApdu->CCID_BulkInBuffer[0] = USB_CCID_RDR_TO_PC_DATA_BLOCK; 		//Msg Type
					pUsbCcidApdu->CCID_BulkInBuffer[7] = card_st.Val;  			//bStatus
					pUsbCcidApdu->CCID_BulkInBuffer[8] = USB_CCID_ICC_MUTE;					//bError ICC_MUTE
					pUsbCcidApdu->CCID_BulkInBuffer[9] = 0;
                    
                    USBCCIDSendDataToHost(pUsbCcidApdu->CCID_BulkInBuffer, 10 );
				}
				else  //else if Card is Present
				{
					SC_Initialize();
					if( SC_PowerOnATR() ) //Get ATR
					{
//						SC_DoPPS();	//switch baud rate based on ATR setting	
                        if (SC_T0ProtocolType() && !SC_T1ProtocolType())
                            usbCcidProtocolNum = USB_CCID_T0_PROTOCOL; 	
                        else if (!SC_T0ProtocolType() && SC_T1ProtocolType())
                            usbCcidProtocolNum = USB_CCID_T1_PROTOCOL; 
                        			
						card_st.Val 		= 0;
						card_st.ICC_Status	= GetCardStatus();
						card_st.CmdStatus	= 0; //processed without error

					    // ATR success
						pUsbCcidApdu->CCID_BulkInBuffer[0] = USB_CCID_RDR_TO_PC_DATA_BLOCK; 		//Msg Type

						pUsbCcidApdu->CCID_BulkInBuffer[1] = scATRLength;
						pUsbCcidApdu->CCID_BulkInBuffer[2] = 0;
						pUsbCcidApdu->CCID_BulkInBuffer[3] = usbCcidBulkInEndpoint[4] = 0;

						pUsbCcidApdu->CCID_BulkInBuffer[7] = card_st.Val;  //bStatus
						pUsbCcidApdu->CCID_BulkInBuffer[8] = 0;			//bError
						pUsbCcidApdu->CCID_BulkInBuffer[9] = 0;  //no extended APDU support

						for (i = 0; i < scATRLength; i++)
						    pUsbCcidApdu->CCID_BulkInBuffer[10 + i] = scCardATR[i];
						USBCCIDSendDataToHost(pUsbCcidApdu->CCID_BulkInBuffer, scATRLength+10 );
				    }
			        else // ATR Failed
			        {
					    // Reply with Error response
					    card_st.ICC_Status	= 1;  // from CCID Rev 1.1 page 28.  Error codes for Hardware Error
					    card_st.CmdStatus	= 1;  // Command Failed
					    ErrCode     		= USB_CCID_HW_ERROR;  // Hardware Error

					    pUsbCcidApdu->CCID_BulkInBuffer[0] = USB_CCID_RDR_TO_PC_DATA_BLOCK; 		//Msg Type
					    pUsbCcidApdu->CCID_BulkInBuffer[7] = card_st.Val;  //bStatus
					    pUsbCcidApdu->CCID_BulkInBuffer[8] = ErrCode;		//bError
					    pUsbCcidApdu->CCID_BulkInBuffer[9] = 0;
                        USBCCIDSendDataToHost(pUsbCcidApdu->CCID_BulkInBuffer, 10 );
				    }// End of else ATR Failed
			    }// End of else - card is present
			}// End case PC_to_RDR_IccPowerOn:    
			break;

			////////////////////////////////////////////////////////////////////////////////////
			case USB_CCID_PC_TO_RDR_ICC_POWER_OFF:
			    if( pUsbCcidApdu->CCID_BulkOutBuffer[5] == 0 )	// must be slot 0 (for 1 slot reader)
			    {
				    //Do power off sequence if required
				    SC_Shutdown();
				    card_st.ICC_Status	= GetCardStatus();	// bStatus - 0 Card Present and active,
														        //           1 Card Present and inactive,
														        //			 2 Not Present
			    }
			    else //slot # out of range
			    {
				    card_st.ICC_Status	= 2;  // from CCID Rev 1.1 page 28.  Error codes for bad slot umber
				    card_st.CmdStatus	= 1;  // Command Failed
				    ErrCode     		= 5;  // bError Slot Does not exist
			    }

			    pUsbCcidApdu->CCID_BulkInBuffer[0] = 0x81; //Msg Type
			    pUsbCcidApdu->CCID_BulkInBuffer[7] = card_st.Val;  //bStatus
			    pUsbCcidApdu->CCID_BulkInBuffer[8] = ErrCode;		//bError
			    pUsbCcidApdu->CCID_BulkInBuffer[9] = (SC_GetCardState()==SC_STATE_CARD_ACTIVE)?0:1;  //Clock Status: 0 Running, 1 Stopped L, 2 Stopped H
                USBCCIDSendDataToHost(pUsbCcidApdu->CCID_BulkInBuffer, 10 );
            break;

            ////////////////////////////////////////////////////////////////////////////////////
            case USB_CCID_PC_TO_RDR_GET_SLOT_STATUS:
                if( pUsbCcidApdu->CCID_BulkOutBuffer[5] == 0 )	// must be slot 0 (for 1 slot reader)
			    {
				    card_st.ICC_Status	= GetCardStatus();	// bStatus - 0 Card Present and active,
														    //           1 Card Present and inactive,
														    //			 2 Not Present
			    }
			    else //slot # out of range
			    {
				    card_st.ICC_Status	= 2;  // from CCID Rev 1.1 page 28.  Error codes for bad slot umber
				    card_st.CmdStatus	= 1;  // Command Failed
				    ErrCode     		= 5;  // bError Slot Does not exist
			    }

			    pUsbCcidApdu->CCID_BulkInBuffer[0] = USB_CCID_RDR_TO_PC_SLOT_STATUS; //Msg Type
			    pUsbCcidApdu->CCID_BulkInBuffer[7] = card_st.Val;  //bStatus
			    pUsbCcidApdu->CCID_BulkInBuffer[8] = ErrCode;		//bError
			    pUsbCcidApdu->CCID_BulkInBuffer[9] = (SC_GetCardState()==SC_STATE_CARD_ACTIVE)?0:1;  //Clock Status: 0 Running, 1 Stopped L, 2 Stopped H
			    USBCCIDSendDataToHost(pUsbCcidApdu->CCID_BulkInBuffer, 10 );
            break;

            ////////////////////////////////////////////////////////////////////////////////////
			case USB_CCID_PC_TO_RDR_XFR_BLOCK:
			    UsbCcidPcToRdrXfrBlock();
			break;

            ////////////////////////////////////////////////////////////////////////////////////
            
			case USB_CCID_PC_TO_RDR_GET_PARAMETERS:
			    UsbCcidSendRdrToPcParameters(); 
			break;
			////////////////////////////////////////////////////////////////////////////////////
			case USB_CCID_PC_TO_RDR_RESET_PARAMETERS :
			    UsbCcidSendRdrToPcParameters();
			break;
			////////////////////////////////////////////////////////////////////////////////////
			case USB_CCID_PC_TO_RDR_SET_PARAMETERS :
			    if  (SC_GetCardState() == SC_STATE_CARD_ACTIVE)
				{
    				if (SC_T0ProtocolType() && SC_T1ProtocolType())
    				{
    				    usbCcidProtocolNum = pUsbCcidApdu->CCID_BulkOutBuffer[7];  
    				}    
    				ppsData[0] = 0xFF; 
					if (usbCcidProtocolNum == USB_CCID_T0_PROTOCOL)   //if T=0 Protocol
					{
    					//pUsbCcidApdu->CCID_BulkOutBuffer[10]; //Read FI Index
    					//pUsbCcidApdu->CCID_BulkOutBuffer[11]; //bmTCCKST0    
    					//pUsbCcidApdu->CCID_BulkOutBuffer[12]; // Read Guard Time
    					//pUsbCcidApdu->CCID_BulkOutBuffer[13]; // Read WI
    					ppsData[1] = 0x00; 
    					
    	            }
    	            else if (usbCcidProtocolNum == USB_CCID_T1_PROTOCOL) 
    	            {
        	            ppsData[1] = 0x01;
        	            //pUsbCcidApdu->CCID_BulkOutBuffer[10]; //Read FI Index
    					//pUsbCcidApdu->CCID_BulkOutBuffer[11]; //bmTCCKST1    
    					//pUsbCcidApdu->CCID_BulkOutBuffer[12]; // Guard Time
    					//pUsbCcidApdu->CCID_BulkOutBuffer[13]; // bmWaitingIntegersT1
    					//pUsbCcidApdu->CCID_BulkOutBuffer[14]; // bClockStop
    					//pUsbCcidApdu->CCID_BulkOutBuffer[15]; //bIFSC
    					//pUsbCcidApdu->CCID_BulkOutBuffer[16]; //bNadValue
        	        } 
        	        ppsData[2] = ppsData[0] ^ ppsData[1];  
        	        if (SC_T0ProtocolType() && SC_T1ProtocolType()) 
        	        {  		    
    			        if (!SC_DoPPS(ppsData))
    			        {
        		            SC_Shutdown();
        			    }
        			}   
    				ccid_clockstatus = pUsbCcidApdu->CCID_BulkOutBuffer[14]; // Read Clock Stop Status
                }
                UsbCcidSendRdrToPcParameters();				
			break;
		
			#ifndef LOW_PIN_COUNT_USB_DEVELOPMENT_KIT
            ////////////////////////////////////////////////////////////////////////////////////
            case USB_CCID_PC_TO_RDR_ESCAPE:
                // This Command is not supoprted
                pUsbCcidApdu->CCID_BulkInBuffer[0] = USB_CCID_RDR_TO_PC_ESCAPE;
				UsbCcidCommandNotSupported();
                
            break;
			#endif
			
            ////////////////////////////////////////////////////////////////////////////////////
            case USB_CCID_PC_TO_RDR_ICC_CLOCK:
                if( pUsbCcidApdu->CCID_BulkOutBuffer[5] == 0 )	// must be slot 0 (for 1 slot reader)
			    {
					//Do power off sequence if required
				    if (pUsbCcidApdu->CCID_BulkOutBuffer[7] == 0)
					{
				        USB_CCID_RestartClock();//Restart Clock
					}
				    else if (pUsbCcidApdu->CCID_BulkOutBuffer[7] == 1)
				    {
				        if (ccid_clockstatus == 1)
						{
				        	USB_CCID_StopClockWithPinLow(); // Stop with Clock signal Low
						}
				        else if (ccid_clockstatus == 2)
						{
				            USB_CCID_StopClockWithPinHigh();// Stop with Clock signal High
						}
				        else if (ccid_clockstatus == 3)
						{
    				        USB_CCID_StopClockWithPinLow(); // Stop with Clock either High or Low
						}
				     }
				     card_st.ICC_Status	= GetCardStatus();	// bStatus - 0 Card Present and active,
														        //           1 Card Present and inactive,
														        //			 2 Not Present
			    }
			    else //slot # out of range
			    {
				    card_st.ICC_Status	= 2;  // from CCID Rev 1.1 page 28.  Error codes for bad slot umber
				    card_st.CmdStatus	= 1;  // Command Failed
				    ErrCode     		= 5;  // bError Slot Does not exist
			    }
			    pUsbCcidApdu->CCID_BulkInBuffer[0] = USB_CCID_RDR_TO_PC_SLOT_STATUS; //Msg Type
			    pUsbCcidApdu->CCID_BulkInBuffer[7] = card_st.Val;  //bStatus
			    pUsbCcidApdu->CCID_BulkInBuffer[8] = ErrCode;		//bError
			    pUsbCcidApdu->CCID_BulkInBuffer[9] = (SC_GetCardState()==SC_STATE_CARD_ACTIVE)?0:1;  //Clock Status: 0 Running, 1 Stopped L, 2 Stopped H
					
				USBCCIDSendDataToHost(pUsbCcidApdu->CCID_BulkInBuffer, 10 );
            break;

            ////////////////////////////////////////////////////////////////////////////////////
			#ifndef LOW_PIN_COUNT_USB_DEVELOPMENT_KIT
            case USB_CCID_PC_TO_RDR_SECURE :
                // This Command is not supoprted
                pUsbCcidApdu->CCID_BulkInBuffer[0] = USB_CCID_RDR_TO_PC_DATA_BLOCK;
                UsbCcidCommandNotSupported();
            break;

            ////////////////////////////////////////////////////////////////////////////////////
            case USB_CCID_PC_TO_RDR_MECHANICAL:
                // This Command is not supoprted
				pUsbCcidApdu->CCID_BulkInBuffer[0] = USB_CCID_RDR_TO_PC_SLOT_STATUS;
				UsbCcidCommandNotSupported();
            ////////////////////////////////////////////////////////////////////////////////////
            case USB_CCID_PC_TO_RDR_ABORT:
                // This Command is not supoprted
				pUsbCcidApdu->CCID_BulkInBuffer[0] = USB_CCID_RDR_TO_PC_SLOT_STATUS;
				UsbCcidCommandNotSupported();

            ////////////////////////////////////////////////////////////////////////////////////
            case USB_CCID_PC_TO_RDR_SET_DATA_RATE_AND_CLOCK_FREQUENCY:
                // This Command is not supoprted
				pUsbCcidApdu->CCID_BulkInBuffer[0] = USB_CCID_RDR_TO_PC_DATA_RATE_AND_CLOCK_FREQUENCY;
				UsbCcidCommandNotSupported();

            ////////////////////////////////////////////////////////////////////////////////////
            case USB_CCID_PC_TO_RDR_T0APDU :
                // This Command is not supoprted
                pUsbCcidApdu->CCID_BulkInBuffer[0] = USB_CCID_RDR_TO_PC_SLOT_STATUS;
                UsbCcidCommandNotSupported();
            break;
 			#endif
            default:
                pUsbCcidApdu->CCID_BulkInBuffer[0] =  USB_CCID_RDR_TO_PC_SLOT_STATUS;
				#ifndef LOW_PIN_COUNT_USB_DEVELOPMENT_KIT
					UsbCcidCommandNotSupported();  
				#else
					card_st.Val 		= 0;
					card_st.ICC_Status	= GetCardStatus();
					card_st.CmdStatus	= 1; //Command Failed Code
					pUsbCcidApdu->CCID_BulkInBuffer[7] = card_st.Val;  //bStatus
    				pUsbCcidApdu->CCID_BulkInBuffer[8] = USB_CCID_CMD_NOT_SUPPORTED; //bError, Command not supported
					USBCCIDSendDataToHost(pUsbCcidApdu->CCID_BulkInBuffer, 10 );  
				#endif 
            break;
        }
        usbCcidBulkOutHandle = USBRxOnePacket(USB_EP_BULK_OUT,(BYTE*)&usbCcidBulkOutEndpoint,USB_EP_SIZE);
    }
}
void USBCCIDBulkInService(void)
{
    WORD byte_to_send;
    BYTE i;

    USBMaskInterrupts();
    if(USBHandleBusy(usbCcidBulkInHandle)) 
    {
        USBUnmaskInterrupts();
        return;
    }


    if(usbCcidBulkInTrfState == USB_CCID_BULK_IN_COMPLETING)
        usbCcidBulkInTrfState = USB_CCID_BULK_IN_READY;
    
    /*
     * If USB_CCID_BULK_IN_READY state, nothing to do, just return.
     */
    if(usbCcidBulkInTrfState == USB_CCID_BULK_IN_READY)
    {
        USBUnmaskInterrupts();
        return;
    }
    
    /*
     * If USB_CCID_BULK_IN_BUSY_ZLP state, send zero length packet
     */
    if(usbCcidBulkInTrfState == USB_CCID_BULK_IN_BUSY_ZLP)
    {
        usbCcidBulkInHandle = USBTxOnePacket(USB_EP_BULK_IN,NULL,0);
        usbCcidBulkInTrfState = USB_CCID_BULK_IN_COMPLETING;
    }
    else if(usbCcidBulkInTrfState == USB_CCID_BULK_IN_BUSY) 
    {
        /*
         * First, have to figure out how many byte of data to send.
         */
    	if(usbCcidBulkInLen > sizeof(usbCcidBulkInEndpoint)) 
    	    byte_to_send = sizeof(usbCcidBulkInEndpoint);
    	else
    	    byte_to_send = usbCcidBulkInLen;
            
        /*
         * Subtract the number of bytes just about to be sent from the total.
         */
    	usbCcidBulkInLen = usbCcidBulkInLen - byte_to_send;
    	  
        pCCIDDst.bRam = (BYTE*)usbCcidBulkInEndpoint; // Set destination pointer
        
        i = byte_to_send;
       
        while(i)
        {
            *pCCIDDst.bRam = *pCCIDSrc.bRam;
            pCCIDDst.bRam++;
            pCCIDSrc.bRam++;
            i--;
        }//end while(byte_to_send._word)
 
        
        /*
         * Lastly, determine if a zero length packet state is necessary.
         * See explanation in USB Specification 2.0: Section 5.8.3
         */
        if(usbCcidBulkInLen == 0)
        {
            if(byte_to_send == USB_EP_SIZE)
                usbCcidBulkInTrfState = USB_CCID_BULK_IN_BUSY_ZLP;
            else
                usbCcidBulkInTrfState = USB_CCID_BULK_IN_COMPLETING;
        }//end if(usbCcidBulkInLen...)
        usbCcidBulkInHandle = USBTxOnePacket(USB_EP_BULK_IN,(BYTE*)usbCcidBulkInEndpoint,byte_to_send);

    }//end if(cdc_tx_sate == USB_CCID_BULK_IN_BUSY)
    USBUnmaskInterrupts();
}//end USBCCIDBulkInService
Пример #12
0
void hidTxOnePacket(void)
{
    hidTxHandle = USBTxOnePacket(HID_EP, (BYTE*)sndHidDataBuffer, 64);
}
Пример #13
0
void midiTxOnePacket(BYTE *packet, BYTE len)
{
    midiTxHandle = USBTxOnePacket(MIDI_EP, packet, len);
}
/*********************************************************************
* Function: void APP_DeviceAudioMIDITasks(void);
*
* Overview: Keeps the Custom HID demo running.
*
* PreCondition: The demo should have been initialized and started via
*   the APP_DeviceAudioMIDIInitialize() and APP_DeviceAudioMIDIStart() demos
*   respectively.
*
* Input: None
*
* Output: None
*
********************************************************************/
void APP_DeviceAudioMIDITasks()
{
    /* If the device is not configured yet, or the device is suspended, then
     * we don't need to run the demo since we can't send any data.
     */
    if( (USBGetDeviceState() < CONFIGURED_STATE) ||
        (USBIsDeviceSuspended() == true))
    {
        return;
    }

    if(!USBHandleBusy(USBRxHandle))
    {
        //We have received a MIDI packet from the host, process it and then
        //  prepare to receive the next packet

        //INSERT MIDI PROCESSING CODE HERE

        //Get ready for next packet (this will overwrite the old data)
        USBRxHandle = USBRxOnePacket(USB_DEVICE_AUDIO_MIDI_ENDPOINT,(uint8_t*)&ReceivedDataBuffer,64);
    }

    /* If the user button is pressed... */
    if(BUTTON_IsPressed(BUTTON_DEVICE_AUDIO_MIDI) == true)
    {
        /* and we haven't sent a transmission in the past 100ms... */
        if(msCounter == 0)
        {
            /* and we have sent the NOTE_OFF for the last note... */
            if(sentNoteOff == true)
            {
                /* and we aren't currently trying to transmit data... */
                if(!USBHandleBusy(USBTxHandle))
                {
                    //Then reset the 100ms counter
                    msCounter = 100;

                    midiData.Val = 0;   //must set all unused values to 0 so go ahead
                                        //  and set them all to 0

                    midiData.CableNumber = 0;
                    midiData.CodeIndexNumber = MIDI_CIN_NOTE_ON;
                    midiData.DATA_0 = 0x90;         //Note on
                    midiData.DATA_1 = pitch;         //pitch
                    midiData.DATA_2 = 0x7F;  //velocity

                    USBTxHandle = USBTxOnePacket(USB_DEVICE_AUDIO_MIDI_ENDPOINT,(uint8_t*)&midiData,4);

                    /* we now need to send the NOTE_OFF for this note. */
                    sentNoteOff = false;
                }
            }
        }
    }
    else
    {
        if(msCounter == 0)
        {
            if(sentNoteOff == false)
            {
                if(!USBHandleBusy(USBTxHandle))
                {
                    //Debounce counter for 100ms
                    msCounter = 100;

                    midiData.Val = 0;   //must set all unused values to 0 so go ahead
                                        //  and set them all to 0

                    midiData.CableNumber = 0;
                    midiData.CodeIndexNumber = MIDI_CIN_NOTE_ON;
                    midiData.DATA_0 = 0x90;     //Note off
                    midiData.DATA_1 = pitch++;     //pitch
                    midiData.DATA_2 = 0x00;        //velocity

                    if(pitch == 0x49)
                    {
                        pitch = 0x3C;
                    }

                    USBTxHandle = USBTxOnePacket(USB_DEVICE_AUDIO_MIDI_ENDPOINT,(uint8_t*)&midiData,4);
                    sentNoteOff = true;
                }
            }
        }
    }
}
BYTE MSDReadHandler(void)
{
    switch(MSDReadState)
    {
        case MSD_READ10_WAIT:
        	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];

            //Assume success initially, msd_csw.bCSWStatus will get set to 0x01 
            //or 0x02 later if an error is detected during the actual read sequence.        	
        	msd_csw.bCSWStatus=0x0;
        	msd_csw.dCSWDataResidue=0x0;
        	
            MSDReadState = MSD_READ10_BLOCK;
            //Fall through to MSD_READ_BLOCK
        case MSD_READ10_BLOCK:
            if(TransferLength.Val == 0)
            {
                MSDReadState = MSD_READ10_WAIT;
                break;
            }
            
            TransferLength.Val--;					// we have read 1 LBA
            MSDReadState = MSD_READ10_SECTOR;
            //Fall through to MSD_READ10_SECTOR
        case MSD_READ10_SECTOR:
            //if the old data isn't completely sent yet
            if(USBHandleBusy(USBMSDInHandle) != 0)
            {
                break;
            }
            
            //Try to read a sector worth of data from the media, but check for
            //possible errors.
    		if(LUNSectorRead(LBA.Val, (BYTE*)&msd_buffer[0]) != TRUE)
    		{
				if(MSDRetryAttempt < MSD_FAILED_READ_MAX_ATTEMPTS)
				{
				    MSDRetryAttempt++;
                    break;
				}
				else
				{  
    				//Too many consecutive failed reads have occurred.  Need to
    				//give up and abandon the sector read attempt; something must
    				//be wrong and we don't want to get stuck in an infinite loop.
    				//Need to indicate to the host that a device error occurred.
    				//However, we can't send the CSW immediately, since the host
    				//still expects to receive sector read data on the IN endpoint 
    				//first.  Therefore, we still send dummy bytes, before
    				//we send the CSW with the failed status in it.
    				msd_csw.bCSWStatus=0x01;		// Error 0x01 Refer page#18
                                                    // of BOT specifications
                    //Set error status sense keys, so the host can check them later
                    //to determine how to proceed.
                    gblSenseData[LUN_INDEX].SenseKey=S_MEDIUM_ERROR;
			        gblSenseData[LUN_INDEX].ASC=ASC_NO_ADDITIONAL_SENSE_INFORMATION;
			        gblSenseData[LUN_INDEX].ASCQ=ASCQ_NO_ADDITIONAL_SENSE_INFORMATION;
                }
            }//else we successfully read a sector worth of data from our media

            LBA.Val++;
			msd_csw.dCSWDataResidue=BLOCKLEN_512;//in order to send the
                                                 //512 bytes of data read
                                                 
            ptrNextData=(BYTE *)&msd_buffer[0];
            
            MSDReadState = MSD_READ10_TX_SECTOR;
    
            //Fall through to MSD_READ10_TX_SECTOR
        case MSD_READ10_TX_SECTOR:
            if(msd_csw.dCSWDataResidue == 0)
            {
                MSDReadState = MSD_READ10_BLOCK;
                break;
            }
            
            MSDReadState = MSD_READ10_TX_PACKET;
            //Fall through to MSD_READ10_TX_PACKET
            
        case MSD_READ10_TX_PACKET:
    		/* Write next chunk of data to EP Buffer and send */
            
            //Make sure the endpoint is available before using it.
            if(USBHandleBusy(USBMSDInHandle))
            {
                break;
            }
            //Prepare the USB module to send an IN transaction worth of data to the host.
            USBMSDInHandle = USBTxOnePacket(MSD_DATA_IN_EP,ptrNextData,MSD_IN_EP_SIZE);
            
 			MSDReadState = MSD_READ10_TX_SECTOR;

    		gblCBW.dCBWDataTransferLength-=	MSD_IN_EP_SIZE;
    		msd_csw.dCSWDataResidue-=MSD_IN_EP_SIZE;
    		ptrNextData+=MSD_IN_EP_SIZE;
            break;
        
        default:
            //Illegal condition, should never occur.  In the event that it ever
            //did occur anyway, try to notify the host of the error.
            msd_csw.bCSWStatus=0x02;  //indicate "Phase Error"
            //Advance state machine
            MSDReadState = MSD_READ10_WAIT;
    }
    
    return MSDReadState;
}
/*********************************************************************************
  Function:
        BYTE MSDTasks(void)
    
  Summary:
    This function runs the MSD class state machines and all of its
    sub-systems. This function should be called periodically once the
    device is in the configured state in order to keep the MSD state
    machine going.
  Description:
    This function runs the MSD class state machines and all of its
    sub-systems. This function should be called periodically once the
    device is in the configured state in order to keep the MSD state
    machine going.
    
    Typical Usage:
    <code>
    void main(void)
    {
        USBDeviceInit();
        while(1)
        {
            USBDeviceTasks();
            if((USBGetDeviceState() \< CONFIGURED_STATE) ||
               (USBIsDeviceSuspended() == TRUE))
            {
                //Either the device is not configured or we are suspended
                //  so we don't want to do execute any application code
                continue;   //go back to the top of the while loop
            }
            else
            {
                //Keep the MSD state machine going
                MSDTasks();
    
                //Run application code.
                UserApplication();
            }
        }
    }
    </code>
  Conditions:
    None
  Return Values:
    BYTE -  the current state of the MSD state machine the valid values are
            defined in MSD.h under the MSDTasks state machine declaration section.
            The possible values are the following\:
            * MSD_WAIT
            * MSD_DATA_IN
            * MSD_DATA_OUT
            * MSD_SEND_CSW
  Remarks:
    None                                                                          
  *********************************************************************************/	
BYTE MSDTasks(void)
{
    BYTE i;
    
    switch(MSD_State)
    {
        case MSD_WAIT:
        {
            //If the MSD state machine is waiting for something to happen
            if(!USBHandleBusy(USBMSDOutHandle))
            {
        		//If we received an OUT packet from the host
                //  then copy the data from the buffer to a global
                //  buffer so that we can keep the information but
                //  reuse the buffer
        		gblCBW.dCBWSignature=msd_cbw.dCBWSignature;					
        		gblCBW.dCBWTag=msd_cbw.dCBWTag;
        		gblCBW.dCBWDataTransferLength=msd_cbw.dCBWDataTransferLength;
            	gblCBW.bCBWFlags=msd_cbw.bCBWFlags;
            	gblCBW.bCBWLUN=msd_cbw.bCBWLUN;
        	    gblCBW.bCBWCBLength=msd_cbw.bCBWCBLength;		// 3 MSB are zero

            	for (i=0;i<msd_cbw.bCBWCBLength;i++)
            	{
            		gblCBW.CBWCB[i]=msd_cbw.CBWCB[i];
                }
            		
                gblCBWLength=USBHandleGetLength(USBMSDOutHandle);

        	    //If this CBW is valid?
        		if ((gblCBWLength==MSD_CBW_SIZE)&&(gblCBW.dCBWSignature==0x43425355)) 
            	{
                    //Is this CBW meaningful?	
       				if((gblCBW.bCBWLUN<=0x0f)
               		&&(gblCBW.bCBWCBLength<=0x10)
               		&&(gblCBW.bCBWCBLength>=0x01)
               		&&(gblCBW.bCBWFlags==0x00||gblCBW.bCBWFlags==0x80)) 
            		{
                		//Prepare the CSW to be sent
                    	msd_csw.dCSWTag=gblCBW.dCBWTag;
                    	msd_csw.dCSWSignature=0x53425355;
                    	
                    	//Keep track of retry attempts, in case of temporary failures
                    	//during processing of a command.
                    	MSDRetryAttempt = 0;
                    	
                    	//Check the command.  With the exception of the REQUEST_SENSE
                    	//command, we should reset the sense key info for each new command block.
                    	//Assume the command will get processed successfully (and hence "NO SENSE" 
                    	//response, which is used for success cases), unless handler code
                    	//later on detects some kind of error.  If it does, it should
                    	//update the sense keys to reflect the type of error detected,
                    	//prior to sending the CSW.
                    	if(gblCBW.CBWCB[0] != MSD_REQUEST_SENSE)
                    	{
                      		gblSenseData[LUN_INDEX].SenseKey=S_NO_SENSE;
        			        gblSenseData[LUN_INDEX].ASC=ASC_NO_ADDITIONAL_SENSE_INFORMATION;
        			        gblSenseData[LUN_INDEX].ASCQ=ASCQ_NO_ADDITIONAL_SENSE_INFORMATION;
    			        }
                    	
        				/* If direction is device to host*/
        				if (gblCBW.bCBWFlags==0x80)
        				{
        					MSD_State=MSD_DATA_IN;
        				}
        				else if (gblCBW.bCBWFlags==0x00) 
            			{
        					/* If direction is host to device*/
        					/* prepare to read data in msd_buffer */
            			    MSD_State=MSD_DATA_OUT;
        				}        								
        			}
        		}
            }
            break;
        }
        case MSD_DATA_IN:
            if(MSDProcessCommand() == MSD_COMMAND_WAIT)
            {
                // Done processing the command, send the status
                MSD_State = MSD_SEND_CSW;
            }
            break;
        case MSD_DATA_OUT:
            if(MSDProcessCommand() == MSD_COMMAND_WAIT)
            {
    			/* Finished receiving the data prepare and send the status */
    		  	if ((msd_csw.bCSWStatus==0x00)&&(msd_csw.dCSWDataResidue!=0)) 
    		  	{
    		  		msd_csw.bCSWStatus=0x02;
    		    }
                MSD_State = MSD_SEND_CSW;
            }
            break;
        case MSD_SEND_CSW:
            if(USBHandleBusy(USBMSDInHandle))
            {
                //The TX buffer is not ready to send the status yet.
                break;
            }
            
            USBMSDInHandle = USBTxOnePacket(MSD_DATA_IN_EP,(BYTE*)&msd_csw,MSD_CSW_SIZE);
            
            //Get ready for next command to come in
            if(!USBHandleBusy(USBMSDOutHandle))
            {
                USBMSDOutHandle = USBRxOnePacket(MSD_DATA_OUT_EP,(BYTE*)&msd_cbw,sizeof(msd_cbw));
            }
        
           	MSD_State=MSD_WAIT;
            break;
            
        default:
            //Illegal condition that should not happen, but might occur if the
            //device firmware incorrectly calls MSDTasks() prior to calling
            //USBMSDInit() during the set-configuration portion of enumeration.
            MSD_State=MSD_WAIT;
    }
    
    return MSD_State;
}