add frame time and display

This commit is contained in:
King Kévin 2017-04-02 13:42:54 +02:00
parent 6922cf655b
commit be1f2f9f65
1 changed files with 67 additions and 18 deletions

85
main.c
View File

@ -34,6 +34,7 @@
#include <libopencm3/stm32/iwdg.h> // independent watchdog utilities
#include <libopencm3/stm32/dbgmcu.h> // debug utilities
#include <libopencm3/stm32/flash.h> // flash utilities
#include <libopencm3/stm32/timer.h> // timer utilities
/* own libraries */
#include "global.h" // board definitions
@ -50,10 +51,16 @@
* @{
*/
volatile bool rtc_tick_flag = false; /**< flag set when RTC ticked */
volatile bool frame_flag = false; /**< flag set when a frame has passed */
/** @} */
#define SQUARE_WAVE_PORT B /**< port connected to RTC DS1307 square wave output */
#define SQUARE_WAVE_PIN 0 /**< pin connected to RTC DS1307 square wave output */
volatile uint8_t rtc_seconds = 0; /** number of seconds passed incremented by the square wave */
#define FRAME_TIMER 1 /**< timer to count frame time */
#define FRAME_RATE 25 /**< frame rate */
volatile uint8_t frame_count = 0; /**< number of frames passed */
/** user input command */
static char command[32] = {0};
@ -188,7 +195,7 @@ void main(void)
board_setup(); // setup board
usart_setup(); // setup USART for user communication
cdcacm_setup(); // setup USB ACM (serial) for user communication
printf("welcome to the STM32F1 CuVoodoo example code\n"); // print welcome message
printf("welcome to the STM32F1 CuVoodoo clapperboard\n"); // print welcome message
#if !(DEBUG)
// show watchdog information
@ -226,7 +233,6 @@ void main(void)
// display date
uint8_t* rtc_ds1307_time = rtc_ds1307_read_time(); // get time/date from external RTC
uint8_t rtc_seconds = 0; // count the number of seconds passed and sync time on minute
if (rtc_ds1307_time==NULL) {
printf("could not get time from DS1307\n");
} else {
@ -242,17 +248,15 @@ void main(void)
// setup TM1637 and MAX7219 7-segments displays
printf("setup 7-segment displays: ");
led_tm1637_setup(); // setup TM1637
led_max7219_setup(); // setup MAX7219
led_max7219_setup(2); // setup MAX7219
if (!led_tm1637_time(88,88)) { // test TM1637 display
printf("could not send time to TM1637\n");
}
if (!led_tm1637_on()) { // switch on TM1637 display
printf("could not switch on TM1637\n");
}
led_max7219_intensity(15,8,0); // set brightness max and enable all digits on 1st display
led_max7219_intensity(15,8,1); // set brightness max and enable all digits on 1st display
led_max7219_test(true,0); // test 1st MAX7219 display
led_max7219_test(true,1); // test 2nd MAX7219 display
led_max7219_intensity(15,8,0xff); // set brightness max and enable all digits
led_max7219_test(true,0xff); // test all MAX7219 displays
for (uint32_t i=0; i<5000000; i++) { // wait a bit to have the user check the display
__asm__("nop");
}
@ -262,17 +266,34 @@ void main(void)
if (!led_tm1637_off()) { // switch off display
printf("could not switch off TM1637\n");
}
led_max7219_test(false,0); // go back in normal operation
led_max7219_test(false,1); // go back in normal operation
led_max7219_off(0); // switch 1st display off
led_max7219_off(1); // switch 2nd display off
led_max7219_test(false,0xff); // go back in normal operation
led_max7219_off(0xff); // switch displays off
printf("OK\n");
led_max7219_number(rtc_ds1307_time[2]*1000000+rtc_ds1307_time[1]*10000+rtc_ds1307_time[0]*100, 0x54, 0); // display time on 1nd display
// display date and time on 7-segments
led_max7219_number(20000000+rtc_ds1307_time[6]*10000+rtc_ds1307_time[5]*100+rtc_ds1307_time[4], 0x14, 1); // display date on 2nd display
led_max7219_on(0); // switch 1st display on
led_max7219_on(1); // switch 2nd display on
led_max7219_number(rtc_ds1307_time[2]*1000000+rtc_ds1307_time[1]*10000+rtc_ds1307_time[0]*100, 0x54, 0); // display time on 1nd display
led_max7219_on(0xff); // switch displays on
// setup frame timer
printf("setup frame timer: ");
rcc_periph_clock_enable(RCC_TIM(FRAME_TIMER)); // enable clock for timer block
timer_reset(TIM(FRAME_TIMER)); // reset timer state
timer_set_mode(TIM(FRAME_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(TIM(FRAME_TIMER), (rcc_ahb_frequency/0xffff+1)-1); // set the prescaler to so count up to one second
timer_set_period(TIM(FRAME_TIMER), 0xffff/FRAME_RATE); // overflow at the end of every rate
timer_update_on_overflow(TIM(FRAME_TIMER)); // only use counter overflow as UEV source (use overflow as timeout)
timer_clear_flag(TIM(FRAME_TIMER), TIM_SR_UIF); // clear flag
timer_enable_irq(TIM(FRAME_TIMER), TIM_DIER_UIE); // enable update interrupt for timer
#if FRAME_TIMER==1
nvic_enable_irq(NVIC_TIM1_UP_IRQ); // catch interrupt in service routine
#else
nvic_enable_irq(NVIC_TIM_IRQ(FRAME_TIMER)); // catch interrupt in service routine
#endif
timer_set_counter(TIM(FRAME_TIMER),0); // restart timer
timer_enable_counter(TIM(FRAME_TIMER)); // enable timer to start counting frames
printf("OK\n");
// main loop
printf("command input: ready\n");
bool action = false; // if an action has been performed don't go to sleep
@ -319,11 +340,23 @@ void main(void)
}
button_flag = false; // reset flag
}
while (frame_flag) { // a frame has passed
frame_flag = false; // reset flag
action = true; // action has been performed
uint8_t dots = 0x40; // dot for minutes on display
if (0==(rtc_seconds%2)) { // even seconds
dots |= 0x10; // add dot for seconds
}
if (0==(frame_count%2)) { // even frames
dots |= 0x04; // add dot for frame
}
led_max7219_number(rtc_ds1307_time[2]*1000000+rtc_ds1307_time[1]*10000+rtc_seconds*100+(frame_count%100), dots, 0); // display frame time on 1nd display
}
while (rtc_tick_flag) { // the external RTC ticked
rtc_tick_flag = false; // reset flag
action = true; // action has been performed
led_toggle(); // toggle LED (good to indicate if main function is stuck)
rtc_seconds++; // increment number of seconds passed
frame_count = 0; // resync frame counter to second
if (rtc_seconds>=60) { // one minute passed
rtc_ds1307_time = rtc_ds1307_read_time(); // get time/date from external RTC
if (rtc_ds1307_time==NULL) {
@ -348,6 +381,22 @@ void main(void)
void EXTI_ISR(SQUARE_WAVE_PIN)(void)
{
exti_reset_request(EXTI(SQUARE_WAVE_PIN)); // reset interrupt
rtc_tick_flag = true; // perform button action
rtc_seconds++; // increment number of seconds passed
rtc_tick_flag = true; // let main know a second passed
}
#if FRAME_TIMER==1
void tim1_up_isr(void)
#else
void TIM_ISR(FRAME_TIMER)(void)
#endif
{
if (timer_get_flag(TIM(FRAME_TIMER), TIM_SR_UIF)) { // overflow update event happened
timer_clear_flag(TIM(FRAME_TIMER), TIM_SR_UIF); // clear flag
frame_count++; // increment frame counter since frame finished
frame_flag = true; // let main know the counter changed
} else { // no other interrupt should occur
while (true); // unhandled exception: wait for the watchdog to bite
}
}