Skip to content

Commit 879bcb9

Browse files
authored
Merge pull request #277 from Sh3Rm4n/peripheral
Add way to modify underlying peripheral
2 parents 44032b1 + 8c0f667 commit 879bcb9

File tree

9 files changed

+189
-82
lines changed

9 files changed

+189
-82
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
6464
- Add `use_pll` to `CFGR` - the clock configuration - to force to use the PLL
6565
source for the systemclock. Also `Clocks::pllclk()` was introduced to be able
6666
to check, whether PLL is used.
67+
- Add unsafe peripheral function to access underlying peripheral ([#277])
6768

6869
[`enumset`]: https://crates.io/crates/enumset
6970

@@ -143,6 +144,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
143144
- A generic `Instance` trait now represents all Spi peripherals.
144145
- `Spi::spi1` and so on are renamed to `Spi::new`.
145146
- Add SPI configuration type to be passed into `Spi::new`
147+
- Remove public fields from `Adc` and `Rtc` ([#277])
146148

147149
## [v0.7.0] - 2021-06-18
148150

@@ -468,6 +470,7 @@ let clocks = rcc
468470
[defmt]: https://github.com/knurling-rs/defmt
469471
[filter]: https://defmt.ferrous-systems.com/filtering.html
470472

473+
[#277]: https://github.com/stm32-rs/stm32f3xx-hal/pull/277
471474
[#273]: https://github.com/stm32-rs/stm32f3xx-hal/pull/273
472475
[#271]: https://github.com/stm32-rs/stm32f3xx-hal/pull/271
473476
[#270]: https://github.com/stm32-rs/stm32f3xx-hal/pull/270

src/adc.rs

Lines changed: 61 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ const MAX_ADVREGEN_STARTUP_US: u32 = 10;
3838
// TODO(Sh3Rm4n) Add configuration and other things like in the `stm32f4xx-hal` crate
3939
pub struct Adc<ADC> {
4040
/// ADC Register
41-
pub rb: ADC,
41+
adc: ADC,
4242
clocks: Clocks,
4343
clock_mode: ClockMode,
4444
operation_mode: Option<OperationMode>,
@@ -312,14 +312,14 @@ macro_rules! adc_hal {
312312
/// * the clock was already enabled with a different setting
313313
///
314314
pub fn $adcx(
315-
rb: $ADC,
315+
adc: $ADC,
316316
adc_common : &mut $ADC_COMMON,
317317
ahb: &mut AHB,
318318
clock_mode: ClockMode,
319319
clocks: Clocks,
320320
) -> Self {
321321
let mut this_adc = Self {
322-
rb,
322+
adc,
323323
clocks,
324324
clock_mode,
325325
operation_mode: None,
@@ -344,7 +344,7 @@ macro_rules! adc_hal {
344344
/// Releases the ADC peripheral and associated pins
345345
pub fn free(mut self) -> $ADC {
346346
self.disable();
347-
self.rb
347+
self.adc
348348
}
349349

350350
/// Software can use ClockMode::SyncDiv1 only if
@@ -359,10 +359,10 @@ macro_rules! adc_hal {
359359

360360
/// sets up adc in one shot mode for a single channel
361361
pub fn setup_oneshot(&mut self) {
362-
self.rb.cr.modify(|_, w| w.adstp().stop());
363-
self.rb.isr.modify(|_, w| w.ovr().clear());
362+
self.adc.cr.modify(|_, w| w.adstp().stop());
363+
self.adc.isr.modify(|_, w| w.ovr().clear());
364364

365-
self.rb.cfgr.modify(|_, w| w
365+
self.adc.cfgr.modify(|_, w| w
366366
.cont().single()
367367
.ovrmod().preserve()
368368
);
@@ -374,11 +374,11 @@ macro_rules! adc_hal {
374374

375375
fn set_sequence_len(&mut self, len: u8) {
376376
crate::assert!(len - 1 < 16, "ADC sequence length must be in 1..=16");
377-
self.rb.sqr1.modify(|_, w| w.l().bits(len - 1));
377+
self.adc.sqr1.modify(|_, w| w.l().bits(len - 1));
378378
}
379379

380380
fn set_align(&self, align: Align) {
381-
self.rb.cfgr.modify(|_, w| w.align().variant(align.into()));
381+
self.adc.cfgr.modify(|_, w| w.align().variant(align.into()));
382382
}
383383

384384
/// Software procedure to enable the ADC
@@ -388,12 +388,12 @@ macro_rules! adc_hal {
388388
// ADRDY=1 was set.
389389
// This assumption is true, if the peripheral was initially enabled through
390390
// this method.
391-
if !self.rb.cr.read().aden().is_enable() {
391+
if !self.adc.cr.read().aden().is_enable() {
392392
// Set ADEN=1
393-
self.rb.cr.modify(|_, w| w.aden().enable());
393+
self.adc.cr.modify(|_, w| w.aden().enable());
394394
// Wait until ADRDY=1 (ADRDY is set after the ADC startup time). This can be
395395
// done using the associated interrupt (setting ADRDYIE=1).
396-
while self.rb.isr.read().adrdy().is_not_ready() {}
396+
while self.adc.isr.read().adrdy().is_not_ready() {}
397397
}
398398
}
399399

@@ -402,39 +402,39 @@ macro_rules! adc_hal {
402402
// NOTE: Software is allowed to set ADSTP only when ADSTART=1 and ADDIS=0
403403
// (ADC is enabled and eventually converting a regular conversion and there is no
404404
// pending request to disable the ADC)
405-
if self.rb.cr.read().addis().bit() == false
406-
&& (self.rb.cr.read().adstart().bit() || self.rb.cr.read().jadstart().bit()) {
407-
self.rb.cr.modify(|_, w| w.adstp().stop());
405+
if self.adc.cr.read().addis().bit() == false
406+
&& (self.adc.cr.read().adstart().bit() || self.adc.cr.read().jadstart().bit()) {
407+
self.adc.cr.modify(|_, w| w.adstp().stop());
408408
// NOTE: In auto-injection mode (JAUTO=1), setting ADSTP bit aborts both
409409
// regular and injected conversions (do not use JADSTP)
410-
if !self.rb.cfgr.read().jauto().is_enabled() {
411-
self.rb.cr.modify(|_, w| w.jadstp().stop());
410+
if !self.adc.cfgr.read().jauto().is_enabled() {
411+
self.adc.cr.modify(|_, w| w.jadstp().stop());
412412
}
413-
while self.rb.cr.read().adstp().bit() || self.rb.cr.read().jadstp().bit() { }
413+
while self.adc.cr.read().adstp().bit() || self.adc.cr.read().jadstp().bit() { }
414414
}
415415

416416
// NOTE: Software is allowed to set ADDIS only when ADEN=1 and both ADSTART=0
417417
// and JADSTART=0 (which ensures that no conversion is ongoing)
418-
if self.rb.cr.read().aden().is_enable() {
419-
self.rb.cr.modify(|_, w| w.addis().disable());
420-
while self.rb.cr.read().addis().bit() { }
418+
if self.adc.cr.read().aden().is_enable() {
419+
self.adc.cr.modify(|_, w| w.addis().disable());
420+
while self.adc.cr.read().addis().bit() { }
421421
}
422422
}
423423

424424
/// Calibrate according to RM0316 15.3.8
425425
fn calibrate(&mut self) {
426-
if !self.rb.cr.read().advregen().is_enabled() {
426+
if !self.adc.cr.read().advregen().is_enabled() {
427427
self.advregen_enable();
428428
self.wait_advregen_startup();
429429
}
430430

431431
self.disable();
432432

433-
self.rb.cr.modify(|_, w| w
433+
self.adc.cr.modify(|_, w| w
434434
.adcaldif().single_ended()
435435
.adcal() .calibration());
436436

437-
while self.rb.cr.read().adcal().is_calibration() {}
437+
while self.adc.cr.read().adcal().is_calibration() {}
438438
}
439439

440440
fn wait_adc_clk_cycles(&self, cycles: u32) {
@@ -451,8 +451,8 @@ macro_rules! adc_hal {
451451

452452
fn advregen_enable(&mut self){
453453
// need to go through intermediate first
454-
self.rb.cr.modify(|_, w| w.advregen().intermediate());
455-
self.rb.cr.modify(|_, w| w.advregen().enabled());
454+
self.adc.cr.modify(|_, w| w.advregen().intermediate());
455+
self.adc.cr.modify(|_, w| w.advregen().enabled());
456456
}
457457

458458
/// wait for the advregen to startup.
@@ -470,16 +470,16 @@ macro_rules! adc_hal {
470470
self.set_chan_smps(chan, SampleTime::default());
471471
self.select_single_chan(chan);
472472

473-
self.rb.cr.modify(|_, w| w.adstart().start());
474-
while self.rb.isr.read().eos().is_not_complete() {}
475-
self.rb.isr.modify(|_, w| w.eos().clear());
476-
return self.rb.dr.read().rdata().bits();
473+
self.adc.cr.modify(|_, w| w.adstart().start());
474+
while self.adc.isr.read().eos().is_not_complete() {}
475+
self.adc.isr.modify(|_, w| w.eos().clear());
476+
return self.adc.dr.read().rdata().bits();
477477
}
478478

479479
/// This should only be invoked with the defined channels for the particular
480480
/// device. (See Pin/Channel mapping above)
481481
fn select_single_chan(&self, chan: u8) {
482-
self.rb.sqr1.modify(|_, w|
482+
self.adc.sqr1.modify(|_, w|
483483
// NOTE(unsafe): chan is the x in ADCn_INx
484484
unsafe { w.sq1().bits(chan) }
485485
);
@@ -489,27 +489,40 @@ macro_rules! adc_hal {
489489
// TODO: there are boundaries on how this can be set depending on the hardware.
490490
fn set_chan_smps(&self, chan: u8, smp: SampleTime) {
491491
match chan {
492-
1 => self.rb.smpr1.modify(|_, w| w.smp1().variant(smp.into())),
493-
2 => self.rb.smpr1.modify(|_, w| w.smp2().variant(smp.into())),
494-
3 => self.rb.smpr1.modify(|_, w| w.smp3().variant(smp.into())),
495-
4 => self.rb.smpr1.modify(|_, w| w.smp4().variant(smp.into())),
496-
5 => self.rb.smpr1.modify(|_, w| w.smp5().variant(smp.into())),
497-
6 => self.rb.smpr1.modify(|_, w| w.smp6().variant(smp.into())),
498-
7 => self.rb.smpr1.modify(|_, w| w.smp7().variant(smp.into())),
499-
8 => self.rb.smpr1.modify(|_, w| w.smp8().variant(smp.into())),
500-
9 => self.rb.smpr1.modify(|_, w| w.smp9().variant(smp.into())),
501-
11 => self.rb.smpr2.modify(|_, w| w.smp10().variant(smp.into())),
502-
12 => self.rb.smpr2.modify(|_, w| w.smp12().variant(smp.into())),
503-
13 => self.rb.smpr2.modify(|_, w| w.smp13().variant(smp.into())),
504-
14 => self.rb.smpr2.modify(|_, w| w.smp14().variant(smp.into())),
505-
15 => self.rb.smpr2.modify(|_, w| w.smp15().variant(smp.into())),
506-
16 => self.rb.smpr2.modify(|_, w| w.smp16().variant(smp.into())),
507-
17 => self.rb.smpr2.modify(|_, w| w.smp17().variant(smp.into())),
508-
18 => self.rb.smpr2.modify(|_, w| w.smp18().variant(smp.into())),
492+
1 => self.adc.smpr1.modify(|_, w| w.smp1().variant(smp.into())),
493+
2 => self.adc.smpr1.modify(|_, w| w.smp2().variant(smp.into())),
494+
3 => self.adc.smpr1.modify(|_, w| w.smp3().variant(smp.into())),
495+
4 => self.adc.smpr1.modify(|_, w| w.smp4().variant(smp.into())),
496+
5 => self.adc.smpr1.modify(|_, w| w.smp5().variant(smp.into())),
497+
6 => self.adc.smpr1.modify(|_, w| w.smp6().variant(smp.into())),
498+
7 => self.adc.smpr1.modify(|_, w| w.smp7().variant(smp.into())),
499+
8 => self.adc.smpr1.modify(|_, w| w.smp8().variant(smp.into())),
500+
9 => self.adc.smpr1.modify(|_, w| w.smp9().variant(smp.into())),
501+
11 => self.adc.smpr2.modify(|_, w| w.smp10().variant(smp.into())),
502+
12 => self.adc.smpr2.modify(|_, w| w.smp12().variant(smp.into())),
503+
13 => self.adc.smpr2.modify(|_, w| w.smp13().variant(smp.into())),
504+
14 => self.adc.smpr2.modify(|_, w| w.smp14().variant(smp.into())),
505+
15 => self.adc.smpr2.modify(|_, w| w.smp15().variant(smp.into())),
506+
16 => self.adc.smpr2.modify(|_, w| w.smp16().variant(smp.into())),
507+
17 => self.adc.smpr2.modify(|_, w| w.smp17().variant(smp.into())),
508+
18 => self.adc.smpr2.modify(|_, w| w.smp18().variant(smp.into())),
509509
_ => crate::unreachable!(),
510510
};
511511
}
512512

513+
/// Get access to the underlying register block.
514+
///
515+
/// # Safety
516+
///
517+
/// This function is not _memory_ unsafe per se, but does not guarantee
518+
/// anything about assumptions of invariants made in this implementation.
519+
///
520+
/// Changing specific options can lead to un-expected behavior and nothing
521+
/// is guaranteed.
522+
pub unsafe fn peripheral(&mut self) -> &mut $ADC {
523+
&mut self.adc
524+
}
525+
513526
}
514527

515528
impl<Word, Pin> OneShot<$ADC, Word, Pin> for Adc<$ADC>

src/delay.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,19 @@ impl Delay {
5555
Delay { clocks, syst }
5656
}
5757

58+
/// Get access to the underlying register block.
59+
///
60+
/// # Safety
61+
///
62+
/// This function is not _memory_ unsafe per se, but does not guarantee
63+
/// anything about assumptions of invariants made in this implementation.
64+
///
65+
/// Changing specific options can lead to un-expected behavior and nothing
66+
/// is guaranteed.
67+
pub unsafe fn peripheral(&mut self) -> &mut SYST {
68+
&mut self.syst
69+
}
70+
5871
/// Releases the system timer (SysTick) resource
5972
pub fn free(self) -> SYST {
6073
self.syst

src/i2c.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,19 @@ impl<I2C, SCL, SDA> I2c<I2C, (SCL, SDA)> {
195195
Self { i2c, pins }
196196
}
197197

198+
/// Get access to the underlying register block.
199+
///
200+
/// # Safety
201+
///
202+
/// This function is not _memory_ unsafe per se, but does not guarantee
203+
/// anything about assumptions of invariants made in this implementation.
204+
///
205+
/// Changing specific options can lead to un-expected behavior and nothing
206+
/// is guaranteed.
207+
pub unsafe fn peripheral(&mut self) -> &mut I2C {
208+
&mut self.i2c
209+
}
210+
198211
/// Releases the I2C peripheral and associated pins
199212
pub fn free(self) -> (I2C, (SCL, SDA)) {
200213
(self.i2c, self.pins)

0 commit comments

Comments
 (0)