you know what let's just paste code
This commit is contained in:
parent
6e309f296a
commit
a729ede7e7
15 changed files with 417 additions and 41 deletions
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -1,3 +0,0 @@
|
||||||
[submodule "pico-sdk"]
|
|
||||||
path = pico-sdk
|
|
||||||
url = https://github.com/raspberrypi/pico-sdk
|
|
16
.vscode/c_cpp_properties.json
vendored
16
.vscode/c_cpp_properties.json
vendored
|
@ -1,17 +1,21 @@
|
||||||
{
|
{
|
||||||
"configurations": [
|
"configurations": [
|
||||||
{
|
{
|
||||||
"name": "Linux",
|
"name": "Pico",
|
||||||
"includePath": [
|
"includePath": [
|
||||||
"${workspaceFolder}/**",
|
"${workspaceFolder}/**",
|
||||||
"${workspaceFolder}/pico-sdk"
|
"${env:HOME}/.pico-sdk/sdk/1.5.1/**"
|
||||||
|
],
|
||||||
|
"forcedInclude": [
|
||||||
|
"${env:HOME}/.pico-sdk/sdk/1.5.1/src/common/pico_base/include/pico.h",
|
||||||
|
"${workspaceFolder}/build/generated/pico_base/pico/config_autogen.h"
|
||||||
],
|
],
|
||||||
"defines": [],
|
"defines": [],
|
||||||
"compilerPath": "/usr/bin/gcc",
|
"compilerPath": "${env:HOME}/.pico-sdk/toolchain/13_2_Rel1/bin/arm-none-eabi-gcc",
|
||||||
|
"compileCommands": "${workspaceFolder}/build/compile_commands.json",
|
||||||
"cStandard": "c17",
|
"cStandard": "c17",
|
||||||
"cppStandard": "gnu++17",
|
"cppStandard": "c++14",
|
||||||
"intelliSenseMode": "linux-gcc-x64",
|
"intelliSenseMode": "linux-gcc-arm"
|
||||||
"configurationProvider": "none"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"version": 4
|
"version": 4
|
||||||
|
|
16
.vscode/cmake-kits.json
vendored
Normal file
16
.vscode/cmake-kits.json
vendored
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "Pico",
|
||||||
|
"compilers": {
|
||||||
|
"C": "${env:HOME}/.pico-sdk/toolchain/13_2_Rel1/bin/arm-none-eabi-gcc",
|
||||||
|
"CXX": "${env:HOME}/.pico-sdk/toolchain/13_2_Rel1/bin/arm-none-eabi-gcc"
|
||||||
|
},
|
||||||
|
"toolchainFile": "${env:HOME}/.pico-sdk/sdk/1.5.1/cmake/preload/toolchains/pico_arm_gcc.cmake",
|
||||||
|
"environmentVariables": {
|
||||||
|
"PATH": "${command:raspberry-pi-pico.getEnvPath};${env:PATH}"
|
||||||
|
},
|
||||||
|
"cmakeSettings": {
|
||||||
|
"Python3_EXECUTABLE": "${command:raspberry-pi-pico.getPythonPath}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
9
.vscode/extensions.json
vendored
Normal file
9
.vscode/extensions.json
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"recommendations": [
|
||||||
|
"marus25.cortex-debug",
|
||||||
|
"ms-vscode.cpptools",
|
||||||
|
"ms-vscode.cpptools-extension-pack",
|
||||||
|
"ms-vscode.vscode-serial-monitor",
|
||||||
|
"raspberry-pi.raspberry-pi-pico",
|
||||||
|
]
|
||||||
|
}
|
68
.vscode/launch.json
vendored
Normal file
68
.vscode/launch.json
vendored
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
{
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Pico Debug (Cortex-Debug)",
|
||||||
|
"cwd": "${workspaceRoot}",
|
||||||
|
"executable": "${command:raspberry-pi-pico.launchTargetPath}",
|
||||||
|
"request": "launch",
|
||||||
|
"type": "cortex-debug",
|
||||||
|
"servertype": "openocd",
|
||||||
|
"serverpath": "${userHome}/.pico-sdk/openocd/v0.12.0-2/bin/openocd.exe",
|
||||||
|
"gdbPath": "gdb",
|
||||||
|
"device": "RP2040",
|
||||||
|
"configFiles": [
|
||||||
|
"interface/cmsis-dap.cfg",
|
||||||
|
"target/rp2040.cfg"
|
||||||
|
],
|
||||||
|
"svdFile": "${userHome}/.pico-sdk/sdk/1.5.1/src/rp2040/hardware_regs/rp2040.svd",
|
||||||
|
"runToEntryPoint": "main",
|
||||||
|
// Give restart the same functionality as runToEntryPoint - main
|
||||||
|
"postRestartCommands": [
|
||||||
|
"break main",
|
||||||
|
"continue"
|
||||||
|
],
|
||||||
|
"openOCDLaunchCommands": [
|
||||||
|
"adapter speed 5000"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Pico Debug (Cortex-Debug with external OpenOCD)",
|
||||||
|
"cwd": "${workspaceRoot}",
|
||||||
|
"executable": "${command:raspberry-pi-pico.launchTargetPath}",
|
||||||
|
"request": "launch",
|
||||||
|
"type": "cortex-debug",
|
||||||
|
"servertype": "external",
|
||||||
|
"gdbTarget": "localhost:3333",
|
||||||
|
"gdbPath": "gdb",
|
||||||
|
"device": "RP2040",
|
||||||
|
"svdFile": "${userHome}/.pico-sdk/sdk/1.5.1/src/rp2040/hardware_regs/rp2040.svd",
|
||||||
|
"runToEntryPoint": "main",
|
||||||
|
// Give restart the same functionality as runToEntryPoint - main
|
||||||
|
"postRestartCommands": [
|
||||||
|
"break main",
|
||||||
|
"continue"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Pico Debug (C++ Debugger)",
|
||||||
|
"type": "cppdbg",
|
||||||
|
"request": "launch",
|
||||||
|
"cwd": "${workspaceRoot}",
|
||||||
|
"program": "${command:raspberry-pi-pico.launchTargetPath}",
|
||||||
|
"MIMode": "gdb",
|
||||||
|
"miDebuggerPath": "gdb",
|
||||||
|
"miDebuggerServerAddress": "localhost:3333",
|
||||||
|
"debugServerPath": "${userHome}/.pico-sdk/openocd/v0.12.0-2/bin/openocd.exe",
|
||||||
|
"debugServerArgs": "-f interface/cmsis-dap.cfg -f target/rp2040.cfg -c \"adapter speed 5000\"",
|
||||||
|
"serverStarted": "Listening on port .* for gdb connections",
|
||||||
|
"filterStderr": true,
|
||||||
|
"hardwareBreakpoints": {
|
||||||
|
"require": true,
|
||||||
|
"limit": 4
|
||||||
|
},
|
||||||
|
"preLaunchTask": "Flash",
|
||||||
|
"svdPath": "${userHome}/.pico-sdk/sdk/1.5.1/src/rp2040/hardware_regs/rp2040.svd"
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
39
.vscode/settings.json
vendored
Normal file
39
.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
{
|
||||||
|
"cmake.options.statusBarVisibility": "hidden",
|
||||||
|
"cmake.options.advanced": {
|
||||||
|
"build": {
|
||||||
|
"statusBarVisibility": "hidden"
|
||||||
|
},
|
||||||
|
"launch": {
|
||||||
|
"statusBarVisibility": "hidden"
|
||||||
|
},
|
||||||
|
"debug": {
|
||||||
|
"statusBarVisibility": "hidden"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"cmake.configureOnEdit": false,
|
||||||
|
"cmake.automaticReconfigure": false,
|
||||||
|
"cmake.configureOnOpen": false,
|
||||||
|
"cmake.generator": "Ninja",
|
||||||
|
"cmake.cmakePath": "${userHome}/.pico-sdk/cmake/v3.28.0-rc6/bin/cmake",
|
||||||
|
"C_Cpp.debugShortcut": false,
|
||||||
|
"terminal.integrated.env.windows": {
|
||||||
|
"PICO_SDK_PATH": "${env:USERPROFILE}/.pico-sdk/sdk/1.5.1",
|
||||||
|
"PICO_TOOLCHAIN_PATH": "${env:USERPROFILE}/.pico-sdk/toolchain/13_2_Rel1",
|
||||||
|
"Path": "${env:USERPROFILE}/.pico-sdk/toolchain/13_2_Rel1/bin;${env:USERPROFILE}/.pico-sdk/cmake/v3.28.0-rc6/bin;${env:USERPROFILE}/.pico-sdk/ninja/v1.11.1;${env:PATH}"
|
||||||
|
},
|
||||||
|
"terminal.integrated.env.osx": {
|
||||||
|
"PICO_SDK_PATH": "${env:HOME}/.pico-sdk/sdk/1.5.1",
|
||||||
|
"PICO_TOOLCHAIN_PATH": "${env:HOME}/.pico-sdk/toolchain/13_2_Rel1",
|
||||||
|
"PATH": "${env:HOME}/.pico-sdk/toolchain/13_2_Rel1/bin:${env:HOME}/.pico-sdk/cmake/v3.28.0-rc6/bin:${env:HOME}/.pico-sdk/ninja/v1.11.1:${env:PATH}"
|
||||||
|
},
|
||||||
|
"terminal.integrated.env.linux": {
|
||||||
|
"PICO_SDK_PATH": "${env:HOME}/.pico-sdk/sdk/1.5.1",
|
||||||
|
"PICO_TOOLCHAIN_PATH": "${env:HOME}/.pico-sdk/toolchain/13_2_Rel1",
|
||||||
|
"PATH": "${env:HOME}/.pico-sdk/toolchain/13_2_Rel1/bin:${env:HOME}/.pico-sdk/cmake/v3.28.0-rc6/bin:${env:HOME}/.pico-sdk/ninja/v1.11.1:${env:PATH}"
|
||||||
|
},
|
||||||
|
"raspberry-pi-pico.cmakeAutoConfigure": true,
|
||||||
|
"raspberry-pi-pico.useCmakeTools": false,
|
||||||
|
"raspberry-pi-pico.cmakePath": "${HOME}/.pico-sdk/cmake/v3.28.0-rc6/bin/cmake",
|
||||||
|
"raspberry-pi-pico.ninjaPath": "${HOME}/.pico-sdk/ninja/v1.11.1/ninja"
|
||||||
|
}
|
38
.vscode/tasks.json
vendored
Normal file
38
.vscode/tasks.json
vendored
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
{
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"label": "Compile Project",
|
||||||
|
"type": "process",
|
||||||
|
"isBuildCommand": true,
|
||||||
|
"command": "${userHome}/.pico-sdk/ninja/v1.11.1/ninja",
|
||||||
|
"args": ["-C", "${workspaceFolder}/build"],
|
||||||
|
"group": "build",
|
||||||
|
"presentation": {
|
||||||
|
"reveal": "always",
|
||||||
|
"panel": "dedicated"
|
||||||
|
},
|
||||||
|
"problemMatcher": "$gcc",
|
||||||
|
"windows": {
|
||||||
|
"command": "${env:USERPROFILE}/.pico-sdk/ninja/v1.11.1/ninja.exe"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Flash",
|
||||||
|
"type": "process",
|
||||||
|
"command": "${userHome}/.pico-sdk/openocd/v0.12.0-2/bin/openocd.exe",
|
||||||
|
"args": [
|
||||||
|
"-f",
|
||||||
|
"interface/cmsis-dap.cfg",
|
||||||
|
"-f",
|
||||||
|
"target/rp2040.cfg",
|
||||||
|
"-c",
|
||||||
|
"adapter speed 5000; program \"${command:raspberry-pi-pico.launchTargetPath}\" verify reset exit"
|
||||||
|
],
|
||||||
|
"problemMatcher": [],
|
||||||
|
"windows": {
|
||||||
|
"command": "${env:USERPROFILE}/.pico-sdk/openocd/v0.12.0-2/bin/openocd.exe",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -1,7 +1,19 @@
|
||||||
|
# == DO NEVER EDIT THE NEXT LINES for Raspberry Pi Pico VS Code Extension to work ==
|
||||||
|
if(WIN32)
|
||||||
|
set(USERHOME $ENV{USERPROFILE})
|
||||||
|
else()
|
||||||
|
set(USERHOME $ENV{HOME})
|
||||||
|
endif()
|
||||||
|
set(PICO_SDK_PATH ${USERHOME}/.pico-sdk/sdk/1.5.1)
|
||||||
|
set(PICO_TOOLCHAIN_PATH ${USERHOME}/.pico-sdk/toolchain/13_2_Rel1)
|
||||||
|
if(WIN32)
|
||||||
|
set(pico-sdk-tools_DIR ${USERHOME}/.pico-sdk/tools/1.5.1)
|
||||||
|
include(${pico-sdk-tools_DIR}/pico-sdk-tools-config.cmake)
|
||||||
|
include(${pico-sdk-tools_DIR}/pico-sdk-tools-config-version.cmake)
|
||||||
|
endif()
|
||||||
|
# ====================================================================================
|
||||||
cmake_minimum_required(VERSION 3.13)
|
cmake_minimum_required(VERSION 3.13)
|
||||||
|
|
||||||
set(PICO_SDK_PATH ../pico-sdk)
|
|
||||||
|
|
||||||
# initialize the SDK based on PICO_SDK_PATH
|
# initialize the SDK based on PICO_SDK_PATH
|
||||||
# note: this must happen before project()
|
# note: this must happen before project()
|
||||||
include(pico_sdk_import.cmake)
|
include(pico_sdk_import.cmake)
|
||||||
|
@ -11,13 +23,13 @@ project(dp)
|
||||||
# initialize the Raspberry Pi Pico SDK
|
# initialize the Raspberry Pi Pico SDK
|
||||||
pico_sdk_init()
|
pico_sdk_init()
|
||||||
|
|
||||||
add_executable(dp
|
file(GLOB SOURCES "src/*.c")
|
||||||
src/main.c
|
add_executable(dp ${SOURCES})
|
||||||
src/display.c
|
target_include_directories(dp PRIVATE "${PROJECT_SOURCE_DIR}/include")
|
||||||
)
|
pico_generate_pio_header(pio_st7789_lcd ${CMAKE_CURRENT_LIST_DIR}/st7789_lcd.pio)
|
||||||
|
|
||||||
# Add pico_stdlib library which aggregates commonly used features
|
# Add pico_stdlib library which aggregates commonly used features
|
||||||
target_link_libraries(dp pico_stdlib hardware_spi)
|
target_link_libraries(dp pico_stdlib hardware_pio hardware_interp)
|
||||||
|
|
||||||
# create map/bin/hex/uf2 file in addition to ELF.
|
# create map/bin/hex/uf2 file in addition to ELF.
|
||||||
pico_add_extra_outputs(dp)
|
pico_add_extra_outputs(dp)
|
10
README.md
10
README.md
|
@ -1,5 +1,7 @@
|
||||||
### Usage
|
### Usage
|
||||||
1. `git submodule update --init --recursive`
|
1. create a new directory and enter it
|
||||||
2. `mkdir build && cd build`
|
2. `git clone --recursive https://github.com/raspberrypi/pico-sdk`
|
||||||
3. `cmake ..`
|
3. git clone this repo and cd into it
|
||||||
4. `make`
|
4. `mkdir build && cd build`
|
||||||
|
5. `cmake ..`
|
||||||
|
6. `make`
|
1
include/display.h
Normal file
1
include/display.h
Normal file
|
@ -0,0 +1 @@
|
||||||
|
void init_display();
|
1
pico-sdk
1
pico-sdk
|
@ -1 +0,0 @@
|
||||||
Subproject commit 6a7db34ff63345a7badec79ebea3aaef1712f374
|
|
|
@ -1,11 +0,0 @@
|
||||||
#include "pico/stdlib.h"
|
|
||||||
#include "hardware/spi.h"
|
|
||||||
|
|
||||||
#define TX_PIN 19
|
|
||||||
#define CLK_PIN 18
|
|
||||||
#define CS_PIN 17
|
|
||||||
#define DC_PIN 20
|
|
||||||
|
|
||||||
void init_display() {
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
#include <stdio.h>
|
|
||||||
#include "pico/stdlib.h"
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
setup_default_uart();
|
|
||||||
printf("Hello, world!\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
153
src/st7789_lcd.c
Normal file
153
src/st7789_lcd.c
Normal file
|
@ -0,0 +1,153 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "hardware/pio.h"
|
||||||
|
#include "hardware/gpio.h"
|
||||||
|
#include "hardware/interp.h"
|
||||||
|
|
||||||
|
#include "st7789_lcd.pio.h"
|
||||||
|
#include "raspberry_256x256_rgb565.h"
|
||||||
|
|
||||||
|
// Tested with the parts that have the height of 240 and 320
|
||||||
|
#define SCREEN_WIDTH 240
|
||||||
|
#define SCREEN_HEIGHT 320
|
||||||
|
#define IMAGE_SIZE 256
|
||||||
|
#define LOG_IMAGE_SIZE 8
|
||||||
|
|
||||||
|
#define PIN_DIN 0
|
||||||
|
#define PIN_CLK 1
|
||||||
|
#define PIN_CS 2
|
||||||
|
#define PIN_DC 3
|
||||||
|
#define PIN_RESET 4
|
||||||
|
#define PIN_BL 5
|
||||||
|
|
||||||
|
#define SERIAL_CLK_DIV 1.f
|
||||||
|
|
||||||
|
#ifndef M_PI
|
||||||
|
#define M_PI 3.14159265358979323846
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Format: cmd length (including cmd byte), post delay in units of 5 ms, then cmd payload
|
||||||
|
// Note the delays have been shortened a little
|
||||||
|
static const uint8_t st7789_init_seq[] = {
|
||||||
|
1, 20, 0x01, // Software reset
|
||||||
|
1, 10, 0x11, // Exit sleep mode
|
||||||
|
2, 2, 0x3a, 0x55, // Set colour mode to 16 bit
|
||||||
|
2, 0, 0x36, 0x00, // Set MADCTL: row then column, refresh is bottom to top ????
|
||||||
|
5, 0, 0x2a, 0x00, 0x00, SCREEN_WIDTH >> 8, SCREEN_WIDTH & 0xff, // CASET: column addresses
|
||||||
|
5, 0, 0x2b, 0x00, 0x00, SCREEN_HEIGHT >> 8, SCREEN_HEIGHT & 0xff, // RASET: row addresses
|
||||||
|
1, 2, 0x21, // Inversion on, then 10 ms delay (supposedly a hack?)
|
||||||
|
1, 2, 0x13, // Normal display on, then 10 ms delay
|
||||||
|
1, 2, 0x29, // Main screen turn on, then wait 500 ms
|
||||||
|
0 // Terminate list
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline void lcd_set_dc_cs(bool dc, bool cs) {
|
||||||
|
sleep_us(1);
|
||||||
|
gpio_put_masked((1u << PIN_DC) | (1u << PIN_CS), !!dc << PIN_DC | !!cs << PIN_CS);
|
||||||
|
sleep_us(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void lcd_write_cmd(PIO pio, uint sm, const uint8_t *cmd, size_t count) {
|
||||||
|
st7789_lcd_wait_idle(pio, sm);
|
||||||
|
lcd_set_dc_cs(0, 0);
|
||||||
|
st7789_lcd_put(pio, sm, *cmd++);
|
||||||
|
if (count >= 2) {
|
||||||
|
st7789_lcd_wait_idle(pio, sm);
|
||||||
|
lcd_set_dc_cs(1, 0);
|
||||||
|
for (size_t i = 0; i < count - 1; ++i)
|
||||||
|
st7789_lcd_put(pio, sm, *cmd++);
|
||||||
|
}
|
||||||
|
st7789_lcd_wait_idle(pio, sm);
|
||||||
|
lcd_set_dc_cs(1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void lcd_init(PIO pio, uint sm, const uint8_t *init_seq) {
|
||||||
|
const uint8_t *cmd = init_seq;
|
||||||
|
while (*cmd) {
|
||||||
|
lcd_write_cmd(pio, sm, cmd + 2, *cmd);
|
||||||
|
sleep_ms(*(cmd + 1) * 5);
|
||||||
|
cmd += *cmd + 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void st7789_start_pixels(PIO pio, uint sm) {
|
||||||
|
uint8_t cmd = 0x2c; // RAMWR
|
||||||
|
lcd_write_cmd(pio, sm, &cmd, 1);
|
||||||
|
lcd_set_dc_cs(1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
stdio_init_all();
|
||||||
|
|
||||||
|
PIO pio = pio0;
|
||||||
|
uint sm = 0;
|
||||||
|
uint offset = pio_add_program(pio, &st7789_lcd_program);
|
||||||
|
st7789_lcd_program_init(pio, sm, offset, PIN_DIN, PIN_CLK, SERIAL_CLK_DIV);
|
||||||
|
|
||||||
|
gpio_init(PIN_CS);
|
||||||
|
gpio_init(PIN_DC);
|
||||||
|
gpio_init(PIN_RESET);
|
||||||
|
gpio_init(PIN_BL);
|
||||||
|
gpio_set_dir(PIN_CS, GPIO_OUT);
|
||||||
|
gpio_set_dir(PIN_DC, GPIO_OUT);
|
||||||
|
gpio_set_dir(PIN_RESET, GPIO_OUT);
|
||||||
|
gpio_set_dir(PIN_BL, GPIO_OUT);
|
||||||
|
|
||||||
|
gpio_put(PIN_CS, 1);
|
||||||
|
gpio_put(PIN_RESET, 1);
|
||||||
|
lcd_init(pio, sm, st7789_init_seq);
|
||||||
|
gpio_put(PIN_BL, 1);
|
||||||
|
|
||||||
|
// Other SDKs: static image on screen, lame, boring
|
||||||
|
// Raspberry Pi Pico SDK: spinning image on screen, bold, exciting
|
||||||
|
|
||||||
|
// Lane 0 will be u coords (bits 8:1 of addr offset), lane 1 will be v
|
||||||
|
// coords (bits 16:9 of addr offset), and we'll represent coords with
|
||||||
|
// 16.16 fixed point. ACCUM0,1 will contain current coord, BASE0/1 will
|
||||||
|
// contain increment vector, and BASE2 will contain image base pointer
|
||||||
|
#define UNIT_LSB 16
|
||||||
|
interp_config lane0_cfg = interp_default_config();
|
||||||
|
interp_config_set_shift(&lane0_cfg, UNIT_LSB - 1); // -1 because 2 bytes per pixel
|
||||||
|
interp_config_set_mask(&lane0_cfg, 1, 1 + (LOG_IMAGE_SIZE - 1));
|
||||||
|
interp_config_set_add_raw(&lane0_cfg, true); // Add full accumulator to base with each POP
|
||||||
|
interp_config lane1_cfg = interp_default_config();
|
||||||
|
interp_config_set_shift(&lane1_cfg, UNIT_LSB - (1 + LOG_IMAGE_SIZE));
|
||||||
|
interp_config_set_mask(&lane1_cfg, 1 + LOG_IMAGE_SIZE, 1 + (2 * LOG_IMAGE_SIZE - 1));
|
||||||
|
interp_config_set_add_raw(&lane1_cfg, true);
|
||||||
|
|
||||||
|
interp_set_config(interp0, 0, &lane0_cfg);
|
||||||
|
interp_set_config(interp0, 1, &lane1_cfg);
|
||||||
|
interp0->base[2] = (uint32_t) raspberry_256x256;
|
||||||
|
|
||||||
|
float theta = 0.f;
|
||||||
|
float theta_max = 2.f * (float) M_PI;
|
||||||
|
while (1) {
|
||||||
|
theta += 0.02f;
|
||||||
|
if (theta > theta_max)
|
||||||
|
theta -= theta_max;
|
||||||
|
int32_t rotate[4] = {
|
||||||
|
(int32_t) (cosf(theta) * (1 << UNIT_LSB)), (int32_t) (-sinf(theta) * (1 << UNIT_LSB)),
|
||||||
|
(int32_t) (sinf(theta) * (1 << UNIT_LSB)), (int32_t) (cosf(theta) * (1 << UNIT_LSB))
|
||||||
|
};
|
||||||
|
interp0->base[0] = rotate[0];
|
||||||
|
interp0->base[1] = rotate[2];
|
||||||
|
st7789_start_pixels(pio, sm);
|
||||||
|
for (int y = 0; y < SCREEN_HEIGHT; ++y) {
|
||||||
|
interp0->accum[0] = rotate[1] * y;
|
||||||
|
interp0->accum[1] = rotate[3] * y;
|
||||||
|
for (int x = 0; x < SCREEN_WIDTH; ++x) {
|
||||||
|
uint16_t colour = *(uint16_t *) (interp0->pop[2]);
|
||||||
|
st7789_lcd_put(pio, sm, colour >> 8);
|
||||||
|
st7789_lcd_put(pio, sm, colour & 0xff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
57
src/st7789_lcd.pio
Normal file
57
src/st7789_lcd.pio
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
;
|
||||||
|
; Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
||||||
|
;
|
||||||
|
; SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
;
|
||||||
|
|
||||||
|
.program st7789_lcd
|
||||||
|
.side_set 1
|
||||||
|
|
||||||
|
; This is just a simple clocked serial TX. At 125 MHz system clock we can
|
||||||
|
; sustain up to 62.5 Mbps.
|
||||||
|
; Data on OUT pin 0
|
||||||
|
; Clock on side-set pin 0
|
||||||
|
|
||||||
|
.wrap_target
|
||||||
|
out pins, 1 side 0 ; stall here if no data (clock low)
|
||||||
|
nop side 1
|
||||||
|
.wrap
|
||||||
|
|
||||||
|
% c-sdk {
|
||||||
|
// For optimal use of DMA bandwidth we would use an autopull threshold of 32,
|
||||||
|
// but we are using a threshold of 8 here (consume 1 byte from each FIFO entry
|
||||||
|
// and discard the remainder) to make things easier for software on the other side
|
||||||
|
|
||||||
|
static inline void st7789_lcd_program_init(PIO pio, uint sm, uint offset, uint data_pin, uint clk_pin, float clk_div) {
|
||||||
|
pio_gpio_init(pio, data_pin);
|
||||||
|
pio_gpio_init(pio, clk_pin);
|
||||||
|
pio_sm_set_consecutive_pindirs(pio, sm, data_pin, 1, true);
|
||||||
|
pio_sm_set_consecutive_pindirs(pio, sm, clk_pin, 1, true);
|
||||||
|
pio_sm_config c = st7789_lcd_program_get_default_config(offset);
|
||||||
|
sm_config_set_sideset_pins(&c, clk_pin);
|
||||||
|
sm_config_set_out_pins(&c, data_pin, 1);
|
||||||
|
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX);
|
||||||
|
sm_config_set_clkdiv(&c, clk_div);
|
||||||
|
sm_config_set_out_shift(&c, false, true, 8);
|
||||||
|
pio_sm_init(pio, sm, offset, &c);
|
||||||
|
pio_sm_set_enabled(pio, sm, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Making use of the narrow store replication behaviour on RP2040 to get the
|
||||||
|
// data left-justified (as we are using shift-to-left to get MSB-first serial)
|
||||||
|
|
||||||
|
static inline void st7789_lcd_put(PIO pio, uint sm, uint8_t x) {
|
||||||
|
while (pio_sm_is_tx_fifo_full(pio, sm))
|
||||||
|
;
|
||||||
|
*(volatile uint8_t*)&pio->txf[sm] = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
// SM is done when it stalls on an empty FIFO
|
||||||
|
|
||||||
|
static inline void st7789_lcd_wait_idle(PIO pio, uint sm) {
|
||||||
|
uint32_t sm_stall_mask = 1u << (sm + PIO_FDEBUG_TXSTALL_LSB);
|
||||||
|
pio->fdebug = sm_stall_mask;
|
||||||
|
while (!(pio->fdebug & sm_stall_mask))
|
||||||
|
;
|
||||||
|
}
|
||||||
|
%}
|
Loading…
Reference in a new issue