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