Merge branch 'usb_usb_init_fix'
This commit is contained in:
commit
8a8a4cf677
14 changed files with 191 additions and 48 deletions
6
.gitmodules
vendored
6
.gitmodules
vendored
|
|
@ -1,3 +1,3 @@
|
||||||
[submodule "tmk_core/protocol/usb_hid/USB_Host_Shield_2.0-git"]
|
[submodule "tmk_core/protocol/usb_hid/USB_Host_Shield_2.0-tmk"]
|
||||||
path = tmk_core/protocol/usb_hid/USB_Host_Shield_2.0-git
|
path = tmk_core/protocol/usb_hid/USB_Host_Shield_2.0-tmk
|
||||||
url = https://github.com/felis/USB_Host_Shield_2.0.git
|
url = https://github.com/tmk/USB_Host_Shield_2.0.git
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,20 @@
|
||||||
TARGET = usb_usb_debug
|
TARGET = usb_usb_debug
|
||||||
UNIMAP_ENABLE = yes
|
|
||||||
|
#UNIMAP_ENABLE = yes
|
||||||
#KEYMAP_SECTION_ENABLE = yes
|
#KEYMAP_SECTION_ENABLE = yes
|
||||||
#LUFA_DEBUG = yes
|
|
||||||
OPT_DEFS += -DDEBUG_USB_HOST
|
# LUFA debug print
|
||||||
|
# This may prevent USB enumeration and keyboard init
|
||||||
|
LUFA_DEBUG = yes
|
||||||
|
# Select one of outputs for debug print
|
||||||
|
LUFA_DEBUG_UART = yes
|
||||||
|
#LUFA_DEBUG_SUART = yes
|
||||||
|
|
||||||
|
# USB_Host_Shield_2.0 debug print
|
||||||
|
# This may prevent USB enumeration and keyboard init
|
||||||
|
#OPT_DEFS += -DDEBUG_USB_HOST
|
||||||
|
|
||||||
|
CONSOLE_ENABLE = yes
|
||||||
|
MOUSEKEY_ENABLE = no
|
||||||
|
EXTRAKEY_ENABLE = no
|
||||||
include Makefile
|
include Makefile
|
||||||
|
|
|
||||||
|
|
@ -36,4 +36,17 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
/* key combination for command */
|
/* key combination for command */
|
||||||
#define IS_COMMAND() (keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)))
|
#define IS_COMMAND() (keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)))
|
||||||
|
|
||||||
|
|
||||||
|
// Disable power saving in USB suspend loop but remote wakeup is still valid.
|
||||||
|
// This allows keep USB::Task() going during suspend without power down time delay.
|
||||||
|
//#define NO_SUSPEND_POWER_DOWN
|
||||||
|
|
||||||
|
|
||||||
|
// Disable USB startup wait, which can delays starting UHS2 Task() for 350-600ms.
|
||||||
|
//#define NO_USB_STARTUP_WAIT_LOOP
|
||||||
|
|
||||||
|
// Disable USB suspend loop, which blocks UHS2 Task() while power saving.
|
||||||
|
// Note that this also disables power saving and remote wakeup from keyboard completely.
|
||||||
|
//#define NO_USB_SUSPEND_LOOP
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#include "host.h"
|
#include "host.h"
|
||||||
#include "keyboard.h"
|
#include "keyboard.h"
|
||||||
|
|
||||||
|
#include "hook.h"
|
||||||
|
#include "suspend.h"
|
||||||
|
#include "lufa.h"
|
||||||
|
|
||||||
|
|
||||||
/* KEY CODE to Matrix
|
/* KEY CODE to Matrix
|
||||||
*
|
*
|
||||||
|
|
@ -71,8 +75,6 @@ static bool matrix_is_mod =false;
|
||||||
* This supports two cascaded hubs and four keyboards
|
* This supports two cascaded hubs and four keyboards
|
||||||
*/
|
*/
|
||||||
USB usb_host;
|
USB usb_host;
|
||||||
USBHub hub1(&usb_host);
|
|
||||||
USBHub hub2(&usb_host);
|
|
||||||
HIDBoot<USB_HID_PROTOCOL_KEYBOARD> kbd1(&usb_host);
|
HIDBoot<USB_HID_PROTOCOL_KEYBOARD> kbd1(&usb_host);
|
||||||
HIDBoot<USB_HID_PROTOCOL_KEYBOARD> kbd2(&usb_host);
|
HIDBoot<USB_HID_PROTOCOL_KEYBOARD> kbd2(&usb_host);
|
||||||
HIDBoot<USB_HID_PROTOCOL_KEYBOARD> kbd3(&usb_host);
|
HIDBoot<USB_HID_PROTOCOL_KEYBOARD> kbd3(&usb_host);
|
||||||
|
|
@ -81,6 +83,8 @@ KBDReportParser kbd_parser1;
|
||||||
KBDReportParser kbd_parser2;
|
KBDReportParser kbd_parser2;
|
||||||
KBDReportParser kbd_parser3;
|
KBDReportParser kbd_parser3;
|
||||||
KBDReportParser kbd_parser4;
|
KBDReportParser kbd_parser4;
|
||||||
|
USBHub hub1(&usb_host);
|
||||||
|
USBHub hub2(&usb_host);
|
||||||
|
|
||||||
|
|
||||||
uint8_t matrix_rows(void) { return MATRIX_ROWS; }
|
uint8_t matrix_rows(void) { return MATRIX_ROWS; }
|
||||||
|
|
@ -233,3 +237,28 @@ void led_set(uint8_t usb_led)
|
||||||
if (kbd3.isReady()) kbd3.SetReport(0, 0, 2, 0, 1, &usb_led);
|
if (kbd3.isReady()) kbd3.SetReport(0, 0, 2, 0, 1, &usb_led);
|
||||||
if (kbd4.isReady()) kbd4.SetReport(0, 0, 2, 0, 1, &usb_led);
|
if (kbd4.isReady()) kbd4.SetReport(0, 0, 2, 0, 1, &usb_led);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We need to keep doing UHS2 USB::Task() to initialize keyboard
|
||||||
|
// even before USB is not configured.
|
||||||
|
void hook_usb_startup_wait_loop(void)
|
||||||
|
{
|
||||||
|
matrix_scan();
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need to keep doing UHS2 USB::Task() to initialize keyboard
|
||||||
|
// even during USB bus is suspended and remote wakeup is not enabled yet on LUFA side.
|
||||||
|
// This situation can happen just after pluging converter into USB port.
|
||||||
|
void hook_usb_suspend_loop(void)
|
||||||
|
{
|
||||||
|
#ifndef LUFA_DEBUG_UART
|
||||||
|
// This corrupts debug print when suspend
|
||||||
|
suspend_power_down();
|
||||||
|
#endif
|
||||||
|
if (USB_Device_RemoteWakeupEnabled) {
|
||||||
|
if (suspend_wakeup_condition()) {
|
||||||
|
USB_Device_SendRemoteWakeup();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
matrix_scan();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,8 +50,12 @@ endif
|
||||||
ifeq (yes,$(strip $(CONSOLE_ENABLE)))
|
ifeq (yes,$(strip $(CONSOLE_ENABLE)))
|
||||||
OPT_DEFS += -DCONSOLE_ENABLE
|
OPT_DEFS += -DCONSOLE_ENABLE
|
||||||
else
|
else
|
||||||
OPT_DEFS += -DNO_PRINT
|
# Remove print functions when console is disabled and
|
||||||
OPT_DEFS += -DNO_DEBUG
|
# no other print method like UART is available
|
||||||
|
ifneq (yes, $(strip $(DEBUG_PRINT_AVAILABLE)))
|
||||||
|
OPT_DEFS += -DNO_PRINT
|
||||||
|
OPT_DEFS += -DNO_DEBUG
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq (yes,$(strip $(COMMAND_ENABLE)))
|
ifeq (yes,$(strip $(COMMAND_ENABLE)))
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
// TODO: Teensy support(ATMega32u4/AT90USB128)
|
|
||||||
// Fixed for Arduino Duemilanove ATmega168p by Jun Wako
|
// Fixed for Arduino Duemilanove ATmega168p by Jun Wako
|
||||||
/* UART Example for Teensy USB Development Board
|
/* UART Example for Teensy USB Development Board
|
||||||
* http://www.pjrc.com/teensy/
|
* http://www.pjrc.com/teensy/
|
||||||
|
|
@ -32,9 +31,42 @@
|
||||||
|
|
||||||
#include "uart.h"
|
#include "uart.h"
|
||||||
|
|
||||||
|
#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega328P__)
|
||||||
|
# define UDRn UDR0
|
||||||
|
# define UBRRn UBRR0
|
||||||
|
# define UCSRnA UCSR0A
|
||||||
|
# define UCSRnB UCSR0B
|
||||||
|
# define UCSRnC UCSR0C
|
||||||
|
# define U2Xn U2X0
|
||||||
|
# define RXENn RXEN0
|
||||||
|
# define TXENn TXEN0
|
||||||
|
# define RXCIEn RXCIE0
|
||||||
|
# define UCSZn1 UCSZ01
|
||||||
|
# define UCSZn0 UCSZ00
|
||||||
|
# define UDRIEn UDRIE0
|
||||||
|
# define UDRE_vect USART_UDRE_vect
|
||||||
|
# define RX_vect USART_RX_vect
|
||||||
|
#elif defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega32U2__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__)
|
||||||
|
# define UDRn UDR1
|
||||||
|
# define UBRRn UBRR1
|
||||||
|
# define UCSRnA UCSR1A
|
||||||
|
# define UCSRnB UCSR1B
|
||||||
|
# define UCSRnC UCSR1C
|
||||||
|
# define U2Xn U2X1
|
||||||
|
# define RXENn RXEN1
|
||||||
|
# define TXENn TXEN1
|
||||||
|
# define RXCIEn RXCIE1
|
||||||
|
# define UCSZn1 UCSZ11
|
||||||
|
# define UCSZn0 UCSZ10
|
||||||
|
# define UDRIEn UDRIE1
|
||||||
|
# define UDRE_vect USART1_UDRE_vect
|
||||||
|
# define RX_vect USART1_RX_vect
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// These buffers may be any size from 2 to 256 bytes.
|
// These buffers may be any size from 2 to 256 bytes.
|
||||||
#define RX_BUFFER_SIZE 64
|
#define RX_BUFFER_SIZE 64
|
||||||
#define TX_BUFFER_SIZE 40
|
#define TX_BUFFER_SIZE 256
|
||||||
|
|
||||||
static volatile uint8_t tx_buffer[TX_BUFFER_SIZE];
|
static volatile uint8_t tx_buffer[TX_BUFFER_SIZE];
|
||||||
static volatile uint8_t tx_buffer_head;
|
static volatile uint8_t tx_buffer_head;
|
||||||
|
|
@ -47,10 +79,10 @@ static volatile uint8_t rx_buffer_tail;
|
||||||
void uart_init(uint32_t baud)
|
void uart_init(uint32_t baud)
|
||||||
{
|
{
|
||||||
cli();
|
cli();
|
||||||
UBRR0 = (F_CPU / 4 / baud - 1) / 2;
|
UBRRn = (F_CPU / 4 / baud - 1) / 2;
|
||||||
UCSR0A = (1<<U2X0);
|
UCSRnA = (1<<U2Xn);
|
||||||
UCSR0B = (1<<RXEN0) | (1<<TXEN0) | (1<<RXCIE0);
|
UCSRnB = (1<<RXENn) | (1<<TXENn) | (1<<RXCIEn);
|
||||||
UCSR0C = (1<<UCSZ01) | (1<<UCSZ00);
|
UCSRnC = (1<<UCSZn1) | (1<<UCSZn0);
|
||||||
tx_buffer_head = tx_buffer_tail = 0;
|
tx_buffer_head = tx_buffer_tail = 0;
|
||||||
rx_buffer_head = rx_buffer_tail = 0;
|
rx_buffer_head = rx_buffer_tail = 0;
|
||||||
sei();
|
sei();
|
||||||
|
|
@ -63,11 +95,13 @@ void uart_putchar(uint8_t c)
|
||||||
|
|
||||||
i = tx_buffer_head + 1;
|
i = tx_buffer_head + 1;
|
||||||
if (i >= TX_BUFFER_SIZE) i = 0;
|
if (i >= TX_BUFFER_SIZE) i = 0;
|
||||||
|
// return immediately to avoid deadlock when interrupt is disabled(called from ISR)
|
||||||
|
if (tx_buffer_tail == i && (SREG & (1<<SREG_I)) == 0) return;
|
||||||
while (tx_buffer_tail == i) ; // wait until space in buffer
|
while (tx_buffer_tail == i) ; // wait until space in buffer
|
||||||
//cli();
|
//cli();
|
||||||
tx_buffer[i] = c;
|
tx_buffer[i] = c;
|
||||||
tx_buffer_head = i;
|
tx_buffer_head = i;
|
||||||
UCSR0B = (1<<RXEN0) | (1<<TXEN0) | (1<<RXCIE0) | (1<<UDRIE0);
|
UCSRnB = (1<<RXENn) | (1<<TXENn) | (1<<RXCIEn) | (1<<UDRIEn);
|
||||||
//sei();
|
//sei();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -98,27 +132,27 @@ uint8_t uart_available(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transmit Interrupt
|
// Transmit Interrupt
|
||||||
ISR(USART_UDRE_vect)
|
ISR(UDRE_vect)
|
||||||
{
|
{
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
|
|
||||||
if (tx_buffer_head == tx_buffer_tail) {
|
if (tx_buffer_head == tx_buffer_tail) {
|
||||||
// buffer is empty, disable transmit interrupt
|
// buffer is empty, disable transmit interrupt
|
||||||
UCSR0B = (1<<RXEN0) | (1<<TXEN0) | (1<<RXCIE0);
|
UCSRnB = (1<<RXENn) | (1<<TXENn) | (1<<RXCIEn);
|
||||||
} else {
|
} else {
|
||||||
i = tx_buffer_tail + 1;
|
i = tx_buffer_tail + 1;
|
||||||
if (i >= TX_BUFFER_SIZE) i = 0;
|
if (i >= TX_BUFFER_SIZE) i = 0;
|
||||||
UDR0 = tx_buffer[i];
|
UDRn = tx_buffer[i];
|
||||||
tx_buffer_tail = i;
|
tx_buffer_tail = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Receive Interrupt
|
// Receive Interrupt
|
||||||
ISR(USART_RX_vect)
|
ISR(RX_vect)
|
||||||
{
|
{
|
||||||
uint8_t c, i;
|
uint8_t c, i;
|
||||||
|
|
||||||
c = UDR0;
|
c = UDRn;
|
||||||
i = rx_buffer_head + 1;
|
i = rx_buffer_head + 1;
|
||||||
if (i >= RX_BUFFER_SIZE) i = 0;
|
if (i >= RX_BUFFER_SIZE) i = 0;
|
||||||
if (i != rx_buffer_tail) {
|
if (i != rx_buffer_tail) {
|
||||||
|
|
@ -21,6 +21,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#include "keyboard.h"
|
#include "keyboard.h"
|
||||||
#include "led.h"
|
#include "led.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
/* -------------------------------------
|
/* -------------------------------------
|
||||||
* Protocol hooks
|
* Protocol hooks
|
||||||
* ------------------------------------- */
|
* ------------------------------------- */
|
||||||
|
|
@ -47,6 +51,10 @@ void hook_usb_suspend_loop(void);
|
||||||
* the "normal" indicator LED status by default. */
|
* the "normal" indicator LED status by default. */
|
||||||
void hook_usb_wakeup(void);
|
void hook_usb_wakeup(void);
|
||||||
|
|
||||||
|
/* Called repeatedly until getting to CONFIGURED state */
|
||||||
|
/* Default behaviour: do nothing. */
|
||||||
|
void hook_usb_startup_wait_loop(void);
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------------------
|
/* -------------------------------------
|
||||||
* Keyboard hooks
|
* Keyboard hooks
|
||||||
|
|
@ -76,5 +84,8 @@ void hook_keyboard_leds_change(uint8_t led_status);
|
||||||
/* Default behaviour: do nothing. */
|
/* Default behaviour: do nothing. */
|
||||||
void hook_bootmagic(void);
|
void hook_bootmagic(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* _HOOKS_H_ */
|
#endif /* _HOOKS_H_ */
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,17 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
void suspend_idle(uint8_t timeout);
|
void suspend_idle(uint8_t timeout);
|
||||||
void suspend_power_down(void);
|
void suspend_power_down(void);
|
||||||
bool suspend_wakeup_condition(void);
|
bool suspend_wakeup_condition(void);
|
||||||
void suspend_wakeup_init(void);
|
void suspend_wakeup_init(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,8 @@ Hook function | Timing
|
||||||
`hook_early_init(void)` | Early in the boot process, before the matrix is initialized and before a connection is made with the host. Thus, this hook has access to very few parameters, but it is a good place to define any custom parameters needed by other early processes.
|
`hook_early_init(void)` | Early in the boot process, before the matrix is initialized and before a connection is made with the host. Thus, this hook has access to very few parameters, but it is a good place to define any custom parameters needed by other early processes.
|
||||||
`hook_late_init(void)` | Near the end of the boot process, after Boot Magic has run and LEDs have been initialized.
|
`hook_late_init(void)` | Near the end of the boot process, after Boot Magic has run and LEDs have been initialized.
|
||||||
`hook_bootmagic(void)` | During the Boot Magic window, after EEPROM and Bootloader checks are made, but before any other built-in Boot Magic checks are made.
|
`hook_bootmagic(void)` | During the Boot Magic window, after EEPROM and Bootloader checks are made, but before any other built-in Boot Magic checks are made.
|
||||||
|
`hook_usb_startup_wait_loop(void)` | Continuously, until the device gets ready and into USB configured state.
|
||||||
|
|
||||||
`hook_usb_wakeup(void)` | When the device wakes up from USB suspend state.
|
`hook_usb_wakeup(void)` | When the device wakes up from USB suspend state.
|
||||||
`hook_usb_suspend_entry(void)` | When the device enters USB suspend state.
|
`hook_usb_suspend_entry(void)` | When the device enters USB suspend state.
|
||||||
`hook_usb_suspend_loop(void)` | Continuously, while the device is in USB suspend state. *Default action:* power down and periodically check the matrix, causing wakeup if needed.
|
`hook_usb_suspend_loop(void)` | Continuously, while the device is in USB suspend state. *Default action:* power down and periodically check the matrix, causing wakeup if needed.
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,20 @@ OPT_DEFS += $(LUFA_OPTS)
|
||||||
# This indicates using LUFA stack
|
# This indicates using LUFA stack
|
||||||
OPT_DEFS += -DPROTOCOL_LUFA
|
OPT_DEFS += -DPROTOCOL_LUFA
|
||||||
|
|
||||||
|
ifeq (yes,$(strip $(LUFA_DEBUG)))
|
||||||
|
LUFA_OPTS += -DLUFA_DEBUG
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq (yes,$(strip $(LUFA_DEBUG_SUART)))
|
ifeq (yes,$(strip $(LUFA_DEBUG_SUART)))
|
||||||
SRC += common/avr/suart.S
|
SRC += common/avr/suart.S
|
||||||
LUFA_OPTS += -DLUFA_DEBUG_SUART
|
LUFA_OPTS += -DLUFA_DEBUG_SUART
|
||||||
|
# Keep print/debug lines when disabling HID console. See common.mk.
|
||||||
|
DEBUG_PRINT_AVAILABLE = yes
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq (yes,$(strip $(LUFA_DEBUG_UART)))
|
||||||
|
SRC += common/avr/uart.c
|
||||||
|
LUFA_OPTS += -DLUFA_DEBUG_UART
|
||||||
|
# Keep print/debug lines when disabling HID console. See common.mk.
|
||||||
|
DEBUG_PRINT_AVAILABLE = yes
|
||||||
endif
|
endif
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,10 @@
|
||||||
#include "avr/suart.h"
|
#include "avr/suart.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef LUFA_DEBUG_UART
|
||||||
|
#include "uart.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "matrix.h"
|
#include "matrix.h"
|
||||||
#include "descriptor.h"
|
#include "descriptor.h"
|
||||||
#include "lufa.h"
|
#include "lufa.h"
|
||||||
|
|
@ -218,7 +222,9 @@ static void console_task(void)
|
||||||
*/
|
*/
|
||||||
void EVENT_USB_Device_Connect(void)
|
void EVENT_USB_Device_Connect(void)
|
||||||
{
|
{
|
||||||
|
#ifdef LUFA_DEBUG
|
||||||
print("[C]");
|
print("[C]");
|
||||||
|
#endif
|
||||||
/* For battery powered device */
|
/* For battery powered device */
|
||||||
if (!USB_IsInitialized) {
|
if (!USB_IsInitialized) {
|
||||||
USB_Disable();
|
USB_Disable();
|
||||||
|
|
@ -229,7 +235,9 @@ void EVENT_USB_Device_Connect(void)
|
||||||
|
|
||||||
void EVENT_USB_Device_Disconnect(void)
|
void EVENT_USB_Device_Disconnect(void)
|
||||||
{
|
{
|
||||||
|
#ifdef LUFA_DEBUG
|
||||||
print("[D]");
|
print("[D]");
|
||||||
|
#endif
|
||||||
/* For battery powered device */
|
/* For battery powered device */
|
||||||
USB_IsInitialized = false;
|
USB_IsInitialized = false;
|
||||||
/* TODO: This doesn't work. After several plug in/outs can not be enumerated.
|
/* TODO: This doesn't work. After several plug in/outs can not be enumerated.
|
||||||
|
|
@ -575,25 +583,22 @@ static void send_consumer(uint16_t data)
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* sendchar
|
* sendchar
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
#ifdef CONSOLE_ENABLE
|
|
||||||
int8_t sendchar(uint8_t c)
|
int8_t sendchar(uint8_t c)
|
||||||
{
|
{
|
||||||
#ifdef LUFA_DEBUG_SUART
|
#ifdef LUFA_DEBUG_SUART
|
||||||
xmit(c);
|
xmit(c);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool r = console_putc(c);
|
#ifdef LUFA_DEBUG_UART
|
||||||
return (r ? 0 : -1);
|
uart_putchar(c);
|
||||||
}
|
|
||||||
#else
|
|
||||||
int8_t sendchar(uint8_t c)
|
|
||||||
{
|
|
||||||
#ifdef LUFA_DEBUG_SUART
|
|
||||||
xmit(c);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONSOLE_ENABLE
|
||||||
|
console_putc(c);
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
@ -629,11 +634,15 @@ int main(void)
|
||||||
SUART_OUT_PORT |= (1<<SUART_OUT_BIT);
|
SUART_OUT_PORT |= (1<<SUART_OUT_BIT);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef LUFA_DEBUG_UART
|
||||||
|
uart_init(115200);
|
||||||
|
#endif
|
||||||
|
|
||||||
// setup sendchar: DO NOT USE print functions before this line
|
// setup sendchar: DO NOT USE print functions before this line
|
||||||
print_set_sendchar(sendchar);
|
print_set_sendchar(sendchar);
|
||||||
host_set_driver(&lufa_driver);
|
host_set_driver(&lufa_driver);
|
||||||
|
|
||||||
print("Keyboard init.\n");
|
print("\n\nKeyboard init.\n");
|
||||||
hook_early_init();
|
hook_early_init();
|
||||||
keyboard_setup();
|
keyboard_setup();
|
||||||
setup_usb();
|
setup_usb();
|
||||||
|
|
@ -645,6 +654,7 @@ int main(void)
|
||||||
|
|
||||||
keyboard_init();
|
keyboard_init();
|
||||||
|
|
||||||
|
#ifndef NO_USB_STARTUP_WAIT_LOOP
|
||||||
/* wait for USB startup */
|
/* wait for USB startup */
|
||||||
while (USB_DeviceState != DEVICE_STATE_Configured) {
|
while (USB_DeviceState != DEVICE_STATE_Configured) {
|
||||||
#if defined(INTERRUPT_CONTROL_ENDPOINT)
|
#if defined(INTERRUPT_CONTROL_ENDPOINT)
|
||||||
|
|
@ -652,19 +662,20 @@ int main(void)
|
||||||
#else
|
#else
|
||||||
USB_USBTask();
|
USB_USBTask();
|
||||||
#endif
|
#endif
|
||||||
matrix_scan();
|
hook_usb_startup_wait_loop();
|
||||||
}
|
}
|
||||||
|
print("\nUSB configured.\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
hook_late_init();
|
hook_late_init();
|
||||||
|
|
||||||
print("\nKeyboard start.\n");
|
print("\nKeyboard start.\n");
|
||||||
while (1) {
|
while (1) {
|
||||||
|
#ifndef NO_USB_SUSPEND_LOOP
|
||||||
while (USB_DeviceState == DEVICE_STATE_Suspended) {
|
while (USB_DeviceState == DEVICE_STATE_Suspended) {
|
||||||
#ifdef LUFA_DEBUG
|
|
||||||
print("[s]");
|
|
||||||
#endif
|
|
||||||
hook_usb_suspend_loop();
|
hook_usb_suspend_loop();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
keyboard_task();
|
keyboard_task();
|
||||||
|
|
||||||
|
|
@ -690,12 +701,12 @@ static uint8_t _led_stats = 0;
|
||||||
__attribute__((weak))
|
__attribute__((weak))
|
||||||
void hook_usb_suspend_entry(void)
|
void hook_usb_suspend_entry(void)
|
||||||
{
|
{
|
||||||
// Turn LED off to save power
|
// Turn off LED to save power and keep its status to resotre it later.
|
||||||
// Set 0 with putting aside status before suspend and restore
|
// LED status will be updated by keyboard_task() in main loop hopefully.
|
||||||
// it after wakeup, then LED is updated at keyboard_task() in main loop
|
|
||||||
_led_stats = keyboard_led_stats;
|
_led_stats = keyboard_led_stats;
|
||||||
keyboard_led_stats = 0;
|
keyboard_led_stats = 0;
|
||||||
led_set(keyboard_led_stats);
|
|
||||||
|
// Calling long task here can prevent USB state transition
|
||||||
|
|
||||||
matrix_clear();
|
matrix_clear();
|
||||||
clear_keyboard();
|
clear_keyboard();
|
||||||
|
|
@ -707,7 +718,10 @@ void hook_usb_suspend_entry(void)
|
||||||
__attribute__((weak))
|
__attribute__((weak))
|
||||||
void hook_usb_suspend_loop(void)
|
void hook_usb_suspend_loop(void)
|
||||||
{
|
{
|
||||||
|
#ifndef LUFA_DEBUG_UART
|
||||||
|
// This corrupts debug print when suspend
|
||||||
suspend_power_down();
|
suspend_power_down();
|
||||||
|
#endif
|
||||||
if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) {
|
if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) {
|
||||||
USB_Device_SendRemoteWakeup();
|
USB_Device_SendRemoteWakeup();
|
||||||
}
|
}
|
||||||
|
|
@ -721,10 +735,11 @@ void hook_usb_wakeup(void)
|
||||||
sleep_led_disable();
|
sleep_led_disable();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Restore LED status
|
// Restore LED status and update at keyboard_task() in main loop
|
||||||
// BIOS/grub won't recognize/enumerate if led_set() takes long(around 40ms?)
|
|
||||||
// Converters fall into the case and miss wakeup event(timeout to reply?) in the end.
|
|
||||||
//led_set(host_keyboard_leds());
|
|
||||||
// Instead, restore stats and update at keyboard_task() in main loop
|
|
||||||
keyboard_led_stats = _led_stats;
|
keyboard_led_stats = _led_stats;
|
||||||
|
|
||||||
|
// Calling long task here can prevent USB state transition
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__attribute__((weak))
|
||||||
|
void hook_usb_startup_wait_loop(void) {}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ USB_HID_DIR = protocol/usb_hid
|
||||||
#
|
#
|
||||||
# USB Host Shield
|
# USB Host Shield
|
||||||
#
|
#
|
||||||
USB_HOST_SHIELD_DIR = $(USB_HID_DIR)/USB_Host_Shield_2.0-git
|
USB_HOST_SHIELD_DIR = $(USB_HID_DIR)/USB_Host_Shield_2.0-tmk
|
||||||
USB_HOST_SHIELD_SRC = \
|
USB_HOST_SHIELD_SRC = \
|
||||||
$(USB_HOST_SHIELD_DIR)/Usb.cpp \
|
$(USB_HOST_SHIELD_DIR)/Usb.cpp \
|
||||||
$(USB_HOST_SHIELD_DIR)/usbhid.cpp \
|
$(USB_HOST_SHIELD_DIR)/usbhid.cpp \
|
||||||
|
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Subproject commit ed08df7e68af06a5612d938b1bbf55cc4458518a
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 48b2a0950496c7b8ba1bb6ddb937b6f00a6de781
|
||||||
Loading…
Add table
Reference in a new issue