KevinOConnor / can2040

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

Transmit Queue Hangs if no ACK Detected #53

Closed wrongbaud closed 2 months ago

wrongbaud commented 5 months ago

Hi All,

I am looking for some insight or guidance on an issue I am running into with the can2040 libraries.

I have noticed that when I attempt to transmit a message, if the ACK is not detected, the RP2040 becomes unresponsive and needs a reset. It is entirely possible that I am using the library incorrectly, my code can be found below:

My code can be seen below:

#include <stdio.h>
#include <stdint.h>
#include "pico/stdlib.h"
#include "pico/binary_info.h"
#include "hardware/irq.h"
#include "can2040.h"
#include "RP2040.h"

static struct can2040 cbus;

static void can2040_cb(struct can2040 *cd, uint32_t notify, struct can2040_msg *msg)
{
    // Add message processing code here...
    return;
}

static void PIOx_IRQHandler(void)
{
    can2040_pio_irq_handler(&cbus);
}

void canbus_setup(void)
{
    uint32_t pio_num = 0;
    uint32_t sys_clock = 125000000, bitrate = 500000;
    uint32_t gpio_rx = 5, gpio_tx = 4;

    // Setup canbus
    can2040_setup(&cbus, pio_num);
    can2040_callback_config(&cbus, can2040_cb);

    // Enable irqs
    irq_set_exclusive_handler(PIO0_IRQ_0_IRQn, PIOx_IRQHandler);
    NVIC_SetPriority(PIO0_IRQ_0_IRQn, 1);
    NVIC_EnableIRQ(PIO0_IRQ_0_IRQn);

    // Start canbus
    can2040_start(&cbus, sys_clock, bitrate, gpio_rx, gpio_tx);
}

int main(void){
        stdio_init_all();
        canbus_setup();
        struct can2040_msg test_msg = {0x123,8,{1,2,3,4,5,6,7,8} };
        can2040_transmit(&cbus,&test_msg);
        can2040_transmit(&cbus,&test_msg);
}

When I run the above code, I only see one attempt at transmitting the test message.

My test setup is as follows:

I have tried both with a 120 ohm termination resistor and without.

Here is a Saleae screenshot of the ACK not being received. For my application, the RP2040 is the first active node on the bus so I expect it to not receive some ACK bits while the system is still powering up.

can-prob

I've tried analyzing this behavior with multiple adapters, and have only ever seen one message transmitted.

Is there a way to tell the Pico to ignore the ACK bit? Is there something blatantly wrong with my setup?

KevinOConnor commented 5 months ago

The screenshot you provided does seem to indicate the message was successfully transmitted. (The received zero bit, that was not transmitted, after the crc information, is what an ack looks like.) So, I'm not sure what you are reporting.

Make sure you are on the latest version of the can2040 code (as there were fixes in this area in earlier versions).

You could try sending several messages with different content. You could also try disconnecting all other nodes on the CANbus to verify the can2040 node continuously transmits when no other nodes are present.

You may also want to try with known working software (Klipper and linux can-utils): https://github.com/KevinOConnor/can2040/blob/master/docs/Tools.md#klipper

-Kevin

wrongbaud commented 5 months ago

Thanks for the reply!

I also noticed that the ACK was being transmitted, but I can't figure out why when using the code above, there is only one message being transmitted.

I've tried several messages with different content, and have seen the same behavior.

The behavior remains the same regardless of what nodes are on the network.

Is there something that I am supposed to be doing in the callback after transmitting?

github-actions[bot] commented 3 months ago

Hello,

It looks like there hasn't been any recent updates on this github ticket. We prefer to only list tickets as "open" if they are actively being worked on. Feel free to provide an update on this ticket. Otherwise the ticket will be automatically closed in a few days.

Best regards,

~ Your friendly GitIssueBot

PS: I'm just an automated script, not a human being.