Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Sun Feb 22 20:42:44 2015 +0000
Revision:
76:f8383f0292c2
Parent:
67:ec999336fcd1
Child:
84:80b15993944e
Stn14 mac adr. Allow SD to be ignored. Only access run/seq list if going to send the list.

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