My favorites | Sign in
Project Home Downloads Wiki Issues Source
Checkout   Browse   Changes    
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
/*
* This file is part of the Bus Pirate project (http://code.google.com/p/the-bus-pirate/).
*
* Written and maintained by the Bus Pirate project.
*
* To the extent possible under law, the project has
* waived all copyright and related or neighboring rights to Bus Pirate. This
* work is published from United States.
*
* For details see: http://creativecommons.org/publicdomain/zero/1.0/.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/

#include "base.h"
//#include "pc_at_keyboard.h"

#define KBCLK_TRIS BP_CLK_DIR
#define KBCLK BP_CLK

#define KBDIO_TRIS BP_MOSI_DIR
#define KBDIO BP_MOSI

extern struct _modeConfig modeConfig;
extern struct _command bpCommand;

#ifdef BP_USE_PCATKB

void kbSetup(void);
unsigned char kbReadBit(void);
unsigned char kbReadCode(void);
unsigned char kbReadByte(void);
unsigned char kbWriteByte(unsigned char c);
unsigned char kbWriteBit(unsigned char c);
void kbScancodeResults(unsigned char c);
unsigned char kbWaitClock(unsigned char c);

struct _kbframe{
unsigned char startbit:1;
unsigned char code;
unsigned char paritybit:1;
unsigned char stopbit:1;
unsigned char parityerror:1;
} kbScancode;


void KEYBsetup(void)
{ modeConfig.HiZ=1;//yes, always HiZ
kbSetup();
}

unsigned int KEYBread(void)
{ kbScancodeResults(kbReadByte());
return kbScancode.code;
}

unsigned int KEYBwrite(unsigned int c)
{ unsigned char temp;

temp=kbWriteByte(c);//send to bus
if(temp==0) //ack bit
{ //bpWmessage(MSG_ACK);
BPMSG1060;
}
else if (temp==1)
{ //bpWmessage(MSG_NACK);
BPMSG1061;
}
else
{ //bpWstring(OUMSG_KB_TIMEOUT);
BPMSG1237;
}
return 0x100;
}

void KEYBmacro(unsigned int c)
{ switch(c)
{ case 0: //bpWline(OUMSG_KB_MACRO_MENU);
BPMSG1238;
break;
case 1: //bpWline(OUMSG_KB__MACRO_LIVE);
BPMSG1239;
BPMSG1250;
while(1)
{ if(kbReadByte()==0)
{ bpWbyte(kbScancode.code);
bpSP;
}
if(U1STAbits.URXDA == 1) //any key pressed, exit
{ c=U1RXREG;
bpBR;
break;
}
}
break;
default: BPMSG1016;
}
}

void kbScancodeResults(unsigned char c)
{ switch(c)
{ case 0: // all ok
//bpWbyte(kbScancode.code);
//bpSP;
break;
case 1:
//bpWstring(OUMSG_KB_ERROR_STARTBIT);
BPMSG1240;
break;
case 2:
//bpWbyte(kbScancode.code);
//bpWstring(OUMSG_KB_ERROR_PARITY);
BPMSG1241;
break;
case 3:
//bpWbyte(kbScancode.code);
//bpWstring(OUMSG_KB_ERROR_STOPBIT);
BPMSG1242;
break;
case 4:
//bpWstring(OUMSG_KB_ERROR_TIMEOUT);
bpSP;
BPMSG1237;
break;
case 0xff://no data
//bpWstring(OUMSG_KB_ERROR_NONE);
BPMSG1243;
break;
default:
//bpWstring(OUMSG_KB_ERROR_UNK);
BPMSG1244;
break;
}
}

void kbSetup(void){
//writes to the PORTs write to the LATCH
KBDIO_TRIS=1;//data input
KBCLK_TRIS=0;//clock output/low
KBCLK=0; //B8 scl
KBDIO=0; //B9 sda
}


unsigned char kbReadBit(void){
unsigned char j;

if(kbWaitClock(0)!=0) return 2; //wait for clock High->LOW (ACTIVE)

j=KBDIO; //read the data pin

if(kbWaitClock(1)!=0) return 2; //wait for clock low->HIGH (IDLE)

return j;
}

//reads scancode into kbScancode structure
//returns 0 - success
//1 - startbit error
//2 - parity error
//3 - stopbit error
//4 - read bit timeout error
unsigned char kbReadCode(void){
unsigned char i, par=0,c=0, b;

//get startbit
kbScancode.startbit=KBDIO;
if(kbScancode.startbit!=0) return 1;//startbit should be 0

//while(KBCLK==0);//wait for clock HIGH (IDLE)
if(kbWaitClock(1)!=0) return 4;

//grab the eight databits LSB
for(i=0;i<8;i++){
c=c>>1;
b=kbReadBit();
if(b==2) return 4; //bit timeout
if(b==1){
c+=0b10000000;
par^=1;
}
}
kbScancode.code=c;

//get parity bit and check
b=kbReadBit();
if(b==2) return 4; //bit timeout
kbScancode.paritybit=b;
//odd parity:if these are the same, there is an error
//condense to bitwise op...
if(kbScancode.paritybit==par){
kbScancode.parityerror=1;
return 2; //error
}else{
kbScancode.parityerror=0;//ok
}

//get stopbit
b=kbReadBit();
if(b==2) return 4; //bit timeout
kbScancode.stopbit=b;//stopbit should be 1
KBCLK_TRIS=0;//set clock low again to idle keyboard
if(kbScancode.stopbit!=1) return 3;

//success!
return 0;
}

unsigned char kbReadByte(void){
unsigned char i,c=0xff;

//let clk float, clk and data will drop if there is data
KBDIO_TRIS=1;//data input
KBCLK_TRIS=1;//clock input/high (keyboard will go low if scan code ready)

for(i=0;i<255;i++){//do a loop, wait for change
//while(1){//for debugging
if(KBCLK==0){//check clock status
c=kbReadCode();//read the scancode
if(c==0 || c==4)break;//success or error, break the loop
}
bpDelayUS(5);//delay
}

//disable any further data by dropping clock line
KBCLK_TRIS=0;//set clock low again

return c;
}

//writes a bit using the KB clock signal.
// 0=success, 2=timeout
unsigned char kbWriteBit(unsigned char c){

if(kbWaitClock(1)!=0) return 2; //wait for low-high transition
KBDIO_TRIS=c;//set data direction
if(kbWaitClock(0)!=0) return 2; //wait for high-low transition
return 0; //data now entered, you have a tiny bit of time before next bit
}

//@c - byte to send
//@returns - ack bit
unsigned char kbWriteByte(unsigned char c){
unsigned char par=0;
unsigned int i;

//take clk low to own the bus
//clock should already be low
KBCLK_TRIS=0;//clock low
KBCLK=0;

bpDelayUS(60);//delay at least 1 bit period (60us), interrupt any other data transfer

//data low to signal host->kb transfer
KBDIO=0;
KBDIO_TRIS=0;//data low

//take clock high again, KB will start own clock
KBCLK_TRIS=1;//clock high/input
bpDelayUS(1);

//while(KBCLK==1);//wait for first falling edge
if(kbWaitClock(0)!=0) return 4; //timeout

//bang out the bits LSB first out using the kb clock signal
for(i=0;i<8;i++){
if((c&1)==1){
if(kbWriteBit(1)!=0)return 4;//send LSB first
par^=1;//track parity bit
}else{
if(kbWriteBit(0)!=0)return 4;//send LSB first
}
c=c>>1;//-- Shift next bit into position
}

//write parity bit
par^=1;//shift parity bit once more so it is opposite
if(kbWriteBit(par)!=0)return 4;//send parity bit

KBDIO_TRIS=1;//configure data for input
KBDIO=0;

//while(KBCLK==0);//wait for low->high transition to align with a readbit
if(kbWaitClock(1)!=0) return 4; //timeout

if(kbReadBit()==2) return 4;//junk bit (stopbit/high)
i=kbReadBit();//ack bit
if(i==2) return 4;

KBCLK_TRIS=0;//set clock low again to halt data
KBCLK=0;

return i;//return ack bit
}


unsigned char kbWaitClock(unsigned char c){
unsigned int i=0xffff;
while(1){
if(KBCLK==c)return 0; //clock changed
i--;
if(i==0)return 1;//timeout
}
}

#endif

Change log

r416 by ianlesnet on Jul 5, 2010   Diff
text updates.
Go to: 
Project members, sign in to write a code review

Older revisions

r371 by ianlesnet on Jun 10, 2010   Diff
Newterm update applied to v4.x code
branch.
r48 by ianlesnet on Oct 16, 2009   Diff
Major change to global command struct.
Will make it easier to pass new
variable to libraries in the future
without editing each individually. It
also keeps a bunch of stuff off the
...
r1 by ianlesnet on Sep 17, 2009   Diff
Reset SVN, removed non public domain
files. Adding from backup.
All revisions of this file

File info

Size: 7153 bytes, 308 lines
Powered by Google Project Hosting