Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Wed Nov 06 00:09:00 2013 +0000
Revision:
49:a2fb3ce86a5c
Parent:
48:ee023b8807d8
Child:
50:163ec8d88aa9
afar and sbd comms. debug OFF. like rev 47

Who changed what in which revision?

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