SAME5x - CAN Bus not TX/RXing properly

Go To Last Post
6 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hey all,

 

I'm having some issues with the CAN module on my SAME51J20A part, which is riding on a custom board made by me. I am using Atmel Start to generate all of my HAL code, and then executing the example code given in driver_examples.c..

 

Problem 1 - When transmitting a 11bit STDID packet, all zeroes are transmitted on the bus - Instead of the packet I set up with an ID of 0x45A

Problem 2 - When I send a packet to my board that matches my filter&mask, I find all zeroes in the FIFO once the RX Callback is called

 

What I have done and noted so far:

  • Bus is set for 100kbps
  • I am using the Microchip CAN bus analyzer tool to receive packets on my PC, as well as sampling the signals using my scope to verify the signal and HW integrity.
  • RX Mask&Filters ARE working (If I change the ID I send, my callback isn't called)
  • HW has been verified, and a packet NOT containing all zeroes makes it into the micro, yet the FIFO is full of zeroes.
  • I do have FreeRTOS running on this system (Which as I am typing this, I wonder if there is a conflict on interrupts and the data is being properly transfered to my FIFOs - Although that usually results in a Hard Fault OR in an Assert failing within FreeRTOS which causes the micro to halt - Which isn't happening)

 

 

Anyone have some suggestions on debugging? - At this point, I believe I have ruled out anything HW related, and that this problem is App code related.. What worries me the most, is that the HAL actually has a bug in it.

 

 

Here is my example code:

 

 

Here is a captured of the CAN_RX pin (The net between the micro and my transceiver), showing that I am in fact sending a packet that is not all zeroes to the micro - Yet when I get to my callback, there is nothing but zeroes.

 

 

 

 

 

Here is a captured output of the CAN_TX pin (The net between the micro and my transceiver), showing that even though I send a packet of non zero bytes - All zeroes are transmitted on the bus.

 

 

 

This topic has a solution.

murph

Debugging - Being a detective in a crime movie where you are also the murderer.

Last Edited: Wed. Mar 27, 2019 - 09:54 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So.. I THINK I am on to something.. Just not sure how to fix it.. Basically what I think the problem is, is that I am putting data into a buffer at address X.. But when the CAN module is looking in address Y and transmitting what it finds there... I think this is the same problem with with both RX and TX..

 

Issue with RX

- The RX Buffer Start Address is stored in the RXBC.RBSA[15:0].. So it only stores 15 bits.. Below is the the description (Which I am may be misunderstanding something within)

Bits 15:0 – RBSA[15:0] Rx Buffer Start Address Configures the start address of the Rx Buffers section in the Message RAM. 
Also used to reference debug message A,B,C. When the CAN module addresses the Message RAM it addresses 32-bit words, not single bytes. 
The configurable start addresses are 32-bit word addresses, i.e. only bits 15 to 2 are evaluated, the two least significant bits are ignored. 
Bits 1 to 0 will always be read back as “00”.

- During init, when setting this buffer, I am passing in an address of my buffer in RAM (0x2001457C)... Which this is a problem, since the register is only 15bits.. So the resulting value in the register is (0x0000457C)   <-- I've confirmed this using the I/O window while debugging

- So now, when I do a read, I THINK the CAN HW attempts to put the data into 0x0000457C (Which I believe will fail since this is Program Space), sets the appropriate flags which causes my ISR to trip.. And then when I access the FIFO (0x2001457C), it's of course empty, because the data wasn't placed there..

 

Issue with TX

- I believe TX is experiencing the exact same thing. TX Buffer Start Address is stored in TXBC.TBSA[15:0].. When setting my TX Buffer Address that is in RAM, The upper 16bits are truncated, resulting in a mismatch later on.. I place data into the appropriate RAM, and initiate a write on the bus, which but the CAN HW looks at the truncated address (Pointing somewhere in the Program space), and ends up sending all zeroes.. (Again, I'm assuming because it attempts a Read on the program space which is denied)..

 

Conclusion:

I don't really have a conclusion at this point. I find it very hard to believe that an issue this severe is present in the silicon, and I believe I am missing something here (Likely very obvious).. Any idea folks? 

 

Any help is much appreciated..

murph

Debugging - Being a detective in a crime movie where you are also the murderer.

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 3

I ran into this too. You need to get the ASF CAN buffers into low enough memory so the 15 bits works.

 

Try this in hpl_can.c (this is based on Atmel Start code):

// The message ram / buffer start addresses are set with 16 bit registers, so we
// need to make sure they stay below 64K in RAM. To do that, we create a section
// called lowRam that starts at 0 -> 0x20000000, and put the msg buffers there.
// See the linker script.

#ifdef CONF_CAN0_ENABLED
COMPILER_ALIGNED(4)
__attribute__((__section__(".lowRam"))) uint8_t can0_rx_fifo[CONF_CAN0_F0DS * CONF_CAN0_RXF0C_F0S];
COMPILER_ALIGNED(4)
__attribute__((__section__(".lowRam"))) uint8_t can0_tx_fifo[CONF_CAN0_TBDS * CONF_CAN0_TXBC_TFQS];
COMPILER_ALIGNED(4)
__attribute__((__section__(".lowRam"))) static struct _can_tx_event_entry can0_tx_event_fifo[CONF_CAN0_TXEFC_EFS];
COMPILER_ALIGNED(4)
__attribute__((__section__(".lowRam"))) static struct _can_standard_message_filter_element can0_rx_std_filter[CONF_CAN0_SIDFC_LSS];
COMPILER_ALIGNED(4)
__attribute__((__section__(".lowRam"))) static struct _can_extended_message_filter_element can0_rx_ext_filter[CONF_CAN0_XIDFC_LSS];

And then in linker script add this to place lowRam:

    /* For CAN buffers */
    .lowRam (NOLOAD):
    {
        . = ALIGN(4);
    } > ram
 

I'll attach the linker script.

Attachment(s): 

JiggerH

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

JiggerHerman wrote:

I ran into this too. You need to get the ASF CAN buffers into low enough memory so the 15 bits works.

 

Try this in hpl_can.c (this is based on Atmel Start code):

// The message ram / buffer start addresses are set with 16 bit registers, so we
// need to make sure they stay below 64K in RAM. To do that, we create a section
// called lowRam that starts at 0 -> 0x20000000, and put the msg buffers there.
// See the linker script.

#ifdef CONF_CAN0_ENABLED
COMPILER_ALIGNED(4)
__attribute__((__section__(".lowRam"))) uint8_t can0_rx_fifo[CONF_CAN0_F0DS * CONF_CAN0_RXF0C_F0S];
COMPILER_ALIGNED(4)
__attribute__((__section__(".lowRam"))) uint8_t can0_tx_fifo[CONF_CAN0_TBDS * CONF_CAN0_TXBC_TFQS];
COMPILER_ALIGNED(4)
__attribute__((__section__(".lowRam"))) static struct _can_tx_event_entry can0_tx_event_fifo[CONF_CAN0_TXEFC_EFS];
COMPILER_ALIGNED(4)
__attribute__((__section__(".lowRam"))) static struct _can_standard_message_filter_element can0_rx_std_filter[CONF_CAN0_SIDFC_LSS];
COMPILER_ALIGNED(4)
__attribute__((__section__(".lowRam"))) static struct _can_extended_message_filter_element can0_rx_ext_filter[CONF_CAN0_XIDFC_LSS];

And then in linker script add this to place lowRam:

    /* For CAN buffers */
    .lowRam (NOLOAD):
    {
        . = ALIGN(4);
    } > ram
 

I'll attach the linker script.

 

 

Wow. That is.. crazy.. This obviously isn't intended to be how it's implemented, and I say that because my filters work which also has a 15bit address and is implemented the same was as the FIFO start addresses.. So instead of an Address, they seem to be an OFFSET within Message RAM which is in the 0x2000zzzz range. You have to attach the context (Message RAM table), to the HW instance itself, which I guess is how it know what address to Offset from?

 

So the CAN Core can properly find the filters using the 15bit address (offset), but it can't locate the FIFOs? Potential errata? Idk..

 

This experience has been very off-putting and makes me regret using Atmel for a device revolving around CAN. I'll try the above just to see if it works and mark this as a solution, but unfortunately I think I am going to have to spin my hardware and switch to NXP or STM (both have an extensive background in providing solutions for CAN/Automotive applications)

 

Thanks Jigger!

 

// Actually.. Jigger, do filters still work after you implemented this "lowRam" workaround? Based on what I have seen so far, I would guess NO.. Again, I will work it out this evening and report back what I find.

murph

Debugging - Being a detective in a crime movie where you are also the murderer.

Last Edited: Wed. Mar 27, 2019 - 01:38 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well. I'm home and just ran it through a couple of tests and it all seems to be working. Thanks again Jigger!.. I tested this fix with both CAN instances on the SAME51, and I now have no problem Transmitting or Receiving packets, as well as utilizing the filters to only receive messages with the ID I want.

 

*Only thing I will have to pay attention to is if I reconfigure my project at all using Start.. I believe it will wipe out the needed changes in the HAL..

murph

Debugging - Being a detective in a crime movie where you are also the murderer.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

 

I downloaded the CAN project for my custom board (SAME51J18A).

CAN clock is 48 MHZ and normal bit timing updated with corresponding values for corresponding baud rates.

 

I changed in linker file as well as in hal_can.c file as explained by  JiggerHerman .

 

My address of tx fifo  is 0x20 which means from base 0x2000000 plus address of tx fifo i.e 0x20000020 is the address where I supposed to write the ID,DLC and data.

I am writing and I checked also while I was debugging in memory the ID,DLC and data is updating.

 

After that I need to add request in order to transmit the frame.

I am using PCAN USB for receiving frame on my PC from custom board.

When I am adding request I am not able to receive any frame on PCAN USB.

In PCAN USB I am getting status as BUSHEAVY.

 

Could you please help me resolving my problem.

  

 

Ujjwal Tambe