LPC54608 CanBus Driver

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

LPC54608 CanBus Driver

Jump to solution
3,059 Views
fatihozen
Contributor IV

Hi,

Is there any example of canbus driver for lpc546 family. I have no experience about can communication. There are two examples in SDK but I could not understand clearly how can works. I have another board which sending messages via canbus. I just know communication frequency is 500 kHz and sending 8 bytes each time and its IDs are 0x000 and 0x002. I want to listen what it is sending to me via canbus. Could someone help me to do that?

I see datas via logic analyzer but I don't know how to init can0 or can1 on my lpc54608 uc.
pastedImage_1.png

Labels (1)
Tags (2)
0 Kudos
1 Solution
2,056 Views
fatihozen
Contributor IV

It is okay now. I defined new array and matched it with rxFrame.data. It is working now.
for(int a=0;a<8;a++) {mydata[a] = rxFrame.data[a];}
Code is below for someone stucks here. Thanks jeremyzhou

#include "fsl_debug_console.h"
#include "fsl_mcan.h"
#include "board.h"
#include "pin_mux.h"
#include <stdbool.h>
/*******************************************************************************
* Definitions
******************************************************************************/
#define EXAMPLE_MCAN_IRQHandler CAN0_IRQ0_IRQHandler
#define EXAMPLE_MCAN_IRQn CAN0_IRQ0_IRQn
#define EXAMPLE_MCAN CAN0
#define MCAN_CLK_FREQ CLOCK_GetFreq(kCLOCK_MCAN0)
#define STDID_OFFSET 18U
#define MSG_RAM_BASE 0x20010000U
#define STD_FILTER_OFS 0x0
#define RX_FIFO0_OFS 0x10U
#define TX_BUFFER_OFS 0x20U
/*******************************************************************************
* Prototypes
******************************************************************************/

/*******************************************************************************
* Variables
******************************************************************************/
volatile bool rxComplete = false;
mcan_rx_buffer_frame_t rxFrame;
mcan_fifo_transfer_t rxXfer;
mcan_handle_t mcanHandle;
/*******************************************************************************
* Code
******************************************************************************/

void CAN0_IRQ0_IRQHandler(void)
{
MCAN_ClearStatusFlag(EXAMPLE_MCAN, CAN_IR_RF0N_MASK);
MCAN_ReadRxFifo(EXAMPLE_MCAN, 0, &rxFrame);
rxComplete = true;
/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
exception return operation might vector to incorrect interrupt */
#if defined __CORTEX_M && (__CORTEX_M == 4U)
__DSB();
#endif
}

int main(void)
{
mcan_config_t mcanConfig;
mcan_frame_filter_config_t rxFilter;
mcan_std_filter_element_config_t stdFilter;
mcan_rx_fifo_config_t rxFifo0;

/* Initialize board hardware. */
/* attach 12 MHz clock to FLEXCOMM0 (debug console) */
CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);

/* Set MCAN clock 48/6=8MHz. */
CLOCK_SetClkDiv(kCLOCK_DivCan0Clk, 6U, true);

BOARD_InitPins();
BOARD_BootClockFROHF48M();
BOARD_InitDebugConsole();

MCAN_GetDefaultConfig(&mcanConfig);
MCAN_Init(EXAMPLE_MCAN, &mcanConfig, MCAN_CLK_FREQ);

/* Set Message RAM base address and clear to avoid BEU/BEC error. */
MCAN_SetMsgRAMBase(EXAMPLE_MCAN, MSG_RAM_BASE);
uint32_t *p=(uint32_t *)(MSG_RAM_BASE);
memset(p, 0, TX_BUFFER_OFS + 0x10U);

/* STD filter config. */
rxFilter.address = 0x0;
rxFilter.idFormat = kMCAN_FrameIDStandard;
rxFilter.listSize = 1U;
rxFilter.nmFrame = kMCAN_reject0;
rxFilter.remFrame = kMCAN_rejectFrame;
MCAN_SetFilterConfig(EXAMPLE_MCAN, &rxFilter);

