From a60dcf5fd9b4235f09c963af1b4ad620bbd04536 Mon Sep 17 00:00:00 2001 From: benstrb Date: Sun, 12 Apr 2026 20:20:41 +0200 Subject: [PATCH] ngl this do be ai, I remove a few things it works --- Cargo.lock | 11 ++++ Cargo.toml | 1 + memory.x | 18 ++++-- src/main.rs | 157 +++++++++++++++++++++++++++++++++++++--------------- 4 files changed, 136 insertions(+), 51 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ac813e0..13251c5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -259,6 +259,16 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c6673768db2d862beb9b39a78fdcb1a69439615d5794a1be50caa9bc92c81967" +[[package]] +name = "otm8009a" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e56059a2e83de4409e5fa0854d3ae891b0f949af86c74ccf76a8bffe4ce6dc6d" +dependencies = [ + "embedded-display-controller", + "embedded-hal 0.2.7", +] + [[package]] name = "panic-halt" version = "1.0.0" @@ -391,6 +401,7 @@ dependencies = [ "defmt", "defmt-rtt", "embedded-hal 1.0.0", + "otm8009a", "panic-halt", "panic-probe", "stm32f4xx-hal", diff --git a/Cargo.toml b/Cargo.toml index b844ebc..cd87a92 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ defmt-rtt = "1.1.0" defmt = "1.0.1" panic-probe = {version = "1.0.0", features = ["print-defmt"]} panic-halt = "1.0.0" +otm8009a = "0.1.0" [dependencies.stm32f4xx-hal] version = "0.23.0" diff --git a/memory.x b/memory.x index 40e7dd0..6833557 100644 --- a/memory.x +++ b/memory.x @@ -1,12 +1,18 @@ /* Memory layout of the STM32F469NI */ MEMORY { - FLASH : ORIGIN = 0x08000000, LENGTH = 2048K - RAM : ORIGIN = 0x20000000, LENGTH = 256K - /* Core Coupled Memory (CCM) SRAM: 128KB at 0x10000000 */ - CCMRAM : ORIGIN = 0x10000000, LENGTH = 128K + FLASH : ORIGIN = 0x08000000, LENGTH = 2M + RAM : ORIGIN = 0x20000000, LENGTH = 384K + CCMRAM : ORIGIN = 0x10000000, LENGTH = 64K + SDRAM : ORIGIN = 0xC0000000, LENGTH = 16M +} + +SECTIONS +{ + .sdram (NOLOAD) : + { + *(.sdram .sdram.*); + } > SDRAM } -/* This is where the call stack will be allocated. */ -/* The stack is of the full size of the RAM, minus the size of the .data section */ _stack_start = ORIGIN(RAM) + LENGTH(RAM); diff --git a/src/main.rs b/src/main.rs index d519383..34fe61b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,65 +1,132 @@ -#![no_std] #![no_main] +#![no_std] +use crate::hal::{ + dsi::{ + ColorCoding, DsiChannel, DsiCmdModeTransmissionKind, DsiConfig, DsiHost, DsiInterrupts, + DsiMode, DsiPhyTimers, DsiPllConfig, DsiVideoMode, LaneCount, + }, + ltdc::{DisplayConfig, DisplayController, PixelFormat}, + pac::{CorePeripherals, Peripherals}, + prelude::*, +}; use cortex_m_rt::entry; use defmt_rtt as _; -use hal::prelude::*; +use otm8009a::{Otm8009A, Otm8009AConfig}; use panic_probe as _; -use stm32f4xx_hal::{self as hal, ltdc::DisplayController}; +use stm32f4xx_hal::{self as hal, ltdc, rcc::Config}; defmt::timestamp!("{=u32}", 0u32); +const WIDTH: usize = 480; +const HEIGHT: usize = 800; + +const DISPLAY_CONFIGURATION: DisplayConfig = DisplayConfig { + active_width: WIDTH as _, + active_height: HEIGHT as _, + h_back_porch: 34, + h_front_porch: 34, + v_back_porch: 15, + v_front_porch: 16, + h_sync: 2, + v_sync: 1, + frame_rate: 60, + h_sync_pol: true, + v_sync_pol: true, + no_data_enable_pol: false, + pixel_clock_pol: true, +}; + #[entry] fn main() -> ! { - let peripherals = hal::pac::Peripherals::take().unwrap(); - let mut rcc = peripherals.RCC.constrain(); - let ltdc = peripherals.LTDC; - let dma2d = peripherals.DMA2D; + let peripherals = Peripherals::take().unwrap(); + let core_peripherals = CorePeripherals::take().unwrap(); - let display_config = hal::ltdc::DisplayConfig { - active_width: 480, - active_height: 800, - h_back_porch: 8, - h_front_porch: 8, - v_back_porch: 1, - v_front_porch: 1, - h_sync: 15, - v_sync: 60, - frame_rate: 5, - h_sync_pol: false, - v_sync_pol: false, - no_data_enable_pol: false, - pixel_clock_pol: false, - }; + let hse_freq = 8.MHz(); + let mut rcc = peripherals + .RCC + .freeze(Config::hse(hse_freq).pclk2(32.MHz()).sysclk(180.MHz())); + let mut delay = core_peripherals.SYST.delay(&rcc.clocks); - let mut display: DisplayController = hal::ltdc::DisplayController::new( - ltdc, - dma2d, - None, - hal::ltdc::PixelFormat::AL88, - display_config, + let gpioh = peripherals.GPIOH.split(&mut rcc); + let mut lcd_reset = gpioh.ph7.into_push_pull_output(); + lcd_reset.set_low(); + delay.delay_ms(20u32); + lcd_reset.set_high(); + delay.delay_ms(10u32); + + #[unsafe(link_section = ".sdram")] + static mut BUFF: [u32; 480 * 800] = [0; 480 * 800]; + + let mut display = DisplayController::::new( + peripherals.LTDC, + peripherals.DMA2D, None, + PixelFormat::ARGB8888, + DISPLAY_CONFIGURATION, + Some(hse_freq), ); - display.draw_pixel(hal::ltdc::Layer::L1, 50, 50, 1); + display.enable_layer(ltdc::Layer::L1); + display.config_layer( + ltdc::Layer::L1, + unsafe { &mut BUFF[..] }, + PixelFormat::ARGB8888, + ); - let gpiog = peripherals.GPIOG.split(&mut rcc); - let gpiod = peripherals.GPIOD.split(&mut rcc); + let dsi_pll_config = unsafe { DsiPllConfig::manual(125, 2, 0, 4) }; + let dsi_config = DsiConfig { + mode: DsiMode::Video { + mode: DsiVideoMode::Burst, + }, + lane_count: LaneCount::DoubleLane, + channel: DsiChannel::Ch0, + hse_freq, + ltdc_freq: 27_429.kHz(), + interrupts: DsiInterrupts::None, + color_coding_host: ColorCoding::TwentyFourBits, + color_coding_wrapper: ColorCoding::TwentyFourBits, + lp_size: 4, + vlp_size: 4, + }; - let mut led1 = gpiog.pg6.into_push_pull_output(); - let mut led2 = gpiod.pd4.into_push_pull_output(); + let mut dsi_host = DsiHost::init( + dsi_pll_config, + DISPLAY_CONFIGURATION, + dsi_config, + peripherals.DSI, + &mut rcc, + ) + .unwrap(); - led1.set_low(); - led2.set_low(); + dsi_host.configure_phy_timers(DsiPhyTimers { + dataline_hs2lp: 35, + dataline_lp2hs: 35, + clock_hs2lp: 35, + clock_lp2hs: 35, + dataline_max_read_time: 0, + stop_wait_time: 10, + }); - loop { - for _ in 0..100000 { - led1.set_low(); - led2.set_high(); - } + dsi_host.set_command_mode_transmission_kind(DsiCmdModeTransmissionKind::AllInLowPower); + dsi_host.start(); + dsi_host.enable_bus_turn_around(); + dsi_host.set_command_mode_transmission_kind(DsiCmdModeTransmissionKind::AllInHighSpeed); + dsi_host.force_rx_low_power(true); + dsi_host.enable_color_test(); - for _ in 0..100000 { - led1.set_high(); - led2.set_low(); - } - } + let mut otm = Otm8009A::new(); + otm.init( + &mut dsi_host, + Otm8009AConfig { + frame_rate: otm8009a::FrameRate::_60Hz, + mode: otm8009a::Mode::Portrait, + color_map: otm8009a::ColorMap::Rgb, + cols: WIDTH as u16, + rows: HEIGHT as u16, + }, + &mut delay, + ) + .unwrap(); + + loop {} }