Add CRC32 emulation on GNU/Linux.
[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 #ifdef GNU_LINUX_EMULATION
262 static const uint32_t crc32_table[256] = {
263   0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
264   0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
265   0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7,
266   0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
267   0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3,
268   0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
269   0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef,
270   0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
271   0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb,
272   0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
273   0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
274   0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
275   0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4,
276   0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
277   0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08,
278   0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
279   0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc,
280   0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
281   0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050,
282   0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
283   0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
284   0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
285   0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1,
286   0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
287   0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5,
288   0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
289   0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9,
290   0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
291   0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd,
292   0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
293   0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
294   0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
295   0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2,
296   0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
297   0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e,
298   0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
299   0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a,
300   0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
301   0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676,
302   0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
303   0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
304   0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
305   0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
306 };
307
308 static uint32_t crc;
309
310 static void
311 crc32_reset (void)
312 {
313   crc = 0xffffffff;
314 }
315
316 static void
317 crc32_step (uint32_t v)
318 {
319   crc = crc32_table[(crc ^ (v << 0))  >> 24] ^ (crc << 8);
320   crc = crc32_table[(crc ^ (v << 8))  >> 24] ^ (crc << 8);
321   crc = crc32_table[(crc ^ (v << 16)) >> 24] ^ (crc << 8);
322   crc = crc32_table[(crc ^ (v << 24)) >> 24] ^ (crc << 8);
323 }
324
325 static uint32_t
326 crc32_get (void)
327 {
328   return crc;
329 }
330
331 static uint32_t
332 rbit (uint32_t v)
333 {
334   v = ((v >> 1) & 0x55555555) | ((v & 0x55555555) << 1);
335   v = ((v >> 2) & 0x33333333) | ((v & 0x33333333) << 2);
336   v = ((v >> 4) & 0x0F0F0F0F) | ((v & 0x0F0F0F0F) << 4);
337   v = ((v >> 8) & 0x00FF00FF) | ((v & 0x00FF00FF) << 8);
338   v = ( v >> 16             ) | ( v               << 16);
339   return v;
340 }
341 #else
342 static void
343 crc32_reset (void)
344 {
345   RCC->AHBENR |= RCC_AHBENR_CRCEN;
346   CRC->CR = CRC_CR_RESET;
347 }
348
349 static void
350 crc32_step (uint32_t v)
351 {
352   CRC->DR = v;
353 }
354
355 static uint32_t
356 crc32_get (void)
357 {
358   return CRC->DR;
359 }
360
361 static uint32_t
362 rbit (uint32_t v)
363 {
364   uint32_t r;
365
366   asm ("rbit    %0, %1" : "=r" (r) : "r" (v));
367   return r;
368 }
369 #endif
370
371 /* After calling this function, CRC module remain enabled.  */
372 static int download_check_crc32 (struct usb_dev *dev, const uint32_t *end_p)
373 {
374   uint32_t crc32 = *end_p;
375   const uint32_t *p;
376
377   crc32_reset ();
378
379   for (p = (const uint32_t *)&_regnual_start; p < end_p; p++)
380     crc32_step (rbit (*p));
381
382   if ((rbit (crc32_get ()) ^ crc32) == 0xffffffff)
383     return usb_lld_ctrl_ack (dev);
384
385   return -1;
386 }
387
388
389 #define NEUG_SPECIAL_BITRATE 110
390
391 struct line_coding
392 {
393   uint32_t bitrate;
394   uint8_t format;
395   uint8_t paritytype;
396   uint8_t datatype;
397 } __attribute__((packed));
398
399 static struct line_coding line_coding = {
400   115200, /* baud rate: 115200    */
401   0x00,   /* stop bits: 1         */
402   0x00,   /* parity:    none      */
403   0x08    /* bits:      8         */
404 };
405
406 #define CDC_CTRL_DTR            0x0001
407
408 static void
409 usb_ctrl_write_finish (struct usb_dev *dev)
410 {
411   struct device_req *arg = &dev->dev_req;
412   uint8_t type_rcp = arg->type & (REQUEST_TYPE|RECIPIENT);
413
414   if (type_rcp == (VENDOR_REQUEST | DEVICE_RECIPIENT)
415       && USB_SETUP_SET (arg->type))
416     {
417       if (arg->request == USB_FSIJ_EXEC)
418         {
419           chopstx_mutex_lock (&usb_mtx);
420           if (fsij_device_state == FSIJ_DEVICE_EXITED)
421             {
422               usb_lld_prepare_shutdown (); /* No further USB communication */
423               fsij_device_state = FSIJ_DEVICE_EXEC_REQUESTED;
424             }
425           chopstx_mutex_unlock (&usb_mtx);
426         }
427       else if (arg->request == USB_NEUG_SET_PASSWD)
428         set_passwd ();
429       else if (arg->request == USB_NEUG_EXIT)
430         {
431           if ((neug_passwd[0] == 0xff && usbbuf[0] == DEFAULT_PASSWD_LEN
432                && !memcmp (usbbuf + 1, DEFAULT_PASSWD, DEFAULT_PASSWD_LEN))
433               || (neug_passwd[0] == usbbuf[0]
434                   && !memcmp (neug_passwd+1, usbbuf+1, neug_passwd[0])))
435             {
436               chopstx_mutex_lock (&usb_mtx);
437               fsij_device_state = FSIJ_DEVICE_NEUG_EXIT_REQUESTED;
438               chopstx_cond_signal (&usb_cnd);
439               chopstx_mutex_unlock (&usb_mtx);
440             }
441         }
442     }
443   else if (type_rcp == (CLASS_REQUEST | INTERFACE_RECIPIENT) && arg->index == 0
444            && USB_SETUP_SET (arg->type))
445     {
446       if (arg->request == USB_CDC_REQ_SET_CONTROL_LINE_STATE)
447         {
448           /* Open/close the connection.  */
449           chopstx_mutex_lock (&usb_mtx);
450           connected = (arg->value & CDC_CTRL_DTR)? 1 : 0;
451           chopstx_cond_signal (&usb_cnd);
452           chopstx_mutex_unlock (&usb_mtx);
453         }
454 #ifdef FRAUCHEKY_SUPPORT
455       else if (running_neug && arg->request == USB_CDC_REQ_SET_LINE_CODING)
456         {
457           chopstx_mutex_lock (&usb_mtx);
458           if (line_coding.bitrate == NEUG_SPECIAL_BITRATE)
459             {
460               fsij_device_state = FSIJ_DEVICE_NEUG_FRAUCHEKY_REQUESTED;
461               chopstx_cond_signal (&usb_cnd);
462             }
463           else if (fsij_device_state == FSIJ_DEVICE_NEUG_FRAUCHEKY_REQUESTED)
464             fsij_device_state = FSIJ_DEVICE_RUNNING;
465           chopstx_mutex_unlock (&usb_mtx);
466         }
467       else if (!running_neug && arg->request == MSC_MASS_STORAGE_RESET_COMMAND)
468         fraucheky_setup_endpoints_for_interface (0);
469 #endif
470     }
471 }
472
473
474 static int
475 vcom_port_data_setup (struct usb_dev *dev)
476 {
477   struct device_req *arg = &dev->dev_req;
478
479   if (USB_SETUP_GET (arg->type))
480     {
481       if (arg->request == USB_CDC_REQ_GET_LINE_CODING)
482         return usb_lld_ctrl_send (dev, &line_coding, sizeof(line_coding));
483     }
484   else  /* USB_SETUP_SET (req) */
485     {
486       if (arg->request == USB_CDC_REQ_SET_LINE_CODING
487           && arg->len == sizeof (line_coding))
488         return usb_lld_ctrl_recv (dev, &line_coding, sizeof (line_coding));
489       else if (arg->request == USB_CDC_REQ_SET_CONTROL_LINE_STATE)
490         return usb_lld_ctrl_ack (dev);
491     }
492
493   return -1;
494 }
495
496 static int
497 usb_setup (struct usb_dev *dev)
498 {
499   struct device_req *arg = &dev->dev_req;
500   uint8_t type_rcp = arg->type & (REQUEST_TYPE|RECIPIENT);
501
502   if (type_rcp == (VENDOR_REQUEST | DEVICE_RECIPIENT))
503     {
504       if (USB_SETUP_GET (arg->type))
505         {
506           if (arg->request == USB_FSIJ_MEMINFO)
507             {
508               chopstx_mutex_lock (&usb_mtx);
509               if (fsij_device_state != FSIJ_DEVICE_EXITED)
510                 {
511                   chopstx_mutex_unlock (&usb_mtx);
512                   return -1;
513                 }
514               chopstx_mutex_unlock (&usb_mtx);
515               return usb_lld_ctrl_send (dev, mem_info, sizeof (mem_info));
516             }
517           else if (arg->request == USB_NEUG_GET_INFO)
518             {
519               if (arg->index == 0)
520                 return usb_lld_ctrl_send (dev, &neug_mode, sizeof (uint8_t));
521               else if (arg->index == 1)
522                 return usb_lld_ctrl_send (dev, &neug_err_cnt, sizeof (uint16_t));
523               else if (arg->index == 2)
524                 return usb_lld_ctrl_send (dev, &neug_err_cnt_rc, sizeof (uint16_t));
525               else if (arg->index == 3)
526                 return usb_lld_ctrl_send (dev, &neug_err_cnt_p64, sizeof (uint16_t));
527               else if (arg->index == 4)
528                 return usb_lld_ctrl_send (dev, &neug_err_cnt_p4k, sizeof (uint16_t));
529               else if (arg->index == 5)
530                 return usb_lld_ctrl_send (dev, &neug_rc_max, sizeof (uint16_t));
531               else if (arg->index == 6)
532                 return usb_lld_ctrl_send (dev, &neug_p64_max, sizeof (uint16_t));
533               else if (arg->index == 7)
534                 return usb_lld_ctrl_send (dev, &neug_p4k_max, sizeof (uint16_t));
535               else
536                 return -1;
537             }
538         }
539       else /* SETUP_SET */
540         {
541           uint8_t *addr = (uint8_t *)(0x20000000UL + arg->value * 0x100 + arg->index);
542
543           if (arg->request == USB_FSIJ_DOWNLOAD)
544             {
545               chopstx_mutex_lock (&usb_mtx);
546               if (fsij_device_state != FSIJ_DEVICE_EXITED)
547                 {
548                   chopstx_mutex_unlock (&usb_mtx);
549                   return -1;
550                 }
551               chopstx_mutex_unlock (&usb_mtx);
552
553               if (addr < &_regnual_start || addr + arg->len > &__heap_end__)
554                 return -1;
555
556               if (arg->index + arg->len < 256)
557                 memset (addr + arg->index + arg->len, 0, 256 - (arg->index + arg->len));
558
559               return usb_lld_ctrl_recv (dev, addr, arg->len);
560             }
561           else if (arg->request == USB_FSIJ_EXEC && arg->len == 0)
562             {
563               chopstx_mutex_lock (&usb_mtx);
564               if (fsij_device_state != FSIJ_DEVICE_EXITED)
565                 {
566                   chopstx_mutex_unlock (&usb_mtx);
567                   return -1;
568                 }
569               chopstx_mutex_unlock (&usb_mtx);
570
571               if (((uintptr_t)addr & 0x03))
572                 return -1;
573
574               return download_check_crc32 (dev, (uint32_t *)addr);
575             }
576           else if (arg->request == USB_NEUG_SET_PASSWD && arg->len <= 32)
577             {
578               usbbuf[0] = arg->len;
579               return usb_lld_ctrl_recv (dev, usbbuf + 1, arg->len);
580             }
581           else if (arg->request == USB_NEUG_EXIT && arg->len <= 32)
582             {
583               chopstx_mutex_lock (&usb_mtx);
584               if (fsij_device_state != FSIJ_DEVICE_RUNNING)
585                 {
586                   chopstx_mutex_unlock (&usb_mtx);
587                   return -1;
588                 }
589               chopstx_mutex_unlock (&usb_mtx);
590
591               usbbuf[0] = arg->len;
592               return usb_lld_ctrl_recv (dev, usbbuf + 1, arg->len);
593             }
594         }
595     }
596   else if (type_rcp == (CLASS_REQUEST | INTERFACE_RECIPIENT)
597            && arg->index == 0)
598     {
599 #ifdef FRAUCHEKY_SUPPORT
600       if (running_neug)
601         return vcom_port_data_setup (dev);
602       else
603         return fraucheky_setup (dev);
604 #else
605       return vcom_port_data_setup (dev);
606 #endif
607     }
608
609   return -1;
610 }
611
612 static int
613 usb_get_descriptor (struct usb_dev *dev)
614 {
615   struct device_req *arg = &dev->dev_req;
616   uint8_t rcp = arg->type & RECIPIENT;
617   uint8_t desc_type = (arg->value >> 8);
618   uint8_t desc_index = (arg->value & 0xff);
619
620 #ifdef FRAUCHEKY_SUPPORT
621   if (!running_neug)
622     return fraucheky_get_descriptor (dev);
623 #endif
624
625   if (rcp != DEVICE_RECIPIENT)
626     return -1;
627
628   if (desc_type == DEVICE_DESCRIPTOR)
629     return usb_lld_ctrl_send (dev,
630                               vcom_device_desc, sizeof (vcom_device_desc));
631   else if (desc_type == CONFIG_DESCRIPTOR)
632     return usb_lld_ctrl_send (dev,
633                               vcom_config_desc, sizeof (vcom_config_desc));
634   else if (desc_type == STRING_DESCRIPTOR)
635     {
636       const uint8_t *str;
637       int size;
638
639       switch (desc_index)
640         {
641         case 0:
642           str = vcom_string0;
643           size = sizeof (vcom_string0);
644           break;
645         case 1:
646           str = neug_string_vendor;
647           size = sizeof (neug_string_vendor);
648           break;
649         case 2:
650           str = neug_string_product;
651           size = sizeof (neug_string_product);
652           break;
653         case 3:
654           str = neug_string_serial;
655           size = sizeof (neug_string_serial);
656           break;
657         case 4:
658           str = neug_revision_detail;
659           size = sizeof (neug_revision_detail);
660           break;
661         case 5:
662           str = neug_config_options;
663           size = sizeof (neug_config_options);
664           break;
665         case 6:
666           str = sys_version;
667           size = sizeof (sys_version);
668           break;
669 #ifdef USE_SYS3
670         case 7:
671           {
672             int i;
673             str = usbbuf;
674             for (i = 0; i < (int)sizeof (usbbuf)/2 - 2; i++)
675               {
676                 if (sys_board_name[i] == 0)
677                   break;
678
679                 usbbuf[i*2+2] = sys_board_name[i];
680                 usbbuf[i*2+3] = 0;
681               }
682             usbbuf[0] = i*2 + 2;
683             usbbuf[1] = STRING_DESCRIPTOR;
684             size = i*2 + 2;
685           }
686           break;
687 #endif
688         default:
689           return -1;
690         }
691
692       return usb_lld_ctrl_send (dev, str, size);
693     }
694
695   return -1;
696 }
697
698 static void
699 neug_setup_endpoints_for_interface (struct usb_dev *dev,
700                                     uint16_t interface, int stop)
701 {
702 #if !defined(GNU_LINUX_EMULATION)
703   (void)dev;
704 #endif
705   
706   if (interface == 0)
707     {
708 #ifdef FRAUCHEKY_SUPPORT
709       if (running_neug)
710         {
711           if (!stop)
712 #ifdef GNU_LINUX_EMULATION
713             usb_lld_setup_endp (dev, ENDP2, 0, 1);
714 #else
715             usb_lld_setup_endpoint (ENDP2, EP_INTERRUPT, 0, 0, ENDP2_TXADDR, 0);
716 #endif
717           else
718             usb_lld_stall_tx (ENDP2);
719         }
720       else
721         fraucheky_setup_endpoints_for_interface (stop);
722 #else
723       if (!stop)
724 #ifdef GNU_LINUX_EMULATION
725         usb_lld_setup_endp (dev, ENDP2, 0, 1);
726 #else
727         usb_lld_setup_endpoint (ENDP2, EP_INTERRUPT, 0, 0, ENDP2_TXADDR, 0);
728 #endif
729       else
730         usb_lld_stall_tx (ENDP2);
731 #endif
732     }
733   else if (interface == 1)
734     {
735       if (!stop)
736         {
737 #ifdef GNU_LINUX_EMULATION
738           usb_lld_setup_endp (dev, ENDP1, 0, 1);
739           usb_lld_setup_endp (dev, ENDP3, 1, 0);
740 #else
741           usb_lld_setup_endpoint (ENDP1, EP_BULK, 0, 0, ENDP1_TXADDR, 0);
742           usb_lld_setup_endpoint (ENDP3, EP_BULK, 0, ENDP3_RXADDR, 0, 64);
743 #endif
744           /* Start with no data receiving (ENDP3 not enabled) */
745         }
746       else
747         {
748           usb_lld_stall_tx (ENDP1);
749           usb_lld_stall_rx (ENDP3);
750         }
751     }
752 }
753
754 static int
755 usb_set_configuration (struct usb_dev *dev)
756 {
757   int i;
758   uint8_t current_conf;
759
760   current_conf = usb_lld_current_configuration (dev);
761   if (current_conf == 0)
762     {
763       if (dev->dev_req.value != 1)
764         return -1;
765
766       usb_lld_set_configuration (dev, 1);
767       for (i = 0; i < NUM_INTERFACES; i++)
768         neug_setup_endpoints_for_interface (dev, i, 0);
769       chopstx_mutex_lock (&usb_mtx);
770       bDeviceState = CONFIGURED;
771       chopstx_mutex_unlock (&usb_mtx);
772     }
773   else if (current_conf != dev->dev_req.value)
774     {
775       if (dev->dev_req.value != 0)
776         return -1;
777
778       usb_lld_set_configuration (dev, 0);
779       for (i = 0; i < NUM_INTERFACES; i++)
780         neug_setup_endpoints_for_interface (dev, i, 1);
781       chopstx_mutex_lock (&usb_mtx);
782       bDeviceState = ADDRESSED;
783       chopstx_cond_signal (&usb_cnd);
784       chopstx_mutex_unlock (&usb_mtx);
785     }
786
787   /* Do nothing when current_conf == value */
788   return usb_lld_ctrl_ack (dev);
789 }
790
791
792 static int
793 usb_set_interface (struct usb_dev *dev)
794 {
795   uint16_t interface = dev->dev_req.index;
796   uint16_t alt = dev->dev_req.value;
797
798   if (interface >= NUM_INTERFACES)
799     return -1;
800
801   if (alt != 0)
802     return -1;
803   else
804     {
805       neug_setup_endpoints_for_interface (dev, interface, 0);
806       return usb_lld_ctrl_ack (dev);
807     }
808 }
809
810 static int
811 usb_get_interface (struct usb_dev *dev)
812 {
813   const uint8_t zero = 0;
814   uint16_t interface = dev->dev_req.index;
815
816   if (interface >= NUM_INTERFACES)
817     return -1;
818
819   return usb_lld_ctrl_send (dev, &zero, 1);
820 }
821
822
823 static int
824 usb_get_status_interface (struct usb_dev *dev)
825 {
826   const uint16_t status_info = 0;
827   uint16_t interface = dev->dev_req.index;
828
829   if (interface >= NUM_INTERFACES)
830     return -1;
831
832   return usb_lld_ctrl_send (dev, &status_info, 2);
833 }
834
835 static void usb_tx_done (uint8_t ep_num, uint16_t len);
836 static void usb_rx_ready (uint8_t ep_num, uint16_t len);
837
838
839 #define INTR_REQ_USB 20
840 #define PRIO_USB 3
841
842 static void *
843 usb_main (void *arg)
844 {
845   chopstx_intr_t interrupt;
846   struct usb_dev dev;
847   int e;
848
849   (void)arg;
850   usb_lld_init (&dev, VCOM_FEATURE_BUS_POWERED);
851   chopstx_claim_irq (&interrupt, INTR_REQ_USB);
852   goto event_handle;    /* For old SYS < 3.0 */
853
854   while (1)
855     {
856       chopstx_intr_wait (&interrupt);
857
858       if (interrupt.ready)
859         {
860           uint8_t ep_num;
861
862         event_handle:
863           e = usb_lld_event_handler (&dev);
864           ep_num = USB_EVENT_ENDP (e);
865
866           if (ep_num != 0)
867             {
868               if (USB_EVENT_TXRX (e))
869                 usb_tx_done (ep_num, USB_EVENT_LEN (e));
870               else
871                 usb_rx_ready (ep_num, USB_EVENT_LEN (e));
872             }
873           else
874             switch (USB_EVENT_ID (e))
875               {
876               case USB_EVENT_DEVICE_RESET:
877                 usb_device_reset (&dev);
878                 continue;
879
880               case USB_EVENT_DEVICE_ADDRESSED:
881                 chopstx_mutex_lock (&usb_mtx);
882                 bDeviceState = ADDRESSED;
883                 chopstx_cond_signal (&usb_cnd);
884                 chopstx_mutex_unlock (&usb_mtx);
885                 continue;
886
887               case USB_EVENT_GET_DESCRIPTOR:
888                 if (usb_get_descriptor (&dev) < 0)
889                   usb_lld_ctrl_error (&dev);
890                 continue;
891
892               case USB_EVENT_SET_CONFIGURATION:
893                 if (usb_set_configuration (&dev) < 0)
894                   usb_lld_ctrl_error (&dev);
895                 continue;
896
897               case USB_EVENT_SET_INTERFACE:
898                 if (usb_set_interface (&dev) < 0)
899                   usb_lld_ctrl_error (&dev);
900                 continue;
901
902               case USB_EVENT_CTRL_REQUEST:
903                 /* Device specific device request.  */
904                 if (usb_setup (&dev) < 0)
905                   usb_lld_ctrl_error (&dev);
906                 continue;
907
908               case USB_EVENT_GET_STATUS_INTERFACE:
909                 if (usb_get_status_interface (&dev) < 0)
910                   usb_lld_ctrl_error (&dev);
911                 continue;
912
913               case USB_EVENT_GET_INTERFACE:
914                 if (usb_get_interface (&dev) < 0)
915                   usb_lld_ctrl_error (&dev);
916                 continue;
917
918               case USB_EVENT_SET_FEATURE_DEVICE:
919               case USB_EVENT_SET_FEATURE_ENDPOINT:
920               case USB_EVENT_CLEAR_FEATURE_DEVICE:
921               case USB_EVENT_CLEAR_FEATURE_ENDPOINT:
922                 usb_lld_ctrl_ack (&dev);
923                 continue;
924
925               case USB_EVENT_CTRL_WRITE_FINISH:
926                 /* Control WRITE transfer finished.  */
927                 usb_ctrl_write_finish (&dev);
928                 continue;
929
930               case USB_EVENT_OK:
931               case USB_EVENT_DEVICE_SUSPEND:
932               default:
933                 continue;
934               }
935         }
936     }
937
938   return NULL;
939 }
940
941 #define ID_OFFSET (2+SERIALNO_STR_LEN*2)
942 static void fill_serial_no_by_unique_id (void)
943 {
944   extern const uint8_t * unique_device_id (void);
945   uint8_t *p = &neug_string_serial[ID_OFFSET];
946   const uint8_t *u = unique_device_id () + 8;
947   int i;
948
949   for (i = 0; i < 4; i++)
950     {
951       uint8_t b = u[3-i];
952       uint8_t nibble;
953
954       nibble = (b >> 4);
955       nibble += (nibble >= 10 ? ('A' - 10) : '0');
956       p[i*4] = nibble;
957       p[i*4+1] = 0;
958       nibble = (b & 0x0f);
959       nibble += (nibble >= 10 ? ('A' - 10) : '0');
960       p[i*4+2] = nibble;
961       p[i*4+3] = 0;
962     }
963 }
964
965
966 static void
967 usb_tx_done (uint8_t ep_num, uint16_t len)
968 {
969   if (ep_num == ENDP1)
970     {
971       chopstx_mutex_lock (&usb_mtx);
972       chopstx_cond_signal (&usb_cnd);
973       chopstx_mutex_unlock (&usb_mtx);
974     }
975   else if (ep_num == ENDP2)
976     {
977       /* INTERRUPT Transfer done */
978     }
979 #ifdef FRAUCHEKY_SUPPORT
980   else if (ep_num == ENDP6)
981     EP6_IN_Callback (len);
982 #else
983   (void)len;
984 #endif
985 }
986
987 #ifdef GNU_LINUX_EMULATION
988 static uint8_t endp3_buf[64];
989 #endif
990
991 static void
992 usb_rx_ready (uint8_t ep_num, uint16_t len)
993 {
994   if (ep_num == ENDP3)
995 #ifdef GNU_LINUX_EMULATION
996     usb_lld_rx_enable_buf (ENDP3, endp3_buf, 64);
997 #else
998     usb_lld_rx_enable (ENDP3);
999 #endif
1000 #ifdef FRAUCHEKY_SUPPORT
1001   else if (ep_num == ENDP6)
1002     EP6_OUT_Callback (len);
1003 #else
1004   (void)len;
1005 #endif
1006 }
1007 \f
1008 typedef uint32_t eventmask_t;
1009 #define ALL_EVENTS (~0)
1010
1011 struct event_flag {
1012   chopstx_mutex_t mutex;
1013   chopstx_cond_t cond;
1014   eventmask_t flag;
1015 };
1016
1017 static void event_flag_init (struct event_flag *ev)
1018 {
1019   ev->flag = 0;
1020   chopstx_mutex_init (&ev->mutex);
1021   chopstx_cond_init (&ev->cond);
1022 }
1023
1024
1025 static eventmask_t event_flag_waitone (struct event_flag *ev, eventmask_t m)
1026 {
1027   int n;
1028
1029   chopstx_mutex_lock (&ev->mutex);
1030   while (!(ev->flag & m))
1031     chopstx_cond_wait (&ev->cond, &ev->mutex);
1032
1033   n = __builtin_ffs ((ev->flag & m));
1034   ev->flag &= ~(1 << (n - 1));
1035   chopstx_mutex_unlock (&ev->mutex);
1036
1037   return (1 << (n - 1));
1038 }
1039
1040 static void event_flag_signal (struct event_flag *ev, eventmask_t m)
1041 {
1042   chopstx_mutex_lock (&ev->mutex);
1043   ev->flag |= m;
1044   chopstx_cond_signal (&ev->cond);
1045   chopstx_mutex_unlock (&ev->mutex);
1046 }
1047
1048 #ifdef GNU_LINUX_EMULATION
1049 extern char __process1_stack_base__[4096];
1050 extern char __process3_stack_base__[4096];
1051 #define STACK_SIZE_LED (sizeof __process1_stack_base__)
1052 #define STACK_SIZE_USB (sizeof __process3_stack_base__)
1053 #else
1054 extern uint8_t __process1_stack_base__[], __process1_stack_size__[];
1055 extern uint8_t __process3_stack_base__[], __process3_stack_size__[];
1056 #define STACK_SIZE_LED ((uintptr_t)__process1_stack_size__)
1057 #define STACK_SIZE_USB ((uintptr_t)__process3_stack_size__)
1058 #endif
1059
1060 #define STACK_ADDR_LED ((uintptr_t)__process1_stack_base__)
1061 #define STACK_ADDR_USB ((uintptr_t)__process3_stack_base__)
1062
1063
1064 #define PRIO_LED 3
1065 static struct event_flag led_event;
1066
1067 #define LED_ONESHOT_SHORT       ((eventmask_t)1)
1068 #define LED_TWOSHOTS            ((eventmask_t)2)
1069 #define LED_ONESHOT_LONG        ((eventmask_t)4)
1070
1071 /*
1072  * LED blinker: When notified, let LED emit for 100ms.
1073  */
1074 static void *
1075 led_blinker (void *arg)
1076 {
1077   (void)arg;
1078
1079   set_led (0);
1080
1081   while (1)
1082     {
1083       eventmask_t m;
1084
1085       m = event_flag_waitone (&led_event, ALL_EVENTS);
1086
1087       set_led (1);
1088       if (m == LED_ONESHOT_SHORT)
1089         chopstx_usec_wait (100*1000);
1090       else if (m == LED_TWOSHOTS)
1091         {
1092           chopstx_usec_wait (50*1000);
1093           set_led (0);
1094           chopstx_usec_wait (50*1000);
1095           set_led (1);
1096           chopstx_usec_wait (50*1000);
1097         }
1098       else
1099         chopstx_usec_wait (250*1000);
1100       set_led (0);
1101     }
1102
1103   return NULL;
1104 }
1105 \f
1106 #define RANDOM_BYTES_LENGTH 64
1107 static uint32_t random_word[RANDOM_BYTES_LENGTH/sizeof (uint32_t)];
1108
1109 #ifdef GNU_LINUX_EMULATION
1110 static uint8_t endp1_buf[RANDOM_BYTES_LENGTH];
1111 #endif
1112
1113 static void copy_to_tx (uint32_t v, int i)
1114 {
1115 #ifdef GNU_LINUX_EMULATION
1116   memcpy (&endp1_buf[i], &v, 4);
1117 #else
1118   usb_lld_txcpy (&v, ENDP1, i * 4, 4);
1119 #endif
1120 }
1121
1122 /*
1123  * In Gnuk 1.0.[12], reGNUal was not relocatable.
1124  * Now, it's relocatable, but we need to calculate its entry address
1125  * based on it's pre-defined address.
1126  */
1127 #define REGNUAL_START_ADDRESS_COMPATIBLE 0x20001400
1128 static uint32_t
1129 calculate_regnual_entry_address (const uint8_t *addr)
1130 {
1131   const uint8_t *p = addr + 4;
1132   uintptr_t v = p[0] + (p[1] << 8) + (p[2] << 16) + (p[3] << 24);
1133
1134   v -= REGNUAL_START_ADDRESS_COMPATIBLE;
1135   v += (uintptr_t)addr;
1136   return v;
1137 }
1138
1139
1140 static int
1141 check_usb_status (void *arg)
1142 {
1143   (void)arg;
1144
1145   return (connected || bDeviceState != CONFIGURED
1146           || fsij_device_state != FSIJ_DEVICE_RUNNING);
1147 }
1148
1149
1150 #ifdef GNU_LINUX_EMULATION
1151 #define main emulated_main
1152 #endif
1153
1154 /*
1155  * Entry point.
1156  *
1157  * NOTE: the main function is already a thread in the system on entry.
1158  */
1159 int
1160 main (int argc, char **argv)
1161 {
1162   uintptr_t entry;
1163   chopstx_t led_thread, usb_thd;
1164   unsigned int count;
1165
1166   (void)argc;
1167   (void)argv;
1168
1169   fill_serial_no_by_unique_id ();
1170
1171   adc_init ();
1172
1173   event_flag_init (&led_event);
1174
1175   chopstx_mutex_init (&usb_mtx);
1176   chopstx_cond_init (&usb_cnd);
1177
1178 #ifdef FRAUCHEKY_SUPPORT
1179   if (fraucheky_enabled ())
1180     {
1181     go_fraucheky:
1182       bDeviceState = UNCONNECTED;
1183       running_neug = 0;
1184       usb_thd = chopstx_create (PRIO_USB, STACK_ADDR_USB, STACK_SIZE_USB,
1185                                 usb_main, NULL);
1186       while (bDeviceState != CONFIGURED)
1187         chopstx_usec_wait (250*1000);
1188       set_led (1);
1189       fraucheky_main ();
1190       chopstx_cancel (usb_thd);
1191       chopstx_join (usb_thd, NULL);
1192       usb_lld_shutdown ();
1193       bDeviceState = UNCONNECTED;
1194     }
1195
1196   running_neug = 1;
1197 #endif
1198
1199   led_thread = chopstx_create (PRIO_LED, STACK_ADDR_LED, STACK_SIZE_LED,
1200                                led_blinker, NULL);
1201
1202   usb_thd = chopstx_create (PRIO_USB, STACK_ADDR_USB, STACK_SIZE_USB,
1203                             usb_main, NULL);
1204
1205   neug_init (random_word, RANDOM_BYTES_LENGTH/sizeof (uint32_t));
1206
1207   chopstx_mutex_lock (&usb_mtx);
1208
1209  not_configured:
1210   count = 0;
1211   /* Initial run-up */
1212   while (count < NEUG_PRE_LOOP || bDeviceState != CONFIGURED)
1213     {
1214       if (fsij_device_state != FSIJ_DEVICE_RUNNING)
1215         break;
1216
1217       chopstx_mutex_unlock (&usb_mtx);
1218       neug_wait_full ();
1219       neug_flush ();
1220
1221       if ((count & 0x0007) == 0)
1222         event_flag_signal (&led_event, LED_ONESHOT_SHORT);
1223       chopstx_usec_wait (25*1000);
1224       count++;
1225       chopstx_mutex_lock (&usb_mtx);
1226     }
1227
1228   /* Holding USB_MTX...  */
1229   while (1)
1230     {
1231       int last_was_fullsizepacket = 0;
1232
1233       if (fsij_device_state != FSIJ_DEVICE_RUNNING)
1234         break;
1235
1236       chopstx_mutex_unlock (&usb_mtx);
1237       while (1)
1238         {
1239           uint32_t usec = 5000*1000;
1240           chopstx_poll_cond_t poll_desc;
1241           struct chx_poll_head *pd_array[1] = {
1242             (struct chx_poll_head *)&poll_desc
1243           };
1244
1245           poll_desc.type = CHOPSTX_POLL_COND;
1246           poll_desc.ready = 0;
1247           poll_desc.cond = &usb_cnd;
1248           poll_desc.mutex = &usb_mtx;
1249           poll_desc.check = check_usb_status;
1250           poll_desc.arg = NULL;
1251
1252           if (chopstx_poll (&usec, 1, pd_array))
1253             break;
1254
1255           /* Timeout */
1256           neug_flush ();
1257           neug_mode_select (line_coding.paritytype);
1258           event_flag_signal (&led_event, LED_TWOSHOTS);
1259         }
1260
1261       chopstx_mutex_lock (&usb_mtx);
1262       if (bDeviceState != CONFIGURED)
1263         goto not_configured;
1264
1265       /* The connection opened.  */
1266       count = 0;
1267
1268       while (1)
1269         {
1270           int i;
1271
1272           chopstx_mutex_unlock (&usb_mtx);
1273           /*
1274            * No parity is standard.  It means providing conditioned output.
1275            * When parity enabled, it means to provide raw output
1276            * (CRC32 filtered when odd, direct sample of ADC when even).
1277            *
1278            * line_coding.paritytype:
1279            *   0: None, 1: Odd, 2: Even
1280            */
1281           neug_mode_select (line_coding.paritytype);
1282
1283           if ((count & 0x03ff) == 0)
1284             event_flag_signal (&led_event, LED_ONESHOT_SHORT);
1285
1286           i = neug_consume_random (copy_to_tx);
1287
1288           if (i == 0 && !last_was_fullsizepacket)
1289             {    /* Only send ZLP when the last packet was fullsize.  */
1290               neug_wait_full ();
1291
1292               chopstx_mutex_lock (&usb_mtx);
1293               if (bDeviceState != CONFIGURED || !connected
1294                   || fsij_device_state != FSIJ_DEVICE_RUNNING)
1295                 break;
1296             }
1297           else
1298             {
1299               if (i == 64/4)
1300                 last_was_fullsizepacket = 1;
1301               else
1302                 last_was_fullsizepacket = 0;
1303
1304               chopstx_mutex_lock (&usb_mtx);
1305               if (bDeviceState != CONFIGURED || !connected
1306                   || fsij_device_state != FSIJ_DEVICE_RUNNING)
1307                 break;
1308
1309               /* Prepare sending random data.  */
1310 #ifdef GNU_LINUX_EMULATION
1311               usb_lld_tx_enable_buf (ENDP1, endp1_buf, i * 4);
1312 #else
1313               usb_lld_tx_enable (ENDP1, i * 4);
1314 #endif
1315               chopstx_cond_wait (&usb_cnd, &usb_mtx);
1316               count++;
1317             }
1318         }
1319     }
1320
1321   chopstx_mutex_unlock (&usb_mtx);
1322
1323   chopstx_cancel (led_thread);
1324   chopstx_join (led_thread, NULL);
1325
1326   /*
1327    * We come here, because of FSIJ_DEVICE_NEUG_EXIT_REQUESTED
1328    * or FSIJ_DEVICE_NEUG_FRAUCHEKY_REQUESTED.
1329    */
1330   neug_fini ();
1331
1332   chopstx_mutex_lock (&usb_mtx);
1333 #ifdef FRAUCHEKY_SUPPORT
1334   if (line_coding.bitrate == NEUG_SPECIAL_BITRATE)
1335     {
1336       while (fsij_device_state == FSIJ_DEVICE_NEUG_FRAUCHEKY_REQUESTED)
1337         {
1338           chopstx_mutex_unlock (&usb_mtx);
1339           set_led (1);
1340           chopstx_usec_wait (500*1000);
1341           set_led (0);
1342           chopstx_usec_wait (500*1000);
1343           chopstx_mutex_lock (&usb_mtx);
1344         }
1345
1346       usb_lld_prepare_shutdown ();
1347       chopstx_mutex_unlock (&usb_mtx);
1348       chopstx_cancel (usb_thd);
1349       chopstx_join (usb_thd, NULL);
1350       usb_lld_shutdown ();
1351       goto go_fraucheky;
1352     }
1353 #endif
1354
1355   fsij_device_state = FSIJ_DEVICE_EXITED;
1356
1357   while (fsij_device_state == FSIJ_DEVICE_EXITED)
1358     {
1359       chopstx_mutex_unlock (&usb_mtx);
1360       chopstx_usec_wait (500*1000);
1361       chopstx_mutex_lock (&usb_mtx);
1362     }
1363   chopstx_mutex_unlock (&usb_mtx);
1364
1365   flash_unlock ();              /* Flash unlock should be done here */
1366   set_led (1);
1367   usb_lld_shutdown ();
1368
1369   /* Finish application.  */
1370   chopstx_cancel (usb_thd);
1371   chopstx_join (usb_thd, NULL);
1372
1373 #ifndef GNU_LINUX_EMULATION
1374   /* Set vector */
1375   SCB->VTOR = (uintptr_t)&_regnual_start;
1376 #endif
1377   entry = calculate_regnual_entry_address (&_regnual_start);
1378 #ifdef DFU_SUPPORT
1379 #define FLASH_SYS_START_ADDR 0x08000000
1380 #define FLASH_SYS_END_ADDR (0x08000000+0x1000)
1381 #define CHIP_ID_REG ((uint32_t *)0xE0042000)
1382   {
1383     extern uint8_t _sys;
1384     uint32_t addr;
1385     handler *new_vector = (handler *)FLASH_SYS_START_ADDR;
1386     void (*func) (void (*)(void)) = (void (*)(void (*)(void)))new_vector[9];
1387     uint32_t flash_page_size = 1024; /* 1KiB default */
1388
1389    if ((*CHIP_ID_ADDR)&0x07 == 0x04) /* High dencity device.  */
1390      flash_page_size += 0x0400; /* It's 2KiB. */
1391
1392     /* Kill DFU */
1393     for (addr = FLASH_SYS_START_ADDR; addr < FLASH_SYS_END_ADDR;
1394          addr += flash_page_size)
1395       flash_erase_page (addr);
1396
1397     /* copy system service routines */
1398     flash_write (FLASH_SYS_START_ADDR, &_sys, 0x1000);
1399
1400     /* Leave NeuG to exec reGNUal */
1401     (*func) ((void (*)(void))entry);
1402     for (;;);
1403   }
1404 #else
1405   /* Leave NeuG to exec reGNUal */
1406   flash_erase_all_and_exec ((void (*)(void))entry);
1407 #endif
1408
1409   /* Never reached */
1410   return 0;
1411 }