From d1a7740a2c93db609eb7a914492bd07bc183061d Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Tue, 13 Sep 2016 09:49:33 +0200 Subject: [PATCH 1/2] Updated RTCC driver with selectable INT1/INT2 trigger --- examples/zolertia/zoul/rtcc/test-rtcc.c | 4 +-- platform/zoul/dev/rtcc-config.h | 3 +-- platform/zoul/dev/rtcc.c | 35 ++++++++++++++++++------- platform/zoul/dev/rtcc.h | 12 +++++++-- 4 files changed, 38 insertions(+), 16 deletions(-) diff --git a/examples/zolertia/zoul/rtcc/test-rtcc.c b/examples/zolertia/zoul/rtcc/test-rtcc.c index 9b8895c09..48068ca5d 100644 --- a/examples/zolertia/zoul/rtcc/test-rtcc.c +++ b/examples/zolertia/zoul/rtcc/test-rtcc.c @@ -159,8 +159,8 @@ PROCESS_THREAD(test_remote_rtcc_process, ev, data) * minute. In case we would want to trigger the alarm on a specific time, * then we would want to set a daily repeat interval */ - if(rtcc_set_alarm_time_date(simple_td, RTCC_ALARM_ON, - RTCC_REPEAT_MINUTE) == AB08_ERROR) { + if(rtcc_set_alarm_time_date(simple_td, RTCC_ALARM_ON, RTCC_REPEAT_MINUTE, + RTCC_TRIGGER_INT1) == AB08_ERROR) { printf("Fail: couldn't set the alarm\n"); PROCESS_EXIT(); } diff --git a/platform/zoul/dev/rtcc-config.h b/platform/zoul/dev/rtcc-config.h index de39d5ec8..cf5f92135 100644 --- a/platform/zoul/dev/rtcc-config.h +++ b/platform/zoul/dev/rtcc-config.h @@ -99,5 +99,4 @@ static const ab080x_register_config_t ab080x_default_setting[] = /** * @} * @} - */ - + */ \ No newline at end of file diff --git a/platform/zoul/dev/rtcc.c b/platform/zoul/dev/rtcc.c index e27bdc555..0fe4284f5 100644 --- a/platform/zoul/dev/rtcc.c +++ b/platform/zoul/dev/rtcc.c @@ -388,10 +388,17 @@ rtcc_get_time_date(simple_td_map *data) } /*---------------------------------------------------------------------------*/ int8_t -rtcc_set_alarm_time_date(simple_td_map *data, uint8_t state, uint8_t repeat) +rtcc_set_alarm_time_date(simple_td_map *data, uint8_t state, uint8_t repeat, + uint8_t trigger) { uint8_t aux[4], buf[RTCC_ALARM_MAP_SIZE]; + if((trigger != RTCC_TRIGGER_INT2) && (trigger != RTCC_TRIGGER_INT1) && + (trigger != RTCC_TRIGGER_BOTH)) { + PRINTF("RTC: invalid trigger pin\n"); + return AB08_ERROR; + } + if(state == RTCC_ALARM_OFF) { if(ab08_read_reg((INT_MASK_ADDR + CONFIG_MAP_OFFSET), &aux[0], 1) == AB08_ERROR) { @@ -505,12 +512,25 @@ rtcc_set_alarm_time_date(simple_td_map *data, uint8_t state, uint8_t repeat) /* Clear the AIE alarm bit */ aux[INT_MASK_ADDR] &= ~INTMASK_AIE; - /* Configure Interrupt parameters for Alarm Interrupt Mode in nIRQ pin, - * and fixed level until interrupt flag is cleared + /* Configure Interrupt parameters for Alarm Interrupt Mode in nIRQ + * or nAIRQ pins and fixed level until interrupt flag is cleared + * RTC_INT1 is connected to the CC2538 + * RTC_INT2 is connected to the power management PIC in revision B */ + if (trigger == RTCC_TRIGGER_INT2) { + aux[CTRL_2_ADDR] |= CTRL2_OUT2S_NAIRQ_OUTB; + /* Only options left enable the INT1 interrupt pin */ + } else { + GPIO_ENABLE_INTERRUPT(RTC_INT1_PORT_BASE, RTC_INT1_PIN_MASK); + ioc_set_over(RTC_INT1_PORT, RTC_INT1_PIN, IOC_OVERRIDE_PUE); + nvic_interrupt_enable(RTC_INT1_VECTOR); + } - /* Enable nIRQ if at least one interrupt is enabled */ - aux[CTRL_2_ADDR] |= CTRL2_OUT1S_NIRQ_NAIRQ_OUT; + if (trigger == RTCC_TRIGGER_INT1) { + aux[CTRL_2_ADDR] |= CTRL2_OUT1S_NIRQ_NAIRQ_OUT; + } else if (trigger == RTCC_TRIGGER_BOTH) { + aux[CTRL_2_ADDR] |= (CTRL2_OUT1S_NIRQ_NAIRQ_OUT + CTRL2_OUT2S_NAIRQ_OUTB); + } if(repeat != RTCC_REPEAT_NONE) { aux[INT_MASK_ADDR] &= ~INTMASK_IM_LOW; @@ -523,11 +543,6 @@ rtcc_set_alarm_time_date(simple_td_map *data, uint8_t state, uint8_t repeat) return AB08_ERROR; } - /* Enable interrupts */ - GPIO_ENABLE_INTERRUPT(RTC_INT1_PORT_BASE, RTC_INT1_PIN_MASK); - ioc_set_over(RTC_INT1_PORT, RTC_INT1_PIN, IOC_OVERRIDE_PUE); - nvic_interrupt_enable(RTC_INT1_VECTOR); - /* Write to the alarm counters */ if(ab08_write_reg((HUNDREDTHS_ALARM_ADDR + ALARM_MAP_OFFSET), buf, RTCC_ALARM_MAP_SIZE) == AB08_ERROR) { diff --git a/platform/zoul/dev/rtcc.h b/platform/zoul/dev/rtcc.h index 4bbcbfe4f..ba4ac7850 100644 --- a/platform/zoul/dev/rtcc.h +++ b/platform/zoul/dev/rtcc.h @@ -275,6 +275,13 @@ enum { RTCC_AUTOCAL_17_MIN, RTCC_AUTOCAL_9_MIN, }; +/* -------------------------------------------------------------------------- */ +enum { + RTCC_TRIGGER_INT1 = 0, + RTCC_TRIGGER_INT2, + RTCC_TRIGGER_BOTH, +}; + /** @} */ /* -------------------------------------------------------------------------- */ /** \name Readable Date and time memory map implementation @@ -337,12 +344,13 @@ int8_t rtcc_print(uint8_t value); * \param data date and time values (in decimal) to match against * \param state set on/off the alarm interruption * \param repeat set the frequency of the alarm (minute, hourly, daily, etc.) + * \param trigger interrupt trigger (INT1, INT2 or both) * \return * \ AB08_SUCCESS date/time set * \ AB08_ERROR failed to set time/date (enable DEBUG for more info) */ int8_t rtcc_set_alarm_time_date(simple_td_map *data, uint8_t state, - uint8_t repeat); + uint8_t repeat, uint8_t trigger); /** * \brief Manually calibrate the RTCC @@ -377,4 +385,4 @@ int8_t rtcc_init(void); /** * @} * @} - */ + */ \ No newline at end of file From 072bf74aa2a0f9ef83f6f1313447f5682f33ac48 Mon Sep 17 00:00:00 2001 From: Antonio Lignan Date: Tue, 13 Sep 2016 15:07:24 +0200 Subject: [PATCH 2/2] Added RTCC function to increase current time in seconds --- examples/zolertia/zoul/rtcc/test-rtcc.c | 51 ++++++++++++++---- platform/zoul/dev/rtcc.c | 69 +++++++++++++++++++++++++ platform/zoul/dev/rtcc.h | 12 ++++- 3 files changed, 122 insertions(+), 10 deletions(-) diff --git a/examples/zolertia/zoul/rtcc/test-rtcc.c b/examples/zolertia/zoul/rtcc/test-rtcc.c index 48068ca5d..b2c7ce937 100644 --- a/examples/zolertia/zoul/rtcc/test-rtcc.c +++ b/examples/zolertia/zoul/rtcc/test-rtcc.c @@ -59,9 +59,14 @@ #define DATE "Unknown" #endif /*---------------------------------------------------------------------------*/ -#define LOOP_PERIOD 60L -#define LOOP_INTERVAL (CLOCK_SECOND * LOOP_PERIOD) -#define TEST_ALARM_SECOND 30 +#define LOOP_PERIOD 60L +#define LOOP_INTERVAL (CLOCK_SECOND * LOOP_PERIOD) +#define TEST_ALARM_SECOND 15 +/*---------------------------------------------------------------------------*/ +/* Enable to match a given second number every minute, else it will trigger an + * interrupt every TEST_ALARM_SECOND + */ +#define TEST_ALARM_MATCH_MIN 0 /*---------------------------------------------------------------------------*/ PROCESS(test_remote_rtcc_process, "Test RTC driver process"); AUTOSTART_PROCESSES(&test_remote_rtcc_process); @@ -72,11 +77,34 @@ static simple_td_map *simple_td = (simple_td_map *)rtc_buffer; static struct etimer et; /*---------------------------------------------------------------------------*/ void +configure_new_alarm(void) +{ + if(rtcc_date_increment_seconds(simple_td, TEST_ALARM_SECOND) == AB08_ERROR) { + printf("Fail: could not increment the next alarm date\n"); + return; + } + + /* We use the RTCC_REPEAT_DAY as we want the RTCC to match the given date */ + if(rtcc_set_alarm_time_date(simple_td, RTCC_ALARM_ON, RTCC_REPEAT_DAY, + RTCC_TRIGGER_INT1) == AB08_ERROR) { + printf("Fail: couldn't set the alarm\n"); + return; + } + + printf("Alarm set to match: "); + rtcc_print(RTCC_PRINT_ALARM_DEC); +} +/*---------------------------------------------------------------------------*/ +void rtcc_interrupt_callback(uint8_t value) { printf("A RTCC interrupt just happened! time/date: "); rtcc_print(RTCC_PRINT_DATE_DEC); - leds_toggle(LEDS_PURPLE); + leds_toggle(LEDS_ALL); + +#if !TEST_ALARM_MATCH_MIN + configure_new_alarm(); +#endif } /*---------------------------------------------------------------------------*/ PROCESS_THREAD(test_remote_rtcc_process, ev, data) @@ -149,9 +177,10 @@ PROCESS_THREAD(test_remote_rtcc_process, ev, data) printf("Configured time: "); rtcc_print(RTCC_PRINT_DATE_DEC); - /* Configure the RTCC to trigger an alarm every TEST_ALARM_SECOND tick */ - printf("Setting an alarm to tick every minute matching %u seconds\n", - TEST_ALARM_SECOND); +#if TEST_ALARM_MATCH_MIN + /* Configure the RTCC to trigger an alarm every TEST_ALARM_SECOND match */ + printf("Setting an alarm to tick every %u seconds match\n", TEST_ALARM_SECOND); + simple_td->seconds = TEST_ALARM_SECOND; /* Notice the arguments, we want to trigger the alarm every time the clock @@ -165,8 +194,12 @@ PROCESS_THREAD(test_remote_rtcc_process, ev, data) PROCESS_EXIT(); } - printf("Alarm set to match: "); - rtcc_print(RTCC_PRINT_ALARM_DEC); +#else + /* Configure the RTCC to trigger an alarm every TEST_ALARM_SECOND tick */ + printf("Setting an alarm to tick every %u seconds\n", TEST_ALARM_SECOND); + + configure_new_alarm(); +#endif PROCESS_END(); } diff --git a/platform/zoul/dev/rtcc.c b/platform/zoul/dev/rtcc.c index 0fe4284f5..30049156f 100644 --- a/platform/zoul/dev/rtcc.c +++ b/platform/zoul/dev/rtcc.c @@ -564,6 +564,75 @@ rtcc_set_alarm_time_date(simple_td_map *data, uint8_t state, uint8_t repeat, return AB08_SUCCESS; } /*---------------------------------------------------------------------------*/ +int8_t +rtcc_date_increment_seconds(simple_td_map *data, uint16_t seconds) +{ + uint16_t aux; + + if(data == NULL) { + PRINTF("RTC: invalid argument\n"); + return AB08_ERROR; + } + + if(rtcc_get_time_date(data) == AB08_ERROR) { + return AB08_ERROR; + } + + /* Nothing to do here but congratulate the user */ + if(!seconds) { + return AB08_SUCCESS; + } + + aux = data->seconds + seconds; + data->seconds = (uint8_t)(aux % 60); + + /* Add the remainder seconds to the minutes counter */ + if(aux > 59) { + aux /= 60; + aux += data->minutes; + data->minutes = (uint8_t)(aux % 60); + } + + /* Add the remainder minutes to the hours counter */ + if(aux > 59) { + aux /= 60; + aux += data->hours; + data->hours = (uint8_t)(aux % 24); + } + + if(aux > 23) { + aux /= 24; + aux += data->day; + + if(data->months == 2) { + if(check_leap_year(data->years)) { + if(aux > 29) { + data->day = (uint8_t)(aux % 29); + data->months++; + } + } else if(aux > 28) { + data->day = (uint8_t)(aux % 28); + data->months++; + } + } else if((data->months == 4) || (data->months == 6) || + (data->months == 9) || (data->months == 11)) { + if(aux > 30) { + data->day = (uint8_t)(aux % 30); + data->months++; + } + } else if(aux > 31) { + data->day = (uint8_t)(aux % 31); + data->months++; + } + } + + if(data->months > 12) { + data->months = data->months % 12; + data->years++; + } + return AB08_SUCCESS; +} +/*---------------------------------------------------------------------------*/ PROCESS(rtcc_int_process, "RTCC interruption process handler"); /*---------------------------------------------------------------------------*/ PROCESS_THREAD(rtcc_int_process, ev, data) diff --git a/platform/zoul/dev/rtcc.h b/platform/zoul/dev/rtcc.h index ba4ac7850..898e9c264 100644 --- a/platform/zoul/dev/rtcc.h +++ b/platform/zoul/dev/rtcc.h @@ -352,6 +352,16 @@ int8_t rtcc_print(uint8_t value); int8_t rtcc_set_alarm_time_date(simple_td_map *data, uint8_t state, uint8_t repeat, uint8_t trigger); +/** + * \brief Increments the current date by a number of seconds + * \param data structure to store the date + * \param seconds the numberof seconds to increment the date + * \return + * \ AB08_SUCCESS updated date values + * \ AB08_ERROR failed to return the values + */ +int8_t rtcc_date_increment_seconds(simple_td_map *data, uint16_t seconds); + /** * \brief Manually calibrate the RTCC * \param mode oscillator to calibrate @@ -385,4 +395,4 @@ int8_t rtcc_init(void); /** * @} * @} - */ \ No newline at end of file + */