diff options
| author | tmk <nobody@nowhere> | 2013-02-25 08:40:15 +0900 |
|---|---|---|
| committer | tmk <nobody@nowhere> | 2013-02-25 14:14:46 +0900 |
| commit | 308abf598d4cc19be3c5b137bbd13d18510a083a (patch) | |
| tree | 8cc5d21272b79d4011734ee074479c2bb99e7fc8 /protocol/serial_soft.c | |
| parent | ea1ede83c36272ccaeb5e4d80efc3885edbb9209 (diff) | |
| download | qmk_firmware-308abf598d4cc19be3c5b137bbd13d18510a083a.tar.gz qmk_firmware-308abf598d4cc19be3c5b137bbd13d18510a083a.zip | |
Fix software serial configure
Diffstat (limited to 'protocol/serial_soft.c')
| -rw-r--r-- | protocol/serial_soft.c | 98 |
1 files changed, 53 insertions, 45 deletions
diff --git a/protocol/serial_soft.c b/protocol/serial_soft.c index c906c6647..e8870bcd7 100644 --- a/protocol/serial_soft.c +++ b/protocol/serial_soft.c | |||
| @@ -43,12 +43,32 @@ 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 (1000000L/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 | ||
| 50 | 69 | ||
| 51 | /* debug for signal timing, see debug pin with oscilloscope */ | 70 | /* debug for signal timing, see debug pin with oscilloscope */ |
| 71 | #define SERIAL_SOFT_DEBUG | ||
| 52 | #ifdef SERIAL_SOFT_DEBUG | 72 | #ifdef SERIAL_SOFT_DEBUG |
| 53 | #define SERIAL_SOFT_DEBUG_INIT() (DDRD |= 1<<7) | 73 | #define SERIAL_SOFT_DEBUG_INIT() (DDRD |= 1<<7) |
| 54 | #define SERIAL_SOFT_DEBUG_TGL() (PORTD ^= 1<<7) | 74 | #define SERIAL_SOFT_DEBUG_TGL() (PORTD ^= 1<<7) |
| @@ -62,8 +82,8 @@ void serial_init(void) | |||
| 62 | { | 82 | { |
| 63 | SERIAL_SOFT_DEBUG_INIT(); | 83 | SERIAL_SOFT_DEBUG_INIT(); |
| 64 | 84 | ||
| 65 | SERIAL_RXD_INIT(); | 85 | SERIAL_SOFT_RXD_INIT(); |
| 66 | SERIAL_TXD_INIT(); | 86 | SERIAL_SOFT_TXD_INIT(); |
| 67 | } | 87 | } |
| 68 | 88 | ||
| 69 | /* RX ring buffer */ | 89 | /* RX ring buffer */ |
| @@ -101,109 +121,97 @@ void serial_send(uint8_t data) | |||
| 101 | { | 121 | { |
| 102 | /* 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 */ |
| 103 | 123 | ||
| 104 | #ifdef SERIAL_BIT_ORDER_MSB | 124 | #ifdef SERIAL_SOFT_BIT_ORDER_MSB |
| 105 | uint8_t mask = 0x80; | 125 | uint8_t mask = 0x80; |
| 106 | #else | 126 | #else |
| 107 | uint8_t mask = 0x01; | 127 | uint8_t mask = 0x01; |
| 108 | #endif | 128 | #endif |
| 109 | 129 | ||
| 110 | #ifdef SERIAL_PARITY_ODD | ||
| 111 | uint8_t parity = 1; | ||
| 112 | #elif defined(SERIAL_PARITY_EVEN) | ||
| 113 | uint8_t parity = 0; | 130 | uint8_t parity = 0; |
| 114 | #endif | ||
| 115 | 131 | ||
| 116 | /* start bit */ | 132 | /* start bit */ |
| 117 | SERIAL_TXD_OFF(); | 133 | SERIAL_SOFT_TXD_OFF(); |
| 118 | _delay_us(WAIT_US-2); | 134 | _delay_us(WAIT_US); |
| 119 | 135 | ||
| 120 | while (mask) { | 136 | while (mask) { |
| 121 | if (data&mask) { | 137 | if (data&mask) { |
| 122 | SERIAL_TXD_ON(); | 138 | SERIAL_SOFT_TXD_ON(); |
| 123 | #if defined(SERIAL_PARITY_EVEN) || defined(SERIAL_PARITY_ODD) | ||
| 124 | parity ^= 1; | 139 | parity ^= 1; |
| 125 | #endif | ||
| 126 | } else { | 140 | } else { |
| 127 | SERIAL_TXD_OFF(); | 141 | SERIAL_SOFT_TXD_OFF(); |
| 128 | } | 142 | } |
| 129 | _delay_us(WAIT_US-2); | 143 | _delay_us(WAIT_US); |
| 130 | 144 | ||
| 131 | #ifdef SERIAL_BIT_ORDER_MSB | 145 | #ifdef SERIAL_SOFT_BIT_ORDER_MSB |
| 132 | mask >>= 1; | 146 | mask >>= 1; |
| 133 | #else | 147 | #else |
| 134 | mask <<= 1; | 148 | mask <<= 1; |
| 135 | #endif | 149 | #endif |
| 136 | } | 150 | } |
| 137 | 151 | ||
| 138 | #if defined(SERIAL_PARITY_EVEN) || defined(SERIAL_PARITY_ODD) | 152 | #if defined(SERIAL_SOFT_PARITY_EVEN) || defined(SERIAL_SOFT_PARITY_ODD) |
| 139 | /* to center of parity bit */ | 153 | /* to center of parity bit */ |
| 140 | if (parity) { | 154 | if (parity != SERIAL_SOFT_PARITY_VAL) { |
| 141 | SERIAL_TXD_ON(); | 155 | SERIAL_SOFT_TXD_ON(); |
| 142 | } else { | 156 | } else { |
| 143 | SERIAL_TXD_OFF(); | 157 | SERIAL_SOFT_TXD_OFF(); |
| 144 | } | 158 | } |
| 145 | _delay_us(WAIT_US-2); | 159 | _delay_us(WAIT_US); |
| 146 | #endif | 160 | #endif |
| 147 | 161 | ||
| 148 | /* stop bit */ | 162 | /* stop bit */ |
| 149 | SERIAL_TXD_ON(); | 163 | SERIAL_SOFT_TXD_ON(); |
| 150 | _delay_us(WAIT_US-2); | 164 | _delay_us(WAIT_US); |
| 151 | } | 165 | } |
| 152 | 166 | ||
| 153 | /* detect edge of start bit */ | 167 | /* detect edge of start bit */ |
| 154 | ISR(SERIAL_RXD_VECT) | 168 | ISR(SERIAL_SOFT_RXD_VECT) |
| 155 | { | 169 | { |
| 156 | SERIAL_SOFT_DEBUG_TGL() | 170 | SERIAL_SOFT_DEBUG_TGL(); |
| 157 | SERIAL_RXD_INT_ENTER() | 171 | SERIAL_SOFT_RXD_INT_ENTER() |
| 158 | 172 | ||
| 159 | uint8_t data = 0; | 173 | uint8_t data = 0; |
| 160 | 174 | ||
| 161 | #ifdef SERIAL_BIT_ORDER_MSB | 175 | #ifdef SERIAL_SOFT_BIT_ORDER_MSB |
| 162 | uint8_t mask = 0x80; | 176 | uint8_t mask = 0x80; |
| 163 | #else | 177 | #else |
| 164 | uint8_t mask = 0x01; | 178 | uint8_t mask = 0x01; |
| 165 | #endif | 179 | #endif |
| 166 | 180 | ||
| 167 | #ifdef SERIAL_PARITY_ODD | ||
| 168 | uint8_t parity = 0; | 181 | uint8_t parity = 0; |
| 169 | #elif defined(SERIAL_PARITY_EVEN) | ||
| 170 | uint8_t parity = 1; | ||
| 171 | #endif | ||
| 172 | 182 | ||
| 173 | /* to center of start bit */ | 183 | /* to center of start bit */ |
| 174 | _delay_us(WAIT_US/2); | 184 | _delay_us(WAIT_US/2); |
| 175 | SERIAL_SOFT_DEBUG_TGL() | 185 | SERIAL_SOFT_DEBUG_TGL(); |
| 176 | do { | 186 | do { |
| 177 | /* to center of next bit */ | 187 | /* to center of next bit */ |
| 178 | _delay_us(WAIT_US); | 188 | _delay_us(WAIT_US); |
| 179 | 189 | ||
| 180 | SERIAL_SOFT_DEBUG_TGL() | 190 | SERIAL_SOFT_DEBUG_TGL(); |
| 181 | if (SERIAL_RXD_READ()) { | 191 | if (SERIAL_SOFT_RXD_IN()) { |
| 182 | data |= mask; | 192 | data |= mask; |
| 183 | #if defined(SERIAL_PARITY_EVEN) || defined(SERIAL_PARITY_ODD) | ||
| 184 | parity ^= 1; | 193 | parity ^= 1; |
| 185 | #endif | ||
| 186 | } | 194 | } |
| 187 | #ifdef SERIAL_BIT_ORDER_MSB | 195 | #ifdef SERIAL_SOFT_BIT_ORDER_MSB |
| 188 | mask >>= 1; | 196 | mask >>= 1; |
| 189 | #else | 197 | #else |
| 190 | mask <<= 1; | 198 | mask <<= 1; |
| 191 | #endif | 199 | #endif |
| 192 | } while (mask); | 200 | } while (mask); |
| 193 | 201 | ||
| 194 | #if defined(SERIAL_PARITY_EVEN) || defined(SERIAL_PARITY_ODD) | 202 | #if defined(SERIAL_SOFT_PARITY_EVEN) || defined(SERIAL_SOFT_PARITY_ODD) |
| 195 | /* to center of parity bit */ | 203 | /* to center of parity bit */ |
| 196 | _delay_us(WAIT_US); | 204 | _delay_us(WAIT_US); |
| 197 | if (SERIAL_RXD_READ()) { parity ^= 1; } | 205 | if (SERIAL_SOFT_RXD_IN()) { parity ^= 1; } |
| 198 | SERIAL_SOFT_DEBUG_TGL() | 206 | SERIAL_SOFT_DEBUG_TGL(); |
| 199 | #endif | 207 | #endif |
| 200 | 208 | ||
| 201 | /* to center of stop bit */ | 209 | /* to center of stop bit */ |
| 202 | _delay_us(WAIT_US); | 210 | _delay_us(WAIT_US); |
| 203 | 211 | ||
| 204 | uint8_t next = (rbuf_head + 1) % RBUF_SIZE; | 212 | uint8_t next = (rbuf_head + 1) % RBUF_SIZE; |
| 205 | #if defined(SERIAL_PARITY_EVEN) || defined(SERIAL_PARITY_ODD) | 213 | #if defined(SERIAL_SOFT_PARITY_EVEN) || defined(SERIAL_SOFT_PARITY_ODD) |
| 206 | if (parity && next != rbuf_tail) { | 214 | if ((parity == SERIAL_SOFT_PARITY_VAL) && next != rbuf_tail) { |
| 207 | #else | 215 | #else |
| 208 | if (next != rbuf_tail) { | 216 | if (next != rbuf_tail) { |
| 209 | #endif | 217 | #endif |
| @@ -211,6 +219,6 @@ ISR(SERIAL_RXD_VECT) | |||
| 211 | rbuf_head = next; | 219 | rbuf_head = next; |
| 212 | } | 220 | } |
| 213 | 221 | ||
| 214 | SERIAL_RXD_INT_EXIT(); | 222 | SERIAL_SOFT_RXD_INT_EXIT(); |
| 215 | SERIAL_SOFT_DEBUG_TGL() | 223 | SERIAL_SOFT_DEBUG_TGL(); |
| 216 | } | 224 | } |
