static void send_mouse(report_mouse_t *report);
static void send_system(uint16_t data);
static void send_consumer(uint16_t data);
-static host_driver_t lufa_driver = {
+host_driver_t lufa_driver = {
keyboard_leds,
send_keyboard,
send_mouse,
};
-static void SetupHardware(void);
-static void Console_HID_Task(void);
-
-int main(void)
+/*******************************************************************************
+ * Console
+ ******************************************************************************/
+#ifdef CONSOLE_ENABLE
+static void Console_Task(void)
{
- SetupHardware();
- sei();
+ /* Device must be connected and configured for the task to run */
+ if (USB_DeviceState != DEVICE_STATE_Configured)
+ return;
- print_enable = true;
- debug_enable = true;
- debug_matrix = true;
- debug_keyboard = true;
- debug_mouse = true;
+ uint8_t ep = Endpoint_GetCurrentEndpoint();
- // TODO: can't print here
- debug("LUFA init\n");
+#if 0
+ // TODO: impl receivechar()/recvchar()
+ Endpoint_SelectEndpoint(CONSOLE_OUT_EPNUM);
- keyboard_init();
- host_set_driver(&lufa_driver);
- while (1) {
- keyboard_proc();
+ /* Check to see if a packet has been sent from the host */
+ if (Endpoint_IsOUTReceived())
+ {
+ /* Check to see if the packet contains data */
+ if (Endpoint_IsReadWriteAllowed())
+ {
+ /* Create a temporary buffer to hold the read in report from the host */
+ uint8_t ConsoleData[CONSOLE_EPSIZE];
+
+ /* Read Console Report Data */
+ Endpoint_Read_Stream_LE(&ConsoleData, sizeof(ConsoleData), NULL);
+
+ /* Process Console Report Data */
+ //ProcessConsoleHIDReport(ConsoleData);
+ }
- Console_HID_Task();
- USB_USBTask();
+ /* Finalize the stream transfer to send the last packet */
+ Endpoint_ClearOUT();
}
-}
+#endif
-void SetupHardware(void)
-{
- /* Disable watchdog if enabled by bootloader/fuses */
- MCUSR &= ~(1 << WDRF);
- wdt_disable();
+ /* IN packet */
+ Endpoint_SelectEndpoint(CONSOLE_IN_EPNUM);
+ if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
+ Endpoint_SelectEndpoint(ep);
+ return;
+ }
- /* Disable clock division */
- clock_prescale_set(clock_div_1);
+ // fill empty bank
+ while (Endpoint_IsReadWriteAllowed())
+ Endpoint_Write_8(0);
- USB_Init();
-}
+ // flash senchar packet
+ if (Endpoint_IsINReady()) {
+ Endpoint_ClearIN();
+ }
-static void Console_HID_Task(void)
+ Endpoint_SelectEndpoint(ep);
+}
+#else
+static void Console_Task(void)
{
- /* Device must be connected and configured for the task to run */
- if (USB_DeviceState != DEVICE_STATE_Configured)
- return;
-
- // TODO: impl receivechar()/recvchar()
- Endpoint_SelectEndpoint(CONSOLE_OUT_EPNUM);
-
- /* Check to see if a packet has been sent from the host */
- if (Endpoint_IsOUTReceived())
- {
- /* Check to see if the packet contains data */
- if (Endpoint_IsReadWriteAllowed())
- {
- /* Create a temporary buffer to hold the read in report from the host */
- uint8_t ConsoleData[CONSOLE_EPSIZE];
-
- /* Read Console Report Data */
- Endpoint_Read_Stream_LE(&ConsoleData, sizeof(ConsoleData), NULL);
-
- /* Process Console Report Data */
- //ProcessConsoleHIDReport(ConsoleData);
- }
-
- /* Finalize the stream transfer to send the last packet */
- Endpoint_ClearOUT();
- }
-
- /* IN packet */
- Endpoint_SelectEndpoint(CONSOLE_IN_EPNUM);
- // send IN packet
- if (Endpoint_IsINReady())
- Endpoint_ClearIN();
}
+#endif
/*******************************************************************************
{
}
+void EVENT_USB_Device_StartOfFrame(void)
+{
+ Console_Task();
+}
+
/** Event handler for the USB_ConfigurationChanged event.
* This is fired when the host sets the current configuration of the USB device after enumeration.
*/
#ifdef EXTRAKEY_ENABLE
/* Setup Extra HID Report Endpoint */
- ConfigSuccess &= Endpoint_ConfigureEndpoint(EXTRA_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
- EXTRA_EPSIZE, ENDPOINT_BANK_SINGLE);
+ ConfigSuccess &= Endpoint_ConfigureEndpoint(EXTRAKEY_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
+ EXTRAKEY_EPSIZE, ENDPOINT_BANK_SINGLE);
#endif
+#ifdef CONSOLE_ENABLE
/* Setup Console HID Report Endpoints */
ConfigSuccess &= Endpoint_ConfigureEndpoint(CONSOLE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
- CONSOLE_EPSIZE, ENDPOINT_BANK_SINGLE);
+ CONSOLE_EPSIZE, ENDPOINT_BANK_DOUBLE);
ConfigSuccess &= Endpoint_ConfigureEndpoint(CONSOLE_OUT_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_OUT,
CONSOLE_EPSIZE, ENDPOINT_BANK_SINGLE);
+#endif
}
/*
static void send_keyboard(report_keyboard_t *report)
{
+ uint8_t timeout = 0;
+
// TODO: handle NKRO report
/* 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(report, sizeof(report_keyboard_t), NULL);
+ while (--timeout && !Endpoint_IsReadWriteAllowed()) ;
+
+ /* Write Keyboard Report Data */
+ Endpoint_Write_Stream_LE(report, sizeof(report_keyboard_t), NULL);
+
+ /* Finalize the stream transfer to send the last packet */
+ Endpoint_ClearIN();
- /* Finalize the stream transfer to send the last packet */
- Endpoint_ClearIN();
- }
keyboard_report_sent = *report;
}
static void send_mouse(report_mouse_t *report)
{
#ifdef MOUSE_ENABLE
+ uint8_t timeout = 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(report, sizeof(report_mouse_t), NULL);
+ while (--timeout && !Endpoint_IsReadWriteAllowed()) ;
- /* Finalize the stream transfer to send the last packet */
- Endpoint_ClearIN();
- }
+ /* Write Mouse Report Data */
+ Endpoint_Write_Stream_LE(report, sizeof(report_mouse_t), NULL);
+
+ /* Finalize the stream transfer to send the last packet */
+ Endpoint_ClearIN();
#endif
}
static void send_system(uint16_t data)
{
+ uint8_t timeout = 0;
+
report_extra_t r = {
.report_id = REPORT_ID_SYSTEM,
.usage = data
};
- Endpoint_SelectEndpoint(EXTRA_IN_EPNUM);
- if (Endpoint_IsReadWriteAllowed()) {
- Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL);
- Endpoint_ClearIN();
- }
+ Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM);
+ while (--timeout && !Endpoint_IsReadWriteAllowed()) ;
+ Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL);
+ Endpoint_ClearIN();
}
static void send_consumer(uint16_t data)
{
+ uint8_t timeout = 0;
+
report_extra_t r = {
.report_id = REPORT_ID_CONSUMER,
.usage = data
};
- Endpoint_SelectEndpoint(EXTRA_IN_EPNUM);
- if (Endpoint_IsReadWriteAllowed()) {
- Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL);
- Endpoint_ClearIN();
- }
+ Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM);
+ while (--timeout && !Endpoint_IsReadWriteAllowed()) ;
+ Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL);
+ Endpoint_ClearIN();
}
/*******************************************************************************
* sendchar
******************************************************************************/
+#ifdef CONSOLE_ENABLE
+#define SEND_TIMEOUT 5
int8_t sendchar(uint8_t c)
{
+ // Not wait once timeouted.
+ // Because sendchar() is called so many times, waiting each call causes big lag.
+ static bool timeouted = false;
+
if (USB_DeviceState != DEVICE_STATE_Configured)
- return -1;
+ return -1;
+ uint8_t ep = Endpoint_GetCurrentEndpoint();
Endpoint_SelectEndpoint(CONSOLE_IN_EPNUM);
+ if (!Endpoint_IsEnabled() || !Endpoint_IsConfigured()) {
+ Endpoint_SelectEndpoint(ep);
+ return -1;
+ }
- uint8_t timeout = 10;
+ if (timeouted && !Endpoint_IsReadWriteAllowed()) {
+ Endpoint_SelectEndpoint(ep);
+ return - 1;
+ }
+
+ timeouted = false;
+
+ uint8_t timeout = SEND_TIMEOUT;
uint16_t prevFN = USB_Device_GetFrameNumber();
- while (!Endpoint_IsINReady()) {
+ while (!Endpoint_IsReadWriteAllowed()) {
switch (USB_DeviceState) {
case DEVICE_STATE_Unattached:
case DEVICE_STATE_Suspended:
return -1;
}
- if (Endpoint_IsStalled())
+ if (Endpoint_IsStalled()) {
+ Endpoint_SelectEndpoint(ep);
return -1;
+ }
if (prevFN != USB_Device_GetFrameNumber()) {
- if (!(timeout--))
+ if (!(timeout--)) {
+ timeouted = true;
+ Endpoint_SelectEndpoint(ep);
return -1;
+ }
prevFN = USB_Device_GetFrameNumber();
}
}
Endpoint_Write_8(c);
- // send when packet is full
+ // send when bank is full
if (!Endpoint_IsReadWriteAllowed())
Endpoint_ClearIN();
+ Endpoint_SelectEndpoint(ep);
+ return 0;
+}
+#else
+int8_t sendchar(uint8_t c)
+{
return 0;
}
+#endif
+
+
+/*******************************************************************************
+ * main
+ ******************************************************************************/
+static void SetupHardware(void)
+{
+ /* Disable watchdog if enabled by bootloader/fuses */
+ MCUSR &= ~(1 << WDRF);
+ wdt_disable();
+
+ /* Disable clock division */
+ clock_prescale_set(clock_div_1);
+
+ // Leonardo needs. Without this USB device is not recognized.
+ USB_Disable();
+
+ USB_Init();
+
+ // for Console_Task
+ USB_Device_EnableSOFEvents();
+}
+
+int main(void) __attribute__ ((weak));
+int main(void)
+{
+ SetupHardware();
+ sei();
+
+ print_enable = true;
+ debug_enable = true;
+ debug_matrix = true;
+ debug_keyboard = true;
+ debug_mouse = true;
+
+ // TODO: can't print here
+ debug("LUFA init\n");
+
+ keyboard_init();
+ host_set_driver(&lufa_driver);
+ while (1) {
+ keyboard_task();
+
+#if !defined(INTERRUPT_CONTROL_ENDPOINT)
+ USB_USBTask();
+#endif
+ }
+}