RT-AICHIP-sample
uart.c
[詳解]
1 /*****************************************************************************
2  * uart.c: UART API file for NXP LPC13xx Family Microprocessors
3  *
4  * Copyright(C) 2008, NXP Semiconductor
5  * All rights reserved.
6  *
7  * History
8  * 2008.08.21 ver 1.00 Preliminary version, first Release
9  *
10 ******************************************************************************/
11 #include "LPC13xx.h"
12 #include "uart.h"
13 
14 
15 // CodeRed - change for CMSIS 1.3
16 #define SystemFrequency SystemCoreClock
17 
19 volatile uint8_t UARTTxEmpty = 1;
21 volatile uint32_t UARTCount = 0;
22 
23 /*****************************************************************************
24 ** Function name: UART_IRQHandler
25 **
26 ** Descriptions: UART interrupt handler
27 **
28 ** parameters: None
29 ** Returned value: None
30 **
31 *****************************************************************************/
32 void UART_IRQHandler(void)
33 {
34  uint8_t IIRValue, LSRValue;
35  uint8_t Dummy = Dummy;
36 
37  IIRValue = LPC_UART->IIR;
38 
39  IIRValue >>= 1; /* skip pending bit in IIR */
40  IIRValue &= 0x07; /* check bit 1~3, interrupt identification */
41  if (IIRValue == IIR_RLS) /* Receive Line Status */
42  {
43  LSRValue = LPC_UART->LSR;
44  /* Receive Line Status */
45  if (LSRValue & (LSR_OE | LSR_PE | LSR_FE | LSR_RXFE | LSR_BI))
46  {
47  /* There are errors or break interrupt */
48  /* Read LSR will clear the interrupt */
49  UARTStatus = LSRValue;
50  Dummy = LPC_UART->RBR; /* Dummy read on RX to clear
51  interrupt, then bail out */
52  return;
53  }
54  if (LSRValue & LSR_RDR) /* Receive Data Ready */
55  {
56  /* If no error on RLS, normal ready, save into the data buffer. */
57  /* Note: read RBR will clear the interrupt */
58  UARTBuffer[UARTCount++] = LPC_UART->RBR;
59  if (UARTCount == BUFSIZE)
60  {
61  UARTCount = 0; /* buffer overflow */
62  }
63  }
64  }
65  else if (IIRValue == IIR_RDA) /* Receive Data Available */
66  {
67  /* Receive Data Available */
68  UARTBuffer[UARTCount++] = LPC_UART->RBR;
69  if (UARTCount == BUFSIZE)
70  {
71  UARTCount = 0; /* buffer overflow */
72  }
73  }
74  else if (IIRValue == IIR_CTI) /* Character timeout indicator */
75  {
76  /* Character Time-out indicator */
77  UARTStatus |= 0x100; /* Bit 9 as the CTI error */
78  }
79  else if (IIRValue == IIR_THRE) /* THRE, transmit holding register empty */
80  {
81  /* THRE interrupt */
82  LSRValue = LPC_UART->LSR; /* Check status in the LSR to see if
83  valid data in U0THR or not */
84  if (LSRValue & LSR_THRE)
85  {
86  UARTTxEmpty = 1;
87  }
88  else
89  {
90  UARTTxEmpty = 0;
91  }
92  }
93  return;
94 }
95 
96 /*****************************************************************************
97 ** Function name: UARTInit
98 **
99 ** Descriptions: Initialize UART0 port, setup pin select,
100 ** clock, parity, stop bits, FIFO, etc.
101 **
102 ** parameters: UART baudrate
103 ** Returned value: None
104 **
105 *****************************************************************************/
106 void UARTInit(uint32_t baudrate)
107 {
108  uint32_t Fdiv;
109  uint32_t regVal;
110 
111  UARTTxEmpty = 1;
112  UARTCount = 0;
113 
114  NVIC_DisableIRQ(UART_IRQn);
115 
116  LPC_IOCON->PIO1_6 &= ~0x07; /* UART I/O config */
117  LPC_IOCON->PIO1_6 |= 0x01; /* UART RXD */
118  LPC_IOCON->PIO1_7 &= ~0x07;
119  LPC_IOCON->PIO1_7 |= 0x01; /* UART TXD */
120  /* Enable UART clock */
121  LPC_SYSCON->SYSAHBCLKCTRL |= (1<<12);
122  LPC_SYSCON->UARTCLKDIV = 0x1; /* divided by 1 */
123 
124  LPC_UART->LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit */
125  regVal = LPC_SYSCON->UARTCLKDIV;
126  Fdiv = (((SystemFrequency/LPC_SYSCON->SYSAHBCLKDIV)/regVal)/16)/baudrate ; /*baud rate */
127 
128  LPC_UART->DLM = Fdiv / 256;
129  LPC_UART->DLL = Fdiv % 256;
130  LPC_UART->LCR = 0x03; /* DLAB = 0 */
131  LPC_UART->FCR = 0x07; /* Enable and reset TX and RX FIFO. */
132 
133  /* Read to clear the line status. */
134  regVal = LPC_UART->LSR;
135 
136  /* Ensure a clean start, no data in either TX or RX FIFO. */
137 // CodeRed - added parentheses around comparison in operand of &
138  while (( LPC_UART->LSR & (LSR_THRE|LSR_TEMT)) != (LSR_THRE|LSR_TEMT) );
139  while ( LPC_UART->LSR & LSR_RDR )
140  {
141  regVal = LPC_UART->RBR; /* Dump data from RX FIFO */
142  }
143 
144  /* Enable the UART Interrupt */
145  NVIC_EnableIRQ(UART_IRQn);
146 
147 #if TX_INTERRUPT
148  LPC_UART->IER = IER_RBR | IER_THRE | IER_RLS; /* Enable UART interrupt */
149 #else
150  LPC_UART->IER = IER_RBR | IER_RLS; /* Enable UART interrupt */
151 #endif
152  return;
153 }
154 
155 /*****************************************************************************
156 ** Function name: UARTSend
157 **
158 ** Descriptions: Send a block of data to the UART 0 port based
159 ** on the data length
160 **
161 ** parameters: buffer pointer, and data length
162 ** Returned value: None
163 **
164 *****************************************************************************/
165 void UARTSend(uint8_t *BufferPtr, uint32_t Length)
166 {
167  LPC_UART->IER = IER_THRE | IER_RLS; // Disable RBR
168 
169  while ( Length != 0 )
170  {
171  /* THRE status, contain valid data */
172 #if !TX_INTERRUPT
173  while ( !(LPC_UART->LSR & LSR_THRE) );
174  LPC_UART->THR = *BufferPtr;
175 #else
176  /* Below flag is set inside the interrupt handler when THRE occurs. */
177  while ( !(UARTTxEmpty & 0x01) );
178  LPC_UART->THR = *BufferPtr;
179  UARTTxEmpty = 0; /* not empty in the THR until it shifts out */
180 #endif
181  BufferPtr++;
182  Length--;
183  }
184 
185  LPC_UART->IER = IER_THRE | IER_RLS | IER_RBR; // Re-enable RBR
186  return;
187 }
188 
189 
190 /******************************************************************************
191 ** End Of File
192 ******************************************************************************/
#define IIR_RDA
Definition: uart.h:25
#define LSR_PE
Definition: uart.h:31
volatile uint32_t UARTCount
Definition: uart.c:21
void UARTInit(uint32_t baudrate)
Definition: uart.c:106
unsigned char uint8_t
Definition: type.h:27
#define LSR_BI
Definition: uart.h:33
#define IER_RLS
Definition: uart.h:21
#define LSR_TEMT
Definition: uart.h:35
#define IER_THRE
Definition: uart.h:20
#define IER_RBR
Definition: uart.h:19
#define LSR_OE
Definition: uart.h:30
void UART_IRQHandler(void)
Definition: uart.c:32
#define BUFSIZE
Definition: i2c.h:16
volatile uint8_t UARTBuffer[BUFSIZE]
Definition: uart.c:20
volatile uint8_t UARTTxEmpty
Definition: uart.c:19
void UARTSend(uint8_t *BufferPtr, uint32_t Length)
Definition: uart.c:165
#define IIR_RLS
Definition: uart.h:24
#define SystemFrequency
Definition: uart.c:16
#define IIR_THRE
Definition: uart.h:27
#define IIR_CTI
Definition: uart.h:26
#define LSR_FE
Definition: uart.h:32
#define LSR_THRE
Definition: uart.h:34
#define LSR_RXFE
Definition: uart.h:36
#define LSR_RDR
Definition: uart.h:29
volatile uint32_t UARTStatus
Definition: uart.c:18
unsigned int uint32_t
Definition: type.h:29