]> git.donarmstrong.com Git - kiibohd-controller.git/blob - Scan/HP150/scan_loop.c
Adding initial HP150 and IBMConvertible scan modules.
[kiibohd-controller.git] / Scan / HP150 / scan_loop.c
1 /* Copyright (C) 2012 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 DATA_PORT PORTC
42 #define DATA_DDR   DDRC
43 #define DATA_PIN      7
44
45 #define CLOCK_PORT PORTC
46 #define CLOCK_DDR   DDRC
47 #define CLOCK_PIN      6
48
49 #define RESET_PORT PORTF
50 #define RESET_DDR   DDRF
51 #define RESET_PIN      7
52
53
54 // ----- Macros -----
55
56 // Make sure we haven't overflowed the buffer
57 #define bufferAdd(byte) \
58                 if ( KeyIndex_BufferUsed < KEYBOARD_BUFFER ) \
59                         KeyIndex_Buffer[KeyIndex_BufferUsed++] = byte
60
61
62
63 // ----- Variables -----
64
65 // Buffer used to inform the macro processing module which keys have been detected as pressed
66 volatile uint8_t KeyIndex_Buffer[KEYBOARD_BUFFER];
67 volatile uint8_t KeyIndex_BufferUsed;
68 volatile uint8_t KeyIndex_Add_InputSignal; // Used to pass the (click/input value) to the keyboard for the clicker
69
70 volatile uint8_t currentWaveState = 0;
71
72
73 // Buffer Signals
74 volatile uint8_t BufferReadyToClear;
75
76
77
78 // ----- Function Declarations -----
79
80 void processKeyValue( uint8_t keyValue );
81 void  removeKeyValue( uint8_t keyValue );
82
83
84
85 // ----- Interrupt Functions -----
86
87 // Generates a constant external clock
88 ISR( TIMER1_COMPA_vect )
89 {
90         if ( currentWaveState )
91         {
92                 CLOCK_PORT &= ~(1 << CLOCK_PIN);
93                 currentWaveState--;
94         }
95         else
96         {
97                 CLOCK_PORT |=  (1 << CLOCK_PIN);
98                 currentWaveState++;
99         }
100 }
101
102
103
104 // ----- Functions -----
105
106 // Setup
107 inline void scan_setup()
108 {
109         // Setup Timer Pulse (16 bit)
110
111         // TODO Clock can be adjusted to whatever (read chip datasheets for limits)
112         // 16 MHz / (2 * Prescaler * (1 + OCR1A)) = 1200.1 baud
113         // Prescaler is 1
114         // Twice every 1200 baud (actually 1200.1, timer isn't accurate enough)
115         // This is close to 820 us, but a bit slower
116         cli();
117         TCCR1B = 0x09;
118         OCR1AH = 0x01;
119         OCR1AL = 0x09;
120         TIMSK1 = (1 << OCIE1A);
121         CLOCK_DDR = (1 << CLOCK_PIN);
122         sei();
123
124
125         // Initially buffer doesn't need to be cleared (it's empty...)
126         BufferReadyToClear = 0;
127
128         // InputSignal is off by default
129         KeyIndex_Add_InputSignal = 0x00;
130
131         // Reset the keyboard before scanning, we might be in a wierd state
132         scan_resetKeyboard();
133 }
134
135
136 // Main Detection Loop
137 // Since this function is non-interruptable, we can do checks here on what stage of the
138 //  output clock we are at (0 or 1)
139 // We are looking for a start of packet
140 // If detected, all subsequent bits are then logged into a variable
141 // Once the end of the packet has been detected (always the same length), decode the pressed keys
142 inline uint8_t scan_loop()
143 {
144         return 0;
145 }
146
147 void processKeyValue( uint8_t keyValue )
148 {
149         // Interpret scan code
150         switch ( keyValue )
151         {
152         case 0x00: // Break code from input?
153                 break;
154         default:
155                 // Make sure the key isn't already in the buffer
156                 for ( uint8_t c = 0; c < KeyIndex_BufferUsed + 1; c++ )
157                 {
158                         // Key isn't in the buffer yet
159                         if ( c == KeyIndex_BufferUsed )
160                         {
161                                 bufferAdd( keyValue );
162
163                                 // Only send data if enabled
164                                 if ( KeyIndex_Add_InputSignal )
165                                         scan_sendData( KeyIndex_Add_InputSignal );
166                                 break;
167                         }
168
169                         // Key already in the buffer
170                         if ( KeyIndex_Buffer[c] == keyValue )
171                                 break;
172                 }
173                 break;
174         }
175 }
176
177 void removeKeyValue( uint8_t keyValue )
178 {
179         // Check for the released key, and shift the other keys lower on the buffer
180         uint8_t c;
181         for ( c = 0; c < KeyIndex_BufferUsed; c++ )
182         {
183                 // Key to release found
184                 if ( KeyIndex_Buffer[c] == keyValue )
185                 {
186                         // Shift keys from c position
187                         for ( uint8_t k = c; k < KeyIndex_BufferUsed - 1; k++ )
188                                 KeyIndex_Buffer[k] = KeyIndex_Buffer[k + 1];
189
190                         // Decrement Buffer
191                         KeyIndex_BufferUsed--;
192
193                         break;
194                 }
195         }
196
197         // Error case (no key to release)
198         if ( c == KeyIndex_BufferUsed + 1 )
199         {
200                 errorLED( 1 );
201                 char tmpStr[6];
202                 hexToStr( keyValue, tmpStr );
203                 erro_dPrint( "Could not find key to release: ", tmpStr );
204         }
205 }
206
207 // Send data 
208 uint8_t scan_sendData( uint8_t dataPayload )
209 {
210         return 0;
211 }
212
213 // Signal KeyIndex_Buffer that it has been properly read
214 void scan_finishedWithBuffer( void )
215 {
216 }
217
218 // Signal that the keys have been properly sent over USB
219 void scan_finishedWithUSBBuffer( void )
220 {
221 }
222
223 // Reset/Hold keyboard
224 // NOTE: Does nothing with the BETKB
225 void scan_lockKeyboard( void )
226 {
227 }
228
229 // NOTE: Does nothing with the BETKB
230 void scan_unlockKeyboard( void )
231 {
232 }
233
234 // Reset Keyboard
235 void scan_resetKeyboard( void )
236 {
237         // TODO Determine the scan period, and the interval to scan each bit
238 }
239