Beispiel #1
0
/*******************************************************************
 * Function:        void USBCBInitEP(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        This function is called when the device becomes
 *                  initialized, which occurs after the host sends a
 *                  SET_CONFIGURATION (wValue not = 0) request.  This
 *                  callback function should initialize the endpoints
 *                  for the device's usage according to the current
 *                  configuration.
 *
 * Note:            None
 *******************************************************************/
void USBCBInitEP(void)
{
    //enable the HID endpoint
    USBEnableEndpoint(HID_EP, USB_IN_ENABLED | USB_OUT_ENABLED | USB_HANDSHAKE_ENABLED | USB_DISALLOW_SETUP);
    //Re-arm the OUT endpoint for the next packet
    //USBOutHandle = HIDRxPacket(HID_EP | MIDI_EP,(BYTE*)&ReceivedHidDataBuffer,64);
    hidRxHandle = USBRxOnePacket(HID_EP, (BYTE*)&rcvHidDataBuffer, 64);

    //enable the HID endpoint
    USBEnableEndpoint(MIDI_EP, USB_OUT_ENABLED | USB_IN_ENABLED | USB_HANDSHAKE_ENABLED | USB_DISALLOW_SETUP);
    //Re-arm the OUT endpoint for the next packet
    midiRxHandle = USBRxOnePacket(MIDI_EP, (BYTE*)&rcvMidiDataBuffer, 64);
}
/**************************************************************************
  Function:
        void USBCCIDInitEP(void)
    
  Summary:
    This function initializes the CCID function driver. This function should
    be called after the SET_CONFIGURATION command.
  Description:
    This function initializes the CCID function driver. This function sets
    the default line coding (baud rate, bit parity, number of data bits,
    and format). This function also enables the endpoints and prepares for
    the first transfer from the host.
    
    This function should be called after the SET_CONFIGURATION command.
    This is most simply done by calling this function from the
    USBCBInitEP() function.
    
    Typical Usage:
    <code>
        void USBCBInitEP(void)
        {
            USBCCIDInitEP();
        }
    </code>
  Conditions:
    None
  Remarks:
    None                                                                   
  **************************************************************************/
 void USBCCIDInitEP(void)
 {
   
    usbCcidBulkInTrfState = USB_CCID_BULK_IN_READY;
    usbCcidBulkInLen =0;
    
    /*
     * 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.
     */
     
    USBEnableEndpoint(USB_EP_INT_IN,USB_IN_ENABLED|USB_HANDSHAKE_ENABLED|USB_DISALLOW_SETUP);
    USBEnableEndpoint(USB_EP_BULK_IN,USB_IN_ENABLED|USB_OUT_ENABLED|USB_HANDSHAKE_ENABLED|USB_DISALLOW_SETUP);

    usbCcidBulkInHandle = 0;
	usbCcidInterruptInHandle = 0;
    usbCcidBulkOutHandle = USBRxOnePacket(USB_EP_BULK_OUT,(BYTE*)&usbCcidBulkOutEndpoint,USB_EP_SIZE);
    
}//end CCIDInitEP
Beispiel #3
0
/**********************************************************************************
  Function:
        BYTE getsUSBUSART(char *buffer, BYTE len)
    
  Summary:
    getsUSBUSART copies a string of BYTEs received through USB CDC Bulk OUT
    endpoint to a user's specified location. It is a non-blocking function.
    It does not wait for data if there is no data available. Instead it
    returns '0' to notify the caller that there is no data available.

  Description:
    getsUSBUSART copies a string of BYTEs received through USB CDC Bulk OUT
    endpoint to a user's specified location. It is a non-blocking function.
    It does not wait for data if there is no data available. Instead it
    returns '0' to notify the caller that there is no data available.
    
    Typical Usage:
    <code>
        BYTE numBytes;
        BYTE buffer[64]
    
        numBytes = getsUSBUSART(buffer,sizeof(buffer)); //until the buffer is free.
        if(numBytes \> 0)
        {
            //we received numBytes bytes of data and they are copied into
            //  the "buffer" variable.  We can do something with the data
            //  here.
        }
    </code>
  Conditions:
    Value of input argument 'len' should be smaller than the maximum
    endpoint size responsible for receiving bulk data from USB host for CDC
    class. Input argument 'buffer' should point to a buffer area that is
    bigger or equal to the size specified by 'len'.
  Input:
    buffer -  Pointer to where received BYTEs are to be stored
    len -     The number of BYTEs expected.
                                                                                   
  **********************************************************************************/
