2025-08-29 8:52 PM - edited 2025-08-29 8:56 PM
Hey everybody,
I was wondering if someone could help me correct my firmware that I've written.
I created a custom board using the STM32C011F4P6 MCU. I put an FTDI UART-to-USB converter on the board to be able to view outgoing messages from the custom board on my laptop.
While writing the firmware needed to demonstrate this functionality of the board, I referenced the C011 reference manual. There, STM describes the following steps to take when transmitting a character via USART, on page 752. I have tried to follow their advice to the best of my ability, but I notice that my board hangs while waiting for the transmission of a character to complete.
My testing code (in my main.c) is shown below:
int main(void)
{
char msg[] = "d";
// initialize debug LED
user_led_init();
// initialize the usart
usart_init();
while (1) {
// transmit string of characters (one character here)
usart_write_chars(msg, strlen(msg));
toggle_led();
delay_ms(500);
}
return 0;
}
Here are the definitions of my usart_init and usart_write_chars functions:
// Author: Aidan Stanford
/* Writing a quick polling UART driver */
/* The main goal of this driver is to interface the STM32C011
* processor with the FTDI USB-to-UART converter on the breakout
* board.
* It is very bare bones. No interrupts or DMA stuff yet!
*/
// TODO: Organize header files better
#include <stdint.h>
#include "stm32c0xx.h"
#include "uart.h"
#include "main.h"
// This function modifies USART2->BRR
void usart_config_br(int baud)
{
// Do math according to the kernel clock source used
uint32_t div = (USART_APB_CLK / (USART_IND_PSC<<1) / baud);
// Set the BSRR register with the result from above
if (USART2->CR1 & (1U<<15)) // oversampling by 8
USART2->BRR = ((div & 0XFFF0) | ((div & 0XF) >> 1)) & ~(0X8);
else
USART2->BRR = div;
}
void usart_init(void)
{
/* Configure appropriate GPIOA pins */
// Enable GPIOA clocks!
RCC->IOPENR |= (RCC_GPIOA_CEN);
// Set speed to high
GPIOA->OSPEEDR |= GPIO_PA4_HS | GPIO_PA5_HS;
// Set pins PA5 and PA4 to AF mode and define their functions
GPIOA->MODER &= ~GPIOA_UART_MSK;
GPIOA->MODER |= GPIO_PA4_AF | GPIO_PA5_AF;
GPIOA->AFR[0] |= (GPIOA_USART2_AF<<16) | (GPIOA_USART2_AF<<20);
// Enable APB clock for USART2
RCC->APBENR1 |= RCC_USART2_CEN;
// Configure usart_ker_ck prescaler of 5 (ends up being 10)
USART2->PRESC |= USART_IND_PSC;
// configure baud rate
usart_config_br(9600);
// Enable the USART peripheral
USART2->CR1 |= USART_EN;
}
// Polling
void usart_read_chars(char *buf, int size)
{
}
void usart_write_chars(char *buf, int size)
{
int c = 0;
USART2->CR1 |= USART_TXE;
while (c < size) {
USART2->TDR = ((int)buf[c]) & 0XFF;
while (!(USART2->ISR & USART_TXE)) {}
++c;
}
/* This is where I hang */
while ((USART2->ISR & (1U<<6))) {}
}
Any chance someone has developed with this MCU before and can give me a reality/sanity check on my code?
Thanks so much!
2025-08-29 10:08 PM
Perhaps you could use the debugger, step the code, and check you've used the right bits.
Stick a scope on the pins, check the signals.
Perhaps just loop with the LED toggling, confirm that works.
Confirm board level functionality with HAL code.