Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Fri Dec 04 02:54:48 2015 +0000
Revision:
114:554fa3a956b4
Parent:
100:3a27edf9ce16
Child:
116:8099b754fbb4
Stn31 CHIPBOARD=SST4ch1GHz. With conf name. No interface chip. Safety nets.

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