BYTE getsUSBUSART(char *buffer, BYTE len)
{
    cdc_rx_len = 0;
    
    if(!USBHandleBusy(CDCDataOutHandle))
    {
        /*
         * Adjust the expected number of BYTEs to equal
         * the actual number of BYTEs received.
         */
        if(len > USBHandleGetLength(CDCDataOutHandle))
            len = USBHandleGetLength(CDCDataOutHandle);
        
        /*
         * Copy data from dual-ram buffer to user's buffer
         */
        for(cdc_rx_len = 0; cdc_rx_len < len; cdc_rx_len++)
            buffer[cdc_rx_len] = cdc_data_rx[cdc_rx_len];

        /*
         * Prepare dual-ram buffer for next OUT transaction
         */

        CDCDataOutHandle = USBRxOnePacket(CDC_DATA_EP,(BYTE*)&cdc_data_rx,sizeof(cdc_data_rx));

    }//end if
    
    return cdc_rx_len;
    
}//end getsUSBUSART
/******************************************************************************
  Function:
    void USBMSDInit(void)
    
  Summary:
    This routine initializes the MSD class packet handles, prepares to
    receive a MSD packet, and initializes the MSD state machine. This
    \function should be called once after the device is enumerated.

  Description:
    This routine initializes the MSD class packet handles, prepares to
    receive a MSD packet, and initializes the MSD state machine. This
    \function should be called once after the device is enumerated.
    
    Typical Usage:
    <code>
    void USBCBInitEP(void)
    {
        USBEnableEndpoint(MSD_DATA_IN_EP,USB_IN_ENABLED|USB_OUT_ENABLED|USB_HANDSHAKE_ENABLED|USB_DISALLOW_SETUP);
        USBMSDInit();
    }
    </code>
  Conditions:
    The device should already be enumerated with a configuration that
    supports MSD before calling this function.
    
  Paramters: None

  Remarks:
    None                                                                                                          
  ****************************************************************************/	
void USBMSDInit(void)
{
    USBMSDInHandle = 0;
    USBMSDOutHandle = USBRxOnePacket(MSD_DATA_OUT_EP,(BYTE*)&msd_cbw,MSD_OUT_EP_SIZE);
    MSD_State=MSD_WAIT;
    gblNumBLKS.Val = 0;
    gblBLKLen.Val = 0;

    gblMediaPresent = 0;

    //For each of the possible logical units
    for(gblCBW.bCBWLUN=0;gblCBW.bCBWLUN<(MAX_LUN + 1);gblCBW.bCBWLUN++)
    {
        //clear all of the soft detach variables
        SoftDetach[gblCBW.bCBWLUN] =  FALSE;

        //see if the media is attached
        if(LUNMediaDetect())
        {
            //initialize the media
            if(LUNMediaInitialize())
            {
                //if the media was present and successfully initialized
                //  then mark and indicator that the media is ready
                gblMediaPresent |= (1<<gblCBW.bCBWLUN);
            }
        }
        ResetSenseData();
    }
}
Beispiel #5
0
/**************************************************************************
  Function:
        void CDCInitEP(void)
    
  Summary:
    This function initializes the CDC function driver. This function should
    be called after the SET_CONFIGURATION command.
  Description:
    This function initializes the CDC function driver. This function sets
    the default line coding (baud rate, bit parity, number of data bits,
    and format). This function also enables the endpoints and prepares for
    the first transfer from the host.
    
    This function should be called after the SET_CONFIGURATION command.
    This is most simply done by calling this function from the
    USBCBInitEP() function.
    
    Typical Usage:
    <code>
        void USBCBInitEP(void)
        {
            CDCInitEP();
        }
    </code>
  Conditions:
    None
  Remarks:
    None                                                                   
  **************************************************************************/
void CDCInitEP(void)
{
   	//Abstract line coding information
   	line_coding.dwDTERate.Val = 19200;      // baud rate
   	line_coding.bCharFormat = 0x00;             // 1 stop bit
   	line_coding.bParityType = 0x00;             // None
   	line_coding.bDataBits = 0x08;               // 5,6,7,8, or 16

    cdc_trf_state = CDC_TX_READY;
    cdc_rx_len = 0;
    
    /*
     * 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.
     */
    USBEnableEndpoint(CDC_COMM_EP,USB_IN_ENABLED|USB_HANDSHAKE_ENABLED|USB_DISALLOW_SETUP);
    USBEnableEndpoint(CDC_DATA_EP,USB_IN_ENABLED|USB_OUT_ENABLED|USB_HANDSHAKE_ENABLED|USB_DISALLOW_SETUP);

    CDCDataOutHandle = USBRxOnePacket(CDC_DATA_EP,(BYTE*)&cdc_data_rx,sizeof(cdc_data_rx));
    CDCDataInHandle = NULL;
}//end CDCInitEP
Beispiel #6
0
/*******************************************************************
 * Function:        void USBCBInitEP(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        This function is called when the device becomes
 *                  initialized, which occurs after the host sends a
 * 					SET_CONFIGURATION (wValue not = 0) request.  This
 *					callback function should initialize the endpoints
 *					for the device's usage according to the current
 *					configuration.
 *
 * Note:            None
 *******************************************************************/