stdFilter.sfec = kMCAN_storeinFifo0;
MCAN_SetSTDFilterElement(EXAMPLE_MCAN, &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(EXAMPLE_MCAN, &rxFifo0);

/* Enable RX fifo0 new message interrupt using interrupt line 0. */
MCAN_EnableInterrupts(EXAMPLE_MCAN, 0, CAN_IE_RF0NE_MASK);
EnableIRQ(CAN0_IRQ0_IRQn);

/* Enter normal mode. */
MCAN_EnterNormalMode(EXAMPLE_MCAN);

void test(void){
if(mydata[0] == 10) {PRINTF(" 0");} else {PRINTF(" -");}
}

while (1)
{
for(int a=0;a<8;a++) {mydata[a] = rxFrame.data[a];}
PRINTF("ID: %x", rxFrame.id >> 18);
PRINTF(" DATA: ");
for(int a=0;a<8;a++) {PRINTF(" %d",mydata[a]);}
test();
PRINTF("\r\n");
}
}

View solution in original post

11 Replies
2,056 Views
fatihozen
Contributor IV

Okay then I move with can loopback example in SDK. But could not achieve the goal. I just want to see datas in my side.
My init code is below.

I know datas coming in 8 byte mode with 500kHz and has normal id. other nodes ids 0x000 and 0x002. I expect to see datas in picture 1 but I see datas like in picture 2. and datas in 2nd picture is meanless. There are 15 bytes ? and I see

that datas are coming even if I dont connect wires to bus. I know that's all are basic infos but I get stuck.

picture1.jpgpicture2.jpg

#include "fsl_debug_console.h"
#include "fsl_mcan.h"
#include "board.h"
#include "pin_mux.h"
#include <stdbool.h>
/*******************************************************************************
* Definitions
******************************************************************************/

#define MSG_RAM_BASE 0x20010000U
#define RX_FIFO0_OFS 0x10U
#define TX_BUFFER_OFS 0x20U
/*******************************************************************************
* Variables
******************************************************************************/
volatile bool rxComplete = false;
mcan_rx_buffer_frame_t rxFrame;
/*******************************************************************************
* Code
******************************************************************************/
void CAN0_IRQ0_IRQHandler(void)
{
MCAN_ClearStatusFlag(CAN0, CAN_IR_RF0N_MASK);
MCAN_ReadRxFifo(CAN0, 0, &rxFrame);
rxComplete = true;
}

int main(void)
{
mcan_config_t mcanConfig;
mcan_frame_filter_config_t rxFilter;
mcan_std_filter_element_config_t stdFilter;
mcan_rx_fifo_config_t rxFifo0;
mcan_tx_buffer_config_t txBuffer;
mcan_tx_buffer_frame_t txFrame;

/* Initialize board hardware. */
CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);

/* Set MCAN clock 48/6=8MHz. */
CLOCK_SetClkDiv(kCLOCK_DivCan0Clk, 6U, true);

BOARD_InitPins();
BOARD_BootClockFROHF48M();
BOARD_InitDebugConsole();

MCAN_GetDefaultConfig(&mcanConfig);
mcanConfig.enableCanfdNormal = true;
MCAN_Init(CAN0, &mcanConfig, CLOCK_GetFreq(kCLOCK_MCAN0));

/* Set Message RAM base address and clear to avoid BEU/BEC error. */
MCAN_SetMsgRAMBase(CAN0, MSG_RAM_BASE);
uint32_t *p=(uint32_t *)(MSG_RAM_BASE);
memset(p, 0, TX_BUFFER_OFS + 0x10U);

/* STD filter config. */
rxFilter.address = 0x000;
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_dual;
stdFilter.sfid1 = 0x000U;
stdFilter.sfid2 = 0x002U;
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);

/* Enter normal mode. */
MCAN_EnterNormalMode(CAN0);

while (1)
{
PRINTF("\n Received Frame ID: 0x%x\r\n", rxFrame.id);
PRINTF("Received Frame DATA: ");
while(rxFrame.dlc--)
{
PRINTF("0x%x ", *(rxFrame.data++));
}
}
}

0 Kudos
2,056 Views
jeremyzhou
NXP Employee
NXP Employee

Hi fatih ozen,

Thank you for your interest in NXP Semiconductor products and 
for the opportunity to serve you.
In the SDK library, the CAN demo illustrates how to setup the CAN bus communication between two Can node, and it uses the CAN0.
And you can learn the more information about the API of CAN module in the attachment.
Hope it helps.
Have a great day,

TIC

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

2,056 Views
fatihozen
Contributor IV

Hi jeremyzhou,

