ttlappalainen / NMEA2000

NMEA2000 library for Arduino
508 stars 211 forks source link

Support for Raspberry Pi Pico (CANPico) #363

Open robofwy opened 7 months ago

robofwy commented 7 months ago

Thank you for your great NMEA2000 library.

I managed to get this working well on a Raspberry Pi Pico with the CANPico carrier board from Canis Labs (from SK Pang). The port to the Canis Labs SDK was relatively simple.

Basically, I created a class tNMEA2000_pico and implemented the CANOpen, CANSendFrame and CANGetFrame functions to make appropriate calls to the API provided by Canis Labs.

I am happy to provide my code if that is useful for anyone else.

One question: what is the purpose of wait_sent in CANSendFrame? I can see in some hardware implementations, an immediate send is used if this is false and the priority is less than or equal to 2.

The API from Canis Labs implements a send FIFO and priority queue. I have my test code working either by just using the FIFO queue or by using the priority queue if wait_sent is false and prio <= 2 (as per NMEA2000_teensy although this implementation calls the wait_sent parameter "fastpacket").

ttlappalainen commented 7 months ago

wait_send is a lot wrong naming, but I have not fixed it - may I should. It actually means that frame is fastpacket and should be take care it will be sent in order. So proper name would be e.g., fastpacket_frame - on NMEA2000_Teensy it is named fastpacket. Naming error has been cause because of incomplete knowledge at the beginning.

Depending of CAN controllers there may be several internal mailboxes, which may have different priorities. FlexCAN (Teensy) has very good controller and can have own mailbox for every priority (0-7). Then it is simpliest just write each priority to specific mailbox. In this way controller can then send higher priority frame before lower priority even it has been queued earlier.

On NMEA2000_Teensy you can see that I use 3 mailboxes for sending. From mailbox logic you can see that fast packet frames and frames with priority>2 will be sent by using 2 lower priority mailboxes. NMEA2000_Teensyx works with all Teensies and there you can see that 8 mailboxes will be used for sending. I have simulated bus traffic with my NMEA Simulator and NMEA2000_Teensyx seem to be more reliable than NMEA2000_Teensy for Teensy 3.x. On my simulation I fill bus with about 1500 frames/second and can still handle all frames.

For NMEA 2000 CAN "drivers" it is important that fast packet frames will be sent in order. If CAN controlle has only one output FIFO or mailbox, sending is simple. But if there is more, then one must take care that same fastpacket frames will use same mailbox. Often this is not the case in CAN libraries. They often offer just way to write frame to library, and then library writes it to next free mailbox and THAT DOES NOT WORK with NMEA2000 fastpacket. So think carefully.

If you want to test your driver and you happen to have Teensy 3.2 or higher, I am interested to arrange remote session for testing. For testing you need to have example ActisenseListenerSender running. For Teensy, I'll provide you code for NMEA Simulator.

oxbown commented 6 months ago

Another project of CANBus protocol on RP2040 processor (Pi Pico) https://github.com/KevinOConnor/can2040/tree/master and the arduino version https://github.com/obdevel/ACAN2040/tree/main

nikokb commented 5 days ago

@robofwy I'd love to see your implementation if you're up for sharing!