void USBCBInitEP(void)
{
    //enable the HID endpoint
    USBEnableEndpoint(MIDI_EP,USB_OUT_ENABLED|USB_IN_ENABLED|USB_HANDSHAKE_ENABLED|USB_DISALLOW_SETUP);

    //Re-arm the OUT endpoint for the next packet
    USBRxHandle = USBRxOnePacket(MIDI_EP,(BYTE*)&ReceivedDataBuffer,64);
}
Beispiel #7
0
void FlashInitEP(void)
{
	FlashTxState = FLASH_TX_READY;

   	USBEnableEndpoint(NAND_TX_EP,USB_IN_ENABLED|USB_HANDSHAKE_ENABLED|USB_DISALLOW_SETUP);
    USBEnableEndpoint(NAND_RX_EP,USB_OUT_ENABLED|USB_HANDSHAKE_ENABLED|USB_DISALLOW_SETUP);

    FlashDataOutHandle = USBRxOnePacket(NAND_RX_EP,(BYTE*)&FlashRxBuffer,sizeof(FlashRxBuffer));
    FlashDataInHandle = NULL;
}
Beispiel #8
0
/**************************************************************************
  Function:
        void CDCInitEP(void)
    
  Summary:
    This function initializes the CDC function driver. This function should
    be called after the SET_CONFIGURATION command (ex: within the context of
    the USBCBInitEP() function).
  Description:
    This function initializes the CDC function driver. This function sets
    the default line coding (baud rate, bit parity, number of data bits,
    and format). This function also enables the endpoints and prepares for
    the first transfer from the host.
    
    This function should be called after the SET_CONFIGURATION command.
    This is most simply done by calling this function from the
    USBCBInitEP() function.
    
    Typical Usage:
    <code>
        void USBCBInitEP(void)
        {
            CDCInitEP();
        }
    </code>
  Conditions:
    None
  Remarks:
    None                                                                   
  **************************************************************************/
void CDCInitEP(void)
{
   	//Abstract line coding information
   	line_coding.dwDTERate.Val = 19200;      // baud rate
   	line_coding.bCharFormat = 0x00;             // 1 stop bit
   	line_coding.bParityType = 0x00;             // None
   	line_coding.bDataBits = 0x08;               // 5,6,7,8, or 16

    cdc_rx_len = 0;
    
    /*
     * 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.
     */
    USBEnableEndpoint(CDC_COMM_EP,USB_IN_ENABLED|USB_HANDSHAKE_ENABLED|USB_DISALLOW_SETUP);
    USBEnableEndpoint(CDC_DATA_EP,USB_IN_ENABLED|USB_OUT_ENABLED|USB_HANDSHAKE_ENABLED|USB_DISALLOW_SETUP);

    CDCDataOutHandle = USBRxOnePacket(CDC_DATA_EP,(BYTE*)&cdc_data_rx,sizeof(cdc_data_rx));
    CDCDataInHandle = NULL;

    #if defined(USB_CDC_SUPPORT_DSR_REPORTING)
      	CDCNotificationInHandle = NULL;
        mInitDTSPin();  //Configure DTS as a digital input
      	SerialStateBitmap.byte = 0x00;
      	OldSerialStateBitmap.byte = !SerialStateBitmap.byte;    //To force firmware to send an initial serial state packet to the host.
        //Prepare a SerialState notification element packet (contains info like DSR state)
        SerialStatePacket.bmRequestType = 0xA1; //Always 0xA1 for this type of packet.
        SerialStatePacket.bNotification = SERIAL_STATE;
        SerialStatePacket.wValue = 0x0000;  //Always 0x0000 for this type of packet
        SerialStatePacket.wIndex = CDC_COMM_INTF_ID;  //Interface number  
        SerialStatePacket.SerialState.byte = 0x00;
        SerialStatePacket.Reserved = 0x00;
        SerialStatePacket.wLength = 0x02;   //Always 2 bytes for this type of packet    
        CDCNotificationHandler();
  	#endif
  	
  	#if defined(USB_CDC_SUPPORT_DTR_SIGNALING)
  	    mInitDTRPin();
  	#endif
  	
  	#if defined(USB_CDC_SUPPORT_HARDWARE_FLOW_CONTROL)
  	    mInitRTSPin();
  	    mInitCTSPin();
  	#endif
    
    cdc_trf_state = CDC_TX_READY;
}//end CDCInitEP
/*********************************************************************
* Function: void APP_DeviceAudioMIDIInitialize(void);
*
* Overview: Initializes the demo code
*
* PreCondition: None
*
* Input: None
*
* Output: None
*
********************************************************************/
void APP_DeviceAudioMIDIInitialize()
{
    USBTxHandle = NULL;
    USBRxHandle = NULL;

    pitch = 0x3C;
    sentNoteOff = true;

    msCounter = 0;

    //enable the HID endpoint
    USBEnableEndpoint(USB_DEVICE_AUDIO_MIDI_ENDPOINT,USB_OUT_ENABLED|USB_IN_ENABLED|USB_HANDSHAKE_ENABLED|USB_DISALLOW_SETUP);

    //Re-arm the OUT endpoint for the next packet
    USBRxHandle = USBRxOnePacket(USB_DEVICE_AUDIO_MIDI_ENDPOINT,(uint8_t*)&ReceivedDataBuffer,64);
}
Beispiel #10
0
void FlashDataWrite()
{
	BYTE *pData = (BYTE *) &FlashRxBuffer;
	BYTE len;

	if (gCommandProgress==0) {
		gGlobalStatus = XNANDErase(gCmdArgA << 5);
		gNextBlock = gCmdArgA << 5;
		gWordsLeft = 0x84;
		gBytesWritten = 0;
		XNANDWriteStart();
		gCommandProgress = 1;
	}

	if (USBHandleBusy(FlashDataOutHandle)) 
		return;
	
	len = USBHandleGetLength(FlashDataOutHandle);
	len/= 4;

	while (len) {
		BYTE writeNow = len > gWordsLeft?gWordsLeft:len;

		XNANDWriteProcess(pData, writeNow);
		pData += writeNow*4;
		len -= writeNow;
		gWordsLeft -= writeNow;

		if (gWordsLeft == 0) {
			gGlobalStatus |= XNANDWriteExecute(gNextBlock);
			gNextBlock++;
			gWordsLeft = 0x84;
			XNANDWriteStart();
			gBytesWritten += 0x210;
		}
	}

    FlashDataOutHandle = USBRxOnePacket(NAND_RX_EP,(BYTE*)&FlashRxBuffer,sizeof(FlashRxBuffer));

	if (gBytesWritten == gCmdArgB)
		gCurrentCommand = 0xFF;
}
Beispiel #11
0
/**********************************************************************************
  Function:
    bool USBCDCEventHandler(USB_EVENT event, void *pdata, uint16_t size)
    
  Summary:
    Handles events from the USB stack, which may have an effect on the CDC 
    endpoint(s).

  Description:
    Handles events from the USB stack.  This function should be called when 
    there is a USB event that needs to be processed by the CDC driver.
    
  Conditions:
    Value of input argument 'len' should be smaller than the maximum
    endpoint size responsible for receiving bulk data from USB host for CDC
    class. Input argument 'buffer' should point to a buffer area that is
    bigger or equal to the size specified by 'len'.
  Input:
    event - the type of event that occured
    pdata - pointer to the data that caused the event
    size - the size of the data that is pointed to by pdata
                                                                                   
  **********************************************************************************/
