Subversion Repositories Projects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1702 - 1
/* MAX3421E USB Host controller LCD/keyboard demonstration */
2
#include <Spi.h>
3
#include <Max3421e.h>
4
#include <Usb.h>
5
#include <Max_LCD.h>
6
 
7
/* keyboard data taken from configuration descriptor */
8
#define KBD_ADDR        1
9
#define KBD_EP          1
10
#define KBD_IF          0
11
#define EP_MAXPKTSIZE   8
12
#define EP_POLL         0x0a
13
/**/
14
//******************************************************************************
15
//  macros to identify special charaters(other than Digits and Alphabets)
16
//******************************************************************************
17
#define BANG        (0x1E)
18
#define AT          (0x1F)
19
#define POUND       (0x20)
20
#define DOLLAR      (0x21)
21
#define PERCENT     (0x22)
22
#define CAP         (0x23)
23
#define AND         (0x24)
24
#define STAR        (0x25)
25
#define OPENBKT     (0x26)
26
#define CLOSEBKT    (0x27)
27
 
28
#define RETURN      (0x28)
29
#define ESCAPE      (0x29)
30
#define BACKSPACE   (0x2A)
31
#define TAB         (0x2B)
32
#define SPACE       (0x2C)
33
#define HYPHEN      (0x2D)
34
#define EQUAL       (0x2E)
35
#define SQBKTOPEN   (0x2F)
36
#define SQBKTCLOSE  (0x30)
37
#define BACKSLASH   (0x31)
38
#define SEMICOLON   (0x33)
39
#define INVCOMMA    (0x34)
40
#define TILDE       (0x35)
41
#define COMMA       (0x36)
42
#define PERIOD      (0x37)
43
#define FRONTSLASH  (0x38)
44
#define DELETE      (0x4c)
45
/**/
46
/* Modifier masks. One for both modifiers */
47
#define SHIFT       0x22
48
#define CTRL        0x11
49
#define ALT         0x44
50
#define GUI         0x88
51
/**/
52
/* "Sticky keys */
53
#define CAPSLOCK    (0x39)
54
#define NUMLOCK     (0x53)
55
#define SCROLLLOCK  (0x47)
56
/* Sticky keys output report bitmasks */
57
#define bmNUMLOCK       0x01
58
#define bmCAPSLOCK      0x02
59
#define bmSCROLLLOCK    0x04
60
/**/
61
EP_RECORD ep_record[ 2 ];  //endpoint record structure for the keyboard
62
 
63
char buf[ 8 ] = { 0 };      //keyboard buffer
64
char old_buf[ 8 ] = { 0 };  //last poll
65
/* Sticky key state */
66
bool numLock = false;
67
bool capsLock = false;
68
bool scrollLock = false;
69
bool line = false;
70
 
71
void setup();
72
void loop();
73
 
74
MAX3421E Max;
75
USB Usb;
76
Max_LCD LCD;
77
 
78
void setup() {
79
  // set up the LCD's number of rows and columns:
80
  LCD.begin(16, 2);
81
  LCD.home();
82
  Serial.begin( 9600 );
83
  Serial.println("Start");
84
  Max.powerOn();
85
  delay( 200 );
86
}
87
 
88
void loop() {
89
    Max.Task();
90
    Usb.Task();
91
    if( Usb.getUsbTaskState() == USB_STATE_CONFIGURING ) {  //wait for addressing state
92
        kbd_init();
93
        Usb.setUsbTaskState( USB_STATE_RUNNING );
94
    }
95
    if( Usb.getUsbTaskState() == USB_STATE_RUNNING ) {  //poll the keyboard
96
        kbd_poll();
97
    }
98
}
99
/* Initialize keyboard */
100
void kbd_init( void )
101
{
102
 byte rcode = 0;  //return code
103
/**/
104
    /* Initialize data structures */
105
    ep_record[ 0 ] = *( Usb.getDevTableEntry( 0,0 ));  //copy endpoint 0 parameters
106
    ep_record[ 1 ].MaxPktSize = EP_MAXPKTSIZE;
107
    ep_record[ 1 ].Interval  = EP_POLL;
108
    ep_record[ 1 ].sndToggle = bmSNDTOG0;
109
    ep_record[ 1 ].rcvToggle = bmRCVTOG0;
110
    Usb.setDevTableEntry( 1, ep_record );              //plug kbd.endpoint parameters to devtable
111
    /* Configure device */
112
    rcode = Usb.setConf( KBD_ADDR, 0, 1 );
113
    if( rcode ) {
114
        Serial.print("Error attempting to configure keyboard. Return code :");
115
        Serial.println( rcode, HEX );
116
        while(1);  //stop
117
    }
118
    /* Set boot protocol */
119
    rcode = Usb.setProto( KBD_ADDR, 0, 0, 0 );
120
    if( rcode ) {
121
        Serial.print("Error attempting to configure boot protocol. Return code :");
122
        Serial.println( rcode, HEX );
123
        while( 1 );  //stop
124
    }
125
    LCD.print("Keyboard initialized");
126
    delay(2000);
127
    LCD.clear();
128
    LCD.home();
129
    Serial.println("Keyboard initialized");
130
}
131
 
