Hi, I'm developing an application requiring uart0 tx/rx with DMA.
Starting from example "low_power_dma_uart_demo" I was able to configure DMA (channel0) and UART0 and the receiving was ok (I don't need Low Power mode, so I've changed some setting with respect to the given example.
I'm not able, at the moment, to set the trasmission with DMA. Which are the steps to do? Do I have to use a new channel (channel 1 for example) and configure it for TX? I tried but without results.
Some hints? Examples? Thank you.
Hi ulivinico
I am trying to develop an application requiring uart0 tx/rx with DMA. I am new in code warrior and I am using KL26Z.
I have found low_power_dma_uart_demo example, however it is not opening. So I don't know where I should start.
I would be very grateful if you could give me some hints or examples.
Thank you in advance!
Hi
You can get KL26Z UART Tx DMA code from http://www.utasker.com/forum/index.php?topic=1721.0
Regards
Mark
Mark, do I have to clear the DMA interrupt request of the specific channel once the DMA transfer is completed?
I get constant DMA interrupts when the CITER loop has completed..
According to the TRM (22.3.12 Clear Interrupt Request Register DMA_CINT), I would assume that i have to write 0x01 to clear the DMA Channel 1 interrupt?
Michael
If you enable an interrupt (DMA_DCR[EINT]) you will get one at the end of the transmitted block.
It is cleared with DMA_INT = (DMA_INT_INT0 << channel_number);
The end of transfer interrupt is useful because it signals that the block has been sent, can be used to control RS485 signal timing, low power activation (without moving to low power mode before a transfer has terminated) and to start a next waiting block.
Attached is the current uTasker UART code which handles interrupt/dma rx/tx operation on all UARTS/LPUART (K, KL, KE, KV, KW).
Regards
Mark
Kinetis: http://www.utasker.com/kinetis.html
Low power with UARTs: https://community.freescale.com/message/421247#421247
UARTs: http://www.utasker.com/docs/uTasker/uTaskerUART.PDF
For the complete "out-of-the-box" Kinetis experience and faster time to market
Thanks Mark, I forgot to clear the DMA_INT within the interrupt..
Hi
Tx use is equivalent to Rx use - but in the other direction. It needs a second DMA channel.
When testing, monitor the DMA error register since it reports any configuration problems that stop it from working. In particular, make sure that each used DMA channel has its own unique priority since setting any two with the same (or left in uninitialised state) will lead to an immediate priority error.
There is setup code for UART DMA below - copied from the uTasker project whereby this code allows all UARTs to be operated in DMA mode if desired. Not shows is the initialisation of all DMA channel priorities which is best done before any DMA has been started in the system since changing priorities during operation could cause spurious problems; if you have a chip with multiple DMA groups also ensure that the groups priorities don't conflict.
Regards
Mark
KINETIS_DMA_TDC *ptrDMA_TCD = (KINETIS_DMA_TDC *)eDMA_DESCRIPTORS;
ptrDMA_TCD += UART_DMA_TX_CHANNEL[Channel];
ptrDMA_TCD->DMA_TCD_SOFF = 1; // source increment one byte
ptrDMA_TCD->DMA_TCD_DOFF = 0; // destination not 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_DADDR = (unsigned long)&(uart_reg->UART_D); // destination is the UART's data register
ptrDMA_TCD->DMA_TCD_NBYTES_ML = 1; // each request starts a single transfer
ptrDMA_TCD->DMA_TCD_CSR = (DMA_TCD_CSR_DREQ | DMA_TCD_CSR_INTMAJOR); // stop after the defined number of service requests and interrupt on completion
fnEnterInterrupt((irq_DMA0_ID + UART_DMA_TX_CHANNEL[Channel]), UART_DMA_TX_INT_PRIORITY[Channel], (void (*)(void))_uart_tx_dma_Interrupt[Channel]); // enter DMA interrupt handler
uart_reg->UART_C5 |= UART_C5_TDMAS; // use DMA rather than interrupts for transmission
POWER_UP(6, SIM_SCGC6_DMAMUX0); // enable DMA multiplexer 0
*(unsigned char *)(DMAMUX0_BLOCK + UART_DMA_TX_CHANNEL[Channel]) = ((DMAMUX_CHCFG_SOURCE_UART0_TX + (2 * Channel)) | DMAMUX_CHCFG_ENBL); // connect UART tx to DMA channel
uart_reg->UART_C2 |= (UART_C2_TIE); // enable the tx dma request (DMA not yet enabled) rather than interrupt mode