xref: /btstack/platform/wiced/btstack_uart_block_wiced.c (revision e501bae08349e058caa4648e0af3dd01cbd89d20)
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 
44*e501bae0SMatthias Ringwald #define BTSTACK_FILE__ "btstack_uart_block_wiced.c"
45e25b4a2fSMatthias Ringwald 
46e25b4a2fSMatthias Ringwald #include "btstack_config.h"
47e25b4a2fSMatthias Ringwald #include "btstack_run_loop_wiced.h"
48e25b4a2fSMatthias Ringwald 
49e25b4a2fSMatthias Ringwald #include "btstack_debug.h"
50e25b4a2fSMatthias Ringwald #include "hci.h"
51e25b4a2fSMatthias Ringwald #include "hci_transport.h"
52e25b4a2fSMatthias Ringwald #include "platform_bluetooth.h"
53e25b4a2fSMatthias Ringwald 
54e25b4a2fSMatthias Ringwald #include "wiced.h"
55e25b4a2fSMatthias Ringwald 
56e25b4a2fSMatthias Ringwald #include <stdio.h>
57e25b4a2fSMatthias Ringwald #include <string.h>
58e25b4a2fSMatthias Ringwald 
59e25b4a2fSMatthias Ringwald // priority higher than WIFI to make sure RTS is set
60e25b4a2fSMatthias Ringwald #define WICED_BT_UART_THREAD_PRIORITY        (WICED_NETWORK_WORKER_PRIORITY - 2)
61e25b4a2fSMatthias Ringwald #define WICED_BT_UART_THREAD_STACK_SIZE      300
62e25b4a2fSMatthias Ringwald 
63e25b4a2fSMatthias Ringwald // assert pre-buffer for packet type is available
64e25b4a2fSMatthias Ringwald #if !defined(HCI_OUTGOING_PRE_BUFFER_SIZE) || (HCI_OUTGOING_PRE_BUFFER_SIZE == 0)
65e25b4a2fSMatthias Ringwald #error HCI_OUTGOING_PRE_BUFFER_SIZE not defined. Please update hci.h
66e25b4a2fSMatthias Ringwald #endif
67e25b4a2fSMatthias Ringwald 
68e25b4a2fSMatthias Ringwald // Default of 512 bytes should be fine. Only needed with BTSTACK_FLOW_CONTROL_UART
69e25b4a2fSMatthias Ringwald #ifndef RX_RING_BUFFER_SIZE
70e25b4a2fSMatthias Ringwald #define RX_RING_BUFFER_SIZE 512
71e25b4a2fSMatthias Ringwald #endif
72e25b4a2fSMatthias Ringwald 
73e25b4a2fSMatthias Ringwald // Use BTSTACK_FLOW_CONTROL_MANUAL is used when Bluetooth RTS/CTS are not connected to UART RTS/CTS pins
74e25b4a2fSMatthias Ringwald // E.g. on RedBear Duo - WICED_BT_UART_MANUAL_CTS_RTS is defined
75e25b4a2fSMatthias Ringwald 
76e25b4a2fSMatthias Ringwald static enum {
77e25b4a2fSMatthias Ringwald     BTSTACK_FLOW_CONTROL_OFF,
78e25b4a2fSMatthias Ringwald     BTSTACK_FLOW_CONTROL_UART,
79e25b4a2fSMatthias Ringwald     BTSTACK_FLOW_CONTROL_MANUAL,
80e25b4a2fSMatthias Ringwald } btstack_flow_control_mode;
81e25b4a2fSMatthias Ringwald 
82e25b4a2fSMatthias Ringwald static wiced_result_t btstack_uart_block_wiced_rx_worker_receive_block(void * arg);
83e25b4a2fSMatthias Ringwald 
84e25b4a2fSMatthias Ringwald static wiced_worker_thread_t tx_worker_thread;
85e25b4a2fSMatthias Ringwald static const uint8_t *       tx_worker_data_buffer;
86e25b4a2fSMatthias Ringwald static uint16_t              tx_worker_data_size;
87e25b4a2fSMatthias Ringwald 
88e25b4a2fSMatthias Ringwald static wiced_worker_thread_t rx_worker_thread;
89e25b4a2fSMatthias Ringwald static uint8_t *             rx_worker_read_buffer;
90e25b4a2fSMatthias Ringwald static uint16_t              rx_worker_read_size;
91e25b4a2fSMatthias Ringwald 
92e25b4a2fSMatthias Ringwald static wiced_ring_buffer_t   rx_ring_buffer;
93e25b4a2fSMatthias Ringwald static uint8_t               rx_data[RX_RING_BUFFER_SIZE];
94e25b4a2fSMatthias Ringwald 
95e25b4a2fSMatthias Ringwald // uart config
96e25b4a2fSMatthias Ringwald static const btstack_uart_config_t * uart_config;
97e25b4a2fSMatthias Ringwald 
98e25b4a2fSMatthias Ringwald // callbacks
99e25b4a2fSMatthias Ringwald static void (*block_sent)(void);
100e25b4a2fSMatthias Ringwald static void (*block_received)(void);
101e25b4a2fSMatthias Ringwald 
102e25b4a2fSMatthias Ringwald // executed on main run loop
103e25b4a2fSMatthias Ringwald static wiced_result_t btstack_uart_block_wiced_main_notify_block_send(void *arg){
104e25b4a2fSMatthias Ringwald     if (block_sent){
105e25b4a2fSMatthias Ringwald         block_sent();
106e25b4a2fSMatthias Ringwald     }
107e25b4a2fSMatthias Ringwald     return WICED_SUCCESS;
108e25b4a2fSMatthias Ringwald }
109e25b4a2fSMatthias Ringwald 
110e25b4a2fSMatthias Ringwald // executed on main run loop
111e25b4a2fSMatthias Ringwald static wiced_result_t btstack_uart_block_wiced_main_notify_block_read(void *arg){
112e25b4a2fSMatthias Ringwald     if (block_received){
113e25b4a2fSMatthias Ringwald         block_received();
114e25b4a2fSMatthias Ringwald     }
115e25b4a2fSMatthias Ringwald     return WICED_SUCCESS;
116e25b4a2fSMatthias Ringwald }
117e25b4a2fSMatthias Ringwald 
118e25b4a2fSMatthias Ringwald // executed on tx worker thread
119e25b4a2fSMatthias Ringwald static wiced_result_t btstack_uart_block_wiced_tx_worker_send_block(void * arg){
120e25b4a2fSMatthias Ringwald     // wait for CTS to become low in manual flow control mode
121e25b4a2fSMatthias Ringwald     if (btstack_flow_control_mode == BTSTACK_FLOW_CONTROL_MANUAL && wiced_bt_uart_pins[WICED_BT_PIN_UART_CTS]){
122e25b4a2fSMatthias Ringwald         while (platform_gpio_input_get(wiced_bt_uart_pins[WICED_BT_PIN_UART_CTS]) == WICED_TRUE){
123e25b4a2fSMatthias Ringwald             wiced_rtos_delay_milliseconds(10);
124e25b4a2fSMatthias Ringwald         }
125e25b4a2fSMatthias Ringwald     }
126e25b4a2fSMatthias Ringwald 
127e25b4a2fSMatthias Ringwald     // blocking send
128e25b4a2fSMatthias Ringwald     platform_uart_transmit_bytes(wiced_bt_uart_driver, tx_worker_data_buffer, tx_worker_data_size);
129e25b4a2fSMatthias Ringwald 
130e25b4a2fSMatthias Ringwald     // let transport know
131e25b4a2fSMatthias Ringwald     btstack_run_loop_wiced_execute_code_on_main_thread(&btstack_uart_block_wiced_main_notify_block_send, NULL);
132e25b4a2fSMatthias Ringwald     return WICED_SUCCESS;
133e25b4a2fSMatthias Ringwald }
134e25b4a2fSMatthias Ringwald 
135e25b4a2fSMatthias Ringwald // executed on rx worker thread
136e25b4a2fSMatthias Ringwald static wiced_result_t btstack_uart_block_wiced_rx_worker_receive_block(void * arg){
137e25b4a2fSMatthias Ringwald 
138e25b4a2fSMatthias Ringwald     if (btstack_flow_control_mode == BTSTACK_FLOW_CONTROL_MANUAL && wiced_bt_uart_pins[WICED_BT_PIN_UART_CTS]){
139e25b4a2fSMatthias Ringwald         platform_gpio_output_low(wiced_bt_uart_pins[WICED_BT_PIN_UART_RTS]);
140e25b4a2fSMatthias Ringwald     }
141e25b4a2fSMatthias Ringwald 
142e25b4a2fSMatthias Ringwald #ifdef WICED_UART_READ_DOES_NOT_RETURN_BYTES_READ
143e25b4a2fSMatthias Ringwald     // older API passes in number of bytes to read (checked in 3.3.1 and 3.4.0)
144e25b4a2fSMatthias Ringwald     platform_uart_receive_bytes(wiced_bt_uart_driver, rx_worker_read_buffer, rx_worker_read_size, WICED_NEVER_TIMEOUT);
145e25b4a2fSMatthias Ringwald #else
146e25b4a2fSMatthias Ringwald     // newer API uses pointer to return number of read bytes
147e25b4a2fSMatthias Ringwald     uint32_t bytes = rx_worker_read_size;
148e25b4a2fSMatthias Ringwald     platform_uart_receive_bytes(wiced_bt_uart_driver, rx_worker_read_buffer, &bytes, WICED_NEVER_TIMEOUT);
149e25b4a2fSMatthias Ringwald     // assumption: bytes = bytes_to_read as timeout is never
150e25b4a2fSMatthias Ringwald #endif
151e25b4a2fSMatthias Ringwald 
152e25b4a2fSMatthias Ringwald     if (btstack_flow_control_mode == BTSTACK_FLOW_CONTROL_MANUAL && wiced_bt_uart_pins[WICED_BT_PIN_UART_CTS]){
153e25b4a2fSMatthias Ringwald         platform_gpio_output_high(wiced_bt_uart_pins[WICED_BT_PIN_UART_RTS]);
154e25b4a2fSMatthias Ringwald     }
155e25b4a2fSMatthias Ringwald 
156e25b4a2fSMatthias Ringwald     // let transport know
157e25b4a2fSMatthias Ringwald     btstack_run_loop_wiced_execute_code_on_main_thread(&btstack_uart_block_wiced_main_notify_block_read, NULL);
158e25b4a2fSMatthias Ringwald     return WICED_SUCCESS;
159e25b4a2fSMatthias Ringwald }
160e25b4a2fSMatthias Ringwald 
161e25b4a2fSMatthias Ringwald static int btstack_uart_block_wiced_init(const btstack_uart_config_t * config){
162e25b4a2fSMatthias Ringwald     uart_config = config;
163e25b4a2fSMatthias Ringwald 
164e25b4a2fSMatthias Ringwald     // determine flow control mode based on hardware config and uart config
165e25b4a2fSMatthias Ringwald     if (uart_config->flowcontrol){
166e25b4a2fSMatthias Ringwald #ifdef WICED_BT_UART_MANUAL_CTS_RTS
167e25b4a2fSMatthias Ringwald         btstack_flow_control_mode = BTSTACK_FLOW_CONTROL_MANUAL;
168e25b4a2fSMatthias Ringwald #else
169e25b4a2fSMatthias Ringwald         btstack_flow_control_mode = BTSTACK_FLOW_CONTROL_UART;
170e25b4a2fSMatthias Ringwald #endif
171e25b4a2fSMatthias Ringwald     } else {
172e25b4a2fSMatthias Ringwald         btstack_flow_control_mode = BTSTACK_FLOW_CONTROL_OFF;
173e25b4a2fSMatthias Ringwald     }
174e25b4a2fSMatthias Ringwald     return 0;
175e25b4a2fSMatthias Ringwald }
176e25b4a2fSMatthias Ringwald 
177e25b4a2fSMatthias Ringwald static int btstack_uart_block_wiced_open(void){
178e25b4a2fSMatthias Ringwald 
179e25b4a2fSMatthias Ringwald     // UART config
180e25b4a2fSMatthias Ringwald     wiced_uart_config_t wiced_uart_config =
181e25b4a2fSMatthias Ringwald     {
182e25b4a2fSMatthias Ringwald         .baud_rate    = uart_config->baudrate,
183e25b4a2fSMatthias Ringwald         .data_width   = DATA_WIDTH_8BIT,
184e25b4a2fSMatthias Ringwald         .parity       = NO_PARITY,
185e25b4a2fSMatthias Ringwald         .stop_bits    = STOP_BITS_1,
186e25b4a2fSMatthias Ringwald     };
187e25b4a2fSMatthias Ringwald 
188e25b4a2fSMatthias Ringwald     if (btstack_flow_control_mode == BTSTACK_FLOW_CONTROL_UART){
189e25b4a2fSMatthias Ringwald         wiced_uart_config.flow_control = FLOW_CONTROL_CTS_RTS;
190e25b4a2fSMatthias Ringwald     } else {
191e25b4a2fSMatthias Ringwald         wiced_uart_config.flow_control = FLOW_CONTROL_DISABLED;
192e25b4a2fSMatthias Ringwald     }
193e25b4a2fSMatthias Ringwald     wiced_ring_buffer_t * ring_buffer = NULL;
194e25b4a2fSMatthias Ringwald 
195e25b4a2fSMatthias Ringwald     // configure HOST and DEVICE WAKE PINs
196e25b4a2fSMatthias Ringwald     platform_gpio_init(wiced_bt_control_pins[WICED_BT_PIN_HOST_WAKE], INPUT_HIGH_IMPEDANCE);
197e25b4a2fSMatthias Ringwald     platform_gpio_init(wiced_bt_control_pins[WICED_BT_PIN_DEVICE_WAKE], OUTPUT_PUSH_PULL);
198e25b4a2fSMatthias Ringwald     platform_gpio_output_low(wiced_bt_control_pins[WICED_BT_PIN_DEVICE_WAKE]);
199e25b4a2fSMatthias Ringwald 
200e25b4a2fSMatthias Ringwald     /* Configure Reg Enable pin to output. Set to HIGH */
201e25b4a2fSMatthias Ringwald     if (wiced_bt_control_pins[ WICED_BT_PIN_POWER ]){
202e25b4a2fSMatthias Ringwald         platform_gpio_init( wiced_bt_control_pins[ WICED_BT_PIN_POWER ], OUTPUT_OPEN_DRAIN_PULL_UP );
203e25b4a2fSMatthias Ringwald         platform_gpio_output_high( wiced_bt_control_pins[ WICED_BT_PIN_POWER ] );
204e25b4a2fSMatthias Ringwald     }
205e25b4a2fSMatthias Ringwald 
206e25b4a2fSMatthias Ringwald     wiced_rtos_delay_milliseconds( 100 );
207e25b4a2fSMatthias Ringwald 
208e25b4a2fSMatthias Ringwald     // Configure RTS
209e25b4a2fSMatthias Ringwald     if (wiced_bt_uart_pins[WICED_BT_PIN_UART_RTS]){
210e25b4a2fSMatthias Ringwald         switch (btstack_flow_control_mode){
211e25b4a2fSMatthias Ringwald             case BTSTACK_FLOW_CONTROL_OFF:
212e25b4a2fSMatthias Ringwald                 // configure RTS pin as output and set to low - always on
213e25b4a2fSMatthias Ringwald                 platform_gpio_init(wiced_bt_uart_pins[WICED_BT_PIN_UART_RTS], OUTPUT_PUSH_PULL);
214e25b4a2fSMatthias Ringwald                 platform_gpio_output_low(wiced_bt_uart_pins[WICED_BT_PIN_UART_RTS]);
215e25b4a2fSMatthias Ringwald                 break;
216e25b4a2fSMatthias Ringwald             case BTSTACK_FLOW_CONTROL_UART:
217e25b4a2fSMatthias Ringwald                 // configuration done by platform_uart_init
218e25b4a2fSMatthias Ringwald                 break;
219e25b4a2fSMatthias Ringwald             case BTSTACK_FLOW_CONTROL_MANUAL:
220e25b4a2fSMatthias Ringwald                 // configure RTS pin as output and set to high - controlled by btstack_uart_block_wiced_rx_worker_receive_block
221e25b4a2fSMatthias Ringwald                 platform_gpio_init(wiced_bt_uart_pins[WICED_BT_PIN_UART_RTS], OUTPUT_PUSH_PULL);
222e25b4a2fSMatthias Ringwald                 platform_gpio_output_high(wiced_bt_uart_pins[WICED_BT_PIN_UART_RTS]);
223e25b4a2fSMatthias Ringwald                 break;
224e25b4a2fSMatthias Ringwald         }
225e25b4a2fSMatthias Ringwald     }
226e25b4a2fSMatthias Ringwald 
227e25b4a2fSMatthias Ringwald     // Configure CTS
228e25b4a2fSMatthias Ringwald     if (wiced_bt_uart_pins[WICED_BT_PIN_UART_CTS]){
229e25b4a2fSMatthias Ringwald         switch (btstack_flow_control_mode){
230e25b4a2fSMatthias Ringwald             case BTSTACK_FLOW_CONTROL_OFF:
231e25b4a2fSMatthias Ringwald                 // don't care
232e25b4a2fSMatthias Ringwald                 break;
233e25b4a2fSMatthias Ringwald             case BTSTACK_FLOW_CONTROL_UART:
234e25b4a2fSMatthias Ringwald                 // configuration done by platform_uart_init
235e25b4a2fSMatthias Ringwald                 break;
236e25b4a2fSMatthias Ringwald             case BTSTACK_FLOW_CONTROL_MANUAL:
237e25b4a2fSMatthias Ringwald                 // configure CTS to input, pull-up
238e25b4a2fSMatthias Ringwald                 platform_gpio_init(wiced_bt_uart_pins[WICED_BT_PIN_UART_CTS], INPUT_PULL_UP);
239e25b4a2fSMatthias Ringwald                 break;
240e25b4a2fSMatthias Ringwald         }
241e25b4a2fSMatthias Ringwald     }
242e25b4a2fSMatthias Ringwald 
243e25b4a2fSMatthias Ringwald     // use ring buffer to allow to receive RX_RING_BUFFER_SIZE/2 addition bytes - not needed with hardware UART
244e25b4a2fSMatthias Ringwald     if (btstack_flow_control_mode != BTSTACK_FLOW_CONTROL_UART){
245e25b4a2fSMatthias Ringwald         ring_buffer_init((wiced_ring_buffer_t *) &rx_ring_buffer, (uint8_t*) rx_data, sizeof( rx_data ) );
246e25b4a2fSMatthias Ringwald         ring_buffer = (wiced_ring_buffer_t *) &rx_ring_buffer;
247e25b4a2fSMatthias Ringwald     }
248e25b4a2fSMatthias Ringwald 
249e25b4a2fSMatthias Ringwald     platform_uart_init( wiced_bt_uart_driver, wiced_bt_uart_peripheral, &wiced_uart_config, ring_buffer );
250e25b4a2fSMatthias Ringwald 
251e25b4a2fSMatthias Ringwald 
252e25b4a2fSMatthias Ringwald     // Reset Bluetooth via RESET line. Fallback to toggling POWER otherwise
253e25b4a2fSMatthias Ringwald     if ( wiced_bt_control_pins[ WICED_BT_PIN_RESET ]){
254e25b4a2fSMatthias Ringwald         platform_gpio_init( wiced_bt_control_pins[ WICED_BT_PIN_RESET ], OUTPUT_PUSH_PULL );
255e25b4a2fSMatthias Ringwald         platform_gpio_output_high( wiced_bt_control_pins[ WICED_BT_PIN_RESET ] );
256e25b4a2fSMatthias Ringwald 
257e25b4a2fSMatthias Ringwald         platform_gpio_output_low( wiced_bt_control_pins[ WICED_BT_PIN_RESET ] );
258e25b4a2fSMatthias Ringwald         wiced_rtos_delay_milliseconds( 100 );
259e25b4a2fSMatthias Ringwald         platform_gpio_output_high( wiced_bt_control_pins[ WICED_BT_PIN_RESET ] );
260e25b4a2fSMatthias Ringwald     }
261e25b4a2fSMatthias Ringwald     else if ( wiced_bt_control_pins[ WICED_BT_PIN_POWER ]){
262e25b4a2fSMatthias Ringwald         platform_gpio_output_low( wiced_bt_control_pins[ WICED_BT_PIN_POWER ] );
263e25b4a2fSMatthias Ringwald         wiced_rtos_delay_milliseconds( 100 );
264e25b4a2fSMatthias Ringwald         platform_gpio_output_high( wiced_bt_control_pins[ WICED_BT_PIN_POWER ] );
265e25b4a2fSMatthias Ringwald     }
266e25b4a2fSMatthias Ringwald 
267e25b4a2fSMatthias Ringwald     // wait for Bluetooth to start up
268e25b4a2fSMatthias Ringwald     wiced_rtos_delay_milliseconds( 500 );
269e25b4a2fSMatthias Ringwald 
270e25b4a2fSMatthias Ringwald     // create worker threads for rx/tx. only single request is posted to their queues
271e25b4a2fSMatthias Ringwald     wiced_rtos_create_worker_thread(&tx_worker_thread, WICED_BT_UART_THREAD_PRIORITY, WICED_BT_UART_THREAD_STACK_SIZE, 1);
272e25b4a2fSMatthias Ringwald     wiced_rtos_create_worker_thread(&rx_worker_thread, WICED_BT_UART_THREAD_PRIORITY, WICED_BT_UART_THREAD_STACK_SIZE, 1);
273e25b4a2fSMatthias Ringwald 
274e25b4a2fSMatthias Ringwald     // tx is ready
275e25b4a2fSMatthias Ringwald     tx_worker_data_size = 0;
276e25b4a2fSMatthias Ringwald     return 0;
277e25b4a2fSMatthias Ringwald }
278e25b4a2fSMatthias Ringwald 
279e25b4a2fSMatthias Ringwald static int btstack_uart_block_wiced_close(void){
280e25b4a2fSMatthias Ringwald     // not implemented
281e25b4a2fSMatthias Ringwald     return 0;
282e25b4a2fSMatthias Ringwald }
283e25b4a2fSMatthias Ringwald 
284e25b4a2fSMatthias Ringwald static void btstack_uart_block_wiced_set_block_received( void (*block_handler)(void)){
285e25b4a2fSMatthias Ringwald     block_received = block_handler;
286e25b4a2fSMatthias Ringwald }
287e25b4a2fSMatthias Ringwald 
288e25b4a2fSMatthias Ringwald static void btstack_uart_block_wiced_set_block_sent( void (*block_handler)(void)){
289e25b4a2fSMatthias Ringwald     block_sent = block_handler;
290e25b4a2fSMatthias Ringwald }
291e25b4a2fSMatthias Ringwald 
292e25b4a2fSMatthias Ringwald static int btstack_uart_block_wiced_set_baudrate(uint32_t baudrate){
293e25b4a2fSMatthias Ringwald 
2947e4bff82SMatthias Ringwald #if defined(_STM32F205RGT6_) || defined(STM32F40_41xxx) || defined(STM32F411xE) || (STM32F412xG)
295e25b4a2fSMatthias Ringwald 
296e25b4a2fSMatthias Ringwald     // directly use STM peripheral functions to change baud rate dynamically
297e25b4a2fSMatthias Ringwald 
298e25b4a2fSMatthias Ringwald     // set TX to high
299e25b4a2fSMatthias Ringwald     log_info("set baud %u", (int) baudrate);
300e25b4a2fSMatthias Ringwald     const platform_gpio_t* gpio = wiced_bt_uart_pins[WICED_BT_PIN_UART_TX];
301e25b4a2fSMatthias Ringwald     platform_gpio_output_high(gpio);
302e25b4a2fSMatthias Ringwald 
303e25b4a2fSMatthias Ringwald     // reconfigure TX pin as GPIO
304e25b4a2fSMatthias Ringwald     GPIO_InitTypeDef gpio_init_structure;
305e25b4a2fSMatthias Ringwald     gpio_init_structure.GPIO_Speed = GPIO_Speed_50MHz;
306e25b4a2fSMatthias Ringwald     gpio_init_structure.GPIO_Mode  = GPIO_Mode_OUT;
307e25b4a2fSMatthias Ringwald     gpio_init_structure.GPIO_OType = GPIO_OType_PP;
308e25b4a2fSMatthias Ringwald     gpio_init_structure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
309e25b4a2fSMatthias Ringwald     gpio_init_structure.GPIO_Pin   = (uint32_t) ( 1 << gpio->pin_number );
310e25b4a2fSMatthias Ringwald     GPIO_Init( gpio->port, &gpio_init_structure );
311e25b4a2fSMatthias Ringwald 
312e25b4a2fSMatthias Ringwald     // disable USART
313e25b4a2fSMatthias Ringwald     USART_Cmd( wiced_bt_uart_peripheral->port, DISABLE );
314e25b4a2fSMatthias Ringwald 
315e25b4a2fSMatthias Ringwald     // setup init structure
316e25b4a2fSMatthias Ringwald     USART_InitTypeDef uart_init_structure;
317e25b4a2fSMatthias Ringwald     uart_init_structure.USART_Mode       = USART_Mode_Rx | USART_Mode_Tx;
318e25b4a2fSMatthias Ringwald     uart_init_structure.USART_BaudRate   = baudrate;
319e25b4a2fSMatthias Ringwald     uart_init_structure.USART_WordLength = USART_WordLength_8b;
320e25b4a2fSMatthias Ringwald     uart_init_structure.USART_StopBits   = USART_StopBits_1;
321e25b4a2fSMatthias Ringwald     uart_init_structure.USART_Parity     = USART_Parity_No;
322e25b4a2fSMatthias Ringwald 
323e25b4a2fSMatthias Ringwald     if (btstack_flow_control_mode == BTSTACK_FLOW_CONTROL_UART){
324e25b4a2fSMatthias Ringwald         uart_init_structure.USART_HardwareFlowControl = USART_HardwareFlowControl_RTS_CTS;
325e25b4a2fSMatthias Ringwald     } else {
326e25b4a2fSMatthias Ringwald         uart_init_structure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
327e25b4a2fSMatthias Ringwald     }
328e25b4a2fSMatthias Ringwald     USART_Init(wiced_bt_uart_peripheral->port, &uart_init_structure);
329e25b4a2fSMatthias Ringwald 
330e25b4a2fSMatthias Ringwald     // enable USART again
331e25b4a2fSMatthias Ringwald     USART_Cmd( wiced_bt_uart_peripheral->port, ENABLE );
332e25b4a2fSMatthias Ringwald 
333e25b4a2fSMatthias Ringwald     // set TX pin as USART again
334e25b4a2fSMatthias Ringwald     gpio_init_structure.GPIO_Mode  = GPIO_Mode_AF;
335e25b4a2fSMatthias Ringwald     GPIO_Init( gpio->port, &gpio_init_structure );
336e25b4a2fSMatthias Ringwald 
337e25b4a2fSMatthias Ringwald #else
338e25b4a2fSMatthias Ringwald     log_error("btstack_uart_block_wiced_set_baudrate not implemented for this WICED Platform");
339e25b4a2fSMatthias Ringwald #endif
340e25b4a2fSMatthias Ringwald     return 0;
341e25b4a2fSMatthias Ringwald }
342e25b4a2fSMatthias Ringwald 
343e25b4a2fSMatthias Ringwald static int btstack_uart_block_wiced_set_parity(int parity){
344e25b4a2fSMatthias Ringwald     log_error("btstack_uart_block_wiced_set_parity not implemented");
345e25b4a2fSMatthias Ringwald     return 0;
346e25b4a2fSMatthias Ringwald }
347e25b4a2fSMatthias Ringwald 
348e25b4a2fSMatthias Ringwald static void btstack_uart_block_wiced_send_block(const uint8_t *buffer, uint16_t length){
349e25b4a2fSMatthias Ringwald     // store in request
350e25b4a2fSMatthias Ringwald     tx_worker_data_buffer = buffer;
351e25b4a2fSMatthias Ringwald     tx_worker_data_size = length;
352e25b4a2fSMatthias Ringwald     wiced_rtos_send_asynchronous_event(&tx_worker_thread, &btstack_uart_block_wiced_tx_worker_send_block, NULL);
353e25b4a2fSMatthias Ringwald }
354e25b4a2fSMatthias Ringwald 
355e25b4a2fSMatthias Ringwald static void btstack_uart_block_wiced_receive_block(uint8_t *buffer, uint16_t len){
356e25b4a2fSMatthias Ringwald     rx_worker_read_buffer = buffer;
357e25b4a2fSMatthias Ringwald     rx_worker_read_size   = len;
358e25b4a2fSMatthias Ringwald     wiced_rtos_send_asynchronous_event(&rx_worker_thread, &btstack_uart_block_wiced_rx_worker_receive_block, NULL);
359e25b4a2fSMatthias Ringwald }
360e25b4a2fSMatthias Ringwald 
361e25b4a2fSMatthias Ringwald 
362e25b4a2fSMatthias Ringwald // static void btstack_uart_block_wiced_set_sleep(uint8_t sleep){
363e25b4a2fSMatthias Ringwald // }
364e25b4a2fSMatthias Ringwald // static void btstack_uart_block_wiced_set_csr_irq_handler( void (*csr_irq_handler)(void)){
365e25b4a2fSMatthias Ringwald // }
366e25b4a2fSMatthias Ringwald 
367e25b4a2fSMatthias Ringwald static const btstack_uart_block_t btstack_uart_block_wiced = {
368e25b4a2fSMatthias Ringwald     /* int  (*init)(hci_transport_config_uart_t * config); */         &btstack_uart_block_wiced_init,
369e25b4a2fSMatthias Ringwald     /* int  (*open)(void); */                                         &btstack_uart_block_wiced_open,
370e25b4a2fSMatthias Ringwald     /* int  (*close)(void); */                                        &btstack_uart_block_wiced_close,
371e25b4a2fSMatthias Ringwald     /* void (*set_block_received)(void (*handler)(void)); */          &btstack_uart_block_wiced_set_block_received,
372e25b4a2fSMatthias Ringwald     /* void (*set_block_sent)(void (*handler)(void)); */              &btstack_uart_block_wiced_set_block_sent,
373e25b4a2fSMatthias Ringwald     /* int  (*set_baudrate)(uint32_t baudrate); */                    &btstack_uart_block_wiced_set_baudrate,
374e25b4a2fSMatthias Ringwald     /* int  (*set_parity)(int parity); */                             &btstack_uart_block_wiced_set_parity,
3754b929998SMatthias Ringwald     /* int  (*set_flowcontrol)(int flowcontrol); */                   NULL,
376e25b4a2fSMatthias Ringwald     /* void (*receive_block)(uint8_t *buffer, uint16_t len); */       &btstack_uart_block_wiced_receive_block,
377e25b4a2fSMatthias Ringwald     /* void (*send_block)(const uint8_t *buffer, uint16_t length); */ &btstack_uart_block_wiced_send_block,
378e25b4a2fSMatthias Ringwald     /* int (*get_supported_sleep_modes); */                           NULL,
379e25b4a2fSMatthias Ringwald     /* void (*set_sleep)(btstack_uart_sleep_mode_t sleep_mode); */    NULL,
380e25b4a2fSMatthias Ringwald     /* void (*set_wakeup_handler)(void (*handler)(void)); */          NULL,
381e25b4a2fSMatthias Ringwald };
382e25b4a2fSMatthias Ringwald 
383e25b4a2fSMatthias Ringwald const btstack_uart_block_t * btstack_uart_block_wiced_instance(void){
384e25b4a2fSMatthias Ringwald     return &btstack_uart_block_wiced;
385e25b4a2fSMatthias Ringwald }
386