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,41 +5,47 @@
#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("PgUp: LED all On\n");
print("Right: Click Off\n"); print("PgDown: LED all On\n");
print("PgUp: LED all On\n"); print("Insert: Layout\n");
print("PgDown: LED all On\n"); print("Delete: Reset\n");
print("Insert: Layout\n");
print("Delete: Reset\n");
return false; return false;
case KC_DEL: case KC_DEL:
print("Reset\n"); print("Reset\n");
serial_send(0x01); serial_send(0x01);
break; break;
case KC_UP: case KC_HOME:
print("Bell On\n"); sun_bell = !sun_bell;
serial_send(0x02); if (sun_bell) {
break; print("Bell On\n");
case KC_DOWN: serial_send(0x02);
print("Bell Off\n"); } else {
serial_send(0x03); print("Bell Off\n");
break; serial_send(0x03);
case KC_LEFT: }
print("Click On\n");
serial_send(0x0A);
break;
case KC_RIGHT:
print("Click Off\n");
serial_send(0x0B);
break; break;
case KC_END:
sun_click = !sun_click;
if (sun_click) {
print("Click On\n");
serial_send(0x0A);
} else {
print("Click Off\n");
serial_send(0x0B);
}
break;
case KC_PGUP: case KC_PGUP:
print("LED all on\n"); print("LED all on\n");
serial_send(0x0E); serial_send(0x0E);
@ -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
/* Serial(USART) configuration * in front of RX/TX to produce the positive logic the MCU expects.
* asynchronous, negative logic, 1200baud, no flow control * The default is Software Serial.
* 1-start bit, 8-data bit, non parity, 1-stop bit
*/ */
#define SERIAL_SOFT_BAUD 1200 #if defined(HARDWARE_SERIAL)
#define SERIAL_SOFT_PARITY_NONE
#define SERIAL_SOFT_BIT_ORDER_LSB
#define SERIAL_SOFT_LOGIC_NEGATIVE
/* RXD Port */
#define SERIAL_SOFT_RXD_ENABLE
#define SERIAL_SOFT_RXD_DDR DDRD
#define SERIAL_SOFT_RXD_PORT PORTD
#define SERIAL_SOFT_RXD_PIN PIND
#define SERIAL_SOFT_RXD_BIT 2
#define SERIAL_SOFT_RXD_VECT INT2_vect
/* RXD Interupt */
#ifdef SERIAL_SOFT_LOGIC_NEGATIVE
/* enable interrupt: INT2(rising edge) */
#define INTR_TRIG_EDGE ((1<<ISC21)|(1<<ISC20))
#else
/* enable interrupt: INT2(falling edge) */
#define INTR_TRIG_EDGE ((1<<ISC21)|(0<<ISC20))
#endif
#define SERIAL_SOFT_RXD_INIT() do { \
/* pin configuration: input with pull-up */ \
SERIAL_SOFT_RXD_DDR &= ~(1<<SERIAL_SOFT_RXD_BIT); \
SERIAL_SOFT_RXD_PORT |= (1<<SERIAL_SOFT_RXD_BIT); \
EICRA |= INTR_TRIG_EDGE; \
EIMSK |= (1<<INT2); \
sei(); \
} while (0)
#define SERIAL_SOFT_RXD_INT_ENTER()
#define SERIAL_SOFT_RXD_INT_EXIT() do { \
/* clear interrupt flag */ \
EIFR = (1<<INTF2); \
} while (0)
#define SERIAL_SOFT_RXD_READ() (SERIAL_SOFT_RXD_PIN&(1<<SERIAL_SOFT_RXD_BIT))
/* TXD Port */
#define SERIAL_SOFT_TXD_ENABLE
#define SERIAL_SOFT_TXD_DDR DDRD
#define SERIAL_SOFT_TXD_PORT PORTD
#define SERIAL_SOFT_TXD_PIN PIND
#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_LO() do { SERIAL_SOFT_TXD_PORT &= ~(1<<SERIAL_SOFT_TXD_BIT); } while (0)
#define SERIAL_SOFT_TXD_INIT() do { \
/* pin configuration: output */ \
SERIAL_SOFT_TXD_DDR |= (1<<SERIAL_SOFT_TXD_BIT); \
/* idle */ \
SERIAL_SOFT_TXD_ON(); \
} while (0)
#endif /* 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
* 1-start bit, 8-data bit, non parity, 1-stop bit
*/
#define SERIAL_SOFT_BAUD 1200
#define SERIAL_SOFT_PARITY_NONE
#define SERIAL_SOFT_BIT_ORDER_LSB
#define SERIAL_SOFT_LOGIC_NEGATIVE
/* RXD Port */
#define SERIAL_SOFT_RXD_ENABLE
#define SERIAL_SOFT_RXD_DDR DDRD
#define SERIAL_SOFT_RXD_PORT PORTD
#define SERIAL_SOFT_RXD_PIN PIND
#define SERIAL_SOFT_RXD_BIT 2
#define SERIAL_SOFT_RXD_VECT INT2_vect
/* RXD Interupt */
#ifdef SERIAL_SOFT_LOGIC_NEGATIVE
/* enable interrupt: INT2(rising edge) */
#define INTR_TRIG_EDGE ((1<<ISC21)|(1<<ISC20))
#else
/* enable interrupt: INT2(falling edge) */
#define INTR_TRIG_EDGE ((1<<ISC21)|(0<<ISC20))
#endif
#define SERIAL_SOFT_RXD_INIT() do { \
/* pin configuration: input with pull-up */ \
SERIAL_SOFT_RXD_DDR &= ~(1<<SERIAL_SOFT_RXD_BIT); \
SERIAL_SOFT_RXD_PORT |= (1<<SERIAL_SOFT_RXD_BIT); \
EICRA |= INTR_TRIG_EDGE; \
EIMSK |= (1<<INT2); \
sei(); \
} while (0)
#define SERIAL_SOFT_RXD_INT_ENTER()
#define SERIAL_SOFT_RXD_INT_EXIT() do { \
/* clear interrupt flag */ \
EIFR = (1<<INTF2); \
} while (0)
#define SERIAL_SOFT_RXD_READ() (SERIAL_SOFT_RXD_PIN&(1<<SERIAL_SOFT_RXD_BIT))
/* TXD Port */
#define SERIAL_SOFT_TXD_ENABLE
#define SERIAL_SOFT_TXD_DDR DDRD
#define SERIAL_SOFT_TXD_PORT PORTD
#define SERIAL_SOFT_TXD_PIN PIND
#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_LO() do { SERIAL_SOFT_TXD_PORT &= ~(1<<SERIAL_SOFT_TXD_BIT); } while (0)
#define SERIAL_SOFT_TXD_INIT() do { \
/* pin configuration: output */ \
SERIAL_SOFT_TXD_DDR |= (1<<SERIAL_SOFT_TXD_BIT); \
/* idle */ \
SERIAL_SOFT_TXD_ON(); \
} while (0)
#endif //hardware serial
#endif //config.h