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 2e3c144f44 imxrt: fix txdeadline add ecc/fd support
2e3c144f44 is described below
commit 2e3c144f440c9e9dfe7ef45675f0a01201ddfe0c
Author: Peter van der Perk <[email protected]>
AuthorDate: Tue Aug 1 09:56:45 2023 +0200
imxrt: fix txdeadline add ecc/fd support
---
arch/arm/src/imxrt/Kconfig | 56 +++++++++++++
arch/arm/src/imxrt/hardware/imxrt_flexcan.h | 6 ++
arch/arm/src/imxrt/imxrt_flexcan.c | 125 +++++++++++++++++++++-------
3 files changed, 156 insertions(+), 31 deletions(-)
diff --git a/arch/arm/src/imxrt/Kconfig b/arch/arm/src/imxrt/Kconfig
index da1c67df5e..b7017a7b06 100644
--- a/arch/arm/src/imxrt/Kconfig
+++ b/arch/arm/src/imxrt/Kconfig
@@ -211,6 +211,18 @@ config IMXRT_FLEXCAN
default n
select ARCH_HAVE_NETDEV_STATISTICS
+config IMXRT_FLEXCAN_ECC
+ bool
+ default n
+
+config IMXRT_FLEXCAN1_FD
+ bool
+ default n
+
+config IMXRT_FLEXCAN2_FD
+ bool
+ default n
+
config IMXRT_FLEXPWM
bool
default n
@@ -536,12 +548,34 @@ menu "FLEXCAN1 Configuration"
config FLEXCAN1_BITRATE
int "CAN bitrate"
+ depends on !(NET_CAN_CANFD && IMXRT_FLEXCAN1_FD)
default 1000000
config FLEXCAN1_SAMPLEP
int "CAN sample point"
+ depends on !(NET_CAN_CANFD && IMXRT_FLEXCAN1_FD)
default 80
+config FLEXCAN1_ARBI_BITRATE
+ int "CAN FD Arbitration phase bitrate"
+ depends on NET_CAN_CANFD && IMXRT_FLEXCAN1_FD
+ default 1000000
+
+config FLEXCAN1_ARBI_SAMPLEP
+ int "CAN FD Arbitration phase sample point"
+ depends on NET_CAN_CANFD && IMXRT_FLEXCAN1_FD
+ default 80
+
+config FLEXCAN1_DATA_BITRATE
+ int "CAN FD Data phase bitrate"
+ depends on NET_CAN_CANFD && IMXRT_FLEXCAN1_FD
+ default 4000000
+
+config FLEXCAN1_DATA_SAMPLEP
+ int "CAN FD Data phase sample point"
+ depends on NET_CAN_CANFD && IMXRT_FLEXCAN1_FD
+ default 90
+
endmenu # IMXRT_FLEXCAN1
menu "FLEXCAN2 Configuration"
@@ -549,12 +583,34 @@ menu "FLEXCAN2 Configuration"
config FLEXCAN2_BITRATE
int "CAN bitrate"
+ depends on !(NET_CAN_CANFD && IMXRT_FLEXCAN2_FD)
default 1000000
config FLEXCAN2_SAMPLEP
int "CAN sample point"
+ depends on !(NET_CAN_CANFD && IMXRT_FLEXCAN2_FD)
+ default 80
+
+config FLEXCAN2_ARBI_BITRATE
+ int "CAN FD Arbitration phase bitrate"
+ depends on NET_CAN_CANFD && IMXRT_FLEXCAN2_FD
+ default 1000000
+
+config FLEXCAN2_ARBI_SAMPLEP
+ int "CAN FD Arbitration phase sample point"
+ depends on NET_CAN_CANFD && IMXRT_FLEXCAN2_FD
default 80
+config FLEXCAN2_DATA_BITRATE
+ int "CAN FD Data phase bitrate"
+ depends on NET_CAN_CANFD && IMXRT_FLEXCAN2_FD
+ default 4000000
+
+config FLEXCAN2_DATA_SAMPLEP
+ int "CAN FD Data phase sample point"
+ depends on NET_CAN_CANFD && IMXRT_FLEXCAN2_FD
+ default 90
+
endmenu # IMXRT_FLEXCAN2
menu "FLEXCAN3 Configuration"
diff --git a/arch/arm/src/imxrt/hardware/imxrt_flexcan.h
b/arch/arm/src/imxrt/hardware/imxrt_flexcan.h
index ae93284598..439d1d4121 100644
--- a/arch/arm/src/imxrt/hardware/imxrt_flexcan.h
+++ b/arch/arm/src/imxrt/hardware/imxrt_flexcan.h
@@ -55,6 +55,12 @@
#define IMXRT_CAN_CBT_OFFSET 0x0050 /* CAN Bit Timing Register */
#define IMXRT_CAN_MB_OFFSET 0x0080 /* CAN MB register */
+#define IMXRT_CAN_MB_SIZE 0x0A60
+#define IMXRT_CAN_MB_END (IMXRT_CAN_MB_OFFSET + IMXRT_CAN_MB_SIZE)
+
+#define IMXRT_CAN_MB2_OFFSET 0x0F28 /* CAN MB2 register */
+#define IMXRT_CAN_MB2_SIZE 0x00D8
+#define IMXRT_CAN_MB2_END (IMXRT_CAN_MB2_OFFSET + IMXRT_CAN_MB2_SIZE)
#define IMXRT_CAN_RXIMR_OFFSET(n) (0x0880+((n)<<2)) /* Rn Individual Mask
Registers */
#define IMXRT_CAN_RXIMR0_OFFSET 0x0880 /* R0 Individual Mask
Registers */
diff --git a/arch/arm/src/imxrt/imxrt_flexcan.c
b/arch/arm/src/imxrt/imxrt_flexcan.c
index 8768f54d03..cabd1161c0 100644
--- a/arch/arm/src/imxrt/imxrt_flexcan.c
+++ b/arch/arm/src/imxrt/imxrt_flexcan.c
@@ -266,7 +266,7 @@ struct imxrt_driver_s
bool canfd_capable;
int mb_address_offset;
#ifdef TX_TIMEOUT_WQ
- WDOG_ID txtimeout[TXMBCOUNT]; /* TX timeout timer */
+ struct wdog_s 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
*/
@@ -486,7 +486,7 @@ static int imxrt_flexcan_interrupt(int irq, void *context,
/* Watchdog timer expirations */
#ifdef TX_TIMEOUT_WQ
static void imxrt_txtimeout_work(void *arg);
-static void imxrt_txtimeout_expiry(int argc, uint32_t arg, ...);
+static void imxrt_txtimeout_expiry(wdparm_t arg);
#endif
/* NuttX callback functions */
@@ -726,8 +726,8 @@ static int imxrt_transmit(struct imxrt_driver_s *priv)
if (timeout > 0)
{
- wd_start(priv->txtimeout[mbi], timeout + 1, imxrt_txtimeout_expiry,
- 1, (wdparm_t)priv);
+ wd_start(&priv->txtimeout[mbi - RXMBCOUNT], timeout + 1,
+ imxrt_txtimeout_expiry, (wdparm_t)priv);
}
#endif
@@ -1004,7 +1004,7 @@ static void imxrt_txdone(struct imxrt_driver_s *priv)
*/
wd_cancel(&priv->txtimeout[mbi]);
- struct mb_s *mb = &priv->tx[mbi];
+ struct mb_s *mb = flexcan_get_mb(priv, mbi + RXMBCOUNT);
mb->cs.code = CAN_TXMB_INACTIVE;
#endif
}
@@ -1155,7 +1155,7 @@ static void imxrt_txtimeout_work(void *arg)
putreg32(mb_bit, priv->base + IMXRT_CAN_IFLAG1_OFFSET);
}
- struct mb_s *mb = &priv->tx[mbi];
+ struct mb_s *mb = flexcan_get_mb(priv, mbi + RXMBCOUNT);
mb->cs.code = CAN_TXMB_ABORT;
priv->txmb[mbi].pending = TX_ABORT;
}
@@ -1170,8 +1170,7 @@ static void imxrt_txtimeout_work(void *arg)
* The last TX never completed. Reset the hardware and start again.
*
* Input Parameters:
- * argc - The number of available arguments
- * arg - The first argument
+ * arg - The argument
*
* Returned Value:
* None
@@ -1181,7 +1180,7 @@ static void imxrt_txtimeout_work(void *arg)
*
****************************************************************************/
-static void imxrt_txtimeout_expiry(int argc, uint32_t arg, ...)
+static void imxrt_txtimeout_expiry(wdparm_t arg)
{
struct imxrt_driver_s *priv = (struct imxrt_driver_s *)arg;
@@ -1533,6 +1532,63 @@ static int imxrt_ioctl(struct net_driver_s *dev, int cmd,
}
#endif /* CONFIG_NETDEV_IOCTL */
+#ifdef CONFIG_IMXRT_FLEXCAN_ECC
+
+/****************************************************************************
+ * Function: imxrt_init_eccram
+ *
+ * Description:
+ * Initialize FLEXCAN ECC RAM
+ *
+ * Input Parameters:
+ * priv - Reference to the private FLEXCAN driver state structure
+ *
+ * Returned Value:
+ * None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static int imxrt_init_eccram(struct imxrt_driver_s *priv)
+{
+ uint32_t i;
+ uint32_t regval;
+ irqstate_t flags;
+
+ flags = enter_critical_section();
+
+ regval = getreg32(priv->base + IMXRT_CAN_CTRL2_OFFSET);
+
+ /* Set WRMFRZ bit in CTRL2 Register to grant write access to memory */
+
+ regval |= CAN_CTRL2_WRMFRZ;
+
+ putreg32(regval, priv->base + IMXRT_CAN_CTRL2_OFFSET);
+
+ for (i = IMXRT_CAN_MB_OFFSET; i < IMXRT_CAN_MB_END; i += 4)
+ {
+ putreg32(0, priv->base + i);
+ }
+
+ for (i = IMXRT_CAN_MB2_OFFSET; i < IMXRT_CAN_MB2_END; i += 4)
+ {
+ putreg32(0, priv->base + i);
+ }
+
+ regval = getreg32(priv->base + IMXRT_CAN_CTRL2_OFFSET);
+
+ /* Clear WRMFRZ bit in CTRL2 Register */
+
+ regval &= ~CAN_CTRL2_WRMFRZ;
+
+ leave_critical_section(flags);
+
+ return 0;
+}
+
+#endif
+
/****************************************************************************
* Function: imxrt_initalize
*
@@ -1556,18 +1612,12 @@ static int imxrt_initialize(struct imxrt_driver_s *priv)
/* initialize CAN device */
-#ifdef CONFIG_IMXRT_FLEXCAN3
- imxrt_setenable(priv->base, 0);
-
- /* Set SYS_CLOCK src */
+ imxrt_setenable(priv->base, 1);
- regval = getreg32(priv->base + IMXRT_CAN_CTRL1_OFFSET);
- regval |= (CAN_CTRL1_CLKSRC);
- putreg32(regval, priv->base + IMXRT_CAN_CTRL1_OFFSET);
+#ifdef CONFIG_IMXRT_FLEXCAN_ECC
+ imxrt_init_eccram(priv);
#endif
- imxrt_setenable(priv->base, 1);
-
imxrt_reset(priv);
/* Enter freeze mode */
@@ -1575,7 +1625,7 @@ static int imxrt_initialize(struct imxrt_driver_s *priv)
imxrt_setfreeze(priv->base, 1);
if (!imxrt_waitfreezeack_change(priv->base, 1))
{
- ninfo("FLEXCAN: freeze fail\n");
+ nerr("FLEXCAN: freeze fail\n");
return -1;
}
@@ -1687,7 +1737,7 @@ static int imxrt_initialize(struct imxrt_driver_s *priv)
imxrt_setfreeze(priv->base, 0);
if (!imxrt_waitfreezeack_change(priv->base, 0))
{
- ninfo("FLEXCAN: unfreeze fail\n");
+ nerr("FLEXCAN: unfreeze fail\n");
return -1;
}
@@ -1790,9 +1840,6 @@ int imxrt_caninitialize(int intf)
{
struct imxrt_driver_s *priv;
int ret;
-#ifdef TX_TIMEOUT_WQ
- uint32_t i;
-#endif
switch (intf)
{
@@ -1804,13 +1851,25 @@ int imxrt_caninitialize(int intf)
memset(priv, 0, sizeof(struct imxrt_driver_s));
priv->base = IMXRT_CAN1_BASE;
priv->config = &imxrt_flexcan1_config;
+# if defined(CONFIG_NET_CAN_CANFD) && defined(CONFIG_IMXRT_FLEXCAN1_FD)
+ priv->canfd_capable = true;
+ priv->mb_address_offset = 14;
+# else
priv->canfd_capable = false;
priv->mb_address_offset = 0;
+# endif
/* Default bitrate configuration */
+# if defined(CONFIG_NET_CAN_CANFD) && defined(CONFIG_IMXRT_FLEXCAN1_FD)
+ 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
@@ -1822,13 +1881,25 @@ int imxrt_caninitialize(int intf)
memset(priv, 0, sizeof(struct imxrt_driver_s));
priv->base = IMXRT_CAN2_BASE;
priv->config = &imxrt_flexcan2_config;
+# if defined(CONFIG_NET_CAN_CANFD) && defined(CONFIG_IMXRT_FLEXCAN2_FD)
+ priv->canfd_capable = true;
+ priv->mb_address_offset = 14;
+# else
priv->canfd_capable = false;
priv->mb_address_offset = 0;
+# endif
/* Default bitrate configuration */
+# if defined(CONFIG_NET_CAN_CANFD) && defined(CONFIG_IMXRT_FLEXCAN2_FD)
+ 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
@@ -1904,14 +1975,6 @@ int imxrt_caninitialize(int intf)
#endif
priv->dev.d_private = (void *)priv; /* Used to recover private state
from dev */
-#ifdef TX_TIMEOUT_WQ
- for (i = 0; i < TXMBCOUNT; i++)
- {
- priv->txtimeout[i] = wd_create(); /* Create TX timeout timer */
- }
-
-#endif
-
/* Put the interface in the down state. This usually amounts to resetting
* the device and/or calling imxrt_ifdown().
*/