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
  ****************************************************************************/