Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Wed Oct 10 05:54:12 2012 +0000
Revision:
21:ce51bb0ba4a5
Parent:
19:74155d652c37
Child:
22:f957c4f840ad
Uses USB comm. Fix rates calc. Power up/down ETH with Afar. Fix sending evt with status. Add num files and bytes of data to status. Can save a local file (i.e. reprogram MBED) via comms. Set config after each comm win (need if cards pow cycle).

Who changed what in which revision?

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