Ejemplo n.º 1
0
uint8_t USBMSC_pollCommand ()
{
	uint16_t state;
    uint8_t edbIndex;
    uint8_t * pCT1;
    uint8_t * pCT2;

    edbIndex = stUsbHandle[MSC0_INTFNUM].edb_Index;
    pCT1 = &tInputEndPointDescriptorBlock[edbIndex].bEPBCTX;
    pCT2 = &tInputEndPointDescriptorBlock[edbIndex].bEPBCTY;

    //check if currently transmitting data..
    if (MscReadControl.bReadProcessing == TRUE){
    	state = usbDisableOutEndpointInterrupt(edbIndex);
        //atomic operation - disable interrupts
        if ((MscReadControl.dwBytesToSendLeft == 0) &&
            (MscReadControl.lbaCount == 0)){
            //data is no more processing - clear flags..
            MscReadControl.bReadProcessing = FALSE;
            usbRestoreOutEndpointInterrupt(state);
        } else {
            if (!(tInputEndPointDescriptorBlock[edbIndex].bEPCNF &
                  EPCNF_STALL)){                    //if it is not stalled - contiune communication
                USBIEPIFG |= 1 << (edbIndex + 1);   //trigger IN interrupt to finish data tranmition
            }
            usbRestoreOutEndpointInterrupt(state);
            return (USBMSC_PROCESS_BUFFER);
        }
    }

    if (MscState.isMSCConfigured == FALSE){
        return (USBMSC_OK_TO_SLEEP);
    }

    if (!MscState.bMscSendCsw){
        if (MscState.bMscCbwReceived){
            if (Scsi_Verify_CBW() == SUCCESS){
                //Successful reception of CBW
                //Parse the CBW opcode and invoke the right command handler function
                Scsi_Cmd_Parser(MSC0_INTFNUM);
                MscState.bMscSendCsw = TRUE;
            }
            MscState.bMscCbwReceived = FALSE;       //CBW is performed!
        } else {
            return (USBMSC_OK_TO_SLEEP);
        }
        //check if any of out pipes has pending data and trigger interrupt

        if ((MscWriteControl.pCT1 != NULL)   &&
            ((*MscWriteControl.pCT1 & EPBCNT_NAK ) ||
             (*MscWriteControl.pCT2 & EPBCNT_NAK ))){
            USBOEPIFG |= 1 << (edbIndex + 1);       //trigger OUT interrupt again
            return (USBMSC_PROCESS_BUFFER);            //do not asleep, as data is coming in
            //and follow up data perform will be required.
        }
    }

    if (MscState.bMscSendCsw){
        if (MscState.bMcsCommandSupported == TRUE){
            //watiting till transport is finished!
            if ((MscWriteControl.bWriteProcessing == FALSE) &&
                (MscReadControl.bReadProcessing == FALSE) &&
                (MscReadControl.lbaCount == 0)){
                //Send CSW
                if (MscState.stallAtEndofTx == TRUE) {
                	if ((*pCT1 & EPBCNT_NAK) && (*pCT2 & EPBCNT_NAK)) {
                		MscState.stallAtEndofTx = FALSE;
                		usbStallInEndpoint(MSC0_INTFNUM);
                	}
                }
                else if (SUCCESS == Scsi_Send_CSW(MSC0_INTFNUM)){
                    MscState.bMscSendCsw = FALSE;
                    return (USBMSC_OK_TO_SLEEP);
                }
            }		
            else {
            	MSCFromHostToBuffer();
            }
        }
    }

    return (USBMSC_PROCESS_BUFFER);                 //When MscState.bMcsCommandSupported = FALSE, bReadProcessing became true, and
                                                    //bWriteProcessing = true.
}
/*This is the core function called by application to handle the MSC SCSI state
 * machine */
