]> git.donarmstrong.com Git - kiibohd-controller.git/blob - Scan/Kaypro1/scan_loop.c
Initial commit of the Kaypro1 scan module
[kiibohd-controller.git] / Scan / Kaypro1 / 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
28 // Project Includes
29 #include <led.h>
30 #include <print.h>
31
32 // Local Includes
33 #include "scan_loop.h"
34
35
36
37 // ----- Defines -----
38
39
40
41 // ----- Macros -----
42
43
44
45 // ----- Variables -----
46
47 uint8_t KeyIndex_Array[KEYBOARD_SIZE + 1];
48
49
50 // Known signals
51 static uint8_t cmd_clickOFF  = 0x0A; // Short beep, turns off clicker
52 static uint8_t cmd_clickON   = 0x04; // Long beep, turns on clicker
53 static uint8_t cmd_ACK_AA    = 0x10; // Keyboard will send ack (0xAA) back to PC
54
55 // Other known signals
56 // 0x02 turns on clicker but with short beep
57
58
59
60 // ----- Functions -----
61
62 // Setup
63 inline void scan_setup()
64 {
65         // Setup the the USART interface for keyboard data input
66         
67         // Setup baud rate
68         // 16 MHz / ( 16 * Baud ) = UBRR
69         // Baud <- 3.358 ms per bit, thus 1000 / 3.358 = 297.80
70         // Thus baud = 3357
71         uint16_t baud = 3357; // Max setting of 4095
72         UBRR1H = (uint8_t)(baud >> 8);
73         UBRR1L = (uint8_t)baud;
74
75         // Enable the receiver, transitter, and RX Complete Interrupt
76         UCSR1B = 0x98;
77
78         // Set frame format: 8 data, no stop bits or parity
79         // Asynchrounous USART mode
80         // Kaypro sends ASCII codes (mostly standard) with 1 start bit and 8 data bits, with no trailing stop or parity bits
81         UCSR1C = 0x06;
82 }
83
84
85 // Main Detection Loop
86 inline uint8_t scan_loop()
87 {
88         /*
89         // Packet Read
90         if ( packet_index == 8 )
91         {
92                 // Disable Error LED, proper key found
93                 errorLED( 0 );
94
95 //#ifdef MAX_DEBUG
96                 // Crazy Debug (Read the Scan Code)
97                 char tmpStr[3];
98                 hexToStr_op( inputData, tmpStr, 2 );
99                 dPrintStrsNL( "Read Data: 0x", tmpStr );
100 //#endif
101                 // - Map the scan code to the index array -
102                 // If the 8th bit is high, remove the keypress, else, add the keypress
103                 // The lower 7 bits are the array index
104                 KeyIndex_Array[(inputData & 0x7F)] = (inputData & 0x80) ? 0x00 : 0x80;
105
106                 // Reset Containers
107                 packet_index = 0;
108                 inputData = 0xFF;
109         }
110         // Bad Packet
111         else if ( packet_index > 8 )
112         {
113                 // Signal Error
114                 errorLED( 1 );
115
116                 char tmpStr[3];
117                 int8ToStr( packet_index, tmpStr );
118                 erro_dPrint( "Big packet? Mismatched... ", tmpStr );
119
120                 packet_index = 0;
121                 inputData = 0xFF;
122         }
123         */
124         /*
125         // Disable keyboard interrupt (does nothing if already off)
126         UNSET_INTR();
127
128         // Read the clock 8 times
129         if ( READ_CLK )
130         {
131                 // Mis-read packet, set back to 0
132                 if ( packet_index == -1 )
133                         packet_index = 0;
134
135                 // Append 1 bit of data
136                 inputData &= ~(READ_DATA << packet_index);
137                 packet_index++;
138
139                 // 8 Bits have been read
140                 if ( packet_index == 8 )
141                 {
142                         // Wait till clock edge falls
143                         while ( READ_CLK );
144
145                         // Sample both lines to make sure this is not a data value
146                         //  and definitely the end of packet data blip
147                         uint16_t badDataCounter = 0;
148                         while ( !( READ_DATA ) && !( READ_CLK ) )
149                                         badDataCounter++;
150
151                         if ( badDataCounter < 25 )
152                         {
153 //#ifdef MAX_DEBUG
154                                 // Crazy Debug (Read the Scan Code)
155                                 char tmpStr[3];
156                                 hexToStr_op( inputData, tmpStr, 2 );
157                                 dbug_dPrint( "Read Data: 0x", tmpStr );
158 //#endif
159                                 // - Map the scan code to the index array -
160                                 // If the 8th bit is high, remove the keypress, else, add the keypress
161                                 // The lower 7 bits are the array index
162                                 KeyIndex_Array[(inputData & 0x7F)] = (inputData & 0x80) ? 0x00 : 0x80;
163                         }
164                         // Even though this is a mis-read packet, we still know what the value is
165                         else
166                         {
167                                 // Signal Error
168                                 errorLED( 1 );
169                                 char tmpStr[3];
170                                 hexToStr_op( inputData, tmpStr, 2 );
171                                 erro_dPrint( "Bad packet? Mismatched... 0x", tmpStr );
172                         }
173
174                         // Reset Containers
175                         inputData = 0xFF;
176                         packet_index = 0;
177
178                         // Interrupt the keyboard, so we don't get packet pieces...
179                         SET_INTR();
180
181                         // Do not wait for next clock, let USB do it's thing (if desired)
182                         return packet_index;
183                 }
184
185                 // Wait till clock edge falls
186                 while ( READ_CLK );
187         }
188
189         // Interrupt keyboard if there is no pending packet
190         SET_INTR();
191         */
192         return 0;
193 }
194
195 // USART Receive Buffer Full Interrupt
196 ISR(USART1_RX_vect)
197 {
198         cli(); // Disable Interrupts
199
200         uint8_t keyValue = UDR1;
201         char tmpStr1[6];
202         hexToStr( keyValue, tmpStr1 );
203         dPrintStrs( tmpStr1, " " );
204
205         // Special keys - For communication to the keyboard
206         // TODO Try to push this functionality into the macros...somehow
207         switch ( keyValue )
208         {
209         case 0xC3: // Keypad Enter
210                 print("\n");
211                 info_print("BEEEEP! - Clicker on");
212                 UDR1 = cmd_clickON;
213                 break;
214
215         case 0xB2: // Keypad Decimal
216                 print("\n");
217                 info_print("BEEP! - Clicker off");
218                 UDR1 = cmd_clickOFF;
219                 break;
220
221         case 0x0A: // Line Feed
222                 print("\n");
223                 info_print("ACK!!");
224                 UDR1 = cmd_ACK_AA;
225                 break;
226         }
227
228         // Add key to processing buffer
229
230         sei(); // Re-enable Interrupts
231 }
232