Add firmware
This commit is contained in:
parent
2e69cea11c
commit
2521dc7949
16
firmware/.cargo/config.toml
Normal file
16
firmware/.cargo/config.toml
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
[target.xtensa-esp32s3-none-elf]
|
||||
runner = "espflash flash --monitor --chip esp32s3"
|
||||
|
||||
[env]
|
||||
ESP_LOG="info"
|
||||
|
||||
[build]
|
||||
rustflags = [
|
||||
"-C", "link-arg=-nostartfiles",
|
||||
"-Z", "stack-protector=all",
|
||||
]
|
||||
|
||||
target = "xtensa-esp32s3-none-elf"
|
||||
|
||||
[unstable]
|
||||
build-std = ["alloc", "core"]
|
||||
42
firmware/.github/workflows/rust_ci.yml
vendored
Normal file
42
firmware/.github/workflows/rust_ci.yml
vendored
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
name: Continuous Integration
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths-ignore:
|
||||
- "**/README.md"
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
jobs:
|
||||
rust-checks:
|
||||
name: Rust Checks
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
action:
|
||||
- command: build
|
||||
args: --release
|
||||
- command: fmt
|
||||
args: --all -- --check
|
||||
- command: clippy
|
||||
args: --all-features --workspace -- -D warnings
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
- name: Setup Rust
|
||||
uses: esp-rs/xtensa-toolchain@v1.5
|
||||
with:
|
||||
default: true
|
||||
buildtargets: esp32s3
|
||||
ldproxy: false
|
||||
- name: Enable caching
|
||||
uses: Swatinem/rust-cache@v2
|
||||
- name: Run command
|
||||
run: cargo ${{ matrix.action.command }} ${{ matrix.action.args }}
|
||||
19
firmware/.gitignore
vendored
Normal file
19
firmware/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
# will have compiled files and executables
|
||||
debug/
|
||||
target/
|
||||
.vscode/
|
||||
.zed/
|
||||
.helix/
|
||||
|
||||
# These are backup files generated by rustfmt
|
||||
**/*.rs.bk
|
||||
|
||||
# MSVC Windows builds of rustc generate these, which store debugging information
|
||||
*.pdb
|
||||
|
||||
# RustRover
|
||||
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
||||
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||
#.idea/
|
||||
1469
firmware/Cargo.lock
generated
Normal file
1469
firmware/Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
52
firmware/Cargo.toml
Normal file
52
firmware/Cargo.toml
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
[package]
|
||||
edition = "2021"
|
||||
name = "acid-firmware"
|
||||
rust-version = "1.86"
|
||||
version = "0.1.0"
|
||||
|
||||
[[bin]]
|
||||
name = "acid-firmware"
|
||||
path = "./src/bin/main.rs"
|
||||
|
||||
[dependencies]
|
||||
# TODO: Remove the `git = ...` fields, which are here because IntelliSense is broken in 1.0.0-rc.0
|
||||
esp-bootloader-esp-idf = { version = "0.2.0", git = "https://github.com/esp-rs/esp-hal", features = ["esp32s3"] }
|
||||
esp-hal = { version = "=1.0.0-rc.0", git = "https://github.com/esp-rs/esp-hal", features = [
|
||||
"esp32s3",
|
||||
"log-04",
|
||||
"unstable",
|
||||
"psram",
|
||||
] }
|
||||
log = "0.4.27"
|
||||
|
||||
critical-section = "1.2.0"
|
||||
embassy-executor = { version = "0.9.0", features = [
|
||||
"log",
|
||||
# "task-arena-size-20480",
|
||||
] }
|
||||
embassy-time = { version = "0.4.0", features = ["log"] }
|
||||
esp-alloc = { version = "0.8.0", git = "https://github.com/esp-rs/esp-hal" }
|
||||
esp-backtrace = { version = "0.17.0", git = "https://github.com/esp-rs/esp-hal", features = [
|
||||
"esp32s3",
|
||||
# "exception-handler",
|
||||
"panic-handler",
|
||||
"println",
|
||||
] }
|
||||
esp-hal-embassy = { version = "0.9.0", git = "https://github.com/esp-rs/esp-hal", features = ["esp32s3", "log-04"] }
|
||||
esp-println = { version = "0.15.0", git = "https://github.com/esp-rs/esp-hal", features = ["esp32s3", "log-04"] }
|
||||
static_cell = "2.1.1"
|
||||
|
||||
|
||||
[profile.dev]
|
||||
# Rust debug is too slow.
|
||||
# For debug builds always builds with some optimization
|
||||
opt-level = "s"
|
||||
|
||||
[profile.release]
|
||||
codegen-units = 1 # LLVM can perform better optimizations using a single thread
|
||||
debug = 2
|
||||
debug-assertions = false
|
||||
incremental = false
|
||||
lto = 'fat'
|
||||
opt-level = 's'
|
||||
overflow-checks = false
|
||||
20
firmware/README.md
Normal file
20
firmware/README.md
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
# Building and running
|
||||
|
||||
```
|
||||
cargo build --release && espflash flash --port COM5 .\target\xtensa-esp32s3-none-elf\release\acid-firmware --monitor
|
||||
```
|
||||
|
||||
A different port may need to be chosen.
|
||||
|
||||
# Monitoring
|
||||
|
||||
```
|
||||
espflash monitor -p COM5
|
||||
```
|
||||
|
||||
A different port may need to be chosen.
|
||||
|
||||
# Debugging
|
||||
|
||||
Sometimes the firmware keeps crashing.
|
||||
Pulling GPIO0 high during reset seems to fix this?
|
||||
52
firmware/build.rs
Normal file
52
firmware/build.rs
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
fn main() {
|
||||
linker_be_nice();
|
||||
// make sure linkall.x is the last linker script (otherwise might cause problems with flip-link)
|
||||
println!("cargo:rustc-link-arg=-Tlinkall.x");
|
||||
}
|
||||
|
||||
fn linker_be_nice() {
|
||||
let args: Vec<String> = std::env::args().collect();
|
||||
if args.len() > 1 {
|
||||
let kind = &args[1];
|
||||
let what = &args[2];
|
||||
|
||||
match kind.as_str() {
|
||||
"undefined-symbol" => match what.as_str() {
|
||||
"_defmt_timestamp" => {
|
||||
eprintln!();
|
||||
eprintln!("💡 `defmt` not found - make sure `defmt.x` is added as a linker script and you have included `use defmt_rtt as _;`");
|
||||
eprintln!();
|
||||
}
|
||||
"_stack_start" => {
|
||||
eprintln!();
|
||||
eprintln!("💡 Is the linker script `linkall.x` missing?");
|
||||
eprintln!();
|
||||
}
|
||||
"esp_wifi_preempt_enable"
|
||||
| "esp_wifi_preempt_yield_task"
|
||||
| "esp_wifi_preempt_task_create" => {
|
||||
eprintln!();
|
||||
eprintln!("💡 `esp-wifi` has no scheduler enabled. Make sure you have the `builtin-scheduler` feature enabled, or that you provide an external scheduler.");
|
||||
eprintln!();
|
||||
}
|
||||
"embedded_test_linker_file_not_added_to_rustflags" => {
|
||||
eprintln!();
|
||||
eprintln!("💡 `embedded-test` not found - make sure `embedded-test.x` is added as a linker script for tests");
|
||||
eprintln!();
|
||||
}
|
||||
_ => (),
|
||||
},
|
||||
// we don't have anything helpful for "missing-lib" yet
|
||||
_ => {
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
std::process::exit(0);
|
||||
}
|
||||
|
||||
println!(
|
||||
"cargo:rustc-link-arg=-Wl,--error-handling-script={}",
|
||||
std::env::current_exe().unwrap().display()
|
||||
);
|
||||
}
|
||||
2
firmware/rust-toolchain.toml
Normal file
2
firmware/rust-toolchain.toml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
[toolchain]
|
||||
channel = "esp"
|
||||
996
firmware/src/bin/main.rs
Normal file
996
firmware/src/bin/main.rs
Normal file
|
|
@ -0,0 +1,996 @@
|
|||
#![no_std]
|
||||
#![no_main]
|
||||
#![deny(
|
||||
clippy::mem_forget,
|
||||
reason = "mem::forget is generally not safe to do with esp_hal types, especially those \
|
||||
holding buffers for the duration of a data transfer."
|
||||
)]
|
||||
#![feature(iter_intersperse)]
|
||||
#![feature(allocator_api)]
|
||||
|
||||
use core::alloc::{GlobalAlloc, Layout};
|
||||
use core::future::IntoFuture;
|
||||
use core::iter::once;
|
||||
|
||||
use alloc::vec::Vec;
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_time::{Duration, Timer};
|
||||
use esp_alloc::{HeapRegion, MemoryCapability};
|
||||
use esp_backtrace as _;
|
||||
use esp_hal::clock::CpuClock;
|
||||
use esp_hal::delay::Delay;
|
||||
use esp_hal::dma::{
|
||||
Channel, DmaChannel, DmaDescriptor, DmaDescriptorFlags, DmaLoopBuf, DmaRxTxBuf, DmaTxBuf,
|
||||
};
|
||||
use esp_hal::gpio::{self, Flex, Level, Output, OutputConfig, OutputPin, Pin};
|
||||
use esp_hal::lcd_cam::lcd::dpi::{self, Dpi, Format, FrameTiming};
|
||||
use esp_hal::lcd_cam::lcd::{self, ClockMode, DelayMode, Lcd, Phase, Polarity};
|
||||
use esp_hal::lcd_cam::{BitOrder, LcdCam};
|
||||
use esp_hal::mcpwm::operator::PwmPin;
|
||||
use esp_hal::mcpwm::{McPwm, PeripheralClockConfig};
|
||||
use esp_hal::peripherals::PSRAM;
|
||||
use esp_hal::rtc_cntl::sleep;
|
||||
use esp_hal::spi::master::{Address, Command, DataMode, Spi};
|
||||
use esp_hal::time::Rate;
|
||||
use esp_hal::timer::systimer::SystemTimer;
|
||||
use esp_hal::{dma_buffers, dma_loop_buffer, dma_tx_buffer, Async};
|
||||
use log::info;
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
// This creates a default app-descriptor required by the esp-idf bootloader.
|
||||
// For more information see: <https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/system/app_image_format.html#application-description>
|
||||
esp_bootloader_esp_idf::esp_app_desc!();
|
||||
|
||||
static PSRAM_ALLOCATOR: esp_alloc::EspHeap = esp_alloc::EspHeap::empty();
|
||||
|
||||
#[esp_hal_embassy::main]
|
||||
async fn main(spawner: Spawner) {
|
||||
// generator version: 0.5.0
|
||||
|
||||
esp_println::logger::init_logger_from_env();
|
||||
|
||||
let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max());
|
||||
let peripherals: esp_hal::peripherals::Peripherals = esp_hal::init(config);
|
||||
|
||||
// Initialize the PSRAM allocator.
|
||||
{
|
||||
let (psram_offset, psram_size) = esp_hal::psram::psram_raw_parts(&peripherals.PSRAM);
|
||||
unsafe {
|
||||
PSRAM_ALLOCATOR.add_region(HeapRegion::new(
|
||||
psram_offset,
|
||||
psram_size,
|
||||
MemoryCapability::External.into(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
let dma_buf_desc = DmaDescriptor {
|
||||
buffer: unsafe {
|
||||
PSRAM_ALLOCATOR.alloc(Layout::from_size_align(2 * 360 * 960, 32).unwrap())
|
||||
},
|
||||
next: core::ptr::null_mut(),
|
||||
flags: {
|
||||
let mut flags = DmaDescriptorFlags(0);
|
||||
flags.set_length(2 * 360 * 960);
|
||||
flags.set_owner(false);
|
||||
flags.set_size(2 * 360 * 960);
|
||||
flags.set_suc_eof(false);
|
||||
flags
|
||||
},
|
||||
};
|
||||
// let dma_buf = DmaTxBuf::new(&[dma_buf_desc], todo!()).unwrap();
|
||||
|
||||
// Use the internal DRAM as the heap.
|
||||
esp_alloc::heap_allocator!(#[link_section = ".dram2_uninit"] size: 64 * 1024);
|
||||
|
||||
let timer0 = SystemTimer::new(peripherals.SYSTIMER);
|
||||
esp_hal_embassy::init(timer0.alarm0);
|
||||
|
||||
info!("Embassy initialized!");
|
||||
|
||||
// TODO: Spawn some tasks
|
||||
let _ = spawner;
|
||||
|
||||
// Enable LDO2
|
||||
let _ = Output::new(peripherals.GPIO17, Level::High, OutputConfig::default());
|
||||
|
||||
// let mut o = Output::new(peripherals.GPIO35, Level::Low, OutputConfig::default());
|
||||
|
||||
// loop {
|
||||
// o.set_high();
|
||||
// Timer::after(Duration::from_secs(1)).await;
|
||||
// o.set_low();
|
||||
// Timer::after(Duration::from_secs(1)).await;
|
||||
// info!("yeet");
|
||||
// Timer::after(Duration::from_secs(1)).await;
|
||||
// }
|
||||
|
||||
// let mut x = Spi::new(
|
||||
// peripherals.SPI2,
|
||||
// esp_hal::spi::master::Config::default().with_frequency(Rate::from_mhz(1)), // For debugging
|
||||
// )
|
||||
// .unwrap()
|
||||
// .with_mosi(peripherals.GPIO35)
|
||||
// .with_sck(peripherals.GPIO36);
|
||||
|
||||
// let init = [
|
||||
// &b"\xff\x05w\x01\x00\x00\x13"[..],
|
||||
// b"\xef\x01\x08",
|
||||
// b"\xff\x05w\x01\x00\x00\x10",
|
||||
// b"\xc0\x02w\x00",
|
||||
// b"\xc1\x02\x11\x0c",
|
||||
// b"\xc2\x02\x07\x02",
|
||||
// b"\xcc\x010",
|
||||
// b"\xb0\x10\x06\xcf\x14\x0c\x0f\x03\x00\n\x07\x1b\x03\x12\x10%6\x1e",
|
||||
// b"\xb1\x10\x0c\xd4\x18\x0c\x0e\x06\x03\x06\x08#\x06\x12\x100/\x1f",
|
||||
// b"\xff\x05w\x01\x00\x00\x11",
|
||||
// b"\xb0\x01s",
|
||||
// b"\xb1\x01|",
|
||||
// b"\xb2\x01\x83",
|
||||
// b"\xb3\x01\x80",
|
||||
// b"\xb5\x01I",
|
||||
// b"\xb7\x01\x87",
|
||||
// b"\xb8\x013",
|
||||
// b"\xb9\x02\x10\x1f",
|
||||
// b"\xbb\x01\x03",
|
||||
// b"\xc1\x01\x08",
|
||||
// b"\xc2\x01\x08",
|
||||
// b"\xd0\x01\x88",
|
||||
// b"\xe0\x06\x00\x00\x02\x00\x00\x0c",
|
||||
// b"\xe1\x0b\x05\x96\x07\x96\x06\x96\x08\x96\x00DD",
|
||||
// b"\xe2\x0c\x00\x00\x03\x03\x00\x00\x02\x00\x00\x00\x02\x00",
|
||||
// b"\xe3\x04\x00\x0033",
|
||||
// b"\xe4\x02DD",
|
||||
// b"\xe5\x10\r\xd4(\x8c\x0f\xd6(\x8c\t\xd0(\x8c\x0b\xd2(\x8c",
|
||||
// b"\xe6\x04\x00\x0033",
|
||||
// b"\xe7\x02DD",
|
||||
// b"\xe8\x10\x0e\xd5(\x8c\x10\xd7(\x8c\n\xd1(\x8c\x0c\xd3(\x8c",
|
||||
// b"\xeb\x06\x00\x01\xe4\xe4D\x00",
|
||||
// b"\xed\x10\xf3\xc1\xba\x0ffwDUUDwf\xf0\xab\x1c?",
|
||||
// b"\xef\x06\x10\r\x04\x08?\x1f",
|
||||
// b"\xff\x05w\x01\x00\x00\x13",
|
||||
// b"\xe8\x02\x00\x0e",
|
||||
// b"\x11\x80x",
|
||||
// b"\xe8\x82\x00\x0c\n",
|
||||
// b"\xe8\x02@\x00",
|
||||
// b"\xff\x05w\x01\x00\x00\x00",
|
||||
// b"6\x01\x00",
|
||||
// b":\x01f",
|
||||
// b")\x80\x14",
|
||||
// b"\xff\x05w\x01\x00\x00\x10",
|
||||
// b"\xe5\x02\x00\x00",
|
||||
// ]
|
||||
// .into_iter()
|
||||
// .flatten()
|
||||
// .copied()
|
||||
// .collect::<Vec<u8>>();
|
||||
|
||||
// info!("init sequence writing");
|
||||
// x.write(&init).unwrap();
|
||||
// info!("init sequence written");
|
||||
|
||||
// TODO: Use PWM to control the pwm_pin.
|
||||
let mut _pwm = McPwm::new(peripherals.MCPWM0, PeripheralClockConfig::with_prescaler(1));
|
||||
let mut _pwm_pin = Output::new(peripherals.GPIO21, Level::High, OutputConfig::default());
|
||||
|
||||
let mut sck = Output::new(peripherals.GPIO36, Level::High, OutputConfig::default());
|
||||
let mut mosi = Flex::new(peripherals.GPIO35);
|
||||
let mut cs = Output::new(peripherals.GPIO6, Level::High, OutputConfig::default());
|
||||
|
||||
mosi.set_input_enable(false);
|
||||
mosi.set_output_enable(true);
|
||||
|
||||
info!("init sequence writing");
|
||||
|
||||
cs.set_low();
|
||||
for op in INIT_SEQUENCE {
|
||||
match *op {
|
||||
InitOp::WriteComm(data) => spi_write_word(false, data, &mut mosi, &mut sck),
|
||||
InitOp::WriteData(data) => spi_write_word(true, data, &mut mosi, &mut sck),
|
||||
InitOp::SleepMs(ms) => Timer::after_millis(ms).await,
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
cs.set_high();
|
||||
|
||||
info!("init sequence written");
|
||||
|
||||
// Timer::after_secs(1).await;
|
||||
|
||||
// x.half_duplex_write(
|
||||
// DataMode::Single,
|
||||
// Command::_9Bit(0xFFFF, DataMode::Single),
|
||||
// Address::None,
|
||||
// 0,
|
||||
// &[],
|
||||
// )
|
||||
// .unwrap();
|
||||
|
||||
// info!("Derp");
|
||||
|
||||
let mut lcd = LcdCam::new(peripherals.LCD_CAM).into_async().lcd;
|
||||
let lcd_config = lcd::dpi::Config::default()
|
||||
.with_frequency(Rate::from_mhz(16)) // From Adafruit
|
||||
.with_clock_mode(ClockMode {
|
||||
polarity: Polarity::IdleLow, // From Adafruit
|
||||
phase: Phase::ShiftHigh, // From Adafruit
|
||||
})
|
||||
.with_format(Format {
|
||||
enable_2byte_mode: true,
|
||||
..Default::default()
|
||||
})
|
||||
.with_timing({
|
||||
// Adafruit's config for this LCD:
|
||||
// https://github.com/adafruit/Adafruit_CircuitPython_Qualia/blob/742d336e05e6a4d8bdaa46e15bbf60c9f30d2eba/adafruit_qualia/displays/bar240x960.py#L81-L97
|
||||
// https://github.com/adafruit/Adafruit_CircuitPython_Qualia/blob/742d336e05e6a4d8bdaa46e15bbf60c9f30d2eba/adafruit_qualia/displays/__init__.py#L59-L62
|
||||
// CircuitPython code handling Adafruit's config
|
||||
// https://github.com/adafruit/circuitpython/blob/97c6617817e95b1f6aa2ce458778aaa8371de39b/ports/espressif/common-hal/dotclockframebuffer/DotClockFramebuffer.c#L63
|
||||
let horizontal_resolution: usize = 240;
|
||||
let vertical_resolution = 960;
|
||||
let overscan_left = 120;
|
||||
let vsync_width = 8;
|
||||
let hsync_width = 8;
|
||||
let horizontal_blank_front_porch = 20;
|
||||
let horizontal_blank_back_porch = 20;
|
||||
let vertical_blank_front_porch = 20;
|
||||
let vertical_blank_back_porch = 20;
|
||||
let hsync_position = 0;
|
||||
let horizontal_active_width = (horizontal_resolution + overscan_left).div_ceil(16) * 16; // Round up to a multiple of 16.
|
||||
let vertical_active_height = vertical_resolution;
|
||||
FrameTiming {
|
||||
horizontal_total_width: horizontal_active_width
|
||||
+ hsync_width
|
||||
+ horizontal_blank_back_porch
|
||||
+ horizontal_blank_back_porch,
|
||||
vertical_total_height: vertical_active_height
|
||||
+ vsync_width
|
||||
+ vertical_blank_back_porch
|
||||
+ vertical_blank_front_porch,
|
||||
horizontal_blank_front_porch,
|
||||
vertical_blank_front_porch,
|
||||
horizontal_active_width,
|
||||
vertical_active_height,
|
||||
vsync_width,
|
||||
hsync_width,
|
||||
hsync_position,
|
||||
}
|
||||
})
|
||||
.with_hsync_idle_level(Level::High)
|
||||
.with_vsync_idle_level(Level::High)
|
||||
.with_de_idle_level(Level::Low);
|
||||
|
||||
// let mut dma_buf = dma_loop_buffer!(2 * 32);
|
||||
let mut dma_buf = dma_tx_buffer!(2 * 960 * 320 / 4).unwrap();
|
||||
|
||||
// let tx_buf = dma_tx_buffer!(core::mem::size_of::<u16>() * 280 * 1000).unwrap();
|
||||
// let (c_rx, c_tx) = peripherals.DMA_CH0.split();
|
||||
// TODO: https://github.com/esp-rs/esp-hal/blob/main/qa-test/src/bin/lcd_dpi.rs
|
||||
let mut dpi = Dpi::new(lcd, peripherals.DMA_CH2, lcd_config)
|
||||
.unwrap()
|
||||
.with_de(peripherals.GPIO37)
|
||||
.with_pclk(peripherals.GPIO34)
|
||||
.with_hsync(peripherals.GPIO44)
|
||||
.with_vsync(peripherals.GPIO43)
|
||||
// Blue
|
||||
.with_data0(peripherals.GPIO38)
|
||||
.with_data1(peripherals.GPIO39)
|
||||
.with_data2(peripherals.GPIO40)
|
||||
.with_data3(peripherals.GPIO41)
|
||||
.with_data4(peripherals.GPIO42)
|
||||
// Green
|
||||
.with_data5(peripherals.GPIO5)
|
||||
.with_data6(peripherals.GPIO12)
|
||||
.with_data7(peripherals.GPIO13)
|
||||
.with_data8(peripherals.GPIO14)
|
||||
.with_data9(peripherals.GPIO15)
|
||||
.with_data10(peripherals.GPIO16)
|
||||
// Red
|
||||
.with_data11(peripherals.GPIO0)
|
||||
.with_data12(peripherals.GPIO1)
|
||||
.with_data13(peripherals.GPIO2)
|
||||
.with_data14(peripherals.GPIO3)
|
||||
.with_data15(peripherals.GPIO4);
|
||||
|
||||
const MAX_RED: u8 = (1 << 5) - 1;
|
||||
const MAX_GREEN: u8 = (1 << 6) - 1;
|
||||
const MAX_BLUE: u8 = (1 << 5) - 1;
|
||||
|
||||
fn rgb(r: u8, g: u8, b: u8) -> u16 {
|
||||
(((r & MAX_RED) as u16) << 11) | (((g & MAX_GREEN) as u16) << 5) | ((b & MAX_BLUE) as u16)
|
||||
}
|
||||
|
||||
let mut colors = core::iter::empty()
|
||||
// Start with red and gradually add green
|
||||
.chain((0..=MAX_GREEN).map(|g| rgb(MAX_RED, g, 0)))
|
||||
// Then remove the red
|
||||
.chain((0..=MAX_RED).rev().map(|r| rgb(r, MAX_GREEN, 0)))
|
||||
// Then add blue
|
||||
.chain((0..=MAX_BLUE).map(|b| rgb(0, MAX_GREEN, b)))
|
||||
// Then remove green
|
||||
.chain((0..=MAX_GREEN).rev().map(|g| rgb(0, g, MAX_BLUE)))
|
||||
// Then add red
|
||||
.chain((0..=MAX_RED).map(|r| rgb(r, 0, MAX_BLUE)))
|
||||
// Then remove blue
|
||||
.chain((0..=MAX_BLUE).rev().map(|b| rgb(MAX_RED, 0, b)))
|
||||
// Once we get we have red, and we can start again.
|
||||
.cycle();
|
||||
|
||||
// let write = |command: u8, args: &[u8]| {
|
||||
// // TODO: 3-wire SPI requires 9-bit words, where each 8-bit word is prefixed by 1 bit
|
||||
// // signifying whether the word is a parameter or not.
|
||||
// // Interleave into a buffer and terminate with NOP commands.
|
||||
// x.half_duplex_write(
|
||||
// DataMode::Single,
|
||||
// Command::_9Bit(command as u16, DataMode::Single),
|
||||
// Address::None,
|
||||
// 0,
|
||||
// &[],
|
||||
// )
|
||||
// .unwrap();
|
||||
// };
|
||||
|
||||
loop {
|
||||
// let mut buf = [0u8; 3];
|
||||
// x.half_duplex_read(
|
||||
// DataMode::Single,
|
||||
// Command::_9Bit(0x04, DataMode::Single),
|
||||
// Address::None,
|
||||
// 1,
|
||||
// &mut buf,
|
||||
// )
|
||||
// .unwrap();
|
||||
let mut buf = [0_u8, 0, 0];
|
||||
spi_read(
|
||||
0xDA,
|
||||
false,
|
||||
&mut mosi,
|
||||
&mut sck,
|
||||
&mut cs,
|
||||
&mut buf[0..][..1],
|
||||
);
|
||||
spi_read(
|
||||
0xDB,
|
||||
false,
|
||||
&mut mosi,
|
||||
&mut sck,
|
||||
&mut cs,
|
||||
&mut buf[1..][..1],
|
||||
);
|
||||
spi_read(
|
||||
0xDC,
|
||||
false,
|
||||
&mut mosi,
|
||||
&mut sck,
|
||||
&mut cs,
|
||||
&mut buf[2..][..1],
|
||||
);
|
||||
let mut buf2 = [0_u8, 0, 0];
|
||||
spi_read(0x04, true, &mut mosi, &mut sck, &mut cs, &mut buf2);
|
||||
// info!("Hello world! {buf:02x?} {buf2:02x?}");
|
||||
|
||||
for (chunk, color) in dma_buf.as_mut_slice().chunks_mut(2).zip(&mut colors) {
|
||||
chunk.copy_from_slice(&color.to_le_bytes());
|
||||
}
|
||||
|
||||
colors.next(); // Shift colors
|
||||
|
||||
let transfer = dpi.send(false, dma_buf).map_err(|e| e.0).unwrap();
|
||||
(_, dpi, dma_buf) = transfer.wait();
|
||||
|
||||
// x.half_duplex_write(
|
||||
// DataMode::Single,
|
||||
// Command::_9Bit(0xFFFF, DataMode::Single),
|
||||
// Address::None,
|
||||
// 0,
|
||||
// &[0x77],
|
||||
// )
|
||||
// .unwrap();
|
||||
// Timer::after(Duration::from_secs(1)).await;
|
||||
}
|
||||
|
||||
// for inspiration have a look at the examples at https://github.com/esp-rs/esp-hal/tree/esp-hal-v1.0.0-rc.0/examples/src/bin
|
||||
}
|
||||
|
||||
fn spi_delay() {
|
||||
Delay::new().delay_micros(1);
|
||||
}
|
||||
|
||||
fn spi_dummy_bit(sck: &mut Output) {
|
||||
sck.set_low();
|
||||
spi_delay();
|
||||
sck.set_high();
|
||||
spi_delay();
|
||||
}
|
||||
|
||||
fn spi_write_bit(bit: bool, mosi: &mut Flex, sck: &mut Output) {
|
||||
mosi.set_level(if bit { Level::High } else { Level::Low });
|
||||
sck.set_low();
|
||||
spi_delay();
|
||||
sck.set_high();
|
||||
spi_delay();
|
||||
}
|
||||
|
||||
fn spi_read_bit(mosi: &mut Flex, sck: &mut Output) -> bool {
|
||||
sck.set_low();
|
||||
spi_delay();
|
||||
sck.set_high();
|
||||
spi_delay();
|
||||
mosi.is_high()
|
||||
}
|
||||
|
||||
fn spi_write_bits(bits: impl Iterator<Item = bool>, mosi: &mut Flex, sck: &mut Output) {
|
||||
for bit in bits {
|
||||
spi_write_bit(bit, mosi, sck);
|
||||
}
|
||||
}
|
||||
|
||||
fn spi_write_word(is_param: bool, data: u8, mosi: &mut Flex, sck: &mut Output) {
|
||||
assert!(sck.is_set_high());
|
||||
spi_write_bits(
|
||||
once(is_param).chain((0..8).map(|i| (data >> i) & 1 != 0).rev()),
|
||||
mosi,
|
||||
sck,
|
||||
);
|
||||
}
|
||||
|
||||
fn spi_write(command: u8, args: &[u8], mosi: &mut Flex, sck: &mut Output, cs: &mut Output) {
|
||||
cs.set_low();
|
||||
spi_write_word(false, command, mosi, sck);
|
||||
|
||||
for &arg in args {
|
||||
spi_write_word(true, arg, mosi, sck);
|
||||
}
|
||||
|
||||
cs.set_high();
|
||||
}
|
||||
|
||||
fn spi_read(
|
||||
command: u8,
|
||||
dummy_cycle: bool,
|
||||
mosi: &mut Flex,
|
||||
sck: &mut Output,
|
||||
cs: &mut Output,
|
||||
output_buffer: &mut [u8],
|
||||
) {
|
||||
output_buffer.fill(0);
|
||||
|
||||
cs.set_low();
|
||||
spi_write_word(false, command, mosi, sck);
|
||||
|
||||
mosi.set_output_enable(false);
|
||||
mosi.set_input_enable(true);
|
||||
|
||||
if dummy_cycle {
|
||||
spi_dummy_bit(sck);
|
||||
}
|
||||
|
||||
for output_byte in output_buffer {
|
||||
for i in (0..8).rev() {
|
||||
if spi_read_bit(mosi, sck) {
|
||||
*output_byte |= 1 << i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mosi.set_input_enable(false);
|
||||
mosi.set_output_enable(true);
|
||||
|
||||
cs.set_high();
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
enum InitOp {
|
||||
Command(u8, &'static [u8]),
|
||||
WriteComm(u8),
|
||||
WriteData(u8),
|
||||
SleepMs(u64),
|
||||
}
|
||||
|
||||
// impl InitOp {
|
||||
// async fn execute<'a>(&'a self, mosi: &'a mut Output<'a>, sck: &'a mut Output<'a>) {
|
||||
// match *self {
|
||||
// InitOp::WriteComm(data) => spi_write(false, data, mosi, sck),
|
||||
// InitOp::WriteData(data) => spi_write(true, data, mosi, sck),
|
||||
// InitOp::SleepMs(ms) => Timer::after_millis(ms).await,
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
use InitOp::*;
|
||||
|
||||
const INIT_SEQUENCE: &[InitOp] = &[
|
||||
WriteComm(0xff),
|
||||
WriteData(0x77),
|
||||
WriteData(0x01),
|
||||
WriteData(0x00),
|
||||
WriteData(0x00),
|
||||
WriteData(0x13),
|
||||
WriteComm(0xef),
|
||||
WriteData(0x08),
|
||||
WriteComm(0xff),
|
||||
WriteData(0x77),
|
||||
WriteData(0x01),
|
||||
WriteData(0x00),
|
||||
WriteData(0x00),
|
||||
WriteData(0x10),
|
||||
WriteComm(0xc0),
|
||||
WriteData(0x77),
|
||||
WriteData(0x00),
|
||||
WriteComm(0xc1),
|
||||
WriteData(0x11),
|
||||
WriteData(0x0c),
|
||||
WriteComm(0xc2),
|
||||
WriteData(0x07),
|
||||
WriteData(0x02),
|
||||
WriteComm(0xcc),
|
||||
WriteData(0x30),
|
||||
WriteComm(0xB0),
|
||||
WriteData(0x06),
|
||||
WriteData(0xCF),
|
||||
WriteData(0x14),
|
||||
WriteData(0x0C),
|
||||
WriteData(0x0F),
|
||||
WriteData(0x03),
|
||||
WriteData(0x00),
|
||||
WriteData(0x0A),
|
||||
WriteData(0x07),
|
||||
WriteData(0x1B),
|
||||
WriteData(0x03),
|
||||
WriteData(0x12),
|
||||
WriteData(0x10),
|
||||
WriteData(0x25),
|
||||
WriteData(0x36),
|
||||
WriteData(0x1E),
|
||||
WriteComm(0xB1),
|
||||
WriteData(0x0C),
|
||||
WriteData(0xD4),
|
||||
WriteData(0x18),
|
||||
WriteData(0x0C),
|
||||
WriteData(0x0E),
|
||||
WriteData(0x06),
|
||||
WriteData(0x03),
|
||||
WriteData(0x06),
|
||||
WriteData(0x08),
|
||||
WriteData(0x23),
|
||||
WriteData(0x06),
|
||||
WriteData(0x12),
|
||||
WriteData(0x10),
|
||||
WriteData(0x30),
|
||||
WriteData(0x2F),
|
||||
WriteData(0x1F),
|
||||
WriteComm(0xff),
|
||||
WriteData(0x77),
|
||||
WriteData(0x01),
|
||||
WriteData(0x00),
|
||||
WriteData(0x00),
|
||||
WriteData(0x11),
|
||||
WriteComm(0xb0),
|
||||
WriteData(0x73),
|
||||
WriteComm(0xb1),
|
||||
WriteData(0x7C),
|
||||
WriteComm(0xb2),
|
||||
WriteData(0x83),
|
||||
WriteComm(0xb3),
|
||||
WriteData(0x80),
|
||||
WriteComm(0xb5),
|
||||
WriteData(0x49),
|
||||
WriteComm(0xb7),
|
||||
WriteData(0x87),
|
||||
WriteComm(0xb8),
|
||||
WriteData(0x33),
|
||||
WriteComm(0xb9),
|
||||
WriteData(0x10),
|
||||
WriteData(0x1f),
|
||||
WriteComm(0xbb),
|
||||
WriteData(0x03),
|
||||
WriteComm(0xc1),
|
||||
WriteData(0x08),
|
||||
WriteComm(0xc2),
|
||||
WriteData(0x08),
|
||||
WriteComm(0xd0),
|
||||
WriteData(0x88),
|
||||
WriteComm(0xe0),
|
||||
WriteData(0x00),
|
||||
WriteData(0x00),
|
||||
WriteData(0x02),
|
||||
WriteData(0x00),
|
||||
WriteData(0x00),
|
||||
WriteData(0x0c),
|
||||
WriteComm(0xe1),
|
||||
WriteData(0x05),
|
||||
WriteData(0x96),
|
||||
WriteData(0x07),
|
||||
WriteData(0x96),
|
||||
WriteData(0x06),
|
||||
WriteData(0x96),
|
||||
WriteData(0x08),
|
||||
WriteData(0x96),
|
||||
WriteData(0x00),
|
||||
WriteData(0x44),
|
||||
WriteData(0x44),
|
||||
WriteComm(0xe2),
|
||||
WriteData(0x00),
|
||||
WriteData(0x00),
|
||||
WriteData(0x03),
|
||||
WriteData(0x03),
|
||||
WriteData(0x00),
|
||||
WriteData(0x00),
|
||||
WriteData(0x02),
|
||||
WriteData(0x00),
|
||||
WriteData(0x00),
|
||||
WriteData(0x00),
|
||||
WriteData(0x02),
|
||||
WriteData(0x00),
|
||||
WriteComm(0xe3),
|
||||
WriteData(0x00),
|
||||
WriteData(0x00),
|
||||
WriteData(0x33),
|
||||
WriteData(0x33),
|
||||
WriteComm(0xe4),
|
||||
WriteData(0x44),
|
||||
WriteData(0x44),
|
||||
WriteComm(0xe5),
|
||||
WriteData(0x0d),
|
||||
WriteData(0xd4),
|
||||
WriteData(0x28),
|
||||
WriteData(0x8c),
|
||||
WriteData(0x0f),
|
||||
WriteData(0xd6),
|
||||
WriteData(0x28),
|
||||
WriteData(0x8c),
|
||||
WriteData(0x09),
|
||||
WriteData(0xd0),
|
||||
WriteData(0x28),
|
||||
WriteData(0x8c),
|
||||
WriteData(0x0b),
|
||||
WriteData(0xd2),
|
||||
WriteData(0x28),
|
||||
WriteData(0x8c),
|
||||
WriteComm(0xe6),
|
||||
WriteData(0x00),
|
||||
WriteData(0x00),
|
||||
WriteData(0x33),
|
||||
WriteData(0x33),
|
||||
WriteComm(0xe7),
|
||||
WriteData(0x44),
|
||||
WriteData(0x44),
|
||||
WriteComm(0xe8),
|
||||
WriteData(0x0e),
|
||||
WriteData(0xd5),
|
||||
WriteData(0x28),
|
||||
WriteData(0x8c),
|
||||
WriteData(0x10),
|
||||
WriteData(0xd7),
|
||||
WriteData(0x28),
|
||||
WriteData(0x8c),
|
||||
WriteData(0x0a),
|
||||
WriteData(0xd1),
|
||||
WriteData(0x28),
|
||||
WriteData(0x8c),
|
||||
WriteData(0x0c),
|
||||
WriteData(0xd3),
|
||||
WriteData(0x28),
|
||||
WriteData(0x8c),
|
||||
WriteComm(0xeb),
|
||||
WriteData(0x00),
|
||||
WriteData(0x01),
|
||||
WriteData(0xe4),
|
||||
WriteData(0xe4),
|
||||
WriteData(0x44),
|
||||
WriteData(0x00),
|
||||
WriteComm(0xed),
|
||||
WriteData(0xf3),
|
||||
WriteData(0xc1),
|
||||
WriteData(0xba),
|
||||
WriteData(0x0f),
|
||||
WriteData(0x66),
|
||||
WriteData(0x77),
|
||||
WriteData(0x44),
|
||||
WriteData(0x55),
|
||||
WriteData(0x55),
|
||||
WriteData(0x44),
|
||||
WriteData(0x77),
|
||||
WriteData(0x66),
|
||||
WriteData(0xf0),
|
||||
WriteData(0xab),
|
||||
WriteData(0x1c),
|
||||
WriteData(0x3f),
|
||||
WriteComm(0xef),
|
||||
WriteData(0x10),
|
||||
WriteData(0x0d),
|
||||
WriteData(0x04),
|
||||
WriteData(0x08),
|
||||
WriteData(0x3f),
|
||||
WriteData(0x1f),
|
||||
WriteComm(0xff),
|
||||
WriteData(0x77),
|
||||
WriteData(0x01),
|
||||
WriteData(0x00),
|
||||
WriteData(0x00),
|
||||
WriteData(0x13),
|
||||
WriteComm(0xe8),
|
||||
WriteData(0x00),
|
||||
WriteData(0x0e),
|
||||
WriteComm(0x11),
|
||||
SleepMs(120),
|
||||
WriteComm(0xe8),
|
||||
WriteData(0x00),
|
||||
WriteData(0x0c),
|
||||
SleepMs(10),
|
||||
WriteComm(0xe8),
|
||||
WriteData(0x40),
|
||||
WriteData(0x00),
|
||||
WriteComm(0xff),
|
||||
WriteData(0x77),
|
||||
WriteData(0x01),
|
||||
WriteData(0x00),
|
||||
WriteData(0x00),
|
||||
WriteData(0x00),
|
||||
WriteComm(0x36),
|
||||
WriteData(0x00),
|
||||
WriteComm(0x3A),
|
||||
WriteData(0x66),
|
||||
WriteComm(0x29),
|
||||
SleepMs(20),
|
||||
/*
|
||||
WriteComm (0xff);
|
||||
WriteData (0x77);
|
||||
WriteData (0x01);
|
||||
WriteData (0x00);
|
||||
WriteData (0x00);
|
||||
WriteData (0x10);
|
||||
WriteComm (0xe5);
|
||||
WriteData (0x00);
|
||||
WriteData (0x00);
|
||||
*/
|
||||
];
|
||||
|
||||
/*
|
||||
TODO: Use this init sequence
|
||||
|
||||
WriteComm (0xff);
|
||||
WriteData (0x77);
|
||||
WriteData (0x01);
|
||||
WriteData (0x00);
|
||||
WriteData (0x00);
|
||||
WriteData (0x13);
|
||||
WriteComm (0xef);
|
||||
WriteData (0x08);
|
||||
WriteComm (0xff);
|
||||
WriteData (0x77);
|
||||
WriteData (0x01);
|
||||
WriteData (0x00);
|
||||
WriteData (0x00);
|
||||
WriteData (0x10);
|
||||
WriteComm (0xc0);
|
||||
WriteData (0x77);
|
||||
WriteData (0x00);
|
||||
WriteComm (0xc1);
|
||||
WriteData (0x11);
|
||||
WriteData (0x0c);
|
||||
WriteComm (0xc2);
|
||||
WriteData (0x07);
|
||||
WriteData (0x02);
|
||||
WriteComm (0xcc);
|
||||
WriteData (0x30);
|
||||
WriteComm (0xB0);
|
||||
WriteData (0x06);
|
||||
WriteData (0xCF);
|
||||
WriteData (0x14);
|
||||
WriteData (0x0C);
|
||||
WriteData (0x0F);
|
||||
WriteData (0x03);
|
||||
WriteData (0x00);
|
||||
WriteData (0x0A);
|
||||
WriteData (0x07);
|
||||
WriteData (0x1B);
|
||||
WriteData (0x03);
|
||||
WriteData (0x12);
|
||||
WriteData (0x10);
|
||||
WriteData (0x25);
|
||||
WriteData (0x36);
|
||||
WriteData (0x1E);
|
||||
WriteComm (0xB1);
|
||||
WriteData (0x0C);
|
||||
WriteData (0xD4);
|
||||
WriteData (0x18);
|
||||
WriteData (0x0C);
|
||||
WriteData (0x0E);
|
||||
WriteData (0x06);
|
||||
WriteData (0x03);
|
||||
WriteData (0x06);
|
||||
WriteData (0x08);
|
||||
WriteData (0x23);
|
||||
WriteData (0x06);
|
||||
WriteData (0x12);
|
||||
WriteData (0x10);
|
||||
WriteData (0x30);
|
||||
WriteData (0x2F);
|
||||
WriteData (0x1F);
|
||||
WriteComm (0xff);
|
||||
WriteData (0x77);
|
||||
WriteData (0x01);
|
||||
WriteData (0x00);
|
||||
WriteData (0x00);
|
||||
WriteData (0x11);
|
||||
WriteComm (0xb0);
|
||||
WriteData (0x73);
|
||||
WriteComm (0xb1);
|
||||
WriteData (0x7C);
|
||||
WriteComm (0xb2);
|
||||
WriteData (0x83);
|
||||
WriteComm (0xb3);
|
||||
WriteData (0x80);
|
||||
WriteComm (0xb5);
|
||||
WriteData (0x49);
|
||||
WriteComm (0xb7);
|
||||
WriteData (0x87);
|
||||
WriteComm (0xb8);
|
||||
WriteData (0x33);
|
||||
WriteComm (0xb9);
|
||||
WriteData (0x10);
|
||||
WriteData (0x1f);
|
||||
WriteComm (0xbb);
|
||||
WriteData (0x03);
|
||||
WriteComm (0xc1);
|
||||
WriteData (0x08);
|
||||
WriteComm (0xc2);
|
||||
WriteData (0x08);
|
||||
WriteComm (0xd0);
|
||||
WriteData (0x88);
|
||||
WriteComm (0xe0);
|
||||
WriteData (0x00);
|
||||
WriteData (0x00);
|
||||
WriteData (0x02);
|
||||
WriteData (0x00);
|
||||
WriteData (0x00);
|
||||
WriteData (0x0c);
|
||||
WriteComm (0xe1);
|
||||
WriteData (0x05);
|
||||
WriteData (0x96);
|
||||
WriteData (0x07);
|
||||
WriteData (0x96);
|
||||
WriteData (0x06);
|
||||
WriteData (0x96);
|
||||
WriteData (0x08);
|
||||
WriteData (0x96);
|
||||
WriteData (0x00);
|
||||
WriteData (0x44);
|
||||
WriteData (0x44);
|
||||
WriteComm (0xe2);
|
||||
WriteData (0x00);
|
||||
WriteData (0x00);
|
||||
WriteData (0x03);
|
||||
WriteData (0x03);
|
||||
WriteData (0x00);
|
||||
WriteData (0x00);
|
||||
WriteData (0x02);
|
||||
WriteData (0x00);
|
||||
WriteData (0x00);
|
||||
WriteData (0x00);
|
||||
WriteData (0x02);
|
||||
WriteData (0x00);
|
||||
WriteComm (0xe3);
|
||||
WriteData (0x00);
|
||||
WriteData (0x00);
|
||||
WriteData (0x33);
|
||||
WriteData (0x33);
|
||||
WriteComm (0xe4);
|
||||
WriteData (0x44);
|
||||
WriteData (0x44);
|
||||
WriteComm (0xe5);
|
||||
WriteData (0x0d);
|
||||
WriteData (0xd4);
|
||||
WriteData (0x28);
|
||||
WriteData (0x8c);
|
||||
WriteData (0x0f);
|
||||
WriteData (0xd6);
|
||||
WriteData (0x28);
|
||||
WriteData (0x8c);
|
||||
WriteData (0x09);
|
||||
WriteData (0xd0);
|
||||
WriteData (0x28);
|
||||
WriteData (0x8c);
|
||||
WriteData (0x0b);
|
||||
WriteData (0xd2);
|
||||
WriteData (0x28);
|
||||
WriteData (0x8c);
|
||||
WriteComm (0xe6);
|
||||
WriteData (0x00);
|
||||
WriteData (0x00);
|
||||
WriteData (0x33);
|
||||
WriteData (0x33);
|
||||
WriteComm (0xe7);
|
||||
WriteData (0x44);
|
||||
WriteData (0x44);
|
||||
WriteComm (0xe8);
|
||||
WriteData (0x0e);
|
||||
WriteData (0xd5);
|
||||
WriteData (0x28);
|
||||
WriteData (0x8c);
|
||||
WriteData (0x10);
|
||||
WriteData (0xd7);
|
||||
WriteData (0x28);
|
||||
WriteData (0x8c);
|
||||
WriteData (0x0a);
|
||||
WriteData (0xd1);
|
||||
WriteData (0x28);
|
||||
WriteData (0x8c);
|
||||
WriteData (0x0c);
|
||||
WriteData (0xd3);
|
||||
WriteData (0x28);
|
||||
WriteData (0x8c);
|
||||
WriteComm (0xeb);
|
||||
WriteData (0x00);
|
||||
WriteData (0x01);
|
||||
WriteData (0xe4);
|
||||
WriteData (0xe4);
|
||||
WriteData (0x44);
|
||||
WriteData (0x00);
|
||||
WriteComm (0xed);
|
||||
WriteData (0xf3);
|
||||
WriteData (0xc1);
|
||||
WriteData (0xba);
|
||||
WriteData (0x0f);
|
||||
WriteData (0x66);
|
||||
WriteData (0x77);
|
||||
WriteData (0x44);
|
||||
WriteData (0x55);
|
||||
WriteData (0x55);
|
||||
WriteData (0x44);
|
||||
WriteData (0x77);
|
||||
WriteData (0x66);
|
||||
WriteData (0xf0);
|
||||
WriteData (0xab);
|
||||
WriteData (0x1c);
|
||||
WriteData (0x3f);
|
||||
WriteComm (0xef);
|
||||
WriteData (0x10);
|
||||
WriteData (0x0d);
|
||||
WriteData (0x04);
|
||||
WriteData (0x08);
|
||||
WriteData (0x3f);
|
||||
WriteData (0x1f);
|
||||
WriteComm (0xff);
|
||||
WriteData (0x77);
|
||||
WriteData (0x01);
|
||||
WriteData (0x00);
|
||||
WriteData (0x00);
|
||||
WriteData (0x13);
|
||||
WriteComm (0xe8);
|
||||
WriteData (0x00);
|
||||
WriteData (0x0e);
|
||||
WriteComm (0x11);
|
||||
Delay_ms(120);
|
||||
WriteComm (0xe8);
|
||||
WriteData (0x00);
|
||||
WriteData (0x0c);
|
||||
Delay_ms(10);
|
||||
WriteComm (0xe8);
|
||||
WriteData (0x40);
|
||||
WriteData (0x00);
|
||||
WriteComm (0xff);
|
||||
WriteData (0x77);
|
||||
WriteData (0x01);
|
||||
WriteData (0x00);
|
||||
WriteData (0x00);
|
||||
WriteData (0x00);
|
||||
WriteComm (0x36);
|
||||
WriteData (0x00);
|
||||
WriteComm (0x3A);
|
||||
WriteData (0x66);
|
||||
WriteComm (0x29);
|
||||
Delay_ms(20);
|
||||
/*
|
||||
WriteComm (0xff);
|
||||
WriteData (0x77);
|
||||
WriteData (0x01);
|
||||
WriteData (0x00);
|
||||
WriteData (0x00);
|
||||
WriteData (0x10);
|
||||
WriteComm (0xe5);
|
||||
WriteData (0x00);
|
||||
WriteData (0x00);
|
||||
*/
|
||||
*/
|
||||
4
firmware/src/lib.rs
Normal file
4
firmware/src/lib.rs
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
#![no_std]
|
||||
#![deny(clippy::mem_forget)]
|
||||
|
||||
pub mod st7701s;
|
||||
9
firmware/src/st7701s.rs
Normal file
9
firmware/src/st7701s.rs
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
use esp_hal::gpio::OutputPin;
|
||||
|
||||
pub struct St7701s {}
|
||||
|
||||
impl St7701s {
|
||||
pub fn new() -> Self {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue