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 61e9cab5f730c31ef739c494cf9acd4c4cc852b0 Author: Peter van der Perk <peter.vanderp...@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 1bc1dc99..73747a8 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 ****************************************************************************/