aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/display.c193
-rw-r--r--src/display.h45
-rw-r--r--src/font.h131
-rw-r--r--src/main.c9
4 files changed, 378 insertions, 0 deletions
diff --git a/src/display.c b/src/display.c
new file mode 100644
index 0000000..6cb0f1c
--- /dev/null
+++ b/src/display.c
@@ -0,0 +1,193 @@
+#include <avr/io.h>
+#include <avr/pgmspace.h>
+#include <util/delay.h>
+
+#include "display.h"
+#include "font.h"
+
+uint8_t cursor_y = 0;
+uint8_t cursor_x = 0;
+
+static uint8_t i2c_transfer(uint8_t usisr_val) {
+ USISR = usisr_val;
+ // 2-wire i2c + (USICS1+USICLK = timer0 clock) + 3-wire master
+ uint8_t cr = (1 << USIWM1) | (1 << USICS1) | (1 << USICLK) | (1 << USITC);
+ do {
+ _delay_us(I2C_DELAY_US);
+ USICR = cr;
+ while (!(PINA & (1 << DISPLAY_SCL)))
+ ; // Wait for next clock falling edge
+ _delay_us(I2C_DELAY_US);
+ USICR = cr;
+ } while (!(USISR & (1 << USIOIF)));
+ _delay_us(I2C_DELAY_US);
+
+ uint8_t data = USIDR;
+ USIDR = 0xFF;
+ DDRA |= (1 << DISPLAY_SDA);
+ return data;
+}
+
+static void i2c_init(void) {
+ PORTA |= (1 << DISPLAY_SDA) | (1 << DISPLAY_SCL);
+ DDRA |= (1 << DISPLAY_SDA) | (1 << DISPLAY_SCL);
+ USIDR = 0xFF;
+ // 2-wire i2c + (USICS1+USICLK = timer0 clock)
+ USICR = (1 << USIWM1) | (1 << USICS1) | (1 << USICLK);
+ // Start interrupt + overflow interrupt + stop interrupt + output collision
+ USISR = (1 << USISIF) | (1 << USIOIF) | (1 << USIPF) | (1 << USIDC);
+}
+
+void i2c_start(void) {
+ PORTA |= (1 << DISPLAY_SCL);
+ while (!(PINA & (1 << DISPLAY_SCL)))
+ ; // Wait for next clock falling edge
+ _delay_us(I2C_DELAY_US);
+ PORTA &= ~(1 << DISPLAY_SDA); // SDA low while SCL high = START
+ _delay_us(I2C_DELAY_US);
+ PORTA &= ~(1 << DISPLAY_SCL);
+ PORTA |= (1 << DISPLAY_SDA);
+}
+
+void i2c_stop(void) {
+ PORTA &= ~(1 << DISPLAY_SDA);
+ _delay_us(I2C_DELAY_US);
+ PORTA |= (1 << DISPLAY_SCL);
+ while (!(PINA & (1 << DISPLAY_SCL)))
+ ;
+ _delay_us(I2C_DELAY_US);
+ PORTA |= (1 << DISPLAY_SDA); // SDA high while SCL high = STOP
+ _delay_us(I2C_DELAY_US);
+}
+
+void i2c_write(uint8_t data) {
+ PORTA &= ~(1 << DISPLAY_SCL);
+ USIDR = data;
+ // transfer 8 bits: counter=0 overflows after 16 edges (8 clocks)
+ i2c_transfer((1 << USISIF) | (1 << USIOIF) | (1 << USIPF) | (1 << USIDC) |
+ 0x00);
+ DDRA &= ~(1 << DISPLAY_SDA);
+ // transfer 1 bit: counter=0x0E overflows after 2 edges (1 clock)
+ i2c_transfer((1 << USISIF) | (1 << USIOIF) | (1 << USIPF) | (1 << USIDC) |
+ 0x0E);
+}
+
+void display_cmd(uint8_t cmd) {
+ i2c_start();
+ i2c_write(OLED_ADDR);
+ i2c_write(0x00); // Control byte: Co=0, D/C#=0
+ i2c_write(cmd);
+ i2c_stop();
+}
+
+void display_clear(void) {
+ for (uint8_t page = 0; page < 8; page++) {
+ display_cmd(DCMD_SET_PAGE_START | page);
+ display_cmd(0x00);
+ display_cmd(DCMD_SET_START_ADDR_HIGHER_COL);
+ i2c_start();
+ i2c_write(OLED_ADDR);
+ i2c_write(0x40);
+ for (uint8_t col = 0; col < 128; col++)
+ i2c_write(0x00);
+ i2c_stop();
+ }
+}
+
+void display_init(void) {
+ i2c_init();
+ _delay_ms(40);
+
+ display_cmd(DCMD_DISPLAY_OFF);
+ display_cmd(DCMD_SET_CLOCK_DIV);
+ display_cmd(0x80);
+ display_cmd(DCMD_SET_MUX_RATIO);
+ display_cmd(63); // 64 rows
+ display_cmd(DCMD_SET_OFFSET);
+ display_cmd(0x00);
+ display_cmd(DCMD_SET_START_LINE);
+ display_cmd(DCMD_SET_CHARGE_PUMP);
+ display_cmd(DCMD_CHARGE_PUMP_ENABLE);
+ display_cmd(DCMD_SET_ADDRESSING_MODE);
+ display_cmd(DCMD_ADDR_HORIZONTAL);
+ display_cmd(DCMD_SET_SEGMENT_REMAP);
+ display_cmd(DCMD_SET_COM_SCAN_DIRECTION);
+ display_cmd(DCMD_SET_COM_PINS);
+ display_cmd(0x12);
+ display_cmd(DCMD_SET_CONTRAST);
+ display_cmd(207);
+ display_cmd(DCMD_SET_PRECHARGE_PERIOD);
+ display_cmd(0xF1);
+ display_cmd(DCMD_SET_VCOMH_DESELECT);
+ display_cmd(0x40);
+ display_cmd(DCMD_OUTPUT_FOLLOWS_RAM);
+ display_cmd(DCMD_NORMAL_MODE);
+ display_cmd(DCMD_DISPLAY_ON);
+
+ display_clear();
+}
+
+static uint8_t scale_column(uint8_t font_byte, uint8_t page) {
+ uint8_t out = 0;
+ for (uint8_t b = 0; b < 8; b++) {
+ uint8_t src = (page * 8 + b) / FONT_SCALE_Y;
+ if (src < FONT_GLYPH_HEIGHT && (font_byte & (1 << src)))
+ out |= (1 << b);
+ }
+ return out;
+}
+
+void display_draw_char(uint8_t c) {
+ if (c < FONT_GLYPH_FIRST_CHAR || c > FONT_GLYPH_LAST_CHAR)
+ return;
+ uint16_t offset = (uint16_t)(c - FONT_GLYPH_FIRST_CHAR) * FONT_GLYPH_WIDTH;
+
+ uint8_t pages = (FONT_GLYPH_HEIGHT * FONT_SCALE_Y + 7) / 8;
+ for (uint8_t p = 0; p < pages; p++) {
+ display_cmd(DCMD_SET_PAGE_START | ((cursor_y + p) & 0x07));
+ display_cmd(cursor_x & 0x0F);
+ display_cmd(DCMD_SET_START_ADDR_HIGHER_COL | (cursor_x >> 4));
+
+ i2c_start();
+ i2c_write(OLED_ADDR);
+ i2c_write(0x40);
+ for (uint8_t col = 0; col < FONT_GLYPH_WIDTH; col++) {
+ uint8_t glyph = pgm_read_byte(&FONT_BITMAP[offset + col]);
+ uint8_t scaled = scale_column(glyph, p);
+ for (uint8_t r = 0; r < FONT_SCALE_X; r++)
+ i2c_write(scaled);
+ }
+ for (uint8_t r = 0; r < FONT_SCALE_X; r++)
+ i2c_write(0x00);
+ i2c_stop();
+ }
+
+ cursor_x += (FONT_GLYPH_WIDTH + CHAR_SPACING) * FONT_SCALE_X;
+}
+
+void display_draw_float2(float num) {
+ cursor_x = 5;
+ cursor_y = 2;
+
+ if (num < 0) {
+ display_draw_char('-');
+ num = -num;
+ }
+
+ int val = (int)(num * 10); // include 1 decimal place
+ int digit;
+ uint8_t is_first = 1;
+
+ for (uint16_t i = 1000; i >= 1; i /= 10, is_first = 0) {
+ // 2 digits left means tis decimal time
+ if (i == 1)
+ display_draw_char('.');
+ digit = (val / i) % 10;
+ val %= i;
+ // if first digit is 0, draw space (tis garbage code)
+ if (is_first && digit == 0)
+ display_draw_char(' ');
+ else
+ display_draw_char(digit + '0');
+ }
+}
diff --git a/src/display.h b/src/display.h
new file mode 100644
index 0000000..254c4f6
--- /dev/null
+++ b/src/display.h
@@ -0,0 +1,45 @@
+#ifndef _MODULE_DISPLAY_H
+#define _MODULE_DISPLAY_H
+
+#include <stdint.h>
+
+// 0x3C << 1
+#define OLED_ADDR 0x78
+
+#define DISPLAY_SDA PA6
+#define DISPLAY_SCL PA4
+
+#define I2C_DELAY_US 5
+
+#define DCMD_DISPLAY_ON 0xAF
+#define DCMD_DISPLAY_OFF 0xAE
+#define DCMD_SET_CLOCK_DIV 0xD5
+#define DCMD_SET_MUX_RATIO 0xA8
+#define DCMD_SET_OFFSET 0xD3
+#define DCMD_SET_START_LINE 0x40
+#define DCMD_SET_CHARGE_PUMP 0x8D
+#define DCMD_CHARGE_PUMP_ENABLE 0x14
+#define DCMD_SET_ADDRESSING_MODE 0x20
+#define DCMD_ADDR_HORIZONTAL 0x00
+#define DCMD_SET_SEGMENT_REMAP 0xA1
+#define DCMD_SET_COM_SCAN_DIRECTION 0xC8
+#define DCMD_SET_COM_PINS 0xDA
+#define DCMD_SET_CONTRAST 0x81
+#define DCMD_SET_PRECHARGE_PERIOD 0xD9
+#define DCMD_SET_VCOMH_DESELECT 0xDB
+#define DCMD_OUTPUT_FOLLOWS_RAM 0xA4
+#define DCMD_NORMAL_MODE 0xA6
+#define DCMD_INVERSE_MODE 0xA7
+#define DCMD_SET_PAGE_START 0xB0
+#define DCMD_SET_START_ADDR_HIGHER_COL 0x10
+
+extern uint8_t cursor_y;
+extern uint8_t cursor_x;
+
+void display_init(void);
+
+void display_draw_char(uint8_t c);
+
+void display_draw_float2(float num);
+
+#endif
diff --git a/src/font.h b/src/font.h
new file mode 100644
index 0000000..24fbcc7
--- /dev/null
+++ b/src/font.h
@@ -0,0 +1,131 @@
+#ifndef _MODULE_FONT_H
+#define _MODULE_FONT_H
+
+#include <avr/pgmspace.h>
+#include <stdint.h>
+
+#define FONT_SCALE_X 3
+#define FONT_SCALE_Y 7
+#define CHAR_SPACING 1
+#define FONT_GLYPH_WIDTH 5
+#define FONT_GLYPH_HEIGHT 8
+#define FONT_GLYPH_FIRST_CHAR 0
+#define FONT_GLYPH_LAST_CHAR 255
+
+const uint8_t FONT_BITMAP[] PROGMEM = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x5B, 0x4F, 0x5B, 0x3E, 0x3E, 0x6B,
+ 0x4F, 0x6B, 0x3E, 0x1C, 0x3E, 0x7C, 0x3E, 0x1C, 0x18, 0x3C, 0x7E, 0x3C,
+ 0x18, 0x1C, 0x57, 0x7D, 0x57, 0x1C, 0x1C, 0x5E, 0x7F, 0x5E, 0x1C, 0x00,
+ 0x18, 0x3C, 0x18, 0x00, 0xFF, 0xE7, 0xC3, 0xE7, 0xFF, 0x00, 0x18, 0x24,
+ 0x18, 0x00, 0xFF, 0xE7, 0xDB, 0xE7, 0xFF, 0x30, 0x48, 0x3A, 0x06, 0x0E,
+ 0x26, 0x29, 0x79, 0x29, 0x26, 0x40, 0x7F, 0x05, 0x05, 0x07, 0x40, 0x7F,
+ 0x05, 0x25, 0x3F, 0x5A, 0x3C, 0xE7, 0x3C, 0x5A, 0x7F, 0x3E, 0x1C, 0x1C,
+ 0x08, 0x08, 0x1C, 0x1C, 0x3E, 0x7F, 0x14, 0x22, 0x7F, 0x22, 0x14, 0x5F,
+ 0x5F, 0x00, 0x5F, 0x5F, 0x06, 0x09, 0x7F, 0x01, 0x7F, 0x00, 0x66, 0x89,
+ 0x95, 0x6A, 0x60, 0x60, 0x60, 0x60, 0x60, 0x94, 0xA2, 0xFF, 0xA2, 0x94,
+ 0x08, 0x04, 0x7E, 0x04, 0x08, 0x10, 0x20, 0x7E, 0x20, 0x10, 0x08, 0x08,
+ 0x2A, 0x1C, 0x08, 0x08, 0x1C, 0x2A, 0x08, 0x08, 0x1E, 0x10, 0x10, 0x10,
+ 0x10, 0x0C, 0x1E, 0x0C, 0x1E, 0x0C, 0x30, 0x38, 0x3E, 0x38, 0x30, 0x06,
+ 0x0E, 0x3E, 0x0E, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F,
+ 0x00, 0x00, 0x00, 0x07, 0x00, 0x07, 0x00, 0x14, 0x7F, 0x14, 0x7F, 0x14,
+ 0x24, 0x2A, 0x7F, 0x2A, 0x12, 0x23, 0x13, 0x08, 0x64, 0x62, 0x36, 0x49,
+ 0x56, 0x20, 0x50, 0x00, 0x08, 0x07, 0x03, 0x00, 0x00, 0x1C, 0x22, 0x41,
+ 0x00, 0x00, 0x41, 0x22, 0x1C, 0x00, 0x2A, 0x1C, 0x7F, 0x1C, 0x2A, 0x08,
+ 0x08, 0x3E, 0x08, 0x08, 0x00, 0x80, 0x70, 0x30, 0x00, 0x08, 0x08, 0x08,
+ 0x08, 0x08, 0x00, 0x00, 0x60, 0x60, 0x00, 0x20, 0x10, 0x08, 0x04, 0x02,
+ 0x3E, 0x51, 0x49, 0x45, 0x3E, 0x00, 0x42, 0x7F, 0x40, 0x00, 0x72, 0x49,
+ 0x49, 0x49, 0x46, 0x21, 0x41, 0x49, 0x4D, 0x33, 0x18, 0x14, 0x12, 0x7F,
+ 0x10, 0x27, 0x45, 0x45, 0x45, 0x39, 0x3C, 0x4A, 0x49, 0x49, 0x31, 0x41,
+ 0x21, 0x11, 0x09, 0x07, 0x36, 0x49, 0x49, 0x49, 0x36, 0x46, 0x49, 0x49,
+ 0x29, 0x1E, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x40, 0x34, 0x00, 0x00,
+ 0x00, 0x08, 0x14, 0x22, 0x41, 0x14, 0x14, 0x14, 0x14, 0x14, 0x00, 0x41,
+ 0x22, 0x14, 0x08, 0x02, 0x01, 0x59, 0x09, 0x06, 0x3E, 0x41, 0x5D, 0x59,
+ 0x4E, 0x7C, 0x12, 0x11, 0x12, 0x7C, 0x7F, 0x49, 0x49, 0x49, 0x36, 0x3E,
+ 0x41, 0x41, 0x41, 0x22, 0x7F, 0x41, 0x41, 0x41, 0x3E, 0x7F, 0x49, 0x49,
+ 0x49, 0x41, 0x7F, 0x09, 0x09, 0x09, 0x01, 0x3E, 0x41, 0x41, 0x51, 0x73,
+ 0x7F, 0x08, 0x08, 0x08, 0x7F, 0x00, 0x41, 0x7F, 0x41, 0x00, 0x20, 0x40,
+ 0x41, 0x3F, 0x01, 0x7F, 0x08, 0x14, 0x22, 0x41, 0x7F, 0x40, 0x40, 0x40,
+ 0x40, 0x7F, 0x02, 0x1C, 0x02, 0x7F, 0x7F, 0x04, 0x08, 0x10, 0x7F, 0x3E,
+ 0x41, 0x41, 0x41, 0x3E, 0x7F, 0x09, 0x09, 0x09, 0x06, 0x3E, 0x41, 0x51,
+ 0x21, 0x5E, 0x7F, 0x09, 0x19, 0x29, 0x46, 0x26, 0x49, 0x49, 0x49, 0x32,
+ 0x03, 0x01, 0x7F, 0x01, 0x03, 0x3F, 0x40, 0x40, 0x40, 0x3F, 0x1F, 0x20,
+ 0x40, 0x20, 0x1F, 0x3F, 0x40, 0x38, 0x40, 0x3F, 0x63, 0x14, 0x08, 0x14,
+ 0x63, 0x03, 0x04, 0x78, 0x04, 0x03, 0x61, 0x59, 0x49, 0x4D, 0x43, 0x00,
+ 0x7F, 0x41, 0x41, 0x41, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, 0x41, 0x41,
+ 0x41, 0x7F, 0x04, 0x02, 0x01, 0x02, 0x04, 0x40, 0x40, 0x40, 0x40, 0x40,
+ 0x00, 0x03, 0x07, 0x08, 0x00, 0x20, 0x54, 0x54, 0x78, 0x40, 0x7F, 0x28,
+ 0x44, 0x44, 0x38, 0x38, 0x44, 0x44, 0x44, 0x28, 0x38, 0x44, 0x44, 0x28,
+ 0x7F, 0x38, 0x54, 0x54, 0x54, 0x18, 0x00, 0x08, 0x7E, 0x09, 0x02, 0x18,
+ 0xA4, 0xA4, 0x9C, 0x78, 0x7F, 0x08, 0x04, 0x04, 0x78, 0x00, 0x44, 0x7D,
+ 0x40, 0x00, 0x20, 0x40, 0x40, 0x3D, 0x00, 0x7F, 0x10, 0x28, 0x44, 0x00,
+ 0x00, 0x41, 0x7F, 0x40, 0x00, 0x7C, 0x04, 0x78, 0x04, 0x78, 0x7C, 0x08,
+ 0x04, 0x04, 0x78, 0x38, 0x44, 0x44, 0x44, 0x38, 0xFC, 0x18, 0x24, 0x24,
+ 0x18, 0x18, 0x24, 0x24, 0x18, 0xFC, 0x7C, 0x08, 0x04, 0x04, 0x08, 0x48,
+ 0x54, 0x54, 0x54, 0x24, 0x04, 0x04, 0x3F, 0x44, 0x24, 0x3C, 0x40, 0x40,
+ 0x20, 0x7C, 0x1C, 0x20, 0x40, 0x20, 0x1C, 0x3C, 0x40, 0x30, 0x40, 0x3C,
+ 0x44, 0x28, 0x10, 0x28, 0x44, 0x4C, 0x90, 0x90, 0x90, 0x7C, 0x44, 0x64,
+ 0x54, 0x4C, 0x44, 0x00, 0x08, 0x36, 0x41, 0x00, 0x00, 0x00, 0x77, 0x00,
+ 0x00, 0x00, 0x41, 0x36, 0x08, 0x00, 0x02, 0x01, 0x02, 0x04, 0x02, 0x3C,
+ 0x26, 0x23, 0x26, 0x3C, 0x1E, 0xA1, 0xA1, 0x61, 0x12, 0x3A, 0x40, 0x40,
+ 0x20, 0x7A, 0x38, 0x54, 0x54, 0x55, 0x59, 0x21, 0x55, 0x55, 0x79, 0x41,
+ 0x22, 0x54, 0x54, 0x78, 0x42, // a-umlaut
+ 0x21, 0x55, 0x54, 0x78, 0x40, 0x20, 0x54, 0x55, 0x79, 0x40, 0x0C, 0x1E,
+ 0x52, 0x72, 0x12, 0x39, 0x55, 0x55, 0x55, 0x59, 0x39, 0x54, 0x54, 0x54,
+ 0x59, 0x39, 0x55, 0x54, 0x54, 0x58, 0x00, 0x00, 0x45, 0x7C, 0x41, 0x00,
+ 0x02, 0x45, 0x7D, 0x42, 0x00, 0x01, 0x45, 0x7C, 0x40, 0x7D, 0x12, 0x11,
+ 0x12, 0x7D, // A-umlaut
+ 0xF0, 0x28, 0x25, 0x28, 0xF0, 0x7C, 0x54, 0x55, 0x45, 0x00, 0x20, 0x54,
+ 0x54, 0x7C, 0x54, 0x7C, 0x0A, 0x09, 0x7F, 0x49, 0x32, 0x49, 0x49, 0x49,
+ 0x32, 0x3A, 0x44, 0x44, 0x44, 0x3A, // o-umlaut
+ 0x32, 0x4A, 0x48, 0x48, 0x30, 0x3A, 0x41, 0x41, 0x21, 0x7A, 0x3A, 0x42,
+ 0x40, 0x20, 0x78, 0x00, 0x9D, 0xA0, 0xA0, 0x7D, 0x3D, 0x42, 0x42, 0x42,
+ 0x3D, // O-umlaut
+ 0x3D, 0x40, 0x40, 0x40, 0x3D, 0x3C, 0x24, 0xFF, 0x24, 0x24, 0x48, 0x7E,
+ 0x49, 0x43, 0x66, 0x2B, 0x2F, 0xFC, 0x2F, 0x2B, 0xFF, 0x09, 0x29, 0xF6,
+ 0x20, 0xC0, 0x88, 0x7E, 0x09, 0x03, 0x20, 0x54, 0x54, 0x79, 0x41, 0x00,
+ 0x00, 0x44, 0x7D, 0x41, 0x30, 0x48, 0x48, 0x4A, 0x32, 0x38, 0x40, 0x40,
+ 0x22, 0x7A, 0x00, 0x7A, 0x0A, 0x0A, 0x72, 0x7D, 0x0D, 0x19, 0x31, 0x7D,
+ 0x26, 0x29, 0x29, 0x2F, 0x28, 0x26, 0x29, 0x29, 0x29, 0x26, 0x30, 0x48,
+ 0x4D, 0x40, 0x20, 0x38, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+ 0x38, 0x2F, 0x10, 0xC8, 0xAC, 0xBA, 0x2F, 0x10, 0x28, 0x34, 0xFA, 0x00,
+ 0x00, 0x7B, 0x00, 0x00, 0x08, 0x14, 0x2A, 0x14, 0x22, 0x22, 0x14, 0x2A,
+ 0x14, 0x08, 0x55, 0x00, 0x55, 0x00, 0x55, // #176 (25% block) missing in old
+ // code
+ 0xAA, 0x55, 0xAA, 0x55, 0xAA, // 50% block
+ 0xFF, 0x55, 0xFF, 0x55, 0xFF, // 75% block
+ 0x00, 0x00, 0x00, 0xFF, 0x00, 0x10, 0x10, 0x10, 0xFF, 0x00, 0x14, 0x14,
+ 0x14, 0xFF, 0x00, 0x10, 0x10, 0xFF, 0x00, 0xFF, 0x10, 0x10, 0xF0, 0x10,
+ 0xF0, 0x14, 0x14, 0x14, 0xFC, 0x00, 0x14, 0x14, 0xF7, 0x00, 0xFF, 0x00,
+ 0x00, 0xFF, 0x00, 0xFF, 0x14, 0x14, 0xF4, 0x04, 0xFC, 0x14, 0x14, 0x17,
+ 0x10, 0x1F, 0x10, 0x10, 0x1F, 0x10, 0x1F, 0x14, 0x14, 0x14, 0x1F, 0x00,
+ 0x10, 0x10, 0x10, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x10, 0x10, 0x10,
+ 0x10, 0x1F, 0x10, 0x10, 0x10, 0x10, 0xF0, 0x10, 0x00, 0x00, 0x00, 0xFF,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xFF, 0x10, 0x00,
+ 0x00, 0x00, 0xFF, 0x14, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x1F,
+ 0x10, 0x17, 0x00, 0x00, 0xFC, 0x04, 0xF4, 0x14, 0x14, 0x17, 0x10, 0x17,
+ 0x14, 0x14, 0xF4, 0x04, 0xF4, 0x00, 0x00, 0xFF, 0x00, 0xF7, 0x14, 0x14,
+ 0x14, 0x14, 0x14, 0x14, 0x14, 0xF7, 0x00, 0xF7, 0x14, 0x14, 0x14, 0x17,
+ 0x14, 0x10, 0x10, 0x1F, 0x10, 0x1F, 0x14, 0x14, 0x14, 0xF4, 0x14, 0x10,
+ 0x10, 0xF0, 0x10, 0xF0, 0x00, 0x00, 0x1F, 0x10, 0x1F, 0x00, 0x00, 0x00,
+ 0x1F, 0x14, 0x00, 0x00, 0x00, 0xFC, 0x14, 0x00, 0x00, 0xF0, 0x10, 0xF0,
+ 0x10, 0x10, 0xFF, 0x10, 0xFF, 0x14, 0x14, 0x14, 0xFF, 0x14, 0x10, 0x10,
+ 0x10, 0x1F, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x10, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x38, 0x44, 0x44,
+ 0x38, 0x44, 0xFC, 0x4A, 0x4A, 0x4A, 0x34, // sharp-s or beta
+ 0x7E, 0x02, 0x02, 0x06, 0x06, 0x02, 0x7E, 0x02, 0x7E, 0x02, 0x63, 0x55,
+ 0x49, 0x41, 0x63, 0x38, 0x44, 0x44, 0x3C, 0x04, 0x40, 0x7E, 0x20, 0x1E,
+ 0x20, 0x06, 0x02, 0x7E, 0x02, 0x02, 0x99, 0xA5, 0xE7, 0xA5, 0x99, 0x1C,
+ 0x2A, 0x49, 0x2A, 0x1C, 0x4C, 0x72, 0x01, 0x72, 0x4C, 0x30, 0x4A, 0x4D,
+ 0x4D, 0x30, 0x30, 0x48, 0x78, 0x48, 0x30, 0xBC, 0x62, 0x5A, 0x46, 0x3D,
+ 0x3E, 0x49, 0x49, 0x49, 0x00, 0x7E, 0x01, 0x01, 0x01, 0x7E, 0x2A, 0x2A,
+ 0x2A, 0x2A, 0x2A, 0x44, 0x44, 0x5F, 0x44, 0x44, 0x40, 0x51, 0x4A, 0x44,
+ 0x40, 0x40, 0x44, 0x4A, 0x51, 0x40, 0x00, 0x00, 0xFF, 0x01, 0x03, 0xE0,
+ 0x80, 0xFF, 0x00, 0x00, 0x08, 0x08, 0x6B, 0x6B, 0x08, 0x36, 0x12, 0x36,
+ 0x24, 0x36, 0x06, 0x0F, 0x09, 0x0F, 0x06, 0x00, 0x00, 0x18, 0x18, 0x00,
+ 0x00, 0x00, 0x10, 0x10, 0x00, 0x30, 0x40, 0xFF, 0x01, 0x01, 0x00, 0x1F,
+ 0x01, 0x01, 0x1E, 0x00, 0x19, 0x1D, 0x17, 0x12, 0x00, 0x3C, 0x3C, 0x3C,
+ 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00 // #255 NBSP
+};
+
+#endif
diff --git a/src/main.c b/src/main.c
index cd3f0be..1b804b7 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,7 +1,16 @@
+#include <avr/io.h>
+#include <avr/pgmspace.h>
#include <util/delay.h>
+#include "display.h"
+
int main(void) {
+ display_init();
+ int n = 1;
+
while (1) {
+ display_draw_float2(1.01 * n);
+ n = (n + 1) % 100;
_delay_ms(1000);
}