KW36A FlexCAN/CAN2.0A junk data and setup

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

KW36A FlexCAN/CAN2.0A junk data and setup

2,099 Views
C2Pwn
Contributor II

I have a KW36A development board and want to set it up to send and receive data at the typical automotive CAN2.0A with standard and extended IDs at 500kbps. No matter what I do, I can't get the correct speed or data to be sent from the bus. Using the frdmkw36_driver_examples_flexcan_interrupt_transfer and connecting it to a logic analyzer yields an output of junk data, given the default configuration of 100,000 kbps and that being set in the decoder, the output is inconsistent junk as seen in the attached images. Using the guide from the FlexCAN Bit Timing Parameters Setup post on the knowledge base did not help; junk is still being output.  In the attached images, I added my clock configuration, what I tried with the peripheral configuration tool (Same result), and any other information.

Attempted troubleshooting: 

Oscilloscope validates that data IS being sent out, and what speed? Nobody knows. 
I wrote a quick program to see what the bus speed is by getting configuration information from the chip registers and dynamically calculating both the settings to use, and the bus speed, which did yield a valid configuration that attains 500kbps in theory, but in practice only outputs junk again. Below is the code for the two or so functions

/*!
 * @brief Calculate CAN timing parameters dynamically
 */
void calculate_can_timing(uint32_t clockFreq, uint32_t desiredBaudRate, uint32_t *bestPrescaler, uint32_t *bestTQ, uint32_t *bestPropSeg, uint32_t *bestPhaseSeg1, uint32_t *bestPhaseSeg2, uint32_t *bestSjw) {
    uint32_t prescaler, propSeg, phaseSeg1, phaseSeg2, sjw, totalTQ;
    float samplePoint = SAMPLE_POINT_PERCENT / 100.0f;
    uint32_t bestBaud = 0;
    float bestError = MAX_ERROR_PERCENT;

    for (totalTQ = MIN_TQ; totalTQ <= MAX_TQ; totalTQ++) {
        prescaler = (clockFreq / (desiredBaudRate * totalTQ)) - 1;

        if (prescaler > 255 || prescaler < 0) {
            continue;
        }

        phaseSeg1 = (uint32_t)(totalTQ * samplePoint) - 1;
        phaseSeg2 = totalTQ - phaseSeg1 - 1;
        propSeg = phaseSeg1 - 1;
        sjw = (phaseSeg2 < 4) ? phaseSeg2 : 4;

        if (propSeg < 0 || phaseSeg1 < 0 || phaseSeg2 < 1 || sjw < 1 || sjw > 4) {
            continue;
        }

        uint32_t actualBaud = clockFreq / ((prescaler + 1) * totalTQ);
        float errorPercent = ((float)(actualBaud - desiredBaudRate) / desiredBaudRate) * 100;

        if (errorPercent < bestError) {
            *bestPrescaler = prescaler;
            *bestTQ = totalTQ;
            *bestPropSeg = propSeg;
            *bestPhaseSeg1 = phaseSeg1;
            *bestPhaseSeg2 = phaseSeg2;
            *bestSjw = sjw;
            bestBaud = actualBaud;
            bestError = errorPercent;
        }
    }

    PRINTF("Best Configuration: Prescaler=%u, PropSeg=%u, PhaseSeg1=%u, PhaseSeg2=%u, SJW=%u\n", *bestPrescaler, *bestPropSeg, *bestPhaseSeg1, *bestPhaseSeg2, *bestSjw);
}

/*!
 * @brief Validate CAN timing parameters
 */
void validate_can_timing(uint32_t clockFreq, uint32_t desiredBaudRate, uint32_t prescaler, uint32_t totalTQ) {
    uint32_t actualBaudRate = clockFreq / ((prescaler + 1) * totalTQ);

    PRINTF("Validating configuration...\n");
    PRINTF("Expected baud rate: %u kbps\n", desiredBaudRate / 1000);
    PRINTF("Actual baud rate: %u kbps\n", actualBaudRate / 1000);

    if (actualBaudRate == desiredBaudRate) {
        PRINTF("Baud rate matches the expected value.\n");
    } else {
        float errorPercent = ((float)(actualBaudRate - desiredBaudRate) / desiredBaudRate) * 100;
        PRINTF("Baud rate mismatch! Error: %.2f%%\n", errorPercent);
    }
}

/*!
 * @brief CAN initialization function
 */
void CAN_Init(void) {
    uint32_t bestPrescaler = 0, bestTQ = 0, bestPropSeg = 0, bestPhaseSeg1 = 0, bestPhaseSeg2 = 0, bestSjw = 0;

    calculate_can_timing(EXAMPLE_CAN_CLK_FREQ, EXPECTED_BAUD_RATE, &bestPrescaler, &bestTQ, &bestPropSeg, &bestPhaseSeg1, &bestPhaseSeg2, &bestSjw);

    flexcan_config_t canConfig = {
        .clksrc=kFLEXCAN_ClkSrcPeri,
        .baudRate = EXPECTED_BAUD_RATE,
        .maxMbNum = 16U,
        .enableLoopBack = false,
        .enableSelfWakeup = false,
        .enableIndividMask = false,
        .enableDoze = false,
        .timingConfig = {
            .preDivider = bestPrescaler,
            .propSeg = bestPropSeg,
            .phaseSeg1 = bestPhaseSeg1,
            .phaseSeg2 = bestPhaseSeg2,
            .rJumpwidth = bestSjw
        }
    };

    FLEXCAN_Init(EXAMPLE_CAN, &canConfig, EXAMPLE_CAN_CLK_FREQ);
    flexcan_rx_mb_config_t CAN0_rx_mb_config_0 = { .id = FLEXCAN_ID_STD(0x7DF), .format = kFLEXCAN_FrameFormatStandard, .type = kFLEXCAN_FrameTypeData };
    FLEXCAN_SetRxMbConfig(EXAMPLE_CAN, RX_MESSAGE_BUFFER_NUM, &CAN0_rx_mb_config_0, true);
    FLEXCAN_SetTxMbConfig(EXAMPLE_CAN, TX_MESSAGE_BUFFER_NUM, true);

    PRINTF("CAN initialized with dynamically calculated timing.\n");
    validate_can_timing(EXAMPLE_CAN_CLK_FREQ, EXPECTED_BAUD_RATE, bestPrescaler, bestTQ);
}


Below is my "custom" code, that I reused from the example which again yields the same result

#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <assert.h>
#include "fsl_flexcan.h"
#include "fsl_debug_console.h"
#include "board.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "peripherals.h"

/*******************************************************************************
 * Definitions
 ******************************************************************************/
#define EXAMPLE_CAN CAN0
#define EXAMPLE_CAN_CLK_FREQ (CLOCK_GetFreq(kCLOCK_BusClk))  // Bus clock as example
#define RX_MESSAGE_BUFFER_NUM (0)
#define TX_MESSAGE_BUFFER_NUM (1)
#define INTERRUPT_PRIORITY 5
#define EXPECTED_BAUD_RATE 500000U
#define SAMPLE_POINT_PERCENT 87.5
#define MAX_TQ 25
#define MIN_TQ 8
#define MAX_ERROR_PERCENT 1  // Allowable error percentage

/*******************************************************************************
 * Variables
 ******************************************************************************/
flexcan_handle_t flexcanHandle;
volatile bool txComplete = false;
volatile bool rxComplete = false;
flexcan_mb_transfer_t txXfer, rxXfer;
flexcan_frame_t frame;
uint32_t txIdentifier = 0x7DF;  // Standard 11-bit ID

/*******************************************************************************
 * Prototypes
 ******************************************************************************/
