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.

TM4C1294NCPDT: Transfer 3200 x 16 bits via DMA to SPI-TX Buffer

Part Number: TM4C1294NCPDT

Hi,

I have problems to use the DMA controller of the microcontroller ot transfer 3200 halfwords (16 bits each) to SSI peripheral in SPI mode to transmit the data to the display.

The transmission simply doesn't work depending on the fact, I cannot see any pixels sent to the display.

The SSI1 peripheral is configured for 16-bit transfer in motorola mode and works without DMA controller.

Here my code, any help is very appreciated.

uint32_t g_ui32uDMAErrCount;

void uDMAErrorHandler(void)
{
    uint32_t ui32Status;

    //
    // Check for uDMA error bit
    //
    ui32Status = MAP_uDMAErrorStatusGet();

    //
    // If there is a uDMA error, then clear the error and increment
    // the error counter.
    //
    if(ui32Status)
    {
        MAP_uDMAErrorStatusClear();
        g_ui32uDMAErrCount++;
    }
}

void uDMA_init(void)
{

    uint32_t trashBin[1] = {0};

    //
    // Enable the uDMA controller at the system level.
    //
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);

    while(!MAP_SysCtlPeripheralReady(SYSCTL_PERIPH_UDMA))
    {
    }

    //
    // Enable the uDMA controller error interrupt.  This interrupt will occur
    // if there is a bus error during a transfer.
    //
    MAP_IntEnable(INT_UDMAERR);

    //
    // Enable the uDMA controller.
    //
    MAP_uDMAEnable();

    //
    // Point at the control table to use for channel control structures.
    //
    MAP_uDMAControlBaseSet(pui8ControlTable);

    //
    // Enable the uDMA interface for TX channel.
    //
    MAP_SSIDMAEnable(SSI1_BASE, SSI_DMA_TX);

    //****************************************************************************
    //uDMA SSI1 TX
    //****************************************************************************

    //
    // Put the attributes in a known state for the uDMA SSI1TX channel.  These
    // should already be disabled by default.
    //
    MAP_uDMAChannelAttributeDisable(UDMA_CHANNEL_SSI1TX,
                                    UDMA_ATTR_ALTSELECT |
                                    UDMA_ATTR_HIGH_PRIORITY |
                                    UDMA_ATTR_REQMASK);

    //
    // Set the USEBURST attribute for the uDMA SSI1TX channel.  This will
    // force the controller to always use a burst when transferring data from
    // the TX buffer to the SSI1.  This is somewhat more effecient bus usage
    // than the default which allows single or burst transfers.
    //
    MAP_uDMAChannelAttributeEnable(UDMA_CHANNEL_SSI1TX, UDMA_ATTR_USEBURST);

    //
    // Configure the control parameters for the SSI1 TX.
    //
    MAP_uDMAChannelControlSet(UDMA_CHANNEL_SSI1TX | UDMA_PRI_SELECT,
                              UDMA_SIZE_16 | UDMA_SRC_INC_16 | UDMA_DST_INC_NONE |
                              UDMA_ARB_1024);


    /* Clear SSI1 RX Buffer */
    while (MAP_SSIDataGetNonBlocking(SSI1_BASE, &trashBin[0])) {}


    MAP_IntMasterEnable();

}

Now the transmission trigger function

void SSI1IntHandler(void)
{
    uint32_t ui32Status;
    uint32_t ui32Mode;

    ui32Status = MAP_SSIIntStatus(SSI1_BASE, 1);

    MAP_SSIIntClear(SSI1_BASE, ui32Status);

    ui32Mode = MAP_uDMAChannelModeGet(UDMA_CHANNEL_SSI1TX | UDMA_PRI_SELECT);
   
}

The DMA transfer function is called frequently.

