User | Revision | Line number | New contents of line |
mbed714 |
0:d616ece2d859
|
1
|
|
mbed714 |
0:d616ece2d859
|
2
|
/*
|
mbed714 |
0:d616ece2d859
|
3
|
Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
|
mbed714 |
0:d616ece2d859
|
4
|
|
mbed714 |
0:d616ece2d859
|
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
mbed714 |
0:d616ece2d859
|
6
|
of this software and associated documentation files (the "Software"), to deal
|
mbed714 |
0:d616ece2d859
|
7
|
in the Software without restriction, including without limitation the rights
|
mbed714 |
0:d616ece2d859
|
8
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
mbed714 |
0:d616ece2d859
|
9
|
copies of the Software, and to permit persons to whom the Software is
|
mbed714 |
0:d616ece2d859
|
10
|
furnished to do so, subject to the following conditions:
|
mbed714 |
0:d616ece2d859
|
11
|
|
mbed714 |
0:d616ece2d859
|
12
|
The above copyright notice and this permission notice shall be included in
|
mbed714 |
0:d616ece2d859
|
13
|
all copies or substantial portions of the Software.
|
mbed714 |
0:d616ece2d859
|
14
|
|
mbed714 |
0:d616ece2d859
|
15
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
mbed714 |
0:d616ece2d859
|
16
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
mbed714 |
0:d616ece2d859
|
17
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
mbed714 |
0:d616ece2d859
|
18
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
mbed714 |
0:d616ece2d859
|
19
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
mbed714 |
0:d616ece2d859
|
20
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
mbed714 |
0:d616ece2d859
|
21
|
THE SOFTWARE.
|
mbed714 |
0:d616ece2d859
|
22
|
*/
|
mbed714 |
0:d616ece2d859
|
23
|
|
mbed714 |
0:d616ece2d859
|
24
|
#include "SerialBuf.h"
|
mbed714 |
0:d616ece2d859
|
25
|
#include "mbed.h"
|
mbed714 |
0:d616ece2d859
|
26
|
|
mbed714 |
0:d616ece2d859
|
27
|
//#define __DEBUG
|
mbed714 |
0:d616ece2d859
|
28
|
#include "dbg/dbg.h"
|
mbed714 |
0:d616ece2d859
|
29
|
|
mbed714 |
0:d616ece2d859
|
30
|
#include "netCfg.h"
|
mbed714 |
0:d616ece2d859
|
31
|
#if NET_GPRS
|
mbed714 |
0:d616ece2d859
|
32
|
|
mbed714 |
0:d616ece2d859
|
33
|
#if NET_USB_SERIAL
|
mbed714 |
0:d616ece2d859
|
34
|
#define m_pStream( a ) (m_pSerial?m_pSerial->a:m_pUsbSerial->a)
|
mbed714 |
0:d616ece2d859
|
35
|
#else
|
mbed714 |
0:d616ece2d859
|
36
|
#define m_pStream( a ) (m_pSerial->a)
|
mbed714 |
0:d616ece2d859
|
37
|
#endif
|
mbed714 |
0:d616ece2d859
|
38
|
|
mbed714 |
0:d616ece2d859
|
39
|
//Circular buf
|
mbed714 |
0:d616ece2d859
|
40
|
|
mbed714 |
0:d616ece2d859
|
41
|
SerialCircularBuf::SerialCircularBuf(int len) : m_readMode(false)
|
mbed714 |
0:d616ece2d859
|
42
|
{
|
mbed714 |
0:d616ece2d859
|
43
|
m_buf = new char[len];
|
mbed714 |
0:d616ece2d859
|
44
|
m_len = len;
|
mbed714 |
0:d616ece2d859
|
45
|
m_pReadStart = m_pRead = m_buf;
|
mbed714 |
0:d616ece2d859
|
46
|
m_pWrite = m_buf;
|
mbed714 |
0:d616ece2d859
|
47
|
}
|
mbed714 |
0:d616ece2d859
|
48
|
|
mbed714 |
0:d616ece2d859
|
49
|
SerialCircularBuf::~SerialCircularBuf()
|
mbed714 |
0:d616ece2d859
|
50
|
{
|
mbed714 |
0:d616ece2d859
|
51
|
if(m_buf)
|
mbed714 |
0:d616ece2d859
|
52
|
delete[] m_buf;
|
mbed714 |
0:d616ece2d859
|
53
|
}
|
mbed714 |
0:d616ece2d859
|
54
|
|
mbed714 |
0:d616ece2d859
|
55
|
int SerialCircularBuf::room() //Return room available in buf
|
mbed714 |
0:d616ece2d859
|
56
|
{
|
mbed714 |
0:d616ece2d859
|
57
|
//return m_len - len() - 1; //-1 is to avoid loop
|
mbed714 |
0:d616ece2d859
|
58
|
if ( m_pReadStart > m_pWrite )
|
mbed714 |
0:d616ece2d859
|
59
|
return ( m_pReadStart - m_pWrite - 1 );
|
mbed714 |
0:d616ece2d859
|
60
|
else
|
mbed714 |
0:d616ece2d859
|
61
|
return m_len - ( m_pWrite - m_pReadStart ) - 1;
|
mbed714 |
0:d616ece2d859
|
62
|
}
|
mbed714 |
0:d616ece2d859
|
63
|
|
mbed714 |
0:d616ece2d859
|
64
|
int SerialCircularBuf::len() //Return chars length in buf
|
mbed714 |
0:d616ece2d859
|
65
|
{
|
mbed714 |
0:d616ece2d859
|
66
|
if ( m_pWrite >= m_pRead )
|
mbed714 |
0:d616ece2d859
|
67
|
return ( m_pWrite - m_pRead );
|
mbed714 |
0:d616ece2d859
|
68
|
else
|
mbed714 |
0:d616ece2d859
|
69
|
return m_len - ( m_pRead - m_pWrite ); // = ( ( m_buf + m_len) - m_pRead ) + ( m_pWrite - m_buf )
|
mbed714 |
0:d616ece2d859
|
70
|
}
|
mbed714 |
0:d616ece2d859
|
71
|
|
mbed714 |
0:d616ece2d859
|
72
|
void SerialCircularBuf::write(char c)
|
mbed714 |
0:d616ece2d859
|
73
|
{
|
mbed714 |
0:d616ece2d859
|
74
|
#if 0
|
mbed714 |
0:d616ece2d859
|
75
|
if(!room())
|
mbed714 |
0:d616ece2d859
|
76
|
return;
|
mbed714 |
0:d616ece2d859
|
77
|
#endif
|
mbed714 |
0:d616ece2d859
|
78
|
//WARN: Must call room() before
|
mbed714 |
0:d616ece2d859
|
79
|
*m_pWrite = c;
|
mbed714 |
0:d616ece2d859
|
80
|
m_pWrite++;
|
mbed714 |
0:d616ece2d859
|
81
|
if(m_pWrite>=m_buf+m_len)
|
mbed714 |
0:d616ece2d859
|
82
|
m_pWrite=m_buf;
|
mbed714 |
0:d616ece2d859
|
83
|
}
|
mbed714 |
0:d616ece2d859
|
84
|
char SerialCircularBuf::read()
|
mbed714 |
0:d616ece2d859
|
85
|
{
|
mbed714 |
0:d616ece2d859
|
86
|
#if 0
|
mbed714 |
0:d616ece2d859
|
87
|
if(!len())
|
mbed714 |
0:d616ece2d859
|
88
|
return 0;
|
mbed714 |
0:d616ece2d859
|
89
|
#endif
|
mbed714 |
0:d616ece2d859
|
90
|
//WARN: Must call len() before
|
mbed714 |
0:d616ece2d859
|
91
|
char c = *m_pRead;
|
mbed714 |
0:d616ece2d859
|
92
|
m_pRead++;
|
mbed714 |
0:d616ece2d859
|
93
|
|
mbed714 |
0:d616ece2d859
|
94
|
if(m_pRead>=m_buf+m_len)
|
mbed714 |
0:d616ece2d859
|
95
|
m_pRead=m_buf;
|
mbed714 |
0:d616ece2d859
|
96
|
|
mbed714 |
0:d616ece2d859
|
97
|
if(!m_readMode) //If readmode=false, trash this char
|
mbed714 |
0:d616ece2d859
|
98
|
m_pReadStart=m_pRead;
|
mbed714 |
0:d616ece2d859
|
99
|
|
mbed714 |
0:d616ece2d859
|
100
|
return c;
|
mbed714 |
0:d616ece2d859
|
101
|
}
|
mbed714 |
0:d616ece2d859
|
102
|
|
mbed714 |
0:d616ece2d859
|
103
|
void SerialCircularBuf::setReadMode(bool readMode) //If true, keeps chars in buf when read, false by default
|
mbed714 |
0:d616ece2d859
|
104
|
{
|
mbed714 |
0:d616ece2d859
|
105
|
if(m_readMode == true && readMode == false)
|
mbed714 |
0:d616ece2d859
|
106
|
{
|
mbed714 |
0:d616ece2d859
|
107
|
//Trash bytes that have been read
|
mbed714 |
0:d616ece2d859
|
108
|
flushRead();
|
mbed714 |
0:d616ece2d859
|
109
|
}
|
mbed714 |
0:d616ece2d859
|
110
|
m_readMode = readMode;
|
mbed714 |
0:d616ece2d859
|
111
|
}
|
mbed714 |
0:d616ece2d859
|
112
|
|
mbed714 |
0:d616ece2d859
|
113
|
void SerialCircularBuf::flushRead() //Delete chars that have been read & return chars len (only useful with readMode = true)
|
mbed714 |
0:d616ece2d859
|
114
|
{
|
mbed714 |
0:d616ece2d859
|
115
|
m_pReadStart = m_pRead;
|
mbed714 |
0:d616ece2d859
|
116
|
}
|
mbed714 |
0:d616ece2d859
|
117
|
|
mbed714 |
0:d616ece2d859
|
118
|
void SerialCircularBuf::resetRead() //Go back to initial read position & return chars len (only useful with readMode = true)
|
mbed714 |
0:d616ece2d859
|
119
|
{
|
mbed714 |
0:d616ece2d859
|
120
|
m_pRead = m_pReadStart;
|
mbed714 |
0:d616ece2d859
|
121
|
}
|
mbed714 |
0:d616ece2d859
|
122
|
|
mbed714 |
0:d616ece2d859
|
123
|
//SerialBuf
|
mbed714 |
0:d616ece2d859
|
124
|
|
mbed714 |
0:d616ece2d859
|
125
|
SerialBuf::SerialBuf(int len) : m_rxBuf(len), m_txBuf(len), m_pSerial(NULL) //Buffer length
|
mbed714 |
0:d616ece2d859
|
126
|
#if NET_USB_SERIAL
|
mbed714 |
0:d616ece2d859
|
127
|
, m_pUsbSerial(NULL)
|
mbed714 |
0:d616ece2d859
|
128
|
#endif
|
mbed714 |
0:d616ece2d859
|
129
|
{
|
mbed714 |
0:d616ece2d859
|
130
|
DBG("New Serial buf@%p\n", this);
|
mbed714 |
0:d616ece2d859
|
131
|
}
|
mbed714 |
0:d616ece2d859
|
132
|
|
mbed714 |
0:d616ece2d859
|
133
|
SerialBuf::~SerialBuf()
|
mbed714 |
0:d616ece2d859
|
134
|
{
|
mbed714 |
0:d616ece2d859
|
135
|
|
mbed714 |
0:d616ece2d859
|
136
|
}
|
mbed714 |
0:d616ece2d859
|
137
|
|
mbed714 |
0:d616ece2d859
|
138
|
void SerialBuf::attach(Serial* pSerial)
|
mbed714 |
0:d616ece2d859
|
139
|
{
|
mbed714 |
0:d616ece2d859
|
140
|
DBG("Serial buf@%p in attach\n", this);
|
mbed714 |
0:d616ece2d859
|
141
|
m_pSerial = pSerial;
|
mbed714 |
0:d616ece2d859
|
142
|
m_pSerial->attach<SerialBuf>(this, &SerialBuf::onRxInterrupt, Serial::RxIrq);
|
mbed714 |
0:d616ece2d859
|
143
|
m_pSerial->attach<SerialBuf>(this, &SerialBuf::onTxInterrupt, Serial::TxIrq);
|
mbed714 |
0:d616ece2d859
|
144
|
onRxInterrupt(); //Read data
|
mbed714 |
0:d616ece2d859
|
145
|
}
|
mbed714 |
0:d616ece2d859
|
146
|
|
mbed714 |
0:d616ece2d859
|
147
|
void SerialBuf::detach()
|
mbed714 |
0:d616ece2d859
|
148
|
{
|
mbed714 |
0:d616ece2d859
|
149
|
if(m_pSerial)
|
mbed714 |
0:d616ece2d859
|
150
|
{
|
mbed714 |
0:d616ece2d859
|
151
|
m_pSerial->attach<SerialBuf>(NULL, NULL, Serial::RxIrq);
|
mbed714 |
0:d616ece2d859
|
152
|
m_pSerial->attach<SerialBuf>(NULL, NULL, Serial::TxIrq);
|
mbed714 |
0:d616ece2d859
|
153
|
m_pSerial = NULL;
|
mbed714 |
0:d616ece2d859
|
154
|
}
|
mbed714 |
0:d616ece2d859
|
155
|
#if NET_USB_SERIAL
|
mbed714 |
0:d616ece2d859
|
156
|
else if(m_pUsbSerial)
|
mbed714 |
0:d616ece2d859
|
157
|
{
|
mbed714 |
0:d616ece2d859
|
158
|
m_pUsbSerial->attach<SerialBuf>(NULL, NULL, UsbSerial::RxIrq);
|
mbed714 |
0:d616ece2d859
|
159
|
m_pUsbSerial->attach<SerialBuf>(NULL, NULL, UsbSerial::TxIrq);
|
mbed714 |
0:d616ece2d859
|
160
|
m_pUsbSerial = NULL;
|
mbed714 |
0:d616ece2d859
|
161
|
}
|
mbed714 |
0:d616ece2d859
|
162
|
#endif
|
mbed714 |
0:d616ece2d859
|
163
|
}
|
mbed714 |
0:d616ece2d859
|
164
|
|
mbed714 |
0:d616ece2d859
|
165
|
#if NET_USB_SERIAL
|
mbed714 |
0:d616ece2d859
|
166
|
void SerialBuf::attach(UsbSerial* pUsbSerial)
|
mbed714 |
0:d616ece2d859
|
167
|
{
|
mbed714 |
0:d616ece2d859
|
168
|
m_pUsbSerial = pUsbSerial;
|
mbed714 |
0:d616ece2d859
|
169
|
m_pUsbSerial->attach<SerialBuf>(this, &SerialBuf::onRxInterrupt, UsbSerial::RxIrq);
|
mbed714 |
0:d616ece2d859
|
170
|
m_pUsbSerial->attach<SerialBuf>(this, &SerialBuf::onTxInterrupt, UsbSerial::TxIrq);
|
mbed714 |
0:d616ece2d859
|
171
|
onRxInterrupt(); //Read data
|
mbed714 |
0:d616ece2d859
|
172
|
}
|
mbed714 |
0:d616ece2d859
|
173
|
#endif
|
mbed714 |
0:d616ece2d859
|
174
|
|
mbed714 |
0:d616ece2d859
|
175
|
char SerialBuf::getc()
|
mbed714 |
0:d616ece2d859
|
176
|
{
|
mbed714 |
0:d616ece2d859
|
177
|
while(!readable());
|
mbed714 |
0:d616ece2d859
|
178
|
char c = m_rxBuf.read();
|
mbed714 |
0:d616ece2d859
|
179
|
return c;
|
mbed714 |
0:d616ece2d859
|
180
|
}
|
mbed714 |
0:d616ece2d859
|
181
|
|
mbed714 |
0:d616ece2d859
|
182
|
void SerialBuf::putc(char c)
|
mbed714 |
0:d616ece2d859
|
183
|
{
|
mbed714 |
0:d616ece2d859
|
184
|
while(!writeable());
|
mbed714 |
0:d616ece2d859
|
185
|
m_txBuf.write(c);
|
mbed714 |
0:d616ece2d859
|
186
|
onTxInterrupt();
|
mbed714 |
0:d616ece2d859
|
187
|
}
|
mbed714 |
0:d616ece2d859
|
188
|
|
mbed714 |
0:d616ece2d859
|
189
|
bool SerialBuf::readable()
|
mbed714 |
0:d616ece2d859
|
190
|
{
|
mbed714 |
0:d616ece2d859
|
191
|
if( !m_rxBuf.len() ) //Fill buf if possible
|
mbed714 |
0:d616ece2d859
|
192
|
onRxInterrupt();
|
mbed714 |
0:d616ece2d859
|
193
|
return (m_rxBuf.len() > 0);
|
mbed714 |
0:d616ece2d859
|
194
|
}
|
mbed714 |
0:d616ece2d859
|
195
|
|
mbed714 |
0:d616ece2d859
|
196
|
bool SerialBuf::writeable()
|
mbed714 |
0:d616ece2d859
|
197
|
{
|
mbed714 |
0:d616ece2d859
|
198
|
if( !m_txBuf.room() ) //Free buf is possible
|
mbed714 |
0:d616ece2d859
|
199
|
onTxInterrupt();
|
mbed714 |
0:d616ece2d859
|
200
|
return (m_txBuf.room() > 0);
|
mbed714 |
0:d616ece2d859
|
201
|
}
|
mbed714 |
0:d616ece2d859
|
202
|
|
mbed714 |
0:d616ece2d859
|
203
|
void SerialBuf::setReadMode(bool readMode) //If true, keeps chars in buf when read, false by default
|
mbed714 |
0:d616ece2d859
|
204
|
{
|
mbed714 |
0:d616ece2d859
|
205
|
m_rxBuf.setReadMode(readMode);
|
mbed714 |
0:d616ece2d859
|
206
|
}
|
mbed714 |
0:d616ece2d859
|
207
|
|
mbed714 |
0:d616ece2d859
|
208
|
void SerialBuf::flushRead() //Delete chars that have been read & return chars len (only useful with readMode = true)
|
mbed714 |
0:d616ece2d859
|
209
|
{
|
mbed714 |
0:d616ece2d859
|
210
|
m_rxBuf.flushRead();
|
mbed714 |
0:d616ece2d859
|
211
|
}
|
mbed714 |
0:d616ece2d859
|
212
|
|
mbed714 |
0:d616ece2d859
|
213
|
void SerialBuf::resetRead() //Go back to initial read position & return chars len (only useful with readMode = true)
|
mbed714 |
0:d616ece2d859
|
214
|
{
|
mbed714 |
0:d616ece2d859
|
215
|
m_rxBuf.resetRead();
|
mbed714 |
0:d616ece2d859
|
216
|
}
|
mbed714 |
0:d616ece2d859
|
217
|
|
mbed714 |
0:d616ece2d859
|
218
|
void SerialBuf::onRxInterrupt() //Callback from m_pSerial
|
mbed714 |
0:d616ece2d859
|
219
|
{
|
mbed714 |
0:d616ece2d859
|
220
|
while( m_rxBuf.room() && m_pStream(readable()) )
|
mbed714 |
0:d616ece2d859
|
221
|
{
|
mbed714 |
0:d616ece2d859
|
222
|
m_rxBuf.write(m_pStream(getc()));
|
mbed714 |
0:d616ece2d859
|
223
|
}
|
mbed714 |
0:d616ece2d859
|
224
|
}
|
mbed714 |
0:d616ece2d859
|
225
|
|
mbed714 |
0:d616ece2d859
|
226
|
void SerialBuf::onTxInterrupt() //Callback from m_pSerial
|
mbed714 |
0:d616ece2d859
|
227
|
{
|
mbed714 |
0:d616ece2d859
|
228
|
while( m_txBuf.len() && m_pStream(writeable()) )
|
mbed714 |
0:d616ece2d859
|
229
|
{
|
mbed714 |
0:d616ece2d859
|
230
|
m_pStream(putc(m_txBuf.read()));
|
mbed714 |
0:d616ece2d859
|
231
|
}
|
mbed714 |
0:d616ece2d859
|
232
|
}
|
mbed714 |
0:d616ece2d859
|
233
|
|
mbed714 |
0:d616ece2d859
|
234
|
|
mbed714 |
0:d616ece2d859
|
235
|
#endif
|