#ifndef _BSP_UART_H #define _BSP_UART_H #include enum uart_parity_e {NONE = 0, EVEN = 1, ODD = 2}; enum uart_stop_e {ONE = 0, TWO = 1}; #ifndef APB_BUS typedef struct __attribute((__packed__)){ // 0x0 volatile uint16_t rx_tx_reg; // 8bit, 0x0 volatile uint16_t rx_avail; // 1bit, 0x0:16 // 0x4 volatile uint16_t irq_ctrl; // 0->tx_ie, 1->rx_ie, 8->tx_ip, 9->rx_ip volatile uint8_t num_tx_avail; // 8bit, 0x4:16 volatile uint8_t num_rx_avail; // 8bit, 0x4:24 volatile uint32_t dummy; // 0xc volatile uint8_t clock_div; // 3bit, 0xc:0 volatile uint8_t frame; // 2bit, 0xc:8 volatile uint8_t stop_bits; // 1bit, 0xc:16 // 0x10 volatile uint8_t status; // readError->0, readOverflowError->1, volatile uint8_t active; // rx_active->0, tx_active-1, set_tx_active->2, clear_tx_active->3 } uart_t; #else typedef struct __attribute((__packed__)) { volatile uint32_t DATA; volatile uint32_t STATUS; volatile uint32_t CLOCK_DIVIDER; volatile uint32_t FRAME_CONFIG; } uart_t; typedef struct __attribute((__packed__)) { uint32_t data_length; enum uart_parity_e parity; enum uart_stop_e stop; uint32_t clock_divider; } uart_config_t; static inline uint32_t uart_get_tx_free(volatile uart_t *reg){ return (reg->STATUS >> 16) & 0xFF; } static inline uint32_t uart_get_rx_avail(volatile uart_t *reg){ return reg->STATUS >> 24; } static void uart_write(volatile uart_t *reg, uint8_t data){ while(uart_get_tx_free(reg) == 0); reg->DATA = data; } static inline uint8_t uart_read(volatile uart_t *reg){ uint32_t res = reg->DATA; while((res&0x10000) == 0) res = reg->DATA; return res; } static inline void uart_set_config(volatile uart_t *reg, uart_config_t *config){ reg->CLOCK_DIVIDER = config->clock_divider; reg->FRAME_CONFIG = ((config->data_length-1) << 0) | (config->parity << 8) | (config->stop << 16); } #endif #endif /* _BSP_UART_H */