DMA_CERQ - response time to actually stop the DMA channel (clear bit in DMA_ERQ)?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

DMA_CERQ - response time to actually stop the DMA channel (clear bit in DMA_ERQ)?

544 Views
jarkko
Contributor I

Is there or actually how much there is/can be delay between giving the DMA disable request and that channel has been actually stopped?

I have basically following code to tackle the uart errors during DMA transfer (see my other post Kinetis (K10) UART DMA rx error handling ).

- key point is to stop DMA&uart until the uart error has been completely solved


void Uart_error_irq( void )

{

  UART_C2_REQ( uart0 ) &= ~(UART_C2_RE_MASK);

  DMA_CERQ = DMA_CERQ_CERQ(uart_rx_dma_ch);

  status = UART_S1_REQ( uart0 );

  (void)UART_D_REG( uart0 );

  UART_C_FIFO_REG( uart0 ) |= (UART_CFIFO_RXFLUSH_MASK);

  print_uart_error( status );

  notifytask(); // posts error event to task

}

task()

{

   event = wait_events();

   if( event & uart_error)

   {

      error_event_handler();

   }

}

void error_event_handler( void )

{
  if( DMA_ERQ & uart_rx_dma_ch )
  {

    // DMA still running

    notifytask(); // kick task again to avoid busy loops // added afterwards

    u32DmaStillRunningCountDebug++;

  }

  else

  {

    SetBufferReadingIndex();

    UART_C_FIFO_REG( uart0 ) |= (UART_CFIFO_RXFLUSH_MASK); // just in case

    DMA_SERQ = DMA_SERQ_SERQ( uart_rx_dma_ch );
    if( DMA_ERR & uart_rx_dma_ch )

    {

      Error();

    }
    UART_C2_REQ( uart0 ) |= UART_C2_RE_MASK;

  }

}

I test the system by calling by Uart_error_irq() periodically from my software (1sec in this case) to simulate the error (this is the only reasonable way to test that my error handling code works & the transferred protocol over uart tolerates such errors).

- I noticed that sometimes u32DmaStillRunningCountDebug increases

Then I looked a little bit further and noticed that DMA_CERQ-command is not always "immediately" visible in DMA_ERQ, so I added the task-re-kicker rather than while( DMA_ERQ & uart_rx_dma_ch )-busy wait loop and now it looks to work ok.

- CPU manual does not mention that there is any delays, based on my tests the delay exists only if there is active uart-transmission ongoing...

If the DMA is serving the uart request I assume that it cannot be immediately stopped? If that is true then the DMA_CERQ delay should not depend of used baudrate because DMA is not connected to uart shift-register so some kind of busy-wait loop could added because the delay "should be" small? What is the worst case delay between DMA_CERQ & DMA_ERQ visibility?

I don't also understand why CPU manual says that BITER-value must match CITER-value or configuration error is reported? Based on my experience that is not true. If you use DMA_CERQ to stop the DMA-channel, you do not need to do any CITER settings to continue with DMA_SERQ. After DMA_SERQ I  also use DMA_ERR-register to check if there is error present in channel and none is present even though the CITER seldom equals BITER because I have 400 byte long buffer.

So both methods in the function look to work equally (and yes, I am sure that in #else the CITER != BITER)

SetBufferReadingIndex()

{

#ifdef FULL_DMA_INIT

  DMA_DADDR( uart_rx_dma_ch ) = buffer;

  DMA_CITER_ELINKNO( uart_rx_dma_ch ) = DMA_BITER_ELINKNO( uart_rx_dma_ch );
  prevciter = DMA_CITER_ELINKNO( uart_rx_dma_ch );

  BufReadIndex = 0U; 

#else

  prevciter = DMA_CITER_ELINKNO( uart_rx_dma_ch );

  BufReadIndex = DMA_DADDR( uart_rx_dma_ch ) - (uint32)buffer;#endif

}

Is there somewhere available a proper description that how the DMA actually works because looks like that CPU manual has errors and also hides information... This is really time consuming trying to figure out cpu-functionality by trial and error!!! Maybe I have now figured out enough of the DMA functionality because code looks now ok and pretty bullet proof so maybe I don't need that information any more but someone else would need...

Labels (1)
0 Kudos
1 Reply

349 Views
EarlOrlando
Senior Contributor II

Hello Jarkko,

The Clear Enable Request doesn't clear the request immediately, you could try to do this quicker by writing 0 in the ERQ register. We don't have information about the worst case delay.

About the CITER and BITER registers, please take a look into the DMA_TCn_BITER_ELINKNO[BITER] description in the reference manual, there is explained why these fields must be equal while the module is configured.

pastedImage_0.png

Best regards,

Earl.

0 Kudos