I did sth but now have a new problem, I see some datas, receiving datas in fifo0 but I don't know how to see them in buffer. 
pastedImage_1.png
These are datas I want to see but don't know how to use them. For example I want to use switch case structure according to first data but I don't know how. Could you help me ?


#include "fsl_debug_console.h"
#include "fsl_mcan.h"
#include "board.h"

#include "pin_mux.h"
#include <stdbool.h>

#define EXAMPLE_MCAN_IRQHandler CAN0_IRQ0_IRQHandler
#define EXAMPLE_MCAN_IRQn CAN0_IRQ0_IRQn
#define EXAMPLE_MCAN CAN0
#define MCAN_CLK_FREQ CLOCK_GetFreq(kCLOCK_MCAN0)
#define STDID_OFFSET 18U
#define MSG_RAM_BASE 0x20010000U
#define STD_FILTER_OFS 0x0
#define RX_FIFO0_OFS 0x100U//0x10U
#define TX_BUFFER_OFS 0x20U
int8_t count;
uint8_t RB[8];
/*******************************************************************************
* Prototypes
******************************************************************************/

/*******************************************************************************
* Variables
******************************************************************************/
volatile bool rxComplete = false;
mcan_rx_buffer_frame_t rxFrame;

mcan_fifo_transfer_t rxXfer;
mcan_handle_t mcanHandle;
/*******************************************************************************
* Code
******************************************************************************/

void CAN0_IRQ0_IRQHandler(void)
{
MCAN_ClearStatusFlag(EXAMPLE_MCAN, CAN_IR_RF0N_MASK);
MCAN_ReadRxFifo(EXAMPLE_MCAN, 0, &rxFrame);
// MCAN_ReadRxBuffer(CAN0, 18U, &rxFrame);
rxComplete = true;
/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
exception return operation might vector to incorrect interrupt */
#if defined __CORTEX_M && (__CORTEX_M == 4U)
__DSB();
#endif
}

/*!
* @brief Main function
*/
int main(void)
{
mcan_config_t mcanConfig;
mcan_frame_filter_config_t rxFilter;
mcan_std_filter_element_config_t stdFilter;
mcan_rx_fifo_config_t rxFifo0;
mcan_rx_buffer_config_t rxBuffer;


/* Initialize board hardware. */
/* attach 12 MHz clock to FLEXCOMM0 (debug console) */
CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);

/* Set MCAN clock 48/6=8MHz. */
CLOCK_SetClkDiv(kCLOCK_DivCan0Clk, 22U, true);

BOARD_InitPins();
// BOARD_BootClockFROHF48M();
BOARD_BootClockPLL180M();
BOARD_InitDebugConsole();

MCAN_GetDefaultConfig(&mcanConfig);
// mcanConfig.enableLoopBackExt = true;
// mcanConfig.enableCanfdNormal = true;
MCAN_Init(EXAMPLE_MCAN, &mcanConfig, MCAN_CLK_FREQ);

/* Set Message RAM base address and clear to avoid BEU/BEC error. */
MCAN_SetMsgRAMBase(EXAMPLE_MCAN, MSG_RAM_BASE);
uint32_t *p=(uint32_t *)(MSG_RAM_BASE);
memset(p, 0, TX_BUFFER_OFS + 0x10U);

/* STD filter config. */
// rxFilter.address = 0x100;
// rxFilter.idFormat = kMCAN_FrameIDStandard;
// rxFilter.listSize = 1U;
// rxFilter.nmFrame = kMCAN_reject0;
// rxFilter.remFrame = kMCAN_rejectFrame;
// MCAN_SetFilterConfig(EXAMPLE_MCAN, &rxFilter);

stdFilter.sfec = kMCAN_storeinFifo0;
// stdFilter.sft = kMCAN_dual;
// stdFilter.sfid1 = 0x002U;
// stdFilter.sfid2 = 0x000U;
MCAN_SetSTDFilterElement(EXAMPLE_MCAN, &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(EXAMPLE_MCAN, &rxFifo0);


// rxBuffer.address = RX_FIFO0_OFS;;
// rxBuffer.datafieldSize = kMCAN_8ByteDatafield;
// MCAN_SetRxBufferConfig(EXAMPLE_MCAN, &rxBuffer);

/* Enable RX fifo0 new message interrupt using interrupt line 0. */
MCAN_EnableInterrupts(EXAMPLE_MCAN, 0, CAN_IE_RF0NE_MASK);
EnableIRQ(CAN0_IRQ0_IRQn);

/* Enter normal mode. */
MCAN_EnterNormalMode(EXAMPLE_MCAN);


while (1)
{
while(!rxComplete)
{
}
PRINTF("ID: %3x", rxFrame.id >> 18);
PRINTF(" DATA: ");
count = 9U;
while(--count)
{
PRINTF("0x%x ", *(rxFrame.data++));
}
while(++count < 9U)
{
rxFrame.data--;
}
PRINTF("\r\n");


}
}

