Squashed commit of the following:

arch/z80/src/ez80:  Clean-up RTC driver; get a clean compilation.  Still untested.

    arch/z80/src/ez80:  This brings the RTC to code complete, but does not yet compile.

    arch/z80/src/ez80/ez80_rtc.c:  Bring in badly ported RTC driver from STM32F4.  Little more than naming changing at this point not even ready to attempt comilation

    arch/z80/src/ez80:  Add RTC driver.  Initial commit is just the STMF4 RTC driver with name changes.
This commit is contained in:
Gregory Nutt 2019-06-08 09:58:24 -06:00
parent 1f3958116a
commit f5b890d098
6 changed files with 1048 additions and 2 deletions

View File

@ -12,7 +12,7 @@
* 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
* the documentation and/or otherr 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
@ -99,6 +99,12 @@ void up_initialize(void)
up_irqinitialize();
#ifdef CONFIG_RTC_ALARM
/* Enable RTC alarm interrupts */
ez80_rtc_irqinitialize();
#endif
#if !defined(CONFIG_SUPPRESS_INTERRUPTS) && !defined(CONFIG_SUPPRESS_TIMER_INTS)
/* Initialize the system timer interrupt */

View File

@ -116,6 +116,10 @@ extern "C"
void up_irqinitialize(void);
#ifdef CONFIG_RTC_ALARM
void ez80_rtc_irqinitialize(void);
#endif
#ifdef USE_LOWSERIALINIT
void up_lowserialinit(void);
#endif

View File

@ -30,6 +30,13 @@ config EZ80_SPI
bool "SPI"
default n
config EZ80_RTC
bool "RTC"
default n
select RTC
select RTC_DATETIME
select TIME_EXTENDED
config EZ80_EMAC
bool "Ethernet MAC"
default n
@ -38,7 +45,23 @@ config EZ80_EMAC
---help---
Enables support for ez80 EMAC driver.
endmenu
endmenu # ez80 Peripheral Support
config EZ80_RTC_32KHZ
bool "32KHz crystal present"
default y
depends on EZ80_RTC
---help---
If there is no 32Hz crystal, the RTC will fall back to use the line
frequency.
config EZ80_RTC_LINEFREQ50
bool "50Hz line frequency"
default n
depends on EZ80_RTC && !EZ80_RTC_32KHZ
---help---
If there is no 32Hz crystal, the RTC will fall back to use the line
frequency, either 50 or 60Hz.
# The ZiLOG ZDS-II Windows toolchain is the only toolchain available for
# the ez80.

View File

@ -63,6 +63,10 @@ ifeq ($(CONFIG_EZ80_SPI),y)
CHIP_CSRCS += ez80_spi.c
endif
ifeq ($(CONFIG_EZ80_RTC),y)
CHIP_CSRCS += ez80_rtc.c
endif
ifeq ($(CONFIG_ARCH_CHIP_EZ80F91),y)
ifeq ($(CONFIG_EZ80_EMAC),y)
CHIP_CSRCS += ez80_emac.c

View File

