void APP_Tasks (void ) { switch(appData.state) { case APP_STATE_INIT: /* Open an instance of the device layer */ appData.deviceHandle = USB_DEVICE_Open( 0, DRV_IO_INTENT_READWRITE ); /* Register a callback with device layer to get * event notification (for end point 0) */ USB_DEVICE_EventCallBackSet(appData.deviceHandle, APP_USBDeviceEventHandler); /* Attach the device */ USB_DEVICE_Attach(appData.deviceHandle); appData.state = APP_STATE_WAIT_FOR_CONFIGURATION; break; case APP_STATE_WAIT_FOR_CONFIGURATION: /* Check if the device is configured. The * isConfigured flag is updated in the * Device Event Handler */ if(appData.isConfigured) { /* Initialize the flag and place a request for a * output report */ appData.isReportReceived = false; USB_DEVICE_HID_ReportReceive(appData.hidInstance, &appData.receiveTransferHandle, (uint8_t *)&appData.keyboardOutputReport,1); appData.state = APP_STATE_CHECK_IF_CONFIGURED; } break; case APP_STATE_CHECK_IF_CONFIGURED: /* This state is needed because the device can get * unconfigured asynchronously. Any application state * machine reset should happen within the state machine * context only. */ if(appData.isConfigured) { appData.state = APP_STATE_SWITCH_PROCESS; } else { /* This means the device got de-configured. * We reset the state and the wait for configuration */ APP_StateReset(); appData.state = APP_STATE_WAIT_FOR_CONFIGURATION; } break; case APP_STATE_SWITCH_PROCESS: /* Process the switch state and go to the * next state. */ APP_ProcessSwitchPress(&appData); appData.state = APP_STATE_CHECK_FOR_OUTPUT_REPORT; break; case APP_STATE_CHECK_FOR_OUTPUT_REPORT: if(appData.isReportReceived == true) { /* Update the LED and schedule and * request */ APP_KeyboardLEDStatus(); appData.isReportReceived = false; USB_DEVICE_HID_ReportReceive(appData.hidInstance, &appData.receiveTransferHandle, (uint8_t *)&appData.keyboardOutputReport,1); } appData.state = APP_STATE_EMULATE_KEYBOARD; break; case APP_STATE_EMULATE_KEYBOARD: if(appData.isReportSentComplete) { /* This means report can be sent*/ APP_EmulateKeyboard(); appData.isReportSentComplete = false; USB_DEVICE_HID_ReportSend(appData.hidInstance, &appData.sendTransferHandle, (uint8_t *)&appData.keyboardInputReport, sizeof(KEYBOARD_INPUT_REPORT)); } appData.state = APP_STATE_CHECK_IF_CONFIGURED; break; case APP_STATE_ERROR: break; default: break; } }
void APP_Tasks ( void ) { //static int8_t vector = 0; static uint8_t movement_length = 0; static bool sent_dont_move = false; short accels[3]; double xvel; double yvel; //int8_t dir_table[] ={-4,-4,-4, 0, 4, 4, 4, 0}; /* Check the application's current state. */ switch ( appData.state ) { /* Application's initial state. */ case APP_STATE_INIT: { /* Open the device layer */ appData.deviceHandle = USB_DEVICE_Open( USB_DEVICE_INDEX_0, DRV_IO_INTENT_READWRITE ); if(appData.deviceHandle != USB_DEVICE_HANDLE_INVALID) { /* Register a callback with device layer to get event notification (for end point 0) */ USB_DEVICE_EventHandlerSet(appData.deviceHandle, APP_USBDeviceEventHandler, 0); appData.state = APP_STATE_WAIT_FOR_CONFIGURATION; } else { /* The Device Layer is not ready to be opened. We should try * again later. */ } break; } case APP_STATE_WAIT_FOR_CONFIGURATION: /* Check if the device is configured. The * isConfigured flag is updated in the * Device Event Handler */ if(appData.isConfigured) { appData.state = APP_STATE_MOUSE_EMULATE; } break; case APP_STATE_MOUSE_EMULATE: APP_ProcessSwitchPress(); /* The following logic rotates the mouse icon when * a switch is pressed */ if(appData.isSwitchPressed) { /* Toggle the mouse emulation with each switch press */ appData.emulateMouse ^= 1; appData.isSwitchPressed = false; } if(appData.emulateMouse) { sent_dont_move = false; if(movement_length > 50) { acc_read_register(OUT_X_L_A, (unsigned char *) accels, 6); xvel = accels[0]/10000; yvel = accels[1]/10000; appData.xCoordinate = (double) xvel; appData.yCoordinate = (double) yvel; appData.mouseButton[0] = MOUSE_BUTTON_STATE_RELEASED; appData.mouseButton[1] = MOUSE_BUTTON_STATE_RELEASED; //appData.xCoordinate =(int8_t)dir_table[vector & 0x07] ; //appData.yCoordinate =(int8_t)dir_table[(vector+2) & 0x07]; //vector ++; movement_length = 0; } } else { appData.mouseButton[0] = MOUSE_BUTTON_STATE_RELEASED; appData.mouseButton[1] = MOUSE_BUTTON_STATE_RELEASED; appData.xCoordinate = 0; appData.yCoordinate = 0; } if(!appData.isMouseReportSendBusy) { if(((sent_dont_move == false) && (!appData.emulateMouse)) || (appData.emulateMouse)) { /* This means we can send the mouse report. The isMouseReportBusy flag is updated in the HID Event Handler. */ appData.isMouseReportSendBusy = true; /* Create the mouse report */ MOUSE_ReportCreate(appData.xCoordinate, appData.yCoordinate, appData.mouseButton, &mouseReport); if(memcmp((const void *)&mouseReportPrevious, (const void *)&mouseReport, (size_t)sizeof(mouseReport)) == 0) { /* Reports are same as previous report. However mouse reports * can be same as previous report as the co-ordinate positions are relative. * In that case it needs to be send */ if((appData.xCoordinate == 0) && (appData.yCoordinate == 0)) { /* If the coordinate positions are 0, that means there * is no relative change */ if(appData.idleRate == 0) { appData.isMouseReportSendBusy = false; } else { /* Check the idle rate here. If idle rate time elapsed * then the data will be sent. Idle rate resolution is * 4 msec as per HID specification; possible range is * between 4msec >= idlerate <= 1020 msec. */ if(appData.setIdleTimer * APP_USB_CONVERT_TO_MILLISECOND >= appData.idleRate * 4) { /* Send REPORT as idle time has elapsed */ appData.isMouseReportSendBusy = true; } else { /* Do not send REPORT as idle time has not elapsed */ appData.isMouseReportSendBusy = false; } } } } if(appData.isMouseReportSendBusy == true) { /* Copy the report sent to previous */ memcpy((void *)&mouseReportPrevious, (const void *)&mouseReport, (size_t)sizeof(mouseReport)); /* Send the mouse report. */ USB_DEVICE_HID_ReportSend(appData.hidInstance, &appData.reportTransferHandle, (uint8_t*)&mouseReport, sizeof(MOUSE_REPORT)); appData.setIdleTimer = 0; } movement_length ++; sent_dont_move = true; } } break; case APP_STATE_ERROR: break; /* The default state should never be executed. */ default: { /* TODO: Handle error in application's state machine. */ break; } } }
/********************************************************** * Application tasks routine. This function implements the * application state machine. ***********************************************************/ void APP_Tasks ( APP_DATA * appData ) { /* Update the application state machine based * on the current state */ USB_DEVICE_CDC_RESULT result; APP_ProcessSwitchPress(appData); switch(appData->state) { case APP_STATE_INIT: /* Open the device layer */ appData->deviceHandle = USB_DEVICE_Open( USB_DEVICE_INDEX_0, DRV_IO_INTENT_READWRITE ); if(appData->deviceHandle == USB_DEVICE_HANDLE_INVALID) { SYS_ASSERT(false, "Could not open device layer"); appData->state = APP_STATE_ERROR; break; } /* Register a callback with device layer to get event notification (for end point 0) */ USB_DEVICE_EventCallBackSet(appData->deviceHandle, APP_USBDeviceEventHandler); /* Attach the device */ USB_DEVICE_Attach (appData->deviceHandle); appData->state = APP_STATE_WAIT_FOR_CONFIGURATION; break; case APP_STATE_WAIT_FOR_CONFIGURATION: /* Check if the device was configured */ if(appData->isConfigured) { /* If the device is configured then lets start reading */ appData->state = APP_STATE_SCHEDULE_READ; } break; case APP_STATE_SCHEDULE_READ: if(APP_StateReset()) { break; } /* If a read is complete, then schedule a read * else wait for the current read to complete */ appData->state = APP_STATE_WAIT_FOR_READ_COMPLETE; if(appData->isReadComplete == true) { appData->isReadComplete = false; appData->readTransferHandle = USB_DEVICE_CDC_TRANSFER_HANDLE_INVALID; USB_DEVICE_CDC_Read (appData->cdcInstance, &appData->readTransferHandle, appData->readBuffer, 64); if(appData->readTransferHandle == USB_DEVICE_CDC_TRANSFER_HANDLE_INVALID) { appData->state = APP_STATE_ERROR; break; } } break; case APP_STATE_WAIT_FOR_READ_COMPLETE: case APP_STATE_CHECK_SWITCH_PRESSED: if(APP_StateReset()) { break; } /* Check if a character was received or a switch was pressed. * The isReadComplete flag gets updated in the CDC event handler. */ if(appData->isReadComplete || appData->isSwitchPressed) { appData->state = APP_STATE_SCHEDULE_WRITE; } break; case APP_STATE_SCHEDULE_WRITE: if(APP_StateReset()) { break; } /* Setup the write */ appData->writeTransferHandle = USB_DEVICE_CDC_TRANSFER_HANDLE_INVALID; appData->isWriteComplete = false; appData->state = APP_STATE_WAIT_FOR_WRITE_COMPLETE; if(appData->isSwitchPressed) { /* If the switch was pressed, then send the switch prompt*/ appData->isSwitchPressed = false; result = USB_DEVICE_CDC_Write(appData->cdcInstance, &appData->writeTransferHandle, switchPrompt, 23, USB_DEVICE_CDC_TRANSFER_FLAGS_DATA_COMPLETE); } else { /* Else echo the received character + 1*/ appData->readBuffer[0] = appData->readBuffer[0] + 1; USB_DEVICE_CDC_Write(appData->cdcInstance, &appData->writeTransferHandle, appData->readBuffer, 1, USB_DEVICE_CDC_TRANSFER_FLAGS_DATA_COMPLETE); } break; case APP_STATE_WAIT_FOR_WRITE_COMPLETE: if(APP_StateReset()) { break; } /* Check if a character was sent. The isWriteComplete * flag gets updated in the CDC event handler */ if(appData->isWriteComplete == true) { appData->state = APP_STATE_SCHEDULE_READ; } break; case APP_STATE_ERROR: break; default: break; } }