Building a CAN API for Arduino DUE

Hello Rob and thank you for your encouraging words!

I checked the electric schematic of the SN65HVD230 based board you mentioned. It can work with the CAN library but in a direct mode. I mean, pin 8 (Rs) is been underused and fixed to ground (high-speed mode). The CAN library contains the SN65HVD234 component data conforming to Arduino API that will be sub-utilized too (I think you don't want to port the manufacture ones).

I would recommend it only for tests purposes, but for your application, you will surely want to migrate to 234 to take advantage of the Due libraries for ultra-low current sleep mode. Additionally, the missing filter and buffer capacitors should be needed if distance between Due and CAN device increases.

In case you decide to get it, I would also recommend to get two for loop tests of the CAN controllers. Notice that the manufacturer's (Wave Share) price differs considerably from the vendor's (DX) (Russian?). By the way, I don't see the 120 ohm terminal resistor in the photos. Only the 10K, I think. Regards!

Here the schematic of the SN65HVD230 based board you mentioned.


the 120k resistor is positioned to the left hand side of the end of bus jumper pins (between the CANL & CANH markings on the Waveshare board).

Thanks very much for your points regarding ultra-low sleep current mode, and the filter & buffer capacitors, i'll defiantly keep it in mind and can see the advantages of the 234 over the 230.

With regards to "pin 8 (Rs) is been underused and fixed to ground (high-speed mode)", looking at the datasheet for the 230 (link below), I don't think that this module / interface board is actually set for full high speed mode, as it has a 10k resistor before the ground connection, and reading the datasheet, this seems to imply that it is actually set up in slope control mode (pg 20 of datasheet) as ~ 15V/usec, does this not imply that it is actually not in full high speed mode? But I may have misunderstood the datasheet (is slew rate not related to the bus frequency?)

Many thanks again,

regards Rob

Rob, You are right. Sorry for overlooking the 120 resistor and the slope mode. According to the specs, the high-speed mode of operation is selected by connecting pin 8 to ground or lowering of V(Rs) to 0.0v < 1.0v (p.2,3). So, no high-speed. I believe the manufacturer sets the board to 'slope' as a typical mode that helps to improve EMC behavior (spikes, harmonics) in case we use an unshielded bus cable in order to save some money, but, the trade-off is a loop propagation delay around 100ns with 10K (p.22,23). Anyway, you may reduce the baud-rate to 250 or 500K if necessary. regards.

Palliser: They explained to me that if we include any ASF based file in the project, there will be needed to add thousand others. I know you did a great job with your RTC Library but in the case of the CAN class, more references need to be considered.

Thanks for the laurels, but the RTC stuff isn't as half as big as the CAN stuff you did and btw. there was an "component_rtc.h" file that was waiting for me and begged me to make an userfriendly (under arduino law-standing) Library. For you there was nothing from arduino to work above it.

Is there hope of the code seeing the light of day soon? There seem to be no fewer than 3 people (4 including me) who could be working on creating a library but instead it's languishing behind the scenes and no code has been posted. This is kind of depressing since there have been mentions of posting code for around 2 months. It's all well and good to want people to create shields but some people are programmers and some people are electrical engineers. The two don't always overlap so asking people to build something for the transceiver interface isn't always realistic. The four pin adapters posted in this thread would be fine to use for testing if we had code. It doesn't even have to be nice code or complete. Something that works is sufficient to get started. It seems like somebody has code that at least partially works since I've seen mention of testing for a long time. What is really stopping the placement of that code on github? There seem to be no shortage of volunteers to work on it. Just saying...

I would have to agree with AdderD. Why can’t preliminary code be posted up for people to start digesting/optimizing/learning/testing/developing? Also, this API that’s being ‘developed’. There hasn’t even been any discussion on how this API will utilize the CAN peripheral and other necessary peripheral features on board the micro.

Let me elaborate: From my experience with micros and peripherals, there are many ways to configure the drivers. Sometimes you can use DMA, sometimes there is dedicated RAM on board for the specifc peripheral, or you might not use either. There’s all kinds of Low Power Mode Options just for CAN. What events will be generating CAN interrupts to the uC?
What exactly is this API establishing? A bare bones CAN driver or are there more layers of software queuing on top?

So why are driver configuration options not up for discussion? The driver is the foundation upon which everything else will be running. It seems as though there should be discussion on this, unless Palliser wants only his CAN driver ideas implemented…

Another "let us code" post here - I don't particularly care how the CAN shield turns out, and it's not going to have any effect on what the CAN API looks like. It's getting to the point that someone is going to fork off and make their own CAN library, but if the efforts happening behind the scenes of this thread are the "officially blessed" efforts, it would be a shame to have conflict in the future.

A GitHub repo with a "This code does not work." line in the README should suffice.

I think, at this moment, an overview of this project would help to clarify and provide some answers for the latest posts:

My original goal was to find a tinker way to communicate the two little "CANRX" and "CANTX" of the new Arduino Due. I did read in the Arduino site that there was no API available for that. I ran through this forum and found nothing in progress. I asked Massimo about it and he invited me to contribute doing so. I started to look for prior arts regarding the integration of SAM family cores and the CAN protocol and found SAM3X-EK development board and Atmel ASF CAN library. This forced me to re-align my original goal with Atmel's goal which is: to show how to configure the two CAN controllers and how to manage CAN message transfers. Then I started to port the Atmel sample to Arduino IDE. I worked alone for a month, posting my progress here in the forum. During this exercise, I didn't imagine that this way was the hardest road. Finally, I made Due to read/write CAN messages, but at a cost: ~40 files (50% Atmel, 50% Arduino). Even though I followed Massimo recommendations trying to minimize the library, I couldn't reduced them too much. So, I asked him and Cristian for help. They did put me in contact with the Atmel engineer that developed the CAN sample. I gave him the files and he started to redo pretty much everything. As I mentioned before, he already built the shield and is doing now tests. He is a leader, an expert with CORTEX-SAM and a hard worker.

Like you guys, I am waiting for the final CAN API. In the meantime, my role these days has been to motivate the making of the shield, which is a must.

All I can say is that Arduino want to release a solid CAN API, providing to this community a good start in working with the CAN protocol. It is a fact that not everyone knows CAN, like some of us. In this way, it will be easier to digest/optimize/learn/test/develop the protocol. And that's when you will be very valuable with new ideas/applications and supporting others that want to learn. Thanks.

Palliser, I did not mean to be critical. People are ready to go on this, and I think it’s time we start working towards a goal. It sounds like the Atmel engineer may have higher priorities or slowed down on progress, maybe we should start working on our own CAN API. What would we need outside of the datasheet to do this?

Yes, I don't mean to sound like a jerk but that point it really looks like whatever is happening behind the scenes is not working. I really seriously am considering starting up an effort to make a new library from the ground up with just Arduino sanctioned code and libraries. It seems like this Atmel person isn't working very quickly. It is true that it appears as if the canbus stuff in the cortex chip isn't the easiest to work with but the Arduino 1.5.2 IDE seems to already have plenty of libsam and CMSIS stuff in it so access to the relevant hardware features to enable canbus should be possible. At first a fresh effort like this would just basically be the ability to send/receive canbus frames without a lot of hand holding but eventually it could be built up. We'll see. I should get my Due soon and transceivers some day and once I get my hardware I'm going to be itching to make things. If this Atmel guy hasn't produced anything by then I might take matters into my own hands. It's OK if my effort doesn't get sanctioned or if I end up abandoning it once/if the sanctioned one sees the light of day. I'll still have learned a lot about the architecture and that's important too.

I have better news!. Today I got the CAN class from the Atmel engineer. It is a raw class to start with. He really did a great job. Now, instead of ~40 files, we have 4 files. The CAN class (.c,.h) and the transceivers class (.c,.h). It compiles OK (0 errors/0 warnings) with the new IDE 1.5.2. I will be running some tests during this weekend and consulting with Arduino for the releasing in github next week. Thanks you for your patience.

That is good news. I know I'm willing to test. I'm sure plenty of other people are itching to do so as well. No need for too much testing before initial commit to git. The whole point in something like git is to disseminate code. Nobody expects a first commit to be perfect. We're just after something to look at. The sooner we see it, the sooner we get started with testing and modifications.

Another week passes and still nothing in GIT. Hardly the spirit of open source, is it?

The "can" branch is now published on github, currently it's in sync with the upstream "ide-1.5.x" branch. I would like to thanks Palliser and aethaniel for the work done so far, and all the other that have contributed to this discussion.

Who is interested in development must checkout the "can" branch since its likely to diverge while the CAN library gets developed and the API evolves. The CAN library is still far from its final shape, a lot of work needs to be done, BTW its public now and I'm excited to see what the community can get out of it.

Finally: thanks you all for your patience, I know that more than two months of wait seems a lot but, believe me, time flies and sometime is very hard to keep up with the amount of inputs coming from this amazing community.

Very exciting, thank you @cmaglie. I'm looking to check out the repo. Thanks for starting this whole effort and the thread, @Palliser

Thanks for the time and effort from all those who have worked on it so far. It'll be great to have something to get our teeth in to. :)

A big thank you to Palliser and CMaglie! This is really cool! Thanks again!

Excellent work guys, thanks again

Ok, I’ve forked the Arduino project and checked out the CAN branch so I’m pretty well good to go there. I looked at the code for the canbus library. It’s a good start. Here is what I think should be done in order from first to last:

  1. The normal arduino way to instantiate a library seems to be to store everything in the class and instantiate it globally. Right now the can library is constantly needing class references passed to its functions. The Can class should be internal to the CANRaw. This was already done in the code but commented out. I’m guessing that whoever wrote the code just hasn’t gotten to it yet. The canbus transceiver class is already a member of the CANRaw function so that’s good.
  2. It would be nice to make it interrupt driven. Right now it appears to be polling driven. That’s OK for testing but you aren’t going to be able to put it on a bus with a new message every 600us and have it work right.
  3. It would probably be good to be able to use DMA transfers to automatically write canbus frames to a software ring buffer.
  4. Filtering should eventually be implemented
  5. Then higher level protocols should be supported as well.

I’ll try to work on some of this. I won’t have any transceiver hardware to test with until Monday.

Thank you AdderD for your notes and insights about the library.

A second CAN sample sketch has been added into the "can" branch. In this example, the two CAN modules work in PRODUCER mode (CAN0 mailbox 0) and CONSUMER mode (CAN1 mailbox 0) and use CAN interrupt handler to check whether the communication has been completed (interrupt is triggered).

Producer Mode: In this mode, when a remote frame is received, the mailbox data are sent automatically. By enabling this mode, a producer can be done using only one mailbox instead of two: one to detect the remote frame and one to send the answer.

Consumer Mode: In this mode, after each transfer request, a remote frame is automatically sent. The first answer received is stored in the corresponding mailbox data registers.