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.
已解决! 转到解答。
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");
}
}
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.
#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++));
}
}
}
Hi fatih ozen,
TIC
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
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.
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");
}
}
Have a great day,
TIC
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
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");
}
According to this output I did or understand something wrong. Could you tell me what is the missing point ?
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!
-----------------------------------------------------------------------------------------------------------------------
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 ?
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");
}
}