CAN Peripheral For RP2040, Courtesy Of PIO

Part of a picture showing all kinds of different CAN devices in a car

[Kevin O’Connor] writes to us about his project, can2040adding CAN support to the RP2040. The RP2040 doesn’t have a CAN peripheral, but [Kevin] wrote code for the RP2040’s PIO engine that can receive and send CAN packets. Now we can all benefit from his work by using this openly available CAN driver. This library is written in C, so it’s a good fit for the lower-level hackers among us, and in all likelihood, it wouldn’t be hard to make a MicroPython wrapper around it.

The CAN bus needs a peripheral for the messages to be handled properly, and people have been using external chips for this purpose until now. These chips, [Kevin] tells us, have lately been unavailable due to the chip shortage, making this project more valuable. The documentation is extensive and accessible, and [Kevin] details how to best use this driver. With such a tool in hand, you can now turn your Pico into a CAN tinkering toolkit, or wire up some CAN devices for use in your own projects!

[Kevin] says this code is already being used in Klipper, a framework powering 3D printers and other machines like them. As for your own purposes, you can absolutely use such a CAN tool to hack on your car – here’s a treasure trove of car hacking documentation, by the way! Thanks to the PIO engine, there seems to be no end to the RP2040’s versatility – you can even drive HDMI monitor with this PIO-based DVI code.

Title picture by Florent.david.lille1, CC BY-SA 3.0

30 thoughts on “CAN Peripheral For RP2040, Courtesy Of PIO

    1. Often your diagnostic CAN is split from the sensor CAN. You can filter codes, and it might put the dashboard light out, but it won’t stop the ECU failing emissions tests with a code present.

      1. Having previously executed a man in the middle attack against (my own) CANbus, for non-emissions related reasons, and speaking purely hypothetically, you absolutely could do it.

        It would be more complicated than just filtering out the DTCs. You’d have to spoof some static messages, and depending on what was going on with the car and which testing protocol was being used potentially change some values on the fly to keep them inside spec, but it’s entirely doable. (But don’t, we’re messing up the environment enough without intentionally putting over polluting vehicles on the road

    2. Awesomeness! I can put my mcp2515s down and go direct.

      Does anyone know if the USB 1.1 has enough BW to make this into a sub $10 usb to canbus cable? with either slcan or gs_usb

      1. Depends. USB 1.0 Full speed is 8 Mb/s, classic CAN goes up to 1 Mb/s and CAN-FD up to 5 Mb/s. However USB1.0 Low Speed only has 150 kb/s. How much bandwidth your micro controller really reaches is of cause a question.

        1. fantastic work Kevin. i’ve been advocating CAN bus for years but had essentially given up because of the lack of adoption in the low end robotic and maker space. i was hoping someone would do what you’ve done w/ the pio but knew it was beyond my pio coding skill. Greatly appreciated. i just got my first pico-W for a quad drone project. I willl absolutely be reserving a core for a CAN bus stack using pio.

      2. In the real world I would think so, as even very slow USB speeds are likely to keep up well enough with a bit of memory buffer available – I’m not a huge expert but I highly doubt the CAN bus is saturated often if ever in a production system.

  1. I just want to know if it will let me use the sweet old school radios from my first gen new Mini (BMW). They lock up until they see a valid i-Bus message, even something simple like turn on the inside lights. Even better if I can add some remote buttons :D

  2. How difficult would it be to spell out, define, acronyms used the first time in articles? In this case it seems obvious that the “C” in “CAN” must stand for “car,” but the “AN”? – kind’a makes the rest of the article less informative

    1. CAN = Controller Area Network. Made popular by cars but also used in marine, robotics, industrial, etc.

      HaD could use a hotlink or brief definition system, wonder how something like wikipedias hover summary work might even work. Maybe that could be done with more explicit tags?

    2. You’d think the “C” stands for Car, but it doesn’t. It stands for Controller Area Network. In the most basic sense, it allows every system to communicate with each other without a middle man, aka host computer. That’s severely oversimplifying it, but still.

    3. What actually would be useful is if authors would link basic acronyms like to their wikipedia page, or even just a simple lexicon: But I fear it would be a mess, authors here every so often fail at properly fact- and typo- check their articles.

    4. You will get this problem with most publications, there is always a degree of assumed knowledge.

      I’ve got a textbook on helicopter aerodynamics for instance that just assumes you will know exactly what each symbol they use means, no common language description or glossary of terms at all (as far as I can recall anyway), which I didn’t – as while symbols and equations do have a large degree of standardization in mathematics and science these days its not entirely universal.

      I don’t see this as a problem however as if you can’t in context figure out what they mean, or a search term to make your knowledge match the writers assumptions the content isn’t for you anyway – read the dumbed down pop-sci magazine/website version that is and will go to great lengths to keep things simple for you…

      Not that I’m opposed to an index of terms and hover text as Kurt suggests – making references you don’t already know easier is a good thing – going to be far from trivial though, as the number of acronyms that will be overloaded with multiple meanings that might come up in a HAD article has to be huge..

    1. You could even hack your current guages to display properly! Most temperature ‘guages’ stay in the middle until the car has properly overheated. I get why they do it, to reduce customer call ins, but we could fix it.

  3. To connect a Raspberry Pi Pico to CAN bus there’s always the CANPico board, which has an MCP2518FD CAN controller and FD transceivers on board (way better than the old MCP2515) plus a MicroPython CAN API. There’s also support for sending data to and from a host via USB serial (the firmware has a second virtual USB serial port for this). And baked into the MicroPython firmware is the CANHack toolkit that can mount a bunch of low-level CAN protocol attacks.

    More on the CANPico here: https://kentindell.github.io/canpico

    The CANHack toolkit: https://github.com/kentindell/canhack

  4. Excellent find, I was hoping someone would figure out how to get the PIO to implement the CAN protocol on the pico. The ESP32 has a CAN driver, but thats overkill for what I wanted to monitor a boat engine and feed the N2K instruments. Looking to finish a Pico interface for the excellent ttlappalainen N2K libraries.

  5. I really like this code. How you use instr_mem to modifiy program instructions on the fly regarding current state is very elegant. Protocol implementation is generally straight forward. Sometime, like here, it can be artistic. Good work man!

  6. Arya Voronova needs to correct their details. Apparently Arsenijs Picugins is the ‘author’ of this piece. That’s who the ‘by’ link goes to, and also in the RSS feed tags. Good article tho!

Leave a Reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.