Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Thu Oct 30 06:42:17 2014 +0000
Revision:
56:0bba0ef15697
Parent:
54:ea1234a44fe8
Child:
59:21128cc24b04
update ext libs, add tempr, allow SST/ATWD, improve handshaking, run/seq list, req seq range, allow SBD only in low pwr, all pins start off, can collect data to ram w/o SD card, add parameters to status update

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 31:b5bd3b189150 11 bool SnConfigFrame::fgApplySafetyNets = true;
uci1 56:0bba0ef15697 12 #if CHIPBOARD==ATWD4CH
uci1 40:1324da35afd4 13 const uint8_t SnConfigFrame::kIOVers = 8;
uci1 56:0bba0ef15697 14 #else // SST
uci1 56:0bba0ef15697 15 const uint8_t SnConfigFrame::kIOVers = 10;
uci1 56:0bba0ef15697 16 #endif
uci1 3:24c5f0f50bf1 17 const char* const SnConfigFrame::kDefConfFile = "/local/DEFCONF.DAT";
uci1 28:484943132bb0 18 const char* const SnConfigFrame::kDefIPflag = "DEF";
uci1 1:e392595b4b76 19 const uint32_t SnConfigFrame::kMinCommWinPrdLowPwr = 14400; // exclusive min low power comm win period (s)
uci1 1:e392595b4b76 20 const uint32_t SnConfigFrame::kMaxCommWinPrdLowPwr = 259200; // exclusive max low power comm win period (s)
uci1 1:e392595b4b76 21 const uint32_t SnConfigFrame::kMinCommWinDurLowPwr = 300; // exclusive min low power comm win duration (s)
uci1 1:e392595b4b76 22 const uint32_t SnConfigFrame::kMaxCommWinDurLowPwr = 3600; // exclusive max low power comm win duration (s)
uci1 1:e392595b4b76 23 const uint8_t SnConfigFrame::kConfLblLen;
uci1 0:664899e0b988 24
uci1 0:664899e0b988 25 uint64_t SnConfigFrame::fgMacAdr = 0;
uci1 0:664899e0b988 26
uci1 0:664899e0b988 27 void SnConfigFrame::SetMacAddress() {
uci1 0:664899e0b988 28 static const uint8_t b64 = sizeof(uint64_t);
uci1 0:664899e0b988 29 static char c[b64];
uci1 0:664899e0b988 30 mbed_mac_address(&(c[0]));
uci1 0:664899e0b988 31 // like a big endian union
uci1 0:664899e0b988 32 fgMacAdr = 0;
uci1 0:664899e0b988 33 const char* a = c+(b64-1);
uci1 0:664899e0b988 34 for (uint8_t i=0; i<b64; i++, a--) {
uci1 0:664899e0b988 35 fgMacAdr |= static_cast<uint64_t>(*a) << (i<<3);
uci1 0:664899e0b988 36 }
uci1 0:664899e0b988 37 }
uci1 0:664899e0b988 38
uci1 0:664899e0b988 39 void SnConfigFrame::SetHardDefaults() {
uci1 0:664899e0b988 40 sprintf(fLabel,"HardDefaults");
uci1 0:664899e0b988 41 fConfTime = 1338854400u; // Tue, 05 Jun 2012 00:00:00 GMT
uci1 0:664899e0b988 42 fRun = 0;
uci1 40:1324da35afd4 43 fFirstSeq = 0;
uci1 54:ea1234a44fe8 44 fEvtsPerSeq = 300;
uci1 8:95a325df1f6b 45 fRunMode = 0;
uci1 56:0bba0ef15697 46 #if CHIPBOARD==ATWD4CH
uci1 1:e392595b4b76 47 fStreamHiLoPlas = 0;
uci1 56:0bba0ef15697 48 #endif
uci1 0:664899e0b988 49 fWvLoseLSB = 0;
uci1 1:e392595b4b76 50 fWvLoseMSB = 4;
uci1 0:664899e0b988 51 fWvBaseline = 0;
uci1 0:664899e0b988 52 fDatPackType = ~0;
uci1 0:664899e0b988 53 uint16_t* dc = &(fDAC[0][0]);
uci1 0:664899e0b988 54 for (uint16_t i=0; i<kTotDacs; i++, dc++) {
uci1 0:664899e0b988 55 *dc = 3072u;
uci1 0:664899e0b988 56 }
uci1 56:0bba0ef15697 57 #if CHIPBOARD==ATWD4CH
uci1 0:664899e0b988 58 fNumPlas = 1;
uci1 0:664899e0b988 59 uint16_t* pl = &(fPLA[0]);
uci1 0:664899e0b988 60 for (uint8_t j=0; j<kNplas; j++, pl++) {
uci1 0:664899e0b988 61 *pl = 0x7FFFu;
uci1 0:664899e0b988 62 }
uci1 56:0bba0ef15697 63 #endif
uci1 28:484943132bb0 64 fNumCardsMajLog = 2;
uci1 54:ea1234a44fe8 65 fEnableThermTrig = 0;
uci1 1:e392595b4b76 66 fForceTrigPeriod = 67u;
uci1 0:664899e0b988 67 fHeartBeatPeriod = 0;
uci1 0:664899e0b988 68 fAmpsOn = 0x0Fu;
uci1 0:664899e0b988 69 fEvtThrtlPeriodMs = 50u;
uci1 28:484943132bb0 70 fPowerMode = kAmpsDatTak|kCardDatTak|kAmpsComWin|kCardComWin|kIridComWin|kAfarComWin;
uci1 39:2f17131d22a5 71 fBatVoltToLowPwr = 0;
uci1 39:2f17131d22a5 72 fBatVoltFromLowPwr = 0;
uci1 28:484943132bb0 73 fVoltCheckPeriod = 600u;
uci1 54:ea1234a44fe8 74 fCommWinPeriod = 600u;
uci1 1:e392595b4b76 75 fCommWinDuration = 600u;
uci1 28:484943132bb0 76 fCommSendData = static_cast<int16_t>(kUseBits);
uci1 0:664899e0b988 77 fCommWinPrdLowPwr = 86100u;
uci1 0:664899e0b988 78 fCommWinDurLowPwr = 300u;
uci1 40:1324da35afd4 79 fCommWinConnectTOMin = 3u;
uci1 40:1324da35afd4 80 fCommWinListenTOMin = 3u;
uci1 22:f957c4f840ad 81 fWatchDogPeriod = WDFAILSAFE;
uci1 56:0bba0ef15697 82 fTempCheckPeriod = 0;
uci1 28:484943132bb0 83 SetDefaultIPs();
uci1 8:95a325df1f6b 84 fIsLowPower = false;
uci1 8:95a325df1f6b 85 memcpy(fNormLabel, fLabel, kConfLblLen);
uci1 8:95a325df1f6b 86 fNormPowerMode = fPowerMode;
uci1 8:95a325df1f6b 87
uci1 54:ea1234a44fe8 88 ApplyConnectListenSafetyNets();
uci1 8:95a325df1f6b 89 }
uci1 8:95a325df1f6b 90
uci1 28:484943132bb0 91 void SnConfigFrame::SetDefaultRemoteServ() {
uci1 28:484943132bb0 92 sprintf(fRemoteServer,"%s","128.195.204.151");
uci1 28:484943132bb0 93 }
uci1 28:484943132bb0 94
uci1 28:484943132bb0 95 void SnConfigFrame::SetDefaultRemotePort() {
uci1 28:484943132bb0 96 fRemotePort = 6655;
uci1 28:484943132bb0 97 }
uci1 28:484943132bb0 98
uci1 28:484943132bb0 99 void SnConfigFrame::SetDefaultMbedIP() {
uci1 28:484943132bb0 100 const uint64_t ip = GetMacAddress();
uci1 28:484943132bb0 101 switch (ip) {
uci1 28:484943132bb0 102 case 0x0002F7F0C3B60000: // station 3
uci1 28:484943132bb0 103 sprintf(fMbedIP,"%s","157.132.94.35");
uci1 28:484943132bb0 104 break;
uci1 28:484943132bb0 105 case 0x0002F7F0C41C0000: // station 4
uci1 28:484943132bb0 106 sprintf(fMbedIP,"%s","157.132.94.37");
uci1 28:484943132bb0 107 break;
uci1 53:9cc158391bea 108 /*
uci1 28:484943132bb0 109 case 0x0002F7F0AEE00000: // station 5
uci1 28:484943132bb0 110 sprintf(fMbedIP,"%s","157.132.94.39");
uci1 28:484943132bb0 111 break;
uci1 53:9cc158391bea 112 */
uci1 53:9cc158391bea 113 case 0x0002F7F0C61A0000: // station 10
uci1 53:9cc158391bea 114 sprintf(fMbedIP,"%s","157.132.94.39");
uci1 53:9cc158391bea 115 break;
uci1 28:484943132bb0 116 case 0x0002F7F0C4450000: // station 6
uci1 28:484943132bb0 117 sprintf(fMbedIP,"%s","157.132.94.41");
uci1 28:484943132bb0 118 break;
uci1 53:9cc158391bea 119 /*
uci1 28:484943132bb0 120 case 0x0002F7F0D2880000: // station 7
uci1 28:484943132bb0 121 sprintf(fMbedIP,"%s","157.132.94.43");
uci1 28:484943132bb0 122 break;
uci1 28:484943132bb0 123 case 0x0002F7F0C0F80000: // station 8
uci1 28:484943132bb0 124 sprintf(fMbedIP,"%s","157.132.94.45");
uci1 28:484943132bb0 125 break;
uci1 53:9cc158391bea 126 */
uci1 53:9cc158391bea 127 case 0x0002F7F175B70000: // station 11
uci1 53:9cc158391bea 128 sprintf(fMbedIP,"%s","157.132.94.43");
uci1 53:9cc158391bea 129 break;
uci1 53:9cc158391bea 130 case 0x0002F7F0C5610000: // station 12
uci1 53:9cc158391bea 131 sprintf(fMbedIP,"%s","157.132.94.45");
uci1 53:9cc158391bea 132 break;
uci1 28:484943132bb0 133 default: // what??
uci1 28:484943132bb0 134 sprintf(fMbedIP,"%s","157.132.94.30"); // anciet station
uci1 28:484943132bb0 135 break;
uci1 28:484943132bb0 136 };
uci1 28:484943132bb0 137 }
uci1 28:484943132bb0 138 // brian dornick 3107
uci1 28:484943132bb0 139 void SnConfigFrame::SetDefaultMaskIP() {
uci1 28:484943132bb0 140 sprintf(fMbedMask,"%s","255.255.255.0");
uci1 28:484943132bb0 141 }
uci1 28:484943132bb0 142
uci1 28:484943132bb0 143 void SnConfigFrame::SetDefaultGateIP() {
uci1 28:484943132bb0 144 sprintf(fMbedGate,"%s","157.132.94.1");
uci1 28:484943132bb0 145 }
uci1 28:484943132bb0 146
uci1 28:484943132bb0 147 void SnConfigFrame::SetDefaultIPs() {
uci1 28:484943132bb0 148 SetDefaultRemoteServ();
uci1 28:484943132bb0 149 SetDefaultRemotePort();
uci1 28:484943132bb0 150 SetDefaultMbedIP();
uci1 28:484943132bb0 151 SetDefaultMaskIP();
uci1 28:484943132bb0 152 SetDefaultGateIP();
uci1 28:484943132bb0 153 }
uci1 28:484943132bb0 154
uci1 40:1324da35afd4 155 void SnConfigFrame::ApplyConnectListenSafetyNets() {
uci1 40:1324da35afd4 156 if (fCommWinConnectTOMin<kDefTimeoutMin) {
uci1 40:1324da35afd4 157 fCommWinConnectTOMin=kDefTimeoutMin;
uci1 40:1324da35afd4 158 }
uci1 56:0bba0ef15697 159 if (fCommWinConnectTOMin>(fCommWinDuration/(60.*static_cast<float>(kNcomms)))) {
uci1 40:1324da35afd4 160 fCommWinConnectTOMin=kDefTimeoutMin;
uci1 40:1324da35afd4 161 }
uci1 40:1324da35afd4 162 if (fCommWinListenTOMin<kDefTimeoutMin) {
uci1 40:1324da35afd4 163 fCommWinListenTOMin=kDefTimeoutMin;
uci1 40:1324da35afd4 164 }
uci1 56:0bba0ef15697 165 if (fCommWinListenTOMin>(fCommWinDuration/(60.*static_cast<float>(kNcomms)))) {
uci1 40:1324da35afd4 166 fCommWinListenTOMin=kDefTimeoutMin;
uci1 40:1324da35afd4 167 }
uci1 40:1324da35afd4 168 }
uci1 40:1324da35afd4 169
uci1 28:484943132bb0 170 void SnConfigFrame::ApplySafetyNets() {
uci1 40:1324da35afd4 171 if (fFirstSeq>kMaxFirstSeq) {
uci1 40:1324da35afd4 172 fFirstSeq=kMaxFirstSeq;
uci1 40:1324da35afd4 173 }
uci1 56:0bba0ef15697 174 #if CHIPBOARD==ATWD4CH
uci1 28:484943132bb0 175 if (fNumPlas>kNplas) {
uci1 28:484943132bb0 176 fNumPlas=kNplas;
uci1 28:484943132bb0 177 }
uci1 56:0bba0ef15697 178 #endif
uci1 28:484943132bb0 179 if (fNumCardsMajLog>kNchans) {
uci1 28:484943132bb0 180 fNumCardsMajLog=kNchans;
uci1 28:484943132bb0 181 }
uci1 28:484943132bb0 182 if (fNumCardsMajLog<1u) {
uci1 28:484943132bb0 183 fNumCardsMajLog=1u;
uci1 28:484943132bb0 184 }
uci1 28:484943132bb0 185 if ( (fForceTrigPeriod>0) &&
uci1 28:484943132bb0 186 (fForceTrigPeriod<kMinForcePer) ) {
uci1 28:484943132bb0 187 fForceTrigPeriod = kMinForcePer;
uci1 28:484943132bb0 188 }
uci1 28:484943132bb0 189 if (fEvtThrtlPeriodMs>kMaxThrottlePerMs) {
uci1 28:484943132bb0 190 fEvtThrtlPeriodMs=kMaxThrottlePerMs;
uci1 28:484943132bb0 191 }
uci1 28:484943132bb0 192 if ( (IsPoweredFor(kIridComWin)==false) &&
uci1 28:484943132bb0 193 (IsPoweredFor(kAfarComWin)==false) ) {
uci1 28:484943132bb0 194 EnablePowerFor(kIridComWin);
uci1 28:484943132bb0 195 EnablePowerFor(kAfarComWin);
uci1 28:484943132bb0 196 }
uci1 39:2f17131d22a5 197 if (fBatVoltToLowPwr>kMaxBatVoltLowPwr) {
uci1 39:2f17131d22a5 198 fBatVoltToLowPwr=kMaxBatVoltLowPwr;
uci1 39:2f17131d22a5 199 }
uci1 39:2f17131d22a5 200 if (fBatVoltFromLowPwr>kMaxBatVoltLowPwr) {
uci1 39:2f17131d22a5 201 fBatVoltFromLowPwr=kMaxBatVoltLowPwr;
uci1 39:2f17131d22a5 202 }
uci1 39:2f17131d22a5 203 if (fBatVoltFromLowPwr<fBatVoltToLowPwr) {
uci1 39:2f17131d22a5 204 fBatVoltFromLowPwr=fBatVoltToLowPwr;
uci1 28:484943132bb0 205 }
uci1 28:484943132bb0 206 if (fCommWinPeriod>kMaxCommWinPeriod) {
uci1 28:484943132bb0 207 fCommWinPeriod=kMaxCommWinPeriod;
uci1 28:484943132bb0 208 }
uci1 40:1324da35afd4 209 if (fCommWinPeriod<kMinCommWinPeriod) {
uci1 40:1324da35afd4 210 fCommWinPeriod=kMinCommWinPeriod;
uci1 40:1324da35afd4 211 }
uci1 28:484943132bb0 212 if (fCommWinDuration<kMinCommWinDur) {
uci1 28:484943132bb0 213 fCommWinDuration=kMinCommWinDur;
uci1 28:484943132bb0 214 }
uci1 28:484943132bb0 215 if (fCommWinPrdLowPwr>kMaxCommWinPeriod) {
uci1 28:484943132bb0 216 fCommWinPrdLowPwr=kMaxCommWinPeriod;
uci1 28:484943132bb0 217 }
uci1 28:484943132bb0 218 if (fCommWinDurLowPwr<kMinCommWinDur) {
uci1 28:484943132bb0 219 fCommWinDurLowPwr=kMinCommWinDur;
uci1 28:484943132bb0 220 }
uci1 40:1324da35afd4 221 ApplyConnectListenSafetyNets();
uci1 28:484943132bb0 222 if (fWatchDogPeriod>kMaxWatchDogPer) {
uci1 28:484943132bb0 223 fWatchDogPeriod=kMaxWatchDogPer;
uci1 28:484943132bb0 224 }
uci1 28:484943132bb0 225 if (fWatchDogPeriod<kMinWatchDogPer) {
uci1 28:484943132bb0 226 fWatchDogPeriod=kMinWatchDogPer;
uci1 28:484943132bb0 227 }
uci1 28:484943132bb0 228 }
uci1 28:484943132bb0 229
uci1 21:ce51bb0ba4a5 230 uint32_t SnConfigFrame::GetTimeoutTime(const uint32_t startTime,
uci1 21:ce51bb0ba4a5 231 const uint32_t delta) const {
uci1 40:1324da35afd4 232 // --.-----lst------.--delta--.--
uci1 40:1324da35afd4 233 // . . .
uci1 40:1324da35afd4 234 // start current returnVal
uci1 40:1324da35afd4 235 //
uci1 40:1324da35afd4 236 // lio=lst+delta bound by comm wind dur
uci1 40:1324da35afd4 237 // returns start + lio
uci1 40:1324da35afd4 238
uci1 21:ce51bb0ba4a5 239 const uint32_t ct = time(0);
uci1 40:1324da35afd4 240 uint32_t lst = ct-startTime;
uci1 21:ce51bb0ba4a5 241 if ( (ct<startTime) || (ct==0) ||
uci1 21:ce51bb0ba4a5 242 (lst>kSecsPerDay) ) {
uci1 21:ce51bb0ba4a5 243 // possible clock problems
uci1 40:1324da35afd4 244 lst = static_cast<uint32_t>(kDefTimeoutMin)*60u;
uci1 21:ce51bb0ba4a5 245 }
uci1 21:ce51bb0ba4a5 246 const uint32_t lio =
uci1 21:ce51bb0ba4a5 247 ((lst+delta) < GetCommWinDuration()) ?
uci1 21:ce51bb0ba4a5 248 lst+delta : GetCommWinDuration();
uci1 21:ce51bb0ba4a5 249 return lio+startTime;
uci1 21:ce51bb0ba4a5 250 }
uci1 21:ce51bb0ba4a5 251
uci1 8:95a325df1f6b 252 void SnConfigFrame::ChangeToLowPower() {
uci1 8:95a325df1f6b 253
uci1 8:95a325df1f6b 254 // save old label
uci1 8:95a325df1f6b 255 memcpy(fNormLabel, fLabel, kConfLblLen);
uci1 8:95a325df1f6b 256
uci1 8:95a325df1f6b 257 // append label
uci1 8:95a325df1f6b 258 // this will allow the new config to be put in the DB
uci1 8:95a325df1f6b 259 int slen = strlen(fLabel);
uci1 8:95a325df1f6b 260 static const char* tag = "_LOWPOW";
uci1 8:95a325df1f6b 261 const int ml = strlen(tag)+1;
uci1 8:95a325df1f6b 262 if (slen > (kConfLblLen-ml) ) {
uci1 8:95a325df1f6b 263 memset(fLabel+kConfLblLen-ml, '\0', ml);
uci1 8:95a325df1f6b 264 }
uci1 8:95a325df1f6b 265 strncat(fLabel, tag, ml-1);
uci1 8:95a325df1f6b 266
uci1 8:95a325df1f6b 267 // save power settings
uci1 8:95a325df1f6b 268 fNormPowerMode = fPowerMode;
uci1 8:95a325df1f6b 269
uci1 8:95a325df1f6b 270 // change power settings
uci1 8:95a325df1f6b 271 DisablePowerFor(kAmpsDatTak);
uci1 8:95a325df1f6b 272 DisablePowerFor(kCardDatTak);
uci1 8:95a325df1f6b 273 DisablePowerFor(kIridDatTak);
uci1 8:95a325df1f6b 274 DisablePowerFor(kAfarDatTak);
uci1 8:95a325df1f6b 275 DisablePowerFor(kAmpsComWin);
uci1 8:95a325df1f6b 276 DisablePowerFor(kCardComWin);
uci1 56:0bba0ef15697 277 if ( IsSBDonlyLowPwrMode() ) {
uci1 56:0bba0ef15697 278 EnablePowerFor(kIridComWin);
uci1 56:0bba0ef15697 279 DisablePowerFor(kAfarComWin);
uci1 56:0bba0ef15697 280 } else if ( (IsPoweredFor(kIridComWin)==false) &&
uci1 56:0bba0ef15697 281 (IsPoweredFor(kAfarComWin)==false) ) {
uci1 8:95a325df1f6b 282 // TODO: turn on only iridum maybe?
uci1 8:95a325df1f6b 283 EnablePowerFor(kIridComWin);
uci1 8:95a325df1f6b 284 EnablePowerFor(kAfarComWin);
uci1 56:0bba0ef15697 285 } // else same as normal for Irid and Afar Com Win
uci1 56:0bba0ef15697 286
uci1 8:95a325df1f6b 287 // set mode to low power
uci1 8:95a325df1f6b 288 fIsLowPower = true;
uci1 8:95a325df1f6b 289 }
uci1 8:95a325df1f6b 290
uci1 8:95a325df1f6b 291 void SnConfigFrame::ChangeToNormPower() {
uci1 8:95a325df1f6b 292 // put label back
uci1 8:95a325df1f6b 293 memcpy(fLabel, fNormLabel, kConfLblLen);
uci1 8:95a325df1f6b 294 // put power settings back
uci1 8:95a325df1f6b 295 fPowerMode = fNormPowerMode;
uci1 8:95a325df1f6b 296 // set mode to normal
uci1 8:95a325df1f6b 297 fIsLowPower = false;
uci1 0:664899e0b988 298 }
uci1 0:664899e0b988 299
uci1 0:664899e0b988 300 void SnConfigFrame::GetPackParsFor(const EDatPackBit d,
uci1 0:664899e0b988 301 uint8_t& loseLSB, uint8_t& loseMSB,
uci1 0:664899e0b988 302 uint16_t& wvBase) const {
uci1 0:664899e0b988 303 const bool pack = IsDatPackedFor(d);
uci1 0:664899e0b988 304 loseLSB = pack ? GetWvLoseLSB() : 0u;
uci1 0:664899e0b988 305 loseMSB = pack ? GetWvLoseMSB() : 0u;
uci1 0:664899e0b988 306 wvBase = pack ? GetWvBaseline() : 0u;
uci1 0:664899e0b988 307 }
uci1 0:664899e0b988 308
uci1 0:664899e0b988 309 void SnConfigFrame::GetHiLoPlas(const uint16_t pla,
uci1 0:664899e0b988 310 uint16_t& hiPla,
uci1 0:664899e0b988 311 uint16_t& loPla,
uci1 0:664899e0b988 312 const bool r2l) {
uci1 0:664899e0b988 313 // split the PLA bitword into 2: one for the high threshold
uci1 0:664899e0b988 314 // and one for the low threshold. "lows" in the string will become
uci1 0:664899e0b988 315 // "highs" in the low threshold PLA.
uci1 0:664899e0b988 316 //
uci1 0:664899e0b988 317 // example 1)
uci1 0:664899e0b988 318 // PLA string = HLHL....
uci1 0:664899e0b988 319 // hi thresh = H.H.....
uci1 0:664899e0b988 320 // lo thresh = .H.H....
uci1 0:664899e0b988 321 //
uci1 0:664899e0b988 322 // example 2)
uci1 0:664899e0b988 323 // PLA string = HBL.....
uci1 0:664899e0b988 324 // hi thresh = HL......
uci1 0:664899e0b988 325 // lo thresh = .LH.....
uci1 0:664899e0b988 326 //
uci1 0:664899e0b988 327 // (with . = A here, to make the example more readable)
uci1 0:664899e0b988 328 //
uci1 0:664899e0b988 329 // A = 11, B = 00
uci1 0:664899e0b988 330 // H = 01 or 10, alternating
uci1 0:664899e0b988 331 // L = 10 or 01, alternating
uci1 0:664899e0b988 332 // 01 at leftmost bits is H
uci1 0:664899e0b988 333 // for example:
uci1 0:664899e0b988 334 // 0x7FFF = 01 11 11 11 11 11 11 11
uci1 0:664899e0b988 335 // => HAAAAAAA for LEFT TO RIGHT
uci1 0:664899e0b988 336 // => AAAAAAAH for RIGHT TO LEFT
uci1 0:664899e0b988 337 // 0x56FF = 01 01 01 10 11 11 11 11
uci1 0:664899e0b988 338 // => HLHHAAAA for LEFT TO RIGHT
uci1 0:664899e0b988 339 // => AAAAHHLH for RIGHT TO LEFT
uci1 0:664899e0b988 340 //
uci1 0:664899e0b988 341 // so HHHHHHHH is
uci1 0:664899e0b988 342 // 01 10 01 10 01 10 01 10 always (r2l or l2r)
uci1 0:664899e0b988 343 //
uci1 0:664899e0b988 344 // r2l = whether to read bits right to left (true) or not (false)
uci1 0:664899e0b988 345 // Mahshid liked right to left
uci1 0:664899e0b988 346 // Liang liked left to right
uci1 0:664899e0b988 347 // so we allow for either
uci1 0:664899e0b988 348
uci1 0:664899e0b988 349 const int8_t start = (r2l) ? 0 : BITS_IN_SHORT-2;
uci1 0:664899e0b988 350 const int8_t end = (r2l) ? BITS_IN_SHORT : -2;
uci1 39:2f17131d22a5 351 const int8_t step = (r2l) ? 2 : -2;
uci1 0:664899e0b988 352
uci1 0:664899e0b988 353 uint8_t hi= (r2l) ? 0x2 : 0x1;
uci1 0:664899e0b988 354 uint8_t lo= (r2l) ? 0x1 : 0x2;
uci1 0:664899e0b988 355
uci1 0:664899e0b988 356 // set all bits to 0
uci1 0:664899e0b988 357 hiPla = 0;
uci1 0:664899e0b988 358 loPla = 0;
uci1 0:664899e0b988 359
uci1 0:664899e0b988 360 for (int8_t i=start; i!=end; i+=step, hi^=0x3, lo^=0x3) {
uci1 0:664899e0b988 361 const uint8_t b = (pla & (0x3<<i)) >> i;
uci1 0:664899e0b988 362 if (b==hi) {
uci1 0:664899e0b988 363 hiPla |= hi << i;
uci1 0:664899e0b988 364 loPla |= 0x3 << i;
uci1 0:664899e0b988 365 } else if (b==lo) {
uci1 0:664899e0b988 366 hiPla |= 0x3 << i;
uci1 0:664899e0b988 367 loPla |= hi << i;
uci1 0:664899e0b988 368 } else if (b==0x3) {
uci1 0:664899e0b988 369 // any
uci1 0:664899e0b988 370 hiPla |= 0x3 << i;
uci1 0:664899e0b988 371 loPla |= 0x3 << i;
uci1 0:664899e0b988 372 } else {
uci1 0:664899e0b988 373 // no check that b is something else.. should be impossible.
uci1 0:664899e0b988 374 // between
uci1 0:664899e0b988 375 hiPla |= lo << i;
uci1 0:664899e0b988 376 loPla |= lo << i;
uci1 0:664899e0b988 377 }
uci1 0:664899e0b988 378 }
uci1 0:664899e0b988 379
uci1 0:664899e0b988 380 }
uci1 0:664899e0b988 381
uci1 0:664899e0b988 382 bool SnConfigFrame::ReadFromFile(const char* cfile) {
uci1 0:664899e0b988 383 // intended only for reading default config file
uci1 0:664899e0b988 384
uci1 3:24c5f0f50bf1 385 /*
uci1 3:24c5f0f50bf1 386 DIR* d;
uci1 3:24c5f0f50bf1 387 struct dirent* dent;
uci1 3:24c5f0f50bf1 388 printf("files in /local:\r\n");
uci1 3:24c5f0f50bf1 389 if ( (d = opendir( "/local" ))!=NULL ) {
uci1 3:24c5f0f50bf1 390 while ( (dent = readdir(d))!=NULL ) {
uci1 3:24c5f0f50bf1 391 printf("%s\r\n",dent->d_name);
uci1 3:24c5f0f50bf1 392 }
uci1 3:24c5f0f50bf1 393 closedir(d);
uci1 3:24c5f0f50bf1 394 }
uci1 3:24c5f0f50bf1 395 */
uci1 56:0bba0ef15697 396 #ifdef DEBUG
uci1 56:0bba0ef15697 397 printf("trying to read config [%s]\r\n",cfile);
uci1 56:0bba0ef15697 398 #endif
uci1 0:664899e0b988 399 bool ret = false;
uci1 0:664899e0b988 400 FILE* cf = fopen(cfile,"rb");
uci1 0:664899e0b988 401 if (cf!=0) {
uci1 56:0bba0ef15697 402 #ifdef DEBUG
uci1 56:0bba0ef15697 403 printf("opened file\r\n");
uci1 56:0bba0ef15697 404 #endif
uci1 16:744ce85aede2 405 // check the header and file size to be
uci1 16:744ce85aede2 406 // protect a bit against corruption
uci1 16:744ce85aede2 407 uint8_t hc; uint32_t hl;
uci1 16:744ce85aede2 408 SnHeaderFrame::ReadFrom(cf, hc, hl);
uci1 56:0bba0ef15697 409 #ifdef DEBUG
uci1 56:0bba0ef15697 410 printf("hc=%hhu, hl=%u\r\n",hc,hl);
uci1 56:0bba0ef15697 411 #endif
uci1 16:744ce85aede2 412 if (hc==SnHeaderFrame::kConfigCode) {
uci1 16:744ce85aede2 413 const int fpos = ftell(cf);
uci1 16:744ce85aede2 414 // how many bytes?
uci1 16:744ce85aede2 415 fseek(cf, 0, SEEK_END); // go to end
uci1 16:744ce85aede2 416 const int fend = ftell(cf);
uci1 16:744ce85aede2 417 fseek(cf, fpos, SEEK_SET); // go back
uci1 56:0bba0ef15697 418
uci1 56:0bba0ef15697 419 #ifdef DEBUG
uci1 56:0bba0ef15697 420 printf("fend-fpos=%d-%d=%d\r\n",fend,fpos,fend-fpos);
uci1 56:0bba0ef15697 421 #endif
uci1 16:744ce85aede2 422 if (hl == fend-fpos) {
uci1 16:744ce85aede2 423 ReadFrom(cf);
uci1 16:744ce85aede2 424 ret = (ferror(cf)==0);
uci1 56:0bba0ef15697 425 #ifdef DEBUG
uci1 56:0bba0ef15697 426 printf("ret = %d\r\n",(int)ret);
uci1 56:0bba0ef15697 427 #endif
uci1 16:744ce85aede2 428 }
uci1 16:744ce85aede2 429 }
uci1 0:664899e0b988 430 fclose(cf);
uci1 0:664899e0b988 431 }
uci1 0:664899e0b988 432 return ret;
uci1 0:664899e0b988 433 }
uci1 0:664899e0b988 434
uci1 0:664899e0b988 435 bool SnConfigFrame::WriteToFile(const char* cfile) const {
uci1 0:664899e0b988 436 // intended only for writing default config file
uci1 0:664899e0b988 437
uci1 0:664899e0b988 438 bool ret = false;
uci1 0:664899e0b988 439 FILE* cf = fopen(cfile,"wb");
uci1 0:664899e0b988 440 if (cf!=0) {
uci1 0:664899e0b988 441 WriteTo(cf);
uci1 0:664899e0b988 442 ret = (ferror(cf)==0);
uci1 0:664899e0b988 443 fclose(cf);
uci1 0:664899e0b988 444 }
uci1 0:664899e0b988 445 return ret;
uci1 0:664899e0b988 446 }