mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
drivers: add netdev driver for ATWINC15x0 WiFi module
This commit is contained in:
parent
649b315214
commit
660a852935
@ -118,6 +118,16 @@ ifneq (,$(filter ata8520e,$(USEMODULE)))
|
||||
FEATURES_REQUIRED += periph_spi
|
||||
endif
|
||||
|
||||
ifneq (,$(filter atwinc15x0,$(USEMODULE)))
|
||||
USEMODULE += luid
|
||||
USEMODULE += netdev_eth
|
||||
USEMODULE += xtimer
|
||||
USEPKG += driver_atwinc15x0
|
||||
FEATURES_REQUIRED += periph_gpio
|
||||
FEATURES_REQUIRED += periph_gpio_irq
|
||||
FEATURES_REQUIRED += periph_spi
|
||||
endif
|
||||
|
||||
ifneq (,$(filter bh1750fvi,$(USEMODULE)))
|
||||
USEMODULE += xtimer
|
||||
FEATURES_REQUIRED += periph_i2c
|
||||
|
@ -48,6 +48,10 @@ ifneq (,$(filter ata8520e,$(USEMODULE)))
|
||||
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/ata8520e/include
|
||||
endif
|
||||
|
||||
ifneq (,$(filter atwinc15x0,$(USEMODULE)))
|
||||
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/atwinc15x0/include
|
||||
endif
|
||||
|
||||
ifneq (,$(filter bh1750fvi,$(USEMODULE)))
|
||||
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/bh1750fvi/include
|
||||
endif
|
||||
|
1
drivers/atwinc15x0/Makefile
Normal file
1
drivers/atwinc15x0/Makefile
Normal file
@ -0,0 +1 @@
|
||||
include $(RIOTBASE)/Makefile.base
|
98
drivers/atwinc15x0/atwinc15x0_bsp.c
Normal file
98
drivers/atwinc15x0/atwinc15x0_bsp.c
Normal file
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Gunar Schorcht
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup drivers_atwinc15x0
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief RIOT BSP API implementation
|
||||
*
|
||||
* @author Gunar Schorcht <gunar@schorcht.net>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "atwinc15x0_internal.h"
|
||||
#include "mutex.h"
|
||||
#include "periph/spi.h"
|
||||
#include "xtimer.h"
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
void atwinc15x0_isr(void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
if (atwinc15x0->bsp_isr != NULL && atwinc15x0->bsp_irq_enabled) {
|
||||
atwinc15x0->bsp_isr();
|
||||
}
|
||||
atwinc15x0_irq();
|
||||
}
|
||||
|
||||
sint8 nm_bsp_init(void)
|
||||
{
|
||||
assert(atwinc15x0);
|
||||
assert(atwinc15x0->params.reset_pin != GPIO_UNDEF);
|
||||
assert(atwinc15x0->params.irq_pin != GPIO_UNDEF);
|
||||
|
||||
gpio_init(atwinc15x0->params.reset_pin, GPIO_OUT);
|
||||
gpio_set(atwinc15x0->params.reset_pin);
|
||||
|
||||
gpio_init_int(atwinc15x0->params.irq_pin, GPIO_IN_PU, GPIO_FALLING,
|
||||
atwinc15x0_isr, NULL);
|
||||
|
||||
if (atwinc15x0->params.chip_en_pin != GPIO_UNDEF) {
|
||||
gpio_init(atwinc15x0->params.chip_en_pin, GPIO_OUT);
|
||||
gpio_set(atwinc15x0->params.chip_en_pin);
|
||||
}
|
||||
|
||||
if (atwinc15x0->params.wake_pin != GPIO_UNDEF) {
|
||||
gpio_init(atwinc15x0->params.wake_pin, GPIO_OUT);
|
||||
gpio_set(atwinc15x0->params.wake_pin);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
sint8 nm_bsp_deinit(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void nm_bsp_reset(void)
|
||||
{
|
||||
assert(atwinc15x0);
|
||||
gpio_clear(atwinc15x0->params.reset_pin);
|
||||
nm_bsp_sleep(100);
|
||||
gpio_set(atwinc15x0->params.reset_pin);
|
||||
nm_bsp_sleep(100);
|
||||
}
|
||||
|
||||
void nm_bsp_sleep(uint32 u32TimeMsec)
|
||||
{
|
||||
xtimer_usleep(u32TimeMsec * US_PER_MS);
|
||||
}
|
||||
|
||||
void nm_bsp_register_isr(tpfNmBspIsr pfIsr)
|
||||
{
|
||||
assert(atwinc15x0);
|
||||
|
||||
DEBUG("%s %p\n", __func__, pfIsr);
|
||||
|
||||
atwinc15x0->bsp_isr = pfIsr;
|
||||
}
|
||||
|
||||
void nm_bsp_interrupt_ctrl(uint8 u8Enable)
|
||||
{
|
||||
assert(atwinc15x0);
|
||||
|
||||
DEBUG("%s %u\n", __func__, u8Enable);
|
||||
|
||||
atwinc15x0->bsp_irq_enabled = u8Enable;
|
||||
}
|
88
drivers/atwinc15x0/atwinc15x0_bus.c
Normal file
88
drivers/atwinc15x0/atwinc15x0_bus.c
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Gunar Schorcht
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup drivers_atwinc15x0
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief RIOT bus wrapper API implementation
|
||||
*
|
||||
* @author Gunar Schorcht <gunar@schorcht.net>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "atwinc15x0_internal.h"
|
||||
#include "bus_wrapper/include/nm_bus_wrapper.h"
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
#define NM_BUS_MAX_TRX_SZ 256
|
||||
|
||||
tstrNmBusCapabilities egstrNmBusCapabilities =
|
||||
{
|
||||
NM_BUS_MAX_TRX_SZ
|
||||
};
|
||||
|
||||
sint8 nm_bus_init(void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
|
||||
assert(atwinc15x0);
|
||||
assert(atwinc15x0->params.ssn_pin != GPIO_UNDEF);
|
||||
|
||||
gpio_init(atwinc15x0->params.ssn_pin, GPIO_OUT);
|
||||
gpio_set(atwinc15x0->params.ssn_pin);
|
||||
|
||||
nm_bsp_reset();
|
||||
nm_bsp_sleep(1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
sint8 nm_bus_ioctl(uint8 cmd, void* params)
|
||||
{
|
||||
assert(atwinc15x0);
|
||||
|
||||
sint8 res = 0;
|
||||
tstrNmSpiRw *spi_params = (tstrNmSpiRw *)params;
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case NM_BUS_IOCTL_RW:
|
||||
spi_acquire(atwinc15x0->params.spi, atwinc15x0->params.ssn_pin,
|
||||
SPI_MODE_0, atwinc15x0->params.spi_clk);
|
||||
spi_transfer_bytes(atwinc15x0->params.spi,
|
||||
atwinc15x0->params.ssn_pin, 0,
|
||||
spi_params->pu8InBuf,
|
||||
spi_params->pu8OutBuf,
|
||||
spi_params->u16Sz);
|
||||
spi_release(atwinc15x0->params.spi);
|
||||
break;
|
||||
|
||||
default:
|
||||
res = M2M_ERR_BUS_FAIL;
|
||||
DEBUG("invalid ioctl cmd\n");
|
||||
break;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
sint8 nm_bus_deinit(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
sint8 nm_bus_reinit(void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
return 0;
|
||||
}
|
524
drivers/atwinc15x0/atwinc15x0_netdev.c
Normal file
524
drivers/atwinc15x0/atwinc15x0_netdev.c
Normal file
@ -0,0 +1,524 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Gunar Schorcht
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup drivers_atwinc15x0
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Netdev driver for the ATWINC15x0 WiFi module
|
||||
*
|
||||
* @author Gunar Schorcht <gunar@schorcht.net>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define ETH_MODE (1)
|
||||
|
||||
#include "atwinc15x0_internal.h"
|
||||
#include "atwinc15x0_params.h"
|
||||
|
||||
#include "bus_wrapper/include/nm_bus_wrapper.h"
|
||||
#include "driver/source/m2m_hif.h"
|
||||
#include "driver/include/m2m_wifi.h"
|
||||
|
||||
#include "assert.h"
|
||||
#include "log.h"
|
||||
#include "net/netdev/eth.h"
|
||||
#include "od.h"
|
||||
#include "xtimer.h"
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#define ENABLE_DEBUG_DUMP (0)
|
||||
#include "debug.h"
|
||||
|
||||
#define ATWINC15X0_MAC_STR "%02x:%02x:%02x:%02x:%02x:%02x"
|
||||
#define ATWINC15X0_MAC_STR_ARG(m) m[0], m[1], m[2], m[3], m[4], m[5]
|
||||
|
||||
#define ATWINC15X0_WAIT_TIME (1 * US_PER_MS)
|
||||
#define ATWINC15X0_WAIT_TIMEOUT (20)
|
||||
#define ATWINC15X0_WAIT_RECONNECT (5 * US_PER_SEC)
|
||||
|
||||
/* Forward function declarations */
|
||||
static void _atwinc15x0_wifi_cb(uint8_t event, void *msg);
|
||||
static void _atwinc15x0_eth_cb(uint8_t type, void *msg, void *ctrl);
|
||||
static int _atwinc15x0_connect(void);
|
||||
|
||||
/**
|
||||
* The following buffer is required by the ATWINC15x0 vendor driver to store
|
||||
* packets received from the ATWINC15x0 WiFI module in it. Its size has to be
|
||||
* at least one Ethernet frame of maximum length.
|
||||
*
|
||||
* The event-driven handling of incoming packets is strictly sequential in
|
||||
* the context of the `netif` thread. This means that an incoming packet
|
||||
* is first received by the `netif` thread and copied to its packet buffer
|
||||
* before the next event of an incoming packet is handled by the ATWINC15x0
|
||||
* vendor driver. It can therefore be assumed that only one received packet
|
||||
* can be in the buffer at a time. No further separate intermediate buffer
|
||||
* is required.
|
||||
*
|
||||
* Furthermore, this buffer can be used for preparing a packet to be sent,
|
||||
* since it can be assumed that receiving and sending packets are implicitly
|
||||
* mutually exclusive due to their strictly sequential processing.
|
||||
*/
|
||||
static uint8_t atwinc15x0_eth_buf[ETHERNET_MAX_LEN];
|
||||
|
||||
/* ATWINC15x0 vendor driver initialization structure (can't be const) */
|
||||
static tstrWifiInitParam atwinc15x0_wifi_params = {
|
||||
.pfAppWifiCb = _atwinc15x0_wifi_cb,
|
||||
.strEthInitParam = {
|
||||
.pfAppWifiCb = _atwinc15x0_wifi_cb,
|
||||
.pfAppEthCb = _atwinc15x0_eth_cb,
|
||||
.au8ethRcvBuf = atwinc15x0_eth_buf,
|
||||
.u16ethRcvBufSize = ARRAY_SIZE(atwinc15x0_eth_buf),
|
||||
.u8EthernetEnable = M2M_WIFI_MODE_ETHERNET,
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Reference to the single ATWINC15x0 device instance
|
||||
*
|
||||
* Since the vendor ATWINC15x0 host driver uses many global variables, only
|
||||
* a single ATWINC15x0 device can be used. Therefore, the RIOT driver only
|
||||
* supports a single instance of an ATWINC15x0 device. The reference is
|
||||
* needed in callback functions where a reference to the device is not
|
||||
* available.
|
||||
*/
|
||||
atwinc15x0_t *atwinc15x0 = NULL;
|
||||
|
||||
static void _atwinc15x0_eth_cb(uint8_t type, void *msg, void *ctrl_buf)
|
||||
{
|
||||
assert(atwinc15x0);
|
||||
assert(msg != NULL);
|
||||
assert(ctrl_buf != NULL);
|
||||
|
||||
tstrM2mIpCtrlBuf *ctrl = (tstrM2mIpCtrlBuf *)ctrl_buf;
|
||||
|
||||
DEBUG("%s type=%u msg=%p len=%d remaining=%d\n", __func__,
|
||||
type, msg, ctrl->u16DataSize, ctrl->u16RemainigDataSize);
|
||||
#if MODULE_OD && ENABLE_DEBUG_DUMP
|
||||
od_hex_dump(msg, ctrl->u16DataSize, 16);
|
||||
#endif
|
||||
|
||||
/* the buffer shouldn't be used here */
|
||||
assert(atwinc15x0->rx_buf == NULL);
|
||||
|
||||
uint32_t state = irq_disable();
|
||||
|
||||
atwinc15x0->rx_buf = msg;
|
||||
atwinc15x0->rx_len = ctrl->u16DataSize;
|
||||
|
||||
irq_restore(state);
|
||||
|
||||
/**
|
||||
* This function is executed in the thread context. Therefore
|
||||
* netdev.event_callback can be called directly, which avoids an
|
||||
* additional intermediate buffer.
|
||||
*/
|
||||
atwinc15x0->netdev.event_callback(&atwinc15x0->netdev,
|
||||
NETDEV_EVENT_RX_COMPLETE);
|
||||
}
|
||||
|
||||
typedef union {
|
||||
tstrM2mWifiStateChanged state_changed;
|
||||
tstrM2MConnInfo conn_info;
|
||||
tstrM2mScanDone scan_done;
|
||||
tstrM2mWifiscanResult scan_result;
|
||||
int8_t rssi;
|
||||
} atwinc15x0_event_t;
|
||||
|
||||
static bool _rssi_info_ready = false;
|
||||
|
||||
static void _atwinc15x0_wifi_cb(uint8_t type, void *msg)
|
||||
{
|
||||
/**
|
||||
* This function is executed in thread context. There is no need to call
|
||||
* netdev_trigger_event_isr and to handle the events in _atwinc15x0_isr
|
||||
*/
|
||||
|
||||
DEBUG("%s %u %p\n", __func__, type, msg);
|
||||
|
||||
atwinc15x0_event_t* event = (atwinc15x0_event_t *)msg;
|
||||
|
||||
switch (type) {
|
||||
case M2M_WIFI_RESP_SCAN_DONE:
|
||||
DEBUG("%s scan done, %d APs found\n", __func__,
|
||||
event->scan_done.u8NumofCh);
|
||||
/* read the first scan result record */
|
||||
m2m_wifi_req_scan_result(0);
|
||||
break;
|
||||
|
||||
case M2M_WIFI_RESP_SCAN_RESULT:
|
||||
LOG_DEBUG("[atwinc15x0] %s: rssi %d, auth %d, ch %d, bssid "
|
||||
ATWINC15X0_MAC_STR "\n",
|
||||
event->scan_result.au8SSID,
|
||||
event->scan_result.s8rssi,
|
||||
event->scan_result.u8AuthType,
|
||||
event->scan_result.u8ch,
|
||||
ATWINC15X0_MAC_STR_ARG(event->scan_result.au8BSSID));
|
||||
|
||||
if (memcmp(&event->scan_result.au8BSSID,
|
||||
&atwinc15x0->ap, ETHERNET_ADDR_LEN) == 0) {
|
||||
/* use the results for current AP to set the current channel */
|
||||
atwinc15x0->channel = event->scan_result.u8ch;
|
||||
}
|
||||
if (event->scan_result.u8index < m2m_wifi_get_num_ap_found()) {
|
||||
/* read the next scan result record */
|
||||
m2m_wifi_req_scan_result(event->scan_result.u8index + 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case M2M_WIFI_RESP_CON_STATE_CHANGED:
|
||||
switch (event->state_changed.u8CurrState) {
|
||||
case M2M_WIFI_DISCONNECTED:
|
||||
LOG_INFO("[atwinc15x0] WiFi disconnected\n");
|
||||
atwinc15x0->connected = false;
|
||||
atwinc15x0->netdev.event_callback(&atwinc15x0->netdev,
|
||||
NETDEV_EVENT_LINK_DOWN);
|
||||
/* wait and try to reconnect */
|
||||
xtimer_usleep(ATWINC15X0_WAIT_RECONNECT);
|
||||
_atwinc15x0_connect();
|
||||
break;
|
||||
case M2M_WIFI_CONNECTED:
|
||||
LOG_INFO("[atwinc15x0] WiFi connected\n");
|
||||
atwinc15x0->connected = true;
|
||||
atwinc15x0->netdev.event_callback(&atwinc15x0->netdev,
|
||||
NETDEV_EVENT_LINK_UP);
|
||||
/* get information about the current AP */
|
||||
m2m_wifi_get_connection_info();
|
||||
/* start a scan for additional info, e.g. used channel */
|
||||
m2m_wifi_request_scan(M2M_WIFI_CH_ALL);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case M2M_WIFI_RESP_CONN_INFO:
|
||||
DEBUG("%s conn info %s, rssi %d, sec %u, bssid "
|
||||
ATWINC15X0_MAC_STR "\n", __func__,
|
||||
event->conn_info.acSSID,
|
||||
event->conn_info.s8RSSI,
|
||||
event->conn_info.u8SecType,
|
||||
ATWINC15X0_MAC_STR_ARG(event->conn_info.au8MACAddress));
|
||||
|
||||
/* set the RSSI and BSSID of the current AP */
|
||||
atwinc15x0->rssi = event->conn_info.s8RSSI;
|
||||
memcpy(atwinc15x0->ap,
|
||||
event->conn_info.au8MACAddress, ETHERNET_ADDR_LEN);
|
||||
break;
|
||||
|
||||
case M2M_WIFI_RESP_CURRENT_RSSI:
|
||||
DEBUG("%s current rssi %d\n", __func__, event->rssi);
|
||||
/* set the RSSI */
|
||||
atwinc15x0->rssi = event->rssi;
|
||||
_rssi_info_ready = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int _atwinc15x0_send(netdev_t *netdev, const iolist_t *iolist)
|
||||
{
|
||||
atwinc15x0_t *dev = (atwinc15x0_t *)netdev;
|
||||
|
||||
assert(dev);
|
||||
assert(dev == atwinc15x0);
|
||||
assert(iolist);
|
||||
|
||||
if (!dev->connected) {
|
||||
DEBUG("%s WiFi is still not connected to AP, cannot send", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* atwinc15x0_eth_buf should not be used for incoming packets here */
|
||||
assert(dev->rx_buf == NULL);
|
||||
|
||||
uint32_t state = irq_disable();
|
||||
uint16_t tx_len = 0;
|
||||
|
||||
/* load packet data into the buffer */
|
||||
for (const iolist_t *iol = iolist; iol; iol = iol->iol_next) {
|
||||
if (tx_len + iol->iol_len > ETHERNET_MAX_LEN) {
|
||||
irq_restore(state);
|
||||
return -EOVERFLOW;
|
||||
}
|
||||
if (iol->iol_len) {
|
||||
memcpy (atwinc15x0_eth_buf + tx_len, iol->iol_base, iol->iol_len);
|
||||
tx_len += iol->iol_len;
|
||||
}
|
||||
}
|
||||
|
||||
#if ENABLE_DEBUG
|
||||
DEBUG("%s send %d byte", __func__, tx_len);
|
||||
#if MODULE_OD && ENABLE_DEBUG_DUMP
|
||||
od_hex_dump(dev->tx_buf, dev->tx_len, OD_WIDTH_DEFAULT);
|
||||
#endif /* MODULE_OD && ENABLE_DEBUG_HEXDUMP */
|
||||
#endif
|
||||
irq_restore(state);
|
||||
|
||||
/* send the the packet */
|
||||
if (m2m_wifi_send_ethernet_pkt(atwinc15x0_eth_buf, tx_len) == M2M_SUCCESS) {
|
||||
netdev->event_callback(netdev, NETDEV_EVENT_TX_COMPLETE);
|
||||
return tx_len;
|
||||
}
|
||||
else {
|
||||
DEBUG("%s sending WiFi packet failed", __func__);
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
|
||||
static int _atwinc15x0_recv(netdev_t *netdev, void *buf, size_t len, void *info)
|
||||
{
|
||||
atwinc15x0_t *dev = (atwinc15x0_t *)netdev;
|
||||
|
||||
(void)info;
|
||||
assert(dev);
|
||||
assert(dev == atwinc15x0);
|
||||
|
||||
uint32_t state = irq_disable();
|
||||
uint16_t rx_size = dev->rx_len;
|
||||
|
||||
if (!rx_size) {
|
||||
/* there is nothing in receive buffer */
|
||||
irq_restore(state);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!buf) {
|
||||
/* get the size of the frame */
|
||||
if (len > 0) {
|
||||
/* if len > 0, drop the frame */
|
||||
dev->rx_len = 0;
|
||||
dev->rx_buf = NULL;
|
||||
}
|
||||
irq_restore(state);
|
||||
return rx_size;
|
||||
}
|
||||
|
||||
if (len < rx_size) {
|
||||
/* buffer is smaller than the number of received bytes */
|
||||
DEBUG("%s not enough space in receive buffer", __func__);
|
||||
/* newest API requires to drop the frame in that case */
|
||||
dev->rx_len = 0;
|
||||
dev->rx_buf = NULL;
|
||||
irq_restore(state);
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
/* remove length bytes, copy received packet to buffer */
|
||||
memcpy(buf, dev->rx_buf, dev->rx_len);
|
||||
dev->rx_len = 0;
|
||||
dev->rx_buf = NULL;
|
||||
|
||||
#if ENABLE_DEBUG
|
||||
ethernet_hdr_t *hdr = (ethernet_hdr_t *)buf;
|
||||
DEBUG("%s received %u byte from addr " ATWINC15X0_MAC_STR "\n",
|
||||
__func__, rx_size, ATWINC15X0_MAC_STR_ARG(hdr->src));
|
||||
#if MODULE_OD && ENABLE_DEBUG_DUMP
|
||||
od_hex_dump(buf, rx_size, OD_WIDTH_DEFAULT);
|
||||
#endif /* MODULE_OD && ENABLE_DEBUG_HEXDUMP */
|
||||
#endif /* ENABLE_DEBUG */
|
||||
|
||||
irq_restore(state);
|
||||
|
||||
return rx_size;
|
||||
}
|
||||
|
||||
static int _atwinc15x0_get(netdev_t *netdev, netopt_t opt, void *val,
|
||||
size_t max_len)
|
||||
{
|
||||
atwinc15x0_t *dev = (atwinc15x0_t *)netdev;
|
||||
|
||||
(void)max_len;
|
||||
assert(val);
|
||||
assert(dev);
|
||||
assert(dev == atwinc15x0);
|
||||
|
||||
DEBUG("%s dev=%p opt=%u val=%p max_len=%u\n", __func__,
|
||||
netdev, opt, val, max_len);
|
||||
|
||||
switch (opt) {
|
||||
case NETOPT_IS_WIRED:
|
||||
return -ENOTSUP;
|
||||
|
||||
case NETOPT_ADDRESS:
|
||||
assert(max_len >= ETHERNET_ADDR_LEN);
|
||||
uint8_t valid;
|
||||
m2m_wifi_get_otp_mac_address((uint8_t *)val, &valid);
|
||||
return (valid) ? ETHERNET_ADDR_LEN : 0;
|
||||
|
||||
case NETOPT_LINK:
|
||||
assert(max_len == sizeof(netopt_enable_t));
|
||||
*((netopt_enable_t *)val) = (dev->connected) ? NETOPT_ENABLE
|
||||
: NETOPT_DISABLE;
|
||||
return sizeof(netopt_enable_t);
|
||||
|
||||
case NETOPT_CHANNEL:
|
||||
assert(max_len == sizeof(uint16_t));
|
||||
*((uint16_t *)val) = dev->channel;
|
||||
return sizeof(uint16_t);
|
||||
|
||||
case NETOPT_RSSI:
|
||||
assert(max_len == sizeof(int8_t));
|
||||
_rssi_info_ready = false;
|
||||
/* trigger the request current RSSI (asynchronous function) */
|
||||
if (m2m_wifi_req_curr_rssi() != M2M_SUCCESS) {
|
||||
return 0;
|
||||
}
|
||||
/* wait for the response with a given timeout */
|
||||
unsigned int _rssi_info_time_out = ATWINC15X0_WAIT_TIMEOUT;
|
||||
while (!_rssi_info_ready && _rssi_info_time_out--) {
|
||||
xtimer_usleep(ATWINC15X0_WAIT_TIME);
|
||||
}
|
||||
/* return the RSSI */
|
||||
*((int8_t *)val) = dev->rssi;
|
||||
return sizeof(int8_t);
|
||||
|
||||
default:
|
||||
return netdev_eth_get(netdev, opt, val, max_len);
|
||||
}
|
||||
}
|
||||
|
||||
static int _atwinc15x0_set(netdev_t *netdev, netopt_t opt, const void *val,
|
||||
size_t max_len)
|
||||
{
|
||||
assert(val);
|
||||
|
||||
DEBUG("%s dev=%p opt=%u val=%p max_len=%u\n", __func__,
|
||||
netdev, opt, val, max_len);
|
||||
|
||||
switch (opt) {
|
||||
case NETOPT_ADDRESS:
|
||||
assert(max_len == ETHERNET_ADDR_LEN);
|
||||
m2m_wifi_set_mac_address((uint8_t *)val);
|
||||
return ETHERNET_ADDR_LEN;
|
||||
default:
|
||||
return netdev_eth_set(netdev, opt, val, max_len);
|
||||
}
|
||||
}
|
||||
|
||||
static int _atwinc15x0_init(netdev_t *netdev)
|
||||
{
|
||||
atwinc15x0_t *dev = (atwinc15x0_t *)netdev;
|
||||
|
||||
(void)netdev;
|
||||
assert(dev);
|
||||
assert(dev == atwinc15x0);
|
||||
|
||||
DEBUG("%s dev=%p\n", __func__, dev);
|
||||
|
||||
atwinc15x0->bsp_isr = NULL;
|
||||
atwinc15x0->bsp_irq_enabled = true;
|
||||
atwinc15x0->connected = false;
|
||||
atwinc15x0->rx_len = 0;
|
||||
atwinc15x0->rx_buf = NULL;
|
||||
|
||||
nm_bsp_init();
|
||||
|
||||
int8_t res;
|
||||
|
||||
/* initialize the WINC Driver*/
|
||||
if ((res = m2m_wifi_init(&atwinc15x0_wifi_params)) != M2M_SUCCESS) {
|
||||
DEBUG("m2m_wifi_init failed with code %d\n", res);
|
||||
if (res == M2M_ERR_FW_VER_MISMATCH) {
|
||||
LOG_WARNING("[atwinc15x0] Firmware version mismatch, "
|
||||
"this may lead to problems.\n");
|
||||
}
|
||||
else {
|
||||
LOG_ERROR("[atwinc15x0] Driver initialization error %d\n", res);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
/* disable the built-in DHCP client */
|
||||
if ((res = m2m_wifi_enable_dhcp(false)) != M2M_SUCCESS) {
|
||||
LOG_ERROR("[atwinc15x0] m2m_wifi_enable_dhcp failed with %d\n", res);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* try to connect and return */
|
||||
return _atwinc15x0_connect();
|
||||
}
|
||||
|
||||
static int _atwinc15x0_connect(void)
|
||||
{
|
||||
tuniM2MWifiAuth auth_info;
|
||||
tenuM2mSecType auth_type = M2M_WIFI_SEC_OPEN;
|
||||
|
||||
#if !defined(MODULE_WIFI_ENTERPRISE) && defined(WIFI_PASS)
|
||||
|
||||
strncpy((char *)auth_info.au8PSK, WIFI_PASS, M2M_MAX_PSK_LEN);
|
||||
auth_type = M2M_WIFI_SEC_WPA_PSK;
|
||||
|
||||
#elif defined(MODULE_WIFI_ENTERPRISE)
|
||||
|
||||
#if defined(WIFI_USER) && defined(WIFI_PASS)
|
||||
strncpy((char *)&auth_info.strCred1x.au8UserName, WIFI_USER, M2M_1X_USR_NAME_MAX);
|
||||
strncpy((char *)&auth_info.strCred1x.au8Passwd, WIFI_PASS, M2M_1X_PWD_MAX);
|
||||
auth_type = M2M_WIFI_SEC_802_1X;
|
||||
#else /* defined(WIFI_EAP_USER) && defined(WIFI_EAP_PASS) */
|
||||
#error WIFI_EAP_USER and WIFI_EAP_PASS have to define the user name \
|
||||
and the password for EAP phase 2 authentication in wifi_enterprise
|
||||
#endif /* defined(WIFI_EAP_USER) && defined(WIFI_EAP_PASS) */
|
||||
|
||||
#endif /* defined(MODULE_ESP_WIFI_ENTERPRISE) */
|
||||
|
||||
/* connect */
|
||||
int8_t res;
|
||||
if ((res = m2m_wifi_connect(WIFI_SSID, sizeof(WIFI_SSID),
|
||||
auth_type, &auth_info,
|
||||
M2M_WIFI_CH_ALL)) != M2M_SUCCESS) {
|
||||
LOG_ERROR("[atwinc15x0] WiFi connect failed with %d\n", res);
|
||||
return res;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void _atwinc15x0_isr(netdev_t *netdev)
|
||||
{
|
||||
atwinc15x0_t *dev = (atwinc15x0_t *)netdev;
|
||||
|
||||
assert(dev);
|
||||
assert(dev == atwinc15x0);
|
||||
|
||||
DEBUG("%s dev=%p\n", __func__, dev);
|
||||
|
||||
/* handle pending ATWINC15x0 module events */
|
||||
while (m2m_wifi_handle_events(NULL) != M2M_SUCCESS) { }
|
||||
}
|
||||
|
||||
const netdev_driver_t atwinc15x0_netdev_driver = {
|
||||
.send = _atwinc15x0_send,
|
||||
.recv = _atwinc15x0_recv,
|
||||
.init = _atwinc15x0_init,
|
||||
.isr = _atwinc15x0_isr,
|
||||
.get = _atwinc15x0_get,
|
||||
.set = _atwinc15x0_set,
|
||||
};
|
||||
|
||||
void atwinc15x0_setup(atwinc15x0_t *dev, const atwinc15x0_params_t *params)
|
||||
{
|
||||
assert(dev);
|
||||
|
||||
atwinc15x0 = dev;
|
||||
atwinc15x0->netdev.driver = &atwinc15x0_netdev_driver;
|
||||
atwinc15x0->params = *params;
|
||||
}
|
||||
|
||||
void atwinc15x0_irq(void)
|
||||
{
|
||||
if (atwinc15x0) {
|
||||
netdev_trigger_event_isr(&atwinc15x0->netdev);
|
||||
}
|
||||
}
|
174
drivers/atwinc15x0/doc.txt
Normal file
174
drivers/atwinc15x0/doc.txt
Normal file
@ -0,0 +1,174 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Gunar Schorcht
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup drivers_atwinc15x0 ATWINC15x0 WiFi module driver
|
||||
* @ingroup drivers_netdev
|
||||
* @brief Network device driver for the Microchip ATWINC15x0 WiFi Module
|
||||
*
|
||||
* @author Gunar Schorcht <gunar@schorcht.net>
|
||||
|
||||
### Introduction
|
||||
|
||||
This module implements a `netdev` device driver for the Microchip ATWINC15x0
|
||||
WiFi module. The ATWINC15x0 WiFi module is widely used as WiFi interface on
|
||||
various boards and extension boards. Examples are:
|
||||
|
||||
- [Adafruit Feather M0 WiFi](https://learn.adafruit.com/adafruit-feather-m0-wifi-atwinc1500/)
|
||||
(also supported by [RIOT](https://doc.riot-os.org/group__boards__feather-m0.html))
|
||||
- [ATWIN1500-XPRO](https://www.microchip.com/DevelopmentTools/ProductDetails/ATWINC1500-XPRO)
|
||||
for the extension of Atmel Xplained PRO boards (also supported by RIOT)
|
||||
- [Adafruit ATWINC1500 WiFi breakout](https://learn.adafruit.com/adafruit-atwinc1500-wifi-module-breakout)
|
||||
- [Watterott ATWINC1500-Breakout](https://github.com/watterott/ATWINC1500-Breakout)
|
||||
|
||||
Since the ATWINC15x0 WiFi module is also the only module supported by the
|
||||
standard [Arduino WiFi101 library](https://github.com/arduino-libraries/WiFi101),
|
||||
there are a number of Arduino shields with the ATWINC15x0 WiFi module, e.g.
|
||||
[Adafruit WINC1500 WiFi Shield for Arduino](https://learn.adafruit.com/adafruit-winc1500-wifi-shield-for-arduino).
|
||||
|
||||
Using this 'netdev' driver together with an ATWINC15x0 WiFi module enables
|
||||
the connection via WiFi in RIOT.
|
||||
|
||||
### Microchip ATWINC15x0 WiFi module
|
||||
|
||||
The ATWINC15x0 WiFi module is a low-power IEEE 802.11 b/g/n module with a
|
||||
bandwidth of 20 MHz in the 2,4 GHz ISM band. It supports the IEEE 802.11i/WPA2
|
||||
personal and enterprise modes. In enterprise mode it supports
|
||||
|
||||
- EAP-TLS
|
||||
- EAP-PEAPv0/1 with TLS
|
||||
- EAP-TTLSv0 with MSCHAPv2
|
||||
- EAP-PEAPv0/1 with MSCHAPv2
|
||||
|
||||
The WiFi module ATWINC15x0 is connected via SPI and supports SPI clock speeds
|
||||
of up to 48 MHz. Although the module also has an I2C and a UART interface,
|
||||
these interfaces are only used for debugging.
|
||||
|
||||
The ATWINC15x0 WiFi module implements a complete TCP/IP procotol stack which is
|
||||
not used in RIOT.
|
||||
|
||||
### Driver Details
|
||||
|
||||
The ATWINC15x0 WiFi `netdev` driver doesn't directly use the ATWINC15x0 WiFi
|
||||
module. Instead, it uses the ATWINC15x0 vendor driver
|
||||
[WINC1500 Wifi](http://asf.atmel.com/docs/latest/sam4s/html/group__winc1500__group.html).
|
||||
from Microchip's Advanced Software Framework. For that purpose, the
|
||||
[Arduino WiFi101 library](https://github.com/arduino-libraries/WiFi101) which
|
||||
also includes this vendor library is used as a package.
|
||||
|
||||
Although the ATWINC15x0 vendor driver is complex and quite large, there is
|
||||
no other way to do it because the ATWINC15x0 WiFi module's programming
|
||||
interface is not documented. At the very least, the ATWINC15x0 WiFi `netdev`
|
||||
driver uses only those parts of the vendor driver that are absolutely
|
||||
necessary.
|
||||
|
||||
The ATWINC15x0 vendor driver consists of several parts:
|
||||
|
||||
- the M2M WiFi library, which implements high-level WiFi connection management
|
||||
Functions
|
||||
- the HIF (Host Interface) library, which implements the interface with the
|
||||
ATWINC15x0 module
|
||||
- the BSP (Bus Support Package) as an abstraction layer for platform-specific
|
||||
Functions
|
||||
- the bus wrapper interface for access to the SPI
|
||||
|
||||
In addition to these parts, the ATWINC15x0 vendor driver contains a
|
||||
socket library and a library for accessing the SPI flash of the ATWINC15x0
|
||||
module, but these are not used in RIOT.
|
||||
|
||||
The ATWINC15x0 WiFi `netdev` driver replaces the BSP and the Bus Wrapper
|
||||
Interface by RIOT specific parts and interacts with ATWINC15x0 vendor driver
|
||||
as shown in the following figure.
|
||||
|
||||
```
|
||||
+-----------------+ +---------------+ +----------+ +------------+
|
||||
| RIOT ATWINC15x0 | | ATWINC15x0 | | RIOT Bus | | ATWINC15x0 |
|
||||
| netdev driver | | vendor driver | | Wrapper | | module |
|
||||
+-----------------+ +---------------+ +----------+ +------------+
|
||||
| | | |
|
||||
| m2m_wifi_func | command | SPI(command) |
|
||||
|------------------------->|--------------->|--------------->|
|
||||
| return | | |
|
||||
|<-------------------------| | |
|
||||
| | | |
|
||||
| | | |
|
||||
| | | |
|
||||
|<------------------------------- IRQ -----------------------|
|
||||
| | | |
|
||||
| m2m_wifi_handle_events | request | SPI(request) |
|
||||
|------------------------->|--------------->|--------------->|
|
||||
| | response | SPI(response) |
|
||||
| atwinc15x0_wifi_cb |<---------------|<---------------|
|
||||
|<-------------------------| | |
|
||||
| | | |
|
||||
| | | |
|
||||
| | | |
|
||||
| | | |
|
||||
|<------------------------------- IRQ -----------------------|
|
||||
| | | |
|
||||
| m2m_wifi_handle_events | request | SPI(request) |
|
||||
|------------------------->|--------------->|--------------->|
|
||||
| | response | SPI(response) |
|
||||
| atwinc15x0_eth_cb |<---------------|<---------------|
|
||||
|<-------------------------| | |
|
||||
```
|
||||
|
||||
As shown, the ATWINC15x0 WiFi module operates asynchronously. This means
|
||||
that when an API function of the ATWINC15x0 driver is called, it simply
|
||||
sends a command to the ATWINC15x0 WiFi module and returns immediately.
|
||||
The command is then executed asynchronously by the ATWINC15x0 WiFi module.
|
||||
As soon as the execution of the command is completed or one or more events
|
||||
are pending, the module interrupts the host. Since the ISR is executed in
|
||||
the interrupt context, the ATWINC15x0 'netdev' driver simply indicates
|
||||
that an interrupt has occurred. The interrupt is handled later in the
|
||||
thread context by calling 'm2m_wifi_handle_events'. This in turn fetches
|
||||
available information from the ATWINC15x0 WiFi module and then calls
|
||||
various callback functions according to the state, all of which are
|
||||
executed in the thread context.
|
||||
|
||||
## Configuration
|
||||
|
||||
The ATWINC15x0 'netdev' driver requires the configuration ATWINC15x0 WiFi
|
||||
module as WiFi settings:
|
||||
|
||||
### Hardware Configuration
|
||||
|
||||
The default configuration is defined in atwinc15x0_params.h and can be
|
||||
overridden either by the board definition or by environment variables in
|
||||
make command line.
|
||||
|
||||
Symbol | Default | Description
|
||||
:------------------------------|:-----------------|:---------------------
|
||||
`ATWINC15X0_PARAM_SPI` | `SPI_DEV(0)` | Used SPI device
|
||||
`ATWINC15X0_PARAM_SPI_CLK` | `SPI_CLK_10MHZ` | Used SPI clock speed
|
||||
`ATWINC15X0_PARAM_SSN_PIN` | `GPIO_PIN(1, 4)` | SPI slave select pin
|
||||
`ATWINC15X0_PARAM_RESET_PIN` | `GPIO_PIN(4, 3)` | `RESET` pin
|
||||
`ATWINC15X0_PARAM_IRQ_PIN` | `GPIO_PIN(7, 4)` | `IRQ` pin
|
||||
`ATWINC15X0_PARAM_CHIP_EN_PIN` | `GPIO_UNDEF` | `CHIP_EN` pin
|
||||
`ATWINC15X0_PARAM_WAKE_PIN` | `GPIO_UNDEF` | WAKE pin
|
||||
|
||||
### WiFi Configuration
|
||||
|
||||
At the moment only WPA2 Personal Mode is supported. The required settings are:
|
||||
|
||||
Parameter | Default | Description
|
||||
:---------|:----------|:------------
|
||||
WIFI_SSID | "RIOT_AP" | SSID of the AP to be used.
|
||||
WIFI_PASS | - | Passphrase used for the AP as clear text (max. 64 chars).
|
||||
|
||||
The following example shows the make command with the setting of different GPIOs and the WiFi parameters.
|
||||
```
|
||||
USEMODULE='atwinc15x0' \
|
||||
CFLAGS='-DWIFI_SSID=\"ssid\" -DWIFI_PASS=\"pass\" \
|
||||
-DATWINC15X0_PARAM_SSN_PIN=GPIO_PIN\(1,6\) \
|
||||
-DATWINC15X0_PARAM_RESET_PIN=GPIO_PIN\(1,4\) \
|
||||
-DATWINC15X0_PARAM_IRQ_PIN=GPIO_PIN\(0,8\)' \
|
||||
make BOARD=... -C examples/gnrc_networking flash term
|
||||
```
|
||||
|
||||
*/
|
47
drivers/atwinc15x0/include/atwinc15x0_internal.h
Normal file
47
drivers/atwinc15x0/include/atwinc15x0_internal.h
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Gunar Schorcht
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup drivers_atwinc15x0
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Internal definitions for the ATWINC15x0 WiFi netdev driver
|
||||
*
|
||||
* @author Gunar Schorcht <gunar@schorcht.net>
|
||||
*/
|
||||
|
||||
#ifndef ATWINC15X0_INTERNAL_H
|
||||
#define ATWINC15X0_INTERNAL_H
|
||||
|
||||
#include "atwinc15x0.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Reference to the single ATWINC15x0 device instance
|
||||
*
|
||||
* Since the vendor ATWINC15x0 host driver uses many global variables, only
|
||||
* a single ATWINC15x0 device can be used. Therefore, the RIOT driver only
|
||||
* supports a single instance of an ATWINC15x0 device.
|
||||
*/
|
||||
extern atwinc15x0_t *atwinc15x0;
|
||||
|
||||
/**
|
||||
* @brief ATWINC15x0 device driver ISR
|
||||
*/
|
||||
void atwinc15x0_irq(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ATWINC15X0_INTERNAL_H */
|
||||
/** @} */
|
101
drivers/atwinc15x0/include/atwinc15x0_params.h
Normal file
101
drivers/atwinc15x0/include/atwinc15x0_params.h
Normal file
@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Gunar Schorcht
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup drivers_atwinc15x0
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Default configuration for the ATWINC15x0 WiFi netdev driver
|
||||
*
|
||||
* @author Gunar Schorcht <gunar@schorcht.net>
|
||||
*/
|
||||
|
||||
#ifndef ATWINC15X0_PARAMS_H
|
||||
#define ATWINC15X0_PARAMS_H
|
||||
|
||||
#include "board.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief SSID of the AP to be used.
|
||||
*/
|
||||
#ifndef WIFI_SSID
|
||||
#define WIFI_SSID "RIOT_AP"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Passphrase used for the AP as clear text (max. 64 chars).
|
||||
*/
|
||||
#ifdef DOXYGEN
|
||||
#define WIFI_PASS "ThisistheRIOTporttoESP"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @name Set default configuration parameters
|
||||
* Pins are adapted to Arduino Mega2560 boards.
|
||||
* @{
|
||||
*/
|
||||
#ifndef ATWINC15X0_PARAM_SPI
|
||||
#define ATWINC15X0_PARAM_SPI SPI_DEV(0)
|
||||
#endif
|
||||
|
||||
#ifndef ATWINC15X0_PARAM_SPI_CLK
|
||||
#define ATWINC15X0_PARAM_SPI_CLK SPI_CLK_10MHZ
|
||||
#endif
|
||||
|
||||
#ifndef ATWINC15X0_PARAM_SSN_PIN
|
||||
#define ATWINC15X0_PARAM_SSN_PIN GPIO_PIN(1, 4) /* D10 (PB4) */
|
||||
#endif
|
||||
|
||||
#ifndef ATWINC15X0_PARAM_RESET_PIN
|
||||
#define ATWINC15X0_PARAM_RESET_PIN GPIO_PIN(4, 3) /* D5 (PE3) */
|
||||
#endif
|
||||
|
||||
#ifndef ATWINC15X0_PARAM_IRQ_PIN
|
||||
#define ATWINC15X0_PARAM_IRQ_PIN GPIO_PIN(7, 4) /* D7 (PH4) */
|
||||
#endif
|
||||
|
||||
#ifndef ATWINC15X0_PARAM_CHIP_EN_PIN
|
||||
#define ATWINC15X0_PARAM_CHIP_EN_PIN GPIO_UNDEF
|
||||
#endif
|
||||
|
||||
#ifndef ATWINC15X0_PARAM_WAKE_PIN
|
||||
#define ATWINC15X0_PARAM_WAKE_PIN GPIO_UNDEF
|
||||
#endif
|
||||
|
||||
#ifndef ATWINC15X0_PARAMS
|
||||
#define ATWINC15X0_PARAMS { \
|
||||
.spi = ATWINC15X0_PARAM_SPI, \
|
||||
.spi_clk = ATWINC15X0_PARAM_SPI_CLK, \
|
||||
.ssn_pin = ATWINC15X0_PARAM_SSN_PIN, \
|
||||
.reset_pin = ATWINC15X0_PARAM_RESET_PIN, \
|
||||
.irq_pin = ATWINC15X0_PARAM_IRQ_PIN, \
|
||||
.chip_en_pin = ATWINC15X0_PARAM_CHIP_EN_PIN, \
|
||||
.wake_pin = ATWINC15X0_PARAM_WAKE_PIN, \
|
||||
}
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Allocate some memory to store the actual configuration
|
||||
*/
|
||||
static const atwinc15x0_params_t atwinc15x0_params[] =
|
||||
{
|
||||
ATWINC15X0_PARAMS
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ATWINC15X0_PARAMS_H */
|
||||
/** @} */
|
50
drivers/atwinc15x0/include/bsp/include/nm_bsp_internal.h
Normal file
50
drivers/atwinc15x0/include/bsp/include/nm_bsp_internal.h
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Gunar Schorcht
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
#if !DOXYGEN
|
||||
|
||||
/**
|
||||
* @ingroup drivers_atwinc15x0
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Internal compile config for the ATWINC15x0 WiFi netdev driver
|
||||
*
|
||||
* @author Gunar Schorcht <gunar@schorcht.net>
|
||||
*/
|
||||
|
||||
#ifndef BSP_INCLUDE_NM_BSP_INTERNAL_H
|
||||
#define BSP_INCLUDE_NM_BSP_INTERNAL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef MODULE_ATMEGA_COMMON
|
||||
#define ARDUINO
|
||||
#endif
|
||||
|
||||
#define CONF_WINC_USE_SPI (1)
|
||||
#define CONF_WINC_PRINTF printf
|
||||
|
||||
#ifndef CONF_WINC_DEBUG
|
||||
#define CONF_WINC_DEBUG (0)
|
||||
#endif
|
||||
|
||||
#ifndef M2M_LOG_LEVEL
|
||||
#define M2M_LOG_LEVEL M2M_LOG_ERROR
|
||||
#endif
|
||||
|
||||
#define NM_EDGE_INTERRUPT (1)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* BSP_INCLUDE_NM_BSP_INTERNAL_H */
|
||||
#endif /* DOXYGEN */
|
80
drivers/include/atwinc15x0.h
Normal file
80
drivers/include/atwinc15x0.h
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Gunar Schorcht
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup drivers_netdev
|
||||
* @brief Netdev Driver for the Microchip ATWINC15x0 WiFi Module
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Public interface for ATWINC15x0 netdev driver
|
||||
*
|
||||
* @author Gunar Schorcht <gunar@schorcht.net>
|
||||
*/
|
||||
|
||||
#ifndef ATWINC15X0_H
|
||||
#define ATWINC15X0_H
|
||||
|
||||
#include "bsp/include/nm_bsp.h"
|
||||
#include "net/ethernet.h"
|
||||
#include "net/netdev.h"
|
||||
#include "periph/gpio.h"
|
||||
#include "periph/spi.h"
|
||||
#include "ringbuffer.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ATWINC15x0 hardware and global parameters
|
||||
*/
|
||||
typedef struct {
|
||||
spi_t spi; /**< SPI device */
|
||||
spi_clk_t spi_clk; /**< SPI clock speed used */
|
||||
gpio_t ssn_pin; /**< SPI SS pin (slave select LOW active) */
|
||||
gpio_t reset_pin; /**< RESET_N pin (LOW active) */
|
||||
gpio_t irq_pin; /**< IRQN pin (LOW active) */
|
||||
gpio_t chip_en_pin; /**< CHIP_EN pin */
|
||||
gpio_t wake_pin; /**< WAKE pin */
|
||||
} atwinc15x0_params_t;
|
||||
|
||||
/**
|
||||
* @brief ATWINC15x0 device descriptor type
|
||||
*/
|
||||
typedef struct atwinc15x0 {
|
||||
netdev_t netdev; /**< Pulls in the netdev fields */
|
||||
atwinc15x0_params_t params; /**< Device initialization parameters */
|
||||
|
||||
bool connected; /**< Indicates whether connected to an AP */
|
||||
char ap[ETHERNET_ADDR_LEN]; /**< BSSID of current AP */
|
||||
uint8_t channel; /**< Channel used for current AP */
|
||||
int8_t rssi; /**< RSSI last measured by the WiFi module */
|
||||
|
||||
uint8_t* rx_buf; /**< Incoming packet in receive buffer */
|
||||
uint16_t rx_len; /**< Length of an incoming packet, if there
|
||||
is no packet in the buffer, it is 0 */
|
||||
|
||||
tpfNmBspIsr bsp_isr; /**< Board support package ISR */
|
||||
bool bsp_irq_enabled; /**< Board support package interrupt enabled */
|
||||
} atwinc15x0_t;
|
||||
|
||||
/**
|
||||
* @brief Setup the ATWINC15x0 WiFi module
|
||||
*
|
||||
* @param[in] dev Device descriptor
|
||||
* @param[in] params Parameters for device initialization
|
||||
*/
|
||||
void atwinc15x0_setup(atwinc15x0_t *dev, const atwinc15x0_params_t *params);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ATWINC15X0_H */
|
||||
/** @} */
|
@ -107,6 +107,7 @@ PSEUDOMODULES += stdio_cdc_acm
|
||||
PSEUDOMODULES += stdio_uart_rx
|
||||
PSEUDOMODULES += suit_transport_%
|
||||
PSEUDOMODULES += wakaama_objects_%
|
||||
PSEUDOMODULES += wifi_enterprise
|
||||
PSEUDOMODULES += xtimer_on_ztimer
|
||||
PSEUDOMODULES += zptr
|
||||
PSEUDOMODULES += ztimer%
|
||||
|
Loading…
Reference in New Issue
Block a user