Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Tue Oct 08 23:44:00 2013 +0000
Revision:
41:d6f5e2f09e07
Parent:
40:1324da35afd4
Child:
42:ac162d15e578
sbd only, debug on. send iridium signal strength. check first event even if cards off. make serial type explicit as Serial has no vtable. SBD comms: send buffered returns bytes sent out, use checksum of msg from modem, fix EmptyRxBuf, add checkSIgStr

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