cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H753ZI DMA Handler stop working when switched from C to C++

CLeo.1
Senior II

Hi everyone, just a question about this DMA not triggering for unknown reasons.

The only thing I can deduced is the switch from C to C++ and how variables behave within an object maybe.

All I know is the peripheral is working and the DMA is setting the right flag. I also tried the C version of my code and it worked. Double check the buffer is in the right memory region as well the RAM_D1.

0693W00000BcUZfQAN.png0693W00000BcUZpQAN.png0693W00000BcUZuQAN.pngFor some reason it doesnt wanna hit the void DMA1_Stream3_IRQHandler(). Yes I used the

Main.cpp

int main () {
 
clock clock;
audioProcessor ap;
uart<uint8_t*> uart(ap.GET_UART4_RxBUFF(), 1);
 
while (1) {
 
	}
}
 
void DMA1_Stream3_IRQHandler() {
 
	if (((DMA1->LISR) & (DMA_LISR_TCIF3)) != 0) {
		  DMA1->LIFCR |= DMA_LIFCR_CTCIF3;
 
		  UART4_TC = OK;
	}
}

uart.h

/*
 * i2s.h
 *
 *  Created on: Jun. 22, 2021
 *      Author: Christopher
 */
 
#ifndef PERIPERHALS_HEADER_MIDCLASS_UART_H_
#define PERIPERHALS_HEADER_MIDCLASS_UART_H_
#include "peripheral.h"
 
 
template <class T>
class uart: public I_peripheral {
 
private:
		void SET_GPIO();
		void SET_Peripheral();
		void SET_Clock();
		void SET_DMA(T Rx_BUFF, uint32_t length);
		void SET_Interrupt();
		void SET_REG(T Rx_BUFF, uint32_t length);
 
public:
		    uart(T Rx_BUFF, uint32_t length) {
			SET_REG(Rx_BUFF, length);
		}
};
 
template <class T>
void uart<T>::SET_GPIO() {
 
	RCC->AHB4ENR &= ~(RCC_AHB4ENR_GPIODEN);
	RCC->AHB4ENR |=   RCC_AHB4ENR_GPIODEN;
 
	GPIOD->MODER &= ~((GPIO_MODER_MODE0) |
				      (GPIO_MODER_MODE1));
 
	GPIOD->MODER |= (GPIO_MODER_MODE0_AF) |
				    (GPIO_MODER_MODE1_AF);
 
	GPIOD->OSPEEDR |= GPIO_OSPEEDR_OSPEED0_VERY_HIGH_SPEED |
				      GPIO_OSPEEDR_OSPEED1_VERY_HIGH_SPEED;
 
 
	GPIOD->AFR[0] &= ~((GPIO_AFRL_AFSEL0) |
				       (GPIO_AFRL_AFSEL1));
 
	GPIOD->AFR[0] |= (GPIO_AFRL_AFSEL0_UART4_RX) |
				     (GPIO_AFRL_AFSEL1_UART4_TX);
}
 
template <class T>
void uart<T>::SET_Peripheral() {
 
	UART4->BRR =  0x412;
	UART4->CR3 |= (USART_CR3_DMAT) | (USART_CR3_DMAR);
	UART4->CR1 |= (USART_CR1_M1_8BITS) | (USART_CR1_M0_8BITS) | (USART_CR1_RE) | (USART_CR1_TE);
	UART4->CR2 |= (USART_CR2_STOP_1BIT);
	UART4->CR1 |= USART_CR1_UE;
}
 
template <class T>
void uart<T>::SET_Clock() {
 
	RCC->APB1LENR |= RCC_APB1LENR_UART4EN;
	RCC->D2CCIP2R &= ~(RCC_D2CCIP2R_USART28SEL);
	RCC->D2CCIP2R |= RCC_D2CCIP2R_USART234578SEL_PLLCLK;
 
}
 
