You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
146 lines
3.5 KiB
146 lines
3.5 KiB
/**
|
|
* TODO file description
|
|
*/
|
|
|
|
#include <avr/pgmspace.h>
|
|
#include "sevenseg.h"
|
|
#include "ssd1306.h"
|
|
|
|
|
|
void sseg_home(struct SevenSeg *disp) {
|
|
disp->x = 0;
|
|
}
|
|
|
|
enum SevenSegBars {
|
|
T=1, RT=2, RB=4, B=8, LB=16, LT=32, M=64
|
|
};
|
|
|
|
static const uint8_t PROGMEM seven[] = {
|
|
[0] = T|RT|RB|B|LB|LT,
|
|
[1] = RT|RB,
|
|
[2] = T|RT|M|LB|B,
|
|
[3] = T|RT|M|RB|B,
|
|
[4] = RT|RB|M|LT,
|
|
[5] = T|LT|M|RB|B,
|
|
[6] = T|LT|LB|B|RB|M,
|
|
[7] = T|RT|RB,
|
|
[8] = T|LT|RT|LB|RB|B|M,
|
|
[9] = T|LT|RT|RB|B|M,
|
|
};
|
|
|
|
static void draw_7seg_dig(uint8_t x, uint8_t y, uint8_t w, uint8_t th, uint8_t digit) {
|
|
uint8_t mask = digit == 255 ? 0 : pgm_read_byte(&seven[digit]);
|
|
|
|
const uint8_t v = w - th * 2;
|
|
const uint8_t subs = 1;
|
|
|
|
ssd1306_setColor((mask & T) ? 0xFFFF : 0);
|
|
ssd1306_fillRect(
|
|
x + th,
|
|
y + 0,
|
|
x + th + v - subs,
|
|
y + th - subs);
|
|
|
|
ssd1306_setColor((mask & M) ? 0xFFFF : 0);
|
|
ssd1306_fillRect(
|
|
x + th,
|
|
y + th + v,
|
|
x + th + v - subs,
|
|
y + th * 2 + v - subs);
|
|
|
|
ssd1306_setColor((mask & B) ? 0xFFFF : 0);
|
|
ssd1306_fillRect(
|
|
x + th,
|
|
y + th * 2 + v * 2,
|
|
x + th + v - subs,
|
|
y + th * 3 + v * 2 - subs);
|
|
|
|
ssd1306_setColor((mask & LT) ? 0xFFFF : 0);
|
|
ssd1306_fillRect(
|
|
x + 0,
|
|
y + th,
|
|
x + th - subs,
|
|
y + th + v - subs);
|
|
|
|
ssd1306_setColor((mask & RT) ? 0xFFFF : 0);
|
|
ssd1306_fillRect(
|
|
x + th + v,
|
|
y + th,
|
|
x + th * 2 + v - subs,
|
|
y + th + v - subs);
|
|
|
|
ssd1306_setColor((mask & LB) ? 0xFFFF : 0);
|
|
ssd1306_fillRect(
|
|
x + 0,
|
|
y + th * 2 + v,
|
|
x + th - subs,
|
|
y + th * 2 + v * 2 - subs);
|
|
|
|
ssd1306_setColor((mask & RB) ? 0xFFFF : 0);
|
|
ssd1306_fillRect(
|
|
x + th + v,
|
|
y + th * 2 + v,
|
|
x + th * 2 + v - subs,
|
|
y + th * 2 + v * 2 - subs);
|
|
}
|
|
|
|
static void draw_7seg_period(uint8_t x, uint8_t y, uint8_t w, uint8_t th) {
|
|
const uint8_t v = w - th * 2;
|
|
const uint8_t subs = 1;
|
|
|
|
ssd1306_setColor(0xFFFF);
|
|
ssd1306_fillRect(
|
|
x,
|
|
y + th * 2 + v * 2,
|
|
x + th - subs,
|
|
y + th * 3 + v * 2 - subs);
|
|
}
|
|
|
|
|
|
void sseg_digit(struct SevenSeg *disp, uint8_t digit) {
|
|
draw_7seg_dig(disp->x, disp->y0, disp->charwidth, disp->thick, digit);
|
|
disp->x += disp->charwidth + disp->spacing;
|
|
}
|
|
|
|
void sseg_blank(struct SevenSeg *disp) {
|
|
draw_7seg_dig(disp->x, disp->y0, disp->charwidth, disp->thick, 255);
|
|
disp->x += disp->charwidth + disp->spacing;
|
|
}
|
|
|
|
void sseg_period(struct SevenSeg *disp) {
|
|
draw_7seg_period(disp->x, disp->y0, disp->charwidth, disp->thick);
|
|
disp->x += disp->thick + disp->spacing;
|
|
}
|
|
|
|
void sseg_number(struct SevenSeg *disp, uint32_t num, uint8_t places, uint8_t decimals) {
|
|
uint8_t digits[5] = {};
|
|
uint8_t pos = 4;
|
|
while (num > 0) {
|
|
uint8_t res = num % 10;
|
|
num /= 10;
|
|
digits[pos] = res;
|
|
pos--;
|
|
}
|
|
|
|
sseg_home(disp);
|
|
bool drawing = false;
|
|
for (uint8_t i = 5 - places; i < 5; i++) {
|
|
uint8_t d = digits[i];
|
|
|
|
if (i == 5 - decimals) {
|
|
sseg_period(disp);
|
|
}
|
|
|
|
if (!drawing && d == 0) {
|
|
if (i == 5 - decimals - 1) {
|
|
sseg_digit(disp, d);
|
|
drawing = true;
|
|
} else {
|
|
sseg_blank(disp);
|
|
}
|
|
} else {
|
|
sseg_digit(disp, d);
|
|
drawing = true;
|
|
}
|
|
}
|
|
}
|
|
|