Message ram location in CAN controller(s) on LPC54608

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Message ram location in CAN controller(s) on LPC54608

2,841 Views
nthove
Contributor I

Does someone have experience with setting up the CAN controller on the LPC54608?

I have troubles initializing the message ram. When I declare the variable (Keil MDK):

uint8_t can_msg_ram_base[128] __attribute__((at (0x20010000)));

...and provide the message ram to the CAN controller like this:

MCAN_SetMsgRAMBase(CAN0, (uint32_t)can_msg_ram_base);

...messages are sent on the CAN bus (see the screenshot, message ID 111h).

However, if I declare the can_msg_ram_base variable on any other address, messages are sent with all zeroes (see first line in screenshot).

Are there any restrictions on the message ram location? The user manual does not specify such restrictions, other than it must be located in internal SRAM. I don't see why I can't put the message ram on an arbitrary location. I also tried  to align this arbitrary location on a 4/8/16-byte boundary, but that does not help. Can someone provide me with more information on the the restrictions for the message ram of the CAN controller(s)?

can_messages.jpg

Labels (1)
Tags (2)
7 Replies

1,962 Views
michaelrauch
Contributor I

I found that it is working on all memory areas, when you consider the following:

- the low 16 bit of MRBA must be zero
- you may use any memory range not going over a 64k block
- the lower 16 bit of the original pointer must be added to the offets of the other register.

see the follwing code fragment (which is working in my project):

this->StdFilterOfs = 0;
this->RxFifo0Ofs = this->StdFilterOfs + 0x10;
this->TxBufferOfs = this->RxFifo0Ofs + this->rxFifoSize*0x10;
this->MRBASize = this->TxBufferOfs + 2*0x10;
this->MRBA = (uint8_t*) MallocSRAMX(this->MRBASize);

uint32_t addofs = ((uint32_t) this->MRBA) & 0xFFFF;
this->StdFilterOfs += addofs;
this->RxFifo0Ofs += addofs;
this->TxBufferOfs += addofs;
this->MRBA = (uint8_t*)(((uint32_t) this->MRBA) & 0xFFFF0000);

1,963 Views
nthove
Contributor I

Thanks for confirming the issue. We’ll await your findings.

0 Kudos

1,963 Views
carstengroen
Senior Contributor II

Norbert,

I see the exact same behavior here (own hardware, LPC54606) !

If I use 0x20010000 as the base address it works, if I declare my own buffer for this it fails. Have you measure on the physical can bus with a scope ? I did also receive all 0's in my PCAN-View but when looking at the bus there were only some sync data sent so I think that PCAN does not quite understand this and shows it as a frame with all 0 in it.

When changing address to the same as the example in the SDK it magically works for me!

(and yes, all my SRAM blocks are powered up and enabled)

Edit, list of the tests I have made (some of the "Not ok" will allow one to send messages, but messages received will be received as all "0"):

//uint8_t MCAN_Memory[2048] __attribute__((at (0x20010000))); // OK
//uint8_t MCAN_Memory[2048] __attribute__((at (0x20018000))); // NOT OK
//uint8_t MCAN_Memory[2048] __attribute__((at (0x20020000))); // OK
//uint8_t MCAN_Memory[2048] __attribute__((at (0x20021000))); // NOT OK
//uint8_t MCAN_Memory[2048] __attribute__((at (0x20022000))); // NOT OK
//uint8_t MCAN_Memory[2048] __attribute__((at (0x04000000))); // OK
//uint8_t MCAN_Memory[2048] __attribute__((at (0x04001000))); // NOT OK
//uint8_t MCAN_Memory[2048] __attribute__((at (0x04002000))); // NOT OK
//uint8_t MCAN_Memory[2048] __attribute__((at (0x04003000))); // NOT OK
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

