[Completed] CAN for libemaple + F4

michael_l
Sat Sep 08, 2018 1:27 pm
I’m trying to get phonog’s HardwareCAN library to work with F4 libmaple.

Here’s the original code: https://github.com/Phonog/Arduino_STM32 … areCAN/src

I’ve added RCC_CAN into rccF4.h/rccF4.c

[RCC_CAN] = { .clk_domain = APB1, .line_num = 25 },

and also changed NVIC namings so it compiles OK. Also AFIO RCC is not used in F4.

Currently the problem is that CAN goes into init mode but does not leave it and it timeouts. Init is performed in can_init function.

From reference:

Once the initialization is complete, the software must request the hardware to enter Normal
mode to be able to synchronize on the CAN bus and start reception and transmission.
The request to enter Normal mode is issued by clearing the INRQ bit in the CAN_MCR
register. The bxCAN enters Normal mode and is ready to take part in bus activities when it
has synchronized with the data transfer on the CAN bus. This is done by waiting for the
occurrence of a sequence of 11 consecutive recessive bits (Bus Idle state). The switch to
Normal mode is confirmed by the hardware by clearing the INAK bit in the CAN_MSR
register.

I have a small test bench CAN network with 2 devices terminated with 120ohm resistors. First one is USBTin CAN-BUS adapter and the other is “mini blue board” aka VCC_GND_F407. I tested with micropython that can driver works and USBTin receives messages from F4 and shows them in the viewer program so CAN BUS is proven to work and CAN hardware in F4 is working.

python code:
from pyb import CAN
import time

#250kBit, F4, PB8 (RX), PB9 (TX)
can = CAN(1, CAN.NORMAL, extframe=False, prescaler=12, sjw=1, bs1=11, bs2=2)

can.setfilter(0, CAN.LIST16, 0, (123, 124, 125, 126)) # set a filter to receive messages with id=123, 124, 125 and 126
while True:
print("sending...")
can.send(b'00000000', 1) # send a message with id 123
time.sleep(.005)
print(can.info())


stevestrong
Sat Sep 08, 2018 4:40 pm
AFIO is indeed not implemented in F4, but the GPIO settings look good.
Eventually you could try to activate the pull-up for the Rx pin.

Be sure that the RCC_CAN1/2 entries in rccF4.h/c have the same position in the respective lists.

Some hints what to check: https://stackoverflow.com/a/13821030
Maybe try Loopback mode?

Have you cleared the INRQ bit?
I would check in my program the status of CAN_MSR/MCR registers after each step I take.

[michael_l – Sat Sep 08, 2018 1:27 pm] –
The bxCAN enters Normal mode and is ready to take part in bus activities when it
has synchronized with the data transfer on the CAN bus. This is done by waiting for the
occurrence of a sequence of 11 consecutive recessive bits (Bus Idle state).

It is not clear to me where those recessive bits should come from, from the other connected device?
Or they are generated by the HW when sending some data?
So try to send some data right after you enter normal mode (by clearing INRQ it), and check the status of the MSR/MCR registers.

Could you maybe share your development on github so that I can check your current code?

You can remove all USB and AFIO related stuff from the code made by Phonog.

I am not sure where and how, but you have to assign parts of the code to these interrupts: __irq_can1_tx, __irq_can1_rx0, (__irq_can1_rx1 maybe optional). Associated NVIC_CAN1_TX, NVIC_CAN1_RX0, NVIC_CAN1_RX1 should be also used in nvic_irq_… functions.


michael_l
Sat Sep 08, 2018 6:49 pm
Thanks for the help!

Ok, I got leaving init mode working by changing this:

gpio_set_mode(PD0, GPIO_INPUT_FLOATING); –> gpio_set_mode(PD0, GPIO_AF_INPUT);

I didn’t understand this was needed.

RCC_APB1RSTR at bit 25 is for CAN1. I use only CAN1 module here. Also the same bit 25 for RCC_APB1ENR.

Sending messages still fail… so that is strange. Guess I’ll have to start debugging it. Recessive bits are read from the bus

LOOPBACK mode will halt the program so I haven’t tried it that much.

Yes, I’ll put the code in github, but later. Attached is the .zip file. It contains some hardcoded stuff though, like using PD0/PD1 for pins. I’ve used HardwareCANexample.ino for testing and modified it with Serial prints


michael_l
Sun Sep 09, 2018 9:21 pm
Small update I got TX part working. And RX works also in polling mode. Had to invent a small hack for that.

1. the baud rate configuration for 500kbit was wrong
2. I had to disable CAN interrupts or it would fault the MCU <– this is something to fix next

When I enable this interrupt nvic_irq_enable(NVIC_CAN1_TX);


stevestrong
Mon Sep 10, 2018 6:41 am
Look for similar interrupts in the core, how they are handled, and how they are defined.
Maybe an
extern “C” void __irq_can_tx(void)

}
helps?

Also, you can check with the debugger the interrupt vector address for that IRQ.
A MAP file viewer can also help sometimes: http://www.sikorskiy.net/prj/amap/


michael_l
Mon Sep 10, 2018 11:47 am
Found the bug!

correct function name is: __irq_can1_tx and I am using __irq_can_tx . :roll: That’s why the handler was never called…

I’ll try this tonight. Basically interrupts are not needed here but this library has been built so that it stores messages in internal buffer so I’ll leave it as it is. Maybe I’ll add some diagnostic functions to find out the state of the controller and various error counters.


stevestrong
Mon Sep 10, 2018 12:19 pm
I am glad you made it, I mentioned the (correct) ISR function names in my post above, my first reply.
Keep us informed!

michael_l
Mon Sep 10, 2018 10:26 pm
I’ve been testing this a little and it seems to work okay after I fixed baud rate configs and added correct interrupt handling function names. I think baud rates are a bit wrong in phonog’s repo as he’s using 18 TQ but saving to BTR something that indicates TQ of 21 but of course they may still work okay. I don’t know. In my case only 125kB worked and I had to change other configs to get it working for me. I’ll test some more and release the code

michael_l
Wed Sep 12, 2018 12:11 pm
So here’s working CAN library for libmaple/F4. Nice thing compared to F1 is that USB Serial works also with CAN.

I’ve tested all baud rates, also added an error stats function. Two examples for normal mode and loopback.


stevestrong
Wed Sep 12, 2018 12:58 pm
@michael_i, nice job, than you.
I will add it to my repo as a library, if you have nothing against.

michael_l
Wed Sep 12, 2018 1:19 pm
[stevestrong – Wed Sep 12, 2018 12:58 pm] –
@michael_i, nice job, than you.
I will add it to my repo as a library, if you have nothing against.

Sure, by all means !


Leave a Reply

Your email address will not be published. Required fields are marked *