]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/lx-rocon.git/blob - sw/app/rocon/appl_usb.c
Use USB for cmdproc and UART for debugging
[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
13 #include "appl_defs.h"
14 #include "usb/usb_defs.h"
15
16 #ifdef CONFIG_KEYVAL
17 #include <keyvalpb.h>
18 #include <lpciap.h>
19 #include <lpciap_kvpb.h>
20 #include <hal_machperiph.h>
21 #endif /*CONFIG_KEYVAL*/
22
23 usb_device_t usb_device;
24 usb_ep_t eps[NUM_ENDPOINTS];
25
26 #define MASK_EP1RX 0x01
27 #define MASK_EP1TX 0x02
28
29 unsigned char ep1_rx_buff[USB_MAX_PACKET];
30 unsigned char ep1_tx_buff[USB_MAX_PACKET];
31 unsigned char ep0_buffer[USB_MAX_PACKET0];
32 int usb_active = 0;
33 int ep1_rx_index = 0, ep1_rx_ready = 1;
34 int ep1_tx_index = 0, ep1_tx_chars = 0;
35
36 #ifdef CONFIG_OC_CMDPROC
37
38 cmd_io_t cmd_io_usbcon_dev;
39
40 #define ED_LINE_CHARS 512
41
42 char ed_line_chars_usbcon_in[ED_LINE_CHARS + 1];
43 char ed_line_chars_usbcon_out[ED_LINE_CHARS + 1];
44
45 ed_line_buf_t ed_line_buf_usbcon_in =
46 {
47 flg:
48   FL_ELB_ECHO,
49   inbuf: 0,
50 alloc:
51   sizeof(ed_line_chars_usbcon_in),
52   maxlen: 0,
53   lastch: 0,
54 buf:
55   ed_line_chars_usbcon_in
56 };
57
58 ed_line_buf_t ed_line_buf_usbcon_out =
59 {
60 flg:
61   FL_ELB_NOCRLF,
62   inbuf: 0,
63 alloc:
64   sizeof(ed_line_chars_usbcon_out),
65   maxlen: 0,
66   lastch: 0,
67 buf:
68   ed_line_chars_usbcon_out
69 };
70
71 cmd_io_t cmd_io_usbcon =
72 {
73 putc:
74   cmd_io_line_putc,
75 getc:
76   NULL,
77 write:
78   cmd_io_write_bychar,
79 read:
80   NULL,
81 priv:
82   {
83   ed_line:
84     {
85     in:
86       &ed_line_buf_usbcon_in,
87     out:
88       &ed_line_buf_usbcon_out,
89     io_stack:
90       &cmd_io_usbcon_dev
91     }
92   }
93 };
94
95 #endif
96
97 static int usb_flash_pkt_wr(struct usb_ep_t *ep, int len, int code)
98 {
99   unsigned char *ptr = ep->ptr - len;
100
101 #ifdef CONFIG_KEYVAL
102   lpcisp_kvpb_copy(NULL, (void *)ep->user_data, ptr, len);
103 #endif /*CONFIG_KEYVAL*/
104
105   ep->user_data += len;
106   ep->ptr = ep0_buffer;
107   return USB_COMPLETE_OK;
108 }
109
110 static int usb_flash_erase(unsigned addr, unsigned len)
111 {
112 #ifdef CONFIG_KEYVAL
113   lpcisp_erase((void *)addr, len);
114 #endif /*CONFIG_KEYVAL*/
115   return 0;
116 }
117
118 static void usb_goto(unsigned address)
119 {
120 #ifdef CONFIG_KEYVAL
121   lpc_watchdog_init(1, 10);
122   lpc_watchdog_feed();
123
124   while (1)
125     {}
126
127 #endif /*CONFIG_KEYVAL*/
128 }
129
130 int appl_usb_vendor(usb_device_t *udev)
131 {
132   unsigned long addr;
133   unsigned len;
134   USB_DEVICE_REQUEST *dreq;
135
136   usb_active = 1;
137   dreq = &udev->request;
138
139 #ifdef CONFIG_KEYVAL
140
141   if (dreq->bRequest != (USB_VENDOR_GET_SET_MEMORY |
142                          USB_DATA_DIR_FROM_HOST | USB_VENDOR_TARGET_FLASH))
143     lpcisp_kvpb_flush(NULL);
144
145 #endif /*CONFIG_KEYVAL*/
146
147   switch (dreq->bRequest & USB_VENDOR_MASK)
148   {
149
150     case USB_VENDOR_GET_CAPABILITIES:
151       ep0_buffer[0] = 0xAA; // test
152       usb_send_control_data(udev, ep0_buffer, 1);
153       return 1;
154
155     case USB_VENDOR_RESET_DEVICE:
156       usb_send_control_data(udev, NULL, 0);
157 #ifdef CONFIG_KEYVAL
158       lpc_watchdog_init(1, 10);
159       lpc_watchdog_feed();
160
161       while (1)
162         {}
163
164 #endif /*CONFIG_KEYVAL*/
165       return 1;
166
167     case USB_VENDOR_GOTO:
168       usb_send_control_data(udev, NULL, 0);
169       usb_goto(dreq->wValue);
170       return 1;
171
172     case USB_VENDOR_ERASE_MEMORY:
173       usb_send_control_data(udev, NULL, 0);
174       usb_flash_erase(dreq->wValue, dreq->wIndex);
175       return 1;
176
177     case USB_VENDOR_ERASE_1KB_MEMORY:  /* erase memory for 1 KB */
178       usb_send_control_data(udev, NULL, 0);
179       usb_flash_erase((uint32_t)dreq->wValue << 10, dreq->wIndex << 10);
180       return 1;
181
182     case USB_VENDOR_GET_SET_MEMORY:
183       addr = (dreq->wValue & 0xffff) | (((unsigned long)dreq->wIndex & 0xffff) << 16);
184       len = dreq->wLength;
185
186       if ((dreq->bmRequestType & USB_DATA_DIR_MASK) == USB_DATA_DIR_FROM_HOST)
187       {
188         switch (dreq->bRequest & USB_VENDOR_TARGET_MASK)
189         {
190           case USB_VENDOR_TARGET_RAM:
191             udev->ep0.ptr = (void *)addr;
192             break;
193
194           case USB_VENDOR_TARGET_FLASH:
195             udev->ep0.next_pkt_fnc = usb_flash_pkt_wr;
196             udev->ep0.user_data = addr;
197             udev->ep0.ptr = ep0_buffer;
198             break;
199
200           default:
201             return -1;
202         }
203
204         if (len)
205           usb_set_control_endfnc(udev, usb_ack_setup);
206         else
207           usb_send_control_data(udev, NULL, 0);
208
209         return 1;
210       }
211       else
212       {
213         switch (dreq->bRequest & USB_VENDOR_TARGET_MASK)
214         {
215           case USB_VENDOR_TARGET_RAM:
216             usb_send_control_data(udev, (void *)addr, len);
217             break;
218
219           default:
220             return -1;
221         }
222
223         return 1;
224       }
225
226       break;
227   }
228
229   return 0;
230 }
231
232 int usb_app_fill_serial_number(uint32_t ul_sn)
233 {
234   char *p = usb_devdes_serial_number;
235   int len_max = sizeof(usb_devdes_serial_number);
236   char c;
237
238   while ((len_max -= 2) >= 2)
239   {
240     p += 2;
241     c = ((ul_sn >> (32 - 4)) & 0xf) + '0';
242     ul_sn <<= 4;
243
244     if (c > '9')
245       c += 'A' - '9' - 1;
246
247     *p = c;
248   }
249
250   return 0;
251 }
252
253 int usb_app_init(void)
254 {
255   memset(&usb_device, 0, sizeof(usb_device));
256
257   eps[0].max_packet_size = USB_MAX_PACKET;
258   eps[1].max_packet_size = USB_MAX_PACKET;
259   eps[0].epnum = 0x81;
260   eps[1].epnum = 0x01;
261   eps[0].event_mask = 0x08;
262   eps[1].event_mask = 0x04;
263   eps[0].udev = &usb_device;
264   eps[1].udev = &usb_device;
265
266   usb_device.id = 1;
267   usb_device.devdes_table = &usb_devdes_table;
268   usb_device.init = usb_lpc_init;
269   usb_debug_set_level(DEBUG_LEVEL_NONE);
270   usb_device.cntep = NUM_ENDPOINTS;
271   usb_device.ep = eps;
272   usb_device.vendor_fnc = appl_usb_vendor;
273
274   usb_init(&usb_device);
275   usb_connect(&usb_device);
276
277   return 0;
278 }
279
280 int usb_app_poll(void)
281 {
282   int active = usb_active;
283   usb_active = 0;
284
285   usb_check_events(&usb_device);
286   usb_control_response(&usb_device);
287
288   /* Check if host sent us something */
289   if (usb_device.ep_events & MASK_EP1TX)
290   {
291     ep1_tx_chars = usb_udev_read_endpoint(&eps[1], ep1_tx_buff, USB_MAX_PACKET);
292     ep1_tx_index = 0;
293     usb_device.ep_events &= ~MASK_EP1TX;
294     CLR_OUT_PIN(LED_PORT, LED2_BIT);
295     usb_active = 1;
296   }
297
298   if (usb_device.ep_events & MASK_EP1RX)
299   {
300     usb_device.ep_events &= ~MASK_EP1RX;
301     ep1_rx_ready = 1;
302   }
303
304   /* Respond if there is something to send and RX is ready */
305   if (ep1_rx_ready && ep1_rx_index != 0)
306   {
307     usb_udev_write_endpoint(&eps[0], ep1_rx_buff, ep1_rx_index);
308     ep1_rx_index = 0;
309     ep1_rx_ready = 0;
310     CLR_OUT_PIN(LED_PORT, LED2_BIT);
311     usb_active = 1;
312   }
313
314   return active;
315 }
316
317 int usb_app_stop(void)
318 {
319   usb_disconnect(&usb_device);
320   return 0;
321 }
322
323 #ifdef CONFIG_OC_CMDPROC
324
325 int cmd_io_getc_usbcon(struct cmd_io *cmd_io)
326 {
327   if (ep1_tx_index >= ep1_tx_chars)
328     return -1;
329
330   return ep1_tx_buff[ep1_tx_index++];
331 }
332
333 int cmd_io_putc_usbcon(struct cmd_io *cmd_io, int ch)
334 {
335   if (ep1_rx_index >= USB_MAX_PACKET)
336   {
337     /* Poll USB and return -1
338      * FIXME: Ugly and hackish. Should be in ISR of course.
339      */
340     usb_app_poll();
341     return -1;
342   }
343
344   ep1_rx_buff[ep1_rx_index++] = (unsigned char)ch;
345   return ch;
346 }
347
348 cmd_io_t cmd_io_usbcon_dev =
349 {
350   .putc = cmd_io_putc_usbcon,
351   .getc = cmd_io_getc_usbcon,
352   .write = cmd_io_write_bychar,
353   .read = cmd_io_read_bychar,
354   .priv.uart = { -1 }
355 };
356
357 #endif