134 lines
2.7 KiB
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);
|
|
} |