Pyboard D - CAN bus extended frames

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
JohnieBraaf
Posts: 9
Joined: Mon Jan 06, 2020 12:08 am

Pyboard D - CAN bus extended frames

Post by JohnieBraaf » Mon Jan 06, 2020 12:24 am

Hi all,

I'm having a hard time getting my head around the following.

I have 2 CAN ports connected to TJA1050 can bus tranceivers with 120ohm termination resistors.
CAN1 RX: X9 to tranceiver
CAN2 TX: X10 to tranceiver

CAN2 RX: Y5 to tranceiver
CAN2 TX: Y6 to tranceiver

With the below script I've setup CAN communication between CAN1 and CAN2 of the pyboard D (767).

Code: Select all

import pyb
import micropython
import network

class CanInterface(pyb.CAN):
    def __init__(self, itf):
	self.itf = itf        
	self.can = pyb.CAN(itf)
                
        self.recv_caller = self.recvcb
	self.send_caller = self.sendcb
	self.init()

    def init(self):
        can = self.can
        can.init(mode=pyb.CAN.NORMAL, extframe=True, prescaler=15, sjw=1, bs1=14, bs2=2, auto_restart=False)
        can.setfilter(bank=self.itf-1, mode=pyb.CAN.MASK32, fifo=self.itf-1, params=(0x0, 0x0))
        can.rxcallback(self.itf-1, self.receive)
	print ("CAN " + str(self.itf) + " initialized")

    def close(self):
        can = self.can
        can.rxcallback(self.itf-1, None)
        can.deinit()

    def send(self, message):
	micropython.schedule(self.send_caller, message)

    # callback on os thread
    def sendcb(self, message):
	can = self.can
	for message, id in message:
	  if can.info()[5] < 3:
	    print(message, id) 	
	    can.send(message, id)
	  else:
	    print("cannot send packet on CAN" + str(self.itf) + ", TX queue is full")

    def receive(self, bus, reason):
        micropython.schedule(self.recv_caller, bus)

    # callback on os thread
    def recvcb(self, bus):
	can = self.can
	if can.any(self.itf-1):
	  rcv = can.recv(self.itf-1)
	  print("CAN" + str(self.itf) + " RX: " + str(hex(rcv[0])) + " " + str(rcv))
	else:
	  print("cannot receive packet on CAN" + str(self.itf) + ", RX queue is empty")
        
    
# setup interfaces
can1 = CanInterface(1)
can2 = CanInterface(2)
pyb.LED(3).on()

# send test message
#can1.send("HI CAN1", 0x202)
#can2.send("Hi CAN2", 0x203)

tim = pyb.Timer(4)
tim.init(freq=100)
msg = [(b'\x00\x00\x01\x1b\x01\x00',0x01)]
tim.callback(lambda t:can1.send(msg)) # send conituous messages
Now, when I change the extended frame property to False, I no longer receive CAN frames.
The bus is still active and I can see the frames on the oscilloscope, but the receive interrupt does not trigger.

Code: Select all

can.init(mode=pyb.CAN.NORMAL, extframe=False, prescaler=15, sjw=1, bs1=14, bs2=2, auto_restart=False)
How can this be? Am I missing something?

JohnieBraaf
Posts: 9
Joined: Mon Jan 06, 2020 12:08 am

Re: Pyboard D - CAN bus extended frames

Post by JohnieBraaf » Thu Jan 09, 2020 8:25 am

I found the answer by myself. It's a bug in pyb_can.c

The filter masking is not correct:

Code: Select all

filter.FilterIdHigh     = (mp_obj_get_int(params[0]) & 0x1FFFE000)  >> 13; 
filter.FilterIdLow      = (((mp_obj_get_int(params[0]) & 0x00001FFF) << 3) | 4) | rtr_masks[0]; 
filter.FilterMaskIdHigh = (mp_obj_get_int(params[1]) & 0x1FFFE000 ) >> 13; 
filter.FilterMaskIdLow  = (((mp_obj_get_int(params[1]) & 0x00001FFF) << 3) | 4) | rtr_masks[1]; 
when I change it to this, I can also receive packets that do not have an extended identifier:

Code: Select all

 
filter.FilterIdHigh = 0x0000; 
filter.FilterIdLow = 0x0000;
filter.FilterMaskIdHigh = 0x0000; 
filter.FilterMaskIdLow = 0x0000;

User avatar
jimmo
Posts: 2754
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: Pyboard D - CAN bus extended frames

Post by jimmo » Thu Jan 09, 2020 12:53 pm

Thanks for the report, I've raised this on GitHub on your behalf: https://github.com/micropython/micropython/issues/5508

JohnieBraaf
Posts: 9
Joined: Mon Jan 06, 2020 12:08 am

Re: Pyboard D - CAN bus extended frames

Post by JohnieBraaf » Thu Jan 09, 2020 1:01 pm

Thank you Jimmo. I have added the details in github.

Post Reply