void delay_ms(uint32_t ms);
void print_actual_baud_rate(void);
void calculate_can_timing(uint32_t clockFreq, uint32_t desiredBaudRate, uint32_t *bestPrescaler, uint32_t *bestTQ, uint32_t *bestPropSeg, uint32_t *bestPhaseSeg1, uint32_t *bestPhaseSeg2, uint32_t *bestSjw);
void validate_can_timing(uint32_t clockFreq, uint32_t desiredBaudRate, uint32_t prescaler, uint32_t totalTQ);

/*******************************************************************************
 * Code
 ******************************************************************************/
/*!
 * @brief Delay function using busy wait
 */
void delay_ms(uint32_t ms) {
    uint32_t cycles = (CLOCK_GetFreq(kCLOCK_CoreSysClk) / 1000) * ms;
    for (uint32_t i = 0; i < cycles; ++i) {
        __NOP();  // No operation to waste time
    }
}

/*!
 * @brief FlexCAN Call Back function
 */
static void flexcan_callback(CAN_Type *base, flexcan_handle_t *handle, status_t status, uint32_t result, void *userData) {
    PRINTF("\n[Callback] Entering FlexCAN callback function.\n");

    // Check for unhandled status and log error
    if (status != kStatus_FLEXCAN_TxIdle && status != kStatus_FLEXCAN_RxIdle) {
        PRINTF("[Callback] Unhandled status: 0x%08X. Possible error occurred.\n", status);

        // Read the ESR1 register to diagnose the error
        uint32_t esr1 = FLEXCAN_GetStatusFlags(base);
        PRINTF("[Callback] ESR1 register: 0x%08X\n", esr1);

        // Handle Bus-Off and other errors
        if (esr1 & CAN_ESR1_BOFFINT_MASK) {
            PRINTF("[Callback] Bus-Off detected. Attempting to recover...\n");
            FLEXCAN_Enable(base, false);
            FLEXCAN_Enable(base, true);
            FLEXCAN_ClearStatusFlags(base, CAN_ESR1_BOFFINT_MASK);
            PRINTF("[Callback] Bus-Off recovery initiated.\n");
        }
        FLEXCAN_ClearStatusFlags(base, esr1);
    }

    // Handle successful transmission
    if (status == kStatus_FLEXCAN_TxIdle) {
        PRINTF("[Callback] Transmission completed for message buffer: %d.\n", result);
        txComplete = true;
    }

    // Handle successful reception
    if (status == kStatus_FLEXCAN_RxIdle) {
        PRINTF("[Callback] Reception completed for message buffer: %d.\n", result);
        rxComplete = true;
    }

    PRINTF("[Callback] Exiting FlexCAN callback function.\n\n");
}

/*!
 * @brief Calculate CAN timing parameters dynamically
 */
void calculate_can_timing(uint32_t clockFreq, uint32_t desiredBaudRate, uint32_t *bestPrescaler, uint32_t *bestTQ, uint32_t *bestPropSeg, uint32_t *bestPhaseSeg1, uint32_t *bestPhaseSeg2, uint32_t *bestSjw) {
    uint32_t prescaler, propSeg, phaseSeg1, phaseSeg2, sjw, totalTQ;
    float samplePoint = SAMPLE_POINT_PERCENT / 100.0f;
    uint32_t bestBaud = 0;
    float bestError = MAX_ERROR_PERCENT;

    for (totalTQ = MIN_TQ; totalTQ <= MAX_TQ; totalTQ++) {
        prescaler = (clockFreq / (desiredBaudRate * totalTQ)) - 1;

        if (prescaler > 255 || prescaler < 0) {
            continue;
        }

        phaseSeg1 = (uint32_t)(totalTQ * samplePoint) - 1;
        phaseSeg2 = totalTQ - phaseSeg1 - 1;
        propSeg = phaseSeg1 - 1;
        sjw = (phaseSeg2 < 4) ? phaseSeg2 : 4;

        if (propSeg < 0 || phaseSeg1 < 0 || phaseSeg2 < 1 || sjw < 1 || sjw > 4) {
            continue;
        }

        uint32_t actualBaud = clockFreq / ((prescaler + 1) * totalTQ);
        float errorPercent = ((float)(actualBaud - desiredBaudRate) / desiredBaudRate) * 100;

        if (errorPercent < bestError) {
            *bestPrescaler = prescaler;
            *bestTQ = totalTQ;
            *bestPropSeg = propSeg;
            *bestPhaseSeg1 = phaseSeg1;
            *bestPhaseSeg2 = phaseSeg2;
            *bestSjw = sjw;
            bestBaud = actualBaud;
            bestError = errorPercent;
        }
    }

    PRINTF("Best Configuration: Prescaler=%u, PropSeg=%u, PhaseSeg1=%u, PhaseSeg2=%u, SJW=%u\n", *bestPrescaler, *bestPropSeg, *bestPhaseSeg1, *bestPhaseSeg2, *bestSjw);
}

