Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Sat Oct 05 04:45:22 2013 +0000
Revision:
40:1324da35afd4
Parent:
39:2f17131d22a5
Child:
41:d6f5e2f09e07
first commit of major overhaul to 2013-2014 mbed code. NOT YET FULLY TESTED. too many changes to list (fix local file receive, fix rates, external comm packes, big SD cards, get to comm win w/o SD, v8 config frame, v4 files, SBD buffering changes...)

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