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.

TMS570LS3137: Use DMA mode to send and receive CAN data.

Part Number: TMS570LS3137

I want to use DMA mode to receive and send CAN data. I configured my program based on an example on the forum. When I sent data to the MCU, the interrupt only entered once, and there was no response when I sent it again. And I cannot configure the buffer size. When I increase the DMA buffer, I only receive one frame of data and enter the interrupt.

  • hello,

    DCAN module has three interface registers: IF1, IF2, and IF3. Those interface registers are used for CPU to read and write from/to the DCAN message RAM. 

    The IF3 register set can automatically be updated with received message objects without the need to initiate the transfer from Message RAM by CPU. The intention of this feature of IF3 is to provide an interface for the DMA to read packets efficiently. So I suggest to use IF3 to receive data if DMA is used.

    To send data with DMA, the DMA transfers data from SRAM memory to CAN IF1/2 data register. In the DMA FTC (frame transfer complete) interrupt service routine,  CPU has to write the message number to command register to start the transfer.

    There are several "gates" before an interrupt request gets to the CPU:

    1. The module that generates an interrupt request has a register to enable each interrupt that it can generate.

    2. Next, the Vectored Interrupt Manager (VIM) has registers to allow an interrupt request from a module to be forwarded to the CPU as per the priority scheme (lower channel number first).

    3. Finally the CPU itself must be configured to respond to the interrupt requests forwarded by the VIM (IRQ or FIQ).

    For DMA configuration, please use frame transfer rather than block transfer, enable DMA FTC interrupt, and enable DMA FTC interrupt in VIM module. 

  • Hello QJ Wang

    The picture shows my register configuration. This configuration refers to a project on the forum. This example is configured as you said. I don't know where there is a problem with this configuration. Caused the problem I mentioned earlier.

    These pictures are CAN1 register configuration

    This picture is IF3 and DMA configuration.

    This picture is the DMA buffer size configuration. I modified the size of element count but it didn't work. It still enters the DMA interrupt after only one frame of data is received.

    This picture is the DMA interrupt function. This function is only triggered once. Sending data to MUC for the second time will not enter this interrupt.

    I don't know what other registers are not configured to cause this situation.

  • In your setup, the message object 2 is configured to update automatically. The DCAN core will check the NewDat flag of msg object 2. If this flag is set, which means msg object received a new message,  the message will be transferred to IF3x  registers.

    If IF3 update is complete, a DMA request is generated. The DMA request stays active until first read access to one of the IF3 registers. The DMA functionality has to be enabled by setting bit DE3 in DCAN Control register. 

    Please double check if DE3 in CTL register is set:

    // Enable DE3 bit in CTL register to trigger DMA when IF3 receives data
     canREG1->CTL |= (1U << 20U);

  • Hello

    On the first picture I set up this register during CAN initialization. Do I need to re-initialize it? I found that the data in the DCAN IF3OBS register is 0x00000018 after entering the interrupt. Is it necessary to read a register to clear this flag so that the interrupt can be triggered again?

    The value of the DCAN IF3OBS register after entering the interrupt.

    Should this register be cleared?What should I do to clear this flag bit?

  • Sorry for skipping the first snapshot yesterday. The IF3OBS will not be cleared after the message is moved to IF3 registers. 

  • Thanks for your help. After the program is modified, the data can be stored in RAM. But now only one data is received and the interrupt will be entered. What should I do if I want to enter the interrupt after receiving multiple data?

    This is my configuration.
    I want to trigger an interrupt after receiving 3 frames of data, but it did not succeed.

  • I don't understand your DMA package settings. Please use the original DMA package settings and change the FRCNT to 3. 

    For CAN TX side, please transmit 3 packages.

  • Thanks for your help,now I can receive data using DMA.

    I have a new question.I use CAN1 and CAN2 to receive data at the same time. CAN1 uses DMA channel 0, frame counts is set to 3, CAN2 uses DMA channel 1, and frame counts is set to 10. I sent 3 frames of data to CAN2, which triggered the interrupt of channel 0. , Is this normal? The two channels seem to influence each other. Shouldn't it be sending 3 frames of data to CAN1 to trigger the interrupt of channel 0, and sending 10 frames of data to CAN2 to trigger the interrupt of channel 1? I think the two channels should not affect each other.

  • And I also encountered similar problems when using SCI's DMA mode to send and receive. I used channel 0 for receiving, frame counts set to 10, channel 1 for sending, and frame counts set to 20. The interrupt of channel 0 is triggered when I send to the 10th byte

  • Then I tried channel 1 and channel 5 again, these two didn't seem to affect each other, I don't know why.

  • Hello,

    CAN1 and CAN2 use different DMA request lines. The message coming to CAN2 doesn't not trigger the DMA transfer of channel 0 used for CAN1.

  • I can get the remaining buffer space of the current channel in the PBACTC register of the DMA. If I open multiple channels at the same time. Is there a way to get the remaining space of the channel buffer that is not currently active?

  • I am sorry I don't fully understand your question. The DMA has its own priority scheme. If fixed priority is used (default), DMA channels are serviced in an ascending order according to the channel number. The lower the channel number, the higher the priority.