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 2023/10/28 07:21:51 UTC

(nuttx) branch master updated: SAMA5D2 add new mcan ioctls

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


The following commit(s) were added to refs/heads/master by this push:
     new bfa14406d6 SAMA5D2 add new mcan ioctls
bfa14406d6 is described below

commit bfa14406d6242eedcd7507681b06ca026ff2ac35
Author: TimJTi <56...@users.noreply.github.com>
AuthorDate: Tue Sep 26 16:07:54 2023 +0100

    SAMA5D2 add new mcan ioctls
---
 arch/arm/src/sama5/sam_mcan.c | 200 +++++++++++++++++++++++++++++++++++++++---
 1 file changed, 188 insertions(+), 12 deletions(-)

diff --git a/arch/arm/src/sama5/sam_mcan.c b/arch/arm/src/sama5/sam_mcan.c
index 2f0b9d5266..54c2a2d76d 100644
--- a/arch/arm/src/sama5/sam_mcan.c
+++ b/arch/arm/src/sama5/sam_mcan.c
@@ -878,17 +878,17 @@ struct sam_mcan_s
 
   const struct sam_config_s *config;
 
-  enum can_state_s state;   /* See enum can_state_s */
+  enum can_state_s state;          /* See enum can_state_s                  */
 #ifdef CONFIG_CAN_EXTID
-  uint8_t nextalloc;        /* Number of allocated extended filters */
+  uint8_t          nextalloc;      /* Number of allocated extended filters  */
 #endif
-  uint8_t nstdalloc;        /* Number of allocated standard filters */
-  mutex_t lock;             /* Enforces mutually exclusive access */
-  sem_t txfsem;             /* Used to wait for TX FIFO availability */
-  uint32_t btp;             /* Current bit timing */
-  uint32_t fbtp;            /* Current fast bit timing */
-  uint32_t rxints;          /* Configured RX interrupts */
-  uint32_t txints;          /* Configured TX interrupts */
+  uint8_t          nstdalloc;      /* Number of allocated standard filters  */
+  mutex_t          lock;           /* Enforces mutually exclusive access    */
+  sem_t            txfsem;         /* Used to wait for TX FIFO availability */
+  uint32_t         btp;            /* Current bit timing                    */
+  uint32_t         fbtp;           /* Current fast bit timing               */
+  uint32_t         rxints;         /* Configured RX interrupts              */
+  uint32_t         txints;         /* Configured TX interrupts              */
 
 #ifdef CONFIG_CAN_EXTID
   uint32_t extfilters[2];   /* Extended filter bit allocator.  2*32=64 */
@@ -936,6 +936,10 @@ static int mcan_add_stdfilter(struct sam_mcan_s *priv,
                               struct canioc_stdfilter_s *stdconfig);
 static int mcan_del_stdfilter(struct sam_mcan_s *priv, int ndx);
 
+static int mcan_set_nart(struct sam_mcan_s *priv, bool enable);
+static int mcan_cancel_tx_buffers(struct sam_mcan_s *priv);
+static int mcan_cancel_rx_fifos(struct sam_mcan_s *priv);
+
 /* CAN driver methods */
 
 static void mcan_reset(struct can_dev_s *dev);
@@ -2838,6 +2842,69 @@ static int mcan_ioctl(struct can_dev_s *dev, int cmd, unsigned long arg)
         }
         break;
 
+        /* CANIOC_SET_NART:
+         *   Description:    Enable/Disable NART (No Automatic Retry)
+         *   Argument:       Set to 1 to enable NART, 0 to disable.
+         *                   Default is disabled.
+         *   Returned Value: Zero (OK) is returned on success. Otherwise -1
+         *                   (ERROR) is returned with the errno variable set
+         *                   to indicate the nature of the error.
+         *   Dependencies:   None
+         */
+
+      case CANIOC_SET_NART:
+        {
+          ret = mcan_set_nart(priv, (bool)arg);
+        }
+        break;
+
+      /* CANIOC_IFLUSH
+       *   Description:    Flush data received but not read
+       *   Argument:       None
+       *   Returned Value: Zero (OK) is returned on success.  Otherwise -1
+       *                   (ERROR) is returned with the errno variable set
+       *                   to indicate the nature of the error.
+       *   Dependencies:   None
+       */
+
+      case CANIOC_IFLUSH:
+        {
+          ret = mcan_cancel_rx_fifos(priv);
+        }
+        break;
+
+      /* CANIOC_OFLUSH
+       *   Description:    Flush data queued but not transmitted
+       *   Argument:       None
+       *   Returned Value: Zero (OK) is returned on success.  Otherwise -1
+       *                   (ERROR) is returned with the errno variable set
+       *                   to indicate the nature of the error.
+       *   Dependencies:   None
+       */
+
+      case CANIOC_OFLUSH:
+        {
+          ret = mcan_cancel_tx_buffers(priv);
+        }
+        break;
+
+      /* CANIOC_IOFLUSH
+       *   Description:    Flush data received but not read, and data queued
+                           but not transmitted
+       *   Argument:       None
+       *   Returned Value: Zero (OK) is returned on success.  Otherwise -1
+       *                   (ERROR) is returned with the errno variable set
+       *                   to indicate the nature of the error.
+       *   Dependencies:   None
+       */
+
+      case CANIOC_IOFLUSH:
+        {
+          ret = mcan_cancel_tx_buffers(priv);
+          ret = mcan_cancel_rx_fifos(priv);
+        }
+        break;
+
       /* Unsupported/unrecognized command */
 
       default:
