main.c
#include "uart4.h"
extern void printf(const char *fmt, ...);
void delay_ms(int ms)
{
int i,j;
for(i = 0; i < ms;i++)
for (j = 0; j < 1800; j++);
}
int main()
{
hal_uart4_init();
while(1)
{
char temp = ' ';
temp = hal_get_char();
hal_put_char(temp + 1);
}
return 0;
}
uart4.h
#ifndef __UART4_H__
#define __UART4_H__
#include "stm32mp1xx_uart.h"
#include "stm32mp1xx_gpio.h"
#define GPIOB ((gpio_t*)0x50003000)
#define GPIOG ((gpio_t*)0x50008000)
#define RCC_MP_AHB4ENSETR ((volatile int*)0x50000A28)#define RCC_MP_APB1ENSETR ((volatile int*)0x50000A00)
void hal_uart4_init();
void hal_put_char(const char str);
void hal_put_string(const char* string);
char hal_get_char();
char* hal_get_string();
int my_strlen(char*);
char *my_strcpy(char*,char*);
char *my_strcat(char*,char*);
void hal_gpio_init(gpio_t*, unsigned int, gpio_init_t*);
void operate_pin(gpio_t*,unsigned int,int);
#endif
uart4.c
#include "uart4.h"
int my_strlen(char *s1){
int len = 0;
while(*s1){
len++;
}
return len;
}
char *my_strcpy(char *s1, char *s2){
int i = 0;
while(*s2){
s1[i] = s2[i];
i++;
}
s1[i] = '\0';
return s1;
}
char *my_strcat(char *s1,char *s2){
int i = 0;
int len1 = my_strlen(s1);
int len2 = my_strlen(s2);
for(int i = 0; i <= len2; i++){
s1[len1 + i + 1] = s2[i];
}
s1[i] = '\0';
return s1;
}
void hal_gpio_init(gpio_t* gpiox,unsigned int pin, gpio_init_t* init){
gpiox->MODER &= ~(0b11 << pin * 2);
gpiox->MODER |= (init->moder << pin * 2);
gpiox->OTYPER &= ~(0b1 << pin);
gpiox->OTYPER |= (init->otyper << pin);
gpiox->OSPEEDR &= ~(0b11 << pin * 2);
gpiox->OSPEEDR |= (init->ospeedr << pin * 2);
gpiox->PUPDR &= ~(0b11 << pin * 2);
gpiox->PUPDR |= (init->pupdr << pin * 2);
}
void operate_pin(gpio_t* gpio,unsigned int pin,int operation_code){
if( operation_code == GPIO_RESET_T){
gpio->ODR &= (0x1 << pin);
}else{
gpio->ODR |= ~(0x1 << pin);
}
}
//initialize all the registers before enable transmission
void hal_uart4_init(){
//initialize RCCs to enable GPIOB GPIOG UART4
//enable GPIOB:
RCC_MP_AHB4ENSETR |= (0b1 << 1);
//enalbe GPIOG:
RCC_MP_AHB4ENSETR |= (0b1 << 6);
//enable UART4
RCC_MP_APB1ENSTER |= (0b1 << 16);
//set GPIOB to alternate function mode
GPIOB->MODER &= ~(0b11 << 2 * 2);
GPIOB->MODER |= 0b10 << 2 * 2;
GPIOB->AFRL &= ~(0b1111 << 8);
GPIOB->AFRL |= 0b1000 << 8;
//set GPIOG to alternate function mode
GPIOG->MODER &= ~(0b11 << 11 * 2);
GPIOG->MODER |= 0b11 << 11 * 2;
GPIOG->AFRH &= ~(0b1111 << 12);
GPIOG->AFRH |= 0b0110 << 12;
//disable USART first
USART4->CR1 &= ~(0b1 << 1);
//initialize CR1
//set word length to 8 by setting M1(28) = 0 & M0(12) = 0
USART4->CR1 &= ~(0b1 << 12);
USART4->CR1 &= ~(0b1 << 28);
//set oversampling mode to 16 bits by setting OVER8(15) = 0
USART4->CR1 &= ~(0b1 << 15);
//disable parity control by setting PCE(10) = 0
USART4->CR1 &= ~(0b1 << 10);
//enable transmitter by setting TE(3) = 1
USART4->CR1 |= (0b1 << 3);
//enable receiver by setting RE(2) = 1
USART4->CR1 |= (0b1 << 2);
//enable USART by setting UE(0) = 1
USART4->CR1 |= (0b1 << 0);
//initialize CR2
//set the number of STOP bits to 1 by setting STOP[13:12] = 00
USART->CR2 &= ~(0b11 << 12);
//initialize BRR
//set BRR register to set the braud rate
//the calulation formation is
//64MHz/115200=0x22b when oversampling by 16
USART->BRR = 0x22b;
//initialize PRESC
//set its value to 0x0000 to prevent dividing input clock
USART->PRESC = 0x0000;
}
void hal_put_char(const char str){
while(!(USART4->ISR & 0b1 << 7));
USART4->TDR = str;
while(!(USART4->ISR & 0b1 << 6));
}
void hal_put_string(const char* string){
int i = 0;
while(string[i] != '\0'){
hal_put_char(string[i]);
i++;
}
}
char hal_get_char(){
while(!(USART4->ISR & 0b1 << 5));
return USART4->RDR;
}
char *hal_get_string(){
char buf[16] = "";
char temp = ' ';
while(temp != '\r'){
temp = hal_get_char();
}
my_strcat(buf,&temp);
return buf;
}