binaryalarmclock/software/main.c

181 lines
4.2 KiB
C

#include <avr/io.h>
#include <avr/interrupt.h>
#include "common.h"
#include "dcftime.h"
#include "display.h"
#include "utils.h"
#define BRIGHTNESS 8
#define KEY_PRESS_THRESHOLD 100
#define MAX_DISPLAY_MODE 2
int main(void) {
TCCR1B |= _BV(WGM12) | _BV(CS11) | _BV(CS10) ; // CTC Mode for Timer 1 (16Bit) with prescale of 64
OCR1A = 250; // Dataload 250
TIMSK = _BV(OCIE1A);
// LED PINs as output
LEDS_DDR = _BV(LEDS_LED1) | _BV(LEDS_LED2) | _BV(LEDS_LED3);
// Display PINs as output
D_DDR = _BV(D_CLK) | _BV(D_STR) | _BV(D_D1) | _BV(D_D2) | _BV(D_D3) | _BV(D_D4);
// All pins low
D_PORT = 0;
// DCF PIN as Input
DCF_DDR &= ~_BV(DCF_INPUT);
// KEY PORTS as Input
KEYS_DDR &= ~( _BV(KEYS_KEY1) | _BV(KEYS_KEY2) | _BV(KEYS_KEY3) | _BV(KEYS_KEY4) );
KEYS_PORT |= _BV(KEYS_KEY1) | _BV(KEYS_KEY2) | _BV(KEYS_KEY3) | _BV(KEYS_KEY4);
// Switch LEDs off
LEDS_PORT &= ~( _BV(LEDS_LED1) | _BV(LEDS_LED2) | _BV(LEDS_LED3) );
/* show display check */
checkUpDisplay();
/* initialize DCF77 */
dcf_init();
/* enable interrupts */
sei();
while(1){
}
return(0);
}
SIGNAL(TIMER1_COMPA_vect) {
static uint8_t counter = 0;
static uint8_t brightnessCounter = 0;
static uint8_t ticker = 0;
static uint8_t data[] = {0,0,0,0};
static uint8_t displayMode = 0;
static uint8_t displayDateMode = 0;
static uint8_t displaySwitchCounter =0;
static uint8_t keyOnePressed = 0, keyTwoPressed = 0, keyThreePressed = 0;
static uint8_t keyOneCounter = 0, keyTwoCounter = 0, keyThreeCounter = 0;
static dcf_datetime datetime = { .is_valid=False }; /** takes the current time and date */
ticker++;
if((KEYS_PIN & _BV(KEYS_KEY1)) == 0 ){
if(keyOneCounter < KEY_PRESS_THRESHOLD) {
keyOneCounter++;
}
}
else{
if(keyOneCounter != 0){
keyOneCounter--;
}
}
if((KEYS_PIN & _BV(KEYS_KEY3)) == 0 ){
if(keyThreeCounter < KEY_PRESS_THRESHOLD) {
keyThreeCounter++;
}
}
else{
if(keyThreeCounter != 0){
keyThreeCounter--;
}
}
keyOnePressed = keyOneCounter + 50 >= KEY_PRESS_THRESHOLD;
keyTwoPressed = keyTwoCounter + 50 >= KEY_PRESS_THRESHOLD;
keyThreePressed = keyThreeCounter + 50 >= KEY_PRESS_THRESHOLD;
if( counter == 4 ){
counter=0;
dcf_signal(DCF_PIN & _BV(DCF_INPUT));
}
else{
counter++;
}
if(ticker == 250){
ticker = 0;
datetime = dcf_current_datetime();
if(keyOnePressed & !(keyTwoCounter || keyThreePressed)){
if(displayMode > 0){
displayMode--;
}
else{
displayMode = MAX_DISPLAY_MODE;
}
}
if(keyThreePressed & !(keyOneCounter || keyTwoPressed)){
if(displayMode < MAX_DISPLAY_MODE){
displayMode++;
}
else{
displayMode = 0;
}
}
switch(displayMode){
case 0:
convertTime((uint8_t)datetime.time.hour, (uint8_t)datetime.time.minute, (uint8_t)datetime.time.second,data);
displayDateMode = 0;
displaySwitchCounter = 0;
break;
case 1:
convertTime((uint8_t)datetime.date.dayofmonth, (uint8_t)datetime.date.month, (uint8_t)datetime.date.year,data);
displayDateMode = 0;
displaySwitchCounter = 0;
break;
case 2:
data[0] = (uint8_t)datetime.time.hour;
data[1] = (uint8_t)datetime.time.minute;
data[2] = (uint8_t)datetime.time.second,data;
if(displaySwitchCounter == 20 ){
displaySwitchCounter = 0;
if(displayDateMode == 3){
displayDateMode = 0;
}
else{
displayDateMode++;
}
}
else{
displaySwitchCounter++;
}
switch(displayDateMode){
case 0: data[3] = 63;
break;
case 1: data[3] = datetime.date.dayofmonth;
break;
case 2: data[3] = datetime.date.month;
break;
case 3: data[3] = datetime.date.year;
break;
}
break;
}
}
if( datetime.is_valid ){
if(brightnessCounter == BRIGHTNESS){
ShowNumber(data[0], data[1], data[2], data[3]);
}
else{
ShowNumber(0,0,0,0);
}
}
else{
waitForSignal(500);
}
if(brightnessCounter == BRIGHTNESS){
brightnessCounter = 0;
LEDS_PORT |= (( (DCF_PIN & _BV(DCF_INPUT)) >> DCF_INPUT) << LEDS_LED2);
}
else{
LEDS_PORT &= ~( _BV(LEDS_LED1) | _BV(LEDS_LED2) | _BV(LEDS_LED3) );
brightnessCounter++;
}
}
// vim:ts=4