HOW TO USE FLEXCAN IN I.MX RT 1052

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

HOW TO USE FLEXCAN IN I.MX RT 1052

1,061 Views
proras
Contributor I

The official SDK FLEXCAN examples does not work properly

/*********main.c**********/

#include "fsl_debug_console.h"

#include "board.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "bsp_flexcan.h"

/*******************************************************************
* Prototypes
*******************************************************************/
uint8_t cnt=0;
uint8_t canbuf[8];
uint8_t rx_canbuf[8];
uint8_t res;

/*******************************************************************
* Code
*******************************************************************/


int main(void)
{

BOARD_ConfigMPU();

BOARD_InitPins();

BOARD_BootClockRUN();
BOARD_InitDebugConsole();

PRINTF("\r\n");
PRINTF("CPU: %d Hz\r\n", CLOCK_GetFreq(kCLOCK_CpuClk));
PRINTF("AHB: %d Hz\r\n", CLOCK_GetFreq(kCLOCK_AhbClk));
PRINTF("SEMC: %d Hz\r\n", CLOCK_GetFreq(kCLOCK_SemcClk));
PRINTF("SYSPLL: %d Hz\r\n", CLOCK_GetFreq(kCLOCK_SysPllClk));
PRINTF("SYSPLLPFD0: %d Hz\r\n", CLOCK_GetFreq(kCLOCK_SysPllPfd0Clk));
PRINTF("SYSPLLPFD1: %d Hz\r\n", CLOCK_GetFreq(kCLOCK_SysPllPfd1Clk));
PRINTF("SYSPLLPFD2: %d Hz\r\n", CLOCK_GetFreq(kCLOCK_SysPllPfd2Clk));
PRINTF("SYSPLLPFD3: %d Hz\r\n", CLOCK_GetFreq(kCLOCK_SysPllPfd3Clk));


uint8_t i=0,j=0;
flexcanInit();
while(1)
{
res=0;
for(i=0;i<8;i++)
{
canbuf[i]=cnt+i;
}
res=CAN2_Send_Msg(canbuf,8);
if(!res)
PRINTF("OK\r\n");
else
PRINTF("False\r\n");

res=CAN2_Receive_Msg(rx_canbuf);
if(res)
{
PRINTF("\r\n");
for(i=0;i<res;i++)
PRINTF("%x",rx_canbuf[i]);
PRINTF("\r\n");
}
}

}

/***********bsp_flexcan.c*********/

#include "fsl_iomuxc.h"
#include "fsl_gpio.h"
#include "bsp_flexcan.h"
#include "fsl_debug_console.h"
#include "clock_config.h"
#include "pin_mux.h"

/* Select 80M clock divided by USB1 PLL (480 MHz) as master flexcan clock source */
#define FLEXCAN_CLOCK_SOURCE_SELECT (2U)
/* Clock divider for master flexcan clock source */
#define FLEXCAN_CLOCK_SOURCE_DIVIDER (3U)
#define CAN_CLK_FREQ ((CLOCK_GetFreq(kCLOCK_Usb1PllClk) / 6) / (FLEXCAN_CLOCK_SOURCE_DIVIDER + 1U))
#define RX_MESSAGE_BUFFER_NUM (9)
#define TX_MESSAGE_BUFFER_NUM (8)
#define TS_CAN CAN2

flexcan_handle_t flexcanHandle;
flexcan_frame_t frame,can2_rxframe;
uint32_t txIdentifier;
uint32_t rxIdentifier;
volatile bool txComplete = false;
volatile bool rxComplete = false;
flexcan_mb_transfer_t txXfer, rxXfer;

