Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Wed Jan 23 19:38:57 2013 +0000
Revision:
33:06eb182d8813
Parent:
32:20877f862cf0
Child:
35:549714a257a4
USB comms. Safety nets disabled. 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 33:06eb182d8813 6 #define DISABLE_CONFIG_SAFETYNETS
uci1 31:b5bd3b189150 7
uci1 33:06eb182d8813 8 //#define ENABLE_AFAR_COMM
uci1 33:06eb182d8813 9 //#define ENABLE_SBD_COMM
uci1 33:06eb182d8813 10 #define ENABLE_USB_COMM
uci1 33:06eb182d8813 11 //#define ENABLE_AFAR_TWITTER
uci1 25:57b2627fe756 12
uci1 18:55f1581f2ee4 13 //#define USE_RTOS_TIMER
uci1 18:55f1581f2ee4 14 //#define USE_ETH_INTERFACE
uci1 12:d472f9811262 15 //#define EVT_TIME_PROFILE
uci1 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 }