0 Kudos
2,056 Views
jeremyzhou
NXP Employee
NXP Employee
I'm not very clear with your qustion, whether you want to recognize the particularr frame via checking the first byte in its format.
If yes, it's eaisy to do it, as the recevied frame will be stored via the MCAN_ReadRxFifo function in the CAN0_IRQ0_IRQHandler function.

Have a great day,
TIC

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos
1,025 Views
williamcarlisle
Contributor II
With this code CAN0_IRQ0_IRQHandler never gets a call. I have a breakpoint in there and it never gets hit.
0 Kudos
2,056 Views
fatihozen
Contributor IV

Hi jeremyzhou,

I know my questions are simple but I'm trying to achieve the goal. According to code below I wait to see some output if any byte in frame is 0xa. But I am missing something I don't know. 

while(!rxComplete)
{
}
PRINTF("ID: %3x", rxFrame.id >> 18);
PRINTF(" DATA: ");
count = 9U;
while(--count)
{
PRINTF("0x%x ", *(rxFrame.data++));

}


while(++count < 9U)
{
rxFrame.data--;
}

if(rxFrame.data[0] == 0xa)
{PRINTF("1112");}
if(rxFrame.data[1] == 0xa)
{PRINTF("1113");}
if(rxFrame.data[2] == 0xa)
{PRINTF("1114");}
if(rxFrame.data[3] == 0xa)
{PRINTF("1115");}
if(rxFrame.data[4] == 0xa)
{PRINTF("1116");}
if(rxFrame.data[5] == 0xa)
{PRINTF("1117");}
if(rxFrame.data[6] == 0xa)
{PRINTF("1118");}
if(rxFrame.data[7] == 0xa)
{PRINTF("1119");}

PRINTF("\r\n");


}

pastedImage_2.png

According to this output I did or understand something wrong. Could you tell me what is the missing point ?

0 Kudos
2,056 Views
jeremyzhou
NXP Employee
NXP Employee

Hi fatih ozen,

Thanks for your reply.

Giving a try the following code.

while(!rxComplete)
{
}

if(rxFrame.data[0] == 0xa)
{PRINTF("1112");}
if(rxFrame.data[1] == 0xa)
{PRINTF("1113");}
if(rxFrame.data[2] == 0xa)
{PRINTF("1114");}
if(rxFrame.data[3] == 0xa)
{PRINTF("1115");}
if(rxFrame.data[4] == 0xa)
{PRINTF("1116");}
if(rxFrame.data[5] == 0xa)
{PRINTF("1117");}
if(rxFrame.data[6] == 0xa)
{PRINTF("1118");}
if(rxFrame.data[7] == 0xa)
{PRINTF("1119");}

PRINTF("\r\n");

}

PRINTF("ID: %3x", rxFrame.id >> 18);
PRINTF(" DATA: ");
count = 9U;
while(--count)
{
PRINTF("0x%x ", *(rxFrame.data++));

}




Have a great day,
TIC

 

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos
2,056 Views
fatihozen
Contributor IV

Hi jeremyzhou‌,

I know what datas I should see on my side on canbus. There is a problem again. When I use semihost console datas have expected values. In second byte(column) I must see all zeros.But if I use UART console I see there some non-zero values. What does cause this ?
pastedImage_1.jpgpastedImage_2.jpg

0 Kudos
2,057 Views
fatihozen
Contributor IV

It is okay now. I defined new array and matched it with rxFrame.data. It is working now.
for(int a=0;a<8;a++) {mydata[a] = rxFrame.data[a];}
Code is below for someone stucks here. Thanks jeremyzhou