132
/* Poll keyboard and print result */
133
/* buffer starts at position 2, 0 is modifier key state and 1 is irrelevant */
134
void kbd_poll( void )
135
{
136
 char i;
137
 static char leds = 0;
138
 byte rcode = 0;     //return code
139
    /* poll keyboard */
140
    rcode = Usb.inTransfer( KBD_ADDR, KBD_EP, 8, buf );
141
    if( rcode != 0 ) {
142
        return;
143
    }//if ( rcode..
144
    for( i = 2; i < 8; i++ ) {
145
     if( buf[ i ] == 0 ) {  //end of non-empty space
146
        break;
147
     }
148
      if( buf_compare( buf[ i ] ) == false ) {   //if new key
149
        switch( buf[ i ] ) {
150
          case CAPSLOCK:
151
            capsLock =! capsLock;
152
            leds = ( capsLock ) ? leds |= bmCAPSLOCK : leds &= ~bmCAPSLOCK;       // set or clear bit 1 of LED report byte
153
            break;
154
          case NUMLOCK:
155
            numLock =! numLock;
156
            leds = ( numLock ) ? leds |= bmNUMLOCK : leds &= ~bmNUMLOCK;           // set or clear bit 0 of LED report byte
157
            break;
158
          case SCROLLLOCK:
159
            scrollLock =! scrollLock;
160
            leds = ( scrollLock ) ? leds |= bmSCROLLLOCK : leds &= ~bmSCROLLLOCK;   // set or clear bit 2 of LED report byte
161
            break;
162
          case DELETE:
163
            LCD.clear();
164
            LCD.home();
165
            line = false;
166
            break;
167
          case RETURN:
168
            line =! line;
169
            LCD.setCursor( 0, line );
170
            break;
171
          default:
172
            //LCD.print("A");                          //output
173
            LCD.print( HIDtoA( buf[ i ], buf[ 0 ] ));
174
            Serial.print(HIDtoA( buf[ i ], buf[ 0 ] ));
175
            break;
176
        }//switch( buf[ i ...
177
        rcode = Usb.setReport( KBD_ADDR, 0, 1, KBD_IF, 0x02, 0, &leds );
178
        if( rcode ) {
179
          Serial.print("Set report error: ");
180
          Serial.println( rcode, HEX );
181
        }//if( rcode ...
182
     }//if( buf_compare( buf[ i ] ) == false ...
183
    }//for( i = 2...
184
    for( i = 2; i < 8; i++ ) {                    //copy new buffer to old
185
      old_buf[ i ] = buf[ i ];
186
    }
187
}
188
/* compare byte against bytes in old buffer */
189
bool buf_compare( byte data )
190
{
191
 char i;
192
 for( i = 2; i < 8; i++ ) {
193
   if( old_buf[ i ] == data ) {
194
     return( true );
195
   }
196
 }
197
 return( false );
198
}
199
 
