|
@@ -1,5 +1,6 @@
|
1
|
1
|
/**
|
2
|
2
|
* Copyright (c) 2022 Brian Starkey <stark3y@gmail.com>
|
|
3
|
+ * Copyright (c) 2023 Thomas Buck <thomas@xythobuz.de>
|
3
|
4
|
*
|
4
|
5
|
* Based on the Pico W tcp_server example:
|
5
|
6
|
* Copyright (c) 2022 Raspberry Pi (Trading) Ltd.
|
|
@@ -32,12 +33,8 @@
|
32
|
33
|
|
33
|
34
|
#ifdef DEBUG
|
34
|
35
|
#include <stdio.h>
|
|
36
|
+#include <stdarg.h>
|
35
|
37
|
#include "pico/stdio_usb.h"
|
36
|
|
-#define DBG_PRINTF_INIT() stdio_usb_init()
|
37
|
|
-#define DBG_PRINTF(...) printf(__VA_ARGS__)
|
38
|
|
-#else
|
39
|
|
-#define DBG_PRINTF_INIT() { }
|
40
|
|
-#define DBG_PRINTF(...) { }
|
41
|
38
|
#endif
|
42
|
39
|
|
43
|
40
|
#if PICOWOTA_WIFI_AP == 1
|
|
@@ -108,8 +105,32 @@ struct image_header app_image_header;
|
108
|
105
|
#define CMD_GO (('G' << 0) | ('O' << 8) | ('G' << 16) | ('O' << 24))
|
109
|
106
|
#define CMD_REBOOT (('B' << 0) | ('O' << 8) | ('O' << 16) | ('T' << 24))
|
110
|
107
|
|
|
108
|
+static uint32_t last_print_state = 0;
|
|
109
|
+
|
|
110
|
+void __attribute__((weak)) picowota_printf_init(void)
|
|
111
|
+{
|
|
112
|
+#ifdef DEBUG
|
|
113
|
+ stdio_usb_init();
|
|
114
|
+#endif
|
|
115
|
+}
|
|
116
|
+
|
|
117
|
+void __attribute__((weak)) picowota_printf(const char* format, ...)
|
|
118
|
+{
|
|
119
|
+#ifdef DEBUG
|
|
120
|
+ va_list args;
|
|
121
|
+ va_start(args, format);
|
|
122
|
+ vprintf(format, args);
|
|
123
|
+ va_end(args);
|
|
124
|
+#endif
|
|
125
|
+}
|
|
126
|
+
|
111
|
127
|
static uint32_t handle_sync(uint32_t *args_in, uint8_t *data_in, uint32_t *resp_args_out, uint8_t *resp_data_out)
|
112
|
128
|
{
|
|
129
|
+ if (last_print_state != CMD_SYNC) {
|
|
130
|
+ picowota_printf("sync cmd\n");
|
|
131
|
+ last_print_state = CMD_SYNC;
|
|
132
|
+ }
|
|
133
|
+
|
113
|
134
|
return RSP_SYNC;
|
114
|
135
|
}
|
115
|
136
|
|
|
@@ -141,6 +162,11 @@ static uint32_t handle_read(uint32_t *args_in, uint8_t *data_in, uint32_t *resp_
|
141
|
162
|
uint32_t addr = args_in[0];
|
142
|
163
|
uint32_t size = args_in[1];
|
143
|
164
|
|
|
165
|
+ if (last_print_state != CMD_READ) {
|
|
166
|
+ picowota_printf("read cmd 0x%08X %d\n", addr, size);
|
|
167
|
+ last_print_state = CMD_READ;
|
|
168
|
+ }
|
|
169
|
+
|
144
|
170
|
memcpy(resp_data_out, (void *)addr, size);
|
145
|
171
|
|
146
|
172
|
return TCP_COMM_RSP_OK;
|
|
@@ -180,6 +206,11 @@ static uint32_t handle_csum(uint32_t *args_in, uint8_t *data_in, uint32_t *resp_
|
180
|
206
|
uint32_t addr = args_in[0];
|
181
|
207
|
uint32_t size = args_in[1];
|
182
|
208
|
|
|
209
|
+ if (last_print_state != CMD_CSUM) {
|
|
210
|
+ picowota_printf("csum cmd 0x%08X %d\n", addr, size);
|
|
211
|
+ last_print_state = CMD_CSUM;
|
|
212
|
+ }
|
|
213
|
+
|
183
|
214
|
int channel = dma_claim_unused_channel(true);
|
184
|
215
|
|
185
|
216
|
dma_channel_config c = dma_channel_get_default_config(channel);
|
|
@@ -269,6 +300,11 @@ static uint32_t handle_crc(uint32_t *args_in, uint8_t *data_in, uint32_t *resp_a
|
269
|
300
|
uint32_t addr = args_in[0];
|
270
|
301
|
uint32_t size = args_in[1];
|
271
|
302
|
|
|
303
|
+ if (last_print_state != CMD_CRC) {
|
|
304
|
+ picowota_printf("crc cmd 0x%08X %d\n", addr, size);
|
|
305
|
+ last_print_state = CMD_CRC;
|
|
306
|
+ }
|
|
307
|
+
|
272
|
308
|
resp_args_out[0] = calc_crc32((void *)addr, size);
|
273
|
309
|
|
274
|
310
|
return TCP_COMM_RSP_OK;
|
|
@@ -289,6 +325,11 @@ static uint32_t handle_erase(uint32_t *args_in, uint8_t *data_in, uint32_t *resp
|
289
|
325
|
uint32_t addr = args_in[0];
|
290
|
326
|
uint32_t size = args_in[1];
|
291
|
327
|
|
|
328
|
+ if (last_print_state != CMD_ERASE) {
|
|
329
|
+ picowota_printf("erase cmd 0x%08X %d\n", addr, size);
|
|
330
|
+ last_print_state = CMD_ERASE;
|
|
331
|
+ }
|
|
332
|
+
|
292
|
333
|
if ((addr < ERASE_ADDR_MIN) || (addr + size >= FLASH_ADDR_MAX)) {
|
293
|
334
|
// Outside flash
|
294
|
335
|
return TCP_COMM_RSP_ERR;
|
|
@@ -348,6 +389,11 @@ static uint32_t handle_write(uint32_t *args_in, uint8_t *data_in, uint32_t *resp
|
348
|
389
|
uint32_t addr = args_in[0];
|
349
|
390
|
uint32_t size = args_in[1];
|
350
|
391
|
|
|
392
|
+ if (last_print_state != CMD_WRITE) {
|
|
393
|
+ picowota_printf("write cmd 0x%08X %d\n", addr, size);
|
|
394
|
+ last_print_state = CMD_WRITE;
|
|
395
|
+ }
|
|
396
|
+
|
351
|
397
|
critical_section_enter_blocking(&critical_section);
|
352
|
398
|
flash_range_program(addr - XIP_BASE, data_in, size);
|
353
|
399
|
critical_section_exit(&critical_section);
|
|
@@ -403,6 +449,11 @@ static bool image_header_ok(struct image_header *hdr)
|
403
|
449
|
|
404
|
450
|
static uint32_t handle_seal(uint32_t *args_in, uint8_t *data_in, uint32_t *resp_args_out, uint8_t *resp_data_out)
|
405
|
451
|
{
|
|
452
|
+ if (last_print_state != CMD_SEAL) {
|
|
453
|
+ picowota_printf("seal cmd\n");
|
|
454
|
+ last_print_state = CMD_SEAL;
|
|
455
|
+ }
|
|
456
|
+
|
406
|
457
|
struct image_header hdr = {
|
407
|
458
|
.vtor = args_in[0],
|
408
|
459
|
.size = args_in[1],
|
|
@@ -477,6 +528,11 @@ static void jump_to_vtor(uint32_t vtor)
|
477
|
528
|
|
478
|
529
|
static uint32_t handle_go(uint32_t *args_in, uint8_t *data_in, uint32_t *resp_args_out, uint8_t *resp_data_out)
|
479
|
530
|
{
|
|
531
|
+ if (last_print_state != CMD_GO) {
|
|
532
|
+ picowota_printf("go cmd\n");
|
|
533
|
+ last_print_state = CMD_GO;
|
|
534
|
+ }
|
|
535
|
+
|
480
|
536
|
struct event ev = {
|
481
|
537
|
.type = EVENT_TYPE_GO,
|
482
|
538
|
.go = {
|
|
@@ -503,6 +559,11 @@ struct comm_command go_cmd = {
|
503
|
559
|
|
504
|
560
|
static uint32_t handle_info(uint32_t *args_in, uint8_t *data_in, uint32_t *resp_args_out, uint8_t *resp_data_out)
|
505
|
561
|
{
|
|
562
|
+ if (last_print_state != CMD_INFO) {
|
|
563
|
+ picowota_printf("info cmd\n");
|
|
564
|
+ last_print_state = CMD_INFO;
|
|
565
|
+ }
|
|
566
|
+
|
506
|
567
|
resp_args_out[0] = WRITE_ADDR_MIN;
|
507
|
568
|
resp_args_out[1] = (XIP_BASE + PICO_FLASH_SIZE_BYTES) - WRITE_ADDR_MIN;
|
508
|
569
|
resp_args_out[2] = FLASH_SECTOR_SIZE;
|
|
@@ -532,6 +593,11 @@ static uint32_t size_reboot(uint32_t *args_in, uint32_t *data_len_out, uint32_t
|
532
|
593
|
|
533
|
594
|
static uint32_t handle_reboot(uint32_t *args_in, uint8_t *data_in, uint32_t *resp_args_out, uint8_t *resp_data_out)
|
534
|
595
|
{
|
|
596
|
+ if (last_print_state != CMD_REBOOT) {
|
|
597
|
+ picowota_printf("reboot cmd\n");
|
|
598
|
+ last_print_state = CMD_REBOOT;
|
|
599
|
+ }
|
|
600
|
+
|
535
|
601
|
struct event ev = {
|
536
|
602
|
.type = EVENT_TYPE_REBOOT,
|
537
|
603
|
.reboot = {
|
|
@@ -564,38 +630,38 @@ static bool should_stay_in_bootloader()
|
564
|
630
|
return !gpio_get(BOOTLOADER_ENTRY_PIN) || wd_says_so;
|
565
|
631
|
}
|
566
|
632
|
|
567
|
|
-int __attribute__((weak)) picowota_network_init()
|
|
633
|
+int __attribute__((weak)) picowota_init(void)
|
568
|
634
|
{
|
569
|
635
|
if (cyw43_arch_init()) {
|
570
|
|
- DBG_PRINTF("failed to initialise\n");
|
|
636
|
+ picowota_printf("failed to initialise\n");
|
571
|
637
|
return 1;
|
572
|
638
|
}
|
573
|
639
|
|
574
|
640
|
#if PICOWOTA_WIFI_AP == 1
|
575
|
641
|
cyw43_arch_enable_ap_mode(wifi_ssid, wifi_pass, CYW43_AUTH_WPA2_AES_PSK);
|
576
|
|
- DBG_PRINTF("Enabled the WiFi AP.\n");
|
|
642
|
+ picowota_printf("Enabled the WiFi AP.\n");
|
577
|
643
|
|
578
|
644
|
ip4_addr_t gw, mask;
|
579
|
645
|
IP4_ADDR(&gw, 192, 168, 4, 1);
|
580
|
646
|
IP4_ADDR(&mask, 255, 255, 255, 0);
|
581
|
647
|
|
582
|
648
|
dhcp_server_init(&dhcp_server, &gw, &mask);
|
583
|
|
- DBG_PRINTF("Started the DHCP server.\n");
|
|
649
|
+ picowota_printf("Started the DHCP server.\n");
|
584
|
650
|
#else
|
585
|
651
|
cyw43_arch_enable_sta_mode();
|
586
|
652
|
|
587
|
|
- DBG_PRINTF("Connecting to WiFi...\n");
|
|
653
|
+ picowota_printf("Connecting to WiFi...\n");
|
588
|
654
|
if (cyw43_arch_wifi_connect_timeout_ms(wifi_ssid, wifi_pass, CYW43_AUTH_WPA2_AES_PSK, 30000)) {
|
589
|
|
- DBG_PRINTF("failed to connect.\n");
|
|
655
|
+ picowota_printf("failed to connect.\n");
|
590
|
656
|
return 1;
|
591
|
657
|
} else {
|
592
|
|
- DBG_PRINTF("Connected.\n");
|
|
658
|
+ picowota_printf("Connected.\n");
|
593
|
659
|
}
|
594
|
660
|
#endif
|
595
|
661
|
return 0;
|
596
|
662
|
}
|
597
|
663
|
|
598
|
|
-void __attribute__((weak)) picowota_network_deinit()
|
|
664
|
+void __attribute__((weak)) picowota_deinit(void)
|
599
|
665
|
{
|
600
|
666
|
#if PICOWOTA_WIFI_AP == 1
|
601
|
667
|
dhcp_server_deinit(&dhcp_server);
|
|
@@ -625,12 +691,13 @@ int main()
|
625
|
691
|
jump_to_vtor(vtor);
|
626
|
692
|
}
|
627
|
693
|
|
628
|
|
- DBG_PRINTF_INIT();
|
|
694
|
+ picowota_printf_init();
|
629
|
695
|
|
630
|
696
|
queue_init(&event_queue, sizeof(struct event), EVENT_QUEUE_LENGTH);
|
631
|
697
|
|
632
|
|
- int n = picowota_network_init();
|
|
698
|
+ int n = picowota_init();
|
633
|
699
|
if (n != 0) {
|
|
700
|
+ picowota_printf("init error %d\n", n);
|
634
|
701
|
return n;
|
635
|
702
|
}
|
636
|
703
|
|
|
@@ -663,18 +730,22 @@ int main()
|
663
|
730
|
case EVENT_TYPE_SERVER_DONE:
|
664
|
731
|
err = tcp_comm_listen(tcp, TCP_PORT);
|
665
|
732
|
if (err != ERR_OK) {
|
666
|
|
- DBG_PRINTF("Failed to start server: %d\n", err);
|
|
733
|
+ picowota_printf("Failed to start server: %d\n", err);
|
|
734
|
+ } else {
|
|
735
|
+ picowota_printf("Listening on port %d\n", TCP_PORT);
|
667
|
736
|
}
|
668
|
737
|
break;
|
669
|
738
|
case EVENT_TYPE_REBOOT:
|
|
739
|
+ picowota_printf("reboot\n");
|
670
|
740
|
tcp_comm_server_close(tcp);
|
671
|
|
- picowota_network_deinit();
|
|
741
|
+ picowota_deinit();
|
672
|
742
|
picowota_reboot(ev.reboot.to_bootloader);
|
673
|
743
|
/* Should never get here */
|
674
|
744
|
break;
|
675
|
745
|
case EVENT_TYPE_GO:
|
|
746
|
+ picowota_printf("go\n");
|
676
|
747
|
tcp_comm_server_close(tcp);
|
677
|
|
- picowota_network_deinit();
|
|
748
|
+ picowota_deinit();
|
678
|
749
|
disable_interrupts();
|
679
|
750
|
reset_peripherals();
|
680
|
751
|
jump_to_vtor(ev.go.vtor);
|
|
@@ -686,6 +757,6 @@ int main()
|
686
|
757
|
picowota_poll();
|
687
|
758
|
}
|
688
|
759
|
|
689
|
|
- picowota_network_deinit();
|
|
760
|
+ picowota_deinit();
|
690
|
761
|
return 0;
|
691
|
762
|
}
|