Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Wed Sep 12 22:50:25 2012 +0000
Revision:
17:4687bf932b8c
Parent:
16:744ce85aede2
Child:
18:55f1581f2ee4
Same as Rev16, but opens a communication window at the end of running in single sequence mode (in StopRunning).

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