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 2021/02/26 06:31:09 UTC

[incubator-nuttx] branch master updated (48050c9 -> 04fc5e3)

This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git.


    from 48050c9  signal: set SIGRTMIN to SIGUSR1 because signo 0 don't catch.
     new 3b219fb  boards/arm/imxrt/teensy-4.x: allow configuration of all CANs
     new 04fc5e3  arch/arm/src/imxrt: updated flexcan driver to support classical and FD frames at once

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 arch/arm/src/imxrt/Kconfig                         |  24 +-
 arch/arm/src/imxrt/hardware/imxrt_flexcan.h        |  60 ++-
 arch/arm/src/imxrt/imxrt_flexcan.c                 | 410 ++++++++++++---------
 boards/arm/imxrt/teensy-4.x/README.txt             |  14 +-
 .../arm/imxrt/teensy-4.x/configs/can-4.1/defconfig |  12 +-
 boards/arm/imxrt/teensy-4.x/src/imxrt_flexcan.c    |  17 +-
 6 files changed, 299 insertions(+), 238 deletions(-)


[incubator-nuttx] 02/02: arch/arm/src/imxrt: updated flexcan driver to support classical and FD frames at once

Posted by xi...@apache.org.
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/incubator-nuttx.git

commit 04fc5e314da0e5d0039e721ccf1127ba7ee3f92e
Author: Michal Lenc <mi...@seznam.cz>
AuthorDate: Thu Feb 25 23:30:45 2021 +0100

    arch/arm/src/imxrt: updated flexcan driver to support classical and FD frames at once
    
    Signed-off-by: Michal Lenc <mi...@seznam.cz>
---
 arch/arm/src/imxrt/Kconfig                  |  24 +-
 arch/arm/src/imxrt/hardware/imxrt_flexcan.h |  60 ++--
 arch/arm/src/imxrt/imxrt_flexcan.c          | 410 ++++++++++++++++------------
 3 files changed, 279 insertions(+), 215 deletions(-)

diff --git a/arch/arm/src/imxrt/Kconfig b/arch/arm/src/imxrt/Kconfig
index 4783121..af12180 100644
--- a/arch/arm/src/imxrt/Kconfig
+++ b/arch/arm/src/imxrt/Kconfig
@@ -450,6 +450,26 @@ config IMXRT_FLEXCAN3
 	select NET_CAN_HAVE_TX_DEADLINE
 	select NET_CAN_HAVE_CANFD
 
+if IMXRT_FLEXCAN1 || IMXRT_FLEXCAN2 || IMXRT_FLEXCAN3
+
+config IMXRT_FLEXCAN_TXMB
+	int "Number of TX message buffers"
+	default 3
+	---help---
+	This defines number of TX messages buffers. Please note that
+	maximum number of all message buffers is 13 (one MB has to
+	be reserved for chip errata ERR005829).
+
+config IMXRT_FLEXCAN_RXMB
+	int "Number of RX message buffers"
+	default 10
+	---help---
+	This defines number of RX messages buffers. Please note that
+	maximum number of all message buffers is 13 (one MB has to
+	be reserved for chip errata ERR005829).
+
+endif
+
 endmenu # FLEXCAN Peripherals
 
 menu "FLEXCAN1 Configuration"
@@ -457,12 +477,10 @@ menu "FLEXCAN1 Configuration"
 
 config FLEXCAN1_BITRATE
 	int "CAN bitrate"
-	depends on !NET_CAN_CANFD
 	default 1000000
 
 config FLEXCAN1_SAMPLEP
 	int "CAN sample point"
-	depends on !NET_CAN_CANFD
 	default 80
 
 endmenu # IMXRT_FLEXCAN1
@@ -472,12 +490,10 @@ menu "FLEXCAN2 Configuration"
 
 config FLEXCAN2_BITRATE
 	int "CAN bitrate"
-	depends on !NET_CAN_CANFD
 	default 1000000
 
 config FLEXCAN2_SAMPLEP
 	int "CAN sample point"
-	depends on !NET_CAN_CANFD
 	default 80
 
 endmenu # IMXRT_FLEXCAN2
diff --git a/arch/arm/src/imxrt/hardware/imxrt_flexcan.h b/arch/arm/src/imxrt/hardware/imxrt_flexcan.h
index f02a31f..1530587 100644
--- a/arch/arm/src/imxrt/hardware/imxrt_flexcan.h
+++ b/arch/arm/src/imxrt/hardware/imxrt_flexcan.h
@@ -122,11 +122,9 @@
 #define IMXRT_CAN_RXIMR62_OFFSET  0x0978            /* R62 Individual Mask Registers */
 #define IMXRT_CAN_RXIMR63_OFFSET  0x097c            /* R63 Individual Mask Registers */
 
-#ifdef CONFIG_IMXRT_FLEXCAN3
 #define IMXRT_CAN_FDCTRL_OFFSET   0x0c00            /* CAN FD Control Register */
 #define IMXRT_CAN_FDCBT_OFFSET    0x0c04            /* CAN FD Bit Timing Register */
 #define IMXRT_CAN_FDCRC_OFFSET    0x0c08            /* CAN FD CRC register */
-#endif /* CONFIG_IMXRT_FLEXCAN3 */
 
 /* Register Bit Definitions *************************************************/
 
@@ -143,20 +141,17 @@
 #  define CAN_MCR_IDAM_FMTD        (3 << CAN_MCR_IDAM_SHIFT) /* Format D: All frames rejected */
 
                                              /* Bit 10: Reserved */
-#ifdef CONFIG_IMXRT_FLEXCAN3
-#  define CAN_MCR_FDEN             (1 << 11) /* Bit 11: CAN FD Operation Enable */
-#endif                                       /* Bit 11: Reserved for FlexCAN1 and FlexCAN2 */
+#define CAN_MCR_FDEN               (1 << 11) /* Bit 11: CAN FD Operation Enable */
+                                             /* Bit 11: Reserved for FlexCAN1 and FlexCAN2 */
 #define CAN_MCR_AEN                (1 << 12) /* Bit 12: Abort Enable */
 #define CAN_MCR_LPRIOEN            (1 << 13) /* Bit 13: Local Priority Enable */
                                              /* Bit 14: Reserved */
-#ifdef CONFIG_IMXRT_FLEXCAN3
-#  define CAN_MCR_DMA              (1 << 15) /* Bit 15: DMA Enable */
-#endif                                       /* Bit 15: Reserved for FlexCAN1 and FlexCAN2 */
+#define CAN_MCR_DMA                (1 << 15) /* Bit 15: DMA Enable */
+                                             /* Bit 15: Reserved for FlexCAN1 and FlexCAN2 */
 #define CAN_MCR_IRMQ               (1 << 16) /* Bit 16: Individual Rx Masking and Queue Enable */
 #define CAN_MCR_SRXDIS             (1 << 17) /* Bit 17: Self Reception Disable */
