mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-03-25 16:43:28 +00:00
windows: repeat UART read/write operation if not all bytes have been read or written
This commit is contained in:
parent
a1a856590c
commit
5b81efe293
@ -79,76 +79,9 @@ static HANDLE serial_port_handle;
|
|||||||
static OVERLAPPED overlapped_read;
|
static OVERLAPPED overlapped_read;
|
||||||
static OVERLAPPED overlapped_write;
|
static OVERLAPPED overlapped_write;
|
||||||
|
|
||||||
|
// -- engine that retries send/receive if not all bytes have been transferred
|
||||||
|
|
||||||
static int btstack_uart_windows_init(const btstack_uart_config_t * config){
|
static void btstack_uart_windows_send_engine(void){
|
||||||
uart_config = config;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void btstack_uart_windows_process_write(btstack_data_source_t *ds, btstack_data_source_callback_type_t callback_type) {
|
|
||||||
|
|
||||||
btstack_run_loop_disable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_WRITE);
|
|
||||||
|
|
||||||
DWORD bytes_written;
|
|
||||||
BOOL ok = GetOverlappedResult(serial_port_handle, &overlapped_write, &bytes_written, FALSE);
|
|
||||||
if(!ok){
|
|
||||||
DWORD err = GetLastError();
|
|
||||||
if (err == ERROR_IO_INCOMPLETE){
|
|
||||||
// IO_INCOMPLETE -> wait for completed
|
|
||||||
btstack_run_loop_enable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_WRITE);
|
|
||||||
} else {
|
|
||||||
log_error("btstack_uart_windows_process_write: error writing");
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// assert all bytes written
|
|
||||||
if (bytes_written != write_bytes_len){
|
|
||||||
log_error("btstack_uart_windows_process_write: requested write %u but %u were written", (int) write_bytes_len, (int) bytes_written);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// notify done
|
|
||||||
if (block_sent){
|
|
||||||
block_sent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void btstack_uart_windows_process_read(btstack_data_source_t *ds, btstack_data_source_callback_type_t callback_type) {
|
|
||||||
|
|
||||||
btstack_run_loop_disable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_READ);
|
|
||||||
|
|
||||||
DWORD bytes_read;
|
|
||||||
BOOL ok = GetOverlappedResult(serial_port_handle, &overlapped_read, &bytes_read, FALSE);
|
|
||||||
if(!ok){
|
|
||||||
DWORD err = GetLastError();
|
|
||||||
if (err == ERROR_IO_INCOMPLETE){
|
|
||||||
// IO_INCOMPLETE -> wait for completed
|
|
||||||
btstack_run_loop_enable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_READ);
|
|
||||||
} else {
|
|
||||||
log_error("btstack_uart_windows_process_write: error writing");
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// assert all bytes read
|
|
||||||
if (bytes_read != read_bytes_len){
|
|
||||||
log_error("btstack_uart_windows_process_read: requested read %u but %u were read", (int) read_bytes_len, (int) bytes_read);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// notify done
|
|
||||||
if (block_received){
|
|
||||||
block_received();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void btstack_uart_windows_send_block(const uint8_t *data, uint16_t size){
|
|
||||||
|
|
||||||
// setup async write
|
|
||||||
write_bytes_data = data;
|
|
||||||
write_bytes_len = size;
|
|
||||||
|
|
||||||
// start write
|
// start write
|
||||||
DWORD bytes_written;
|
DWORD bytes_written;
|
||||||
BOOL ok = WriteFile(serial_port_handle, // handle
|
BOOL ok = WriteFile(serial_port_handle, // handle
|
||||||
@ -158,7 +91,6 @@ static void btstack_uart_windows_send_block(const uint8_t *data, uint16_t size){
|
|||||||
&overlapped_write); // overlapped structure
|
&overlapped_write); // overlapped structure
|
||||||
|
|
||||||
if (ok){
|
if (ok){
|
||||||
|
|
||||||
// assert all bytes written
|
// assert all bytes written
|
||||||
if (bytes_written != write_bytes_len){
|
if (bytes_written != write_bytes_len){
|
||||||
log_error("btstack_uart_windows_send_block: requested write %u but %u were written", (int) write_bytes_len, (int) bytes_written);
|
log_error("btstack_uart_windows_send_block: requested write %u but %u were written", (int) write_bytes_len, (int) bytes_written);
|
||||||
@ -186,13 +118,7 @@ static void btstack_uart_windows_send_block(const uint8_t *data, uint16_t size){
|
|||||||
btstack_run_loop_enable_data_source_callbacks(&transport_data_source_write, DATA_SOURCE_CALLBACK_WRITE);
|
btstack_run_loop_enable_data_source_callbacks(&transport_data_source_write, DATA_SOURCE_CALLBACK_WRITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void btstack_uart_windows_receive_block(uint8_t *buffer, uint16_t len){
|
static void btstack_uart_windows_receive_engine(void){
|
||||||
|
|
||||||
// setup async read
|
|
||||||
read_bytes_data = buffer;
|
|
||||||
read_bytes_len = len;
|
|
||||||
|
|
||||||
// go
|
|
||||||
DWORD bytes_read;
|
DWORD bytes_read;
|
||||||
BOOL ok = ReadFile(serial_port_handle, // handle
|
BOOL ok = ReadFile(serial_port_handle, // handle
|
||||||
read_bytes_data, // (LPCSTR) 8-bit data
|
read_bytes_data, // (LPCSTR) 8-bit data
|
||||||
@ -201,7 +127,6 @@ static void btstack_uart_windows_receive_block(uint8_t *buffer, uint16_t len){
|
|||||||
&overlapped_read); // overlapped structure
|
&overlapped_read); // overlapped structure
|
||||||
|
|
||||||
if (ok){
|
if (ok){
|
||||||
|
|
||||||
// assert all bytes read
|
// assert all bytes read
|
||||||
if (bytes_read != read_bytes_len){
|
if (bytes_read != read_bytes_len){
|
||||||
log_error("btstack_uart_windows_receive_block: requested read %u but %u were read", (int) read_bytes_len, (int) bytes_read);
|
log_error("btstack_uart_windows_receive_block: requested read %u but %u were read", (int) read_bytes_len, (int) bytes_read);
|
||||||
@ -221,7 +146,7 @@ static void btstack_uart_windows_receive_block(uint8_t *buffer, uint16_t len){
|
|||||||
|
|
||||||
DWORD err = GetLastError();
|
DWORD err = GetLastError();
|
||||||
if (err != ERROR_IO_PENDING){
|
if (err != ERROR_IO_PENDING){
|
||||||
log_error("btstack_uart_windows_receive_block: error reading");
|
log_error("error reading");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,6 +154,100 @@ static void btstack_uart_windows_receive_block(uint8_t *buffer, uint16_t len){
|
|||||||
btstack_run_loop_enable_data_source_callbacks(&transport_data_source_read, DATA_SOURCE_CALLBACK_READ);
|
btstack_run_loop_enable_data_source_callbacks(&transport_data_source_read, DATA_SOURCE_CALLBACK_READ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// -- overlapped IO handlers for read & write
|
||||||
|
|
||||||
|
static void btstack_uart_windows_process_write(btstack_data_source_t *ds, btstack_data_source_callback_type_t callback_type) {
|
||||||
|
|
||||||
|
btstack_run_loop_disable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_WRITE);
|
||||||
|
|
||||||
|
DWORD bytes_written;
|
||||||
|
BOOL ok = GetOverlappedResult(serial_port_handle, &overlapped_write, &bytes_written, FALSE);
|
||||||
|
if(!ok){
|
||||||
|
DWORD err = GetLastError();
|
||||||
|
if (err == ERROR_IO_INCOMPLETE){
|
||||||
|
// IO_INCOMPLETE -> wait for completed
|
||||||
|
btstack_run_loop_enable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_WRITE);
|
||||||
|
} else {
|
||||||
|
log_error("write: error writing");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// assert all bytes written
|
||||||
|
if (bytes_written != write_bytes_len){
|
||||||
|
log_debug("write: requested to write %u but %u were written, try again", (int) write_bytes_len, (int) bytes_written);
|
||||||
|
btstack_uart_windows_send_engine();
|
||||||
|
write_bytes_data += bytes_written;
|
||||||
|
write_bytes_len -= bytes_written;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// notify done
|
||||||
|
if (block_sent){
|
||||||
|
block_sent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void btstack_uart_windows_process_read(btstack_data_source_t *ds, btstack_data_source_callback_type_t callback_type) {
|
||||||
|
|
||||||
|
btstack_run_loop_disable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_READ);
|
||||||
|
|
||||||
|
DWORD bytes_read;
|
||||||
|
BOOL ok = GetOverlappedResult(serial_port_handle, &overlapped_read, &bytes_read, FALSE);
|
||||||
|
if(!ok){
|
||||||
|
DWORD err = GetLastError();
|
||||||
|
if (err == ERROR_IO_INCOMPLETE){
|
||||||
|
// IO_INCOMPLETE -> wait for completed
|
||||||
|
btstack_run_loop_enable_data_source_callbacks(ds, DATA_SOURCE_CALLBACK_READ);
|
||||||
|
} else {
|
||||||
|
log_error("error reading");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// assert all bytes read
|
||||||
|
if (bytes_read != read_bytes_len){
|
||||||
|
log_debug("read: requested read %u but %u were read, try again", (int) read_bytes_len, (int) bytes_read);
|
||||||
|
read_bytes_data += bytes_read;
|
||||||
|
read_bytes_len -= bytes_read;
|
||||||
|
btstack_uart_windows_receive_engine();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// notify done
|
||||||
|
if (block_received){
|
||||||
|
block_received();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- API implementation
|
||||||
|
|
||||||
|
static int btstack_uart_windows_init(const btstack_uart_config_t * config){
|
||||||
|
uart_config = config;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void btstack_uart_windows_send_block(const uint8_t *data, uint16_t size){
|
||||||
|
// setup async write
|
||||||
|
write_bytes_data = data;
|
||||||
|
write_bytes_len = size;
|
||||||
|
|
||||||
|
// go
|
||||||
|
btstack_uart_windows_send_engine();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void btstack_uart_windows_receive_block(uint8_t *buffer, uint16_t len){
|
||||||
|
// setup async read
|
||||||
|
read_bytes_data = buffer;
|
||||||
|
read_bytes_len = len;
|
||||||
|
|
||||||
|
// go
|
||||||
|
btstack_uart_windows_receive_engine();
|
||||||
|
}
|
||||||
|
|
||||||
static void btstack_uart_windows_set_baudrate_option(DCB * serial_params, uint32_t baudrate){
|
static void btstack_uart_windows_set_baudrate_option(DCB * serial_params, uint32_t baudrate){
|
||||||
serial_params->BaudRate = baudrate;
|
serial_params->BaudRate = baudrate;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user