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

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

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

#define SYS_FREQ		16000000	// 16MHz
#define APB1_CLK		SYS_FREQ

#define UART_BAUDRATE	115200

static void uart_set_baudrate(USART_TypeDef *USARTx, uint32_t PeriphCLK, uint32_t BaudRate);
static uint16_t compute_uart_bd(uint32_t PeriphCLK, uint32_t BaudRate);

void uar2_tx_init(void);
void uart2_write(int ch);

int main(void)
{
	uar2_tx_init();

	while(1)
	{
		uart2_write('Y');

	}
}

void uar2_tx_init(void)
{
	/*Enable clock access to gpioa */
	RCC->AHBENR |= GPIOAEN;

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

	/*Set PA2 alternate function type to UART_TX (AF1)*/
	GPIOA->AFR[0] |= (1U<<8); // AFR[0] is for low register and AFR[1] for high register
	GPIOA->AFR[0] &=~(1U<<9);
	GPIOA->AFR[0] &=~(1U<<10);
	GPIOA->AFR[0] &=~(1U<<11);


	/****************Configure uart module*******************/
	/*Enable clock access to uart2 */
	RCC->APB1ENR |= UART2EN;

	/*Configure baudrate*/
	uart_set_baudrate(USART2,APB1_CLK,UART_BAUDRATE);

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

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

}


void uart2_write(int ch)
{
	/*Make sure the transmit data register is empty*/
	while(!(USART2->ISR & SR_TXE))

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


static void uart_set_baudrate(USART_TypeDef *USARTx, uint32_t PeriphCLK, uint32_t BaudRate)
{
	USARTx->BRR = compute_uart_bd(PeriphCLK, BaudRate);
}

/* This formula gives the value back to baudrate register*/
static uint16_t compute_uart_bd(uint32_t PeriphCLK, uint32_t BaudRate)
{
	return ((PeriphCLK + (BaudRate/2U))/BaudRate);
}

