support wifi chip esp8266 based on uart2
This commit is contained in:
parent
234c2b14fa
commit
9b47a30c09
|
@ -140,7 +140,7 @@ menuconfig BSP_USING_CAN
|
||||||
default n
|
default n
|
||||||
|
|
||||||
menuconfig BSP_USING_ESP8266
|
menuconfig BSP_USING_ESP8266
|
||||||
depends on U16550_UART3
|
depends on U16550_UART2
|
||||||
bool "Using ESP8266 device"
|
bool "Using ESP8266 device"
|
||||||
default n
|
default n
|
||||||
|
|
||||||
|
|
|
@ -58,4 +58,8 @@ ifeq ($(CONFIG_BSP_USING_CAN),y)
|
||||||
CSRCS += k210_can.c can_demo.c
|
CSRCS += k210_can.c can_demo.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_BSP_USING_ESP8266),y)
|
||||||
|
CSRCS += k210_esp8266.c esp8266_demo.c
|
||||||
|
endif
|
||||||
|
|
||||||
include $(TOPDIR)/boards/Board.mk
|
include $(TOPDIR)/boards/Board.mk
|
||||||
|
|
|
@ -0,0 +1,118 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 AIIT XUOS Lab
|
||||||
|
* XiUOS is licensed under Mulan PSL v2.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||||
|
* You may obtain a copy of Mulan PSL v2 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL2
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||||
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||||
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the Mulan PSL v2 for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file esp8266_demo.c
|
||||||
|
* @brief xidatong-riscv64 esp8266_demo.c
|
||||||
|
* @version 1.0
|
||||||
|
* @author AIIT XUOS Lab
|
||||||
|
* @date 2022.08.22
|
||||||
|
*/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Included Files
|
||||||
|
****************************************************************************/
|
||||||
|
#include "k210_esp8266.h"
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include "time.h"
|
||||||
|
|
||||||
|
#define ec_print printf
|
||||||
|
#define ESP8266_DEMO_TIMEOUT 10
|
||||||
|
|
||||||
|
|
||||||
|
// first: receive \n\rRDY\n\r
|
||||||
|
// second: AT -> OK
|
||||||
|
|
||||||
|
static int esp8266_read_with_time(int fd, char *buffer, int seconds)
|
||||||
|
{
|
||||||
|
int read_size = 0;
|
||||||
|
time_t cur_time = time(NULL);
|
||||||
|
time_t last_time = cur_time;
|
||||||
|
|
||||||
|
while(cur_time < last_time + seconds)
|
||||||
|
{
|
||||||
|
read_size = read(fd, buffer, 256);
|
||||||
|
|
||||||
|
if(read_size < 0)
|
||||||
|
{
|
||||||
|
ec_print("esp8266 read failed %d\n", read_size);
|
||||||
|
return -ETIME;
|
||||||
|
}
|
||||||
|
else if(read_size)
|
||||||
|
{
|
||||||
|
ec_print("esp8266 read size %d ok!\n", read_size);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
cur_time = time(NULL);
|
||||||
|
}
|
||||||
|
return read_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
int esp8266_check_demo(int fd, char *send_str, char *recv_str)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
char buf[ESP8266_RECV_BUF_SIZE] = {0};
|
||||||
|
|
||||||
|
if(send_str)
|
||||||
|
{
|
||||||
|
ret = write(fd, send_str, strlen(send_str));
|
||||||
|
|
||||||
|
if(ret < 0)
|
||||||
|
{
|
||||||
|
ec_print("esp8266 write failed %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ec_print("write %s ret = %d\n", send_str, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = esp8266_read_with_time(fd, buf, ESP8266_DEMO_TIMEOUT);
|
||||||
|
if(ret < 0)
|
||||||
|
{
|
||||||
|
ec_print("esp8266 read failed %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ec_print("esp8266 read: %s!\n", buf);
|
||||||
|
|
||||||
|
if(strstr(buf, recv_str))
|
||||||
|
{
|
||||||
|
ec_print("esp8266 %s found!\n", recv_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Esp8266Demo(void)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
k210_gpiohs_set_value(FPIOA_ESP8266_EN, GPIO_PV_HIGH);
|
||||||
|
up_mdelay(100);
|
||||||
|
|
||||||
|
ec_print("start %s\n", __func__);
|
||||||
|
|
||||||
|
fd = open("/dev/esp8266", O_RDWR);
|
||||||
|
if(fd < 0)
|
||||||
|
{
|
||||||
|
ec_print("esp8266 open failed %d\n", fd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
up_mdelay(2000);
|
||||||
|
esp8266_check_demo(fd, "AT\r\n", "OK");
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
ec_print("end %s\n", __func__);
|
||||||
|
}
|
|
@ -0,0 +1,462 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 AIIT XUOS Lab
|
||||||
|
* XiUOS is licensed under Mulan PSL v2.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||||
|
* You may obtain a copy of Mulan PSL v2 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL2
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||||
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||||
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the Mulan PSL v2 for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file k210_esp8266.c
|
||||||
|
* @brief support to register esp8266 pointer and function
|
||||||
|
* @version 1.0
|
||||||
|
* @author AIIT XUOS Lab
|
||||||
|
* @date 2022-07-20
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <nuttx/fs/fs.h>
|
||||||
|
#include <nuttx/wqueue.h>
|
||||||
|
#include <sys/poll.h>
|
||||||
|
#include "ctype.h"
|
||||||
|
#include "k210_esp8266.h"
|
||||||
|
|
||||||
|
#define ec_print printf
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
struct esp8266_dev_s g_esp8266dev;
|
||||||
|
static char *esp8266_dev_name = "/dev/esp8266";
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
void esp8266_print_buf(int size, uint8_t *buf)
|
||||||
|
{
|
||||||
|
char ch[10] = {0};
|
||||||
|
char temp[256] = {0};
|
||||||
|
|
||||||
|
if(size >= 256)
|
||||||
|
size = 256;
|
||||||
|
|
||||||
|
for(int i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
if(buf[i] == '\r')
|
||||||
|
{
|
||||||
|
strcat(temp, "\\r");
|
||||||
|
}
|
||||||
|
else if(buf[i] == '\n')
|
||||||
|
{
|
||||||
|
strcat(temp, "\\n");
|
||||||
|
}
|
||||||
|
else if(isascii(buf[i]))
|
||||||
|
{
|
||||||
|
snprintf(ch, sizeof(ch), "%c", buf[i]);
|
||||||
|
strcat(temp, ch);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
snprintf(ch, sizeof(ch), "%#x ", buf[i]);
|
||||||
|
strcat(temp, ch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(size)
|
||||||
|
ec_print("esp8266 read %d data: %s\n", size, temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
int esp8266_read_buf(void *dev, int *size, uint8_t *buf)
|
||||||
|
{
|
||||||
|
uart_dev_t *uart_dev = (uart_dev_t *)dev;
|
||||||
|
int cur_size = uart_dev->recv.head - uart_dev->recv.tail;
|
||||||
|
*size = *size > cur_size ? cur_size : *size;
|
||||||
|
memcpy(buf, uart_dev->recv.buffer, *size);
|
||||||
|
uart_dev->recv.head = uart_dev->recv.tail;
|
||||||
|
esp8266_print_buf(*size, buf);
|
||||||
|
return *size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: esp8266_data_work
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* thread task esp8266_data_work
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
static FAR void esp8266_data_work(FAR void *arg)
|
||||||
|
{
|
||||||
|
struct esp8266_dev_s *esp8266_dev = (struct esp8266_dev_s *)arg;
|
||||||
|
uart_dev_t *uart_dev = esp8266_dev->uart_dev;
|
||||||
|
nxsem_wait(&esp8266_dev->waitsem);
|
||||||
|
esp8266_dev->recv_size = ESP8266_RECV_BUF_SIZE;
|
||||||
|
esp8266_read_buf(uart_dev, &esp8266_dev->recv_size, esp8266_dev->recv_buf);
|
||||||
|
work_queue(HPWORK, &esp8266_dev->irqwork, esp8266_data_work, esp8266_dev, ESP8266_INCREMENT);
|
||||||
|
// esp8266info("uart size %d ok!\n", esp8266_dev->recv_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int esp8266_bringup(struct esp8266_dev_s *dev)
|
||||||
|
{
|
||||||
|
// struct esp8266_dev_s *esp8266_dev = &g_esp8266dev;
|
||||||
|
|
||||||
|
dev->uart_fd = open(dev->dev_name, O_RDWR);
|
||||||
|
|
||||||
|
esp8266info("open %s fd = %d\n", dev->dev_name, dev->uart_fd);
|
||||||
|
|
||||||
|
work_queue(HPWORK, &dev->irqwork, esp8266_data_work, dev, ESP8266_INCREMENT);
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int esp8266_write_config(struct esp8266_dev_s *dev)
|
||||||
|
{
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int esp8266_shutdown(struct esp8266_dev_s *dev)
|
||||||
|
{
|
||||||
|
close(dev->uart_fd);
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int esp8266_open(FAR struct file *filep)
|
||||||
|
{
|
||||||
|
FAR struct inode *inode;
|
||||||
|
FAR struct esp8266_dev_s *priv;
|
||||||
|
|
||||||
|
uint8_t ref_cnt;
|
||||||
|
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
DEBUGASSERT(filep);
|
||||||
|
inode = filep->f_inode;
|
||||||
|
DEBUGASSERT(inode && inode->i_private);
|
||||||
|
|
||||||
|
priv = (FAR struct esp8266_dev_s *)inode->i_private;
|
||||||
|
|
||||||
|
/* Get exclusive access to the driver data structure */
|
||||||
|
ret = nxsem_wait(&priv->devsem);
|
||||||
|
|
||||||
|
if(ret < 0)
|
||||||
|
{
|
||||||
|
esp8266err("ERROR: nxsem_wait failed: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Increment the reference count */
|
||||||
|
ref_cnt = priv->crefs + 1;
|
||||||
|
|
||||||
|
if(ref_cnt == 0)
|
||||||
|
{
|
||||||
|
/* More than 255 opens; uint8_t overflows to zero */
|
||||||
|
nxsem_post(&priv->devsem);
|
||||||
|
return -EMFILE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* When the reference increments to 1, this is the first open event
|
||||||
|
* on the driver.. and the time when we must initialize the driver.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if(ref_cnt == 1)
|
||||||
|
{
|
||||||
|
ret = esp8266_bringup(priv);
|
||||||
|
|
||||||
|
if(ret < 0)
|
||||||
|
{
|
||||||
|
esp8266err("ERROR: esp8266_bringup failed: %d\n", ret);
|
||||||
|
nxsem_post(&priv->devsem);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = esp8266_write_config(priv);
|
||||||
|
|
||||||
|
if(ret < 0)
|
||||||
|
{
|
||||||
|
esp8266err("ERROR: esp8266_write_config failed: %d\n", ret);
|
||||||
|
nxsem_post(&priv->devsem);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Save the new open count on success */
|
||||||
|
priv->crefs = ref_cnt;
|
||||||
|
|
||||||
|
nxsem_post(&priv->devsem);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: esp8266_close
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int esp8266_close(FAR struct file *filep)
|
||||||
|
{
|
||||||
|
FAR struct inode *inode;
|
||||||
|
FAR struct esp8266_dev_s *priv;
|
||||||
|
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
DEBUGASSERT(filep);
|
||||||
|
inode = filep->f_inode;
|
||||||
|
DEBUGASSERT(inode && inode->i_private);
|
||||||
|
|
||||||
|
priv = (FAR struct esp8266_dev_s *)inode->i_private;
|
||||||
|
|
||||||
|
/* Get exclusive access to the driver data structure */
|
||||||
|
ret = nxsem_wait(&priv->devsem);
|
||||||
|
|
||||||
|
if(ret < 0)
|
||||||
|
{
|
||||||
|
esp8266err("ERROR: nxsem_wait failed: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Decrement the reference count unless it would decrement a negative
|
||||||
|
* value.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if(priv->crefs >= 1)
|
||||||
|
{
|
||||||
|
priv->crefs--;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* When the count decrements to zero, there are no further open references
|
||||||
|
* to the driver and it esp8266 be uninitialized.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if(priv->crefs == 0)
|
||||||
|
{
|
||||||
|
esp8266_shutdown(priv);
|
||||||
|
}
|
||||||
|
|
||||||
|
nxsem_post(&priv->devsem);
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: esp8266_read
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static ssize_t esp8266_read(FAR struct file *filep, FAR char *buffer, size_t len)
|
||||||
|
{
|
||||||
|
FAR struct inode *inode;
|
||||||
|
FAR struct esp8266_dev_s *priv;
|
||||||
|
int ret, buf_size = len;
|
||||||
|
|
||||||
|
DEBUGASSERT(filep);
|
||||||
|
inode = filep->f_inode;
|
||||||
|
DEBUGASSERT(inode && inode->i_private);
|
||||||
|
|
||||||
|
priv = (FAR struct esp8266_dev_s *)inode->i_private;
|
||||||
|
|
||||||
|
ret = nxsem_wait(&priv->devsem);
|
||||||
|
|
||||||
|
if(ret < 0)
|
||||||
|
{
|
||||||
|
esp8266err("ERROR: nxsem_wait failed: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf_size = len > priv->recv_size ? priv->recv_size : len;
|
||||||
|
memcpy(buffer, priv->recv_buf, buf_size);
|
||||||
|
nxsem_post(&priv->devsem);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: esp8266_write
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static ssize_t esp8266_write(FAR struct file *filep, FAR const char *buffer, size_t len)
|
||||||
|
{
|
||||||
|
FAR struct inode *inode;
|
||||||
|
FAR struct esp8266_dev_s *priv;
|
||||||
|
int ret;
|
||||||
|
DEBUGASSERT(filep);
|
||||||
|
inode = filep->f_inode;
|
||||||
|
DEBUGASSERT(inode && inode->i_private);
|
||||||
|
priv = (FAR struct esp8266_dev_s *)inode->i_private;
|
||||||
|
|
||||||
|
/* Get exclusive access to the driver data structure */
|
||||||
|
ret = nxsem_wait(&priv->devsem);
|
||||||
|
|
||||||
|
if(ret < 0)
|
||||||
|
{
|
||||||
|
esp8266err("ERROR: nxsem_wait failed: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = write(priv->uart_fd, buffer, len);
|
||||||
|
esp8266info("write fd %d len %ld ret = %d\n", priv->uart_fd, len, ret);
|
||||||
|
nxsem_post(&priv->devsem);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: esp8266_ioctl
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int esp8266_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
||||||
|
{
|
||||||
|
FAR struct inode *inode;
|
||||||
|
FAR struct esp8266_dev_s *priv;
|
||||||
|
FAR uint32_t *ptr;
|
||||||
|
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
DEBUGASSERT(filep);
|
||||||
|
inode = filep->f_inode;
|
||||||
|
DEBUGASSERT(inode && inode->i_private);
|
||||||
|
|
||||||
|
priv = (FAR struct esp8266_dev_s *)inode->i_private;
|
||||||
|
|
||||||
|
/* Get exclusive access to the driver data structure */
|
||||||
|
ret = nxsem_wait(&priv->devsem);
|
||||||
|
|
||||||
|
if(ret < 0)
|
||||||
|
{
|
||||||
|
esp8266err("ERROR: nxsem_wait failed: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Process the IOCTL by command */
|
||||||
|
|
||||||
|
switch(cmd)
|
||||||
|
{
|
||||||
|
case ESP8266IOC_SETFREQUENCY: /* arg: Pointer to uint32_t frequency value */
|
||||||
|
ptr = (FAR uint32_t *)((uintptr_t)arg);
|
||||||
|
DEBUGASSERT(priv->config != NULL && ptr != NULL);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ret = -ENOTTY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
nxsem_post(&priv->devsem);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: esp8266_poll
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int esp8266_poll(FAR struct file *filep, FAR struct pollfd *fds, bool setup)
|
||||||
|
{
|
||||||
|
FAR struct inode *inode;
|
||||||
|
FAR struct esp8266_dev_s *priv;
|
||||||
|
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
esp8266info("setup: %d\n", (int)setup);
|
||||||
|
|
||||||
|
DEBUGASSERT(filep && fds);
|
||||||
|
inode = filep->f_inode;
|
||||||
|
DEBUGASSERT(inode && inode->i_private);
|
||||||
|
|
||||||
|
priv = (FAR struct esp8266_dev_s *)inode->i_private;
|
||||||
|
|
||||||
|
/* Are we setting up the poll? Or tearing it down? */
|
||||||
|
ret = nxsem_wait(&priv->devsem);
|
||||||
|
|
||||||
|
if(ret < 0)
|
||||||
|
{
|
||||||
|
esp8266err("ERROR: nxsem_wait failed: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(setup)
|
||||||
|
{
|
||||||
|
/* Ignore waits that do not include POLLIN */
|
||||||
|
if((fds->events & POLLIN) == 0)
|
||||||
|
{
|
||||||
|
esp8266err("ERROR: Missing POLLIN: revents: %08x\n", fds->revents);
|
||||||
|
nxsem_post(&priv->devsem);
|
||||||
|
return -EDEADLK;
|
||||||
|
}
|
||||||
|
esp8266_notify(priv->uart_dev);
|
||||||
|
}
|
||||||
|
else if(fds->priv)
|
||||||
|
{
|
||||||
|
/* This is a request to tear down the poll. */
|
||||||
|
struct pollfd **slot = (struct pollfd **)fds->priv;
|
||||||
|
DEBUGASSERT(slot != NULL);
|
||||||
|
/* Remove all memory of the poll setup */
|
||||||
|
*slot = NULL;
|
||||||
|
fds->priv = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
nxsem_post(&priv->devsem);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const struct file_operations esp8266_fops =
|
||||||
|
{
|
||||||
|
esp8266_open, /* open */
|
||||||
|
esp8266_close, /* close */
|
||||||
|
esp8266_read, /* read */
|
||||||
|
esp8266_write, /* write */
|
||||||
|
NULL, /* seek */
|
||||||
|
esp8266_ioctl, /* ioctl */
|
||||||
|
esp8266_poll /* poll */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: esp8266_register
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Register /dev/ext_uartN
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
static int esp8266_register(FAR const char *devpath)
|
||||||
|
{
|
||||||
|
FAR struct esp8266_dev_s *priv = &g_esp8266dev;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
nxsem_init(&priv->devsem, 0, 1);
|
||||||
|
nxsem_init(&priv->waitsem, 0, 0);
|
||||||
|
nxsem_set_protocol(&priv->waitsem, SEM_PRIO_NONE);
|
||||||
|
|
||||||
|
/* Register the driver */
|
||||||
|
ret = register_driver(devpath, &esp8266_fops, 0666, priv);
|
||||||
|
if(ret < 0)
|
||||||
|
{
|
||||||
|
kmm_free(priv);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void esp8266_notify(uart_dev_t *dev)
|
||||||
|
{
|
||||||
|
if(dev == g_esp8266dev.uart_dev)
|
||||||
|
nxsem_post(&g_esp8266dev.waitsem);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: esp8266_init
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Ch376 default initialization function
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void board_esp8266_initialize(void)
|
||||||
|
{
|
||||||
|
k210_fpioa_config(ESP8266_EN_PIN, ESP8266_FUNC_GPIO(FPIOA_ESP8266_EN));
|
||||||
|
k210_gpiohs_set_direction(FPIOA_ESP8266_EN, GPIO_DM_OUTPUT);
|
||||||
|
k210_gpiohs_set_value(FPIOA_ESP8266_EN, GPIO_PV_HIGH);
|
||||||
|
|
||||||
|
fpioa_set_function(ESP8266_RX_PIN, FPIOA_ESP8266_RX);
|
||||||
|
fpioa_set_function(ESP8266_TX_PIN, FPIOA_ESP8266_TX);
|
||||||
|
|
||||||
|
#if defined(CONFIG_U16550_UART2)
|
||||||
|
g_esp8266dev.dev_name = "/dev/uart2";
|
||||||
|
u16550_register(&g_esp8266dev.uart_dev, 2);
|
||||||
|
esp8266_register(esp8266_dev_name);
|
||||||
|
esp8266info("dev %p ok!\n", g_esp8266dev.uart_dev);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,137 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 AIIT XUOS Lab
|
||||||
|
* XiUOS is licensed under Mulan PSL v2.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||||
|
* You may obtain a copy of Mulan PSL v2 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL2
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||||
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||||
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the Mulan PSL v2 for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file k210_esp8266.h
|
||||||
|
* @brief define aiit-riscv64-board esp8266 function and struct
|
||||||
|
* @version 1.0
|
||||||
|
* @author AIIT XUOS Lab
|
||||||
|
* @date 2022-09-7
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __K210_ESP8266_H_
|
||||||
|
#define __K210_ESP8266_H_
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
#include <nuttx/kmalloc.h>
|
||||||
|
#include <nuttx/arch.h>
|
||||||
|
#include <nuttx/irq.h>
|
||||||
|
#include <nuttx/pthread.h>
|
||||||
|
#include <nuttx/semaphore.h>
|
||||||
|
#include <nuttx/wqueue.h>
|
||||||
|
#include <nuttx/wdog.h>
|
||||||
|
#include <nuttx/clock.h>
|
||||||
|
#include <nuttx/time.h>
|
||||||
|
#include <nuttx/fs/fs.h>
|
||||||
|
#include <nuttx/fs/ioctl.h>
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sched.h>
|
||||||
|
#include <debug.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#include <arch/board/board.h>
|
||||||
|
#include "riscv_internal.h"
|
||||||
|
|
||||||
|
#include "k210_config.h"
|
||||||
|
#include "k210_fpioa.h"
|
||||||
|
#include "k210_gpiohs.h"
|
||||||
|
#include "xidatong-riscv64.h"
|
||||||
|
#include "nuttx/serial/serial.h"
|
||||||
|
#include "nuttx/serial/uart_16550.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* Define CH438 PIN NUM */
|
||||||
|
#define ESP8266_RX_PIN 6
|
||||||
|
#define ESP8266_TX_PIN 7
|
||||||
|
#define ESP8266_EN_PIN 8
|
||||||
|
|
||||||
|
/* Define ch438 FPIOA NUMBER */
|
||||||
|
#define FPIOA_ESP8266_RX 66
|
||||||
|
#define FPIOA_ESP8266_TX 67
|
||||||
|
#define FPIOA_ESP8266_EN 4
|
||||||
|
|
||||||
|
#define ESP8266_FUNC_GPIO(n) ((K210_IO_FUNC_GPIOHS0 + n) | K210_IOFLAG_GPIOHS)
|
||||||
|
|
||||||
|
#define ESP8266IOC_SETFREQUENCY _WLIOC(0x0001) /* arg: Pointer to uint32_t frequency value */
|
||||||
|
#define ESP8266IOC_GETFREQUENCY _WLIOC(0x0002) /* arg: Pointer to uint32_t frequency value */
|
||||||
|
|
||||||
|
/* esp8266 debug */
|
||||||
|
#ifdef CONFIG_DEBUG_ESP8266_ERROR
|
||||||
|
# define esp8266err _err
|
||||||
|
#else
|
||||||
|
# define esp8266err _none
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_DEBUG_ESP8266_WARN
|
||||||
|
# define esp8266warn _warn
|
||||||
|
#else
|
||||||
|
# define esp8266warn _none
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_DEBUG_ESP8266_INFO
|
||||||
|
# define esp8266info _info
|
||||||
|
#else
|
||||||
|
# define esp8266info _none
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ESP8266_RECV_BUF_SIZE 256
|
||||||
|
#define ESP8266_INCREMENT MSEC2TICK(33)
|
||||||
|
|
||||||
|
struct esp8266_config_s
|
||||||
|
{
|
||||||
|
int (*attach)(FAR const struct esp8266_config_s *config, xcpt_t isr,
|
||||||
|
FAR void *arg);
|
||||||
|
void (*enable)(FAR const struct esp8266_config_s *config, bool enable);
|
||||||
|
void (*clear)(FAR const struct esp8266_config_s *config);
|
||||||
|
|
||||||
|
void (*wakeup)(FAR const struct esp8266_config_s *config);
|
||||||
|
void (*nreset)(FAR const struct esp8266_config_s *config, bool state);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct esp8266_dev_s
|
||||||
|
{
|
||||||
|
uint8_t crefs; /* Number of times the device
|
||||||
|
* has been opened */
|
||||||
|
uint8_t nwaiters; /* Number of threads waiting for
|
||||||
|
* data */
|
||||||
|
sem_t devsem; /* Manages exclusive access to
|
||||||
|
* this structure */
|
||||||
|
sem_t waitsem; /* Used to wait for the
|
||||||
|
* availability of data */
|
||||||
|
FAR const struct esp8266_config_s *config; /* Board configuration data */
|
||||||
|
struct work_s irqwork; /* Supports the interrupt
|
||||||
|
* handling "bottom half" */
|
||||||
|
char *dev_name;
|
||||||
|
int uart_fd;
|
||||||
|
uart_dev_t *uart_dev;
|
||||||
|
int recv_size;
|
||||||
|
uint8_t recv_buf[ESP8266_RECV_BUF_SIZE];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void esp8266_notify(uart_dev_t *dev);
|
||||||
|
void board_esp8266_initialize(void);
|
||||||
|
|
||||||
|
#endif
|
|
@ -47,11 +47,11 @@ int k210_fpioa_get_io_by_function(uint8_t function)
|
||||||
{
|
{
|
||||||
int index = 0;
|
int index = 0;
|
||||||
uint32_t RegValue = 0x0000;
|
uint32_t RegValue = 0x0000;
|
||||||
uint32_t *fpioa = (uint32_t *)K210_FPIOA_BASE;
|
uint32_t *fpioa_base = (uint32_t *)K210_FPIOA_BASE;
|
||||||
|
|
||||||
for (index = 0; index < K210_IO_NUMBER; index++)
|
for (index = 0; index < K210_IO_NUMBER; index++)
|
||||||
{
|
{
|
||||||
RegValue = getreg32(&fpioa[index]);
|
RegValue = getreg32(&fpioa_base[index]);
|
||||||
if ((RegValue & 0xFF) == function)
|
if ((RegValue & 0xFF) == function)
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,7 @@ int k210_fpioa_get_io_by_function(uint8_t function)
|
||||||
|
|
||||||
void k210_fpioa_config(uint32_t io, uint32_t ioflags)
|
void k210_fpioa_config(uint32_t io, uint32_t ioflags)
|
||||||
{
|
{
|
||||||
uint32_t *fpioa = (uint32_t *)K210_FPIOA_BASE;
|
uint32_t *fpioa_base = (uint32_t *)K210_FPIOA_BASE;
|
||||||
DEBUGASSERT(io < K210_IO_NUMBER);
|
DEBUGASSERT(io < K210_IO_NUMBER);
|
||||||
putreg32(ioflags, &fpioa[io]);
|
putreg32(ioflags, &fpioa_base[io]);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue