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