[TRAVEO2]CAN txCallback

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
hjkwon
Level 1
Level 1
Distributor
First like given First like received First solution authored

The CAN Driver is being tested as a request for the CAN Transmit Confirm function.
As shown in Fig. 1, CAN_TxMsgCallback function was input to txCallback in canCfg, and TCE of IE was set to 1 in Cy_CANFD_Init() as shown in Fig. 2.

Fig1.png

Fig 1. txCallback of CAN Configuration

Fig2.png

Fig 2. Set TCE = 1 in Cy_CANFD_Init()
However, when CAN Transmit was performed, it was confirmed that CAN Signal was normally output, but no Interrupt occurred.
Please check whether the Transmission Completed interrupt is not implemented in SDL yet or the setting method is incorrect. (For reference, the CAN_RxMsgCallback() function is called normally.)
I am attaching the tested code, so please check it.

 

 

 

 

 

 

 

 

 

/***************************************************************************//**
* \file main_cm4.c
*
* \version 1.0
*
* \brief Main example file for CM4
*
********************************************************************************
* \copyright
* Copyright 2016-2020, Cypress Semiconductor Corporation. All rights reserved.
* You may use this file only in accordance with the license, terms, conditions,
* disclaimers, and limitations in the end user license agreement accompanying
* the software package with which this file was provided.
*******************************************************************************/

#include "cy_project.h"
#include "cy_device_headers.h"

#define NON_ISO_OPERATION 1

/* CAN in Use */
#define CY_CANFD_TYPE                   CY_CANFD0_TYPE   
#define CY_CANFD_RX_PORT                CY_CANFD0_RX_PORT
#define CY_CANFD_RX_PIN                 CY_CANFD0_RX_PIN 
#define CY_CANFD_TX_PORT                CY_CANFD0_TX_PORT
#define CY_CANFD_TX_PIN                 CY_CANFD0_TX_PIN 
#define CY_CANFD_RX_MUX                 CY_CANFD0_RX_MUX 
#define CY_CANFD_TX_MUX                 CY_CANFD0_TX_MUX 
#define CY_CANFD_PCLK                   CY_CANFD0_PCLK
#define CY_CANFD_IRQN                   CY_CANFD0_IRQN

static void PortInit(void);
void CanfdInterruptHandler(void);
void CAN_TxMsgCallback(void);
void CAN_RxMsgCallback(bool bRxFifoMsg, uint8_t u8MsgBufOrRxFifoNum, cy_stc_canfd_msg_t* pstcCanFDmsg);
void CAN_RxFifoWithTopCallback(uint8_t u8FifoNum, uint8_t u8BufferSizeInWord, uint32_t* pu32RxBuf);
bool CAN_TxConfirm( cy_pstc_canfd_type_t pstcCanFD );
#if NON_ISO_OPERATION == 1
  static void SetISOFormat(cy_pstc_canfd_type_t canfd);
#endif

/* Port configuration */
typedef struct
{
    volatile stc_GPIO_PRT_t* portReg;
    uint8_t pinNum;
    cy_stc_gpio_pin_config_t cfg;
}stc_pin_config;

/* Standard ID Filter configration */
static const cy_stc_id_filter_t stdIdFilter[] = 
{
    CANFD_CONFIG_STD_ID_FILTER_CLASSIC_RXBUFF(0x010u, 0u),      /* ID=0x010, store into RX buffer Idx0 */
    CANFD_CONFIG_STD_ID_FILTER_CLASSIC_RXBUFF(0x020u, 1u),      /* ID=0x020, store into RX buffer Idx1 */
};

/* Extended ID Filter configration */
static const cy_stc_extid_filter_t extIdFilter[] = 
{
    CANFD_CONFIG_EXT_ID_FILTER_CLASSIC_RXBUFF(0x10010u, 2u),    /* ID=0x10010, store into RX buffer Idx2 */
    CANFD_CONFIG_EXT_ID_FILTER_CLASSIC_RXBUFF(0x10020u, 3u),    /* ID=0x10020, store into RX buffer Idx3 */
};

