Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Thu Nov 01 07:00:17 2012 +0000
Revision:
27:efc4d654b139
Parent:
25:57b2627fe756
Child:
28:484943132bb0
Afar comms enabled. Bug fixes: comm win opens with high rate now and no power to afar with afar comm enabled will not stall MBED. Features: stop file transfer, delete a specified run or delete all files on the SD card (file trans handshakes).

Who changed what in which revision?

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