#ifndef H__USART_ #define H__USART_ #include "common.h" #include "rcc.h" #include /* * Possibel 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 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. */ 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:5; bits_t deat:5; bits_t rtoie:1; bits_t eobie:1; bits_t m1:1; bits_t reserved:3; } 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. */ 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; uint32_t is_r; uint32_t ic_r; uint32_t rd_r; uint32_t td_r; } usart_t; #define USART1 (* (__IO usart_t*) 0x40013800) #define USART2 (* (__IO usart_t*) 0x40004400) typedef enum { OVERSAMPLE_8, OVERSAMPLE_16 } oversampling_mode_t; static inline void usart_set_divisor( __IO usart_t* usart, uint16_t usartdiv) { if (usart->c1.r & (1 << 15)) { /* OVER8 is set. */ usart->br.over8.high = (usartdiv & ~7); usart->br.over8.low = ((usartdiv & 7) >> 1); } else { /* OVER8 is not set. */ usart->br.v = usartdiv; } } static inline void usart_set_oversampling_mode( __IO usart_t* usart, oversampling_mode_t mode) { usart->c1.over8 = mode == OVERSAMPLE_8; } typedef enum { USART_PARITY_DISABLED = 0, USART_PARITY_ODD = 1, USART_PARITY_EVEN = 2, } 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); /* * Send a byte on the usart, This command blocks until the data * is fully sent. */ void usart_transmit_byte(__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( __IO usart_t* usart, const uint8_t* bytes, uint32_t n); void usart_transmit_str(__IO usart_t* usart, const char* str); void usart_printf(__IO usart_t* usart, const char* fmt, ...); /* Returns non-zero if usart2 is enabled. */ int is_usart2_enabled(); /* Enable the second USART. */ int enable_usart2(uint32_t baud); #endif /* H__USART_ */