Using CAN bus: baud configuration, and recv() in IRC

Discuss development of drivers for external hardware and components, such as LCD screens, sensors, motor drivers, etc.
Target audience: Users and developers of drivers.
Post Reply
ahebert
Posts: 4
Joined: Fri Nov 07, 2014 11:04 pm

Using CAN bus: baud configuration, and recv() in IRC

Post by ahebert » Tue Jul 05, 2016 9:11 pm

I have successfully wired transceivers to my pyboard (v1.0) and I am sending/receiving on both CAN busses, which I'm quite happy with. Now there are a couple of things I'm confused about as I refine my setup:

1. How to choose parameters for a given baud rate for CAN.init()?

I would like to make a list of settings (prescaler, sjw, bs1, bs2, assume PCLK1=42MHz) to work with all of the supported baud rates of my PEAK usb-CAN adapter. The supported baud rates are 5000, 10000, 20000, 33333, 47619, 50000, 83333, 95238, 100000, 125000, 250000, 500000, 800000, 1000000.

I wrote a script to generate a list of all viable settings for each baud rate, but many of them don't work. Through trial and error with that list, I found settings that successfully send/receive at the highest four baud rates:

Code: Select all

# This worked for 125k baud rate
can1.init(CAN.NORMAL, extframe=False, prescaler=16, sjw=1, bs1=14, bs2=6)

# This worked for 250k baud rate
can1.init(CAN.NORMAL, extframe=False, prescaler=8, sjw=1, bs1=14, bs2=6)

# This worked for 500k baud rate
can1.init(CAN.NORMAL, extframe=False, prescaler=4, sjw=1, bs1=14, bs2=6)

# This worked for 1M baud rate
can1.init(CAN.NORMAL, extframe=False, prescaler=2, sjw=1, bs1=14, bs2=6)
The documentation (http://docs.micropython.org/en/latest/p ... b.CAN.html) says, "See page 680 of the STM32F405 datasheet for more details." But all the datasheets that I found are ~200 pages at most, and have very little to say about the CAN features. If anyone has a link to details of the CAN configuration parameters for the STM32F405, I will be most grateful.

2. How to receive data into a buffer using an IRC (e.g. CAN.rxcallback(), Timer, external interrupt)?

It seems that the `CAN.recv()` method allocates new memory when it's called, based on the memory error that I get when I try to call it from `CAN.rxcallback()`. I would like to preallocate a buffer for 1000 CAN messages, and have them stored in the buffer as they come in, without consideration with my main program loop, which is handling user inputs and drawing to a screen.

Is that possible with the micropython CAN library? If not, is there a particular reason to avoid what I'm suggesting?


Thanks in advance for any advice.

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Using CAN bus: baud configuration, and recv() in IRC

Post by dhylands » Tue Jul 05, 2016 9:42 pm

You want page xxx of the Reference Manual, which can be found here:
http://www.st.com/resource/en/reference ... 031020.pdf
which is over 1700 pages.

The clock tree on page 152 will probably be useful to look at.

The CAN peripheral is covered in pages 1079 thru 1123.

Page 1096 has the bit-timing calculations, and the BTR register is descibed on page 1108-1109.

Keil has what looks to be a nice application note here:
http://www.keil.com/appnotes/files/apnt_236.pdf

Post Reply