Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Fri Nov 28 07:47:34 2014 +0000
Revision:
65:2cb3e99ce466
Parent:
63:4820a4460f00
Child:
67:ec999336fcd1
same as 64 but remove debug and enable safety nets

Who changed what in which revision?

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