Add software UART and battery monitor
This commit is contained in:
		
							parent
							
								
									01fa462e2c
								
							
						
					
					
						commit
						862f519e24
					
				@ -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;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										156
									
								
								keyboard/hhkb_rn42/suart.S
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										156
									
								
								keyboard/hhkb_rn42/suart.S
									
									
									
									
									
										Normal file
									
								
							@ -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
 | 
			
		||||
							
								
								
									
										8
									
								
								keyboard/hhkb_rn42/suart.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								keyboard/hhkb_rn42/suart.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,8 @@
 | 
			
		||||
#ifndef SUART
 | 
			
		||||
#define SUART
 | 
			
		||||
 | 
			
		||||
void xmit(uint8_t);
 | 
			
		||||
uint8_t rcvr(void);
 | 
			
		||||
uint8_t recv(void);
 | 
			
		||||
 | 
			
		||||
#endif	/* SUART */
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user