-#ifdef CONFIG_IMXRT_FLEXCAN3
-#  define CAN_MCR_DOZE             (1 << 18) /* Bit 18: Doze Mode Enable */
-#endif                                       /* Bit 18: Reserved for FlexCAN1 and FlexCAN2 */
+#define CAN_MCR_DOZE               (1 << 18) /* Bit 18: Doze Mode Enable */
+                                             /* Bit 18: Reserved for FlexCAN1 and FlexCAN2 */
 #define CAN_MCR_WAKSRC             (1 << 19) /* Bit 19: Wake Up Source */
 #define CAN_MCR_LPMACK             (1 << 20) /* Bit 20: Low Power Mode Acknowledge */
 #define CAN_MCR_WRNEN              (1 << 21) /* Bit 21: Warning Interrupt Enable */
@@ -185,9 +180,8 @@
 #define CAN_CTRL1_RWRNMSK          (1 << 10) /* Bit 10: Rx Warning Interrupt Mask */
 #define CAN_CTRL1_TWRNMSK          (1 << 11) /* Bit 11: Tx Warning Interrupt Mask */
 #define CAN_CTRL1_LPB              (1 << 12) /* Bit 12: Loop Back Mode */
-#ifdef CONFIG_IMXRT_FLEXCAN3
-#  define CAN_CTRL1_CLKSRC         (1 << 13) /* Bit 13: CAN Engine Clock Source */
-#endif                                       /* Bit 13: Reserved for FlexCAN1 and FlexCAN2 */
+#define CAN_CTRL1_CLKSRC           (1 << 13) /* Bit 13: CAN Engine Clock Source */
+                                             /* Bit 13: Reserved for FlexCAN1 and FlexCAN2 */
 #define CAN_CTRL1_ERRMSK           (1 << 14) /* Bit 14: Error Mask */
 #define CAN_CTRL1_BOFFMSK          (1 << 15) /* Bit 15: Bus Off Mask */
 #define CAN_CTRL1_PSEG2_SHIFT      (16)      /* Bits 16-18: Phase Segment 2 */
@@ -227,12 +221,11 @@
 #define CAN_ECR_TXERRCNT_MASK      (0xff << CAN_ECR_TXERRCNT_SHIFT)
 #define CAN_ECR_RXERRCNT_SHIFT     (8)       /* Bits 8-15: Receive Error Counter */
 #define CAN_ECR_RXERRCNT_MASK      (0xff << CAN_ECR_RXERRCNT_SHIFT)
-#ifdef CONFIG_IMXRT_FLEXCAN3
-#  define CAN_ECR_TXERRCNTFAST_SHIFT (16)    /* Bits 16-23: Transmit Error Counter for fast bits */
-#  define CAN_ECR_TXERRCNTFAST_MASK  (0xff << CAN_ECR_TXERRCNTFAST_SHIFT)
-#  define CAN_ECR_RXERRCNTFAST_SHIFT (24)    /* Bits 24-31: Receive Error Counter for fast bits */
-#  define CAN_ECR_RXERRCNTFAST_MASK  (0xff << CAN_ECR_RXERRCNTFAST_SHIFT)
-#endif                                       /* Bits 16-31: Reserved for FlexCAN1 and FlexCAN2 */
+#define CAN_ECR_TXERRCNTFAST_SHIFT (16)      /* Bits 16-23: Transmit Error Counter for fast bits */
+#define CAN_ECR_TXERRCNTFAST_MASK  (0xff << CAN_ECR_TXERRCNTFAST_SHIFT)
+#define CAN_ECR_RXERRCNTFAST_SHIFT (24)      /* Bits 24-31: Receive Error Counter for fast bits */
+#define CAN_ECR_RXERRCNTFAST_MASK  (0xff << CAN_ECR_RXERRCNTFAST_SHIFT)
+                                             /* Bits 16-31: Reserved for FlexCAN1 and FlexCAN2 */
 
 /* Error and Status 1 Register */
 
@@ -261,7 +254,6 @@
 #define CAN_ESR1_RWRNINT           (1 << 16) /* Bit 16: Rx Warning Interrupt Flag */
 #define CAN_ESR1_TWRNINT           (1 << 17) /* Bit 17: Tx Warning Interrupt Flag */
 #define CAN_ESR1_SYNCH             (1 << 18) /* Bit 18: CAN Synchronization Status */
-#ifdef CONFIG_IMXRT_FLEXCAN3
 #define CAN_ESR1_BOFFDONEINT       (1 << 19) /* Bit 19: Bus Off Done Interrupt */
 #define CAN_ESR1_ERRINTFAST        (1 << 20) /* Bit 20: Error Iterrupt for Errors Detected in Data Phase of CAN FD frames */
 #define CAN_ESR1_ERROVR            (1 << 21) /* Bit 21: Error Overrun */
@@ -272,7 +264,7 @@
                                              /* Bit 29: Reserved */
 #define CAN_ESR1_BIT0ERRFAST       (1 << 30) /* Bit 30: Bit0 Error in the Data Phase of CAN FD frames */
 #define CAN_ESR1_BIT1ERRFAST       (1 << 31) /* Bit 31: Bit1 Error in the Data Phase of CAN FD frames */
-#endif                                       /* Bits 19-31: Reserved for FlexCAN1 and FlexCAN2 */
+                                             /* Bits 19-31: Reserved for FlexCAN1 and FlexCAN2 */
 
 /* Interrupt Masks 2 Register */
 
@@ -292,14 +284,13 @@
 
 /* Control 2 Register */
 
-#ifdef CONFIG_IMXRT_FLEXCAN3
                                              /* Bits 0-10: Reserved */
-#  define CAN_CTRL2_EDFLTDIS       (1 << 11) /* Bit 11: Edge Filter Disable */
-#  define CAN_CTRL2_ISOCANFDEN     (1 << 12) /* Bit 12: ISO CAN FD Enable */
+#define CAN_CTRL2_EDFLTDIS         (1 << 11) /* Bit 11: Edge Filter Disable */
+#define CAN_CTRL2_ISOCANFDEN       (1 << 12) /* Bit 12: ISO CAN FD Enable */
                                              /* Bit 13: Reserved */
-#  define CAN_CTRL2_PREXCEN        (1 << 14) /* Bit 14: Protocol Exception Enable */
-#  define CAN_CTRL2_TIMERSRC       (1 << 15) /* Bit 15: Timer Source */
-#endif                                       /* Bits 0-15: Reserved for FlexCAN1 and FlexCAN2 */
+#define CAN_CTRL2_PREXCEN          (1 << 14) /* Bit 14: Protocol Exception Enable */
+#define CAN_CTRL2_TIMERSRC         (1 << 15) /* Bit 15: Timer Source */
+                                             /* Bits 0-15: Reserved for FlexCAN1 and FlexCAN2 */
 #define CAN_CTRL2_EACEN            (1 << 16) /* Bit 16: Entire Frame Arbitration Field Comparison Enable (Rx) */
 #define CAN_CTRL2_RRS              (1 << 17) /* Bit 17: Remote Request Storing */
 #define CAN_CTRL2_MRP              (1 << 18) /* Bit 18: Mailboxes Reception Priority */
@@ -323,14 +314,11 @@
 #  define CAN_CTRL2_RFFN_112MB     (13 << CAN_CTRL2_RFFN_SHIFT)
 #  define CAN_CTRL2_RFFN_120MB     (14 << CAN_CTRL2_RFFN_SHIFT)
 #  define CAN_CTRL2_RFFN_128MB     (15 << CAN_CTRL2_RFFN_SHIFT)
