4 #include "interrupts.h"
5 #include "at91sam7s256.h"
14 #define AT91C_PERIPHERAL_ID_UDP 11
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)
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)
26 static U8 currentConfig;
27 static unsigned currentConnection;
28 static unsigned currentRxBank;
29 static unsigned usbTimeOut;
32 static const U8 dd[] = {
53 // Configuration descriptor
54 static const U8 cfd[] = {
88 // Serial Number Descriptor
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
107 static const U8 ld[] = {0x04,0x03,0x09,0x04}; // Language descriptor
109 extern void udp_isr_entry(void);
111 static int configured = 0;
114 //static char* hexchars = "0123456789abcdef";
116 /* supress a warning by GCC
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];
135 udp_check_interrupt()
137 if (*AT91C_UDP_ISR & END_OF_BUS_RESET)
139 //display_goto_xy(0,0);
140 //display_string("Bus Reset");
142 *AT91C_UDP_ICR = END_OF_BUS_RESET;
143 *AT91C_UDP_ICR = SUSPEND_RESUME;
144 *AT91C_UDP_ICR = WAKEUP;
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);
153 else if (*AT91C_UDP_ISR & SUSPEND_INT)
155 //display_goto_xy(0,0);
156 //display_string("Suspend");
158 if (configured == 1) configured = 2;
160 *AT91C_UDP_ICR = SUSPEND_INT;
161 currentRxBank = AT91C_UDP_RX_DATA_BK0;
163 else if (*AT91C_UDP_ISR & SUSPEND_RESUME)
165 //display_goto_xy(0,0);
166 //display_string("Resume");
168 if (configured == 2) configured = 1;
170 *AT91C_UDP_ICR = WAKEUP;
171 *AT91C_UDP_ICR = SUSPEND_RESUME;
173 else if (*AT91C_UDP_ISR & AT91C_UDP_EPINT0)
175 *AT91C_UDP_ICR = AT91C_UDP_EPINT0;
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);
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);
195 /* Set up default state */
198 currentConnection = 0;
199 currentRxBank = AT91C_UDP_RX_DATA_BK0;
201 /*i_state = interrupts_get_and_disable();
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);
209 interrupts_enable(); */
223 *AT91C_PIOA_PER = (1 << 16);
224 *AT91C_PIOA_OER = (1 << 16);
225 *AT91C_PIOA_SODR = (1 << 16);
237 udp_short_timed_out()
239 return (USB_TIMEOUT <
240 ((((*AT91C_PITC_PIIR) & AT91C_PITC_CPIV)
241 - usbTimeOut) & AT91C_PITC_CPIV));
244 static int timeout_counter = 0;
249 if(udp_short_timed_out())
252 udp_short_reset_timeout();
254 return (timeout_counter > 500);
261 udp_short_reset_timeout();
265 udp_short_reset_timeout()
267 usbTimeOut = ((*AT91C_PITC_PIIR) & AT91C_PITC_CPIV);
271 udp_read(U8* buf, int len)
273 int packetSize = 0, i;
275 if (udp_configured() != 1) return 0;
277 if ((*AT91C_UDP_CSR1) & currentRxBank) // data to read
279 packetSize = (*AT91C_UDP_CSR1) >> 16;
280 if (packetSize > len) packetSize = len;
282 for(i=0;i<packetSize;i++) buf[i] = *AT91C_UDP_FDR1;
284 *AT91C_UDP_CSR1 &= ~(currentRxBank);
286 if (currentRxBank == AT91C_UDP_RX_DATA_BK0) {
287 currentRxBank = AT91C_UDP_RX_DATA_BK1;
289 currentRxBank = AT91C_UDP_RX_DATA_BK0;
296 udp_write(U8* buf, int len)
300 if (configured != 1) return;
302 for(i=0;i<len;i++) *AT91C_UDP_FDR2 = buf[i];
304 *AT91C_UDP_CSR2 |= AT91C_UDP_TXPKTRDY;
308 while ( !((*AT91C_UDP_CSR2) & AT91C_UDP_TXCOMP) )
309 if (udp_configured() != 1 || udp_timed_out()) return;
311 (*AT91C_UDP_CSR2) &= ~(AT91C_UDP_TXCOMP);
313 while ((*AT91C_UDP_CSR2) & AT91C_UDP_TXCOMP);
319 (*AT91C_UDP_CSR0) |= AT91C_UDP_TXPKTRDY;
323 while ( !((*AT91C_UDP_CSR0) & AT91C_UDP_TXCOMP) && !udp_timed_out());
325 (*AT91C_UDP_CSR0) &= ~(AT91C_UDP_TXCOMP);
326 while ((*AT91C_UDP_CSR0) & AT91C_UDP_TXCOMP);
329 void udp_send_stall()
331 (*AT91C_UDP_CSR0) |= AT91C_UDP_FORCESTALL;
332 while ( !((*AT91C_UDP_CSR0) & AT91C_UDP_ISOERROR) );
334 (*AT91C_UDP_CSR0) &= ~(AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR);
335 while ((*AT91C_UDP_CSR0) & (AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR));
338 void udp_send_control(U8* p, int len, int send_null)
344 // send 8 bytes or less
346 for(j=0;j<8 && i<len;j++)
348 *AT91C_UDP_FDR0 = p[i++];
351 // Packet ready to send
353 (*AT91C_UDP_CSR0) |= AT91C_UDP_TXPKTRDY;
358 tmp = (*AT91C_UDP_CSR0);
360 if (tmp & AT91C_UDP_RX_DATA_BK0)
363 (*AT91C_UDP_CSR0) &= ~(AT91C_UDP_TXPKTRDY);
365 (*AT91C_UDP_CSR0) &= ~(AT91C_UDP_RX_DATA_BK0);
369 while (!(tmp & AT91C_UDP_TXCOMP) && !udp_timed_out());
371 (*AT91C_UDP_CSR0) &= ~(AT91C_UDP_TXCOMP);
373 while ((*AT91C_UDP_CSR0) & AT91C_UDP_TXCOMP);
377 // If needed send the null terminating data
378 if (send_null) udp_send_null();
381 while(!((*AT91C_UDP_CSR0) & AT91C_UDP_RX_DATA_BK0) && !udp_timed_out());
383 (*AT91C_UDP_CSR0) &= ~(AT91C_UDP_RX_DATA_BK0);
390 udp_check_interrupt();
391 /*display_goto_xy(0,7);
392 display_int(configured,1);
401 int req, len, ind, val;
404 if (!((*AT91C_UDP_CSR0) & AT91C_UDP_RXSETUP)) return;
406 bt = *AT91C_UDP_FDR0;
407 br = *AT91C_UDP_FDR0;
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));
415 *AT91C_UDP_CSR0 |= AT91C_UDP_DIR;
416 while ( !((*AT91C_UDP_CSR0) & AT91C_UDP_DIR) );
419 *AT91C_UDP_CSR0 &= ~AT91C_UDP_RXSETUP;
420 while ( ((*AT91C_UDP_CSR0) & AT91C_UDP_RXSETUP) );
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);
442 case STD_GET_DESCRIPTOR:
443 if (val == 0x100) // Get device descriptor
445 udp_send_control((U8 *)dd, sizeof(dd), 0);
447 else if (val == 0x200) // Configuration descriptor
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();
452 else if ((val & 0xF00) == 0x300)
457 udp_send_control((U8 *)ld, sizeof(ld), 0);
460 udp_send_control(snd, sizeof(snd), 0);
472 case STD_SET_ADDRESS:
474 (*AT91C_UDP_CSR0) |= AT91C_UDP_TXPKTRDY;
478 while(((*AT91C_UDP_CSR0) & AT91C_UDP_TXPKTRDY) && !udp_timed_out());
480 *AT91C_UDP_FADDR = (AT91C_UDP_FEN | val);
482 *AT91C_UDP_GLBSTATE = (val) ? AT91C_UDP_FADDEN : 0;
486 case STD_SET_CONFIGURATION:
491 *AT91C_UDP_GLBSTATE = (val) ? AT91C_UDP_CONFG : AT91C_UDP_FADDEN;
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;
499 case STD_SET_FEATURE_ENDPOINT:
503 if ((val == 0) && ind && (ind <= 3))
508 (*AT91C_UDP_CSR1) = 0;
511 (*AT91C_UDP_CSR2) = 0;
514 (*AT91C_UDP_CSR3) = 0;
519 else udp_send_stall();
522 case STD_CLEAR_FEATURE_ENDPOINT:
525 if ((val == 0) && ind && (ind <= 3))
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;
542 else udp_send_stall();
546 case STD_GET_CONFIGURATION:
548 udp_send_control((U8 *) &(currentConfig), sizeof(currentConfig), 0);
551 case STD_GET_STATUS_ZERO:
554 udp_send_control((U8 *) &status, sizeof(status), 0);
557 case STD_GET_STATUS_INTERFACE:
560 udp_send_control((U8 *) &status, sizeof(status), 0);
563 case STD_GET_STATUS_ENDPOINT:
568 if (((*AT91C_UDP_GLBSTATE) & AT91C_UDP_CONFG) && (ind <= 3))
573 status = ((*AT91C_UDP_CSR1) & AT91C_UDP_EPEDS) ? 0 : 1;
576 status = ((*AT91C_UDP_CSR2) & AT91C_UDP_EPEDS) ? 0 : 1;
579 status = ((*AT91C_UDP_CSR3) & AT91C_UDP_EPEDS) ? 0 : 1;
582 udp_send_control((U8 *) &status, sizeof(status), 0);
584 else if (((*AT91C_UDP_GLBSTATE) & AT91C_UDP_FADDEN) && (ind == 0))
586 status = ((*AT91C_UDP_CSR0) & AT91C_UDP_EPEDS) ? 0 : 1;
587 udp_send_control((U8 *) &status, sizeof(status), 0);
589 else udp_send_stall(); // Illegal request :-(
593 case STD_SET_FEATURE_INTERFACE:
594 case STD_CLEAR_FEATURE_INTERFACE:
598 case STD_SET_INTERFACE:
599 case STD_SET_FEATURE_ZERO:
600 case STD_CLEAR_FEATURE_ZERO: