wip
This commit is contained in:
30
src/gpio.h
30
src/gpio.h
@@ -13,10 +13,36 @@ struct gpio {
|
||||
volatile uint32_t ODR; // Port output data register
|
||||
volatile uint32_t BSRR; // Port bit set/reset register
|
||||
volatile uint32_t LCKR; // Port configuration lock register
|
||||
volatile uint32_t AFRL[2]; // Alternative function low register
|
||||
volatile uint32_t AFRH[2]; // Alternative function high register
|
||||
volatile uint32_t AFRL; // Alternative function low register
|
||||
volatile uint32_t AFRH; // Alternative function high register
|
||||
};
|
||||
|
||||
#define GPIOA_BASE_ADDR (0x40020000U)
|
||||
#define GPIOA ((struct gpio *) GPIOA_BASE_ADDR)
|
||||
|
||||
// MODER register
|
||||
#define GPIO_MODER_MODER3_BIT 7 // Bits [7:6]
|
||||
#define GPIO_MODER_MODER3_MASK (0b11)
|
||||
#define GPIO_MODER_MODER3_AF (0b10)
|
||||
|
||||
#define GPIO_MODER_MODER2_BIT 4 // Bits [5:4]
|
||||
#define GPIO_MODER_MODER2_MASK (0b11)
|
||||
#define GPIO_MODER_MODER2_AF (0b10)
|
||||
|
||||
// AFRL register
|
||||
#define GPIO_AFRL_AFRL3_BIT 12 // Bits [15:12]
|
||||
#define GPIO_AFRL_AFRL3_MASK (0b1111)
|
||||
#define GPIO_AFRL_AFRL3_USART2_RX (0b0111) // Alternative function 7
|
||||
|
||||
#define GPIO_AFRL_AFRL2_BIT 8 // Bits [11:8]
|
||||
#define GPIO_AFRL_AFRL2_MASK (0b1111)
|
||||
#define GPIO_AFRL_AFRL2_USART2_TX (0b0111) // Alternative function 7
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define GPIO_BASE_ADDR (0x40020000U)
|
||||
#define GPIO_PORT_OFFSET (0x400U)
|
||||
#define GPIO(port) ((struct gpio*)(uintptr_t)(GPIO_BASE_ADDR + (GPIO_PORT_OFFSET * port)))
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "flash.h"
|
||||
#include "pwr.h"
|
||||
#include "timer.h"
|
||||
#include "usart.h"
|
||||
|
||||
#define exit 42
|
||||
|
||||
@@ -76,7 +77,9 @@ static void system_clock_init(void) {
|
||||
int main(void) {
|
||||
(void) system_clock_init();
|
||||
(void) tim4_init();
|
||||
(void) usart2_init();
|
||||
|
||||
(void) tim4_start();
|
||||
(void) tim4_start();
|
||||
|
||||
uint16_t led = PIN('C', 13); // Blue LED
|
||||
@@ -90,6 +93,9 @@ int main(void) {
|
||||
led_on = !led_on;
|
||||
gpio_write(led, led_on);
|
||||
|
||||
while ((USART2->ISR & USART_ISR_TC) != USART_ISR_TC);
|
||||
USART2->TDR = '#';
|
||||
|
||||
counter = TIM4->CNT;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -114,10 +114,18 @@ struct rcc {
|
||||
#define RCC_CFGR_SW_MASK (0b11)
|
||||
#define RCC_CFGR_SW(clock) ((clock & RCC_CFGR_SW_MASK) << RCC_CFGR_SW_BIT)
|
||||
|
||||
// AHB1ENR Register
|
||||
// GPIOA AHB1ENR
|
||||
#define RCC_AHB1ENR_GPIOAEN_BIT 0
|
||||
#define RCC_AHB1ENR_GPIOAEN_ENABLE (1 << RCC_AHB1ENR_GPIOAEN_BIT)
|
||||
|
||||
// APB1ENR Register
|
||||
#define RCC_APB1ENR_PWREN_BIT 28
|
||||
#define RCC_APB1ENR_PWREN_CLOCK_ENABLE (1 << RCC_APB1ENR_PWREN_BIT)
|
||||
|
||||
#define RCC_APB1ENR_USART2EN_BIT 17
|
||||
#define RCC_APB1ENR_USART2EN_ENABLE (1 << RCC_APB1ENR_USART2EN_BIT)
|
||||
|
||||
#define RCC_APB1ENR_TIM4_BIT 2
|
||||
#define RCC_APB1ENR_TIM4_ENABLE (1 << RCC_APB1ENR_TIM4_BIT)
|
||||
|
||||
|
||||
@@ -18,5 +18,5 @@ void tim4_init(void) {
|
||||
}
|
||||
|
||||
void tim4_start(void) {
|
||||
TIM4->CR1 |= TIM4_ENABLE;
|
||||
TIM4->CR1 |= TIM_ENABLE;
|
||||
}
|
||||
|
||||
@@ -29,8 +29,8 @@ struct timer {
|
||||
#define TIM4_BASE_ADDR (0x40000800U)
|
||||
#define TIM4 ((struct timer *) TIM4_BASE_ADDR)
|
||||
|
||||
#define TIM4_CR_CEN_BIT 0
|
||||
#define TIM4_ENABLE (1 << TIM4_CR_CEN_BIT)
|
||||
#define TIM_CR1_CEN_BIT 0
|
||||
#define TIM_ENABLE (1 << TIM_CR1_CEN_BIT)
|
||||
|
||||
void tim4_init(void);
|
||||
void tim4_start(void);
|
||||
|
||||
63
src/usart.c
Normal file
63
src/usart.c
Normal file
@@ -0,0 +1,63 @@
|
||||
#include "rcc.h"
|
||||
#include "gpio.h"
|
||||
#include "usart.h"
|
||||
|
||||
void usart2_init(void) {
|
||||
// Enable clock for GPIOA
|
||||
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN_ENABLE;
|
||||
|
||||
// Configure PA2 and PA3 (USART2 pins) to use alternative functions
|
||||
GPIOA->MODER &= ~(GPIO_MODER_MODER2_MASK << GPIO_MODER_MODER2_BIT);
|
||||
GPIOA->MODER |= (GPIO_MODER_MODER2_AF << GPIO_MODER_MODER2_BIT);
|
||||
GPIOA->MODER &= ~(GPIO_MODER_MODER3_MASK << GPIO_MODER_MODER3_BIT);
|
||||
GPIOA->MODER |= (GPIO_MODER_MODER3_AF << GPIO_MODER_MODER3_BIT);
|
||||
|
||||
// Set pin alternative modes to use USART
|
||||
GPIOA->AFRL &= ~(GPIO_AFRL_AFRL2_MASK << GPIO_AFRL_AFRL2_BIT);
|
||||
GPIOA->AFRL |= (GPIO_AFRL_AFRL2_USART2_TX << GPIO_AFRL_AFRL2_BIT);
|
||||
GPIOA->AFRL &= ~(GPIO_AFRL_AFRL3_MASK << GPIO_AFRL_AFRL3_BIT);
|
||||
GPIOA->AFRL |= (GPIO_AFRL_AFRL3_USART2_RX << GPIO_AFRL_AFRL3_BIT);
|
||||
|
||||
// Enable USART
|
||||
RCC->AHB1ENR |= RCC_APB1ENR_USART2EN_ENABLE;
|
||||
|
||||
// Clear control registers
|
||||
USART2->CR1 = 0;
|
||||
USART2->CR2 = 0;
|
||||
USART2->CR3 = 0;
|
||||
|
||||
// Calculate Baud rate:
|
||||
// baud = f_clock / (8 * (2 - OVER8) * USARTDIV); =>
|
||||
// (8 * (2 - OVER8) * USARTDIV) = f_clock / baud; =>
|
||||
// USARTDIV = (f_clock / (baud * (8 * (2 - OVER8))); =>
|
||||
|
||||
// Target Baud rate = 115200, f_clock = 48MHz
|
||||
|
||||
// With OVER8 = 1 (oversampling by 8)
|
||||
// USARTDIV = (48E6 / (115200 * (8 * (2 - 1))) = 52.083
|
||||
// mantissa = 52
|
||||
// fraction = 0.083 * 8 = 0.664 ~= 1
|
||||
|
||||
// rounding fraction up: USARTDIV = 53
|
||||
// baud = 48E6 / (8 * (52 + 1)) = 113207.54716981133
|
||||
// error of 0.1% (115200 / 113207.54716981133)
|
||||
|
||||
// rounding fraction down: USARTDIV = 52
|
||||
// baud = 48E6 / (8 * 52) = 115384.61538461539
|
||||
// error of 0.001% (115384.61538461539 / 115200)
|
||||
|
||||
USART2->CR1 |= USART_CR1_OVER8_8;
|
||||
|
||||
USART2->BRR &= ~(USART_BRR_MANTISSA_MASK << USART_BRR_MANTISSA_BIT);
|
||||
USART2->BRR |= (52 << USART_BRR_MANTISSA_BIT);
|
||||
USART2->BRR &= ~(USART_BRR_FRACTION_MASK << USART_BRR_FRACTION_BIT);
|
||||
USART2->BRR |= (0 << USART_BRR_FRACTION_BIT);
|
||||
|
||||
// Enable transmitter and receiver
|
||||
USART2->CR1 |= USART_CR1_TE_ENABLE;
|
||||
USART2->CR1 |= USART_CR1_RE_ENABLE;
|
||||
}
|
||||
|
||||
void usart2_start(void) {
|
||||
USART2->CR1 |= USART_CR1_UE_ENABLE;
|
||||
}
|
||||
46
src/usart.h
Normal file
46
src/usart.h
Normal file
@@ -0,0 +1,46 @@
|
||||
#ifndef USART_H_
|
||||
#define USART_H_
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
struct usart {
|
||||
volatile uint32_t SR; // Status register
|
||||
volatile uint32_t DR; // Data register
|
||||
volatile uint32_t BRR; // Baud rate register
|
||||
volatile uint32_t CR1; // Control register 1
|
||||
volatile uint32_t CR2; // Control register 2
|
||||
volatile uint32_t CR3; // Control register 3
|
||||
volatile uint32_t GTPR; // Guard time and prescaler registe
|
||||
};
|
||||
|
||||
#define USART2_BASE_ADDR (0x40004400U)
|
||||
#define USART2 ((struct usart *) USART2_BASE_ADDR)
|
||||
|
||||
// CR Register
|
||||
// Oversampling mode
|
||||
#define USART_CR1_OVER8_BIT 15
|
||||
#define USART_CR1_OVER8_8 (1 << USART_CR1_OVER8_BIT)
|
||||
|
||||
// USART enable
|
||||
#define USART_CR1_UE_BIT 13
|
||||
#define USART_CR1_UE_ENABLE (1 << USART_CR1_UE_BIT)
|
||||
|
||||
// Trasmitter enable
|
||||
#define USART_CR1_TE_BIT 3
|
||||
#define USART_CR1_TE_ENABLE (1 << USART_CR1_TE_BIT)
|
||||
|
||||
// Receiver enable
|
||||
#define USART_CR1_RE_BIT 2
|
||||
#define USART_CR1_RE_ENABLE (1 << USART_CR1_RE_BIT)
|
||||
|
||||
// BRR Register
|
||||
#define USART_BRR_MANTISSA_BIT 4 // Bits [15:4]
|
||||
#define USART_BRR_MANTISSA_MASK (0b111111111111) // Bits [15:4]
|
||||
|
||||
#define USART_BRR_FRACTION_BIT 0 // Bits [3:0]
|
||||
#define USART_BRR_FRACTION_MASK (0b111) // Bits [3:0]
|
||||
|
||||
void usart2_init(void);
|
||||
void usart2_start(void);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user