Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Thu May 23 22:26:39 2013 +0000
Revision:
36:87865913ae6f
Parent:
35:549714a257a4
Child:
37:ff95e7070f26
this will not compile. just starting to modularize the comms and essential packages for extraction (to use in both the DAQ and monitoring station)

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