27 #include <libopencmsis/core_cm3.h> 28 #include <libopencm3/cm3/scb.h> 29 #include <libopencm3/cm3/nvic.h> 30 #include <libopencm3/stm32/gpio.h> 31 #include <libopencm3/stm32/rcc.h> 32 #include <libopencm3/stm32/exti.h> 33 #include <libopencm3/stm32/rtc.h> 34 #include <libopencm3/stm32/iwdg.h> 35 #include <libopencm3/stm32/dbgmcu.h> 36 #include <libopencm3/stm32/flash.h> 37 #include <libopencm3/stm32/timer.h> 48 #define WATCHDOG_PERIOD 10000 53 volatile bool rtc_tick_flag = false; 54 volatile bool frame_flag = false; 55 volatile bool keep_alive_flag = false; 56 volatile bool clap_flag = false; 59 #define POWER_SWITCH_PORT B 60 #define POWER_SWITCH_PIN 8 61 #define POWER_BUTTON_PORT B 62 #define POWER_BUTTON_PIN 1 64 #define SQUARE_WAVE_PORT B 65 #define SQUARE_WAVE_PIN 0 66 volatile uint8_t rtc_seconds = 0; 68 #define STANDBY_TIMEOUT 30 69 volatile uint16_t standby_timer = 0; 73 volatile uint8_t frame_count = 0; 75 #define BUZZER_TIMER 1 76 #define BUZZER_1_PORT A 77 #define BUZZER_1_PIN 7 78 #define BUZZER_2_PORT A 79 #define BUZZER_2_PIN 8 107 #define BUTTON_SECONDS_UP 9 108 #define BUTTON_SECONDS_DOWN 13 110 // buttons to adjust numbers and seconds (mutliplexed in a 4x4 matrix) 111 #define BUTTONS_DRIVE_PORT A 112 #define BUTTONS_DRIVE_PIN0 0 113 #define BUTTONS_DRIVE_PIN1 1 114 #define BUTTONS_DRIVE_PIN2 2 115 #define BUTTONS_DRIVE_PIN3 3 116 #define BUTTONS_READ_PORT A 117 #define BUTTONS_READ_PIN0 4 118 #define BUTTONS_READ_PIN1 5 119 #define BUTTONS_READ_PIN2 6 120 #define BUTTONS_READ_PIN3 15 122 #define CLAP_BUTTON_PORT B 123 #define CLAP_BUTTON_PIN 14 127 uint8_t morse[2*4*5*2] = {0}; 129 int16_t morse_delay = -1; 132 static char command[32] = {0}; 139 static char newline = 0;
142 }
else if (
'\r' == c ||
'\n' == c) {
143 if (0==newline || c==newline) {
168 const char* delimiter =
" ";
169 char* word = strtok(str,delimiter);
174 if (0==strcmp(word,
"help")) {
175 printf(
"available commands:\n");
176 printf(
"led [on|off|toggle]\n");
177 printf(
"time [HH:MM:SS]\n");
178 printf(
"date [YYYY-MM-DD]\n");
179 }
else if (0==strcmp(word,
"led")) {
180 word = strtok(NULL,delimiter);
183 }
else if (0==strcmp(word,
"on")) {
185 printf(
"LED switched on\n");
186 }
else if (0==strcmp(word,
"off")) {
188 printf(
"LED switched off\n");
189 }
else if (0==strcmp(word,
"toggle")) {
195 }
else if (0==strcmp(word,
"time")) {
196 word = strtok(NULL,delimiter);
199 }
else if (strlen(word)!=8 || word[0]<
'0' || word[0]>
'2' || word[1]<
'0' || word[1]>
'9' || word[3]<
'0' || word[3]>
'5' || word[4]<
'0' || word[4]>
'9' || word[6]<
'0' || word[6]>
'5' || word[7]<
'0' || word[7]>
'9') {
203 printf(
"setting hours failed\n");
205 printf(
"setting minutes failed\n");
207 printf(
"setting seconds failed\n");
213 }
else if (0==strcmp(word,
"date")) {
214 word = strtok(NULL,delimiter);
217 }
else if (strlen(word)!=10 || word[0]!=
'2' || word[1]!=
'0' || word[2]<
'0' || word[2]>
'9' || word[3]<
'0' || word[3]>
'9' || word[5]<
'0' || word[5]>
'1' || word[6]<
'0' || word[6]>
'9' || word[8]<
'0' || word[8]>
'3' || word[9]<
'0' || word[9]>
'9') {
221 printf(
"setting year failed\n");
223 printf(
"setting month failed\n");
225 printf(
"setting day failed\n");
236 printf(
"command not recognized. enter help to list commands\n");
299 uint16_t morse_numbers[] = {numbers[1].
number, numbers[2].
number};
300 printf(
"morsing scene: %u, take: %u\n", morse_numbers[0], morse_numbers[1]);
301 for (uint8_t morse_number=0; morse_number<
LENGTH(morse_numbers); morse_number++) {
302 bool not_zero =
false;
303 if (0xffff==morse_numbers[morse_number]) {
304 for (uint8_t i=morse_number*4*2*5; i<(morse_number+1)*4*2*5; i++) {
308 for (uint8_t digit=0; digit<4; digit++) {
309 uint16_t
number = morse_numbers[morse_number];
311 for (uint8_t divide=digit; divide<3; divide++) {
316 if (number!=0 || digit==3) {
329 morse[(morse_number*4+digit)*2*5+0] = 1*
MORSE_DOT;
330 morse[(morse_number*4+digit)*2*5+2] = 1*
MORSE_DOT;
331 morse[(morse_number*4+digit)*2*5+4] = 3*
MORSE_DOT;
332 morse[(morse_number*4+digit)*2*5+6] = 3*
MORSE_DOT;
333 morse[(morse_number*4+digit)*2*5+8] = 3*
MORSE_DOT;
336 morse[(morse_number*4+digit)*2*5+0] = 1*
MORSE_DOT;
337 morse[(morse_number*4+digit)*2*5+2] = 1*
MORSE_DOT;
338 morse[(morse_number*4+digit)*2*5+4] = 1*
MORSE_DOT;
339 morse[(morse_number*4+digit)*2*5+6] = 3*
MORSE_DOT;
340 morse[(morse_number*4+digit)*2*5+8] = 3*
MORSE_DOT;
343 morse[(morse_number*4+digit)*2*5+0] = 1*
MORSE_DOT;
344 morse[(morse_number*4+digit)*2*5+2] = 1*
MORSE_DOT;
345 morse[(morse_number*4+digit)*2*5+4] = 1*
MORSE_DOT;
346 morse[(morse_number*4+digit)*2*5+6] = 1*
MORSE_DOT;
347 morse[(morse_number*4+digit)*2*5+8] = 3*
MORSE_DOT;
350 morse[(morse_number*4+digit)*2*5+0] = 1*
MORSE_DOT;
351 morse[(morse_number*4+digit)*2*5+2] = 1*
MORSE_DOT;
352 morse[(morse_number*4+digit)*2*5+4] = 1*
MORSE_DOT;
353 morse[(morse_number*4+digit)*2*5+6] = 1*
MORSE_DOT;
354 morse[(morse_number*4+digit)*2*5+8] = 1*
MORSE_DOT;
357 morse[(morse_number*4+digit)*2*5+0] = 3*
MORSE_DOT;
358 morse[(morse_number*4+digit)*2*5+2] = 1*
MORSE_DOT;
359 morse[(morse_number*4+digit)*2*5+4] = 1*
MORSE_DOT;
360 morse[(morse_number*4+digit)*2*5+6] = 1*
MORSE_DOT;
361 morse[(morse_number*4+digit)*2*5+8] = 1*
MORSE_DOT;
364 morse[(morse_number*4+digit)*2*5+0] = 3*
MORSE_DOT;
365 morse[(morse_number*4+digit)*2*5+2] = 3*
MORSE_DOT;
366 morse[(morse_number*4+digit)*2*5+4] = 1*
MORSE_DOT;
367 morse[(morse_number*4+digit)*2*5+6] = 1*
MORSE_DOT;
368 morse[(morse_number*4+digit)*2*5+8] = 1*
MORSE_DOT;
371 morse[(morse_number*4+digit)*2*5+0] = 3*
MORSE_DOT;
372 morse[(morse_number*4+digit)*2*5+2] = 3*
MORSE_DOT;
373 morse[(morse_number*4+digit)*2*5+4] = 3*
MORSE_DOT;
374 morse[(morse_number*4+digit)*2*5+6] = 1*
MORSE_DOT;
375 morse[(morse_number*4+digit)*2*5+8] = 1*
MORSE_DOT;
378 morse[(morse_number*4+digit)*2*5+0] = 3*
MORSE_DOT;
379 morse[(morse_number*4+digit)*2*5+2] = 3*
MORSE_DOT;
380 morse[(morse_number*4+digit)*2*5+4] = 3*
MORSE_DOT;
381 morse[(morse_number*4+digit)*2*5+6] = 3*
MORSE_DOT;
382 morse[(morse_number*4+digit)*2*5+8] = 1*
MORSE_DOT;
386 morse[(morse_number*4+digit)*2*5+0] = 3*
MORSE_DOT;
387 morse[(morse_number*4+digit)*2*5+2] = 3*
MORSE_DOT;
388 morse[(morse_number*4+digit)*2*5+4] = 3*
MORSE_DOT;
389 morse[(morse_number*4+digit)*2*5+6] = 3*
MORSE_DOT;
390 morse[(morse_number*4+digit)*2*5+8] = 3*
MORSE_DOT;
392 morse[(morse_number*4+digit)*2*5+0] = 0;
393 morse[(morse_number*4+digit)*2*5+2] = 0;
394 morse[(morse_number*4+digit)*2*5+4] = 0;
395 morse[(morse_number*4+digit)*2*5+6] = 0;
396 morse[(morse_number*4+digit)*2*5+8] = 0;
401 for (uint8_t space=0; space<5; space++) {
402 if (0==
morse[(morse_number*4+digit)*2*5+space*2]) {
403 morse[(morse_number*4+digit)*2*5+space*2+1] = 0;
421 rcc_clock_setup_in_hse_8mhz_out_72mhz();
429 rcc_periph_clock_enable(RCC_AFIO);
437 DBGMCU_CR |= DBGMCU_CR_IWDG_STOP;
438 DBGMCU_CR |= DBGMCU_CR_WWDG_STOP;
439 DBGMCU_CR |= DBGMCU_CR_STANDBY;
440 DBGMCU_CR |= DBGMCU_CR_STOP;
441 DBGMCU_CR |= DBGMCU_CR_SLEEP;
451 gpio_primary_remap(AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON,0);
452 printf(
"\nwelcome to the CuVoodoo clapperboard\n");
457 if (FLASH_OBR&FLASH_OBR_OPTERR) {
458 printf(
"option bytes not set in flash: software wachtdog used (not started at reset)\n");
459 }
else if (FLASH_OBR&FLASH_OBR_WDG_SW) {
460 printf(
"software wachtdog used (not started at reset)\n");
462 printf(
"hardware wachtdog used (started at reset)\n");
467 printf(
"setup external RTC: ");
473 rcc_periph_clock_enable(RCC_AFIO);
482 printf(
"/!\\ RTC oscillator is disabled: the battery may be empty\n");
487 if (rtc_ds1307_time==NULL) {
488 printf(
"could not get time from DS1307\n");
491 printf(
"current date: 20%02u-%02u-%02u %02u:%02u:%02u\n", rtc_ds1307_time[6], rtc_ds1307_time[5], rtc_ds1307_time[4], rtc_ds1307_time[2], rtc_ds1307_time[1], rtc_ds1307_time[0]);
495 printf(
"setup multiplexer: ");
508 printf(
"setup 7-segment displays: ");
510 for (uint8_t tm1637=0; tm1637<
LENGTH(numbers); tm1637++) {
513 printf(
"could not test TM1637 %u\n", tm1637);
520 for (
volatile uint32_t i=0; i<10000000; i++);
522 for (uint8_t tm1637=0; tm1637<
LENGTH(numbers); tm1637++) {
525 printf(
"could not switch off TM1637 %u\n", tm1637);
534 uint8_t bytes[2] = {0};
536 printf(
"could not get number from EEPROM\n");
546 printf(
"%u\n", numbers[number].number);
552 led_max7219_number(20000000+rtc_ds1307_time[6]*10000+rtc_ds1307_time[5]*100+rtc_ds1307_time[4], 0x14, 0);
553 led_max7219_number(rtc_ds1307_time[2]*1000000+rtc_ds1307_time[1]*10000+rtc_ds1307_time[0]*100, 0x54, 1);
557 printf(
"setup frame timer: ");
560 timer_set_mode(
TIM(
FRAME_TIMER), TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
561 timer_set_prescaler(
TIM(
FRAME_TIMER), (rcc_ahb_frequency/0xffff+1)-1);
567 nvic_enable_irq(NVIC_TIM1_UP_IRQ);
576 printf(
"setup piezo-buzzer PWM timer: ");
578 rcc_periph_clock_enable(RCC_AFIO);
579 gpio_primary_remap(AFIO_MAPR_SWJ_MASK, AFIO_MAPR_TIM1_REMAP_PARTIAL_REMAP);
587 timer_set_mode(
TIM(
BUZZER_TIMER), TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
590 timer_set_oc_value(
TIM(
BUZZER_TIMER), TIM_OC1, rcc_ahb_frequency/4000/2-1);
600 printf(
"setup display buttons: ");
605 gpio_primary_remap(AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON, 0);
606 uint16_t buttons = 0;
609 printf(
"setup clap button: ");
613 rcc_periph_clock_enable(RCC_AFIO);
621 printf(
"command input: ready\n");
624 bool char_flag =
false;
643 if (c==
'\r' || c==
'\n') {
661 char time[] =
"00000000";
662 time[0] += (rtc_ds1307_time[2]/10)%10;
663 time[1] += (rtc_ds1307_time[2])%10;
665 time[2] += (rtc_ds1307_time[1]/10)%10;
666 time[3] += (rtc_ds1307_time[1])%10;
704 uint16_t buttons_new = 0;
741 uint16_t buttons_diff = buttons^buttons_new;
742 buttons = buttons_new;
749 }
else if (buttons&(1<<numbers[
number].up) && buttons_diff&(1<<numbers[
number].
up)) {
760 }
else if (0==numbers[number].number) {
776 printf(
"could not set number on EEPROM\n");
782 if (rtc_ds1307_time==NULL) {
783 printf(
"could not get time from DS1307: resetting\n");
789 if (!(23==rtc_ds1307_time[2] && 59==rtc_ds1307_time[1] && 59==rtc_ds1307_time[0])) {
790 rtc_ds1307_time[0] += 1;
791 while (rtc_ds1307_time[0]>=60) {
792 rtc_ds1307_time[0] -= 60;
793 rtc_ds1307_time[1] += 1;
795 while (rtc_ds1307_time[1]>=60) {
796 rtc_ds1307_time[1] -= 60;
797 rtc_ds1307_time[2] += 1;
799 while (rtc_ds1307_time[2]>=24) {
800 rtc_ds1307_time[2] -= 24;
805 if (!(0==rtc_ds1307_time[2] && 0==rtc_ds1307_time[1] && 0==rtc_ds1307_time[0])) {
806 if (rtc_ds1307_time[0]>0) {
807 rtc_ds1307_time[0] -= 1;
809 rtc_ds1307_time[0] = 59;
810 if (rtc_ds1307_time[1]>0) {
811 rtc_ds1307_time[1] -= 1;
813 rtc_ds1307_time[1] = 59;
814 rtc_ds1307_time[2] -= 1;
820 if (!
rtc_ds1307_write_time(rtc_ds1307_time[0], rtc_ds1307_time[1], rtc_ds1307_time[2], rtc_ds1307_time[3], rtc_ds1307_time[4], rtc_ds1307_time[5], rtc_ds1307_time[6])) {
821 printf(
"could not set time on DS1307: resetting\n");
835 printf(
"shutting down\n");
839 uint8_t bytes[
LENGTH(numbers)*2] = {0};
849 printf(
"could not set numbers on EEPROM\n");
852 for (uint8_t tm1637=0; tm1637<7; tm1637++) {
859 SCB_SCR |= SCB_SCR_SLEEPDEEP;
860 pwr_set_standby_mode();
865 if (rtc_ds1307_time==NULL) {
866 printf(
"could not get time from DS1307: resetting\n");
870 if (0==rtc_ds1307_time[1] && 0==rtc_ds1307_time[2]) {
871 led_max7219_number(20000000+rtc_ds1307_time[6]*10000+rtc_ds1307_time[5]*100+rtc_ds1307_time[4], 0x14, 0);
911 void tim1_up_isr(
void)
number to be display and changed using the buttons
void board_setup(void)
setup board peripherals
#define FRAME_TIMER
timer to count frame time
uint8_t morse[2 *4 *5 *2]
to encode 2 4-digit numbers (scene and take) into Morse code (5 sign+space)
bool led_tm1637_number(uint16_t number)
display number
bool rtc_ds1307_write_date(uint8_t date)
write date into RTC IC
#define TIM_ISR(x)
get interrupt service routine for timer base on TIM identifier
size_t putc(char c)
print a single character on user output
volatile uint8_t frame_count
number of frames passed
void rtc_ds1307_setup(void)
setup communication with RTC IC configure the I2C port defined in the sources
bool rtc_ds1307_write_time(uint8_t seconds, uint8_t minutes, uint8_t hours, uint8_t day, uint8_t date, uint8_t month, uint8_t year)
write time into RTC IC
volatile bool usart_received
how many bytes available in the received buffer since last read
#define MUX_S2_PIN
pin to select multiplexer output
void cdcacm_putchar(char c)
send character over USB (non-blocking)
bool rtc_ds1307_write_rom(uint16_t start, uint8_t *data, uint8_t length)
write to ROM on AT24Cxx EEPROM
struct number_t numbers[]
episode, scene, take, video 1, audio 1, video 2, audio 2 number (in this order)
static char command[32]
user input command
bool rtc_ds1307_write_year(uint8_t year)
write year into RTC IC
#define RCC_GPIO(x)
get RCC for GPIO based on GPIO identifier
#define FRAME_RATE
frame rate in frames per second
volatile bool keep_alive_flag
flag to restart shutdown counter on power switch activity
void led_max7219_setup(uint8_t displays)
setup communication with MAX7219 IC
bool rtc_ds1307_oscillator_enable(void)
enable RTC IC oscillator
bool rtc_ds1307_write_month(uint8_t month)
write month into RTC IC
#define POWER_BUTTON_PORT
port to detect power switching activity by shaking (to keep alive)
void led_off(void)
switch off board LED
bool rtc_ds1307_write_minutes(uint8_t minutes)
write minutes into RTC IC
#define BUTTONS_READ_PIN2
pin used to read buttons column 2
#define NVIC_TIM_IRQ(x)
get NVIC IRQ for timer base on TIM identifier
#define BUTTONS_DRIVE_PIN0
pin used to drive buttons row 0
uint8_t up
which of the 16 buttons is to increment the number
bool led_max7219_text(char *text, uint8_t display)
display text
library to communicate with a Titan Micro TM1637 IC attached to a 7-segment displays (API) ...
uint16_t number
number to display (0-9999, 0xffff=off)
#define WATCHDOG_PERIOD
watchdog period in ms
static void process_command(char *str)
process user command
#define BUTTONS_DRIVE_PIN3
pin used to drive buttons row 3
#define NVIC_EXTI_IRQ(x)
get NVIC IRQ for external interrupt base on external interrupt/pin
#define MUX_S1_PORT
port to select multiplexer output
#define CLAP_BUTTON_PIN
port for button to detect clap action
#define MUX_EN_PIN
pin to enable multiplexer
#define BUTTONS_READ_PIN0
pin used to read buttons column 0
global definitions and methods (API)
#define STANDBY_TIMEOUT
number of seconds after last shake before going down
#define GPIO(x)
get GPIO based on GPIO identifier
#define POWER_BUTTON_PIN
pin to detect power switching activity by shaking (to keep alive)
volatile uint8_t rtc_seconds
number of seconds passed, incremented by the square wave
#define MORSE_DOT
Morse code variables, to buzz/beep scene and take.
#define BUTTONS_DRIVE_PIN1
pin used to drive buttons row 1
#define SQUARE_WAVE_PIN
pin connected to RTC DS1307 square wave output
void cdcacm_setup(void)
setup USB CDC ACM peripheral
#define BUZZER_TIMER
timer to generate scene and take count
#define BUZZER_2_PIN
use timer channel 1 (and it's negative) to driver buzzer
#define RCC_TIM(x)
get RCC for timer based on TIM identifier
uint8_t rtc_ds1307_read_month(void)
read month from RTC IC
#define MUX_EN_PORT
port to enable multiplexer
void led_max7219_test(bool test, uint8_t display)
switch display in test or normal operation mode
int16_t morse_delay
number of frames before beeping (-1=no need to beep yet, -2=beeping completed)
#define POWER_SWITCH_PORT
port to switch power of all devices (including this micro-controller)
#define BUTTONS_READ_PIN3
pin used to read buttons column 3
volatile bool frame_flag
flag set when a frame has passed
#define BUZZER_1_PIN
use timer channel 1 (and it's negative) to driver buzzer
uint8_t rtc_ds1307_read_year(void)
read year from RTC IC
uint8_t * rtc_ds1307_read_time(void)
read time from RTC IC
uint8_t display
which display on the channel multiplexer
volatile bool clap_flag
flag set on clap
#define BUTTONS_DRIVE_PORT
port used to drive the buttons rows
uint8_t rtc_ds1307_read_seconds(void)
read seconds from RTC IC
#define MUX_S0_PIN
pin to select multiplexer output
volatile uint8_t cdcacm_received
how many bytes available in the received buffer since last read
#define CLAP_BUTTON_PORT
port for button to detect clap action
uint8_t command_i
user input command index
#define EXTI(x)
get external interrupt based on pin identifier
#define MUX_S0_PORT
port to select multiplexer output
void led_max7219_on(uint8_t display)
switch display on
void led_max7219_number(uint32_t number, uint8_t dots, uint8_t display)
display number
bool rtc_ds1307_write_hours(uint8_t hours)
write hours into RTC IC
uint8_t rtc_ds1307_read_date(void)
read date from RTC IC
#define SQUARE_WAVE_PORT
port connected to RTC DS1307 square wave output
bool rtc_ds1307_write_seconds(uint8_t seconds)
write seconds into RTC IC
void usart_putchar_nonblocking(char c)
send character over USART (non-blocking)
bool rtc_ds1307_read_rom(uint16_t start, uint8_t *data, uint16_t length)
read ROM from AT24Cxx EEPROM
#define BUTTON_SECONDS_DOWN
which of the 16 buttons is to decrement the seconds
volatile bool rtc_tick_flag
flag set when RTC ticked
#define POWER_SWITCH_PIN
pin to switch power of all devices (including this micro-controller)
static void mux_select(uint8_t output)
select clock output for TM1637 display using the analog multiplexer
#define MUX_S2_PORT
port to select multiplexer output
#define EXTI_ISR(x)
get interrupt service routine for timer base on external interrupt/pin
library for USART communication (API)
void led_tm1637_setup(void)
setup communication with TM1637 IC
#define BUTTONS_READ_PORT
port used to read the buttons columns
size_t printf(const char *format,...)
print format string on user output
#define BUTTON_SECONDS_UP
which of the 16 buttons is to increment the seconds
void led_max7219_off(uint8_t display)
switch display off
printing utilities to replace the large printf from the standard library (API)
#define BUTTONS_READ_PIN1
pin used to read buttons column 1
#define BUTTONS_DRIVE_PIN2
pin used to drive buttons row 2
void led_max7219_intensity(uint8_t intensity, uint8_t digits, uint8_t display)
set display intensity
bool led_tm1637_off(void)
switch display on
char usart_getchar(void)
get character received over USART (blocking)
library for USB CDC ACM communication (API)
library to communicate with a Maxim MAX7219 IC attached to a 8-digit 7-segment (API) ...
#define LENGTH(x)
get the length of an array
static void encode_morse(void)
encode scene and take into Morse code (in morse variable)
bool led_tm1637_time(uint8_t hours, uint8_t minutes)
display time
#define TIM(x)
get TIM based on TIM identifier
uint8_t morse_i
index in Morse array
void led_toggle(void)
toggle board LED
uint8_t down
which of the 16 buttons is to decrement the number
bool rtc_ds1307_oscillator_disabled(void)
verify if oscillator is disabled
library to communicate with the Maxim DS1307 I2C RTC IC (API)
volatile uint16_t standby_timer
number of seconds since last power-up activity (using shake sensor)
bool rtc_ds1307_write_square_wave(uint16_t frequency)
write square wave output frequency (in Hz)
void main(void)
program entry point this is the firmware function started by the micro-controller ...
#define MUX_S1_PIN
pin to select multiplexer output
void usart_setup(void)
setup USART peripheral
uint8_t rtc_ds1307_read_hours(void)
read hours from RTC IC
void led_on(void)
switch on board LED
char cdcacm_getchar(void)
get character received over USB (blocking)
#define BUZZER_1_PORT
use timer channel 1 (and it's negative) to driver buzzer
#define BUZZER_2_PORT
use timer channel 1 (and it's negative) to driver buzzer
uint8_t rtc_ds1307_read_minutes(void)
read minutes from RTC IC