aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/display.c101
-rw-r--r--src/display.h32
-rw-r--r--src/main.c5
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);
diff --git a/src/main.c b/src/main.c
index 6f621af..11ad99f 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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(); }