From 816520ed77e593d6c3b645f90a8087bc49b1ceaf Mon Sep 17 00:00:00 2001 From: J / Jacob Babich Date: Wed, 13 Apr 2022 01:49:16 -0400 Subject: [PATCH] progress --- .gitignore | 8 - .vscode/settings.json | 5 + Cargo.toml | 3 + new-main.bin | Bin 53268 -> 0 bytes src/lib.rs | 56 ------- src/lib/memory.rs | 83 ++++++++++ src/lib/mod.rs | 343 ++++++++++++++++++++++++++++++++++++++++++ src/lib/registers.rs | 106 +++++++++++++ src/main.rs | 72 ++++++--- 9 files changed, 588 insertions(+), 88 deletions(-) create mode 100644 .vscode/settings.json delete mode 100755 new-main.bin delete mode 100644 src/lib.rs create mode 100644 src/lib/memory.rs create mode 100644 src/lib/mod.rs create mode 100644 src/lib/registers.rs diff --git a/.gitignore b/.gitignore index b25267d..549dfbb 100644 --- a/.gitignore +++ b/.gitignore @@ -4,12 +4,4 @@ Cargo.lock target/ -# editor files -.vscode/* -!.vscode/*.md -!.vscode/*.svd -!.vscode/launch.json -!.vscode/tasks.json -!.vscode/extensions.json - .history/ diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..86cf0e1 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +// https://github.com/rust-lang/vscode-rust/issues/729#issuecomment-635977755 +{ + "rust-analyzer.cargo.target": "thumbv7em-none-eabihf", + "rust-analyzer.checkOnSave.allTargets": false +} \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index dd5728e..05cc8bf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,6 +24,9 @@ panic-halt = "0.2.0" # features = ["stm32f303", "rt"] # version = "0.7.1" +[lib] +path = "src/lib/mod.rs" + # this lets you use `cargo fix`! [[bin]] name = "test-cortex-m4-rust" diff --git a/new-main.bin b/new-main.bin deleted file mode 100755 index f154b7468a9a118d551211b157ea67eb5b528626..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53268 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 diff --git a/src/lib.rs b/src/lib.rs deleted file mode 100644 index ef9c0b2..0000000 --- a/src/lib.rs +++ /dev/null @@ -1,56 +0,0 @@ -#![no_std] - -pub struct Board; - -impl Board { - pub fn setup_gpio_port(port: Port, options: PortSetup) -> PortIO { - PortIO - } -} - -pub enum Port { - A, - F, -} - -pub struct PortSetup; - -pub struct PortIO; - -impl PortIO { - pub fn setup_pin(pin: Pin, options: PinSetup) -> PinIO { - PinIO - } -} - -pub enum Pin { - Zero = 0, - One = 1, - Two = 2, - Three = 3, - Four = 4, - Five = 5, - Six = 6, - Seven = 7, -} - -pub struct PinSetup; - -pub struct PinIO; - -impl PinIO { - pub fn clear(&mut self) { - todo!(); - } - pub fn set(&mut self) { - todo!(); - } - pub fn toggle(&mut self) { - todo!(); - } -} - - -pub fn setup_board() -> Board { - Board -} diff --git a/src/lib/memory.rs b/src/lib/memory.rs new file mode 100644 index 0000000..8ca199f --- /dev/null +++ b/src/lib/memory.rs @@ -0,0 +1,83 @@ +//! Interact with memory + +use core::ptr; + +use crate::{Bit, L}; + +pub unsafe fn read(address: *mut u32) -> u32 { + ptr::read_volatile(address) +} +pub unsafe fn write(address: *mut u32, new: u32) { + ptr::write_volatile(address, new); +} + +pub unsafe fn update u32>(address: *mut u32, updater: Updater) { + write(address, updater(read(address))); +} + +pub unsafe fn read_bits(address: *mut u32, bits: &[u32; N]) -> [bool; N] { + let current = read(address); + let mut result = [L; N]; + + // TODO: look up accumulate or reduce or something + for (i, bit) in bits.iter().enumerate() { + result[i] = (current & (1 << bit)) != 0; + } + + result +} +pub unsafe fn write_bits(address: *mut u32, bits: &[u32; N], values: [bool; N]) { + update(address, |current| { + let mut new = current; + // TODO: look up accumulate or reduce or something + for (bit, set) in bits.iter().zip(values) { + if set { + new |= (1 << bit); + } else { + new &= !(1 << bit); + } + } + new + }) +} + +pub unsafe fn update_bits [bool; N]>(address: *mut u32, bits: &[Bit; N], updater: Updater) { + write_bits(address, bits, updater(read_bits(address, bits))) +} + +pub unsafe fn set_bits(address: *mut u32, bits: &[Bit]) { + update(address, |current| { + let mut new = current; + + // TODO: look up accumulate or reduce or something + for bit in bits { + new |= (1 << bit); + } + + new + }) +} +pub unsafe fn clear_bits(address: *mut u32, bits: &[Bit]) { + update(address, |current| { + let mut new = current; + + // TODO: look up accumulate or reduce or something + for bit in bits { + new &= !(1 << bit); + } + + new + }) +} +pub unsafe fn toggle_bits(address: *mut u32, bits: &[Bit]) { + update(address, |current| { + let mut new = current; + + // TODO: look up accumulate or reduce or something + for bit in bits { + new ^= (1 << bit); + } + + new + }) +} diff --git a/src/lib/mod.rs b/src/lib/mod.rs new file mode 100644 index 0000000..10751a1 --- /dev/null +++ b/src/lib/mod.rs @@ -0,0 +1,343 @@ +#![no_std] + +mod memory; +mod registers; + +pub const H: bool = true; +pub const L: bool = false; + +pub struct Board; +// TODO: check page 704 for timers +// TODO: impl Drop trait so that tasks all run before the main function ends? + +impl Board { + pub fn setup_gpio_port(&self, port: Port, options: PortSetup) -> PortIO { + let port_io = PortIO { port }; + + unsafe { + memory::set_bits(registers::system::RCGCGPIO, &[port_io.run_mode_clock_gate_control()]); + } + + port_io + } +} + +// Page 684 of the data sheet for how the lock mechanism works +const UNLOCK: u32 = 0x4C4F434B; + +pub enum Port { + A, + B, + C, + D, + E, + F, +} + +pub struct PortSetup; + +pub struct PortIO { + port: Port, +} + +impl PortIO { + /// The memory address of the analog mode select (AMSEL) register for this port + fn analog_mode_select(&self) -> *mut u32 { + match self.port { + Port::A => registers::gpio::amsel::PORT_A, + Port::F => registers::gpio::amsel::PORT_F, + _ => todo!(), + } + } + + /// The memory address of the commit (CR register for this port + fn commit(&self) -> *mut u32 { + match self.port { + Port::A => registers::gpio::cr::PORT_A, + Port::F => registers::gpio::cr::PORT_F, + _ => todo!(), + } + } + + /// The memory address of the data (DATA) register for this port + fn data(&self) -> *mut u32 { + match self.port { + Port::A => registers::gpio::data::PORT_A, + Port::F => registers::gpio::data::PORT_F, + _ => todo!(), + } + } + + /// The memory address of the direction (DIR) register for this port + fn direction(&self) -> *mut u32 { + match self.port { + Port::A => registers::gpio::dir::PORT_A, + Port::F => registers::gpio::dir::PORT_F, + _ => todo!(), + } + } + + /// The memory address of the lock (LOCK) register + fn lock(&self) -> *mut u32 { + match self.port { + Port::A => registers::gpio::lock::PORT_A, + Port::F => registers::gpio::lock::PORT_F, + _ => todo!(), + } + } + + /// The memory address of the port control (PCTL) register for this port + fn port_control(&self) -> *mut u32 { + match self.port { + Port::A => registers::gpio::pctl::PORT_A, + Port::F => registers::gpio::pctl::PORT_F, + _ => todo!(), + + } + } + + /// The memory address of the pull-down resistor select (PDR) register for this port + fn pull_down_select(&self) -> *mut u32 { + match self.port { + Port::A => registers::gpio::pdr::PORT_A, + Port::F => registers::gpio::pdr::PORT_F, + _ => todo!(), + } + } + + /// The memory address of the pull-up resistor select (PUR) register for this port + fn pull_up_select(&self) -> *mut u32 { + match self.port { + Port::A => registers::gpio::pur::PORT_A, + Port::F => registers::gpio::pur::PORT_F, + _ => todo!(), + } + } + + // Note to self: page 1351 of data sheet for PWM + // Apparently also for ADC! +} + + +impl PortIO { + /// The corresponding bit for this port in system's run-mode clock gate control (RCGC) register + fn run_mode_clock_gate_control(&self) -> Bit { + match self.port { + Port::A => Bit::Zero, + Port::B => Bit::One, + Port::C => Bit::Two, + Port::D => Bit::Three, + Port::E => Bit::Four, + Port::F => Bit::Five, + } + } +} + +impl PortIO { + pub fn setup_readable_pins( + &self, + bits: &[Bit; N], + options: ReadablePinSetup, + ) -> ReadablePins { + // Unlock the pins + unsafe { + memory::write(self.lock(), UNLOCK); + + memory::set_bits(self.commit(), bits); + } + + // Disable analog when it's not selected (and enable analog if it is) + match options.function { + Function::Analog => unsafe { + memory::set_bits(self.analog_mode_select(), bits); + }, + _ => unsafe { + memory::clear_bits(self.analog_mode_select(), bits); + }, + } + + unsafe { + memory::clear_bits(self.direction(), bits); + } + + // TODO: finish + + let data_address = self.data(); + + let pins: [ReadablePin; N] = bits.map(|bit| ReadablePin { data_address, bit }); + + ReadablePins { data_address, pins } + } + + pub fn setup_writable_pins( + &self, + bits: &[Bit; N], + options: WritablePinSetup, + ) -> WritablePins { + // Unlock the pins + unsafe { + memory::write(self.lock(), UNLOCK); + + memory::set_bits(self.commit(), bits); + } + + // Disable analog when it's not selected (and enable analog if it is) + match options.function { + Function::Analog => unsafe { + memory::set_bits(self.analog_mode_select(), bits); + }, + _ => unsafe { + memory::clear_bits(self.analog_mode_select(), bits); + }, + } + + unsafe { + memory::set_bits(self.direction(), bits); + } + + unsafe { + for bit in bits { + let memory_bits = [0; N]; + let values = match options.function { + Function::Analog => todo!(), + Function::Digital => todo!(), + Function::CAN => todo!(), + Function::I2C => todo!(), + Function::PWM => todo!(), + Function::UART => todo!(), + }; + memory::write_bits(self.port_control(), memory_bits, values); + } + } + + // TODO: check page 671 or 682 (+ more prob) for a table showing initial pin states + + // TODO: finish + + let data_address = self.data(); + + let pins: [WritablePin; N] = bits.map(|bit| WritablePin { data_address, bit }); + + WritablePins { data_address, pins } + } +} + +#[derive(Clone, Copy)] +pub enum Bit { + Zero = 0, + One = 1, + Two = 2, + Three = 3, + Four = 4, + Five = 5, + Six = 6, + Seven = 7, +} + +/// Page 1351 of data sheet +pub enum Function { + Analog, + Digital, + CAN, + I2C, + PWM, + UART, +} + +pub struct ReadablePinSetup { + pub function: Function, +} +pub struct ReadablePins { + data_address: *mut u32, + pins: [ReadablePin; N], +} +impl ReadablePins { + pub fn pins(&self) -> [ReadablePin; N] { + self.pins + } + + pub fn read_all(&self) -> [bool; N] { + unsafe { memory::read_bits(self.data_address, &self.pins.map(|pin| pin.bit)) } + } +} +#[derive(Clone, Copy)] +pub struct ReadablePin { + data_address: *mut u32, + bit: Bit, +} +impl ReadablePin { + pub fn read(&self) -> bool { + let current = unsafe { memory::read(self.data_address) }; + current & (1 << self.bit as u32) != 0 + } +} + +pub struct WritablePinSetup { + pub function: Function, +} +pub struct WritablePins { + data_address: *mut u32, + pins: [WritablePin; N], +} +impl WritablePins { + pub fn pins(&self) -> [WritablePin; N] { + self.pins + } + + pub fn read_all(&self) -> [bool; N] { + unsafe { memory::read_bits(self.data_address, &self.pins.map(|pin| pin.bit)) } + } + pub fn write_all(&mut self, values: [bool; N]) { + unsafe { memory::write_bits(self.data_address, &self.pins.map(|pin| pin.bit), values) } + } + pub fn update_all [bool; N]>(&mut self, updater: Updater) { + self.write_all(updater(self.read_all())); + } + + pub fn clear_all(&mut self) { + unsafe { + memory::clear_bits(self.data_address, &self.pins.map(|pin| pin.bit)); + } + } + pub fn set_all(&mut self) { + unsafe { + memory::set_bits(self.data_address, &self.pins.map(|pin| pin.bit)); + } + } + pub fn toggle_all(&mut self) { + unsafe { + memory::toggle_bits(self.data_address, &self.pins.map(|pin| pin.bit)); + } + } +} + +#[derive(Clone, Copy)] +pub struct WritablePin { + data_address: *mut u32, + bit: Bit, +} +impl WritablePin { + pub fn read(&self) -> bool { + let current = unsafe { memory::read(self.data_address) }; + current & (1 << self.bit as u32) != 0 + } + pub fn clear(&mut self) { + unsafe { + memory::clear_bits(self.data_address, &[self.bit]); + } + } + pub fn set(&mut self) { + unsafe { + memory::set_bits(self.data_address, &[self.bit]); + } + } + pub fn toggle(&mut self) { + unsafe { + memory::toggle_bits(self.data_address, &[self.bit]); + } + } +} + +pub fn setup_board() -> Board { + Board +} diff --git a/src/lib/registers.rs b/src/lib/registers.rs new file mode 100644 index 0000000..b7834ba --- /dev/null +++ b/src/lib/registers.rs @@ -0,0 +1,106 @@ +//! Memory addresses of registers +//! Data sheet: https://www.ti.com/lit/ds/spms376e/spms376e.pdf + +// TODO: check page 92-94 for more features ("Memory Map" table)! + +// TODO: check page 1230 onward for PWM + +/// Modeled after page 660 of data sheet (GPIO Register Map) +pub mod gpio { + mod base { + pub const PORT_A: u32 = 0x4000_4000; + pub const PORT_F: u32 = 0x4002_5000; + } + + /// Page 671 of data sheet + pub mod afsel { + const OFFSET: u32 = 0x420; + + pub const PORT_A: *mut u32 = (super::base::PORT_A + OFFSET) as *mut u32; + pub const PORT_F: *mut u32 = (super::base::PORT_F + OFFSET) as *mut u32; + } + + /// Page 687 of data sheet + pub mod amsel { + const OFFSET: u32 = 0x52C; + + pub const PORT_A: *mut u32 = (super::base::PORT_A + OFFSET) as *mut u32; + pub const PORT_F: *mut u32 = (super::base::PORT_F + OFFSET) as *mut u32; + } + + /// Page 685 of data sheet + pub mod cr { + const OFFSET: u32 = 0x524; + + pub const PORT_A: *mut u32 = (super::base::PORT_A + OFFSET) as *mut u32; + pub const PORT_F: *mut u32 = (super::base::PORT_F + OFFSET) as *mut u32; + } + + /// Page 662 of data sheet + pub mod data { + const OFFSET: u32 = 0x000; + + pub const PORT_A: *mut u32 = (super::base::PORT_A + OFFSET) as *mut u32; + pub const PORT_F: *mut u32 = (super::base::PORT_F + OFFSET) as *mut u32; + } + + /// Page 682 of data sheet + pub mod den { + const OFFSET: u32 = 0x51C; + + pub const PORT_A: *mut u32 = (super::base::PORT_A + OFFSET) as *mut u32; + pub const PORT_F: *mut u32 = (super::base::PORT_F + OFFSET) as *mut u32; + } + + /// Page 663 of data sheet + pub mod dir { + const OFFSET: u32 = 0x400; + + pub const PORT_A: *mut u32 = (super::base::PORT_A + OFFSET) as *mut u32; + pub const PORT_F: *mut u32 = (super::base::PORT_F + OFFSET) as *mut u32; + } + + /// Page 684 of data sheet + pub mod lock { + const OFFSET: u32 = 0x520; + + pub const PORT_A: *mut u32 = (super::base::PORT_A + OFFSET) as *mut u32; + pub const PORT_F: *mut u32 = (super::base::PORT_F + OFFSET) as *mut u32; + } + + /// Page 688 of data sheet + pub mod pctl { + const OFFSET: u32 = 0x52C; + + pub const PORT_A: *mut u32 = (super::base::PORT_A + OFFSET) as *mut u32; + pub const PORT_F: *mut u32 = (super::base::PORT_F + OFFSET) as *mut u32; + } + + /// Page 679 of data sheet + pub mod pdr { + const OFFSET: u32 = 0x514; + + pub const PORT_A: *mut u32 = (super::base::PORT_A + OFFSET) as *mut u32; + pub const PORT_F: *mut u32 = (super::base::PORT_F + OFFSET) as *mut u32; + } + + /// Page 677 of data sheet + pub mod pur { + const OFFSET: u32 = 0x510; + + pub const PORT_A: *mut u32 = (super::base::PORT_A + OFFSET) as *mut u32; + pub const PORT_F: *mut u32 = (super::base::PORT_F + OFFSET) as *mut u32; + } + + // TODO: examine page 670 for when (if) I do interrupts +} + +// TODO: examine page 690 (ADC) for applicability + +/// Page 231 of data sheet +pub mod system { + const BASE: u32 = 0x400F_E000; + + // TODO: page 340 + pub const RCGCGPIO: *mut u32 = (BASE + 0x608) as *mut u32; +} diff --git a/src/main.rs b/src/main.rs index e19fe3a..dc1a174 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,6 +6,8 @@ use core::ptr; use panic_halt as _; // you can put a breakpoint on `rust_begin_unwind` to catch panics use cortex_m_rt::entry; +use test_cortex_m4_rust::{Function, Bit, ReadablePinSetup, WritablePinSetup, PortSetup, Port, setup_board, H, L}; +// use test_cortex_m4_rust::setup_board; // Begin .h file contents @@ -15,9 +17,9 @@ const GPIO_PORTF_DIR_R: *mut u32 = 0x40025400 as *mut u32; const GPIO_PORTF_AFSEL_R: *mut u32 = 0x40025420 as *mut u32; const GPIO_PORTF_PUR_R: *mut u32 = 0x40025510 as *mut u32; const GPIO_PORTF_DEN_R: *mut u32 = 0x4002551C as *mut u32; -const GPIO_PORTF_LOCK_R: *mut u32 = 0x40025520 as *mut u32; -const GPIO_PORTF_CR_R: *mut u32 = 0x40025524 as *mut u32; -const GPIO_PORTF_AMSEL_R: *mut u32 = 0x40025528 as *mut u32; +const GPIOLOCK_PORT_F: *mut u32 = 0x40025520 as *mut u32; +const GPIOCR_PORT_F: *mut u32 = 0x40025524 as *mut u32; +const GPIOAMSEL_PORT_F: *mut u32 = 0x40025528 as *mut u32; const GPIO_PORTF_PCTL_R: *mut u32 = 0x4002552C as *mut u32; const SYSCTL_RCGCPIO_R: *mut u32 = 0x400FE608 as *mut u32; @@ -41,26 +43,26 @@ const BLUE: u8 = 0b0000_0100; fn setup_port_f() { // 1) activate clock for Port F - unsafe { - ptr::write_volatile( - SYSCTL_RCGCPIO_R, - ptr::read_volatile(SYSCTL_RCGCPIO_R) | 0x00_00_00_20, - ); - } + // unsafe { + // ptr::write_volatile( + // SYSCTL_RCGCPIO_R, + // ptr::read_volatile(SYSCTL_RCGCPIO_R) | 0x00_00_00_20, + // ); + // } // Delay - for _ in 0u8..2u8 {} + // for _ in 0u8..2u8 {} // 2) unlock GPIO Port F - unsafe { - ptr::write_volatile(GPIO_PORTF_LOCK_R, 0x4C4F434B); - // allow changes to PF4-0 - // only PF0 needs to be unlocked, other bits can't be locked - ptr::write_volatile(GPIO_PORTF_CR_R, 0b0001_1111); - } + // unsafe { + // ptr::write_volatile(GPIOLOCK_PORT_F, 0x4C4F434B); + // // allow changes to PF4-0 + // // only PF0 needs to be unlocked, other bits can't be locked + // ptr::write_volatile(GPIOCR_PORT_F, 0b0001_1111); + // } // 3) disable analog on PF - unsafe { ptr::write_volatile(GPIO_PORTF_AMSEL_R, 0x00) } + // unsafe { ptr::write_volatile(GPIOAMSEL_PORT_F, 0x00) } // 4) PCTL GPIO on PF4-0 unsafe { @@ -68,9 +70,9 @@ fn setup_port_f() { } // 5) PF4,PF0 in, PF3-1 out - unsafe { - ptr::write_volatile(GPIO_PORTF_DIR_R, 0x0E); - } + // unsafe { + // ptr::write_volatile(GPIO_PORTF_DIR_R, 0x0E); + // } // 6) disable alt funct on PF7-0 unsafe { ptr::write_volatile(GPIO_PORTF_AFSEL_R, 0x00); @@ -97,6 +99,26 @@ fn output_to_port_f(value: u8) { } } +// #[entry] +// fn main() -> ! { +// let board = setup_board(); +// let port_f = board.setup_gpio_port(Port::F, PortSetup); + +// let switches = port_f.setup_readable_pins([Bit::Zero, Bit::Four], ReadablePinSetup); +// let [sw1, sw2] = switches.pins(); + +// let mut rgb_led = port_f.setup_writable_pins(&[Bit::One, Bit::Three, Bit::Two], WritablePinSetup { drive: PinDrive::Digital }); + +// loop { +// match switches.read_all() { +// [L, L] => rgb_led.write_all([L, H, L]), +// [L, H] => rgb_led.write_all([L, L, H]), +// [H, L] => rgb_led.write_all([L, H, L]), +// [H, H] => rgb_led.write_all([L, L, L]), +// } +// } +// } + #[entry] fn main() -> ! { setup_port_f(); @@ -105,12 +127,14 @@ fn main() -> ! { let status = input_from_port_f(); match status { - 0x01 => output_to_port_f(BLUE), - 0x10 => output_to_port_f(RED), - 0x00 => output_to_port_f(GREEN), + 0x00 => output_to_port_f(RED | GREEN), + 0x01 => output_to_port_f(RED), + 0x10 => output_to_port_f(GREEN), 0x11 => output_to_port_f(BLACK), // Impossible case - _ => output_to_port_f(RED | BLUE), + _ => output_to_port_f(BLUE), } } } + +// TODO: implement an extremely simple example of the task system (using a timer trigger) that is a traffic light (green -> yellow -> red -> green...)