COSA
An Object-Oriented Platform for Arduino Programming
Ciao.cpp
Go to the documentation of this file.
1 
21 #include "Ciao.hh"
22 
23 // Ciao configuration
24 static char MAGIC[] = "Cosa::Ciao";
25 static const uint8_t MAJOR = 1;
26 static const uint8_t MINOR = 0;
27 
28 // Ciao header descriptor
29 #if defined(NREFECTION)
30 #define descr_name 0
31 #define magic_name 0
32 #define major_name 0
33 #define minor_name 0
34 #define endian_name 0
35 #else
36 static const char descr_name[] __PROGMEM = "Ciao::header_t";
37 static const char magic_name[] __PROGMEM= "magic";
38 static const char major_name[] __PROGMEM= "major";
39 static const char minor_name[] __PROGMEM= "minor";
40 static const char endian_name[] __PROGMEM = "endian";
41 #endif
42 static const Ciao::Descriptor::member_t descr_members[] __PROGMEM = {
43  {
45  0,
46  magic_name,
47  0
48  },
49  {
51  1,
52  major_name,
53  0
54  },
55  {
57  1,
58  minor_name,
59  0
60  },
61  {
63  1,
64  endian_name,
65  0
66  }
67 };
70  descr_name,
71  descr_members,
72  membersof(descr_members)
73 };
74 
75 void
77 {
78  header_t header;
79  header.magic = MAGIC;
80  header.major = MAJOR;
81  header.minor = MINOR;
82  header.endian = LITTLE_ENDIAN;
83  write(&Descriptor::header_t, &header, 1);
84 }
85 
86 void
87 Ciao::write(char* s)
88 {
89  write(UINT8_TYPE, 0);
90  m_dev->puts(s);
91  m_dev->putchar(0);
92 }
93 
94 void
96 {
97  write(UINT8_TYPE, 0);
98  m_dev->puts(buf);
99  m_dev->putchar(0);
100 }
101 
102 void
103 Ciao::write(uint8_t value)
104 {
105  write(UINT8_TYPE, 1);
106  m_dev->putchar(value);
107 }
108 
109 void
110 Ciao::write(uint8_t* buf, uint16_t count)
111 {
112  write(UINT8_TYPE, count);
113  m_dev->write(buf, count * sizeof(uint8_t));
114 }
115 
116 void
117 Ciao::write(uint16_t value)
118 {
119  write(UINT16_TYPE, 1);
120  m_dev->write(&value, sizeof(value));
121 }
122 
123 void
124 Ciao::write(uint16_t* buf, uint16_t count)
125 {
126  write(UINT16_TYPE, count);
127  m_dev->write(buf, count * sizeof(uint16_t));
128 }
129 
130 void
131 Ciao::write(uint32_t value)
132 {
133  write(UINT32_TYPE, 1);
134  m_dev->write(&value, sizeof(value));
135 }
136 
137 void
138 Ciao::write(uint32_t* buf, uint16_t count)
139 {
140  write(UINT32_TYPE, count);
141  m_dev->write(buf, count * sizeof(uint32_t));
142 }
143 
144 void
145 Ciao::write(uint64_t value)
146 {
147  write(UINT64_TYPE, 1);
148  m_dev->write(&value, sizeof(value));
149 }
150 
151 void
152 Ciao::write(uint64_t* buf, uint16_t count)
153 {
154  write(UINT64_TYPE, count);
155  m_dev->write(buf, count * sizeof(uint32_t));
156 }
157 
158 void
159 Ciao::write(int8_t value)
160 {
161  write(INT8_TYPE, 1);
162  m_dev->putchar(value);
163 }
164 
165 void
166 Ciao::write(int8_t* buf, uint16_t count)
167 {
168  write(INT8_TYPE, count);
169  m_dev->write(buf, count * sizeof(int8_t));
170 }
171 
172 void
173 Ciao::write(int16_t value)
174 {
175  write(INT16_TYPE, 1);
176  m_dev->write(&value, sizeof(value));
177 }
178 
179 void Ciao::write(int16_t* buf, uint16_t count)
180 {
181  write(INT16_TYPE, count);
182  m_dev->write(buf, count * sizeof(int16_t));
183 }
184 
185 void
186 Ciao::write(int32_t value)
187 {
188  write(INT32_TYPE, 1);
189  m_dev->write(&value, sizeof(value));
190 }
191 
192 void
193 Ciao::write(int32_t* buf, uint16_t count)
194 {
195  write(INT32_TYPE, count);
196  m_dev->write(buf, count * sizeof(int32_t));
197 }
198 
199 void
200 Ciao::write(int64_t value)
201 {
202  write(INT64_TYPE, 1);
203  m_dev->write(&value, sizeof(value));
204 }
205 
206 void
207 Ciao::write(int64_t* buf, uint16_t count)
208 {
209  write(INT64_TYPE, count);
210  m_dev->write(buf, count * sizeof(int32_t));
211 }
212 
213 void
214 Ciao::write(float value)
215 {
216  write(FLOAT32_TYPE, 1);
217  m_dev->write(&value, sizeof(value));
218 }
219 
220 void
221 Ciao::write(float* buf, uint16_t count)
222 {
223  write(FLOAT32_TYPE, count);
224  m_dev->write(buf, count * sizeof(float));
225 }
226 
227 void
228 Ciao::write(uint8_t type, uint16_t count)
229 {
230  // Tag byte contains count[0..7]
231  if (count < 8) {
232  count |= type;
233  }
234 
235  // Else tag byte contains marker. Succeeding byte counter[8..255]
236  else if (count < 256) {
237  m_dev->putchar(type | COUNT8_ATTR);
238  }
239 
240  // Else tag byte contains marker. Succeeding two bytes counter[256..64K]
241  else {
242  m_dev->putchar(type | COUNT16_ATTR);
243  m_dev->putchar(count >> 8);
244  }
245 
246  m_dev->putchar(count);
247 }
248 
249 void
251 {
252  // Read descriptor from program memory
254  memcpy_P(&d, desc, sizeof(d));
255 
256  // Write descriptor start tag and identity number (8 or 16-bit)
257  if (d.id < 256) {
259  }
260  else {
262  m_dev->putchar(d.id >> 8);
263  }
264  m_dev->putchar(d.id);
265 
266  // Write descriptor null terminated name null
267  m_dev->puts((str_P) d.name);
268  m_dev->putchar(0);
269 
270  // Write members with name null terminated
271  const Descriptor::member_t* mp = d.member;
272  for (uint16_t i = 0; i < d.count; i++) {
274  memcpy_P(&m, mp++, sizeof(m));
275  write(m.type, m.count);
276  m_dev->puts((str_P) m.name);
277  m_dev->putchar(0);
278  }
279 
280  // Write descriptor end tag
282 }
283 
284 static const uint8_t sizeoftype[] __PROGMEM = {
285  sizeof(uint8_t),
286  sizeof(uint16_t),
287  sizeof(uint32_t),
288  sizeof(uint64_t),
289  0,
290  0,
291  0,
292  0,
293  sizeof(int8_t),
294  sizeof(int16_t),
295  sizeof(int32_t),
296  sizeof(int64_t),
297  0,
298  sizeof(float32_t),
299  0,
300  0
301 };
302 
303 void
304 Ciao::write(const Descriptor::user_t* desc, void* buf, uint16_t count)
305 {
306  // Read descriptor from program memory
308  memcpy_P(&d, desc, sizeof(d));
309 
310  // Write type tag for user data with count and type identity
311  if (d.id < 256) {
312  write(USER8_TYPE, count);
313  }
314  else {
315  write(USER16_TYPE, count);
316  m_dev->putchar(d.id >> 8);
317  }
318  m_dev->putchar(d.id);
319 
320  // Write data buffer to stream
321  uint8_t* dp = (uint8_t*) buf;
322  while (count--) {
323  const Descriptor::member_t* mp = d.member;
324  for (uint16_t i = 0; i < d.count; i++) {
326  memcpy_P(&m, mp++, sizeof(m));
327  // Allow strings and data elements vectors only
328  // Fix: Add table with user defined types
329  if (m.count == 0 && m.type == UINT8_TYPE) {
330  uint8_t* sp = *((uint8_t**) dp);
331  uint8_t d;
332  do {
333  d = *sp++;
334  m_dev->putchar(d);
335  } while (d != 0);
336  dp += sizeof(sp);
337  }
338  else {
339  size_t s = pgm_read_byte(&sizeoftype[m.type >> 4]) * m.count;
340  if (s == 0) return;
341  m_dev->write(dp, s);
342  dp += s;
343  }
344  }
345  }
346 }
void begin()
Definition: Ciao.cpp:76
uint8_t major
Definition: Ciao.hh:124
virtual int putchar(char c)
virtual int puts(const char *s)
static const char descr_name[] __PROGMEM
Definition: Ciao.cpp:36
float float32_t
Definition: Types.h:107
void write(char *s)
Definition: Ciao.cpp:87
virtual int write(const void *buf, size_t size)
const char * name
Definition: Ciao.hh:111
const char * name
Definition: Ciao.hh:106
static char MAGIC[]
Definition: Ciao.cpp:24
char * magic
Definition: Ciao.hh:123
#define membersof(x)
Definition: Types.h:165
static const uint8_t MINOR
Definition: Ciao.cpp:26
const class prog_str * str_P
Definition: Types.h:187
uint8_t minor
Definition: Ciao.hh:125
static const uint8_t MAJOR
Definition: Ciao.cpp:25
IOStream::Device * m_dev
Definition: Ciao.hh:307
uint8_t endian
Definition: Ciao.hh:126
const member_t * member
Definition: Ciao.hh:112
Ciao header descriptor (8-bit, 1-15).
Definition: Ciao.hh:99
static const user_t header_t
Definition: Ciao.hh:115