blob: c5c2b7c09e4a64950d09924d1deaa55f2c2cd60d [file] [log] [blame]
Sylvain Munautbc9f5c42020-09-14 10:22:29 +02001/*
2 * fw_app.c
3 *
4 * Copyright (C) 2019-2020 Sylvain Munaut <tnt@246tNt.com>
5 * SPDX-License-Identifier: GPL-3.0-or-later
6 */
7
8#include <stdint.h>
9#include <stdbool.h>
10#include <string.h>
11
12#include <no2usb/usb.h>
13#include <no2usb/usb_dfu_rt.h>
14
Sylvain Munautbc9f5c42020-09-14 10:22:29 +020015#include "console.h"
16#include "e1.h"
Sylvain Munautef5fe382022-01-12 11:55:44 +010017#include "gps.h"
Sylvain Munautbc9f5c42020-09-14 10:22:29 +020018#include "led.h"
19#include "misc.h"
20#include "mini-printf.h"
21#include "spi.h"
Sylvain Munautcaf8cf92022-01-12 13:35:12 +010022#include "usb_dev.h"
Sylvain Munaut632a3002020-10-29 13:25:45 +010023#include "usb_e1.h"
Sylvain Munautbc9f5c42020-09-14 10:22:29 +020024#include "utils.h"
25
26
27extern const struct usb_stack_descriptors app_stack_desc;
28
29static void
30serial_no_init()
31{
32 uint8_t buf[8];
33 char *id, *desc;
34 int i;
35
36 flash_manuf_id(buf);
37 printf("Flash Manufacturer : %s\n", hexstr(buf, 3, true));
38
39 flash_unique_id(buf);
40 printf("Flash Unique ID : %s\n", hexstr(buf, 8, true));
41
42 /* Overwrite descriptor string */
43 /* In theory in rodata ... but nothing is ro here */
44 id = hexstr(buf, 8, false);
45 desc = (char*)app_stack_desc.str[1];
46 for (i=0; i<16; i++)
47 desc[2 + (i << 1)] = id[i];
48}
49
50static void
51boot_dfu(void)
52{
53 /* Force re-enumeration */
54 usb_disconnect();
55
56 /* Boot firmware */
Sylvain Munaut46d6b412020-10-29 13:19:05 +010057 reboot(1);
Sylvain Munautbc9f5c42020-09-14 10:22:29 +020058}
59
60void
61usb_dfu_rt_cb_reboot(void)
62{
63 boot_dfu();
64}
65
66
Sylvain Munautbc9f5c42020-09-14 10:22:29 +020067void main()
68{
Sylvain Munautbc9f5c42020-09-14 10:22:29 +020069 int cmd = 0;
70
71 /* Init console IO */
72 console_init();
Sylvain Munaut2c33f6d2022-01-12 14:12:31 +010073 printf("\n\nBooting %s\n", fw_build_str);
Sylvain Munautbc9f5c42020-09-14 10:22:29 +020074
75 /* LED */
76 led_init();
77
78 /* SPI */
79 spi_init();
Sylvain Munaut5e860472020-09-15 22:20:21 +020080 serial_no_init();
81
82 /* Enable LED now that we're done with SPI */
83 e1_led_set(true, 0x00);
Sylvain Munautbc9f5c42020-09-14 10:22:29 +020084
85 /* Setup E1 Vref */
86 int d = 25;
Sylvain Munaut5e860472020-09-15 22:20:21 +020087#if defined(BOARD_ICE1USB_PROTO_ICEBREAKER) || defined(BOARD_ICE1USB_PROTO_BITSY)
Sylvain Munautbc9f5c42020-09-14 10:22:29 +020088 pdm_set(PDM_E1_CT, true, 128, false);
89 pdm_set(PDM_E1_P, true, 128 - d, false);
90 pdm_set(PDM_E1_N, true, 128 + d, false);
Sylvain Munaut5e860472020-09-15 22:20:21 +020091#else
92 pdm_set(PDM_E1_RX0, true, 128 + d, false);
93 pdm_set(PDM_E1_RX1, true, 128 + d, false);
94#endif
Sylvain Munautbc9f5c42020-09-14 10:22:29 +020095
96 /* Setup clock tuning */
97 pdm_set(PDM_CLK_HI, true, 2048, false);
98 pdm_set(PDM_CLK_LO, false, 0, false);
99
Sylvain Munautef5fe382022-01-12 11:55:44 +0100100 /* GPS init */
101 gps_init();
102
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200103 /* Enable USB directly */
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200104 usb_init(&app_stack_desc);
Sylvain Munautcaf8cf92022-01-12 13:35:12 +0100105 usb_dev_init();
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200106 usb_dfu_rt_init();
107 usb_e1_init();
108
109 /* Start */
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200110 led_state(true);
111 usb_connect();
112
113 /* Main loop */
114 while (1)
115 {
116 /* Prompt ? */
117 if (cmd >= 0)
118 printf("Command> ");
119
120 /* Poll for command */
121 cmd = getchar_nowait();
122
123 if (cmd >= 0) {
Sylvain Munautb4d25792022-01-06 22:04:21 +0100124 if (cmd > 32 && cmd < 127)
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200125 putchar(cmd);
Sylvain Munautb4d25792022-01-06 22:04:21 +0100126 putchar('\r');
127 putchar('\n');
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200128
129 switch (cmd)
130 {
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200131 case 'b':
132 boot_dfu();
133 break;
Sylvain Munautb4d25792022-01-06 22:04:21 +0100134 case 'p':
135 panic("Test panic");
136 break;
137 case 'q':
Sylvain Munaut3da51512022-01-03 22:12:59 +0100138 e1_debug_print(0, false);
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200139 break;
Sylvain Munautb4d25792022-01-06 22:04:21 +0100140 case 'Q':
Sylvain Munaut3da51512022-01-03 22:12:59 +0100141 e1_debug_print(0, true);
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200142 break;
Sylvain Munautb4d25792022-01-06 22:04:21 +0100143 case 'w':
144 e1_debug_print(1, false);
145 break;
146 case 'W':
147 e1_debug_print(1, true);
148 break;
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200149 case 'c':
150 usb_connect();
151 break;
152 case 'd':
153 usb_disconnect();
154 break;
Sylvain Munautb4d25792022-01-06 22:04:21 +0100155 case 'u':
156 usb_debug_print();
157 break;
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200158 default:
159 break;
160 }
161 }
162
163 /* USB poll */
164 usb_poll();
165
166 /* E1 poll */
Sylvain Munautc9c22a62022-01-12 11:47:08 +0100167 usb_e1_poll();
Sylvain Munautef5fe382022-01-12 11:55:44 +0100168
169 /* GPS poll */
170 gps_poll();
Sylvain Munautbc9f5c42020-09-14 10:22:29 +0200171 }
172}