Stairs/module/src/lib/VeryTinyBigChars.c

134 lines
2.7 KiB
C

/*
* Stairs lighting
* Copyright 2017 (c) Mark van Renswoude
*
* https://git.x2software.net/pub/Stairs
*/
#include "VeryTinyBigChars.h"
#include "VeryTinySSD1306.h"
#include <avr/pgmspace.h>
/*
* Each digit is composed of a 3x5 grid where each bit represents
* whether or not to draw that area. It is then stretched.
*
* Example:
*
* XXX
* X
* XXX
* X
* XXX
*
* The least significant bit is the top left corner, going down
* after that before wrapping to the middle column.
*/
const uint16_t ssd1306_digits_32px [] PROGMEM = {
0b0111111000111111, // 0
0b0100001111110010, // 1
0b0101111010111101, // 2
0b0111111010110101, // 3
0b0111110010000111, // 4
0b0111011010110111, // 5
0b0111011010111111, // 6
0b0111110000100001, // 7
0b0111111010111111, // 8
0b0111111010110111 // 9
};
void ssd1306_drawchar_32px(uint8_t x, uint16_t matrix)
{
uint8_t column[4];
// Vertical mode
ssd1306_setMemoryAddressingMode(0b01);
if (ssd1306_currentRenderFrame() == 1)
{
ssd1306_setPageStartAddress(4);
ssd1306_setPageAddress(4, 7);
}
else
{
ssd1306_setPageStartAddress(0);
ssd1306_setPageAddress(0, 3);
}
ssd1306_setCursor(x, 0);
ssd1306_startData();
// Three columns, each shifted 5 bits
for (uint8_t shift = 0; shift < 3; shift++)
{
uint16_t columnValue = matrix >> (shift * 5);
// It's a bit rough, but it works! First, third and fifth "row" are 6 bits, in between are 7 bits = 32 total
column[0] = 0;
column[1] = 0;
column[2] = 0;
column[3] = 0;
// 0 = 0b0111111000111111
if (columnValue & 0b1)
column[0] |= 0b00111111;
if (columnValue & 0b10) {
column[0] |= 0b11000000;
column[1] |= 0b00011111;
}
if (columnValue & 0b100) {
column[1] |= 0b11100000;
column[2] |= 0b00000111;
}
if (columnValue & 0b1000) {
column[2] |= 0b11111000;
column[3] |= 0b00000011;
}
if (columnValue & 0b10000)
column[3] |= 0b11111100;
// Each column is 6 pixels wide
for (uint8_t repeat = 0; repeat < SSD1306_CharColumnWidth_32px; repeat++)
{
ssd1306_sendData(column[0]);
ssd1306_sendData(column[1]);
ssd1306_sendData(column[2]);
ssd1306_sendData(column[3]);
}
}
ssd1306_endData();
// Default: horizontal mode
ssd1306_setMemoryAddressingMode(0b00);
ssd1306_setPageStartAddress(0);
ssd1306_setPageAddress(0, 7);
}
void ssd1306_drawdigit_32px(uint8_t x, uint8_t value)
{
if (value < 0 || value > 9)
return;
ssd1306_drawchar_32px(x, pgm_read_word(&ssd1306_digits_32px[value]));
}
void ssd1306_drawplus_32px(uint8_t x)
{
ssd1306_drawchar_32px(x, 0b0001000111000100);
}
void ssd1306_drawminus_32px(uint8_t x)
{
ssd1306_drawchar_32px(x, 0b0001000010000100);
}