/elec/propeller-clock

To get this branch, use:
bzr branch http://bzr.ed.am/elec/propeller-clock
57 by edam
added ulibc
1
/*
2
 * serstream
3
 * Implementation of input/output streams for the Arduino serial classes
4
 *
5
 *  Created on: 2 Jan 2011
6
 *      Author: Andy Brown
7
 *
8
 *  http://andybrown.me.uk/ws/terms-and-conditions
9
 */
10
11
#ifndef __810370EC_AD69_4ef7_91F5_B1AA16F14712
12
#define __810370EC_AD69_4ef7_91F5_B1AA16F14712
13
14
#include <basic_definitions>
15
16
//#include <stl_config.h>
17
#include <iosfwd>
18
#include <ios>
19
#include <istream>
20
#include <ostream>
21
#include <iostream>
22
#include <HardwareSerial.h>
23
24
25
namespace std
26
{
27
/*
28
 * basic_serialbuf implements an unbuffered basic_streambuf as a backing buffer
29
 * for the IO classes
30
 */
31
 
32
	template <class charT, class traits, class Tserial>
33
		class basic_serialbuf : public basic_streambuf<charT,traits>
34
	{
35
	public:
36
37
	/*
38
	 * Types used here
39
	 */
40
41
		typedef charT char_type;
42
		typedef typename traits::int_type int_type;
43
44
	/*
45
	 * constructor - wraps an existing Tserial class instance
46
	 */
47
48
		explicit basic_serialbuf(Tserial& serial_,ios_base::openmode which_ = ios_base::in | ios_base::out)
49
			: _serial(serial_)
50
		{
51
			basic_streambuf<charT,traits>::openedFor = which_;
52
		}
53
54
	/*
55
	 * Required to maintain the chain
56
	 */
57
58
		virtual ~basic_serialbuf() { }
59
60
	/*
61
	 * Get a reference to the wrapped object
62
	 */
63
64
		Tserial& serial() { return _serial; }
65
66
	protected:
67
		
68
	/*
69
	 * Get how many bytes available
70
	 */
71
72
		virtual int showmanyc(){
73
			return _serial.available();
74
		}
75
		
76
	/*
77
	 * Read up to n chars
78
	 */
79
80
		virtual streamsize xsgetn(char_type* c, streamsize n) {
81
		
82
			streamsize i = 0;
83
			char_type data;
84
			
85
			while((data=_serial.read())!=-1 && i < n ) {
86
				c[i] = data;
87
				++i;
88
			}
89
			return i;
90
		}
91
92
	/*
93
	 * Write up to n chars
94
	 */
95
96
		virtual streamsize xsputn(const char_type* s, streamsize n){
97
			
98
			//_serial.print("[PUT ");
99
			//_serial.print(n);
100
			//_serial.print("] ");
101
			for(streamsize i=0;i<n;i++)
102
			{
103
				char_type c = s[i];
104
				if ( c == '\n' )
105
					_serial.print('\r');
106
				_serial.print(c);
107
			}
108
109
			return n;
110
		}
111
112
	/*
113
	 * write a single char
114
	 */
115
116
		virtual int_type overflow (int_type c = traits::eof()) {
117
			if(!traits::eq_int_type(c,traits::eof()))
118
			{
119
				//_serial.print("[OF]");
120
				if ( (char_type)c == '\n' )
121
					_serial.print('\r');
122
				_serial.print((char_type)c);
123
			}
124
			return traits::not_eof(c);
125
		}
126
127
		
128
	/*
129
	 * peek at a char where possible
130
	 */
131
132
		virtual int_type underflow(){
133
			if(_serial.available())
134
				return _serial.peek();
135
			else 
136
				return traits::eof();
137
		}
138
139
	/*
140
	 * Read a char where possible
141
	 */
142
143
		virtual int_type uflow(){
144
			if(_serial.available())
145
				return _serial.read();
146
			else 
147
				return traits::eof();
148
		}
149
150
	/*
151
	 * Our wrapped arduino class
152
	 */
153
154
		Tserial& _serial;
155
	};
156
157
158
/*
159
 * Input stream
160
 */
161
162
	template <class charT, class traits, class Tserial> class basic_iserialstream
163
		: public basic_istream<charT,traits>
164
	{
165
	public:
166
167
	/*
168
	 * Types used here
169
	 */
170
171
		typedef charT char_type;
172
173
	/*
174
	 * Constructor - default the serial object to #1
175
	 * Mega users can explicity initialise with one of
176
	 * the others
177
	 */
178
179
		explicit basic_iserialstream(Tserial& serial_)
180
			: basic_ios<charT, traits>(&sb), basic_istream<charT,traits>(&sb), sb(serial_,ios_base::in)
181
		{
182
		}
183
184
	/*
185
	 * Required to maintain the chain
186
	 */
187
188
		virtual ~basic_iserialstream() {  }
189
		
190
	/*
191
	 * Initialise the baud rate
192
	 */
193
194
		void begin(long speed_) {
195
			sb.serial().begin(speed_);
196
			sb.serial().println(__FUNCTION__);
197
		}
198
		
199
	/*
200
	 * The wrapped object
201
	 */
202
203
	private:
204
		basic_serialbuf<charT,traits,Tserial> sb;
205
	};
206
207
208
/*
209
 * Output stream
210
 */
211
212
	template <class charT, class traits, class Tserial> class basic_oserialstream
213
		: public basic_ostream<charT,traits>
214
	{
215
	public:
216
217
	/*
218
	 * Types used here
219
	 */
220
221
		typedef charT char_type;
222
223
		/*
224
		 * Constructor - default the serial object to #1
225
		 * Mega users can explicity initialise with one of
226
		 * the others
227
		 */
228
229
		explicit basic_oserialstream(Tserial& serial_)
230
			: basic_ios<charT, traits>(&sb), basic_ostream<charT,traits>(&sb), sb(serial_,ios_base::out)
231
		{
232
		}
233
		
234
		/*
235
		 * Required to maintain the chain
236
		 */
237
238
		virtual ~basic_oserialstream() {  }
239
240
		/*
241
		 * Initialise the baud rate
242
		 */
243
244
		void begin(long speed_) {
245
			sb.serial().begin(speed_);
246
		}
247
		
248
	/*
249
	 * The wrapped object
250
	 */
251
252
	private:
253
		basic_serialbuf<charT,traits,Tserial> sb;
254
	};
255
256
257
/*
258
 * Input/output stream
259
 */
260
261
	template <class charT, class traits, class Tserial> class basic_ioserialstream
262
		 : public basic_iostream<charT,traits>
263
	{
264
	public:
265
266
	/*
267
	 * Types used here
268
	 */
269
270
		typedef charT char_type;
271
272
		/*
273
		 * Constructor - default the serial object to #1
274
		 * Mega users can explicity initialise with one of
275
		 * the others
276
		 */
277
278
		explicit basic_ioserialstream(Tserial& serial_)
279
			: basic_ios<charT, traits>(&sb), basic_iostream<charT,traits>(&sb), sb(serial_,ios_base::in | ios_base::out)
280
		{
281
		}
282
283
		/*
284
		 * Required to maintain the chain
285
		 */
286
287
		virtual ~basic_ioserialstream(){  }
288
289
		/*
290
		 * Initialise the baud rate
291
		 */
292
293
		void begin(long speed_) {
294
			sb.serial().begin(speed_);
295
		}
296
		
297
	/*
298
	 * The wrapped object
299
	 */
300
301
	private:
302
		basic_serialbuf<charT, traits, Tserial> sb;
303
	};
304
305
306
307
}
308
309
#endif