/*!
 * @brief Validate CAN timing parameters
 */
void validate_can_timing(uint32_t clockFreq, uint32_t desiredBaudRate, uint32_t prescaler, uint32_t totalTQ) {
    uint32_t actualBaudRate = clockFreq / ((prescaler + 1) * totalTQ);

    PRINTF("Validating configuration...\n");
    PRINTF("Expected baud rate: %u kbps\n", desiredBaudRate / 1000);
    PRINTF("Actual baud rate: %u kbps\n", actualBaudRate / 1000);

    if (actualBaudRate == desiredBaudRate) {
        PRINTF("Baud rate matches the expected value.\n");
    } else {
        float errorPercent = ((float)(actualBaudRate - desiredBaudRate) / desiredBaudRate) * 100;
        PRINTF("Baud rate mismatch! Error: %.2f%%\n", errorPercent);
    }
}

/*!
 * @brief CAN initialization function
 */
void CAN_Init(void) {
    uint32_t bestPrescaler = 0, bestTQ = 0, bestPropSeg = 0, bestPhaseSeg1 = 0, bestPhaseSeg2 = 0, bestSjw = 0;

    calculate_can_timing(EXAMPLE_CAN_CLK_FREQ, EXPECTED_BAUD_RATE, &bestPrescaler, &bestTQ, &bestPropSeg, &bestPhaseSeg1, &bestPhaseSeg2, &bestSjw);

    flexcan_config_t canConfig = {
        .clksrc=kFLEXCAN_ClkSrcPeri,
        .baudRate = EXPECTED_BAUD_RATE,
        .maxMbNum = 16U,
        .enableLoopBack = false,
        .enableSelfWakeup = false,
        .enableIndividMask = false,
        .enableDoze = false,
        .timingConfig = {
            .preDivider = bestPrescaler,
            .propSeg = bestPropSeg,
            .phaseSeg1 = bestPhaseSeg1,
            .phaseSeg2 = bestPhaseSeg2,
            .rJumpwidth = bestSjw
        }
    };

    FLEXCAN_Init(EXAMPLE_CAN, &canConfig, EXAMPLE_CAN_CLK_FREQ);
    flexcan_rx_mb_config_t CAN0_rx_mb_config_0 = { .id = FLEXCAN_ID_STD(0x7DF), .format = kFLEXCAN_FrameFormatStandard, .type = kFLEXCAN_FrameTypeData };
    FLEXCAN_SetRxMbConfig(EXAMPLE_CAN, RX_MESSAGE_BUFFER_NUM, &CAN0_rx_mb_config_0, true);
    FLEXCAN_SetTxMbConfig(EXAMPLE_CAN, TX_MESSAGE_BUFFER_NUM, true);

    PRINTF("CAN initialized with dynamically calculated timing.\n");
    validate_can_timing(EXAMPLE_CAN_CLK_FREQ, EXPECTED_BAUD_RATE, bestPrescaler, bestTQ);
}

