1 /*
2  * Copyright (c) 2019 Nordic Semiconductor ASA.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/drivers/gpio.h>
8 #include <zephyr/drivers/uart.h>
9 #include <zephyr/device.h>
10 #include <zephyr/devicetree.h>
11 #include <zephyr/kernel.h>
12 
13 #define RESET_NODE DT_NODELABEL(nrf52840_reset)
14 
15 #if DT_NODE_HAS_STATUS_OKAY(RESET_NODE)
16 
17 #define RESET_GPIO_CTRL  DT_GPIO_CTLR(RESET_NODE, gpios)
18 #define RESET_GPIO_PIN   DT_GPIO_PIN(RESET_NODE, gpios)
19 #define RESET_GPIO_FLAGS DT_GPIO_FLAGS(RESET_NODE, gpios)
20 
bt_hci_transport_setup(const struct device * h4)21 int bt_hci_transport_setup(const struct device *h4)
22 {
23 	int err;
24 	char c;
25 	const struct device *const port = DEVICE_DT_GET(RESET_GPIO_CTRL);
26 
27 	if (!device_is_ready(port)) {
28 		return -EIO;
29 	}
30 
31 	/* Configure pin as output and initialize it to inactive state. */
32 	err = gpio_pin_configure(port, RESET_GPIO_PIN,
33 				 RESET_GPIO_FLAGS | GPIO_OUTPUT_INACTIVE);
34 	if (err) {
35 		return err;
36 	}
37 
38 	/* Reset the nRF52840 and let it wait until the pin is inactive again
39 	 * before running to main to ensure that it won't send any data until
40 	 * the H4 device is setup and ready to receive.
41 	 */
42 	err = gpio_pin_set(port, RESET_GPIO_PIN, 1);
43 	if (err) {
44 		return err;
45 	}
46 
47 	/* Wait for the nRF52840 peripheral to stop sending data.
48 	 *
49 	 * It is critical (!) to wait here, so that all bytes
50 	 * on the lines are received and drained correctly.
51 	 */
52 	k_sleep(K_MSEC(10));
53 
54 	/* Drain bytes */
55 	while (h4 && uart_fifo_read(h4, &c, 1)) {
56 		continue;
57 	}
58 
59 	/* We are ready, let the nRF52840 run to main */
60 	err = gpio_pin_set(port, RESET_GPIO_PIN, 0);
61 	if (err) {
62 		return err;
63 	}
64 
65 	return 0;
66 }
67 
68 #endif /* DT_NODE_HAS_STATUS_OKAY(RESET_NODE) */
69