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 build
.cache .cache
compile_commands.json compile-commands.json
.ccls-cache

View File

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

View File

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

View File

@ -3,117 +3,64 @@
#include "hardware/gpio.h" #include "hardware/gpio.h"
#include "hardware/i2c.h" #include "hardware/i2c.h"
#include "pico/error.h" #include "pico/error.h"
#include <pico/stdlib.h>
#include <pico/stdio.h>
#include <cstdio>
#define ADDR 0x3c
static bool failure = false; static bool failure = false;
int main(void) { int main(void) {
stdio_init_all(); sh1106_disp disp;
busy_wait_ms(1000);
gpio_init(25); gpio_init(25);
gpio_set_dir(25, GPIO_OUT); 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); busy_wait_ms(100);
disp.poweron();
disp.test();
while (true) { while (true) {
/*
gpio_put(25, false); gpio_put(25, false);
busy_wait_ms(failure ? 50 : 500); busy_wait_ms(failure ? 500 : 50);
gpio_put(25, true); gpio_put(25, true);
busy_wait_ms(failure ? 50 : 500); busy_wait_ms(failure ? 500 : 50);
*/
disp.test();
busy_wait_ms(10);
} }
return 0; return 0;
} }
static void write_cmd(uint8_t cmd) { sh1106_i2c::sh1106_i2c(uint8_t addr) : m_addr(addr) {
uint8_t buf[2] = {0x80, cmd}; m_i2c = i2c0;
if (i2c_write_timeout_us(i2c0, ADDR, buf, 2, false, 1000000) < 0) {
failure = true; i2c_init(i2c0, 200000);
printf("TX fail\n");
} else { gpio_init(0);
printf("TX succ\n"); 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) { sh1106_disp::sh1106_disp() : m_i2c_conn(0x3c) {}
if (i2c_write_timeout_us(i2c0, ADDR, data, len, false, 1000000) < 0) {
failure = true; void sh1106_disp::poweron() { m_i2c_conn.write_cmd(SH1106_SET_DISP | 0x00); }
printf("data fail\n");
} else { void sh1106_disp::poweroff() { m_i2c_conn.write_cmd(SH1106_SET_DISP | 0x01); }
printf("data succ\n");
} 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);
ssd1306::ssd1306() { m_i2c_conn.write_cmd(SH1106_SET_LOW_COLUMN_ADDRESS | 0x0);
write_cmd(SET_DISP | 0x00); // Off m_i2c_conn.write_cmd(SH1106_SET_CONTRAST);
// m_i2c_conn.write_cmd(0xFF);
write_cmd(SET_MUX_RATIO); // The height m_i2c_conn.write_cmd(SH1106_SET_NORM_INV | 0x1);
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);
} }

View File

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