Skip to content
Permalink
Browse files

Bluetooth: hci: h4: use GPIO reset for nrf52840_pca10090 controllers

This patch adds support to the nRF9160 for using a dedicated
GPIO pin to reset controllers running on nrf52840_pca10090.

It resets the controller before opening the H4 device, and it
delays the controller from booting until all bytes traveling
to the host have been received and drained from the UART,
thus ensuring that communication can begin from a clean state.

Signed-off-by: Emanuele Di Santo <emdi@nordicsemi.no>
Signed-off-by: Carles Cufi <carles.cufi@nordicsemi.no>
  • Loading branch information...
lemrey authored and carlescufi committed Apr 17, 2019
1 parent bca3deb commit 0db7dda09ddd2047895ac50fc7aa29deccd1b222
@@ -0,0 +1,7 @@
# Copyright (c) 2019 Nordic Semiconductor ASA.
# SPDX-License-Identifier: Apache-2.0

if(CONFIG_BOARD_NRF52840_GPIO_RESET)
zephyr_library()
zephyr_library_sources(nrf52840_reset.c)
endif()
@@ -6,4 +6,23 @@

if BOARD_NRF9160_PCA10090 || BOARD_NRF9160_PCA10090NS

config BOARD_NRF52840_GPIO_RESET
bool "Use nRF52840 PCA10090 GPIO reset pin"
default y if BT_H4
help
Use a GPIO pin to reset the nRF52840 controller and let it wait
until all bytes traveling to the H4 device have been received
and drained, thus ensuring communication can begin correctly.

if BOARD_NRF52840_GPIO_RESET

config BOARD_NRF52840_GPIO_RESET_PIN
int "Reset pin"
range 17 23
default 23
help
GPIO pin on the nRF9160 used to reset the nRF52840.

endif

endif # BOARD_NRF9160_PCA10090 || BOARD_NRF9160_PCA10090NS
@@ -0,0 +1,72 @@
/*
* Copyright (c) 2019 Nordic Semiconductor ASA.
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <gpio.h>
#include <uart.h>
#include <device.h>

#define RESET_PIN CONFIG_BOARD_NRF52840_GPIO_RESET_PIN

/* Must be a pin from 17 to 23.
* Only those can be connected to the nRF52840.
*/
BUILD_ASSERT_MSG(RESET_PIN > 16 && RESET_PIN < 24,
"Selected pin is not connected to nRF52840");

int bt_hci_transport_setup(struct device *h4)
{
int err;
char c;
struct device *port;

port = device_get_binding(DT_GPIO_P0_DEV_NAME);
if (!port) {
return -EIO;
}

/* Pull the pin low before configuring it as output, to ensure that
* it is driven to the correct level as soon as it is configured.
*/
err = gpio_pin_write(port, RESET_PIN, 0);
if (err) {
return err;
}

err = gpio_pin_configure(port, RESET_PIN, GPIO_DIR_OUT);
if (err) {
return err;
}

/* Reset the nRF52840 and let it wait until the pin is
* pulled low again before running to main to ensure
* that it won't send any data until the H4 device
* is setup and ready to receive.
*/
err = gpio_pin_write(port, RESET_PIN, 1);
if (err) {
return err;
}

/* Wait for the nRF52840 peripheral to stop sending data.
*
* It is critical (!) to wait here, so that all bytes
* on the lines are received and drained correctly.
*/
k_sleep(1);

/* Drain bytes */
while (uart_fifo_read(h4, &c, 1)) {
continue;
}

/* We are ready, let the nRF52840 run to main */
err = gpio_pin_write(port, RESET_PIN, 0);
if (err) {
return err;
}

return 0;
}

0 comments on commit 0db7dda

Please sign in to comment.
You can’t perform that action at this time.