1
0

Merge pull request #347 from omenlabs/master

Add hardware serial support for sun_usb converter
This commit is contained in:
tmk 2016-05-16 15:10:11 +09:00
commit 75854878cc
4 changed files with 125 additions and 78 deletions

View File

@ -11,8 +11,8 @@ TARGET_DIR = .
SRC = keymap.c \ SRC = keymap.c \
matrix.c \ matrix.c \
led.c \ led.c \
command_extra.c \ command_extra.c
protocol/serial_soft.c
CONFIG_H = config.h CONFIG_H = config.h
@ -64,8 +64,15 @@ MOUSEKEY_ENABLE = yes # Mouse keys
EXTRAKEY_ENABLE = yes # Audio control and System control EXTRAKEY_ENABLE = yes # Audio control and System control
CONSOLE_ENABLE = yes # Console for debug CONSOLE_ENABLE = yes # Console for debug
COMMAND_ENABLE = yes # Commands for debug and configuration COMMAND_ENABLE = yes # Commands for debug and configuration
#HARDWARE_SERIAL = yes # Use hardware serial (requires inverted serial, see README)
#NKRO_ENABLE = yes # USB Nkey Rollover #NKRO_ENABLE = yes # USB Nkey Rollover
ifdef HARDWARE_SERIAL
SRC := protocol/serial_uart.c $(SRC)
OPT_DEFS += -DHARDWARE_SERIAL
else
SRC := protocol/serial_soft.c $(SRC)
endif
# Boot Section Size in bytes # Boot Section Size in bytes
# Teensy halfKay 512 # Teensy halfKay 512

View File

@ -48,7 +48,9 @@ Frame format: 1-Start bit, 8-Data bits, No-Parity, 1-Stop bit
To use AVR UART engine you need external inverter in front of RX and TX pin. To use AVR UART engine you need external inverter in front of RX and TX pin.
Otherwise you can software serial routine to communicate the keyboard. Otherwise you can software serial routine to communicate the keyboard.
This converter uses software method, you doesn't need any inverter part. This converter uses software method by default, so you don't need any inverter part. But
it can also be built with 'make HARDWARE_SERIAL=y' to enable hardware serial if there
is an inverter present. Good results have been obtained using a 74LS04 and hardware serial.
Commands From System To Keyboard Commands From System To Keyboard

View File

