Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Tue Feb 03 00:04:30 2015 +0000
Revision:
67:ec999336fcd1
Parent:
65:2cb3e99ce466
Child:
76:f8383f0292c2
STN20 Hardcoded (mac adr and config label). Power off periphs before powering anything on. do NOT use interface chip for mac adr or files (except reprogramming)

Who changed what in which revision?

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