Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ embedded-hal = { version = "0.2.6", features = ["unproven"] }
embedded-dma = "0.2.0"
cortex-m = { version = "^0.7.7", features = ["critical-section-single-core"] }
defmt = { version = ">=0.2.0,<0.4", optional = true }
stm32h7 = { version = "0.16.0", package = "stm32h7-staging", features = ["critical-section"], default-features = false }
stm32h7 = { git = "https://github.com/stm32-rs/stm32-rs-nightlies", features = ["critical-section"], default-features = false }
#stm32h7 = { version = "0.17.0", package = "stm32h7-staging", features = ["critical-section"], default-features = false }
void = { version = "1.0.2", default-features = false }
cast = { version = "0.3.0", default-features = false }
nb = "1.0.0"
Expand Down
6 changes: 3 additions & 3 deletions src/adc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -734,10 +734,10 @@ macro_rules! adc_hal {
/// Enable ADC
pub fn enable(mut self) -> Adc<$ADC, Enabled> {
// Refer to RM0433 Rev 7 - Chapter 25.4.9
self.rb.isr().modify(|_, w| w.adrdy().set_bit());
self.rb.cr().modify(|_, w| w.aden().set_bit());
self.rb.isr().modify(|_, w| w.adrdy().clear());
self.rb.cr().modify(|_, w| w.aden().enabled());
while self.rb.isr().read().adrdy().bit_is_clear() {}
self.rb.isr().modify(|_, w| w.adrdy().set_bit());
self.rb.isr().modify(|_, w| w.adrdy().clear());

self.configure();

Expand Down
211 changes: 67 additions & 144 deletions src/dma/bdma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -587,161 +587,84 @@ where
}
}

