-
Notifications
You must be signed in to change notification settings - Fork 136
Expand file tree
/
Copy pathserial.h
More file actions
186 lines (157 loc) · 5.68 KB
/
Copy pathserial.h
File metadata and controls
186 lines (157 loc) · 5.68 KB
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
//
/// \file serial.h
//
// Circle - A C++ bare metal environment for Raspberry Pi
// Copyright (C) 2014-2021 R. Stange <rsta2@o2online.de>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
#ifndef _circle_serial_h
#define _circle_serial_h
#include <circle/device.h>
#include <circle/interrupt.h>
#include <circle/gpiopin.h>
#include <circle/spinlock.h>
#include <circle/sysconfig.h>
#include <circle/types.h>
/// \class CSerialDevice
/// \brief Driver for PL011 UART
///
/// \details GPIO pin mapping (chip numbers)
/// nDevice | TXD | RXD | Support
/// :-----: | :----: | :----: | :------
/// 0 | GPIO14 | GPIO15 | All boards
/// ^ | GPIO32 | GPIO33 | Compute Modules
/// ^ | GPIO36 | GPIO37 | Compute Modules
/// 1 | | | None (AUX)
/// 2 | GPIO0 | GPIO1 | Raspberry Pi 4 only
/// 3 | GPIO4 | GPIO5 | Raspberry Pi 4 only
/// 4 | GPIO8 | GPIO9 | Raspberry Pi 4 only
/// 5 | GPIO12 | GPIO13 | Raspberry Pi 4 only
/// GPIO32/33 and GPIO36/37 can be selected with system option SERIAL_GPIO_SELECT.\n
/// GPIO0/1 are normally reserved for ID EEPROM.\n
/// Handshake lines CTS and RTS are not supported.
#if RASPPI < 4
#define SERIAL_DEVICES 1
#else
#define SERIAL_DEVICES 6
#endif
#define SERIAL_BUF_SIZE 2048 // must be a power of 2
#define SERIAL_BUF_MASK (SERIAL_BUF_SIZE-1)
// serial options
#define SERIAL_OPTION_ONLCR 0 ///< Translate NL to NL+CR on output (default)
// returned from Read/Write as negative value
#define SERIAL_ERROR_BREAK 1
#define SERIAL_ERROR_OVERRUN 2
#define SERIAL_ERROR_FRAMING 3
#define SERIAL_ERROR_PARITY 4
class CSerialDevice : public CDevice
{
public:
enum TParity
{
ParityNone,
ParityOdd,
ParityEven,
ParityUnknown
};
public:
#ifndef USE_RPI_STUB_AT
/// \param pInterruptSystem Pointer to interrupt system object (or 0 for polling driver)
/// \param bUseFIQ Use FIQ instead of IRQ
/// \param nDevice Device number (see: GPIO pin mapping)
CSerialDevice (CInterruptSystem *pInterruptSystem = 0, boolean bUseFIQ = FALSE,
unsigned nDevice = 0);
~CSerialDevice (void);
#endif
/// \param nBaudrate Baud rate in bits per second
/// \param nDataBits Number of data bits (5..8, default 8)
/// \param nStopBits Number of stop bits (1..2, default 1)
/// \param Parity Parity setting (ParityNone (default), ParityOdd or ParityEven)
/// \return Operation successful?
#ifndef USE_RPI_STUB_AT
boolean Initialize (unsigned nBaudrate = 115200,
unsigned nDataBits = 8, unsigned nStopBits = 1,
TParity Parity = ParityNone);
#else
boolean Initialize (unsigned nBaudrate = 115200);
#endif
/// \param pBuffer Pointer to data to be sent
/// \param nCount Number of bytes to be sent
/// \return Number of bytes successfully sent (< 0 on error)
int Write (const void *pBuffer, size_t nCount);
#ifndef USE_RPI_STUB_AT
/// \param pBuffer Pointer to buffer for received data
/// \param nCount Maximum number of bytes to be received
/// \return Number of bytes received (0 no data available, < 0 on error)
int Read (void *pBuffer, size_t nCount);
/// \return Serial options mask (see serial options)
unsigned GetOptions (void) const;
/// \param nOptions Serial options mask (see serial options)
void SetOptions (unsigned nOptions);
typedef void TMagicReceivedHandler (void);
/// \param pMagic String for which is searched in the received data\n
/// (must remain valid after return from this method)
/// \param pHandler Handler which is called, when the magic string is found
/// \note Does only work with interrupt driver.
void RegisterMagicReceivedHandler (const char *pMagic, TMagicReceivedHandler *pHandler);
protected:
/// \return Number of bytes buffer space available for Write()
/// \note Does only work with interrupt driver.
unsigned AvailableForWrite (void);
/// \return Number of bytes already received available for Read()
/// \note Does only work with interrupt driver.
unsigned AvailableForRead (void);
/// \return Next received byte which will be returned by Read() (-1 if no data available)
/// \note Does only work with interrupt driver.
int Peek (void);
/// \brief Waits until all written bytes have been sent out
void Flush (void);
private:
boolean Write (u8 uchChar);
void InterruptHandler (void);
static void InterruptStub (void *pParam);
private:
CInterruptSystem *m_pInterruptSystem;
boolean m_bUseFIQ;
unsigned m_nDevice;
uintptr m_nBaseAddress;
boolean m_bValid;
#if SERIAL_GPIO_SELECT == 14
CGPIOPin m_GPIO32;
CGPIOPin m_GPIO33;
#endif
CGPIOPin m_TxDPin;
CGPIOPin m_RxDPin;
u8 m_RxBuffer[SERIAL_BUF_SIZE];
volatile unsigned m_nRxInPtr;
volatile unsigned m_nRxOutPtr;
volatile int m_nRxStatus;
u8 m_TxBuffer[SERIAL_BUF_SIZE];
volatile unsigned m_nTxInPtr;
volatile unsigned m_nTxOutPtr;
unsigned m_nOptions;
const char *m_pMagic;
const char *m_pMagicPtr;
TMagicReceivedHandler *m_pMagicReceivedHandler;
CSpinLock m_SpinLock;
CSpinLock m_LineSpinLock;
static unsigned s_nInterruptUseCount;
static CInterruptSystem *s_pInterruptSystem;
static boolean s_bUseFIQ;
static volatile u32 s_nInterruptDeviceMask;
static CSerialDevice *s_pThis[SERIAL_DEVICES];
#endif
};
#endif