/** * TODO file description */ #include #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; } } }