Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Wed Jun 05 17:29:31 2019 +0000
Revision:
125:ce4045184366
Parent:
119:b3d7699d0eb0
Added SnRateListner proto-class, publishing this version of the code in order to enable exporting of most recent features.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
uci1 21:ce51bb0ba4a5 1 #include "SnEventFrame.h"
uci1 21:ce51bb0ba4a5 2
uci1 21:ce51bb0ba4a5 3 #include "SnCRCUtils.h"
uci1 21:ce51bb0ba4a5 4
uci1 21:ce51bb0ba4a5 5 //#define DEBUG
uci1 21:ce51bb0ba4a5 6
uci1 56:0bba0ef15697 7 #if CHIPBOARD==ATWD4CH
uci1 21:ce51bb0ba4a5 8 const uint8_t SnEventFrame::kIOVers = 1; // MUST BE INCREASED if any member var changes (==> also if kNchans, etc. change!)
uci1 114:554fa3a956b4 9 #elif CHIPBOARD==SST4CH
uci1 56:0bba0ef15697 10 const uint8_t SnEventFrame::kIOVers = 2; // MUST BE INCREASED if any member var changes (==> also if kNchans, etc. change!)
uci1 114:554fa3a956b4 11 #elif CHIPBOARD==SST4CH_1GHz
uci1 114:554fa3a956b4 12 const uint8_t SnEventFrame::kIOVers = 3; // MUST BE INCREASED if any member var changes (==> also if kNchans, etc. change!)
uci1 116:8099b754fbb4 13 #elif CHIPBOARD==SST4CH512
uci1 116:8099b754fbb4 14 const uint8_t SnEventFrame::kIOVers = 4; // MUST BE INCREASED if any member var changes (==> also if kNchans, etc. change!)
uci1 116:8099b754fbb4 15 #elif CHIPBOARD==SST4CH512_1GHz
uci1 116:8099b754fbb4 16 const uint8_t SnEventFrame::kIOVers = 5; // MUST BE INCREASED if any member var changes (==> also if kNchans, etc. change!)
uci1 119:b3d7699d0eb0 17 #elif CHIPBOARD==SST8CH
uci1 119:b3d7699d0eb0 18 const uint8_t SnEventFrame::kIOVers = 6; // MUST BE INCREASED if any member var changes (==> also if kNchans, etc. change!)
uci1 119:b3d7699d0eb0 19 #elif CHIPBOARD==SST8CH_1GHz
uci1 119:b3d7699d0eb0 20 const uint8_t SnEventFrame::kIOVers = 7; // MUST BE INCREASED if any member var changes (==> also if kNchans, etc. change!)
uci1 114:554fa3a956b4 21 #else
uci1 114:554fa3a956b4 22 #error CHIPBOARD value not accounted for in event frame i/o version.
uci1 56:0bba0ef15697 23 #endif
uci1 21:ce51bb0ba4a5 24
uci1 21:ce51bb0ba4a5 25 const char* SnEventFrame::ReadFrom(const char* const buf,
uci1 21:ce51bb0ba4a5 26 const uint8_t loseLSB, const uint8_t loseMSB,
uci1 21:ce51bb0ba4a5 27 const uint16_t wvBaseline) {
uci1 21:ce51bb0ba4a5 28 // no check on the length of buf is done here
uci1 21:ce51bb0ba4a5 29 // that should be been done already
uci1 21:ce51bb0ba4a5 30 //
uci1 21:ce51bb0ba4a5 31 // must match ::WriteToBuf
uci1 21:ce51bb0ba4a5 32
uci1 21:ce51bb0ba4a5 33 // NOTE: on the mbed, this is reduntant (char is unsigned)
uci1 21:ce51bb0ba4a5 34 // but this way, the block can be copied to other computers
uci1 21:ce51bb0ba4a5 35 // and still work.
uci1 21:ce51bb0ba4a5 36 union Usub {
uci1 21:ce51bb0ba4a5 37 const char* s;
uci1 21:ce51bb0ba4a5 38 const uint8_t* u;
uci1 21:ce51bb0ba4a5 39 } b;
uci1 21:ce51bb0ba4a5 40 b.s = buf;
uci1 56:0bba0ef15697 41
uci1 21:ce51bb0ba4a5 42 uint8_t Rv=0;
uci1 21:ce51bb0ba4a5 43 b.s = SnBitUtils::ReadFrom(b.s, Rv); // i/o version
uci1 21:ce51bb0ba4a5 44 if (Rv>0) {
uci1 56:0bba0ef15697 45
uci1 56:0bba0ef15697 46 const uint16_t nsamps = GetTotSamplesForIOVers(Rv);
uci1 56:0bba0ef15697 47
uci1 21:ce51bb0ba4a5 48 b.s = SnBitUtils::ReadFrom(b.s, fMbedTime);
uci1 21:ce51bb0ba4a5 49 b.s = SnBitUtils::ReadFrom(b.s, fEvtNum);
uci1 21:ce51bb0ba4a5 50 b.s = SnBitUtils::ReadFrom(b.s, fDTms);
uci1 21:ce51bb0ba4a5 51 b.s = SnBitUtils::ReadFrom(b.s, fTrgNum);
uci1 21:ce51bb0ba4a5 52 b.s = SnBitUtils::ReadFrom(b.s, fTrgBits);
uci1 56:0bba0ef15697 53 b.u = UnpackWavef(b.u, fData, loseLSB, loseMSB, wvBaseline, nsamps);
uci1 21:ce51bb0ba4a5 54 b.s = SnBitUtils::ReadFrom(b.s, fCRC);
uci1 56:0bba0ef15697 55
uci1 56:0bba0ef15697 56 #if CHIPBOARD!=ATWD4CH
uci1 116:8099b754fbb4 57 const uint16_t nstopBytes = GetStopBytesForIOVersBufferSafe(Rv);
uci1 56:0bba0ef15697 58 if (Rv>1) {
uci1 56:0bba0ef15697 59 b.s = SnBitUtils::ReadFrom(b.s, fStop, nstopBytes);
uci1 56:0bba0ef15697 60 }
uci1 56:0bba0ef15697 61 #endif
uci1 21:ce51bb0ba4a5 62 }
uci1 21:ce51bb0ba4a5 63
uci1 21:ce51bb0ba4a5 64 return b.s;
uci1 21:ce51bb0ba4a5 65 }
uci1 21:ce51bb0ba4a5 66
uci1 21:ce51bb0ba4a5 67 char* SnEventFrame::WriteTo(char* const buf,
uci1 21:ce51bb0ba4a5 68 const uint8_t loseLSB, const uint8_t loseMSB,
uci1 21:ce51bb0ba4a5 69 const uint16_t wvBaseline) const {
uci1 21:ce51bb0ba4a5 70 // no check on the length of the buf is done here
uci1 21:ce51bb0ba4a5 71 // that should be done already
uci1 21:ce51bb0ba4a5 72 //
uci1 21:ce51bb0ba4a5 73 // must match ReadFromBuf
uci1 21:ce51bb0ba4a5 74
uci1 21:ce51bb0ba4a5 75 // NOTE: on the mbed, this is reduntant (char is unsigned)
uci1 21:ce51bb0ba4a5 76 // but this way, the block can be copied to other computers
uci1 21:ce51bb0ba4a5 77 // and still work.
uci1 21:ce51bb0ba4a5 78 union {
uci1 21:ce51bb0ba4a5 79 char* s;
uci1 21:ce51bb0ba4a5 80 uint8_t* u;
uci1 21:ce51bb0ba4a5 81 } b;
uci1 21:ce51bb0ba4a5 82 b.s = buf;
uci1 21:ce51bb0ba4a5 83
uci1 21:ce51bb0ba4a5 84 b.s = SnBitUtils::WriteTo(b.s, kIOVers); // i/o version
uci1 21:ce51bb0ba4a5 85
uci1 56:0bba0ef15697 86 const uint16_t nsamps = GetTotSamplesForIOVers(kIOVers);
uci1 56:0bba0ef15697 87
uci1 21:ce51bb0ba4a5 88 b.s = SnBitUtils::WriteTo(b.s, fMbedTime);
uci1 21:ce51bb0ba4a5 89 b.s = SnBitUtils::WriteTo(b.s, fEvtNum);
uci1 21:ce51bb0ba4a5 90 b.s = SnBitUtils::WriteTo(b.s, fDTms);
uci1 21:ce51bb0ba4a5 91 b.s = SnBitUtils::WriteTo(b.s, fTrgNum);
uci1 21:ce51bb0ba4a5 92 b.s = SnBitUtils::WriteTo(b.s, fTrgBits);
uci1 56:0bba0ef15697 93 b.u = PackWavef(b.u, fData, loseLSB, loseMSB, wvBaseline, nsamps);
uci1 21:ce51bb0ba4a5 94 b.s = SnBitUtils::WriteTo(b.s, fCRC);
uci1 21:ce51bb0ba4a5 95
uci1 56:0bba0ef15697 96 #if CHIPBOARD!=ATWD4CH
uci1 116:8099b754fbb4 97 const uint16_t nstopBytes = GetStopBytesForIOVersBufferSafe(kIOVers);
uci1 56:0bba0ef15697 98 if (kIOVers>1) {
uci1 56:0bba0ef15697 99 // we test kIOVers rather than the CHIPBOARD #define in order
uci1 56:0bba0ef15697 100 // to ensure that the i/o version is the ONLY variable that determines
uci1 56:0bba0ef15697 101 // what the event looks like in a file or communication.
uci1 56:0bba0ef15697 102 // this is the only way to ensure readability going forward.
uci1 116:8099b754fbb4 103 #ifdef DEBUG
uci1 116:8099b754fbb4 104 printf("kNstopBytes=%hu, nstopBytes=%hu, kIOVers=%hhu\r\n",
uci1 116:8099b754fbb4 105 kNstopBytes, nstopBytes, kIOVers);
uci1 116:8099b754fbb4 106 char* x = b.s;
uci1 116:8099b754fbb4 107 #endif
uci1 56:0bba0ef15697 108 b.s = SnBitUtils::WriteTo(b.s, fStop, nstopBytes);
uci1 116:8099b754fbb4 109 #ifdef DEBUG
uci1 116:8099b754fbb4 110 printf("wrote %d stop bytes\r\n", b.s - x);
uci1 116:8099b754fbb4 111 #endif
uci1 56:0bba0ef15697 112 }
uci1 56:0bba0ef15697 113 #endif
uci1 56:0bba0ef15697 114
uci1 21:ce51bb0ba4a5 115 #ifdef DEBUG
uci1 21:ce51bb0ba4a5 116 printf("SnEventFrame::WriteTo:\r\n");
uci1 21:ce51bb0ba4a5 117 for (uint32_t i=0; i<b.s-buf; i++) {
uci1 21:ce51bb0ba4a5 118 printf("%02X ",buf[i]);
uci1 21:ce51bb0ba4a5 119 }
uci1 21:ce51bb0ba4a5 120 printf("\r\n");
uci1 21:ce51bb0ba4a5 121 #endif
uci1 21:ce51bb0ba4a5 122
uci1 21:ce51bb0ba4a5 123 return b.s;
uci1 21:ce51bb0ba4a5 124 }
uci1 21:ce51bb0ba4a5 125
uci1 21:ce51bb0ba4a5 126 void SnEventFrame::CalcCRC() {
uci1 21:ce51bb0ba4a5 127 // CRC made using union on a little endian (mbed) processor
uci1 42:ac162d15e578 128 fCRC = SnCRCUtils::GetCRC32for(fData, kTotSamps);
uci1 56:0bba0ef15697 129 #if CHIPBOARD!=ATWD4CH
uci1 56:0bba0ef15697 130 fCRC = SnCRCUtils::GetUpdatedCRC32for(fCRC, fStop, kNstopBytes);
uci1 56:0bba0ef15697 131 #endif
uci1 42:ac162d15e578 132 #ifdef DEBUG
uci1 42:ac162d15e578 133 printf("SnEventFrame::CalcCRC crc=%u\r\n",fCRC);
uci1 42:ac162d15e578 134 #endif
uci1 21:ce51bb0ba4a5 135 }
uci1 21:ce51bb0ba4a5 136
uci1 21:ce51bb0ba4a5 137 bool SnEventFrame::ReadFromFileToBuf(FILE* f,
uci1 21:ce51bb0ba4a5 138 char* const evtBuf,
uci1 21:ce51bb0ba4a5 139 const uint8_t loseLSB,
uci1 21:ce51bb0ba4a5 140 const uint8_t loseMSB) {
uci1 21:ce51bb0ba4a5 141 // file position expected to be at this event frame already
uci1 21:ce51bb0ba4a5 142 bool ret = false;
uci1 21:ce51bb0ba4a5 143 if (f!=0) {
uci1 25:57b2627fe756 144 if (fread(evtBuf, SizeOf(kIOVers, loseLSB, loseMSB), 1u, f)!=0) {
uci1 21:ce51bb0ba4a5 145 ret = true;
uci1 21:ce51bb0ba4a5 146 }
uci1 21:ce51bb0ba4a5 147 }
uci1 21:ce51bb0ba4a5 148 return ret;
uci1 21:ce51bb0ba4a5 149 }
uci1 21:ce51bb0ba4a5 150
uci1 21:ce51bb0ba4a5 151 bool SnEventFrame::ReadFrom(FILE* f,
uci1 21:ce51bb0ba4a5 152 char* const evtBuf,
uci1 21:ce51bb0ba4a5 153 const uint8_t loseLSB, const uint8_t loseMSB,
uci1 21:ce51bb0ba4a5 154 const uint16_t wvBaseline) {
uci1 21:ce51bb0ba4a5 155 // file position expected to be at this event frame already
uci1 21:ce51bb0ba4a5 156 const bool ret = ReadFromFileToBuf(f, evtBuf, loseLSB, loseMSB);
uci1 21:ce51bb0ba4a5 157 if (ret) {
uci1 21:ce51bb0ba4a5 158 ReadFrom(evtBuf, loseLSB, loseMSB, wvBaseline);
uci1 21:ce51bb0ba4a5 159 }
uci1 21:ce51bb0ba4a5 160 return ret;
uci1 21:ce51bb0ba4a5 161 }
uci1 21:ce51bb0ba4a5 162
uci1 21:ce51bb0ba4a5 163 bool SnEventFrame::WriteTo(FILE* f, char* const evtBuf,
uci1 21:ce51bb0ba4a5 164 const uint8_t loseLSB, const uint8_t loseMSB,
uci1 21:ce51bb0ba4a5 165 const uint16_t wvBaseline) const {
uci1 21:ce51bb0ba4a5 166 // file pointer should be in correct location
uci1 21:ce51bb0ba4a5 167
uci1 21:ce51bb0ba4a5 168 WriteTo(evtBuf, loseLSB, loseMSB, wvBaseline);
uci1 21:ce51bb0ba4a5 169 return WriteToFileFromBuf(f, evtBuf, loseLSB, loseMSB);
uci1 21:ce51bb0ba4a5 170 }
uci1 21:ce51bb0ba4a5 171
uci1 21:ce51bb0ba4a5 172 bool SnEventFrame::WriteToFileFromBuf(FILE* f, char* const evtBuf,
uci1 21:ce51bb0ba4a5 173 const uint8_t loseLSB, const uint8_t loseMSB) {
uci1 21:ce51bb0ba4a5 174 // file pointer should be in correct location
uci1 21:ce51bb0ba4a5 175
uci1 21:ce51bb0ba4a5 176 bool ret = false;
uci1 21:ce51bb0ba4a5 177 if (f!=0) {
uci1 21:ce51bb0ba4a5 178 fwrite(evtBuf, SizeOf(kIOVers, loseLSB, loseMSB), 1u, f);
uci1 21:ce51bb0ba4a5 179 ret = (ferror(f)==false);
uci1 21:ce51bb0ba4a5 180 }
uci1 21:ce51bb0ba4a5 181 return ret;
uci1 21:ce51bb0ba4a5 182
uci1 21:ce51bb0ba4a5 183 }
uci1 21:ce51bb0ba4a5 184
uci1 21:ce51bb0ba4a5 185
uci1 21:ce51bb0ba4a5 186 uint8_t* SnEventFrame::PackWavef(uint8_t* const buf, const uint16_t* const data,
uci1 21:ce51bb0ba4a5 187 const uint8_t loseLSB, const uint8_t loseMSB,
uci1 56:0bba0ef15697 188 const uint16_t wvBaseline,
uci1 56:0bba0ef15697 189 const uint16_t nsamps) {
uci1 21:ce51bb0ba4a5 190 // Compress the data. This is potentially LOSSY; it depends
uci1 21:ce51bb0ba4a5 191 // on the dynamic range and on the options.
uci1 21:ce51bb0ba4a5 192 // See SnConfigFrame::fWvLoseLSB and SnConfigFrame::fWvLoseMSB.
uci1 21:ce51bb0ba4a5 193 // If the number of least signficant bits to lose is not 0, the
uci1 21:ce51bb0ba4a5 194 // compression will be lossy (decreased resolution -- this is ok
uci1 21:ce51bb0ba4a5 195 // if the noise of the signal is much greater than the resolution).
uci1 21:ce51bb0ba4a5 196 // Losing the most significant bits will only be lossy if the
uci1 21:ce51bb0ba4a5 197 // signal-SnConfigFrame::fWvBaseline cannot fit in the reduced
uci1 21:ce51bb0ba4a5 198 // dynamic range (each MSB bit reducing the DR by a factor of 2).
uci1 21:ce51bb0ba4a5 199 //
uci1 21:ce51bb0ba4a5 200 // Note that the mbed uses little endian. Behavior should be the
uci1 21:ce51bb0ba4a5 201 // same on big endian, but this has not been tested.
uci1 21:ce51bb0ba4a5 202 //
uci1 21:ce51bb0ba4a5 203 // Use an unsigned buffer to prevent bits being changed during
uci1 21:ce51bb0ba4a5 204 // an implicit unsigned -> signed cast.
uci1 21:ce51bb0ba4a5 205 //
uci1 21:ce51bb0ba4a5 206 // buf = the byte array into which the data should be packed
uci1 21:ce51bb0ba4a5 207 // data = the data to pack
uci1 21:ce51bb0ba4a5 208 // loseLSB = number of least significant bits to throw away
uci1 21:ce51bb0ba4a5 209 // loseMSB = number of most significant bits to throw away
uci1 21:ce51bb0ba4a5 210 // wvBaseline = baseline to subtract to from ADC before packing
uci1 21:ce51bb0ba4a5 211
uci1 21:ce51bb0ba4a5 212 const uint32_t blen = SizeOfPackedWavef(loseLSB, loseMSB);
uci1 21:ce51bb0ba4a5 213 const uint8_t packSmpBits = BITS_IN_SHORT-loseLSB-loseMSB;
uci1 21:ce51bb0ba4a5 214
uci1 21:ce51bb0ba4a5 215 // make sure this buffer space is all 0's to start
uci1 21:ce51bb0ba4a5 216 memset(buf, 0, blen*sizeof(uint8_t));
uci1 21:ce51bb0ba4a5 217
uci1 21:ce51bb0ba4a5 218 const uint16_t clipHi = uint16_t(
uci1 21:ce51bb0ba4a5 219 uint16_t(uint16_t(0xFFFFu >> loseLSB) << (loseLSB+loseMSB))
uci1 21:ce51bb0ba4a5 220 >> loseMSB);
uci1 21:ce51bb0ba4a5 221
uci1 21:ce51bb0ba4a5 222 uint8_t* b = buf;
uci1 21:ce51bb0ba4a5 223 const uint16_t* dev = data;
uci1 21:ce51bb0ba4a5 224 uint16_t dum;
uci1 21:ce51bb0ba4a5 225 int8_t sbit=0;
uci1 56:0bba0ef15697 226 for (uint16_t i=0; i<nsamps; ++i, ++dev) {
uci1 21:ce51bb0ba4a5 227 // dump the bits we don't want
uci1 21:ce51bb0ba4a5 228 dum = (*dev) - wvBaseline;
uci1 21:ce51bb0ba4a5 229 if (dum<clipHi) {
uci1 21:ce51bb0ba4a5 230 dum >>= loseLSB;
uci1 21:ce51bb0ba4a5 231 dum <<= (loseLSB+loseMSB);
uci1 21:ce51bb0ba4a5 232 } else {
uci1 21:ce51bb0ba4a5 233 dum = clipHi << loseMSB;
uci1 21:ce51bb0ba4a5 234 }
uci1 21:ce51bb0ba4a5 235 if (sbit<=0) {
uci1 21:ce51bb0ba4a5 236 // lose MSB's put in previous short (or none if sbit==0)
uci1 21:ce51bb0ba4a5 237 dum <<= -sbit;
uci1 21:ce51bb0ba4a5 238 *b |= dum >> 8u; // "first" byte of the short
uci1 21:ce51bb0ba4a5 239 dum <<= 8u;
uci1 21:ce51bb0ba4a5 240 *(b+1) |= dum >> 8u; // "second"
uci1 21:ce51bb0ba4a5 241 // move to next number (dev++ in the for loop)
uci1 21:ce51bb0ba4a5 242 // move starting bit up
uci1 21:ce51bb0ba4a5 243 // but stay in this byte of the buf (do not increment b)
uci1 21:ce51bb0ba4a5 244 // since kPackSmpBits <= kBitsInShort, sbit can't
uci1 21:ce51bb0ba4a5 245 // move past the end of the current two bytes
uci1 21:ce51bb0ba4a5 246 sbit += packSmpBits;
uci1 21:ce51bb0ba4a5 247 } else {
uci1 21:ce51bb0ba4a5 248 // first few bits towards the end of this short
uci1 21:ce51bb0ba4a5 249 dum >>= sbit;
uci1 21:ce51bb0ba4a5 250 *b |= dum >> 8u; // "first" byte of the short
uci1 21:ce51bb0ba4a5 251 dum <<= 8u;
uci1 21:ce51bb0ba4a5 252 *(b+1) |= dum >> 8u; // "second"
uci1 21:ce51bb0ba4a5 253 if ( (sbit+packSmpBits) >= BITS_IN_SHORT ) {
uci1 21:ce51bb0ba4a5 254 b+=2; // move to next short in the buf
uci1 21:ce51bb0ba4a5 255 i--; dev--; // but stay on this number
uci1 21:ce51bb0ba4a5 256 // move starting bit back into the short we just filled
uci1 21:ce51bb0ba4a5 257 sbit -= BITS_IN_SHORT;
uci1 21:ce51bb0ba4a5 258 } else {
uci1 21:ce51bb0ba4a5 259 // stay in this buffer and move to the next number
uci1 21:ce51bb0ba4a5 260 // move starting bit up
uci1 21:ce51bb0ba4a5 261 sbit += packSmpBits;
uci1 21:ce51bb0ba4a5 262 }
uci1 21:ce51bb0ba4a5 263 }
uci1 21:ce51bb0ba4a5 264 }
uci1 21:ce51bb0ba4a5 265
uci1 21:ce51bb0ba4a5 266 return buf+blen;
uci1 21:ce51bb0ba4a5 267 }
uci1 21:ce51bb0ba4a5 268
uci1 21:ce51bb0ba4a5 269 const uint8_t* SnEventFrame::UnpackWavef(const uint8_t* const buf,
uci1 21:ce51bb0ba4a5 270 uint16_t* const data,
uci1 21:ce51bb0ba4a5 271 const uint8_t loseLSB,
uci1 21:ce51bb0ba4a5 272 const uint8_t loseMSB,
uci1 56:0bba0ef15697 273 const uint16_t wvBaseline,
uci1 56:0bba0ef15697 274 const uint16_t nsamps) {
uci1 21:ce51bb0ba4a5 275 if (loseLSB==0 && loseMSB==0 && wvBaseline==0) {
uci1 56:0bba0ef15697 276 memcpy(data, buf, nsamps*sizeof(uint16_t));
uci1 21:ce51bb0ba4a5 277 } else {
uci1 21:ce51bb0ba4a5 278
uci1 21:ce51bb0ba4a5 279 const uint8_t packSmpBits = BITS_IN_SHORT-loseLSB-loseMSB;
uci1 21:ce51bb0ba4a5 280
uci1 21:ce51bb0ba4a5 281 // make sure data is all 0's to start
uci1 56:0bba0ef15697 282 memset(data, 0, nsamps*sizeof(uint16_t));
uci1 21:ce51bb0ba4a5 283
uci1 21:ce51bb0ba4a5 284 const uint8_t* b = buf;
uci1 21:ce51bb0ba4a5 285 uint16_t* dev = data;
uci1 21:ce51bb0ba4a5 286 uint16_t dum;
uci1 21:ce51bb0ba4a5 287 int8_t sbit=0;
uci1 56:0bba0ef15697 288 for (uint16_t i=0; i<nsamps; ++i, ++dev) {
uci1 21:ce51bb0ba4a5 289 dum = (*b) << 8u;
uci1 21:ce51bb0ba4a5 290 dum |= *(b+1);
uci1 21:ce51bb0ba4a5 291 if (sbit<=0) {
uci1 21:ce51bb0ba4a5 292 dum >>= (-sbit+loseLSB+loseMSB);
uci1 21:ce51bb0ba4a5 293 dum <<= loseLSB;
uci1 21:ce51bb0ba4a5 294 *dev |= dum;
uci1 21:ce51bb0ba4a5 295 // add baseline and move to next number (dev++ in the for loop)
uci1 21:ce51bb0ba4a5 296 *dev += wvBaseline;
uci1 21:ce51bb0ba4a5 297 // but stay in this short of the buf (do not increment b)
uci1 21:ce51bb0ba4a5 298 // move starting bit up
uci1 21:ce51bb0ba4a5 299 sbit += packSmpBits;
uci1 21:ce51bb0ba4a5 300 } else {
uci1 21:ce51bb0ba4a5 301 dum <<= sbit;
uci1 21:ce51bb0ba4a5 302 dum >>= loseMSB+loseLSB;
uci1 21:ce51bb0ba4a5 303 dum <<= loseLSB;
uci1 21:ce51bb0ba4a5 304 *dev = dum;
uci1 21:ce51bb0ba4a5 305 if ( (sbit+packSmpBits) >= BITS_IN_SHORT ) {
uci1 21:ce51bb0ba4a5 306 b+=2; // move to next short in the buf
uci1 21:ce51bb0ba4a5 307 i--; dev--; // but stay on this number
uci1 21:ce51bb0ba4a5 308 // move starting bit back into the short we just read from
uci1 21:ce51bb0ba4a5 309 sbit -= BITS_IN_SHORT;
uci1 21:ce51bb0ba4a5 310 } else {
uci1 21:ce51bb0ba4a5 311 // add baseline and move to next number (dev++ in the for loop)
uci1 21:ce51bb0ba4a5 312 *dev += wvBaseline;
uci1 21:ce51bb0ba4a5 313 sbit += packSmpBits;
uci1 21:ce51bb0ba4a5 314 }
uci1 21:ce51bb0ba4a5 315 }
uci1 21:ce51bb0ba4a5 316 }
uci1 21:ce51bb0ba4a5 317 }
uci1 21:ce51bb0ba4a5 318
uci1 21:ce51bb0ba4a5 319 return buf+SizeOfPackedWavef(loseLSB, loseMSB);
uci1 21:ce51bb0ba4a5 320 }
uci1 21:ce51bb0ba4a5 321