use interrupt to reliably increment time

This commit is contained in:
King Kévin 2016-03-26 14:34:55 +01:00
parent 2d60475b81
commit 62066fe980
3 changed files with 39 additions and 22 deletions

View File

@ -71,7 +71,7 @@ void rtc_setup(void)
rcc_periph_clock_enable(SQUARE_WAVE_RCC); // enable GPIO peripheral
gpio_set_mode(SQUARE_WAVE_PORT, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, SQUARE_WAVE_PIN); // set pin to input with pull up
gpio_set(SQUARE_WAVE_PORT, SQUARE_WAVE_PIN); // pull up since the square wave output is open drain
#if defined(SQUARE_WAVE_EXTI) && defined(SQUARE_WAVE_IRQ) && defined(SQUARE_WAVE_ISR) && defined(SQUARE_WAVE_HANDLING) && SQUARE_WAVE_HANDLING
#if defined(SQUARE_WAVE_EXTI) && defined(SQUARE_WAVE_IRQ) && defined(SQUARE_WAVE_ISR)
rcc_periph_clock_enable(RCC_AFIO); // enable alternate function clock for external interrupt
exti_select_source(SQUARE_WAVE_EXTI, SQUARE_WAVE_PORT); // mask external interrupt of this pin only for this port
exti_set_trigger(SQUARE_WAVE_EXTI, EXTI_TRIGGER_FALLING); // trigger on falling

View File

@ -30,7 +30,7 @@
#define SQUARE_WAVE_EXTI EXTI10 /**< GPIO external interrupt (exti 10 for pin 12) */
#define SQUARE_WAVE_IRQ NVIC_EXTI15_10_IRQ /**< GPIO line interrupt (interrupt for line 15 to 10 for pin 10) */
#define SQUARE_WAVE_ISR exti15_10_isr /**< GPIO line interrupt service routine (isr for line 15 to 10 for pin 10) */
#define SQUARE_WAVE_HANDLING true /**< to to have the library handle the square wave interrupt (setting square_wave_flag) */
#define SQUARE_WAVE_HANDLING false /**< to to have the library handle the square wave interrupt (setting square_wave_flag) */
/** @} */
#if defined(SQUARE_WAVE_EXTI) && defined(SQUARE_WAVE_IRQ) && defined(SQUARE_WAVE_ISR) && defined(SQUARE_WAVE_HANDLING) && SQUARE_WAVE_HANDLING

57
main.c
View File