#include "fsl_debug_console.h"
#include "fsl_mcan.h"
#include "board.h"
#include "pin_mux.h"
#include <stdbool.h>
/*******************************************************************************
* Definitions
******************************************************************************/
#define EXAMPLE_MCAN_IRQHandler CAN0_IRQ0_IRQHandler
#define EXAMPLE_MCAN_IRQn CAN0_IRQ0_IRQn
#define EXAMPLE_MCAN CAN0
#define MCAN_CLK_FREQ CLOCK_GetFreq(kCLOCK_MCAN0)
#define STDID_OFFSET 18U
#define MSG_RAM_BASE 0x20010000U
#define STD_FILTER_OFS 0x0
#define RX_FIFO0_OFS 0x10U
#define TX_BUFFER_OFS 0x20U
/*******************************************************************************
* Prototypes
******************************************************************************/

/*******************************************************************************
* Variables
******************************************************************************/
volatile bool rxComplete = false;
mcan_rx_buffer_frame_t rxFrame;
mcan_fifo_transfer_t rxXfer;
mcan_handle_t mcanHandle;
/*******************************************************************************
* Code
******************************************************************************/

void CAN0_IRQ0_IRQHandler(void)
{
MCAN_ClearStatusFlag(EXAMPLE_MCAN, CAN_IR_RF0N_MASK);
MCAN_ReadRxFifo(EXAMPLE_MCAN, 0, &rxFrame);
rxComplete = true;
/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
exception return operation might vector to incorrect interrupt */
#if defined __CORTEX_M && (__CORTEX_M == 4U)
__DSB();
#endif
}

int main(void)
{
mcan_config_t mcanConfig;
mcan_frame_filter_config_t rxFilter;
mcan_std_filter_element_config_t stdFilter;
mcan_rx_fifo_config_t rxFifo0;

/* Initialize board hardware. */
/* attach 12 MHz clock to FLEXCOMM0 (debug console) */
CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);

/* Set MCAN clock 48/6=8MHz. */
CLOCK_SetClkDiv(kCLOCK_DivCan0Clk, 6U, true);

BOARD_InitPins();
BOARD_BootClockFROHF48M();
BOARD_InitDebugConsole();

MCAN_GetDefaultConfig(&mcanConfig);
MCAN_Init(EXAMPLE_MCAN, &mcanConfig, MCAN_CLK_FREQ);

/* Set Message RAM base address and clear to avoid BEU/BEC error. */
MCAN_SetMsgRAMBase(EXAMPLE_MCAN, MSG_RAM_BASE);
uint32_t *p=(uint32_t *)(MSG_RAM_BASE);
memset(p, 0, TX_BUFFER_OFS + 0x10U);

/* STD filter config. */
rxFilter.address = 0x0;
rxFilter.idFormat = kMCAN_FrameIDStandard;
rxFilter.listSize = 1U;
rxFilter.nmFrame = kMCAN_reject0;
rxFilter.remFrame = kMCAN_rejectFrame;
MCAN_SetFilterConfig(EXAMPLE_MCAN, &rxFilter);

stdFilter.sfec = kMCAN_storeinFifo0;
MCAN_SetSTDFilterElement(EXAMPLE_MCAN, &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(EXAMPLE_MCAN, &rxFifo0);

/* Enable RX fifo0 new message interrupt using interrupt line 0. */
MCAN_EnableInterrupts(EXAMPLE_MCAN, 0, CAN_IE_RF0NE_MASK);
EnableIRQ(CAN0_IRQ0_IRQn);

/* Enter normal mode. */
MCAN_EnterNormalMode(EXAMPLE_MCAN);

void test(void){
if(mydata[0] == 10) {PRINTF(" 0");} else {PRINTF(" -");}
}

while (1)
{
for(int a=0;a<8;a++) {mydata[a] = rxFrame.data[a];}
PRINTF("ID: %x", rxFrame.id >> 18);
PRINTF(" DATA: ");
for(int a=0;a<8;a++) {PRINTF(" %d",mydata[a]);}
test();
PRINTF("\r\n");
}
}

1,031 Views
williamcarlisle
Contributor II

This really isn't much help to anyone stuck on this. There are lots of errors when trying to build and undefined variables.

0 Kudos
2,056 Views
fatihozen
Contributor IV

Hello jeremyzhou‌,
Thanks for reply.
The following code is not doing what I want to. I am not sure I can reach datas via  " rxFrame.data[0-8] ".

0 Kudos