Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Wed Sep 12 04:47:22 2012 +0000
Revision:
16:744ce85aede2
Parent:
15:f2569d8e4176
Child:
17:4687bf932b8c
SBD comm seems to be working. USB comm seems to be working (at 115200 baud). AFAR comm seems to be working. This version is set for USB communication and has zero text output.

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 8:95a325df1f6b 433 while (true) {
uci1 8:95a325df1f6b 434 led3 = 1; led4=1;
uci1 8:95a325df1f6b 435 wait(0.5);
uci1 8:95a325df1f6b 436 led3 = 0; led4=0;
uci1 8:95a325df1f6b 437 wait(0.5);
uci1 8:95a325df1f6b 438 //Watchdog::kick(); - if we kick the watchdog, the station is unrecoverable without physical access
uci1 8:95a325df1f6b 439 }
uci1 8:95a325df1f6b 440 }
uci1 1:e392595b4b76 441
uci1 0:664899e0b988 442 int main() {
uci1 1:e392595b4b76 443 {
uci1 16:744ce85aede2 444 //gCpu.baud(19200);
uci1 15:f2569d8e4176 445 #ifdef SSNOTIFY
uci1 15:f2569d8e4176 446 printf("main: start\r\n");
uci1 15:f2569d8e4176 447 #endif
uci1 2:e67f7c158087 448 led1=1; wait(0.2);
uci1 2:e67f7c158087 449 led1=0; led2=1; wait(0.2);
uci1 2:e67f7c158087 450 led2=0; led3=1; wait(0.2);
uci1 2:e67f7c158087 451 led3=0; led4=1; wait(0.2);
uci1 1:e392595b4b76 452 led4=0;
uci1 1:e392595b4b76 453 }
uci1 16:744ce85aede2 454
uci1 8:95a325df1f6b 455 // RTOS stuff must be made inside main for some reason
uci1 15:f2569d8e4176 456 //gComms[0] = new SnCommAfarTCP(gConf);
uci1 16:744ce85aede2 457 //gComms[0] = new SnCommSBD(&gSBDport, &gCpu);
uci1 16:744ce85aede2 458 gComms[0] = new SnCommUsb(&gCpu);
uci1 13:7a1fb885a8e4 459
uci1 8:95a325df1f6b 460 #ifdef USE_RTOS_TIMER
uci1 8:95a325df1f6b 461 gForceTicker = new rtos::RtosTimer(&procForceTrigger);
uci1 8:95a325df1f6b 462 gHeartbeatTicker = new rtos::RtosTimer(&procHeartbeat);
uci1 8:95a325df1f6b 463 gCommWinTicker = new rtos::RtosTimer(&procCommWin);
uci1 8:95a325df1f6b 464 gPowerCheckTicker = new rtos::RtosTimer(&procPowerCheck);
uci1 8:95a325df1f6b 465 #endif
uci1 8:95a325df1f6b 466
uci1 0:664899e0b988 467 led2=1;
uci1 0:664899e0b988 468 //wait_ms(100);
uci1 1:e392595b4b76 469
uci1 12:d472f9811262 470 #ifdef DEBUG
uci1 3:24c5f0f50bf1 471 printf("\n\n\n\n\n\nstarting\r\n");
uci1 12:d472f9811262 472 #endif
uci1 1:e392595b4b76 473
uci1 0:664899e0b988 474 // a failsafe
uci1 0:664899e0b988 475 Watchdog::kick(kWDFailsafe);
uci1 0:664899e0b988 476
uci1 1:e392595b4b76 477 // set the clock to the BS time, if it's not set
uci1 1:e392595b4b76 478 if ( (static_cast<int32_t>(time(0)))<0 ) {
uci1 1:e392595b4b76 479 set_time(kBStime);
uci1 1:e392595b4b76 480 }
uci1 12:d472f9811262 481 #ifdef DEBUG
uci1 1:e392595b4b76 482 printf("time = %d\r\n",(int32_t)time(0));
uci1 12:d472f9811262 483 #endif
uci1 1:e392595b4b76 484 gLastCommWin = time(0); // prevent comm win proc
uci1 0:664899e0b988 485
uci1 8:95a325df1f6b 486 #ifdef USE_RTOS_TIMER
uci1 8:95a325df1f6b 487 gForceTicker->stop();
uci1 8:95a325df1f6b 488 #else
uci1 0:664899e0b988 489 gForceTicker.detach();
uci1 8:95a325df1f6b 490 #endif
uci1 0:664899e0b988 491 gFirstEvt = true;
uci1 0:664899e0b988 492
uci1 4:a91682e19d6b 493 // (probably) power down comms and power up cards,amps
uci1 4:a91682e19d6b 494 SetPower(false);
uci1 4:a91682e19d6b 495
uci1 0:664899e0b988 496 //
uci1 0:664899e0b988 497 // get config
uci1 0:664899e0b988 498 //
uci1 12:d472f9811262 499 #ifdef DEBUG
uci1 8:95a325df1f6b 500 printf("call OpenCommWin\r\n");
uci1 12:d472f9811262 501 #endif
uci1 13:7a1fb885a8e4 502 OpenCommWin(true); // alwasy configure, even if no new config
uci1 3:24c5f0f50bf1 503
uci1 0:664899e0b988 504 // get ready to trigger
uci1 0:664899e0b988 505 PIN_spi.format( 16, 1 ); // change to data readout format
uci1 15:f2569d8e4176 506 PIN_spi.frequency( 10000000 ); // Max is 12.5 MHz
uci1 0:664899e0b988 507
uci1 0:664899e0b988 508 led2=0;
uci1 0:664899e0b988 509
uci1 0:664899e0b988 510 // the main event loop. wait for triggers in SendClock
uci1 12:d472f9811262 511 gTrgTimer.start();
uci1 12:d472f9811262 512 register int32_t etms=0; // time between written events
uci1 0:664899e0b988 513 while( true )
uci1 0:664899e0b988 514 {
uci1 0:664899e0b988 515 // in here, we wait for triggers from the MB-FPGA
uci1 0:664899e0b988 516 Watchdog::kick(); // don't reset!
uci1 1:e392595b4b76 517
uci1 1:e392595b4b76 518 led1 = !led1;
uci1 1:e392595b4b76 519
uci1 12:d472f9811262 520 #ifdef DEBUG
uci1 1:e392595b4b76 521 printf("calling wait trig\r\n");
uci1 1:e392595b4b76 522 printf("gFirstEvt=%s\r\n",gFirstEvt?"true":"false");
uci1 5:9cea89700c66 523 printf("readingout=%d\r\n",(int)gReadingOut);
uci1 12:d472f9811262 524 #endif
uci1 1:e392595b4b76 525
uci1 0:664899e0b988 526 PIN_lockRegisters = 0; // allow data to come from DFPGA
uci1 0:664899e0b988 527 WaitTrigAndSendClock();
uci1 0:664899e0b988 528 PIN_lockRegisters = 1; // block registers during readout
uci1 1:e392595b4b76 529
uci1 12:d472f9811262 530 #ifdef EVT_TIME_PROFILE
uci1 12:d472f9811262 531 Timer prof;
uci1 12:d472f9811262 532 prof.start();
uci1 12:d472f9811262 533 int befReadWv=0, aftReadWv=0, befSaveEvt=0, aftSaveEvt=0,
uci1 12:d472f9811262 534 befChkPow=0, aftChkPow=0, befNewSeq=0, aftNewSeq=0, endOfLoop=0;
uci1 12:d472f9811262 535 #endif
uci1 12:d472f9811262 536
uci1 1:e392595b4b76 537 if (gReadingOut) {
uci1 12:d472f9811262 538
uci1 12:d472f9811262 539 const int32_t ttms = gTrgTimer.read_ms(); // time since last trigger
uci1 12:d472f9811262 540 gTrgTimer.reset(); gTrgTimer.start(); // restart trigger timer
uci1 12:d472f9811262 541 etms += ttms;
uci1 8:95a325df1f6b 542
uci1 8:95a325df1f6b 543 Watchdog::kick(); // don't reset!
uci1 15:f2569d8e4176 544
uci1 1:e392595b4b76 545 //
uci1 1:e392595b4b76 546 // got trigger. read registers to mbed and build the event
uci1 1:e392595b4b76 547 //
uci1 1:e392595b4b76 548
uci1 1:e392595b4b76 549 led4=1;
uci1 1:e392595b4b76 550
uci1 1:e392595b4b76 551 // read data & calc CRC
uci1 12:d472f9811262 552 #ifdef EVT_TIME_PROFILE
uci1 12:d472f9811262 553 prof.stop(); befReadWv=prof.read_us(); prof.start();
uci1 12:d472f9811262 554 #endif
uci1 12:d472f9811262 555
uci1 1:e392595b4b76 556 gEvent.ReadWaveforms(PIN_spi, PIN_selCardHiBit, PIN_selCardLoBit);
uci1 15:f2569d8e4176 557
uci1 12:d472f9811262 558 #ifdef EVT_TIME_PROFILE
uci1 12:d472f9811262 559 prof.stop(); aftReadWv=prof.read_us(); prof.start();
uci1 12:d472f9811262 560 #endif
uci1 12:d472f9811262 561
uci1 1:e392595b4b76 562 gEvent.SetCurMbedTime();
uci1 1:e392595b4b76 563 // TODO: no way to check for external trigger?
uci1 1:e392595b4b76 564 if (gEvent.IsForcedTrg()==false) {
uci1 1:e392595b4b76 565 gEvent.SetTrgBit(kThmTrg);
uci1 1:e392595b4b76 566 gEvent.SetTrgNum((gTrgNum[kThmTrg])++);
uci1 1:e392595b4b76 567 } // else already set by procForceTrigger
uci1 1:e392595b4b76 568 // (no need to calc if we throw this event away)
uci1 1:e392595b4b76 569
uci1 1:e392595b4b76 570 Watchdog::kick(); // don't reset!
uci1 1:e392595b4b76 571
uci1 12:d472f9811262 572 #ifdef DEBUG
uci1 1:e392595b4b76 573 printf("gFirstEvt=%s\r\n",gFirstEvt?"true":"false");
uci1 12:d472f9811262 574 #endif
uci1 1:e392595b4b76 575
uci1 1:e392595b4b76 576 if ( gEvent.IsForcedTrg() || gFirstEvt ||
uci1 1:e392595b4b76 577 (etms>gConf.GetEvtThrtlPeriodMs()) ) {
uci1 1:e392595b4b76 578
uci1 1:e392595b4b76 579 led2=1;
uci1 1:e392595b4b76 580
uci1 1:e392595b4b76 581 PIN_lockRegisters = 0; // done reading, unlock so we can talk to SD card.
uci1 1:e392595b4b76 582
uci1 12:d472f9811262 583 #ifdef EVT_TIME_PROFILE
uci1 12:d472f9811262 584 prof.stop(); befSaveEvt=prof.read_us(); prof.start();
uci1 12:d472f9811262 585 #endif
uci1 12:d472f9811262 586
uci1 1:e392595b4b76 587 SaveEvent(etms);
uci1 12:d472f9811262 588 etms=0;
uci1 8:95a325df1f6b 589
uci1 12:d472f9811262 590 #ifdef EVT_TIME_PROFILE
uci1 12:d472f9811262 591 prof.stop(); aftSaveEvt=prof.read_us(); prof.start();
uci1 12:d472f9811262 592 #endif
uci1 1:e392595b4b76 593 }
uci1 1:e392595b4b76 594 }
uci1 12:d472f9811262 595 #ifdef DEBUG
uci1 1:e392595b4b76 596 printf("past reading out\r\n");
uci1 12:d472f9811262 597 #endif
uci1 1:e392595b4b76 598
uci1 1:e392595b4b76 599 led4=0; led2=0;
uci1 12:d472f9811262 600
uci1 12:d472f9811262 601 #ifdef EVT_TIME_PROFILE
uci1 12:d472f9811262 602 prof.stop(); befChkPow=prof.read_us(); prof.start();
uci1 12:d472f9811262 603 #endif
uci1 8:95a325df1f6b 604 // check the power?
uci1 8:95a325df1f6b 605 if (gCheckPower) {
uci1 12:d472f9811262 606 #ifdef DEBUG
uci1 8:95a325df1f6b 607 printf("call check power\r\n");
uci1 12:d472f9811262 608 #endif
uci1 8:95a325df1f6b 609 CheckPower(false);
uci1 8:95a325df1f6b 610 }
uci1 12:d472f9811262 611 #ifdef EVT_TIME_PROFILE
uci1 12:d472f9811262 612 prof.stop(); aftChkPow=prof.read_us(); prof.start();
uci1 12:d472f9811262 613 #endif
uci1 8:95a325df1f6b 614
uci1 12:d472f9811262 615 #ifdef EVT_TIME_PROFILE
uci1 12:d472f9811262 616 prof.stop(); befNewSeq=prof.read_us(); prof.start();
uci1 12:d472f9811262 617 #endif
uci1 8:95a325df1f6b 618 // make new seq?
uci1 8:95a325df1f6b 619 if (IsSeqComplete()) {
uci1 12:d472f9811262 620 #ifdef DEBUG
uci1 10:3c93db1cfb12 621 printf("seq complete. sngseq=%d\r\n",gConf.IsSingleSeqRunMode());
uci1 12:d472f9811262 622 #endif
uci1 8:95a325df1f6b 623 MakeOutputFile(gConf.IsSingleSeqRunMode());
uci1 8:95a325df1f6b 624 }
uci1 12:d472f9811262 625 #ifdef EVT_TIME_PROFILE
uci1 12:d472f9811262 626 prof.stop(); aftNewSeq=prof.read_us(); prof.start();
uci1 12:d472f9811262 627 #endif
uci1 12:d472f9811262 628
uci1 8:95a325df1f6b 629 // open comm win?
uci1 0:664899e0b988 630 if (gOpenCommWin) {
uci1 12:d472f9811262 631 #ifdef DEBUG
uci1 1:e392595b4b76 632 printf("gOpenComWin=%s, opening\r\n",gOpenCommWin?"true":"false");
uci1 12:d472f9811262 633 #endif
uci1 0:664899e0b988 634 OpenCommWin();
uci1 0:664899e0b988 635 gOpenCommWin=false;
uci1 1:e392595b4b76 636 } else {
uci1 12:d472f9811262 637 #ifdef DEBUG
uci1 1:e392595b4b76 638 printf("gOpenCommWin=false\r\n");
uci1 12:d472f9811262 639 #endif
uci1 0:664899e0b988 640 }
uci1 12:d472f9811262 641
uci1 12:d472f9811262 642 #ifdef EVT_TIME_PROFILE
uci1 12:d472f9811262 643 prof.stop(); endOfLoop=prof.read_us(); prof.start();
uci1 12:d472f9811262 644 printf("befReadWv=%d, aftReadWv=%d, befSaveEvt=%d, aftSaveEvt=%d, "
uci1 12:d472f9811262 645 "befChkPow=%d, aftChkPow=%d, befNewSeq=%d, aftNewSeq=%d, endOfLoop=%d\r\n",
uci1 12:d472f9811262 646 befReadWv, aftReadWv, befSaveEvt, aftSaveEvt,
uci1 12:d472f9811262 647 befChkPow, aftChkPow, befNewSeq, aftNewSeq, endOfLoop);
uci1 12:d472f9811262 648 #endif
uci1 15:f2569d8e4176 649
uci1 15:f2569d8e4176 650 // get ready to trigger
uci1 15:f2569d8e4176 651 PIN_spi.format( 16, 1 ); // change to data readout format
uci1 15:f2569d8e4176 652 PIN_spi.frequency( 10000000 ); // Max is 12.5 MHz
uci1 0:664899e0b988 653 }
uci1 0:664899e0b988 654
uci1 0:664899e0b988 655 }
uci1 0:664899e0b988 656
uci1 0:664899e0b988 657 //
uci1 0:664899e0b988 658 // save the event
uci1 0:664899e0b988 659 //
uci1 0:664899e0b988 660 void SaveEvent(const int32_t etms) {
uci1 0:664899e0b988 661 // write the event
uci1 12:d472f9811262 662
uci1 12:d472f9811262 663 #ifdef DEBUG
uci1 3:24c5f0f50bf1 664 printf("save event\r\n");
uci1 12:d472f9811262 665 #endif
uci1 3:24c5f0f50bf1 666
uci1 0:664899e0b988 667 // set the event number & dt
uci1 3:24c5f0f50bf1 668 gEvent.SetEvtNum(gEvtNum);
uci1 0:664899e0b988 669 gEvent.SetDTms(etms);
uci1 0:664899e0b988 670
uci1 0:664899e0b988 671 // save to SD
uci1 11:de443350ec4a 672 PIN_lockRegisters = 0; // unlock so we can talk to SD card.
uci1 1:e392595b4b76 673 SnSDUtils::WriteEventTo(SnSDUtils::GetCurFile(), gGenBuf, gEvent, gConf);
uci1 0:664899e0b988 674
uci1 0:664899e0b988 675 // reset
uci1 0:664899e0b988 676 gEvent.ClearEvent();
uci1 0:664899e0b988 677
uci1 3:24c5f0f50bf1 678 // increment event number
uci1 3:24c5f0f50bf1 679 ++gEvtNum;
uci1 3:24c5f0f50bf1 680
uci1 12:d472f9811262 681 #ifdef DEBUG
uci1 8:95a325df1f6b 682 printf("gEvtNum=%u\r\n",gEvtNum);
uci1 12:d472f9811262 683 #endif
uci1 3:24c5f0f50bf1 684 }
uci1 3:24c5f0f50bf1 685
uci1 3:24c5f0f50bf1 686 void MakeOutputFile(const bool stopRunning) {
uci1 10:3c93db1cfb12 687 PIN_lockRegisters = 0; // unlock so we can talk to SD card.
uci1 12:d472f9811262 688 #ifdef DEBUG
uci1 10:3c93db1cfb12 689 printf("closing output file. gEvtNum=%u, gPowNum=%u, stop=%d\r\n",
uci1 10:3c93db1cfb12 690 gEvtNum,gPowNum,(int)stopRunning);
uci1 12:d472f9811262 691 #endif
uci1 13:7a1fb885a8e4 692
uci1 3:24c5f0f50bf1 693 SnSDUtils::CloseOutputFile(SnSDUtils::GetCurFile());
uci1 13:7a1fb885a8e4 694
uci1 12:d472f9811262 695 #ifdef DEBUG
uci1 10:3c93db1cfb12 696 printf("file closed\r\n");
uci1 12:d472f9811262 697 #endif
uci1 3:24c5f0f50bf1 698 if (stopRunning) {
uci1 8:95a325df1f6b 699 StopRunning();
uci1 0:664899e0b988 700 }
uci1 8:95a325df1f6b 701 FILE* cf = SnSDUtils::OpenNewOutputFile(gConf.GetMacAddress(),
uci1 8:95a325df1f6b 702 gConf.GetRun());
uci1 13:7a1fb885a8e4 703 // reset event, timers, trigger counters
uci1 13:7a1fb885a8e4 704 ResetCountersClearEvt();
uci1 8:95a325df1f6b 705 if (cf!=0) {
uci1 8:95a325df1f6b 706 wait_ms(200);
uci1 8:95a325df1f6b 707 GetAvePowerReading();
uci1 12:d472f9811262 708 #ifdef DEBUG
uci1 8:95a325df1f6b 709 printf("writing power. v1=%g, v2=%g, r1=%g, r2=%g, t=%u, pownum=%u\r\n",
uci1 8:95a325df1f6b 710 gPower.GetAveV1(), gPower.GetAveV2(),
uci1 8:95a325df1f6b 711 gPower.GetRmsV1(), gPower.GetRmsV2(), gPower.GetTime(),
uci1 8:95a325df1f6b 712 gPowNum);
uci1 12:d472f9811262 713 #endif
uci1 8:95a325df1f6b 714 SnSDUtils::WritePowerTo(cf, gPower, gPowNum);
uci1 8:95a325df1f6b 715 }
uci1 12:d472f9811262 716 #ifdef DEBUG
uci1 3:24c5f0f50bf1 717 printf("made output file with run %u\r\n",gConf.GetRun());
uci1 3:24c5f0f50bf1 718 printf("filename=%s\r\n",SnSDUtils::GetCurFileName());
uci1 12:d472f9811262 719 #endif
uci1 3:24c5f0f50bf1 720 SnSDUtils::WriteConfig(SnSDUtils::GetCurFile(), gConf);
uci1 0:664899e0b988 721 }
uci1 0:664899e0b988 722
uci1 0:664899e0b988 723 //
uci1 4:a91682e19d6b 724 // power stuff
uci1 4:a91682e19d6b 725 //
uci1 4:a91682e19d6b 726 void SetPower(const bool isCommWin) {
uci1 8:95a325df1f6b 727 // TODO: turn on amps individually, when that's possible
uci1 4:a91682e19d6b 728 if (isCommWin) {
uci1 5:9cea89700c66 729 PIN_turn_on_system = gConf.GetPowPinSetting(SnConfigFrame::kCardComWin);
uci1 4:a91682e19d6b 730 wait_ms(10);
uci1 5:9cea89700c66 731 PIN_turn_on_amps = gConf.GetPowPinSetting(SnConfigFrame::kAmpsComWin);
uci1 4:a91682e19d6b 732 wait_ms(10);
uci1 5:9cea89700c66 733 PIN_iridSbd_power = gConf.GetPowPinSetting(SnConfigFrame::kIridComWin);
uci1 4:a91682e19d6b 734 wait_ms(10);
uci1 5:9cea89700c66 735 PIN_afar_power = gConf.GetPowPinSetting(SnConfigFrame::kAfarComWin);
uci1 4:a91682e19d6b 736 wait_ms(10);
uci1 4:a91682e19d6b 737 } else {
uci1 5:9cea89700c66 738 PIN_turn_on_system = gConf.GetPowPinSetting(SnConfigFrame::kCardDatTak);
uci1 4:a91682e19d6b 739 wait_ms(10);
uci1 5:9cea89700c66 740 PIN_turn_on_amps = gConf.GetPowPinSetting(SnConfigFrame::kAmpsDatTak);
uci1 4:a91682e19d6b 741 wait_ms(10);
uci1 5:9cea89700c66 742 PIN_iridSbd_power = gConf.GetPowPinSetting(SnConfigFrame::kIridDatTak);
uci1 4:a91682e19d6b 743 wait_ms(10);
uci1 5:9cea89700c66 744 PIN_afar_power = gConf.GetPowPinSetting(SnConfigFrame::kAfarDatTak);
uci1 4:a91682e19d6b 745 wait_ms(10);
uci1 4:a91682e19d6b 746 }
uci1 16:744ce85aede2 747 wait(1.5); // let things power up
uci1 12:d472f9811262 748 #ifdef DEBUG
uci1 16:744ce85aede2 749 printf("power word (%hhu): ",gConf.GetPowerMode()); SnBitUtils::printBits(gConf.GetPowerMode(),true);
uci1 6:6f002d202f59 750 printf("set power (iscom %d, pw %hhu): cards %d, amps %d, irid %d, afar %d\r\n",
uci1 6:6f002d202f59 751 isCommWin, gConf.GetPowerMode(), PIN_turn_on_system.read(), PIN_turn_on_amps.read(),
uci1 6:6f002d202f59 752 PIN_iridSbd_power.read(), PIN_afar_power.read());
uci1 12:d472f9811262 753 #endif
uci1 4:a91682e19d6b 754 }
uci1 4:a91682e19d6b 755
uci1 4:a91682e19d6b 756 //
uci1 0:664899e0b988 757 // set configuration
uci1 0:664899e0b988 758 //
uci1 1:e392595b4b76 759 void SetConfigAndMakeOutputFile() {
uci1 12:d472f9811262 760 #ifdef DEBUG
uci1 1:e392595b4b76 761 printf("SetConfigAndMakeOutputFile\r\n");
uci1 12:d472f9811262 762 #endif
uci1 1:e392595b4b76 763
uci1 0:664899e0b988 764 // restart watchdog
uci1 0:664899e0b988 765 Watchdog::kick(gConf.GetWatchdogPeriod());
uci1 0:664899e0b988 766
uci1 1:e392595b4b76 767 // block (thermal) triggers during configuration
uci1 1:e392595b4b76 768 PIN_enableThermTrig = 0;
uci1 1:e392595b4b76 769 PIN_ADC_CS = 1;
uci1 1:e392595b4b76 770 PIN_DoNotRestartAllClocks = 1;
uci1 1:e392595b4b76 771 PIN_forceTrigger = 0;
uci1 3:24c5f0f50bf1 772 PIN_heartbeat = 0;
uci1 1:e392595b4b76 773 wait_ms(20);
uci1 1:e392595b4b76 774
uci1 8:95a325df1f6b 775 if (AreCardsPowered()) {
uci1 8:95a325df1f6b 776 // Set PLA value(s)
uci1 8:95a325df1f6b 777 PIN_spi.format( 16, 0 ); // change mode for DAC & PLA value setting
uci1 8:95a325df1f6b 778 PIN_spi.frequency(1000000);
uci1 8:95a325df1f6b 779 PIN_MajLogHiBit=1;
uci1 8:95a325df1f6b 780 PIN_MajLogLoBit=1;
uci1 8:95a325df1f6b 781 PIN_enableThermTrig=0;
uci1 0:664899e0b988 782
uci1 8:95a325df1f6b 783 uint16_t hi, lo;
uci1 8:95a325df1f6b 784 PIN_PLA_cs=1;
uci1 8:95a325df1f6b 785 wait(4);
uci1 8:95a325df1f6b 786 for (uint8_t pi=0; pi<kNplas; pi++) {
uci1 8:95a325df1f6b 787 if (pi < gConf.GetNumPlas()) {
uci1 8:95a325df1f6b 788 SnConfigFrame::GetHiLoPlas(gConf.GetPla(pi), hi, lo);
uci1 8:95a325df1f6b 789 PIN_spi.write(hi);
uci1 8:95a325df1f6b 790 PIN_spi.write(lo);
uci1 12:d472f9811262 791 #ifdef DEBUG
uci1 8:95a325df1f6b 792 printf("pla hi %hu, lo %hu\r\n",hi,lo);
uci1 12:d472f9811262 793 #endif
uci1 8:95a325df1f6b 794 } else {
uci1 8:95a325df1f6b 795 PIN_spi.write(kNoTrigPla); // hi
uci1 8:95a325df1f6b 796 PIN_spi.write(kNoTrigPla); // lo
uci1 12:d472f9811262 797 #ifdef DEBUG
uci1 8:95a325df1f6b 798 printf("pla hi %hu, lo %hu\r\n",kNoTrigPla,kNoTrigPla);
uci1 12:d472f9811262 799 #endif
uci1 8:95a325df1f6b 800 }
uci1 8:95a325df1f6b 801 Watchdog::kick();
uci1 0:664899e0b988 802 }
uci1 8:95a325df1f6b 803 wait(3);
uci1 8:95a325df1f6b 804 PIN_PLA_cs=0;
uci1 8:95a325df1f6b 805 wait(3);
uci1 0:664899e0b988 806
uci1 8:95a325df1f6b 807 // DAC values
uci1 8:95a325df1f6b 808 //
uci1 8:95a325df1f6b 809 // first 12 bits = DAC value
uci1 8:95a325df1f6b 810 // next 2 bits = DAC ID
uci1 8:95a325df1f6b 811 // last 2 bits = dFPGA ID
uci1 8:95a325df1f6b 812 //
uci1 8:95a325df1f6b 813 // But FPGA uses "gray encoding" which means only 1 bit
uci1 8:95a325df1f6b 814 // can change at a time (of the last 4 bits). So even tho
uci1 8:95a325df1f6b 815 // the card/dac# is encoded, the order is also important
uci1 8:95a325df1f6b 816 // 0000 (dac0,card0), 0001 (dac0,card1), 0011 (dac0,card3), 0010 (dac0,card2),
uci1 8:95a325df1f6b 817 // 0110 (dac1,card2), 0111 (dac1,card3), 0101 (dac1,card1), etc.
uci1 12:d472f9811262 818 #ifdef DEBUG
uci1 8:95a325df1f6b 819 printf("setting dacs\r\n");
uci1 12:d472f9811262 820 #endif
uci1 8:95a325df1f6b 821 uint16_t dv=0;
uci1 8:95a325df1f6b 822 for (uint8_t i=0, gri=0; i<kTotDacs; i++) {
uci1 8:95a325df1f6b 823 // get the gray-codes for this iteration
uci1 8:95a325df1f6b 824 gri = SnBitUtils::binToGray(i);
uci1 8:95a325df1f6b 825
uci1 8:95a325df1f6b 826 // build bit word
uci1 8:95a325df1f6b 827 dv = static_cast<int>(gConf.GetDac(gri & 0x0003u, gri >> 2u));
uci1 8:95a325df1f6b 828 dv <<= 4u;
uci1 8:95a325df1f6b 829 dv |= gri;
uci1 8:95a325df1f6b 830
uci1 12:d472f9811262 831 #ifdef DEBUG
uci1 8:95a325df1f6b 832 printf("dac %04x\r\n",dv);
uci1 12:d472f9811262 833 #endif
uci1 8:95a325df1f6b 834
uci1 8:95a325df1f6b 835 // send to FPGA
uci1 8:95a325df1f6b 836 PIN_start_fpga=1;
uci1 8:95a325df1f6b 837 PIN_spi.write(dv);
uci1 8:95a325df1f6b 838 PIN_start_fpga=0;
uci1 8:95a325df1f6b 839
uci1 8:95a325df1f6b 840 Watchdog::kick();
uci1 8:95a325df1f6b 841
uci1 8:95a325df1f6b 842 }
uci1 12:d472f9811262 843 #ifdef DEBUG
uci1 8:95a325df1f6b 844 printf("dacs set\r\n");
uci1 12:d472f9811262 845 #endif
uci1 8:95a325df1f6b 846 wait_ms(20);
uci1 8:95a325df1f6b 847 } else {
uci1 12:d472f9811262 848 #ifdef DEBUG
uci1 8:95a325df1f6b 849 printf("cards off. skipping PLA and DAC setting\r\n");
uci1 12:d472f9811262 850 #endif
uci1 0:664899e0b988 851 }
uci1 0:664899e0b988 852
uci1 0:664899e0b988 853 // Majority Logic Trigger selection (# of cards)
uci1 0:664899e0b988 854 SnBitUtils::SetChanNumBits(gConf.GetNumCardsMajLog() - 1u,
uci1 0:664899e0b988 855 PIN_MajLogHiBit, PIN_MajLogLoBit);
uci1 0:664899e0b988 856
uci1 0:664899e0b988 857 // Enable thermal trigger?
uci1 0:664899e0b988 858 PIN_enableThermTrig = gConf.IsThermTrigEnabled();
uci1 0:664899e0b988 859
uci1 0:664899e0b988 860 PIN_spi.format( 16, 1 ); // back to trigger mode
uci1 1:e392595b4b76 861 PIN_spi.frequency( 10000000 ); // Max is 12.5 MHz
uci1 1:e392595b4b76 862
uci1 8:95a325df1f6b 863 // make new output file
uci1 8:95a325df1f6b 864 // put after PLA/DAC, in case they affect the power readings
uci1 8:95a325df1f6b 865 wait_ms(200);
uci1 8:95a325df1f6b 866 MakeOutputFile();
uci1 8:95a325df1f6b 867
uci1 15:f2569d8e4176 868 // reset tickers
uci1 15:f2569d8e4176 869 ResetAllTickers();
uci1 8:95a325df1f6b 870
uci1 8:95a325df1f6b 871 // TODO: change comm parameters
uci1 8:95a325df1f6b 872 /*
uci1 8:95a325df1f6b 873 printf("set comm params\r\n");
uci1 8:95a325df1f6b 874 for (uint8_t cc=0; cc<kNcomms; cc++) {
uci1 8:95a325df1f6b 875 if (gComms[cc]!=0) {
uci1 8:95a325df1f6b 876 gComms[cc]->Set(gConf);
uci1 8:95a325df1f6b 877 }
uci1 3:24c5f0f50bf1 878 }
uci1 8:95a325df1f6b 879 */
uci1 0:664899e0b988 880
uci1 0:664899e0b988 881 Watchdog::kick(); // don't reset!
uci1 8:95a325df1f6b 882
uci1 12:d472f9811262 883 #ifdef DEBUG
uci1 8:95a325df1f6b 884 printf("set config done\r\n");
uci1 12:d472f9811262 885 #endif
uci1 0:664899e0b988 886 }
uci1 0:664899e0b988 887
uci1 0:664899e0b988 888 //
uci1 0:664899e0b988 889 // readout functions
uci1 0:664899e0b988 890 //
uci1 0:664899e0b988 891 void WaitTrigAndSendClock() {
uci1 1:e392595b4b76 892
uci1 12:d472f9811262 893 #ifdef DEBUG
uci1 1:e392595b4b76 894 printf("WaitTrigAndSendClock\r\n");
uci1 6:6f002d202f59 895 printf("wait trig: (pw %hhu): cards %d, amps %d, irid %d, afar %d\r\n",
uci1 6:6f002d202f59 896 gConf.GetPowerMode(), PIN_turn_on_system.read(), PIN_turn_on_amps.read(),
uci1 6:6f002d202f59 897 PIN_iridSbd_power.read(), PIN_afar_power.read());
uci1 8:95a325df1f6b 898 printf("cards powered=%d\r\n",(int)AreCardsPowered());
uci1 12:d472f9811262 899 #endif
uci1 0:664899e0b988 900
uci1 15:f2569d8e4176 901 PIN_spi.format( 16, 1 ); // back to trigger mode
uci1 15:f2569d8e4176 902 PIN_spi.frequency( 10000000 ); // Max is 12.5 MHz
uci1 15:f2569d8e4176 903
uci1 8:95a325df1f6b 904 if (AreCardsPowered()) {
uci1 8:95a325df1f6b 905
uci1 8:95a325df1f6b 906 if (gFirstEvt==false) {
uci1 8:95a325df1f6b 907 PIN_DoNotRestartAllClocks = 0;
uci1 8:95a325df1f6b 908 wait_us(1);
uci1 8:95a325df1f6b 909 PIN_DoNotRestartAllClocks = 1;
uci1 8:95a325df1f6b 910 //led3 = !led3; // toggle send clock led
uci1 8:95a325df1f6b 911 } else {
uci1 8:95a325df1f6b 912 gFirstEvt = false;
uci1 8:95a325df1f6b 913 }
uci1 8:95a325df1f6b 914
uci1 8:95a325df1f6b 915 //
uci1 8:95a325df1f6b 916 // wait for a trigger here.
uci1 8:95a325df1f6b 917 //
uci1 12:d472f9811262 918 #ifdef DEBUG
uci1 8:95a325df1f6b 919 printf("starting wait for trig\r\n");
uci1 12:d472f9811262 920 #endif
uci1 16:744ce85aede2 921
uci1 8:95a325df1f6b 922 gReadingOut = false; // this will allow forced triggers (see procForceTrigger())
uci1 8:95a325df1f6b 923 while ( PIN_a_sf_clk == 1 ) {
uci1 8:95a325df1f6b 924 if (gOpenCommWin || gCheckPower) {
uci1 12:d472f9811262 925 #ifdef DEBUG
uci1 8:95a325df1f6b 926 printf("break com=%d, pow=%d\r\n",gOpenCommWin,gCheckPower);
uci1 12:d472f9811262 927 #endif
uci1 8:95a325df1f6b 928 return; // break out to open comms or check power
uci1 8:95a325df1f6b 929 }
uci1 0:664899e0b988 930 }
uci1 8:95a325df1f6b 931 PIN_forceTrigger=0; // necessary for forced triggers, harmless for other triggers
uci1 8:95a325df1f6b 932 gReadingOut = true; // disallow new forced triggers
uci1 15:f2569d8e4176 933
uci1 15:f2569d8e4176 934 // we can't be interrupted before data arrives at the MB FPGA
uci1 15:f2569d8e4176 935 //StopAllTickers();
uci1 15:f2569d8e4176 936 /*
uci1 15:f2569d8e4176 937 procForceTrigger();
uci1 15:f2569d8e4176 938 procHeartbeat();
uci1 15:f2569d8e4176 939 procPowerCheck();
uci1 15:f2569d8e4176 940 procCommWin();
uci1 15:f2569d8e4176 941 */
uci1 16:744ce85aede2 942
uci1 16:744ce85aede2 943 //wait_us(6);
uci1 16:744ce85aede2 944
uci1 8:95a325df1f6b 945 //
uci1 8:95a325df1f6b 946 // collect data from daughter cards
uci1 8:95a325df1f6b 947 //
uci1 8:95a325df1f6b 948 // TODO: what if some card (set of channels) doesn't respond?
uci1 8:95a325df1f6b 949 // currently, will wait forever?
uci1 8:95a325df1f6b 950 // also, if ch1 is dead, will wait forever (due to FPGA code)
uci1 16:744ce85aede2 951 gAdcToMBtimer.start();
uci1 16:744ce85aede2 952 for( uint8_t i = 0; i < 128; ++i ) {
uci1 16:744ce85aede2 953 while (PIN_a_sf_clk==1) {}
uci1 16:744ce85aede2 954 while (PIN_a_sf_clk==0) {}
uci1 16:744ce85aede2 955 /*
uci1 16:744ce85aede2 956 if ((i == 10)&&(gEvtNum % 20)) {
uci1 16:744ce85aede2 957 wait_us(8);
uci1 16:744ce85aede2 958 }
uci1 16:744ce85aede2 959 */
uci1 16:744ce85aede2 960 PIN_ADC_CS = 0;
uci1 16:744ce85aede2 961 PIN_spi.write( 0x00 );
uci1 16:744ce85aede2 962 PIN_ADC_CS = 1;
uci1 16:744ce85aede2 963 /*
uci1 8:95a325df1f6b 964 if( PIN_a_sf_clk == 1 ) {
uci1 8:95a325df1f6b 965 if( i == 0 )
uci1 8:95a325df1f6b 966 wait_us( 1 );
uci1 8:95a325df1f6b 967
uci1 8:95a325df1f6b 968 PIN_ADC_CS = 0;
uci1 8:95a325df1f6b 969 PIN_spi.write( 0x00 );
uci1 8:95a325df1f6b 970 PIN_ADC_CS = 1;
uci1 8:95a325df1f6b 971 } else {
uci1 8:95a325df1f6b 972 i--;
uci1 8:95a325df1f6b 973 }
uci1 16:744ce85aede2 974 */
uci1 0:664899e0b988 975 }
uci1 16:744ce85aede2 976 gAdcToMBtimer.stop();
uci1 16:744ce85aede2 977 #ifdef DEBUG
uci1 16:744ce85aede2 978 printf("total time = %d us\r\n", gAdcToMBtimer.read_us());
uci1 16:744ce85aede2 979 #endif
uci1 16:744ce85aede2 980 if ( kAdcToMBtimeCut < gAdcToMBtimer.read_us() ) {
uci1 16:744ce85aede2 981 gEvent.SetTrgBit(kAdcToMBflag);
uci1 16:744ce85aede2 982 }
uci1 16:744ce85aede2 983 gAdcToMBtimer.reset();
uci1 15:f2569d8e4176 984
uci1 15:f2569d8e4176 985 // restart the timers
uci1 15:f2569d8e4176 986 //ResetAllTickers();
uci1 8:95a325df1f6b 987 } else {
uci1 8:95a325df1f6b 988 // cards have no power. don't try reading out
uci1 8:95a325df1f6b 989 gReadingOut=false;
uci1 0:664899e0b988 990 }
uci1 0:664899e0b988 991 }
uci1 0:664899e0b988 992
uci1 13:7a1fb885a8e4 993 SnCommWin::ECommWinResult OpenCommWin(const bool forceReconfig) {
uci1 0:664899e0b988 994 // loop through each comm mode:
uci1 0:664899e0b988 995 // a) try to connect
uci1 0:664899e0b988 996 // b) if connected, listen for config
uci1 0:664899e0b988 997 // c) if config requests data, send it
uci1 16:744ce85aede2 998 /*
uci1 16:744ce85aede2 999 for (int i=0; i<5; i++) {
uci1 16:744ce85aede2 1000 led4=1;
uci1 16:744ce85aede2 1001 led3=1;
uci1 16:744ce85aede2 1002 wait(0.5);
uci1 16:744ce85aede2 1003 led4=0;
uci1 16:744ce85aede2 1004 led3=0;
uci1 16:744ce85aede2 1005 wait(0.5);
uci1 16:744ce85aede2 1006 }
uci1 16:744ce85aede2 1007 */
uci1 3:24c5f0f50bf1 1008 gLastCommWin = time(0);
uci1 13:7a1fb885a8e4 1009
uci1 0:664899e0b988 1010 SnCommWin::ECommWinResult res = SnCommWin::kUndefFail;
uci1 0:664899e0b988 1011
uci1 1:e392595b4b76 1012 bool gotNewConfig=false;
uci1 13:7a1fb885a8e4 1013
uci1 13:7a1fb885a8e4 1014 if (gConf.GetCommWinDuration()==0) {
uci1 13:7a1fb885a8e4 1015 // TODO: set min so this is not possible
uci1 13:7a1fb885a8e4 1016 res = SnCommWin::kOkNoMsg;
uci1 13:7a1fb885a8e4 1017 } else {
uci1 13:7a1fb885a8e4 1018
uci1 13:7a1fb885a8e4 1019 gCommWinOpen = true;
uci1 1:e392595b4b76 1020 Watchdog::kick(); // don't reset!
uci1 13:7a1fb885a8e4 1021
uci1 13:7a1fb885a8e4 1022 #ifdef DEBUG
uci1 13:7a1fb885a8e4 1023 printf("opening comm window at %d\r\n", (int32_t)gLastCommWin);
uci1 16:744ce85aede2 1024 printf("duration=%u\r\n",gConf.GetCommWinDuration());
uci1 13:7a1fb885a8e4 1025 #endif
uci1 13:7a1fb885a8e4 1026
uci1 13:7a1fb885a8e4 1027 // close the file so that the data is all written out.
uci1 13:7a1fb885a8e4 1028 // and open it back up at the beginning (for reading)
uci1 12:d472f9811262 1029 #ifdef DEBUG
uci1 13:7a1fb885a8e4 1030 printf("close & open file. gEvtNum=%u, gPowNum=%u\r\n",gEvtNum,gPowNum);
uci1 12:d472f9811262 1031 #endif
uci1 13:7a1fb885a8e4 1032 PIN_lockRegisters = 0; // unlock so we can talk to SD card.
uci1 13:7a1fb885a8e4 1033 SnSDUtils::CloseOutputFile(SnSDUtils::GetCurFile());
uci1 13:7a1fb885a8e4 1034 SnSDUtils::OpenExistingFile(SnSDUtils::GetCurFileName(), true);
uci1 13:7a1fb885a8e4 1035
uci1 13:7a1fb885a8e4 1036 // (probably) power down cards,amps and power up comms
uci1 13:7a1fb885a8e4 1037 SetPower(true);
uci1 13:7a1fb885a8e4 1038
uci1 15:f2569d8e4176 1039
uci1 13:7a1fb885a8e4 1040 bool sendStat[kNcomms];
uci1 13:7a1fb885a8e4 1041 for (uint8_t i=0; i<kNcomms; i++) {
uci1 13:7a1fb885a8e4 1042 sendStat[i]=true;
uci1 13:7a1fb885a8e4 1043 }
uci1 13:7a1fb885a8e4 1044 bool* ss = sendStat;
uci1 13:7a1fb885a8e4 1045 SnCommWin** cw = gComms;
uci1 13:7a1fb885a8e4 1046 for (uint8_t i=0; ((time(0)-gLastCommWin)<gConf.GetCommWinDuration()); i++, cw++, ss++) {
uci1 1:e392595b4b76 1047 Watchdog::kick(); // don't reset!
uci1 13:7a1fb885a8e4 1048 if (i==kNcomms) {
uci1 13:7a1fb885a8e4 1049 i=0;
uci1 13:7a1fb885a8e4 1050 cw = gComms;
uci1 13:7a1fb885a8e4 1051 ss = sendStat;
uci1 13:7a1fb885a8e4 1052 }
uci1 13:7a1fb885a8e4 1053 if ((*cw)==0) {
uci1 13:7a1fb885a8e4 1054 continue;
uci1 13:7a1fb885a8e4 1055 }
uci1 16:744ce85aede2 1056
uci1 16:744ce85aede2 1057 const uint32_t conto =
uci1 16:744ce85aede2 1058 (gConf.GetCommWinDuration() < (*cw)->GetConnectTimeout()) ?
uci1 16:744ce85aede2 1059 gConf.GetCommWinDuration() : (*cw)->GetConnectTimeout();
uci1 16:744ce85aede2 1060 const uint32_t listo =
uci1 16:744ce85aede2 1061 (gConf.GetCommWinDuration() < (*cw)->GetListenTimeout()) ?
uci1 16:744ce85aede2 1062 gConf.GetCommWinDuration() : (*cw)->GetListenTimeout();
uci1 16:744ce85aede2 1063
uci1 16:744ce85aede2 1064 // update power reading in case we want to send it in status
uci1 16:744ce85aede2 1065 GetAvePowerReading();
uci1 16:744ce85aede2 1066 // get the trigger rates
uci1 16:744ce85aede2 1067 float thmrate=0, evtrate=0;
uci1 16:744ce85aede2 1068 GetRates(thmrate, evtrate);
uci1 13:7a1fb885a8e4 1069 // open window and (mabye) send status update
uci1 12:d472f9811262 1070 #ifdef DEBUG
uci1 13:7a1fb885a8e4 1071 printf("calling OpenWindow. ss=%d\r\n",(int)(*ss));
uci1 13:7a1fb885a8e4 1072 printf("gtt=%u, ct=%d, lcw=%d, dur=%u\r\n",GetTimeoutTime(gLastCommWin,conto),
uci1 13:7a1fb885a8e4 1073 time(0), gLastCommWin, gConf.GetCommWinDuration());
uci1 12:d472f9811262 1074 #endif
uci1 13:7a1fb885a8e4 1075 const SnCommWin::ECommWinResult conres = (*cw)->OpenWindow(
uci1 13:7a1fb885a8e4 1076 GetTimeoutTime(gLastCommWin, conto), *ss, gConf, gEvent, gPower,
uci1 13:7a1fb885a8e4 1077 SnSDUtils::GetCurSeqNum(), thmrate, evtrate,
uci1 13:7a1fb885a8e4 1078 gGenBuf);
uci1 13:7a1fb885a8e4 1079 if (conres>=SnCommWin::kConnected) {
uci1 1:e392595b4b76 1080 Watchdog::kick(); // don't reset!
uci1 13:7a1fb885a8e4 1081 // connected. listen for config
uci1 13:7a1fb885a8e4 1082 *ss = false; // don't send status next time
uci1 12:d472f9811262 1083 #ifdef DEBUG
uci1 13:7a1fb885a8e4 1084 printf("get conf gtt=%u\r\n",GetTimeoutTime(gLastCommWin, listo));
uci1 12:d472f9811262 1085 #endif
uci1 13:7a1fb885a8e4 1086 const SnCommWin::ECommWinResult cfgres = (*cw)->GetConfig(
uci1 13:7a1fb885a8e4 1087 gConf, GetTimeoutTime(gLastCommWin, listo), gGenBuf, gBufSize);
uci1 16:744ce85aede2 1088
uci1 13:7a1fb885a8e4 1089 if (cfgres>=SnCommWin::kOkWithMsg) {
uci1 13:7a1fb885a8e4 1090 Watchdog::kick(); // don't reset!
uci1 16:744ce85aede2 1091
uci1 12:d472f9811262 1092 #ifdef DEBUG
uci1 13:7a1fb885a8e4 1093 printf("received config!\r\n");
uci1 13:7a1fb885a8e4 1094 printf("send data = %d\r\n", gConf.GetCommSendData());
uci1 12:d472f9811262 1095 #endif
uci1 13:7a1fb885a8e4 1096 // send data if need be (files, some events, etc)
uci1 13:7a1fb885a8e4 1097 const uint32_t winto = GetTimeoutTime(gLastCommWin,
uci1 13:7a1fb885a8e4 1098 gConf.GetCommWinDuration());
uci1 13:7a1fb885a8e4 1099 const uint32_t gtt = gConf.IsObeyingTimeout() ? winto : 0;
uci1 13:7a1fb885a8e4 1100 if (gConf.GetCommSendData()!=0) {
uci1 12:d472f9811262 1101 #ifdef DEBUG
uci1 13:7a1fb885a8e4 1102 printf("sending data, gtt=%u. lcw=%u, dur=%u, obey=%s\r\n",
uci1 13:7a1fb885a8e4 1103 GetTimeoutTime(gLastCommWin, gConf.GetCommWinDuration()),
uci1 13:7a1fb885a8e4 1104 gLastCommWin, gConf.GetCommWinDuration(),
uci1 13:7a1fb885a8e4 1105 gConf.IsObeyingTimeout() ? "true" : "false");
uci1 12:d472f9811262 1106 #endif
uci1 16:744ce85aede2 1107
uci1 13:7a1fb885a8e4 1108 res = (*cw)->SendData(gConf, gEvent, gPower, gGenBuf, gBufSize,
uci1 13:7a1fb885a8e4 1109 gtt, winto);
uci1 13:7a1fb885a8e4 1110 } else {
uci1 13:7a1fb885a8e4 1111 // don't send anything
uci1 13:7a1fb885a8e4 1112 res = cfgres;
uci1 13:7a1fb885a8e4 1113 }
uci1 13:7a1fb885a8e4 1114 #ifdef DEBUG
uci1 13:7a1fb885a8e4 1115 printf("Got config!\r\n");
uci1 13:7a1fb885a8e4 1116 #endif
uci1 13:7a1fb885a8e4 1117 gotNewConfig = (cfgres!=SnCommWin::kOkWthMsgNoConf);
uci1 13:7a1fb885a8e4 1118 Watchdog::kick(); // don't reset!
uci1 13:7a1fb885a8e4 1119 break;
uci1 13:7a1fb885a8e4 1120 }
uci1 0:664899e0b988 1121 }
uci1 13:7a1fb885a8e4 1122
uci1 13:7a1fb885a8e4 1123 Watchdog::kick(); // don't reset!
uci1 0:664899e0b988 1124 }
uci1 15:f2569d8e4176 1125 // close the connection(s)
uci1 15:f2569d8e4176 1126 cw = gComms;
uci1 15:f2569d8e4176 1127 for (uint8_t i=0; i<kNcomms; i++, cw++) {
uci1 15:f2569d8e4176 1128 if ((*cw)==0) {
uci1 15:f2569d8e4176 1129 continue;
uci1 15:f2569d8e4176 1130 }
uci1 16:744ce85aede2 1131 if ((*cw)->GetCommType()==SnConfigFrame::kIrid) {
uci1 16:744ce85aede2 1132 #ifdef DEBUG
uci1 16:744ce85aede2 1133 printf("try to set iridium time\r\n");
uci1 16:744ce85aede2 1134 #endif
uci1 16:744ce85aede2 1135 // set the clock before closing connection
uci1 16:744ce85aede2 1136 const bool con =
uci1 16:744ce85aede2 1137 (*cw)->Connect(GetTimeoutTime(gLastCommWin,
uci1 16:744ce85aede2 1138 gConf.GetCommWinDuration()));
uci1 16:744ce85aede2 1139 if (con) {
uci1 16:744ce85aede2 1140 const uint32_t nt = (*cw)->TrySetSysTimeUnix(
uci1 16:744ce85aede2 1141 GetTimeoutTime(gLastCommWin,gConf.GetCommWinDuration()));
uci1 16:744ce85aede2 1142 }
uci1 16:744ce85aede2 1143 }
uci1 15:f2569d8e4176 1144 (*cw)->CloseConn(GetTimeoutTime(gLastCommWin,gConf.GetCommWinDuration()));
uci1 15:f2569d8e4176 1145 Watchdog::kick(); // don't reset!
uci1 15:f2569d8e4176 1146 }
uci1 0:664899e0b988 1147 }
uci1 12:d472f9811262 1148
uci1 4:a91682e19d6b 1149 // (probably) power down comms and power up cards,amps
uci1 4:a91682e19d6b 1150 SetPower(false);
uci1 4:a91682e19d6b 1151
uci1 1:e392595b4b76 1152 gFirstEvt = true;
uci1 4:a91682e19d6b 1153
uci1 1:e392595b4b76 1154 // reset config with system powered (for DAC/PLA setting)
uci1 13:7a1fb885a8e4 1155 if (gotNewConfig || forceReconfig) {
uci1 12:d472f9811262 1156 #ifdef DEBUG
uci1 1:e392595b4b76 1157 printf("calling SetConfigAndMakeOutputFile\r\n");
uci1 12:d472f9811262 1158 #endif
uci1 1:e392595b4b76 1159 SetConfigAndMakeOutputFile();
uci1 12:d472f9811262 1160 } else {
uci1 12:d472f9811262 1161 MakeOutputFile();
uci1 1:e392595b4b76 1162 }
uci1 12:d472f9811262 1163 #ifdef DEBUG
uci1 1:e392595b4b76 1164 printf("closing comm win at %d\r\n",(int32_t)time(0));
uci1 12:d472f9811262 1165 #endif
uci1 1:e392595b4b76 1166
uci1 0:664899e0b988 1167 gCommWinOpen = false;
uci1 0:664899e0b988 1168 return res;
uci1 0:664899e0b988 1169 }