cancel
Showing results for 
Search instead for 
Did you mean: 

How to execute a function in main.c instead of model.cpp?

Krautermann
Senior II

I am using the STM32H745XIH6 board with touchgfx. And I am calling the HAL_UART_Transmit_DMA function in model.cpp whenever the user entered a string on the LCD.

But I would like this HAL_UART function to be execute to main.c instead. How do I do this codewise? I am not very experienced with interacting C++ with C. The function that I want to transfer to main.c is SendData2MCU(int UART, int DMA, uint8_t* data)

 

#include <gui/model/Model.hpp>
#include <gui/model/ModelListener.hpp>

#ifndef SIMULATOR
#include "main.h"
#include "string.h"
extern "C"
{
	extern UART_HandleTypeDef huart1;
	extern UART_HandleTypeDef huart3;
	extern UART_HandleTypeDef huart7;
	extern uint8_t RX1_String_cpy[512];
	extern uint8_t RX3_String_cpy[512];
	extern uint8_t RX7_String_cpy[512];
	extern int DMA_complete;
}
#endif

Model::Model() : modelListener(0), toggleGreenLEDButtonState(false), toggleRedLEDButtonState(false)
{

}

void Model::tick()
{
#ifndef SIMULATOR
	modelListener->RX1_3Data((char*) RX1_String_cpy, (char*) RX3_String_cpy);
	modelListener->RX7_Data((char*) RX7_String_cpy);
	modelListener->klima_sim_receive((char*) RX1_String_cpy);
#endif
}

// The following code needs to be executed in main.c
void Model::SendData2MCU(int UART, int DMA, uint8_t* data)
{
#ifndef SIMULATOR
	if(UART==0)
	{
		if(DMA==0)
		{
			HAL_UART_Transmit(&huart3, (uint8_t*) data, strlen((char*)data)-2, 100);
		}
		else if(DMA==1)
		{
			DMA_complete = 0;
			HAL_UART_Transmit_DMA(&huart3, (uint8_t*) data, strlen((char*)data)-2);
			while(DMA_complete == 0){};
		}
	}
	if(UART==1)
	{
		if(DMA==0)
		{
			HAL_UART_Transmit(&huart1, (uint8_t*) data, strlen((char*)data), 100);
		}
		else if(DMA==1)
		{
			DMA_complete = 0;
			HAL_UART_Transmit_DMA(&huart1, (uint8_t*) data, strlen((char*)data));
			while(DMA_complete == 0){};
		}
	}
#endif
}

 

The reason for this is, DMA has been shown to not be working reliably when compiled in C++. I have been told that the compiler can convert C directly to assembly language but for C++, it has to be translated into another form first and this therefore causes unreliability. 
 

13 REPLIES 13
Krautermann
Senior II

@MM..1 
I removed the function (modelListener->RX1_3Data((char*) RX1_String_cpy, (char*) RX3_String_cpy);) from model::tick() and also from presenter as per your suggestion. And then I extern the RX_String directly to view. But then I don't see the string being displayed on LCD anymore. Why is that?

#include <gui/screen2_screen/Screen2View.hpp>

#ifndef SIMULATOR
#include "stdio.h"
#include "main.h"
#include <cstring>
#include <string>
extern "C"
{
	extern uint8_t RX1_String_cpy[512];
	extern uint8_t RX3_String_cpy[512];
}
#endif

void Screen2View::RX1_3Data()
{
	RX_TextArea.setWideTextAction(touchgfx::WIDE_TEXT_WORDWRAP);
	if(UARTToggleButton.getState()==1) //UART 1
	{
		char *ptr = strtok((char*)RX1_String_cpy, ",");
		int i = 0;
		while(ptr != NULL)
		{
			temparray[i] = ptr;
			i++;
			ptr = strtok(NULL, ",");
		}
		n = sprintf(Datarray, "Temp: %s\nHumidity: %s\nMode: %s\nNo. of Alarms:%s\n", temparray[0], temparray[1], temparray[2], temparray[3]);
		Unicode::snprintf(RX_TextAreaBuffer, RX_TEXTAREA_SIZE, Datarray);
	}
	else if(UARTToggleButton.getState()==0) //UART 3
	{
		Unicode::strncpy(RX_TextAreaBuffer, (char*)RX3_String_cpy, RX_TEXTAREA_SIZE);
	}
	RX_TextArea.invalidate();
}

The HAL_UART_Receive_DMA function from main is definitely working as I can see the signal on oscilloscope.

What is the workaround to show the string received straight to view?

You dont read my text carefuly, you need check if new str received. Most simple method is after show string erase cpy, and on callback fill cpy string. 

Then in some right place if (cpy[0] != 0) call your show func with erase on end ... Right place is for example tick handler created in screen.

No offense to you but to be honest it's kinda hard to understand what you are trying to say with the way you write your English :(

I read your response multiple times to try to understand your suggestion. The Transmit now works, I have put the HAL_UART_Transmit in main file and can see it displayed on view. But for receive, if I remove it from modelListener, it does not work. 


Yes my english isnt my priority and native. I write basic princip no soap around. And i never write remove receive ... 
try read next time i write remove senddata...

For receive i wrote not call it every tick , but only if changed.

void Model::tick()
{
#ifndef SIMULATOR
if(newnotshowed) modelListener->RX1_3Data((char*) RX1_String_cpy, (char*) RX3_String_cpy);
if(newnotshowed2) modelListener->RX7_Data((char*) RX7_String_cpy);
//this is wast efunc call place it in RX1_3 in presenter or ...	modelListener->klima_sim_receive((char*) RX1_String_cpy);
#endif
}

Your C++ programming skills is close to my english too no offense  :)