Переглянути джерело

proper timeouts for ble write, now working.

Thomas Buck 6 місяці тому
джерело
коміт
c3a43c4f91
4 змінених файлів з 83 додано та 26 видалено
  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 Переглянути файл

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

+ 58
- 8
src/ble.c Переглянути файл

@@ -20,12 +20,17 @@
20 20
  */
21 21
 
22 22
 #include "pico/cyw43_arch.h"
23
+#include "hardware/watchdog.h"
23 24
 
24 25
 #include "config.h"
25 26
 #include "log.h"
26 27
 #include "util.h"
27 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 34
 #define BLE_MAX_SCAN_AGE_MS (10 * 1000)
30 35
 #define BLE_MAX_SERVICES 8
31 36
 #define BLE_MAX_CHARACTERISTICS 8
@@ -485,10 +490,18 @@ int32_t ble_read(const uint8_t *characteristic, uint8_t *buff, uint16_t buff_len
485 490
     read_len = 0;
486 491
     cyw43_thread_exit();
487 492
 
493
+    uint32_t start_time = to_ms_since_boot(get_absolute_time());
488 494
     while (1) {
489 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 506
         cyw43_thread_enter();
494 507
         enum ble_state state_cached = state;
@@ -506,7 +519,7 @@ int32_t ble_read(const uint8_t *characteristic, uint8_t *buff, uint16_t buff_len
506 519
     if (read_len > buff_len) {
507 520
         debug("buffer too short (%d < %d)", buff_len, read_len);
508 521
         cyw43_thread_exit();
509
-        return -3;
522
+        return -4;
510 523
     }
511 524
 
512 525
     memcpy(buff, data_buff, read_len);
@@ -566,10 +579,19 @@ int8_t ble_write(const uint8_t *service, const uint8_t *characteristic,
566 579
         cyw43_thread_exit();
567 580
 
568 581
         debug("waiting for service discovery");
582
+
583
+        uint32_t start_time = to_ms_since_boot(get_absolute_time());
569 584
         while (1) {
570 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 596
             cyw43_thread_enter();
575 597
             enum ble_state state_cached = state;
@@ -580,6 +602,11 @@ int8_t ble_write(const uint8_t *service, const uint8_t *characteristic,
580 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 612
     // check if characteristic has already been discovered
@@ -616,7 +643,7 @@ int8_t ble_write(const uint8_t *service, const uint8_t *characteristic,
616 643
         if (r != ERROR_CODE_SUCCESS) {
617 644
             cyw43_thread_exit();
618 645
             debug("gatt characteristic discovery failed %d", r);
619
-            return -3;
646
+            return -4;
620 647
         }
621 648
 
622 649
         state = TC_W4_CHARACTERISTIC;
@@ -624,10 +651,19 @@ int8_t ble_write(const uint8_t *service, const uint8_t *characteristic,
624 651
         cyw43_thread_exit();
625 652
 
626 653
         debug("waiting for characteristic discovery");
654
+
655
+        uint32_t start_time = to_ms_since_boot(get_absolute_time());
627 656
         while (1) {
628 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 668
             cyw43_thread_enter();
633 669
             enum ble_state state_cached = state;
@@ -638,6 +674,11 @@ int8_t ble_write(const uint8_t *service, const uint8_t *characteristic,
638 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 684
     if (buff_len > BLE_MAX_VALUE_LEN) {
@@ -652,17 +693,26 @@ int8_t ble_write(const uint8_t *service, const uint8_t *characteristic,
652 693
     if (r != ERROR_CODE_SUCCESS) {
653 694
         cyw43_thread_exit();
654 695
         debug("gatt write failed %d", r);
655
-        return -4;
696
+        return -6;
656 697
     }
657 698
 
658 699
     state = TC_W4_WRITE;
659 700
     cyw43_thread_exit();
660 701
 
661 702
     debug("waiting for write");
703
+
704
+    uint32_t start_time = to_ms_since_boot(get_absolute_time());
662 705
     while (1) {
663 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 717
         cyw43_thread_enter();
668 718
         enum ble_state state_cached = state;
@@ -676,7 +726,7 @@ int8_t ble_write(const uint8_t *service, const uint8_t *characteristic,
676 726
 
677 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 730
     state = TC_READY;
681 731
 
682 732
     cyw43_thread_exit();

+ 1
- 2
src/main.c Переглянути файл

@@ -76,8 +76,7 @@ int main(void) {
76 76
     debug("debug_disk_init");
77 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 81
     debug("init done");
83 82
     lcd_set_backlight(0x8000);

+ 22
- 16
src/serial.c Переглянути файл

@@ -52,6 +52,19 @@ static struct ring_buffer tx = RB_INIT(tx_buff, sizeof(tx_buff));
52 52
 
53 53
 static bool reroute_serial_debug = false;
54 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 69
 static void serial_irq(void) {
57 70
     // Rx - read from UART FIFO to local buffer
@@ -65,8 +78,7 @@ static void serial_irq(void) {
65 78
         if (rb_len(&tx) > 0) {
66 79
             uart_putc_raw(UART_ID, rb_pop(&tx));
67 80
         } else {
68
-            uart_set_irq_enables(UART_ID, true, false);
69
-            tx_irq_state = false;
81
+            SET_TX_IRQ(false);
70 82
             break;
71 83
         }
72 84
     }
@@ -86,13 +98,12 @@ void serial_init(void) {
86 98
     irq_set_exclusive_handler(UART_IRQ, serial_irq);
87 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 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 108
     while ((rb_len(&tx) == 0) && uart_is_writable(UART_ID) && (count > 0)) {
98 109
         uart_putc_raw(UART_ID, *buf++);
@@ -112,21 +123,17 @@ void serial_write(const uint8_t *buf, size_t count) {
112 123
         count -= space;
113 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 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 132
 #endif // SERIAL_WRITES_BLOCK_WHEN_BUFFER_FULL
125 133
 
126 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 139
 void serial_set_reroute(bool reroute) {
@@ -134,9 +141,8 @@ void serial_set_reroute(bool reroute) {
134 141
 }
135 142
 
136 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 146
     if (rb_len(&rx) >= 1) {
141 147
         if (rb_peek(&rx) == ENTER_BOOTLOADER_MAGIC) {
142 148
             reset_to_bootloader();
@@ -147,5 +153,5 @@ void serial_run(void) {
147 153
         }
148 154
     }
149 155
 
150
-    uart_set_irq_enables(UART_ID, true, tx_irq_state);
156
+    SET_RX_IRQ(true);
151 157
 }

Завантаження…
Відмінити
Зберегти