Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Fri Nov 28 05:41:42 2014 +0000
Revision:
63:4820a4460f00
Parent:
62:4b59c1eb429f
Child:
65:2cb3e99ce466
Revert to SDFileSystemFilInfo with no-stall changes to SDFileSystem.cpp . change watchdog to internal RC clock. move check power to after startup LED sequence. make InitSDCard try up to 26 init's. DEBUG ENABLED, NO SAFETY NETS

Who changed what in which revision?

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