cancel
Showing results for 
Search instead for 
Did you mean: 

Anyone have experience with the STM32H750VB board from ebay? I am having trouble with USART1

JD.1
Associate II

Using this board from ebay with the STM32H750VB mcu and I have USART1 configured, and it 'functions' but the data I send from the pc is not what the board is getting. I had to download several serial clients until I found one that would read parity as 'space' and that made it work correctly but I have no parity configured on the board, and Im stumped as to why its not getting what I am sending.

If I send the letter 'A' (ascii 65) the board gets decimal 160. The MSB seems to be set sometime when it shouldn't be, and I cannot figure out whats causing it. Ive spent close to 50 hours trying to figure this out. Anyone have any ideas?

I got some basic pinout and description info from a post @Community member​ made a few months ago, and I thought it was working correctly but then noticed this data problem. I've used cubemx to generate all code, I've hand written it based on reg values from the reference manual, and I have tried several examples from various places on the web.

__GPIOA_CLK_ENABLE();
 
	GPIO_InitTypeDef GPIO_InitStructure;
 
	GPIO_InitStructure.Pin = GPIO_PIN_9;
	GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
	GPIO_InitStructure.Alternate = GPIO_AF7_USART1;
	GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
	GPIO_InitStructure.Pull = GPIO_PULLUP;
	HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
 
	GPIO_InitStructure.Pin = GPIO_PIN_10;
	GPIO_InitStructure.Mode = GPIO_MODE_AF_OD;
	HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
 
	__USART1_CLK_ENABLE();
	//Most of these registers are already at zero when reset. but im getting desperate. 
	//set word length. 2 bits
	USART1->CR1 &= ~(USART_CR1_M0);	//00 = 1s,8d,Ns
	USART1->CR1 &= ~(USART_CR1_M1);	//01 = 1s,9d,Ns
									//10 = 1s,7d,Ns
	//set stop bits
	USART1->CR2 &= ~(USART_CR2_STOP_0 | USART_CR2_STOP_1);	//00=1 stop bit
															//01=.5 stop bit
															//10=2 stop bit
															//11=1.5 stop bit
	//set parity
	USART1->CR1 &= ~(USART_CR1_PCE);	//0=parity control disabled
										//1=parity control enabled
 
	//set msb/lsb
	USART1->CR2 &= ~(USART_CR2_MSBFIRST);	//0=0 bit first
											//1=7/8 bit first
 
	//set flow hw control
	USART1->CR3 &= ~(USART_CR3_RTSE | USART_CR3_CTSE); //0=turn of ready to send and clear to send
 
	//set tx/rx enable
	USART1->CR1 |= (USART_CR1_RE | USART_CR1_TE);	//enable transmit and receive
 
	//set over sampling
	USART1->CR1 &= ~(USART_CR1_OVER8);	//0=over sample by 16
										//1=over sample by 8
 
	//set interrupts
	USART1->CR1 |= (USART_CR1_RXNEIE_RXFNEIE); //enable interrupts
 
	//set FIFO
	USART1->CR1 &= ~(USART_CR1_FIFOEN);
 
	uint32_t Baud = 9600;
	//set baud rate
	//((clkspeed/prescaler) + (baudrate/2))/baudrate
	USART1->BRR = ((HAL_RCC_GetPCLK2Freq() / 1) + (Baud / 2U)) / Baud;
	USART1->CR1 |= (USART_CR1_UE);
 
	/* Peripheral interrupt init*/
	HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
	HAL_NVIC_EnableIRQ(USART1_IRQn);

7 REPLIES 7
JD.1
Associate II

...

TDK
Guru

The fact that you're getting characters, but not the right ones, suggests the clock is the issue.

Can you verify your clock is correct with a logic analyzer? If not, post your clock initialization. Specifically if you're using HSI, make sure the calibration and trim values are set correctly, as these can throw off the clock by more than the allowed UART tolerance.

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

Clock is configured by CubeMX currently. I replaced all the manual clock configuration I had implemented. Its not garbage data exactly, its as if I cannot get rid of the parity bit no matter what I try. If I set data bits to 7 instead of 8 with the below, it does work, but I have to set the client to 7 data bits as well and I do not understand why. Is there ALWAYS a parity bit no matter what? and can you not drop it off with &0x1FF or 0xFF on the RDR?

//set word length. 2 bits
USART1->CR1 &= ~(USART_CR1_M0);//00 = 1s,8d,Ns
USART1->CR1 |= (USART_CR1_M1);	//01 = 1s,9d,Ns
								//10 = 1s,7d,Ns
 

Current RCC:

