diff --git a/drivers/wireless/bluetooth/Make.defs b/drivers/wireless/bluetooth/Make.defs index 064ee37337b..367d301ff8d 100644 --- a/drivers/wireless/bluetooth/Make.defs +++ b/drivers/wireless/bluetooth/Make.defs @@ -44,13 +44,16 @@ CSRCS += bt_uart.c ifeq ($(CONFIG_BLUETOOTH_UART_GENERIC),y) CSRCS += bt_uart_generic.c endif +ifeq ($(CONFIG_BLUETOOTH_UART_CC2564),y) +CSRCS += bt_uart_cc2564.c +endif endif ifeq ($(CONFIG_BLUETOOTH_NULL),y) CSRCS += bt_null.c endif -# Include common Bluetooth drvier build support +# Include common Bluetooth driver build support DEPPATH += --dep-path wireless$(DELIM)bluetooth VPATH += :wireless$(DELIM)bluetooth diff --git a/drivers/wireless/bluetooth/bt_uart_cc2564.c b/drivers/wireless/bluetooth/bt_uart_cc2564.c new file mode 100644 index 00000000000..2b8d5a45f74 --- /dev/null +++ b/drivers/wireless/bluetooth/bt_uart_cc2564.c @@ -0,0 +1,226 @@ +/**************************************************************************** + * drivers/wireless/bluetooth/bt_uart_cc2564.c + * CC2564 UART based Bluetooth driver + * + * Copyright (C) 2018 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 THE COPYRIGHT HOLDER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "bt_uart.h" + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* The arrays below do not contain firmware. Find the firmware at ti.com. + * Convert .bts files to C arrays as described there and merge into these + * arrays. + */ + +static const uint8_t ble_firmware[] = +{ +#warning Missing CC2564 ble firmware. + 0 +}; + +static const uint8_t cc256x_firmware[] = +{ +#warning Missing CC2564 bluetooth firmware + 0 +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static int cc2564_send(FAR const struct btuart_lowerhalf_s *lower, + FAR const uint8_t *buf, ssize_t count) +{ + FAR const uint8_t *ptr = buf; + ssize_t nwritten; + + while (count > 0) + { + nwritten = lower->write(lower, ptr, count); + count -= nwritten; + ptr += nwritten; + } + + return 0; +} + +static void cc2564_recv(FAR const struct btuart_lowerhalf_s *lower, + FAR uint8_t *buf, ssize_t count) +{ + FAR uint8_t *ptr = buf; + ssize_t nread; + + while (count > 0) + { + nread = lower->read(lower, ptr, count); + count -= nread; + ptr += nread; + } +} + + +static int cc2564_load(FAR const struct btuart_lowerhalf_s *lower, + FAR const uint8_t *chipdata) +{ + uint8_t buffer[32]; + uint8_t h4_event = 0x04; + uint8_t h4_cmd = 0x01; + uint32_t length = 0; + FAR const uint8_t *data; + + for(data = chipdata; *data++; data += length) + { + uint16_t opcode; + opcode = ((uint16_t)(*(data+1)) << 8) + *data; + + length = data[2] + sizeof(opcode) + sizeof(data[2]); + + cc2564_send(lower, &h4_cmd, 1); + cc2564_send(lower, data, length); + + cc2564_recv(lower, buffer, 1); + if (h4_event == buffer[0]) + { + cc2564_recv(lower, &buffer[1], 2); + cc2564_recv(lower, &buffer[3], buffer[2]); + } + else + { + wlerr("ERROR: Unknown data\n"); + return -EIO; + } + } + + return 0; +} + +int load_cc2564_firmware(FAR const struct btuart_lowerhalf_s *lower) +{ + int ret; + + /* Check for missing firmware */ + + if (sizeof(cc256x_firmware) < 10 || sizeof(ble_firmware) < 10) + { + return -EINVAL; + } + + ret = cc2564_load(lower, cc256x_firmware); + if (ret == 0) + { + ret = cc2564_load(lower, ble_firmware); + } + + return ret; +} + +/**************************************************************************** + * Name: btuart_register + * + * Description: + * Create the UART-based Bluetooth device and register it with the + * Bluetooth stack. + * + * Input Parameters: + * lower - an instance of the lower half driver interface + * + * Returned Value: + * Zero is returned on success; a negated errno value is returned on any + * failure. + * + ****************************************************************************/ + +int btuart_register(FAR const struct btuart_lowerhalf_s *lower) +{ + FAR struct btuart_upperhalf_s *upper; + int ret; + + wlinfo("lower %p\n", lower); + + DEBUGASSERT(lower != NULL); + + /* Allocate a new instance of the upper half driver state structure */ + + upper = (FAR struct btuart_upperhalf_s *) + kmm_zalloc(sizeof(struct btuart_upperhalf_s)); + + if (upper == NULL) + { + wlerr("ERROR: Failed to allocate upper-half state\n"); + return -ENOMEM; + } + + /* Initialize the upper half driver state */ + + upper->dev.head_reserve = H4_HEADER_SIZE; + upper->dev.open = btuart_open; + upper->dev.send = btuart_send; + upper->lower = lower; + + /* Load firmware */ + + ret = load_cc2564_firmware(lower); + if (ret < 0) + { + wlerr("ERROR: Firmware error\n"); + kmm_free(upper); + return -EINVAL; + } + + /* And register the driver with the network and the Bluetooth stack. */ + + ret = bt_netdev_register(&upper->dev); + if (ret < 0) + { + wlerr("ERROR: bt_driver_register failed: %d\n", ret); + kmm_free(upper); + } + + return ret; +} +