can initialization process doesn't work on stm32f4
xoviat opened this issue · comments
This does seem to work (though I haven't yet sent a message):
dp.RCC.apb2enr.write(|w| w.syscfgen().enabled());
let gpioa = dp.GPIOA.split();
let gpiob = dp.GPIOB.split();
let gpioc = dp.GPIOC.split();
let mut rcc = dp.RCC.constrain();
let clocks = rcc
.cfgr
.use_hse(16.mhz())
.sysclk(48.mhz())
.pclk1(24.mhz())
.freeze();
let mut delay = Delay::new(cp.SYST, clocks);
CAN1::enable(&mut rcc.apb1);
dp.CAN1.mcr.modify(|_, w| w.sleep().clear_bit());
let mut waiting = true;
while waiting {
let msr = dp.CAN1.msr.read();
if msr.slak().bit_is_set() {
waiting = false;
}
}
dp.CAN1.mcr.modify(|_, w| w.dbf().clear_bit());
let r_mcr = dp.CAN1.mcr.read().bits();
let r_msr = dp.CAN1.msr.read().bits();
let r_tsr = dp.CAN1.tsr.read().bits();
/* request initializiation */
dp.CAN1.mcr.modify(|_, w| w.inrq().set_bit());
let mut waiting = true;
while waiting {
let msr = dp.CAN1.msr.read();
if msr.inak().bit_is_set() {
waiting = false;
}
}
dp.CAN1.btr.modify(|_, w| unsafe { w.bits(0x001c_0003) });
compare to the initialization process in this pacakge
can.mcr
.modify(|_, w| w.sleep().clear_bit().inrq().set_bit());
while can.msr.read().inak().bit_is_clear() {}
can.mcr
.modify(|_, w| w.sleep().set_bit().inrq().clear_bit());
while can.msr.read().slak().bit_is_clear() {}
let msr = can.msr.read();
while !msr.slak().bit_is_set() {
can.mcr
.modify(|_, w| w.abom().set_bit().sleep().clear_bit());
}
I'm not sure why it's currently done this way, but the slak()
bit is not set.
see https://gist.github.com/xoviat/63f973ae8d19b8ee8563bc0515afb616 for the cubeide driver
Relevant parts from the Reference Manual:
If software requests entry to initialization mode by setting the INRQ bit while bxCAN is in Sleep mode, it must also clear the SLEEP bit
bxcan
code is doing excactly that
After the SLEEP bit has been cleared, Sleep mode is exited once bxCAN has synchronized with the CAN bus, refer to Figure 336. The Sleep mode is exited once the SLAK bit has been cleared by hardware.
We are not waiting for SLAK to be clear, which appears to be the root cause.
As why this works on stm32f1xx and not on stm32f4xx I can only guess: stm32f1xx probably was running at a slow enough clock for the flag to be cleared in time
note: this may still be needed, but I misunderstood the issue. keep this open for a bit.