aboutsummaryrefslogtreecommitdiff
path: root/tmk_core/protocol/ps2_interrupt.c
diff options
context:
space:
mode:
Diffstat (limited to 'tmk_core/protocol/ps2_interrupt.c')
-rw-r--r--tmk_core/protocol/ps2_interrupt.c91
1 files changed, 80 insertions, 11 deletions
diff --git a/tmk_core/protocol/ps2_interrupt.c b/tmk_core/protocol/ps2_interrupt.c
index 5afc8a82e..780040d15 100644
--- a/tmk_core/protocol/ps2_interrupt.c
+++ b/tmk_core/protocol/ps2_interrupt.c
@@ -40,11 +40,19 @@ POSSIBILITY OF SUCH DAMAGE.
40 */ 40 */
41 41
42#include <stdbool.h> 42#include <stdbool.h>
43#include <avr/interrupt.h> 43
44#include <util/delay.h> 44#if defined(__AVR__)
45# include <avr/interrupt.h>
46#elif defined(PROTOCOL_CHIBIOS) // TODO: or STM32 ?
47// chibiOS headers
48# include "ch.h"
49# include "hal.h"
50#endif
51
45#include "ps2.h" 52#include "ps2.h"
46#include "ps2_io.h" 53#include "ps2_io.h"
47#include "print.h" 54#include "print.h"
55#include "wait.h"
48 56
49#define WAIT(stat, us, err) \ 57#define WAIT(stat, us, err) \
50 do { \ 58 do { \
@@ -61,12 +69,30 @@ static inline void pbuf_enqueue(uint8_t data);
61static inline bool pbuf_has_data(void); 69static inline bool pbuf_has_data(void);
62static inline void pbuf_clear(void); 70static inline void pbuf_clear(void);
63 71
72#if defined(PROTOCOL_CHIBIOS)
73void ps2_interrupt_service_routine(void);
74void palCallback(void *arg) { ps2_interrupt_service_routine(); }
75
76# define PS2_INT_INIT() \
77 { palSetLineMode(PS2_CLOCK, PAL_MODE_INPUT); } \
78 while (0)
79# define PS2_INT_ON() \
80 { \
81 palEnableLineEvent(PS2_CLOCK, PAL_EVENT_MODE_FALLING_EDGE); \
82 palSetLineCallback(PS2_CLOCK, palCallback, NULL); \
83 } \
84 while (0)
85# define PS2_INT_OFF() \
86 { palDisableLineEvent(PS2_CLOCK); } \
87 while (0)
88#endif // PROTOCOL_CHIBIOS
89
64void ps2_host_init(void) { 90void ps2_host_init(void) {
65 idle(); 91 idle();
66 PS2_INT_INIT(); 92 PS2_INT_INIT();
67 PS2_INT_ON(); 93 PS2_INT_ON();
68 // POR(150-2000ms) plus BAT(300-500ms) may take 2.5sec([3]p.20) 94 // POR(150-2000ms) plus BAT(300-500ms) may take 2.5sec([3]p.20)
69 //_delay_ms(2500); 95 // wait_ms(2500);
70} 96}
71 97
72uint8_t ps2_host_send(uint8_t data) { 98uint8_t ps2_host_send(uint8_t data) {
@@ -77,7 +103,7 @@ uint8_t ps2_host_send(uint8_t data) {
77 103
78 /* terminate a transmission if we have */ 104 /* terminate a transmission if we have */
79 inhibit(); 105 inhibit();
80 _delay_us(100); // 100us [4]p.13, [5]p.50 106 wait_us(100); // 100us [4]p.13, [5]p.50
81 107
82 /* 'Request to Send' and Start bit */ 108 /* 'Request to Send' and Start bit */
83 data_lo(); 109 data_lo();
@@ -86,7 +112,6 @@ uint8_t ps2_host_send(uint8_t data) {
86 112
87 /* Data bit[2-9] */ 113 /* Data bit[2-9] */
88 for (uint8_t i = 0; i < 8; i++) { 114 for (uint8_t i = 0; i < 8; i++) {
89 _delay_us(15);
90 if (data & (1 << i)) { 115 if (data & (1 << i)) {
91 parity = !parity; 116 parity = !parity;
92 data_hi(); 117 data_hi();
@@ -98,7 +123,7 @@ uint8_t ps2_host_send(uint8_t data) {
98 } 123 }
99 124
100 /* Parity bit */ 125 /* Parity bit */
101 _delay_us(15); 126 wait_us(15);
102 if (parity) { 127 if (parity) {
103 data_hi(); 128 data_hi();
104 } else { 129 } else {
@@ -108,7 +133,7 @@ uint8_t ps2_host_send(uint8_t data) {
108 WAIT(clock_lo, 50, 5); 133 WAIT(clock_lo, 50, 5);
109 134
110 /* Stop bit */ 135 /* Stop bit */
111 _delay_us(15); 136 wait_us(15);
112 data_hi(); 137 data_hi();
113 138
114 /* Ack */ 139 /* Ack */
@@ -132,7 +157,7 @@ uint8_t ps2_host_recv_response(void) {
132 // Command may take 25ms/20ms at most([5]p.46, [3]p.21) 157 // Command may take 25ms/20ms at most([5]p.46, [3]p.21)
133 uint8_t retry = 25; 158 uint8_t retry = 25;
134 while (retry-- && !pbuf_has_data()) { 159 while (retry-- && !pbuf_has_data()) {
135 _delay_ms(1); 160 wait_ms(1);
136 } 161 }
137 return pbuf_dequeue(); 162 return pbuf_dequeue();
138} 163}
@@ -148,7 +173,7 @@ uint8_t ps2_host_recv(void) {
148 } 173 }
149} 174}
150 175
151ISR(PS2_INT_VECT) { 176void ps2_interrupt_service_routine(void) {
152 static enum { 177 static enum {
153 INIT, 178 INIT,
154 START, 179 START,
@@ -218,6 +243,10 @@ RETURN:
218 return; 243 return;
219} 244}
220 245
246#if defined(__AVR__)
247ISR(PS2_INT_VECT) { ps2_interrupt_service_routine(); }
248#endif
249
221/* send LED state to keyboard */ 250/* send LED state to keyboard */
222void ps2_host_set_led(uint8_t led) { 251void ps2_host_set_led(uint8_t led) {
223 ps2_host_send(0xED); 252 ps2_host_send(0xED);
@@ -232,8 +261,13 @@ static uint8_t pbuf[PBUF_SIZE];
232static uint8_t pbuf_head = 0; 261static uint8_t pbuf_head = 0;
233static uint8_t pbuf_tail = 0; 262static uint8_t pbuf_tail = 0;
234static inline void pbuf_enqueue(uint8_t data) { 263static inline void pbuf_enqueue(uint8_t data) {
264#if defined(__AVR__)
235 uint8_t sreg = SREG; 265 uint8_t sreg = SREG;
236 cli(); 266 cli();
267#elif defined(PROTOCOL_CHIBIOS)
268 chSysLockFromISR();
269#endif
270
237 uint8_t next = (pbuf_head + 1) % PBUF_SIZE; 271 uint8_t next = (pbuf_head + 1) % PBUF_SIZE;
238 if (next != pbuf_tail) { 272 if (next != pbuf_tail) {
239 pbuf[pbuf_head] = data; 273 pbuf[pbuf_head] = data;
@@ -241,31 +275,66 @@ static inline void pbuf_enqueue(uint8_t data) {
241 } else { 275 } else {
242 print("pbuf: full\n"); 276 print("pbuf: full\n");
243 } 277 }
278
279#if defined(__AVR__)
244 SREG = sreg; 280 SREG = sreg;
281#elif defined(PROTOCOL_CHIBIOS)
282 chSysUnlockFromISR();
283#endif
245} 284}
246static inline uint8_t pbuf_dequeue(void) { 285static inline uint8_t pbuf_dequeue(void) {
247 uint8_t val = 0; 286 uint8_t val = 0;
248 287
288#if defined(__AVR__)
249 uint8_t sreg = SREG; 289 uint8_t sreg = SREG;
250 cli(); 290 cli();
291#elif defined(PROTOCOL_CHIBIOS)
292 chSysLock();
293#endif
294
251 if (pbuf_head != pbuf_tail) { 295 if (pbuf_head != pbuf_tail) {
252 val = pbuf[pbuf_tail]; 296 val = pbuf[pbuf_tail];
253 pbuf_tail = (pbuf_tail + 1) % PBUF_SIZE; 297 pbuf_tail = (pbuf_tail + 1) % PBUF_SIZE;
254 } 298 }
299
300#if defined(__AVR__)
255 SREG = sreg; 301 SREG = sreg;
302#elif defined(PROTOCOL_CHIBIOS)
303 chSysUnlock();
304#endif
256 305
257 return val; 306 return val;
258} 307}
259static inline bool pbuf_has_data(void) { 308static inline bool pbuf_has_data(void) {
309#if defined(__AVR__)
260 uint8_t sreg = SREG; 310 uint8_t sreg = SREG;
261 cli(); 311 cli();
312#elif defined(PROTOCOL_CHIBIOS)
313 chSysLock();
314#endif
315
262 bool has_data = (pbuf_head != pbuf_tail); 316 bool has_data = (pbuf_head != pbuf_tail);
263 SREG = sreg; 317
318#if defined(__AVR__)
319 SREG = sreg;
320#elif defined(PROTOCOL_CHIBIOS)
321 chSysUnlock();
322#endif
264 return has_data; 323 return has_data;
265} 324}
266static inline void pbuf_clear(void) { 325static inline void pbuf_clear(void) {
326#if defined(__AVR__)
267 uint8_t sreg = SREG; 327 uint8_t sreg = SREG;
268 cli(); 328 cli();
329#elif defined(PROTOCOL_CHIBIOS)
330 chSysLock();
331#endif
332
269 pbuf_head = pbuf_tail = 0; 333 pbuf_head = pbuf_tail = 0;
270 SREG = sreg; 334
335#if defined(__AVR__)
336 SREG = sreg;
337#elif defined(PROTOCOL_CHIBIOS)
338 chSysUnlock();
339#endif
271} 340}