This class provides an API to communicate with a u-blox GNSS chip. The files here were originally part of the C027_Support library (https://developer.mbed.org/teams/ublox/code/C027_Support/ at revision 138:dafbbf31bf76) but have been separated out, primarily for use on the u-blox C030 board where the cellular interace portion of the C027_Support library will instead be provided through the new mbed Cellular API.

Dependents:   example-ublox-at-cellular-interface-ext example-gnss example-low-power-sleep example-C030-out-of-box-demo ... more

Committer:
fahim.alavi@u-blox.com
Date:
Mon Dec 17 12:11:07 2018 +0500
Revision:
29:54fd002f2376
Parent:
1:ef70a58a6c98
Decoding and decoding status of NAV-SAT added

Who changed what in which revision?

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