diff --git a/arch/arm/src/stm32/stm32_hciuart.c b/arch/arm/src/stm32/stm32_hciuart.c index d52b39c2ed2..294b97be764 100644 --- a/arch/arm/src/stm32/stm32_hciuart.c +++ b/arch/arm/src/stm32/stm32_hciuart.c @@ -54,14 +54,16 @@ #include #include -#include +#include "up_arch.h" +#include "up_internal.h" #include "chip.h" #include "stm32_uart.h" #include "stm32_dma.h" #include "stm32_rcc.h" -#include "up_arch.h" -#include "up_internal.h" +#include "stm32_hciuart.h" + +#include /**************************************************************************** * Pre-processor Definitions @@ -929,6 +931,7 @@ static uint16_t hciuart_rxinuse(const struct hciuart_config_s *config) inuse = (state->rxtail + config->rxbufsize) - state->rxhead; } + wlinfo("inuse %lu\n", (unsigned long)inuse); return inuse; } @@ -956,6 +959,8 @@ static inline void hciuart_rxflow_enable(const struct hciuart_config_s *config) if (inuse >= config->rxupper) { + wlinfo("Enable RTS flow control\n"); + stm32_gpiowrite(config->rts_gpio, true); state->rxflow = true; } @@ -981,10 +986,12 @@ static inline void hciuart_rxflow_disable(const struct hciuart_config_s *config) if (state->rxflow) { - uin16_t inused = hciuart_rxinuse(config); + uint16_t inused = hciuart_rxinuse(config); if (inuse <= config->rxlower) { + wlinfo("Disable RTS flow control\n"); + stm32_gpiowrite(config->rts_gpio, false); state->rxflow = false; } @@ -1129,6 +1136,7 @@ static ssize_t hciuart_copytorxbuffer(const struct hciuart_config_s *config) nxsem_post(&state->rxwait); } + wlinfo("nbytes %ld\n", (long)nbytes); return nbytes; } @@ -1191,6 +1199,8 @@ static ssize_t hciuart_copyfromrxbuffer(const struct hciuart_config_s *config, /* Save the updated Rx buffer head index */ state->rxhead = rxhead; + + wlinfo("nbytes %ld\n", (long)nbytes); return nbytes; } @@ -1248,6 +1258,7 @@ static ssize_t hciuart_copytotxfifo(const struct hciuart_config_s *config) nbytes++; } + wlinfo("nbytes %ld\n", (long)nbytes); return nbytes; } @@ -1280,6 +1291,8 @@ static void hciuart_line_configure(const struct hciuart_config_s *config) uint32_t regval; uint32_t brr; + wlinfo("baud %lu\n", (unsigned long)config->baud); + /* Load CR1 */ regval = hciuart_getreg32(config, STM32_USART_CR1_OFFSET); @@ -1539,6 +1552,8 @@ static int hciuart_configure(const struct hciuart_config_s *config) * was enabled in stm32_lowsetup(). */ + wlinfo("config %p\n", config); + /* Enable USART APB1/2 clock */ hciuart_apbclock_enable(config); @@ -1676,6 +1691,7 @@ static int hciuart_interrupt(int irq, void *context, void *arg) /* Get the masked USART status word. */ status = hciuart_getreg32(config, STM32_USART_SR_OFFSET); + wlinfo("status %08x\n", status); /* USART interrupts: * @@ -1809,6 +1825,8 @@ static void hciuart_rxattach(const struct btuart_lowerhalf_s *lower, struct hciuart_state_s *state; irqstate_t flags; + wlinfo("config %p callback %p arg %p\n", config, callback, arg); + DEBUGASSERT(config != NULL && config->state != NULL); state = config->state; @@ -1864,6 +1882,8 @@ static void hciuart_rxenable(const struct btuart_lowerhalf_s *lower, if (config->rxdmabuffer != NULL) { + wlinfo("config %p enable %u (DMA)\n", config, enable); + /* En/disable DMA reception. * * Note that it is not safe to check for available bytes and immediately @@ -1880,6 +1900,8 @@ static void hciuart_rxenable(const struct btuart_lowerhalf_s *lower, uint32_t intset; irqstate_t flags; + wlinfo("config %p enable %u (non-DMA)\n", config, enable); + /* USART receive interrupts: * * Enable Status Meaning Usage @@ -1940,6 +1962,9 @@ static ssize_t hciuart_read(const struct btuart_lowerhalf_s *lower, ssize_t nbytes; bool rxenable; + wlinfo("config %p buffer %p buflen %lu\n", + config, buffer, (unsigned long)buflen); + /* NOTE: This assumes that the caller has exclusive access to the Rx * buffer, i.e., one lower half instance can server only one upper half! */ @@ -2054,6 +2079,9 @@ static ssize_t hciuart_write(const struct btuart_lowerhalf_s *lower, size_t remaining; irqstate_t flags; + wlinfo("config %p buffer %p buflen %lu\n", + config, buffer, (unsigned long)buflen); + DEBUGASSERT(config != NULL && config->state != NULL); state = config->state; @@ -2183,6 +2211,8 @@ static ssize_t hciuart_rxdrain(const struct btuart_lowerhalf_s *lower) ssize_t nbytes; bool rxenable; + wlinfo("config %p\n"); + DEBUGASSERT(config != NULL && config->state != NULL); state = config->state; @@ -2235,10 +2265,12 @@ static void hciuart_dma_rxcallback(DMA_HANDLE handle, uint8_t status, void *arg) { const struct hciuart_config_s *config = - (const struct hciuart_config_s *)lower; - struct hciuart_state_s *state = config->state; + (const struct hciuart_config_s *)arg; + struct hciuart_state_s *state; ssize_t nbytes; + wlinfo("status %u config %p\n", status, config); + DEBUGASSERT(config != NULL && config->state != NULL); state = config->state; @@ -2377,21 +2409,31 @@ static int hciuart_pm_prepare(struct pm_callback_s *cb, int domain, * Name: hciuart_instantiate * * Description: - * Register serial console and serial ports. This assumes that - * hciuart_initialize was called previously. + * Obtain an instance of the HCI UART interface for the specified HCI UART + * This assumes that hciuart_initialize was called previously. + * + * Input Parameters: + * uart - Identifies the HCI UART to be configured + * + * Returned Value: + * On success, a reference to the HCI UART lower driver for the associated + * U[S]ART * ****************************************************************************/ -const struct btuart_lowerhalf_s *hciuart_instantiate(int uart) +const struct btuart_lowerhalf_s *hciuart_instantiate(enum hciuart_devno_e uart) { const struct hciuart_config_s *config; #ifdef CONFIG_PM int ret; #endif + wlinfo("Instantiating HCIUART%d\n", (int)uart + 1); + DEBUGASSERT((int)uart >= 0 && (int)uart < 8); + /* Check if this uart is available in the configuration */ - config = g_hciuarts[uart]; + config = g_hciuarts[(int)uart]; if (config == NULL) { wlerr("ERROR: UART%d not configured\n", uart + 1); @@ -2406,7 +2448,7 @@ const struct btuart_lowerhalf_s *hciuart_instantiate(int uart) UNUSED(ret); #endif - /* Configure the UART */ + /* Configure and enable the UART */ hciuart_configure(config); return &config->lower; @@ -2416,9 +2458,14 @@ const struct btuart_lowerhalf_s *hciuart_instantiate(int uart) * Name: hciuart_initialize * * Description: - * Performs the low level USART initialization early in debug so that the - * serial console will be available during bootup. This must be called - * after hciuart_instantiate. + * Performs the low-level, one-time USART initialization. This must be + * called before hciuart_instantiate. + * + * Input Paramters: + * None + * + * Returned Value: + * None * ****************************************************************************/ @@ -2438,6 +2485,8 @@ void hciuart_initialize(void) { state = config->state; + wlinfo("Initializing HCIUART%d\n", i + 1); + /* Disable U[S]ART interrupts */ hciuart_disableints(config, HCIUART_ALLINTS); @@ -2474,6 +2523,12 @@ void hciuart_initialize(void) * * This function should be called from a timer or other periodic context. * + * Input Paramters: + * None + * + * Returned Value: + * None + * ****************************************************************************/ #ifdef CONFIG_STM32_HCIUART_RXDMA diff --git a/arch/arm/src/stm32/stm32_hciuart.h b/arch/arm/src/stm32/stm32_hciuart.h new file mode 100644 index 00000000000..17b5c7b307c --- /dev/null +++ b/arch/arm/src/stm32/stm32_hciuart.h @@ -0,0 +1,120 @@ +/**************************************************************************** + * arch/arm/src/stm32/stm32_hciuart.h + * + * 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 NuttX 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 OWNER 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. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32_HCIUART_H +#define __ARCH_ARM_SRC_STM32_HCIUART_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +enum hciuart_devno_e +{ + HCIUART1 = 0, /* HCI UART on STM32 USART1 */ + HCIUART2 = 1, /* HCI UART on STM32 USART2 */ + HCIUART3 = 2, /* HCI UART on STM32 USART3 */ + /* UARTs 4-5 do not support RTS/CTS flow control */ + HCIUART5 = 5, /* HCI UART on STM32 USART6 */ + HCIUART6 = 6, /* HCI UART on STM32 UART7 */ + HCIUART7 = 7 /* HCI UART on STM32 UART8 */ +}; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: hciuart_instantiate + * + * Description: + * Obtain an instance of the HCI UART interface for the specified HCI UART + * This assumes that hciuart_initialize was called previously. + * + * Input Parameters: + * uart - Identifies the HCI UART to be configured + * + * Returned Value: + * On success, a reference to the HCI UART lower driver for the associated + * U[S]ART + * + ****************************************************************************/ + +const struct btuart_lowerhalf_s *hciuart_instantiate(enum hciuart_devno_e uart); + +/**************************************************************************** + * Name: hciuart_initialize + * + * Description: + * Performs the low-level, one-time USART initialization. This must be + * called before hciuart_instantiate. + * + * Input Paramters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void hciuart_initialize(void); + +/**************************************************************************** + * Name: stm32_serial_dma_poll + * + * Description: + * Checks receive DMA buffers for received bytes that have not accumulated + * to the point where the DMA half/full interrupt has triggered. + * + * This function should be called from a timer or other periodic context. + * + * Input Paramters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_HCIUART_RXDMA +void stm32_serial_dma_poll(void); +#endif + +#endif /* __ARCH_ARM_SRC_STM32_HCIUART_H */ diff --git a/configs/stm32f4discovery/src/Makefile b/configs/stm32f4discovery/src/Makefile index 8f8a4b14cea..a3677772636 100644 --- a/configs/stm32f4discovery/src/Makefile +++ b/configs/stm32f4discovery/src/Makefile @@ -1,7 +1,8 @@ ############################################################################ # configs/stm32f4discovery/src/Makefile # -# Copyright (C) 2011-2013, 2015-2016 Gregory Nutt. All rights reserved. +# Copyright (C) 2011-2013, 2015-2016, 2018 Gregory Nutt. All rights +# reserved. # Author: Gregory Nutt # # Redistribution and use in source and binary forms, with or without @@ -164,6 +165,12 @@ ifeq ($(CONFIG_TIMER),y) CSRCS += stm32_timer.c endif +ifeq ($(CONFIG_STM32_HCIUART),y) +ifeq ($(CONFIG_BLUETOOTH_UART),y) +CSRCS += stm32_hciuart.c +endif +endif + ifeq ($(CONFIG_STM32_ROMFS),y) CSRCS += stm32_romfs_initialize.c endif diff --git a/configs/stm32f4discovery/src/stm32_bringup.c b/configs/stm32f4discovery/src/stm32_bringup.c index 97ba5805906..94d54ee7c2a 100644 --- a/configs/stm32f4discovery/src/stm32_bringup.c +++ b/configs/stm32f4discovery/src/stm32_bringup.c @@ -345,6 +345,14 @@ int stm32_bringup(void) } #endif +#ifdef HAVE_HCIUART + ret = hciuart_dev_initialize(); + if (ret < 0) + { + serr("ERROR: Failed to initialize HCI UART driver: %d\n", ret); + } +#endif + #if defined(CONFIG_RNDIS) && defined(CONFIG_NSH_MACADDR) uint8_t mac[6]; mac[0] = 0xaa; /* TODO */ diff --git a/configs/stm32f4discovery/src/stm32_hciuart.c b/configs/stm32f4discovery/src/stm32_hciuart.c new file mode 100644 index 00000000000..f1f5696b866 --- /dev/null +++ b/configs/stm32f4discovery/src/stm32_hciuart.c @@ -0,0 +1,107 @@ +/************************************************************************************ + * configs/stm32f4discovery/src/stm32_xen1210.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Alan Carvalho de Assis + * + * 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 NuttX 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 OWNER 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 "stm32_hciuart.h" +#include "stm32f4discovery.h" + +#include + +#ifdef HAVE_HCIUART + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: hciuart_dev_initialize + * + * Description: + * This function is called by board initialization logic to configure the + * Bluetooth HCI UART driver + * + * Input Parameters: + * None + * + * Returned Value: + * Zero is returned on success. Otherwise, a negated errno value is + * returned to indicate the nature of the failure. + * + ****************************************************************************/ + +int hciuart_dev_initialize(void) +{ + const struct btuart_lowerhalf_s *lower; + int ret; + + /* Perform one-time initialization */ + + hciuart_initialize(); + + /* Instantiate the HCI UART lower half interface */ + + lower = hciuart_instantiate(HCIUART_SERDEV); + if (lower == NULL) + { + wlerr("ERROR: Failed to instantiate HCIUART%d\n", HCIUART_SERDEV + 1); + return -ENODEV; + } + + /* Then iniatialize the HCI UART upper half driver and register it as a + * network device. + */ + + ret = btuart_register(lower); + if (ret < 0) + { + wlerr("ERROR: btuart_register() failed: %d\n", ret); + } + + return ret; +} + +#endif /* HAVE_HCIUART */ diff --git a/configs/stm32f4discovery/src/stm32f4discovery.h b/configs/stm32f4discovery/src/stm32f4discovery.h index 61481079e36..ec195a33adb 100644 --- a/configs/stm32f4discovery/src/stm32f4discovery.h +++ b/configs/stm32f4discovery/src/stm32f4discovery.h @@ -83,6 +83,7 @@ #define HAVE_RTC_DRIVER 1 #define HAVE_ELF 1 #define HAVE_NETMONITOR 1 +#define HAVE_HCIUART 1 /* Can't support USB host or device features if USB OTG FS is not enabled */ @@ -215,6 +216,26 @@ # endif #endif +/* Check if we have the prequisites for an HCI UART */ + +#if !defined(CONFIG_STM32_HCIUART) || !defined(CONFIG_BLUETOOTH_UART) +# undef HAVE_HCIUART +#elif defined(CONFIG_STM32_USART1_HCIUART) +# define HCIUART_SERDEV HCIUART1 +#elif defined(CONFIG_STM32_USART2_HCIUART) +# define HCIUART_SERDEV HCIUART2 +#elif defined(CONFIG_STM32_USART3_HCIUART) +# define HCIUART_SERDEV HCIUART3 +#elif defined(CONFIG_STM32_USART6_HCIUART) +# define HCIUART_SERDEV HCIUART6 +#elif defined(CONFIG_STM32_UART7_HCIUART) +# define HCIUART_SERDEV HCIUART7 +#elif defined(CONFIG_STM32_UART8_HCIUART) +# define HCIUART_SERDEV HCIUART8 +#else +# error No HCI UART specifified +#endif + /* STM32F4 Discovery GPIOs **************************************************/ /* LEDs */ @@ -788,11 +809,13 @@ int stm32_timer_driver_setup(FAR const char *devpath, int timer); * Name: xen1210_archinitialize * * Description: - * This function is called by board initialization logic to configure the - * XEN1210 driver. This function will register the driver as /dev/mag0 + * Each board that supports an xen1210 device must provide this function. + * This function is called by application-specific, setup logic to + * configure the accelerometer device. This function will register the + * driver as /dev/accelN where N is the minor device number. * * Input Parameters: - * None + * minor - The input device minor number * * Returned Value: * Zero is returned on success. Otherwise, a negated errno value is @@ -804,5 +827,25 @@ int stm32_timer_driver_setup(FAR const char *devpath, int timer); int xen1210_archinitialize(int minor); #endif +/**************************************************************************** + * Name: hciuart_dev_initialize + * + * Description: + * This function is called by board initialization logic to configure the + * Bluetooth HCI UART driver + * + * Input Parameters: + * None + * + * Returned Value: + * Zero is returned on success. Otherwise, a negated errno value is + * returned to indicate the nature of the failure. + * + ****************************************************************************/ + +#ifdef HAVE_HCIUART +int hciuart_dev_initialize(void); +#endif + #endif /* __ASSEMBLY__ */ #endif /* __CONFIGS_STM32F4DISCOVERY_SRC_STM32F4DISCOVERY_H */ diff --git a/wireless/bluetooth/bt_hcicore.c b/wireless/bluetooth/bt_hcicore.c index 5cd273df210..f44d3cc9d55 100644 --- a/wireless/bluetooth/bt_hcicore.c +++ b/wireless/bluetooth/bt_hcicore.c @@ -1785,7 +1785,7 @@ void bt_conn_cb_register(FAR struct bt_conn_cb_s *cb) g_callback_list = cb; } -#ifdef CONFIG_DEBUG_WIRELESS_INFO +#ifdef CONFIG_DEBUG_WIRELESS_ERROR FAR const char *bt_addr_str(FAR const bt_addr_t *addr) { static char bufs[2][18]; @@ -1811,4 +1811,4 @@ FAR const char *bt_addr_le_str(FAR const bt_addr_le_t *addr) return str; } -#endif /* CONFIG_DEBUG_WIRELESS_INFO */ +#endif /* CONFIG_DEBUG_WIRELESS_ERROR */ diff --git a/wireless/bluetooth/bt_hcicore.h b/wireless/bluetooth/bt_hcicore.h index 5c4a9c393cf..d8506356cf8 100644 --- a/wireless/bluetooth/bt_hcicore.h +++ b/wireless/bluetooth/bt_hcicore.h @@ -58,19 +58,6 @@ * Pre-processor Definitions ****************************************************************************/ -/* Enabling debug increases stack size requirement considerably */ - -#if defined(CONFIG_DEBUG_WIRELESS_INFO) -# define BT_STACK_DEBUG_EXTRA 512 -#else -# define BT_STACK_DEBUG_EXTRA 0 -#endif - -#define BT_STACK(name, size) \ - char __stack name[(size) + BT_STACK_DEBUG_EXTRA] -#define BT_STACK_NOINIT(name, size) \ - char __noinit __stack name[(size) + BT_STACK_DEBUG_EXTRA] - /* LMP feature helpers */ #define lmp_bredr_capable(dev) (!((dev).features[4] & BT_LMP_NO_BREDR)) @@ -278,7 +265,7 @@ int bt_hci_cmd_send_sync(uint16_t opcode, FAR struct bt_buf_s *buf, * not multi-threading safe */ -#ifdef CONFIG_DEBUG_WIRELESS_INFO +#ifdef CONFIG_DEBUG_WIRELESS_ERROR FAR const char *bt_addr_str(FAR const bt_addr_t *addr); FAR const char *bt_addr_le_str(FAR const bt_addr_le_t *addr); #endif