diff options
| -rw-r--r-- | src/display.c | 101 | ||||
| -rw-r--r-- | src/display.h | 32 | ||||
| -rw-r--r-- | src/main.c | 5 |
3 files changed, 79 insertions, 59 deletions
diff --git a/src/display.c b/src/display.c index 6baa27a..271d6a3 100644 --- a/src/display.c +++ b/src/display.c @@ -3,18 +3,9 @@ #include <stdint.h> #include <util/delay.h> -#include "button.h" #include "display.h" #include "rtc.h" -// "_gfedcba" -// Reversed because a-g is mapped to pa0-6. (pa7 is decimal) -// Complemented because display is common anode -const uint32_t digit_masks[] = { - 0b1000000, 0b1111001, 0b0100100, 0b0110000, 0b0011001, - 0b0010010, 0b0000010, 0b1111000, 0b0000000, 0b0010000, -}; - void display_setup() { // Set prescaler CS01 + CS00 (F_CPU / 64) + CTC // For 32768Hz -> 32768/64 = 512Hz @@ -36,70 +27,66 @@ void display_setup() { } volatile uint8_t current_digit = 0; -#define TOTAL_DIGITS 4 // Render current digit void display_render(void) { - // button_tick(); // Check button click - write_time(minutes, seconds, current_digit); // Cycle through the 4 digits - current_digit = (current_digit + 1) % TOTAL_DIGITS; + current_digit = (current_digit + 1) % 4; } -inline uint32_t get_digit(uint8_t digit) { - return digit_masks[digit]; // digit % 10 -} +// TODO: Wtf. Fix the names + +#define DSEGMENT_1 6 +#define DSEGMENT_MASK_1 ((1 << 6) | (1 << 7)) +#define DSEGMENT_2 5 +#define DSEGMENT_MASK_2 ((1 << 5) | (1 << 10)) + +#define ALL_DUAL_PURPOSE_PINS (DSEGMENT_MASK_1 | DSEGMENT_MASK_2) + +uint8_t dual_purpose_pins[] = {6, 7, 5, 10}; +uint8_t dual_purpose_antipins[] = {7, 6, 10, 5}; void write_time(uint16_t hour, uint16_t minute, uint8_t digit_index) { - uint8_t minute_digit1 = minute % 10; - uint8_t minute_digit2 = (minute / 10) % 10; - // unsigned short hour_digit1 = hour % 10; - // unsigned short hour_digit2 = (hour / 10) % 10; + // reset pins + uint32_t ddr = ~ALL_DUAL_PURPOSE_PINS; + uint32_t port = 0; + + uint8_t digit = get_digit(hour, minute, digit_index); + uint32_t segments = get_digit_mask(digit); + uint8_t pin = dual_purpose_pins[digit_index]; + uint8_t antipin = dual_purpose_antipins[digit_index]; + uint8_t segment_pin = digit_index / 2 == 0 ? DSEGMENT_1 : DSEGMENT_2; + uint8_t other_segment_pin = digit_index / 2 == 0 ? DSEGMENT_2 : DSEGMENT_1; + uint8_t other_segment_mask = + digit_index / 2 == 0 ? DSEGMENT_MASK_2 : DSEGMENT_MASK_1; - // reset pins (all output except PA7,PB2) - uint16_t ddra = ~((1 << PA7)); - uint16_t ddrb = ~((1 << PB2)); - uint16_t porta = 0; - uint16_t portb = 0; + port = segments; - if (digit_index == 0 || digit_index == 2) { - uint32_t segments = get_digit(minute_digit1); - porta = segments; - ddra |= (1 << PA7); - porta |= (1 << PA7); - if (segments & (1 << 6)) { - // If seg inactive, enable other input and enable pull up res - ddrb &= ~(1 << PB2); - portb |= (1 << PB2); - } else { - // If seg active, enable other output and set to 0 - ddrb |= (1 << PB2); - portb &= ~(1 << PB2); - } + // Activate dual purpose segment + ddr |= (1 << pin); + port |= (1 << pin); + if (segments & (1 << segment_pin)) { + // If seg inactive, enable other input and enable pull up res + ddr &= ~(1 << antipin); + port |= (1 << antipin); + } else { + // If seg active, enable other output and set to 0 + ddr |= (1 << antipin); + port &= ~(1 << antipin); } - if (digit_index == 1 || digit_index == 3) { - uint32_t segments = get_digit(minute_digit2); - porta = segments; - ddrb |= (1 << PB2); - portb |= (1 << PB2); - if (segments & (1 << 6)) { - // If seg inactive, enable other input and enable pull up res - ddra &= ~(1 << PA7); - porta |= (1 << PA7); - } else { - // If seg active, enable other output and set to 0 - ddra |= (1 << PA7); - porta &= ~(1 << PA7); - } + // Activate other dual purpose segment + if ((segments & (1 << other_segment_pin)) == 0) { + ddr |= other_segment_mask; + port &= ~other_segment_mask; } // cli(); - DDRA = ddra; - DDRB = ddrb; - PORTA = porta; - PORTB = portb; + DDRA = ddr; + DDRB = ddr >> 8; + PORTA = port; + PORTB = port >> 8; // sei(); } diff --git a/src/display.h b/src/display.h index 5c03ee4..c410731 100644 --- a/src/display.h +++ b/src/display.h @@ -2,11 +2,41 @@ #define _LOADED_DISPLAY #include <stdint.h> +// "_gfedcba" +// Reversed because a-g is mapped to pa0-6. (pa7 is decimal) +// Complemented because display is common anode +static const uint32_t digit_masks[] = { + 0b1000000, 0b1111001, 0b0100100, 0b0110000, 0b0011001, + 0b0010010, 0b0000010, 0b1111000, 0b0000000, 0b0010000, +}; + volatile extern uint8_t current_digit; void display_setup(void); -void write_time(uint16_t hour, uint16_t minute, uint8_t digit_mask); +static inline uint32_t get_digit_mask(uint8_t digit) { + return digit_masks[digit % 10]; +} + +static inline uint8_t get_digit(uint16_t hour, uint16_t minute, + uint8_t digit_index) { + // TODO: use hour + // uint8_t hour_digit1 = hour % 10; + // uint8_t hour_digit2 = (hour / 10) % 10; + switch (digit_index) { + case 0: + return minute % 10; + case 1: + return (minute / 10) % 10; + case 2: + return (minute % 10) + 1; + case 3: + return ((minute / 10) % 10) + 1; + } + return 0; +} + +void write_time(uint16_t hour, uint16_t minute, uint8_t digit_index); void display_render(void); @@ -19,7 +19,10 @@ FUSES = { // Display interrupt // Timer 0 has lower priority than timer 1, so some ticks could get skipped on // interrupt starvation -ISR(TIM0_COMPA_vect, ISR_FLATTEN) { display_render(); } +ISR(TIM0_COMPA_vect, ISR_FLATTEN) { + // button_tick(); // Check button click + display_render(); +} // RTC interrupt ISR(TIM1_COMPA_vect, ISR_FLATTEN) { rtc_increment(); } |
