SingingCat 0
application
main.c
1#include "main-header.h"
2#include "loader-api.h"
3#include "sx1262/sx1262.h"
4#include "irq_router.h"
5#include "ti1101.h"
6#include "softirq.h"
7#include "constants.h"
8#include "user_app_exe.h"
9#include "uECC.h"
10#include "flashapp.h"
11#include "function-instr.h"
12#include "wireless_state_machine.h"
13#include "powersave.h"
14#include "baseinfo.h"
15#include "ti1101-pinconfig.h"
16#include "metrics/metrics.h"
17#include "streams.h"
18#include "led.h"
19#include "sensors/sensor.h"
20#include "espressif/esp8266.h"
21#include "espressif/esp8266_flash.h"
22#include "espressif/esp8266_flash_from_serialport.h"
23#include "boot_info.h"
24#include "fets.h"
25#include "powerup.h"
26#include "ascii_parser.h"
27#include "usb.h"
28#include "route_command.h"
29#include "forwarding.h"
30#include "networkif.h"
31#include "route_command.h"
32#include "partitions.h"
33#include "sc_time.h"
34#include "hijack.h"
35// #include "bare-metal.h"
36
37extern byte overflow_check_active;
38
43static void start_delayed();
44
45struct hal_workspace hal;
46extern uint32_t acm_byte_received;
47static char minibuf[265];
48static byte ping_loop;
49static byte wifi_fail_ctr;
50static byte stopped = 0;
51static volatile int ping_ctr;
52static volatile int ack_ctr;
53static volatile long last_ping_received;
54#define MAX_SECS_BEFORE_DELAYED_START 10
55#define MAX_SECS_BETWEEN_STOP_WARNING 10
56#define MAX_SECS_BETWEEN_RADIO_BROADCASTS 300
57#define MAX_SECS_BETWEEN_LOOP_SAMPLES 5
58struct ringbuffer console_ringbuffer;
59
60// TODO: make this static (non-static because of troubleshooting 26/3/22)
61void irq_metric_counter(int pin) {
62 metric_inc_by_number(IRQ_COUNTER);
63}
64static void init_irq_metric_counter() {
65 // BREAKS irq stuff!!! (e.g. radio inbound packets)
66 //hal.pin_irq_callback = &irq_metric_counter;
67}
68
69void set_new_node_id(char *nodetxt) {
70 long nodeid = ascii_parse_hex((const byte *)nodetxt, strlen(nodetxt), NULL);
71
72 config_get_ram_struct()->nodeid = nodeid;
73 config_commit();
74 IPLOG("Committed new nodeid %N\r\n", config_get_ram_struct()->nodeid);
75}
76void create_new_node_id() {
77 config_get_ram_struct()->nodeid = adr_create_new_node_id();
78 config_commit();
79 IPLOG("Committed new nodeid %N\r\n", config_get_ram_struct()->nodeid);
80}
81void print_program_status() {
82 IPLOG("************* Application Info ************\r\n");
83 IPLOG("Build # %i\r\n", CNW_BUILD_VERSION);
84 IPLOG("Build Info: %s\r\n", get_cnw_build_info());
85 IPLOG("ModuleID: %i\r\n", (int)config_get_moduleid());
86 IPLOG("Application base: %p\r\n", get_app_header());
87 IPLOG("Loader API: %s\r\n", loader_has_api() ? "Yes" : "No");
88 IPLOG("Loader Version: %i\r\n", loader_get_version());
89 IPLOG("Last PC: %p\r\n", get_reboot_info()->function);
90 IPLOG("Secs since boot: %D\r\n", mculib_get_seconds_since_boot());
91 IPLOG("Secs since start: %D\r\n", get_seconds_since_start());
92 IPLOG("PowerUP MSG/cause : %i/%i\r\n", powerup_status(), mculib_get_reset_source());
93 IPLOG("Powermode flags: %p\r\n", config_get_powermode_flags());
94 IPLOG("Wifi Status: %s\r\n", esp8266_status_string());
95 IPLOG("Wifi State Machine: %s\r\n", wireless_state_to_string(wireless_get_current_state()));
96 IPLOG("Cloud Connection: %s\r\n", esp_cloud_is_connected() ? "Yes" : "No");
97 char buf[50];
98 struct ipv4address *adr = esp8266_get_current_ip();
99
100 if (adr == NULL) {
101 snprintf(buf, 40, "N/A");
102 } else {
103 snprintf(buf, 40, "%i.%i.%i.%i", adr->ip1, adr->ip2, adr->ip3, adr->ip4);
104 }
105 IPLOG("Wifi IP Address: %s\r\n", buf);
106 IPLOG("Userapp address: %p (linked for %p)\r\n", get_user_app(), (user_app_is_valid() ? get_user_app()->base:0));
107 IPLOG("Userapp version: %i\r\n", user_app_is_valid() ? get_user_app()->version : 0);
108 IPLOG("Userapp Repo: %i\r\n", user_app_is_valid() ? get_user_app()->repoid : 0);
109 IPLOG("Userapp enabled: %s\r\n", user_app_is_enabled() ? "Yes" : "No");
110 IPLOG("Userapp detected: %s\r\n", user_app_is_valid() ? "Yes" : "No");
111 IPLOG("Userapp executable: %s\r\n", user_app_executable() ? "Yes" : "No");
112 IPLOG("Userapp crc ok: %s\r\n", user_app_checksum_valid() ? "Yes" : "No");
113}
114
115static void failAt(uint32_t *x) {
116 printf("Failing at %p\r\n", x);
117 printf("Failing at %p\r\n", *x);
118 printf("Failing at %p\r\n", x);
119 *x = 1;
120}
121static void wifi_set_ap(char *line) {
122 int i;
123
124 for (i = 0; i < strlen(line); i++) {
125 if (line[i] == ' ') {
126 line[i] = 0;
127 esp8266_add_ap(line, line + i + 1);
128 }
129 }
131}
132
133void printHelp() {
134 print_program_status();
135 print_node_id(config_get_ram_struct()->nodeid);
136 printf("******* console help *****\r\n");
137 printf("newnodeid: create a new nodeid (careful), optional specifiy new id\r\n");
138 printf("verbose|quiet: set output to console on or off\r\n");
139 printf("constants: display constants in ram area\r\n");
140 printf("ping: ping once via radio\r\n");
141 printf("radiooff: disable cc1101\r\n");
142 printf("radioon: enable cc1101\r\n");
143 printf("wifioff: disable esp8266\r\n");
144 printf("wifion: enable esp8266\r\n");
145 printf("startflash: set esp8266 into flash mode via serial (for esptool)\r\n");
146 printf("startusbflash: set esp8266 into flash mode via usb (for esptool)\r\n");
147 printf("wififlash: same as startflash plus reset when done\r\n");
148 printf("wifidebug: reset esp8266 and bridge serialports\r\n");
149 printf("wifiscan: scan and list wifi accesspoints\r\n");
150 printf("sensorserver: set the dns-name of the server to send sensordata to\r\n");
151 printf("server: set the dns-name of the server to connect to\r\n");
152 printf("restart: restart app\r\n");
153 printf("startapp [adr]:start app at address adr\r\n");
154 printf("reset [num]: reset mcu (type=num,default=0)\r\n");
155 printf("pins: show current pint mappings\r\n");
156 printf("wifi2serial: bridge esp8266 serial to console\r\n");
157 printf("wifibaud [num]:set baudrate of esp8266 usart\r\n");
158 printf("wififlsp [num]:set baudrate of esp8266 usart during flash\r\n");
159 printf("ssid ssid pw: set new accesspoint credentials, e.g. \"ssid foo bar\"\r\n");
160 printf("esp_reset: reset esp8266\r\n");
161 printf("esp_init: setup esp8266\r\n");
162 printf("esp_debug: enable debug mode of esp8266 (also esp_debug [int])\r\n");
163 printf("esp_nodebug: disable debug mode of esp8266\r\n");
164 printf("esp_info: show state of esp8266 controller\r\n");
165 printf("esptest: low-level tests of esp8266\r\n");
166 printf("espmac: reads the mac address of esp8266 using rom bootloader\r\n");
167 printf("config_erase: erase config from flash\r\n");
168 printf("announce: broadcast routing updates\r\n");
169 printf("pingserver: send ping to server\r\n");
170 printf("network: print network information\r\n");
171 printf("nicprobe: reprobe network adapters\r\n");
172 printf("routes: print routing table\r\n");
173 printf("route_debug: enable/disable debug of routing code \r\n");
174 printf("forward_debug: enable/disable debug of forwarding code\r\n");
175 printf("forward_table: view forwarding tables\r\n");
176 printf("outqueue: print outbound command queue\r\n");
177 printf("clrqueue: clear outbound command queue\r\n");
178 printf("freecom: free all commands\r\n");
179 printf("fail: cause a hardfault\r\n");
180 printf("stop: stop processing everything but console\r\n");
181 printf("cont: continue processing stuff\r\n");
182 printf("loaderreset: erase loader config\r\n");
183 printf("loaderseq: set this app to latest loader sequence\r\n");
184 printf("log [string]: log something\r\n");
185 printf("memtest: check memory\r\n");
186 printf("stream_init: close all current streams\r\n");
187 printf("stream_info: print info of all current streams\r\n");
188 printf("stream_enable: start processing all streams\r\n");
189 printf("stream_disable:stop processing all streams\r\n");
190 printf("sensors: print sensor status\r\n");
191 printf("sensors_off: disable sensors\r\n");
192 printf("sensors_on: enable sensors\r\n");
193 printf("sensors_run: run sensors [name of sensor] (e.g. \"sensors_run 0 3\" (read sensor 0)\r\n");
194 printf("set_flag a b: set config flag a to b\r\n");
195 printf("show_flags: show current flags\r\n");
196 printf("pm_disable: disable power save modes\r\n");
197 printf("pm_wake: wake from power save mode\r\n");
198 printf("user_enable: enable userapp\r\n");
199 printf("user_disable: disable userapp\r\n");
200 printf("metric_send: send metrics to server \r\n");
201 printf("pwm_status: print status of current pwm\r\n");
202 printf("clock_sync: request clock synchronisation from server\r\n");
203 printf("softirq: print softirq status\r\n");
204 printf("clocksync [n] clock info OR enable(n=1))/disable(n=0) clocksync \r\n");
205 printf("********** end console help ******\r\n");
206}
207
208static uint32_t getmaxmem() {
209 uint32_t *start = (uint32_t *)0x20000000 + 2048;
210 //uint32_t *end = (uint32_t *)0x2000BFFF;
211
212 uint32_t *foo = start + 1024;
213 uint32_t *lc = start + 1048;
214
215 if (*foo == 0xAF34B012) {
216 return *lc;
217 }
218 *foo = 0xAF34B012;
219 uint32_t *adr = start;
220
221 for (;;) {
222 printf("poking memory at: %p\r\n", adr);
223 *lc = (uint32_t)adr;
224 adr = adr + 1024;
225 *adr = (uint32_t)adr;
226 if (*adr != (uint32_t)adr) {
227 break;
228 }
229 }
230 return *lc;
231}
232static void memcheck() {
233 uint32_t foo[] = { 0x20001FFF, 0x2000BFFF, 0x20001000, 0x20013f00, 0x20010000, 0 };
234 int i = 0;
235
236 for (;;) {
237 uint32_t f = foo[i];
238 if (f == 0) {
239 break;
240 }
241 printf("Memory at %p is stack: %i?\r\n", (void *)f, is_stack((void *)f));
242 i++;
243 }
244 printf("Max memory: %p\r\n", getmaxmem());
245}
246
247/*
248 * here input from the debug tty is processed.
249 * it checks for known strings (see readme)
250 * everything else it attempts to parse as a command
251 */
252void process_terminal_input() {
253 int linelen;
254 struct command *com;
255 char *terminal_line;
256
257 terminal_line = (char *)&minibuf;
258 linelen = console_get_line(terminal_line, 255);
259 if (linelen <= 0) {
260 if (linelen == -1) {
261 ringbuffer_init(&console_ringbuffer); // exceptionally long line - remove
262 }
263 return;
264 }
265 IPLOG("tty rx (%i): \"%s\"\r\n", linelen, terminal_line);
266 if ((strcmp(terminal_line, "help") == 0) || (strcmp(terminal_line, "?") == 0)) {
267 setquietflag(0); // someone typed help -> stop "quiet" mode
268 printHelp();
269 } else if (strcmp(terminal_line, "verbose") == 0) {
270 setquietflag(0);
271 } else if (strcmp(terminal_line, "user_disable") == 0) {
272 user_app_disable();
273 } else if (strcmp(terminal_line, "user_enable") == 0) {
274 user_app_reset_state();
275 user_app_exe_init();
276 user_app_enable();
277 } else if (strcmp(terminal_line, "quiet") == 0) {
278 setquietflag(1);
279 } else if ((strcmp(terminal_line, "status") == 0) || (strcmp(terminal_line, "\t") == 0)) {
280 print_program_status();
281 esp_info();
282 } else if (strcmp(terminal_line, "newnodeid") == 0) {
283 create_new_node_id();
284 } else if (startsWith(terminal_line, "newnodeid ")) {
285 set_new_node_id(terminal_line + 10);
286 } else if (strcmp(terminal_line, "ping") == 0) {
287 ping_loop = 0;
288 // doping();
289 } else if (strcmp(terminal_line, "network") == 0) {
290 print_all_nics();
291 } else if (strcmp(terminal_line, "nicprobe") == 0) {
292 init_all_nics();
293 } else if (strcmp(terminal_line, "radiooff") == 0) {
294 config_set_ti1101disable(1);
295 config_commit();
296 stop_nic_by_type(SOURCE_RADIO);
297 } else if (strcmp(terminal_line, "radioon") == 0) {
298 config_set_ti1101disable(0);
299 config_commit();
300 start_nic_by_type(SOURCE_RADIO);
301 } else if (strcmp(terminal_line, "wifioff") == 0) {
302 config_set_wifidisable(1);
303 config_commit();
305 } else if (strcmp(terminal_line, "wifion") == 0) {
306 config_set_wifidisable(0);
307 config_set_wifidetected(1);
308 config_commit();
310 } else if (strcmp(terminal_line, "usbappupdate") == 0) {
311 usb_appupdate();
312 } else if (strcmp(terminal_line, "startflash") == 0) {
314 } else if (strcmp(terminal_line, "startusbflash") == 0) {
315 esp8266_wififlash_usb_bridge();
316 } else if (strcmp(terminal_line, "wififlash") == 0) {
317 esp8266_flash_from_serialport();
318 printf("Wififlash done\r\n");
319 } else if (strcmp(terminal_line, "restart") == 0) {
320 restart_app();
321 } else if (startsWith(terminal_line, "startapp ")) {
322 restart_app_adr(atoi(terminal_line + 9));
323 } else if (startsWith(terminal_line, "reset")) {
324 printf("Resetting...\r\n");
325 reboot_fast();
326 } else if (startsWith(terminal_line, "wifibaud ")) {
327 int b = atoi(terminal_line + 9);
328 esp8266_set_operational_baudrate(b);
329 printf("Set ESP8266 Baudrate to %i\r\n", b);
330 } else if (startsWith(terminal_line, "wififlsp ")) {
331 int b = atoi(terminal_line + 9);
332 espflash_set_baud(b);
333 } else if (strcmp(terminal_line, "wifidebug") == 0) {
334 esp8266_dodebug("c");
335 } else if (strcmp(terminal_line, "wifiscan") == 0) {
336 start_wifi_scan();
337 } else if (startsWith(terminal_line, "wifidebug ")) {
338 esp8266_dodebug(terminal_line + 10);
339 } else if (strcmp(terminal_line, "pins") == 0) {
340 mculib_print_mappings(&printf);
341 } else if (strcmp(terminal_line, "wifi2serial") == 0) {
342 mculib_serialport_enable(MAIN_MCULIBHANDLE, USART_ESP8266, esp8266_get_operational_baudrate());
344 } else if (strcmp(terminal_line, "announce") == 0) {
345 send_routing_update_now();
346 } else if (strcmp(terminal_line, "routes") == 0) {
348 } else if (strcmp(terminal_line, "powerup") == 0) {
349 send_power_up_now(POWERUP_CLI);
350 } else if (strcmp(terminal_line, "esp_ota") == 0) {
351 esp8266_ota();
352 } else if (strcmp(terminal_line, "esp_reset") == 0) {
353 unhijack_esp32();
355 } else if (strcmp(terminal_line, "esp_init") == 0) {
356 esp_init();
357 } else if (strcmp(terminal_line, "esp_debug") == 0) {
358 set_esp8266_debug(3);
359 } else if (startsWith(terminal_line, "esp_debug ")) {
360 set_esp8266_debug(atoi(terminal_line + 10));
361 } else if (strcmp(terminal_line, "esptest") == 0) {
362 esp8266_test();
363 } else if (strcmp(terminal_line, "espmac") == 0) {
364 char buf[34];
365 esp_read_mac();
366 esp_get_mac(buf, sizeof(buf));
367 printf("Mac read: \"%s\"\r\n", buf);
368 } else if (strcmp(terminal_line, "esp_info") == 0) {
369 esp_info();
370 } else if (strcmp(terminal_line, "esp_nodebug") == 0) {
371 set_esp8266_debug(0);
372 } else if (startsWith(terminal_line, "server ")) {
373 const char *sn = terminal_line + 7;
374 config_set_cloud_server(sn);
375 config_commit();
377 } else if (startsWith(terminal_line, "sensorserver ")) {
378 const char *sn = terminal_line + 13;
379 config_set_sensor_server(sn);
380 printf("Set sensor server to \"%s\"\r\n", sn);
381 config_commit();
382 } else if (strcmp(terminal_line, "config_erase") == 0) {
383 config_erase();
384 } else if (strcmp(terminal_line, "sensors") == 0) {
385 sensor_info();
386 } else if (startsWith(terminal_line, "sensors_run ")) {
387 sensor_run_str(terminal_line + 12);
388 } else if (strcmp(terminal_line, "sensors_off") == 0) {
389 sensors_off();
390 config_set_sensors_enabled(0);
391 config_commit();
392 } else if (strcmp(terminal_line, "sensors_on") == 0) {
393 sensors_init();
394 config_set_sensors_enabled(1);
395 config_commit();
396 } else if (strcmp(terminal_line, "fail") == 0) {
397 failAt((void *)0x1fff000);
398 failAt((void *)&hal - (1024 * 32));
399 } else if (strcmp(terminal_line, "stop") == 0) {
400 stopped = 1;
401 } else if (strcmp(terminal_line, "outqueue") == 0) {
402 print_outbound_queue();
403 } else if (strcmp(terminal_line, "freecom") == 0) {
404 free_commands(-1);
405 } else if (strcmp(terminal_line, "clrqueue") == 0) {
407 } else if (strcmp(terminal_line, "pingserver") == 0) {
408 //pingserver();
409 } else if (strcmp(terminal_line, "loaderseq") == 0) {
410 int x = loader_set_latest_app(get_app_header());
411 printf("Loader sequence number increased. result: %i\r\n", x);
412 } else if (strcmp(terminal_line, "loaderreset") == 0) {
413 loader_erase_config();
414 printf("Config erased.\r\n");
415 } else if (strcmp(terminal_line, "constants") == 0) {
416 constants_print();
417 } else if (strcmp(terminal_line, "memtest") == 0) {
418 memcheck();
419 } else if (strcmp(terminal_line, "stream_enable") == 0) {
421 } else if (strcmp(terminal_line, "stream_disable") == 0) {
423 } else if (strcmp(terminal_line, "stream_info") == 0) {
425 } else if (strcmp(terminal_line, "stream_init") == 0) {
426 stream_init();
427 printf("Streams reinitialized\r\n");
428 } else if (strcmp(terminal_line, "show_flags") == 0) {
429 printf("Flags : %p\r\n", config_get_flags());
430 printf("UserFlags: %p\r\n", (uint32_t)get_user_config_flags());
431 } else if (startsWith(terminal_line, "set_flag ")) {
432 config_flag_line(terminal_line + 9);
433 } else if (startsWith(terminal_line, "log ")) {
434 iplog("%s", terminal_line + 4);
435 printf("Logged \"%s\"\r\n", terminal_line + 4);
436 } else if (strcmp(terminal_line, "forward_table") == 0) {
437 print_forwarding_table();
438 } else if (strcmp(terminal_line, "softirq") == 0) {
439 print_softirqs();
440 } else if (strcmp(terminal_line, "clocksync") == 0) {
441 clocksync_help();
442 } else if (startsWith(terminal_line, "clocksync ")) {
443 clocksync_enable((uint8_t)((terminal_line[10]) - '0'));
444 } else if (strcmp(terminal_line, "forward_debug") == 0) {
445 set_forward_debug(1);
446 routing_command_debug(1);
447 } else if (strcmp(terminal_line, "route_debug") == 0) {
448 if (get_routing_debug()) {
449 set_routing_debug(0);
450 } else {
451 set_routing_debug(1);
452 }
453 } else if (strcmp(terminal_line, "cont") == 0) {
454 stopped = 0;
455 } else if (strcmp(terminal_line, "pm_disable") == 0) {
456 config_set_flag(CONFIG_FLAGS_POWER_SAVE, 0);
457 } else if (strcmp(terminal_line, "pm_wake") == 0) {
458 set_mcu_power_mode(0xFF);
459 } else if (startsWith(terminal_line, "ssid ")) {
460 wifi_set_ap(terminal_line + 5);
461 } else if (strcmp(terminal_line, "flashdebug") == 0) {
462 flash_debug();
463 } else if (strcmp(terminal_line, "clock_sync") == 0) {
464 send_clock_sync_request();
465 } else if (strcmp(terminal_line, "pwm_status") == 0) {
466 print_pwm_state();
467 } else if (strcmp(terminal_line, "metric_send") == 0) {
468 metric_send();
469 } else {
470 // it is not a known string, so parse as command
471 com = command_parse((const byte *)terminal_line, linelen);
472 if (com == NULL) {
473 IPLOG("Invalid command from tty: \"%s\"\r\n", terminal_line);
474 printHex("TTY: ", (const uint8_t *)terminal_line, linelen);
475 } else {
476 com->sourcedev = 3;
478 got_new_packet(com, 255);
479 }
480 }
481}
482
483int console_get_line(char *outbuf, int outbufsize) {
484 return ringbuffer_get_to_delimiter(&console_ringbuffer, '\r', outbuf, outbufsize);
485}
486void console_add_byte(uint8_t b) {
487 ringbuffer_add_byte(&console_ringbuffer, b);
488}
489uint16_t console_get_byte() {
490 return ringbuffer_get_byte(&console_ringbuffer);
491}
492void console_reset() {
493 ringbuffer_init(&console_ringbuffer);
494}
495
496void app_main_no_return() __attribute__ ((noreturn));
497void serialirq(int port, byte b) __attribute__((no_instrument_function));
498
499// called by mculib whenever we get a new byte
500void serialirq(int port, byte b) {
501 IncMetric_METRIC_IRQ_SERIAL;
502 if (user_serial_callback(port, b)) {
503 return;
504 }
505 if (port == USART_ESP8266) {
506 if (hijack_receive_esp32(b) == 0) {
508 }
509 return;
510 } else if (port == USART_CONSOLE) {
511 if (acm_byte_received == 0) { // only accept if we don't get data from acm
512 ringbuffer_add_byte(&console_ringbuffer, b);
513 }
514 } else if (port == 3) {
515 //userheader
516 } else {
517 printf("Dodgy port IRQ: %i\r\n", port);
518 }
519}
520void app_main_no_return() {
521 int ci = constants_init();
522
523 hijack_init();
524 powerup_init();
525 mculib_init(&hal);
526 mculib_reset_source_clear();
527 stream_init();
528 ringbuffer_init(&console_ringbuffer);
529 packet_init();
531 softirq_init();
532 logging_init();
533 routing_init();
536 mculib_enable_irq(MAIN_MCULIBHANDLE);
537 mculib_serialport_enable(MAIN_MCULIBHANDLE, USART_CONSOLE, 115200);
538 sctime_init();
539 int i;
540
541 for (i = 0; i < 3; i++) {
542 printf("\r\n");
543 }
544 constants()->reset_counter++;
545 constants_validate();
546 if (ci) {
547 printf("Constant ram area re-initialised.\r\n\r\n");
548 } else {
549 printf("Constant ram area reusable (Reset #%i).\r\n\r\n", constants()->reset_counter);
550 constants_print();
551 }
552 printf("SingingCat Application #%i\r\n", CNW_BUILD_VERSION);
553 printf("Initializing systicks...\r\n");
554 mculib_systick(10, &UserSysTick_Handler);
555 printf("Hal->systick load : %D\r\n", mculib_workspace_get()->systick_load);
556 printf("Hal->systick calibration: %D\r\n", mculib_workspace_get()->systick_calibration);
557 printf("Getting time...\r\n");
558
559 printf("Time is: %i\r\n", get_seconds_since_start());
560 stopped = 0;
561 overflow_check_active = 1;
562
563 wifi_fail_ctr = 0;
564 ping_loop = 0;
565 ping_ctr = 0;
566 ack_ctr = 0;
567 irq_router_init();
568 if (flash_config_init()) {
569 IPLOG("Config: Created\r\n");
570 // created config
571 long l = loader_get_user_long();
572 //printf("Loadertable: %p\r\n", get_loader_table());
573 printf("User long: %p\r\n", (void *)l);
574 } else {
575 IPLOG("Config: Valid\r\n");
576 }
577 fets_init();
578
579 metric_init();
580
581 mculib_watchdog_avoid();
582 long n = config_get_log_node();
583
584 if (n != 0) {
586 logging_on();
587 }
588
589 // start usb
590 usb_start();
591 print_to_usb(1);
592 routing_command_init();
593
594 // indicate we got power and are running
595 led_init();
596 if (mculib_get_reset_source() == HAL_RESET_POWER) {
597 led_indicate(LED_POWERUP);
598 } else {
599 led_indicate(LED_RESET);
600 }
601
602 mculib_serialport_callback(MAIN_MCULIBHANDLE, &serialirq);
603
604 init_nic_registry();
605 IPLOG("************* App started ************\r\n");
606
607 partition_init();
608
609 printf("Init userapp..\r\n");
610 user_app_exe_init(); // init userapp stuff
611
612 IPLOG("********* Init Network ***********\r\n");
613 // we try the new 'netdev' api:
614 register_nic(ti1101_get_netdev(), SOURCE_RADIO);
615 register_nic(sx1262_get_netdev(), SOURCE_LORA);
616
617 // ******************* init all nics
618 init_all_nics();
619 // ******************* init serialport etc..
620
621
623 printf("********** MAIN ***********\r\n");
624 logging_event_loop(); // flush out the logging (small buffers, do this often)
625
626 avoid_watchdog();
627
628 printf("Initializing wifi...\r\n");
629 esp_init();
630 logging_event_loop(); // flush out the logging (small buffers, do this often)
631 printf("wifi initialized...\r\n");
632
633
634 if (!adr_isvalid(config_get_ram_struct()->nodeid)) {
635 create_new_node_id();
636 }
637 logging_event_loop(); // flush out the logging (small buffers, do this often)
638 print_node_id(config_get_ram_struct()->nodeid);
639
640 logging_event_loop(); // flush out the logging (small buffers, do this often)
641 print_program_status();
642 logging_event_loop(); // flush out the logging (small buffers, do this often)
643 IPLOG("User long: %p\r\n", (void *)loader_get_user_long());
644
645 logging_event_loop(); // flush out the logging (small buffers, do this often)
646
647 long lastradioping = 0;
648
649 logging_event_loop(); // flush out the logging (small buffers, do this often)
650
651 static uint8_t delayed_started = 0;
652
653 if (mculib_usb_host_connected(MAIN_MCULIBHANDLE) == 0) {
654 printf("No usb host, starting immediately...\r\n");
655 // if no usb host is connected, start immediately
656 start_delayed();
657 delayed_started = 1;
658 }
659
660 init_irq_metric_counter();
661
662 uint32_t loopctr1 = 0;
663 long loopctrsec = 0;
664
665 long delayedctr = 0;
666
667 /********************************************************
668 ***** MAIN LOOP ********
669 *******************************************************/
670 IPLOG("mainloop!\r\n");
671 logging_event_loop(); // flush out the logging (small buffers, do this often)
672
673
674 while (1) {
675 metric_inc_by_number(LOOP_COUNTER);
676 // we start some stuff "delayed" (if and only if a usb host is connected)
677 // this makes it easier to recover from borken userapps
678 if (!delayed_started) {
679 if (mculib_has_time_passed(MAX_SECS_BEFORE_DELAYED_START, &delayedctr)) {
680 printf("usb host, completing late initialization...\r\n");
681 start_delayed();
682 delayed_started = 1;
683 }
684 }
685 /************************ powersave handling ****************/
686
687 // shall we go into powersave mode?
688 power_main_loop(); // this function may not return for upto 5 minutes
689
690 /************************ full-feature, no powersave mode: ****************/
691 process_irqs(); // process all the softirqs now
692
693 loopctr1++;
694
695 if (mculib_has_time_passed(MAX_SECS_BETWEEN_LOOP_SAMPLES, &loopctrsec)) {
696 if (loopctr1 < 500) {
697 // if too slow, increase speed!
698 power_set_speed(10);
699 }
700 printf("Loopctrs: %i @ speed %i\r\n", loopctr1, mculib_get_speed());
701 loopctr1 = 0;
702 }
703 avoid_watchdog();
704 /* check for commands on the terminal */
705 process_terminal_input();
706
707 if (stopped) {
708 if (mculib_has_time_passed(MAX_SECS_BETWEEN_STOP_WARNING, &lastradioping)) {
709 printf("Stopped (\"cont\" to continue.)\r\n");
710 }
711 continue;
712 }
713
714 avoid_watchdog();
715 logging_event_loop(); // flush out the logging (small buffers, do this often)
716
717 /* process incoming esp8266 packets */
718 if ((!config_get_wifidisable()) && (!is_hijacked_esp32())) {
719 int bs;
720 int r = 0;
721 while ((bs = esp8266_packet_size()) > 0) {
722 r++;
723 if (r > 5) { // process at most 5 packets in one loop
724 break;
725 }
726 esp8266_get_buf()[bs] = 0;
728 }
729 }
730
731 //Delay(1); // in main: only loop in .001s intervals
732
733 // TODO: each eventqueue should report wether or not it requires another
734 // call. if we knew that here, we could safely go to sleep at some point
735
736 // check the event queues. (reset watchdog before entering a queue)
737
738 avoid_watchdog();
739 logging_event_loop(); // flush out the logging (small buffers, do this often)
740
741 process_nic_event_loop();
742 avoid_watchdog();
743 logging_event_loop(); // flush out the logging (small buffers, do this often)
744
745 avoid_watchdog(); // we are progressing, so go away watchdog
746 if (is_hijacked_esp32()) {
747 //this takes current bytes in dma buffer and feeds them to the one-byte soft-IRQ
748 mculib_serialport_transferbuffer(USART_ESP8266);
749 } else {
750 esp8266_event_loop();
751 }
752
753 avoid_watchdog();
754 logging_event_loop(); // flush out the logging (small buffers, do this often)
755
756 avoid_watchdog(); // we are progressing, so go away watchdog
758
759 avoid_watchdog();
760 logging_event_loop(); // flush out the logging (small buffers, do this often)
761
762 avoid_watchdog(); // we are progressing, so go away watchdog
763 routing_event_loop();
764
765 avoid_watchdog();
766 logging_event_loop(); // flush out the logging (small buffers, do this often)
767
768 avoid_watchdog(); // we are progressing, so go away watchdog
769 process_command_queue(); // do this at the end to so to quickly get rid of queued packets
770
771 avoid_watchdog();
772 logging_event_loop(); // flush out the logging (small buffers, do this often)
773
774 avoid_watchdog();
775 stream_loop();
776
777 avoid_watchdog();
778 logging_event_loop(); // flush out the logging (small buffers, do this often)
779
780 led_loop();
781
782 /* this needs an oscilloscope to properly be debugged */
783 /*
784 * int nspeed = 10;
785 * uint32_t speed_lock = mculib_raise_speed(nspeed);
786 * printf("New MCU Speed: %i\r\n",nspeed);
787 * mculib_serialport_enable(USART_CONSOLE, 115200);
788 */
789 avoid_watchdog();
790 logging_event_loop(); // flush out the logging (small buffers, do this often)
791
792 sensor_loop();
793 logging_event_loop(); // flush out the logging (small buffers, do this often)
794 /*
795 * nspeed = mculib_lower_speed(speed_lock);
796 * printf("New MCU Speed: %i\r\n",nspeed);
797 * mculib_serialport_enable(USART_CONSOLE, 115200);
798 */
799 if (user_app_executable()) {
800 avoid_watchdog();
801 logging_event_loop(); // flush out the logging (small buffers, do this often)
802 invoke_user_loop();
803 }
804
805 avoid_watchdog();
806 logging_event_loop(); // flush out the logging (small buffers, do this often)
807 fets_loop();
808
809 avoid_watchdog();
810 logging_event_loop(); // flush out the logging (small buffers, do this often)
811 metric_loop();
812
813 avoid_watchdog();
814 logging_event_loop(); // flush out the logging (small buffers, do this often)
815 check_power_on_loop();
816
817 avoid_watchdog();
818 logging_event_loop(); // flush out the logging
819 check_time_on_loop();
820 }
821}
822
823
824static void start_delayed() {
825 if (config_get_flag(CONFIG_FLAGS_START_USERAPP_ON_BOOT)) {
826 printf("Enable userapp..\r\n");
827 user_app_enable(); // do this before sensors are enabled, so we pick up any sensors that are registered from user
828 }
829 if (config_get_sensors_enabled()) {
830 sensors_init();
831 } else {
832 printf("sensors disabled in config.\r\n");
833 }
834}
835
839int app_main(void) {
840 app_main_no_return();
841 return 0;
842}
definitions of routing table structures
void logging_set_node(long nodeid)
log to a given node. Usually this would be an app or a server
Definition: logging.c:27
void esp8266_enable()
enable the esp8266 (switch it on)
Definition: esp8266.c:1442
void esp8266_wififlash_bridge(void)
set esp8266 to flash mode, sync and then bridge ("startflash")
Definition: esp8266.c:675
void packet_init()
initialize (reset, clear) all buffers
Definition: packetbuffer.c:52
void routing_print_table()
print routing table
Definition: routing.c:539
int app_main(void)
Definition: main.c:839
void logging_init()
initialise logging. logging is disabled after calling this function
Definition: logging.c:20
int esp_read_mac()
Definition: esp8266.c:948
void stream_loop()
called periodically, checks for stale streams and/or hung ones
Definition: streams.c:590
void free_commands(int index)
free commands by index (-1 for all)
Definition: queue.c:181
void decode_esp_packet_init()
int esp8266_packet_size()
returns 0 if no packet is in buf, otherwise returns size of packet in bytes
void print_boot_info()
print startup information
Definition: boot_info.c:37
void routing_init()
called when we power-up
Definition: routing.c:57
char * esp8266_status_string()
returns a human readable status string of the wifi connection
Definition: esp8266.c:859
int start(int MCULIBHANDLE, struct sc_firmware_api *api)
this is called when the board powers up
Definition: userhooks.c:31
void sensors_init()
initialize sensors, runtime, config, powerup each sensor in turn etc..
Definition: sensor.c:382
void esp8266_read_byte_from_serialport(int val)
this is called directly from the usart IRQ. be quick. and do not use printf()
Definition: esp8266.c:1262
void sensors_off()
disable sensors
Definition: sensor.c:629
void esp8266_ota()
tell the esp to do an OTA
Definition: esp8266.c:1328
int sensor_loop()
called periodically. this will either query sensors when they are due or will set the isdue flag for ...
Definition: sensor.c:845
byte * esp8266_get_buf()
get the buffer
void logging_event_loop()
sends current buffer and empties it
Definition: logging.c:54
void print_stream_info()
print summary of current streams to console
Definition: streams.c:642
void esp8266_reset()
reset state machine and esp8266
Definition: esp8266.c:387
void esp8266_got_packet(const byte *buf, int size)
Definition: esp8266.c:1069
void clear_outbound_queue()
clear the outbound queue any commands within the queue are silently discarded
Definition: queue.c:87
int ack_ctr
void stream_enable()
enable all stream handling (default)
Definition: streams.c:54
void logging_on()
enable logging and logging processing. buffers are used for logging
Definition: logging.c:42
int esp_get_mac(char *buf, int bufsize)
get the esp8266 mac address.
Definition: esp8266.c:931
byte got_new_packet(struct command *com, uint8_t signal_indicator)
stack received a new packet (signal indicator is a 0-255 byte value, interface specific)
Definition: routing.c:111
void esp8266_disable()
disable the esp8266 (switch it off)
Definition: esp8266.c:1446
void stream_disable()
disable all stream handling
Definition: streams.c:47
void command_print(struct command *com)
prints a command in human readable format to serial console
void process_command_queue()
this gets called when we got some cpu cycles spare we then send out commands and timeout other comman...
Definition: queue.c:682
void esp_init()
call this ONCE before calling anything else
Definition: esp8266.c:883
void esp8266_test()
Definition: esp8266.c:256
struct ipv4address * esp8266_get_current_ip()
return last ip (null if none)
Definition: esp8266.c:1229
void esp8266_add_ap(const char *ssid, const char *pw)
add an ap to the list of known ap
Definition: esp8266.c:424
void esp8266_bridge()
bridge debug serialport and esp8266 (e.g. "wifidebug")
Definition: esp8266.c:791
void multi_mem_init()
called very early on, even before printf works
Definition: multiram.c:26
void init_command_handler()
resets the command handler
void iplog(const char *format,...)
log something to a remote node
Definition: logging.c:87
int com
Definition: command.h:22