arch/arm/src/lpc54xx: Add an RTC driver and a RTC character driver lower half. configs/lpcxpresso-lpc54628: Add logic to register the RTC character driver if it is enabled. Enable the RTC and RTC character driver in the NSH configuration.
This commit is contained in:
parent
7e7bdd181f
commit
0b91074850
@ -406,6 +406,11 @@ config LPC54_LCD
|
||||
default n
|
||||
depends on ARCH_LPC54_HAVE_LCD
|
||||
|
||||
config LPC54_RTC
|
||||
bool "RTC"
|
||||
default n
|
||||
select RTC
|
||||
|
||||
config LPC54_SDMMC
|
||||
bool "SD/MMC"
|
||||
default n
|
||||
|
@ -105,6 +105,13 @@ ifeq ($(CONFIG_LPC54_GPIOIRQ),y)
|
||||
CHIP_CSRCS += lpc54_gpioirq.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_RTC),y)
|
||||
CHIP_CSRCS += lpc54_rtc.c
|
||||
ifeq ($(CONFIG_RTC_DRIVER),y)
|
||||
CHIP_CSRCS += lpc54_rtc_lowerhalf.c
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_LPC54_WWDT),y)
|
||||
CHIP_CSRCS += lpc54_wwdt.c
|
||||
endif
|
||||
|
96
arch/arm/src/lpc54xx/chip/lpc54_rtc.h
Normal file
96
arch/arm/src/lpc54xx/chip/lpc54_rtc.h
Normal file
@ -0,0 +1,96 @@
|
||||
/********************************************************************************************
|
||||
* arch/arm/src/lpc54xx/lpc54_rtc.h
|
||||
*
|
||||
* Copyright (C) 2017 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.
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#ifndef __ARCH_ARM_SRC_LPC54XX_CHIP_LPC54_RTC_H
|
||||
#define __ARCH_ARM_SRC_LPC54XX_CHIP_LPC54_RTC_H
|
||||
|
||||
/********************************************************************************************
|
||||
* Included Files
|
||||
********************************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include "chip/lpc54_memorymap.h"
|
||||
|
||||
/********************************************************************************************
|
||||
* Pre-processor Definitions
|
||||
********************************************************************************************/
|
||||
|
||||
#define LPC54_RTC_NGPREGS 8 /* Nubmer of general purpose registers */
|
||||
|
||||
/* Register offsets *************************************************************************/
|
||||
|
||||
#define LPC54_RTC_CTRL_OFFSET 0x0000 /* RTC control */
|
||||
#define LPC54_RTC_MATCH_OFFSET 0x0004 /* RTC match */
|
||||
#define LPC54_RTC_COUNT_OFFSET 0x0008 /* RTC counter */
|
||||
#define LPC54_RTC_WAKE_OFFSET 0x000c /* High-resolution/wake-up timer control */
|
||||
|
||||
/* General purpose registers */
|
||||
|
||||
#define LPC54_RTC_GPREG_OFFSET(n) (0x0040 + ((n) << 2))
|
||||
|
||||
/* Register addresses ***********************************************************************/
|
||||
|
||||
#define LPC54_RTC_CTRL (LPC54_RTC_BASE + LPC54_RTC_CTRL_OFFSET)
|
||||
#define LPC54_RTC_MATCH (LPC54_RTC_BASE + LPC54_RTC_MATCH_OFFSET)
|
||||
#define LPC54_RTC_COUNT (LPC54_RTC_BASE + LPC54_RTC_COUNT_OFFSET)
|
||||
#define LPC54_RTC_WAKE (LPC54_RTC_BASE + LPC54_RTC_WAKE_OFFSET)
|
||||
|
||||
/* General purpose registers */
|
||||
|
||||
#define LPC54_RTC_GPREG(n) (LPC54_RTC_BASE + LPC54_RTC_GPREG_OFFSET(n))
|
||||
|
||||
/* Register bit definitions *****************************************************************/
|
||||
|
||||
/* RTC control */
|
||||
|
||||
#define RTC_CTRL_SWRESET (1 << 0) /* Bit 0: Software reset control */
|
||||
#define RTC_CTRL_ALARM1HZ (1 << 2) /* Bit 2: RTC 1 Hz timer alarm flag status */
|
||||
#define RTC_CTRL_WAKE1KHZ (1 << 3) /* Bit 3: RTC 1 kHz timer wake-up flag status */
|
||||
#define RTC_CTRL_ALARMDPDEN (1 << 4) /* Bit 4: RTC 1 Hz timer alarm enable for deep power-down */
|
||||
#define RTC_CTRL_WAKEDPDEN (1 << 5) /* Bit 5: RTC 1 kHz timer wake-up enable for deep power-down */
|
||||
#define RTC_CTRL_RTC1KHZEN (1 << 6) /* Bit 6: RTC 1 kHz clock enable */
|
||||
#define RTC_CTRL_RTCEN (1 << 7) /* Bit 7: RTC enable */
|
||||
#define RTC_CTRL_OSCPD (1 << 8) /* Bit 8: RTC oscillator power-down control */
|
||||
|
||||
/* RTC match (32-bit timer match value) */
|
||||
/* RTC counter (32-bit counter value) */
|
||||
|
||||
/* High-resolution/wake-up timer control */
|
||||
|
||||
#define RTC_WAKE_MASK 0xffff /* Bits 0-15: 16 hi-resoution/wake-up timer */
|
||||
|
||||
/* General purpose registers (32-bit value) */
|
||||
|
||||
#endif /* __ARCH_ARM_SRC_LPC54XX_CHIP_LPC54_RTC_H */
|
@ -279,7 +279,7 @@
|
||||
#define LPC54_SYSCON_FROCTRL (LPC54_SYSCON_BASE + LPC54_SYSCON_FROCTRL_OFFSET)
|
||||
#define LPC54_SYSCON_SYSOSCCTRL (LPC54_SYSCON_BASE + LPC54_SYSCON_SYSOSCCTRL_OFFSET)
|
||||
#define LPC54_SYSCON_WDTOSCCTRL (LPC54_SYSCON_BASE + LPC54_SYSCON_WDTOSCCTRL_OFFSET)
|
||||
#define LPC54_SYSCON_RTCOSCCTRL_ (LPC54_SYSCON_BASE + LPC54_SYSCON_RTCOSCCTRL_OFFSET)
|
||||
#define LPC54_SYSCON_RTCOSCCTRL (LPC54_SYSCON_BASE + LPC54_SYSCON_RTCOSCCTRL_OFFSET)
|
||||
#define LPC54_SYSCON_USBPLLCTRL (LPC54_SYSCON_BASE + LPC54_SYSCON_USBPLLCTRL_OFFSET)
|
||||
#define LPC54_SYSCON_USBPLLSTAT (LPC54_SYSCON_BASE + LPC54_SYSCON_USBPLLSTAT_OFFSET)
|
||||
#define LPC54_SYSCON_SYSPLLCTRL (LPC54_SYSCON_BASE + LPC54_SYSCON_SYSPLLCTRL_OFFSET)
|
||||
@ -741,8 +741,8 @@
|
||||
#define SYSCON_WDTOSCCTRL_FREQSEL_SHIFT (5) /* Bits 5-9: Frequency select */
|
||||
#define SYSCON_WDTOSCCTRL_FREQSEL_MASK (0x1f << SYSCON_WDTOSCCTRL_FREQSEL_SHIFT)
|
||||
# define SYSCON_WDTOSCCTRL_FREQSEL_04pMHZ (1 << SYSCON_WDTOSCCTRL_FREQSEL_SHIFT) /* 0.4 MHz */
|
||||
# define SYSCON_WDTOSCCTRL_FREQSEL_0p75MHZ (2 << SYSCON_WDTOSCCTRL_FREQSEL_SHIFT) /* 0.6 MHz */
|
||||
# define SYSCON_WDTOSCCTRL_FREQSEL_0p9MHZ (3 << SYSCON_WDTOSCCTRL_FREQSEL_SHIFT) /* 0.75 MHz */
|
||||
# define SYSCON_WDTOSCCTRL_FREQSEL_0p6MHZ (2 << SYSCON_WDTOSCCTRL_FREQSEL_SHIFT) /* 0.6 MHz */
|
||||
# define SYSCON_WDTOSCCTRL_FREQSEL_0p75MHZ (3 << SYSCON_WDTOSCCTRL_FREQSEL_SHIFT) /* 0.75 MHz */
|
||||
# define SYSCON_WDTOSCCTRL_FREQSEL_0p9MHZ (4 << SYSCON_WDTOSCCTRL_FREQSEL_SHIFT) /* 0.9 MHz */
|
||||
# define SYSCON_WDTOSCCTRL_FREQSEL_1p0MHZ (5 << SYSCON_WDTOSCCTRL_FREQSEL_SHIFT) /* 1.0 MHz */
|
||||
# define SYSCON_WDTOSCCTRL_FREQSEL_1p2MHZ (6 << SYSCON_WDTOSCCTRL_FREQSEL_SHIFT) /* 1.2 MHz */
|
||||
@ -773,7 +773,9 @@
|
||||
# define SYSCON_WDTOSCCTRL_FREQSEL_3p05MHZ (31 << SYSCON_WDTOSCCTRL_FREQSEL_SHIFT) /* 3.05 MHz */
|
||||
|
||||
/* RTC oscillator 32 kHz output control */
|
||||
#define SYSCON_RTCOSCCTRL_
|
||||
|
||||
#define SYSCON_RTCOSCCTRL_EN (1 << 0) /* Bit 0: RTC 32 kHz clock enable */
|
||||
|
||||
/* USB PLL control */
|
||||
#define SYSCON_USBPLLCTRL_
|
||||
/* USB PLL status */
|
||||
|
377
arch/arm/src/lpc54xx/lpc54_rtc.c
Normal file
377
arch/arm/src/lpc54xx/lpc54_rtc.c
Normal file
@ -0,0 +1,377 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/lpc54/lpc54_rtc.c
|
||||
*
|
||||
* Copyright (C) 2017 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 <time.h>
|
||||
#include <errno.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/lpc54_rtc.h"
|
||||
#include "lpc54_enableclk.h"
|
||||
#include "lpc54_rtc.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Configuration ************************************************************/
|
||||
|
||||
#ifdef CONFIG_RTC_HIRES
|
||||
# error "CONFIG_RTC_HIRES is not supported"
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_RTC_ALARM
|
||||
/* Callback to use when the alarm expires */
|
||||
|
||||
static alarmcb_t g_alarmcb;
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/* Variable determines if the RTC has been initialized and enabled. */
|
||||
|
||||
volatile bool g_rtc_enabled = false;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lpc54_rtc_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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_RTC_ALARM
|
||||
static int lpc54_rtc_interrupt(int irq, void *context, FAR void *arg)
|
||||
{
|
||||
uint32_t status = getreg16(LPC54_RTC_CTRL);
|
||||
|
||||
if ((status & RTC_CTRL_ALARM1HZ) != 0 && g_alarmcb != NULL)
|
||||
{
|
||||
/* Clear pending status */
|
||||
|
||||
putreg32(status | RTC_CTRL_ALARM1HZ | RTC_CTRL_WAKE1KHZ, LPC54_RTC_CTRL);
|
||||
|
||||
/* Perform the alarm callback */
|
||||
|
||||
g_alarmcb();
|
||||
g_alarmcb = NULL;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* 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)
|
||||
{
|
||||
uint32_t regval;
|
||||
|
||||
/* Enable the clock to the RTC register interface and peripheral clock. */
|
||||
|
||||
lpc54_rtc_enableclk();
|
||||
|
||||
/* If the 32 kHz output of the RTC is used by another part of the system, enable it
|
||||
* via the EN bit in the RTCOSCCTRL register
|
||||
*/
|
||||
|
||||
putreg32(SYSCON_RTCOSCCTRL_EN, LPC54_SYSCON_RTCOSCCTRL);
|
||||
|
||||
/* The RTC is already running or, perhaps waiting to be enabled if it was never
|
||||
* configured. We will set enable the RTC only if the time if initialized by
|
||||
* higher level logic.
|
||||
*/
|
||||
|
||||
g_rtc_enabled = true;
|
||||
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.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* The current time in seconds
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
time_t up_rtc_time(void)
|
||||
{
|
||||
/* Read and return the 32-bit 1Hz RTC counter value */
|
||||
|
||||
return getreg32(LPC54_RTC_COUNT);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* 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)
|
||||
{
|
||||
irqstate_t flags;
|
||||
uint32_t regval;
|
||||
|
||||
/* Read the Break out the time values */
|
||||
|
||||
flags = enter_critical_section();
|
||||
|
||||
/* Make sure the the RTC is out of reset, but not enabled. */
|
||||
|
||||
regval = getreg32(LPC54_RTC_CTRL);
|
||||
regval &= ~(RTC_CTRL_SWRESET | RTC_CTRL_RTCEN | RTC_CTRL_RTC1KHZEN |
|
||||
RTC_CTRL_OSCPD);
|
||||
putreg32(regval, LPC54_RTC_CTRL);
|
||||
|
||||
/* Then write the time in seconds to the counter register. NOTE that we
|
||||
* can only write to this register when the RTC_EN bit in the RTC CTRL
|
||||
* Register is 0.
|
||||
*/
|
||||
|
||||
putreg32(tp->tv_sec, LPC54_RTC_COUNT);
|
||||
|
||||
/* (Re-)enabled the RTC. The counter increments one second after the
|
||||
* RTC_EN bit is set.
|
||||
*/
|
||||
|
||||
regval |= RTC_CTRL_RTCEN;
|
||||
putreg32(regval, LPC54_RTC_CTRL);
|
||||
|
||||
/* Make sure that magic value is in the general purpose register */
|
||||
|
||||
putreg32(RTC_MAGIC, RTC_MAGIC_REG);
|
||||
|
||||
leave_critical_section(flags);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lpc54_rtc_setalarm
|
||||
*
|
||||
* Description:
|
||||
* Set up an alarm.
|
||||
*
|
||||
* Input Parameters:
|
||||
* tp - The time to set the alarm
|
||||
* callback - The function to call when the alarm expires.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success; a negated errno on failure
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_RTC_ALARM
|
||||
int lpc54_rtc_setalarm(FAR const struct timespec *tp, alarmcb_t callback)
|
||||
{
|
||||
irqstate_t flags;
|
||||
uint32_t regval;
|
||||
int ret = -EBUSY;
|
||||
|
||||
/* Is there already something waiting on the ALARM? */
|
||||
|
||||
flags = enter_critical_section();
|
||||
if (g_alarmcb == NULL)
|
||||
{
|
||||
/* No.. Save the callback function pointer */
|
||||
|
||||
g_alarmcb = callback;
|
||||
|
||||
/* Make sure the the RTC is out of reset. */
|
||||
|
||||
regval = getreg32(LPC54_RTC_CTRL);
|
||||
regval &= ~(RTC_CTRL_SWRESET | RTC_CTRL_ALARMDPDEN | RTC_CTRL_RTC1KHZEN |
|
||||
RTC_CTRL_WAKEDPDEN | RTC_CTRL_OSCPD);
|
||||
putreg32(regval, LPC54_RTC_CTRL);
|
||||
|
||||
/* Make sure that the ALARM interrupt is attached and enabled. */
|
||||
|
||||
irq_attach(LPC54_IRQ_RTC, lpc54_rtc_interrupt, NULL);
|
||||
up_enable_irq(LPC54_IRQ_RTC);
|
||||
|
||||
/* Set the alarm match register */
|
||||
|
||||
putreg32(tp->tv_sec, LPC54_RTC_MATCH);
|
||||
|
||||
/* Enable RTC alarm */
|
||||
|
||||
regval |= RTC_CTRL_ALARMDPDEN;
|
||||
putreg32(regval, LPC54_RTC_CTRL);
|
||||
ret = OK;
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lpc54_rtc_rdalarm
|
||||
*
|
||||
* Description:
|
||||
* Query an alarm configured in hardware.
|
||||
*
|
||||
* Input Parameters:
|
||||
* time - Current alarm setting.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success; a negated errno on failure
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_RTC_ALARM
|
||||
int lpc54_rtc_rdalarm(FAR struct tm *time)
|
||||
{
|
||||
uint32_t match;
|
||||
|
||||
match = getreg32(LPC54_RTC_MATCH);
|
||||
(void)gmtime_r((time_t *)&match, time);
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lpc54_rtc_cancelalarm
|
||||
*
|
||||
* Description:
|
||||
* Cancel a pending alarm alarm
|
||||
*
|
||||
* Input Parameters:
|
||||
* none
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success; a negated errno on failure
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_RTC_ALARM
|
||||
int lpc54_rtc_cancelalarm(void)
|
||||
{
|
||||
irqstate_t flags;
|
||||
uint32_t regval;
|
||||
int ret = -ENODATA;
|
||||
|
||||
flags = enter_critical_section();
|
||||
if (g_alarmcb != NULL)
|
||||
{
|
||||
/* Cancel the global callback function */
|
||||
|
||||
g_alarmcb = NULL;
|
||||
|
||||
/* Disable the Alarm interrupt */
|
||||
|
||||
up_disable_irq(LPC54_IRQ_RTC);
|
||||
|
||||
/* Unset the alarm */
|
||||
|
||||
regval = getreg32(LPC54_RTC_CTRL);
|
||||
regval &= ~(RTC_CTRL_SWRESET | RTC_CTRL_ALARMDPDEN | RTC_CTRL_RTC1KHZEN |
|
||||
RTC_CTRL_WAKEDPDEN | RTC_CTRL_OSCPD);
|
||||
putreg32(regval, LPC54_RTC_CTRL);
|
||||
|
||||
ret = OK;
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
172
arch/arm/src/lpc54xx/lpc54_rtc.h
Normal file
172
arch/arm/src/lpc54xx/lpc54_rtc.h
Normal file
@ -0,0 +1,172 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/lpc54xx/lpc54_rtc.h
|
||||
*
|
||||
* Copyright (C) 2017 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_LPC54XX_LPC54_RTC_H
|
||||
#define __ARCH_ARM_SRC_LPC54XX_LPC54_RTC_H
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include "chip.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define RTC_MAGIC (0xfacefeed)
|
||||
#define RTC_MAGIC_REG LPC54_RTC_GPREG(0)
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#ifdef CONFIG_RTC_ALARM
|
||||
/* The form of an alarm callback */
|
||||
|
||||
typedef CODE void (*alarmcb_t)(void);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
#define EXTERN extern "C"
|
||||
extern "C"
|
||||
{
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lpc54_rtc_setalarm
|
||||
*
|
||||
* Description:
|
||||
* Set up an alarm.
|
||||
*
|
||||
* Input Parameters:
|
||||
* tp - the time to set the alarm
|
||||
* callback - the function to call when the alarm expires.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success; a negated errno on failure
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_RTC_ALARM
|
||||
struct timespec;
|
||||
int lpc54_rtc_setalarm(FAR const struct timespec *tp, alarmcb_t callback);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lpc54_rtc_rdalarm
|
||||
*
|
||||
* Description:
|
||||
* Query an alarm configured in hardware.
|
||||
*
|
||||
* Input Parameters:
|
||||
* time - Current alarm setting.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success; a negated errno on failure
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_RTC_ALARM
|
||||
struct tm;
|
||||
int lpc54_rtc_rdalarm(FAR struct tm *time);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lpc54_rtc_cancelalarm
|
||||
*
|
||||
* Description:
|
||||
* Cancel a pending alarm alarm
|
||||
*
|
||||
* Input Parameters:
|
||||
* none
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success; a negated errno on failure
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_RTC_ALARM
|
||||
int lpc54_rtc_cancelalarm(void);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lpc54_rtc_lowerhalf
|
||||
*
|
||||
* Description:
|
||||
* Instantiate the RTC lower half driver for the LPC54. General usage:
|
||||
*
|
||||
* #include <nuttx/timers/rtc.h>
|
||||
* #include "lpc54_rtc.h"
|
||||
*
|
||||
* struct rtc_lowerhalf_s *lower;
|
||||
* lower = lpc54_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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_RTC_DRIVER
|
||||
struct rtc_lowerhalf_s;
|
||||
FAR struct rtc_lowerhalf_s *lpc54_rtc_lowerhalf(void);
|
||||
#endif
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif /* __ASSEMBLY__ */
|
||||
#endif /* __ARCH_ARM_SRC_LPC54XX_LPC54_RTC_H */
|
660
arch/arm/src/lpc54xx/lpc54_rtc_lowerhalf.c
Normal file
660
arch/arm/src/lpc54xx/lpc54_rtc_lowerhalf.c
Normal file
@ -0,0 +1,660 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/lpc54xx/lpc54_rtc_lowerhalf.c
|
||||
*
|
||||
* Copyright (C) 2017 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 <nuttx/arch.h>
|
||||
#include <nuttx/timers/rtc.h>
|
||||
|
||||
#include "up_arch.h"
|
||||
|
||||
#include "chip/lpc54_rtc.h"
|
||||
#include "lpc54_rtc.h"
|
||||
|
||||
#ifdef CONFIG_RTC_DRIVER
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_RTC_ALARM
|
||||
struct lpc54_cbinfo_s
|
||||
{
|
||||
volatile rtc_alarm_callback_t cb; /* Callback when the alarm expires */
|
||||
volatile FAR void *priv; /* Private argument to accompany callback */
|
||||
};
|
||||
#endif
|
||||
|
||||
/* This is the private type for the RTC state. It must be cast compatible
|
||||
* with struct rtc_lowerhalf_s.
|
||||
*/
|
||||
|
||||
struct lpc54_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 */
|
||||
|
||||
struct lpc54_cbinfo_s cbinfo;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_RTC_PERIODIC
|
||||
/* Periodic wakeup information */
|
||||
|
||||
struct lower_setperiodic_s periodic;
|
||||
#endif
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/* Prototypes for static methods in struct rtc_ops_s */
|
||||
|
||||
static int lpc54_rdtime(FAR struct rtc_lowerhalf_s *lower,
|
||||
FAR struct rtc_time *rtctime);
|
||||
static int lpc54_settime(FAR struct rtc_lowerhalf_s *lower,
|
||||
FAR const struct rtc_time *rtctime);
|
||||
static bool lpc54_havesettime(FAR struct rtc_lowerhalf_s *lower);
|
||||
|
||||
#ifdef CONFIG_RTC_ALARM
|
||||
static int lpc54_setalarm(FAR struct rtc_lowerhalf_s *lower,
|
||||
FAR const struct lower_setalarm_s *alarminfo);
|
||||
static int lpc54_setrelative(FAR struct rtc_lowerhalf_s *lower,
|
||||
FAR const struct lower_setrelative_s *alarminfo);
|
||||
static int lpc54_cancelalarm(FAR struct rtc_lowerhalf_s *lower,
|
||||
int alarmid);
|
||||
static int lpc54_rdalarm(FAR struct rtc_lowerhalf_s *lower,
|
||||
FAR struct lower_rdalarm_s *alarminfo);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_RTC_PERIODIC
|
||||
static int lpc54_setperiodic(FAR struct rtc_lowerhalf_s *lower,
|
||||
FAR const struct lower_setperiodic_s *alarminfo);
|
||||
static int lpc54_cancelperiodic(FAR struct rtc_lowerhalf_s *lower, int id);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
/* LPC54 RTC driver operations */
|
||||
|
||||
static const struct rtc_ops_s g_rtc_ops =
|
||||
{
|
||||
.rdtime = lpc54_rdtime,
|
||||
.settime = lpc54_settime,
|
||||
.havesettime = lpc54_havesettime,
|
||||
#ifdef CONFIG_RTC_ALARM
|
||||
.setalarm = lpc54_setalarm,
|
||||
.setrelative = lpc54_setrelative,
|
||||
.cancelalarm = lpc54_cancelalarm,
|
||||
.rdalarm = lpc54_rdalarm,
|
||||
#endif
|
||||
#ifdef CONFIG_RTC_PERIODIC
|
||||
.setperiodic = lpc54_setperiodic,
|
||||
.cancelperiodic = lpc54_cancelperiodic,
|
||||
#endif
|
||||
#ifdef CONFIG_RTC_IOCTL
|
||||
.ioctl = NULL,
|
||||
#endif
|
||||
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
|
||||
.destroy = NULL,
|
||||
#endif
|
||||
};
|
||||
|
||||
/* LPC54 RTC device state */
|
||||
|
||||
static struct lpc54_lowerhalf_s g_rtc_lowerhalf =
|
||||
{
|
||||
.ops = &g_rtc_ops,
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lpc54_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 lpc54_alarm_callback(void)
|
||||
{
|
||||
FAR struct lpc54_cbinfo_s *cbinfo = &g_rtc_lowerhalf.cbinfo;
|
||||
|
||||
/* 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)cbinfo->cb;
|
||||
FAR void *arg = (FAR void *)cbinfo->priv;
|
||||
|
||||
cbinfo->cb = NULL;
|
||||
cbinfo->priv = NULL;
|
||||
|
||||
/* Perform the callback */
|
||||
|
||||
if (cb != NULL)
|
||||
{
|
||||
cb(arg, 0);
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_RTC_ALARM */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lpc54_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 lpc54_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))
|
||||
{
|
||||
int errcode = get_errno();
|
||||
DEBUGASSERT(errcode > 0);
|
||||
return -errcode;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lpc54_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 lpc54_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: lpc54_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 lpc54_havesettime(FAR struct rtc_lowerhalf_s *lower)
|
||||
{
|
||||
return getreg32(RTC_MAGIC_REG) == RTC_MAGIC;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lpc54_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 lpc54_setalarm(FAR struct rtc_lowerhalf_s *lower,
|
||||
FAR const struct lower_setalarm_s *alarminfo)
|
||||
{
|
||||
FAR struct lpc54_lowerhalf_s *priv;
|
||||
FAR struct lpc54_cbinfo_s *cbinfo;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(lower != NULL && alarminfo != NULL && alarminfo->id == 0);
|
||||
priv = (FAR struct lpc54_lowerhalf_s *)lower;
|
||||
|
||||
ret = nxsem_wait(&priv->devsem);
|
||||
if (ret < 0)
|
||||
{
|
||||
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 */
|
||||
|
||||
cbinfo = &priv->cbinfo;
|
||||
cbinfo->cb = alarminfo->cb;
|
||||
cbinfo->priv = alarminfo->priv;
|
||||
|
||||
/* And set the alarm */
|
||||
|
||||
ret = lpc54_rtc_setalarm(&ts, lpc54_alarm_callback);
|
||||
if (ret < 0)
|
||||
{
|
||||
cbinfo->cb = NULL;
|
||||
cbinfo->priv = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
nxsem_post(&priv->devsem);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lpc54_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 lpc54_setrelative(FAR struct rtc_lowerhalf_s *lower,
|
||||
FAR const struct lower_setrelative_s *alarminfo)
|
||||
{
|
||||
FAR struct lpc54_lowerhalf_s *priv;
|
||||
FAR struct lpc54_cbinfo_s *cbinfo;
|
||||
FAR struct timespec ts;
|
||||
int ret = -EINVAL;
|
||||
|
||||
DEBUGASSERT(lower != NULL && alarminfo != NULL && alarminfo->id == 0);
|
||||
priv = (FAR struct lpc54_lowerhalf_s *)lower;
|
||||
|
||||
if (alarminfo->id == 0 && alarminfo->reltime > 0)
|
||||
{
|
||||
/* Disable pre-emption while we do this so that we don't have to worry
|
||||
* about being suspended and working on an old time.
|
||||
*/
|
||||
|
||||
sched_lock();
|
||||
|
||||
/* Get the current time in seconds */
|
||||
|
||||
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 */
|
||||
|
||||
cbinfo = &priv->cbinfo;
|
||||
cbinfo->cb = alarminfo->cb;
|
||||
cbinfo->priv = alarminfo->priv;
|
||||
|
||||
/* And set the alarm */
|
||||
|
||||
ret = lpc54_rtc_setalarm(&ts, lpc54_alarm_callback);
|
||||
if (ret < 0)
|
||||
{
|
||||
cbinfo->cb = NULL;
|
||||
cbinfo->priv = NULL;
|
||||
}
|
||||
|
||||
sched_unlock();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lpc54_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 lpc54_cancelalarm(FAR struct rtc_lowerhalf_s *lower, int alarmid)
|
||||
{
|
||||
FAR struct lpc54_lowerhalf_s *priv;
|
||||
FAR struct lpc54_cbinfo_s *cbinfo;
|
||||
|
||||
DEBUGASSERT(lower != NULL);
|
||||
DEBUGASSERT(alarmid == 0);
|
||||
priv = (FAR struct lpc54_lowerhalf_s *)lower;
|
||||
|
||||
/* Nullify callback information to reduce window for race conditions */
|
||||
|
||||
cbinfo = &priv->cbinfo;
|
||||
cbinfo->cb = NULL;
|
||||
cbinfo->priv = NULL;
|
||||
|
||||
/* Then cancel the alarm */
|
||||
|
||||
return lpc54_rtc_cancelalarm();
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lpc54_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 lpc54_rdalarm(FAR struct rtc_lowerhalf_s *lower,
|
||||
FAR struct lower_rdalarm_s *alarminfo)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
|
||||
DEBUGASSERT(lower != NULL && alarminfo != NULL && alarminfo->id == 0 &&
|
||||
alarminfo->time != NULL);
|
||||
|
||||
if (alarminfo->id == 0)
|
||||
{
|
||||
ret = lpc54_rtc_rdalarm((FAR struct tm *)alarminfo->time);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lpc54_periodic_callback
|
||||
*
|
||||
* Description:
|
||||
* This is the function that is called from the RTC driver when the periodic
|
||||
* wakeup goes off. It just invokes the upper half drivers callback.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_RTC_PERIODIC
|
||||
static int lpc54_periodic_callback(void)
|
||||
{
|
||||
FAR struct lpc54_lowerhalf_s *lower;
|
||||
struct lower_setperiodic_s *cbinfo;
|
||||
rtc_wakeup_callback_t cb;
|
||||
FAR void *priv;
|
||||
|
||||
lower = (FAR struct lpc54_lowerhalf_s *)&g_rtc_lowerhalf;
|
||||
|
||||
cbinfo = &lower->periodic;
|
||||
cb = (rtc_wakeup_callback_t)cbinfo->cb;
|
||||
priv = (FAR void *)cbinfo->priv;
|
||||
|
||||
/* Perform the callback */
|
||||
|
||||
if (cb != NULL)
|
||||
{
|
||||
cb(priv, 0);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
#endif /* CONFIG_RTC_PERIODIC */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lpc54_setperiodic
|
||||
*
|
||||
* Description:
|
||||
* Set a new periodic wakeup relative to the current time, with a given
|
||||
* period. This function implements the setperiodic() 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 wakeup activity
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned
|
||||
* on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_RTC_PERIODIC
|
||||
static int lpc54_setperiodic(FAR struct rtc_lowerhalf_s *lower,
|
||||
FAR const struct lower_setperiodic_s *alarminfo)
|
||||
{
|
||||
FAR struct lpc54_lowerhalf_s *priv;
|
||||
int ret;
|
||||
|
||||
ASSERT(lower != NULL && alarminfo != NULL);
|
||||
priv = (FAR struct lpc54_lowerhalf_s *)lower;
|
||||
|
||||
ret = nxsem_wait(&priv->devsem);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
memcpy(&priv->periodic, alarminfo, sizeof(struct lower_setperiodic_s));
|
||||
|
||||
ret = lpc54_rtc_setperiodic(&alarminfo->period, lpc54_periodic_callback);
|
||||
|
||||
nxsem_post(&priv->devsem);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lpc54_cancelperiodic
|
||||
*
|
||||
* Description:
|
||||
* Cancel the current periodic wakeup activity. This function implements
|
||||
* the cancelperiodic() method of the RTC driver interface
|
||||
*
|
||||
* Input Parameters:
|
||||
* lower - A reference to RTC lower half driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned
|
||||
* on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_RTC_PERIODIC
|
||||
static int lpc54_cancelperiodic(FAR struct rtc_lowerhalf_s *lower, int id)
|
||||
{
|
||||
FAR struct lpc54_lowerhalf_s *priv;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(lower != NULL);
|
||||
priv = (FAR struct lpc54_lowerhalf_s *)lower;
|
||||
|
||||
DEBUGASSERT(id == 0);
|
||||
|
||||
ret = nxsem_wait(&priv->devsem);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = lpc54_rtc_cancelperiodic();
|
||||
|
||||
nxsem_post(&priv->devsem);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lpc54_rtc_lowerhalf
|
||||
*
|
||||
* Description:
|
||||
* Instantiate the RTC lower half driver for the LPC54. General usage:
|
||||
*
|
||||
* #include <nuttx/timers/rtc.h>
|
||||
* #include "lpc54_rtc.h>
|
||||
*
|
||||
* struct rtc_lowerhalf_s *lower;
|
||||
* lower = lpc54_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 *lpc54_rtc_lowerhalf(void)
|
||||
{
|
||||
nxsem_init(&g_rtc_lowerhalf.devsem, 0, 1);
|
||||
|
||||
return (FAR struct rtc_lowerhalf_s *)&g_rtc_lowerhalf;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_RTC_DRIVER */
|
@ -96,7 +96,7 @@
|
||||
#else /* !CONFIG_STM32_STM32F10XX */
|
||||
|
||||
#if !defined(CONFIG_RTC_MAGIC)
|
||||
# define CONFIG_RTC_MAGIC (0xfacefeee)
|
||||
# define CONFIG_RTC_MAGIC (0xfacefeed)
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_RTC_MAGIC_REG)
|
||||
@ -137,7 +137,7 @@ extern "C"
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: stm32_rtc_irqinitialize
|
||||
*
|
||||
* Description:
|
||||
@ -150,7 +150,7 @@ extern "C"
|
||||
* Returned Value:
|
||||
* Zero (OK) on success; a negated errno on failure
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
int stm32_rtc_irqinitialize(void);
|
||||
|
||||
@ -208,7 +208,7 @@ int stm32_rtc_setdatetime(FAR const struct tm *tp);
|
||||
* Instantiate the RTC lower half driver for the STM32. General usage:
|
||||
*
|
||||
* #include <nuttx/timers/rtc.h>
|
||||
* #include "stm32_rtc.h>
|
||||
* #include "stm32_rtc.h"
|
||||
*
|
||||
* struct rtc_lowerhalf_s *lower;
|
||||
* lower = stm32_rtc_lowerhalf();
|
||||
|
@ -73,6 +73,8 @@ STATUS
|
||||
2017-12-24: Added basic DMA support; brought in the WWDT driver from the
|
||||
LPC43 which has the same peripheral. Neither tested; almost certainly
|
||||
non-functional without some additional investment.
|
||||
2017-12-25: Added an RTC driver. It appears to be functional but has not
|
||||
been well tested.
|
||||
|
||||
There is still no support for the Accelerometer, SPIFI, Ethernet, or USB.
|
||||
There is a complete, but not-yet-functional SD card drirver. There is a
|
||||
@ -344,6 +346,21 @@ Configurations
|
||||
|
||||
CONFIG_NSH_MMCSDSLOTNO=0
|
||||
|
||||
6. The RTC is enabled in this configuration.
|
||||
|
||||
NuttShell (NSH) NuttX-7.23
|
||||
nsh> date
|
||||
Jan 01 00:00:06 1970
|
||||
nsh> date -s "DEC 25 08:00:00 2017"
|
||||
nsh> date
|
||||
Dec 25 08:00:01 2017
|
||||
|
||||
After reset:
|
||||
|
||||
NuttShell (NSH) NuttX-7.23
|
||||
nsh> date
|
||||
Dec 25 08:00:05 2017
|
||||
|
||||
nxwm:
|
||||
|
||||
This is a special configuration setup for the NxWM window manager
|
||||
|
@ -25,6 +25,7 @@ CONFIG_LPC54_EMC_DYNAMIC_CS0=y
|
||||
CONFIG_LPC54_EMC=y
|
||||
CONFIG_LPC54_GPIOIRQ=y
|
||||
CONFIG_LPC54_I2C2_MASTER=y
|
||||
CONFIG_LPC54_RTC=y
|
||||
CONFIG_LPC54_USART0=y
|
||||
CONFIG_MAX_TASKS=16
|
||||
CONFIG_MAX_WDOGPARMS=2
|
||||
@ -43,6 +44,9 @@ CONFIG_RAM_SIZE=163840
|
||||
CONFIG_RAM_START=0x10000000
|
||||
CONFIG_RAW_BINARY=y
|
||||
CONFIG_RR_INTERVAL=200
|
||||
CONFIG_RTC_ALARM=y
|
||||
CONFIG_RTC_DRIVER=y
|
||||
CONFIG_RTC_IOCTL=y
|
||||
CONFIG_SCHED_WAITPID=y
|
||||
CONFIG_SDCLONE_DISABLE=y
|
||||
CONFIG_START_DAY=2
|
||||
|
@ -57,6 +57,11 @@
|
||||
# include "lpc54_sdmmc.h"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_RTC_DRIVER
|
||||
# include <nuttx/timers/rtc.h>
|
||||
# include "lpc54_rtc.h"
|
||||
#endif
|
||||
|
||||
#include "lpcxpresso-lpc54628.h"
|
||||
|
||||
/****************************************************************************
|
||||
@ -81,6 +86,9 @@ int lpc54_bringup(void)
|
||||
{
|
||||
#ifdef HAVE_MMCSD
|
||||
struct sdio_dev_s *sdmmc;
|
||||
#endif
|
||||
#ifdef HAVE_RTC_DRIVER
|
||||
struct rtc_lowerhalf_s *rtc;
|
||||
#endif
|
||||
int ret;
|
||||
|
||||
@ -94,8 +102,30 @@ int lpc54_bringup(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
FAR struct sdio_dev_s *lpc54_sdmmc_initialize(int slotno);
|
||||
#ifdef HAVE_RTC_DRIVER
|
||||
/* Instantiate the STM32 lower-half RTC driver */
|
||||
|
||||
rtc = lpc54_rtc_lowerhalf();
|
||||
if (rtc == NULL)
|
||||
{
|
||||
syslog(LOG_ERR,
|
||||
"ERROR: Failed to instantiate the RTC lower-half driver\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Bind the lower half driver and register the combined RTC driver
|
||||
* as /dev/rtc0
|
||||
*/
|
||||
|
||||
ret = rtc_initialize(0, rtc);
|
||||
if (ret < 0)
|
||||
{
|
||||
syslog(LOG_ERR,
|
||||
"ERROR: Failed to bind/register the RTC driver: %d\n",
|
||||
ret);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_I2CTOOL
|
||||
/* Register I2C drivers on behalf of the I2C tool */
|
||||
|
@ -49,9 +49,10 @@
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define HAVE_I2CTOOL 1
|
||||
#define HAVE_FT5x06 1
|
||||
#define HAVE_MMCSD 1
|
||||
#define HAVE_I2CTOOL 1
|
||||
#define HAVE_FT5x06 1
|
||||
#define HAVE_MMCSD 1
|
||||
#define HAVE_RTC_DRIVER 1
|
||||
|
||||
/* Do we need to register I2C drivers on behalf of the I2C tool? */
|
||||
|
||||
@ -118,6 +119,12 @@
|
||||
# undef HAVE_MMCSD
|
||||
#endif
|
||||
|
||||
/* Check if we can support the RTC driver */
|
||||
|
||||
#if !defined(CONFIG_RTC) || !defined(CONFIG_RTC_DRIVER)
|
||||
# undef HAVE_RTC_DRIVER
|
||||
#endif
|
||||
|
||||
/* Indices into a sparse I2C array. Used with lpc54_i2c_handle() */
|
||||
|
||||
#ifdef CONFIG_LPC54_I2C0_MASTER
|
||||
|
Loading…
Reference in New Issue
Block a user