use interrupt to reliably increment time
This commit is contained in:
parent
2d60475b81
commit
62066fe980
@ -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
|
||||
|
@ -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
57
main.c
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user