Paparazzi UAS  v4.2.2_stable-4-gcc32f65
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
uart_arch.c
Go to the documentation of this file.
1 /*
2  * $Id$
3  *
4  * Copyright (C) 2008-2010 The Paparazzi Team
5  *
6  * This file is part of paparazzi.
7  *
8  * paparazzi is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2, or (at your option)
11  * any later version.
12  *
13  * paparazzi is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with paparazzi; see the file COPYING. If not, write to
20  * the Free Software Foundation, 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  *
23  */
24 
25 /*
26  * Brief LPC21 uart code
27  */
28 
29 #include "mcu_periph/uart.h"
30 #include "armVIC.h"
31 
32 static inline void uart_disable_interrupts(struct uart_periph* p) {
33  // disable interrups
34  ((uartRegs_t *)(p->reg_addr))->ier = 0x00; // disable all interrupts
35  ((uartRegs_t *)(p->reg_addr))->iir; // clear interrupt ID
36  ((uartRegs_t *)(p->reg_addr))->rbr; // clear receive register
37  ((uartRegs_t *)(p->reg_addr))->lsr; // clear line status register
38 }
39 
40 static inline void uart_enable_interrupts(struct uart_periph* p) {
41  // enable receiver interrupts
42  ((uartRegs_t *)(p->reg_addr))->ier = UIER_ERBFI;
43 }
44 
45 static inline void uart_set_baudrate(struct uart_periph* p, uint32_t baud) {
46  // set the baudrate
47  ((uartRegs_t *)(p->reg_addr))->lcr = ULCR_DLAB_ENABLE; // select divisor latches
48  ((uartRegs_t *)(p->reg_addr))->dll = (uint8_t)baud; // set for baud low byte
49  ((uartRegs_t *)(p->reg_addr))->dlm = (uint8_t)(baud >> 8); // set for baud high byte
50 
51  // set the number of characters and other
52  // user specified operating parameters
53  // For now: hard wired configuration 8 bits 1 stop no parity
54  // fifo triger -> 8 bytes
55  ((uartRegs_t *)(p->reg_addr))->lcr = (UART_8N1 & ~ULCR_DLAB_ENABLE);
56  ((uartRegs_t *)(p->reg_addr))->fcr = UART_FIFO_8;
57 }
58 
59 void uart_periph_set_baudrate(struct uart_periph* p, uint32_t baud, bool_t hw_flow_control __attribute__ ((unused))) {
61  uart_set_baudrate(p, baud);
63 }
64 
65 void uart_transmit(struct uart_periph* p, uint8_t data ) {
66  uint16_t temp;
67  unsigned cpsr;
68 
69  temp = (p->tx_insert_idx + 1) % UART_TX_BUFFER_SIZE;
70 
71  if (temp == p->tx_extract_idx)
72  return; // no room
73 
74  cpsr = disableIRQ(); // disable global interrupts
75  ((uartRegs_t *)(p->reg_addr))->ier &= ~UIER_ETBEI; // disable TX interrupts
76  restoreIRQ(cpsr); // restore global interrupts
77 
78  // check if in process of sending data
79  if (p->tx_running) {
80  // add to queue
81  p->tx_buf[p->tx_insert_idx] = data;
82  p->tx_insert_idx = temp;
83  } else {
84  // set running flag and write to output register
85  p->tx_running = 1;
86  ((uartRegs_t *)(p->reg_addr))->thr = data;
87  }
88 
89  cpsr = disableIRQ(); // disable global interrupts
90  ((uartRegs_t *)(p->reg_addr))->ier |= UIER_ETBEI; // enable TX interrupts
91  restoreIRQ(cpsr); // restore global interrupts
92 }
93 
94 static inline void uart_ISR(struct uart_periph* p)
95 {
96  uint8_t iid;
97 
98  // loop until not more interrupt sources
99  while (((iid = ((uartRegs_t *)(p->reg_addr))->iir) & UIIR_NO_INT) == 0)
100  {
101  // identify & process the highest priority interrupt
102  switch (iid & UIIR_ID_MASK)
103  {
104  case UIIR_RLS_INT: // Receive Line Status
105  ((uartRegs_t *)(p->reg_addr))->lsr; // read LSR to clear
106  break;
107 
108  case UIIR_CTI_INT: // Character Timeout Indicator
109  case UIIR_RDA_INT: // Receive Data Available
110  do
111  {
112  uint16_t temp;
113 
114  // calc next insert index & store character
115  temp = (p->rx_insert_idx + 1) % UART_RX_BUFFER_SIZE;
116  p->rx_buf[p->rx_insert_idx] = ((uartRegs_t *)(p->reg_addr))->rbr;
117 
118  // check for more room in queue
119  if (temp != p->rx_extract_idx)
120  p->rx_insert_idx = temp; // update insert index
121  }
122  while (((uartRegs_t *)(p->reg_addr))->lsr & ULSR_RDR);
123 
124  break;
125 
126  case UIIR_THRE_INT: // Transmit Holding Register Empty
127  while (((uartRegs_t *)(p->reg_addr))->lsr & ULSR_THRE)
128  {
129  // check if more data to send
130  if (p->tx_insert_idx != p->tx_extract_idx)
131  {
132  ((uartRegs_t *)(p->reg_addr))->thr = p->tx_buf[p->tx_extract_idx];
133  p->tx_extract_idx++;
135  }
136  else
137  {
138  // no
139  p->tx_running = 0; // clear running flag
140  break;
141  }
142  }
143 
144  break;
145 
146  default: // Unknown
147  ((uartRegs_t *)(p->reg_addr))->lsr;
148  ((uartRegs_t *)(p->reg_addr))->rbr;
149  break;
150  }
151  }
152 }
153 
154 #ifdef USE_UART0
155 
156 #ifndef UART0_VIC_SLOT
157 #define UART0_VIC_SLOT 5
158 #endif
159 
160 void uart0_ISR(void) __attribute__((naked));
161 
162 void uart0_ISR(void) {
163  // perform proper ISR entry so thumb-interwork works properly
164  ISR_ENTRY();
165 
166  uart_ISR(&uart0);
167 
168  VICVectAddr = 0x00000000; // clear this interrupt from the VIC
169  ISR_EXIT(); // recover registers and return
170 }
171 
172 void uart0_init( void ) {
173 
174  uart_periph_init(&uart0);
175  uart0.reg_addr = UART0_BASE;
176 
177 #ifdef USE_UART0_RX_ONLY
178  // only use the RX0 P0.1 pin, no TX
180 #else
181  // set port pins for UART0
183 #endif
184 
185  // initialize uart parameters
186  uart_disable_interrupts(&uart0);
187  uart_set_baudrate(&uart0, UART0_BAUD);
188 
189  // initialize the interrupt vector
190  VICIntSelect &= ~VIC_BIT(VIC_UART0); // UART0 selected as IRQ
191  VICIntEnable = VIC_BIT(VIC_UART0); // UART0 interrupt enabled
192  _VIC_CNTL(UART0_VIC_SLOT) = VIC_ENABLE | VIC_UART0;
193  _VIC_ADDR(UART0_VIC_SLOT) = (uint32_t)uart0_ISR; // address of the ISR
194 
195  uart_enable_interrupts(&uart0);
196 }
197 
198 #endif /* USE_UART0 */
199 
200 #ifdef USE_UART1
201 
202 #ifndef UART1_VIC_SLOT
203 #define UART1_VIC_SLOT 6
204 #endif
205 
206 void uart1_ISR(void) __attribute__((naked));
207 
208 void uart1_ISR(void) {
209  // perform proper ISR entry so thumb-interwork works properly
210  ISR_ENTRY();
211 
212  uart_ISR(&uart1);
213 
214  VICVectAddr = 0x00000000; // clear this interrupt from the VIC
215  ISR_EXIT(); // recover registers and return
216 }
217 
218 void uart1_init( void ) {
219 
220  uart_periph_init(&uart1);
221  uart1.reg_addr = UART1_BASE;
222 
223 #ifdef USE_UART1_RX_ONLY
224  // only use the RX1 P0.9 pin, no TX
226 #else
227  // set port pins for UART1
229 #endif
230 
231  uart_disable_interrupts(&uart1);
232  uart_set_baudrate(&uart1, UART1_BAUD);
233 
234  // initialize the interrupt vector
235  VICIntSelect &= ~VIC_BIT(VIC_UART1); // UART1 selected as IRQ
236  VICIntEnable = VIC_BIT(VIC_UART1); // UART1 interrupt enabled
237  _VIC_CNTL(UART1_VIC_SLOT) = VIC_ENABLE | VIC_UART1;
238  _VIC_ADDR(UART1_VIC_SLOT) = (uint32_t)uart1_ISR; // address of the ISR
239 
240  // enable receiver interrupts
241  uart_enable_interrupts(&uart1);
242 }
243 
244 #endif
245 
#define VICIntSelect
Definition: LPC21xx.h:398
unsigned short uint16_t
Definition: types.h:16
#define VIC_UART0
Definition: lpcVIC.h:74
arch independent UART (Universal Asynchronous Receiver/Transmitter) API
#define U1_PINMASK_RX
Definition: LPC21xx.h:136
#define U0_PINSEL
Definition: LPC21xx.h:113
#define U1_PINSEL
Definition: LPC21xx.h:133
#define U1_PINMASK
Definition: LPC21xx.h:134
uint8_t tx_running
Definition: uart.h:52
#define _VIC_CNTL(idx)
Definition: armVIC.h:19
#define U0_PINSEL_RX
Definition: LPC21xx.h:115
#define UIER_ETBEI
Definition: lpcUART.h:59
#define UART_8N1
Definition: uart_arch.h:44
#define UIER_ERBFI
Definition: lpcUART.h:58
void * reg_addr
Definition: uart.h:54
#define U1_PINSEL_RX
Definition: LPC21xx.h:135
#define VIC_UART1
Definition: lpcVIC.h:75
uint16_t tx_extract_idx
Definition: uart.h:51
static void uart_ISR(struct uart_periph *p)
Definition: uart_arch.c:94
void uart_transmit(struct uart_periph *p, uint8_t data)
Definition: uart_arch.c:65
#define _VIC_ADDR(idx)
Definition: armVIC.h:20
void uart_periph_set_baudrate(struct uart_periph *p, uint32_t baud, bool_t hw_flow_control __attribute__((unused)))
Definition: uart_arch.c:59
#define UIIR_NO_INT
Definition: lpcUART.h:64
UART peripheral.
Definition: uart.h:43
static void uart_enable_interrupts(struct uart_periph *p)
Definition: uart_arch.c:40
#define UIIR_ID_MASK
Definition: lpcUART.h:70
#define UART_TX_BUFFER_SIZE
Definition: uart.h:37
#define UIIR_CTI_INT
Definition: lpcUART.h:69
#define U0_PINMASK_RX
Definition: LPC21xx.h:116
static void uart_set_baudrate(struct uart_periph *p, uint32_t baud)
Definition: uart_arch.c:45
#define VICVectAddr
Definition: LPC21xx.h:404
void uart_periph_init(struct uart_periph *p)
Definition: uart.c:47
unsigned long uint32_t
Definition: types.h:18
#define ULSR_RDR
Definition: lpcUART.h:102
#define UIIR_RDA_INT
Definition: lpcUART.h:67
#define UART1_BASE
Definition: LPC21xx.h:132
unsigned restoreIRQ(unsigned oldCPSR)
Definition: armVIC.c:42
uint16_t rx_insert_idx
Definition: uart.h:46
#define UART0_BASE
Definition: LPC21xx.h:112
#define VIC_BIT(chan)
Definition: lpcVIC.h:105
#define UIIR_RLS_INT
Definition: lpcUART.h:68
uint8_t tx_buf[UART_TX_BUFFER_SIZE]
Definition: uart.h:49
#define PINSEL0
Definition: LPC21xx.h:315
#define U0_PINMASK
Definition: LPC21xx.h:114
unsigned char uint8_t
Definition: types.h:14
#define UART_FIFO_8
Definition: uart_arch.h:60
unsigned disableIRQ(void)
Definition: armVIC.c:33
#define ISR_EXIT()
Definition: armVIC.h:61
#define ULSR_THRE
Definition: lpcUART.h:107
uint16_t tx_insert_idx
Definition: uart.h:50
#define VICIntEnable
Definition: LPC21xx.h:399
uint8_t rx_buf[UART_RX_BUFFER_SIZE]
Definition: uart.h:45
static void uart_disable_interrupts(struct uart_periph *p)
Definition: uart_arch.c:32
uint16_t rx_extract_idx
Definition: uart.h:47
#define UIIR_THRE_INT
Definition: lpcUART.h:66
#define UART_RX_BUFFER_SIZE
Definition: uart.h:36
__attribute__((always_inline))
Definition: i2c_arch.c:35
#define ISR_ENTRY()
Definition: armVIC.h:40
#define VIC_ENABLE
Definition: lpcVIC.h:102
#define ULCR_DLAB_ENABLE
Definition: lpcUART.h:94