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