void mySetLineCodingHandler(void) { //If the request is not in a valid range if(cdc_notice.GetLineCoding.dwDTERate.Val > 115200) { USBStallEndpoint(0,1); } else { DWORD_VAL dwBaud; CDCSetBaudRate(cdc_notice.GetLineCoding.dwDTERate.Val); dwBaud.Val = (CLOCK_FREQ/4)/line_coding.dwDTERate.Val-1; SPBRG = dwBaud.v[0]; SPBRGH = dwBaud.v[1]; } }
/****************************************************************************** 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: 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: 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; }