Compare commits

..

No commits in common. "c4250df4b5c2e2b959a97f6e85ae770de7b3702b" and "2d1278daa1ec36070a7ccf9ff78af7d5f27d2e34" have entirely different histories.

5 changed files with 68 additions and 117 deletions

3
.gitignore vendored
View File

@ -1,4 +1,3 @@
build
.cache
compile_commands.json
.ccls-cache
compile-commands.json

View File

@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.13)
set(PICO_SDK_PATH "${CMAKE_CURRENT_SOURCE_DIR}/pico-sdk")
include(pico_sdk_import.cmake)
project(SSD1306 C CXX ASM)
project(SH1106 C CXX ASM)
pico_sdk_init()
add_subdirectory(src)

View File

@ -5,6 +5,5 @@ add_executable(main
target_link_libraries(main pico_stdlib hardware_i2c hardware_uart)
pico_enable_stdio_uart(main 0)
pico_enable_stdio_usb(main 1)
pico_add_extra_outputs(main)

View File

@ -3,117 +3,64 @@
#include "hardware/gpio.h"
#include "hardware/i2c.h"
#include "pico/error.h"
#include <pico/stdlib.h>
#include <pico/stdio.h>
#include <cstdio>
#define ADDR 0x3c
static bool failure = false;
int main(void) {
stdio_init_all();
busy_wait_ms(1000);
sh1106_disp disp;
gpio_init(25);
gpio_set_dir(25, GPIO_OUT);
i2c_init(i2c0, 115200);
gpio_init(0);
gpio_init(1);
gpio_set_function(0, GPIO_FUNC_I2C);
gpio_set_function(1, GPIO_FUNC_I2C);
ssd1306 disp;
busy_wait_ms(100);
while (true) {
/*
gpio_put(25, false);
busy_wait_ms(failure ? 50 : 500);
gpio_put(25, true);
busy_wait_ms(failure ? 50 : 500);
*/
disp.poweron();
disp.test();
busy_wait_ms(10);
while (true) {
gpio_put(25, false);
busy_wait_ms(failure ? 500 : 50);
gpio_put(25, true);
busy_wait_ms(failure ? 500 : 50);
}
return 0;
}
static void write_cmd(uint8_t cmd) {
uint8_t buf[2] = {0x80, cmd};
if (i2c_write_timeout_us(i2c0, ADDR, buf, 2, false, 1000000) < 0) {
failure = true;
printf("TX fail\n");
} else {
printf("TX succ\n");
sh1106_i2c::sh1106_i2c(uint8_t addr) : m_addr(addr) {
m_i2c = i2c0;
i2c_init(i2c0, 200000);
gpio_init(0);
gpio_init(1);
gpio_set_function(0, GPIO_FUNC_I2C);
gpio_set_function(1, GPIO_FUNC_I2C);
}
void sh1106_i2c::write_cmd(uint8_t cmd) {
failure |= i2c_write_blocking(i2c0, m_addr, &cmd, 1, false) < 0;
}
void sh1106_i2c::write_data(const uint8_t *data, size_t len) {
for (size_t i = 0; i < len; i++) {
failure |= i2c_write_blocking(i2c0, m_addr, &data[i], 1, false) < 0;
}
}
static void write_data(uint8_t *data, size_t len) {
if (i2c_write_timeout_us(i2c0, ADDR, data, len, false, 1000000) < 0) {
failure = true;
printf("data fail\n");
} else {
printf("data succ\n");
}
}
ssd1306::ssd1306() {
write_cmd(SET_DISP | 0x00); // Off
//
write_cmd(SET_MUX_RATIO); // The height
write_cmd(63); // The height
write_cmd(SET_DISP_OFFSET); // No offset
write_cmd(0x00); // No offset
write_cmd(SET_DISP_START_LINE | 0x00); // Resolution and layout
write_cmd(SET_SEG_REMAP | 0x01);
write_cmd(SET_COM_OUT_DIR | 0x08); // Scan from COM[N] to COM0
write_cmd(SET_COM_PIN_CFG);
write_cmd(0x02);
write_cmd(SET_CONTRAST);
write_cmd(0xFF);
write_cmd(SET_ENTIRE_ON);
write_cmd(SET_NORM_INV | 0x00);
write_cmd(SET_DISP_CLK_DIV);
write_cmd(0x80);
write_cmd(SET_PRECHARGE);
write_cmd(0x22);
write_cmd(SET_CHARGE_PUMP);
write_cmd(0x14);
write_cmd(SET_DISP | 0x01);
write_cmd(SET_MEM_ADDR);
write_cmd(0x00); // Horizontal
/*
write_cmd(SET_VCOM_DESEL);
write_cmd(0x30);
*/
write_cmd(SET_COL_ADDR);
write_cmd(0);
write_cmd(127);
write_cmd(SET_PAGE_ADDR);
write_cmd(0);
write_cmd(63);
}
void ssd1306::test() {
static bool flip = true;
uint8_t buf[2] = {0x40, 0x00};
write_data(buf, 2);
sh1106_disp::sh1106_disp() : m_i2c_conn(0x3c) {}
void sh1106_disp::poweron() { m_i2c_conn.write_cmd(SH1106_SET_DISP | 0x00); }
void sh1106_disp::poweroff() { m_i2c_conn.write_cmd(SH1106_SET_DISP | 0x01); }
void sh1106_disp::test() {
uint8_t buf[3] = {0xFF};
m_i2c_conn.write_cmd(SH1106_SET_PAGE_ADDRESS | 0x0);
m_i2c_conn.write_cmd(SH1106_SET_HIGH_COLUMN_ADDRESS | 0x2);
m_i2c_conn.write_cmd(SH1106_SET_LOW_COLUMN_ADDRESS | 0x0);
m_i2c_conn.write_cmd(SH1106_SET_CONTRAST);
m_i2c_conn.write_cmd(0xFF);
m_i2c_conn.write_cmd(SH1106_SET_NORM_INV | 0x1);
}

View File

@ -3,29 +3,35 @@
#include <stdint.h>
#define SET_CONTRAST (0x81)
#define SET_ENTIRE_ON (0xA4)
#define SET_NORM_INV (0xA6)
#define SET_DISP (0xAE)
#define SET_MEM_ADDR (0x20)
#define SET_COL_ADDR (0x21)
#define SET_PAGE_ADDR (0x22)
#define SET_DISP_START_LINE (0x40)
#define SET_SEG_REMAP (0xA0)
#define SET_MUX_RATIO (0xA8)
#define SET_COM_OUT_DIR (0xC0)
#define SET_DISP_OFFSET (0xD3)
#define SET_COM_PIN_CFG (0xDA)
#define SET_DISP_CLK_DIV (0xD5)
#define SET_PRECHARGE (0xD9)
#define SET_VCOM_DESEL (0xDB)
#define SET_CHARGE_PUMP (0x8D)
const uint8_t SH1106_SET_CONTRAST = 0x81u;
const uint8_t SH1106_SET_NORM_INV = 0xa6u;
const uint8_t SH1106_SET_DISP = 0xaeu;
const uint8_t SH1106_SET_SCAN_DIR = 0xc0u;
const uint8_t SH1106_SET_SEG_REMAP = 0xa0u;
const uint8_t SH1106_SET_LOW_COLUMN_ADDRESS = 0x00u;
const uint8_t SH1106_SET_HIGH_COLUMN_ADDRESS = 0x10u;
const uint8_t SH1106_SET_PAGE_ADDRESS = 0xb0u;
class sh1106_i2c {
private:
i2c_inst_t *m_i2c;
uint8_t m_addr;
class ssd1306 {
public:
ssd1306();
sh1106_i2c(uint8_t addr);
void poweron();
void test();
void write_cmd(uint8_t cmd);
void write_data(const uint8_t *data, size_t len);
};
class sh1106_disp {
private:
sh1106_i2c m_i2c_conn;
public:
sh1106_disp();
void poweron();
void poweroff();
void test();
};