/*!
 * @brief Main function
 */
int main(void) {
    BOARD_InitBootPins();
    BOARD_InitBootClocks();
    BOARD_InitDebugConsole();

    PRINTF("[Main] Initializing FlexCAN...\n");

    EnableIRQ(CAN0_IRQn);
    NVIC_SetPriority(CAN0_IRQn, INTERRUPT_PRIORITY);

    CAN_Init();

    FLEXCAN_TransferCreateHandle(EXAMPLE_CAN, &flexcanHandle, flexcan_callback, NULL);
    FLEXCAN_SetRxMbGlobalMask(EXAMPLE_CAN, FLEXCAN_RX_MB_STD_MASK(txIdentifier, 0, 0));

    FLEXCAN_ClearMbStatusFlags(EXAMPLE_CAN, 1U << RX_MESSAGE_BUFFER_NUM);

    frame.id = 0x7DF;
    frame.format = kFLEXCAN_FrameFormatStandard;
    frame.type = kFLEXCAN_FrameTypeData;
    frame.length = 8;
    frame.dataWord0 = 0x02010000;
    frame.dataWord1 = 0x00000000;

    txXfer.mbIdx = TX_MESSAGE_BUFFER_NUM;
    txXfer.frame = &frame;
    PRINTF("[Main] Sending CAN frame...\n");
    FLEXCAN_TransferSendNonBlocking(EXAMPLE_CAN, &flexcanHandle, &txXfer);

    while (!txComplete) { delay_ms(1); }
    txComplete = false;

    rxXfer.mbIdx = RX_MESSAGE_BUFFER_NUM;
    rxXfer.frame = &frame;
    FLEXCAN_TransferReceiveNonBlocking(EXAMPLE_CAN, &flexcanHandle, &rxXfer);

    while (!rxComplete) { delay_ms(1); }
    rxComplete = false;

    if (frame.id == FLEXCAN_ID_STD(txIdentifier) && frame.dataWord0 == 0xF35B39BD && frame.dataWord1 == 0xD5865D3C) {
        PRINTF("CAN frame received successfully!\n");
    } else {
        PRINTF("CAN frame mismatch! Transmission or reception failed.\n");
        assert(false && "CAN frame mismatch");
    }

    delay_ms(500);
    return 0;
}


What I want to achieve is to properly be able to read and write to standard CAN 2.0A used in most vehicles. Any help would be extremely appreciated as I have been stuck; perhaps even my CAN transceiver is broken. Attached is also my PulseView session in case anybody would like to point out an issue in my setup.

Tags (4)
0 Kudos
Reply
9 Replies

1,870 Views
Itzel_UV
NXP Employee
NXP Employee

Hi,

 

In order to establish the baud rate FD, you could use the formula that is described on this post. It goes something like this:

Itzel_UV_0-1727383747024.png

 

On the FlexCAN Bit Timing Calculation guide the flexcanConfig  will have modified the clock on the

kFLEXCAN_ClkSrcOsc, baudRate=500000 and baudrateFD=3200000, in order to achieve the baud rate of 500kHz.

 

To have it on the CAN 2.0A, you don't have to make any modifications, it's already set by default on the CAN 2.0A, if you desire to modify this you could check the post of how to modify it.

 

Hope the answer finds you well. Come back if there's more questions.

 

Regards,

Itzel.

0 Kudos
Reply

1,912 Views
Itzel_UV
NXP Employee
NXP Employee

Hello,

 

From your last reply I understood that there is no trouble anymore to have the 500kbps. Could you explain what is you are referring as "The chip is giving undefined behavior".

 

Could you describe better the actual situation?

 

Regards,

Itzel.

0 Kudos
Reply

