Alberto
You may have mixed up the minor and major loops. Also ensure that you don't leave registers like DMA_TCD0_NBYTES_MLNO unconfigured since they have random values otherwise.
Below is the rx configuration from the uTasker project. This allows DMA operation parallel on all available Kinetis UARTs (just Rx shown in half-buffer, full buffer interrupt modes or free-running circular buffer mode). Although not a problem with your single channel setup, you generally need to manage DMA channel priorities to avoid conflicts when working with multiple ones.
The complete project is available at KINETIS Project Code and it allows you to test the UART DMA operation in its Kinetis simulator to help save time learning and debugging. Send me an email if you would like to try it. The UART DMA driven driver has been used successfully in industrial projects using multiple > 1,5Mb/s UARTs in environments requiring high reliability communications.
Regards
Mark
if (pars->ucDMAConfig & UART_RX_DMA) {
KINETIS_DMA_TDC *ptrDMA_TCD = (KINETIS_DMA_TDC *)eDMA_DESCRIPTORS;
ptrDMA_TCD += UART_DMA_RX_CHANNEL[Channel];
fnEnterInterrupt((irq_DMA0_ID + UART_DMA_RX_CHANNEL[Channel]), UART_DMA_RX_INT_PRIORITY[Channel], (void (*)(void))_uart_rx_dma_Interrupt[Channel]); // enter DMA interrupt handler
uart_reg->UART_C5 |= UART_C5_RDMAS; // use DMA rather than interrupts for reception
POWER_UP(6, SIM_SCGC6_DMAMUX0); // enable DMA multiplexer 0
*(unsigned char *)(DMAMUX0_BLOCK + UART_DMA_RX_CHANNEL[Channel]) = ((DMAMUX_CHCFG_SOURCE_UART0_RX + (2 * Channel)) | DMAMUX_CHCFG_ENBL); // connect UART rx to DMA channel
ptrDMA_TCD->DMA_TCD_BITER_ELINK = ptrDMA_TCD->DMA_TCD_CITER_ELINK = pars->Rx_tx_sizes.RxQueueSize; // the length of the input buffer in use
ptrDMA_TCD->DMA_TCD_SOFF = 0; // source not increment
ptrDMA_TCD->DMA_TCD_DOFF = 1; // destination incremented
ptrDMA_TCD->DMA_TCD_ATTR = (DMA_TCD_ATTR_DSIZE_8 | DMA_TCD_ATTR_SSIZE_8); // transfer sizes always single bytes
ptrDMA_TCD->DMA_TCD_SADDR = (volatile unsigned long)&(uart_reg->UART_D); // source is the UART's data register
ptrDMA_TCD->DMA_TCD_NBYTES_ML = 1; // each request starts a single transfer
if (pars->ucDMAConfig & (UART_RX_DMA_HALF_BUFFER | UART_RX_DMA_FULL_BUFFER)) { // if operating in half-buffer or full buffer mode
if (pars->ucDMAConfig & UART_RX_DMA_HALF_BUFFER) {
ptrDMA_TCD->DMA_TCD_CSR = (DMA_TCD_CSR_INTMAJOR | DMA_TCD_CSR_INTHALF); // never disable and inform on half and full buffer
}
else {
ptrDMA_TCD->DMA_TCD_CSR = (DMA_TCD_CSR_INTMAJOR); // never disable and inform on full buffer
}
}
else {
ptrDMA_TCD->DMA_TCD_CSR = 0;
usDMA_progress[Channel] = ptrDMA_TCD->DMA_TCD_BITER_ELINK;
}
ptrDMA_TCD->DMA_TCD_SLAST = 0; // no change to address when the buffer has filled
ptrDMA_TCD->DMA_TCD_DLASTSGA = (-pars->Rx_tx_sizes.RxQueueSize); // when the buffer has been filled set the destination back to the start of it
}
else {
uart_reg->UART_C5 &= ~(UART_C5_RDMAS); // disable rx DMA so that rx interrupt mode can be used
}