This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TMS570LS1114: CAN function issue

Part Number: TMS570LS1114


Dears

please help me to check the code as below, my issue is  that IF3 data cannot be synchronized with IF2 !

#include "all_header.h"
#include "system.h"
#include "emif.h"
#include "errata_SSWF021_45.h"
#include "etpwm.h"
#include "sys_dma.h"


#include "reg_etpwm.h"

#include <stdio.h>
#include <string.h>

static uint32_t Received_ID ; /*SD_20210119*/

static uint32 DMA_Comp_Flag;

g_dmaCTRL g_dmaCTRLPKT; /*dma control packet configuration stack*/

#define D_COUNT 8
#define D_SIZE 8

int data;

uint32 cnt = 0;
uint32 error = 0;
uint32 tx_done = 0;
uint32 CpuCount = 0;
uint32 timer0 = 0;


uint8_t tx_data1[D_COUNT] = {1, 2, 3, 4, 4, 3, 2, 1}; /*transmit buffer in sys ram*/
uint8_t tx_data2[D_COUNT] = {1, 3, 5, 7, 9, 11, 13, 15};
uint8_t tx_data3[D_COUNT] = {2, 4, 6, 8, 10, 12, 14, 16};

uint8_t rx_data[D_COUNT] = {0};
uint8_t rx_data1[D_COUNT] = {0}; /*receive buffer in sys ram*/
uint8_t rx_data2[D_COUNT] = {0};
uint8_t rx_data3[D_COUNT] = {0};

void delay(uint32 time);
void dmaConfigCtrlRxPacket(uint32 sadd,uint32 dadd,uint32 dsize);
uint32 checkPackets(uint8 *src_packet,uint8 *dst_packet,uint32 psize);


void dmaGroupANotification(dmaInterrupt_t inttype, uint32 channel)
{
DMA_Comp_Flag = 0x5555AAAA;
}


void delay(uint32 time)
{
int i;

for(i = 0; i < time; i++)
;
}
void main(void)
{
_enable_interrupt_(); /*Enable IRQ interrupt in ARM CPSR register*/
DMA_Comp_Flag = 0xAAAA5555; /* Reset the Flag */

rtiInit();
rtiEnableNotification(rtiNOTIFICATION_COMPARE0);
// rtiDisableNotification(rtiNOTIFICATION_COMPARE0);
_enable_IRQ();
rtiStartCounter(rtiCOUNTER_BLOCK0);

u8gv_tmr_addr = get_tmr_addr();
canInit(); /* initialize can*/
vimInit();

canREG1->CTL |= (uint32)(1<<18); /*enable DMA DE1 for IF1*/
canREG1->CTL |= (uint32)(1<<19); /*enable DMA DE2 for IF2*/
canREG1->CTL |= (uint32)(1<<20); /*Enable DE3 bit in CTL register to trigger DMA when IF3 receives data*/
canREG1->IF3OBS = 0x0000001AU; /* Read ARB, DATA A & B - 8 bytes */
canREG1->IF3UEy[0] = 0x0000002AU; /*Message box of RX 2,4,6 configured for auto update*/


/* - DMA Configuration */
dmaEnable(); /* Enable DMA */
// dmaEnableInterrupt(DMA_CH16, FTC); /*Enable Interrupt after reception of data*/
dmaEnableInterrupt(DMA_CH0, FTC);

// dmaReqAssign(DMA_CH2,17); /*DMA Configuration and Enable DMA:DCAN1 IF1对应DMAREQ[17]*/
// dmaReqAssign(DMA_CH1,6); /*DCAN1 IF2对应DMAREQ[6]*/
dmaReqAssign(DMA_CH0,16); /*DCAN1 IF3对应请求线DMAREQ[16]*/
// canEnableloopback(canREG1, Internal_Lbk);

/* - Populate dma control packets structure */
/* Source Address = IF3 Data register
* Destination = Receive Buffer in Sys RAM
* Length = 1 ( 64bits = 8 * 8 Bytes)
*/
// dmaConfigCtrlRxPacket((uint32)(&tx_data2), (uint32)(&(canREG1->IF1DATx[0])), 1);
dmaConfigCtrlRxPacket((uint32)(&(canREG1->IF3DATx[0])),(uint32)(&rx_data2),1);
// dmaConfigCtrlRxPacket((uint32)(&rx_data2),(uint32)(&(canREG1->IF2DATx[0])),1);

dmaSetCtrlPacket(DMA_CH0, g_dmaCTRLPKT); /*setting dma control packets for transmit*/
// dmaSetCtrlPacket(DMA_CH1, g_dmaCTRLPKT);
// dmaSetCtrlPacket(DMA_CH2, g_dmaCTRLPKT);

dmaSetChEnable(DMA_CH0, DMA_SW); /*CH0使能,IF1填充数据*/
// dmaSetChEnable(DMA_CH1, DMA_SW);


#if 1
while(1)
{
// printf("CAN TX\n");
delay(100000);

DMA_Comp_Flag = 0xAAAA5555; /* Reset the Flag */

canTransmit(canREG1, canMESSAGE_BOX3, (const uint8 *)&tx_data2[0]); /* transmit on can1 */
// canIsTxMessagePending(canREG1, canMESSAGE_BOX3);
CpuCount = canIsTxMessagePending(canREG1, canMESSAGE_BOX3);

// can1LowLevelInterrupt();
// can1HighLevelInterrupt();

while(!canIsRxMessageArrived(canREG1, canMESSAGE_BOX4))
;
dmaFTCAInterrupt();
while(DMA_Comp_Flag != 0x5555AAAA); /* Wait for the DMA interrupt ISR to set the Flag */
canGetData(canREG1, canMESSAGE_BOX4, (uint8 *)&rx_data[0]); /* receive on can1 */
Received_ID = (canREG1->IF3ARB & 0x1FFC0000)>>18;

}
#endif

return 0;
}


