use timer to count ticks based on square wave output
This commit is contained in:
parent
06d7e0fda0
commit
111c0a5455
|
@ -28,9 +28,9 @@
|
||||||
#define SQUARE_WAVE_PORT GPIOB /**< GPIO port (port B) */
|
#define SQUARE_WAVE_PORT GPIOB /**< GPIO port (port B) */
|
||||||
#define SQUARE_WAVE_PIN GPIO10 /**< GPIO pin (pin PA10) */
|
#define SQUARE_WAVE_PIN GPIO10 /**< GPIO pin (pin PA10) */
|
||||||
#define SQUARE_WAVE_EXTI EXTI10 /**< GPIO external interrupt (exti 10 for pin 12) */
|
#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_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_ISR exti15_10_isr /**< GPIO line interrupt service routine (isr for line 15 to 10 for pin 10) */
|
||||||
#define SQUARE_WAVE_HANDLING false /**< to to have the library handle the square wave interrupt (setting square_wave_flag) */
|
//#define SQUARE_WAVE_HANDLING true /**< 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
|
#if defined(SQUARE_WAVE_EXTI) && defined(SQUARE_WAVE_IRQ) && defined(SQUARE_WAVE_ISR) && defined(SQUARE_WAVE_HANDLING) && SQUARE_WAVE_HANDLING
|
||||||
|
|
71
main.c
71
main.c
|
@ -13,12 +13,12 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
/** @file main.c
|
/** @file main.c
|
||||||
@author King Kévin <kingkevin@cuvoodoo.info>
|
* @author King Kévin <kingkevin@cuvoodoo.info>
|
||||||
@date 2016
|
* @date 2016
|
||||||
@brief show the time on a LED strip
|
* @brief show the time on a LED strip
|
||||||
|
*
|
||||||
The LED strip consists of 60 WS2812b LEDs.
|
* The LED strip consists of 60 WS2812b LEDs.
|
||||||
The time is read from a DS1307 RTC module.
|
* The time is read from a DS1307 RTC module.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* standard libraries */
|
/* standard libraries */
|
||||||
|
@ -36,6 +36,7 @@ The time is read from a DS1307 RTC module.
|
||||||
#include <libopencmsis/core_cm3.h> // Cortex M3 utilities
|
#include <libopencmsis/core_cm3.h> // Cortex M3 utilities
|
||||||
#include <libopencm3/cm3/nvic.h> // interrupt utilities
|
#include <libopencm3/cm3/nvic.h> // interrupt utilities
|
||||||
#include <libopencm3/stm32/exti.h> // external interrupt utilities
|
#include <libopencm3/stm32/exti.h> // external interrupt utilities
|
||||||
|
#include <libopencm3/stm32/timer.h> // timer utilities
|
||||||
|
|
||||||
/* own libraries */
|
/* own libraries */
|
||||||
#include "global.h" // board definitions
|
#include "global.h" // board definitions
|
||||||
|
@ -52,7 +53,6 @@ volatile bool time_flag = false; /**< flag set when time changed */
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
#define TICKS_PER_SECOND 256 /**< the number of ticks in one second */
|
#define TICKS_PER_SECOND 256 /**< the number of ticks in one second */
|
||||||
#define SQUARE_WAVE_FREQUENCY 4096 /**< square wave output frequency from the RTC IC */
|
|
||||||
/** @defgroup main_ticks ticks per time units
|
/** @defgroup main_ticks ticks per time units
|
||||||
* @note these are derived from TICKS_PER_SECOND
|
* @note these are derived from TICKS_PER_SECOND
|
||||||
* @note I have to use type variables because defines would be stored in signed integers, leading to an overflow it later calculations
|
* @note I have to use type variables because defines would be stored in signed integers, leading to an overflow it later calculations
|
||||||
|
@ -68,6 +68,22 @@ const uint32_t ticks_hour = 60*60*TICKS_PER_SECOND;
|
||||||
const uint32_t ticks_midday = 12*60*60*TICKS_PER_SECOND;
|
const uint32_t ticks_midday = 12*60*60*TICKS_PER_SECOND;
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
|
/** @defgroup square_wave_timer timer peripheral used to count timer based on RTC IC square wave output
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define SQUARE_WAVE_FREQUENCY 4096 /**< square wave output frequency from the RTC IC */
|
||||||
|
#define SQUARE_WAVE_TIMER TIM2 /**< timer peripheral */
|
||||||
|
#define SQUARE_WAVE_TIMER_RCC RCC_TIM2 /**< timer peripheral clock */
|
||||||
|
#define SQUARE_WAVE_TIMER_IC TIM_IC1 /**< input capture channel (for TIM2_CH1) */
|
||||||
|
#define SQUARE_WAVE_TIMER_IN TIM_IC_IN_TI1 /**< input capture input source (TIM2_CH1 becomes TI1, then TI1F, then TI1FP1) */
|
||||||
|
#define SQUARE_WAVE_TIMER_TS TIM_SMCR_TS_IT1FP1 /**< input capture trigger (actually TI1FP1) */
|
||||||
|
#define SQUARE_WAVE_TIMER_IRQ NVIC_TIM2_IRQ /**< timer interrupt */
|
||||||
|
#define SQUARE_WAVE_TIMER_ISR tim2_isr /**< timer interrupt service routine */
|
||||||
|
#define SQUARE_WAVE_GPIO_RCC RCC_GPIOA /**< timer port peripheral clock (TIM2_CH1 on PA0)*/
|
||||||
|
#define SQUARE_WAVE_GPIO_PORT GPIOA /**< timer port (TIM2_CH1 on PA0) */
|
||||||
|
#define SQUARE_WAVE_GPIO_PIN GPIO_TIM2_CH1_ETR /**< timer pin input, connect to RTC IC square wave output (TIM2_CH1 on PA0) */
|
||||||
|
/** @} */
|
||||||
|
|
||||||
/** RGB values for the WS2812b clock LEDs */
|
/** RGB values for the WS2812b clock LEDs */
|
||||||
uint8_t clock_leds[WS2812B_LEDS*3] = {0};
|
uint8_t clock_leds[WS2812B_LEDS*3] = {0};
|
||||||
/** current time in tick */
|
/** current time in tick */
|
||||||
|
@ -209,12 +225,12 @@ static void clock_show_time(uint32_t time)
|
||||||
}
|
}
|
||||||
uint16_t led_second = (WS2812B_LEDS*(time%ticks_minute))/ticks_minute; // get LED for seconds
|
uint16_t led_second = (WS2812B_LEDS*(time%ticks_minute))/ticks_minute; // get LED for seconds
|
||||||
uint8_t brightness_second = (255*(time%ticks_second))/ticks_second; // get brightness for seconds
|
uint8_t brightness_second = (255*(time%ticks_second))/ticks_second; // get brightness for seconds
|
||||||
// set second LED
|
// set seconds LED
|
||||||
clock_leds[led_second*3+0] = brightness_second;
|
clock_leds[led_second*3+0] = brightness_second;
|
||||||
//clock_leds[led_second*3+1] = 0; // clear other colors (minutes/hours indication)
|
//clock_leds[led_second*3+1] = 0; // clear other colors (minutes/hours indication)
|
||||||
//clock_leds[led_second*3+2] = 0; // clear other colors (minutes/hours indication)
|
//clock_leds[led_second*3+2] = 0; // clear other colors (minutes/hours indication)
|
||||||
// set previous LED
|
// set previous seconds LED
|
||||||
led_second = (led_second==0) ? WS2812B_LEDS-1 : led_second-1; // previous LED
|
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+0] = 0xff-brightness_second;
|
||||||
//clock_leds[led_second*3+1] = 0; // clear other colors (minutes/hours indication)
|
//clock_leds[led_second*3+1] = 0; // clear other colors (minutes/hours indication)
|
||||||
//clock_leds[led_second*3+2] = 0; // clear other colors (minutes/hours indication)
|
//clock_leds[led_second*3+2] = 0; // clear other colors (minutes/hours indication)
|
||||||
|
@ -373,6 +389,25 @@ int main(void)
|
||||||
rtc_setup(); // setup RTC module
|
rtc_setup(); // setup RTC module
|
||||||
rtc_write_square_wave(SQUARE_WAVE_FREQUENCY); // set square wave output frequency
|
rtc_write_square_wave(SQUARE_WAVE_FREQUENCY); // set square wave output frequency
|
||||||
|
|
||||||
|
// setup timer to generate tick from square wave output */
|
||||||
|
rcc_periph_clock_enable(SQUARE_WAVE_GPIO_RCC); // enable clock for GPIO peripheral
|
||||||
|
gpio_set_mode(SQUARE_WAVE_GPIO_PORT, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, SQUARE_WAVE_GPIO_PIN); // set pin as input
|
||||||
|
gpio_set(SQUARE_WAVE_GPIO_PORT, SQUARE_WAVE_GPIO_PIN); // enable pull-up
|
||||||
|
rcc_periph_clock_enable(SQUARE_WAVE_TIMER_RCC); // enable clock for timer peripheral
|
||||||
|
timer_reset(SQUARE_WAVE_TIMER); // reset timer state
|
||||||
|
timer_ic_set_input(SQUARE_WAVE_TIMER, SQUARE_WAVE_TIMER_IC, SQUARE_WAVE_TIMER_IN); // configure channel as input capture
|
||||||
|
timer_ic_set_filter(SQUARE_WAVE_TIMER, SQUARE_WAVE_TIMER_IC, TIM_IC_OFF); // use no input capture filter
|
||||||
|
timer_ic_set_polarity(SQUARE_WAVE_TIMER, SQUARE_WAVE_TIMER_IC, TIM_IC_FALLING); //capture on falling edge
|
||||||
|
timer_slave_set_trigger(SQUARE_WAVE_TIMER, SQUARE_WAVE_TIMER_TS); // select trigger
|
||||||
|
timer_slave_set_mode(SQUARE_WAVE_TIMER, TIM_SMCR_SMS_ECM1); // select external clock more 1 as input
|
||||||
|
timer_ic_enable(SQUARE_WAVE_TIMER, SQUARE_WAVE_TIMER_IC); // enable input capture
|
||||||
|
timer_set_mode(SQUARE_WAVE_TIMER, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP); // set timer mode, use undivided timer clock, edge alignment (simple count), and count up
|
||||||
|
timer_set_prescaler(SQUARE_WAVE_TIMER, 0); // no need to prescale
|
||||||
|
timer_set_period(SQUARE_WAVE_TIMER, SQUARE_WAVE_FREQUENCY/TICKS_PER_SECOND-1); // set the tick period
|
||||||
|
timer_enable_irq(SQUARE_WAVE_TIMER, TIM_DIER_UIE); // enable interrupt for timer
|
||||||
|
nvic_enable_irq(SQUARE_WAVE_TIMER_IRQ); // allow interrupt for timer
|
||||||
|
timer_enable_counter(SQUARE_WAVE_TIMER); // enable timer to count ticks
|
||||||
|
|
||||||
printf("welcome to the CuVoodoo LED clock\n"); // print welcome message
|
printf("welcome to the CuVoodoo LED clock\n"); // print welcome message
|
||||||
led_on(); // switch on LED to indicate setup completed
|
led_on(); // switch on LED to indicate setup completed
|
||||||
|
|
||||||
|
@ -383,8 +418,8 @@ int main(void)
|
||||||
|
|
||||||
// get date and time
|
// get date and time
|
||||||
uint16_t* rtc_time = rtc_read_time(); // get RTC time/date
|
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]);
|
|
||||||
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
|
||||||
|
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]);
|
||||||
clock_animate_time(current_time); // set time with animation
|
clock_animate_time(current_time); // set time with animation
|
||||||
|
|
||||||
printf("input commands\n");
|
printf("input commands\n");
|
||||||
|
@ -430,7 +465,6 @@ int main(void)
|
||||||
while (time_flag) { // time passed
|
while (time_flag) { // time passed
|
||||||
time_flag = false; // reset flag
|
time_flag = false; // reset flag
|
||||||
action = true; // action has been performed
|
action = true; // action has been performed
|
||||||
led_toggle();
|
|
||||||
if ((current_time%ticks_minute)==0) { // sync each minute
|
if ((current_time%ticks_minute)==0) { // sync each minute
|
||||||
rtc_time = rtc_read_time(); // get RTC time/date
|
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
|
current_time = rtc_time[2]*ticks_hour+rtc_time[1]*ticks_minute+rtc_time[0]*ticks_second; // calculate current time
|
||||||
|
@ -459,18 +493,13 @@ void BUTTON_ISR(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(SQUARE_WAVE_EXTI) && defined(SQUARE_WAVE_IRQ) && defined(SQUARE_WAVE_ISR) && defined(SQUARE_WAVE_HANDLING) && !SQUARE_WAVE_HANDLING
|
#if defined(SQUARE_WAVE_TIMER_IRQ) && defined(SQUARE_WAVE_TIMER_ISR)
|
||||||
/** @brief square wave input interrupt */
|
void SQUARE_WAVE_TIMER_ISR(void)
|
||||||
void SQUARE_WAVE_ISR(void)
|
|
||||||
{
|
{
|
||||||
static uint16_t square_wave_prescale = 0; /**< prescale the square wave output to generate a tick */
|
if (timer_get_flag(SQUARE_WAVE_TIMER, TIM_SR_UIF)) { // overflow even happened
|
||||||
|
timer_clear_flag(SQUARE_WAVE_TIMER, TIM_SR_UIF); // clear flag
|
||||||
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
|
current_time++; // increment time
|
||||||
time_flag = true; // update flag
|
time_flag = true; // update flag
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue