-
Notifications
You must be signed in to change notification settings - Fork 0
/
display.c
110 lines (94 loc) · 2.29 KB
/
display.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/*
* Copyright (C) 2017 Piotr Janczyk
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*/
#include "display.h"
#include <avr/pgmspace.h>
#include <stdbool.h>
volatile uint8_t display_port[4] = { 0, 0, 0, 0 };
volatile bool display_blink = false;
/**
* Display connection:
*
* Anodes:
* left digit, green - PC0
* right digit, green - PC1
* left digit, red - PC2
* right digit, red - PC3
*
* Cathodes:
* A - PD2
* B - PD3
* C - PD6
* D - PD5
* E - PD4
* F - PD1
* G - PD7
* DOT - PD0
*/
static const uint8_t PROGMEM DISPLAY_DIGIT_SEGMENTS[13] = {
0x7E, // 0
0x48, // 1
0xBC, // 2
0xEC, // 3
0xCA, // 4
0xE6, // 5
0xF6, // 6
0x4E, // 7
0xFE, // 8
0xEE, // 9
0x00, // empty
0xB6, // E (used to display "Er")
0x90, // r (used to display "Er")
};
static inline uint8_t abs8(int8_t v) {
if (v < 0) {
return -v;
} else {
return v;
}
}
void display_routine(void) {
static uint8_t current_digit = 0;
static uint8_t blink_counter = 0;
blink_counter = (blink_counter + 1) % 256;
current_digit = (current_digit + 1) % 6;
PORTD = 0xff;
if (!display_blink || blink_counter >= 64) {
PORTC = 1 << (current_digit % 4);
PORTD = ~display_port[current_digit % 4];
}
}
void display_show_number(int8_t number, uint8_t flags) {
uint8_t absolute = abs8(number);
uint8_t d1;
uint8_t d2;
if (number >= -9 && number <= 9) {
d1 = absolute % 10;
d2 = 10; // empty
} else if (number >= -99 && number <= 99) {
d1 = absolute % 10;
d2 = absolute / 10;
} else {
d1 = 12; // R
d2 = 11; // e
}
uint8_t minus_sign = (number < 0) ? 1 : 0;
d1 = pgm_read_byte(&DISPLAY_DIGIT_SEGMENTS[d1]);
d2 = pgm_read_byte(&DISPLAY_DIGIT_SEGMENTS[d2]) | minus_sign;
display_port[0] = (flags & DISPLAY_FLAG_GREEN) ? d2 : 0;
display_port[1] = (flags & DISPLAY_FLAG_GREEN) ? d1 : 0;
display_port[2] = (flags & DISPLAY_FLAG_RED) ? d2 : 0;
display_port[3] = (flags & DISPLAY_FLAG_RED) ? d1 : 0;
display_blink = (flags & DISPLAY_FLAG_BLINK);
}
void display_show_nothing(void) {
display_port[0] = 0;
display_port[1] = 0;
display_port[2] = 0;
display_port[3] = 0;
}