ae83f9b22c27c85ab80069c7b71d6f970fc9e1ed
[gnuk/neug.git] / src / main.c
1 /*
2  * main.c - main routine of neug
3  *
4  * Main routine:
5  * Copyright (C) 2011, 2012, 2013, 2015, 2016, 2017
6  *               Free Software Initiative of Japan
7  * Author: NIIBE Yutaka <gniibe@fsij.org>
8  *
9  * This file is a part of NeuG, a True Random Number Generator
10  * implementation.
11  *
12  * NeuG is free software: you can redistribute it and/or modify it
13  * under the terms of the GNU General Public License as published by
14  * the Free Software Foundation, either version 3 of the License, or
15  * (at your option) any later version.
16  *
17  * NeuG is distributed in the hope that it will be useful, but WITHOUT
18  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
20  * License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
24  *
25  */
26
27
28 #include <stdint.h>
29 #include <string.h>
30 #include <chopstx.h>
31
32 #include "config.h"
33 #include "neug.h"
34 #include "usb_lld.h"
35 #include "sys.h"
36 #ifndef GNU_LINUX_EMULATION
37 #include "mcu/stm32f103.h"
38 #endif
39 #include "adc.h"
40
41 enum {
42   FSIJ_DEVICE_RUNNING = 0,
43   FSIJ_DEVICE_EXITED,
44   FSIJ_DEVICE_EXEC_REQUESTED,
45   /**/
46   FSIJ_DEVICE_NEUG_FRAUCHEKY_REQUESTED = 254,
47   FSIJ_DEVICE_NEUG_EXIT_REQUESTED = 255
48 };
49
50 #ifdef FRAUCHEKY_SUPPORT
51 static uint8_t running_neug;
52 extern void EP6_IN_Callback (uint16_t len);
53 extern void EP6_OUT_Callback (uint16_t len);
54 #endif
55
56 static chopstx_mutex_t usb_mtx;
57 static chopstx_cond_t usb_cnd;
58 static uint32_t bDeviceState = UNCONNECTED; /* USB device status */
59 static uint8_t fsij_device_state = FSIJ_DEVICE_RUNNING;
60 static uint8_t connected;
61
62
63 #define ENDP0_RXADDR        (0x40)
64 #define ENDP0_TXADDR        (0x80)
65 #define ENDP1_TXADDR        (0xc0)
66 #define ENDP2_TXADDR        (0x100)
67 #define ENDP3_RXADDR        (0x140)
68
69 #define USB_CDC_REQ_SET_LINE_CODING             0x20
70 #define USB_CDC_REQ_GET_LINE_CODING             0x21
71 #define USB_CDC_REQ_SET_CONTROL_LINE_STATE      0x22
72 #define USB_CDC_REQ_SEND_BREAK                  0x23
73
74 /* USB Device Descriptor */
75 static const uint8_t vcom_device_desc[18] = {
76   18,   /* bLength */
77   DEVICE_DESCRIPTOR,            /* bDescriptorType */
78   0x10, 0x01,                   /* bcdUSB = 1.1 */
79   0x02,                         /* bDeviceClass (CDC).              */
80   0x00,                         /* bDeviceSubClass.                 */
81   0x00,                         /* bDeviceProtocol.                 */
82   0x40,                         /* bMaxPacketSize.                  */
83 #include "usb-vid-pid-ver.c.inc"
84   1,                            /* iManufacturer.                   */
85   2,                            /* iProduct.                        */
86   3,                            /* iSerialNumber.                   */
87   1                             /* bNumConfigurations.              */
88 };
89
90 #define VCOM_FEATURE_BUS_POWERED        0x80
91
92 /* Configuration Descriptor tree for a CDC.*/
93 static const uint8_t vcom_config_desc[67] = {
94   9,
95   CONFIG_DESCRIPTOR,            /* bDescriptorType: Configuration   */
96   /* Configuration Descriptor.*/
97   67, 0x00,                     /* wTotalLength.                    */
98   0x02,                         /* bNumInterfaces.                  */
99   0x01,                         /* bConfigurationValue.             */
100   0,                            /* iConfiguration.                  */
101   VCOM_FEATURE_BUS_POWERED,     /* bmAttributes.                    */
102   50,                           /* bMaxPower (100mA).               */
103   /* Interface Descriptor.*/
104   9,
105   INTERFACE_DESCRIPTOR,
106   0x00,            /* bInterfaceNumber.                */
107   0x00,            /* bAlternateSetting.               */
108   0x01,            /* bNumEndpoints.                   */
109   0x02,            /* bInterfaceClass (Communications Interface Class,
110                       CDC section 4.2).  */
111   0x02,            /* bInterfaceSubClass (Abstract Control Model, CDC
112                       section 4.3).  */
113   0x01,            /* bInterfaceProtocol (AT commands, CDC section
114                       4.4).  */
115   0,               /* iInterface.                      */
116   /* Header Functional Descriptor (CDC section 5.2.3).*/
117   5,          /* bLength.                         */
118   0x24,       /* bDescriptorType (CS_INTERFACE).  */
119   0x00,       /* bDescriptorSubtype (Header Functional Descriptor). */
120   0x10, 0x01, /* bcdCDC.                          */
121   /* Call Management Functional Descriptor. */
122   5,            /* bFunctionLength.                 */
123   0x24,         /* bDescriptorType (CS_INTERFACE).  */
124   0x01,         /* bDescriptorSubtype (Call Management Functional
125                    Descriptor). */
126   0x03,         /* bmCapabilities (D0+D1).          */
127   0x01,         /* bDataInterface.                  */
128   /* ACM Functional Descriptor.*/
129   4,            /* bFunctionLength.                 */
130   0x24,         /* bDescriptorType (CS_INTERFACE).  */
131   0x02,         /* bDescriptorSubtype (Abstract Control Management
132                    Descriptor).  */
133   0x02,         /* bmCapabilities.                  */
134   /* Union Functional Descriptor.*/
135   5,            /* bFunctionLength.                 */
136   0x24,         /* bDescriptorType (CS_INTERFACE).  */
137   0x06,         /* bDescriptorSubtype (Union Functional
138                    Descriptor).  */
139   0x00,         /* bMasterInterface (Communication Class
140                    Interface).  */
141   0x01,         /* bSlaveInterface0 (Data Class Interface).  */
142   /* Endpoint 2 Descriptor.*/
143   7,
144   ENDPOINT_DESCRIPTOR,
145   ENDP2|0x80,    /* bEndpointAddress.    */
146   0x03,          /* bmAttributes (Interrupt).        */
147   0x08, 0x00,    /* wMaxPacketSize.                  */
148   0xFF,          /* bInterval.                       */
149   /* Interface Descriptor.*/
150   9,
151   INTERFACE_DESCRIPTOR,          /* bDescriptorType: */
152   0x01,          /* bInterfaceNumber.                */
153   0x00,          /* bAlternateSetting.               */
154   0x02,          /* bNumEndpoints.                   */
155   0x0A,          /* bInterfaceClass (Data Class Interface, CDC section 4.5). */
156   0x00,          /* bInterfaceSubClass (CDC section 4.6). */
157   0x00,          /* bInterfaceProtocol (CDC section 4.7). */
158   0x00,          /* iInterface.                      */
159   /* Endpoint 3 Descriptor.*/
160   7,
161   ENDPOINT_DESCRIPTOR,          /* bDescriptorType: Endpoint */
162   ENDP3,    /* bEndpointAddress. */
163   0x02,                         /* bmAttributes (Bulk).             */
164   0x40, 0x00,                   /* wMaxPacketSize.                  */
165   0x00,                         /* bInterval.                       */
166   /* Endpoint 1 Descriptor.*/
167   7,
168   ENDPOINT_DESCRIPTOR,          /* bDescriptorType: Endpoint */
169   ENDP1|0x80,                   /* bEndpointAddress. */
170   0x02,                         /* bmAttributes (Bulk).             */
171   0x40, 0x00,                   /* wMaxPacketSize.                  */
172   0x00                          /* bInterval.                       */
173 };
174
175
176 /*
177  * U.S. English language identifier.
178  */
179 static const uint8_t vcom_string0[4] = {
180   4,                            /* bLength */
181   STRING_DESCRIPTOR,
182   0x09, 0x04                    /* LangID = 0x0409: US-English */
183 };
184
185 #include "usb-strings.c.inc"
186
187 static void neug_setup_endpoints_for_interface (struct usb_dev *dev,
188                                                 uint16_t interface, int stop);
189 #ifdef FRAUCHEKY_SUPPORT
190 #define MSC_MASS_STORAGE_RESET_COMMAND 0xFF
191 extern int fraucheky_enabled (void);
192 extern void fraucheky_main (void);
193
194 extern void fraucheky_setup_endpoints_for_interface (int stop);
195 extern int fraucheky_setup (struct usb_dev *dev);
196 extern int fraucheky_get_descriptor (struct usb_dev *dev);
197 #endif
198
199 #define NUM_INTERFACES 2
200
201 static void
202 usb_device_reset (struct usb_dev *dev)
203 {
204   int i;
205
206   usb_lld_reset (dev, VCOM_FEATURE_BUS_POWERED);
207
208   /* Initialize Endpoint 0.  */
209 #ifdef GNU_LINUX_EMULATION
210   usb_lld_setup_endp (dev, ENDP0, 1, 1);
211 #else
212   usb_lld_setup_endpoint (ENDP0, EP_CONTROL, 0, ENDP0_RXADDR, ENDP0_TXADDR, 64);
213 #endif
214
215   /* Stop the interface */
216   for (i = 0; i < NUM_INTERFACES; i++)
217     neug_setup_endpoints_for_interface (dev, i, 1);
218
219   /* Notify upper layer.  */
220   chopstx_mutex_lock (&usb_mtx);
221   bDeviceState = ATTACHED;
222   connected = 0;
223   chopstx_cond_signal (&usb_cnd);
224   chopstx_mutex_unlock (&usb_mtx);
225 }
226
227 extern uint8_t _regnual_start, __heap_end__;
228
229 static const uint8_t *const mem_info[] = { &_regnual_start,  &__heap_end__, };
230
231 /* USB vendor requests to control pipe */
232 #define USB_FSIJ_MEMINFO          0
233 #define USB_FSIJ_DOWNLOAD         1
234 #define USB_FSIJ_EXEC             2
235 #define USB_NEUG_SET_PASSWD     253
236 #define USB_NEUG_GET_INFO       254
237 #define USB_NEUG_EXIT           255 /* Ask to exit and to receive reGNUal */
238
239 uint8_t neug_passwd[33] __attribute__ ((section(".passwd"))) = {
240   0xff,
241   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
242   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
243   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
244 };
245 static uint8_t usbbuf[64];
246
247 #define DEFAULT_PASSWD "12345678"
248 #define DEFAULT_PASSWD_LEN 8
249
250 static void set_passwd (void)
251 {
252   flash_unlock ();
253   if (neug_passwd[0] != 0xff)
254     flash_erase_page ((uintptr_t)neug_passwd);
255   if (usbbuf[0] == DEFAULT_PASSWD_LEN
256       && !memcmp (usbbuf + 1, DEFAULT_PASSWD, DEFAULT_PASSWD_LEN))
257     return;
258   flash_write ((uintptr_t)neug_passwd, usbbuf, usbbuf[0] + 1);
259 }
260
261
262 /* After calling this function, CRC module remain enabled.  */
263 static int download_check_crc32 (struct usb_dev *dev, const uint32_t *end_p)
264 {
265   uint32_t crc32 = *end_p;
266   const uint32_t *p;
267
268   crc32_rv_reset ();
269
270   for (p = (const uint32_t *)&_regnual_start; p < end_p; p++)
271     crc32_rv_step (rbit (*p));
272
273   if ((rbit (crc32_rv_get ()) ^ crc32) == 0xffffffff)
274     return usb_lld_ctrl_ack (dev);
275
276   return -1;
277 }
278
279
280 #define NEUG_SPECIAL_BITRATE 110
281
282 struct line_coding
283 {
284   uint32_t bitrate;
285   uint8_t format;
286   uint8_t paritytype;
287   uint8_t datatype;
288 } __attribute__((packed));
289
290 static struct line_coding line_coding = {
291   115200, /* baud rate: 115200    */
292   0x00,   /* stop bits: 1         */
293   0x00,   /* parity:    none      */
294   0x08    /* bits:      8         */
295 };
296
297 #define CDC_CTRL_DTR            0x0001
298
299 static void
300 usb_ctrl_write_finish (struct usb_dev *dev)
301 {
302   struct device_req *arg = &dev->dev_req;
303   uint8_t type_rcp = arg->type & (REQUEST_TYPE|RECIPIENT);
304
305   if (type_rcp == (VENDOR_REQUEST | DEVICE_RECIPIENT)
306       && USB_SETUP_SET (arg->type))
307     {
308       if (arg->request == USB_FSIJ_EXEC)
309         {
310           chopstx_mutex_lock (&usb_mtx);
311           if (fsij_device_state == FSIJ_DEVICE_EXITED)
312             {
313               usb_lld_prepare_shutdown (); /* No further USB communication */
314               fsij_device_state = FSIJ_DEVICE_EXEC_REQUESTED;
315             }
316           chopstx_mutex_unlock (&usb_mtx);
317         }
318       else if (arg->request == USB_NEUG_SET_PASSWD)
319         set_passwd ();
320       else if (arg->request == USB_NEUG_EXIT)
321         {
322           if ((neug_passwd[0] == 0xff && usbbuf[0] == DEFAULT_PASSWD_LEN
323                && !memcmp (usbbuf + 1, DEFAULT_PASSWD, DEFAULT_PASSWD_LEN))
324               || (neug_passwd[0] == usbbuf[0]
325                   && !memcmp (neug_passwd+1, usbbuf+1, neug_passwd[0])))
326             {
327               chopstx_mutex_lock (&usb_mtx);
328               fsij_device_state = FSIJ_DEVICE_NEUG_EXIT_REQUESTED;
329               chopstx_cond_signal (&usb_cnd);
330               chopstx_mutex_unlock (&usb_mtx);
331             }
332         }
333     }
334   else if (type_rcp == (CLASS_REQUEST | INTERFACE_RECIPIENT) && arg->index == 0
335            && USB_SETUP_SET (arg->type))
336     {
337       if (arg->request == USB_CDC_REQ_SET_CONTROL_LINE_STATE)
338         {
339           /* Open/close the connection.  */
340           chopstx_mutex_lock (&usb_mtx);
341           connected = (arg->value & CDC_CTRL_DTR)? 1 : 0;
342           chopstx_cond_signal (&usb_cnd);
343           chopstx_mutex_unlock (&usb_mtx);
344         }
345 #ifdef FRAUCHEKY_SUPPORT
346       else if (running_neug && arg->request == USB_CDC_REQ_SET_LINE_CODING)
347         {
348           chopstx_mutex_lock (&usb_mtx);
349           if (line_coding.bitrate == NEUG_SPECIAL_BITRATE)
350             {
351               fsij_device_state = FSIJ_DEVICE_NEUG_FRAUCHEKY_REQUESTED;
352               chopstx_cond_signal (&usb_cnd);
353             }
354           else if (fsij_device_state == FSIJ_DEVICE_NEUG_FRAUCHEKY_REQUESTED)
355             fsij_device_state = FSIJ_DEVICE_RUNNING;
356           chopstx_mutex_unlock (&usb_mtx);
357         }
358       else if (!running_neug && arg->request == MSC_MASS_STORAGE_RESET_COMMAND)
359         fraucheky_setup_endpoints_for_interface (0);
360 #endif
361     }
362 }
363
364
365 static int
366 vcom_port_data_setup (struct usb_dev *dev)
367 {
368   struct device_req *arg = &dev->dev_req;
369
370   if (USB_SETUP_GET (arg->type))
371     {
372       if (arg->request == USB_CDC_REQ_GET_LINE_CODING)
373         return usb_lld_ctrl_send (dev, &line_coding, sizeof(line_coding));
374     }
375   else  /* USB_SETUP_SET (req) */
376     {
377       if (arg->request == USB_CDC_REQ_SET_LINE_CODING
378           && arg->len == sizeof (line_coding))
379         return usb_lld_ctrl_recv (dev, &line_coding, sizeof (line_coding));
380       else if (arg->request == USB_CDC_REQ_SET_CONTROL_LINE_STATE)
381         return usb_lld_ctrl_ack (dev);
382     }
383
384   return -1;
385 }
386
387 static int
388 usb_setup (struct usb_dev *dev)
389 {
390   struct device_req *arg = &dev->dev_req;
391   uint8_t type_rcp = arg->type & (REQUEST_TYPE|RECIPIENT);
392
393   if (type_rcp == (VENDOR_REQUEST | DEVICE_RECIPIENT))
394     {
395       if (USB_SETUP_GET (arg->type))
396         {
397           if (arg->request == USB_FSIJ_MEMINFO)
398             {
399               chopstx_mutex_lock (&usb_mtx);
400               if (fsij_device_state != FSIJ_DEVICE_EXITED)
401                 {
402                   chopstx_mutex_unlock (&usb_mtx);
403                   return -1;
404                 }
405               chopstx_mutex_unlock (&usb_mtx);
406               return usb_lld_ctrl_send (dev, mem_info, sizeof (mem_info));
407             }
408           else if (arg->request == USB_NEUG_GET_INFO)
409             {
410               if (arg->index == 0)
411                 return usb_lld_ctrl_send (dev, &neug_mode, sizeof (uint8_t));
412               else if (arg->index == 1)
413                 return usb_lld_ctrl_send (dev, &neug_err_cnt, sizeof (uint16_t));
414               else if (arg->index == 2)
415                 return usb_lld_ctrl_send (dev, &neug_err_cnt_rc, sizeof (uint16_t));
416               else if (arg->index == 3)
417                 return usb_lld_ctrl_send (dev, &neug_err_cnt_p64, sizeof (uint16_t));
418               else if (arg->index == 4)
419                 return usb_lld_ctrl_send (dev, &neug_err_cnt_p4k, sizeof (uint16_t));
420               else if (arg->index == 5)
421                 return usb_lld_ctrl_send (dev, &neug_rc_max, sizeof (uint16_t));
422               else if (arg->index == 6)
423                 return usb_lld_ctrl_send (dev, &neug_p64_max, sizeof (uint16_t));
424               else if (arg->index == 7)
425                 return usb_lld_ctrl_send (dev, &neug_p4k_max, sizeof (uint16_t));
426               else
427                 return -1;
428             }
429         }
430       else /* SETUP_SET */
431         {
432           uint8_t *addr = (uint8_t *)(0x20000000UL + arg->value * 0x100 + arg->index);
433
434           if (arg->request == USB_FSIJ_DOWNLOAD)
435             {
436               chopstx_mutex_lock (&usb_mtx);
437               if (fsij_device_state != FSIJ_DEVICE_EXITED)
438                 {
439                   chopstx_mutex_unlock (&usb_mtx);
440                   return -1;
441                 }
442               chopstx_mutex_unlock (&usb_mtx);
443
444               if (addr < &_regnual_start || addr + arg->len > &__heap_end__)
445                 return -1;
446
447               if (arg->index + arg->len < 256)
448                 memset (addr + arg->index + arg->len, 0, 256 - (arg->index + arg->len));
449
450               return usb_lld_ctrl_recv (dev, addr, arg->len);
451             }
452           else if (arg->request == USB_FSIJ_EXEC && arg->len == 0)
453             {
454               chopstx_mutex_lock (&usb_mtx);
455               if (fsij_device_state != FSIJ_DEVICE_EXITED)
456                 {
457                   chopstx_mutex_unlock (&usb_mtx);
458                   return -1;
459                 }
460               chopstx_mutex_unlock (&usb_mtx);
461
462               if (((uintptr_t)addr & 0x03))
463                 return -1;
464
465               return download_check_crc32 (dev, (uint32_t *)addr);
466             }
467           else if (arg->request == USB_NEUG_SET_PASSWD && arg->len <= 32)
468             {
469               usbbuf[0] = arg->len;
470               return usb_lld_ctrl_recv (dev, usbbuf + 1, arg->len);
471             }
472           else if (arg->request == USB_NEUG_EXIT && arg->len <= 32)
473             {
474               chopstx_mutex_lock (&usb_mtx);
475               if (fsij_device_state != FSIJ_DEVICE_RUNNING)
476                 {
477                   chopstx_mutex_unlock (&usb_mtx);
478                   return -1;
479                 }
480               chopstx_mutex_unlock (&usb_mtx);
481
482               usbbuf[0] = arg->len;
483               return usb_lld_ctrl_recv (dev, usbbuf + 1, arg->len);
484             }
485         }
486     }
487   else if (type_rcp == (CLASS_REQUEST | INTERFACE_RECIPIENT)
488            && arg->index == 0)
489     {
490 #ifdef FRAUCHEKY_SUPPORT
491       if (running_neug)
492         return vcom_port_data_setup (dev);
493       else
494         return fraucheky_setup (dev);
495 #else
496       return vcom_port_data_setup (dev);
497 #endif
498     }
499
500   return -1;
501 }
502
503 static int
504 usb_get_descriptor (struct usb_dev *dev)
505 {
506   struct device_req *arg = &dev->dev_req;
507   uint8_t rcp = arg->type & RECIPIENT;
508   uint8_t desc_type = (arg->value >> 8);
509   uint8_t desc_index = (arg->value & 0xff);
510
511 #ifdef FRAUCHEKY_SUPPORT
512   if (!running_neug)
513     return fraucheky_get_descriptor (dev);
514 #endif
515
516   if (rcp != DEVICE_RECIPIENT)
517     return -1;
518
519   if (desc_type == DEVICE_DESCRIPTOR)
520     return usb_lld_ctrl_send (dev,
521                               vcom_device_desc, sizeof (vcom_device_desc));
522   else if (desc_type == CONFIG_DESCRIPTOR)
523     return usb_lld_ctrl_send (dev,
524                               vcom_config_desc, sizeof (vcom_config_desc));
525   else if (desc_type == STRING_DESCRIPTOR)
526     {
527       const uint8_t *str;
528       int size;
529
530       switch (desc_index)
531         {
532         case 0:
533           str = vcom_string0;
534           size = sizeof (vcom_string0);
535           break;
536         case 1:
537           str = neug_string_vendor;
538           size = sizeof (neug_string_vendor);
539           break;
540         case 2:
541           str = neug_string_product;
542           size = sizeof (neug_string_product);
543           break;
544         case 3:
545           str = neug_string_serial;
546           size = sizeof (neug_string_serial);
547           break;
548         case 4:
549           str = neug_revision_detail;
550           size = sizeof (neug_revision_detail);
551           break;
552         case 5:
553           str = neug_config_options;
554           size = sizeof (neug_config_options);
555           break;
556         case 6:
557           str = sys_version;
558           size = sizeof (sys_version);
559           break;
560 #ifdef USE_SYS3
561         case 7:
562           {
563             int i;
564             str = usbbuf;
565             for (i = 0; i < (int)sizeof (usbbuf)/2 - 2; i++)
566               {
567                 if (sys_board_name[i] == 0)
568                   break;
569
570                 usbbuf[i*2+2] = sys_board_name[i];
571                 usbbuf[i*2+3] = 0;
572               }
573             usbbuf[0] = i*2 + 2;
574             usbbuf[1] = STRING_DESCRIPTOR;
575             size = i*2 + 2;
576           }
577           break;
578 #endif
579         default:
580           return -1;
581         }
582
583       return usb_lld_ctrl_send (dev, str, size);
584     }
585
586   return -1;
587 }
588
589 static void
590 neug_setup_endpoints_for_interface (struct usb_dev *dev,
591                                     uint16_t interface, int stop)
592 {
593 #if !defined(GNU_LINUX_EMULATION)
594   (void)dev;
595 #endif
596   
597   if (interface == 0)
598     {
599 #ifdef FRAUCHEKY_SUPPORT
600       if (running_neug)
601         {
602           if (!stop)
603 #ifdef GNU_LINUX_EMULATION
604             usb_lld_setup_endp (dev, ENDP2, 0, 1);
605 #else
606             usb_lld_setup_endpoint (ENDP2, EP_INTERRUPT, 0, 0, ENDP2_TXADDR, 0);
607 #endif
608           else
609             usb_lld_stall_tx (ENDP2);
610         }
611       else
612         fraucheky_setup_endpoints_for_interface (stop);
613 #else
614       if (!stop)
615 #ifdef GNU_LINUX_EMULATION
616         usb_lld_setup_endp (dev, ENDP2, 0, 1);
617 #else
618         usb_lld_setup_endpoint (ENDP2, EP_INTERRUPT, 0, 0, ENDP2_TXADDR, 0);
619 #endif
620       else
621         usb_lld_stall_tx (ENDP2);
622 #endif
623     }
624   else if (interface == 1)
625     {
626       if (!stop)
627         {
628 #ifdef GNU_LINUX_EMULATION
629           usb_lld_setup_endp (dev, ENDP1, 0, 1);
630           usb_lld_setup_endp (dev, ENDP3, 1, 0);
631 #else
632           usb_lld_setup_endpoint (ENDP1, EP_BULK, 0, 0, ENDP1_TXADDR, 0);
633           usb_lld_setup_endpoint (ENDP3, EP_BULK, 0, ENDP3_RXADDR, 0, 64);
634 #endif
635           /* Start with no data receiving (ENDP3 not enabled) */
636         }
637       else
638         {
639           usb_lld_stall_tx (ENDP1);
640           usb_lld_stall_rx (ENDP3);
641         }
642     }
643 }
644
645 static int
646 usb_set_configuration (struct usb_dev *dev)
647 {
648   int i;
649   uint8_t current_conf;
650
651   current_conf = usb_lld_current_configuration (dev);
652   if (current_conf == 0)
653     {
654       if (dev->dev_req.value != 1)
655         return -1;
656
657       usb_lld_set_configuration (dev, 1);
658       for (i = 0; i < NUM_INTERFACES; i++)
659         neug_setup_endpoints_for_interface (dev, i, 0);
660       chopstx_mutex_lock (&usb_mtx);
661       bDeviceState = CONFIGURED;
662       chopstx_mutex_unlock (&usb_mtx);
663     }
664   else if (current_conf != dev->dev_req.value)
665     {
666       if (dev->dev_req.value != 0)
667         return -1;
668
669       usb_lld_set_configuration (dev, 0);
670       for (i = 0; i < NUM_INTERFACES; i++)
671         neug_setup_endpoints_for_interface (dev, i, 1);
672       chopstx_mutex_lock (&usb_mtx);
673       bDeviceState = ADDRESSED;
674       chopstx_cond_signal (&usb_cnd);
675       chopstx_mutex_unlock (&usb_mtx);
676     }
677
678   /* Do nothing when current_conf == value */
679   return usb_lld_ctrl_ack (dev);
680 }
681
682
683 static int
684 usb_set_interface (struct usb_dev *dev)
685 {
686   uint16_t interface = dev->dev_req.index;
687   uint16_t alt = dev->dev_req.value;
688
689   if (interface >= NUM_INTERFACES)
690     return -1;
691
692   if (alt != 0)
693     return -1;
694   else
695     {
696       neug_setup_endpoints_for_interface (dev, interface, 0);
697       return usb_lld_ctrl_ack (dev);
698     }
699 }
700
701 static int
702 usb_get_interface (struct usb_dev *dev)
703 {
704   const uint8_t zero = 0;
705   uint16_t interface = dev->dev_req.index;
706
707   if (interface >= NUM_INTERFACES)
708     return -1;
709
710   return usb_lld_ctrl_send (dev, &zero, 1);
711 }
712
713
714 static int
715 usb_get_status_interface (struct usb_dev *dev)
716 {
717   const uint16_t status_info = 0;
718   uint16_t interface = dev->dev_req.index;
719
720   if (interface >= NUM_INTERFACES)
721     return -1;
722
723   return usb_lld_ctrl_send (dev, &status_info, 2);
724 }
725
726 static void usb_tx_done (uint8_t ep_num, uint16_t len);
727 static void usb_rx_ready (uint8_t ep_num, uint16_t len);
728
729
730 #define INTR_REQ_USB 20
731 #define PRIO_USB 3
732
733 static void *
734 usb_main (void *arg)
735 {
736   chopstx_intr_t interrupt;
737   struct usb_dev dev;
738   int e;
739
740   (void)arg;
741   usb_lld_init (&dev, VCOM_FEATURE_BUS_POWERED);
742   chopstx_claim_irq (&interrupt, INTR_REQ_USB);
743   goto event_handle;    /* For old SYS < 3.0 */
744
745   while (1)
746     {
747       chopstx_intr_wait (&interrupt);
748
749       if (interrupt.ready)
750         {
751           uint8_t ep_num;
752
753         event_handle:
754           e = usb_lld_event_handler (&dev);
755           ep_num = USB_EVENT_ENDP (e);
756
757           if (ep_num != 0)
758             {
759               if (USB_EVENT_TXRX (e))
760                 usb_tx_done (ep_num, USB_EVENT_LEN (e));
761               else
762                 usb_rx_ready (ep_num, USB_EVENT_LEN (e));
763             }
764           else
765             switch (USB_EVENT_ID (e))
766               {
767               case USB_EVENT_DEVICE_RESET:
768                 usb_device_reset (&dev);
769                 continue;
770
771               case USB_EVENT_DEVICE_ADDRESSED:
772                 chopstx_mutex_lock (&usb_mtx);
773                 bDeviceState = ADDRESSED;
774                 chopstx_cond_signal (&usb_cnd);
775                 chopstx_mutex_unlock (&usb_mtx);
776                 continue;
777
778               case USB_EVENT_GET_DESCRIPTOR:
779                 if (usb_get_descriptor (&dev) < 0)
780                   usb_lld_ctrl_error (&dev);
781                 continue;
782
783               case USB_EVENT_SET_CONFIGURATION:
784                 if (usb_set_configuration (&dev) < 0)
785                   usb_lld_ctrl_error (&dev);
786                 continue;
787
788               case USB_EVENT_SET_INTERFACE:
789                 if (usb_set_interface (&dev) < 0)
790                   usb_lld_ctrl_error (&dev);
791                 continue;
792
793               case USB_EVENT_CTRL_REQUEST:
794                 /* Device specific device request.  */
795                 if (usb_setup (&dev) < 0)
796                   usb_lld_ctrl_error (&dev);
797                 continue;
798
799               case USB_EVENT_GET_STATUS_INTERFACE:
800                 if (usb_get_status_interface (&dev) < 0)
801                   usb_lld_ctrl_error (&dev);
802                 continue;
803
804               case USB_EVENT_GET_INTERFACE:
805                 if (usb_get_interface (&dev) < 0)
806                   usb_lld_ctrl_error (&dev);
807                 continue;
808
809               case USB_EVENT_SET_FEATURE_DEVICE:
810               case USB_EVENT_SET_FEATURE_ENDPOINT:
811               case USB_EVENT_CLEAR_FEATURE_DEVICE:
812               case USB_EVENT_CLEAR_FEATURE_ENDPOINT:
813                 usb_lld_ctrl_ack (&dev);
814                 continue;
815
816               case USB_EVENT_CTRL_WRITE_FINISH:
817                 /* Control WRITE transfer finished.  */
818                 usb_ctrl_write_finish (&dev);
819                 continue;
820
821               case USB_EVENT_OK:
822               case USB_EVENT_DEVICE_SUSPEND:
823               default:
824                 continue;
825               }
826         }
827     }
828
829   return NULL;
830 }
831
832 #define ID_OFFSET (2+SERIALNO_STR_LEN*2)
833 static void fill_serial_no_by_unique_id (void)
834 {
835   extern const uint8_t * unique_device_id (void);
836   uint8_t *p = &neug_string_serial[ID_OFFSET];
837   const uint8_t *u = unique_device_id () + 8;
838   int i;
839
840   for (i = 0; i < 4; i++)
841     {
842       uint8_t b = u[3-i];
843       uint8_t nibble;
844
845       nibble = (b >> 4);
846       nibble += (nibble >= 10 ? ('A' - 10) : '0');
847       p[i*4] = nibble;
848       p[i*4+1] = 0;
849       nibble = (b & 0x0f);
850       nibble += (nibble >= 10 ? ('A' - 10) : '0');
851       p[i*4+2] = nibble;
852       p[i*4+3] = 0;
853     }
854 }
855
856
857 static void
858 usb_tx_done (uint8_t ep_num, uint16_t len)
859 {
860   if (ep_num == ENDP1)
861     {
862       chopstx_mutex_lock (&usb_mtx);
863       chopstx_cond_signal (&usb_cnd);
864       chopstx_mutex_unlock (&usb_mtx);
865     }
866   else if (ep_num == ENDP2)
867     {
868       /* INTERRUPT Transfer done */
869     }
870 #ifdef FRAUCHEKY_SUPPORT
871   else if (ep_num == ENDP6)
872     EP6_IN_Callback (len);
873 #else
874   (void)len;
875 #endif
876 }
877
878 #ifdef GNU_LINUX_EMULATION
879 static uint8_t endp3_buf[64];
880 #endif
881
882 static void
883 usb_rx_ready (uint8_t ep_num, uint16_t len)
884 {
885   if (ep_num == ENDP3)
886 #ifdef GNU_LINUX_EMULATION
887     usb_lld_rx_enable_buf (ENDP3, endp3_buf, 64);
888 #else
889     usb_lld_rx_enable (ENDP3);
890 #endif
891 #ifdef FRAUCHEKY_SUPPORT
892   else if (ep_num == ENDP6)
893     EP6_OUT_Callback (len);
894 #else
895   (void)len;
896 #endif
897 }
898 \f
899 typedef uint32_t eventmask_t;
900 #define ALL_EVENTS (~0)
901
902 struct event_flag {
903   chopstx_mutex_t mutex;
904   chopstx_cond_t cond;
905   eventmask_t flag;
906 };
907
908 static void event_flag_init (struct event_flag *ev)
909 {
910   ev->flag = 0;
911   chopstx_mutex_init (&ev->mutex);
912   chopstx_cond_init (&ev->cond);
913 }
914
915
916 static eventmask_t event_flag_waitone (struct event_flag *ev, eventmask_t m)
917 {
918   int n;
919
920   chopstx_mutex_lock (&ev->mutex);
921   while (!(ev->flag & m))
922     chopstx_cond_wait (&ev->cond, &ev->mutex);
923
924   n = __builtin_ffs ((ev->flag & m));
925   ev->flag &= ~(1 << (n - 1));
926   chopstx_mutex_unlock (&ev->mutex);
927
928   return (1 << (n - 1));
929 }
930
931 static void event_flag_signal (struct event_flag *ev, eventmask_t m)
932 {
933   chopstx_mutex_lock (&ev->mutex);
934   ev->flag |= m;
935   chopstx_cond_signal (&ev->cond);
936   chopstx_mutex_unlock (&ev->mutex);
937 }
938
939 #ifdef GNU_LINUX_EMULATION
940 extern char __process1_stack_base__[4096];
941 extern char __process3_stack_base__[4096];
942 #define STACK_SIZE_LED (sizeof __process1_stack_base__)
943 #define STACK_SIZE_USB (sizeof __process3_stack_base__)
944 #else
945 extern uint8_t __process1_stack_base__[], __process1_stack_size__[];
946 extern uint8_t __process3_stack_base__[], __process3_stack_size__[];
947 #define STACK_SIZE_LED ((uintptr_t)__process1_stack_size__)
948 #define STACK_SIZE_USB ((uintptr_t)__process3_stack_size__)
949 #endif
950
951 #define STACK_ADDR_LED ((uintptr_t)__process1_stack_base__)
952 #define STACK_ADDR_USB ((uintptr_t)__process3_stack_base__)
953
954
955 #define PRIO_LED 3
956 static struct event_flag led_event;
957
958 #define LED_ONESHOT_SHORT       ((eventmask_t)1)
959 #define LED_TWOSHOTS            ((eventmask_t)2)
960 #define LED_ONESHOT_LONG        ((eventmask_t)4)
961
962 /*
963  * LED blinker: When notified, let LED emit for 100ms.
964  */
965 static void *
966 led_blinker (void *arg)
967 {
968   (void)arg;
969
970   set_led (0);
971
972   while (1)
973     {
974       eventmask_t m;
975
976       m = event_flag_waitone (&led_event, ALL_EVENTS);
977
978       set_led (1);
979       if (m == LED_ONESHOT_SHORT)
980         chopstx_usec_wait (100*1000);
981       else if (m == LED_TWOSHOTS)
982         {
983           chopstx_usec_wait (50*1000);
984           set_led (0);
985           chopstx_usec_wait (50*1000);
986           set_led (1);
987           chopstx_usec_wait (50*1000);
988         }
989       else
990         chopstx_usec_wait (250*1000);
991       set_led (0);
992     }
993
994   return NULL;
995 }
996 \f
997 #define RANDOM_BYTES_LENGTH 64
998 static uint32_t random_word[RANDOM_BYTES_LENGTH/sizeof (uint32_t)];
999
1000 #ifdef GNU_LINUX_EMULATION
1001 static uint8_t endp1_buf[RANDOM_BYTES_LENGTH];
1002 #endif
1003
1004 static void copy_to_tx (uint32_t v, int i)
1005 {
1006 #ifdef GNU_LINUX_EMULATION
1007   memcpy (&endp1_buf[i], &v, 4);
1008 #else
1009   usb_lld_txcpy (&v, ENDP1, i * 4, 4);
1010 #endif
1011 }
1012
1013 /*
1014  * In Gnuk 1.0.[12], reGNUal was not relocatable.
1015  * Now, it's relocatable, but we need to calculate its entry address
1016  * based on it's pre-defined address.
1017  */
1018 #define REGNUAL_START_ADDRESS_COMPATIBLE 0x20001400
1019 static uint32_t
1020 calculate_regnual_entry_address (const uint8_t *addr)
1021 {
1022   const uint8_t *p = addr + 4;
1023   uintptr_t v = p[0] + (p[1] << 8) + (p[2] << 16) + (p[3] << 24);
1024
1025   v -= REGNUAL_START_ADDRESS_COMPATIBLE;
1026   v += (uintptr_t)addr;
1027   return v;
1028 }
1029
1030
1031 static int
1032 check_usb_status (void *arg)
1033 {
1034   (void)arg;
1035
1036   return (connected || bDeviceState != CONFIGURED
1037           || fsij_device_state != FSIJ_DEVICE_RUNNING);
1038 }
1039
1040
1041 #ifdef GNU_LINUX_EMULATION
1042 #define main emulated_main
1043 #endif
1044
1045 /*
1046  * Entry point.
1047  *
1048  * NOTE: the main function is already a thread in the system on entry.
1049  */
1050 int
1051 main (int argc, char **argv)
1052 {
1053   uintptr_t entry;
1054   chopstx_t led_thread, usb_thd;
1055   unsigned int count;
1056
1057   (void)argc;
1058   (void)argv;
1059
1060   fill_serial_no_by_unique_id ();
1061
1062   adc_init ();
1063
1064   event_flag_init (&led_event);
1065
1066   chopstx_mutex_init (&usb_mtx);
1067   chopstx_cond_init (&usb_cnd);
1068
1069 #ifdef FRAUCHEKY_SUPPORT
1070   if (fraucheky_enabled ())
1071     {
1072     go_fraucheky:
1073       bDeviceState = UNCONNECTED;
1074       running_neug = 0;
1075       usb_thd = chopstx_create (PRIO_USB, STACK_ADDR_USB, STACK_SIZE_USB,
1076                                 usb_main, NULL);
1077       while (bDeviceState != CONFIGURED)
1078         chopstx_usec_wait (250*1000);
1079       set_led (1);
1080       fraucheky_main ();
1081       chopstx_cancel (usb_thd);
1082       chopstx_join (usb_thd, NULL);
1083       usb_lld_shutdown ();
1084       bDeviceState = UNCONNECTED;
1085     }
1086
1087   running_neug = 1;
1088 #endif
1089
1090   led_thread = chopstx_create (PRIO_LED, STACK_ADDR_LED, STACK_SIZE_LED,
1091                                led_blinker, NULL);
1092
1093   usb_thd = chopstx_create (PRIO_USB, STACK_ADDR_USB, STACK_SIZE_USB,
1094                             usb_main, NULL);
1095
1096   neug_init (random_word, RANDOM_BYTES_LENGTH/sizeof (uint32_t));
1097
1098   chopstx_mutex_lock (&usb_mtx);
1099
1100  not_configured:
1101   count = 0;
1102   /* Initial run-up */
1103   while (count < NEUG_PRE_LOOP || bDeviceState != CONFIGURED)
1104     {
1105       if (fsij_device_state != FSIJ_DEVICE_RUNNING)
1106         break;
1107
1108       chopstx_mutex_unlock (&usb_mtx);
1109       neug_wait_full ();
1110       neug_flush ();
1111
1112       if ((count & 0x0007) == 0)
1113         event_flag_signal (&led_event, LED_ONESHOT_SHORT);
1114       chopstx_usec_wait (25*1000);
1115       count++;
1116       chopstx_mutex_lock (&usb_mtx);
1117     }
1118
1119   /* Holding USB_MTX...  */
1120   while (1)
1121     {
1122       int last_was_fullsizepacket = 0;
1123
1124       if (fsij_device_state != FSIJ_DEVICE_RUNNING)
1125         break;
1126
1127       chopstx_mutex_unlock (&usb_mtx);
1128       while (1)
1129         {
1130           uint32_t usec = 5000*1000;
1131           chopstx_poll_cond_t poll_desc;
1132           struct chx_poll_head *pd_array[1] = {
1133             (struct chx_poll_head *)&poll_desc
1134           };
1135
1136           poll_desc.type = CHOPSTX_POLL_COND;
1137           poll_desc.ready = 0;
1138           poll_desc.cond = &usb_cnd;
1139           poll_desc.mutex = &usb_mtx;
1140           poll_desc.check = check_usb_status;
1141           poll_desc.arg = NULL;
1142
1143           if (chopstx_poll (&usec, 1, pd_array))
1144             break;
1145
1146           /* Timeout */
1147           neug_flush ();
1148           neug_mode_select (line_coding.paritytype);
1149           event_flag_signal (&led_event, LED_TWOSHOTS);
1150         }
1151
1152       chopstx_mutex_lock (&usb_mtx);
1153       if (bDeviceState != CONFIGURED)
1154         goto not_configured;
1155
1156       /* The connection opened.  */
1157       count = 0;
1158
1159       while (1)
1160         {
1161           int i;
1162
1163           chopstx_mutex_unlock (&usb_mtx);
1164           /*
1165            * No parity is standard.  It means providing conditioned output.
1166            * When parity enabled, it means to provide raw output
1167            * (CRC32 filtered when odd, direct sample of ADC when even).
1168            *
1169            * line_coding.paritytype:
1170            *   0: None, 1: Odd, 2: Even
1171            */
1172           neug_mode_select (line_coding.paritytype);
1173
1174           if ((count & 0x03ff) == 0)
1175             event_flag_signal (&led_event, LED_ONESHOT_SHORT);
1176
1177           i = neug_consume_random (copy_to_tx);
1178
1179           if (i == 0 && !last_was_fullsizepacket)
1180             {    /* Only send ZLP when the last packet was fullsize.  */
1181               neug_wait_full ();
1182
1183               chopstx_mutex_lock (&usb_mtx);
1184               if (bDeviceState != CONFIGURED || !connected
1185                   || fsij_device_state != FSIJ_DEVICE_RUNNING)
1186                 break;
1187             }
1188           else
1189             {
1190               if (i == 64/4)
1191                 last_was_fullsizepacket = 1;
1192               else
1193                 last_was_fullsizepacket = 0;
1194
1195               chopstx_mutex_lock (&usb_mtx);
1196               if (bDeviceState != CONFIGURED || !connected
1197                   || fsij_device_state != FSIJ_DEVICE_RUNNING)
1198                 break;
1199
1200               /* Prepare sending random data.  */
1201 #ifdef GNU_LINUX_EMULATION
1202               usb_lld_tx_enable_buf (ENDP1, endp1_buf, i * 4);
1203 #else
1204               usb_lld_tx_enable (ENDP1, i * 4);
1205 #endif
1206               chopstx_cond_wait (&usb_cnd, &usb_mtx);
1207               count++;
1208             }
1209         }
1210     }
1211
1212   chopstx_mutex_unlock (&usb_mtx);
1213
1214   chopstx_cancel (led_thread);
1215   chopstx_join (led_thread, NULL);
1216
1217   /*
1218    * We come here, because of FSIJ_DEVICE_NEUG_EXIT_REQUESTED
1219    * or FSIJ_DEVICE_NEUG_FRAUCHEKY_REQUESTED.
1220    */
1221   neug_fini ();
1222
1223   chopstx_mutex_lock (&usb_mtx);
1224 #ifdef FRAUCHEKY_SUPPORT
1225   if (line_coding.bitrate == NEUG_SPECIAL_BITRATE)
1226     {
1227       while (fsij_device_state == FSIJ_DEVICE_NEUG_FRAUCHEKY_REQUESTED)
1228         {
1229           chopstx_mutex_unlock (&usb_mtx);
1230           set_led (1);
1231           chopstx_usec_wait (500*1000);
1232           set_led (0);
1233           chopstx_usec_wait (500*1000);
1234           chopstx_mutex_lock (&usb_mtx);
1235         }
1236
1237       usb_lld_prepare_shutdown ();
1238       chopstx_mutex_unlock (&usb_mtx);
1239       chopstx_cancel (usb_thd);
1240       chopstx_join (usb_thd, NULL);
1241       usb_lld_shutdown ();
1242       goto go_fraucheky;
1243     }
1244 #endif
1245
1246   fsij_device_state = FSIJ_DEVICE_EXITED;
1247
1248   while (fsij_device_state == FSIJ_DEVICE_EXITED)
1249     {
1250       chopstx_mutex_unlock (&usb_mtx);
1251       chopstx_usec_wait (500*1000);
1252       chopstx_mutex_lock (&usb_mtx);
1253     }
1254   chopstx_mutex_unlock (&usb_mtx);
1255
1256   flash_unlock ();              /* Flash unlock should be done here */
1257   set_led (1);
1258   usb_lld_shutdown ();
1259
1260   /* Finish application.  */
1261   chopstx_cancel (usb_thd);
1262   chopstx_join (usb_thd, NULL);
1263
1264 #ifndef GNU_LINUX_EMULATION
1265   /* Set vector */
1266   SCB->VTOR = (uintptr_t)&_regnual_start;
1267 #endif
1268   entry = calculate_regnual_entry_address (&_regnual_start);
1269 #ifdef DFU_SUPPORT
1270 #define FLASH_SYS_START_ADDR 0x08000000
1271 #define FLASH_SYS_END_ADDR (0x08000000+0x1000)
1272 #define CHIP_ID_REG ((uint32_t *)0xE0042000)
1273   {
1274     extern uint8_t _sys;
1275     uint32_t addr;
1276     handler *new_vector = (handler *)FLASH_SYS_START_ADDR;
1277     void (*func) (void (*)(void)) = (void (*)(void (*)(void)))new_vector[9];
1278     uint32_t flash_page_size = 1024; /* 1KiB default */
1279
1280    if ((*CHIP_ID_ADDR)&0x07 == 0x04) /* High dencity device.  */
1281      flash_page_size += 0x0400; /* It's 2KiB. */
1282
1283     /* Kill DFU */
1284     for (addr = FLASH_SYS_START_ADDR; addr < FLASH_SYS_END_ADDR;
1285          addr += flash_page_size)
1286       flash_erase_page (addr);
1287
1288     /* copy system service routines */
1289     flash_write (FLASH_SYS_START_ADDR, &_sys, 0x1000);
1290
1291     /* Leave NeuG to exec reGNUal */
1292     (*func) ((void (*)(void))entry);
1293     for (;;);
1294   }
1295 #else
1296   /* Leave NeuG to exec reGNUal */
1297   flash_erase_all_and_exec ((void (*)(void))entry);
1298 #endif
1299
1300   /* Never reached */
1301   return 0;
1302 }