template <class T>
void uart<T>::SET_DMA(T Rx_BUFF, uint32_t length) {
 
	RCC->AHB1ENR &= ~(RCC_AHB1ENR_DMA1EN);
	RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN;
 
		//Setup DMA
		DMAMUX1_Channel3->CCR &= ~(DMAMUX_CxCR_DMAREQ_ID);
		DMAMUX1_Channel3->CCR |=  (DMAMUX_CxCR_DMAREQ_ID_UART4_Rx);
 
		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_PERI_TO_MEM)   |
							  (DMA_SxCR_PFCTRL_DMA_FLOW)   |
							  (DMA_SxCR_TCIE);
 
		DMA1_Stream3->NDTR = length;
 
		DMA1_Stream3->PAR  = (uint32_t)&UART4->RDR;
		DMA1_Stream3->M0AR = (uint32_t)Rx_BUFF;
 
		DMA1_Stream3->CR |= DMA_SxCR_EN;
}
 
template <class T>
void uart<T>::SET_Interrupt() {
 
	NVIC_EnableIRQ(DMA1_Stream3_IRQn);
	NVIC_SetPriority(DMA1_Stream3_IRQn,1);
}
 
template <class T>
void uart<T>::SET_REG(T Rx_BUFF, uint32_t length) {
 
	SET_Clock();
	SET_GPIO();
	SET_DMA(Rx_BUFF, length);
	SET_Peripheral();
    SET_Interrupt();
}
 
#endif /* PERIPERHALS_HEADER_MIDCLASS_UART_H_ */

 Some function to get the pointer to the buffer

/*
 * audioProcessor.cpp
 *
 *  Created on: Jun. 22, 2021
 *      Author: Christopher
 */
#include "audioProcessor.h"
 
 	  int audioProcessor::SAI1_A_RxBUFF[4096] = {0};
	  int audioProcessor::SAI1_B_TxBUFF[4096] = {0};
	  int audioProcessor::SAI2_A_TxBUFF[4096] = {0};
	  uint16_t audioProcessor::WS2812B_TxBUFF[1] = {0};
	  uint8_t audioProcessor::UART4_RxBUFF[1] = {0};
 
 	   int * audioProcessor::GET_SAI1_A_RxBUFF() {
		     return SAI1_A_RxBUFF;
	   }
 
	   int * audioProcessor::GET_SAI1_B_TxBUFF() {
	   		 return SAI1_B_TxBUFF;
	   }
 
	   int * audioProcessor::GET_SAI2_A_TxBUFF() {
	   	     return SAI2_A_TxBUFF;
	   }
 
	   uint16_t * audioProcessor::GET_WS2812B_TxBUFF() {
	  	   	   	 return WS2812B_TxBUFF;
	  	   }
 
	   uint8_t * audioProcessor::GET_UART4_RxBUFF() {
	   	   	 return UART4_RxBUFF;
	   }
 
	   uint8_t audioProcessor::GET_volume() {
		   return volume;
	   }
 
	   uint8_t audioProcessor::GET_subVolume() {
	   		   return subVolume;
	   	   }
 
	   double audioProcessor::GET_inputCompensator() {
	  		   return inputCompensator;
	   }
 
 

1 ACCEPTED SOLUTION

Accepted Solutions
TDK
Guru

The linker is looking for "DMA1_Stream3_IRQHandler", but if this function is with in a C++ file, the name it is mangled and so the linker doesn't find it. (It still compiles because there is a weakly defined default handler that it falls back to.)

Enclose the function in extern "C" brackets.

extern "C" {
 
void DMA1_Stream3_IRQHandler() {
  ...
}
 
}

If you feel a post has answered your question, please click "Accept as Solution".

View solution in original post

2 REPLIES 2
TDK
Guru

The linker is looking for "DMA1_Stream3_IRQHandler", but if this function is with in a C++ file, the name it is mangled and so the linker doesn't find it. (It still compiles because there is a weakly defined default handler that it falls back to.)

Enclose the function in extern "C" brackets.

extern "C" {
 
void DMA1_Stream3_IRQHandler() {
  ...
}
 
}

If you feel a post has answered your question, please click "Accept as Solution".

YUP! Just found this solution as well and that exact reasoning as to why using it. Thank you