@ -0,0 +1,801 @@
/****************************************************************************
* arch/z80/src/ez80/ez80_rtc.c
*
* Copyright (C) 2019 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 <stdint.h>
#include <stdbool.h>
#include <sched.h>
#include <time.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/arch.h>
#include <nuttx/irq.h>
#include <arch/io.h>
#include "chip.h"
#include "up_arch.h"
#include "ez80_rtc.h"
#include <arch/board/board.h>
#ifdef CONFIG_EZ80_RTC
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Configuration ************************************************************/
#ifndef CONFIG_RTC_DATETIME
# error "CONFIG_RTC_DATETIME must be set to use this driver"
#endif
#ifdef CONFIG_RTC_HIRES
# error "CONFIG_RTC_HIRES must NOT be set with this driver"
#endif
/* Constants ****************************************************************/
#define SYNCHRO_TIMEOUT (0x00020000)
#define INITMODE_TIMEOUT (0x00010000)
/* Proxy definitions to make the same code work for all the EZ80 series ****/
# define EZ80_RCC_XXX EZ80_RCC_BDCR
# define RCC_XXX_YYYRST RCC_BDCR_BDRST
# define RCC_XXX_RTCEN RCC_BDCR_RTCEN
# define RCC_XXX_RTCSEL_MASK RCC_BDCR_RTCSEL_MASK
# define RCC_XXX_RTCSEL_LSE RCC_BDCR_RTCSEL_LSE
# define RCC_XXX_RTCSEL_LSI RCC_BDCR_RTCSEL_LSI
# define RCC_XXX_RTCSEL_HSE RCC_BDCR_RTCSEL_HSE
/* Time conversions */
#define MINUTES_IN_HOUR 60
#define HOURS_IN_DAY 24
#define hours_add(parm_hrs) \
time->tm_hour += parm_hrs;\
if ((HOURS_IN_DAY-1) < (time->tm_hour))\
{\
time->tm_hour = (parm_hrs - HOURS_IN_DAY);\
}
#define RTC_ALRMR_DIS_MASK (RTC_ALRMR_MSK4 | RTC_ALRMR_MSK3 | \
RTC_ALRMR_MSK2 | RTC_ALRMR_MSK1)
#define RTC_ALRMR_DIS_DATE_MASK (RTC_ALRMR_MSK4)
#define RTC_ALRMR_ENABLE (0)
/****************************************************************************
* Private Types
*****************************************************************************/
/* Raw time from the RTC. All are binary. */
struct rtc_timeregs_s
{
uint8_t sec; /* Seconds Range 0-59 */
uint8_t min; /* Minutes Range 0-59 */
uint8_t hrs; /* Hours Range 0-23 */
uint8_t dow; /* Day of week Range 1-7 */
uint8_t dom; /* Day of month Range 1-31 */
uint8_t mon; /* Month Range 1-12 */
uint8_t yr; /* Year Range 0-99 */
uint8_t cen; /* Century Range 0-99 */
};
/* Alarm time from the RTC. All are BCD encoded. */
struct rtc_almregs_s
{
uint8_t sec; /* Seconds */
uint8_t min; /* Minutes */
uint8_t hrs; /* Hours */
uint8_t dow; /* Day of week */
};
#ifdef CONFIG_RTC_ALARM
struct alm_cbinfo_s
{
volatile alm_callback_t ac_cb; /* Client callback function */
volatile FAR void *ac_arg; /* Argument to pass with the callback function */
};
#endif
/****************************************************************************
* Private Data
****************************************************************************/
/* Interrupt handlers attached to the ALARM EXTI */
static xcpt_t g_alarm_callback;
static void *g_callback_arg;
#ifdef CONFIG_RTC_ALARM
/* Callback to use when an EXTI is activated */
static struct alm_cbinfo_s g_alarmcb;
#endif
/****************************************************************************
* Public Data
****************************************************************************/
/* g_rtc_enabled is set true after the RTC has successfully initialized */
volatile bool g_rtc_enabled = false;
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/* Debug */
static void rtc_dumpregs(FAR const char *msg);
static void rtc_dumptime(FAR const struct tm *tp, FAR const char *msg);
/* Register access */
static void rtc_unlock(void);
static void rtc_lock(void);
static void get_raw_time(struct rtc_timeregs_s *rtcregs);
static void set_raw_time(const struct rtc_timeregs_s *rtcregs);
#ifdef CONFIG_RTC_ALARM
static void get_raw_alarm(struct rtc_timeregs_s *almregs);
static void set_raw_alarm(const struct rtc_timeregs_s *almregs);
static int ez80_alarm_interrupt(int irq, void *context, void *arg);
static int ez80_rtc_getalarmdatetime(const struct rtc_almregs_s almregs
FAR struct tm *tp);
#endif
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: rtc_dumpregs
****************************************************************************/
#ifdef CONFIG_DEBUG_RTC_INFO
static void rtc_dumpregs(FAR const char *msg)
{
int rtc_state;
rtcinfo("%s:\n", msg);
rtcinfo(" SEC: %02x\n", inp(EZ80_RTC_SEC));
rtcinfo(" MIN: %02x\n", inp(EZ80_RTC_MIN));
rtcinfo(" HRS: %02x\n", inp(EZ80_RTC_HRS));
rtcinfo(" DOW: %02x\n", inp(EZ80_RTC_DOW));
rtcinfo(" DOM: %02x\n", inp(EZ80_RTC_DOM));
rtcinfo(" MON: %02x\n", inp(EZ80_RTC_MON));
rtcinfo(" YR: %02x\n", inp(EZ80_RTC_YR));
rtcinfo(" CEN: %02x\n", inp(EZ80_RTC_CEN));
rtcinfo(" ASEC: %02x\n", inp(EZ80_RTC_ASEC));
rtcinfo(" AMIN: %02x\n", inp(EZ80_RTC_AMIN));
rtcinfo(" AHRS: %02x\n", inp(EZ80_RTC_AHRS));
rtcinfo(" ADOW: %02x\n", inp(EZ80_RTC_ADOW));
rtcinfo(" ACTRL: %02x\n", inp(EZ80_RTC_ACTRL));
rtcinfo(" CTRL: %02x\n", inp(EZ80_RTC_CTRL));
}
#else
# define rtc_dumpregs(msg)
#endif
/****************************************************************************
* Name: rtc_dumptime
****************************************************************************/
#ifdef CONFIG_DEBUG_RTC_INFO
static void rtc_dumptime(FAR const struct tm *tp, FAR const char *msg)
{
rtcinfo("%s:\n", msg);
rtcinfo(" tm_sec: %08x\n", tp->tm_sec);
rtcinfo(" tm_min: %08x\n", tp->tm_min);
rtcinfo(" tm_hour: %08x\n", tp->tm_hour);
rtcinfo(" tm_mday: %08x\n", tp->tm_mday);
rtcinfo(" tm_mon: %08x\n", tp->tm_mon);
rtcinfo(" tm_year: %08x\n", tp->tm_year);
}
#else
# define rtc_dumptime(tp, msg)
#endif
/****************************************************************************
* Name: rtc_unlock
*
* Description:
* Disable RTC write protection
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
static void rtc_unlock(void)
{
uint8_t regval;
regval = inp(EZ80_RTC_CTRL);
regval |= EZ80_RTC_UNLOCK;
outp(EZ80_RTC_CTRL,regval);
}
/****************************************************************************
* Name: rtc_lock
*
* Description:
* Enable RTC write protection
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
static void rtc_lock(void)
{
uint8_t regval;
regval = inp(EZ80_RTC_CTRL);
regval &= ~EZ80_RTC_UNLOCK;
outp(EZ80_RTC_CTRL,regval);
}
/****************************************************************************
* Name: get_raw_time
*
* Description:
* Read all of the RTC time registers
*
* Input Parameters:
* rtcregs - Location to return the raw RTC time registers
*
* Returned Value:
* None
*
****************************************************************************/
static void get_raw_time(struct rtc_timeregs_s *rtcregs)
{
rtcregs->sec = inp(EZ80_RTC_SEC);
rtcregs->min = inp(EZ80_RTC_MIN);
rtcregs->hrs = inp(EZ80_RTC_HRS);
rtcregs->dow = inp(EZ80_RTC_DOW);
rtcregs->dom = inp(EZ80_RTC_DOM);
rtcregs->mon = inp(EZ80_RTC_MON);
rtcregs->yr = inp(EZ80_RTC_YR);
rtcregs->cen = inp(EZ80_RTC_CEN);
}
/****************************************************************************
* Name: set_raw_time
*
* Description:
* Write all of the RTC time registers
*
* Input Parameters:
* almregs - New RTC register values
*
* Returned Value:
* None
*
****************************************************************************/
static void set_raw_time(const struct rtc_timeregs_s *rtcregs)
{
rtc_unlock();
outp(EZ80_RTC_SEC, rtcregs->sec);
outp(EZ80_RTC_MIN, rtcregs->min);
outp(EZ80_RTC_HRS, rtcregs->hrs);
outp(EZ80_RTC_DOW, rtcregs->dow);
outp(EZ80_RTC_DOM, rtcregs->dom);
outp(EZ80_RTC_MON, rtcregs->mon);
outp(EZ80_RTC_YR, rtcregs->yr);
outp(EZ80_RTC_CEN, rtcregs->cen);
rtc_unlock();
}
/****************************************************************************
* Name: get_raw_alarm
*
* Description:
* Read all of the RTC alarm registers
*
* Input Parameters:
* almregs - Location to return the raw RTC alarm registers
*
* Returned Value:
* None
*
****************************************************************************/
static void get_raw_alarm(struct rtc_timeregs_s *almregs)
{
almregs->sec = inp(EZ80_RTC_ASEC);
almregs->min = inp(EZ80_RTC_AMIN);
almregs->hrs = inp(EZ80_RTC_AHRS);
almregs->dow = inp(EZ80_RTC_ADOW);
}
/****************************************************************************
* Name: set_raw_alarm
*
* Description:
* Write all of the RTC alarm registers
*
* Input Parameters:
* almregs - New RTC register values
*
* Returned Value:
* None
*
****************************************************************************/
static void set_raw_alarm(const struct rtc_timeregs_s *almregs)
{
rtc_unlock();
outp(EZ80_RTC_ASEC, almregs->sec);
outp(EZ80_RTC_AMIN, almregs->min);
outp(EZ80_RTC_AHRS, almregs->hrs);
outp(EZ80_RTC_ADOW, almregs->dow);
rtc_unlock();
}
/****************************************************************************
* Name: ez80_alarm_interrupt
*
* Description:
* RTC ALARM interrupt service routine through the EXTI line
*
* 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 ez80_alarm_interrupt(int irq, void *context, void *arg)
{
uint_t regval;
/* Verify that the alarm iinterrupt is pending */
regval = inp(EZ80_RTC_CTRL);
if ((regval & EZ80_RTC_ALARM) != 0)
{
/* Disable the alarm and disable the alarm interrupt */
rtc_unlock();
outp(EZ80_RTC_ACTRL, 0);
regval = inp(EZ80_RTC_CTRL);
regval &= ~EZ80_RTC_INTEN;
outp(EZ80_RTC_CTRL, regval);
rtc_lock();
up_irq_disble(EZ80_RTC_IRQ);
/* Perform the alarm callback */
cb = g_alarmcb.ac_cb;
cb_arg = (FAR void *)g_alarmcb.ac_arg;
g_alarmcb.ac_cb = NULL;
g_alarmcb.ac_arg = NULL;
cb(cb_arg);
}
return OK;
}
#endif
/****************************************************************************
* Name: ez80_rtc_getalarmdatetime
*
* Description:
* Get the current date and time for a RTC alarm.
*
* Input Parameters:
* reg - RTC alarm register
* tp - The location to return the high resolution time value.
*
* Returned Value:
* Zero (OK) on success; a negated errno on failure
*
****************************************************************************/
#ifdef CONFIG_RTC_ALARM
static int ez80_rtc_getalarmdatetime(const struct rtc_almregs_s almregs
FAR struct tm *tp)
{
uint32_t data, tmp;
DEBUGASSERT(tp != NULL);
/* Sample the data time register. */
data = inp(reg);
/* Convert the RTC time to fields in struct tm format. All of the EZ80
* ranges of values correspond between struct tm and the time register.
*/
tp->tm_sec = xxx(tmp);
tp->tm_min = xxx(tmp);
tp->tm_hour = xxx(tmp);
tp->tm_mday = xxx(tmp);
return OK;
}
#endif
/****************************************************************************
* 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)
{
uint8_t regval;
/* Some boards do not have the external 32khz oscillator installed,
* for those boards we must fallback to the crummy line frequency
* clock source.
*/
regval = 0;
#ifndef CONFIG_EZ80_RTC_32KHZ
#ifdef EZ80_RTC_LINEFREQ50
/* Use the internal 50/60 Hz clock as the input to the RTC block */
regval |= (EZ80_RTC_FREQSEL | EZ80_RTC_CLKSEL);
#else
regval |= EZ80_RTC_CLKSEL;
#endif
#endif
outp(EZ80_RTC_CTRL, regval);
rtc_dumpregs("After Initialization");
g_rtc_enabled = true;
return OK;
}
/************************************************************************************
* Name: ez80_rtc_irqinitialize
*
* Description:
* Initialize IRQs for RTC, not possible during up_rtc_initialize because
* up_irqinitialize is called later.
*
* Input Parameters:
* None
*
* Returned Value:
* Zero (OK) on success; a negated errno on failure
*
************************************************************************************/
#ifdef CONFIG_RTC_ALARM
int ez80_rtc_irqinitialize(void)
{
DEBUGVERIFY(irq_attach(EZ80_RTC_IRQ, ez80_alarm_interrupt, NULL));
}
#endif
/****************************************************************************
* Name: up_rtc_getdatetime
*
* Description:
* Get the current date and time from the date/time RTC. This is used to
* replace the system timer. It is only used by the RTOS during
* initialization to set up the system time when CONFIG_RTC and
* CONFIG_RTC_DATETIME are selected (and CONFIG_RTC_HIRES is not).
*
* Input Parameters:
* tp - The location to return the high resolution time value.
*
* Returned Value:
* Zero (OK) on success; a negated errno on failure
*
****************************************************************************/
int up_rtc_getdatetime(FAR struct tm *tp)
{
struct rtc_timeregs_s timeregs;
struct rtc_timeregs_s tmpregs;
/* Sample the data time registers. There is a race condition here... ,
* for example, we sample the time just before midnight on December 31,
* the date couldbe wrong because the day rolled over while were
* sampling. Thus loop for checking wrap here is needed.
*/
do
{
get_raw_time(&tmpregs);
get_raw_time(&timeregs);
}
while (tmpregs.min != timeregs.min &&
tmpregs.hrs != timeregs.hrs &&
tmpregs.dom != timeregs.dom &&
tmpregs.mon != timeregs.mon &&
tmpregs.yr != timeregs.yr &&
tmpregs.cen != timeregs.cen);
rtc_dumpregs("Reading Time");
/* Convert the RTC time to fields in struct tm format. All of the EZ80
* ranges of values correspond between struct tm and the time register.
*/
tp->tm_sec = timeregs.sec;
tp->tm_min = timeregs.min;
tp->tm_hour = timeregs.min;
tp->tm_mday = timeregs.dom;
tp->tm_mon = timeregs.dom - 1; /* Range is 0-11 */
/* Years since 1900 */
tp->tm_year = (uint16_t)timeregs.cen * 100 + (uint16_t)timeregs.yr - 1900;
rtc_dumptime((FAR const struct tm *)tp, "Returning");
return OK;
}
/****************************************************************************
* Name: ez80_rtc_setdatetime
*
* Description:
* Set the RTC to the provided time. RTC implementations which provide
* up_rtc_getdatetime() (CONFIG_RTC_DATETIME is selected) should provide
* this function.
*
* Input Parameters:
* tp - the time to use
*
* Returned Value:
* Zero (OK) on success; a negated errno on failure
*
****************************************************************************/
int ez80_rtc_setdatetime(FAR const struct tm *tp)
{
struct rtc_timeregs_s timeregs;
uint16_t year;
uint16_t cen;
timeregs.sec = tp->tm_sec;
timeregs.min = tp->tm_min;
timeregs.min = tp->tm_hour;
timeregs.dom = tp->tm_mday;
timeregs.dom = tp->tm_mon + 1; /* Range is 1-12 */
/* Years AD */
year = tp->tm_year + 1900;
cen = year * 100;
timeregs.cen = cen;
timeregs.yr = year - 100 * cen;
set_raw_time(&timeregs);
rtc_dumpregs("New time setting");
return OK;
}
/****************************************************************************
* 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)
{
FAR struct tm newtime;
/* Break out the time values (not that the time is set only to units of
* seconds)
*/
(void)gmtime_r(&tp->tv_sec, &newtime);
return ez80_rtc_setdatetime(&newtime);
}
/****************************************************************************
* Name: ez80_rtc_setalarm
*
* Description:
* Set an alarm to an absolute time using associated hardware.
*
* Input Parameters:
* alminfo - Information about the alarm configuration.
*
* Returned Value:
* Zero (OK) on success; a negated errno on failure
*
****************************************************************************/
#ifdef CONFIG_RTC_ALARM
int ez80_rtc_setalarm(FAR struct alm_setalarm_s *alminfo)
{
struct rtc_almregs_s almregs;
int ret = -EINVAL;
DEBUGASSERT(alminfo != NULL);
rtc_dumptime(&alminfo->as_time, "New alarm time");
/* Save the callback info */
g_alarmcb.ac_cb = alminfo->as_cb;
g_alarmcb.ac_arg = alminfo->as_arg;
/* Set the alarm time */
almregs.sec = alminfo->as_time.sec;
almregs.min = alminfo->as_time.min;
almregs.hrs = alminfo->as_time.hrs;
almregs.dow = alminfo->as_time.dow;
set_raw_alarm(&alarmregs);
/* Enable the alarm */
rtc_unlock();
outp(EZ80_RTC_ACTRL, EZ80_RTX_AALL);
regval = inp(EZ80_RTC_CTRL);
regval |= ~EZ80_RTC_INTEN;
outp(EZ80_RTC_CTRL, regval);
rtc_lock();
rtc_dumpregs("Set Alarm");
/* Enable the alarm interrupt at the interrupt controller */
up_irq_enable(EZ80_RTC_IRQ);
return OK;
}
#endif
/****************************************************************************
* Name: ez80_rtc_cancelalarm
*
* Description:
* Cancel an alarm.
*
* Input Parameters:
* alarmid - Identifies the alarm to be cancelled
*
* Returned Value:
* Zero (OK) on success; a negated errno on failure
*
****************************************************************************/
#ifdef CONFIG_RTC_ALARM
int ez80_rtc_cancelalarm(void)
{
/* Cancel the global callback function */
g_alarmcb[alarmid].ac_cb = NULL;
g_alarmcb[alarmid].ac_arg = NULL;
/* Disable RTC alarm and and the alarm interrupt */
rtc_unlock();
outp(EZ80_RTC_ACTRL, 0);
regval = inp(EZ80_RTC_CTRL);
regval &= ~EZ80_RTC_INTEN;
outp(EZ80_RTC_CTRL, regval);
rtc_lock();
up_irq_disable(EZ80_RTC_IRQ);
return OK;
}
#endif
/****************************************************************************
* Name: ez80_rtc_rdalarm
*
* Description:
* Return the current alarm setting.
*
* Input Parameters:
* almtime - Location to retun the current alarm ime.
*
* Returned Value:
* Zero (OK) on success; a negated errno on failure
*
****************************************************************************/
#ifdef CONFIG_RTC_ALARM
int ez80_rtc_rdalarm(FAR struct rtc_time *almtime)
struct rtc_almregs_s almregs;
int ret = -EINVAL;
DEBUGASSERT(almtime != NULL);
/* Read the alarm time from the RTC */
get_raw_alarm(&almregs);
/* A return that as struct tm */
return ez80_rtc_getalarmdatetime(&almregs, almtime);
}
#endif
#endif /* CONFIG_EZ80_RTC */

View File

@ -0,0 +1,208 @@
/****************************************************************************
* arch/z80/src/ez80/ez80_rtc.h
*
* Copyright (C) 2019 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_EZ80_SRC_EZ80_EZ80_RTC_H
#define __ARCH_EZ80_SRC_EZ80_EZ80_RTC_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <time.h>
#include "chip.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* RTC registers ************************************************************/
/* Provided in z80F91.h */
/* RTC register bit definitions *********************************************/
/* ACTRL register */
#define EZ80_RTC_ASECEN (1 << 0) /* Bit 0: Enable seconds alarm */
#define EZ80_RTC_AMINEN (1 << 1) /* Bit 1: Enable minutes alarm */
#define EZ80_RTC_AHRSEN (1 << 2) /* Bit 4: Enable hours alarm */
#define EZ80_RTC_ADOWEN (1 << 3) /* Bit 3: Enable day-of-week alarm */
#define EZ80_RTX_AALL 0x0f /* All times */
/* CTRL register */
#define EZ80_RTC_UNLOCK (1 << 0) /* Bit 0: RTC registers unlocked */
#define EZ80_RTC_SLPWAKE (1 << 1) /* Bit 1: Alarm sleep recovery */
#define EZ80_RTC_FREQSEL (1 << 3) /* Bit 3: Power line is 50Hz */
#define EZ80_RTC_CLKSEL (1 << 4) /* Bit 4: Clock source is power line */
#define EZ80_RTC_BCDEN (1 << 5) /* Bit 5: BCD encoded time */
#define EZ80_RTC_INTEN (1 << 6) /* Bit 6: Alarm interrupt enabled */
#define EZ80_RTC_ALARM (1 << 7) /* Bit 7: Alarm interrupt active */
/****************************************************************************
* Public Types
****************************************************************************/
#ifndef __ASSEMBLY__
typedef CODE void (*alm_callback_t)(FAR void *arg);
/* Structure used to pass parameters to set an alarm */
struct alm_setalarm_s
{
struct tm as_time; /* Alarm expiration time */
alm_callback_t as_cb; /* Callback (if non-NULL) */
FAR void *as_arg; /* Argument for callback */
};
/****************************************************************************
* Public Data
****************************************************************************/
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: ez80_rtc_setdatetime
*
* Description:
* Set the RTC to the provided time. RTC implementations which provide
* up_rtc_getdatetime() (CONFIG_RTC_DATETIME is selected) should provide
* this function.
*
* Input Parameters:
* tp - the time to use
*
* Returned Value:
* Zero (OK) on success; a negated errno on failure
*
****************************************************************************/
struct tm;
int ez80_rtc_setdatetime(FAR const struct tm *tp);
/****************************************************************************
* Name: ez80_rtc_lowerhalf
*
* Description:
* Instantiate the RTC lower half driver for the EZ80. General usage:
*
* #include <nuttx/timers/rtc.h>
* #include "ez80_rtc.h"
*
* struct rtc_lowerhalf_s *lower;
* lower = ez80_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 *ez80_rtc_lowerhalf(void);
#endif
#ifdef CONFIG_RTC_ALARM
/****************************************************************************
* Name: ez80_rtc_setalarm
*
* Description:
* Set an alarm to an absolute time using associated hardware.
*
* Input Parameters:
* alminfo - Information about the alarm configuration.
*
* Returned Value:
* Zero (OK) on success; a negated errno on failure
*
****************************************************************************/
int ez80_rtc_setalarm(FAR struct alm_setalarm_s *alminfo);
/****************************************************************************
* Name: ez80_rtc_rdalarm
*
* Description:
* Return the current alarm setting.
*
* Input Parameters:
* almtime - Location to retun the current alarm ime.
*
* Returned Value:
* Zero (OK) on success; a negated errno on failure
*
****************************************************************************/
int ez80_rtc_rdalarm(FAR struct rtc_time *almtime);
/****************************************************************************
* Name: ez80_rtc_cancelalarm
*
* Description:
* Cancel an alarm.
*
* Input Parameters:
* None
*
* Returned Value:
* Zero (OK) on success; a negated errno on failure
*
****************************************************************************/
int ez80_rtc_cancelalarm(void);
#endif /* CONFIG_RTC_ALARM */
#endif /* __ARCH_EZ80_SRC_EZ80_RTC_H */