TX can busy after the first transmission

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

TX can busy after the first transmission

506 Views
j_alex
Contributor I

Hello, i am using the following code in order to send and receive via interrupt on the flexCan, with MIMXRT1061CVL5B.

/* Select 60M clock divided by USB1 PLL (480 MHz) as master flexcan clock source */
#define FLEXCAN_CLOCK_SOURCE_SELECT (0U)
/* Clock divider for master flexcan clock source */
#define FLEXCAN_CLOCK_SOURCE_DIVIDER (2U)
/* Get frequency of flexcan clock */
#define EXAMPLE_CAN_CLK_FREQ ((CLOCK_GetFreq(kCLOCK_Usb1PllClk) / / (FLEXCAN_CLOCK_SOURCE_DIVIDER + 1U))
/* Set USE_IMPROVED_TIMING_CONFIG macro to use api to calculates the improved CAN / CAN FD timing values. */
#define USE_IMPROVED_TIMING_CONFIG (1U)
/* Fix MISRA_C-2012 Rule 17.7. */
#define LOG_INFO (void)PRINTF

 

#define RX_MESSAGE_BUFFER_NUM (9)
#define TX_MESSAGE_BUFFER_NUM (10)

flexcan_handle_t flexcanHandle;
volatile bool txComplete = false;
volatile bool rxComplete = false;
volatile bool wakenUp = false;
void * CAN_Pointer;
flexcan_frame_t txFrame, rxFrame;

void CAN1_FLEXCAN_IRQHANDLER(void)
{

#if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
uint64_t flag = 1U;
#else
uint32_t flag = 1U;
#endif

/* If new data arrived. */
if (0U != FLEXCAN_GetMbStatusFlags(CAN1_PERIPHERAL, flag << RX_MESSAGE_BUFFER_NUM))
{
FLEXCAN_ClearMbStatusFlags(CAN1_PERIPHERAL, flag << RX_MESSAGE_BUFFER_NUM);
#if (defined(USE_CANFD) && USE_CANFD)
(void)FLEXCAN_ReadFDRxMb(CAN1_PERIPHERAL, RX_MESSAGE_BUFFER_NUM, &rxFrame);
#else
(void)FLEXCAN_ReadRxMb(CAN1_PERIPHERAL, RX_MESSAGE_BUFFER_NUM, &rxFrame);
#endif
rxComplete = true;
PRINTF("New message received\n");
PRINTF("id 0x%3x\n",rxFrame.id>> CAN_ID_STD_SHIFT);
PRINTF("%x\n",rxFrame.dataByte0);
PRINTF("%x\n",rxFrame.dataByte1);
PRINTF("%x\n",rxFrame.dataByte2);
PRINTF("%x\n",rxFrame.dataByte3);
PRINTF("%x\n",rxFrame.dataByte4);
PRINTF("%x\n",rxFrame.dataByte5);
PRINTF("%x\n",rxFrame.dataByte6);
PRINTF("%x\n",rxFrame.dataByte7);


}
else
{
FLEXCAN_ClearMbStatusFlags(CAN1_PERIPHERAL, flag << TX_MESSAGE_BUFFER_NUM);
txComplete = true;
}
SDK_ISR_EXIT_BARRIER;
}

 

static void CAN1_init(void) {


flexcan_config_t flexcanConfig;
flexcan_rx_mb_config_t mbConfig;
CLOCK_SetMux(kCLOCK_CanMux, FLEXCAN_CLOCK_SOURCE_SELECT);
CLOCK_SetDiv(kCLOCK_CanDiv, FLEXCAN_CLOCK_SOURCE_DIVIDER);
#if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
uint64_t flag = 1U;
#else
uint32_t flag = 1U;
#endif

/* Get FlexCAN module default Configuration. */
FLEXCAN_GetDefaultConfig(&flexcanConfig);
#if defined(EXAMPLE_CAN_CLK_SOURCE)
flexcanConfig.clksrc=EXAMPLE_CAN_CLK_SOURCE;
#endif
FLEXCAN_Init(CAN1_PERIPHERAL, &flexcanConfig, EXAMPLE_CAN_CLK_FREQ);

uint32_t rxIdentifier=0x0422;
/* Set Rx Masking mechanism. */
FLEXCAN_SetRxMbGlobalMask(CAN1_PERIPHERAL, FLEXCAN_RX_MB_STD_MASK(rxIdentifier, 0, 0));

//CAN1_rx_fifo_config.idFilterTable[0] =0x0422;
//CAN1_rx_fifo_config.idFilterTable[1] =0x0423;
//FLEXCAN_SetRxFifoConfig(CAN1_PERIPHERAL, &CAN1_rx_fifo_config, true);

/* Setup Rx Message Buffer. */
mbConfig.format = kFLEXCAN_FrameFormatStandard;
mbConfig.type = kFLEXCAN_FrameTypeData;
mbConfig.id = FLEXCAN_ID_STD(rxIdentifier);
/* Message buffer 9 initialization */
FLEXCAN_SetRxMbConfig(CAN1_PERIPHERAL, 9, & mbConfig, true);
/* Message buffer 10 initialization */
FLEXCAN_SetTxMbConfig(CAN1_PERIPHERAL, 10, true);
FLEXCAN_EnableMbInterrupts(CAN1_PERIPHERAL, flag << RX_MESSAGE_BUFFER_NUM);
FLEXCAN_EnableMbInterrupts(CAN1_PERIPHERAL, flag << TX_MESSAGE_BUFFER_NUM);
/* Enable interrupt CAN1_IRQn request in the NVIC. */
EnableIRQ(CAN1_FLEXCAN_IRQN);

}

 

void CAN1_send(uint8_t data[8]){

flexcan_frame_t frame;
flexcan_mb_transfer_t txXfer;
uint32_t txIdentifier;
txIdentifier=0x01b1;
frame.dataByte0=data[0];
frame.dataByte1=data[1];
frame.dataByte2=data[2];
frame.dataByte3=data[3];
frame.dataByte4=data[4];
frame.dataByte5=data[5];
frame.dataByte6=data[6];
frame.dataByte7=data[7];

frame.id = FLEXCAN_ID_STD(txIdentifier);
frame.format = (uint8_t)kFLEXCAN_FrameFormatStandard;
frame.type = (uint8_t)kFLEXCAN_FrameTypeData;
frame.length = (uint8_t)DLC;

txXfer.mbIdx = (uint8_t)TX_MESSAGE_BUFFER_NUM;
txXfer.frame = &frame;

FLEXCAN_TransferSendNonBlocking(CAN1_PERIPHERAL, &flexcanHandle, &txXfer);
// PRINTF("end of transmission\n");
while(!txComplete)
{
PRINTF("True\n");
};
txComplete=false;
}

 

In my main, I call the init and send functions. My NXP is linked to a PCAN view. First I send a message and it was successfully received in the PCAN view, then I try to send a second message but it fails because the FLEXCAN_TxBusy is at set one. My question is why do I end up in such a state after the first transmission, why after the first success the TX line goes to the busy state all the time. 

 

 

0 Kudos
1 Reply

484 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi @j_alex ,

    Thank you for your interest in the NXP MIMXRT product, I would like to provide service for you.

    Do you test the SDK code for the RT1060 directly?

   I mean this code:

   SDK_2_11_1_EVK-MIMXRT1060\boards\evkmimxrt1060\driver_examples\flexcan\interrupt_transfer

   Please note, this code already add the ID filter function.

  In the previous time, I test it, and I can send and receive the flexCAN data for several times.

 FlexCAN_testresult.png

 

So, I think you can use our SDK flexcan code test it with your peakcan directly.

After it works OK, then you can modify to your own code.

 

Wish it helps you!

Best Regards,

Kerry

0 Kudos