diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2022-12-13 16:45:49 -0700 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2022-12-13 16:45:49 -0700 |
commit | 540e0316aa425a8fbd126d31350dbe51fca92791 (patch) | |
tree | abc938b9b9f21b7d2357a18272d84c263d767142 /src/hal/gpio.rs | |
parent | 8bb2d168044213ce9bd31a19efb6bab90f5c9722 (diff) | |
download | stm32l4-rust-master.tar.gz stm32l4-rust-master.tar.bz2 stm32l4-rust-master.zip |
This rapidly blinks the sysled on the stm32.
This shows the ability to manipulate memory mapped registers.
Diffstat (limited to 'src/hal/gpio.rs')
-rw-r--r-- | src/hal/gpio.rs | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/src/hal/gpio.rs b/src/hal/gpio.rs new file mode 100644 index 0000000..d25a7db --- /dev/null +++ b/src/hal/gpio.rs @@ -0,0 +1,148 @@ +/** Base addresses for the Gpio ports. */ +static GPIOA_BASE: u32 = 0x48000000; +static GPIOB_BASE: u32 = 0x48000400; +static GPIOC_BASE: u32 = 0x48000800; +static GPIOH_BASE: u32 = 0x48001C00; + +use crate::hal::common::{regget, regset}; +use crate::hal::rcc::{get_rcc, GpioPortN}; + +#[derive(Clone, Copy)] +pub enum GpioMode { + Input = 0, + Output = 1, + Alternate = 2, + Analog = 3, +} + +#[derive(Clone, Copy)] +pub enum GpioOutputType { + PushPull = 0, + OpenDrain = 1, +} + +pub enum GpioSpeed { + Low = 0, + Medium = 1, + High = 2, + VeryHigh = 3, +} + +pub enum GpioPullDir { + None = 0, + Up = 1, + Down = 2, +} + +/* Struct representation of a GPIO Port. */ +#[repr(C)] +struct GpioPortMem { + /* Mode of each GPIO pin for this GPIO port. */ + mode_r: u32, + + /* Output type for each gpio pin in this port. */ + otype_r: u32, + + /* GPIO port output speed. */ + ospeed_r: u32, + + /* GPIO port pull-up/pull-down register */ + pupd_r: u32, + + /* GPIO port input data register. */ + id_r: u32, + + /* GPIO port output data register. */ + od_r: u32, + + /* GPIO port bit set/reset register. */ + bsr_r: u32, + + /* GPIO port configuration lock register. */ + lck_r: u32, + + /* Alternate function low-register. */ + af_rl: u32, + + /* Alternate function high-register. */ + af_rh: u32, + + /* GPIO port bit register. */ + br_r: u32, + + /* Analog switch control register. */ + asc_r: u32, +} + +#[derive(Clone, Copy)] +pub struct GpioPort { + mem: *mut GpioPortMem, +} + +pub struct GpioPin { + port: GpioPort, + pin_number: u8, +} + +impl GpioPort { + pub fn pin(self: &mut GpioPort, n: u8) -> GpioPin { + return GpioPin { + port: *self, + pin_number: n, + }; + } +} + +impl GpioPin { + pub unsafe fn set_mode(self: &mut GpioPin, mode: GpioMode) -> () { + let mode_ptr: *mut u32 = &mut (*self.port.mem).mode_r; + regset(mode_ptr, 3 << self.pin_number * 2, mode as u32); + } + + pub unsafe fn set_pull_dir(self: &mut GpioPin, pull_dir: GpioPullDir) { + let pull_dir_ptr: *mut u32 = &mut (*self.port.mem).pupd_r; + regset(pull_dir_ptr, 3 << self.pin_number * 2, pull_dir_ptr as u32); + } + + pub unsafe fn set_output_type(self: &mut GpioPin, otype: GpioOutputType) -> () { + let otype_ptr: *mut u32 = &mut (*self.port.mem).otype_r; + regset(otype_ptr, 1 << self.pin_number, otype as u32); + } + + pub unsafe fn set_output_speed(self: &mut GpioPin, ospeed: GpioSpeed) -> () { + let ospeed_ptr: *mut u32 = &mut (*self.port.mem).ospeed_r; + regset(ospeed_ptr, 3 << self.pin_number * 2, ospeed as u32); + } + + pub unsafe fn get(self: &mut GpioPin) -> bool { + let id_r: *mut u32 = &mut (*self.port.mem).id_r; + regget(id_r, 1 << self.pin_number) != 0 + } + + pub unsafe fn set_high(self: &mut GpioPin) { + self.set(true); + } + + pub unsafe fn set_low(self: &mut GpioPin) { + self.set(false); + } + + pub unsafe fn set(self: &mut GpioPin, on: bool) -> () { + let od_r: *mut u32 = &mut (*self.port.mem).od_r; + regset(od_r, 1 << self.pin_number, on as u32); + } +} + +pub fn get_gpio_port_a() -> GpioPort { + get_rcc().enable_gpio_port(GpioPortN::A); + return GpioPort { + mem: GPIOA_BASE as *mut GpioPortMem, + }; +} + +pub fn get_gpio_port_b() -> GpioPort { + get_rcc().enable_gpio_port(GpioPortN::B); + return GpioPort { + mem: GPIOB_BASE as *mut GpioPortMem, + }; +} |