Library to access LPC17xx peripherals. It uses static inline functions, constant propagation and dead code elimination to be as fast as possible.

Dependents:   Chua-VGA Wolfram-1D-VGA WolframRnd-1D-VGA Basin-VGA ... more

Committer:
Ivop
Date:
Wed Jan 04 01:42:56 2012 +0000
Revision:
2:148b9af2b336
Parent:
0:7a91348b4a02
fixed bug in fl_uart_send_byte. thanks to smayr for finding it

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Ivop 2:148b9af2b336 1 /* Copyright (C) 2010, 2011, 2012 by Ivo van Poorten <ivop@euronet.nl>
Ivop 0:7a91348b4a02 2 * This file is licensed under the terms of the GNU Lesser
Ivop 0:7a91348b4a02 3 * General Public License, version 3.
Ivop 0:7a91348b4a02 4 */
Ivop 0:7a91348b4a02 5
Ivop 0:7a91348b4a02 6 #ifndef FASTLIB_UART_H
Ivop 0:7a91348b4a02 7 #define FASTLIB_UART_H
Ivop 0:7a91348b4a02 8
Ivop 0:7a91348b4a02 9 #include "fastlib/common.h"
Ivop 0:7a91348b4a02 10
Ivop 0:7a91348b4a02 11 #define FL_UART_RBR 0x00
Ivop 0:7a91348b4a02 12 #define FL_UART_THR 0x00
Ivop 0:7a91348b4a02 13 #define FL_UART_DLL 0x00
Ivop 0:7a91348b4a02 14
Ivop 0:7a91348b4a02 15 #define FL_UART_DLM 0x04
Ivop 0:7a91348b4a02 16 #define FL_UART_IER 0x04
Ivop 0:7a91348b4a02 17
Ivop 0:7a91348b4a02 18 #define FL_UART_IIR 0x08
Ivop 0:7a91348b4a02 19 #define FL_UART_FCR 0x08
Ivop 0:7a91348b4a02 20
Ivop 0:7a91348b4a02 21 #define FL_UART_LCR 0x0C
Ivop 0:7a91348b4a02 22 #define FL_UART_MCR 0x10 /* UART1 only */
Ivop 0:7a91348b4a02 23 #define FL_UART_LSR 0x14
Ivop 0:7a91348b4a02 24 #define FL_UART_MSR 0x18 /* UART1 only */
Ivop 0:7a91348b4a02 25 #define FL_UART_SCR 0x1C
Ivop 0:7a91348b4a02 26 #define FL_UART_ACR 0x20
Ivop 0:7a91348b4a02 27 #define FL_UART_ICR 0x24 /* UART023 only */
Ivop 0:7a91348b4a02 28 #define FL_UART_FDR 0x28
Ivop 0:7a91348b4a02 29 #define FL_UART_TER 0x30
Ivop 0:7a91348b4a02 30
Ivop 0:7a91348b4a02 31 #define FL_UART_RS485CTRL 0x4C /* UART1 only */
Ivop 0:7a91348b4a02 32 #define FL_UART_RS485ADRMATCH 0x50 /* UART1 only */
Ivop 0:7a91348b4a02 33 #define FL_UART_RS485DLY 0x54 /* UART1 only */
Ivop 0:7a91348b4a02 34
Ivop 0:7a91348b4a02 35 #define FL_UART0_BASE 0x4000C000
Ivop 0:7a91348b4a02 36 #define FL_UART1_BASE 0x40010000
Ivop 0:7a91348b4a02 37 #define FL_UART2_BASE 0x40098000
Ivop 0:7a91348b4a02 38 #define FL_UART3_BASE 0x4009C000
Ivop 0:7a91348b4a02 39
Ivop 0:7a91348b4a02 40 #define FL_UART(num, field) \
Ivop 0:7a91348b4a02 41 ((volatile uint32_t *)(fl_uart_num_to_base(num) + FL_UART_##field))
Ivop 0:7a91348b4a02 42
Ivop 0:7a91348b4a02 43 static inline unsigned fl_uart_num_to_base(const unsigned num) {
Ivop 0:7a91348b4a02 44 switch(num) {
Ivop 0:7a91348b4a02 45 case 0: return FL_UART0_BASE;
Ivop 0:7a91348b4a02 46 case 1: return FL_UART1_BASE;
Ivop 0:7a91348b4a02 47 case 2: return FL_UART2_BASE;
Ivop 0:7a91348b4a02 48 default: return FL_UART3_BASE;
Ivop 0:7a91348b4a02 49 }
Ivop 0:7a91348b4a02 50 }
Ivop 0:7a91348b4a02 51
Ivop 0:7a91348b4a02 52 static inline unsigned fl_uart_receive_byte(const unsigned uart) {
Ivop 0:7a91348b4a02 53 return *FL_UART(uart, RBR);
Ivop 0:7a91348b4a02 54 }
Ivop 0:7a91348b4a02 55
Ivop 0:7a91348b4a02 56 static inline void fl_uart_send_byte(const unsigned uart, const unsigned byte) {
Ivop 2:148b9af2b336 57 *FL_UART(uart, THR) = byte;
Ivop 0:7a91348b4a02 58 }
Ivop 0:7a91348b4a02 59
Ivop 0:7a91348b4a02 60 static inline unsigned fl_uart_get_divisor_latch(const unsigned uart) {
Ivop 0:7a91348b4a02 61 unsigned divisor;
Ivop 0:7a91348b4a02 62 *FL_UART(uart, LCR) |= 1U<<7; // enable access to latch
Ivop 0:7a91348b4a02 63
Ivop 0:7a91348b4a02 64 divisor = *FL_UART(uart, DLL) | (*FL_UART(uart, DLM) << 8);
Ivop 0:7a91348b4a02 65
Ivop 0:7a91348b4a02 66 *FL_UART(uart, LCR) &= ~(1U<<7); // disable access to latch
Ivop 0:7a91348b4a02 67 return divisor;
Ivop 0:7a91348b4a02 68 }
Ivop 0:7a91348b4a02 69
Ivop 0:7a91348b4a02 70 /* divisor: 16-bit value */
Ivop 0:7a91348b4a02 71 static inline void fl_uart_set_divisor_latch(const unsigned uart, const unsigned divisor) {
Ivop 0:7a91348b4a02 72 *FL_UART(uart, LCR) |= 1U<<7; // enable access to latch
Ivop 0:7a91348b4a02 73
Ivop 0:7a91348b4a02 74 *FL_UART(uart, DLL) = divisor & 0xff;
Ivop 0:7a91348b4a02 75 *FL_UART(uart, DLM) = (divisor >> 8) & 0xff;
Ivop 0:7a91348b4a02 76
Ivop 0:7a91348b4a02 77 *FL_UART(uart, LCR) &= ~(1U<<7); // disable access to latch
Ivop 0:7a91348b4a02 78 }
Ivop 0:7a91348b4a02 79
Ivop 0:7a91348b4a02 80 static inline void fl_uart_rx_data_available_interrupt_enable(const unsigned uart, const unsigned state) {
Ivop 0:7a91348b4a02 81 if (state) *FL_UART(uart, IER) |= (1U<<0);
Ivop 0:7a91348b4a02 82 else *FL_UART(uart, IER) &= ~(1U<<0);
Ivop 0:7a91348b4a02 83 }
Ivop 0:7a91348b4a02 84
Ivop 0:7a91348b4a02 85 static inline void fl_uart_tx_fifo_empty_interrupt_enable(const unsigned uart, const unsigned state) {
Ivop 0:7a91348b4a02 86 if (state) *FL_UART(uart, IER) |= (1U<<1);
Ivop 0:7a91348b4a02 87 else *FL_UART(uart, IER) &= ~(1U<<1);
Ivop 0:7a91348b4a02 88 }
Ivop 0:7a91348b4a02 89
Ivop 0:7a91348b4a02 90 static inline void fl_uart_rx_line_status_interrupt_enable(const unsigned uart, const unsigned state) {
Ivop 0:7a91348b4a02 91 if (state) *FL_UART(uart, IER) |= (1U<<2);
Ivop 0:7a91348b4a02 92 else *FL_UART(uart, IER) &= ~(1U<<2);
Ivop 0:7a91348b4a02 93 }
Ivop 0:7a91348b4a02 94
Ivop 0:7a91348b4a02 95 static inline void fl_uart_end_of_autobaud_interrupt_enable(const unsigned uart, const unsigned state) {
Ivop 0:7a91348b4a02 96 if (state) *FL_UART(uart, IER) |= (1U<<8);
Ivop 0:7a91348b4a02 97 else *FL_UART(uart, IER) &= ~(1U<<8);
Ivop 0:7a91348b4a02 98 }
Ivop 0:7a91348b4a02 99
Ivop 0:7a91348b4a02 100 static inline void fl_uart_timeout_autobaud_interrupt_enable(const unsigned uart, const unsigned state) {
Ivop 0:7a91348b4a02 101 if (state) *FL_UART(uart, IER) |= (1U<<9);
Ivop 0:7a91348b4a02 102 else *FL_UART(uart, IER) &= ~(1U<<9);
Ivop 0:7a91348b4a02 103 }
Ivop 0:7a91348b4a02 104
Ivop 0:7a91348b4a02 105 static inline unsigned fl_uart_interrupt_status(const unsigned uart) {
Ivop 0:7a91348b4a02 106 return !(*FL_UART(uart, IIR) & 1); // negate, because status is active low
Ivop 0:7a91348b4a02 107 }
Ivop 0:7a91348b4a02 108
Ivop 0:7a91348b4a02 109 #define FL_UART_INTERRUPT_RLS 3 /* rx line status */
Ivop 0:7a91348b4a02 110 #define FL_UART_INTERRUPT_RDA 2 /* rx data available */
Ivop 0:7a91348b4a02 111 #define FL_UART_INTERRUPT_CTI 6 /* character time-out */
Ivop 0:7a91348b4a02 112 #define FL_UART_INTERRUPT_THRE 1 /* tx fifo empty */
Ivop 0:7a91348b4a02 113 #define FL_UART_INTERRUPT_MODEM 0 /* modem interrupt, uart1 only */
Ivop 0:7a91348b4a02 114
Ivop 0:7a91348b4a02 115 static inline unsigned fl_uart_get_interrupt_identification(const unsigned uart) {
Ivop 0:7a91348b4a02 116 return (*FL_UART(uart, IIR) >> 1) & 7;
Ivop 0:7a91348b4a02 117 }
Ivop 0:7a91348b4a02 118
Ivop 0:7a91348b4a02 119 /* returns 0 or !0 */
Ivop 0:7a91348b4a02 120 static inline unsigned fl_uart_end_of_autobaud_interrupt(const unsigned uart) {
Ivop 0:7a91348b4a02 121 return *FL_UART(uart, IIR) & (1U<<8);
Ivop 0:7a91348b4a02 122 }
Ivop 0:7a91348b4a02 123 static inline unsigned fl_uart_timeout_autobaud_interrupt(const unsigned uart) {
Ivop 0:7a91348b4a02 124 return *FL_UART(uart, IIR) & (1U<<9);
Ivop 0:7a91348b4a02 125 }
Ivop 0:7a91348b4a02 126
Ivop 0:7a91348b4a02 127 /* call is more or less mandatory for application (page 305) */
Ivop 0:7a91348b4a02 128 static inline void fl_uart_enable_fifos(const unsigned uart) {
Ivop 0:7a91348b4a02 129 *FL_UART(uart, FCR) |= 1U<<0;
Ivop 0:7a91348b4a02 130 }
Ivop 0:7a91348b4a02 131 /* disable/enable cycle clears fifo */
Ivop 0:7a91348b4a02 132 static inline void fl_uart_disable_fifos(const unsigned uart) {
Ivop 0:7a91348b4a02 133 *FL_UART(uart, FCR) &= ~(1U<<0);
Ivop 0:7a91348b4a02 134 }
Ivop 0:7a91348b4a02 135
Ivop 0:7a91348b4a02 136 static inline void fl_uart_reset_rx_fifo(const unsigned uart) {
Ivop 0:7a91348b4a02 137 *FL_UART(uart, FCR) |= 1U<<1; // bit is self-clearing
Ivop 0:7a91348b4a02 138 }
Ivop 0:7a91348b4a02 139
Ivop 0:7a91348b4a02 140 static inline void fl_uart_reset_tx_fifo(const unsigned uart) {
Ivop 0:7a91348b4a02 141 *FL_UART(uart, FCR) |= 1U<<2; // bit is self-clearing
Ivop 0:7a91348b4a02 142 }
Ivop 0:7a91348b4a02 143
Ivop 0:7a91348b4a02 144 static inline void fl_uart_enable_dma_mode(const unsigned uart, const unsigned state) {
Ivop 0:7a91348b4a02 145 if (state) *FL_UART(uart, FCR) |= 1U<<3 ;
Ivop 0:7a91348b4a02 146 else *FL_UART(uart, FCR) &= ~(1U<<3);
Ivop 0:7a91348b4a02 147 }
Ivop 0:7a91348b4a02 148
Ivop 0:7a91348b4a02 149 static inline void fl_uart_set_rx_trigger_level(const unsigned uart, const unsigned level) {
Ivop 0:7a91348b4a02 150 if (level != 14) *FL_UART(uart, FCR) &= ~(3U<<6);
Ivop 0:7a91348b4a02 151 switch(level) {
Ivop 0:7a91348b4a02 152 default: return;
Ivop 0:7a91348b4a02 153 case 4: *FL_UART(uart, FCR) |= 1U<<6; return;
Ivop 0:7a91348b4a02 154 case 8: *FL_UART(uart, FCR) |= 2U<<6; return;
Ivop 0:7a91348b4a02 155 case 14: *FL_UART(uart, FCR) |= 3U<<6; return;
Ivop 0:7a91348b4a02 156 }
Ivop 0:7a91348b4a02 157 }
Ivop 0:7a91348b4a02 158
Ivop 0:7a91348b4a02 159 #define FL_UART_5BIT 0
Ivop 0:7a91348b4a02 160 #define FL_UART_6BIT 1
Ivop 0:7a91348b4a02 161 #define FL_UART_7BIT 2
Ivop 0:7a91348b4a02 162 #define FL_UART_8BIT 3
Ivop 0:7a91348b4a02 163
Ivop 0:7a91348b4a02 164 #define FL_UART_1STOPBIT 0
Ivop 0:7a91348b4a02 165 #define FL_UART_2STOPBITS 1
Ivop 0:7a91348b4a02 166
Ivop 0:7a91348b4a02 167 #define FL_UART_NO_PARITY 0
Ivop 0:7a91348b4a02 168 #define FL_UART_PARITY 1
Ivop 0:7a91348b4a02 169
Ivop 0:7a91348b4a02 170 #define FL_UART_ODD 0
Ivop 0:7a91348b4a02 171 #define FL_UART_EVEN 1
Ivop 0:7a91348b4a02 172 #define FL_UART_FORCE1 2
Ivop 0:7a91348b4a02 173 #define FL_UART_FORCE0 3
Ivop 0:7a91348b4a02 174
Ivop 0:7a91348b4a02 175 static inline void fl_uart_line_config(const unsigned uart, const unsigned wordlength, const unsigned stopbit, \
Ivop 0:7a91348b4a02 176 const unsigned parity_enable, const unsigned parity_type) {
Ivop 0:7a91348b4a02 177 const unsigned combined = wordlength | (stopbit << 2) | (parity_enable << 3) | (parity_type << 4);
Ivop 0:7a91348b4a02 178 *FL_UART(uart, LCR) &= ~(0x3fU);
Ivop 0:7a91348b4a02 179 *FL_UART(uart, LCR) |= combined;
Ivop 0:7a91348b4a02 180 }
Ivop 0:7a91348b4a02 181
Ivop 0:7a91348b4a02 182 static inline void fl_uart_break_transmission(const unsigned uart, const unsigned state) {
Ivop 0:7a91348b4a02 183 if (state) *FL_UART(uart, LCR) |= 1U<<6 ;
Ivop 0:7a91348b4a02 184 else *FL_UART(uart, LCR) &= ~(1U<<6);
Ivop 0:7a91348b4a02 185 }
Ivop 0:7a91348b4a02 186
Ivop 0:7a91348b4a02 187 static inline unsigned fl_uart_get_line_status(const unsigned uart) {
Ivop 0:7a91348b4a02 188 return *FL_UART(uart, LSR);
Ivop 0:7a91348b4a02 189 }
Ivop 0:7a91348b4a02 190
Ivop 0:7a91348b4a02 191 /* read status first and use functions below to test what is happening */
Ivop 0:7a91348b4a02 192 /* the reason for this is that a status read clears several bits */
Ivop 0:7a91348b4a02 193
Ivop 0:7a91348b4a02 194 #define FL_LSR_TEST(what, where) \
Ivop 0:7a91348b4a02 195 static inline unsigned fl_uart_##what(const unsigned status) { \
Ivop 0:7a91348b4a02 196 return status & (where); \
Ivop 0:7a91348b4a02 197 }
Ivop 0:7a91348b4a02 198
Ivop 0:7a91348b4a02 199 FL_LSR_TEST(rx_fifo_not_empty, 1U<<0);
Ivop 0:7a91348b4a02 200 FL_LSR_TEST(rx_fifo_overun_error, 1U<<1);
Ivop 0:7a91348b4a02 201 FL_LSR_TEST(rx_parity_error, 1U<<2);
Ivop 0:7a91348b4a02 202 FL_LSR_TEST(rx_framing_error, 1U<<3);
Ivop 0:7a91348b4a02 203 FL_LSR_TEST(rx_break_interrupt, 1U<<4); /* associated with top of fifo */
Ivop 0:7a91348b4a02 204 FL_LSR_TEST(tx_send_register_empty, 1U<<5);
Ivop 0:7a91348b4a02 205 FL_LSR_TEST(tx_empty, 1U<<6); /* both send and status register */
Ivop 0:7a91348b4a02 206 FL_LSR_TEST(rx_error_entered_fifo, 1U<<7);
Ivop 0:7a91348b4a02 207
Ivop 0:7a91348b4a02 208 static inline void fl_uart_write_scratch_pad(const unsigned uart, const unsigned byte) {
Ivop 0:7a91348b4a02 209 *FL_UART(uart, SCR) = byte & 0xff;
Ivop 0:7a91348b4a02 210 }
Ivop 0:7a91348b4a02 211
Ivop 0:7a91348b4a02 212 static inline unsigned fl_uart_read_scratch_pad(const unsigned uart) {
Ivop 0:7a91348b4a02 213 return *FL_UART(uart, SCR);
Ivop 0:7a91348b4a02 214 }
Ivop 0:7a91348b4a02 215
Ivop 0:7a91348b4a02 216 static inline void fl_uart_autobaud_config(const unsigned uart, const unsigned mode, const unsigned autorestart) {
Ivop 0:7a91348b4a02 217 *FL_UART(uart, ACR) = (mode << 1) | (autorestart << 2); // writing zeroes to other bits has no impact (p.308/309)
Ivop 0:7a91348b4a02 218 }
Ivop 0:7a91348b4a02 219
Ivop 0:7a91348b4a02 220 static inline void fl_uart_start_autobaud(const unsigned uart) {
Ivop 0:7a91348b4a02 221 *FL_UART(uart, ACR) |= 1; // bit is auto-clearing
Ivop 0:7a91348b4a02 222 }
Ivop 0:7a91348b4a02 223
Ivop 0:7a91348b4a02 224 static inline void fl_uart_clear_end_of_autobaud_interrupt(const unsigned uart) {
Ivop 0:7a91348b4a02 225 *FL_UART(uart, ACR) |= 1U<<8;
Ivop 0:7a91348b4a02 226 }
Ivop 0:7a91348b4a02 227
Ivop 0:7a91348b4a02 228 static inline void fl_uart_clear_autobaud_timeout_interrupt(const unsigned uart) {
Ivop 0:7a91348b4a02 229 *FL_UART(uart, ACR) |= 1U<<9;
Ivop 0:7a91348b4a02 230 }
Ivop 0:7a91348b4a02 231
Ivop 0:7a91348b4a02 232 static inline void fl_uart_set_fractional_divider(const unsigned uart, const unsigned divaddval, const unsigned mulval) {
Ivop 0:7a91348b4a02 233 *FL_UART(uart, FDR) &= ~(0xff);
Ivop 0:7a91348b4a02 234 *FL_UART(uart, FDR) |= divaddval | (mulval<<4);
Ivop 0:7a91348b4a02 235 }
Ivop 0:7a91348b4a02 236
Ivop 0:7a91348b4a02 237 static inline unsigned fl_uart_get_fractional_divider(const unsigned uart) {
Ivop 0:7a91348b4a02 238 return *FL_UART(uart, FDR);
Ivop 0:7a91348b4a02 239 }
Ivop 0:7a91348b4a02 240
Ivop 0:7a91348b4a02 241 static inline void fl_uart_transmitter_enable(const unsigned uart, const unsigned state) {
Ivop 0:7a91348b4a02 242 if (state) *FL_UART(uart, TER) |= 1U<<7 ;
Ivop 0:7a91348b4a02 243 else *FL_UART(uart, TER) &= ~(1U<<7);
Ivop 0:7a91348b4a02 244 }
Ivop 0:7a91348b4a02 245
Ivop 0:7a91348b4a02 246 // infrared mode only works on uart0, 2 and 3
Ivop 0:7a91348b4a02 247
Ivop 0:7a91348b4a02 248 static inline void fl_uart_infrared_mode(const unsigned uart, const unsigned state) {
Ivop 0:7a91348b4a02 249 if (state) *FL_UART(uart, ICR) |= 1U<<0;
Ivop 0:7a91348b4a02 250 else *FL_UART(uart, ICR) &= ~(1U<<0);
Ivop 0:7a91348b4a02 251 }
Ivop 0:7a91348b4a02 252 static inline void fl_uart_infrared_input_inverted(const unsigned uart, const unsigned state) {
Ivop 0:7a91348b4a02 253 if (state) *FL_UART(uart, ICR) |= 1U<<1;
Ivop 0:7a91348b4a02 254 else *FL_UART(uart, ICR) &= ~(1U<<1);
Ivop 0:7a91348b4a02 255 }
Ivop 0:7a91348b4a02 256 static inline void fl_uart_infrared_fixed_pulsewidth(const unsigned uart, const unsigned state) {
Ivop 0:7a91348b4a02 257 if (state) *FL_UART(uart, ICR) |= 1U<<2;
Ivop 0:7a91348b4a02 258 else *FL_UART(uart, ICR) &= ~(1U<<2);
Ivop 0:7a91348b4a02 259 }
Ivop 0:7a91348b4a02 260 // see UM10360 page 312 for pulsediv values (0-7)
Ivop 0:7a91348b4a02 261 static inline void fl_uart_infrared_config_pulse(const unsigned uart, const unsigned pulsediv) {
Ivop 0:7a91348b4a02 262 *FL_UART(uart, ICR) &= ~(7U<<3);
Ivop 0:7a91348b4a02 263 *FL_UART(uart, ICR) |= pulsediv << 3;
Ivop 0:7a91348b4a02 264 }
Ivop 0:7a91348b4a02 265
Ivop 0:7a91348b4a02 266
Ivop 0:7a91348b4a02 267 // functions below only work for uart1 (full modem interface)
Ivop 0:7a91348b4a02 268
Ivop 0:7a91348b4a02 269 static inline void fl_modem_status_interrupt_enable(const unsigned state) {
Ivop 0:7a91348b4a02 270 if (state) *FL_UART(1, IER) |= (1U<<3);
Ivop 0:7a91348b4a02 271 else *FL_UART(1, IER) &= ~(1U<<3);
Ivop 0:7a91348b4a02 272 }
Ivop 0:7a91348b4a02 273
Ivop 0:7a91348b4a02 274 static inline void fl_modem_cts_interrupt_enable(const unsigned state) {
Ivop 0:7a91348b4a02 275 if (state) *FL_UART(1, IER) |= (1U<<7);
Ivop 0:7a91348b4a02 276 else *FL_UART(1, IER) &= ~(1U<<7);
Ivop 0:7a91348b4a02 277 }
Ivop 0:7a91348b4a02 278
Ivop 0:7a91348b4a02 279 static inline void fl_modem_control(const unsigned dtr_control, const unsigned rts_control, const unsigned loopback,
Ivop 0:7a91348b4a02 280 const unsigned rts, const unsigned cts) {
Ivop 0:7a91348b4a02 281 *FL_UART(1, MCR) = dtr_control | (rts_control << 1) | (loopback << 4) | (rts << 6) | (cts << 7);
Ivop 0:7a91348b4a02 282 }
Ivop 0:7a91348b4a02 283
Ivop 0:7a91348b4a02 284 static inline unsigned fl_modem_get_status(void) {
Ivop 0:7a91348b4a02 285 return *FL_UART(1, MSR);
Ivop 0:7a91348b4a02 286 }
Ivop 0:7a91348b4a02 287
Ivop 0:7a91348b4a02 288 /* read status first and use functions below to test what is happening */
Ivop 0:7a91348b4a02 289 /* the reason for this is that a status read clears several bits */
Ivop 0:7a91348b4a02 290
Ivop 0:7a91348b4a02 291 #define FL_MSR_TEST(what, where) \
Ivop 0:7a91348b4a02 292 static inline unsigned fl_modem_##what(const unsigned status) { \
Ivop 0:7a91348b4a02 293 return status & (where); \
Ivop 0:7a91348b4a02 294 }
Ivop 0:7a91348b4a02 295
Ivop 0:7a91348b4a02 296 FL_MSR_TEST(cts_state_changed, 1U<<0);
Ivop 0:7a91348b4a02 297 FL_MSR_TEST(dsr_state_changed, 1U<<1);
Ivop 0:7a91348b4a02 298 FL_MSR_TEST(low_to_high_ri, 1U<<2);
Ivop 0:7a91348b4a02 299 FL_MSR_TEST(dcd_state_changed, 1U<<3);
Ivop 0:7a91348b4a02 300 FL_MSR_TEST(cts_state, 1U<<4); /* clear to send */
Ivop 0:7a91348b4a02 301 FL_MSR_TEST(dsr_state, 1U<<5); /* data set ready */
Ivop 0:7a91348b4a02 302 FL_MSR_TEST(ri_state, 1U<<6); /* ring indicator */
Ivop 0:7a91348b4a02 303 FL_MSR_TEST(dcd_state, 1U<<7); /* data carrier detect */
Ivop 0:7a91348b4a02 304
Ivop 0:7a91348b4a02 305 // RS-485/EIA-485 mode functions, also uart1 only
Ivop 0:7a91348b4a02 306
Ivop 0:7a91348b4a02 307 static inline void fl_rs485_normal_multidrop_mode_enable(const unsigned state) {
Ivop 0:7a91348b4a02 308 if (state) *FL_UART(1, RS485CTRL) |= 1U<<0 ;
Ivop 0:7a91348b4a02 309 else *FL_UART(1, RS485CTRL) &= ~(1U<<0);
Ivop 0:7a91348b4a02 310 }
Ivop 0:7a91348b4a02 311
Ivop 0:7a91348b4a02 312 static inline void fl_rs485_receiver_enable(const unsigned state) {
Ivop 0:7a91348b4a02 313 if (state) *FL_UART(1, RS485CTRL) |= 1U<<1 ;
Ivop 0:7a91348b4a02 314 else *FL_UART(1, RS485CTRL) &= ~(1U<<1);
Ivop 0:7a91348b4a02 315 }
Ivop 0:7a91348b4a02 316
Ivop 0:7a91348b4a02 317 static inline void fl_rs485_auto_address_detect_enable(const unsigned state) {
Ivop 0:7a91348b4a02 318 if (state) *FL_UART(1, RS485CTRL) |= 1U<<2 ;
Ivop 0:7a91348b4a02 319 else *FL_UART(1, RS485CTRL) &= ~(1U<<2);
Ivop 0:7a91348b4a02 320 }
Ivop 0:7a91348b4a02 321
Ivop 0:7a91348b4a02 322 static inline void fl_rs485_auto_direction_control_enable(const unsigned state) {
Ivop 0:7a91348b4a02 323 if (state) *FL_UART(1, RS485CTRL) |= 1U<<4 ;
Ivop 0:7a91348b4a02 324 else *FL_UART(1, RS485CTRL) &= ~(1U<<4);
Ivop 0:7a91348b4a02 325 }
Ivop 0:7a91348b4a02 326
Ivop 0:7a91348b4a02 327 static inline void fl_rs485_direction_control_on_rts_pin(void) {
Ivop 0:7a91348b4a02 328 *FL_UART(1, RS485CTRL) &= ~(1U<<3);
Ivop 0:7a91348b4a02 329 }
Ivop 0:7a91348b4a02 330
Ivop 0:7a91348b4a02 331 static inline void fl_rs485_direction_control_on_dtr_pin(void) {
Ivop 0:7a91348b4a02 332 *FL_UART(1, RS485CTRL) |= 1U<<3;
Ivop 0:7a91348b4a02 333 }
Ivop 0:7a91348b4a02 334
Ivop 0:7a91348b4a02 335 static inline void fl_rs485_direction_control_polarity(const unsigned oinv) {
Ivop 0:7a91348b4a02 336 if (oinv) *FL_UART(1, RS485CTRL) |= 1U<<5 ;
Ivop 0:7a91348b4a02 337 else *FL_UART(1, RS485CTRL) &= ~(1U<<5);
Ivop 0:7a91348b4a02 338 }
Ivop 0:7a91348b4a02 339
Ivop 0:7a91348b4a02 340 static inline void fl_rs485_set_address_match(const unsigned byte) {
Ivop 0:7a91348b4a02 341 *FL_UART(1, RS485ADRMATCH) = byte & 0xff;
Ivop 0:7a91348b4a02 342 }
Ivop 0:7a91348b4a02 343
Ivop 0:7a91348b4a02 344 static inline void fl_rs485_set_delay_time(const unsigned byte) {
Ivop 0:7a91348b4a02 345 *FL_UART(1, RS485DLY) = byte & 0xff;
Ivop 0:7a91348b4a02 346 }
Ivop 0:7a91348b4a02 347
Ivop 0:7a91348b4a02 348 #endif