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.

TMS570LC43x mibspi dma: blocks are received with bit loss, data shifted to the left

Other Parts Discussed in Thread: HALCOGEN

Hello,

we have a problem with our mipspi dma code.

I had another question related to this that got resolved, but i open a new thred, because i can upload our updated code. Link to old thread for backtracking: e2e.ti.com/.../1872323

We managed to send blocks and they are received, but the data is shifted to the left by 1 to 4 bits, depending on the chosen baudrate.
When we set the baudrate in HALCoGen to 125 KHz, the data is shifted by one bit, at 2000 KHz it is shifted by 4 bits. So i assume that some buffer is not fast enough and misses the first bits that are sent. But we could not find out, where this loss initially starts. Could you please have a look on our code and help us? Our code is in user_mibspi.c and the HALCoGen code is in HL_mibspi.c an HL_sys_dma.c.

Here is our ccs-project in a 7z archive:https://e2e.ti.com/cfs-file/__key/communityserver-discussions-components-files/312/6320.avionik.7z

  • Hi Philipp,
    Today is a US holiday. I will take at look of your project tomorrow.
  • Hi Philipp,
    Can you please tell me your hardware setup?
  • Hi Philipp,

      I see some issues with your code. Let me pick DMA_MIBSPI5_RX as a example. The DMA_MIBSPI5_RX is DMA_CH3 according to your #define. So when you call dmaSetChEnable(DMA_MIBSPI5_RX, DMA_HW) you are enabling channel 3 of the DMA module. However, in the call to mibspiDmaConfig(mibspiREG5, DMA_MIBSPI5_RX, 0, 1) you are mapping the TX to request line 0 and RX to request line 1. The MiBSPI5 request 1 is actually the DMA request 30 to the DMA module for which by default also channel 30 of the DMA module, not channel 3. See below excerpt from the datasheet.

    dmaSetCtrlPacket(DMA_MIBSPI1_RX, g_dmaCTRLPKT1_RX);
    dmaSetCtrlPacket(DMA_MIBSPI1_TX, g_dmaCTRLPKT1_TX);
    //MIBSPI2
    dmaSetCtrlPacket(DMA_MIBSPI2_RX, g_dmaCTRLPKT2_RX);
    dmaSetCtrlPacket(DMA_MIBSPI2_TX, g_dmaCTRLPKT2_TX);
    //MIBSPI3
    dmaSetCtrlPacket(DMA_MIBSPI3_RX, g_dmaCTRLPKT3_RX);
    dmaSetCtrlPacket(DMA_MIBSPI3_TX, g_dmaCTRLPKT3_TX);
    //MIBSPI4
    dmaSetCtrlPacket(DMA_MIBSPI4_RX, g_dmaCTRLPKT4_RX);
    dmaSetCtrlPacket(DMA_MIBSPI4_TX, g_dmaCTRLPKT4_TX);
    //MIBSPI5
    dmaSetCtrlPacket(DMA_MIBSPI5_RX, g_dmaCTRLPKT5_RX);
    dmaSetCtrlPacket(DMA_MIBSPI5_TX, g_dmaCTRLPKT5_TX);

    /* - setting the dma channel to trigger on h/w request */
    dmaSetChEnable(DMA_MIBSPI1_RX, DMA_HW);
    dmaSetChEnable(DMA_MIBSPI1_TX, DMA_HW);
    dmaSetChEnable(DMA_MIBSPI2_RX, DMA_HW);
    dmaSetChEnable(DMA_MIBSPI3_RX, DMA_HW);
    dmaSetChEnable(DMA_MIBSPI4_RX, DMA_HW);
    dmaSetChEnable(DMA_MIBSPI5_RX, DMA_HW);

    /* - configuring the mibspi dma , channel 0 , tx line -0 , rxline -1 */
    /* - refer to the device data sheet dma request source for mibspi tx/rx */
    mibspiDmaConfig(mibspiREG1, DMA_MIBSPI1_TX, 0, 1);
    mibspiDmaConfig(mibspiREG2, DMA_MIBSPI2_RX, 0, 1);
    mibspiDmaConfig(mibspiREG3, DMA_MIBSPI3_RX, 0, 1);
    mibspiDmaConfig(mibspiREG4, DMA_MIBSPI4_RX, 0, 1);
    mibspiDmaConfig(mibspiREG5, DMA_MIBSPI5_RX, 0, 1);

  • Hello Charles,

    thank you for your answer. We fixed this issue by adding

    // SPI1:
    dmaReqAssign(DMA_MIBSPI1_TX, DMA_REQ0);
    dmaReqAssign(DMA_MIBSPI1_RX, DMA_REQ1);
    //SPI2*/
    dmaReqAssign(DMA_MIBSPI2_TX, DMA_REQ3);
    dmaReqAssign(DMA_MIBSPI2_RX, DMA_REQ2);
    //SPI3:
    dmaReqAssign(DMA_MIBSPI3_TX, DMA_REQ15);
    dmaReqAssign(DMA_MIBSPI3_RX, DMA_REQ14);
    //SPI4:
    dmaReqAssign(DMA_MIBSPI4_TX, DMA_REQ25);
    dmaReqAssign(DMA_MIBSPI4_RX, DMA_REQ24);
    //SPI5:
    dmaReqAssign(DMA_MIBSPI5_TX, DMA_REQ31);
    dmaReqAssign(DMA_MIBSPI5_RX, DMA_REQ30);

    Now all dma interrupts work. But the bits are still shifted to the left, and we don't know why.

    For now, our hardware setup is very simple. We just connected mibspi 1 to mibspi 5 in 3 pin mode.

    Later, we will connect 4 boards with mibspi, where every board can broadcast over mibspi 1 and the other 3 boards listen to it on mibspi 2, 3 or 4. Every board will have mibspi 1 connected to it's own mibspi 5, to check transfer quality.
  • Philip,

    Regarding the bit-shift, did you check the clock polarity and phase to make sure they are correct?
    Make sure to look at the diagrams rather than using 'mode 0, 1, 2, 3' as is commonly used because the MibSPI encodings for phase and polarity are different than the commonly used encodings.
  • Hi Philipp,

      Are you comparing between TXDATA1 and RXDATA5 and see the data in RXDATA5 is a shifted version of the TXDATA1?

  • Hello Anthony,

    what exactly do you mean by correct? We communicate inbetween the same board and as far as I understood, the board can handle multiple dataformats. We use it as it is by default:

    /** - Data Format 0 */
    mibspiREG5->FMT0 = (uint32)((uint32)0U << 24U) /* wdelay */
    | (uint32)((uint32)0U << 23U) /* parity Polarity */
    | (uint32)((uint32)0U << 22U) /* parity enable */
    | (uint32)((uint32)0U << 21U) /* wait on enable */
    | (uint32)((uint32)0U << 20U) /* shift direction */
    | (uint32)((uint32)0U << 17U) /* clock polarity */
    | (uint32)((uint32)0U << 16U) /* clock phase */
    | (uint32)((uint32)74U << 8U) /* baudrate prescale */
    | (uint32)((uint32)16U << 0U); /* data word length */

    We initialize all dataformats the same and all MibSPIs are using their dataformat 0, so if MibSPI1 sends with dataformat 0 and MibSPI5 receives with it, i thought there should be no problem.
  • Hello Charles,

    that is exactly our problem. If we send as slow as we can, the data in RXDATA5 is shifted by 1 bit. And the faster we send, the more it is shifted.
  • Hi Philip,

    Sorry I did not understand you were just communicating between two MibSPI.  If that is the case then as long as the data format is the same you should be ok.

    You may want to check that your clock frequency is not too high.


    You can get in trouble when trying to communicate with *other* non-Hercules devices over SPI if you don't look at the timing diagrams but just go by the mode # 0,1,2,3 and try to just use those #'s for phase/polarity.   That's what I was thinking might be your bit shift problem.

  • Hello Charles,

    so we did now everything we could think of. We connected the sending mibSPI1 to an oscilloscope and it is sending just fine. The data is set when the clock goes high and when it goes low it is stable, as it should be. And it is not shifted, we see exactly the data from TXDATA1 in the oscilloscope and in an additional logicanalyser as well.
    We also connected a different SPI device to the receiving mibSPI5. This device sends really slow, with one clockphase of a few milliseconds. And because in slavemode the board has no own clock, it works just fine. The data is received in the board as it is send by the external device (some arduino like board).
    But if we connect the two mibSPIs, the data is shifted again. We think that the mibSPI5 is somehow going to sleep inbetween sending blocks and hence loosing the first bits. But we did not activate it anywhere.
    We could really need some help now, there must be a way to fix this.

    regards,
    Philipp
  • Hi Philipp,
    Sorry, I was out of office today.

    If you use MibSPI1 to send simple data to MibSPI5 without the DMA, will you get proper. I just want to isolate the DMA in the picture. I just feel that the MibSPI5 is somehow not setup properly, i.e. the clock phase or clock edge. Another thing I can think of is the WDELAY. Can you add some WDELAY couunts and enable the feature with the WDEL bit to see if it makes some difference since you said the slow external device will work fine. Another experiment that you can do is to reverse the direction by setting MibSPI5 as master and MibSPI1 as slave. In this case will you get shifted data by MibSPI1?

    BTW, the MibSPI does not go to sleep.
  • Hello Charles,

    deactivating DMA and sending only with mipSPI shifts the data too. Sending from 5 to 1 has no effect either. We now figured out that if we send with a baudrate of 1000 kHz, a Wdelay in mibSPI1 of 5 and Shift LSB first enabled, the data is received unshifted. If we however change the baudrate or Wdelay or the LSB first option to any value, the data gets shifted again.
  • Hi Philipp,
    Since you said without the DMA the problem still persists, please send me the simplest project that I can reproduce on my bench. I will like the version that does not have the DMA and uses just the MibSPI1 to send data to MibSPI5 which you should already have.

    I assume you use the HalCoGen to setup the device and MibSPI1/5. Please also include the .hcg and .dil.
  • Hello Charles,

    thank you again for your help, here is the 7z file:

    /cfs-file/__key/communityserver-discussions-components-files/312/8562.avionik.7z

    I kept all the files from our tem in the project, so it should compile without error.

    Our testfunction testSPI(), which sends one or more packages, is in user_mibspi.c. We deactivated DMA temporarily and send the data manually.

    Regards,

    Philipp

  • Hi Philipp,
    I will take a look.
  • Hi Philipp,
    I didn't quite get anything working yet. Checking the MibSPI5 RAM (starting 0xff0a0200) and I don't see anything for the received data. First of all, I don't think the testcase you send has the DMA disabled. I can see in the MIBSPI_initBus() you still call dmaEnable(). I confirm this by reading the DMA GlbCtrl register in the register window. I can also see that the MibSPI1 RAM (starting at 0xff0e0000) has been loaded with some transmit data. If I disable the DMA by calling the dmaDisable() then I don't see any transmit data at the MibSPI1 RAM. This means you are still using the DMA.

    I also see that in MibSPI1 TgxCtrl registers you don't have any transfer group enabled? You are in Multi-buffer mode, correct? You need to enable the corresponding transfer group. Perhaps this is the reason I don't see any bus activity let along seeing bit loss as you reported.

    I will suggest you to keep the testcase simple for debugging the bit loss issue. It seems like you are encoding CRC checksum as part of the payload. I think it will be simpler to work with simple data. Limit your buffer size to small size first and simple data in a known sequence for easier debug.
  • Hello Charles,

    I'm sorry, we had a worng commit in git, so i sent you the wrong state. This one should work:

    /cfs-file/__key/communityserver-discussions-components-files/312/2335.avionik.7z

  • Hi Philipp,

     I looked at your code and made a small modification like below highlighted in red. I also removed all the calls to mibspiTransfer() inside the MIBSPI_initBus(). With this slight modification I don't see any bit shifted. Attached is also the modified project.

    3857.MibSPI1_MibSPI5_transfer.zip

     

    int MIBSPI_sendData(int tgNr, uint8_t * data) {

    //@todo check if last transmition complete

    //while(!DMASendComplete);

    uint8_t count = 0; // count, goes from 0 to TGSIZE

    for (count = 0; count < D_SIZE; count++) {

    //send one TGSIZE sized Package over DMA

    TXDATA1[count] = 0x00FF & data[count];

    }/** enable TG tramsfer*/

    mibspiSetData(mibspiREG1, 0, TXDATA1);

    // Activate mibspiTransfer

    mibspiTransfer(mibspiREG1, 0);//TODO

    mibspiTransfer(mibspiREG5, 0);// Added to enable MibSPI5

    //@TODO: for opti. use interruot to set variable

    //while (dmaREG->BTCFLAG & 0x00000001 != 1U); // Wait for Block Transfer Complete, for testing

       while(!(mibspiIsTransferComplete(mibspiREG1,0)));//TEst if mibspiGroup is finished

    return MIBSPI_RETURN_OK;

    }