mirror of
https://github.com/apache/nuttx.git
synced 2026-10-07 06:15:20 +00:00
This commit addes support for the i.MXRT RTC. This initial commit is code complete (with limited featurs and options) but untested.
Squashed commit of the following:
arch/arm/src/imxrt: Fix some first time compile issues.
arch/arm/src/imxrt: This brings the RTC implement to code complete but still untested.
arch/arm/src/imxrt: Add some RTC initialization logic.
arch/arm/src/imxrt: Flesh out most of the RTC driver lower half and LPSRTC support.
arch/arm/src/imxrt: Some inital, partial implementation of the HPRTC and LPSRTC.
arch/arm/src/imxrt: Add HPSRTC/HPRTC file framework (no logic, just skeleton files).
arch/arm/src/imxrt: Add HPRTC header file.
Some initial configuration logic for SNVS LPRTC and HP RTC.
This commit is contained in:
parent
691470c1cd
commit
5889a2397c
9 changed files with 1850 additions and 9 deletions
|
|
@ -136,6 +136,15 @@ config IMXRT_SEMC
|
|||
bool "Smart External Memory Controller (SEMC)"
|
||||
default n
|
||||
|
||||
config IMXRT_SNVS_LPSRTC
|
||||
bool "LP SRTC"
|
||||
default n
|
||||
select IMXRT_SNVS_HPRTC
|
||||
|
||||
config IMXRT_SNVS_HPRTC
|
||||
bool "HP RTC"
|
||||
default n
|
||||
|
||||
endmenu # i.MX RT Peripheral Selection
|
||||
|
||||
menuconfig IMXRT_GPIO_IRQ
|
||||
|
|
@ -452,4 +461,23 @@ config IMXRT_EDMA_EDBG
|
|||
system exits debug mode or the EDBG bit is cleared
|
||||
|
||||
endmenu # eDMA Global Configuration
|
||||
|
||||
menu "RTC Configuration"
|
||||
depends on IMXRT_SNVS_HPRTC
|
||||
|
||||
config IMXRT_RTC_MAGIC_REG
|
||||
int "RTC SNVS GPR"
|
||||
default 0
|
||||
range 0 3
|
||||
---help---
|
||||
The BKP register used to store/check the Magic value to determine if
|
||||
RTC is already setup
|
||||
|
||||
config IMXRT_RTC_MAGIC
|
||||
hex "RTC Magic 1"
|
||||
default 0xfacefeed
|
||||
---help---
|
||||
Value used as Magic to determine if the RTC is already setup
|
||||
|
||||
endmenu
|
||||
endif # ARCH_CHIP_IMXRT
|
||||
|
|
|
|||
|
|
@ -120,6 +120,17 @@ ifeq ($(CONFIG_IMXRT_EDMA),y)
|
|||
CHIP_CSRCS += imxrt_edma.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_IMXRT_SNVS_LPSRTC),y)
|
||||
CHIP_CSRCS += imxrt_lpsrtc.c
|
||||
CHIP_CSRCS += imxrt_hprtc.c
|
||||
else ifeq ($(CONFIG_IMXRT_SNVS_HPRTC),y)
|
||||
CHIP_CSRCS += imxrt_hprtc.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_RTC_DRIVER),y)
|
||||
CHIP_CSRCS += imxrt_rtc_lowerhalf.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_IMXRT_ENET),y)
|
||||
CHIP_CSRCS += imxrt_enet.c
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@
|
|||
* Pre-processor Definitions
|
||||
********************************************************************************************/
|
||||
|
||||
#define IMXRT_SNVS_LP_MAXTAMPER 10
|
||||
|
||||
/* Register offsets *************************************************************************/
|
||||
|
||||
#define IMXRT_SNVS_HPLR_OFFSET 0x0000 /* SNVS_HP Lock Register */
|
||||
|
|
@ -127,7 +129,9 @@
|
|||
/* Bits 0-3: Reserved */
|
||||
#define SNVS_HPCOMR_LPSWR (1 << 4) /* Bit 4: LP Software Reset */
|
||||
#define SNVS_HPCOMR_LPSWRDIS (1 << 5) /* Bit 5: LP Software Reset Disable */
|
||||
/* Bits 6-30: Reserved */
|
||||
/* Bits 6-7: Reserved */
|
||||
#define SNVS_HPCOMR_SWSV (1 << 8) /* Bit 8: */
|
||||
/* Bits 9-30: Reserved */
|
||||
#define SNVS_HPCOMR_NPSWAEN (1 << 31) /* Bit 31: Non-Privileged Software Access Enable */
|
||||
|
||||
/* SNVS_HP Control Register */
|
||||
|
|
@ -143,6 +147,7 @@
|
|||
/* Bit 9: Reserved */
|
||||
#define SNVS_HPCR_HPCALBVAL_SHIFT (10) /* Bits 10-14: HP Calibration Value */
|
||||
#define SNVS_HPCR_HPCALBVAL_MASK (31 << SNVS_HPCR_HPCALBVAL_SHIFT)
|
||||
# define SNVS_HPCR_HPCALBVAL(n) ((uint32_t)(n) << SNVS_HPCR_HPCALBVAL_SHIFT)
|
||||
# define SNVS_HPCR_HPCALBVAL_ZERO (0 << SNVS_HPCR_HPCALBVAL_SHIFT) /* +0 counts per 32768 ticks */
|
||||
# define SNVS_HPCR_HPCALBVAL_P1 (1 << SNVS_HPCR_HPCALBVAL_SHIFT) /* +1 counts per 32768 ticks */
|
||||
# define SNVS_HPCR_HPCALBVAL_P2 (2 << SNVS_HPCR_HPCALBVAL_SHIFT) /* +2 counts per 32768 ticks */
|
||||
|
|
@ -151,7 +156,9 @@
|
|||
# define SNVS_HPCR_HPCALBVAL_M15 (17 << SNVS_HPCR_HPCALBVAL_SHIFT) /* -15 counts per 32768 ticks */
|
||||
# define SNVS_HPCR_HPCALBVAL_M2 (30 << SNVS_HPCR_HPCALBVAL_SHIFT) /* -2 counts per 32768 ticks */
|
||||
# define SNVS_HPCR_HPCALBVAL_M1 (31 << SNVS_HPCR_HPCALBVAL_SHIFT) /* -1 counts per 32768 ticks */
|
||||
/* Bits 15-23: Reserved */
|
||||
/* Bits 15: Reserved */
|
||||
#define SNVS_HPCR_HPTS (1 << 16) /* Bit 16: LPSRTC time sychronization */
|
||||
/* Bits 17-23: Reserved */
|
||||
#define SNVS_HPCR_BTNCONFIG_SHIFT (24) /* Bits 24-26: Button Configuration */
|
||||
#define SNVS_HPCR_BTNCONFIG_MASK (7 << SNVS_HPCR_BTNCONFIG_SHIFT)
|
||||
# define SNVS_HPCR_BTNCONFIG_ LOW (0 << SNVS_HPCR_BTNCONFIG_SHIFT) /* Button signal active low */
|
||||
|
|
@ -183,8 +190,6 @@
|
|||
|
||||
#define SNVS_HPTAMR_MASK 0x00007fff /* Bits 0-14: HP Time Alarm, most-significant 15 bits */
|
||||
|
||||
#define SNVS_HPTALR_
|
||||
|
||||
/* SNVS_LP Lock Register */
|
||||
|
||||
/* Bits 0-3: Reserved */
|
||||
|
|
@ -203,6 +208,20 @@
|
|||
#define SNVS_LPCR_TOP (1 << 6) /* Bit 6: Turn off System Power */
|
||||
#define SNVS_LPCR_PWRGLITCHEN (1 << 7) /* Bit 7: Power Glitch Enable */
|
||||
/* Bits 8-15: Reserved */
|
||||
#define SNVS_LPCR_LPCALBEN (1 << 8) /* Bit 8: LP Real Time Counter Calibration Enabled */
|
||||
/* Bit 9: Reserved */
|
||||
#define SNVS_LPCR_LPCALBVAL_SHIFT (10) /* Bits 10-14: LP Calibration Value */
|
||||
#define SNVS_LPCR_LPCALBVAL_MASK (31 << SNVS_LPCR_LPCALBVAL_SHIFT)
|
||||
# define SNVS_LPCR_LPCALBVAL(n) ((uint32_t)(n) << SNVS_LPCR_LPCALBVAL_SHIFT)
|
||||
# define SNVS_LPCR_LPCALBVAL_ZERO (0 << SNVS_LPCR_LPCALBVAL_SHIFT) /* +0 counts per 32768 ticks */
|
||||
# define SNVS_LPCR_LPCALBVAL_P1 (1 << SNVS_LPCR_LPCALBVAL_SHIFT) /* +1 counts per 32768 ticks */
|
||||
# define SNVS_LPCR_LPCALBVAL_P2 (2 << SNVS_LPCR_LPCALBVAL_SHIFT) /* +2 counts per 32768 ticks */
|
||||
# define SNVS_LPCR_LPCALBVAL_P15 (15 << SNVS_LPCR_LPCALBVAL_SHIFT) /* +15 counts per 32768 ticks */
|
||||
# define SNVS_LPCR_LPCALBVAL_M16 (16 << SNVS_LPCR_LPCALBVAL_SHIFT) /* -16 counts per 32768 ticks */
|
||||
# define SNVS_LPCR_LPCALBVAL_M15 (17 << SNVS_LPCR_LPCALBVAL_SHIFT) /* -15 counts per 32768 ticks */
|
||||
# define SNVS_LPCR_LPCALBVAL_M2 (30 << SNVS_LPCR_LPCALBVAL_SHIFT) /* -2 counts per 32768 ticks */
|
||||
# define SNVS_LPCR_LPCALBVAL_M1 (31 << SNVS_LPCR_LPCALBVAL_SHIFT) /* -1 counts per 32768 ticks */
|
||||
/* Bit 15: Reserved */
|
||||
#define SNVS_LPCR_BTNPRESSTIME_SHIFT (16) /* Bits 16-17: PMIC button press time out values */
|
||||
#define SNVS_LPCR_BTNPRESSTIME_MASK (3 << SNVS_LPCR_BTNPRESSTIME_SHIFT)
|
||||
# define SNVS_LPCR_BTNPRESSTIME_5SEC (0 << SNVS_LPCR_BTNPRESSTIME_SHIFT) /* 5 secs */
|
||||
|
|
@ -229,7 +248,7 @@
|
|||
|
||||
/* Bits 0-1: Reserved */
|
||||
#define SNVS_LPSR_MCR (1 << 2) /* Bit 2: Monotonic Counter Rollover */
|
||||
/* Bits 3-16: Reserved */ */
|
||||
/* Bits 3-16: Reserved */
|
||||
#define SNVS_LPSR_EO (1 << 17) /* Bit 17: Emergency Off */
|
||||
#define SNVS_LPSR_SPO (1 << 18) /* Bit 18: Set Power Off */
|
||||
/* Bits 19-31: Reserved */
|
||||
|
|
|
|||
613
arch/arm/src/imxrt/imxrt_hprtc.c
Normal file
613
arch/arm/src/imxrt/imxrt_hprtc.c
Normal file
|
|
@ -0,0 +1,613 @@
|
|||
/************************************************************************************
|
||||
* arch/arm/src/imxrt/imxrt_lpsrtc.c
|
||||
*
|
||||
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
* Included Files
|
||||
************************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/timers/rtc.h>
|
||||
|
||||
#include <arch/board/board.h>
|
||||
|
||||
#include "up_arch.h"
|
||||
|
||||
#include "chip/imxrt_snvs.h"
|
||||
#include "imxrt_periphclks.h"
|
||||
#include "imxrt_lpsrtc.h"
|
||||
#include "imxrt_hprtc.h"
|
||||
|
||||
#ifdef CONFIG_IMXRT_SNVS_HPRTC
|
||||
|
||||
/************************************************************************************
|
||||
* Private Data
|
||||
************************************************************************************/
|
||||
|
||||
/* Callback to use when the alarm expires */
|
||||
|
||||
#if defined(CONFIG_RTC_ALARM) && defined(CONFIG_RTC_DRIVER)
|
||||
static hprtc_alarm_callback_t g_hprtc_alarmcb;
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
* Public Data
|
||||
************************************************************************************/
|
||||
|
||||
#if !defined(CONFIG_IMXRT_SNVS_LPSRTC) && defined(CONFIG_RTC_DRIVER)
|
||||
bool g_hprtc_timset; /* True: time has been set since power up */
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
* Private Functions
|
||||
************************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
* Name: imxrt_snvs_interrupt
|
||||
*
|
||||
* Description:
|
||||
* RTC interrupt service routine
|
||||
*
|
||||
* Input Parameters:
|
||||
* irq - The IRQ number that generated the interrupt
|
||||
* context - Architecture specific register save information.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success; A negated errno value on failure.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#if defined(CONFIG_RTC_ALARM) && defined(CONFIG_RTC_DRIVER)
|
||||
static int imxrt_snvs_interrupt(int irq, void *context, FAR void *arg)
|
||||
{
|
||||
hprtc_alarm_callback_t cb;
|
||||
|
||||
/* The alarm is the only interrupt enabled */
|
||||
|
||||
DEBUGASSERT((getreg32(IMXRT_SNVS_HPSR) & SNVS_HPSR_HPTA) != 0);
|
||||
|
||||
/* Sample and clear the callback */
|
||||
|
||||
cb = g_hprtc_alarmcb;
|
||||
g_hprtc_alarmcb = NULL;
|
||||
|
||||
/* Disable the alarm, alarm interrupts, clear pending alarm interrupt status */
|
||||
|
||||
imxrt_hprtc_alarmdisable();
|
||||
|
||||
/* Perform the callback */
|
||||
|
||||
cb();
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
* Name: imxrt_hprtc_enable
|
||||
*
|
||||
* Description:
|
||||
* Enable/start the HPRTC time counter.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
static void imxrt_hprtc_enable(void)
|
||||
{
|
||||
uint32_t regval;
|
||||
|
||||
/* Enable the HPRTC */
|
||||
|
||||
regval = getreg32(IMXRT_SNVS_HPCR);
|
||||
regval |= SNVS_HPCR_RTCEN;
|
||||
putreg32(regval, IMXRT_SNVS_HPCR);
|
||||
|
||||
while ((getreg32(IMXRT_SNVS_HPCR) & SNVS_HPCR_RTCEN) == 0)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
* Name: imxrt_hprtc_alarmenable
|
||||
*
|
||||
* Description:
|
||||
* Enable alarm interrupts. This is currently only used internally at the time
|
||||
* that alarm interrupts are enabled.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#if defined(CONFIG_RTC_ALARM) && defined(CONFIG_RTC_DRIVER)
|
||||
static void imxrt_hprtc_alarmenable(void)
|
||||
{
|
||||
uint32_t regval;
|
||||
|
||||
/* Enable the alarm */
|
||||
|
||||
regval = getreg32(IMXRT_SNVS_HPCR);
|
||||
regval |= SNVS_HPCR_HPTAEN;
|
||||
putreg32(regval, IMXRT_SNVS_HPCR);
|
||||
|
||||
/* Enable alarm interrupts at the NVIC */
|
||||
|
||||
up_enable_irq(IMXRT_IRQ_SNVS);
|
||||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
* Public Functions
|
||||
************************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
* Functions used only for HPRTC
|
||||
************************************************************************************/
|
||||
|
||||
#ifndef CONFIG_IMXRT_SNVS_LPSRTC
|
||||
|
||||
/************************************************************************************
|
||||
* Name: up_rtc_time
|
||||
*
|
||||
* Description:
|
||||
* Get the current time in seconds. This is similar to the standard time()
|
||||
* function. This interface is only required if the low-resolution RTC/counter
|
||||
* hardware implementation selected. It is only used by the RTOS during
|
||||
* initialization to set up the system time when CONFIG_RTC is set but neither
|
||||
* CONFIG_RTC_HIRES nor CONFIG_RTC_DATETIME are set.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* The current time in seconds
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
time_t up_rtc_time(void)
|
||||
{
|
||||
/* Delegate to imxrt_hprtc_time() */
|
||||
|
||||
return imxrt_hprtc_time();
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
* Name: up_rtc_settime
|
||||
*
|
||||
* Description:
|
||||
* Set the RTC to the provided time. All RTC implementations must be able to
|
||||
* set their time based on a standard timespec.
|
||||
*
|
||||
* Input Parameters:
|
||||
* tp - the time to use
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success; a negated errno on failure
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
int up_rtc_settime(FAR const struct timespec *tp)
|
||||
{
|
||||
uint32_t regval;
|
||||
|
||||
DEBUGASSERT(tp != NULL);
|
||||
|
||||
/* Disable the HPRTC */
|
||||
|
||||
regval = getreg32(IMXRT_SNVS_HPCR);
|
||||
regval = hcpr & ~SNVS_HPCR_RTCEN;
|
||||
putreg32(regval, IMXRT_SNVS_HPCR);
|
||||
|
||||
while ((getreg32(IMXRT_SNVS_HPCR) & SNVS_HPCR_RTCEN) != 0)
|
||||
{
|
||||
}
|
||||
|
||||
/* Set HPRTC time in seconds. We could do better by accounting for the
|
||||
* ts->tv_nsec unused residual.
|
||||
*
|
||||
* IMXRT_SNVS_HPTAMR Bits 9-14 = 15-bit MSB of alarm setting.
|
||||
* IMXRT_SNVS_HPTALR 32-bit LSB of alarm setting.
|
||||
*/
|
||||
|
||||
putreg32((uint32_t)ts->tv_sec >> 17, IMXRT_SNVS_HPRTCMR);
|
||||
putreg32((uint32_t)ts->tv_sec << 15, IMXRT_SNVS_HPRTCLR);
|
||||
|
||||
#ifdef CONFIG_RTC_DRIVER
|
||||
/* The time has been set */
|
||||
|
||||
g_hprtc_timset = true;
|
||||
#endif
|
||||
|
||||
/* Unconditionally re-enable the HPRTC */
|
||||
|
||||
imxrt_hprtc_enable();
|
||||
return OK;
|
||||
}
|
||||
|
||||
#endif /* !CONFIG_IMXRT_SNVS_LPSRTC */
|
||||
|
||||
/************************************************************************************
|
||||
* Logic Common to LPSRTC and HPRTC
|
||||
************************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
* Name: up_rtc_initialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize the hardware RTC per the selected configuration. This function is
|
||||
* called once during the OS initialization sequence
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success; a negated errno on failure
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
int up_rtc_initialize(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
#ifdef CONFIG_IMXRT_SNVS_LPSRTC
|
||||
/* Perform LPSRTC initialization */
|
||||
|
||||
ret = imxrt_lpsrtc_initialize();
|
||||
if (ret < 0)
|
||||
{
|
||||
rtcerr("ERROR: imxrt_lpsrtc_initialize failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
/* Initialize the HPRTC */
|
||||
|
||||
ret = imxrt_hprtc_initialize();
|
||||
if (ret < 0)
|
||||
{
|
||||
rtcerr("ERROR: imxrt_hprtc_initialize failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Start the HPRTC */
|
||||
|
||||
imxrt_hprtc_enable();
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_IMXRT_SNVS_HPRTC) && defined(CONFIG_RTC_ALARM) && \
|
||||
defined(CONFIG_RTC_DRIVER)
|
||||
/* Attach the alarm interrupt handler */
|
||||
|
||||
ret = irq_attach(IMXRT_IRQ_SNVS, imxrt_snvs_interrupt, NULL);
|
||||
if (ret < 0)
|
||||
{
|
||||
rtcerr("ERROR: Failed to attach to IRQ%d\n", IMXRT_IRQ_SNVS);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
* Name: imxrt_hprtc_initialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize the LPSRTC per the selected configuration. This function is called
|
||||
* via up_rtc_initialize (see imxrt_hprtc.c).
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success; a negated errno on failure
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
int imxrt_hprtc_initialize(void)
|
||||
{
|
||||
uint32_t regval;
|
||||
|
||||
/* Enable clocking to the the SNVS HP module.
|
||||
* Clock is on in run mode, but off in WAIT and STOP modes.
|
||||
*/
|
||||
|
||||
imxrt_clockrun_snvs_hp();
|
||||
|
||||
/* Enable non-privileged access */
|
||||
|
||||
regval = getreg32(IMXRT_SNVS_HPCOMR);
|
||||
regval |= (SNVS_HPCOMR_NPSWAEN | SNVS_HPCOMR_SWSV);
|
||||
putreg32(regval, IMXRT_SNVS_HPCOMR);
|
||||
|
||||
/* TODO: Set the periodic interrupt frequency */
|
||||
|
||||
putreg32(SNVS_HPCR_PIFREQ(0), IMXRT_SNVS_HPCR);
|
||||
|
||||
#ifdef CONFIG_IMXRTC_HPRTC_CALENABLE
|
||||
/* Set the HPRTC calibration value */
|
||||
|
||||
regval = getreg32(IMXRT_SNVS_HPCR);
|
||||
regval &= ~SNVS_HPCR_HPCALBVAL_MASK;
|
||||
regval |= SNVS_HPCR_HPCALBVAL(CONFIG_IMXRTC_HPRTC_CALVALUE);
|
||||
regval |= SNVS_HPCR_HPCALBEN;
|
||||
putreg32(regval, IMXRT_SNVS_HPCR);
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
* Name: imxrt_hprtc_synchronize
|
||||
*
|
||||
* Description:
|
||||
* Synchronize the HPRTC to the LPSRTC and enable the HPRTC timer.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#ifdef CONFIG_IMXRT_SNVS_LPSRTC
|
||||
void imxrt_hprtc_synchronize(void)
|
||||
{
|
||||
uint32_t regval;
|
||||
uint32_t hpcr;
|
||||
|
||||
/* Make sure that the RTC is disabled (it should be at this point in the LPSRTC
|
||||
* initialization sequence).
|
||||
*/
|
||||
|
||||
hpcr = getreg32(IMXRT_SNVS_HPCR);
|
||||
regval = hpcr;
|
||||
regval &= ~SNVS_HPCR_RTCEN;
|
||||
putreg32(regval, IMXRT_SNVS_HPCR);
|
||||
|
||||
while ((getreg32(IMXRT_SNVS_HPCR) & SNVS_HPCR_RTCEN) != 0)
|
||||
{
|
||||
}
|
||||
|
||||
/* Synchronize to the LPSRTC */
|
||||
|
||||
regval = getreg32(IMXRT_SNVS_HPCR);
|
||||
regval |= SNVS_HPCR_HPTS;
|
||||
putreg32(regval, IMXRT_SNVS_HPCR);
|
||||
|
||||
/* Unconditionally enable the HPRTC */
|
||||
|
||||
imxrt_hprtc_enable();
|
||||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
* Name: imxrt_hprtc_time
|
||||
*
|
||||
* Description:
|
||||
* Get the current time in seconds. This is the underlying implementation of the
|
||||
* up_rtc_time() function that is used by the RTOS during initialization to set up
|
||||
* the system time.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* The current time in seconds
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
uint32_t imxrt_hprtc_time(void)
|
||||
{
|
||||
uint32_t seconds;
|
||||
uint32_t verify = 0;
|
||||
|
||||
/* Do consecutive reads until value is correct */
|
||||
|
||||
do
|
||||
{
|
||||
/* IMXRT_SNVS_HPRTCMR: Bits 9-14 = 15-bit MSB of counter.
|
||||
* IMXRT_SNVS_HPRTCLR: 32-bit LSB of counter.
|
||||
*
|
||||
* REVISIT: This could be modified to support CONFIG_RTC_HI_RES
|
||||
*/
|
||||
|
||||
seconds = verify;
|
||||
verify = (getreg32(IMXRT_SNVS_HPRTCMR) << 17) |
|
||||
(getreg32(IMXRT_SNVS_HPRTCLR) >> 15);
|
||||
}
|
||||
while (verify != seconds);
|
||||
|
||||
return seconds;
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
* Name: imxrt_hprtc_getalarm
|
||||
*
|
||||
* Description:
|
||||
* Get the current alarm setting in seconds. This is only used by the lower half
|
||||
* RTC driver.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* The current alarm setting in seconds
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#if defined(CONFIG_RTC_ALARM) && defined(CONFIG_RTC_DRIVER)
|
||||
uint32_t imxrt_hprtc_getalarm(void)
|
||||
{
|
||||
/* Return the alarm setting in seconds
|
||||
*
|
||||
* IMXRT_SNVS_HPTAMR Bits 9-14 = 15-bit MSB of alarm setting.
|
||||
* IMXRT_SNVS_HPTALR 32-bit LSB of alarm setting.
|
||||
*/
|
||||
|
||||
return (getreg32(IMXRT_SNVS_HPTAMR) << 17) |
|
||||
(getreg32(IMXRT_SNVS_HPTALR) >> 15);
|
||||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
* Name: imxrt_hprtc_setalarm
|
||||
*
|
||||
* Description:
|
||||
* Set the alarm (in seconds) and enable alarm interrupts. This is only used by
|
||||
* the lower half RTC driver.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* The current alarm setting in seconds
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#if defined(CONFIG_RTC_ALARM) && defined(CONFIG_RTC_DRIVER)
|
||||
int imxrt_hprtc_setalarm(FAR struct timespec *ts, hprtc_alarm_callback_t cb)
|
||||
{
|
||||
irqstate_t flags;
|
||||
uint32_t regval;
|
||||
uint32_t now;
|
||||
|
||||
DEBUGASSERT(ts != NULL && cb != NULL);
|
||||
|
||||
/* Disable interrupts so that the following sequence of events will not be
|
||||
* interrupted or preempted.
|
||||
*/
|
||||
|
||||
flags = spin_lock_irqsave();
|
||||
|
||||
now = imxrt_hprtc_time();
|
||||
|
||||
/* Return error if the alarm time has passed.
|
||||
* NOTES: (1) This will fail, of course, when the number of seconds since
|
||||
* epoch wraps. (2) We could do better by accounting for the ts->tv_nsec
|
||||
* unused residual.
|
||||
*/
|
||||
|
||||
if ((uint32_t)ts->tv_sec <= now)
|
||||
{
|
||||
rtcwarn("WARNING: time is in the past\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Disable the RTC alarm interrupt */
|
||||
|
||||
regval = getreg32(IMXRT_SNVS_HPCR);
|
||||
regval &= ~SNVS_HPCR_HPTAEN;
|
||||
putreg32(regval, IMXRT_SNVS_HPCR);
|
||||
|
||||
while ((getreg32(IMXRT_SNVS_HPCR) & SNVS_HPCR_HPTAEN) != 0)
|
||||
{
|
||||
}
|
||||
|
||||
/* Save the alarm callback */
|
||||
|
||||
g_hprtc_alarmcb = cb;
|
||||
|
||||
/* Set alarm in seconds
|
||||
*
|
||||
* IMXRT_SNVS_HPTAMR Bits 9-14 = 15-bit MSB of alarm setting.
|
||||
* IMXRT_SNVS_HPTALR 32-bit LSB of alarm setting.
|
||||
*/
|
||||
|
||||
putreg32((uint32_t)ts->tv_sec >> 17, IMXRT_SNVS_HPTAMR);
|
||||
putreg32((uint32_t)ts->tv_sec << 15, IMXRT_SNVS_HPTALR);
|
||||
|
||||
/* Unconditionally enable the RTC alarm interrupt */
|
||||
|
||||
imxrt_hprtc_alarmenable();
|
||||
spin_unlock_irqrestore(flags);
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
* Name: imxrt_hprtc_alarmdisable
|
||||
*
|
||||
* Description:
|
||||
* Disable alarm interrupts. Used internally after the receipt of the alarm
|
||||
* interrupt. Also called by the lower-half RTC driver in order to cancel an
|
||||
* alarm.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#if defined(CONFIG_RTC_ALARM) && defined(CONFIG_RTC_DRIVER)
|
||||
void imxrt_hprtc_alarmdisable(void)
|
||||
{
|
||||
uint32_t regval;
|
||||
|
||||
/* Disable alarm interrupts at the NVIC */
|
||||
|
||||
up_disable_irq(IMXRT_IRQ_SNVS);
|
||||
|
||||
/* Disable the alarm function */
|
||||
|
||||
regval = getreg32(IMXRT_SNVS_HPCR);
|
||||
regval &= ~SNVS_HPCR_HPTAEN;
|
||||
putreg32(regval, IMXRT_SNVS_HPCR);
|
||||
|
||||
/* Clear any pending alarm interrupts */
|
||||
|
||||
putreg32(SNVS_HPSR_HPTA, IMXRT_SNVS_HPSR);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_IMXRT_SNVS_HPRTC */
|
||||
255
arch/arm/src/imxrt/imxrt_hprtc.h
Normal file
255
arch/arm/src/imxrt/imxrt_hprtc.h
Normal file
|
|
@ -0,0 +1,255 @@
|
|||
/****************************************************************************
|
||||
* arch/arm/src/imxrt/imxrt_hprtc.h
|
||||
*
|
||||
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ARCH_ARM_SRC_IMXRT_IMXRT_HPRTC_H
|
||||
#define __ARCH_ARM_SRC_IMXRT_IMXRT_HPRTC_H
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include "chip.h"
|
||||
|
||||
#ifdef CONFIG_IMXRT_SNVS_HPRTC
|
||||
|
||||
/****************************************************************************
|
||||
* Preprocessor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_RTC_DATETIME
|
||||
# error CONFIG_RTC_DATETIME should not be selected with this driver
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_RTC_PERIODIC
|
||||
# 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
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/* Callback type used by the HPRTC log to notify the RTC driver when the
|
||||
* alarm expires.
|
||||
*/
|
||||
|
||||
typedef CODE void (*hprtc_alarm_callback_t)(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
#if !defined(CONFIG_IMXRT_SNVS_LPSRTC) && defined(CONFIG_RTC_DRIVER)
|
||||
bool g_hprtc_timset; /* True: time has been set since power up */
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
#define EXTERN extern "C"
|
||||
extern "C"
|
||||
{
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
* Functions used only for HPRTC
|
||||
************************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
* Logic Common to LPSRTC and HPRTC
|
||||
************************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt_rtc_lowerhalf
|
||||
*
|
||||
* Description:
|
||||
* Instantiate the RTC lower half driver for the i.MXRT. General usage:
|
||||
*
|
||||
* #include <nuttx/timers/rtc.h>
|
||||
* #include "imxrt_hprtc.h"
|
||||
*
|
||||
* struct rtc_lowerhalf_s *lower;
|
||||
* lower = imxrt_hprtc_lowerhalf();
|
||||
* rtc_initialize(0, lower);
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* On success, a non-NULL RTC lower interface is returned. NULL is
|
||||
* returned on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_RTC_DRIVER
|
||||
struct rtc_lowerhalf_s;
|
||||
FAR struct rtc_lowerhalf_s *imxrt_rtc_lowerhalf(void);
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
* Name: imxrt_hprtc_initialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize the LPSRTC per the selected configuration. This function is called
|
||||
* via up_rtc_initialize (see imxrt_hprtc.c).
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success; a negated errno on failure
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
int imxrt_hprtc_initialize(void);
|
||||
|
||||
/************************************************************************************
|
||||
* Name: imxrt_hprtc_synchronize
|
||||
*
|
||||
* Description:
|
||||
* Synchronize the HPRTC to the LPSRTC and enable the HPRTC timer.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#ifdef CONFIG_IMXRT_SNVS_LPSRTC
|
||||
void imxrt_hprtc_synchronize(void);
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
* Name: imxrt_hprtc_time
|
||||
*
|
||||
* Description:
|
||||
* Get the current time in seconds. This is the underlying implementation of the
|
||||
* up_rtc_tim() function that is used by the RTOS during initialization to set up
|
||||
* the system time.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* The current time in seconds
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
uint32_t imxrt_hprtc_time(void);
|
||||
|
||||
/************************************************************************************
|
||||
* Name: imxrt_hprtc_getalarm
|
||||
*
|
||||
* Description:
|
||||
* Get the current alarm setting in seconds. This is only used by the lower half
|
||||
* RTC driver.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* The current alarm setting in seconds
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#if defined(CONFIG_RTC_ALARM) && defined(CONFIG_RTC_DRIVER)
|
||||
uint32_t imxrt_hprtc_getalarm(void);
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
* Name: imxrt_hprtc_setalarm
|
||||
*
|
||||
* Description:
|
||||
* Set the alarm (in seconds) and enable alarm interrupts. This is only used by
|
||||
* the lower half RTC driver.
|
||||
*
|
||||
* Input Parameters:
|
||||
* sec - The new alarm setting
|
||||
*
|
||||
* Returned Value:
|
||||
* The current alarm setting in seconds
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#if defined(CONFIG_RTC_ALARM) && defined(CONFIG_RTC_DRIVER)
|
||||
int imxrt_hprtc_setalarm(FAR struct timespec *ts, hprtc_alarm_callback_t cb);
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
* Name: imxrt_hprtc_alarmdisable
|
||||
*
|
||||
* Description:
|
||||
* Disable alarm interrupts. Used internally after the receipt of the alarm
|
||||
* interrupt. Also called by the lower-half RTC driver in order to cancel an
|
||||
* alarm.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#if defined(CONFIG_RTC_ALARM) && defined(CONFIG_RTC_DRIVER)
|
||||
void imxrt_hprtc_alarmdisable(void);
|
||||
#endif
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* CONFIG_IMXRT_SNVS_HPRTC */
|
||||
#endif /* __ARCH_ARM_SRC_IMXRT_IMXRT_HPRTC_H */
|
||||
258
arch/arm/src/imxrt/imxrt_lpsrtc.c
Normal file
258
arch/arm/src/imxrt/imxrt_lpsrtc.c
Normal file
|
|
@ -0,0 +1,258 @@
|
|||
/************************************************************************************
|
||||
* arch/arm/src/imxrt/imxrt_lpsrtc.c
|
||||
*
|
||||
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
* Included Files
|
||||
************************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/timers/rtc.h>
|
||||
|
||||
#include <arch/board/board.h>
|
||||
|
||||
#include "up_arch.h"
|
||||
|
||||
#include "chip/imxrt_snvs.h"
|
||||
#include "imxrt_periphclks.h"
|
||||
#include "imxrt_hprtc.h"
|
||||
#include "imxrt_lpsrtc.h"
|
||||
|
||||
#ifdef CONFIG_IMXRT_SNVS_LPSRTC
|
||||
|
||||
/************************************************************************************
|
||||
* Private Functions
|
||||
************************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
* Name: imxrt_lpsrtc_enable
|
||||
*
|
||||
* Description:
|
||||
* Enable/start the LPRTC time counter.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
static void imxrt_lpsrtc_enable(void)
|
||||
{
|
||||
uint32_t regval;
|
||||
|
||||
/* Enable the LPSRTC */
|
||||
|
||||
regval = getreg32(IMXRT_SNVS_LPCR);
|
||||
regval |= SNVS_LPCR_MCENV;
|
||||
putreg32(regval, IMXRT_SNVS_LPCR);
|
||||
|
||||
while ((getreg32(IMXRT_SNVS_LPCR) & SNVS_LPCR_MCENV) == 0)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
* Public Functions
|
||||
************************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
* Name: imxrt_lpsrtc_initialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize the LPSRTC per the selected configuration. This function is called
|
||||
* via up_rtc_initialize (see imxrt_hprtc.c).
|
||||
*
|
||||
* NOTE that the LPSRTC is always configured synchronized with the HPRTC. This
|
||||
* means that the time is set via the LPSRTC but read via the HPRTC. Also, only
|
||||
* the alarms from the HPRTC are used.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success; a negated errno on failure
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
int imxrt_lpsrtc_initialize(void)
|
||||
{
|
||||
#ifdef CONFIG_IMXRTC_LPSRTC_CALENABLE
|
||||
uint32_t regval;
|
||||
#endif
|
||||
|
||||
/* Initialize the HPRTC */
|
||||
|
||||
imxrt_hprtc_initialize();
|
||||
|
||||
/* Enable clocking to the the SNVS LP module.
|
||||
* Clock is on during all modes, except STOP mode.
|
||||
*/
|
||||
|
||||
imxrt_clockall_snvs_lp();
|
||||
|
||||
#ifdef CONFIG_IMXRTC_LPSRTC_CALENABLE
|
||||
/* Set the LPSRTC calibration value */
|
||||
|
||||
regval = getreg32(IMXRT_SNVS_LPCR);
|
||||
regval &= ~SNVS_LPCR_LPCALBVAL_MASK;
|
||||
regval |= SNVS_LPCR_LPCALBVAL(CONFIG_IMXRTC_LPSRTC_CALVALUE);
|
||||
regval |= SNVS_LPCR_LPCALBEN;
|
||||
putreg32(regval, IMXRT_SNVS_LPCR);
|
||||
#endif
|
||||
|
||||
/* Disable tamper pins.
|
||||
* TODO: I don't think this applies the currently supported device.
|
||||
*/
|
||||
|
||||
/* Enable the LPSRTC */
|
||||
|
||||
imxrt_lpsrtc_enable();
|
||||
|
||||
/* Synchronize HPRTC time with the LPSRTC and enable HPRTC */
|
||||
|
||||
imxrt_hprtc_synchronize();
|
||||
return OK;
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
* Name: up_rtc_time
|
||||
*
|
||||
* Description:
|
||||
* Get the current time in seconds. This is similar to the standard time()
|
||||
* function. This interface is only required if the low-resolution RTC/counter
|
||||
* hardware implementation selected. It is only used by the RTOS during
|
||||
* initialization to set up the system time when CONFIG_RTC is set but neither
|
||||
* CONFIG_RTC_HIRES nor CONFIG_RTC_DATETIME are set.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* The current time in seconds
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#ifndef CONFIG_RTC_HIRES
|
||||
time_t up_rtc_time(void)
|
||||
{
|
||||
/* Delegate to imxrt_hprtc_time() */
|
||||
|
||||
return imxrt_hprtc_time();
|
||||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
* Name: up_rtc_settime
|
||||
*
|
||||
* Description:
|
||||
* Set the RTC to the provided time. All RTC implementations must be able to
|
||||
* set their time based on a standard timespec.
|
||||
*
|
||||
* Input Parameters:
|
||||
* tp - the time to use
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success; a negated errno on failure
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
int up_rtc_settime(FAR const struct timespec *ts)
|
||||
{
|
||||
uint32_t regval;
|
||||
|
||||
DEBUGASSERT(ts != NULL);
|
||||
|
||||
/* Disable the LPSRTC */
|
||||
|
||||
regval = getreg32(IMXRT_SNVS_LPCR);
|
||||
regval &= ~SNVS_LPCR_MCENV;
|
||||
putreg32(regval, IMXRT_SNVS_LPCR);
|
||||
|
||||
while ((getreg32(IMXRT_SNVS_LPCR) & SNVS_LPCR_MCENV) != 0)
|
||||
{
|
||||
}
|
||||
|
||||
/* Set LPSRTC time in seconds. We could do better by accounting for the
|
||||
* ts->tv_nsec unused residual.
|
||||
*
|
||||
* IMXRT_SNVS_LPSMCMR Bits 9-14 = 15-bit MSB of alarm setting.
|
||||
* IMXRT_SNVS_LPSMCLR 32-bit LSB of alarm setting.
|
||||
*/
|
||||
|
||||
putreg32((uint32_t)ts->tv_sec >> 17, IMXRT_SNVS_LPSMCMR);
|
||||
putreg32((uint32_t)ts->tv_sec << 15, IMXRT_SNVS_LPSMCLR);
|
||||
|
||||
/* The time has been set */
|
||||
|
||||
putreg32(CONFIG_IMXRT_RTC_MAGIC,
|
||||
IMXRT_SNVS_LPGPR(CONFIG_IMXRT_RTC_MAGIC_REG));
|
||||
|
||||
/* Unconditionally re-enable the LPSRTC */
|
||||
|
||||
imxrt_lpsrtc_enable();
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt_lpsrtc_havesettime
|
||||
*
|
||||
* Description:
|
||||
* Check if the LPSRTC time has been set
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* Returns true if RTC date-time have been previously set.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
bool imxrt_lpsrtc_havesettime(void)
|
||||
{
|
||||
return (getreg32(IMXRT_SNVS_LPGPR(CONFIG_IMXRT_RTC_MAGIC_REG)) ==
|
||||
CONFIG_IMXRT_RTC_MAGIC);
|
||||
}
|
||||
#endif /* CONFIG_IMXRT_SNVS_LPSRTC */
|
||||
127
arch/arm/src/imxrt/imxrt_lpsrtc.h
Normal file
127
arch/arm/src/imxrt/imxrt_lpsrtc.h
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
/****************************************************************************
|
||||
* arch/arm/src/imxrt/imxrt_lpsrtc.h
|
||||
*
|
||||
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ARCH_ARM_SRC_IMXRT_IMXRT_LPSRTC_H
|
||||
#define __ARCH_ARM_SRC_IMXRT_IMXRT_LPSRTC_H
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include "chip.h"
|
||||
|
||||
#ifdef CONFIG_IMXRT_SNVS_LPSRTC
|
||||
|
||||
/****************************************************************************
|
||||
* Preprocessor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
# ifdef CONFIG_RTC_DATETIME
|
||||
# error CONFIG_RTC_DATETIME should not be selected with this driver
|
||||
# endif
|
||||
|
||||
# ifdef CONFIG_RTC_PERIODIC
|
||||
# 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
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
#define EXTERN extern "C"
|
||||
extern "C"
|
||||
{
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
* Name: imxrt_lpsrtc_initialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize the LPSRTC per the selected configuration. This function is called
|
||||
* via up_rtc_initialize (see imxrt_hprtc.c).
|
||||
*
|
||||
* NOTE that the LPSRTC is always configured synchronized with the HPRTC. This
|
||||
* means that the time is set via the LPSRTC but read via the HPRTC. Also, only
|
||||
* the alarms from the HPRTC are used.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success; a negated errno on failure
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
int imxrt_lpsrtc_initialize(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt_lpsrtc_havesettime
|
||||
*
|
||||
* Description:
|
||||
* Check if the LPSRTC time has been set
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* Returns true if RTC date-time have been previously set.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
bool imxrt_lpsrtc_havesettime(void);
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif /* __ASSEMBLY__ */
|
||||
#endif /* CONFIG_IMXRT_SNVS_LPSRTC */
|
||||
#endif /* __ARCH_ARM_SRC_IMXRT_IMXRT_LPSRTC_H */
|
||||
534
arch/arm/src/imxrt/imxrt_rtc_lowerhalf.c
Normal file
534
arch/arm/src/imxrt/imxrt_rtc_lowerhalf.c
Normal file
|
|
@ -0,0 +1,534 @@
|
|||
/****************************************************************************
|
||||
* arch/arm/src/imxrt/imxrt_rtc_lowerhalf.c
|
||||
*
|
||||
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/timers/rtc.h>
|
||||
|
||||
#include "up_arch.h"
|
||||
|
||||
#include "chip.h"
|
||||
#include "imxrt_lpsrtc.h"
|
||||
#include "imxrt_hprtc.h"
|
||||
|
||||
#ifdef CONFIG_RTC_DRIVER
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/* This is the private type for the RTC state. It must be cast compatible
|
||||
* with struct rtc_lowerhalf_s.
|
||||
*/
|
||||
|
||||
struct imxrt_lowerhalf_s
|
||||
{
|
||||
/* This is the contained reference to the read-only, lower-half
|
||||
* operations vtable (which may lie in FLASH or ROM)
|
||||
*/
|
||||
|
||||
FAR const struct rtc_ops_s *ops;
|
||||
|
||||
/* Data following is private to this driver and not visible outside of
|
||||
* this file.
|
||||
*/
|
||||
|
||||
sem_t devsem; /* Threads can only exclusively access the RTC */
|
||||
|
||||
#ifdef CONFIG_RTC_ALARM
|
||||
/* Alarm callback information */
|
||||
|
||||
volatile rtc_alarm_callback_t cb; /* Callback when the alarm expires */
|
||||
volatile FAR void *priv; /* Private argument to accompany callback */
|
||||
#endif
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/* Prototypes for static methods in struct rtc_ops_s */
|
||||
|
||||
static int imxrt_rdtime(FAR struct rtc_lowerhalf_s *lower,
|
||||
FAR struct rtc_time *rtctime);
|
||||
static int imxrt_settime(FAR struct rtc_lowerhalf_s *lower,
|
||||
FAR const struct rtc_time *rtctime);
|
||||
static bool imxrt_havesettime(FAR struct rtc_lowerhalf_s *lower);
|
||||
|
||||
#ifdef CONFIG_RTC_ALARM
|
||||
static int imxrt_setalarm(FAR struct rtc_lowerhalf_s *lower,
|
||||
FAR const struct lower_setalarm_s *alarminfo);
|
||||
static int imxrt_setrelative(FAR struct rtc_lowerhalf_s *lower,
|
||||
FAR const struct lower_setrelative_s *alarminfo);
|
||||
static int imxrt_cancelalarm(FAR struct rtc_lowerhalf_s *lower,
|
||||
int alarmid);
|
||||
static int imxrt_rdalarm(FAR struct rtc_lowerhalf_s *lower,
|
||||
FAR struct lower_rdalarm_s *alarminfo);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
/* i.MXRT RTC driver operations */
|
||||
|
||||
static const struct rtc_ops_s g_rtc_ops =
|
||||
{
|
||||
.rdtime = imxrt_rdtime,
|
||||
.settime = imxrt_settime,
|
||||
.havesettime = imxrt_havesettime,
|
||||
#ifdef CONFIG_RTC_ALARM
|
||||
.setalarm = imxrt_setalarm,
|
||||
.setrelative = imxrt_setrelative,
|
||||
.cancelalarm = imxrt_cancelalarm,
|
||||
.rdalarm = imxrt_rdalarm,
|
||||
#endif
|
||||
#ifdef CONFIG_RTC_PERIODIC
|
||||
.setperiodic = NULL, /* Not implemented */
|
||||
.cancelperiodic = NULL,
|
||||
#endif
|
||||
#ifdef CONFIG_RTC_IOCTL
|
||||
.ioctl = NULL,
|
||||
#endif
|
||||
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
|
||||
.destroy = NULL,
|
||||
#endif
|
||||
};
|
||||
|
||||
/* i.MXRT RTC device state */
|
||||
|
||||
static struct imxrt_lowerhalf_s g_rtc_lowerhalf =
|
||||
{
|
||||
.ops = &g_rtc_ops,
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt_alarm_callback
|
||||
*
|
||||
* Description:
|
||||
* This is the function that is called from the RTC driver when the alarm
|
||||
* goes off. It just invokes the upper half drivers callback.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_RTC_ALARM
|
||||
static void imxrt_alarm_callback(void)
|
||||
{
|
||||
FAR struct imxrt_lowerhalf_s *rtc = &g_rtc_lowerhalf;
|
||||
|
||||
/* Sample and clear the callback information to minimize the window in
|
||||
* time in which race conditions can occur.
|
||||
*/
|
||||
|
||||
rtc_alarm_callback_t cb = (rtc_alarm_callback_t)rtc->cb;
|
||||
FAR void *arg = (FAR void *)rtc->priv;
|
||||
|
||||
rtc->cb = NULL;
|
||||
rtc->priv = NULL;
|
||||
|
||||
/* Perform the callback */
|
||||
|
||||
if (cb != NULL)
|
||||
{
|
||||
cb(arg, 0);
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_RTC_ALARM */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt_rdtime
|
||||
*
|
||||
* Description:
|
||||
* Implements the rdtime() method of the RTC driver interface
|
||||
*
|
||||
* Input Parameters:
|
||||
* lower - A reference to RTC lower half driver state structure
|
||||
* rcttime - The location in which to return the current RTC time.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned
|
||||
* on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int imxrt_rdtime(FAR struct rtc_lowerhalf_s *lower,
|
||||
FAR struct rtc_time *rtctime)
|
||||
{
|
||||
time_t timer;
|
||||
|
||||
/* The resolution of time is only 1 second */
|
||||
|
||||
timer = up_rtc_time();
|
||||
|
||||
/* Convert the one second epoch time to a struct tm */
|
||||
|
||||
if (gmtime_r(&timer, (FAR struct tm *)rtctime) == 0)
|
||||
{
|
||||
int errcode = get_errno();
|
||||
DEBUGASSERT(errcode > 0);
|
||||
|
||||
rtcerr("ERROR: gmtime_r failed: %d\n", errcode);
|
||||
return -errcode;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt_settime
|
||||
*
|
||||
* Description:
|
||||
* Implements the settime() method of the RTC driver interface
|
||||
*
|
||||
* Input Parameters:
|
||||
* lower - A reference to RTC lower half driver state structure
|
||||
* rcttime - The new time to set
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned
|
||||
* on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int imxrt_settime(FAR struct rtc_lowerhalf_s *lower,
|
||||
FAR const struct rtc_time *rtctime)
|
||||
{
|
||||
struct timespec ts;
|
||||
|
||||
/* Convert the struct rtc_time to a time_t. Here we assume that struct
|
||||
* rtc_time is cast compatible with struct tm.
|
||||
*/
|
||||
|
||||
ts.tv_sec = mktime((FAR struct tm *)rtctime);
|
||||
ts.tv_nsec = 0;
|
||||
|
||||
/* Now set the time (to one second accuracy) */
|
||||
|
||||
return up_rtc_settime(&ts);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt_havesettime
|
||||
*
|
||||
* Description:
|
||||
* Implements the havesettime() method of the RTC driver interface
|
||||
*
|
||||
* Input Parameters:
|
||||
* lower - A reference to RTC lower half driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* Returns true if RTC date-time have been previously set.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static bool imxrt_havesettime(FAR struct rtc_lowerhalf_s *lower)
|
||||
{
|
||||
#ifdef CONFIG_IMXRT_SNVS_LPSRTC
|
||||
return imxrt_lpsrtc_havesettime();
|
||||
#else
|
||||
return g_hprtc_timset;
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt_setalarm
|
||||
*
|
||||
* Description:
|
||||
* Set a new alarm. This function implements the setalarm() method of the
|
||||
* RTC driver interface
|
||||
*
|
||||
* Input Parameters:
|
||||
* lower - A reference to RTC lower half driver state structure
|
||||
* alarminfo - Provided information needed to set the alarm
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned
|
||||
* on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_RTC_ALARM
|
||||
static int imxrt_setalarm(FAR struct rtc_lowerhalf_s *lower,
|
||||
FAR const struct lower_setalarm_s *alarminfo)
|
||||
{
|
||||
FAR struct imxrt_lowerhalf_s *rtc;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(lower != NULL && alarminfo != NULL && alarminfo->id == 0);
|
||||
rtc = (FAR struct imxrt_lowerhalf_s *)lower;
|
||||
|
||||
/* Get exclusive access to the alarm */
|
||||
|
||||
ret = nxsem_wait(&rtc->devsem);
|
||||
if (ret < 0)
|
||||
{
|
||||
rtcerr("ERROR: nxsem_wait failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = -EINVAL;
|
||||
if (alarminfo->id == 0)
|
||||
{
|
||||
struct timespec ts;
|
||||
|
||||
/* Convert the RTC time to a timespec (1 second accuracy) */
|
||||
|
||||
ts.tv_sec = mktime((FAR struct tm *)&alarminfo->time);
|
||||
ts.tv_nsec = 0;
|
||||
|
||||
/* Remember the callback information */
|
||||
|
||||
rtc->cb = alarminfo->cb;
|
||||
rtc->priv = alarminfo->priv;
|
||||
|
||||
/* And set the alarm */
|
||||
|
||||
ret = imxrt_hprtc_setalarm(&ts, imxrt_alarm_callback);
|
||||
if (ret < 0)
|
||||
{
|
||||
rtc->cb = NULL;
|
||||
rtc->priv = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
nxsem_post(&rtc->devsem);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt_setrelative
|
||||
*
|
||||
* Description:
|
||||
* Set a new alarm relative to the current time. This function implements
|
||||
* the setrelative() method of the RTC driver interface
|
||||
*
|
||||
* Input Parameters:
|
||||
* lower - A reference to RTC lower half driver state structure
|
||||
* alarminfo - Provided information needed to set the alarm
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned
|
||||
* on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_RTC_ALARM
|
||||
static int imxrt_setrelative(FAR struct rtc_lowerhalf_s *lower,
|
||||
FAR const struct lower_setrelative_s *alarminfo)
|
||||
{
|
||||
FAR struct imxrt_lowerhalf_s *rtc;
|
||||
FAR struct timespec ts;
|
||||
int ret = -EINVAL;
|
||||
|
||||
DEBUGASSERT(lower != NULL && alarminfo != NULL && alarminfo->id == 0);
|
||||
rtc = (FAR struct imxrt_lowerhalf_s *)lower;
|
||||
|
||||
/* Get exclusive access to the alarm */
|
||||
|
||||
ret = nxsem_wait(&rtc->devsem);
|
||||
if (ret < 0)
|
||||
{
|
||||
rtcerr("ERROR: nxsem_wait failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = -EINVAL;
|
||||
if (alarminfo->id == 0 && alarminfo->reltime > 0)
|
||||
{
|
||||
/* Get the current time in seconds */
|
||||
/* The resolution of time is only 1 second */
|
||||
|
||||
ts.tv_sec = up_rtc_time();
|
||||
ts.tv_nsec = 0;
|
||||
|
||||
/* Add the seconds offset. Add one to the number of seconds because
|
||||
* we are unsure of the phase of the timer.
|
||||
*/
|
||||
|
||||
ts.tv_sec += (alarminfo->reltime + 1);
|
||||
|
||||
/* Remember the callback information */
|
||||
|
||||
rtc->cb = alarminfo->cb;
|
||||
rtc->priv = alarminfo->priv;
|
||||
|
||||
/* And set the alarm */
|
||||
|
||||
ret = imxrt_hprtc_setalarm(&ts, imxrt_alarm_callback);
|
||||
if (ret < 0)
|
||||
{
|
||||
rtc->cb = NULL;
|
||||
rtc->priv = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
nxsem_post(&rtc->devsem);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt_cancelalarm
|
||||
*
|
||||
* Description:
|
||||
* Cancel the current alarm. This function implements the cancelalarm()
|
||||
* method of the RTC driver interface
|
||||
*
|
||||
* Input Parameters:
|
||||
* lower - A reference to RTC lower half driver state structure
|
||||
* alarminfo - Provided information needed to set the alarm
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned
|
||||
* on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_RTC_ALARM
|
||||
static int imxrt_cancelalarm(FAR struct rtc_lowerhalf_s *lower, int alarmid)
|
||||
{
|
||||
/* We cancel the alarm by alarm by disabling the alarm and the alarm
|
||||
* interrupt.
|
||||
*/
|
||||
|
||||
imxrt_hprtc_alarmdisable();
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt_rdalarm
|
||||
*
|
||||
* Description:
|
||||
* Query the RTC alarm.
|
||||
*
|
||||
* Input Parameters:
|
||||
* lower - A reference to RTC lower half driver state structure
|
||||
* alarminfo - Provided information needed to query the alarm
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned
|
||||
* on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_RTC_ALARM
|
||||
static int imxrt_rdalarm(FAR struct rtc_lowerhalf_s *lower,
|
||||
FAR struct lower_rdalarm_s *alarminfo)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
|
||||
DEBUGASSERT(lower != NULL && alarminfo != NULL && alarminfo->time != NULL);
|
||||
DEBUGASSERT(alarminfo->id == 0);
|
||||
|
||||
/* There is only one alarm */
|
||||
|
||||
if (alarminfo->id == 0)
|
||||
{
|
||||
time_t alarm;
|
||||
|
||||
/* Get the current alarm setting in seconds */
|
||||
|
||||
alarm = (time_t)imxrt_hprtc_getalarm();
|
||||
|
||||
/* Convert the one second epoch time to a struct tm */
|
||||
|
||||
ret = OK;
|
||||
if (gmtime_r(&alarm, (FAR struct tm *)alarminfo->time) == 0)
|
||||
{
|
||||
int errcode = get_errno();
|
||||
DEBUGASSERT(errcode > 0);
|
||||
ret = -errcode;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt_rtc_lowerhalf
|
||||
*
|
||||
* Description:
|
||||
* Instantiate the RTC lower half driver for the i.MXRT. General usage:
|
||||
*
|
||||
* #include <nuttx/timers/rtc.h>
|
||||
*
|
||||
* struct rtc_lowerhalf_s *lower;
|
||||
* lower = imxrt_rtc_lowerhalf();
|
||||
* rtc_initialize(0, lower);
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* On success, a non-NULL RTC lower interface is returned. NULL is
|
||||
* returned on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct rtc_lowerhalf_s *imxrt_rtc_lowerhalf(void)
|
||||
{
|
||||
nxsem_init(&g_rtc_lowerhalf.devsem, 0, 1);
|
||||
|
||||
return (FAR struct rtc_lowerhalf_s *)&g_rtc_lowerhalf;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_RTC_DRIVER */
|
||||
|
|
@ -289,10 +289,6 @@ Configuration sub-directories
|
|||
CONFIG_NSH_NETINIT_THREAD_PRIORITY=80
|
||||
CONFIG_NSH_NETINIT_THREAD_STACKSIZE=1568
|
||||
|
||||
STATUS: As of this writing, I get a hardfault when I enable the PHY
|
||||
interrupt so I suspect that there is something incorrect in that
|
||||
pin configuration.
|
||||
|
||||
nsh:
|
||||
|
||||
Configures the NuttShell (nsh) located at examples/nsh. This NSH
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue