arch/nrf53: add RTC support
This commit is contained in:
parent
6a2152aa44
commit
f9f41bbd95
@ -106,6 +106,10 @@ config NRF53_PWM
|
|||||||
bool
|
bool
|
||||||
default n
|
default n
|
||||||
|
|
||||||
|
config NRF53_RTC
|
||||||
|
bool
|
||||||
|
default n
|
||||||
|
|
||||||
menu "NRF53 Peripheral Selection"
|
menu "NRF53 Peripheral Selection"
|
||||||
|
|
||||||
config NRF53_GPIOTE
|
config NRF53_GPIOTE
|
||||||
@ -159,6 +163,17 @@ config NRF53_SAADC
|
|||||||
bool "SAADC"
|
bool "SAADC"
|
||||||
default n
|
default n
|
||||||
|
|
||||||
|
config NRF53_RTC0
|
||||||
|
bool "RTC0"
|
||||||
|
select NRF53_RTC
|
||||||
|
depends on !NRF53_SOFTDEVICE_CONTROLLER
|
||||||
|
default n
|
||||||
|
|
||||||
|
config NRF53_RTC1
|
||||||
|
bool "RTC1"
|
||||||
|
select NRF53_RTC
|
||||||
|
default n
|
||||||
|
|
||||||
endmenu # NRF53 Peripheral Selection
|
endmenu # NRF53 Peripheral Selection
|
||||||
|
|
||||||
menu "Clock Configuration"
|
menu "Clock Configuration"
|
||||||
|
@ -70,6 +70,10 @@ ifeq ($(CONFIG_NRF53_SAADC),y)
|
|||||||
CHIP_CSRCS += nrf53_adc.c
|
CHIP_CSRCS += nrf53_adc.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_NRF53_RTC),y)
|
||||||
|
CHIP_CSRCS += nrf53_rtc.c
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(CONFIG_PM),y)
|
ifeq ($(CONFIG_PM),y)
|
||||||
CHIP_CSRCS += nrf53_pminitialize.c
|
CHIP_CSRCS += nrf53_pminitialize.c
|
||||||
endif
|
endif
|
||||||
|
801
arch/arm/src/nrf53/nrf53_rtc.c
Normal file
801
arch/arm/src/nrf53/nrf53_rtc.c
Normal file
@ -0,0 +1,801 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* arch/arm/src/nrf53/nrf53_rtc.c
|
||||||
|
*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership. The
|
||||||
|
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the
|
||||||
|
* License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Included Files
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
#include <nuttx/arch.h>
|
||||||
|
#include <nuttx/irq.h>
|
||||||
|
|
||||||
|
#include "arm_internal.h"
|
||||||
|
#include "hardware/nrf53_rtc.h"
|
||||||
|
|
||||||
|
#include "nrf53_rtc.h"
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Pre-processor Definitions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Types
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
struct nrf53_rtc_priv_s
|
||||||
|
{
|
||||||
|
struct nrf53_rtc_ops_s *ops;
|
||||||
|
uint32_t base;
|
||||||
|
uint32_t irq;
|
||||||
|
uint8_t chan;
|
||||||
|
bool inuse;
|
||||||
|
};
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Function Prototypes
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/* RTC registers access *****************************************************/
|
||||||
|
|
||||||
|
static uint32_t nrf53_rtc_getreg(struct nrf53_rtc_dev_s *dev,
|
||||||
|
uint32_t offset);
|
||||||
|
static void nrf53_rtc_putreg(struct nrf53_rtc_dev_s *dev,
|
||||||
|
uint32_t offset,
|
||||||
|
uint32_t value);
|
||||||
|
|
||||||
|
/* RTC helpers **************************************************************/
|
||||||
|
|
||||||
|
static uint32_t nrf53_rtc_irq2reg(struct nrf53_rtc_dev_s *dev,
|
||||||
|
uint8_t s);
|
||||||
|
static uint32_t nrf53_rtc_evt2reg(struct nrf53_rtc_dev_s *dev,
|
||||||
|
uint8_t evt);
|
||||||
|
|
||||||
|
/* RTC operations ***********************************************************/
|
||||||
|
|
||||||
|
static int nrf53_rtc_start(struct nrf53_rtc_dev_s *dev);
|
||||||
|
static int nrf53_rtc_stop(struct nrf53_rtc_dev_s *dev);
|
||||||
|
static int nrf53_rtc_clear(struct nrf53_rtc_dev_s *dev);
|
||||||
|
static int nrf53_rtc_trgovrflw(struct nrf53_rtc_dev_s *dev);
|
||||||
|
static int nrf53_rtc_getcounter(struct nrf53_rtc_dev_s *dev,
|
||||||
|
uint32_t *cc);
|
||||||
|
static int nrf53_rtc_setcc(struct nrf53_rtc_dev_s *dev, uint8_t i,
|
||||||
|
uint32_t cc);
|
||||||
|
static int nrf53_rtc_getcc(struct nrf53_rtc_dev_s *dev, uint8_t i,
|
||||||
|
uint32_t *cc);
|
||||||
|
static int nrf53_rtc_setpre(struct nrf53_rtc_dev_s *dev, uint16_t pre);
|
||||||
|
static int nrf53_rtc_setisr(struct nrf53_rtc_dev_s *dev, xcpt_t handler,
|
||||||
|
void * arg);
|
||||||
|
static int nrf53_rtc_enableint(struct nrf53_rtc_dev_s *dev, uint8_t s);
|
||||||
|
static int nrf53_rtc_disableint(struct nrf53_rtc_dev_s *dev, uint8_t s);
|
||||||
|
static int nrf53_rtc_checkint(struct nrf53_rtc_dev_s *dev, uint8_t s);
|
||||||
|
static int nrf53_rtc_ackint(struct nrf53_rtc_dev_s *dev, uint8_t s);
|
||||||
|
static int nrf53_rtc_enableevt(struct nrf53_rtc_dev_s *dev, uint8_t evt);
|
||||||
|
static int nrf53_rtc_disableevt(struct nrf53_rtc_dev_s *dev,
|
||||||
|
uint8_t evt);
|
||||||
|
static uint32_t nrf53_rtc_getbase(struct nrf53_rtc_dev_s *dev);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Data
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/* NRF53 RTC ops */
|
||||||
|
|
||||||
|
struct nrf53_rtc_ops_s nrf53_rtc_ops =
|
||||||
|
{
|
||||||
|
.start = nrf53_rtc_start,
|
||||||
|
.stop = nrf53_rtc_stop,
|
||||||
|
.clear = nrf53_rtc_clear,
|
||||||
|
.trgovrflw = nrf53_rtc_trgovrflw,
|
||||||
|
.getcounter = nrf53_rtc_getcounter,
|
||||||
|
.setcc = nrf53_rtc_setcc,
|
||||||
|
.getcc = nrf53_rtc_getcc,
|
||||||
|
.setpre = nrf53_rtc_setpre,
|
||||||
|
.setisr = nrf53_rtc_setisr,
|
||||||
|
.enableint = nrf53_rtc_enableint,
|
||||||
|
.disableint = nrf53_rtc_disableint,
|
||||||
|
.checkint = nrf53_rtc_checkint,
|
||||||
|
.ackint = nrf53_rtc_ackint,
|
||||||
|
.enableevt = nrf53_rtc_enableevt,
|
||||||
|
.disableevt = nrf53_rtc_disableevt,
|
||||||
|
.getbase = nrf53_rtc_getbase,
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef CONFIG_NRF53_RTC0
|
||||||
|
/* RTC0 */
|
||||||
|
|
||||||
|
struct nrf53_rtc_priv_s g_nrf53_rtc0_priv =
|
||||||
|
{
|
||||||
|
.ops = &nrf53_rtc_ops,
|
||||||
|
.base = NRF53_RTC0_BASE,
|
||||||
|
.irq = NRF53_IRQ_RTC0,
|
||||||
|
.chan = 4,
|
||||||
|
.inuse = false,
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_NRF53_RTC1
|
||||||
|
/* RTC1 */
|
||||||
|
|
||||||
|
struct nrf53_rtc_priv_s g_nrf53_rtc1_priv =
|
||||||
|
{
|
||||||
|
.ops = &nrf53_rtc_ops,
|
||||||
|
.base = NRF53_RTC1_BASE,
|
||||||
|
.irq = NRF53_IRQ_RTC1,
|
||||||
|
.chan = 4,
|
||||||
|
.inuse = false,
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nrf53_rtc_getreg
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Get a 32-bit register value by offset
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static uint32_t nrf53_rtc_getreg(struct nrf53_rtc_dev_s *dev,
|
||||||
|
uint32_t offset)
|
||||||
|
{
|
||||||
|
DEBUGASSERT(dev);
|
||||||
|
|
||||||
|
return getreg32(((struct nrf53_rtc_priv_s *)dev)->base + offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nrf53_rtc_putreg
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Put a 32-bit register value by offset
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static void nrf53_rtc_putreg(struct nrf53_rtc_dev_s *dev,
|
||||||
|
uint32_t offset,
|
||||||
|
uint32_t value)
|
||||||
|
{
|
||||||
|
DEBUGASSERT(dev);
|
||||||
|
|
||||||
|
putreg32(value, ((struct nrf53_rtc_priv_s *)dev)->base + offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nrf53_rtc_irq2reg
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Get the value of the interrupt register corresponding to the given
|
||||||
|
* interrupt source
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static uint32_t nrf53_rtc_irq2reg(struct nrf53_rtc_dev_s *dev, uint8_t s)
|
||||||
|
{
|
||||||
|
uint32_t regval = 0;
|
||||||
|
|
||||||
|
switch (s)
|
||||||
|
{
|
||||||
|
case NRF53_RTC_EVT_TICK:
|
||||||
|
{
|
||||||
|
regval = RTC_INT_TICK;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case NRF53_RTC_EVT_OVRFLW:
|
||||||
|
{
|
||||||
|
regval = RTC_INT_OVRFLW;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case NRF53_RTC_EVT_COMPARE0:
|
||||||
|
{
|
||||||
|
regval = RTC_INT_COMPARE(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case NRF53_RTC_EVT_COMPARE1:
|
||||||
|
{
|
||||||
|
regval = RTC_INT_COMPARE(1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case NRF53_RTC_EVT_COMPARE2:
|
||||||
|
{
|
||||||
|
regval = RTC_INT_COMPARE(2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case NRF53_RTC_EVT_COMPARE3:
|
||||||
|
{
|
||||||
|
regval = RTC_INT_COMPARE(3);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
rtcerr("ERROR: unsupported IRQ source %d\n", s);
|
||||||
|
regval = 0;
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
errout:
|
||||||
|
return regval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nrf53_rtc_evt2reg
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Get the offset of the event register corresponding to the given event
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static uint32_t nrf53_rtc_evt2reg(struct nrf53_rtc_dev_s *dev,
|
||||||
|
uint8_t evt)
|
||||||
|
{
|
||||||
|
uint32_t regval;
|
||||||
|
|
||||||
|
switch (evt)
|
||||||
|
{
|
||||||
|
case NRF53_RTC_EVT_TICK:
|
||||||
|
{
|
||||||
|
regval = RTC_EVTEN_TICK;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case NRF53_RTC_EVT_OVRFLW:
|
||||||
|
{
|
||||||
|
regval = RTC_EVTEN_OVRFLW;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case NRF53_RTC_EVT_COMPARE0:
|
||||||
|
{
|
||||||
|
regval = RTC_EVTEN_COMPARE(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case NRF53_RTC_EVT_COMPARE1:
|
||||||
|
{
|
||||||
|
regval = RTC_EVTEN_COMPARE(1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case NRF53_RTC_EVT_COMPARE2:
|
||||||
|
{
|
||||||
|
regval = RTC_EVTEN_COMPARE(2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case NRF53_RTC_EVT_COMPARE3:
|
||||||
|
{
|
||||||
|
regval = RTC_EVTEN_COMPARE(3);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
rtcerr("ERROR: unsupported EVENT %d\n", evt);
|
||||||
|
regval = 0;
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
errout:
|
||||||
|
return regval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nrf53_rtc_start
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int nrf53_rtc_start(struct nrf53_rtc_dev_s *dev)
|
||||||
|
{
|
||||||
|
DEBUGASSERT(dev);
|
||||||
|
|
||||||
|
nrf53_rtc_putreg(dev, NRF53_RTC_TASKS_START_OFFSET, RTC_TASKS_START);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nrf53_rtc_stop
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int nrf53_rtc_stop(struct nrf53_rtc_dev_s *dev)
|
||||||
|
{
|
||||||
|
DEBUGASSERT(dev);
|
||||||
|
|
||||||
|
nrf53_rtc_putreg(dev, NRF53_RTC_TASKS_STOP_OFFSET, RTC_TASKS_STOP);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nrf53_rtc_clear
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int nrf53_rtc_clear(struct nrf53_rtc_dev_s *dev)
|
||||||
|
{
|
||||||
|
DEBUGASSERT(dev);
|
||||||
|
|
||||||
|
nrf53_rtc_putreg(dev, NRF53_RTC_TASKS_CLEAR_OFFSET, RTC_TASKS_CLEAR);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nrf53_rtc_trgovrflw
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int nrf53_rtc_trgovrflw(struct nrf53_rtc_dev_s *dev)
|
||||||
|
{
|
||||||
|
DEBUGASSERT(dev);
|
||||||
|
|
||||||
|
nrf53_rtc_putreg(dev, NRF53_RTC_TASKS_TRIGOVRFLW_OFFSET,
|
||||||
|
RTC_TASKS_TRIGOVRFLW);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int nrf53_rtc_getcounter(struct nrf53_rtc_dev_s *dev,
|
||||||
|
uint32_t *ctr)
|
||||||
|
{
|
||||||
|
DEBUGASSERT(dev);
|
||||||
|
DEBUGASSERT(ctr);
|
||||||
|
|
||||||
|
*ctr = nrf53_rtc_getreg(dev, NRF53_RTC_COUNTER_OFFSET);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nrf53_rtc_setcc
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int nrf53_rtc_setcc(struct nrf53_rtc_dev_s *dev, uint8_t i,
|
||||||
|
uint32_t cc)
|
||||||
|
{
|
||||||
|
struct nrf53_rtc_priv_s *rtc = NULL;
|
||||||
|
int ret = OK;
|
||||||
|
|
||||||
|
DEBUGASSERT(dev);
|
||||||
|
|
||||||
|
rtc = (struct nrf53_rtc_priv_s *)dev;
|
||||||
|
|
||||||
|
/* Is the channel supported? */
|
||||||
|
|
||||||
|
if (i > rtc->chan)
|
||||||
|
{
|
||||||
|
rtcerr("ERROR: unsupported RTCER channel %d\n", i);
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
|
||||||
|
nrf53_rtc_putreg(dev, NRF53_RTC_CC_OFFSET(i), cc);
|
||||||
|
|
||||||
|
errout:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nrf53_rtc_getcc
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int nrf53_rtc_getcc(struct nrf53_rtc_dev_s *dev, uint8_t i,
|
||||||
|
uint32_t *cc)
|
||||||
|
{
|
||||||
|
struct nrf53_rtc_priv_s *rtc = NULL;
|
||||||
|
int ret = OK;
|
||||||
|
|
||||||
|
DEBUGASSERT(dev);
|
||||||
|
DEBUGASSERT(cc);
|
||||||
|
|
||||||
|
rtc = (struct nrf53_rtc_priv_s *)dev;
|
||||||
|
|
||||||
|
/* Is the channel supported? */
|
||||||
|
|
||||||
|
if (i > rtc->chan)
|
||||||
|
{
|
||||||
|
rtcerr("ERROR: unsupported RTCER channel %d\n", i);
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
|
||||||
|
*cc = nrf53_rtc_getreg(dev, NRF53_RTC_CC_OFFSET(i));
|
||||||
|
|
||||||
|
errout:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nrf53_rtc_setpre
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int nrf53_rtc_setpre(struct nrf53_rtc_dev_s *dev, uint16_t pre)
|
||||||
|
{
|
||||||
|
int ret = OK;
|
||||||
|
|
||||||
|
DEBUGASSERT(dev);
|
||||||
|
|
||||||
|
if (pre > RTC_PRESCALER_MAX)
|
||||||
|
{
|
||||||
|
rtcerr("ERROR: unsupported RTC prescaler %d\n", pre);
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
|
||||||
|
nrf53_rtc_putreg(dev, NRF53_RTC_PRESCALER_OFFSET, pre);
|
||||||
|
|
||||||
|
errout:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nrf53_rtc_setisr
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int nrf53_rtc_setisr(struct nrf53_rtc_dev_s *dev, xcpt_t handler,
|
||||||
|
void *arg)
|
||||||
|
{
|
||||||
|
struct nrf53_rtc_priv_s *rtc = NULL;
|
||||||
|
int ret = OK;
|
||||||
|
|
||||||
|
DEBUGASSERT(dev);
|
||||||
|
|
||||||
|
rtc = (struct nrf53_rtc_priv_s *)dev;
|
||||||
|
|
||||||
|
/* Disable interrupt when callback is removed */
|
||||||
|
|
||||||
|
if (!handler)
|
||||||
|
{
|
||||||
|
up_disable_irq(rtc->irq);
|
||||||
|
irq_detach(rtc->irq);
|
||||||
|
ret = OK;
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Otherwise set callback and enable interrupt */
|
||||||
|
|
||||||
|
irq_attach(rtc->irq, handler, arg);
|
||||||
|
up_enable_irq(rtc->irq);
|
||||||
|
|
||||||
|
errout:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nrf53_rtc_enableint
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int nrf53_rtc_enableint(struct nrf53_rtc_dev_s *dev, uint8_t s)
|
||||||
|
{
|
||||||
|
uint32_t regval = 0;
|
||||||
|
int ret = OK;
|
||||||
|
|
||||||
|
DEBUGASSERT(dev);
|
||||||
|
|
||||||
|
/* Get register value for given interrupt source */
|
||||||
|
|
||||||
|
regval = nrf53_rtc_irq2reg(dev, s);
|
||||||
|
if (regval == 0)
|
||||||
|
{
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
|
||||||
|
nrf53_rtc_putreg(dev, NRF53_RTC_INTENSET_OFFSET, regval);
|
||||||
|
|
||||||
|
errout:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nrf53_rtc_disableint
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int nrf53_rtc_disableint(struct nrf53_rtc_dev_s *dev, uint8_t s)
|
||||||
|
{
|
||||||
|
uint32_t regval = 0;
|
||||||
|
int ret = OK;
|
||||||
|
|
||||||
|
DEBUGASSERT(dev);
|
||||||
|
|
||||||
|
/* Get register value for given interrupt source */
|
||||||
|
|
||||||
|
regval = nrf53_rtc_irq2reg(dev, s);
|
||||||
|
if (regval == 0)
|
||||||
|
{
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
|
||||||
|
nrf53_rtc_putreg(dev, NRF53_RTC_INTENCLR_OFFSET, regval);
|
||||||
|
|
||||||
|
errout:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nrf53_rtc_checkint
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int nrf53_rtc_checkint(struct nrf53_rtc_dev_s *dev, uint8_t s)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
DEBUGASSERT(dev);
|
||||||
|
|
||||||
|
switch (s)
|
||||||
|
{
|
||||||
|
case NRF53_RTC_EVT_TICK:
|
||||||
|
{
|
||||||
|
ret = nrf53_rtc_getreg(dev, NRF53_RTC_EVENTS_TICK_OFFSET);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case NRF53_RTC_EVT_OVRFLW:
|
||||||
|
{
|
||||||
|
ret = nrf53_rtc_getreg(dev, NRF53_RTC_EVENTS_OVRFLW_OFFSET);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case NRF53_RTC_EVT_COMPARE0:
|
||||||
|
{
|
||||||
|
ret = nrf53_rtc_getreg(dev, NRF53_RTC_EVENTS_COMPARE_OFFSET(0));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case NRF53_RTC_EVT_COMPARE1:
|
||||||
|
{
|
||||||
|
ret = nrf53_rtc_getreg(dev, NRF53_RTC_EVENTS_COMPARE_OFFSET(1));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case NRF53_RTC_EVT_COMPARE2:
|
||||||
|
{
|
||||||
|
ret = nrf53_rtc_getreg(dev, NRF53_RTC_EVENTS_COMPARE_OFFSET(2));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case NRF53_RTC_EVT_COMPARE3:
|
||||||
|
{
|
||||||
|
ret = nrf53_rtc_getreg(dev, NRF53_RTC_EVENTS_COMPARE_OFFSET(3));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
rtcerr("ERROR: unsupported IRQ source %d\n", s);
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
errout:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nrf53_rtc_ackint
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int nrf53_rtc_ackint(struct nrf53_rtc_dev_s *dev, uint8_t s)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
DEBUGASSERT(dev);
|
||||||
|
|
||||||
|
switch (s)
|
||||||
|
{
|
||||||
|
case NRF53_RTC_EVT_TICK:
|
||||||
|
{
|
||||||
|
nrf53_rtc_putreg(dev, NRF53_RTC_EVENTS_TICK_OFFSET, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case NRF53_RTC_EVT_OVRFLW:
|
||||||
|
{
|
||||||
|
nrf53_rtc_putreg(dev, NRF53_RTC_EVENTS_OVRFLW_OFFSET, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case NRF53_RTC_EVT_COMPARE0:
|
||||||
|
{
|
||||||
|
nrf53_rtc_putreg(dev, NRF53_RTC_EVENTS_COMPARE_OFFSET(0), 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case NRF53_RTC_EVT_COMPARE1:
|
||||||
|
{
|
||||||
|
nrf53_rtc_putreg(dev, NRF53_RTC_EVENTS_COMPARE_OFFSET(1), 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case NRF53_RTC_EVT_COMPARE2:
|
||||||
|
{
|
||||||
|
nrf53_rtc_putreg(dev, NRF53_RTC_EVENTS_COMPARE_OFFSET(2), 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case NRF53_RTC_EVT_COMPARE3:
|
||||||
|
{
|
||||||
|
nrf53_rtc_putreg(dev, NRF53_RTC_EVENTS_COMPARE_OFFSET(3), 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
rtcerr("ERROR: unsupported IRQ source %d\n", s);
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
errout:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nrf53_rtc_enableevt
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int nrf53_rtc_enableevt(struct nrf53_rtc_dev_s *dev, uint8_t evt)
|
||||||
|
{
|
||||||
|
uint32_t regval = 0;
|
||||||
|
int ret = OK;
|
||||||
|
|
||||||
|
DEBUGASSERT(dev);
|
||||||
|
|
||||||
|
/* Get register value for given event */
|
||||||
|
|
||||||
|
regval = nrf53_rtc_evt2reg(dev, evt);
|
||||||
|
if (regval == 0)
|
||||||
|
{
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
|
||||||
|
nrf53_rtc_putreg(dev, NRF53_RTC_EVTENSET_OFFSET, regval);
|
||||||
|
|
||||||
|
errout:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nrf53_rtc_disableevt
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static int nrf53_rtc_disableevt(struct nrf53_rtc_dev_s *dev, uint8_t evt)
|
||||||
|
{
|
||||||
|
uint32_t regval = 0;
|
||||||
|
int ret = OK;
|
||||||
|
|
||||||
|
DEBUGASSERT(dev);
|
||||||
|
|
||||||
|
/* Get register value for given event */
|
||||||
|
|
||||||
|
regval = nrf53_rtc_evt2reg(dev, evt);
|
||||||
|
if (regval == 0)
|
||||||
|
{
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
|
||||||
|
nrf53_rtc_putreg(dev, NRF53_RTC_EVTENCLR_OFFSET, regval);
|
||||||
|
|
||||||
|
errout:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nrf53_rtc_getbase
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static uint32_t nrf53_rtc_getbase(struct nrf53_rtc_dev_s *dev)
|
||||||
|
{
|
||||||
|
struct nrf53_rtc_priv_s *rtc = (struct nrf53_rtc_priv_s *)dev;
|
||||||
|
DEBUGASSERT(dev);
|
||||||
|
|
||||||
|
return rtc->base;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nrf53_rtc_init
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Initialize RTC device
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
struct nrf53_rtc_dev_s *nrf53_rtc_init(int rtc)
|
||||||
|
{
|
||||||
|
struct nrf53_rtc_priv_s *priv = NULL;
|
||||||
|
|
||||||
|
/* Get RTC instance */
|
||||||
|
|
||||||
|
switch (rtc)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_NRF53_RTC0
|
||||||
|
case 0:
|
||||||
|
{
|
||||||
|
priv = &g_nrf53_rtc0_priv;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_NRF53_RTC1
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
priv = &g_nrf53_rtc1_priv;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
rtcerr("ERROR: unsupported RTC %d\n", rtc);
|
||||||
|
goto errout;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->inuse != false)
|
||||||
|
{
|
||||||
|
/* RTC already in use */
|
||||||
|
|
||||||
|
priv = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
errout:
|
||||||
|
return (struct nrf53_rtc_dev_s *)priv;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nrf53_rtc_deinit
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Deinit RTC device
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int nrf53_rtc_deinit(struct nrf53_rtc_dev_s *dev)
|
||||||
|
{
|
||||||
|
struct nrf53_rtc_priv_s *rtc = NULL;
|
||||||
|
|
||||||
|
DEBUGASSERT(dev);
|
||||||
|
|
||||||
|
rtc = (struct nrf53_rtc_priv_s *)dev;
|
||||||
|
|
||||||
|
rtc->inuse = false;
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
139
arch/arm/src/nrf53/nrf53_rtc.h
Normal file
139
arch/arm/src/nrf53/nrf53_rtc.h
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* arch/arm/src/nrf53/nrf53_rtc.h
|
||||||
|
*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership. The
|
||||||
|
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the
|
||||||
|
* License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __ARCH_ARM_SRC_NRF53_NRF53_RTC_H
|
||||||
|
#define __ARCH_ARM_SRC_NRF53_NRF53_RTC_H
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Included Files
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Pre-processor Definitions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/* Helpers ******************************************************************/
|
||||||
|
|
||||||
|
#define NRF53_RTC_START(d) ((d)->ops->start(d))
|
||||||
|
#define NRF53_RTC_STOP(d) ((d)->ops->stop(d))
|
||||||
|
#define NRF53_RTC_CLEAR(d) ((d)->ops->clear(d))
|
||||||
|
#define NRF53_RTC_TRGOVRFLW(d) ((d)->ops->trgovrflw(d))
|
||||||
|
#define NRF53_RTC_GETCOUNTER(d, c) ((d)->ops->getcounter(d, c))
|
||||||
|
#define NRF53_RTC_SETCC(d, i, cc) ((d)->ops->setcc(d, i, cc))
|
||||||
|
#define NRF53_RTC_GETCC(d, i, cc) ((d)->ops->setcc(d, i, cc))
|
||||||
|
#define NRF53_RTC_SETPRE(d, pre) ((d)->ops->setpre(d, pre))
|
||||||
|
#define NRF53_RTC_SETISR(d, hnd, arg) ((d)->ops->setisr(d, hnd, arg))
|
||||||
|
#define NRF53_RTC_ENABLEINT(d, s) ((d)->ops->enableint(d, s))
|
||||||
|
#define NRF53_RTC_DISABLEINT(d, s) ((d)->ops->disableint(d, s))
|
||||||
|
#define NRF53_RTC_CHECKINT(d, s) ((d)->ops->checkint(d, s))
|
||||||
|
#define NRF53_RTC_ACKINT(d, s) ((d)->ops->ackint(d, s))
|
||||||
|
#define NRF53_RTC_ENABLEEVT(d, s) ((d)->ops->enableevt(d, s))
|
||||||
|
#define NRF53_RTC_DISABLEEVT(d, s) ((d)->ops->disableevt(d, s))
|
||||||
|
#define NRF53_RTC_GETBASE(d) ((d)->ops->getbase(d))
|
||||||
|
|
||||||
|
/* These are defined for direct access to registers, which is needed in some
|
||||||
|
* critical parts where access speed is important
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define NRF53_RTC_GETCOUNTER_REG(base) (getreg32(base + NRF53_RTC_COUNTER_OFFSET))
|
||||||
|
#define NRF53_RTC_SETCC_REG(base, ch, cc) (putreg32(cc, base + NRF53_RTC_CC_OFFSET(ch)))
|
||||||
|
#define NRF53_RTC_GETCC_REG(base, ch) (getreg32(base + NRF53_RTC_CC_OFFSET(ch)))
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Types
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/* RTC CC index */
|
||||||
|
|
||||||
|
enum nrf53_rtc_cc_e
|
||||||
|
{
|
||||||
|
NRF53_RTC_CC0 = 0,
|
||||||
|
NRF53_RTC_CC1 = 1,
|
||||||
|
NRF53_RTC_CC2 = 2,
|
||||||
|
NRF53_RTC_CC3 = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* RTC Interrupts/Events */
|
||||||
|
|
||||||
|
enum nrf53_rtc_evt_e
|
||||||
|
{
|
||||||
|
NRF53_RTC_EVT_TICK = 0,
|
||||||
|
NRF53_RTC_EVT_OVRFLW = 1,
|
||||||
|
NRF53_RTC_EVT_COMPARE0 = 2,
|
||||||
|
NRF53_RTC_EVT_COMPARE1 = 3,
|
||||||
|
NRF53_RTC_EVT_COMPARE2 = 4,
|
||||||
|
NRF53_RTC_EVT_COMPARE3 = 5,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* NRF53 RTC device */
|
||||||
|
|
||||||
|
struct nrf53_rtc_dev_s
|
||||||
|
{
|
||||||
|
struct nrf53_rtc_ops_s *ops;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* NRF53 RTC ops */
|
||||||
|
|
||||||
|
struct nrf53_rtc_ops_s
|
||||||
|
{
|
||||||
|
/* RTC tasks */
|
||||||
|
|
||||||
|
int (*start)(struct nrf53_rtc_dev_s *dev);
|
||||||
|
int (*stop)(struct nrf53_rtc_dev_s *dev);
|
||||||
|
int (*clear)(struct nrf53_rtc_dev_s *dev);
|
||||||
|
int (*trgovrflw)(struct nrf53_rtc_dev_s *dev);
|
||||||
|
|
||||||
|
/* RTC operations */
|
||||||
|
|
||||||
|
int (*getcounter)(struct nrf53_rtc_dev_s *dev, uint32_t *cc);
|
||||||
|
int (*setcc)(struct nrf53_rtc_dev_s *dev, uint8_t i, uint32_t cc);
|
||||||
|
int (*getcc)(struct nrf53_rtc_dev_s *dev, uint8_t i, uint32_t *cc);
|
||||||
|
int (*setpre)(struct nrf53_rtc_dev_s *dev, uint16_t pre);
|
||||||
|
|
||||||
|
/* RTC interrupts */
|
||||||
|
|
||||||
|
int (*setisr)(struct nrf53_rtc_dev_s *dev, xcpt_t handler, void *arg);
|
||||||
|
int (*enableint)(struct nrf53_rtc_dev_s *dev, uint8_t source);
|
||||||
|
int (*disableint)(struct nrf53_rtc_dev_s *dev, uint8_t source);
|
||||||
|
int (*checkint)(struct nrf53_rtc_dev_s *dev, uint8_t source);
|
||||||
|
int (*ackint)(struct nrf53_rtc_dev_s *dev, uint8_t source);
|
||||||
|
|
||||||
|
/* RTC events */
|
||||||
|
|
||||||
|
int (*enableevt)(struct nrf53_rtc_dev_s *dev, uint8_t evt);
|
||||||
|
int (*disableevt)(struct nrf53_rtc_dev_s *dev, uint8_t evt);
|
||||||
|
|
||||||
|
/* Utility */
|
||||||
|
|
||||||
|
uint32_t (*getbase)(struct nrf53_rtc_dev_s *dev);
|
||||||
|
};
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Function Prototypes
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
struct nrf53_rtc_dev_s *nrf53_rtc_init(int rtc);
|
||||||
|
int nrf53_rtc_deinit(struct nrf53_rtc_dev_s *dev);
|
||||||
|
|
||||||
|
#endif /* __ARCH_ARM_SRC_NRF53_NRF53_RTC_H */
|
Loading…
Reference in New Issue
Block a user