uart_11xx.c
Go to the documentation of this file.
1 /*
2  * @brief LPC11xx UART chip driver
3  *
4  * @note
5  * Copyright(C) NXP Semiconductors, 2012
6  * All rights reserved.
7  *
8  * @par
9  * Software that is described herein is for illustrative purposes only
10  * which provides customers with programming information regarding the
11  * LPC products. This software is supplied "AS IS" without any warranties of
12  * any kind, and NXP Semiconductors and its licensor disclaim any and
13  * all warranties, express or implied, including all implied warranties of
14  * merchantability, fitness for a particular purpose and non-infringement of
15  * intellectual property rights. NXP Semiconductors assumes no responsibility
16  * or liability for the use of the software, conveys no license or rights under any
17  * patent, copyright, mask work right, or any other intellectual property rights in
18  * or to any products. NXP Semiconductors reserves the right to make changes
19  * in the software without notification. NXP Semiconductors also makes no
20  * representation or warranty that such application will be suitable for the
21  * specified use without further testing or modification.
22  *
23  * @par
24  * Permission to use, copy, modify, and distribute this software and its
25  * documentation is hereby granted, under NXP Semiconductors' and its
26  * licensor's relevant copyrights in the software, without fee, provided that it
27  * is used in conjunction with NXP Semiconductors microcontrollers. This
28  * copyright, permission, and disclaimer notice must appear in all copies of
29  * this code.
30  */
31 
32 #include "chip.h"
33 
34 #if __GNUC__
35 # pragma GCC diagnostic ignored "-Wsign-conversion"
36 # pragma GCC diagnostic ignored "-Wconversion"
37 # pragma GCC diagnostic ignored "-Wmissing-declarations"
38 # pragma GCC diagnostic ignored "-Wunused-parameter"
39 #endif
40 
41 /*****************************************************************************
42  * Private types/enumerations/variables
43  ****************************************************************************/
44 
45 /*****************************************************************************
46  * Public types/enumerations/variables
47  ****************************************************************************/
48 
49 /*****************************************************************************
50  * Private functions
51  ****************************************************************************/
52 
53 /*****************************************************************************
54  * Public functions
55  ****************************************************************************/
56 
57 /* Initializes the pUART peripheral */
59 {
62 
63  /* Enable FIFOs by default, reset them */
65 
66  /* Default 8N1, with DLAB disabled */
68 
69  /* Disable fractional divider */
70  pUART->FDR = 0x10;
71 }
72 
73 /* De-initializes the pUART peripheral */
75 {
77 }
78 
79 /* Transmit a byte array through the UART peripheral (non-blocking) */
80 int Chip_UART_Send(LPC_USART_T *pUART, const void *data, int numBytes)
81 {
82  int sent = 0;
83  uint8_t *p8 = (uint8_t *) data;
84 
85  /* Send until the transmit FIFO is full or out of bytes */
86  while ((sent < numBytes) &&
87  ((Chip_UART_ReadLineStatus(pUART) & UART_LSR_THRE) != 0)) {
88  Chip_UART_SendByte(pUART, *p8);
89  p8++;
90  sent++;
91  }
92 
93  return sent;
94 }
95 
96 /* Transmit a byte array through the UART peripheral (blocking) */
97 int Chip_UART_SendBlocking(LPC_USART_T *pUART, const void *data, int numBytes)
98 {
99  int pass, sent = 0;
100  uint8_t *p8 = (uint8_t *) data;
101 
102  while (numBytes > 0) {
103  pass = Chip_UART_Send(pUART, p8, numBytes);
104  numBytes -= pass;
105  sent += pass;
106  p8 += pass;
107  }
108 
109  return sent;
110 }
111 
112 /* Read data through the UART peripheral (non-blocking) */
113 int Chip_UART_Read(LPC_USART_T *pUART, void *data, int numBytes)
114 {
115  int readBytes = 0;
116  uint8_t *p8 = (uint8_t *) data;
117 
118  /* Send until the transmit FIFO is full or out of bytes */
119  while ((readBytes < numBytes) &&
120  ((Chip_UART_ReadLineStatus(pUART) & UART_LSR_RDR) != 0)) {
121  *p8 = Chip_UART_ReadByte(pUART);
122  p8++;
123  readBytes++;
124  }
125 
126  return readBytes;
127 }
128 
129 /* Read data through the UART peripheral (blocking) */
130 int Chip_UART_ReadBlocking(LPC_USART_T *pUART, void *data, int numBytes)
131 {
132  int pass, readBytes = 0;
133  uint8_t *p8 = (uint8_t *) data;
134 
135  while (readBytes < numBytes) {
136  pass = Chip_UART_Read(pUART, p8, numBytes);
137  numBytes -= pass;
138  readBytes += pass;
139  p8 += pass;
140  }
141 
142  return readBytes;
143 }
144 
145 /* Determines and sets best dividers to get a target bit rate */
147 {
148  uint32_t div, divh, divl, clkin;
149 
150  /* Determine UART clock in rate without FDR */
151  clkin = Chip_Clock_GetMainClockRate();
152  div = clkin / (baudrate * 16);
153 
154  /* High and low halves of the divider */
155  divh = div / 256;
156  divl = div - (divh * 256);
157 
159  Chip_UART_SetDivisorLatches(pUART, divl, divh);
161 
162  /* Fractional FDR alreadt setup for 1 in UART init */
163 
164  return clkin / div;
165 }
166 
167 /* UART receive-only interrupt handler for ring buffers */
169 {
170  /* New data will be ignored if data not popped in time */
171  while (Chip_UART_ReadLineStatus(pUART) & UART_LSR_RDR) {
172  uint8_t ch = Chip_UART_ReadByte(pUART);
173  RingBuffer_Insert(pRB, &ch);
174  }
175 }
176 
177 /* UART transmit-only interrupt handler for ring buffers */
179 {
180  uint8_t ch;
181 
182  /* Fill FIFO until full or until TX ring buffer is empty */
183  while ((Chip_UART_ReadLineStatus(pUART) & UART_LSR_THRE) != 0 &&
184  RingBuffer_Pop(pRB, &ch)) {
185  Chip_UART_SendByte(pUART, ch);
186  }
187 }
188 
189 /* Populate a transmit ring buffer and start UART transmit */
190 uint32_t Chip_UART_SendRB(LPC_USART_T *pUART, RINGBUFF_T *pRB, const void *data, int bytes)
191 {
192  uint32_t ret;
193  uint8_t *p8 = (uint8_t *) data;
194 
195  /* Don't let UART transmit ring buffer change in the UART IRQ handler */
197 
198  /* Move as much data as possible into transmit ring buffer */
199  ret = RingBuffer_InsertMult(pRB, p8, bytes);
200  Chip_UART_TXIntHandlerRB(pUART, pRB);
201 
202  /* Add additional data to transmit ring buffer if possible */
203  ret += RingBuffer_InsertMult(pRB, (p8 + ret), (bytes - ret));
204 
205  /* Enable UART transmit interrupt */
207 
208  return ret;
209 }
210 
211 /* Copy data from a receive ring buffer */
212 int Chip_UART_ReadRB(LPC_USART_T *pUART, RINGBUFF_T *pRB, void *data, int bytes)
213 {
214  (void) pUART;
215 
216  return RingBuffer_PopMult(pRB, (uint8_t *) data, bytes);
217 }
218 
219 /* UART receive/transmit interrupt handler for ring buffers */
221 {
222  /* Handle transmit interrupt if enabled */
223  if (pUART->IER & UART_IER_THREINT) {
224  Chip_UART_TXIntHandlerRB(pUART, pTXRB);
225 
226  /* Disable transmit interrupt if the ring buffer is empty */
227  if (RingBuffer_IsEmpty(pTXRB)) {
229  }
230  }
231 
232  /* Handle receive interrupt */
233  Chip_UART_RXIntHandlerRB(pUART, pRXRB);
234 }
235 
236 /* Determines and sets best dividers to get a target baud rate */
238 
239 {
240  uint32_t uClk = 0;
241  uint32_t dval = 0;
242  uint32_t mval = 0;
243  uint32_t dl = 0;
244  uint32_t rate16 = 16 * baudrate;
245  uint32_t actualRate = 0;
246 
247  /* Get Clock rate */
249 
250  /* The fractional is calculated as (PCLK % (16 * Baudrate)) / (16 * Baudrate)
251  * Let's make it to be the ratio DivVal / MulVal
252  */
253  dval = uClk % rate16;
254 
255  /* The PCLK / (16 * Baudrate) is fractional
256  * => dval = pclk % rate16
257  * mval = rate16;
258  * now mormalize the ratio
259  * dval / mval = 1 / new_mval
260  * new_mval = mval / dval
261  * new_dval = 1
262  */
263  if (dval > 0) {
264  mval = rate16 / dval;
265  dval = 1;
266 
267  /* In case mval still bigger then 4 bits
268  * no adjustment require
269  */
270  if (mval > 12) {
271  dval = 0;
272  }
273  }
274  dval &= 0xf;
275  mval &= 0xf;
276  dl = uClk / (rate16 + rate16 *dval / mval);
277 
278  /* Update UART registers */
282 
283  /* Set best fractional divider */
284  pUART->FDR = (UART_FDR_MULVAL(mval) | UART_FDR_DIVADDVAL(dval));
285 
286  /* Return actual baud rate */
287  actualRate = uClk / (16 * dl + 16 * dl * dval / mval);
288  return actualRate;
289 }
Chip_UART_DeInit
void Chip_UART_DeInit(LPC_USART_T *pUART)
De-initializes the pUART peripheral.
Definition: uart_11xx.c:74
RingBuffer_PopMult
int RingBuffer_PopMult(RINGBUFF_T *RingBuff, void *data, int num)
Pop an array of items from the ring buffer.
Chip_UART_DisableDivisorAccess
STATIC INLINE void Chip_UART_DisableDivisorAccess(LPC_USART_T *pUART)
Disable access to Divisor Latches.
Definition: uart_11xx.h:439
LPC_USART_T
USART register block structure.
Definition: uart_11xx.h:49
uavcan::uint32_t
std::uint32_t uint32_t
Definition: std.hpp:26
Chip_UART_ReadByte
STATIC INLINE uint8_t Chip_UART_ReadByte(LPC_USART_T *pUART)
Read a single byte data from the UART peripheral.
Definition: uart_11xx.h:336
UART_FCR_RX_RS
#define UART_FCR_RX_RS
Definition: uart_11xx.h:147
UART_LSR_THRE
#define UART_LSR_THRE
Definition: uart_11xx.h:204
UART_FCR_TX_RS
#define UART_FCR_TX_RS
Definition: uart_11xx.h:148
UART_FDR_DIVADDVAL
#define UART_FDR_DIVADDVAL(n)
Macro defines for UART Fractional Divider Register.
Definition: uart_11xx.h:274
UART_LCR_SBS_1BIT
#define UART_LCR_SBS_1BIT
Definition: uart_11xx.h:172
RingBuffer_InsertMult
int RingBuffer_InsertMult(RINGBUFF_T *RingBuff, const void *data, int num)
Insert an array of items into ring buffer.
UART_LCR_PARITY_DIS
#define UART_LCR_PARITY_DIS
Definition: uart_11xx.h:177
RingBuffer_IsEmpty
STATIC INLINE int RingBuffer_IsEmpty(RINGBUFF_T *RingBuff)
Return empty status of ring buffer.
Definition: ring_buffer.h:133
UART_LCR_WLEN8
#define UART_LCR_WLEN8
Definition: uart_11xx.h:168
Chip_UART_IRQRBHandler
void Chip_UART_IRQRBHandler(LPC_USART_T *pUART, RINGBUFF_T *pRXRB, RINGBUFF_T *pTXRB)
UART receive/transmit interrupt handler for ring buffers.
Definition: uart_11xx.c:220
Chip_UART_SendByte
STATIC INLINE void Chip_UART_SendByte(LPC_USART_T *pUART, uint8_t data)
Transmit a single data byte through the UART peripheral.
Definition: uart_11xx.h:323
Chip_UART_IntDisable
STATIC INLINE void Chip_UART_IntDisable(LPC_USART_T *pUART, uint32_t intMask)
Disable UART interrupts.
Definition: uart_11xx.h:366
Chip_UART_ReadRB
int Chip_UART_ReadRB(LPC_USART_T *pUART, RINGBUFF_T *pRB, void *data, int bytes)
Copy data from a receive ring buffer.
Definition: uart_11xx.c:212
Chip_UART_EnableDivisorAccess
STATIC INLINE void Chip_UART_EnableDivisorAccess(LPC_USART_T *pUART)
Enable access to Divisor Latches.
Definition: uart_11xx.h:429
UART_FCR_FIFO_EN
#define UART_FCR_FIFO_EN
Macro defines for UART FIFO Control Register.
Definition: uart_11xx.h:146
LPC_USART_T::FDR
__IO uint32_t FDR
Definition: uart_11xx.h:74
Chip_UART_IntEnable
STATIC INLINE void Chip_UART_IntEnable(LPC_USART_T *pUART, uint32_t intMask)
Enable UART interrupts.
Definition: uart_11xx.h:351
UART_FDR_MULVAL
#define UART_FDR_MULVAL(n)
Definition: uart_11xx.h:275
UART_LSR_RDR
#define UART_LSR_RDR
Macro defines for UART Line Status Register.
Definition: uart_11xx.h:199
Chip_Clock_EnablePeriphClock
STATIC INLINE void Chip_Clock_EnablePeriphClock(CHIP_SYSCTL_CLOCK_T clk)
Enable a system or peripheral clock.
Definition: clock_11xx.h:295
Chip_Clock_SetUARTClockDiv
STATIC INLINE void Chip_Clock_SetUARTClockDiv(uint32_t div)
Set UART divider clock.
Definition: clock_11xx.h:339
Chip_UART_TXIntHandlerRB
void Chip_UART_TXIntHandlerRB(LPC_USART_T *pUART, RINGBUFF_T *pRB)
UART transmit-only interrupt handler for ring buffers.
Definition: uart_11xx.c:178
UART_LOAD_DLM
#define UART_LOAD_DLM(div)
Macro defines for UART Divisor Latch MSB register.
Definition: uart_11xx.h:109
UART_LOAD_DLL
#define UART_LOAD_DLL(div)
Macro defines for UART Divisor Latch LSB register.
Definition: uart_11xx.h:103
uavcan::uint8_t
std::uint8_t uint8_t
Definition: std.hpp:24
UART_IER_THREINT
#define UART_IER_THREINT
Definition: uart_11xx.h:116
Chip_UART_RXIntHandlerRB
void Chip_UART_RXIntHandlerRB(LPC_USART_T *pUART, RINGBUFF_T *pRB)
UART receive-only interrupt handler for ring buffers.
Definition: uart_11xx.c:168
Chip_UART_SetDivisorLatches
STATIC INLINE void Chip_UART_SetDivisorLatches(LPC_USART_T *pUART, uint8_t dll, uint8_t dlm)
Set LSB and MSB divisor latch registers.
Definition: uart_11xx.h:454
RINGBUFF_T
Ring buffer structure.
Definition: ring_buffer.h:45
Chip_UART_ReadLineStatus
STATIC INLINE uint32_t Chip_UART_ReadLineStatus(LPC_USART_T *pUART)
Return Line Status register/status (LSR)
Definition: uart_11xx.h:505
Chip_UART_ConfigData
STATIC INLINE void Chip_UART_ConfigData(LPC_USART_T *pUART, uint32_t config)
Configure data width, parity and stop bits.
Definition: uart_11xx.h:419
LPC_USART_T::IER
__IO uint32_t IER
Definition: uart_11xx.h:58
Chip_Clock_GetMainClockRate
uint32_t Chip_Clock_GetMainClockRate(void)
Return main clock rate.
Definition: clock_11xx.c:248
RingBuffer_Insert
int RingBuffer_Insert(RINGBUFF_T *RingBuff, const void *data)
Insert a single item into ring buffer.
Chip_UART_SetBaud
uint32_t Chip_UART_SetBaud(LPC_USART_T *pUART, uint32_t baudrate)
Sets best dividers to get a target bit rate (without fractional divider)
Definition: uart_11xx.c:146
Chip_UART_Init
void Chip_UART_Init(LPC_USART_T *pUART)
Initializes the pUART peripheral.
Definition: uart_11xx.c:58
Chip_UART_Read
int Chip_UART_Read(LPC_USART_T *pUART, void *data, int numBytes)
Read data through the UART peripheral (non-blocking)
Definition: uart_11xx.c:113
Chip_UART_Send
int Chip_UART_Send(LPC_USART_T *pUART, const void *data, int numBytes)
Transmit a byte array through the UART peripheral (non-blocking)
Definition: uart_11xx.c:80
Chip_UART_ReadBlocking
int Chip_UART_ReadBlocking(LPC_USART_T *pUART, void *data, int numBytes)
Read data through the UART peripheral (blocking)
Definition: uart_11xx.c:130
chip.h
Chip_UART_SetBaudFDR
uint32_t Chip_UART_SetBaudFDR(LPC_USART_T *pUART, uint32_t baudrate)
Sets best dividers to get a target bit rate (with fractional divider)
Definition: uart_11xx.c:237
Chip_UART_SendRB
uint32_t Chip_UART_SendRB(LPC_USART_T *pUART, RINGBUFF_T *pRB, const void *data, int bytes)
Populate a transmit ring buffer and start UART transmit.
Definition: uart_11xx.c:190
RingBuffer_Pop
int RingBuffer_Pop(RINGBUFF_T *RingBuff, void *data)
Pop an item from the ring buffer.
Chip_UART_SetupFIFOS
STATIC INLINE void Chip_UART_SetupFIFOS(LPC_USART_T *pUART, uint32_t fcr)
Setup the UART FIFOs.
Definition: uart_11xx.h:404
Chip_Clock_DisablePeriphClock
STATIC INLINE void Chip_Clock_DisablePeriphClock(CHIP_SYSCTL_CLOCK_T clk)
Disable a system or peripheral clock.
Definition: clock_11xx.h:305
SYSCTL_CLOCK_UART0
@ SYSCTL_CLOCK_UART0
Definition: clock_11xx.h:245
Chip_UART_SendBlocking
int Chip_UART_SendBlocking(LPC_USART_T *pUART, const void *data, int numBytes)
Transmit a byte array through the UART peripheral (blocking)
Definition: uart_11xx.c:97


uavcan_communicator
Author(s):
autogenerated on Fri Dec 13 2024 03:10:03