/**************************************************************************** Function: void App_Detect_Device(void) Description: This function monitors the status of device connected/disconnected Precondition: None Parameters: None Return Values: None Remarks: None ***************************************************************************/ void App_Detect_Device(void) { if(!USBHostHID_ApiDeviceDetect()) { App_State_Mouse_Keyboard = DEVICE_NOT_CONNECTED; } }
void hidTask (void) { BYTE i; int deviceValue = 0; USBTasks(); App_Detect_Device(); switch (App_State_Mouse_Keyboard) { case DEVICE_NOT_CONNECTED: connectedDevice = DEVICE_NOT_CONNECTED_OR_NOT_SUPPORTED; USBTasks(); if (DisplayDeatachOnce == FALSE) { DisplayDeatachOnce = TRUE; } if (USBHostHID_ApiDeviceDetect()) { DisplayConnectOnce = FALSE; deviceValue = USBHID_ReportDecriptor_Difference(); if (deviceValue == USB_HID_MOUSE) { App_State_Mouse_Keyboard = MOUSE_DEVICE_CONNECTED; } else if (deviceValue == USB_HID_KEYBOARD) { App_State_Mouse_Keyboard = KEYBOARD_DEVICE_CONNECTED; } } break; case MOUSE_DEVICE_CONNECTED: UART2PrintString("\r\n"); UART2PrintString(UHP_MOUSE_CONNECTED); UART2PrintString("\r\n"); connectedDevice = DEVICE_MOUSE; App_State_Mouse_Keyboard = MOUSE_READY_TO_TX_RX_REPORT; if (DisplayConnectOnce == FALSE) { DisplayConnectOnce = TRUE; DisplayDeatachOnce = FALSE; } break; case KEYBOARD_DEVICE_CONNECTED: UART2PrintString("\r\n"); UART2PrintString(UHP_KEYBOARD_CONNECTED); UART2PrintString("\r\n"); connectedDevice = DEVICE_KEYBOARD; App_State_Mouse_Keyboard = KEYBOARD_READY_TO_TX_RX_REPORT; if (DisplayConnectOnce == FALSE) { DisplayConnectOnce = TRUE; DisplayDeatachOnce = FALSE; } InitializeTimer(); break; case MOUSE_READY_TO_TX_RX_REPORT: if (!USBHostHID_ApiDeviceDetect()) { App_State_Mouse_Keyboard = DEVICE_NOT_CONNECTED; } else { App_State_Mouse_Keyboard = MOUSE_GET_INPUT_REPORT; } break; case KEYBOARD_READY_TO_TX_RX_REPORT: if (!USBHostHID_ApiDeviceDetect()) { App_State_Mouse_Keyboard = DEVICE_NOT_CONNECTED; } break; case MOUSE_GET_INPUT_REPORT: if (USBHostHID_ApiGetReport(Appl_raw_report_buffer.Report_ID, 0, Appl_raw_report_buffer.ReportSize, Appl_raw_report_buffer.ReportData)) { // Host may be busy/error -- keep trying } else { App_State_Mouse_Keyboard = MOUSE_INPUT_REPORT_PENDING; } USBTasks(); break; case KEYBOARD_GET_INPUT_REPORT: if (USBHostHID_ApiGetReport(Appl_raw_report_buffer.Report_ID, Appl_ModifierKeysDetails.interfaceNum, Appl_raw_report_buffer.ReportSize, Appl_raw_report_buffer.ReportData)) { /* Host may be busy/error -- keep trying */ } else { App_State_Mouse_Keyboard = KEYBOARD_INPUT_REPORT_PENDING; } USBTasks(); break; case MOUSE_INPUT_REPORT_PENDING: if (USBHostHID_ApiTransferIsComplete(&ErrorDriver, &NumOfBytesRcvd)) { if (ErrorDriver || (NumOfBytesRcvd != Appl_raw_report_buffer.ReportSize)) { ErrorCounter++; if (MAX_ERROR_COUNTER <= ErrorDriver) App_State_Mouse_Keyboard = ERROR_REPORTED; else App_State_Mouse_Keyboard = MOUSE_READY_TO_TX_RX_REPORT; } else { ErrorCounter = 0; ReportBufferUpdated = TRUE; App_State_Mouse_Keyboard = MOUSE_READY_TO_TX_RX_REPORT; if (DisplayConnectOnce == TRUE) { for (i = 0; i < Appl_raw_report_buffer.ReportSize; i++) { if (Appl_raw_report_buffer.ReportData[i] != 0) { DisplayConnectOnce = FALSE; } } } App_ProcessInputReport_Mouse(); } } break; case KEYBOARD_INPUT_REPORT_PENDING: if (USBHostHID_ApiTransferIsComplete(&ErrorDriver, &NumOfBytesRcvd)) { if (ErrorDriver || (NumOfBytesRcvd != Appl_raw_report_buffer.ReportSize)) { ErrorCounter++; if (MAX_ERROR_COUNTER <= ErrorDriver) { App_State_Mouse_Keyboard = ERROR_REPORTED; } else { App_State_Mouse_Keyboard = KEYBOARD_READY_TO_TX_RX_REPORT; } } else { ErrorCounter = 0; ReportBufferUpdated = TRUE; App_State_Mouse_Keyboard = KEYBOARD_READY_TO_TX_RX_REPORT; if (DisplayConnectOnce == TRUE) { for (i = 0; i < Appl_raw_report_buffer.ReportSize; i++) { if (Appl_raw_report_buffer.ReportData[i] != 0) { DisplayConnectOnce = FALSE; } } } App_ProcessInputReport_Keyboard(); App_PrepareOutputReport(); } } break; case SEND_OUTPUT_REPORT: /* Will be done while implementing Keyboard */ if (USBHostHID_ApiSendReport(Appl_LED_Indicator.reportID, Appl_LED_Indicator.interfaceNum, Appl_LED_Indicator.reportLength, (BYTE*) & Appl_led_report_buffer)) { /* Host may be busy/error -- keep trying */ } else { App_State_Mouse_Keyboard = OUTPUT_REPORT_PENDING; } USBTasks(); break; case OUTPUT_REPORT_PENDING: if (USBHostHID_ApiTransferIsComplete(&ErrorDriver, &NumOfBytesRcvd)) { if (ErrorDriver) { ErrorCounter++; if (MAX_ERROR_COUNTER <= ErrorDriver) App_State_Mouse_Keyboard = ERROR_REPORTED; } else { ErrorCounter = 0; App_State_Mouse_Keyboard = KEYBOARD_READY_TO_TX_RX_REPORT; } } break; case ERROR_REPORTED: break; default: break; } }
/********************************************************************* * 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; } }
/********************************************************************* * 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(keyboard.state != WAITING_FOR_DEVICE) { keyboard.state = DEVICE_NOT_CONNECTED; keyboard.inUse = false; if(keyboard.keys.buffer != NULL) { free(keyboard.keys.buffer); keyboard.keys.buffer = NULL; } } } switch(keyboard.state) { case DEVICE_NOT_CONNECTED: PRINT_ClearScreen(); PRINT_String("Attach keyboard\r\n", 17); keyboard.state = WAITING_FOR_DEVICE; 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); keyboard.state = DEVICE_CONNECTED; TIMER_RequestTick(&APP_HostHIDTimerHandler, 10); } break; case DEVICE_CONNECTED: break; case GET_INPUT_REPORT: if(USBHostHID_ApiGetReport( keyboard.keys.id, keyboard.keys.normal.parsed.details.interfaceNum, keyboard.keys.size, keyboard.keys.buffer ) ) { /* Host may be busy/error -- keep trying */ } else { keyboard.state = INPUT_REPORT_PENDING; } break; case INPUT_REPORT_PENDING: if(USBHostHID_ApiTransferIsComplete(&error, &count)) { if(error || (count == 0)) { keyboard.state = DEVICE_CONNECTED; } else { keyboard.state = DEVICE_CONNECTED; App_ProcessInputReport(); if(keyboard.leds.updated == true) { keyboard.state = SEND_OUTPUT_REPORT; } } } break; case SEND_OUTPUT_REPORT: /* Will be done while implementing Keyboard */ if(USBHostHID_ApiSendReport( keyboard.leds.parsed.details.reportID, keyboard.leds.parsed.details.interfaceNum, keyboard.leds.parsed.details.reportLength, (uint8_t*)&keyboard.leds.report ) ) { /* Host may be busy/error -- keep trying */ } else { keyboard.state = OUTPUT_REPORT_PENDING; } break; case OUTPUT_REPORT_PENDING: if(USBHostHID_ApiTransferIsComplete(&error, &count)) { keyboard.leds.updated = false; keyboard.state = DEVICE_CONNECTED; } break; case ERROR_REPORTED: break; default: break; } }
/********************************************************************* * Function: void APP_HostHIDMouseTasks(void); * * Overview: Keeps the demo running. * * PreCondition: The demo should have been initialized via * the APP_HostHIDMouseInitialize() * * Input: None * * Output: None * ********************************************************************/ void APP_HostHIDMouseTasks() { uint8_t error; uint8_t count; if(!USBHostHID_ApiDeviceDetect()) { if(mouse.state != WAITING_FOR_DEVICE) { mouse.state = DEVICE_NOT_CONNECTED; mouse.inUse = false; if(mouse.buffer != NULL) { free(mouse.buffer); mouse.buffer = NULL; } } } switch(mouse.state) { case DEVICE_NOT_CONNECTED: PRINT_ClearScreen(); PRINT_String("Attach mouse\r\n", 17); mouse.state = WAITING_FOR_DEVICE; break; case WAITING_FOR_DEVICE: if(USBHostHID_ApiDeviceDetect()) /* True if report descriptor is parsed with no error */ { SYSTEM_Initialize(SYSTEM_STATE_USB_HOST_HID_MOUSE); PRINT_ClearScreen(); PRINT_String("L:0 R:0\r\nX:0x00 Y:0x00\r\n", 24); mouse.state = DEVICE_CONNECTED; TIMER_RequestTick(&APP_HostHIDTimerHandler, 10); } break; case DEVICE_CONNECTED: break; case GET_INPUT_REPORT: if(USBHostHID_ApiGetReport( mouse.deflection.parsed.details.reportID, mouse.deflection.parsed.details.interfaceNum, mouse.deflection.parsed.details.reportLength, mouse.buffer ) ) { /* Host may be busy/error -- keep trying */ } else { mouse.state = INPUT_REPORT_PENDING; } break; case INPUT_REPORT_PENDING: if(USBHostHID_ApiTransferIsComplete(&error, &count)) { if(error || (count != mouse.deflection.parsed.details.reportLength)) { mouse.state = DEVICE_CONNECTED; } else { mouse.state = DEVICE_CONNECTED; App_ProcessInputReport(); } } break; case ERROR_REPORTED: break; default: break; } }
//****************************************************************************** //****************************************************************************** // Main //****************************************************************************** //****************************************************************************** int main (void) { BYTE i; DWORD temp; int value; value = SYSTEMConfigWaitStatesAndPB( GetSystemClock() ); mJTAGPortEnable(DEBUG_JTAGPORT_OFF); // Enable the cache for the best performance CheKseg0CacheOn(); value = OSCCON; while (!(value & 0x00000020)) { value = OSCCON; // Wait for PLL lock to stabilize } InitKeyboardDriver(); INTEnableSystemMultiVectoredInt(); // Init status LED mPORTCSetBits(BIT_0); mPORTCSetPinsDigitalOut(BIT_0); //DBINIT(); // Initialize USB layers USBInitialize(0); while (1) { USBTasks(); App_Detect_Device(); switch (App_State_Keyboard) { case DEVICE_NOT_CONNECTED: mPORTCSetBits(BIT_0); USBTasks(); if (DisplayDeatachOnce == FALSE) { DBPRINTF("Device Detached\n"); DisplayDeatachOnce = TRUE; } if (USBHostHID_ApiDeviceDetect()) /* True if report descriptor is parsed with no error */ { DBPRINTF("Device Attached\n"); App_State_Keyboard = DEVICE_CONNECTED; DisplayConnectOnce = FALSE; } break; case DEVICE_CONNECTED: mPORTCClearBits(BIT_0); App_State_Keyboard = READY_TO_TX_RX_REPORT; if (DisplayConnectOnce == FALSE) { DisplayConnectOnce = TRUE; DisplayDeatachOnce = FALSE; } InitializeTimer(); // start 10ms timer to schedule input reports break; case READY_TO_TX_RX_REPORT: if (!USBHostHID_ApiDeviceDetect()) { App_State_Keyboard = DEVICE_NOT_CONNECTED; // DisplayOnce = FALSE; } break; case GET_INPUT_REPORT: if (USBHostHID_ApiGetReport(Appl_raw_report_buffer.Report_ID, Appl_ModifierKeysDetails.interfaceNum, Appl_raw_report_buffer.ReportSize, Appl_raw_report_buffer.ReportData)) { /* Host may be busy/error -- keep trying */ } else { App_State_Keyboard = INPUT_REPORT_PENDING; } USBTasks(); break; case INPUT_REPORT_PENDING: if (USBHostHID_ApiTransferIsComplete(&ErrorDriver, &NumOfBytesRcvd)) { if (ErrorDriver || (NumOfBytesRcvd != Appl_raw_report_buffer.ReportSize )) { ErrorCounter++ ; if (MAX_ERROR_COUNTER <= ErrorDriver) App_State_Keyboard = ERROR_REPORTED; else App_State_Keyboard = READY_TO_TX_RX_REPORT; } else { ErrorCounter = 0; ReportBufferUpdated = TRUE; App_State_Keyboard = READY_TO_TX_RX_REPORT; if (DisplayConnectOnce == TRUE) { for (i = 0; i < Appl_raw_report_buffer.ReportSize; i++) { if (Appl_raw_report_buffer.ReportData[i] != 0) { //LCDClear(); //LCDL1Home(); DisplayConnectOnce = FALSE; } } } App_ProcessInputReport(); App_PrepareOutputReport(); } } break; case SEND_OUTPUT_REPORT: /* Will be done while implementing Keyboard */ if (USBHostHID_ApiSendReport(Appl_LED_Indicator.reportID, Appl_LED_Indicator.interfaceNum, Appl_LED_Indicator.reportLength, (BYTE*) & Appl_led_report_buffer)) { /* Host may be busy/error -- keep trying */ } else { App_State_Keyboard = OUTPUT_REPORT_PENDING; } USBTasks(); break; case OUTPUT_REPORT_PENDING: if (USBHostHID_ApiTransferIsComplete(&ErrorDriver, &NumOfBytesRcvd)) { if (ErrorDriver) { ErrorCounter++ ; if (MAX_ERROR_COUNTER <= ErrorDriver) App_State_Keyboard = ERROR_REPORTED; // App_State_Keyboard = READY_TO_TX_RX_REPORT; } else { ErrorCounter = 0; App_State_Keyboard = READY_TO_TX_RX_REPORT; } } break; case ERROR_REPORTED: break; default: break; } } }
/********************************************************************* * Function: void APP_HostHIDPICkitTasks(void); * * Overview: Keeps the demo running. * * PreCondition: The demo should have been initialized via * the APP_HostHIDPICkitInitialize() * * Input: None * * Output: None * ********************************************************************/ void APP_HostHIDPICkitTasks() { 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; IEC1bits.U2RXIE= 0; //?timijk disable RXIE LED_Off(LED_USB_HOST_HID_PICKIT_DEVICE_READY); break; case WAITING_FOR_DEVICE: if (USBHostHID_ApiDeviceDetect()) /* True if report descriptor is parsed with no error */ { SYSTEM_Initialize(SYSTEM_STATE_USB_HOST_HID_PICKIT); LED_On(LED_USB_HOST_HID_PICKIT_DEVICE_READY); pickit.state = DEVICE_CONNECTED; } break; case DEVICE_CONNECTED: if( isCmdQueEmpty()) break; if(getCmdQueSize()==1) { //if the size of commands is 1, it means read from USB device pickit.state = GET_INPUT_REPORT; incCmdBufferRdIdx(); } else { pickit.state = SEND_OUTPUT_REPORT; } break; case GET_INPUT_REPORT: if (USBHostHID_ApiGetReport(pickit.details.reportID, pickit.details.interfaceNum, pickit.size, (uint8_t *)rspBuffer //pickit.buffer ) ) { /* Host may be busy/error -- keep trying */ } else { pickit.state = INPUT_REPORT_PENDING; } break; case INPUT_REPORT_PENDING: if (USBHostHID_ApiTransferIsComplete(&error, &count)) { if (error || (count == 0)) { pickit.state = GET_INPUT_REPORT; // retry } else { pickit.state = DEVICE_CONNECTED; App_ProcessInputReport(); } } break; case SEND_OUTPUT_REPORT: //TMR4=0; //?timijk performance test::start timer App_PrepareOutputReport(); if (USBHostHID_ApiSendReport(pickit.details.reportID, pickit.details.interfaceNum, pickit.size, pickit.buffer )) { /* Host may be busy/error -- keep trying */ } else { pickit.state = OUTPUT_REPORT_PENDING; //retry_count=0; } break; case OUTPUT_REPORT_PENDING: //timijk 2016.01.13 Issue if (USBHostHID_ApiTransferIsComplete(&error, &count)) { //signal the transaction is complete U2TXREG = TMR4>>8; pickit.state = DEVICE_CONNECTED; //LATBbits.LATB4=0; } break; case ERROR_REPORTED: break; default: break; }