Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Sat Oct 05 04:45:22 2013 +0000
Revision:
40:1324da35afd4
Parent:
38:9070c17536cd
Child:
42:ac162d15e578
first commit of major overhaul to 2013-2014 mbed code. NOT YET FULLY TESTED. too many changes to list (fix local file receive, fix rates, external comm packes, big SD cards, get to comm win w/o SD, v8 config frame, v4 files, SBD buffering changes...)

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 21:ce51bb0ba4a5 83 }
uci1 21:ce51bb0ba4a5 84
uci1 21:ce51bb0ba4a5 85 bool SnEventFrame::ReadFromFileToBuf(FILE* f,
uci1 21:ce51bb0ba4a5 86 char* const evtBuf,
uci1 21:ce51bb0ba4a5 87 const uint8_t loseLSB,
uci1 21:ce51bb0ba4a5 88 const uint8_t loseMSB) {
uci1 21:ce51bb0ba4a5 89 // file position expected to be at this event frame already
uci1 21:ce51bb0ba4a5 90 bool ret = false;
uci1 21:ce51bb0ba4a5 91 if (f!=0) {
uci1 25:57b2627fe756 92 if (fread(evtBuf, SizeOf(kIOVers, loseLSB, loseMSB), 1u, f)!=0) {
uci1 21:ce51bb0ba4a5 93 ret = true;
uci1 21:ce51bb0ba4a5 94 }
uci1 21:ce51bb0ba4a5 95 }
uci1 21:ce51bb0ba4a5 96 return ret;
uci1 21:ce51bb0ba4a5 97 }
uci1 21:ce51bb0ba4a5 98
uci1 21:ce51bb0ba4a5 99 bool SnEventFrame::ReadFrom(FILE* f,
uci1 21:ce51bb0ba4a5 100 char* const evtBuf,
uci1 21:ce51bb0ba4a5 101 const uint8_t loseLSB, const uint8_t loseMSB,
uci1 21:ce51bb0ba4a5 102 const uint16_t wvBaseline) {
uci1 21:ce51bb0ba4a5 103 // file position expected to be at this event frame already
uci1 21:ce51bb0ba4a5 104 const bool ret = ReadFromFileToBuf(f, evtBuf, loseLSB, loseMSB);
uci1 21:ce51bb0ba4a5 105 if (ret) {
uci1 21:ce51bb0ba4a5 106 ReadFrom(evtBuf, loseLSB, loseMSB, wvBaseline);
uci1 21:ce51bb0ba4a5 107 }
uci1 21:ce51bb0ba4a5 108 return ret;
uci1 21:ce51bb0ba4a5 109 }
uci1 21:ce51bb0ba4a5 110
uci1 21:ce51bb0ba4a5 111 bool SnEventFrame::WriteTo(FILE* f, char* const evtBuf,
uci1 21:ce51bb0ba4a5 112 const uint8_t loseLSB, const uint8_t loseMSB,
uci1 21:ce51bb0ba4a5 113 const uint16_t wvBaseline) const {
uci1 21:ce51bb0ba4a5 114 // file pointer should be in correct location
uci1 21:ce51bb0ba4a5 115
uci1 21:ce51bb0ba4a5 116 WriteTo(evtBuf, loseLSB, loseMSB, wvBaseline);
uci1 21:ce51bb0ba4a5 117 return WriteToFileFromBuf(f, evtBuf, loseLSB, loseMSB);
uci1 21:ce51bb0ba4a5 118 }
uci1 21:ce51bb0ba4a5 119
uci1 21:ce51bb0ba4a5 120 bool SnEventFrame::WriteToFileFromBuf(FILE* f, char* const evtBuf,
uci1 21:ce51bb0ba4a5 121 const uint8_t loseLSB, const uint8_t loseMSB) {
uci1 21:ce51bb0ba4a5 122 // file pointer should be in correct location
uci1 21:ce51bb0ba4a5 123
uci1 21:ce51bb0ba4a5 124 bool ret = false;
uci1 21:ce51bb0ba4a5 125 if (f!=0) {
uci1 21:ce51bb0ba4a5 126 fwrite(evtBuf, SizeOf(kIOVers, loseLSB, loseMSB), 1u, f);
uci1 21:ce51bb0ba4a5 127 ret = (ferror(f)==false);
uci1 21:ce51bb0ba4a5 128 }
uci1 21:ce51bb0ba4a5 129 return ret;
uci1 21:ce51bb0ba4a5 130
uci1 21:ce51bb0ba4a5 131 }
uci1 21:ce51bb0ba4a5 132
uci1 21:ce51bb0ba4a5 133
uci1 21:ce51bb0ba4a5 134 uint8_t* SnEventFrame::PackWavef(uint8_t* const buf, const uint16_t* const data,
uci1 21:ce51bb0ba4a5 135 const uint8_t loseLSB, const uint8_t loseMSB,
uci1 21:ce51bb0ba4a5 136 const uint16_t wvBaseline) {
uci1 21:ce51bb0ba4a5 137 // Compress the data. This is potentially LOSSY; it depends
uci1 21:ce51bb0ba4a5 138 // on the dynamic range and on the options.
uci1 21:ce51bb0ba4a5 139 // See SnConfigFrame::fWvLoseLSB and SnConfigFrame::fWvLoseMSB.
uci1 21:ce51bb0ba4a5 140 // If the number of least signficant bits to lose is not 0, the
uci1 21:ce51bb0ba4a5 141 // compression will be lossy (decreased resolution -- this is ok
uci1 21:ce51bb0ba4a5 142 // if the noise of the signal is much greater than the resolution).
uci1 21:ce51bb0ba4a5 143 // Losing the most significant bits will only be lossy if the
uci1 21:ce51bb0ba4a5 144 // signal-SnConfigFrame::fWvBaseline cannot fit in the reduced
uci1 21:ce51bb0ba4a5 145 // dynamic range (each MSB bit reducing the DR by a factor of 2).
uci1 21:ce51bb0ba4a5 146 //
uci1 21:ce51bb0ba4a5 147 // Note that the mbed uses little endian. Behavior should be the
uci1 21:ce51bb0ba4a5 148 // same on big endian, but this has not been tested.
uci1 21:ce51bb0ba4a5 149 //
uci1 21:ce51bb0ba4a5 150 // Use an unsigned buffer to prevent bits being changed during
uci1 21:ce51bb0ba4a5 151 // an implicit unsigned -> signed cast.
uci1 21:ce51bb0ba4a5 152 //
uci1 21:ce51bb0ba4a5 153 // buf = the byte array into which the data should be packed
uci1 21:ce51bb0ba4a5 154 // data = the data to pack
uci1 21:ce51bb0ba4a5 155 // loseLSB = number of least significant bits to throw away
uci1 21:ce51bb0ba4a5 156 // loseMSB = number of most significant bits to throw away
uci1 21:ce51bb0ba4a5 157 // wvBaseline = baseline to subtract to from ADC before packing
uci1 21:ce51bb0ba4a5 158
uci1 21:ce51bb0ba4a5 159 const uint32_t blen = SizeOfPackedWavef(loseLSB, loseMSB);
uci1 21:ce51bb0ba4a5 160 const uint8_t packSmpBits = BITS_IN_SHORT-loseLSB-loseMSB;
uci1 21:ce51bb0ba4a5 161
uci1 21:ce51bb0ba4a5 162 // make sure this buffer space is all 0's to start
uci1 21:ce51bb0ba4a5 163 memset(buf, 0, blen*sizeof(uint8_t));
uci1 21:ce51bb0ba4a5 164
uci1 21:ce51bb0ba4a5 165 const uint16_t clipHi = uint16_t(
uci1 21:ce51bb0ba4a5 166 uint16_t(uint16_t(0xFFFFu >> loseLSB) << (loseLSB+loseMSB))
uci1 21:ce51bb0ba4a5 167 >> loseMSB);
uci1 21:ce51bb0ba4a5 168
uci1 21:ce51bb0ba4a5 169 uint8_t* b = buf;
uci1 21:ce51bb0ba4a5 170 const uint16_t* dev = data;
uci1 21:ce51bb0ba4a5 171 uint16_t dum;
uci1 21:ce51bb0ba4a5 172 int8_t sbit=0;
uci1 21:ce51bb0ba4a5 173 for (uint16_t i=0; i<kTotSamps; ++i, ++dev) {
uci1 21:ce51bb0ba4a5 174 // dump the bits we don't want
uci1 21:ce51bb0ba4a5 175 dum = (*dev) - wvBaseline;
uci1 21:ce51bb0ba4a5 176 if (dum<clipHi) {
uci1 21:ce51bb0ba4a5 177 dum >>= loseLSB;
uci1 21:ce51bb0ba4a5 178 dum <<= (loseLSB+loseMSB);
uci1 21:ce51bb0ba4a5 179 } else {
uci1 21:ce51bb0ba4a5 180 dum = clipHi << loseMSB;
uci1 21:ce51bb0ba4a5 181 }
uci1 21:ce51bb0ba4a5 182 if (sbit<=0) {
uci1 21:ce51bb0ba4a5 183 // lose MSB's put in previous short (or none if sbit==0)
uci1 21:ce51bb0ba4a5 184 dum <<= -sbit;
uci1 21:ce51bb0ba4a5 185 *b |= dum >> 8u; // "first" byte of the short
uci1 21:ce51bb0ba4a5 186 dum <<= 8u;
uci1 21:ce51bb0ba4a5 187 *(b+1) |= dum >> 8u; // "second"
uci1 21:ce51bb0ba4a5 188 // move to next number (dev++ in the for loop)
uci1 21:ce51bb0ba4a5 189 // move starting bit up
uci1 21:ce51bb0ba4a5 190 // but stay in this byte of the buf (do not increment b)
uci1 21:ce51bb0ba4a5 191 // since kPackSmpBits <= kBitsInShort, sbit can't
uci1 21:ce51bb0ba4a5 192 // move past the end of the current two bytes
uci1 21:ce51bb0ba4a5 193 sbit += packSmpBits;
uci1 21:ce51bb0ba4a5 194 } else {
uci1 21:ce51bb0ba4a5 195 // first few bits towards the end of this short
uci1 21:ce51bb0ba4a5 196 dum >>= sbit;
uci1 21:ce51bb0ba4a5 197 *b |= dum >> 8u; // "first" byte of the short
uci1 21:ce51bb0ba4a5 198 dum <<= 8u;
uci1 21:ce51bb0ba4a5 199 *(b+1) |= dum >> 8u; // "second"
uci1 21:ce51bb0ba4a5 200 if ( (sbit+packSmpBits) >= BITS_IN_SHORT ) {
uci1 21:ce51bb0ba4a5 201 b+=2; // move to next short in the buf
uci1 21:ce51bb0ba4a5 202 i--; dev--; // but stay on this number
uci1 21:ce51bb0ba4a5 203 // move starting bit back into the short we just filled
uci1 21:ce51bb0ba4a5 204 sbit -= BITS_IN_SHORT;
uci1 21:ce51bb0ba4a5 205 } else {
uci1 21:ce51bb0ba4a5 206 // stay in this buffer and move to the next number
uci1 21:ce51bb0ba4a5 207 // move starting bit up
uci1 21:ce51bb0ba4a5 208 sbit += packSmpBits;
uci1 21:ce51bb0ba4a5 209 }
uci1 21:ce51bb0ba4a5 210 }
uci1 21:ce51bb0ba4a5 211 }
uci1 21:ce51bb0ba4a5 212
uci1 21:ce51bb0ba4a5 213 return buf+blen;
uci1 21:ce51bb0ba4a5 214 }
uci1 21:ce51bb0ba4a5 215
uci1 21:ce51bb0ba4a5 216 const uint8_t* SnEventFrame::UnpackWavef(const uint8_t* const buf,
uci1 21:ce51bb0ba4a5 217 uint16_t* const data,
uci1 21:ce51bb0ba4a5 218 const uint8_t loseLSB,
uci1 21:ce51bb0ba4a5 219 const uint8_t loseMSB,
uci1 21:ce51bb0ba4a5 220 const uint16_t wvBaseline) {
uci1 21:ce51bb0ba4a5 221 if (loseLSB==0 && loseMSB==0 && wvBaseline==0) {
uci1 21:ce51bb0ba4a5 222 memcpy(data, buf, kTotSamps*sizeof(uint16_t));
uci1 21:ce51bb0ba4a5 223 } else {
uci1 21:ce51bb0ba4a5 224
uci1 21:ce51bb0ba4a5 225 const uint8_t packSmpBits = BITS_IN_SHORT-loseLSB-loseMSB;
uci1 21:ce51bb0ba4a5 226
uci1 21:ce51bb0ba4a5 227 // make sure data is all 0's to start
uci1 21:ce51bb0ba4a5 228 memset(data, 0, kTotSamps*sizeof(uint16_t));
uci1 21:ce51bb0ba4a5 229
uci1 21:ce51bb0ba4a5 230 const uint8_t* b = buf;
uci1 21:ce51bb0ba4a5 231 uint16_t* dev = data;
uci1 21:ce51bb0ba4a5 232 uint16_t dum;
uci1 21:ce51bb0ba4a5 233 int8_t sbit=0;
uci1 21:ce51bb0ba4a5 234 for (uint16_t i=0; i<kTotSamps; ++i, ++dev) {
uci1 21:ce51bb0ba4a5 235 dum = (*b) << 8u;
uci1 21:ce51bb0ba4a5 236 dum |= *(b+1);
uci1 21:ce51bb0ba4a5 237 if (sbit<=0) {
uci1 21:ce51bb0ba4a5 238 dum >>= (-sbit+loseLSB+loseMSB);
uci1 21:ce51bb0ba4a5 239 dum <<= loseLSB;
uci1 21:ce51bb0ba4a5 240 *dev |= dum;
uci1 21:ce51bb0ba4a5 241 // add baseline and move to next number (dev++ in the for loop)
uci1 21:ce51bb0ba4a5 242 *dev += wvBaseline;
uci1 21:ce51bb0ba4a5 243 // but stay in this short of the buf (do not increment b)
uci1 21:ce51bb0ba4a5 244 // move starting bit up
uci1 21:ce51bb0ba4a5 245 sbit += packSmpBits;
uci1 21:ce51bb0ba4a5 246 } else {
uci1 21:ce51bb0ba4a5 247 dum <<= sbit;
uci1 21:ce51bb0ba4a5 248 dum >>= loseMSB+loseLSB;
uci1 21:ce51bb0ba4a5 249 dum <<= loseLSB;
uci1 21:ce51bb0ba4a5 250 *dev = dum;
uci1 21:ce51bb0ba4a5 251 if ( (sbit+packSmpBits) >= BITS_IN_SHORT ) {
uci1 21:ce51bb0ba4a5 252 b+=2; // move to next short in the buf
uci1 21:ce51bb0ba4a5 253 i--; dev--; // but stay on this number
uci1 21:ce51bb0ba4a5 254 // move starting bit back into the short we just read from
uci1 21:ce51bb0ba4a5 255 sbit -= BITS_IN_SHORT;
uci1 21:ce51bb0ba4a5 256 } else {
uci1 21:ce51bb0ba4a5 257 // add baseline and move to next number (dev++ in the for loop)
uci1 21:ce51bb0ba4a5 258 *dev += wvBaseline;
uci1 21:ce51bb0ba4a5 259 sbit += packSmpBits;
uci1 21:ce51bb0ba4a5 260 }
uci1 21:ce51bb0ba4a5 261 }
uci1 21:ce51bb0ba4a5 262 }
uci1 21:ce51bb0ba4a5 263 }
uci1 21:ce51bb0ba4a5 264
uci1 21:ce51bb0ba4a5 265 return buf+SizeOfPackedWavef(loseLSB, loseMSB);
uci1 21:ce51bb0ba4a5 266 }
uci1 21:ce51bb0ba4a5 267