This is an automated email from the ASF dual-hosted git repository. xiaoxiang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit aa5ac49a21f64407ce38a5a75a08e36575bd2360 Author: raiden00pl <[email protected]> AuthorDate: Sat Jul 22 14:17:50 2023 +0200 arch/nrf91: convert modem AT interface to serial device --- arch/arm/src/nrf91/nrf91_modem_at.c | 332 ++++++++++++++++++++++++------------ 1 file changed, 226 insertions(+), 106 deletions(-) diff --git a/arch/arm/src/nrf91/nrf91_modem_at.c b/arch/arm/src/nrf91/nrf91_modem_at.c index 917b7644c3..1bab4411e1 100644 --- a/arch/arm/src/nrf91/nrf91_modem_at.c +++ b/arch/arm/src/nrf91/nrf91_modem_at.c @@ -25,7 +25,7 @@ #include <nuttx/config.h> #include <nuttx/fs/fs.h> -#include <nuttx/mutex.h> +#include <nuttx/serial/serial.h> #include <debug.h> #include <fcntl.h> @@ -39,6 +39,7 @@ ****************************************************************************/ #define NRF91_MODEM_AT_RX 255 +#define NRF91_MODEM_AT_TX 255 /**************************************************************************** * Private Types @@ -46,43 +47,89 @@ struct nrf91_modem_at_s { - char rxbuf[NRF91_MODEM_AT_RX]; - size_t rx_i; - sem_t rx_sem; - mutex_t lock; + /* Norificaiton */ + + bool notif_now; + const char *notif; + size_t notif_len; + size_t notif_i; + + /* Response */ + + const char *resp; + bool resp_now; + size_t resp_len; + size_t resp_i; + + /* TX */ + + char txbuf[NRF91_MODEM_AT_TX]; + size_t tx_i; }; /**************************************************************************** * Private Function Prototypes ****************************************************************************/ -static void nrf91_modem_at_notify_handler(const char *notif); -static void nrf91_modem_at_resp_handler(const char *resp); -static ssize_t nrf91_modem_at_read(struct file *filep, char *buffer, - size_t buflen); -static ssize_t nrf91_modem_at_write(struct file *filep, const char *buffer, - size_t buflen); +static int nrf91_modem_at_setup(struct uart_dev_s *dev); +static void nrf91_modem_at_shutdown(struct uart_dev_s *dev); +static int nrf91_modem_at_attach(struct uart_dev_s *dev); +static void nrf91_modem_at_detach(struct uart_dev_s *dev); static int nrf91_modem_at_ioctl(struct file *filep, int cmd, unsigned long arg); +static int nrf91_modem_at_receive(struct uart_dev_s *dev, + unsigned int *status); +static void nrf91_modem_at_rxint(struct uart_dev_s *dev, bool enable); +static bool nrf91_modem_at_rxavailable(struct uart_dev_s *dev); +static void nrf91_modem_at_send(struct uart_dev_s *dev, int ch); +static void nrf91_modem_at_txint(struct uart_dev_s *dev, bool enable); +static bool nrf91_modem_at_txready(struct uart_dev_s *dev); +static bool nrf91_modem_at_txempty(struct uart_dev_s *dev); /**************************************************************************** * Private Data ****************************************************************************/ -static const struct file_operations g_nrf91_modem_at_fops = +static const struct uart_ops_s g_nrf91_modem_at_fops = { - NULL, /* open */ - NULL, /* close */ - nrf91_modem_at_read, /* read */ - nrf91_modem_at_write, /* write */ - NULL, /* seek */ - nrf91_modem_at_ioctl, /* ioctl */ - NULL, /* mmap */ - NULL, /* truncate */ - NULL /* poll */ + .setup = nrf91_modem_at_setup, + .shutdown = nrf91_modem_at_shutdown, + .attach = nrf91_modem_at_attach, + .detach = nrf91_modem_at_detach, + .ioctl = nrf91_modem_at_ioctl, + .receive = nrf91_modem_at_receive, + .rxint = nrf91_modem_at_rxint, + .rxavailable = nrf91_modem_at_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif + .send = nrf91_modem_at_send, + .txint = nrf91_modem_at_txint, + .txready = nrf91_modem_at_txready, + .txempty = nrf91_modem_at_txempty, }; -static struct nrf91_modem_at_s g_nrf91_modem_at; +static struct nrf91_modem_at_s g_nrf91_modem_at_priv; + +static char g_modem1rxbuffer[NRF91_MODEM_AT_RX]; +static char g_modem1txbuffer[NRF91_MODEM_AT_TX]; + +static uart_dev_t g_nrf91_modem_at = +{ + .isconsole = false, + .ops = &g_nrf91_modem_at_fops, + .priv = &g_nrf91_modem_at_priv, + .recv = + { + .size = NRF91_MODEM_AT_RX, + .buffer = g_modem1rxbuffer, + }, + .xmit = + { + .size = NRF91_MODEM_AT_TX, + .buffer = g_modem1txbuffer, + }, +}; /**************************************************************************** * Private Functions @@ -94,16 +141,14 @@ static struct nrf91_modem_at_s g_nrf91_modem_at; static void nrf91_modem_at_notify_handler(const char *notif) { - struct nrf91_modem_at_s *dev = &g_nrf91_modem_at; - - /* Copy notify */ + struct uart_dev_s *dev = &g_nrf91_modem_at; + struct nrf91_modem_at_s *priv = (struct nrf91_modem_at_s *)dev->priv; - strncpy(&dev->rxbuf[dev->rx_i], notif, NRF91_MODEM_AT_RX - dev->rx_i); - dev->rx_i += strlen(notif); + priv->notif_i = 0; + priv->notif = notif; + priv->notif_len = strlen(notif); - /* Wake-up any thread waiting in recv */ - - nxsem_post(&dev->rx_sem); + uart_recvchars(dev); } /**************************************************************************** @@ -112,140 +157,215 @@ static void nrf91_modem_at_notify_handler(const char *notif) static void nrf91_modem_at_resp_handler(const char *resp) { - struct nrf91_modem_at_s *dev = &g_nrf91_modem_at; + struct uart_dev_s *dev = &g_nrf91_modem_at; + struct nrf91_modem_at_s *priv = (struct nrf91_modem_at_s *)dev->priv; + + priv->resp_i = 0; + priv->resp = resp; + priv->resp_len = strlen(resp); + + uart_recvchars(dev); +} + +/**************************************************************************** + * Name: nrf91_modem_at_setup + ****************************************************************************/ + +static int nrf91_modem_at_setup(struct uart_dev_s *dev) +{ + struct nrf91_modem_at_s *priv = (struct nrf91_modem_at_s *)dev->priv; + + /* Reset private data */ + + memset(priv, 0, sizeof(struct nrf91_modem_at_s)); + + /* Initialize AT modem */ + + nrf_modem_at_notif_handler_set(nrf91_modem_at_notify_handler); + nrf_modem_at_cmd_custom_set(NULL, 0); - /* Copy response */ + return OK; +} - strncpy(&dev->rxbuf[dev->rx_i], resp, NRF91_MODEM_AT_RX - dev->rx_i); - dev->rx_i += strlen(resp); +/**************************************************************************** + * Name: nrf91_modem_at_shutdown + ****************************************************************************/ - /* Wake-up any thread waiting in recv */ +static void nrf91_modem_at_shutdown(struct uart_dev_s *dev) +{ + nrf_modem_at_notif_handler_set(NULL); +} - nxsem_post(&dev->rx_sem); +/**************************************************************************** + * Name: nrf91_modem_at_attach + ****************************************************************************/ + +static int nrf91_modem_at_attach(struct uart_dev_s *dev) +{ + return OK; } /**************************************************************************** - * Name: nrf91_modem_at_read + * Name: nrf91_modem_at_detach ****************************************************************************/ -static ssize_t nrf91_modem_at_read(struct file *filep, char *buffer, - size_t len) +static void nrf91_modem_at_detach(struct uart_dev_s *dev) { - struct nrf91_modem_at_s *dev = NULL; - struct inode *inode = NULL; - int ret = 0; +} - DEBUGASSERT(filep); - inode = filep->f_inode; +/**************************************************************************** + * Name: nrf91_modem_at_ioct + ****************************************************************************/ - DEBUGASSERT(inode && inode->i_private); - dev = (struct nrf91_modem_at_s *)inode->i_private; +static int nrf91_modem_at_ioctl(struct file *filep, int cmd, + unsigned long arg) +{ + return OK; +} - ret = nxmutex_lock(&dev->lock); - if (ret < 0) - { - return ret; - } +/**************************************************************************** + * Name: nrf91_modem_at_receive + ****************************************************************************/ + +static int nrf91_modem_at_receive(struct uart_dev_s *dev, + unsigned int *status) +{ + struct nrf91_modem_at_s *priv = (struct nrf91_modem_at_s *)dev->priv; + char ch = 0; - if ((filep->f_oflags & O_NONBLOCK) != 0) + *status = 0; + + if (priv->resp != NULL && priv->notif_now == false) { - nxsem_trywait(&dev->rx_sem); - ret = 0; + priv->resp_now = true; + ch = priv->resp[priv->resp_i++]; + if (priv->resp_i >= priv->resp_len) + { + priv->resp = NULL; + priv->resp_now = false; + } } - else + else if (priv->notif != NULL && priv->resp_now == false) { - ret = nxsem_wait(&dev->rx_sem); + priv->notif_now = true; + ch = priv->notif[priv->notif_i++]; + if (priv->notif_i >= priv->notif_len) + { + priv->notif = NULL; + priv->notif_now = false; + } } - if (ret < 0) - { - return ret; - } + return (int)ch; +} - /* Get response data */ +/**************************************************************************** + * Name: nrf91_modem_at_rxint + ****************************************************************************/ - if (len > dev->rx_i) - { - len = dev->rx_i; - } +static void nrf91_modem_at_rxint(struct uart_dev_s *dev, bool enable) +{ +} - strncpy(buffer, dev->rxbuf, len); - dev->rx_i = 0; - ret = len; +/**************************************************************************** + * Name: nrf91_modem_at_rxavailable + ****************************************************************************/ - nxmutex_unlock(&dev->lock); - return ret; +static bool nrf91_modem_at_rxavailable(struct uart_dev_s *dev) +{ + struct nrf91_modem_at_s *priv = (struct nrf91_modem_at_s *)dev->priv; + return priv->notif || priv->resp; } /**************************************************************************** - * Name: nrf91_modem_at_write + * Name: nrf91_modem_at_send ****************************************************************************/ -static ssize_t nrf91_modem_at_write(struct file *filep, const char *buffer, - size_t len) +static void nrf91_modem_at_send(struct uart_dev_s *dev, int ch) { - struct nrf91_modem_at_s *dev = NULL; - struct inode *inode = NULL; - int ret = 0; + struct nrf91_modem_at_s *priv = (struct nrf91_modem_at_s *)dev->priv; + int ret = OK; + + if (priv->tx_i + 1 > NRF91_MODEM_AT_TX) + { + _err("no free space in TX buffer\n"); + } - DEBUGASSERT(filep); - inode = filep->f_inode; + priv->txbuf[priv->tx_i] = (char)ch; + priv->tx_i += 1; - DEBUGASSERT(inode && inode->i_private); - dev = (struct nrf91_modem_at_s *)inode->i_private; + /* Special formating Nordic AT interface (escape charactes) */ - ret = nxmutex_lock(&dev->lock); - if (ret < 0) + if (ch == '%') { - return ret; + priv->txbuf[priv->tx_i] = '%'; + priv->tx_i += 1; } - /* Send AT command */ + if (priv->txbuf[priv->tx_i - 1] == '\r') + { + priv->txbuf[priv->tx_i - 1] = '\0'; - ret = nrf_modem_at_cmd_async(nrf91_modem_at_resp_handler, buffer); + /* Send AT command */ - nxmutex_unlock(&dev->lock); - return ret; + ret = nrf_modem_at_cmd_async(nrf91_modem_at_resp_handler, priv->txbuf); + if (ret < 0) + { + _err("nrf_modem_at_cmd_async failed %d\n", ret); + } + + /* Reset buffer */ + + memset(priv->txbuf, 0, NRF91_MODEM_AT_TX); + priv->tx_i = 0; + } } /**************************************************************************** - * Name: nrf91_modem_at_ioct + * Name: nrf91_modem_at_txint ****************************************************************************/ -static int nrf91_modem_at_ioctl(struct file *filep, int cmd, - unsigned long arg) +static void nrf91_modem_at_txint(struct uart_dev_s *dev, bool enable) { - return -ENOTTY; + if (enable) + { + uart_xmitchars(dev); + } } /**************************************************************************** - * Public Functions + * Name: nrf91_modem_at_txready ****************************************************************************/ +static bool nrf91_modem_at_txready(struct uart_dev_s *dev) +{ + return true; +} + /**************************************************************************** - * Name: nrf91_at_register + * Name: nrf91_modem_at_txempty ****************************************************************************/ -int nrf91_at_register(const char *path) +static bool nrf91_modem_at_txempty(struct uart_dev_s *dev) { - struct nrf91_modem_at_s *dev = &g_nrf91_modem_at; - int ret = OK; - - /* Initialize mutex & sem */ - - memset(&g_nrf91_modem_at, 0, sizeof(struct nrf91_modem_at_s)); + return true; +} - nxmutex_init(&dev->lock); - nxsem_init(&dev->rx_sem, 0, 0); +/**************************************************************************** + * Public Functions + ****************************************************************************/ - /* Initialize AT modem */ +/**************************************************************************** + * Name: nrf91_at_register + ****************************************************************************/ - nrf_modem_at_notif_handler_set(nrf91_modem_at_notify_handler); - nrf_modem_at_cmd_custom_set(NULL, 0); +int nrf91_at_register(const char *path) +{ + int ret = OK; /* Register driver */ - ret = register_driver(path, &g_nrf91_modem_at_fops, 0666, dev); + ret = uart_register(path, &g_nrf91_modem_at); if (ret < 0) { nerr("ERROR: register_driver failed: %d\n", ret);
