/*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. }
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. }