#ifndef H__USART_ #define H__USART_ #include #include #include "common.h" #include "rcc.h" #include #define USART1 (* (__IO usart_t*) USART1_BASE) #define USART2 (* (__IO usart_t*) USART2_BASE) /* * Possible USART clock sources. */ typedef enum { USART_CLK_SRC_PLK = 0, /* Clock derived from the SysClk. */ USART_CLK_SRC_SYSCLK = 1, /* System clock. */ USART_CLK_SRC_HSI16 = 2, /* 16MHz oscillator. */ USART_CLK_SRC_LSE = 3 /* Low power 32kHz clock. */ } usart_clk_src_t; typedef struct { /* USART configuration registers 0x04 - 0x0c. */ union { __IO uint32_t c_r1; struct { bits_t ue:1; /* UART enable */ bits_t uesm:1; /* UART enabled in stop mode. */ bits_t re:1; /* reciever enabled. */ bits_t te:1; /* transmitter enabled. */ bits_t idleie:1; /* Idle interrupt enabled. */ 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; bits_t wake:1; bits_t m0:1; bits_t mme:1; bits_t cmie:1; bits_t over8:1; bits_t dedt:4; bits_t deat:4; bits_t rtoie:1; bits_t eobie:1; bits_t m1:1; bits_t reserved:3; } PACKED c1_bf; /* c1_bf = c1 bit field */ }; /* USART Control Register 1. */ __IO uint32_t c_r2; union { __IO uint32_t c_r3; struct { bits_t eie:1; // Error interrupt enable. bits_t iren:1; // IrDA mode enabled bits_t irlp:1; // IrDA low power bits_t hdsel:1; // Half duplex selection bits_t nack:1; // Smartcard NACK enable bits_t scen:1; // Smartocard mode enable bits_t dmar:1; // DMA enable reciever bits_t dmat:1; // DMA enable transmitter bits_t rtse:1; // RTS enable bits_t ctse:1; // CTS enable bits_t ctsie:1; // CTS interrupt enable bits_t onebit:1; // One sample bit method enable bits_t ovrdis:1; // Overrun disable bits_t ddre:1; // DMA Disable on reception error bits_t dem:1; // Driver enable mode bits_t dep:1; // Driver enable polarity selection bits_t reserved0:1; bits_t scarcnt:3; // Smartcard auto-retry count. bits_t wus:2; // Wakeup from STOP mode interrept flag selection bits_t wufie:1; // Wakeup from STOP mode interrup enable bits_t ucesm:1; // USART clock enable in STOP mode. bits_t tcbgtie:1; // Transmission complete before guard time interrupt bits_t reserved1:7; } PACKED c3_bf; }; /* USART baud rate register. */ uint32_t br_r; uint32_t gtp_r; uint32_t rto_r; uint32_t rq_r; /* USART ISR register. Offset = 0x1c*/ union { __IO uint32_t is_r; /* Interrupt service register. */ struct { bits_t pe:1; // Parity error bits_t fe:1; // Framing error bits_t nf:1; // START bit noise detection flag. bits_t ore:1; // Overrun error bits_t dlie:1; // Idle line detected bits_t rxne:1; // Read data register not empty bits_t tc:1; // Transmission complete bits_t txe:1; // Transmit data register empty bits_t lbdf:1; // LIN break detection flag bits_t ctsif:1; // CTS interrupt flag bits_t cts:1; // CTS flag. bits_t rtof:1; // Receiever timeout bits_t eobf:1; // End of block flag bits_t reserved0:1; bits_t abre:1; // Auto baud rate error bits_t abrf:1; // Auto baud rate flag bits_t busy:1; // Busy flag bits_t cmf:1; // Character match flag bits_t sbkf:1; // send break flag bits_t rwu:1; // receiver wakeup frlom mute mode. bits_t wuf:1; // Wakeup from stop mode flag bits_t teack:1; // Transmit enable acknowledge flag. bits_t reack:1; // Receieve enable acknowledge flag. bits_t reserved1:2; bits_t tcbgt:1; // Transmission completer before guard time completion. bits_t reserved2:6; } PACKED is_bf; /* Interrupt servite bit field. */ }; union { __IO uint32_t ic_r; struct { bits_t pecf:1; // Parity error clear flag bits_t fecf:1; // Framing error clear flag bits_t ncf:1; // Noise detected clear flag bits_t orecf:1; // Overrun error clear flag bits_t idlecf:1; // Idle line detected clear flag bits_t reserved0:1; bits_t tccf:1; // Transmission complete clear flag bits_t tcbgtcf:1; // Transmission completed before guard time clear flag bits_t lbdcf:1; // LIN break detection clear flag bits_t ctscf:1; // CTS clear flag bits_t reserved1:1; bits_t rtocf:1; // Receiver timeout clear flag bits_t eobcf:1; // End of block clear flag bits_t reserved2:4; bits_t cmcf:1; // Character match clear flag bits_t reserved3:2; // Character match clear flag bits_t wucf:1; // Wakeup from Stop mode clear flag. bits_t reserved4:11; } PACKED ic_bf; }; uint32_t rd_r; uint32_t td_r; } usart_t; static_assert(offsetof(usart_t, ic_r) == 0x20, "Offset assertion failed."); static_assert(offsetof(usart_t, rd_r) == 0x24, "Offset assertion failed."); typedef enum { OVERSAMPLE_8, OVERSAMPLE_16 } oversampling_mode_t; static inline void usart_set_divisor( __IO usart_t* usart, uint32_t usartdiv) { if (usart->c_r1 & (1 << 15)) { /* OVER8 is set. */ usart->br_r = (usartdiv & ~7) | ((usartdiv & 7) >> 1); } else { /* OVER8 is not set. */ usart->br_r = usartdiv; } } 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); } } typedef enum { USART_PARITY_DISABLED = 0, USART_PARITY_EVEN = 2 << 9, USART_PARITY_ODD = 3 << 9, } usart_parity_t; typedef enum { USART_ENABLE_TX = 0x02, USART_ENABLE_RX = 0x01, USART_ENABLE_DISABLED = 0x00, } usart_enable_t; void usart_set_parity(__IO usart_t* usart, usart_parity_t parity); void usart_set_enabled(__IO usart_t* usart, usart_enable_t enabled); void usart_enable_dma(__IO usart_t* usart, usart_enable_t enabled); /* * Send a byte on the usart, This command blocks until the data * is fully sent. */ void usart_transmit_byte_sync(__IO usart_t* usart, uint8_t byte); void set_usart1_clock_src(__IO rcc_t* rcc, usart_clk_src_t usart_clk_src); void set_usart1_clock_enabled(__IO rcc_t* rcc, bool enable); void set_usart2_clock_src(__IO rcc_t* rcc, usart_clk_src_t usart_clk_src); void set_usart2_clock_enabled(__IO rcc_t* rcc, bool enable); void usart_transmit_bytes_sync( __IO usart_t* usart, const uint8_t* bytes, uint32_t n); void usart_transmit_str_sync(__IO usart_t* usart, const char* str); void usart_printf(__IO usart_t* usart, const char* fmt, ...); #endif /* H__USART_ */