bool USBCDCEventHandler(USB_EVENT event, void *pdata, uint16_t size)
{
    switch( (uint16_t)event )
    {  
        case EVENT_TRANSFER_TERMINATED:
            if(pdata == CDCDataOutHandle)
            {
                CDCDataOutHandle = USBRxOnePacket(CDC_DATA_EP,(uint8_t*)&cdc_data_rx,sizeof(cdc_data_rx));
            }
            if(pdata == CDCDataInHandle)
            {
                //flush all of the data in the CDC buffer
                cdc_trf_state = CDC_TX_READY;
                cdc_tx_len = 0;
            }
            break;
        default:
            return false;
    }      
    return true;
}
Beispiel #12
0
/**********************************************************************************
  Function:
    BOOL USBCDCEventHandler(USB_EVENT event, void *pdata, WORD size)
    
  Summary:
    Handles events from the USB stack, which may have an effect on the CDC 
    endpoint(s).

  Description:
    Handles events from the USB stack.  This function should be called when 
    there is a USB event that needs to be processed by the CDC driver.
    
  Conditions:
    Value of input argument 'len' should be smaller than the maximum
    endpoint size responsible for receiving bulk data from USB host for CDC
    class. Input argument 'buffer' should point to a buffer area that is
    bigger or equal to the size specified by 'len'.
  Input:
    event - the type of event that occured
    pdata - pointer to the data that caused the event
    size - the size of the data that is pointed to by pdata
                                                                                   
  **********************************************************************************/
BOOL USBCDCEventHandler(USB_EVENT event, void *pdata, WORD size)
{
    switch( (INT)event )
    {  
        case EVENT_TRANSFER_TERMINATED:
            if(pdata == CDCDataOutHandle)
            {
                CDCDataOutHandle = USBRxOnePacket(CDC_DATA_EP,(BYTE*)&cdc_data_rx,sizeof(cdc_data_rx));  
            }
            if(pdata == CDCDataInHandle)
            {
                //flush all of the data in the CDC buffer
                cdc_trf_state = CDC_TX_READY;
                cdc_tx_len = 0;
            }
            break;
        default:
            return FALSE;
    }      
    return TRUE; 
}
/*********************************************************************************
  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;
}
/*********************************************************************
* 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;
                }
            }
        }
    }
}
USB_HANDLE ChipKITUSBRxOnePacket(BYTE ep, BYTE* data, WORD len)
{
	return(USBRxOnePacket(ep, data, len));
}
Beispiel #16
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);
    }
}
Beispiel #17
0
void midiRxOnePacket(void)
{
    midiRxHandle = USBRxOnePacket(MIDI_EP, (BYTE*)&rcvMidiDataBuffer[0], 64);
}
Beispiel #18
0
void hidRxOnePacket(void)
{
    hidRxHandle = USBRxOnePacket(HID_EP, (BYTE*)&rcvHidDataBuffer[0], 64);
}
Beispiel #19
0
/********************************************************************
 * Function:        void ProcessIO(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        This function is a place holder for other user
 *                  routines. It is a mixture of both USB and
 *                  non-USB tasks.
 *
 * Note:            None
 *******************************************************************/
