KevinOConnor / can2040

Software CAN bus implementation for rp2040 micro-controllers
GNU General Public License v3.0
667 stars 66 forks source link

Suspicious Timing Inconsistencies in CAN2040 PIO Signal Capture #46

Closed lamuguo closed 1 year ago

lamuguo commented 1 year ago

2023-08-18-213707_216x301_scrot_360 pio.log

I have already adjusted the CAN rate to 10 kHz, low enough for debugging. The PIO should be capturing a signal every 100 µs, and then the can2040 processes 10 of these signals. So, the time difference I'm logging should be around 1 ms. While most of the logs are accurate, sometimes there's a bump, like the case of 6501 => 9307 you can see.

The code is available here: https://github.com/lamuguo/pico-examples/tree/debug-can2040, and the main program is: https://github.com/lamuguo/pico-examples/blob/debug-can2040/pio/can2040/can_main.c. It is a can2040 hello world. I guess I miss something to enable can2040 PIO to get the correct clock. Any hints?

btw, I can use my simple_gpio (https://github.com/lamuguo/pico-examples/blob/debug-can2040/pio/simple_can/simple_gpio.c) and simple_can (https://github.com/lamuguo/pico-examples/blob/debug-can2040/pio/simple_can/simple_can.c) to get the correct result.

And the message on the bus for debugging is "322#DEADBEAF", sent by cansend: $ cansend can0 B22#DEADBEAF

2023-08-18-221126_1452x242_scrot

lamuguo commented 1 year ago

It seems that my previous understanding of the can2040 might have been incorrect. After revisiting the code, it appears that the sync state machine adjusts the start time for reading, specifically by delaying the initiation of rx through irq. This could lead to variations in the start time between successive reads. Below is a log that should provide a clearer picture.

2023-08-20-123436_228x444_scrot

I haven't managed to parse the message correctly yet, but this could be because it's not correctly parsing the message start. I'll take a closer look at the state transitions of the data_state. It's probably not an issue with the can2040 itself. I'll go ahead and close this issue for now.

KevinOConnor commented 1 year ago

FYI, there's some info on the state machines at https://github.com/KevinOConnor/can2040/blob/master/docs/Code_Overview.md . The rx fifo signals are purposely disabled during idle (all high bits) to reduce load on the ARM core. Also, the bit sampling needs to be synchronized to each transmission, so one should not expect that each message will start at any particular time relative to the bit timing of the last received message.

Cheers, -Kevin