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.

DMA: at least SCI & SPI requires DMA request (SCI:SET TX DMA & SPI: DMAREQEN) toggling between sending

Other Parts Discussed in Thread: HALCOGEN

Where this "feature" is described, not in errdata, TRM or datasheet, this looks to be a bug in CPU because functionality is really absurd? Based on TRM text the the DMA requests shall be always generated if the corresponding request bit is set in peripheral side and DMA channel has that request source activated but that looks not to be the case...

DMA is capable of sending only one stream if not toggling the peripheral requests between sending like this
scilinREG->CLEARINT = BIT_n(16U);
scilinREG->SETINT = BIT_n(16U);

and in SPI side
spiREG4->INT0 &= ~BIT_n(16U);
spiREG4->INT0 |= BIT_n(16U);

Of course you can disable the peripheral request in DMA BTC interrupt (if using one) or if not using BTC then clear the request always when starting new HW-trigger to DMA.

If not toggling the requesting peripheral side the DMA PEND register stays 0, DMA HW reqs are in place and also SCI&SPI registers indicates that those are ready to receive data. So by looking the registers the DMA is ready to run and peripheral is ready to receive, only missing thing is the DMA requests :).

So this is ok:
scilinREG->CLEARINT = BIT_n(16U); // could be in BTC ISR
scilinREG->SETINT = BIT_n(16U);
dmaSetChEnable( DMA_CH_SCI_TX, DMA_HW );
And this:
scilinREG->CLEARINT = BIT_n(16U); // could be in BTC ISR
dmaSetChEnable( DMA_CH_SCI_TX, DMA_HW );
scilinREG->SETINT = BIT_n(16U);


But this isn't (basically setting DMA request once active and leave it that way)
dmaSetChEnable( DMA_CH_SCI_TX, DMA_HW );
scilinREG->SETINT = BIT_n(16U);
And this neither
scilinREG->SETINT = BIT_n(16U);
dmaSetChEnable( DMA_CH_SCI_TX, DMA_HW );


In TRM chapter 29.5.2 there is weird sentence.
"Because all data has been transmitted, the interrupt/DMA request should be halted. This can be done by either disabling the transmit interrupt (CLR TX INT) / DMA request (CLR TX DMA bit) or by disabling the transmitter(clear TXENA bit)."

- Is that toggling requirement really hidden into this sentence ("should be halted")  (SPI does not have following kind of text at all). With DMA there is no need (or let's say there shouldn't be any need to disable anything) because SCI peripheral can't know (or shouldn't know) when DMA has sent all the data so if DMA is stopped the requests generated by SCI should go to PEND register to wait next DMA start.

TRM chapter 27.7 says
"The SPI generates a request on the TX_DMA_REQ line each time the TX data is copied to the TX shift register either from the TXBUF or from peripheral data bus (when TXBUF is empty).
The first TX_DMA_REQ pulse is generated when either of the following is true:
•  DMAREQEN (SPIINT0[16]) is set to 1 while SPIEN (SPIGCR1[24]) is already 1.
•  SPIEN (SPIGCR1[24]) is set to 1 while DMAREQEN (SPIINT0[16]) is already 1."
- This says clearly that DMA requests shall be generated if DMAREQEN & SPIEN is kept ON despite of completing one DMA block

This is really simple to reproduce, set DMA to send something for example at 1 sec interval (something which sending takes less than 1 sec :)) and take out clear line just to noticed that DMA sends item only once.

  • No, that is not how it works. The DMA once properly started will send the programmed number of frames to the SCI or SPI TX.  Do you have the correct request line assigned to the DMA channel. The assignments are in the DREQASIn registers starting at address 0xFFFFF054. There is a mibspi DMA example in HALCoGen under the TMS570LS31x family. It should work on the TSM570LS12x devices as well. Start an new HALCoGen project selecting a TSM570LS31x family member than look at HELP->Help Topics ->  Examples -> example_mibspiDma.

  • Did you try it? Everything is set (DREQAS is set once and then not touched) and everything works until I remove either of these line from the code depending the peripheral of course. After removal the fist DMA block goes through but nothing after that
    scilinREG->CLEARINT = BIT_n(16U);
    spiREG4->INT0 &= ~BIT_n(16U);

    Like I said, after stopping the code the HW request in the corresponding DMA channel is enabled and peripheral flag register indicates that more data could be taken.

    This is XL2-RM46 kit if used CPU matter...

  • I have another problem and uploaded project for that, you can use the same project. Run as is, SCI&SPI prints nicely (well actually SPI loses character but it does not matter in this experemental), comment out individually these line(s) to see what happens
    spiREG4->INT0 &= ~SPI_INT0_DMAREQEN; // MUST BE PRESENT, otherwise SPI hangs after 1 sending...
    scilinREG->CLEARINT = SCI_SET_TX_DMA; // MUST BE PRESENT, otherwise SCI hangs after 1 sending...

    e2e.ti.com/.../1914604
  • Hi Jarkko,

    Like you wrote TRM chapter 27.7 states

    "The SPI generates a request on the TX_DMA_REQ line each time the TX data is copied to the TX shift register either from the TXBUF or from peripheral data bus (when TXBUF is empty).
    The first TX_DMA_REQ pulse is generated when either of the following is true:
    •  DMAREQEN (SPIINT0[16]) is set to 1 while SPIEN (SPIGCR1[24]) is already 1.
    •  SPIEN (SPIGCR1[24]) is set to 1 while DMAREQEN (SPIINT0[16]) is already 1."

    Note that in both cases there is transition from off to on (or 0 to 1) either on SPIEN or DMAREQEN. And either of these transitions is required to generate the TX_DMA_REQ. Thus in stable situation even the peripheral would be ready for new data 

    Meaning that in case when SPIEN is 1, DMAREQEN is 1 and you then configure and enable DMA, the transfer does not start because there is no transition in any of the signals. So in this case you either need manually toggle DMAREQNE or SPIEN or manually write the first data and configure DMA to start from second data. In first case the transition generates TX_DMA_REQ and DMA starts. And in latter case when peripheral copies the manually written data to its internal shift register, TX_DMA_REQ is generated and thus DMA transfer starts.

    For SCI there is not that explicit explanation on generating first DMA request, there is a mention in TMR chapter 28.2.5.1

    "Either an Interrupt or a DMA request is generated the moment TXRDY is set."

    And TXRDY is set when SCI transmit buffer is ready to receive new data (so in the end at the same when data is copied to shift register, just like with SPI). But seems similarly the first DMA request needs to be generated manually by toggling the DMA request.

    Kind Regards,

      Jani

  • Requirement for toggling the DMAREQEN must come from this, because you usually modify what you send. The peripheral is ready to receive the data and it has signalled it to DMA, but DMA loses this signal when you configure next stream to be sent...

    Table 16-10 (DMA PEND-register description).

    “The pending bit is automatically cleared….

    - The control packet is modified after the pending bit is set.”

    SCI needs toggling for same reason.