Solved
STM32F303VC Bare Metal - How to Enable VCP / USART Over USB?
I'm trying to follow the reference manual to use USART over USB via VCP (bare metal), but Realterm isn't able to read *any* data. According to the user manual, USART/VCP over USB should be supported, mentioning it's on the PC4,PC5 pins. Here's the code I'm using:
#include <stdio.h>
#include "stm32f303xc.h"
/* USART1 is an alternative function of GPIOC */
#define GPIOCEN (1U << 19)
#define USART1EN (1U << 14)
/* USART1 -> CR1 Control Register */
#define CR1_TE (1U << 3)
#define CR1_UE (1U << 0)
#define SYS_FREQ 8000000
#define APB2_CLK SYS_FREQ
#define USART_BAUDRATE 9600
static void usart_set_baudrate(USART_TypeDef *USARTx, uint32_t PeriphClk, uint32_t BaudRate);
static uint16_t compute_usart_bd(uint32_t PeriphClk, uint32_t BaudRate);
void usart1_tx_init(void);
void usart1_write(int ch);
int main(void)
{
usart1_tx_init();
while(1)
{
usart1_write('H');
usart1_write('i');
}
}
void usart1_tx_init(void)
{
/****** Configure UART GPIO pin ******/
/* Enable clock access to GPIOC */
RCC -> AHBENR |= GPIOCEN;
/* Set PC4 mode to alternate function mode */
GPIOC -> MODER &= ~(1U << 8);
GPIOC -> MODER |= (1U << 9);
/* Set PC4 alternate function type to USART_TX */
GPIOC -> AFR[0] |= (1U << 28);
GPIOC -> AFR[0] |= (1U << 29);
GPIOC -> AFR[0] |= (1U << 30);
GPIOC -> AFR[0] &= ~(1U << 31);
/****** Configure UART module ******/
/* Enable clock access to USART1 */
RCC -> APB2ENR |= USART1EN;
/* Configure baud rate */
usart_set_baudrate(USART1, APB2_CLK, USART_BAUDRATE);
/* Enable UART module */
USART1 -> CR1 = CR1_UE;
/* Configure the transfer direction */
USART1 -> CR1 = CR1_TE;
}
void usart1_write(int ch)
{
/* Make sure transmit data register is empty */
while (!(USART1 -> ISR & ISR_TXE)){}
/* Write to transmit data register */
USART1 -> TDR = (ch & 0xFF);
}
static void usart_set_baudrate(USART_TypeDef *USARTx, uint32_t PeriphClk, uint32_t BaudRate)
{
USARTx -> BRR = compute_usart_bd(PeriphClk, BaudRate);
}
static uint16_t compute_usart_bd(uint32_t PeriphClk, uint32_t BaudRate)
{
return ((PeriphClk + (BaudRate/2U))/BaudRate);
}I'd very much appreciate any help or resources I could look at!
