From 862f519e241b83113566eebde71841958b2d00b7 Mon Sep 17 00:00:00 2001 From: tmk Date: Mon, 14 Jul 2014 15:20:10 +0900 Subject: [PATCH] Add software UART and battery monitor --- keyboard/hhkb_rn42/Makefile | 1 + keyboard/hhkb_rn42/config.h | 7 ++ keyboard/hhkb_rn42/main.c | 49 ++++++++++- keyboard/hhkb_rn42/rn42.c | 4 + keyboard/hhkb_rn42/rn42.h | 5 ++ keyboard/hhkb_rn42/suart.S | 156 ++++++++++++++++++++++++++++++++++++ keyboard/hhkb_rn42/suart.h | 8 ++ 7 files changed, 227 insertions(+), 3 deletions(-) create mode 100644 keyboard/hhkb_rn42/suart.S create mode 100644 keyboard/hhkb_rn42/suart.h diff --git a/keyboard/hhkb_rn42/Makefile b/keyboard/hhkb_rn42/Makefile index 8cfe3f1184..9e1acfa442 100644 --- a/keyboard/hhkb_rn42/Makefile +++ b/keyboard/hhkb_rn42/Makefile @@ -53,6 +53,7 @@ SRC += keymap_common.c \ matrix.c \ led.c \ serial_uart.c \ + suart.S \ rn42.c \ main.c diff --git a/keyboard/hhkb_rn42/config.h b/keyboard/hhkb_rn42/config.h index a0ab878eb8..5e6d7a6436 100644 --- a/keyboard/hhkb_rn42/config.h +++ b/keyboard/hhkb_rn42/config.h @@ -76,6 +76,13 @@ along with this program. If not, see . #endif +/* for debug */ +#define SUART_OUT_PORT PORTD +#define SUART_OUT_BIT 0 +#define SUART_IN_PIN PIND +#define SUART_IN_BIT 1 + + /* * Feature disable options * These options are also useful to firmware size reduction. diff --git a/keyboard/hhkb_rn42/main.c b/keyboard/hhkb_rn42/main.c index a2c217a2d3..0b455193fb 100644 --- a/keyboard/hhkb_rn42/main.c +++ b/keyboard/hhkb_rn42/main.c @@ -12,10 +12,16 @@ #include "action.h" #include "action_util.h" #include "wait.h" - +#include "suart.h" bool config_mode = false; +static int8_t sendchar_func(uint8_t c) +{ + sendchar(c); // LUFA + xmit(c); // SUART +} + static void SetupHardware(void) { /* Disable watchdog if enabled by bootloader/fuses */ @@ -32,7 +38,16 @@ static void SetupHardware(void) // for Console_Task USB_Device_EnableSOFEvents(); - print_set_sendchar(sendchar); + print_set_sendchar(sendchar_func); + + // SUART PD0:output, PD1:input + DDRD |= (1<<0); + PORTD |= (1<<0); + DDRD &= ~(1<<1); + PORTD |= (1<<1); + + // CTS control + CTS_INIT(); } static bool force_usb = false; @@ -70,6 +85,12 @@ int main(void) sleep_led_init(); #endif + // ADC for battery + //ADMUX = (1< @@ -146,6 +172,7 @@ bool command_extra(uint8_t code) print("a: Bluetooth auto connect\n"); print("del: Bluetooth disconnect\n"); print("i: info\n"); + print("b: battery voltage\n"); if (config_mode) { return true; @@ -208,6 +235,22 @@ bool command_extra(uint8_t code) xprintf("rn42_ready(): %X\n", rn42_ready()); xprintf("config_mode: %X\n", config_mode); return true; + case KC_B: + // battery monitor + ADCSRA |= (1< +// RN-42 CTS pin +#define CTS_INIT() (DDRD |= (1<<5)) +#define CTS_HI() (PORTD |= (1<<5)) +#define CTS_LO() (PORTD &= ~(1<<5)) + host_driver_t rn42_driver; host_driver_t rn42_config_driver; diff --git a/keyboard/hhkb_rn42/suart.S b/keyboard/hhkb_rn42/suart.S new file mode 100644 index 0000000000..9fa5452928 --- /dev/null +++ b/keyboard/hhkb_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/suart.h b/keyboard/hhkb_rn42/suart.h new file mode 100644 index 0000000000..72725b998f --- /dev/null +++ b/keyboard/hhkb_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 */