User | Revision | Line number | New contents of line |
jp |
0:cf255d2aa92f
|
1
|
/*
|
jp |
0:cf255d2aa92f
|
2
|
* Copyright or © or Copr. 2010, Thomas SOETE
|
jp |
0:cf255d2aa92f
|
3
|
*
|
jp |
0:cf255d2aa92f
|
4
|
* Author e-mail: thomas@soete.org
|
jp |
0:cf255d2aa92f
|
5
|
* Library website : http://mbed.org/users/Alkorin/libraries/SimpleLib/
|
jp |
0:cf255d2aa92f
|
6
|
*
|
jp |
0:cf255d2aa92f
|
7
|
* This software is governed by the CeCILL license under French law and
|
jp |
0:cf255d2aa92f
|
8
|
* abiding by the rules of distribution of free software. You can use,
|
jp |
0:cf255d2aa92f
|
9
|
* modify and/ or redistribute the software under the terms of the CeCILL
|
jp |
0:cf255d2aa92f
|
10
|
* license as circulated by CEA, CNRS and INRIA at the following URL
|
jp |
0:cf255d2aa92f
|
11
|
* "http://www.cecill.info".
|
jp |
0:cf255d2aa92f
|
12
|
*
|
jp |
0:cf255d2aa92f
|
13
|
* As a counterpart to the access to the source code and rights to copy,
|
jp |
0:cf255d2aa92f
|
14
|
* modify and redistribute granted by the license, users are provided only
|
jp |
0:cf255d2aa92f
|
15
|
* with a limited warranty and the software's author, the holder of the
|
jp |
0:cf255d2aa92f
|
16
|
* economic rights, and the successive licensors have only limited
|
jp |
0:cf255d2aa92f
|
17
|
* liability.
|
jp |
0:cf255d2aa92f
|
18
|
*
|
jp |
0:cf255d2aa92f
|
19
|
* In this respect, the user's attention is drawn to the risks associated
|
jp |
0:cf255d2aa92f
|
20
|
* with loading, using, modifying and/or developing or reproducing the
|
jp |
0:cf255d2aa92f
|
21
|
* software by the user in light of its specific status of free software,
|
jp |
0:cf255d2aa92f
|
22
|
* that may mean that it is complicated to manipulate, and that also
|
jp |
0:cf255d2aa92f
|
23
|
* therefore means that it is reserved for developers and experienced
|
jp |
0:cf255d2aa92f
|
24
|
* professionals having in-depth computer knowledge. Users are therefore
|
jp |
0:cf255d2aa92f
|
25
|
* encouraged to load and test the software's suitability as regards their
|
jp |
0:cf255d2aa92f
|
26
|
* requirements in conditions enabling the security of their systems and/or
|
jp |
0:cf255d2aa92f
|
27
|
* data to be ensured and, more generally, to use and operate it in the
|
jp |
0:cf255d2aa92f
|
28
|
* same conditions as regards security.
|
jp |
0:cf255d2aa92f
|
29
|
*
|
jp |
0:cf255d2aa92f
|
30
|
* The fact that you are presently reading this means that you have had
|
jp |
0:cf255d2aa92f
|
31
|
* knowledge of the CeCILL license and that you accept its terms.
|
jp |
0:cf255d2aa92f
|
32
|
*/
|
jp |
0:cf255d2aa92f
|
33
|
|
jp |
0:cf255d2aa92f
|
34
|
#ifndef __SIMPLELIB_SERIAL_H__
|
jp |
0:cf255d2aa92f
|
35
|
#define __SIMPLELIB_SERIAL_H__
|
jp |
0:cf255d2aa92f
|
36
|
|
jp |
0:cf255d2aa92f
|
37
|
#include "mbed_globals.h"
|
jp |
0:cf255d2aa92f
|
38
|
#include "interrupts.h"
|
jp |
0:cf255d2aa92f
|
39
|
|
jp |
0:cf255d2aa92f
|
40
|
/**********************************
|
jp |
0:cf255d2aa92f
|
41
|
* Simple Serial Managment *
|
jp |
0:cf255d2aa92f
|
42
|
**********************************
|
jp |
0:cf255d2aa92f
|
43
|
* The interrupt handler is : *
|
jp |
0:cf255d2aa92f
|
44
|
* SERIAL_INTERRUPT_HANDLER(void) *
|
jp |
0:cf255d2aa92f
|
45
|
* UART0 : Serial over USB *
|
jp |
0:cf255d2aa92f
|
46
|
* UART1 : TX p13, RX p14 *
|
jp |
0:cf255d2aa92f
|
47
|
* UART2 : TX p28, RX p27 *
|
jp |
0:cf255d2aa92f
|
48
|
* UART3 : TX p9, RX p10 *
|
jp |
0:cf255d2aa92f
|
49
|
**********************************/
|
jp |
0:cf255d2aa92f
|
50
|
|
jp |
0:cf255d2aa92f
|
51
|
/** Registers **/
|
jp |
0:cf255d2aa92f
|
52
|
// Serial port (Choose UARTn (0,1,2,3))
|
jp |
0:cf255d2aa92f
|
53
|
#define UART_NUMBER UART0
|
jp |
0:cf255d2aa92f
|
54
|
#define UART_BASE TOKENPASTE2(LPC_,UART_NUMBER)
|
jp |
0:cf255d2aa92f
|
55
|
|
jp |
0:cf255d2aa92f
|
56
|
// Peripheral Clock Selection registers (See 4.7.3 p56)
|
jp |
0:cf255d2aa92f
|
57
|
#define UART0_PCLK_REG (LPC_SC->PCLKSEL0)
|
jp |
0:cf255d2aa92f
|
58
|
#define UART1_PCLK_REG (LPC_SC->PCLKSEL0)
|
jp |
0:cf255d2aa92f
|
59
|
#define UART2_PCLK_REG (LPC_SC->PCLKSEL1)
|
jp |
0:cf255d2aa92f
|
60
|
#define UART3_PCLK_REG (LPC_SC->PCLKSEL1)
|
jp |
0:cf255d2aa92f
|
61
|
#define UART_PCLK_REG TOKENPASTE2(UART_NUMBER,_PCLK_REG)
|
jp |
0:cf255d2aa92f
|
62
|
|
jp |
0:cf255d2aa92f
|
63
|
#define UART0_PCLK_OFFSET 6
|
jp |
0:cf255d2aa92f
|
64
|
#define UART1_PCLK_OFFSET 8
|
jp |
0:cf255d2aa92f
|
65
|
#define UART2_PCLK_OFFSET 16
|
jp |
0:cf255d2aa92f
|
66
|
#define UART3_PCLK_OFFSET 18
|
jp |
0:cf255d2aa92f
|
67
|
#define UART_PCLK_OFFSET TOKENPASTE2(UART_NUMBER,_PCLK_OFFSET)
|
jp |
0:cf255d2aa92f
|
68
|
|
jp |
0:cf255d2aa92f
|
69
|
#define UART0_PCLK ((LPC_SC->PCLKSEL0 >> 6) & 0x03)
|
jp |
0:cf255d2aa92f
|
70
|
#define UART1_PCLK ((LPC_SC->PCLKSEL0 >> 8) & 0x03)
|
jp |
0:cf255d2aa92f
|
71
|
#define UART2_PCLK ((LPC_SC->PCLKSEL1 >> 16) & 0x03)
|
jp |
0:cf255d2aa92f
|
72
|
#define UART3_PCLK ((LPC_SC->PCLKSEL1 >> 18) & 0x03)
|
jp |
0:cf255d2aa92f
|
73
|
#define UART_PCLK TOKENPASTE2(UART_NUMBER,_PCLK)
|
jp |
0:cf255d2aa92f
|
74
|
|
jp |
0:cf255d2aa92f
|
75
|
// Pin Function Select register (See 8.5.1-8 p108)
|
jp |
0:cf255d2aa92f
|
76
|
#define UART0RX_PINSEL_REG (LPC_PINCON->PINSEL0)
|
jp |
0:cf255d2aa92f
|
77
|
#define UART1RX_PINSEL_REG (LPC_PINCON->PINSEL1)
|
jp |
0:cf255d2aa92f
|
78
|
#define UART2RX_PINSEL_REG (LPC_PINCON->PINSEL0)
|
jp |
0:cf255d2aa92f
|
79
|
#define UART3RX_PINSEL_REG (LPC_PINCON->PINSEL0)
|
jp |
0:cf255d2aa92f
|
80
|
#define UARTRX_PINSEL_REG TOKENPASTE2(UART_NUMBER,RX_PINSEL_REG)
|
jp |
0:cf255d2aa92f
|
81
|
|
jp |
0:cf255d2aa92f
|
82
|
#define UART0TX_PINSEL_REG (LPC_PINCON->PINSEL0)
|
jp |
0:cf255d2aa92f
|
83
|
#define UART1TX_PINSEL_REG (LPC_PINCON->PINSEL0)
|
jp |
0:cf255d2aa92f
|
84
|
#define UART2TX_PINSEL_REG (LPC_PINCON->PINSEL0)
|
jp |
0:cf255d2aa92f
|
85
|
#define UART3TX_PINSEL_REG (LPC_PINCON->PINSEL0)
|
jp |
0:cf255d2aa92f
|
86
|
#define UARTTX_PINSEL_REG TOKENPASTE2(UART_NUMBER,TX_PINSEL_REG)
|
jp |
0:cf255d2aa92f
|
87
|
|
jp |
0:cf255d2aa92f
|
88
|
#define UART0RX_PINSEL_OFFSET 6
|
jp |
0:cf255d2aa92f
|
89
|
#define UART1RX_PINSEL_OFFSET 0
|
jp |
0:cf255d2aa92f
|
90
|
#define UART2RX_PINSEL_OFFSET 22
|
jp |
0:cf255d2aa92f
|
91
|
#define UART3RX_PINSEL_OFFSET 2
|
jp |
0:cf255d2aa92f
|
92
|
#define UARTRX_PINSEL_OFFSET TOKENPASTE2(UART_NUMBER,RX_PINSEL_OFFSET)
|
jp |
0:cf255d2aa92f
|
93
|
|
jp |
0:cf255d2aa92f
|
94
|
#define UART0TX_PINSEL_OFFSET 4
|
jp |
0:cf255d2aa92f
|
95
|
#define UART1TX_PINSEL_OFFSET 30
|
jp |
0:cf255d2aa92f
|
96
|
#define UART2TX_PINSEL_OFFSET 20
|
jp |
0:cf255d2aa92f
|
97
|
#define UART3TX_PINSEL_OFFSET 0
|
jp |
0:cf255d2aa92f
|
98
|
#define UARTTX_PINSEL_OFFSET TOKENPASTE2(UART_NUMBER,TX_PINSEL_OFFSET)
|
jp |
0:cf255d2aa92f
|
99
|
|
jp |
0:cf255d2aa92f
|
100
|
#define UART0_PINSEL_VALUE 1U
|
jp |
0:cf255d2aa92f
|
101
|
#define UART1_PINSEL_VALUE 1U
|
jp |
0:cf255d2aa92f
|
102
|
#define UART2_PINSEL_VALUE 1U
|
jp |
0:cf255d2aa92f
|
103
|
#define UART3_PINSEL_VALUE 2U
|
jp |
0:cf255d2aa92f
|
104
|
#define UART_PINSEL_VALUE TOKENPASTE2(UART_NUMBER,_PINSEL_VALUE)
|
jp |
0:cf255d2aa92f
|
105
|
|
jp |
0:cf255d2aa92f
|
106
|
/** Interrupt handlers **/
|
jp |
0:cf255d2aa92f
|
107
|
#define SERIAL_INTERRUPT_HANDLER EXTERN_C void __IRQ TOKENPASTE2(UART_NUMBER,_IRQHandler)
|
jp |
0:cf255d2aa92f
|
108
|
|
jp |
0:cf255d2aa92f
|
109
|
/** Bits **/
|
jp |
0:cf255d2aa92f
|
110
|
// RBR Interrupt Enable (UnIER, 14.4.4 p302)
|
jp |
0:cf255d2aa92f
|
111
|
#define RBR_INT_BIT 0
|
jp |
0:cf255d2aa92f
|
112
|
// Receiver Data Ready (UnLSR, 14.4.8 p306)
|
jp |
0:cf255d2aa92f
|
113
|
#define RDR_BIT 0
|
jp |
0:cf255d2aa92f
|
114
|
// Transmitter Holding Register Empty (UnLSR, 14.4.8 p306)
|
jp |
0:cf255d2aa92f
|
115
|
#define THRE_BIT 5
|
jp |
0:cf255d2aa92f
|
116
|
// RBR Interrupt Enable (UnIER, 14.4.4 p302)
|
jp |
0:cf255d2aa92f
|
117
|
#define SERIAL_INT_RX 1
|
jp |
0:cf255d2aa92f
|
118
|
// THRE Interrupt Enable (UnIER, 14.4.4 p302)
|
jp |
0:cf255d2aa92f
|
119
|
#define SERIAL_INT_TX 2
|
jp |
0:cf255d2aa92f
|
120
|
// Divisor Latch Access Bit (UnLCR, 14.4.7 p306)
|
jp |
0:cf255d2aa92f
|
121
|
#define DLA_BIT 7
|
jp |
0:cf255d2aa92f
|
122
|
// Power Control for Peripherals (PCONP, 4.8.7.1 p63)
|
jp |
0:cf255d2aa92f
|
123
|
#define UART0_PCONP_BIT 3
|
jp |
0:cf255d2aa92f
|
124
|
#define UART1_PCONP_BIT 4
|
jp |
0:cf255d2aa92f
|
125
|
#define UART2_PCONP_BIT 24
|
jp |
0:cf255d2aa92f
|
126
|
#define UART3_PCONP_BIT 25
|
jp |
0:cf255d2aa92f
|
127
|
|
jp |
0:cf255d2aa92f
|
128
|
/** Macros **/
|
jp |
0:cf255d2aa92f
|
129
|
#define SERIAL_PUTCHAR(c) do { \
|
jp |
0:cf255d2aa92f
|
130
|
while (GET_BIT_VALUE(UART_BASE->LSR, THRE_BIT) == 0); \
|
jp |
0:cf255d2aa92f
|
131
|
UART_BASE->THR = c; \
|
jp |
0:cf255d2aa92f
|
132
|
} while(0)
|
jp |
0:cf255d2aa92f
|
133
|
|
jp |
0:cf255d2aa92f
|
134
|
#define SERIAL_DATA_TO_READ() (GET_BIT_VALUE(UART_BASE->LSR, RDR_BIT) == 1)
|
jp |
0:cf255d2aa92f
|
135
|
|
jp |
0:cf255d2aa92f
|
136
|
#define SERIAL_GETCHAR() (UART_BASE->RBR)
|
jp |
0:cf255d2aa92f
|
137
|
|
jp |
0:cf255d2aa92f
|
138
|
// Enable interrupt for RX or TX (SERIAL_INT_RX and SERIAL_INT_TX)
|
jp |
0:cf255d2aa92f
|
139
|
#define SERIAL_ENABLE_INTERRUPT(value) do { \
|
jp |
0:cf255d2aa92f
|
140
|
UART_BASE->IER = value; \
|
jp |
0:cf255d2aa92f
|
141
|
ENABLE_INTERRUPT(TOKENPASTE2(UART_NUMBER,_IRQn)); \
|
jp |
0:cf255d2aa92f
|
142
|
} while(0)
|
jp |
0:cf255d2aa92f
|
143
|
|
jp |
0:cf255d2aa92f
|
144
|
extern __INLINE void SERIAL_INIT()
|
jp |
0:cf255d2aa92f
|
145
|
{
|
jp |
0:cf255d2aa92f
|
146
|
// Enable UARTn
|
jp |
0:cf255d2aa92f
|
147
|
SET_BIT_VALUE(LPC_SC->PCONP, TOKENPASTE2(UART_NUMBER,_PCONP_BIT) , 1);
|
jp |
0:cf255d2aa92f
|
148
|
// Enable FIFO and reset RX/TX FIFO (See 14.4.6 p305)
|
jp |
0:cf255d2aa92f
|
149
|
UART_BASE->FCR = 0x07;
|
jp |
0:cf255d2aa92f
|
150
|
// 8-bits, No Parity, 1 stop bit (See 14.4.7 p306)
|
jp |
0:cf255d2aa92f
|
151
|
UART_BASE->LCR = 0x03;
|
jp |
0:cf255d2aa92f
|
152
|
// Set CCLK as Peripheral Clock for UART (96MHz with mbed library)
|
jp |
0:cf255d2aa92f
|
153
|
UART_PCLK_REG = (UART_PCLK_REG & (~(3UL << UART_PCLK_OFFSET))) | (1U << UART_PCLK_OFFSET);
|
jp |
0:cf255d2aa92f
|
154
|
// Define Pin's functions as UART
|
jp |
0:cf255d2aa92f
|
155
|
UARTRX_PINSEL_REG = (UARTRX_PINSEL_REG & (~(3U << UARTRX_PINSEL_OFFSET))) | (UART_PINSEL_VALUE << UARTRX_PINSEL_OFFSET);
|
jp |
0:cf255d2aa92f
|
156
|
UARTTX_PINSEL_REG = (UARTTX_PINSEL_REG & (~(3U << UARTTX_PINSEL_OFFSET))) | (UART_PINSEL_VALUE << UARTTX_PINSEL_OFFSET);
|
jp |
0:cf255d2aa92f
|
157
|
}
|
jp |
0:cf255d2aa92f
|
158
|
|
jp |
0:cf255d2aa92f
|
159
|
// See 14.4.5 p303
|
jp |
0:cf255d2aa92f
|
160
|
extern __INLINE int SERIAL_CHECK_INTERRUPT(void) {
|
jp |
0:cf255d2aa92f
|
161
|
uint32_t serialStatus = UART_BASE->IIR;
|
jp |
0:cf255d2aa92f
|
162
|
|
jp |
0:cf255d2aa92f
|
163
|
if (serialStatus & 1) // IntStatus, 1 = No Interrupt is pending.
|
jp |
0:cf255d2aa92f
|
164
|
return 0;
|
jp |
0:cf255d2aa92f
|
165
|
|
jp |
0:cf255d2aa92f
|
166
|
serialStatus = (serialStatus >> 1) & 0x3; // IntId, 2 = More than threshold data to read, 6 = Some caracters to read
|
jp |
0:cf255d2aa92f
|
167
|
if (serialStatus != 2 && serialStatus != 6)
|
jp |
0:cf255d2aa92f
|
168
|
return 0;
|
jp |
0:cf255d2aa92f
|
169
|
|
jp |
0:cf255d2aa92f
|
170
|
return 1;
|
jp |
0:cf255d2aa92f
|
171
|
}
|
jp |
0:cf255d2aa92f
|
172
|
|
jp |
0:cf255d2aa92f
|
173
|
extern __INLINE void SERIAL_SETBAUD(unsigned int baud) {
|
jp |
0:cf255d2aa92f
|
174
|
// Peripheral Clock Selection register bit values (See Table 42, p57)
|
jp |
0:cf255d2aa92f
|
175
|
uint16_t divisorValue = (SystemCoreClock / 16 / baud);
|
jp |
0:cf255d2aa92f
|
176
|
#if 0
|
jp |
0:cf255d2aa92f
|
177
|
// Peripheral Clock for UART is set to CCLK in SERIAL_INIT. Divisor is then 1.
|
jp |
0:cf255d2aa92f
|
178
|
// Else, use code below
|
jp |
0:cf255d2aa92f
|
179
|
static int divisors[4] = { 4, 1, 2, 8 };
|
jp |
0:cf255d2aa92f
|
180
|
uint16_t divisorValue = ((SystemCoreClock / 16 / baud) / divisors[UART_PCLK]);
|
jp |
0:cf255d2aa92f
|
181
|
#endif
|
jp |
0:cf255d2aa92f
|
182
|
|
jp |
0:cf255d2aa92f
|
183
|
UART_BASE->LCR |= (1 << DLA_BIT);
|
jp |
0:cf255d2aa92f
|
184
|
UART_BASE->DLM = (uint8_t) (divisorValue >> 8);
|
jp |
0:cf255d2aa92f
|
185
|
UART_BASE->DLL = (uint8_t) divisorValue;
|
jp |
0:cf255d2aa92f
|
186
|
UART_BASE->LCR &= ~(1 << DLA_BIT);
|
jp |
0:cf255d2aa92f
|
187
|
}
|
jp |
0:cf255d2aa92f
|
188
|
|
jp |
0:cf255d2aa92f
|
189
|
#endif |