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.

DMA and SPI in compatibility mode transfer is worng

Other Parts Discussed in Thread: RM48L952, HALCOGEN

Hello,

I have 2 RM48L952 and I'm trying to implement an SPI interface between them. The master side is OK, the problem is on the slave. I configured the DMA and I see that it receives data, but the data being read is intermittent.

For test purposes I'm trying to send a simple counter to the slave, 10 bytes but when I do the transfer only even bytes are valid. For example: I should receive 00, 01, 02, 03, 04, 05, 06, 07, 08, 09, but I end up receiving 80 00 81 01 82 02 83 03 84 04 85 05.

Here's my configuration:

DMAConfiguration_t g_slaveConfig_DMA_SPI3_RX =
{
    .ISADDR               = 0xFFF7F840U, // spi + 2 CHECK
    .IDADDR               = (uint32_t)&dma_test_buffer[0],
    .FRAME_COUNT          = 150,
    .ELEMENT_COUNT        = 1,
    .CHCTRL_TRANSFER_TYPE = DMA_TRANSFER_TYPE_FRAME,
    .CHCTRL_AMW           = DMA_AMWR_POSTINCREMENT,
    .CHCTRL_AMR           = DMA_AMWR_CONSTANT,
    .CHCTRL_RES           = DMA_RWES_BYTE,//CHECK DMA_RWES_BYTE,
    .CHCTRL_WES           = DMA_RWES_BYTE,//CHECK DMA_RWES_BYTE,
    .CHCTRL_CHAIN         = CMA_CHAIN_NONE,
    .CHCTRL_AIM           = DMA_AIM_DISABLED,
    .TRIGGER_TYPE         = DMA_TRIGGER_TYPE_HARDWARE_TRIGGER
};

        DMAReg->GCTRL  = 0x00000001U; /* reset dma       */
        DMAReg->GCTRL  = 0x00010000U; /* enable dma      */
        DMAReg->GCTRL |= 0x00000300U; /* stop at suspend */

        /* DMA req assign */
        DMAReg->DREQASI0 = (DMAREQ14 << 24U); /* Map request line 14 to Dma channel 0 */

        /* Setup control packet */
        DMAControl->Packet[DMACH0].ISADDR  = g_slaveConfig_DMA_SPI3_RX.ISADDR;
        DMAControl->Packet[DMACH0].IDADDR  = g_slaveConfig_DMA_SPI3_RX.IDADDR;
        DMAControl->Packet[DMACH0].ITCOUNT = (g_slaveConfig_DMA_SPI3_RX.FRAME_COUNT << 16U)
                                           | (g_slaveConfig_DMA_SPI3_RX.ELEMENT_COUNT);

        DMAControl->Packet[DMACH0].CHCTRL  = ((g_slaveConfig_DMA_SPI3_RX.CHCTRL_CHAIN        << 16U)
                                           | (g_slaveConfig_DMA_SPI3_RX.CHCTRL_RES           << 14U)
                                           | (g_slaveConfig_DMA_SPI3_RX.CHCTRL_WES           << 12U)
                                           | (g_slaveConfig_DMA_SPI3_RX.CHCTRL_TRANSFER_TYPE << 8U)
                                           | (g_slaveConfig_DMA_SPI3_RX.CHCTRL_AMR           << 3U)
                                           | (g_slaveConfig_DMA_SPI3_RX.CHCTRL_AMW           << 1U)
                                           | (g_slaveConfig_DMA_SPI3_RX.CHCTRL_AIM));

        DMAControl->Packet[0].EIOFF  = 0;
        DMAControl->Packet[0].FIOFF  = 0;

        /* Channel 0 port assignment to port B */
        DMAReg->PAR0 |= (4U << 28U);

        /* DMA channel enable */
        DMAReg->HWCHENAS =  (1 << DMACH0);

        /* SPI Dma en (bit 16) */
        SPI3Reg->SPIINT0 |= 0x00010000U;

I also tried using 0xFFF7F843U and 0xFFF7F842U(just in case), following the instructions found in this thread

  • I should also mention that I also tried using 0xFFF7F843U and 0xFFF7F842U (just in case) as source as address as suggested in this thread: e2e.ti.com/.../346619
  • Pablo,

    Can you share your project or at least the Halcogen configuration files so I can have a look?
    Also can you specify which version of Halcogen you are using?

  • I am not using Halcogen. I am trying to build a new version, removing some code that i can't share and when I'm done I'll post it here.

    This might take some time
  • 7433.DMA_TEST.zipFinally finished removing the protected code. The code as I left it is just horrible, but it works :)

    Sorry for the messy code, but the creation of this monster was rushed.

  • Pablo,


    I will try your code tomorrow.

    I've attached a test project (using halcogen) that runs on a single device using SPI1 as Master and SPI4 as Slave.

    SPI1 is using polling to send the data while SPI4 is using DMA to move the DATA from the receive buffer to an array.
    Both SPIs are configured in 8bit mode.

    The device clock is extremely low in the test to simplify debug with scope and logic analyzer.

    This code runs on a big endian device, so the only big difference is the source address for the read 8 bit from SPI4.

    I'm using 8 frame of 1 element (8 bit constant address read and 8 bit indexed write).

    Please have a look and let me know if this is helpful.

    7608.TMS570LS1224_SPI1_SPI4_DMA.zip

  • Pablo,

    I was able to compile your project, but I face problem when I run it.
    The code traps in data abort after calling the MapClocks();


    I looked to your code and found something that is not correct for your use case.

            g_slaveDriverSPI3.com->DMACTRL0 = (1 << 31)
                                             |(1 << 15) ;

    You are using MIBSPI3 in legacy mode (SPI3). The DMACTRLx are valid for MIBSPI mode only.
    Later you do:

            /* SPI Dma en (bit 16) */
            g_slaveDriverSPI3.com->SPIINT0 |= 0x00010000U;

    This is correct. As soon as a data is received, a DMA request will be fired.

    Try to correct this and let me know.

  • Ok, I corrected what you told me to, but the exact same error occurs.

    I'll try to put my code on the RM48 HDK. There might be a difference between the board I'm owrking with and the HDK that doesn't let the code run properly

  • I gost frustrated today and disabled DMA and did a SPI transfer using interruptions and saw that it receives the EXACT SAME bytes as it did with DMA. This means that there's something wrong with my SPI configuration (it was working correctly ... I probably messed things up when I tried to implement the DMA, since I changed A LOT of things and created that horrible little monster i sent you).

    After that I enabled all SPI interruption except for the TXINT and started receiving byte by byte and then i verified the flag register to see what was happening, since the interruption being triggered was a low level interrupt, and I programmed the RXINT to be highlevel interruption and the errors to be low level.

    At first I only saw the TX flag being set which was strange since it's not an error and it wasn't being programmed. OK .. this means that there are still some errors in the SPi configuration. I reconfigured some registers and saw what happened. Now things are a little bit crazier ... I can see that the RX overrun flag is being set, but when I read the SPIBUF I don't read the data received from the master .... I read the data being sent by the slave ... so .. another error.

    I'll keep on trying here and sorry for taking so long to answer. These past few days I spent them aoutside the office and only recently returned, so I'm kinda in a hurry to get home which means that I probably inserted a LOT of errors. I replied to your post because, even with these errors because knowing what I'm doing might help you to help me.

    Sorry for the long post