You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2024/09/28 05:12:00 UTC

(nuttx) 02/02: capture:add multiple register.

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 9a84484df5dd4c67a51b4ecb097ffd56435b23e8
Author: yangguangcai <ya...@xiaomi.com>
AuthorDate: Tue Jul 2 09:52:42 2024 +0800

    capture:add multiple register.
    
    Signed-off-by: yangguangcai <ya...@xiaomi.com>
---
 drivers/timers/capture.c       | 145 +++++++++++++++++++++++++++++------------
 include/nuttx/timers/capture.h |   3 +
 2 files changed, 107 insertions(+), 41 deletions(-)

diff --git a/drivers/timers/capture.c b/drivers/timers/capture.c
index a67614d150..fa2db25d14 100644
--- a/drivers/timers/capture.c
+++ b/drivers/timers/capture.c
@@ -60,8 +60,9 @@
 struct cap_upperhalf_s
 {
   uint8_t                    crefs;    /* The number of times the device has been opened */
+  uint8_t                    nchan;    /* The number of channels, only invalid for multi channels */
   mutex_t                    lock;     /* Supports mutual exclusion */
-  FAR struct cap_lowerhalf_s *lower;   /* lower-half state */
+  FAR struct cap_lowerhalf_s **lower;  /* lower-half state */
 };
 
 /****************************************************************************
@@ -135,16 +136,21 @@ static int cap_open(FAR struct file *filep)
 
   if (tmp == 1)
     {
-      FAR struct cap_lowerhalf_s *lower = upper->lower;
+      FAR struct cap_lowerhalf_s **lower = upper->lower;
+      uint8_t i;
 
-      /* Yes.. perform one time hardware initialization. */
-
-      DEBUGASSERT(lower->ops->start != NULL);
-
-      ret = lower->ops->start(lower);
-      if (ret < 0)
+      for (i = 0; i < upper->nchan; i++)
         {
-          goto errout_with_lock;
+          ret = lower[i]->ops->start(lower[i]);
+          if (ret < 0)
+            {
+              while (i-- > 0)
+                {
+                  lower[i]->ops->stop(lower[i]);
+                }
+
+              goto errout_with_lock;
+            }
         }
     }
 
@@ -192,17 +198,19 @@ static int cap_close(FAR struct file *filep)
     }
   else
     {
-      FAR struct cap_lowerhalf_s *lower = upper->lower;
+      FAR struct cap_lowerhalf_s **lower = upper->lower;
+      uint8_t i;
 
       /* There are no more references to the port */
 
       upper->crefs = 0;
 
-      /* Disable the PWM Capture device */
-
-      DEBUGASSERT(lower->ops->stop != NULL);
+      for (i = 0; i < upper->nchan; i++)
+        {
+          /* Disable the PWM Capture device */
 
-      lower->ops->stop(lower);
+          lower[i]->ops->stop(lower[i]);
+        }
     }
 
   nxmutex_unlock(&upper->lock);
@@ -257,10 +265,11 @@ static ssize_t cap_write(FAR struct file *filep,
 
 static int cap_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
 {
-  FAR struct inode          *inode = filep->f_inode;
+  FAR struct inode           *inode = filep->f_inode;
   FAR struct cap_upperhalf_s *upper;
-  FAR struct cap_lowerhalf_s *lower;
+  FAR struct cap_lowerhalf_s **lower;
   int                        ret;
+  uint8_t                    i;
 
   cpinfo("cmd: %d arg: %ld\n", cmd, arg);
   upper = inode->i_private;
@@ -287,8 +296,16 @@ static int cap_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
       case CAPIOC_DUTYCYCLE:
         {
           FAR uint8_t *ptr = (FAR uint8_t *)((uintptr_t)arg);
-          DEBUGASSERT(lower->ops->getduty != NULL && ptr);
-          ret = lower->ops->getduty(lower, ptr);
+          DEBUGASSERT(ptr);
+          for (i = 0; i < upper->nchan; i++)
+            {
+              DEBUGASSERT(lower[i]->ops->getduty != NULL);
+              ret = lower[i]->ops->getduty(lower[i], &ptr[i]);
+              if (ret < 0)
+                {
+                  break;
+                }
+            }
         }
         break;
 
@@ -299,8 +316,16 @@ static int cap_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
       case CAPIOC_FREQUENCE:
         {
           FAR uint32_t *ptr = (FAR uint32_t *)((uintptr_t)arg);
-          DEBUGASSERT(lower->ops->getfreq != NULL && ptr);
-          ret = lower->ops->getfreq(lower, ptr);
+          DEBUGASSERT(ptr);
+          for (i = 0; i < upper->nchan; i++)
+            {
+              DEBUGASSERT(lower[i]->ops->getfreq != NULL);
+              ret = lower[i]->ops->getfreq(lower[i], &ptr[i]);
+              if (ret < 0)
+                {
+                  break;
+                }
+            }
         }
         break;
 
@@ -311,8 +336,16 @@ static int cap_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
       case CAPIOC_EDGES:
         {
           FAR uint32_t *ptr = (FAR uint32_t *)((uintptr_t)arg);
-          DEBUGASSERT(lower->ops->getedges != NULL && ptr);
-          ret = lower->ops->getedges(lower, ptr);
+          DEBUGASSERT(ptr);
+          for (i = 0; i < upper->nchan; i++)
+            {
+              DEBUGASSERT(lower[i]->ops->getedges != NULL);
+              ret = lower[i]->ops->getedges(lower[i], &ptr[i]);
+              if (ret < 0)
+                {
+                  break;
+                }
+            }
         }
         break;
 
@@ -325,26 +358,26 @@ static int cap_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
         {
           FAR struct cap_all_s *ptr =
                      (FAR struct cap_all_s *)((uintptr_t)arg);
-          DEBUGASSERT(lower->ops->getduty != NULL && ptr);
-          DEBUGASSERT(lower->ops->getedges != NULL && ptr);
-          DEBUGASSERT(lower->ops->getfreq != NULL && ptr);
-
-          ret = lower->ops->getduty(lower, &ptr->duty);
-          if (ret < 0)
-            {
-              break;
-            }
-
-          ret = lower->ops->getfreq(lower, &ptr->freq);
-          if (ret < 0)
-            {
-              break;
-            }
-
-          ret = lower->ops->getedges(lower, &ptr->edges);
-          if (ret < 0)
+          DEBUGASSERT(ptr);
+          for (i = 0 ; i < upper->nchan ; i++)
             {
-              break;
+              ret = lower[i]->ops->getduty(lower[i], &ptr[i].duty);
+              if (ret < 0)
+                {
+                  break;
+                }
+
+              ret = lower[i]->ops->getfreq(lower[i], &ptr[i].freq);
+              if (ret < 0)
+                {
+                  break;
+                }
+
+              ret = lower[i]->ops->getedges(lower[i], &ptr[i].edges);
+              if (ret < 0)
+                {
+                  break;
+                }
             }
         }
         break;
@@ -395,6 +428,35 @@ int cap_register(FAR const char *devpath, FAR struct cap_lowerhalf_s *lower)
 
   /* Allocate the upper-half data structure */
 
+  upper = (FAR struct cap_upperhalf_s *)
+           kmm_zalloc(sizeof(struct cap_upperhalf_s) +
+                      sizeof(FAR struct cap_lowerhalf_s *));
+  if (!upper)
+    {
+      return -ENOMEM;
+    }
+
+  /* Initialize the PWM Capture device structure
+   * (it was already zeroed by kmm_zalloc())
+   */
+
+  nxmutex_init(&upper->lock);
+  upper->lower = (FAR struct cap_lowerhalf_s **)(upper + 1);
+  upper->lower[0] = lower;
+  upper->nchan = 1;
+
+  /* Register the PWM Capture device */
+
+  return register_driver(devpath, &g_capops, 0666, upper);
+}
+
+int cap_register_multiple(FAR const char *devpath,
+                          FAR struct cap_lowerhalf_s **lower, int n)
+{
+  FAR struct cap_upperhalf_s *upper;
+
+  /* Allocate the upper-half data structure */
+
   upper = (FAR struct cap_upperhalf_s *)
            kmm_zalloc(sizeof(struct cap_upperhalf_s));
   if (!upper)
@@ -408,6 +470,7 @@ int cap_register(FAR const char *devpath, FAR struct cap_lowerhalf_s *lower)
 
   nxmutex_init(&upper->lock);
   upper->lower = lower;
+  upper->nchan = n;
 
   /* Register the PWM Capture device */
 
diff --git a/include/nuttx/timers/capture.h b/include/nuttx/timers/capture.h
index 1f6ec19051..fb9e46d8b2 100644
--- a/include/nuttx/timers/capture.h
+++ b/include/nuttx/timers/capture.h
@@ -134,6 +134,9 @@ extern "C"
 int cap_register(FAR const char *devpath,
                  FAR struct cap_lowerhalf_s *lower);
 
+int cap_register_multiple(FAR const char *devpath,
+                          FAR struct cap_lowerhalf_s **lower, int n);
+
 #undef EXTERN
 #ifdef __cplusplus
 }