My init code for CAN (for now its just mostly a copy of the sample...)

    /* Set MCAN clock */
    CLOCK_SetClkDiv(kCLOCK_DivCan0Clk, 1, true);
     
    MCAN_GetDefaultConfig(&mcanConfig);
     mcanConfig.baudRateA=125000;

    MCAN_Init(CAN0, &mcanConfig, CLOCK_GetFreq(kCLOCK_MCAN0));

    /* Create MCAN handle structure and set call back function. */
    MCAN_TransferCreateHandle(CAN0, &mcanHandle, mcan_callback, NULL);

    /* Set Message RAM base address and clear to avoid BEU/BEC error. */
    MCAN_SetMsgRAMBase(CAN0, (uint32_t)MCAN_Memory);
    uint32_t *p=(uint32_t *)(MCAN_Memory);
    memset(p, 0, TX_BUFFER_OFS + 0x10U);
     
     
    /* STD filter config. */
    rxFilter.address = STD_FILTER_OFS;
    rxFilter.idFormat = kMCAN_FrameIDStandard;
    rxFilter.listSize = 1U;
    rxFilter.nmFrame = kMCAN_reject0;
    rxFilter.remFrame = kMCAN_rejectFrame;
    MCAN_SetFilterConfig(CAN0, &rxFilter);
    
    stdFilter.sfec = kMCAN_storeinFifo0;
    /* Classic filter mode, only filter matching ID. */
    stdFilter.sft = kMCAN_classic;
    stdFilter.sfid1 = rxIdentifier;
    stdFilter.sfid2 = 0x7FFU;
    MCAN_SetSTDFilterElement(CAN0, &rxFilter, &stdFilter, 0);
     
     
    /* RX fifo0 config. */
    rxFifo0.address = RX_FIFO0_OFS;
    rxFifo0.elementSize = 1U;
    rxFifo0.watermark = 0;
    rxFifo0.opmode = kMCAN_FifoBlocking;
    rxFifo0.datafieldSize = kMCAN_8ByteDatafield;
    MCAN_SetRxFifo0Config(CAN0, &rxFifo0);

    /* TX buffer config. */
    txBuffer.address = TX_BUFFER_OFS;
    txBuffer.dedicatedSize = 1U;
    txBuffer.fqSize = 0;
    txBuffer.datafieldSize = kMCAN_8ByteDatafield;
    MCAN_SetTxBufferConfig(CAN0, &txBuffer);

    /* Finish software initialization and enter normal mode, synchronizes to
       CAN bus, ready for communication */
    MCAN_EnterNormalMode(CAN0);     
     ‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

1,963 Views
Dezheng_Tang
NXP Employee
NXP Employee

Thanks a lot! Confirmed your finding, have reported to the design team to look into that.

1,963 Views
Dezheng_Tang
NXP Employee
NXP Employee

Casten,

    Sorry that I am not able to get back you sooner on this. The design engineer was not available in the last few days, and today, we start debugging this together. Here is my finding and I am still waiting for design to get back to me on this.

    You should be able to use all these memory region below for MCAN data communication:

//uint8_t MCAN_Memory[2048] __attribute__((at (0x20010000))); // OK
//uint8_t MCAN_Memory[2048] __attribute__((at (0x20018000))); // NOT OK
//uint8_t MCAN_Memory[2048] __attribute__((at (0x20020000))); // OK
//uint8_t MCAN_Memory[2048] __attribute__((at (0x20021000))); // NOT OK
//uint8_t MCAN_Memory[2048] __attribute__((at (0x20022000))); // NOT OK
//uint8_t MCAN_Memory[2048] __attribute__((at (0x04000000))); // OK
//uint8_t MCAN_Memory[2048] __attribute__((at (0x04001000))); // NOT OK
//uint8_t MCAN_Memory[2048] __attribute__((at (0x04002000))); // NOT OK
//uint8_t MCAN_Memory[2048] __attribute__((at (0x04003000))); // NOT OK

However, if you use 0x2001x000, the base address in MRBA register needs to be 0x20010000.

if you use 0x2002x000, the base address in MRBA register needs to be 0x20020000.

if you use 0x0400x000, the base address in MRBA register needs to be 0x04000000.

"x" above could be any value.

The base address need to be at the 0x10000 boundary or MCAN message receive won't work. 

So, inside SDK, change

#define CAN_MRBA_BA_MASK                         (0xFFFFFFFFU)

to

#define CAN_MRBA_BA_MASK                         (0xFFFF0000U)

Please try it again and post your results here.

Once it's confirmed by the H/W design team, we will update the Users Manual as well as SDK software.

Thanks!

 

0 Kudos

1,963 Views
carstengroen
Senior Contributor II

Any news on this ?

0 Kudos

1,963 Views
Dezheng_Tang
NXP Employee
NXP Employee

In addition to PDRUNCFG0 that make sure all the RAMs are powered up, check the clocks to SRAM1/2/3 are enabled in AHBCLKCTRLx register in SYSCON offset at 0x200.

0 Kudos