diff options
Diffstat (limited to 'tmk_core/protocol/xt_interrupt.c')
-rw-r--r-- | tmk_core/protocol/xt_interrupt.c | 166 |
1 files changed, 0 insertions, 166 deletions
diff --git a/tmk_core/protocol/xt_interrupt.c b/tmk_core/protocol/xt_interrupt.c deleted file mode 100644 index ba9d71848..000000000 --- a/tmk_core/protocol/xt_interrupt.c +++ /dev/null | |||
@@ -1,166 +0,0 @@ | |||
1 | /* | ||
2 | Copyright 2018 Jun WAKO <wakojun@gmail.com> | ||
3 | Copyright 2016 Ethan Apodaca <papodaca@gmail.com> | ||
4 | |||
5 | This software is licensed with a Modified BSD License. | ||
6 | All of this is supposed to be Free Software, Open Source, DFSG-free, | ||
7 | GPL-compatible, and OK to use in both free and proprietary applications. | ||
8 | Additions and corrections to this file are welcome. | ||
9 | |||
10 | |||
11 | Redistribution and use in source and binary forms, with or without | ||
12 | modification, are permitted provided that the following conditions are met: | ||
13 | |||
14 | * Redistributions of source code must retain the above copyright | ||
15 | notice, this list of conditions and the following disclaimer. | ||
16 | |||
17 | * Redistributions in binary form must reproduce the above copyright | ||
18 | notice, this list of conditions and the following disclaimer in | ||
19 | the documentation and/or other materials provided with the | ||
20 | distribution. | ||
21 | |||
22 | * Neither the name of the copyright holders nor the names of | ||
23 | contributors may be used to endorse or promote products derived | ||
24 | from this software without specific prior written permission. | ||
25 | |||
26 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
27 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
28 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
29 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
30 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
31 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
32 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
33 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
34 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
35 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
36 | POSSIBILITY OF SUCH DAMAGE. | ||
37 | */ | ||
38 | |||
39 | #include <stdbool.h> | ||
40 | #include <avr/interrupt.h> | ||
41 | #include "xt.h" | ||
42 | #include "wait.h" | ||
43 | #include "debug.h" | ||
44 | |||
45 | static inline uint8_t pbuf_dequeue(void); | ||
46 | static inline void pbuf_enqueue(uint8_t data); | ||
47 | static inline bool pbuf_has_data(void); | ||
48 | static inline void pbuf_clear(void); | ||
49 | |||
50 | void xt_host_init(void) { | ||
51 | XT_INT_INIT(); | ||
52 | XT_INT_OFF(); | ||
53 | |||
54 | /* hard reset */ | ||
55 | #ifdef XT_RESET | ||
56 | XT_RESET(); | ||
57 | #endif | ||
58 | |||
59 | /* soft reset: pull clock line down for 20ms */ | ||
60 | XT_DATA_LO(); | ||
61 | XT_CLOCK_LO(); | ||
62 | wait_ms(20); | ||
63 | |||
64 | /* input mode with pullup */ | ||
65 | XT_CLOCK_IN(); | ||
66 | XT_DATA_IN(); | ||
67 | |||
68 | XT_INT_ON(); | ||
69 | } | ||
70 | |||
71 | /* get data received by interrupt */ | ||
72 | uint8_t xt_host_recv(void) { | ||
73 | if (pbuf_has_data()) { | ||
74 | return pbuf_dequeue(); | ||
75 | } else { | ||
76 | return 0; | ||
77 | } | ||
78 | } | ||
79 | |||
80 | ISR(XT_INT_VECT) { | ||
81 | /* | ||
82 | * XT signal format consits of 10 or 9 clocks and sends start bits and 8-bit data, | ||
83 | * which should be read on falling edge of clock. | ||
84 | * | ||
85 | * start(0), start(1), bit0, bit1, bit2, bit3, bit4, bit5, bit6, bit7 | ||
86 | * | ||
87 | * Original IBM XT keyboard sends start(0) bit while some of clones don't. | ||
88 | * Start(0) bit is read as low on data line while start(1) as high. | ||
89 | * | ||
90 | * https://github.com/tmk/tmk_keyboard/wiki/IBM-PC-XT-Keyboard-Protocol | ||
91 | */ | ||
92 | static enum { START, BIT0, BIT1, BIT2, BIT3, BIT4, BIT5, BIT6, BIT7 } state = START; | ||
93 | static uint8_t data = 0; | ||
94 | |||
95 | uint8_t dbit = XT_DATA_READ(); | ||
96 | |||
97 | // This is needed if using PCINT which can be called on both falling and rising edge | ||
98 | // if (XT_CLOCK_READ()) return; | ||
99 | |||
100 | switch (state) { | ||
101 | case START: | ||
102 | // ignore start(0) bit | ||
103 | if (!dbit) return; | ||
104 | break; | ||
105 | case BIT0 ... BIT7: | ||
106 | data >>= 1; | ||
107 | if (dbit) data |= 0x80; | ||
108 | break; | ||
109 | } | ||
110 | if (state++ == BIT7) { | ||
111 | pbuf_enqueue(data); | ||
112 | state = START; | ||
113 | data = 0; | ||
114 | } | ||
115 | return; | ||
116 | } | ||
117 | |||
118 | /*-------------------------------------------------------------------- | ||
119 | * Ring buffer to store scan codes from keyboard | ||
120 | *------------------------------------------------------------------*/ | ||
121 | #define PBUF_SIZE 32 | ||
122 | static uint8_t pbuf[PBUF_SIZE]; | ||
123 | static uint8_t pbuf_head = 0; | ||
124 | static uint8_t pbuf_tail = 0; | ||
125 | |||
126 | static inline void pbuf_enqueue(uint8_t data) { | ||
127 | uint8_t sreg = SREG; | ||
128 | cli(); | ||
129 | uint8_t next = (pbuf_head + 1) % PBUF_SIZE; | ||
130 | if (next != pbuf_tail) { | ||
131 | pbuf[pbuf_head] = data; | ||
132 | pbuf_head = next; | ||
133 | } else { | ||
134 | dprintf("pbuf: full\n"); | ||
135 | } | ||
136 | SREG = sreg; | ||
137 | } | ||
138 | |||
139 | static inline uint8_t pbuf_dequeue(void) { | ||
140 | uint8_t val = 0; | ||
141 | |||
142 | uint8_t sreg = SREG; | ||
143 | cli(); | ||
144 | if (pbuf_head != pbuf_tail) { | ||
145 | val = pbuf[pbuf_tail]; | ||
146 | pbuf_tail = (pbuf_tail + 1) % PBUF_SIZE; | ||
147 | } | ||
148 | SREG = sreg; | ||
149 | |||
150 | return val; | ||
151 | } | ||
152 | |||
153 | static inline bool pbuf_has_data(void) { | ||
154 | uint8_t sreg = SREG; | ||
155 | cli(); | ||
156 | bool has_data = (pbuf_head != pbuf_tail); | ||
157 | SREG = sreg; | ||
158 | return has_data; | ||
159 | } | ||
160 | |||
161 | static inline void pbuf_clear(void) { | ||
162 | uint8_t sreg = SREG; | ||
163 | cli(); | ||
164 | pbuf_head = pbuf_tail = 0; | ||
165 | SREG = sreg; | ||
166 | } | ||