Browse Source

proper timeouts for ble write, now working.

Thomas Buck 1 year ago
parent
commit
c3a43c4f91
4 changed files with 83 additions and 26 deletions
  1. 2
    0
      include/config.h
  2. 58
    8
      src/ble.c
  3. 1
    2
      src/main.c
  4. 22
    16
      src/serial.c

+ 2
- 0
include/config.h View File

19
 #ifndef __CONFIG_H__
19
 #ifndef __CONFIG_H__
20
 #define __CONFIG_H__
20
 #define __CONFIG_H__
21
 
21
 
22
+#define WATCHDOG_PERIOD_MS 1000
23
+
22
 // ASCII 0x18 = CAN (cancel)
24
 // ASCII 0x18 = CAN (cancel)
23
 #define ENTER_BOOTLOADER_MAGIC 0x18
25
 #define ENTER_BOOTLOADER_MAGIC 0x18
24
 
26
 

+ 58
- 8
src/ble.c View File

20
  */
20
  */
21
 
21
 
22
 #include "pico/cyw43_arch.h"
22
 #include "pico/cyw43_arch.h"
23
+#include "hardware/watchdog.h"
23
 
24
 
24
 #include "config.h"
25
 #include "config.h"
25
 #include "log.h"
26
 #include "log.h"
26
 #include "util.h"
27
 #include "util.h"
27
 #include "ble.h"
28
 #include "ble.h"
28
 
29
 
30
+#define BLE_READ_TIMEOUT_MS 500
31
+#define BLE_SRVC_TIMEOUT_MS 500
32
+#define BLE_CHAR_TIMEOUT_MS 2000
33
+#define BLE_WRTE_TIMEOUT_MS 500
29
 #define BLE_MAX_SCAN_AGE_MS (10 * 1000)
34
 #define BLE_MAX_SCAN_AGE_MS (10 * 1000)
30
 #define BLE_MAX_SERVICES 8
35
 #define BLE_MAX_SERVICES 8
31
 #define BLE_MAX_CHARACTERISTICS 8
36
 #define BLE_MAX_CHARACTERISTICS 8
485
     read_len = 0;
490
     read_len = 0;
486
     cyw43_thread_exit();
491
     cyw43_thread_exit();
487
 
492
 
493
+    uint32_t start_time = to_ms_since_boot(get_absolute_time());
488
     while (1) {
494
     while (1) {
489
         sleep_ms(1);
495
         sleep_ms(1);
490
 
496
 
491
-        // TODO timeout
497
+        uint32_t now = to_ms_since_boot(get_absolute_time());
498
+        if ((now - start_time) >= BLE_READ_TIMEOUT_MS) {
499
+            debug("timeout waiting for read");
500
+            return -3;
501
+        }
502
+#if BLE_READ_TIMEOUT_MS >= (WATCHDOG_PERIOD_MS / 2)
503
+        watchdog_update();
504
+#endif
492
 
505
 
493
         cyw43_thread_enter();
506
         cyw43_thread_enter();
494
         enum ble_state state_cached = state;
507
         enum ble_state state_cached = state;
506
     if (read_len > buff_len) {
519
     if (read_len > buff_len) {
507
         debug("buffer too short (%d < %d)", buff_len, read_len);
520
         debug("buffer too short (%d < %d)", buff_len, read_len);
508
         cyw43_thread_exit();
521
         cyw43_thread_exit();
509
-        return -3;
522
+        return -4;
510
     }
523
     }
511
 
524
 
512
     memcpy(buff, data_buff, read_len);
525
     memcpy(buff, data_buff, read_len);
566
         cyw43_thread_exit();
579
         cyw43_thread_exit();
567
 
580
 
568
         debug("waiting for service discovery");
581
         debug("waiting for service discovery");
582
+
583
+        uint32_t start_time = to_ms_since_boot(get_absolute_time());
569
         while (1) {
584
         while (1) {
570
             sleep_ms(1);
585
             sleep_ms(1);
571
 
586
 
572
-            // TODO timeout
587
+            uint32_t now = to_ms_since_boot(get_absolute_time());
588
+            if ((now - start_time) >= BLE_SRVC_TIMEOUT_MS) {
589
+                debug("timeout waiting for service");
590
+                return -3;
591
+            }
592
+#if BLE_SRVC_TIMEOUT_MS >= (WATCHDOG_PERIOD_MS / 2)
593
+            watchdog_update();
594
+#endif
573
 
595
 
574
             cyw43_thread_enter();
596
             cyw43_thread_enter();
575
             enum ble_state state_cached = state;
597
             enum ble_state state_cached = state;
580
                 break;
602
                 break;
581
             }
603
             }
582
         }
604
         }
605
+
606
+        // allow some time for service discovery
607
+        watchdog_update();
608
+
609
+        cyw43_thread_enter();
583
     }
610
     }
584
 
611
 
585
     // check if characteristic has already been discovered
612
     // check if characteristic has already been discovered
616
         if (r != ERROR_CODE_SUCCESS) {
643
         if (r != ERROR_CODE_SUCCESS) {
617
             cyw43_thread_exit();
644
             cyw43_thread_exit();
618
             debug("gatt characteristic discovery failed %d", r);
645
             debug("gatt characteristic discovery failed %d", r);
619
-            return -3;
646
+            return -4;
620
         }
647
         }
621
 
648
 
622
         state = TC_W4_CHARACTERISTIC;
649
         state = TC_W4_CHARACTERISTIC;
624
         cyw43_thread_exit();
651
         cyw43_thread_exit();
625
 
652
 
626
         debug("waiting for characteristic discovery");
653
         debug("waiting for characteristic discovery");
654
+
655
+        uint32_t start_time = to_ms_since_boot(get_absolute_time());
627
         while (1) {
656
         while (1) {
628
             sleep_ms(1);
657
             sleep_ms(1);
629
 
658
 
630
-            // TODO timeout
659
+            uint32_t now = to_ms_since_boot(get_absolute_time());
660
+            if ((now - start_time) >= BLE_CHAR_TIMEOUT_MS) {
661
+                debug("timeout waiting for characteristic");
662
+                return -5;
663
+            }
664
+#if BLE_CHAR_TIMEOUT_MS >= (WATCHDOG_PERIOD_MS / 2)
665
+            watchdog_update();
666
+#endif
631
 
667
 
632
             cyw43_thread_enter();
668
             cyw43_thread_enter();
633
             enum ble_state state_cached = state;
669
             enum ble_state state_cached = state;
638
                 break;
674
                 break;
639
             }
675
             }
640
         }
676
         }
677
+
678
+        // allow some time for characteristic discovery
679
+        watchdog_update();
680
+
681
+        cyw43_thread_enter();
641
     }
682
     }
642
 
683
 
643
     if (buff_len > BLE_MAX_VALUE_LEN) {
684
     if (buff_len > BLE_MAX_VALUE_LEN) {
652
     if (r != ERROR_CODE_SUCCESS) {
693
     if (r != ERROR_CODE_SUCCESS) {
653
         cyw43_thread_exit();
694
         cyw43_thread_exit();
654
         debug("gatt write failed %d", r);
695
         debug("gatt write failed %d", r);
655
-        return -4;
696
+        return -6;
656
     }
697
     }
657
 
698
 
658
     state = TC_W4_WRITE;
699
     state = TC_W4_WRITE;
659
     cyw43_thread_exit();
700
     cyw43_thread_exit();
660
 
701
 
661
     debug("waiting for write");
702
     debug("waiting for write");
703
+
704
+    uint32_t start_time = to_ms_since_boot(get_absolute_time());
662
     while (1) {
705
     while (1) {
663
         sleep_ms(1);
706
         sleep_ms(1);
664
 
707
 
665
-        // TODO timeout
708
+        uint32_t now = to_ms_since_boot(get_absolute_time());
709
+        if ((now - start_time) >= BLE_WRTE_TIMEOUT_MS) {
710
+            debug("timeout waiting for write");
711
+            return -7;
712
+        }
713
+#if BLE_WRTE_TIMEOUT_MS >= (WATCHDOG_PERIOD_MS / 2)
714
+        watchdog_update();
715
+#endif
666
 
716
 
667
         cyw43_thread_enter();
717
         cyw43_thread_enter();
668
         enum ble_state state_cached = state;
718
         enum ble_state state_cached = state;
676
 
726
 
677
     cyw43_thread_enter();
727
     cyw43_thread_enter();
678
 
728
 
679
-    int8_t ret = (state == TC_WRITE_COMPLETE) ? 0 : -1;
729
+    int8_t ret = (state == TC_WRITE_COMPLETE) ? 0 : -8;
680
     state = TC_READY;
730
     state = TC_READY;
681
 
731
 
682
     cyw43_thread_exit();
732
     cyw43_thread_exit();

+ 1
- 2
src/main.c View File

76
     debug("debug_disk_init");
76
     debug("debug_disk_init");
77
     debug_disk_init();
77
     debug_disk_init();
78
 
78
 
79
-    // trigger after 1000ms
80
-    watchdog_enable(1000, 1);
79
+    watchdog_enable(WATCHDOG_PERIOD_MS, 1);
81
 
80
 
82
     debug("init done");
81
     debug("init done");
83
     lcd_set_backlight(0x8000);
82
     lcd_set_backlight(0x8000);

+ 22
- 16
src/serial.c View File

52
 
52
 
53
 static bool reroute_serial_debug = false;
53
 static bool reroute_serial_debug = false;
54
 static bool tx_irq_state = false;
54
 static bool tx_irq_state = false;
55
+static bool rx_irq_state = false;
56
+#define SET_TX_IRQ(v) {                 \
57
+    tx_irq_state = v;                   \
58
+    uart_set_irq_enables(UART_ID,       \
59
+                         rx_irq_state,  \
60
+                         tx_irq_state); \
61
+}
62
+#define SET_RX_IRQ(v) {                 \
63
+    rx_irq_state = v;                   \
64
+    uart_set_irq_enables(UART_ID,       \
65
+                         rx_irq_state,  \
66
+                         tx_irq_state); \
67
+}
55
 
68
 
56
 static void serial_irq(void) {
69
 static void serial_irq(void) {
57
     // Rx - read from UART FIFO to local buffer
70
     // Rx - read from UART FIFO to local buffer
65
         if (rb_len(&tx) > 0) {
78
         if (rb_len(&tx) > 0) {
66
             uart_putc_raw(UART_ID, rb_pop(&tx));
79
             uart_putc_raw(UART_ID, rb_pop(&tx));
67
         } else {
80
         } else {
68
-            uart_set_irq_enables(UART_ID, true, false);
69
-            tx_irq_state = false;
81
+            SET_TX_IRQ(false);
70
             break;
82
             break;
71
         }
83
         }
72
     }
84
     }
86
     irq_set_exclusive_handler(UART_IRQ, serial_irq);
98
     irq_set_exclusive_handler(UART_IRQ, serial_irq);
87
     irq_set_enabled(UART_IRQ, true);
99
     irq_set_enabled(UART_IRQ, true);
88
 
100
 
89
-    uart_set_irq_enables(UART_ID, true, false);
90
-    tx_irq_state = false;
101
+    SET_RX_IRQ(true);
102
+    SET_TX_IRQ(false);
91
 }
103
 }
