You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by je...@apache.org on 2021/05/20 05:24:01 UTC

[incubator-nuttx] 04/21: arch: cxd56xx: Fix RTC alarm cancellation process

This is an automated email from the ASF dual-hosted git repository.

jerpelea pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 89fd987a1ae97f189795c56f2b38ad321352603d
Author: SPRESENSE <41...@users.noreply.github.com>
AuthorDate: Wed May 19 17:04:01 2021 +0900

    arch: cxd56xx: Fix RTC alarm cancellation process
    
    There is an issue that the next alarm is expired immediately after
    canceling a RTC alarm. Fixed alarm settings to be completely cleared
    when canceling an RTC alarm.
---
 arch/arm/src/cxd56xx/cxd56_rtc.c | 36 +++++++++++++++++++++++++++++++++++-
 1 file changed, 35 insertions(+), 1 deletion(-)

diff --git a/arch/arm/src/cxd56xx/cxd56_rtc.c b/arch/arm/src/cxd56xx/cxd56_rtc.c
index 58cec8a..410f09f 100644
--- a/arch/arm/src/cxd56xx/cxd56_rtc.c
+++ b/arch/arm/src/cxd56xx/cxd56_rtc.c
@@ -542,6 +542,7 @@ int cxd56_rtc_setalarm(FAR struct alm_setalarm_s *alminfo)
   int ret = -EBUSY;
   int id;
   uint64_t count;
+  uint32_t mask;
 
   ASSERT(alminfo != NULL);
   DEBUGASSERT(RTC_ALARM_LAST > alminfo->as_id);
@@ -565,6 +566,13 @@ int cxd56_rtc_setalarm(FAR struct alm_setalarm_s *alminfo)
 
       count -= g_rtc_save->offset;
 
+      /* clear previsous setting */
+
+      mask = RTCREG_ALM0_ERR_FLAG_MASK | RTCREG_ALM0_FLAG_MASK;
+      mask <<= id;
+
+      putreg32(mask, CXD56_RTC0_ALMCLR);
+
       /* wait until previous alarm request is completed */
 
       while (RTCREG_ASET_BUSY_MASK & getreg32(CXD56_RTC0_SETALMPRECNT(id)));
@@ -609,10 +617,11 @@ int cxd56_rtc_cancelalarm(enum alm_id_e alarmid)
   FAR struct alm_cbinfo_s *cbinfo;
   irqstate_t flags;
   int ret = -ENODATA;
+  uint32_t mask;
 
   DEBUGASSERT(RTC_ALARM_LAST > alarmid);
 
-  /* Set the alarm in hardware and enable interrupts */
+  /* Cancel the alarm in hardware and clear interrupts */
 
   cbinfo = &g_alarmcb[alarmid];
 
@@ -628,6 +637,31 @@ int cxd56_rtc_cancelalarm(enum alm_id_e alarmid)
 
       putreg32(0, CXD56_RTC0_ALMOUTEN(alarmid));
 
+      while (RTCREG_ALM_BUSY_MASK & getreg32(CXD56_RTC0_ALMOUTEN(alarmid)));
+
+      /* wait until previous alarm request is completed */
+
+      while (RTCREG_ASET_BUSY_MASK &
+             getreg32(CXD56_RTC0_SETALMPRECNT(alarmid)));
+
+      /* clear the alarm counter */
+
+      putreg32(0, CXD56_RTC0_SETALMPOSTCNT(alarmid));
+      putreg32(0, CXD56_RTC0_SETALMPRECNT(alarmid));
+
+      while (RTCREG_ASET_BUSY_MASK &
+             getreg32(CXD56_RTC0_SETALMPRECNT(alarmid)));
+
+      /* wait until the interrupt flag is clear */
+
+      mask = RTCREG_ALM0_ERR_FLAG_MASK | RTCREG_ALM0_FLAG_MASK;
+      mask <<= alarmid;
+
+      while (mask & getreg32(CXD56_RTC0_ALMFLG))
+        {
+          putreg32(mask, CXD56_RTC0_ALMCLR);
+        }
+
       spin_unlock_irqrestore(NULL, flags);
 
       ret = OK;