diff options
author | Pekaso <pekaso34@gmail.com> | 2018-09-28 10:06:19 +0900 |
---|---|---|
committer | Drashna Jaelre <drashna@live.com> | 2018-09-27 18:06:19 -0700 |
commit | a65085a89354e89ddd3517aa63c74ef6dd32ca8b (patch) | |
tree | 7fa976bcd86055d56c6c3be9528c2aaf976ae1c7 | |
parent | 8ef747accf6e59ff50a3dde1cb34f56e4edce9fe (diff) | |
download | qmk_firmware-a65085a89354e89ddd3517aa63c74ef6dd32ca8b.tar.gz qmk_firmware-a65085a89354e89ddd3517aa63c74ef6dd32ca8b.zip |
Keyboard: [Fortitude60] LED fix and Serial improvement (#3982)
* arrangement Underglow
* modified serial function references from helix
* Remove defines (ws2812_*REG)
-rw-r--r-- | keyboards/fortitude60/config.h | 1 | ||||
-rw-r--r-- | keyboards/fortitude60/keymaps/default/config.h | 1 | ||||
-rw-r--r-- | keyboards/fortitude60/keymaps/default/keymap.c | 4 | ||||
-rw-r--r-- | keyboards/fortitude60/keymaps/default/rules.mk | 1 | ||||
-rw-r--r-- | keyboards/fortitude60/rev1/config.h | 11 | ||||
-rw-r--r-- | keyboards/fortitude60/rev1/rules.mk | 1 | ||||
-rw-r--r-- | keyboards/fortitude60/serial.c | 451 | ||||
-rw-r--r-- | keyboards/fortitude60/serial.h | 86 | ||||
-rw-r--r-- | keyboards/fortitude60/serial_config.h | 14 |
9 files changed, 420 insertions, 150 deletions
diff --git a/keyboards/fortitude60/config.h b/keyboards/fortitude60/config.h index 863722d7d..27a44ab92 100644 --- a/keyboards/fortitude60/config.h +++ b/keyboards/fortitude60/config.h | |||
@@ -19,5 +19,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
19 | #define CONFIG_H | 19 | #define CONFIG_H |
20 | 20 | ||
21 | #include "config_common.h" | 21 | #include "config_common.h" |
22 | #include <serial_config.h> | ||
22 | 23 | ||
23 | #endif // CONFIG_H | 24 | #endif // CONFIG_H |
diff --git a/keyboards/fortitude60/keymaps/default/config.h b/keyboards/fortitude60/keymaps/default/config.h index b356791fc..174837348 100644 --- a/keyboards/fortitude60/keymaps/default/config.h +++ b/keyboards/fortitude60/keymaps/default/config.h | |||
@@ -28,7 +28,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
28 | // #define MASTER_RIGHT | 28 | // #define MASTER_RIGHT |
29 | #define EE_HANDS | 29 | #define EE_HANDS |
30 | 30 | ||
31 | #define USE_SERIAL_PD2 | ||
32 | /* #undef RGBLED_NUM */ | 31 | /* #undef RGBLED_NUM */ |
33 | /* #define RGBLIGHT_ANIMATIONS */ | 32 | /* #define RGBLIGHT_ANIMATIONS */ |
34 | /* #define RGBLED_NUM 12 */ | 33 | /* #define RGBLED_NUM 12 */ |
diff --git a/keyboards/fortitude60/keymaps/default/keymap.c b/keyboards/fortitude60/keymaps/default/keymap.c index 18d2527e4..9d724a8ec 100644 --- a/keyboards/fortitude60/keymaps/default/keymap.c +++ b/keyboards/fortitude60/keymaps/default/keymap.c | |||
@@ -119,9 +119,9 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | |||
119 | * ,-----------------------------------------. ,-----------------------------------------. | 119 | * ,-----------------------------------------. ,-----------------------------------------. |
120 | * | ` | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | Del | | 120 | * | ` | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | Del | |
121 | * |------+------+------+------+------+------. ,------+------+------+------+------+------| | 121 | * |------+------+------+------+------+------. ,------+------+------+------+------+------| |
122 | * | ` | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | Bksp | | 122 | * | ` | 1 | ↑ | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | Bksp | |
123 | * |------+------+------+------+------+------. ,------+------+------+------+------+------| | 123 | * |------+------+------+------+------+------. ,------+------+------+------+------+------| |
124 | * | Del | F1 | F2 | F3 | F4 | F5 | | F6 | - | = | [ | ] | | | | 124 | * | Del | ← | ↓ | → | F4 | F5 | | F6 | - | = | [ | ] | | | |
125 | * |------+------+------+------+------+------+-------------+------+------+------+------+------+------| | 125 | * |------+------+------+------+------+------+-------------+------+------+------+------+------+------| |
126 | * | | F7 | F8 | F9 | F10 | F11 | | | F12 |ISO # |ISO / | | | | | 126 | * | | F7 | F8 | F9 | F10 | F11 | | | F12 |ISO # |ISO / | | | | |
127 | * `-------------+------+------+------+------+------+------+------+------+------+------+-------------' | 127 | * `-------------+------+------+------+------+------+------+------+------+------+------+-------------' |
diff --git a/keyboards/fortitude60/keymaps/default/rules.mk b/keyboards/fortitude60/keymaps/default/rules.mk index e0ed6f0c2..1964bd0a7 100644 --- a/keyboards/fortitude60/keymaps/default/rules.mk +++ b/keyboards/fortitude60/keymaps/default/rules.mk | |||
@@ -1 +1,2 @@ | |||
1 | RGBLIGHT_ENABLE = no | 1 | RGBLIGHT_ENABLE = no |
2 | BACKLIGHT_ENABLE = no \ No newline at end of file | ||
diff --git a/keyboards/fortitude60/rev1/config.h b/keyboards/fortitude60/rev1/config.h index 4ba195ff8..8c6f21afe 100644 --- a/keyboards/fortitude60/rev1/config.h +++ b/keyboards/fortitude60/rev1/config.h | |||
@@ -64,12 +64,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
64 | ) | 64 | ) |
65 | 65 | ||
66 | /* ws2812 RGB LED */ | 66 | /* ws2812 RGB LED */ |
67 | /* #define RGB_DI_PIN D3 */ | 67 | #ifdef RGBLIGHT_ENABLE |
68 | /* #define RGBLIGHT_TIMER */ | 68 | #define RGB_DI_PIN B5 |
69 | /* #define RGBLED_NUM 16 // Number of LEDs */ | 69 | #define RGBLIGHT_TIMER |
70 | /* #define ws2812_PORTREG PORTD */ | 70 | #define RGBLED_NUM 18 // Number of LEDs */ |
71 | /* #define ws2812_DDRREG DDRD */ | 71 | #endif |
72 | |||
73 | /* | 72 | /* |
74 | * Feature disable options | 73 | * Feature disable options |
75 | * These options are also useful to firmware size reduction. | 74 | * These options are also useful to firmware size reduction. |
diff --git a/keyboards/fortitude60/rev1/rules.mk b/keyboards/fortitude60/rev1/rules.mk index bd518d8f2..e69de29bb 100644 --- a/keyboards/fortitude60/rev1/rules.mk +++ b/keyboards/fortitude60/rev1/rules.mk | |||
@@ -1 +0,0 @@ | |||
1 | BACKLIGHT_ENABLE = yes | ||
diff --git a/keyboards/fortitude60/serial.c b/keyboards/fortitude60/serial.c index 46dfad021..cea1a5f6c 100644 --- a/keyboards/fortitude60/serial.c +++ b/keyboards/fortitude60/serial.c | |||
@@ -9,20 +9,102 @@ | |||
9 | #include <avr/io.h> | 9 | #include <avr/io.h> |
10 | #include <avr/interrupt.h> | 10 | #include <avr/interrupt.h> |
11 | #include <util/delay.h> | 11 | #include <util/delay.h> |
12 | #include <stddef.h> | ||
12 | #include <stdbool.h> | 13 | #include <stdbool.h> |
13 | #include "serial.h" | 14 | #include "serial.h" |
15 | //#include <pro_micro.h> | ||
16 | |||
17 | #ifdef USE_SERIAL | ||
18 | |||
19 | #ifndef SERIAL_USE_MULTI_TRANSACTION | ||
20 | /* --- USE Simple API (OLD API, compatible with let's split serial.c) */ | ||
21 | #if SERIAL_SLAVE_BUFFER_LENGTH > 0 | ||
22 | uint8_t volatile serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH] = {0}; | ||
23 | #endif | ||
24 | #if SERIAL_MASTER_BUFFER_LENGTH > 0 | ||
25 | uint8_t volatile serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH] = {0}; | ||
26 | #endif | ||
27 | uint8_t volatile status0 = 0; | ||
28 | |||
29 | SSTD_t transactions[] = { | ||
30 | { (uint8_t *)&status0, | ||
31 | #if SERIAL_MASTER_BUFFER_LENGTH > 0 | ||
32 | sizeof(serial_master_buffer), (uint8_t *)serial_master_buffer, | ||
33 | #else | ||
34 | 0, (uint8_t *)NULL, | ||
35 | #endif | ||
36 | #if SERIAL_SLAVE_BUFFER_LENGTH > 0 | ||
37 | sizeof(serial_slave_buffer), (uint8_t *)serial_slave_buffer | ||
38 | #else | ||
39 | 0, (uint8_t *)NULL, | ||
40 | #endif | ||
41 | } | ||
42 | }; | ||
43 | |||
44 | void serial_master_init(void) | ||
45 | { soft_serial_initiator_init(transactions); } | ||
14 | 46 | ||
15 | #ifndef USE_I2C | 47 | void serial_slave_init(void) |
48 | { soft_serial_target_init(transactions); } | ||
16 | 49 | ||
17 | // Serial pulse period in microseconds. Its probably a bad idea to lower this | 50 | // 0 => no error |
18 | // value. | 51 | // 1 => slave did not respond |
19 | #define SERIAL_DELAY 24 | 52 | // 2 => checksum error |
53 | int serial_update_buffers() | ||
54 | { return soft_serial_transaction(); } | ||
55 | |||
56 | #endif // Simple API (OLD API, compatible with let's split serial.c) | ||
57 | |||
58 | #define ALWAYS_INLINE __attribute__((always_inline)) | ||
59 | #define NO_INLINE __attribute__((noinline)) | ||
60 | #define _delay_sub_us(x) __builtin_avr_delay_cycles(x) | ||
61 | |||
62 | // Serial pulse period in microseconds. | ||
63 | #define TID_SEND_ADJUST 14 | ||
64 | |||
65 | #define SELECT_SERIAL_SPEED 1 | ||
66 | #if SELECT_SERIAL_SPEED == 0 | ||
67 | // Very High speed | ||
68 | #define SERIAL_DELAY 4 // micro sec | ||
69 | #define READ_WRITE_START_ADJUST 33 // cycles | ||
70 | #define READ_WRITE_WIDTH_ADJUST 3 // cycles | ||
71 | #elif SELECT_SERIAL_SPEED == 1 | ||
72 | // High speed | ||
73 | #define SERIAL_DELAY 6 // micro sec | ||
74 | #define READ_WRITE_START_ADJUST 30 // cycles | ||
75 | #define READ_WRITE_WIDTH_ADJUST 3 // cycles | ||
76 | #elif SELECT_SERIAL_SPEED == 2 | ||
77 | // Middle speed | ||
78 | #define SERIAL_DELAY 12 // micro sec | ||
79 | #define READ_WRITE_START_ADJUST 30 // cycles | ||
80 | #define READ_WRITE_WIDTH_ADJUST 3 // cycles | ||
81 | #elif SELECT_SERIAL_SPEED == 3 | ||
82 | // Low speed | ||
83 | #define SERIAL_DELAY 24 // micro sec | ||
84 | #define READ_WRITE_START_ADJUST 30 // cycles | ||
85 | #define READ_WRITE_WIDTH_ADJUST 3 // cycles | ||
86 | #elif SELECT_SERIAL_SPEED == 4 | ||
87 | // Very Low speed | ||
88 | #define SERIAL_DELAY 50 // micro sec | ||
89 | #define READ_WRITE_START_ADJUST 30 // cycles | ||
90 | #define READ_WRITE_WIDTH_ADJUST 3 // cycles | ||
91 | #else | ||
92 | #error Illegal Serial Speed | ||
93 | #endif | ||
20 | 94 | ||
21 | uint8_t volatile serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH] = {0}; | ||
22 | uint8_t volatile serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH] = {0}; | ||
23 | 95 | ||
24 | #define SLAVE_DATA_CORRUPT (1<<0) | 96 | #define SERIAL_DELAY_HALF1 (SERIAL_DELAY/2) |
25 | volatile uint8_t status = 0; | 97 | #define SERIAL_DELAY_HALF2 (SERIAL_DELAY - SERIAL_DELAY/2) |
98 | |||
99 | #define SLAVE_INT_WIDTH_US 1 | ||
100 | #ifndef SERIAL_USE_MULTI_TRANSACTION | ||
101 | #define SLAVE_INT_RESPONSE_TIME SERIAL_DELAY | ||
102 | #else | ||
103 | #define SLAVE_INT_ACK_WIDTH_UNIT 2 | ||
104 | #define SLAVE_INT_ACK_WIDTH 4 | ||
105 | #endif | ||
106 | |||
107 | static SSTD_t *Transaction_table = NULL; | ||
26 | 108 | ||
27 | inline static | 109 | inline static |
28 | void serial_delay(void) { | 110 | void serial_delay(void) { |
@@ -30,13 +112,25 @@ void serial_delay(void) { | |||
30 | } | 112 | } |
31 | 113 | ||
32 | inline static | 114 | inline static |
115 | void serial_delay_half1(void) { | ||
116 | _delay_us(SERIAL_DELAY_HALF1); | ||
117 | } | ||
118 | |||
119 | inline static | ||
120 | void serial_delay_half2(void) { | ||
121 | _delay_us(SERIAL_DELAY_HALF2); | ||
122 | } | ||
123 | |||
124 | inline static void serial_output(void) ALWAYS_INLINE; | ||
125 | inline static | ||
33 | void serial_output(void) { | 126 | void serial_output(void) { |
34 | SERIAL_PIN_DDR |= SERIAL_PIN_MASK; | 127 | SERIAL_PIN_DDR |= SERIAL_PIN_MASK; |
35 | } | 128 | } |
36 | 129 | ||
37 | // make the serial pin an input with pull-up resistor | 130 | // make the serial pin an input with pull-up resistor |
131 | inline static void serial_input_with_pullup(void) ALWAYS_INLINE; | ||
38 | inline static | 132 | inline static |
39 | void serial_input(void) { | 133 | void serial_input_with_pullup(void) { |
40 | SERIAL_PIN_DDR &= ~SERIAL_PIN_MASK; | 134 | SERIAL_PIN_DDR &= ~SERIAL_PIN_MASK; |
41 | SERIAL_PIN_PORT |= SERIAL_PIN_MASK; | 135 | SERIAL_PIN_PORT |= SERIAL_PIN_MASK; |
42 | } | 136 | } |
@@ -46,190 +140,305 @@ uint8_t serial_read_pin(void) { | |||
46 | return !!(SERIAL_PIN_INPUT & SERIAL_PIN_MASK); | 140 | return !!(SERIAL_PIN_INPUT & SERIAL_PIN_MASK); |
47 | } | 141 | } |
48 | 142 | ||
143 | inline static void serial_low(void) ALWAYS_INLINE; | ||
49 | inline static | 144 | inline static |
50 | void serial_low(void) { | 145 | void serial_low(void) { |
51 | SERIAL_PIN_PORT &= ~SERIAL_PIN_MASK; | 146 | SERIAL_PIN_PORT &= ~SERIAL_PIN_MASK; |
52 | } | 147 | } |
53 | 148 | ||
149 | inline static void serial_high(void) ALWAYS_INLINE; | ||
54 | inline static | 150 | inline static |
55 | void serial_high(void) { | 151 | void serial_high(void) { |
56 | SERIAL_PIN_PORT |= SERIAL_PIN_MASK; | 152 | SERIAL_PIN_PORT |= SERIAL_PIN_MASK; |
57 | } | 153 | } |
58 | 154 | ||
59 | void serial_master_init(void) { | 155 | void soft_serial_initiator_init(SSTD_t *sstd_table) |
60 | serial_output(); | 156 | { |
61 | serial_high(); | 157 | Transaction_table = sstd_table; |
158 | serial_output(); | ||
159 | serial_high(); | ||
62 | } | 160 | } |
63 | 161 | ||
64 | void serial_slave_init(void) { | 162 | void soft_serial_target_init(SSTD_t *sstd_table) |
65 | serial_input(); | 163 | { |
66 | 164 | Transaction_table = sstd_table; | |
67 | #ifndef USE_SERIAL_PD2 | 165 | serial_input_with_pullup(); |
68 | // Enable INT0 | 166 | |
69 | EIMSK |= _BV(INT0); | 167 | #if SERIAL_PIN_MASK == _BV(PD0) |
70 | // Trigger on falling edge of INT0 | 168 | // Enable INT0 |
71 | EICRA &= ~(_BV(ISC00) | _BV(ISC01)); | 169 | EIMSK |= _BV(INT0); |
170 | // Trigger on falling edge of INT0 | ||
171 | EICRA &= ~(_BV(ISC00) | _BV(ISC01)); | ||
172 | #elif SERIAL_PIN_MASK == _BV(PD2) | ||
173 | // Enable INT2 | ||
174 | EIMSK |= _BV(INT2); | ||
175 | // Trigger on falling edge of INT2 | ||
176 | EICRA &= ~(_BV(ISC20) | _BV(ISC21)); | ||
72 | #else | 177 | #else |
73 | // Enable INT2 | 178 | #error unknown SERIAL_PIN_MASK value |
74 | EIMSK |= _BV(INT2); | ||
75 | // Trigger on falling edge of INT2 | ||
76 | EICRA &= ~(_BV(ISC20) | _BV(ISC21)); | ||
77 | #endif | 179 | #endif |
78 | } | 180 | } |
79 | 181 | ||
80 | // Used by the master to synchronize timing with the slave. | 182 | // Used by the sender to synchronize timing with the reciver. |
183 | static void sync_recv(void) NO_INLINE; | ||
81 | static | 184 | static |
82 | void sync_recv(void) { | 185 | void sync_recv(void) { |
83 | serial_input(); | 186 | for (uint8_t i = 0; i < SERIAL_DELAY*5 && serial_read_pin(); i++ ) { |
84 | // This shouldn't hang if the slave disconnects because the | 187 | } |
85 | // serial line will float to high if the slave does disconnect. | 188 | // This shouldn't hang if the target disconnects because the |
189 | // serial line will float to high if the target does disconnect. | ||
86 | while (!serial_read_pin()); | 190 | while (!serial_read_pin()); |
87 | serial_delay(); | ||
88 | } | 191 | } |
89 | 192 | ||
90 | // Used by the slave to send a synchronization signal to the master. | 193 | // Used by the reciver to send a synchronization signal to the sender. |
194 | static void sync_send(void)NO_INLINE; | ||
91 | static | 195 | static |
92 | void sync_send(void) { | 196 | void sync_send(void) { |
93 | serial_output(); | ||
94 | |||
95 | serial_low(); | 197 | serial_low(); |
96 | serial_delay(); | 198 | serial_delay(); |
97 | |||
98 | serial_high(); | 199 | serial_high(); |
99 | } | 200 | } |
100 | 201 | ||
101 | // Reads a byte from the serial line | 202 | // Reads a byte from the serial line |
102 | static | 203 | static uint8_t serial_read_chunk(uint8_t *pterrcount, uint8_t bit) NO_INLINE; |
103 | uint8_t serial_read_byte(void) { | 204 | static uint8_t serial_read_chunk(uint8_t *pterrcount, uint8_t bit) { |
104 | uint8_t byte = 0; | 205 | uint8_t byte, i, p, pb; |
105 | serial_input(); | 206 | |
106 | for ( uint8_t i = 0; i < 8; ++i) { | 207 | _delay_sub_us(READ_WRITE_START_ADJUST); |
107 | byte = (byte << 1) | serial_read_pin(); | 208 | for( i = 0, byte = 0, p = 0; i < bit; i++ ) { |
108 | serial_delay(); | 209 | serial_delay_half1(); // read the middle of pulses |
109 | _delay_us(1); | 210 | if( serial_read_pin() ) { |
211 | byte = (byte << 1) | 1; p ^= 1; | ||
212 | } else { | ||
213 | byte = (byte << 1) | 0; p ^= 0; | ||
214 | } | ||
215 | _delay_sub_us(READ_WRITE_WIDTH_ADJUST); | ||
216 | serial_delay_half2(); | ||
110 | } | 217 | } |
218 | /* recive parity bit */ | ||
219 | serial_delay_half1(); // read the middle of pulses | ||
220 | pb = serial_read_pin(); | ||
221 | _delay_sub_us(READ_WRITE_WIDTH_ADJUST); | ||
222 | serial_delay_half2(); | ||
223 | |||
224 | *pterrcount += (p != pb)? 1 : 0; | ||
111 | 225 | ||
112 | return byte; | 226 | return byte; |
113 | } | 227 | } |
114 | 228 | ||
115 | // Sends a byte with MSB ordering | 229 | // Sends a byte with MSB ordering |
116 | static | 230 | void serial_write_chunk(uint8_t data, uint8_t bit) NO_INLINE; |
117 | void serial_write_byte(uint8_t data) { | 231 | void serial_write_chunk(uint8_t data, uint8_t bit) { |
118 | uint8_t b = 8; | 232 | uint8_t b, p; |
119 | serial_output(); | 233 | for( p = 0, b = 1<<(bit-1); b ; b >>= 1) { |
120 | while( b-- ) { | 234 | if(data & b) { |
121 | if(data & (1 << b)) { | 235 | serial_high(); p ^= 1; |
122 | serial_high(); | 236 | } else { |
123 | } else { | 237 | serial_low(); p ^= 0; |
124 | serial_low(); | 238 | } |
239 | serial_delay(); | ||
125 | } | 240 | } |
241 | /* send parity bit */ | ||
242 | if(p & 1) { serial_high(); } | ||
243 | else { serial_low(); } | ||
126 | serial_delay(); | 244 | serial_delay(); |
127 | } | ||
128 | } | ||
129 | 245 | ||
130 | // interrupt handle to be used by the slave device | 246 | serial_low(); // sync_send() / senc_recv() need raise edge |
131 | ISR(SERIAL_PIN_INTERRUPT) { | 247 | } |
132 | sync_send(); | ||
133 | 248 | ||
134 | uint8_t checksum = 0; | 249 | static void serial_send_packet(uint8_t *buffer, uint8_t size) NO_INLINE; |
135 | for (int i = 0; i < SERIAL_SLAVE_BUFFER_LENGTH; ++i) { | 250 | static |
136 | serial_write_byte(serial_slave_buffer[i]); | 251 | void serial_send_packet(uint8_t *buffer, uint8_t size) { |
252 | for (uint8_t i = 0; i < size; ++i) { | ||
253 | uint8_t data; | ||
254 | data = buffer[i]; | ||
137 | sync_send(); | 255 | sync_send(); |
138 | checksum += serial_slave_buffer[i]; | 256 | serial_write_chunk(data,8); |
139 | } | 257 | } |
140 | serial_write_byte(checksum); | 258 | } |
141 | sync_send(); | ||
142 | 259 | ||
143 | // wait for the sync to finish sending | 260 | static uint8_t serial_recive_packet(uint8_t *buffer, uint8_t size) NO_INLINE; |
144 | serial_delay(); | 261 | static |
262 | uint8_t serial_recive_packet(uint8_t *buffer, uint8_t size) { | ||
263 | uint8_t pecount = 0; | ||
264 | for (uint8_t i = 0; i < size; ++i) { | ||
265 | uint8_t data; | ||
266 | sync_recv(); | ||
267 | data = serial_read_chunk(&pecount, 8); | ||
268 | buffer[i] = data; | ||
269 | } | ||
270 | return pecount == 0; | ||
271 | } | ||
145 | 272 | ||
146 | // read the middle of pulses | 273 | inline static |
147 | _delay_us(SERIAL_DELAY/2); | 274 | void change_sender2reciver(void) { |
275 | sync_send(); //0 | ||
276 | serial_delay_half1(); //1 | ||
277 | serial_low(); //2 | ||
278 | serial_input_with_pullup(); //2 | ||
279 | serial_delay_half1(); //3 | ||
280 | } | ||
148 | 281 | ||
149 | uint8_t checksum_computed = 0; | 282 | inline static |
150 | for (int i = 0; i < SERIAL_MASTER_BUFFER_LENGTH; ++i) { | 283 | void change_reciver2sender(void) { |
151 | serial_master_buffer[i] = serial_read_byte(); | 284 | sync_recv(); //0 |
152 | sync_send(); | 285 | serial_delay(); //1 |
153 | checksum_computed += serial_master_buffer[i]; | 286 | serial_low(); //3 |
154 | } | 287 | serial_output(); //3 |
155 | uint8_t checksum_received = serial_read_byte(); | 288 | serial_delay_half1(); //4 |
156 | sync_send(); | 289 | } |
157 | 290 | ||
158 | serial_input(); // end transaction | 291 | // interrupt handle to be used by the target device |
292 | ISR(SERIAL_PIN_INTERRUPT) { | ||
159 | 293 | ||
160 | if ( checksum_computed != checksum_received ) { | 294 | #ifndef SERIAL_USE_MULTI_TRANSACTION |
161 | status |= SLAVE_DATA_CORRUPT; | 295 | serial_low(); |
296 | serial_output(); | ||
297 | SSTD_t *trans = Transaction_table; | ||
298 | #else | ||
299 | // recive transaction table index | ||
300 | uint8_t tid; | ||
301 | uint8_t pecount = 0; | ||
302 | sync_recv(); | ||
303 | tid = serial_read_chunk(&pecount,4); | ||
304 | if(pecount> 0) | ||
305 | return; | ||
306 | serial_delay_half1(); | ||
307 | |||
308 | serial_high(); // response step1 low->high | ||
309 | serial_output(); | ||
310 | _delay_sub_us(SLAVE_INT_ACK_WIDTH_UNIT*SLAVE_INT_ACK_WIDTH); | ||
311 | SSTD_t *trans = &Transaction_table[tid]; | ||
312 | serial_low(); // response step2 ack high->low | ||
313 | #endif | ||
314 | |||
315 | // target send phase | ||
316 | if( trans->target2initiator_buffer_size > 0 ) | ||
317 | serial_send_packet((uint8_t *)trans->target2initiator_buffer, | ||
318 | trans->target2initiator_buffer_size); | ||
319 | // target switch to input | ||
320 | change_sender2reciver(); | ||
321 | |||
322 | // target recive phase | ||
323 | if( trans->initiator2target_buffer_size > 0 ) { | ||
324 | if (serial_recive_packet((uint8_t *)trans->initiator2target_buffer, | ||
325 | trans->initiator2target_buffer_size) ) { | ||
326 | *trans->status = TRANSACTION_ACCEPTED; | ||
327 | } else { | ||
328 | *trans->status = TRANSACTION_DATA_ERROR; | ||
329 | } | ||
162 | } else { | 330 | } else { |
163 | status &= ~SLAVE_DATA_CORRUPT; | 331 | *trans->status = TRANSACTION_ACCEPTED; |
164 | } | 332 | } |
165 | } | ||
166 | 333 | ||
167 | inline | 334 | sync_recv(); //weit initiator output to high |
168 | bool serial_slave_DATA_CORRUPT(void) { | ||
169 | return status & SLAVE_DATA_CORRUPT; | ||
170 | } | 335 | } |
171 | 336 | ||
172 | // Copies the serial_slave_buffer to the master and sends the | 337 | ///////// |
173 | // serial_master_buffer to the slave. | 338 | // start transaction by initiator |
339 | // | ||
340 | // int soft_serial_transaction(int sstd_index) | ||
174 | // | 341 | // |
175 | // Returns: | 342 | // Returns: |
176 | // 0 => no error | 343 | // TRANSACTION_END |
177 | // 1 => slave did not respond | 344 | // TRANSACTION_NO_RESPONSE |
178 | int serial_update_buffers(void) { | 345 | // TRANSACTION_DATA_ERROR |
179 | // this code is very time dependent, so we need to disable interrupts | 346 | // this code is very time dependent, so we need to disable interrupts |
347 | #ifndef SERIAL_USE_MULTI_TRANSACTION | ||
348 | int soft_serial_transaction(void) { | ||
349 | SSTD_t *trans = Transaction_table; | ||
350 | #else | ||
351 | int soft_serial_transaction(int sstd_index) { | ||
352 | SSTD_t *trans = &Transaction_table[sstd_index]; | ||
353 | #endif | ||
180 | cli(); | 354 | cli(); |
181 | 355 | ||
182 | // signal to the slave that we want to start a transaction | 356 | // signal to the target that we want to start a transaction |
183 | serial_output(); | 357 | serial_output(); |
184 | serial_low(); | 358 | serial_low(); |
185 | _delay_us(1); | 359 | _delay_us(SLAVE_INT_WIDTH_US); |
186 | 360 | ||
187 | // wait for the slaves response | 361 | #ifndef SERIAL_USE_MULTI_TRANSACTION |
188 | serial_input(); | 362 | // wait for the target response |
189 | serial_high(); | 363 | serial_input_with_pullup(); |
190 | _delay_us(SERIAL_DELAY); | 364 | _delay_us(SLAVE_INT_RESPONSE_TIME); |
191 | 365 | ||
192 | // check if the slave is present | 366 | // check if the target is present |
193 | if (serial_read_pin()) { | 367 | if (serial_read_pin()) { |
194 | // slave failed to pull the line low, assume not present | 368 | // target failed to pull the line low, assume not present |
369 | serial_output(); | ||
370 | serial_high(); | ||
371 | *trans->status = TRANSACTION_NO_RESPONSE; | ||
195 | sei(); | 372 | sei(); |
196 | return 1; | 373 | return TRANSACTION_NO_RESPONSE; |
197 | } | 374 | } |
198 | 375 | ||
199 | // if the slave is present syncronize with it | 376 | #else |
200 | sync_recv(); | 377 | // send transaction table index |
201 | 378 | sync_send(); | |
202 | uint8_t checksum_computed = 0; | 379 | _delay_sub_us(TID_SEND_ADJUST); |
203 | // receive data from the slave | 380 | serial_write_chunk(sstd_index, 4); |
204 | for (int i = 0; i < SERIAL_SLAVE_BUFFER_LENGTH; ++i) { | 381 | serial_delay_half1(); |
205 | serial_slave_buffer[i] = serial_read_byte(); | 382 | |
206 | sync_recv(); | 383 | // wait for the target response (step1 low->high) |
207 | checksum_computed += serial_slave_buffer[i]; | 384 | serial_input_with_pullup(); |
385 | while( !serial_read_pin() ) { | ||
386 | _delay_sub_us(2); | ||
208 | } | 387 | } |
209 | uint8_t checksum_received = serial_read_byte(); | ||
210 | sync_recv(); | ||
211 | 388 | ||
212 | if (checksum_computed != checksum_received) { | 389 | // check if the target is present (step2 high->low) |
213 | sei(); | 390 | for( int i = 0; serial_read_pin(); i++ ) { |
214 | return 2; | 391 | if (i > SLAVE_INT_ACK_WIDTH + 1) { |
392 | // slave failed to pull the line low, assume not present | ||
393 | serial_output(); | ||
394 | serial_high(); | ||
395 | *trans->status = TRANSACTION_NO_RESPONSE; | ||
396 | sei(); | ||
397 | return TRANSACTION_NO_RESPONSE; | ||
398 | } | ||
399 | _delay_sub_us(SLAVE_INT_ACK_WIDTH_UNIT); | ||
215 | } | 400 | } |
401 | #endif | ||
216 | 402 | ||
217 | uint8_t checksum = 0; | 403 | // initiator recive phase |
218 | // send data to the slave | 404 | // if the target is present syncronize with it |
219 | for (int i = 0; i < SERIAL_MASTER_BUFFER_LENGTH; ++i) { | 405 | if( trans->target2initiator_buffer_size > 0 ) { |
220 | serial_write_byte(serial_master_buffer[i]); | 406 | if (!serial_recive_packet((uint8_t *)trans->target2initiator_buffer, |
221 | sync_recv(); | 407 | trans->target2initiator_buffer_size) ) { |
222 | checksum += serial_master_buffer[i]; | 408 | serial_output(); |
409 | serial_high(); | ||
410 | *trans->status = TRANSACTION_DATA_ERROR; | ||
411 | sei(); | ||
412 | return TRANSACTION_DATA_ERROR; | ||
413 | } | ||
414 | } | ||
415 | |||
416 | // initiator switch to output | ||
417 | change_reciver2sender(); | ||
418 | |||
419 | // initiator send phase | ||
420 | if( trans->initiator2target_buffer_size > 0 ) { | ||
421 | serial_send_packet((uint8_t *)trans->initiator2target_buffer, | ||
422 | trans->initiator2target_buffer_size); | ||
223 | } | 423 | } |
224 | serial_write_byte(checksum); | ||
225 | sync_recv(); | ||
226 | 424 | ||
227 | // always, release the line when not in use | 425 | // always, release the line when not in use |
228 | serial_output(); | 426 | sync_send(); |
229 | serial_high(); | ||
230 | 427 | ||
428 | *trans->status = TRANSACTION_END; | ||
231 | sei(); | 429 | sei(); |
232 | return 0; | 430 | return TRANSACTION_END; |
233 | } | 431 | } |
234 | 432 | ||
433 | #ifdef SERIAL_USE_MULTI_TRANSACTION | ||
434 | int soft_serial_get_and_clean_status(int sstd_index) { | ||
435 | SSTD_t *trans = &Transaction_table[sstd_index]; | ||
436 | cli(); | ||
437 | int retval = *trans->status; | ||
438 | *trans->status = 0;; | ||
439 | sei(); | ||
440 | return retval; | ||
441 | } | ||
235 | #endif | 442 | #endif |
443 | |||
444 | #endif \ No newline at end of file | ||
diff --git a/keyboards/fortitude60/serial.h b/keyboards/fortitude60/serial.h index 361f1881b..d00898055 100644 --- a/keyboards/fortitude60/serial.h +++ b/keyboards/fortitude60/serial.h | |||
@@ -1,32 +1,80 @@ | |||
1 | #ifndef MY_SERIAL_H | 1 | #ifndef SOFT_SERIAL_H |
2 | #define MY_SERIAL_H | 2 | #define SOFT_SERIAL_H |
3 | 3 | ||
4 | #include "config.h" | ||
5 | #include <stdbool.h> | 4 | #include <stdbool.h> |
6 | 5 | ||
7 | /* TODO: some defines for interrupt setup */ | 6 | // ///////////////////////////////////////////////////////////////// |
8 | #define SERIAL_PIN_DDR DDRD | 7 | // Need Soft Serial defines in serial_config.h |
9 | #define SERIAL_PIN_PORT PORTD | 8 | // ///////////////////////////////////////////////////////////////// |
10 | #define SERIAL_PIN_INPUT PIND | 9 | // ex. |
10 | // #define SERIAL_PIN_DDR DDRD | ||
11 | // #define SERIAL_PIN_PORT PORTD | ||
12 | // #define SERIAL_PIN_INPUT PIND | ||
13 | // #define SERIAL_PIN_MASK _BV(PD?) ?=0,2 | ||
14 | // #define SERIAL_PIN_INTERRUPT INT?_vect ?=0,2 | ||
15 | // | ||
16 | // //// USE Simple API (OLD API, compatible with let's split serial.c) | ||
17 | // ex. | ||
18 | // #define SERIAL_SLAVE_BUFFER_LENGTH MATRIX_ROWS/2 | ||
19 | // #define SERIAL_MASTER_BUFFER_LENGTH 1 | ||
20 | // | ||
21 | // //// USE flexible API (using multi-type transaction function) | ||
22 | // #define SERIAL_USE_MULTI_TRANSACTION | ||
23 | // | ||
24 | // ///////////////////////////////////////////////////////////////// | ||
11 | 25 | ||
12 | #ifndef USE_SERIAL_PD2 | ||
13 | #define SERIAL_PIN_MASK _BV(PD0) | ||
14 | #define SERIAL_PIN_INTERRUPT INT0_vect | ||
15 | #else | ||
16 | #define SERIAL_PIN_MASK _BV(PD2) | ||
17 | #define SERIAL_PIN_INTERRUPT INT2_vect | ||
18 | #endif | ||
19 | |||
20 | #define SERIAL_SLAVE_BUFFER_LENGTH MATRIX_ROWS/2 | ||
21 | #define SERIAL_MASTER_BUFFER_LENGTH 1 | ||
22 | 26 | ||
23 | // Buffers for master - slave communication | 27 | #ifndef SERIAL_USE_MULTI_TRANSACTION |
28 | /* --- USE Simple API (OLD API, compatible with let's split serial.c) */ | ||
29 | #if SERIAL_SLAVE_BUFFER_LENGTH > 0 | ||
24 | extern volatile uint8_t serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH]; | 30 | extern volatile uint8_t serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH]; |
31 | #endif | ||
32 | #if SERIAL_MASTER_BUFFER_LENGTH > 0 | ||
25 | extern volatile uint8_t serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH]; | 33 | extern volatile uint8_t serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH]; |
34 | #endif | ||
26 | 35 | ||
27 | void serial_master_init(void); | 36 | void serial_master_init(void); |
28 | void serial_slave_init(void); | 37 | void serial_slave_init(void); |
29 | int serial_update_buffers(void); | 38 | int serial_update_buffers(void); |
30 | bool serial_slave_data_corrupt(void); | ||
31 | 39 | ||
40 | #endif // USE Simple API | ||
41 | |||
42 | // Soft Serial Transaction Descriptor | ||
43 | typedef struct _SSTD_t { | ||
44 | uint8_t *status; | ||
45 | uint8_t initiator2target_buffer_size; | ||
46 | uint8_t *initiator2target_buffer; | ||
47 | uint8_t target2initiator_buffer_size; | ||
48 | uint8_t *target2initiator_buffer; | ||
49 | } SSTD_t; | ||
50 | |||
51 | // initiator is transaction start side | ||
52 | void soft_serial_initiator_init(SSTD_t *sstd_table); | ||
53 | // target is interrupt accept side | ||
54 | void soft_serial_target_init(SSTD_t *sstd_table); | ||
55 | |||
56 | // initiator resullt | ||
57 | #define TRANSACTION_END 0 | ||
58 | #define TRANSACTION_NO_RESPONSE 0x1 | ||
59 | #define TRANSACTION_DATA_ERROR 0x2 | ||
60 | #ifndef SERIAL_USE_MULTI_TRANSACTION | ||
61 | int soft_serial_transaction(void); | ||
62 | #else | ||
63 | int soft_serial_transaction(int sstd_index); | ||
32 | #endif | 64 | #endif |
65 | |||
66 | // target status | ||
67 | // *SSTD_t.status has | ||
68 | // initiator: | ||
69 | // TRANSACTION_END | ||
70 | // or TRANSACTION_NO_RESPONSE | ||
71 | // or TRANSACTION_DATA_ERROR | ||
72 | // target: | ||
73 | // TRANSACTION_DATA_ERROR | ||
74 | // or TRANSACTION_ACCEPTED | ||
75 | #define TRANSACTION_ACCEPTED 0x4 | ||
76 | #ifdef SERIAL_USE_MULTI_TRANSACTION | ||
77 | int soft_serial_get_and_clean_status(int sstd_index); | ||
78 | #endif | ||
79 | |||
80 | #endif /* SOFT_SERIAL_H */ \ No newline at end of file | ||
diff --git a/keyboards/fortitude60/serial_config.h b/keyboards/fortitude60/serial_config.h new file mode 100644 index 000000000..96a54afbd --- /dev/null +++ b/keyboards/fortitude60/serial_config.h | |||
@@ -0,0 +1,14 @@ | |||
1 | #ifndef SOFT_SERIAL_CONFIG_H | ||
2 | #define SOFT_SERIAL_CONFIG_H | ||
3 | |||
4 | /* Soft Serial defines */ | ||
5 | #define SERIAL_PIN_DDR DDRD | ||
6 | #define SERIAL_PIN_PORT PORTD | ||
7 | #define SERIAL_PIN_INPUT PIND | ||
8 | #define SERIAL_PIN_MASK _BV(PD2) | ||
9 | #define SERIAL_PIN_INTERRUPT INT2_vect | ||
10 | |||
11 | #define SERIAL_SLAVE_BUFFER_LENGTH MATRIX_ROWS/2 | ||
12 | #define SERIAL_MASTER_BUFFER_LENGTH 1 | ||
13 | |||
14 | #endif /* SOFT_SERIAL_CONFIG_H */ \ No newline at end of file | ||