|
@@ -11,8 +11,9 @@
|
11
|
11
|
#include <stdlib.h>
|
12
|
12
|
|
13
|
13
|
#include "RP2040.h"
|
14
|
|
-#include "pico/time.h"
|
15
|
14
|
#include "pico/critical_section.h"
|
|
15
|
+#include "pico/time.h"
|
|
16
|
+#include "pico/util/queue.h"
|
16
|
17
|
#include "hardware/dma.h"
|
17
|
18
|
#include "hardware/flash.h"
|
18
|
19
|
#include "hardware/structs/dma.h"
|
|
@@ -41,6 +42,27 @@ extern const char *wifi_ssid;
|
41
|
42
|
extern const char *wifi_pass;
|
42
|
43
|
critical_section_t critical_section;
|
43
|
44
|
|
|
45
|
+#define EVENT_QUEUE_LENGTH 8
|
|
46
|
+queue_t event_queue;
|
|
47
|
+
|
|
48
|
+enum event_type {
|
|
49
|
+ EVENT_TYPE_REBOOT = 1,
|
|
50
|
+ EVENT_TYPE_GO,
|
|
51
|
+ EVENT_TYPE_SERVER_DONE,
|
|
52
|
+};
|
|
53
|
+
|
|
54
|
+struct event {
|
|
55
|
+ enum event_type type;
|
|
56
|
+ union {
|
|
57
|
+ struct {
|
|
58
|
+ bool to_bootloader;
|
|
59
|
+ } reboot;
|
|
60
|
+ struct {
|
|
61
|
+ uint32_t vtor;
|
|
62
|
+ } go;
|
|
63
|
+ };
|
|
64
|
+};
|
|
65
|
+
|
44
|
66
|
#define BOOTLOADER_ENTRY_PIN 15
|
45
|
67
|
#define BOOTLOADER_ENTRY_MAGIC 0xb105f00d
|
46
|
68
|
|
|
@@ -434,15 +456,18 @@ static void jump_to_vtor(uint32_t vtor)
|
434
|
456
|
|
435
|
457
|
static uint32_t handle_go(uint32_t *args_in, uint8_t *data_in, uint32_t *resp_args_out, uint8_t *resp_data_out)
|
436
|
458
|
{
|
437
|
|
- disable_interrupts();
|
438
|
|
-
|
439
|
|
- reset_peripherals();
|
440
|
|
-
|
441
|
|
- jump_to_vtor(args_in[0]);
|
|
459
|
+ struct event ev = {
|
|
460
|
+ .type = EVENT_TYPE_GO,
|
|
461
|
+ .go = {
|
|
462
|
+ .vtor = args_in[0],
|
|
463
|
+ },
|
|
464
|
+ };
|
442
|
465
|
|
443
|
|
- while(1);
|
|
466
|
+ if (!queue_try_add(&event_queue, &ev)) {
|
|
467
|
+ return TCP_COMM_RSP_ERR;
|
|
468
|
+ }
|
444
|
469
|
|
445
|
|
- return TCP_COMM_RSP_ERR;
|
|
470
|
+ return TCP_COMM_RSP_OK;
|
446
|
471
|
}
|
447
|
472
|
|
448
|
473
|
struct comm_command go_cmd = {
|
|
@@ -503,10 +528,18 @@ static uint32_t size_reboot(uint32_t *args_in, uint32_t *data_len_out, uint32_t
|
503
|
528
|
|
504
|
529
|
static uint32_t handle_reboot(uint32_t *args_in, uint8_t *data_in, uint32_t *resp_args_out, uint8_t *resp_data_out)
|
505
|
530
|
{
|
506
|
|
- // Will never return
|
507
|
|
- do_reboot(args_in[0]);
|
|
531
|
+ struct event ev = {
|
|
532
|
+ .type = EVENT_TYPE_REBOOT,
|
|
533
|
+ .reboot = {
|
|
534
|
+ .to_bootloader = !!args_in[0],
|
|
535
|
+ },
|
|
536
|
+ };
|
|
537
|
+
|
|
538
|
+ if (!queue_try_add(&event_queue, &ev)) {
|
|
539
|
+ return TCP_COMM_RSP_ERR;
|
|
540
|
+ }
|
508
|
541
|
|
509
|
|
- return TCP_COMM_RSP_ERR;
|
|
542
|
+ return TCP_COMM_RSP_OK;
|
510
|
543
|
}
|
511
|
544
|
|
512
|
545
|
struct comm_command reboot_cmd = {
|
|
@@ -521,8 +554,12 @@ struct comm_command reboot_cmd = {
|
521
|
554
|
|
522
|
555
|
int main()
|
523
|
556
|
{
|
|
557
|
+ err_t err;
|
|
558
|
+
|
524
|
559
|
DBG_PRINTF_INIT();
|
525
|
560
|
|
|
561
|
+ queue_init(&event_queue, sizeof(struct event), EVENT_QUEUE_LENGTH);
|
|
562
|
+
|
526
|
563
|
if (cyw43_arch_init()) {
|
527
|
564
|
DBG_PRINTF("failed to initialise\n");
|
528
|
565
|
return 1;
|
|
@@ -555,18 +592,40 @@ int main()
|
555
|
592
|
|
556
|
593
|
struct tcp_comm_ctx *tcp = tcp_comm_new(cmds, sizeof(cmds) / sizeof(cmds[0]), CMD_SYNC);
|
557
|
594
|
|
|
595
|
+ struct event ev = {
|
|
596
|
+ .type = EVENT_TYPE_SERVER_DONE,
|
|
597
|
+ };
|
|
598
|
+
|
|
599
|
+ queue_add_blocking(&event_queue, &ev);
|
|
600
|
+
|
558
|
601
|
for ( ; ; ) {
|
559
|
|
- err_t err = tcp_comm_listen(tcp, TCP_PORT);
|
560
|
|
- if (err != ERR_OK) {
|
561
|
|
- DBG_PRINTF("Failed to start server: %d\n", err);
|
562
|
|
- sleep_ms(1000);
|
563
|
|
- continue;
|
|
602
|
+ while (queue_try_remove(&event_queue, &ev)) {
|
|
603
|
+ switch (ev.type) {
|
|
604
|
+ case EVENT_TYPE_SERVER_DONE:
|
|
605
|
+ err = tcp_comm_listen(tcp, TCP_PORT);
|
|
606
|
+ if (err != ERR_OK) {
|
|
607
|
+ DBG_PRINTF("Failed to start server: %d\n", err);
|
|
608
|
+ }
|
|
609
|
+ break;
|
|
610
|
+ case EVENT_TYPE_REBOOT:
|
|
611
|
+ tcp_comm_server_close(tcp);
|
|
612
|
+ cyw43_arch_deinit();
|
|
613
|
+ do_reboot(ev.reboot.to_bootloader);
|
|
614
|
+ /* Should never get here */
|
|
615
|
+ break;
|
|
616
|
+ case EVENT_TYPE_GO:
|
|
617
|
+ tcp_comm_server_close(tcp);
|
|
618
|
+ cyw43_arch_deinit();
|
|
619
|
+ disable_interrupts();
|
|
620
|
+ reset_peripherals();
|
|
621
|
+ jump_to_vtor(ev.go.vtor);
|
|
622
|
+ /* Should never get here */
|
|
623
|
+ break;
|
|
624
|
+ };
|
564
|
625
|
}
|
565
|
626
|
|
566
|
|
- while (!tcp_comm_server_done(tcp)) {
|
567
|
|
- cyw43_arch_poll();
|
568
|
|
- sleep_ms(1);
|
569
|
|
- }
|
|
627
|
+ cyw43_arch_poll();
|
|
628
|
+ sleep_ms(5);
|
570
|
629
|
}
|
571
|
630
|
|
572
|
631
|
cyw43_arch_deinit();
|