Transmiting a buffer on UART with DMA

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

Transmiting a buffer on UART with DMA

Jump to solution
2,358 Views
john71
Senior Contributor I

Right now I transmit a buffer by blocking method

 

send_log_data_uart0(log_buffer_data, page_chunk);

 

Now I have to send it using DMA.

 

void DMA_Init(void)
{
	//enable clock for DMAMUX and DMA
	SIM_SCGC6 |= SIM_SCGC6_DMAMUX0_MASK;
	SIM_SCGC7 |= SIM_SCGC7_DMA_MASK;

	//enable channel 0 and set the source - 3 = UART0 Transmit ($3.3.9.1 Table 3-26)
	DMAMUX0_CHCFG0 |= DMAMUX_CHCFG_ENBL_MASK | DMAMUX_CHCFG_SOURCE(3);

	//set memory address for source and destination
	DMA_TCD0_SADDR = (uint32_t)&log_buffer_data;  //global scope buffer
	DMA_TCD0_DADDR = (uint32_t)&UART0_D;

    //set an offset
	DMA_TCD0_SOFF = 0;  //???
	DMA_TCD0_DOFF = 0;  //???

	//set data transfer size - byte
	DMA_TCD0_ATTR = DMA_ATTR_SSIZE(0) | DMA_ATTR_DSIZE(0);  //???

	//number of bytes to be transfered in each service request
	DMA_TCD0_NBYTES_MLNO = glob_data_chank;  //???

	//current major iteration count (a single iteration)
	DMA_TCD0_CITER_ELINKNO = DMA_CITER_ELINKNO_CITER(1);  //???
	DMA_TCD0_BITER_ELINKNO = DMA_BITER_ELINKNO_BITER(1);  //???

	DMA_TCD0_SLAST = 0;   //???
	DMA_TCD0_DLASTSGA = 0; //???

	//setup control and status register
	//DMA_TCD0_CSR = 0;

	//interrupt when tx/rx buffer is full. stop DMA on single transfer.
	DMA_TCD0_CSR = DMA_CSR_INTMAJOR_MASK | DMA_CSR_DREQ_MASK;
	//enable request signal for channel 0
	DMA_ERQ = DMA_ERQ_ERQ0_MASK;
}

 

So I have some questions.

1. Those registers with a question sign (//???) - is it configured OK?

2. buffer size can be changed (glob_data_chank). Should I update the DMA_TCD0_NBYTES_MLNO on every service request?

3. How do I set a DMA interrupt? Do I need the interrupt? I can poll the done flag

 

while (DMA_TCD0_CSR & DMA_CSR_DONE_MASK)

 

4. Do I need any additional setup on UART side? Do I need these lines?

 

UART0_C2 |= UART_C2_TIE_MASK;
UART0_C5 |= UART_C5_TDMAS_MASK;

 

5. How do I start a new transaction? Like this?

 

DMA_TCD0_CSR |= DMA_CSR_START_MASK;

 

0 Kudos
Reply
1 Solution
2,291 Views
PabloAvalos
NXP TechSupport
NXP TechSupport

Hello, @john71 

 

First of all, I am very thankful for your patience.

 

Then, I would like to know, which mcu are you using for?

Sharing with you a couple of threads of our community, where you can find accurate information on how DMA works. I would like to help you by telling you if the configuration of your registers with a question sign (//???) are configured ok, but it depends on your application needs.

 

Hoping this links might be helpful:

https://community.nxp.com/t5/Kinetis-Microcontrollers/UART-DMA-Configuration/m-p/1166667

https://community.nxp.com/t5/Kinetis-Microcontrollers/Kinetis-K60-K70-configuration-of-DMA-with-I2S-...

 

At last but not least, regarding your other questions, the register DMA_TCD0_NBYTES_MLNO defines the number of bytes to transfer per request, so if you are going to change the data size to transfer in every request, you should update this register. For DMA interruption, you can refer to this link Interrupt on DMA Completion where is being used a Kinetis  K27 Series. Lastly, I will suggest you to check our SDK Examples, by searching and downloading your mcu sdk here: SDK Builder, where you can get functional examples on eDMA and DMA transfers in our MCUXpresso IDE.

Please let me know if you have more questions.

 

Best Regards.

Pablo Avalos.

View solution in original post

0 Kudos
Reply
3 Replies
2,292 Views
PabloAvalos
NXP TechSupport
NXP TechSupport

Hello, @john71 

 

First of all, I am very thankful for your patience.

 

Then, I would like to know, which mcu are you using for?

Sharing with you a couple of threads of our community, where you can find accurate information on how DMA works. I would like to help you by telling you if the configuration of your registers with a question sign (//???) are configured ok, but it depends on your application needs.

 

Hoping this links might be helpful:

https://community.nxp.com/t5/Kinetis-Microcontrollers/UART-DMA-Configuration/m-p/1166667

https://community.nxp.com/t5/Kinetis-Microcontrollers/Kinetis-K60-K70-configuration-of-DMA-with-I2S-...

 

At last but not least, regarding your other questions, the register DMA_TCD0_NBYTES_MLNO defines the number of bytes to transfer per request, so if you are going to change the data size to transfer in every request, you should update this register. For DMA interruption, you can refer to this link Interrupt on DMA Completion where is being used a Kinetis  K27 Series. Lastly, I will suggest you to check our SDK Examples, by searching and downloading your mcu sdk here: SDK Builder, where you can get functional examples on eDMA and DMA transfers in our MCUXpresso IDE.

Please let me know if you have more questions.

 

Best Regards.

Pablo Avalos.

0 Kudos
Reply
2,281 Views
john71
Senior Contributor I

Thank you

0 Kudos
Reply
2,325 Views
john71
Senior Contributor I

Nobody knows how DMA works?

 

0 Kudos
Reply