Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Tue Oct 16 04:47:44 2012 +0000
Revision:
22:f957c4f840ad
Parent:
21:ce51bb0ba4a5
Child:
28:484943132bb0
USB comm only. Make firing of comm window independent of real time clock. Add heartbeat firing time to the data stream.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
uci1 0:664899e0b988 1 #include "SnConfigFrame.h"
uci1 0:664899e0b988 2
uci1 0:664899e0b988 3 #include "mbed.h"
uci1 0:664899e0b988 4
uci1 0:664899e0b988 5 #include "SnBitUtils.h"
uci1 16:744ce85aede2 6 #include "SnHeaderFrame.h"
uci1 22:f957c4f840ad 7 #include "Watchdog.h"
uci1 0:664899e0b988 8
uci1 0:664899e0b988 9 extern "C" void mbed_mac_address(char *);
uci1 0:664899e0b988 10
uci1 0:664899e0b988 11
uci1 18:55f1581f2ee4 12 const uint8_t SnConfigFrame::kIOVers = 4;
uci1 3:24c5f0f50bf1 13 const char* const SnConfigFrame::kDefConfFile = "/local/DEFCONF.DAT";
uci1 1:e392595b4b76 14 const uint32_t SnConfigFrame::kMinCommWinPrdLowPwr = 14400; // exclusive min low power comm win period (s)
uci1 1:e392595b4b76 15 const uint32_t SnConfigFrame::kMaxCommWinPrdLowPwr = 259200; // exclusive max low power comm win period (s)
uci1 1:e392595b4b76 16 const uint32_t SnConfigFrame::kMinCommWinDurLowPwr = 300; // exclusive min low power comm win duration (s)
uci1 1:e392595b4b76 17 const uint32_t SnConfigFrame::kMaxCommWinDurLowPwr = 3600; // exclusive max low power comm win duration (s)
uci1 1:e392595b4b76 18 const uint8_t SnConfigFrame::kConfLblLen;
uci1 0:664899e0b988 19
uci1 0:664899e0b988 20 uint64_t SnConfigFrame::fgMacAdr = 0;
uci1 0:664899e0b988 21
uci1 0:664899e0b988 22 void SnConfigFrame::SetMacAddress() {
uci1 0:664899e0b988 23 static const uint8_t b64 = sizeof(uint64_t);
uci1 0:664899e0b988 24 static char c[b64];
uci1 0:664899e0b988 25 mbed_mac_address(&(c[0]));
uci1 0:664899e0b988 26 // like a big endian union
uci1 0:664899e0b988 27 fgMacAdr = 0;
uci1 0:664899e0b988 28 const char* a = c+(b64-1);
uci1 0:664899e0b988 29 for (uint8_t i=0; i<b64; i++, a--) {
uci1 0:664899e0b988 30 fgMacAdr |= static_cast<uint64_t>(*a) << (i<<3);
uci1 0:664899e0b988 31 }
uci1 0:664899e0b988 32 }
uci1 0:664899e0b988 33
uci1 0:664899e0b988 34 void SnConfigFrame::SetHardDefaults() {
uci1 0:664899e0b988 35 sprintf(fLabel,"HardDefaults");
uci1 0:664899e0b988 36 fConfTime = 1338854400u; // Tue, 05 Jun 2012 00:00:00 GMT
uci1 0:664899e0b988 37 fRun = 0;
uci1 0:664899e0b988 38 fFirstEvt = 0;
uci1 8:95a325df1f6b 39 fEvtsPerSeq = 1000;
uci1 8:95a325df1f6b 40 fRunMode = 0;
uci1 1:e392595b4b76 41 fStreamHiLoPlas = 0;
uci1 0:664899e0b988 42 fWvLoseLSB = 0;
uci1 1:e392595b4b76 43 fWvLoseMSB = 4;
uci1 0:664899e0b988 44 fWvBaseline = 0;
uci1 0:664899e0b988 45 fDatPackType = ~0;
uci1 0:664899e0b988 46 uint16_t* dc = &(fDAC[0][0]);
uci1 0:664899e0b988 47 for (uint16_t i=0; i<kTotDacs; i++, dc++) {
uci1 0:664899e0b988 48 *dc = 3072u;
uci1 0:664899e0b988 49 }
uci1 0:664899e0b988 50 fNumPlas = 1;
uci1 0:664899e0b988 51 uint16_t* pl = &(fPLA[0]);
uci1 0:664899e0b988 52 for (uint8_t j=0; j<kNplas; j++, pl++) {
uci1 0:664899e0b988 53 *pl = 0x7FFFu;
uci1 0:664899e0b988 54 }
uci1 3:24c5f0f50bf1 55 fNumCardsMajLog = 1;
uci1 0:664899e0b988 56 fEnableThermTrig = 1;
uci1 1:e392595b4b76 57 fForceTrigPeriod = 67u;
uci1 0:664899e0b988 58 fHeartBeatPeriod = 0;
uci1 0:664899e0b988 59 fAmpsOn = 0x0Fu;
uci1 0:664899e0b988 60 fEvtThrtlPeriodMs = 50u;
uci1 4:a91682e19d6b 61 fPowerMode = kAmpsDatTak|kCardDatTak|kIridComWin|kAfarComWin;
uci1 0:664899e0b988 62 fBatVoltLowPwr = 0;
uci1 8:95a325df1f6b 63 fVoltCheckPeriod = 1200u;
uci1 0:664899e0b988 64 fCommWinPeriod = 3300u;
uci1 1:e392595b4b76 65 fCommWinDuration = 600u;
uci1 0:664899e0b988 66 fCommSendData = 0;
uci1 0:664899e0b988 67 fCommWinPrdLowPwr = 86100u;
uci1 0:664899e0b988 68 fCommWinDurLowPwr = 300u;
uci1 8:95a325df1f6b 69 sprintf(fRemoteServer,"%s","128.195.204.151");
uci1 8:95a325df1f6b 70 fRemotePort = 6655;
uci1 8:95a325df1f6b 71 sprintf(fMbedIP,"%s","128.195.204.148");
uci1 8:95a325df1f6b 72 sprintf(fMbedMask,"%s","255.255.255.0");
uci1 8:95a325df1f6b 73 sprintf(fMbedGate,"%s","128.195.204.1");
uci1 22:f957c4f840ad 74 fWatchDogPeriod = WDFAILSAFE;
uci1 8:95a325df1f6b 75
uci1 8:95a325df1f6b 76 fIsLowPower = false;
uci1 8:95a325df1f6b 77 memcpy(fNormLabel, fLabel, kConfLblLen);
uci1 8:95a325df1f6b 78 fNormPowerMode = fPowerMode;
uci1 8:95a325df1f6b 79
uci1 8:95a325df1f6b 80
uci1 8:95a325df1f6b 81 }
uci1 8:95a325df1f6b 82
uci1 21:ce51bb0ba4a5 83 uint32_t SnConfigFrame::GetTimeoutTime(const uint32_t startTime,
uci1 21:ce51bb0ba4a5 84 const uint32_t delta) const {
uci1 21:ce51bb0ba4a5 85 const uint32_t ct = time(0);
uci1 21:ce51bb0ba4a5 86 uint32_t lst = time(0)-startTime;
uci1 21:ce51bb0ba4a5 87 if ( (ct<startTime) || (ct==0) ||
uci1 21:ce51bb0ba4a5 88 (lst>kSecsPerDay) ) {
uci1 21:ce51bb0ba4a5 89 // possible clock problems
uci1 21:ce51bb0ba4a5 90 lst = kDefTimeout;
uci1 21:ce51bb0ba4a5 91 }
uci1 21:ce51bb0ba4a5 92 const uint32_t lio =
uci1 21:ce51bb0ba4a5 93 ((lst+delta) < GetCommWinDuration()) ?
uci1 21:ce51bb0ba4a5 94 lst+delta : GetCommWinDuration();
uci1 21:ce51bb0ba4a5 95 return lio+startTime;
uci1 21:ce51bb0ba4a5 96 }
uci1 21:ce51bb0ba4a5 97
uci1 8:95a325df1f6b 98 void SnConfigFrame::ChangeToLowPower() {
uci1 8:95a325df1f6b 99
uci1 8:95a325df1f6b 100 // save old label
uci1 8:95a325df1f6b 101 memcpy(fNormLabel, fLabel, kConfLblLen);
uci1 8:95a325df1f6b 102
uci1 8:95a325df1f6b 103 // append label
uci1 8:95a325df1f6b 104 // this will allow the new config to be put in the DB
uci1 8:95a325df1f6b 105 int slen = strlen(fLabel);
uci1 8:95a325df1f6b 106 static const char* tag = "_LOWPOW";
uci1 8:95a325df1f6b 107 const int ml = strlen(tag)+1;
uci1 8:95a325df1f6b 108 if (slen > (kConfLblLen-ml) ) {
uci1 8:95a325df1f6b 109 memset(fLabel+kConfLblLen-ml, '\0', ml);
uci1 8:95a325df1f6b 110 }
uci1 8:95a325df1f6b 111 strncat(fLabel, tag, ml-1);
uci1 8:95a325df1f6b 112
uci1 8:95a325df1f6b 113 // save power settings
uci1 8:95a325df1f6b 114 fNormPowerMode = fPowerMode;
uci1 8:95a325df1f6b 115
uci1 8:95a325df1f6b 116 // change power settings
uci1 8:95a325df1f6b 117 DisablePowerFor(kAmpsDatTak);
uci1 8:95a325df1f6b 118 DisablePowerFor(kCardDatTak);
uci1 8:95a325df1f6b 119 DisablePowerFor(kIridDatTak);
uci1 8:95a325df1f6b 120 DisablePowerFor(kAfarDatTak);
uci1 8:95a325df1f6b 121 DisablePowerFor(kAmpsComWin);
uci1 8:95a325df1f6b 122 DisablePowerFor(kCardComWin);
uci1 8:95a325df1f6b 123 if ( (IsPoweredFor(kIridComWin)==false) &&
uci1 8:95a325df1f6b 124 (IsPoweredFor(kAfarComWin)==false) ) {
uci1 8:95a325df1f6b 125 // TODO: turn on only iridum maybe?
uci1 8:95a325df1f6b 126 EnablePowerFor(kIridComWin);
uci1 8:95a325df1f6b 127 EnablePowerFor(kAfarComWin);
uci1 8:95a325df1f6b 128 }
uci1 8:95a325df1f6b 129 // set mode to low power
uci1 8:95a325df1f6b 130 fIsLowPower = true;
uci1 8:95a325df1f6b 131 }
uci1 8:95a325df1f6b 132
uci1 8:95a325df1f6b 133 void SnConfigFrame::ChangeToNormPower() {
uci1 8:95a325df1f6b 134 // put label back
uci1 8:95a325df1f6b 135 memcpy(fLabel, fNormLabel, kConfLblLen);
uci1 8:95a325df1f6b 136 // put power settings back
uci1 8:95a325df1f6b 137 fPowerMode = fNormPowerMode;
uci1 8:95a325df1f6b 138 // set mode to normal
uci1 8:95a325df1f6b 139 fIsLowPower = false;
uci1 0:664899e0b988 140 }
uci1 0:664899e0b988 141
uci1 0:664899e0b988 142 void SnConfigFrame::GetPackParsFor(const EDatPackBit d,
uci1 0:664899e0b988 143 uint8_t& loseLSB, uint8_t& loseMSB,
uci1 0:664899e0b988 144 uint16_t& wvBase) const {
uci1 0:664899e0b988 145 const bool pack = IsDatPackedFor(d);
uci1 0:664899e0b988 146 loseLSB = pack ? GetWvLoseLSB() : 0u;
uci1 0:664899e0b988 147 loseMSB = pack ? GetWvLoseMSB() : 0u;
uci1 0:664899e0b988 148 wvBase = pack ? GetWvBaseline() : 0u;
uci1 0:664899e0b988 149 }
uci1 0:664899e0b988 150
uci1 0:664899e0b988 151 void SnConfigFrame::GetHiLoPlas(const uint16_t pla,
uci1 0:664899e0b988 152 uint16_t& hiPla,
uci1 0:664899e0b988 153 uint16_t& loPla,
uci1 0:664899e0b988 154 const bool r2l) {
uci1 0:664899e0b988 155 // split the PLA bitword into 2: one for the high threshold
uci1 0:664899e0b988 156 // and one for the low threshold. "lows" in the string will become
uci1 0:664899e0b988 157 // "highs" in the low threshold PLA.
uci1 0:664899e0b988 158 //
uci1 0:664899e0b988 159 // example 1)
uci1 0:664899e0b988 160 // PLA string = HLHL....
uci1 0:664899e0b988 161 // hi thresh = H.H.....
uci1 0:664899e0b988 162 // lo thresh = .H.H....
uci1 0:664899e0b988 163 //
uci1 0:664899e0b988 164 // example 2)
uci1 0:664899e0b988 165 // PLA string = HBL.....
uci1 0:664899e0b988 166 // hi thresh = HL......
uci1 0:664899e0b988 167 // lo thresh = .LH.....
uci1 0:664899e0b988 168 //
uci1 0:664899e0b988 169 // (with . = A here, to make the example more readable)
uci1 0:664899e0b988 170 //
uci1 0:664899e0b988 171 // A = 11, B = 00
uci1 0:664899e0b988 172 // H = 01 or 10, alternating
uci1 0:664899e0b988 173 // L = 10 or 01, alternating
uci1 0:664899e0b988 174 // 01 at leftmost bits is H
uci1 0:664899e0b988 175 // for example:
uci1 0:664899e0b988 176 // 0x7FFF = 01 11 11 11 11 11 11 11
uci1 0:664899e0b988 177 // => HAAAAAAA for LEFT TO RIGHT
uci1 0:664899e0b988 178 // => AAAAAAAH for RIGHT TO LEFT
uci1 0:664899e0b988 179 // 0x56FF = 01 01 01 10 11 11 11 11
uci1 0:664899e0b988 180 // => HLHHAAAA for LEFT TO RIGHT
uci1 0:664899e0b988 181 // => AAAAHHLH for RIGHT TO LEFT
uci1 0:664899e0b988 182 //
uci1 0:664899e0b988 183 // so HHHHHHHH is
uci1 0:664899e0b988 184 // 01 10 01 10 01 10 01 10 always (r2l or l2r)
uci1 0:664899e0b988 185 //
uci1 0:664899e0b988 186 // r2l = whether to read bits right to left (true) or not (false)
uci1 0:664899e0b988 187 // Mahshid liked right to left
uci1 0:664899e0b988 188 // Liang liked left to right
uci1 0:664899e0b988 189 // so we allow for either
uci1 0:664899e0b988 190
uci1 0:664899e0b988 191 const int8_t start = (r2l) ? 0 : BITS_IN_SHORT-2;
uci1 0:664899e0b988 192 const int8_t end = (r2l) ? BITS_IN_SHORT : -2;
uci1 0:664899e0b988 193 const int8_t step = (r2l) ? 2 : -2;
uci1 0:664899e0b988 194
uci1 0:664899e0b988 195 uint8_t hi= (r2l) ? 0x2 : 0x1;
uci1 0:664899e0b988 196 uint8_t lo= (r2l) ? 0x1 : 0x2;
uci1 0:664899e0b988 197
uci1 0:664899e0b988 198 // set all bits to 0
uci1 0:664899e0b988 199 hiPla = 0;
uci1 0:664899e0b988 200 loPla = 0;
uci1 0:664899e0b988 201
uci1 0:664899e0b988 202 for (int8_t i=start; i!=end; i+=step, hi^=0x3, lo^=0x3) {
uci1 0:664899e0b988 203 const uint8_t b = (pla & (0x3<<i)) >> i;
uci1 0:664899e0b988 204 if (b==hi) {
uci1 0:664899e0b988 205 hiPla |= hi << i;
uci1 0:664899e0b988 206 loPla |= 0x3 << i;
uci1 0:664899e0b988 207 } else if (b==lo) {
uci1 0:664899e0b988 208 hiPla |= 0x3 << i;
uci1 0:664899e0b988 209 loPla |= hi << i;
uci1 0:664899e0b988 210 } else if (b==0x3) {
uci1 0:664899e0b988 211 // any
uci1 0:664899e0b988 212 hiPla |= 0x3 << i;
uci1 0:664899e0b988 213 loPla |= 0x3 << i;
uci1 0:664899e0b988 214 } else {
uci1 0:664899e0b988 215 // no check that b is something else.. should be impossible.
uci1 0:664899e0b988 216 // between
uci1 0:664899e0b988 217 hiPla |= lo << i;
uci1 0:664899e0b988 218 loPla |= lo << i;
uci1 0:664899e0b988 219 }
uci1 0:664899e0b988 220 }
uci1 0:664899e0b988 221
uci1 0:664899e0b988 222 }
uci1 0:664899e0b988 223
uci1 0:664899e0b988 224 bool SnConfigFrame::ReadFromFile(const char* cfile) {
uci1 0:664899e0b988 225 // intended only for reading default config file
uci1 0:664899e0b988 226
uci1 3:24c5f0f50bf1 227 /*
uci1 3:24c5f0f50bf1 228 DIR* d;
uci1 3:24c5f0f50bf1 229 struct dirent* dent;
uci1 3:24c5f0f50bf1 230 printf("files in /local:\r\n");
uci1 3:24c5f0f50bf1 231 if ( (d = opendir( "/local" ))!=NULL ) {
uci1 3:24c5f0f50bf1 232 while ( (dent = readdir(d))!=NULL ) {
uci1 3:24c5f0f50bf1 233 printf("%s\r\n",dent->d_name);
uci1 3:24c5f0f50bf1 234 }
uci1 3:24c5f0f50bf1 235 closedir(d);
uci1 3:24c5f0f50bf1 236 }
uci1 3:24c5f0f50bf1 237 */
uci1 0:664899e0b988 238 bool ret = false;
uci1 0:664899e0b988 239 FILE* cf = fopen(cfile,"rb");
uci1 0:664899e0b988 240 if (cf!=0) {
uci1 16:744ce85aede2 241 // check the header and file size to be
uci1 16:744ce85aede2 242 // protect a bit against corruption
uci1 16:744ce85aede2 243 uint8_t hc; uint32_t hl;
uci1 16:744ce85aede2 244 SnHeaderFrame::ReadFrom(cf, hc, hl);
uci1 16:744ce85aede2 245 if (hc==SnHeaderFrame::kConfigCode) {
uci1 16:744ce85aede2 246 const int fpos = ftell(cf);
uci1 16:744ce85aede2 247 // how many bytes?
uci1 16:744ce85aede2 248 fseek(cf, 0, SEEK_END); // go to end
uci1 16:744ce85aede2 249 const int fend = ftell(cf);
uci1 16:744ce85aede2 250 fseek(cf, fpos, SEEK_SET); // go back
uci1 16:744ce85aede2 251
uci1 16:744ce85aede2 252 if (hl == fend-fpos) {
uci1 16:744ce85aede2 253 ReadFrom(cf);
uci1 16:744ce85aede2 254 ret = (ferror(cf)==0);
uci1 16:744ce85aede2 255 }
uci1 16:744ce85aede2 256 }
uci1 0:664899e0b988 257 fclose(cf);
uci1 0:664899e0b988 258 }
uci1 0:664899e0b988 259 return ret;
uci1 0:664899e0b988 260 }
uci1 0:664899e0b988 261
uci1 0:664899e0b988 262 bool SnConfigFrame::WriteToFile(const char* cfile) const {
uci1 0:664899e0b988 263 // intended only for writing default config file
uci1 0:664899e0b988 264
uci1 0:664899e0b988 265 bool ret = false;
uci1 0:664899e0b988 266 FILE* cf = fopen(cfile,"wb");
uci1 0:664899e0b988 267 if (cf!=0) {
uci1 0:664899e0b988 268 WriteTo(cf);
uci1 0:664899e0b988 269 ret = (ferror(cf)==0);
uci1 0:664899e0b988 270 fclose(cf);
uci1 0:664899e0b988 271 }
uci1 0:664899e0b988 272 return ret;
uci1 0:664899e0b988 273 }