1,889 Views
C2Pwn
Contributor II
I cant seem to get the chip to emit a valid, detectable 500k baud CAN signal, nor can I get it to read a valid, detectable 500k baud CAN signal. No matter what prescaler, timesegments, and SJW I use, it just refuses to work. My goal is to interact with CAN 2.0A (Classic CAN), how would I set up my chip to do this? The example project for the SDK uses FlexCAN with FD, and is at 1000000 baud.
0 Kudos
Reply

1,964 Views
Itzel_UV
NXP Employee
NXP Employee

Hello,

 

Could you tell me please, the baud rate that you got on practice measured from your logical analyzer? I can't appreciate well on the previews post that you attached. 

 

Also, we recommend modifying the example directly with the defines and configuration files. Using Configtools could modify some files that are critical when working with wireless devices.

 

Hopping you're answer. 

 

Regards,

Itzel

 

0 Kudos
Reply

1,922 Views
C2Pwn
Contributor II

The baud rate varied, please check the new reply giving an update on the issue. I can send valid messages but receiving them with the same config fails, despite making 100% sure that the signal generated by the second node IS 500k baud and works. 

0 Kudos
Reply

2,019 Views
Itzel_UV
NXP Employee
NXP Employee

Hello,

 

From what I'm understanding you want to get to run a FlexCAN 2.0A that is fixed on the 500kbps. Could you try making only the modifications to run it at the kbps wanted, taking on consideration the same guide mention on your own post.

 

To know about the speed to validate that the data is being sent, you could use the FlexCAN Bit Timming Calculation guide, you could find it here.

 

Keep us update of the results that you are having.

 

Regards,

Itzel

0 Kudos
Reply

1,924 Views
C2Pwn
Contributor II

I managed to figure out half the problem. The biggest error was that I had no secondary node giving an ACK on sending a message. However, I am now unable to configure it for 500kbps to sniff automotive CAN. My bus clock is at 32mhz yet no matter which valid configuration I give it, it constantly throws errors


********* FLEXCAN Listener Node *********
Message format: Standard (11 bit id)
Listening for incoming CAN messages.
*****************************************

Callback: Error status detected on the CAN bus. Checking error flags...
Error: General Error Flag is set. Checking detailed error flags...
Error: CAN bus stuffing error detected.
Error: CAN bus form error detected.
Error: CAN bus CRC error detected.