@ -44,9 +44,10 @@ The time is read from a DS1307 RTC module.
#include "rtc_ds1307.h" // Real Time Clock DS1307 utilities
/** @defgroup main_flags flag set in interrupts to be processed in main task
@{
* @{
*/
volatile bool button_flag = false; /**< flag set if board user button has been pressed */
volatile bool button_flag = false; /**< flag set when board user button has been pressed/released */
volatile bool time_flag = false; /**< flag set when time changed */
/** @} */
#define TICKS_PER_SECOND 256 /**< the number of ticks in one second */
@ -68,6 +69,8 @@ const uint32_t ticks_midday = 12*60*60*TICKS_PER_SECOND;
/** RGB values for the WS2812b clock LEDs */
uint8_t clock_leds[WS2812B_LEDS*3] = {0};
/** current time in tick */
volatile uint32_t current_time = 0;
int _write(int file, char *ptr, int len)
{
@ -206,9 +209,10 @@ static void clock_show_time(uint32_t time)
clock_leds[led_second*3+1] = 0;
clock_leds[led_second*3+2] = 0;
// set previous LED
clock_leds[((led_second-1)%WS2812B_LEDS)*3+0] = 0xff-brightness_second;
clock_leds[((led_second-1)%WS2812B_LEDS)*3+1] = 0;
clock_leds[((led_second-1)%WS2812B_LEDS)*3+2] = 0;
led_second = (led_second==0) ? WS2812B_LEDS-1 : led_second-1; // previous LED
clock_leds[led_second*3+0] = 0xff-brightness_second;
clock_leds[led_second*3+1] = 0;
clock_leds[led_second*3+2] = 0;
}
/** @brief set the LEDs
@ -227,11 +231,9 @@ static void leds_set(void)
*/
static void clock_set_time(uint32_t time)
{
led_off();
clock_show_time(time); // set time
leds_set(); // set the colors of all LEDs
ws2812b_transmit(); // transmit set color
led_on();
}
/** @brief incrementally set the time on the LEDs
@ -310,7 +312,7 @@ int main(void)
// get date and time
uint16_t* rtc_time = rtc_read_time(); // get RTC time/date
printf("current date: %04d-%02d-%02d %02d:%02d:%02d\n", rtc_time[6], rtc_time[5], rtc_time[4], rtc_time[2], rtc_time[1], rtc_time[0]);
uint32_t current_time = rtc_time[2]*ticks_hour+rtc_time[1]*ticks_minute+rtc_time[0]*ticks_second; // the current time
current_time = rtc_time[2]*ticks_hour+rtc_time[1]*ticks_minute+rtc_time[0]*ticks_second; // the current time
clock_animate_time(current_time); // set time with animation
//rtc_write_time(0,52,9,4,23,3,2016);
@ -321,7 +323,6 @@ int main(void)
button_flag = false; // reset button flag
char c = ' '; // to store received character
bool char_flag = false; // a new character has been received
uint16_t square_wave_prescale = 0; // prescale the square wave output to generate a tick
while (true) { // infinite loop
while (usart_received) { // data received over UART
action = true; // action has been performed
@ -345,18 +346,18 @@ int main(void)
action = true; // action has been performed
led_toggle(); // toggle LED
}
while (square_wave_flag) { // time passed
square_wave_flag = false; // reset flag
while (time_flag) { // time passed
time_flag = false; // reset flag
action = true; // action has been performed
square_wave_prescale = (square_wave_prescale+1)%(SQUARE_WAVE_FREQUENCY/TICKS_PER_SECOND); // increment pre-scale counter
if (square_wave_prescale==0) { // pre-scale completed
current_time++; // increment time
if ((current_time%ticks_second)==0) { // sync on seconds
//rtc_time = rtc_read_time(); // get RTC time/date
//current_time = rtc_time[2]*ticks_hour+rtc_time[1]*ticks_minute+rtc_time[0]*ticks_second; // calculate current time
printf("it is now %02lu:%02lu:%02lu\n", current_time/ticks_hour, (current_time%ticks_hour)/ticks_minute, (current_time%ticks_minute)/ticks_second); // display time
}
clock_set_time(current_time); // set time
led_toggle();
if ((current_time%ticks_minute)==0) { // sync each minute
rtc_time = rtc_read_time(); // get RTC time/date
current_time = rtc_time[2]*ticks_hour+rtc_time[1]*ticks_minute+rtc_time[0]*ticks_second; // calculate current time
printf("it is now %02lu:%02lu:%02lu\n", current_time/ticks_hour, (current_time%ticks_hour)/ticks_minute, (current_time%ticks_minute)/ticks_second); // display time
}
clock_set_time(current_time); // set time
if ((current_time%ticks_second)==0) { // print each second
//printf("%02lu:%02lu:%02lu\n", current_time/ticks_hour, (current_time%ticks_hour)/ticks_minute, (current_time%ticks_minute)/ticks_second); // display time
}
}
if (action) { // go to sleep if nothing had to be done, else recheck for activity
@ -376,3 +377,19 @@ void BUTTON_ISR(void)
button_flag = true; // perform button action
}
#endif
#if defined(SQUARE_WAVE_EXTI) && defined(SQUARE_WAVE_IRQ) && defined(SQUARE_WAVE_ISR) && defined(SQUARE_WAVE_HANDLING) && !SQUARE_WAVE_HANDLING
/** @brief square wave input interrupt */
void SQUARE_WAVE_ISR(void)
{
static uint16_t square_wave_prescale = 0; /**< prescale the square wave output to generate a tick */
exti_reset_request(SQUARE_WAVE_EXTI); // reset interrupt
square_wave_prescale = (square_wave_prescale+1)%(SQUARE_WAVE_FREQUENCY/TICKS_PER_SECOND); // increment pre-scale counter
if (square_wave_prescale==0) { // pre-scale completed
current_time++; // increment time
time_flag = true; // update flag
}
}
#endif