add IPCC peripheral for stm32wb
This commit is contained in:
parent
1cf26f0eb3
commit
8c733c29cc
2 changed files with 188 additions and 0 deletions
186
embassy-stm32/src/ipcc.rs
Normal file
186
embassy-stm32/src/ipcc.rs
Normal file
|
@ -0,0 +1,186 @@
|
|||
use embassy_hal_common::{into_ref, Peripheral, PeripheralRef};
|
||||
|
||||
use crate::peripherals::IPCC;
|
||||
|
||||
#[non_exhaustive]
|
||||
#[derive(Clone, Copy, Default)]
|
||||
pub struct Config {
|
||||
// TODO: add IPCC peripheral configuration, if any, here
|
||||
// reserved for future use
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[repr(C)]
|
||||
pub enum IpccChannel {
|
||||
Channel1 = 0,
|
||||
Channel2 = 1,
|
||||
Channel3 = 2,
|
||||
Channel4 = 3,
|
||||
Channel5 = 4,
|
||||
Channel6 = 5,
|
||||
}
|
||||
|
||||
pub(crate) mod sealed {
|
||||
pub trait Instance: crate::rcc::RccPeripheral {
|
||||
fn regs() -> crate::pac::ipcc::Ipcc;
|
||||
fn set_cpu2(enabled: bool);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Ipcc<'d> {
|
||||
_peri: PeripheralRef<'d, IPCC>,
|
||||
}
|
||||
|
||||
impl<'d> Ipcc<'d> {
|
||||
pub fn new(peri: impl Peripheral<P = IPCC> + 'd, _config: Config) -> Self {
|
||||
into_ref!(peri);
|
||||
|
||||
Self { _peri: peri }
|
||||
}
|
||||
|
||||
pub fn init(&mut self) {
|
||||
IPCC::enable();
|
||||
IPCC::reset();
|
||||
IPCC::set_cpu2(true);
|
||||
|
||||
unsafe { _configure_pwr() };
|
||||
|
||||
let regs = IPCC::regs();
|
||||
|
||||
unsafe {
|
||||
regs.cpu(0).cr().modify(|w| {
|
||||
w.set_rxoie(true);
|
||||
w.set_txfie(true);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn c1_set_rx_channel(&mut self, channel: IpccChannel, enabled: bool) {
|
||||
let regs = IPCC::regs();
|
||||
|
||||
// If bit is set to 1 then interrupt is disabled
|
||||
unsafe { regs.cpu(0).mr().modify(|w| w.set_chom(channel.into(), !enabled)) }
|
||||
}
|
||||
|
||||
pub fn c1_get_rx_channel(&self, channel: IpccChannel) -> bool {
|
||||
let regs = IPCC::regs();
|
||||
|
||||
// If bit is set to 1 then interrupt is disabled
|
||||
unsafe { !regs.cpu(0).mr().read().chom(channel.into()) }
|
||||
}
|
||||
|
||||
pub fn c2_set_rx_channel(&mut self, channel: IpccChannel, enabled: bool) {
|
||||
let regs = IPCC::regs();
|
||||
|
||||
// If bit is set to 1 then interrupt is disabled
|
||||
unsafe { regs.cpu(1).mr().modify(|w| w.set_chom(channel.into(), !enabled)) }
|
||||
}
|
||||
|
||||
pub fn c2_get_rx_channel(&self, channel: IpccChannel) -> bool {
|
||||
let regs = IPCC::regs();
|
||||
|
||||
// If bit is set to 1 then interrupt is disabled
|
||||
unsafe { !regs.cpu(1).mr().read().chom(channel.into()) }
|
||||
}
|
||||
|
||||
pub fn c1_set_tx_channel(&mut self, channel: IpccChannel, enabled: bool) {
|
||||
let regs = IPCC::regs();
|
||||
|
||||
// If bit is set to 1 then interrupt is disabled
|
||||
unsafe { regs.cpu(0).mr().modify(|w| w.set_chfm(channel.into(), !enabled)) }
|
||||
}
|
||||
|
||||
pub fn c1_get_tx_channel(&self, channel: IpccChannel) -> bool {
|
||||
let regs = IPCC::regs();
|
||||
|
||||
// If bit is set to 1 then interrupt is disabled
|
||||
unsafe { !regs.cpu(0).mr().read().chfm(channel.into()) }
|
||||
}
|
||||
|
||||
pub fn c2_set_tx_channel(&mut self, channel: IpccChannel, enabled: bool) {
|
||||
let regs = IPCC::regs();
|
||||
|
||||
// If bit is set to 1 then interrupt is disabled
|
||||
unsafe { regs.cpu(1).mr().modify(|w| w.set_chfm(channel.into(), !enabled)) }
|
||||
}
|
||||
|
||||
pub fn c2_get_tx_channel(&self, channel: IpccChannel) -> bool {
|
||||
let regs = IPCC::regs();
|
||||
|
||||
// If bit is set to 1 then interrupt is disabled
|
||||
unsafe { !regs.cpu(1).mr().read().chfm(channel.into()) }
|
||||
}
|
||||
|
||||
/// clears IPCC receive channel status for CPU1
|
||||
pub fn c1_clear_flag_channel(&mut self, channel: IpccChannel) {
|
||||
let regs = IPCC::regs();
|
||||
|
||||
unsafe { regs.cpu(0).scr().write(|w| w.set_chc(channel.into(), true)) }
|
||||
}
|
||||
|
||||
/// clears IPCC receive channel status for CPU2
|
||||
pub fn c2_clear_flag_channel(&mut self, channel: IpccChannel) {
|
||||
let regs = IPCC::regs();
|
||||
|
||||
unsafe { regs.cpu(1).scr().write(|w| w.set_chc(channel.into(), true)) }
|
||||
}
|
||||
|
||||
pub fn c1_set_flag_channel(&mut self, channel: IpccChannel) {
|
||||
let regs = IPCC::regs();
|
||||
|
||||
unsafe { regs.cpu(0).scr().write(|w| w.set_chs(channel.into(), true)) }
|
||||
}
|
||||
|
||||
pub fn c2_set_flag_channel(&mut self, channel: IpccChannel) {
|
||||
let regs = IPCC::regs();
|
||||
|
||||
unsafe { regs.cpu(1).scr().write(|w| w.set_chs(channel.into(), true)) }
|
||||
}
|
||||
|
||||
pub fn c1_is_active_flag(&self, channel: IpccChannel) -> bool {
|
||||
let regs = IPCC::regs();
|
||||
|
||||
unsafe { regs.cpu(0).sr().read().chf(channel.into()) }
|
||||
}
|
||||
|
||||
pub fn c2_is_active_flag(&self, channel: IpccChannel) -> bool {
|
||||
let regs = IPCC::regs();
|
||||
|
||||
unsafe { regs.cpu(1).sr().read().chf(channel.into()) }
|
||||
}
|
||||
|
||||
pub fn is_tx_pending(&self, channel: IpccChannel) -> bool {
|
||||
!self.c1_is_active_flag(channel) && self.c1_get_tx_channel(channel)
|
||||
}
|
||||
|
||||
pub fn is_rx_pending(&self, channel: IpccChannel) -> bool {
|
||||
self.c2_is_active_flag(channel) && self.c1_get_rx_channel(channel)
|
||||
}
|
||||
}
|
||||
|
||||
impl sealed::Instance for crate::peripherals::IPCC {
|
||||
fn regs() -> crate::pac::ipcc::Ipcc {
|
||||
crate::pac::IPCC
|
||||
}
|
||||
|
||||
fn set_cpu2(enabled: bool) {
|
||||
unsafe { crate::pac::PWR.cr4().modify(|w| w.set_c2boot(enabled)) }
|
||||
}
|
||||
}
|
||||
|
||||
/// extension trait that constrains the [`Ipcc`] peripheral
|
||||
pub trait IpccExt<'d> {
|
||||
fn constrain(self) -> Ipcc<'d>;
|
||||
}
|
||||
impl<'d> IpccExt<'d> for IPCC {
|
||||
fn constrain(self) -> Ipcc<'d> {
|
||||
Ipcc { _peri: self.into_ref() }
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn _configure_pwr() {
|
||||
let rcc = crate::pac::RCC;
|
||||
|
||||
// set RF wake-up clock = LSE
|
||||
rcc.csr().modify(|w| w.set_rfwkpsel(0b01));
|
||||
}
|
|
@ -44,6 +44,8 @@ pub mod i2c;
|
|||
#[cfg(crc)]
|
||||
pub mod crc;
|
||||
pub mod flash;
|
||||
#[cfg(stm32wb)]
|
||||
pub mod ipcc;
|
||||
pub mod pwm;
|
||||
#[cfg(quadspi)]
|
||||
pub mod qspi;
|
||||
|
|
Loading…
Reference in a new issue