void init_DMA_transfer(void){

        //while(MAP_uDMAChannelModeGet(UDMA_CHANNEL_SSI1TX | UDMA_PRI_SELECT) != UDMA_MODE_STOP){}
        while(MAP_uDMAChannelIsEnabled(UDMA_CHANNEL_SSI1TX)){}

        if(pixelpointer == pixelbuffer1)
            pixelpointer = pixelbuffer2;
        else
            pixelpointer = pixelbuffer1;


        //
        // Set up the transfer parameters for the uDMA SSI1 TX channel.  This will
        // configure the transfer source and destination and the transfer size.
        // Basic mode is used because the peripheral is making the uDMA transfer
        // request.  The source is the TX buffer and the destination is the SSI1
        // data register.
        //
        MAP_uDMAChannelTransferSet(UDMA_CHANNEL_SSI1TX | UDMA_PRI_SELECT,
                                   UDMA_MODE_BASIC, pixelpointer,
                                   (void *)(SSI1_BASE + SSI_O_DR),
                                   3200);

        //
        // Now the uDMA SSI1 TX channel are primed to start a
        // transfer.  As soon as the channel are enabled, the peripheral will
        // issue a transfer request and the data transfers will begin.
        //
        MAP_uDMAChannelEnable(UDMA_CHANNEL_SSI1TX);

        //
        // Enable the SSI1 DMA TX interrupt.
        //
        MAP_SSIIntEnable(SSI1_BASE, SSI_DMATX);

        //
        // Enable the SSI1 peripheral interrupts.
        //
        MAP_IntEnable(INT_SSI1);

        // Requests a uDMA channel to start a transfer.
        //MAP_uDMAChannelRequest(UDMA_CHANNEL_SSI1TX);

}