RCC_OscInitTypeDef RCC_OscInitStruct = { 0 };
	RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0 };
	RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = { 0 };
 
	/** Supply configuration update enable
	*/
	HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);
	/** Configure the main internal regulator output voltage
	*/
	__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3);
 
	while (!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}
	/** Initializes the CPU, AHB and APB busses clocks
	*/
	RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
	RCC_OscInitStruct.HSIState = RCC_HSI_DIV1;
	RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
	RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
	RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
	RCC_OscInitStruct.PLL.PLLM = 32;
	RCC_OscInitStruct.PLL.PLLN = 129;
	RCC_OscInitStruct.PLL.PLLP = 2;
	RCC_OscInitStruct.PLL.PLLQ = 2;
	RCC_OscInitStruct.PLL.PLLR = 2;
	RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3;
	RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
	RCC_OscInitStruct.PLL.PLLFRACN = 0;
	if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
	{
		//Error_Handler();
	}
	/** Initializes the CPU, AHB and APB busses clocks
	*/
	RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
		| RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2
		| RCC_CLOCKTYPE_D3PCLK1 | RCC_CLOCKTYPE_D1PCLK1;
	RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
	RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
	RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV1;
	RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV1;
	RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV1;
	RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV1;
	RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV1;
 
	if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
	{
		//Error_Handler();
	}
	PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_USART1
		| RCC_PERIPHCLK_SPI1 | RCC_PERIPHCLK_SDMMC;
	PeriphClkInitStruct.SdmmcClockSelection = RCC_SDMMCCLKSOURCE_PLL;
	PeriphClkInitStruct.Spi123ClockSelection = RCC_SPI123CLKSOURCE_PLL;
	PeriphClkInitStruct.Usart234578ClockSelection = RCC_USART234578CLKSOURCE_D2PCLK1; 
	PeriphClkInitStruct.Usart16ClockSelection = RCC_USART16CLKSOURCE_D2PCLK2;
	if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
	{
	Error_Handler();
	}

Current ISR:

void USART1_IRQHandler()
{
	uint32_t IIR = HOST_USART->ISR;   //<--flag clears when we read the ISR
	if ((IIR & USART_FLAG_RXNE)!=0) //<-- check to see if this is an RXNE (read data register not empty
	{
		uint8_t byte = (uint8_t)(HOST_USART->RDR & 0x1FF); //<-- 0xFF doesnt work either
		Hardware_Abstraction_Layer::Serial::host_ring_buffer->put(byte);
		Hardware_Abstraction_Layer::Serial::send(0, &byte); //<--echo back what we got
	}
}

TDK
Guru

> Is there ALWAYS a parity bit no matter what? and can you not drop it off with &0x1FF or 0xFF on the RDR?

You can set no parity by clearing the USART_CR1_PCE bit. Why do you think yours keeps adding a parity bit? Have you actually looked at a scope trace and seen it? Note that "space" parity isn't really common, as it doesn't actually provide a parity check.

> RCC_HSICALIBRATION_DEFAULT

See what this is getting evaluated to and ensure it's right for the chip revision you have. CubeMX got it wrong for a while, not sure the current status.

#if defined(RCC_HSICFGR_HSITRIM_6)
#define RCC_HSICALIBRATION_DEFAULT     (0x40U)         /* Default HSI calibration trimming value, for STM32H7 rev.V and above  */
#else
#define RCC_HSICALIBRATION_DEFAULT     (0x20U)         /* Default HSI calibration trimming value, for STM32H7 rev.Y */
#endif

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

Space parity isn't even an option on the STM32H7. Unlikely that's what the processor is doing.

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

RCC_HSICALIBRATION_DEFAULT is evaluating to 0x40, and I think the chip is a Y revision. I'll change it and see if there is any effect.

Parity has been configured off for the USART.

No the chip doesnt support space parity, Im just stating that with a client setting of space parity I can get data to the board and it is correct. Data from the board however is then jumbled. I can also set the data bits to 7 instead of 8 in the USART config and the data to and from the board is correct. However I cannot specify 7 data bits to communicate with the board because the same software communicates with other processors at 8 data bits.

Here is a comparison of some of the values:

10100101 <--sent from client

110100101<-- mcu byte read is

10011110 <--sent from client

110011110<-- mcu byte read is

10100101 <--sent from client

110100101<-- mcu byte read is

RDR is 9 bits wide, so I can mask off the far left bit with 0xFF. But when I send a value that is smaller say 0x10 this is what is read from RDR

00010000<--from client

10010000<-- mcu byte read is

Masking it off with 0XFF still picks up the far left byte, and its broken again.

The only thing left I can think of is that something else is connected to USART1 and I dont know what it is.

I'll change the trim value and see what it does.

JD.1
Associate II

Well I think this has resolved it!

#if defined(RCC_HSICFGR_HSITRIM_6)
#define RCC_HSICALIBRATION_DEFAULT     (0x20U)         /* Default HSI calibration trimming value, for STM32H7 rev.V and above  */
#else
#define RCC_HSICALIBRATION_DEFAULT     (0x20U)         /* Default HSI calibration trimming value, for STM32H7 rev.Y */
#endif

I changed it from 40 to 20 back and forth a few times. At 40 I get garbage, at 20 it is correct!

So question now, what is the proper way to configure that? If I undefine RCCHSICFGR_HSITRIM_6 its could probably have effects on other things. Should I just leave the value changed in the define?

And I am presuming this value is specific to the Y chip, because Y is higher than V, but there are 2 values and Im assuming its a specific to Y revision value.