embassy/embassy-stm32/src/tl_mbox/ipcc.rs

175 lines
4.7 KiB
Rust
Raw Normal View History

2023-05-27 22:05:07 +02:00
use self::sealed::Instance;
2023-04-27 17:03:22 +02:00
use crate::peripherals::IPCC;
2023-04-27 17:22:41 +02:00
use crate::rcc::sealed::RccPeripheral;
2023-04-27 17:03:22 +02:00
#[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,
}
2023-05-27 22:05:07 +02:00
pub mod sealed {
2023-04-27 17:03:22 +02:00
pub trait Instance: crate::rcc::RccPeripheral {
fn regs() -> crate::pac::ipcc::Ipcc;
fn set_cpu2(enabled: bool);
}
}
2023-05-27 22:05:07 +02:00
pub struct Ipcc;
2023-04-27 17:03:22 +02:00
2023-05-26 10:56:55 +02:00
impl Ipcc {
2023-05-27 22:05:07 +02:00
pub fn enable(_config: Config) {
2023-04-27 17:03:22 +02:00
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);
})
}
}
2023-05-27 22:05:07 +02:00
pub fn c1_set_rx_channel(channel: IpccChannel, enabled: bool) {
2023-04-27 17:03:22 +02:00
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 as usize, !enabled)) }
2023-04-27 17:03:22 +02:00
}
2023-05-27 22:05:07 +02:00
pub fn c1_get_rx_channel(channel: IpccChannel) -> bool {
2023-04-27 17:03:22 +02:00
let regs = IPCC::regs();
// If bit is set to 1 then interrupt is disabled
unsafe { !regs.cpu(0).mr().read().chom(channel as usize) }
2023-04-27 17:03:22 +02:00
}
2023-05-26 10:56:55 +02:00
#[allow(dead_code)]
2023-05-27 22:05:07 +02:00
pub fn c2_set_rx_channel(channel: IpccChannel, enabled: bool) {
2023-04-27 17:03:22 +02:00
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 as usize, !enabled)) }
2023-04-27 17:03:22 +02:00
}
2023-05-26 10:56:55 +02:00
#[allow(dead_code)]
2023-05-27 22:05:07 +02:00
pub fn c2_get_rx_channel(channel: IpccChannel) -> bool {
2023-04-27 17:03:22 +02:00
let regs = IPCC::regs();
// If bit is set to 1 then interrupt is disabled
unsafe { !regs.cpu(1).mr().read().chom(channel as usize) }
2023-04-27 17:03:22 +02:00
}
2023-05-27 22:05:07 +02:00
pub fn c1_set_tx_channel(channel: IpccChannel, enabled: bool) {
2023-04-27 17:03:22 +02:00
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 as usize, !enabled)) }
2023-04-27 17:03:22 +02:00
}
2023-05-27 22:05:07 +02:00
pub fn c1_get_tx_channel(channel: IpccChannel) -> bool {
2023-04-27 17:03:22 +02:00
let regs = IPCC::regs();
// If bit is set to 1 then interrupt is disabled
unsafe { !regs.cpu(0).mr().read().chfm(channel as usize) }
2023-04-27 17:03:22 +02:00
}
2023-05-26 10:56:55 +02:00
#[allow(dead_code)]
2023-05-27 22:05:07 +02:00
pub fn c2_set_tx_channel(channel: IpccChannel, enabled: bool) {
2023-04-27 17:03:22 +02:00
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 as usize, !enabled)) }
2023-04-27 17:03:22 +02:00
}
2023-05-26 10:56:55 +02:00
#[allow(dead_code)]
2023-05-27 22:05:07 +02:00
pub fn c2_get_tx_channel(channel: IpccChannel) -> bool {
2023-04-27 17:03:22 +02:00
let regs = IPCC::regs();
// If bit is set to 1 then interrupt is disabled
unsafe { !regs.cpu(1).mr().read().chfm(channel as usize) }
2023-04-27 17:03:22 +02:00
}
/// clears IPCC receive channel status for CPU1
2023-05-27 22:05:07 +02:00
pub fn c1_clear_flag_channel(channel: IpccChannel) {
2023-04-27 17:03:22 +02:00
let regs = IPCC::regs();
unsafe { regs.cpu(0).scr().write(|w| w.set_chc(channel as usize, true)) }
2023-04-27 17:03:22 +02:00
}
2023-05-26 10:56:55 +02:00
#[allow(dead_code)]
2023-04-27 17:03:22 +02:00
/// clears IPCC receive channel status for CPU2
2023-05-27 22:05:07 +02:00
pub fn c2_clear_flag_channel(channel: IpccChannel) {
2023-04-27 17:03:22 +02:00
let regs = IPCC::regs();
unsafe { regs.cpu(1).scr().write(|w| w.set_chc(channel as usize, true)) }
2023-04-27 17:03:22 +02:00
}
2023-05-27 22:05:07 +02:00
pub fn c1_set_flag_channel(channel: IpccChannel) {
2023-04-27 17:03:22 +02:00
let regs = IPCC::regs();
unsafe { regs.cpu(0).scr().write(|w| w.set_chs(channel as usize, true)) }
2023-04-27 17:03:22 +02:00
}
2023-05-26 10:56:55 +02:00
#[allow(dead_code)]
2023-05-27 22:05:07 +02:00
pub fn c2_set_flag_channel(channel: IpccChannel) {
2023-04-27 17:03:22 +02:00
let regs = IPCC::regs();
unsafe { regs.cpu(1).scr().write(|w| w.set_chs(channel as usize, true)) }
2023-04-27 17:03:22 +02:00
}
2023-05-27 22:05:07 +02:00
pub fn c1_is_active_flag(channel: IpccChannel) -> bool {
2023-04-27 17:03:22 +02:00
let regs = IPCC::regs();
unsafe { regs.cpu(0).sr().read().chf(channel as usize) }
2023-04-27 17:03:22 +02:00
}
2023-05-27 22:05:07 +02:00
pub fn c2_is_active_flag(channel: IpccChannel) -> bool {
2023-04-27 17:03:22 +02:00
let regs = IPCC::regs();
unsafe { regs.cpu(1).sr().read().chf(channel as usize) }
2023-04-27 17:03:22 +02:00
}
2023-05-27 22:05:07 +02:00
pub fn is_tx_pending(channel: IpccChannel) -> bool {
2023-05-26 10:56:55 +02:00
!Self::c1_is_active_flag(channel) && Self::c1_get_tx_channel(channel)
2023-04-27 17:03:22 +02:00
}
2023-05-15 11:25:02 +02:00
2023-05-27 22:05:07 +02:00
pub fn is_rx_pending(channel: IpccChannel) -> bool {
2023-05-26 10:56:55 +02:00
Self::c2_is_active_flag(channel) && Self::c1_get_rx_channel(channel)
2023-05-15 11:25:02 +02:00
}
2023-04-27 17:03:22 +02:00
}
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)) }
}
}
unsafe fn _configure_pwr() {
let rcc = crate::pac::RCC;
// set RF wake-up clock = LSE
rcc.csr().modify(|w| w.set_rfwkpsel(0b01));
}