Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Tue Jul 30 02:03:21 2013 +0000
Revision:
39:2f17131d22a5
Parent:
37:ff95e7070f26
Child:
40:1324da35afd4
Temp commit so we can revert to other revisions. Changed some dynamic_casts to static_casts. Added NULL char to config label writing and updated io versions. Added battery hysteresis.

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