void flexcanInit(void)
{
flexcan_config_t flexcanConfig;
flexcan_rx_mb_config_t mbConfig;

txIdentifier = 0x123;
rxIdentifier = 0x123;
CLOCK_SetMux(kCLOCK_CanMux, FLEXCAN_CLOCK_SOURCE_SELECT);
CLOCK_SetDiv(kCLOCK_CanDiv, FLEXCAN_CLOCK_SOURCE_DIVIDER);
/* Get FlexCAN module default Configuration. */
/*
* flexcanConfig.clkSrc = kFLEXCAN_ClkSrcOsc;
* flexcanConfig.baudRate = 1000000U;
* flexcanConfig.maxMbNum = 16;
* flexcanConfig.enableLoopBack = false;
* flexcanConfig.enableSelfWakeup = false;
* flexcanConfig.enableIndividMask = false;
* flexcanConfig.enableDoze = false;
*/
FLEXCAN_GetDefaultConfig(&flexcanConfig);
#if (!defined(FSL_FEATURE_FLEXCAN_SUPPORT_ENGINE_CLK_SEL_REMOVE)) || !FSL_FEATURE_FLEXCAN_SUPPORT_ENGINE_CLK_SEL_REMOVE
flexcanConfig.clkSrc = kFLEXCAN_ClkSrcPeri;
#endif /* FSL_FEATURE_FLEXCAN_SUPPORT_ENGINE_CLK_SEL_REMOVE */
#if (defined(SET_CAN_QUANTUM) && SET_CAN_QUANTUM)
flexcanConfig.timingConfig.phaseSeg1 = PSEG1;
flexcanConfig.timingConfig.phaseSeg2 = PSEG2;
flexcanConfig.timingConfig.propSeg = PROPSEG;
#endif
flexcanConfig.baudRate=500000U;
//flexcanConfig.enableLoopBack = true;

FLEXCAN_Init(TS_CAN, &flexcanConfig, CAN_CLK_FREQ);
FLEXCAN_EnableMbInterrupts(TS_CAN,1<<RX_MESSAGE_BUFFER_NUM); //ʹÄÜRXÏûÏ¢»º³åÖжÏ
//FLEXCAN_TransferCreateHandle(CAN1, &flexcanHandle, flexcan_callback, NULL);
EnableIRQ(CAN2_IRQn);
FLEXCAN_SetRxMbGlobalMask(TS_CAN, FLEXCAN_RX_MB_STD_MASK(rxIdentifier, 0, 0));
mbConfig.format = kFLEXCAN_FrameFormatStandard;
mbConfig.type = kFLEXCAN_FrameTypeData;
mbConfig.id = FLEXCAN_ID_STD(rxIdentifier);

FLEXCAN_SetRxMbConfig(TS_CAN, RX_MESSAGE_BUFFER_NUM, &mbConfig, true);
FLEXCAN_SetTxMbConfig(TS_CAN, TX_MESSAGE_BUFFER_NUM, true);
// while(1)
// {
// frame.id = FLEXCAN_ID_STD(rxIdentifier);
// frame.format = kFLEXCAN_FrameFormatStandard;
// frame.type = kFLEXCAN_FrameTypeData;
// frame.length = 2;
// frame.dataByte0=0x64;
// frame.dataByte1=0x00;
// txXfer.frame = &frame;
// txXfer.mbIdx = TX_MESSAGE_BUFFER_NUM;
// FLEXCAN_TransferSendNonBlocking(TS_CAN, &flexcanHandle, &txXfer);//SendMsg
// PRINTF("TEST1\r\n\r\n");
// while (!txComplete)
// {
// };
// txComplete = false;
// PRINTF("Start to Wait data from Node A\r\n\r\n");
// rxXfer.mbIdx = RX_MESSAGE_BUFFER_NUM;
// rxXfer.frame = &frame;
// FLEXCAN_TransferReceiveNonBlocking(TS_CAN, &flexcanHandle, &rxXfer);
// while (!rxComplete)
// {
// };
// rxComplete = false;
// PRINTF("Rx MB ID: 0x%3x, Rx MB data: 0x%x\r\n", frame.id >> CAN_ID_STD_SHIFT, frame.dataByte0);
// frame.id = FLEXCAN_ID_EXT(0x0ff46f00);
// txXfer.mbIdx = TX_MESSAGE_BUFFER_NUM;
// }

}

static void flexcan_callback(CAN_Type *base, flexcan_handle_t *handle, status_t status, uint32_t result, void *userData)
{
PRINTF("TEST\r\n\r\n");
switch (status)
{
case kStatus_FLEXCAN_RxIdle:
if (RX_MESSAGE_BUFFER_NUM == result)
{
rxComplete = true;
}
break;

case kStatus_FLEXCAN_TxIdle:
if (TX_MESSAGE_BUFFER_NUM == result)
{
txComplete = true;
}
break;

default:
break;
}
}

//CAN2ÖжϷþÎñº¯Êý
void CAN2_IRQHandler(void)
{
if (FLEXCAN_GetMbStatusFlags(TS_CAN,1<<RX_MESSAGE_BUFFER_NUM)) //ÅжÏCAN2µÄRXÐÅÏ¢»º³åÊÇ·ñÊÕµ½Êý¾Ý
{
FLEXCAN_ClearMbStatusFlags(CAN2,1<<RX_MESSAGE_BUFFER_NUM); //Çå³ýÖжϱê־λ
FLEXCAN_ReadRxMb(TS_CAN,RX_MESSAGE_BUFFER_NUM,&can2_rxframe); //¶ÁÈ¡Êý¾Ý
rxComplete=true; //±ê¼Ç¶ÁÈ¡Íê³É
}
__DSB();
}

uint8_t CAN2_Send_Msg(uint8_t* msg,uint8_t len)
{
uint8_t ret=0;

frame.format=kFLEXCAN_FrameFormatStandard; //±ê×¼¸ñʽ
frame.type=kFLEXCAN_FrameTypeData; //Êý¾ÝÖ¡
frame.id=FLEXCAN_ID_STD(0x123); //±ê×¼ID
frame.length=len; //³¤¶È8

//ÉèÖÃÊý¾Ý
frame.dataByte0=msg[0];
frame.dataByte1=msg[1];
frame.dataByte2=msg[2];
frame.dataByte3=msg[3];
frame.dataByte4=msg[4];
frame.dataByte5=msg[5];
frame.dataByte6=msg[6];
frame.dataByte7=msg[7];

if(FLEXCAN_TransferSendBlocking(TS_CAN,TX_MESSAGE_BUFFER_NUM,&frame)==kStatus_Success) ret=0;
else ret=1;

return ret;
}


uint8_t CAN2_Receive_Msg(uint8_t *buf)
{
uint8_t datalen=0;

if(rxComplete==true) 
{
rxComplete=false;

buf[0]=can2_rxframe.dataByte0;
buf[1]=can2_rxframe.dataByte1;
buf[2]=can2_rxframe.dataByte2;
buf[3]=can2_rxframe.dataByte3;
buf[4]=can2_rxframe.dataByte4;
buf[5]=can2_rxframe.dataByte5;
buf[6]=can2_rxframe.dataByte6;
buf[7]=can2_rxframe.dataByte7;
datalen=can2_rxframe.length;
}
else
datalen=0;

return datalen;
}

Labels (1)
0 Kudos
1 Reply

784 Views
jeremyzhou
NXP Employee
NXP Employee

Hi 宇辉 杨,

Thank you for your interest in NXP Semiconductor products and for the opportunity to serve you.
Whether you can describe the phenomenon of the 'issue' in details.
Have a great day,
TIC

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

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos