Fix STM32 RTC Alarm interrupts. They were being enabled BEFORE the interrupt system was being initialized.

This commit is contained in:
Gregory Nutt 2016-07-23 10:36:06 -06:00
parent 14de4b99f8
commit 5a0f9fcb7d
5 changed files with 106 additions and 58 deletions

View File

@ -52,22 +52,6 @@
#include "group/group.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/

View File

@ -136,6 +136,7 @@ struct alm_cbinfo_s
/* Callback to use when an EXTI is activated */
static struct alm_cbinfo_s g_alarmcb[RTC_ALARM_LAST];
static bool g_alarm_enabled; /* True: Alarm interrupts are enabled */
#endif
/****************************************************************************
@ -157,6 +158,7 @@ static int rtchw_set_alrmar(rtc_alarmreg_t alarmreg);
static int rtchw_check_alrbwf(void);
static int rtchw_set_alrmbr(rtc_alarmreg_t alarmreg);
#endif
static void alarm_enable(void);
#endif
/****************************************************************************
@ -811,6 +813,46 @@ rtchw_set_alrmbr_exit:
}
#endif
/****************************************************************************
* Name: alarm_enable
*
* Description:
* Enable ALARM interrupts
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
#ifdef CONFIG_RTC_ALARM
static void alarm_enable(void)
{
/* Is the alarm already enabled? */
if (!g_alarm_enabled)
{
/* Configure RTC interrupt to catch alarm interrupts. All RTC
* interrupts are connected to the EXTI controller. To enable the
* RTC Alarm interrupt, the following sequence is required:
*
* 1. Configure and enable the EXTI Line 17 RTC ALARM in interrupt
* mode and select the rising edge sensitivity.
* For STM32F4xx
* EXTI line 21 RTC Tamper & Timestamp
* EXTI line 22 RTC Wakeup
* 2. Configure and enable the RTC_Alarm IRQ channel in the NVIC.
* 3. Configure the RTC to generate RTC alarms (Alarm A or Alarm B).
*/
stm32_exti_alarm(true, false, true, stm32_rtc_alarm_handler);
g_alarm_enabled = true;
}
}
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
@ -1010,25 +1052,7 @@ int up_rtc_initialize(void)
return -ETIMEDOUT;
}
#ifdef CONFIG_RTC_ALARM
/* Configure RTC interrupt to catch alarm interrupts. All RTC interrupts
* are connected to the EXTI controller. To enable the RTC Alarm
* interrupt, the following sequence is required:
*
* 1. Configure and enable the EXTI Line 17 RTC ALARM in interrupt mode
* and select the rising edge sensitivity.
* For STM32F4xx
* EXTI line 21 RTC Tamper & Timestamp
* EXTI line 22 RTC Wakeup
* 2. Configure and enable the RTC_Alarm IRQ channel in the NVIC.
* 3. Configure the RTC to generate RTC alarms (Alarm A or Alarm B).
*/
stm32_exti_alarm(true, false, true, stm32_rtc_alarm_handler);
rtc_dumpregs("After InitExtiAlarm");
#else
rtc_dumpregs("After Initialization");
#endif
g_rtc_enabled = true;
return OK;
@ -1321,6 +1345,10 @@ int stm32_rtc_setalarm(FAR struct alm_setalarm_s *alminfo)
ASSERT(alminfo != NULL);
DEBUGASSERT(RTC_ALARM_LAST > alminfo->as_id);
/* Make sure the the alarm interrupt is enabled at the NVIC */
alarm_enable();
/* REVISIT: Should test that the time is in the future */
rtc_dumptime(&alminfo->as_time, "New alarm time");
@ -1335,7 +1363,7 @@ int stm32_rtc_setalarm(FAR struct alm_setalarm_s *alminfo)
(rtc_bin2bcd(alminfo->as_time.tm_hour) << RTC_ALRMR_HU_SHIFT) |
(rtc_bin2bcd(alminfo->as_time.tm_mday) << RTC_ALRMR_DU_SHIFT);
/* Set the alarm in hardware and enable interrupts */
/* Set the alarm in hardware and enable interrupts from the RTC */
switch (alminfo->as_id)
{

View File

@ -247,7 +247,7 @@ static int stm32l4_irqinfo(int irq, uintptr_t *regaddr, uint32_t *bit,
if (irq >= STM32L4_IRQ_FIRST)
{
n = irq - STM32L4_IRQ_FIRST;
n = irq - STM32L4_IRQ_FIRST;
*regaddr = NVIC_IRQ_ENABLE(n) + offset;
*bit = (uint32_t)1 << (n & 0x1f);
}

View File

@ -134,6 +134,7 @@ struct alm_cbinfo_s
/* Callback to use when an EXTI is activated */
static struct alm_cbinfo_s g_alarmcb[RTC_ALARM_LAST];
static bool g_alarm_enabled; /* True: Alarm interrupts are enabled */
#endif
/************************************************************************************
@ -153,6 +154,7 @@ static int rtchw_check_alrawf(void);
static int rtchw_check_alrbwf(void);
static int rtchw_set_alrmar(rtc_alarmreg_t alarmreg);
static int rtchw_set_alrmbr(rtc_alarmreg_t alarmreg);
static void alarm_enable(void);
#endif
/************************************************************************************
@ -766,6 +768,45 @@ rtchw_set_alrmbr_exit:
}
#endif
/****************************************************************************
* Name: alarm_enable
*
* Description:
* Enable ALARM interrupts
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
#ifdef CONFIG_RTC_ALARM
static void alarm_enable(void)
{
/* Is the alarm already enabled? */
if (!g_alarm_enabled)
{
/* Configure RTC interrupt to catch alarm interrupts. All RTC
* interrupts are connected to the EXTI controller. To enable the
* RTC Alarm interrupt, the following sequence is required:
*
* 1. Configure and enable the EXTI Line 18 in interrupt mode and
* select the rising edge sensitivity.
* EXTI line 19 RTC Tamper or Timestamp or CSS_LSE
* EXTI line 20 RTC Wakeup
* 2. Configure and enable the RTC_Alarm IRQ channel in the NVIC.
* 3. Configure the RTC to generate RTC alarms (Alarm A or Alarm B).
*/
stm32l4_exti_alarm(true, false, true, stm32l4_rtc_alarm_handler);
g_alarm_enabled = true;
}
}
#endif
/************************************************************************************
* Public Functions
************************************************************************************/
@ -949,22 +990,6 @@ int up_rtc_initialize(void)
(void)stm32l4_pwr_enablebkp(false);
}
#ifdef CONFIG_RTC_ALARM
/* Configure RTC interrupt to catch alarm interrupts. All RTC interrupts are
* connected to the EXTI controller. To enable the RTC Alarm interrupt, the
* following sequence is required:
*
* 1. Configure and enable the EXTI Line 18 in interrupt mode and select the
* rising edge sensitivity.
* EXTI line 19 RTC Tamper or Timestamp or CSS_LSE
* EXTI line 20 RTC Wakeup
* 2. Configure and enable the RTC_Alarm IRQ channel in the NVIC.
* 3. Configure the RTC to generate RTC alarms (Alarm A or Alarm B).
*/
stm32l4_exti_alarm(true, false, true, stm32l4_rtc_alarm_handler);
#endif
g_rtc_enabled = true;
rtc_dumpregs("After Initialization");
@ -1241,6 +1266,10 @@ int stm32l4_rtc_setalarm(FAR struct alm_setalarm_s *alminfo)
ASSERT(alminfo != NULL);
DEBUGASSERT(RTC_ALARM_LAST > alminfo->as_id);
/* Make sure the the alarm interrupt is enabled at the NVIC */
alarm_enable();
/* REVISIT: Should test that the time is in the future */
rtc_dumptime(&alminfo->as_time, "New alarm time");
@ -1249,7 +1278,7 @@ int stm32l4_rtc_setalarm(FAR struct alm_setalarm_s *alminfo)
alarmreg = rtc_reg_alrmr_bin2bcd(&alminfo->as_time);
/* Set the alarm in hardware and enable interrupts */
/* Set the alarm in hardware and enable interrupts from the RTC */
switch (alminfo->as_id)
{

View File

@ -254,7 +254,8 @@ int board_app_initialize(uintptr_t arg)
lower = stm32_rtc_lowerhalf();
if (!lower)
{
serr("ERROR: Failed to instantiate the RTC lower-half driver\n");
syslog(LOG_ERR,
"ERROR: Failed to instantiate the RTC lower-half driver\n");
return -ENOMEM;
}
else
@ -266,7 +267,9 @@ int board_app_initialize(uintptr_t arg)
ret = rtc_initialize(0, lower);
if (ret < 0)
{
serr("ERROR: Failed to bind/register the RTC driver: %d\n", ret);
syslog(LOG_ERR,
"ERROR: Failed to bind/register the RTC driver: %d\n",
ret);
return ret;
}
}
@ -289,7 +292,8 @@ int board_app_initialize(uintptr_t arg)
mtd = m25p_initialize(spi);
if (!mtd)
{
syslog(LOG_ERR, "ERROR: Failed to bind SPI port 0 to the SPI FLASH driver\n");
syslog(LOG_ERR,
"ERROR: Failed to bind SPI port 0 to the SPI FLASH driver\n");
return -ENODEV;
}
#warning "Now what are we going to do with this SPI FLASH driver?"
@ -303,7 +307,8 @@ int board_app_initialize(uintptr_t arg)
sdio = sdio_initialize(CONFIG_NSH_MMCSDSLOTNO);
if (!sdio)
{
syslog(LOG_ERR, "ERROR: Failed to initialize SDIO slot %d\n",
syslog(LOG_ERR,
"ERROR: Failed to initialize SDIO slot %d\n",
CONFIG_NSH_MMCSDSLOTNO);
return -ENODEV;
}
@ -313,7 +318,9 @@ int board_app_initialize(uintptr_t arg)
ret = mmcsd_slotinitialize(CONFIG_NSH_MMCSDMINOR, sdio);
if (ret != OK)
{
syslog(LOG_ERR, "ERROR: Failed to bind SDIO to the MMC/SD driver: %d\n", ret);
syslog(LOG_ERR,
"ERROR: Failed to bind SDIO to the MMC/SD driver: %d\n",
ret);
return ret;
}