drivers: wifi: eswifi: Add uart bus interface
Add uart bus interface to extended esWIFI driver. This enables all Inventek modules with IWIN AT Commands firmware. Signed-off-by: Gerson Fernando Budke <gerson.budke@atl-electronics.com>
This commit is contained in:
parent
f479f60f84
commit
d8c9cb8d89
6 changed files with 295 additions and 2 deletions
|
@ -286,7 +286,7 @@
|
|||
/drivers/watchdog/*gecko* @oanerer
|
||||
/drivers/watchdog/wdt_handlers.c @andrewboie
|
||||
/drivers/wifi/ @jukkar @tbursztyka @pfalcon
|
||||
/drivers/wifi/eswifi/ @loicpoulain
|
||||
/drivers/wifi/eswifi/ @loicpoulain @nandojve
|
||||
/drivers/wifi/winc1500/ @kludentwo
|
||||
/dts/arc/ @abrodkin @ruuddw @iriszzw
|
||||
/dts/arm/atmel/sam4e* @nandojve
|
||||
|
|
|
@ -10,11 +10,13 @@ if(CONFIG_WIFI_ESWIFI)
|
|||
|
||||
zephyr_sources(
|
||||
eswifi_core.c
|
||||
eswifi_bus_spi.c
|
||||
eswifi_offload.c
|
||||
eswifi_socket.c
|
||||
)
|
||||
|
||||
zephyr_sources_ifdef(CONFIG_WIFI_ESWIFI_BUS_SPI eswifi_bus_spi.c)
|
||||
zephyr_sources_ifdef(CONFIG_WIFI_ESWIFI_BUS_UART eswifi_bus_uart.c)
|
||||
|
||||
zephyr_sources_ifdef(CONFIG_WIFI_ESWIFI_SHELL eswifi_shell.c)
|
||||
|
||||
zephyr_sources_ifdef(CONFIG_NET_SOCKETS_OFFLOAD eswifi_socket_offload.c)
|
||||
|
|
|
@ -10,9 +10,24 @@ menuconfig WIFI_ESWIFI
|
|||
select NET_OFFLOAD
|
||||
select NET_SOCKETS
|
||||
select NET_SOCKETS_OFFLOAD
|
||||
select GPIO
|
||||
|
||||
if WIFI_ESWIFI
|
||||
|
||||
choice WIFI_ESWIFI_BUS
|
||||
bool "Select BUS interface"
|
||||
default WIFI_ESWIFI_BUS_SPI
|
||||
|
||||
config WIFI_ESWIFI_BUS_SPI
|
||||
bool "SPI Bus interface"
|
||||
select SPI
|
||||
|
||||
config WIFI_ESWIFI_BUS_UART
|
||||
bool "UART Bus interface"
|
||||
select SERIAL
|
||||
|
||||
endchoice
|
||||
|
||||
config WIFI_ESWIFI_THREAD_PRIO
|
||||
int "esWiFi threads priority"
|
||||
default 2
|
||||
|
|
253
drivers/wifi/eswifi/eswifi_bus_uart.c
Normal file
253
drivers/wifi/eswifi/eswifi_bus_uart.c
Normal file
|
@ -0,0 +1,253 @@
|
|||
/**
|
||||
* Copyright (c) 2018 Linaro
|
||||
* Copyright (c) 2020 ATL Electronics
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#define DT_DRV_COMPAT inventek_eswifi_uart
|
||||
|
||||
#include "eswifi_log.h"
|
||||
LOG_MODULE_DECLARE(LOG_MODULE_NAME);
|
||||
|
||||
#include <zephyr.h>
|
||||
#include <kernel.h>
|
||||
#include <device.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/ring_buffer.h>
|
||||
#include <drivers/gpio.h>
|
||||
#include <drivers/uart.h>
|
||||
|
||||
#include "eswifi.h"
|
||||
|
||||
#define ESWIFI_RING_BUF_SIZE 2048
|
||||
|
||||
enum eswifi_uart_fsm {
|
||||
ESWIFI_UART_FSM_WAIT_CR,
|
||||
ESWIFI_UART_FSM_WAIT_LF,
|
||||
ESWIFI_UART_FSM_WAIT_MARK,
|
||||
ESWIFI_UART_FSM_WAIT_SPACE,
|
||||
ESWIFI_UART_FSM_END,
|
||||
};
|
||||
|
||||
struct eswifi_uart_data {
|
||||
const struct device *dev;
|
||||
enum eswifi_uart_fsm fsm;
|
||||
size_t rx_count;
|
||||
size_t rx_buf_size;
|
||||
char *rx_buf;
|
||||
|
||||
/* RX Ring Buf */
|
||||
uint8_t iface_rb_buf[ESWIFI_RING_BUF_SIZE];
|
||||
struct ring_buf rx_rb;
|
||||
};
|
||||
|
||||
static struct eswifi_uart_data eswifi_uart0; /* Static instance */
|
||||
|
||||
static void eswifi_iface_uart_flush(struct eswifi_uart_data *uart)
|
||||
{
|
||||
uint8_t c;
|
||||
|
||||
while (uart_fifo_read(uart->dev, &c, 1) > 0) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
static void eswifi_iface_uart_isr(const struct device *uart_dev,
|
||||
void *user_data)
|
||||
{
|
||||
struct eswifi_uart_data *uart = &eswifi_uart0; /* Static instance */
|
||||
int rx = 0;
|
||||
uint8_t *dst;
|
||||
uint32_t partial_size = 0;
|
||||
uint32_t total_size = 0;
|
||||
|
||||
ARG_UNUSED(user_data);
|
||||
|
||||
while (uart_irq_update(uart->dev) &&
|
||||
uart_irq_rx_ready(uart->dev)) {
|
||||
if (!partial_size) {
|
||||
partial_size = ring_buf_put_claim(&uart->rx_rb, &dst,
|
||||
UINT32_MAX);
|
||||
}
|
||||
if (!partial_size) {
|
||||
LOG_ERR("Rx buffer doesn't have enough space");
|
||||
eswifi_iface_uart_flush(uart);
|
||||
break;
|
||||
}
|
||||
|
||||
rx = uart_fifo_read(uart->dev, dst, partial_size);
|
||||
if (rx <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
dst += rx;
|
||||
total_size += rx;
|
||||
partial_size -= rx;
|
||||
}
|
||||
|
||||
ring_buf_put_finish(&uart->rx_rb, total_size);
|
||||
}
|
||||
|
||||
static char get_fsm_char(int fsm)
|
||||
{
|
||||
switch (fsm) {
|
||||
case ESWIFI_UART_FSM_WAIT_CR:
|
||||
return('C');
|
||||
case ESWIFI_UART_FSM_WAIT_LF:
|
||||
return('L');
|
||||
case ESWIFI_UART_FSM_WAIT_MARK:
|
||||
return('M');
|
||||
case ESWIFI_UART_FSM_WAIT_SPACE:
|
||||
return('S');
|
||||
case ESWIFI_UART_FSM_END:
|
||||
return('E');
|
||||
}
|
||||
|
||||
return('?');
|
||||
}
|
||||
|
||||
static int eswifi_uart_get_resp(struct eswifi_uart_data *uart)
|
||||
{
|
||||
uint8_t c;
|
||||
|
||||
while (ring_buf_get(&uart->rx_rb, &c, 1) > 0) {
|
||||
LOG_DBG("FSM: %c, RX: 0x%02x : %c",
|
||||
get_fsm_char(uart->fsm), c, c);
|
||||
|
||||
if (uart->rx_buf_size > 0) {
|
||||
uart->rx_buf[uart->rx_count++] = c;
|
||||
|
||||
if (uart->rx_count == uart->rx_buf_size) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
switch (uart->fsm) {
|
||||
case ESWIFI_UART_FSM_WAIT_CR:
|
||||
if (c == '\r') {
|
||||
uart->fsm = ESWIFI_UART_FSM_WAIT_LF;
|
||||
}
|
||||
break;
|
||||
case ESWIFI_UART_FSM_WAIT_LF:
|
||||
if (c == '\n') {
|
||||
uart->fsm = ESWIFI_UART_FSM_WAIT_MARK;
|
||||
} else if (c != '\r') {
|
||||
uart->fsm = ESWIFI_UART_FSM_WAIT_CR;
|
||||
}
|
||||
break;
|
||||
case ESWIFI_UART_FSM_WAIT_MARK:
|
||||
if (c == '>') {
|
||||
uart->fsm = ESWIFI_UART_FSM_WAIT_SPACE;
|
||||
} else if (c == '\r') {
|
||||
uart->fsm = ESWIFI_UART_FSM_WAIT_LF;
|
||||
} else {
|
||||
uart->fsm = ESWIFI_UART_FSM_WAIT_CR;
|
||||
}
|
||||
break;
|
||||
case ESWIFI_UART_FSM_WAIT_SPACE:
|
||||
if (c == ' ') {
|
||||
uart->fsm = ESWIFI_UART_FSM_END;
|
||||
} else if (c == '\r') {
|
||||
uart->fsm = ESWIFI_UART_FSM_WAIT_LF;
|
||||
} else {
|
||||
uart->fsm = ESWIFI_UART_FSM_WAIT_CR;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int eswifi_uart_wait_prompt(struct eswifi_uart_data *uart)
|
||||
{
|
||||
unsigned int max_retries = 60 * 1000; /* 1 minute */
|
||||
int err;
|
||||
|
||||
while (--max_retries) {
|
||||
err = eswifi_uart_get_resp(uart);
|
||||
if (err) {
|
||||
LOG_DBG("Err: 0x%08x - %d", err, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
if (uart->fsm == ESWIFI_UART_FSM_END) {
|
||||
LOG_DBG("Success!");
|
||||
return uart->rx_count;
|
||||
}
|
||||
|
||||
/* allow other threads to be scheduled */
|
||||
k_sleep(K_MSEC(1));
|
||||
}
|
||||
|
||||
LOG_DBG("Timeout");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
static int eswifi_uart_request(struct eswifi_dev *eswifi, char *cmd,
|
||||
size_t clen, char *rsp, size_t rlen)
|
||||
{
|
||||
struct eswifi_uart_data *uart = eswifi->bus_data;
|
||||
int count;
|
||||
int err;
|
||||
|
||||
LOG_DBG("cmd=%p (%u byte), rsp=%p (%u byte)", cmd, clen, rsp, rlen);
|
||||
|
||||
/* Send CMD */
|
||||
for (count = 0; count < clen; count++) {
|
||||
uart_poll_out(uart->dev, cmd[count]);
|
||||
}
|
||||
|
||||
uart->fsm = ESWIFI_UART_FSM_WAIT_CR;
|
||||
uart->rx_count = 0;
|
||||
uart->rx_buf = rsp;
|
||||
uart->rx_buf_size = rlen;
|
||||
|
||||
err = eswifi_uart_wait_prompt(uart);
|
||||
|
||||
if (err > 0) {
|
||||
LOG_HEXDUMP_DBG(uart->rx_buf, uart->rx_count, "Stream");
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int eswifi_uart_init(struct eswifi_dev *eswifi)
|
||||
{
|
||||
struct eswifi_uart_data *uart = &eswifi_uart0; /* Static instance */
|
||||
|
||||
uart->dev = device_get_binding(DT_INST_BUS_LABEL(0));
|
||||
if (!uart->dev) {
|
||||
LOG_ERR("Failed to initialize uart driver");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
eswifi->bus_data = uart;
|
||||
|
||||
uart_irq_rx_disable(uart->dev);
|
||||
uart_irq_tx_disable(uart->dev);
|
||||
eswifi_iface_uart_flush(uart);
|
||||
uart_irq_callback_set(uart->dev, eswifi_iface_uart_isr);
|
||||
uart_irq_rx_enable(uart->dev);
|
||||
|
||||
ring_buf_init(&uart->rx_rb, sizeof(uart->iface_rb_buf),
|
||||
uart->iface_rb_buf);
|
||||
|
||||
LOG_DBG("success");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct eswifi_bus_ops eswifi_bus_ops_uart = {
|
||||
.init = eswifi_uart_init,
|
||||
.request = eswifi_uart_request,
|
||||
};
|
||||
|
||||
struct eswifi_bus_ops *eswifi_get_bus(void)
|
||||
{
|
||||
return &eswifi_bus_ops_uart;
|
||||
}
|
|
@ -4,7 +4,12 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_WIFI_ESWIFI_BUS_UART)
|
||||
#define DT_DRV_COMPAT inventek_eswifi_uart
|
||||
#else
|
||||
#define DT_DRV_COMPAT inventek_eswifi
|
||||
#endif
|
||||
|
||||
#include "eswifi_log.h"
|
||||
LOG_MODULE_REGISTER(LOG_MODULE_NAME);
|
||||
|
||||
|
|
18
dts/bindings/wifi/inventek,eswifi-uart.yaml
Normal file
18
dts/bindings/wifi/inventek,eswifi-uart.yaml
Normal file
|
@ -0,0 +1,18 @@
|
|||
# Copyright (c) 2018, Linaro Limited
|
||||
# Copyright (c) 2020, ATL Electronics
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: es-WiFi module (uart firmware interface)
|
||||
|
||||
compatible: "inventek,eswifi-uart"
|
||||
|
||||
include: uart-device.yaml
|
||||
|
||||
properties:
|
||||
resetn-gpios:
|
||||
type: phandle-array
|
||||
required: true
|
||||
|
||||
wakeup-gpios:
|
||||
type: phandle-array
|
||||
required: false
|
Loading…
Add table
Add a link
Reference in a new issue