Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Sat Nov 22 02:35:11 2014 +0000
Revision:
61:42cbfc02e0e0
Parent:
59:21128cc24b04
Child:
62:4b59c1eb429f
remove brownout code. add 512 bytes to general buffer. make status frame v1 max size use event max size v1

Who changed what in which revision?

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