I have assigend the interrupt-handler-functions to the interrupt vector table.

  • Greetings,

    My firm & I have (some) experience w/a variety of Displays - and believe that 'further information' will better enable our - or another's - abiltiy to assist/guide you.

    Ali Naseri said:
    The SSI1 peripheral is configured for 16-bit transfer in motorola mode and works without DMA controller.

    By 'works' - do you mean that your:

    • display produces images - and updates - matching your expectations
    • MCU program w/out µDMA
    • and the powering & interconnects

    all perform to your satisfaction?    If so - as the µDMA will 'Raise the Data Tranfer Flow (possibly data's: rate & volume) - have you checked the voltage (at the display) while the µDMA transfer is on-going?    The ground connection - between MCU board & Display - must be adequate, as well.

    Ali Naseri said:
    The transmission simply doesn't work depending on the fact, I cannot see any pixels sent to the display.

    I'd tend to agree (xmsn fails) providing that your 'MCU -> Display set-up' (minus the µDMA addition) 'really' was unchanged!

    When 'diagnosing' such serial interfaces - the use of a multi-channel scope - proves a tremendous asset.   Your ability to monitor (even capture/store) the SPI's TX Data, Clock & CS (even the RX Data ... or Display handshake - if one exists) 'Speed, Ease & Enhance' such diagnosis.   Always!

    It would assist those here if you would provide and/or perform:

    • Slow your µDMA attempted transfer - give it 'every' chance to succeed!   (Speed is to follow - once the transfer is assured as 'robust!')
    • Does µDMA alter the expected transmission 'In any manner?'    (i.e. adds 'marker signals' even bytes of data)   You should be 'Seeking' any/all differences' - which the use of µDMA (may) impose upon your (past) successful data transfer.
    • Is that 3200x16 bit 'SPI-TX buffer' (equally) in play - during 'NON-µDMA' data transfers?    (3200, 16 bit, 'color' pixels covers 5 rows of a 640 pixel width screen!)   Is it possible that the µDMA mode causes a 'Breach of that 'magic'  (3200) number of  pixel transfers?'    (3200 appears NOT a good/highly usable, binary number.)
    • Have you attempted to debug your code while in the µDMA mode?    By setting progressive break points - deeper & deeper w/in your code - it should be possible to identify 'where' your code 'breaks.'
    • You noted a 'µDMA' interrupt - I would make every effort to insure that such interrupt is 'triggered & performing correctly' - we'd bet heavily that a mistake there is the primary cause of your problem!     Can you deploy the µDMA 'interrupt-free' - or w/the simplest possible interrupt?   [edit: a large number of interrupts are noted - it is doubted that you can run the µDMA 'interrupt-free' - thus you 'must' get each/every interrupt right!
    • Spec of the Display - especially the Timing Diagram & related Charts
    • Scope Caps revealing SPI TX Data, Clock, CS  (and any outbound signal from the Display)
    • Those Caps would be profoundly useful if:
      • the first set  - revealing the SPI signals during your 'successful' (i.e. non-µDMA) transfers
      • the 2nd set -  revealing those same SPI signals but during your 'failed' (µDMA transfers)
    • and perhaps a spare set of signals showing the voltage levels - at the display's power pins - under 'failing' conditions

    It IS 'w/in the realm' - that your µDMA transfer is 'working' - yet may 'exceed the capacity' of your display to 'properly process' that rate & volume of incoming data.    (I'd not bet the 'entire' farm on that - however)

    Kindly note that my group has never employed the TM4C129 series - and that I've thus made no attempt to 'scan your code' for errors.   (far outside my experience & time/effort available...)    Instead I've tried to cover the 'most usual, Diagnostic Procedures' - which have a great record of success - provided the MCU and Peripheral are (otherwise) behaving correctly...

    Vendor has created & provided examples of µDMA usage - usually best for you to start w/the 'most basic' - and to systematically 'raise the degree of difficulty.'    Your multi-channel scope - is very much required - for this method to succeed...

  • Hi cb1,

    thanks for the detailed answer

    I suspect that my display always needs the chipselect signal change after each transferred 16-bit word.

    Without DMA, the SW has waited routine until the transfer of two bytes is completed before the new two bytes are put into the SSI-TX buffer.

    Is there a possibility that the chipselect signal is also toggled during a DMA transfer with each transfer of two bytes to the display?

    I think this is the main problem, that I also observed on the oscilloscope, that the cs signal is not toggled anymore.

    But exactly this behavior is needed for the SPI transfer to the display.

    Edit:

    According to the datasheet of the LCD controller, there is no CS signal toggle necessary at transfering the 16 bit color pixel information.

    But what is concerning: I have seen on the oscilloscope just stochastic noise on every SPI-line when i am switiching the software routine to DMA and not one rectified signal any more. How can this happen?

  • Hello my friend - and thank you for (both) your thoughtful & detailed response - especially that analysis.    Indeed - the 'need or lack of need' to 'toggle the SPI Peripheral's CS' - is a well noted source of user issues.

    Follows now (yet more) 'cb1 opinion' - which (may) suffer due to: lack of display spec & our using µDMA of (other, far faster) ARM Cortex MCUs.   (again we have never employed '4C129.')

    As w/any Serial Peripheral- the 'MCU must "Bend to the will" of the peripheral.   (which means - fully complying w/the peripheral's signal & timing specifications.)    Now your 2nd post is 'highly effective' as it adds, 'TWO - HIGH VALUE, DETAILED FACTS' - which almost surely, 'Lead to your solution:'

    • Display datasheet lists, 'No requirement for CS toggle - per 16 bit pixel data transfer - between MCU & Display.   Yet - you noted that during your successful - 'NON µDMA transfers' - "the CS signal IS toggled."   (not the 'letter' - but the 'spirit' of your quote.)    This places you in a real quandary - yet there IS a way out. 
      • earlier you identified the appearance of a, 'wait routine' - "until the transfer of 2 bytes is completed."   At/around that 'wait routine' - has deliberate effort been made to 'Toggle CS?'    And if, 'Not specifically directed by your software' - was that 'toggle of CS' automatically generated by the MCU?
      • If the 'Toggle of CS' was software directed - it should be easy for you to (temporarily) bypass that code.   And then observe results.
    • As to your report of 'stochastic noise upon each/every SPI-line - while operating under µDMA mode' - that's an absolutely crucial finding & report!    (and 'just' what the diagnostic doctor - ordered!)   Rather clearly - in the attempt to 'Switch to µDMA mode' - the 'full & proper Set-Up of SPI functionality - appears to have FAILED!    And Failed BADLY!    You must systematically examine any/all differences between your SPI Peripheral's 'Enabling, Configuration & Interrupt Management' - under both 'NON µDMA mode (i.e. working) and 'µDMA mode (i.e. Non-working).   The absence of proper SPI signals is a 'dead giveaway' - that (somewhere) your SPI Set-Up/Config has been breached - OR that your µDMA code has never/improperly allowed the MCU's SPI Peripheral to OUTPUT!

    A very careful review of your µDMA code (i.e. systematic examination & test/verify - piece by piece) or  'vendor (or skilled user) arrival' - and (near) instant recognition of code error(s) - is now required as my 'Diagnostic grab-bag' has been depleted.    Good job on 'your' Diagnostic Efforts - they've proven immensely helpful...

  • Hi CB1,

    you are right in the point, that the MCU have to be adjusted to the Display specs. That is the problem. I have seen on the oscilloscope the bitrate of the SPI interface is too high for the Display.

    So the Display controller shut off the transmission line and no more pixels are printed after ca. 20 lines of 320 pixels width.

    So could there a possibility to reduce the DMA transfer rate? Otherwise I have to work again with the interrupts "End of Transmission" and so on. The SPI speed should be adjustable with the DMA speed.

  • The SSI bit rate is set as the 5th parameter in the function:

        SSIConfigSetExpClk(SSI1_BASE, ui32SysClock, SSI_FRF_MOTO_MODE_0,
                           SSI_MODE_MASTER, 1000000, 16);
    

    In this example it is set to 1MBaud (1000000).

    The DMA will trigger when there is room in the FIFO for more data to transmit and will therefore usually keep a continuous data flow going.

  • Ali Naseri said:
    ...the MCU's (SPI clock rate) has to be adjusted to the Display specs.    That is the problem.   I have seen on the oscilloscope the bit-rate of the SPI interface is too high for the Display.

    Should this observation prove true - then our 'diagnostic teaming' has proved fruitful.   (Always great when that happens!)    However - before we consume 'Too much of our own 'Kool-Aid' * - you should discover, (both) 'How & Why' the 'SPI bit-rate' rises during µDMA mode.   (thus violates the display's SPI input spec.)

    You note, "20 lines of 320 pixels width."   As these are 16 bit/pixel - I believe that 3200 SPI clocks will fill (just) TEN lines of pixels.    (320*10 = 3200 QED)

    Vendor agent has described, 'How to dial in the SPI clock rate.'    Yet your issue 'remains' - "WHY does the SPI clock rate CHANGE - when switching from 'normal SPI' to 'SPI under µDMA' operation?    That's your issue in a nutshell - but w/a severe 'caveat.'     

    Earlier you noted 'ZERO SPI signal output'  (stochastic noise, only)  while in µDMA-SPI mode.    What have you done - to change that?    (as you now report SPI signal output - at too high a clock rate!)

    'Kool-Aid' a commercial drink which now represents 'Individual's or firm's' (unconfirmed yet) STRONG BELIEF in their method/idea's superiority...

  • Hi CB1,

    may the DMA of the TIVA TM4C1294 has a limit to transfer 1024 items in one request, as I have found that out by using DMA with QSPI-Flash on the same MCU.

    Otherwise the DMA is delivering biased data to the destination memory if the transfer item limit is more than 1024.

    The Display has an own problem with the physical connection via flex cable. At high frequencies the clock signal gets jitter, so with a short delay between 16 bit blocks the clock can resynchrone or in more detail: the jitter is not big enough at the 16 bit boundary.

    Thank you for your help and stay helpfully...

  • Greetings,

    Pardon - the reporting from 'post to post' seems 'inconsistent' - and that (never aids) your 'remote, diagnostic team.'   

    Specifically:

    • Display was reported to 'work fine' when operated under 'Non-µDMA' conditions.    Yet today - we learn that 'physical connections are substandard.'
    • No recognizable signal output occurred upon the SPI signal channels (stochastic noise, only) when first attempting 'µDMA-SPI Mode.'   Later - too high a speed SPI clocks were observed - yet no explanation as to how the SPI signals were suddenly 'recovered.'
    • Today we learn of 'jitter' upon the SPI clock (we are not 'so sure' of that) - yet that was never past reported.

    Now the process of  'MCU <-> Display Diagnosis' is somewhat complex - and that is why - consistency in 'back & forth diagnostic efforts' and high responsiveness' prove vital.   Minus proper answers to (what are believed to be) 'reasonable questions' - the diagnostic effort stalls.   Our hope is that you can recognize - and (both) understand & accept this...

    I've linked our response to a similar 'Display Issue' - therein you will find (my firm's ability) to 'very well have predicted'  (your)  issues - as (now) reported here.   (failed/failing connections et. al.)

    https://e2e.ti.com/support/microcontrollers/other/f/908/t/829992