From 86312236622732f23de1367977dd603e4aa7ed99 Mon Sep 17 00:00:00 2001 From: zhangpeng Date: Thu, 21 Mar 2024 17:04:02 +0800 Subject: [PATCH 1/2] Add dac --- CHANGELOG.md | 1 + Cargo.toml | 6 ++- src/dac.rs | 105 ++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 2 + src/rcc/enable.rs | 5 ++- 5 files changed, 116 insertions(+), 3 deletions(-) create mode 100644 src/dac.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 27668998..edf2c3fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Add changelog check on PRs - Replace UB code by a legitimate pointer access - Reexport `Direction` from `qei` +- Add dac ## [v0.10.0] - 2022-12-12 diff --git a/Cargo.toml b/Cargo.toml index 8415a1a6..b66f6b95 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -61,13 +61,15 @@ stm32f107 = ["stm32f1/stm32f107", "device-selected", "connectivity"] # Devices with 64 or 128 Kb ROM medium = [] # Devices with 256 or 512 Kb ROM -high = ["medium"] +high = ["medium", "has-dac"] # Devices with 768 Kb ROM or more xl = ["high"] # Connectivity line devices (`stm32f105xx` and `stm32f107xx`) -connectivity = ["medium", "has-can"] +connectivity = ["medium", "has-can", "has-dac"] # Devices with CAN interface has-can = [] +# Devices with Dac +has-dac = [] rtic = ["rtic-monotonic"] diff --git a/src/dac.rs b/src/dac.rs new file mode 100644 index 00000000..44ba9413 --- /dev/null +++ b/src/dac.rs @@ -0,0 +1,105 @@ +//! # API for the Digital to Analog converter +//! +//! Currently only supports writing to the DR of the DAC, +//! just a basic one-shot conversion. +#![deny(unused_imports)] + +use crate::{ + gpio::{Analog, PA4, PA5}, + pac::{DAC, RCC}, + rcc::{Enable, Reset}, +}; + +pub struct C1; +pub struct C2; + +pub trait DacOut { + fn set_value(&mut self, val: V); + fn get_value(&mut self) -> V; +} + +pub trait DacPin { + fn enable(&mut self); +} + +pub trait Pins { + type Output; + #[doc(hidden)] + fn init() -> Self::Output; +} + +impl Pins for PA4 { + type Output = C1; + fn init() -> Self::Output { + C1 + } +} + +impl Pins for PA5 { + type Output = C2; + fn init() -> Self::Output { + C2 + } +} + +impl Pins for (PA4, PA5) { + type Output = (C1, C2); + fn init() -> Self::Output { + (C1, C2) + } +} + +pub fn dac(_dac: DAC, _pins: PINS) -> PINS::Output +where + PINS: Pins, +{ + unsafe { + // Enable and reset clock. + let rcc = unsafe { &(*RCC::ptr()) }; + DAC::enable(rcc); + DAC::reset(rcc); + + PINS::init() + } +} + +macro_rules! dac { + ($CX:ident, $en:ident, $cen:ident, $cal_flag:ident, $trim:ident, $mode:ident, $dhrx:ident, $dac_dor:ident, $daccxdhr:ident) => { + impl DacPin for $CX { + fn enable(&mut self) { + let dac = unsafe { &(*DAC::ptr()) }; + dac.cr.modify(|_, w| w.$en().set_bit()); + } + } + + impl DacOut for $CX { + fn set_value(&mut self, val: u16) { + let dac = unsafe { &(*DAC::ptr()) }; + dac.$dhrx.write(|w| unsafe { w.bits(val as u32) }); + } + + fn get_value(&mut self) -> u16 { + let dac = unsafe { &(*DAC::ptr()) }; + dac.$dac_dor.read().bits() as u16 + } + } + }; +} + +pub trait DacExt { + fn constrain(self, pins: PINS) -> PINS::Output + where + PINS: Pins; +} + +impl DacExt for DAC { + fn constrain(self, pins: PINS) -> PINS::Output + where + PINS: Pins, + { + dac(self, pins) + } +} + +dac!(C1, en1, cen1, cal_flag1, otrim1, mode1, dhr12r1, dor1, dacc1dhr); +dac!(C2, en2, cen2, cal_flag2, otrim2, mode2, dhr12r2, dor2, dacc2dhr); diff --git a/src/lib.rs b/src/lib.rs index a6906de5..2997c027 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -150,6 +150,8 @@ pub mod bb; pub mod can; #[cfg(feature = "device-selected")] pub mod crc; +#[cfg(all(feature = "device-selected", feature = "has-dac"))] +pub mod dac; #[cfg(feature = "device-selected")] pub mod dma; #[cfg(feature = "device-selected")] diff --git a/src/rcc/enable.rs b/src/rcc/enable.rs index a0374e97..a2e6ef31 100644 --- a/src/rcc/enable.rs +++ b/src/rcc/enable.rs @@ -73,10 +73,13 @@ bus! { CAN1 => (APB1, 25), CAN2 => (APB1, 26), } +#[cfg(feature = "has-dac")] +bus! { + DAC => (APB1, 29), +} #[cfg(all(feature = "stm32f103", feature = "high"))] bus! { ADC3 => (APB2, 15), - DAC => (APB1, 29), UART4 => (APB1, 19), UART5 => (APB1, 20), } From d8675fcdf97e9dd55342aa2a56c5992bbdeafe37 Mon Sep 17 00:00:00 2001 From: zhangpeng Date: Fri, 22 Mar 2024 09:14:49 +0800 Subject: [PATCH 2/2] Fix "unnecessary unsafe" warning --- src/dac.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/dac.rs b/src/dac.rs index 44ba9413..ea40063f 100644 --- a/src/dac.rs +++ b/src/dac.rs @@ -53,14 +53,12 @@ pub fn dac(_dac: DAC, _pins: PINS) -> PINS::Output where PINS: Pins, { - unsafe { - // Enable and reset clock. - let rcc = unsafe { &(*RCC::ptr()) }; - DAC::enable(rcc); - DAC::reset(rcc); + // Enable and reset clock. + let rcc = unsafe { &(*RCC::ptr()) }; + DAC::enable(rcc); + DAC::reset(rcc); - PINS::init() - } + PINS::init() } macro_rules! dac {