Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Fri Oct 31 23:33:31 2014 +0000
Revision:
59:21128cc24b04
Parent:
56:0bba0ef15697
Child:
61:42cbfc02e0e0
Enable safety nets. Allow IP setting via text files on mbed.

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