Teensy 3.1 and CAN Bus

You can build a full-featured FlexCAN driver by creating a project with Freescale's Processor Expert software...

Thank you for the feedback! I have been referring to the Freescale files. In this case the target is a bit different, being intended as a (hopefully) simple API Arduino-friendly library.
 
Great going, teachop!

BTW: I'm not sure if this is helpful to you, Paul, or anyone in this thread, but have you checked out the GEVCU.org project?

http://gevcu.org/

The purpose of the project is to create a control unit for DIY electric car conversions, namely so they could talk over CAN with the DMOC controller which drives the Siemens AC motors. You can actually buy one at EVTV.me, but everything is there on the site to both build your own, including the software to run it as everything is open source.

They have succesfully got CAN working (supporting two different CAN transcivers, to boot) on the Cortex-M3, and the libraries they have developed are apparently fully loaded (masks, filters, extended frames, multi-speed, etc.). If you check the hardware tab, their initial prototypes used an Actual DUE connected to the main board, but the latest version is a custom all-in-one board incorproating the ATSAM3X8EA-AU. I must admit I'm quickly out of my depths both CAN and hardware related so not sure how that compares to the M4 used in the Teensy 3.1.

Also, if you check their schematic of this board, I really like their choice of transceiver, TI's ISO1050DW, as it provides full isolation from any nasty spikes or faults that may happen on the CAN bus, protecting Teensy and anything else hanging off of it.

http://www.ti.com/lit/ds/symlink/iso1050.pdf

One more: check out their nicely filtered and isolated 3.3V power supply on the schematic, too, as well as the fully isolated I/O. This thing was built in-car-tough.

Anyway, great work so far, and I hope that helps!
 
Here is the CAN library for the Due that forms the basis for the GEVCU CAN controlling.
Thanks North_Van for all the great feedback and information. That driver is one that I did look at briefly when skimming CAN code on github. I will look at this in more detail. Good stuff. Maybe I need to plan for two versions of the driver, one with this type of powerful interface.

My idea was an API simple, easy and Arduino-like (begin, send, recv). If makers need to tie together distributed systems, say in a robot or whatever, CAN could be easier than roll-your-own protocol with Serial or I2C or SPI libraries. The Teensy being teensy, it fits well with distributed smart I/O schemes. CAN is not much used by us hobby types. The smarts in a CAN peripheral like framing and CRC, retries, acking, bit stuffing, the noise margin, the built in arbitration (like I2C), two wires, inexpensive tranceivers (unfortunately the 3V stuff is pretty much all SMT) make it a great backbone for simple distributed smart I/O systems. I wanted to go for Keep It Simple and make it easy.
 
The FlexCAN_Library driver now has transmit and receive buffering courtesy of branduino. There is still more to do. Please try it out and give feedback if you CAN!
https://github.com/teachop/FlexCAN_Library

Nice job! Did a quick test and it seems to be working fine in both directions at 1Mbps.

Two suggestions to the API:
1) specify the speed of the CAN bus in the begin() method rather than in the constructor. You may even pre-create the FlexCAN object (as there won't be more than one) similarly to the Serial interfaces.
2) I could not find any Arduino recommendations for type names, but I believe the convention is to end it with "_t", so CAN_message_t or canMessage_t or can_message_t. This is a minor thing, but maybe someone can comment on what is the official Arduino recommendation here?

P.S. You may want to add the new available() method to both the keywords file and readme
 
Thanks for the testing pawelsky! And thanks to branduino for the helpful work.

pawelsky, the item 2 and PS changes are being made now. The item 1 changes I am still pondering. For item 2, people are using the library so it will be an additional typedef in the header allowing the old type to still live. I will update the driver and example code to prefer the _t name.

I am planning to add an optional parameter when the object is constructed that will enable blocking if not defaulted. When given, the read() and write() will spin on yield() instead of returning 0. This was the idea of the timeout field in CAN_message/CAN_message_t. It is most important on the write() side. If the parameter isn't given the interface will not be changed, so hopefully nobody will break when they update.
 
For item 2, people are using the library so it will be an additional typedef in the header allowing the old type to still live.

