Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Fri Oct 30 04:49:40 2015 +0000
Revision:
84:80b15993944e
Parent:
76:f8383f0292c2
Child:
97:9f3fe603e8b5
conf v11,12. ip to ints. write 64chr lbl. send status data packs. comm pwr as needed. comm each evt. conn/list TO separate afar, sbd. calc FFT, L1 trigger, L1 scaledown. pre-compl opts in own file. max comm fail 75. htbt and clock frames store vars.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
uci1 0:664899e0b988 1 #include "mbed.h"
uci1 56:0bba0ef15697 2
uci1 56:0bba0ef15697 3 const uint32_t gPowerOnTime( time(0) );
uci1 56:0bba0ef15697 4
uci1 22:f957c4f840ad 5 // start a watchdog as soon as possible
uci1 22:f957c4f840ad 6 #include "Watchdog.h"
uci1 22:f957c4f840ad 7 Watchdog::SnKickStarter gKickStarter(WDFAILSAFE);
uci1 0:664899e0b988 8
uci1 84:80b15993944e 9 // CHIPBOARD is defined in SnPreCompOptions.h
uci1 56:0bba0ef15697 10
uci1 0:664899e0b988 11 #include <stdint.h>
uci1 37:ff95e7070f26 12 #include "SnConstants.h"
uci1 37:ff95e7070f26 13
uci1 67:ec999336fcd1 14 #ifndef USE_INTERFACE_CHIP
uci1 67:ec999336fcd1 15 // to avoid calling the interface chip,
uci1 67:ec999336fcd1 16 // the mac address is hard coded (ugh!)
uci1 67:ec999336fcd1 17 extern "C" void mbed_mac_address(char * mac) {
uci1 67:ec999336fcd1 18 #ifdef DEBUG
uci1 67:ec999336fcd1 19 printf("calling MY mbed_mac_address\r\n");
uci1 67:ec999336fcd1 20 #endif
uci1 67:ec999336fcd1 21 memmove(mac, kDefaultMacAdress, sizeof(kDefaultMacAdress));
uci1 67:ec999336fcd1 22 };
uci1 67:ec999336fcd1 23 #endif
uci1 67:ec999336fcd1 24
uci1 84:80b15993944e 25 #ifdef DEBUG
uci1 84:80b15993944e 26 #include "SnMemMonitor.h"
uci1 84:80b15993944e 27 #endif
uci1 84:80b15993944e 28
uci1 0:664899e0b988 29 #include "SDFileSystem.h"
uci1 15:f2569d8e4176 30 #ifdef USE_MODSERIAL
uci1 41:d6f5e2f09e07 31 #define MODSERIAL_RX_BUF_SIZE 512
uci1 41:d6f5e2f09e07 32 #define MODSERIAL_TX_BUF_SIZE 512
uci1 0:664899e0b988 33 #include "MODSERIAL.h"
uci1 56:0bba0ef15697 34 #endif // USE_MODSERIAL
uci1 21:ce51bb0ba4a5 35 #include "FATDirHandle.h"
uci1 21:ce51bb0ba4a5 36 #include "EthernetPowerControl.h"
uci1 0:664899e0b988 37 #include "SnBitUtils.h"
uci1 0:664899e0b988 38 #include "SnSDUtils.h"
uci1 0:664899e0b988 39 #include "SnConfigFrame.h"
uci1 0:664899e0b988 40 #include "SnEventFrame.h"
uci1 0:664899e0b988 41 #include "SnStatusFrame.h"
uci1 2:e67f7c158087 42 #include "SnHeaderFrame.h"
uci1 22:f957c4f840ad 43 #include "SnHeartbeatFrame.h"
uci1 40:1324da35afd4 44 #include "SnClockSetFrame.h"
uci1 41:d6f5e2f09e07 45 #include "SnSignalStrengthFrame.h"
uci1 0:664899e0b988 46 #include "SnCommWin.h"
uci1 41:d6f5e2f09e07 47 #ifdef ENABLE_AFAR_COMM
uci1 18:55f1581f2ee4 48 #ifdef USE_ETH_INTERFACE
uci1 7:079617408fec 49 #include "SnCommAfarTCP.h"
uci1 18:55f1581f2ee4 50 #else
uci1 37:ff95e7070f26 51 #include "SnCommWinAfar.h"
uci1 28:484943132bb0 52 #ifdef ENABLE_AFAR_TWITTER
uci1 37:ff95e7070f26 53 #include "SnCommWinTwitter.h"
uci1 41:d6f5e2f09e07 54 #endif // ENABLE_AFAR_TWITTER
uci1 41:d6f5e2f09e07 55 #endif // USE_ETH_INTERFACE
uci1 41:d6f5e2f09e07 56 #endif // ENABLE_AFAR_COMM
uci1 41:d6f5e2f09e07 57 #ifdef ENABLE_USB_COMM
uci1 41:d6f5e2f09e07 58 #include "SnCommWinUsb.h"
uci1 56:0bba0ef15697 59 #endif // ENABLE_USB_COMM
uci1 41:d6f5e2f09e07 60 #ifdef ENABLE_SBD_COMM
uci1 37:ff95e7070f26 61 #include "SnCommWinSBD.h"
uci1 56:0bba0ef15697 62 #endif // ENABLE_SBD_COMM
uci1 41:d6f5e2f09e07 63 //#include "SnBase64.h"
uci1 8:95a325df1f6b 64 #ifdef USE_RTOS_TIMER
uci1 8:95a325df1f6b 65 #include "RtosTimer.h"
uci1 56:0bba0ef15697 66 #endif // USE_RTOS_TIMER
uci1 56:0bba0ef15697 67 #include "DS1820.h"
uci1 84:80b15993944e 68 #include "SnL1SingleFreqSupp.h"
uci1 0:664899e0b988 69
uci1 40:1324da35afd4 70 extern "C" void mbed_reset();
uci1 31:b5bd3b189150 71
uci1 0:664899e0b988 72 //
uci1 0:664899e0b988 73 // MBED PINS (ordered by number)
uci1 0:664899e0b988 74 //
uci1 0:664899e0b988 75 // leds (for debugging)
uci1 67:ec999336fcd1 76 DigitalOut led1(LED1,1);
uci1 67:ec999336fcd1 77 DigitalOut led2(LED2,1);
uci1 67:ec999336fcd1 78 DigitalOut led3(LED3,1);
uci1 67:ec999336fcd1 79 DigitalOut led4(LED4,1);
uci1 56:0bba0ef15697 80
uci1 56:0bba0ef15697 81 // Set up power pins - Note that it's Zero for "on" in ATWD2013, but high for "on" in SST2014
uci1 56:0bba0ef15697 82 #if CHIPBOARD==ATWD4CH
uci1 56:0bba0ef15697 83 DigitalOut PIN_turn_on_system(p17,1); // this turns off the system
uci1 56:0bba0ef15697 84 DigitalOut PIN_turn_on_amps(p25,1); // this turns off the amps
uci1 56:0bba0ef15697 85 #else
uci1 56:0bba0ef15697 86 DigitalOut PIN_turn_on_system(p17,0); // this turns off the system
uci1 56:0bba0ef15697 87 DigitalOut PIN_turn_on_amps(p25,0); // this turns off the amps
uci1 56:0bba0ef15697 88 #endif // ATWD4CH
uci1 15:f2569d8e4176 89 // SD card select
uci1 56:0bba0ef15697 90 DigitalOut PIN_SD_CS(p8,0);
uci1 56:0bba0ef15697 91 #if CHIPBOARD==ATWD4CH
uci1 0:664899e0b988 92 // Activate/select chip by falling edge
uci1 56:0bba0ef15697 93 DigitalOut PIN_ADC_CS(p9,0);
uci1 0:664899e0b988 94 // clock signal to activate PLA setting
uci1 56:0bba0ef15697 95 DigitalOut PIN_PLA_cs(p10,0);
uci1 56:0bba0ef15697 96 #else
uci1 56:0bba0ef15697 97 I2C PIN_i2c(p9, p10);
uci1 56:0bba0ef15697 98 #endif // ATWD4CH
uci1 0:664899e0b988 99 // To force a trigger
uci1 56:0bba0ef15697 100 DigitalOut PIN_forceTrigger(p11,0); //modification
uci1 0:664899e0b988 101 // To suppress thermal triggers
uci1 56:0bba0ef15697 102 DigitalOut PIN_enableThermTrig(p12,0);
uci1 56:0bba0ef15697 103 #if CHIPBOARD==ATWD4CH
uci1 0:664899e0b988 104 // Restart clock on all FPGAs.
uci1 56:0bba0ef15697 105 DigitalOut PIN_DoNotRestartAllClocks(p13,0);
uci1 56:0bba0ef15697 106 #else
uci1 56:0bba0ef15697 107 DigitalOut PIN_ResetChips(p13,0);
uci1 56:0bba0ef15697 108 #endif // ATWD4CH
uci1 56:0bba0ef15697 109 #if CHIPBOARD==ATWD4CH
uci1 0:664899e0b988 110 // This tells the DFPGAs to store the data on motherboard FPGA and
uci1 0:664899e0b988 111 // read it out.
uci1 56:0bba0ef15697 112 DigitalIn PIN_a_sf_clk(p14);
uci1 0:664899e0b988 113 DigitalIn PIN_rst_a_sf(p15);
uci1 56:0bba0ef15697 114 #else
uci1 56:0bba0ef15697 115 DigitalIn PIN_dataReady(p14); // when triggered data is stored in the mb FPGA and ready for readout by mbed
uci1 56:0bba0ef15697 116 #endif // ATWD4CH
uci1 1:e392595b4b76 117 // afar power
uci1 56:0bba0ef15697 118 DigitalOut PIN_afar_power(p16,0);
uci1 4:a91682e19d6b 119 // batter voltage/current measurement
uci1 4:a91682e19d6b 120 AnalogIn PIN_vADC1(p19);
uci1 4:a91682e19d6b 121 AnalogIn PIN_vADC2(p18);
uci1 56:0bba0ef15697 122 #if CHIPBOARD==ATWD4CH
uci1 0:664899e0b988 123 // Lock daughter card registeres (during data readout).
uci1 56:0bba0ef15697 124 DigitalOut PIN_lockRegisters(p20,0);
uci1 56:0bba0ef15697 125 #else
uci1 56:0bba0ef15697 126 DigitalOut PIN_readingData(p20,0);
uci1 56:0bba0ef15697 127 #endif // ATWD4CH
uci1 1:e392595b4b76 128 // iridium (SBD) power
uci1 56:0bba0ef15697 129 DigitalOut PIN_iridSbd_power(p21,0);
uci1 0:664899e0b988 130 // Majority logic pins
uci1 56:0bba0ef15697 131 DigitalOut PIN_MajLogHiBit(p22,0);
uci1 56:0bba0ef15697 132 DigitalOut PIN_MajLogLoBit(p23,0);
uci1 56:0bba0ef15697 133 // To launch a heartbeat pulse
uci1 56:0bba0ef15697 134 DigitalOut PIN_heartbeat(p24,0);
uci1 56:0bba0ef15697 135 #if CHIPBOARD==ATWD4CH
uci1 0:664899e0b988 136 // Tell FPGA to be ready to accept DAC values
uci1 56:0bba0ef15697 137 DigitalOut PIN_start_fpga(p26,0);
uci1 56:0bba0ef15697 138 #else
uci1 56:0bba0ef15697 139 DigitalIn PIN_unused26(p26);
uci1 56:0bba0ef15697 140 #endif // ATWD4CH
uci1 56:0bba0ef15697 141 #if CHIPBOARD==ATWD4CH
uci1 0:664899e0b988 142 // Two bits to the select the daughter card for readout
uci1 56:0bba0ef15697 143 DigitalOut PIN_selCardHiBit(p29,0);
uci1 56:0bba0ef15697 144 DigitalOut PIN_selCardLoBit(p30,0);
uci1 56:0bba0ef15697 145 #else
uci1 56:0bba0ef15697 146 DigitalOut PIN_dualOrSingleThresholds(p29, 1); // 1 = dual (hi AND lo thresh crossings)
uci1 56:0bba0ef15697 147 DigitalOut PIN_differentialTrigSignal(p30, 1); // 1 = chip sends one trigger signal per channel with reduced noise, 0 = chip sends each comparator signal separately
uci1 56:0bba0ef15697 148 #endif // ATWD4CH
uci1 0:664899e0b988 149 // Setup SPI pins
uci1 0:664899e0b988 150 SPI PIN_spi( p5, p6, p7 );
uci1 3:24c5f0f50bf1 151
uci1 56:0bba0ef15697 152 #if CHIPBOARD==SST4CH
uci1 56:0bba0ef15697 153 PinName gThermPinName(p15);
uci1 56:0bba0ef15697 154 DS1820 PIN_therm(gThermPinName, gThermPinName, false); // be default, on external power
uci1 56:0bba0ef15697 155 #endif
uci1 41:d6f5e2f09e07 156
uci1 41:d6f5e2f09e07 157 // we have to do this shit because Serial and MODSERIAL don't have virtual functions
uci1 41:d6f5e2f09e07 158 // so calling, e.g. readable from a Serial* will call Serial::readable instead of MODSERIAL::readable
uci1 41:d6f5e2f09e07 159 // and the comms will wait forever
uci1 15:f2569d8e4176 160 #ifdef USE_MODSERIAL
uci1 41:d6f5e2f09e07 161 #define MAIN_SERIALTYPE AjK::MODSERIAL
uci1 15:f2569d8e4176 162 #else
uci1 41:d6f5e2f09e07 163 #define MAIN_SERIALTYPE Serial
uci1 56:0bba0ef15697 164 #endif // USE_MODSERIAL
uci1 41:d6f5e2f09e07 165
uci1 41:d6f5e2f09e07 166 // this needs to be first in case some other global uses a print statement
uci1 41:d6f5e2f09e07 167 static MAIN_SERIALTYPE gCpu( USBTX, USBRX ); // defined here so it might be used for debugging output
uci1 41:d6f5e2f09e07 168
uci1 41:d6f5e2f09e07 169 static MAIN_SERIALTYPE gSBDport(p28, p27,
uci1 16:744ce85aede2 170 #ifdef USE_MODSERIAL
uci1 41:d6f5e2f09e07 171 MODSERIAL_TX_BUF_SIZE, MODSERIAL_RX_BUF_SIZE,
uci1 56:0bba0ef15697 172 #endif // USE_MODSERIAL
uci1 41:d6f5e2f09e07 173 "sbd");
uci1 41:d6f5e2f09e07 174
uci1 56:0bba0ef15697 175 // The SD card
uci1 21:ce51bb0ba4a5 176 static SDFileSystem sd(p5, p6, p7, p8, SnSDUtils::kSDdir+1); // no leading '/'
uci1 67:ec999336fcd1 177
uci1 67:ec999336fcd1 178 // local file system is still created even if USE_INTERFACE_CHIP is not defined
uci1 67:ec999336fcd1 179 // this is done to allow the mbed to be reprogrammed remotely
uci1 25:57b2627fe756 180 static LocalFileSystem local((SnCommWin::kLocalDir)+1); // no leading '/'
uci1 0:664899e0b988 181
uci1 0:664899e0b988 182 //
uci1 0:664899e0b988 183 // fwd declare fcns
uci1 0:664899e0b988 184 //
uci1 0:664899e0b988 185 void ReadAllRegisters();
uci1 0:664899e0b988 186 void ReadRegister(const uint8_t chan, int16_t* dev);
uci1 22:f957c4f840ad 187 void SaveHeartbeat();
uci1 0:664899e0b988 188 void SaveEvent(const int32_t etms);
uci1 0:664899e0b988 189 void WaitTrigAndSendClock();
uci1 1:e392595b4b76 190 void SetConfigAndMakeOutputFile();
uci1 40:1324da35afd4 191 SnCommWin::ECommWinResult OpenCommWin(const bool forceReconfig=false,
uci1 40:1324da35afd4 192 const bool isStartupWin=false);
uci1 3:24c5f0f50bf1 193 void MakeOutputFile(const bool stopRunning=false);
uci1 84:80b15993944e 194 bool IsPowerAllowedFor(const bool isCommWin,
uci1 84:80b15993944e 195 const uint8_t devicesInUse,
uci1 84:80b15993944e 196 const SnConfigFrame::EDatPackBit b);
uci1 84:80b15993944e 197 void SetPower(const bool isCommWin,
uci1 84:80b15993944e 198 const uint8_t devicesInUse);
uci1 84:80b15993944e 199 void CheckPower(const bool isCommWin,
uci1 84:80b15993944e 200 const bool saveReading=true,
uci1 84:80b15993944e 201 const uint8_t devicesInUse=
uci1 84:80b15993944e 202 SnConfigFrame::kIrid |
uci1 84:80b15993944e 203 SnConfigFrame::kAfar);
uci1 84:80b15993944e 204 void CheckTemp();
uci1 84:80b15993944e 205 void UpdateTemperature();
uci1 84:80b15993944e 206 bool AreCardsPowered(const bool checkPin);
uci1 84:80b15993944e 207 void GetAvePowerReading();
uci1 84:80b15993944e 208 #if CHIPBOARD==SST4CH
uci1 84:80b15993944e 209 void InitTempProbe();
uci1 84:80b15993944e 210 #endif
uci1 84:80b15993944e 211 void ResetCountersClearEvt();
uci1 84:80b15993944e 212 void CalcRate(const uint32_t numtrgs,
uci1 84:80b15993944e 213 const double tottime_ms,
uci1 84:80b15993944e 214 float& rate);
uci1 84:80b15993944e 215 void GetRates(float& thmrate, float& evtrate);
uci1 84:80b15993944e 216 void AddToRate(const double dt, const bool isThm);
uci1 84:80b15993944e 217 bool IsSeqComplete();
uci1 8:95a325df1f6b 218 void procForceTrigger();
uci1 8:95a325df1f6b 219 void procHeartbeat();
uci1 8:95a325df1f6b 220 void procPowerCheck();
uci1 56:0bba0ef15697 221 void procTempCheck();
uci1 8:95a325df1f6b 222 void procCommWin();
uci1 40:1324da35afd4 223 #ifdef USE_RTOS
uci1 8:95a325df1f6b 224 void procForceTrigger(void const *) { return procForceTrigger(); }
uci1 8:95a325df1f6b 225 void procHeartbeat(void const *) { return procHeartbeat(); }
uci1 8:95a325df1f6b 226 void procPowerCheck(void const *) { return procPowerCheck(); }
uci1 8:95a325df1f6b 227 void procCommWin(void const *) { return procCommWin(); }
uci1 56:0bba0ef15697 228 void procTempCheck(void const *) { return procTempCheck(); }
uci1 56:0bba0ef15697 229 #endif // USE_RTOS
uci1 0:664899e0b988 230
uci1 0:664899e0b988 231 //
uci1 0:664899e0b988 232 // globals
uci1 0:664899e0b988 233 //
uci1 0:664899e0b988 234 // readout objs
uci1 8:95a325df1f6b 235 // TODO: use RtosTimer instead of Ticker?
uci1 40:1324da35afd4 236 #ifdef USE_RTOS
uci1 8:95a325df1f6b 237 static rtos::RtosTimer* gForceTicker;
uci1 8:95a325df1f6b 238 static rtos::RtosTimer* gHeartbeatTicker;
uci1 8:95a325df1f6b 239 static rtos::RtosTimer* gCommWinTicker;
uci1 8:95a325df1f6b 240 static rtos::RtosTimer* gPowerCheckTicker;
uci1 56:0bba0ef15697 241 static rtos::RtosTimer* gTempCheckTicker;
uci1 8:95a325df1f6b 242 #else
uci1 0:664899e0b988 243 static Ticker gForceTicker;
uci1 3:24c5f0f50bf1 244 static Ticker gHeartbeatTicker;
uci1 1:e392595b4b76 245 static Ticker gCommWinTicker;
uci1 8:95a325df1f6b 246 static Ticker gPowerCheckTicker;
uci1 56:0bba0ef15697 247 static Ticker gTempCheckTicker;
uci1 56:0bba0ef15697 248 #endif // USE_RTOS
uci1 40:1324da35afd4 249 static Timer gAllTrgTimer;
uci1 40:1324da35afd4 250 static Timer gThmTrgTimer;
uci1 16:744ce85aede2 251 static Timer gAdcToMBtimer;
uci1 67:ec999336fcd1 252
uci1 84:80b15993944e 253 static Timer gSinceClkSet;
uci1 41:d6f5e2f09e07 254 static SnClockSetFrame gClkSet;
uci1 41:d6f5e2f09e07 255 static SnSignalStrengthFrame gSigStr;
uci1 31:b5bd3b189150 256 #ifdef DISABLE_CONFIG_SAFETYNETS
uci1 31:b5bd3b189150 257 static SnConfigFrame gConf(false);
uci1 31:b5bd3b189150 258 #else
uci1 0:664899e0b988 259 static SnConfigFrame gConf;
uci1 56:0bba0ef15697 260 #endif // DISABLE_CONFIG_SAFETYNETS
uci1 0:664899e0b988 261 static SnEventFrame gEvent;
uci1 84:80b15993944e 262 //static SnEventFrame gLastEvent;
uci1 8:95a325df1f6b 263 static SnPowerFrame gPower;
uci1 56:0bba0ef15697 264 static SnTempFrame gTemperature;
uci1 0:664899e0b988 265 // parameters
uci1 21:ce51bb0ba4a5 266 static bool gCardsPowered = false;
uci1 0:664899e0b988 267 static bool gFirstEvt = true;
uci1 56:0bba0ef15697 268 static volatile bool gReadingOut = false; // if data is being read from the FPGA
uci1 15:f2569d8e4176 269 static volatile bool gCommWinOpen = false; // if it's open
uci1 1:e392595b4b76 270 static volatile bool gOpenCommWin = false; // if it should be opened
uci1 8:95a325df1f6b 271 static volatile bool gCheckPower = false; // if it should be checked
uci1 56:0bba0ef15697 272 static volatile bool gCheckTemp = false; // if it should be checked
uci1 8:95a325df1f6b 273 static uint32_t gPowNum = 0;
uci1 8:95a325df1f6b 274 static uint32_t gEvtNum = 0; // num of evt written
uci1 84:80b15993944e 275 static volatile bool gForcedTrig = false; // forced trigger bit
uci1 84:80b15993944e 276 static volatile bool gAdcToMBflag = false; // flag in case getting the ADC values took too long
uci1 84:80b15993944e 277 //static uint32_t gTrgNum[kNumTrgs] = {0}; // num of this type of trg received
uci1 84:80b15993944e 278 static uint32_t gNumThmTrigs = 0; // number of thermal triggers counted
uci1 84:80b15993944e 279 static uint32_t gNumFrcTrigs = 0; // number of forced triggers counted
uci1 84:80b15993944e 280 static uint8_t gL1ScaledownCount = 0; // write an event every X L1 failures
uci1 0:664899e0b988 281 // i/o
uci1 21:ce51bb0ba4a5 282 static time_t gLastCommWin = 0; // time
uci1 22:f957c4f840ad 283 static uint32_t gCommWinChecks = 0;
uci1 22:f957c4f840ad 284 static uint32_t gNcommWinChecks = 0;
uci1 40:1324da35afd4 285 static uint16_t gConsecCommFails = 0;
uci1 22:f957c4f840ad 286 // heartbeat
uci1 84:80b15993944e 287 static SnHeartbeatFrame gHrtbt;
uci1 22:f957c4f840ad 288 static time_t gLastHrtbt = 0;
uci1 23:ccf39298f205 289 static volatile bool gHrtbtFired = false;
uci1 22:f957c4f840ad 290 static uint32_t gHrtbtNum = 0;
uci1 22:f957c4f840ad 291 // rates
uci1 22:f957c4f840ad 292 static double gThmDtSum = 0; // sum of all time diffs between thermal trigs
uci1 22:f957c4f840ad 293 static double gEvtDtSum = 0; // sum of all time diffs between events
uci1 22:f957c4f840ad 294 static uint32_t gThmNumDt = 0; // number of thermal trig time diffs added up
uci1 22:f957c4f840ad 295 static uint32_t gEvtNumDt = 0; // number of event time diffs added up
uci1 10:3c93db1cfb12 296 // this should be bigger than anything that will actually be used
uci1 40:1324da35afd4 297 static const uint32_t gBufSize=SnStatusFrame::kMaxSizeOf + (2u*SnHeaderFrame::kMaxSizeOf) + SnPowerFrame::kMaxSizeOf
uci1 61:42cbfc02e0e0 298 + SnEventFrame::kMaxSizeOf // (this is redundant and could be removed if mem is sparse)
uci1 84:80b15993944e 299 + 256; // breathing room
uci1 3:24c5f0f50bf1 300 static char gGenBuf[gBufSize]; // must be big enough for event or status or config!
uci1 11:de443350ec4a 301 static SnCommWin* gComms[kNcomms] = { 0 }; // order => priority. afar uses RTOS, and must be made inside main
uci1 28:484943132bb0 302 #if defined(ENABLE_AFAR_TWITTER) && defined(ENABLE_AFAR_COMM)
uci1 28:484943132bb0 303 static SnCommAfarNetIfTwitter* gTwit = 0;
uci1 28:484943132bb0 304 #endif
uci1 84:80b15993944e 305 static float gChanFFT[kNsamps] = { 0 }; // only one chan at a time to save RAM
uci1 84:80b15993944e 306 // status update data cache and flags
uci1 84:80b15993944e 307 static SnClockSetFrame gStTrgStartClk;
uci1 84:80b15993944e 308 static SnClockSetFrame gStTrgStopClk;
uci1 84:80b15993944e 309 static SnPowerFrame gStPower;
uci1 84:80b15993944e 310 static SnTempFrame gStTemperature;
uci1 84:80b15993944e 311 static volatile bool gStNewPower(false);
uci1 84:80b15993944e 312 static volatile bool gStNewEvent(false);
uci1 84:80b15993944e 313 static volatile bool gStNewHeartbeat(false);
uci1 84:80b15993944e 314 static volatile bool gStNewTemperature(false);
uci1 0:664899e0b988 315
uci1 84:80b15993944e 316 #ifdef EVT_TIME_PROFILE
uci1 84:80b15993944e 317 Timer gProfiler;
uci1 84:80b15993944e 318 #endif
uci1 67:ec999336fcd1 319
uci1 0:664899e0b988 320 void procForceTrigger() {
uci1 0:664899e0b988 321 if (gReadingOut==false && gCommWinOpen==false) {
uci1 15:f2569d8e4176 322 led3=!led3;
uci1 12:d472f9811262 323 #ifdef DEBUG
uci1 8:95a325df1f6b 324 printf("proc force\r\n");
uci1 56:0bba0ef15697 325 #if CHIPBOARD==ATWD4CH
uci1 47:fbe956b10a91 326 printf("PIN_forceTrigge=%d, PIN_turn_on_system=%d, "
uci1 47:fbe956b10a91 327 "PIN_a_sf_clk=%d\r\n",
uci1 47:fbe956b10a91 328 PIN_forceTrigger.read(), PIN_turn_on_system.read(),
uci1 47:fbe956b10a91 329 PIN_a_sf_clk.read());
uci1 56:0bba0ef15697 330 #else
uci1 56:0bba0ef15697 331 printf("PIN_forceTrigge=%d, PIN_turn_on_system=%d, "
uci1 56:0bba0ef15697 332 "PIN_dataReady=%d\r\n",
uci1 56:0bba0ef15697 333 PIN_forceTrigger.read(), PIN_turn_on_system.read(),
uci1 56:0bba0ef15697 334 PIN_dataReady.read());
uci1 56:0bba0ef15697 335 #endif // ATWD4CH
uci1 12:d472f9811262 336 #endif
uci1 84:80b15993944e 337 gForcedTrig = true;
uci1 84:80b15993944e 338 ++gNumFrcTrigs;
uci1 84:80b15993944e 339 // ++(gTrgNum[kFrcTrg]);
uci1 84:80b15993944e 340 // gEvent.SetTrgBit(kFrcTrg);
uci1 84:80b15993944e 341 // gEvent.SetTrgNum(++(gTrgNum[kFrcTrg]));
uci1 23:ccf39298f205 342 //PIN_forceTrigger = 0;
uci1 0:664899e0b988 343 PIN_forceTrigger = 1; // force a trigger
uci1 21:ce51bb0ba4a5 344 PIN_forceTrigger = 0;
uci1 0:664899e0b988 345 }
uci1 0:664899e0b988 346 }
uci1 0:664899e0b988 347
uci1 3:24c5f0f50bf1 348 void procHeartbeat() {
uci1 3:24c5f0f50bf1 349 if (gReadingOut==false && gCommWinOpen==false) {
uci1 12:d472f9811262 350 #ifdef DEBUG
uci1 8:95a325df1f6b 351 printf("proc heartbeat\r\n");
uci1 12:d472f9811262 352 #endif
uci1 67:ec999336fcd1 353 led3=!led3;
uci1 23:ccf39298f205 354 //PIN_heartbeat = 0;
uci1 3:24c5f0f50bf1 355 PIN_heartbeat = 1; // heartbeat pulse
uci1 3:24c5f0f50bf1 356 PIN_heartbeat = 0;
uci1 22:f957c4f840ad 357 gLastHrtbt = time(0);
uci1 22:f957c4f840ad 358 gHrtbtFired = true;
uci1 22:f957c4f840ad 359 ++gHrtbtNum;
uci1 3:24c5f0f50bf1 360 }
uci1 3:24c5f0f50bf1 361 }
uci1 3:24c5f0f50bf1 362
uci1 8:95a325df1f6b 363 void procPowerCheck() {
uci1 12:d472f9811262 364 #ifdef DEBUG
uci1 8:95a325df1f6b 365 printf("proc power\r\n");
uci1 12:d472f9811262 366 #endif
uci1 67:ec999336fcd1 367 led3=!led3;
uci1 8:95a325df1f6b 368 gCheckPower=true;
uci1 8:95a325df1f6b 369 }
uci1 8:95a325df1f6b 370
uci1 56:0bba0ef15697 371 void procTempCheck() {
uci1 56:0bba0ef15697 372 #ifdef DEBUG
uci1 56:0bba0ef15697 373 printf("proc temp check\r\n");
uci1 56:0bba0ef15697 374 #endif
uci1 67:ec999336fcd1 375 led3=!led3;
uci1 56:0bba0ef15697 376 gCheckTemp=true;
uci1 56:0bba0ef15697 377 }
uci1 56:0bba0ef15697 378
uci1 0:664899e0b988 379 void procCommWin() {
uci1 22:f957c4f840ad 380 ++gCommWinChecks;
uci1 27:efc4d654b139 381 //if ( (time(0) - gLastCommWin) > gConf.GetCommWinPeriod() ) {
uci1 22:f957c4f840ad 382 #ifdef DEBUG
uci1 27:efc4d654b139 383 printf("<><><><><><> gCommWinChecks=%u, gNcommWinChecks=%u\r\n",
uci1 27:efc4d654b139 384 gCommWinChecks, gNcommWinChecks);
uci1 22:f957c4f840ad 385 #endif
uci1 27:efc4d654b139 386 if ( gCommWinChecks >= gNcommWinChecks ) {
uci1 12:d472f9811262 387 #ifdef DEBUG
uci1 27:efc4d654b139 388 printf("proc comm win.\r\n");
uci1 12:d472f9811262 389 #endif
uci1 27:efc4d654b139 390 led3=!led3;
uci1 27:efc4d654b139 391 gOpenCommWin = true;
uci1 0:664899e0b988 392 }
uci1 0:664899e0b988 393 }
uci1 0:664899e0b988 394
uci1 21:ce51bb0ba4a5 395 bool AreCardsPowered(const bool checkPin) {
uci1 21:ce51bb0ba4a5 396 #ifdef DEBUG
uci1 56:0bba0ef15697 397 printf("acp call: PIN_turn_on_system=%d, gCardsPowered=%d\r\n",
uci1 21:ce51bb0ba4a5 398 PIN_turn_on_system.read(), gCardsPowered);
uci1 21:ce51bb0ba4a5 399 #endif
uci1 21:ce51bb0ba4a5 400 if (checkPin) {
uci1 56:0bba0ef15697 401 #if CHIPBOARD==ATWD4CH
uci1 21:ce51bb0ba4a5 402 gCardsPowered = (PIN_turn_on_system.read()==0);
uci1 56:0bba0ef15697 403 #else
uci1 56:0bba0ef15697 404 gCardsPowered = (PIN_turn_on_system.read()==1);
uci1 56:0bba0ef15697 405 #endif // ATWD4CH
uci1 16:744ce85aede2 406 }
uci1 56:0bba0ef15697 407 #ifdef DEBUG
uci1 56:0bba0ef15697 408 printf("acp return: PIN_turn_on_system=%d, gCardsPowered=%d\r\n",
uci1 56:0bba0ef15697 409 PIN_turn_on_system.read(), gCardsPowered);
uci1 56:0bba0ef15697 410 #endif
uci1 21:ce51bb0ba4a5 411 return gCardsPowered;
uci1 8:95a325df1f6b 412 }
uci1 0:664899e0b988 413
uci1 8:95a325df1f6b 414 void GetAvePowerReading() {
uci1 8:95a325df1f6b 415 // use one measurement as the assumed average
uci1 8:95a325df1f6b 416 // in order to reduce computational errors
uci1 8:95a325df1f6b 417 int32_t v1, v2;
uci1 8:95a325df1f6b 418 const uint16_t aaveV1 = PIN_vADC1.read_u16();
uci1 8:95a325df1f6b 419 const uint16_t aaveV2 = PIN_vADC2.read_u16();
uci1 8:95a325df1f6b 420 float n=0, ave1=0, ave2=0, rms1=0, rms2=0;
uci1 56:0bba0ef15697 421 for (uint16_t i=0; i<kNvoltsAve; ++i) {
uci1 8:95a325df1f6b 422 v1 = PIN_vADC1.read_u16() - aaveV1;
uci1 8:95a325df1f6b 423 v2 = PIN_vADC2.read_u16() - aaveV2;
uci1 8:95a325df1f6b 424 n += 1;
uci1 8:95a325df1f6b 425 ave1 += v1;
uci1 8:95a325df1f6b 426 rms1 += v1*v1;
uci1 8:95a325df1f6b 427 ave2 += v2;
uci1 8:95a325df1f6b 428 rms2 += v2*v2;
uci1 8:95a325df1f6b 429 }
uci1 8:95a325df1f6b 430 rms1 -= (ave1*ave1)/n;
uci1 8:95a325df1f6b 431 rms2 -= (ave2*ave2)/n;
uci1 8:95a325df1f6b 432 rms1 /= n-1;
uci1 8:95a325df1f6b 433 rms2 /= n-1;
uci1 9:a1a39573dd43 434 rms1 = sqrt(rms1);
uci1 9:a1a39573dd43 435 rms2 = sqrt(rms2);
uci1 8:95a325df1f6b 436 ave1 /= n;
uci1 8:95a325df1f6b 437 ave2 /= n;
uci1 8:95a325df1f6b 438 ave1 += aaveV1;
uci1 8:95a325df1f6b 439 ave2 += aaveV2;
uci1 8:95a325df1f6b 440 gPower.Set(ave1, ave2, rms1, rms2, time(0));
uci1 56:0bba0ef15697 441 #ifdef DEBUG
uci1 56:0bba0ef15697 442 printf("ave power. v1=%g, v2=%g, r1=%g, r2=%g, t=%u\r\n",
uci1 56:0bba0ef15697 443 gPower.GetAveV1(), gPower.GetAveV2(),
uci1 56:0bba0ef15697 444 gPower.GetRmsV1(), gPower.GetRmsV2(), gPower.GetTime());
uci1 56:0bba0ef15697 445 #endif
uci1 8:95a325df1f6b 446 }
uci1 0:664899e0b988 447
uci1 56:0bba0ef15697 448 #if CHIPBOARD==SST4CH
uci1 56:0bba0ef15697 449 void InitTempProbe() {
uci1 56:0bba0ef15697 450 #ifdef DEBUG
uci1 56:0bba0ef15697 451 printf("setting temp probe power mode\r\n");
uci1 56:0bba0ef15697 452 #endif
uci1 56:0bba0ef15697 453 // set power style for temperature probe
uci1 56:0bba0ef15697 454 PIN_therm.set_use_parasite_power( gConf.IsTempUsingParasitePower() );
uci1 56:0bba0ef15697 455 // setup the probe
uci1 56:0bba0ef15697 456 #ifdef DEBUG
uci1 56:0bba0ef15697 457 printf("calling therm probe search_ROM_setup\r\n");
uci1 56:0bba0ef15697 458 #endif
uci1 56:0bba0ef15697 459 PIN_therm.search_ROM_setup();
uci1 56:0bba0ef15697 460 const int tsr = PIN_therm.search_ROM(); // this is necessary for some reason
uci1 56:0bba0ef15697 461 #ifdef DEBUG
uci1 56:0bba0ef15697 462 printf("search ROM = %d\r\n", tsr);
uci1 56:0bba0ef15697 463 #endif
uci1 56:0bba0ef15697 464 }
uci1 56:0bba0ef15697 465 #endif
uci1 56:0bba0ef15697 466
uci1 56:0bba0ef15697 467 void UpdateTemperature() {
uci1 56:0bba0ef15697 468 // ask chip to convert temperature
uci1 67:ec999336fcd1 469 #if CHIPBOARD==SST4CH
uci1 56:0bba0ef15697 470 PIN_therm.convert_temperature(true, DS1820::all_devices);
uci1 56:0bba0ef15697 471 gTemperature.SetTempAndTime( PIN_therm.temperature('c'), time(0) );
uci1 56:0bba0ef15697 472 #ifdef DEBUG
uci1 56:0bba0ef15697 473 printf("TTTTTTTT temp = %g at %u\r\n", gTemperature.GetTemperature(),
uci1 56:0bba0ef15697 474 gTemperature.GetTime());
uci1 56:0bba0ef15697 475 #endif
uci1 67:ec999336fcd1 476 #else
uci1 67:ec999336fcd1 477 return; // do nothing
uci1 67:ec999336fcd1 478 #endif
uci1 56:0bba0ef15697 479 }
uci1 56:0bba0ef15697 480
uci1 56:0bba0ef15697 481 void CheckTemp() {
uci1 56:0bba0ef15697 482 #ifdef DEBUG
uci1 56:0bba0ef15697 483 printf("CheckTemp\r\n");
uci1 56:0bba0ef15697 484 #endif
uci1 56:0bba0ef15697 485 UpdateTemperature();
uci1 56:0bba0ef15697 486 // save to disk
uci1 56:0bba0ef15697 487 FILE* cf = SnSDUtils::GetCurFile();
uci1 56:0bba0ef15697 488 if (cf!=0) {
uci1 56:0bba0ef15697 489 #if CHIPBOARD==ATWD4CH
uci1 56:0bba0ef15697 490 PIN_lockRegisters = 0; // unlock so we can talk to the SD card
uci1 56:0bba0ef15697 491 #else
uci1 56:0bba0ef15697 492 PIN_readingData = 0; // unlock so we can talk to the SD card
uci1 56:0bba0ef15697 493 #endif // ATWD4CH
uci1 56:0bba0ef15697 494 #ifdef DEBUG
uci1 56:0bba0ef15697 495 printf("writing temp. temp = %g at %u\r\n",
uci1 56:0bba0ef15697 496 gTemperature.GetTemperature(),
uci1 56:0bba0ef15697 497 gTemperature.GetTime());
uci1 56:0bba0ef15697 498 #endif
uci1 56:0bba0ef15697 499 SnSDUtils::WriteTempTo(cf, gTemperature);
uci1 56:0bba0ef15697 500 }
uci1 56:0bba0ef15697 501 gCheckTemp = false;
uci1 56:0bba0ef15697 502 }
uci1 56:0bba0ef15697 503
uci1 56:0bba0ef15697 504 void CheckPower(const bool isCommWin,
uci1 84:80b15993944e 505 const bool saveReading,
uci1 84:80b15993944e 506 const uint8_t devicesInUse) {
uci1 12:d472f9811262 507 #ifdef DEBUG
uci1 8:95a325df1f6b 508 printf("CheckPower\r\n");
uci1 12:d472f9811262 509 #endif
uci1 8:95a325df1f6b 510 // read power
uci1 8:95a325df1f6b 511 GetAvePowerReading();
uci1 56:0bba0ef15697 512 if (saveReading) {
uci1 56:0bba0ef15697 513 // save to disk
uci1 56:0bba0ef15697 514 FILE* cf = SnSDUtils::GetCurFile();
uci1 56:0bba0ef15697 515 if (cf!=0) {
uci1 56:0bba0ef15697 516 #if CHIPBOARD==ATWD4CH
uci1 56:0bba0ef15697 517 PIN_lockRegisters = 0; // unlock so we can talk to the SD card
uci1 56:0bba0ef15697 518 #else
uci1 56:0bba0ef15697 519 PIN_readingData = 0; // unlock so we can talk to the SD card
uci1 56:0bba0ef15697 520 #endif // ATWD4CH
uci1 12:d472f9811262 521 #ifdef DEBUG
uci1 56:0bba0ef15697 522 printf("writing power. v1=%g, v2=%g, r1=%g, r2=%g, t=%u, pownum=%u\r\n",
uci1 56:0bba0ef15697 523 gPower.GetAveV1(), gPower.GetAveV2(),
uci1 56:0bba0ef15697 524 gPower.GetRmsV1(), gPower.GetRmsV2(), gPower.GetTime(),
uci1 56:0bba0ef15697 525 gPowNum);
uci1 12:d472f9811262 526 #endif
uci1 56:0bba0ef15697 527 SnSDUtils::WritePowerTo(cf, gPower, gPowNum);
uci1 56:0bba0ef15697 528 }
uci1 8:95a325df1f6b 529 }
uci1 8:95a325df1f6b 530 // do we need to change modes?
uci1 8:95a325df1f6b 531 bool changed = false;
uci1 8:95a325df1f6b 532 if (gConf.IsLowPowerMode()) {
uci1 56:0bba0ef15697 533 #ifdef DEBUG
uci1 56:0bba0ef15697 534 printf("in low pwr. v1=%g, fromLP=%hu\r\n",
uci1 56:0bba0ef15697 535 gPower.GetAveV1(), gConf.GetBatVoltFromLowPwr());
uci1 56:0bba0ef15697 536 #endif
uci1 39:2f17131d22a5 537 if (gPower.GetAveV1() > gConf.GetBatVoltFromLowPwr()) {
uci1 12:d472f9811262 538 #ifdef DEBUG
uci1 8:95a325df1f6b 539 printf("chaing to normal power!\r\n");
uci1 12:d472f9811262 540 #endif
uci1 8:95a325df1f6b 541 gConf.ChangeToNormPower();
uci1 8:95a325df1f6b 542 changed = true;
uci1 8:95a325df1f6b 543 }
uci1 8:95a325df1f6b 544 } else {
uci1 56:0bba0ef15697 545 #ifdef DEBUG
uci1 56:0bba0ef15697 546 printf("in normal pwr. v1=%g, toLP=%hu\r\n",
uci1 56:0bba0ef15697 547 gPower.GetAveV1(), gConf.GetBatVoltToLowPwr());
uci1 56:0bba0ef15697 548 #endif
uci1 39:2f17131d22a5 549 if (gPower.GetAveV1() < gConf.GetBatVoltToLowPwr()) {
uci1 12:d472f9811262 550 #ifdef DEBUG
uci1 8:95a325df1f6b 551 printf("chaing to low power!\r\n");
uci1 12:d472f9811262 552 #endif
uci1 8:95a325df1f6b 553 gConf.ChangeToLowPower();
uci1 8:95a325df1f6b 554 changed = true;
uci1 8:95a325df1f6b 555 }
uci1 8:95a325df1f6b 556 }
uci1 8:95a325df1f6b 557 if (changed) {
uci1 84:80b15993944e 558 SetPower(isCommWin, devicesInUse); // TODO: This will fail if isCommWin==false? (currently not possible, but..)
uci1 12:d472f9811262 559 #ifdef DEBUG
uci1 8:95a325df1f6b 560 printf("Using config %s\r\n",gConf.GetLabel());
uci1 12:d472f9811262 561 #endif
uci1 8:95a325df1f6b 562 SetConfigAndMakeOutputFile(); // setup defaults in case no communication
uci1 8:95a325df1f6b 563 }
uci1 8:95a325df1f6b 564 // checking done
uci1 8:95a325df1f6b 565 gCheckPower = false;
uci1 8:95a325df1f6b 566 }
uci1 8:95a325df1f6b 567
uci1 84:80b15993944e 568 void ResetCounters() {
uci1 12:d472f9811262 569 const uint32_t evtStartCurSeq = (SnSDUtils::GetCurSeqNum()) // no -1; start with seq=0
uci1 12:d472f9811262 570 * gConf.GetEvtsPerFile();
uci1 84:80b15993944e 571 // gEvent.ClearEvent();
uci1 40:1324da35afd4 572 gEvtNum = evtStartCurSeq;
uci1 12:d472f9811262 573 gPowNum = evtStartCurSeq;
uci1 84:80b15993944e 574 // memset(gTrgNum, 0, sizeof(uint32_t)*kNumTrgs);
uci1 84:80b15993944e 575 gNumThmTrigs = 0;
uci1 84:80b15993944e 576 gNumFrcTrigs = 0;
uci1 84:80b15993944e 577 gForcedTrig = false;
uci1 22:f957c4f840ad 578 // reset rate counters
uci1 22:f957c4f840ad 579 gThmDtSum = 0;
uci1 22:f957c4f840ad 580 gThmNumDt = 0;
uci1 22:f957c4f840ad 581 gEvtDtSum = 0;
uci1 22:f957c4f840ad 582 gEvtNumDt = 0;
uci1 22:f957c4f840ad 583 // reset heartbeat counters
uci1 22:f957c4f840ad 584 gLastHrtbt = 0;
uci1 22:f957c4f840ad 585 gHrtbtFired = false;
uci1 22:f957c4f840ad 586 gHrtbtNum = 0;
uci1 84:80b15993944e 587 // reset status data caches
uci1 84:80b15993944e 588 gStNewPower = false;
uci1 84:80b15993944e 589 gStNewEvent = false;
uci1 84:80b15993944e 590 gStNewHeartbeat = false;
uci1 84:80b15993944e 591 gStNewTemperature = false;
uci1 84:80b15993944e 592
uci1 13:7a1fb885a8e4 593 #ifdef DEBUG
uci1 13:7a1fb885a8e4 594 printf("Reset: gEvtNum=%u, gPowNum=%u, evtStartCS=%u\r\n",
uci1 13:7a1fb885a8e4 595 gEvtNum, gPowNum, evtStartCurSeq);
uci1 13:7a1fb885a8e4 596 #endif
uci1 10:3c93db1cfb12 597 }
uci1 10:3c93db1cfb12 598
uci1 56:0bba0ef15697 599 void CalcRate(const uint32_t numtrgs,
uci1 56:0bba0ef15697 600 const double tottime_ms,
uci1 56:0bba0ef15697 601 float& rate) {
uci1 56:0bba0ef15697 602 rate = 0;
uci1 56:0bba0ef15697 603 if (numtrgs>1) {
uci1 56:0bba0ef15697 604 if (tottime_ms>0.0) {
uci1 56:0bba0ef15697 605 rate = static_cast<float>(numtrgs)
uci1 56:0bba0ef15697 606 / (tottime_ms/1e3);
uci1 56:0bba0ef15697 607 } else {
uci1 56:0bba0ef15697 608 // lots of triggers in 0 time
uci1 56:0bba0ef15697 609 rate = 1e6;
uci1 56:0bba0ef15697 610 }
uci1 56:0bba0ef15697 611 }
uci1 56:0bba0ef15697 612 }
uci1 56:0bba0ef15697 613
uci1 10:3c93db1cfb12 614 void GetRates(float& thmrate, float& evtrate) {
uci1 10:3c93db1cfb12 615 thmrate = evtrate = 0;
uci1 22:f957c4f840ad 616 #ifdef DEBUG
uci1 22:f957c4f840ad 617 printf("** Getting rates: gThmNumDt=%d, gThmDtSum=%g, "
uci1 22:f957c4f840ad 618 "gEvtNumDt=%d, gEvtDtSum=%g\r\n",
uci1 22:f957c4f840ad 619 gThmNumDt, gThmDtSum, gEvtNumDt, gEvtDtSum);
uci1 22:f957c4f840ad 620 #endif
uci1 22:f957c4f840ad 621
uci1 56:0bba0ef15697 622 CalcRate(gThmNumDt, gThmDtSum, thmrate);
uci1 56:0bba0ef15697 623 CalcRate(gEvtNumDt, gEvtDtSum, evtrate);
uci1 22:f957c4f840ad 624 }
uci1 22:f957c4f840ad 625
uci1 56:0bba0ef15697 626 void AddToRate(const double dt, const bool isThm) {
uci1 22:f957c4f840ad 627 if (isThm) {
uci1 22:f957c4f840ad 628 gThmDtSum += dt;
uci1 22:f957c4f840ad 629 gThmNumDt += 1u;
uci1 22:f957c4f840ad 630 } else {
uci1 22:f957c4f840ad 631 gEvtDtSum += dt;
uci1 22:f957c4f840ad 632 gEvtNumDt += 1u;
uci1 10:3c93db1cfb12 633 }
uci1 22:f957c4f840ad 634 #ifdef DEBUG
uci1 22:f957c4f840ad 635 printf("** AddToRate: dt=%g, isThm=%d\r\n",dt,(int)isThm);
uci1 22:f957c4f840ad 636 printf("** AddToRate: gThmNumDt=%d, gThmDtSum=%g, "
uci1 22:f957c4f840ad 637 "gEvtNumDt=%d, gEvtDtSum=%g\r\n",
uci1 22:f957c4f840ad 638 gThmNumDt, gThmDtSum, gEvtNumDt, gEvtDtSum);
uci1 22:f957c4f840ad 639 #endif
uci1 10:3c93db1cfb12 640 }
uci1 10:3c93db1cfb12 641
uci1 8:95a325df1f6b 642 bool IsSeqComplete() {
uci1 12:d472f9811262 643 #ifdef DEBUG
uci1 84:80b15993944e 644 printf("IsSeqComplete: eps=%hu, cntpow=%d, pow=%u, evt=%u, seq=%hu\r\n",
uci1 10:3c93db1cfb12 645 gConf.GetEvtsPerFile(), (int)gConf.IsCountingPowerReadings(),
uci1 40:1324da35afd4 646 gPowNum, gEvtNum, SnSDUtils::GetCurSeqNum());
uci1 12:d472f9811262 647 #endif
uci1 8:95a325df1f6b 648 if (gConf.GetEvtsPerFile()>0) {
uci1 12:d472f9811262 649 const uint32_t evtEndCurSeq = (SnSDUtils::GetCurSeqNum()+1) // account for seq=0
uci1 12:d472f9811262 650 * gConf.GetEvtsPerFile();
uci1 12:d472f9811262 651 #ifdef DEBUG
uci1 12:d472f9811262 652 printf("evtEndCurSeq=%u\r\n",evtEndCurSeq);
uci1 12:d472f9811262 653 #endif
uci1 8:95a325df1f6b 654 if (gConf.IsCountingPowerReadings()) {
uci1 12:d472f9811262 655 return (gPowNum>=evtEndCurSeq);
uci1 8:95a325df1f6b 656 } else {
uci1 12:d472f9811262 657 // first event num is a one-time per run offset, not one per sequence
uci1 40:1324da35afd4 658 return (gEvtNum>=evtEndCurSeq);
uci1 8:95a325df1f6b 659 }
uci1 12:d472f9811262 660 } else {
uci1 12:d472f9811262 661 return false;
uci1 8:95a325df1f6b 662 }
uci1 8:95a325df1f6b 663 }
uci1 1:e392595b4b76 664
uci1 40:1324da35afd4 665 #ifdef USE_RTOS
uci1 8:95a325df1f6b 666 void stopTicker(rtos::RtosTimer* tik) {
uci1 8:95a325df1f6b 667 if (tik!=0) {
uci1 8:95a325df1f6b 668 tik->stop();
uci1 8:95a325df1f6b 669 }
uci1 8:95a325df1f6b 670 }
uci1 8:95a325df1f6b 671 #else
uci1 8:95a325df1f6b 672 void stopTicker(Ticker& tik) {
uci1 8:95a325df1f6b 673 tik.detach();
uci1 8:95a325df1f6b 674 }
uci1 56:0bba0ef15697 675 #endif // USE_RTOS
uci1 8:95a325df1f6b 676
uci1 40:1324da35afd4 677 #ifdef USE_RTOS
uci1 18:55f1581f2ee4 678 float resetTicker(rtos::RtosTimer* tik, const float timSec,
uci1 18:55f1581f2ee4 679 const float maxTimSec) {
uci1 8:95a325df1f6b 680 if (tik!=0) {
uci1 8:95a325df1f6b 681 tik->stop();
uci1 8:95a325df1f6b 682 if (timSec>0) {
uci1 18:55f1581f2ee4 683 float tp = timSec > maxTimSec ? maxTimSec : timSec;
uci1 8:95a325df1f6b 684 tp *= 1000u; // ms
uci1 8:95a325df1f6b 685 tik->start(tp);
uci1 8:95a325df1f6b 686 return tp;
uci1 8:95a325df1f6b 687 }
uci1 8:95a325df1f6b 688 }
uci1 8:95a325df1f6b 689 return 0;
uci1 8:95a325df1f6b 690 }
uci1 8:95a325df1f6b 691 #else
uci1 18:55f1581f2ee4 692 float resetTicker(Ticker& tik, const float timSec,
uci1 18:55f1581f2ee4 693 const float maxTimSec, void (*fptr)(void)) {
uci1 8:95a325df1f6b 694 tik.detach();
uci1 8:95a325df1f6b 695 if (timSec>0) {
uci1 18:55f1581f2ee4 696 const float tp = timSec > maxTimSec ? maxTimSec : timSec;
uci1 8:95a325df1f6b 697 tik.attach(fptr, tp);
uci1 8:95a325df1f6b 698 return tp;
uci1 8:95a325df1f6b 699 }
uci1 8:95a325df1f6b 700 return 0;
uci1 8:95a325df1f6b 701 }
uci1 56:0bba0ef15697 702 #endif // USE_RTOS
uci1 8:95a325df1f6b 703
uci1 15:f2569d8e4176 704 void StopAllTickers() {
uci1 8:95a325df1f6b 705 stopTicker(gForceTicker);
uci1 8:95a325df1f6b 706 stopTicker(gHeartbeatTicker);
uci1 8:95a325df1f6b 707 stopTicker(gCommWinTicker);
uci1 8:95a325df1f6b 708 stopTicker(gPowerCheckTicker);
uci1 56:0bba0ef15697 709 stopTicker(gTempCheckTicker);
uci1 15:f2569d8e4176 710 }
uci1 15:f2569d8e4176 711
uci1 15:f2569d8e4176 712 void ResetAllTickers() {
uci1 40:1324da35afd4 713 #ifdef USE_RTOS
uci1 18:55f1581f2ee4 714 const float ftp = resetTicker(gForceTicker, gConf.GetForceTrigPeriod(),
uci1 18:55f1581f2ee4 715 kAbsMaxTimer);
uci1 40:1324da35afd4 716 Thread::wait(131); // make it less likely for multiple triggers to fire too close together
uci1 18:55f1581f2ee4 717 const float hbp = resetTicker(gHeartbeatTicker, gConf.GetHeartbeatPeriod(),
uci1 18:55f1581f2ee4 718 kAbsMaxTimer);
uci1 40:1324da35afd4 719 Thread::wait(173); // make it less likely for multiple triggers to fire too close together
uci1 18:55f1581f2ee4 720 const float cwp = resetTicker(gCommWinTicker, gConf.GetCommWinPeriod(),
uci1 18:55f1581f2ee4 721 kCommWinLongPrdTk);
uci1 40:1324da35afd4 722 Thread::wait(169); // make it less likely for multiple triggers to fire too close together
uci1 18:55f1581f2ee4 723 const float pcp = resetTicker(gPowerCheckTicker, gConf.GetVoltCheckPeriod(),
uci1 18:55f1581f2ee4 724 kAbsMaxTimer);
uci1 56:0bba0ef15697 725 Thread::wait(143); // make it less likely for multiple triggers to fire too close together
uci1 56:0bba0ef15697 726 const float ctp = resetTicker(gTempCheckTicker, gConf.GetTempCheckPeriod(),
uci1 56:0bba0ef15697 727 kAbsMaxTimer);
uci1 15:f2569d8e4176 728 #else
uci1 18:55f1581f2ee4 729 const float ftp = resetTicker(gForceTicker, gConf.GetForceTrigPeriod(),
uci1 18:55f1581f2ee4 730 kAbsMaxTimer, &procForceTrigger);
uci1 25:57b2627fe756 731 wait_ms(131); // make it less likely for multiple triggers to fire too close together
uci1 18:55f1581f2ee4 732 const float hbp = resetTicker(gHeartbeatTicker, gConf.GetHeartbeatPeriod(),
uci1 18:55f1581f2ee4 733 kAbsMaxTimer, &procHeartbeat);
uci1 25:57b2627fe756 734 wait_ms(173); // make it less likely for multiple triggers to fire too close together
uci1 18:55f1581f2ee4 735 const float cwp = resetTicker(gCommWinTicker, gConf.GetCommWinPeriod(),
uci1 18:55f1581f2ee4 736 kCommWinLongPrdTk, &procCommWin);
uci1 25:57b2627fe756 737 wait_ms(169); // make it less likely for multiple triggers to fire too close together
uci1 18:55f1581f2ee4 738 const float pcp = resetTicker(gPowerCheckTicker, gConf.GetVoltCheckPeriod(),
uci1 18:55f1581f2ee4 739 kAbsMaxTimer, &procPowerCheck);
uci1 56:0bba0ef15697 740 wait_ms(143); // make it less likely for multiple triggers to fire too close together
uci1 56:0bba0ef15697 741 const float ctp = resetTicker(gTempCheckTicker, gConf.GetTempCheckPeriod(),
uci1 56:0bba0ef15697 742 kAbsMaxTimer, &procTempCheck);
uci1 56:0bba0ef15697 743 #endif // USE_RTOS
uci1 15:f2569d8e4176 744 #ifdef DEBUG
uci1 18:55f1581f2ee4 745 printf("attach force trig %g\r\n",ftp);
uci1 18:55f1581f2ee4 746 printf("attach heart beat %g\r\n",hbp);
uci1 18:55f1581f2ee4 747 printf("attach comm win %g\r\n",cwp);
uci1 18:55f1581f2ee4 748 printf("attach power chk %g\r\n",pcp);
uci1 56:0bba0ef15697 749 printf("attach temp chk %g\r\n",ctp);
uci1 15:f2569d8e4176 750 #endif
uci1 15:f2569d8e4176 751 }
uci1 61:42cbfc02e0e0 752 /*
uci1 56:0bba0ef15697 753 void UponBrownout() {
uci1 56:0bba0ef15697 754 // signal brownout by all LEDs off
uci1 56:0bba0ef15697 755 led1 = led2 = led3 = led4 = 0;
uci1 56:0bba0ef15697 756 // note that debug printing here is pointless,
uci1 56:0bba0ef15697 757 // since power over USB will prevent brownout
uci1 56:0bba0ef15697 758
uci1 56:0bba0ef15697 759 // close the current file
uci1 56:0bba0ef15697 760 #if CHIPBOARD==ATWD4CH
uci1 56:0bba0ef15697 761 PIN_lockRegisters = 0; // unlock so we can talk to the SD card
uci1 56:0bba0ef15697 762 #else
uci1 56:0bba0ef15697 763 PIN_readingData = 0; // unlock so we can talk to the SD card
uci1 56:0bba0ef15697 764 #endif
uci1 56:0bba0ef15697 765 SnSDUtils::WriteTrigWaitWinTime(SnSDUtils::GetCurFile(),
uci1 56:0bba0ef15697 766 gClkSet,
uci1 56:0bba0ef15697 767 false);
uci1 56:0bba0ef15697 768 SnSDUtils::CloseOutputFile(SnSDUtils::GetCurFile());
uci1 56:0bba0ef15697 769
uci1 56:0bba0ef15697 770 // change to low power settings
uci1 56:0bba0ef15697 771 gConf.ChangeToLowPower();
uci1 56:0bba0ef15697 772 // actually power stuff down
uci1 56:0bba0ef15697 773 SetPower(gCommWinOpen);
uci1 56:0bba0ef15697 774
uci1 56:0bba0ef15697 775 // goodnight
uci1 56:0bba0ef15697 776 Sleep();
uci1 56:0bba0ef15697 777 }
uci1 61:42cbfc02e0e0 778 */
uci1 15:f2569d8e4176 779 void StopRunning() {
uci1 15:f2569d8e4176 780 #if defined(DEBUG) || defined(SSNOTIFY)
uci1 15:f2569d8e4176 781 printf("stop running\r\n");
uci1 15:f2569d8e4176 782 #endif
uci1 15:f2569d8e4176 783 StopAllTickers();
uci1 17:4687bf932b8c 784 OpenCommWin();
uci1 8:95a325df1f6b 785 while (true) {
uci1 8:95a325df1f6b 786 led3 = 1; led4=1;
uci1 40:1324da35afd4 787 #ifdef USE_RTOS
uci1 40:1324da35afd4 788 Thread::wait(500);
uci1 40:1324da35afd4 789 #else
uci1 8:95a325df1f6b 790 wait(0.5);
uci1 56:0bba0ef15697 791 #endif // USE_RTOS
uci1 8:95a325df1f6b 792 led3 = 0; led4=0;
uci1 40:1324da35afd4 793 #ifdef USE_RTOS
uci1 40:1324da35afd4 794 Thread::wait(500);
uci1 40:1324da35afd4 795 #else
uci1 8:95a325df1f6b 796 wait(0.5);
uci1 56:0bba0ef15697 797 #endif // USE_RTOS
uci1 22:f957c4f840ad 798 // don't kick the watchdog
uci1 22:f957c4f840ad 799 // if we do, the station is unrecoverable without physical access
uci1 8:95a325df1f6b 800 }
uci1 8:95a325df1f6b 801 }
uci1 1:e392595b4b76 802
uci1 40:1324da35afd4 803
uci1 56:0bba0ef15697 804 int InitSDCard() {
uci1 40:1324da35afd4 805 #ifdef DEBUG
uci1 40:1324da35afd4 806 printf("initializing SD card..\r\n");
uci1 40:1324da35afd4 807 #endif
uci1 76:f8383f0292c2 808 int ret = 1; // always fail if ignoring the SD card (1==fail)
uci1 76:f8383f0292c2 809 if (gConf.IsIgnoringSDcard()==false) {
uci1 76:f8383f0292c2 810 // initialize the SD card. this should prevent the issue with
uci1 76:f8383f0292c2 811 // seq 0 being overwritten upon power up or the SD card first
uci1 76:f8383f0292c2 812 // being insterted
uci1 63:4820a4460f00 813 ret = sd.disk_initialize();
uci1 76:f8383f0292c2 814 // may need to try a bunch of times to get it to init
uci1 76:f8383f0292c2 815 for (int i=0; i<25 && (ret!=0); ++i) {
uci1 76:f8383f0292c2 816 ret = sd.disk_initialize();
uci1 76:f8383f0292c2 817 #ifdef DEBUG
uci1 76:f8383f0292c2 818 printf("called disk_initialize (ret=%d)\r\n",ret);
uci1 76:f8383f0292c2 819 #endif
uci1 76:f8383f0292c2 820 }
uci1 76:f8383f0292c2 821 }
uci1 56:0bba0ef15697 822 #ifdef DEBUG
uci1 76:f8383f0292c2 823 printf("init SD card %d..\r\n", ret);
uci1 56:0bba0ef15697 824 #endif
uci1 56:0bba0ef15697 825 return ret;
uci1 40:1324da35afd4 826 }
uci1 40:1324da35afd4 827
uci1 0:664899e0b988 828 int main() {
uci1 22:f957c4f840ad 829 // a failsafe
uci1 62:4b59c1eb429f 830 //Watchdog::kick(WDFAILSAFE);
uci1 62:4b59c1eb429f 831 #ifdef DEBUG
uci1 63:4820a4460f00 832 printf("Restart watchdog with time [%u] at [%u]\r\n",
uci1 63:4820a4460f00 833 gConf.GetWatchdogPeriod(), time(0));
uci1 84:80b15993944e 834 printf("Free memory = %d\r\n", FreeMem());
uci1 62:4b59c1eb429f 835 #endif
uci1 62:4b59c1eb429f 836 Watchdog::kick(gConf.GetWatchdogPeriod());
uci1 56:0bba0ef15697 837
uci1 56:0bba0ef15697 838 gCpu.baud(CPUBAUD_SN);
uci1 56:0bba0ef15697 839
uci1 1:e392595b4b76 840 {
uci1 18:55f1581f2ee4 841 #if defined(SSNOTIFY) || defined(DEBUG)
uci1 41:d6f5e2f09e07 842 printf("\n\n\n\n\nmain: start\r\n");
uci1 15:f2569d8e4176 843 #endif
uci1 67:ec999336fcd1 844 led1=led2=led3=led4=0;
uci1 40:1324da35afd4 845 #ifdef USE_RTOS
uci1 40:1324da35afd4 846 led1=1; Thread::wait(200);
uci1 40:1324da35afd4 847 led1=0; led2=1; Thread::wait(200);
uci1 40:1324da35afd4 848 led2=0; led3=1; Thread::wait(200);
uci1 40:1324da35afd4 849 led3=0; led4=1; Thread::wait(200);
uci1 40:1324da35afd4 850 #else
uci1 2:e67f7c158087 851 led1=1; wait(0.2);
uci1 2:e67f7c158087 852 led1=0; led2=1; wait(0.2);
uci1 2:e67f7c158087 853 led2=0; led3=1; wait(0.2);
uci1 2:e67f7c158087 854 led3=0; led4=1; wait(0.2);
uci1 56:0bba0ef15697 855 #endif // USE_RTOS
uci1 1:e392595b4b76 856 led4=0;
uci1 1:e392595b4b76 857 }
uci1 67:ec999336fcd1 858
uci1 67:ec999336fcd1 859 // signal startup before first comm win
uci1 67:ec999336fcd1 860 led2 = led1 = 1;
uci1 25:57b2627fe756 861
uci1 56:0bba0ef15697 862 // don't initialize yet, but give SnSDUtils a pointer to
uci1 56:0bba0ef15697 863 // the function that initializes it, so it can call the fcn later
uci1 40:1324da35afd4 864 SnSDUtils::fgDoInit = &InitSDCard;
uci1 56:0bba0ef15697 865
uci1 63:4820a4460f00 866 // check in case we need to go to low power
uci1 63:4820a4460f00 867 //wait(4); // TODO: the vADCs read high for first ~4-5sec
uci1 63:4820a4460f00 868 CheckPower(false, false);
uci1 63:4820a4460f00 869 #ifdef DEBUG
uci1 63:4820a4460f00 870 printf("startup power: cards %d, amps %d, irid %d, afar %d\r\n",
uci1 63:4820a4460f00 871 PIN_turn_on_system.read(), PIN_turn_on_amps.read(),
uci1 63:4820a4460f00 872 PIN_iridSbd_power.read(), PIN_afar_power.read());
uci1 63:4820a4460f00 873 #endif
uci1 63:4820a4460f00 874
uci1 61:42cbfc02e0e0 875 /*
uci1 56:0bba0ef15697 876 // Note: the brownout isn't useful since it sees either 5V or nothing on our board
uci1 56:0bba0ef15697 877 // set up the brownout interrupt
uci1 56:0bba0ef15697 878 NVIC_SetVector(BOD_IRQn, (uint32_t)&UponBrownout);
uci1 56:0bba0ef15697 879 // Enable Brown Out Detect Interrupt
uci1 56:0bba0ef15697 880 NVIC_EnableIRQ(BOD_IRQn);
uci1 61:42cbfc02e0e0 881 */
uci1 56:0bba0ef15697 882
uci1 21:ce51bb0ba4a5 883 #ifdef DEBUG
uci1 18:55f1581f2ee4 884 printf("making comm objects\r\n");
uci1 18:55f1581f2ee4 885 #endif
uci1 25:57b2627fe756 886
uci1 25:57b2627fe756 887 uint8_t comi(0);
uci1 25:57b2627fe756 888 #ifdef ENABLE_AFAR_COMM
uci1 25:57b2627fe756 889 // RTOS stuff must be made inside main for some reason
uci1 18:55f1581f2ee4 890 #ifdef USE_ETH_INTERFACE
uci1 41:d6f5e2f09e07 891 #ifdef DEBUG
uci1 41:d6f5e2f09e07 892 printf("making SnCommAfarTCP\r\n");
uci1 41:d6f5e2f09e07 893 #endif
uci1 25:57b2627fe756 894 gComms[comi++] = new SnCommAfarTCP(gConf);
uci1 18:55f1581f2ee4 895 #else
uci1 41:d6f5e2f09e07 896 #ifdef DEBUG
uci1 41:d6f5e2f09e07 897 printf("making SnCommWinAfar\r\n");
uci1 41:d6f5e2f09e07 898 #endif
uci1 37:ff95e7070f26 899 //gComms[comi++] = new SnCommAfarNetIf(gConf);
uci1 37:ff95e7070f26 900 gComms[comi++] = new SnCommWinAfar(gConf);
uci1 28:484943132bb0 901 #ifdef ENABLE_AFAR_TWITTER
uci1 41:d6f5e2f09e07 902 #ifdef DEBUG
uci1 41:d6f5e2f09e07 903 printf("making SnCommAfarNetIfTwitter\r\n");
uci1 41:d6f5e2f09e07 904 #endif
uci1 28:484943132bb0 905 gTwit = new SnCommAfarNetIfTwitter(gConf);
uci1 56:0bba0ef15697 906 #endif // ENABLE_AFAR_TWITTER
uci1 56:0bba0ef15697 907 #endif // USE_ETH_INTERFACE
uci1 56:0bba0ef15697 908 #endif // ENABLE_AFAR_COMM
uci1 25:57b2627fe756 909 #ifdef ENABLE_SBD_COMM
uci1 41:d6f5e2f09e07 910 #ifdef DEBUG
uci1 41:d6f5e2f09e07 911 printf("making SnCommWinSBD\r\n");
uci1 41:d6f5e2f09e07 912 #endif
uci1 40:1324da35afd4 913 gComms[comi++] = new SnCommWinSBD(&gSBDport);
uci1 56:0bba0ef15697 914 #endif // ENABLE_SBD_COMM
uci1 25:57b2627fe756 915 #ifdef ENABLE_USB_COMM
uci1 41:d6f5e2f09e07 916 #ifdef DEBUG
uci1 41:d6f5e2f09e07 917 printf("makin SnCommWinUsb\r\n");
uci1 41:d6f5e2f09e07 918 #endif
uci1 37:ff95e7070f26 919 gComms[comi++] = new SnCommWinUsb(&gCpu);
uci1 56:0bba0ef15697 920 #endif // ENABLE_USB_COMM
uci1 18:55f1581f2ee4 921
uci1 18:55f1581f2ee4 922 #ifdef DEBUG
uci1 28:484943132bb0 923 printf("made comm objects\r\n");
uci1 41:d6f5e2f09e07 924 #ifdef USE_MODSERIAL
uci1 41:d6f5e2f09e07 925 printf("using MODSERIAL\r\n");
uci1 56:0bba0ef15697 926 #endif // USE_MODSERIAL
uci1 18:55f1581f2ee4 927 #endif
uci1 40:1324da35afd4 928
uci1 40:1324da35afd4 929 if (comi!=kNcomms) {
uci1 40:1324da35afd4 930 error("comi=[%hhu] != kNcomms=[%hhu]\r\n",
uci1 40:1324da35afd4 931 comi, kNcomms);
uci1 40:1324da35afd4 932 // will die here with blue lights of death
uci1 40:1324da35afd4 933 }
uci1 40:1324da35afd4 934
uci1 40:1324da35afd4 935 #ifdef USE_RTOS
uci1 8:95a325df1f6b 936 gForceTicker = new rtos::RtosTimer(&procForceTrigger);
uci1 8:95a325df1f6b 937 gHeartbeatTicker = new rtos::RtosTimer(&procHeartbeat);
uci1 8:95a325df1f6b 938 gCommWinTicker = new rtos::RtosTimer(&procCommWin);
uci1 8:95a325df1f6b 939 gPowerCheckTicker = new rtos::RtosTimer(&procPowerCheck);
uci1 56:0bba0ef15697 940 gTempCheckTicker = new rtos::RtosTimer(&procTempCheck);
uci1 56:0bba0ef15697 941 #endif // USE_RTOS
uci1 67:ec999336fcd1 942
uci1 1:e392595b4b76 943 // set the clock to the BS time, if it's not set
uci1 1:e392595b4b76 944 if ( (static_cast<int32_t>(time(0)))<0 ) {
uci1 1:e392595b4b76 945 set_time(kBStime);
uci1 1:e392595b4b76 946 }
uci1 12:d472f9811262 947 #ifdef DEBUG
uci1 1:e392595b4b76 948 printf("time = %d\r\n",(int32_t)time(0));
uci1 12:d472f9811262 949 #endif
uci1 1:e392595b4b76 950 gLastCommWin = time(0); // prevent comm win proc
uci1 0:664899e0b988 951
uci1 40:1324da35afd4 952 #ifdef USE_RTOS
uci1 8:95a325df1f6b 953 gForceTicker->stop();
uci1 8:95a325df1f6b 954 #else
uci1 0:664899e0b988 955 gForceTicker.detach();
uci1 56:0bba0ef15697 956 #endif // USE_RTOS
uci1 0:664899e0b988 957 gFirstEvt = true;
uci1 56:0bba0ef15697 958
uci1 67:ec999336fcd1 959
uci1 67:ec999336fcd1 960 #ifdef DEBUG
uci1 67:ec999336fcd1 961 printf("MAC=%012llX\r\n", (gConf.GetMacAddress())>>16); // 64 -> 48 bits
uci1 67:ec999336fcd1 962 printf("my ip = %s\r\n", gConf.GetMbedIP());
uci1 67:ec999336fcd1 963 printf("my mask = %s\r\n", gConf.GetMbedMask());
uci1 67:ec999336fcd1 964 printf("my gate = %s\r\n", gConf.GetMbedGate());
uci1 67:ec999336fcd1 965 printf("remote server = %s : %hu\r\n",
uci1 67:ec999336fcd1 966 gConf.GetRemoteServer(), gConf.GetRemotePort());
uci1 84:80b15993944e 967 for (uint8_t i=0; i<SnConfigFrame::kNumDatStreams; ++i) {
uci1 84:80b15993944e 968 printf("data stream %hhu (%s): connectTO=%hhu, listenTO=%hhu\r\n",
uci1 84:80b15993944e 969 i, SnConfigFrame::GetDataStreamNameOfIdx(i),
uci1 84:80b15993944e 970 gConf.GetCommWinConnectTOofIdx(i),
uci1 84:80b15993944e 971 gConf.GetCommWinListenTOofIdx(i));
uci1 84:80b15993944e 972 }
uci1 67:ec999336fcd1 973 #endif
uci1 67:ec999336fcd1 974
uci1 4:a91682e19d6b 975 // (probably) power down comms and power up cards,amps
uci1 84:80b15993944e 976 SetPower(false, SnConfigFrame::kIrid | SnConfigFrame::kAfar);
uci1 56:0bba0ef15697 977 // check power again to see if voltages drooped
uci1 56:0bba0ef15697 978 CheckPower(false, false);
uci1 4:a91682e19d6b 979
uci1 0:664899e0b988 980 //
uci1 0:664899e0b988 981 // get config
uci1 0:664899e0b988 982 //
uci1 12:d472f9811262 983 #ifdef DEBUG
uci1 84:80b15993944e 984 printf("run mode\r\n");
uci1 84:80b15993944e 985 printf("IsCountingPowerReadings=%d\r\n",(int)gConf.IsCountingPowerReadings());
uci1 84:80b15993944e 986 printf("IsSingleSeqRunMode=%d\r\n",(int)gConf.IsSingleSeqRunMode());
uci1 84:80b15993944e 987 printf("IsDualThresholdMode=%d\r\n",(int)gConf.IsDualThresholdMode());
uci1 84:80b15993944e 988 printf("IsDifferentialTrigMode=%d\r\n",(int)gConf.IsDifferentialTrigMode());
uci1 84:80b15993944e 989 printf("IsSBDonlyLowPwrMode=%d\r\n",(int)gConf.IsSBDonlyLowPwrMode());
uci1 84:80b15993944e 990 printf("IsRunSeqListOneCommWinOnly=%d\r\n",(int)gConf.IsRunSeqListOneCommWinOnly());
uci1 84:80b15993944e 991 printf("IsIgnoringSDcard=%d\r\n",(int)gConf.IsIgnoringSDcard());
uci1 84:80b15993944e 992 printf("IsCommPowerSimple=%d\r\n",(int)gConf.IsCommPowerSimple());
uci1 8:95a325df1f6b 993 printf("call OpenCommWin\r\n");
uci1 84:80b15993944e 994 printf("Free memory = %d\r\n", FreeMem());
uci1 12:d472f9811262 995 #endif
uci1 67:ec999336fcd1 996 led2 = led1 = 0; // back to "normal" for comm win
uci1 40:1324da35afd4 997 OpenCommWin(true, true); // alwasy configure, even if no new config
uci1 3:24c5f0f50bf1 998
uci1 0:664899e0b988 999 // get ready to trigger
uci1 0:664899e0b988 1000 PIN_spi.format( 16, 1 ); // change to data readout format
uci1 15:f2569d8e4176 1001 PIN_spi.frequency( 10000000 ); // Max is 12.5 MHz
uci1 0:664899e0b988 1002
uci1 41:d6f5e2f09e07 1003 // read and cache the dCard power pin setting,
uci1 41:d6f5e2f09e07 1004 // so we can use the cached value later
uci1 37:ff95e7070f26 1005 AreCardsPowered(true); // TODO: should this be an if?
uci1 56:0bba0ef15697 1006 register double etms=0; // time between written events
uci1 41:d6f5e2f09e07 1007
uci1 41:d6f5e2f09e07 1008 // the main event loop. wait for triggers in SendClock
uci1 41:d6f5e2f09e07 1009 while ( true ) {
uci1 0:664899e0b988 1010 // in here, we wait for triggers from the MB-FPGA
uci1 0:664899e0b988 1011 Watchdog::kick(); // don't reset!
uci1 1:e392595b4b76 1012
uci1 67:ec999336fcd1 1013 led1 = 1; // signal normal running (i.e. waiting)
uci1 1:e392595b4b76 1014
uci1 12:d472f9811262 1015 #ifdef DEBUG
uci1 1:e392595b4b76 1016 printf("calling wait trig\r\n");
uci1 1:e392595b4b76 1017 printf("gFirstEvt=%s\r\n",gFirstEvt?"true":"false");
uci1 5:9cea89700c66 1018 printf("readingout=%d\r\n",(int)gReadingOut);
uci1 84:80b15993944e 1019 printf("Free memory = %d\r\n", FreeMem());
uci1 12:d472f9811262 1020 #endif
uci1 40:1324da35afd4 1021 if (gFirstEvt) {
uci1 41:d6f5e2f09e07 1022 #ifdef DEBUG
uci1 41:d6f5e2f09e07 1023 printf("WriteTrigWaitWinTime (start)\r\n");
uci1 41:d6f5e2f09e07 1024 #endif
uci1 40:1324da35afd4 1025 SnSDUtils::WriteTrigWaitWinTime(SnSDUtils::GetCurFile(),
uci1 40:1324da35afd4 1026 gClkSet,
uci1 40:1324da35afd4 1027 true);
uci1 40:1324da35afd4 1028 gThmTrgTimer.reset(); gThmTrgTimer.start();
uci1 40:1324da35afd4 1029 gAllTrgTimer.reset(); gAllTrgTimer.start();
uci1 84:80b15993944e 1030 gStTrgStartClk = gClkSet;
uci1 56:0bba0ef15697 1031 #if CHIPBOARD==SST4CH
uci1 56:0bba0ef15697 1032 // reset in case a trigger arrived before we were ready
uci1 56:0bba0ef15697 1033 // this is mostly to ensure that the chip gets reset on soft
uci1 56:0bba0ef15697 1034 // reboot, in case it got stopped prior to the reboot
uci1 56:0bba0ef15697 1035 PIN_ResetChips = 1;
uci1 56:0bba0ef15697 1036 PIN_ResetChips = 0;
uci1 56:0bba0ef15697 1037 #endif
uci1 40:1324da35afd4 1038 }
uci1 76:f8383f0292c2 1039
uci1 56:0bba0ef15697 1040 #if CHIPBOARD==ATWD4CH
uci1 56:0bba0ef15697 1041 PIN_lockRegisters = 0; // allow data to come from DFPGA
uci1 56:0bba0ef15697 1042 WaitTrigAndSendClock(); // wait for trigger and move data to MB. this returns immediately if cards are powered off
uci1 56:0bba0ef15697 1043 PIN_lockRegisters = 1; // block registers during readout
uci1 56:0bba0ef15697 1044 #else
uci1 56:0bba0ef15697 1045 PIN_readingData = 0; // not reading yet
uci1 56:0bba0ef15697 1046 WaitTrigAndSendClock(); // wait for trigger. this returns immediately if cards are powered off
uci1 56:0bba0ef15697 1047 // PIN_readingData will be set high by SnEventFrame::ReadWaveformsSST
uci1 56:0bba0ef15697 1048 #endif // ATWD4CH
uci1 12:d472f9811262 1049 #ifdef EVT_TIME_PROFILE
uci1 84:80b15993944e 1050 gProfiler.start();
uci1 84:80b15993944e 1051 int befSaveEvt=0, aftSaveEvt=0,
uci1 12:d472f9811262 1052 befChkPow=0, aftChkPow=0, befNewSeq=0, aftNewSeq=0, endOfLoop=0;
uci1 56:0bba0ef15697 1053 #endif // EVT_TIME_PROFILE
uci1 12:d472f9811262 1054
uci1 1:e392595b4b76 1055 if (gReadingOut) {
uci1 67:ec999336fcd1 1056
uci1 67:ec999336fcd1 1057 led1 = 0; led4 = 1; // signal reading out
uci1 67:ec999336fcd1 1058
uci1 56:0bba0ef15697 1059 const double ttms = gThmTrgTimer.read_us() / 1e3; // for rate calculation
uci1 56:0bba0ef15697 1060 const double atms = gAllTrgTimer.read_us() / 1e3; // for throttle
uci1 84:80b15993944e 1061 // if (gEvent.IsForcedTrg()==false) {
uci1 84:80b15993944e 1062 if (gForcedTrig) {
uci1 40:1324da35afd4 1063 // don't reset if not a thermal trigger
uci1 40:1324da35afd4 1064 gThmTrgTimer.reset(); gThmTrgTimer.start();
uci1 40:1324da35afd4 1065 }
uci1 40:1324da35afd4 1066 gAllTrgTimer.reset(); gAllTrgTimer.start(); // restart trigger timer
uci1 40:1324da35afd4 1067 etms += atms; // time between events
uci1 8:95a325df1f6b 1068
uci1 8:95a325df1f6b 1069 Watchdog::kick(); // don't reset!
uci1 15:f2569d8e4176 1070
uci1 1:e392595b4b76 1071 //
uci1 1:e392595b4b76 1072 // got trigger. read registers to mbed and build the event
uci1 1:e392595b4b76 1073 //
uci1 1:e392595b4b76 1074
uci1 50:163ec8d88aa9 1075 // TODO: no way to check for external trigger?
uci1 84:80b15993944e 1076 if (gForcedTrig==false) {
uci1 84:80b15993944e 1077 // ++(gTrgNum[kThmTrg]);
uci1 84:80b15993944e 1078 ++gNumThmTrigs;
uci1 50:163ec8d88aa9 1079 AddToRate(ttms, true);
uci1 84:80b15993944e 1080 }
uci1 1:e392595b4b76 1081
uci1 84:80b15993944e 1082 if ( gForcedTrig || gFirstEvt ||
uci1 56:0bba0ef15697 1083 (etms>=gConf.GetEvtThrtlPeriodMs()) ) {
uci1 1:e392595b4b76 1084
uci1 12:d472f9811262 1085 #ifdef EVT_TIME_PROFILE
uci1 84:80b15993944e 1086 gProfiler.stop(); befSaveEvt=gProfiler.read_us(); gProfiler.start();
uci1 56:0bba0ef15697 1087 #endif // EVT_TIME_PROFILE
uci1 84:80b15993944e 1088
uci1 84:80b15993944e 1089 // want to keep this event. save it (and check if it passes L1)
uci1 1:e392595b4b76 1090 SaveEvent(etms);
uci1 22:f957c4f840ad 1091 AddToRate(etms, false);
uci1 12:d472f9811262 1092 etms=0;
uci1 84:80b15993944e 1093
uci1 12:d472f9811262 1094 #ifdef EVT_TIME_PROFILE
uci1 84:80b15993944e 1095 gProfiler.stop(); aftSaveEvt=gProfiler.read_us(); gProfiler.start();
uci1 56:0bba0ef15697 1096 #endif // EVT_TIME_PROFILE
uci1 84:80b15993944e 1097
uci1 56:0bba0ef15697 1098 } else {
uci1 56:0bba0ef15697 1099 #if CHIPBOARD==SST4CH
uci1 56:0bba0ef15697 1100 // reset in case a trigger arrived before we were ready
uci1 56:0bba0ef15697 1101 PIN_ResetChips = 1;
uci1 56:0bba0ef15697 1102 PIN_ResetChips = 0;
uci1 12:d472f9811262 1103 #endif
uci1 1:e392595b4b76 1104 }
uci1 67:ec999336fcd1 1105
uci1 84:80b15993944e 1106 // done with this event.
uci1 84:80b15993944e 1107 // reset flags from the "old" event
uci1 84:80b15993944e 1108 gForcedTrig = false;
uci1 84:80b15993944e 1109 gAdcToMBflag = false;
uci1 84:80b15993944e 1110
uci1 67:ec999336fcd1 1111 led1 = 1; led4 = 0; // end signal reading out
uci1 67:ec999336fcd1 1112
uci1 1:e392595b4b76 1113 }
uci1 12:d472f9811262 1114 #ifdef DEBUG
uci1 1:e392595b4b76 1115 printf("past reading out\r\n");
uci1 12:d472f9811262 1116 #endif
uci1 1:e392595b4b76 1117
uci1 23:ccf39298f205 1118 if (gHrtbtFired) {
uci1 67:ec999336fcd1 1119 led1 = 1; led4 = 1; // signal saving transient
uci1 84:80b15993944e 1120 gHrtbt.SetTime( gLastHrtbt );
uci1 84:80b15993944e 1121 // -1 so we start counting at 0
uci1 84:80b15993944e 1122 // counting inside proc so we have a record of the number of proc's
uci1 84:80b15993944e 1123 // even if we are saving/triggering slower than they're firing
uci1 84:80b15993944e 1124 gHrtbt.SetNum( (gHrtbtNum>0) ? (gHrtbtNum - 1) : 0 );
uci1 23:ccf39298f205 1125 SaveHeartbeat();
uci1 23:ccf39298f205 1126 gHrtbtFired=false;
uci1 84:80b15993944e 1127 gStNewHeartbeat = true;
uci1 67:ec999336fcd1 1128 led1 = 1; led4 = 0; // end signal saving transient
uci1 23:ccf39298f205 1129 }
uci1 12:d472f9811262 1130
uci1 12:d472f9811262 1131 #ifdef EVT_TIME_PROFILE
uci1 84:80b15993944e 1132 gProfiler.stop(); befChkPow=gProfiler.read_us(); gProfiler.start();
uci1 56:0bba0ef15697 1133 #endif // EVT_TIME_PROFILE
uci1 8:95a325df1f6b 1134 // check the power?
uci1 8:95a325df1f6b 1135 if (gCheckPower) {
uci1 12:d472f9811262 1136 #ifdef DEBUG
uci1 8:95a325df1f6b 1137 printf("call check power\r\n");
uci1 12:d472f9811262 1138 #endif
uci1 67:ec999336fcd1 1139 led1 = 1; led4 = 1; // signal saving transient
uci1 8:95a325df1f6b 1140 CheckPower(false);
uci1 84:80b15993944e 1141 gStPower = gPower;
uci1 84:80b15993944e 1142 gStNewPower = true;
uci1 67:ec999336fcd1 1143 led1 = 1; led4 = 0; // end signal saving transient
uci1 8:95a325df1f6b 1144 }
uci1 12:d472f9811262 1145 #ifdef EVT_TIME_PROFILE
uci1 84:80b15993944e 1146 gProfiler.stop(); aftChkPow=gProfiler.read_us(); gProfiler.start();
uci1 56:0bba0ef15697 1147 #endif // EVT_TIME_PROFILE
uci1 56:0bba0ef15697 1148
uci1 56:0bba0ef15697 1149 if (gCheckTemp) {
uci1 56:0bba0ef15697 1150 #ifdef DEBUG
uci1 56:0bba0ef15697 1151 printf("call check temp\r\n");
uci1 12:d472f9811262 1152 #endif
uci1 67:ec999336fcd1 1153 led1 = 1; led4 = 1; // signal saving transient
uci1 56:0bba0ef15697 1154 CheckTemp();
uci1 84:80b15993944e 1155 gStTemperature = gTemperature;
uci1 84:80b15993944e 1156 gStNewTemperature = true;
uci1 67:ec999336fcd1 1157 led1 = 1; led4 = 0; // end signal saving transient
uci1 56:0bba0ef15697 1158 }
uci1 8:95a325df1f6b 1159
uci1 21:ce51bb0ba4a5 1160 // open comm win?
uci1 21:ce51bb0ba4a5 1161 if (gOpenCommWin) {
uci1 21:ce51bb0ba4a5 1162 #ifdef DEBUG
uci1 21:ce51bb0ba4a5 1163 printf("gOpenComWin=%s, opening\r\n",gOpenCommWin?"true":"false");
uci1 41:d6f5e2f09e07 1164 printf("WriteTrigWaitWinTime (stop)\r\n");
uci1 21:ce51bb0ba4a5 1165 #endif
uci1 40:1324da35afd4 1166 SnSDUtils::WriteTrigWaitWinTime(SnSDUtils::GetCurFile(),
uci1 40:1324da35afd4 1167 gClkSet,
uci1 40:1324da35afd4 1168 false);
uci1 84:80b15993944e 1169 gStTrgStopClk = gClkSet;
uci1 67:ec999336fcd1 1170 led1 = 0; // signal not waiting
uci1 21:ce51bb0ba4a5 1171 OpenCommWin();
uci1 67:ec999336fcd1 1172 led1 = 1; // end signal not waiting
uci1 21:ce51bb0ba4a5 1173 gOpenCommWin=false;
uci1 22:f957c4f840ad 1174 gFirstEvt = true;
uci1 40:1324da35afd4 1175 gAllTrgTimer.reset();
uci1 40:1324da35afd4 1176 gThmTrgTimer.reset();
uci1 22:f957c4f840ad 1177 etms=0;
uci1 21:ce51bb0ba4a5 1178 } else {
uci1 21:ce51bb0ba4a5 1179 #ifdef DEBUG
uci1 27:efc4d654b139 1180 printf("gOpenCommWin=false, gCommWinChecks=%u, gNcommWinChecks=%u\r\n",
uci1 27:efc4d654b139 1181 gCommWinChecks, gNcommWinChecks);
uci1 21:ce51bb0ba4a5 1182 #endif
uci1 21:ce51bb0ba4a5 1183 }
uci1 21:ce51bb0ba4a5 1184
uci1 12:d472f9811262 1185 #ifdef EVT_TIME_PROFILE
uci1 84:80b15993944e 1186 gProfiler.stop(); befNewSeq=gProfiler.read_us(); gProfiler.start();
uci1 56:0bba0ef15697 1187 #endif // EVT_TIME_PROFILE
uci1 8:95a325df1f6b 1188 // make new seq?
uci1 8:95a325df1f6b 1189 if (IsSeqComplete()) {
uci1 12:d472f9811262 1190 #ifdef DEBUG
uci1 10:3c93db1cfb12 1191 printf("seq complete. sngseq=%d\r\n",gConf.IsSingleSeqRunMode());
uci1 41:d6f5e2f09e07 1192 printf("WriteTrigWaitWinTime (stop)\r\n");
uci1 12:d472f9811262 1193 #endif
uci1 67:ec999336fcd1 1194 led1 = 1; led2 = 1; led4 = 1; // signal saving file
uci1 40:1324da35afd4 1195 SnSDUtils::WriteTrigWaitWinTime(SnSDUtils::GetCurFile(),
uci1 40:1324da35afd4 1196 gClkSet,
uci1 40:1324da35afd4 1197 false);
uci1 84:80b15993944e 1198 gStTrgStopClk = gClkSet;
uci1 8:95a325df1f6b 1199 MakeOutputFile(gConf.IsSingleSeqRunMode());
uci1 22:f957c4f840ad 1200 gFirstEvt = true;
uci1 40:1324da35afd4 1201 gThmTrgTimer.reset();
uci1 40:1324da35afd4 1202 gAllTrgTimer.reset();
uci1 22:f957c4f840ad 1203 etms=0;
uci1 67:ec999336fcd1 1204 led1 = 1; led2 = 0; led4 = 0; // end signal saving file
uci1 8:95a325df1f6b 1205 }
uci1 12:d472f9811262 1206 #ifdef EVT_TIME_PROFILE
uci1 84:80b15993944e 1207 gProfiler.stop(); aftNewSeq=gProfiler.read_us(); gProfiler.start();
uci1 56:0bba0ef15697 1208 #endif // EVT_TIME_PROFILE
uci1 12:d472f9811262 1209
uci1 12:d472f9811262 1210 #ifdef EVT_TIME_PROFILE
uci1 84:80b15993944e 1211 gProfiler.stop(); endOfLoop=gProfiler.read_us(); gProfiler.start();
uci1 84:80b15993944e 1212 printf("befSaveEvt=%d, aftSaveEvt=%d, "
uci1 12:d472f9811262 1213 "befChkPow=%d, aftChkPow=%d, befNewSeq=%d, aftNewSeq=%d, endOfLoop=%d\r\n",
uci1 84:80b15993944e 1214 befSaveEvt, aftSaveEvt,
uci1 12:d472f9811262 1215 befChkPow, aftChkPow, befNewSeq, aftNewSeq, endOfLoop);
uci1 56:0bba0ef15697 1216 #endif // EVT_TIME_PROFILE
uci1 41:d6f5e2f09e07 1217
uci1 41:d6f5e2f09e07 1218 /*
uci1 15:f2569d8e4176 1219 // get ready to trigger
uci1 15:f2569d8e4176 1220 PIN_spi.format( 16, 1 ); // change to data readout format
uci1 15:f2569d8e4176 1221 PIN_spi.frequency( 10000000 ); // Max is 12.5 MHz
uci1 41:d6f5e2f09e07 1222 */
uci1 22:f957c4f840ad 1223
uci1 21:ce51bb0ba4a5 1224 // reset event
uci1 22:f957c4f840ad 1225 // clear after comm win, so full event can be sent with status
uci1 22:f957c4f840ad 1226 // but don't clear counters or trigger bits, as
uci1 84:80b15993944e 1227 // gEvent.ClearEvent(true);
uci1 21:ce51bb0ba4a5 1228
uci1 41:d6f5e2f09e07 1229 } // end while (true)
uci1 0:664899e0b988 1230
uci1 0:664899e0b988 1231 }
uci1 0:664899e0b988 1232
uci1 0:664899e0b988 1233 //
uci1 22:f957c4f840ad 1234 // save a heartbeat tag
uci1 22:f957c4f840ad 1235 //
uci1 22:f957c4f840ad 1236 void SaveHeartbeat() {
uci1 22:f957c4f840ad 1237 #ifdef DEBUG
uci1 84:80b15993944e 1238 printf("save heartbeat #%u, time %u\r\n",
uci1 84:80b15993944e 1239 gHrtbt.GetNum(), gHrtbt.GetTime());
uci1 22:f957c4f840ad 1240 #endif
uci1 84:80b15993944e 1241 // save to SD
uci1 56:0bba0ef15697 1242 #if CHIPBOARD==ATWD4CH
uci1 84:80b15993944e 1243 PIN_lockRegisters = 0; // unlock so we can talk to the SD card
uci1 56:0bba0ef15697 1244 #else
uci1 84:80b15993944e 1245 PIN_readingData = 0; // unlock so we can talk to the SD card
uci1 56:0bba0ef15697 1246 #endif
uci1 84:80b15993944e 1247 SnSDUtils::WriteHeartbeatTo(SnSDUtils::GetCurFile(), gHrtbt);
uci1 22:f957c4f840ad 1248 }
uci1 22:f957c4f840ad 1249
uci1 22:f957c4f840ad 1250 //
uci1 0:664899e0b988 1251 // save the event
uci1 0:664899e0b988 1252 //
uci1 0:664899e0b988 1253 void SaveEvent(const int32_t etms) {
uci1 0:664899e0b988 1254 // write the event
uci1 12:d472f9811262 1255
uci1 12:d472f9811262 1256 #ifdef DEBUG
uci1 84:80b15993944e 1257 // check that the event is still the same as gLastEvent
uci1 84:80b15993944e 1258 /*
uci1 84:80b15993944e 1259 bool esame = gEvent.GetMbedTime() == gLastEvent.GetMbedTime();
uci1 84:80b15993944e 1260 esame &= gEvent.GetEvtNum() == gLastEvent.GetEvtNum();
uci1 84:80b15993944e 1261 esame &= gEvent.GetDTms() == gLastEvent.GetDTms();
uci1 84:80b15993944e 1262 esame &= gEvent.GetTrgNum() == gLastEvent.GetTrgNum();
uci1 84:80b15993944e 1263 esame &= gEvent.GetTrgBits() == gLastEvent.GetTrgBits();
uci1 84:80b15993944e 1264 esame &= gEvent.GetCRC() == gLastEvent.GetCRC();
uci1 84:80b15993944e 1265 for (uint16_t i=0; i<kTotSamps; ++i) {
uci1 84:80b15993944e 1266 esame &= (gEvent.GetData())[i] == (gLastEvent.GetData())[i];
uci1 84:80b15993944e 1267 }
uci1 84:80b15993944e 1268 #if CHIPBOARD!=ATWD4CH
uci1 84:80b15993944e 1269 for (uint16_t i=0; i<kNstopBytes; ++i) {
uci1 84:80b15993944e 1270 esame &= (gEvent.GetStop())[i] == (gLastEvent.GetStop())[i];
uci1 84:80b15993944e 1271 }
uci1 84:80b15993944e 1272 printf("EEEEEEEE event==lastEvt = %s\r\n", (esame?"true":"false"));
uci1 84:80b15993944e 1273 #endif
uci1 84:80b15993944e 1274 */
uci1 84:80b15993944e 1275 #endif
uci1 84:80b15993944e 1276
uci1 84:80b15993944e 1277 // ok, now we can overwrite the old gEvent data
uci1 84:80b15993944e 1278 // reset event
uci1 84:80b15993944e 1279 gEvent.ClearEvent(true, true);
uci1 84:80b15993944e 1280
uci1 84:80b15993944e 1281 // read data & calc CRC
uci1 84:80b15993944e 1282 #ifdef EVT_TIME_PROFILE
uci1 84:80b15993944e 1283 int befReadWv=0, aftReadWv=0, befWriteEvt=0, aftWriteEvt=0;
uci1 84:80b15993944e 1284 gProfiler.stop(); befReadWv=gProfiler.read_us(); gProfiler.start();
uci1 84:80b15993944e 1285 #endif // EVT_TIME_PROFILE
uci1 84:80b15993944e 1286
uci1 84:80b15993944e 1287 #if CHIPBOARD==ATWD4CH
uci1 84:80b15993944e 1288 // get the data to the MBED
uci1 84:80b15993944e 1289 gEvent.ReadWaveformsATWD(PIN_spi, PIN_selCardHiBit, PIN_selCardLoBit);
uci1 84:80b15993944e 1290 #else
uci1 84:80b15993944e 1291 gEvent.ReadWaveformsSST(PIN_spi, PIN_readingData);
uci1 84:80b15993944e 1292 // reset in case a trigger arrived before we were ready
uci1 84:80b15993944e 1293 PIN_ResetChips = 1;
uci1 84:80b15993944e 1294 // wait_us(1);
uci1 84:80b15993944e 1295 PIN_ResetChips = 0;
uci1 84:80b15993944e 1296 #endif //ATWD4CH
uci1 84:80b15993944e 1297
uci1 84:80b15993944e 1298 #ifdef EVT_TIME_PROFILE
uci1 84:80b15993944e 1299 gProfiler.stop(); aftReadWv=gProfiler.read_us(); gProfiler.start();
uci1 84:80b15993944e 1300 #endif // EVT_TIME_PROFILE
uci1 84:80b15993944e 1301
uci1 84:80b15993944e 1302 gEvent.SetCurMbedTime();
uci1 84:80b15993944e 1303
uci1 84:80b15993944e 1304 Watchdog::kick(); // don't reset!
uci1 84:80b15993944e 1305
uci1 84:80b15993944e 1306 #ifdef DEBUG
uci1 84:80b15993944e 1307 printf("gFirstEvt=%s\r\n",gFirstEvt?"true":"false");
uci1 84:80b15993944e 1308 #endif
uci1 84:80b15993944e 1309
uci1 84:80b15993944e 1310 #if CHIPBOARD==ATWD4CH
uci1 84:80b15993944e 1311 PIN_lockRegisters = 0; // done reading, unlock so we can talk to the SD card
uci1 84:80b15993944e 1312 #else
uci1 84:80b15993944e 1313 // (this is redundant; it's already set low by SnEventFrame)
uci1 84:80b15993944e 1314 PIN_readingData = 0; // done reading, unlock so we can talk to the SD card
uci1 84:80b15993944e 1315 #endif // ATWD4CH
uci1 84:80b15993944e 1316
uci1 84:80b15993944e 1317 #ifdef DEBUG
uci1 84:80b15993944e 1318 printf("waveform read out. save event (%u)\r\n", gEvtNum);
uci1 12:d472f9811262 1319 #endif
uci1 3:24c5f0f50bf1 1320
uci1 0:664899e0b988 1321 // set the event number & dt
uci1 3:24c5f0f50bf1 1322 gEvent.SetEvtNum(gEvtNum);
uci1 0:664899e0b988 1323 gEvent.SetDTms(etms);
uci1 84:80b15993944e 1324 // set trigger bits
uci1 84:80b15993944e 1325 if (gForcedTrig) {
uci1 84:80b15993944e 1326 gEvent.SetTrgBit(kForced);
uci1 84:80b15993944e 1327 // gEvent.SetTrgNum(gTrgNum[kFrcTrg]);
uci1 84:80b15993944e 1328 gEvent.SetTrgNum(gNumFrcTrigs);
uci1 84:80b15993944e 1329 } else {
uci1 84:80b15993944e 1330 gEvent.SetTrgBit(kThermal);
uci1 84:80b15993944e 1331 // gEvent.SetTrgNum(gTrgNum[kThmTrg]);
uci1 84:80b15993944e 1332 gEvent.SetTrgNum(gNumThmTrigs);
uci1 84:80b15993944e 1333 }
uci1 84:80b15993944e 1334 if (gAdcToMBflag) {
uci1 84:80b15993944e 1335 gEvent.SetTrgBit(kAdcToMBflag);
uci1 84:80b15993944e 1336 }
uci1 0:664899e0b988 1337
uci1 84:80b15993944e 1338 // this is in the config too, but doesn't hurt to flip the bit
uci1 84:80b15993944e 1339 // in the event
uci1 84:80b15993944e 1340 if (gConf.IsL1TrigApplied()) {
uci1 84:80b15993944e 1341 gEvent.SetTrgBit(kL1TrgApplied);
uci1 84:80b15993944e 1342 }
uci1 84:80b15993944e 1343
uci1 84:80b15993944e 1344 // ----
uci1 84:80b15993944e 1345 // L1 check(s) go here!
uci1 84:80b15993944e 1346 bool L1okToSave = true;
uci1 84:80b15993944e 1347
uci1 84:80b15993944e 1348 #ifdef DEBUG
uci1 84:80b15993944e 1349 Timer l1timer;
uci1 84:80b15993944e 1350 l1timer.start();
uci1 84:80b15993944e 1351 printf("L1 single freq supp ratio = %hhu (%g)\r\n",
uci1 84:80b15993944e 1352 gConf.GetSingleFreqSuppRatioRaw(),
uci1 84:80b15993944e 1353 gConf.GetSingleFreqSuppRatio());
uci1 84:80b15993944e 1354 #endif
uci1 84:80b15993944e 1355
uci1 84:80b15993944e 1356 // TODO: move the FFT calculation out here so that
uci1 84:80b15993944e 1357 // other L1's could use it too. haven't done this already
uci1 84:80b15993944e 1358 // in order to save RAM and not cache the whole thing when
uci1 84:80b15993944e 1359 // we only have one L1 cut.
uci1 84:80b15993944e 1360
uci1 84:80b15993944e 1361 // check L1 single frequency suppression cut
uci1 84:80b15993944e 1362 if ( gConf.IsSingleFreqSuppEnabled() ) {
uci1 84:80b15993944e 1363 const EL1TrigStatus passL1SingleFreqSupp =
uci1 84:80b15993944e 1364 SnL1SingleFreqSupp::ProcessEvent(gEvent, gChanFFT,
uci1 84:80b15993944e 1365 gConf.GetSingleFreqSuppRatio());
uci1 84:80b15993944e 1366 #ifdef DEBUG
uci1 84:80b15993944e 1367 l1timer.stop();
uci1 84:80b15993944e 1368 printf("L1 single freq supp took [%d] us\r\n",
uci1 84:80b15993944e 1369 l1timer.read_us());
uci1 84:80b15993944e 1370 printf("passL1SingleFreqSupp=%s\r\n",
uci1 84:80b15993944e 1371 passL1SingleFreqSupp==kL1Pass ? "pass"
uci1 84:80b15993944e 1372 : passL1SingleFreqSupp==kL1Fail ? "fail"
uci1 84:80b15993944e 1373 : "other");
uci1 84:80b15993944e 1374 #endif
uci1 84:80b15993944e 1375 if (passL1SingleFreqSupp==kL1Pass) {
uci1 84:80b15993944e 1376 gEvent.SetTrgBit(kSingleFreqSupp);
uci1 84:80b15993944e 1377 } else if ( (passL1SingleFreqSupp==kL1Fail) &&
uci1 84:80b15993944e 1378 gConf.IsL1TrigApplied() ) {
uci1 84:80b15993944e 1379 L1okToSave = false;
uci1 84:80b15993944e 1380 }
uci1 84:80b15993944e 1381 // else if kL1UnableToProcess, the bit won't get set
uci1 84:80b15993944e 1382 // but the event can/will be saved
uci1 84:80b15993944e 1383 }
uci1 84:80b15993944e 1384
uci1 84:80b15993944e 1385
uci1 84:80b15993944e 1386 // NO MORE L1 checks below here! (or the scaledown won't work)
uci1 84:80b15993944e 1387 // -----
uci1 84:80b15993944e 1388
uci1 84:80b15993944e 1389 #ifdef EVT_TIME_PROFILE
uci1 84:80b15993944e 1390 gProfiler.stop(); befWriteEvt=gProfiler.read_us(); gProfiler.start();
uci1 84:80b15993944e 1391 #endif // EVT_TIME_PROFILE
uci1 84:80b15993944e 1392
uci1 0:664899e0b988 1393 // save to SD
uci1 56:0bba0ef15697 1394 #if CHIPBOARD==ATWD4CH
uci1 56:0bba0ef15697 1395 PIN_lockRegisters = 0; // unlock so we can talk to the SD card
uci1 56:0bba0ef15697 1396 #else
uci1 56:0bba0ef15697 1397 PIN_readingData = 0; // unlock so we can talk to the SD card
uci1 56:0bba0ef15697 1398 #endif
uci1 84:80b15993944e 1399
uci1 84:80b15993944e 1400 // scale down to override L1 trigger failures
uci1 84:80b15993944e 1401 if ( (L1okToSave==false) && (gConf.GetL1Scaledown()!=0) ) {
uci1 84:80b15993944e 1402 ++gL1ScaledownCount;
uci1 84:80b15993944e 1403
uci1 84:80b15993944e 1404 if ( gL1ScaledownCount == gConf.GetL1Scaledown() ) {
uci1 84:80b15993944e 1405 gL1ScaledownCount = 0;
uci1 84:80b15993944e 1406 L1okToSave = true;
uci1 84:80b15993944e 1407 #ifdef DEBUG
uci1 84:80b15993944e 1408 printf("))) L1 scaledown!\r\n");
uci1 84:80b15993944e 1409 #endif
uci1 84:80b15993944e 1410 }
uci1 84:80b15993944e 1411 }
uci1 84:80b15993944e 1412
uci1 84:80b15993944e 1413 #ifdef DEBUG
uci1 84:80b15993944e 1414 printf("L1 scaledown count = %hhu, scaledown=%hhu, L1okToSave=%s\r\n",
uci1 84:80b15993944e 1415 gL1ScaledownCount,
uci1 84:80b15993944e 1416 gConf.GetL1Scaledown(),
uci1 84:80b15993944e 1417 L1okToSave ? "true" : "false");
uci1 84:80b15993944e 1418 printf("event trigger bits = ");
uci1 84:80b15993944e 1419 SnBitUtils::printBits(gEvent.GetTrgBits(), true);
uci1 84:80b15993944e 1420 #endif
uci1 0:664899e0b988 1421
uci1 84:80b15993944e 1422 // always save forced triggers
uci1 84:80b15993944e 1423 if (L1okToSave || gForcedTrig) {
uci1 84:80b15993944e 1424 SnSDUtils::WriteEventTo(SnSDUtils::GetCurFile(), gGenBuf, gEvent, gConf);
uci1 84:80b15993944e 1425
uci1 84:80b15993944e 1426 // a good event
uci1 84:80b15993944e 1427 gStNewEvent = true;
uci1 84:80b15993944e 1428
uci1 84:80b15993944e 1429 // send it?
uci1 84:80b15993944e 1430 if ( gConf.IsCommWindowEachEvent() ) {
uci1 84:80b15993944e 1431 #ifdef DEBUG
uci1 84:80b15993944e 1432 printf("COMM EACH EVENT => gOpenCommWin = true\r\n");
uci1 84:80b15993944e 1433 #endif
uci1 84:80b15993944e 1434 gOpenCommWin = true;
uci1 84:80b15993944e 1435 }
uci1 84:80b15993944e 1436 }
uci1 84:80b15993944e 1437
uci1 84:80b15993944e 1438 #ifdef EVT_TIME_PROFILE
uci1 84:80b15993944e 1439 gProfiler.stop(); aftWriteEvt=gProfiler.read_us(); gProfiler.start();
uci1 84:80b15993944e 1440 printf("befReadWv=%d, aftReadWv=%d, befWriteEvt=%d, aftWriteEvt=%d\r\n",
uci1 84:80b15993944e 1441 befReadWv, aftReadWv, befWriteEvt, aftWriteEvt);
uci1 84:80b15993944e 1442 #endif // EVT_TIME_PROFILE
uci1 84:80b15993944e 1443
uci1 40:1324da35afd4 1444 // make a copy in case we need to send it with the status
uci1 40:1324da35afd4 1445 // (copy it because we are going to clear this event while
uci1 40:1324da35afd4 1446 // waiting for the next trigger)
uci1 84:80b15993944e 1447 // gEvent.CopyTo(gLastEvent);
uci1 40:1324da35afd4 1448
uci1 3:24c5f0f50bf1 1449 // increment event number
uci1 3:24c5f0f50bf1 1450 ++gEvtNum;
uci1 3:24c5f0f50bf1 1451
uci1 12:d472f9811262 1452 #ifdef DEBUG
uci1 84:80b15993944e 1453 printf("next gEvtNum=%u\r\n",gEvtNum);
uci1 12:d472f9811262 1454 #endif
uci1 3:24c5f0f50bf1 1455 }
uci1 3:24c5f0f50bf1 1456
uci1 3:24c5f0f50bf1 1457 void MakeOutputFile(const bool stopRunning) {
uci1 56:0bba0ef15697 1458 #if CHIPBOARD==ATWD4CH
uci1 56:0bba0ef15697 1459 PIN_lockRegisters = 0; // unlock so we can talk to the SD card
uci1 56:0bba0ef15697 1460 #else
uci1 56:0bba0ef15697 1461 PIN_readingData = 0; // unlock so we can talk to the SD card
uci1 56:0bba0ef15697 1462 #endif
uci1 12:d472f9811262 1463 #ifdef DEBUG
uci1 10:3c93db1cfb12 1464 printf("closing output file. gEvtNum=%u, gPowNum=%u, stop=%d\r\n",
uci1 10:3c93db1cfb12 1465 gEvtNum,gPowNum,(int)stopRunning);
uci1 12:d472f9811262 1466 #endif
uci1 13:7a1fb885a8e4 1467
uci1 3:24c5f0f50bf1 1468 SnSDUtils::CloseOutputFile(SnSDUtils::GetCurFile());
uci1 13:7a1fb885a8e4 1469
uci1 12:d472f9811262 1470 #ifdef DEBUG
uci1 10:3c93db1cfb12 1471 printf("file closed\r\n");
uci1 12:d472f9811262 1472 #endif
uci1 3:24c5f0f50bf1 1473 if (stopRunning) {
uci1 8:95a325df1f6b 1474 StopRunning();
uci1 0:664899e0b988 1475 }
uci1 56:0bba0ef15697 1476 FILE* cf = SnSDUtils::OpenNewOutputFile(SnConfigFrame::GetMacAddress(),
uci1 40:1324da35afd4 1477 gConf.GetRun(),
uci1 76:f8383f0292c2 1478 gConf.GetFirstSeq(),
uci1 76:f8383f0292c2 1479 gConf.IsSendingFilesRunSeqList());
uci1 13:7a1fb885a8e4 1480 // reset event, timers, trigger counters
uci1 84:80b15993944e 1481 ResetCounters();
uci1 8:95a325df1f6b 1482 if (cf!=0) {
uci1 40:1324da35afd4 1483 #ifdef USE_RTOS
uci1 40:1324da35afd4 1484 Thread::wait(200);
uci1 40:1324da35afd4 1485 #else
uci1 8:95a325df1f6b 1486 wait_ms(200);
uci1 40:1324da35afd4 1487 #endif
uci1 8:95a325df1f6b 1488 GetAvePowerReading();
uci1 12:d472f9811262 1489 #ifdef DEBUG
uci1 8:95a325df1f6b 1490 printf("writing power. v1=%g, v2=%g, r1=%g, r2=%g, t=%u, pownum=%u\r\n",
uci1 8:95a325df1f6b 1491 gPower.GetAveV1(), gPower.GetAveV2(),
uci1 8:95a325df1f6b 1492 gPower.GetRmsV1(), gPower.GetRmsV2(), gPower.GetTime(),
uci1 8:95a325df1f6b 1493 gPowNum);
uci1 12:d472f9811262 1494 #endif
uci1 8:95a325df1f6b 1495 SnSDUtils::WritePowerTo(cf, gPower, gPowNum);
uci1 8:95a325df1f6b 1496 }
uci1 12:d472f9811262 1497 #ifdef DEBUG
uci1 3:24c5f0f50bf1 1498 printf("made output file with run %u\r\n",gConf.GetRun());
uci1 3:24c5f0f50bf1 1499 printf("filename=%s\r\n",SnSDUtils::GetCurFileName());
uci1 12:d472f9811262 1500 #endif
uci1 3:24c5f0f50bf1 1501 SnSDUtils::WriteConfig(SnSDUtils::GetCurFile(), gConf);
uci1 19:74155d652c37 1502 #ifdef DEBUG
uci1 19:74155d652c37 1503 printf("write config to file\r\n");
uci1 19:74155d652c37 1504 #endif
uci1 0:664899e0b988 1505 }
uci1 0:664899e0b988 1506
uci1 40:1324da35afd4 1507 bool PowerDownCommPeriph(const SnConfigFrame::EDatPackBit type) {
uci1 67:ec999336fcd1 1508 #ifdef DEBUG
uci1 67:ec999336fcd1 1509 printf("PowerDownCommPeriph: type=%d\r\n",(int)type);
uci1 67:ec999336fcd1 1510 #endif
uci1 40:1324da35afd4 1511 SnCommWin** cw = gComms;
uci1 56:0bba0ef15697 1512 for (uint8_t i=0; i<kNcomms; ++i, ++cw) {
uci1 40:1324da35afd4 1513 if ((*cw)==0) {
uci1 40:1324da35afd4 1514 continue;
uci1 40:1324da35afd4 1515 } else if ((*cw)->GetCommType()==type) {
uci1 67:ec999336fcd1 1516 #ifdef DEBUG
uci1 67:ec999336fcd1 1517 printf("calling PowerDown\r\n");
uci1 67:ec999336fcd1 1518 #endif
uci1 40:1324da35afd4 1519 return (*cw)->PowerDown(gConf.GetTimeoutTime(time(0),
uci1 84:80b15993944e 1520 gConf.GetCommWinConnectTO(type)));
uci1 40:1324da35afd4 1521 }
uci1 40:1324da35afd4 1522 }
uci1 40:1324da35afd4 1523 return false;
uci1 40:1324da35afd4 1524 }
uci1 40:1324da35afd4 1525
uci1 0:664899e0b988 1526 //
uci1 4:a91682e19d6b 1527 // power stuff
uci1 4:a91682e19d6b 1528 //
uci1 67:ec999336fcd1 1529 bool IsCurrentlyPowered(const SnConfigFrame::EPowerModeBit p,
uci1 67:ec999336fcd1 1530 DigitalOut& pin) {
uci1 67:ec999336fcd1 1531 // check if the current pin value is equal to
uci1 67:ec999336fcd1 1532 // what it should be if the peripheral is on
uci1 67:ec999336fcd1 1533 return gConf.GetPowPinSetting(p, true) == pin.read();
uci1 67:ec999336fcd1 1534 }
uci1 67:ec999336fcd1 1535
uci1 84:80b15993944e 1536 void ChangeCardPower(const bool isCommWin,
uci1 84:80b15993944e 1537 const bool isOn) {
uci1 67:ec999336fcd1 1538 // change cards power
uci1 67:ec999336fcd1 1539 const SnConfigFrame::EPowerModeBit pbit = (isCommWin)
uci1 67:ec999336fcd1 1540 ? SnConfigFrame::kCardComWin
uci1 67:ec999336fcd1 1541 : SnConfigFrame::kCardDatTak;
uci1 84:80b15993944e 1542 const int value = gConf.GetPowPinSetting(pbit, isOn);
uci1 21:ce51bb0ba4a5 1543 #ifdef DEBUG
uci1 67:ec999336fcd1 1544 printf("setting cards pin power to %d (comm=%d)\r\n",
uci1 67:ec999336fcd1 1545 value, static_cast<int>(isCommWin));
uci1 21:ce51bb0ba4a5 1546 #endif
uci1 67:ec999336fcd1 1547 PIN_turn_on_system = value;
uci1 40:1324da35afd4 1548 #ifdef USE_RTOS
uci1 40:1324da35afd4 1549 Thread::wait(10);
uci1 40:1324da35afd4 1550 #else
uci1 30:f869ed4bcc08 1551 wait_ms(10);
uci1 40:1324da35afd4 1552 #endif
uci1 67:ec999336fcd1 1553 }
uci1 67:ec999336fcd1 1554
uci1 84:80b15993944e 1555 void ChangeAmpsPower(const bool isCommWin,
uci1 84:80b15993944e 1556 const bool isOn) {
uci1 40:1324da35afd4 1557 // change amps power
uci1 67:ec999336fcd1 1558 const SnConfigFrame::EPowerModeBit pbit = (isCommWin)
uci1 67:ec999336fcd1 1559 ? SnConfigFrame::kAmpsComWin
uci1 67:ec999336fcd1 1560 : SnConfigFrame::kAmpsDatTak;
uci1 84:80b15993944e 1561 const int value = gConf.GetPowPinSetting(pbit, isOn);
uci1 40:1324da35afd4 1562 #ifdef DEBUG
uci1 67:ec999336fcd1 1563 printf("setting amps pin power to %d (comm=%d)\r\n",
uci1 67:ec999336fcd1 1564 value, static_cast<int>(isCommWin));
uci1 40:1324da35afd4 1565 #endif
uci1 67:ec999336fcd1 1566 PIN_turn_on_amps = value;
uci1 40:1324da35afd4 1567 #ifdef USE_RTOS
uci1 40:1324da35afd4 1568 Thread::wait(10);
uci1 40:1324da35afd4 1569 #else
uci1 30:f869ed4bcc08 1570 wait_ms(10);
uci1 40:1324da35afd4 1571 #endif
uci1 67:ec999336fcd1 1572 }
uci1 67:ec999336fcd1 1573
uci1 84:80b15993944e 1574 void ChangeIridPower(const bool isCommWin,
uci1 84:80b15993944e 1575 const bool isOn) {
uci1 67:ec999336fcd1 1576 // change iridium power setting
uci1 67:ec999336fcd1 1577 // if going from ON to OFF, call the special
uci1 67:ec999336fcd1 1578 // power down procedure, so as not to lose
uci1 67:ec999336fcd1 1579 // the non-volatile memory settings
uci1 67:ec999336fcd1 1580
uci1 67:ec999336fcd1 1581 const SnConfigFrame::EPowerModeBit ibit = (isCommWin)
uci1 67:ec999336fcd1 1582 ? SnConfigFrame::kIridComWin
uci1 67:ec999336fcd1 1583 : SnConfigFrame::kIridDatTak;
uci1 67:ec999336fcd1 1584 const SnConfigFrame::EPowerModeBit abit = (isCommWin)
uci1 67:ec999336fcd1 1585 ? SnConfigFrame::kAfarComWin
uci1 67:ec999336fcd1 1586 : SnConfigFrame::kAfarDatTak;
uci1 67:ec999336fcd1 1587
uci1 67:ec999336fcd1 1588 // these checks are complicated because the iridium might
uci1 67:ec999336fcd1 1589 // be powered off the Afar (12V) relay,
uci1 67:ec999336fcd1 1590 // rather than the iridium (5V) relay
uci1 67:ec999336fcd1 1591 const bool iridFromOn = (kIridPwrFromAfar) ?
uci1 67:ec999336fcd1 1592 IsCurrentlyPowered(abit, PIN_afar_power) :
uci1 67:ec999336fcd1 1593 IsCurrentlyPowered(ibit, PIN_iridSbd_power);
uci1 84:80b15993944e 1594 if ( iridFromOn && (isOn==false) ) {
uci1 40:1324da35afd4 1595 #ifdef DEBUG
uci1 40:1324da35afd4 1596 printf("calling PowerDown for Iridium\r\n");
uci1 40:1324da35afd4 1597 #endif
uci1 40:1324da35afd4 1598 PowerDownCommPeriph(SnConfigFrame::kIrid);
uci1 40:1324da35afd4 1599 }
uci1 67:ec999336fcd1 1600 const int value = (kIridPwrFromAfar)
uci1 67:ec999336fcd1 1601 ? gConf.GetPowPinSetting(ibit, false) // leave the iridium relay off. use afar relay.
uci1 84:80b15993944e 1602 : gConf.GetPowPinSetting(ibit, isOn);
uci1 40:1324da35afd4 1603 #ifdef DEBUG
uci1 67:ec999336fcd1 1604 printf("setting iridium pin power to %d (comm=%d)\r\n",
uci1 67:ec999336fcd1 1605 value, static_cast<int>(isCommWin));
uci1 40:1324da35afd4 1606 #endif
uci1 67:ec999336fcd1 1607 PIN_iridSbd_power = value;
uci1 40:1324da35afd4 1608 #ifdef USE_RTOS
uci1 40:1324da35afd4 1609 Thread::wait(10);
uci1 40:1324da35afd4 1610 #else
uci1 30:f869ed4bcc08 1611 wait_ms(10);
uci1 40:1324da35afd4 1612 #endif
uci1 67:ec999336fcd1 1613
uci1 67:ec999336fcd1 1614 }
uci1 67:ec999336fcd1 1615
uci1 84:80b15993944e 1616 void ChangeAfarPower(const bool isCommWin,
uci1 84:80b15993944e 1617 const bool isOn) {
uci1 67:ec999336fcd1 1618 // change the AFAR relay power setting
uci1 67:ec999336fcd1 1619 // also power up or down the ethernet PHY port
uci1 67:ec999336fcd1 1620 // as appropriate
uci1 67:ec999336fcd1 1621 // the procedure is complicated by the fact that
uci1 67:ec999336fcd1 1622 // the iridium may be powered off the Afar (12V) relay,
uci1 67:ec999336fcd1 1623 // in which case we need to turn this relay on if
uci1 67:ec999336fcd1 1624 // *either* Afar or iridium want power
uci1 67:ec999336fcd1 1625 #ifdef DEBUG
uci1 67:ec999336fcd1 1626 printf("bef: pconp=%u (%08x), pcenet=%u (%08x)\r\n",
uci1 67:ec999336fcd1 1627 LPC_SC->PCONP, LPC_SC->PCONP, LPC1768_PCONP_PCENET, LPC1768_PCONP_PCENET);
uci1 67:ec999336fcd1 1628 printf("pcenet bef power: status=%d\r\n",Peripheral_GetStatus(LPC1768_PCONP_PCENET));
uci1 67:ec999336fcd1 1629 #endif
uci1 67:ec999336fcd1 1630
uci1 67:ec999336fcd1 1631 const SnConfigFrame::EPowerModeBit abit = (isCommWin)
uci1 67:ec999336fcd1 1632 ? SnConfigFrame::kAfarComWin
uci1 67:ec999336fcd1 1633 : SnConfigFrame::kAfarDatTak;
uci1 67:ec999336fcd1 1634
uci1 67:ec999336fcd1 1635 const bool afarFromOn = IsCurrentlyPowered(abit, PIN_afar_power);
uci1 67:ec999336fcd1 1636
uci1 40:1324da35afd4 1637 // change ethernet PHY port power
uci1 21:ce51bb0ba4a5 1638 #ifdef DEBUG
uci1 67:ec999336fcd1 1639 printf("afar pin=%d, afarFromOn=%d, afarToOn=%d\r\n",
uci1 67:ec999336fcd1 1640 PIN_afar_power.read(), static_cast<int>(afarFromOn),
uci1 84:80b15993944e 1641 static_cast<int>(isOn));
uci1 21:ce51bb0ba4a5 1642 #endif
uci1 84:80b15993944e 1643 if (isOn) {
uci1 21:ce51bb0ba4a5 1644 #ifdef DEBUG
uci1 30:f869ed4bcc08 1645 printf("PHY cowin powering up\r\n");
uci1 21:ce51bb0ba4a5 1646 #endif
uci1 40:1324da35afd4 1647 PHY_PowerUp();
uci1 40:1324da35afd4 1648 #ifdef USE_RTOS
uci1 40:1324da35afd4 1649 Thread::wait(1000);
uci1 40:1324da35afd4 1650 #else
uci1 40:1324da35afd4 1651 wait(1);
uci1 40:1324da35afd4 1652 #endif
uci1 21:ce51bb0ba4a5 1653 #ifdef DEBUG
uci1 30:f869ed4bcc08 1654 printf("PHY cowin powered up\r\n");
uci1 21:ce51bb0ba4a5 1655 #endif
uci1 4:a91682e19d6b 1656 } else {
uci1 40:1324da35afd4 1657 // change afar power
uci1 40:1324da35afd4 1658 // power down periph if going from on to off
uci1 40:1324da35afd4 1659 // change afar power
uci1 40:1324da35afd4 1660 if (afarFromOn) {
uci1 40:1324da35afd4 1661 PowerDownCommPeriph(SnConfigFrame::kAfar);
uci1 40:1324da35afd4 1662 }
uci1 21:ce51bb0ba4a5 1663 #ifdef DEBUG
uci1 30:f869ed4bcc08 1664 printf("PHY cowin powering down\r\n");
uci1 21:ce51bb0ba4a5 1665 #endif
uci1 40:1324da35afd4 1666 PHY_PowerDown();
uci1 40:1324da35afd4 1667 #ifdef USE_RTOS
uci1 40:1324da35afd4 1668 Thread::wait(1000);
uci1 40:1324da35afd4 1669 #else
uci1 40:1324da35afd4 1670 wait(1);
uci1 40:1324da35afd4 1671 #endif
uci1 21:ce51bb0ba4a5 1672 #ifdef DEBUG
uci1 30:f869ed4bcc08 1673 printf("PHY cowin powered down\r\n");
uci1 21:ce51bb0ba4a5 1674 #endif
uci1 30:f869ed4bcc08 1675 }
uci1 21:ce51bb0ba4a5 1676 #ifdef DEBUG
uci1 30:f869ed4bcc08 1677 printf("PHY done\r\n");
uci1 21:ce51bb0ba4a5 1678 #endif
uci1 40:1324da35afd4 1679 #ifdef USE_RTOS
uci1 40:1324da35afd4 1680 Thread::wait(100);
uci1 40:1324da35afd4 1681 #else
uci1 30:f869ed4bcc08 1682 wait_ms(100);
uci1 40:1324da35afd4 1683 #endif
uci1 67:ec999336fcd1 1684
uci1 40:1324da35afd4 1685 // change afar power
uci1 84:80b15993944e 1686 const int value = gConf.GetPowPinSetting(abit, isOn);
uci1 67:ec999336fcd1 1687 PIN_afar_power = value;
uci1 40:1324da35afd4 1688 #ifdef USE_RTOS
uci1 40:1324da35afd4 1689 Thread::wait(1500);
uci1 40:1324da35afd4 1690 #else
uci1 40:1324da35afd4 1691 wait(1.5);
uci1 40:1324da35afd4 1692 #endif
uci1 12:d472f9811262 1693 #ifdef DEBUG
uci1 21:ce51bb0ba4a5 1694 printf("aft: pconp=%u (%08x), pcenet=%u (%08x)\r\n",
uci1 21:ce51bb0ba4a5 1695 LPC_SC->PCONP, LPC_SC->PCONP, LPC1768_PCONP_PCENET, LPC1768_PCONP_PCENET);
uci1 67:ec999336fcd1 1696 printf("pcenet aft power: status=%d\r\n",Peripheral_GetStatus(LPC1768_PCONP_PCENET));
uci1 21:ce51bb0ba4a5 1697 #endif
uci1 67:ec999336fcd1 1698
uci1 67:ec999336fcd1 1699 }
uci1 67:ec999336fcd1 1700
uci1 84:80b15993944e 1701 bool IsPowerAllowedFor(const bool isCommWin,
uci1 84:80b15993944e 1702 const uint8_t devicesInUse,
uci1 84:80b15993944e 1703 const SnConfigFrame::EDatPackBit b) {
uci1 84:80b15993944e 1704 if (isCommWin && (gConf.IsCommPowerSimple()==false)) {
uci1 84:80b15993944e 1705 return ( (devicesInUse & b)!=0 );
uci1 84:80b15993944e 1706 }
uci1 84:80b15993944e 1707 return true;
uci1 84:80b15993944e 1708 }
uci1 84:80b15993944e 1709
uci1 84:80b15993944e 1710 void SetPower(const bool isCommWin,
uci1 84:80b15993944e 1711 const uint8_t devicesInUse) {
uci1 84:80b15993944e 1712 // devicesInUse could really just be a second set of "power mode" bits
uci1 84:80b15993944e 1713 // where the bit being on means "I want to change power for this device"
uci1 84:80b15993944e 1714 // but then.. how to handle the possibility that the bit word contains,
uci1 84:80b15993944e 1715 // for example, both bits AfarDatTak and AfarComWin being on?
uci1 84:80b15993944e 1716 // so instead, we keep the "isCommWin" boolean which forces the separation
uci1 84:80b15993944e 1717 // and deviceInUse is only applied when isCommWin==true
uci1 84:80b15993944e 1718 //
uci1 84:80b15993944e 1719 // multiple devices can be specified by, e.g., kIrid | kAfar
uci1 67:ec999336fcd1 1720 #ifdef DEBUG
uci1 67:ec999336fcd1 1721 printf("set power. isCommWin=%s\r\n",(isCommWin)?"true":"false");
uci1 67:ec999336fcd1 1722 printf("WD reset = %d\r\n",(int)Watchdog::didWatchdogReset());
uci1 67:ec999336fcd1 1723 printf("power word (%hhu): ",gConf.GetPowerMode()); SnBitUtils::printBits(gConf.GetPowerMode(),true);
uci1 67:ec999336fcd1 1724 printf("IsPoweredFor CardDatTak = %d\r\n",(int)gConf.IsPoweredFor(SnConfigFrame::kCardDatTak));
uci1 67:ec999336fcd1 1725 printf("IsPoweredFor AmpsDatTak = %d\r\n",(int)gConf.IsPoweredFor(SnConfigFrame::kAmpsDatTak));
uci1 67:ec999336fcd1 1726 printf("IsPoweredFor IridDatTak = %d\r\n",(int)gConf.IsPoweredFor(SnConfigFrame::kIridDatTak));
uci1 67:ec999336fcd1 1727 printf("IsPoweredFor AfarDatTak = %d\r\n",(int)gConf.IsPoweredFor(SnConfigFrame::kAfarDatTak));
uci1 67:ec999336fcd1 1728 printf("IsPoweredFor CardComWin = %d\r\n",(int)gConf.IsPoweredFor(SnConfigFrame::kCardComWin));
uci1 67:ec999336fcd1 1729 printf("IsPoweredFor AmpsComWin = %d\r\n",(int)gConf.IsPoweredFor(SnConfigFrame::kAmpsComWin));
uci1 67:ec999336fcd1 1730 printf("IsPoweredFor IridComWin = %d\r\n",(int)gConf.IsPoweredFor(SnConfigFrame::kIridComWin));
uci1 67:ec999336fcd1 1731 printf("IsPoweredFor AfarComWin = %d\r\n",(int)gConf.IsPoweredFor(SnConfigFrame::kAfarComWin));
uci1 84:80b15993944e 1732 printf("devicesInUse = %hhu\r\n", (uint8_t)devicesInUse);
uci1 84:80b15993944e 1733 printf("IsCommPowerSimple = %s\r\n", (gConf.IsCommPowerSimple() ? "true" : "false"));
uci1 67:ec999336fcd1 1734 #endif
uci1 67:ec999336fcd1 1735
uci1 67:ec999336fcd1 1736 const SnConfigFrame::EPowerModeBit cardpb = (isCommWin)
uci1 67:ec999336fcd1 1737 ? SnConfigFrame::kCardComWin
uci1 67:ec999336fcd1 1738 : SnConfigFrame::kCardDatTak;
uci1 67:ec999336fcd1 1739 const SnConfigFrame::EPowerModeBit ampspb = (isCommWin)
uci1 67:ec999336fcd1 1740 ? SnConfigFrame::kAmpsComWin
uci1 67:ec999336fcd1 1741 : SnConfigFrame::kAmpsDatTak;
uci1 67:ec999336fcd1 1742 const SnConfigFrame::EPowerModeBit iridpb = (isCommWin)
uci1 67:ec999336fcd1 1743 ? SnConfigFrame::kIridComWin
uci1 67:ec999336fcd1 1744 : SnConfigFrame::kIridDatTak;
uci1 67:ec999336fcd1 1745 const SnConfigFrame::EPowerModeBit afarpb = (isCommWin)
uci1 67:ec999336fcd1 1746 ? SnConfigFrame::kAfarComWin
uci1 67:ec999336fcd1 1747 : SnConfigFrame::kAfarDatTak;
uci1 67:ec999336fcd1 1748
uci1 67:ec999336fcd1 1749 //
uci1 67:ec999336fcd1 1750 // FIRST turn the things off that should be off.
uci1 67:ec999336fcd1 1751 // this prevents short periods of high power usage
uci1 67:ec999336fcd1 1752 //
uci1 67:ec999336fcd1 1753
uci1 84:80b15993944e 1754 const bool cardToOn = gConf.IsPoweredFor(cardpb);
uci1 84:80b15993944e 1755 const bool ampsToOn = gConf.IsPoweredFor(ampspb);
uci1 84:80b15993944e 1756
uci1 84:80b15993944e 1757 // these are complicated because iridium might
uci1 67:ec999336fcd1 1758 // be powered off of the afar line
uci1 84:80b15993944e 1759 // also ignore the devices in use if we're not in a comm window
uci1 67:ec999336fcd1 1760 const bool iridToOn = (kIridPwrFromAfar) ?
uci1 84:80b15993944e 1761 (gConf.IsPoweredFor(afarpb) && IsPowerAllowedFor(isCommWin, devicesInUse, SnConfigFrame::kIrid)) :
uci1 84:80b15993944e 1762 (gConf.IsPoweredFor(iridpb) && IsPowerAllowedFor(isCommWin, devicesInUse, SnConfigFrame::kIrid));
uci1 84:80b15993944e 1763 const bool afarToOn = (kIridPwrFromAfar) ?
uci1 84:80b15993944e 1764 ( (gConf.IsPoweredFor(afarpb) && IsPowerAllowedFor(isCommWin, devicesInUse, SnConfigFrame::kAfar))
uci1 84:80b15993944e 1765 ||(gConf.IsPoweredFor(iridpb) && IsPowerAllowedFor(isCommWin, devicesInUse, SnConfigFrame::kIrid)) ) :
uci1 84:80b15993944e 1766 (gConf.IsPoweredFor(afarpb) && IsPowerAllowedFor(isCommWin, devicesInUse, SnConfigFrame::kAfar));
uci1 67:ec999336fcd1 1767
uci1 84:80b15993944e 1768 if (cardToOn==false) {
uci1 67:ec999336fcd1 1769 #ifdef DEBUG
uci1 67:ec999336fcd1 1770 printf("power down cards\r\n");
uci1 67:ec999336fcd1 1771 #endif
uci1 84:80b15993944e 1772 ChangeCardPower(isCommWin, cardToOn);
uci1 67:ec999336fcd1 1773 }
uci1 84:80b15993944e 1774 if (ampsToOn==false) {
uci1 67:ec999336fcd1 1775 #ifdef DEBUG
uci1 67:ec999336fcd1 1776 printf("power down amps\r\n");
uci1 67:ec999336fcd1 1777 printf("ampspb=%d, is powered for =%d\r\n",
uci1 67:ec999336fcd1 1778 (int)ampspb,
uci1 67:ec999336fcd1 1779 (int)(gConf.IsPoweredFor(ampspb)));
uci1 67:ec999336fcd1 1780 printf("is powered amps dat tak = %d, amps com win = %d\r\n",
uci1 67:ec999336fcd1 1781 (int)(gConf.IsPoweredFor(SnConfigFrame::kAmpsDatTak)),
uci1 67:ec999336fcd1 1782 (int)(gConf.IsPoweredFor(SnConfigFrame::kAmpsComWin)));
uci1 67:ec999336fcd1 1783 #endif
uci1 84:80b15993944e 1784 ChangeAmpsPower(isCommWin, ampsToOn);
uci1 67:ec999336fcd1 1785 }
uci1 67:ec999336fcd1 1786 if (iridToOn==false) {
uci1 67:ec999336fcd1 1787 #ifdef DEBUG
uci1 67:ec999336fcd1 1788 printf("power down irid\r\n");
uci1 67:ec999336fcd1 1789 #endif
uci1 84:80b15993944e 1790 ChangeIridPower(isCommWin, iridToOn);
uci1 67:ec999336fcd1 1791 }
uci1 67:ec999336fcd1 1792 if (afarToOn==false) {
uci1 67:ec999336fcd1 1793 #ifdef DEBUG
uci1 67:ec999336fcd1 1794 printf("power down afar\r\n");
uci1 67:ec999336fcd1 1795 #endif
uci1 84:80b15993944e 1796 ChangeAfarPower(isCommWin, afarToOn);
uci1 67:ec999336fcd1 1797 }
uci1 67:ec999336fcd1 1798
uci1 67:ec999336fcd1 1799 //
uci1 67:ec999336fcd1 1800 // THEN turn on things that want to go on
uci1 67:ec999336fcd1 1801 //
uci1 84:80b15993944e 1802 if (cardToOn) {
uci1 67:ec999336fcd1 1803 #ifdef DEBUG
uci1 67:ec999336fcd1 1804 printf("power ON cards\r\n");
uci1 67:ec999336fcd1 1805 #endif
uci1 84:80b15993944e 1806 ChangeCardPower(isCommWin, cardToOn);
uci1 67:ec999336fcd1 1807 }
uci1 84:80b15993944e 1808 if (ampsToOn) {
uci1 67:ec999336fcd1 1809 #ifdef DEBUG
uci1 67:ec999336fcd1 1810 printf("power ON amps\r\n");
uci1 67:ec999336fcd1 1811 #endif
uci1 84:80b15993944e 1812 ChangeAmpsPower(isCommWin, ampsToOn);
uci1 67:ec999336fcd1 1813 }
uci1 67:ec999336fcd1 1814 if (iridToOn) {
uci1 67:ec999336fcd1 1815 #ifdef DEBUG
uci1 67:ec999336fcd1 1816 printf("power ON iridium\r\n");
uci1 67:ec999336fcd1 1817 #endif
uci1 84:80b15993944e 1818 ChangeIridPower(isCommWin, iridToOn);
uci1 67:ec999336fcd1 1819 }
uci1 67:ec999336fcd1 1820 if (afarToOn) {
uci1 67:ec999336fcd1 1821 #ifdef DEBUG
uci1 67:ec999336fcd1 1822 printf("power ON afar\r\n");
uci1 67:ec999336fcd1 1823 #endif
uci1 84:80b15993944e 1824 ChangeAfarPower(isCommWin, afarToOn);
uci1 67:ec999336fcd1 1825 }
uci1 67:ec999336fcd1 1826
uci1 21:ce51bb0ba4a5 1827 #ifdef DEBUG
uci1 16:744ce85aede2 1828 printf("power word (%hhu): ",gConf.GetPowerMode()); SnBitUtils::printBits(gConf.GetPowerMode(),true);
uci1 6:6f002d202f59 1829 printf("set power (iscom %d, pw %hhu): cards %d, amps %d, irid %d, afar %d\r\n",
uci1 6:6f002d202f59 1830 isCommWin, gConf.GetPowerMode(), PIN_turn_on_system.read(), PIN_turn_on_amps.read(),
uci1 6:6f002d202f59 1831 PIN_iridSbd_power.read(), PIN_afar_power.read());
uci1 12:d472f9811262 1832 #endif
uci1 4:a91682e19d6b 1833 }
uci1 4:a91682e19d6b 1834
uci1 4:a91682e19d6b 1835 //
uci1 0:664899e0b988 1836 // set configuration
uci1 0:664899e0b988 1837 //
uci1 1:e392595b4b76 1838 void SetConfigAndMakeOutputFile() {
uci1 12:d472f9811262 1839 #ifdef DEBUG
uci1 1:e392595b4b76 1840 printf("SetConfigAndMakeOutputFile\r\n");
uci1 12:d472f9811262 1841 #endif
uci1 1:e392595b4b76 1842
uci1 0:664899e0b988 1843 // restart watchdog
uci1 62:4b59c1eb429f 1844 #ifdef DEBUG
uci1 62:4b59c1eb429f 1845 printf("Restart watchdog with time [%u]\r\n",
uci1 62:4b59c1eb429f 1846 gConf.GetWatchdogPeriod());
uci1 62:4b59c1eb429f 1847 #endif
uci1 0:664899e0b988 1848 Watchdog::kick(gConf.GetWatchdogPeriod());
uci1 0:664899e0b988 1849
uci1 1:e392595b4b76 1850 // block (thermal) triggers during configuration
uci1 1:e392595b4b76 1851 PIN_enableThermTrig = 0;
uci1 56:0bba0ef15697 1852 #if CHIPBOARD==ATWD4CH
uci1 1:e392595b4b76 1853 PIN_ADC_CS = 1;
uci1 1:e392595b4b76 1854 PIN_DoNotRestartAllClocks = 1;
uci1 56:0bba0ef15697 1855 #endif
uci1 1:e392595b4b76 1856 PIN_forceTrigger = 0;
uci1 3:24c5f0f50bf1 1857 PIN_heartbeat = 0;
uci1 40:1324da35afd4 1858 #ifdef USE_RTOS
uci1 40:1324da35afd4 1859 Thread::wait(20);
uci1 40:1324da35afd4 1860 #else
uci1 1:e392595b4b76 1861 wait_ms(20);
uci1 40:1324da35afd4 1862 #endif
uci1 1:e392595b4b76 1863
uci1 22:f957c4f840ad 1864 gCommWinChecks = 0;
uci1 22:f957c4f840ad 1865 gNcommWinChecks = gConf.GetCommWinPeriod() / kCommWinLongPrdTk;
uci1 22:f957c4f840ad 1866
uci1 21:ce51bb0ba4a5 1867 if (AreCardsPowered(true)) {
uci1 8:95a325df1f6b 1868 // Set PLA value(s)
uci1 56:0bba0ef15697 1869 PIN_spi.format( 16, 0 ); // change mode for DAC & PLA value setting (with ATWD4CH)
uci1 8:95a325df1f6b 1870 PIN_spi.frequency(1000000);
uci1 8:95a325df1f6b 1871 PIN_MajLogHiBit=1;
uci1 8:95a325df1f6b 1872 PIN_MajLogLoBit=1;
uci1 8:95a325df1f6b 1873 PIN_enableThermTrig=0;
uci1 0:664899e0b988 1874
uci1 56:0bba0ef15697 1875 #if CHIPBOARD==ATWD4CH
uci1 8:95a325df1f6b 1876 uint16_t hi, lo;
uci1 8:95a325df1f6b 1877 PIN_PLA_cs=1;
uci1 40:1324da35afd4 1878 #ifdef USE_RTOS
uci1 40:1324da35afd4 1879 Thread::wait(4000);
uci1 40:1324da35afd4 1880 #else
uci1 8:95a325df1f6b 1881 wait(4);
uci1 40:1324da35afd4 1882 #endif
uci1 56:0bba0ef15697 1883 for (uint8_t pi=0; pi<kNplas; ++pi) {
uci1 8:95a325df1f6b 1884 if (pi < gConf.GetNumPlas()) {
uci1 8:95a325df1f6b 1885 SnConfigFrame::GetHiLoPlas(gConf.GetPla(pi), hi, lo);
uci1 8:95a325df1f6b 1886 PIN_spi.write(hi);
uci1 8:95a325df1f6b 1887 PIN_spi.write(lo);
uci1 12:d472f9811262 1888 #ifdef DEBUG
uci1 8:95a325df1f6b 1889 printf("pla hi %hu, lo %hu\r\n",hi,lo);
uci1 12:d472f9811262 1890 #endif
uci1 8:95a325df1f6b 1891 } else {
uci1 8:95a325df1f6b 1892 PIN_spi.write(kNoTrigPla); // hi
uci1 8:95a325df1f6b 1893 PIN_spi.write(kNoTrigPla); // lo
uci1 12:d472f9811262 1894 #ifdef DEBUG
uci1 8:95a325df1f6b 1895 printf("pla hi %hu, lo %hu\r\n",kNoTrigPla,kNoTrigPla);
uci1 12:d472f9811262 1896 #endif
uci1 8:95a325df1f6b 1897 }
uci1 8:95a325df1f6b 1898 Watchdog::kick();
uci1 0:664899e0b988 1899 }
uci1 40:1324da35afd4 1900 #ifdef USE_RTOS
uci1 40:1324da35afd4 1901 Thread::wait(3000);
uci1 40:1324da35afd4 1902 #else
uci1 8:95a325df1f6b 1903 wait(3);
uci1 40:1324da35afd4 1904 #endif
uci1 8:95a325df1f6b 1905 PIN_PLA_cs=0;
uci1 40:1324da35afd4 1906 #ifdef USE_RTOS
uci1 40:1324da35afd4 1907 Thread::wait(3000);
uci1 40:1324da35afd4 1908 #else
uci1 8:95a325df1f6b 1909 wait(3);
uci1 40:1324da35afd4 1910 #endif
uci1 0:664899e0b988 1911
uci1 56:0bba0ef15697 1912
uci1 8:95a325df1f6b 1913 // DAC values
uci1 8:95a325df1f6b 1914 //
uci1 8:95a325df1f6b 1915 // first 12 bits = DAC value
uci1 8:95a325df1f6b 1916 // next 2 bits = DAC ID
uci1 8:95a325df1f6b 1917 // last 2 bits = dFPGA ID
uci1 8:95a325df1f6b 1918 //
uci1 8:95a325df1f6b 1919 // But FPGA uses "gray encoding" which means only 1 bit
uci1 8:95a325df1f6b 1920 // can change at a time (of the last 4 bits). So even tho
uci1 8:95a325df1f6b 1921 // the card/dac# is encoded, the order is also important
uci1 8:95a325df1f6b 1922 // 0000 (dac0,card0), 0001 (dac0,card1), 0011 (dac0,card3), 0010 (dac0,card2),
uci1 8:95a325df1f6b 1923 // 0110 (dac1,card2), 0111 (dac1,card3), 0101 (dac1,card1), etc.
uci1 12:d472f9811262 1924 #ifdef DEBUG
uci1 8:95a325df1f6b 1925 printf("setting dacs\r\n");
uci1 12:d472f9811262 1926 #endif
uci1 8:95a325df1f6b 1927 uint16_t dv=0;
uci1 56:0bba0ef15697 1928 for (uint8_t i=0, gri=0; i<kTotDacs; ++i) {
uci1 8:95a325df1f6b 1929 // get the gray-codes for this iteration
uci1 8:95a325df1f6b 1930 gri = SnBitUtils::binToGray(i);
uci1 8:95a325df1f6b 1931
uci1 8:95a325df1f6b 1932 // build bit word
uci1 8:95a325df1f6b 1933 dv = static_cast<int>(gConf.GetDac(gri & 0x0003u, gri >> 2u));
uci1 8:95a325df1f6b 1934 dv <<= 4u;
uci1 8:95a325df1f6b 1935 dv |= gri;
uci1 8:95a325df1f6b 1936
uci1 12:d472f9811262 1937 #ifdef DEBUG
uci1 8:95a325df1f6b 1938 printf("dac %04x\r\n",dv);
uci1 12:d472f9811262 1939 #endif
uci1 8:95a325df1f6b 1940
uci1 8:95a325df1f6b 1941 // send to FPGA
uci1 8:95a325df1f6b 1942 PIN_start_fpga=1;
uci1 8:95a325df1f6b 1943 PIN_spi.write(dv);
uci1 8:95a325df1f6b 1944 PIN_start_fpga=0;
uci1 8:95a325df1f6b 1945
uci1 8:95a325df1f6b 1946 Watchdog::kick();
uci1 8:95a325df1f6b 1947
uci1 8:95a325df1f6b 1948 }
uci1 56:0bba0ef15697 1949 #else // SST
uci1 56:0bba0ef15697 1950
uci1 56:0bba0ef15697 1951 // set and/or & differential pins
uci1 56:0bba0ef15697 1952
uci1 56:0bba0ef15697 1953 // set DACs via I2C
uci1 56:0bba0ef15697 1954
uci1 56:0bba0ef15697 1955 uint16_t dv=0;
uci1 56:0bba0ef15697 1956 uint8_t dn=0;
uci1 56:0bba0ef15697 1957 uint8_t cmdAndDac[3];
uci1 56:0bba0ef15697 1958 for (uint8_t ch=0; ch<kNchans; ++ch) {
uci1 56:0bba0ef15697 1959 for (uint8_t dc=0; dc<kNchanDacs; ++dc) {
uci1 56:0bba0ef15697 1960 // for (uint16_t dc=kNchanDacs-1; dc>=0; --dc) { // first all the highs, then the lows
uci1 56:0bba0ef15697 1961 // for (int16_t ch=kNchans-1; ch>=0; --ch) { // chans in reverse order
uci1 56:0bba0ef15697 1962 bool dok = false;
uci1 56:0bba0ef15697 1963 for (uint8_t tries = 0; (tries<kMaxDacSetTries) && (dok==false); ++tries) {
uci1 56:0bba0ef15697 1964 #ifdef DEBUG
uci1 56:0bba0ef15697 1965 printf("start i2c for dc=%hhu, ch=%hhu, try=%hhu, dok=%s\r\n",
uci1 56:0bba0ef15697 1966 dc, ch, tries, (dok ? "true" : "false"));
uci1 56:0bba0ef15697 1967 printf("address 0x%hhx (%hhd) ", kAllLTC2657, kAllLTC2657);
uci1 56:0bba0ef15697 1968 SnBitUtils::printBits(kAllLTC2657, true);
uci1 56:0bba0ef15697 1969 #endif
uci1 56:0bba0ef15697 1970 // build data to send
uci1 56:0bba0ef15697 1971 // blame the engineers for this bizzare mapping from
uci1 56:0bba0ef15697 1972 // chan, threshold -> DAC number
uci1 56:0bba0ef15697 1973 dn = (kTotDacs-1)-(dc*kNchans)-ch;
uci1 56:0bba0ef15697 1974 if (dn>7) { // invalid code for LTC2657 dac chip
uci1 56:0bba0ef15697 1975 error("chan/dac combination too big for 3 bits!");
uci1 56:0bba0ef15697 1976 }
uci1 56:0bba0ef15697 1977 dn |= (kUpdateDacCmd<<4); // prefix with update DAC value command
uci1 56:0bba0ef15697 1978 #ifdef DEBUG
uci1 56:0bba0ef15697 1979 printf("dn=%hhu ", dn);
uci1 56:0bba0ef15697 1980 SnBitUtils::printBits(dn, true);
uci1 56:0bba0ef15697 1981 #endif
uci1 56:0bba0ef15697 1982 dv = (gConf.GetDac(ch, dc)) << 4; // put 0's at the end (12 bits of num then 4 zero bits)
uci1 56:0bba0ef15697 1983 #ifdef DEBUG
uci1 56:0bba0ef15697 1984 printf("dv=%hu\r\n",dv);
uci1 56:0bba0ef15697 1985 printf("ch=%hhu, dc=%hhu, dac=%hu\r\n",ch,dc,gConf.GetDac(ch,dc));
uci1 56:0bba0ef15697 1986 #endif
uci1 56:0bba0ef15697 1987 // mbed i2c.write seems to send it "backwards" from a (low endian) bit
uci1 56:0bba0ef15697 1988 // point of view.. i guess it's forwards from an intuitive pov?
uci1 56:0bba0ef15697 1989 cmdAndDac[0] = dn;
uci1 56:0bba0ef15697 1990 cmdAndDac[1] = (dv & 0xFF00u) >> 8; // 8 MSBs of 12 bit num first
uci1 56:0bba0ef15697 1991 cmdAndDac[2] = (dv & 0x00FFu); // 4 LSBs of 12 bit num followed by 4 zeros
uci1 56:0bba0ef15697 1992
uci1 56:0bba0ef15697 1993 #ifdef DEBUG
uci1 56:0bba0ef15697 1994 printf("cmdAndDac[0]="); SnBitUtils::printBits(cmdAndDac[2],true);
uci1 56:0bba0ef15697 1995 printf("cmdAndDac[1]="); SnBitUtils::printBits(cmdAndDac[1],true);
uci1 56:0bba0ef15697 1996 printf("cmdAndDac[2]="); SnBitUtils::printBits(cmdAndDac[0],true);
uci1 56:0bba0ef15697 1997 #endif
uci1 56:0bba0ef15697 1998 // try to send it
uci1 56:0bba0ef15697 1999 // TODO: if no ACK, is just re-trying the whole thing good enough?
uci1 56:0bba0ef15697 2000 // TODO: assign correct slave address for the DAC chip (this is a global address)
uci1 56:0bba0ef15697 2001 dok = PIN_i2c.write(kAllLTC2657,
uci1 56:0bba0ef15697 2002 reinterpret_cast<char*>(cmdAndDac),
uci1 56:0bba0ef15697 2003 3*sizeof(uint8_t))==0;
uci1 56:0bba0ef15697 2004 } // end try loop
uci1 56:0bba0ef15697 2005 }
uci1 56:0bba0ef15697 2006 }
uci1 56:0bba0ef15697 2007
uci1 56:0bba0ef15697 2008 #endif // CHIPBOARD
uci1 56:0bba0ef15697 2009
uci1 12:d472f9811262 2010 #ifdef DEBUG
uci1 8:95a325df1f6b 2011 printf("dacs set\r\n");
uci1 12:d472f9811262 2012 #endif
uci1 40:1324da35afd4 2013 #ifdef USE_RTOS
uci1 40:1324da35afd4 2014 Thread::wait(20);
uci1 40:1324da35afd4 2015 #else
uci1 8:95a325df1f6b 2016 wait_ms(20);
uci1 40:1324da35afd4 2017 #endif
uci1 8:95a325df1f6b 2018 } else {
uci1 12:d472f9811262 2019 #ifdef DEBUG
uci1 8:95a325df1f6b 2020 printf("cards off. skipping PLA and DAC setting\r\n");
uci1 12:d472f9811262 2021 #endif
uci1 0:664899e0b988 2022 }
uci1 56:0bba0ef15697 2023
uci1 56:0bba0ef15697 2024 #if CHIPBOARD==SST4CH
uci1 56:0bba0ef15697 2025 // set the SST triggering run mode
uci1 56:0bba0ef15697 2026 PIN_dualOrSingleThresholds = gConf.IsDualThresholdMode();
uci1 56:0bba0ef15697 2027 PIN_differentialTrigSignal = gConf.IsDifferentialTrigMode();
uci1 56:0bba0ef15697 2028 #endif
uci1 0:664899e0b988 2029
uci1 0:664899e0b988 2030 // Majority Logic Trigger selection (# of cards)
uci1 0:664899e0b988 2031 SnBitUtils::SetChanNumBits(gConf.GetNumCardsMajLog() - 1u,
uci1 0:664899e0b988 2032 PIN_MajLogHiBit, PIN_MajLogLoBit);
uci1 0:664899e0b988 2033
uci1 0:664899e0b988 2034 // Enable thermal trigger?
uci1 0:664899e0b988 2035 PIN_enableThermTrig = gConf.IsThermTrigEnabled();
uci1 0:664899e0b988 2036
uci1 56:0bba0ef15697 2037 #if CHIPBOARD==SST4CH
uci1 56:0bba0ef15697 2038 InitTempProbe();
uci1 56:0bba0ef15697 2039 #endif
uci1 56:0bba0ef15697 2040
uci1 0:664899e0b988 2041 PIN_spi.format( 16, 1 ); // back to trigger mode
uci1 1:e392595b4b76 2042 PIN_spi.frequency( 10000000 ); // Max is 12.5 MHz
uci1 1:e392595b4b76 2043
uci1 8:95a325df1f6b 2044 // make new output file
uci1 8:95a325df1f6b 2045 // put after PLA/DAC, in case they affect the power readings
uci1 40:1324da35afd4 2046 #ifdef USE_RTOS
uci1 40:1324da35afd4 2047 Thread::wait(200);
uci1 40:1324da35afd4 2048 #else
uci1 8:95a325df1f6b 2049 wait_ms(200);
uci1 40:1324da35afd4 2050 #endif
uci1 8:95a325df1f6b 2051 MakeOutputFile();
uci1 8:95a325df1f6b 2052
uci1 21:ce51bb0ba4a5 2053 // reset tickers
uci1 21:ce51bb0ba4a5 2054 ResetAllTickers();
uci1 0:664899e0b988 2055
uci1 0:664899e0b988 2056 Watchdog::kick(); // don't reset!
uci1 8:95a325df1f6b 2057
uci1 12:d472f9811262 2058 #ifdef DEBUG
uci1 8:95a325df1f6b 2059 printf("set config done\r\n");
uci1 12:d472f9811262 2060 #endif
uci1 0:664899e0b988 2061 }
uci1 0:664899e0b988 2062
uci1 0:664899e0b988 2063 //
uci1 0:664899e0b988 2064 // readout functions
uci1 0:664899e0b988 2065 //
uci1 0:664899e0b988 2066 void WaitTrigAndSendClock() {
uci1 1:e392595b4b76 2067
uci1 12:d472f9811262 2068 #ifdef DEBUG
uci1 1:e392595b4b76 2069 printf("WaitTrigAndSendClock\r\n");
uci1 6:6f002d202f59 2070 printf("wait trig: (pw %hhu): cards %d, amps %d, irid %d, afar %d\r\n",
uci1 6:6f002d202f59 2071 gConf.GetPowerMode(), PIN_turn_on_system.read(), PIN_turn_on_amps.read(),
uci1 6:6f002d202f59 2072 PIN_iridSbd_power.read(), PIN_afar_power.read());
uci1 21:ce51bb0ba4a5 2073 printf("cards powered=%d\r\n",(int)AreCardsPowered(true));
uci1 12:d472f9811262 2074 #endif
uci1 15:f2569d8e4176 2075
uci1 21:ce51bb0ba4a5 2076 #ifdef DEBUG
uci1 41:d6f5e2f09e07 2077 printf("gFirstEvt=%s\r\n",gFirstEvt?"true":"false");
uci1 21:ce51bb0ba4a5 2078 #endif
uci1 41:d6f5e2f09e07 2079 if (AreCardsPowered(false)) {
uci1 41:d6f5e2f09e07 2080
uci1 41:d6f5e2f09e07 2081 PIN_spi.format( 16, 1 ); // back to trigger mode
uci1 41:d6f5e2f09e07 2082 PIN_spi.frequency( 10000000 ); // Max is 12.5 MHz
uci1 8:95a325df1f6b 2083
uci1 47:fbe956b10a91 2084 if (gFirstEvt==false) {
uci1 56:0bba0ef15697 2085 #if CHIPBOARD==ATWD4CH
uci1 47:fbe956b10a91 2086 PIN_DoNotRestartAllClocks = 0;
uci1 47:fbe956b10a91 2087 wait_us(1);
uci1 47:fbe956b10a91 2088 PIN_DoNotRestartAllClocks = 1;
uci1 56:0bba0ef15697 2089 #endif
uci1 47:fbe956b10a91 2090 } else {
uci1 47:fbe956b10a91 2091 gFirstEvt = false;
uci1 47:fbe956b10a91 2092 }
uci1 47:fbe956b10a91 2093
uci1 8:95a325df1f6b 2094 //
uci1 8:95a325df1f6b 2095 // wait for a trigger here.
uci1 8:95a325df1f6b 2096 //
uci1 12:d472f9811262 2097 #ifdef DEBUG
uci1 8:95a325df1f6b 2098 printf("starting wait for trig\r\n");
uci1 12:d472f9811262 2099 #endif
uci1 16:744ce85aede2 2100
uci1 8:95a325df1f6b 2101 gReadingOut = false; // this will allow forced triggers (see procForceTrigger())
uci1 56:0bba0ef15697 2102 #if CHIPBOARD==ATWD4CH
uci1 56:0bba0ef15697 2103 while ( PIN_a_sf_clk == 1 ) { // wait for trigger
uci1 56:0bba0ef15697 2104 #else
uci1 56:0bba0ef15697 2105 while ( PIN_dataReady==0 ) { // wait for data in mb fpga
uci1 56:0bba0ef15697 2106 #endif
uci1 56:0bba0ef15697 2107 if (gOpenCommWin || gCheckPower || gCheckTemp) {
uci1 12:d472f9811262 2108 #ifdef DEBUG
uci1 56:0bba0ef15697 2109 printf("break com=%d, pow=%d, tmp=%d\r\n",
uci1 56:0bba0ef15697 2110 gOpenCommWin,gCheckPower,gCheckTemp);
uci1 12:d472f9811262 2111 #endif
uci1 8:95a325df1f6b 2112 return; // break out to open comms or check power
uci1 8:95a325df1f6b 2113 }
uci1 0:664899e0b988 2114 }
uci1 8:95a325df1f6b 2115 gReadingOut = true; // disallow new forced triggers
uci1 56:0bba0ef15697 2116
uci1 15:f2569d8e4176 2117 // we can't be interrupted before data arrives at the MB FPGA
uci1 15:f2569d8e4176 2118 //StopAllTickers();
uci1 16:744ce85aede2 2119
uci1 23:ccf39298f205 2120 //wait_us(5);
uci1 56:0bba0ef15697 2121
uci1 56:0bba0ef15697 2122 #if CHIPBOARD==ATWD4CH
uci1 56:0bba0ef15697 2123 // ATWD
uci1 8:95a325df1f6b 2124 //
uci1 8:95a325df1f6b 2125 // collect data from daughter cards
uci1 8:95a325df1f6b 2126 //
uci1 8:95a325df1f6b 2127 // TODO: what if some card (set of channels) doesn't respond?
uci1 8:95a325df1f6b 2128 // currently, will wait forever?
uci1 8:95a325df1f6b 2129 // also, if ch1 is dead, will wait forever (due to FPGA code)
uci1 16:744ce85aede2 2130 gAdcToMBtimer.start();
uci1 56:0bba0ef15697 2131 for( uint16_t i = 0; i < kNsamps; ++i ) {
uci1 16:744ce85aede2 2132 while (PIN_a_sf_clk==1) {}
uci1 16:744ce85aede2 2133 while (PIN_a_sf_clk==0) {}
uci1 56:0bba0ef15697 2134
uci1 16:744ce85aede2 2135 PIN_ADC_CS = 0;
uci1 16:744ce85aede2 2136 PIN_spi.write( 0x00 );
uci1 16:744ce85aede2 2137 PIN_ADC_CS = 1;
uci1 0:664899e0b988 2138 }
uci1 16:744ce85aede2 2139 gAdcToMBtimer.stop();
uci1 16:744ce85aede2 2140 #ifdef DEBUG
uci1 16:744ce85aede2 2141 printf("total time = %d us\r\n", gAdcToMBtimer.read_us());
uci1 16:744ce85aede2 2142 #endif
uci1 16:744ce85aede2 2143 if ( kAdcToMBtimeCut < gAdcToMBtimer.read_us() ) {
uci1 84:80b15993944e 2144 // gEvent.SetTrgBit(kAdcToMBflag);
uci1 84:80b15993944e 2145 gAdcToMBflag = true;
uci1 16:744ce85aede2 2146 }
uci1 16:744ce85aede2 2147 gAdcToMBtimer.reset();
uci1 15:f2569d8e4176 2148
uci1 56:0bba0ef15697 2149 #else
uci1 56:0bba0ef15697 2150 // For SST, data is already in the mb FPGA, so no need to do anything here
uci1 56:0bba0ef15697 2151 #endif
uci1 56:0bba0ef15697 2152
uci1 8:95a325df1f6b 2153 } else {
uci1 8:95a325df1f6b 2154 // cards have no power. don't try reading out
uci1 8:95a325df1f6b 2155 gReadingOut=false;
uci1 47:fbe956b10a91 2156 // set gFirstEvt to false even if cards are powered off.
uci1 47:fbe956b10a91 2157 // otherwise, if cards ARE powered off, it will always be
uci1 47:fbe956b10a91 2158 // true and the "start trigger" clock will be written continuously
uci1 47:fbe956b10a91 2159 gFirstEvt = false;
uci1 0:664899e0b988 2160 }
uci1 56:0bba0ef15697 2161
uci1 0:664899e0b988 2162 }
uci1 0:664899e0b988 2163
uci1 40:1324da35afd4 2164 bool IsPinPowered(const SnCommWin* cw) {
uci1 40:1324da35afd4 2165 bool havePower = false;
uci1 40:1324da35afd4 2166 switch (cw->GetCommType()) {
uci1 40:1324da35afd4 2167 case SnConfigFrame::kIrid:
uci1 40:1324da35afd4 2168 havePower = gConf.IsPoweredFor(SnConfigFrame::kIridComWin)
uci1 40:1324da35afd4 2169 && ( (kIridPwrFromAfar)
uci1 40:1324da35afd4 2170 ? PIN_afar_power.read()
uci1 40:1324da35afd4 2171 : PIN_iridSbd_power.read() ==
uci1 40:1324da35afd4 2172 gConf.GetPowPinSetting(SnConfigFrame::kIridComWin));
uci1 40:1324da35afd4 2173 break;
uci1 40:1324da35afd4 2174 case SnConfigFrame::kAfar:
uci1 40:1324da35afd4 2175 havePower = gConf.IsPoweredFor(SnConfigFrame::kAfarComWin)
uci1 40:1324da35afd4 2176 && (PIN_afar_power.read() ==
uci1 40:1324da35afd4 2177 gConf.GetPowPinSetting(SnConfigFrame::kAfarComWin));
uci1 40:1324da35afd4 2178 break;
uci1 40:1324da35afd4 2179 case SnConfigFrame::kUSB:
uci1 40:1324da35afd4 2180 havePower = true; // USB always on (for now)
uci1 40:1324da35afd4 2181 break;
uci1 40:1324da35afd4 2182 case SnConfigFrame::kSDcard: // shouldn't happen. skip it
uci1 40:1324da35afd4 2183 default: // unknown.. skip it
uci1 40:1324da35afd4 2184 break;
uci1 40:1324da35afd4 2185 };
uci1 40:1324da35afd4 2186 return havePower;
uci1 40:1324da35afd4 2187 }
uci1 40:1324da35afd4 2188
uci1 40:1324da35afd4 2189
uci1 40:1324da35afd4 2190 SnCommWin::ECommWinResult OpenCommWin(const bool forceReconfig,
uci1 40:1324da35afd4 2191 const bool isStartupWin) {
uci1 0:664899e0b988 2192 // loop through each comm mode:
uci1 0:664899e0b988 2193 // a) try to connect
uci1 0:664899e0b988 2194 // b) if connected, listen for config
uci1 0:664899e0b988 2195 // c) if config requests data, send it
uci1 67:ec999336fcd1 2196
uci1 67:ec999336fcd1 2197 led2 = 1;
uci1 67:ec999336fcd1 2198
uci1 3:24c5f0f50bf1 2199 gLastCommWin = time(0);
uci1 13:7a1fb885a8e4 2200
uci1 0:664899e0b988 2201 SnCommWin::ECommWinResult res = SnCommWin::kUndefFail;
uci1 0:664899e0b988 2202
uci1 21:ce51bb0ba4a5 2203 // get the trigger rates
uci1 21:ce51bb0ba4a5 2204 float thmrate=0, evtrate=0;
uci1 21:ce51bb0ba4a5 2205 GetRates(thmrate, evtrate);
uci1 22:f957c4f840ad 2206 #ifdef DEBUG
uci1 56:0bba0ef15697 2207 printf("config=%s\r\n", gConf.GetLabel());
uci1 22:f957c4f840ad 2208 printf("thmrate=%g, evtrate=%g\r\n",thmrate,evtrate);
uci1 84:80b15993944e 2209 printf("Free memory = %d\r\n", FreeMem());
uci1 22:f957c4f840ad 2210 #endif
uci1 21:ce51bb0ba4a5 2211
uci1 21:ce51bb0ba4a5 2212 StopAllTickers();
uci1 40:1324da35afd4 2213
uci1 13:7a1fb885a8e4 2214 if (gConf.GetCommWinDuration()==0) {
uci1 13:7a1fb885a8e4 2215 // TODO: set min so this is not possible
uci1 13:7a1fb885a8e4 2216 res = SnCommWin::kOkNoMsg;
uci1 13:7a1fb885a8e4 2217 } else {
uci1 13:7a1fb885a8e4 2218
uci1 13:7a1fb885a8e4 2219 gCommWinOpen = true;
uci1 1:e392595b4b76 2220 Watchdog::kick(); // don't reset!
uci1 13:7a1fb885a8e4 2221
uci1 13:7a1fb885a8e4 2222 #ifdef DEBUG
uci1 13:7a1fb885a8e4 2223 printf("opening comm window at %d\r\n", (int32_t)gLastCommWin);
uci1 16:744ce85aede2 2224 printf("duration=%u\r\n",gConf.GetCommWinDuration());
uci1 13:7a1fb885a8e4 2225 #endif
uci1 13:7a1fb885a8e4 2226
uci1 13:7a1fb885a8e4 2227 // close the file so that the data is all written out.
uci1 13:7a1fb885a8e4 2228 // and open it back up at the beginning (for reading)
uci1 12:d472f9811262 2229 #ifdef DEBUG
uci1 13:7a1fb885a8e4 2230 printf("close & open file. gEvtNum=%u, gPowNum=%u\r\n",gEvtNum,gPowNum);
uci1 25:57b2627fe756 2231 printf("curfile=%p, filename=%s\r\n",SnSDUtils::GetCurFile(),
uci1 25:57b2627fe756 2232 SnSDUtils::GetCurFileName());
uci1 12:d472f9811262 2233 #endif
uci1 40:1324da35afd4 2234
uci1 40:1324da35afd4 2235 if (isStartupWin==false) {
uci1 56:0bba0ef15697 2236 #if CHIPBOARD==ATWD4CH
uci1 56:0bba0ef15697 2237 PIN_lockRegisters = 0; // unlock so we can talk to the SD card
uci1 56:0bba0ef15697 2238 #else
uci1 56:0bba0ef15697 2239 PIN_readingData = 0; // unlock so we can talk to the SD card
uci1 56:0bba0ef15697 2240 #endif
uci1 25:57b2627fe756 2241 #ifdef DEBUG
uci1 40:1324da35afd4 2242 printf("closing output file\r\n");
uci1 25:57b2627fe756 2243 #endif
uci1 40:1324da35afd4 2244 SnSDUtils::CloseOutputFile(SnSDUtils::GetCurFile());
uci1 25:57b2627fe756 2245 #ifdef DEBUG
uci1 40:1324da35afd4 2246 printf("open existing file (%d)\r\n",strlen(SnSDUtils::GetCurFileName()));
uci1 25:57b2627fe756 2247 #endif
uci1 40:1324da35afd4 2248 SnSDUtils::OpenExistingFile(SnSDUtils::GetCurFileName(), true, false);
uci1 40:1324da35afd4 2249 }
uci1 40:1324da35afd4 2250
uci1 21:ce51bb0ba4a5 2251 #ifdef DEBUG
uci1 21:ce51bb0ba4a5 2252 printf("setting power\r\n");
uci1 21:ce51bb0ba4a5 2253 #endif
uci1 84:80b15993944e 2254 // (probably) power down cards,amps
uci1 84:80b15993944e 2255 // don't power up comms yet (only as needed for use)
uci1 84:80b15993944e 2256 SetPower(true, 0);
uci1 13:7a1fb885a8e4 2257
uci1 25:57b2627fe756 2258 // time to recount files for the status update
uci1 40:1324da35afd4 2259 // for the startup win, don't access SD card in case we
uci1 40:1324da35afd4 2260 // rebooted due to a problem with the SD card
uci1 40:1324da35afd4 2261 SnStatusFrame::fgRecalcFiles = !isStartupWin;
uci1 25:57b2627fe756 2262
uci1 28:484943132bb0 2263 #if defined(ENABLE_AFAR_TWITTER) && defined(ENABLE_AFAR_COMM)
uci1 28:484943132bb0 2264 bool doTwitter = false;
uci1 28:484943132bb0 2265 #endif
uci1 28:484943132bb0 2266
uci1 21:ce51bb0ba4a5 2267 #ifdef DEBUG
uci1 21:ce51bb0ba4a5 2268 printf("start loop over comms\r\n");
uci1 21:ce51bb0ba4a5 2269 #endif
uci1 84:80b15993944e 2270 bool needToConnect=true; // still need to talk to the outside
uci1 84:80b15993944e 2271 bool sendStat[kNcomms]; // if need to send status over this peripheral
uci1 84:80b15993944e 2272 bool needClos[kNcomms]; // if need to call CloseConn on this peripheral
uci1 56:0bba0ef15697 2273 for (uint8_t i=0; i<kNcomms; ++i) {
uci1 13:7a1fb885a8e4 2274 sendStat[i]=true;
uci1 84:80b15993944e 2275 needClos[i]=true;
uci1 13:7a1fb885a8e4 2276 }
uci1 13:7a1fb885a8e4 2277 bool* ss = sendStat;
uci1 84:80b15993944e 2278 bool* nc = needClos;
uci1 13:7a1fb885a8e4 2279 SnCommWin** cw = gComms;
uci1 84:80b15993944e 2280 for (uint8_t i=0; needToConnect && ((time(0)-gLastCommWin)<gConf.GetCommWinDuration());
uci1 84:80b15993944e 2281 ++i, ++cw, ++ss, ++nc) {
uci1 1:e392595b4b76 2282 Watchdog::kick(); // don't reset!
uci1 13:7a1fb885a8e4 2283 if (i==kNcomms) {
uci1 13:7a1fb885a8e4 2284 i=0;
uci1 13:7a1fb885a8e4 2285 cw = gComms;
uci1 13:7a1fb885a8e4 2286 ss = sendStat;
uci1 84:80b15993944e 2287 nc = needClos;
uci1 13:7a1fb885a8e4 2288 }
uci1 27:efc4d654b139 2289 // skip if no comm object
uci1 13:7a1fb885a8e4 2290 if ((*cw)==0) {
uci1 13:7a1fb885a8e4 2291 continue;
uci1 13:7a1fb885a8e4 2292 }
uci1 84:80b15993944e 2293
uci1 84:80b15993944e 2294 const SnConfigFrame::EDatPackBit ctype = (*cw)->GetCommType();
uci1 84:80b15993944e 2295
uci1 84:80b15993944e 2296 // power up for this device
uci1 84:80b15993944e 2297 if (gConf.IsCommPowerSimple()==false) {
uci1 84:80b15993944e 2298 SetPower(true, ctype);
uci1 84:80b15993944e 2299 }
uci1 84:80b15993944e 2300
uci1 27:efc4d654b139 2301 // skip if no power for this comm
uci1 27:efc4d654b139 2302 // THIS IS VITAL! For example, if the ethernet
uci1 27:efc4d654b139 2303 // port is powered down, making an Ethernet obejct
uci1 27:efc4d654b139 2304 // (done in netif) will stall forever waiting for the clock.
uci1 27:efc4d654b139 2305 // Do it here to keep all PIN usage in main.cpp
uci1 40:1324da35afd4 2306 const bool havePower=IsPinPowered(*cw);
uci1 27:efc4d654b139 2307 if (havePower==false) {
uci1 27:efc4d654b139 2308 continue;
uci1 27:efc4d654b139 2309 }
uci1 40:1324da35afd4 2310
uci1 40:1324da35afd4 2311 // always apply safety nets to connection and listen so
uci1 40:1324da35afd4 2312 // that we don't accidently shut down comms (i.e. with
uci1 40:1324da35afd4 2313 // connectTO or listnTO being 0)
uci1 40:1324da35afd4 2314 gConf.ApplyConnectListenSafetyNets();
uci1 84:80b15993944e 2315
uci1 16:744ce85aede2 2316 const uint32_t conto =
uci1 84:80b15993944e 2317 (gConf.GetCommWinDuration() < gConf.GetCommWinConnectTO(ctype)) ?
uci1 84:80b15993944e 2318 gConf.GetCommWinDuration() : gConf.GetCommWinConnectTO(ctype);
uci1 16:744ce85aede2 2319 const uint32_t listo =
uci1 84:80b15993944e 2320 (gConf.GetCommWinDuration() < gConf.GetCommWinListenTO(ctype)) ?
uci1 84:80b15993944e 2321 gConf.GetCommWinDuration() : gConf.GetCommWinListenTO(ctype);
uci1 40:1324da35afd4 2322
uci1 84:80b15993944e 2323 //
uci1 84:80b15993944e 2324 // try to connect to the outside if we haven't yet
uci1 84:80b15993944e 2325 //
uci1 16:744ce85aede2 2326 // update power reading in case we want to send it in status
uci1 16:744ce85aede2 2327 GetAvePowerReading();
uci1 56:0bba0ef15697 2328
uci1 56:0bba0ef15697 2329 // update temperature in case we want to send it in status
uci1 56:0bba0ef15697 2330 if (isStartupWin) {
uci1 56:0bba0ef15697 2331 #if CHIPBOARD==SST4CH
uci1 56:0bba0ef15697 2332 InitTempProbe();
uci1 56:0bba0ef15697 2333 #endif
uci1 56:0bba0ef15697 2334 }
uci1 56:0bba0ef15697 2335 UpdateTemperature();
uci1 21:ce51bb0ba4a5 2336
uci1 13:7a1fb885a8e4 2337 // open window and (mabye) send status update
uci1 12:d472f9811262 2338 #ifdef DEBUG
uci1 84:80b15993944e 2339 printf("Free memory = %d\r\n", FreeMem());
uci1 84:80b15993944e 2340 printf("calling OpenWindow. ss=%d. ctype=%hhu (%s)\r\n",
uci1 84:80b15993944e 2341 (int)(*ss),(uint8_t)ctype,SnConfigFrame::GetDataStreamName(ctype));
uci1 40:1324da35afd4 2342 printf("conto=%u, listo=%u, dur=%u, connTO=%u, lisTO=%u\r\n",
uci1 40:1324da35afd4 2343 conto,listo,gConf.GetCommWinDuration(),
uci1 84:80b15993944e 2344 gConf.GetCommWinConnectTO(ctype), gConf.GetCommWinListenTO(ctype));
uci1 84:80b15993944e 2345 printf("stopAt=%u, current=%d, lastComWin=%d, dt~%u\r\n",
uci1 84:80b15993944e 2346 gConf.GetTimeoutTime(gLastCommWin,conto),
uci1 84:80b15993944e 2347 time(0), gLastCommWin,
uci1 84:80b15993944e 2348 gConf.GetTimeoutTime(gLastCommWin,conto)-time(0));
uci1 12:d472f9811262 2349 #endif
uci1 84:80b15993944e 2350
uci1 84:80b15993944e 2351 //
uci1 84:80b15993944e 2352 // open the connection and send the status update (if the
uci1 84:80b15993944e 2353 // status has not yet been sent over this peripheral)
uci1 84:80b15993944e 2354 //
uci1 84:80b15993944e 2355 const SnCommWin::ECommWinResult conres = (*cw)->OpenWindow( *ss,
uci1 84:80b15993944e 2356 gConf, gPower, gEvent, SnSDUtils::GetCurSeqNum(), thmrate, evtrate,
uci1 84:80b15993944e 2357 gPowerOnTime, gTemperature,
uci1 84:80b15993944e 2358 gGenBuf, gConf.GetTimeoutTime(gLastCommWin, conto));
uci1 84:80b15993944e 2359
uci1 56:0bba0ef15697 2360 #ifdef DEBUG
uci1 56:0bba0ef15697 2361 printf("conres = %d\r\n",static_cast<int>(conres));
uci1 56:0bba0ef15697 2362 #endif
uci1 13:7a1fb885a8e4 2363 if (conres>=SnCommWin::kConnected) {
uci1 1:e392595b4b76 2364 Watchdog::kick(); // don't reset!
uci1 13:7a1fb885a8e4 2365 // connected. listen for config
uci1 13:7a1fb885a8e4 2366 *ss = false; // don't send status next time
uci1 84:80b15993944e 2367 *nc = true; // will need to close this connection
uci1 40:1324da35afd4 2368
uci1 40:1324da35afd4 2369 // clear watchdog reset bit now that we've told someone
uci1 40:1324da35afd4 2370 Watchdog::clearResetFlag();
uci1 40:1324da35afd4 2371
uci1 28:484943132bb0 2372 #if defined(ENABLE_AFAR_TWITTER) && defined(ENABLE_AFAR_COMM)
uci1 84:80b15993944e 2373 if (ctype==SnConfigFrame::kAfar) {
uci1 28:484943132bb0 2374 // if we connected by Afar
uci1 28:484943132bb0 2375 doTwitter = true;
uci1 28:484943132bb0 2376 }
uci1 28:484943132bb0 2377 #endif
uci1 28:484943132bb0 2378
uci1 12:d472f9811262 2379 #ifdef DEBUG
uci1 21:ce51bb0ba4a5 2380 printf("get conf gtt=%u\r\n",gConf.GetTimeoutTime(gLastCommWin, listo));
uci1 12:d472f9811262 2381 #endif
uci1 84:80b15993944e 2382 //
uci1 84:80b15993944e 2383 // ask for a new config
uci1 84:80b15993944e 2384 //
uci1 13:7a1fb885a8e4 2385 const SnCommWin::ECommWinResult cfgres = (*cw)->GetConfig(
uci1 21:ce51bb0ba4a5 2386 gConf, gConf.GetTimeoutTime(gLastCommWin, listo), gGenBuf, gBufSize);
uci1 56:0bba0ef15697 2387 #ifdef DEBUG
uci1 56:0bba0ef15697 2388 printf("cfgres = %d\r\n",static_cast<int>(cfgres));
uci1 56:0bba0ef15697 2389 #endif
uci1 13:7a1fb885a8e4 2390 if (cfgres>=SnCommWin::kOkWithMsg) {
uci1 13:7a1fb885a8e4 2391 Watchdog::kick(); // don't reset!
uci1 16:744ce85aede2 2392
uci1 12:d472f9811262 2393 #ifdef DEBUG
uci1 13:7a1fb885a8e4 2394 printf("received config!\r\n");
uci1 13:7a1fb885a8e4 2395 printf("send data = %d\r\n", gConf.GetCommSendData());
uci1 12:d472f9811262 2396 #endif
uci1 84:80b15993944e 2397
uci1 21:ce51bb0ba4a5 2398 const uint32_t winto = gConf.GetTimeoutTime(gLastCommWin,
uci1 21:ce51bb0ba4a5 2399 gConf.GetCommWinDuration());
uci1 40:1324da35afd4 2400 //const uint32_t gtt = gConf.IsObeyingTimeout() ? winto : 0;
uci1 40:1324da35afd4 2401
uci1 84:80b15993944e 2402 //
uci1 84:80b15993944e 2403 // send status data -- do this after getting the config!
uci1 84:80b15993944e 2404 // (avoid a situation where sending all this data causes a timeout,
uci1 84:80b15993944e 2405 // thereby preventing a new config from being accepted)
uci1 84:80b15993944e 2406 //
uci1 84:80b15993944e 2407 res = (*cw)->SendStatusData(gConf,
uci1 84:80b15993944e 2408 gStTrgStartClk, gStTrgStopClk,
uci1 84:80b15993944e 2409 gStPower, gEvent, gStTemperature,
uci1 84:80b15993944e 2410 gHrtbt, gStNewPower, gStNewEvent,
uci1 84:80b15993944e 2411 gStNewHeartbeat, gStNewTemperature,
uci1 84:80b15993944e 2412 gGenBuf, winto);
uci1 84:80b15993944e 2413 #ifdef DEBUG
uci1 84:80b15993944e 2414 printf("SendStatusData res=%d\r\n",
uci1 84:80b15993944e 2415 static_cast<int32_t>(res));
uci1 84:80b15993944e 2416 #endif
uci1 84:80b15993944e 2417
uci1 84:80b15993944e 2418 //
uci1 40:1324da35afd4 2419 // check if there are any requests before sending data
uci1 84:80b15993944e 2420 //
uci1 40:1324da35afd4 2421 if (gConf.IsWaitingHndShkBeforeSendData()) {
uci1 40:1324da35afd4 2422 // send handshake request
uci1 40:1324da35afd4 2423 (*cw)->SendHndshkReq(gGenBuf, winto);
uci1 40:1324da35afd4 2424 // wait for response
uci1 40:1324da35afd4 2425 uint8_t hndshk(0); uint32_t hndshkLen(0);
uci1 40:1324da35afd4 2426 res = (*cw)->WaitHandshake(gConf, winto, gGenBuf, gBufSize, hndshk,
uci1 40:1324da35afd4 2427 &hndshkLen);
uci1 56:0bba0ef15697 2428 #ifdef DEBUG
uci1 56:0bba0ef15697 2429 printf("WaitHandshake res = %d\r\n",static_cast<int>(res));
uci1 56:0bba0ef15697 2430 #endif
uci1 40:1324da35afd4 2431 // handle response
uci1 40:1324da35afd4 2432 if (SnCommWin::kOkWithMsg==res) {
uci1 40:1324da35afd4 2433 res = (*cw)->HandleHandshake(SnSDUtils::GetCurFile(),
uci1 40:1324da35afd4 2434 SnSDUtils::GetCurFileName(),
uci1 84:80b15993944e 2435 gConf, gEvent, gPower, gGenBuf, gBufSize,
uci1 84:80b15993944e 2436 // gConf, gLastEvent, gPower, gGenBuf, gBufSize,
uci1 40:1324da35afd4 2437 winto, hndshk, hndshkLen);
uci1 56:0bba0ef15697 2438 #ifdef DEBUG
uci1 56:0bba0ef15697 2439 printf("HandleHandshake res = %d\r\n",static_cast<int>(res));
uci1 56:0bba0ef15697 2440 #endif
uci1 40:1324da35afd4 2441 }
uci1 84:80b15993944e 2442 } // if handshake before data
uci1 84:80b15993944e 2443
uci1 84:80b15993944e 2444 //
uci1 84:80b15993944e 2445 // send data if need be (files, some events, etc)
uci1 84:80b15993944e 2446 //
uci1 13:7a1fb885a8e4 2447 if (gConf.GetCommSendData()!=0) {
uci1 12:d472f9811262 2448 #ifdef DEBUG
uci1 40:1324da35afd4 2449 printf("sending data, winto=%u. lcw=%u, dur=%u, obey=%s\r\n",
uci1 40:1324da35afd4 2450 winto,
uci1 13:7a1fb885a8e4 2451 gLastCommWin, gConf.GetCommWinDuration(),
uci1 13:7a1fb885a8e4 2452 gConf.IsObeyingTimeout() ? "true" : "false");
uci1 12:d472f9811262 2453 #endif
uci1 16:744ce85aede2 2454
uci1 84:80b15993944e 2455 res = (*cw)->SendData(gConf,
uci1 84:80b15993944e 2456 // gLastEvent, gPower, gGenBuf, gBufSize,
uci1 84:80b15993944e 2457 gEvent, gPower, gGenBuf, gBufSize,
uci1 40:1324da35afd4 2458 winto);
uci1 56:0bba0ef15697 2459 #ifdef DEBUG
uci1 56:0bba0ef15697 2460 printf("SendData res = %d\r\n",static_cast<int>(res));
uci1 56:0bba0ef15697 2461 #endif
uci1 56:0bba0ef15697 2462
uci1 13:7a1fb885a8e4 2463 } else {
uci1 13:7a1fb885a8e4 2464 // don't send anything
uci1 13:7a1fb885a8e4 2465 res = cfgres;
uci1 84:80b15993944e 2466 } // if send data
uci1 13:7a1fb885a8e4 2467 #ifdef DEBUG
uci1 13:7a1fb885a8e4 2468 printf("Got config!\r\n");
uci1 13:7a1fb885a8e4 2469 #endif
uci1 13:7a1fb885a8e4 2470 Watchdog::kick(); // don't reset!
uci1 84:80b15993944e 2471
uci1 84:80b15993944e 2472 // need to close this connection
uci1 84:80b15993944e 2473 *nc = true;
uci1 84:80b15993944e 2474 // stop trying to connect to outside
uci1 84:80b15993944e 2475 // don't break immediately, so that we can close conn and
uci1 84:80b15993944e 2476 // maybe tweet (pff..)
uci1 84:80b15993944e 2477 needToConnect = false;
uci1 84:80b15993944e 2478
uci1 84:80b15993944e 2479 } // if config recvd ok with message
uci1 84:80b15993944e 2480
uci1 84:80b15993944e 2481 //
uci1 84:80b15993944e 2482 // stupid legacy twitter crap.
uci1 84:80b15993944e 2483 //
uci1 84:80b15993944e 2484 // after normal Afar connection closed, try to tweet
uci1 84:80b15993944e 2485 #if defined(ENABLE_AFAR_TWITTER) && defined(ENABLE_AFAR_COMM)
uci1 84:80b15993944e 2486 if (ctype==SnConfigFrame::kAfar) {
uci1 84:80b15993944e 2487 // tweet
uci1 84:80b15993944e 2488 #ifdef DEBUG
uci1 84:80b15993944e 2489 printf("for twitter: gTwit=%p, doTwitter=%d\r\n",gTwit,(int)doTwitter);
uci1 84:80b15993944e 2490 #endif
uci1 84:80b15993944e 2491 // send a twitter update
uci1 84:80b15993944e 2492 if ( (gTwit!=0) && doTwitter ) {
uci1 84:80b15993944e 2493 const uint32_t conto =
uci1 84:80b15993944e 2494 (gConf.GetCommWinDuration() < gTwit->GetConnectTimeout()) ?
uci1 84:80b15993944e 2495 gConf.GetCommWinDuration() : gTwit->GetConnectTimeout();
uci1 84:80b15993944e 2496 const uint32_t listo =
uci1 84:80b15993944e 2497 (gConf.GetCommWinDuration() < gTwit->GetListenTimeout()) ?
uci1 84:80b15993944e 2498 gConf.GetCommWinDuration() : gTwit->GetListenTimeout();
uci1 84:80b15993944e 2499 #ifdef DEBUG
uci1 84:80b15993944e 2500 printf("open twit window. conto=%u, listo=%u\r\n",
uci1 84:80b15993944e 2501 conto, listo);
uci1 84:80b15993944e 2502 #endif
uci1 84:80b15993944e 2503 const SnCommWin::ECommWinResult conres = gTwit->OpenWindow(
uci1 84:80b15993944e 2504 gConf.GetTimeoutTime(gLastCommWin, conto), false, gConf,
uci1 84:80b15993944e 2505 // gLastEvent, gPower,
uci1 84:80b15993944e 2506 gEvent, gPower,
uci1 84:80b15993944e 2507 SnSDUtils::GetCurSeqNum(), thmrate, evtrate,
uci1 84:80b15993944e 2508 gGenBuf);
uci1 84:80b15993944e 2509 if (conres>=SnCommWin::kConnected) {
uci1 84:80b15993944e 2510 Watchdog::kick(); // don't reset!
uci1 84:80b15993944e 2511 gTwit->Tweet(gConf, thmrate, evtrate, gGenBuf,
uci1 84:80b15993944e 2512 gConf.GetTimeoutTime(time(0), listo));
uci1 84:80b15993944e 2513 }
uci1 84:80b15993944e 2514 }
uci1 84:80b15993944e 2515 } // end tweet block
uci1 84:80b15993944e 2516 #endif
uci1 84:80b15993944e 2517
uci1 21:ce51bb0ba4a5 2518 } else {
uci1 40:1324da35afd4 2519 // OpenWindow did not connect
uci1 21:ce51bb0ba4a5 2520 (*cw)->CloseConn(gConf.GetTimeoutTime(gLastCommWin, listo));
uci1 84:80b15993944e 2521 *nc = false;
uci1 84:80b15993944e 2522 #ifdef DEBUG
uci1 84:80b15993944e 2523 printf("no connect close conn. i=%d, nc=%s\r\n",
uci1 84:80b15993944e 2524 (int32_t)i, (*nc) ? "true" : "false");
uci1 84:80b15993944e 2525 #endif
uci1 21:ce51bb0ba4a5 2526 } // if connected
uci1 13:7a1fb885a8e4 2527
uci1 13:7a1fb885a8e4 2528 Watchdog::kick(); // don't reset!
uci1 84:80b15993944e 2529
uci1 84:80b15993944e 2530 if (*nc) {
uci1 84:80b15993944e 2531 // need to close this connection
uci1 84:80b15993944e 2532 #ifdef DEBUG
uci1 84:80b15993944e 2533 printf("close conn extra time. i=%d, nc=%s\r\n",
uci1 84:80b15993944e 2534 (int32_t)i, (*nc) ? "true" : "false");
uci1 84:80b15993944e 2535 #endif
uci1 84:80b15993944e 2536 const uint32_t extraDiscTime = gLastCommWin
uci1 84:80b15993944e 2537 + gConf.GetCommWinConnectTO((*cw)->GetCommType());
uci1 84:80b15993944e 2538 (*cw)->CloseConn(
uci1 84:80b15993944e 2539 gConf.GetTimeoutTime(extraDiscTime, gConf.GetCommWinDuration()));
uci1 84:80b15993944e 2540 *nc = false;
uci1 84:80b15993944e 2541 }
uci1 84:80b15993944e 2542
uci1 84:80b15993944e 2543 Watchdog::kick(); // don't reset!
uci1 21:ce51bb0ba4a5 2544 } // end loop over comms
uci1 28:484943132bb0 2545
uci1 84:80b15993944e 2546
uci1 41:d6f5e2f09e07 2547 // check Iridium time, send Iridium signal strength, and close the connection(s)
uci1 15:f2569d8e4176 2548 cw = gComms;
uci1 84:80b15993944e 2549 nc = needClos;
uci1 84:80b15993944e 2550 for (uint8_t i=0; i<kNcomms; ++i, ++cw, ++nc) {
uci1 15:f2569d8e4176 2551 if ((*cw)==0) {
uci1 15:f2569d8e4176 2552 continue;
uci1 15:f2569d8e4176 2553 }
uci1 84:80b15993944e 2554
uci1 84:80b15993944e 2555 const SnConfigFrame::EDatPackBit ctype = (*cw)->GetCommType();
uci1 84:80b15993944e 2556
uci1 84:80b15993944e 2557 // check Iridium time
uci1 84:80b15993944e 2558 if (ctype==SnConfigFrame::kIrid) {
uci1 40:1324da35afd4 2559
uci1 84:80b15993944e 2560 // power up for this device
uci1 84:80b15993944e 2561 if (gConf.IsCommPowerSimple()==false) {
uci1 84:80b15993944e 2562 SetPower(true, ctype);
uci1 84:80b15993944e 2563 }
uci1 84:80b15993944e 2564 const bool havePower=IsPinPowered(*cw);
uci1 84:80b15993944e 2565 if (havePower==false) {
uci1 84:80b15993944e 2566 continue;
uci1 84:80b15993944e 2567 }
uci1 84:80b15993944e 2568
uci1 16:744ce85aede2 2569 #ifdef DEBUG
uci1 16:744ce85aede2 2570 printf("try to set iridium time\r\n");
uci1 16:744ce85aede2 2571 #endif
uci1 16:744ce85aede2 2572 // set the clock before closing connection
uci1 41:d6f5e2f09e07 2573 const uint32_t totime =
uci1 41:d6f5e2f09e07 2574 gConf.GetTimeoutTime(gLastCommWin,
uci1 41:d6f5e2f09e07 2575 gConf.GetCommWinDuration());
uci1 41:d6f5e2f09e07 2576 #ifdef DEBUG
uci1 41:d6f5e2f09e07 2577 printf("totime=%u, ctime=%u\r\n",totime,time(0));
uci1 41:d6f5e2f09e07 2578 #endif
uci1 41:d6f5e2f09e07 2579 const bool con = (*cw)->Connect(totime);
uci1 84:80b15993944e 2580 *nc = true;
uci1 84:80b15993944e 2581
uci1 16:744ce85aede2 2582 if (con) {
uci1 40:1324da35afd4 2583 uint32_t prvTime(0), setTime(0);
uci1 41:d6f5e2f09e07 2584 const bool gottime = (*cw)->TrySetSysTimeUnix(
uci1 41:d6f5e2f09e07 2585 totime, prvTime, setTime);
uci1 41:d6f5e2f09e07 2586 if (gottime) {
uci1 84:80b15993944e 2587 gClkSet.SetClocks( prvTime, setTime, time(0),
uci1 84:80b15993944e 2588 gSinceClkSet.read_us() );
uci1 84:80b15993944e 2589 gSinceClkSet.reset();
uci1 84:80b15993944e 2590 gSinceClkSet.start();
uci1 41:d6f5e2f09e07 2591 #ifdef DEBUG
uci1 84:80b15993944e 2592 // printf("sig str: totime=%u, ctime=%u\r\n",totime,time(0));
uci1 84:80b15993944e 2593 printf("sig str: totime=%u, ctime=%u\r\n",totime,gClkSet.GetCurTime());
uci1 41:d6f5e2f09e07 2594 #endif
uci1 41:d6f5e2f09e07 2595 // got time; now send signal strength
uci1 41:d6f5e2f09e07 2596 (*cw)->SendSignalStrength( gGenBuf, gSigStr, totime );
uci1 84:80b15993944e 2597 } // if got the iridium system time
uci1 84:80b15993944e 2598 } // if connected (again, possibly)
uci1 84:80b15993944e 2599 } // if iridium
uci1 84:80b15993944e 2600
uci1 84:80b15993944e 2601 if (*nc) {
uci1 84:80b15993944e 2602
uci1 84:80b15993944e 2603 // power up for this device
uci1 84:80b15993944e 2604 if (gConf.IsCommPowerSimple()==false) {
uci1 84:80b15993944e 2605 SetPower(true, ctype);
uci1 16:744ce85aede2 2606 }
uci1 84:80b15993944e 2607 const bool havePower=IsPinPowered(*cw);
uci1 84:80b15993944e 2608 if (havePower==false) {
uci1 84:80b15993944e 2609 continue;
uci1 84:80b15993944e 2610 }
uci1 84:80b15993944e 2611
uci1 28:484943132bb0 2612 #ifdef DEBUG
uci1 84:80b15993944e 2613 printf("last loop close conn. i=%d, nc=%s\r\n",
uci1 84:80b15993944e 2614 (int32_t)i, (*nc) ? "true" : "false");
uci1 28:484943132bb0 2615 #endif
uci1 84:80b15993944e 2616
uci1 84:80b15993944e 2617 const uint32_t extraDiscTime = gLastCommWin
uci1 84:80b15993944e 2618 + gConf.GetCommWinConnectTO((*cw)->GetCommType());
uci1 84:80b15993944e 2619 (*cw)->CloseConn(gConf.GetTimeoutTime(extraDiscTime, gConf.GetCommWinDuration()));
uci1 84:80b15993944e 2620 *nc = false;
uci1 84:80b15993944e 2621 }
uci1 84:80b15993944e 2622 } // end loop: check time, close conns
uci1 40:1324da35afd4 2623
uci1 84:80b15993944e 2624 /*
uci1 40:1324da35afd4 2625 // close connections
uci1 40:1324da35afd4 2626 cw = gComms;
uci1 56:0bba0ef15697 2627 for (uint8_t i=0; i<kNcomms; ++i, ++cw) {
uci1 40:1324da35afd4 2628 if ((*cw)==0) {
uci1 40:1324da35afd4 2629 continue;
uci1 40:1324da35afd4 2630 } else {
uci1 40:1324da35afd4 2631 }
uci1 28:484943132bb0 2632 }
uci1 84:80b15993944e 2633 */
uci1 84:80b15993944e 2634
uci1 28:484943132bb0 2635 } // if duration >0
uci1 28:484943132bb0 2636
uci1 28:484943132bb0 2637 /* not working. must use DEFCONF.DAT to change IP's.
uci1 28:484943132bb0 2638 // change comm parameters (IP addresses)
uci1 28:484943132bb0 2639 #ifdef DEBUG
uci1 28:484943132bb0 2640 printf("set comm params\r\n");
uci1 28:484943132bb0 2641 #endif
uci1 28:484943132bb0 2642 for (uint8_t cc=0; cc<kNcomms; cc++) {
uci1 28:484943132bb0 2643 if (gComms[cc]!=0) {
uci1 28:484943132bb0 2644 gComms[cc]->Set(gConf);
uci1 15:f2569d8e4176 2645 }
uci1 0:664899e0b988 2646 }
uci1 28:484943132bb0 2647 */
uci1 40:1324da35afd4 2648
uci1 40:1324da35afd4 2649
uci1 40:1324da35afd4 2650 // check if we missed too many consecutive connections
uci1 40:1324da35afd4 2651 if (res<=SnCommWin::kAllFails) {
uci1 40:1324da35afd4 2652 ++gConsecCommFails;
uci1 40:1324da35afd4 2653 #ifdef DEBUG
uci1 56:0bba0ef15697 2654 printf("res=%d, gConsecCommFails=%hu, kMaxConsecCommFails=%hu\r\n",
uci1 56:0bba0ef15697 2655 static_cast<int>(res), gConsecCommFails,kMaxConsecCommFails);
uci1 40:1324da35afd4 2656 #endif
uci1 40:1324da35afd4 2657 if (gConsecCommFails>kMaxConsecCommFails) {
uci1 40:1324da35afd4 2658 #ifdef DEBUG
uci1 40:1324da35afd4 2659 printf("rebooting\r\n");
uci1 40:1324da35afd4 2660 #endif
uci1 40:1324da35afd4 2661 // goodbye cruel world, it's over. walk on by...
uci1 40:1324da35afd4 2662 mbed_reset();
uci1 40:1324da35afd4 2663 }
uci1 40:1324da35afd4 2664 } else {
uci1 40:1324da35afd4 2665 gConsecCommFails=0;
uci1 40:1324da35afd4 2666 }
uci1 28:484943132bb0 2667
uci1 4:a91682e19d6b 2668 // (probably) power down comms and power up cards,amps
uci1 84:80b15993944e 2669 SetPower(false, SnConfigFrame::kIrid | SnConfigFrame::kAfar);
uci1 4:a91682e19d6b 2670
uci1 1:e392595b4b76 2671 // reset config with system powered (for DAC/PLA setting)
uci1 12:d472f9811262 2672 #ifdef DEBUG
uci1 21:ce51bb0ba4a5 2673 printf("calling SetConfigAndMakeOutputFile\r\n");
uci1 12:d472f9811262 2674 #endif
uci1 76:f8383f0292c2 2675
uci1 76:f8383f0292c2 2676 if (gConf.IsRunSeqListOneCommWinOnly()) {
uci1 76:f8383f0292c2 2677 SnSDUtils::ClearRunSeqList(gConf.IsSendingFilesRunSeqList());
uci1 76:f8383f0292c2 2678 }
uci1 22:f957c4f840ad 2679
uci1 21:ce51bb0ba4a5 2680 SetConfigAndMakeOutputFile();
uci1 21:ce51bb0ba4a5 2681
uci1 56:0bba0ef15697 2682 // check power in case we should be in low power mode
uci1 56:0bba0ef15697 2683 // but don't save this reading to the file
uci1 56:0bba0ef15697 2684 // (there's already one near the beginning)
uci1 56:0bba0ef15697 2685 CheckPower(false, false);
uci1 56:0bba0ef15697 2686
uci1 12:d472f9811262 2687 #ifdef DEBUG
uci1 1:e392595b4b76 2688 printf("closing comm win at %d\r\n",(int32_t)time(0));
uci1 84:80b15993944e 2689 printf("Free memory = %d\r\n", FreeMem());
uci1 12:d472f9811262 2690 #endif
uci1 67:ec999336fcd1 2691
uci1 67:ec999336fcd1 2692 led2 = 0;
uci1 1:e392595b4b76 2693
uci1 0:664899e0b988 2694 gCommWinOpen = false;
uci1 0:664899e0b988 2695 return res;
uci1 0:664899e0b988 2696 }