Skip to main content
CLeo.1
Senior II
May 4, 2021
Solved

Can't enable DMA stream for UART4 Tx

  • May 4, 2021
  • 7 replies
  • 1337 views

Currently I am using the STM32H753ZIT6 to do all the bare metals.

Essentially what I am trying to do is just enable UART4 Tx to send some debug messages thats all.

Everytime I try to enable the DMA1_Stream3 (UART4_Tx) it just gives me a TEIF3 error and doesnt enable the DMA_Stream3, where as the Rx works fine (It can get enabled).

Whats going on here?

MAIN:

#include <stdint.h>
 
#include "EXIT_FACTORY.h"
#include "CLOCK_FACTORY.h"
#include "I2S_FACTORY.h"
#include "UART_FACTORY.h"
 
static int I2S1_TxBUFF[4096];
static int I2S1_RxBUFF[4096];
 
static uint8_t UART4_RxBUFF[1];
static uint8_t UART4_TxBUFF[1];
 
int main (void) {
 
	INIT_CLOCK();
	INIT_I2S(I2S1_RxBUFF, I2S1_TxBUFF);
	INIT_UART(UART4_RxBUFF, UART4_TxBUFF);
	INIT_EXIT();
 
 
 
	//TIMER
 
 
	while(1) {
 
 
 
 
	}
}

Code:

// ENABLE DMA
	RCC->AHB1ENR &= ~(RCC_AHB1ENR_DMA1EN);
	RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN;
 
	//Setup DMA
	DMAMUX1_Channel2->CCR &= ~(DMAMUX_CxCR_DMAREQ_ID);
	DMAMUX1_Channel2->CCR |= (DMAMUX_CxCR_DMAREQ_ID_UART4_Rx);
 
	DMAMUX1_Channel3->CCR &= ~(DMAMUX_CxCR_DMAREQ_ID);
	DMAMUX1_Channel3->CCR |= (DMAMUX_CxCR_DMAREQ_ID_UART4_Tx);
 
	DMA1_Stream2->CR &= ~((DMA_SxCR_CT) |
			 (DMA_SxCR_PL) |
						 (DMA_SxCR_MSIZE) |
						 (DMA_SxCR_PSIZE) |
						 (DMA_SxCR_MINC) |
						 (DMA_SxCR_CIRC) |
						 (DMA_SxCR_DIR) |
						 (DMA_SxCR_PFCTRL)|
						 (DMA_SxCR_TCIE) |
						 (DMA_SxCR_HTIE));
 
	DMA1_Stream2->CR |= (DMA_SxCR_CT_MEM0) |
			 (DMA_SxCR_PL_HIGH) |
						 (DMA_SxCR_MSIZE_8BIT) |
						 (DMA_SxCR_PSIZE_8BIT) |
						 (DMA_SxCR_CIRC) |
						 (DMA_SxCR_DIR_PERI_TO_MEM) |
						 (DMA_SxCR_PFCTRL_DMA_FLOW) |
						 (DMA_SxCR_TCIE);
 
 
	DMA1_Stream3->CR &= ~((DMA_SxCR_CT) |
			 (DMA_SxCR_PL) |
						 (DMA_SxCR_MSIZE) |
						 (DMA_SxCR_PSIZE) |
						 (DMA_SxCR_MINC) |
						 (DMA_SxCR_CIRC) |
						 (DMA_SxCR_DIR) |
						 (DMA_SxCR_PFCTRL)|
						 (DMA_SxCR_TCIE) |
						 (DMA_SxCR_HTIE));
 
	DMA1_Stream3->CR |= (DMA_SxCR_CT_MEM0) |
			 (DMA_SxCR_PL_HIGH) |
						 (DMA_SxCR_MSIZE_8BIT) |
						 (DMA_SxCR_PSIZE_8BIT) |
						 (DMA_SxCR_CIRC) |
						 (DMA_SxCR_DIR_MEM_TO_PERI) |
						 (DMA_SxCR_PFCTRL_DMA_FLOW);
 
 
 
	DMA1_Stream2->NDTR = 0x01;
	DMA1_Stream3->NDTR = 0x01;
 
	DMA1_Stream2->PAR = (uint32_t)&UART4->RDR;
	DMA1_Stream2->M0AR = (uint32_t)UART4_RxBUFF;
 
	DMA1_Stream3->PAR = (uint32_t)&UART4->TDR;
	DMA1_Stream3->M0AR = (uint32_t)UART4_TxBUFF;
 
 
	DMA1_Stream2->CR |= DMA_SxCR_EN;
	DMA1_Stream3->CR |= DMA_SxCR_EN;

This topic has been closed for replies.
Best answer by CLeo.1

The issue wasn't using either ITCM nor DTCM, it was a simple mistake of forgetting to pass the array address, instead I pass-by-value the array it self, so those memory address of "0x98" or "0x88" where just garage values from the array not being initialized.

However thank you from above, as I didn't know it ITCM or DTCM was a thing.

7 replies

waclawek.jan
Super User
May 4, 2021

Read out and check/post the DMA registers content.

Is the buffer in memory accessible by DMA?

JW

CLeo.1
CLeo.1Author
Senior II
May 4, 2021

@Community member​ 

The memory should be in SRAM as its located as a global variable in the Main.c posted above.

Yes DMA1 has access to all memory types, flash, SRAM, peri as well .

Yup, tried loading a 0x05 into the buffer. Checked it before and after. Its still a 0x05 in there

waclawek.jan
Super User
May 4, 2021

In 'H7, DTCM is not accessibly by DMA.

JW

CLeo.1
CLeo.1Author
Senior II
May 4, 2021

Wait, I am so confused, because this is not anything new I believe.

I just checked using my old code which is the same MCU (H7) and i got it enabled, but when using this new code I get that. So what are you trying to say?

How come the I2S M0AR works but not this?

What I noticed between the old code and the new code is that MOAR values are so different, old code is in this 0xYYYYYYYYYYYY and the new code is like 0x98, or 0x88

CLeo.1
CLeo.1Author
Senior II
May 4, 2021

Did I bymistake switch to use DTCM?

TDK
May 4, 2021

> The memory should be in SRAM as its located as a global variable in the Main.c posted above.

Global variables can be in DTCM. Your linker file would specify where things go. Can't tell anything from main.c alone.

> What I noticed between the old code and the new code is that MOAR values are so different, old code is in this 0xYYYYYYYYYYYY and the new code is like 0x98, or 0x88

0x98 or 0x88 would be in ITCM.

"If you feel a post has answered your question, please click ""Accept as Solution""."
CLeo.1
CLeo.1AuthorBest answer
Senior II
May 4, 2021

The issue wasn't using either ITCM nor DTCM, it was a simple mistake of forgetting to pass the array address, instead I pass-by-value the array it self, so those memory address of "0x98" or "0x88" where just garage values from the array not being initialized.

However thank you from above, as I didn't know it ITCM or DTCM was a thing.