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.

uDMA to SSI Transfer - Am I missing something?

Hi everyone,

I'm a bit stuck on setting up a uDMA transfer. I want to transfer 32 bits of data from the SSI3 data register to a buffer.

I have still enabled the SSI3 RXIM interrupt as its my understanding that this is where the udma interrupt will go to. 

When I execute the code I am going into the interrupt handler but it is the SSI3 receive interrupt that is firing not the udma transfer complete interrupt.

I realise my interrupt handler is missing code to restart the transfer.

can anyone offer me some guidance? I feel like I have missed something fundamental. 

uint32_t ucControlTable[256] __attribute__ ((aligned(1024))); //Control Table for uDMA

volatile uint32_t InputStreamPtr[256];

void initSSI3(void)

{

SYSCTL->RCGCSSI |= 0x00000008; //enable clock gating
vDelayX(5);
SSI3->CR1 &= ~SSI_CR1_SSE; // disable operation when changing bits
SSI3->CR1 |= SSI_CR1_MS; // set as slave
SSI3->CC = SSI_CC_CS_SYSPLL; // system clock
SSI3->CPSR = 0x62; // BR=SysClk/(CPSDVSR * (1 + SCR)) => 127551 = 50000000 / (98d*(1+3))
SSI3->CR0 |= SSI_CR0_FRF_TI;
SSI3->CR0 |= SSI_CR0_DSS_16; // 16 bit data size
SSI3->CR0 |= 0x03 << 8; // BR=SysClk/(CPSDVSR * (1 + SCR)) => 127551 = 50000000 / (98d*(1+3))

while(0 != (uiClearData == SSI3->DR));

}

void initUdma(void)

{

SYSCTL->RCGCDMA = 0x01; //enable uDMA clock
vDelayX(5); //wait
UDMA->CFG = 0x00000001; //Enable uDMA controller
UDMA->CTLBASE = (uint32_t)ucControlTable; //Base address for channel control
UDMA->CHMAP1 = (UDMA->CHMAP1&0xF0FFFFFF)|0x01000000; //Channel 14 used
UDMA->PRIOCLR = (1UL<<14); //Channel 14 default priority
UDMA->ALTCLR = (1UL<<14); //Channel 14 primary control
UDMA->USEBURSTCLR = (1UL<<14); //Allow burst and single request response
UDMA->REQMASKCLR = (1UL<<14); //recognise requests for channel 14

ucControlTable[CH14PR] = (uint32_t)SSI3->DR; //rx from peripheral and put to txdestptr
ucControlTable[CH14PR+4] = (uint32_t)InputStreamPtr;
ucControlTable[CH14PR+8] = 0x5D004001;

/* DMACHCTL Bits Value Description
DSTINC 31:30 01 destination address increment by 16 bits
DSTSIZE 29:28 01 16-bit destination data size
SRCINC 27:26 11 no source address increment
SRCSIZE 25:24 01 16-bit source data size
reserved 23:18 000000 N/A
ARBSIZE 17:14 0001 Arbitrates after 2 transfer
XFERSIZE 13:4 0000000000 Transfer count items
NXTUSEBURST 3 0 N/A
XFERMODE 2:0 001 Use basic transfer mode
*/



SSI3->DMACTL = (1UL<<0); // set dma ctrl for rx fifo - set after dma set up
UDMA->ENASET |= (1UL<<14); //| (1UL<<15);

}

void startSSI3(void)

{

SSI3->CR1 |= SSI_CR1_SSE; // enable operation
while(0 != (uiClearData == SSI3->DR)); // empty receive fifo
SSI3->IM = SSI_IM_RXIM;
SSI3->ICR = SSI_IM_RXIM;

}

void vSSI3InterruptHandler(void)

{
unsigned int uiDataReceive;

SSI3->ICR = SSI_IM_RXIM;


//uiDataReceive = SSI3->DR;
//SSI3->DR = uiDataReceive;
//while(!(SSI1->SR & SSI_SR_TFE));  //old loopback code

}

Thanks 