// Macro that creates a struct representing a stream on either BDMA controller
// A struct representing a stream on either BDMA controller
//
// The implementation does the heavy lifting of mapping to the right fields on
// the stream
macro_rules! bdma_stream {
($(($name:ident, $number:expr,
$ifcr:ident, $tcif:ident, $htif:ident, $teif:ident, $gif:ident,
$isr:ident, $tcisr:ident, $htisr:ident, $teisr:ident, $gisr:ident)
),+$(,)*) => {
$(
impl<I: Instance> InstanceStream for StreamX<I, $number> {
#[inline(always)]
fn stream_clear_interrupts(&mut self) {
//NOTE(unsafe) Atomic write with no side-effects and we only access the bits
// that belongs to the StreamX
let dma = unsafe { &*I::ptr() };
dma.$ifcr().write(|w| w
.$tcif().set_bit() //Clear transfer complete interrupt flag
.$htif().set_bit() //Clear half transfer interrupt flag
.$teif().set_bit() //Clear transfer error interrupt flag
.$gif().set_bit() //Clear global interrupt flag
);
let _ = dma.$isr().read();
let _ = dma.$isr().read(); // Delay 2 peripheral clocks
}
impl<I: Instance, const S: u8> InstanceStream for StreamX<I, S> {
#[inline(always)]
fn stream_clear_interrupts(&mut self) {
//NOTE(unsafe) Atomic write with no side-effects and we only access the bits
// that belongs to the StreamX
let dma = unsafe { &*I::ptr() };
dma.ifcr().write(
|w| {
w.ctcif(S)
.set_bit() //Clear transfer complete interrupt flag
.chtif(S)
.set_bit() //Clear half transfer interrupt flag
.cteif(S)
.set_bit() //Clear transfer error interrupt flag
.cgif(S)
.set_bit()
}, //Clear global interrupt flag
);
let _ = dma.isr().read();
let _ = dma.isr().read(); // Delay 2 peripheral clocks
}

#[inline(always)]
fn stream_clear_transfer_complete_flag(&mut self) {
//NOTE(unsafe) Atomic write with no side-effects and we only access the bits
// that belongs to the StreamX
let dma = unsafe { &*I::ptr() };
dma.$ifcr().write(|w| w.$tcif().set_bit());
}
#[inline(always)]
fn stream_clear_transfer_complete_flag(&mut self) {
//NOTE(unsafe) Atomic write with no side-effects and we only access the bits
// that belongs to the StreamX
let dma = unsafe { &*I::ptr() };
dma.ifcr().write(|w| w.ctcif(S).set_bit());
}

#[inline(always)]
fn stream_clear_transfer_complete_interrupt(&mut self) {
self.stream_clear_transfer_complete_flag();
//NOTE(unsafe) Atomic read with no side-effects.
let dma = unsafe { &*I::ptr() };
let _ = dma.$isr().read();
let _ = dma.$isr().read(); // Delay 2 peripheral clocks
}
#[inline(always)]
fn stream_clear_transfer_complete_interrupt(&mut self) {
self.stream_clear_transfer_complete_flag();
//NOTE(unsafe) Atomic read with no side-effects.
let dma = unsafe { &*I::ptr() };
let _ = dma.isr().read();
let _ = dma.isr().read(); // Delay 2 peripheral clocks
}

#[inline(always)]
fn stream_clear_transfer_error_interrupt(&mut self) {
//NOTE(unsafe) Atomic write with no side-effects and we only access the bits
// that belongs to the StreamX
let dma = unsafe { &*I::ptr() };
dma.$ifcr().write(|w| w.$teif().set_bit());
let _ = dma.$isr().read();
let _ = dma.$isr().read(); // Delay 2 peripheral clocks
}
#[inline(always)]
fn stream_clear_transfer_error_interrupt(&mut self) {
//NOTE(unsafe) Atomic write with no side-effects and we only access the bits
// that belongs to the StreamX
let dma = unsafe { &*I::ptr() };
dma.ifcr().write(|w| w.cteif(S).set_bit());
let _ = dma.isr().read();
let _ = dma.isr().read(); // Delay 2 peripheral clocks
}

#[inline(always)]
fn stream_get_transfer_complete_flag() -> bool {
//NOTE(unsafe) Atomic read with no side effects
let dma = unsafe { &*I::ptr() };
dma.$isr().read().$tcisr().bit_is_set()
}
#[inline(always)]
fn stream_get_transfer_complete_flag() -> bool {
//NOTE(unsafe) Atomic read with no side effects
let dma = unsafe { &*I::ptr() };
dma.isr().read().tcif(S).bit_is_set()
}

#[inline(always)]
fn stream_get_half_transfer_flag() -> bool {
//NOTE(unsafe) Atomic read with no side effects
let dma = unsafe { &*I::ptr() };
dma.$isr().read().$htisr().bit_is_set()
}
#[inline(always)]
fn stream_get_half_transfer_flag() -> bool {
//NOTE(unsafe) Atomic read with no side effects
let dma = unsafe { &*I::ptr() };
dma.isr().read().htif(S).bit_is_set()
}

#[inline(always)]
fn stream_clear_half_transfer_interrupt(&mut self) {
//NOTE(unsafe) Atomic write with no side-effects and we only access the bits
// that belongs to the StreamX
let dma = unsafe { &*I::ptr() };
dma.$ifcr().write(|w| w.$htif().set_bit());
let _ = dma.$isr().read();
let _ = dma.$isr().read(); // Delay 2 peripheral clocks
}
}
)+
};
#[inline(always)]
fn stream_clear_half_transfer_interrupt(&mut self) {
//NOTE(unsafe) Atomic write with no side-effects and we only access the bits
// that belongs to the StreamX
let dma = unsafe { &*I::ptr() };
dma.ifcr().write(|w| w.chtif(S).set_bit());
let _ = dma.isr().read();
let _ = dma.isr().read(); // Delay 2 peripheral clocks
}
}

#[cfg(not(feature = "rm0468"))]
bdma_stream!(
// Note: the field names start from one, unlike the RM where they start from
// zero. May need updating if it gets fixed upstream.
(
Stream0, 0, ifcr, ctcif1, chtif1, cteif1, cgif1, isr, tcif1, htif1,
teif1, gif1
),
(
Stream1, 1, ifcr, ctcif2, chtif2, cteif2, cgif2, isr, tcif2, htif2,
teif2, gif2
),
(
Stream2, 2, ifcr, ctcif3, chtif3, cteif3, cgif3, isr, tcif3, htif3,
teif3, gif3
),
(
Stream3, 3, ifcr, ctcif4, chtif4, cteif4, cgif4, isr, tcif4, htif4,
teif4, gif4
),
(
Stream4, 4, ifcr, ctcif5, chtif5, cteif5, cgif5, isr, tcif5, htif5,
teif5, gif5
),
(
Stream5, 5, ifcr, ctcif6, chtif6, cteif6, cgif6, isr, tcif6, htif6,
teif6, gif6
),
(
Stream6, 6, ifcr, ctcif7, chtif7, cteif7, cgif7, isr, tcif7, htif7,
teif7, gif7
),
(
Stream7, 7, ifcr, ctcif8, chtif8, cteif8, cgif8, isr, tcif8, htif8,
teif8, gif8
),
);
#[cfg(feature = "rm0468")]
bdma_stream!(
// For this sub-familiy, the field names do match the RM.
(
Stream0, 0, ifcr, ctcif0, chtif0, cteif0, cgif0, isr, tcif0, htif0,
teif0, gif0
),
(
Stream1, 1, ifcr, ctcif1, chtif1, cteif1, cgif1, isr, tcif1, htif1,
teif1, gif1
),
(
Stream2, 2, ifcr, ctcif2, chtif2, cteif2, cgif2, isr, tcif2, htif2,
teif2, gif2
),
(
Stream3, 3, ifcr, ctcif3, chtif3, cteif3, cgif3, isr, tcif3, htif3,
teif3, gif3
),
(
Stream4, 4, ifcr, ctcif4, chtif4, cteif4, cgif4, isr, tcif4, htif4,
teif4, gif4
),
(
Stream5, 5, ifcr, ctcif5, chtif5, cteif5, cgif5, isr, tcif5, htif5,
teif5, gif5
),
(
Stream6, 6, ifcr, ctcif6, chtif6, cteif6, cgif6, isr, tcif6, htif6,
teif6, gif6
),
(
Stream7, 7, ifcr, ctcif7, chtif7, cteif7, cgif7, isr, tcif7, htif7,
teif7, gif7
),
);

/// Type alias for the DMA Request Multiplexer
///
pub type DMAReq = pac::dmamux2::ccr::DMAREQ_ID;
Expand Down
6 changes: 4 additions & 2 deletions src/flash/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -277,8 +277,10 @@ const UNLOCK_KEY2: u32 = 0xCDEF_89AB;

#[allow(unused_unsafe)]
fn unlock(bank: &BANK) {
bank.keyr().write(|w| unsafe { w.keyr().bits(UNLOCK_KEY1) });
bank.keyr().write(|w| unsafe { w.keyr().bits(UNLOCK_KEY2) });
bank.keyr()
.write(|w| unsafe { w.key1r().bits(UNLOCK_KEY1) });
bank.keyr()
.write(|w| unsafe { w.key1r().bits(UNLOCK_KEY2) });
assert!(!bank.cr().read().lock().bit())
}

Expand Down
61 changes: 37 additions & 24 deletions src/flash/operations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ impl NorFlashError for Error {
impl Error {
fn read(flash_bank: &BANK) -> Option<Self> {
let sr = flash_bank.sr().read();

#[cfg(not(feature = "rm0455"))]
if sr.operr().bit() {
return Some(Error::Operation);
}

if sr.pgserr().bit() {
Some(Error::ProgrammingSequence)
} else if sr.wrperr().bit() {
Expand All @@ -61,8 +67,6 @@ impl Error {
Some(Error::Strobe)
} else if sr.incerr().bit() {
Some(Error::Inconsistency)
} else if sr.operr().bit() {
Some(Error::Operation)
} else if sr.rdperr().bit() {
Some(Error::ReadProtection)
} else if sr.rdserr().bit() {
Expand All @@ -75,22 +79,25 @@ impl Error {
}
}
fn clear_error_flags(regs: &BANK) {
regs.sr().modify(|_, w| {
w.pgserr()
.set_bit()
.wrperr()
regs.ccr().write(|w| {
let w = w
.clr_pgserr()
.set_bit()
.strberr()
.clr_wrperr()
.set_bit()
.incerr()
.clr_strberr()
.set_bit()
.operr()
.set_bit()
.rdperr()
.clr_incerr();

#[cfg(not(feature = "rm0455"))]
let w = w.set_bit().clr_operr();

w.set_bit()
.clr_rdperr()
.set_bit()
.rdserr()
.clr_rdserr()
.set_bit()
.dbeccerr()
.clr_dbeccerr()
.set_bit()
});
}
Expand Down Expand Up @@ -167,15 +174,19 @@ impl UnlockedFlashBank<'_> {

#[rustfmt::skip]
self.bank.cr().modify(|_, w| unsafe {
w
// start
.start().set_bit()
// sector number
.snb().bits(sector)
// sector erase
.ser().set_bit()
// sector number
#[cfg(feature = "rm0455")]
let w = w.ssn().bits(sector);

#[cfg(not(feature = "rm0455"))]
let w = w.snb().bits(sector);

// sector erase
w.ser().set_bit()
// not programming
.pg().clear_bit()
// start
.start().set_bit()
});
self.wait_ready();
self.ok()
Expand Down Expand Up @@ -214,11 +225,13 @@ impl UnlockedFlashBank<'_> {
#[rustfmt::skip]
#[allow(unused_unsafe)]
self.bank.cr().modify(|_, w| unsafe {
w
#[cfg(not(feature = "rm0455"))]
let w = w
// double-word parallelism
.psize().bits(0b11)
// not sector erase
.ser().clear_bit()
.psize().bits(0b11);

// not sector erase
w.ser().clear_bit()
// programming
.pg().set_bit()
});
Expand Down
Loading
Loading