Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Wed Aug 08 23:27:37 2012 +0000
Revision:
8:95a325df1f6b
Parent:
3:24c5f0f50bf1
Child:
21:ce51bb0ba4a5
Check power for low pow running. Average power over 500 readings. Use RTOS timers instead of tickers. Allow data taking of events, power readings or both, even if cards are off. Bug in EthernetInterface prevents IPs being reset. Lots of debug output.

Who changed what in which revision?

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