Skip to content

Commit 11c5b5a

Browse files
authored
Merge branch 'main' into feature/usb
2 parents 2e8b35b + 906b83a commit 11c5b5a

File tree

14 files changed

+1708
-380
lines changed

14 files changed

+1708
-380
lines changed
File renamed without changes.

Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ static_assertions = "1.1"
2121
fugit = "0.3.5"
2222
stm32-usbd = { version = "0.7.0", optional = true }
2323
critical-section = "1.1.2"
24+
fixed = { version = "1.28.0", optional = true }
2425

2526
[dependencies.cortex-m]
2627
version = "0.7.7"
@@ -94,6 +95,7 @@ log-itm = ["cortex-m-log/itm"]
9495
log-rtt = []
9596
log-semihost = ["cortex-m-log/semihosting"]
9697
defmt-logging = ["defmt"]
98+
cordic = ["dep:fixed"]
9799

98100
[profile.dev]
99101
codegen-units = 1
@@ -114,3 +116,7 @@ required-features = ["stm32g474"]
114116
[[example]]
115117
name = "usb_serial"
116118
required-features = ["usb"]
119+
120+
[[example]]
121+
name = "cordic"
122+
required-features = ["cordic"]

examples/comp.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,6 @@ extern crate cortex_m_rt as rt;
1313

1414
use rt::entry;
1515

