Reply
Posts: 244
Registered: ‎05-19-2014

CAN Bus Tx/Rx - getting started

I'm designing a board that uses CAN bus to respond to simple commands and transmit back information. There will be one controlling node and several of my boards talking to it. Each board has its own unique identity which it can use to filter out the messages.

 

I've used the F50x_CAN0_Transmit example and now I can see that data correctly arriving at a PC CAN Bus program.

 

I've also tried using the F50x_CAN0_Receive example to try to get it to read messages from the PC CAN Bus program, but it doesn't respond at all. I can see the digital Rx line continuously receiving on the F500 microprocessor chip, but it won't trigger the interrupt.

 

I know that the example is expecting 32 messages with ID's starting at 0, and I'm transmitting just one with and ID of 0. I'd still expect it to cause an interrupt.

 

So the question is, has anyone actually tried this example, and does it work? If it does, can anyone suggest why it might not cause an interrupt, given that the code is copied from the example?

 

Can someone also tell me why there are two sets of registers IF1 and IF2? Is it intended that IF1 is used for transmit and the other for receive? Obviously the example code uses two separate boards for send and receive, so there wouldn't be a clash if they both use IF1 for transmit and receive.

 

Sorry if this is a bit basic, but it's absolutely bewildering for someone who hasn't used it before.

Posts: 244
Registered: ‎05-19-2014

Re: CAN Bus Tx/Rx - getting started

Ok, slight progress on this. I've changed the receive to use IF2 instead of IF1 and it now triggers an interrupt when I send a packet. However, the data all reads zero and the status returns an Ewarn error.

This is what I have for initialising the Rx side...

 

void CAN0Rx_Init (void)
{
U8 iter;
U8 SFRPAGE_save = SFRPAGE;
SFRPAGE = CAN0_PAGE; // All CAN register are on page 0x0C
CAN0CN |= 0x01; // Start Intialisation mode
//---------Initialize general CAN peripheral settings
CAN0CN |= 0x4E;
CAN0BT = 0x1402; // Based on 24 Mhz CAN clock, set the
CAN0IF2CM = 0x00F0; // Write Operation
CAN0IF2M1 = 0x0000; // Mask Bits 15-0 not used for filtering
CAN0IF2M2 = 0x5FFC;
CAN0IF2A1 = 0x0000; // 11-bit ID, so lower 16-bits not used
CAN0IF2MC = 0x1480 | MESSAGE_SIZE; // Enable Receive Interrupt
//---------Initialize unique settings for each valid message object - from Rx example code. I'm using MESSAGE_OBJECTS = 1

for (iter = 0; iter < MESSAGE_OBJECTS; iter++)
{
// For example purposes, set 11-bit identifier based on the message
// object that is used to send it.

// Arbitration Registers
CAN0IF2A2 = 0x8000 | (iter << 2); // Set MsgVal to valid 
// Set Direction to write
// Set 11-bit Identifier to iter

CAN0IF2CR = iter; // Start command request

while (CAN0IF2CRH & 0x80) {} // Poll on Busy bit
}

//---------Initialize settings for unused message objects

for (iter = MESSAGE_OBJECTS; iter < 32; iter++)
{
// Set remaining message objects to be Ignored
CAN0IF2A2 = 0x0000; // Set MsgVal to 0 to Ignore
CAN0IF2CR = iter; // Start command request

while (CAN0IF2CRH & 0x80) {} // Poll on Busy bit
}

CAN0CN &= ~0x41; // Return to Normal Mode and disable
// access to bit timing register

SFRPAGE = SFRPAGE_save;
}

 

When I run it, I know the interrupt happens because I toggle an LED, but I can also see on the oscilloscope that the data is constantly being sent from the PC Can bus program, even though it's only sending one message, so clearly there's an error in the protocol.

I've trawled through the Can Bus reference and looked as the various register settings and it all looks sensible. The length of repeated message packets on the oscilloscope is consistent with 1MHz bit rate and you can clearly see the frames.

 

Can anyone see what I've got set incorrectly, or suggest a way to move forward?

Posts: 244
Registered: ‎05-19-2014

Re: CAN Bus Tx/Rx - getting started

Ok, the issue was that I was looking in the wrong place for the message data received.

 

I now have a modified version of the Rx example code working, and I can see that message IDs of 0-31 are being correctly read, but message IDs above that get ignored although the interrupt still occurs.

 

How are these things intended to work? I have ten things I need each node to do. Should I be assigning message IDs of 0-9 one to each function so they're buffered in the data memory if they arrive in quick succession?

If that's how it's done, should some of the higher bits of the message ID be used to filter the messages with a different mask for each node when it's initialised?