BYTE USBMSC_poll ()
{
    BYTE edbIndex;

    edbIndex = stUsbHandle[MSC0_INTFNUM].edb_Index;

    //check if currently transmitting data..
    if (MscReadControl.bReadProcessing == TRUE){
        BYTE bGIE;
        bGIE  = (__get_SR_register() & GIE);        //save interrupt status
        //atomic operation - disable interrupts
        _DINT_FET();                      //Disable global interrupts
        if ((MscReadControl.dwBytesToSendLeft == 0) &&
            (MscReadControl.lbaCount == 0)){
            //data is no more processing - clear flags..
            MscReadControl.bReadProcessing = FALSE;
            __bis_SR_register(bGIE);                //restore interrupt status
        } else {
            if (!(tInputEndPointDescriptorBlock[edbIndex].bEPCNF &
                  EPCNF_STALL)){                    //if it is not stalled - contiune communication
                USBIEPIFG |= 1 << (edbIndex + 1);   //trigger IN interrupt to finish data tranmition
            }
            __bis_SR_register(bGIE);                //restore interrupt status
            return (kUSBMSC_processBuffer);
        }
    }

    if (MscState.isMSCConfigured == FALSE){
        return (kUSBMSC_okToSleep);
    }

    if (!MscState.bMscSendCsw){
        if (MscState.bMscCbwReceived){
            if (Scsi_Verify_CBW() == SUCCESS){
                //Successful reception of CBW
                //Parse the CBW opcode and invoke the right command handler function
                Scsi_Cmd_Parser(MSC0_INTFNUM);
                MscState.bMscSendCsw = TRUE;
            }
            MscState.bMscCbwReceived = FALSE;       //CBW is performed!
        } else {
            return (kUSBMSC_okToSleep);
        }
        //check if any of out pipes has pending data and trigger interrupt

        if ((MscWriteControl.pCT1 != NULL)   &&
            ((*MscWriteControl.pCT1 & EPBCNT_NAK ) ||
             (*MscWriteControl.pCT2 & EPBCNT_NAK ))){
            USBOEPIFG |= 1 << (edbIndex + 1);       //trigger OUT interrupt again
            return (kUSBMSC_okToSleep);             //do not asleep, as data is coming in
            //and follow up data perform will be required.
        }
    }

    if (MscState.bMscSendCsw){
        if (MscState.bMcsCommandSupported == TRUE){
            //watiting till transport is finished!
            if ((MscWriteControl.bWriteProcessing == FALSE) &&
                (MscReadControl.bReadProcessing == FALSE) &&
                (MscReadControl.lbaCount == 0)){
                //Send CSW
                if (SUCCESS == Scsi_Send_CSW(MSC0_INTFNUM)){
                    MscState.bMscSendCsw = FALSE;
                    return (kUSBMSC_okToSleep);
                }
            }		
            else {
            	MSCFromHostToBuffer();
            }
        }
    }

    return (kUSBMSC_processBuffer);                 //When MscState.bMcsCommandSupported = FALSE, bReadProcessing became true, and
                                                    //bWriteProcessing = true.
}
Ejemplo n.º 3
0
__interrupt VOID iUsbInterruptHandler(VOID)
{
    BYTE bWakeUp = FALSE;
    //Check if the setup interrupt is pending.
    //We need to check it before other interrupts,
    //to work around that the Setup Int has lower priority then Input Endpoint 0
    if (USBIFG & SETUPIFG)
    {
        bWakeUp = SetupPacketInterruptHandler();
        USBIFG &= ~SETUPIFG;    // clear the interrupt bit
    }
    switch (__even_in_range(USBVECINT & 0x3f, USBVECINT_OUTPUT_ENDPOINT7))
    {
    case USBVECINT_NONE:
      break;
    case USBVECINT_PWR_DROP:
      __no_operation();
      break;
    case USBVECINT_PLL_LOCK:
      break;
    case USBVECINT_PLL_SIGNAL:
      break;
    case USBVECINT_PLL_RANGE:
      if (wUsbEventMask & kUSB_clockFaultEvent)
      {
          bWakeUp = USB_handleClockEvent();
      }
      break;
    case USBVECINT_PWR_VBUSOn:
      PWRVBUSonHandler();
      if (wUsbEventMask & kUSB_VbusOnEvent)
      {
          bWakeUp = USB_handleVbusOnEvent();
      }
      break;
    case USBVECINT_PWR_VBUSOff:
      PWRVBUSoffHandler();
      if (wUsbEventMask & kUSB_VbusOffEvent)
      {
          bWakeUp = USB_handleVbusOffEvent();
      }
      break;
    case USBVECINT_USB_TIMESTAMP:
      break;
    case USBVECINT_INPUT_ENDPOINT0:
      IEP0InterruptHandler();
      break;
    case USBVECINT_OUTPUT_ENDPOINT0:
      OEP0InterruptHandler();
      break;
    case USBVECINT_RSTR:
      USB_reset();
      if (wUsbEventMask & kUSB_UsbResetEvent)
      {
          bWakeUp = USB_handleResetEvent();
      }
      break;
    case USBVECINT_SUSR:
      USB_suspend();
      if (wUsbEventMask & kUSB_UsbSuspendEvent)
      {
          bWakeUp = USB_handleSuspendEvent();
      }
      break;
    case USBVECINT_RESR:
      USB_resume();
      if (wUsbEventMask & kUSB_UsbResumeEvent)
      {
          bWakeUp = USB_handleResumeEvent();
      }
      //-- after resume we will wake up! Independ what event handler says.
      bWakeUp = TRUE;
      break;
    case USBVECINT_SETUP_PACKET_RECEIVED:
      // NAK both IEP and OEP enpoints
      tEndPoint0DescriptorBlock.bIEPBCNT = EPBCNT_NAK;
      tEndPoint0DescriptorBlock.bOEPBCNT = EPBCNT_NAK;
      SetupPacketInterruptHandler();
      break;
    case USBVECINT_STPOW_PACKET_RECEIVED:
      break;
    case USBVECINT_INPUT_ENDPOINT1:
      bWakeUp = MSCToHostFromBuffer();
      break;
    case USBVECINT_INPUT_ENDPOINT2:
      break;
    case USBVECINT_INPUT_ENDPOINT3:
      //send saved bytes from buffer...
      bWakeUp = CdcToHostFromBuffer(CDC0_INTFNUM);
      break;
    case USBVECINT_INPUT_ENDPOINT4:
      //send saved bytes from buffer...
      bWakeUp = HidToHostFromBuffer(HID0_INTFNUM);
      break;
    case USBVECINT_INPUT_ENDPOINT5:
      break;
    case USBVECINT_INPUT_ENDPOINT6:
      break;
    case USBVECINT_INPUT_ENDPOINT7:
      break;
    case USBVECINT_OUTPUT_ENDPOINT1:
      bWakeUp = MSCFromHostToBuffer();
      break;
    case USBVECINT_OUTPUT_ENDPOINT2:
      break;
    case USBVECINT_OUTPUT_ENDPOINT3:
      //call callback function if no receive operation is underway
      if (!CdcIsReceiveInProgress(CDC0_INTFNUM))
      {
          if (wUsbEventMask & kUSB_dataReceivedEvent)
          {
              bWakeUp = USBCDC_handleDataReceived(CDC0_INTFNUM);
          }
      }
      else
      {
          //complete receive opereation - copy data to user buffer
          bWakeUp = CdcToBufferFromHost(CDC0_INTFNUM);
      }
      break;
    case USBVECINT_OUTPUT_ENDPOINT4:
      //call callback function if no receive operation is underway
      if (!HidIsReceiveInProgress(HID0_INTFNUM))
      {
           if (wUsbEventMask & kUSB_dataReceivedEvent)
           {
               bWakeUp = USBHID_handleDataReceived(HID0_INTFNUM);
           }
      }
      else
      {
           //complete receive opereation - copy data to user buffer
           bWakeUp = HidToBufferFromHost(HID0_INTFNUM);
      }
      break;
    case USBVECINT_OUTPUT_ENDPOINT5:
      break;
    case USBVECINT_OUTPUT_ENDPOINT6:
      break;
    case USBVECINT_OUTPUT_ENDPOINT7:
      break;
    default:
      break;
    }
    if (bWakeUp)
    {
    	 __bic_SR_register_on_exit(LPM3_bits);   // Exit LPM0-3
    	 __no_operation();                       // Required for debugger
    }
}