diff options
Diffstat (limited to 'protocol')
| -rw-r--r-- | protocol/serial.h | 1 | ||||
| -rw-r--r-- | protocol/serial_soft.c | 119 | ||||
| -rw-r--r-- | protocol/serial_uart.c | 93 | ||||
| -rw-r--r-- | protocol/vusb/vusb.c | 4 |
4 files changed, 200 insertions, 17 deletions
diff --git a/protocol/serial.h b/protocol/serial.h index bd071bec9..96913c867 100644 --- a/protocol/serial.h +++ b/protocol/serial.h | |||
| @@ -41,6 +41,7 @@ POSSIBILITY OF SUCH DAMAGE. | |||
| 41 | /* host role */ | 41 | /* host role */ |
| 42 | void serial_init(void); | 42 | void serial_init(void); |
| 43 | uint8_t serial_recv(void); | 43 | uint8_t serial_recv(void); |
| 44 | int16_t serial_recv2(void); | ||
| 44 | void serial_send(uint8_t data); | 45 | void serial_send(uint8_t data); |
| 45 | 46 | ||
| 46 | #endif | 47 | #endif |
diff --git a/protocol/serial_soft.c b/protocol/serial_soft.c index beddc353c..e8870bcd7 100644 --- a/protocol/serial_soft.c +++ b/protocol/serial_soft.c | |||
| @@ -43,15 +43,47 @@ POSSIBILITY OF SUCH DAMAGE. | |||
| 43 | 43 | ||
| 44 | /* | 44 | /* |
| 45 | * Stupid Inefficient Busy-wait Software Serial | 45 | * Stupid Inefficient Busy-wait Software Serial |
| 46 | * is still useful for negative logic signal like Sun protocol not supported by hardware USART. | 46 | * which is still useful for negative logic signal like Sun protocol |
| 47 | * if it is not supported by hardware UART. | ||
| 48 | * | ||
| 49 | * TODO: delay is not accurate enough. Instruction cycle should be counted and inline assemby is needed. | ||
| 47 | */ | 50 | */ |
| 48 | 51 | ||
| 49 | #define WAIT_US (1000000/SERIAL_BAUD) | 52 | #define WAIT_US (1000000L/SERIAL_SOFT_BAUD) |
| 53 | |||
| 54 | #ifdef SERIAL_SOFT_LOGIC_NEGATIVE | ||
| 55 | #define SERIAL_SOFT_RXD_IN() !(SERIAL_SOFT_RXD_READ()) | ||
| 56 | #define SERIAL_SOFT_TXD_ON() SERIAL_SOFT_TXD_LO() | ||
| 57 | #define SERIAL_SOFT_TXD_OFF() SERIAL_SOFT_TXD_HI() | ||
| 58 | #else | ||
| 59 | #define SERIAL_SOFT_RXD_IN() !!(SERIAL_SOFT_RXD_READ()) | ||
| 60 | #define SERIAL_SOFT_TXD_ON() SERIAL_SOFT_TXD_HI() | ||
| 61 | #define SERIAL_SOFT_TXD_OFF() SERIAL_SOFT_TXD_LO() | ||
| 62 | #endif | ||
| 63 | |||
| 64 | #ifdef SERIAL_SOFT_PARITY_EVEN | ||
| 65 | #define SERIAL_SOFT_PARITY_VAL 0 | ||
| 66 | #elif defined(SERIAL_SOFT_PARITY_ODD) | ||
| 67 | #define SERIAL_SOFT_PARITY_VAL 1 | ||
| 68 | #endif | ||
| 69 | |||
| 70 | /* debug for signal timing, see debug pin with oscilloscope */ | ||
| 71 | #define SERIAL_SOFT_DEBUG | ||
| 72 | #ifdef SERIAL_SOFT_DEBUG | ||
| 73 | #define SERIAL_SOFT_DEBUG_INIT() (DDRD |= 1<<7) | ||
| 74 | #define SERIAL_SOFT_DEBUG_TGL() (PORTD ^= 1<<7) | ||
| 75 | #else | ||
| 76 | #define SERIAL_SOFT_DEBUG_INIT() | ||
| 77 | #define SERIAL_SOFT_DEBUG_TGL() | ||
| 78 | #endif | ||
| 79 | |||
| 50 | 80 | ||
| 51 | void serial_init(void) | 81 | void serial_init(void) |
| 52 | { | 82 | { |
| 53 | SERIAL_RXD_INIT(); | 83 | SERIAL_SOFT_DEBUG_INIT(); |
| 54 | SERIAL_TXD_INIT(); | 84 | |
| 85 | SERIAL_SOFT_RXD_INIT(); | ||
| 86 | SERIAL_SOFT_TXD_INIT(); | ||
| 55 | } | 87 | } |
| 56 | 88 | ||
| 57 | /* RX ring buffer */ | 89 | /* RX ring buffer */ |
| @@ -60,6 +92,7 @@ static uint8_t rbuf[RBUF_SIZE]; | |||
| 60 | static uint8_t rbuf_head = 0; | 92 | static uint8_t rbuf_head = 0; |
| 61 | static uint8_t rbuf_tail = 0; | 93 | static uint8_t rbuf_tail = 0; |
| 62 | 94 | ||
| 95 | |||
| 63 | uint8_t serial_recv(void) | 96 | uint8_t serial_recv(void) |
| 64 | { | 97 | { |
| 65 | uint8_t data = 0; | 98 | uint8_t data = 0; |
| @@ -72,68 +105,120 @@ uint8_t serial_recv(void) | |||
| 72 | return data; | 105 | return data; |
| 73 | } | 106 | } |
| 74 | 107 | ||
| 108 | int16_t serial_recv2(void) | ||
| 109 | { | ||
| 110 | uint8_t data = 0; | ||
| 111 | if (rbuf_head == rbuf_tail) { | ||
| 112 | return -1; | ||
| 113 | } | ||
| 114 | |||
| 115 | data = rbuf[rbuf_tail]; | ||
| 116 | rbuf_tail = (rbuf_tail + 1) % RBUF_SIZE; | ||
| 117 | return data; | ||
| 118 | } | ||
| 119 | |||
| 75 | void serial_send(uint8_t data) | 120 | void serial_send(uint8_t data) |
| 76 | { | 121 | { |
| 77 | /* signal state: IDLE: ON, START: OFF, STOP: ON, DATA0: OFF, DATA1: ON */ | 122 | /* signal state: IDLE: ON, START: OFF, STOP: ON, DATA0: OFF, DATA1: ON */ |
| 78 | /* start bit */ | ||
| 79 | SERIAL_TXD_OFF(); | ||
| 80 | _delay_us(WAIT_US); | ||
| 81 | 123 | ||
| 82 | #ifdef SERIAL_BIT_ORDER_MSB | 124 | #ifdef SERIAL_SOFT_BIT_ORDER_MSB |
| 83 | uint8_t mask = 0x80; | 125 | uint8_t mask = 0x80; |
| 84 | #else | 126 | #else |
| 85 | uint8_t mask = 0x01; | 127 | uint8_t mask = 0x01; |
| 86 | #endif | 128 | #endif |
| 129 | |||
| 130 | uint8_t parity = 0; | ||
| 131 | |||
| 132 | /* start bit */ | ||
| 133 | SERIAL_SOFT_TXD_OFF(); | ||
| 134 | _delay_us(WAIT_US); | ||
| 135 | |||
| 87 | while (mask) { | 136 | while (mask) { |
| 88 | if (data&mask) { SERIAL_TXD_ON(); } else { SERIAL_TXD_OFF(); } | 137 | if (data&mask) { |
| 138 | SERIAL_SOFT_TXD_ON(); | ||
| 139 | parity ^= 1; | ||
| 140 | } else { | ||
| 141 | SERIAL_SOFT_TXD_OFF(); | ||
| 142 | } | ||
| 89 | _delay_us(WAIT_US); | 143 | _delay_us(WAIT_US); |
| 90 | 144 | ||
| 91 | #ifdef SERIAL_BIT_ORDER_MSB | 145 | #ifdef SERIAL_SOFT_BIT_ORDER_MSB |
| 92 | mask >>= 1; | 146 | mask >>= 1; |
| 93 | #else | 147 | #else |
| 94 | mask <<= 1; | 148 | mask <<= 1; |
| 95 | #endif | 149 | #endif |
| 96 | } | 150 | } |
| 97 | 151 | ||
| 152 | #if defined(SERIAL_SOFT_PARITY_EVEN) || defined(SERIAL_SOFT_PARITY_ODD) | ||
| 153 | /* to center of parity bit */ | ||
| 154 | if (parity != SERIAL_SOFT_PARITY_VAL) { | ||
| 155 | SERIAL_SOFT_TXD_ON(); | ||
| 156 | } else { | ||
| 157 | SERIAL_SOFT_TXD_OFF(); | ||
| 158 | } | ||
| 159 | _delay_us(WAIT_US); | ||
| 160 | #endif | ||
| 161 | |||
| 98 | /* stop bit */ | 162 | /* stop bit */ |
| 99 | SERIAL_TXD_ON(); | 163 | SERIAL_SOFT_TXD_ON(); |
| 100 | _delay_us(WAIT_US); | 164 | _delay_us(WAIT_US); |
| 101 | } | 165 | } |
| 102 | 166 | ||
| 103 | /* detect edge of start bit */ | 167 | /* detect edge of start bit */ |
| 104 | ISR(SERIAL_RXD_VECT) | 168 | ISR(SERIAL_SOFT_RXD_VECT) |
| 105 | { | 169 | { |
| 106 | SERIAL_RXD_INT_ENTER() | 170 | SERIAL_SOFT_DEBUG_TGL(); |
| 171 | SERIAL_SOFT_RXD_INT_ENTER() | ||
| 107 | 172 | ||
| 108 | uint8_t data = 0; | 173 | uint8_t data = 0; |
| 109 | #ifdef SERIAL_BIT_ORDER_MSB | 174 | |
| 175 | #ifdef SERIAL_SOFT_BIT_ORDER_MSB | ||
| 110 | uint8_t mask = 0x80; | 176 | uint8_t mask = 0x80; |
| 111 | #else | 177 | #else |
| 112 | uint8_t mask = 0x01; | 178 | uint8_t mask = 0x01; |
| 113 | #endif | 179 | #endif |
| 180 | |||
| 181 | uint8_t parity = 0; | ||
| 182 | |||
| 114 | /* to center of start bit */ | 183 | /* to center of start bit */ |
| 115 | _delay_us(WAIT_US/2); | 184 | _delay_us(WAIT_US/2); |
| 185 | SERIAL_SOFT_DEBUG_TGL(); | ||
| 116 | do { | 186 | do { |
| 117 | /* to center of next bit */ | 187 | /* to center of next bit */ |
| 118 | _delay_us(WAIT_US); | 188 | _delay_us(WAIT_US); |
| 119 | 189 | ||
| 120 | if (SERIAL_RXD_READ()) { | 190 | SERIAL_SOFT_DEBUG_TGL(); |
| 191 | if (SERIAL_SOFT_RXD_IN()) { | ||
| 121 | data |= mask; | 192 | data |= mask; |
| 193 | parity ^= 1; | ||
| 122 | } | 194 | } |
| 123 | #ifdef SERIAL_BIT_ORDER_MSB | 195 | #ifdef SERIAL_SOFT_BIT_ORDER_MSB |
| 124 | mask >>= 1; | 196 | mask >>= 1; |
| 125 | #else | 197 | #else |
| 126 | mask <<= 1; | 198 | mask <<= 1; |
| 127 | #endif | 199 | #endif |
| 128 | } while (mask); | 200 | } while (mask); |
| 201 | |||
| 202 | #if defined(SERIAL_SOFT_PARITY_EVEN) || defined(SERIAL_SOFT_PARITY_ODD) | ||
| 203 | /* to center of parity bit */ | ||
| 204 | _delay_us(WAIT_US); | ||
| 205 | if (SERIAL_SOFT_RXD_IN()) { parity ^= 1; } | ||
| 206 | SERIAL_SOFT_DEBUG_TGL(); | ||
| 207 | #endif | ||
| 208 | |||
| 129 | /* to center of stop bit */ | 209 | /* to center of stop bit */ |
| 130 | _delay_us(WAIT_US); | 210 | _delay_us(WAIT_US); |
| 131 | 211 | ||
| 132 | uint8_t next = (rbuf_head + 1) % RBUF_SIZE; | 212 | uint8_t next = (rbuf_head + 1) % RBUF_SIZE; |
| 213 | #if defined(SERIAL_SOFT_PARITY_EVEN) || defined(SERIAL_SOFT_PARITY_ODD) | ||
| 214 | if ((parity == SERIAL_SOFT_PARITY_VAL) && next != rbuf_tail) { | ||
| 215 | #else | ||
| 133 | if (next != rbuf_tail) { | 216 | if (next != rbuf_tail) { |
| 217 | #endif | ||
| 134 | rbuf[rbuf_head] = data; | 218 | rbuf[rbuf_head] = data; |
| 135 | rbuf_head = next; | 219 | rbuf_head = next; |
| 136 | } | 220 | } |
| 137 | 221 | ||
| 138 | SERIAL_RXD_INT_EXIT(); | 222 | SERIAL_SOFT_RXD_INT_EXIT(); |
| 223 | SERIAL_SOFT_DEBUG_TGL(); | ||
| 139 | } | 224 | } |
diff --git a/protocol/serial_uart.c b/protocol/serial_uart.c new file mode 100644 index 000000000..6c0af8817 --- /dev/null +++ b/protocol/serial_uart.c | |||
| @@ -0,0 +1,93 @@ | |||
| 1 | /* | ||
| 2 | Copyright 2013 Jun WAKO <wakojun@gmail.com> | ||
| 3 | |||
| 4 | This software is licensed with a Modified BSD License. | ||
| 5 | All of this is supposed to be Free Software, Open Source, DFSG-free, | ||
| 6 | GPL-compatible, and OK to use in both free and proprietary applications. | ||
| 7 | Additions and corrections to this file are welcome. | ||
| 8 | |||
| 9 | |||
| 10 | Redistribution and use in source and binary forms, with or without | ||
| 11 | modification, are permitted provided that the following conditions are met: | ||
| 12 | |||
| 13 | * Redistributions of source code must retain the above copyright | ||
| 14 | notice, this list of conditions and the following disclaimer. | ||
| 15 | |||
| 16 | * Redistributions in binary form must reproduce the above copyright | ||
| 17 | notice, this list of conditions and the following disclaimer in | ||
| 18 | the documentation and/or other materials provided with the | ||
| 19 | distribution. | ||
| 20 | |||
| 21 | * Neither the name of the copyright holders nor the names of | ||
| 22 | contributors may be used to endorse or promote products derived | ||
| 23 | from this software without specific prior written permission. | ||
| 24 | |||
| 25 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
| 26 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 27 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 28 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
| 29 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
| 30 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
| 31 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
| 32 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
| 33 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
| 34 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| 35 | POSSIBILITY OF SUCH DAMAGE. | ||
| 36 | */ | ||
| 37 | |||
| 38 | #include <stdbool.h> | ||
| 39 | #include <avr/io.h> | ||
| 40 | #include <avr/interrupt.h> | ||
| 41 | #include "serial.h" | ||
| 42 | |||
| 43 | |||
| 44 | void serial_init(void) | ||
| 45 | { | ||
| 46 | SERIAL_UART_INIT(); | ||
| 47 | } | ||
| 48 | |||
| 49 | // RX ring buffer | ||
| 50 | #define RBUF_SIZE 8 | ||
| 51 | static uint8_t rbuf[RBUF_SIZE]; | ||
| 52 | static uint8_t rbuf_head = 0; | ||
| 53 | static uint8_t rbuf_tail = 0; | ||
| 54 | |||
| 55 | uint8_t serial_recv(void) | ||
| 56 | { | ||
| 57 | uint8_t data = 0; | ||
| 58 | if (rbuf_head == rbuf_tail) { | ||
| 59 | return 0; | ||
| 60 | } | ||
| 61 | |||
| 62 | data = rbuf[rbuf_tail]; | ||
| 63 | rbuf_tail = (rbuf_tail + 1) % RBUF_SIZE; | ||
| 64 | return data; | ||
| 65 | } | ||
| 66 | |||
| 67 | int16_t serial_recv2(void) | ||
| 68 | { | ||
| 69 | uint8_t data = 0; | ||
| 70 | if (rbuf_head == rbuf_tail) { | ||
| 71 | return -1; | ||
| 72 | } | ||
| 73 | |||
| 74 | data = rbuf[rbuf_tail]; | ||
| 75 | rbuf_tail = (rbuf_tail + 1) % RBUF_SIZE; | ||
| 76 | return data; | ||
| 77 | } | ||
| 78 | |||
| 79 | void serial_send(uint8_t data) | ||
| 80 | { | ||
| 81 | while (!SERIAL_UART_TXD_READY) ; | ||
| 82 | SERIAL_UART_DATA = data; | ||
| 83 | } | ||
| 84 | |||
| 85 | // USART RX complete interrupt | ||
| 86 | ISR(SERIAL_UART_RXD_VECT) | ||
| 87 | { | ||
| 88 | uint8_t next = (rbuf_head + 1) % RBUF_SIZE; | ||
| 89 | if (next != rbuf_tail) { | ||
| 90 | rbuf[rbuf_head] = SERIAL_UART_DATA; | ||
| 91 | rbuf_head = next; | ||
| 92 | } | ||
| 93 | } | ||
diff --git a/protocol/vusb/vusb.c b/protocol/vusb/vusb.c index 1d5f4a852..328885a9b 100644 --- a/protocol/vusb/vusb.c +++ b/protocol/vusb/vusb.c | |||
| @@ -88,6 +88,10 @@ static void send_keyboard(report_keyboard_t *report) | |||
| 88 | } else { | 88 | } else { |
| 89 | debug("kbuf: full\n"); | 89 | debug("kbuf: full\n"); |
| 90 | } | 90 | } |
| 91 | |||
| 92 | // NOTE: send key strokes of Macro | ||
| 93 | usbPoll(); | ||
| 94 | vusb_transfer_keyboard(); | ||
| 91 | } | 95 | } |
| 92 | 96 | ||
| 93 | 97 | ||
