BYTE USBHostCtrlWrite( BYTE deviceAddress, void *buffer, DWORD length ) { BYTE RetVal; DWORD i; // Validate the call if ((g_usbbt.initialized != 1) || (g_usbbt.deviceAddress != deviceAddress)) return USB_INVALID_STATE; if (g_usbbt.endpointCtrl_Busy) return USB_BUSY; UART2PrintString( "USBHostCtrlWrite\r\n" ); for(i = 0; i < length; i++) { UART2PutHex(*((char*)buffer+i)); } UART2PrintString( "\r\n" ); g_usbbt.endpointCtrl_Busy = 1; RetVal = USBHostIssueDeviceRequest( deviceAddress, USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS, 0, 0, 0, length, buffer, USB_DEVICE_REQUEST_SET, g_usbbt.clientDriverID); if (RetVal != USB_SUCCESS) { g_usbbt.endpointCtrl_Busy = 0; } return RetVal; }
BYTE USBHostBlukWrite( BYTE deviceAddress, void *buffer, DWORD length ) { BYTE RetVal; DWORD i; // Validate the call if ((g_usbbt.initialized != 1) || (g_usbbt.deviceAddress != deviceAddress)) return USB_INVALID_STATE; if (g_usbbt.endpointBulkOUT_Busy) return USB_BUSY; UART2PrintString( "USBHostBlukWrite\r\n" ); for(i = 0; i < length; i++) { UART2PutHex(*((char*)buffer+i)); } UART2PrintString( "\r\n" ); // Set the busy flag and start a new OUT transfer. g_usbbt.endpointBulkOUT_Busy = 1; RetVal = USBHostWrite( deviceAddress, g_usbbt.endpointBulkOUT, (BYTE *)buffer, length ); if (RetVal != USB_SUCCESS) { g_usbbt.endpointBulkOUT_Busy = 0; // Clear flag to allow re-try } return RetVal; }
void packet_dump(BYTE* data,long size){ long j; UART2PrintString( "DATA=" ); for(j = 0;j < size;j++){ UART2PutHex(data[j]); UART2PrintString( " " ); } UART2PrintString( "\r\n" ); }
/**************************************************************************** Function: void App_ProcessInputReport_Mouse(void) Description: This function processes input report received from HID Mouse device. Precondition: None Parameters: None Return Values: None Remarks: None ***************************************************************************/ void App_ProcessInputReport_Mouse(void) { /* process input report received from device */ USBHostHID_ApiImportData(Appl_raw_report_buffer.ReportData, Appl_raw_report_buffer.ReportSize ,Appl_Button_report_buffer, &Appl_Mouse_Buttons_Details); USBHostHID_ApiImportData(Appl_raw_report_buffer.ReportData, Appl_raw_report_buffer.ReportSize ,Appl_XY_report_buffer, &Appl_XY_Axis_Details); { unsigned int i; UART2PrintString( "\r\n" ); UART2PrintString( UHP_MOUSE_REPORT ); for(i=0;i<(Appl_raw_report_buffer.ReportSize);i++) { if(i!=0) UART2PrintString( "-" ); UART2PutHex( Appl_raw_report_buffer.ReportData[i]); } UART2PrintString( "\r\n" ); // UART2PrintString( "\r\n Left Bt : " ); UART2PutHex( Appl_Button_report_buffer[0]); // UART2PrintString( "\r\n Right Bt : " ); UART2PutHex( Appl_Button_report_buffer[1]); // // UART2PrintString( "\r\n X-Axis : " ); UART2PutHex( Appl_XY_report_buffer[0]); // UART2PrintString( "\r\n Y-Axis : " ); UART2PutHex( Appl_XY_report_buffer[1]); if(Appl_Button_report_buffer[0] == 0x01) { // Turn on Left Button, Green LED, D1 TRISBbits.TRISB12 = 0; _RB12=0; } else { // Turn off Left Button, Green LED, D1 TRISBbits.TRISB12 = 1; } if(Appl_Button_report_buffer[1] == 0x01) { // Turn on Left Button, Green LED, D1 TRISBbits.TRISB14 = 0; _RB14=0; } else { // Turn off Left Button, Green LED, D1 TRISBbits.TRISB14 = 1; } } }
/**************************************************************************** Function: BOOL USB_HID_DataCollectionHandler(void) Description: This function is invoked by HID client , purpose is to collect the details extracted from the report descriptor. HID client will store information extracted from the report descriptor in data structures. Application needs to create object for each report type it needs to extract. For ex: HID_DATA_DETAILS pickit.keys.modifier.details; HID_DATA_DETAILS is defined in file usb_host_hid_appl_interface.h Each member of the structure must be initialized inside this function. Application interface layer provides functions : USBHostHID_ApiFindBit() USBHostHID_ApiFindValue() These functions can be used to fill in the details as shown in the demo code. Precondition: None Parameters: None Return Values: true - If the report details are collected successfully. false - If the application does not find the the supported format. Remarks: This Function name should be entered in the USB configuration tool in the field "Parsed Data Collection handler". If the application does not define this function , then HID cient assumes that Application is aware of report format of the attached device. ***************************************************************************/ bool APP_HostHIDKeyboardReportParser(void) { uint8_t NumOfReportItem = 0; uint8_t i; USB_HID_ITEM_LIST* pitemListPtrs; USB_HID_DEVICE_RPT_INFO* pDeviceRptinfo; HID_REPORTITEM *reportItem; HID_USAGEITEM *hidUsageItem; //uint8_t usageIndex; // uint8_t reportIndex; // uint8_t usageItem; /* The pickit is already in use. */ if (pickit.inUse == true) { //PRINT_String( "-In Use-\r\n",10); return false; } pDeviceRptinfo = USBHostHID_GetCurrentReportInfo(); // Get current Report Info pointer pitemListPtrs = USBHostHID_GetItemListPointers(); // Get pointer to list of item pointers /* Find Report Item Index for Modifier Keys */ /* Once report Item is located , extract information from data structures provided by the parser */ NumOfReportItem = pDeviceRptinfo->reportItems; #ifdef DEBUG_MODE UART2PrintString("APP: NumOfReportItem:"); UART2PutHex(NumOfReportItem); UART2PutChar('\n'); USBHID_ReportDecriptor_Dump(); #endif reportItem = &pitemListPtrs->reportItemList[0]; pickit.details.reportLength = 64; // (pitemListPtrs->reportList[reportIndex].inputBits + 7) / 8; pickit.details.reportID = (uint8_t) reportItem->globals.reportID; pickit.details.bitOffset = (uint8_t) reportItem->startBit; pickit.details.bitLength = (uint8_t) reportItem->globals.reportsize; pickit.details.count = (uint8_t) reportItem->globals.reportCount; pickit.details.interfaceNum = USBHostHID_ApiGetCurrentInterfaceNum(); pickit.size = 64; pickit.buffer = (uint8_t*) malloc(pickit.size); pickit.inUse = true; return (pickit.inUse); }
void log_print_buf(const void* buf, int size) { const BYTE* byte_buf = (const BYTE*) buf; int s = size; while (size-- > 0) { UART2PutHex(*byte_buf++); UART2PutChar(' '); } UART2PutChar('\r'); UART2PutChar('\n'); byte_buf -= s; while (s-- > 0) { UART2PutChar(*byte_buf++); } UART2PutChar('\r'); UART2PutChar('\n'); }
void FileCallback(ADB_FILE_HANDLE f, const void* data, UINT32 data_len) { if (data) { UINT32 i; UART2PrintString("***** Got file data *******\r\n"); for (i = 0; i < data_len; ++i) { UART2PutHex(((const BYTE*) data)[i]); UART2PutChar(' '); } } else { if (data_len == 0) { UART2PrintString("***** EOF *******\r\n"); } else { UART2PrintString("***** Error *******\r\n"); } state = STATE_DONE; } }
void nrf_send_frame (uint8_t * frame) { int ret; nrf_write_reg (R_CONFIG, R_CONFIG_PWR_UP | R_CONFIG_EN_CRC); for (ret = 0; ret < 32; ret++) { UART2PutHex (frame[ret]); UART2PutStr (" "); } UART2PutStr ("\n\r"); NRF_CS_LOW (); SPI2_xmit (C_W_TX_PAYLOAD); SPI2_transmit (frame, 32); NRF_CS_HIGH (); NRF_CE_HIGH (); while (1) { ret = nrf_read_reg (R_FIFO_STATUS); if ((ret & R_FIFO_STATUS_TX_EMPTY) == R_FIFO_STATUS_TX_EMPTY) break; } NRF_CE_LOW (); nrf_write_reg (R_STATUS, R_CONFIG_MASK_RX_DR | R_CONFIG_MASK_TX_DS | R_CONFIG_MASK_MAX_RT); ret = nrf_cmd_status (C_NOP); }
void App_ProcessInputReport_Keyboard(void) { BYTE i; BYTE j; /* process input report received from device */ USBHostHID_ApiImportData(Appl_raw_report_buffer.ReportData, Appl_raw_report_buffer.ReportSize ,Appl_BufferModifierKeys, &Appl_ModifierKeysDetails); USBHostHID_ApiImportData(Appl_raw_report_buffer.ReportData, Appl_raw_report_buffer.ReportSize ,Appl_BufferNormalKeys, &Appl_NormalKeysDetails); BOOL before = TRUE; BOOL csnLock = FALSE; BOOL allZero = TRUE; for(i=0;i<(sizeof(Appl_BufferNormalKeys)/sizeof(Appl_BufferNormalKeys[0]));i++) { if(Appl_BufferNormalKeys[i]) allZero = FALSE; if(!App_CompareKeyPressedPrevBuf(Appl_BufferNormalKeys[i])) { before = FALSE; if(Appl_BufferNormalKeys[i] == HID_CAPS_LOCK_VAL) { CAPS_Lock_Pressed = !CAPS_Lock_Pressed; LED_Key_Pressed = csnLock = TRUE; Appl_led_report_buffer.CAPS_LOCK = CAPS_Lock_Pressed; }else if(Appl_BufferNormalKeys[i] == HID_NUM_LOCK_VAL) { NUM_Lock_Pressed = !NUM_Lock_Pressed; LED_Key_Pressed = csnLock = TRUE; Appl_led_report_buffer.NUM_LOCK = NUM_Lock_Pressed; }else if(Appl_BufferNormalKeys[i] == HID_SCROLL_LOCK_VAL) { SCROLL_Lock_Pressed = !SCROLL_Lock_Pressed; LED_Key_Pressed = csnLock = TRUE; Appl_led_report_buffer.SCROLL_LOCK = SCROLL_Lock_Pressed; } } } if(allZero && allZero!=lastAllZero) before = FALSE; lastAllZero = allZero; if(!csnLock) { if(before && KeyRepeatCounter<=REPEAT_COUNT) KeyRepeatCounter++; if(!before || KeyRepeatCounter>REPEAT_COUNT) { /* check if key press was present in previous report */ // if key press was pressed in previous report neglect it ???? UART2PrintString( "\r\n" ); UART2PrintString( UHP_KEYBOARD_REPORT ); for(j=0;j<(Appl_raw_report_buffer.ReportSize);j++) { if(j!=0) UART2PrintString( "-" ); if(j==0 && CAPS_Lock_Pressed) UART2PutHex( Appl_raw_report_buffer.ReportData[j] ^ 0x02); else UART2PutHex( Appl_raw_report_buffer.ReportData[j]); } UART2PrintString( "\r\n" ); //data = App_HID2ASCII(Appl_BufferNormalKeys[i]); // convert data to ascii //UART2PutChar(data); } } if(!before) KeyRepeatCounter = 0; App_CopyToShadowBuffer(); App_Clear_Data_Buffer(); }
/**************************************************************************** Function: USB_HID_RPT_DESC_ERROR _USBHostHID_Parse_Report(BYTE* hidReportDescriptor ,WORD lengthOfDescriptor, WORD pollRate, BYTE interfaceNum) Description: This function is called by usb_host_hid.c after a valid configuration device is found. This function parses the report descriptor and stores data in data structures. Application can access these data structures to understand report format and device capabilities Precondition: None Parameters: BYTE* hidReportDescriptor - Pointer to raw report descriptor WORD lengthOfDescriptor - Length of Report Descriptor WORD pollRate - Poll rate of the report BYTE interfaceNum - interface number of the respective report descriptor. Return Values: USB_HID_RPT_DESC_ERROR - Returns error code(enum) if found while parsing the report descriptor Remarks: None ***************************************************************************/ USB_HID_RPT_DESC_ERROR _USBHostHID_Parse_Report(BYTE* hidReportDescriptor , WORD lengthOfDescriptor , WORD pollRate, BYTE interfaceNum) { WORD sizeRequired = 0; WORD len_to_be_parsed =0; BYTE* currentRptDescPtr = NULL; BYTE* assignMem = NULL; /* Main Item Vars */ HID_COLLECTION *collectionLocal = NULL; HID_REPORT *reportLocal = NULL; /* Global Item Vars */ HID_REPORT *lreport = NULL; BYTE lreportIndex = (BYTE)NULL; /* Local Item Vars */ HID_DESIGITEM *ldesignatorItem = NULL; HID_STRINGITEM *lstringItem = NULL; HID_USAGEITEM *lusageItem = NULL; /*HID Error */ USB_HID_RPT_DESC_ERROR lhidError = HID_ERR; HID_ITEM_INFO item; BYTE i=0; BYTE dataByte=0 ; BYTE ldataSize=0; if((hidReportDescriptor == NULL) ||(lengthOfDescriptor == 0)) { /* set error flag */ return(HID_ERR_NullPointer); } _USBHostHID_InitDeviceRptInfo(); deviceRptInfo.interfaceNumber = interfaceNum; // update interface number for the report deviceRptInfo.reportPollingRate = pollRate; len_to_be_parsed = lengthOfDescriptor; currentRptDescPtr = hidReportDescriptor; while(len_to_be_parsed > 0) /* First parse to calculate the space required for all the items */ { item.ItemDetails.val = *currentRptDescPtr; /* Data need not be parsed at this point */ ldataSize = item.ItemDetails.ItemSize ; if(item.ItemDetails.ItemSize == 3) ldataSize = 4; currentRptDescPtr += (ldataSize+1) ; /* point to next item i.e size of item data + 1(item detail) */ len_to_be_parsed -= (ldataSize+1); /* remaining bytes = current - (length of data + 1)*/ switch (item.ItemDetails.ItemType) { case HIDType_Main: /* Main Items */ switch (item.ItemDetails.ItemTag) { case HIDTag_Collection: deviceRptInfo.collections++; deviceRptInfo.collectionNesting++; if (deviceRptInfo.collectionNesting > deviceRptInfo.maxCollectionNesting) deviceRptInfo.maxCollectionNesting = deviceRptInfo.collectionNesting; break; case HIDTag_EndCollection: if (deviceRptInfo.collectionNesting-- == 0) lhidError = HID_ERR_UnexpectedEndCollection ;/* Error: UnexpectedEndCollection */ break; case HIDTag_Input: case HIDTag_Output: case HIDTag_Feature: deviceRptInfo.reportItems++; break; default : break; } break; case HIDType_Global: /* Global Items */ switch (item.ItemDetails.ItemTag) { case HIDTag_ReportID: deviceRptInfo.reports++; break; case HIDTag_Push: deviceRptInfo.globalsNesting++; if (deviceRptInfo.globalsNesting > deviceRptInfo.maxGlobalsNesting) deviceRptInfo.maxGlobalsNesting = deviceRptInfo.globalsNesting; break; case HIDTag_Pop: deviceRptInfo.globalsNesting--; if (deviceRptInfo.globalsNesting > deviceRptInfo.maxGlobalsNesting) lhidError = HID_ERR_UnexpectedPop ;/* Error: global nesting rolled to negative ... */ break; default : break; } break; case HIDType_Local: /* Local Item */ switch (item.ItemDetails.ItemTag) { case HIDTag_Usage: deviceRptInfo.usages++; break; case HIDTag_UsageMinimum: case HIDTag_UsageMaximum: deviceRptInfo.usageRanges++; break; case HIDTag_StringIndex: deviceRptInfo.strings++; break; case HIDTag_StringMinimum: case HIDTag_StringMaximum: deviceRptInfo.stringRanges++; break; case HIDTag_DesignatorIndex: deviceRptInfo.designators++; break; case HIDTag_DesignatorMinimum: case HIDTag_DesignatorMaximum: deviceRptInfo.designatorRanges++; break; default : break; } break; default : break; } } if(lhidError) { return(lhidError); } if (deviceRptInfo.collectionNesting != 0) return(HID_ERR_MissingEndCollection) /* HID_RPT_DESC_FORMAT_IMPROPER */; if (deviceRptInfo.collections == 1) return(HID_ERR_MissingTopLevelCollection) /* HID_RPT_DESC_FORMAT_IMPROPER */; if (deviceRptInfo.reportItems == 0) return(HID_ERR_NoReports)/* HID_RPT_DESC_FORMAT_IMPROPER */; if ((deviceRptInfo.usageRanges & 1) == 1) return(HID_ERR_UnmatchedUsageRange)/* HID_RPT_DESC_FORMAT_IMPROPER */; if ((deviceRptInfo.stringRanges & 1) == 1) return(HID_ERR_UnmatchedStringRange)/* HID_RPT_DESC_FORMAT_IMPROPER */; if ((deviceRptInfo.designatorRanges & 1) == 1) return(HID_ERR_UnmatchedDesignatorRange)/* HID_RPT_DESC_FORMAT_IMPROPER */; /* usages , strings & descriptors are in pair */ deviceRptInfo.usages += (deviceRptInfo.usageRanges/2); deviceRptInfo.strings += (deviceRptInfo.stringRanges/2); deviceRptInfo.designators += (deviceRptInfo.designatorRanges/2); /* Calculate space required */ sizeRequired = (sizeof(HID_COLLECTION) * deviceRptInfo.collections) + (sizeof(HID_REPORTITEM) * deviceRptInfo.reportItems) + (sizeof(HID_REPORT) * deviceRptInfo.reports) + (sizeof(HID_USAGEITEM) * deviceRptInfo.usages) + (sizeof(HID_STRINGITEM) * deviceRptInfo.strings) + (sizeof(HID_DESIGITEM) * deviceRptInfo.designators) + (sizeof(int) * deviceRptInfo.maxCollectionNesting) + (sizeof(HID_GLOBALS) * deviceRptInfo.maxGlobalsNesting); if (parsedDataMem != NULL) { freezHID( parsedDataMem ); } parsedDataMem = (BYTE*) malloc(sizeRequired); #ifdef DEBUG_MODE UART2PrintString( "HID: Memory for Report Descriptor: " ); UART2PutHex( sizeRequired ); #endif if (parsedDataMem == NULL) return(HID_ERR_NotEnoughMemory); /* Error: Not enough memory */ assignMem = (BYTE*) parsedDataMem; /* Allocate Space */ itemListPtrs.collectionList = (HID_COLLECTION *) assignMem; assignMem += (sizeof(HID_COLLECTION) * deviceRptInfo.collections); itemListPtrs.reportItemList = (HID_REPORTITEM *) assignMem; assignMem += (sizeof(HID_REPORTITEM) * deviceRptInfo.reportItems); itemListPtrs.reportList = (HID_REPORT *) assignMem; assignMem += (sizeof(HID_REPORT) * deviceRptInfo.reports); itemListPtrs.usageItemList = (HID_USAGEITEM *) assignMem; assignMem += (sizeof(HID_USAGEITEM) * deviceRptInfo.usages); itemListPtrs.stringItemList = (HID_STRINGITEM *) assignMem; assignMem += (sizeof(HID_STRINGITEM) * deviceRptInfo.strings); itemListPtrs.designatorItemList = (HID_DESIGITEM *) assignMem; assignMem += (sizeof(HID_DESIGITEM) * deviceRptInfo.designators); itemListPtrs.collectionStack = (BYTE *) assignMem; assignMem += (sizeof(int) * deviceRptInfo.maxCollectionNesting); itemListPtrs.globalsStack = (HID_GLOBALS *) assignMem; _USBHostHID_InitDeviceRptInfo(); // Initialize the virtual collection collectionLocal = itemListPtrs.collectionList; collectionLocal->data = 0; collectionLocal->firstChild = 0; collectionLocal->firstReportItem = 0; collectionLocal->firstUsageItem = 0; collectionLocal->nextSibling = 0; collectionLocal->parent = 0; collectionLocal->reportItems = 0; collectionLocal->usageItems = 0; collectionLocal->usagePage = 0; // Initialize the default report reportLocal = itemListPtrs.reportList; reportLocal->featureBits = 0; reportLocal->inputBits = 0; reportLocal->outputBits = 0; reportLocal->reportID = 0; /* re-init ptr to Rpt Descp & Length of Descp */ len_to_be_parsed = lengthOfDescriptor; currentRptDescPtr = hidReportDescriptor; #ifdef DEBUG_MODE UART2PrintString( "HID-HOST: ... 2nd Parse \n" ); #endif while(len_to_be_parsed > 0) /* Second parse to fill the tables with each item detail */ { item.ItemDetails.val = *currentRptDescPtr; item.Data.uItemData = 0; ldataSize = item.ItemDetails.ItemSize ; if(item.ItemDetails.ItemSize == 3) ldataSize = 4; currentRptDescPtr++; /* ptr points to data */ for (i = 0; i < ldataSize; i++) { dataByte = *currentRptDescPtr++; /* signed data will be taken care in ItemTag it is expected */ item.Data.uItemData |= ((DWORD)dataByte << (i*8)); } len_to_be_parsed -= (ldataSize+1); /* remaining bytes = current - (length of current item + 1)*/ switch(item.ItemDetails.ItemType) { case HIDType_Main: /* look for Main Items*/ switch(item.ItemDetails.ItemTag) { case HIDTag_Input : case HIDTag_Output : case HIDTag_Feature : lhidError = _USBHostHID_Parse_ReportType(&item); break; case HIDTag_Collection : _USBHostHID_Parse_Collection(&item); break; case HIDTag_EndCollection : _USBHostHID_Parse_EndCollection(&item); break; } break; case HIDType_Global: /* look for Global Items*/ switch(item.ItemDetails.ItemTag) { case HIDTag_UsagePage : deviceRptInfo.globals.usagePage = item.Data.uItemData; break; case HIDTag_LogicalMinimum : /* convert to signed val */ // Sign extend one value _USBHostHID_ConvertDataToSigned(&item); deviceRptInfo.globals.logicalMinimum = item.Data.sItemData; break; case HIDTag_LogicalMaximum :/* convert to signed val */ // Sign extend one value _USBHostHID_ConvertDataToSigned(&item); deviceRptInfo.globals.logicalMaximum = item.Data.uItemData; break; case HIDTag_PhysicalMinimum :/* convert to signed val */ // Sign extend one value _USBHostHID_ConvertDataToSigned(&item); deviceRptInfo.globals.physicalMinimum = item.Data.uItemData; break; case HIDTag_PhysicalMaximum :/* convert to signed val */ // Sign extend one value _USBHostHID_ConvertDataToSigned(&item); deviceRptInfo.globals.physicalMaximum = item.Data.uItemData; break; case HIDTag_UnitExponent : deviceRptInfo.globals.unitExponent = item.Data.uItemData; break; case HIDTag_ReportSize : deviceRptInfo.globals.reportsize = item.Data.uItemData; if (deviceRptInfo.globals.reportsize == 0) lhidError = HID_ERR_ZeroReportSize; break; case HIDTag_ReportID : if (item.Data.uItemData) { // Look for the Report ID in the table lreportIndex = 0; while ((lreportIndex < deviceRptInfo.reports) && (itemListPtrs.reportList[lreportIndex].reportID != item.Data.uItemData)) lreportIndex++; // initialize the entry if it's new and there's room for it // Start with 8 bits for the Report ID if (lreportIndex == deviceRptInfo.reports) { lreport = &itemListPtrs.reportList[deviceRptInfo.reports++]; lreport->reportID = item.Data.uItemData; lreport->inputBits = 8; lreport->outputBits = 8; lreport->featureBits = 8; } // remember which report is being processed deviceRptInfo.globals.reportID = item.Data.uItemData; deviceRptInfo.globals.reportIndex = lreportIndex; } else { lhidError = HID_ERR_ZeroReportID; } break; case HIDTag_ReportCount : if (item.Data.uItemData) { deviceRptInfo.globals.reportCount = item.Data.uItemData; } else { lhidError = HID_ERR_ZeroReportCount; } break; case HIDTag_Push : itemListPtrs.globalsStack[deviceRptInfo.globalsNesting++] = deviceRptInfo.globals; break; case HIDTag_Pop : deviceRptInfo.globals = itemListPtrs.globalsStack[--deviceRptInfo.globalsNesting] ; break; } break; case HIDType_Local: /* look for Local Items*/ switch(item.ItemDetails.ItemTag) { case HIDTag_Usage : lusageItem = &itemListPtrs.usageItemList[deviceRptInfo.usageItems++]; lusageItem->isRange = FALSE; if (item.ItemDetails.ItemSize == 3) /* 4 data bytes */ { lusageItem->usagePage = item.Data.uItemData >> 16; lusageItem->usage = item.Data.uItemData & 0x00FF; } else { lusageItem->usagePage = deviceRptInfo.globals.usagePage; lusageItem->usage = item.Data.uItemData; } break; case HIDTag_UsageMinimum : if(deviceRptInfo.haveUsageMax) { lusageItem = &itemListPtrs.usageItemList[deviceRptInfo.usageItems++]; lusageItem->isRange = TRUE; if(item.ItemDetails.ItemSize == 3) { lusageItem->usagePage = item.Data.uItemData >> 16; lusageItem->usageMinimum = item.Data.uItemData & 0x00FFL; } else {
/************************************************************************* * Function: ManageDemoState * * Preconditions: The DemoState global variable must be initialized to * DEMO_STATE_IDLE (0). (This occurs on reset.) * * Input: DemoState (global) * Actions selected based value of DemoState on function * entry. * * deviceAddress (global) * May use device address to access device, depending on * state. * * DataPacket (global) * May read data from packet buffer, depending on state. * * Output: DemoState (global) * Updates demo state as appropriate. * * DataPacket (global) * May cause data in the packet buffer to be updated, * depending on state. * * Returns: None * * Side Effects: Depend on state transition * * Overview: This routine maintains the state of the application, * updateing global data and taking actions as necessary * to maintain the custom demo operations. *************************************************************************/ void ManageDemoState ( void ) { BYTE RetVal; BlinkStatus(); // Watch for device timeouts // if (MSTimerGetTime() > DEMO_TIMEOUT_LIMIT) // { // if (DemoState == DEMO_STATE_IDLE) // { // LCDWriteLine( 2, "Awaiting Device" ); // } // else // { // UART2PrintString( "Device Time-out Error!\r\n" ); // LCDWriteLine( 2, "Dev Time-out Err" ); // DemoState = DEMO_STATE_ERROR; // } // } // Watch for device detaching if (USBHostGenericDeviceDetached(deviceAddress) && deviceAddress != 0) { UART2PrintString( "Generic demo device detached - polled\r\n" ); DemoState = DEMO_INITIALIZE; deviceAddress = 0; } switch (DemoState) { case DEMO_INITIALIZE: InitLcdMessage(); DemoState = DEMO_STATE_IDLE; break; /** Idle State: Loops here until attach **/ case DEMO_STATE_IDLE: if (CheckForNewAttach()) { DemoState = DEMO_STATE_GET_DEV_VERSION; } break; /** Sequence: Read Dev FW Version **/ case DEMO_STATE_GET_DEV_VERSION: // Send the Read Version command DataPacket.CMD = READ_VERSION; DataPacket.len = 2; if (!USBHostGenericTxIsBusy(deviceAddress)) { if ( (RetVal=USBHostGenericWrite(deviceAddress, &DataPacket, 2)) == USB_SUCCESS ) { DemoState = DEMO_STATE_WAITING_VER_REQ; } else { UART2PrintString( "1 Device Write Error 0x" ); UART2PutHex(RetVal); UART2PrintString( "\r\n" ); LCDWriteLine( 2, "Dev Write Error " ); } } break; case DEMO_STATE_WAITING_VER_REQ: if (!USBHostGenericTxIsBusy(deviceAddress) ) DemoState = DEMO_STATE_READ_DEV_VERSION; break; case DEMO_STATE_READ_DEV_VERSION: if (!USBHostGenericRxIsBusy(deviceAddress)) { if ( (RetVal=USBHostGenericRead(deviceAddress, &DataPacket, 4)) == USB_SUCCESS ) { DemoState = DEMO_STATE_WAITING_READ_VER; } else { UART2PrintString( "1 Device Read Error 0x" ); UART2PutHex(RetVal); UART2PrintString( "\r\n" ); LCDWriteLine( 2, "Dev Read Error " ); } } break; case DEMO_STATE_WAITING_READ_VER: if (!USBHostGenericRxIsBusy(deviceAddress)) DemoState = DEMO_STATE_VERIFY_DEV_FW_VER; break; case DEMO_STATE_VERIFY_DEV_FW_VER: if (ValidateAndDisplayDeviceFwVersion()) DemoState = DEMO_STATE_GET_TEMPERATURE; else DemoState = DEMO_STATE_ERROR; break; /** Sequence: Read Temperature Sensor Data **/ case DEMO_STATE_GET_TEMPERATURE: // Send the Read Temperature command DataPacket.CMD = RD_TEMP; DataPacket.len = 2; if (!USBHostGenericTxIsBusy(deviceAddress)) { if ( (RetVal=USBHostGenericWrite(deviceAddress, &DataPacket, 2)) == USB_SUCCESS) { DemoState = DEMO_STATE_WAITING_GET_TEMP; } else { UART2PrintString( "2 Device Write Error 0x" ); UART2PutHex(RetVal); UART2PrintString( "\r\n" ); LCDWriteLine( 2, "Dev Write Error " ); } } break; case DEMO_STATE_WAITING_GET_TEMP: if (!USBHostGenericTxIsBusy(deviceAddress) ) { DemoState = DEMO_STATE_READ_TEMPERATURE; } break; case DEMO_STATE_READ_TEMPERATURE: if (!USBHostGenericRxIsBusy(deviceAddress)) { if ( (RetVal=USBHostGenericRead(deviceAddress, &DataPacket, 3)) == USB_SUCCESS) { DemoState = DEMO_STATE_WAITING_READ_TEMP; } else { UART2PrintString( "2 Device Read Error 0x" ); UART2PutHex(RetVal); UART2PrintString( "\r\n" ); LCDWriteLine( 2, "Dev Read Error " ); } } break; case DEMO_STATE_WAITING_READ_TEMP: if (!USBHostGenericRxIsBusy(deviceAddress)) { DemoState = DEMO_STATE_DISPLAY_TEMPERATURE; } break; case DEMO_STATE_DISPLAY_TEMPERATURE: DisplayTemperature(); DemoState = DEMO_STATE_GET_POT; break; /** Sequence: Read POT Sensor Data **/ case DEMO_STATE_GET_POT: // Send the Read POT command DataPacket.CMD = RD_POT; DataPacket.len = 2; if (!USBHostGenericTxIsBusy(deviceAddress)) { if ( (RetVal=USBHostGenericWrite(deviceAddress, &DataPacket, 2)) == USB_SUCCESS) { DemoState = DEMO_STATE_WAITING_GET_POT; } else { UART2PrintString( "3 Device Write Error 0x" ); UART2PutHex(RetVal); UART2PrintString( "\r\n" ); LCDWriteLine( 2, "Dev Write Error " ); } } break; case DEMO_STATE_WAITING_GET_POT: if (!USBHostGenericTxIsBusy(deviceAddress) ) DemoState = DEMO_STATE_READ_POT; break; case DEMO_STATE_READ_POT: if (!USBHostGenericRxIsBusy(deviceAddress)) { if ( (RetVal=USBHostGenericRead(deviceAddress, &DataPacket, 3)) == USB_SUCCESS) { DemoState = DEMO_STATE_WAITING_READ_POT; } else { UART2PrintString( "3 Device Read Error 0x" ); UART2PutHex(RetVal); UART2PrintString( "\r\n" ); LCDWriteLine( 2, "Dev Read Error " ); } } break; case DEMO_STATE_WAITING_READ_POT: if (!USBHostGenericRxIsBusy(deviceAddress)) DemoState = DEMO_STATE_DISPLAY_POT; break; case DEMO_STATE_DISPLAY_POT: DisplayPot(); DemoState = DEMO_STATE_SEND_SET_LED; break; /** Sequence: Update LEDs **/ case DEMO_STATE_SEND_SET_LED: // Send the set-LED command DataPacket.CMD = UPDATE_LED; DataPacket.len = 3; if (Switch3WasPressed()) { DataPacket.led_num = 3; // LED 3 on original PIC18 FS USB board DataPacket.led_status = LEDState.bits.b3 ^ 1; } else if (Switch6WasPressed()) { DataPacket.led_num = 4; // LED 4 on original PIC18 FS USB board DataPacket.led_status = LEDState.bits.b4 ^ 1; } else { DemoState = DEMO_STATE_GET_TEMPERATURE; break; } if (!USBHostGenericTxIsBusy(deviceAddress)) { if ( (RetVal=USBHostGenericWrite(deviceAddress, &DataPacket, 3)) == USB_SUCCESS) { DemoState = DEMO_STATE_WAITING_SET_LED; } else { UART2PrintString( "4 Device Write Error 0x" ); UART2PutHex(RetVal); UART2PrintString( "\r\n" ); LCDWriteLine( 2, "Dev Write Error " ); } } break; case DEMO_STATE_WAITING_SET_LED: if (!USBHostGenericTxIsBusy(deviceAddress) ) DemoState = DEMO_STATE_READ_SET_LED_RESP; break; case DEMO_STATE_READ_SET_LED_RESP: if (!USBHostGenericRxIsBusy(deviceAddress)) { DataPacket.CMD = CMD_INVALID; if ( (RetVal=USBHostGenericRead(deviceAddress, &DataPacket, 1)) == USB_SUCCESS) { DemoState = DEMO_STATE_WAITING_LED_RESP; } else { UART2PrintString( "4 Device Read Error 0x" ); UART2PutHex(RetVal); UART2PrintString( "\r\n" ); LCDWriteLine( 2, "Dev Read Error " ); } } break; case DEMO_STATE_WAITING_LED_RESP: if (!USBHostGenericRxIsBusy(deviceAddress)) DemoState = DEMO_STATE_UPDATE_LED_STATE; break; case DEMO_STATE_UPDATE_LED_STATE: if (DataPacket.CMD == UPDATE_LED) // CMD updated by read from device { if (DataPacket.led_num == 3) // led_num left-over from set-LED command send { LEDState.bits.b3 ^= 1; // mLED_10_Toggle(); } else if (DataPacket.led_num == 4) { LEDState.bits.b4 ^= 1; // mLED_9_Toggle(); } } DemoState = DEMO_STATE_GET_TEMPERATURE; break; /** Error state: Hold here until detached **/ case DEMO_STATE_ERROR: // To Do: Flash LEDs break; default: DemoState = DEMO_INITIALIZE; break; } DelayMs(1); // 1ms delay } // ManageDemoState
/********************************************************************* * Function: void APP_HostHIDKeyboardTasks(void); * * Overview: Keeps the demo running. * * PreCondition: The demo should have been initialized via * the APP_HostHIDKeyboardInitialize() * * Input: None * * Output: None * ********************************************************************/ void APP_HostHIDKeyboardTasks() { uint8_t error; uint8_t count; if (!USBHostHID_ApiDeviceDetect()) { if (pickit.state != WAITING_FOR_DEVICE) { pickit.state = DEVICE_NOT_CONNECTED; #ifdef DEBUG_MODE UART2PrintString("APP: PICkit Disconnected!\n"); #endif pickit.inUse = false; if (pickit.buffer != NULL) { free(pickit.buffer); pickit.buffer = NULL; } } } switch (pickit.state) { case DEVICE_NOT_CONNECTED: //PRINT_ClearScreen(); #ifdef DEBUG_MODE UART2PrintString("APP: Attach PICkit\n"); #endif pickit.state = WAITING_FOR_DEVICE; IEC0bits.U1RXIE=0; LED_Off(LED_USB_HOST_HID_KEYBOARD_DEVICE_READY); break; case WAITING_FOR_DEVICE: if (USBHostHID_ApiDeviceDetect()) /* True if report descriptor is parsed with no error */ { //PRINT_ClearScreen(); SYSTEM_Initialize(SYSTEM_STATE_USB_HOST_HID_KEYBOARD); LED_On(LED_USB_HOST_HID_KEYBOARD_DEVICE_READY); pickit.state = DEVICE_CONNECTED; //timwuu 2015.12.31 change control right from timer3 to uart TIMER_RequestTick(&APP_HostHIDTimerHandler, 2); //2ms } break; case DEVICE_CONNECTED: break; case GET_INPUT_REPORT: if (USBHostHID_ApiGetReport(pickit.details.reportID, pickit.details.interfaceNum, pickit.size, pickit.buffer ) ) { /* Host may be busy/error -- keep trying */ #ifdef DEBUG_MODE UART2PrintString("GET_INPUT_REPORT:BUSY\n"); #endif } else { #ifdef DEBUG_MODE UART2PrintString("GET_INPUT_REPORT:OK\n"); #endif pickit.state = INPUT_REPORT_PENDING; } break; case INPUT_REPORT_PENDING: if (USBHostHID_ApiTransferIsComplete(&error, &count)) { if (error || (count == 0)) { #ifdef DEBUG_MODE if(error) UART2PrintString("INPUT_REPORT_PENDING:ERROR\n"); if(count==0) UART2PrintString("INPUT_REPORT_PENDING:ZERO\n"); #endif pickit.state = DEVICE_CONNECTED; } else { #ifdef DEBUG_MODE UART2PrintString("INPUT_REPORT_PENDING:OK\n"); #endif UART2PutHex(pickit.buffer[61]); UART2PutHex(pickit.buffer[60]); UART2PutChar(':'); pickit.state = DEVICE_CONNECTED; App_ProcessInputReport(); } } break; case SEND_OUTPUT_REPORT: //App_PrepareOutputReport(); if (USBHostHID_ApiSendReport(pickit.details.reportID, pickit.details.interfaceNum, pickit.size, (uint8_t *)cmdBuffer)) { //pickit.buffer)) { /* Host may be busy/error -- keep trying */ #ifdef DEBUG_MODE UART2PrintString("SEND_OUTPUT_REPORT:BUSY\n"); #endif } else { #ifdef DEBUG_MODE UART2PrintString("SEND_OUTPUT_REPORT:OK\n"); #endif UB_SetCmdBufferStateEmpty(); pickit.state = OUTPUT_REPORT_PENDING; } break; case OUTPUT_REPORT_PENDING: //timijk 2016.01.13 Issue if (USBHostHID_ApiTransferIsComplete(&error, &count)) { #ifdef DEBUG_MODE UART2PrintString("OUTPUT_REPORT_PENDING\n"); #endif //?timwuu 2016.01.02 signal the device is ready for the next command // if(error) { // UART2PutChar('*'); // UART2PutHex(error); // LATBbits.LATB15 =1; // pickit.state = SEND_OUTPUT_REPORT; //resent the data // } // else // { U1TXREG = 0x00; //LENGTH ZERO DATA pickit.state = DEVICE_CONNECTED; // } } break; case ERROR_REPORTED: break; default: break; } }
BOOL USBHostUSBBTInit( BYTE address, DWORD flags, BYTE clientDriverID ) { int i = 0; BYTE *descriptor; UART2PrintString( "USBBT init\r\n" ); descriptor = USBHostGetCurrentConfigurationDescriptor( address ); // Find the next interface descriptor. while (i < ((USB_CONFIGURATION_DESCRIPTOR *)descriptor)->wTotalLength) { // See if we are pointing to an interface descriptor. if (descriptor[i+1] == USB_DESCRIPTOR_INTERFACE) { g_usbbt.endpointCtrl = 0; g_usbbt.endpointInt = 0; g_usbbt.endpointBulkIN = 0; g_usbbt.endpointBulkOUT = 0; // Scan for endpoint descriptors. i += descriptor[i]; while (descriptor[i+1] == USB_DESCRIPTOR_ENDPOINT) { if (descriptor[i+3] == 0x02) // Bulk { if (((descriptor[i+2] & 0x80) == 0x80) && (g_usbbt.endpointBulkIN == 0)) { g_usbbt.endpointBulkIN = descriptor[i+2]; } if (((descriptor[i+2] & 0x80) == 0x00) && (g_usbbt.endpointBulkOUT == 0)) { g_usbbt.endpointBulkOUT = descriptor[i+2]; } } else if(descriptor[i+3] == 0x03) // Interrupt { g_usbbt.endpointInt = descriptor[i+2]; } else if(descriptor[i+3] == 0x00) // Control { g_usbbt.endpointCtrl = descriptor[i+2]; } i += descriptor[i]; } if ((g_usbbt.endpointInt != 0) && (g_usbbt.endpointBulkIN != 0) && (g_usbbt.endpointBulkOUT != 0)) { g_usbbt.initialized = 1; g_usbbt.deviceAddress = address; g_usbbt.clientDriverID = clientDriverID; /* if(g_usbbt.endpointBulkIN_Busy == 0) { USBHostBlukRead(address,bulk_buf,MAX_DATA_PACKET_LENGTH); } if(g_usbbt.endpointInt_Busy == 0) { USBHostIntRead(address,int_buf,MAX_DATA_PACKET_LENGTH); }*/ UART2PrintString( " Control endpoint : " ); UART2PutHex( g_usbbt.endpointCtrl ); UART2PrintString( " Interrupt endpoint IN: " ); UART2PutHex( g_usbbt.endpointInt ); UART2PrintString( " Bulk endpoint IN: " ); UART2PutHex( g_usbbt.endpointBulkIN ); UART2PrintString( " Bulk endpoint OUT: " ); UART2PutHex( g_usbbt.endpointBulkOUT ); UART2PrintString( "\r\n" ); usb_bt_init(); return TRUE; } } // Jump to the next descriptor in this configuration. i += descriptor[i]; } return FALSE; }
BOOL USBHostUSBBTEventHandler( BYTE address, USB_EVENT event, void *data, DWORD size ) { switch (event) { case EVENT_NONE: // No event occured (NULL event) return TRUE; break; case EVENT_DETACH: // USB cable has been detached (data: BYTE, address of device) g_usbbt.initialized = 0; g_usbbt.deviceAddress = 0; UART2PrintString( "USBBT detach \r\n" ); return TRUE; break; case EVENT_TRANSFER: // A USB transfer has completed - optional #if defined( USB_ENABLE_TRANSFER_EVENT ) if ( (data != NULL) && (size == sizeof(HOST_TRANSFER_DATA)) ) { DWORD i; DWORD dataCount = ((HOST_TRANSFER_DATA *)data)->dataCount; BYTE *userData = ((HOST_TRANSFER_DATA *)data)->pUserData; // BYTE errorCode = ((HOST_TRANSFER_DATA *)data)->bErrorCode; if ( ((HOST_TRANSFER_DATA *)data)->bEndpointAddress == g_usbbt.endpointBulkIN ) { g_usbbt.endpointBulkIN_Busy = 0; if(dataCount != 0) { UART2PrintString( "BulkIN " ); for(i = 0; i < dataCount; i++) { UART2PutHex(userData[i]); } UART2PrintString( "\r\n" ); // bt event usb_bt_call_handler(USB_BT_EVENT_BULK_READ,userData,dataCount); } } else if ( ((HOST_TRANSFER_DATA *)data)->bEndpointAddress == g_usbbt.endpointBulkOUT ) { UART2PrintString( "BulkOUT \r\n" ); g_usbbt.endpointBulkOUT_Busy = 0; uint8_t dummy_event = DAEMON_EVENT_HCI_PACKET_SENT; packet_handler(HCI_EVENT_PACKET, &dummy_event, 1); } else if ( ((HOST_TRANSFER_DATA *)data)->bEndpointAddress == g_usbbt.endpointCtrl ) { UART2PrintString( "Ctrl \r\n" ); g_usbbt.endpointCtrl_Busy = 0; uint8_t dummy_event = DAEMON_EVENT_HCI_PACKET_SENT; packet_handler(HCI_EVENT_PACKET, &dummy_event, 1); } else if ( ((HOST_TRANSFER_DATA *)data)->bEndpointAddress == g_usbbt.endpointInt ) { g_usbbt.endpointInt_Busy = 0; if(dataCount != 0) { UART2PrintString( "Int " ); for(i = 0; i < dataCount; i++) { UART2PutHex(userData[i]); } UART2PrintString( "\r\n" ); // bt event usb_bt_call_handler(USB_BT_EVENT_INTERRUPT_READ,userData,dataCount); } } else { return FALSE; } if(!g_usbbt.endpointCtrl_Busy && !g_usbbt.endpointBulkOUT_Busy) { if(g_usbbt.endpointBulkIN_Busy == 0) { USBHostBlukRead(g_usbbt.deviceAddress,bulk_buf,MAX_DATA_PACKET_LENGTH); } if(g_usbbt.endpointInt_Busy == 0) { USBHostIntRead(g_usbbt.deviceAddress,int_buf,MAX_DATA_PACKET_LENGTH); } } return TRUE; } else return FALSE; #endif case EVENT_SOF: // Start of frame - NOT NEEDED case EVENT_RESUME: // Device-mode resume received case EVENT_SUSPEND: // Device-mode suspend/idle event received case EVENT_RESET: // Device-mode bus reset received case EVENT_STALL: // A stall has occured case EVENT_BUS_ERROR: default: break; } return FALSE; }
BOOL USB_ApplicationEventHandler ( BYTE address, USB_EVENT event, void *data, DWORD size ) { #ifdef USB_GENERIC_SUPPORT_SERIAL_NUMBERS BYTE i; #endif #ifdef DEBUG_MODE int data_num; #endif // Handle specific events. switch (event) { case EVENT_GENERIC_ATTACH: if (size == sizeof(GENERIC_DEVICE_ID)) { deviceAddress = ((GENERIC_DEVICE_ID *)data)->deviceAddress; UART2PrintString( "Generic demo device attached - event, deviceAddress=" ); UART2PutDec( deviceAddress ); UART2PrintString( "\r\n" ); #ifdef USB_GENERIC_SUPPORT_SERIAL_NUMBERS for (i=1; i<((GENERIC_DEVICE_ID *)data)->serialNumberLength; i++) { UART2PutChar( ((GENERIC_DEVICE_ID *)data)->serialNumber[i] ); } #endif UART2PrintString( "\r\n" ); btClientData.Initialized = TRUE; btClientData.State = BT_INITIALIZE; return TRUE; } break; case EVENT_GENERIC_DETACH: deviceAddress = 0; UART2PrintString( "Generic demo device detached - event\r\n" ); return TRUE; case EVENT_GENERIC_TX2_DONE: // The main state machine will poll the driver. // UART2PrintString( "TX2_DONE\r\n" ); return TRUE; case EVENT_GENERIC_RX2_DONE: if(*(DWORD*)data != 0) { #ifdef DEBUG_MODE UART2PrintString( "HCI:R2: " ); for(data_num=0;data_num<*(DWORD*)data;data_num++) {UART2PutHex(buf2[data_num]);UART2PutChar(' ');} UART2PrintString( "\r\n" ); #endif phybusif_input_acl(cb,buf2,*(DWORD*)data); } btClientData.State = BT_STATE_IDLE; return TRUE; case EVENT_GENERIC_RX1_DONE: if(*(DWORD*)data != 0) { #ifdef DEBUG_MODE UART2PrintString( "HCI:R1: " ); for(data_num=0;data_num<*(DWORD*)data;data_num++) {UART2PutHex(buf1[data_num]);UART2PutChar(' ');} UART2PrintString( "\r\n" ); #endif phybusif_input_event(cb,buf1,*(DWORD*)data); } btClientData.State = BT_STATE_IDLE; return TRUE; case EVENT_VBUS_REQUEST_POWER: // We'll let anything attach. return TRUE; case EVENT_VBUS_RELEASE_POWER: // We aren't keeping track of power. return TRUE; case EVENT_HUB_ATTACH: UART2PrintString( "\r\n***** USB Error - hubs are not supported *****\r\n" ); return TRUE; break; case EVENT_UNSUPPORTED_DEVICE: UART2PrintString( "\r\n***** USB Error - device is not supported *****\r\n" ); return TRUE; break; case EVENT_CANNOT_ENUMERATE: UART2PrintString( "\r\n***** USB Error - cannot enumerate device *****\r\n" ); return TRUE; break; case EVENT_CLIENT_INIT_ERROR: UART2PrintString( "\r\n***** USB Error - client driver initialization error *****\r\n" ); return TRUE; break; case EVENT_OUT_OF_MEMORY: UART2PrintString( "\r\n***** USB Error - out of heap memory *****\r\n" ); return TRUE; break; case EVENT_UNSPECIFIED_ERROR: // This should never be generated. UART2PrintString( "\r\n***** USB Error - unspecified *****\r\n" ); return TRUE; break; case EVENT_SUSPEND: case EVENT_DETACH: case EVENT_RESUME: case EVENT_BUS_ERROR: return TRUE; break; default: break; } return FALSE; } // USB_ApplicationEventHandler
BOOL USBHostMIDIInit ( BYTE address, DWORD flags, BYTE clientDriverID ) { BYTE *config_descriptor; BYTE *ptr; BYTE bDescriptorType; BYTE bLength; BYTE bNumEndpoints; BYTE bNumInterfaces; BYTE bInterfaceNumber; BYTE bAlternateSetting; BYTE Class; BYTE SubClass; BYTE Protocol; BYTE currentEndpoint; WORD wTotalLength; BYTE index = 0; BOOL error = FALSE; MIDI_DEVICE *device = &devices[0]; config_descriptor = USBHostGetCurrentConfigurationDescriptor(address); ptr = config_descriptor; // Load up the values from the Configuration Descriptor bLength = *ptr++; bDescriptorType = *ptr++; wTotalLength = *ptr++; // In case these are not word aligned wTotalLength += (*ptr++) << 8; bNumInterfaces = *ptr++; // Skip over the rest of the Configuration Descriptor index += bLength; ptr = &config_descriptor[index]; while (!error && (index < wTotalLength)) { // Check the descriptor length and type bLength = *ptr++; bDescriptorType = *ptr++; // Find an interface descriptor if (bDescriptorType != USB_DESCRIPTOR_INTERFACE) { // Skip over the rest of the Descriptor index += bLength; ptr = &config_descriptor[index]; } else { // Read some data from the interface descriptor bInterfaceNumber = *ptr++; bAlternateSetting = *ptr++; bNumEndpoints = *ptr++; Class = *ptr++; SubClass = *ptr++; Protocol = *ptr++; // Check to see if this is a MIDI inteface descripter if (Class != AUDIO_CLASS || SubClass != MIDI_SUB_CLASS || Protocol != MIDI_PROTOCOL) { // If we cannot support this interface, skip it. index += bLength; ptr = &config_descriptor[index]; continue; } // Initialize the device device->deviceAddress = address; device->clientDriverID = clientDriverID; device->numEndpoints = bNumEndpoints; // Allocate enough memory for each endpoint if ((device->endpoints = (MIDI_ENDPOINT_DATA*)malloc( sizeof(MIDI_ENDPOINT_DATA) * bNumEndpoints)) == NULL) { // Out of memory error = TRUE; } if (!error) { // Skip over the rest of the Interface Descriptor index += bLength; ptr = &config_descriptor[index]; // Find the Endpoint Descriptors. There might be Class and Vendor descriptors in here currentEndpoint = 0; while (!error && (index < wTotalLength) && (currentEndpoint < bNumEndpoints)) { bLength = *ptr++; bDescriptorType = *ptr++; if (bDescriptorType != USB_DESCRIPTOR_ENDPOINT) { // Skip over the rest of the Descriptor index += bLength; ptr = &config_descriptor[index]; } else { device->endpoints[currentEndpoint].endpointAddress = *ptr++; ptr++; device->endpoints[currentEndpoint].endpointSize = *ptr++; device->endpoints[currentEndpoint].endpointSize += (*ptr++) << 8; device->endpoints[currentEndpoint].busy = FALSE; if(device->endpoints[currentEndpoint].endpointSize > 64) { // For full speed bulk endpoints, only 8, 16, 32, and 64 byte packets are supported // But we will accept anything less than or equal to 64. error = TRUE; } // Get ready for the next endpoint. currentEndpoint++; index += bLength; ptr = &config_descriptor[index]; } } } // Ensure that we found all the endpoints for this interface. if (currentEndpoint != bNumEndpoints) { error = TRUE; } } } if (error) { // Destroy whatever list of interfaces, settings, and endpoints we created. // The "new" variables point to the current node we are trying to remove. if (device->endpoints != NULL) { free( device->endpoints ); device->endpoints = NULL; } return FALSE; } #ifdef DEBUG_MODE UART2PrintString( "USB MIDI Client Initalized: " ); UART2PrintString( " address=" ); UART2PutDec( address ); UART2PrintString( " Number of Endpoings=" ); UART2PutHex( bNumEndpoints ); UART2PrintString( "\r\n" ); #endif // Notify that application that we've been attached to a device. USB_HOST_APP_EVENT_HANDLER(address, EVENT_MIDI_ATTACH, device, sizeof(MIDI_DEVICE) ); return TRUE; } // USBHostMIDIInit