16-
#[cfg(not(feature = "stm32g474"))]
17-
#[entry]
18-
fn main() -> ! {
19-
#[allow(clippy::empty_loop)]
20-
loop {} // TODO: add support for more devices
21-
}
22-
23-
#[cfg(feature = "stm32g474")]
2416
#[entry]
2517
fn main() -> ! {
2618
use hal::comparator::{ComparatorExt, ComparatorSplit, Config, Hysteresis, RefintInput};

examples/comp_w_dac.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,6 @@ extern crate cortex_m_rt as rt;
88

99
use rt::entry;
1010

11-
#[cfg(not(feature = "stm32g474"))]
12-
#[entry]
13-
fn main() -> ! {
14-
#[allow(clippy::empty_loop)]
15-
loop {} // TODO: add support for more devices
16-
}
17-
18-
#[cfg(feature = "stm32g474")]
1911
#[entry]
2012
fn main() -> ! {
2113
use embedded_hal::Direction;

examples/cordic.rs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#![deny(warnings)]
2+
#![deny(unsafe_code)]
3+
#![no_main]
4+
#![no_std]
5+
6+
extern crate cortex_m;
7+
extern crate cortex_m_rt as rt;
8+
extern crate stm32g4xx_hal as hal;
9+
10+
use fixed::types::I1F15;
11+
use hal::cordic::{
12+
func::{dynamic::Mode as _, scale::N0, Magnitude, SinCos, Sqrt},
13+
prec::P60,
14+
types::{Q15, Q31},
15+
Ext as _,
16+
};
17+
use hal::prelude::*;
18+
use hal::pwr::PwrExt;
19+
use hal::rcc::Config;
20+
use hal::stm32;
21+
use rt::entry;
22+
23+
#[macro_use]
24+
mod utils;
25+
26+
use utils::logger::println;
27+
28+
#[entry]
29+
fn main() -> ! {
30+
let dp = stm32::Peripherals::take().expect("cannot take peripherals");
31+
let pwr = dp.PWR.constrain().freeze();
32+
let mut rcc = dp.RCC.freeze(Config::hsi(), pwr);
33+
34+
let mut cordic = dp
35+
.CORDIC
36+
.constrain(&mut rcc)
37+
.freeze::<Q15, Q31, SinCos, P60>(); // 16 bit arguments, 32 bit results, compute sine and cosine, 60 iterations
38+
39+
// static operation (zero overhead)
40+
41+
cordic.start(I1F15::from_num(-0.25 /* -45 degreees */));
42+
43+
let (sin, cos) = cordic.result();
44+
45+
println!("sin: {}, cos: {}", sin.to_num::<f32>(), cos.to_num::<f32>());
46+
47+
// dynamic operation
48+
49+
let mut cordic = cordic.into_dynamic();
50+
51+
let sqrt = cordic.run::<Sqrt<N0>>(I1F15::from_num(0.25));
52+
println!("sqrt: {}", sqrt.to_num::<f32>());
53+
let magnitude = cordic.run::<Magnitude>((I1F15::from_num(0.25), I1F15::from_num(0.5)));
54+
println!("magnitude: {}", magnitude.to_num::<f32>());
55+
56+
loop {}
57+
}

examples/opamp.rs

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,7 @@
55

66
use stm32g4xx_hal::adc::AdcClaim;
77
use stm32g4xx_hal::adc::ClockSource;
8-
use stm32g4xx_hal::gpio::gpioa::*;
9-
use stm32g4xx_hal::gpio::Analog;
10-
use stm32g4xx_hal::opamp::opamp1::IntoPga as _;
11-
use stm32g4xx_hal::opamp::opamp2::IntoPga as _;
12-
use stm32g4xx_hal::opamp::NonInvertingGain;
13-
use stm32g4xx_hal::opamp::PgaModeInternal;
8+
use stm32g4xx_hal::opamp::{Gain, InternalOutput};
149
use stm32g4xx_hal::prelude::*;
1510
use stm32g4xx_hal::pwr::PwrExt;
1611

@@ -40,32 +35,36 @@ fn main() -> ! {
4035
let (opamp1, opamp2, opamp3, ..) = dp.OPAMP.split(&mut rcc);
4136

4237
// Set up opamp1 and opamp2 in follower mode
43-
let opamp1 = opamp1.follower(gpioa.pa1, Some(gpioa.pa2));
44-
let opamp2 = opamp2.follower(gpioa.pa7, Option::<PA6<Analog>>::None);
38+
let opamp1 = opamp1.follower(gpioa.pa1, gpioa.pa2);
39+
let opamp2 = opamp2.follower(gpioa.pa7, InternalOutput);
4540

4641
// Set up opamp1 and opamp2 in open loop mode
47-
let opamp3 = opamp3.open_loop(gpiob.pb0, gpiob.pb2, Some(gpiob.pb1));
42+
let opamp3 = opamp3.open_loop(gpiob.pb0, gpiob.pb2, gpiob.pb1);
4843

4944
// disable opamps
50-
let (opamp1, pa1, some_pa2) = opamp1.disable();
51-
let (opamp2, pa7, _none) = opamp2.disable();
45+
let (opamp1, pa1, pa2) = opamp1.disable();
46+
let (opamp2, pa7) = opamp2.disable();
5247

53-
let (_opamp3, _pb0, _pb2, _some_pb1) = opamp3.disable();
48+
let (_opamp3, _pb0, _pb2, _pb1) = opamp3.disable();
5449

5550
// Configure opamp1 with pa1 as non-inverting input and set gain to x2
5651
let _opamp1 = opamp1.pga(
5752
pa1,
58-
PgaModeInternal::gain(NonInvertingGain::Gain2),
59-
some_pa2, // Route output to pin pa2
53+
pa2, // Route output to pin pa2
54+
Gain::Gain2,
6055
);
6156

6257
// Configure op with pa7 as non-inverting input and set gain to x4
6358
let opamp2 = opamp2.pga(
6459
pa7,
65-
PgaModeInternal::gain(NonInvertingGain::Gain4),
66-
Option::<PA6<Analog>>::None, // Do not route output to any external pin, use internal AD instead
60+
InternalOutput, // Do not route output to any external pin, use internal AD instead
61+
Gain::Gain4,
6762
);
6863

64+
// Lock opamp2. After the opamp is locked its registers cannot be written
65+
// until the device is reset (even if using unsafe register accesses).
66+
let opamp2 = opamp2.lock();
67+
6968
let mut delay = cp.SYST.delay(&rcc.clocks);
7069
let mut adc = dp
7170
.ADC2
@@ -86,8 +85,7 @@ fn main() -> ! {
8685

8786
#[allow(unreachable_code)]
8887
{
89-
let (_opamp1, _pa1, _mode) = _opamp1.disable();
90-
let (_opamp2, _pa7, _mode) = opamp2.disable();
88+
let (_opamp1, _pin) = _opamp1.disable();
9189

9290
loop {
9391
delay.delay_ms(100);

examples/utils/logger.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ cfg_if::cfg_if! {
4141

4242
#[allow(unused_macros)]
4343
macro_rules! println {
44-
($($tt:tt)*) => {
45-
log::info!($($tt,)*);
44+
($($arg:tt)+) => {
45+
log::info!($($arg)+);
4646
};
4747
}
4848

@@ -90,8 +90,11 @@ cfg_if::cfg_if! {
9090

9191
#[allow(unused_macros)]
9292
macro_rules! println {
93-
($($tt:tt)*) => {
94-
cortex_m_semihosting::hprintln!($($tt,)*).unwrap();
93+
($s:expr) => {
94+
cortex_m_semihosting::hprintln!($s).unwrap();
95+
};
96+
($s:expr, $($tt:tt)*) => {
97+
cortex_m_semihosting::hprintln!($s, $($tt)*).unwrap();
9598
};
9699
}
97100

src/adc.rs

Lines changed: 25 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ pub use crate::time::U32Ext as _;
1313
use crate::{
1414
dma::{mux::DmaMuxResources, traits::TargetAddress, PeripheralToMemory},
1515
gpio::*,
16-
opamp,
16+
opamp::{self, InternalOutput},
1717
rcc::{Enable, Rcc, Reset},
1818
signature::{VtempCal130, VtempCal30, VDDA_CALIB},
1919
stm32,
@@ -144,21 +144,25 @@ macro_rules! adc_pins {
144144
};
145145
}
146146

147-
macro_rules! adc_op_pga {
147+
macro_rules! adc_opamp {
148148
($($opamp:ty => ($adc:ident, $chan:expr)),+ $(,)*) => {
149149
$(
150-
impl<A, B> Channel<stm32::$adc> for $opamp {
150+
impl<A> Channel<stm32::$adc> for opamp::Follower<$opamp, A, InternalOutput> {
151151
type ID = u8;
152152
fn channel() -> u8 { $chan }
153153
}
154-
)+
155-
};
156-
}
157154

158-
macro_rules! adc_op_follower {
159-
($($opamp:ty => ($adc:ident, $chan:expr)),+ $(,)*) => {
160-
$(
161-
impl<A> Channel<stm32::$adc> for $opamp {
155+
impl<A, B> Channel<stm32::$adc> for opamp::OpenLoop<$opamp, A, B, InternalOutput> {
156+
type ID = u8;
157+
fn channel() -> u8 { $chan }
158+
}
159+
160+
impl<A> Channel<stm32::$adc> for opamp::Pga<$opamp, A, InternalOutput> {
161+
type ID = u8;
162+
fn channel() -> u8 { $chan }
163+
}
164+
165+
impl Channel<stm32::$adc> for opamp::Locked<$opamp, InternalOutput> {
162166
type ID = u8;
163167
fn channel() -> u8 { $chan }
164168
}
@@ -2811,21 +2815,13 @@ adc_pins!(
28112815
);
28122816

28132817
// See https://www.st.com/resource/en/reference_manual/rm0440-stm32g4-series-advanced-armbased-32bit-mcus-stmicroelectronics.pdf#page=782
2814-
adc_op_pga!(
2818+
adc_opamp!(
28152819
// TODO: Add all opamp types: OpenLoop, Follower(for all opamps)
28162820
// TODO: Should we restrict type parameters A and B?
28172821
// TODO: Also allow AD-channels shared by pins
2818-
opamp::opamp1::Pga<A, B> => (ADC1, 13),
2819-
opamp::opamp2::Pga<A, B> => (ADC2, 16),
2820-
2821-
opamp::opamp3::Pga<A, B> => (ADC2, 18),
2822-
);
2823-
2824-
adc_op_follower!(
2825-
opamp::opamp1::Follower<A> => (ADC1, 13),
2826-
opamp::opamp2::Follower<A> => (ADC2, 16),
2827-
2828-
opamp::opamp3::Follower<A> => (ADC2, 18),
2822+
opamp::Opamp1 => (ADC1, 13),
2823+
opamp::Opamp2 => (ADC2, 16),
2824+
opamp::Opamp3 => (ADC2, 18),
28292825
);
28302826

28312827
#[cfg(any(
@@ -2836,16 +2832,16 @@ adc_op_follower!(
28362832
feature = "stm32g491",
28372833
feature = "stm32g4a1",
28382834
))]
2839-
adc_op_pga!(
2840-
opamp::opamp3::Pga<A, B> => (ADC3, 13),
2841-
opamp::opamp4::Pga<A, B> => (ADC5, 5),
2842-
opamp::opamp5::Pga<A, B> => (ADC5, 3),
2843-
opamp::opamp6::Pga<A, B> => (ADC4, 17),
2835+
adc_opamp!(
2836+
opamp::Opamp3 => (ADC3, 13),
2837+
opamp::Opamp4 => (ADC5, 5),
2838+
opamp::Opamp5 => (ADC5, 3),
2839+
opamp::Opamp6 => (ADC4, 17),
28442840
);
28452841

28462842
#[cfg(any(feature = "stm32g491", feature = "stm32g4a1",))]
2847-
adc_op_pga!(
2848-
opamp::opamp6::Pga<A, B> => (ADC3, 17),
2843+
adc_opamp!(
2844+
opamp::Opamp6 => (ADC3, 17),
28492845
);
28502846

28512847
#[cfg(any(feature = "stm32g491", feature = "stm32g4a1",))]

0 commit comments

Comments
 (0)