Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Wed Jan 23 19:29:01 2013 +0000
Revision:
31:b5bd3b189150
Parent:
30:f869ed4bcc08
Child:
32:20877f862cf0
Added option in SnConstants to allow for proper switching of peripheral power in stations that have the Afar and Iridium power lines spliced together. Afar, SBD and Twitter comms enabled. Afar and Iridium powered together.

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