From 59ea5e02f76a37e5021c5f9d02af149e48e7c07c Mon Sep 17 00:00:00 2001 From: tmk Date: Sat, 19 Jul 2014 02:33:23 +0900 Subject: Mkdir rn42 --- keyboard/hhkb_rn42/rn42/main.c | 102 +++++++++++++++ keyboard/hhkb_rn42/rn42/rn42.c | 192 +++++++++++++++++++++++++++ keyboard/hhkb_rn42/rn42/rn42.h | 18 +++ keyboard/hhkb_rn42/rn42/rn42_task.c | 255 ++++++++++++++++++++++++++++++++++++ keyboard/hhkb_rn42/rn42/rn42_task.h | 10 ++ keyboard/hhkb_rn42/rn42/suart.S | 156 ++++++++++++++++++++++ keyboard/hhkb_rn42/rn42/suart.h | 8 ++ 7 files changed, 741 insertions(+) create mode 100644 keyboard/hhkb_rn42/rn42/main.c create mode 100644 keyboard/hhkb_rn42/rn42/rn42.c create mode 100644 keyboard/hhkb_rn42/rn42/rn42.h create mode 100644 keyboard/hhkb_rn42/rn42/rn42_task.c create mode 100644 keyboard/hhkb_rn42/rn42/rn42_task.h create mode 100644 keyboard/hhkb_rn42/rn42/suart.S create mode 100644 keyboard/hhkb_rn42/rn42/suart.h (limited to 'keyboard/hhkb_rn42/rn42') diff --git a/keyboard/hhkb_rn42/rn42/main.c b/keyboard/hhkb_rn42/rn42/main.c new file mode 100644 index 0000000000..a3a37c0747 --- /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 0000000000..3fcd64ad6a --- /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 0000000000..4189733b49 --- /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 0000000000..7ec4c1b540 --- /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 0000000000..8f6c3ab64d --- /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 0000000000..9fa5452928 --- /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 0000000000..72725b998f --- /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 */ -- cgit v1.2.3 From 3e7875455ed392ce5238efa0734e82995e1f8040 Mon Sep 17 00:00:00 2001 From: tmk Date: Sun, 20 Jul 2014 14:42:44 +0900 Subject: Add flow control by firmware to serial_uart --- keyboard/hhkb_rn42/rn42/rn42_task.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'keyboard/hhkb_rn42/rn42') diff --git a/keyboard/hhkb_rn42/rn42/rn42_task.c b/keyboard/hhkb_rn42/rn42/rn42_task.c index 7ec4c1b540..2bc1c7fd04 100644 --- a/keyboard/hhkb_rn42/rn42/rn42_task.c +++ b/keyboard/hhkb_rn42/rn42/rn42_task.c @@ -56,9 +56,7 @@ void rn42_task(void) // Config mode: print output from RN-42 while ((c = serial_recv2()) != -1) { // without flow control it'll fail to receive data when flooded - rn42_cts_hi(); xprintf("%c", c); - rn42_cts_lo(); } } else { // Raw mode: interpret output report of LED state -- cgit v1.2.3 From 4b2b32a14b805a363c5dc035a2d1384e60865ad3 Mon Sep 17 00:00:00 2001 From: tmk Date: Wed, 23 Jul 2014 12:23:00 +0900 Subject: Add rn42_lined(): connection status(GPIO2) --- keyboard/hhkb_rn42/rn42/rn42.c | 5 +++++ keyboard/hhkb_rn42/rn42/rn42.h | 1 + keyboard/hhkb_rn42/rn42/rn42_task.c | 2 ++ 3 files changed, 8 insertions(+) (limited to 'keyboard/hhkb_rn42/rn42') diff --git a/keyboard/hhkb_rn42/rn42/rn42.c b/keyboard/hhkb_rn42/rn42/rn42.c index 3fcd64ad6a..e7d8ba45cc 100644 --- a/keyboard/hhkb_rn42/rn42/rn42.c +++ b/keyboard/hhkb_rn42/rn42/rn42.c @@ -86,6 +86,11 @@ void rn42_cts_lo(void) PORTD &= ~(1<<5); } +bool rn42_linked(void) +{ + return PINF&(1<<6); +} + static uint8_t keyboard_leds(void) { return 0; } diff --git a/keyboard/hhkb_rn42/rn42/rn42.h b/keyboard/hhkb_rn42/rn42/rn42.h index 4189733b49..72cbb2d724 100644 --- a/keyboard/hhkb_rn42/rn42/rn42.h +++ b/keyboard/hhkb_rn42/rn42/rn42.h @@ -14,5 +14,6 @@ void rn42_disconnect(void); bool rn42_rts(void); void rn42_cts_hi(void); void rn42_cts_lo(void); +bool rn42_linked(void); #endif diff --git a/keyboard/hhkb_rn42/rn42/rn42_task.c b/keyboard/hhkb_rn42/rn42/rn42_task.c index 2bc1c7fd04..437dd46f49 100644 --- a/keyboard/hhkb_rn42/rn42/rn42_task.c +++ b/keyboard/hhkb_rn42/rn42/rn42_task.c @@ -162,8 +162,10 @@ bool command_extra(uint8_t code) 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_linked(): %X\n", rn42_linked()); xprintf("rn42_rts(): %X\n", rn42_rts()); xprintf("config_mode: %X\n", config_mode); + xprintf("VBUS: %X\n", USBSTA&(1< Date: Mon, 28 Jul 2014 11:56:02 +0900 Subject: Add battery monitor and LED control --- keyboard/hhkb_rn42/rn42/rn42_task.c | 46 ++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) (limited to 'keyboard/hhkb_rn42/rn42') diff --git a/keyboard/hhkb_rn42/rn42/rn42_task.c b/keyboard/hhkb_rn42/rn42/rn42_task.c index 437dd46f49..fd5a814b29 100644 --- a/keyboard/hhkb_rn42/rn42/rn42_task.c +++ b/keyboard/hhkb_rn42/rn42/rn42_task.c @@ -13,6 +13,17 @@ static bool config_mode = false; static bool force_usb = false; +static void status_led(bool on) +{ + if (on) { + DDRE |= (1<<6); + PORTE &= ~(1<<6); + } else { + DDRE |= (1<<6); + PORTE |= (1<<6); + } +} + static void battery_adc_init(void) { ADMUX = (1< Date: Mon, 28 Jul 2014 15:12:00 +0900 Subject: Add initial setting of Linked pin --- keyboard/hhkb_rn42/rn42/rn42.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'keyboard/hhkb_rn42/rn42') diff --git a/keyboard/hhkb_rn42/rn42/rn42.c b/keyboard/hhkb_rn42/rn42/rn42.c index e7d8ba45cc..556c61af95 100644 --- a/keyboard/hhkb_rn42/rn42/rn42.c +++ b/keyboard/hhkb_rn42/rn42/rn42.c @@ -25,12 +25,17 @@ host_driver_t rn42_driver = { 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< Date: Mon, 28 Jul 2014 15:52:07 +0900 Subject: Add connection indicator --- keyboard/hhkb_rn42/rn42/rn42_task.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'keyboard/hhkb_rn42/rn42') diff --git a/keyboard/hhkb_rn42/rn42/rn42_task.c b/keyboard/hhkb_rn42/rn42/rn42_task.c index fd5a814b29..2813b1c5ff 100644 --- a/keyboard/hhkb_rn42/rn42/rn42_task.c +++ b/keyboard/hhkb_rn42/rn42/rn42_task.c @@ -58,10 +58,10 @@ static void battery_led(bool on) { if (on) { DDRF |= (1<<5); - PORTF &= ~(1<<5); + PORTF &= ~(1<<5); // Low } else { DDRF &= ~(1<<5); - PORTF |= (1<<5); + PORTF &= ~(1<<5); // HiZ } } @@ -80,9 +80,9 @@ void rn42_task_init(void) { battery_adc_init(); - // battery charging(input with pull-up) + // battery charging(HiZ) DDRF &= ~(1<<5); - PORTF |= (1<<5); + PORTF &= ~(1<<5); } void rn42_task(void) @@ -135,6 +135,15 @@ void rn42_task(void) host_set_driver(&lufa_driver); } } + + /* Battery monitor */ + + /* Connection monitor */ + if (rn42_linked()) { + status_led(true); + } else { + status_led(false); + } } -- cgit v1.2.3 From 807ed33a9a29ee3c5248226d0e865d0580d7eebc Mon Sep 17 00:00:00 2001 From: tmk Date: Sat, 30 Aug 2014 15:59:41 +0900 Subject: Fix rn42_linked() to use pullup --- keyboard/hhkb_rn42/rn42/rn42.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'keyboard/hhkb_rn42/rn42') diff --git a/keyboard/hhkb_rn42/rn42/rn42.c b/keyboard/hhkb_rn42/rn42/rn42.c index 556c61af95..bdffad7667 100644 --- a/keyboard/hhkb_rn42/rn42/rn42.c +++ b/keyboard/hhkb_rn42/rn42/rn42.c @@ -34,7 +34,7 @@ void rn42_init(void) // PF6: linked(input without pull-up) DDRF &= ~(1<<6); - PORTF &= ~(1<<6); + PORTF |= (1<<6); // PF1: RTS(low: allowed to send, high: not allowed) DDRF &= ~(1<<1); @@ -93,7 +93,11 @@ void rn42_cts_lo(void) bool rn42_linked(void) { - return PINF&(1<<6); + // RN-42 GPIO2 + // Hi-Z: Not powered + // High: Linked + // Low: Connecting + return !rn42_rts() && PINF&(1<<6); } -- cgit v1.2.3 From 02939ab1d831ab7bb02edb28cb0b21fb61bced56 Mon Sep 17 00:00:00 2001 From: tmk Date: Thu, 4 Sep 2014 05:30:00 +0900 Subject: Add battery management --- keyboard/hhkb_rn42/rn42/battery.c | 119 ++++++++++++++++++++++++++++++++++++ keyboard/hhkb_rn42/rn42/battery.h | 34 +++++++++++ keyboard/hhkb_rn42/rn42/rn42_task.c | 71 ++++----------------- 3 files changed, 164 insertions(+), 60 deletions(-) create mode 100644 keyboard/hhkb_rn42/rn42/battery.c create mode 100644 keyboard/hhkb_rn42/rn42/battery.h (limited to 'keyboard/hhkb_rn42/rn42') diff --git a/keyboard/hhkb_rn42/rn42/battery.c b/keyboard/hhkb_rn42/rn42/battery.c new file mode 100644 index 0000000000..32de864481 --- /dev/null +++ b/keyboard/hhkb_rn42/rn42/battery.c @@ -0,0 +1,119 @@ +#include +#include +#include "battery.h" + + +/* + * Battery + */ +void battery_init(void) +{ + // blink + battery_led(LED_ON); _delay_ms(500); + battery_led(LED_OFF); _delay_ms(500); + battery_led(LED_ON); _delay_ms(500); + battery_led(LED_OFF); _delay_ms(500); + // LED indicates charger status + battery_led(LED_CHARGER); + + // ADC setting for voltage monitor + // Ref:2.56V band-gap, Input:ADC0(PF0), Prescale:128(16MHz/128=125KHz) + ADMUX = (1< BATTERY_VOLTAGE_LOW_RECOVERY) { + low = false; + } + return low; +} + +battery_status_t battery_status(void) +{ + if (USBSTA&(1< +#include + +typedef enum { + FULL_CHARGED, + CHARGING, + DISCHARGING, + LOW_VOLTAGE, +} battery_status_t; + +typedef enum { + LED_CHARGER = 0, + LED_ON, + LED_OFF, + LED_TOGGLE, +} battery_led_t; + +/* Battery API */ +void battery_init(void); +void battery_led(battery_led_t val); +bool battery_charging(void); +uint16_t battery_voltage(void); +battery_status_t battery_status(void); + +#define BATTERY_VOLTAGE_LOW_LIMIT 3500 +#define BATTERY_VOLTAGE_LOW_RECOVERY 3700 +// ADC offset:16, resolution:5mV +#define BATTERY_ADC_OFFSET 16 +#define BATTERY_ADC_RESOLUTION 5 + +#endif diff --git a/keyboard/hhkb_rn42/rn42/rn42_task.c b/keyboard/hhkb_rn42/rn42/rn42_task.c index 2813b1c5ff..07b34e111a 100644 --- a/keyboard/hhkb_rn42/rn42/rn42_task.c +++ b/keyboard/hhkb_rn42/rn42/rn42_task.c @@ -9,6 +9,7 @@ #include "print.h" #include "timer.h" #include "command.h" +#include "battery.h" static bool config_mode = false; static bool force_usb = false; @@ -24,65 +25,9 @@ static void status_led(bool on) } } -static void battery_adc_init(void) -{ - ADMUX = (1< Date: Thu, 4 Sep 2014 17:08:23 +0900 Subject: Monitor battery and alert low voltage --- keyboard/hhkb_rn42/rn42/battery.c | 13 ++++++---- keyboard/hhkb_rn42/rn42/battery.h | 1 + keyboard/hhkb_rn42/rn42/rn42_task.c | 47 +++++++++++++++++++++++++++++++++---- 3 files changed, 52 insertions(+), 9 deletions(-) (limited to 'keyboard/hhkb_rn42/rn42') diff --git a/keyboard/hhkb_rn42/rn42/battery.c b/keyboard/hhkb_rn42/rn42/battery.c index 32de864481..c6988fe336 100644 --- a/keyboard/hhkb_rn42/rn42/battery.c +++ b/keyboard/hhkb_rn42/rn42/battery.c @@ -49,10 +49,11 @@ bool battery_charging(void) { if (!(USBSTA&(1< 1000) { + /* every second */ + prev_timer = timer_read(); + + /* Low voltage alert */ + uint8_t bs = battery_status(); + if (bs == LOW_VOLTAGE) { + battery_led(LED_ON); + } else { + battery_led(LED_CHARGER); + } + + static uint8_t prev_status = UNKNOWN; + if (bs != prev_status) { + prev_status = bs; + switch (bs) { + case FULL_CHARGED: xprintf("FULL_CHARGED\n"); break; + case CHARGING: xprintf("CHARGING\n"); break; + case DISCHARGING: xprintf("DISCHARGING\n"); break; + case LOW_VOLTAGE: xprintf("LOW_VOLTAGE\n"); break; + default: xprintf("UNKNOWN STATUS\n"); break; + }; + } + + /* every minute */ + if (sec == 0) { + uint32_t t = timer_read32()/1000; + uint16_t v = battery_voltage(); + uint8_t h = t/3600; + uint8_t m = t%3600/60; + uint8_t s = t%60; + xprintf("%02u:%02u:%02u\t%umV\n", h, m, s, v); + /* TODO: xprintf doesn't work for this. + xprintf("%02u:%02u:%02u\t%umV\n", (t/3600), (t%3600/60), (t%60), v); + */ + } + sec++; sec = sec%60; } + /* Connection monitor */ if (rn42_linked()) { status_led(true); -- cgit v1.2.3 From d8dd18b4217ce56ee3248e3b09598196e0b6731c Mon Sep 17 00:00:00 2001 From: tmk Date: Fri, 5 Sep 2014 11:37:05 +0900 Subject: Improve rn42_task time resolution --- keyboard/hhkb_rn42/rn42/rn42_task.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'keyboard/hhkb_rn42/rn42') diff --git a/keyboard/hhkb_rn42/rn42/rn42_task.c b/keyboard/hhkb_rn42/rn42/rn42_task.c index 30914452e5..31a415cedf 100644 --- a/keyboard/hhkb_rn42/rn42/rn42_task.c +++ b/keyboard/hhkb_rn42/rn42/rn42_task.c @@ -83,11 +83,10 @@ void rn42_task(void) static uint16_t prev_timer = 0; - static uint8_t sec = 0; - // NOTE: not exact 1 sec - if (timer_elapsed(prev_timer) > 1000) { + uint16_t e = timer_elapsed(prev_timer); + if (e > 1000) { /* every second */ - prev_timer = timer_read(); + prev_timer += e/1000*1000; /* Low voltage alert */ uint8_t bs = battery_status(); @@ -110,8 +109,8 @@ void rn42_task(void) } /* every minute */ - if (sec == 0) { - uint32_t t = timer_read32()/1000; + uint32_t t = timer_read32()/1000; + if (t%60 == 0) { uint16_t v = battery_voltage(); uint8_t h = t/3600; uint8_t m = t%3600/60; @@ -121,7 +120,6 @@ void rn42_task(void) xprintf("%02u:%02u:%02u\t%umV\n", (t/3600), (t%3600/60), (t%60), v); */ } - sec++; sec = sec%60; } -- cgit v1.2.3 From 2015027da325e9f9b602af1f36ceeeebbcd6c78d Mon Sep 17 00:00:00 2001 From: tmk Date: Sat, 20 Sep 2014 06:12:49 +0900 Subject: Add FET swtich for battery ADC --- keyboard/hhkb_rn42/rn42/battery.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'keyboard/hhkb_rn42/rn42') diff --git a/keyboard/hhkb_rn42/rn42/battery.c b/keyboard/hhkb_rn42/rn42/battery.c index c6988fe336..0320e1baf1 100644 --- a/keyboard/hhkb_rn42/rn42/battery.c +++ b/keyboard/hhkb_rn42/rn42/battery.c @@ -21,6 +21,10 @@ void battery_init(void) ADMUX = (1< Date: Mon, 22 Sep 2014 14:20:49 +0900 Subject: Add keyboard LED control via Bluetooth --- keyboard/hhkb_rn42/rn42/rn42.c | 6 ++++-- keyboard/hhkb_rn42/rn42/rn42.h | 1 + keyboard/hhkb_rn42/rn42/rn42_task.c | 6 +++--- 3 files changed, 8 insertions(+), 5 deletions(-) (limited to 'keyboard/hhkb_rn42/rn42') diff --git a/keyboard/hhkb_rn42/rn42/rn42.c b/keyboard/hhkb_rn42/rn42/rn42.c index bdffad7667..1565b4cf14 100644 --- a/keyboard/hhkb_rn42/rn42/rn42.c +++ b/keyboard/hhkb_rn42/rn42/rn42.c @@ -101,7 +101,9 @@ bool rn42_linked(void) } -static uint8_t keyboard_leds(void) { return 0; } +static uint8_t leds = 0; +static uint8_t keyboard_leds(void) { return leds; } +void rn42_set_leds(uint8_t l) { leds = l; } static void send_keyboard(report_keyboard_t *report) { @@ -199,7 +201,7 @@ host_driver_t rn42_config_driver = { config_send_consumer }; -static uint8_t config_keyboard_leds(void) { return 0; } +static uint8_t config_keyboard_leds(void) { return leds; } 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) {} diff --git a/keyboard/hhkb_rn42/rn42/rn42.h b/keyboard/hhkb_rn42/rn42/rn42.h index 72cbb2d724..5283a3648c 100644 --- a/keyboard/hhkb_rn42/rn42/rn42.h +++ b/keyboard/hhkb_rn42/rn42/rn42.h @@ -15,5 +15,6 @@ bool rn42_rts(void); void rn42_cts_hi(void); void rn42_cts_lo(void); bool rn42_linked(void); +void rn42_set_leds(uint8_t l); #endif diff --git a/keyboard/hhkb_rn42/rn42/rn42_task.c b/keyboard/hhkb_rn42/rn42/rn42_task.c index 31a415cedf..c3359ed506 100644 --- a/keyboard/hhkb_rn42/rn42/rn42_task.c +++ b/keyboard/hhkb_rn42/rn42/rn42_task.c @@ -7,6 +7,7 @@ #include "lufa.h" #include "rn42_task.h" #include "print.h" +#include "debug.h" #include "timer.h" #include "command.h" #include "battery.h" @@ -45,7 +46,6 @@ void rn42_task(void) // LED Out report: 0xFE, 0x02, 0x01, // 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; @@ -60,8 +60,8 @@ void rn42_task(void) 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); + dprintf("LED status: %02X\n", c); + rn42_set_leds(c); state = LED_INIT; break; default: -- cgit v1.2.3 From 608ebe2686bdb3fdbd0426731cabdf6082c57b53 Mon Sep 17 00:00:00 2001 From: tmk Date: Sun, 23 Nov 2014 13:08:05 +0900 Subject: Matrix power saving --- keyboard/hhkb_rn42/rn42/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'keyboard/hhkb_rn42/rn42') diff --git a/keyboard/hhkb_rn42/rn42/main.c b/keyboard/hhkb_rn42/rn42/main.c index a3a37c0747..43d887067d 100644 --- a/keyboard/hhkb_rn42/rn42/main.c +++ b/keyboard/hhkb_rn42/rn42/main.c @@ -85,7 +85,7 @@ int main(void) print("Keyboard start.\n"); while (1) { while (USB_DeviceState == DEVICE_STATE_Suspended) { - suspend_power_down(); + suspend_power_down(WDTO_120MS); if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) { USB_Device_SendRemoteWakeup(); } -- cgit v1.2.3