Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Wed May 29 18:54:19 2013 +0000
Revision:
38:9070c17536cd
Parent:
25:57b2627fe756
Child:
40:1324da35afd4
Update SnCRCUtils to use templated function. Add MODSERIAL include to SnCommWinUsb when enabled. Move iridium constants to SnCommConstants.

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