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);

Reply via email to