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