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.

Using uDMA to TX SSI in master mode sends twice too many words

Hi,

I have adapted the Tivaware example that use the uDMA to transfer to/from the UART to work with the SSI in TI master mode.

I can see on the scope that the TX is sending twice too many words (16bit transfers) and I can't see what I've done wrong. Would be very grateful if someone could check or suggest reason for me.

#define SSI_TXBUF_SIZE         8
static uint16_t SSITXbuf[SSI_TXBUF_SIZE];

The SSI is initialised....

    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI0);            //fpga spi comms
    ROM_SSIDisable(SSI0_BASE);                                    //disable it while we configure it
    ROM_GPIOPinConfigure(GPIO_PA2_SSI0CLK);
    ROM_GPIOPinConfigure(GPIO_PA3_SSI0FSS);
    ROM_GPIOPinConfigure(GPIO_PA4_SSI0RX);
    ROM_GPIOPinConfigure(GPIO_PA5_SSI0TX);
    ROM_GPIOPinTypeSSI(GPIO_PORTA_BASE, GPIO_PIN_5 | GPIO_PIN_4 | GPIO_PIN_3 | GPIO_PIN_2);
    ROM_SSIClockSourceSet(SSI0_BASE, SSI_CLOCK_SYSTEM);
    ROM_SSIConfigSetExpClk(SSI0_BASE,
                           ROM_SysCtlClockGet(),
                           SSI_FRF_TI,
                           SSI_MODE_MASTER,
                           25000000,
                           16);
    ROM_SSIEnable(SSI0_BASE);
    ROM_SSIDMAEnable(SSI0_BASE, SSI_DMA_RX | SSI_DMA_TX);
    ROM_IntEnable(INT_SSI0);

The uDMA is initialised...

    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
    ROM_uDMAEnable();
    ROM_uDMAControlBaseSet(uDmaControlTable);

    //rx
    ROM_uDMAChannelAttributeDisable(UDMA_CHANNEL_SSI0RX, UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK);
    ROM_uDMAChannelControlSet(UDMA_CHANNEL_SSI0RX | UDMA_PRI_SELECT,
                              UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_4);
    ROM_uDMAChannelControlSet(UDMA_CHANNEL_SSI0RX | UDMA_ALT_SELECT,
                              UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_4);
    ROM_uDMAChannelTransferSet(UDMA_CHANNEL_SSI0RX | UDMA_PRI_SELECT,
                               UDMA_MODE_PINGPONG,
                               (void *)(SSI0_BASE + SSI_O_DR),
                               SSIRXbufA,
                               sizeof(SSIRXbufA));
    ROM_uDMAChannelTransferSet(UDMA_CHANNEL_SSI0RX | UDMA_ALT_SELECT,
                               UDMA_MODE_PINGPONG,
                               (void *)(SSI0_BASE + SSI_O_DR),
                               SSIRXbufB,
                               sizeof(SSIRXbufB));
    ROM_uDMAChannelEnable(UDMA_CHANNEL_SSI0RX);

    //tx
    ROM_uDMAChannelAttributeDisable(UDMA_CHANNEL_SSI0TX,
                                    UDMA_ATTR_ALTSELECT | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK | UDMA_ATTR_USEBURST);
    ROM_uDMAChannelControlSet(UDMA_CHANNEL_SSI0TX | UDMA_PRI_SELECT,
                              UDMA_SIZE_16 | UDMA_SRC_INC_16 | UDMA_DST_INC_NONE | UDMA_ARB_4);
    ROM_uDMAChannelTransferSet(UDMA_CHANNEL_SSI0TX | UDMA_PRI_SELECT,
                               UDMA_MODE_BASIC,
                               SSITXbuf,
                               (void *)(SSI0_BASE + SSI_O_DR),
                               sizeof(SSITXbuf));
    ROM_uDMAChannelEnable(UDMA_CHANNEL_SSI0TX);

The SSI interrupt handler for the TX is...

    if(!ROM_uDMAChannelIsEnabled(UDMA_CHANNEL_SSI0TX)) {   //if finished, start another for test
        ROM_uDMAChannelTransferSet(UDMA_CHANNEL_SSI0TX | UDMA_PRI_SELECT,
                                   UDMA_MODE_BASIC, SSITXbuf,
                                   (void *)(SSI0_BASE + SSI_O_DR),
                                   sizeof(SSITXbuf));

        for(i=0;i<SSI_TXBUF_SIZE;i++)        //init test pattern because TXBUF gets corrupted, why??
            SSITXbuf[i] = i+1;

        redLedTog;          //frame trigger for scope

        ROM_uDMAChannelEnable(UDMA_CHANNEL_SSI0TX);

many thanks,

Richard