Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Wed Nov 28 01:24:23 2012 +0000
Revision:
30:f869ed4bcc08
Parent:
28:484943132bb0
Child:
31:b5bd3b189150
Change power so to account for the Iridium being on the same relay as afar. Afar, SBD, Twitter enabled. No Debugging.

Who changed what in which revision?

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