/** Task to determine if the user is wishes to start the programming sequence, and if so executes the * required functions to program the attached target (if any) with the files loaded to the Dataflash. */ void Programmer_Task(void) { static bool HasAttempted = false; if (Buttons_GetStatus() & BUTTONS_BUTTON1) { if (!(HasAttempted)) HasAttempted = true; else return; puts("==== PROGRAMMING CYCLE STARTED ====\r\n"); #if defined(USB_CAN_BE_BOTH) printf("Using %s Drive...\r\n", (USB_CurrentMode == USB_MODE_Host) ? "External" : "Internal"); #endif puts("Reading Configuration File...\r\n"); if (!(ProgrammerConfig_ProcessConfiguration())) goto EndOfProgCycle; EndOfProgCycle: puts("==== PROGRAMMING CYCLE FINISHED ====\r\n"); } else { HasAttempted = false; } }
/** HID class driver callback function for the creation of HID reports to the host. * * \param[in] HIDInterfaceInfo Pointer to the HID class interface configuration structure being referenced * \param[in,out] ReportID Report ID requested by the host if non-zero, otherwise callback should set to the generated report ID * \param[in] ReportType Type of the report to create, either HID_REPORT_ITEM_In or HID_REPORT_ITEM_Feature * \param[out] ReportData Pointer to a buffer where the created report should be stored * \param[out] ReportSize Number of bytes written in the report (or zero if no report is to be sent) * * \return Boolean true to force the sending of the report, false to let the library determine if it needs to be sent */ bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, uint8_t* const ReportID, const uint8_t ReportType, void* ReportData, uint16_t* const ReportSize) { USB_KeyboardReport_Data_t* KeyboardReport = (USB_KeyboardReport_Data_t*)ReportData; uint8_t JoyStatus_LCL = Joystick_GetStatus(); uint8_t ButtonStatus_LCL = Buttons_GetStatus(); uint8_t UsedKeyCodes = 0; if (JoyStatus_LCL & JOY_UP) KeyboardReport->KeyCode[UsedKeyCodes++] = HID_KEYBOARD_SC_A; else if (JoyStatus_LCL & JOY_DOWN) KeyboardReport->KeyCode[UsedKeyCodes++] = HID_KEYBOARD_SC_B; if (JoyStatus_LCL & JOY_LEFT) KeyboardReport->KeyCode[UsedKeyCodes++] = HID_KEYBOARD_SC_C; else if (JoyStatus_LCL & JOY_RIGHT) KeyboardReport->KeyCode[UsedKeyCodes++] = HID_KEYBOARD_SC_D; if (JoyStatus_LCL & JOY_PRESS) KeyboardReport->KeyCode[UsedKeyCodes++] = HID_KEYBOARD_SC_E; if (ButtonStatus_LCL & BUTTONS_BUTTON1) KeyboardReport->KeyCode[UsedKeyCodes++] = HID_KEYBOARD_SC_F; if (UsedKeyCodes) KeyboardReport->Modifier = HID_KEYBOARD_MODIFIER_LEFTSHIFT; *ReportSize = sizeof(USB_KeyboardReport_Data_t); return false; }
/* Routine to update keyboard state */ static void Keyboard_UpdateReport(void) { uint8_t joystick_status = Joystick_GetStatus(); HID_KEYBOARD_CLEAR_REPORT(&g_keyBoard.report[0]); switch (joystick_status) { case JOY_PRESS: HID_KEYBOARD_REPORT_SET_KEY_PRESS(g_keyBoard.report, 0x53); break; case JOY_LEFT: HID_KEYBOARD_REPORT_SET_KEY_PRESS(g_keyBoard.report, 0x5C); break; case JOY_RIGHT: HID_KEYBOARD_REPORT_SET_KEY_PRESS(g_keyBoard.report, 0x5E); break; case JOY_UP: HID_KEYBOARD_REPORT_SET_KEY_PRESS(g_keyBoard.report, 0x60); break; case JOY_DOWN: HID_KEYBOARD_REPORT_SET_KEY_PRESS(g_keyBoard.report, 0x5A); break; case NO_BUTTON_PRESSED: if (Buttons_GetStatus() != NO_BUTTON_PRESSED) HID_KEYBOARD_REPORT_SET_KEY_PRESS(g_keyBoard.report, 0x57); break; } }
/** HID class driver callback function for the creation of HID reports to the host. * * \param[in] HIDInterfaceInfo Pointer to the HID class interface configuration structure being referenced * \param[in,out] ReportID Report ID requested by the host if non-zero, otherwise callback should set to the generated report ID * \param[in] ReportType Type of the report to create, either REPORT_ITEM_TYPE_In or REPORT_ITEM_TYPE_Feature * \param[out] ReportData Pointer to a buffer where the created report should be stored * \param[out] ReportSize Number of bytes written in the report (or zero if no report is to be sent * * \return Boolean true to force the sending of the report, false to let the library determine if it needs to be sent */ bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, uint8_t* const ReportID, const uint8_t ReportType, void* ReportData, uint16_t* ReportSize) { USB_MouseReport_Data_t* MouseReport = (USB_MouseReport_Data_t*)ReportData; uint8_t JoyStatus_LCL = Joystick_GetStatus(); uint8_t ButtonStatus_LCL = Buttons_GetStatus(); if (JoyStatus_LCL & JOY_UP) MouseReport->Y = -1; else if (JoyStatus_LCL & JOY_DOWN) MouseReport->Y = 1; if (JoyStatus_LCL & JOY_RIGHT) MouseReport->X = 1; else if (JoyStatus_LCL & JOY_LEFT) MouseReport->X = -1; if (JoyStatus_LCL & JOY_PRESS) MouseReport->Button = (1 << 0); if (ButtonStatus_LCL & BUTTONS_BUTTON1) MouseReport->Button |= (1 << 1); *ReportSize = sizeof(USB_MouseReport_Data_t); return true; }
/** HID class driver callback function for the creation of HID reports to the host. * * \param[in] HIDInterfaceInfo Pointer to the HID class interface configuration structure being referenced * \param[in,out] ReportID Report ID requested by the host if non-zero, otherwise callback should set to the generated report ID * \param[in] ReportType Type of the report to create, either REPORT_ITEM_TYPE_In or REPORT_ITEM_TYPE_Feature * \param[out] ReportData Pointer to a buffer where the created report should be stored * \param[out] ReportSize Number of bytes written in the report (or zero if no report is to be sent * * \return Boolean true to force the sending of the report, false to let the library determine if it needs to be sent */ bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, uint8_t* const ReportID, const uint8_t ReportType, void* ReportData, uint16_t* ReportSize) { USB_KeyboardReport_Data_t* KeyboardReport = (USB_KeyboardReport_Data_t*)ReportData; uint8_t JoyStatus_LCL = Joystick_GetStatus(); uint8_t ButtonStatus_LCL = Buttons_GetStatus(); KeyboardReport->Modifier = HID_KEYBOARD_MODIFER_LEFTSHIFT; if (JoyStatus_LCL & JOY_UP) KeyboardReport->KeyCode[0] = 0x04; // A else if (JoyStatus_LCL & JOY_DOWN) KeyboardReport->KeyCode[0] = 0x05; // B if (JoyStatus_LCL & JOY_LEFT) KeyboardReport->KeyCode[0] = 0x06; // C else if (JoyStatus_LCL & JOY_RIGHT) KeyboardReport->KeyCode[0] = 0x07; // D if (JoyStatus_LCL & JOY_PRESS) KeyboardReport->KeyCode[0] = 0x08; // E if (ButtonStatus_LCL & BUTTONS_BUTTON1) KeyboardReport->KeyCode[0] = 0x09; // F *ReportSize = sizeof(USB_KeyboardReport_Data_t); return false; }
/** ISR to handle the reloading of the PWM timer with the next sample. */ ISR(TIMER0_COMPA_vect, ISR_BLOCK) { uint8_t PrevPipe = Pipe_GetCurrentPipe(); /* Check that the USB bus is ready for the next sample to write */ if (Audio_Host_IsReadyForNextSample(&Speaker_Audio_Interface)) { int16_t AudioSample; #if defined(USE_TEST_TONE) static uint8_t SquareWaveSampleCount; static int16_t CurrentWaveValue; /* In test tone mode, generate a square wave at 1/256 of the sample rate */ if (SquareWaveSampleCount++ == 0xFF) CurrentWaveValue ^= 0x8000; /* Only generate audio if the board button is being pressed */ AudioSample = (Buttons_GetStatus() & BUTTONS_BUTTON1) ? CurrentWaveValue : 0; #else /* Audio sample is ADC value scaled to fit the entire range */ AudioSample = ((SAMPLE_MAX_RANGE / ADC_MAX_RANGE) * ADC_GetResult()); #if defined(MICROPHONE_BIASED_TO_HALF_RAIL) /* Microphone is biased to half rail voltage, subtract the bias from the sample value */ AudioSample -= (SAMPLE_MAX_RANGE / 2); #endif #endif Audio_Host_WriteSample16(&Speaker_Audio_Interface, AudioSample); Audio_Host_WriteSample16(&Speaker_Audio_Interface, AudioSample); } Pipe_SelectPipe(PrevPipe); }
int main(void) { uint_reg_t Dummy; /* ============================= * Buttons Compile Check * ============================= */ // cppcheck-suppress redundantAssignment Dummy = BUTTONS_BUTTON1; Buttons_Init(); // cppcheck-suppress redundantAssignment Dummy = Buttons_GetStatus(); Buttons_Disable(); /* ============================= * Dataflash Compile Check * ============================= */ // cppcheck-suppress redundantAssignment Dummy = DATAFLASH_TOTALCHIPS + DATAFLASH_NO_CHIP + DATAFLASH_CHIP1 + DATAFLASH_PAGE_SIZE + DATAFLASH_PAGES; Dataflash_Init(); Dataflash_TransferByte(0); Dataflash_SendByte(0); // cppcheck-suppress redundantAssignment Dummy = Dataflash_ReceiveByte(); // cppcheck-suppress redundantAssignment Dummy = Dataflash_GetSelectedChip(); Dataflash_SelectChip(DATAFLASH_CHIP1); Dataflash_DeselectChip(); Dataflash_SelectChipFromPage(0); Dataflash_ToggleSelectedChipCS(); Dataflash_WaitWhileBusy(); Dataflash_SendAddressBytes(0, 0); /* ============================= * LEDs Compile Check * ============================= */ // cppcheck-suppress redundantAssignment Dummy = LEDS_LED1 + LEDS_LED2 + LEDS_LED3 + LEDS_LED4; LEDs_Init(); LEDs_TurnOnLEDs(LEDS_ALL_LEDS); LEDs_TurnOffLEDs(LEDS_ALL_LEDS); LEDs_SetAllLEDs(LEDS_ALL_LEDS); LEDs_ChangeLEDs(LEDS_ALL_LEDS, LEDS_NO_LEDS); LEDs_ToggleLEDs(LEDS_ALL_LEDS); // cppcheck-suppress redundantAssignment Dummy = LEDs_GetLEDs(); LEDs_Disable(); /* ============================= * Joystick Compile Check * ============================= */ // cppcheck-suppress redundantAssignment Dummy = JOY_LEFT + JOY_RIGHT + JOY_UP + JOY_DOWN + JOY_PRESS; Joystick_Init(); // cppcheck-suppress redundantAssignment Dummy = Joystick_GetStatus(); Joystick_Disable(); (void)Dummy; }
/* HID class driver callback function for the creation of HID reports to the host */ bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t *const HIDInterfaceInfo, uint8_t *const ReportID, const uint8_t ReportType, void *ReportData, uint16_t *const ReportSize) { uint8_t *Data = (uint8_t *) ReportData; uint8_t JoyStatus_LCL = Joystick_GetStatus(); uint8_t ButtonStatus_LCL = Buttons_GetStatus(); uint8_t ret = 0; if (JoyStatus_LCL & JOY_UP) { ret |= 0x01; } if (JoyStatus_LCL & JOY_LEFT) { ret |= 0x02; } if (JoyStatus_LCL & JOY_RIGHT) { ret |= 0x04; } if (JoyStatus_LCL & JOY_PRESS) { ret |= 0x08; } if (JoyStatus_LCL & JOY_DOWN) { ret |= 0x10; } if (ButtonStatus_LCL & BUTTONS_BUTTON1) { ret |= 0x20; } Data[0] = ret; *ReportSize = GENERIC_REPORT_SIZE; return false; }
/** Keyboard task. This generates the next keyboard HID report for the host, and transmits it via the * keyboard IN endpoint when the host is ready for more data. Additionally, it processes host LED status * reports sent to the device via the keyboard OUT reporting endpoint. */ void Keyboard_HID_Task(void) { uint8_t JoyStatus_LCL = Joystick_GetStatus(); /* Device must be connected and configured for the task to run */ if (USB_DeviceState != DEVICE_STATE_Configured) return; /* Check if board button is not pressed, if so mouse mode enabled */ if (!(Buttons_GetStatus() & BUTTONS_BUTTON1)) { /* Make sent key uppercase by indicating that the left shift key is pressed */ KeyboardReportData.Modifier = KEYBOARD_MODIFER_LEFTSHIFT; if (JoyStatus_LCL & JOY_UP) KeyboardReportData.KeyCode[0] = 0x04; // A else if (JoyStatus_LCL & JOY_DOWN) KeyboardReportData.KeyCode[0] = 0x05; // B if (JoyStatus_LCL & JOY_LEFT) KeyboardReportData.KeyCode[0] = 0x06; // C else if (JoyStatus_LCL & JOY_RIGHT) KeyboardReportData.KeyCode[0] = 0x07; // D if (JoyStatus_LCL & JOY_PRESS) KeyboardReportData.KeyCode[0] = 0x08; // E } /* Select the Keyboard Report Endpoint */ Endpoint_SelectEndpoint(KEYBOARD_IN_EPNUM); /* Check if Keyboard Endpoint Ready for Read/Write */ if (Endpoint_IsReadWriteAllowed()) { /* Write Keyboard Report Data */ Endpoint_Write_Stream_LE(&KeyboardReportData, sizeof(KeyboardReportData)); /* Finalize the stream transfer to send the last packet */ Endpoint_ClearIN(); /* Clear the report data afterwards */ memset(&KeyboardReportData, 0, sizeof(KeyboardReportData)); } /* Select the Keyboard LED Report Endpoint */ Endpoint_SelectEndpoint(KEYBOARD_OUT_EPNUM); /* Check if Keyboard LED Endpoint Ready for Read/Write */ if (Endpoint_IsReadWriteAllowed()) { /* Read in and process the LED report from the host */ Keyboard_ProcessLEDReport(Endpoint_Read_Byte()); /* Handshake the OUT Endpoint - clear endpoint and ready for next report */ Endpoint_ClearOUT(); } }
/** HID class driver callback function for the creation of HID reports to the host. * * \param[in] HIDInterfaceInfo Pointer to the HID class interface configuration structure being referenced * \param[in,out] ReportID Report ID requested by the host if non-zero, otherwise callback should set to the generated report ID * \param[out] ReportData Pointer to a buffer where the created report should be stored * \param[out] ReportSize Number of bytes written in the report (or zero if no report is to be sent * * \return Boolean true to force the sending of the report, false to let the library determine if it needs to be sent */ bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, uint8_t* const ReportID, void* ReportData, uint16_t* ReportSize) { uint8_t JoyStatus_LCL = Joystick_GetStatus(); uint8_t ButtonStatus_LCL = Buttons_GetStatus(); /* Determine which interface must have its report generated */ if (HIDInterfaceInfo == &Keyboard_HID_Interface) { USB_KeyboardReport_Data_t* KeyboardReport = (USB_KeyboardReport_Data_t*)ReportData; /* If first board button not being held down, no keyboard report */ if (!(ButtonStatus_LCL & BUTTONS_BUTTON1)) return 0; if (JoyStatus_LCL & JOY_UP) KeyboardReport->KeyCode[0] = 0x04; // A else if (JoyStatus_LCL & JOY_DOWN) KeyboardReport->KeyCode[0] = 0x05; // B if (JoyStatus_LCL & JOY_LEFT) KeyboardReport->KeyCode[0] = 0x06; // C else if (JoyStatus_LCL & JOY_RIGHT) KeyboardReport->KeyCode[0] = 0x07; // D if (JoyStatus_LCL & JOY_PRESS) KeyboardReport->KeyCode[0] = 0x08; // E *ReportSize = sizeof(USB_KeyboardReport_Data_t); return false; } else { USB_MouseReport_Data_t* MouseReport = (USB_MouseReport_Data_t*)ReportData; /* If first board button being held down, no mouse report */ if (ButtonStatus_LCL & BUTTONS_BUTTON1) return 0; if (JoyStatus_LCL & JOY_UP) MouseReport->Y = -1; else if (JoyStatus_LCL & JOY_DOWN) MouseReport->Y = 1; if (JoyStatus_LCL & JOY_LEFT) MouseReport->X = -1; else if (JoyStatus_LCL & JOY_RIGHT) MouseReport->X = 1; if (JoyStatus_LCL & JOY_PRESS) MouseReport->Button = (1 << 0); *ReportSize = sizeof(USB_MouseReport_Data_t); return true; } }
void taskPulsador(void * pvParameters) { uint8_t state = NO_OPRIMIDO; while(1) { switch(state) { case NO_OPRIMIDO: if(Buttons_GetStatus(SW4) == 1) { setTickCounter(0); state = ANTIRREBOTE; vTaskDelay(20/portTICK_RATE_MS); } else { vTaskDelay(100/portTICK_RATE_MS); } break; case ANTIRREBOTE: if(Buttons_GetStatus(SW4) == 1) { state = OPRIMIDO; } else { state = NO_OPRIMIDO; } break; case OPRIMIDO: if(Buttons_GetStatus(SW4) != 1) { tiempoOprimido = (getTickCounter() < 1000)?getTickCounter():999; state = NO_OPRIMIDO; } break; default: break; } } }
/** HID class driver callback function for the creation of HID reports to the host. * * \param[in] HIDInterfaceInfo Pointer to the HID class interface configuration structure being referenced * \param[in,out] ReportID Report ID requested by the host if non-zero, otherwise callback should set to the generated report ID * \param[in] ReportType Type of the report to create, either HID_REPORT_ITEM_In or HID_REPORT_ITEM_Feature * \param[out] ReportData Pointer to a buffer where the created report should be stored * \param[out] ReportSize Number of bytes written in the report (or zero if no report is to be sent) * * \return Boolean \c true to force the sending of the report, \c false to let the library determine if it needs to be sent */ bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, uint8_t* const ReportID, const uint8_t ReportType, void* ReportData, uint16_t* const ReportSize) { uint8_t JoyStatus_LCL = Joystick_GetStatus(); uint8_t ButtonStatus_LCL = Buttons_GetStatus(); if (!(ButtonStatus_LCL & BUTTONS_BUTTON1)) { USB_KeyboardReport_Data_t* KeyboardReport = (USB_KeyboardReport_Data_t*)ReportData; KeyboardReport->Modifier = HID_KEYBOARD_MODIFIER_LEFTSHIFT; if (JoyStatus_LCL & JOY_UP) KeyboardReport->KeyCode[0] = HID_KEYBOARD_SC_A; else if (JoyStatus_LCL & JOY_DOWN) KeyboardReport->KeyCode[0] = HID_KEYBOARD_SC_B; if (JoyStatus_LCL & JOY_LEFT) KeyboardReport->KeyCode[0] = HID_KEYBOARD_SC_C; else if (JoyStatus_LCL & JOY_RIGHT) KeyboardReport->KeyCode[0] = HID_KEYBOARD_SC_D; if (JoyStatus_LCL & JOY_PRESS) KeyboardReport->KeyCode[0] = HID_KEYBOARD_SC_E; *ReportID = HID_REPORTID_KeyboardReport; *ReportSize = sizeof(USB_KeyboardReport_Data_t); return false; } else { USB_MouseReport_Data_t* MouseReport = (USB_MouseReport_Data_t*)ReportData; if (JoyStatus_LCL & JOY_UP) MouseReport->Y = -1; else if (JoyStatus_LCL & JOY_DOWN) MouseReport->Y = 1; if (JoyStatus_LCL & JOY_LEFT) MouseReport->X = -1; else if (JoyStatus_LCL & JOY_RIGHT) MouseReport->X = 1; if (JoyStatus_LCL & JOY_PRESS) MouseReport->Button |= (1 << 0); *ReportID = HID_REPORTID_MouseReport; *ReportSize = sizeof(USB_MouseReport_Data_t); return true; } }
int main(void) { uint_reg_t Dummy; /* ============================= * Buttons Compile Check * ============================= */ Buttons_Init(); // cppcheck-suppress redundantAssignment Dummy = Buttons_GetStatus(); Buttons_Disable(); /* ============================= * Dataflash Compile Check * ============================= */ Dataflash_Init(); Dataflash_TransferByte(0); Dataflash_SendByte(0); // cppcheck-suppress redundantAssignment Dummy = Dataflash_ReceiveByte(); // cppcheck-suppress redundantAssignment Dummy = Dataflash_GetSelectedChip(); Dataflash_SelectChip(0); Dataflash_DeselectChip(); Dataflash_SelectChipFromPage(0); Dataflash_ToggleSelectedChipCS(); Dataflash_WaitWhileBusy(); Dataflash_SendAddressBytes(0, 0); /* ============================= * LEDs Compile Check * ============================= */ LEDs_Init(); LEDs_TurnOnLEDs(LEDS_ALL_LEDS); LEDs_TurnOffLEDs(LEDS_ALL_LEDS); LEDs_SetAllLEDs(LEDS_ALL_LEDS); LEDs_ChangeLEDs(LEDS_ALL_LEDS, LEDS_NO_LEDS); LEDs_ToggleLEDs(LEDS_ALL_LEDS); // cppcheck-suppress redundantAssignment Dummy = LEDs_GetLEDs(); LEDs_Disable(); /* ============================= * Joystick Compile Check * ============================= */ Joystick_Init(); // cppcheck-suppress redundantAssignment Dummy = Joystick_GetStatus(); Joystick_Disable(); (void)Dummy; }
/** Checks for the button state */ void service_button(void) { uint8_t ButtonStatus_LCL = Buttons_GetStatus(); if (ButtonStatus_LCL & BUTTONS_BUTTON1) { if (! button_is_pressed) { button_pressed_timestamp = millis10(); button_is_pressed = true; } } else { button_is_pressed = false; } }
/** Reads the joystick and button status, sending commands to the launcher as needed. */ void Read_Joystick_Status(void) { uint8_t JoyStatus_LCL = Joystick_GetStatus(); uint8_t Buttons_LCL = Buttons_GetStatus(); if (Buttons_LCL & BUTTONS_BUTTON1) Send_Command(CMD_FIRE); else if (JoyStatus_LCL & JOY_UP) Send_Command(CMD_UP); else if (JoyStatus_LCL & JOY_DOWN) Send_Command(CMD_DOWN); else if (JoyStatus_LCL & JOY_LEFT) Send_Command(CMD_LEFT); else if (JoyStatus_LCL & JOY_RIGHT) Send_Command(CMD_RIGHT); else if (CmdState != CMD_STOP) Send_Command(CMD_STOP); }
/** HID class driver callback function for the creation of HID reports to the host. * * \param[in] HIDInterfaceInfo Pointer to the HID class interface configuration structure being referenced * \param[in,out] ReportID Report ID requested by the host if non-zero, otherwise callback should set to the generated report ID * \param[in] ReportType Type of the report to create, either HID_REPORT_ITEM_In or HID_REPORT_ITEM_Feature * \param[out] ReportData Pointer to a buffer where the created report should be stored * \param[out] ReportSize Number of bytes written in the report (or zero if no report is to be sent) * * \return Boolean true to force the sending of the report, false to let the library determine if it needs to be sent */ bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, uint8_t* const ReportID, const uint8_t ReportType, void* ReportData, uint16_t* const ReportSize) { USB_MediaReport_Data_t* MediaReport = (USB_MediaReport_Data_t*)ReportData; uint8_t JoyStatus_LCL = Joystick_GetStatus(); uint8_t ButtonStatus_LCL = Buttons_GetStatus(); /* Update the Media Control report with the user button presses */ MediaReport->Mute = ((ButtonStatus_LCL & BUTTONS_BUTTON1) ? true : false); MediaReport->PlayPause = ((JoyStatus_LCL & JOY_PRESS) ? true : false); MediaReport->VolumeUp = ((JoyStatus_LCL & JOY_UP) ? true : false); MediaReport->VolumeDown = ((JoyStatus_LCL & JOY_DOWN) ? true : false); MediaReport->PreviousTrack = ((JoyStatus_LCL & JOY_LEFT) ? true : false); MediaReport->NextTrack = ((JoyStatus_LCL & JOY_RIGHT) ? true : false); *ReportSize = sizeof(USB_MediaReport_Data_t); return false; }
/** ISR to handle the reloading of the endpoint with the next sample. */ ISR(TIMER0_COMPA_vect, ISR_BLOCK) { uint8_t PrevPipe = Pipe_GetCurrentPipe(); Pipe_SelectPipe(AUDIO_DATA_OUT_PIPE); Pipe_Unfreeze(); /* Check if the current pipe can be written to (device ready for more data) */ if (Pipe_IsOUTReady()) { int16_t AudioSample; #if defined(USE_TEST_TONE) static uint8_t SquareWaveSampleCount; static int16_t CurrentWaveValue; /* In test tone mode, generate a square wave at 1/256 of the sample rate */ if (SquareWaveSampleCount++ == 0xFF) CurrentWaveValue ^= 0x8000; /* Only generate audio if the board button is being pressed */ AudioSample = (Buttons_GetStatus() & BUTTONS_BUTTON1) ? CurrentWaveValue : 0; #else /* Audio sample is ADC value scaled to fit the entire range */ AudioSample = ((SAMPLE_MAX_RANGE / ADC_MAX_RANGE) * ADC_GetResult()); #if defined(MICROPHONE_BIASED_TO_HALF_RAIL) /* Microphone is biased to half rail voltage, subtract the bias from the sample value */ AudioSample -= (SAMPLE_MAX_RANGE / 2); #endif #endif Pipe_Write_16_LE(AudioSample); Pipe_Write_16_LE(AudioSample); if (!(Pipe_IsReadWriteAllowed())) Pipe_ClearOUT(); } Pipe_Freeze(); Pipe_SelectPipe(PrevPipe); }
/** Mouse task. This generates the next mouse HID report for the host, and transmits it via the * mouse IN endpoint when the host is ready for more data. */ void Mouse_HID_Task(void) { uint8_t JoyStatus_LCL = Joystick_GetStatus(); /* Device must be connected and configured for the task to run */ if (USB_DeviceState != DEVICE_STATE_Configured) return; /* Check if board button is pressed, if so mouse mode enabled */ if (Buttons_GetStatus() & BUTTONS_BUTTON1) { if (JoyStatus_LCL & JOY_UP) MouseReportData.Y = 1; else if (JoyStatus_LCL & JOY_DOWN) MouseReportData.Y = -1; if (JoyStatus_LCL & JOY_RIGHT) MouseReportData.X = 1; else if (JoyStatus_LCL & JOY_LEFT) MouseReportData.X = -1; if (JoyStatus_LCL & JOY_PRESS) MouseReportData.Button = (1 << 0); } /* Select the Mouse Report Endpoint */ Endpoint_SelectEndpoint(MOUSE_IN_EPNUM); /* Check if Mouse Endpoint Ready for Read/Write */ if (Endpoint_IsReadWriteAllowed()) { /* Write Mouse Report Data */ Endpoint_Write_Stream_LE(&MouseReportData, sizeof(MouseReportData)); /* Finalize the stream transfer to send the last packet */ Endpoint_ClearIN(); /* Clear the report data afterwards */ memset(&MouseReportData, 0, sizeof(MouseReportData)); } }
static uint8_t Check_Buttons_Pressed(void) { static uint8_t buttons_status; static uint8_t ret; buttons_status = Buttons_GetStatus(); if((buttons_status & BUTTONS_BUTTON1) == BUTTONS_BUTTON1) button1_enable = true; // button pressed check timer enable else button1_enable = false; if(button1_pressed_flag) // button1 pressed (Specified time elapsed, enabled by sysTick_Handler function) { button1_pressed_flag = false; // pressed button clear ret = BUTTONS_BUTTON1; // return pressed button status } else { ret = 0; } return ret; }
/** Fills the given HID report data structure with the next HID report to send to the host. * * \param[out] ReportData Pointer to a HID report data structure to be filled * * \return Boolean true if the new report differs from the last report, false otherwise */ bool GetNextReport(USB_JoystickReport_Data_t* const ReportData) { static uint8_t PrevJoyStatus = 0; static uint8_t PrevButtonStatus = 0; uint8_t JoyStatus_LCL = Joystick_GetStatus(); uint8_t ButtonStatus_LCL = Buttons_GetStatus(); bool InputChanged = false; /* Clear the report contents */ memset(ReportData, 0, sizeof(USB_JoystickReport_Data_t)); if (JoyStatus_LCL & JOY_UP) ReportData->Y = -100; else if (JoyStatus_LCL & JOY_DOWN) ReportData->Y = 100; if (JoyStatus_LCL & JOY_LEFT) ReportData->X = -100; else if (JoyStatus_LCL & JOY_RIGHT) ReportData->X = 100; if (JoyStatus_LCL & JOY_PRESS) ReportData->Button |= (1 << 1); if (ButtonStatus_LCL & BUTTONS_BUTTON1) ReportData->Button |= (1 << 0); /* Check if the new report is different to the previous report */ InputChanged = (uint8_t)(PrevJoyStatus ^ JoyStatus_LCL) | (uint8_t)(PrevButtonStatus ^ ButtonStatus_LCL); /* Save the current joystick status for later comparison */ PrevJoyStatus = JoyStatus_LCL; PrevButtonStatus = ButtonStatus_LCL; /* Return whether the new report is different to the previous report or not */ return InputChanged; }
/** Checks for changes in the position of the board joystick, sending MIDI events to the host upon each change. */ void CheckJoystickMovement(void) { static uint8_t PrevJoystickStatus; uint8_t MIDICommand = 0; uint8_t MIDIPitch; /* Get current joystick mask, XOR with previous to detect joystick changes */ uint8_t JoystickStatus = Joystick_GetStatus(); uint8_t JoystickChanges = (JoystickStatus ^ PrevJoystickStatus); /* Get board button status - if pressed use second virtual cable, otherwise use the first */ uint8_t VirtualCable = (Buttons_GetStatus() & BUTTONS_BUTTON1) ? 1 : 0; if (JoystickChanges & JOY_LEFT) { MIDICommand = ((JoystickStatus & JOY_LEFT)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF); MIDIPitch = 0x3C; } if (JoystickChanges & JOY_UP) { MIDICommand = ((JoystickStatus & JOY_UP)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF); MIDIPitch = 0x3D; } if (JoystickChanges & JOY_RIGHT) { MIDICommand = ((JoystickStatus & JOY_RIGHT)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF); MIDIPitch = 0x3E; } if (JoystickChanges & JOY_DOWN) { MIDICommand = ((JoystickStatus & JOY_DOWN)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF); MIDIPitch = 0x3F; } if (JoystickChanges & JOY_PRESS) { MIDICommand = ((JoystickStatus & JOY_PRESS)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF); MIDIPitch = 0x3B; } if (MIDICommand) { MIDI_EventPacket_t MIDIEvent = (MIDI_EventPacket_t) { .Event = MIDI_EVENT(VirtualCable, MIDICommand), .Data1 = MIDICommand | MIDI_CHANNEL(1), .Data2 = MIDIPitch, .Data3 = MIDI_STANDARD_VELOCITY, }; MIDI_Device_SendEventPacket(&Keyboard_MIDI_Interface, &MIDIEvent); MIDI_Device_Flush(&Keyboard_MIDI_Interface); } PrevJoystickStatus = JoystickStatus; } /** Event handler for the library USB Connection event. */ void EVENT_USB_Device_Connect(void) { LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING); }
/** Checks for movement of the board's joystick, and sends corresponding MIDI note on/off * messages to the host. */ void CheckJoystickMovement(void) { static uint8_t PrevJoystickStatus; uint8_t MIDICommand = 0; uint8_t MIDIPitch; /* Get current joystick mask, XOR with previous to detect joystick changes */ uint8_t JoystickStatus = Joystick_GetStatus(); uint8_t JoystickChanges = (JoystickStatus ^ PrevJoystickStatus); /* Get board button status - if pressed use channel 10 (percussion), otherwise use channel 1 */ uint8_t Channel = ((Buttons_GetStatus() & BUTTONS_BUTTON1) ? MIDI_CHANNEL(10) : MIDI_CHANNEL(1)); if (JoystickChanges & JOY_LEFT) { MIDICommand = ((JoystickStatus & JOY_LEFT)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF); MIDIPitch = 0x3C; } else if (JoystickChanges & JOY_UP) { MIDICommand = ((JoystickStatus & JOY_UP)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF); MIDIPitch = 0x3D; } else if (JoystickChanges & JOY_RIGHT) { MIDICommand = ((JoystickStatus & JOY_RIGHT)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF); MIDIPitch = 0x3E; } else if (JoystickChanges & JOY_DOWN) { MIDICommand = ((JoystickStatus & JOY_DOWN)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF); MIDIPitch = 0x3F; } else if (JoystickChanges & JOY_PRESS) { MIDICommand = ((JoystickStatus & JOY_PRESS)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF); MIDIPitch = 0x3B; } if (MIDICommand) { MIDI_EventPacket_t MIDIEvent = (MIDI_EventPacket_t) { .Event = MIDI_EVENT(0, MIDICommand), .Data1 = MIDICommand | Channel, .Data2 = MIDIPitch, .Data3 = MIDI_STANDARD_VELOCITY, }; MIDI_Host_SendEventPacket(&Keyboard_MIDI_Interface, &MIDIEvent); MIDI_Host_Flush(&Keyboard_MIDI_Interface); } PrevJoystickStatus = JoystickStatus; } /** Event handler for the USB_DeviceAttached event. This indicates that a device has been attached to the host, and * starts the library USB task to begin the enumeration and USB management process. */ void EVENT_USB_Host_DeviceAttached(void) { puts_P(PSTR("Device Attached.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING); }
/** Task to handle the generation of MIDI note change events in response to presses of the board joystick, and send them * to the host. */ void MIDI_Task(void) { static uint8_t PrevJoystickStatus; /* Device must be connected and configured for the task to run */ if (USB_DeviceState != DEVICE_STATE_Configured) return; Endpoint_SelectEndpoint(MIDI_STREAM_IN_EPADDR); if (Endpoint_IsINReady()) { uint8_t MIDICommand = 0; uint8_t MIDIPitch; uint8_t JoystickStatus = Joystick_GetStatus(); uint8_t JoystickChanges = (JoystickStatus ^ PrevJoystickStatus); /* Get board button status - if pressed use channel 10 (percussion), otherwise use channel 1 */ uint8_t Channel = ((Buttons_GetStatus() & BUTTONS_BUTTON1) ? MIDI_CHANNEL(10) : MIDI_CHANNEL(1)); if (JoystickChanges & JOY_LEFT) { MIDICommand = ((JoystickStatus & JOY_LEFT)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF); MIDIPitch = 0x3C; } if (JoystickChanges & JOY_UP) { MIDICommand = ((JoystickStatus & JOY_UP)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF); MIDIPitch = 0x3D; } if (JoystickChanges & JOY_RIGHT) { MIDICommand = ((JoystickStatus & JOY_RIGHT)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF); MIDIPitch = 0x3E; } if (JoystickChanges & JOY_DOWN) { MIDICommand = ((JoystickStatus & JOY_DOWN)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF); MIDIPitch = 0x3F; } if (JoystickChanges & JOY_PRESS) { MIDICommand = ((JoystickStatus & JOY_PRESS)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF); MIDIPitch = 0x3B; } /* Check if a MIDI command is to be sent */ if (MIDICommand) { MIDI_EventPacket_t MIDIEvent = (MIDI_EventPacket_t) { .Event = MIDI_EVENT(0, MIDICommand), .Data1 = MIDICommand | Channel, .Data2 = MIDIPitch, .Data3 = MIDI_STANDARD_VELOCITY, }; /* Write the MIDI event packet to the endpoint */ Endpoint_Write_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL); /* Send the data in the endpoint to the host */ Endpoint_ClearIN(); } /* Save previous joystick value for next joystick change detection */ PrevJoystickStatus = JoystickStatus; } /* Select the MIDI OUT stream */ Endpoint_SelectEndpoint(MIDI_STREAM_OUT_EPADDR); /* Check if a MIDI command has been received */ if (Endpoint_IsOUTReceived()) { MIDI_EventPacket_t MIDIEvent; /* Read the MIDI event packet from the endpoint */ Endpoint_Read_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL); /* Check to see if the sent command is a note on message with a non-zero velocity */ if ((MIDIEvent.Event == MIDI_EVENT(0, MIDI_COMMAND_NOTE_ON)) && (MIDIEvent.Data3 > 0)) { /* Change LEDs depending on the pitch of the sent note */ LEDs_SetAllLEDs(MIDIEvent.Data2 > 64 ? LEDS_LED1 : LEDS_LED2); } else { /* Turn off all LEDs in response to non Note On messages */ LEDs_SetAllLEDs(LEDS_NO_LEDS); } /* If the endpoint is now empty, clear the bank */ if (!(Endpoint_BytesInEndpoint())) { /* Clear the endpoint ready for new packet */ Endpoint_ClearOUT(); } } }
/** Task to handle the generation of MIDI note change events in response to presses of the board joystick, and send them * to the host. */ void MIDI_Task(void) { static uint8_t PrevJoystickStatus; /* Device must be connected and configured for the task to run */ if (USB_DeviceState != DEVICE_STATE_Configured) return; Endpoint_SelectEndpoint(MIDI_STREAM_IN_EPNUM); if (Endpoint_IsINReady()) { uint8_t MIDICommand = 0; uint8_t MIDIPitch; uint8_t JoystickStatus = Joystick_GetStatus(); uint8_t JoystickChanges = (JoystickStatus ^ PrevJoystickStatus); /* Get board button status - if pressed use channel 10 (percussion), otherwise use channel 1 */ uint8_t Channel = ((Buttons_GetStatus() & BUTTONS_BUTTON1) ? MIDI_CHANNEL(10) : MIDI_CHANNEL(1)); if (JoystickChanges & JOY_LEFT) { MIDICommand = ((JoystickStatus & JOY_LEFT)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF); MIDIPitch = 0x3C; } if (JoystickChanges & JOY_UP) { MIDICommand = ((JoystickStatus & JOY_UP)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF); MIDIPitch = 0x3D; } if (JoystickChanges & JOY_RIGHT) { MIDICommand = ((JoystickStatus & JOY_RIGHT)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF); MIDIPitch = 0x3E; } if (JoystickChanges & JOY_DOWN) { MIDICommand = ((JoystickStatus & JOY_DOWN)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF); MIDIPitch = 0x3F; } if (JoystickChanges & JOY_PRESS) { MIDICommand = ((JoystickStatus & JOY_PRESS)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF); MIDIPitch = 0x3B; } /* Check if a MIDI command is to be sent */ if (MIDICommand) { USB_MIDI_EventPacket_t MIDIEvent = (USB_MIDI_EventPacket_t) { .CableNumber = 0, .Command = (MIDICommand >> 4), .Data1 = MIDICommand | Channel, .Data2 = MIDIPitch, .Data3 = MIDI_STANDARD_VELOCITY, }; /* Write the MIDI event packet to the endpoint */ Endpoint_Write_Stream_LE(&MIDIEvent, sizeof(MIDIEvent)); /* Send the data in the endpoint to the host */ Endpoint_ClearIN(); } /* Save previous joystick value for next joystick change detection */ PrevJoystickStatus = JoystickStatus; } /* Select the MIDI OUT stream */ Endpoint_SelectEndpoint(MIDI_STREAM_OUT_EPNUM); /* Check if endpoint is ready to be read from, if so discard its (unused) data */ if (Endpoint_IsOUTReceived()) Endpoint_ClearOUT(); }
/** HID class driver callback function for the creation of HID reports to the host. * * \param[in] HIDInterfaceInfo Pointer to the HID class interface configuration structure being referenced * \param[in,out] ReportID Report ID requested by the host if non-zero, otherwise callback should set to the generated report ID * \param[in] ReportType Type of the report to create, either HID_REPORT_ITEM_In or HID_REPORT_ITEM_Feature * \param[out] ReportData Pointer to a buffer where the created report should be stored * \param[out] ReportSize Number of bytes written in the report (or zero if no report is to be sent) * * \return Boolean true to force the sending of the report, false to let the library determine if it needs to be sent */ bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, uint8_t* const ReportID, const uint8_t ReportType, void* ReportData, uint16_t* const ReportSize) { uint8_t JoyStatus_LCL = Joystick_GetStatus(); uint8_t ButtonStatus_LCL = Buttons_GetStatus(); /* Determine which interface must have its report generated */ if (HIDInterfaceInfo == &Keyboard_HID_Interface) { USB_KeyboardReport_Data_t* KeyboardReport = (USB_KeyboardReport_Data_t*)ReportData; /* If first board button not being held down, no keyboard report */ if (!(ButtonStatus_LCL & BUTTONS_BUTTON1)) return 0; KeyboardReport->Modifier = HID_KEYBOARD_MODIFIER_LEFTSHIFT; if (JoyStatus_LCL & JOY_UP) KeyboardReport->KeyCode[0] = HID_KEYBOARD_SC_A; else if (JoyStatus_LCL & JOY_DOWN) KeyboardReport->KeyCode[0] = HID_KEYBOARD_SC_B; if (JoyStatus_LCL & JOY_LEFT) KeyboardReport->KeyCode[0] = HID_KEYBOARD_SC_C; else if (JoyStatus_LCL & JOY_RIGHT) KeyboardReport->KeyCode[0] = HID_KEYBOARD_SC_D; if (JoyStatus_LCL & JOY_PRESS) KeyboardReport->KeyCode[0] = HID_KEYBOARD_SC_E; *ReportSize = sizeof(USB_KeyboardReport_Data_t); return false; } else { USB_MouseReport_Data_t* MouseReport = (USB_MouseReport_Data_t*)ReportData; /* If first board button being held down, no mouse report */ if (ButtonStatus_LCL & BUTTONS_BUTTON1) return 0; if (JoyStatus_LCL & JOY_UP) MouseReport->Y = -1; else if (JoyStatus_LCL & JOY_DOWN) MouseReport->Y = 1; if (JoyStatus_LCL & JOY_LEFT) MouseReport->X = -1; else if (JoyStatus_LCL & JOY_RIGHT) MouseReport->X = 1; if (JoyStatus_LCL & JOY_PRESS) MouseReport->Button |= (1 << 0); *ReportSize = sizeof(USB_MouseReport_Data_t); return true; } }
/** Task to read in note on/off messages from the attached MIDI device and print it to the serial port. * When the board joystick or buttons are pressed, note on/off messages are sent to the attached device. */ void MIDIHost_Task(void) { if (USB_HostState != HOST_STATE_Configured) return; Pipe_SelectPipe(MIDI_DATA_IN_PIPE); Pipe_Unfreeze(); if (Pipe_IsINReceived()) { MIDI_EventPacket_t MIDIEvent; Pipe_Read_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL); if (!(Pipe_BytesInPipe())) Pipe_ClearIN(); bool NoteOnEvent = (MIDIEvent.Event == MIDI_EVENT(0, MIDI_COMMAND_NOTE_ON)); bool NoteOffEvent = (MIDIEvent.Event == MIDI_EVENT(0, MIDI_COMMAND_NOTE_OFF)); if (NoteOnEvent || NoteOffEvent) { printf_P(PSTR("MIDI Note %s - Channel %d, Pitch %d, Velocity %d\r\n"), NoteOnEvent ? "On" : "Off", ((MIDIEvent.Data1 & 0x0F) + 1), MIDIEvent.Data2, MIDIEvent.Data3); } } Pipe_Freeze(); Pipe_SelectPipe(MIDI_DATA_OUT_PIPE); Pipe_Unfreeze(); if (Pipe_IsOUTReady()) { uint8_t MIDICommand = 0; uint8_t MIDIPitch; static uint8_t PrevJoystickStatus; uint8_t JoystickStatus = Joystick_GetStatus(); uint8_t JoystickChanges = (JoystickStatus ^ PrevJoystickStatus); /* Get board button status - if pressed use channel 10 (percussion), otherwise use channel 1 */ uint8_t Channel = ((Buttons_GetStatus() & BUTTONS_BUTTON1) ? MIDI_CHANNEL(10) : MIDI_CHANNEL(1)); if (JoystickChanges & JOY_LEFT) { MIDICommand = ((JoystickStatus & JOY_LEFT)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF); MIDIPitch = 0x3C; } if (JoystickChanges & JOY_UP) { MIDICommand = ((JoystickStatus & JOY_UP)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF); MIDIPitch = 0x3D; } if (JoystickChanges & JOY_RIGHT) { MIDICommand = ((JoystickStatus & JOY_RIGHT)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF); MIDIPitch = 0x3E; } if (JoystickChanges & JOY_DOWN) { MIDICommand = ((JoystickStatus & JOY_DOWN)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF); MIDIPitch = 0x3F; } if (JoystickChanges & JOY_PRESS) { MIDICommand = ((JoystickStatus & JOY_PRESS)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF); MIDIPitch = 0x3B; } /* Check if a MIDI command is to be sent */ if (MIDICommand) { MIDI_EventPacket_t MIDIEvent = (MIDI_EventPacket_t) { .Event = MIDI_EVENT(0, MIDICommand), .Data1 = MIDICommand | Channel, .Data2 = MIDIPitch, .Data3 = MIDI_STANDARD_VELOCITY, }; /* Write the MIDI event packet to the pipe */ Pipe_Write_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL); /* Send the data in the pipe to the device */ Pipe_ClearOUT(); } Pipe_Freeze(); /* Save previous joystick value for next joystick change detection */ PrevJoystickStatus = JoystickStatus; } }