1 /*
2  * Copyright (c) 2025 Arduino SA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <stdint.h>
8 #include <string.h>
9 
10 #include <zephyr/kernel.h>
11 #include "esp_hosted_wifi.h"
12 
13 #include <zephyr/logging/log.h>
14 LOG_MODULE_REGISTER(esp_hosted_hal, CONFIG_WIFI_LOG_LEVEL);
15 
esp_hosted_hal_init(const struct device * dev)16 int esp_hosted_hal_init(const struct device *dev)
17 {
18 	const esp_hosted_config_t *config = dev->config;
19 
20 	if (!spi_is_ready_dt(&config->spi_bus)) {
21 		LOG_ERR("SPI device is not ready");
22 		return -ENODEV;
23 	}
24 
25 	/* Configure pins. */
26 	gpio_pin_configure_dt(&config->dataready_gpio, GPIO_OUTPUT);
27 	gpio_pin_configure_dt(&config->reset_gpio, GPIO_OUTPUT);
28 
29 	/* Perform a hard-reset */
30 	gpio_pin_set_dt(&config->dataready_gpio, 1);
31 	gpio_pin_set_dt(&config->reset_gpio, 0);
32 	k_msleep(100);
33 	gpio_pin_set_dt(&config->reset_gpio, 1);
34 	k_msleep(500);
35 
36 	/* Configure handshake/dataready pins. */
37 	gpio_pin_configure_dt(&config->dataready_gpio, GPIO_INPUT);
38 	gpio_pin_configure_dt(&config->handshake_gpio, GPIO_INPUT);
39 
40 	return 0;
41 }
42 
esp_hosted_hal_data_ready(const struct device * dev)43 bool esp_hosted_hal_data_ready(const struct device *dev)
44 {
45 	const esp_hosted_config_t *config = dev->config;
46 
47 	return gpio_pin_get_dt(&config->dataready_gpio);
48 }
49 
esp_hosted_hal_spi_transfer(const struct device * dev,void * tx,void * rx,uint32_t size)50 int esp_hosted_hal_spi_transfer(const struct device *dev, void *tx, void *rx, uint32_t size)
51 {
52 	int ret = 0;
53 	esp_hosted_data_t *data = dev->data;
54 	const esp_hosted_config_t *config = dev->config;
55 
56 	const struct spi_buf tx_buf = {.buf = tx ? tx : rx, .len = size};
57 	const struct spi_buf_set tx_set = {.buffers = &tx_buf, .count = 1};
58 
59 	const struct spi_buf rx_buf = {.buf = rx ? rx : tx, .len = size};
60 	const struct spi_buf_set rx_set = {.buffers = &rx_buf, .count = 1};
61 
62 	/* Wait for handshake pin to go high. */
63 	for (uint64_t start = k_uptime_get();; k_msleep(1)) {
64 		if (gpio_pin_get_dt(&config->handshake_gpio) &&
65 		    (rx == NULL || gpio_pin_get_dt(&config->dataready_gpio))) {
66 			break;
67 		}
68 		if ((k_uptime_get() - start) >= 100) {
69 			return -ETIMEDOUT;
70 		}
71 	}
72 
73 	if (k_sem_take(&data->bus_sem, K_FOREVER) != 0) {
74 		return -1;
75 	}
76 
77 	/* Transfer SPI buffers. */
78 	if (spi_transceive_dt(&config->spi_bus, &tx_set, &rx_set)) {
79 		LOG_ERR("spi_transceive failed");
80 		ret = -EIO;
81 	}
82 
83 	k_sem_give(&data->bus_sem);
84 	return ret;
85 }
86