Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Thu Nov 27 03:12:32 2014 +0000
Revision:
62:4b59c1eb429f
Parent:
61:42cbfc02e0e0
Child:
63:4820a4460f00
add debug to watchdog. set watchdog to config value at main() start

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 59:21128cc24b04 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 48:ee023b8807d8 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 56:0bba0ef15697 744 const int ret = sd.disk_initialize();
uci1 56:0bba0ef15697 745 #ifdef DEBUG
uci1 56:0bba0ef15697 746 printf("called disk_initialize (ret=%d)\r\n",ret);
uci1 56:0bba0ef15697 747 #endif
uci1 56:0bba0ef15697 748 return ret;
uci1 40:1324da35afd4 749 }
uci1 40:1324da35afd4 750
uci1 0:664899e0b988 751 int main() {
uci1 22:f957c4f840ad 752 // a failsafe
uci1 62:4b59c1eb429f 753 //Watchdog::kick(WDFAILSAFE);
uci1 62:4b59c1eb429f 754 #ifdef DEBUG
uci1 62:4b59c1eb429f 755 printf("Restart watchdog with time [%u]\r\n",
uci1 62:4b59c1eb429f 756 gConf.GetWatchdogPeriod());
uci1 62:4b59c1eb429f 757 #endif
uci1 62:4b59c1eb429f 758 Watchdog::kick(gConf.GetWatchdogPeriod());
uci1 56:0bba0ef15697 759
uci1 56:0bba0ef15697 760 gCpu.baud(CPUBAUD_SN);
uci1 56:0bba0ef15697 761
uci1 56:0bba0ef15697 762 // check in case we need to go to low power
uci1 56:0bba0ef15697 763 //wait(4); // TODO: the vADCs read high for first ~4-5sec
uci1 56:0bba0ef15697 764 CheckPower(false, false);
uci1 56:0bba0ef15697 765 #ifdef DEBUG
uci1 56:0bba0ef15697 766 printf("startup power: cards %d, amps %d, irid %d, afar %d\r\n",
uci1 56:0bba0ef15697 767 PIN_turn_on_system.read(), PIN_turn_on_amps.read(),
uci1 56:0bba0ef15697 768 PIN_iridSbd_power.read(), PIN_afar_power.read());
uci1 56:0bba0ef15697 769 #endif
uci1 27:efc4d654b139 770
uci1 1:e392595b4b76 771 {
uci1 18:55f1581f2ee4 772 #if defined(SSNOTIFY) || defined(DEBUG)
uci1 41:d6f5e2f09e07 773 printf("\n\n\n\n\nmain: start\r\n");
uci1 15:f2569d8e4176 774 #endif
uci1 40:1324da35afd4 775 #ifdef USE_RTOS
uci1 40:1324da35afd4 776 led1=1; Thread::wait(200);
uci1 40:1324da35afd4 777 led1=0; led2=1; Thread::wait(200);
uci1 40:1324da35afd4 778 led2=0; led3=1; Thread::wait(200);
uci1 40:1324da35afd4 779 led3=0; led4=1; Thread::wait(200);
uci1 40:1324da35afd4 780 #else
uci1 2:e67f7c158087 781 led1=1; wait(0.2);
uci1 2:e67f7c158087 782 led1=0; led2=1; wait(0.2);
uci1 2:e67f7c158087 783 led2=0; led3=1; wait(0.2);
uci1 2:e67f7c158087 784 led3=0; led4=1; wait(0.2);
uci1 56:0bba0ef15697 785 #endif // USE_RTOS
uci1 1:e392595b4b76 786 led4=0;
uci1 1:e392595b4b76 787 }
uci1 25:57b2627fe756 788
uci1 56:0bba0ef15697 789 // don't initialize yet, but give SnSDUtils a pointer to
uci1 56:0bba0ef15697 790 // the function that initializes it, so it can call the fcn later
uci1 40:1324da35afd4 791 SnSDUtils::fgDoInit = &InitSDCard;
uci1 56:0bba0ef15697 792
uci1 61:42cbfc02e0e0 793 /*
uci1 56:0bba0ef15697 794 // Note: the brownout isn't useful since it sees either 5V or nothing on our board
uci1 56:0bba0ef15697 795 // set up the brownout interrupt
uci1 56:0bba0ef15697 796 NVIC_SetVector(BOD_IRQn, (uint32_t)&UponBrownout);
uci1 56:0bba0ef15697 797 // Enable Brown Out Detect Interrupt
uci1 56:0bba0ef15697 798 NVIC_EnableIRQ(BOD_IRQn);
uci1 61:42cbfc02e0e0 799 */
uci1 56:0bba0ef15697 800
uci1 21:ce51bb0ba4a5 801 #ifdef DEBUG
uci1 18:55f1581f2ee4 802 printf("making comm objects\r\n");
uci1 18:55f1581f2ee4 803 #endif
uci1 25:57b2627fe756 804
uci1 25:57b2627fe756 805 uint8_t comi(0);
uci1 25:57b2627fe756 806 #ifdef ENABLE_AFAR_COMM
uci1 25:57b2627fe756 807 // RTOS stuff must be made inside main for some reason
uci1 18:55f1581f2ee4 808 #ifdef USE_ETH_INTERFACE
uci1 41:d6f5e2f09e07 809 #ifdef DEBUG
uci1 41:d6f5e2f09e07 810 printf("making SnCommAfarTCP\r\n");
uci1 41:d6f5e2f09e07 811 #endif
uci1 25:57b2627fe756 812 gComms[comi++] = new SnCommAfarTCP(gConf);
uci1 18:55f1581f2ee4 813 #else
uci1 41:d6f5e2f09e07 814 #ifdef DEBUG
uci1 41:d6f5e2f09e07 815 printf("making SnCommWinAfar\r\n");
uci1 41:d6f5e2f09e07 816 #endif
uci1 37:ff95e7070f26 817 //gComms[comi++] = new SnCommAfarNetIf(gConf);
uci1 37:ff95e7070f26 818 gComms[comi++] = new SnCommWinAfar(gConf);
uci1 28:484943132bb0 819 #ifdef ENABLE_AFAR_TWITTER
uci1 41:d6f5e2f09e07 820 #ifdef DEBUG
uci1 41:d6f5e2f09e07 821 printf("making SnCommAfarNetIfTwitter\r\n");
uci1 41:d6f5e2f09e07 822 #endif
uci1 28:484943132bb0 823 gTwit = new SnCommAfarNetIfTwitter(gConf);
uci1 56:0bba0ef15697 824 #endif // ENABLE_AFAR_TWITTER
uci1 56:0bba0ef15697 825 #endif // USE_ETH_INTERFACE
uci1 56:0bba0ef15697 826 #endif // ENABLE_AFAR_COMM
uci1 25:57b2627fe756 827 #ifdef ENABLE_SBD_COMM
uci1 41:d6f5e2f09e07 828 #ifdef DEBUG
uci1 41:d6f5e2f09e07 829 printf("making SnCommWinSBD\r\n");
uci1 41:d6f5e2f09e07 830 #endif
uci1 40:1324da35afd4 831 gComms[comi++] = new SnCommWinSBD(&gSBDport);
uci1 56:0bba0ef15697 832 #endif // ENABLE_SBD_COMM
uci1 25:57b2627fe756 833 #ifdef ENABLE_USB_COMM
uci1 41:d6f5e2f09e07 834 #ifdef DEBUG
uci1 41:d6f5e2f09e07 835 printf("makin SnCommWinUsb\r\n");
uci1 41:d6f5e2f09e07 836 #endif
uci1 37:ff95e7070f26 837 gComms[comi++] = new SnCommWinUsb(&gCpu);
uci1 56:0bba0ef15697 838 #endif // ENABLE_USB_COMM
uci1 18:55f1581f2ee4 839
uci1 18:55f1581f2ee4 840 #ifdef DEBUG
uci1 28:484943132bb0 841 printf("made comm objects\r\n");
uci1 41:d6f5e2f09e07 842 #ifdef USE_MODSERIAL
uci1 41:d6f5e2f09e07 843 printf("using MODSERIAL\r\n");
uci1 56:0bba0ef15697 844 #endif // USE_MODSERIAL
uci1 18:55f1581f2ee4 845 #endif
uci1 40:1324da35afd4 846
uci1 40:1324da35afd4 847 if (comi!=kNcomms) {
uci1 40:1324da35afd4 848 error("comi=[%hhu] != kNcomms=[%hhu]\r\n",
uci1 40:1324da35afd4 849 comi, kNcomms);
uci1 40:1324da35afd4 850 // will die here with blue lights of death
uci1 40:1324da35afd4 851 }
uci1 40:1324da35afd4 852
uci1 40:1324da35afd4 853 #ifdef USE_RTOS
uci1 8:95a325df1f6b 854 gForceTicker = new rtos::RtosTimer(&procForceTrigger);
uci1 8:95a325df1f6b 855 gHeartbeatTicker = new rtos::RtosTimer(&procHeartbeat);
uci1 8:95a325df1f6b 856 gCommWinTicker = new rtos::RtosTimer(&procCommWin);
uci1 8:95a325df1f6b 857 gPowerCheckTicker = new rtos::RtosTimer(&procPowerCheck);
uci1 56:0bba0ef15697 858 gTempCheckTicker = new rtos::RtosTimer(&procTempCheck);
uci1 56:0bba0ef15697 859 #endif // USE_RTOS
uci1 8:95a325df1f6b 860
uci1 0:664899e0b988 861 led2=1;
uci1 41:d6f5e2f09e07 862
uci1 1:e392595b4b76 863 // set the clock to the BS time, if it's not set
uci1 1:e392595b4b76 864 if ( (static_cast<int32_t>(time(0)))<0 ) {
uci1 1:e392595b4b76 865 set_time(kBStime);
uci1 1:e392595b4b76 866 }
uci1 12:d472f9811262 867 #ifdef DEBUG
uci1 1:e392595b4b76 868 printf("time = %d\r\n",(int32_t)time(0));
uci1 12:d472f9811262 869 #endif
uci1 1:e392595b4b76 870 gLastCommWin = time(0); // prevent comm win proc
uci1 0:664899e0b988 871
uci1 40:1324da35afd4 872 #ifdef USE_RTOS
uci1 8:95a325df1f6b 873 gForceTicker->stop();
uci1 8:95a325df1f6b 874 #else
uci1 0:664899e0b988 875 gForceTicker.detach();
uci1 56:0bba0ef15697 876 #endif // USE_RTOS
uci1 0:664899e0b988 877 gFirstEvt = true;
uci1 56:0bba0ef15697 878
uci1 4:a91682e19d6b 879 // (probably) power down comms and power up cards,amps
uci1 4:a91682e19d6b 880 SetPower(false);
uci1 56:0bba0ef15697 881 // check power again to see if voltages drooped
uci1 56:0bba0ef15697 882 CheckPower(false, false);
uci1 4:a91682e19d6b 883
uci1 0:664899e0b988 884 //
uci1 0:664899e0b988 885 // get config
uci1 0:664899e0b988 886 //
uci1 12:d472f9811262 887 #ifdef DEBUG
uci1 8:95a325df1f6b 888 printf("call OpenCommWin\r\n");
uci1 12:d472f9811262 889 #endif
uci1 40:1324da35afd4 890 OpenCommWin(true, true); // alwasy configure, even if no new config
uci1 3:24c5f0f50bf1 891
uci1 0:664899e0b988 892 // get ready to trigger
uci1 0:664899e0b988 893 PIN_spi.format( 16, 1 ); // change to data readout format
uci1 15:f2569d8e4176 894 PIN_spi.frequency( 10000000 ); // Max is 12.5 MHz
uci1 0:664899e0b988 895
uci1 0:664899e0b988 896 led2=0;
uci1 0:664899e0b988 897
uci1 41:d6f5e2f09e07 898 // read and cache the dCard power pin setting,
uci1 41:d6f5e2f09e07 899 // so we can use the cached value later
uci1 37:ff95e7070f26 900 AreCardsPowered(true); // TODO: should this be an if?
uci1 56:0bba0ef15697 901 register double etms=0; // time between written events
uci1 41:d6f5e2f09e07 902
uci1 41:d6f5e2f09e07 903 // the main event loop. wait for triggers in SendClock
uci1 41:d6f5e2f09e07 904 while ( true ) {
uci1 0:664899e0b988 905 // in here, we wait for triggers from the MB-FPGA
uci1 0:664899e0b988 906 Watchdog::kick(); // don't reset!
uci1 1:e392595b4b76 907
uci1 1:e392595b4b76 908 led1 = !led1;
uci1 1:e392595b4b76 909
uci1 12:d472f9811262 910 #ifdef DEBUG
uci1 1:e392595b4b76 911 printf("calling wait trig\r\n");
uci1 1:e392595b4b76 912 printf("gFirstEvt=%s\r\n",gFirstEvt?"true":"false");
uci1 5:9cea89700c66 913 printf("readingout=%d\r\n",(int)gReadingOut);
uci1 12:d472f9811262 914 #endif
uci1 40:1324da35afd4 915 if (gFirstEvt) {
uci1 41:d6f5e2f09e07 916 #ifdef DEBUG
uci1 41:d6f5e2f09e07 917 printf("WriteTrigWaitWinTime (start)\r\n");
uci1 41:d6f5e2f09e07 918 #endif
uci1 40:1324da35afd4 919 SnSDUtils::WriteTrigWaitWinTime(SnSDUtils::GetCurFile(),
uci1 40:1324da35afd4 920 gClkSet,
uci1 40:1324da35afd4 921 true);
uci1 40:1324da35afd4 922 gThmTrgTimer.reset(); gThmTrgTimer.start();
uci1 40:1324da35afd4 923 gAllTrgTimer.reset(); gAllTrgTimer.start();
uci1 56:0bba0ef15697 924 #if CHIPBOARD==SST4CH
uci1 56:0bba0ef15697 925 // reset in case a trigger arrived before we were ready
uci1 56:0bba0ef15697 926 // this is mostly to ensure that the chip gets reset on soft
uci1 56:0bba0ef15697 927 // reboot, in case it got stopped prior to the reboot
uci1 56:0bba0ef15697 928 PIN_ResetChips = 1;
uci1 56:0bba0ef15697 929 PIN_ResetChips = 0;
uci1 56:0bba0ef15697 930 #endif
uci1 40:1324da35afd4 931 }
uci1 56:0bba0ef15697 932 #if CHIPBOARD==ATWD4CH
uci1 56:0bba0ef15697 933 PIN_lockRegisters = 0; // allow data to come from DFPGA
uci1 56:0bba0ef15697 934 WaitTrigAndSendClock(); // wait for trigger and move data to MB. this returns immediately if cards are powered off
uci1 56:0bba0ef15697 935 PIN_lockRegisters = 1; // block registers during readout
uci1 56:0bba0ef15697 936 #else
uci1 56:0bba0ef15697 937 PIN_readingData = 0; // not reading yet
uci1 56:0bba0ef15697 938 WaitTrigAndSendClock(); // wait for trigger. this returns immediately if cards are powered off
uci1 56:0bba0ef15697 939 // PIN_readingData will be set high by SnEventFrame::ReadWaveformsSST
uci1 56:0bba0ef15697 940 #endif // ATWD4CH
uci1 12:d472f9811262 941 #ifdef EVT_TIME_PROFILE
uci1 12:d472f9811262 942 Timer prof;
uci1 12:d472f9811262 943 prof.start();
uci1 12:d472f9811262 944 int befReadWv=0, aftReadWv=0, befSaveEvt=0, aftSaveEvt=0,
uci1 12:d472f9811262 945 befChkPow=0, aftChkPow=0, befNewSeq=0, aftNewSeq=0, endOfLoop=0;
uci1 56:0bba0ef15697 946 #endif // EVT_TIME_PROFILE
uci1 12:d472f9811262 947
uci1 1:e392595b4b76 948 if (gReadingOut) {
uci1 56:0bba0ef15697 949 const double ttms = gThmTrgTimer.read_us() / 1e3; // for rate calculation
uci1 56:0bba0ef15697 950 const double atms = gAllTrgTimer.read_us() / 1e3; // for throttle
uci1 40:1324da35afd4 951 if (gEvent.IsForcedTrg()==false) {
uci1 40:1324da35afd4 952 // don't reset if not a thermal trigger
uci1 40:1324da35afd4 953 gThmTrgTimer.reset(); gThmTrgTimer.start();
uci1 40:1324da35afd4 954 }
uci1 40:1324da35afd4 955 gAllTrgTimer.reset(); gAllTrgTimer.start(); // restart trigger timer
uci1 40:1324da35afd4 956 etms += atms; // time between events
uci1 8:95a325df1f6b 957
uci1 8:95a325df1f6b 958 Watchdog::kick(); // don't reset!
uci1 15:f2569d8e4176 959
uci1 1:e392595b4b76 960 //
uci1 1:e392595b4b76 961 // got trigger. read registers to mbed and build the event
uci1 1:e392595b4b76 962 //
uci1 1:e392595b4b76 963
uci1 1:e392595b4b76 964 led4=1;
uci1 50:163ec8d88aa9 965
uci1 50:163ec8d88aa9 966 // TODO: no way to check for external trigger?
uci1 50:163ec8d88aa9 967 if (gEvent.IsForcedTrg()==false) {
uci1 50:163ec8d88aa9 968 gEvent.SetTrgBit(kThmTrg);
uci1 50:163ec8d88aa9 969 gEvent.SetTrgNum(++(gTrgNum[kThmTrg]));
uci1 50:163ec8d88aa9 970 AddToRate(ttms, true);
uci1 50:163ec8d88aa9 971 } // else already set by procForceTrigger
uci1 1:e392595b4b76 972
uci1 22:f957c4f840ad 973 if ( gEvent.IsForcedTrg() || gFirstEvt ||
uci1 56:0bba0ef15697 974 (etms>=gConf.GetEvtThrtlPeriodMs()) ) {
uci1 22:f957c4f840ad 975
uci1 22:f957c4f840ad 976 // read data & calc CRC
uci1 12:d472f9811262 977 #ifdef EVT_TIME_PROFILE
uci1 22:f957c4f840ad 978 prof.stop(); befReadWv=prof.read_us(); prof.start();
uci1 56:0bba0ef15697 979 #endif // EVT_TIME_PROFILE
uci1 12:d472f9811262 980
uci1 56:0bba0ef15697 981 #if CHIPBOARD==ATWD4CH
uci1 22:f957c4f840ad 982 // get the data to the MBED
uci1 56:0bba0ef15697 983 gEvent.ReadWaveformsATWD(PIN_spi, PIN_selCardHiBit, PIN_selCardLoBit);
uci1 56:0bba0ef15697 984 #else
uci1 56:0bba0ef15697 985 gEvent.ReadWaveformsSST(PIN_spi, PIN_readingData);
uci1 56:0bba0ef15697 986 // reset in case a trigger arrived before we were ready
uci1 56:0bba0ef15697 987 PIN_ResetChips = 1;
uci1 56:0bba0ef15697 988 // wait_us(1);
uci1 56:0bba0ef15697 989 PIN_ResetChips = 0;
uci1 56:0bba0ef15697 990 #endif //ATWD4CH
uci1 56:0bba0ef15697 991
uci1 12:d472f9811262 992 #ifdef EVT_TIME_PROFILE
uci1 22:f957c4f840ad 993 prof.stop(); aftReadWv=prof.read_us(); prof.start();
uci1 56:0bba0ef15697 994 #endif // EVT_TIME_PROFILE
uci1 12:d472f9811262 995
uci1 22:f957c4f840ad 996 gEvent.SetCurMbedTime();
uci1 22:f957c4f840ad 997
uci1 22:f957c4f840ad 998 Watchdog::kick(); // don't reset!
uci1 22:f957c4f840ad 999
uci1 12:d472f9811262 1000 #ifdef DEBUG
uci1 22:f957c4f840ad 1001 printf("gFirstEvt=%s\r\n",gFirstEvt?"true":"false");
uci1 12:d472f9811262 1002 #endif
uci1 1:e392595b4b76 1003
uci1 1:e392595b4b76 1004 led2=1;
uci1 22:f957c4f840ad 1005 /*
uci1 21:ce51bb0ba4a5 1006 gRecentCountTime = static_cast<uint32_t>(time(0));
uci1 21:ce51bb0ba4a5 1007 gRecentEvtNum = gEvtNum;
uci1 21:ce51bb0ba4a5 1008 // do start time second so that if we get only one event,
uci1 21:ce51bb0ba4a5 1009 // the delta(t) will be less than 0 and the rates not calculated
uci1 21:ce51bb0ba4a5 1010 if (gDoResetLastCount) {
uci1 21:ce51bb0ba4a5 1011 gLastCountReset = static_cast<uint32_t>(time(0)); // to calc rates
uci1 21:ce51bb0ba4a5 1012 gLastEventReset = gEvtNum;
uci1 21:ce51bb0ba4a5 1013 gDoResetLastCount = false;
uci1 21:ce51bb0ba4a5 1014 }
uci1 22:f957c4f840ad 1015 */
uci1 21:ce51bb0ba4a5 1016
uci1 56:0bba0ef15697 1017 #if CHIPBOARD==ATWD4CH
uci1 56:0bba0ef15697 1018 PIN_lockRegisters = 0; // done reading, unlock so we can talk to the SD card
uci1 56:0bba0ef15697 1019 #else
uci1 56:0bba0ef15697 1020 // (this is redundant; it's already set low by SnEventFrame)
uci1 56:0bba0ef15697 1021 PIN_readingData = 0; // done reading, unlock so we can talk to the SD card
uci1 56:0bba0ef15697 1022 #endif // ATWD4CH
uci1 1:e392595b4b76 1023
uci1 12:d472f9811262 1024 #ifdef EVT_TIME_PROFILE
uci1 12:d472f9811262 1025 prof.stop(); befSaveEvt=prof.read_us(); prof.start();
uci1 56:0bba0ef15697 1026 #endif // EVT_TIME_PROFILE
uci1 12:d472f9811262 1027
uci1 1:e392595b4b76 1028 SaveEvent(etms);
uci1 22:f957c4f840ad 1029 AddToRate(etms, false);
uci1 12:d472f9811262 1030 etms=0;
uci1 8:95a325df1f6b 1031
uci1 12:d472f9811262 1032 #ifdef EVT_TIME_PROFILE
uci1 12:d472f9811262 1033 prof.stop(); aftSaveEvt=prof.read_us(); prof.start();
uci1 56:0bba0ef15697 1034 #endif // EVT_TIME_PROFILE
uci1 56:0bba0ef15697 1035 } else {
uci1 56:0bba0ef15697 1036 #if CHIPBOARD==SST4CH
uci1 56:0bba0ef15697 1037 // reset in case a trigger arrived before we were ready
uci1 56:0bba0ef15697 1038 PIN_ResetChips = 1;
uci1 56:0bba0ef15697 1039 PIN_ResetChips = 0;
uci1 12:d472f9811262 1040 #endif
uci1 1:e392595b4b76 1041 }
uci1 1:e392595b4b76 1042 }
uci1 12:d472f9811262 1043 #ifdef DEBUG
uci1 1:e392595b4b76 1044 printf("past reading out\r\n");
uci1 12:d472f9811262 1045 #endif
uci1 1:e392595b4b76 1046
uci1 23:ccf39298f205 1047 if (gHrtbtFired) {
uci1 23:ccf39298f205 1048 SaveHeartbeat();
uci1 23:ccf39298f205 1049 gHrtbtFired=false;
uci1 23:ccf39298f205 1050 }
uci1 23:ccf39298f205 1051
uci1 1:e392595b4b76 1052 led4=0; led2=0;
uci1 12:d472f9811262 1053
uci1 12:d472f9811262 1054 #ifdef EVT_TIME_PROFILE
uci1 12:d472f9811262 1055 prof.stop(); befChkPow=prof.read_us(); prof.start();
uci1 56:0bba0ef15697 1056 #endif // EVT_TIME_PROFILE
uci1 8:95a325df1f6b 1057 // check the power?
uci1 8:95a325df1f6b 1058 if (gCheckPower) {
uci1 12:d472f9811262 1059 #ifdef DEBUG
uci1 8:95a325df1f6b 1060 printf("call check power\r\n");
uci1 12:d472f9811262 1061 #endif
uci1 8:95a325df1f6b 1062 CheckPower(false);
uci1 8:95a325df1f6b 1063 }
uci1 12:d472f9811262 1064 #ifdef EVT_TIME_PROFILE
uci1 12:d472f9811262 1065 prof.stop(); aftChkPow=prof.read_us(); prof.start();
uci1 56:0bba0ef15697 1066 #endif // EVT_TIME_PROFILE
uci1 56:0bba0ef15697 1067
uci1 56:0bba0ef15697 1068 if (gCheckTemp) {
uci1 56:0bba0ef15697 1069 #ifdef DEBUG
uci1 56:0bba0ef15697 1070 printf("call check temp\r\n");
uci1 12:d472f9811262 1071 #endif
uci1 56:0bba0ef15697 1072 CheckTemp();
uci1 56:0bba0ef15697 1073 }
uci1 8:95a325df1f6b 1074
uci1 21:ce51bb0ba4a5 1075 // open comm win?
uci1 21:ce51bb0ba4a5 1076 if (gOpenCommWin) {
uci1 21:ce51bb0ba4a5 1077 #ifdef DEBUG
uci1 21:ce51bb0ba4a5 1078 printf("gOpenComWin=%s, opening\r\n",gOpenCommWin?"true":"false");
uci1 41:d6f5e2f09e07 1079 printf("WriteTrigWaitWinTime (stop)\r\n");
uci1 21:ce51bb0ba4a5 1080 #endif
uci1 40:1324da35afd4 1081 SnSDUtils::WriteTrigWaitWinTime(SnSDUtils::GetCurFile(),
uci1 40:1324da35afd4 1082 gClkSet,
uci1 40:1324da35afd4 1083 false);
uci1 21:ce51bb0ba4a5 1084 OpenCommWin();
uci1 21:ce51bb0ba4a5 1085 gOpenCommWin=false;
uci1 22:f957c4f840ad 1086 gFirstEvt = true;
uci1 40:1324da35afd4 1087 gAllTrgTimer.reset();
uci1 40:1324da35afd4 1088 gThmTrgTimer.reset();
uci1 22:f957c4f840ad 1089 etms=0;
uci1 21:ce51bb0ba4a5 1090 } else {
uci1 21:ce51bb0ba4a5 1091 #ifdef DEBUG
uci1 27:efc4d654b139 1092 printf("gOpenCommWin=false, gCommWinChecks=%u, gNcommWinChecks=%u\r\n",
uci1 27:efc4d654b139 1093 gCommWinChecks, gNcommWinChecks);
uci1 21:ce51bb0ba4a5 1094 #endif
uci1 21:ce51bb0ba4a5 1095 }
uci1 21:ce51bb0ba4a5 1096
uci1 12:d472f9811262 1097 #ifdef EVT_TIME_PROFILE
uci1 12:d472f9811262 1098 prof.stop(); befNewSeq=prof.read_us(); prof.start();
uci1 56:0bba0ef15697 1099 #endif // EVT_TIME_PROFILE
uci1 8:95a325df1f6b 1100 // make new seq?
uci1 8:95a325df1f6b 1101 if (IsSeqComplete()) {
uci1 12:d472f9811262 1102 #ifdef DEBUG
uci1 10:3c93db1cfb12 1103 printf("seq complete. sngseq=%d\r\n",gConf.IsSingleSeqRunMode());
uci1 41:d6f5e2f09e07 1104 printf("WriteTrigWaitWinTime (stop)\r\n");
uci1 12:d472f9811262 1105 #endif
uci1 40:1324da35afd4 1106 SnSDUtils::WriteTrigWaitWinTime(SnSDUtils::GetCurFile(),
uci1 40:1324da35afd4 1107 gClkSet,
uci1 40:1324da35afd4 1108 false);
uci1 8:95a325df1f6b 1109 MakeOutputFile(gConf.IsSingleSeqRunMode());
uci1 22:f957c4f840ad 1110 gFirstEvt = true;
uci1 40:1324da35afd4 1111 gThmTrgTimer.reset();
uci1 40:1324da35afd4 1112 gAllTrgTimer.reset();
uci1 22:f957c4f840ad 1113 etms=0;
uci1 8:95a325df1f6b 1114 }
uci1 12:d472f9811262 1115 #ifdef EVT_TIME_PROFILE
uci1 12:d472f9811262 1116 prof.stop(); aftNewSeq=prof.read_us(); prof.start();
uci1 56:0bba0ef15697 1117 #endif // EVT_TIME_PROFILE
uci1 12:d472f9811262 1118
uci1 12:d472f9811262 1119 #ifdef EVT_TIME_PROFILE
uci1 12:d472f9811262 1120 prof.stop(); endOfLoop=prof.read_us(); prof.start();
uci1 12:d472f9811262 1121 printf("befReadWv=%d, aftReadWv=%d, befSaveEvt=%d, aftSaveEvt=%d, "
uci1 12:d472f9811262 1122 "befChkPow=%d, aftChkPow=%d, befNewSeq=%d, aftNewSeq=%d, endOfLoop=%d\r\n",
uci1 12:d472f9811262 1123 befReadWv, aftReadWv, befSaveEvt, aftSaveEvt,
uci1 12:d472f9811262 1124 befChkPow, aftChkPow, befNewSeq, aftNewSeq, endOfLoop);
uci1 56:0bba0ef15697 1125 #endif // EVT_TIME_PROFILE
uci1 41:d6f5e2f09e07 1126
uci1 41:d6f5e2f09e07 1127 /*
uci1 15:f2569d8e4176 1128 // get ready to trigger
uci1 15:f2569d8e4176 1129 PIN_spi.format( 16, 1 ); // change to data readout format
uci1 15:f2569d8e4176 1130 PIN_spi.frequency( 10000000 ); // Max is 12.5 MHz
uci1 41:d6f5e2f09e07 1131 */
uci1 22:f957c4f840ad 1132
uci1 21:ce51bb0ba4a5 1133 // reset event
uci1 22:f957c4f840ad 1134 // clear after comm win, so full event can be sent with status
uci1 22:f957c4f840ad 1135 // but don't clear counters or trigger bits, as
uci1 22:f957c4f840ad 1136 gEvent.ClearEvent(true);
uci1 21:ce51bb0ba4a5 1137
uci1 41:d6f5e2f09e07 1138 } // end while (true)
uci1 0:664899e0b988 1139
uci1 0:664899e0b988 1140 }
uci1 0:664899e0b988 1141
uci1 0:664899e0b988 1142 //
uci1 22:f957c4f840ad 1143 // save a heartbeat tag
uci1 22:f957c4f840ad 1144 //
uci1 22:f957c4f840ad 1145 void SaveHeartbeat() {
uci1 22:f957c4f840ad 1146 if (gHrtbtNum>0) {
uci1 22:f957c4f840ad 1147 #ifdef DEBUG
uci1 22:f957c4f840ad 1148 printf("save heartbeat #%u, time %u\r\n",
uci1 22:f957c4f840ad 1149 gHrtbtNum-1, gLastHrtbt);
uci1 22:f957c4f840ad 1150 #endif
uci1 22:f957c4f840ad 1151 // save to SD
uci1 56:0bba0ef15697 1152 #if CHIPBOARD==ATWD4CH
uci1 56:0bba0ef15697 1153 PIN_lockRegisters = 0; // unlock so we can talk to the SD card
uci1 56:0bba0ef15697 1154 #else
uci1 56:0bba0ef15697 1155 PIN_readingData = 0; // unlock so we can talk to the SD card
uci1 56:0bba0ef15697 1156 #endif
uci1 22:f957c4f840ad 1157 SnSDUtils::WriteHeartbeatTo(SnSDUtils::GetCurFile(),
uci1 22:f957c4f840ad 1158 gLastHrtbt, gHrtbtNum-1); // -1 so it counts from 0
uci1 22:f957c4f840ad 1159 }
uci1 22:f957c4f840ad 1160 }
uci1 22:f957c4f840ad 1161
uci1 22:f957c4f840ad 1162 //
uci1 0:664899e0b988 1163 // save the event
uci1 0:664899e0b988 1164 //
uci1 0:664899e0b988 1165 void SaveEvent(const int32_t etms) {
uci1 0:664899e0b988 1166 // write the event
uci1 12:d472f9811262 1167
uci1 12:d472f9811262 1168 #ifdef DEBUG
uci1 56:0bba0ef15697 1169 printf("save event (%u)\r\n", gEvtNum);
uci1 12:d472f9811262 1170 #endif
uci1 3:24c5f0f50bf1 1171
uci1 0:664899e0b988 1172 // set the event number & dt
uci1 3:24c5f0f50bf1 1173 gEvent.SetEvtNum(gEvtNum);
uci1 0:664899e0b988 1174 gEvent.SetDTms(etms);
uci1 0:664899e0b988 1175
uci1 0:664899e0b988 1176 // save to SD
uci1 56:0bba0ef15697 1177 #if CHIPBOARD==ATWD4CH
uci1 56:0bba0ef15697 1178 PIN_lockRegisters = 0; // unlock so we can talk to the SD card
uci1 56:0bba0ef15697 1179 #else
uci1 56:0bba0ef15697 1180 PIN_readingData = 0; // unlock so we can talk to the SD card
uci1 56:0bba0ef15697 1181 #endif
uci1 1:e392595b4b76 1182 SnSDUtils::WriteEventTo(SnSDUtils::GetCurFile(), gGenBuf, gEvent, gConf);
uci1 0:664899e0b988 1183
uci1 40:1324da35afd4 1184 // make a copy in case we need to send it with the status
uci1 40:1324da35afd4 1185 // (copy it because we are going to clear this event while
uci1 40:1324da35afd4 1186 // waiting for the next trigger)
uci1 40:1324da35afd4 1187 gEvent.CopyTo(gLastEvent);
uci1 40:1324da35afd4 1188
uci1 3:24c5f0f50bf1 1189 // increment event number
uci1 3:24c5f0f50bf1 1190 ++gEvtNum;
uci1 3:24c5f0f50bf1 1191
uci1 12:d472f9811262 1192 #ifdef DEBUG
uci1 8:95a325df1f6b 1193 printf("gEvtNum=%u\r\n",gEvtNum);
uci1 12:d472f9811262 1194 #endif
uci1 3:24c5f0f50bf1 1195 }
uci1 3:24c5f0f50bf1 1196
uci1 3:24c5f0f50bf1 1197 void MakeOutputFile(const bool stopRunning) {
uci1 56:0bba0ef15697 1198 #if CHIPBOARD==ATWD4CH
uci1 56:0bba0ef15697 1199 PIN_lockRegisters = 0; // unlock so we can talk to the SD card
uci1 56:0bba0ef15697 1200 #else
uci1 56:0bba0ef15697 1201 PIN_readingData = 0; // unlock so we can talk to the SD card
uci1 56:0bba0ef15697 1202 #endif
uci1 12:d472f9811262 1203 #ifdef DEBUG
uci1 10:3c93db1cfb12 1204 printf("closing output file. gEvtNum=%u, gPowNum=%u, stop=%d\r\n",
uci1 10:3c93db1cfb12 1205 gEvtNum,gPowNum,(int)stopRunning);
uci1 12:d472f9811262 1206 #endif
uci1 13:7a1fb885a8e4 1207
uci1 3:24c5f0f50bf1 1208 SnSDUtils::CloseOutputFile(SnSDUtils::GetCurFile());
uci1 13:7a1fb885a8e4 1209
uci1 12:d472f9811262 1210 #ifdef DEBUG
uci1 10:3c93db1cfb12 1211 printf("file closed\r\n");
uci1 12:d472f9811262 1212 #endif
uci1 3:24c5f0f50bf1 1213 if (stopRunning) {
uci1 8:95a325df1f6b 1214 StopRunning();
uci1 0:664899e0b988 1215 }
uci1 56:0bba0ef15697 1216 FILE* cf = SnSDUtils::OpenNewOutputFile(SnConfigFrame::GetMacAddress(),
uci1 40:1324da35afd4 1217 gConf.GetRun(),
uci1 40:1324da35afd4 1218 gConf.GetFirstSeq());
uci1 13:7a1fb885a8e4 1219 // reset event, timers, trigger counters
uci1 13:7a1fb885a8e4 1220 ResetCountersClearEvt();
uci1 8:95a325df1f6b 1221 if (cf!=0) {
uci1 40:1324da35afd4 1222 #ifdef USE_RTOS
uci1 40:1324da35afd4 1223 Thread::wait(200);
uci1 40:1324da35afd4 1224 #else
uci1 8:95a325df1f6b 1225 wait_ms(200);
uci1 40:1324da35afd4 1226 #endif
uci1 8:95a325df1f6b 1227 GetAvePowerReading();
uci1 12:d472f9811262 1228 #ifdef DEBUG
uci1 8:95a325df1f6b 1229 printf("writing power. v1=%g, v2=%g, r1=%g, r2=%g, t=%u, pownum=%u\r\n",
uci1 8:95a325df1f6b 1230 gPower.GetAveV1(), gPower.GetAveV2(),
uci1 8:95a325df1f6b 1231 gPower.GetRmsV1(), gPower.GetRmsV2(), gPower.GetTime(),
uci1 8:95a325df1f6b 1232 gPowNum);
uci1 12:d472f9811262 1233 #endif
uci1 8:95a325df1f6b 1234 SnSDUtils::WritePowerTo(cf, gPower, gPowNum);
uci1 8:95a325df1f6b 1235 }
uci1 12:d472f9811262 1236 #ifdef DEBUG
uci1 3:24c5f0f50bf1 1237 printf("made output file with run %u\r\n",gConf.GetRun());
uci1 3:24c5f0f50bf1 1238 printf("filename=%s\r\n",SnSDUtils::GetCurFileName());
uci1 12:d472f9811262 1239 #endif
uci1 3:24c5f0f50bf1 1240 SnSDUtils::WriteConfig(SnSDUtils::GetCurFile(), gConf);
uci1 19:74155d652c37 1241 #ifdef DEBUG
uci1 19:74155d652c37 1242 printf("write config to file\r\n");
uci1 19:74155d652c37 1243 #endif
uci1 0:664899e0b988 1244 }
uci1 0:664899e0b988 1245
uci1 40:1324da35afd4 1246 bool PowerDownCommPeriph(const SnConfigFrame::EDatPackBit type) {
uci1 40:1324da35afd4 1247
uci1 40:1324da35afd4 1248 SnCommWin** cw = gComms;
uci1 56:0bba0ef15697 1249 for (uint8_t i=0; i<kNcomms; ++i, ++cw) {
uci1 40:1324da35afd4 1250 if ((*cw)==0) {
uci1 40:1324da35afd4 1251 continue;
uci1 40:1324da35afd4 1252 } else if ((*cw)->GetCommType()==type) {
uci1 40:1324da35afd4 1253 return (*cw)->PowerDown(gConf.GetTimeoutTime(time(0),
uci1 40:1324da35afd4 1254 gConf.GetCommWinConnectTO()));
uci1 40:1324da35afd4 1255 }
uci1 40:1324da35afd4 1256 }
uci1 40:1324da35afd4 1257 return false;
uci1 40:1324da35afd4 1258 }
uci1 40:1324da35afd4 1259
uci1 0:664899e0b988 1260 //
uci1 4:a91682e19d6b 1261 // power stuff
uci1 4:a91682e19d6b 1262 //
uci1 4:a91682e19d6b 1263 void SetPower(const bool isCommWin) {
uci1 21:ce51bb0ba4a5 1264 #ifdef DEBUG
uci1 30:f869ed4bcc08 1265 printf("set power. isCommWin=%s\r\n",(isCommWin)?"true":"false");
uci1 21:ce51bb0ba4a5 1266 printf("bef: pconp=%u (%08x), pcenet=%u (%08x)\r\n",
uci1 21:ce51bb0ba4a5 1267 LPC_SC->PCONP, LPC_SC->PCONP, LPC1768_PCONP_PCENET, LPC1768_PCONP_PCENET);
uci1 21:ce51bb0ba4a5 1268 printf("pcenet bef power: status=%d\r\n",Peripheral_GetStatus(LPC1768_PCONP_PCENET));
uci1 61:42cbfc02e0e0 1269 printf("WD reset = %d\r\n",(int)Watchdog::didWatchdogReset());
uci1 21:ce51bb0ba4a5 1270 #endif
uci1 30:f869ed4bcc08 1271
uci1 30:f869ed4bcc08 1272 SnConfigFrame::EPowerModeBit cardpb(SnConfigFrame::kCardDatTak),
uci1 30:f869ed4bcc08 1273 ampspb(SnConfigFrame::kAmpsDatTak),
uci1 30:f869ed4bcc08 1274 iridpb(SnConfigFrame::kIridDatTak),
uci1 30:f869ed4bcc08 1275 afarpb(SnConfigFrame::kAfarDatTak);
uci1 4:a91682e19d6b 1276 if (isCommWin) {
uci1 30:f869ed4bcc08 1277 cardpb = SnConfigFrame::kCardComWin;
uci1 30:f869ed4bcc08 1278 ampspb = SnConfigFrame::kAmpsComWin;
uci1 30:f869ed4bcc08 1279 iridpb = SnConfigFrame::kIridComWin;
uci1 30:f869ed4bcc08 1280 afarpb = SnConfigFrame::kAfarComWin;
uci1 30:f869ed4bcc08 1281 }
uci1 30:f869ed4bcc08 1282 // TODO: turn on amps individually, when that's possible
uci1 40:1324da35afd4 1283
uci1 40:1324da35afd4 1284 // change cards power
uci1 40:1324da35afd4 1285 #ifdef DEBUG
uci1 40:1324da35afd4 1286 printf("setting cards pin power\r\n");
uci1 40:1324da35afd4 1287 #endif
uci1 30:f869ed4bcc08 1288 PIN_turn_on_system = gConf.GetPowPinSetting(cardpb);
uci1 40:1324da35afd4 1289 #ifdef USE_RTOS
uci1 40:1324da35afd4 1290 Thread::wait(10);
uci1 40:1324da35afd4 1291 #else
uci1 30:f869ed4bcc08 1292 wait_ms(10);
uci1 40:1324da35afd4 1293 #endif
uci1 40:1324da35afd4 1294 // change amps power
uci1 40:1324da35afd4 1295 #ifdef DEBUG
uci1 40:1324da35afd4 1296 printf("setting amps pin power\r\n");
uci1 40:1324da35afd4 1297 #endif
uci1 30:f869ed4bcc08 1298 PIN_turn_on_amps = gConf.GetPowPinSetting(ampspb);
uci1 40:1324da35afd4 1299 #ifdef USE_RTOS
uci1 40:1324da35afd4 1300 Thread::wait(10);
uci1 40:1324da35afd4 1301 #else
uci1 30:f869ed4bcc08 1302 wait_ms(10);
uci1 40:1324da35afd4 1303 #endif
uci1 40:1324da35afd4 1304 // change iridium power
uci1 40:1324da35afd4 1305 // power down periph if going from on to off
uci1 40:1324da35afd4 1306 const bool iridToOn = (kIridPwrFromAfar) ?
uci1 40:1324da35afd4 1307 gConf.IsPoweredFor(afarpb) :
uci1 40:1324da35afd4 1308 gConf.IsPoweredFor(iridpb);
uci1 40:1324da35afd4 1309 const bool iridFromOn = PIN_iridSbd_power.read()==
uci1 40:1324da35afd4 1310 (kIridPwrFromAfar ? gConf.GetPowPinSetting(afarpb, true)
uci1 40:1324da35afd4 1311 : gConf.GetPowPinSetting(iridpb, true));
uci1 40:1324da35afd4 1312 if ( iridFromOn && (iridToOn==false) ) {
uci1 40:1324da35afd4 1313 #ifdef DEBUG
uci1 40:1324da35afd4 1314 printf("calling PowerDown for Iridium\r\n");
uci1 40:1324da35afd4 1315 #endif
uci1 40:1324da35afd4 1316 PowerDownCommPeriph(SnConfigFrame::kIrid);
uci1 40:1324da35afd4 1317 }
uci1 40:1324da35afd4 1318 #ifdef DEBUG
uci1 40:1324da35afd4 1319 printf("setting iridium pin power\r\n");
uci1 40:1324da35afd4 1320 #endif
uci1 40:1324da35afd4 1321 PIN_iridSbd_power = (kIridPwrFromAfar)
uci1 30:f869ed4bcc08 1322 ? gConf.GetPowPinSetting(iridpb, false) // leave the iridium relay off. use afar relay.
uci1 30:f869ed4bcc08 1323 : gConf.GetPowPinSetting(iridpb);
uci1 40:1324da35afd4 1324 #ifdef USE_RTOS
uci1 40:1324da35afd4 1325 Thread::wait(10);
uci1 40:1324da35afd4 1326 #else
uci1 30:f869ed4bcc08 1327 wait_ms(10);
uci1 40:1324da35afd4 1328 #endif
uci1 40:1324da35afd4 1329 // change ethernet PHY port power
uci1 21:ce51bb0ba4a5 1330 #ifdef DEBUG
uci1 30:f869ed4bcc08 1331 printf("afar pin=%d, com powsetting=%d\r\n",PIN_afar_power.read(),
uci1 30:f869ed4bcc08 1332 gConf.GetPowPinSetting(afarpb));
uci1 21:ce51bb0ba4a5 1333 #endif
uci1 40:1324da35afd4 1334 if (gConf.IsPoweredFor(afarpb) ||
uci1 40:1324da35afd4 1335 (kIridPwrFromAfar && gConf.IsPoweredFor(iridpb)) ) {
uci1 21:ce51bb0ba4a5 1336 #ifdef DEBUG
uci1 30:f869ed4bcc08 1337 printf("PHY cowin powering up\r\n");
uci1 21:ce51bb0ba4a5 1338 #endif
uci1 40:1324da35afd4 1339 PHY_PowerUp();
uci1 40:1324da35afd4 1340 #ifdef USE_RTOS
uci1 40:1324da35afd4 1341 Thread::wait(1000);
uci1 40:1324da35afd4 1342 #else
uci1 40:1324da35afd4 1343 wait(1);
uci1 40:1324da35afd4 1344 #endif
uci1 21:ce51bb0ba4a5 1345 #ifdef DEBUG
uci1 30:f869ed4bcc08 1346 printf("PHY cowin powered up\r\n");
uci1 21:ce51bb0ba4a5 1347 #endif
uci1 4:a91682e19d6b 1348 } else {
uci1 40:1324da35afd4 1349 // change afar power
uci1 40:1324da35afd4 1350 // power down periph if going from on to off
uci1 40:1324da35afd4 1351 // change afar power
uci1 40:1324da35afd4 1352 int afon = gConf.GetPowPinSetting(afarpb, true);
uci1 40:1324da35afd4 1353 if (kIridPwrFromAfar) {
uci1 40:1324da35afd4 1354 // NOTE: the following only works because for the
uci1 40:1324da35afd4 1355 // irid & afar pins, 1 = on!
uci1 40:1324da35afd4 1356 afon |= gConf.GetPowPinSetting(iridpb, true);
uci1 40:1324da35afd4 1357 }
uci1 40:1324da35afd4 1358 const bool afarFromOn = (PIN_afar_power.read()==afon);
uci1 40:1324da35afd4 1359 if (afarFromOn) {
uci1 40:1324da35afd4 1360 PowerDownCommPeriph(SnConfigFrame::kAfar);
uci1 40:1324da35afd4 1361 }
uci1 21:ce51bb0ba4a5 1362 #ifdef DEBUG
uci1 30:f869ed4bcc08 1363 printf("PHY cowin powering down\r\n");
uci1 21:ce51bb0ba4a5 1364 #endif
uci1 40:1324da35afd4 1365 PHY_PowerDown();
uci1 40:1324da35afd4 1366 #ifdef USE_RTOS
uci1 40:1324da35afd4 1367 Thread::wait(1000);
uci1 40:1324da35afd4 1368 #else
uci1 40:1324da35afd4 1369 wait(1);
uci1 40:1324da35afd4 1370 #endif
uci1 21:ce51bb0ba4a5 1371 #ifdef DEBUG
uci1 30:f869ed4bcc08 1372 printf("PHY cowin powered down\r\n");
uci1 21:ce51bb0ba4a5 1373 #endif
uci1 30:f869ed4bcc08 1374 }
uci1 21:ce51bb0ba4a5 1375 #ifdef DEBUG
uci1 30:f869ed4bcc08 1376 printf("PHY done\r\n");
uci1 21:ce51bb0ba4a5 1377 #endif
uci1 40:1324da35afd4 1378 #ifdef USE_RTOS
uci1 40:1324da35afd4 1379 Thread::wait(100);
uci1 40:1324da35afd4 1380 #else
uci1 30:f869ed4bcc08 1381 wait_ms(100);
uci1 40:1324da35afd4 1382 #endif
uci1 40:1324da35afd4 1383 // change afar power
uci1 30:f869ed4bcc08 1384 int afpp = gConf.GetPowPinSetting(afarpb);
uci1 40:1324da35afd4 1385 if (kIridPwrFromAfar) {
uci1 40:1324da35afd4 1386 // NOTE: the following only works because for the
uci1 40:1324da35afd4 1387 // irid & afar pins, 1 = on!
uci1 30:f869ed4bcc08 1388 afpp |= gConf.GetPowPinSetting(iridpb);
uci1 4:a91682e19d6b 1389 }
uci1 30:f869ed4bcc08 1390 PIN_afar_power = afpp;
uci1 40:1324da35afd4 1391 #ifdef USE_RTOS
uci1 40:1324da35afd4 1392 Thread::wait(1500);
uci1 40:1324da35afd4 1393 #else
uci1 40:1324da35afd4 1394 wait(1.5);
uci1 40:1324da35afd4 1395 #endif
uci1 12:d472f9811262 1396 #ifdef DEBUG
uci1 21:ce51bb0ba4a5 1397 printf("aft: pconp=%u (%08x), pcenet=%u (%08x)\r\n",
uci1 21:ce51bb0ba4a5 1398 LPC_SC->PCONP, LPC_SC->PCONP, LPC1768_PCONP_PCENET, LPC1768_PCONP_PCENET);
uci1 21:ce51bb0ba4a5 1399 #endif
uci1 21:ce51bb0ba4a5 1400 #ifdef DEBUG
uci1 16:744ce85aede2 1401 printf("power word (%hhu): ",gConf.GetPowerMode()); SnBitUtils::printBits(gConf.GetPowerMode(),true);
uci1 6:6f002d202f59 1402 printf("set power (iscom %d, pw %hhu): cards %d, amps %d, irid %d, afar %d\r\n",
uci1 6:6f002d202f59 1403 isCommWin, gConf.GetPowerMode(), PIN_turn_on_system.read(), PIN_turn_on_amps.read(),
uci1 6:6f002d202f59 1404 PIN_iridSbd_power.read(), PIN_afar_power.read());
uci1 21:ce51bb0ba4a5 1405 printf("pcenet aft power: status=%d\r\n",Peripheral_GetStatus(LPC1768_PCONP_PCENET));
uci1 12:d472f9811262 1406 #endif
uci1 4:a91682e19d6b 1407 }
uci1 4:a91682e19d6b 1408
uci1 4:a91682e19d6b 1409 //
uci1 0:664899e0b988 1410 // set configuration
uci1 0:664899e0b988 1411 //
uci1 1:e392595b4b76 1412 void SetConfigAndMakeOutputFile() {
uci1 12:d472f9811262 1413 #ifdef DEBUG
uci1 1:e392595b4b76 1414 printf("SetConfigAndMakeOutputFile\r\n");
uci1 12:d472f9811262 1415 #endif
uci1 1:e392595b4b76 1416
uci1 0:664899e0b988 1417 // restart watchdog
uci1 62:4b59c1eb429f 1418 #ifdef DEBUG
uci1 62:4b59c1eb429f 1419 printf("Restart watchdog with time [%u]\r\n",
uci1 62:4b59c1eb429f 1420 gConf.GetWatchdogPeriod());
uci1 62:4b59c1eb429f 1421 #endif
uci1 0:664899e0b988 1422 Watchdog::kick(gConf.GetWatchdogPeriod());
uci1 0:664899e0b988 1423
uci1 1:e392595b4b76 1424 // block (thermal) triggers during configuration
uci1 1:e392595b4b76 1425 PIN_enableThermTrig = 0;
uci1 56:0bba0ef15697 1426 #if CHIPBOARD==ATWD4CH
uci1 1:e392595b4b76 1427 PIN_ADC_CS = 1;
uci1 1:e392595b4b76 1428 PIN_DoNotRestartAllClocks = 1;
uci1 56:0bba0ef15697 1429 #endif
uci1 1:e392595b4b76 1430 PIN_forceTrigger = 0;
uci1 3:24c5f0f50bf1 1431 PIN_heartbeat = 0;
uci1 40:1324da35afd4 1432 #ifdef USE_RTOS
uci1 40:1324da35afd4 1433 Thread::wait(20);
uci1 40:1324da35afd4 1434 #else
uci1 1:e392595b4b76 1435 wait_ms(20);
uci1 40:1324da35afd4 1436 #endif
uci1 1:e392595b4b76 1437
uci1 22:f957c4f840ad 1438 gCommWinChecks = 0;
uci1 22:f957c4f840ad 1439 gNcommWinChecks = gConf.GetCommWinPeriod() / kCommWinLongPrdTk;
uci1 22:f957c4f840ad 1440
uci1 21:ce51bb0ba4a5 1441 if (AreCardsPowered(true)) {
uci1 8:95a325df1f6b 1442 // Set PLA value(s)
uci1 56:0bba0ef15697 1443 PIN_spi.format( 16, 0 ); // change mode for DAC & PLA value setting (with ATWD4CH)
uci1 8:95a325df1f6b 1444 PIN_spi.frequency(1000000);
uci1 8:95a325df1f6b 1445 PIN_MajLogHiBit=1;
uci1 8:95a325df1f6b 1446 PIN_MajLogLoBit=1;
uci1 8:95a325df1f6b 1447 PIN_enableThermTrig=0;
uci1 0:664899e0b988 1448
uci1 56:0bba0ef15697 1449 #if CHIPBOARD==ATWD4CH
uci1 8:95a325df1f6b 1450 uint16_t hi, lo;
uci1 8:95a325df1f6b 1451 PIN_PLA_cs=1;
uci1 40:1324da35afd4 1452 #ifdef USE_RTOS
uci1 40:1324da35afd4 1453 Thread::wait(4000);
uci1 40:1324da35afd4 1454 #else
uci1 8:95a325df1f6b 1455 wait(4);
uci1 40:1324da35afd4 1456 #endif
uci1 56:0bba0ef15697 1457 for (uint8_t pi=0; pi<kNplas; ++pi) {
uci1 8:95a325df1f6b 1458 if (pi < gConf.GetNumPlas()) {
uci1 8:95a325df1f6b 1459 SnConfigFrame::GetHiLoPlas(gConf.GetPla(pi), hi, lo);
uci1 8:95a325df1f6b 1460 PIN_spi.write(hi);
uci1 8:95a325df1f6b 1461 PIN_spi.write(lo);
uci1 12:d472f9811262 1462 #ifdef DEBUG
uci1 8:95a325df1f6b 1463 printf("pla hi %hu, lo %hu\r\n",hi,lo);
uci1 12:d472f9811262 1464 #endif
uci1 8:95a325df1f6b 1465 } else {
uci1 8:95a325df1f6b 1466 PIN_spi.write(kNoTrigPla); // hi
uci1 8:95a325df1f6b 1467 PIN_spi.write(kNoTrigPla); // lo
uci1 12:d472f9811262 1468 #ifdef DEBUG
uci1 8:95a325df1f6b 1469 printf("pla hi %hu, lo %hu\r\n",kNoTrigPla,kNoTrigPla);
uci1 12:d472f9811262 1470 #endif
uci1 8:95a325df1f6b 1471 }
uci1 8:95a325df1f6b 1472 Watchdog::kick();
uci1 0:664899e0b988 1473 }
uci1 40:1324da35afd4 1474 #ifdef USE_RTOS
uci1 40:1324da35afd4 1475 Thread::wait(3000);
uci1 40:1324da35afd4 1476 #else
uci1 8:95a325df1f6b 1477 wait(3);
uci1 40:1324da35afd4 1478 #endif
uci1 8:95a325df1f6b 1479 PIN_PLA_cs=0;
uci1 40:1324da35afd4 1480 #ifdef USE_RTOS
uci1 40:1324da35afd4 1481 Thread::wait(3000);
uci1 40:1324da35afd4 1482 #else
uci1 8:95a325df1f6b 1483 wait(3);
uci1 40:1324da35afd4 1484 #endif
uci1 0:664899e0b988 1485
uci1 56:0bba0ef15697 1486
uci1 8:95a325df1f6b 1487 // DAC values
uci1 8:95a325df1f6b 1488 //
uci1 8:95a325df1f6b 1489 // first 12 bits = DAC value
uci1 8:95a325df1f6b 1490 // next 2 bits = DAC ID
uci1 8:95a325df1f6b 1491 // last 2 bits = dFPGA ID
uci1 8:95a325df1f6b 1492 //
uci1 8:95a325df1f6b 1493 // But FPGA uses "gray encoding" which means only 1 bit
uci1 8:95a325df1f6b 1494 // can change at a time (of the last 4 bits). So even tho
uci1 8:95a325df1f6b 1495 // the card/dac# is encoded, the order is also important
uci1 8:95a325df1f6b 1496 // 0000 (dac0,card0), 0001 (dac0,card1), 0011 (dac0,card3), 0010 (dac0,card2),
uci1 8:95a325df1f6b 1497 // 0110 (dac1,card2), 0111 (dac1,card3), 0101 (dac1,card1), etc.
uci1 12:d472f9811262 1498 #ifdef DEBUG
uci1 8:95a325df1f6b 1499 printf("setting dacs\r\n");
uci1 12:d472f9811262 1500 #endif
uci1 8:95a325df1f6b 1501 uint16_t dv=0;
uci1 56:0bba0ef15697 1502 for (uint8_t i=0, gri=0; i<kTotDacs; ++i) {
uci1 8:95a325df1f6b 1503 // get the gray-codes for this iteration
uci1 8:95a325df1f6b 1504 gri = SnBitUtils::binToGray(i);
uci1 8:95a325df1f6b 1505
uci1 8:95a325df1f6b 1506 // build bit word
uci1 8:95a325df1f6b 1507 dv = static_cast<int>(gConf.GetDac(gri & 0x0003u, gri >> 2u));
uci1 8:95a325df1f6b 1508 dv <<= 4u;
uci1 8:95a325df1f6b 1509 dv |= gri;
uci1 8:95a325df1f6b 1510
uci1 12:d472f9811262 1511 #ifdef DEBUG
uci1 8:95a325df1f6b 1512 printf("dac %04x\r\n",dv);
uci1 12:d472f9811262 1513 #endif
uci1 8:95a325df1f6b 1514
uci1 8:95a325df1f6b 1515 // send to FPGA
uci1 8:95a325df1f6b 1516 PIN_start_fpga=1;
uci1 8:95a325df1f6b 1517 PIN_spi.write(dv);
uci1 8:95a325df1f6b 1518 PIN_start_fpga=0;
uci1 8:95a325df1f6b 1519
uci1 8:95a325df1f6b 1520 Watchdog::kick();
uci1 8:95a325df1f6b 1521
uci1 8:95a325df1f6b 1522 }
uci1 56:0bba0ef15697 1523 #else // SST
uci1 56:0bba0ef15697 1524
uci1 56:0bba0ef15697 1525 // set and/or & differential pins
uci1 56:0bba0ef15697 1526
uci1 56:0bba0ef15697 1527 // set DACs via I2C
uci1 56:0bba0ef15697 1528
uci1 56:0bba0ef15697 1529 uint16_t dv=0;
uci1 56:0bba0ef15697 1530 uint8_t dn=0;
uci1 56:0bba0ef15697 1531 uint8_t cmdAndDac[3];
uci1 56:0bba0ef15697 1532 for (uint8_t ch=0; ch<kNchans; ++ch) {
uci1 56:0bba0ef15697 1533 for (uint8_t dc=0; dc<kNchanDacs; ++dc) {
uci1 56:0bba0ef15697 1534 // for (uint16_t dc=kNchanDacs-1; dc>=0; --dc) { // first all the highs, then the lows
uci1 56:0bba0ef15697 1535 // for (int16_t ch=kNchans-1; ch>=0; --ch) { // chans in reverse order
uci1 56:0bba0ef15697 1536 bool dok = false;
uci1 56:0bba0ef15697 1537 for (uint8_t tries = 0; (tries<kMaxDacSetTries) && (dok==false); ++tries) {
uci1 56:0bba0ef15697 1538 #ifdef DEBUG
uci1 56:0bba0ef15697 1539 printf("start i2c for dc=%hhu, ch=%hhu, try=%hhu, dok=%s\r\n",
uci1 56:0bba0ef15697 1540 dc, ch, tries, (dok ? "true" : "false"));
uci1 56:0bba0ef15697 1541 printf("address 0x%hhx (%hhd) ", kAllLTC2657, kAllLTC2657);
uci1 56:0bba0ef15697 1542 SnBitUtils::printBits(kAllLTC2657, true);
uci1 56:0bba0ef15697 1543 #endif
uci1 56:0bba0ef15697 1544 // build data to send
uci1 56:0bba0ef15697 1545 // blame the engineers for this bizzare mapping from
uci1 56:0bba0ef15697 1546 // chan, threshold -> DAC number
uci1 56:0bba0ef15697 1547 dn = (kTotDacs-1)-(dc*kNchans)-ch;
uci1 56:0bba0ef15697 1548 if (dn>7) { // invalid code for LTC2657 dac chip
uci1 56:0bba0ef15697 1549 error("chan/dac combination too big for 3 bits!");
uci1 56:0bba0ef15697 1550 }
uci1 56:0bba0ef15697 1551 dn |= (kUpdateDacCmd<<4); // prefix with update DAC value command
uci1 56:0bba0ef15697 1552 #ifdef DEBUG
uci1 56:0bba0ef15697 1553 printf("dn=%hhu ", dn);
uci1 56:0bba0ef15697 1554 SnBitUtils::printBits(dn, true);
uci1 56:0bba0ef15697 1555 #endif
uci1 56:0bba0ef15697 1556 dv = (gConf.GetDac(ch, dc)) << 4; // put 0's at the end (12 bits of num then 4 zero bits)
uci1 56:0bba0ef15697 1557 #ifdef DEBUG
uci1 56:0bba0ef15697 1558 printf("dv=%hu\r\n",dv);
uci1 56:0bba0ef15697 1559 printf("ch=%hhu, dc=%hhu, dac=%hu\r\n",ch,dc,gConf.GetDac(ch,dc));
uci1 56:0bba0ef15697 1560 #endif
uci1 56:0bba0ef15697 1561 // mbed i2c.write seems to send it "backwards" from a (low endian) bit
uci1 56:0bba0ef15697 1562 // point of view.. i guess it's forwards from an intuitive pov?
uci1 56:0bba0ef15697 1563 cmdAndDac[0] = dn;
uci1 56:0bba0ef15697 1564 cmdAndDac[1] = (dv & 0xFF00u) >> 8; // 8 MSBs of 12 bit num first
uci1 56:0bba0ef15697 1565 cmdAndDac[2] = (dv & 0x00FFu); // 4 LSBs of 12 bit num followed by 4 zeros
uci1 56:0bba0ef15697 1566
uci1 56:0bba0ef15697 1567 #ifdef DEBUG
uci1 56:0bba0ef15697 1568 printf("cmdAndDac[0]="); SnBitUtils::printBits(cmdAndDac[2],true);
uci1 56:0bba0ef15697 1569 printf("cmdAndDac[1]="); SnBitUtils::printBits(cmdAndDac[1],true);
uci1 56:0bba0ef15697 1570 printf("cmdAndDac[2]="); SnBitUtils::printBits(cmdAndDac[0],true);
uci1 56:0bba0ef15697 1571 #endif
uci1 56:0bba0ef15697 1572 // try to send it
uci1 56:0bba0ef15697 1573 // TODO: if no ACK, is just re-trying the whole thing good enough?
uci1 56:0bba0ef15697 1574 // TODO: assign correct slave address for the DAC chip (this is a global address)
uci1 56:0bba0ef15697 1575 dok = PIN_i2c.write(kAllLTC2657,
uci1 56:0bba0ef15697 1576 reinterpret_cast<char*>(cmdAndDac),
uci1 56:0bba0ef15697 1577 3*sizeof(uint8_t))==0;
uci1 56:0bba0ef15697 1578 } // end try loop
uci1 56:0bba0ef15697 1579 }
uci1 56:0bba0ef15697 1580 }
uci1 56:0bba0ef15697 1581
uci1 56:0bba0ef15697 1582 #endif // CHIPBOARD
uci1 56:0bba0ef15697 1583
uci1 12:d472f9811262 1584 #ifdef DEBUG
uci1 8:95a325df1f6b 1585 printf("dacs set\r\n");
uci1 12:d472f9811262 1586 #endif
uci1 40:1324da35afd4 1587 #ifdef USE_RTOS
uci1 40:1324da35afd4 1588 Thread::wait(20);
uci1 40:1324da35afd4 1589 #else
uci1 8:95a325df1f6b 1590 wait_ms(20);
uci1 40:1324da35afd4 1591 #endif
uci1 8:95a325df1f6b 1592 } else {
uci1 12:d472f9811262 1593 #ifdef DEBUG
uci1 8:95a325df1f6b 1594 printf("cards off. skipping PLA and DAC setting\r\n");
uci1 12:d472f9811262 1595 #endif
uci1 0:664899e0b988 1596 }
uci1 56:0bba0ef15697 1597
uci1 56:0bba0ef15697 1598 #if CHIPBOARD==SST4CH
uci1 56:0bba0ef15697 1599 // set the SST triggering run mode
uci1 56:0bba0ef15697 1600 PIN_dualOrSingleThresholds = gConf.IsDualThresholdMode();
uci1 56:0bba0ef15697 1601 PIN_differentialTrigSignal = gConf.IsDifferentialTrigMode();
uci1 56:0bba0ef15697 1602 #endif
uci1 0:664899e0b988 1603
uci1 0:664899e0b988 1604 // Majority Logic Trigger selection (# of cards)
uci1 0:664899e0b988 1605 SnBitUtils::SetChanNumBits(gConf.GetNumCardsMajLog() - 1u,
uci1 0:664899e0b988 1606 PIN_MajLogHiBit, PIN_MajLogLoBit);
uci1 0:664899e0b988 1607
uci1 0:664899e0b988 1608 // Enable thermal trigger?
uci1 0:664899e0b988 1609 PIN_enableThermTrig = gConf.IsThermTrigEnabled();
uci1 0:664899e0b988 1610
uci1 56:0bba0ef15697 1611 #if CHIPBOARD==SST4CH
uci1 56:0bba0ef15697 1612 InitTempProbe();
uci1 56:0bba0ef15697 1613 #endif
uci1 56:0bba0ef15697 1614
uci1 0:664899e0b988 1615 PIN_spi.format( 16, 1 ); // back to trigger mode
uci1 1:e392595b4b76 1616 PIN_spi.frequency( 10000000 ); // Max is 12.5 MHz
uci1 1:e392595b4b76 1617
uci1 8:95a325df1f6b 1618 // make new output file
uci1 8:95a325df1f6b 1619 // put after PLA/DAC, in case they affect the power readings
uci1 40:1324da35afd4 1620 #ifdef USE_RTOS
uci1 40:1324da35afd4 1621 Thread::wait(200);
uci1 40:1324da35afd4 1622 #else
uci1 8:95a325df1f6b 1623 wait_ms(200);
uci1 40:1324da35afd4 1624 #endif
uci1 8:95a325df1f6b 1625 MakeOutputFile();
uci1 8:95a325df1f6b 1626
uci1 21:ce51bb0ba4a5 1627 // reset tickers
uci1 21:ce51bb0ba4a5 1628 ResetAllTickers();
uci1 0:664899e0b988 1629
uci1 0:664899e0b988 1630 Watchdog::kick(); // don't reset!
uci1 8:95a325df1f6b 1631
uci1 12:d472f9811262 1632 #ifdef DEBUG
uci1 8:95a325df1f6b 1633 printf("set config done\r\n");
uci1 12:d472f9811262 1634 #endif
uci1 0:664899e0b988 1635 }
uci1 0:664899e0b988 1636
uci1 0:664899e0b988 1637 //
uci1 0:664899e0b988 1638 // readout functions
uci1 0:664899e0b988 1639 //
uci1 0:664899e0b988 1640 void WaitTrigAndSendClock() {
uci1 1:e392595b4b76 1641
uci1 12:d472f9811262 1642 #ifdef DEBUG
uci1 1:e392595b4b76 1643 printf("WaitTrigAndSendClock\r\n");
uci1 6:6f002d202f59 1644 printf("wait trig: (pw %hhu): cards %d, amps %d, irid %d, afar %d\r\n",
uci1 6:6f002d202f59 1645 gConf.GetPowerMode(), PIN_turn_on_system.read(), PIN_turn_on_amps.read(),
uci1 6:6f002d202f59 1646 PIN_iridSbd_power.read(), PIN_afar_power.read());
uci1 21:ce51bb0ba4a5 1647 printf("cards powered=%d\r\n",(int)AreCardsPowered(true));
uci1 12:d472f9811262 1648 #endif
uci1 15:f2569d8e4176 1649
uci1 21:ce51bb0ba4a5 1650 #ifdef DEBUG
uci1 41:d6f5e2f09e07 1651 printf("gFirstEvt=%s\r\n",gFirstEvt?"true":"false");
uci1 21:ce51bb0ba4a5 1652 #endif
uci1 41:d6f5e2f09e07 1653 if (AreCardsPowered(false)) {
uci1 41:d6f5e2f09e07 1654
uci1 41:d6f5e2f09e07 1655 PIN_spi.format( 16, 1 ); // back to trigger mode
uci1 41:d6f5e2f09e07 1656 PIN_spi.frequency( 10000000 ); // Max is 12.5 MHz
uci1 8:95a325df1f6b 1657
uci1 47:fbe956b10a91 1658 if (gFirstEvt==false) {
uci1 56:0bba0ef15697 1659 #if CHIPBOARD==ATWD4CH
uci1 47:fbe956b10a91 1660 PIN_DoNotRestartAllClocks = 0;
uci1 47:fbe956b10a91 1661 wait_us(1);
uci1 47:fbe956b10a91 1662 PIN_DoNotRestartAllClocks = 1;
uci1 56:0bba0ef15697 1663 #endif
uci1 47:fbe956b10a91 1664 //led3 = !led3; // toggle send clock led
uci1 47:fbe956b10a91 1665 } else {
uci1 47:fbe956b10a91 1666 gFirstEvt = false;
uci1 47:fbe956b10a91 1667 }
uci1 47:fbe956b10a91 1668
uci1 8:95a325df1f6b 1669 //
uci1 8:95a325df1f6b 1670 // wait for a trigger here.
uci1 8:95a325df1f6b 1671 //
uci1 12:d472f9811262 1672 #ifdef DEBUG
uci1 8:95a325df1f6b 1673 printf("starting wait for trig\r\n");
uci1 12:d472f9811262 1674 #endif
uci1 16:744ce85aede2 1675
uci1 8:95a325df1f6b 1676 gReadingOut = false; // this will allow forced triggers (see procForceTrigger())
uci1 56:0bba0ef15697 1677 #if CHIPBOARD==ATWD4CH
uci1 56:0bba0ef15697 1678 while ( PIN_a_sf_clk == 1 ) { // wait for trigger
uci1 56:0bba0ef15697 1679 #else
uci1 56:0bba0ef15697 1680 while ( PIN_dataReady==0 ) { // wait for data in mb fpga
uci1 56:0bba0ef15697 1681 #endif
uci1 56:0bba0ef15697 1682 if (gOpenCommWin || gCheckPower || gCheckTemp) {
uci1 12:d472f9811262 1683 #ifdef DEBUG
uci1 56:0bba0ef15697 1684 printf("break com=%d, pow=%d, tmp=%d\r\n",
uci1 56:0bba0ef15697 1685 gOpenCommWin,gCheckPower,gCheckTemp);
uci1 12:d472f9811262 1686 #endif
uci1 8:95a325df1f6b 1687 return; // break out to open comms or check power
uci1 8:95a325df1f6b 1688 }
uci1 0:664899e0b988 1689 }
uci1 8:95a325df1f6b 1690 gReadingOut = true; // disallow new forced triggers
uci1 56:0bba0ef15697 1691
uci1 15:f2569d8e4176 1692 // we can't be interrupted before data arrives at the MB FPGA
uci1 15:f2569d8e4176 1693 //StopAllTickers();
uci1 16:744ce85aede2 1694
uci1 23:ccf39298f205 1695 //wait_us(5);
uci1 56:0bba0ef15697 1696
uci1 56:0bba0ef15697 1697 #if CHIPBOARD==ATWD4CH
uci1 56:0bba0ef15697 1698 // ATWD
uci1 8:95a325df1f6b 1699 //
uci1 8:95a325df1f6b 1700 // collect data from daughter cards
uci1 8:95a325df1f6b 1701 //
uci1 8:95a325df1f6b 1702 // TODO: what if some card (set of channels) doesn't respond?
uci1 8:95a325df1f6b 1703 // currently, will wait forever?
uci1 8:95a325df1f6b 1704 // also, if ch1 is dead, will wait forever (due to FPGA code)
uci1 16:744ce85aede2 1705 gAdcToMBtimer.start();
uci1 56:0bba0ef15697 1706 for( uint16_t i = 0; i < kNsamps; ++i ) {
uci1 16:744ce85aede2 1707 while (PIN_a_sf_clk==1) {}
uci1 16:744ce85aede2 1708 while (PIN_a_sf_clk==0) {}
uci1 56:0bba0ef15697 1709
uci1 16:744ce85aede2 1710 PIN_ADC_CS = 0;
uci1 16:744ce85aede2 1711 PIN_spi.write( 0x00 );
uci1 16:744ce85aede2 1712 PIN_ADC_CS = 1;
uci1 0:664899e0b988 1713 }
uci1 16:744ce85aede2 1714 gAdcToMBtimer.stop();
uci1 16:744ce85aede2 1715 #ifdef DEBUG
uci1 16:744ce85aede2 1716 printf("total time = %d us\r\n", gAdcToMBtimer.read_us());
uci1 16:744ce85aede2 1717 #endif
uci1 16:744ce85aede2 1718 if ( kAdcToMBtimeCut < gAdcToMBtimer.read_us() ) {
uci1 16:744ce85aede2 1719 gEvent.SetTrgBit(kAdcToMBflag);
uci1 16:744ce85aede2 1720 }
uci1 16:744ce85aede2 1721 gAdcToMBtimer.reset();
uci1 15:f2569d8e4176 1722
uci1 56:0bba0ef15697 1723 #else
uci1 56:0bba0ef15697 1724 // For SST, data is already in the mb FPGA, so no need to do anything here
uci1 56:0bba0ef15697 1725 #endif
uci1 56:0bba0ef15697 1726
uci1 8:95a325df1f6b 1727 } else {
uci1 8:95a325df1f6b 1728 // cards have no power. don't try reading out
uci1 8:95a325df1f6b 1729 gReadingOut=false;
uci1 47:fbe956b10a91 1730 // set gFirstEvt to false even if cards are powered off.
uci1 47:fbe956b10a91 1731 // otherwise, if cards ARE powered off, it will always be
uci1 47:fbe956b10a91 1732 // true and the "start trigger" clock will be written continuously
uci1 47:fbe956b10a91 1733 gFirstEvt = false;
uci1 0:664899e0b988 1734 }
uci1 56:0bba0ef15697 1735
uci1 0:664899e0b988 1736 }
uci1 0:664899e0b988 1737
uci1 40:1324da35afd4 1738 bool IsPinPowered(const SnCommWin* cw) {
uci1 40:1324da35afd4 1739 bool havePower = false;
uci1 40:1324da35afd4 1740 switch (cw->GetCommType()) {
uci1 40:1324da35afd4 1741 case SnConfigFrame::kIrid:
uci1 40:1324da35afd4 1742 havePower = gConf.IsPoweredFor(SnConfigFrame::kIridComWin)
uci1 40:1324da35afd4 1743 && ( (kIridPwrFromAfar)
uci1 40:1324da35afd4 1744 ? PIN_afar_power.read()
uci1 40:1324da35afd4 1745 : PIN_iridSbd_power.read() ==
uci1 40:1324da35afd4 1746 gConf.GetPowPinSetting(SnConfigFrame::kIridComWin));
uci1 40:1324da35afd4 1747 break;
uci1 40:1324da35afd4 1748 case SnConfigFrame::kAfar:
uci1 40:1324da35afd4 1749 havePower = gConf.IsPoweredFor(SnConfigFrame::kAfarComWin)
uci1 40:1324da35afd4 1750 && (PIN_afar_power.read() ==
uci1 40:1324da35afd4 1751 gConf.GetPowPinSetting(SnConfigFrame::kAfarComWin));
uci1 40:1324da35afd4 1752 break;
uci1 40:1324da35afd4 1753 case SnConfigFrame::kUSB:
uci1 40:1324da35afd4 1754 havePower = true; // USB always on (for now)
uci1 40:1324da35afd4 1755 break;
uci1 40:1324da35afd4 1756 case SnConfigFrame::kSDcard: // shouldn't happen. skip it
uci1 40:1324da35afd4 1757 default: // unknown.. skip it
uci1 40:1324da35afd4 1758 break;
uci1 40:1324da35afd4 1759 };
uci1 40:1324da35afd4 1760 return havePower;
uci1 40:1324da35afd4 1761 }
uci1 40:1324da35afd4 1762
uci1 40:1324da35afd4 1763
uci1 40:1324da35afd4 1764 SnCommWin::ECommWinResult OpenCommWin(const bool forceReconfig,
uci1 40:1324da35afd4 1765 const bool isStartupWin) {
uci1 0:664899e0b988 1766 // loop through each comm mode:
uci1 0:664899e0b988 1767 // a) try to connect
uci1 0:664899e0b988 1768 // b) if connected, listen for config
uci1 0:664899e0b988 1769 // c) if config requests data, send it
uci1 16:744ce85aede2 1770 /*
uci1 16:744ce85aede2 1771 for (int i=0; i<5; i++) {
uci1 16:744ce85aede2 1772 led4=1;
uci1 16:744ce85aede2 1773 led3=1;
uci1 16:744ce85aede2 1774 wait(0.5);
uci1 16:744ce85aede2 1775 led4=0;
uci1 16:744ce85aede2 1776 led3=0;
uci1 16:744ce85aede2 1777 wait(0.5);
uci1 16:744ce85aede2 1778 }
uci1 16:744ce85aede2 1779 */
uci1 3:24c5f0f50bf1 1780 gLastCommWin = time(0);
uci1 13:7a1fb885a8e4 1781
uci1 0:664899e0b988 1782 SnCommWin::ECommWinResult res = SnCommWin::kUndefFail;
uci1 0:664899e0b988 1783
uci1 21:ce51bb0ba4a5 1784 // get the trigger rates
uci1 21:ce51bb0ba4a5 1785 float thmrate=0, evtrate=0;
uci1 21:ce51bb0ba4a5 1786 GetRates(thmrate, evtrate);
uci1 22:f957c4f840ad 1787 #ifdef DEBUG
uci1 56:0bba0ef15697 1788 printf("config=%s\r\n", gConf.GetLabel());
uci1 22:f957c4f840ad 1789 printf("thmrate=%g, evtrate=%g\r\n",thmrate,evtrate);
uci1 22:f957c4f840ad 1790 #endif
uci1 21:ce51bb0ba4a5 1791
uci1 21:ce51bb0ba4a5 1792 StopAllTickers();
uci1 40:1324da35afd4 1793
uci1 13:7a1fb885a8e4 1794 if (gConf.GetCommWinDuration()==0) {
uci1 13:7a1fb885a8e4 1795 // TODO: set min so this is not possible
uci1 13:7a1fb885a8e4 1796 res = SnCommWin::kOkNoMsg;
uci1 13:7a1fb885a8e4 1797 } else {
uci1 13:7a1fb885a8e4 1798
uci1 13:7a1fb885a8e4 1799 gCommWinOpen = true;
uci1 1:e392595b4b76 1800 Watchdog::kick(); // don't reset!
uci1 13:7a1fb885a8e4 1801
uci1 13:7a1fb885a8e4 1802 #ifdef DEBUG
uci1 13:7a1fb885a8e4 1803 printf("opening comm window at %d\r\n", (int32_t)gLastCommWin);
uci1 16:744ce85aede2 1804 printf("duration=%u\r\n",gConf.GetCommWinDuration());
uci1 13:7a1fb885a8e4 1805 #endif
uci1 13:7a1fb885a8e4 1806
uci1 13:7a1fb885a8e4 1807 // close the file so that the data is all written out.
uci1 13:7a1fb885a8e4 1808 // and open it back up at the beginning (for reading)
uci1 12:d472f9811262 1809 #ifdef DEBUG
uci1 13:7a1fb885a8e4 1810 printf("close & open file. gEvtNum=%u, gPowNum=%u\r\n",gEvtNum,gPowNum);
uci1 25:57b2627fe756 1811 printf("curfile=%p, filename=%s\r\n",SnSDUtils::GetCurFile(),
uci1 25:57b2627fe756 1812 SnSDUtils::GetCurFileName());
uci1 12:d472f9811262 1813 #endif
uci1 40:1324da35afd4 1814
uci1 40:1324da35afd4 1815 if (isStartupWin==false) {
uci1 56:0bba0ef15697 1816 #if CHIPBOARD==ATWD4CH
uci1 56:0bba0ef15697 1817 PIN_lockRegisters = 0; // unlock so we can talk to the SD card
uci1 56:0bba0ef15697 1818 #else
uci1 56:0bba0ef15697 1819 PIN_readingData = 0; // unlock so we can talk to the SD card
uci1 56:0bba0ef15697 1820 #endif
uci1 25:57b2627fe756 1821 #ifdef DEBUG
uci1 40:1324da35afd4 1822 printf("closing output file\r\n");
uci1 25:57b2627fe756 1823 #endif
uci1 40:1324da35afd4 1824 SnSDUtils::CloseOutputFile(SnSDUtils::GetCurFile());
uci1 25:57b2627fe756 1825 #ifdef DEBUG
uci1 40:1324da35afd4 1826 printf("open existing file (%d)\r\n",strlen(SnSDUtils::GetCurFileName()));
uci1 25:57b2627fe756 1827 #endif
uci1 40:1324da35afd4 1828 SnSDUtils::OpenExistingFile(SnSDUtils::GetCurFileName(), true, false);
uci1 40:1324da35afd4 1829 }
uci1 40:1324da35afd4 1830
uci1 21:ce51bb0ba4a5 1831 #ifdef DEBUG
uci1 21:ce51bb0ba4a5 1832 printf("setting power\r\n");
uci1 21:ce51bb0ba4a5 1833 #endif
uci1 13:7a1fb885a8e4 1834 // (probably) power down cards,amps and power up comms
uci1 13:7a1fb885a8e4 1835 SetPower(true);
uci1 13:7a1fb885a8e4 1836
uci1 25:57b2627fe756 1837 // time to recount files for the status update
uci1 40:1324da35afd4 1838 // for the startup win, don't access SD card in case we
uci1 40:1324da35afd4 1839 // rebooted due to a problem with the SD card
uci1 40:1324da35afd4 1840 SnStatusFrame::fgRecalcFiles = !isStartupWin;
uci1 25:57b2627fe756 1841
uci1 28:484943132bb0 1842 #if defined(ENABLE_AFAR_TWITTER) && defined(ENABLE_AFAR_COMM)
uci1 28:484943132bb0 1843 bool doTwitter = false;
uci1 28:484943132bb0 1844 #endif
uci1 28:484943132bb0 1845
uci1 21:ce51bb0ba4a5 1846 #ifdef DEBUG
uci1 21:ce51bb0ba4a5 1847 printf("start loop over comms\r\n");
uci1 21:ce51bb0ba4a5 1848 #endif
uci1 13:7a1fb885a8e4 1849 bool sendStat[kNcomms];
uci1 56:0bba0ef15697 1850 for (uint8_t i=0; i<kNcomms; ++i) {
uci1 13:7a1fb885a8e4 1851 sendStat[i]=true;
uci1 13:7a1fb885a8e4 1852 }
uci1 13:7a1fb885a8e4 1853 bool* ss = sendStat;
uci1 13:7a1fb885a8e4 1854 SnCommWin** cw = gComms;
uci1 56:0bba0ef15697 1855 for (uint8_t i=0; ((time(0)-gLastCommWin)<gConf.GetCommWinDuration()); ++i, ++cw, ++ss) {
uci1 1:e392595b4b76 1856 Watchdog::kick(); // don't reset!
uci1 13:7a1fb885a8e4 1857 if (i==kNcomms) {
uci1 13:7a1fb885a8e4 1858 i=0;
uci1 13:7a1fb885a8e4 1859 cw = gComms;
uci1 13:7a1fb885a8e4 1860 ss = sendStat;
uci1 13:7a1fb885a8e4 1861 }
uci1 27:efc4d654b139 1862 // skip if no comm object
uci1 13:7a1fb885a8e4 1863 if ((*cw)==0) {
uci1 13:7a1fb885a8e4 1864 continue;
uci1 13:7a1fb885a8e4 1865 }
uci1 27:efc4d654b139 1866 // skip if no power for this comm
uci1 27:efc4d654b139 1867 // THIS IS VITAL! For example, if the ethernet
uci1 27:efc4d654b139 1868 // port is powered down, making an Ethernet obejct
uci1 27:efc4d654b139 1869 // (done in netif) will stall forever waiting for the clock.
uci1 27:efc4d654b139 1870 // Do it here to keep all PIN usage in main.cpp
uci1 40:1324da35afd4 1871 const bool havePower=IsPinPowered(*cw);
uci1 27:efc4d654b139 1872 if (havePower==false) {
uci1 27:efc4d654b139 1873 continue;
uci1 27:efc4d654b139 1874 }
uci1 40:1324da35afd4 1875
uci1 40:1324da35afd4 1876 // always apply safety nets to connection and listen so
uci1 40:1324da35afd4 1877 // that we don't accidently shut down comms (i.e. with
uci1 40:1324da35afd4 1878 // connectTO or listnTO being 0)
uci1 40:1324da35afd4 1879 gConf.ApplyConnectListenSafetyNets();
uci1 16:744ce85aede2 1880 const uint32_t conto =
uci1 40:1324da35afd4 1881 (gConf.GetCommWinDuration() < gConf.GetCommWinConnectTO()) ?
uci1 40:1324da35afd4 1882 gConf.GetCommWinDuration() : gConf.GetCommWinConnectTO();
uci1 16:744ce85aede2 1883 const uint32_t listo =
uci1 40:1324da35afd4 1884 (gConf.GetCommWinDuration() < gConf.GetCommWinListenTO()) ?
uci1 40:1324da35afd4 1885 gConf.GetCommWinDuration() : gConf.GetCommWinListenTO();
uci1 40:1324da35afd4 1886
uci1 16:744ce85aede2 1887 // update power reading in case we want to send it in status
uci1 16:744ce85aede2 1888 GetAvePowerReading();
uci1 56:0bba0ef15697 1889
uci1 56:0bba0ef15697 1890 // update temperature in case we want to send it in status
uci1 56:0bba0ef15697 1891 if (isStartupWin) {
uci1 56:0bba0ef15697 1892 #if CHIPBOARD==SST4CH
uci1 56:0bba0ef15697 1893 InitTempProbe();
uci1 56:0bba0ef15697 1894 #endif
uci1 56:0bba0ef15697 1895 }
uci1 56:0bba0ef15697 1896 UpdateTemperature();
uci1 21:ce51bb0ba4a5 1897
uci1 13:7a1fb885a8e4 1898 // open window and (mabye) send status update
uci1 12:d472f9811262 1899 #ifdef DEBUG
uci1 13:7a1fb885a8e4 1900 printf("calling OpenWindow. ss=%d\r\n",(int)(*ss));
uci1 40:1324da35afd4 1901 printf("conto=%u, listo=%u, dur=%u, connTO=%u, lisTO=%u\r\n",
uci1 40:1324da35afd4 1902 conto,listo,gConf.GetCommWinDuration(),
uci1 40:1324da35afd4 1903 gConf.GetCommWinConnectTO(), gConf.GetCommWinListenTO());
uci1 21:ce51bb0ba4a5 1904 printf("gtt=%u, ct=%d, lcw=%d, dur=%u\r\n",gConf.GetTimeoutTime(gLastCommWin,conto),
uci1 13:7a1fb885a8e4 1905 time(0), gLastCommWin, gConf.GetCommWinDuration());
uci1 12:d472f9811262 1906 #endif
uci1 13:7a1fb885a8e4 1907 const SnCommWin::ECommWinResult conres = (*cw)->OpenWindow(
uci1 40:1324da35afd4 1908 // gConf.GetTimeoutTime(gLastCommWin, conto), *ss, gConf, gEvent, gPower,
uci1 40:1324da35afd4 1909 gConf.GetTimeoutTime(gLastCommWin, conto), *ss, gConf, gLastEvent, gPower,
uci1 56:0bba0ef15697 1910 SnSDUtils::GetCurSeqNum(), thmrate, evtrate, gPowerOnTime, gTemperature,
uci1 13:7a1fb885a8e4 1911 gGenBuf);
uci1 56:0bba0ef15697 1912 #ifdef DEBUG
uci1 56:0bba0ef15697 1913 printf("conres = %d\r\n",static_cast<int>(conres));
uci1 56:0bba0ef15697 1914 #endif
uci1 13:7a1fb885a8e4 1915 if (conres>=SnCommWin::kConnected) {
uci1 1:e392595b4b76 1916 Watchdog::kick(); // don't reset!
uci1 13:7a1fb885a8e4 1917 // connected. listen for config
uci1 13:7a1fb885a8e4 1918 *ss = false; // don't send status next time
uci1 40:1324da35afd4 1919
uci1 40:1324da35afd4 1920 // clear watchdog reset bit now that we've told someone
uci1 40:1324da35afd4 1921 Watchdog::clearResetFlag();
uci1 40:1324da35afd4 1922
uci1 28:484943132bb0 1923 #if defined(ENABLE_AFAR_TWITTER) && defined(ENABLE_AFAR_COMM)
uci1 28:484943132bb0 1924 if ((*cw)->GetCommType()==SnConfigFrame::kAfar) {
uci1 28:484943132bb0 1925 // if we connected by Afar
uci1 28:484943132bb0 1926 doTwitter = true;
uci1 28:484943132bb0 1927 }
uci1 28:484943132bb0 1928 #endif
uci1 28:484943132bb0 1929
uci1 12:d472f9811262 1930 #ifdef DEBUG
uci1 21:ce51bb0ba4a5 1931 printf("get conf gtt=%u\r\n",gConf.GetTimeoutTime(gLastCommWin, listo));
uci1 12:d472f9811262 1932 #endif
uci1 13:7a1fb885a8e4 1933 const SnCommWin::ECommWinResult cfgres = (*cw)->GetConfig(
uci1 21:ce51bb0ba4a5 1934 gConf, gConf.GetTimeoutTime(gLastCommWin, listo), gGenBuf, gBufSize);
uci1 56:0bba0ef15697 1935 #ifdef DEBUG
uci1 56:0bba0ef15697 1936 printf("cfgres = %d\r\n",static_cast<int>(cfgres));
uci1 56:0bba0ef15697 1937 #endif
uci1 13:7a1fb885a8e4 1938 if (cfgres>=SnCommWin::kOkWithMsg) {
uci1 13:7a1fb885a8e4 1939 Watchdog::kick(); // don't reset!
uci1 16:744ce85aede2 1940
uci1 12:d472f9811262 1941 #ifdef DEBUG
uci1 13:7a1fb885a8e4 1942 printf("received config!\r\n");
uci1 13:7a1fb885a8e4 1943 printf("send data = %d\r\n", gConf.GetCommSendData());
uci1 12:d472f9811262 1944 #endif
uci1 13:7a1fb885a8e4 1945 // send data if need be (files, some events, etc)
uci1 21:ce51bb0ba4a5 1946 const uint32_t winto = gConf.GetTimeoutTime(gLastCommWin,
uci1 21:ce51bb0ba4a5 1947 gConf.GetCommWinDuration());
uci1 40:1324da35afd4 1948 //const uint32_t gtt = gConf.IsObeyingTimeout() ? winto : 0;
uci1 40:1324da35afd4 1949
uci1 40:1324da35afd4 1950 // check if there are any requests before sending data
uci1 40:1324da35afd4 1951 if (gConf.IsWaitingHndShkBeforeSendData()) {
uci1 40:1324da35afd4 1952 // send handshake request
uci1 40:1324da35afd4 1953 (*cw)->SendHndshkReq(gGenBuf, winto);
uci1 40:1324da35afd4 1954 // wait for response
uci1 40:1324da35afd4 1955 uint8_t hndshk(0); uint32_t hndshkLen(0);
uci1 40:1324da35afd4 1956 res = (*cw)->WaitHandshake(gConf, winto, gGenBuf, gBufSize, hndshk,
uci1 40:1324da35afd4 1957 &hndshkLen);
uci1 56:0bba0ef15697 1958 #ifdef DEBUG
uci1 56:0bba0ef15697 1959 printf("WaitHandshake res = %d\r\n",static_cast<int>(res));
uci1 56:0bba0ef15697 1960 #endif
uci1 40:1324da35afd4 1961 // handle response
uci1 40:1324da35afd4 1962 if (SnCommWin::kOkWithMsg==res) {
uci1 40:1324da35afd4 1963 res = (*cw)->HandleHandshake(SnSDUtils::GetCurFile(),
uci1 40:1324da35afd4 1964 SnSDUtils::GetCurFileName(),
uci1 40:1324da35afd4 1965 gConf, gLastEvent, gPower, gGenBuf, gBufSize,
uci1 40:1324da35afd4 1966 winto, hndshk, hndshkLen);
uci1 56:0bba0ef15697 1967 #ifdef DEBUG
uci1 56:0bba0ef15697 1968 printf("HandleHandshake res = %d\r\n",static_cast<int>(res));
uci1 56:0bba0ef15697 1969 #endif
uci1 40:1324da35afd4 1970 }
uci1 40:1324da35afd4 1971 }
uci1 13:7a1fb885a8e4 1972 if (gConf.GetCommSendData()!=0) {
uci1 12:d472f9811262 1973 #ifdef DEBUG
uci1 40:1324da35afd4 1974 printf("sending data, winto=%u. lcw=%u, dur=%u, obey=%s\r\n",
uci1 40:1324da35afd4 1975 winto,
uci1 13:7a1fb885a8e4 1976 gLastCommWin, gConf.GetCommWinDuration(),
uci1 13:7a1fb885a8e4 1977 gConf.IsObeyingTimeout() ? "true" : "false");
uci1 12:d472f9811262 1978 #endif
uci1 16:744ce85aede2 1979
uci1 40:1324da35afd4 1980 res = (*cw)->SendData(gConf, gLastEvent, gPower, gGenBuf, gBufSize,
uci1 40:1324da35afd4 1981 winto);
uci1 56:0bba0ef15697 1982 #ifdef DEBUG
uci1 56:0bba0ef15697 1983 printf("SendData res = %d\r\n",static_cast<int>(res));
uci1 56:0bba0ef15697 1984 #endif
uci1 56:0bba0ef15697 1985
uci1 13:7a1fb885a8e4 1986 } else {
uci1 13:7a1fb885a8e4 1987 // don't send anything
uci1 13:7a1fb885a8e4 1988 res = cfgres;
uci1 13:7a1fb885a8e4 1989 }
uci1 13:7a1fb885a8e4 1990 #ifdef DEBUG
uci1 13:7a1fb885a8e4 1991 printf("Got config!\r\n");
uci1 13:7a1fb885a8e4 1992 #endif
uci1 13:7a1fb885a8e4 1993 Watchdog::kick(); // don't reset!
uci1 13:7a1fb885a8e4 1994 break;
uci1 13:7a1fb885a8e4 1995 }
uci1 21:ce51bb0ba4a5 1996 } else {
uci1 40:1324da35afd4 1997 // OpenWindow did not connect
uci1 21:ce51bb0ba4a5 1998 (*cw)->CloseConn(gConf.GetTimeoutTime(gLastCommWin, listo));
uci1 21:ce51bb0ba4a5 1999 } // if connected
uci1 13:7a1fb885a8e4 2000
uci1 13:7a1fb885a8e4 2001 Watchdog::kick(); // don't reset!
uci1 21:ce51bb0ba4a5 2002 } // end loop over comms
uci1 28:484943132bb0 2003
uci1 41:d6f5e2f09e07 2004 // check Iridium time, send Iridium signal strength, and close the connection(s)
uci1 15:f2569d8e4176 2005 cw = gComms;
uci1 56:0bba0ef15697 2006 for (uint8_t i=0; i<kNcomms; ++i, ++cw) {
uci1 15:f2569d8e4176 2007 if ((*cw)==0) {
uci1 15:f2569d8e4176 2008 continue;
uci1 15:f2569d8e4176 2009 }
uci1 40:1324da35afd4 2010 const bool havePower=IsPinPowered(*cw);
uci1 40:1324da35afd4 2011 if (havePower==false) {
uci1 40:1324da35afd4 2012 continue;
uci1 40:1324da35afd4 2013 }
uci1 40:1324da35afd4 2014
uci1 28:484943132bb0 2015 // check Iridium time
uci1 16:744ce85aede2 2016 if ((*cw)->GetCommType()==SnConfigFrame::kIrid) {
uci1 16:744ce85aede2 2017 #ifdef DEBUG
uci1 16:744ce85aede2 2018 printf("try to set iridium time\r\n");
uci1 16:744ce85aede2 2019 #endif
uci1 16:744ce85aede2 2020 // set the clock before closing connection
uci1 41:d6f5e2f09e07 2021 const uint32_t totime =
uci1 41:d6f5e2f09e07 2022 gConf.GetTimeoutTime(gLastCommWin,
uci1 41:d6f5e2f09e07 2023 gConf.GetCommWinDuration());
uci1 41:d6f5e2f09e07 2024 #ifdef DEBUG
uci1 41:d6f5e2f09e07 2025 printf("totime=%u, ctime=%u\r\n",totime,time(0));
uci1 41:d6f5e2f09e07 2026 #endif
uci1 41:d6f5e2f09e07 2027 const bool con = (*cw)->Connect(totime);
uci1 16:744ce85aede2 2028 if (con) {
uci1 40:1324da35afd4 2029 uint32_t prvTime(0), setTime(0);
uci1 41:d6f5e2f09e07 2030 const bool gottime = (*cw)->TrySetSysTimeUnix(
uci1 41:d6f5e2f09e07 2031 totime, prvTime, setTime);
uci1 41:d6f5e2f09e07 2032 if (gottime) {
uci1 41:d6f5e2f09e07 2033 gClkSet.SetClocks(prvTime, setTime);
uci1 41:d6f5e2f09e07 2034 #ifdef DEBUG
uci1 41:d6f5e2f09e07 2035 printf("sig str: totime=%u, ctime=%u\r\n",totime,time(0));
uci1 41:d6f5e2f09e07 2036 #endif
uci1 41:d6f5e2f09e07 2037 // got time; now send signal strength
uci1 41:d6f5e2f09e07 2038 (*cw)->SendSignalStrength( gGenBuf, gSigStr, totime );
uci1 41:d6f5e2f09e07 2039 }
uci1 16:744ce85aede2 2040 }
uci1 16:744ce85aede2 2041 }
uci1 40:1324da35afd4 2042 // close the connection -- this must be why Twitter didn't work!
uci1 40:1324da35afd4 2043 //(*cw)->CloseConn(gConf.GetTimeoutTime(gLastCommWin,gConf.GetCommWinDuration()));
uci1 28:484943132bb0 2044 // after normal Afar connection closed, try to tweet
uci1 31:b5bd3b189150 2045 #if defined(ENABLE_AFAR_TWITTER) && defined(ENABLE_AFAR_COMM)
uci1 28:484943132bb0 2046 if ((*cw)->GetCommType()==SnConfigFrame::kAfar) {
uci1 28:484943132bb0 2047 // tweet
uci1 28:484943132bb0 2048 #ifdef DEBUG
uci1 28:484943132bb0 2049 printf("for twitter: gTwit=%p, doTwitter=%d\r\n",gTwit,(int)doTwitter);
uci1 28:484943132bb0 2050 #endif
uci1 28:484943132bb0 2051 // send a twitter update
uci1 28:484943132bb0 2052 if ( (gTwit!=0) && doTwitter ) {
uci1 28:484943132bb0 2053 const uint32_t conto =
uci1 28:484943132bb0 2054 (gConf.GetCommWinDuration() < gTwit->GetConnectTimeout()) ?
uci1 28:484943132bb0 2055 gConf.GetCommWinDuration() : gTwit->GetConnectTimeout();
uci1 28:484943132bb0 2056 const uint32_t listo =
uci1 28:484943132bb0 2057 (gConf.GetCommWinDuration() < gTwit->GetListenTimeout()) ?
uci1 28:484943132bb0 2058 gConf.GetCommWinDuration() : gTwit->GetListenTimeout();
uci1 28:484943132bb0 2059 #ifdef DEBUG
uci1 28:484943132bb0 2060 printf("open twit window. conto=%u, listo=%u\r\n",
uci1 28:484943132bb0 2061 conto, listo);
uci1 28:484943132bb0 2062 #endif
uci1 28:484943132bb0 2063 const SnCommWin::ECommWinResult conres = gTwit->OpenWindow(
uci1 28:484943132bb0 2064 gConf.GetTimeoutTime(gLastCommWin, conto), false, gConf,
uci1 40:1324da35afd4 2065 gLastEvent, gPower,
uci1 28:484943132bb0 2066 SnSDUtils::GetCurSeqNum(), thmrate, evtrate,
uci1 28:484943132bb0 2067 gGenBuf);
uci1 28:484943132bb0 2068 if (conres>=SnCommWin::kConnected) {
uci1 28:484943132bb0 2069 Watchdog::kick(); // don't reset!
uci1 28:484943132bb0 2070 gTwit->Tweet(gConf, thmrate, evtrate, gGenBuf,
uci1 28:484943132bb0 2071 gConf.GetTimeoutTime(time(0), listo));
uci1 28:484943132bb0 2072 }
uci1 28:484943132bb0 2073 }
uci1 40:1324da35afd4 2074 } // end tweet block
uci1 28:484943132bb0 2075 #endif
uci1 40:1324da35afd4 2076 Watchdog::kick(); // don't reset!
uci1 40:1324da35afd4 2077 } // end loop: check time, tweet, etc
uci1 40:1324da35afd4 2078
uci1 40:1324da35afd4 2079 // close connections
uci1 40:1324da35afd4 2080 const uint32_t extraDiscTime = gLastCommWin + gConf.GetCommWinConnectTO();
uci1 40:1324da35afd4 2081 cw = gComms;
uci1 56:0bba0ef15697 2082 for (uint8_t i=0; i<kNcomms; ++i, ++cw) {
uci1 40:1324da35afd4 2083 if ((*cw)==0) {
uci1 40:1324da35afd4 2084 continue;
uci1 40:1324da35afd4 2085 } else {
uci1 40:1324da35afd4 2086 (*cw)->CloseConn(gConf.GetTimeoutTime(extraDiscTime, gConf.GetCommWinDuration()));
uci1 40:1324da35afd4 2087 }
uci1 28:484943132bb0 2088 }
uci1 40:1324da35afd4 2089
uci1 28:484943132bb0 2090 } // if duration >0
uci1 28:484943132bb0 2091
uci1 28:484943132bb0 2092 /* not working. must use DEFCONF.DAT to change IP's.
uci1 28:484943132bb0 2093 // change comm parameters (IP addresses)
uci1 28:484943132bb0 2094 #ifdef DEBUG
uci1 28:484943132bb0 2095 printf("set comm params\r\n");
uci1 28:484943132bb0 2096 #endif
uci1 28:484943132bb0 2097 for (uint8_t cc=0; cc<kNcomms; cc++) {
uci1 28:484943132bb0 2098 if (gComms[cc]!=0) {
uci1 28:484943132bb0 2099 gComms[cc]->Set(gConf);
uci1 15:f2569d8e4176 2100 }
uci1 0:664899e0b988 2101 }
uci1 28:484943132bb0 2102 */
uci1 40:1324da35afd4 2103
uci1 40:1324da35afd4 2104
uci1 40:1324da35afd4 2105 // check if we missed too many consecutive connections
uci1 40:1324da35afd4 2106 if (res<=SnCommWin::kAllFails) {
uci1 40:1324da35afd4 2107 ++gConsecCommFails;
uci1 40:1324da35afd4 2108 #ifdef DEBUG
uci1 56:0bba0ef15697 2109 printf("res=%d, gConsecCommFails=%hu, kMaxConsecCommFails=%hu\r\n",
uci1 56:0bba0ef15697 2110 static_cast<int>(res), gConsecCommFails,kMaxConsecCommFails);
uci1 40:1324da35afd4 2111 #endif
uci1 40:1324da35afd4 2112 if (gConsecCommFails>kMaxConsecCommFails) {
uci1 40:1324da35afd4 2113 #ifdef DEBUG
uci1 40:1324da35afd4 2114 printf("rebooting\r\n");
uci1 40:1324da35afd4 2115 #endif
uci1 40:1324da35afd4 2116 // goodbye cruel world, it's over. walk on by...
uci1 40:1324da35afd4 2117 mbed_reset();
uci1 40:1324da35afd4 2118 }
uci1 40:1324da35afd4 2119 } else {
uci1 40:1324da35afd4 2120 gConsecCommFails=0;
uci1 40:1324da35afd4 2121 }
uci1 28:484943132bb0 2122
uci1 4:a91682e19d6b 2123 // (probably) power down comms and power up cards,amps
uci1 4:a91682e19d6b 2124 SetPower(false);
uci1 4:a91682e19d6b 2125
uci1 1:e392595b4b76 2126 // reset config with system powered (for DAC/PLA setting)
uci1 12:d472f9811262 2127 #ifdef DEBUG
uci1 21:ce51bb0ba4a5 2128 printf("calling SetConfigAndMakeOutputFile\r\n");
uci1 12:d472f9811262 2129 #endif
uci1 22:f957c4f840ad 2130
uci1 21:ce51bb0ba4a5 2131 SetConfigAndMakeOutputFile();
uci1 21:ce51bb0ba4a5 2132
uci1 56:0bba0ef15697 2133 if (gConf.IsRunSeqListOneCommWinOnly()) {
uci1 56:0bba0ef15697 2134 SnSDUtils::ClearRunSeqList();
uci1 56:0bba0ef15697 2135 }
uci1 56:0bba0ef15697 2136
uci1 56:0bba0ef15697 2137 // check power in case we should be in low power mode
uci1 56:0bba0ef15697 2138 // but don't save this reading to the file
uci1 56:0bba0ef15697 2139 // (there's already one near the beginning)
uci1 56:0bba0ef15697 2140 CheckPower(false, false);
uci1 56:0bba0ef15697 2141
uci1 12:d472f9811262 2142 #ifdef DEBUG
uci1 1:e392595b4b76 2143 printf("closing comm win at %d\r\n",(int32_t)time(0));
uci1 12:d472f9811262 2144 #endif
uci1 1:e392595b4b76 2145
uci1 0:664899e0b988 2146 gCommWinOpen = false;
uci1 0:664899e0b988 2147 return res;
uci1 0:664899e0b988 2148 }