void ProcessIO(void)
{

    // User Application USB tasks
    if((USBDeviceState < CONFIGURED_STATE)||(USBSuspendControl==1)) 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

		BOOL note_stealing = FALSE;
		static BYTE note;
		int channel;
		BYTE oldest_channel;
		unsigned long lowest_counter;
		BOOL duplicate_note = FALSE;
		float bent_note;
		unsigned char bend_value;

		USB_AUDIO_MIDI_EVENT_PACKET *packet = ReceivedDataBuffer; // suspicious pointer conversion, yada yada
	
		// run through the complete buffer (16 packets x 4 bytes) and process MIDI messages
		int buffer = 16; while(buffer--)
		{
			switch(packet->DATA_0 & MIDI_MESSAGE_MASK)
			{
				case MIDI_NOTE_ON:

					if(note_stealing)
					{
						// Note stealing logic: find the channel with the lowest steal counter,
						// and reassign it to the newest note on command. In the event of a
						// tie, channel order decides.
	
						oldest_channel = 0;
						lowest_counter = 0xFFFFFFFF;
	
						note = packet->DATA_1;
						
						channel = CHANNELS;
						while(channel--)
						{
							if(Generator[channel].Active == TRUE)
								Generator[channel].StealTimer--;
	
							if(Generator[channel].MidiNote == note && Generator[channel].Active == TRUE)
								duplicate_note = TRUE;
	
							if(Generator[channel].StealTimer < lowest_counter)
							{
								lowest_counter = Generator[channel].StealTimer;
								oldest_channel = channel;
							}
						}
	
						if(!duplicate_note)
						{
							Generator[oldest_channel].MidiNote = note;
							Generator[oldest_channel].Period = NotePeriod[note];
							Generator[oldest_channel].StealTimer = 0xFFFFFFFF;
							Generator[oldest_channel].Active = TRUE;
						}
					}
					else
					{
						note = packet->DATA_1;
						channel = packet->DATA_0 & MIDI_CHANNEL_MASK;

						if(channel >= 0 && channel < CHANNELS)
						{
							Generator[channel].MidiNote = note;
							Generator[channel].Period = NotePeriod[note];
							Generator[channel].Active = TRUE;
						}
					}

					break;
				
				case MIDI_NOTE_OFF:

					if(note_stealing)
					{
						channel = CHANNELS;
		
						note = packet->DATA_1;
		
						// find the active channel for this note, if it exists
						while(channel--)
						{
							if(Generator[channel].MidiNote == note)
							{
								//kill it
								Generator[channel].Active = FALSE;
								Generator[channel].StealTimer = 0;
								break;
							}
						}
					}
					else
					{
						note = packet->DATA_1;
						channel = packet->DATA_0 & MIDI_CHANNEL_MASK;

						if(channel >= 0 && channel < CHANNELS)
						{
							if(Generator[channel].MidiNote == note)
							{
								Generator[channel].Active = FALSE;
							}
						}
					}

					break;

				// Please excuse this atrocious bend code. It was rushed to be used, only to not
				// actually be used at all due to a change in song choice. It did work "kind of"
				// when I originally implemented it, but I never ironed the bugs out. In fact it
				// may not work at all in its present state due to changes elsewhere. I definitely
				// did have it working at one point in time for a song demo I decided not to make.

				case MIDI_PITCH_BEND:
					{
						channel = packet->DATA_0 & MIDI_CHANNEL_MASK;
						

						if(channel >= 0 && channel < CHANNELS)
						{
							note = Generator[channel].MidiNote;
							//bent_note = NotePeriod[note];

							// 100 cents per semitone, PITCH_BEND_RANGE max semitones

							// 1. calculate how many cents to bend pitch ...

							// we can use a piecewise linear interpolation between semitones
							// if we restrict the max bend range to +/- 2 semitones, we can
							// just check if the bend is between 0 and 1 semitones and linearly interpolate,
							// or if it's between 1 and 2 semitones, start at the next highest note, and linearly
							// interpolate to the one above that (or so on for successively higher ranges)

							// 2 ^ 1/12 = 1.05946309435929526456...
							// 2 ^-1/12 = 0.94387431268169349664...

							// for PITCH_BEND_RANGE = 2
							// max cents = PITCH_BEND_RANGE * 100 = 200 cents
							// 0x2000 - 0x3FFF = 200 cents; 0x2000 - 0x0000 = 200 cents

							// 0x2000 = no bend, 0x0000 = full bend down, 0x3FFF = full bend up


							// 1. assemble the 14-bit bend value
							//bend_value = ((int)(Generator[channel].DATA_2 & 0x7F) << 7) | (int)(Generator[channel].DATA_1 & 0x7F);

							// actually, we can probably get away with using only the most significant byte because the floppy-stepper-oscillator is such a crude sound in the first place
							bend_value = packet->DATA_2;

							
							
							// 2. determine if the bend is up or down
							if(bend_value > 0x40)
							{
								bend_value -= 0x40; // value between 0x00 and 0x3F

								if(bend_value >= 0x20) // bend past +1 semitone
								{
									bend_value -= 0x20; // value between 0x00 and 0x1F;
									bent_note = NotePeriod[note+1];
								}
								else // bend between 0 and +1 semitone
								{
									bent_note = NotePeriod[note];
								}

								// !! FIX THIS
								// !! we need to bend the cycle period down to bend frequency up, and vice-versa

								//bend_value = 0x20 - bend_value;
								bent_note *= BendCoeff[bend_value];
							}
							else if(bend_value < 0x40)
							{
								bend_value = bend_value - 0x39;
							}

							Generator[channel].Period = bent_note;
						}
					}

					break;

				default:
					break;
			}
	
			packet++;
		}

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

}//end ProcessIO
/******************************************************************************
 	Function:
 		BYTE MSDWriteHandler(void)
 		
 	Description:
 		This funtion processes a write command received through 
 		the MSD class driver
 		
 	PreCondition:
 		None
 		
 	Parameters:
 		None
 		
 	Return Values:
 		BYTE - the current state of the MSDWriteHandler state
 		machine.  The valid values are defined in MSD.h under the 
 		MSDWriteHandler state machine declaration section
 		
 	Remarks:
 		None
 
 *****************************************************************************/
