You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
KED/csl/stm32f042/Src/imp_usart.c

163 lines
4.1 KiB

/**
**************************************************************************************************
* @file usart.c
* @author Kerem Yollu & Edwin Koch
* @date 03.11.2021
* @version 0.4 Unstable
**************************************************************************************************
* @brief Implementation of usart.h for the STM32F042K6 MCU
*
* **Detailed Description :**
*
* This source code uses bit manipulation in order to minimise the footprint of pin initialisation
* and manipulation. It's based on the CMSIS/Device/ST/STM32F0xx/Include/stm32f042x6.h Header file
* to get the obtain the right Registers.
*
* @todo:
* - 04.11.21 check if the buad rate calcutation is working good for all awailable baud rates
* - 04.11.21 Implment interrupts asap
* - 04.11.21 Implment other functionalities as they are needed
**************************************************************************************************
*/
#include "usart.h"
#include "pin.h"
#define SYST_CLK 8000000
#define AF1 0x01
#define USART_CHANNEL ((USART_TypeDef *)channel)
void usartInit( usartNo_t channel,
pinNo_t pinTx,
pinNo_t pinRx,
uint32_t baud,
usartWordLength_t lenght,
uint8_t parity,
usartHwFlowCtrl_t flowCtrl)
{
/* Configuring the pins for the uart*/
usartInitTx(pinTx);
usartInitRx(pinRx);
//Enable the UART Module on the periferal bus this must be done before setting any register.
if(channel == usart2)
{
RCC->APB1ENR |= RCC_APB1ENR_USART2EN;
}
else
{
RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
}
USART_CHANNEL->CR1 = 0; // The = 0 is on purpose to set uart to default mode.
USART_CHANNEL->CR2 = 0; // The = 0 is on purpose to set uart to default mode.
USART_CHANNEL->CR3 = 0; // The = 0 is on purpose to set uart to default mode.
usartSetBaudRate(channel,baud);
usartSetWordLenght(channel, lenght);
usartSetHwFlowCtrl(channel, flowCtrl);
USART_CHANNEL->CR1 |= USART_CR1_TE; //Enbale trasnmit
USART_CHANNEL->CR1 |= USART_CR1_RE; //Enable recieve
//UART Enable shall allwas be at the end of configuration.
USART_CHANNEL->CR1 |= USART_CR1_UE;
}
void usartInitTx(pinNo_t pinTx)
{
//pinConfig(pinTx, alternate, def_stage, def_res, def_speed);
pinSetMode(pinTx,alternate);
pinSetAlternate(pinTx, AF1);
}
void usartInitRx(pinNo_t pinRx)
{
//pinConfig(pinRx, alternate, def_stage, def_res, def_speed);
pinSetMode(pinRx,alternate);
pinSetAlternate(pinRx, AF1);
}
//this one is special as the register bist's don't follow eachother.
void usartSetWordLenght(usartNo_t channel, usartWordLength_t lenght)
{
if(lenght == seven)
{
USART_CHANNEL->CR1 |= USART_CR1_M1;
USART_CHANNEL->CR1 &= ~USART_CR1_M0;
}
else if (lenght == eight)
{
USART_CHANNEL->CR1 &= ~USART_CR1_M0;
USART_CHANNEL->CR1 &= ~USART_CR1_M1;
}
else if(lenght == nine)
{
USART_CHANNEL->CR1 &= ~USART_CR1_M1;
USART_CHANNEL->CR1 |= USART_CR1_M0;
}
}
static uint16_t usartComputeBaudRate(uint32_t clk, uint32_t baud)
{
//return((clk + (baud/2U))/baud);
return(clk/baud);
}
void usartSetBaudRate(usartNo_t channel, uint32_t baud)
{
USART_CHANNEL->BRR = usartComputeBaudRate(SYST_CLK,baud);
}
void usartSetHwFlowCtrl(usartNo_t channel, usartHwFlowCtrl_t flowCtrl)
{
if(flowCtrl == noFlowControl)
{
USART_CHANNEL->CR3 &= ~USART_CR3_CTSE;
USART_CHANNEL->CR3 &= ~USART_CR3_RTSE;
}
else if(flowCtrl == cts)
{
USART_CHANNEL->CR3 |= USART_CR3_CTSE;
}
else if(flowCtrl == rts)
{
USART_CHANNEL->CR3 |= USART_CR3_RTSE;
}
else if(flowCtrl == ctsRts)
{
USART_CHANNEL->CR3 |= USART_CR3_CTSE;
USART_CHANNEL->CR3 |= USART_CR3_RTSE;
}
}
void print_Usart(usartNo_t channel,char *ptr)
{
uint16_t len = 0;
while(ptr[len] != '\0')
{
usartSendChar(channel, ptr[len]);
len++;
}
}
void usartSendChar(usartNo_t channel, uint8_t ch)
{
// Make sure that TX buffer is empty
while(!(USART_CHANNEL->ISR & USART_ISR_TXE)){}
USART_CHANNEL->TDR = ch;
}
uint8_t usartGetChar(usartNo_t channel)
{
// Make sure that TX buffer is empty
while(!(USART_CHANNEL->ISR & USART_ISR_RXNE)){}
return USART_CHANNEL->RDR;
}