1e25b4a2fSMatthias Ringwald /* 2e25b4a2fSMatthias Ringwald * Copyright (C) 2015 BlueKitchen GmbH 3e25b4a2fSMatthias Ringwald * 4e25b4a2fSMatthias Ringwald * Redistribution and use in source and binary forms, with or without 5e25b4a2fSMatthias Ringwald * modification, are permitted provided that the following conditions 6e25b4a2fSMatthias Ringwald * are met: 7e25b4a2fSMatthias Ringwald * 8e25b4a2fSMatthias Ringwald * 1. Redistributions of source code must retain the above copyright 9e25b4a2fSMatthias Ringwald * notice, this list of conditions and the following disclaimer. 10e25b4a2fSMatthias Ringwald * 2. Redistributions in binary form must reproduce the above copyright 11e25b4a2fSMatthias Ringwald * notice, this list of conditions and the following disclaimer in the 12e25b4a2fSMatthias Ringwald * documentation and/or other materials provided with the distribution. 13e25b4a2fSMatthias Ringwald * 3. Neither the name of the copyright holders nor the names of 14e25b4a2fSMatthias Ringwald * contributors may be used to endorse or promote products derived 15e25b4a2fSMatthias Ringwald * from this software without specific prior written permission. 16e25b4a2fSMatthias Ringwald * 4. Any redistribution, use, or modification is done solely for 17e25b4a2fSMatthias Ringwald * personal benefit and not for any commercial purpose or for 18e25b4a2fSMatthias Ringwald * monetary gain. 19e25b4a2fSMatthias Ringwald * 20e25b4a2fSMatthias Ringwald * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 21e25b4a2fSMatthias Ringwald * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22e25b4a2fSMatthias Ringwald * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23e25b4a2fSMatthias Ringwald * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS 24e25b4a2fSMatthias Ringwald * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25e25b4a2fSMatthias Ringwald * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26e25b4a2fSMatthias Ringwald * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 27e25b4a2fSMatthias Ringwald * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28e25b4a2fSMatthias Ringwald * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29e25b4a2fSMatthias Ringwald * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 30e25b4a2fSMatthias Ringwald * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31e25b4a2fSMatthias Ringwald * SUCH DAMAGE. 32e25b4a2fSMatthias Ringwald * 33e25b4a2fSMatthias Ringwald * Please inquire about commercial licensing options at 34e25b4a2fSMatthias Ringwald * [email protected] 35e25b4a2fSMatthias Ringwald * 36e25b4a2fSMatthias Ringwald */ 37e25b4a2fSMatthias Ringwald 38e25b4a2fSMatthias Ringwald /* 39e25b4a2fSMatthias Ringwald * hci_h4_transport_wiced.c 40e25b4a2fSMatthias Ringwald * 41e25b4a2fSMatthias Ringwald * HCI Transport API implementation for basic H4 protocol for use with btstack_run_loop_wiced.c 42e25b4a2fSMatthias Ringwald */ 43e25b4a2fSMatthias Ringwald 44e501bae0SMatthias Ringwald #define BTSTACK_FILE__ "btstack_uart_block_wiced.c" 45e25b4a2fSMatthias Ringwald 46e25b4a2fSMatthias Ringwald #include "btstack_config.h" 47e25b4a2fSMatthias Ringwald #include "btstack_debug.h" 48369e4864SMatthias Ringwald #include "btstack_run_loop_wiced.h" 49369e4864SMatthias Ringwald #include "btstack_uart_block.h" 50369e4864SMatthias Ringwald 51e25b4a2fSMatthias Ringwald #include "hci.h" 52e25b4a2fSMatthias Ringwald #include "hci_transport.h" 53e25b4a2fSMatthias Ringwald #include "platform_bluetooth.h" 54e25b4a2fSMatthias Ringwald 55e25b4a2fSMatthias Ringwald #include "wiced.h" 56e25b4a2fSMatthias Ringwald 57e25b4a2fSMatthias Ringwald #include <stdio.h> 58e25b4a2fSMatthias Ringwald #include <string.h> 59e25b4a2fSMatthias Ringwald 60e25b4a2fSMatthias Ringwald // priority higher than WIFI to make sure RTS is set 61e25b4a2fSMatthias Ringwald #define WICED_BT_UART_THREAD_PRIORITY (WICED_NETWORK_WORKER_PRIORITY - 2) 62e25b4a2fSMatthias Ringwald #define WICED_BT_UART_THREAD_STACK_SIZE 300 63e25b4a2fSMatthias Ringwald 64e25b4a2fSMatthias Ringwald // assert pre-buffer for packet type is available 65e25b4a2fSMatthias Ringwald #if !defined(HCI_OUTGOING_PRE_BUFFER_SIZE) || (HCI_OUTGOING_PRE_BUFFER_SIZE == 0) 66e25b4a2fSMatthias Ringwald #error HCI_OUTGOING_PRE_BUFFER_SIZE not defined. Please update hci.h 67e25b4a2fSMatthias Ringwald #endif 68e25b4a2fSMatthias Ringwald 69e25b4a2fSMatthias Ringwald // Default of 512 bytes should be fine. Only needed with BTSTACK_FLOW_CONTROL_UART 70e25b4a2fSMatthias Ringwald #ifndef RX_RING_BUFFER_SIZE 71e25b4a2fSMatthias Ringwald #define RX_RING_BUFFER_SIZE 512 72e25b4a2fSMatthias Ringwald #endif 73e25b4a2fSMatthias Ringwald 74e25b4a2fSMatthias Ringwald // Use BTSTACK_FLOW_CONTROL_MANUAL is used when Bluetooth RTS/CTS are not connected to UART RTS/CTS pins 75e25b4a2fSMatthias Ringwald // E.g. on RedBear Duo - WICED_BT_UART_MANUAL_CTS_RTS is defined 76e25b4a2fSMatthias Ringwald 77e25b4a2fSMatthias Ringwald static enum { 78e25b4a2fSMatthias Ringwald BTSTACK_FLOW_CONTROL_OFF, 79e25b4a2fSMatthias Ringwald BTSTACK_FLOW_CONTROL_UART, 80e25b4a2fSMatthias Ringwald BTSTACK_FLOW_CONTROL_MANUAL, 81e25b4a2fSMatthias Ringwald } btstack_flow_control_mode; 82e25b4a2fSMatthias Ringwald 83e25b4a2fSMatthias Ringwald static wiced_result_t btstack_uart_block_wiced_rx_worker_receive_block(void * arg); 84e25b4a2fSMatthias Ringwald 85e25b4a2fSMatthias Ringwald static wiced_worker_thread_t tx_worker_thread; 86e25b4a2fSMatthias Ringwald static const uint8_t * tx_worker_data_buffer; 87e25b4a2fSMatthias Ringwald static uint16_t tx_worker_data_size; 88e25b4a2fSMatthias Ringwald 89e25b4a2fSMatthias Ringwald static wiced_worker_thread_t rx_worker_thread; 90e25b4a2fSMatthias Ringwald static uint8_t * rx_worker_read_buffer; 91e25b4a2fSMatthias Ringwald static uint16_t rx_worker_read_size; 92e25b4a2fSMatthias Ringwald 93e25b4a2fSMatthias Ringwald static wiced_ring_buffer_t rx_ring_buffer; 94e25b4a2fSMatthias Ringwald static uint8_t rx_data[RX_RING_BUFFER_SIZE]; 95e25b4a2fSMatthias Ringwald 96e25b4a2fSMatthias Ringwald // uart config 97e25b4a2fSMatthias Ringwald static const btstack_uart_config_t * uart_config; 98e25b4a2fSMatthias Ringwald 99e25b4a2fSMatthias Ringwald // callbacks 100e25b4a2fSMatthias Ringwald static void (*block_sent)(void); 101e25b4a2fSMatthias Ringwald static void (*block_received)(void); 102e25b4a2fSMatthias Ringwald 103e25b4a2fSMatthias Ringwald // executed on main run loop 104e25b4a2fSMatthias Ringwald static wiced_result_t btstack_uart_block_wiced_main_notify_block_send(void *arg){ 105e25b4a2fSMatthias Ringwald if (block_sent){ 106e25b4a2fSMatthias Ringwald block_sent(); 107e25b4a2fSMatthias Ringwald } 108e25b4a2fSMatthias Ringwald return WICED_SUCCESS; 109e25b4a2fSMatthias Ringwald } 110e25b4a2fSMatthias Ringwald 111e25b4a2fSMatthias Ringwald // executed on main run loop 112e25b4a2fSMatthias Ringwald static wiced_result_t btstack_uart_block_wiced_main_notify_block_read(void *arg){ 113e25b4a2fSMatthias Ringwald if (block_received){ 114e25b4a2fSMatthias Ringwald block_received(); 115e25b4a2fSMatthias Ringwald } 116e25b4a2fSMatthias Ringwald return WICED_SUCCESS; 117e25b4a2fSMatthias Ringwald } 118e25b4a2fSMatthias Ringwald 119e25b4a2fSMatthias Ringwald // executed on tx worker thread 120*739fcdb2SMatthias Ringwald static btstack_context_callback_registration_t block_send_callback_registration; 121e25b4a2fSMatthias Ringwald static wiced_result_t btstack_uart_block_wiced_tx_worker_send_block(void * arg){ 122e25b4a2fSMatthias Ringwald // wait for CTS to become low in manual flow control mode 123e25b4a2fSMatthias Ringwald if (btstack_flow_control_mode == BTSTACK_FLOW_CONTROL_MANUAL && wiced_bt_uart_pins[WICED_BT_PIN_UART_CTS]){ 124e25b4a2fSMatthias Ringwald while (platform_gpio_input_get(wiced_bt_uart_pins[WICED_BT_PIN_UART_CTS]) == WICED_TRUE){ 125e25b4a2fSMatthias Ringwald wiced_rtos_delay_milliseconds(10); 126e25b4a2fSMatthias Ringwald } 127e25b4a2fSMatthias Ringwald } 128e25b4a2fSMatthias Ringwald 129e25b4a2fSMatthias Ringwald // blocking send 130e25b4a2fSMatthias Ringwald platform_uart_transmit_bytes(wiced_bt_uart_driver, tx_worker_data_buffer, tx_worker_data_size); 131e25b4a2fSMatthias Ringwald 132e25b4a2fSMatthias Ringwald // let transport know 133*739fcdb2SMatthias Ringwald block_send_callback_registration.callback = &btstack_uart_block_wiced_main_notify_block_send; 134*739fcdb2SMatthias Ringwald btstack_run_loop_execute_code_on_main_thread(&block_send_callback_registration); 135e25b4a2fSMatthias Ringwald return WICED_SUCCESS; 136e25b4a2fSMatthias Ringwald } 137e25b4a2fSMatthias Ringwald 138e25b4a2fSMatthias Ringwald // executed on rx worker thread 139*739fcdb2SMatthias Ringwald static btstack_context_callback_registration_t block_received_callback_registration; 140e25b4a2fSMatthias Ringwald static wiced_result_t btstack_uart_block_wiced_rx_worker_receive_block(void * arg){ 141e25b4a2fSMatthias Ringwald 142e25b4a2fSMatthias Ringwald if (btstack_flow_control_mode == BTSTACK_FLOW_CONTROL_MANUAL && wiced_bt_uart_pins[WICED_BT_PIN_UART_CTS]){ 143e25b4a2fSMatthias Ringwald platform_gpio_output_low(wiced_bt_uart_pins[WICED_BT_PIN_UART_RTS]); 144e25b4a2fSMatthias Ringwald } 145e25b4a2fSMatthias Ringwald 146e25b4a2fSMatthias Ringwald #ifdef WICED_UART_READ_DOES_NOT_RETURN_BYTES_READ 147e25b4a2fSMatthias Ringwald // older API passes in number of bytes to read (checked in 3.3.1 and 3.4.0) 148e25b4a2fSMatthias Ringwald platform_uart_receive_bytes(wiced_bt_uart_driver, rx_worker_read_buffer, rx_worker_read_size, WICED_NEVER_TIMEOUT); 149e25b4a2fSMatthias Ringwald #else 150e25b4a2fSMatthias Ringwald // newer API uses pointer to return number of read bytes 151e25b4a2fSMatthias Ringwald uint32_t bytes = rx_worker_read_size; 152e25b4a2fSMatthias Ringwald platform_uart_receive_bytes(wiced_bt_uart_driver, rx_worker_read_buffer, &bytes, WICED_NEVER_TIMEOUT); 153e25b4a2fSMatthias Ringwald // assumption: bytes = bytes_to_read as timeout is never 154e25b4a2fSMatthias Ringwald #endif 155e25b4a2fSMatthias Ringwald 156e25b4a2fSMatthias Ringwald if (btstack_flow_control_mode == BTSTACK_FLOW_CONTROL_MANUAL && wiced_bt_uart_pins[WICED_BT_PIN_UART_CTS]){ 157e25b4a2fSMatthias Ringwald platform_gpio_output_high(wiced_bt_uart_pins[WICED_BT_PIN_UART_RTS]); 158e25b4a2fSMatthias Ringwald } 159e25b4a2fSMatthias Ringwald 160e25b4a2fSMatthias Ringwald // let transport know 161*739fcdb2SMatthias Ringwald block_received_callback_registration.callback = &btstack_uart_block_wiced_main_notify_block_read; 162*739fcdb2SMatthias Ringwald btstack_run_loop_execute_code_on_main_thread(&block_received_callback_registration); 163e25b4a2fSMatthias Ringwald return WICED_SUCCESS; 164e25b4a2fSMatthias Ringwald } 165e25b4a2fSMatthias Ringwald 166e25b4a2fSMatthias Ringwald static int btstack_uart_block_wiced_init(const btstack_uart_config_t * config){ 167e25b4a2fSMatthias Ringwald uart_config = config; 168e25b4a2fSMatthias Ringwald 169e25b4a2fSMatthias Ringwald // determine flow control mode based on hardware config and uart config 170e25b4a2fSMatthias Ringwald if (uart_config->flowcontrol){ 171e25b4a2fSMatthias Ringwald #ifdef WICED_BT_UART_MANUAL_CTS_RTS 172e25b4a2fSMatthias Ringwald btstack_flow_control_mode = BTSTACK_FLOW_CONTROL_MANUAL; 173e25b4a2fSMatthias Ringwald #else 174e25b4a2fSMatthias Ringwald btstack_flow_control_mode = BTSTACK_FLOW_CONTROL_UART; 175e25b4a2fSMatthias Ringwald #endif 176e25b4a2fSMatthias Ringwald } else { 177e25b4a2fSMatthias Ringwald btstack_flow_control_mode = BTSTACK_FLOW_CONTROL_OFF; 178e25b4a2fSMatthias Ringwald } 179e25b4a2fSMatthias Ringwald return 0; 180e25b4a2fSMatthias Ringwald } 181e25b4a2fSMatthias Ringwald 182e25b4a2fSMatthias Ringwald static int btstack_uart_block_wiced_open(void){ 183e25b4a2fSMatthias Ringwald 184e25b4a2fSMatthias Ringwald // UART config 185e25b4a2fSMatthias Ringwald wiced_uart_config_t wiced_uart_config = 186e25b4a2fSMatthias Ringwald { 187e25b4a2fSMatthias Ringwald .baud_rate = uart_config->baudrate, 188e25b4a2fSMatthias Ringwald .data_width = DATA_WIDTH_8BIT, 189e25b4a2fSMatthias Ringwald .parity = NO_PARITY, 190e25b4a2fSMatthias Ringwald .stop_bits = STOP_BITS_1, 191e25b4a2fSMatthias Ringwald }; 192e25b4a2fSMatthias Ringwald 193e25b4a2fSMatthias Ringwald if (btstack_flow_control_mode == BTSTACK_FLOW_CONTROL_UART){ 194e25b4a2fSMatthias Ringwald wiced_uart_config.flow_control = FLOW_CONTROL_CTS_RTS; 195e25b4a2fSMatthias Ringwald } else { 196e25b4a2fSMatthias Ringwald wiced_uart_config.flow_control = FLOW_CONTROL_DISABLED; 197e25b4a2fSMatthias Ringwald } 198e25b4a2fSMatthias Ringwald wiced_ring_buffer_t * ring_buffer = NULL; 199e25b4a2fSMatthias Ringwald 200e25b4a2fSMatthias Ringwald // configure HOST and DEVICE WAKE PINs 201e25b4a2fSMatthias Ringwald platform_gpio_init(wiced_bt_control_pins[WICED_BT_PIN_HOST_WAKE], INPUT_HIGH_IMPEDANCE); 202e25b4a2fSMatthias Ringwald platform_gpio_init(wiced_bt_control_pins[WICED_BT_PIN_DEVICE_WAKE], OUTPUT_PUSH_PULL); 203e25b4a2fSMatthias Ringwald platform_gpio_output_low(wiced_bt_control_pins[WICED_BT_PIN_DEVICE_WAKE]); 204e25b4a2fSMatthias Ringwald 205e25b4a2fSMatthias Ringwald /* Configure Reg Enable pin to output. Set to HIGH */ 206e25b4a2fSMatthias Ringwald if (wiced_bt_control_pins[ WICED_BT_PIN_POWER ]){ 207e25b4a2fSMatthias Ringwald platform_gpio_init( wiced_bt_control_pins[ WICED_BT_PIN_POWER ], OUTPUT_OPEN_DRAIN_PULL_UP ); 208e25b4a2fSMatthias Ringwald platform_gpio_output_high( wiced_bt_control_pins[ WICED_BT_PIN_POWER ] ); 209e25b4a2fSMatthias Ringwald } 210e25b4a2fSMatthias Ringwald 211e25b4a2fSMatthias Ringwald wiced_rtos_delay_milliseconds( 100 ); 212e25b4a2fSMatthias Ringwald 213e25b4a2fSMatthias Ringwald // Configure RTS 214e25b4a2fSMatthias Ringwald if (wiced_bt_uart_pins[WICED_BT_PIN_UART_RTS]){ 215e25b4a2fSMatthias Ringwald switch (btstack_flow_control_mode){ 216e25b4a2fSMatthias Ringwald case BTSTACK_FLOW_CONTROL_OFF: 217e25b4a2fSMatthias Ringwald // configure RTS pin as output and set to low - always on 218e25b4a2fSMatthias Ringwald platform_gpio_init(wiced_bt_uart_pins[WICED_BT_PIN_UART_RTS], OUTPUT_PUSH_PULL); 219e25b4a2fSMatthias Ringwald platform_gpio_output_low(wiced_bt_uart_pins[WICED_BT_PIN_UART_RTS]); 220e25b4a2fSMatthias Ringwald break; 221e25b4a2fSMatthias Ringwald case BTSTACK_FLOW_CONTROL_UART: 222e25b4a2fSMatthias Ringwald // configuration done by platform_uart_init 223e25b4a2fSMatthias Ringwald break; 224e25b4a2fSMatthias Ringwald case BTSTACK_FLOW_CONTROL_MANUAL: 225e25b4a2fSMatthias Ringwald // configure RTS pin as output and set to high - controlled by btstack_uart_block_wiced_rx_worker_receive_block 226e25b4a2fSMatthias Ringwald platform_gpio_init(wiced_bt_uart_pins[WICED_BT_PIN_UART_RTS], OUTPUT_PUSH_PULL); 227e25b4a2fSMatthias Ringwald platform_gpio_output_high(wiced_bt_uart_pins[WICED_BT_PIN_UART_RTS]); 228e25b4a2fSMatthias Ringwald break; 229e25b4a2fSMatthias Ringwald } 230e25b4a2fSMatthias Ringwald } 231e25b4a2fSMatthias Ringwald 232e25b4a2fSMatthias Ringwald // Configure CTS 233e25b4a2fSMatthias Ringwald if (wiced_bt_uart_pins[WICED_BT_PIN_UART_CTS]){ 234e25b4a2fSMatthias Ringwald switch (btstack_flow_control_mode){ 235e25b4a2fSMatthias Ringwald case BTSTACK_FLOW_CONTROL_OFF: 236e25b4a2fSMatthias Ringwald // don't care 237e25b4a2fSMatthias Ringwald break; 238e25b4a2fSMatthias Ringwald case BTSTACK_FLOW_CONTROL_UART: 239e25b4a2fSMatthias Ringwald // configuration done by platform_uart_init 240e25b4a2fSMatthias Ringwald break; 241e25b4a2fSMatthias Ringwald case BTSTACK_FLOW_CONTROL_MANUAL: 242e25b4a2fSMatthias Ringwald // configure CTS to input, pull-up 243e25b4a2fSMatthias Ringwald platform_gpio_init(wiced_bt_uart_pins[WICED_BT_PIN_UART_CTS], INPUT_PULL_UP); 244e25b4a2fSMatthias Ringwald break; 245e25b4a2fSMatthias Ringwald } 246e25b4a2fSMatthias Ringwald } 247e25b4a2fSMatthias Ringwald 248e25b4a2fSMatthias Ringwald // use ring buffer to allow to receive RX_RING_BUFFER_SIZE/2 addition bytes - not needed with hardware UART 249e25b4a2fSMatthias Ringwald if (btstack_flow_control_mode != BTSTACK_FLOW_CONTROL_UART){ 250e25b4a2fSMatthias Ringwald ring_buffer_init((wiced_ring_buffer_t *) &rx_ring_buffer, (uint8_t*) rx_data, sizeof( rx_data ) ); 251e25b4a2fSMatthias Ringwald ring_buffer = (wiced_ring_buffer_t *) &rx_ring_buffer; 252e25b4a2fSMatthias Ringwald } 253e25b4a2fSMatthias Ringwald 254e25b4a2fSMatthias Ringwald platform_uart_init( wiced_bt_uart_driver, wiced_bt_uart_peripheral, &wiced_uart_config, ring_buffer ); 255e25b4a2fSMatthias Ringwald 256e25b4a2fSMatthias Ringwald 257e25b4a2fSMatthias Ringwald // Reset Bluetooth via RESET line. Fallback to toggling POWER otherwise 258e25b4a2fSMatthias Ringwald if ( wiced_bt_control_pins[ WICED_BT_PIN_RESET ]){ 259e25b4a2fSMatthias Ringwald platform_gpio_init( wiced_bt_control_pins[ WICED_BT_PIN_RESET ], OUTPUT_PUSH_PULL ); 260e25b4a2fSMatthias Ringwald platform_gpio_output_high( wiced_bt_control_pins[ WICED_BT_PIN_RESET ] ); 261e25b4a2fSMatthias Ringwald 262e25b4a2fSMatthias Ringwald platform_gpio_output_low( wiced_bt_control_pins[ WICED_BT_PIN_RESET ] ); 263e25b4a2fSMatthias Ringwald wiced_rtos_delay_milliseconds( 100 ); 264e25b4a2fSMatthias Ringwald platform_gpio_output_high( wiced_bt_control_pins[ WICED_BT_PIN_RESET ] ); 265e25b4a2fSMatthias Ringwald } 266e25b4a2fSMatthias Ringwald else if ( wiced_bt_control_pins[ WICED_BT_PIN_POWER ]){ 267e25b4a2fSMatthias Ringwald platform_gpio_output_low( wiced_bt_control_pins[ WICED_BT_PIN_POWER ] ); 268e25b4a2fSMatthias Ringwald wiced_rtos_delay_milliseconds( 100 ); 269e25b4a2fSMatthias Ringwald platform_gpio_output_high( wiced_bt_control_pins[ WICED_BT_PIN_POWER ] ); 270e25b4a2fSMatthias Ringwald } 271e25b4a2fSMatthias Ringwald 272e25b4a2fSMatthias Ringwald // wait for Bluetooth to start up 273e25b4a2fSMatthias Ringwald wiced_rtos_delay_milliseconds( 500 ); 274e25b4a2fSMatthias Ringwald 275e25b4a2fSMatthias Ringwald // create worker threads for rx/tx. only single request is posted to their queues 276e25b4a2fSMatthias Ringwald wiced_rtos_create_worker_thread(&tx_worker_thread, WICED_BT_UART_THREAD_PRIORITY, WICED_BT_UART_THREAD_STACK_SIZE, 1); 277e25b4a2fSMatthias Ringwald wiced_rtos_create_worker_thread(&rx_worker_thread, WICED_BT_UART_THREAD_PRIORITY, WICED_BT_UART_THREAD_STACK_SIZE, 1); 278e25b4a2fSMatthias Ringwald 279e25b4a2fSMatthias Ringwald // tx is ready 280e25b4a2fSMatthias Ringwald tx_worker_data_size = 0; 281e25b4a2fSMatthias Ringwald return 0; 282e25b4a2fSMatthias Ringwald } 283e25b4a2fSMatthias Ringwald 284e25b4a2fSMatthias Ringwald static int btstack_uart_block_wiced_close(void){ 285e25b4a2fSMatthias Ringwald // not implemented 286e25b4a2fSMatthias Ringwald return 0; 287e25b4a2fSMatthias Ringwald } 288e25b4a2fSMatthias Ringwald 289e25b4a2fSMatthias Ringwald static void btstack_uart_block_wiced_set_block_received( void (*block_handler)(void)){ 290e25b4a2fSMatthias Ringwald block_received = block_handler; 291e25b4a2fSMatthias Ringwald } 292e25b4a2fSMatthias Ringwald 293e25b4a2fSMatthias Ringwald static void btstack_uart_block_wiced_set_block_sent( void (*block_handler)(void)){ 294e25b4a2fSMatthias Ringwald block_sent = block_handler; 295e25b4a2fSMatthias Ringwald } 296e25b4a2fSMatthias Ringwald 297e25b4a2fSMatthias Ringwald static int btstack_uart_block_wiced_set_baudrate(uint32_t baudrate){ 298e25b4a2fSMatthias Ringwald 2997e4bff82SMatthias Ringwald #if defined(_STM32F205RGT6_) || defined(STM32F40_41xxx) || defined(STM32F411xE) || (STM32F412xG) 300e25b4a2fSMatthias Ringwald 301e25b4a2fSMatthias Ringwald // directly use STM peripheral functions to change baud rate dynamically 302e25b4a2fSMatthias Ringwald 303e25b4a2fSMatthias Ringwald // set TX to high 304e25b4a2fSMatthias Ringwald log_info("set baud %u", (int) baudrate); 305e25b4a2fSMatthias Ringwald const platform_gpio_t* gpio = wiced_bt_uart_pins[WICED_BT_PIN_UART_TX]; 306e25b4a2fSMatthias Ringwald platform_gpio_output_high(gpio); 307e25b4a2fSMatthias Ringwald 308e25b4a2fSMatthias Ringwald // reconfigure TX pin as GPIO 309e25b4a2fSMatthias Ringwald GPIO_InitTypeDef gpio_init_structure; 310e25b4a2fSMatthias Ringwald gpio_init_structure.GPIO_Speed = GPIO_Speed_50MHz; 311e25b4a2fSMatthias Ringwald gpio_init_structure.GPIO_Mode = GPIO_Mode_OUT; 312e25b4a2fSMatthias Ringwald gpio_init_structure.GPIO_OType = GPIO_OType_PP; 313e25b4a2fSMatthias Ringwald gpio_init_structure.GPIO_PuPd = GPIO_PuPd_NOPULL; 314e25b4a2fSMatthias Ringwald gpio_init_structure.GPIO_Pin = (uint32_t) ( 1 << gpio->pin_number ); 315e25b4a2fSMatthias Ringwald GPIO_Init( gpio->port, &gpio_init_structure ); 316e25b4a2fSMatthias Ringwald 317e25b4a2fSMatthias Ringwald // disable USART 318e25b4a2fSMatthias Ringwald USART_Cmd( wiced_bt_uart_peripheral->port, DISABLE ); 319e25b4a2fSMatthias Ringwald 320e25b4a2fSMatthias Ringwald // setup init structure 321e25b4a2fSMatthias Ringwald USART_InitTypeDef uart_init_structure; 322e25b4a2fSMatthias Ringwald uart_init_structure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; 323e25b4a2fSMatthias Ringwald uart_init_structure.USART_BaudRate = baudrate; 324e25b4a2fSMatthias Ringwald uart_init_structure.USART_WordLength = USART_WordLength_8b; 325e25b4a2fSMatthias Ringwald uart_init_structure.USART_StopBits = USART_StopBits_1; 326e25b4a2fSMatthias Ringwald uart_init_structure.USART_Parity = USART_Parity_No; 327e25b4a2fSMatthias Ringwald 328e25b4a2fSMatthias Ringwald if (btstack_flow_control_mode == BTSTACK_FLOW_CONTROL_UART){ 329e25b4a2fSMatthias Ringwald uart_init_structure.USART_HardwareFlowControl = USART_HardwareFlowControl_RTS_CTS; 330e25b4a2fSMatthias Ringwald } else { 331e25b4a2fSMatthias Ringwald uart_init_structure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; 332e25b4a2fSMatthias Ringwald } 333e25b4a2fSMatthias Ringwald USART_Init(wiced_bt_uart_peripheral->port, &uart_init_structure); 334e25b4a2fSMatthias Ringwald 335e25b4a2fSMatthias Ringwald // enable USART again 336e25b4a2fSMatthias Ringwald USART_Cmd( wiced_bt_uart_peripheral->port, ENABLE ); 337e25b4a2fSMatthias Ringwald 338e25b4a2fSMatthias Ringwald // set TX pin as USART again 339e25b4a2fSMatthias Ringwald gpio_init_structure.GPIO_Mode = GPIO_Mode_AF; 340e25b4a2fSMatthias Ringwald GPIO_Init( gpio->port, &gpio_init_structure ); 341e25b4a2fSMatthias Ringwald 342e25b4a2fSMatthias Ringwald #else 343e25b4a2fSMatthias Ringwald log_error("btstack_uart_block_wiced_set_baudrate not implemented for this WICED Platform"); 344e25b4a2fSMatthias Ringwald #endif 345e25b4a2fSMatthias Ringwald return 0; 346e25b4a2fSMatthias Ringwald } 347e25b4a2fSMatthias Ringwald 348e25b4a2fSMatthias Ringwald static int btstack_uart_block_wiced_set_parity(int parity){ 349e25b4a2fSMatthias Ringwald log_error("btstack_uart_block_wiced_set_parity not implemented"); 350e25b4a2fSMatthias Ringwald return 0; 351e25b4a2fSMatthias Ringwald } 352e25b4a2fSMatthias Ringwald 353e25b4a2fSMatthias Ringwald static void btstack_uart_block_wiced_send_block(const uint8_t *buffer, uint16_t length){ 354e25b4a2fSMatthias Ringwald // store in request 355e25b4a2fSMatthias Ringwald tx_worker_data_buffer = buffer; 356e25b4a2fSMatthias Ringwald tx_worker_data_size = length; 357e25b4a2fSMatthias Ringwald wiced_rtos_send_asynchronous_event(&tx_worker_thread, &btstack_uart_block_wiced_tx_worker_send_block, NULL); 358e25b4a2fSMatthias Ringwald } 359e25b4a2fSMatthias Ringwald 360e25b4a2fSMatthias Ringwald static void btstack_uart_block_wiced_receive_block(uint8_t *buffer, uint16_t len){ 361e25b4a2fSMatthias Ringwald rx_worker_read_buffer = buffer; 362e25b4a2fSMatthias Ringwald rx_worker_read_size = len; 363e25b4a2fSMatthias Ringwald wiced_rtos_send_asynchronous_event(&rx_worker_thread, &btstack_uart_block_wiced_rx_worker_receive_block, NULL); 364e25b4a2fSMatthias Ringwald } 365e25b4a2fSMatthias Ringwald 366e25b4a2fSMatthias Ringwald 367e25b4a2fSMatthias Ringwald // static void btstack_uart_block_wiced_set_sleep(uint8_t sleep){ 368e25b4a2fSMatthias Ringwald // } 369e25b4a2fSMatthias Ringwald // static void btstack_uart_block_wiced_set_csr_irq_handler( void (*csr_irq_handler)(void)){ 370e25b4a2fSMatthias Ringwald // } 371e25b4a2fSMatthias Ringwald 372e25b4a2fSMatthias Ringwald static const btstack_uart_block_t btstack_uart_block_wiced = { 373e25b4a2fSMatthias Ringwald /* int (*init)(hci_transport_config_uart_t * config); */ &btstack_uart_block_wiced_init, 374e25b4a2fSMatthias Ringwald /* int (*open)(void); */ &btstack_uart_block_wiced_open, 375e25b4a2fSMatthias Ringwald /* int (*close)(void); */ &btstack_uart_block_wiced_close, 376e25b4a2fSMatthias Ringwald /* void (*set_block_received)(void (*handler)(void)); */ &btstack_uart_block_wiced_set_block_received, 377e25b4a2fSMatthias Ringwald /* void (*set_block_sent)(void (*handler)(void)); */ &btstack_uart_block_wiced_set_block_sent, 378e25b4a2fSMatthias Ringwald /* int (*set_baudrate)(uint32_t baudrate); */ &btstack_uart_block_wiced_set_baudrate, 379e25b4a2fSMatthias Ringwald /* int (*set_parity)(int parity); */ &btstack_uart_block_wiced_set_parity, 3804b929998SMatthias Ringwald /* int (*set_flowcontrol)(int flowcontrol); */ NULL, 381e25b4a2fSMatthias Ringwald /* void (*receive_block)(uint8_t *buffer, uint16_t len); */ &btstack_uart_block_wiced_receive_block, 382e25b4a2fSMatthias Ringwald /* void (*send_block)(const uint8_t *buffer, uint16_t length); */ &btstack_uart_block_wiced_send_block, 383e25b4a2fSMatthias Ringwald /* int (*get_supported_sleep_modes); */ NULL, 384e25b4a2fSMatthias Ringwald /* void (*set_sleep)(btstack_uart_sleep_mode_t sleep_mode); */ NULL, 385e25b4a2fSMatthias Ringwald /* void (*set_wakeup_handler)(void (*handler)(void)); */ NULL, 386cf159062SMatthias Ringwald NULL, NULL, NULL, NULL, 387e25b4a2fSMatthias Ringwald }; 388e25b4a2fSMatthias Ringwald 389e25b4a2fSMatthias Ringwald const btstack_uart_block_t * btstack_uart_block_wiced_instance(void){ 390e25b4a2fSMatthias Ringwald return &btstack_uart_block_wiced; 391e25b4a2fSMatthias Ringwald } 392