-#ifdef CONFIG_IMXRT_FLEXCAN3
                                              /* Bits 28-29: Reserved */
-#  define CAN_CTRL2_BOFFDONEMSK    (1 << 30) /* Bit 30: Bus Off Done Interrupt Mask */
-#  define CAN_CTRL2_ERRMSKFAST     (1 << 31) /* Bit 31: Error Interrupt for Errors Detected in the Data Phase of CAN FD frames */
-#else
-#  define CAN_CTRL2_WRMFRZ         (1 << 28) /* Bit 28: Enable unrestricted write access to FlexCAN memory in Freeze mode */
+#define CAN_CTRL2_BOFFDONEMSK      (1 << 30) /* Bit 30: Bus Off Done Interrupt Mask */
+#define CAN_CTRL2_ERRMSKFAST       (1 << 31) /* Bit 31: Error Interrupt for Errors Detected in the Data Phase of CAN FD frames */
+#define CAN_CTRL2_WRMFRZ           (1 << 28) /* Bit 28: Enable unrestricted write access to FlexCAN memory in Freeze mode */
                                              /* Bits 29-31: Reserved */
-#endif
 
 /* Error and Status 2 Register */
 
@@ -365,8 +353,6 @@
 
 #define CAN_RXIMR(n)               (1 << (n)) /* Bit n: Individual Mask Bits */
 
-#ifdef CONFIG_IMXRT_FLEXCAN3
-
 /* CAN Bit Timing register */
 
 #define CAN_CBT_EPSEG2_SHIFT       (0)       /* Bits 0-4: Extended Phase Segment 2 */
@@ -441,8 +427,6 @@
 #define CAN_FDCRC_FD_MBCRC(x)      (((uint32_t)(((uint32_t)(x)) << CAN_FDCRC_FD_MBCRC_SHIFT)) & CAN_FDCRC_FD_MBCRC_MASK)
                                             /* Bit 31: Reserved */
 
-#endif /* CONFIG_IMXRT_FLEXCAN3 */
-
 /* CAN MB TX codes */
 #define CAN_TXMB_INACTIVE          0x8        /* MB is not active. */
 #define CAN_TXMB_ABORT             0x9        /* MB is aborted. */
diff --git a/arch/arm/src/imxrt/imxrt_flexcan.c b/arch/arm/src/imxrt/imxrt_flexcan.c
index 6b2f978..68d1788 100644
--- a/arch/arm/src/imxrt/imxrt_flexcan.c
+++ b/arch/arm/src/imxrt/imxrt_flexcan.c
@@ -39,6 +39,7 @@
 #include <nuttx/arch.h>
 #include <nuttx/wqueue.h>
 #include <nuttx/signal.h>
+#include <nuttx/spinlock.h>
 #include <nuttx/net/netdev.h>
 #include <nuttx/net/can.h>
 
@@ -78,12 +79,12 @@
 #define FLAGEFF                     (1 << 31) /* Extended frame format */
 #define FLAGRTR                     (1 << 30) /* Remote transmission request */
 
-#define RXMBCOUNT                   10
-#define TXMBCOUNT                   4
+#define RXMBCOUNT                   CONFIG_IMXRT_FLEXCAN_RXMB
+#define TXMBCOUNT                   (CONFIG_IMXRT_FLEXCAN_TXMB + 1)
 #define TOTALMBCOUNT                RXMBCOUNT + TXMBCOUNT
 
 #define IFLAG1_RX                   ((1 << RXMBCOUNT)-1)
-#define IFLAG1_TX                   (((1 << TXMBCOUNT)-1) << RXMBCOUNT)
+#define IFLAG1_TX                   (((1 << TXMBCOUNT)-2) << RXMBCOUNT)
 
 #define CAN_FIFO_NE                 (1 << 5)
 #define CAN_FIFO_OV                 (1 << 6)
@@ -125,11 +126,23 @@
 #define TX_TIMEOUT_WQ
 #endif
 
+#if (CONFIG_IMXRT_FLEXCAN_RXMB + CONFIG_IMXRT_FLEXCAN_TXMB) > 13
+# error Only 13 MB are allowed to be used
+#endif
+
 /* Interrupt flags for RX fifo */
 #define IFLAG1_RXFIFO               (CAN_FIFO_NE | CAN_FIFO_WARN | CAN_FIFO_OV)
 
 static int peak_tx_mailbox_index_ = 0;
 
+static uint8_t mb_address[] =
+                              {
+                               0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c,
+                               0x1e, 0x20, 0x22, 0x24, 0x26, 0x28, 0x2a,
+                               0x10, 0x19, 0x22, 0x2b, 0x34, 0x3d, 0x46,
+                               0x50, 0x59, 0x62, 0x6b, 0x74, 0x7d, 0x86
+                              };
+
 /****************************************************************************
  * Private Types
  ****************************************************************************/
@@ -185,11 +198,7 @@ struct mb_s
 {
   union cs_e cs;
   union id_e id;
-#ifdef CONFIG_NET_CAN_CANFD
-  union data_e data[16];
-#else
-  union data_e data[2];
-#endif
+  union data_e data[];
 };
 
 #ifdef CONFIG_NET_CAN_RAW_TX_DEADLINE
