aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--03-refactor/include/clock.h8
-rw-r--r--03-refactor/include/rcc.h119
-rw-r--r--03-refactor/include/usart.h126
-rw-r--r--03-refactor/src/clock.c35
-rw-r--r--03-refactor/src/main.c18
-rw-r--r--03-refactor/src/usart.c16
6 files changed, 230 insertions, 92 deletions
diff --git a/03-refactor/include/clock.h b/03-refactor/include/clock.h
index 1191f73..30c1302 100644
--- a/03-refactor/include/clock.h
+++ b/03-refactor/include/clock.h
@@ -62,14 +62,6 @@ typedef enum {
PLLM_DIVISOR_8 = 7,
} pllm_divisor_t;
-/* Possible sources for the input clock. */
-typedef enum {
- PLL_SRC_NONE = 0,
- PLL_SRC_MSI = 1,
- PLL_SRC_HSI = 2,
- PLL_SRC_HSE = 3,
-} pll_src_t;
-
/* Valid sources for the system clock. */
typedef enum {
SYSTEM_CLOCK_SRC_MSI = 0,
diff --git a/03-refactor/include/rcc.h b/03-refactor/include/rcc.h
index b2abcd2..827d66f 100644
--- a/03-refactor/include/rcc.h
+++ b/03-refactor/include/rcc.h
@@ -6,6 +6,20 @@
#define RCC_BASE ((uint32_t)0x40021000)
+typedef enum {
+ SYS_CLK_SW_MSI,
+ SYS_CLK_SW_HSI,
+ SYS_CLK_SW_HSE,
+ SYS_CLK_SW_PLL,
+} sys_clk_sw_t;
+
+typedef enum {
+ PLL_SRC_NONE,
+ PLL_SRC_MSI,
+ PLL_SRC_HSI,
+ PLL_SRC_HSE
+} pll_src_t;
+
typedef struct {
/* Clock control register. Offset 0x00. */
union RCC_CR {
@@ -41,9 +55,80 @@ typedef struct {
} PACKED;
} __IO c;
- __IO uint32_t icsc_r; /* Internal clock srcs calibration register. 0x04 */
- __IO uint32_t cfg_r; /* clock confguration register. 0x08 */
- __IO uint32_t pllcfg_r; /* PLL Configuration register. 0x0c */
+ /* Internal clock sources calibration register (RCC_ICSCR) Offset 0x04. */
+ union RCC_ICSCR {
+ __IO uint32_t r; /* 32 bit register. */
+
+ /* Bit field for icsc_r. */
+ struct {
+ bits_t msical:8;
+ bits_t msitrim:8;
+ bits_t hsical:8;
+ bits_t hsitrim:5;
+
+ RESERVED(3);
+ } PACKED;
+ } __IO icscr;
+
+
+ /* Clock configuration register. */
+ union RCC_CFGR {
+ __IO uint32_t r;
+
+ /* Bitfields for cfg_r. */
+ struct {
+ sys_clk_sw_t sw:2; /* System clock switch. @see sys_clk_sw_t enum. */
+ sys_clk_sw_t sws:2; /* System clock switch status. */
+
+ bits_t hpre:4; /* AHB prescaler. */
+ bits_t ppre:3; /* APB low-speed prescaller. */
+
+ RESERVED(1);
+
+ bits_t stopwuck:1; /* Wakeup from Stop and CSS backup clock selection. */
+ bits_t mcosel:4; /* Microcontroller clock output. */
+ bits_t mcopre:3; /* MCO prescaller. */
+
+ RESERVED(1);
+ } PACKED __IO;
+ } __IO cfg;
+
+ /* PLL Configuration register. Offset 0x0c */
+ union RCC_PLLCFGR {
+ __IO uint32_t r;
+
+ /* Bitfields for pllcfg_r */
+ struct {
+ pll_src_t pllsrc:2; /* PLL input source clock. */
+
+ RESERVED(2);
+
+ bits_t pllm:3; /* Divisions factor for the main PLL and audio PLL */
+
+ RESERVED(1);
+
+ bits_t plln:7; /* main PLL multiplication factor for VCO, must be
+ * on interval [8, 86] inclusive */
+ RESERVED(1);
+
+ bits_t pllpen:1; /* Main PLL PLLSAI1CLK output enable. */
+ bits_t pllp:1; /* Main division factor for PLLP.
+ * 0 = 7, 1 = 17 */
+ RESERVED(2);
+
+ bits_t pllqen:1; /* Main PLL PLL48M1CLK output enabled. */
+ bits_t pllq:2; /* PLLQ division factor. in 2^x. */
+
+ RESERVED(1);
+
+ bits_t pllren:1; /* PLL PLLCLK enabled. */
+ bits_t pllr:2; ; /* main pll divion factor. 2^x. */
+
+ bits_t pllpdiv:5; /* PLLP division factor. 0 to be handled by PLLP. */
+
+ } PACKED __IO;
+ } __IO pllcfg;
+
__IO uint32_t pllsai1cfg_r; /* PLLSAI1 configuration register. 0x10 */
__IO uint32_t reserved_1; /* Not used. offset 0x14. */
@@ -95,32 +180,4 @@ typedef struct {
#define RCC (*(__IO rcc_t*)RCC_BASE)
-/* Macros to operate on the RCC registers. */
-
-/* Sets the HSE. rcc is the RCC to use, e is zero for off, non-zero for on. */
-#define set_hse(rcc, e) \
- do { \
- if (e) { \
- (rcc).c_r |= 1 << 16; \
- } else { \
- (rcc).c_r &= ~(1 << 16); \
- } \
- } while (0)
-
-/* Sets the HSI. rcc is the RCC to use, e is zero for off, non-zero for on. */
-#define set_hsi(rcc, e) \
- do { \
- if (e) { \
- (rcc).c_r |= 1 << 8; \
- } else { \
- (rcc).c_r &= ~(1 << 8); \
- } \
- } while (0)
-
-/* Checks to see if the hse is ready. */
-#define hse_ready(rcc) ((rcc).c_r & (1 << 17))
-
-/* Checks to see if the hse is ready. */
-#define hsi_ready(rcc) ((rcc).c_r & (1 << 10))
-
#endif
diff --git a/03-refactor/include/usart.h b/03-refactor/include/usart.h
index 257aab6..3fea253 100644
--- a/03-refactor/include/usart.h
+++ b/03-refactor/include/usart.h
@@ -17,9 +17,9 @@ typedef enum {
} usart_clk_src_t;
typedef struct {
- /* USART configuration registers 0x04 - 0x0c. */
- union {
- uint32_t c_r1;
+ /* USART conttrol register 1. */
+ union USART_CR1 {
+ __IO uint32_t r;
struct {
bits_t ue:1; /* UART enable */
bits_t uesm:1; /* UART enabled in stop mode. */
@@ -29,6 +29,7 @@ typedef struct {
bits_t rxneie:1; /* RXNEIE RXNE interrupt enable. */
bits_t tcie:1;
bits_t txeie:1;
+
bits_t peie:1;
bits_t ps:1;
bits_t pce:1;
@@ -37,19 +38,103 @@ typedef struct {
bits_t mme:1;
bits_t cmie:1;
bits_t over8:1;
- bits_t dedt:4;
- bits_t deat:4;
+
+ bits_t dedt:5;
+ bits_t deat:5;
+
bits_t rtoie:1;
bits_t eobie:1;
bits_t m1:1;
bits_t reserved:3;
- } PACKED c1_bf;
- };
- uint32_t c_r2;
- uint32_t c_r3;
+ } PACKED;
+ } __IO c1;
+
+ /* USART control register 2. */
+ union USART_CR2 {
+ __IO uint32_t r;
+
+ struct {
+ RESERVED(4);
+ bits_t addm7:1;
+ bits_t lbdl:1;
+ bits_t lbdie:1;
+ RESERVED(1);
+
+ bits_t lbcl:1;
+ bits_t cpha:1;
+ bits_t cpol:1;
+ bits_t clken:1;
+ bits_t stop:2;
+ bits_t linen:1;
+ bits_t swap:1;
+
+ bits_t rxinv:1;
+ bits_t txinv:1;
+ bits_t datainv:1;
+ bits_t msbfirst:1;
+ bits_t abren:1;
+ bits_t abrmod:2;
+ bits_t rtoen:1;
+
+ bits_t add:8;
+ } PACKED;
+ } __IO c2;
+
+ union USART_CR3 {
+ __IO uint32_t r;
+
+ struct {
+ bits_t eie:1;
+ bits_t iren:1;
+ bits_t irlp:1;
+ bits_t hdsel:1;
+ bits_t nack:1;
+ bits_t scen:1;
+ bits_t dmar:1;
+ bits_t dmat:1;
+
+ bits_t rtse:1;
+ bits_t ctse:1;
+ bits_t ctsie:1;
+ bits_t onebit:1;
+ bits_t ovrdis:1;
+ bits_t ddre:1;
+ bits_t dem:1;
+ bits_t dep:1;
+
+ RESERVED(1);
+ bits_t scarcnt:3;
+ bits_t wus:2;
+ bits_t wufie:1;
+ bits_t ucesm:1;
+
+ bits_t tcbgtie:1;
+ RESERVED(7);
+ } PACKED;
+ } __IO c3;
/* USART baud rate register. */
- uint32_t br_r;
+ union USART_BRR {
+ __IO uint32_t r;
+
+ struct {
+ uint16_t v;
+ RESERVED(16);
+ } PACKED;
+
+ /* Structure to use when OVER8 is set in the control register
+ * USART_C1. */
+ struct {
+ bits_t low:3;
+
+ RESERVED(1);
+
+ bits_t high:12;
+
+ RESERVED(16);
+ } PACKED over8;
+ } __IO br;
+
uint32_t gtp_r;
uint32_t rto_r;
uint32_t rq_r;
@@ -68,16 +153,15 @@ typedef enum {
static inline void usart_set_divisor(
__IO usart_t* usart,
- uint32_t usartdiv)
+ uint16_t usartdiv)
{
- if (usart->c_r1 & (1 << 15)) {
+ if (usart->c1.r & (1 << 15)) {
/* OVER8 is set. */
- usart->br_r =
- (usartdiv & ~7) |
- ((usartdiv & 7) >> 1);
+ usart->br.over8.high = (usartdiv & ~7);
+ usart->br.over8.low = ((usartdiv & 7) >> 1);
} else {
/* OVER8 is not set. */
- usart->br_r = usartdiv;
+ usart->br.v = usartdiv;
}
}
@@ -85,17 +169,13 @@ static inline void usart_set_oversampling_mode(
__IO usart_t* usart,
oversampling_mode_t mode)
{
- if (mode == OVERSAMPLE_8) {
- usart->c_r1 |= 1 << 15;
- } else {
- usart->c_r1 &= ~(1 << 15);
- }
+ usart->c1.over8 = mode == OVERSAMPLE_8;
}
typedef enum {
USART_PARITY_DISABLED = 0,
- USART_PARITY_EVEN = 2 << 9,
- USART_PARITY_ODD = 3 << 9,
+ USART_PARITY_ODD = 1,
+ USART_PARITY_EVEN = 2,
} usart_parity_t;
typedef enum {
diff --git a/03-refactor/src/clock.c b/03-refactor/src/clock.c
index c4dcbac..7256500 100644
--- a/03-refactor/src/clock.c
+++ b/03-refactor/src/clock.c
@@ -61,8 +61,21 @@ int configure_pll(
return E_BADPLLN;
}
- RCC.pllcfg_r = (pllp_div_factor << 27) | (pllr << 24) | (pllq << 20) |
- (pllp << 16) | (plln << 8) | (pllm << 4) | (pllsrc << 0);
+ union RCC_PLLCFGR tmp;
+
+ tmp.pllpdiv = pllp_div_factor;
+ tmp.pllr = pllr >> 1;
+ tmp.pllren = pllr & 1;
+ tmp.pllp = pllp >> 1;
+ tmp.pllpen = pllp & 1;
+ tmp.pllq = pllq >> 1;
+ tmp.pllqen = pllq & 1;
+ tmp.plln = plln;
+ tmp.pllm = pllm;
+
+ tmp.pllsrc = pllsrc;
+
+ RCC.pllcfg = tmp;
return 0;
}
@@ -79,13 +92,13 @@ int set_system_clock_MHz(uint8_t mhz)
pll_off();
configure_pll(
- 0 /* pllp_div_factor */, PLL_DIVISOR_4 /* pllr: VCO / 4 = mhz MHz. */,
- PLL_DIVISOR_4 /* pllq: VCO / 4 = mhz MHz */, PLLP_DIVISOR_7 /* pllp */,
-
- /* The following set the frequency of VCO to (mhz*4)MHz: mhz * 1 * 4MHz.
- */
- mhz /* plln | mhz */, PLLM_DIVISOR_1 /* pllm | 01 */,
- PLL_SRC_MSI /* pll src | 04 Mhz */);
+ 0,
+ PLL_DIVISOR_4,
+ PLL_DIVISOR_4,
+ PLLP_DIVISOR_7,
+ mhz,
+ PLLM_DIVISOR_1,
+ PLL_SRC_MSI);
pll_on();
@@ -101,8 +114,8 @@ int set_system_clock_MHz(uint8_t mhz)
int set_system_clock_src(system_clock_src_t src)
{
- uint8_t value = RCC.cfg_r & ~0x03;
- RCC.cfg_r = value | src;
+ uint8_t value = RCC.cfg.r & ~0x03;
+ RCC.cfg.r = value | src;
}
int enable_hsi(__IO rcc_t* rcc, bool enable)
diff --git a/03-refactor/src/main.c b/03-refactor/src/main.c
index 5af52ed..0545087 100644
--- a/03-refactor/src/main.c
+++ b/03-refactor/src/main.c
@@ -30,9 +30,9 @@ int enable_usart2(uint32_t baud_rate)
// disable USART first to allow setting of other control bits
// This also disables parity checking and enables 16 times oversampling
- USART2.c_r1 = 0;
- USART2.c_r2 = 0;
- USART2.c_r3 = 0;
+ USART2.c1.r = 0;
+ USART2.c2.r = 0;
+ USART2.c3.r = 0;
usart_set_divisor(&USART2, 16000000 / baud_rate);
usart_set_enabled(&USART2, USART_ENABLE_TX | USART_ENABLE_RX);
@@ -60,13 +60,13 @@ int enable_usart1(uint32_t baud_rate)
RCC.apb2rst_r &= ~BIT(14); /* De-assert reset of USART1 */
uint32_t baud_rate_div = 80000000 / baud_rate;
- USART1.c_r1 = 0;
- USART1.c_r2 = 0;
- USART1.c_r3 = 0;
- USART1.br_r = baud_rate_div;
+ USART1.c1.r = 0;
+ USART1.c2.r = 0;
+ USART1.c3.r = 0;
+ USART1.br.v = baud_rate_div;
- USART1.c_r1 |= BIT(3) | BIT(2);
- USART1.c_r1 |= BIT(0);
+ USART1.c1.r |= BIT(3) | BIT(2);
+ USART1.c1.r |= BIT(0);
/* Enable the transmitter and the receiver. */
usart_set_enabled(&USART1, USART_ENABLE_TX);
diff --git a/03-refactor/src/usart.c b/03-refactor/src/usart.c
index eddfbe7..a3b0061 100644
--- a/03-refactor/src/usart.c
+++ b/03-refactor/src/usart.c
@@ -31,23 +31,19 @@ void set_usart1_clock_enabled(__IO rcc_t* rcc, bool enable)
void usart_set_parity(__IO usart_t* usart, usart_parity_t parity)
{
- uint32_t c_r1 = usart->c_r1;
- c_r1 &= ~(0x3 << 9);
- c_r1 |= parity;
- usart->c_r1 = c_r1;
+ usart->c1.pce = !!parity;
+ usart->c1.ps = parity & 1;
}
void usart_set_enabled(__IO usart_t* usart, usart_enable_t enabled)
{
- uint32_t c_r1 = usart->c_r1;
-
if (!enabled) {
- usart->c1_bf.ue = 0;
+ usart->c1.ue = 0;
} else {
/* Set the rx enabled. */
- usart->c1_bf.re = !!(enabled & USART_ENABLE_RX);
- usart->c1_bf.te = !!(enabled & USART_ENABLE_TX);
- usart->c1_bf.ue = 1;
+ usart->c1.re = !!(enabled & USART_ENABLE_RX);
+ usart->c1.te = !!(enabled & USART_ENABLE_TX);
+ usart->c1.ue = 1;
}
}