extract oled to separate file

master
Ondřej Hruška 1 year ago
parent b4f9b87ce0
commit 9af5a84669
  1. 2
      CMakeLists.txt
  2. 200
      main.c
  3. 199
      oled.c
  4. 19
      oled.h

@ -6,7 +6,7 @@ set(CMAKE_CXX_STANDARD 17)
pico_sdk_init()
add_executable(test
main.c
main.c oled.c
ufb/framebuffer.c ufb/utf8.c ufb/font.c ufb/fb_7seg.c ufb/fb_text.c
)

200
main.c

@ -7,191 +7,23 @@
#include "framebuffer.h"
#include "fb_text.h"
const uint LED_PIN = 25;
const uint DC_PIN = 20;
const uint RST_PIN = 21;
#include "oled.h"
#define SSD1309_HEIGHT 64
const uint LED_PIN = 25;
/* Picotool info */
// Make the SPI pins available to picotool
bi_decl(bi_2pins_with_func(PICO_DEFAULT_SPI_TX_PIN, PICO_DEFAULT_SPI_SCK_PIN, GPIO_FUNC_SPI))
bi_decl(bi_1pin_with_name(PICO_DEFAULT_SPI_CSN_PIN, "SPI CS"))
bi_decl(bi_1pin_with_name(DC_PIN, "OLED DC"))
bi_decl(bi_1pin_with_name(RST_PIN, "OLED RST"))
bi_decl(bi_program_description("OLED demo"))
bi_decl(bi_1pin_with_name(LED_PIN, "Blink LED"))
static inline void cs_select() {
asm volatile("nop \n nop \n nop");
gpio_put(PICO_DEFAULT_SPI_CSN_PIN, 0); // Active low
asm volatile("nop \n nop \n nop");
}
static inline void cs_deselect() {
asm volatile("nop \n nop \n nop");
gpio_put(PICO_DEFAULT_SPI_CSN_PIN, 1);
asm volatile("nop \n nop \n nop");
}
static inline void dc_command() {
gpio_put(DC_PIN, 0);
}
static inline void dc_data() {
gpio_put(DC_PIN, 1);
}
static void oled_command16(uint8_t cmd, uint8_t arg) {
uint8_t buf[2];
buf[0] = cmd;
buf[1] = arg;
dc_command();
cs_select();
spi_write_blocking(spi_default, buf, 2);
cs_deselect();
}
static void oled_command(uint8_t cmd) {
dc_command();
cs_select();
spi_write_blocking(spi_default, &cmd, 1);
cs_deselect();
}
static void oled_reset() {
// Issue a display reset
gpio_put(RST_PIN, 0);
sleep_ms(1);
gpio_put(RST_PIN, 1);
sleep_ms(1);
}
int main() {
bi_decl(bi_program_description("This is a test binary."));
bi_decl(bi_1pin_with_name(LED_PIN, "On-board LED"));
stdio_init_all();
gpio_init(LED_PIN);
gpio_set_dir(LED_PIN, GPIO_OUT);
// This example will use SPI0 at 10MHz.
spi_init(spi_default, 10 * 1000 * 1000);
gpio_set_function(PICO_DEFAULT_SPI_SCK_PIN, GPIO_FUNC_SPI);
gpio_set_function(PICO_DEFAULT_SPI_TX_PIN, GPIO_FUNC_SPI);
// Chip select is active-low, so we'll initialise it to a driven-high state
gpio_init(PICO_DEFAULT_SPI_CSN_PIN);
gpio_set_dir(PICO_DEFAULT_SPI_CSN_PIN, GPIO_OUT);
gpio_put(PICO_DEFAULT_SPI_CSN_PIN, 1);
gpio_init(DC_PIN);
gpio_set_dir(DC_PIN, GPIO_OUT);
gpio_init(RST_PIN);
gpio_set_dir(RST_PIN, GPIO_OUT);
oled_reset();
// simplified display init
oled_command(0xAE); /* Display off */
//oled_command16(0xD5, 0xF0); // set clock speed
oled_command16(0x20, 0b00); // page addressing mode: 00 - horizontal, 01 vertical, 10 page
oled_command16(0x81, 0xFF);
//oled_command16(0xD9, 0xff);
oled_command(0xAF); /*--turn on SSD1309 panel */
#if 0
/* Init OLED */
oled_command(0xAE); /* Display off */
// Configure the display - only setting things that differ from the default:
oled_command16(0x20, 0b10); /* Set Memory Addressing Mode */
/* 00,Horizontal Addressing Mode; 01,Vertical Addressing Mode; */
/* 10,Page Addressing Mode (RESET); 11,Invalid */
oled_command(0xB0); /*Set Page Start Address for Page Addressing Mode, B0-B7 */
#ifdef SSD1309_MIRROR_VERT
oled_command(0xC1);
#else
oled_command(0xC0);
#endif
// lower nibble is value
oled_command(0x00); /*---set low column address 00~0F */
oled_command(0x10); /*---set high column address 10~1F */
oled_command(0x40); /*--set start line address - 40~7F */
oled_command16(0x81, 0x7F); /*--set contrast control register - ? 0xFF */
#ifdef SSD1309_MIRROR_HORIZ
oled_command(0xA1);
#else
oled_command(0xA0);
#endif
#ifdef SSD1309_INVERSE_COLOR
oled_command(0xA7); /*--set inverse color */
#else
oled_command(0xA6); /*--set normal color */
#endif
/*--set multiplex ratio(1 to 64) */
#if (SSD1309_HEIGHT == 32)
oled_command16(0xA8, 0x1F);
#elif (SSD1309_HEIGHT == 64)
oled_command16(0xA8, 0x3F);
#else
#error "bad height"
#endif
oled_command(0xA4); /* 0xA4, Output follows RAM content;0xa5,Output ignores RAM content */
oled_command16(0xD3, 0x00); /*-set display offset */
oled_command16(0xD5, 0xF0); /*--set display clock divide ratio/oscillator frequency */
oled_command16(0xD9, 0x22); /*--set pre-charge period */
/*--set com pins hardware configuration */
#if (SSD1309_HEIGHT == 32)
oled_command16(0xDA, 0x02);
#elif (SSD1309_HEIGHT == 64)
oled_command16(0xDA, 0x12);
#else
#error "bad height"
#endif
oled_command16(0xDB, 0x34); /*--set vcomh */
// ??? not listed in the datasheet
// oled_command(0x8D); /*--set DC-DC enable */
// oled_command(0x14); /* */
oled_command(0xAF); /*--turn on SSD1309 panel */
oled_command(0xA5); // entire display on - for test
#endif
oled_init();
#define ZIR_W 12
#define ZIR_H 24
@ -239,27 +71,18 @@ int main() {
fb_clear();
fb_bitmap(5, 5, ZIR_W, ZIR_H, zirafa, 1);
fb_text(40, 23, "MEOW", FONT_DOUBLE, 1);
fb_text(50, 35, "meow", FONT_DOUBLE, 1);
fb_text(40, 35, "MEOW", FONT_DOUBLE, 1);
fb_text(50, 20, "meow", FONT_DOUBLE, 1);
fb_frame(0, 0, 128, 64, 2, 1);
fb_blit();
// dc_data();
// cs_select();
// uint8_t pattern = 0;
// for (uint i = 0; i < 128 * 8; i++) {
// pattern = i & 0xFF;
// spi_write_blocking(spi_default, &pattern, 1);
// }
// cs_deselect();
while (1) {
oled_command(0xA6); // invert
oled_invert(true);
gpio_put(LED_PIN, 0);
sleep_ms(1000);
oled_command(0xA7); // uninvert
oled_invert(false);
gpio_put(LED_PIN, 1);
@ -267,10 +90,3 @@ int main() {
sleep_ms(1000);
}
}
void fb_blit() {
dc_data();
cs_select();
spi_write_blocking(spi_default, fb, FB_LEN);
cs_deselect();
}

199
oled.c

@ -0,0 +1,199 @@
//
// Created by MightyPork on 2022/12/28.
//
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
#include "pico/binary_info.h"
#include "hardware/spi.h"
#include "framebuffer.h"
static const uint DC_PIN = 20;
static const uint RST_PIN = 21;
#define SSD1309_HEIGHT 64
/* Picotool info */
// Make the SPI pins available to picotool
bi_decl(bi_2pins_with_func(PICO_DEFAULT_SPI_TX_PIN, PICO_DEFAULT_SPI_SCK_PIN, GPIO_FUNC_SPI))
bi_decl(bi_1pin_with_name(PICO_DEFAULT_SPI_CSN_PIN, "SPI CS"))
bi_decl(bi_1pin_with_name(DC_PIN, "OLED DC"))
bi_decl(bi_1pin_with_name(RST_PIN, "OLED RST"))
static inline void cs_select() {
asm volatile("nop \n nop \n nop");
gpio_put(PICO_DEFAULT_SPI_CSN_PIN, 0); // Active low
asm volatile("nop \n nop \n nop");
}
static inline void cs_deselect() {
asm volatile("nop \n nop \n nop");
gpio_put(PICO_DEFAULT_SPI_CSN_PIN, 1);
asm volatile("nop \n nop \n nop");
}
static inline void dc_command() {
gpio_put(DC_PIN, 0);
}
static inline void dc_data() {
gpio_put(DC_PIN, 1);
}
void oled_command16(uint8_t cmd, uint8_t arg) {
uint8_t buf[2];
buf[0] = cmd;
buf[1] = arg;
dc_command();
cs_select();
spi_write_blocking(spi_default, buf, 2);
cs_deselect();
}
void oled_command(uint8_t cmd) {
dc_command();
cs_select();
spi_write_blocking(spi_default, &cmd, 1);
cs_deselect();
}
void oled_reset() {
// Issue a display reset
gpio_put(RST_PIN, 0);
sleep_ms(1);
gpio_put(RST_PIN, 1);
sleep_ms(1);
}
void oled_invert(bool invert) {
if (invert) {
oled_command(0xA6);
} else {
oled_command(0xA7);
}
}
void oled_init() {
// This example will use SPI0 at 10MHz.
spi_init(spi_default, 10 * 1000 * 1000);
gpio_set_function(PICO_DEFAULT_SPI_SCK_PIN, GPIO_FUNC_SPI);
gpio_set_function(PICO_DEFAULT_SPI_TX_PIN, GPIO_FUNC_SPI);
// Chip select is active-low, so we'll initialise it to a driven-high state
gpio_init(PICO_DEFAULT_SPI_CSN_PIN);
gpio_set_dir(PICO_DEFAULT_SPI_CSN_PIN, GPIO_OUT);
gpio_put(PICO_DEFAULT_SPI_CSN_PIN, 1);
gpio_init(DC_PIN);
gpio_set_dir(DC_PIN, GPIO_OUT);
gpio_init(RST_PIN);
gpio_set_dir(RST_PIN, GPIO_OUT);
oled_reset();
// simplified display init
oled_command(0xAE); /* Display off */
//oled_command16(0xD5, 0xF0); // set clock speed
oled_command16(0x20, 0b00); // page addressing mode: 00 - horizontal, 01 vertical, 10 page
oled_command16(0x81, 0xFF); // contrast
oled_command(0xAF); /*--turn on SSD1309 panel */
#if 0
/* Init OLED */
oled_command(0xAE); /* Display off */
// Configure the display - only setting things that differ from the default:
oled_command16(0x20, 0b10); /* Set Memory Addressing Mode */
/* 00,Horizontal Addressing Mode; 01,Vertical Addressing Mode; */
/* 10,Page Addressing Mode (RESET); 11,Invalid */
oled_command(0xB0); /*Set Page Start Address for Page Addressing Mode, B0-B7 */
#ifdef SSD1309_MIRROR_VERT
oled_command(0xC1);
#else
oled_command(0xC0);
#endif
// lower nibble is value
oled_command(0x00); /*---set low column address 00~0F */
oled_command(0x10); /*---set high column address 10~1F */
oled_command(0x40); /*--set start line address - 40~7F */
oled_command16(0x81, 0x7F); /*--set contrast control register - ? 0xFF */
#ifdef SSD1309_MIRROR_HORIZ
oled_command(0xA1);
#else
oled_command(0xA0);
#endif
#ifdef SSD1309_INVERSE_COLOR
oled_command(0xA7); /*--set inverse color */
#else
oled_command(0xA6); /*--set normal color */
#endif
/*--set multiplex ratio(1 to 64) */
#if (SSD1309_HEIGHT == 32)
oled_command16(0xA8, 0x1F);
#elif (SSD1309_HEIGHT == 64)
oled_command16(0xA8, 0x3F);
#else
#error "bad height"
#endif
oled_command(0xA4); /* 0xA4, Output follows RAM content;0xa5,Output ignores RAM content */
oled_command16(0xD3, 0x00); /*-set display offset */
oled_command16(0xD5, 0xF0); /*--set display clock divide ratio/oscillator frequency */
oled_command16(0xD9, 0x22); /*--set pre-charge period */
/*--set com pins hardware configuration */
#if (SSD1309_HEIGHT == 32)
oled_command16(0xDA, 0x02);
#elif (SSD1309_HEIGHT == 64)
oled_command16(0xDA, 0x12);
#else
#error "bad height"
#endif
oled_command16(0xDB, 0x34); /*--set vcomh */
// ??? not listed in the datasheet
// oled_command(0x8D); /*--set DC-DC enable */
// oled_command(0x14); /* */
oled_command(0xAF); /*--turn on SSD1309 panel */
oled_command(0xA5); // entire display on - for test
#endif
}
void oled_data(uint8_t *data, size_t len) {
dc_data();
cs_select();
spi_write_blocking(spi_default, data, len);
cs_deselect();
}
void fb_blit() {
oled_data(fb, FB_LEN);
}

@ -0,0 +1,19 @@
//
// Created by MightyPork on 2022/12/28.
//
#ifndef TEST_PROJECT_OLED_H
#define TEST_PROJECT_OLED_H
#include <stdint.h>
#include <stddef.h>
void oled_init();
void oled_reset();
void oled_command(uint8_t cmd);
void oled_command16(uint8_t cmd, uint8_t arg);
void oled_invert(bool invert);
void oled_data(uint8_t *data, size_t len);
#endif //TEST_PROJECT_OLED_H
Loading…
Cancel
Save