]> git.donarmstrong.com Git - kiibohd-controller.git/blob - Scan/Tandy1000/scan_loop.c
a44e789389c4ee36d941e72108d4e9fc6d8cfa51
[kiibohd-controller.git] / Scan / Tandy1000 / scan_loop.c
1 /* Copyright (C) 2011 by Jacob Alexander
2  * 
3  * Permission is hereby granted, free of charge, to any person obtaining a copy
4  * of this software and associated documentation files (the "Software"), to deal
5  * in the Software without restriction, including without limitation the rights
6  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7  * copies of the Software, and to permit persons to whom the Software is
8  * furnished to do so, subject to the following conditions:
9  * 
10  * The above copyright notice and this permission notice shall be included in
11  * all copies or substantial portions of the Software.
12  * 
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19  * THE SOFTWARE.
20  */
21
22 // ----- Includes -----
23
24 // AVR Includes
25 #include <avr/interrupt.h>
26 #include <avr/io.h>
27 #include <util/delay.h>
28
29 // Project Includes
30 #include <led.h>
31 #include <print.h>
32
33 // Local Includes
34 #include "scan_loop.h"
35
36
37
38 // ----- Defines -----
39
40 // Pinout Defines
41 #define CLK_READ  PIND
42 #define CLK_PORT PORTD
43 #define CLK_DDR   DDRD
44 #define CLK_PIN      1
45
46 #define DATA_READ  PIND
47 #define DATA_PORT PORTD
48 #define DATA_DDR   DDRD
49 #define DATA_PIN      0
50
51 #define INTR_PORT PORTD
52 #define INTR_DDR   DDRD
53 #define INTR_PIN      0
54
55
56
57 // ----- Macros -----
58
59 #define READ_CLK       CLK_READ &   (1 <<  CLK_PIN) ? 1 : 0
60 #define READ_DATA     DATA_READ &   (1 << DATA_PIN) ? 0 : 1
61
62 #define UNSET_INTR()  INTR_DDR &= ~(1 << INTR_PIN)
63 #define   SET_INTR()  INTR_DDR |=  (1 << INTR_PIN)
64
65 #define bufferAdd(byte) \
66                 if ( KeyIndex_BufferUsed < KEYBOARD_BUFFER ) \
67                         KeyIndex_Buffer[KeyIndex_BufferUsed++] = byte
68
69
70 // ----- Variables -----
71
72 // Buffer used to inform the macro processing module which keys have been detected as pressed
73 volatile uint8_t KeyIndex_Buffer[KEYBOARD_BUFFER];
74 volatile uint8_t KeyIndex_BufferUsed;
75
76
77 // Scan Code Retrieval Variables
78 uint8_t inputData    = 0xFF;
79 uint8_t packet_index = 0;
80
81
82
83 // ----- Functions -----
84
85 // Setup
86 inline void scan_setup()
87 {
88         // Initially reset the keyboard (just in case we are in a wierd state)
89         scan_resetKeyboard();
90
91         // Setup SPI for data input using the clock and data inputs
92         // TODO
93         /*
94         // Setup inputs
95         CLK_DDR  &= ~(1 << CLK_PIN);
96         DATA_DDR &= ~(1 << DATA_PIN);
97
98         // Setup Pull-up's
99         CLK_PORT  &= ~(1 << CLK_PIN);  // (CLK)
100         DATA_PORT &= ~(1 << DATA_PIN); // (/DATA)
101         */
102
103         // Setup Keyboard Interrupt
104         INTR_DDR  &= ~(1 << INTR_PIN);
105         INTR_PORT &= ~(1 << INTR_PIN);
106
107         // Setup Keyboard Reset Line
108         // TODO
109 }
110
111
112 // Main Detection Loop
113 inline uint8_t scan_loop()
114 {
115         /*
116         // Packet Read
117         if ( packet_index == 8 )
118         {
119                 // Disable Error LED, proper key found
120                 errorLED( 0 );
121
122 //#ifdef MAX_DEBUG
123                 // Crazy Debug (Read the Scan Code)
124                 char tmpStr[3];
125                 hexToStr_op( inputData, tmpStr, 2 );
126                 dPrintStrsNL( "Read Data: 0x", tmpStr );
127 //#endif
128                 // - Map the scan code to the index array -
129                 // If the 8th bit is high, remove the keypress, else, add the keypress
130                 // The lower 7 bits are the array index
131                 KeyIndex_Array[(inputData & 0x7F)] = (inputData & 0x80) ? 0x00 : 0x80;
132
133                 // Reset Containers
134                 packet_index = 0;
135                 inputData = 0xFF;
136         }
137         // Bad Packet
138         else if ( packet_index > 8 )
139         {
140                 // Signal Error
141                 errorLED( 1 );
142
143                 char tmpStr[3];
144                 int8ToStr( packet_index, tmpStr );
145                 erro_dPrint( "Big packet? Mismatched... ", tmpStr );
146
147                 packet_index = 0;
148                 inputData = 0xFF;
149         }
150         */
151
152         // Disable keyboard interrupt (does nothing if already off)
153         UNSET_INTR();
154
155         // Read the clock 8 times
156         if ( READ_CLK )
157         {
158                 // Mis-read packet, set back to 0
159                 if ( packet_index == -1 )
160                         packet_index = 0;
161
162                 // Append 1 bit of data
163                 inputData &= ~(READ_DATA << packet_index);
164                 packet_index++;
165
166                 // 8 Bits have been read
167                 if ( packet_index == 8 )
168                 {
169                         // Wait till clock edge falls
170                         while ( READ_CLK );
171
172                         // Sample both lines to make sure this is not a data value
173                         //  and definitely the end of packet data blip
174                         uint16_t badDataCounter = 0;
175                         while ( !( READ_DATA ) && !( READ_CLK ) )
176                                         badDataCounter++;
177
178                         if ( badDataCounter < 25 )
179                         {
180 //#ifdef MAX_DEBUG
181                                 // Crazy Debug (Read the Scan Code)
182                                 char tmpStr[3];
183                                 hexToStr_op( inputData, tmpStr, 2 );
184                                 dbug_dPrint( "Read Data: 0x", tmpStr );
185 //#endif
186                                 // - Map the scan code to the index array -
187                                 // If the 8th bit is high, remove the keypress, else, add the keypress
188                                 // The lower 7 bits are the array index
189                                 KeyIndex_Array[(inputData & 0x7F)] = (inputData & 0x80) ? 0x00 : 0x80;
190                         }
191                         // Even though this is a mis-read packet, we still know what the value is
192                         else
193                         {
194                                 // Signal Error
195                                 errorLED( 1 );
196                                 char tmpStr[3];
197                                 hexToStr_op( inputData, tmpStr, 2 );
198                                 erro_dPrint( "Bad packet? Mismatched... 0x", tmpStr );
199                         }
200
201                         // Reset Containers
202                         inputData = 0xFF;
203                         packet_index = 0;
204
205                         // Interrupt the keyboard, so we don't get packet pieces...
206                         SET_INTR();
207
208                         // Do not wait for next clock, let USB do it's thing (if desired)
209                         return packet_index;
210                 }
211
212                 // Wait till clock edge falls
213                 while ( READ_CLK );
214         }
215
216         // Interrupt keyboard if there is no pending packet
217         SET_INTR();
218
219         return packet_index;
220 }
221
222 // Send data
223 // XXX Not used with the Tandy1000
224 uint8_t scan_sendData( uint8_t dataPayload )
225 {
226         return 0;
227 }
228
229 // Signal KeyIndex_Buffer that it has been properly read
230 // TODO
231 void scan_finishedWithBuffer( void )
232 {
233 }
234
235 // Reset/Hold keyboard
236 // Warning! This will cause the keyboard to not send any data, so you can't disable with a keypress
237 // The Tandy 1000 keyboard has a dedicated hold/processor interrupt line
238 void scan_lockKeyboard( void )
239 {
240         UNSET_INTR();
241 }
242
243 void scan_unlockKeyboard( void )
244 {
245         SET_INTR();
246 }
247
248 // Reset Keyboard
249 void scan_resetKeyboard( void )
250 {
251         // TODO Tandy1000 has a dedicated reset line
252 }
253