200
/* HID to ASCII converter. Takes HID keyboard scancode, returns ASCII code */
201
byte HIDtoA( byte HIDbyte, byte mod )
202
{
203
  /* upper row of the keyboard, numbers and special symbols */
204
  if( HIDbyte >= 0x1e && HIDbyte <= 0x27 ) {
205
    if(( mod & SHIFT ) || numLock ) {    //shift key pressed
206
      switch( HIDbyte ) {
207
        case BANG:  return( 0x21 );
208
        case AT:    return( 0x40 );
209
        case POUND: return( 0x23 );
210
        case DOLLAR: return( 0x24 );
211
        case PERCENT: return( 0x25 );
212
        case CAP: return( 0x5e );
213
        case AND: return( 0x26 );
214
        case STAR: return( 0x2a );
215
        case OPENBKT: return( 0x28 );
216
        case CLOSEBKT: return( 0x29 );
217
      }//switch( HIDbyte...
218
    }
219
    else {                  //numbers
220
      if( HIDbyte == 0x27 ) {  //zero
221
        return( 0x30 );
222
      }
223
      else {
224
        return( HIDbyte + 0x13 );
225
      }
226
    }//numbers
227
  }//if( HIDbyte >= 0x1e && HIDbyte <= 0x27
228
  /**/
229
  /* number pad. Arrows are not supported */
230
  if(( HIDbyte >= 0x59 && HIDbyte <= 0x61 ) && ( numLock == true )) {  // numbers 1-9
231
    return( HIDbyte - 0x28 );
232
  }
233
  if(( HIDbyte == 0x62 ) && ( numLock == true )) {                      //zero
234
    return( 0x30 );
235
  }
236
  /* Letters a-z */
237
  if( HIDbyte >= 0x04 && HIDbyte <= 0x1d ) {
238
    if((( capsLock == true ) && ( mod & SHIFT ) == 0 ) || (( capsLock == false ) && ( mod & SHIFT ))) {  //upper case
239
      return( HIDbyte + 0x3d );
240
    }
241
    else {  //lower case
242
      return( HIDbyte + 0x5d );
243
    }
244
  }//if( HIDbyte >= 0x04 && HIDbyte <= 0x1d...
245
  /* Other special symbols */
246
  if( HIDbyte >= 0x2c && HIDbyte <= 0x38 ) {
247
    switch( HIDbyte ) {
248
      case SPACE: return( 0x20 );
249
      case HYPHEN:
250
        if(( mod & SHIFT ) == false ) {
251
         return( 0x2d );
252
        }
253
        else {
254
          return( 0x5f );
255
        }
256
      case EQUAL:
257
       if(( mod & SHIFT ) == false ) {
258
        return( 0x3d );
259
       }
260
       else {
261
        return( 0x2b );
262
       }
263
       case SQBKTOPEN:
264
         if(( mod & SHIFT ) == false ) {
265
          return( 0x5b );
266
         }
267
         else {
268
          return( 0x7b );
269
         }
270
       case SQBKTCLOSE:
271
         if(( mod & SHIFT ) == false ) {
272
          return( 0x5d );
273
         }
274
         else {
275
          return( 0x7d );
276
         }
277
       case BACKSLASH:
278
         if(( mod & SHIFT ) == false ) {
279
           return( 0x5c );
280
         }
281
         else {
282
           return( 0x7c );
283
         }
284
       case SEMICOLON:
285
         if(( mod & SHIFT ) == false ) {
286
           return( 0x3b );
287
         }
288
         else {
289
           return( 0x3a );
290
         }
291
      case INVCOMMA:
292
        if(( mod & SHIFT ) == false ) {
293
          return( 0x27 );
294
        }
295
        else {
296
          return( 0x22 );
297
        }
298
      case TILDE:
299
        if(( mod & SHIFT ) == false ) {
300
          return( 0x60 );
301
        }
302
        else {
303
          return( 0x7e );
304
        }
305
      case COMMA:
306
        if(( mod & SHIFT ) == false ) {
307
          return( 0x2c );
308
        }
309
        else {
310
          return( 0x3c );
311
        }
312
      case PERIOD:
313
        if(( mod & SHIFT ) == false ) {
314
          return( 0x2e );
315
        }
316
        else {
317
          return( 0x3e );
318
        }
319
      case FRONTSLASH:
320
        if(( mod & SHIFT ) == false ) {
321
          return( 0x2f );
322
        }
323
        else {
324
          return( 0x3f );
325
        }
326
      default:
327
        break;
328
    }//switch( HIDbyte..
329
  }//if( HIDbye >= 0x2d && HIDbyte <= 0x38..
330
  return( 0 );
331
}
332
 
333
 
334
 
335