diff --git a/main.c b/main.c index aaee92d..5aa85fe 100644 --- a/main.c +++ b/main.c @@ -62,10 +62,16 @@ volatile uint8_t rtc_seconds = 0; /**< number of seconds passed incremented by t #define STANDBY_TIMEOUT 30 /**< number of seconds after last shake before going down */ volatile uint16_t standby_timer = 0; /**< number of seconds since last wake-up/activity */ -#define FRAME_TIMER 1 /**< timer to count frame time */ +#define FRAME_TIMER 2 /**< timer to count frame time */ #define FRAME_RATE 25 /**< frame rate */ volatile uint8_t frame_count = 0; /**< number of frames passed */ +#define BUZZER_TIMER 1 /**< timer to generate scene and take count */ +#define BUZZER_1_PORT A /**< use timer 1 channel 1 (and it's negative) to driver buzzer */ +#define BUZZER_1_PIN 7 /**< use timer 1 channel 1 (and it's negative) to driver buzzer */ +#define BUZZER_2_PORT A /**< use timer 1 channel 1 (and it's negative) to driver buzzer */ +#define BUZZER_2_PIN 8 /**< use timer 1 channel 1 (and it's negative) to driver buzzer */ + #define MUX_EN_PORT B /**< port to enable multiplexer */ #define MUX_EN_PIN 9 /**< pin to enable multiplexer */ #define MUX_S0_PORT B /**< port to select multiplexer output */ @@ -281,7 +287,7 @@ void main(void) usart_setup(); // setup USART for user communication cdcacm_setup(); // setup USB ACM (serial) for user communication gpio_primary_remap(AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON,0); // disable JTAG (but leave SWD on) since we need most of the GPIOs - printf("welcome to the CuVoodoo clapperboard\n"); // print welcome message + printf("\nwelcome to the CuVoodoo clapperboard\n"); // print welcome message #if !(DEBUG) // show watchdog information @@ -394,6 +400,28 @@ void main(void) timer_enable_counter(TIM(FRAME_TIMER)); // enable timer to start counting frames printf("OK\n"); + // setup PWM for piezo-buzzer + printf("setup piezo-buzzer timer: "); + rcc_periph_clock_enable(RCC_GPIO(BUZZER_1_PORT)); // enable clock for GPIO peripheral + rcc_periph_clock_enable(RCC_AFIO); // enable clock for alternate function (PWM) + gpio_primary_remap(AFIO_MAPR_SWJ_MASK, AFIO_MAPR_TIM1_REMAP_PARTIAL_REMAP); // remap TIM1_CH1N to PA7 instead of PB13 + gpio_set_mode(GPIO(BUZZER_1_PORT), GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO(BUZZER_1_PIN)); // set pin as output to have a PWM to driver piezo buzzer + rcc_periph_clock_enable(RCC_GPIO(BUZZER_2_PORT)); // enable clock for GPIO peripheral + gpio_set_mode(GPIO(BUZZER_2_PORT), GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO(BUZZER_2_PIN)); // set pin as output to have a PWM to driver piezo buzzer + rcc_periph_clock_enable(RCC_TIM(BUZZER_TIMER)); // enable clock for timer peripheral + timer_reset(TIM(BUZZER_TIMER)); // reset timer state + timer_set_mode(TIM(BUZZER_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(BUZZER_TIMER), 0); // no prescaler to keep most precise timer (72MHz/2^16=1099<2kHz) + timer_set_period(TIM(BUZZER_TIMER), rcc_ahb_frequency/2000-1); // set the PWM frequency to 2kHz for piezo-buzzer + timer_set_oc_value(TIM(BUZZER_TIMER), TIM_OC1, rcc_ahb_frequency/2000/2-1); // duty cycle to 50% (also applies to TIM_OC1N) + // no preload is used, although the reference manual says to enable it + timer_set_oc_mode(TIM(BUZZER_TIMER), TIM_OC1, TIM_OCM_PWM1); // set timer to generate PWM (also applies to TIM_OC1N) + timer_enable_oc_output(TIM(BUZZER_TIMER), TIM_OC1); // enable output to generate PWM + timer_enable_oc_output(TIM(BUZZER_TIMER), TIM_OC1N); // enable output to generate PWM (complementary to be louder) + timer_enable_break_main_output(TIM(BUZZER_TIMER)); // enable master output + timer_generate_event(TIM(BUZZER_TIMER), TIM_EGR_UG); // generate update event to reload registers and reset counter + printf("OK\n"); + // main loop printf("command input: ready\n"); bool action = false; // if an action has been performed don't go to sleep @@ -431,15 +459,6 @@ void main(void) } } } - while (button_flag) { // user pressed button - action = true; // action has been performed - printf("button pressed\n"); - led_toggle(); // toggle LED - for (uint32_t i=0; i<1000000; i++) { // wait a bit to remove noise and double trigger - __asm__("nop"); - } - button_flag = false; // reset flag - } while (frame_flag) { // a frame has passed frame_flag = false; // reset flag action = true; // action has been performed @@ -465,6 +484,11 @@ void main(void) rtc_tick_flag = false; // reset flag action = true; // action has been performed led_toggle(); // toggle LED (good to indicate if main function is stuck) + if (rtc_seconds%2) { + timer_enable_counter(TIM(BUZZER_TIMER)); // start buzzing + } else { + timer_disable_counter(TIM(BUZZER_TIMER)); // start buzzing + } if (standby_timer>=STANDBY_TIMEOUT) { // standby timeout complete // go into standby mode printf("shutting down\n");