/* CAN configuration */
cy_stc_canfd_config_t canCfg = 
{
    .txCallback     = CAN_TxMsgCallback, // Unused.
    .rxCallback     = CAN_RxMsgCallback,
    .rxFifoWithTopCallback = NULL, //CAN_RxFifoWithTopCallback,
    .statusCallback = NULL, // Un-supported now
    .errorCallback  = NULL, // Un-supported now

    .canFDMode      = false, // Use standard CAN mode

  #if (CY_USE_PSVP == 1)
    // 24 MHz
    .bitrate        =       // Nominal bit rate settings (sampling point = 75%)
    {
        .prescaler      = 6u - 1u,  // cclk/6, When using 500bps, 1bit = 8tq
        .timeSegment1   = 5u - 1u, // tseg1 = 5tq
        .timeSegment2   = 2u - 1u,  // tseg2 = 2tq
        .syncJumpWidth  = 2u - 1u,  // sjw   = 2tq
    },
  #else
    // 40 MHz
    .bitrate        =       // Nominal bit rate settings (sampling point = 75%)
    {
        .prescaler      = 10u - 1u,  // cclk/10, When using 500bps, 1bit = 8tq
        .timeSegment1   = 5u - 1u, // tseg1 = 5tq
        .timeSegment2   = 2u - 1u,  // tseg2 = 2tq
        .syncJumpWidth  = 2u - 1u,  // sjw   = 2tq
    },
  #endif
    
    .tdcConfig      =       // Transceiver delay compensation, unused.
    {
        .tdcEnabled     = false,
        .tdcOffset      = 0,
        .tdcFilterWindow= 0,
    },
    .sidFilterConfig    =   // Standard ID filter
    {
        .numberOfSIDFilters = sizeof(stdIdFilter) / sizeof(stdIdFilter[0]),
        .sidFilter          = stdIdFilter,
    },
    .extidFilterConfig  =   // Extended ID filter
    {
        .numberOfEXTIDFilters   = sizeof(extIdFilter) / sizeof(extIdFilter[0]),
        .extidFilter            = extIdFilter,
        .extIDANDMask           = 0x1fffffff,   // No pre filtering.
    },
    .globalFilterConfig =   // Global filter
    {
        .nonMatchingFramesStandard = CY_CANFD_REJECT_NON_MATCHING,  // Reject none match IDs
        .nonMatchingFramesExtended = CY_CANFD_REJECT_NON_MATCHING,  // Reject none match IDs
        .rejectRemoteFramesStandard = true, // No remote frame
        .rejectRemoteFramesExtended = true, // No remote frame
    },
    .rxBufferDataSize = CY_CANFD_BUFFER_DATA_SIZE_64,
    .rxFifo1DataSize  = CY_CANFD_BUFFER_DATA_SIZE_8,
    .rxFifo0DataSize  = CY_CANFD_BUFFER_DATA_SIZE_8,
    .txBufferDataSize = CY_CANFD_BUFFER_DATA_SIZE_64,
    .rxFifo0Config    = // RX FIFO0, unused.
    {
        .mode = CY_CANFD_FIFO_MODE_BLOCKING,
        .watermark = 0u,
        .numberOfFifoElements = 0u,
        .topPointerLogicEnabled = false,
    },
    .rxFifo1Config    = // RX FIFO1, unused.
    {
        .mode = CY_CANFD_FIFO_MODE_BLOCKING,
        .watermark = 0u,
        .numberOfFifoElements = 0u,
        .topPointerLogicEnabled = false, // true,
    },
    .noOfRxBuffers  = 4u,
    .noOfTxBuffers  = 4u,
};

/* CAN port configuration */
static const stc_pin_config can_pin_cfg[] =
{
    /* CAN0_2 RX */
    {
        .portReg = CY_CANFD_RX_PORT, 
        .pinNum  = CY_CANFD_RX_PIN,
        {
            .outVal = 0,
            .driveMode = CY_GPIO_DM_HIGHZ,
            .hsiom = CY_CANFD_RX_MUX,
            .intEdge = 0,
            .intMask = 0,
            .vtrip = 0,
            .slewRate = 0,
            .driveSel = 0,
            .vregEn = 0,
            .ibufMode = 0,
            .vtripSel = 0,
            .vrefSel = 0,
            .vohSel = 0,
        }
    },
    /* CAN0_2 TX */
    {
        .portReg = CY_CANFD_TX_PORT,
        .pinNum  = CY_CANFD_TX_PIN,
        {
            .outVal = 1,
            .driveMode = CY_GPIO_DM_STRONG,
            .hsiom = CY_CANFD_TX_MUX,
            .intEdge = 0,
            .intMask = 0,
            .vtrip = 0,
            .slewRate = 0,
            .driveSel = 0,
            .vregEn = 0,
            .ibufMode = 0,
            .vtripSel = 0,
            .vrefSel = 0,
            .vohSel = 0,
        }
    },
};

