cancel
Showing results for 
Search instead for 
Did you mean: 

UART data is not transmitted

AHass.1
Associate II

Dear community,

after solving some issues with the help of the community, I am stuck on the next problem. I really don't know why my UART, which seems to be initialized correctly, does not shift out my data for transmission.

After initializing my USART2, the TC and TXE (USART SR register) flags are immediately set, as I personally expect. But when I write data to the data register for transmission, I would expect the TXE and TC flag to be reset, and after a few more cycles (depending on my baudrate) my TXE and TC flag should be set again, after transmission is done and hence both registers are empty again. But that simply does not happen. I also do not measure anything on the corresponding pins. Here is my code:

void initIrda(void)
{
	if (!isIrdaInitialized())
	{
		write_data_ptr = 0;
		transmit_data_ptr = 0;
		received_data_ptr = 0;
		read_data_ptr = 0;
 
		GPIOA->AFR[0] |= (0b0111 << GPIO_AFRL_AFSEL2_Pos);	// Alternate function AF7 for PA2 and PA3
		GPIOA->AFR[0] |= (0b0111 << GPIO_AFRL_AFSEL3_Pos);
		startIrda();
		NVIC_EnableIRQ(USART2_IRQn);						// Enable USART2 interrupt (CMSIS command)
		USART2->CR3	 |= (1 << USART_CR3_IREN_Pos);			// IrDA mode enable
		USART2->CR1  //|= (1 << USART_CR1_TXEIE_Pos)			// Enable TX-Interrupts
					 //|  (1 << USART_CR1_TCIE_Pos)			// Enable Transmission Complete Interrupts
					 |=  (1 << USART_CR1_PEIE_Pos) 			// Enable Interrupts for parity errors
					 |  (1 << USART_CR1_IDLEIE_Pos)			// Enable Interrupt when idle line is detected
					 |  (1 << USART_CR1_RXNEIE_Pos)			// Enable RX-Interrupts
					 |  (1 << USART_CR1_TE_Pos)				// Enable Transmitter
					 |  (1 << USART_CR1_RE_Pos);			// Enable Receiver
		USART2->CR1 |= (1 << USART_CR1_UE_Pos);				// enable UART
		USART2->CR1 &= ~(1 << USART_CR1_M_Pos);				// 1 Start bit, 8 Data bits, n Stop bit
		USART2->CR2 &= ~(0b11 << USART_CR2_STOP_Pos);		// 1 Stop bit
		USART2->BRR = 0x045;								// Baudrate 115200 (see documentation how this value was calculated)
		irda_status.initialized = 1;
	}
}
 
void startIrda(void)
{
	RCC->APB1ENR |= (1 << RCC_APB1ENR_USART2EN_Pos);	// turn clock on for usart2 periphery
	irda_status.running = 1;
}
 
void irda_tick(void)
{
	while (transmit_data_ptr != write_data_ptr && isTXempty())
	{
		USART2->CR1 |= (1 << USART_CR1_TE_Pos);				// send an idle frame
		USART2->DR = tx_buffer[transmit_data_ptr];
		transmit_data_ptr = (transmit_data_ptr + 1) & (BUFFER_SIZE - 1);
		while(!((USART2->SR & USART_SR_TC_Msk) == USART_SR_TC)) {};		// wait for transmission to finish
	}
}
 
static uint8_t isTXempty(void)
{
	return (READ_BIT(USART2->SR, USART_SR_TXE) == USART_SR_TXE);
}
 
void irda_write(const char* arr_ptr, size_t size)
{
	size_t i = 0;
	for (i = 0; i < size; i++)
	{
		tx_buffer[write_data_ptr] = *(arr_ptr + i);
		write_data_ptr = (write_data_ptr + 1) & (BUFFER_SIZE - 1);
	}
}

Any help would be appreciated, I am really in desperation. Thank you.

1 REPLY 1
TDK
Guru

> write_data_ptr = (write_data_ptr + 1) & (BUFFER_SIZE - 1);

This is odd. Maybe it'll work if BUFFER_SIZE is a power of 2. If you're trying to wrap around a circular buffer, "... % BUFFER_SIZE" would be better.

Edit: I don't see any issues in the code you posted, but you didn't include everything relevant. initIrda is never called in what you posted, as well as other functions.

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