COSA
An Object-Oriented Platform for Arduino Programming
Types.h
Go to the documentation of this file.
1 
24 #ifndef COSA_TYPES_H
25 #define COSA_TYPES_H
26 
27 #include <avr/io.h>
28 #include <avr/sleep.h>
29 #include <avr/eeprom.h>
30 #include <avr/interrupt.h>
31 #include <avr/pgmspace.h>
32 #include <avr/sfr_defs.h>
33 #include <util/delay_basic.h>
34 
35 #include <stdarg.h>
36 #include <stdint.h>
37 #include <stdlib.h>
38 #include <string.h>
39 
40 #include "Cosa/Errno.h"
41 #include "Cosa/Board.hh"
42 #include "Cosa.h"
43 
47 #define __UNIQUE(name) __CONCAT(name,__LINE__)
48 
52 #define ROUND(x,y) (((x) + (y - 1)) / (y))
53 
57 #define CHARBITS 8
58 
62 #define BYTES(bits) ROUND(bits, CHARBITS)
63 
67 #ifndef UINT8_MAX
68 # define UINT8_MAX ((uin8_t) 0xffU)
69 #endif
70 #ifndef UINT16_MAX
71 # define UINT16_MAX ((uint16_t) 0xffffU)
72 #endif
73 #ifndef UINT32_MAX
74 # define UINT32_MAX ((uint32_t) 0xffffffffUL)
75 #endif
76 #ifndef INT_MAX
77 # define INT_MIN INT16_MIN
78 # define INT_MAX INT16_MAX
79 #endif
80 #ifndef INT8_MAX
81 # define INT8_MIN ((int8_t) 0x80)
82 # define INT8_MAX ((int8_t) 0x7f)
83 #endif
84 #ifndef INT16_MAX
85 # define INT16_MIN ((int16_t) 0x8000)
86 # define INT16_MAX ((int16_t) 0x7fff)
87 #endif
88 #ifndef INT32_MAX
89 # define INT32_MIN ((int32_t) 0x80000000L)
90 # define INT32_MAX ((int32_t) 0x7fffffffL)
91 #endif
92 #ifndef INT_MAX
93 # define INT_MIN INT16_MIN
94 # define INT_MAX INT16_MAX
95 #endif
96 
100 #ifndef NULL
101 # define NULL ((void*) 0)
102 #endif
103 
107 typedef float float32_t;
108 
112 union univ16_t {
113  uint16_t as_uint16;
114  int16_t as_int16;
115  uint8_t as_uint8[2];
116  int8_t as_int8[2];
117  const void* as_ptr_P;
118  void* as_ptr;
119  struct {
120  uint8_t low;
121  uint8_t high;
122  };
123 };
124 typedef univ16_t univ_t;
125 
129 union univ32_t {
131  uint32_t as_uint32;
132  int32_t as_int32;
133  univ16_t as_univ16[2];
134  uint16_t as_uint16[2];
135  int16_t as_int16[2];
136  uint8_t as_uint8[4];
137  int8_t as_int8[4];
138  const void* as_ptr_P[2];
139  void* as_ptr[2];
140  struct {
141  uint16_t low;
142  uint16_t high;
143  };
144 };
145 
152 #define LIKELY(x) __builtin_expect((x), true)
153 #define UNLIKELY(x) __builtin_expect((x), false)
154 
158 #define UNUSED(x) (void) (x)
159 
165 #define membersof(x) (sizeof(x) / sizeof(x[0]))
166 
167 /*
168  * Workaround for gcc offsetof macro usage and program memory data
169  * warning in Arduino build with older version of AVR-GCC (1.0.5,
170  * 1.5.6-r2 etc).
171  */
172 #if ((__GNUC__ == 4) && (__GNUC_MINOR__ <= 3))
173 # undef offsetof
174 # define offsetof(t,m) \
175  (__extension__( \
176  { \
177  const t* __p = NULL; \
178  (size_t) &__p->m; \
179  } \
180  ))
181 # define __PROGMEM __attribute__((section(".progmem.data")))
182 #else
183 # define __PROGMEM PROGMEM
184 #endif
185 
187 typedef const PROGMEM class prog_str* str_P;
188 
194 #define STR_P(s) \
195  (__extension__( \
196  { \
197  static const char __c[] __PROGMEM = (s); \
198  (str_P) &__c[0]; \
199  } \
200  ))
201 #undef PSTR
202 #define PSTR(s) STR_P(s)
203 #define __PSTR(s) STR_P(s)
204 
205 inline char*
206 strcat_P(char* s1, str_P s2)
207 {
208  return (strcat_P(s1, (const char*) s2));
209 }
210 
211 inline str_P
212 strchr_P(str_P s, int __val)
213 {
214  return ((str_P) strchr_P((const char*) s, __val));
215 }
216 
217 inline str_P
218 strchrnul_P(str_P s, int __val)
219 {
220  return ((str_P) strchrnul_P((const char*) s, __val));
221 }
222 
223 inline int
224 strcmp_P(const char *s1, str_P s2)
225 {
226  return (strcmp_P(s1, (const char*) s2));
227 }
228 
229 inline int
230 strncmp_P(const char *s1, str_P s2, size_t n)
231 {
232  return (strncmp_P(s1, (const char*) s2, n));
233 }
234 
235 inline char*
236 strcpy_P(char* s1, str_P s2)
237 {
238  return (strcpy_P(s1, (const char*) s2));
239 }
240 
241 inline int
242 strcasecmp_P(const char *s1, str_P s2)
243 {
244  return (strcasecmp_P(s1, (const char*) s2));
245 }
246 
247 inline char*
248 strcasestr_P(const char *s1, str_P s2)
249 {
250  return (strcasestr_P(s1, (const char*) s2));
251 }
252 
253 inline size_t
255 {
256  return (strlen_P((const char*) s));
257 }
258 
260 typedef const PROGMEM void* void_P;
261 typedef const PROGMEM void_P void_vec_P;
262 
263 /* Check if static_assert needs to be disabled */
264 #if (ARDUINO < 150)
265 # if !defined(__GXX_EXPERIMENTAL_CXX0X__)
266 # define static_assert(condition,message)
267 # endif
268 #endif
269 
274 #define I_CPU (F_CPU / 1000000L)
275 
280 #define DELAY(us) _delay_loop_2((us) * (F_CPU / 4000000L))
281 
287 extern void (*delay)(uint32_t ms);
288 
294 extern void (*sleep)(uint16_t s);
295 
300 extern void (*yield)();
301 
305 #define nop() __asm__ __volatile__("nop")
306 
312 #define barrier() __asm__ __volatile__("" ::: "memory")
313 
318 inline uint8_t lock() __attribute__((always_inline));
319 inline uint8_t lock()
320 {
321  uint8_t key = SREG;
322  __asm__ __volatile__("cli" ::: "memory");
323  return (key);
324 }
325 
330 inline void unlock(uint8_t key) __attribute__((always_inline));
331 inline void unlock(uint8_t key)
332 {
333  SREG = key;
334  __asm__ __volatile__("" ::: "memory");
335 }
336 
342 inline void __unlock(uint8_t* key) __attribute__((always_inline));
343 inline void __unlock(uint8_t* key)
344 {
345  SREG = *key;
346  __asm__ __volatile__("" ::: "memory");
347 }
348 
360 #define synchronized \
361  for (uint8_t __key __attribute__((__cleanup__(__unlock))) = lock(), \
362  i = 1; i != 0; i--)
363 
367 typedef volatile bool condvar_t;
368 
375 inline uint8_t lock(condvar_t &cond) __attribute__((always_inline));
376 inline uint8_t lock(condvar_t &cond)
377 {
378  uint8_t key = lock();
379  while (UNLIKELY(cond)) {
380  unlock(key);
381  yield();
382  key = lock();
383  }
384  cond = true;
385  return (key);
386 }
387 
391 struct iovec_t {
392  void* buf;
393  size_t size;
394  iovec_t(void* buf = NULL, size_t size = 0)
395  {
396  this->buf = buf;
397  this->size = size;
398  }
399 };
400 
406 inline size_t iovec_size(const iovec_t* vec) __attribute__((always_inline));
407 inline size_t iovec_size(const iovec_t* vec)
408 {
409  size_t len = 0;
410  for (const iovec_t* vp = vec; vp->buf != NULL; vp++)
411  len += vp->size;
412  return (len);
413 }
414 
428 inline void iovec_arg(iovec_t* &vp, const void* buf, size_t size)
429  __attribute__((always_inline));
430 inline void iovec_arg(iovec_t* &vp, const void* buf, size_t size)
431 {
432  vp->buf = (void*) buf;
433  vp->size = size;
434  vp++;
435 }
436 
448 inline void iovec_end(iovec_t* &vp) __attribute__((always_inline));
449 inline void iovec_end(iovec_t* &vp)
450 {
451  vp->buf = 0;
452  vp->size = 0;
453 }
454 
460 inline uint16_t swap(uint16_t value) __attribute__((always_inline));
461 inline uint16_t swap(uint16_t value)
462 {
463  asm volatile("mov __tmp_reg__, %A0" "\n\t"
464  "mov %A0, %B0" "\n\t"
465  "mov %B0, __tmp_reg__" "\n\t"
466  : "=r" (value)
467  : "0" (value)
468  );
469  return (value);
470 }
471 
478 inline void swap(uint16_t* dest, const uint16_t* src, size_t size)
479 {
480  if (UNLIKELY(size == 0)) return;
481  do {
482  *dest++ = swap(*src++);
483  } while (--size);
484 }
485 
492 template<class T>
493 void swap(T* dest, const T* src)
494 {
495  swap((uint16_t*) dest, (const uint16_t*) src, sizeof(T) / sizeof(uint16_t));
496 }
497 
503 inline void swap(uint16_t* buf, size_t size)
504 {
505  if (UNLIKELY(size == 0)) return;
506  do {
507  int16_t data = *buf;
508  *buf++ = swap(data);
509  } while (--size);
510 }
511 
517 template<class T>
518 void swap(T* buf)
519 {
520  swap((uint16_t*) buf, sizeof(T) / sizeof(uint16_t));
521 }
522 
528 inline int16_t swap(int16_t value) __attribute__((always_inline));
529 inline int16_t swap(int16_t value)
530 {
531  return ((int16_t) swap((uint16_t) value));
532 }
533 
540 inline void swap(int16_t* dest, const int16_t* src, size_t size)
541 {
542  if (UNLIKELY(size == 0)) return;
543  do {
544  *dest++ = swap(*src++);
545  } while (--size);
546 }
547 
553 inline uint32_t swap(uint32_t value) __attribute__((always_inline));
554 inline uint32_t swap(uint32_t value)
555 {
556  asm volatile("mov __tmp_reg__, %A0" "\n\t"
557  "mov %A0, %D0" "\n\t"
558  "mov %D0, __tmp_reg__" "\n\t"
559  "mov __tmp_reg__, %B0" "\n\t"
560  "mov %B0, %C0" "\n\t"
561  "mov %C0, __tmp_reg__" "\n\t"
562  : "=r" (value)
563  : "0" (value)
564  );
565  return (value);
566 }
567 
573 inline int32_t swap(int32_t value) __attribute__((always_inline));
574 inline int32_t swap(int32_t value)
575 {
576  return ((int32_t) swap((uint32_t) value));
577 }
578 
583 #define ntoh swap
584 #define hton swap
585 
591 inline char tohex(uint8_t value) __attribute__((always_inline));
592 inline char tohex(uint8_t value)
593 {
594  value &= 0xf;
595  if (UNLIKELY(value > 9))
596  return (value - 10 + 'a');
597  return (value + '0');
598 }
599 
605 inline char toHEX(uint8_t value) __attribute__((always_inline));
606 inline char toHEX(uint8_t value)
607 {
608  value &= 0xf;
609  if (UNLIKELY(value > 9))
610  return (value - 10 + 'A');
611  return (value + '0');
612 }
613 
614 #endif
volatile bool condvar_t
Definition: Types.h:367
int strncmp_P(const char *s1, str_P s2, size_t n)
Definition: Types.h:230
uint8_t as_uint8[2]
Definition: Types.h:115
float float32_t
Definition: Types.h:107
float32_t as_float32
Definition: Types.h:130
uint8_t high
Definition: Types.h:121
uint16_t swap(uint16_t value)
Definition: Types.h:461
#define NULL
Definition: Types.h:101
iovec_t(void *buf=NULL, size_t size=0)
Definition: Types.h:394
const void_P void_vec_P
Definition: Types.h:261
Definition: Types.h:391
int32_t as_int32
Definition: Types.h:132
uint8_t lock()
Definition: Types.h:319
void(* delay)(uint32_t ms)
const class prog_str * str_P
Definition: Types.h:187
univ16_t univ_t
Definition: Types.h:124
size_t size
Size of buffer in bytes.
Definition: Types.h:393
int16_t as_int16
Definition: Types.h:114
uint32_t as_uint32
Definition: Types.h:131
char * strcasestr_P(const char *s1, str_P s2)
Definition: Types.h:248
int strcasecmp_P(const char *s1, str_P s2)
Definition: Types.h:242
char toHEX(uint8_t value)
Definition: Types.h:606
void(* yield)()
void * buf
Buffer pointer.
Definition: Types.h:392
char * strcpy_P(char *s1, str_P s2)
Definition: Types.h:236
str_P strchr_P(str_P s, int __val)
Definition: Types.h:212
void __unlock(uint8_t *key)
Definition: Types.h:343
void(* sleep)(uint16_t s)
char tohex(uint8_t value)
Definition: Types.h:592
void * as_ptr
Definition: Types.h:118
char * strcat_P(char *s1, str_P s2)
Definition: Types.h:206
uint16_t as_uint16
Definition: Types.h:113
void unlock(uint8_t key)
Definition: Types.h:331
uint16_t low
Definition: Types.h:141
const void * as_ptr_P
Definition: Types.h:117
const void * void_P
Definition: Types.h:260
uint16_t high
Definition: Types.h:142
#define UNLIKELY(x)
Definition: Types.h:153
uint8_t low
Definition: Types.h:120
size_t strlen_P(str_P s)
Definition: Types.h:254
str_P strchrnul_P(str_P s, int __val)
Definition: Types.h:218
int8_t as_int8[2]
Definition: Types.h:116
void iovec_arg(iovec_t *&vp, const void *buf, size_t size)
Definition: Types.h:430
void iovec_end(iovec_t *&vp)
Definition: Types.h:449
size_t iovec_size(const iovec_t *vec)
Definition: Types.h:407
int strcmp_P(const char *s1, str_P s2)
Definition: Types.h:224