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
uart.h@2:148b9af2b336, 2012-01-04 (annotated)
- 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?
User | Revision | Line number | New 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 |