From: tmk Date: Fri, 18 Jul 2014 17:33:23 +0000 (+0900) Subject: Mkdir rn42 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=59ea5e02f76a37e5021c5f9d02af149e48e7c07c;p=tmk_firmware.git Mkdir rn42 --- diff --git a/keyboard/hhkb_rn42/MEMO.txt b/keyboard/hhkb_rn42/MEMO.txt index 36d4afb..100b444 100644 --- a/keyboard/hhkb_rn42/MEMO.txt +++ b/keyboard/hhkb_rn42/MEMO.txt @@ -2,6 +2,7 @@ Roving RN-42 ============ 07/16 After fix of voltage dividor on GPIO6, had a trouble that it could not send a char to BT module, though could receive. Found R8 had wrong 1K resistor and changed to 10K, after that it can send to the module again. Not sure how it had sent with the wrong 1K before. +07/18 On Linux, had an USB related trouble; keyobard or console didn't work for some reason. Changing PID cured this problem. Very annoying, took very long time before resolved it. @@ -28,6 +29,28 @@ DONE: - Power selector doesn't work; Q4 MOSFET leaks from Lipo to USB power line. -- use Schottky instead 07/04 +Lipo +---- +Sparkfun Polymer Lithium Ion Battery 850mAh: +https://www.sparkfun.com/products/341 +Lipo Cell spec: +https://www.sparkfun.com/datasheets/Batteries/063048%20Li-polymer.pdf +Protection spec: +http://dlnmh9ip6v2uc.cloudfront.net/datasheets/Prototyping/BatteryProtection.pdf + min typical max +over-charge 4.255 4.280 4.305 +over-charge discover? 4.030 4.080 4.130 +over-discharge 2.827 2.900 2.973 +over-discharge discover 3.022 3.100 3.178 + +ADC voltage monitor: voltage divider 10K+10K(0.5) + ADC=V*0.5/2.56*1024 + V ADC + ------------------ + 4.20 0x347(839) + 3.10 0x26b(619) + + Configuration diff --git a/keyboard/hhkb_rn42/Makefile b/keyboard/hhkb_rn42/Makefile index 7a27a43..b46b777 100644 --- a/keyboard/hhkb_rn42/Makefile +++ b/keyboard/hhkb_rn42/Makefile @@ -51,12 +51,7 @@ TARGET_DIR = . # List C source files here. (C dependencies are automatically generated.) SRC += keymap_common.c \ matrix.c \ - led.c \ - serial_uart.c \ - suart.S \ - rn42.c \ - rn42_task.c \ - main.c + led.c ifdef KEYMAP SRC := keymap_$(KEYMAP).c $(SRC) @@ -135,6 +130,7 @@ COMMAND_ENABLE = yes # Commands for debug and configuration VPATH += $(TARGET_DIR) VPATH += $(TOP_DIR) +include rn42.mk include $(TOP_DIR)/protocol.mk include $(TOP_DIR)/protocol/lufa.mk include $(TOP_DIR)/common.mk diff --git a/keyboard/hhkb_rn42/main.c b/keyboard/hhkb_rn42/main.c deleted file mode 100644 index c84f6b0..0000000 --- a/keyboard/hhkb_rn42/main.c +++ /dev/null @@ -1,101 +0,0 @@ -#include -#include -#include -#include "lufa.h" -#include "print.h" -#include "sendchar.h" -#include "rn42.h" -#include "rn42_task.h" -#include "serial.h" -#include "keyboard.h" -#include "keycode.h" -#include "action.h" -#include "action_util.h" -#include "wait.h" -#include "suart.h" - -static int8_t sendchar_func(uint8_t c) -{ - sendchar(c); // LUFA - xmit(c); // SUART - return 0; -} - -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(); - print_set_sendchar(sendchar_func); - - // SUART PD0:output, PD1:input - DDRD |= (1<<0); - PORTD |= (1<<0); - DDRD &= ~(1<<1); - PORTD |= (1<<1); -} - -int main(void) __attribute__ ((weak)); -int main(void) -{ - SetupHardware(); - sei(); - - /* wait for USB startup to get ready for debug output */ - uint8_t timeout = 255; // timeout when USB is not available(Bluetooth) - while (timeout-- && USB_DeviceState != DEVICE_STATE_Configured) { - wait_ms(4); -#if defined(INTERRUPT_CONTROL_ENDPOINT) - ; -#else - USB_USBTask(); -#endif - } - print("USB configured.\n"); - - rn42_init(); - rn42_task_init(); - print("RN-42 init\n"); - - /* init modules */ - keyboard_init(); - - if (!rn42_rts()) { - host_set_driver(&rn42_driver); - } else { - host_set_driver(&lufa_driver); - } - -#ifdef SLEEP_LED_ENABLE - sleep_led_init(); -#endif - - print("Keyboard start.\n"); - while (1) { - while (USB_DeviceState == DEVICE_STATE_Suspended) { - suspend_power_down(); - if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) { - USB_Device_SendRemoteWakeup(); - } - } - - keyboard_task(); - -#if !defined(INTERRUPT_CONTROL_ENDPOINT) - USB_USBTask(); -#endif - - rn42_task(); - } -} diff --git a/keyboard/hhkb_rn42/rn42.c b/keyboard/hhkb_rn42/rn42.c deleted file mode 100644 index 3fcd64a..0000000 --- a/keyboard/hhkb_rn42/rn42.c +++ /dev/null @@ -1,192 +0,0 @@ -#include -#include "host.h" -#include "host_driver.h" -#include "serial.h" -#include "rn42.h" -#include "print.h" -#include "wait.h" - - -/* Host driver */ -static uint8_t keyboard_leds(void); -static void send_keyboard(report_keyboard_t *report); -static void send_mouse(report_mouse_t *report); -static void send_system(uint16_t data); -static void send_consumer(uint16_t data); - -host_driver_t rn42_driver = { - keyboard_leds, - send_keyboard, - send_mouse, - send_system, - send_consumer -}; - - -void rn42_init(void) -{ - // PF7: BT connection control(HiZ: connect, low: disconnect) - // JTAG disable for PORT F. write JTD bit twice within four cycles. - MCUCR |= (1<mods); - serial_send(0x00); - serial_send(report->keys[0]); - serial_send(report->keys[1]); - serial_send(report->keys[2]); - serial_send(report->keys[3]); - serial_send(report->keys[4]); - serial_send(report->keys[5]); -} - -static void send_mouse(report_mouse_t *report) -{ - // wake from deep sleep -/* - PORTD |= (1<<5); // high - wait_ms(5); - PORTD &= ~(1<<5); // low -*/ - - serial_send(0xFD); // Raw report mode - serial_send(5); // length - serial_send(2); // descriptor type - serial_send(report->buttons); - serial_send(report->x); - serial_send(report->y); - serial_send(report->v); -} - -static void send_system(uint16_t data) -{ - // Table 5-6 of RN-BT-DATA-UB - // 81,82,83 scan codes can be used? -} - - -static uint16_t usage2bits(uint16_t usage) -{ - switch (usage) { - case AC_HOME: return 0x01; - case AL_EMAIL: return 0x02; - case AC_SEARCH: return 0x04; - //case AL_KBD_LAYOUT: return 0x08; // Apple virtual keybaord toggle - case AUDIO_VOL_UP: return 0x10; - case AUDIO_VOL_DOWN: return 0x20; - case AUDIO_MUTE: return 0x40; - case TRANSPORT_PLAY_PAUSE: return 0x80; - case TRANSPORT_NEXT_TRACK: return 0x100; - case TRANSPORT_PREV_TRACK: return 0x200; - case TRANSPORT_STOP: return 0x400; - case TRANSPORT_STOP_EJECT: return 0x800; - //case return 0x1000; // Fast forward - //case return 0x2000; // Rewind - //case return 0x4000; // Stop/eject - //case return 0x8000; // Internet browser - }; - return 0; -} - -static void send_consumer(uint16_t data) -{ - uint16_t bits = usage2bits(data); - serial_send(0xFD); // Raw report mode - serial_send(3); // length - serial_send(3); // descriptor type - serial_send(bits&0xFF); - serial_send((bits>>8)&0xFF); -} - - -/* Null driver for config_mode */ -static uint8_t config_keyboard_leds(void); -static void config_send_keyboard(report_keyboard_t *report); -static void config_send_mouse(report_mouse_t *report); -static void config_send_system(uint16_t data); -static void config_send_consumer(uint16_t data); - -host_driver_t rn42_config_driver = { - config_keyboard_leds, - config_send_keyboard, - config_send_mouse, - config_send_system, - config_send_consumer -}; - -static uint8_t config_keyboard_leds(void) { return 0; } -static void config_send_keyboard(report_keyboard_t *report) {} -static void config_send_mouse(report_mouse_t *report) {} -static void config_send_system(uint16_t data) {} -static void config_send_consumer(uint16_t data) {} diff --git a/keyboard/hhkb_rn42/rn42.h b/keyboard/hhkb_rn42/rn42.h deleted file mode 100644 index 4189733..0000000 --- a/keyboard/hhkb_rn42/rn42.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef RN42_H -#define RN42_H - -#include - -host_driver_t rn42_driver; -host_driver_t rn42_config_driver; - -void rn42_init(void); -void rn42_putc(uint8_t c); -bool rn42_autoconnecting(void); -void rn42_autoconnect(void); -void rn42_disconnect(void); -bool rn42_rts(void); -void rn42_cts_hi(void); -void rn42_cts_lo(void); - -#endif diff --git a/keyboard/hhkb_rn42/rn42.mk b/keyboard/hhkb_rn42/rn42.mk new file mode 100644 index 0000000..653a809 --- /dev/null +++ b/keyboard/hhkb_rn42/rn42.mk @@ -0,0 +1,11 @@ +RN42_DIR = rn42 + +SRC += serial_uart.c \ + rn42/suart.S \ + rn42/rn42.c \ + rn42/rn42_task.c \ + rn42/main.c + +OPT_DEFS += -DPROTOCOL_RN42 + +VPATH += $(RN42_DIR) diff --git a/keyboard/hhkb_rn42/rn42/main.c b/keyboard/hhkb_rn42/rn42/main.c new file mode 100644 index 0000000..a3a37c0 --- /dev/null +++ b/keyboard/hhkb_rn42/rn42/main.c @@ -0,0 +1,102 @@ +#include +#include +#include +#include "lufa.h" +#include "print.h" +#include "sendchar.h" +#include "rn42.h" +#include "rn42_task.h" +#include "serial.h" +#include "keyboard.h" +#include "keycode.h" +#include "action.h" +#include "action_util.h" +#include "wait.h" +#include "suart.h" +#include "suspend.h" + +static int8_t sendchar_func(uint8_t c) +{ + sendchar(c); // LUFA + xmit(c); // SUART + return 0; +} + +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(); + print_set_sendchar(sendchar_func); + + // SUART PD0:output, PD1:input + DDRD |= (1<<0); + PORTD |= (1<<0); + DDRD &= ~(1<<1); + PORTD |= (1<<1); +} + +int main(void) __attribute__ ((weak)); +int main(void) +{ + SetupHardware(); + sei(); + + /* wait for USB startup to get ready for debug output */ + uint8_t timeout = 255; // timeout when USB is not available(Bluetooth) + while (timeout-- && USB_DeviceState != DEVICE_STATE_Configured) { + wait_ms(4); +#if defined(INTERRUPT_CONTROL_ENDPOINT) + ; +#else + USB_USBTask(); +#endif + } + print("USB configured.\n"); + + rn42_init(); + rn42_task_init(); + print("RN-42 init\n"); + + /* init modules */ + keyboard_init(); + + if (!rn42_rts()) { + host_set_driver(&rn42_driver); + } else { + host_set_driver(&lufa_driver); + } + +#ifdef SLEEP_LED_ENABLE + sleep_led_init(); +#endif + + print("Keyboard start.\n"); + while (1) { + while (USB_DeviceState == DEVICE_STATE_Suspended) { + suspend_power_down(); + if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) { + USB_Device_SendRemoteWakeup(); + } + } + + keyboard_task(); + +#if !defined(INTERRUPT_CONTROL_ENDPOINT) + USB_USBTask(); +#endif + + rn42_task(); + } +} diff --git a/keyboard/hhkb_rn42/rn42/rn42.c b/keyboard/hhkb_rn42/rn42/rn42.c new file mode 100644 index 0000000..3fcd64a --- /dev/null +++ b/keyboard/hhkb_rn42/rn42/rn42.c @@ -0,0 +1,192 @@ +#include +#include "host.h" +#include "host_driver.h" +#include "serial.h" +#include "rn42.h" +#include "print.h" +#include "wait.h" + + +/* Host driver */ +static uint8_t keyboard_leds(void); +static void send_keyboard(report_keyboard_t *report); +static void send_mouse(report_mouse_t *report); +static void send_system(uint16_t data); +static void send_consumer(uint16_t data); + +host_driver_t rn42_driver = { + keyboard_leds, + send_keyboard, + send_mouse, + send_system, + send_consumer +}; + + +void rn42_init(void) +{ + // PF7: BT connection control(HiZ: connect, low: disconnect) + // JTAG disable for PORT F. write JTD bit twice within four cycles. + MCUCR |= (1<mods); + serial_send(0x00); + serial_send(report->keys[0]); + serial_send(report->keys[1]); + serial_send(report->keys[2]); + serial_send(report->keys[3]); + serial_send(report->keys[4]); + serial_send(report->keys[5]); +} + +static void send_mouse(report_mouse_t *report) +{ + // wake from deep sleep +/* + PORTD |= (1<<5); // high + wait_ms(5); + PORTD &= ~(1<<5); // low +*/ + + serial_send(0xFD); // Raw report mode + serial_send(5); // length + serial_send(2); // descriptor type + serial_send(report->buttons); + serial_send(report->x); + serial_send(report->y); + serial_send(report->v); +} + +static void send_system(uint16_t data) +{ + // Table 5-6 of RN-BT-DATA-UB + // 81,82,83 scan codes can be used? +} + + +static uint16_t usage2bits(uint16_t usage) +{ + switch (usage) { + case AC_HOME: return 0x01; + case AL_EMAIL: return 0x02; + case AC_SEARCH: return 0x04; + //case AL_KBD_LAYOUT: return 0x08; // Apple virtual keybaord toggle + case AUDIO_VOL_UP: return 0x10; + case AUDIO_VOL_DOWN: return 0x20; + case AUDIO_MUTE: return 0x40; + case TRANSPORT_PLAY_PAUSE: return 0x80; + case TRANSPORT_NEXT_TRACK: return 0x100; + case TRANSPORT_PREV_TRACK: return 0x200; + case TRANSPORT_STOP: return 0x400; + case TRANSPORT_STOP_EJECT: return 0x800; + //case return 0x1000; // Fast forward + //case return 0x2000; // Rewind + //case return 0x4000; // Stop/eject + //case return 0x8000; // Internet browser + }; + return 0; +} + +static void send_consumer(uint16_t data) +{ + uint16_t bits = usage2bits(data); + serial_send(0xFD); // Raw report mode + serial_send(3); // length + serial_send(3); // descriptor type + serial_send(bits&0xFF); + serial_send((bits>>8)&0xFF); +} + + +/* Null driver for config_mode */ +static uint8_t config_keyboard_leds(void); +static void config_send_keyboard(report_keyboard_t *report); +static void config_send_mouse(report_mouse_t *report); +static void config_send_system(uint16_t data); +static void config_send_consumer(uint16_t data); + +host_driver_t rn42_config_driver = { + config_keyboard_leds, + config_send_keyboard, + config_send_mouse, + config_send_system, + config_send_consumer +}; + +static uint8_t config_keyboard_leds(void) { return 0; } +static void config_send_keyboard(report_keyboard_t *report) {} +static void config_send_mouse(report_mouse_t *report) {} +static void config_send_system(uint16_t data) {} +static void config_send_consumer(uint16_t data) {} diff --git a/keyboard/hhkb_rn42/rn42/rn42.h b/keyboard/hhkb_rn42/rn42/rn42.h new file mode 100644 index 0000000..4189733 --- /dev/null +++ b/keyboard/hhkb_rn42/rn42/rn42.h @@ -0,0 +1,18 @@ +#ifndef RN42_H +#define RN42_H + +#include + +host_driver_t rn42_driver; +host_driver_t rn42_config_driver; + +void rn42_init(void); +void rn42_putc(uint8_t c); +bool rn42_autoconnecting(void); +void rn42_autoconnect(void); +void rn42_disconnect(void); +bool rn42_rts(void); +void rn42_cts_hi(void); +void rn42_cts_lo(void); + +#endif diff --git a/keyboard/hhkb_rn42/rn42/rn42_task.c b/keyboard/hhkb_rn42/rn42/rn42_task.c new file mode 100644 index 0000000..7ec4c1b --- /dev/null +++ b/keyboard/hhkb_rn42/rn42/rn42_task.c @@ -0,0 +1,255 @@ +#include +#include "keycode.h" +#include "serial.h" +#include "host.h" +#include "action.h" +#include "action_util.h" +#include "lufa.h" +#include "rn42_task.h" +#include "print.h" +#include "timer.h" +#include "command.h" + +static bool config_mode = false; +static bool force_usb = false; + +static void battery_adc_init(void) +{ + ADMUX = (1< + // To get the report over UART set bit3 with SH, command. + static enum {LED_INIT, LED_FE, LED_02, LED_01} state = LED_INIT; + xprintf("%02X\n", c); + switch (state) { + case LED_INIT: + if (c == 0xFE) state = LED_FE; + else state = LED_INIT; + break; + case LED_FE: + if (c == 0x02) state = LED_02; + else state = LED_INIT; + break; + case LED_02: + if (c == 0x01) state = LED_01; + else state = LED_INIT; + break; + case LED_01: + // TODO: move to rn42.c and make accessible with keyboard_leds() + xprintf("LED status: %02X\n", c); + state = LED_INIT; + break; + default: + state = LED_INIT; + } + } + } + + /* Bluetooth mode when ready */ + if (!config_mode && !force_usb) { + if (!rn42_rts() && host_get_driver() != &rn42_driver) { + clear_keyboard(); + host_set_driver(&rn42_driver); + } else if (rn42_rts() && host_get_driver() != &lufa_driver) { + clear_keyboard(); + host_set_driver(&lufa_driver); + } + } +} + + + +/****************************************************************************** + * Command + ******************************************************************************/ +bool command_extra(uint8_t code) +{ + static host_driver_t *prev_driver = &rn42_driver; + switch (code) { + case KC_H: + case KC_SLASH: /* ? */ + print("\n\n----- Bluetooth RN-42 Help -----\n"); + print("Del: enter/exit config mode(auto_connect/disconnect)\n"); + print("i: RN-42 info\n"); + print("b: battery voltage\n"); + + if (config_mode) { + return true; + } else { + print("u: Force USB mode\n"); + return false; // to display default command help + } + case KC_DELETE: + if (rn42_autoconnecting()) { + prev_driver = host_get_driver(); + clear_keyboard(); + _delay_ms(500); + host_set_driver(&rn42_config_driver); // null driver; not to send a key to host + rn42_disconnect(); + print("\nRN-42: disconnect\n"); + print("Enter config mode\n"); + print("type $$$ to start and + for local echo\n"); + command_state = CONSOLE; + config_mode = true; + } else { + rn42_autoconnect(); + print("\nRN-42: auto_connect\n"); + print("Exit config mode\n"); + command_state = ONESHOT; + config_mode = false; + //clear_keyboard(); + host_set_driver(prev_driver); + } + return true; + case KC_U: + if (config_mode) return false; + if (force_usb) { + print("Auto mode\n"); + force_usb = false; + } else { + print("USB mode\n"); + force_usb = true; + clear_keyboard(); + host_set_driver(&lufa_driver); + } + return true; + case KC_I: + print("\n----- RN-42 info -----\n"); + xprintf("protocol: %s\n", (host_get_driver() == &rn42_driver) ? "RN-42" : "LUFA"); + xprintf("force_usb: %X\n", force_usb); + xprintf("rn42_autoconnecting(): %X\n", rn42_autoconnecting()); + xprintf("rn42_rts(): %X\n", rn42_rts()); + xprintf("config_mode: %X\n", config_mode); + return true; + case KC_B: + // battery monitor + xprintf("BAT: %04X(%08lX)\n", battery_adc(), timer_read32()); + return true; + default: + if (config_mode) + return true; + else + return false; // exec default command + } + return true; +} + +static uint8_t code2asc(uint8_t code); +bool command_console_extra(uint8_t code) +{ + switch (code) { + default: + rn42_putc(code2asc(code)); + return true; + } + return false; +} + +// convert keycode into ascii charactor +static uint8_t code2asc(uint8_t code) +{ + bool shifted = (get_mods() & (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT))) ? true : false; + switch (code) { + case KC_A: return (shifted ? 'A' : 'a'); + case KC_B: return (shifted ? 'B' : 'b'); + case KC_C: return (shifted ? 'C' : 'c'); + case KC_D: return (shifted ? 'D' : 'd'); + case KC_E: return (shifted ? 'E' : 'e'); + case KC_F: return (shifted ? 'F' : 'f'); + case KC_G: return (shifted ? 'G' : 'g'); + case KC_H: return (shifted ? 'H' : 'h'); + case KC_I: return (shifted ? 'I' : 'i'); + case KC_J: return (shifted ? 'J' : 'j'); + case KC_K: return (shifted ? 'K' : 'k'); + case KC_L: return (shifted ? 'L' : 'l'); + case KC_M: return (shifted ? 'M' : 'm'); + case KC_N: return (shifted ? 'N' : 'n'); + case KC_O: return (shifted ? 'O' : 'o'); + case KC_P: return (shifted ? 'P' : 'p'); + case KC_Q: return (shifted ? 'Q' : 'q'); + case KC_R: return (shifted ? 'R' : 'r'); + case KC_S: return (shifted ? 'S' : 's'); + case KC_T: return (shifted ? 'T' : 't'); + case KC_U: return (shifted ? 'U' : 'u'); + case KC_V: return (shifted ? 'V' : 'v'); + case KC_W: return (shifted ? 'W' : 'w'); + case KC_X: return (shifted ? 'X' : 'x'); + case KC_Y: return (shifted ? 'Y' : 'y'); + case KC_Z: return (shifted ? 'Z' : 'z'); + case KC_1: return (shifted ? '!' : '1'); + case KC_2: return (shifted ? '@' : '2'); + case KC_3: return (shifted ? '#' : '3'); + case KC_4: return (shifted ? '$' : '4'); + case KC_5: return (shifted ? '%' : '5'); + case KC_6: return (shifted ? '^' : '6'); + case KC_7: return (shifted ? '&' : '7'); + case KC_8: return (shifted ? '*' : '8'); + case KC_9: return (shifted ? '(' : '9'); + case KC_0: return (shifted ? ')' : '0'); + case KC_ENTER: return '\n'; + case KC_ESCAPE: return 0x1B; + case KC_BSPACE: return '\b'; + case KC_TAB: return '\t'; + case KC_SPACE: return ' '; + case KC_MINUS: return (shifted ? '_' : '-'); + case KC_EQUAL: return (shifted ? '+' : '='); + case KC_LBRACKET: return (shifted ? '{' : '['); + case KC_RBRACKET: return (shifted ? '}' : ']'); + case KC_BSLASH: return (shifted ? '|' : '\\'); + case KC_NONUS_HASH: return (shifted ? '|' : '\\'); + case KC_SCOLON: return (shifted ? ':' : ';'); + case KC_QUOTE: return (shifted ? '"' : '\''); + case KC_GRAVE: return (shifted ? '~' : '`'); + case KC_COMMA: return (shifted ? '<' : ','); + case KC_DOT: return (shifted ? '>' : '.'); + case KC_SLASH: return (shifted ? '?' : '/'); + case KC_DELETE: return '\0'; // Delete to disconnect + default: return ' '; + } +} diff --git a/keyboard/hhkb_rn42/rn42/rn42_task.h b/keyboard/hhkb_rn42/rn42/rn42_task.h new file mode 100644 index 0000000..8f6c3ab --- /dev/null +++ b/keyboard/hhkb_rn42/rn42/rn42_task.h @@ -0,0 +1,10 @@ +#ifndef RN42_TASK_H +#define RN42_TASK_H + +#include +#include "rn42.h" + +void rn42_task_init(void); +void rn42_task(void); + +#endif diff --git a/keyboard/hhkb_rn42/rn42/suart.S b/keyboard/hhkb_rn42/rn42/suart.S new file mode 100644 index 0000000..9fa5452 --- /dev/null +++ b/keyboard/hhkb_rn42/rn42/suart.S @@ -0,0 +1,156 @@ +;---------------------------------------------------------------------------; +; Software implemented UART module ; +; (C)ChaN, 2005 (http://elm-chan.org/) ; +;---------------------------------------------------------------------------; +; Bit rate settings: +; +; 1MHz 2MHz 4MHz 6MHz 8MHz 10MHz 12MHz 16MHz 20MHz +; 2.4kbps 138 - - - - - - - - +; 4.8kbps 68 138 - - - - - - - +; 9.6kbps 33 68 138 208 - - - - - +; 19.2kbps - 33 68 102 138 173 208 - - +; 38.4kbps - - 33 50 68 85 102 138 172 +; 57.6kbps - - 21 33 44 56 68 91 114 +; 115.2kbps - - - - 21 27 33 44 56 + +.nolist +#include +.list + +#define BPS 44 /* Bit delay. (see above table) */ +#define BIDIR 0 /* 0:Separated Tx/Rx, 1:Shared Tx/Rx */ + +#define OUT_1 sbi _SFR_IO_ADDR(SUART_OUT_PORT), SUART_OUT_BIT /* Output 1 */ +#define OUT_0 cbi _SFR_IO_ADDR(SUART_OUT_PORT), SUART_OUT_BIT /* Output 0 */ +#define SKIP_IN_1 sbis _SFR_IO_ADDR(SUART_IN_PIN), SUART_IN_BIT /* Skip if 1 */ +#define SKIP_IN_0 sbic _SFR_IO_ADDR(SUART_IN_PIN), SUART_IN_BIT /* Skip if 0 */ + + + +#ifdef SPM_PAGESIZE +.macro _LPMI reg + lpm \reg, Z+ +.endm +.macro _MOVW dh,dl, sh,sl + movw \dl, \sl +.endm +#else +.macro _LPMI reg + lpm + mov \reg, r0 + adiw ZL, 1 +.endm +.macro _MOVW dh,dl, sh,sl + mov \dl, \sl + mov \dh, \sh +.endm +#endif + + + +;---------------------------------------------------------------------------; +; Transmit a byte in serial format of N81 +; +;Prototype: void xmit (uint8_t data); +;Size: 16 words + +.global xmit +.func xmit +xmit: +#if BIDIR + ldi r23, BPS-1 ;Pre-idle time for bidirectional data line +5: dec r23 ; + brne 5b ;/ +#endif + in r0, _SFR_IO_ADDR(SREG) ;Save flags + + com r24 ;C = start bit + ldi r25, 10 ;Bit counter + cli ;Start critical section + +1: ldi r23, BPS-1 ;----- Bit transferring loop +2: dec r23 ;Wait for a bit time + brne 2b ;/ + brcs 3f ;MISO = bit to be sent + OUT_1 ; +3: brcc 4f ; + OUT_0 ;/ +4: lsr r24 ;Get next bit into C + dec r25 ;All bits sent? + brne 1b ; no, coutinue + + out _SFR_IO_ADDR(SREG), r0 ;End of critical section + ret +.endfunc + + + +;---------------------------------------------------------------------------; +; Receive a byte +; +;Prototype: uint8_t rcvr (void); +;Size: 19 words + +.global rcvr +.func rcvr +rcvr: + in r0, _SFR_IO_ADDR(SREG) ;Save flags + + ldi r24, 0x80 ;Receiving shift reg + cli ;Start critical section + +1: SKIP_IN_1 ;Wait for idle + rjmp 1b +2: SKIP_IN_0 ;Wait for start bit + rjmp 2b + ldi r25, BPS/2 ;Wait for half bit time +3: dec r25 + brne 3b + +4: ldi r25, BPS ;----- Bit receiving loop +5: dec r25 ;Wait for a bit time + brne 5b ;/ + lsr r24 ;Next bit + SKIP_IN_0 ;Get a data bit into r24.7 + ori r24, 0x80 + brcc 4b ;All bits received? no, continue + + out _SFR_IO_ADDR(SREG), r0 ;End of critical section + ret +.endfunc + + +; Not wait for start bit. This should be called after detecting start bit. +.global recv +.func recv +recv: + in r0, _SFR_IO_ADDR(SREG) ;Save flags + + ldi r24, 0x80 ;Receiving shift reg + cli ;Start critical section + +;1: SKIP_IN_1 ;Wait for idle +; rjmp 1b +;2: SKIP_IN_0 ;Wait for start bit +; rjmp 2b + ldi r25, BPS/2 ;Wait for half bit time +3: dec r25 + brne 3b + +4: ldi r25, BPS ;----- Bit receiving loop +5: dec r25 ;Wait for a bit time + brne 5b ;/ + lsr r24 ;Next bit + SKIP_IN_0 ;Get a data bit into r24.7 + ori r24, 0x80 + brcc 4b ;All bits received? no, continue + + ldi r25, BPS/2 ;Wait for half bit time +6: dec r25 + brne 6b +7: SKIP_IN_1 ;Wait for stop bit + rjmp 7b + + out _SFR_IO_ADDR(SREG), r0 ;End of critical section + ret +.endfunc diff --git a/keyboard/hhkb_rn42/rn42/suart.h b/keyboard/hhkb_rn42/rn42/suart.h new file mode 100644 index 0000000..72725b9 --- /dev/null +++ b/keyboard/hhkb_rn42/rn42/suart.h @@ -0,0 +1,8 @@ +#ifndef SUART +#define SUART + +void xmit(uint8_t); +uint8_t rcvr(void); +uint8_t recv(void); + +#endif /* SUART */ diff --git a/keyboard/hhkb_rn42/rn42_task.c b/keyboard/hhkb_rn42/rn42_task.c deleted file mode 100644 index 7ec4c1b..0000000 --- a/keyboard/hhkb_rn42/rn42_task.c +++ /dev/null @@ -1,255 +0,0 @@ -#include -#include "keycode.h" -#include "serial.h" -#include "host.h" -#include "action.h" -#include "action_util.h" -#include "lufa.h" -#include "rn42_task.h" -#include "print.h" -#include "timer.h" -#include "command.h" - -static bool config_mode = false; -static bool force_usb = false; - -static void battery_adc_init(void) -{ - ADMUX = (1< - // To get the report over UART set bit3 with SH, command. - static enum {LED_INIT, LED_FE, LED_02, LED_01} state = LED_INIT; - xprintf("%02X\n", c); - switch (state) { - case LED_INIT: - if (c == 0xFE) state = LED_FE; - else state = LED_INIT; - break; - case LED_FE: - if (c == 0x02) state = LED_02; - else state = LED_INIT; - break; - case LED_02: - if (c == 0x01) state = LED_01; - else state = LED_INIT; - break; - case LED_01: - // TODO: move to rn42.c and make accessible with keyboard_leds() - xprintf("LED status: %02X\n", c); - state = LED_INIT; - break; - default: - state = LED_INIT; - } - } - } - - /* Bluetooth mode when ready */ - if (!config_mode && !force_usb) { - if (!rn42_rts() && host_get_driver() != &rn42_driver) { - clear_keyboard(); - host_set_driver(&rn42_driver); - } else if (rn42_rts() && host_get_driver() != &lufa_driver) { - clear_keyboard(); - host_set_driver(&lufa_driver); - } - } -} - - - -/****************************************************************************** - * Command - ******************************************************************************/ -bool command_extra(uint8_t code) -{ - static host_driver_t *prev_driver = &rn42_driver; - switch (code) { - case KC_H: - case KC_SLASH: /* ? */ - print("\n\n----- Bluetooth RN-42 Help -----\n"); - print("Del: enter/exit config mode(auto_connect/disconnect)\n"); - print("i: RN-42 info\n"); - print("b: battery voltage\n"); - - if (config_mode) { - return true; - } else { - print("u: Force USB mode\n"); - return false; // to display default command help - } - case KC_DELETE: - if (rn42_autoconnecting()) { - prev_driver = host_get_driver(); - clear_keyboard(); - _delay_ms(500); - host_set_driver(&rn42_config_driver); // null driver; not to send a key to host - rn42_disconnect(); - print("\nRN-42: disconnect\n"); - print("Enter config mode\n"); - print("type $$$ to start and + for local echo\n"); - command_state = CONSOLE; - config_mode = true; - } else { - rn42_autoconnect(); - print("\nRN-42: auto_connect\n"); - print("Exit config mode\n"); - command_state = ONESHOT; - config_mode = false; - //clear_keyboard(); - host_set_driver(prev_driver); - } - return true; - case KC_U: - if (config_mode) return false; - if (force_usb) { - print("Auto mode\n"); - force_usb = false; - } else { - print("USB mode\n"); - force_usb = true; - clear_keyboard(); - host_set_driver(&lufa_driver); - } - return true; - case KC_I: - print("\n----- RN-42 info -----\n"); - xprintf("protocol: %s\n", (host_get_driver() == &rn42_driver) ? "RN-42" : "LUFA"); - xprintf("force_usb: %X\n", force_usb); - xprintf("rn42_autoconnecting(): %X\n", rn42_autoconnecting()); - xprintf("rn42_rts(): %X\n", rn42_rts()); - xprintf("config_mode: %X\n", config_mode); - return true; - case KC_B: - // battery monitor - xprintf("BAT: %04X(%08lX)\n", battery_adc(), timer_read32()); - return true; - default: - if (config_mode) - return true; - else - return false; // exec default command - } - return true; -} - -static uint8_t code2asc(uint8_t code); -bool command_console_extra(uint8_t code) -{ - switch (code) { - default: - rn42_putc(code2asc(code)); - return true; - } - return false; -} - -// convert keycode into ascii charactor -static uint8_t code2asc(uint8_t code) -{ - bool shifted = (get_mods() & (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT))) ? true : false; - switch (code) { - case KC_A: return (shifted ? 'A' : 'a'); - case KC_B: return (shifted ? 'B' : 'b'); - case KC_C: return (shifted ? 'C' : 'c'); - case KC_D: return (shifted ? 'D' : 'd'); - case KC_E: return (shifted ? 'E' : 'e'); - case KC_F: return (shifted ? 'F' : 'f'); - case KC_G: return (shifted ? 'G' : 'g'); - case KC_H: return (shifted ? 'H' : 'h'); - case KC_I: return (shifted ? 'I' : 'i'); - case KC_J: return (shifted ? 'J' : 'j'); - case KC_K: return (shifted ? 'K' : 'k'); - case KC_L: return (shifted ? 'L' : 'l'); - case KC_M: return (shifted ? 'M' : 'm'); - case KC_N: return (shifted ? 'N' : 'n'); - case KC_O: return (shifted ? 'O' : 'o'); - case KC_P: return (shifted ? 'P' : 'p'); - case KC_Q: return (shifted ? 'Q' : 'q'); - case KC_R: return (shifted ? 'R' : 'r'); - case KC_S: return (shifted ? 'S' : 's'); - case KC_T: return (shifted ? 'T' : 't'); - case KC_U: return (shifted ? 'U' : 'u'); - case KC_V: return (shifted ? 'V' : 'v'); - case KC_W: return (shifted ? 'W' : 'w'); - case KC_X: return (shifted ? 'X' : 'x'); - case KC_Y: return (shifted ? 'Y' : 'y'); - case KC_Z: return (shifted ? 'Z' : 'z'); - case KC_1: return (shifted ? '!' : '1'); - case KC_2: return (shifted ? '@' : '2'); - case KC_3: return (shifted ? '#' : '3'); - case KC_4: return (shifted ? '$' : '4'); - case KC_5: return (shifted ? '%' : '5'); - case KC_6: return (shifted ? '^' : '6'); - case KC_7: return (shifted ? '&' : '7'); - case KC_8: return (shifted ? '*' : '8'); - case KC_9: return (shifted ? '(' : '9'); - case KC_0: return (shifted ? ')' : '0'); - case KC_ENTER: return '\n'; - case KC_ESCAPE: return 0x1B; - case KC_BSPACE: return '\b'; - case KC_TAB: return '\t'; - case KC_SPACE: return ' '; - case KC_MINUS: return (shifted ? '_' : '-'); - case KC_EQUAL: return (shifted ? '+' : '='); - case KC_LBRACKET: return (shifted ? '{' : '['); - case KC_RBRACKET: return (shifted ? '}' : ']'); - case KC_BSLASH: return (shifted ? '|' : '\\'); - case KC_NONUS_HASH: return (shifted ? '|' : '\\'); - case KC_SCOLON: return (shifted ? ':' : ';'); - case KC_QUOTE: return (shifted ? '"' : '\''); - case KC_GRAVE: return (shifted ? '~' : '`'); - case KC_COMMA: return (shifted ? '<' : ','); - case KC_DOT: return (shifted ? '>' : '.'); - case KC_SLASH: return (shifted ? '?' : '/'); - case KC_DELETE: return '\0'; // Delete to disconnect - default: return ' '; - } -} diff --git a/keyboard/hhkb_rn42/rn42_task.h b/keyboard/hhkb_rn42/rn42_task.h deleted file mode 100644 index d75b030..0000000 --- a/keyboard/hhkb_rn42/rn42_task.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef RN42_TASK_H -#define RN42_TASK_H - -#include -#include "rn42.h" - -void rn42_task(void); - -#endif diff --git a/keyboard/hhkb_rn42/suart.S b/keyboard/hhkb_rn42/suart.S deleted file mode 100644 index 9fa5452..0000000 --- a/keyboard/hhkb_rn42/suart.S +++ /dev/null @@ -1,156 +0,0 @@ -;---------------------------------------------------------------------------; -; Software implemented UART module ; -; (C)ChaN, 2005 (http://elm-chan.org/) ; -;---------------------------------------------------------------------------; -; Bit rate settings: -; -; 1MHz 2MHz 4MHz 6MHz 8MHz 10MHz 12MHz 16MHz 20MHz -; 2.4kbps 138 - - - - - - - - -; 4.8kbps 68 138 - - - - - - - -; 9.6kbps 33 68 138 208 - - - - - -; 19.2kbps - 33 68 102 138 173 208 - - -; 38.4kbps - - 33 50 68 85 102 138 172 -; 57.6kbps - - 21 33 44 56 68 91 114 -; 115.2kbps - - - - 21 27 33 44 56 - -.nolist -#include -.list - -#define BPS 44 /* Bit delay. (see above table) */ -#define BIDIR 0 /* 0:Separated Tx/Rx, 1:Shared Tx/Rx */ - -#define OUT_1 sbi _SFR_IO_ADDR(SUART_OUT_PORT), SUART_OUT_BIT /* Output 1 */ -#define OUT_0 cbi _SFR_IO_ADDR(SUART_OUT_PORT), SUART_OUT_BIT /* Output 0 */ -#define SKIP_IN_1 sbis _SFR_IO_ADDR(SUART_IN_PIN), SUART_IN_BIT /* Skip if 1 */ -#define SKIP_IN_0 sbic _SFR_IO_ADDR(SUART_IN_PIN), SUART_IN_BIT /* Skip if 0 */ - - - -#ifdef SPM_PAGESIZE -.macro _LPMI reg - lpm \reg, Z+ -.endm -.macro _MOVW dh,dl, sh,sl - movw \dl, \sl -.endm -#else -.macro _LPMI reg - lpm - mov \reg, r0 - adiw ZL, 1 -.endm -.macro _MOVW dh,dl, sh,sl - mov \dl, \sl - mov \dh, \sh -.endm -#endif - - - -;---------------------------------------------------------------------------; -; Transmit a byte in serial format of N81 -; -;Prototype: void xmit (uint8_t data); -;Size: 16 words - -.global xmit -.func xmit -xmit: -#if BIDIR - ldi r23, BPS-1 ;Pre-idle time for bidirectional data line -5: dec r23 ; - brne 5b ;/ -#endif - in r0, _SFR_IO_ADDR(SREG) ;Save flags - - com r24 ;C = start bit - ldi r25, 10 ;Bit counter - cli ;Start critical section - -1: ldi r23, BPS-1 ;----- Bit transferring loop -2: dec r23 ;Wait for a bit time - brne 2b ;/ - brcs 3f ;MISO = bit to be sent - OUT_1 ; -3: brcc 4f ; - OUT_0 ;/ -4: lsr r24 ;Get next bit into C - dec r25 ;All bits sent? - brne 1b ; no, coutinue - - out _SFR_IO_ADDR(SREG), r0 ;End of critical section - ret -.endfunc - - - -;---------------------------------------------------------------------------; -; Receive a byte -; -;Prototype: uint8_t rcvr (void); -;Size: 19 words - -.global rcvr -.func rcvr -rcvr: - in r0, _SFR_IO_ADDR(SREG) ;Save flags - - ldi r24, 0x80 ;Receiving shift reg - cli ;Start critical section - -1: SKIP_IN_1 ;Wait for idle - rjmp 1b -2: SKIP_IN_0 ;Wait for start bit - rjmp 2b - ldi r25, BPS/2 ;Wait for half bit time -3: dec r25 - brne 3b - -4: ldi r25, BPS ;----- Bit receiving loop -5: dec r25 ;Wait for a bit time - brne 5b ;/ - lsr r24 ;Next bit - SKIP_IN_0 ;Get a data bit into r24.7 - ori r24, 0x80 - brcc 4b ;All bits received? no, continue - - out _SFR_IO_ADDR(SREG), r0 ;End of critical section - ret -.endfunc - - -; Not wait for start bit. This should be called after detecting start bit. -.global recv -.func recv -recv: - in r0, _SFR_IO_ADDR(SREG) ;Save flags - - ldi r24, 0x80 ;Receiving shift reg - cli ;Start critical section - -;1: SKIP_IN_1 ;Wait for idle -; rjmp 1b -;2: SKIP_IN_0 ;Wait for start bit -; rjmp 2b - ldi r25, BPS/2 ;Wait for half bit time -3: dec r25 - brne 3b - -4: ldi r25, BPS ;----- Bit receiving loop -5: dec r25 ;Wait for a bit time - brne 5b ;/ - lsr r24 ;Next bit - SKIP_IN_0 ;Get a data bit into r24.7 - ori r24, 0x80 - brcc 4b ;All bits received? no, continue - - ldi r25, BPS/2 ;Wait for half bit time -6: dec r25 - brne 6b -7: SKIP_IN_1 ;Wait for stop bit - rjmp 7b - - out _SFR_IO_ADDR(SREG), r0 ;End of critical section - ret -.endfunc diff --git a/keyboard/hhkb_rn42/suart.h b/keyboard/hhkb_rn42/suart.h deleted file mode 100644 index 72725b9..0000000 --- a/keyboard/hhkb_rn42/suart.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef SUART -#define SUART - -void xmit(uint8_t); -uint8_t rcvr(void); -uint8_t recv(void); - -#endif /* SUART */ diff --git a/rules.mk b/rules.mk index 7a40d1d..83c9da5 100644 --- a/rules.mk +++ b/rules.mk @@ -565,6 +565,7 @@ $(OBJDIR)/%.o : %.cpp # Assemble: create object files from assembler source files. $(OBJDIR)/%.o : %.S @echo + mkdir -p $(@D) @echo $(MSG_ASSEMBLING) $< $(CC) -c $(ALL_ASFLAGS) $< -o $@