1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 | /* Freescale K20 microprocessor UART register definitions */
/*
* Copyright (c) 2013-2014 Wind River Systems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @brief Contains the UART Registers for the K20 Family of microprocessors.
*/
#ifndef _K20UART_H_
#define _K20UART_H_
#include <stdint.h>
#include <misc/__assert.h>
#ifdef __cplusplus
extern "C" {
#endif
union BDH {
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;
}; /* 0x000 BaudRate High */
union C1 {
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;
}; /* 0x002 Control 1 */
#define RX_EN_MASK 0x04
#define TX_EN_MASK 0x08
union C2 {
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;
}; /* 0x003 Control 2 */
union C3 {
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;
}; /* 0x006 Control 3 */
union C4 {
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;
}; /* 0x00A Control 4 */
#define TX_DATA_EMPTY_MASK 0x80
#define RX_DATA_FULL_MASK 0x20
union S1 {
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;
}; /* 0x004 Status 1 */
union S2 {
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;
}; /* 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
union PFIFO {
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;
}; /* 0x010 Fifo Parameter 1 */
#define RX_FIFO_FLUSH_MASK 0x40
#define TX_FIFO_FLUSH_MASK 0x80
union CFIFO {
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;
}; /* 0x011 Fifo Control */
struct K20_UART {
union BDH bdh; /* 0x000 Baud Rate High */
uint8_t bdl; /* 0x001 Baud Rate Low (04)*/
union C1 c1; /* 0x002 Control 1 */
union C2 c2; /* 0x003 Control 2 */
union S1 s1; /* 0x004 Status 1 (C0) RO*/
union S2 s2; /* 0x005 Status 2 */
union C3 c3; /* 0x006 Control 3 */
uint8_t d; /* 0x007 Data */
uint8_t ma1; /* 0x008 Match Address 1 */
uint8_t ma2; /* 0x009 Match Address 1 */
union C4 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 */
union PFIFO pfifo; /* 0x010 FIFO Param */
union CFIFO 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*/
/* 0x032-0xFFF Reserved */
uint8_t z_reserv_statused038_03c[0x1000 - 0x32];
}; /* K20 Microntroller UART module */
/**
* @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 N/A
*/
static ALWAYS_INLINE void _uart_k20_baud_rate_set(volatile struct K20_UART *u,
uint32_t clk_freq,
uint32_t baud_rate)
{
/* avoid divide by zero */
if ((baud_rate == 0) || (clk_freq == 0)) {
return;
}
/*
* 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 */
u->bdh.field.sbr = (uint8_t)(sbr >> 8);
u->bdl = (uint8_t)(sbr & 0xFF);
u->c4.field.brfa = brfa;
}
/**
* @brief Enable FIFO for K20 UART port
*
* @param uart_p UART data
*
* @return N/A
*/
static inline void _uart_k20_fifo_enable(volatile struct K20_UART *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;
}
#ifdef __cplusplus
}
#endif
#endif /* _K20UART_H_ */
|