Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Thu Nov 28 01:18:39 2013 +0000
Revision:
50:163ec8d88aa9
Parent:
49:a2fb3ce86a5c
Child:
51:b2bc37d660c0
USB comms. Require at least 2 events to calc rates. Move AddToRates for thermal triggers back outside of throttle check, to allow high rate calculations.

Who changed what in which revision?

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