aboutsummaryrefslogtreecommitdiff
path: root/protocol/ps2.c
diff options
context:
space:
mode:
Diffstat (limited to 'protocol/ps2.c')
-rw-r--r--protocol/ps2.c59
1 files changed, 38 insertions, 21 deletions
diff --git a/protocol/ps2.c b/protocol/ps2.c
index e5873a9bf..4886b16d0 100644
--- a/protocol/ps2.c
+++ b/protocol/ps2.c
@@ -91,6 +91,9 @@ uint8_t ps2_error = PS2_ERR_NONE;
91 91
92void ps2_host_init(void) 92void ps2_host_init(void)
93{ 93{
94 // POR(150-2000ms) plus BAT(300-500ms) may take 2.5sec([3]p.20)
95 _delay_ms(2500);
96
94#ifdef PS2_USE_INT 97#ifdef PS2_USE_INT
95 PS2_INT_INIT(); 98 PS2_INT_INIT();
96 PS2_INT_ON(); 99 PS2_INT_ON();
@@ -163,32 +166,30 @@ ERROR:
163/* receive data when host want else inhibit communication */ 166/* receive data when host want else inhibit communication */
164uint8_t ps2_host_recv_response(void) 167uint8_t ps2_host_recv_response(void)
165{ 168{
169 // Command might take 20ms to response([3]p.21)
170 // TrackPoint might take 25ms ([5]2.7)
166 uint8_t data = 0; 171 uint8_t data = 0;
167 172 uint8_t try = 200;
168#ifdef PS2_USE_INT 173 while (try-- && (data = ps2_host_recv())) ;
169 PS2_INT_OFF(); 174 return data;
175}
170#endif 176#endif
171 /* terminate a transmission if we have */ 177
172 inhibit(); 178#ifndef PS2_USE_INT
173 _delay_us(100); 179uint8_t ps2_host_recv(void)
180{
181 uint8_t data = 0;
174 182
175 /* release lines(idle state) */ 183 /* release lines(idle state) */
176 idle(); 184 idle();
177 185
178 /* wait start bit */ 186 /* wait start bit */
179 wait_clock_lo(25000); // command response may take 20 ms at most 187 wait_clock_lo(100); // TODO: this is enough?
180 data = recv_data(); 188 data = recv_data();
181 189
182 inhibit(); 190 inhibit();
183 return data; 191 return data;
184} 192}
185#endif
186
187#ifndef PS2_USE_INT
188uint8_t ps2_host_recv(void)
189{
190 return ps2_host_recv_response();
191}
192#else 193#else
193/* ring buffer to store ps/2 key data */ 194/* ring buffer to store ps/2 key data */
194#define PBUF_SIZE 32 195#define PBUF_SIZE 32
@@ -241,13 +242,6 @@ static inline void pbuf_clear(void)
241/* get data received by interrupt */ 242/* get data received by interrupt */
242uint8_t ps2_host_recv(void) 243uint8_t ps2_host_recv(void)
243{ 244{
244 if (ps2_error) {
245 print("x");
246 phex(ps2_error);
247 ps2_host_send(0xFE); // request to resend
248 ps2_error = PS2_ERR_NONE;
249 }
250 idle();
251 return pbuf_dequeue(); 245 return pbuf_dequeue();
252} 246}
253 247
@@ -450,3 +444,26 @@ static inline void inhibit(void)
450 clock_lo(); 444 clock_lo();
451 data_hi(); 445 data_hi();
452} 446}
447
448
449/* PS/2 Resources
450 *
451 * [1] The PS/2 Mouse/Keyboard Protocol
452 * http://www.computer-engineering.org/ps2protocol/
453 * Concise and thorough primer of PS/2 protocol.
454 *
455 * [2] Keyboard and Auxiliary Device Controller
456 * http://www.mcamafia.de/pdf/ibm_hitrc07.pdf
457 * Signal Timing and Format
458 *
459 * [3] Keyboards(101- and 102-key)
460 * http://www.mcamafia.de/pdf/ibm_hitrc11.pdf
461 * Keyboard Layout, Scan Code Set, POR, and Commands.
462 *
463 * [4] PS/2 Reference Manuals
464 * http://www.mcamafia.de/pdf/ibm_hitrc07.pdf
465 * Collection of IBM Personal System/2 documents.
466 *
467 * [5] TrackPoint Engineering Specifications for version 3E
468 * https://web.archive.org/web/20100526161812/http://wwwcssrv.almaden.ibm.com/trackpoint/download.html
469 */