2 * main.c - main routine of neug
5 * Copyright (C) 2011, 2012, 2013 Free Software Initiative of Japan
6 * Author: NIIBE Yutaka <gniibe@fsij.org>
8 * This file is a part of NeuG, a True Random Number Generator
11 * NeuG is free software: you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by
13 * the Free Software Foundation, either version 3 of the License, or
14 * (at your option) any later version.
16 * NeuG is distributed in the hope that it will be useful, but WITHOUT
17 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
18 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
19 * License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program. If not, see <http://www.gnu.org/licenses/>.
35 #include "stm32f103.h"
39 FSIJ_DEVICE_RUNNING = 0,
41 FSIJ_DEVICE_EXEC_REQUESTED,
43 FSIJ_DEVICE_NEUG_EXIT_REQUESTED = 255
46 static chopstx_mutex_t usb_mtx;
47 static chopstx_cond_t cnd_usb;
48 static uint32_t bDeviceState = UNCONNECTED; /* USB device status */
49 static uint8_t fsij_device_state = FSIJ_DEVICE_RUNNING;
50 static uint8_t connected;
51 static uint32_t wait_usb_connection; /* Timer variable. */
54 extern uint8_t __process0_stack_end__;
55 static chopstx_t main_thd = (uint32_t)(&__process0_stack_end__ - 60);
57 #define ENDP0_RXADDR (0x40)
58 #define ENDP0_TXADDR (0x80)
59 #define ENDP1_TXADDR (0xc0)
60 #define ENDP2_TXADDR (0x100)
61 #define ENDP3_RXADDR (0x140)
63 #define USB_CDC_REQ_SET_LINE_CODING 0x20
64 #define USB_CDC_REQ_GET_LINE_CODING 0x21
65 #define USB_CDC_REQ_SET_CONTROL_LINE_STATE 0x22
66 #define USB_CDC_REQ_SEND_BREAK 0x23
68 /* USB Device Descriptor */
69 static const uint8_t vcom_device_desc[18] = {
71 USB_DEVICE_DESCRIPTOR_TYPE, /* bDescriptorType */
72 0x10, 0x01, /* bcdUSB = 1.1 */
73 0x02, /* bDeviceClass (CDC). */
74 0x00, /* bDeviceSubClass. */
75 0x00, /* bDeviceProtocol. */
76 0x40, /* bMaxPacketSize. */
77 #include "usb-vid-pid-ver.c.inc"
78 1, /* iManufacturer. */
80 3, /* iSerialNumber. */
81 1 /* bNumConfigurations. */
84 /* Configuration Descriptor tree for a CDC.*/
85 static const uint8_t vcom_configuration_desc[67] = {
87 USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */
88 /* Configuration Descriptor.*/
89 67, 0x00, /* wTotalLength. */
90 0x02, /* bNumInterfaces. */
91 0x01, /* bConfigurationValue. */
92 0, /* iConfiguration. */
93 0x80, /* bmAttributes (bus powered). */
94 50, /* bMaxPower (100mA). */
95 /* Interface Descriptor.*/
97 USB_INTERFACE_DESCRIPTOR_TYPE,
98 0x00, /* bInterfaceNumber. */
99 0x00, /* bAlternateSetting. */
100 0x01, /* bNumEndpoints. */
101 0x02, /* bInterfaceClass (Communications Interface Class,
103 0x02, /* bInterfaceSubClass (Abstract Control Model, CDC
105 0x01, /* bInterfaceProtocol (AT commands, CDC section
108 /* Header Functional Descriptor (CDC section 5.2.3).*/
110 0x24, /* bDescriptorType (CS_INTERFACE). */
111 0x00, /* bDescriptorSubtype (Header Functional Descriptor). */
112 0x10, 0x01, /* bcdCDC. */
113 /* Call Management Functional Descriptor. */
114 5, /* bFunctionLength. */
115 0x24, /* bDescriptorType (CS_INTERFACE). */
116 0x01, /* bDescriptorSubtype (Call Management Functional
118 0x03, /* bmCapabilities (D0+D1). */
119 0x01, /* bDataInterface. */
120 /* ACM Functional Descriptor.*/
121 4, /* bFunctionLength. */
122 0x24, /* bDescriptorType (CS_INTERFACE). */
123 0x02, /* bDescriptorSubtype (Abstract Control Management
125 0x02, /* bmCapabilities. */
126 /* Union Functional Descriptor.*/
127 5, /* bFunctionLength. */
128 0x24, /* bDescriptorType (CS_INTERFACE). */
129 0x06, /* bDescriptorSubtype (Union Functional
131 0x00, /* bMasterInterface (Communication Class
133 0x01, /* bSlaveInterface0 (Data Class Interface). */
134 /* Endpoint 2 Descriptor.*/
136 USB_ENDPOINT_DESCRIPTOR_TYPE,
137 ENDP2|0x80, /* bEndpointAddress. */
138 0x03, /* bmAttributes (Interrupt). */
139 0x08, 0x00, /* wMaxPacketSize. */
140 0xFF, /* bInterval. */
141 /* Interface Descriptor.*/
143 USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: */
144 0x01, /* bInterfaceNumber. */
145 0x00, /* bAlternateSetting. */
146 0x02, /* bNumEndpoints. */
147 0x0A, /* bInterfaceClass (Data Class Interface, CDC section 4.5). */
148 0x00, /* bInterfaceSubClass (CDC section 4.6). */
149 0x00, /* bInterfaceProtocol (CDC section 4.7). */
150 0x00, /* iInterface. */
151 /* Endpoint 3 Descriptor.*/
153 USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
154 ENDP3, /* bEndpointAddress. */
155 0x02, /* bmAttributes (Bulk). */
156 0x40, 0x00, /* wMaxPacketSize. */
157 0x00, /* bInterval. */
158 /* Endpoint 1 Descriptor.*/
160 USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
161 ENDP1|0x80, /* bEndpointAddress. */
162 0x02, /* bmAttributes (Bulk). */
163 0x40, 0x00, /* wMaxPacketSize. */
164 0x00 /* bInterval. */
169 * U.S. English language identifier.
171 static const uint8_t vcom_string0[4] = {
173 USB_STRING_DESCRIPTOR_TYPE,
174 0x09, 0x04 /* LangID = 0x0409: US-English */
177 #define USB_STRINGS_FOR_NEUG 1
178 #include "usb-strings.c.inc"
181 * Serial Number string. NOTE: This does not have CONST qualifier.
183 static uint8_t vcom_string3[28] = {
185 USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType. */
186 '0', 0, '.', 0, '1', 0, '1', 0, /* Version number of NeuG. */
188 0, 0, 0, 0, /* Filled by Unique device ID. */
195 #define NUM_INTERFACES 2
199 usb_cb_device_reset (void)
201 /* Set DEVICE as not configured */
202 usb_lld_set_configuration (0);
204 /* Current Feature initialization */
205 usb_lld_set_feature (vcom_configuration_desc[7]);
209 /* Initialize Endpoint 0 */
210 usb_lld_setup_endpoint (ENDP0, EP_CONTROL, 0, ENDP0_RXADDR, ENDP0_TXADDR, 64);
213 extern uint8_t _regnual_start, __heap_end__;
215 static const uint8_t *const mem_info[] = { &_regnual_start, &__heap_end__, };
217 /* USB vendor requests to control pipe */
218 #define USB_FSIJ_MEMINFO 0
219 #define USB_FSIJ_DOWNLOAD 1
220 #define USB_FSIJ_EXEC 2
221 #define USB_NEUG_GET_INFO 254
222 #define USB_NEUG_EXIT 255 /* Ask to exit and to receive reGNUal */
225 static uint32_t rbit (uint32_t v)
229 asm ("rbit %0, %1" : "=r" (r) : "r" (v));
233 /* After calling this function, CRC module remain enabled. */
234 static int download_check_crc32 (const uint32_t *end_p)
236 uint32_t crc32 = *end_p;
239 RCC->AHBENR |= RCC_AHBENR_CRCEN;
240 CRC->CR = CRC_CR_RESET;
242 for (p = (const uint32_t *)&_regnual_start; p < end_p; p++)
245 if ((rbit (CRC->DR) ^ crc32) == 0xffffffff)
248 return USB_UNSUPPORT;
252 usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, uint16_t value,
253 uint16_t index, uint16_t len)
255 uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT);
257 if (type_rcp == (VENDOR_REQUEST | DEVICE_RECIPIENT)
258 && USB_SETUP_SET (req) && len == 0)
260 if (req_no == USB_FSIJ_EXEC)
262 chopstx_mutex_lock (&usb_mtx);
263 if (fsij_device_state == FSIJ_DEVICE_EXITED)
265 usb_lld_prepare_shutdown (); /* No further USB communication */
266 fsij_device_state = FSIJ_DEVICE_EXEC_REQUESTED;
268 chopstx_mutex_unlock (&usb_mtx);
270 else if (req_no == USB_NEUG_EXIT)
272 /* Force exit from the main loop. */
273 if (wait_usb_connection)
275 wait_usb_connection = 0;
276 chopstx_wakeup_usec_wait (main_thd);
280 chopstx_mutex_lock (&usb_mtx);
281 chopstx_cond_signal (&cnd_usb);
282 chopstx_mutex_unlock (&usb_mtx);
286 else if (type_rcp == (CLASS_REQUEST | INTERFACE_RECIPIENT)
287 && index == 0 && USB_SETUP_SET (req)
288 && req_no == USB_CDC_REQ_SET_CONTROL_LINE_STATE)
290 /* Open/close the connection. */
291 chopstx_mutex_lock (&usb_mtx);
292 connected = (value != 0)? 1 : 0;
293 if (wait_usb_connection)
294 { /* It is waiting a connection. */
295 if (connected) /* It's now connected. */
297 wait_usb_connection = 0;
298 chopstx_wakeup_usec_wait (main_thd);
302 chopstx_cond_signal (&cnd_usb);
303 chopstx_mutex_unlock (&usb_mtx);
313 } __attribute__((packed));
315 static struct line_coding line_coding = {
316 115200, /* baud rate: 115200 */
317 0x00, /* stop bits: 1 */
318 0x00, /* parity: none */
324 vcom_port_data_setup (uint8_t req, uint8_t req_no, uint16_t value,
328 if (USB_SETUP_GET (req))
330 if (req_no == USB_CDC_REQ_GET_LINE_CODING
331 && len == sizeof (line_coding))
333 usb_lld_set_data_to_send (&line_coding, sizeof (line_coding));
337 else /* USB_SETUP_SET (req) */
339 if (req_no == USB_CDC_REQ_SET_LINE_CODING
340 && len == sizeof (line_coding))
342 usb_lld_set_data_to_recv (&line_coding, sizeof (line_coding));
345 else if (req_no == USB_CDC_REQ_SET_CONTROL_LINE_STATE)
349 return USB_UNSUPPORT;
353 usb_cb_setup (uint8_t req, uint8_t req_no,
354 uint16_t value, uint16_t index, uint16_t len)
356 uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT);
358 if (type_rcp == (VENDOR_REQUEST | DEVICE_RECIPIENT))
360 if (USB_SETUP_GET (req))
362 if (req_no == USB_FSIJ_MEMINFO)
364 usb_lld_set_data_to_send (mem_info, sizeof (mem_info));
367 else if (req_no == USB_NEUG_GET_INFO)
370 usb_lld_set_data_to_send (&neug_mode, sizeof (uint8_t));
372 usb_lld_set_data_to_send (&neug_err_cnt, sizeof (uint16_t));
374 usb_lld_set_data_to_send (&neug_err_cnt_rc, sizeof (uint16_t));
376 usb_lld_set_data_to_send (&neug_err_cnt_p64, sizeof (uint16_t));
378 usb_lld_set_data_to_send (&neug_err_cnt_p4k, sizeof (uint16_t));
380 usb_lld_set_data_to_send (&neug_rc_max, sizeof (uint16_t));
382 usb_lld_set_data_to_send (&neug_p64_max, sizeof (uint16_t));
384 usb_lld_set_data_to_send (&neug_p4k_max, sizeof (uint16_t));
386 return USB_UNSUPPORT;
393 uint8_t *addr = (uint8_t *)(0x20000000 + value * 0x100 + index);
395 if (req_no == USB_FSIJ_DOWNLOAD)
397 chopstx_mutex_lock (&usb_mtx);
398 if (fsij_device_state != FSIJ_DEVICE_EXITED)
400 chopstx_mutex_unlock (&usb_mtx);
401 return USB_UNSUPPORT;
403 chopstx_mutex_unlock (&usb_mtx);
405 if (addr < &_regnual_start || addr + len > &__heap_end__)
406 return USB_UNSUPPORT;
408 if (index + len < 256)
409 memset (addr + index + len, 0, 256 - (index + len));
411 usb_lld_set_data_to_recv (addr, len);
414 else if (req_no == USB_FSIJ_EXEC && len == 0)
416 chopstx_mutex_lock (&usb_mtx);
417 if (fsij_device_state != FSIJ_DEVICE_EXITED)
419 chopstx_mutex_unlock (&usb_mtx);
420 return USB_UNSUPPORT;
422 chopstx_mutex_unlock (&usb_mtx);
424 if (((uint32_t)addr & 0x03))
425 return USB_UNSUPPORT;
427 return download_check_crc32 ((uint32_t *)addr);
429 else if (req_no == USB_NEUG_EXIT && len == 0)
431 chopstx_mutex_lock (&usb_mtx);
432 if (fsij_device_state != FSIJ_DEVICE_RUNNING)
434 chopstx_mutex_unlock (&usb_mtx);
435 return USB_UNSUPPORT;
438 fsij_device_state = FSIJ_DEVICE_NEUG_EXIT_REQUESTED;
439 chopstx_wakeup_usec_wait (main_thd);
440 chopstx_cond_signal (&cnd_usb);
441 chopstx_mutex_unlock (&usb_mtx);
447 else if (type_rcp == (CLASS_REQUEST | INTERFACE_RECIPIENT))
449 return vcom_port_data_setup (req, req_no, value, len);
451 return USB_UNSUPPORT;
455 usb_cb_get_descriptor (uint8_t rcp, uint8_t desc_type, uint8_t desc_index,
459 if (rcp != DEVICE_RECIPIENT)
460 return USB_UNSUPPORT;
462 if (desc_type == DEVICE_DESCRIPTOR)
464 usb_lld_set_data_to_send (vcom_device_desc, sizeof (vcom_device_desc));
467 else if (desc_type == CONFIG_DESCRIPTOR)
469 usb_lld_set_data_to_send (vcom_configuration_desc,
470 sizeof (vcom_configuration_desc));
473 else if (desc_type == STRING_DESCRIPTOR)
482 size = sizeof (vcom_string0);
485 str = neug_string_vendor;
486 size = sizeof (neug_string_vendor);
489 str = neug_string_product;
490 size = sizeof (neug_string_product);
494 size = sizeof (vcom_string3);
497 str = neug_revision_detail;
498 size = sizeof (neug_revision_detail);
501 str = neug_config_options;
502 size = sizeof (neug_config_options);
506 size = sizeof (sys_version);
509 return USB_UNSUPPORT;
512 usb_lld_set_data_to_send (str, size);
516 return USB_UNSUPPORT;
520 neug_setup_endpoints_for_interface (uint16_t interface, int stop)
525 usb_lld_setup_endpoint (ENDP2, EP_INTERRUPT, 0, 0, ENDP2_TXADDR, 0);
527 usb_lld_stall_tx (ENDP2);
529 else if (interface == 1)
533 usb_lld_setup_endpoint (ENDP1, EP_BULK, 0, 0, ENDP1_TXADDR, 0);
534 usb_lld_setup_endpoint (ENDP3, EP_BULK, 0, ENDP3_RXADDR, 0, 64);
538 usb_lld_stall_tx (ENDP1);
539 usb_lld_stall_rx (ENDP3);
544 int usb_cb_handle_event (uint8_t event_type, uint16_t value)
547 uint8_t current_conf;
551 case USB_EVENT_ADDRESS:
552 chopstx_mutex_lock (&usb_mtx);
553 bDeviceState = ADDRESSED;
554 chopstx_mutex_unlock (&usb_mtx);
556 case USB_EVENT_CONFIG:
557 current_conf = usb_lld_current_configuration ();
558 if (current_conf == 0)
561 return USB_UNSUPPORT;
563 usb_lld_set_configuration (1);
564 for (i = 0; i < NUM_INTERFACES; i++)
565 neug_setup_endpoints_for_interface (i, 0);
566 chopstx_mutex_lock (&usb_mtx);
567 bDeviceState = CONFIGURED;
568 chopstx_mutex_unlock (&usb_mtx);
570 else if (current_conf != value)
573 return USB_UNSUPPORT;
575 usb_lld_set_configuration (0);
576 for (i = 0; i < NUM_INTERFACES; i++)
577 neug_setup_endpoints_for_interface (i, 1);
578 chopstx_mutex_lock (&usb_mtx);
579 bDeviceState = ADDRESSED;
580 chopstx_mutex_unlock (&usb_mtx);
582 /* Do nothing when current_conf == value */
590 return USB_UNSUPPORT;
594 int usb_cb_interface (uint8_t cmd, uint16_t interface, uint16_t alt)
596 static uint8_t zero = 0;
598 if (interface >= NUM_INTERFACES)
599 return USB_UNSUPPORT;
603 case USB_SET_INTERFACE:
605 return USB_UNSUPPORT;
608 neug_setup_endpoints_for_interface (interface, 0);
612 case USB_GET_INTERFACE:
613 usb_lld_set_data_to_send (&zero, 1);
617 case USB_QUERY_INTERFACE:
622 #define INTR_REQ_USB 20
628 chopstx_intr_t interrupt;
631 usb_lld_init (vcom_configuration_desc[7]);
632 chopstx_claim_irq (&interrupt, INTR_REQ_USB);
633 usb_interrupt_handler ();
637 chopstx_intr_wait (&interrupt);
639 /* Process interrupt. */
640 usb_interrupt_handler ();
647 static void fill_serial_no_by_unique_id (void)
649 extern const uint8_t * unique_device_id (void);
650 uint8_t *p = &vcom_string3[12];
651 const uint8_t *u = unique_device_id ();
654 for (i = 0; i < 4; i++)
660 nibble += (nibble >= 10 ? ('A' - 10) : '0');
663 nibble += (nibble >= 10 ? ('A' - 10) : '0');
669 EP1_IN_Callback (void)
671 chopstx_mutex_lock (&usb_mtx);
672 chopstx_cond_signal (&cnd_usb);
673 chopstx_mutex_unlock (&usb_mtx);
677 EP2_IN_Callback (void)
682 EP3_OUT_Callback (void)
684 usb_lld_rx_enable (ENDP3);
687 typedef uint32_t eventmask_t;
688 #define ALL_EVENTS (~0)
691 chopstx_mutex_t mutex;
696 static void event_flag_init (struct event_flag *ev)
699 chopstx_mutex_init (&ev->mutex);
700 chopstx_cond_init (&ev->cond);
704 static eventmask_t event_flag_waitone (struct event_flag *ev, eventmask_t m)
708 chopstx_mutex_lock (&ev->mutex);
709 while (!(ev->flag & m))
710 chopstx_cond_wait (&ev->cond, &ev->mutex);
712 n = __builtin_ffs ((ev->flag & m));
713 ev->flag &= ~(1 << (n - 1));
714 chopstx_mutex_unlock (&ev->mutex);
716 return (1 << (n - 1));
719 static void event_flag_signal (struct event_flag *ev, eventmask_t m)
721 chopstx_mutex_lock (&ev->mutex);
723 chopstx_cond_signal (&ev->cond);
724 chopstx_mutex_unlock (&ev->mutex);
727 extern uint8_t __process1_stack_base__, __process1_stack_size__;
728 extern uint8_t __process3_stack_base__, __process3_stack_size__;
730 const uint32_t __stackaddr_led = (uint32_t)&__process1_stack_base__;
731 const size_t __stacksize_led = (size_t)&__process1_stack_size__;
732 const uint32_t __stackaddr_usb = (uint32_t)&__process3_stack_base__;
733 const size_t __stacksize_usb = (size_t)&__process3_stack_size__;
737 static struct event_flag led_event;
739 #define LED_ONESHOT_SHORT ((eventmask_t)1)
740 #define LED_TWOSHOTS ((eventmask_t)2)
741 #define LED_ONESHOT_LONG ((eventmask_t)4)
744 * LED blinker: When notified, let LED emit for 100ms.
747 led_blinker (void *arg)
757 m = event_flag_waitone (&led_event, ALL_EVENTS);
758 if (fsij_device_state != FSIJ_DEVICE_RUNNING) /* No usb_mtx lock. */
762 if (m == LED_ONESHOT_SHORT)
763 chopstx_usec_wait (100*1000);
764 else if (m == LED_TWOSHOTS)
766 chopstx_usec_wait (50*1000);
768 chopstx_usec_wait (50*1000);
770 chopstx_usec_wait (50*1000);
773 chopstx_usec_wait (250*1000);
780 #define RANDOM_BYTES_LENGTH 64
781 static uint32_t random_word[RANDOM_BYTES_LENGTH/sizeof (uint32_t)];
783 static void copy_to_tx (uint32_t v, int i)
785 usb_lld_txcpy (&v, ENDP1, i * 4, 4);
789 * In Gnuk 1.0.[12], reGNUal was not relocatable.
790 * Now, it's relocatable, but we need to calculate its entry address
791 * based on it's pre-defined address.
793 #define REGNUAL_START_ADDRESS_COMPATIBLE 0x20001400
795 calculate_regnual_entry_address (const uint8_t *addr)
797 const uint8_t *p = addr + 4;
798 uint32_t v = p[0] + (p[1] << 8) + (p[2] << 16) + (p[3] << 24);
800 v -= REGNUAL_START_ADDRESS_COMPATIBLE;
809 * NOTE: the main function is already a thread in the system on entry.
812 main (int argc, char **argv)
815 chopstx_t led_thread, usb_thd;
821 fill_serial_no_by_unique_id ();
825 event_flag_init (&led_event);
827 led_thread = chopstx_create (PRIO_LED, __stackaddr_led, __stacksize_led,
830 chopstx_mutex_init (&usb_mtx);
831 chopstx_cond_init (&cnd_usb);
833 usb_thd = chopstx_create (PRIO_USB, __stackaddr_usb, __stacksize_usb,
836 neug_init (random_word, RANDOM_BYTES_LENGTH/sizeof (uint32_t));
838 chopstx_mutex_lock (&usb_mtx);
843 while (count < NEUG_PRE_LOOP || bDeviceState != CONFIGURED)
845 if (fsij_device_state != FSIJ_DEVICE_RUNNING)
848 chopstx_mutex_unlock (&usb_mtx);
852 if ((count & 0x0007) == 0)
853 event_flag_signal (&led_event, LED_ONESHOT_SHORT);
854 chopstx_usec_wait (25*1000);
856 chopstx_mutex_lock (&usb_mtx);
859 /* Holding USB_MTX. */
862 int last_was_fullsizepacket = 0;
864 if (fsij_device_state != FSIJ_DEVICE_RUNNING)
869 wait_usb_connection = 5000*1000;
870 if (connected || bDeviceState != CONFIGURED
871 || fsij_device_state != FSIJ_DEVICE_RUNNING)
874 chopstx_mutex_unlock (&usb_mtx);
876 neug_mode_select (line_coding.paritytype);
877 event_flag_signal (&led_event, LED_TWOSHOTS);
878 chopstx_usec_wait_var (&wait_usb_connection);
879 chopstx_mutex_lock (&usb_mtx);
882 if (bDeviceState != CONFIGURED)
885 /* The connection opened. */
892 chopstx_mutex_unlock (&usb_mtx);
894 * No parity is standard. It means providing conditioned output.
895 * When parity enabled, it means to provide raw output
896 * (CRC32 filtered when odd, direct sample of ADC when even).
898 * line_coding.paritytype:
899 * 0: None, 1: Odd, 2: Even
901 neug_mode_select (line_coding.paritytype);
903 if ((count & 0x03ff) == 0)
904 event_flag_signal (&led_event, LED_ONESHOT_SHORT);
906 i = neug_consume_random (copy_to_tx);
908 if (i == 0 && !last_was_fullsizepacket)
909 { /* Only send ZLP when the last packet was fullsize. */
912 chopstx_mutex_lock (&usb_mtx);
913 if (bDeviceState != CONFIGURED || !connected
914 || fsij_device_state != FSIJ_DEVICE_RUNNING)
920 last_was_fullsizepacket = 1;
922 last_was_fullsizepacket = 0;
924 chopstx_mutex_lock (&usb_mtx);
925 if (bDeviceState != CONFIGURED || !connected
926 || fsij_device_state != FSIJ_DEVICE_RUNNING)
929 /* Prepare sending random data. */
930 usb_lld_tx_enable (ENDP1, i * 4);
931 chopstx_cond_wait (&cnd_usb, &usb_mtx);
937 chopstx_mutex_unlock (&usb_mtx);
939 chopstx_cancel (led_thread);
940 chopstx_join (led_thread, NULL);
943 * We come here, because of FSIJ_DEVICE_NEUG_EXIT_REQUESTED.
947 chopstx_mutex_lock (&usb_mtx);
948 fsij_device_state = FSIJ_DEVICE_EXITED;
950 while (fsij_device_state == FSIJ_DEVICE_EXITED)
952 chopstx_mutex_unlock (&usb_mtx);
953 chopstx_usec_wait (500*1000);
954 chopstx_mutex_lock (&usb_mtx);
956 chopstx_mutex_unlock (&usb_mtx);
958 flash_unlock (); /* Flash unlock should be done here */
962 /* Finish application. */
963 chopstx_cancel (usb_thd);
964 chopstx_join (usb_thd, NULL);
967 SCB->VTOR = (uint32_t)&_regnual_start;
968 entry = calculate_regnual_entry_address (&_regnual_start);
970 #define FLASH_SYS_START_ADDR 0x08000000
971 #define FLASH_SYS_END_ADDR (0x08000000+0x1000)
975 handler *new_vector = (handler *)FLASH_SYS_START_ADDR;
976 void (*func) (void (*)(void)) = (void (*)(void (*)(void)))new_vector[9];
979 for (addr = FLASH_SYS_START_ADDR; addr < FLASH_SYS_END_ADDR;
980 addr += FLASH_PAGE_SIZE)
981 flash_erase_page (addr);
983 /* copy system service routines */
984 flash_write (FLASH_SYS_START_ADDR, &_sys, 0x1000);
986 /* Leave NeuG to exec reGNUal */
987 (*func) ((void (*)(void))entry);
991 /* Leave NeuG to exec reGNUal */
992 flash_erase_all_and_exec ((void (*)(void))entry);