FLEXCAN-TransferReceiveNonBlocking quickly fails to generate a callback function after initializatio

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

FLEXCAN-TransferReceiveNonBlocking quickly fails to generate a callback function after initializatio

跳至解决方案
447 次查看
Bo_yun
Contributor I

    Hello, I would like to use flexcan on a development board based on imx 8mp. During the process, I referred to the routine "evkmimx8mp flexcan_interrupt_transfer". Then make modifications based on this routine. Since we did not use CANFD, I have removed the code related to CANFD from the program. The modified code is as follows.
    There is a problem now that if CAN_init() is executed immediately, CAN_send() can be executed to successfully send CAN messages (i.e. enter the callback function). If CAN_send() is executed a few seconds after CAN_init(), the message cannot be sent. The return value of FLEXCAN-TransferSendNonBlocking shows normal execution, indicating that the callback function can no longer be entered.
    I added the flexcan code based on Hello World, and I suspect that the interrupt set by CAN in the initialization function was quickly restored. However, there is no other interrupt set in the program, so I would like to ask what is the reason for this? And how to solve it, thank you

#define FLCAN1 FLEXCAN1
#define CAN1_CLK_FREQ                                                                    \
    (CLOCK_GetPllFreq(kCLOCK_SystemPll1Ctrl) / (CLOCK_GetRootPreDivider(kCLOCK_RootFlexCan1)) / \
     (CLOCK_GetRootPostDivider(kCLOCK_RootFlexCan1)))

#define USE_IMPROVED_TIMING_CONFIG_CAN1 (1U)
#define RX_MESSAGE_BUFFER_NUM_CAN1 (9)
#define TX_MESSAGE_BUFFER_NUM_CAN1 (8)
#define DLC_CAN1 (8)
 
flexcan_handle_t flexcan1Handle;            
flexcan_mb_transfer_t txXfer_can1, rxXfer_can1;       
flexcan_frame_t txFrame_can1, rxFrame_can1;
uint32_t txIdentifier = 0x321;
uint32_t rxIdentifier = 0x123;
uint8_t txData_can1[8] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};

volatile bool txComplete_can1 = false;
volatile bool rxComplete_can1 = false;
volatile bool wakenUp    = false;

 
static FLEXCAN_CALLBACK(flexcan_callback)
{
    PRINTF("mmmmmmmmmmmmmmmmmmmmm");
    switch (status)
    {
        case kStatus_Success:
            
            PRINTF("CAN message sent successfully.\n");
            break;

        case kStatus_FLEXCAN_RxIdle: 
            PRINTF("CAN Rx idle.\r\n");
            if (RX_MESSAGE_BUFFER_NUM_CAN1 == result)
            {
                rxComplete_can1 = true;
            }
            else
            {
                PRINTF("CAN Rx error.\n");
            }
            break;

        case kStatus_FLEXCAN_TxIdle:
            PRINTF("CAN Tx idle.\r\n");
            if (TX_MESSAGE_BUFFER_NUM_CAN1 == result)
            {
                txComplete_can1 = true;
            }
            else
            {
                PRINTF("CAN Tx error.\n");
            }
            break;
       
        case kStatus_FLEXCAN_TxBusy:
            
            PRINTF("CAN Tx busy.\n");
            break;

        case kStatus_FLEXCAN_ErrorStatus:
            
            PRINTF("CAN error status.\n");
            break;

        default:
            PRINTF("Unknown status: %d\n", status);
            break;
    }
}

 
void CAN_Init(void)
{  
    CLOCK_SetRootMux(kCLOCK_RootFlexCan1, kCLOCK_FlexCanRootmuxSysPll1);
    CLOCK_SetRootDivider(kCLOCK_RootFlexCan1, 2U, 5U);                   
   
 
    flexcan_config_t flexcan1Config;
    FLEXCAN_GetDefaultConfig(&flexcan1Config);
    flexcan1Config.bitRate=50000U;

 
    flexcan_timing_config_t timing1_config;  
    memset(&timing1_config, 0, sizeof(flexcan_timing_config_t));
    if (FLEXCAN_CalculateImprovedTimingValues(FLCAN1, flexcan1Config.bitRate, CAN1_CLK_FREQ, &timing1_config))
    {
        memcpy(&(flexcan1Config.timingConfig), &timing1_config, sizeof(flexcan_timing_config_t));
    }

   
    FLEXCAN_Init(FLCAN1, &flexcan1Config, CAN1_CLK_FREQ);
    FLEXCAN_TransferCreateHandle(FLCAN1, &flexcan1Handle, flexcan_callback, NULL);      
    FLEXCAN_SetRxMbGlobalMask(FLCAN1, FLEXCAN_RX_MB_STD_MASK(rxIdentifier, 0, 0));

    
    flexcan_rx_mb_config_t mbConfig_can1; 
    mbConfig_can1.format = kFLEXCAN_FrameFormatStandard;
    mbConfig_can1.type   = kFLEXCAN_FrameTypeData;
    mbConfig_can1.id     = FLEXCAN_ID_STD(rxIdentifier);

    FLEXCAN_SetRxMbConfig(FLCAN1, RX_MESSAGE_BUFFER_NUM_CAN1, &mbConfig_can1, true);
    FLEXCAN_SetTxMbConfig(FLCAN1, TX_MESSAGE_BUFFER_NUM_CAN1, true);

    
    // FLEXCAN_EnableInterrupts(FLEXCAN1, kFLEXCAN_TxWarningInterruptEnable | kFLEXCAN_RxWarningInterruptEnable);
}
 
 
void CAN_Send(void)
{

    txData_can1[0]++;

    txFrame_can1.id     = FLEXCAN_ID_STD(txIdentifier);
    txFrame_can1.format = (uint8_t)kFLEXCAN_FrameFormatStandard;       
    txFrame_can1.type   = (uint8_t)kFLEXCAN_FrameTypeData;             
    txFrame_can1.length = (uint8_t)DLC_CAN1;
    txFrame_can1.dataWord0 = CAN_WORD0_DATA_BYTE_0(txData_can1[0]) | CAN_WORD0_DATA_BYTE_1(txData_can1[1]) |
                        CAN_WORD0_DATA_BYTE_2(txData_can1[2]) | CAN_WORD0_DATA_BYTE_3(txData_can1[3]);
    txFrame_can1.dataWord1 = CAN_WORD1_DATA_BYTE_4(txData_can1[4]) | CAN_WORD1_DATA_BYTE_5(txData_can1[5]) |
                        CAN_WORD1_DATA_BYTE_6(txData_can1[6]) | CAN_WORD1_DATA_BYTE_7(txData_can1[7]);
    txXfer_can1.mbIdx = (uint8_t)TX_MESSAGE_BUFFER_NUM_CAN1;         

    txXfer_can1.frame = &txFrame_can1;                               
    PRINTF("dddddddddd\r\n");
    status_t status=FLEXCAN_TransferSendNonBlocking(FLCAN1, &flexcan1Handle, &txXfer_can1);     
    if (status != kStatus_Success) {
        PRINTF("Failed to start non-blocking transfer: %d\n", status);
    } else {
        PRINTF("Non-blocking transfer started successfully.\n");
    }

    while (!txComplete_can1)
    {
       
    }
    txComplete_can1 = false;
    PRINTF("tx word0 = 0x%x\r\n", txFrame_can1.dataWord0);
    PRINTF("tx word1 = 0x%x\r\n", txFrame_can1.dataWord1);
}
0 项奖励
回复
1 解答
432 次查看
Bio_TICFSL
NXP TechSupport
NXP TechSupport

Hello,

You better try the Demo sample that comes with linux BSP, it initialize your board and transfer the data. please check it:

https://www.nxp.com/design/design-center/software/embedded-software/i-mx-software/embedded-linux-for...

Regards

 

在原帖中查看解决方案

0 项奖励
回复
2 回复数
433 次查看
Bio_TICFSL
NXP TechSupport
NXP TechSupport

Hello,

You better try the Demo sample that comes with linux BSP, it initialize your board and transfer the data. please check it:

https://www.nxp.com/design/design-center/software/embedded-software/i-mx-software/embedded-linux-for...

Regards

 

0 项奖励
回复
414 次查看
Bo_yun
Contributor I

Thank you very much for your suggestion. But we plan to drive CAN communication on the 8mp M-core. Previously, the demo "evkmimx8mp flexcan_interrupt_transfer" was obtained from SDK (2.15), but after being rewritten, it was placed in our own project and resulted in the inability to enter the callback function

0 项奖励
回复