static void flexcan_callback(CAN_Type *base, flexcan_handle_t *handle, status_t status, uint32_t result, void *userData)
{

	switch (status)
    {
        case kStatus_FLEXCAN_TxBusy:
            PRINTF("Callback: Tx Message Buffer is busy. Message Buffer: %d\r\n", result);
            break;

        case kStatus_FLEXCAN_TxIdle:
            if (TX_MESSAGE_BUFFER_NUM == result)
            {
                txComplete = true;
                PRINTF("Callback: Transmission completed on Tx Message Buffer %d\r\n", result);
            }
            else
            {
                PRINTF("Callback: Transmission completed on unexpected Message Buffer %d\r\n", result);
            }
            break;

        case kStatus_FLEXCAN_TxSwitchToRx:
            PRINTF("Callback: Remote Message sent, Message Buffer %d switched to receive mode.\r\n", result);
            break;

        case kStatus_FLEXCAN_RxBusy:
            PRINTF("Callback: Rx Message Buffer %d is busy.\r\n", result);
            break;

        case kStatus_FLEXCAN_RxIdle:
            if (RX_MESSAGE_BUFFER_NUM == result)
            {
                rxComplete = true;
                PRINTF("Callback: Message received on Rx Message Buffer %d\r\n", result);
            }
            else
            {
                PRINTF("Callback: Received on unexpected Message Buffer %d\r\n", result);
            }
            break;

        case kStatus_FLEXCAN_RxOverflow:
            PRINTF("Callback: Rx Message Buffer %d overflowed. Data was lost.\r\n", result);
            break;

        case kStatus_FLEXCAN_ErrorStatus:
        {
            PRINTF("Callback: Error status detected on the CAN bus. Checking error flags...\r\n");

            // Retrieve the error flags
            uint32_t errorFlags = FLEXCAN_GetStatusFlags(base);

            if (errorFlags & kFLEXCAN_TxWarningIntFlag)
            {
                PRINTF("Error: Tx Warning Interrupt Flag is set.\r\n");
            }
            if (errorFlags & kFLEXCAN_RxWarningIntFlag)
            {
                PRINTF("Error: Rx Warning Interrupt Flag is set.\r\n");
            }
            if (errorFlags & kFLEXCAN_BusOffIntFlag)
            {
                PRINTF("Error: Bus Off Flag is set. CAN controller is in bus-off state.\r\n");
                // Recover from bus-off if needed
            }
            if (errorFlags & kFLEXCAN_ErrorFlag)
            {
                PRINTF("Error: General Error Flag is set. Checking detailed error flags...\r\n");

                // Detailed error flags
                if (errorFlags & kFLEXCAN_StuffingError)
                {
                    PRINTF("Error: CAN bus stuffing error detected.\r\n");
                }
                if (errorFlags & kFLEXCAN_FormError)
                {
                    PRINTF("Error: CAN bus form error detected.\r\n");
                }
                if (errorFlags & kFLEXCAN_CrcError)
                {
                    PRINTF("Error: CAN bus CRC error detected.\r\n");
                }
                if (errorFlags & kFLEXCAN_AckError)
                {
                    PRINTF("Error: CAN bus acknowledgment error detected.\r\n");
                }
                if (errorFlags & kFLEXCAN_Bit0Error)
                {
                    PRINTF("Error: CAN bus Bit 0 error detected.\r\n");
                }
                if (errorFlags & kFLEXCAN_Bit1Error)
                {
                    PRINTF("Error: CAN bus Bit 1 error detected.\r\n");
                }
            }

            // Clear error flags after logging
            FLEXCAN_ClearStatusFlags(base, errorFlags);

            break;
        }

        case kStatus_FLEXCAN_UnHandled:
            PRINTF("Callback: Unhandled interrupt occurred.\r\n");
            break;

        default:
            PRINTF("Callback: Unknown status code: 0x%x, Message Buffer: %d\r\n", status, result);
            break;
    }
}

 

My setup is as such


const flexcan_config_t CAN0_config = {
  .clksrc=kFLEXCAN_ClkSrcOsc,
  .baudRate = 500000UL,
  .baudRateFD = 2000000UL,
  .maxMbNum = 16U,
  .enableLoopBack = false,
  .enableSelfWakeup = false,
  .enableIndividMask = false,
  .enableDoze = false,
  .timingConfig = {
    .preDivider = 3,
    .propSeg = 1,
    .phaseSeg1 = 3,
    .phaseSeg2 = 2,
    .rJumpwidth = 1
  }
};
/* Message buffer 0 configuration structure */
const flexcan_rx_mb_config_t CAN0_rx_mb_config_0 = {
  .id = FLEXCAN_ID_STD(0UL),
  .format = kFLEXCAN_FrameFormatStandard,
  .type = kFLEXCAN_FrameTypeData
};


No matter what I try, the chip just refuses to accept the config, despite me SEEING that I can send out a valid 500k baud CAN packet that my signal analyzer can decode. The chip is giving undefined behavior.

0 Kudos
Reply

2,008 Views
C2Pwn
Contributor II

I do indeed want to get the FlexCAN driver to function with CAN 2.0A at 500kbps. As for what you mean by "only the modifications to run it at the kbps wanted", I am a bit confused. Be aware that I tried using a standard setup via the peripheral tool as well as hardcoding the configuration details about the baud rate. Calculating it after setting it results in a speed that appears to be 500kbps, but in practice, it is not as seen on the logic analyzer. My code also runs this check automatically as a sanity check, as seen here