@@ -2876,7 +2943,8 @@ static int mcan_remoterequest(struct can_dev_s *dev, uint16_t id)
  *    Send one can message.
  *
  *    One CAN-message consists of a maximum of 10 bytes.  A message is
- *    composed of at least the first 2 bytes (when there are no data bytes).
+ *    composed of at least the  && priv->config != NULLfirst 2 bytes
+ *    (when there are no data bytes).
  *
  *    Byte 0:      Bits 0-7: Bits 3-10 of the 11-bit CAN identifier
  *    Byte 1:      Bits 5-7: Bits 0-2 of the 11-bit CAN identifier
@@ -3380,6 +3448,114 @@ static void mcan_error(struct can_dev_s *dev, uint32_t status)
 }
 #endif /* CONFIG_CAN_ERRORS */
 
+/****************************************************************************
+ * Name: mcan_set_nart
+ *
+ * Description:
+ *   Enable/Disable NART (No Automatic Retry),
+ *   AKA "DAR" - Disable Automatic Retry
+ *
+ * Input Parameters:
+ *   priv      - An instance of the MCAN driver state structure.
+ *   enable - enable or disable.
+ *
+ * Returned Value:
+ *   Zero on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int mcan_set_nart(struct sam_mcan_s *priv, bool enable)
+{
+  uint32_t regval;
+
+  DEBUGASSERT(priv != NULL);
+
+  regval = mcan_getreg(priv, SAM_MCAN_CCCR_OFFSET);
+  if (enable)
+    {
+      regval |= MCAN_CCCR_DAR;
+    }
+  else
+    {
+      regval &= ~MCAN_CCCR_DAR;
+    }
+
+  mcan_putreg(priv, SAM_MCAN_CCCR_OFFSET, regval);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: mcan_cancel_tx_buffers
+ *
+ * Description:
+ *   Cancel all pending, buffered, transmissions
+ *
+ * Input Parameters:
+ *   priv      - An instance of the MCAN driver state structure.
+ *
+ * Returned Value:
+ *   Success
+ *
+ ****************************************************************************/
+
+static int mcan_cancel_tx_buffers(struct sam_mcan_s *priv)
+{
+  uint32_t regval;
+
+  DEBUGASSERT(priv != NULL);
+
+  mcan_putreg(priv, SAM_MCAN_TXBCR_OFFSET, 0xffff);
+
+  do
+    {
+      regval = mcan_getreg(priv, SAM_MCAN_TXBRP_OFFSET);
+    }
+  while (regval != 0);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: mcan_cancel_rx_fifos
+ *
+ * Description:
+ *   Cancel all queued/received messages
+ *
+ * Input Parameters:
+ *   priv      - An instance of the MCAN driver state structure.
+ *
+ * Returned Value:
+ *   Success
+ *
+ ****************************************************************************/
+
+static int mcan_cancel_rx_fifos(struct sam_mcan_s *priv)
+{
+  uint32_t ir;
+  uint32_t ie;
+  uint32_t pending;
+
+  DEBUGASSERT(priv != NULL);
+
+  mcan_putreg(priv, SAM_MCAN_RXF0A_OFFSET, 0);
+  mcan_putreg(priv, SAM_MCAN_RXF1A_OFFSET, 0);
+
+  /* Clear RX interrupts */
+
+  ir = mcan_getreg(priv, SAM_MCAN_IR_OFFSET);
+  ie = mcan_getreg(priv, SAM_MCAN_IE_OFFSET);
+
+  pending = (ir & ie);
+
+  if ((pending & priv->rxints) != 0)
+    {
+      mcan_putreg(priv, SAM_MCAN_IR_OFFSET, priv->rxints);
+    }
+
+  return OK;
+}
+
 /****************************************************************************
  * Name: mcan_receive
  *
@@ -3713,7 +3889,7 @@ static int mcan_interrupt(int irq, void *context, void *arg)
           /* Check if there is anything in RX FIFO1 */
 
           regval = mcan_getreg(priv, SAM_MCAN_RXF1S_OFFSET);
-          nelem  = (regval & MCAN_RXF0S_F0FL_MASK) >> MCAN_RXF0S_F0FL_SHIFT;
+          nelem  = (regval & MCAN_RXF1S_F1FL_MASK) >> MCAN_RXF1S_F1FL_SHIFT;
           if (nelem == 0)
             {
               /* Break out of the loop if RX FIFO1 is empty */
@@ -3729,7 +3905,7 @@ static int mcan_interrupt(int irq, void *context, void *arg)
 
           ndx = (regval & MCAN_RXF1S_F1GI_MASK) >> MCAN_RXF1S_F1GI_SHIFT;
 
-          if ((regval & MCAN_RXF0S_RF0L) != 0)
+          if ((regval & MCAN_RXF1S_RF1L) != 0)
             {
               canerr("ERROR: Message lost: %08" PRIx32 "\n", regval);
             }