]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/lx-rocon.git/blob - sw/app/rocon/appl_usb.c
f3aff84796d2b70343be0be48f0bb18545504934
[fpga/lx-cpu1/lx-rocon.git] / sw / app / rocon / appl_usb.c
1 #include <types.h>
2 #include <cpu_def.h>
3 #include <system_def.h>
4 #include <string.h>
5 #include <stdio.h>
6 #include <stdint.h>
7 #include <endian.h>
8 #include <usb/lpc.h>
9 #include <usb/usb.h>
10 #include <usb/usb_loader.h>
11 #include <usb/usbdebug.h>
12 #include <cmd_proc.h>
13 #include <hal_gpio.h>
14
15 #include "appl_defs.h"
16 #include "usb/usb_defs.h"
17 #include "appl_fpga.h"
18
19 #ifdef CONFIG_KEYVAL
20 #include <keyvalpb.h>
21 #include <lpciap.h>
22 #include <lpciap_kvpb.h>
23 #include <hal_machperiph.h>
24 #endif /*CONFIG_KEYVAL*/
25
26 #include <endian.h>
27 #if __BYTE_ORDER == __BIG_ENDIAN
28 #include <byteswap.h>
29 #define SWAP(x) ((((x) & 0xFF) << 8) | (((x) >> 8) & 0xFF))
30 #else /*__LITTLE_ENDIAN*/
31 #define SWAP(x) (x)
32 #endif
33
34 #define USB_VENDOR_TARGET_TUMBL                   0x03
35 #define USB_VENDOR_TARGET_32BIT                   0x04
36
37 #define USB_CMD_FPGA_CONFIGURE                    0xF000
38 #define USB_CMD_FPGA_MEASURE_READ                 0xF001
39 #define USB_CMD_FPGA_MEASURE_WRITE                0xF002
40
41 #define USB_CMD_FPGA_IRC_GET_RESET                0xF010
42 #define USB_CMD_FPGA_IRC_SET_RESET                0xF011
43 #define USB_CMD_FPGA_IRC_DUMP                     0xF012
44
45 #define USB_CMD_FPGA_LXMASTER_GET_RESET           0xF020
46 #define USB_CMD_FPGA_LXMASTER_SET_RESET           0xF021
47 #define USB_CMD_FPGA_LXMASTER_TRANSMITTER_GET_REG 0xF022
48 #define USB_CMD_FPGA_LXMASTER_TRANSMITTER_SET_REG 0xF023
49 #define USB_CMD_FPGA_LXMASTER_TRANSMITTER_WRITE   0xF024
50 #define USB_CMD_FPGA_LXMASTER_TRANSMITTER_DUMP    0xF025
51
52 #define USB_CMD_FPGA_TUMBL_SET_RESET              0xF100
53 #define USB_CMD_FPGA_TUMBL_SET_HALT               0xF101
54 #define USB_CMD_FPGA_TUMBL_SET_TRACE              0xF102
55 #define USB_CMD_FPGA_TUMBL_KICK_TRACE             0xF103
56 #define USB_CMD_FPGA_TUMBL_GET_PC                 0xF104
57
58 #define USB_CMD_FPGA_TUMBL_DUMP_IMEM              0xF200
59 #define USB_CMD_FPGA_TUMBL_DUMP_DMEM              0xF201
60
61 #define USB_CMD_FPGA_RESET                        0xFFFF
62
63 usb_device_t usb_device;
64 usb_ep_t eps[NUM_ENDPOINTS];
65
66 #define MASK_EP1RX 0x01
67 #define MASK_EP1TX 0x02
68
69 unsigned char ep1_rx_buff[USB_MAX_PACKET] __attribute__ ((aligned (8)));
70 unsigned char ep1_tx_buff[USB_MAX_PACKET] __attribute__ ((aligned (8)));
71 unsigned char ep0_buffer[USB_MAX_PACKET0] __attribute__ ((aligned (8)));
72 int usb_active = 0;
73 int ep1_rx_index = 0, ep1_rx_ready = 1;
74 int ep1_tx_index = 0, ep1_tx_chars = 0;
75
76 #ifdef CONFIG_OC_CMDPROC
77
78 cmd_io_t cmd_io_usbcon_dev;
79
80 #define ED_LINE_CHARS 512
81
82 char ed_line_chars_usbcon_in[ED_LINE_CHARS + 1];
83 char ed_line_chars_usbcon_out[ED_LINE_CHARS + 1];
84
85 ed_line_buf_t ed_line_buf_usbcon_in =
86 {
87 flg:
88   FL_ELB_ECHO,
89   inbuf: 0,
90 alloc:
91   sizeof(ed_line_chars_usbcon_in),
92   maxlen: 0,
93   lastch: 0,
94 buf:
95   ed_line_chars_usbcon_in
96 };
97
98 ed_line_buf_t ed_line_buf_usbcon_out =
99 {
100 flg:
101   FL_ELB_NOCRLF,
102   inbuf: 0,
103 alloc:
104   sizeof(ed_line_chars_usbcon_out),
105   maxlen: 0,
106   lastch: 0,
107 buf:
108   ed_line_chars_usbcon_out
109 };
110
111 cmd_io_t cmd_io_usbcon =
112 {
113 putc:
114   cmd_io_line_putc,
115 getc:
116   NULL,
117 write:
118   cmd_io_write_bychar,
119 read:
120   NULL,
121 priv:
122   {
123   ed_line:
124     {
125     in:
126       &ed_line_buf_usbcon_in,
127     out:
128       &ed_line_buf_usbcon_out,
129     io_stack:
130       &cmd_io_usbcon_dev
131     }
132   }
133 };
134
135 #endif
136
137 static int usb_flash_pkt_wr(struct usb_ep_t *ep, int len, int code)
138 {
139   unsigned char *ptr = ep->ptr - len;
140
141 #ifdef CONFIG_KEYVAL
142   lpcisp_kvpb_copy(NULL, (void *)ep->user_data, ptr, len);
143 #endif /*CONFIG_KEYVAL*/
144
145   ep->user_data += len;
146   ep->ptr = ep0_buffer;
147   return USB_COMPLETE_OK;
148 }
149
150 static int usb_tumbl_pkt_wr(struct usb_ep_t *ep, int len, int code)
151 {
152   unsigned char *ptr = ep->ptr - len;
153
154   fpga_tumbl_write(ep->user_data, ptr, len);
155
156   ep->user_data += len;
157   ep->ptr = ep0_buffer;
158   return USB_COMPLETE_OK;
159 }
160
161 static int usb_32bit_pkt_wr(struct usb_ep_t *ep, int len, int code)
162 {
163   uint32_t *srcptr = (uint32_t *)(ep->ptr - len);
164   volatile uint32_t *dstptr = (uint32_t *)ep->user_data;
165   int pos;
166
167   for (pos = 0; len - pos >= 4; pos += 4, dstptr++, srcptr++)
168     *dstptr = *srcptr;
169
170   ep->user_data += len;
171   ep->ptr = ep0_buffer;
172   return USB_COMPLETE_OK;
173 }
174
175 int usb_32bit_pkt_rd(struct usb_ep_t *ep, int len, int code)
176 {
177   volatile uint32_t *srcptr;
178   uint32_t *dstptr;
179   int pos;
180
181   ep->ptr = ep0_buffer;
182   dstptr = (uint32_t *)ep->ptr;
183   srcptr = (uint32_t *)ep->user_data;
184
185   for (pos = 0; len - pos >= 4; pos += 4, dstptr++, srcptr++)
186     *dstptr = *srcptr;
187
188   ep->user_data += len;
189   return USB_COMPLETE_OK;
190 }
191
192 static int usb_flash_erase(unsigned addr, unsigned len)
193 {
194 #ifdef CONFIG_KEYVAL
195   lpcisp_erase((void *)addr, len);
196 #endif /*CONFIG_KEYVAL*/
197   return 0;
198 }
199
200 static void usb_goto(unsigned address)
201 {
202 #ifdef CONFIG_KEYVAL
203   lpc_watchdog_init(1, 10);
204   lpc_watchdog_feed();
205
206   while (1)
207     {}
208
209 #endif /*CONFIG_KEYVAL*/
210 }
211
212 /* Not re-entrant */
213 uint16_t vendor_call_ret = 0xFFFF;
214
215 uint16_t appl_usb_vendor_call(uint16_t command, uint16_t argument)
216 {
217   int i, j;
218
219   switch (command)
220   {
221     case USB_CMD_FPGA_CONFIGURE:
222       return fpga_configure();
223
224     case USB_CMD_FPGA_MEASURE_READ:
225       return fpga_measure_bus_read();
226
227     case USB_CMD_FPGA_MEASURE_WRITE:
228       return fpga_measure_bus_write();
229
230     case USB_CMD_FPGA_IRC_GET_RESET:
231       printf("IRC RESET: 0x%02x\n", *fpga_irc_reset);
232       return 0;
233
234     case USB_CMD_FPGA_IRC_SET_RESET:
235       /* When starting, zero out counters */
236       *fpga_irc_reset = argument & 0x0001;
237       return 0;
238
239     case USB_CMD_FPGA_IRC_DUMP:
240       for (i = 0; i < 8; i++)
241         printf("IRC%d: count = %d, count index = %d, mark = %d, ab_error = %d, index_event = %d, index = %d\n", i+1,
242                (unsigned int) fpga_irc[i]->count, (unsigned int) fpga_irc[i]->count_index, ((*(fpga_irc_state[i])) & 0x01) != 0,
243                ((*(fpga_irc_state[i])) & 0x02) != 0, ((*(fpga_irc_state[i])) & 0x04) != 0, ((*(fpga_irc_state[i])) & 0x08) != 0);
244       return 0;
245
246     case USB_CMD_FPGA_LXMASTER_GET_RESET:
247       printf("LXMASTER RESET: 0x%02x\n", *fpga_lx_master_reset);
248       return 0;
249
250     case USB_CMD_FPGA_LXMASTER_SET_RESET:
251       /* When starting, zero out counters */
252       *fpga_lx_master_reset = argument & 0x0001;
253       return 0;
254
255     case USB_CMD_FPGA_LXMASTER_TRANSMITTER_GET_REG:
256       printf("LXMASTER TRANSMITTER REG: 0x%02x\n", *fpga_lx_master_transmitter_reg);
257       return 0;
258
259     case USB_CMD_FPGA_LXMASTER_TRANSMITTER_SET_REG:
260       /* When starting, zero out counters */
261       *fpga_lx_master_transmitter_reg = argument & 0x0001;
262       return 0;
263
264     case USB_CMD_FPGA_LXMASTER_TRANSMITTER_WRITE:
265       for (i = 0; i < (argument / 4); i++)
266         fpga_lx_master_transmitter_base[i] = fpga_lx_master_conf[i];
267       return 0;
268
269     case USB_CMD_FPGA_LXMASTER_TRANSMITTER_DUMP:
270       printf("LX MASTER TRANSMITTER MEM:\n");
271       for (i = 0; i < 16; i++)
272       {
273         for (j = 0; j < 16; j++)
274           printf("%04X ", (unsigned int) (fpga_lx_master_transmitter_base[i*16 + j] & 0xFFFF));
275
276         printf("\n");
277       }
278       return 0;
279
280     case USB_CMD_FPGA_TUMBL_SET_RESET:
281       return fpga_tumbl_set_reset(argument);
282
283     case USB_CMD_FPGA_TUMBL_SET_HALT:
284       return fpga_tumbl_set_halt(argument);
285
286     case USB_CMD_FPGA_TUMBL_SET_TRACE:
287       return fpga_tumbl_set_trace(argument);
288
289     case USB_CMD_FPGA_TUMBL_KICK_TRACE:
290       return fpga_tumbl_kick_trace();
291
292     case USB_CMD_FPGA_TUMBL_GET_PC:
293       printf("Tubml PC: 0x%08X\n", (unsigned int) *fpga_tumbl_pc);
294       return 0;
295
296     case USB_CMD_FPGA_TUMBL_DUMP_IMEM:
297       printf("TUMBL IMEM:\n");
298       for (i = 0; i < 64; i++)
299       {
300         for (j = 0; j < 8; j++)
301           printf("%08X ", (unsigned int) fpga_tumbl_imem[i*8 + j]);
302
303         printf("\n");
304       }
305       return 0;
306
307     case USB_CMD_FPGA_TUMBL_DUMP_DMEM:
308       printf("TUMBL DMEM:\n");
309       for (i = 0; i < 128; i++)
310       {
311         for (j = 0; j < 8; j++)
312           printf("%08X ", (unsigned int) fpga_tumbl_dmem[i*8 + j]);
313
314         printf("\n");
315       }
316       return 0;
317
318     case USB_CMD_FPGA_RESET:
319       hal_gpio_direction_output(XC_INIT_PIN, 0);
320
321       for (i = 0; i < 128; i++)
322         {}
323
324       hal_gpio_direction_output(XC_INIT_PIN, 1);
325       return 0;
326   }
327
328   return 0xFFFF;
329 }
330
331 int appl_usb_vendor(usb_device_t *udev)
332 {
333   unsigned long addr;
334   unsigned len;
335   USB_DEVICE_REQUEST *dreq;
336
337   usb_active = 1;
338   dreq = &udev->request;
339
340 #ifdef CONFIG_KEYVAL
341
342   if (dreq->bRequest != (USB_VENDOR_GET_SET_MEMORY |
343                          USB_DATA_DIR_FROM_HOST | USB_VENDOR_TARGET_FLASH))
344     lpcisp_kvpb_flush(NULL);
345
346 #endif /*CONFIG_KEYVAL*/
347
348   switch (dreq->bRequest & USB_VENDOR_MASK)
349   {
350     case USB_VENDOR_GET_CAPABILITIES:
351       ep0_buffer[0] = 0xAA; // test
352       usb_send_control_data(udev, ep0_buffer, 1);
353       return 1;
354
355     case USB_VENDOR_RESET_DEVICE:
356       usb_send_control_data(udev, NULL, 0);
357 #ifdef CONFIG_KEYVAL
358       lpc_watchdog_init(1, 10);
359       lpc_watchdog_feed();
360
361       while (1)
362         {}
363
364 #endif /*CONFIG_KEYVAL*/
365       return 1;
366
367     case USB_VENDOR_GOTO:
368       usb_send_control_data(udev, NULL, 0);
369       usb_goto(dreq->wValue);
370       return 1;
371
372     case USB_VENDOR_ERASE_MEMORY:
373       usb_send_control_data(udev, NULL, 0);
374       usb_flash_erase(dreq->wValue, dreq->wIndex);
375       return 1;
376
377     case USB_VENDOR_ERASE_1KB_MEMORY:  /* erase memory for 1 KB */
378       usb_send_control_data(udev, NULL, 0);
379       usb_flash_erase((uint32_t)dreq->wValue << 10, dreq->wIndex << 10);
380       return 1;
381
382     case USB_VENDOR_CALL:
383       vendor_call_ret = SWAP(appl_usb_vendor_call(dreq->wIndex, dreq->wValue));
384       usb_send_control_data(udev, (unsigned char *) &vendor_call_ret, sizeof(uint16_t));
385       return 1;
386
387     case USB_VENDOR_GET_SET_MEMORY:
388       addr = (dreq->wValue & 0xffff) | (((unsigned long)dreq->wIndex & 0xffff) << 16);
389       len = dreq->wLength;
390
391       if ((dreq->bmRequestType & USB_DATA_DIR_MASK) == USB_DATA_DIR_FROM_HOST)
392       {
393         switch (dreq->bRequest & USB_VENDOR_TARGET_MASK)
394         {
395           case USB_VENDOR_TARGET_RAM:
396             udev->ep0.ptr = (void *)addr;
397             break;
398
399           case USB_VENDOR_TARGET_FLASH:
400             udev->ep0.next_pkt_fnc = usb_flash_pkt_wr;
401             udev->ep0.user_data = addr;
402             udev->ep0.ptr = ep0_buffer;
403             break;
404
405           case USB_VENDOR_TARGET_TUMBL:
406             udev->ep0.next_pkt_fnc = usb_tumbl_pkt_wr;
407             udev->ep0.user_data = addr;
408             udev->ep0.ptr = ep0_buffer;
409             break;
410
411           case USB_VENDOR_TARGET_32BIT:
412             udev->ep0.next_pkt_fnc = usb_32bit_pkt_wr;
413             udev->ep0.user_data = addr;
414             udev->ep0.ptr = ep0_buffer;
415             break;
416
417           default:
418             return -1;
419         }
420
421         if (len)
422           usb_set_control_endfnc(udev, usb_ack_setup);
423         else
424           usb_send_control_data(udev, NULL, 0);
425
426         return 1;
427       }
428       else
429       {
430         switch (dreq->bRequest & USB_VENDOR_TARGET_MASK)
431         {
432           case USB_VENDOR_TARGET_RAM:
433             usb_send_control_data(udev, (void *)addr, len);
434             break;
435
436           case USB_VENDOR_TARGET_32BIT:
437             udev->ep0.next_pkt_fnc = usb_32bit_pkt_rd;
438             udev->ep0.user_data=addr;
439             usb_send_control_data( udev, ep0_buffer, len);
440             break;
441
442           default:
443             return -1;
444         }
445
446         return 1;
447       }
448
449       break;
450   }
451
452   return 0;
453 }
454
455 int usb_app_fill_serial_number(uint32_t ul_sn)
456 {
457   char *p = usb_devdes_serial_number;
458   int len_max = sizeof(usb_devdes_serial_number);
459   char c;
460
461   while ((len_max -= 2) >= 2)
462   {
463     p += 2;
464     c = ((ul_sn >> (32 - 4)) & 0xf) + '0';
465     ul_sn <<= 4;
466
467     if (c > '9')
468       c += 'A' - '9' - 1;
469
470     *p = c;
471   }
472
473   return 0;
474 }
475
476 int usb_app_init(void)
477 {
478   memset(&usb_device, 0, sizeof(usb_device));
479
480   eps[0].max_packet_size = USB_MAX_PACKET;
481   eps[1].max_packet_size = USB_MAX_PACKET;
482   eps[0].epnum = 0x81;
483   eps[1].epnum = 0x01;
484   eps[0].event_mask = 0x08;
485   eps[1].event_mask = 0x04;
486   eps[0].udev = &usb_device;
487   eps[1].udev = &usb_device;
488
489   usb_device.id = 1;
490   usb_device.devdes_table = &usb_devdes_table;
491   usb_device.init = usb_lpc_init;
492   usb_debug_set_level(DEBUG_LEVEL_NONE);
493   usb_device.cntep = NUM_ENDPOINTS;
494   usb_device.ep = eps;
495   usb_device.vendor_fnc = appl_usb_vendor;
496
497   usb_init(&usb_device);
498   usb_connect(&usb_device);
499
500   return 0;
501 }
502
503 int usb_check_ep1()
504 {
505   if (usb_device.ep_events & MASK_EP1RX)
506   {
507     usb_device.ep_events &= ~MASK_EP1RX;
508     //TODO: Use some field in the structure, probably flags
509     ep1_rx_ready = 1;
510   }
511
512   /* Respond if there is something to send and RX is ready */
513   if (ep1_rx_ready && ep1_rx_index != 0)
514   {
515     usb_udev_write_endpoint(&eps[0], ep1_rx_buff, ep1_rx_index);
516     ep1_rx_index = 0;
517     ep1_rx_ready = 0;
518     hal_gpio_set_value(LED2_PIN, 0);
519     return 1;
520   }
521
522   return 0;
523 }
524
525 int usb_app_poll(void)
526 {
527   int active = usb_active;
528   usb_active = 0;
529
530   usb_check_events(&usb_device);
531   usb_control_response(&usb_device);
532
533   /* Check TX endpoint */
534   if (usb_device.ep_events & MASK_EP1TX)
535   {
536     ep1_tx_chars = usb_udev_read_endpoint(&eps[1], ep1_tx_buff, USB_MAX_PACKET);
537     ep1_tx_index = 0;
538     usb_device.ep_events &= ~MASK_EP1TX;
539     hal_gpio_set_value(LED2_PIN, 0);
540     usb_active = 1;
541   }
542
543   /* Check RX endpoint */
544   usb_active |= usb_check_ep1();
545
546   return active;
547 }
548
549 int usb_app_stop(void)
550 {
551   usb_disconnect(&usb_device);
552   return 0;
553 }
554
555 #ifdef CONFIG_OC_CMDPROC
556
557 int cmd_io_getc_usbcon(struct cmd_io *cmd_io)
558 {
559   if (ep1_tx_index >= ep1_tx_chars)
560     return -1;
561
562   return ep1_tx_buff[ep1_tx_index++];
563 }
564
565 int cmd_io_putc_usbcon(struct cmd_io *cmd_io, int ch)
566 {
567   if (ep1_rx_index >= USB_MAX_PACKET)
568   {
569     /* Check EP1 status and return -1 if unavailable */
570     usb_check_events(&usb_device);
571     usb_check_ep1();
572
573     /* Check again if it wasn't emptied */
574     if (ep1_rx_index >= USB_MAX_PACKET)
575       return -1;
576   }
577
578   ep1_rx_buff[ep1_rx_index++] = (unsigned char)ch;
579   return ch;
580 }
581
582 cmd_io_t cmd_io_usbcon_dev =
583 {
584   .putc = cmd_io_putc_usbcon,
585   .getc = cmd_io_getc_usbcon,
586   .write = cmd_io_write_bychar,
587   .read = cmd_io_read_bychar,
588   .priv.uart = { -1 }
589 };
590
591 #endif