Add a bunch of APNs

Fork of C027_Support by Xinlei Cao

Committer:
mazgch
Date:
Fri May 16 14:13:00 2014 +0000
Revision:
75:ce6e12067d0c
Parent:
74:208e3e32d263
Child:
95:8282dbbe1492
minor tweaks

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mazgch 0:cb2d45baaca3 1 #pragma once
mazgch 75:ce6e12067d0c 2 #include "Relax.h"
mazgch 0:cb2d45baaca3 3
mazgch 40:295099ff5338 4 /** pipe, this class implements a buffered pipe that can be savely
mazgch 40:295099ff5338 5 written and read between two context. E.g. Written from a task
mazgch 40:295099ff5338 6 and read from a interrupt.
mazgch 40:295099ff5338 7 */
mazgch 0:cb2d45baaca3 8 template <class T>
mazgch 0:cb2d45baaca3 9 class Pipe
mazgch 0:cb2d45baaca3 10 {
mazgch 0:cb2d45baaca3 11 public:
mazgch 40:295099ff5338 12 /* Constructor
mazgch 40:295099ff5338 13 \param n size of the pipe/buffer
mazgch 40:295099ff5338 14 \param b optional buffer that should be used.
mazgch 40:295099ff5338 15 if NULL the constructor will allocate a buffer of size n.
mazgch 40:295099ff5338 16 */
mazgch 9:e7a5959ffae1 17 Pipe(int n, T* b = NULL)
mazgch 0:cb2d45baaca3 18 {
mazgch 74:208e3e32d263 19 _a = b ? NULL : n ? new T[n] : NULL;
mazgch 9:e7a5959ffae1 20 _r = 0;
mazgch 9:e7a5959ffae1 21 _w = 0;
mazgch 9:e7a5959ffae1 22 _b = b ? b : _a;
mazgch 9:e7a5959ffae1 23 _s = n;
mazgch 0:cb2d45baaca3 24 }
mazgch 40:295099ff5338 25 /** Destructor
mazgch 40:295099ff5338 26 frees a allocated buffer.
mazgch 40:295099ff5338 27 */
mazgch 41:b94a1f410e71 28 ~Pipe(void)
mazgch 0:cb2d45baaca3 29 {
mazgch 9:e7a5959ffae1 30 if (_a)
mazgch 9:e7a5959ffae1 31 delete [] _a;
mazgch 0:cb2d45baaca3 32 }
mazgch 40:295099ff5338 33
mazgch 40:295099ff5338 34 /* This function can be used during debugging to hexdump the
mazgch 40:295099ff5338 35 content of a buffer to the stdout.
mazgch 40:295099ff5338 36 */
mazgch 21:c4d64830bf02 37 void dump(void)
mazgch 21:c4d64830bf02 38 {
mazgch 21:c4d64830bf02 39 int o = _r;
mazgch 21:c4d64830bf02 40 printf("pipe: %d/%d ", size(), _s);
mazgch 21:c4d64830bf02 41 while (o != _w) {
mazgch 21:c4d64830bf02 42 T t = _b[o];
mazgch 21:c4d64830bf02 43 printf("%0*X", sizeof(T)*2, t);
mazgch 21:c4d64830bf02 44 o = _inc(o);
mazgch 21:c4d64830bf02 45 }
mazgch 21:c4d64830bf02 46 printf("\n");
mazgch 21:c4d64830bf02 47 }
mazgch 40:295099ff5338 48
mazgch 40:295099ff5338 49 // writing thread/context API
mazgch 40:295099ff5338 50 //-------------------------------------------------------------
mazgch 40:295099ff5338 51
mazgch 40:295099ff5338 52 /** Check if buffer is writeable (=not full)
mazgch 40:295099ff5338 53 \return true if writeable
mazgch 40:295099ff5338 54 */
mazgch 40:295099ff5338 55 bool writeable(void)
mazgch 0:cb2d45baaca3 56 {
mazgch 9:e7a5959ffae1 57 return free() > 0;
mazgch 0:cb2d45baaca3 58 }
mazgch 40:295099ff5338 59
mazgch 40:295099ff5338 60 /** Return the number of free elements in the buffer
mazgch 40:295099ff5338 61 \return the number of free elements
mazgch 40:295099ff5338 62 */
mazgch 40:295099ff5338 63 int free(void)
mazgch 0:cb2d45baaca3 64 {
mazgch 9:e7a5959ffae1 65 int s = _r - _w;
mazgch 9:e7a5959ffae1 66 if (s <= 0)
mazgch 9:e7a5959ffae1 67 s += _s;
mazgch 9:e7a5959ffae1 68 return s - 1;
mazgch 0:cb2d45baaca3 69 }
mazgch 40:295099ff5338 70
mazgch 40:295099ff5338 71 /* Add a single element to the buffer. (blocking)
mazgch 40:295099ff5338 72 \param c the element to add.
mazgch 40:295099ff5338 73 \return c
mazgch 40:295099ff5338 74 */
mazgch 13:e2446fcdc246 75 T putc(T c)
mazgch 0:cb2d45baaca3 76 {
mazgch 9:e7a5959ffae1 77 int i = _w;
mazgch 0:cb2d45baaca3 78 int j = i;
mazgch 0:cb2d45baaca3 79 i = _inc(i);
mazgch 9:e7a5959ffae1 80 while (i == _r) // = !writeable()
mazgch 75:ce6e12067d0c 81 RELAX_MS(0);
mazgch 9:e7a5959ffae1 82 _b[j] = c;
mazgch 13:e2446fcdc246 83 _w = i;
mazgch 13:e2446fcdc246 84 return c;
mazgch 0:cb2d45baaca3 85 }
mazgch 40:295099ff5338 86
mazgch 40:295099ff5338 87 /* Add a buffer of elements to the buffer.
mazgch 40:295099ff5338 88 \param p the elements to add
mazgch 40:295099ff5338 89 \param n the number elements to add from p
mazgch 40:295099ff5338 90 \param t set to true if blocking, false otherwise
mazgch 40:295099ff5338 91 \return number elements added
mazgch 40:295099ff5338 92 */
mazgch 9:e7a5959ffae1 93 int put(const T* p, int n, bool t = false)
mazgch 0:cb2d45baaca3 94 {
mazgch 9:e7a5959ffae1 95 int c = n;
mazgch 9:e7a5959ffae1 96 while (c)
mazgch 0:cb2d45baaca3 97 {
mazgch 9:e7a5959ffae1 98 int f;
mazgch 9:e7a5959ffae1 99 for (;;) // wait for space
mazgch 0:cb2d45baaca3 100 {
mazgch 9:e7a5959ffae1 101 f = free();
mazgch 74:208e3e32d263 102 if (f > 0) break; // data avail
mazgch 9:e7a5959ffae1 103 if (!t) return n - c; // no more space and not blocking
mazgch 75:ce6e12067d0c 104 RELAX_MS(0);
mazgch 0:cb2d45baaca3 105 }
mazgch 9:e7a5959ffae1 106 // check free space
mazgch 9:e7a5959ffae1 107 if (c < f) f = c;
mazgch 9:e7a5959ffae1 108 int w = _w;
mazgch 9:e7a5959ffae1 109 int m = _s - w;
mazgch 9:e7a5959ffae1 110 // check wrap
mazgch 9:e7a5959ffae1 111 if (f > m) f = m;
mazgch 9:e7a5959ffae1 112 memcpy(&_b[w], p, f);
mazgch 9:e7a5959ffae1 113 _w = _inc(w, f);
mazgch 9:e7a5959ffae1 114 c -= f;
mazgch 9:e7a5959ffae1 115 p += f;
mazgch 8:2435cdff8015 116 }
mazgch 9:e7a5959ffae1 117 return n - c;
mazgch 0:cb2d45baaca3 118 }
mazgch 40:295099ff5338 119
mazgch 40:295099ff5338 120 // reading thread/context API
mazgch 0:cb2d45baaca3 121 // --------------------------------------------------------
mazgch 40:295099ff5338 122
mazgch 40:295099ff5338 123 /** Check if there are any emelemnt available (readble / not empty)
mazgch 40:295099ff5338 124 \return true if readable/not empty
mazgch 40:295099ff5338 125 */
mazgch 40:295099ff5338 126 bool readable(void)
mazgch 0:cb2d45baaca3 127 {
mazgch 9:e7a5959ffae1 128 return (_r != _w);
mazgch 0:cb2d45baaca3 129 }
mazgch 40:295099ff5338 130
mazgch 40:295099ff5338 131 /** Get the number of values available in the buffer
mazgch 40:295099ff5338 132 return the number of element available
mazgch 40:295099ff5338 133 */
mazgch 41:b94a1f410e71 134 int size(void)
mazgch 0:cb2d45baaca3 135 {
mazgch 9:e7a5959ffae1 136 int s = _w - _r;
mazgch 9:e7a5959ffae1 137 if (s < 0)
mazgch 9:e7a5959ffae1 138 s += _s;
mazgch 9:e7a5959ffae1 139 return s;
mazgch 0:cb2d45baaca3 140 }
mazgch 40:295099ff5338 141
mazgch 40:295099ff5338 142 /** get a single value from buffered pipe (this function will block if no values available)
mazgch 40:295099ff5338 143 \return the element extracted
mazgch 40:295099ff5338 144 */
mazgch 0:cb2d45baaca3 145 T getc(void)
mazgch 0:cb2d45baaca3 146 {
mazgch 9:e7a5959ffae1 147 int r = _r;
mazgch 9:e7a5959ffae1 148 while (r == _w) // = !readable()
mazgch 75:ce6e12067d0c 149 RELAX_MS(0);
mazgch 9:e7a5959ffae1 150 T t = _b[r];
mazgch 9:e7a5959ffae1 151 _r = _inc(r);
mazgch 0:cb2d45baaca3 152 return t;
mazgch 0:cb2d45baaca3 153 }
mazgch 40:295099ff5338 154
mazgch 40:295099ff5338 155 /*! get elements from the buffered pipe
mazgch 40:295099ff5338 156 \param p the elements extracted
mazgch 40:295099ff5338 157 \param n the maximum number elements to extract
mazgch 40:295099ff5338 158 \param t set to true if blocking, false otherwise
mazgch 40:295099ff5338 159 \return number elements extracted
mazgch 40:295099ff5338 160 */
mazgch 41:b94a1f410e71 161 int get(T* p, int n, bool t = false)
mazgch 0:cb2d45baaca3 162 {
mazgch 9:e7a5959ffae1 163 int c = n;
mazgch 9:e7a5959ffae1 164 while (c)
mazgch 0:cb2d45baaca3 165 {
mazgch 9:e7a5959ffae1 166 int f;
mazgch 9:e7a5959ffae1 167 for (;;) // wait for data
mazgch 0:cb2d45baaca3 168 {
mazgch 9:e7a5959ffae1 169 f = size();
mazgch 9:e7a5959ffae1 170 if (f) break; // free space
mazgch 9:e7a5959ffae1 171 if (!t) return n - c; // no space and not blocking
mazgch 75:ce6e12067d0c 172 RELAX_MS(0);
mazgch 0:cb2d45baaca3 173 }
mazgch 9:e7a5959ffae1 174 // check available data
mazgch 9:e7a5959ffae1 175 if (c < f) f = c;
mazgch 9:e7a5959ffae1 176 int r = _r;
mazgch 9:e7a5959ffae1 177 int m = _s - r;
mazgch 9:e7a5959ffae1 178 // check wrap
mazgch 9:e7a5959ffae1 179 if (f > m) f = m;
mazgch 9:e7a5959ffae1 180 memcpy(p, &_b[r], f);
mazgch 9:e7a5959ffae1 181 _r = _inc(r, f);
mazgch 9:e7a5959ffae1 182 c -= f;
mazgch 9:e7a5959ffae1 183 p += f;
mazgch 0:cb2d45baaca3 184 }
mazgch 9:e7a5959ffae1 185 return n - c;
mazgch 0:cb2d45baaca3 186 }
mazgch 9:e7a5959ffae1 187
mazgch 40:295099ff5338 188 // the following functions are useful if you like to inspect
mazgch 40:295099ff5338 189 // or parse the buffer in the reading thread/context
mazgch 40:295099ff5338 190 // --------------------------------------------------------
mazgch 9:e7a5959ffae1 191
mazgch 40:295099ff5338 192 /** set the parsing index and return the number of available
mazgch 40:295099ff5338 193 elments starting this position.
mazgch 40:295099ff5338 194 \param ix the index to set.
mazgch 40:295099ff5338 195 \return the number of elements starting at this position
mazgch 40:295099ff5338 196 */
mazgch 41:b94a1f410e71 197 int set(int ix)
mazgch 9:e7a5959ffae1 198 {
mazgch 21:c4d64830bf02 199 int sz = size();
mazgch 21:c4d64830bf02 200 ix = (ix > sz) ? sz : ix;
mazgch 21:c4d64830bf02 201 _o = _inc(_r, ix);
mazgch 21:c4d64830bf02 202 return sz - ix;
mazgch 9:e7a5959ffae1 203 }
mazgch 40:295099ff5338 204
mazgch 40:295099ff5338 205 /** get the next element from parsing position and increment parsing index
mazgch 40:295099ff5338 206 \return the extracted element.
mazgch 40:295099ff5338 207 */
mazgch 41:b94a1f410e71 208 T next(void)
mazgch 9:e7a5959ffae1 209 {
mazgch 9:e7a5959ffae1 210 int o = _o;
mazgch 9:e7a5959ffae1 211 T t = _b[o];
mazgch 9:e7a5959ffae1 212 _o = _inc(o);
mazgch 9:e7a5959ffae1 213 return t;
mazgch 9:e7a5959ffae1 214 }
mazgch 40:295099ff5338 215
mazgch 40:295099ff5338 216 /** commit the index, mrk the current parsing index as consumed data.
mazgch 40:295099ff5338 217 */
mazgch 41:b94a1f410e71 218 void done(void)
mazgch 9:e7a5959ffae1 219 {
mazgch 9:e7a5959ffae1 220 _r = _o;
mazgch 9:e7a5959ffae1 221 }
mazgch 0:cb2d45baaca3 222
mazgch 0:cb2d45baaca3 223 private:
mazgch 40:295099ff5338 224 /** increment the index
mazgch 40:295099ff5338 225 \param i index to increment
mazgch 40:295099ff5338 226 \param n the step to increment
mazgch 40:295099ff5338 227 \return the incremented index.
mazgch 40:295099ff5338 228 */
mazgch 40:295099ff5338 229 inline int _inc(int i, int n = 1)
mazgch 40:295099ff5338 230 {
mazgch 40:295099ff5338 231 i += n;
mazgch 40:295099ff5338 232 if (i >= _s)
mazgch 40:295099ff5338 233 i -= _s;
mazgch 40:295099ff5338 234 return i;
mazgch 40:295099ff5338 235 }
mazgch 40:295099ff5338 236
mazgch 9:e7a5959ffae1 237 T* _b; //!< buffer
mazgch 9:e7a5959ffae1 238 T* _a; //!< allocated buffer
mazgch 9:e7a5959ffae1 239 int _s; //!< size of buffer (s - 1) elements can be stored
mazgch 9:e7a5959ffae1 240 volatile int _w; //!< write index
mazgch 9:e7a5959ffae1 241 volatile int _r; //!< read index
mazgch 9:e7a5959ffae1 242 int _o; //!< offest index used by parsing functions
mazgch 0:cb2d45baaca3 243 };