You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by gn...@apache.org on 2020/06/02 14:09:38 UTC
[incubator-nuttx] 20/31: S32K1XX Added High res timer support
FlexCAN allocate memory for timestamp
This is an automated email from the ASF dual-hosted git repository.
gnutt pushed a commit to branch SocketCAN
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
commit cd52a3f042dfdec9eaa2646da4bfad850ad277c8
Author: Peter van der Perk <pe...@nxp.com>
AuthorDate: Thu Mar 12 13:59:33 2020 +0100
S32K1XX Added High res timer support
FlexCAN allocate memory for timestamp
---
arch/arm/src/s32k1xx/s32k1xx_flexcan.c | 14 +++++-
arch/arm/src/s32k1xx/s32k1xx_rtc.c | 79 ++++++++++++++++++++++++++++++++--
arch/arm/src/s32k1xx/s32k1xx_rtc.h | 8 ----
3 files changed, 87 insertions(+), 14 deletions(-)
diff --git a/arch/arm/src/s32k1xx/s32k1xx_flexcan.c b/arch/arm/src/s32k1xx/s32k1xx_flexcan.c
index 8e79833..2654c2e 100644
--- a/arch/arm/src/s32k1xx/s32k1xx_flexcan.c
+++ b/arch/arm/src/s32k1xx/s32k1xx_flexcan.c
@@ -49,6 +49,10 @@
#include "s32k1xx_pin.h"
#include "s32k1xx_flexcan.h"
+#ifdef CONFIG_NET_TIMESTAMP
+#include <sys/time.h>
+#endif
+
#ifdef CONFIG_S32K1XX_FLEXCAN
/****************************************************************************
@@ -108,6 +112,12 @@
#define POOL_SIZE 1
+#ifdef CONFIG_NET_TIMESTAMP
+#define MSG_DATA sizeof(struct timeval)
+#else
+#define MSG_DATA 0
+#endif
+
/* Interrupt flags for RX fifo */
#define IFLAG1_RXFIFO (CAN_FIFO_NE | CAN_FIFO_WARN | CAN_FIFO_OV)
@@ -223,8 +233,8 @@ struct s32k1xx_driver_s
static struct s32k1xx_driver_s g_flexcan[CONFIG_S32K1XX_ENET_NETHIFS];
#ifdef CAN_FD
-static uint8_t g_tx_pool[sizeof(struct canfd_frame)*POOL_SIZE];
-static uint8_t g_rx_pool[sizeof(struct canfd_frame)*POOL_SIZE];
+static uint8_t g_tx_pool[(sizeof(struct canfd_frame)+MSG_DATA)*POOL_SIZE];
+static uint8_t g_rx_pool[(sizeof(struct canfd_frame)+MSG_DATA)*POOL_SIZE];
#else
static uint8_t g_tx_pool[sizeof(struct can_frame)*POOL_SIZE]
__attribute__((aligned(ARMV7M_DCACHE_LINESIZE)));
diff --git a/arch/arm/src/s32k1xx/s32k1xx_rtc.c b/arch/arm/src/s32k1xx/s32k1xx_rtc.c
index 7c70b76..7f84dcf 100644
--- a/arch/arm/src/s32k1xx/s32k1xx_rtc.c
+++ b/arch/arm/src/s32k1xx/s32k1xx_rtc.c
@@ -157,11 +157,11 @@ int up_rtc_initialize(void)
putreg32(regval, S32K1XX_RTC_CR);
- /* Set LPO_1KHZ clock source */
+ /* Increment on 32.768Khz clock */
regval = getreg32(S32K1XX_RTC_CR);
- regval |= RTC_CR_LPOS;
+ regval &= ~RTC_CR_LPOS;
putreg32(regval, S32K1XX_RTC_CR);
@@ -181,6 +181,16 @@ int up_rtc_initialize(void)
putreg32(regval, S32K1XX_RTC_CR);
+ regval = getreg32(S32K1XX_RTC_SR);
+
+ if(regval & RTC_SR_TIF)
+ {
+ regval &= ~RTC_SR_TCE;
+ putreg32(regval, S32K1XX_RTC_SR);
+ /* Write TSR register to clear invalid */
+ putreg32(0x0, S32K1XX_RTC_TSR);
+ }
+
/* Enable the rtc */
s32k1xx_rtc_enable();
@@ -207,7 +217,7 @@ int up_rtc_initialize(void)
* The current time in seconds
*
****************************************************************************/
-
+#ifndef CONFIG_RTC_HIRES
time_t up_rtc_time(void)
{
uint32_t regval;
@@ -217,6 +227,55 @@ time_t up_rtc_time(void)
return (uint32_t) (regval);
}
+#endif
+
+/****************************************************************************
+ * Name: up_rtc_gettime
+ *
+ * Description:
+ * Get the current time from the high resolution RTC clock/counter. This
+ * interface is only supported by the high-resolution RTC/counter hardware
+ * implementation. It is used to replace the system timer.
+ *
+ * Input Parameters:
+ * tp - The location to return the high resolution time value.
+ *
+ * Returned Value:
+ * Zero (OK) on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_RTC_HIRES
+int up_rtc_gettime(FAR struct timespec *tp)
+{
+ irqstate_t flags;
+ uint32_t seconds;
+ uint32_t prescaler;
+ uint32_t prescaler2;
+
+ /* Get prescaler and seconds register. this is in a loop which ensures that
+ * registers will be re-read if during the reads the prescaler has
+ * wrapped-around.
+ */
+
+ flags = enter_critical_section();
+ do
+ {
+ prescaler = getreg32(S32K1XX_RTC_TPR);
+ seconds = getreg32(S32K1XX_RTC_TSR);
+ prescaler2 = getreg32(S32K1XX_RTC_TPR);
+ }
+ while (prescaler > prescaler2);
+
+ leave_critical_section(flags);
+
+ /* Build seconds + nanoseconds from seconds and prescaler register */
+
+ tp->tv_sec = seconds;
+ tp->tv_nsec = prescaler * (1000000000 / CONFIG_RTC_FREQUENCY);
+ return OK;
+}
+#endif
/****************************************************************************
* Name: up_rtc_settime
@@ -236,13 +295,25 @@ time_t up_rtc_time(void)
int up_rtc_settime(FAR const struct timespec *ts)
{
DEBUGASSERT(ts != NULL);
+
+ irqstate_t flags;
+ uint32_t seconds;
+ uint32_t prescaler;
+
+ seconds = ts->tv_sec;
+ prescaler = ts->tv_nsec * (CONFIG_RTC_FREQUENCY / 1000000000);
+
+ flags = enter_critical_section();
s32k1xx_rtc_disable();
- putreg32((uint32_t)ts->tv_sec, S32K1XX_RTC_TSR);
+ putreg32(prescaler, S32K1XX_RTC_TPR); /* Always write prescaler first */
+ putreg32(seconds, S32K1XX_RTC_TSR);
s32k1xx_rtc_enable();
+ leave_critical_section(flags);
+
return OK;
}
diff --git a/arch/arm/src/s32k1xx/s32k1xx_rtc.h b/arch/arm/src/s32k1xx/s32k1xx_rtc.h
index b00c3d3..35ce10d 100644
--- a/arch/arm/src/s32k1xx/s32k1xx_rtc.h
+++ b/arch/arm/src/s32k1xx/s32k1xx_rtc.h
@@ -58,14 +58,6 @@
# error CONFIG_RTC_PERIODIC should not be selected with this driver
# endif
-/* REVISIT: This is probably supportable. The 47 bit timer does have
- * accuracy greater than 1 second.
- */
-
-# ifdef CONFIG_RTC_HIRES
-# error CONFIG_RTC_PERIODIC should not be selected with this driver
-# endif
-
/****************************************************************************
* Public Function Prototypes
****************************************************************************/