@@ -53,6 +53,7 @@ SRC += keymap_common.c \ | |||
matrix.c \ | |||
led.c \ | |||
serial_uart.c \ | |||
suart.S \ | |||
rn42.c \ | |||
main.c | |||
@@ -76,6 +76,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
#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. |
@@ -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<<REFS0); // Ref:AVCC, Input:ADC0(PF0) | |||
ADMUX = (1<<REFS1) | (1<<REFS0); // Ref:AVCC, Input:ADC0(PF0) | |||
ADCSRA = (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0); // Prescale:128 | |||
ADCSRA |= (1<<ADEN); // enable ADC | |||
print("Keyboard start.\n"); | |||
while (1) { | |||
/* | |||
@@ -89,7 +110,12 @@ int main(void) | |||
int16_t c; | |||
if (config_mode) { | |||
while ((c = serial_recv2()) != -1) xprintf("%c", c); | |||
while ((c = serial_recv2()) != -1) { | |||
// without flow control it'll fail to receive data when flooded | |||
CTS_HI(); | |||
xprintf("%c", c); | |||
CTS_LO(); | |||
} | |||
} else { | |||
while ((c = serial_recv2()) != -1) { | |||
// LED Out report: 0xFE, 0x02, 0x01, <leds> | |||
@@ -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<<ADEN) | (1<<ADSC); | |||
while (ADCSRA & (1<<ADSC)) ; | |||
uint16_t bat = ADCL; | |||
bat = ADCH<<8 | bat; | |||
xprintf("BAT: %04X\n", bat); | |||
ADCSRA |= (1<<ADEN) | (1<<ADSC); | |||
while (ADCSRA & (1<<ADSC)) ; | |||
bat = ADCL; | |||
bat = ADCH<<8 | bat; | |||
xprintf("BAT: %04X\n", bat); | |||
ADCSRA &= ~(1<<ADEN); | |||
return true; | |||
default: | |||
if (config_mode) | |||
return true; |
@@ -70,9 +70,11 @@ static uint8_t keyboard_leds(void) { return 0; } | |||
static void send_keyboard(report_keyboard_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(9); // length | |||
@@ -90,9 +92,11 @@ static void send_keyboard(report_keyboard_t *report) | |||
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 |
@@ -3,6 +3,11 @@ | |||
#include <stdbool.h> | |||
// 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; | |||
@@ -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 <avr/io.h> | |||
.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 |
@@ -0,0 +1,8 @@ | |||
#ifndef SUART | |||
#define SUART | |||
void xmit(uint8_t); | |||
uint8_t rcvr(void); | |||
uint8_t recv(void); | |||
#endif /* SUART */ |