This is an easy search&replace change for everyone using the library (compiler will complain so it won't be missed) so I don't think it makes much sense to keep 2 typedefs while it still is not widely used. Just my opinion.
 
Thanks guys. I am part of OpenLCB dev team, so am very interested in CAN on Teensy, will ramp this up, now.
 
We need to maintain message ordering. I do not think the FIFO maintains this, since it will fill the first free buffer (ie, it's not really a FIFO). However, I can just reduce to using one receive buffer. We use specific calls for blocking and non-blocking, but I will just adapt the library. Thanks for doing this ... I had made a start, but had not finished it.
 
We need to maintain message ordering
Yes. The TX isn't guaranteed to be in-order. My intention had been to implement an optional parameter for TX calls where a single buffer with blocking could be specified. This would guarantee in-order transmission since most fragmentation protocols will break if they are out of order.

This concept isn't implemented yet (somebody else helped out with buffering before I got there which was appreciated) but it can be added in a compatible manner by reserving one tx buffer for this, using blocking (under way), and making sure the optional parameter defaults to the existing behavior. Would this satisfy your requirements?

I have also been pondering implementing a fragmentation protocol that doesn't die when the frames are out of order. Some day. Maybe...
 
Yes, will do as I have time. We do use fragmentation and protocols which are order sensitive, see below for a brief description. We have been somewhat disappointed in the CAN controllers, and have have had to reduce to one or two buffers so that we can control ordering. We generally use a control loop, so none blocking calls is generally preferred so as to not shut down concurrent UI or other processing.

Model trains contain microprocessors that are addressed and communicate bidirectionally to control train speed, acceleration, direction, lighting and sound. In addition, axcillary off-the-rail items, such as turnout control, signals, visual and audio animations, and ambient lighting and sound all require control. Our layouts can get large, see: http://www.miniatur-wunderland.com/uploads/media/guide-english_01.pdf and http://it.wikipedia.org/wiki/File:FREMO-ses-e25318.jpg OpenLCB is a public project to develop a general and flexible local control bus for small to large layouts, including such as these. OpenLCB is a set of general messaging protocols, which were designed so that they can be implemented/adapted to CAN. The base ones include: Events with 64-bit event#s, Datagrams with up the 72-byte of data, and Streams with unlimited length data. Streams involve fragmentation on all transports, and datagrams on CAN. In addition, we have other basic messages to handle node discovery and validation, event discovery, and bus management. Additional protocols are built onto this base, and are typically application specific, in this case model railroads. The system is built to be layered, transport-agnositic, extendible, robust, and to include gateways between segments with interest based routing. CAN is very useful for us since we operate in a noisy environment and need a reliable last-mile bus, but we are also targeting serial buses, such as Ethernet, RS485, RF, etc.
 
We do use fragmentation and protocols which are order sensitive, see below for a brief description.
Wow! Nice! In my "day job" I deal with the in-order and non-blocking aspects as well. But it isn't in a transport-agnostic way. For example, some of my stuff is on CANopen, and I pre-allocate TX buffers based on the function code. Network management messages have their own buffers for example, and don't have an in-order requirement. SDO, which is the fragmentation protocol there, uses a single buffer for TX and stays in order. And yes the CAN cannot block the control loop. The other biggest portion of my CAN stuff run automotive diagnostic protocols, now mostly standardized by the emissions testing laws. Also here there is a fragmentation protocol that requires in-order RX and TX.

I was thinking there was a "simple" segment for getting hobby electronics onto CAN but your use is beyond what I ever imagined! One way to handle in-order and multiple buffers is IRQ message rolling FIFOs (both ways) instead of in the chip. And you are right for as powerful as the CAN interfaces tend to be, it is frustrating to find there is no support for in-order buffering (often). I did push the optional blocking stuff thinking it will help casual use. First time I ever put blocking in a CAN driver! If you don't set the timeout field non-zero it doesn't do anything. (I do normally have the timeout field, but it is used by the driver itself to snuff stale messages that never got onto the bus)

Thanks so much for taking the time to explain your requirements, really a big help - probably I am shooting at the wrong target? Still want it to be simple for hobby use as CAN is indeed awesome (but some days I used to want to go back and talk to Bosch about the whole 8 byte thing). ...I have some pondering to do...
 
Hey, you are defining the lowest level stuff, and tat is very helpful. Most people will just want to get two nodes talking, so much easier requirement. FIFOs etc can be added above this layer.

BTW, we have not found hardware filtering to be very useful, but might be more useful in some applications.
 
we have not found hardware filtering to be very useful
Ok. As you say filtering depends on the application. It can be helpful in two ways 1) keep unrelated traffic from eating up CPU cycles, and 2) pre-route rx frames into your application buffers (some parts support this).
 
Yes, agreed. In our case, our use of the CAN header is such that filters are not that helpful. But you and I agree that it usefulness is very dependant on the application, so being able to set filters is useful in the API.
 
Hi

I have used the FlexCAN in the Kinetis; is is essentially the same as the FlexCAN in the Freescale Coldfires.
My own driver for it is described here: http://www.utasker.com/docs/uTasker/uTaskerCAN.PDF and there is also a video of it in use on a Kinetis at https://www.youtube.com/watch?v=Ha8cv_XEvco

I never tried it on the Teensy 3.1 (it needs a CAN transceiver to be hooked up to it and other CAN nodes oin the network to be able to operate) but have simulated it on the Teensy (similar to the simulation technique in the video). Presently I am considering adding a CANopen layer but haven't experienced a very big demand for CAN itself...

Regards

Mark

@techop - I think that the FlexCAN buffers send only on a priority basis (ID defines priority). I recently used the bxCAN in the ST-Micro STM32 and it does have a mode that can be set to control "in-order" transmission.
 
Back
Top