Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

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

Who changed what in which revision?

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