diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2018-01-24 00:12:03 -0700 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2018-01-24 00:12:03 -0700 |
commit | 80360c4b8361320b726897c86ee13f9b4caf004a (patch) | |
tree | 9a590055e440025d7d36701a540d9e7e39c082d4 | |
parent | 2545ae2d57e5b70975e3fd3b3e570da13dbf62f0 (diff) | |
download | stm32l4-80360c4b8361320b726897c86ee13f9b4caf004a.tar.gz stm32l4-80360c4b8361320b726897c86ee13f9b4caf004a.tar.bz2 stm32l4-80360c4b8361320b726897c86ee13f9b4caf004a.zip |
More fields in USART and RCC set to use bitfields.
-rw-r--r-- | 03-refactor/include/clock.h | 8 | ||||
-rw-r--r-- | 03-refactor/include/rcc.h | 119 | ||||
-rw-r--r-- | 03-refactor/include/usart.h | 126 | ||||
-rw-r--r-- | 03-refactor/src/clock.c | 35 | ||||
-rw-r--r-- | 03-refactor/src/main.c | 18 | ||||
-rw-r--r-- | 03-refactor/src/usart.c | 16 |
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; } } |