Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Wed Oct 30 21:15:33 2013 +0000
Revision:
42:ac162d15e578
Parent:
40:1324da35afd4
Child:
56:0bba0ef15697
no debug. afar and sbd enabled. twitter off (broken). fix so modserial does not use vtable. add CheckSignalStrength. fix Send to return bytes sent, not buffered. use SBD checksum and without union

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