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