nuttx/arch/arm/src/stm32/stm32_exti_alarm.c

139 lines
4.2 KiB
C
Raw Normal View History

/****************************************************************************
* arch/arm/src/stm32/stm32_exti_alarm.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 <nuttx/irq.h>
#include <nuttx/arch.h>
#include <stdint.h>
#include <stdbool.h>
#include <errno.h>
#include <arch/irq.h>
#include "arm_arch.h"
#include "chip.h"
#include "stm32_gpio.h"
#include "stm32_exti.h"
/****************************************************************************
* Private Data
****************************************************************************/
/* Interrupt handlers attached to the ALARM EXTI */
static xcpt_t g_alarm_callback;
static void *g_callback_arg;
2015-10-04 22:59:08 +02:00
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: stm32_exti_alarm_isr
*
* Description:
* EXTI ALARM interrupt service routine/dispatcher
*
****************************************************************************/
static int stm32_exti_alarm_isr(int irq, void *context, FAR void *arg)
{
int ret = OK;
/* Clear the pending EXTI interrupt */
putreg32(EXTI_RTC_ALARM, STM32_EXTI_PR);
/* And dispatch the interrupt to the handler */
if (g_alarm_callback)
{
ret = g_alarm_callback(irq, context, g_callback_arg);
}
return ret;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: stm32_exti_alarm
*
* Description:
* Sets/clears EXTI alarm interrupt.
*
* Input Parameters:
Merged in juniskane/nuttx_stm32l4/stm32l4_rtc_fixes_pr (pull request #509) STM32L4 small fixes to RTC * STM32L4 RTC: init mode was never exited because nested locking in rtc_synchwait() disabled backup domain access * STM32L4 RTC: use backup register magic value instead of INITS bit The INITS (bit 4) of RTC_ISR register cannot be used to reliably detect backup domain reset. This is because we can operate our device without ever initializing the year field in the RTC calendar if our application does not care about correct date being set. Hardware also clears the bit when RTC date is set back to year 2000: nsh> date -s "Jan 01 00:00:00 2001" rtc_dumptime: Setting time: rtc_dumptime: tm: 2001-01-01 00:00:00 rtc_dumpregs: New time setting: rtc_dumpregs: TR: 00000000 rtc_dumpregs: DR: 00012101 rtc_dumpregs: CR: 00000000 rtc_dumpregs: ISR: 00000037 ... nsh> date -s "Jan 01 00:00:00 2000" rtc_dumptime: Setting time: rtc_dumptime: tm: 2000-01-01 00:00:00 rtc_dumpregs: New time setting: rtc_dumpregs: TR: 00000000 rtc_dumpregs: DR: 0000c101 rtc_dumpregs: CR: 00000000 rtc_dumpregs: ISR: 00000027 <--- Bit 4 went missing! ... This patch allows us to do: stm32l4_pmstop(true); /* Stop mode disables HSE/HSI/PLL and wake happens with default system * clock. So reconfigure clocks early on Stop mode return. */ stm32l4_clockconfig(); without stm32l4_clockconfig() doing spurious and harmful backup domain reset in rcc_resetbkp(). * STM32L4 RTC: put back the SSR race condition workaround ST has confirmed that the issue has not been fixed, and that it applies to STM32L4 too (was not in errata sheets due to documentation bug) See discussion: https://community.st.com/thread/43710-issue-with-rtc-maximum-time-resolution * STM32F4, STM32L4, STM32F7 RTC: add more CONFIG_RTC_NALARMS > 1 to reduce code size * STM32L4: rename stm32l4_rtcc.c to stm32l4_rtc.c to better match STM32F7 Cosmetic changes to comments * STM32, STM32L4, STM32F7 RTC: stray comment and typos in chip/stm32_rtcc.h * STM32L4 RTC: change maximum alarm time from 24h to one month Approved-by: Gregory Nutt <gnutt@nuttx.org>
2017-10-13 14:32:33 +02:00
* - rising/falling edge: enables interrupt on rising/falling edge
* - event: generate event when set
* - func: when non-NULL, generate interrupt
* - arg: Argument passed to the interrupt callback
*
* Returned Value:
* Zero (OK) on success; a negated errno value on failure indicating the
* nature of the failure.
*
****************************************************************************/
int stm32_exti_alarm(bool risingedge, bool fallingedge, bool event,
xcpt_t func, void *arg)
{
g_alarm_callback = func;
g_callback_arg = arg;
/* Install external interrupt handlers (if not already attached) */
if (func)
{
irq_attach(STM32_IRQ_RTCALRM, stm32_exti_alarm_isr, NULL);
up_enable_irq(STM32_IRQ_RTCALRM);
}
else
{
up_disable_irq(STM32_IRQ_RTCALRM);
}
/* Configure rising/falling edges */
modifyreg32(STM32_EXTI_RTSR,
risingedge ? 0 : EXTI_RTC_ALARM,
risingedge ? EXTI_RTC_ALARM : 0);
modifyreg32(STM32_EXTI_FTSR,
fallingedge ? 0 : EXTI_RTC_ALARM,
fallingedge ? EXTI_RTC_ALARM : 0);
/* Enable Events and Interrupts */
modifyreg32(STM32_EXTI_EMR,
event ? 0 : EXTI_RTC_ALARM,
event ? EXTI_RTC_ALARM : 0);
modifyreg32(STM32_EXTI_IMR,
func ? 0 : EXTI_RTC_ALARM,
func ? EXTI_RTC_ALARM : 0);
return OK;
}