int main(void)
{
    SystemInit();

    __enable_irq(); /* Enable global interrupts. */

    /* Place your initialization/startup code here (e.g. MyInst_Start()) */
    
    /* Setup CAN clock (cclk).
     * This clock is used as base clock of the CAN communication.
     */
    {
        /* PSVP: In this example, no divid, just enable the clock.-> Use 24MHz (PSVP default PERI clock) as cclk.
           Silicon: Use divider 2 --> 40MHz
         */
        Cy_SysClk_PeriphAssignDivider(CY_CANFD_PCLK, CY_SYSCLK_DIV_8_BIT, 0u);
      #if (CY_USE_PSVP == 1)
        Cy_SysClk_PeriphSetDivider(CY_SYSCLK_DIV_8_BIT, 0u, 0u); // 24 MHz
      #else
        Cy_SysClk_PeriphSetDivider(CY_SYSCLK_DIV_8_BIT, 0u, 1u); // 40 MHz
      #endif
        Cy_SysClk_PeriphEnableDivider(CY_SYSCLK_DIV_8_BIT, 0u);
    }

    /* For PSVP, DeInit to initialize CANFD IP */
    {
        Cy_CANFD_DeInit(CY_CANFD_TYPE);
    }

    /* Initialize CAN ports and the CAN tranceiver. */
    {
        PortInit();
    }

    /* Setup CANFD interrupt */
    {
        cy_stc_sysint_irq_t irq_cfg;
        irq_cfg = (cy_stc_sysint_irq_t){
            .sysIntsrc=CY_CANFD_IRQN, /* Use interrupt LINE0 */
            .intIdx     = CPUIntIdx3_IRQn,
            .isEnabled  = true,
        };
        Cy_SysInt_InitIRQ(&irq_cfg);
	Cy_SysInt_SetSystemIrqVector(irq_cfg.sysIntSrc, CanfdInterruptHandler);
	
        NVIC_SetPriority(CPUIntIdx3_IRQn, 0);
        NVIC_ClearPendingIRQ(CPUIntIdx3_IRQn);
        NVIC_EnableIRQ(CPUIntIdx3_IRQn);
    }

    /* Initialize CAN as CANFD */
    {
        Cy_CANFD_Init(CY_CANFD_TYPE, &canCfg);
    #if NON_ISO_OPERATION == 1
        SetISOFormat(CY_CANFD_TYPE);
    #endif
    }
    /* Now a ch configured as CANFD is working. */

    cy_stc_canfd_msg_t msg = {0};

    msg.canFDFormat = false;
    msg.idConfig.extended = false;
    msg.idConfig.identifier = 0x11;
    msg.dataConfig.dataLengthCode = 8;
    msg.dataConfig.data[0] = 1;
    Cy_CANFD_UpdateAndTransmitMsgBuffer(CY_CANFD_TYPE, 0, &msg);

    for(;;)
    {
        if(CAN_TxConfirm(CY_CANFD_TYPE) == 1)
        {
            msg.dataConfig.data[0] = msg.dataConfig.data[0] + 1;
            Cy_CANFD_UpdateAndTransmitMsgBuffer(CY_CANFD_TYPE, 0, &msg);
        }
    }
}

bool CAN_TxConfirm( cy_pstc_canfd_type_t canfd )
{
    volatile stc_CANFD_CH_M_TTCAN_t*  pstcCanFDChMTTCAN;

    pstcCanFDChMTTCAN = &canfd->M_TTCAN;

    if(pstcCanFDChMTTCAN->unIR.stcField.u1TC == 1)
    {
        /* Clear the Transmission completed flag */
        pstcCanFDChMTTCAN->unIR.stcField.u1TC = 1UL;
        return true;
    }
    else
    {
        return false;
    }
}

