From 5a0f9fcb7d097ffbb5e45f956ed82cff087dddc1 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sat, 23 Jul 2016 10:36:06 -0600 Subject: [PATCH] Fix STM32 RTC Alarm interrupts. They were being enabled BEFORE the interrupt system was being initialized. --- arch/arm/src/armv7-r/arm_doirq.c | 16 ------ arch/arm/src/stm32/stm32f40xxx_rtcc.c | 66 ++++++++++++++++------- arch/arm/src/stm32l4/stm32l4_irq.c | 2 +- arch/arm/src/stm32l4/stm32l4_rtcc.c | 63 ++++++++++++++++------ configs/stm3240g-eval/src/stm32_appinit.c | 17 ++++-- 5 files changed, 106 insertions(+), 58 deletions(-) diff --git a/arch/arm/src/armv7-r/arm_doirq.c b/arch/arm/src/armv7-r/arm_doirq.c index fdf392d338..5d492f5ddc 100644 --- a/arch/arm/src/armv7-r/arm_doirq.c +++ b/arch/arm/src/armv7-r/arm_doirq.c @@ -52,22 +52,6 @@ #include "group/group.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/arch/arm/src/stm32/stm32f40xxx_rtcc.c b/arch/arm/src/stm32/stm32f40xxx_rtcc.c index c20024d8b1..518406bfa1 100644 --- a/arch/arm/src/stm32/stm32f40xxx_rtcc.c +++ b/arch/arm/src/stm32/stm32f40xxx_rtcc.c @@ -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) { diff --git a/arch/arm/src/stm32l4/stm32l4_irq.c b/arch/arm/src/stm32l4/stm32l4_irq.c index 7376b14675..720c05ecc6 100644 --- a/arch/arm/src/stm32l4/stm32l4_irq.c +++ b/arch/arm/src/stm32l4/stm32l4_irq.c @@ -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); } diff --git a/arch/arm/src/stm32l4/stm32l4_rtcc.c b/arch/arm/src/stm32l4/stm32l4_rtcc.c index d4c3c6c533..7e20a328af 100644 --- a/arch/arm/src/stm32l4/stm32l4_rtcc.c +++ b/arch/arm/src/stm32l4/stm32l4_rtcc.c @@ -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) { diff --git a/configs/stm3240g-eval/src/stm32_appinit.c b/configs/stm3240g-eval/src/stm32_appinit.c index 58938c9c2e..7523030be2 100644 --- a/configs/stm3240g-eval/src/stm32_appinit.c +++ b/configs/stm3240g-eval/src/stm32_appinit.c @@ -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; }