cancel
Showing results for 
Search instead for 
Did you mean: 

UART driver issue NUCLEO F411RE

NicRoberts
Senior II

I'm trying to set up a simple UART debug just for transmission from the the NUCLEO board.

uart.c

#include "uart.h"

#define GPIOAEN			(1U<<0)
#define UART2EN			(1U<<17)

#define CR1_TE			(1U<<3)
#define CR1_UE			(1U<<13)
#define SR_TXE			(1U<<7)

#define SYS_FREQ		16000000
#define APB1_CLK		SYS_FREQ

#define UART_BAUDRATE	115200

static void uart2_set_baudrate(uint32_t periph_clk, uint32_t baudrate);
static uint16_t compute_uart_bd(uint32_t periph_clk, uint32_t baudrate);
static void uart2_write(int ch);


int __io_putchar(int ch)
{
	uart2_write(ch);
	return ch;
}

void uart2_tx_init(void)
{
	/*** Configure UART GPIO pin ***/
	/* Enable clock access to GPIOA */
	RCC->AHB1ENR |= GPIOAEN;

	/* Set PA2 mode to alternate function mode */
	GPIOA->MODER &=~ (1U<<4);
	GPIOA->MODER |= (1U<<5);

	/* Set PA2 alt function to UART tx (AF07) */
	GPIOA->AFR[0] |= (1U<<8);
	GPIOA->AFR[0] |= (1U<<9);
	GPIOA->AFR[0] |= (1U<<10);
	GPIOA->AFR[0] &=~ (1U<<11);

	/*** Configure the UART ***/
	/* Enable clock access to UART2 */
	RCC->AHB1ENR |= UART2EN;

	/* Configure baudrate */
	uart2_set_baudrate(APB1_CLK, UART_BAUDRATE);

	/* Configure transfer direction */
    USART2->CR1 = CR1_TE;

	/* Enable UART module */
    USART2->CR1 |= CR1_UE;
}

static void uart2_write(int ch)
{
	/* Ensure transmit data register empty */
	while(!(USART2->SR & SR_TXE)){}

	/* Write to the transmit data register */
	USART2->DR = (ch & 0xFF);
}


static void uart2_set_baudrate(uint32_t periph_clk, uint32_t baudrate)
{
	USART2->BRR = compute_uart_bd(periph_clk, baudrate);
}

static uint16_t compute_uart_bd(uint32_t periph_clk, uint32_t baudrate)
{
	return ((periph_clk + (baudrate / 2U)) / baudrate);
}

 

 uart.h

#ifndef __UART_H__
#define __UART_H__

#include "stm32f4xx.h"
#include <stdint.h>

void uart2_tx_init(void);

#endif

 

main.c

#include "stm32f4xx.h"
#include <stdio.h>
#include "uart.h"

static void psuedo_delay(int dly);

int main(void)
{
	/* Initialize UART2 */
	uart2_tx_init();

    while(1)
    {
    	printf("hi there!\n\r");
    	psuedo_delay(9000);
    }
}

static void psuedo_delay(int dly)
{
	for(int i = 0; i < dly; i++)
	{
             // DO NOTHING
	}
}

 

If I'm right then PA2 has been set up as a UART TX with a Baud rate of 115200 & this is connected to the USB on the board.

 

But when I open a TeraTerm window & connect to the board I get nothing just a blank terminal window. What am I missing here?

20 REPLIES 20

I appreciate your insistence on using "official, proven and correct bit masks" but my intention here is to understand how things are working at a register level without abstraction. 

As pointed out by @Andrew Neil some posts back now, the issue was actually the use of the drivers (yes user error as I had been blindly cut & pasting code). I was erroneously prototyping the USART configuration function in main() instead of calling it (there was a stray void in there that I was obviously blind to until this morning).

 

The actual driver itself works as it should even with "custom constants"