Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

STM32F412 CAN Bus drops frames #3610

Open
ProjectRobal opened this issue Dec 4, 2024 · 0 comments
Open

STM32F412 CAN Bus drops frames #3610

ProjectRobal opened this issue Dec 4, 2024 · 0 comments

Comments

@ProjectRobal
Copy link

ProjectRobal commented Dec 4, 2024

Hello I have a program for STM32F412 written using Embassy Rust. I have a code which takes data and split it into chunks and then sent it through CAN. Problem is when I comment lines with debug messages some frames are dropped.

My clocks configuration:

    let mut config = Config::default();

    config.rcc.hse = Some(Hse{
        freq: Hertz(25_000_000),
        mode: HseMode::Oscillator
    });

    config.rcc.hsi = false;

    config.rcc.pll_src = PllSource::HSE;

    config.rcc.sys = Sysclk::PLL1_P;

    config.rcc.pll = Some(Pll{
        prediv:PllPreDiv::DIV25,
        mul:PllMul::MUL400,
        divp:Some(PllPDiv::DIV4),
        divr:Some(PllRDiv::DIV2),
        divq:Some(PllQDiv::DIV2)
    });

    config.rcc.ahb_pre = AHBPrescaler::DIV1;

    config.rcc.apb1_pre = APBPrescaler::DIV2;

    config.rcc.apb2_pre = APBPrescaler::DIV2;

    let p = embassy_stm32::init(config);

Can initialization:

let mut can = Can::new(p.CAN1, p.PB8, p.PB9, Irqs);

    // accept only id from main board ( with Raspberry Pi ).
    // let's make it that every device will have two addresses, one for sending data and second for reciving data
    // In that case:
    // Vel Saltis recive id: 1
    // Vel Saltis send id: 2
    can.modify_filters().enable_bank(1, Fifo::Fifo0, Mask32::frames_with_std_id(StandardId::new(1).unwrap(),StandardId::new(0x7FF).unwrap()));

    can.set_automatic_wakeup(false);

    can.modify_config()
        .set_loopback(false) // Receive own frames
        .set_silent(false)
        .set_automatic_retransmit(true)
        .set_bitrate(500_000);

let can_txrx: (embassy_stm32::can::CanTx<'_>, embassy_stm32::can::CanRx<'_>) = can.split();

unsafe
    {
        let buf_tx = can_txrx.0.buffered(&mut CAN_TX_BUFFER);

        let buf_rx = can_txrx.1.buffered(&mut CAN_RX_BUFFER);

        let espace:Espace<'static,CAN_BUFFER_SIZE> = Espace::new(buf_rx);

        let scenic:Scenic<'static,CAN_BUFFER_SIZE> = Scenic::new(buf_tx);

        info!("Starting Scenic task!");
        _spawner.spawn(scenic_task(scenic)).unwrap();


        info!("Starting Espace task!");
        _spawner.spawn(espace_task(espace)).unwrap();
    }

    can.enable().await;

Function in which frames are sent:

pub struct CanFrame
{
    pub data:[u8;96],
    pub size:u8,
    pub id:u8,
    pub target_id:u16,
}

impl CanFrame {
    pub fn new(id:u8,size:u8) -> Self
    {
        CanFrame{
            id,
            size,
            data:[0;96],
            target_id:2
        }
    }
}

pub static SCENIC_TRUNK:Channel<ThreadModeRawMutex,CanFrame,100> = Channel::new();


/// a task for reading data from CAN
pub struct Scenic<'a,const SIZE:usize>
{
    can:BufferedCanTx<'a,SIZE>
}

impl<'a,const SIZE:usize> Scenic<'a,SIZE> {
    pub fn new(can:BufferedCanTx<'a,SIZE>) ->Self
    {
        
        Scenic{
            can
        }
    }

    // recive task
    pub async fn run(&mut self)
    {
        // wait for incoming frame
        let frame = SCENIC_TRUNK.receive().await;

        if frame.size == 0
        {
            return ;
        }

        let data = &frame.data[..(frame.size) as usize];
        let id = frame.id;

        let mut offset:u16 = 0;

        info!("Scenic id: {}",id);
        info!("Scenic size: {}",frame.size);

        for chunk in data.chunks(5)
        {
            let mut msg:[u8;8]=[0;8];
            
            msg[0] = id;

            // msg[1] = ( offset>>8 & 0xFF ) as u8;
            // msg[2] = ( offset & 0xFF ) as u8;

            msg[1..3].clone_from_slice(&offset.to_le_bytes());

            msg[3..(3+chunk.len())].clone_from_slice(chunk);

            let frame = Frame::new_data(unwrap!(StandardId::new(frame.target_id)), &msg[..(3+chunk.len())]).unwrap();

            info!("Scenic offset: {} id: {}",offset,id);
            
            self.can.write(&frame).await;

            offset += chunk.len() as u16;
        }
    }

}

My project toml file:

[package]
edition = "2024"
name = "kapibara_vel_saltis"
version = "0.1.0"
license = "MIT OR Apache-2.0"

[dependencies]
# Change stm32f429zi to your chip name, if necessary.
embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32f412re", "unstable-pac", "time-driver-tim2", "exti", "chrono","time" ]  }
embassy-sync = { version = "0.6.0", path = "../../embassy-sync", features = ["defmt"] }
embassy-executor = { version = "0.6.3", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] }
embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-1_000_000"] }
embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }

defmt = "0.3"
defmt-rtt = "0.4"

cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
cortex-m-rt = "0.7.0"
embedded-hal = "0.2.6"
embedded-io = { version = "0.6.0" }
embedded-io-async = { version = "0.6.1" }
panic-probe = { version = "0.3", features = ["print-defmt"] }
futures-util = { version = "0.3.30", default-features = false }
heapless = { version = "0.8", default-features = false }
nb = "1.0.0"
embedded-storage = "0.3.1"
micromath = "=1.0.0"
usbd-hid = "0.7.0"
static_cell = "2"
chrono = { version = "^0.4", default-features = false}

crc = "3.0.1"
mpu6050 = { path = "./src/libs/mpu6050" }
hmc5983 = { path = "./src/libs/hmc5983"}
qmc5883l = { path = "./src/libs/qmc5883l" }
vl53l0x = { path = "./src/libs/vl53l0x" }
as5600 = { path = "./src/libs/as5600" }
madgwick = "0.1.1"
libm = "0.2.8"
embedded-hal-async = "1.0.0"

[profile.release]
debug = 2

I don't know if it is a bug or I am doing something wrong.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant