Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Wed Jun 05 17:29:31 2019 +0000
Revision:
125:ce4045184366
Parent:
123:6267de54c8ba
Added SnRateListner proto-class, publishing this version of the code in order to enable exporting of most recent features.

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