git rm --cached lib/libssd1306/bld/

This commit is contained in:
2022-11-14 00:59:26 +01:00
parent 317aed825e
commit 3124b29176
49 changed files with 256 additions and 180 deletions
+193 -172
View File
@@ -4,138 +4,134 @@
#include "framebuffer.h"
#define MIN(a,b) ((a)>(b)?(b):(a))
#define MAX(a,b) ((a)>(b)?(a):(b))
#define MIN(a, b) ((a)>(b)?(b):(a))
#define MAX(a, b) ((a)>(b)?(a):(b))
#include <string.h>
uint8_t fb[(FBH / 8) * FBW];
/** Fill with a vertical pattern, 1 byte */
void fb_fill(uint8_t pattern) {
void fb_fill(uint8_t pattern)
{
memset(fb, pattern, sizeof(fb));
}
void fb_clear() {
fb_fill(0);
}
void fb_px(uint8_t x, uint8_t y, uint8_t color) {
if (x >= FBW || y >= FBH) return;
const uint8_t row = y / 8;
const uint8_t rowrem = y % 8;
const uint16_t cell = (uint16_t) x + (uint16_t) row * FBW;
if (color) {
fb[cell] |= (1 << rowrem);
static void draw_mask(fbsize_t idx, uint8_t mask, uint8_t color)
{
if (color != 0) {
fb[idx] |= mask;
} else {
fb[cell] &= ~(1 << rowrem);
fb[idx] &= ~mask;
}
}
void fb_hline(uint8_t x, uint8_t y, uint8_t w, uint8_t color) {
if (x >= FBW || y >= FBH) return;
void fb_px(fbpos_t x, fbpos_t y, uint8_t color)
{
if (x >= FBW || y >= FBH) { return; }
const fbpos_t row = y / 8;
const fbpos_t rowrem = y % 8;
const fbsize_t cell = (fbsize_t) x + (fbsize_t) row * FBW;
draw_mask(cell, 1 << rowrem, color);
}
uint8_t fb_getpx(fbpos_t x, fbpos_t y)
{
if (x >= FBW || y >= FBH) { return 0; }
const fbpos_t row = y / 8;
const fbpos_t rowrem = y % 8;
const fbsize_t cell = (fbsize_t) x + (fbsize_t) row * FBW;
if (fb[cell] & (1 << rowrem)) {
return 0xFF;
} else {
return 0x00;
}
}
void fb_hline(fbpos_t x, fbpos_t y, fbpos_t w, uint8_t color)
{
if (x >= FBW || y >= FBH) { return; }
w = MIN(FBW - x, w);
const uint8_t row = y / 8;
const uint8_t rowrem = y % 8;
uint16_t cell = (uint16_t) x + (uint16_t) row * FBW;
for(uint8_t i = 0; i < w; i++) {
if (color) {
fb[cell] |= (1 << rowrem);
} else {
fb[cell] &= ~(1 << rowrem);
}
const fbpos_t row = y / 8;
const fbpos_t rowrem = y % 8;
fbsize_t cell = (fbsize_t) x + (fbsize_t) row * FBW;
for (uint8_t i = 0; i < w; i++) {
draw_mask(cell, 1 << rowrem, color);
cell++;
}
}
void fb_vline(uint8_t x, uint8_t y, uint8_t h, uint8_t color) {
if (x >= FBW || y >= FBH) return;
void fb_vline(fbpos_t x, fbpos_t y, fbpos_t h, uint8_t color)
{
if (x >= FBW || y >= FBH) { return; }
h = MIN(FBH - y - 1, h);
const uint8_t row = y / 8;
const uint8_t rowrem = y % 8;
const fbpos_t row = y / 8;
const fbpos_t rowrem = y % 8;
uint16_t cell = (uint16_t) x + (uint16_t) row * FBW;
if (rowrem + h < 8) {
// all within one cell
uint8_t mask = (0xFF << rowrem) & (0xFF >> (h-rowrem));
if (color) {
fb[cell] |= mask;
} else {
fb[cell] &= ~mask;
}
const uint8_t mask = (0xFF << rowrem) & (0xFF >> (8 - h - rowrem));
draw_mask(cell, mask, color);
return;
} else {
// First
uint8_t mask = (0xFF << rowrem);
if (color) {
fb[cell] |= mask;
} else {
fb[cell] &= ~mask;
}
h -= rowrem;
draw_mask(cell, 0xFF << rowrem, color);
h -= (rowrem == 0 ? 8 : (8 - rowrem));
uint8_t whole_cells = h / 8;
h -= whole_cells * 8;
for(uint8_t i = 0; i < whole_cells; i++) {
cell += FBW;
if (color) {
fb[cell] = 0xFF;
} else {
fb[cell] = 0;
const fbpos_t whole_cells = h / 8;
if (whole_cells > 0) {
h -= whole_cells * 8;
for (fbpos_t i = 0; i < whole_cells; i++) {
cell += FBW;
draw_mask(cell, 0xFF, color);
}
}
// last
mask = (0xFF >> (8-h));
if (color) {
fb[cell] |= mask;
} else {
fb[cell] &= ~mask;
}
cell += FBW;
draw_mask(cell, 0xFF >> (8 - h), color);
}
}
void fb_rect(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t color) {
if (x >= FBW || y >= FBH) return;
w = MIN(FBW - x - 1, w);
h = MIN(FBH - y - 1, h);
const uint8_t row = y / 8;
const uint8_t rowrem = y % 8;
uint16_t cell = (uint16_t) x + (uint16_t) row * FBW;
void fb_rect(fbpos_t x, fbpos_t y, fbpos_t w, fbpos_t h, uint8_t color)
{
if (x >= FBW || y >= FBH) { return; }
w = MIN(FBW - x, w);
h = MIN(FBH - y, h);
const fbpos_t row = y / 8;
const fbpos_t rowrem = y % 8;
fbsize_t cell = (fbsize_t) x + (fbsize_t) row * FBW;
if (rowrem + h <= 8) {
if (w == 1 && h == 1) {
fb_px(x, y, color);
} else if (w == 1) {
fb_vline(x, y, h, color);
} else if (h == 1) {
fb_hline(x, y, w, color);
} else if (rowrem + h <= 8) {
// all within one cell
uint8_t mask = (0xFF << rowrem) & (0xFF >> (8 - (h - rowrem)));
uint8_t mask = (0xFF << rowrem) & (0xFF >> (8 - h - rowrem));
for(uint8_t i = 0; i < w; i++) {
if (color) {
fb[cell + i] |= mask;
} else {
fb[cell + i] &= ~mask;
}
for (fbpos_t i = 0; i < w; i++) {
draw_mask(cell + i, mask, color);
}
return;
} else {
// First
uint8_t mask = (0xFF << rowrem);
for(uint8_t i = 0; i < w; i++) {
if (color) {
fb[cell + i] |= mask;
} else {
fb[cell + i] &= ~mask;
}
for (fbpos_t i = 0; i < w; i++) {
draw_mask(cell + i, mask, color);
}
h -= 8 - rowrem;
uint8_t whole_cells = h / 8;
h -= whole_cells * 8;
for(uint8_t j = 0; j < whole_cells; j++) {
cell += FBW;
for(uint8_t i = 0; i < w; i++) {
if (color) {
fb[cell + i] = 0xFF;
} else {
fb[cell + i] = 0;
const fbpos_t whole_cells = h / 8;
if (whole_cells > 0) {
h -= whole_cells * 8;
for (fbpos_t j = 0; j < whole_cells; j++) {
cell += FBW;
for (fbpos_t i = 0; i < w; i++) {
draw_mask(cell + i, 0xFF, color);
}
}
}
@@ -143,109 +139,64 @@ void fb_rect(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t color) {
cell += FBW;
// last
mask = (0xFF >> (8-h));
for(uint8_t i = 0; i < w; i++) {
if (color) {
fb[cell + i] |= mask;
} else {
fb[cell + i] &= ~mask;
}
mask = (0xFF >> (8 - h));
for (fbpos_t i = 0; i < w; i++) {
draw_mask(cell + i, mask, color);
}
}
}
void fb_bitmap(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint8_t *map, uint8_t color) {
if (x >= FBW || y >= FBH) return;
const uint8_t w0 = w;
const uint8_t h0 = h;
void fb_frame(fbpos_t x, fbpos_t y, fbpos_t w, fbpos_t h, fbpos_t thickness, uint8_t color)
{
if (thickness == 0) {
return;
} else if (thickness == 1) {
fb_hline(x, y, w, color);
fb_vline(x, y, h, color);
fb_hline(x, y + h - 1, w, color);
fb_vline(x + w - 1, y, h, color);
} else {
fb_rect(x, y, w, thickness, color);
fb_rect(x, y + h - thickness, w, thickness, color);
fb_rect(x, y + thickness, thickness, h - 2 * thickness, color);
fb_rect(x + w - thickness, y + thickness, thickness, h - 2 * thickness, color);
}
}
void fb_bitmap(fbpos_t x, fbpos_t y, fbpos_t w, fbpos_t h, const uint8_t *map, uint8_t color)
{
if (x >= FBW || y >= FBH) { return; }
const fbpos_t w0 = w;
w = MIN(FBW - x - 1, w);
h = MIN(FBH - y - 1, h);
const uint8_t row = y / 8;
const uint8_t rowrem = y % 8;
uint16_t cell = (uint16_t) x + (uint16_t) row * FBW;
const fbpos_t row = y / 8;
const fbpos_t rowrem = y % 8;
fbsize_t cell = (fbsize_t) x + (fbsize_t) row * FBW;
if (rowrem + h <= 8) {
for(uint8_t i = 0; i < w; i++) {
for (fbpos_t i = 0; i < w; i++) {
// all within one cell
uint8_t mask = (map[i] & (0xFF >> (8-h))) << rowrem;
if (color) {
fb[cell + i] |= mask;
} else {
fb[cell + i] &= ~mask;
}
const uint8_t mask = (map[i] & (0xFF >> (8 - h))) << rowrem;
draw_mask(cell + i, mask, color);
}
return;
} else if (rowrem == 0) {
// Optimization
uint8_t mapc0 = 0;
// First
for(uint8_t i = 0; i < w; i++) {
uint8_t mask = map[i];
if (color) {
fb[cell + i] |= mask;
} else {
fb[cell + i] &= ~mask;
}
}
h -= 8;
// Middle
uint8_t whole_cells = h / 8;
h -= whole_cells * 8;
for(uint8_t j = 0; j < whole_cells; j++) {
cell += FBW;
mapc0 += w0;
for(uint8_t i = 0; i < w; i++) {
uint8_t mask = map[i + mapc0];
if (color) {
fb[cell + i] |= mask;
} else {
fb[cell + i] &= ~mask;
}
}
}
// last
mapc0 += w0;
cell += FBW;
// last
for(uint8_t i = 0; i < w; i++) {
uint8_t mask = map[i + mapc0] & (0xFF >> (8-h));
if (color) {
fb[cell + i] |= mask;
} else {
fb[cell + i] &= ~mask;
}
}
} else {
uint8_t mapc0 = 0;
fbsize_t mapc0 = 0;
// Draw the bitmap slice-by-slice based on how rows of the bitmap intersect with rows of the canvas.
// This could be optimized to walk each row of the canvas only once, but the code would get bigger.
while (h > 0) {
// First
for (uint8_t i = 0; i < w; i++) {
uint8_t mask = (map[i + mapc0] & (0xFF >> rowrem)) << rowrem;
if (color) {
fb[cell + i] |= mask;
} else {
fb[cell + i] &= ~mask;
}
for (fbpos_t i = 0; i < w; i++) {
const uint8_t mask = (map[i + mapc0] & (0xFF >> rowrem)) << rowrem;
draw_mask(cell + i, mask, color);
}
//mapc0 += w0;
cell += FBW;
// leftover of the first row in map
// last
for (uint8_t i = 0; i < w; i++) {
uint8_t mask = (map[i + mapc0] & (0xFF << (8 - rowrem))) >> (8 - rowrem);
if (color) {
fb[cell + i] |= mask;
} else {
fb[cell + i] &= ~mask;
if (rowrem != 0) {
for (fbpos_t i = 0; i < w; i++) {
const uint8_t mask = (map[i + mapc0] & (0xFF << (8 - rowrem))) >> (8 - rowrem);
draw_mask(cell + i, mask, color);
}
}
@@ -259,3 +210,73 @@ void fb_bitmap(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint8_t *map, u
}
}
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,
};
fbpos_t fb_7seg_dig(fbpos_t x, fbpos_t y, fbpos_t w, fbpos_t h, fbpos_t th, uint8_t digit, uint8_t color)
{
const uint8_t mask = digit > 9 ? 0 : pgm_read_byte(&seven[digit]);
const fbpos_t wi = w - th * 2;
const fbpos_t hi = (h - th * 3) / 2;
bool bcolor = !color; // changed for XOR
fb_rect(x + th,
y,
wi,
th, bcolor ^ (bool) (mask & T));
fb_rect(x + th,
y + th + hi,
wi,
th, bcolor ^ (bool) (mask & M));
fb_rect(x + th,
y + th * 2 + hi * 2,
wi,
th, bcolor ^ (bool) (mask & B));
fb_rect(x,
y + th,
th,
hi, bcolor ^ (bool) (mask & LT));
fb_rect(x + th + wi,
y + hi + th,
th,
hi, bcolor ^ (bool) (mask & LB));
fb_rect(x + th + wi,
y + th,
th,
hi, bcolor ^ (bool) (mask & RT));
fb_rect(x + th + wi,
y + th * 2 + hi,
th,
hi, bcolor ^ (bool) (mask & RB));
return w;
}
fbpos_t fb_7seg_period(fbpos_t x, fbpos_t y, fbpos_t w, fbpos_t h, fbpos_t th, uint8_t color)
{
const fbpos_t hi = (h - th * 3) / 2;
fb_rect(x, y + hi * 2 + th * 2, th, th, color);
return th;
}
+56 -7
View File
@@ -13,6 +13,9 @@
#define FBSET 0xFF
#define FBCLEAR 0x00
typedef uint16_t fbsize_t;
typedef uint8_t fbpos_t;
/// Framebuffer backing array.
///
/// The format is the native format for SSD1306: array of bytes representing pixels in 8 rows at once, LSB is the topmost row.
@@ -26,16 +29,62 @@
/// and more bytes continue rows 8-15 and so on
extern uint8_t fb[(FBH / 8) * FBW];
/// Fill the entire screen with a byte pattern.
/// Use 0xFF or 0x00 for a solid fill. Other patterns may be used to create horizontal stripes.
void fb_fill(uint8_t pattern);
void fb_clear(void);
void fb_px(uint8_t x, uint8_t y, uint8_t color);
void fb_hline(uint8_t x, uint8_t y, uint8_t w, uint8_t color);
void fb_vline(uint8_t x, uint8_t y, uint8_t h, uint8_t color);
void fb_rect(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t color);
void fb_bitmap(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint8_t *map, uint8_t color);
/// Clear the display (fill with 0x00)
static inline void fb_clear(void)
{
fb_fill(0);
}
/// Set a single pixel
void fb_px(fbpos_t x, fbpos_t y, uint8_t color);
/// Get pixel color
uint8_t fb_getpx(fbpos_t x, fbpos_t y);
/// Draw a horizontal line
void fb_hline(fbpos_t x, fbpos_t y, fbpos_t w, uint8_t color);
/// Draw a vertical line
void fb_vline(fbpos_t x, fbpos_t y, fbpos_t h, uint8_t color);
/// Draw a filled rect
void fb_rect(fbpos_t x, fbpos_t y, fbpos_t w, fbpos_t h, uint8_t color);
/// Draw a frame (unfilled rect)
void fb_frame(fbpos_t x, fbpos_t y, fbpos_t w, fbpos_t h, fbpos_t thickness, uint8_t color);
/// Draw a bitmap
void fb_bitmap(fbpos_t x, fbpos_t y, fbpos_t w, fbpos_t h, const uint8_t *map, uint8_t color);
/// Draw a 7-segment digit. Returns its width (without spacing)
///
/// \param x - pos X (left top)
/// \param y - pos Y (left top)
/// \param w - full digit width
/// \param h - full digit height; will be adjusted down if needed
/// \param th - thickness
/// \param digit - digit 0-9
/// \return width taken
fbpos_t fb_7seg_dig(fbpos_t x, fbpos_t y, fbpos_t w, fbpos_t h, fbpos_t th, uint8_t digit, uint8_t color);
/// Draw a 7-segment period. Returns its width (without spacing).
/// Digit height is (w * 2 - th)
///
/// \param x - pos X (digit left top)
/// \param y - pos Y (digit left top)
/// \param w - full digit width
/// \param h - full digit height; will be adjusted down if needed
/// \param th - thickness
/// \return width taken
fbpos_t fb_7seg_period(fbpos_t x, fbpos_t y, fbpos_t w, fbpos_t h, fbpos_t th, uint8_t color);
/// Output the framebuffer array `fb` to the display device.
///
/// The user must implement this
extern void fb_blit(void);
#endif //FRAMEBUFFER_H
+6
View File
@@ -4,4 +4,10 @@
#define FBW 128
#define FBH 32
#include <avr/pgmspace.h>
/*
#define PROGMEM
#define pgm_read_byte(adr) (*adr)
*/
#endif /* FRAMEBUFFER_CONFIG_H */