BYTE MSDWriteHandler(void)
{
    static BYTE MSDWriteState = MSD_WRITE10_WAIT;
    
    switch(MSDWriteState)
    {
        case MSD_WRITE10_WAIT:
         	/* 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;	
        	
        	MSD_State = MSD_WRITE10_BLOCK;
        	//Fall through to MSD_WRITE10_BLOCK
        case MSD_WRITE10_BLOCK:
            if(TransferLength.Val == 0)
            {
                MSDWriteState = MSD_WRITE10_WAIT;
                break;
            }
            
            MSDWriteState = MSD_WRITE10_RX_SECTOR;
            ptrNextData=(BYTE *)&msd_buffer[0];
              
        	msd_csw.dCSWDataResidue=BLOCKLEN_512;
        	
            //Fall through to MSD_WRITE10_RX_SECTOR
        case MSD_WRITE10_RX_SECTOR:
        {
      		/* Read 512B into msd_buffer*/
      		if(msd_csw.dCSWDataResidue>0) 
      		{
                if(USBHandleBusy(USBMSDOutHandle) == TRUE)
                {
                    break;
                }

                USBMSDOutHandle = USBRxOnePacket(MSD_DATA_OUT_EP,ptrNextData,MSD_OUT_EP_SIZE);
                MSDWriteState = MSD_WRITE10_RX_PACKET;
                //Fall through to MSD_WRITE10_RX_PACKET
      	    }
      	    else
      	    {
          		if(LUNWriteProtectState()) 
                {
              	    gblSenseData[LUN_INDEX].SenseKey=S_NOT_READY;
              	    gblSenseData[LUN_INDEX].ASC=ASC_WRITE_PROTECTED;
              	    gblSenseData[LUN_INDEX].ASCQ=ASCQ_WRITE_PROTECTED;
              	    msd_csw.bCSWStatus=0x01;
              	    //TODO: (DF) - what state should I return to?
              	}
              	else
              	{
      			    MSDWriteState = MSD_WRITE10_SECTOR;     
      			}
      			break;
          	}
        }
        //Fall through to MSD_WRITE10_RX_PACKET
        case MSD_WRITE10_RX_PACKET:
            if(USBHandleBusy(USBMSDOutHandle) == TRUE)
            {
                break;
            }
            
        	gblCBW.dCBWDataTransferLength-=USBHandleGetLength(USBMSDOutHandle);		// 64B read
        	msd_csw.dCSWDataResidue-=USBHandleGetLength(USBMSDOutHandle);
            ptrNextData += MSD_OUT_EP_SIZE;
            
            MSDWriteState = MSD_WRITE10_RX_SECTOR;
            break;
        case MSD_WRITE10_SECTOR:
        {
      		if(LUNSectorWrite(LBA.Val, (BYTE*)&msd_buffer[0], (LBA.Val==0)?TRUE:FALSE) != TRUE)
      		{
          		break;
      		}
      
    //		if (status) {
    //			msd_csw.bCSWStatus=0x01;
    //			/* add some sense keys here*/
    //		}
      
      		LBA.Val++;				// One LBA is written. Write the next LBA
      		TransferLength.Val--;
      
            MSDWriteState = MSD_WRITE10_BLOCK;
            break;
        } 
    }
    
    return MSDWriteState;
}
/******************************************************************************
 	Function:
 		BYTE MSDWriteHandler(void)
 		
 	Description:
 		This funtion processes a write command received through 
 		the MSD class driver
 		
 	PreCondition:
 		None
 		
 	Parameters:
 		None
 		
 	Return Values:
 		BYTE - the current state of the MSDWriteHandler state
 		machine.  The valid values are defined in MSD.h under the 
 		MSDWriteHandler state machine declaration section
 		
 	Remarks:
 		None
 
 *****************************************************************************/
