1818
1919#include "bluetooth_btstack_uart_block_ev3.h"
2020
21+ #define DEBUG 1
22+
23+ #if DEBUG
24+ #include <pbdrv/../../drv/uart/uart_debug_first_port.h>
25+ #define DEBUG_PRINT pbdrv_uart_debug_printf
26+ #else
27+ #define DEBUG_PRINT (...)
28+ #endif
29+
2130// If a read has been requested, a pointer to the buffer and its length, else
2231// null and zero.
2332static uint8_t * read_buf ;
@@ -31,9 +40,6 @@ static int write_buf_len;
3140// Should the reader and writer processes shut down?
3241static bool start_shutdown ;
3342
34- // Count of threads that have finished since start_shutdown was set.
35- static int8_t threads_shutdown_complete ;
36-
3743// Called when a block finishes sending.
3844static void (* block_sent )(void );
3945// Called when a block finishes being received.
@@ -54,6 +60,8 @@ static pbdrv_uart_dev_t *pbdrv_bluetooth_btstack_uart_block_ev3_uart_device() {
5460}
5561
5662static int pbdrv_bluetooth_btstack_uart_block_ev3_init (const btstack_uart_config_t * config ) {
63+ block_received = NULL ;
64+ block_sent = NULL ;
5765 pbdrv_uart_set_baud_rate (pbdrv_bluetooth_btstack_uart_block_ev3_uart_device (), config -> baudrate );
5866 // TODO: add parity, flow control APIs and obey them.
5967
@@ -63,7 +71,8 @@ static int pbdrv_bluetooth_btstack_uart_block_ev3_init(const btstack_uart_config
6371static pbio_error_t pbdrv_bluetooth_btstack_uart_block_ev3_do_read_process (pbio_os_state_t * state , void * context ) {
6472 pbdrv_uart_dev_t * const uart = pbdrv_bluetooth_btstack_uart_block_ev3_uart_device ();
6573
66- pbio_os_state_t read_state ;
74+ static pbio_os_state_t read_state ;
75+ static pbio_error_t err ;
6776 PBIO_OS_ASYNC_BEGIN (state );
6877
6978 while (true) {
@@ -72,23 +81,42 @@ static pbio_error_t pbdrv_bluetooth_btstack_uart_block_ev3_do_read_process(pbio_
7281 break ;
7382 }
7483
84+ // Come up for air every 500ms to check for shutdown. If we don't do this,
85+ // reads will hang permanently during a bluetooth module shutdown, which
86+ // deadlocks the shutdown process since this UART block then will not close.
87+ //
88+ // This is kinda unsatisfying though because *what if* a read is pending
89+ // and the message happens to come in just after 500ms and gets split up.
90+ // Things are going to get confusing! There should probably be a way
91+ // to cancel pending reads and writes in the UART interface.
92+ // That way we don't have to set a timeout and only interrupt a read
93+ // if we need to do so explicitly.
7594 PBIO_OS_AWAIT (state , & read_state ,
76- pbdrv_uart_read (state , uart , read_buf , read_buf_len , /*timeout=*/ 0 ));
95+ (err = pbdrv_uart_read (& read_state , uart , read_buf , read_buf_len , 500 )));
96+
97+ if (err == PBIO_ERROR_TIMEDOUT ) {
98+ // Just a timeout, go back to waiting.
99+ continue ;
100+ }
101+ if (err != PBIO_SUCCESS ) {
102+ DEBUG_PRINT ("UART read error: %d\n" , err );
103+ }
104+
77105 read_buf = NULL ;
78106 read_buf_len = 0 ;
79107 if (block_received ) {
80108 block_received ();
81109 }
82110 }
83111
84- ++ threads_shutdown_complete ;
85112 PBIO_OS_ASYNC_END (PBIO_SUCCESS );
86113}
87114
88115static pbio_error_t pbdrv_bluetooth_btstack_uart_block_ev3_do_write_process (pbio_os_state_t * state , void * context ) {
89116 pbdrv_uart_dev_t * const uart = pbdrv_bluetooth_btstack_uart_block_ev3_uart_device ();
90117
91- pbio_os_state_t write_state ;
118+ static pbio_os_state_t write_state ;
119+ static pbio_error_t err ;
92120
93121 PBIO_OS_ASYNC_BEGIN (state );
94122
@@ -99,15 +127,19 @@ static pbio_error_t pbdrv_bluetooth_btstack_uart_block_ev3_do_write_process(pbio
99127 }
100128
101129 PBIO_OS_AWAIT (state , & write_state ,
102- pbdrv_uart_write (& write_state , uart , (uint8_t * )write_buf , write_buf_len , /*timeout=*/ 0 ));
130+ (err = pbdrv_uart_write (& write_state , uart , (uint8_t * )write_buf , write_buf_len , /*timeout=*/ 0 )));
131+
132+ if (err != PBIO_SUCCESS ) {
133+ DEBUG_PRINT ("UART write error: %d\n" , err );
134+ }
135+
103136 write_buf = NULL ;
104137 write_buf_len = 0 ;
105138 if (block_sent ) {
106139 block_sent ();
107140 }
108141 }
109142
110- ++ threads_shutdown_complete ;
111143 PBIO_OS_ASYNC_END (PBIO_SUCCESS );
112144}
113145
@@ -118,22 +150,21 @@ static int pbdrv_bluetooth_btstack_uart_block_ev3_open(void) {
118150 read_buf = NULL ;
119151 read_buf_len = 0 ;
120152 start_shutdown = false;
121- threads_shutdown_complete = 0 ;
122- block_received = NULL ;
123- block_sent = NULL ;
124153
125- pbio_os_process_start ( & reader_process , pbdrv_bluetooth_btstack_uart_block_ev3_do_read_process , NULL );
154+ DEBUG_PRINT ( "Starting UART read/write processes\n" );
126155 pbio_os_process_start (& writer_process , pbdrv_bluetooth_btstack_uart_block_ev3_do_write_process , NULL );
156+ pbio_os_process_start (& reader_process , pbdrv_bluetooth_btstack_uart_block_ev3_do_read_process , NULL );
127157
128158 return 0 ;
129159}
130160
131161static int pbdrv_bluetooth_btstack_uart_block_ev3_close (void ) {
132162 start_shutdown = true;
133- while (threads_shutdown_complete < 2 ) {
134- pbio_os_run_processes_and_wait_for_event ();
163+ DEBUG_PRINT ("Waiting for UART read/write processes to shut down...\n" );
164+ while (reader_process .err != PBIO_SUCCESS || writer_process .err != PBIO_SUCCESS ) {
165+ pbio_os_request_poll ();
166+ pbio_os_run_processes_once ();
135167 }
136-
137168 return 0 ;
138169}
139170
0 commit comments