Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Tue May 03 02:01:35 2016 +0000
Revision:
116:8099b754fbb4
Parent:
115:29f46e4b65d4
Child:
117:fd6798ba2e26
One program for all stns via UID/MAC lookup table or generation. Status sends number trg/evt and livetime, not rates. Add 512 sample evt and RFFT-LUTs. Add L1Scaledown trg bit. Allow skip SST reset at start. Fix dt at end of seq. End of comm signal.

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 59:21128cc24b04 5 //#define DEBUG
uci1 59:21128cc24b04 6
uci1 0:664899e0b988 7 #include "SnBitUtils.h"
uci1 16:744ce85aede2 8 #include "SnHeaderFrame.h"
uci1 22:f957c4f840ad 9 #include "Watchdog.h"
uci1 76:f8383f0292c2 10 #include "SnSDUtils.h"
uci1 0:664899e0b988 11
uci1 0:664899e0b988 12 extern "C" void mbed_mac_address(char *);
uci1 0:664899e0b988 13
uci1 31:b5bd3b189150 14 bool SnConfigFrame::fgApplySafetyNets = true;
uci1 56:0bba0ef15697 15 #if CHIPBOARD==ATWD4CH
uci1 84:80b15993944e 16 const uint8_t SnConfigFrame::kIOVers = 11;
uci1 114:554fa3a956b4 17 #elif CHIPBOARD==SST4CH
uci1 84:80b15993944e 18 const uint8_t SnConfigFrame::kIOVers = 12;
uci1 114:554fa3a956b4 19 #elif CHIPBOARD==SST4CH_1GHz
uci1 114:554fa3a956b4 20 const uint8_t SnConfigFrame::kIOVers = 13;
uci1 116:8099b754fbb4 21 #elif CHIPBOARD==SST4CH512
uci1 116:8099b754fbb4 22 const uint8_t SnConfigFrame::kIOVers = 14;
uci1 116:8099b754fbb4 23 #elif CHIPBOARD==SST4CH512_1GHz
uci1 116:8099b754fbb4 24 const uint8_t SnConfigFrame::kIOVers = 15;
uci1 114:554fa3a956b4 25 #else
uci1 114:554fa3a956b4 26 #error CHIPBOARD value not used in config frame i/o version
uci1 56:0bba0ef15697 27 #endif
uci1 67:ec999336fcd1 28
uci1 67:ec999336fcd1 29 #ifdef USE_INTERFACE_CHIP
uci1 3:24c5f0f50bf1 30 const char* const SnConfigFrame::kDefConfFile = "/local/DEFCONF.DAT";
uci1 59:21128cc24b04 31 const char* const SnConfigFrame::kDefRemIpFilen = "/local/REMOTIP.TXT";
uci1 59:21128cc24b04 32 const char* const SnConfigFrame::kDefRemPortFilen = "/local/REMOTPRT.TXT";
uci1 59:21128cc24b04 33 const char* const SnConfigFrame::kDefMbedIPFilen = "/local/MBEDIP.TXT";
uci1 59:21128cc24b04 34 const char* const SnConfigFrame::kDefMbedMaskFilen = "/local/MBEDMASK.TXT";
uci1 59:21128cc24b04 35 const char* const SnConfigFrame::kDefMbedGateFilen = "/local/MBEDGATE.TXT";
uci1 67:ec999336fcd1 36 #endif
uci1 67:ec999336fcd1 37
uci1 28:484943132bb0 38 const char* const SnConfigFrame::kDefIPflag = "DEF";
uci1 84:80b15993944e 39 const uint32_t SnConfigFrame::kDefIPvalue = 0;
uci1 1:e392595b4b76 40 const uint32_t SnConfigFrame::kMinCommWinPrdLowPwr = 14400; // exclusive min low power comm win period (s)
uci1 1:e392595b4b76 41 const uint32_t SnConfigFrame::kMaxCommWinPrdLowPwr = 259200; // exclusive max low power comm win period (s)
uci1 1:e392595b4b76 42 const uint32_t SnConfigFrame::kMinCommWinDurLowPwr = 300; // exclusive min low power comm win duration (s)
uci1 1:e392595b4b76 43 const uint32_t SnConfigFrame::kMaxCommWinDurLowPwr = 3600; // exclusive max low power comm win duration (s)
uci1 1:e392595b4b76 44 const uint8_t SnConfigFrame::kConfLblLen;
uci1 0:664899e0b988 45
uci1 0:664899e0b988 46 uint64_t SnConfigFrame::fgMacAdr = 0;
uci1 0:664899e0b988 47
uci1 0:664899e0b988 48 void SnConfigFrame::SetMacAddress() {
uci1 0:664899e0b988 49 static const uint8_t b64 = sizeof(uint64_t);
uci1 0:664899e0b988 50 static char c[b64];
uci1 67:ec999336fcd1 51 // NOTE: the function below may not be the one provided by MBED!
uci1 67:ec999336fcd1 52 // see main.cpp
uci1 0:664899e0b988 53 mbed_mac_address(&(c[0]));
uci1 0:664899e0b988 54 // like a big endian union
uci1 0:664899e0b988 55 fgMacAdr = 0;
uci1 0:664899e0b988 56 const char* a = c+(b64-1);
uci1 0:664899e0b988 57 for (uint8_t i=0; i<b64; i++, a--) {
uci1 0:664899e0b988 58 fgMacAdr |= static_cast<uint64_t>(*a) << (i<<3);
uci1 0:664899e0b988 59 }
uci1 67:ec999336fcd1 60 #ifdef DEBUG
uci1 67:ec999336fcd1 61 printf("MAC=%012llX\r\n", fgMacAdr>>16); // 64 -> 48 bits
uci1 67:ec999336fcd1 62 #endif
uci1 0:664899e0b988 63 }
uci1 0:664899e0b988 64
uci1 0:664899e0b988 65 void SnConfigFrame::SetHardDefaults() {
uci1 116:8099b754fbb4 66 sprintf(fLabel,"DefaultRev116");
uci1 0:664899e0b988 67 fConfTime = 1338854400u; // Tue, 05 Jun 2012 00:00:00 GMT
uci1 0:664899e0b988 68 fRun = 0;
uci1 40:1324da35afd4 69 fFirstSeq = 0;
uci1 54:ea1234a44fe8 70 fEvtsPerSeq = 300;
uci1 56:0bba0ef15697 71 #if CHIPBOARD==ATWD4CH
uci1 67:ec999336fcd1 72 fRunMode = kRSListOneCW;
uci1 1:e392595b4b76 73 fStreamHiLoPlas = 0;
uci1 67:ec999336fcd1 74 #else // not ATWD4CH
uci1 67:ec999336fcd1 75 fRunMode = kDualThreshBit | kDiffTrigBit | kRSListOneCW;
uci1 56:0bba0ef15697 76 #endif
uci1 0:664899e0b988 77 fWvLoseLSB = 0;
uci1 1:e392595b4b76 78 fWvLoseMSB = 4;
uci1 0:664899e0b988 79 fWvBaseline = 0;
uci1 84:80b15993944e 80 fDatPackType = kSDcard | kIrid | kAfar | kUSB; // starting with io vers 11+, this is no longer changeable
uci1 0:664899e0b988 81 uint16_t* dc = &(fDAC[0][0]);
uci1 0:664899e0b988 82 for (uint16_t i=0; i<kTotDacs; i++, dc++) {
uci1 0:664899e0b988 83 *dc = 3072u;
uci1 0:664899e0b988 84 }
uci1 56:0bba0ef15697 85 #if CHIPBOARD==ATWD4CH
uci1 0:664899e0b988 86 fNumPlas = 1;
uci1 0:664899e0b988 87 uint16_t* pl = &(fPLA[0]);
uci1 0:664899e0b988 88 for (uint8_t j=0; j<kNplas; j++, pl++) {
uci1 0:664899e0b988 89 *pl = 0x7FFFu;
uci1 0:664899e0b988 90 }
uci1 56:0bba0ef15697 91 #endif
uci1 28:484943132bb0 92 fNumCardsMajLog = 2;
uci1 54:ea1234a44fe8 93 fEnableThermTrig = 0;
uci1 67:ec999336fcd1 94 fForceTrigPeriod = 0;
uci1 0:664899e0b988 95 fHeartBeatPeriod = 0;
uci1 84:80b15993944e 96 //fAmpsOn = 0x0Fu; removed vers 11+
uci1 67:ec999336fcd1 97 fEvtThrtlPeriodMs = 0;
uci1 76:f8383f0292c2 98 fPowerMode = kIridComWin | kAfarComWin;
uci1 39:2f17131d22a5 99 fBatVoltToLowPwr = 0;
uci1 39:2f17131d22a5 100 fBatVoltFromLowPwr = 0;
uci1 67:ec999336fcd1 101 fVoltCheckPeriod = 127u;
uci1 54:ea1234a44fe8 102 fCommWinPeriod = 600u;
uci1 1:e392595b4b76 103 fCommWinDuration = 600u;
uci1 28:484943132bb0 104 fCommSendData = static_cast<int16_t>(kUseBits);
uci1 0:664899e0b988 105 fCommWinPrdLowPwr = 86100u;
uci1 0:664899e0b988 106 fCommWinDurLowPwr = 300u;
uci1 84:80b15993944e 107 for (uint8_t i=0; i<kNumDatStreams; ++i) {
uci1 85:3ced48ef94c5 108 fCommWinConnTOMins[i] = GetDefaultConnTOMinOf(GetDataStreamForIndex(i));
uci1 85:3ced48ef94c5 109 fCommWinListTOMins[i] = GetDefaultListTOMinOf(GetDataStreamForIndex(i));
uci1 84:80b15993944e 110 }
uci1 22:f957c4f840ad 111 fWatchDogPeriod = WDFAILSAFE;
uci1 67:ec999336fcd1 112 #if CHIPBOARD==ATWD4CH
uci1 84:80b15993944e 113 // fTempCheckPeriod = 0;
uci1 70:1cee873a35b6 114 #else // not ATWD4CH
uci1 70:1cee873a35b6 115 fTempCheckPeriod = -8;
uci1 67:ec999336fcd1 116 #endif
uci1 28:484943132bb0 117 SetDefaultIPs();
uci1 8:95a325df1f6b 118 fIsLowPower = false;
uci1 8:95a325df1f6b 119 memcpy(fNormLabel, fLabel, kConfLblLen);
uci1 8:95a325df1f6b 120 fNormPowerMode = fPowerMode;
uci1 8:95a325df1f6b 121
uci1 54:ea1234a44fe8 122 ApplyConnectListenSafetyNets();
uci1 8:95a325df1f6b 123 }
uci1 8:95a325df1f6b 124
uci1 28:484943132bb0 125 void SnConfigFrame::SetDefaultRemoteServ() {
uci1 59:21128cc24b04 126 if (false==ReadDefaultRemoteServer()) {
uci1 59:21128cc24b04 127 sprintf(fRemoteServer,"%s","128.195.204.151");
uci1 59:21128cc24b04 128 }
uci1 28:484943132bb0 129 }
uci1 28:484943132bb0 130
uci1 28:484943132bb0 131 void SnConfigFrame::SetDefaultRemotePort() {
uci1 59:21128cc24b04 132 if (false==ReadDefaultRemotePort()) {
uci1 59:21128cc24b04 133 fRemotePort = 6655;
uci1 59:21128cc24b04 134 }
uci1 28:484943132bb0 135 }
uci1 28:484943132bb0 136
uci1 28:484943132bb0 137 void SnConfigFrame::SetDefaultMbedIP() {
uci1 59:21128cc24b04 138 // see ReadDefaultIPFile
uci1 59:21128cc24b04 139 //
uci1 59:21128cc24b04 140 // these hardcoded defaults are only here
uci1 59:21128cc24b04 141 // "in case". they make it difficult/impossible
uci1 59:21128cc24b04 142 // to swap boards in the field without internet
uci1 59:21128cc24b04 143 // access to change the mbed program
uci1 28:484943132bb0 144 const uint64_t ip = GetMacAddress();
uci1 59:21128cc24b04 145 if (false==ReadDefaultMbedIP()) {
uci1 59:21128cc24b04 146 switch (ip) {
uci1 67:ec999336fcd1 147 case 0x0002F7F0AEE00000: // stn 20, atwd mb 1
uci1 67:ec999336fcd1 148 sprintf(fMbedIP,"%s","157.132.94.30");
uci1 67:ec999336fcd1 149 break;
uci1 59:21128cc24b04 150 case 0x0002F7F2244B0000: // stn 13, board 102
uci1 59:21128cc24b04 151 sprintf(fMbedIP,"%s","157.132.94.31");
uci1 59:21128cc24b04 152 break;
uci1 59:21128cc24b04 153 case 0x0002F7F20A9C0000: // stn 14, board 104
uci1 59:21128cc24b04 154 sprintf(fMbedIP,"%s","157.132.94.33");
uci1 59:21128cc24b04 155 break;
uci1 67:ec999336fcd1 156 case 0x0002F7F21A8A0000: // board 111
uci1 67:ec999336fcd1 157 sprintf(fMbedIP,"%s","157.132.94.34");
uci1 67:ec999336fcd1 158 break;
uci1 67:ec999336fcd1 159 case 0x0002F7F0C3B60000: // station 3, atwd mb 5
uci1 59:21128cc24b04 160 sprintf(fMbedIP,"%s","157.132.94.35");
uci1 59:21128cc24b04 161 break;
uci1 59:21128cc24b04 162 case 0x0002F7F0C41C0000: // station 4
uci1 67:ec999336fcd1 163 case 0x0002F7F1F7A80000: // stn 15, board 110
uci1 59:21128cc24b04 164 sprintf(fMbedIP,"%s","157.132.94.37");
uci1 59:21128cc24b04 165 break;
uci1 67:ec999336fcd1 166 case 0x0002F7F0C61A0000: // station 10, atwd mb 8
uci1 59:21128cc24b04 167 sprintf(fMbedIP,"%s","157.132.94.39");
uci1 59:21128cc24b04 168 break;
uci1 59:21128cc24b04 169 case 0x0002F7F0C4450000: // station 6
uci1 59:21128cc24b04 170 case 0x0002F7F1E9ED0000: // board 108
uci1 67:ec999336fcd1 171 case 0x0002F7F224440000: // stn 19, board 105
uci1 59:21128cc24b04 172 sprintf(fMbedIP,"%s","157.132.94.41");
uci1 59:21128cc24b04 173 break;
uci1 59:21128cc24b04 174 case 0x0002F7F175B70000: // station 11
uci1 67:ec999336fcd1 175 case 0x0002F7F202C10000: // stn 17, board 109
uci1 59:21128cc24b04 176 sprintf(fMbedIP,"%s","157.132.94.43");
uci1 59:21128cc24b04 177 break;
uci1 86:051a09841ca3 178 case 0x0002F7F1F6340000: // stn 31, board 107
uci1 86:051a09841ca3 179 sprintf(fMbedIP,"%s","157.132.94.47");
uci1 86:051a09841ca3 180 break;
uci1 86:051a09841ca3 181 case 0x0002F7F1F21A0000: // stn 32, board 112
uci1 86:051a09841ca3 182 sprintf(fMbedIP,"%s","157.132.94.48");
uci1 86:051a09841ca3 183 break;
uci1 86:051a09841ca3 184 case 0x0002F7F1F2120000: // stn 30, board 113
uci1 86:051a09841ca3 185 sprintf(fMbedIP,"%s","157.132.94.49");
uci1 86:051a09841ca3 186 break;
uci1 59:21128cc24b04 187 default: // what??
uci1 86:051a09841ca3 188 sprintf(fMbedIP,"%s","157.132.94.46"); // usually for tent
uci1 59:21128cc24b04 189 break;
uci1 59:21128cc24b04 190 };
uci1 59:21128cc24b04 191 }
uci1 28:484943132bb0 192 }
uci1 28:484943132bb0 193 // brian dornick 3107
uci1 28:484943132bb0 194 void SnConfigFrame::SetDefaultMaskIP() {
uci1 59:21128cc24b04 195 if (false==ReadDefaultMbedMask()) {
uci1 59:21128cc24b04 196 sprintf(fMbedMask,"%s","255.255.255.0");
uci1 59:21128cc24b04 197 }
uci1 28:484943132bb0 198 }
uci1 28:484943132bb0 199
uci1 28:484943132bb0 200 void SnConfigFrame::SetDefaultGateIP() {
uci1 59:21128cc24b04 201 if (false==ReadDefaultMbedGate()) {
uci1 59:21128cc24b04 202 sprintf(fMbedGate,"%s","157.132.94.1");
uci1 59:21128cc24b04 203 }
uci1 59:21128cc24b04 204 }
uci1 59:21128cc24b04 205
uci1 67:ec999336fcd1 206 #ifdef USE_INTERFACE_CHIP
uci1 59:21128cc24b04 207 bool SnConfigFrame::ReadOneIPFrom(const char* ipfname,
uci1 59:21128cc24b04 208 char* ipstr) {
uci1 59:21128cc24b04 209 bool ok = false;
uci1 59:21128cc24b04 210 FILE* ipf = fopen(ipfname, "r");
uci1 59:21128cc24b04 211 if (ipf!=0) {
uci1 59:21128cc24b04 212 uint8_t ipbytes[4] = {0,0,0,0};
uci1 59:21128cc24b04 213 const int nr = fscanf(ipf,"%hhu.%hhu.%hhu.%hhu\n",
uci1 59:21128cc24b04 214 &(ipbytes[0]), &(ipbytes[1]),
uci1 59:21128cc24b04 215 &(ipbytes[2]), &(ipbytes[3]));
uci1 59:21128cc24b04 216 if (4==nr) {
uci1 59:21128cc24b04 217 const int nc =
uci1 59:21128cc24b04 218 sprintf(ipstr,"%hhu.%hhu.%hhu.%hhu",
uci1 59:21128cc24b04 219 ipbytes[0], ipbytes[1],
uci1 59:21128cc24b04 220 ipbytes[2], ipbytes[3]);
uci1 59:21128cc24b04 221 ok = nc>0;
uci1 59:21128cc24b04 222 }
uci1 76:f8383f0292c2 223 fclose(ipf);
uci1 59:21128cc24b04 224 }
uci1 59:21128cc24b04 225 #ifdef DEBUG
uci1 59:21128cc24b04 226 printf("ReadOneIPInto : ipstr=[%s], ok=%d\r\n",
uci1 59:21128cc24b04 227 ipstr, (int)ok);
uci1 59:21128cc24b04 228 #endif
uci1 59:21128cc24b04 229 return ok;
uci1 59:21128cc24b04 230 }
uci1 67:ec999336fcd1 231 #endif
uci1 59:21128cc24b04 232
uci1 59:21128cc24b04 233 bool SnConfigFrame::ReadDefaultRemoteServer() {
uci1 67:ec999336fcd1 234 #ifdef USE_INTERFACE_CHIP
uci1 59:21128cc24b04 235 const bool ok = ReadOneIPFrom(kDefRemIpFilen, fRemoteServer);
uci1 59:21128cc24b04 236 #ifdef DEBUG
uci1 59:21128cc24b04 237 printf("remote = %s\r\n", fRemoteServer);
uci1 59:21128cc24b04 238 #endif
uci1 59:21128cc24b04 239 return ok;
uci1 67:ec999336fcd1 240 #else // do not USE_INTERFACE_CHIP
uci1 67:ec999336fcd1 241 return false;
uci1 67:ec999336fcd1 242 #endif // USE_INTERFACE_CHIP
uci1 59:21128cc24b04 243 }
uci1 59:21128cc24b04 244
uci1 59:21128cc24b04 245 bool SnConfigFrame::ReadDefaultRemotePort() {
uci1 67:ec999336fcd1 246 #ifdef USE_INTERFACE_CHIP
uci1 59:21128cc24b04 247 bool ok = false;
uci1 59:21128cc24b04 248 FILE* pf = fopen(kDefRemPortFilen, "r");
uci1 59:21128cc24b04 249 if (pf!=0) {
uci1 59:21128cc24b04 250 ok = (1==fscanf(pf, "%hu\n", &fRemotePort));
uci1 76:f8383f0292c2 251 fclose(pf);
uci1 59:21128cc24b04 252 }
uci1 59:21128cc24b04 253 #ifdef DEBUG
uci1 59:21128cc24b04 254 printf("port = %hu\r\n", fRemotePort);
uci1 59:21128cc24b04 255 #endif
uci1 59:21128cc24b04 256 return ok;
uci1 67:ec999336fcd1 257 #else // do not USE_INTERFACE_CHIP
uci1 67:ec999336fcd1 258 return false;
uci1 67:ec999336fcd1 259 #endif // USE_INTERFACE_CHIP
uci1 59:21128cc24b04 260 }
uci1 59:21128cc24b04 261
uci1 59:21128cc24b04 262 bool SnConfigFrame::ReadDefaultMbedIP() {
uci1 67:ec999336fcd1 263 #ifdef USE_INTERFACE_CHIP
uci1 59:21128cc24b04 264 const bool ok = ReadOneIPFrom(kDefMbedIPFilen, fMbedIP);
uci1 59:21128cc24b04 265 #ifdef DEBUG
uci1 59:21128cc24b04 266 printf("mbed = %s\r\n", fMbedIP);
uci1 59:21128cc24b04 267 #endif
uci1 59:21128cc24b04 268 return ok;
uci1 67:ec999336fcd1 269 #else // do not USE_INTERFACE_CHIP
uci1 67:ec999336fcd1 270 return false;
uci1 67:ec999336fcd1 271 #endif // USE_INTERFACE_CHIP
uci1 59:21128cc24b04 272 }
uci1 59:21128cc24b04 273
uci1 59:21128cc24b04 274 bool SnConfigFrame::ReadDefaultMbedMask() {
uci1 67:ec999336fcd1 275 #ifdef USE_INTERFACE_CHIP
uci1 59:21128cc24b04 276 const bool ok = ReadOneIPFrom(kDefMbedMaskFilen, fMbedMask);
uci1 59:21128cc24b04 277 #ifdef DEBUG
uci1 59:21128cc24b04 278 printf("mask = %s\r\n", fMbedMask);
uci1 59:21128cc24b04 279 #endif
uci1 59:21128cc24b04 280 return ok;
uci1 67:ec999336fcd1 281 #else // do not USE_INTERFACE_CHIP
uci1 67:ec999336fcd1 282 return false;
uci1 67:ec999336fcd1 283 #endif // USE_INTERFACE_CHIP
uci1 59:21128cc24b04 284 }
uci1 59:21128cc24b04 285
uci1 59:21128cc24b04 286 bool SnConfigFrame::ReadDefaultMbedGate() {
uci1 67:ec999336fcd1 287 #ifdef USE_INTERFACE_CHIP
uci1 59:21128cc24b04 288 const bool ok = ReadOneIPFrom(kDefMbedGateFilen, fMbedGate);
uci1 59:21128cc24b04 289 #ifdef DEBUG
uci1 59:21128cc24b04 290 printf("gate = %s\r\n", fMbedGate);
uci1 59:21128cc24b04 291 #endif
uci1 59:21128cc24b04 292 return ok;
uci1 67:ec999336fcd1 293 #else // do not USE_INTERFACE_CHIP
uci1 67:ec999336fcd1 294 return false;
uci1 67:ec999336fcd1 295 #endif // USE_INTERFACE_CHIP
uci1 59:21128cc24b04 296 }
uci1 59:21128cc24b04 297
uci1 28:484943132bb0 298
uci1 28:484943132bb0 299 void SnConfigFrame::SetDefaultIPs() {
uci1 59:21128cc24b04 300 GetMacAddress(); // just to make sure it gets read
uci1 67:ec999336fcd1 301 SetDefaultRemoteServ();
uci1 67:ec999336fcd1 302 SetDefaultRemotePort();
uci1 67:ec999336fcd1 303 SetDefaultMbedIP();
uci1 67:ec999336fcd1 304 SetDefaultMaskIP();
uci1 67:ec999336fcd1 305 SetDefaultGateIP();
uci1 28:484943132bb0 306 }
uci1 28:484943132bb0 307
uci1 84:80b15993944e 308 void SnConfigFrame::ApplyConnectListenSafetyNets(const uint8_t dataStreamIdx) {
uci1 84:80b15993944e 309 const float maxto_f = (fCommWinDuration/(60.*static_cast<float>(kNcomms)));
uci1 84:80b15993944e 310 const uint8_t maxto = (maxto_f < kDefTimeoutMin) ? kDefTimeoutMin :
uci1 84:80b15993944e 311 (maxto_f > 255.0) ? kDefTimeoutSafe : static_cast<uint8_t>(maxto_f);
uci1 84:80b15993944e 312 if (fCommWinConnTOMins[dataStreamIdx] < kDefTimeoutMin) {
uci1 84:80b15993944e 313 fCommWinConnTOMins[dataStreamIdx] = kDefTimeoutMin;
uci1 84:80b15993944e 314 }
uci1 84:80b15993944e 315 if (fCommWinConnTOMins[dataStreamIdx] > maxto) {
uci1 84:80b15993944e 316 fCommWinConnTOMins[dataStreamIdx] = maxto;
uci1 40:1324da35afd4 317 }
uci1 84:80b15993944e 318 if (fCommWinListTOMins[dataStreamIdx] < kDefTimeoutMin) {
uci1 84:80b15993944e 319 fCommWinListTOMins[dataStreamIdx] = kDefTimeoutMin;
uci1 84:80b15993944e 320 }
uci1 84:80b15993944e 321 if (fCommWinListTOMins[dataStreamIdx] > maxto) {
uci1 84:80b15993944e 322 fCommWinListTOMins[dataStreamIdx] = maxto;
uci1 40:1324da35afd4 323 }
uci1 84:80b15993944e 324 }
uci1 84:80b15993944e 325
uci1 84:80b15993944e 326 void SnConfigFrame::ApplyConnectListenSafetyNets() {
uci1 84:80b15993944e 327 for (uint8_t i=0; i<kNumDatStreams; ++i) {
uci1 84:80b15993944e 328 ApplyConnectListenSafetyNets(i);
uci1 40:1324da35afd4 329 }
uci1 40:1324da35afd4 330 }
uci1 40:1324da35afd4 331
uci1 28:484943132bb0 332 void SnConfigFrame::ApplySafetyNets() {
uci1 40:1324da35afd4 333 if (fFirstSeq>kMaxFirstSeq) {
uci1 40:1324da35afd4 334 fFirstSeq=kMaxFirstSeq;
uci1 40:1324da35afd4 335 }
uci1 56:0bba0ef15697 336 #if CHIPBOARD==ATWD4CH
uci1 28:484943132bb0 337 if (fNumPlas>kNplas) {
uci1 28:484943132bb0 338 fNumPlas=kNplas;
uci1 28:484943132bb0 339 }
uci1 56:0bba0ef15697 340 #endif
uci1 28:484943132bb0 341 if (fNumCardsMajLog>kNchans) {
uci1 28:484943132bb0 342 fNumCardsMajLog=kNchans;
uci1 28:484943132bb0 343 }
uci1 28:484943132bb0 344 if (fNumCardsMajLog<1u) {
uci1 28:484943132bb0 345 fNumCardsMajLog=1u;
uci1 28:484943132bb0 346 }
uci1 28:484943132bb0 347 if ( (fForceTrigPeriod>0) &&
uci1 28:484943132bb0 348 (fForceTrigPeriod<kMinForcePer) ) {
uci1 28:484943132bb0 349 fForceTrigPeriod = kMinForcePer;
uci1 28:484943132bb0 350 }
uci1 28:484943132bb0 351 if (fEvtThrtlPeriodMs>kMaxThrottlePerMs) {
uci1 28:484943132bb0 352 fEvtThrtlPeriodMs=kMaxThrottlePerMs;
uci1 28:484943132bb0 353 }
uci1 28:484943132bb0 354 if ( (IsPoweredFor(kIridComWin)==false) &&
uci1 28:484943132bb0 355 (IsPoweredFor(kAfarComWin)==false) ) {
uci1 28:484943132bb0 356 EnablePowerFor(kIridComWin);
uci1 28:484943132bb0 357 EnablePowerFor(kAfarComWin);
uci1 28:484943132bb0 358 }
uci1 39:2f17131d22a5 359 if (fBatVoltToLowPwr>kMaxBatVoltLowPwr) {
uci1 39:2f17131d22a5 360 fBatVoltToLowPwr=kMaxBatVoltLowPwr;
uci1 39:2f17131d22a5 361 }
uci1 39:2f17131d22a5 362 if (fBatVoltFromLowPwr>kMaxBatVoltLowPwr) {
uci1 39:2f17131d22a5 363 fBatVoltFromLowPwr=kMaxBatVoltLowPwr;
uci1 39:2f17131d22a5 364 }
uci1 39:2f17131d22a5 365 if (fBatVoltFromLowPwr<fBatVoltToLowPwr) {
uci1 39:2f17131d22a5 366 fBatVoltFromLowPwr=fBatVoltToLowPwr;
uci1 28:484943132bb0 367 }
uci1 28:484943132bb0 368 if (fCommWinPeriod>kMaxCommWinPeriod) {
uci1 28:484943132bb0 369 fCommWinPeriod=kMaxCommWinPeriod;
uci1 28:484943132bb0 370 }
uci1 40:1324da35afd4 371 if (fCommWinPeriod<kMinCommWinPeriod) {
uci1 40:1324da35afd4 372 fCommWinPeriod=kMinCommWinPeriod;
uci1 40:1324da35afd4 373 }
uci1 28:484943132bb0 374 if (fCommWinDuration<kMinCommWinDur) {
uci1 28:484943132bb0 375 fCommWinDuration=kMinCommWinDur;
uci1 28:484943132bb0 376 }
uci1 28:484943132bb0 377 if (fCommWinPrdLowPwr>kMaxCommWinPeriod) {
uci1 28:484943132bb0 378 fCommWinPrdLowPwr=kMaxCommWinPeriod;
uci1 28:484943132bb0 379 }
uci1 28:484943132bb0 380 if (fCommWinDurLowPwr<kMinCommWinDur) {
uci1 28:484943132bb0 381 fCommWinDurLowPwr=kMinCommWinDur;
uci1 28:484943132bb0 382 }
uci1 40:1324da35afd4 383 ApplyConnectListenSafetyNets();
uci1 28:484943132bb0 384 if (fWatchDogPeriod>kMaxWatchDogPer) {
uci1 28:484943132bb0 385 fWatchDogPeriod=kMaxWatchDogPer;
uci1 28:484943132bb0 386 }
uci1 28:484943132bb0 387 if (fWatchDogPeriod<kMinWatchDogPer) {
uci1 28:484943132bb0 388 fWatchDogPeriod=kMinWatchDogPer;
uci1 28:484943132bb0 389 }
uci1 116:8099b754fbb4 390 if (fSnglFreqRatio<kMinSingleFreqSuppRatio) {
uci1 116:8099b754fbb4 391 fSnglFreqRatio=kDefSingleFreqSuppRatio;
uci1 116:8099b754fbb4 392 }
uci1 116:8099b754fbb4 393 if (fSnglFreqRatio>kMaxSingleFreqSuppRatio) {
uci1 116:8099b754fbb4 394 fSnglFreqRatio=kDefSingleFreqSuppRatio;
uci1 116:8099b754fbb4 395 }
uci1 116:8099b754fbb4 396 #ifdef DEBUG
uci1 116:8099b754fbb4 397 printf("||||||||| safety: fSnglFreqRatio=%hhu\r\n", fSnglFreqRatio);
uci1 116:8099b754fbb4 398 #endif
uci1 28:484943132bb0 399 }
uci1 28:484943132bb0 400
uci1 21:ce51bb0ba4a5 401 uint32_t SnConfigFrame::GetTimeoutTime(const uint32_t startTime,
uci1 21:ce51bb0ba4a5 402 const uint32_t delta) const {
uci1 40:1324da35afd4 403 // --.-----lst------.--delta--.--
uci1 40:1324da35afd4 404 // . . .
uci1 40:1324da35afd4 405 // start current returnVal
uci1 40:1324da35afd4 406 //
uci1 40:1324da35afd4 407 // lio=lst+delta bound by comm wind dur
uci1 40:1324da35afd4 408 // returns start + lio
uci1 40:1324da35afd4 409
uci1 21:ce51bb0ba4a5 410 const uint32_t ct = time(0);
uci1 40:1324da35afd4 411 uint32_t lst = ct-startTime;
uci1 21:ce51bb0ba4a5 412 if ( (ct<startTime) || (ct==0) ||
uci1 21:ce51bb0ba4a5 413 (lst>kSecsPerDay) ) {
uci1 21:ce51bb0ba4a5 414 // possible clock problems
uci1 84:80b15993944e 415 lst = static_cast<uint32_t>(kDefTimeoutSafe)*60u;
uci1 21:ce51bb0ba4a5 416 }
uci1 21:ce51bb0ba4a5 417 const uint32_t lio =
uci1 21:ce51bb0ba4a5 418 ((lst+delta) < GetCommWinDuration()) ?
uci1 21:ce51bb0ba4a5 419 lst+delta : GetCommWinDuration();
uci1 21:ce51bb0ba4a5 420 return lio+startTime;
uci1 21:ce51bb0ba4a5 421 }
uci1 21:ce51bb0ba4a5 422
uci1 8:95a325df1f6b 423 void SnConfigFrame::ChangeToLowPower() {
uci1 8:95a325df1f6b 424
uci1 8:95a325df1f6b 425 // save old label
uci1 8:95a325df1f6b 426 memcpy(fNormLabel, fLabel, kConfLblLen);
uci1 8:95a325df1f6b 427
uci1 8:95a325df1f6b 428 // append label
uci1 8:95a325df1f6b 429 // this will allow the new config to be put in the DB
uci1 8:95a325df1f6b 430 int slen = strlen(fLabel);
uci1 8:95a325df1f6b 431 static const char* tag = "_LOWPOW";
uci1 8:95a325df1f6b 432 const int ml = strlen(tag)+1;
uci1 8:95a325df1f6b 433 if (slen > (kConfLblLen-ml) ) {
uci1 8:95a325df1f6b 434 memset(fLabel+kConfLblLen-ml, '\0', ml);
uci1 8:95a325df1f6b 435 }
uci1 8:95a325df1f6b 436 strncat(fLabel, tag, ml-1);
uci1 8:95a325df1f6b 437
uci1 8:95a325df1f6b 438 // save power settings
uci1 8:95a325df1f6b 439 fNormPowerMode = fPowerMode;
uci1 8:95a325df1f6b 440
uci1 8:95a325df1f6b 441 // change power settings
uci1 8:95a325df1f6b 442 DisablePowerFor(kAmpsDatTak);
uci1 8:95a325df1f6b 443 DisablePowerFor(kCardDatTak);
uci1 8:95a325df1f6b 444 DisablePowerFor(kIridDatTak);
uci1 8:95a325df1f6b 445 DisablePowerFor(kAfarDatTak);
uci1 8:95a325df1f6b 446 DisablePowerFor(kAmpsComWin);
uci1 8:95a325df1f6b 447 DisablePowerFor(kCardComWin);
uci1 56:0bba0ef15697 448 if ( IsSBDonlyLowPwrMode() ) {
uci1 56:0bba0ef15697 449 EnablePowerFor(kIridComWin);
uci1 56:0bba0ef15697 450 DisablePowerFor(kAfarComWin);
uci1 56:0bba0ef15697 451 } else if ( (IsPoweredFor(kIridComWin)==false) &&
uci1 56:0bba0ef15697 452 (IsPoweredFor(kAfarComWin)==false) ) {
uci1 8:95a325df1f6b 453 // TODO: turn on only iridum maybe?
uci1 8:95a325df1f6b 454 EnablePowerFor(kIridComWin);
uci1 8:95a325df1f6b 455 EnablePowerFor(kAfarComWin);
uci1 56:0bba0ef15697 456 } // else same as normal for Irid and Afar Com Win
uci1 56:0bba0ef15697 457
uci1 8:95a325df1f6b 458 // set mode to low power
uci1 8:95a325df1f6b 459 fIsLowPower = true;
uci1 84:80b15993944e 460
uci1 84:80b15993944e 461 if (fgApplySafetyNets) {
uci1 84:80b15993944e 462 ApplySafetyNets();
uci1 84:80b15993944e 463 }
uci1 8:95a325df1f6b 464 }
uci1 8:95a325df1f6b 465
uci1 8:95a325df1f6b 466 void SnConfigFrame::ChangeToNormPower() {
uci1 8:95a325df1f6b 467 // put label back
uci1 8:95a325df1f6b 468 memcpy(fLabel, fNormLabel, kConfLblLen);
uci1 8:95a325df1f6b 469 // put power settings back
uci1 8:95a325df1f6b 470 fPowerMode = fNormPowerMode;
uci1 8:95a325df1f6b 471 // set mode to normal
uci1 8:95a325df1f6b 472 fIsLowPower = false;
uci1 84:80b15993944e 473
uci1 84:80b15993944e 474 if (fgApplySafetyNets) {
uci1 84:80b15993944e 475 ApplySafetyNets();
uci1 84:80b15993944e 476 }
uci1 0:664899e0b988 477 }
uci1 0:664899e0b988 478
uci1 0:664899e0b988 479 void SnConfigFrame::GetPackParsFor(const EDatPackBit d,
uci1 0:664899e0b988 480 uint8_t& loseLSB, uint8_t& loseMSB,
uci1 0:664899e0b988 481 uint16_t& wvBase) const {
uci1 0:664899e0b988 482 const bool pack = IsDatPackedFor(d);
uci1 0:664899e0b988 483 loseLSB = pack ? GetWvLoseLSB() : 0u;
uci1 0:664899e0b988 484 loseMSB = pack ? GetWvLoseMSB() : 0u;
uci1 0:664899e0b988 485 wvBase = pack ? GetWvBaseline() : 0u;
uci1 0:664899e0b988 486 }
uci1 0:664899e0b988 487
uci1 0:664899e0b988 488 void SnConfigFrame::GetHiLoPlas(const uint16_t pla,
uci1 0:664899e0b988 489 uint16_t& hiPla,
uci1 0:664899e0b988 490 uint16_t& loPla,
uci1 0:664899e0b988 491 const bool r2l) {
uci1 0:664899e0b988 492 // split the PLA bitword into 2: one for the high threshold
uci1 0:664899e0b988 493 // and one for the low threshold. "lows" in the string will become
uci1 0:664899e0b988 494 // "highs" in the low threshold PLA.
uci1 0:664899e0b988 495 //
uci1 0:664899e0b988 496 // example 1)
uci1 0:664899e0b988 497 // PLA string = HLHL....
uci1 0:664899e0b988 498 // hi thresh = H.H.....
uci1 0:664899e0b988 499 // lo thresh = .H.H....
uci1 0:664899e0b988 500 //
uci1 0:664899e0b988 501 // example 2)
uci1 0:664899e0b988 502 // PLA string = HBL.....
uci1 0:664899e0b988 503 // hi thresh = HL......
uci1 0:664899e0b988 504 // lo thresh = .LH.....
uci1 0:664899e0b988 505 //
uci1 0:664899e0b988 506 // (with . = A here, to make the example more readable)
uci1 0:664899e0b988 507 //
uci1 0:664899e0b988 508 // A = 11, B = 00
uci1 0:664899e0b988 509 // H = 01 or 10, alternating
uci1 0:664899e0b988 510 // L = 10 or 01, alternating
uci1 0:664899e0b988 511 // 01 at leftmost bits is H
uci1 0:664899e0b988 512 // for example:
uci1 0:664899e0b988 513 // 0x7FFF = 01 11 11 11 11 11 11 11
uci1 0:664899e0b988 514 // => HAAAAAAA for LEFT TO RIGHT
uci1 0:664899e0b988 515 // => AAAAAAAH for RIGHT TO LEFT
uci1 0:664899e0b988 516 // 0x56FF = 01 01 01 10 11 11 11 11
uci1 0:664899e0b988 517 // => HLHHAAAA for LEFT TO RIGHT
uci1 0:664899e0b988 518 // => AAAAHHLH for RIGHT TO LEFT
uci1 0:664899e0b988 519 //
uci1 0:664899e0b988 520 // so HHHHHHHH is
uci1 0:664899e0b988 521 // 01 10 01 10 01 10 01 10 always (r2l or l2r)
uci1 0:664899e0b988 522 //
uci1 0:664899e0b988 523 // r2l = whether to read bits right to left (true) or not (false)
uci1 0:664899e0b988 524 // Mahshid liked right to left
uci1 0:664899e0b988 525 // Liang liked left to right
uci1 0:664899e0b988 526 // so we allow for either
uci1 0:664899e0b988 527
uci1 0:664899e0b988 528 const int8_t start = (r2l) ? 0 : BITS_IN_SHORT-2;
uci1 0:664899e0b988 529 const int8_t end = (r2l) ? BITS_IN_SHORT : -2;
uci1 39:2f17131d22a5 530 const int8_t step = (r2l) ? 2 : -2;
uci1 0:664899e0b988 531
uci1 0:664899e0b988 532 uint8_t hi= (r2l) ? 0x2 : 0x1;
uci1 0:664899e0b988 533 uint8_t lo= (r2l) ? 0x1 : 0x2;
uci1 0:664899e0b988 534
uci1 0:664899e0b988 535 // set all bits to 0
uci1 0:664899e0b988 536 hiPla = 0;
uci1 0:664899e0b988 537 loPla = 0;
uci1 0:664899e0b988 538
uci1 0:664899e0b988 539 for (int8_t i=start; i!=end; i+=step, hi^=0x3, lo^=0x3) {
uci1 0:664899e0b988 540 const uint8_t b = (pla & (0x3<<i)) >> i;
uci1 0:664899e0b988 541 if (b==hi) {
uci1 0:664899e0b988 542 hiPla |= hi << i;
uci1 0:664899e0b988 543 loPla |= 0x3 << i;
uci1 0:664899e0b988 544 } else if (b==lo) {
uci1 0:664899e0b988 545 hiPla |= 0x3 << i;
uci1 0:664899e0b988 546 loPla |= hi << i;
uci1 0:664899e0b988 547 } else if (b==0x3) {
uci1 0:664899e0b988 548 // any
uci1 0:664899e0b988 549 hiPla |= 0x3 << i;
uci1 0:664899e0b988 550 loPla |= 0x3 << i;
uci1 0:664899e0b988 551 } else {
uci1 0:664899e0b988 552 // no check that b is something else.. should be impossible.
uci1 0:664899e0b988 553 // between
uci1 0:664899e0b988 554 hiPla |= lo << i;
uci1 0:664899e0b988 555 loPla |= lo << i;
uci1 0:664899e0b988 556 }
uci1 0:664899e0b988 557 }
uci1 0:664899e0b988 558
uci1 0:664899e0b988 559 }
uci1 0:664899e0b988 560
uci1 0:664899e0b988 561 bool SnConfigFrame::ReadFromFile(const char* cfile) {
uci1 0:664899e0b988 562 // intended only for reading default config file
uci1 0:664899e0b988 563
uci1 3:24c5f0f50bf1 564 /*
uci1 3:24c5f0f50bf1 565 DIR* d;
uci1 3:24c5f0f50bf1 566 struct dirent* dent;
uci1 3:24c5f0f50bf1 567 printf("files in /local:\r\n");
uci1 3:24c5f0f50bf1 568 if ( (d = opendir( "/local" ))!=NULL ) {
uci1 3:24c5f0f50bf1 569 while ( (dent = readdir(d))!=NULL ) {
uci1 3:24c5f0f50bf1 570 printf("%s\r\n",dent->d_name);
uci1 3:24c5f0f50bf1 571 }
uci1 3:24c5f0f50bf1 572 closedir(d);
uci1 3:24c5f0f50bf1 573 }
uci1 3:24c5f0f50bf1 574 */
uci1 56:0bba0ef15697 575 #ifdef DEBUG
uci1 56:0bba0ef15697 576 printf("trying to read config [%s]\r\n",cfile);
uci1 56:0bba0ef15697 577 #endif
uci1 0:664899e0b988 578 bool ret = false;
uci1 0:664899e0b988 579 FILE* cf = fopen(cfile,"rb");
uci1 0:664899e0b988 580 if (cf!=0) {
uci1 56:0bba0ef15697 581 #ifdef DEBUG
uci1 56:0bba0ef15697 582 printf("opened file\r\n");
uci1 56:0bba0ef15697 583 #endif
uci1 16:744ce85aede2 584 // check the header and file size to be
uci1 16:744ce85aede2 585 // protect a bit against corruption
uci1 16:744ce85aede2 586 uint8_t hc; uint32_t hl;
uci1 16:744ce85aede2 587 SnHeaderFrame::ReadFrom(cf, hc, hl);
uci1 56:0bba0ef15697 588 #ifdef DEBUG
uci1 56:0bba0ef15697 589 printf("hc=%hhu, hl=%u\r\n",hc,hl);
uci1 56:0bba0ef15697 590 #endif
uci1 16:744ce85aede2 591 if (hc==SnHeaderFrame::kConfigCode) {
uci1 16:744ce85aede2 592 const int fpos = ftell(cf);
uci1 16:744ce85aede2 593 // how many bytes?
uci1 16:744ce85aede2 594 fseek(cf, 0, SEEK_END); // go to end
uci1 16:744ce85aede2 595 const int fend = ftell(cf);
uci1 16:744ce85aede2 596 fseek(cf, fpos, SEEK_SET); // go back
uci1 56:0bba0ef15697 597
uci1 56:0bba0ef15697 598 #ifdef DEBUG
uci1 56:0bba0ef15697 599 printf("fend-fpos=%d-%d=%d\r\n",fend,fpos,fend-fpos);
uci1 56:0bba0ef15697 600 #endif
uci1 16:744ce85aede2 601 if (hl == fend-fpos) {
uci1 16:744ce85aede2 602 ReadFrom(cf);
uci1 16:744ce85aede2 603 ret = (ferror(cf)==0);
uci1 56:0bba0ef15697 604 #ifdef DEBUG
uci1 56:0bba0ef15697 605 printf("ret = %d\r\n",(int)ret);
uci1 56:0bba0ef15697 606 #endif
uci1 16:744ce85aede2 607 }
uci1 16:744ce85aede2 608 }
uci1 0:664899e0b988 609 fclose(cf);
uci1 0:664899e0b988 610 }
uci1 0:664899e0b988 611 return ret;
uci1 0:664899e0b988 612 }
uci1 0:664899e0b988 613
uci1 0:664899e0b988 614 bool SnConfigFrame::WriteToFile(const char* cfile) const {
uci1 0:664899e0b988 615 // intended only for writing default config file
uci1 0:664899e0b988 616
uci1 0:664899e0b988 617 bool ret = false;
uci1 0:664899e0b988 618 FILE* cf = fopen(cfile,"wb");
uci1 0:664899e0b988 619 if (cf!=0) {
uci1 0:664899e0b988 620 WriteTo(cf);
uci1 0:664899e0b988 621 ret = (ferror(cf)==0);
uci1 0:664899e0b988 622 fclose(cf);
uci1 0:664899e0b988 623 }
uci1 0:664899e0b988 624 return ret;
uci1 76:f8383f0292c2 625 }
uci1 76:f8383f0292c2 626
uci1 76:f8383f0292c2 627 void SnConfigFrame::SetSDNeedToInitFlag() {
uci1 76:f8383f0292c2 628 // reset the SD card init cache, in case the SD ignore run mode changed
uci1 76:f8383f0292c2 629 SnSDUtils::SetDoNeedToInit();
uci1 76:f8383f0292c2 630 }
uci1 84:80b15993944e 631
uci1 84:80b15993944e 632 void SnConfigFrame::GetIpStrFromVal(const uint32_t ip,
uci1 84:80b15993944e 633 char(& str)[SnConfigFrame::kIPLen]) {
uci1 84:80b15993944e 634 if (ip==kDefIPvalue) {
uci1 84:80b15993944e 635 snprintf(str, kIPLen, kDefIPflag);
uci1 84:80b15993944e 636 } else {
uci1 84:80b15993944e 637 // little endian, but same method is used in ipToVal so the
uci1 84:80b15993944e 638 // conversions will be consistent on this machine, but of course,
uci1 84:80b15993944e 639 // the remote machine better send the right integer...
uci1 84:80b15993944e 640 union {
uci1 84:80b15993944e 641 uint8_t c[4];
uci1 84:80b15993944e 642 uint32_t u;
uci1 84:80b15993944e 643 } x;
uci1 84:80b15993944e 644 x.u = ip;
uci1 84:80b15993944e 645 snprintf(str, kIPLen, "%hhu.%hhu.%hhu.%hhu",
uci1 84:80b15993944e 646 x.c[3], x.c[2], x.c[1], x.c[0]);
uci1 84:80b15993944e 647 }
uci1 84:80b15993944e 648 }
uci1 84:80b15993944e 649
uci1 84:80b15993944e 650 uint32_t SnConfigFrame::GetIpValFromStr(const char(& str)[SnConfigFrame::kIPLen]) {
uci1 84:80b15993944e 651 if (strncmp(str, kDefIPflag, kIPLen)==0) {
uci1 84:80b15993944e 652 return kDefIPvalue;
uci1 84:80b15993944e 653 } else {
uci1 84:80b15993944e 654 union {
uci1 84:80b15993944e 655 uint8_t c[4];
uci1 84:80b15993944e 656 uint32_t u;
uci1 84:80b15993944e 657 } x;
uci1 84:80b15993944e 658 // 17 = space for terminating null
uci1 84:80b15993944e 659 // little endian, but same method is used in ipToVal so the
uci1 84:80b15993944e 660 // conversions will be consistent on this machine, but of course,
uci1 84:80b15993944e 661 // the remote machine better send the right integer...
uci1 84:80b15993944e 662 sscanf(str, "%hhu.%hhu.%hhu.%hhu",
uci1 84:80b15993944e 663 x.c+3, x.c+2, x.c+1, x.c);
uci1 84:80b15993944e 664 return x.u;
uci1 84:80b15993944e 665 }
uci1 84:80b15993944e 666 }