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/*gecko* @oanerer
|
||||||
/drivers/watchdog/wdt_handlers.c @andrewboie
|
/drivers/watchdog/wdt_handlers.c @andrewboie
|
||||||
/drivers/wifi/ @jukkar @tbursztyka @pfalcon
|
/drivers/wifi/ @jukkar @tbursztyka @pfalcon
|
||||||
/drivers/wifi/eswifi/ @loicpoulain
|
/drivers/wifi/eswifi/ @loicpoulain @nandojve
|
||||||
/drivers/wifi/winc1500/ @kludentwo
|
/drivers/wifi/winc1500/ @kludentwo
|
||||||
/dts/arc/ @abrodkin @ruuddw @iriszzw
|
/dts/arc/ @abrodkin @ruuddw @iriszzw
|
||||||
/dts/arm/atmel/sam4e* @nandojve
|
/dts/arm/atmel/sam4e* @nandojve
|
||||||
|
|
|
@ -10,11 +10,13 @@ if(CONFIG_WIFI_ESWIFI)
|
||||||
|
|
||||||
zephyr_sources(
|
zephyr_sources(
|
||||||
eswifi_core.c
|
eswifi_core.c
|
||||||
eswifi_bus_spi.c
|
|
||||||
eswifi_offload.c
|
eswifi_offload.c
|
||||||
eswifi_socket.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_WIFI_ESWIFI_SHELL eswifi_shell.c)
|
||||||
|
|
||||||
zephyr_sources_ifdef(CONFIG_NET_SOCKETS_OFFLOAD eswifi_socket_offload.c)
|
zephyr_sources_ifdef(CONFIG_NET_SOCKETS_OFFLOAD eswifi_socket_offload.c)
|
||||||
|
|
|
@ -10,9 +10,24 @@ menuconfig WIFI_ESWIFI
|
||||||
select NET_OFFLOAD
|
select NET_OFFLOAD
|
||||||
select NET_SOCKETS
|
select NET_SOCKETS
|
||||||
select NET_SOCKETS_OFFLOAD
|
select NET_SOCKETS_OFFLOAD
|
||||||
|
select GPIO
|
||||||
|
|
||||||
if WIFI_ESWIFI
|
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
|
config WIFI_ESWIFI_THREAD_PRIO
|
||||||
int "esWiFi threads priority"
|
int "esWiFi threads priority"
|
||||||
default 2
|
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
|
* 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
|
#define DT_DRV_COMPAT inventek_eswifi
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "eswifi_log.h"
|
#include "eswifi_log.h"
|
||||||
LOG_MODULE_REGISTER(LOG_MODULE_NAME);
|
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