void canMessageNotification(canBASE_t *node, uint32_t messageBox)
{

while(!canIsRxMessageArrived(canREG1, canMESSAGE_BOX4))
;

canGetData(canREG1, canMESSAGE_BOX4, (uint8 *)&rx_data[0]);
Received_ID = (canREG1->IF3ARB & 0x1FFC0000)>>18;

/*
switch(rx_data[0])
{
case 13:
data = (rx_data[1] - 0x30) * 1000 + (rx_data[2] - 0x30) * 100 + (rx_data[3] -0x30) * 10 + rx_data[4] - 0x30;
data *= 1.25;
break;
default:
break;
}

etpwmREG1->CMPA = data;

memset(rx_data, 0, sizeof(rx_data));
data = 0;
*/
}

#pragma WEAK(rtiNotification)
void rtiNotification(uint32 notification)
{

/* Reset the Flag */
timer0 ++;
}


void dmaConfigCtrlRxPacket(uint32 sadd,uint32 dadd,uint32 dsize)
{
g_dmaCTRLPKT.SADD = sadd; /* source address */
g_dmaCTRLPKT.DADD = dadd; /* destination address */
g_dmaCTRLPKT.CHCTRL = 0; /* channel control */
g_dmaCTRLPKT.FRCNT = 1; /* frame count */
g_dmaCTRLPKT.ELCNT = dsize; /* element count */
g_dmaCTRLPKT.ELDOFFSET = 0; /* element destination offset */
g_dmaCTRLPKT.ELSOFFSET = 0; /* element source offset */
g_dmaCTRLPKT.FRDOFFSET = 0; /* frame destination offset */
g_dmaCTRLPKT.FRSOFFSET = 0; /* frame source offset */
g_dmaCTRLPKT.PORTASGN = 4; /* port b */
g_dmaCTRLPKT.RDSIZE = ACCESS_64_BIT; /* read size */
g_dmaCTRLPKT.WRSIZE = ACCESS_64_BIT; /* write size */
g_dmaCTRLPKT.TTYPE = FRAME_TRANSFER ; /* transfer type 一个请求触发一帧传输 */
g_dmaCTRLPKT.ADDMODERD = ADDR_FIXED; /* address mode read */
g_dmaCTRLPKT.ADDMODEWR = ADDR_FIXED; /* address mode write */
g_dmaCTRLPKT.AUTOINIT = AUTOINIT_ON; /* autoinit */
}
/* USER CODE END */

  • Hello Cooper,

    Can you please describe your question? I am not able to get the point from your code.

  • Dear Wang:

    When using CAN function, configure IF1 for data sending, IF2 for data receiving, and IF3 for monitoring data;It was found that the IF2 data was updated at the time of receiving, but the data monitored by IF3 remained unchanged,so I do not know what happened.

  • Hello,

    After the data was transmitted from mailbox 3, please check if the IF3x Data registers are updated. 

    When you add a breakpoint in DMA notification function, does the code run to this breakpoint? If not, please check if the VIM channel for DMA interrupt is enabled (VIM channel 33)?

  • dear Wang:

    I want to know , in CAN communication, I configured IF2 as RX, and IF3 used DMA to monitor data. Where are the data sources of these two and what are the differences?

    Why is the data received different (I am running in debug mode, does it matter?)I use two CPUs to send different data A and B, why do I IF2 and IF3 receive different data? One shows receiving data A and the other shows data B
    .In addition, when I run a single step, I can see the received data in the IF2 register, and when I run a continuous run, the data is not displayed in IF2.

  • Dear Wang:

    IF3x Data registers are updated >> answer: I configured the registers : canREG1->IF3UEy[0] = 0x0000002AU;/*Message box of RX 2,4,6 configured for auto update*/

    please check if the VIM channel for DMA interrupt is enabled (VIM channel 33)>> answer: My code could not go into this interrupt, i donot know the reason , this is my code updated as below,please help to check!

    #include "all_header.h"
    #include "system.h"
    #include "emif.h"
    #include "errata_SSWF021_45.h"
    #include "etpwm.h"
    #include "sys_dma.h"
    #include "reg_etpwm.h"
    #include <stdio.h>
    #include <string.h>

    static uint32_t Received_ID ; /*SD_20210119*/
    static uint32 DMA_Comp_Flag;

    g_dmaCTRL g_dmaCTRLPKT; /*dma control packet configuration stack*/

    #define D_COUNT 8
    #define D_SIZE 8

    int data;

    uint32 cnt = 0;
    uint32 error = 0;
    uint32 tx_done = 0;
    uint32 CpuCount = 0;
    uint32 timer0 = 0;

    uint8_t tx_data1[D_COUNT] = {1, 2, 3, 4, 4, 3, 2, 1}; /*transmit buffer in sys ram*/
    uint8_t tx_data2[D_COUNT] = {1, 3, 5, 7, 9, 11, 13, 15};
    uint8_t tx_data3[D_COUNT] = {2, 4, 6, 8, 10, 12, 14, 16};

    uint8_t rx_data[D_COUNT] = {0}; /*receive buffer in sys ram*/
    /*
    uint8_t rx_data1[D_COUNT] = {0};
    uint8_t rx_data2[D_COUNT] = {0};
    uint8_t rx_data3[D_COUNT] = {0};
    */
    void delay(uint32 time);
    void dmaConfigCtrlRxPacket(uint32 sadd,uint32 dadd,uint32 dsize);
    void dmaGroupANotification(dmaInterrupt_t inttype, uint32 channel);
    {
    DMA_Comp_Flag = 0x5555AAAA;
    }

    void delay(uint32 time)
    {
    int i;

    for(i = 0; i < time; i++)
    ;
    }
    void main(void)
    {
    _enable_interrupt_(); /*Enable IRQ interrupt in ARM CPSR register*/
    DMA_Comp_Flag = 0xAAAA5555; /* Reset the Flag */

    u8gv_tmr_addr = get_tmr_addr();
    canInit(); /* initialize can*/

    canREG1->CTL |= (uint32)(1<<20); /*Enable DE3 bit in CTL register to trigger DMA when IF3 receives data*/
    canREG1->IF3OBS = 0x0000001AU; /* Read ARB, DATA A & B - 8 bytes */
    canREG1->IF3UEy[0] = 0x0000002AU; /*Message box of RX 2,4,6 configured for auto update*/

    /* - DMA Configuration */
    dmaEnable(); /* Enable DMA */
    /*======RX DMA======*/
    dmaEnableInterrupt(DMA_CH0, FTC); /* Enable Interrupt after reception of data */
    dmaReqAssign(DMA_CH0,16U); /*assigning dma request: channel-0 with request line - 16 ( DCAN1IF3)*/
    vimEnableInterrupt(33U,SYS_IRQ); /* VIM DMA FTCA:Frame transfer complete*/

    /* - Populate dma control packets structure */
    /* Source Address = IF3 Data register
    * Destination = Receive Buffer in Sys RAM
    * Length = 1 ( 64bits = 8 * 8 Bytes)
    */
    dmaConfigCtrlRxPacket((uint32)(&(canREG1->IF3DATx[0])),(uint32)(&rx_data),1);
    dmaSetCtrlPacket(DMA_CH0, g_dmaCTRLPKT); /*setting dma control packets for transmit*/
    dmaREG->GCHIENAS |= 1<<DMA_CH0; /* enable the channel global interrupt */

    /*======RX DMA END======*/


    #if 1
    while(1)
    {
    // printf("CAN TX\n");
    // delay(10000000); /*0.1us*10000000=1s=1000ms*/

    DMA_Comp_Flag = 0xAAAA5555; /* Reset the Flag */
    canTransmit(canREG1, canMESSAGE_BOX3, (const uint8 *)&tx_data2[0]); /* transmit on can1 */
    dmaFTCAInterrupt();
    while(DMA_Comp_Flag != 0x5555AAAA); /* Wait for the DMA interrupt ISR to set the Flag */

    }
    #endif

    return 0;
    }

    void canMessageNotification(canBASE_t *node, uint32_t messageBox)
    {

    Received_ID = (canREG1->IF3ARB & 0x1FFC0000)>>18;

    /* - setting the dma channel to trigger on S/w request */
    dmaSetChEnable(DMA_CH0, DMA_SW);

    }

    void dmaConfigCtrlRxPacket(uint32 sadd,uint32 dadd,uint32 dsize)
    {
    g_dmaCTRLPKT.SADD = sadd; /* source address */
    g_dmaCTRLPKT.DADD = dadd; /* destination address */
    g_dmaCTRLPKT.CHCTRL = 0; /* channel control */
    g_dmaCTRLPKT.FRCNT = 1; /* frame count */
    g_dmaCTRLPKT.ELCNT = dsize; /* element count */
    g_dmaCTRLPKT.ELDOFFSET = 0; /* element destination offset */
    g_dmaCTRLPKT.ELSOFFSET = 0; /* element source offset */
    g_dmaCTRLPKT.FRDOFFSET = 0; /* frame destination offset */
    g_dmaCTRLPKT.FRSOFFSET = 0; /* frame source offset */
    g_dmaCTRLPKT.PORTASGN = 4; /* port b */
    g_dmaCTRLPKT.RDSIZE = ACCESS_64_BIT; /* read size */
    g_dmaCTRLPKT.WRSIZE = ACCESS_64_BIT; /* write size */
    g_dmaCTRLPKT.TTYPE = FRAME_TRANSFER ; /* transfer type 一个请求触发一帧传输 */
    g_dmaCTRLPKT.ADDMODERD = ADDR_FIXED; /* address mode read */
    g_dmaCTRLPKT.ADDMODEWR = ADDR_FIXED; /* address mode write */
    g_dmaCTRLPKT.AUTOINIT = AUTOINIT_ON; /* autoinit */
    }
    /* USER CODE END */

     

  • Hello Copper,

    IF2 read is to read message object from CAN message RAM to IF2 registers. The source is message object in CAN message RAM, and the destination is IFx registers. The canGetData() function copy the data from IF2 data register to your data array in MCU SRAM.

    IF3 data register is updated automatically with the received message object. The data source address of DMA transfer is IF3 data register, and destination address is your data array in MCU SRAM. 

    When you run single step, did you check the data in IF3 data register? Is the data in IF3 data register different from the data in IF2 data register?

  • I did a test this evening. No issue.

    IF3x data is exactly same as the data transmitted (IF1x Data A&B registers).

  • Please change the element size from 64 to 32

    g_dmaCTRLPKT.RDSIZE = ACCESS_32_BIT; /* read size */
    g_dmaCTRLPKT.WRSIZE = ACCESS_32_BIT; /* write size */
    g_dmaCTRLPKT.TTYPE = FRAME_TRANSFER ; /* transfer type 一个请求触发一帧传输 */
    g_dmaCTRLPKT.ADDMODERD = ADDR_INC1; /* address mode read */
    g_dmaCTRLPKT.ADDMODEWR = ADDR_INC1; /* address mode write */

    and

    change the number of elements:

    dmaConfigCtrlRxPacket((uint32)(&(canREG1->IF3DATx[0])),(uint32)(&rx_data),2);