Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Wed Oct 10 05:54:12 2012 +0000
Revision:
21:ce51bb0ba4a5
Parent:
8:95a325df1f6b
Child:
25:57b2627fe756
Uses USB comm. Fix rates calc. Power up/down ETH with Afar. Fix sending evt with status. Add num files and bytes of data to status. Can save a local file (i.e. reprogram MBED) via comms. Set config after each comm win (need if cards pow cycle).

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