xref: /btstack/platform/wiced/btstack_uart_block_wiced.c (revision 2fca4dad957cd7b88f4657ed51e89c12615dda72)
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
23*2fca4dadSMilanka Ringwald  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN
24*2fca4dadSMilanka Ringwald  * GMBH 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
btstack_uart_block_wiced_main_notify_block_send(void * arg)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
btstack_uart_block_wiced_main_notify_block_read(void * arg)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
120739fcdb2SMatthias Ringwald static btstack_context_callback_registration_t block_send_callback_registration;
btstack_uart_block_wiced_tx_worker_send_block(void * arg)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
133739fcdb2SMatthias Ringwald     block_send_callback_registration.callback = &btstack_uart_block_wiced_main_notify_block_send;
1349d933ba2SMatthias Ringwald     btstack_run_loop_execute_on_main_thread(&block_send_callback_registration);
135e25b4a2fSMatthias Ringwald     return WICED_SUCCESS;
136e25b4a2fSMatthias Ringwald }
137e25b4a2fSMatthias Ringwald 
138e25b4a2fSMatthias Ringwald // executed on rx worker thread
139739fcdb2SMatthias Ringwald static btstack_context_callback_registration_t block_received_callback_registration;
btstack_uart_block_wiced_rx_worker_receive_block(void * arg)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
161739fcdb2SMatthias Ringwald     block_received_callback_registration.callback = &btstack_uart_block_wiced_main_notify_block_read;
1629d933ba2SMatthias Ringwald     btstack_run_loop_execute_on_main_thread(&block_received_callback_registration);
163e25b4a2fSMatthias Ringwald     return WICED_SUCCESS;
164e25b4a2fSMatthias Ringwald }
165e25b4a2fSMatthias Ringwald 
btstack_uart_block_wiced_init(const btstack_uart_config_t * config)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 
btstack_uart_block_wiced_open(void)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 
btstack_uart_block_wiced_close(void)284e25b4a2fSMatthias Ringwald static int btstack_uart_block_wiced_close(void){
285e25b4a2fSMatthias Ringwald     // not implemented
286e25b4a2fSMatthias Ringwald     return 0;
287e25b4a2fSMatthias Ringwald }
288e25b4a2fSMatthias Ringwald 
btstack_uart_block_wiced_set_block_received(void (* block_handler)(void))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 
btstack_uart_block_wiced_set_block_sent(void (* block_handler)(void))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 
btstack_uart_block_wiced_set_baudrate(uint32_t baudrate)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 
btstack_uart_block_wiced_set_parity(int parity)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 
btstack_uart_block_wiced_send_block(const uint8_t * buffer,uint16_t length)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 
btstack_uart_block_wiced_receive_block(uint8_t * buffer,uint16_t len)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 
btstack_uart_block_wiced_instance(void)389e25b4a2fSMatthias Ringwald const btstack_uart_block_t * btstack_uart_block_wiced_instance(void){
390e25b4a2fSMatthias Ringwald     return &btstack_uart_block_wiced;
391e25b4a2fSMatthias Ringwald }
392