From d8ce0b404945dab3a436eb2c7f294f73aa617efc Mon Sep 17 00:00:00 2001 From: Archie Hilton Date: Wed, 26 Jun 2024 23:39:14 +0100 Subject: [PATCH] Initial commit --- .clangd | 5 +++ .gitignore | 2 ++ .gitmodules | 3 ++ CMakeLists.txt | 9 ++++++ compile_commands.json | 1 + pico-sdk | 1 + pico_sdk_import.cmake | 73 +++++++++++++++++++++++++++++++++++++++++++ src/CMakeLists.txt | 9 ++++++ src/main.cc | 66 ++++++++++++++++++++++++++++++++++++++ src/main.hh | 37 ++++++++++++++++++++++ 10 files changed, 206 insertions(+) create mode 100755 .clangd create mode 100644 .gitignore create mode 100644 .gitmodules create mode 100755 CMakeLists.txt create mode 120000 compile_commands.json create mode 160000 pico-sdk create mode 100644 pico_sdk_import.cmake create mode 100644 src/CMakeLists.txt create mode 100644 src/main.cc create mode 100644 src/main.hh diff --git a/.clangd b/.clangd new file mode 100755 index 0000000..bf0f570 --- /dev/null +++ b/.clangd @@ -0,0 +1,5 @@ +CompileFlags: + #Add: [--query-driver=/usr/bin/arm-none-eabi-g++] + Compiler: /usr/bin/arm-none-eabi-g++ + + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9785597 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +build +.cache diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..643f237 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "pico-sdk"] + path = pico-sdk + url = https://github.com/raspberrypi/pico-sdk diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100755 index 0000000..94c0fca --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,9 @@ +cmake_minimum_required(VERSION 3.13) + +set(PICO_SDK_PATH "${CMAKE_CURRENT_SOURCE_DIR}/pico-sdk") +include(pico_sdk_import.cmake) + +project(SH1106 C CXX ASM) +pico_sdk_init() + +add_subdirectory(src) diff --git a/compile_commands.json b/compile_commands.json new file mode 120000 index 0000000..25eb4b2 --- /dev/null +++ b/compile_commands.json @@ -0,0 +1 @@ +build/compile_commands.json \ No newline at end of file diff --git a/pico-sdk b/pico-sdk new file mode 160000 index 0000000..6a7db34 --- /dev/null +++ b/pico-sdk @@ -0,0 +1 @@ +Subproject commit 6a7db34ff63345a7badec79ebea3aaef1712f374 diff --git a/pico_sdk_import.cmake b/pico_sdk_import.cmake new file mode 100644 index 0000000..65f8a6f --- /dev/null +++ b/pico_sdk_import.cmake @@ -0,0 +1,73 @@ +# This is a copy of /external/pico_sdk_import.cmake + +# This can be dropped into an external project to help locate this SDK +# It should be include()ed prior to project() + +if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH)) + set(PICO_SDK_PATH $ENV{PICO_SDK_PATH}) + message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')") +endif () + +if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT)) + set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT}) + message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')") +endif () + +if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH)) + set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH}) + message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')") +endif () + +set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK") +set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable") +set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK") + +if (NOT PICO_SDK_PATH) + if (PICO_SDK_FETCH_FROM_GIT) + include(FetchContent) + set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR}) + if (PICO_SDK_FETCH_FROM_GIT_PATH) + get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}") + endif () + # GIT_SUBMODULES_RECURSE was added in 3.17 + if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.17.0") + FetchContent_Declare( + pico_sdk + GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk + GIT_TAG master + GIT_SUBMODULES_RECURSE FALSE + ) + else () + FetchContent_Declare( + pico_sdk + GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk + GIT_TAG master + ) + endif () + + if (NOT pico_sdk) + message("Downloading Raspberry Pi Pico SDK") + FetchContent_Populate(pico_sdk) + set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR}) + endif () + set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE}) + else () + message(FATAL_ERROR + "SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git." + ) + endif () +endif () + +get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}") +if (NOT EXISTS ${PICO_SDK_PATH}) + message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found") +endif () + +set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake) +if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE}) + message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK") +endif () + +set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE) + +include(${PICO_SDK_INIT_CMAKE_FILE}) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..fa70ec5 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,9 @@ +add_executable(main + main.cc + ) + +target_link_libraries(main pico_stdlib hardware_i2c hardware_uart) + +pico_enable_stdio_uart(main 0) + +pico_add_extra_outputs(main) diff --git a/src/main.cc b/src/main.cc new file mode 100644 index 0000000..d9b63fb --- /dev/null +++ b/src/main.cc @@ -0,0 +1,66 @@ +#include "main.hh" + +#include "hardware/gpio.h" +#include "hardware/i2c.h" +#include "pico/error.h" + +static bool failure = false; + +int main(void) { + sh1106_disp disp; + + gpio_init(25); + gpio_set_dir(25, GPIO_OUT); + + busy_wait_ms(100); + + disp.poweron(); + disp.test(); + + while (true) { + gpio_put(25, false); + busy_wait_ms(failure ? 500 : 50); + gpio_put(25, true); + busy_wait_ms(failure ? 500 : 50); + } + + return 0; +} + +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; + } +} + +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); +} diff --git a/src/main.hh b/src/main.hh new file mode 100644 index 0000000..b0eafa8 --- /dev/null +++ b/src/main.hh @@ -0,0 +1,37 @@ +#pragma once +#include + +#include + +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; + +public: + sh1106_i2c(uint8_t addr); + + 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(); +};