Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Tue Nov 17 06:26:23 2015 +0000
Revision:
98:ce72ef143b9b
Parent:
97:9f3fe603e8b5
Child:
100:3a27edf9ce16
S30 with conf name. Send copy of config with status update pack. 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 56:0bba0ef15697 152 #if CHIPBOARD==SST4CH
uci1 56:0bba0ef15697 153 PinName gThermPinName(p15);
uci1 56:0bba0ef15697 154 DS1820 PIN_therm(gThermPinName, gThermPinName, false); // be default, on external power
uci1 56:0bba0ef15697 155 #endif
uci1 41:d6f5e2f09e07 156
uci1 41:d6f5e2f09e07 157 // we have to do this shit because Serial and MODSERIAL don't have virtual functions
uci1 41:d6f5e2f09e07 158 // so calling, e.g. readable from a Serial* will call Serial::readable instead of MODSERIAL::readable
uci1 41:d6f5e2f09e07 159 // and the comms will wait forever
uci1 15:f2569d8e4176 160 #ifdef USE_MODSERIAL
uci1 41:d6f5e2f09e07 161 #define MAIN_SERIALTYPE AjK::MODSERIAL
uci1 15:f2569d8e4176 162 #else
uci1 41:d6f5e2f09e07 163 #define MAIN_SERIALTYPE Serial
uci1 56:0bba0ef15697 164 #endif // USE_MODSERIAL
uci1 41:d6f5e2f09e07 165
uci1 41:d6f5e2f09e07 166 // this needs to be first in case some other global uses a print statement
uci1 41:d6f5e2f09e07 167 static MAIN_SERIALTYPE gCpu( USBTX, USBRX ); // defined here so it might be used for debugging output
uci1 41:d6f5e2f09e07 168
uci1 41:d6f5e2f09e07 169 static MAIN_SERIALTYPE gSBDport(p28, p27,
uci1 16:744ce85aede2 170 #ifdef USE_MODSERIAL
uci1 41:d6f5e2f09e07 171 MODSERIAL_TX_BUF_SIZE, MODSERIAL_RX_BUF_SIZE,
uci1 56:0bba0ef15697 172 #endif // USE_MODSERIAL
uci1 41:d6f5e2f09e07 173 "sbd");
uci1 41:d6f5e2f09e07 174
uci1 56:0bba0ef15697 175 // The SD card
uci1 21:ce51bb0ba4a5 176 static SDFileSystem sd(p5, p6, p7, p8, SnSDUtils::kSDdir+1); // no leading '/'
uci1 67:ec999336fcd1 177
uci1 67:ec999336fcd1 178 // local file system is still created even if USE_INTERFACE_CHIP is not defined
uci1 67:ec999336fcd1 179 // this is done to allow the mbed to be reprogrammed remotely
uci1 25:57b2627fe756 180 static LocalFileSystem local((SnCommWin::kLocalDir)+1); // no leading '/'
uci1 0:664899e0b988 181
uci1 0:664899e0b988 182 //
uci1 0:664899e0b988 183 // fwd declare fcns
uci1 0:664899e0b988 184 //
uci1 0:664899e0b988 185 void ReadAllRegisters();
uci1 0:664899e0b988 186 void ReadRegister(const uint8_t chan, int16_t* dev);
uci1 22:f957c4f840ad 187 void SaveHeartbeat();
uci1 0:664899e0b988 188 void SaveEvent(const int32_t etms);
uci1 0:664899e0b988 189 void WaitTrigAndSendClock();
uci1 1:e392595b4b76 190 void SetConfigAndMakeOutputFile();
uci1 40:1324da35afd4 191 SnCommWin::ECommWinResult OpenCommWin(const bool forceReconfig=false,
uci1 40:1324da35afd4 192 const bool isStartupWin=false);
uci1 3:24c5f0f50bf1 193 void MakeOutputFile(const bool stopRunning=false);
uci1 84:80b15993944e 194 bool IsPowerAllowedFor(const bool isCommWin,
uci1 84:80b15993944e 195 const uint8_t devicesInUse,
uci1 84:80b15993944e 196 const SnConfigFrame::EDatPackBit b);
uci1 84:80b15993944e 197 void SetPower(const bool isCommWin,
uci1 84:80b15993944e 198 const uint8_t devicesInUse);
uci1 84:80b15993944e 199 void CheckPower(const bool isCommWin,
uci1 84:80b15993944e 200 const bool saveReading=true,
uci1 84:80b15993944e 201 const uint8_t devicesInUse=
uci1 84:80b15993944e 202 SnConfigFrame::kIrid |
uci1 84:80b15993944e 203 SnConfigFrame::kAfar);
uci1 84:80b15993944e 204 void CheckTemp();
uci1 84:80b15993944e 205 void UpdateTemperature();
uci1 84:80b15993944e 206 bool AreCardsPowered(const bool checkPin);
uci1 84:80b15993944e 207 void GetAvePowerReading();
uci1 84:80b15993944e 208 #if CHIPBOARD==SST4CH
uci1 84:80b15993944e 209 void InitTempProbe();
uci1 84:80b15993944e 210 #endif
uci1 84:80b15993944e 211 void ResetCountersClearEvt();
uci1 84:80b15993944e 212 void CalcRate(const uint32_t numtrgs,
uci1 84:80b15993944e 213 const double tottime_ms,
uci1 84:80b15993944e 214 float& rate);
uci1 84:80b15993944e 215 void GetRates(float& thmrate, float& evtrate);
uci1 84:80b15993944e 216 void AddToRate(const double dt, const bool isThm);
uci1 84:80b15993944e 217 bool IsSeqComplete();
uci1 8:95a325df1f6b 218 void procForceTrigger();
uci1 8:95a325df1f6b 219 void procHeartbeat();
uci1 8:95a325df1f6b 220 void procPowerCheck();
uci1 56:0bba0ef15697 221 void procTempCheck();
uci1 8:95a325df1f6b 222 void procCommWin();
uci1 40:1324da35afd4 223 #ifdef USE_RTOS
uci1 8:95a325df1f6b 224 void procForceTrigger(void const *) { return procForceTrigger(); }
uci1 8:95a325df1f6b 225 void procHeartbeat(void const *) { return procHeartbeat(); }
uci1 8:95a325df1f6b 226 void procPowerCheck(void const *) { return procPowerCheck(); }
uci1 8:95a325df1f6b 227 void procCommWin(void const *) { return procCommWin(); }
uci1 56:0bba0ef15697 228 void procTempCheck(void const *) { return procTempCheck(); }
uci1 56:0bba0ef15697 229 #endif // USE_RTOS
uci1 0:664899e0b988 230
uci1 0:664899e0b988 231 //
uci1 0:664899e0b988 232 // globals
uci1 0:664899e0b988 233 //
uci1 0:664899e0b988 234 // readout objs
uci1 8:95a325df1f6b 235 // TODO: use RtosTimer instead of Ticker?
uci1 40:1324da35afd4 236 #ifdef USE_RTOS
uci1 8:95a325df1f6b 237 static rtos::RtosTimer* gForceTicker;
uci1 8:95a325df1f6b 238 static rtos::RtosTimer* gHeartbeatTicker;
uci1 8:95a325df1f6b 239 static rtos::RtosTimer* gCommWinTicker;
uci1 8:95a325df1f6b 240 static rtos::RtosTimer* gPowerCheckTicker;
uci1 56:0bba0ef15697 241 static rtos::RtosTimer* gTempCheckTicker;
uci1 8:95a325df1f6b 242 #else
uci1 0:664899e0b988 243 static Ticker gForceTicker;
uci1 3:24c5f0f50bf1 244 static Ticker gHeartbeatTicker;
uci1 1:e392595b4b76 245 static Ticker gCommWinTicker;
uci1 8:95a325df1f6b 246 static Ticker gPowerCheckTicker;
uci1 56:0bba0ef15697 247 static Ticker gTempCheckTicker;
uci1 56:0bba0ef15697 248 #endif // USE_RTOS
uci1 40:1324da35afd4 249 static Timer gAllTrgTimer;
uci1 40:1324da35afd4 250 static Timer gThmTrgTimer;
uci1 16:744ce85aede2 251 static Timer gAdcToMBtimer;
uci1 67:ec999336fcd1 252
uci1 84:80b15993944e 253 static Timer gSinceClkSet;
uci1 41:d6f5e2f09e07 254 static SnClockSetFrame gClkSet;
uci1 41:d6f5e2f09e07 255 static SnSignalStrengthFrame gSigStr;
uci1 31:b5bd3b189150 256 #ifdef DISABLE_CONFIG_SAFETYNETS
uci1 31:b5bd3b189150 257 static SnConfigFrame gConf(false);
uci1 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 56:0bba0ef15697 450 #if CHIPBOARD==SST4CH
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 67:ec999336fcd1 471 #if CHIPBOARD==SST4CH
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 62:4b59c1eb429f 837 #endif
uci1 62:4b59c1eb429f 838 Watchdog::kick(gConf.GetWatchdogPeriod());
uci1 56:0bba0ef15697 839
uci1 56:0bba0ef15697 840 gCpu.baud(CPUBAUD_SN);
uci1 56:0bba0ef15697 841
uci1 1:e392595b4b76 842 {
uci1 18:55f1581f2ee4 843 #if defined(SSNOTIFY) || defined(DEBUG)
uci1 41:d6f5e2f09e07 844 printf("\n\n\n\n\nmain: start\r\n");
uci1 15:f2569d8e4176 845 #endif
uci1 67:ec999336fcd1 846 led1=led2=led3=led4=0;
uci1 40:1324da35afd4 847 #ifdef USE_RTOS
uci1 40:1324da35afd4 848 led1=1; Thread::wait(200);
uci1 40:1324da35afd4 849 led1=0; led2=1; Thread::wait(200);
uci1 40:1324da35afd4 850 led2=0; led3=1; Thread::wait(200);
uci1 40:1324da35afd4 851 led3=0; led4=1; Thread::wait(200);
uci1 40:1324da35afd4 852 #else
uci1 2:e67f7c158087 853 led1=1; wait(0.2);
uci1 2:e67f7c158087 854 led1=0; led2=1; wait(0.2);
uci1 2:e67f7c158087 855 led2=0; led3=1; wait(0.2);
uci1 2:e67f7c158087 856 led3=0; led4=1; wait(0.2);
uci1 56:0bba0ef15697 857 #endif // USE_RTOS
uci1 1:e392595b4b76 858 led4=0;
uci1 1:e392595b4b76 859 }
uci1 67:ec999336fcd1 860
uci1 67:ec999336fcd1 861 // signal startup before first comm win
uci1 67:ec999336fcd1 862 led2 = led1 = 1;
uci1 25:57b2627fe756 863
uci1 56:0bba0ef15697 864 // don't initialize yet, but give SnSDUtils a pointer to
uci1 56:0bba0ef15697 865 // the function that initializes it, so it can call the fcn later
uci1 40:1324da35afd4 866 SnSDUtils::fgDoInit = &InitSDCard;
uci1 56:0bba0ef15697 867
uci1 63:4820a4460f00 868 // check in case we need to go to low power
uci1 63:4820a4460f00 869 //wait(4); // TODO: the vADCs read high for first ~4-5sec
uci1 63:4820a4460f00 870 CheckPower(false, false);
uci1 63:4820a4460f00 871 #ifdef DEBUG
uci1 63:4820a4460f00 872 printf("startup power: cards %d, amps %d, irid %d, afar %d\r\n",
uci1 63:4820a4460f00 873 PIN_turn_on_system.read(), PIN_turn_on_amps.read(),
uci1 63:4820a4460f00 874 PIN_iridSbd_power.read(), PIN_afar_power.read());
uci1 63:4820a4460f00 875 #endif
uci1 63:4820a4460f00 876
uci1 61:42cbfc02e0e0 877 /*
uci1 56:0bba0ef15697 878 // Note: the brownout isn't useful since it sees either 5V or nothing on our board
uci1 56:0bba0ef15697 879 // set up the brownout interrupt
uci1 56:0bba0ef15697 880 NVIC_SetVector(BOD_IRQn, (uint32_t)&UponBrownout);
uci1 56:0bba0ef15697 881 // Enable Brown Out Detect Interrupt
uci1 56:0bba0ef15697 882 NVIC_EnableIRQ(BOD_IRQn);
uci1 61:42cbfc02e0e0 883 */
uci1 56:0bba0ef15697 884
uci1 21:ce51bb0ba4a5 885 #ifdef DEBUG
uci1 18:55f1581f2ee4 886 printf("making comm objects\r\n");
uci1 18:55f1581f2ee4 887 #endif
uci1 25:57b2627fe756 888
uci1 25:57b2627fe756 889 uint8_t comi(0);
uci1 25:57b2627fe756 890 #ifdef ENABLE_AFAR_COMM
uci1 25:57b2627fe756 891 // RTOS stuff must be made inside main for some reason
uci1 18:55f1581f2ee4 892 #ifdef USE_ETH_INTERFACE
uci1 41:d6f5e2f09e07 893 #ifdef DEBUG
uci1 41:d6f5e2f09e07 894 printf("making SnCommAfarTCP\r\n");
uci1 41:d6f5e2f09e07 895 #endif
uci1 25:57b2627fe756 896 gComms[comi++] = new SnCommAfarTCP(gConf);
uci1 18:55f1581f2ee4 897 #else
uci1 41:d6f5e2f09e07 898 #ifdef DEBUG
uci1 41:d6f5e2f09e07 899 printf("making SnCommWinAfar\r\n");
uci1 41:d6f5e2f09e07 900 #endif
uci1 37:ff95e7070f26 901 //gComms[comi++] = new SnCommAfarNetIf(gConf);
uci1 37:ff95e7070f26 902 gComms[comi++] = new SnCommWinAfar(gConf);
uci1 28:484943132bb0 903 #ifdef ENABLE_AFAR_TWITTER
uci1 41:d6f5e2f09e07 904 #ifdef DEBUG
uci1 41:d6f5e2f09e07 905 printf("making SnCommAfarNetIfTwitter\r\n");
uci1 41:d6f5e2f09e07 906 #endif
uci1 28:484943132bb0 907 gTwit = new SnCommAfarNetIfTwitter(gConf);
uci1 56:0bba0ef15697 908 #endif // ENABLE_AFAR_TWITTER
uci1 56:0bba0ef15697 909 #endif // USE_ETH_INTERFACE
uci1 56:0bba0ef15697 910 #endif // ENABLE_AFAR_COMM
uci1 25:57b2627fe756 911 #ifdef ENABLE_SBD_COMM
uci1 41:d6f5e2f09e07 912 #ifdef DEBUG
uci1 41:d6f5e2f09e07 913 printf("making SnCommWinSBD\r\n");
uci1 41:d6f5e2f09e07 914 #endif
uci1 40:1324da35afd4 915 gComms[comi++] = new SnCommWinSBD(&gSBDport);
uci1 56:0bba0ef15697 916 #endif // ENABLE_SBD_COMM
uci1 25:57b2627fe756 917 #ifdef ENABLE_USB_COMM
uci1 41:d6f5e2f09e07 918 #ifdef DEBUG
uci1 41:d6f5e2f09e07 919 printf("makin SnCommWinUsb\r\n");
uci1 41:d6f5e2f09e07 920 #endif
uci1 37:ff95e7070f26 921 gComms[comi++] = new SnCommWinUsb(&gCpu);
uci1 56:0bba0ef15697 922 #endif // ENABLE_USB_COMM
uci1 18:55f1581f2ee4 923
uci1 18:55f1581f2ee4 924 #ifdef DEBUG
uci1 28:484943132bb0 925 printf("made comm objects\r\n");
uci1 41:d6f5e2f09e07 926 #ifdef USE_MODSERIAL
uci1 41:d6f5e2f09e07 927 printf("using MODSERIAL\r\n");
uci1 56:0bba0ef15697 928 #endif // USE_MODSERIAL
uci1 18:55f1581f2ee4 929 #endif
uci1 40:1324da35afd4 930
uci1 40:1324da35afd4 931 if (comi!=kNcomms) {
uci1 40:1324da35afd4 932 error("comi=[%hhu] != kNcomms=[%hhu]\r\n",
uci1 40:1324da35afd4 933 comi, kNcomms);
uci1 40:1324da35afd4 934 // will die here with blue lights of death
uci1 40:1324da35afd4 935 }
uci1 40:1324da35afd4 936
uci1 40:1324da35afd4 937 #ifdef USE_RTOS
uci1 8:95a325df1f6b 938 gForceTicker = new rtos::RtosTimer(&procForceTrigger);
uci1 8:95a325df1f6b 939 gHeartbeatTicker = new rtos::RtosTimer(&procHeartbeat);
uci1 8:95a325df1f6b 940 gCommWinTicker = new rtos::RtosTimer(&procCommWin);
uci1 8:95a325df1f6b 941 gPowerCheckTicker = new rtos::RtosTimer(&procPowerCheck);
uci1 56:0bba0ef15697 942 gTempCheckTicker = new rtos::RtosTimer(&procTempCheck);
uci1 56:0bba0ef15697 943 #endif // USE_RTOS
uci1 67:ec999336fcd1 944
uci1 1:e392595b4b76 945 // set the clock to the BS time, if it's not set
uci1 1:e392595b4b76 946 if ( (static_cast<int32_t>(time(0)))<0 ) {
uci1 1:e392595b4b76 947 set_time(kBStime);
uci1 1:e392595b4b76 948 }
uci1 12:d472f9811262 949 #ifdef DEBUG
uci1 1:e392595b4b76 950 printf("time = %d\r\n",(int32_t)time(0));
uci1 12:d472f9811262 951 #endif
uci1 1:e392595b4b76 952 gLastCommWin = time(0); // prevent comm win proc
uci1 0:664899e0b988 953
uci1 40:1324da35afd4 954 #ifdef USE_RTOS
uci1 8:95a325df1f6b 955 gForceTicker->stop();
uci1 8:95a325df1f6b 956 #else
uci1 0:664899e0b988 957 gForceTicker.detach();
uci1 56:0bba0ef15697 958 #endif // USE_RTOS
uci1 0:664899e0b988 959 gFirstEvt = true;
uci1 56:0bba0ef15697 960
uci1 67:ec999336fcd1 961
uci1 67:ec999336fcd1 962 #ifdef DEBUG
uci1 67:ec999336fcd1 963 printf("MAC=%012llX\r\n", (gConf.GetMacAddress())>>16); // 64 -> 48 bits
uci1 67:ec999336fcd1 964 printf("my ip = %s\r\n", gConf.GetMbedIP());
uci1 67:ec999336fcd1 965 printf("my mask = %s\r\n", gConf.GetMbedMask());
uci1 67:ec999336fcd1 966 printf("my gate = %s\r\n", gConf.GetMbedGate());
uci1 67:ec999336fcd1 967 printf("remote server = %s : %hu\r\n",
uci1 67:ec999336fcd1 968 gConf.GetRemoteServer(), gConf.GetRemotePort());
uci1 84:80b15993944e 969 for (uint8_t i=0; i<SnConfigFrame::kNumDatStreams; ++i) {
uci1 84:80b15993944e 970 printf("data stream %hhu (%s): connectTO=%hhu, listenTO=%hhu\r\n",
uci1 84:80b15993944e 971 i, SnConfigFrame::GetDataStreamNameOfIdx(i),
uci1 84:80b15993944e 972 gConf.GetCommWinConnectTOofIdx(i),
uci1 84:80b15993944e 973 gConf.GetCommWinListenTOofIdx(i));
uci1 84:80b15993944e 974 }
uci1 67:ec999336fcd1 975 #endif
uci1 67:ec999336fcd1 976
uci1 4:a91682e19d6b 977 // (probably) power down comms and power up cards,amps
uci1 84:80b15993944e 978 SetPower(false, SnConfigFrame::kIrid | SnConfigFrame::kAfar);
uci1 56:0bba0ef15697 979 // check power again to see if voltages drooped
uci1 56:0bba0ef15697 980 CheckPower(false, false);
uci1 4:a91682e19d6b 981
uci1 0:664899e0b988 982 //
uci1 0:664899e0b988 983 // get config
uci1 0:664899e0b988 984 //
uci1 12:d472f9811262 985 #ifdef DEBUG
uci1 84:80b15993944e 986 printf("run mode\r\n");
uci1 84:80b15993944e 987 printf("IsCountingPowerReadings=%d\r\n",(int)gConf.IsCountingPowerReadings());
uci1 84:80b15993944e 988 printf("IsSingleSeqRunMode=%d\r\n",(int)gConf.IsSingleSeqRunMode());
uci1 84:80b15993944e 989 printf("IsDualThresholdMode=%d\r\n",(int)gConf.IsDualThresholdMode());
uci1 84:80b15993944e 990 printf("IsDifferentialTrigMode=%d\r\n",(int)gConf.IsDifferentialTrigMode());
uci1 84:80b15993944e 991 printf("IsSBDonlyLowPwrMode=%d\r\n",(int)gConf.IsSBDonlyLowPwrMode());
uci1 84:80b15993944e 992 printf("IsRunSeqListOneCommWinOnly=%d\r\n",(int)gConf.IsRunSeqListOneCommWinOnly());
uci1 84:80b15993944e 993 printf("IsIgnoringSDcard=%d\r\n",(int)gConf.IsIgnoringSDcard());
uci1 84:80b15993944e 994 printf("IsCommPowerSimple=%d\r\n",(int)gConf.IsCommPowerSimple());
uci1 8:95a325df1f6b 995 printf("call OpenCommWin\r\n");
uci1 84:80b15993944e 996 printf("Free memory = %d\r\n", FreeMem());
uci1 12:d472f9811262 997 #endif
uci1 67:ec999336fcd1 998 led2 = led1 = 0; // back to "normal" for comm win
uci1 40:1324da35afd4 999 OpenCommWin(true, true); // alwasy configure, even if no new config
uci1 3:24c5f0f50bf1 1000
uci1 0:664899e0b988 1001 // get ready to trigger
uci1 0:664899e0b988 1002 PIN_spi.format( 16, 1 ); // change to data readout format
uci1 15:f2569d8e4176 1003 PIN_spi.frequency( 10000000 ); // Max is 12.5 MHz
uci1 0:664899e0b988 1004
uci1 41:d6f5e2f09e07 1005 // read and cache the dCard power pin setting,
uci1 41:d6f5e2f09e07 1006 // so we can use the cached value later
uci1 37:ff95e7070f26 1007 AreCardsPowered(true); // TODO: should this be an if?
uci1 56:0bba0ef15697 1008 register double etms=0; // time between written events
uci1 41:d6f5e2f09e07 1009
uci1 41:d6f5e2f09e07 1010 // the main event loop. wait for triggers in SendClock
uci1 41:d6f5e2f09e07 1011 while ( true ) {
uci1 0:664899e0b988 1012 // in here, we wait for triggers from the MB-FPGA
uci1 0:664899e0b988 1013 Watchdog::kick(); // don't reset!
uci1 1:e392595b4b76 1014
uci1 67:ec999336fcd1 1015 led1 = 1; // signal normal running (i.e. waiting)
uci1 1:e392595b4b76 1016
uci1 12:d472f9811262 1017 #ifdef DEBUG
uci1 1:e392595b4b76 1018 printf("calling wait trig\r\n");
uci1 1:e392595b4b76 1019 printf("gFirstEvt=%s\r\n",gFirstEvt?"true":"false");
uci1 5:9cea89700c66 1020 printf("readingout=%d\r\n",(int)gReadingOut);
uci1 84:80b15993944e 1021 printf("Free memory = %d\r\n", FreeMem());
uci1 12:d472f9811262 1022 #endif
uci1 40:1324da35afd4 1023 if (gFirstEvt) {
uci1 41:d6f5e2f09e07 1024 #ifdef DEBUG
uci1 41:d6f5e2f09e07 1025 printf("WriteTrigWaitWinTime (start)\r\n");
uci1 41:d6f5e2f09e07 1026 #endif
uci1 97:9f3fe603e8b5 1027 gClkSet.UpdateClock( gSinceClkSet );
uci1 40:1324da35afd4 1028 SnSDUtils::WriteTrigWaitWinTime(SnSDUtils::GetCurFile(),
uci1 40:1324da35afd4 1029 gClkSet,
uci1 40:1324da35afd4 1030 true);
uci1 40:1324da35afd4 1031 gThmTrgTimer.reset(); gThmTrgTimer.start();
uci1 40:1324da35afd4 1032 gAllTrgTimer.reset(); gAllTrgTimer.start();
uci1 84:80b15993944e 1033 gStTrgStartClk = gClkSet;
uci1 56:0bba0ef15697 1034 #if CHIPBOARD==SST4CH
uci1 56:0bba0ef15697 1035 // reset in case a trigger arrived before we were ready
uci1 56:0bba0ef15697 1036 // this is mostly to ensure that the chip gets reset on soft
uci1 56:0bba0ef15697 1037 // reboot, in case it got stopped prior to the reboot
uci1 56:0bba0ef15697 1038 PIN_ResetChips = 1;
uci1 56:0bba0ef15697 1039 PIN_ResetChips = 0;
uci1 56:0bba0ef15697 1040 #endif
uci1 40:1324da35afd4 1041 }
uci1 76:f8383f0292c2 1042
uci1 56:0bba0ef15697 1043 #if CHIPBOARD==ATWD4CH
uci1 56:0bba0ef15697 1044 PIN_lockRegisters = 0; // allow data to come from DFPGA
uci1 56:0bba0ef15697 1045 WaitTrigAndSendClock(); // wait for trigger and move data to MB. this returns immediately if cards are powered off
uci1 56:0bba0ef15697 1046 PIN_lockRegisters = 1; // block registers during readout
uci1 56:0bba0ef15697 1047 #else
uci1 56:0bba0ef15697 1048 PIN_readingData = 0; // not reading yet
uci1 56:0bba0ef15697 1049 WaitTrigAndSendClock(); // wait for trigger. this returns immediately if cards are powered off
uci1 56:0bba0ef15697 1050 // PIN_readingData will be set high by SnEventFrame::ReadWaveformsSST
uci1 56:0bba0ef15697 1051 #endif // ATWD4CH
uci1 12:d472f9811262 1052 #ifdef EVT_TIME_PROFILE
uci1 84:80b15993944e 1053 gProfiler.start();
uci1 84:80b15993944e 1054 int befSaveEvt=0, aftSaveEvt=0,
uci1 12:d472f9811262 1055 befChkPow=0, aftChkPow=0, befNewSeq=0, aftNewSeq=0, endOfLoop=0;
uci1 56:0bba0ef15697 1056 #endif // EVT_TIME_PROFILE
uci1 12:d472f9811262 1057
uci1 1:e392595b4b76 1058 if (gReadingOut) {
uci1 67:ec999336fcd1 1059
uci1 67:ec999336fcd1 1060 led1 = 0; led4 = 1; // signal reading out
uci1 67:ec999336fcd1 1061
uci1 56:0bba0ef15697 1062 const double ttms = gThmTrgTimer.read_us() / 1e3; // for rate calculation
uci1 56:0bba0ef15697 1063 const double atms = gAllTrgTimer.read_us() / 1e3; // for throttle
uci1 84:80b15993944e 1064 // if (gEvent.IsForcedTrg()==false) {
uci1 84:80b15993944e 1065 if (gForcedTrig) {
uci1 40:1324da35afd4 1066 // don't reset if not a thermal trigger
uci1 40:1324da35afd4 1067 gThmTrgTimer.reset(); gThmTrgTimer.start();
uci1 40:1324da35afd4 1068 }
uci1 40:1324da35afd4 1069 gAllTrgTimer.reset(); gAllTrgTimer.start(); // restart trigger timer
uci1 40:1324da35afd4 1070 etms += atms; // time between events
uci1 8:95a325df1f6b 1071
uci1 8:95a325df1f6b 1072 Watchdog::kick(); // don't reset!
uci1 15:f2569d8e4176 1073
uci1 1:e392595b4b76 1074 //
uci1 1:e392595b4b76 1075 // got trigger. read registers to mbed and build the event
uci1 1:e392595b4b76 1076 //
uci1 1:e392595b4b76 1077
uci1 50:163ec8d88aa9 1078 // TODO: no way to check for external trigger?
uci1 84:80b15993944e 1079 if (gForcedTrig==false) {
uci1 84:80b15993944e 1080 // ++(gTrgNum[kThmTrg]);
uci1 84:80b15993944e 1081 ++gNumThmTrigs;
uci1 50:163ec8d88aa9 1082 AddToRate(ttms, true);
uci1 84:80b15993944e 1083 }
uci1 1:e392595b4b76 1084
uci1 84:80b15993944e 1085 if ( gForcedTrig || gFirstEvt ||
uci1 56:0bba0ef15697 1086 (etms>=gConf.GetEvtThrtlPeriodMs()) ) {
uci1 1:e392595b4b76 1087
uci1 12:d472f9811262 1088 #ifdef EVT_TIME_PROFILE
uci1 84:80b15993944e 1089 gProfiler.stop(); befSaveEvt=gProfiler.read_us(); gProfiler.start();
uci1 56:0bba0ef15697 1090 #endif // EVT_TIME_PROFILE
uci1 84:80b15993944e 1091
uci1 84:80b15993944e 1092 // want to keep this event. save it (and check if it passes L1)
uci1 1:e392595b4b76 1093 SaveEvent(etms);
uci1 22:f957c4f840ad 1094 AddToRate(etms, false);
uci1 12:d472f9811262 1095 etms=0;
uci1 84:80b15993944e 1096
uci1 12:d472f9811262 1097 #ifdef EVT_TIME_PROFILE
uci1 84:80b15993944e 1098 gProfiler.stop(); aftSaveEvt=gProfiler.read_us(); gProfiler.start();
uci1 56:0bba0ef15697 1099 #endif // EVT_TIME_PROFILE
uci1 84:80b15993944e 1100
uci1 56:0bba0ef15697 1101 } else {
uci1 56:0bba0ef15697 1102 #if CHIPBOARD==SST4CH
uci1 56:0bba0ef15697 1103 // reset in case a trigger arrived before we were ready
uci1 56:0bba0ef15697 1104 PIN_ResetChips = 1;
uci1 56:0bba0ef15697 1105 PIN_ResetChips = 0;
uci1 12:d472f9811262 1106 #endif
uci1 1:e392595b4b76 1107 }
uci1 67:ec999336fcd1 1108
uci1 84:80b15993944e 1109 // done with this event.
uci1 84:80b15993944e 1110 // reset flags from the "old" event
uci1 84:80b15993944e 1111 gForcedTrig = false;
uci1 84:80b15993944e 1112 gAdcToMBflag = false;
uci1 84:80b15993944e 1113
uci1 67:ec999336fcd1 1114 led1 = 1; led4 = 0; // end signal reading out
uci1 67:ec999336fcd1 1115
uci1 1:e392595b4b76 1116 }
uci1 12:d472f9811262 1117 #ifdef DEBUG
uci1 1:e392595b4b76 1118 printf("past reading out\r\n");
uci1 12:d472f9811262 1119 #endif
uci1 1:e392595b4b76 1120
uci1 23:ccf39298f205 1121 if (gHrtbtFired) {
uci1 67:ec999336fcd1 1122 led1 = 1; led4 = 1; // signal saving transient
uci1 84:80b15993944e 1123 gHrtbt.SetTime( gLastHrtbt );
uci1 84:80b15993944e 1124 // -1 so we start counting at 0
uci1 84:80b15993944e 1125 // counting inside proc so we have a record of the number of proc's
uci1 84:80b15993944e 1126 // even if we are saving/triggering slower than they're firing
uci1 84:80b15993944e 1127 gHrtbt.SetNum( (gHrtbtNum>0) ? (gHrtbtNum - 1) : 0 );
uci1 23:ccf39298f205 1128 SaveHeartbeat();
uci1 23:ccf39298f205 1129 gHrtbtFired=false;
uci1 84:80b15993944e 1130 gStNewHeartbeat = true;
uci1 67:ec999336fcd1 1131 led1 = 1; led4 = 0; // end signal saving transient
uci1 23:ccf39298f205 1132 }
uci1 12:d472f9811262 1133
uci1 12:d472f9811262 1134 #ifdef EVT_TIME_PROFILE
uci1 84:80b15993944e 1135 gProfiler.stop(); befChkPow=gProfiler.read_us(); gProfiler.start();
uci1 56:0bba0ef15697 1136 #endif // EVT_TIME_PROFILE
uci1 8:95a325df1f6b 1137 // check the power?
uci1 8:95a325df1f6b 1138 if (gCheckPower) {
uci1 12:d472f9811262 1139 #ifdef DEBUG
uci1 8:95a325df1f6b 1140 printf("call check power\r\n");
uci1 12:d472f9811262 1141 #endif
uci1 67:ec999336fcd1 1142 led1 = 1; led4 = 1; // signal saving transient
uci1 8:95a325df1f6b 1143 CheckPower(false);
uci1 84:80b15993944e 1144 gStPower = gPower;
uci1 84:80b15993944e 1145 gStNewPower = true;
uci1 67:ec999336fcd1 1146 led1 = 1; led4 = 0; // end signal saving transient
uci1 8:95a325df1f6b 1147 }
uci1 12:d472f9811262 1148 #ifdef EVT_TIME_PROFILE
uci1 84:80b15993944e 1149 gProfiler.stop(); aftChkPow=gProfiler.read_us(); gProfiler.start();
uci1 56:0bba0ef15697 1150 #endif // EVT_TIME_PROFILE
uci1 56:0bba0ef15697 1151
uci1 56:0bba0ef15697 1152 if (gCheckTemp) {
uci1 56:0bba0ef15697 1153 #ifdef DEBUG
uci1 56:0bba0ef15697 1154 printf("call check temp\r\n");
uci1 12:d472f9811262 1155 #endif
uci1 67:ec999336fcd1 1156 led1 = 1; led4 = 1; // signal saving transient
uci1 56:0bba0ef15697 1157 CheckTemp();
uci1 84:80b15993944e 1158 gStTemperature = gTemperature;
uci1 84:80b15993944e 1159 gStNewTemperature = true;
uci1 67:ec999336fcd1 1160 led1 = 1; led4 = 0; // end signal saving transient
uci1 56:0bba0ef15697 1161 }
uci1 8:95a325df1f6b 1162
uci1 21:ce51bb0ba4a5 1163 // open comm win?
uci1 21:ce51bb0ba4a5 1164 if (gOpenCommWin) {
uci1 21:ce51bb0ba4a5 1165 #ifdef DEBUG
uci1 21:ce51bb0ba4a5 1166 printf("gOpenComWin=%s, opening\r\n",gOpenCommWin?"true":"false");
uci1 41:d6f5e2f09e07 1167 printf("WriteTrigWaitWinTime (stop)\r\n");
uci1 21:ce51bb0ba4a5 1168 #endif
uci1 97:9f3fe603e8b5 1169 gClkSet.UpdateClock( gSinceClkSet );
uci1 40:1324da35afd4 1170 SnSDUtils::WriteTrigWaitWinTime(SnSDUtils::GetCurFile(),
uci1 40:1324da35afd4 1171 gClkSet,
uci1 40:1324da35afd4 1172 false);
uci1 84:80b15993944e 1173 gStTrgStopClk = gClkSet;
uci1 67:ec999336fcd1 1174 led1 = 0; // signal not waiting
uci1 21:ce51bb0ba4a5 1175 OpenCommWin();
uci1 67:ec999336fcd1 1176 led1 = 1; // end signal not waiting
uci1 21:ce51bb0ba4a5 1177 gOpenCommWin=false;
uci1 22:f957c4f840ad 1178 gFirstEvt = true;
uci1 40:1324da35afd4 1179 gAllTrgTimer.reset();
uci1 40:1324da35afd4 1180 gThmTrgTimer.reset();
uci1 22:f957c4f840ad 1181 etms=0;
uci1 21:ce51bb0ba4a5 1182 } else {
uci1 21:ce51bb0ba4a5 1183 #ifdef DEBUG
uci1 27:efc4d654b139 1184 printf("gOpenCommWin=false, gCommWinChecks=%u, gNcommWinChecks=%u\r\n",
uci1 27:efc4d654b139 1185 gCommWinChecks, gNcommWinChecks);
uci1 21:ce51bb0ba4a5 1186 #endif
uci1 21:ce51bb0ba4a5 1187 }
uci1 21:ce51bb0ba4a5 1188
uci1 12:d472f9811262 1189 #ifdef EVT_TIME_PROFILE
uci1 84:80b15993944e 1190 gProfiler.stop(); befNewSeq=gProfiler.read_us(); gProfiler.start();
uci1 56:0bba0ef15697 1191 #endif // EVT_TIME_PROFILE
uci1 8:95a325df1f6b 1192 // make new seq?
uci1 8:95a325df1f6b 1193 if (IsSeqComplete()) {
uci1 12:d472f9811262 1194 #ifdef DEBUG
uci1 10:3c93db1cfb12 1195 printf("seq complete. sngseq=%d\r\n",gConf.IsSingleSeqRunMode());
uci1 41:d6f5e2f09e07 1196 printf("WriteTrigWaitWinTime (stop)\r\n");
uci1 12:d472f9811262 1197 #endif
uci1 67:ec999336fcd1 1198 led1 = 1; led2 = 1; led4 = 1; // signal saving file
uci1 97:9f3fe603e8b5 1199 gClkSet.UpdateClock( gSinceClkSet );
uci1 40:1324da35afd4 1200 SnSDUtils::WriteTrigWaitWinTime(SnSDUtils::GetCurFile(),
uci1 40:1324da35afd4 1201 gClkSet,
uci1 40:1324da35afd4 1202 false);
uci1 84:80b15993944e 1203 gStTrgStopClk = gClkSet;
uci1 8:95a325df1f6b 1204 MakeOutputFile(gConf.IsSingleSeqRunMode());
uci1 22:f957c4f840ad 1205 gFirstEvt = true;
uci1 40:1324da35afd4 1206 gThmTrgTimer.reset();
uci1 40:1324da35afd4 1207 gAllTrgTimer.reset();
uci1 22:f957c4f840ad 1208 etms=0;
uci1 67:ec999336fcd1 1209 led1 = 1; led2 = 0; led4 = 0; // end signal saving file
uci1 8:95a325df1f6b 1210 }
uci1 12:d472f9811262 1211 #ifdef EVT_TIME_PROFILE
uci1 84:80b15993944e 1212 gProfiler.stop(); aftNewSeq=gProfiler.read_us(); gProfiler.start();
uci1 56:0bba0ef15697 1213 #endif // EVT_TIME_PROFILE
uci1 12:d472f9811262 1214
uci1 12:d472f9811262 1215 #ifdef EVT_TIME_PROFILE
uci1 84:80b15993944e 1216 gProfiler.stop(); endOfLoop=gProfiler.read_us(); gProfiler.start();
uci1 84:80b15993944e 1217 printf("befSaveEvt=%d, aftSaveEvt=%d, "
uci1 12:d472f9811262 1218 "befChkPow=%d, aftChkPow=%d, befNewSeq=%d, aftNewSeq=%d, endOfLoop=%d\r\n",
uci1 84:80b15993944e 1219 befSaveEvt, aftSaveEvt,
uci1 12:d472f9811262 1220 befChkPow, aftChkPow, befNewSeq, aftNewSeq, endOfLoop);
uci1 56:0bba0ef15697 1221 #endif // EVT_TIME_PROFILE
uci1 41:d6f5e2f09e07 1222
uci1 41:d6f5e2f09e07 1223 /*
uci1 15:f2569d8e4176 1224 // get ready to trigger
uci1 15:f2569d8e4176 1225 PIN_spi.format( 16, 1 ); // change to data readout format
uci1 15:f2569d8e4176 1226 PIN_spi.frequency( 10000000 ); // Max is 12.5 MHz
uci1 41:d6f5e2f09e07 1227 */
uci1 22:f957c4f840ad 1228
uci1 21:ce51bb0ba4a5 1229 // reset event
uci1 22:f957c4f840ad 1230 // clear after comm win, so full event can be sent with status
uci1 22:f957c4f840ad 1231 // but don't clear counters or trigger bits, as
uci1 84:80b15993944e 1232 // gEvent.ClearEvent(true);
uci1 21:ce51bb0ba4a5 1233
uci1 41:d6f5e2f09e07 1234 } // end while (true)
uci1 0:664899e0b988 1235
uci1 0:664899e0b988 1236 }
uci1 0:664899e0b988 1237
uci1 0:664899e0b988 1238 //
uci1 22:f957c4f840ad 1239 // save a heartbeat tag
uci1 22:f957c4f840ad 1240 //
uci1 22:f957c4f840ad 1241 void SaveHeartbeat() {
uci1 22:f957c4f840ad 1242 #ifdef DEBUG
uci1 84:80b15993944e 1243 printf("save heartbeat #%u, time %u\r\n",
uci1 84:80b15993944e 1244 gHrtbt.GetNum(), gHrtbt.GetTime());
uci1 22:f957c4f840ad 1245 #endif
uci1 84:80b15993944e 1246 // save to SD
uci1 56:0bba0ef15697 1247 #if CHIPBOARD==ATWD4CH
uci1 84:80b15993944e 1248 PIN_lockRegisters = 0; // unlock so we can talk to the SD card
uci1 56:0bba0ef15697 1249 #else
uci1 84:80b15993944e 1250 PIN_readingData = 0; // unlock so we can talk to the SD card
uci1 56:0bba0ef15697 1251 #endif
uci1 84:80b15993944e 1252 SnSDUtils::WriteHeartbeatTo(SnSDUtils::GetCurFile(), gHrtbt);
uci1 22:f957c4f840ad 1253 }
uci1 22:f957c4f840ad 1254
uci1 22:f957c4f840ad 1255 //
uci1 0:664899e0b988 1256 // save the event
uci1 0:664899e0b988 1257 //
uci1 0:664899e0b988 1258 void SaveEvent(const int32_t etms) {
uci1 0:664899e0b988 1259 // write the event
uci1 12:d472f9811262 1260
uci1 12:d472f9811262 1261 #ifdef DEBUG
uci1 84:80b15993944e 1262 // check that the event is still the same as gLastEvent
uci1 84:80b15993944e 1263 /*
uci1 84:80b15993944e 1264 bool esame = gEvent.GetMbedTime() == gLastEvent.GetMbedTime();
uci1 84:80b15993944e 1265 esame &= gEvent.GetEvtNum() == gLastEvent.GetEvtNum();
uci1 84:80b15993944e 1266 esame &= gEvent.GetDTms() == gLastEvent.GetDTms();
uci1 84:80b15993944e 1267 esame &= gEvent.GetTrgNum() == gLastEvent.GetTrgNum();
uci1 84:80b15993944e 1268 esame &= gEvent.GetTrgBits() == gLastEvent.GetTrgBits();
uci1 84:80b15993944e 1269 esame &= gEvent.GetCRC() == gLastEvent.GetCRC();
uci1 84:80b15993944e 1270 for (uint16_t i=0; i<kTotSamps; ++i) {
uci1 84:80b15993944e 1271 esame &= (gEvent.GetData())[i] == (gLastEvent.GetData())[i];
uci1 84:80b15993944e 1272 }
uci1 84:80b15993944e 1273 #if CHIPBOARD!=ATWD4CH
uci1 84:80b15993944e 1274 for (uint16_t i=0; i<kNstopBytes; ++i) {
uci1 84:80b15993944e 1275 esame &= (gEvent.GetStop())[i] == (gLastEvent.GetStop())[i];
uci1 84:80b15993944e 1276 }
uci1 84:80b15993944e 1277 printf("EEEEEEEE event==lastEvt = %s\r\n", (esame?"true":"false"));
uci1 84:80b15993944e 1278 #endif
uci1 84:80b15993944e 1279 */
uci1 84:80b15993944e 1280 #endif
uci1 84:80b15993944e 1281
uci1 84:80b15993944e 1282 // ok, now we can overwrite the old gEvent data
uci1 84:80b15993944e 1283 // reset event
uci1 84:80b15993944e 1284 gEvent.ClearEvent(true, true);
uci1 84:80b15993944e 1285
uci1 84:80b15993944e 1286 // read data & calc CRC
uci1 84:80b15993944e 1287 #ifdef EVT_TIME_PROFILE
uci1 84:80b15993944e 1288 int befReadWv=0, aftReadWv=0, befWriteEvt=0, aftWriteEvt=0;
uci1 84:80b15993944e 1289 gProfiler.stop(); befReadWv=gProfiler.read_us(); gProfiler.start();
uci1 84:80b15993944e 1290 #endif // EVT_TIME_PROFILE
uci1 84:80b15993944e 1291
uci1 84:80b15993944e 1292 #if CHIPBOARD==ATWD4CH
uci1 84:80b15993944e 1293 // get the data to the MBED
uci1 84:80b15993944e 1294 gEvent.ReadWaveformsATWD(PIN_spi, PIN_selCardHiBit, PIN_selCardLoBit);
uci1 84:80b15993944e 1295 #else
uci1 84:80b15993944e 1296 gEvent.ReadWaveformsSST(PIN_spi, PIN_readingData);
uci1 84:80b15993944e 1297 // reset in case a trigger arrived before we were ready
uci1 84:80b15993944e 1298 PIN_ResetChips = 1;
uci1 84:80b15993944e 1299 // wait_us(1);
uci1 84:80b15993944e 1300 PIN_ResetChips = 0;
uci1 84:80b15993944e 1301 #endif //ATWD4CH
uci1 84:80b15993944e 1302
uci1 84:80b15993944e 1303 #ifdef EVT_TIME_PROFILE
uci1 84:80b15993944e 1304 gProfiler.stop(); aftReadWv=gProfiler.read_us(); gProfiler.start();
uci1 84:80b15993944e 1305 #endif // EVT_TIME_PROFILE
uci1 84:80b15993944e 1306
uci1 84:80b15993944e 1307 gEvent.SetCurMbedTime();
uci1 84:80b15993944e 1308
uci1 84:80b15993944e 1309 Watchdog::kick(); // don't reset!
uci1 84:80b15993944e 1310
uci1 84:80b15993944e 1311 #ifdef DEBUG
uci1 84:80b15993944e 1312 printf("gFirstEvt=%s\r\n",gFirstEvt?"true":"false");
uci1 84:80b15993944e 1313 #endif
uci1 84:80b15993944e 1314
uci1 84:80b15993944e 1315 #if CHIPBOARD==ATWD4CH
uci1 84:80b15993944e 1316 PIN_lockRegisters = 0; // done reading, unlock so we can talk to the SD card
uci1 84:80b15993944e 1317 #else
uci1 84:80b15993944e 1318 // (this is redundant; it's already set low by SnEventFrame)
uci1 84:80b15993944e 1319 PIN_readingData = 0; // done reading, unlock so we can talk to the SD card
uci1 84:80b15993944e 1320 #endif // ATWD4CH
uci1 84:80b15993944e 1321
uci1 84:80b15993944e 1322 #ifdef DEBUG
uci1 84:80b15993944e 1323 printf("waveform read out. save event (%u)\r\n", gEvtNum);
uci1 12:d472f9811262 1324 #endif
uci1 3:24c5f0f50bf1 1325
uci1 0:664899e0b988 1326 // set the event number & dt
uci1 3:24c5f0f50bf1 1327 gEvent.SetEvtNum(gEvtNum);
uci1 0:664899e0b988 1328 gEvent.SetDTms(etms);
uci1 84:80b15993944e 1329 // set trigger bits
uci1 84:80b15993944e 1330 if (gForcedTrig) {
uci1 84:80b15993944e 1331 gEvent.SetTrgBit(kForced);
uci1 84:80b15993944e 1332 // gEvent.SetTrgNum(gTrgNum[kFrcTrg]);
uci1 84:80b15993944e 1333 gEvent.SetTrgNum(gNumFrcTrigs);
uci1 84:80b15993944e 1334 } else {
uci1 84:80b15993944e 1335 gEvent.SetTrgBit(kThermal);
uci1 84:80b15993944e 1336 // gEvent.SetTrgNum(gTrgNum[kThmTrg]);
uci1 84:80b15993944e 1337 gEvent.SetTrgNum(gNumThmTrigs);
uci1 84:80b15993944e 1338 }
uci1 84:80b15993944e 1339 if (gAdcToMBflag) {
uci1 84:80b15993944e 1340 gEvent.SetTrgBit(kAdcToMBflag);
uci1 84:80b15993944e 1341 }
uci1 0:664899e0b988 1342
uci1 84:80b15993944e 1343 // this is in the config too, but doesn't hurt to flip the bit
uci1 84:80b15993944e 1344 // in the event
uci1 84:80b15993944e 1345 if (gConf.IsL1TrigApplied()) {
uci1 84:80b15993944e 1346 gEvent.SetTrgBit(kL1TrgApplied);
uci1 84:80b15993944e 1347 }
uci1 84:80b15993944e 1348
uci1 84:80b15993944e 1349 // ----
uci1 84:80b15993944e 1350 // L1 check(s) go here!
uci1 84:80b15993944e 1351 bool L1okToSave = true;
uci1 84:80b15993944e 1352
uci1 84:80b15993944e 1353 #ifdef DEBUG
uci1 84:80b15993944e 1354 Timer l1timer;
uci1 84:80b15993944e 1355 l1timer.start();
uci1 84:80b15993944e 1356 printf("L1 single freq supp ratio = %hhu (%g)\r\n",
uci1 84:80b15993944e 1357 gConf.GetSingleFreqSuppRatioRaw(),
uci1 84:80b15993944e 1358 gConf.GetSingleFreqSuppRatio());
uci1 84:80b15993944e 1359 #endif
uci1 84:80b15993944e 1360
uci1 84:80b15993944e 1361 // TODO: move the FFT calculation out here so that
uci1 84:80b15993944e 1362 // other L1's could use it too. haven't done this already
uci1 84:80b15993944e 1363 // in order to save RAM and not cache the whole thing when
uci1 84:80b15993944e 1364 // we only have one L1 cut.
uci1 84:80b15993944e 1365
uci1 84:80b15993944e 1366 // check L1 single frequency suppression cut
uci1 84:80b15993944e 1367 if ( gConf.IsSingleFreqSuppEnabled() ) {
uci1 84:80b15993944e 1368 const EL1TrigStatus passL1SingleFreqSupp =
uci1 84:80b15993944e 1369 SnL1SingleFreqSupp::ProcessEvent(gEvent, gChanFFT,
uci1 84:80b15993944e 1370 gConf.GetSingleFreqSuppRatio());
uci1 84:80b15993944e 1371 #ifdef DEBUG
uci1 84:80b15993944e 1372 l1timer.stop();
uci1 84:80b15993944e 1373 printf("L1 single freq supp took [%d] us\r\n",
uci1 84:80b15993944e 1374 l1timer.read_us());
uci1 84:80b15993944e 1375 printf("passL1SingleFreqSupp=%s\r\n",
uci1 84:80b15993944e 1376 passL1SingleFreqSupp==kL1Pass ? "pass"
uci1 84:80b15993944e 1377 : passL1SingleFreqSupp==kL1Fail ? "fail"
uci1 84:80b15993944e 1378 : "other");
uci1 84:80b15993944e 1379 #endif
uci1 84:80b15993944e 1380 if (passL1SingleFreqSupp==kL1Pass) {
uci1 84:80b15993944e 1381 gEvent.SetTrgBit(kSingleFreqSupp);
uci1 84:80b15993944e 1382 } else if ( (passL1SingleFreqSupp==kL1Fail) &&
uci1 84:80b15993944e 1383 gConf.IsL1TrigApplied() ) {
uci1 84:80b15993944e 1384 L1okToSave = false;
uci1 84:80b15993944e 1385 }
uci1 84:80b15993944e 1386 // else if kL1UnableToProcess, the bit won't get set
uci1 84:80b15993944e 1387 // but the event can/will be saved
uci1 84:80b15993944e 1388 }
uci1 84:80b15993944e 1389
uci1 84:80b15993944e 1390
uci1 84:80b15993944e 1391 // NO MORE L1 checks below here! (or the scaledown won't work)
uci1 84:80b15993944e 1392 // -----
uci1 84:80b15993944e 1393
uci1 84:80b15993944e 1394 #ifdef EVT_TIME_PROFILE
uci1 84:80b15993944e 1395 gProfiler.stop(); befWriteEvt=gProfiler.read_us(); gProfiler.start();
uci1 84:80b15993944e 1396 #endif // EVT_TIME_PROFILE
uci1 84:80b15993944e 1397
uci1 0:664899e0b988 1398 // save to SD
uci1 56:0bba0ef15697 1399 #if CHIPBOARD==ATWD4CH
uci1 56:0bba0ef15697 1400 PIN_lockRegisters = 0; // unlock so we can talk to the SD card
uci1 56:0bba0ef15697 1401 #else
uci1 56:0bba0ef15697 1402 PIN_readingData = 0; // unlock so we can talk to the SD card
uci1 56:0bba0ef15697 1403 #endif
uci1 84:80b15993944e 1404
uci1 84:80b15993944e 1405 // scale down to override L1 trigger failures
uci1 84:80b15993944e 1406 if ( (L1okToSave==false) && (gConf.GetL1Scaledown()!=0) ) {
uci1 84:80b15993944e 1407 ++gL1ScaledownCount;
uci1 84:80b15993944e 1408
uci1 84:80b15993944e 1409 if ( gL1ScaledownCount == gConf.GetL1Scaledown() ) {
uci1 84:80b15993944e 1410 gL1ScaledownCount = 0;
uci1 84:80b15993944e 1411 L1okToSave = true;
uci1 84:80b15993944e 1412 #ifdef DEBUG
uci1 84:80b15993944e 1413 printf("))) L1 scaledown!\r\n");
uci1 84:80b15993944e 1414 #endif
uci1 84:80b15993944e 1415 }
uci1 84:80b15993944e 1416 }
uci1 84:80b15993944e 1417
uci1 84:80b15993944e 1418 #ifdef DEBUG
uci1 84:80b15993944e 1419 printf("L1 scaledown count = %hhu, scaledown=%hhu, L1okToSave=%s\r\n",
uci1 84:80b15993944e 1420 gL1ScaledownCount,
uci1 84:80b15993944e 1421 gConf.GetL1Scaledown(),
uci1 84:80b15993944e 1422 L1okToSave ? "true" : "false");
uci1 84:80b15993944e 1423 printf("event trigger bits = ");
uci1 84:80b15993944e 1424 SnBitUtils::printBits(gEvent.GetTrgBits(), true);
uci1 84:80b15993944e 1425 #endif
uci1 0:664899e0b988 1426
uci1 84:80b15993944e 1427 // always save forced triggers
uci1 84:80b15993944e 1428 if (L1okToSave || gForcedTrig) {
uci1 84:80b15993944e 1429 SnSDUtils::WriteEventTo(SnSDUtils::GetCurFile(), gGenBuf, gEvent, gConf);
uci1 84:80b15993944e 1430
uci1 84:80b15993944e 1431 // a good event
uci1 84:80b15993944e 1432 gStNewEvent = true;
uci1 84:80b15993944e 1433
uci1 84:80b15993944e 1434 // send it?
uci1 84:80b15993944e 1435 if ( gConf.IsCommWindowEachEvent() ) {
uci1 84:80b15993944e 1436 #ifdef DEBUG
uci1 84:80b15993944e 1437 printf("COMM EACH EVENT => gOpenCommWin = true\r\n");
uci1 84:80b15993944e 1438 #endif
uci1 84:80b15993944e 1439 gOpenCommWin = true;
uci1 84:80b15993944e 1440 }
uci1 84:80b15993944e 1441 }
uci1 84:80b15993944e 1442
uci1 84:80b15993944e 1443 #ifdef EVT_TIME_PROFILE
uci1 84:80b15993944e 1444 gProfiler.stop(); aftWriteEvt=gProfiler.read_us(); gProfiler.start();
uci1 84:80b15993944e 1445 printf("befReadWv=%d, aftReadWv=%d, befWriteEvt=%d, aftWriteEvt=%d\r\n",
uci1 84:80b15993944e 1446 befReadWv, aftReadWv, befWriteEvt, aftWriteEvt);
uci1 84:80b15993944e 1447 #endif // EVT_TIME_PROFILE
uci1 84:80b15993944e 1448
uci1 40:1324da35afd4 1449 // make a copy in case we need to send it with the status
uci1 40:1324da35afd4 1450 // (copy it because we are going to clear this event while
uci1 40:1324da35afd4 1451 // waiting for the next trigger)
uci1 84:80b15993944e 1452 // gEvent.CopyTo(gLastEvent);
uci1 40:1324da35afd4 1453
uci1 3:24c5f0f50bf1 1454 // increment event number
uci1 3:24c5f0f50bf1 1455 ++gEvtNum;
uci1 3:24c5f0f50bf1 1456
uci1 12:d472f9811262 1457 #ifdef DEBUG
uci1 84:80b15993944e 1458 printf("next gEvtNum=%u\r\n",gEvtNum);
uci1 12:d472f9811262 1459 #endif
uci1 3:24c5f0f50bf1 1460 }
uci1 3:24c5f0f50bf1 1461
uci1 3:24c5f0f50bf1 1462 void MakeOutputFile(const bool stopRunning) {
uci1 56:0bba0ef15697 1463 #if CHIPBOARD==ATWD4CH
uci1 56:0bba0ef15697 1464 PIN_lockRegisters = 0; // unlock so we can talk to the SD card
uci1 56:0bba0ef15697 1465 #else
uci1 56:0bba0ef15697 1466 PIN_readingData = 0; // unlock so we can talk to the SD card
uci1 56:0bba0ef15697 1467 #endif
uci1 12:d472f9811262 1468 #ifdef DEBUG
uci1 10:3c93db1cfb12 1469 printf("closing output file. gEvtNum=%u, gPowNum=%u, stop=%d\r\n",
uci1 10:3c93db1cfb12 1470 gEvtNum,gPowNum,(int)stopRunning);
uci1 12:d472f9811262 1471 #endif
uci1 13:7a1fb885a8e4 1472
uci1 3:24c5f0f50bf1 1473 SnSDUtils::CloseOutputFile(SnSDUtils::GetCurFile());
uci1 13:7a1fb885a8e4 1474
uci1 12:d472f9811262 1475 #ifdef DEBUG
uci1 10:3c93db1cfb12 1476 printf("file closed\r\n");
uci1 12:d472f9811262 1477 #endif
uci1 3:24c5f0f50bf1 1478 if (stopRunning) {
uci1 8:95a325df1f6b 1479 StopRunning();
uci1 0:664899e0b988 1480 }
uci1 56:0bba0ef15697 1481 FILE* cf = SnSDUtils::OpenNewOutputFile(SnConfigFrame::GetMacAddress(),
uci1 40:1324da35afd4 1482 gConf.GetRun(),
uci1 76:f8383f0292c2 1483 gConf.GetFirstSeq(),
uci1 76:f8383f0292c2 1484 gConf.IsSendingFilesRunSeqList());
uci1 13:7a1fb885a8e4 1485 // reset event, timers, trigger counters
uci1 84:80b15993944e 1486 ResetCounters();
uci1 8:95a325df1f6b 1487 if (cf!=0) {
uci1 40:1324da35afd4 1488 #ifdef USE_RTOS
uci1 40:1324da35afd4 1489 Thread::wait(200);
uci1 40:1324da35afd4 1490 #else
uci1 8:95a325df1f6b 1491 wait_ms(200);
uci1 40:1324da35afd4 1492 #endif
uci1 8:95a325df1f6b 1493 GetAvePowerReading();
uci1 12:d472f9811262 1494 #ifdef DEBUG
uci1 8:95a325df1f6b 1495 printf("writing power. v1=%g, v2=%g, r1=%g, r2=%g, t=%u, pownum=%u\r\n",
uci1 8:95a325df1f6b 1496 gPower.GetAveV1(), gPower.GetAveV2(),
uci1 8:95a325df1f6b 1497 gPower.GetRmsV1(), gPower.GetRmsV2(), gPower.GetTime(),
uci1 8:95a325df1f6b 1498 gPowNum);
uci1 12:d472f9811262 1499 #endif
uci1 8:95a325df1f6b 1500 SnSDUtils::WritePowerTo(cf, gPower, gPowNum);
uci1 8:95a325df1f6b 1501 }
uci1 12:d472f9811262 1502 #ifdef DEBUG
uci1 3:24c5f0f50bf1 1503 printf("made output file with run %u\r\n",gConf.GetRun());
uci1 3:24c5f0f50bf1 1504 printf("filename=%s\r\n",SnSDUtils::GetCurFileName());
uci1 12:d472f9811262 1505 #endif
uci1 3:24c5f0f50bf1 1506 SnSDUtils::WriteConfig(SnSDUtils::GetCurFile(), gConf);
uci1 19:74155d652c37 1507 #ifdef DEBUG
uci1 19:74155d652c37 1508 printf("write config to file\r\n");
uci1 19:74155d652c37 1509 #endif
uci1 0:664899e0b988 1510 }
uci1 0:664899e0b988 1511
uci1 40:1324da35afd4 1512 bool PowerDownCommPeriph(const SnConfigFrame::EDatPackBit type) {
uci1 67:ec999336fcd1 1513 #ifdef DEBUG
uci1 67:ec999336fcd1 1514 printf("PowerDownCommPeriph: type=%d\r\n",(int)type);
uci1 67:ec999336fcd1 1515 #endif
uci1 40:1324da35afd4 1516 SnCommWin** cw = gComms;
uci1 56:0bba0ef15697 1517 for (uint8_t i=0; i<kNcomms; ++i, ++cw) {
uci1 40:1324da35afd4 1518 if ((*cw)==0) {
uci1 40:1324da35afd4 1519 continue;
uci1 40:1324da35afd4 1520 } else if ((*cw)->GetCommType()==type) {
uci1 67:ec999336fcd1 1521 #ifdef DEBUG
uci1 67:ec999336fcd1 1522 printf("calling PowerDown\r\n");
uci1 67:ec999336fcd1 1523 #endif
uci1 40:1324da35afd4 1524 return (*cw)->PowerDown(gConf.GetTimeoutTime(time(0),
uci1 84:80b15993944e 1525 gConf.GetCommWinConnectTO(type)));
uci1 40:1324da35afd4 1526 }
uci1 40:1324da35afd4 1527 }
uci1 40:1324da35afd4 1528 return false;
uci1 40:1324da35afd4 1529 }
uci1 40:1324da35afd4 1530
uci1 0:664899e0b988 1531 //
uci1 4:a91682e19d6b 1532 // power stuff
uci1 4:a91682e19d6b 1533 //
uci1 67:ec999336fcd1 1534 bool IsCurrentlyPowered(const SnConfigFrame::EPowerModeBit p,
uci1 67:ec999336fcd1 1535 DigitalOut& pin) {
uci1 67:ec999336fcd1 1536 // check if the current pin value is equal to
uci1 67:ec999336fcd1 1537 // what it should be if the peripheral is on
uci1 67:ec999336fcd1 1538 return gConf.GetPowPinSetting(p, true) == pin.read();
uci1 67:ec999336fcd1 1539 }
uci1 67:ec999336fcd1 1540
uci1 84:80b15993944e 1541 void ChangeCardPower(const bool isCommWin,
uci1 84:80b15993944e 1542 const bool isOn) {
uci1 67:ec999336fcd1 1543 // change cards power
uci1 67:ec999336fcd1 1544 const SnConfigFrame::EPowerModeBit pbit = (isCommWin)
uci1 67:ec999336fcd1 1545 ? SnConfigFrame::kCardComWin
uci1 67:ec999336fcd1 1546 : SnConfigFrame::kCardDatTak;
uci1 84:80b15993944e 1547 const int value = gConf.GetPowPinSetting(pbit, isOn);
uci1 21:ce51bb0ba4a5 1548 #ifdef DEBUG
uci1 67:ec999336fcd1 1549 printf("setting cards pin power to %d (comm=%d)\r\n",
uci1 67:ec999336fcd1 1550 value, static_cast<int>(isCommWin));
uci1 21:ce51bb0ba4a5 1551 #endif
uci1 67:ec999336fcd1 1552 PIN_turn_on_system = value;
uci1 40:1324da35afd4 1553 #ifdef USE_RTOS
uci1 40:1324da35afd4 1554 Thread::wait(10);
uci1 40:1324da35afd4 1555 #else
uci1 30:f869ed4bcc08 1556 wait_ms(10);
uci1 40:1324da35afd4 1557 #endif
uci1 67:ec999336fcd1 1558 }
uci1 67:ec999336fcd1 1559
uci1 84:80b15993944e 1560 void ChangeAmpsPower(const bool isCommWin,
uci1 84:80b15993944e 1561 const bool isOn) {
uci1 40:1324da35afd4 1562 // change amps power
uci1 67:ec999336fcd1 1563 const SnConfigFrame::EPowerModeBit pbit = (isCommWin)
uci1 67:ec999336fcd1 1564 ? SnConfigFrame::kAmpsComWin
uci1 67:ec999336fcd1 1565 : SnConfigFrame::kAmpsDatTak;
uci1 84:80b15993944e 1566 const int value = gConf.GetPowPinSetting(pbit, isOn);
uci1 40:1324da35afd4 1567 #ifdef DEBUG
uci1 67:ec999336fcd1 1568 printf("setting amps pin power to %d (comm=%d)\r\n",
uci1 67:ec999336fcd1 1569 value, static_cast<int>(isCommWin));
uci1 40:1324da35afd4 1570 #endif
uci1 67:ec999336fcd1 1571 PIN_turn_on_amps = value;
uci1 40:1324da35afd4 1572 #ifdef USE_RTOS
uci1 40:1324da35afd4 1573 Thread::wait(10);
uci1 40:1324da35afd4 1574 #else
uci1 30:f869ed4bcc08 1575 wait_ms(10);
uci1 40:1324da35afd4 1576 #endif
uci1 67:ec999336fcd1 1577 }
uci1 67:ec999336fcd1 1578
uci1 84:80b15993944e 1579 void ChangeIridPower(const bool isCommWin,
uci1 84:80b15993944e 1580 const bool isOn) {
uci1 67:ec999336fcd1 1581 // change iridium power setting
uci1 67:ec999336fcd1 1582 // if going from ON to OFF, call the special
uci1 67:ec999336fcd1 1583 // power down procedure, so as not to lose
uci1 67:ec999336fcd1 1584 // the non-volatile memory settings
uci1 67:ec999336fcd1 1585
uci1 67:ec999336fcd1 1586 const SnConfigFrame::EPowerModeBit ibit = (isCommWin)
uci1 67:ec999336fcd1 1587 ? SnConfigFrame::kIridComWin
uci1 67:ec999336fcd1 1588 : SnConfigFrame::kIridDatTak;
uci1 67:ec999336fcd1 1589 const SnConfigFrame::EPowerModeBit abit = (isCommWin)
uci1 67:ec999336fcd1 1590 ? SnConfigFrame::kAfarComWin
uci1 67:ec999336fcd1 1591 : SnConfigFrame::kAfarDatTak;
uci1 67:ec999336fcd1 1592
uci1 67:ec999336fcd1 1593 // these checks are complicated because the iridium might
uci1 67:ec999336fcd1 1594 // be powered off the Afar (12V) relay,
uci1 67:ec999336fcd1 1595 // rather than the iridium (5V) relay
uci1 67:ec999336fcd1 1596 const bool iridFromOn = (kIridPwrFromAfar) ?
uci1 67:ec999336fcd1 1597 IsCurrentlyPowered(abit, PIN_afar_power) :
uci1 67:ec999336fcd1 1598 IsCurrentlyPowered(ibit, PIN_iridSbd_power);
uci1 84:80b15993944e 1599 if ( iridFromOn && (isOn==false) ) {
uci1 40:1324da35afd4 1600 #ifdef DEBUG
uci1 40:1324da35afd4 1601 printf("calling PowerDown for Iridium\r\n");
uci1 40:1324da35afd4 1602 #endif
uci1 40:1324da35afd4 1603 PowerDownCommPeriph(SnConfigFrame::kIrid);
uci1 40:1324da35afd4 1604 }
uci1 67:ec999336fcd1 1605 const int value = (kIridPwrFromAfar)
uci1 67:ec999336fcd1 1606 ? gConf.GetPowPinSetting(ibit, false) // leave the iridium relay off. use afar relay.
uci1 84:80b15993944e 1607 : gConf.GetPowPinSetting(ibit, isOn);
uci1 40:1324da35afd4 1608 #ifdef DEBUG
uci1 67:ec999336fcd1 1609 printf("setting iridium pin power to %d (comm=%d)\r\n",
uci1 67:ec999336fcd1 1610 value, static_cast<int>(isCommWin));
uci1 40:1324da35afd4 1611 #endif
uci1 67:ec999336fcd1 1612 PIN_iridSbd_power = value;
uci1 40:1324da35afd4 1613 #ifdef USE_RTOS
uci1 40:1324da35afd4 1614 Thread::wait(10);
uci1 40:1324da35afd4 1615 #else
uci1 30:f869ed4bcc08 1616 wait_ms(10);
uci1 40:1324da35afd4 1617 #endif
uci1 67:ec999336fcd1 1618
uci1 67:ec999336fcd1 1619 }
uci1 67:ec999336fcd1 1620
uci1 84:80b15993944e 1621 void ChangeAfarPower(const bool isCommWin,
uci1 84:80b15993944e 1622 const bool isOn) {
uci1 67:ec999336fcd1 1623 // change the AFAR relay power setting
uci1 67:ec999336fcd1 1624 // also power up or down the ethernet PHY port
uci1 67:ec999336fcd1 1625 // as appropriate
uci1 67:ec999336fcd1 1626 // the procedure is complicated by the fact that
uci1 67:ec999336fcd1 1627 // the iridium may be powered off the Afar (12V) relay,
uci1 67:ec999336fcd1 1628 // in which case we need to turn this relay on if
uci1 67:ec999336fcd1 1629 // *either* Afar or iridium want power
uci1 67:ec999336fcd1 1630 #ifdef DEBUG
uci1 67:ec999336fcd1 1631 printf("bef: pconp=%u (%08x), pcenet=%u (%08x)\r\n",
uci1 67:ec999336fcd1 1632 LPC_SC->PCONP, LPC_SC->PCONP, LPC1768_PCONP_PCENET, LPC1768_PCONP_PCENET);
uci1 67:ec999336fcd1 1633 printf("pcenet bef power: status=%d\r\n",Peripheral_GetStatus(LPC1768_PCONP_PCENET));
uci1 67:ec999336fcd1 1634 #endif
uci1 67:ec999336fcd1 1635
uci1 67:ec999336fcd1 1636 const SnConfigFrame::EPowerModeBit abit = (isCommWin)
uci1 67:ec999336fcd1 1637 ? SnConfigFrame::kAfarComWin
uci1 67:ec999336fcd1 1638 : SnConfigFrame::kAfarDatTak;
uci1 67:ec999336fcd1 1639
uci1 67:ec999336fcd1 1640 const bool afarFromOn = IsCurrentlyPowered(abit, PIN_afar_power);
uci1 67:ec999336fcd1 1641
uci1 40:1324da35afd4 1642 // change ethernet PHY port power
uci1 21:ce51bb0ba4a5 1643 #ifdef DEBUG
uci1 67:ec999336fcd1 1644 printf("afar pin=%d, afarFromOn=%d, afarToOn=%d\r\n",
uci1 67:ec999336fcd1 1645 PIN_afar_power.read(), static_cast<int>(afarFromOn),
uci1 84:80b15993944e 1646 static_cast<int>(isOn));
uci1 21:ce51bb0ba4a5 1647 #endif
uci1 84:80b15993944e 1648 if (isOn) {
uci1 21:ce51bb0ba4a5 1649 #ifdef DEBUG
uci1 30:f869ed4bcc08 1650 printf("PHY cowin powering up\r\n");
uci1 21:ce51bb0ba4a5 1651 #endif
uci1 40:1324da35afd4 1652 PHY_PowerUp();
uci1 40:1324da35afd4 1653 #ifdef USE_RTOS
uci1 40:1324da35afd4 1654 Thread::wait(1000);
uci1 40:1324da35afd4 1655 #else
uci1 40:1324da35afd4 1656 wait(1);
uci1 40:1324da35afd4 1657 #endif
uci1 21:ce51bb0ba4a5 1658 #ifdef DEBUG
uci1 30:f869ed4bcc08 1659 printf("PHY cowin powered up\r\n");
uci1 21:ce51bb0ba4a5 1660 #endif
uci1 4:a91682e19d6b 1661 } else {
uci1 40:1324da35afd4 1662 // change afar power
uci1 40:1324da35afd4 1663 // power down periph if going from on to off
uci1 40:1324da35afd4 1664 // change afar power
uci1 40:1324da35afd4 1665 if (afarFromOn) {
uci1 40:1324da35afd4 1666 PowerDownCommPeriph(SnConfigFrame::kAfar);
uci1 40:1324da35afd4 1667 }
uci1 21:ce51bb0ba4a5 1668 #ifdef DEBUG
uci1 30:f869ed4bcc08 1669 printf("PHY cowin powering down\r\n");
uci1 21:ce51bb0ba4a5 1670 #endif
uci1 40:1324da35afd4 1671 PHY_PowerDown();
uci1 40:1324da35afd4 1672 #ifdef USE_RTOS
uci1 40:1324da35afd4 1673 Thread::wait(1000);
uci1 40:1324da35afd4 1674 #else
uci1 40:1324da35afd4 1675 wait(1);
uci1 40:1324da35afd4 1676 #endif
uci1 21:ce51bb0ba4a5 1677 #ifdef DEBUG
uci1 30:f869ed4bcc08 1678 printf("PHY cowin powered down\r\n");
uci1 21:ce51bb0ba4a5 1679 #endif
uci1 30:f869ed4bcc08 1680 }
uci1 21:ce51bb0ba4a5 1681 #ifdef DEBUG
uci1 30:f869ed4bcc08 1682 printf("PHY done\r\n");
uci1 21:ce51bb0ba4a5 1683 #endif
uci1 40:1324da35afd4 1684 #ifdef USE_RTOS
uci1 40:1324da35afd4 1685 Thread::wait(100);
uci1 40:1324da35afd4 1686 #else
uci1 30:f869ed4bcc08 1687 wait_ms(100);
uci1 40:1324da35afd4 1688 #endif
uci1 67:ec999336fcd1 1689
uci1 40:1324da35afd4 1690 // change afar power
uci1 84:80b15993944e 1691 const int value = gConf.GetPowPinSetting(abit, isOn);
uci1 67:ec999336fcd1 1692 PIN_afar_power = value;
uci1 40:1324da35afd4 1693 #ifdef USE_RTOS
uci1 40:1324da35afd4 1694 Thread::wait(1500);
uci1 40:1324da35afd4 1695 #else
uci1 40:1324da35afd4 1696 wait(1.5);
uci1 40:1324da35afd4 1697 #endif
uci1 12:d472f9811262 1698 #ifdef DEBUG
uci1 21:ce51bb0ba4a5 1699 printf("aft: pconp=%u (%08x), pcenet=%u (%08x)\r\n",
uci1 21:ce51bb0ba4a5 1700 LPC_SC->PCONP, LPC_SC->PCONP, LPC1768_PCONP_PCENET, LPC1768_PCONP_PCENET);
uci1 67:ec999336fcd1 1701 printf("pcenet aft power: status=%d\r\n",Peripheral_GetStatus(LPC1768_PCONP_PCENET));
uci1 21:ce51bb0ba4a5 1702 #endif
uci1 67:ec999336fcd1 1703
uci1 67:ec999336fcd1 1704 }
uci1 67:ec999336fcd1 1705
uci1 84:80b15993944e 1706 bool IsPowerAllowedFor(const bool isCommWin,
uci1 84:80b15993944e 1707 const uint8_t devicesInUse,
uci1 84:80b15993944e 1708 const SnConfigFrame::EDatPackBit b) {
uci1 84:80b15993944e 1709 if (isCommWin && (gConf.IsCommPowerSimple()==false)) {
uci1 84:80b15993944e 1710 return ( (devicesInUse & b)!=0 );
uci1 84:80b15993944e 1711 }
uci1 84:80b15993944e 1712 return true;
uci1 84:80b15993944e 1713 }
uci1 84:80b15993944e 1714
uci1 84:80b15993944e 1715 void SetPower(const bool isCommWin,
uci1 84:80b15993944e 1716 const uint8_t devicesInUse) {
uci1 84:80b15993944e 1717 // devicesInUse could really just be a second set of "power mode" bits
uci1 84:80b15993944e 1718 // where the bit being on means "I want to change power for this device"
uci1 84:80b15993944e 1719 // but then.. how to handle the possibility that the bit word contains,
uci1 84:80b15993944e 1720 // for example, both bits AfarDatTak and AfarComWin being on?
uci1 84:80b15993944e 1721 // so instead, we keep the "isCommWin" boolean which forces the separation
uci1 84:80b15993944e 1722 // and deviceInUse is only applied when isCommWin==true
uci1 84:80b15993944e 1723 //
uci1 84:80b15993944e 1724 // multiple devices can be specified by, e.g., kIrid | kAfar
uci1 67:ec999336fcd1 1725 #ifdef DEBUG
uci1 67:ec999336fcd1 1726 printf("set power. isCommWin=%s\r\n",(isCommWin)?"true":"false");
uci1 67:ec999336fcd1 1727 printf("WD reset = %d\r\n",(int)Watchdog::didWatchdogReset());
uci1 67:ec999336fcd1 1728 printf("power word (%hhu): ",gConf.GetPowerMode()); SnBitUtils::printBits(gConf.GetPowerMode(),true);
uci1 67:ec999336fcd1 1729 printf("IsPoweredFor CardDatTak = %d\r\n",(int)gConf.IsPoweredFor(SnConfigFrame::kCardDatTak));
uci1 67:ec999336fcd1 1730 printf("IsPoweredFor AmpsDatTak = %d\r\n",(int)gConf.IsPoweredFor(SnConfigFrame::kAmpsDatTak));
uci1 67:ec999336fcd1 1731 printf("IsPoweredFor IridDatTak = %d\r\n",(int)gConf.IsPoweredFor(SnConfigFrame::kIridDatTak));
uci1 67:ec999336fcd1 1732 printf("IsPoweredFor AfarDatTak = %d\r\n",(int)gConf.IsPoweredFor(SnConfigFrame::kAfarDatTak));
uci1 67:ec999336fcd1 1733 printf("IsPoweredFor CardComWin = %d\r\n",(int)gConf.IsPoweredFor(SnConfigFrame::kCardComWin));
uci1 67:ec999336fcd1 1734 printf("IsPoweredFor AmpsComWin = %d\r\n",(int)gConf.IsPoweredFor(SnConfigFrame::kAmpsComWin));
uci1 67:ec999336fcd1 1735 printf("IsPoweredFor IridComWin = %d\r\n",(int)gConf.IsPoweredFor(SnConfigFrame::kIridComWin));
uci1 67:ec999336fcd1 1736 printf("IsPoweredFor AfarComWin = %d\r\n",(int)gConf.IsPoweredFor(SnConfigFrame::kAfarComWin));
uci1 84:80b15993944e 1737 printf("devicesInUse = %hhu\r\n", (uint8_t)devicesInUse);
uci1 84:80b15993944e 1738 printf("IsCommPowerSimple = %s\r\n", (gConf.IsCommPowerSimple() ? "true" : "false"));
uci1 67:ec999336fcd1 1739 #endif
uci1 67:ec999336fcd1 1740
uci1 67:ec999336fcd1 1741 const SnConfigFrame::EPowerModeBit cardpb = (isCommWin)
uci1 67:ec999336fcd1 1742 ? SnConfigFrame::kCardComWin
uci1 67:ec999336fcd1 1743 : SnConfigFrame::kCardDatTak;
uci1 67:ec999336fcd1 1744 const SnConfigFrame::EPowerModeBit ampspb = (isCommWin)
uci1 67:ec999336fcd1 1745 ? SnConfigFrame::kAmpsComWin
uci1 67:ec999336fcd1 1746 : SnConfigFrame::kAmpsDatTak;
uci1 67:ec999336fcd1 1747 const SnConfigFrame::EPowerModeBit iridpb = (isCommWin)
uci1 67:ec999336fcd1 1748 ? SnConfigFrame::kIridComWin
uci1 67:ec999336fcd1 1749 : SnConfigFrame::kIridDatTak;
uci1 67:ec999336fcd1 1750 const SnConfigFrame::EPowerModeBit afarpb = (isCommWin)
uci1 67:ec999336fcd1 1751 ? SnConfigFrame::kAfarComWin
uci1 67:ec999336fcd1 1752 : SnConfigFrame::kAfarDatTak;
uci1 67:ec999336fcd1 1753
uci1 67:ec999336fcd1 1754 //
uci1 67:ec999336fcd1 1755 // FIRST turn the things off that should be off.
uci1 67:ec999336fcd1 1756 // this prevents short periods of high power usage
uci1 67:ec999336fcd1 1757 //
uci1 67:ec999336fcd1 1758
uci1 84:80b15993944e 1759 const bool cardToOn = gConf.IsPoweredFor(cardpb);
uci1 84:80b15993944e 1760 const bool ampsToOn = gConf.IsPoweredFor(ampspb);
uci1 84:80b15993944e 1761
uci1 84:80b15993944e 1762 // these are complicated because iridium might
uci1 67:ec999336fcd1 1763 // be powered off of the afar line
uci1 84:80b15993944e 1764 // also ignore the devices in use if we're not in a comm window
uci1 67:ec999336fcd1 1765 const bool iridToOn = (kIridPwrFromAfar) ?
uci1 84:80b15993944e 1766 (gConf.IsPoweredFor(afarpb) && IsPowerAllowedFor(isCommWin, devicesInUse, SnConfigFrame::kIrid)) :
uci1 84:80b15993944e 1767 (gConf.IsPoweredFor(iridpb) && IsPowerAllowedFor(isCommWin, devicesInUse, SnConfigFrame::kIrid));
uci1 84:80b15993944e 1768 const bool afarToOn = (kIridPwrFromAfar) ?
uci1 84:80b15993944e 1769 ( (gConf.IsPoweredFor(afarpb) && IsPowerAllowedFor(isCommWin, devicesInUse, SnConfigFrame::kAfar))
uci1 84:80b15993944e 1770 ||(gConf.IsPoweredFor(iridpb) && IsPowerAllowedFor(isCommWin, devicesInUse, SnConfigFrame::kIrid)) ) :
uci1 84:80b15993944e 1771 (gConf.IsPoweredFor(afarpb) && IsPowerAllowedFor(isCommWin, devicesInUse, SnConfigFrame::kAfar));
uci1 67:ec999336fcd1 1772
uci1 84:80b15993944e 1773 if (cardToOn==false) {
uci1 67:ec999336fcd1 1774 #ifdef DEBUG
uci1 67:ec999336fcd1 1775 printf("power down cards\r\n");
uci1 67:ec999336fcd1 1776 #endif
uci1 84:80b15993944e 1777 ChangeCardPower(isCommWin, cardToOn);
uci1 67:ec999336fcd1 1778 }
uci1 84:80b15993944e 1779 if (ampsToOn==false) {
uci1 67:ec999336fcd1 1780 #ifdef DEBUG
uci1 67:ec999336fcd1 1781 printf("power down amps\r\n");
uci1 67:ec999336fcd1 1782 printf("ampspb=%d, is powered for =%d\r\n",
uci1 67:ec999336fcd1 1783 (int)ampspb,
uci1 67:ec999336fcd1 1784 (int)(gConf.IsPoweredFor(ampspb)));
uci1 67:ec999336fcd1 1785 printf("is powered amps dat tak = %d, amps com win = %d\r\n",
uci1 67:ec999336fcd1 1786 (int)(gConf.IsPoweredFor(SnConfigFrame::kAmpsDatTak)),
uci1 67:ec999336fcd1 1787 (int)(gConf.IsPoweredFor(SnConfigFrame::kAmpsComWin)));
uci1 67:ec999336fcd1 1788 #endif
uci1 84:80b15993944e 1789 ChangeAmpsPower(isCommWin, ampsToOn);
uci1 67:ec999336fcd1 1790 }
uci1 67:ec999336fcd1 1791 if (iridToOn==false) {
uci1 67:ec999336fcd1 1792 #ifdef DEBUG
uci1 67:ec999336fcd1 1793 printf("power down irid\r\n");
uci1 67:ec999336fcd1 1794 #endif
uci1 84:80b15993944e 1795 ChangeIridPower(isCommWin, iridToOn);
uci1 67:ec999336fcd1 1796 }
uci1 67:ec999336fcd1 1797 if (afarToOn==false) {
uci1 67:ec999336fcd1 1798 #ifdef DEBUG
uci1 67:ec999336fcd1 1799 printf("power down afar\r\n");
uci1 67:ec999336fcd1 1800 #endif
uci1 84:80b15993944e 1801 ChangeAfarPower(isCommWin, afarToOn);
uci1 67:ec999336fcd1 1802 }
uci1 67:ec999336fcd1 1803
uci1 67:ec999336fcd1 1804 //
uci1 67:ec999336fcd1 1805 // THEN turn on things that want to go on
uci1 67:ec999336fcd1 1806 //
uci1 84:80b15993944e 1807 if (cardToOn) {
uci1 67:ec999336fcd1 1808 #ifdef DEBUG
uci1 67:ec999336fcd1 1809 printf("power ON cards\r\n");
uci1 67:ec999336fcd1 1810 #endif
uci1 84:80b15993944e 1811 ChangeCardPower(isCommWin, cardToOn);
uci1 67:ec999336fcd1 1812 }
uci1 84:80b15993944e 1813 if (ampsToOn) {
uci1 67:ec999336fcd1 1814 #ifdef DEBUG
uci1 67:ec999336fcd1 1815 printf("power ON amps\r\n");
uci1 67:ec999336fcd1 1816 #endif
uci1 84:80b15993944e 1817 ChangeAmpsPower(isCommWin, ampsToOn);
uci1 67:ec999336fcd1 1818 }
uci1 67:ec999336fcd1 1819 if (iridToOn) {
uci1 67:ec999336fcd1 1820 #ifdef DEBUG
uci1 67:ec999336fcd1 1821 printf("power ON iridium\r\n");
uci1 67:ec999336fcd1 1822 #endif
uci1 84:80b15993944e 1823 ChangeIridPower(isCommWin, iridToOn);
uci1 67:ec999336fcd1 1824 }
uci1 67:ec999336fcd1 1825 if (afarToOn) {
uci1 67:ec999336fcd1 1826 #ifdef DEBUG
uci1 67:ec999336fcd1 1827 printf("power ON afar\r\n");
uci1 67:ec999336fcd1 1828 #endif
uci1 84:80b15993944e 1829 ChangeAfarPower(isCommWin, afarToOn);
uci1 67:ec999336fcd1 1830 }
uci1 67:ec999336fcd1 1831
uci1 21:ce51bb0ba4a5 1832 #ifdef DEBUG
uci1 16:744ce85aede2 1833 printf("power word (%hhu): ",gConf.GetPowerMode()); SnBitUtils::printBits(gConf.GetPowerMode(),true);
uci1 6:6f002d202f59 1834 printf("set power (iscom %d, pw %hhu): cards %d, amps %d, irid %d, afar %d\r\n",
uci1 6:6f002d202f59 1835 isCommWin, gConf.GetPowerMode(), PIN_turn_on_system.read(), PIN_turn_on_amps.read(),
uci1 6:6f002d202f59 1836 PIN_iridSbd_power.read(), PIN_afar_power.read());
uci1 12:d472f9811262 1837 #endif
uci1 4:a91682e19d6b 1838 }
uci1 4:a91682e19d6b 1839
uci1 4:a91682e19d6b 1840 //
uci1 0:664899e0b988 1841 // set configuration
uci1 0:664899e0b988 1842 //
uci1 1:e392595b4b76 1843 void SetConfigAndMakeOutputFile() {
uci1 12:d472f9811262 1844 #ifdef DEBUG
uci1 1:e392595b4b76 1845 printf("SetConfigAndMakeOutputFile\r\n");
uci1 12:d472f9811262 1846 #endif
uci1 1:e392595b4b76 1847
uci1 0:664899e0b988 1848 // restart watchdog
uci1 62:4b59c1eb429f 1849 #ifdef DEBUG
uci1 62:4b59c1eb429f 1850 printf("Restart watchdog with time [%u]\r\n",
uci1 62:4b59c1eb429f 1851 gConf.GetWatchdogPeriod());
uci1 62:4b59c1eb429f 1852 #endif
uci1 0:664899e0b988 1853 Watchdog::kick(gConf.GetWatchdogPeriod());
uci1 0:664899e0b988 1854
uci1 1:e392595b4b76 1855 // block (thermal) triggers during configuration
uci1 1:e392595b4b76 1856 PIN_enableThermTrig = 0;
uci1 56:0bba0ef15697 1857 #if CHIPBOARD==ATWD4CH
uci1 1:e392595b4b76 1858 PIN_ADC_CS = 1;
uci1 1:e392595b4b76 1859 PIN_DoNotRestartAllClocks = 1;
uci1 56:0bba0ef15697 1860 #endif
uci1 1:e392595b4b76 1861 PIN_forceTrigger = 0;
uci1 3:24c5f0f50bf1 1862 PIN_heartbeat = 0;
uci1 40:1324da35afd4 1863 #ifdef USE_RTOS
uci1 40:1324da35afd4 1864 Thread::wait(20);
uci1 40:1324da35afd4 1865 #else
uci1 1:e392595b4b76 1866 wait_ms(20);
uci1 40:1324da35afd4 1867 #endif
uci1 1:e392595b4b76 1868
uci1 22:f957c4f840ad 1869 gCommWinChecks = 0;
uci1 22:f957c4f840ad 1870 gNcommWinChecks = gConf.GetCommWinPeriod() / kCommWinLongPrdTk;
uci1 22:f957c4f840ad 1871
uci1 21:ce51bb0ba4a5 1872 if (AreCardsPowered(true)) {
uci1 8:95a325df1f6b 1873 // Set PLA value(s)
uci1 56:0bba0ef15697 1874 PIN_spi.format( 16, 0 ); // change mode for DAC & PLA value setting (with ATWD4CH)
uci1 8:95a325df1f6b 1875 PIN_spi.frequency(1000000);
uci1 8:95a325df1f6b 1876 PIN_MajLogHiBit=1;
uci1 8:95a325df1f6b 1877 PIN_MajLogLoBit=1;
uci1 8:95a325df1f6b 1878 PIN_enableThermTrig=0;
uci1 0:664899e0b988 1879
uci1 56:0bba0ef15697 1880 #if CHIPBOARD==ATWD4CH
uci1 8:95a325df1f6b 1881 uint16_t hi, lo;
uci1 8:95a325df1f6b 1882 PIN_PLA_cs=1;
uci1 40:1324da35afd4 1883 #ifdef USE_RTOS
uci1 40:1324da35afd4 1884 Thread::wait(4000);
uci1 40:1324da35afd4 1885 #else
uci1 8:95a325df1f6b 1886 wait(4);
uci1 40:1324da35afd4 1887 #endif
uci1 56:0bba0ef15697 1888 for (uint8_t pi=0; pi<kNplas; ++pi) {
uci1 8:95a325df1f6b 1889 if (pi < gConf.GetNumPlas()) {
uci1 8:95a325df1f6b 1890 SnConfigFrame::GetHiLoPlas(gConf.GetPla(pi), hi, lo);
uci1 8:95a325df1f6b 1891 PIN_spi.write(hi);
uci1 8:95a325df1f6b 1892 PIN_spi.write(lo);
uci1 12:d472f9811262 1893 #ifdef DEBUG
uci1 8:95a325df1f6b 1894 printf("pla hi %hu, lo %hu\r\n",hi,lo);
uci1 12:d472f9811262 1895 #endif
uci1 8:95a325df1f6b 1896 } else {
uci1 8:95a325df1f6b 1897 PIN_spi.write(kNoTrigPla); // hi
uci1 8:95a325df1f6b 1898 PIN_spi.write(kNoTrigPla); // lo
uci1 12:d472f9811262 1899 #ifdef DEBUG
uci1 8:95a325df1f6b 1900 printf("pla hi %hu, lo %hu\r\n",kNoTrigPla,kNoTrigPla);
uci1 12:d472f9811262 1901 #endif
uci1 8:95a325df1f6b 1902 }
uci1 8:95a325df1f6b 1903 Watchdog::kick();
uci1 0:664899e0b988 1904 }
uci1 40:1324da35afd4 1905 #ifdef USE_RTOS
uci1 40:1324da35afd4 1906 Thread::wait(3000);
uci1 40:1324da35afd4 1907 #else
uci1 8:95a325df1f6b 1908 wait(3);
uci1 40:1324da35afd4 1909 #endif
uci1 8:95a325df1f6b 1910 PIN_PLA_cs=0;
uci1 40:1324da35afd4 1911 #ifdef USE_RTOS
uci1 40:1324da35afd4 1912 Thread::wait(3000);
uci1 40:1324da35afd4 1913 #else
uci1 8:95a325df1f6b 1914 wait(3);
uci1 40:1324da35afd4 1915 #endif
uci1 0:664899e0b988 1916
uci1 56:0bba0ef15697 1917
uci1 8:95a325df1f6b 1918 // DAC values
uci1 8:95a325df1f6b 1919 //
uci1 8:95a325df1f6b 1920 // first 12 bits = DAC value
uci1 8:95a325df1f6b 1921 // next 2 bits = DAC ID
uci1 8:95a325df1f6b 1922 // last 2 bits = dFPGA ID
uci1 8:95a325df1f6b 1923 //
uci1 8:95a325df1f6b 1924 // But FPGA uses "gray encoding" which means only 1 bit
uci1 8:95a325df1f6b 1925 // can change at a time (of the last 4 bits). So even tho
uci1 8:95a325df1f6b 1926 // the card/dac# is encoded, the order is also important
uci1 8:95a325df1f6b 1927 // 0000 (dac0,card0), 0001 (dac0,card1), 0011 (dac0,card3), 0010 (dac0,card2),
uci1 8:95a325df1f6b 1928 // 0110 (dac1,card2), 0111 (dac1,card3), 0101 (dac1,card1), etc.
uci1 12:d472f9811262 1929 #ifdef DEBUG
uci1 8:95a325df1f6b 1930 printf("setting dacs\r\n");
uci1 12:d472f9811262 1931 #endif
uci1 8:95a325df1f6b 1932 uint16_t dv=0;
uci1 56:0bba0ef15697 1933 for (uint8_t i=0, gri=0; i<kTotDacs; ++i) {
uci1 8:95a325df1f6b 1934 // get the gray-codes for this iteration
uci1 8:95a325df1f6b 1935 gri = SnBitUtils::binToGray(i);
uci1 8:95a325df1f6b 1936
uci1 8:95a325df1f6b 1937 // build bit word
uci1 8:95a325df1f6b 1938 dv = static_cast<int>(gConf.GetDac(gri & 0x0003u, gri >> 2u));
uci1 8:95a325df1f6b 1939 dv <<= 4u;
uci1 8:95a325df1f6b 1940 dv |= gri;
uci1 8:95a325df1f6b 1941
uci1 12:d472f9811262 1942 #ifdef DEBUG
uci1 8:95a325df1f6b 1943 printf("dac %04x\r\n",dv);
uci1 12:d472f9811262 1944 #endif
uci1 8:95a325df1f6b 1945
uci1 8:95a325df1f6b 1946 // send to FPGA
uci1 8:95a325df1f6b 1947 PIN_start_fpga=1;
uci1 8:95a325df1f6b 1948 PIN_spi.write(dv);
uci1 8:95a325df1f6b 1949 PIN_start_fpga=0;
uci1 8:95a325df1f6b 1950
uci1 8:95a325df1f6b 1951 Watchdog::kick();
uci1 8:95a325df1f6b 1952
uci1 8:95a325df1f6b 1953 }
uci1 56:0bba0ef15697 1954 #else // SST
uci1 56:0bba0ef15697 1955
uci1 56:0bba0ef15697 1956 // set and/or & differential pins
uci1 56:0bba0ef15697 1957
uci1 56:0bba0ef15697 1958 // set DACs via I2C
uci1 56:0bba0ef15697 1959
uci1 56:0bba0ef15697 1960 uint16_t dv=0;
uci1 56:0bba0ef15697 1961 uint8_t dn=0;
uci1 56:0bba0ef15697 1962 uint8_t cmdAndDac[3];
uci1 56:0bba0ef15697 1963 for (uint8_t ch=0; ch<kNchans; ++ch) {
uci1 56:0bba0ef15697 1964 for (uint8_t dc=0; dc<kNchanDacs; ++dc) {
uci1 56:0bba0ef15697 1965 // for (uint16_t dc=kNchanDacs-1; dc>=0; --dc) { // first all the highs, then the lows
uci1 56:0bba0ef15697 1966 // for (int16_t ch=kNchans-1; ch>=0; --ch) { // chans in reverse order
uci1 56:0bba0ef15697 1967 bool dok = false;
uci1 56:0bba0ef15697 1968 for (uint8_t tries = 0; (tries<kMaxDacSetTries) && (dok==false); ++tries) {
uci1 56:0bba0ef15697 1969 #ifdef DEBUG
uci1 56:0bba0ef15697 1970 printf("start i2c for dc=%hhu, ch=%hhu, try=%hhu, dok=%s\r\n",
uci1 56:0bba0ef15697 1971 dc, ch, tries, (dok ? "true" : "false"));
uci1 56:0bba0ef15697 1972 printf("address 0x%hhx (%hhd) ", kAllLTC2657, kAllLTC2657);
uci1 56:0bba0ef15697 1973 SnBitUtils::printBits(kAllLTC2657, true);
uci1 56:0bba0ef15697 1974 #endif
uci1 56:0bba0ef15697 1975 // build data to send
uci1 56:0bba0ef15697 1976 // blame the engineers for this bizzare mapping from
uci1 56:0bba0ef15697 1977 // chan, threshold -> DAC number
uci1 56:0bba0ef15697 1978 dn = (kTotDacs-1)-(dc*kNchans)-ch;
uci1 56:0bba0ef15697 1979 if (dn>7) { // invalid code for LTC2657 dac chip
uci1 56:0bba0ef15697 1980 error("chan/dac combination too big for 3 bits!");
uci1 56:0bba0ef15697 1981 }
uci1 56:0bba0ef15697 1982 dn |= (kUpdateDacCmd<<4); // prefix with update DAC value command
uci1 56:0bba0ef15697 1983 #ifdef DEBUG
uci1 56:0bba0ef15697 1984 printf("dn=%hhu ", dn);
uci1 56:0bba0ef15697 1985 SnBitUtils::printBits(dn, true);
uci1 56:0bba0ef15697 1986 #endif
uci1 56:0bba0ef15697 1987 dv = (gConf.GetDac(ch, dc)) << 4; // put 0's at the end (12 bits of num then 4 zero bits)
uci1 56:0bba0ef15697 1988 #ifdef DEBUG
uci1 56:0bba0ef15697 1989 printf("dv=%hu\r\n",dv);
uci1 56:0bba0ef15697 1990 printf("ch=%hhu, dc=%hhu, dac=%hu\r\n",ch,dc,gConf.GetDac(ch,dc));
uci1 56:0bba0ef15697 1991 #endif
uci1 56:0bba0ef15697 1992 // mbed i2c.write seems to send it "backwards" from a (low endian) bit
uci1 56:0bba0ef15697 1993 // point of view.. i guess it's forwards from an intuitive pov?
uci1 56:0bba0ef15697 1994 cmdAndDac[0] = dn;
uci1 56:0bba0ef15697 1995 cmdAndDac[1] = (dv & 0xFF00u) >> 8; // 8 MSBs of 12 bit num first
uci1 56:0bba0ef15697 1996 cmdAndDac[2] = (dv & 0x00FFu); // 4 LSBs of 12 bit num followed by 4 zeros
uci1 56:0bba0ef15697 1997
uci1 56:0bba0ef15697 1998 #ifdef DEBUG
uci1 56:0bba0ef15697 1999 printf("cmdAndDac[0]="); SnBitUtils::printBits(cmdAndDac[2],true);
uci1 56:0bba0ef15697 2000 printf("cmdAndDac[1]="); SnBitUtils::printBits(cmdAndDac[1],true);
uci1 56:0bba0ef15697 2001 printf("cmdAndDac[2]="); SnBitUtils::printBits(cmdAndDac[0],true);
uci1 56:0bba0ef15697 2002 #endif
uci1 56:0bba0ef15697 2003 // try to send it
uci1 56:0bba0ef15697 2004 // TODO: if no ACK, is just re-trying the whole thing good enough?
uci1 56:0bba0ef15697 2005 // TODO: assign correct slave address for the DAC chip (this is a global address)
uci1 56:0bba0ef15697 2006 dok = PIN_i2c.write(kAllLTC2657,
uci1 56:0bba0ef15697 2007 reinterpret_cast<char*>(cmdAndDac),
uci1 56:0bba0ef15697 2008 3*sizeof(uint8_t))==0;
uci1 56:0bba0ef15697 2009 } // end try loop
uci1 56:0bba0ef15697 2010 }
uci1 56:0bba0ef15697 2011 }
uci1 56:0bba0ef15697 2012
uci1 56:0bba0ef15697 2013 #endif // CHIPBOARD
uci1 56:0bba0ef15697 2014
uci1 12:d472f9811262 2015 #ifdef DEBUG
uci1 8:95a325df1f6b 2016 printf("dacs set\r\n");
uci1 12:d472f9811262 2017 #endif
uci1 40:1324da35afd4 2018 #ifdef USE_RTOS
uci1 40:1324da35afd4 2019 Thread::wait(20);
uci1 40:1324da35afd4 2020 #else
uci1 8:95a325df1f6b 2021 wait_ms(20);
uci1 40:1324da35afd4 2022 #endif
uci1 8:95a325df1f6b 2023 } else {
uci1 12:d472f9811262 2024 #ifdef DEBUG
uci1 8:95a325df1f6b 2025 printf("cards off. skipping PLA and DAC setting\r\n");
uci1 12:d472f9811262 2026 #endif
uci1 0:664899e0b988 2027 }
uci1 56:0bba0ef15697 2028
uci1 56:0bba0ef15697 2029 #if CHIPBOARD==SST4CH
uci1 56:0bba0ef15697 2030 // set the SST triggering run mode
uci1 56:0bba0ef15697 2031 PIN_dualOrSingleThresholds = gConf.IsDualThresholdMode();
uci1 56:0bba0ef15697 2032 PIN_differentialTrigSignal = gConf.IsDifferentialTrigMode();
uci1 56:0bba0ef15697 2033 #endif
uci1 0:664899e0b988 2034
uci1 0:664899e0b988 2035 // Majority Logic Trigger selection (# of cards)
uci1 0:664899e0b988 2036 SnBitUtils::SetChanNumBits(gConf.GetNumCardsMajLog() - 1u,
uci1 0:664899e0b988 2037 PIN_MajLogHiBit, PIN_MajLogLoBit);
uci1 0:664899e0b988 2038
uci1 0:664899e0b988 2039 // Enable thermal trigger?
uci1 0:664899e0b988 2040 PIN_enableThermTrig = gConf.IsThermTrigEnabled();
uci1 0:664899e0b988 2041
uci1 56:0bba0ef15697 2042 #if CHIPBOARD==SST4CH
uci1 56:0bba0ef15697 2043 InitTempProbe();
uci1 56:0bba0ef15697 2044 #endif
uci1 56:0bba0ef15697 2045
uci1 0:664899e0b988 2046 PIN_spi.format( 16, 1 ); // back to trigger mode
uci1 1:e392595b4b76 2047 PIN_spi.frequency( 10000000 ); // Max is 12.5 MHz
uci1 1:e392595b4b76 2048
uci1 8:95a325df1f6b 2049 // make new output file
uci1 8:95a325df1f6b 2050 // put after PLA/DAC, in case they affect the power readings
uci1 40:1324da35afd4 2051 #ifdef USE_RTOS
uci1 40:1324da35afd4 2052 Thread::wait(200);
uci1 40:1324da35afd4 2053 #else
uci1 8:95a325df1f6b 2054 wait_ms(200);
uci1 40:1324da35afd4 2055 #endif
uci1 8:95a325df1f6b 2056 MakeOutputFile();
uci1 8:95a325df1f6b 2057
uci1 21:ce51bb0ba4a5 2058 // reset tickers
uci1 21:ce51bb0ba4a5 2059 ResetAllTickers();
uci1 0:664899e0b988 2060
uci1 0:664899e0b988 2061 Watchdog::kick(); // don't reset!
uci1 8:95a325df1f6b 2062
uci1 12:d472f9811262 2063 #ifdef DEBUG
uci1 8:95a325df1f6b 2064 printf("set config done\r\n");
uci1 12:d472f9811262 2065 #endif
uci1 0:664899e0b988 2066 }
uci1 0:664899e0b988 2067
uci1 0:664899e0b988 2068 //
uci1 0:664899e0b988 2069 // readout functions
uci1 0:664899e0b988 2070 //
uci1 0:664899e0b988 2071 void WaitTrigAndSendClock() {
uci1 1:e392595b4b76 2072
uci1 12:d472f9811262 2073 #ifdef DEBUG
uci1 1:e392595b4b76 2074 printf("WaitTrigAndSendClock\r\n");
uci1 6:6f002d202f59 2075 printf("wait trig: (pw %hhu): cards %d, amps %d, irid %d, afar %d\r\n",
uci1 6:6f002d202f59 2076 gConf.GetPowerMode(), PIN_turn_on_system.read(), PIN_turn_on_amps.read(),
uci1 6:6f002d202f59 2077 PIN_iridSbd_power.read(), PIN_afar_power.read());
uci1 21:ce51bb0ba4a5 2078 printf("cards powered=%d\r\n",(int)AreCardsPowered(true));
uci1 12:d472f9811262 2079 #endif
uci1 15:f2569d8e4176 2080
uci1 21:ce51bb0ba4a5 2081 #ifdef DEBUG
uci1 41:d6f5e2f09e07 2082 printf("gFirstEvt=%s\r\n",gFirstEvt?"true":"false");
uci1 21:ce51bb0ba4a5 2083 #endif
uci1 41:d6f5e2f09e07 2084 if (AreCardsPowered(false)) {
uci1 41:d6f5e2f09e07 2085
uci1 41:d6f5e2f09e07 2086 PIN_spi.format( 16, 1 ); // back to trigger mode
uci1 41:d6f5e2f09e07 2087 PIN_spi.frequency( 10000000 ); // Max is 12.5 MHz
uci1 8:95a325df1f6b 2088
uci1 47:fbe956b10a91 2089 if (gFirstEvt==false) {
uci1 56:0bba0ef15697 2090 #if CHIPBOARD==ATWD4CH
uci1 47:fbe956b10a91 2091 PIN_DoNotRestartAllClocks = 0;
uci1 47:fbe956b10a91 2092 wait_us(1);
uci1 47:fbe956b10a91 2093 PIN_DoNotRestartAllClocks = 1;
uci1 56:0bba0ef15697 2094 #endif
uci1 47:fbe956b10a91 2095 } else {
uci1 47:fbe956b10a91 2096 gFirstEvt = false;
uci1 47:fbe956b10a91 2097 }
uci1 47:fbe956b10a91 2098
uci1 8:95a325df1f6b 2099 //
uci1 8:95a325df1f6b 2100 // wait for a trigger here.
uci1 8:95a325df1f6b 2101 //
uci1 12:d472f9811262 2102 #ifdef DEBUG
uci1 8:95a325df1f6b 2103 printf("starting wait for trig\r\n");
uci1 12:d472f9811262 2104 #endif
uci1 16:744ce85aede2 2105
uci1 8:95a325df1f6b 2106 gReadingOut = false; // this will allow forced triggers (see procForceTrigger())
uci1 56:0bba0ef15697 2107 #if CHIPBOARD==ATWD4CH
uci1 56:0bba0ef15697 2108 while ( PIN_a_sf_clk == 1 ) { // wait for trigger
uci1 56:0bba0ef15697 2109 #else
uci1 56:0bba0ef15697 2110 while ( PIN_dataReady==0 ) { // wait for data in mb fpga
uci1 56:0bba0ef15697 2111 #endif
uci1 56:0bba0ef15697 2112 if (gOpenCommWin || gCheckPower || gCheckTemp) {
uci1 12:d472f9811262 2113 #ifdef DEBUG
uci1 56:0bba0ef15697 2114 printf("break com=%d, pow=%d, tmp=%d\r\n",
uci1 56:0bba0ef15697 2115 gOpenCommWin,gCheckPower,gCheckTemp);
uci1 12:d472f9811262 2116 #endif
uci1 8:95a325df1f6b 2117 return; // break out to open comms or check power
uci1 8:95a325df1f6b 2118 }
uci1 0:664899e0b988 2119 }
uci1 8:95a325df1f6b 2120 gReadingOut = true; // disallow new forced triggers
uci1 56:0bba0ef15697 2121
uci1 15:f2569d8e4176 2122 // we can't be interrupted before data arrives at the MB FPGA
uci1 15:f2569d8e4176 2123 //StopAllTickers();
uci1 16:744ce85aede2 2124
uci1 23:ccf39298f205 2125 //wait_us(5);
uci1 56:0bba0ef15697 2126
uci1 56:0bba0ef15697 2127 #if CHIPBOARD==ATWD4CH
uci1 56:0bba0ef15697 2128 // ATWD
uci1 8:95a325df1f6b 2129 //
uci1 8:95a325df1f6b 2130 // collect data from daughter cards
uci1 8:95a325df1f6b 2131 //
uci1 8:95a325df1f6b 2132 // TODO: what if some card (set of channels) doesn't respond?
uci1 8:95a325df1f6b 2133 // currently, will wait forever?
uci1 8:95a325df1f6b 2134 // also, if ch1 is dead, will wait forever (due to FPGA code)
uci1 16:744ce85aede2 2135 gAdcToMBtimer.start();
uci1 56:0bba0ef15697 2136 for( uint16_t i = 0; i < kNsamps; ++i ) {
uci1 16:744ce85aede2 2137 while (PIN_a_sf_clk==1) {}
uci1 16:744ce85aede2 2138 while (PIN_a_sf_clk==0) {}
uci1 56:0bba0ef15697 2139
uci1 16:744ce85aede2 2140 PIN_ADC_CS = 0;
uci1 16:744ce85aede2 2141 PIN_spi.write( 0x00 );
uci1 16:744ce85aede2 2142 PIN_ADC_CS = 1;
uci1 0:664899e0b988 2143 }
uci1 16:744ce85aede2 2144 gAdcToMBtimer.stop();
uci1 16:744ce85aede2 2145 #ifdef DEBUG
uci1 16:744ce85aede2 2146 printf("total time = %d us\r\n", gAdcToMBtimer.read_us());
uci1 16:744ce85aede2 2147 #endif
uci1 16:744ce85aede2 2148 if ( kAdcToMBtimeCut < gAdcToMBtimer.read_us() ) {
uci1 84:80b15993944e 2149 // gEvent.SetTrgBit(kAdcToMBflag);
uci1 84:80b15993944e 2150 gAdcToMBflag = true;
uci1 16:744ce85aede2 2151 }
uci1 16:744ce85aede2 2152 gAdcToMBtimer.reset();
uci1 15:f2569d8e4176 2153
uci1 56:0bba0ef15697 2154 #else
uci1 56:0bba0ef15697 2155 // For SST, data is already in the mb FPGA, so no need to do anything here
uci1 56:0bba0ef15697 2156 #endif
uci1 56:0bba0ef15697 2157
uci1 8:95a325df1f6b 2158 } else {
uci1 8:95a325df1f6b 2159 // cards have no power. don't try reading out
uci1 8:95a325df1f6b 2160 gReadingOut=false;
uci1 47:fbe956b10a91 2161 // set gFirstEvt to false even if cards are powered off.
uci1 47:fbe956b10a91 2162 // otherwise, if cards ARE powered off, it will always be
uci1 47:fbe956b10a91 2163 // true and the "start trigger" clock will be written continuously
uci1 47:fbe956b10a91 2164 gFirstEvt = false;
uci1 0:664899e0b988 2165 }
uci1 56:0bba0ef15697 2166
uci1 0:664899e0b988 2167 }
uci1 0:664899e0b988 2168
uci1 40:1324da35afd4 2169 bool IsPinPowered(const SnCommWin* cw) {
uci1 40:1324da35afd4 2170 bool havePower = false;
uci1 40:1324da35afd4 2171 switch (cw->GetCommType()) {
uci1 40:1324da35afd4 2172 case SnConfigFrame::kIrid:
uci1 40:1324da35afd4 2173 havePower = gConf.IsPoweredFor(SnConfigFrame::kIridComWin)
uci1 40:1324da35afd4 2174 && ( (kIridPwrFromAfar)
uci1 40:1324da35afd4 2175 ? PIN_afar_power.read()
uci1 40:1324da35afd4 2176 : PIN_iridSbd_power.read() ==
uci1 40:1324da35afd4 2177 gConf.GetPowPinSetting(SnConfigFrame::kIridComWin));
uci1 40:1324da35afd4 2178 break;
uci1 40:1324da35afd4 2179 case SnConfigFrame::kAfar:
uci1 40:1324da35afd4 2180 havePower = gConf.IsPoweredFor(SnConfigFrame::kAfarComWin)
uci1 40:1324da35afd4 2181 && (PIN_afar_power.read() ==
uci1 40:1324da35afd4 2182 gConf.GetPowPinSetting(SnConfigFrame::kAfarComWin));
uci1 40:1324da35afd4 2183 break;
uci1 40:1324da35afd4 2184 case SnConfigFrame::kUSB:
uci1 40:1324da35afd4 2185 havePower = true; // USB always on (for now)
uci1 40:1324da35afd4 2186 break;
uci1 40:1324da35afd4 2187 case SnConfigFrame::kSDcard: // shouldn't happen. skip it
uci1 40:1324da35afd4 2188 default: // unknown.. skip it
uci1 40:1324da35afd4 2189 break;
uci1 40:1324da35afd4 2190 };
uci1 40:1324da35afd4 2191 return havePower;
uci1 40:1324da35afd4 2192 }
uci1 40:1324da35afd4 2193
uci1 40:1324da35afd4 2194
uci1 40:1324da35afd4 2195 SnCommWin::ECommWinResult OpenCommWin(const bool forceReconfig,
uci1 40:1324da35afd4 2196 const bool isStartupWin) {
uci1 0:664899e0b988 2197 // loop through each comm mode:
uci1 0:664899e0b988 2198 // a) try to connect
uci1 0:664899e0b988 2199 // b) if connected, listen for config
uci1 0:664899e0b988 2200 // c) if config requests data, send it
uci1 67:ec999336fcd1 2201
uci1 67:ec999336fcd1 2202 led2 = 1;
uci1 67:ec999336fcd1 2203
uci1 3:24c5f0f50bf1 2204 gLastCommWin = time(0);
uci1 13:7a1fb885a8e4 2205
uci1 0:664899e0b988 2206 SnCommWin::ECommWinResult res = SnCommWin::kUndefFail;
uci1 0:664899e0b988 2207
uci1 21:ce51bb0ba4a5 2208 // get the trigger rates
uci1 21:ce51bb0ba4a5 2209 float thmrate=0, evtrate=0;
uci1 21:ce51bb0ba4a5 2210 GetRates(thmrate, evtrate);
uci1 22:f957c4f840ad 2211 #ifdef DEBUG
uci1 56:0bba0ef15697 2212 printf("config=%s\r\n", gConf.GetLabel());
uci1 22:f957c4f840ad 2213 printf("thmrate=%g, evtrate=%g\r\n",thmrate,evtrate);
uci1 84:80b15993944e 2214 printf("Free memory = %d\r\n", FreeMem());
uci1 22:f957c4f840ad 2215 #endif
uci1 21:ce51bb0ba4a5 2216
uci1 21:ce51bb0ba4a5 2217 StopAllTickers();
uci1 40:1324da35afd4 2218
uci1 13:7a1fb885a8e4 2219 if (gConf.GetCommWinDuration()==0) {
uci1 13:7a1fb885a8e4 2220 // TODO: set min so this is not possible
uci1 13:7a1fb885a8e4 2221 res = SnCommWin::kOkNoMsg;
uci1 13:7a1fb885a8e4 2222 } else {
uci1 13:7a1fb885a8e4 2223
uci1 13:7a1fb885a8e4 2224 gCommWinOpen = true;
uci1 1:e392595b4b76 2225 Watchdog::kick(); // don't reset!
uci1 13:7a1fb885a8e4 2226
uci1 13:7a1fb885a8e4 2227 #ifdef DEBUG
uci1 13:7a1fb885a8e4 2228 printf("opening comm window at %d\r\n", (int32_t)gLastCommWin);
uci1 16:744ce85aede2 2229 printf("duration=%u\r\n",gConf.GetCommWinDuration());
uci1 13:7a1fb885a8e4 2230 #endif
uci1 13:7a1fb885a8e4 2231
uci1 13:7a1fb885a8e4 2232 // close the file so that the data is all written out.
uci1 13:7a1fb885a8e4 2233 // and open it back up at the beginning (for reading)
uci1 12:d472f9811262 2234 #ifdef DEBUG
uci1 13:7a1fb885a8e4 2235 printf("close & open file. gEvtNum=%u, gPowNum=%u\r\n",gEvtNum,gPowNum);
uci1 25:57b2627fe756 2236 printf("curfile=%p, filename=%s\r\n",SnSDUtils::GetCurFile(),
uci1 25:57b2627fe756 2237 SnSDUtils::GetCurFileName());
uci1 12:d472f9811262 2238 #endif
uci1 40:1324da35afd4 2239
uci1 40:1324da35afd4 2240 if (isStartupWin==false) {
uci1 56:0bba0ef15697 2241 #if CHIPBOARD==ATWD4CH
uci1 56:0bba0ef15697 2242 PIN_lockRegisters = 0; // unlock so we can talk to the SD card
uci1 56:0bba0ef15697 2243 #else
uci1 56:0bba0ef15697 2244 PIN_readingData = 0; // unlock so we can talk to the SD card
uci1 56:0bba0ef15697 2245 #endif
uci1 25:57b2627fe756 2246 #ifdef DEBUG
uci1 40:1324da35afd4 2247 printf("closing output file\r\n");
uci1 25:57b2627fe756 2248 #endif
uci1 40:1324da35afd4 2249 SnSDUtils::CloseOutputFile(SnSDUtils::GetCurFile());
uci1 25:57b2627fe756 2250 #ifdef DEBUG
uci1 40:1324da35afd4 2251 printf("open existing file (%d)\r\n",strlen(SnSDUtils::GetCurFileName()));
uci1 25:57b2627fe756 2252 #endif
uci1 40:1324da35afd4 2253 SnSDUtils::OpenExistingFile(SnSDUtils::GetCurFileName(), true, false);
uci1 40:1324da35afd4 2254 }
uci1 40:1324da35afd4 2255
uci1 21:ce51bb0ba4a5 2256 #ifdef DEBUG
uci1 21:ce51bb0ba4a5 2257 printf("setting power\r\n");
uci1 21:ce51bb0ba4a5 2258 #endif
uci1 84:80b15993944e 2259 // (probably) power down cards,amps
uci1 84:80b15993944e 2260 // don't power up comms yet (only as needed for use)
uci1 84:80b15993944e 2261 SetPower(true, 0);
uci1 13:7a1fb885a8e4 2262
uci1 25:57b2627fe756 2263 // time to recount files for the status update
uci1 40:1324da35afd4 2264 // for the startup win, don't access SD card in case we
uci1 40:1324da35afd4 2265 // rebooted due to a problem with the SD card
uci1 40:1324da35afd4 2266 SnStatusFrame::fgRecalcFiles = !isStartupWin;
uci1 25:57b2627fe756 2267
uci1 28:484943132bb0 2268 #if defined(ENABLE_AFAR_TWITTER) && defined(ENABLE_AFAR_COMM)
uci1 28:484943132bb0 2269 bool doTwitter = false;
uci1 28:484943132bb0 2270 #endif
uci1 28:484943132bb0 2271
uci1 21:ce51bb0ba4a5 2272 #ifdef DEBUG
uci1 21:ce51bb0ba4a5 2273 printf("start loop over comms\r\n");
uci1 21:ce51bb0ba4a5 2274 #endif
uci1 84:80b15993944e 2275 bool needToConnect=true; // still need to talk to the outside
uci1 84:80b15993944e 2276 bool sendStat[kNcomms]; // if need to send status over this peripheral
uci1 84:80b15993944e 2277 bool needClos[kNcomms]; // if need to call CloseConn on this peripheral
uci1 56:0bba0ef15697 2278 for (uint8_t i=0; i<kNcomms; ++i) {
uci1 13:7a1fb885a8e4 2279 sendStat[i]=true;
uci1 84:80b15993944e 2280 needClos[i]=true;
uci1 13:7a1fb885a8e4 2281 }
uci1 13:7a1fb885a8e4 2282 bool* ss = sendStat;
uci1 84:80b15993944e 2283 bool* nc = needClos;
uci1 13:7a1fb885a8e4 2284 SnCommWin** cw = gComms;
uci1 84:80b15993944e 2285 for (uint8_t i=0; needToConnect && ((time(0)-gLastCommWin)<gConf.GetCommWinDuration());
uci1 84:80b15993944e 2286 ++i, ++cw, ++ss, ++nc) {
uci1 1:e392595b4b76 2287 Watchdog::kick(); // don't reset!
uci1 13:7a1fb885a8e4 2288 if (i==kNcomms) {
uci1 13:7a1fb885a8e4 2289 i=0;
uci1 13:7a1fb885a8e4 2290 cw = gComms;
uci1 13:7a1fb885a8e4 2291 ss = sendStat;
uci1 84:80b15993944e 2292 nc = needClos;
uci1 13:7a1fb885a8e4 2293 }
uci1 27:efc4d654b139 2294 // skip if no comm object
uci1 13:7a1fb885a8e4 2295 if ((*cw)==0) {
uci1 13:7a1fb885a8e4 2296 continue;
uci1 13:7a1fb885a8e4 2297 }
uci1 84:80b15993944e 2298
uci1 84:80b15993944e 2299 const SnConfigFrame::EDatPackBit ctype = (*cw)->GetCommType();
uci1 84:80b15993944e 2300
uci1 84:80b15993944e 2301 // power up for this device
uci1 84:80b15993944e 2302 if (gConf.IsCommPowerSimple()==false) {
uci1 84:80b15993944e 2303 SetPower(true, ctype);
uci1 84:80b15993944e 2304 }
uci1 84:80b15993944e 2305
uci1 27:efc4d654b139 2306 // skip if no power for this comm
uci1 27:efc4d654b139 2307 // THIS IS VITAL! For example, if the ethernet
uci1 27:efc4d654b139 2308 // port is powered down, making an Ethernet obejct
uci1 27:efc4d654b139 2309 // (done in netif) will stall forever waiting for the clock.
uci1 27:efc4d654b139 2310 // Do it here to keep all PIN usage in main.cpp
uci1 40:1324da35afd4 2311 const bool havePower=IsPinPowered(*cw);
uci1 27:efc4d654b139 2312 if (havePower==false) {
uci1 27:efc4d654b139 2313 continue;
uci1 27:efc4d654b139 2314 }
uci1 40:1324da35afd4 2315
uci1 40:1324da35afd4 2316 // always apply safety nets to connection and listen so
uci1 40:1324da35afd4 2317 // that we don't accidently shut down comms (i.e. with
uci1 40:1324da35afd4 2318 // connectTO or listnTO being 0)
uci1 40:1324da35afd4 2319 gConf.ApplyConnectListenSafetyNets();
uci1 84:80b15993944e 2320
uci1 16:744ce85aede2 2321 const uint32_t conto =
uci1 84:80b15993944e 2322 (gConf.GetCommWinDuration() < gConf.GetCommWinConnectTO(ctype)) ?
uci1 84:80b15993944e 2323 gConf.GetCommWinDuration() : gConf.GetCommWinConnectTO(ctype);
uci1 16:744ce85aede2 2324 const uint32_t listo =
uci1 84:80b15993944e 2325 (gConf.GetCommWinDuration() < gConf.GetCommWinListenTO(ctype)) ?
uci1 84:80b15993944e 2326 gConf.GetCommWinDuration() : gConf.GetCommWinListenTO(ctype);
uci1 40:1324da35afd4 2327
uci1 84:80b15993944e 2328 //
uci1 84:80b15993944e 2329 // try to connect to the outside if we haven't yet
uci1 84:80b15993944e 2330 //
uci1 16:744ce85aede2 2331 // update power reading in case we want to send it in status
uci1 16:744ce85aede2 2332 GetAvePowerReading();
uci1 56:0bba0ef15697 2333
uci1 56:0bba0ef15697 2334 // update temperature in case we want to send it in status
uci1 56:0bba0ef15697 2335 if (isStartupWin) {
uci1 56:0bba0ef15697 2336 #if CHIPBOARD==SST4CH
uci1 56:0bba0ef15697 2337 InitTempProbe();
uci1 56:0bba0ef15697 2338 #endif
uci1 56:0bba0ef15697 2339 }
uci1 56:0bba0ef15697 2340 UpdateTemperature();
uci1 21:ce51bb0ba4a5 2341
uci1 13:7a1fb885a8e4 2342 // open window and (mabye) send status update
uci1 12:d472f9811262 2343 #ifdef DEBUG
uci1 84:80b15993944e 2344 printf("Free memory = %d\r\n", FreeMem());
uci1 84:80b15993944e 2345 printf("calling OpenWindow. ss=%d. ctype=%hhu (%s)\r\n",
uci1 84:80b15993944e 2346 (int)(*ss),(uint8_t)ctype,SnConfigFrame::GetDataStreamName(ctype));
uci1 40:1324da35afd4 2347 printf("conto=%u, listo=%u, dur=%u, connTO=%u, lisTO=%u\r\n",
uci1 40:1324da35afd4 2348 conto,listo,gConf.GetCommWinDuration(),
uci1 84:80b15993944e 2349 gConf.GetCommWinConnectTO(ctype), gConf.GetCommWinListenTO(ctype));
uci1 84:80b15993944e 2350 printf("stopAt=%u, current=%d, lastComWin=%d, dt~%u\r\n",
uci1 84:80b15993944e 2351 gConf.GetTimeoutTime(gLastCommWin,conto),
uci1 84:80b15993944e 2352 time(0), gLastCommWin,
uci1 84:80b15993944e 2353 gConf.GetTimeoutTime(gLastCommWin,conto)-time(0));
uci1 12:d472f9811262 2354 #endif
uci1 84:80b15993944e 2355
uci1 84:80b15993944e 2356 //
uci1 84:80b15993944e 2357 // open the connection and send the status update (if the
uci1 84:80b15993944e 2358 // status has not yet been sent over this peripheral)
uci1 84:80b15993944e 2359 //
uci1 84:80b15993944e 2360 const SnCommWin::ECommWinResult conres = (*cw)->OpenWindow( *ss,
uci1 84:80b15993944e 2361 gConf, gPower, gEvent, SnSDUtils::GetCurSeqNum(), thmrate, evtrate,
uci1 84:80b15993944e 2362 gPowerOnTime, gTemperature,
uci1 84:80b15993944e 2363 gGenBuf, gConf.GetTimeoutTime(gLastCommWin, conto));
uci1 84:80b15993944e 2364
uci1 56:0bba0ef15697 2365 #ifdef DEBUG
uci1 56:0bba0ef15697 2366 printf("conres = %d\r\n",static_cast<int>(conres));
uci1 56:0bba0ef15697 2367 #endif
uci1 13:7a1fb885a8e4 2368 if (conres>=SnCommWin::kConnected) {
uci1 1:e392595b4b76 2369 Watchdog::kick(); // don't reset!
uci1 13:7a1fb885a8e4 2370 // connected. listen for config
uci1 13:7a1fb885a8e4 2371 *ss = false; // don't send status next time
uci1 84:80b15993944e 2372 *nc = true; // will need to close this connection
uci1 40:1324da35afd4 2373
uci1 40:1324da35afd4 2374 // clear watchdog reset bit now that we've told someone
uci1 40:1324da35afd4 2375 Watchdog::clearResetFlag();
uci1 40:1324da35afd4 2376
uci1 28:484943132bb0 2377 #if defined(ENABLE_AFAR_TWITTER) && defined(ENABLE_AFAR_COMM)
uci1 84:80b15993944e 2378 if (ctype==SnConfigFrame::kAfar) {
uci1 28:484943132bb0 2379 // if we connected by Afar
uci1 28:484943132bb0 2380 doTwitter = true;
uci1 28:484943132bb0 2381 }
uci1 28:484943132bb0 2382 #endif
uci1 28:484943132bb0 2383
uci1 12:d472f9811262 2384 #ifdef DEBUG
uci1 21:ce51bb0ba4a5 2385 printf("get conf gtt=%u\r\n",gConf.GetTimeoutTime(gLastCommWin, listo));
uci1 12:d472f9811262 2386 #endif
uci1 98:ce72ef143b9b 2387 // copy old config
uci1 98:ce72ef143b9b 2388 gConfCopy = gConf;
uci1 98:ce72ef143b9b 2389
uci1 84:80b15993944e 2390 //
uci1 84:80b15993944e 2391 // ask for a new config
uci1 84:80b15993944e 2392 //
uci1 13:7a1fb885a8e4 2393 const SnCommWin::ECommWinResult cfgres = (*cw)->GetConfig(
uci1 21:ce51bb0ba4a5 2394 gConf, gConf.GetTimeoutTime(gLastCommWin, listo), gGenBuf, gBufSize);
uci1 56:0bba0ef15697 2395 #ifdef DEBUG
uci1 56:0bba0ef15697 2396 printf("cfgres = %d\r\n",static_cast<int>(cfgres));
uci1 56:0bba0ef15697 2397 #endif
uci1 13:7a1fb885a8e4 2398 if (cfgres>=SnCommWin::kOkWithMsg) {
uci1 13:7a1fb885a8e4 2399 Watchdog::kick(); // don't reset!
uci1 16:744ce85aede2 2400
uci1 12:d472f9811262 2401 #ifdef DEBUG
uci1 13:7a1fb885a8e4 2402 printf("received config!\r\n");
uci1 13:7a1fb885a8e4 2403 printf("send data = %d\r\n", gConf.GetCommSendData());
uci1 12:d472f9811262 2404 #endif
uci1 84:80b15993944e 2405
uci1 21:ce51bb0ba4a5 2406 const uint32_t winto = gConf.GetTimeoutTime(gLastCommWin,
uci1 21:ce51bb0ba4a5 2407 gConf.GetCommWinDuration());
uci1 40:1324da35afd4 2408 //const uint32_t gtt = gConf.IsObeyingTimeout() ? winto : 0;
uci1 40:1324da35afd4 2409
uci1 84:80b15993944e 2410 //
uci1 84:80b15993944e 2411 // send status data -- do this after getting the config!
uci1 84:80b15993944e 2412 // (avoid a situation where sending all this data causes a timeout,
uci1 84:80b15993944e 2413 // thereby preventing a new config from being accepted)
uci1 84:80b15993944e 2414 //
uci1 98:ce72ef143b9b 2415 res = (*cw)->SendStatusData(gConf, gConfCopy,
uci1 84:80b15993944e 2416 gStTrgStartClk, gStTrgStopClk,
uci1 84:80b15993944e 2417 gStPower, gEvent, gStTemperature,
uci1 84:80b15993944e 2418 gHrtbt, gStNewPower, gStNewEvent,
uci1 84:80b15993944e 2419 gStNewHeartbeat, gStNewTemperature,
uci1 84:80b15993944e 2420 gGenBuf, winto);
uci1 84:80b15993944e 2421 #ifdef DEBUG
uci1 84:80b15993944e 2422 printf("SendStatusData res=%d\r\n",
uci1 84:80b15993944e 2423 static_cast<int32_t>(res));
uci1 84:80b15993944e 2424 #endif
uci1 84:80b15993944e 2425
uci1 84:80b15993944e 2426 //
uci1 40:1324da35afd4 2427 // check if there are any requests before sending data
uci1 84:80b15993944e 2428 //
uci1 40:1324da35afd4 2429 if (gConf.IsWaitingHndShkBeforeSendData()) {
uci1 40:1324da35afd4 2430 // send handshake request
uci1 40:1324da35afd4 2431 (*cw)->SendHndshkReq(gGenBuf, winto);
uci1 40:1324da35afd4 2432 // wait for response
uci1 40:1324da35afd4 2433 uint8_t hndshk(0); uint32_t hndshkLen(0);
uci1 40:1324da35afd4 2434 res = (*cw)->WaitHandshake(gConf, winto, gGenBuf, gBufSize, hndshk,
uci1 40:1324da35afd4 2435 &hndshkLen);
uci1 56:0bba0ef15697 2436 #ifdef DEBUG
uci1 56:0bba0ef15697 2437 printf("WaitHandshake res = %d\r\n",static_cast<int>(res));
uci1 56:0bba0ef15697 2438 #endif
uci1 40:1324da35afd4 2439 // handle response
uci1 40:1324da35afd4 2440 if (SnCommWin::kOkWithMsg==res) {
uci1 40:1324da35afd4 2441 res = (*cw)->HandleHandshake(SnSDUtils::GetCurFile(),
uci1 40:1324da35afd4 2442 SnSDUtils::GetCurFileName(),
uci1 84:80b15993944e 2443 gConf, gEvent, gPower, gGenBuf, gBufSize,
uci1 84:80b15993944e 2444 // gConf, gLastEvent, gPower, gGenBuf, gBufSize,
uci1 40:1324da35afd4 2445 winto, hndshk, hndshkLen);
uci1 56:0bba0ef15697 2446 #ifdef DEBUG
uci1 56:0bba0ef15697 2447 printf("HandleHandshake res = %d\r\n",static_cast<int>(res));
uci1 56:0bba0ef15697 2448 #endif
uci1 40:1324da35afd4 2449 }
uci1 84:80b15993944e 2450 } // if handshake before data
uci1 84:80b15993944e 2451
uci1 84:80b15993944e 2452 //
uci1 84:80b15993944e 2453 // send data if need be (files, some events, etc)
uci1 84:80b15993944e 2454 //
uci1 13:7a1fb885a8e4 2455 if (gConf.GetCommSendData()!=0) {
uci1 12:d472f9811262 2456 #ifdef DEBUG
uci1 40:1324da35afd4 2457 printf("sending data, winto=%u. lcw=%u, dur=%u, obey=%s\r\n",
uci1 40:1324da35afd4 2458 winto,
uci1 13:7a1fb885a8e4 2459 gLastCommWin, gConf.GetCommWinDuration(),
uci1 13:7a1fb885a8e4 2460 gConf.IsObeyingTimeout() ? "true" : "false");
uci1 12:d472f9811262 2461 #endif
uci1 16:744ce85aede2 2462
uci1 84:80b15993944e 2463 res = (*cw)->SendData(gConf,
uci1 84:80b15993944e 2464 // gLastEvent, gPower, gGenBuf, gBufSize,
uci1 84:80b15993944e 2465 gEvent, gPower, gGenBuf, gBufSize,
uci1 40:1324da35afd4 2466 winto);
uci1 56:0bba0ef15697 2467 #ifdef DEBUG
uci1 56:0bba0ef15697 2468 printf("SendData res = %d\r\n",static_cast<int>(res));
uci1 56:0bba0ef15697 2469 #endif
uci1 56:0bba0ef15697 2470
uci1 13:7a1fb885a8e4 2471 } else {
uci1 13:7a1fb885a8e4 2472 // don't send anything
uci1 13:7a1fb885a8e4 2473 res = cfgres;
uci1 84:80b15993944e 2474 } // if send data
uci1 13:7a1fb885a8e4 2475 #ifdef DEBUG
uci1 13:7a1fb885a8e4 2476 printf("Got config!\r\n");
uci1 13:7a1fb885a8e4 2477 #endif
uci1 13:7a1fb885a8e4 2478 Watchdog::kick(); // don't reset!
uci1 84:80b15993944e 2479
uci1 84:80b15993944e 2480 // need to close this connection
uci1 84:80b15993944e 2481 *nc = true;
uci1 84:80b15993944e 2482 // stop trying to connect to outside
uci1 84:80b15993944e 2483 // don't break immediately, so that we can close conn and
uci1 84:80b15993944e 2484 // maybe tweet (pff..)
uci1 84:80b15993944e 2485 needToConnect = false;
uci1 84:80b15993944e 2486
uci1 84:80b15993944e 2487 } // if config recvd ok with message
uci1 84:80b15993944e 2488
uci1 84:80b15993944e 2489 //
uci1 84:80b15993944e 2490 // stupid legacy twitter crap.
uci1 84:80b15993944e 2491 //
uci1 84:80b15993944e 2492 // after normal Afar connection closed, try to tweet
uci1 84:80b15993944e 2493 #if defined(ENABLE_AFAR_TWITTER) && defined(ENABLE_AFAR_COMM)
uci1 84:80b15993944e 2494 if (ctype==SnConfigFrame::kAfar) {
uci1 84:80b15993944e 2495 // tweet
uci1 84:80b15993944e 2496 #ifdef DEBUG
uci1 84:80b15993944e 2497 printf("for twitter: gTwit=%p, doTwitter=%d\r\n",gTwit,(int)doTwitter);
uci1 84:80b15993944e 2498 #endif
uci1 84:80b15993944e 2499 // send a twitter update
uci1 84:80b15993944e 2500 if ( (gTwit!=0) && doTwitter ) {
uci1 84:80b15993944e 2501 const uint32_t conto =
uci1 84:80b15993944e 2502 (gConf.GetCommWinDuration() < gTwit->GetConnectTimeout()) ?
uci1 84:80b15993944e 2503 gConf.GetCommWinDuration() : gTwit->GetConnectTimeout();
uci1 84:80b15993944e 2504 const uint32_t listo =
uci1 84:80b15993944e 2505 (gConf.GetCommWinDuration() < gTwit->GetListenTimeout()) ?
uci1 84:80b15993944e 2506 gConf.GetCommWinDuration() : gTwit->GetListenTimeout();
uci1 84:80b15993944e 2507 #ifdef DEBUG
uci1 84:80b15993944e 2508 printf("open twit window. conto=%u, listo=%u\r\n",
uci1 84:80b15993944e 2509 conto, listo);
uci1 84:80b15993944e 2510 #endif
uci1 84:80b15993944e 2511 const SnCommWin::ECommWinResult conres = gTwit->OpenWindow(
uci1 84:80b15993944e 2512 gConf.GetTimeoutTime(gLastCommWin, conto), false, gConf,
uci1 84:80b15993944e 2513 // gLastEvent, gPower,
uci1 84:80b15993944e 2514 gEvent, gPower,
uci1 84:80b15993944e 2515 SnSDUtils::GetCurSeqNum(), thmrate, evtrate,
uci1 84:80b15993944e 2516 gGenBuf);
uci1 84:80b15993944e 2517 if (conres>=SnCommWin::kConnected) {
uci1 84:80b15993944e 2518 Watchdog::kick(); // don't reset!
uci1 84:80b15993944e 2519 gTwit->Tweet(gConf, thmrate, evtrate, gGenBuf,
uci1 84:80b15993944e 2520 gConf.GetTimeoutTime(time(0), listo));
uci1 84:80b15993944e 2521 }
uci1 84:80b15993944e 2522 }
uci1 84:80b15993944e 2523 } // end tweet block
uci1 84:80b15993944e 2524 #endif
uci1 84:80b15993944e 2525
uci1 21:ce51bb0ba4a5 2526 } else {
uci1 40:1324da35afd4 2527 // OpenWindow did not connect
uci1 21:ce51bb0ba4a5 2528 (*cw)->CloseConn(gConf.GetTimeoutTime(gLastCommWin, listo));
uci1 84:80b15993944e 2529 *nc = false;
uci1 84:80b15993944e 2530 #ifdef DEBUG
uci1 84:80b15993944e 2531 printf("no connect close conn. i=%d, nc=%s\r\n",
uci1 84:80b15993944e 2532 (int32_t)i, (*nc) ? "true" : "false");
uci1 84:80b15993944e 2533 #endif
uci1 21:ce51bb0ba4a5 2534 } // if connected
uci1 13:7a1fb885a8e4 2535
uci1 13:7a1fb885a8e4 2536 Watchdog::kick(); // don't reset!
uci1 84:80b15993944e 2537
uci1 84:80b15993944e 2538 if (*nc) {
uci1 84:80b15993944e 2539 // need to close this connection
uci1 84:80b15993944e 2540 #ifdef DEBUG
uci1 84:80b15993944e 2541 printf("close conn extra time. i=%d, nc=%s\r\n",
uci1 84:80b15993944e 2542 (int32_t)i, (*nc) ? "true" : "false");
uci1 84:80b15993944e 2543 #endif
uci1 84:80b15993944e 2544 const uint32_t extraDiscTime = gLastCommWin
uci1 84:80b15993944e 2545 + gConf.GetCommWinConnectTO((*cw)->GetCommType());
uci1 84:80b15993944e 2546 (*cw)->CloseConn(
uci1 84:80b15993944e 2547 gConf.GetTimeoutTime(extraDiscTime, gConf.GetCommWinDuration()));
uci1 84:80b15993944e 2548 *nc = false;
uci1 84:80b15993944e 2549 }
uci1 84:80b15993944e 2550
uci1 84:80b15993944e 2551 Watchdog::kick(); // don't reset!
uci1 21:ce51bb0ba4a5 2552 } // end loop over comms
uci1 28:484943132bb0 2553
uci1 84:80b15993944e 2554
uci1 41:d6f5e2f09e07 2555 // check Iridium time, send Iridium signal strength, and close the connection(s)
uci1 15:f2569d8e4176 2556 cw = gComms;
uci1 84:80b15993944e 2557 nc = needClos;
uci1 84:80b15993944e 2558 for (uint8_t i=0; i<kNcomms; ++i, ++cw, ++nc) {
uci1 15:f2569d8e4176 2559 if ((*cw)==0) {
uci1 15:f2569d8e4176 2560 continue;
uci1 15:f2569d8e4176 2561 }
uci1 84:80b15993944e 2562
uci1 84:80b15993944e 2563 const SnConfigFrame::EDatPackBit ctype = (*cw)->GetCommType();
uci1 84:80b15993944e 2564
uci1 84:80b15993944e 2565 // check Iridium time
uci1 84:80b15993944e 2566 if (ctype==SnConfigFrame::kIrid) {
uci1 40:1324da35afd4 2567
uci1 84:80b15993944e 2568 // power up for this device
uci1 84:80b15993944e 2569 if (gConf.IsCommPowerSimple()==false) {
uci1 84:80b15993944e 2570 SetPower(true, ctype);
uci1 84:80b15993944e 2571 }
uci1 84:80b15993944e 2572 const bool havePower=IsPinPowered(*cw);
uci1 84:80b15993944e 2573 if (havePower==false) {
uci1 84:80b15993944e 2574 continue;
uci1 84:80b15993944e 2575 }
uci1 84:80b15993944e 2576
uci1 16:744ce85aede2 2577 #ifdef DEBUG
uci1 16:744ce85aede2 2578 printf("try to set iridium time\r\n");
uci1 16:744ce85aede2 2579 #endif
uci1 16:744ce85aede2 2580 // set the clock before closing connection
uci1 41:d6f5e2f09e07 2581 const uint32_t totime =
uci1 41:d6f5e2f09e07 2582 gConf.GetTimeoutTime(gLastCommWin,
uci1 41:d6f5e2f09e07 2583 gConf.GetCommWinDuration());
uci1 41:d6f5e2f09e07 2584 #ifdef DEBUG
uci1 41:d6f5e2f09e07 2585 printf("totime=%u, ctime=%u\r\n",totime,time(0));
uci1 41:d6f5e2f09e07 2586 #endif
uci1 41:d6f5e2f09e07 2587 const bool con = (*cw)->Connect(totime);
uci1 84:80b15993944e 2588 *nc = true;
uci1 84:80b15993944e 2589
uci1 16:744ce85aede2 2590 if (con) {
uci1 40:1324da35afd4 2591 uint32_t prvTime(0), setTime(0);
uci1 41:d6f5e2f09e07 2592 const bool gottime = (*cw)->TrySetSysTimeUnix(
uci1 41:d6f5e2f09e07 2593 totime, prvTime, setTime);
uci1 41:d6f5e2f09e07 2594 if (gottime) {
uci1 84:80b15993944e 2595 gClkSet.SetClocks( prvTime, setTime, time(0),
uci1 84:80b15993944e 2596 gSinceClkSet.read_us() );
uci1 84:80b15993944e 2597 gSinceClkSet.reset();
uci1 84:80b15993944e 2598 gSinceClkSet.start();
uci1 41:d6f5e2f09e07 2599 #ifdef DEBUG
uci1 84:80b15993944e 2600 // printf("sig str: totime=%u, ctime=%u\r\n",totime,time(0));
uci1 84:80b15993944e 2601 printf("sig str: totime=%u, ctime=%u\r\n",totime,gClkSet.GetCurTime());
uci1 41:d6f5e2f09e07 2602 #endif
uci1 41:d6f5e2f09e07 2603 // got time; now send signal strength
uci1 41:d6f5e2f09e07 2604 (*cw)->SendSignalStrength( gGenBuf, gSigStr, totime );
uci1 84:80b15993944e 2605 } // if got the iridium system time
uci1 84:80b15993944e 2606 } // if connected (again, possibly)
uci1 84:80b15993944e 2607 } // if iridium
uci1 84:80b15993944e 2608
uci1 84:80b15993944e 2609 if (*nc) {
uci1 84:80b15993944e 2610
uci1 84:80b15993944e 2611 // power up for this device
uci1 84:80b15993944e 2612 if (gConf.IsCommPowerSimple()==false) {
uci1 84:80b15993944e 2613 SetPower(true, ctype);
uci1 16:744ce85aede2 2614 }
uci1 84:80b15993944e 2615 const bool havePower=IsPinPowered(*cw);
uci1 84:80b15993944e 2616 if (havePower==false) {
uci1 84:80b15993944e 2617 continue;
uci1 84:80b15993944e 2618 }
uci1 84:80b15993944e 2619
uci1 28:484943132bb0 2620 #ifdef DEBUG
uci1 84:80b15993944e 2621 printf("last loop close conn. i=%d, nc=%s\r\n",
uci1 84:80b15993944e 2622 (int32_t)i, (*nc) ? "true" : "false");
uci1 28:484943132bb0 2623 #endif
uci1 84:80b15993944e 2624
uci1 84:80b15993944e 2625 const uint32_t extraDiscTime = gLastCommWin
uci1 84:80b15993944e 2626 + gConf.GetCommWinConnectTO((*cw)->GetCommType());
uci1 84:80b15993944e 2627 (*cw)->CloseConn(gConf.GetTimeoutTime(extraDiscTime, gConf.GetCommWinDuration()));
uci1 84:80b15993944e 2628 *nc = false;
uci1 84:80b15993944e 2629 }
uci1 84:80b15993944e 2630 } // end loop: check time, close conns
uci1 40:1324da35afd4 2631
uci1 84:80b15993944e 2632 /*
uci1 40:1324da35afd4 2633 // close connections
uci1 40:1324da35afd4 2634 cw = gComms;
uci1 56:0bba0ef15697 2635 for (uint8_t i=0; i<kNcomms; ++i, ++cw) {
uci1 40:1324da35afd4 2636 if ((*cw)==0) {
uci1 40:1324da35afd4 2637 continue;
uci1 40:1324da35afd4 2638 } else {
uci1 40:1324da35afd4 2639 }
uci1 28:484943132bb0 2640 }
uci1 84:80b15993944e 2641 */
uci1 84:80b15993944e 2642
uci1 28:484943132bb0 2643 } // if duration >0
uci1 28:484943132bb0 2644
uci1 28:484943132bb0 2645 /* not working. must use DEFCONF.DAT to change IP's.
uci1 28:484943132bb0 2646 // change comm parameters (IP addresses)
uci1 28:484943132bb0 2647 #ifdef DEBUG
uci1 28:484943132bb0 2648 printf("set comm params\r\n");
uci1 28:484943132bb0 2649 #endif
uci1 28:484943132bb0 2650 for (uint8_t cc=0; cc<kNcomms; cc++) {
uci1 28:484943132bb0 2651 if (gComms[cc]!=0) {
uci1 28:484943132bb0 2652 gComms[cc]->Set(gConf);
uci1 15:f2569d8e4176 2653 }
uci1 0:664899e0b988 2654 }
uci1 28:484943132bb0 2655 */
uci1 40:1324da35afd4 2656
uci1 40:1324da35afd4 2657
uci1 40:1324da35afd4 2658 // check if we missed too many consecutive connections
uci1 40:1324da35afd4 2659 if (res<=SnCommWin::kAllFails) {
uci1 40:1324da35afd4 2660 ++gConsecCommFails;
uci1 40:1324da35afd4 2661 #ifdef DEBUG
uci1 56:0bba0ef15697 2662 printf("res=%d, gConsecCommFails=%hu, kMaxConsecCommFails=%hu\r\n",
uci1 56:0bba0ef15697 2663 static_cast<int>(res), gConsecCommFails,kMaxConsecCommFails);
uci1 40:1324da35afd4 2664 #endif
uci1 40:1324da35afd4 2665 if (gConsecCommFails>kMaxConsecCommFails) {
uci1 40:1324da35afd4 2666 #ifdef DEBUG
uci1 40:1324da35afd4 2667 printf("rebooting\r\n");
uci1 40:1324da35afd4 2668 #endif
uci1 40:1324da35afd4 2669 // goodbye cruel world, it's over. walk on by...
uci1 40:1324da35afd4 2670 mbed_reset();
uci1 40:1324da35afd4 2671 }
uci1 40:1324da35afd4 2672 } else {
uci1 40:1324da35afd4 2673 gConsecCommFails=0;
uci1 40:1324da35afd4 2674 }
uci1 28:484943132bb0 2675
uci1 4:a91682e19d6b 2676 // (probably) power down comms and power up cards,amps
uci1 84:80b15993944e 2677 SetPower(false, SnConfigFrame::kIrid | SnConfigFrame::kAfar);
uci1 4:a91682e19d6b 2678
uci1 1:e392595b4b76 2679 // reset config with system powered (for DAC/PLA setting)
uci1 12:d472f9811262 2680 #ifdef DEBUG
uci1 21:ce51bb0ba4a5 2681 printf("calling SetConfigAndMakeOutputFile\r\n");
uci1 12:d472f9811262 2682 #endif
uci1 76:f8383f0292c2 2683
uci1 76:f8383f0292c2 2684 if (gConf.IsRunSeqListOneCommWinOnly()) {
uci1 76:f8383f0292c2 2685 SnSDUtils::ClearRunSeqList(gConf.IsSendingFilesRunSeqList());
uci1 76:f8383f0292c2 2686 }
uci1 22:f957c4f840ad 2687
uci1 21:ce51bb0ba4a5 2688 SetConfigAndMakeOutputFile();
uci1 21:ce51bb0ba4a5 2689
uci1 56:0bba0ef15697 2690 // check power in case we should be in low power mode
uci1 56:0bba0ef15697 2691 // but don't save this reading to the file
uci1 56:0bba0ef15697 2692 // (there's already one near the beginning)
uci1 56:0bba0ef15697 2693 CheckPower(false, false);
uci1 56:0bba0ef15697 2694
uci1 12:d472f9811262 2695 #ifdef DEBUG
uci1 1:e392595b4b76 2696 printf("closing comm win at %d\r\n",(int32_t)time(0));
uci1 84:80b15993944e 2697 printf("Free memory = %d\r\n", FreeMem());
uci1 12:d472f9811262 2698 #endif
uci1 67:ec999336fcd1 2699
uci1 67:ec999336fcd1 2700 led2 = 0;
uci1 1:e392595b4b76 2701
uci1 0:664899e0b988 2702 gCommWinOpen = false;
uci1 0:664899e0b988 2703 return res;
uci1 0:664899e0b988 2704 }