diff --git a/README.md b/README.md index 5210053b3..23550e9be 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ Status | Platform [](https://buildbot.bluekitchen-gmbh.com/btstack/builders/port-msp430f5229lp-cc2564b-develop) | [MSP-EXP430F5529LP LaunchPad](http://www.ti.com/ww/en/launchpad/launchpads-msp430-msp-exp430f5529lp.html#tabs) with [Bluetooth CC2564 Module Evaluation Board](http://www.ti.com/tool/cc2564modnem) and [EM Adapter BoosterPack](http://www.ti.com/tool/boost-ccemadapter) with additional 32768Hz quartz oscillator [](https://buildbot.bluekitchen-gmbh.com/btstack/builders/port-stm32-f103rb-nucleo-develop) | [STM32 Nucleo development board NUCLEO-F103RB](http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF259875) with [Bluetooth CC2564 Module Evaluation Board](http://www.ti.com/tool/cc2564modnem) and [EM Adapter BoosterPack](http://www.ti.com/tool/boost-ccemadapter) with additional 32768Hz quartz oscillator [](https://buildbot.bluekitchen-gmbh.com/btstack/builders/port-pic32-harmony-develop) | [Microchip's PIC32 Bluetooth Audio Development Kit](http://www.microchip.com/Developmenttools/ProductDetails.aspx?PartNO=DV320032) -[](https://buildbot.bluekitchen-gmbh.com/btstack/builders/port-wiced-develop) | [RedBear Duo](https://github.com/redbear/WICED-SDK) with Broadcom BCM43438 A1 +[](https://buildbot.bluekitchen-gmbh.com/btstack/builders/port-wiced-h4-develop) | [RedBear Duo](https://github.com/redbear/WICED-SDK) with Broadcom BCM43438 A1 #### Other Platforms: diff --git a/port/wiced/btstack_config.h b/port/wiced-h4/wiced/btstack_config.h similarity index 100% rename from port/wiced/btstack_config.h rename to port/wiced-h4/wiced/btstack_config.h diff --git a/port/wiced/btstack_link_key_db_wiced_dct.c b/port/wiced-h4/wiced/btstack_link_key_db_wiced_dct.c similarity index 100% rename from port/wiced/btstack_link_key_db_wiced_dct.c rename to port/wiced-h4/wiced/btstack_link_key_db_wiced_dct.c diff --git a/port/wiced/btstack_link_key_db_wiced_dct.h b/port/wiced-h4/wiced/btstack_link_key_db_wiced_dct.h similarity index 100% rename from port/wiced/btstack_link_key_db_wiced_dct.h rename to port/wiced-h4/wiced/btstack_link_key_db_wiced_dct.h diff --git a/port/wiced/btstack_run_loop_wiced.c b/port/wiced-h4/wiced/btstack_run_loop_wiced.c similarity index 100% rename from port/wiced/btstack_run_loop_wiced.c rename to port/wiced-h4/wiced/btstack_run_loop_wiced.c diff --git a/port/wiced/btstack_run_loop_wiced.h b/port/wiced-h4/wiced/btstack_run_loop_wiced.h similarity index 100% rename from port/wiced/btstack_run_loop_wiced.h rename to port/wiced-h4/wiced/btstack_run_loop_wiced.h diff --git a/port/wiced/btstack_uart_block_wiced.c b/port/wiced-h4/wiced/btstack_uart_block_wiced.c similarity index 100% rename from port/wiced/btstack_uart_block_wiced.c rename to port/wiced-h4/wiced/btstack_uart_block_wiced.c diff --git a/port/wiced/create_examples.py b/port/wiced-h4/wiced/create_examples.py similarity index 100% rename from port/wiced/create_examples.py rename to port/wiced-h4/wiced/create_examples.py diff --git a/port/wiced/hci_transport_h4_wiced.c b/port/wiced-h4/wiced/hci_transport_h4_wiced.c similarity index 100% rename from port/wiced/hci_transport_h4_wiced.c rename to port/wiced-h4/wiced/hci_transport_h4_wiced.c diff --git a/port/wiced/main.c b/port/wiced-h4/wiced/main.c similarity index 100% rename from port/wiced/main.c rename to port/wiced-h4/wiced/main.c diff --git a/port/wiced/readme.md b/port/wiced-h4/wiced/readme.md similarity index 100% rename from port/wiced/readme.md rename to port/wiced-h4/wiced/readme.md diff --git a/port/wiced/wiced.mk b/port/wiced-h4/wiced/wiced.mk similarity index 100% rename from port/wiced/wiced.mk rename to port/wiced-h4/wiced/wiced.mk diff --git a/port/wiced-h5/btstack_aes128_wiced.c b/port/wiced-h5/btstack_aes128_wiced.c new file mode 100644 index 000000000..9168c898b --- /dev/null +++ b/port/wiced-h5/btstack_aes128_wiced.c @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2015 BlueKitchen GmbH + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * 4. Any redistribution, use, or modification is done solely for + * personal benefit and not for any commercial purpose or for + * monetary gain. + * + * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS + * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Please inquire about commercial licensing options at + * contact@bluekitchen-gmbh.com + * + */ + +#define __BTSTACK_FILE__ "main.c" + +#include "wiced_security.h" + +static aes_context_t wiced_aes128_context; + +void btstack_aes128_calc(uint8_t * key, uint8_t * plaintext, uint8_t * result); +void btstack_aes128_calc(uint8_t * key, uint8_t * plaintext, uint8_t * result){ + aes_setkey_enc(&wiced_aes128_context, key, 128); + aes_crypt_ecb(&wiced_aes128_context, AES_ENCRYPT , plaintext, result); +} diff --git a/port/wiced-h5/btstack_config.h b/port/wiced-h5/btstack_config.h new file mode 100644 index 000000000..09b09d6cf --- /dev/null +++ b/port/wiced-h5/btstack_config.h @@ -0,0 +1,45 @@ +// +// btstack_config.h for WICED port +// + +#ifndef __BTSTACK_CONFIG +#define __BTSTACK_CONFIG + +// Port related features +#define HAVE_EMBEDDED_TIME_MS +#define WICED_BT_UART_MANUAL_CTS_RTS +#define HAVE_AES128 + +// BTstack features that can be enabled +#define ENABLE_BLE +#define ENABLE_CLASSIC +#define ENABLE_LE_PERIPHERAL +#define ENABLE_LE_CENTRAL +#define ENABLE_LE_SECURE_CONNECTIONS +#define ENABLE_LOG_ERROR +#define ENABLE_LOG_INFO +// #define ENABLE_LOG_DEBUG + +// BTstack configuration. buffers, sizes, ... +#define HCI_ACL_PAYLOAD_SIZE 100 +#define MAX_SPP_CONNECTIONS 1 +#define MAX_NR_GATT_CLIENTS 1 +#define MAX_NR_HCI_CONNECTIONS MAX_SPP_CONNECTIONS +#define MAX_NR_L2CAP_SERVICES 2 +#define MAX_NR_L2CAP_CHANNELS (1+MAX_SPP_CONNECTIONS) +#define MAX_NR_RFCOMM_MULTIPLEXERS MAX_SPP_CONNECTIONS +#define MAX_NR_RFCOMM_SERVICES 1 +#define MAX_NR_RFCOMM_CHANNELS MAX_SPP_CONNECTIONS +#define MAX_NR_BTSTACK_LINK_KEY_DB_MEMORY_ENTRIES 2 +#define MAX_NR_BNEP_SERVICES 0 +#define MAX_NR_BNEP_CHANNELS 0 +#define MAX_NR_HFP_CONNECTIONS 0 +#define MAX_NR_WHITELIST_ENTRIES 1 +#define MAX_NR_SM_LOOKUP_ENTRIES 3 +#define MAX_NR_SERVICE_RECORD_ITEMS 1 +#define MAX_NR_LE_DEVICE_DB_ENTRIES 1 + +// Nun Link Keys stored in WICED DCT +#define NVM_NUM_LINK_KEYS 10 + +#endif \ No newline at end of file diff --git a/port/wiced-h5/btstack_link_key_db_wiced_dct.c b/port/wiced-h5/btstack_link_key_db_wiced_dct.c new file mode 100644 index 000000000..38b10b0c4 --- /dev/null +++ b/port/wiced-h5/btstack_link_key_db_wiced_dct.c @@ -0,0 +1,228 @@ +/* + * Copyright (C) 2016 BlueKitchen GmbH + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * 4. Any redistribution, use, or modification is done solely for + * personal benefit and not for any commercial purpose or for + * monetary gain. + * + * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS + * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Please inquire about commercial licensing options at + * contact@bluekitchen-gmbh.com + * + */ + +#define __BTSTACK_FILE__ "btstack_link_key_db_wiced_dct.c" + +/* + * btstack_link_key_db_wiced_dct.c + * + * Persistent Link Key implemenetation for WICED using DCT mechanism + */ + +#include "classic/btstack_link_key_db.h" + +#include "stdint.h" +#include "string.h" +#include "btstack_debug.h" +#include "btstack_util.h" + +#include "wiced.h" + +// Link Key Magic +#define LINK_KEY_MAGIC ((uint32_t) 'B' << 24 | 'T' << 16 | 'L' << 8 | 'K') + +typedef struct link_key_nvm { + uint32_t magic; + uint32_t seq_nr; // used for "last recently stored" eviction strategy + bd_addr_t bd_addr; + link_key_t link_key; + link_key_type_t link_key_type; +} link_key_nvm_t; + +static char link_key_to_str_buffer[LINK_KEY_STR_LEN+1]; // 11223344556677889900112233445566\0 +static char *link_key_to_str(link_key_t link_key){ + char * p = link_key_to_str_buffer; + int i; + for (i = 0; i < LINK_KEY_LEN ; i++) { + *p++ = char_for_nibble((link_key[i] >> 4) & 0x0F); + *p++ = char_for_nibble((link_key[i] >> 0) & 0x0F); + } + *p = 0; + return (char *) link_key_to_str_buffer; +} + +static void link_key_db_init(void){ + log_info("Link Key DB initialized for DCT\n"); +} + +static void link_key_db_close(void){ +} + +// @return valid +static int link_key_read(int index, link_key_nvm_t * out_entry){ + + // calculate address + uint32_t address = index * sizeof(link_key_nvm_t); + + // read lock + link_key_nvm_t * entry; + wiced_dct_read_lock((void*) &entry, WICED_FALSE, DCT_APP_SECTION, address, sizeof(link_key_nvm_t)); + + if (entry->magic == LINK_KEY_MAGIC){ + memcpy(out_entry, entry, sizeof(link_key_nvm_t)); + } else { + memset(out_entry, 0, sizeof(link_key_nvm_t)); + } + + // read unlock + wiced_dct_read_unlock((void*) entry, WICED_FALSE); + + return out_entry->magic == LINK_KEY_MAGIC; +} + +static void link_key_write(int index, link_key_nvm_t * entry){ + // calculate address + uint32_t address = index * sizeof(link_key_nvm_t); + // write block + wiced_dct_write((void*)entry, DCT_APP_SECTION, address, sizeof(link_key_nvm_t)); +} + +// returns entry index or -1 +static int link_key_find_entry_for_address(bd_addr_t address){ + link_key_nvm_t item; + int i; + for (i=0;i not found\n", bd_addr_to_str(bd_addr)); + return 0; + } + link_key_nvm_t item; + link_key_read(index, &item); + memcpy(link_key, item.link_key, LINK_KEY_LEN); + if (link_key_type) { + *link_key_type = item.link_key_type; + } + log_info("link_key_db_get_link_key for %s -> found %s\n", bd_addr_to_str(bd_addr), link_key_to_str(link_key)); + return 1; +} + +static void link_key_db_delete_link_key(bd_addr_t bd_addr){ + int index = link_key_find_entry_for_address(bd_addr); + if (index < 0) return; + + link_key_nvm_t item; + memset(&item, 0, sizeof(item)); + link_key_write(index, &item); +} + + +static void link_key_db_put_link_key(bd_addr_t bd_addr, link_key_t link_key, link_key_type_t link_key_type){ + // check for existing record + int index = link_key_find_entry_for_address(bd_addr); + + // if not found, use new entry + if (index < 0) { + index = link_key_find_free_entry(); + } + + log_info("link_key_db_put_link_key for %s - key %s - at index %u\n", bd_addr_to_str(bd_addr), link_key_to_str(link_key), index); + + link_key_nvm_t item; + item.magic = LINK_KEY_MAGIC; + item.seq_nr = link_key_highest_seq_nr() + 1; + memcpy(item.bd_addr, bd_addr, sizeof(bd_addr_t)); + memcpy(item.link_key, link_key, LINK_KEY_LEN); + item.link_key_type = link_key_type; + link_key_write(index, &item); +} + +static void link_key_db_set_local_bd_addr(bd_addr_t bd_addr){ +} + +const btstack_link_key_db_t btstack_link_key_db_wiced_dct = { + link_key_db_init, + link_key_db_set_local_bd_addr, + link_key_db_close, + link_key_db_get_link_key, + link_key_db_put_link_key, + link_key_db_delete_link_key, +}; + +// custom function +void btstack_link_key_db_wiced_dct_delete_all(void){ + int i; + link_key_nvm_t entry; + memset(&entry, 0, sizeof(link_key_nvm_t)); + for (i=0;i // NULL + +#include "btstack_linked_list.h" +#include "btstack_debug.h" +#include "btstack_run_loop.h" +#include "btstack_run_loop_wiced.h" + +typedef struct function_call { + wiced_result_t (*fn)(void * arg); + void * arg; +} function_call_t; + +static const btstack_run_loop_t btstack_run_loop_wiced; + +static wiced_queue_t btstack_run_loop_queue; + +// the run loop +static btstack_linked_list_t timers; + +static uint32_t btstack_run_loop_wiced_get_time_ms(void){ + wiced_time_t time; + wiced_time_get_time(&time); + return time; +} + +// set timer +static void btstack_run_loop_wiced_set_timer(btstack_timer_source_t *ts, uint32_t timeout_in_ms){ + ts->timeout = btstack_run_loop_wiced_get_time_ms() + timeout_in_ms + 1; +} + +/** + * Add timer to run_loop (keep list sorted) + */ +static void btstack_run_loop_wiced_add_timer(btstack_timer_source_t *ts){ + btstack_linked_item_t *it; + for (it = (btstack_linked_item_t *) &timers; it->next ; it = it->next){ + // don't add timer that's already in there + if ((btstack_timer_source_t *) it->next == ts){ + log_error( "btstack_run_loop_timer_add error: timer to add already in list!"); + return; + } + if (ts->timeout < ((btstack_timer_source_t *) it->next)->timeout) { + break; + } + } + ts->item.next = it->next; + it->next = (btstack_linked_item_t *) ts; +} + +/** + * Remove timer from run loop + */ +static int btstack_run_loop_wiced_remove_timer(btstack_timer_source_t *ts){ + return btstack_linked_list_remove(&timers, (btstack_linked_item_t *) ts); +} + +static void btstack_run_loop_wiced_dump_timer(void){ +#ifdef ENABLE_LOG_INFO + btstack_linked_item_t *it; + int i = 0; + for (it = (btstack_linked_item_t *) timers; it ; it = it->next){ + btstack_timer_source_t *ts = (btstack_timer_source_t*) it; + log_info("timer %u, timeout %u\n", i, (unsigned int) ts->timeout); + } +#endif +} + +// schedules execution similar to wiced_rtos_send_asynchronous_event for worker threads +void btstack_run_loop_wiced_execute_code_on_main_thread(wiced_result_t (*fn)(void *arg), void * arg){ + function_call_t message; + message.fn = fn; + message.arg = arg; + wiced_rtos_push_to_queue(&btstack_run_loop_queue, &message, WICED_NEVER_TIMEOUT); +} + +/** + * Execute run_loop + */ +static void btstack_run_loop_wiced_execute(void) { + while (1) { + // get next timeout + uint32_t timeout_ms = WICED_NEVER_TIMEOUT; + if (timers) { + btstack_timer_source_t * ts = (btstack_timer_source_t *) timers; + uint32_t now = btstack_run_loop_wiced_get_time_ms(); + if (ts->timeout < now){ + // remove timer before processing it to allow handler to re-register with run loop + btstack_run_loop_remove_timer(ts); + // printf("RL: timer %p\n", ts->process); + ts->process(ts); + continue; + } + timeout_ms = ts->timeout - now; + } + + // pop function call + function_call_t message = { NULL, NULL }; + wiced_rtos_pop_from_queue( &btstack_run_loop_queue, &message, timeout_ms); + if (message.fn){ + // execute code on run loop + // printf("RL: execute %p\n", message.fn); + message.fn(message.arg); + } + } +} + +static void btstack_run_loop_wiced_btstack_run_loop_init(void){ + timers = NULL; + + // queue to receive events: up to 2 calls from transport, up to 3 for app + wiced_rtos_init_queue(&btstack_run_loop_queue, "BTstack Run Loop", sizeof(function_call_t), 5); +} + +/** + * @brief Provide btstack_run_loop_posix instance for use with btstack_run_loop_init + */ +const btstack_run_loop_t * btstack_run_loop_wiced_get_instance(void){ + return &btstack_run_loop_wiced; +} + +static const btstack_run_loop_t btstack_run_loop_wiced = { + &btstack_run_loop_wiced_btstack_run_loop_init, + NULL, + NULL, + NULL, + NULL, + &btstack_run_loop_wiced_set_timer, + &btstack_run_loop_wiced_add_timer, + &btstack_run_loop_wiced_remove_timer, + &btstack_run_loop_wiced_execute, + &btstack_run_loop_wiced_dump_timer, + &btstack_run_loop_wiced_get_time_ms, +}; diff --git a/port/wiced-h5/btstack_run_loop_wiced.h b/port/wiced-h5/btstack_run_loop_wiced.h new file mode 100644 index 000000000..ae44fbdc2 --- /dev/null +++ b/port/wiced-h5/btstack_run_loop_wiced.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2014 BlueKitchen GmbH + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * 4. Any redistribution, use, or modification is done solely for + * personal benefit and not for any commercial purpose or for + * monetary gain. + * + * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS + * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Please inquire about commercial licensing options at + * contact@bluekitchen-gmbh.com + * + */ + +/* + * btstack_run_loop_wiced.h + * + * Functions relevant for BTstack WICED port + */ + +#ifndef __btstack_run_loop_WICED_H +#define __btstack_run_loop_WICED_H + +#include "btstack_config.h" +#include "btstack_run_loop.h" +#include "wiced.h" + +#if defined __cplusplus +extern "C" { +#endif + +/** + * @brief Provide btstack_run_loop_posix instance for use with btstack_run_loop_init + */ +const btstack_run_loop_t * btstack_run_loop_wiced_get_instance(void); + +/* + * @brief Execute code on BTstack run loop. Can be used to control BTstack from a different thread + */ +void btstack_run_loop_wiced_execute_code_on_main_thread(wiced_result_t (*fn)(void *arg), void * arg); + +/* API_END */ + +#if defined __cplusplus +} +#endif + +#endif // __btstack_run_loop_WICED_H diff --git a/port/wiced-h5/btstack_uart_block_wiced.c b/port/wiced-h5/btstack_uart_block_wiced.c new file mode 100644 index 000000000..64871eb54 --- /dev/null +++ b/port/wiced-h5/btstack_uart_block_wiced.c @@ -0,0 +1,384 @@ +/* + * Copyright (C) 2015 BlueKitchen GmbH + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * 4. Any redistribution, use, or modification is done solely for + * personal benefit and not for any commercial purpose or for + * monetary gain. + * + * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS + * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Please inquire about commercial licensing options at + * contact@bluekitchen-gmbh.com + * + */ + +/* + * hci_h4_transport_wiced.c + * + * HCI Transport API implementation for basic H4 protocol for use with btstack_run_loop_wiced.c + */ + +#define __BTSTACK_FILE__ "hci_transport_h4_wiced.c" + +#include "btstack_config.h" +#include "btstack_run_loop_wiced.h" + +#include "btstack_debug.h" +#include "hci.h" +#include "hci_transport.h" +#include "platform_bluetooth.h" + +#include "wiced.h" + +#include +#include + +// priority higher than WIFI to make sure RTS is set +#define WICED_BT_UART_THREAD_PRIORITY (WICED_NETWORK_WORKER_PRIORITY - 2) +#define WICED_BT_UART_THREAD_STACK_SIZE 300 + +// assert pre-buffer for packet type is available +#if !defined(HCI_OUTGOING_PRE_BUFFER_SIZE) || (HCI_OUTGOING_PRE_BUFFER_SIZE == 0) +#error HCI_OUTGOING_PRE_BUFFER_SIZE not defined. Please update hci.h +#endif + +// Default of 512 bytes should be fine. Only needed with BTSTACK_FLOW_CONTROL_UART +#ifndef RX_RING_BUFFER_SIZE +#define RX_RING_BUFFER_SIZE 512 +#endif + +// Use BTSTACK_FLOW_CONTROL_MANUAL is used when Bluetooth RTS/CTS are not connected to UART RTS/CTS pins +// E.g. on RedBear Duo - WICED_BT_UART_MANUAL_CTS_RTS is defined + +static enum { + BTSTACK_FLOW_CONTROL_OFF, + BTSTACK_FLOW_CONTROL_UART, + BTSTACK_FLOW_CONTROL_MANUAL, +} btstack_flow_control_mode; + +static wiced_result_t btstack_uart_block_wiced_rx_worker_receive_block(void * arg); + +static wiced_worker_thread_t tx_worker_thread; +static const uint8_t * tx_worker_data_buffer; +static uint16_t tx_worker_data_size; + +static wiced_worker_thread_t rx_worker_thread; +static uint8_t * rx_worker_read_buffer; +static uint16_t rx_worker_read_size; + +static wiced_ring_buffer_t rx_ring_buffer; +static uint8_t rx_data[RX_RING_BUFFER_SIZE]; + +// uart config +static const btstack_uart_config_t * uart_config; + +// callbacks +static void (*block_sent)(void); +static void (*block_received)(void); + +// executed on main run loop +static wiced_result_t btstack_uart_block_wiced_main_notify_block_send(void *arg){ + if (block_sent){ + block_sent(); + } + return WICED_SUCCESS; +} + +// executed on main run loop +static wiced_result_t btstack_uart_block_wiced_main_notify_block_read(void *arg){ + if (block_received){ + block_received(); + } + return WICED_SUCCESS; +} + +// executed on tx worker thread +static wiced_result_t btstack_uart_block_wiced_tx_worker_send_block(void * arg){ + // wait for CTS to become low in manual flow control mode + if (btstack_flow_control_mode == BTSTACK_FLOW_CONTROL_MANUAL && wiced_bt_uart_pins[WICED_BT_PIN_UART_CTS]){ + while (platform_gpio_input_get(wiced_bt_uart_pins[WICED_BT_PIN_UART_CTS]) == WICED_TRUE){ + wiced_rtos_delay_milliseconds(10); + } + } + + // blocking send + platform_uart_transmit_bytes(wiced_bt_uart_driver, tx_worker_data_buffer, tx_worker_data_size); + + // let transport know + btstack_run_loop_wiced_execute_code_on_main_thread(&btstack_uart_block_wiced_main_notify_block_send, NULL); + return WICED_SUCCESS; +} + +// executed on rx worker thread +static wiced_result_t btstack_uart_block_wiced_rx_worker_receive_block(void * arg){ + + if (btstack_flow_control_mode == BTSTACK_FLOW_CONTROL_MANUAL && wiced_bt_uart_pins[WICED_BT_PIN_UART_CTS]){ + platform_gpio_output_low(wiced_bt_uart_pins[WICED_BT_PIN_UART_RTS]); + } + +#ifdef WICED_UART_READ_DOES_NOT_RETURN_BYTES_READ + // older API passes in number of bytes to read (checked in 3.3.1 and 3.4.0) + platform_uart_receive_bytes(wiced_bt_uart_driver, rx_worker_read_buffer, rx_worker_read_size, WICED_NEVER_TIMEOUT); +#else + // newer API uses pointer to return number of read bytes + uint32_t bytes = rx_worker_read_size; + platform_uart_receive_bytes(wiced_bt_uart_driver, rx_worker_read_buffer, &bytes, WICED_NEVER_TIMEOUT); + // assumption: bytes = bytes_to_read as timeout is never +#endif + + if (btstack_flow_control_mode == BTSTACK_FLOW_CONTROL_MANUAL && wiced_bt_uart_pins[WICED_BT_PIN_UART_CTS]){ + platform_gpio_output_high(wiced_bt_uart_pins[WICED_BT_PIN_UART_RTS]); + } + + // let transport know + btstack_run_loop_wiced_execute_code_on_main_thread(&btstack_uart_block_wiced_main_notify_block_read, NULL); + return WICED_SUCCESS; +} + +static int btstack_uart_block_wiced_init(const btstack_uart_config_t * config){ + uart_config = config; + + // determine flow control mode based on hardware config and uart config + if (uart_config->flowcontrol){ +#ifdef WICED_BT_UART_MANUAL_CTS_RTS + btstack_flow_control_mode = BTSTACK_FLOW_CONTROL_MANUAL; +#else + btstack_flow_control_mode = BTSTACK_FLOW_CONTROL_UART; +#endif + } else { + btstack_flow_control_mode = BTSTACK_FLOW_CONTROL_OFF; + } + return 0; +} + +static int btstack_uart_block_wiced_open(void){ + + // UART config + wiced_uart_config_t wiced_uart_config = + { + .baud_rate = uart_config->baudrate, + .data_width = DATA_WIDTH_8BIT, + .parity = NO_PARITY, + .stop_bits = STOP_BITS_1, + }; + + if (btstack_flow_control_mode == BTSTACK_FLOW_CONTROL_UART){ + wiced_uart_config.flow_control = FLOW_CONTROL_CTS_RTS; + } else { + wiced_uart_config.flow_control = FLOW_CONTROL_DISABLED; + } + wiced_ring_buffer_t * ring_buffer = NULL; + + // configure HOST and DEVICE WAKE PINs + platform_gpio_init(wiced_bt_control_pins[WICED_BT_PIN_HOST_WAKE], INPUT_HIGH_IMPEDANCE); + platform_gpio_init(wiced_bt_control_pins[WICED_BT_PIN_DEVICE_WAKE], OUTPUT_PUSH_PULL); + platform_gpio_output_low(wiced_bt_control_pins[WICED_BT_PIN_DEVICE_WAKE]); + + /* Configure Reg Enable pin to output. Set to HIGH */ + if (wiced_bt_control_pins[ WICED_BT_PIN_POWER ]){ + platform_gpio_init( wiced_bt_control_pins[ WICED_BT_PIN_POWER ], OUTPUT_OPEN_DRAIN_PULL_UP ); + platform_gpio_output_high( wiced_bt_control_pins[ WICED_BT_PIN_POWER ] ); + } + + wiced_rtos_delay_milliseconds( 100 ); + + // Configure RTS + if (wiced_bt_uart_pins[WICED_BT_PIN_UART_RTS]){ + switch (btstack_flow_control_mode){ + case BTSTACK_FLOW_CONTROL_OFF: + // configure RTS pin as output and set to low - always on + platform_gpio_init(wiced_bt_uart_pins[WICED_BT_PIN_UART_RTS], OUTPUT_PUSH_PULL); + platform_gpio_output_low(wiced_bt_uart_pins[WICED_BT_PIN_UART_RTS]); + break; + case BTSTACK_FLOW_CONTROL_UART: + // configuration done by platform_uart_init + break; + case BTSTACK_FLOW_CONTROL_MANUAL: + // configure RTS pin as output and set to high - controlled by btstack_uart_block_wiced_rx_worker_receive_block + platform_gpio_init(wiced_bt_uart_pins[WICED_BT_PIN_UART_RTS], OUTPUT_PUSH_PULL); + platform_gpio_output_high(wiced_bt_uart_pins[WICED_BT_PIN_UART_RTS]); + break; + } + } + + // Configure CTS + if (wiced_bt_uart_pins[WICED_BT_PIN_UART_CTS]){ + switch (btstack_flow_control_mode){ + case BTSTACK_FLOW_CONTROL_OFF: + // don't care + break; + case BTSTACK_FLOW_CONTROL_UART: + // configuration done by platform_uart_init + break; + case BTSTACK_FLOW_CONTROL_MANUAL: + // configure CTS to input, pull-up + platform_gpio_init(wiced_bt_uart_pins[WICED_BT_PIN_UART_CTS], INPUT_PULL_UP); + break; + } + } + + // use ring buffer to allow to receive RX_RING_BUFFER_SIZE/2 addition bytes - not needed with hardware UART + if (btstack_flow_control_mode != BTSTACK_FLOW_CONTROL_UART){ + ring_buffer_init((wiced_ring_buffer_t *) &rx_ring_buffer, (uint8_t*) rx_data, sizeof( rx_data ) ); + ring_buffer = (wiced_ring_buffer_t *) &rx_ring_buffer; + } + + platform_uart_init( wiced_bt_uart_driver, wiced_bt_uart_peripheral, &wiced_uart_config, ring_buffer ); + + + // Reset Bluetooth via RESET line. Fallback to toggling POWER otherwise + if ( wiced_bt_control_pins[ WICED_BT_PIN_RESET ]){ + platform_gpio_init( wiced_bt_control_pins[ WICED_BT_PIN_RESET ], OUTPUT_PUSH_PULL ); + platform_gpio_output_high( wiced_bt_control_pins[ WICED_BT_PIN_RESET ] ); + + platform_gpio_output_low( wiced_bt_control_pins[ WICED_BT_PIN_RESET ] ); + wiced_rtos_delay_milliseconds( 100 ); + platform_gpio_output_high( wiced_bt_control_pins[ WICED_BT_PIN_RESET ] ); + } + else if ( wiced_bt_control_pins[ WICED_BT_PIN_POWER ]){ + platform_gpio_output_low( wiced_bt_control_pins[ WICED_BT_PIN_POWER ] ); + wiced_rtos_delay_milliseconds( 100 ); + platform_gpio_output_high( wiced_bt_control_pins[ WICED_BT_PIN_POWER ] ); + } + + // wait for Bluetooth to start up + wiced_rtos_delay_milliseconds( 500 ); + + // create worker threads for rx/tx. only single request is posted to their queues + wiced_rtos_create_worker_thread(&tx_worker_thread, WICED_BT_UART_THREAD_PRIORITY, WICED_BT_UART_THREAD_STACK_SIZE, 1); + wiced_rtos_create_worker_thread(&rx_worker_thread, WICED_BT_UART_THREAD_PRIORITY, WICED_BT_UART_THREAD_STACK_SIZE, 1); + + // tx is ready + tx_worker_data_size = 0; + return 0; +} + +static int btstack_uart_block_wiced_close(void){ + // not implemented + return 0; +} + +static void btstack_uart_block_wiced_set_block_received( void (*block_handler)(void)){ + block_received = block_handler; +} + +static void btstack_uart_block_wiced_set_block_sent( void (*block_handler)(void)){ + block_sent = block_handler; +} + +static int btstack_uart_block_wiced_set_baudrate(uint32_t baudrate){ + +#if defined(_STM32F205RGT6_) || defined(STM32F40_41xxx) + + // directly use STM peripheral functions to change baud rate dynamically + + // set TX to high + log_info("set baud %u", (int) baudrate); + const platform_gpio_t* gpio = wiced_bt_uart_pins[WICED_BT_PIN_UART_TX]; + platform_gpio_output_high(gpio); + + // reconfigure TX pin as GPIO + GPIO_InitTypeDef gpio_init_structure; + gpio_init_structure.GPIO_Speed = GPIO_Speed_50MHz; + gpio_init_structure.GPIO_Mode = GPIO_Mode_OUT; + gpio_init_structure.GPIO_OType = GPIO_OType_PP; + gpio_init_structure.GPIO_PuPd = GPIO_PuPd_NOPULL; + gpio_init_structure.GPIO_Pin = (uint32_t) ( 1 << gpio->pin_number ); + GPIO_Init( gpio->port, &gpio_init_structure ); + + // disable USART + USART_Cmd( wiced_bt_uart_peripheral->port, DISABLE ); + + // setup init structure + USART_InitTypeDef uart_init_structure; + uart_init_structure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; + uart_init_structure.USART_BaudRate = baudrate; + uart_init_structure.USART_WordLength = USART_WordLength_8b; + uart_init_structure.USART_StopBits = USART_StopBits_1; + uart_init_structure.USART_Parity = USART_Parity_No; + + if (btstack_flow_control_mode == BTSTACK_FLOW_CONTROL_UART){ + uart_init_structure.USART_HardwareFlowControl = USART_HardwareFlowControl_RTS_CTS; + } else { + uart_init_structure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; + } + USART_Init(wiced_bt_uart_peripheral->port, &uart_init_structure); + + // enable USART again + USART_Cmd( wiced_bt_uart_peripheral->port, ENABLE ); + + // set TX pin as USART again + gpio_init_structure.GPIO_Mode = GPIO_Mode_AF; + GPIO_Init( gpio->port, &gpio_init_structure ); + +#else + log_error("btstack_uart_block_wiced_set_baudrate not implemented for this WICED Platform"); +#endif + return 0; +} + +static int btstack_uart_block_wiced_set_parity(int parity){ + log_error("btstack_uart_block_wiced_set_parity not implemented"); + return 0; +} + +static void btstack_uart_block_wiced_send_block(const uint8_t *buffer, uint16_t length){ + // store in request + tx_worker_data_buffer = buffer; + tx_worker_data_size = length; + wiced_rtos_send_asynchronous_event(&tx_worker_thread, &btstack_uart_block_wiced_tx_worker_send_block, NULL); +} + +static void btstack_uart_block_wiced_receive_block(uint8_t *buffer, uint16_t len){ + rx_worker_read_buffer = buffer; + rx_worker_read_size = len; + wiced_rtos_send_asynchronous_event(&rx_worker_thread, &btstack_uart_block_wiced_rx_worker_receive_block, NULL); +} + + +// static void btstack_uart_block_wiced_set_sleep(uint8_t sleep){ +// } +// static void btstack_uart_block_wiced_set_csr_irq_handler( void (*csr_irq_handler)(void)){ +// } + +static const btstack_uart_block_t btstack_uart_block_wiced = { + /* int (*init)(hci_transport_config_uart_t * config); */ &btstack_uart_block_wiced_init, + /* int (*open)(void); */ &btstack_uart_block_wiced_open, + /* int (*close)(void); */ &btstack_uart_block_wiced_close, + /* void (*set_block_received)(void (*handler)(void)); */ &btstack_uart_block_wiced_set_block_received, + /* void (*set_block_sent)(void (*handler)(void)); */ &btstack_uart_block_wiced_set_block_sent, + /* int (*set_baudrate)(uint32_t baudrate); */ &btstack_uart_block_wiced_set_baudrate, + /* int (*set_parity)(int parity); */ &btstack_uart_block_wiced_set_parity, + /* void (*receive_block)(uint8_t *buffer, uint16_t len); */ &btstack_uart_block_wiced_receive_block, + /* void (*send_block)(const uint8_t *buffer, uint16_t length); */ &btstack_uart_block_wiced_send_block, + /* int (*get_supported_sleep_modes); */ NULL, + /* void (*set_sleep)(btstack_uart_sleep_mode_t sleep_mode); */ NULL, + /* void (*set_wakeup_handler)(void (*handler)(void)); */ NULL, +}; + +const btstack_uart_block_t * btstack_uart_block_wiced_instance(void){ + return &btstack_uart_block_wiced; +} \ No newline at end of file diff --git a/port/wiced-h5/create_examples.py b/port/wiced-h5/create_examples.py new file mode 100755 index 000000000..0bd4bd6d8 --- /dev/null +++ b/port/wiced-h5/create_examples.py @@ -0,0 +1,92 @@ +#!/usr/bin/env python +# +# Create project files for all BTstack embedded examples in WICED/apps/btstack + +import os +import shutil +import sys +import time +import subprocess + +mk_template = '''# +# BTstack example 'EXAMPLE' for WICED port +# +# Generated by TOOL +# On DATE + +NAME := EXAMPLE + +GLOBAL_INCLUDES += . + +$(NAME)_SOURCES := ../../../libraries/btstack/example/EXAMPLE.c +$(NAME)_COMPONENTS += btstack/port/wiced +$(NAME)_CFLAGS += ADDITIONAL_CFLAGS +''' + +gatt_update_template = '''#!/bin/sh +DIR=`dirname $0` +BTSTACK_ROOT=$DIR/../../../libraries/btstack +echo "Creating EXAMPLE.h from EXAMPLE.gatt" +$BTSTACK_ROOT/tool/compile_gatt.py $BTSTACK_ROOT/example/EXAMPLE.gatt $DIR/EXAMPLE.h +''' + +# get script path +script_path = os.path.abspath(os.path.dirname(sys.argv[0])) + +# validate WICED root by reading version.txt +wiced_root = script_path + "/../../../../" +wiced_version = "" +try: + with open(wiced_root + 'version.txt', 'r') as fin: + wiced_version = fin.read() # Read the contents of the file into memory. +except: + pass +if not "WICED Version" in wiced_version: + print("Cannot find WICED root. Make sure BTstack is checked out in WICED-SDK-X/libraries") + sys.exit(1) + +# show WICED version +wiced_version = wiced_version.split()[2] +print("Found WICED SDK version: %s" % wiced_version) + +additional_cflags = "" +if wiced_version < "3.4.0": + print("Adding WICED_UART_READ_DOES_NOT_RETURN_BYTES_READ for SDK < 3.4.0") + additional_cflags = "-DWICED_UART_READ_DOES_NOT_RETURN_BYTES_READ" + + +# path to examples +examples_embedded = script_path + "/../../example/" + +# path to WICED/apps/btstack +apps_btstack = wiced_root + "/apps/btstack/" + +print("Creating examples in apps/btstack:") + +# iterate over btstack examples +for file in os.listdir(examples_embedded): + if not file.endswith(".c"): + continue + example = file[:-2] + + # create folder + apps_folder = apps_btstack + example + "/" + if not os.path.exists(apps_folder): + os.makedirs(apps_folder) + + # create .mk file + with open(apps_folder + example + ".mk", "wt") as fout: + fout.write(mk_template.replace("EXAMPLE", example).replace("TOOL", script_path).replace("ADDITIONAL_CFLAGS", additional_cflags).replace("DATE",time.strftime("%c"))) + + # create update_gatt.sh if .gatt file is present + gatt_path = examples_embedded + example + ".gatt" + if os.path.exists(gatt_path): + update_gatt_script = apps_folder + "update_gatt_db.sh" + with open(update_gatt_script, "wt") as fout: + fout.write(gatt_update_template.replace("EXAMPLE", example)) + os.chmod(update_gatt_script, 0o755) + subprocess.call(update_gatt_script + "> /dev/null", shell=True) + print("- %s including compiled GATT DB" % example) + else: + print("- %s" % example) + diff --git a/port/wiced-h5/hci_transport_h4_wiced.c b/port/wiced-h5/hci_transport_h4_wiced.c new file mode 100644 index 000000000..6d1671aae --- /dev/null +++ b/port/wiced-h5/hci_transport_h4_wiced.c @@ -0,0 +1,378 @@ +/* + * Copyright (C) 2015 BlueKitchen GmbH + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * 4. Any redistribution, use, or modification is done solely for + * personal benefit and not for any commercial purpose or for + * monetary gain. + * + * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS + * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Please inquire about commercial licensing options at + * contact@bluekitchen-gmbh.com + * + */ + +/* + * hci_h4_transport_wiced.c + * + * HCI Transport API implementation for basic H4 protocol for use with btstack_run_loop_wiced.c + */ + +#define __BTSTACK_FILE__ "hci_transport_h4_wiced.c" + +#include "btstack_config.h" +#include "btstack_run_loop_wiced.h" + +#include "btstack_debug.h" +#include "hci.h" +#include "hci_transport.h" +#include "platform_bluetooth.h" + +#include "wiced.h" + +#include +#include + +// priority higher than WIFI to make sure RTS is set +#define WICED_BT_UART_THREAD_PRIORITY (WICED_NETWORK_WORKER_PRIORITY - 2) +#define WICED_BT_UART_THREAD_STACK_SIZE 300 + +// assert pre-buffer for packet type is available +#if !defined(HCI_OUTGOING_PRE_BUFFER_SIZE) || (HCI_OUTGOING_PRE_BUFFER_SIZE == 0) +#error HCI_OUTGOING_PRE_BUFFER_SIZE not defined. Please update hci.h +#endif + +/* Default of 512 bytes should be fine. Only needed if WICED_BT_UART_MANUAL_CTS_RTS */ +#ifndef RX_RING_BUFFER_SIZE +#define RX_RING_BUFFER_SIZE 512 +#endif + + +static wiced_result_t h4_rx_worker_receive_packet(void * arg); +static void dummy_handler(uint8_t packet_type, uint8_t *packet, uint16_t size); + +typedef struct hci_transport_h4 { + hci_transport_t transport; + btstack_data_source_t *ds; + int uart_fd; // different from ds->fd for HCI reader thread + /* power management support, e.g. used by iOS */ + btstack_timer_source_t sleep_timer; +} hci_transport_h4_t; + +// single instance +static hci_transport_h4_t * hci_transport_h4 = NULL; +static hci_transport_config_uart_t * hci_transport_config_uart = NULL; + +static void (*packet_handler)(uint8_t packet_type, uint8_t *packet, uint16_t size) = dummy_handler; + +static wiced_worker_thread_t tx_worker_thread; +static const uint8_t * tx_worker_data_buffer; +static uint16_t tx_worker_data_size; + +static wiced_worker_thread_t rx_worker_thread; +static int rx_worker_read_pos; + +static uint8_t hci_packet_with_pre_buffer[HCI_INCOMING_PRE_BUFFER_SIZE + 1 + HCI_PACKET_BUFFER_SIZE]; // packet type + max(acl header + acl payload, event header + event data) +static uint8_t * hci_packet = &hci_packet_with_pre_buffer[HCI_INCOMING_PRE_BUFFER_SIZE]; + +#ifdef WICED_BT_UART_MANUAL_CTS_RTS +static volatile wiced_ring_buffer_t rx_ring_buffer; +static volatile uint8_t rx_data[RX_RING_BUFFER_SIZE]; +#endif + +// executed on main run loop +static wiced_result_t h4_main_deliver_packet(void *arg){ + // deliver packet + packet_handler(hci_packet[0], &hci_packet[1], rx_worker_read_pos-1); + // trigger receive of next packet + wiced_rtos_send_asynchronous_event(&rx_worker_thread, &h4_rx_worker_receive_packet, NULL); + return WICED_SUCCESS; +} + +// executed on main run loop +static wiced_result_t h4_main_notify_packet_send(void *arg){ + // prepare for next packet + tx_worker_data_size = 0; + // notify upper stack that it might be possible to send again + uint8_t event[] = { HCI_EVENT_TRANSPORT_PACKET_SENT, 0}; + packet_handler(HCI_EVENT_PACKET, &event[0], sizeof(event)); + return WICED_SUCCESS; +} + +// executed on rx worker thread + +static void h4_rx_worker_receive_bytes(int bytes_to_read){ + +#ifdef WICED_UART_READ_DOES_NOT_RETURN_BYTES_READ + // older API passes in number of bytes to read (checked in 3.3.1 and 3.4.0) + platform_uart_receive_bytes(wiced_bt_uart_driver, &hci_packet[rx_worker_read_pos], bytes_to_read, WICED_NEVER_TIMEOUT); +#else + // newer API uses pointer to return number of read bytes + uint32_t bytes = bytes_to_read; + platform_uart_receive_bytes(wiced_bt_uart_driver, &hci_packet[rx_worker_read_pos], &bytes, WICED_NEVER_TIMEOUT); + // assumption: bytes = bytes_to_rad as timeout is never +#endif + rx_worker_read_pos += bytes_to_read; + +} + +static wiced_result_t h4_rx_worker_receive_packet(void * arg){ + +#ifdef WICED_BT_UART_MANUAL_CTS_RTS + platform_gpio_output_low(wiced_bt_uart_pins[WICED_BT_PIN_UART_RTS]); +#endif + + while (1){ + rx_worker_read_pos = 0; + h4_rx_worker_receive_bytes(1); + switch (hci_packet[0]){ + case HCI_EVENT_PACKET: + h4_rx_worker_receive_bytes(HCI_EVENT_HEADER_SIZE); + h4_rx_worker_receive_bytes(hci_packet[2]); + break; + case HCI_ACL_DATA_PACKET: + h4_rx_worker_receive_bytes(HCI_ACL_HEADER_SIZE); + h4_rx_worker_receive_bytes(little_endian_read_16( hci_packet, 3)); + break; + case HCI_SCO_DATA_PACKET: + h4_rx_worker_receive_bytes(HCI_SCO_HEADER_SIZE); + h4_rx_worker_receive_bytes(hci_packet[3]); + break; + default: + // try again + log_error("h4_rx_worker_receive_packet: invalid packet type 0x%02x", hci_packet[0]); + continue; + } + +#ifdef WICED_BT_UART_MANUAL_CTS_RTS + platform_gpio_output_high(wiced_bt_uart_pins[WICED_BT_PIN_UART_RTS]); +#endif + + // deliver packet on main thread + btstack_run_loop_wiced_execute_code_on_main_thread(&h4_main_deliver_packet, NULL); + return WICED_SUCCESS; + } +} + +// executed on tx worker thread +static wiced_result_t h4_tx_worker_send_packet(void * arg){ +#ifdef WICED_BT_UART_MANUAL_CTS_RTS + while (platform_gpio_input_get(wiced_bt_uart_pins[WICED_BT_PIN_UART_CTS]) == WICED_TRUE){ + wiced_rtos_delay_milliseconds(100); + } +#endif + // blocking send + platform_uart_transmit_bytes(wiced_bt_uart_driver, tx_worker_data_buffer, tx_worker_data_size); + // let stack know + btstack_run_loop_wiced_execute_code_on_main_thread(&h4_main_notify_packet_send, NULL); + return WICED_SUCCESS; +} + +static int h4_set_baudrate(uint32_t baudrate){ + +#if defined(_STM32F205RGT6_) || defined(STM32F40_41xxx) + + // directly use STM peripheral functions to change baud rate dynamically + + // set TX to high + log_info("h4_set_baudrate %u", (int) baudrate); + const platform_gpio_t* gpio = wiced_bt_uart_pins[WICED_BT_PIN_UART_TX]; + platform_gpio_output_high(gpio); + + // reconfigure TX pin as GPIO + GPIO_InitTypeDef gpio_init_structure; + gpio_init_structure.GPIO_Speed = GPIO_Speed_50MHz; + gpio_init_structure.GPIO_Mode = GPIO_Mode_OUT; + gpio_init_structure.GPIO_OType = GPIO_OType_PP; + gpio_init_structure.GPIO_PuPd = GPIO_PuPd_NOPULL; + gpio_init_structure.GPIO_Pin = (uint32_t) ( 1 << gpio->pin_number ); + GPIO_Init( gpio->port, &gpio_init_structure ); + + // disable USART + USART_Cmd( wiced_bt_uart_peripheral->port, DISABLE ); + + // setup init structure + USART_InitTypeDef uart_init_structure; + uart_init_structure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; + uart_init_structure.USART_BaudRate = baudrate; + uart_init_structure.USART_WordLength = USART_WordLength_8b; + uart_init_structure.USART_StopBits = USART_StopBits_1; + uart_init_structure.USART_Parity = USART_Parity_No; + uart_init_structure.USART_HardwareFlowControl = USART_HardwareFlowControl_RTS_CTS; +#ifdef WICED_BT_UART_MANUAL_CTS_RTS + uart_init_structure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; +#endif + USART_Init(wiced_bt_uart_peripheral->port, &uart_init_structure); + + // enable USART again + USART_Cmd( wiced_bt_uart_peripheral->port, ENABLE ); + + // set TX pin as USART again + gpio_init_structure.GPIO_Mode = GPIO_Mode_AF; + GPIO_Init( gpio->port, &gpio_init_structure ); + +#else + log_error("h4_set_baudrate not implemented for this WICED Platform"); +#endif + return 0; +} + +static void h4_init(const void * transport_config){ + // check for hci_transport_config_uart_t + if (!transport_config) { + log_error("hci_transport_h4_wiced: no config!"); + return; + } + if (((hci_transport_config_t*)transport_config)->type != HCI_TRANSPORT_CONFIG_UART) { + log_error("hci_transport_h4_wiced: config not of type != HCI_TRANSPORT_CONFIG_UART!"); + return; + } + hci_transport_config_uart = (hci_transport_config_uart_t*) transport_config; +} + +static int h4_open(void){ + + // UART config + wiced_uart_config_t uart_config = + { + .baud_rate = 115200, + .data_width = DATA_WIDTH_8BIT, + .parity = NO_PARITY, + .stop_bits = STOP_BITS_1, + .flow_control = FLOW_CONTROL_CTS_RTS, + }; + wiced_ring_buffer_t * ring_buffer = NULL; + + // configure HOST and DEVICE WAKE PINs + platform_gpio_init(wiced_bt_control_pins[WICED_BT_PIN_HOST_WAKE], INPUT_HIGH_IMPEDANCE); + platform_gpio_init(wiced_bt_control_pins[WICED_BT_PIN_DEVICE_WAKE], OUTPUT_PUSH_PULL); + platform_gpio_output_low(wiced_bt_control_pins[WICED_BT_PIN_DEVICE_WAKE]); + + /* Configure Reg Enable pin to output. Set to HIGH */ + if (wiced_bt_control_pins[ WICED_BT_PIN_POWER ]){ + platform_gpio_init( wiced_bt_control_pins[ WICED_BT_PIN_POWER ], OUTPUT_OPEN_DRAIN_PULL_UP ); + platform_gpio_output_high( wiced_bt_control_pins[ WICED_BT_PIN_POWER ] ); + } + + wiced_rtos_delay_milliseconds( 100 ); + + // -- init UART +#ifdef WICED_BT_UART_MANUAL_CTS_RTS + // configure RTS pin as output and set to high + platform_gpio_init(wiced_bt_uart_pins[WICED_BT_PIN_UART_RTS], OUTPUT_PUSH_PULL); + platform_gpio_output_high(wiced_bt_uart_pins[WICED_BT_PIN_UART_RTS]); + + // configure CTS to input, pull-up + platform_gpio_init(wiced_bt_uart_pins[WICED_BT_PIN_UART_CTS], INPUT_PULL_UP); + + // use ring buffer to allow to receive RX_RING_BUFFER_SIZE/2 addition bytes before raising RTS + // casts avoid warnings because of volatile qualifier + ring_buffer_init((wiced_ring_buffer_t *) &rx_ring_buffer, (uint8_t*) rx_data, sizeof( rx_data ) ); + ring_buffer = (wiced_ring_buffer_t *) &rx_ring_buffer; + + // don't try + uart_config.flow_control = FLOW_CONTROL_DISABLED; +#endif + platform_uart_init( wiced_bt_uart_driver, wiced_bt_uart_peripheral, &uart_config, ring_buffer ); + + + // Reset Bluetooth via RESET line. Fallback to toggling POWER otherwise + if ( wiced_bt_control_pins[ WICED_BT_PIN_RESET ]){ + platform_gpio_init( wiced_bt_control_pins[ WICED_BT_PIN_RESET ], OUTPUT_PUSH_PULL ); + platform_gpio_output_high( wiced_bt_control_pins[ WICED_BT_PIN_RESET ] ); + + platform_gpio_output_low( wiced_bt_control_pins[ WICED_BT_PIN_RESET ] ); + wiced_rtos_delay_milliseconds( 100 ); + platform_gpio_output_high( wiced_bt_control_pins[ WICED_BT_PIN_RESET ] ); + } + else if ( wiced_bt_control_pins[ WICED_BT_PIN_POWER ]){ + platform_gpio_output_low( wiced_bt_control_pins[ WICED_BT_PIN_POWER ] ); + wiced_rtos_delay_milliseconds( 100 ); + platform_gpio_output_high( wiced_bt_control_pins[ WICED_BT_PIN_POWER ] ); + } + + // wait for Bluetooth to start up + wiced_rtos_delay_milliseconds( 500 ); + + // create worker threads for rx/tx. only single request is posted to their queues + wiced_rtos_create_worker_thread(&tx_worker_thread, WICED_BT_UART_THREAD_PRIORITY, WICED_BT_UART_THREAD_STACK_SIZE, 1); + wiced_rtos_create_worker_thread(&rx_worker_thread, WICED_BT_UART_THREAD_PRIORITY, WICED_BT_UART_THREAD_STACK_SIZE, 1); + + // start receiving packet + wiced_rtos_send_asynchronous_event(&rx_worker_thread, &h4_rx_worker_receive_packet, NULL); + + // tx is ready + tx_worker_data_size = 0; + return 0; +} + +static int h4_close(void){ + // not implementd + return 0; +} + +static int h4_send_packet(uint8_t packet_type, uint8_t * data, int size){ + // store packet type before actual data and increase size + size++; + data--; + *data = packet_type; + + // store in request + tx_worker_data_buffer = data; + tx_worker_data_size = size; + // send packet as single block + wiced_rtos_send_asynchronous_event(&tx_worker_thread, &h4_tx_worker_send_packet, NULL); + return 0; +} + +static void h4_register_packet_handler(void (*handler)(uint8_t packet_type, uint8_t *packet, uint16_t size)){ + packet_handler = handler; +} + +static int h4_can_send_packet_now(uint8_t packet_type){ + return tx_worker_data_size == 0; +} + +static void dummy_handler(uint8_t packet_type, uint8_t *packet, uint16_t size){ +} + +// get h4 singleton +const hci_transport_t * hci_transport_h4_instance(const btstack_uart_block_t * uart_driver) { + if (hci_transport_h4 == NULL) { + hci_transport_h4 = (hci_transport_h4_t*)malloc( sizeof(hci_transport_h4_t)); + memset(hci_transport_h4, 0, sizeof(hci_transport_h4_t)); + hci_transport_h4->ds = NULL; + hci_transport_h4->transport.name = "H4_WICED"; + hci_transport_h4->transport.init = h4_init; + hci_transport_h4->transport.open = h4_open; + hci_transport_h4->transport.close = h4_close; + hci_transport_h4->transport.register_packet_handler = h4_register_packet_handler; + hci_transport_h4->transport.can_send_packet_now = h4_can_send_packet_now; + hci_transport_h4->transport.send_packet = h4_send_packet; + hci_transport_h4->transport.set_baudrate = h4_set_baudrate; + } + return (const hci_transport_t *) hci_transport_h4; +} diff --git a/port/wiced-h5/main.c b/port/wiced-h5/main.c new file mode 100644 index 000000000..5f4c2e890 --- /dev/null +++ b/port/wiced-h5/main.c @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2015 BlueKitchen GmbH + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * 4. Any redistribution, use, or modification is done solely for + * personal benefit and not for any commercial purpose or for + * monetary gain. + * + * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS + * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Please inquire about commercial licensing options at + * contact@bluekitchen-gmbh.com + * + */ + +#define __BTSTACK_FILE__ "main.c" + +#include "btstack.h" +#include "btstack_chipset_bcm.h" +#include "btstack_chipset_bcm_download_firmware.h" +#include "btstack_run_loop_wiced.h" +#include "btstack_link_key_db_wiced_dct.h" + +#include "generated_mac_address.txt" + +#include "platform_bluetooth.h" +#include "wiced.h" +#include "platform/wwd_platform_interface.h" + +extern int btstack_main(int argc, char ** argv); +extern const btstack_uart_block_t * btstack_uart_block_wiced_instance(void); + +static void phase2(int status); + +// see generated_mac_address.txt - "macaddr=02:0A:F7:3d:76:be" +static const char * wifi_mac_address = NVRAM_GENERATED_MAC_ADDRESS; + +static btstack_packet_callback_registration_t hci_event_callback_registration; + +static btstack_uart_config_t uart_config; + +static const hci_transport_config_uart_t transport_config = { + HCI_TRANSPORT_CONFIG_UART, + 115200, + 200000, // 300000+ didn't work reliably, the 48 MHz UART config might be needed for this + 0, + NULL, +}; + + +static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ + if (packet_type != HCI_EVENT_PACKET) return; + if (hci_event_packet_get_type(packet) != BTSTACK_EVENT_STATE) return; + if (btstack_event_state_get_state(packet) != HCI_STATE_WORKING) return; + printf("BTstack up and running.\n"); +} + +void application_start(void){ + + /* Initialise the WICED device without WLAN */ + wiced_core_init(); + + /* 32 kHz clock also needed for Bluetooth */ + host_platform_init_wlan_powersave_clock(); + + printf("BTstack on WICED\n"); + +#if 0 + // init GPIOs D0-D5 for debugging - not used + wiced_gpio_init(D0, OUTPUT_PUSH_PULL); + wiced_gpio_init(D1, OUTPUT_PUSH_PULL); + wiced_gpio_init(D2, OUTPUT_PUSH_PULL); + wiced_gpio_init(D3, OUTPUT_PUSH_PULL); + wiced_gpio_init(D4, OUTPUT_PUSH_PULL); + wiced_gpio_init(D5, OUTPUT_PUSH_PULL); + + wiced_gpio_output_low(D0); + wiced_gpio_output_low(D1); + wiced_gpio_output_low(D2); + wiced_gpio_output_low(D3); + wiced_gpio_output_low(D4); + wiced_gpio_output_low(D5); +#endif + + // start with BTstack init - especially configure HCI Transport + btstack_memory_init(); + + // enable full log output while porting + // hci_dump_open(NULL, HCI_DUMP_STDOUT); + + // setup run loop + btstack_run_loop_init(btstack_run_loop_wiced_get_instance()); + + // get BCM chipset driver + const btstack_chipset_t * chipset = btstack_chipset_bcm_instance(); + chipset->init(&transport_config); + + // setup uart driver + const btstack_uart_block_t * uart_driver = btstack_uart_block_wiced_instance(); + + // extract UART config from transport config + uart_config.baudrate = transport_config.baudrate_init; + uart_config.flowcontrol = transport_config.flowcontrol; + uart_config.device_name = transport_config.device_name; + uart_driver->init(&uart_config); + + // init HCI + const hci_transport_t * transport = hci_transport_h5_instance(uart_driver); + hci_init(transport, (void*) &transport_config); + hci_set_link_key_db(btstack_link_key_db_wiced_dct_instance()); + hci_set_chipset(chipset); + + // inform about BTstack state + hci_event_callback_registration.callback = &packet_handler; + hci_add_event_handler(&hci_event_callback_registration); + + // use WIFI Mac address + 1 for Bluetooth + bd_addr_t dummy = { 1,2,3,4,5,6}; + sscanf_bd_addr(&wifi_mac_address[8], dummy); + dummy[5]++; + hci_set_bd_addr(dummy); + + // phase #1 download firmware + printf("Phase 1: Download firmware\n"); + + // phase #2 start main app + btstack_chipset_bcm_download_firmware(uart_driver, transport_config.baudrate_main, &phase2); + + // go + btstack_run_loop_execute(); +} + +static void phase2(int status){ + + if (status){ + printf("Download firmware failed\n"); + return; + } + + printf("Phase 2: Main app\n"); + + // setup app + btstack_main(0, NULL); +} diff --git a/port/wiced-h5/readme.md b/port/wiced-h5/readme.md new file mode 100644 index 000000000..5f52e5295 --- /dev/null +++ b/port/wiced-h5/readme.md @@ -0,0 +1,37 @@ +# BTstack port for WICED platform using H5 transport and Broadcom/Cypress Bluetooth chipsets. + +Only tested on Redbear Duo platform. Please install [RedBear WICED Add-On](https://github.com/redbear/WICED-SDK) first. + +To integrate BTstack into the WICED SDK, please move the BTstack project into WICED-SDK-3.5.2/libraries. +Then create projects for BTstack examples in WICED/apps/btstack by running: + + ./create_examples.py + +Now, the BTstack examples can be build from the WICED root in the same way as other examples, e.g.: + + ./make btstack.spp_and_le_counter-RB_DUO + +to build the SPP-and-LE-Counter example for the RedBear Duo. + +See WICED documentation about how to install it. + +It should work with all WICED platforms that contain a Broadcom Bluetooth chipset. + +The maximal baud rate is limited to 2 mbps. + +The port uses the generated WIFI address plus 1 as Bluetooth MAC address. +It stores Classic Link Keys using the DCT mechanism. + +All examples that rovide a GATT Server use the GATT DB in the .gatt file. Therefore you need to run ./update_gatt_db.sh in the apps/btstack/$(EXAMPLE) folder after modifying the .gatt file. + +## Notes on the H5 port + +If the CTR/RTS hardware control lines of the Bluetooth Controller is connected to your MCU, we recommend using the wiced-h4 port instead. +If they are not connected, H5 is required to provide a reliable connecion including retransmissions in both directions. + +There are a few oddities so far that have been worked around in H5 mode: + +- It does not seem possible to upload the FW Mini Driver a.k.a. patchram a.k.a. init script via H5. BTstack uses btstack_chipset_bcm_download_firmware.c to upload the FW Mini Driver via a minimal H4 implementation, before starting up in H5 mode. BCM/CYP chipsets able to switch to H5. + +- With the AP6212A on the RedBear Duo and the FW Mini Driver from WICED-SDK-3.5.2/libraries/drivers/bluetooth/firmware/43438A1/26MHz/bt_firmware_image.c, the HCI LE Encrypt command to perform an AES128 encryption seems to hang in H5 (but works in H4). As a work around, BTstack was configured to use a CPU implementation of AES128 (#define HAVE_AES128). + diff --git a/port/wiced-h5/wiced.mk b/port/wiced-h5/wiced.mk new file mode 100644 index 000000000..936931144 --- /dev/null +++ b/port/wiced-h5/wiced.mk @@ -0,0 +1,70 @@ +# +# BTstack port for WICED framework +# + +ifndef BT_CHIP +$(error BT_CHIP not set - WICED BTstack port only supported with Broadcom Bluetooth chipset) +endif + +NAME := BTstack_for_BCM$(BT_CHIP)$(BT_CHIP_REVISION) + +GLOBAL_INCLUDES += \ + . \ + ../../src \ + ../../platform/embedded \ + ../../chipset/bcm \ + ../../../../ + +# micro-ecc of WICED tree used for SECP256R1 in LE Secure Connections +$(NAME)_COMPONENTS += crypto/micro-ecc + +# core BTstack sources +$(NAME)_SOURCES += \ + ../../src/ad_parser.c \ + ../../src/ble/att_db.c \ + ../../src/ble/att_dispatch.c \ + ../../src/ble/att_server.c \ + ../../src/ble/gatt_client.c \ + ../../src/ble/le_device_db_memory.c \ + ../../src/ble/gatt-service/battery_service_server.c \ + ../../src/ble/sm.c \ + ../../src/classic/hfp.c \ + ../../src/classic/hfp_ag.c \ + ../../src/classic/hfp_hf.c \ + ../../src/classic/hsp_hs.c \ + ../../src/classic/hsp_hs.c \ + ../../src/classic/rfcomm.c \ + ../../src/classic/sdp_server.c \ + ../../src/classic/sdp_client.c \ + ../../src/classic/sdp_client_rfcomm.c \ + ../../src/classic/sdp_util.c \ + ../../src/classic/spp_server.c \ + ../../src/btstack_linked_list.c \ + ../../src/btstack_memory.c \ + ../../src/btstack_memory_pool.c \ + ../../src/btstack_run_loop.c \ + ../../src/btstack_util.c \ + ../../src/btstack_slip.c \ + ../../src/hci.c \ + ../../src/hci_cmd.c \ + ../../src/hci_dump.c \ + ../../src/hci_transport_h5.c \ + ../../src/l2cap.c \ + ../../src/l2cap_signaling.c \ + ../../example/sco_demo_util.c \ + +# WICED port incl. support for Broadcom chipset +$(NAME)_SOURCES += \ + main.c \ + btstack_link_key_db_wiced_dct.c \ + btstack_run_loop_wiced.c \ + btstack_uart_block_wiced.c \ + btstack_aes128_wiced.c \ + ../../chipset/bcm/btstack_chipset_bcm.c \ + ../../chipset/bcm/btstack_chipset_bcm_download_firmware.c \ + +ifeq ($(BT_CHIP_XTAL_FREQUENCY),) +$(NAME)_SOURCES += ../../../drivers/bluetooth/firmware/$(BT_CHIP)$(BT_CHIP_REVISION)/bt_firmware_image.c +else +$(NAME)_SOURCES += ../../../drivers/bluetooth/firmware/$(BT_CHIP)$(BT_CHIP_REVISION)/$(BT_CHIP_XTAL_FREQUENCY)/bt_firmware_image.c +endif