void validate_can_timing(uint32_t clockFreq, uint32_t desiredBaudRate, uint32_t prescaler, uint32_t totalTQ) {
    uint32_t actualBaudRate = clockFreq / ((prescaler + 1) * totalTQ);

    PRINTF("Validating configuration...\n");
    PRINTF("Expected baud rate: %u kbps\n", desiredBaudRate / 1000);
    PRINTF("Actual baud rate: %u kbps\n", actualBaudRate / 1000);

    if (actualBaudRate == desiredBaudRate) {
        PRINTF("Baud rate matches the expected value.\n");
    } else {
        float errorPercent = ((float)(actualBaudRate - desiredBaudRate) / desiredBaudRate) * 100;
        PRINTF("Baud rate mismatch! Error: %.2f%%\n", errorPercent);
    }
}


The issue I seem to be seeing is that within the driver, the moment the transmit flag is sent, it starts blasting out junk messages that make no sense (We can see a trace of this in our error log)

What should I do?

0 Kudos
Reply

2,056 Views
C2Pwn
Contributor II

For additional context, here are my callback errors

[Callback] Exiting callback function.
[Callback] Entering callback function.
[Callback] Status: 5310, Result: 0x248d1a
[Callback] Error Status Register (ESR1): 0x24051a
[Callback] CAN Error Interrupt!
[Callback] Fault Confinement error!
[Callback] Rx Warning!
[Callback] Default case: Unhandled status.
[Callback] Exiting callback function.
[Callback] Entering callback function.
[Callback] Status: 5310, Result: 0x240592
[Callback] Error Status Register (ESR1): 0x248d92
[Callback] CAN Error Interrupt!
[Callback] Fault Confinement error!
[Callback] Rx Warning!
[Callback] Default case: Unhandled status.
[Callback] Exiting callback function.
[Callback] Entering callback function.
[Callback] Status: 5310, Result: 0x248d1a
[Callback] Error Status Register (ESR1): 0x248d1a
[Callback] CAN Error Interrupt!
[Callback] Fault Confinement error!
[Callback] Rx Warning!
[Callback] Default case: Unhandled status.
[Callback] Exiting callback function.
[Callback] Entering callback function.
[Callback] Status: 5310, Result: 0x248d92
[Callback] Error Status Register (ESR1): 0x248d92
[Callback] CAN Error Interrupt!
[Callback] Fault Confinement error!
[Callback] Rx Warning!
[Callback] Default case: Unhandled status.
[Callback] Exiting callback function.
[Callback] Entering callback function.
[Callback] Status: 5310, Result: 0x248d1a
[Callback] Error Status Register (ESR1): 0x24051a
[Callback] CAN Error Interrupt!
[Callback] Fault Confinement error!
[Callback] Rx Warning!
[Callback] Default case: Unhandled status.
[Callback] Exiting callback function.
[Callback] Entering callback function.
[Callback] Status: 5310, Result: 0x24051a
[Callback] Error Status Register (ESR1): 0x248d1a
[Callback] CAN Error Interrupt!
[Callback] Fault Confinement error!
[Callback] Rx Warning!
[Callback] Default case: Unhandled status.
[Callback] Exiting callback function.
[Callback] Entering callback function.
[Callback] Status: 5310, Result: 0x248d92
[Callback] Error Status Register (ESR1): 0x248d92
[Callback] CAN Error Interrupt!
[Callback] Fault Confinement error!
[Callback] Rx Warning!
[Callback] Default case: Unhandled status.
[Callback] Exiting callback function.
[Callback] Entering callback function.
[Callback] Status: 5310, Result: 0x24051a
[Callback] Error Status Register (ESR1): 0x248d1a
[Callback] CAN Error Interrupt!
[Callback] Fault Confinement error!
[Callback] Rx Warning!
[Callback] Default case: Unhandled status.
[Callback] Exiting callback function.
[Callback] Entering callback function.
[Callback] Status:
0 Kudos
Reply