Sarah 

  • Hello Sarah

    Which TM4C device is this: TM4C123 or TM4C129?

    Regards
    Amit
  • H Amit,

    Apologies, It is the TM4C123. Does how I set up the control table seem correct?

    ucControlTable[CH14PR] = (uint32_t)SSI3->DR;
    ucControlTable[CH14PR+4] = (uint32_t)InputStreamPtr;
    ucControlTable[CH14PR+8] = 0x5D004001;

    Thanks

    Sarah
  • I realised I have this set up wrong. I just want to transfer two half words into a buffer. So I've changed my buffer and destination end pointer accordingly. It hasn't made any difference as nothing is being transferred still.

    volatile uint16_t InputStreamPtr[2];

    ucControlTable[CH14PR] = (uint32_t)SSI3->DR;
    ucControlTable[CH14PR+4] = (uint32_t)InputStreamPtr + 3;
    ucControlTable[CH14PR+8] = 0x5D004001;


    If I view ucControlTable I can see data at ucControlTable[CH14PR] but nothing transfers to my buffer. Everything is enabled.
    My interrupt handler is still firing from the sssi3 rxim interrupt not a udma interrupt.

    Thanks
  • Hello Sarah,

    What is 0x5D004001? It is not a valid system address

    Regards
    Amit
  • Hi Amit,

    You've been (so) gentle w/Sarah.

    Her (exclusive) use of dreaded DRM "eats" (your) time, effort & ability to help others - does it not?

    Gentle reminder that (all) should employ the API - rather than DRM - may curb this wasteful, delaying, error-prone DRM method...

    We note that "illegal" address: 0x5D004001 is unlikely to appear if the API was employed...

    Perhaps of greater importance - once you resolve this issue for her - it will prove of minimal value to all others - who (properly) wish to employ the API.   What then?

  • Hi Amit,

    Its the control word value for the memory structure for channel 14.

    /* DMACHCTL Bits Value Description
    DSTINC 31:30 01 destination address increment by 16 bits
    DSTSIZE 29:28 01 16-bit destination data size
    SRCINC 27:26 11 no source address increment
    SRCSIZE 25:24 01 16-bit source data size
    reserved 23:18 0000 00 N/A
    ARBSIZE 17:14 00 01 Arbitrates after 2 transfer
    XFERSIZE 13:4 00 0000 0001 Transfer count items
    NXTUSEBURST 3 0 N/A
    XFERMODE 2:0 001 Use basic transfer mode
    */

    On a side note should I have to enable the ssi3 receive interrupt when using the udma?


    thanks
    Sarah
  • Hello cb1,

    The datasheet states initialization and configuration examples using the dreaded DRM so I didn't think I was being too presumptuous to ask for help.

    I wasn't instructed by my FAE to not use DRM. I've never used this chip before and thought using DRM would give me a better understanding all round? Is this not the case? Should I just copy api examples and not give it another thought?

    Please note that 0x5D004001 is not an address.

    Sarah
  • Hello Sarah,

    My sincere apologies (the control structure in DRM view confuses me). There was a similar post some time back where SSI and DMA were not working. And we figured out it was the sequence of operations.

    e2e.ti.com/.../437340

    Regards
    Amit
  • Thank you Amit. I will give that a try.

    Sarah
  • Hello Sarah,

    Indeed the MCU manual employs DRM - in fact (never mentioning) the vast, detailed & far more efficient API.   Pity that your FAE did not note the added complexity which DRM (always) invokes.  

    You'll note that Amit (often) advises against the use of DRM (and did so in his post to you today) - as its complexity demands painstaking effort - each/every time that it is employed.   In contrast - the API is long tested/proven - has been used by thousands before you.   That's my point.

    Of course you're being facetious voicing, "Not give it another thought."   Those are your words - never mine - yet (some) here care for Amit - seek not to "dilute" his great efforts.   Clearly - some review of critical registers is helpful - yet to present a barrage of DRM only - as you've done - proves inefficient & most never works without great pain/suffering.

    Amit & I both recognized the 0x5 value similarly - again the API encapsulates such - proves so much easier & more efficient.

    In echo of your earlier words, you may wish to give the API another (apparently first) thought...

  • Hi cb1,

    Thank you for addressing your message to me directly this time. 

    Yes, Amit is a star and clearly very well liked and appreciated on this board. 

    Have a nice day. 

    Sarah 

  • Hi Sarah,

    One trusts the value of the vast, detailed API has at least begun to, "hit home."   It really proves a terrific time-saver, error-reducer, & code/project enhancer!    The API encapsulates so much - manages almost all of the critical, bit-sensitive, register issues - which the DRM forces (too optimistically, I'd say) upon users.

    Now your post was very well composed - demonstrated great attention to detail - yet someone had to highlight the "perils" of DRM only postings...

    As to efficiency - I'd wager tall stack of Vegas chips that w/in a week or so (all) of your DRM-based Register mastery will have cooled - and you'll be forced to page-thru most all of those (often multi-page) register settings.    That said - you're unique in having commented extensively - most fail to exercise that discipline - thus "Bravo Sarah."

    Users land here usually high in anxiety, sometimes in frustration - and Amit stands very much alone.   (in years past - forum was attended by many)   Please do consider that if every poster presented "DRM only code" the forum would (likely) grind to a halt.   That can't be good - thus my writing inviting your kind consideration...   Bon chance...

    (one notes that a properly versed/aware FAE - usually - but not always - should care more for the forum than humble, "outsider.")

  • Hello Sarah,

    Did the issue got resolved?

    During the post-thread I did observer cb1's time and again revert to APIs. Let me add my vote to the same, it makes debug simpler as the API's are made correct by construct (baring a few where we do find bug and correct), reducing the issue thread to sequencing of events.

    Regards
    Amit
  • Hi Amit,

    Yes it is resolved and all working now, I misunderstood how to map the channel. In the future I will only request assistance on this forum if I use the API.

    UDMA->CHMAP1 = (UDMA->CHMAP1&0xF0FFFFFF)|0x01000000; //Channel 14 used

    I thought I was selecting channel 14 on chmap1. When I should have been encoding peripheral '2' at location 14 which is in chmap1.

    UDMA->CHMAP1 = (0x02<<UDMA_CHMAP1_CH14SEL_S); // DMA Channel 14 uses peripheral 2 -> SSI3 RX

    Your input has been great. Thanks a lot.

    Sarah
  • Good for you, Sarah - thanks much for closing the loop.
    Kindly note that on occasion - when execution speed and/or code size prove critical - DRM may be advantageous.
    That said - on the whole - your "very advantaged use" of the API (instead of DRM) should speed, ease & enhance your efforts.    (while easing Amit's role)    Bon chance...

  • Hello Sarah,

    That is exactly cb1 was rallying. API's would have simplified the development and debug

    Regards
    Amit