Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Wed Oct 30 21:15:33 2013 +0000
Revision:
42:ac162d15e578
Parent:
41:d6f5e2f09e07
Child:
43:aba4136470be
no debug. afar and sbd enabled. twitter off (broken). fix so modserial does not use vtable. add CheckSignalStrength. fix Send to return bytes sent, not buffered. use SBD checksum and without union

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 42:ac162d15e578 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 42:ac162d15e578 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 }