cancel
Showing results for 
Search instead for 
Did you mean: 

Can't enable DMA stream for UART4 Tx

CLeo.1
Senior II

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;

1 ACCEPTED SOLUTION

Accepted Solutions
CLeo.1
Senior II

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.

View solution in original post

7 REPLIES 7

Read out and check/post the DMA registers content.

Is the buffer in memory accessible by DMA?

JW

CLeo.1
Senior II

@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

In 'H7, DTCM is not accessibly by DMA.

JW

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

Did I bymistake switch to use DTCM?

TDK
Guru

> 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
Senior II

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.