| /* Freescale K20 microprocessor UART register definitions */ |
| |
| /* |
| * Copyright (c) 2013-2014 Wind River Systems, Inc. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are met: |
| * |
| * 1) Redistributions of source code must retain the above copyright notice, |
| * this list of conditions and the following disclaimer. |
| * |
| * 2) Redistributions in binary form must reproduce the above copyright notice, |
| * this list of conditions and the following disclaimer in the documentation |
| * and/or other materials provided with the distribution. |
| * |
| * 3) Neither the name of Wind River Systems nor the names of its contributors |
| * may be used to endorse or promote products derived from this software without |
| * specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
| * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| * POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| /** |
| * @brief Contains the UART Registers for the K20 Family of microprocessors. |
| */ |
| |
| #ifndef _K20UART_H_ |
| #define _K20UART_H_ |
| |
| #include <stdint.h> |
| #include <misc/__assert.h> |
| |
| typedef union { |
| uint8_t value; |
| struct { |
| uint8_t sbr : 5 __packed; /* Hi Baud Rate Bits */ |
| uint8_t res_5 : 1 __packed; |
| uint8_t rx_edge_int_en : 1 __packed; /* RxD Active Edge */ |
| uint8_t lbkd_int_en : 1 __packed; /* LIN Break Detect */ |
| } field; |
| } BDH_t; /* 0x000 BaudRate High */ |
| |
| typedef union { |
| uint8_t value; |
| struct { |
| uint8_t odd_parity : 1 __packed; |
| uint8_t parity_enable : 1 __packed; |
| uint8_t idle_line_type : 1 __packed; |
| uint8_t rx_wakep_method : 1 __packed; |
| uint8_t mode9bit : 1 __packed; |
| uint8_t remote_loopback : 1 __packed; |
| uint8_t uart_stop_wait : 1 __packed; |
| uint8_t loopback_en : 1 __packed; |
| } field; |
| } C1_t; /* 0x002 Control 1 */ |
| |
| #define RX_EN_MASK 0x04 |
| #define TX_EN_MASK 0x08 |
| |
| typedef union { |
| uint8_t value; |
| struct { |
| uint8_t send_break : 1 __packed; |
| uint8_t rx_wakeup_ctrl : 1 __packed; |
| uint8_t rx_enable : 1 __packed; |
| uint8_t tx_enable : 1 __packed; |
| uint8_t idle_line_int_en : 1 __packed; |
| uint8_t rx_full_int_dma_tx_en : 1 __packed; |
| uint8_t tx_complete_int_en : 1 __packed; |
| uint8_t tx_int_dma_tx_en : 1 __packed; |
| } field; |
| } C2_t; /* 0x003 Control 2 */ |
| |
| typedef union { |
| uint8_t value; |
| struct { |
| uint8_t parity_err_int_en : 1 __packed; |
| uint8_t frame_err_int_en : 1 __packed; |
| uint8_t noise_err_int_en : 1 __packed; |
| uint8_t overrun_err_int_en : 1 __packed; |
| uint8_t tx_data_invert : 1 __packed; |
| uint8_t tx_data_pin_outt_dir : 1 __packed; |
| uint8_t tx_bit8 : 1 __packed; |
| uint8_t rx_bit8 : 1 __packed; |
| } field; |
| } C3_t; /* 0x006 Control 3 */ |
| |
| typedef union { |
| uint8_t value; |
| struct { |
| uint8_t brfa : 5 __packed; /* BaudRateFineAdjust*/ |
| uint8_t mode10bit : 1 __packed; |
| uint8_t matech_addr_mode1_en : 1 __packed; |
| uint8_t match_addr_mode2_en : 1 __packed; |
| } field; |
| } C4_t; /* 0x00A Control 4 */ |
| |
| #define TX_DATA_EMPTY_MASK 0x80 |
| #define RX_DATA_FULL_MASK 0x20 |
| |
| typedef union { |
| uint8_t value; |
| struct { |
| uint8_t parity_err : 1 __packed; |
| uint8_t framing_err : 1 __packed; |
| uint8_t noice : 1 __packed; |
| uint8_t rx_overrun : 1 __packed; |
| uint8_t idle_line : 1 __packed; |
| uint8_t rx_data_full : 1 __packed; |
| uint8_t tx_complete : 1 __packed; |
| uint8_t tx_data_empty : 1 __packed; |
| } field; |
| } S1_t; /* 0x004 Status 1 */ |
| |
| typedef union { |
| uint8_t value; |
| struct e { |
| uint8_t rx_active : 1 __packed; |
| uint8_t lin_bk_detect_en : 1 __packed; |
| uint8_t brk_char_len13 : 1 __packed; |
| uint8_t rx_wakeup_idle_detect : 1 __packed; |
| uint8_t rx_data_inverted : 1 __packed; |
| uint8_t msb_first : 1 __packed; |
| uint8_t rxedgif : 1 __packed; |
| uint8_t lbkdif : 1 __packed; |
| } field; |
| } S2_t; /* 0x005 Status 2 */ |
| |
| #define FIFO_SIZE_1 0 |
| #define FIFO_SIZE_4 1 |
| #define FIFO_SIZE_8 2 |
| #define FIFO_SIZE_16 3 |
| #define FIFO_SIZE_32 4 |
| #define FIFO_SIZE_64 5 |
| #define FIFO_SIZE_128 6 |
| #define FIFO_SIZE_RES 6 /* Reserved size */ |
| |
| #define RX_FIFO_EN_MASK 0x08 |
| #define TX_FIFO_EN_MASK 0x80 |
| |
| typedef union { |
| uint8_t value; |
| struct { |
| uint8_t rx_fifo_size : 3 __packed; /* read-only */ |
| uint8_t rx_fifo_en : 1 __packed; |
| uint8_t tx_fifo_size : 3 __packed; /* read-only */ |
| uint8_t tx_fifo_en : 1 __packed; |
| } field; |
| } PFIFO_t; /* 0x010 Fifo Parameter 1 */ |
| |
| #define RX_FIFO_FLUSH_MASK 0x40 |
| #define TX_FIFO_FLUSH_MASK 0x80 |
| |
| typedef union { |
| uint8_t value; |
| struct { |
| uint8_t rx_fifo_underflow_int_en : 1 __packed; |
| uint8_t tx_fifo_overflow_int_en : 1 __packed; |
| uint8_t rx_fifo_overflow_int_en : 1 __packed; |
| uint8_t res_3 : 3 __packed; |
| uint8_t rx_fifo_flush : 1 __packed; /* write-only */ |
| uint8_t tx_fifo_flush : 1 __packed; /* write-only */ |
| } field; |
| } CFIFO_t; /* 0x011 Fifo Control */ |
| |
| typedef volatile struct { |
| BDH_t bdh; /* 0x000 Baud Rate High */ |
| uint8_t bdl; /* 0x001 Baud Rate Low (04)*/ |
| C1_t c1; /* 0x002 Control 1 */ |
| C2_t c2; /* 0x003 Control 2 */ |
| S1_t s1; /* 0x004 Status 1 (C0) RO*/ |
| S2_t s2; /* 0x005 Status 2 */ |
| C3_t c3; /* 0x006 Control 3 */ |
| uint8_t d; /* 0x007 Data */ |
| uint8_t ma1; /* 0x008 Match Address 1 */ |
| uint8_t ma2; /* 0x009 Match Address 1 */ |
| C4_t c4; /* 0x00A Control 4 */ |
| uint8_t c5; /* 0x00B Control 5 */ |
| uint8_t ed; /* 0x00C Extended Data */ |
| uint8_t modem; /* 0x00D Modem */ |
| uint8_t ir; /* 0x00E Infrared */ |
| uint8_t z_reserved00f; /* 0x00F */ |
| PFIFO_t pfifo; /* 0x010 FIFO Param */ |
| CFIFO_t cfifo; /* 0x011 FIFO Control */ |
| uint8_t sfifo; /* 0x012 FIFO Status (C0)*/ |
| uint8_t twfifo; /* 0x013 FIFO Tx Watermark */ |
| uint8_t tcfifo; /* 0x014 FIFO Tx Count */ |
| uint8_t rwfifo; /* 0x015 FIFO Rx Watermark (01)*/ |
| uint8_t rcfifo; /* 0x016 FIFO Rx Count */ |
| uint8_t u_7816[0x20 - 0x17]; /* 0x017-0x1F UART ISO-7816 standard */ |
| uint8_t u_cea709_1[0x32 - 0x20]; /* 0x020-0x31 UART CEA8709.1 standard |
| */ |
| uint8_t z_reserv_statused038_03c[0x1000 - 0x32]; /* 0x032-0xFFF |
| Reserved */ |
| } K20_UART_t; /* K20 Microntroller UART module */ |
| |
| /** Device data structure */ |
| struct uart_k20_dev_data_t { |
| uint8_t seq_port_num; /**< Sequential port number */ |
| }; |
| |
| /** |
| * @brief Set baud rate for K20 UART port. |
| * |
| * @param uart_p UART data |
| * @param clk_freq Clock frequency |
| * @param baud_rate Baud rate to set |
| * |
| * @return None |
| */ |
| static ALWAYS_INLINE void _k20_uart_baud_rate_set(K20_UART_t *uart_p, |
| uint32_t clk_freq, |
| uint32_t baud_rate) |
| { |
| /* |
| * The baud rate is calculated as: |
| * baud_rate = clk_freq/(16*(SBR[12:0]+BRFA[5:0]/32)), where |
| * - SBR is the combined UART Baud Rate Register settings and |
| * - BRFA is the UART Baud Rate Fine Adjustment setting |
| * This is equivalent to: |
| * 32xSBR + BRFA = 2 * clkFreq/baudRate |
| */ |
| uint32_t clk_br = 2 * clk_freq / baud_rate; |
| uint16_t sbr = clk_br >> 5; |
| uint8_t brfa = clk_br - (sbr << 5); |
| |
| __ASSERT((sbr && 0x1FFF), |
| "clk_freq is too high or baud_rate is too low"); |
| |
| /* Note there are other fields (interrupts flag) in BDH register */ |
| uart_p->bdh.field.sbr = (uint8_t)(sbr >> 8); |
| uart_p->bdl = (uint8_t)(sbr & 0xFF); |
| uart_p->c4.field.brfa = brfa; |
| } |
| |
| /** |
| * @brief Enable FIFO for K20 UART port |
| * |
| * @param uart_p UART data |
| * |
| * @return None |
| */ |
| static inline void _k20_uart_fifo_enable(K20_UART_t *uart_p) |
| { |
| uint8_t tx_rx_state = uart_p->c2.value && (TX_EN_MASK | RX_EN_MASK); |
| |
| /* disable Rx and Tx */ |
| uart_p->c2.value &= !(TX_EN_MASK | RX_EN_MASK); |
| |
| uart_p->pfifo.value |= (TX_FIFO_EN_MASK | RX_FIFO_EN_MASK); |
| |
| uart_p->cfifo.value |= (TX_FIFO_FLUSH_MASK | RX_FIFO_FLUSH_MASK); |
| |
| /* restore Rx and Tx */ |
| uart_p->c2.value |= tx_rx_state; |
| } |
| |
| #endif /* _K20UART_H_ */ |