BYTE MSDWriteHandler(void)
{
    switch(MSDWriteState)
    {
        case MSD_WRITE10_WAIT:
         	/* 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];
        
        	//Initially assume success, unless handler code later encounters an
        	//error condition and sets the status to 0x01 or 0x02.
        	msd_csw.bCSWStatus=0x0;	
        	
        	MSD_State = MSD_WRITE10_BLOCK;
        	//Fall through to MSD_WRITE10_BLOCK
        case MSD_WRITE10_BLOCK:
            if(TransferLength.Val == 0)
            {
                MSDWriteState = MSD_WRITE10_WAIT;
                break;
            }
            
            MSDWriteState = MSD_WRITE10_RX_SECTOR;
            ptrNextData=(BYTE *)&msd_buffer[0];
              
        	msd_csw.dCSWDataResidue=BLOCKLEN_512;
        	
            //Fall through to MSD_WRITE10_RX_SECTOR
        case MSD_WRITE10_RX_SECTOR:
        {
      		/* Read 512B into msd_buffer*/
      		if(msd_csw.dCSWDataResidue>0) 
      		{
                if(USBHandleBusy(USBMSDOutHandle) == TRUE)
                {
                    break;
                }

                USBMSDOutHandle = USBRxOnePacket(MSD_DATA_OUT_EP,ptrNextData,MSD_OUT_EP_SIZE);
                MSDWriteState = MSD_WRITE10_RX_PACKET;
                //Fall through to MSD_WRITE10_RX_PACKET
      	    }
      	    else
      	    {
          		//We finished receiving a sector worth of data from the host.
          		//Check if the media is write protected before deciding what
          		//to do with the data.
          		if(LUNWriteProtectState()) 
                {
                    //The device appears to be write protected.
              	    //Let host know error occurred.  The bCSWStatus flag is also used by
              	    //the write handler, to know not to even attempt the write sequence.
              	    msd_csw.bCSWStatus=0x01;    
              	    
                    //Set sense keys so the host knows what caused the error.
              	    gblSenseData[LUN_INDEX].SenseKey=S_NOT_READY;
              	    gblSenseData[LUN_INDEX].ASC=ASC_WRITE_PROTECTED;
              	    gblSenseData[LUN_INDEX].ASCQ=ASCQ_WRITE_PROTECTED;
              	}
   			    MSDWriteState = MSD_WRITE10_SECTOR;     
      			break;
          	}
        }
        //Fall through to MSD_WRITE10_RX_PACKET
        case MSD_WRITE10_RX_PACKET:
            if(USBHandleBusy(USBMSDOutHandle) == TRUE)
            {
                break;
            }
            
        	gblCBW.dCBWDataTransferLength-=USBHandleGetLength(USBMSDOutHandle);		// 64B read
        	msd_csw.dCSWDataResidue-=USBHandleGetLength(USBMSDOutHandle);
            ptrNextData += MSD_OUT_EP_SIZE;
            
            MSDWriteState = MSD_WRITE10_RX_SECTOR;
            break;
        case MSD_WRITE10_SECTOR:
        {
            //Make sure that no error has been detected, before performing the write
            //operation.  If there was an error, skip the write operation, but allow
            //the TransferLength to continue decrementing, so that we can eventually
            //receive all OUT bytes that the host is planning on sending us.  Only
            //after that is complete will the host send the IN token for the CSW packet,
            //which will contain the bCSWStatus letting it know an error occurred.
      		if(msd_csw.bCSWStatus == 0x00)
      		{
          		if(LUNSectorWrite(LBA.Val, (BYTE*)&msd_buffer[0], (LBA.Val==0)?TRUE:FALSE) != TRUE)
          		{
              		//The write operation failed for some reason.  Keep track of retry
              		//attempts and abort if repeated write attempts also fail.
    				if(MSDRetryAttempt < MSD_FAILED_WRITE_MAX_ATTEMPTS)
    				{
    				    MSDRetryAttempt++;
                        break;
    				}
    				else
    				{  
        				//Too many consecutive failed write attempts have occurred. 
        				//Need to give up and abandon the write attempt.
        				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;
                    }              		
          		}
      		}
      
            //One LBA is written (unless an error occurred).  Advance state
            //variables so we can eventually finish handling the CBW request.
      		LBA.Val++;				
      		TransferLength.Val--;      
            MSDWriteState = MSD_WRITE10_BLOCK;
            break;
        } 
        
        default:
            //Illegal condition which should not occur.  If for some reason it
            //does, try to let the host know know an error has occurred.
            msd_csw.bCSWStatus=0x02;    //Phase Error
            MSDWriteState = MSD_WRITE10_WAIT;            
    }
    
    return MSDWriteState;
}
Beispiel #22
0
/*******************************************************************
 * Function:        bool USER_USB_CALLBACK_EVENT_HANDLER(
 *                        USB_EVENT event, void *pdata, uint16_t size)
 *
 * PreCondition:    None
 *
 * Input:           USB_EVENT event - the type of event
 *                  void *pdata - pointer to the event data
 *                  uint16_t size - size of the event data
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        This function is called from the USB stack to
 *                  notify a user application that a USB event
 *                  occured.  This callback is in interrupt context
 *                  when the USB_INTERRUPT option is selected.
 *
 * Note:            None
 *******************************************************************/
