OSDN Git Service

Update lejos_osek to nxtOSEK_v205b0.zip
[nxt-jsp/etrobo-atk.git] / nxtOSEK / lejos_nxj / src / nxtvm / platform / nxt / udp.c
1
2 #include "mytypes.h"
3 #include "udp.h"
4 #include "interrupts.h"
5 #include "at91sam7s256.h"
6
7 #include "aic.h"
8 #include "systick.h"
9 #include "display.h"
10
11 #define EP_OUT  1
12 #define EP_IN   2
13
14 #define AT91C_PERIPHERAL_ID_UDP         11
15
16 #define AT91C_UDP_CSR0  ((AT91_REG *)   0xFFFB0030) 
17 #define AT91C_UDP_CSR1  ((AT91_REG *)   0xFFFB0034) 
18 #define AT91C_UDP_CSR2  ((AT91_REG *)   0xFFFB0038) 
19 #define AT91C_UDP_CSR3  ((AT91_REG *)   0xFFFB003C)
20
21 #define AT91C_UDP_FDR0  ((AT91_REG *)   0xFFFB0050) 
22 #define AT91C_UDP_FDR1  ((AT91_REG *)   0xFFFB0054) 
23 #define AT91C_UDP_FDR2  ((AT91_REG *)   0xFFFB0058) 
24 #define AT91C_UDP_FDR3  ((AT91_REG *)   0xFFFB005C) 
25
26 static U8 currentConfig;
27 static unsigned currentConnection;
28 static unsigned currentRxBank;
29 static unsigned usbTimeOut;
30
31 // Device descriptor
32 static const U8 dd[] = {
33   0x12, 
34   0x01,
35   0x00,
36   0x02,
37   0x00,
38   0x00,
39   0x00, 
40   0x08,
41   0x94,
42   0x06,
43   0x02,
44   0x00,
45   0x00,
46   0x00,
47   0x00, 
48   0x00, 
49   0x01,
50   0x01  
51 };
52
53 // Configuration descriptor
54 static const U8 cfd[] = {
55   0x09,
56   0x02,
57   0x20,
58   0x00, 
59   0x01,
60   0x01, 
61   0x00,
62   0xC0,
63   0x00,
64   0x09,
65   0x04,
66   0x00,
67   0x00,
68   0x02,
69   0xFF, 
70   0xFF,
71   0xFF,
72   0x00,
73   0x07, 
74   0x05,
75   0x01,
76   0x02,
77   64,
78   0x00,
79   0x00, 
80   0x07,
81   0x05,
82   0x82,
83   0x02,
84   64,
85   0x00,
86   0x00};
87
88 // Serial Number Descriptor
89 static U8 snd[] =
90 {
91       0x1A,
92       0x03, 
93       0x31, 0x00,     // MSD of Lap (Lap[2,3]) in UNICode
94       0x32, 0x00,     // Lap[4,5]
95       0x33, 0x00,     // Lap[6,7]
96       0x34, 0x00,     // Lap[8,9]
97       0x35, 0x00,     // Lap[10,11]
98       0x36, 0x00,     // Lap[12,13]
99       0x37, 0x00,     // Lap[14,15]
100       0x38, 0x00,     // LSD of Lap (Lap[16,17]) in UNICode
101       0x30, 0x00,     // MSD of Nap (Nap[18,19]) in UNICode
102       0x30, 0x00,     // LSD of Nap (Nap[20,21]) in UNICode
103       0x39, 0x00,     // MSD of Uap in UNICode
104       0x30, 0x00      // LSD of Uap in UNICode
105 };
106
107 static const U8 ld[] = {0x04,0x03,0x09,0x04}; // Language descriptor
108       
109 extern void udp_isr_entry(void);
110
111 static int configured = 0;
112
113 //static char x4[5];
114 //static char* hexchars = "0123456789abcdef";
115
116 /*  supress a warning by GCC
117 static char *
118 hex4(int i)
119 {
120   x4[0] = hexchars[(i >> 12) & 0xF];
121   x4[1] = hexchars[(i >> 8) & 0xF];
122   x4[2] = hexchars[(i >> 4) & 0xF];
123   x4[3] = hexchars[i & 0xF];
124   x4[4] = 0;
125   return x4;
126 }
127 */
128
129 void
130 udp_isr_C(void)
131 {
132 }
133
134 void
135 udp_check_interrupt()
136 {
137   if (*AT91C_UDP_ISR & END_OF_BUS_RESET) 
138   { 
139         //display_goto_xy(0,0);
140         //display_string("Bus Reset");
141         //display_update();
142         *AT91C_UDP_ICR = END_OF_BUS_RESET;          
143         *AT91C_UDP_ICR = SUSPEND_RESUME;      
144         *AT91C_UDP_ICR = WAKEUP;              
145         configured = 0;
146         currentConfig = 0;
147         *AT91C_UDP_RSTEP = 0xFFFFFFFF;
148         *AT91C_UDP_RSTEP = 0x0; 
149         currentRxBank = AT91C_UDP_RX_DATA_BK0;
150         *AT91C_UDP_FADDR = AT91C_UDP_FEN;    
151         *AT91C_UDP_CSR0 = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_CTRL); 
152   }
153   else if (*AT91C_UDP_ISR & SUSPEND_INT)
154   {
155         //display_goto_xy(0,0);
156         //display_string("Suspend");
157         //display_update();
158     if (configured == 1) configured = 2;
159     else configured = 0;
160         *AT91C_UDP_ICR = SUSPEND_INT;
161         currentRxBank = AT91C_UDP_RX_DATA_BK0;
162   }
163   else if (*AT91C_UDP_ISR & SUSPEND_RESUME)
164   {
165         //display_goto_xy(0,0);
166         //display_string("Resume");
167         //display_update();
168     if (configured == 2) configured = 1;
169     else configured = 0;
170     *AT91C_UDP_ICR = WAKEUP;
171     *AT91C_UDP_ICR = SUSPEND_RESUME;
172   }
173   else if (*AT91C_UDP_ISR & AT91C_UDP_EPINT0)
174   {
175     *AT91C_UDP_ICR = AT91C_UDP_EPINT0; 
176         udp_enumerate();                                        
177   } 
178 }
179
180 int
181 udp_init(void)
182 {
183   //int i_state;
184
185   /* Make sure the USB PLL and clock are set up */
186   *AT91C_CKGR_PLLR |= AT91C_CKGR_USBDIV_1;
187   *AT91C_PMC_SCER = AT91C_PMC_UDP;
188   *AT91C_PMC_PCER = (1 << AT91C_ID_UDP);
189
190   /* Enable the UDP pull up by outputting a zero on PA.16 */
191   *AT91C_PIOA_PER = (1 << 16);
192   *AT91C_PIOA_OER = (1 << 16);
193   *AT91C_PIOA_CODR = (1 << 16);
194
195   /* Set up default state */
196
197   currentConfig = 0;
198   currentConnection = 0;
199   currentRxBank = AT91C_UDP_RX_DATA_BK0;
200
201   /*i_state = interrupts_get_and_disable();
202
203   aic_mask_off(AT91C_PERIPHERAL_ID_UDP);
204   aic_set_vector(AT91C_PERIPHERAL_ID_UDP, AIC_INT_LEVEL_NORMAL,
205                  (U32) udp_isr_entry);
206   aic_mask_on(AT91C_PERIPHERAL_ID_UDP);
207
208   if (i_state)
209     interrupts_enable(); */
210
211   return 1; 
212 }
213
214 void
215 udp_close(U32 u)
216 {
217   /* Nothing */
218 }
219
220 void
221 udp_disable()
222 {
223   *AT91C_PIOA_PER = (1 << 16);
224   *AT91C_PIOA_OER = (1 << 16);
225   *AT91C_PIOA_SODR = (1 << 16);
226 }
227
228 void 
229 udp_reset()
230 {
231   udp_disable();  
232   systick_wait_ms(1);
233   udp_init();
234 }
235
236 int
237 udp_short_timed_out()
238 {
239   return (USB_TIMEOUT < 
240      ((((*AT91C_PITC_PIIR) & AT91C_PITC_CPIV) 
241          - usbTimeOut) & AT91C_PITC_CPIV));
242 }
243
244 static int timeout_counter = 0;
245
246 int
247 udp_timed_out()
248 {
249    if(udp_short_timed_out())
250    {
251       timeout_counter++;
252       udp_short_reset_timeout();
253    }
254    return (timeout_counter > 500);
255 }
256
257 void
258 udp_reset_timeout()
259 {
260   timeout_counter = 0;
261   udp_short_reset_timeout();  
262 }
263
264 void
265 udp_short_reset_timeout()
266 {
267   usbTimeOut = ((*AT91C_PITC_PIIR) & AT91C_PITC_CPIV);  
268 }
269
270 int
271 udp_read(U8* buf, int len)
272 {
273   int packetSize = 0, i;
274   
275   if (udp_configured() != 1) return 0;
276   
277   if ((*AT91C_UDP_CSR1) & currentRxBank) // data to read
278   {
279         packetSize = (*AT91C_UDP_CSR1) >> 16;
280         if (packetSize > len) packetSize = len;
281         
282         for(i=0;i<packetSize;i++) buf[i] = *AT91C_UDP_FDR1;
283         
284         *AT91C_UDP_CSR1 &= ~(currentRxBank);    
285
286     if (currentRxBank == AT91C_UDP_RX_DATA_BK0) {       
287       currentRxBank = AT91C_UDP_RX_DATA_BK1;
288     } else {
289       currentRxBank = AT91C_UDP_RX_DATA_BK0;
290     }
291   }
292   return packetSize;
293 }
294
295 void
296 udp_write(U8* buf, int len)
297 {
298   int i;
299   
300   if (configured != 1) return;
301   
302   for(i=0;i<len;i++) *AT91C_UDP_FDR2 = buf[i];
303   
304   *AT91C_UDP_CSR2 |= AT91C_UDP_TXPKTRDY;
305   
306   udp_reset_timeout();
307   
308   while ( !((*AT91C_UDP_CSR2) & AT91C_UDP_TXCOMP) )     
309      if (udp_configured() != 1 || udp_timed_out()) return;
310             
311  (*AT91C_UDP_CSR2) &= ~(AT91C_UDP_TXCOMP);
312
313   while ((*AT91C_UDP_CSR2) & AT91C_UDP_TXCOMP);
314 }
315
316 void 
317 udp_send_null()
318 {
319    (*AT91C_UDP_CSR0) |= AT91C_UDP_TXPKTRDY;
320
321    udp_reset_timeout();
322
323    while ( !((*AT91C_UDP_CSR0) & AT91C_UDP_TXCOMP) && !udp_timed_out());
324
325    (*AT91C_UDP_CSR0) &= ~(AT91C_UDP_TXCOMP);
326    while ((*AT91C_UDP_CSR0) & AT91C_UDP_TXCOMP);
327 }
328
329 void udp_send_stall()
330 {
331   (*AT91C_UDP_CSR0) |= AT91C_UDP_FORCESTALL;                           
332   while ( !((*AT91C_UDP_CSR0) & AT91C_UDP_ISOERROR) );                    
333
334   (*AT91C_UDP_CSR0) &= ~(AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR);
335   while ((*AT91C_UDP_CSR0) & (AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR));
336 }
337
338 void udp_send_control(U8* p, int len, int send_null)
339 {
340   int i = 0, j, tmp;
341   
342   do
343   {
344         // send 8 bytes or less 
345
346         for(j=0;j<8 && i<len;j++)
347         {
348           *AT91C_UDP_FDR0 = p[i++];
349         }
350
351         // Packet ready to send 
352         
353         (*AT91C_UDP_CSR0) |= AT91C_UDP_TXPKTRDY;
354         udp_reset_timeout();    
355     
356         do 
357         {
358           tmp = (*AT91C_UDP_CSR0);
359
360           if (tmp & AT91C_UDP_RX_DATA_BK0)
361           {
362
363             (*AT91C_UDP_CSR0) &= ~(AT91C_UDP_TXPKTRDY);
364
365                 (*AT91C_UDP_CSR0) &= ~(AT91C_UDP_RX_DATA_BK0);
366         return;
367           }
368         }
369         while (!(tmp & AT91C_UDP_TXCOMP) && !udp_timed_out());
370         
371         (*AT91C_UDP_CSR0) &= ~(AT91C_UDP_TXCOMP);
372     
373         while ((*AT91C_UDP_CSR0) & AT91C_UDP_TXCOMP);
374
375   }
376   while (i < len);
377   // If needed send the null terminating data 
378   if (send_null) udp_send_null();
379   udp_reset_timeout();
380
381   while(!((*AT91C_UDP_CSR0) & AT91C_UDP_RX_DATA_BK0) && !udp_timed_out());
382
383   (*AT91C_UDP_CSR0) &= ~(AT91C_UDP_RX_DATA_BK0);
384
385 }
386
387 int
388 udp_configured()
389 {
390   udp_check_interrupt();
391   /*display_goto_xy(0,7);
392   display_int(configured,1);
393   display_update();*/
394   return configured;
395 }
396
397 void 
398 udp_enumerate()
399 {
400   U8 bt, br;
401   int req, len, ind, val; 
402   short status;
403   
404   if (!((*AT91C_UDP_CSR0) & AT91C_UDP_RXSETUP)) return;
405   
406   bt = *AT91C_UDP_FDR0;
407   br = *AT91C_UDP_FDR0;
408   
409   val = ((*AT91C_UDP_FDR0 & 0xFF) | (*AT91C_UDP_FDR0 << 8));
410   ind = ((*AT91C_UDP_FDR0 & 0xFF) | (*AT91C_UDP_FDR0 << 8));
411   len = ((*AT91C_UDP_FDR0 & 0xFF) | (*AT91C_UDP_FDR0 << 8));
412   
413   if (bt & 0x80)
414   {
415     *AT91C_UDP_CSR0 |= AT91C_UDP_DIR; 
416     while ( !((*AT91C_UDP_CSR0) & AT91C_UDP_DIR) );
417   }
418   
419   *AT91C_UDP_CSR0 &= ~AT91C_UDP_RXSETUP;
420   while ( ((*AT91C_UDP_CSR0)  & AT91C_UDP_RXSETUP)  );
421
422   req = br << 8 | bt;
423   
424   /*
425   if (1) {
426         display_goto_xy(0,0);
427     display_string(hex4(req));
428     display_goto_xy(4,0);
429     display_string(hex4(val));
430     display_goto_xy(8,0);
431     display_string(hex4(ind));
432     display_goto_xy(12,0);
433     display_string(hex4(len));
434     display_goto_xy(0,1);
435     display_string("   ");
436     display_update();
437   }
438   */
439     
440   switch(req)
441   {
442     case STD_GET_DESCRIPTOR: 
443       if (val == 0x100) // Get device descriptor
444       {
445         udp_send_control((U8 *)dd, sizeof(dd), 0);
446       }
447       else if (val == 0x200) // Configuration descriptor
448       {     
449         udp_send_control((U8 *)cfd, (len < sizeof(cfd) ? len : sizeof(cfd)), (len > sizeof(cfd) ? 1 : 0));
450         //if (len > sizeof(cfd)) udp_send_null();
451       } 
452       else if ((val & 0xF00) == 0x300)
453       {
454         switch(val & 0xFF)
455         {
456           case 0x00:
457                 udp_send_control((U8 *)ld, sizeof(ld), 0);
458             break;
459           case 0x01:
460                     udp_send_control(snd, sizeof(snd), 0);
461             break;
462           default:
463                         udp_send_stall();
464         }
465       }  
466       else
467       {
468         udp_send_stall();
469       }
470       break;
471         
472     case STD_SET_ADDRESS:
473       
474       (*AT91C_UDP_CSR0) |= AT91C_UDP_TXPKTRDY;
475
476       udp_reset_timeout();
477
478       while(((*AT91C_UDP_CSR0) & AT91C_UDP_TXPKTRDY) && !udp_timed_out());
479         
480       *AT91C_UDP_FADDR = (AT91C_UDP_FEN | val);            
481                                                                    
482       *AT91C_UDP_GLBSTATE  = (val) ? AT91C_UDP_FADDEN : 0;
483       
484       break;
485         
486     case STD_SET_CONFIGURATION:
487
488       configured = 1;
489       currentConfig = val;
490       udp_send_null(); 
491       *AT91C_UDP_GLBSTATE  = (val) ? AT91C_UDP_CONFG : AT91C_UDP_FADDEN;
492
493       *AT91C_UDP_CSR1 = (val) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_OUT) : 0; 
494       *AT91C_UDP_CSR2 = (val) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_IN)  : 0;
495       *AT91C_UDP_CSR3 = (val) ? (AT91C_UDP_EPTYPE_INT_IN)   : 0;      
496       
497       break;
498       
499     case STD_SET_FEATURE_ENDPOINT:
500
501       ind &= 0x0F;
502
503       if ((val == 0) && ind && (ind <= 3))
504       {
505         switch (ind)
506         {
507           case 1:   
508             (*AT91C_UDP_CSR1) = 0;
509             break;
510           case 2:   
511             (*AT91C_UDP_CSR2) = 0;
512             break;
513           case 3:   
514             (*AT91C_UDP_CSR3) = 0;
515             break;
516         }
517         udp_send_null();
518       }
519       else udp_send_stall();
520       break;
521
522     case STD_CLEAR_FEATURE_ENDPOINT:
523       ind &= 0x0F;
524
525       if ((val == 0) && ind && (ind <= 3))
526       {                                             
527         if (ind == 1) {
528           (*AT91C_UDP_CSR1) = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_OUT); 
529           (*AT91C_UDP_RSTEP) |= AT91C_UDP_EP1;
530           (*AT91C_UDP_RSTEP) &= ~AT91C_UDP_EP1;
531         } else if (ind == 2) {
532           (*AT91C_UDP_CSR2) = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_IN);
533           (*AT91C_UDP_RSTEP) |= AT91C_UDP_EP2;
534           (*AT91C_UDP_RSTEP) &= ~AT91C_UDP_EP2;
535         } else if (ind == 3) {
536           (*AT91C_UDP_CSR3) = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_INT_IN);
537           (*AT91C_UDP_RSTEP) |= AT91C_UDP_EP3;
538           (*AT91C_UDP_RSTEP) &= ~AT91C_UDP_EP3; 
539         }
540         udp_send_null();
541       }
542       else udp_send_stall();
543
544       break;
545       
546     case STD_GET_CONFIGURATION:                                   
547
548       udp_send_control((U8 *) &(currentConfig), sizeof(currentConfig), 0);
549       break;
550
551     case STD_GET_STATUS_ZERO:
552     
553       status = 0x01; 
554       udp_send_control((U8 *) &status, sizeof(status), 0);
555       break;
556       
557     case STD_GET_STATUS_INTERFACE:
558
559       status = 0;
560       udp_send_control((U8 *) &status, sizeof(status), 0);
561       break;
562
563     case STD_GET_STATUS_ENDPOINT:
564
565       status = 0;
566       ind &= 0x0F;
567
568       if (((*AT91C_UDP_GLBSTATE) & AT91C_UDP_CONFG) && (ind <= 3)) 
569       {
570         switch (ind)
571         {
572           case 1: 
573             status = ((*AT91C_UDP_CSR1) & AT91C_UDP_EPEDS) ? 0 : 1; 
574             break;
575           case 2: 
576             status = ((*AT91C_UDP_CSR2) & AT91C_UDP_EPEDS) ? 0 : 1;
577             break;
578           case 3: 
579             status = ((*AT91C_UDP_CSR3) & AT91C_UDP_EPEDS) ? 0 : 1;
580             break;
581         }
582         udp_send_control((U8 *) &status, sizeof(status), 0);
583       }
584       else if (((*AT91C_UDP_GLBSTATE) & AT91C_UDP_FADDEN) && (ind == 0))
585       {
586         status = ((*AT91C_UDP_CSR0) & AT91C_UDP_EPEDS) ? 0 : 1;
587         udp_send_control((U8 *) &status, sizeof(status), 0);
588       }
589       else udp_send_stall();                                // Illegal request :-(
590
591       break;
592       
593     case STD_SET_FEATURE_INTERFACE:
594     case STD_CLEAR_FEATURE_INTERFACE:
595       udp_send_null();
596       break;
597  
598     case STD_SET_INTERFACE:     
599     case STD_SET_FEATURE_ZERO:
600     case STD_CLEAR_FEATURE_ZERO:
601     default:
602       udp_send_stall();
603   } 
604 }
605
606
607
608
609
610