@ -5,16 +5,18 @@
#include "print.h" #include "print.h"
#include "command.h" #include "command.h"
bool sun_bell = false;
bool sun_click = false;
bool command_extra(uint8_t code) bool command_extra(uint8_t code)
{ {
switch (code) { switch (code) {
case KC_H: case KC_H:
case KC_SLASH: /* ? */ case KC_SLASH: /* ? */
print("\n\n----- Sun converter Help -----\n"); print("\n\n----- Sun converter Help -----\n");
print("Up: Bell On\n"); print("Home: Toggle Bell\n");
print("Down: Bell Off\n"); print("End: Toggle Click\n");
print("Left: Click On\n");
print("Right: Click Off\n");
print("PgUp: LED all On\n"); print("PgUp: LED all On\n");
print("PgDown: LED all On\n"); print("PgDown: LED all On\n");
print("Insert: Layout\n"); print("Insert: Layout\n");
@ -24,21 +26,25 @@ bool command_extra(uint8_t code)
print("Reset\n"); print("Reset\n");
serial_send(0x01); serial_send(0x01);
break; break;
case KC_UP: case KC_HOME:
sun_bell = !sun_bell;
if (sun_bell) {
print("Bell On\n"); print("Bell On\n");
serial_send(0x02); serial_send(0x02);
break; } else {
case KC_DOWN:
print("Bell Off\n"); print("Bell Off\n");
serial_send(0x03); serial_send(0x03);
}
break; break;
case KC_LEFT: case KC_END:
sun_click = !sun_click;
if (sun_click) {
print("Click On\n"); print("Click On\n");
serial_send(0x0A); serial_send(0x0A);
break; } else {
case KC_RIGHT:
print("Click Off\n"); print("Click Off\n");
serial_send(0x0B); serial_send(0x0B);
}
break; break;
case KC_PGUP: case KC_PGUP:
print("LED all on\n"); print("LED all on\n");
@ -55,6 +61,7 @@ bool command_extra(uint8_t code)
serial_send(0x0F); serial_send(0x0F);
break; break;
default: default:
xprintf("Unknown extra command: %02X\n", code);
return false; return false;
} }
return true; return true;

View File

@ -39,57 +39,88 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/* legacy keymap support */ /* legacy keymap support */
#define USE_LEGACY_KEYMAP #define USE_LEGACY_KEYMAP
/* HARDWARE_SERAIL assumes that a logic inverter (7404) is placed
* in front of RX/TX to produce the positive logic the MCU expects.
* The default is Software Serial.
*/
#if defined(HARDWARE_SERIAL)
/* Serial(USART) configuration /* Hardware Serial (USART) configuration
* asynchronous, negative logic, 1200baud, no flow control
* 1-start bit, 8-data bit, non parity, 1-stop bit
*
*/
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega32U2__)
#define SERIAL_UART_BAUD 1200
#define SERIAL_UART_DATA UDR1
#define SERIAL_UART_UBRR ((F_CPU/(16UL*SERIAL_UART_BAUD))-1)
#define SERIAL_UART_RXD_VECT USART1_RX_vect
#define SERIAL_UART_TXD_READY (UCSR1A&(1<<UDRE1))
#define SERIAL_UART_INIT() do { \
UBRR1L = (uint8_t) SERIAL_UART_UBRR; /* baud rate */ \
UBRR1H = (uint8_t) (SERIAL_UART_UBRR>>8); /* baud rate */ \
UCSR1B = (1<<RXCIE1) | (1<<RXEN1) | /* RX: interrupt, RX: enable */ \
(1<<TXEN1); /* TX: enable */ \
UCSR1C = (0<<UPM11) | (0<<UPM10) | /* parity: none(00), even(01), odd(11) */ \
(0<<UCSZ12) | (1<<UCSZ11) | (1<<UCSZ10); /* data-8bit(011) */ \
sei(); \
} while(0)
#else
# error "USART configuration is needed."
#endif
#else
/* Software Serial configuration
* asynchronous, negative logic, 1200baud, no flow control * asynchronous, negative logic, 1200baud, no flow control
* 1-start bit, 8-data bit, non parity, 1-stop bit * 1-start bit, 8-data bit, non parity, 1-stop bit
*/ */
#define SERIAL_SOFT_BAUD 1200 #define SERIAL_SOFT_BAUD 1200
#define SERIAL_SOFT_PARITY_NONE #define SERIAL_SOFT_PARITY_NONE
#define SERIAL_SOFT_BIT_ORDER_LSB #define SERIAL_SOFT_BIT_ORDER_LSB
#define SERIAL_SOFT_LOGIC_NEGATIVE #define SERIAL_SOFT_LOGIC_NEGATIVE
/* RXD Port */ /* RXD Port */
#define SERIAL_SOFT_RXD_ENABLE #define SERIAL_SOFT_RXD_ENABLE
#define SERIAL_SOFT_RXD_DDR DDRD #define SERIAL_SOFT_RXD_DDR DDRD
#define SERIAL_SOFT_RXD_PORT PORTD #define SERIAL_SOFT_RXD_PORT PORTD
#define SERIAL_SOFT_RXD_PIN PIND #define SERIAL_SOFT_RXD_PIN PIND
#define SERIAL_SOFT_RXD_BIT 2 #define SERIAL_SOFT_RXD_BIT 2
#define SERIAL_SOFT_RXD_VECT INT2_vect #define SERIAL_SOFT_RXD_VECT INT2_vect
/* RXD Interupt */ /* RXD Interupt */
#ifdef SERIAL_SOFT_LOGIC_NEGATIVE #ifdef SERIAL_SOFT_LOGIC_NEGATIVE
/* enable interrupt: INT2(rising edge) */ /* enable interrupt: INT2(rising edge) */
#define INTR_TRIG_EDGE ((1<<ISC21)|(1<<ISC20)) #define INTR_TRIG_EDGE ((1<<ISC21)|(1<<ISC20))
#else #else
/* enable interrupt: INT2(falling edge) */ /* enable interrupt: INT2(falling edge) */
#define INTR_TRIG_EDGE ((1<<ISC21)|(0<<ISC20)) #define INTR_TRIG_EDGE ((1<<ISC21)|(0<<ISC20))
#endif #endif
#define SERIAL_SOFT_RXD_INIT() do { \ #define SERIAL_SOFT_RXD_INIT() do { \
/* pin configuration: input with pull-up */ \ /* pin configuration: input with pull-up */ \
SERIAL_SOFT_RXD_DDR &= ~(1<<SERIAL_SOFT_RXD_BIT); \ SERIAL_SOFT_RXD_DDR &= ~(1<<SERIAL_SOFT_RXD_BIT); \
SERIAL_SOFT_RXD_PORT |= (1<<SERIAL_SOFT_RXD_BIT); \ SERIAL_SOFT_RXD_PORT |= (1<<SERIAL_SOFT_RXD_BIT); \
EICRA |= INTR_TRIG_EDGE; \ EICRA |= INTR_TRIG_EDGE; \
EIMSK |= (1<<INT2); \ EIMSK |= (1<<INT2); \
sei(); \ sei(); \
} while (0) } while (0)
#define SERIAL_SOFT_RXD_INT_ENTER() #define SERIAL_SOFT_RXD_INT_ENTER()
#define SERIAL_SOFT_RXD_INT_EXIT() do { \ #define SERIAL_SOFT_RXD_INT_EXIT() do { \
/* clear interrupt flag */ \ /* clear interrupt flag */ \
EIFR = (1<<INTF2); \ EIFR = (1<<INTF2); \
} while (0) } while (0)
#define SERIAL_SOFT_RXD_READ() (SERIAL_SOFT_RXD_PIN&(1<<SERIAL_SOFT_RXD_BIT)) #define SERIAL_SOFT_RXD_READ() (SERIAL_SOFT_RXD_PIN&(1<<SERIAL_SOFT_RXD_BIT))
/* TXD Port */ /* TXD Port */
#define SERIAL_SOFT_TXD_ENABLE #define SERIAL_SOFT_TXD_ENABLE
#define SERIAL_SOFT_TXD_DDR DDRD #define SERIAL_SOFT_TXD_DDR DDRD
#define SERIAL_SOFT_TXD_PORT PORTD #define SERIAL_SOFT_TXD_PORT PORTD
#define SERIAL_SOFT_TXD_PIN PIND #define SERIAL_SOFT_TXD_PIN PIND
#define SERIAL_SOFT_TXD_BIT 3 #define SERIAL_SOFT_TXD_BIT 3
#define SERIAL_SOFT_TXD_HI() do { SERIAL_SOFT_TXD_PORT |= (1<<SERIAL_SOFT_TXD_BIT); } while (0) #define SERIAL_SOFT_TXD_HI() do { SERIAL_SOFT_TXD_PORT |= (1<<SERIAL_SOFT_TXD_BIT); } while (0)
#define SERIAL_SOFT_TXD_LO() do { SERIAL_SOFT_TXD_PORT &= ~(1<<SERIAL_SOFT_TXD_BIT); } while (0) #define SERIAL_SOFT_TXD_LO() do { SERIAL_SOFT_TXD_PORT &= ~(1<<SERIAL_SOFT_TXD_BIT); } while (0)
#define SERIAL_SOFT_TXD_INIT() do { \ #define SERIAL_SOFT_TXD_INIT() do { \
/* pin configuration: output */ \ /* pin configuration: output */ \
SERIAL_SOFT_TXD_DDR |= (1<<SERIAL_SOFT_TXD_BIT); \ SERIAL_SOFT_TXD_DDR |= (1<<SERIAL_SOFT_TXD_BIT); \
/* idle */ \ /* idle */ \
SERIAL_SOFT_TXD_ON(); \ SERIAL_SOFT_TXD_ON(); \
} while (0) } while (0)
#endif #endif //hardware serial
#endif //config.h