stm32_hal2/can/
g4.rs

1use fdcan;
2
3#[cfg(not(feature = "g431"))]
4use crate::pac::{FDCAN2, FDCAN3};
5use crate::{
6    pac::{FDCAN1, RCC},
7    util::rcc_en_reset,
8};
9
10const MESSAGE_RAM_BASE_ADDRESS: u32 = 0x4000_a400;
11
12// The RM is a bit contradictory. Table 3 implies that each FDCAN memory block is 0x400 in size.
13// But section 44.3.3 says each block is 0x350 and that is what actually works.
14const MESSAGE_RAM_SIZE: u32 = 0x350;
15
16const FDCAN1_MESSAGE_RAM_ADDRESS: u32 = MESSAGE_RAM_BASE_ADDRESS;
17const FDCAN2_MESSAGE_RAM_ADDRESS: u32 = FDCAN1_MESSAGE_RAM_ADDRESS + MESSAGE_RAM_SIZE;
18const FDCAN3_MESSAGE_RAM_ADDRESS: u32 = FDCAN2_MESSAGE_RAM_ADDRESS + MESSAGE_RAM_SIZE;
19
20macro_rules! create_cans {
21    ($can:ident, $fdcan:ident, $msg_ram_address:ident ) => {
22        /// Interface to the CAN peripheral.
23        pub struct $can {
24            pub regs: $fdcan,
25        }
26        impl $can {
27            /// Initialize a CAN peripheral, including  enabling and resetting
28            /// its RCC peripheral clock. This is not handled by the `bxcan` or `canfd` crates.
29            pub fn new(regs: $fdcan) -> Self {
30                let rcc = unsafe { &*RCC::ptr() };
31
32                rcc_en_reset!(apb1, fdcan, rcc);
33
34                Self { regs }
35            }
36
37            /// Print the (raw) contents of the status register.
38            pub fn read_status(&self) -> u32 {
39                unsafe { self.regs.psr().read().bits() }
40            }
41        }
42        unsafe impl fdcan::Instance for $can {
43            const REGISTERS: *mut fdcan::RegisterBlock = $fdcan::ptr() as *mut _;
44        }
45
46        unsafe impl fdcan::message_ram::Instance for $can {
47            const MSG_RAM: *mut fdcan::message_ram::RegisterBlock = ($msg_ram_address as *mut _);
48        }
49    };
50}
51
52create_cans!(Can, FDCAN1, FDCAN1_MESSAGE_RAM_ADDRESS);
53#[cfg(not(feature = "g431"))]
54create_cans!(Can2, FDCAN2, FDCAN2_MESSAGE_RAM_ADDRESS);
55#[cfg(not(feature = "g431"))]
56create_cans!(Can3, FDCAN3, FDCAN3_MESSAGE_RAM_ADDRESS);