bool USER_USB_CALLBACK_EVENT_HANDLER(USB_EVENT event, void *pdata, uint16_t size)
{
    switch((int)event)
    {
        case EVENT_TRANSFER:
            //Add application specific callback task or callback function here if desired.
            break;

        case EVENT_SOF:
            break;

        case EVENT_SUSPEND:
            break;

        case EVENT_RESUME:
            break;

        case EVENT_CONFIGURED:
            /* When the device is configured, we can (re)initialize the demo
             * code. */
            APP_DeviceMSDInitialize();
            APP_DeviceCDCEmulatorInitialize();

            break;

        case EVENT_SET_DESCRIPTOR:
            break;

        case EVENT_EP0_REQUEST:
            /* We have received a non-standard USB request.  The MSD driver
             * needs to check to see if the request was for it. */
            USBCheckMSDRequest();
            USBCheckCDCRequest();

            break;

        case EVENT_BUS_ERROR:
            break;

        case EVENT_TRANSFER_TERMINATED:
            //Add application specific callback task or callback function here if desired.
            //The EVENT_TRANSFER_TERMINATED event occurs when the host performs a CLEAR
            //FEATURE (endpoint halt) request on an application endpoint which was
            //previously armed (UOWN was = 1).  Here would be a good place to:
            //1.  Determine which endpoint the transaction that just got terminated was
            //      on, by checking the handle value in the *pdata.
            //2.  Re-arm the endpoint if desired (typically would be the case for OUT
            //      endpoints).

            //Check if the host recently did a clear endpoint halt on the MSD OUT endpoint.
            //In this case, we want to re-arm the MSD OUT endpoint, so we are prepared
            //to receive the next CBW that the host might want to send.
            //Note: If however the STALL was due to a CBW not valid condition,
            //then we are required to have a persistent STALL, where it cannot
            //be cleared (until MSD reset recovery takes place).  See MSD BOT
            //specs v1.0, section 6.6.1.
            if(MSDWasLastCBWValid() == false)
            {
                //Need to re-stall the endpoints, for persistent STALL behavior.
                USBStallEndpoint(MSD_DATA_IN_EP, IN_TO_HOST);
                USBStallEndpoint(MSD_DATA_OUT_EP, OUT_FROM_HOST);
            }
            else
            {
                //Check if the host cleared halt on the bulk out endpoint.  In this
                //case, we should re-arm the endpoint, so we can receive the next CBW.
                if((USB_HANDLE)pdata == USBGetNextHandle(MSD_DATA_OUT_EP, OUT_FROM_HOST))
                {
                    USBMSDOutHandle = USBRxOnePacket(MSD_DATA_OUT_EP, (uint8_t*)&msd_cbw, MSD_OUT_EP_SIZE);
                }
            }
            break;

        default:
            break;
    }
    return true;
}
/*********************************************************************************
  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;
}
Beispiel #24
0
/*******************************************************************
 * Function:        BOOL USER_USB_CALLBACK_EVENT_HANDLER(
 *                        USB_EVENT event, void *pdata, WORD size)
 *
 * PreCondition:    None
 *
 * Input:           USB_EVENT event - the type of event
 *                  void *pdata - pointer to the event data
 *                  WORD size - size of the event data
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        This function is called from the USB stack to
 *                  notify a user application that a USB event
 *                  occured.  This callback is in interrupt context
 *                  when the USB_INTERRUPT option is selected.
 *
 * Note:            None
 *******************************************************************/
BOOL USER_USB_CALLBACK_EVENT_HANDLER(USB_EVENT event, void *pdata, WORD size)
{
	switch ((INT)event)
	{
		case EVENT_TRANSFER:
			//Add application specific callback task or callback function here if desired.
			break;
		case EVENT_SOF:
			USBCB_SOF_Handler();
			break;
		case EVENT_SUSPEND:
			USBCBSuspend();
			break;
		case EVENT_RESUME:
			USBCBWakeFromSuspend();
			break;
		case EVENT_CONFIGURED:
			USBCBInitEP();
			break;
		case EVENT_SET_DESCRIPTOR:
			USBCBStdSetDscHandler();
			break;
		case EVENT_EP0_REQUEST:
			USBCBCheckOtherReq();
			break;
		case EVENT_BUS_ERROR:
			USBCBErrorHandler();
			break;
		case EVENT_TRANSFER_TERMINATED:
			// Add application specific callback task or callback function here if desired.
			// The EVENT_TRANSFER_TERMINATED event occurs when the host performs a CLEAR
			// FEATURE (endpoint halt) request on an application endpoint which was 
			// previously armed (UOWN was = 1).  Here would be a good place to:
			// 1.  Determine which endpoint the transaction that just got terminated was 
			//     on, by checking the handle value in the *pdata.
			// 2.  Re-arm the endpoint if desired (typically would be the case for OUT 
			//     endpoints).

			// Check if the host recently did a clear endpoint halt on the MSD OUT endpoint.
			// In this case, we want to re-arm the MSD OUT endpoint, so we are prepared
			// to receive the next CBW that the host might want to send.
			// Note: If however the STALL was due to a CBW not valid condition, 
			// then we are required to have a persistent STALL, where it cannot 
			// be cleared (until MSD reset recovery takes place).  See MSD BOT 
			// specs v1.0, section 6.6.1.
			if (MSDWasLastCBWValid() == FALSE)
			{
				// Need to re-stall the endpoints, for persistent STALL behavior.
				USBStallEndpoint(MSD_DATA_IN_EP, IN_TO_HOST);
				USBStallEndpoint(MSD_DATA_OUT_EP, OUT_FROM_HOST);
			}
			else
			{
				// Check if the host cleared halt on the bulk out endpoint.  In this
				// case, we should re-arm the endpoint, so we can receive the next CBW.
				if ((USB_HANDLE)pdata == USBGetNextHandle(MSD_DATA_OUT_EP, OUT_FROM_HOST))
				{
					USBMSDOutHandle = USBRxOnePacket(MSD_DATA_OUT_EP, (BYTE*)&msd_cbw, MSD_OUT_EP_SIZE);
				}
			}
			break;
		default:
			break;
	}
	return TRUE;
}