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.

TM4C129 SSI1/uDMA Potential Errata

Other Parts Discussed in Thread: TM4C129ENCZAD

I'm working on a custom board utilizing two custom board featuring a TM4C129ENCZAD. The Tiva interfaces with another microcontroller via two SPI buses (SSI0 and SSI1). For TM4C129 is configured as a slave using mode 0 and with a 6.25Mbit clock rate. I configured the first bus (SSI0) to use uDMA for both RX and TX and it works great. When I duplicated my efforts for the second bus however things are very diffferent. They both have their own DMA channels but it seems when I go to enable UDMA_CHANNEL_SSI1TX it changes all the settings in the SSI registers. I provided two screenshots, one before and another after where you can see this happen. Any help would be much apprecated.

Thank you.

  • I am a bit confused, you said you wanted to use 2 busses, SS0 and SS2, but then you configure the SS1 for the second bus

    You're enabling the SS1 after the SS0 right?

    The SS0TX and SS1TX has the same DMA chanel so that may be the quase of erratic behavior, see a part of the table here:

  • I apologize that was a typo, I'm trying to use SSI0 and SSI1 not SSI2. I have chanels 10/11 (SSI0) and 24/25 (SSI1) set up on the primarys by calling uDMAChannelAssign.

  • could you please post the code you use for DMA initialization and configuration? 

    Edit: and also the SSi trigger config?

  • // At this point the SSI1 peripheral is already enabled and the pins are correctly
    // configured. Here we initialize the peripheral and make sure it's in a known state.
    SysCtlPeripheralReset(SYSCTL_PERIPH_SSI1); while(!SysCtlPeripheralReady(SYSCTL_PERIPH_SSI1)); SSIConfigSetExpClk(LEG1_SPI_BASE, systemClock, SSI_FRF_MOTO_MODE_0, SSI_MODE_SLAVE, LEG1_SPI_SPEED, 8); SSIEnable(LEG1_SPI_BASE);
    uDMAChannelAssign(UDMA_CH24_SSI1RX); uDMAChannelAttributeDisable(UDMA_CHANNEL_SSI1RX, UDMA_ATTR_ALL); uDMAChannelAttributeEnable(UDMA_CHANNEL_SSI1RX, UDMA_ATTR_USEBURST); uDMAChannelControlSet(UDMA_CHANNEL_SSI1RX | UDMA_PRI_SELECT, UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARB_4);
    uDMAChannelAssign(UDMA_CH25_SSI1TX); uDMAChannelAttributeDisable(UDMA_CHANNEL_SSI1TX, UDMA_ATTR_ALL); uDMAChannelAttributeEnable(UDMA_CHANNEL_SSI1TX, UDMA_ATTR_USEBURST); uDMAChannelControlSet(UDMA_CHANNEL_SSI1TX | UDMA_PRI_SELECT, UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARB_4); // At this point an event has taken place which indicates to me a SPI transfer from the master is coming. // I clean out the Rx FIFO (we know nothing more is being transfered at this point in time) uint32_t dummy[8]; uint32_t count = SSIDataGetNonBlocking(LEG1_SPI_BASE, &dummy[0]);
    SSIDMAEnable(LEG1_SPI_BASE, SSI_DMA_RX | SSI_DMA_TX);
    // We're actually packing this up into a UDP datagram so we grab a pointer to the // MAC descriptor. uint8_t * ptr = (uint8_t *)g_psTxDescriptor[g_ui32TxDescIndex].pvBuffer1;
    // sizeof(acoustic_t) = 852B uDMAChannelTransferSet(UDMA_CHANNEL_SSI1TX | UDMA_PRI_SELECT, UDMA_MODE_BASIC, (void *)&buffy[0], (void *)(LEG1_SPI_BASE + SSI_O_DR), sizeof(acoustic_t)); uDMAChannelTransferSet(UDMA_CHANNEL_SSI1RX | UDMA_PRI_SELECT, UDMA_MODE_BASIC, (void *)(LEG1_SPI_BASE + SSI_O_DR), (void *)&ptr[UDP_IP_HEADER_SIZE], sizeof(acoustic_t)); uDMAChannelEnable(UDMA_CHANNEL_SSI1TX); uDMAChannelEnable(UDMA_CHANNEL_SSI1RX);

  • Could you please in

    uDMAChannelTransferSet(UDMA_CHANNEL_SSI1TX | UDMA_PRI_SELECT,
               UDMA_MODE_BASIC,
               (void *)&buffy[0],
               (void *)(LEG1_SPI_BASE + SSI_O_DR),
               sizeof(acoustic_t));
    Change the destination address to see if it also gives you those erros, reason i am saying that is because you have a ARB of 4, and also a destination incrementation of 8 bits, that means you don't keep writing data into the FIFO, but istead you are writing it to the other registers, notice that the registers that change are after the SSI_O_DR
  • Luis,

    You're right, it did not corrupt the other registers. Could you explain this to me a bit more, specifically about how arbitration works? I changed all foru uDMA channels to arbitration of 1 and also disabled burst and everything works now.

    Thank you very much for the time,

    Nate

  • You were just messing arround with the SSI registers and you can se in the table below that every 4 bytes, you have another register that configs diferent things. You were cycling the destination address through the 4 bytes of each register.

    Now about the FIFO. You only have the DR to store data, the SSI will store it in the fifo everytime it receives it, while the FIFO has space in it