/
uart.cpp
149 lines (121 loc) · 3.41 KB
/
uart.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
//
// begin license header
//
// This file is part of Pixy CMUcam5 or "Pixy" for short
//
// All Pixy source code is provided under the terms of the
// GNU General Public License v2 (http://www.gnu.org/licenses/gpl-2.0.html).
// Those wishing to use Pixy source code, software and/or
// technologies under different licensing terms should contact us at
// cmucam@cs.cmu.edu. Such licensing terms are available for
// all portions of the Pixy codebase presented here.
//
// end license header
//
#include "inttypes.h"
#include "lpc43xx_scu.h"
#include "pixyvals.h"
#include "uart.h"
Uart *g_uart0;
extern "C" void UART0_IRQHandler(void);
void UART0_IRQHandler(void)
{
g_uart0->irqHandler();
}
void Uart::irqHandler()
{
uint32_t status;
uint8_t i, c;
volatile uint32_t v;
m_flag = false;
/* Determine the interrupt source */
status = m_uart->IIR & UART_IIR_INTID_MASK;
if (status==UART_IIR_INTID_RDA) // Receive Data Available
m_rq.write(m_uart->RBR&UART_RBR_MASKBIT);
else if (status==UART_IIR_INTID_CTI)
v = m_uart->RBR; // toss...
else if (status==UART_IIR_INTID_THRE) // Transmit Holding Empty
{
for (i=0; i<UART_TX_FIFO_SIZE; i++) // fill transmit FIFO
{
if (m_tq.read(&c))
{
m_flag = true;
m_uart->THR = c;
}
}
}
}
int Uart::open()
{
scu_pinmux(0x2, 0, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC1); // U0_TXD
scu_pinmux(0x2, 1, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC1); // U0_RXD
scu_pinmux(0x1, 3, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC0); // turn SSP1_MISO into GPIO0[10]
scu_pinmux(0x1, 4, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC0); // turn SSP1_MOSI into GPIO0[11]
NVIC_EnableIRQ(USART0_IRQn);
return 0;
}
int Uart::close()
{
scu_pinmux(0x2, 0, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC4); // U0_TXD
scu_pinmux(0x2, 1, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC4); // U0_RXD
NVIC_DisableIRQ(USART0_IRQn);
return 0;
}
int Uart::receive(uint8_t *buf, uint32_t len)
{
uint32_t i;
for (i=0; i<len; i++)
{
if (m_rq.read(buf+i)==0)
break;
}
return i;
}
int Uart::receiveLen()
{
return m_rq.receiveLen();
}
int Uart::update()
{
if (m_flag==false)
{
m_uart->THR = 0; // send a 0 to get the transmit interrupt going again, send 16 bits
m_uart->THR = 0;
}
return 0;
}
Uart::Uart(LPC_USARTn_Type *uart, SerialCallback callback) : m_rq(UART_RECEIVE_BUF_SIZE), m_tq(UART_TRANSMIT_BUF_SIZE, callback)
{
UART_FIFO_CFG_Type ufifo;
UART_CFG_Type ucfg;
m_uart = uart;
m_flag = false;
// regular config
ucfg.Baud_rate = UART_DEFAULT_BAUDRATE;
ucfg.Databits = UART_DATABIT_8;
ucfg.Parity = UART_PARITY_NONE;
ucfg.Stopbits = UART_STOPBIT_1;
ucfg.Clock_Speed = CLKFREQ;
UART_Init(m_uart, &ucfg);
// config FIFOs
ufifo.FIFO_DMAMode = DISABLE;
ufifo.FIFO_Level = UART_FIFO_TRGLEV0;
ufifo.FIFO_ResetRxBuf = ENABLE;
ufifo.FIFO_ResetTxBuf = ENABLE;
UART_FIFOConfig(m_uart, &ufifo);
UART_TxCmd(m_uart, ENABLE);
// enable interrupts
UART_IntConfig(m_uart, UART_INTCFG_RBR, ENABLE);
UART_IntConfig(m_uart, UART_INTCFG_THRE, ENABLE);
NVIC_SetPriority(USART0_IRQn, 0);
}
int Uart::setBaudrate(uint32_t baudrate)
{
UART_setBaudRate(m_uart, baudrate, CLKFREQ);
return 0;
}
void uart_init(SerialCallback callback)
{
g_uart0 = new Uart(LPC_USART0, callback);
}