Renesas RZG2L

Hi, I want to use canfd internal loopback on Renesas RZG2 because my board doesn´t have CAN transceivers, Any idea or example to use it.

Regards

Parents
  • So, the idea is use it on Cortex-M33, so I configured canfd 1, I'm using this API to change CANFD operation mode, 

    R_CANFD_ModeTransition(&g_canfd1_ctrl,CAN_OPERATION_MODE_NORMAL,CAN_TEST_MODE_LOOPBACK_INERRNAL);

    After write something in the can bus the callback is called but the event is for CAN_EVENT_TX_COMPLETE, my question is Where is the received data on canfd? and Why interrupt is not called when a RX even happen. I attach an image.

  • #include "canfd_thread.h"
    /* CANFD_thread entry function */
    
    #define CAN_EXAMPLE_ID      (0x18ff622)
    
    can_frame_t g_can0_tx_frame;
    can_frame_t g_can0_rx_frame;
    
    can_frame_t g_can1_tx_frame;
    can_frame_t g_can1_rx_frame;
    
    
    volatile canfd_error_t g_err_status = (canfd_error_t) 0;
    
    #define CAN_EXAMPLE_64_BYTES    64
    
    
    const canfd_afl_entry_t p_canfd0_afl[CANFD_CFG_AFL_CH0_RULE_NUM] =
    {
        /* Store all data frames with at least 0 bytes from Extended IDs CAN_EXAMPLE_ID in RX FIFO 0 */
        {
            .id =
            {
                .id         = CAN_EXAMPLE_ID,
                .frame_type = CAN_FRAME_TYPE_DATA,
                .id_mode    = CAN_ID_MODE_EXTENDED
            },
            .mask =
            {
                .mask_id         =  0x1FFFFFFF,
                .mask_frame_type = 1,
                .mask_id_mode    = 1
            },
            .destination =
            {
                .minimum_dlc       = CANFD_MINIMUM_DLC_0,
                .rx_buffer         = CANFD_RX_MB_NONE,
                .fifo_select_flags = (canfd_rx_fifo_t) (CANFD_RX_FIFO_0)
            }
        }
    };
    
    const canfd_afl_entry_t p_canfd1_afl[CANFD_CFG_AFL_CH1_RULE_NUM] =
    {
     /* Store all data frames with at least 0 bytes from Extended IDs CAN_EXAMPLE_ID in RX FIFO 1 */
        {
            .id =
            {
                .id         = CAN_EXAMPLE_ID,
                .frame_type = CAN_FRAME_TYPE_DATA,
                .id_mode    = CAN_ID_MODE_EXTENDED
            },
            .mask =
            {
                .mask_id         =  0x1FFFFFFF,
                .mask_frame_type = 1,
                .mask_id_mode    = 1
            },
            .destination =
            {
                .minimum_dlc       = CANFD_MINIMUM_DLC_0,
                .rx_buffer         = CANFD_RX_MB_NONE,
                .fifo_select_flags = (canfd_rx_fifo_t) (CANFD_RX_FIFO_1)
            }
        }
    };
    
    
    void canfd0_callback (can_callback_args_t * p_args)
    {
        switch (p_args->event)
        {
            case CAN_EVENT_RX_COMPLETE:    /* Receive complete event. */
            {
                /* Read received frame */
                memcpy(&g_can0_rx_frame, p_args->p_frame, sizeof(can_frame_t));
                /* Handle event */
                break;
            }
            case CAN_EVENT_TX_COMPLETE:    /* Transmit complete event. */
            {
                /* Handle event */
    
                break;
            }
            case CAN_EVENT_ERR_GLOBAL:                        /* Global error. */
            case CAN_EVENT_ERR_CHANNEL:                       /* Channel error. */
            {
                /* Get error status */
                g_err_status = (canfd_error_t) p_args->error; /* Check error code with canfd_error_t. */
                /* Handle event */
                break;
            }
            default:
            {
                break;
            }
        }
    }
    
    void canfd1_callback (can_callback_args_t * p_args)
    {
        switch (p_args->event)
        {
            case CAN_EVENT_RX_COMPLETE:    /* Receive complete event. */
            {
                /* Read received frame */
                memcpy(&g_can1_rx_frame, p_args->p_frame, sizeof(can_frame_t));
                /* Handle event */
                break;
            }
            case CAN_EVENT_TX_COMPLETE:    /* Transmit complete event. */
            {
                /* Handle event */
    
                break;
            }
            case CAN_EVENT_ERR_GLOBAL:                        /* Global error. */
            case CAN_EVENT_ERR_CHANNEL:                       /* Channel error. */
            {
                /* Get error status */
                g_err_status = (canfd_error_t) p_args->error; /* Check error code with canfd_error_t. */
                /* Handle event */
                break;
            }
            default:
            {
                break;
            }
        }
    }
    
    
    /* pvParameters contains TaskHandle_t */
    void canfd_thread_entry(void *pvParameters)
    {
        FSP_PARAMETER_NOT_USED (pvParameters);
    
        /* Assert reset signal for CANFD. */
        R_BSP_MODULE_RSTON(FSP_IP_CANFD, 0);
        R_BSP_MODULE_RSTON(FSP_IP_CANFD, 1);
    
        fsp_err_t err;
        err = R_CANFD_Open(&g_canfd0_ctrl, &g_canfd0_cfg);
        err = R_CANFD_Open(&g_canfd1_ctrl, &g_canfd1_cfg);
        /* Handle any errors. This function should be defined by the user. */
        assert(FSP_SUCCESS == err);
    
        /* Switch to external loopback mode */
        err = R_CANFD_ModeTransition(&g_canfd0_ctrl, CAN_OPERATION_MODE_NORMAL, CAN_TEST_MODE_LOOPBACK_INTERNAL);
        err = R_CANFD_ModeTransition(&g_canfd1_ctrl, CAN_OPERATION_MODE_NORMAL, CAN_TEST_MODE_LOOPBACK_INTERNAL);
        //err = R_CANFD_ModeTransition(&g_canfd0_ctrl, CAN_OPERATION_MODE_NORMAL, CAN_TEST_MODE_LOOPBACK_EXTERNAL);
        //err = R_CANFD_ModeTransition(&g_canfd1_ctrl, CAN_OPERATION_MODE_NORMAL, CAN_TEST_MODE_LOOPBACK_EXTERNAL);
        assert(FSP_SUCCESS == err);
    
        /* Configure a frame to write 64 bytes with bitrate switching (BRS) enabled */
        g_can0_tx_frame.id               = CAN_EXAMPLE_ID;
        g_can0_tx_frame.id_mode          = CAN_ID_MODE_EXTENDED;
        g_can0_tx_frame.type             = CAN_FRAME_TYPE_DATA;
        g_can0_tx_frame.data_length_code = CAN_EXAMPLE_64_BYTES;
        g_can0_tx_frame.options          = CANFD_FRAME_OPTION_FD | CANFD_FRAME_OPTION_BRS;
    
        /* Configure a frame to write 64 bytes with bitrate switching (BRS) enabled */
        g_can1_tx_frame.id               = CAN_EXAMPLE_ID;
        g_can1_tx_frame.id_mode          = CAN_ID_MODE_EXTENDED;
        g_can1_tx_frame.type             = CAN_FRAME_TYPE_DATA;
        g_can1_tx_frame.data_length_code = CAN_EXAMPLE_64_BYTES;
        g_can1_tx_frame.options          = CANFD_FRAME_OPTION_FD | CANFD_FRAME_OPTION_BRS;
    
        /* Write some data to the transmit frame */
        for (uint32_t i = 0; i < CAN_DATA_BUFFER_LENGTH; i++)
        {
            if (i % 2 == 0) {
                g_can0_tx_frame.data[i] = (uint8_t) 0xAA;
            }
            else {
                g_can0_tx_frame.data[i] = (uint8_t) 0x55;
            }
        }
        for (uint32_t i = 0; i < CAN_DATA_BUFFER_LENGTH; i++)
        {
            if (i % 2 == 0) {
                g_can1_tx_frame.data[i] = (uint8_t) 0x55;
            }
            else {
                g_can1_tx_frame.data[i] = (uint8_t) 0xAA;
            }
        }
    
        /* Send data on the bus */
        err = R_CANFD_Write(&g_canfd0_ctrl, CANFD_TX_MB_0, &g_can0_tx_frame);
        assert(FSP_SUCCESS == err);
        err = R_CANFD_Write(&g_canfd1_ctrl, CANFD_TX_MB_0, &g_can1_tx_frame);
        assert(FSP_SUCCESS == err);
        /* Wait for a transmit and/or receive callback event */
    
        while (1)
        {
            vTaskDelay (1);
        }
    }
    

    Have a look at this.

    RXFIFO0 and RXFIFO1 have to be configured in the smart configurator.

  • So I tried with this example, but interrupt by CAN_RX_EVENT_COMPLETE never happens even RXFIFO0 and RXFIFO1 are enabled

    Should I configure something else to get an interrupt by a RX event?

Reply Children