92
 
104
 
93
 void serial_write(const uint8_t *buf, size_t count) {
105
 void serial_write(const uint8_t *buf, size_t count) {
94
-    uart_set_irq_enables(UART_ID, true, false);
95
-    tx_irq_state = false;
106
+    SET_TX_IRQ(false);
96
 
107
 
97
     while ((rb_len(&tx) == 0) && uart_is_writable(UART_ID) && (count > 0)) {
108
     while ((rb_len(&tx) == 0) && uart_is_writable(UART_ID) && (count > 0)) {
98
         uart_putc_raw(UART_ID, *buf++);
109
         uart_putc_raw(UART_ID, *buf++);
112
         count -= space;
123
         count -= space;
113
         off += space;
124
         off += space;
114
 
125
 
115
-        uart_set_irq_enables(UART_ID, true, true);
116
-        tx_irq_state = true;
126
+        SET_TX_IRQ(true);
117
 
127
 
118
         sleep_ms(1);
128
         sleep_ms(1);
119
 
129
 
120
-        uart_set_irq_enables(UART_ID, true, false);
121
-        tx_irq_state = false;
130
+        SET_TX_IRQ(false);
122
     }
131
     }
123
-
124
 #endif // SERIAL_WRITES_BLOCK_WHEN_BUFFER_FULL
132
 #endif // SERIAL_WRITES_BLOCK_WHEN_BUFFER_FULL
125
 
133
 
126
     rb_add(&tx, buf + off, count);
134
     rb_add(&tx, buf + off, count);
127
 
135
 
128
-    uart_set_irq_enables(UART_ID, true, true);
129
-    tx_irq_state = true;
136
+    SET_TX_IRQ(true);
130
 }
137
 }
131
 
138
 
132
 void serial_set_reroute(bool reroute) {
139
 void serial_set_reroute(bool reroute) {
134
 }
141
 }
135
 
142
 
136
 void serial_run(void) {
143
 void serial_run(void) {
137
-    uart_set_irq_enables(UART_ID, false, tx_irq_state);
144
+    SET_RX_IRQ(false);
138
 
145
 
139
-    // Rx - pass local buffer to further processing
140
     if (rb_len(&rx) >= 1) {
146
     if (rb_len(&rx) >= 1) {
141
         if (rb_peek(&rx) == ENTER_BOOTLOADER_MAGIC) {
147
         if (rb_peek(&rx) == ENTER_BOOTLOADER_MAGIC) {
142
             reset_to_bootloader();
148
             reset_to_bootloader();
147
         }
153
         }
148
     }
154
     }
149
 
155
 
150
-    uart_set_irq_enables(UART_ID, true, tx_irq_state);
156
+    SET_RX_IRQ(true);
151
 }
157
 }

Loading…
Cancel
Save