Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Fri Aug 31 02:09:09 2012 +0000
Revision:
15:f2569d8e4176
Parent:
14:2736b57bbbed
Child:
16:744ce85aede2
Removed debug output between trigger and and dFPGA->MB request that corrupted data. Lots of work on SBD, but not quite working yet. Debug output off, but start/stop running notifications are on.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
uci1 0:664899e0b988 1 #include "mbed.h"
uci1 0:664899e0b988 2
uci1 8:95a325df1f6b 3 #define USE_RTOS_TIMER
uci1 8:95a325df1f6b 4
uci1 12:d472f9811262 5 //#define EVT_TIME_PROFILE
uci1 14:2736b57bbbed 6 //#define DEBUG
uci1 15:f2569d8e4176 7 #define SSNOTIFY
uci1 15:f2569d8e4176 8 #define USE_MODSERIAL
uci1 12:d472f9811262 9
uci1 0:664899e0b988 10 #include <stdint.h>
uci1 0:664899e0b988 11 #include "SDFileSystem.h"
uci1 15:f2569d8e4176 12 #ifdef USE_MODSERIAL
uci1 0:664899e0b988 13 #include "MODSERIAL.h"
uci1 15:f2569d8e4176 14 #endif
uci1 0:664899e0b988 15 #include "Watchdog.h"
uci1 0:664899e0b988 16 #include "SnConstants.h"
uci1 0:664899e0b988 17 #include "SnBitUtils.h"
uci1 0:664899e0b988 18 #include "SnSDUtils.h"
uci1 0:664899e0b988 19 #include "SnConfigFrame.h"
uci1 0:664899e0b988 20 #include "SnEventFrame.h"
uci1 0:664899e0b988 21 #include "SnStatusFrame.h"
uci1 2:e67f7c158087 22 #include "SnHeaderFrame.h"
uci1 0:664899e0b988 23 #include "SnCommWin.h"
uci1 7:079617408fec 24 #include "SnCommAfarTCP.h"
uci1 0:664899e0b988 25 #include "SnCommUsb.h"
uci1 15:f2569d8e4176 26 #include "SnCommSBD.h"
uci1 1:e392595b4b76 27 #include "SnBase64.h"
uci1 8:95a325df1f6b 28 #ifdef USE_RTOS_TIMER
uci1 8:95a325df1f6b 29 #include "RtosTimer.h"
uci1 8:95a325df1f6b 30 #endif
uci1 0:664899e0b988 31
uci1 0:664899e0b988 32 //
uci1 0:664899e0b988 33 // MBED PINS (ordered by number)
uci1 0:664899e0b988 34 //
uci1 0:664899e0b988 35 // leds (for debugging)
uci1 0:664899e0b988 36 DigitalOut led1(LED1);
uci1 0:664899e0b988 37 DigitalOut led2(LED2);
uci1 0:664899e0b988 38 DigitalOut led3(LED3);
uci1 0:664899e0b988 39 DigitalOut led4(LED4);
uci1 0:664899e0b988 40 // Set up power pins - Note that it's Zero for "on"
uci1 1:e392595b4b76 41 DigitalOut PIN_turn_on_system(p17); // this turns on system
uci1 0:664899e0b988 42 DigitalOut PIN_turn_on_amps(p25);
uci1 15:f2569d8e4176 43 // SD card select
uci1 15:f2569d8e4176 44 DigitalOut PIN_SD_CS(p8);
uci1 0:664899e0b988 45 // Activate/select chip by falling edge
uci1 0:664899e0b988 46 DigitalOut PIN_ADC_CS( p9 );
uci1 0:664899e0b988 47 // clock signal to activate PLA setting
uci1 0:664899e0b988 48 DigitalOut PIN_PLA_cs(p10);
uci1 0:664899e0b988 49 // To force a trigger
uci1 0:664899e0b988 50 DigitalOut PIN_forceTrigger(p11); //modification
uci1 0:664899e0b988 51 // To suppress thermal triggers
uci1 0:664899e0b988 52 DigitalOut PIN_enableThermTrig(p12);
uci1 0:664899e0b988 53 // Restart clock on all FPGAs.
uci1 0:664899e0b988 54 DigitalOut PIN_DoNotRestartAllClocks( p13 );
uci1 0:664899e0b988 55 // This tells the DFPGAs to store the data on motherboard FPGA and
uci1 0:664899e0b988 56 // read it out.
uci1 0:664899e0b988 57 DigitalIn PIN_a_sf_clk( p14 );
uci1 0:664899e0b988 58 DigitalIn PIN_rst_a_sf(p15);
uci1 1:e392595b4b76 59 // afar power
uci1 1:e392595b4b76 60 DigitalOut PIN_afar_power(p16);
uci1 4:a91682e19d6b 61 // batter voltage/current measurement
uci1 4:a91682e19d6b 62 AnalogIn PIN_vADC1(p19);
uci1 4:a91682e19d6b 63 AnalogIn PIN_vADC2(p18);
uci1 0:664899e0b988 64 // Lock daughter card registeres (during data readout).
uci1 0:664899e0b988 65 DigitalOut PIN_lockRegisters( p20 );
uci1 1:e392595b4b76 66 // iridium (SBD) power
uci1 1:e392595b4b76 67 DigitalOut PIN_iridSbd_power(p21);
uci1 0:664899e0b988 68 // Majority logic pins
uci1 0:664899e0b988 69 DigitalOut PIN_MajLogHiBit(p22);
uci1 0:664899e0b988 70 DigitalOut PIN_MajLogLoBit(p23);
uci1 0:664899e0b988 71 // Tell FPGA to be ready to accept DAC values
uci1 0:664899e0b988 72 DigitalOut PIN_start_fpga(p26);
uci1 0:664899e0b988 73 // Two bits to the select the daughter card for readout
uci1 0:664899e0b988 74 DigitalOut PIN_selCardHiBit( p29 );
uci1 0:664899e0b988 75 DigitalOut PIN_selCardLoBit( p30 );
uci1 0:664899e0b988 76 // To launch a heartbeat pulse
uci1 0:664899e0b988 77 DigitalOut PIN_heartbeat(p24);
uci1 0:664899e0b988 78 // Setup SPI pins
uci1 0:664899e0b988 79 SPI PIN_spi( p5, p6, p7 );
uci1 0:664899e0b988 80 // The SD card
uci1 3:24c5f0f50bf1 81
uci1 3:24c5f0f50bf1 82 // this needs to be first in case some other global uses a print statement
uci1 15:f2569d8e4176 83 #ifdef USE_MODSERIAL
uci1 13:7a1fb885a8e4 84 static MODSERIAL gCpu( USBTX, USBRX ); // defined here so it might be used for debugging output
uci1 15:f2569d8e4176 85 static MODSERIAL gSBDport(p28, p27, "sbd");
uci1 15:f2569d8e4176 86 #else
uci1 15:f2569d8e4176 87 static Serial gCpu( USBTX, USBRX ); // defined here so it might be used for debugging output
uci1 13:7a1fb885a8e4 88 static Serial gSBDport(p28, p27, "sbd");
uci1 15:f2569d8e4176 89 #endif
uci1 13:7a1fb885a8e4 90 static SDFileSystem sd(p5, p6, p7, p8, SnSDUtils::kSDsubDir+1);
uci1 13:7a1fb885a8e4 91 static LocalFileSystem local("local");
uci1 0:664899e0b988 92
uci1 0:664899e0b988 93 //
uci1 0:664899e0b988 94 // fwd declare fcns
uci1 0:664899e0b988 95 //
uci1 0:664899e0b988 96 void ReadAllRegisters();
uci1 0:664899e0b988 97 void ReadRegister(const uint8_t chan, int16_t* dev);
uci1 0:664899e0b988 98 void SaveEvent(const int32_t etms);
uci1 0:664899e0b988 99 void WaitTrigAndSendClock();
uci1 1:e392595b4b76 100 void SetConfigAndMakeOutputFile();
uci1 13:7a1fb885a8e4 101 SnCommWin::ECommWinResult OpenCommWin(const bool forceReconfig=false);
uci1 3:24c5f0f50bf1 102 void MakeOutputFile(const bool stopRunning=false);
uci1 4:a91682e19d6b 103 void SetPower(const bool isCommWin);
uci1 8:95a325df1f6b 104 void procForceTrigger();
uci1 8:95a325df1f6b 105 void procHeartbeat();
uci1 8:95a325df1f6b 106 void procPowerCheck();
uci1 8:95a325df1f6b 107 void procCommWin();
uci1 8:95a325df1f6b 108 #ifdef USE_RTOS_TIMER
uci1 8:95a325df1f6b 109 void procForceTrigger(void const *) { return procForceTrigger(); }
uci1 8:95a325df1f6b 110 void procHeartbeat(void const *) { return procHeartbeat(); }
uci1 8:95a325df1f6b 111 void procPowerCheck(void const *) { return procPowerCheck(); }
uci1 8:95a325df1f6b 112 void procCommWin(void const *) { return procCommWin(); }
uci1 8:95a325df1f6b 113 #endif
uci1 0:664899e0b988 114
uci1 0:664899e0b988 115 //
uci1 0:664899e0b988 116 // globals
uci1 0:664899e0b988 117 //
uci1 0:664899e0b988 118 // readout objs
uci1 8:95a325df1f6b 119 // TODO: use RtosTimer instead of Ticker?
uci1 8:95a325df1f6b 120 #ifdef USE_RTOS_TIMER
uci1 8:95a325df1f6b 121 static rtos::RtosTimer* gForceTicker;
uci1 8:95a325df1f6b 122 static rtos::RtosTimer* gHeartbeatTicker;
uci1 8:95a325df1f6b 123 static rtos::RtosTimer* gCommWinTicker;
uci1 8:95a325df1f6b 124 static rtos::RtosTimer* gPowerCheckTicker;
uci1 8:95a325df1f6b 125 #else
uci1 0:664899e0b988 126 static Ticker gForceTicker;
uci1 3:24c5f0f50bf1 127 static Ticker gHeartbeatTicker;
uci1 1:e392595b4b76 128 static Ticker gCommWinTicker;
uci1 8:95a325df1f6b 129 static Ticker gPowerCheckTicker;
uci1 8:95a325df1f6b 130 #endif
uci1 12:d472f9811262 131 static Timer gTrgTimer;
uci1 0:664899e0b988 132 static SnConfigFrame gConf;
uci1 0:664899e0b988 133 static SnEventFrame gEvent;
uci1 8:95a325df1f6b 134 static SnPowerFrame gPower;
uci1 0:664899e0b988 135 // parameters
uci1 0:664899e0b988 136 static bool gFirstEvt = true;
uci1 15:f2569d8e4176 137 static volatile bool gReadingOut = false;
uci1 15:f2569d8e4176 138 static volatile bool gCommWinOpen = false; // if it's open
uci1 1:e392595b4b76 139 static volatile bool gOpenCommWin = false; // if it should be opened
uci1 8:95a325df1f6b 140 static volatile bool gCheckPower = false; // if it should be checked
uci1 8:95a325df1f6b 141 static uint32_t gPowNum = 0;
uci1 8:95a325df1f6b 142 static uint32_t gEvtNum = 0; // num of evt written
uci1 8:95a325df1f6b 143 static uint32_t gTrgNum[kNumTrgs] = {0}; // num of this type of trg received
uci1 0:664899e0b988 144 // i/o
uci1 1:e392595b4b76 145 static time_t gLastCommWin = 0;
uci1 10:3c93db1cfb12 146 static uint32_t gLastCountReset = 0;
uci1 10:3c93db1cfb12 147 // this should be bigger than anything that will actually be used
uci1 10:3c93db1cfb12 148 static const uint32_t gBufSize=SnStatusFrame::kMaxSizeOf + (2u*SnHeaderFrame::kMaxSizeOf) + SnPowerFrame::kMaxSizeOf;
uci1 6:6f002d202f59 149 //static const uint32_t gB64Bsize=BASE64ENC_LEN(gBufSize)+1;
uci1 6:6f002d202f59 150 //static char gB64Buf[gB64Bsize];
uci1 3:24c5f0f50bf1 151 static char gGenBuf[gBufSize]; // must be big enough for event or status or config!
uci1 11:de443350ec4a 152 static SnCommWin* gComms[kNcomms] = { 0 }; // order => priority. afar uses RTOS, and must be made inside main
uci1 0:664899e0b988 153
uci1 0:664899e0b988 154 void procForceTrigger() {
uci1 0:664899e0b988 155 if (gReadingOut==false && gCommWinOpen==false) {
uci1 15:f2569d8e4176 156 led3=!led3;
uci1 12:d472f9811262 157 #ifdef DEBUG
uci1 8:95a325df1f6b 158 printf("proc force\r\n");
uci1 12:d472f9811262 159 #endif
uci1 0:664899e0b988 160 gEvent.SetTrgBit(kFrcTrg);
uci1 0:664899e0b988 161 gEvent.SetTrgNum((gTrgNum[kFrcTrg])++);
uci1 0:664899e0b988 162 PIN_forceTrigger = 1; // force a trigger
uci1 0:664899e0b988 163 }
uci1 0:664899e0b988 164 }
uci1 0:664899e0b988 165
uci1 3:24c5f0f50bf1 166 void procHeartbeat() {
uci1 3:24c5f0f50bf1 167 if (gReadingOut==false && gCommWinOpen==false) {
uci1 12:d472f9811262 168 #ifdef DEBUG
uci1 8:95a325df1f6b 169 printf("proc heartbeat\r\n");
uci1 12:d472f9811262 170 #endif
uci1 3:24c5f0f50bf1 171 PIN_heartbeat = 1; // heartbeat pulse
uci1 3:24c5f0f50bf1 172 PIN_heartbeat = 0;
uci1 3:24c5f0f50bf1 173 }
uci1 3:24c5f0f50bf1 174 }
uci1 3:24c5f0f50bf1 175
uci1 8:95a325df1f6b 176 void procPowerCheck() {
uci1 12:d472f9811262 177 #ifdef DEBUG
uci1 8:95a325df1f6b 178 printf("proc power\r\n");
uci1 12:d472f9811262 179 #endif
uci1 8:95a325df1f6b 180 gCheckPower=true;
uci1 8:95a325df1f6b 181 }
uci1 8:95a325df1f6b 182
uci1 0:664899e0b988 183 void procCommWin() {
uci1 0:664899e0b988 184 if (gReadingOut==false && gCommWinOpen==false) {
uci1 1:e392595b4b76 185 if ( (time(0) - gLastCommWin) > gConf.GetCommWinPeriod() ) {
uci1 12:d472f9811262 186 #ifdef DEBUG
uci1 8:95a325df1f6b 187 printf("proc comm win\r\n");
uci1 12:d472f9811262 188 #endif
uci1 1:e392595b4b76 189 led3=!led3;
uci1 1:e392595b4b76 190 gOpenCommWin = true;
uci1 1:e392595b4b76 191 }
uci1 0:664899e0b988 192 }
uci1 0:664899e0b988 193 }
uci1 0:664899e0b988 194
uci1 1:e392595b4b76 195 uint32_t GetTimeoutTime(const uint32_t startTime,
uci1 1:e392595b4b76 196 const uint32_t delta) {
uci1 1:e392595b4b76 197 const uint32_t lst = time(0)-startTime;
uci1 1:e392595b4b76 198 const uint32_t lio =
uci1 1:e392595b4b76 199 ((lst+delta) < gConf.GetCommWinDuration()) ?
uci1 1:e392595b4b76 200 lst+delta : gConf.GetCommWinDuration();
uci1 1:e392595b4b76 201 return lio+startTime;
uci1 1:e392595b4b76 202 }
uci1 1:e392595b4b76 203
uci1 8:95a325df1f6b 204 bool AreCardsPowered() {
uci1 12:d472f9811262 205 #ifdef DEBUG
uci1 8:95a325df1f6b 206 printf("acp: PIN_turn_on_system=%d\r\n",PIN_turn_on_system.read());
uci1 12:d472f9811262 207 #endif
uci1 8:95a325df1f6b 208 return (PIN_turn_on_system.read()==0);
uci1 8:95a325df1f6b 209 }
uci1 0:664899e0b988 210
uci1 8:95a325df1f6b 211 void GetAvePowerReading() {
uci1 8:95a325df1f6b 212 // use one measurement as the assumed average
uci1 8:95a325df1f6b 213 // in order to reduce computational errors
uci1 8:95a325df1f6b 214 int32_t v1, v2;
uci1 8:95a325df1f6b 215 const uint16_t aaveV1 = PIN_vADC1.read_u16();
uci1 8:95a325df1f6b 216 const uint16_t aaveV2 = PIN_vADC2.read_u16();
uci1 8:95a325df1f6b 217 float n=0, ave1=0, ave2=0, rms1=0, rms2=0;
uci1 8:95a325df1f6b 218 for (uint16_t i=0; i<kNvoltsAve; i++) {
uci1 8:95a325df1f6b 219 v1 = PIN_vADC1.read_u16() - aaveV1;
uci1 8:95a325df1f6b 220 v2 = PIN_vADC2.read_u16() - aaveV2;
uci1 8:95a325df1f6b 221 n += 1;
uci1 8:95a325df1f6b 222 ave1 += v1;
uci1 8:95a325df1f6b 223 rms1 += v1*v1;
uci1 8:95a325df1f6b 224 ave2 += v2;
uci1 8:95a325df1f6b 225 rms2 += v2*v2;
uci1 8:95a325df1f6b 226 }
uci1 8:95a325df1f6b 227 rms1 -= (ave1*ave1)/n;
uci1 8:95a325df1f6b 228 rms2 -= (ave2*ave2)/n;
uci1 8:95a325df1f6b 229 rms1 /= n-1;
uci1 8:95a325df1f6b 230 rms2 /= n-1;
uci1 9:a1a39573dd43 231 rms1 = sqrt(rms1);
uci1 9:a1a39573dd43 232 rms2 = sqrt(rms2);
uci1 8:95a325df1f6b 233 ave1 /= n;
uci1 8:95a325df1f6b 234 ave2 /= n;
uci1 8:95a325df1f6b 235 ave1 += aaveV1;
uci1 8:95a325df1f6b 236 ave2 += aaveV2;
uci1 8:95a325df1f6b 237 gPower.Set(ave1, ave2, rms1, rms2, time(0));
uci1 8:95a325df1f6b 238 }
uci1 0:664899e0b988 239
uci1 8:95a325df1f6b 240 void CheckPower(const bool isCommWin) {
uci1 12:d472f9811262 241 #ifdef DEBUG
uci1 8:95a325df1f6b 242 printf("CheckPower\r\n");
uci1 12:d472f9811262 243 #endif
uci1 8:95a325df1f6b 244 // read power
uci1 8:95a325df1f6b 245 GetAvePowerReading();
uci1 8:95a325df1f6b 246 // save to disk
uci1 8:95a325df1f6b 247 FILE* cf = SnSDUtils::GetCurFile();
uci1 8:95a325df1f6b 248 if (cf!=0) {
uci1 11:de443350ec4a 249 PIN_lockRegisters = 0; // unlock so we can talk to SD card.
uci1 12:d472f9811262 250 #ifdef DEBUG
uci1 8:95a325df1f6b 251 printf("writing power. v1=%g, v2=%g, r1=%g, r2=%g, t=%u, pownum=%u\r\n",
uci1 8:95a325df1f6b 252 gPower.GetAveV1(), gPower.GetAveV2(),
uci1 8:95a325df1f6b 253 gPower.GetRmsV1(), gPower.GetRmsV2(), gPower.GetTime(),
uci1 8:95a325df1f6b 254 gPowNum);
uci1 12:d472f9811262 255 #endif
uci1 8:95a325df1f6b 256 SnSDUtils::WritePowerTo(cf, gPower, gPowNum);
uci1 8:95a325df1f6b 257 }
uci1 8:95a325df1f6b 258 // do we need to change modes?
uci1 8:95a325df1f6b 259 bool changed = false;
uci1 8:95a325df1f6b 260 if (gConf.IsLowPowerMode()) {
uci1 8:95a325df1f6b 261 if (gPower.GetAveV1() > gConf.GetBatVoltLowPwr()) {
uci1 12:d472f9811262 262 #ifdef DEBUG
uci1 8:95a325df1f6b 263 printf("chaing to normal power!\r\n");
uci1 12:d472f9811262 264 #endif
uci1 8:95a325df1f6b 265 gConf.ChangeToNormPower();
uci1 8:95a325df1f6b 266 changed = true;
uci1 8:95a325df1f6b 267 }
uci1 8:95a325df1f6b 268 } else {
uci1 8:95a325df1f6b 269 if (gPower.GetAveV1() < gConf.GetBatVoltLowPwr()) {
uci1 12:d472f9811262 270 #ifdef DEBUG
uci1 8:95a325df1f6b 271 printf("chaing to low power!\r\n");
uci1 12:d472f9811262 272 #endif
uci1 8:95a325df1f6b 273 gConf.ChangeToLowPower();
uci1 8:95a325df1f6b 274 changed = true;
uci1 8:95a325df1f6b 275 }
uci1 8:95a325df1f6b 276 }
uci1 8:95a325df1f6b 277 if (changed) {
uci1 8:95a325df1f6b 278 SetPower(isCommWin);
uci1 12:d472f9811262 279 #ifdef DEBUG
uci1 8:95a325df1f6b 280 printf("Using config %s\r\n",gConf.GetLabel());
uci1 12:d472f9811262 281 #endif
uci1 8:95a325df1f6b 282 SetConfigAndMakeOutputFile(); // setup defaults in case no communication
uci1 8:95a325df1f6b 283 }
uci1 8:95a325df1f6b 284 // checking done
uci1 8:95a325df1f6b 285 gCheckPower = false;
uci1 8:95a325df1f6b 286 }
uci1 8:95a325df1f6b 287
uci1 10:3c93db1cfb12 288 void ResetCountersClearEvt() {
uci1 12:d472f9811262 289 const uint32_t evtStartCurSeq = (SnSDUtils::GetCurSeqNum()) // no -1; start with seq=0
uci1 12:d472f9811262 290 * gConf.GetEvtsPerFile();
uci1 10:3c93db1cfb12 291 gEvent.ClearEvent();
uci1 12:d472f9811262 292 gEvtNum = gConf.GetFirstEvt() + evtStartCurSeq;
uci1 12:d472f9811262 293 gPowNum = evtStartCurSeq;
uci1 10:3c93db1cfb12 294 memset(gTrgNum, 0, sizeof(uint32_t)*kNumTrgs);
uci1 13:7a1fb885a8e4 295 gLastCountReset = static_cast<uint32_t>(time(0)); // to calc rates
uci1 13:7a1fb885a8e4 296 #ifdef DEBUG
uci1 13:7a1fb885a8e4 297 printf("Reset: gEvtNum=%u, gPowNum=%u, evtStartCS=%u\r\n",
uci1 13:7a1fb885a8e4 298 gEvtNum, gPowNum, evtStartCurSeq);
uci1 13:7a1fb885a8e4 299 #endif
uci1 10:3c93db1cfb12 300 }
uci1 10:3c93db1cfb12 301
uci1 10:3c93db1cfb12 302 void GetRates(float& thmrate, float& evtrate) {
uci1 10:3c93db1cfb12 303 thmrate = evtrate = 0;
uci1 10:3c93db1cfb12 304 const uint32_t dt = static_cast<uint32_t>(time(0)) - gLastCountReset;
uci1 10:3c93db1cfb12 305 if (dt>0) {
uci1 10:3c93db1cfb12 306 thmrate = gTrgNum[kThmTrg] / dt;
uci1 10:3c93db1cfb12 307 evtrate = (gEvtNum + gConf.GetFirstEvt()) / dt;
uci1 10:3c93db1cfb12 308 }
uci1 10:3c93db1cfb12 309 }
uci1 10:3c93db1cfb12 310
uci1 8:95a325df1f6b 311 bool IsSeqComplete() {
uci1 12:d472f9811262 312 #ifdef DEBUG
uci1 12:d472f9811262 313 printf("IsSeqComplete: eps=%u, cntpow=%d, fe=%u, pow=%u, evt=%u, seq=%hu\r\n",
uci1 10:3c93db1cfb12 314 gConf.GetEvtsPerFile(), (int)gConf.IsCountingPowerReadings(),
uci1 12:d472f9811262 315 gConf.GetFirstEvt(), gPowNum, gEvtNum, SnSDUtils::GetCurSeqNum());
uci1 12:d472f9811262 316 #endif
uci1 8:95a325df1f6b 317 if (gConf.GetEvtsPerFile()>0) {
uci1 12:d472f9811262 318 const uint32_t evtEndCurSeq = (SnSDUtils::GetCurSeqNum()+1) // account for seq=0
uci1 12:d472f9811262 319 * gConf.GetEvtsPerFile();
uci1 12:d472f9811262 320 #ifdef DEBUG
uci1 12:d472f9811262 321 printf("evtEndCurSeq=%u\r\n",evtEndCurSeq);
uci1 12:d472f9811262 322 #endif
uci1 8:95a325df1f6b 323 if (gConf.IsCountingPowerReadings()) {
uci1 12:d472f9811262 324 return (gPowNum>=evtEndCurSeq);
uci1 8:95a325df1f6b 325 } else {
uci1 12:d472f9811262 326 // first event num is a one-time per run offset, not one per sequence
uci1 12:d472f9811262 327 return (gEvtNum>=(gConf.GetFirstEvt()+evtEndCurSeq));
uci1 8:95a325df1f6b 328 }
uci1 12:d472f9811262 329 } else {
uci1 12:d472f9811262 330 return false;
uci1 8:95a325df1f6b 331 }
uci1 8:95a325df1f6b 332 }
uci1 1:e392595b4b76 333
uci1 8:95a325df1f6b 334 #ifdef USE_RTOS_TIMER
uci1 8:95a325df1f6b 335 void stopTicker(rtos::RtosTimer* tik) {
uci1 8:95a325df1f6b 336 if (tik!=0) {
uci1 8:95a325df1f6b 337 tik->stop();
uci1 8:95a325df1f6b 338 }
uci1 8:95a325df1f6b 339 }
uci1 8:95a325df1f6b 340 #else
uci1 8:95a325df1f6b 341 void stopTicker(Ticker& tik) {
uci1 8:95a325df1f6b 342 tik.detach();
uci1 8:95a325df1f6b 343 }
uci1 8:95a325df1f6b 344 #endif
uci1 8:95a325df1f6b 345
uci1 8:95a325df1f6b 346 #ifdef USE_RTOS_TIMER
uci1 8:95a325df1f6b 347 uint32_t resetTicker(rtos::RtosTimer* tik, const uint32_t timSec,
uci1 8:95a325df1f6b 348 const uint32_t maxTimSec) {
uci1 8:95a325df1f6b 349 if (tik!=0) {
uci1 8:95a325df1f6b 350 tik->stop();
uci1 8:95a325df1f6b 351 if (timSec>0) {
uci1 8:95a325df1f6b 352 uint32_t tp = timSec > maxTimSec ? maxTimSec : timSec;
uci1 8:95a325df1f6b 353 tp *= 1000u; // ms
uci1 8:95a325df1f6b 354 tik->start(tp);
uci1 8:95a325df1f6b 355 return tp;
uci1 8:95a325df1f6b 356 }
uci1 8:95a325df1f6b 357 }
uci1 8:95a325df1f6b 358 return 0;
uci1 8:95a325df1f6b 359 }
uci1 8:95a325df1f6b 360 #else
uci1 8:95a325df1f6b 361 uint32_t resetTicker(Ticker& tik, const uint32_t timSec,
uci1 8:95a325df1f6b 362 const uint32_t maxTimSec, void (*fptr)(void)) {
uci1 8:95a325df1f6b 363 tik.detach();
uci1 8:95a325df1f6b 364 if (timSec>0) {
uci1 8:95a325df1f6b 365 const uint32_t tp = timSec > maxTimSec ? maxTimSec : timSec;
uci1 8:95a325df1f6b 366 tik.attach(fptr, tp);
uci1 8:95a325df1f6b 367 return tp;
uci1 8:95a325df1f6b 368 }
uci1 8:95a325df1f6b 369 return 0;
uci1 8:95a325df1f6b 370 }
uci1 8:95a325df1f6b 371 #endif
uci1 8:95a325df1f6b 372
uci1 15:f2569d8e4176 373 void StopAllTickers() {
uci1 8:95a325df1f6b 374 stopTicker(gForceTicker);
uci1 8:95a325df1f6b 375 stopTicker(gHeartbeatTicker);
uci1 8:95a325df1f6b 376 stopTicker(gCommWinTicker);
uci1 8:95a325df1f6b 377 stopTicker(gPowerCheckTicker);
uci1 15:f2569d8e4176 378 }
uci1 15:f2569d8e4176 379
uci1 15:f2569d8e4176 380 void ResetAllTickers() {
uci1 15:f2569d8e4176 381 #ifdef USE_RTOS_TIMER
uci1 15:f2569d8e4176 382 const uint32_t ftp = resetTicker(gForceTicker, gConf.GetForceTrigPeriod(),
uci1 15:f2569d8e4176 383 kAbsMaxTimer);
uci1 15:f2569d8e4176 384 const uint32_t hbp = resetTicker(gHeartbeatTicker, gConf.GetHeartbeatPeriod(),
uci1 15:f2569d8e4176 385 kAbsMaxTimer);
uci1 15:f2569d8e4176 386 const uint32_t cwp = resetTicker(gCommWinTicker, gConf.GetCommWinPeriod(),
uci1 15:f2569d8e4176 387 kCommWinLongPrdTk);
uci1 15:f2569d8e4176 388 const uint32_t pcp = resetTicker(gPowerCheckTicker, gConf.GetVoltCheckPeriod(),
uci1 15:f2569d8e4176 389 kAbsMaxTimer);
uci1 15:f2569d8e4176 390 #else
uci1 15:f2569d8e4176 391 const uint32_t ftp = resetTicker(gForceTicker, gConf.GetForceTrigPeriod(),
uci1 15:f2569d8e4176 392 kAbsMaxTimer, &procForceTrigger);
uci1 15:f2569d8e4176 393 const uint32_t hbp = resetTicker(gHeartbeatTicker, gConf.GetHeartbeatPeriod(),
uci1 15:f2569d8e4176 394 kAbsMaxTimer, &procHeartbeat);
uci1 15:f2569d8e4176 395 const uint32_t cwp = resetTicker(gCommWinTicker, gConf.GetCommWinPeriod(),
uci1 15:f2569d8e4176 396 kCommWinLongPrdTk, &procCommWin);
uci1 15:f2569d8e4176 397 const uint32_t pcp = resetTicker(gPowerCheckTicker, gConf.GetVoltCheckPeriod(),
uci1 15:f2569d8e4176 398 kAbsMaxTimer, &procPowerCheck);
uci1 15:f2569d8e4176 399 #endif
uci1 15:f2569d8e4176 400 #ifdef DEBUG
uci1 15:f2569d8e4176 401 printf("attach force trig %u\r\n",ftp);
uci1 15:f2569d8e4176 402 printf("attach heart beat %u\r\n",hbp);
uci1 15:f2569d8e4176 403 printf("attach comm win %u\r\n",cwp);
uci1 15:f2569d8e4176 404 printf("attach power chk %u\r\n",pcp);
uci1 15:f2569d8e4176 405 #endif
uci1 15:f2569d8e4176 406 }
uci1 15:f2569d8e4176 407
uci1 15:f2569d8e4176 408 void StopRunning() {
uci1 15:f2569d8e4176 409 #if defined(DEBUG) || defined(SSNOTIFY)
uci1 15:f2569d8e4176 410 printf("stop running\r\n");
uci1 15:f2569d8e4176 411 #endif
uci1 15:f2569d8e4176 412 StopAllTickers();
uci1 8:95a325df1f6b 413 while (true) {
uci1 8:95a325df1f6b 414 led3 = 1; led4=1;
uci1 8:95a325df1f6b 415 wait(0.5);
uci1 8:95a325df1f6b 416 led3 = 0; led4=0;
uci1 8:95a325df1f6b 417 wait(0.5);
uci1 8:95a325df1f6b 418 //Watchdog::kick(); - if we kick the watchdog, the station is unrecoverable without physical access
uci1 8:95a325df1f6b 419 }
uci1 8:95a325df1f6b 420 }
uci1 1:e392595b4b76 421
uci1 0:664899e0b988 422 int main() {
uci1 1:e392595b4b76 423 {
uci1 15:f2569d8e4176 424 #ifdef SSNOTIFY
uci1 15:f2569d8e4176 425 printf("main: start\r\n");
uci1 15:f2569d8e4176 426 #endif
uci1 2:e67f7c158087 427 led1=1; wait(0.2);
uci1 2:e67f7c158087 428 led1=0; led2=1; wait(0.2);
uci1 2:e67f7c158087 429 led2=0; led3=1; wait(0.2);
uci1 2:e67f7c158087 430 led3=0; led4=1; wait(0.2);
uci1 1:e392595b4b76 431 led4=0;
uci1 1:e392595b4b76 432 }
uci1 1:e392595b4b76 433
uci1 8:95a325df1f6b 434 // RTOS stuff must be made inside main for some reason
uci1 15:f2569d8e4176 435 //gComms[0] = new SnCommAfarTCP(gConf);
uci1 15:f2569d8e4176 436 gComms[0] = new SnCommSBD(&gSBDport);
uci1 13:7a1fb885a8e4 437
uci1 8:95a325df1f6b 438 #ifdef USE_RTOS_TIMER
uci1 8:95a325df1f6b 439 gForceTicker = new rtos::RtosTimer(&procForceTrigger);
uci1 8:95a325df1f6b 440 gHeartbeatTicker = new rtos::RtosTimer(&procHeartbeat);
uci1 8:95a325df1f6b 441 gCommWinTicker = new rtos::RtosTimer(&procCommWin);
uci1 8:95a325df1f6b 442 gPowerCheckTicker = new rtos::RtosTimer(&procPowerCheck);
uci1 8:95a325df1f6b 443 #endif
uci1 8:95a325df1f6b 444
uci1 0:664899e0b988 445 led2=1;
uci1 0:664899e0b988 446 //wait_ms(100);
uci1 1:e392595b4b76 447
uci1 12:d472f9811262 448 #ifdef DEBUG
uci1 3:24c5f0f50bf1 449 printf("\n\n\n\n\n\nstarting\r\n");
uci1 12:d472f9811262 450 #endif
uci1 1:e392595b4b76 451
uci1 0:664899e0b988 452 // a failsafe
uci1 0:664899e0b988 453 Watchdog::kick(kWDFailsafe);
uci1 0:664899e0b988 454
uci1 1:e392595b4b76 455 // set the clock to the BS time, if it's not set
uci1 1:e392595b4b76 456 if ( (static_cast<int32_t>(time(0)))<0 ) {
uci1 1:e392595b4b76 457 set_time(kBStime);
uci1 1:e392595b4b76 458 }
uci1 12:d472f9811262 459 #ifdef DEBUG
uci1 1:e392595b4b76 460 printf("time = %d\r\n",(int32_t)time(0));
uci1 12:d472f9811262 461 #endif
uci1 1:e392595b4b76 462 gLastCommWin = time(0); // prevent comm win proc
uci1 0:664899e0b988 463
uci1 8:95a325df1f6b 464 #ifdef USE_RTOS_TIMER
uci1 8:95a325df1f6b 465 gForceTicker->stop();
uci1 8:95a325df1f6b 466 #else
uci1 0:664899e0b988 467 gForceTicker.detach();
uci1 8:95a325df1f6b 468 #endif
uci1 0:664899e0b988 469 gFirstEvt = true;
uci1 0:664899e0b988 470
uci1 4:a91682e19d6b 471 // (probably) power down comms and power up cards,amps
uci1 4:a91682e19d6b 472 SetPower(false);
uci1 4:a91682e19d6b 473
uci1 0:664899e0b988 474 //
uci1 0:664899e0b988 475 // get config
uci1 0:664899e0b988 476 //
uci1 12:d472f9811262 477 #ifdef DEBUG
uci1 8:95a325df1f6b 478 printf("call OpenCommWin\r\n");
uci1 12:d472f9811262 479 #endif
uci1 13:7a1fb885a8e4 480 OpenCommWin(true); // alwasy configure, even if no new config
uci1 3:24c5f0f50bf1 481
uci1 0:664899e0b988 482 // get ready to trigger
uci1 0:664899e0b988 483 PIN_spi.format( 16, 1 ); // change to data readout format
uci1 15:f2569d8e4176 484 PIN_spi.frequency( 10000000 ); // Max is 12.5 MHz
uci1 0:664899e0b988 485
uci1 0:664899e0b988 486 led2=0;
uci1 0:664899e0b988 487
uci1 0:664899e0b988 488 // the main event loop. wait for triggers in SendClock
uci1 12:d472f9811262 489 gTrgTimer.start();
uci1 12:d472f9811262 490 register int32_t etms=0; // time between written events
uci1 0:664899e0b988 491 while( true )
uci1 0:664899e0b988 492 {
uci1 0:664899e0b988 493 // in here, we wait for triggers from the MB-FPGA
uci1 0:664899e0b988 494 Watchdog::kick(); // don't reset!
uci1 1:e392595b4b76 495
uci1 1:e392595b4b76 496 led1 = !led1;
uci1 1:e392595b4b76 497
uci1 12:d472f9811262 498 #ifdef DEBUG
uci1 1:e392595b4b76 499 printf("calling wait trig\r\n");
uci1 1:e392595b4b76 500 printf("gFirstEvt=%s\r\n",gFirstEvt?"true":"false");
uci1 5:9cea89700c66 501 printf("readingout=%d\r\n",(int)gReadingOut);
uci1 12:d472f9811262 502 #endif
uci1 1:e392595b4b76 503
uci1 0:664899e0b988 504 PIN_lockRegisters = 0; // allow data to come from DFPGA
uci1 0:664899e0b988 505 WaitTrigAndSendClock();
uci1 0:664899e0b988 506 PIN_lockRegisters = 1; // block registers during readout
uci1 1:e392595b4b76 507
uci1 12:d472f9811262 508 #ifdef EVT_TIME_PROFILE
uci1 12:d472f9811262 509 Timer prof;
uci1 12:d472f9811262 510 prof.start();
uci1 12:d472f9811262 511 int befReadWv=0, aftReadWv=0, befSaveEvt=0, aftSaveEvt=0,
uci1 12:d472f9811262 512 befChkPow=0, aftChkPow=0, befNewSeq=0, aftNewSeq=0, endOfLoop=0;
uci1 12:d472f9811262 513 #endif
uci1 12:d472f9811262 514
uci1 1:e392595b4b76 515 if (gReadingOut) {
uci1 12:d472f9811262 516
uci1 12:d472f9811262 517 const int32_t ttms = gTrgTimer.read_ms(); // time since last trigger
uci1 12:d472f9811262 518 gTrgTimer.reset(); gTrgTimer.start(); // restart trigger timer
uci1 12:d472f9811262 519 etms += ttms;
uci1 8:95a325df1f6b 520
uci1 8:95a325df1f6b 521 Watchdog::kick(); // don't reset!
uci1 15:f2569d8e4176 522
uci1 1:e392595b4b76 523 //
uci1 1:e392595b4b76 524 // got trigger. read registers to mbed and build the event
uci1 1:e392595b4b76 525 //
uci1 1:e392595b4b76 526
uci1 1:e392595b4b76 527 led4=1;
uci1 1:e392595b4b76 528
uci1 1:e392595b4b76 529 // read data & calc CRC
uci1 12:d472f9811262 530 #ifdef EVT_TIME_PROFILE
uci1 12:d472f9811262 531 prof.stop(); befReadWv=prof.read_us(); prof.start();
uci1 12:d472f9811262 532 #endif
uci1 12:d472f9811262 533
uci1 1:e392595b4b76 534 gEvent.ReadWaveforms(PIN_spi, PIN_selCardHiBit, PIN_selCardLoBit);
uci1 15:f2569d8e4176 535
uci1 12:d472f9811262 536 #ifdef EVT_TIME_PROFILE
uci1 12:d472f9811262 537 prof.stop(); aftReadWv=prof.read_us(); prof.start();
uci1 12:d472f9811262 538 #endif
uci1 12:d472f9811262 539
uci1 1:e392595b4b76 540 gEvent.SetCurMbedTime();
uci1 1:e392595b4b76 541 // TODO: no way to check for external trigger?
uci1 1:e392595b4b76 542 if (gEvent.IsForcedTrg()==false) {
uci1 1:e392595b4b76 543 gEvent.SetTrgBit(kThmTrg);
uci1 1:e392595b4b76 544 gEvent.SetTrgNum((gTrgNum[kThmTrg])++);
uci1 1:e392595b4b76 545 } // else already set by procForceTrigger
uci1 1:e392595b4b76 546 // (no need to calc if we throw this event away)
uci1 1:e392595b4b76 547
uci1 1:e392595b4b76 548 Watchdog::kick(); // don't reset!
uci1 1:e392595b4b76 549
uci1 12:d472f9811262 550 #ifdef DEBUG
uci1 1:e392595b4b76 551 printf("gFirstEvt=%s\r\n",gFirstEvt?"true":"false");
uci1 12:d472f9811262 552 #endif
uci1 1:e392595b4b76 553
uci1 1:e392595b4b76 554 if ( gEvent.IsForcedTrg() || gFirstEvt ||
uci1 1:e392595b4b76 555 (etms>gConf.GetEvtThrtlPeriodMs()) ) {
uci1 1:e392595b4b76 556
uci1 1:e392595b4b76 557 led2=1;
uci1 1:e392595b4b76 558
uci1 1:e392595b4b76 559 PIN_lockRegisters = 0; // done reading, unlock so we can talk to SD card.
uci1 1:e392595b4b76 560
uci1 12:d472f9811262 561 #ifdef EVT_TIME_PROFILE
uci1 12:d472f9811262 562 prof.stop(); befSaveEvt=prof.read_us(); prof.start();
uci1 12:d472f9811262 563 #endif
uci1 12:d472f9811262 564
uci1 1:e392595b4b76 565 SaveEvent(etms);
uci1 12:d472f9811262 566 etms=0;
uci1 8:95a325df1f6b 567
uci1 12:d472f9811262 568 #ifdef EVT_TIME_PROFILE
uci1 12:d472f9811262 569 prof.stop(); aftSaveEvt=prof.read_us(); prof.start();
uci1 12:d472f9811262 570 #endif
uci1 1:e392595b4b76 571 }
uci1 1:e392595b4b76 572 }
uci1 12:d472f9811262 573 #ifdef DEBUG
uci1 1:e392595b4b76 574 printf("past reading out\r\n");
uci1 12:d472f9811262 575 #endif
uci1 1:e392595b4b76 576
uci1 1:e392595b4b76 577 led4=0; led2=0;
uci1 12:d472f9811262 578
uci1 12:d472f9811262 579 #ifdef EVT_TIME_PROFILE
uci1 12:d472f9811262 580 prof.stop(); befChkPow=prof.read_us(); prof.start();
uci1 12:d472f9811262 581 #endif
uci1 8:95a325df1f6b 582 // check the power?
uci1 8:95a325df1f6b 583 if (gCheckPower) {
uci1 12:d472f9811262 584 #ifdef DEBUG
uci1 8:95a325df1f6b 585 printf("call check power\r\n");
uci1 12:d472f9811262 586 #endif
uci1 8:95a325df1f6b 587 CheckPower(false);
uci1 8:95a325df1f6b 588 }
uci1 12:d472f9811262 589 #ifdef EVT_TIME_PROFILE
uci1 12:d472f9811262 590 prof.stop(); aftChkPow=prof.read_us(); prof.start();
uci1 12:d472f9811262 591 #endif
uci1 8:95a325df1f6b 592
uci1 12:d472f9811262 593 #ifdef EVT_TIME_PROFILE
uci1 12:d472f9811262 594 prof.stop(); befNewSeq=prof.read_us(); prof.start();
uci1 12:d472f9811262 595 #endif
uci1 8:95a325df1f6b 596 // make new seq?
uci1 8:95a325df1f6b 597 if (IsSeqComplete()) {
uci1 12:d472f9811262 598 #ifdef DEBUG
uci1 10:3c93db1cfb12 599 printf("seq complete. sngseq=%d\r\n",gConf.IsSingleSeqRunMode());
uci1 12:d472f9811262 600 #endif
uci1 8:95a325df1f6b 601 MakeOutputFile(gConf.IsSingleSeqRunMode());
uci1 8:95a325df1f6b 602 }
uci1 12:d472f9811262 603 #ifdef EVT_TIME_PROFILE
uci1 12:d472f9811262 604 prof.stop(); aftNewSeq=prof.read_us(); prof.start();
uci1 12:d472f9811262 605 #endif
uci1 12:d472f9811262 606
uci1 8:95a325df1f6b 607 // open comm win?
uci1 0:664899e0b988 608 if (gOpenCommWin) {
uci1 12:d472f9811262 609 #ifdef DEBUG
uci1 1:e392595b4b76 610 printf("gOpenComWin=%s, opening\r\n",gOpenCommWin?"true":"false");
uci1 12:d472f9811262 611 #endif
uci1 0:664899e0b988 612 OpenCommWin();
uci1 0:664899e0b988 613 gOpenCommWin=false;
uci1 1:e392595b4b76 614 } else {
uci1 12:d472f9811262 615 #ifdef DEBUG
uci1 1:e392595b4b76 616 printf("gOpenCommWin=false\r\n");
uci1 12:d472f9811262 617 #endif
uci1 0:664899e0b988 618 }
uci1 12:d472f9811262 619
uci1 12:d472f9811262 620 #ifdef EVT_TIME_PROFILE
uci1 12:d472f9811262 621 prof.stop(); endOfLoop=prof.read_us(); prof.start();
uci1 12:d472f9811262 622 printf("befReadWv=%d, aftReadWv=%d, befSaveEvt=%d, aftSaveEvt=%d, "
uci1 12:d472f9811262 623 "befChkPow=%d, aftChkPow=%d, befNewSeq=%d, aftNewSeq=%d, endOfLoop=%d\r\n",
uci1 12:d472f9811262 624 befReadWv, aftReadWv, befSaveEvt, aftSaveEvt,
uci1 12:d472f9811262 625 befChkPow, aftChkPow, befNewSeq, aftNewSeq, endOfLoop);
uci1 12:d472f9811262 626 #endif
uci1 15:f2569d8e4176 627
uci1 15:f2569d8e4176 628 // get ready to trigger
uci1 15:f2569d8e4176 629 PIN_spi.format( 16, 1 ); // change to data readout format
uci1 15:f2569d8e4176 630 PIN_spi.frequency( 10000000 ); // Max is 12.5 MHz
uci1 0:664899e0b988 631 }
uci1 0:664899e0b988 632
uci1 0:664899e0b988 633 }
uci1 0:664899e0b988 634
uci1 0:664899e0b988 635 //
uci1 0:664899e0b988 636 // save the event
uci1 0:664899e0b988 637 //
uci1 0:664899e0b988 638 void SaveEvent(const int32_t etms) {
uci1 0:664899e0b988 639 // write the event
uci1 12:d472f9811262 640
uci1 12:d472f9811262 641 #ifdef DEBUG
uci1 3:24c5f0f50bf1 642 printf("save event\r\n");
uci1 12:d472f9811262 643 #endif
uci1 3:24c5f0f50bf1 644
uci1 0:664899e0b988 645 // set the event number & dt
uci1 3:24c5f0f50bf1 646 gEvent.SetEvtNum(gEvtNum);
uci1 0:664899e0b988 647 gEvent.SetDTms(etms);
uci1 0:664899e0b988 648
uci1 0:664899e0b988 649 // save to SD
uci1 11:de443350ec4a 650 PIN_lockRegisters = 0; // unlock so we can talk to SD card.
uci1 1:e392595b4b76 651 SnSDUtils::WriteEventTo(SnSDUtils::GetCurFile(), gGenBuf, gEvent, gConf);
uci1 0:664899e0b988 652
uci1 0:664899e0b988 653 // reset
uci1 0:664899e0b988 654 gEvent.ClearEvent();
uci1 0:664899e0b988 655
uci1 3:24c5f0f50bf1 656 // increment event number
uci1 3:24c5f0f50bf1 657 ++gEvtNum;
uci1 3:24c5f0f50bf1 658
uci1 12:d472f9811262 659 #ifdef DEBUG
uci1 8:95a325df1f6b 660 printf("gEvtNum=%u\r\n",gEvtNum);
uci1 12:d472f9811262 661 #endif
uci1 3:24c5f0f50bf1 662 }
uci1 3:24c5f0f50bf1 663
uci1 3:24c5f0f50bf1 664 void MakeOutputFile(const bool stopRunning) {
uci1 10:3c93db1cfb12 665 PIN_lockRegisters = 0; // unlock so we can talk to SD card.
uci1 12:d472f9811262 666 #ifdef DEBUG
uci1 10:3c93db1cfb12 667 printf("closing output file. gEvtNum=%u, gPowNum=%u, stop=%d\r\n",
uci1 10:3c93db1cfb12 668 gEvtNum,gPowNum,(int)stopRunning);
uci1 12:d472f9811262 669 #endif
uci1 13:7a1fb885a8e4 670
uci1 3:24c5f0f50bf1 671 SnSDUtils::CloseOutputFile(SnSDUtils::GetCurFile());
uci1 13:7a1fb885a8e4 672
uci1 12:d472f9811262 673 #ifdef DEBUG
uci1 10:3c93db1cfb12 674 printf("file closed\r\n");
uci1 12:d472f9811262 675 #endif
uci1 3:24c5f0f50bf1 676 if (stopRunning) {
uci1 8:95a325df1f6b 677 StopRunning();
uci1 0:664899e0b988 678 }
uci1 8:95a325df1f6b 679 FILE* cf = SnSDUtils::OpenNewOutputFile(gConf.GetMacAddress(),
uci1 8:95a325df1f6b 680 gConf.GetRun());
uci1 13:7a1fb885a8e4 681 // reset event, timers, trigger counters
uci1 13:7a1fb885a8e4 682 ResetCountersClearEvt();
uci1 8:95a325df1f6b 683 if (cf!=0) {
uci1 8:95a325df1f6b 684 wait_ms(200);
uci1 8:95a325df1f6b 685 GetAvePowerReading();
uci1 12:d472f9811262 686 #ifdef DEBUG
uci1 8:95a325df1f6b 687 printf("writing power. v1=%g, v2=%g, r1=%g, r2=%g, t=%u, pownum=%u\r\n",
uci1 8:95a325df1f6b 688 gPower.GetAveV1(), gPower.GetAveV2(),
uci1 8:95a325df1f6b 689 gPower.GetRmsV1(), gPower.GetRmsV2(), gPower.GetTime(),
uci1 8:95a325df1f6b 690 gPowNum);
uci1 12:d472f9811262 691 #endif
uci1 8:95a325df1f6b 692 SnSDUtils::WritePowerTo(cf, gPower, gPowNum);
uci1 8:95a325df1f6b 693 }
uci1 12:d472f9811262 694 #ifdef DEBUG
uci1 3:24c5f0f50bf1 695 printf("made output file with run %u\r\n",gConf.GetRun());
uci1 3:24c5f0f50bf1 696 printf("filename=%s\r\n",SnSDUtils::GetCurFileName());
uci1 12:d472f9811262 697 #endif
uci1 3:24c5f0f50bf1 698 SnSDUtils::WriteConfig(SnSDUtils::GetCurFile(), gConf);
uci1 0:664899e0b988 699 }
uci1 0:664899e0b988 700
uci1 0:664899e0b988 701 //
uci1 4:a91682e19d6b 702 // power stuff
uci1 4:a91682e19d6b 703 //
uci1 4:a91682e19d6b 704 void SetPower(const bool isCommWin) {
uci1 8:95a325df1f6b 705 // TODO: turn on amps individually, when that's possible
uci1 4:a91682e19d6b 706 if (isCommWin) {
uci1 5:9cea89700c66 707 PIN_turn_on_system = gConf.GetPowPinSetting(SnConfigFrame::kCardComWin);
uci1 4:a91682e19d6b 708 wait_ms(10);
uci1 5:9cea89700c66 709 PIN_turn_on_amps = gConf.GetPowPinSetting(SnConfigFrame::kAmpsComWin);
uci1 4:a91682e19d6b 710 wait_ms(10);
uci1 5:9cea89700c66 711 PIN_iridSbd_power = gConf.GetPowPinSetting(SnConfigFrame::kIridComWin);
uci1 4:a91682e19d6b 712 wait_ms(10);
uci1 5:9cea89700c66 713 PIN_afar_power = gConf.GetPowPinSetting(SnConfigFrame::kAfarComWin);
uci1 4:a91682e19d6b 714 wait_ms(10);
uci1 4:a91682e19d6b 715 } else {
uci1 5:9cea89700c66 716 PIN_turn_on_system = gConf.GetPowPinSetting(SnConfigFrame::kCardDatTak);
uci1 4:a91682e19d6b 717 wait_ms(10);
uci1 5:9cea89700c66 718 PIN_turn_on_amps = gConf.GetPowPinSetting(SnConfigFrame::kAmpsDatTak);
uci1 4:a91682e19d6b 719 wait_ms(10);
uci1 5:9cea89700c66 720 PIN_iridSbd_power = gConf.GetPowPinSetting(SnConfigFrame::kIridDatTak);
uci1 4:a91682e19d6b 721 wait_ms(10);
uci1 5:9cea89700c66 722 PIN_afar_power = gConf.GetPowPinSetting(SnConfigFrame::kAfarDatTak);
uci1 4:a91682e19d6b 723 wait_ms(10);
uci1 4:a91682e19d6b 724 }
uci1 15:f2569d8e4176 725 wait(1); // let things power up
uci1 12:d472f9811262 726 #ifdef DEBUG
uci1 6:6f002d202f59 727 printf("set power (iscom %d, pw %hhu): cards %d, amps %d, irid %d, afar %d\r\n",
uci1 6:6f002d202f59 728 isCommWin, gConf.GetPowerMode(), PIN_turn_on_system.read(), PIN_turn_on_amps.read(),
uci1 6:6f002d202f59 729 PIN_iridSbd_power.read(), PIN_afar_power.read());
uci1 12:d472f9811262 730 #endif
uci1 4:a91682e19d6b 731 }
uci1 4:a91682e19d6b 732
uci1 4:a91682e19d6b 733 //
uci1 0:664899e0b988 734 // set configuration
uci1 0:664899e0b988 735 //
uci1 1:e392595b4b76 736 void SetConfigAndMakeOutputFile() {
uci1 12:d472f9811262 737 #ifdef DEBUG
uci1 1:e392595b4b76 738 printf("SetConfigAndMakeOutputFile\r\n");
uci1 12:d472f9811262 739 #endif
uci1 1:e392595b4b76 740
uci1 0:664899e0b988 741 // restart watchdog
uci1 0:664899e0b988 742 Watchdog::kick(gConf.GetWatchdogPeriod());
uci1 0:664899e0b988 743
uci1 1:e392595b4b76 744 // block (thermal) triggers during configuration
uci1 1:e392595b4b76 745 PIN_enableThermTrig = 0;
uci1 1:e392595b4b76 746 PIN_ADC_CS = 1;
uci1 1:e392595b4b76 747 PIN_DoNotRestartAllClocks = 1;
uci1 1:e392595b4b76 748 PIN_forceTrigger = 0;
uci1 3:24c5f0f50bf1 749 PIN_heartbeat = 0;
uci1 1:e392595b4b76 750 wait_ms(20);
uci1 1:e392595b4b76 751
uci1 8:95a325df1f6b 752 if (AreCardsPowered()) {
uci1 8:95a325df1f6b 753 // Set PLA value(s)
uci1 8:95a325df1f6b 754 PIN_spi.format( 16, 0 ); // change mode for DAC & PLA value setting
uci1 8:95a325df1f6b 755 PIN_spi.frequency(1000000);
uci1 8:95a325df1f6b 756 PIN_MajLogHiBit=1;
uci1 8:95a325df1f6b 757 PIN_MajLogLoBit=1;
uci1 8:95a325df1f6b 758 PIN_enableThermTrig=0;
uci1 0:664899e0b988 759
uci1 8:95a325df1f6b 760 uint16_t hi, lo;
uci1 8:95a325df1f6b 761 PIN_PLA_cs=1;
uci1 8:95a325df1f6b 762 wait(4);
uci1 8:95a325df1f6b 763 for (uint8_t pi=0; pi<kNplas; pi++) {
uci1 8:95a325df1f6b 764 if (pi < gConf.GetNumPlas()) {
uci1 8:95a325df1f6b 765 SnConfigFrame::GetHiLoPlas(gConf.GetPla(pi), hi, lo);
uci1 8:95a325df1f6b 766 PIN_spi.write(hi);
uci1 8:95a325df1f6b 767 PIN_spi.write(lo);
uci1 12:d472f9811262 768 #ifdef DEBUG
uci1 8:95a325df1f6b 769 printf("pla hi %hu, lo %hu\r\n",hi,lo);
uci1 12:d472f9811262 770 #endif
uci1 8:95a325df1f6b 771 } else {
uci1 8:95a325df1f6b 772 PIN_spi.write(kNoTrigPla); // hi
uci1 8:95a325df1f6b 773 PIN_spi.write(kNoTrigPla); // lo
uci1 12:d472f9811262 774 #ifdef DEBUG
uci1 8:95a325df1f6b 775 printf("pla hi %hu, lo %hu\r\n",kNoTrigPla,kNoTrigPla);
uci1 12:d472f9811262 776 #endif
uci1 8:95a325df1f6b 777 }
uci1 8:95a325df1f6b 778 Watchdog::kick();
uci1 0:664899e0b988 779 }
uci1 8:95a325df1f6b 780 wait(3);
uci1 8:95a325df1f6b 781 PIN_PLA_cs=0;
uci1 8:95a325df1f6b 782 wait(3);
uci1 0:664899e0b988 783
uci1 8:95a325df1f6b 784 // DAC values
uci1 8:95a325df1f6b 785 //
uci1 8:95a325df1f6b 786 // first 12 bits = DAC value
uci1 8:95a325df1f6b 787 // next 2 bits = DAC ID
uci1 8:95a325df1f6b 788 // last 2 bits = dFPGA ID
uci1 8:95a325df1f6b 789 //
uci1 8:95a325df1f6b 790 // But FPGA uses "gray encoding" which means only 1 bit
uci1 8:95a325df1f6b 791 // can change at a time (of the last 4 bits). So even tho
uci1 8:95a325df1f6b 792 // the card/dac# is encoded, the order is also important
uci1 8:95a325df1f6b 793 // 0000 (dac0,card0), 0001 (dac0,card1), 0011 (dac0,card3), 0010 (dac0,card2),
uci1 8:95a325df1f6b 794 // 0110 (dac1,card2), 0111 (dac1,card3), 0101 (dac1,card1), etc.
uci1 12:d472f9811262 795 #ifdef DEBUG
uci1 8:95a325df1f6b 796 printf("setting dacs\r\n");
uci1 12:d472f9811262 797 #endif
uci1 8:95a325df1f6b 798 uint16_t dv=0;
uci1 8:95a325df1f6b 799 for (uint8_t i=0, gri=0; i<kTotDacs; i++) {
uci1 8:95a325df1f6b 800 // get the gray-codes for this iteration
uci1 8:95a325df1f6b 801 gri = SnBitUtils::binToGray(i);
uci1 8:95a325df1f6b 802
uci1 8:95a325df1f6b 803 // build bit word
uci1 8:95a325df1f6b 804 dv = static_cast<int>(gConf.GetDac(gri & 0x0003u, gri >> 2u));
uci1 8:95a325df1f6b 805 dv <<= 4u;
uci1 8:95a325df1f6b 806 dv |= gri;
uci1 8:95a325df1f6b 807
uci1 12:d472f9811262 808 #ifdef DEBUG
uci1 8:95a325df1f6b 809 printf("dac %04x\r\n",dv);
uci1 12:d472f9811262 810 #endif
uci1 8:95a325df1f6b 811
uci1 8:95a325df1f6b 812 // send to FPGA
uci1 8:95a325df1f6b 813 PIN_start_fpga=1;
uci1 8:95a325df1f6b 814 PIN_spi.write(dv);
uci1 8:95a325df1f6b 815 PIN_start_fpga=0;
uci1 8:95a325df1f6b 816
uci1 8:95a325df1f6b 817 Watchdog::kick();
uci1 8:95a325df1f6b 818
uci1 8:95a325df1f6b 819 }
uci1 12:d472f9811262 820 #ifdef DEBUG
uci1 8:95a325df1f6b 821 printf("dacs set\r\n");
uci1 12:d472f9811262 822 #endif
uci1 8:95a325df1f6b 823 wait_ms(20);
uci1 8:95a325df1f6b 824 } else {
uci1 12:d472f9811262 825 #ifdef DEBUG
uci1 8:95a325df1f6b 826 printf("cards off. skipping PLA and DAC setting\r\n");
uci1 12:d472f9811262 827 #endif
uci1 0:664899e0b988 828 }
uci1 0:664899e0b988 829
uci1 0:664899e0b988 830 // Majority Logic Trigger selection (# of cards)
uci1 0:664899e0b988 831 SnBitUtils::SetChanNumBits(gConf.GetNumCardsMajLog() - 1u,
uci1 0:664899e0b988 832 PIN_MajLogHiBit, PIN_MajLogLoBit);
uci1 0:664899e0b988 833
uci1 0:664899e0b988 834 // Enable thermal trigger?
uci1 0:664899e0b988 835 PIN_enableThermTrig = gConf.IsThermTrigEnabled();
uci1 0:664899e0b988 836
uci1 0:664899e0b988 837 PIN_spi.format( 16, 1 ); // back to trigger mode
uci1 1:e392595b4b76 838 PIN_spi.frequency( 10000000 ); // Max is 12.5 MHz
uci1 1:e392595b4b76 839
uci1 8:95a325df1f6b 840 // make new output file
uci1 8:95a325df1f6b 841 // put after PLA/DAC, in case they affect the power readings
uci1 8:95a325df1f6b 842 wait_ms(200);
uci1 8:95a325df1f6b 843 MakeOutputFile();
uci1 8:95a325df1f6b 844
uci1 15:f2569d8e4176 845 // reset tickers
uci1 15:f2569d8e4176 846 ResetAllTickers();
uci1 8:95a325df1f6b 847
uci1 8:95a325df1f6b 848 // TODO: change comm parameters
uci1 8:95a325df1f6b 849 /*
uci1 8:95a325df1f6b 850 printf("set comm params\r\n");
uci1 8:95a325df1f6b 851 for (uint8_t cc=0; cc<kNcomms; cc++) {
uci1 8:95a325df1f6b 852 if (gComms[cc]!=0) {
uci1 8:95a325df1f6b 853 gComms[cc]->Set(gConf);
uci1 8:95a325df1f6b 854 }
uci1 3:24c5f0f50bf1 855 }
uci1 8:95a325df1f6b 856 */
uci1 0:664899e0b988 857
uci1 0:664899e0b988 858 Watchdog::kick(); // don't reset!
uci1 8:95a325df1f6b 859
uci1 12:d472f9811262 860 #ifdef DEBUG
uci1 8:95a325df1f6b 861 printf("set config done\r\n");
uci1 12:d472f9811262 862 #endif
uci1 0:664899e0b988 863 }
uci1 0:664899e0b988 864
uci1 0:664899e0b988 865 //
uci1 0:664899e0b988 866 // readout functions
uci1 0:664899e0b988 867 //
uci1 0:664899e0b988 868 void WaitTrigAndSendClock() {
uci1 1:e392595b4b76 869
uci1 12:d472f9811262 870 #ifdef DEBUG
uci1 1:e392595b4b76 871 printf("WaitTrigAndSendClock\r\n");
uci1 6:6f002d202f59 872 printf("wait trig: (pw %hhu): cards %d, amps %d, irid %d, afar %d\r\n",
uci1 6:6f002d202f59 873 gConf.GetPowerMode(), PIN_turn_on_system.read(), PIN_turn_on_amps.read(),
uci1 6:6f002d202f59 874 PIN_iridSbd_power.read(), PIN_afar_power.read());
uci1 8:95a325df1f6b 875 printf("cards powered=%d\r\n",(int)AreCardsPowered());
uci1 12:d472f9811262 876 #endif
uci1 0:664899e0b988 877
uci1 15:f2569d8e4176 878 PIN_spi.format( 16, 1 ); // back to trigger mode
uci1 15:f2569d8e4176 879 PIN_spi.frequency( 10000000 ); // Max is 12.5 MHz
uci1 15:f2569d8e4176 880
uci1 8:95a325df1f6b 881 if (AreCardsPowered()) {
uci1 8:95a325df1f6b 882
uci1 8:95a325df1f6b 883 if (gFirstEvt==false) {
uci1 8:95a325df1f6b 884 PIN_DoNotRestartAllClocks = 0;
uci1 8:95a325df1f6b 885 wait_us(1);
uci1 8:95a325df1f6b 886 PIN_DoNotRestartAllClocks = 1;
uci1 8:95a325df1f6b 887 //led3 = !led3; // toggle send clock led
uci1 8:95a325df1f6b 888 } else {
uci1 8:95a325df1f6b 889 gFirstEvt = false;
uci1 8:95a325df1f6b 890 }
uci1 8:95a325df1f6b 891
uci1 8:95a325df1f6b 892 //
uci1 8:95a325df1f6b 893 // wait for a trigger here.
uci1 8:95a325df1f6b 894 //
uci1 12:d472f9811262 895 #ifdef DEBUG
uci1 8:95a325df1f6b 896 printf("starting wait for trig\r\n");
uci1 12:d472f9811262 897 #endif
uci1 8:95a325df1f6b 898 gReadingOut = false; // this will allow forced triggers (see procForceTrigger())
uci1 8:95a325df1f6b 899 while ( PIN_a_sf_clk == 1 ) {
uci1 8:95a325df1f6b 900 if (gOpenCommWin || gCheckPower) {
uci1 12:d472f9811262 901 #ifdef DEBUG
uci1 8:95a325df1f6b 902 printf("break com=%d, pow=%d\r\n",gOpenCommWin,gCheckPower);
uci1 12:d472f9811262 903 #endif
uci1 8:95a325df1f6b 904 return; // break out to open comms or check power
uci1 8:95a325df1f6b 905 }
uci1 0:664899e0b988 906 }
uci1 8:95a325df1f6b 907 PIN_forceTrigger=0; // necessary for forced triggers, harmless for other triggers
uci1 8:95a325df1f6b 908 gReadingOut = true; // disallow new forced triggers
uci1 15:f2569d8e4176 909
uci1 15:f2569d8e4176 910 // we can't be interrupted before data arrives at the MB FPGA
uci1 15:f2569d8e4176 911 //StopAllTickers();
uci1 15:f2569d8e4176 912 /*
uci1 15:f2569d8e4176 913 procForceTrigger();
uci1 15:f2569d8e4176 914 procHeartbeat();
uci1 15:f2569d8e4176 915 procPowerCheck();
uci1 15:f2569d8e4176 916 procCommWin();
uci1 15:f2569d8e4176 917 */
uci1 15:f2569d8e4176 918
uci1 8:95a325df1f6b 919 //
uci1 8:95a325df1f6b 920 // collect data from daughter cards
uci1 8:95a325df1f6b 921 //
uci1 8:95a325df1f6b 922 // TODO: what if some card (set of channels) doesn't respond?
uci1 8:95a325df1f6b 923 // currently, will wait forever?
uci1 8:95a325df1f6b 924 // also, if ch1 is dead, will wait forever (due to FPGA code)
uci1 8:95a325df1f6b 925 for( uint8_t i = 0; i < kNsamps; i++ ) {
uci1 8:95a325df1f6b 926 if( PIN_a_sf_clk == 1 ) {
uci1 8:95a325df1f6b 927 if( i == 0 )
uci1 8:95a325df1f6b 928 wait_us( 1 );
uci1 8:95a325df1f6b 929
uci1 8:95a325df1f6b 930 PIN_ADC_CS = 0;
uci1 8:95a325df1f6b 931 PIN_spi.write( 0x00 );
uci1 8:95a325df1f6b 932 PIN_ADC_CS = 1;
uci1 8:95a325df1f6b 933 } else {
uci1 8:95a325df1f6b 934 i--;
uci1 8:95a325df1f6b 935 }
uci1 0:664899e0b988 936 }
uci1 15:f2569d8e4176 937
uci1 15:f2569d8e4176 938 // restart the timers
uci1 15:f2569d8e4176 939 //ResetAllTickers();
uci1 15:f2569d8e4176 940
uci1 8:95a325df1f6b 941 } else {
uci1 8:95a325df1f6b 942 // cards have no power. don't try reading out
uci1 8:95a325df1f6b 943 gReadingOut=false;
uci1 0:664899e0b988 944 }
uci1 0:664899e0b988 945 }
uci1 0:664899e0b988 946
uci1 13:7a1fb885a8e4 947 SnCommWin::ECommWinResult OpenCommWin(const bool forceReconfig) {
uci1 0:664899e0b988 948 // loop through each comm mode:
uci1 0:664899e0b988 949 // a) try to connect
uci1 0:664899e0b988 950 // b) if connected, listen for config
uci1 0:664899e0b988 951 // c) if config requests data, send it
uci1 3:24c5f0f50bf1 952
uci1 3:24c5f0f50bf1 953 gLastCommWin = time(0);
uci1 13:7a1fb885a8e4 954
uci1 0:664899e0b988 955 SnCommWin::ECommWinResult res = SnCommWin::kUndefFail;
uci1 0:664899e0b988 956
uci1 1:e392595b4b76 957 bool gotNewConfig=false;
uci1 13:7a1fb885a8e4 958
uci1 13:7a1fb885a8e4 959 if (gConf.GetCommWinDuration()==0) {
uci1 13:7a1fb885a8e4 960 // TODO: set min so this is not possible
uci1 13:7a1fb885a8e4 961 res = SnCommWin::kOkNoMsg;
uci1 13:7a1fb885a8e4 962 } else {
uci1 13:7a1fb885a8e4 963
uci1 13:7a1fb885a8e4 964 gCommWinOpen = true;
uci1 1:e392595b4b76 965 Watchdog::kick(); // don't reset!
uci1 13:7a1fb885a8e4 966
uci1 13:7a1fb885a8e4 967 #ifdef DEBUG
uci1 13:7a1fb885a8e4 968 printf("opening comm window at %d\r\n", (int32_t)gLastCommWin);
uci1 13:7a1fb885a8e4 969 #endif
uci1 13:7a1fb885a8e4 970
uci1 13:7a1fb885a8e4 971 // close the file so that the data is all written out.
uci1 13:7a1fb885a8e4 972 // and open it back up at the beginning (for reading)
uci1 12:d472f9811262 973 #ifdef DEBUG
uci1 13:7a1fb885a8e4 974 printf("close & open file. gEvtNum=%u, gPowNum=%u\r\n",gEvtNum,gPowNum);
uci1 12:d472f9811262 975 #endif
uci1 13:7a1fb885a8e4 976 PIN_lockRegisters = 0; // unlock so we can talk to SD card.
uci1 13:7a1fb885a8e4 977 SnSDUtils::CloseOutputFile(SnSDUtils::GetCurFile());
uci1 13:7a1fb885a8e4 978 SnSDUtils::OpenExistingFile(SnSDUtils::GetCurFileName(), true);
uci1 13:7a1fb885a8e4 979
uci1 13:7a1fb885a8e4 980 // (probably) power down cards,amps and power up comms
uci1 13:7a1fb885a8e4 981 SetPower(true);
uci1 13:7a1fb885a8e4 982
uci1 15:f2569d8e4176 983
uci1 15:f2569d8e4176 984 // TODO: implement asking the comms for their timeout
uci1 15:f2569d8e4176 985 //const uint32_t conto = (gConf.GetCommWinDuration() < kConnectTimeout) ?
uci1 15:f2569d8e4176 986 // gConf.GetCommWinDuration() : kConnectTimeout;
uci1 15:f2569d8e4176 987 const uint32_t conto = (gConf.GetCommWinDuration() < kConnectTOSBD) ?
uci1 15:f2569d8e4176 988 gConf.GetCommWinDuration() : kConnectTOSBD;
uci1 13:7a1fb885a8e4 989 const uint32_t listo = (gConf.GetCommWinDuration() < kListenTimeout) ?
uci1 13:7a1fb885a8e4 990 gConf.GetCommWinDuration() : kListenTimeout;
uci1 13:7a1fb885a8e4 991
uci1 13:7a1fb885a8e4 992 bool sendStat[kNcomms];
uci1 13:7a1fb885a8e4 993 for (uint8_t i=0; i<kNcomms; i++) {
uci1 13:7a1fb885a8e4 994 sendStat[i]=true;
uci1 13:7a1fb885a8e4 995 }
uci1 13:7a1fb885a8e4 996 bool* ss = sendStat;
uci1 13:7a1fb885a8e4 997 SnCommWin** cw = gComms;
uci1 13:7a1fb885a8e4 998 for (uint8_t i=0; ((time(0)-gLastCommWin)<gConf.GetCommWinDuration()); i++, cw++, ss++) {
uci1 1:e392595b4b76 999 Watchdog::kick(); // don't reset!
uci1 13:7a1fb885a8e4 1000 if (i==kNcomms) {
uci1 13:7a1fb885a8e4 1001 i=0;
uci1 13:7a1fb885a8e4 1002 cw = gComms;
uci1 13:7a1fb885a8e4 1003 ss = sendStat;
uci1 13:7a1fb885a8e4 1004 }
uci1 13:7a1fb885a8e4 1005 if ((*cw)==0) {
uci1 13:7a1fb885a8e4 1006 continue;
uci1 13:7a1fb885a8e4 1007 }
uci1 13:7a1fb885a8e4 1008 // open window and (mabye) send status update
uci1 12:d472f9811262 1009 #ifdef DEBUG
uci1 13:7a1fb885a8e4 1010 printf("calling OpenWindow. ss=%d\r\n",(int)(*ss));
uci1 13:7a1fb885a8e4 1011 printf("gtt=%u, ct=%d, lcw=%d, dur=%u\r\n",GetTimeoutTime(gLastCommWin,conto),
uci1 13:7a1fb885a8e4 1012 time(0), gLastCommWin, gConf.GetCommWinDuration());
uci1 12:d472f9811262 1013 #endif
uci1 13:7a1fb885a8e4 1014 // update power reading in case we want to send it in status
uci1 13:7a1fb885a8e4 1015 GetAvePowerReading();
uci1 13:7a1fb885a8e4 1016 // get the trigger rates
uci1 13:7a1fb885a8e4 1017 float thmrate=0, evtrate=0;
uci1 13:7a1fb885a8e4 1018 GetRates(thmrate, evtrate);
uci1 13:7a1fb885a8e4 1019 const SnCommWin::ECommWinResult conres = (*cw)->OpenWindow(
uci1 13:7a1fb885a8e4 1020 GetTimeoutTime(gLastCommWin, conto), *ss, gConf, gEvent, gPower,
uci1 13:7a1fb885a8e4 1021 SnSDUtils::GetCurSeqNum(), thmrate, evtrate,
uci1 13:7a1fb885a8e4 1022 gGenBuf);
uci1 13:7a1fb885a8e4 1023 if (conres>=SnCommWin::kConnected) {
uci1 1:e392595b4b76 1024 Watchdog::kick(); // don't reset!
uci1 13:7a1fb885a8e4 1025 // connected. listen for config
uci1 13:7a1fb885a8e4 1026 *ss = false; // don't send status next time
uci1 12:d472f9811262 1027 #ifdef DEBUG
uci1 13:7a1fb885a8e4 1028 printf("get conf gtt=%u\r\n",GetTimeoutTime(gLastCommWin, listo));
uci1 12:d472f9811262 1029 #endif
uci1 13:7a1fb885a8e4 1030 const SnCommWin::ECommWinResult cfgres = (*cw)->GetConfig(
uci1 13:7a1fb885a8e4 1031 gConf, GetTimeoutTime(gLastCommWin, listo), gGenBuf, gBufSize);
uci1 13:7a1fb885a8e4 1032 if (cfgres>=SnCommWin::kOkWithMsg) {
uci1 13:7a1fb885a8e4 1033 Watchdog::kick(); // don't reset!
uci1 12:d472f9811262 1034 #ifdef DEBUG
uci1 13:7a1fb885a8e4 1035 printf("received config!\r\n");
uci1 13:7a1fb885a8e4 1036 printf("send data = %d\r\n", gConf.GetCommSendData());
uci1 12:d472f9811262 1037 #endif
uci1 13:7a1fb885a8e4 1038 // send data if need be (files, some events, etc)
uci1 13:7a1fb885a8e4 1039 const uint32_t winto = GetTimeoutTime(gLastCommWin,
uci1 13:7a1fb885a8e4 1040 gConf.GetCommWinDuration());
uci1 13:7a1fb885a8e4 1041 const uint32_t gtt = gConf.IsObeyingTimeout() ? winto : 0;
uci1 13:7a1fb885a8e4 1042 if (gConf.GetCommSendData()!=0) {
uci1 12:d472f9811262 1043 #ifdef DEBUG
uci1 13:7a1fb885a8e4 1044 printf("sending data, gtt=%u. lcw=%u, dur=%u, obey=%s\r\n",
uci1 13:7a1fb885a8e4 1045 GetTimeoutTime(gLastCommWin, gConf.GetCommWinDuration()),
uci1 13:7a1fb885a8e4 1046 gLastCommWin, gConf.GetCommWinDuration(),
uci1 13:7a1fb885a8e4 1047 gConf.IsObeyingTimeout() ? "true" : "false");
uci1 12:d472f9811262 1048 #endif
uci1 13:7a1fb885a8e4 1049 res = (*cw)->SendData(gConf, gEvent, gPower, gGenBuf, gBufSize,
uci1 13:7a1fb885a8e4 1050 gtt, winto);
uci1 13:7a1fb885a8e4 1051 } else {
uci1 13:7a1fb885a8e4 1052 // don't send anything
uci1 13:7a1fb885a8e4 1053 res = cfgres;
uci1 13:7a1fb885a8e4 1054 }
uci1 13:7a1fb885a8e4 1055 #ifdef DEBUG
uci1 13:7a1fb885a8e4 1056 printf("Got config!\r\n");
uci1 13:7a1fb885a8e4 1057 #endif
uci1 13:7a1fb885a8e4 1058 gotNewConfig = (cfgres!=SnCommWin::kOkWthMsgNoConf);
uci1 13:7a1fb885a8e4 1059 Watchdog::kick(); // don't reset!
uci1 13:7a1fb885a8e4 1060 break;
uci1 13:7a1fb885a8e4 1061 }
uci1 0:664899e0b988 1062 }
uci1 13:7a1fb885a8e4 1063
uci1 13:7a1fb885a8e4 1064 Watchdog::kick(); // don't reset!
uci1 0:664899e0b988 1065 }
uci1 15:f2569d8e4176 1066 // close the connection(s)
uci1 15:f2569d8e4176 1067 cw = gComms;
uci1 15:f2569d8e4176 1068 for (uint8_t i=0; i<kNcomms; i++, cw++) {
uci1 15:f2569d8e4176 1069 if ((*cw)==0) {
uci1 15:f2569d8e4176 1070 continue;
uci1 15:f2569d8e4176 1071 }
uci1 15:f2569d8e4176 1072 (*cw)->CloseConn(GetTimeoutTime(gLastCommWin,gConf.GetCommWinDuration()));
uci1 15:f2569d8e4176 1073 Watchdog::kick(); // don't reset!
uci1 15:f2569d8e4176 1074 }
uci1 0:664899e0b988 1075 }
uci1 12:d472f9811262 1076
uci1 4:a91682e19d6b 1077 // (probably) power down comms and power up cards,amps
uci1 4:a91682e19d6b 1078 SetPower(false);
uci1 4:a91682e19d6b 1079
uci1 1:e392595b4b76 1080 gFirstEvt = true;
uci1 4:a91682e19d6b 1081
uci1 1:e392595b4b76 1082 // reset config with system powered (for DAC/PLA setting)
uci1 13:7a1fb885a8e4 1083 if (gotNewConfig || forceReconfig) {
uci1 12:d472f9811262 1084 #ifdef DEBUG
uci1 1:e392595b4b76 1085 printf("calling SetConfigAndMakeOutputFile\r\n");
uci1 12:d472f9811262 1086 #endif
uci1 1:e392595b4b76 1087 SetConfigAndMakeOutputFile();
uci1 12:d472f9811262 1088 } else {
uci1 12:d472f9811262 1089 MakeOutputFile();
uci1 1:e392595b4b76 1090 }
uci1 12:d472f9811262 1091 #ifdef DEBUG
uci1 1:e392595b4b76 1092 printf("closing comm win at %d\r\n",(int32_t)time(0));
uci1 12:d472f9811262 1093 #endif
uci1 1:e392595b4b76 1094
uci1 0:664899e0b988 1095 gCommWinOpen = false;
uci1 0:664899e0b988 1096 return res;
uci1 0:664899e0b988 1097 }