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