@@ -260,30 +269,24 @@ struct imxrt_driver_s
 {
   uint32_t base;                /* FLEXCAN base address */
   bool bifup;                   /* true:ifup false:ifdown */
+  bool canfd_capable;
+  int mb_address_offset;
 #ifdef TX_TIMEOUT_WQ
   WDOG_ID txtimeout[TXMBCOUNT]; /* TX timeout timer */
 #endif
-  struct work_s irqwork;        /* For deferring interrupt work to the wq */
-  struct work_s pollwork;       /* For deferring poll work to the work wq */
-#ifdef CONFIG_NET_CAN_CANFD
-  struct canfd_frame *txdesc;   /* A pointer to the list of TX descriptor */
-  struct canfd_frame *rxdesc;   /* A pointer to the list of RX descriptors */
-#else
-  struct can_frame *txdesc;     /* A pointer to the list of TX descriptor */
-  struct can_frame *rxdesc;     /* A pointer to the list of RX descriptors */
-#endif
+  struct work_s irqwork;            /* For deferring interrupt work to the wq */
+  struct work_s pollwork;           /* For deferring poll work to the work wq */
+  struct canfd_frame *txdesc_fd;    /* A pointer to the list of TX descriptor for FD frames */
+  struct canfd_frame *rxdesc_fd;    /* A pointer to the list of RX descriptors for FD frames */
+  struct can_frame *txdesc;         /* A pointer to the list of TX descriptor */
+  struct can_frame *rxdesc;         /* A pointer to the list of RX descriptors */
 
   /* This holds the information visible to the NuttX network */
 
   struct net_driver_s dev;      /* Interface understood by the network */
 
-  struct mb_s *rx;
-  struct mb_s *tx;
-
   struct flexcan_timeseg arbi_timing; /* Timing for arbitration phase */
-#ifdef CONFIG_NET_CAN_CANFD
   struct flexcan_timeseg data_timing; /* Timing for data phase */
-#endif
 
   const struct flexcan_config_s *config;
 
@@ -476,6 +479,8 @@ static uint32_t imxrt_waitmcr_change(uint32_t base,
 static uint32_t imxrt_waitesr2_change(uint32_t base,
                                        uint32_t mask,
                                        uint32_t target_state);
+static struct mb_s *flexcan_get_mb(FAR struct imxrt_driver_s *priv,
+                                    uint32_t mbi);
 
 /* Interrupt handling */
 
@@ -532,11 +537,13 @@ static void imxrt_reset(struct imxrt_driver_s *priv);
 
 static bool imxrt_txringfull(FAR struct imxrt_driver_s *priv)
 {
-  uint32_t mbi = 0;
+  uint32_t mbi = RXMBCOUNT;
+  struct mb_s *mb;
 
   while (mbi < TXMBCOUNT)
     {
-      if (priv->tx[mbi].cs.code != CAN_TXMB_DATAORREMOTE)
+      mb = flexcan_get_mb(priv, mbi);
+      if (mb->cs.code != CAN_TXMB_DATAORREMOTE)
         {
           return 0;
         }
@@ -588,14 +595,14 @@ static int imxrt_transmit(FAR struct imxrt_driver_s *priv)
     {
       mbi  = ((getreg32(priv->base + IMXRT_CAN_ESR2_OFFSET) &
         CAN_ESR2_LPTM_MASK) >> CAN_ESR2_LPTM_SHIFT);
-      mbi -= RXMBCOUNT;
     }
 
-  mb_bit = 1 << (RXMBCOUNT + mbi);
+  mb_bit = 1 << mbi;
 
-  while (mbi < TXMBCOUNT)
+  while (mbi < TOTALMBCOUNT)
     {
-      if (priv->tx[mbi].cs.code != CAN_TXMB_DATAORREMOTE)
+      struct mb_s *mb = flexcan_get_mb(priv, mbi);
+      if (mb->cs.code != CAN_TXMB_DATAORREMOTE)
         {
           putreg32(mb_bit, priv->base + IMXRT_CAN_IFLAG1_OFFSET);
           break;
@@ -605,7 +612,7 @@ static int imxrt_transmit(FAR struct imxrt_driver_s *priv)
       mbi++;
     }
 
-  if (mbi == TXMBCOUNT)
+  if (mbi == TOTALMBCOUNT)
     {
       nwarn("No TX MB available mbi %" PRIi32 "\r\n", mbi);
       NETDEV_TXERRORS(&priv->dev);
@@ -655,7 +662,7 @@ static int imxrt_transmit(FAR struct imxrt_driver_s *priv)
 
   union cs_e cs;
   cs.code = CAN_TXMB_DATAORREMOTE;
-  struct mb_s *mb = &priv->tx[mbi];
+  struct mb_s *mb = flexcan_get_mb(priv, mbi);
   mb->cs.code = CAN_TXMB_INACTIVE;
 
   if (priv->dev.d_len == sizeof(struct can_frame))
@@ -710,6 +717,16 @@ static int imxrt_transmit(FAR struct imxrt_driver_s *priv)
 
   mb->cs = cs; /* Go. */
 
+  /* Errata ER005829 step 8: Write twice into the first TX MB
+   * Errata mentions writng 0x8 value, but this one couses
+   * the ESR2_LPTM register to choose the reserved MB for
+   * transmiting the package, hence we write 0x3
+   */
+
+  struct mb_s *buffer = flexcan_get_mb(priv, RXMBCOUNT);
+  buffer->cs.code = 0x3;
+  buffer->cs.code = 0x3;
+
   regval = getreg32(priv->base + IMXRT_CAN_IMASK1_OFFSET);
   regval |= mb_bit;
   putreg32(regval, priv->base + IMXRT_CAN_IMASK1_OFFSET);
@@ -779,15 +796,12 @@ static int imxrt_txpoll(struct net_driver_s *dev)
            * not, return a non-zero value to terminate the poll.
            */
 
-          if ((getreg32(priv->base + IMXRT_CAN_ESR2_OFFSET) &
+          if (!((getreg32(priv->base + IMXRT_CAN_ESR2_OFFSET) &
               (CAN_ESR2_IMB | CAN_ESR2_VPS)) ==
-              (CAN_ESR2_IMB | CAN_ESR2_VPS))
-            {
-              if (!imxrt_txringfull(priv))
+              (CAN_ESR2_IMB | CAN_ESR2_VPS)) || (imxrt_txringfull(priv)))
                 {
                   return -EBUSY;
                 }
-            }
         }
     }
 
@@ -818,23 +832,40 @@ static int imxrt_txpoll(struct net_driver_s *dev)
 static void imxrt_receive(FAR struct imxrt_driver_s *priv,
                             uint32_t flags)
 {
-  uint32_t mb_index;
+  uint32_t mbi;
+  uint32_t mbj;
   struct mb_s *rf;
-#ifdef CONFIG_NET_CAN_CANFD
+# ifdef CONFIG_NET_CAN_CANFD
   uint32_t *frame_data_word;
   uint32_t i;
-#endif
+# endif
+  uint32_t f;
 
-  while ((mb_index = arm_lsb(flags)) != 32)
+  while ((f = flags) != 0)
     {
-      rf = &priv->rx[mb_index];
+      mbj = mbi = arm_lsb(f);
+      rf = flexcan_get_mb(priv, mbi);
+      uint32_t t = rf->cs.time_stamp;
+      while ((f &= ~(1 << mbj)) != 0)
+        {
+          mbj = arm_lsb(f);
+          struct mb_s *rf_next = flexcan_get_mb(priv, mbj);
+          uint16_t t_next = rf_next->cs.time_stamp;
+          if ((int16_t)(t - t_next) > 0)
+            {
+              t = t_next;
+              mbi = mbj;
+            }
+        }
+
+      rf = flexcan_get_mb(priv, mbi);
 
       /* Read the frame contents */
 
 #ifdef CONFIG_NET_CAN_CANFD
       if (rf->cs.edl) /* CAN FD frame */
         {
-        struct canfd_frame *frame = (struct canfd_frame *)priv->rxdesc;
+        struct canfd_frame *frame = (struct canfd_frame *)priv->rxdesc_fd;
 
           if (rf->cs.ide)
             {
@@ -862,7 +893,7 @@ static void imxrt_receive(FAR struct imxrt_driver_s *priv,
 
           /* Clear MB interrupt flag */
 
-          putreg32(1 << mb_index,
+          putreg32(1 << mbi,
                    priv->base + IMXRT_CAN_IFLAG1_OFFSET);
 
           /* Copy the buffer pointer to priv->dev..  Set amount of data
@@ -899,7 +930,7 @@ static void imxrt_receive(FAR struct imxrt_driver_s *priv,
 
           /* Clear MB interrupt flag */
 
-          putreg32(1 << mb_index,
+          putreg32(1 << mbi,
                    priv->base + IMXRT_CAN_IFLAG1_OFFSET);
 
           /* Copy the buffer pointer to priv->dev..  Set amount of data
@@ -923,9 +954,16 @@ static void imxrt_receive(FAR struct imxrt_driver_s *priv,
        * queue is not full.
        */
 
-      priv->dev.d_buf = (uint8_t *)priv->txdesc;
+      if (priv->canfd_capable)
+        {
+          priv->dev.d_buf = (uint8_t *)priv->txdesc_fd;
+        }
+      else
+        {
+          priv->dev.d_buf = (uint8_t *)priv->txdesc;
+        }
 
-      flags &= ~(1 << mb_index);
+      flags &= ~(1 << mbi);
 
       /* Reread interrupt flags and process them in this loop */
 
@@ -1241,6 +1279,13 @@ static uint32_t imxrt_waitesr2_change(uint32_t base, uint32_t mask,
   return false;
 }
 
+static struct mb_s *flexcan_get_mb(FAR struct imxrt_driver_s *priv,
+                                    uint32_t mbi)
+{
+  return (struct mb_s *)(priv->base +
+                        (mb_address[priv->mb_address_offset + mbi] << 3));
+}
+
 /****************************************************************************
  * Function: imxrt_ifup
  *
@@ -1270,16 +1315,18 @@ static int imxrt_ifup(struct net_driver_s *dev)
     }
 
   priv->bifup = true;
-
-#ifdef CONFIG_NET_CAN_CANFD
-  priv->txdesc = (struct canfd_frame *)&g_tx_pool;
-  priv->rxdesc = (struct canfd_frame *)&g_rx_pool;
-#else
   priv->txdesc = (struct can_frame *)&g_tx_pool;
   priv->rxdesc = (struct can_frame *)&g_rx_pool;
-#endif
-
-  priv->dev.d_buf = (uint8_t *)priv->txdesc;
+  if (priv->canfd_capable)
+    {
+      priv->txdesc_fd = (struct canfd_frame *)&g_tx_pool;
+      priv->rxdesc_fd = (struct canfd_frame *)&g_rx_pool;
+      priv->dev.d_buf = (uint8_t *)priv->txdesc_fd;
+    }
+  else
+    {
+      priv->dev.d_buf = (uint8_t *)priv->txdesc;
+    }
 
   /* Set interrupts */
 
@@ -1434,13 +1481,17 @@ static int imxrt_ioctl(struct net_driver_s *dev, int cmd,
               (struct can_ioctl_data_s *)((uintptr_t)arg);
           req->arbi_bitrate = priv->arbi_timing.bitrate / 1000; /* kbit/s */
           req->arbi_samplep = priv->arbi_timing.samplep;
-#ifdef CONFIG_NET_CAN_CANFD
-          req->data_bitrate = priv->data_timing.bitrate / 1000; /* kbit/s */
-          req->data_samplep = priv->data_timing.samplep;
-#else
-          req->data_bitrate = 0;
-          req->data_samplep = 0;
-#endif
+          if (priv->canfd_capable)
+            {
+              req->data_bitrate = priv->data_timing.bitrate / 1000; /* kbit/s */
+              req->data_samplep = priv->data_timing.samplep;
+            }
+          else
+            {
+              req->data_bitrate = 0;
+              req->data_samplep = 0;
+            }
+
           ret = OK;
         }
         break;
@@ -1463,29 +1514,32 @@ static int imxrt_ioctl(struct net_driver_s *dev, int cmd,
               ret = -EINVAL;
             }
 
-#ifdef CONFIG_NET_CAN_CANFD
-          struct flexcan_timeseg data_timing;
-          data_timing.bitrate = req->data_bitrate * 1000;
-          data_timing.samplep = req->data_samplep;
-
-          if (ret == OK && imxrt_bitratetotimeseg(&data_timing, 10, 1))
-            {
-              ret = OK;
-            }
-          else
-            {
-              ret = -EINVAL;
-            }
-#endif
+          if (priv->canfd_capable)
+          {
+            struct flexcan_timeseg data_timing;
+            data_timing.bitrate = req->data_bitrate * 1000;
+            data_timing.samplep = req->data_samplep;
+
+            if (ret == OK && imxrt_bitratetotimeseg(&data_timing, 10, 1))
+              {
+                ret = OK;
+              }
+            else
+              {
+                ret = -EINVAL;
+              }
+          }
 
           if (ret == OK)
             {
               /* Reset CAN controller and start with new timings */
 
               priv->arbi_timing = arbi_timing;
-#ifdef CONFIG_NET_CAN_CANFD
-              priv->data_timing = data_timing;
-#endif
+              if (priv->canfd_capable)
+              {
+                priv->data_timing = data_timing;
+              }
+
               imxrt_ifup(dev);
             }
         }
@@ -1546,69 +1600,82 @@ static int imxrt_initialize(struct imxrt_driver_s *priv)
       return -1;
     }
 
-#ifndef CONFIG_NET_CAN_CANFD
-  regval  = getreg32(priv->base + IMXRT_CAN_CTRL1_OFFSET);
-  regval &= ~(CAN_CTRL1_PRESDIV_MASK | CAN_CTRL1_PROPSEG_MASK |
-              CAN_CTRL1_PSEG1_MASK | CAN_CTRL1_PSEG2_MASK |
-              CAN_CTRL1_RJW_MASK);
-  regval |= CAN_CTRL1_PRESDIV(priv->arbi_timing.presdiv) | /* Prescaler divisor factor */
-            CAN_CTRL1_PROPSEG(priv->arbi_timing.propseg) | /* Propagation segment */
-            CAN_CTRL1_PSEG1(priv->arbi_timing.pseg1) |     /* Phase buffer segment 1 */
-            CAN_CTRL1_PSEG2(priv->arbi_timing.pseg2) |     /* Phase buffer segment 2 */
-            CAN_CTRL1_RJW(1);                              /* Resynchronization jump width */
-  putreg32(regval, priv->base + IMXRT_CAN_CTRL1_OFFSET);
-
-#else
-  regval  = getreg32(priv->base + IMXRT_CAN_CBT_OFFSET);
-  regval &= ~(CAN_CBT_EPRESDIV_MASK | CAN_CBT_EPROPSEG_MASK |
-              CAN_CBT_EPSEG1_MASK | CAN_CBT_EPSEG2_MASK |
-              CAN_CBT_ERJW_MASK);
-  regval |= CAN_CBT_BTF |                                 /* Enable extended bit timing
-                                                           * configurations for CAN-FD for setting up
-                                                           * separately nominal and data phase */
-            CAN_CBT_EPRESDIV(priv->arbi_timing.presdiv) | /* Prescaler divisor factor */
-            CAN_CBT_EPROPSEG(priv->arbi_timing.propseg) | /* Propagation segment */
-            CAN_CBT_EPSEG1(priv->arbi_timing.pseg1) |     /* Phase buffer segment 1 */
-            CAN_CBT_EPSEG2(priv->arbi_timing.pseg2) |     /* Phase buffer segment 2 */
-            CAN_CBT_ERJW(1);                              /* Resynchronization jump width */
-  putreg32(regval, priv->base + IMXRT_CAN_CBT_OFFSET);
-
-  /* Enable CAN FD feature */
+  if (!priv->canfd_capable)
+    {
+      regval  = getreg32(priv->base + IMXRT_CAN_CTRL1_OFFSET);
+      regval &= ~(CAN_CTRL1_PRESDIV_MASK | CAN_CTRL1_PROPSEG_MASK |
+                  CAN_CTRL1_PSEG1_MASK | CAN_CTRL1_PSEG2_MASK |
+                 CAN_CTRL1_RJW_MASK);
+      regval |= CAN_CTRL1_PRESDIV(priv->arbi_timing.presdiv) | /* Prescaler divisor factor */
+                CAN_CTRL1_PROPSEG(priv->arbi_timing.propseg) | /* Propagation segment */
+                CAN_CTRL1_PSEG1(priv->arbi_timing.pseg1) |     /* Phase buffer segment 1 */
+                CAN_CTRL1_PSEG2(priv->arbi_timing.pseg2) |     /* Phase buffer segment 2 */
+                CAN_CTRL1_RJW(1);                              /* Resynchronization jump width */
+      putreg32(regval, priv->base + IMXRT_CAN_CTRL1_OFFSET);
+    }
+  else
+    {
+      regval  = getreg32(priv->base + IMXRT_CAN_CBT_OFFSET);
+      regval &= ~(CAN_CBT_EPRESDIV_MASK | CAN_CBT_EPROPSEG_MASK |
+                  CAN_CBT_EPSEG1_MASK | CAN_CBT_EPSEG2_MASK |
+                  CAN_CBT_ERJW_MASK);
+      regval |= CAN_CBT_BTF |                                 /* Enable extended bit timing
+                                                               * configurations for CAN-FD for setting up
+                                                               * separately nominal and data phase */
+                CAN_CBT_EPRESDIV(priv->arbi_timing.presdiv) | /* Prescaler divisor factor */
+                CAN_CBT_EPROPSEG(priv->arbi_timing.propseg) | /* Propagation segment */
+                CAN_CBT_EPSEG1(priv->arbi_timing.pseg1) |     /* Phase buffer segment 1 */
+                CAN_CBT_EPSEG2(priv->arbi_timing.pseg2) |     /* Phase buffer segment 2 */
+                CAN_CBT_ERJW(1);                              /* Resynchronization jump width */
+      putreg32(regval, priv->base + IMXRT_CAN_CBT_OFFSET);
+
+      /* Enable CAN FD feature */
+
+      regval  = getreg32(priv->base + IMXRT_CAN_MCR_OFFSET);
+      regval |= CAN_MCR_FDEN;
+      putreg32(regval, priv->base + IMXRT_CAN_MCR_OFFSET);
+
+      regval  = getreg32(priv->base + IMXRT_CAN_FDCBT_OFFSET);
+      regval &= ~(CAN_FDCBT_FPRESDIV_MASK | CAN_FDCBT_FPROPSEG_MASK |
+                  CAN_FDCBT_FPSEG1_MASK | CAN_FDCBT_FPSEG2_MASK |
+                 CAN_FDCBT_FRJW_MASK);
+      regval |= CAN_FDCBT_FPRESDIV(priv->data_timing.presdiv) |  /* Prescaler divisor factor of 1 */
+                CAN_FDCBT_FPROPSEG(priv->data_timing.propseg) |  /* Propagation
+                                                                  * segment (only register that doesn't add 1) */
+                CAN_FDCBT_FPSEG1(priv->data_timing.pseg1) |      /* Phase buffer segment 1 */
+                CAN_FDCBT_FPSEG2(priv->data_timing.pseg2) |      /* Phase buffer segment 2 */
+                CAN_FDCBT_FRJW(priv->data_timing.pseg2);         /* Resynchorinzation jump width same as PSEG2 */
+      putreg32(regval, priv->base + IMXRT_CAN_FDCBT_OFFSET);
+
+      /* Additional CAN-FD configurations */
+
+      regval  = getreg32(priv->base + IMXRT_CAN_FDCTRL_OFFSET);
+
+      regval |= CAN_FDCTRL_FDRATE |     /* Enable bit rate switch in data phase of frame */
+                CAN_FDCTRL_TDCEN |      /* Enable transceiver delay compensation */
+                CAN_FDCTRL_TDCOFF(5) |  /* Setup 5 cycles for data phase sampling delay */
+                CAN_FDCTRL_MSBSR0(3) |  /* Setup 64 bytes per MB 0-6 */
+                CAN_FDCTRL_MSBSR1(3);   /* Setup 64 bytes per MB 7-13 */
+      putreg32(regval, priv->base + IMXRT_CAN_FDCTRL_OFFSET);
+
+      regval  = getreg32(priv->base + IMXRT_CAN_CTRL2_OFFSET);
+      regval |= CAN_CTRL2_ISOCANFDEN;
+      putreg32(regval, priv->base + IMXRT_CAN_CTRL2_OFFSET);
+    }
 
-  regval  = getreg32(priv->base + IMXRT_CAN_MCR_OFFSET);
-  regval |= CAN_MCR_FDEN;
-  putreg32(regval, priv->base + IMXRT_CAN_MCR_OFFSET);
+  /*  Errata ER005829 step 7: Reserve first TX MB
+   *  Errata mentions writng 0x8 value, but this one couses
+   *  the ESR2_LPTM register to choose the reserved MB for
+   *  transmiting the package, hence we write 0x3
+   */
 
-  regval  = getreg32(priv->base + IMXRT_CAN_FDCBT_OFFSET);
-  regval &= ~(CAN_FDCBT_FPRESDIV_MASK | CAN_FDCBT_FPROPSEG_MASK |
-              CAN_FDCBT_FPSEG1_MASK | CAN_FDCBT_FPSEG2_MASK |
-              CAN_FDCBT_FRJW_MASK);
-  regval |= CAN_FDCBT_FPRESDIV(priv->data_timing.presdiv) |  /* Prescaler divisor factor of 1 */
-            CAN_FDCBT_FPROPSEG(priv->data_timing.propseg) |  /* Propagation
-                                                              * segment (only register that doesn't add 1) */
-            CAN_FDCBT_FPSEG1(priv->data_timing.pseg1) |      /* Phase buffer segment 1 */
-            CAN_FDCBT_FPSEG2(priv->data_timing.pseg2) |      /* Phase buffer segment 2 */
-            CAN_FDCBT_FRJW(priv->data_timing.pseg2);         /* Resynchorinzation jump width same as PSEG2 */
-  putreg32(regval, priv->base + IMXRT_CAN_FDCBT_OFFSET);
-
-  /* Additional CAN-FD configurations */
-
-  regval  = getreg32(priv->base + IMXRT_CAN_FDCTRL_OFFSET);
-
-  regval |= CAN_FDCTRL_FDRATE |     /* Enable bit rate switch in data phase of frame */
-            CAN_FDCTRL_TDCEN |      /* Enable transceiver delay compensation */
-            CAN_FDCTRL_TDCOFF(5) |  /* Setup 5 cycles for data phase sampling delay */
-            CAN_FDCTRL_MSBSR0(3);   /* Setup 64 bytes per message buffer (7 MB's) */
-  putreg32(regval, priv->base + IMXRT_CAN_FDCTRL_OFFSET);
-
-  regval  = getreg32(priv->base + IMXRT_CAN_CTRL2_OFFSET);
-  regval |= CAN_CTRL2_ISOCANFDEN;
-  putreg32(regval, priv->base + IMXRT_CAN_CTRL2_OFFSET);
-#endif
+      struct mb_s *buffer = flexcan_get_mb(priv, RXMBCOUNT);
+      buffer->cs.code = 0x3;
 
-  for (i = TXMBCOUNT; i < TOTALMBCOUNT; i++)
+  for (i = RXMBCOUNT + 1; i < TOTALMBCOUNT; i++)
     {
-      priv->rx[i].id.w = 0x0;
+      struct mb_s *rx = flexcan_get_mb(priv, i);
+      rx->id.w = 0x0;
 
       /* FIXME sometimes we get a hard fault here */
     }
@@ -1622,14 +1689,15 @@ static int imxrt_initialize(struct imxrt_driver_s *priv)
 
   for (i = 0; i < RXMBCOUNT; i++)
     {
-      ninfo("Set MB%" PRIi32 " to receive %p\r\n", i, &priv->rx[i]);
-      priv->rx[i].cs.edl = 0x1;
-      priv->rx[i].cs.brs = 0x1;
-      priv->rx[i].cs.esi = 0x0;
-      priv->rx[i].cs.code = 4;
-      priv->rx[i].cs.srr = 0x0;
-      priv->rx[i].cs.ide = 0x1;
-      priv->rx[i].cs.rtr = 0x0;
+      struct mb_s *rx = flexcan_get_mb(priv, i);
+      ninfo("Set MB%" PRIi32 " to receive %p\r\n", i, rx);
+      rx->cs.edl = 0x1;
+      rx->cs.brs = 0x1;
+      rx->cs.esi = 0x0;
+      rx->cs.code = 4;
+      rx->cs.srr = 0x0;
+      rx->cs.ide = 0x1;
+      rx->cs.rtr = 0x0;
     }
 
   putreg32(IFLAG1_RX, priv->base + IMXRT_CAN_IFLAG1_OFFSET);
@@ -1686,12 +1754,13 @@ static void imxrt_reset(struct imxrt_driver_s *priv)
 
   for (i = 0; i < TOTALMBCOUNT; i++)
     {
-      ninfo("MB %" PRIi32 " %p\r\n", i, &priv->rx[i]);
-      ninfo("MB %" PRIi32 " %p\r\n", i, &priv->rx[i].id.w);
-      priv->rx[i].cs.cs = 0x0;
-      priv->rx[i].id.w = 0x0;
-      priv->rx[i].data[0].w00 = 0x0;
-      priv->rx[i].data[1].w00 = 0x0;
+      struct mb_s *rx = flexcan_get_mb(priv, i);
+      ninfo("MB %" PRIi32 " %p\r\n", i, rx);
+      ninfo("MB %" PRIi32 " %p\r\n", i, &rx->id.w);
+      rx->cs.cs = 0x0;
+      rx->id.w = 0x0;
+      rx->data[0].w00 = 0x0;
+      rx->data[1].w00 = 0x0;
     }
 
   regval  = getreg32(priv->base + IMXRT_CAN_MCR_OFFSET);
@@ -1756,18 +1825,13 @@ int imxrt_caninitialize(int intf)
       memset(priv, 0, sizeof(struct imxrt_driver_s));
       priv->base         = IMXRT_CAN1_BASE;
       priv->config       = &imxrt_flexcan1_config;
+      priv->canfd_capable = false;
+      priv->mb_address_offset = 0;
 
       /* Default bitrate configuration */
 
-#  ifdef CONFIG_NET_CAN_CANFD
-      priv->arbi_timing.bitrate = CONFIG_FLEXCAN1_ARBI_BITRATE;
-      priv->arbi_timing.samplep = CONFIG_FLEXCAN1_ARBI_SAMPLEP;
-      priv->data_timing.bitrate = CONFIG_FLEXCAN1_DATA_BITRATE;
-      priv->data_timing.samplep = CONFIG_FLEXCAN1_DATA_SAMPLEP;
-#  else
       priv->arbi_timing.bitrate = CONFIG_FLEXCAN1_BITRATE;
       priv->arbi_timing.samplep = CONFIG_FLEXCAN1_SAMPLEP;
-#  endif
       break;
 #endif
 
@@ -1779,18 +1843,13 @@ int imxrt_caninitialize(int intf)
       memset(priv, 0, sizeof(struct imxrt_driver_s));
       priv->base   = IMXRT_CAN2_BASE;
       priv->config = &imxrt_flexcan2_config;
+      priv->canfd_capable = false;
+      priv->mb_address_offset = 0;
 
       /* Default bitrate configuration */
 
-#  ifdef CONFIG_NET_CAN_CANFD
-      priv->arbi_timing.bitrate = CONFIG_FLEXCAN2_ARBI_BITRATE;
-      priv->arbi_timing.samplep = CONFIG_FLEXCAN2_ARBI_SAMPLEP;
-      priv->data_timing.bitrate = CONFIG_FLEXCAN2_DATA_BITRATE;
-      priv->data_timing.samplep = CONFIG_FLEXCAN2_DATA_SAMPLEP;
-#  else
       priv->arbi_timing.bitrate = CONFIG_FLEXCAN2_BITRATE;
       priv->arbi_timing.samplep = CONFIG_FLEXCAN2_SAMPLEP;
-#  endif
       break;
 #endif
 
@@ -1802,6 +1861,13 @@ int imxrt_caninitialize(int intf)
       memset(priv, 0, sizeof(struct imxrt_driver_s));
       priv->base   = IMXRT_CAN3_BASE;
       priv->config = &imxrt_flexcan3_config;
+#  ifdef CONFIG_NET_CAN_CANFD
+      priv->canfd_capable = true;
+      priv->mb_address_offset = 14;
+#  else
+      priv->canfd_capable = false;
+      priv->mb_address_offset = 0;
+#  endif
 
       /* Default bitrate configuration */
 
@@ -1828,14 +1894,15 @@ int imxrt_caninitialize(int intf)
       return -1;
     }
 
-#ifdef CONFIG_NET_CAN_CANFD
-  if (!imxrt_bitratetotimeseg(&priv->data_timing, 1, 1))
+  if (priv->canfd_capable)
     {
-      nerr("ERROR: Invalid CAN data phase timings please try another "
-           "sample point or refer to the reference manual\n");
-      return -1;
+      if (!imxrt_bitratetotimeseg(&priv->data_timing, 1, 1))
+        {
+          nerr("ERROR: Invalid CAN data phase timings please try another "
+               "sample point or refer to the reference manual\n");
+          return -1;
+        }
     }
-#endif
 
   imxrt_config_gpio(priv->config->tx_pin);
   imxrt_config_gpio(priv->config->rx_pin);
@@ -1865,9 +1932,6 @@ int imxrt_caninitialize(int intf)
     }
 
 #endif
-  priv->rx            = (struct mb_s *)(priv->base + IMXRT_CAN_MB_OFFSET);
-  priv->tx            = (struct mb_s *)(priv->base + IMXRT_CAN_MB_OFFSET +
-                          (sizeof(struct mb_s) * RXMBCOUNT));
 
   /* Put the interface in the down state.  This usually amounts to resetting
    * the device and/or calling imxrt_ifdown().


[incubator-nuttx] 01/02: boards/arm/imxrt/teensy-4.x: allow configuration of all CANs

Posted by xi...@apache.org.
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/incubator-nuttx.git

commit 3b219fb2da3fd524a34f47591e3c07b8363db740
Author: Michal Lenc <mi...@seznam.cz>
AuthorDate: Thu Feb 25 23:27:34 2021 +0100

    boards/arm/imxrt/teensy-4.x: allow configuration of all CANs
    
    Signed-off-by: Michal Lenc <mi...@seznam.cz>
---
 boards/arm/imxrt/teensy-4.x/README.txt                | 14 ++++++--------
 boards/arm/imxrt/teensy-4.x/configs/can-4.1/defconfig | 12 ++++--------
 boards/arm/imxrt/teensy-4.x/src/imxrt_flexcan.c       | 17 ++++++++++-------
 3 files changed, 20 insertions(+), 23 deletions(-)

diff --git a/boards/arm/imxrt/teensy-4.x/README.txt b/boards/arm/imxrt/teensy-4.x/README.txt
index 86fb3ce..b6e9374 100644
--- a/boards/arm/imxrt/teensy-4.x/README.txt
+++ b/boards/arm/imxrt/teensy-4.x/README.txt
@@ -138,8 +138,9 @@ Configuration sub-directories
   can-4.1:
 
     This is an nsh configuration (see above) for Teensy-4.x with added support of 
-    CAN driver. FlexCAN3 is chosen as default, the change can be made at System 
-    type peripheral selection.
+    CAN driver. All FlexCANs (CAN1, CAN2, CAN3) are chosen as default. FlexCAN3
+    is FD capable. Please note that device driver name if counted from zero.
+    That means for CAN1 -> can0, CAN2 -> can1 and CAN3 -> can2
 
     Bitrate and sample point can be also changed at System type peripheral selection,
     basic values are 1 MHz for bitrate and 0.80 for sample point. The FlexCAN driver
@@ -147,15 +148,12 @@ Configuration sub-directories
 
     The configuration also includes CAN utilities as candump and cansend.
 
-    CAN_FD supported but not enabled. For CAN_FD please select following:
-
-    CAN_FD = y
-    NET_CAN_CANFD = y
-    NET_CAN_SOCK_OPTS = y
-
     This configuration can be easily changed to work with Teensy 4.0 by
     selecting CONFIG_TEENSY_40=y.
 
+    This configuration runs over LPUART1 (pins 24 and 25 on Teensy). Communication
+    over USB console can be turn on, but it couses problems with FlexCAN.
+
   netnsh-4.1:
 
     This configuration is similar to the nsh configuration except that is
diff --git a/boards/arm/imxrt/teensy-4.x/configs/can-4.1/defconfig b/boards/arm/imxrt/teensy-4.x/configs/can-4.1/defconfig
index 664e35e..cfecc87 100644
--- a/boards/arm/imxrt/teensy-4.x/configs/can-4.1/defconfig
+++ b/boards/arm/imxrt/teensy-4.x/configs/can-4.1/defconfig
@@ -5,7 +5,6 @@
 # You can then do "make savedefconfig" to generate a new defconfig file that includes your
 # modifications.
 #
-# CONFIG_NET_CAN_CANFD is not set
 # CONFIG_NET_ETHERNET is not set
 # CONFIG_NET_IPv4 is not set
 CONFIG_ARCH="arm"
@@ -21,17 +20,16 @@ CONFIG_ARMV7M_ICACHE=y
 CONFIG_ARMV7M_USEBASEPRI=y
 CONFIG_BOARD_LOOPSPERMSEC=104926
 CONFIG_BUILTIN=y
-CONFIG_CAN=y
 CONFIG_CANUTILS_CANDUMP=y
 CONFIG_CANUTILS_CANSEND=y
-CONFIG_CDCACM=y
-CONFIG_CDCACM_CONSOLE=y
 CONFIG_FS_PROCFS=y
 CONFIG_IDLETHREAD_STACKSIZE=2048
+CONFIG_IMXRT_FLEXCAN1=y
+CONFIG_IMXRT_FLEXCAN2=y
 CONFIG_IMXRT_FLEXCAN3=y
 CONFIG_IMXRT_LPUART1=y
-CONFIG_IMXRT_USBDEV=y
 CONFIG_INTELHEX_BINARY=y
+CONFIG_LPUART1_SERIAL_CONSOLE=y
 CONFIG_MAX_TASKS=16
 CONFIG_NET=y
 CONFIG_NETDEVICES=y
@@ -40,7 +38,7 @@ CONFIG_NETDEV_LATEINIT=y
 CONFIG_NETDEV_STATISTICS=y
 CONFIG_NET_CAN=y
 CONFIG_NET_CAN_NOTIFIER=y
-CONFIG_NET_SOCKOPTS=y
+CONFIG_NET_CAN_SOCK_OPTS=y
 CONFIG_NET_STATISTICS=y
 CONFIG_NET_TIMESTAMP=y
 CONFIG_NFILE_DESCRIPTORS=8
@@ -49,7 +47,6 @@ CONFIG_NSH_BUILTIN_APPS=y
 CONFIG_NSH_FILEIOSIZE=512
 CONFIG_NSH_LINELEN=64
 CONFIG_NSH_READLINE=y
-CONFIG_NSH_USBCONSOLE=y
 CONFIG_RAM_SIZE=1048576
 CONFIG_RAM_START=0x20200000
 CONFIG_SCHED_HPWORK=y
@@ -58,5 +55,4 @@ CONFIG_START_DAY=14
 CONFIG_START_MONTH=3
 CONFIG_SYSTEM_NSH=y
 CONFIG_TEENSY_41=y
-CONFIG_USBDEV=y
 CONFIG_USER_ENTRYPOINT="nsh_main"
diff --git a/boards/arm/imxrt/teensy-4.x/src/imxrt_flexcan.c b/boards/arm/imxrt/teensy-4.x/src/imxrt_flexcan.c
index d12d133..8d08c46 100644
--- a/boards/arm/imxrt/teensy-4.x/src/imxrt_flexcan.c
+++ b/boards/arm/imxrt/teensy-4.x/src/imxrt_flexcan.c
@@ -50,31 +50,34 @@
 int imxrt_can_setup(void)
 {
   int ret;
-#ifdef CONFIG_IMXRT_FLEXCAN3
+#ifdef CONFIG_IMXRT_FLEXCAN1
   /* Call arm_caninitialize() to get an instance of the CAN interface */
 
-  ret = imxrt_caninitialize(3);
+  ret = imxrt_caninitialize(1);
   if (ret < 0)
     {
       canerr("ERROR: Failed to get CAN interface\n");
       return -ENODEV;
     }
-#elif CONFIG_IMXRT_FLEXCAN2
+
+#endif
+#ifdef CONFIG_IMXRT_FLEXCAN2
   ret = imxrt_caninitialize(2);
   if (ret < 0)
     {
       canerr("ERROR: Failed to get CAN interface\n");
       return -ENODEV;
     }
-#elif CONFIG_IMXRT_FLEXCAN1
-    ret = imxrt_caninitialize(1);
+
+#endif
+#ifdef CONFIG_IMXRT_FLEXCAN3
+  ret = imxrt_caninitialize(3);
   if (ret < 0)
     {
       canerr("ERROR: Failed to get CAN interface\n");
       return -ENODEV;
     }
-#else
-  return -ENODEV;
+
 #endif
   UNUSED(ret);
   return OK;