#if NON_ISO_OPERATION == 1
static void SetISOFormat(cy_pstc_canfd_type_t canfd)
{
    /* Now a ch configured as CANFD is working. */
    canfd->M_TTCAN.unCCCR.stcField.u1INIT = 1;
    while(canfd->M_TTCAN.unCCCR.stcField.u1INIT != 1);
        /* Cancel protection by setting CCE */
    canfd->M_TTCAN.unCCCR.stcField.u1CCE = 1;
    canfd->M_TTCAN.unCCCR.stcField.u1NISO = 1;

    canfd->M_TTCAN.unCCCR.stcField.u1INIT = 0;
    while(canfd->M_TTCAN.unCCCR.stcField.u1INIT != 0);
}
#endif

/* Initialize CAN regarding pins */
static void PortInit(void)
{
    for (uint8_t i = 0; i < (sizeof(can_pin_cfg) / sizeof(can_pin_cfg[0])); i++)
    {
        Cy_GPIO_Pin_Init(can_pin_cfg[i].portReg, can_pin_cfg[i].pinNum, &can_pin_cfg[i].cfg);
    }
}

/* CANFD reception callback */
void CAN_RxMsgCallback(bool bRxFifoMsg, uint8_t u8MsgBufOrRxFifoNum, cy_stc_canfd_msg_t* pstcCanFDmsg)
{
    /* Just loop back to the sender with +1 ID */
    pstcCanFDmsg->idConfig.identifier += 1u;
    Cy_CANFD_UpdateAndTransmitMsgBuffer
    (
        CY_CANFD_TYPE,
        u8MsgBufOrRxFifoNum,
        pstcCanFDmsg
    );
}

void CAN_TxMsgCallback(void)
{

}

void CAN_RxFifoWithTopCallback(uint8_t u8FifoNum, uint8_t   u8BufferSizeInWord, uint32_t* pu32RxBuf)
{
    /*TODO*/
}

/* CANFD intrerrupt handler */
void CanfdInterruptHandler(void)
{
    /* Just invoking */
    Cy_CANFD_IrqHandler(CY_CANFD_TYPE);
}

/* [] END OF FILE */

 

 

 

 

 

 

 

 

 

0 Likes
1 Solution
hjkwon
Level 1
Level 1
Distributor
First like given First like received First solution authored

I have resolved.

The solution is as follows.

--------------------------------------------

cy_en_canfd_status_t Cy_CANFD_Init(cy_pstc_canfd_type_t pstcCanFD, const cy_stc_canfd_config_t* pstcConfig)
{
    ..........
    
    /* Interrupt Enable */
    ....
    unIE.stcField.u1TCE   = 1; /* Transmission Completed */ //change to 1 
    ....
 
    /*Added for Transmission Interrupt Enable */
    pstcCanFDChMTTCAN->unTXBTIE.u32Register = 0xF;
 
    .....
}
--------------------------

View solution in original post

3 Replies
Apurva_S
Moderator
Moderator
Moderator
100 likes received 500 replies posted 250 solutions authored

Hi @hjkwon 

Please elaborate a little about your setup. Which Traveo T2G device are you using? Which version of SDL are you working with? Are you using any of the evaluation boards or are you using a custom board?

Regards.

0 Likes
hjkwon
Level 1
Level 1
Distributor
First like given First like received First solution authored

Board: Traove EV Board 176 SO & BB

MCU: CYT2BL8

SDL: SDL 7.3.0

Purpose: CAN Test - After CAN data output, I want to check the output with Interrupt.

 

0 Likes
hjkwon
Level 1
Level 1
Distributor
First like given First like received First solution authored

I have resolved.

The solution is as follows.

--------------------------------------------

cy_en_canfd_status_t Cy_CANFD_Init(cy_pstc_canfd_type_t pstcCanFD, const cy_stc_canfd_config_t* pstcConfig)
{
    ..........
    
    /* Interrupt Enable */
    ....
    unIE.stcField.u1TCE   = 1; /* Transmission Completed */ //change to 1 
    ....
 
    /*Added for Transmission Interrupt Enable */
    pstcCanFDChMTTCAN->unTXBTIE.u32Register = 0xF;
 
    .....
}
--------------------------