Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Sat Aug 04 01:48:55 2012 +0000
Revision:
7:079617408fec
Parent:
6:6f002d202f59
Child:
8:95a325df1f6b
Bug fix to seq finder. Comms totally disabled. Many debug messages.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
uci1 0:664899e0b988 1 #include "mbed.h"
uci1 0:664899e0b988 2
uci1 0:664899e0b988 3 #include <stdint.h>
uci1 0:664899e0b988 4 #include "SDFileSystem.h"
uci1 0:664899e0b988 5 #include "MODSERIAL.h"
uci1 0:664899e0b988 6 #include "Watchdog.h"
uci1 0:664899e0b988 7 #include "SnConstants.h"
uci1 0:664899e0b988 8 #include "SnBitUtils.h"
uci1 0:664899e0b988 9 #include "SnSDUtils.h"
uci1 0:664899e0b988 10 #include "SnConfigFrame.h"
uci1 0:664899e0b988 11 #include "SnEventFrame.h"
uci1 0:664899e0b988 12 #include "SnStatusFrame.h"
uci1 2:e67f7c158087 13 #include "SnHeaderFrame.h"
uci1 0:664899e0b988 14 #include "SnCommWin.h"
uci1 7:079617408fec 15 #include "SnCommAfarTCP.h"
uci1 0:664899e0b988 16 #include "SnCommUsb.h"
uci1 1:e392595b4b76 17 #include "SnBase64.h"
uci1 0:664899e0b988 18
uci1 0:664899e0b988 19 //
uci1 0:664899e0b988 20 // MBED PINS (ordered by number)
uci1 0:664899e0b988 21 //
uci1 0:664899e0b988 22 // leds (for debugging)
uci1 0:664899e0b988 23 DigitalOut led1(LED1);
uci1 0:664899e0b988 24 DigitalOut led2(LED2);
uci1 0:664899e0b988 25 DigitalOut led3(LED3);
uci1 0:664899e0b988 26 DigitalOut led4(LED4);
uci1 0:664899e0b988 27 // Set up power pins - Note that it's Zero for "on"
uci1 1:e392595b4b76 28 DigitalOut PIN_turn_on_system(p17); // this turns on system
uci1 0:664899e0b988 29 DigitalOut PIN_turn_on_amps(p25);
uci1 0:664899e0b988 30 // Activate/select chip by falling edge
uci1 0:664899e0b988 31 DigitalOut PIN_ADC_CS( p9 );
uci1 0:664899e0b988 32 // clock signal to activate PLA setting
uci1 0:664899e0b988 33 DigitalOut PIN_PLA_cs(p10);
uci1 0:664899e0b988 34 // To force a trigger
uci1 0:664899e0b988 35 DigitalOut PIN_forceTrigger(p11); //modification
uci1 0:664899e0b988 36 // To suppress thermal triggers
uci1 0:664899e0b988 37 DigitalOut PIN_enableThermTrig(p12);
uci1 0:664899e0b988 38 // Restart clock on all FPGAs.
uci1 0:664899e0b988 39 DigitalOut PIN_DoNotRestartAllClocks( p13 );
uci1 0:664899e0b988 40 // This tells the DFPGAs to store the data on motherboard FPGA and
uci1 0:664899e0b988 41 // read it out.
uci1 0:664899e0b988 42 DigitalIn PIN_a_sf_clk( p14 );
uci1 0:664899e0b988 43 DigitalIn PIN_rst_a_sf(p15);
uci1 1:e392595b4b76 44 // afar power
uci1 1:e392595b4b76 45 DigitalOut PIN_afar_power(p16);
uci1 4:a91682e19d6b 46 // batter voltage/current measurement
uci1 4:a91682e19d6b 47 AnalogIn PIN_vADC1(p19);
uci1 4:a91682e19d6b 48 AnalogIn PIN_vADC2(p18);
uci1 0:664899e0b988 49 // Lock daughter card registeres (during data readout).
uci1 0:664899e0b988 50 DigitalOut PIN_lockRegisters( p20 );
uci1 1:e392595b4b76 51 // iridium (SBD) power
uci1 1:e392595b4b76 52 DigitalOut PIN_iridSbd_power(p21);
uci1 0:664899e0b988 53 // Majority logic pins
uci1 0:664899e0b988 54 DigitalOut PIN_MajLogHiBit(p22);
uci1 0:664899e0b988 55 DigitalOut PIN_MajLogLoBit(p23);
uci1 0:664899e0b988 56 // Tell FPGA to be ready to accept DAC values
uci1 0:664899e0b988 57 DigitalOut PIN_start_fpga(p26);
uci1 0:664899e0b988 58 // Two bits to the select the daughter card for readout
uci1 0:664899e0b988 59 DigitalOut PIN_selCardHiBit( p29 );
uci1 0:664899e0b988 60 DigitalOut PIN_selCardLoBit( p30 );
uci1 0:664899e0b988 61 // To launch a heartbeat pulse
uci1 0:664899e0b988 62 DigitalOut PIN_heartbeat(p24);
uci1 0:664899e0b988 63 // Setup SPI pins
uci1 0:664899e0b988 64 SPI PIN_spi( p5, p6, p7 );
uci1 0:664899e0b988 65 // The SD card
uci1 3:24c5f0f50bf1 66
uci1 3:24c5f0f50bf1 67 // this needs to be first in case some other global uses a print statement
uci1 3:24c5f0f50bf1 68 static MODSERIAL gCpu( USBTX, USBRX ); // defined here so it might be used for debugging output
uci1 3:24c5f0f50bf1 69
uci1 0:664899e0b988 70 SDFileSystem sd(p5, p6, p7, p8, SnSDUtils::kSDsubDir+1);
uci1 0:664899e0b988 71 LocalFileSystem local("local");
uci1 0:664899e0b988 72
uci1 0:664899e0b988 73 //
uci1 0:664899e0b988 74 // fwd declare fcns
uci1 0:664899e0b988 75 //
uci1 0:664899e0b988 76 void ReadAllRegisters();
uci1 0:664899e0b988 77 void ReadRegister(const uint8_t chan, int16_t* dev);
uci1 0:664899e0b988 78 void SaveEvent(const int32_t etms);
uci1 0:664899e0b988 79 void WaitTrigAndSendClock();
uci1 1:e392595b4b76 80 void SetConfigAndMakeOutputFile();
uci1 0:664899e0b988 81 SnCommWin::ECommWinResult OpenCommWin();
uci1 3:24c5f0f50bf1 82 void MakeOutputFile(const bool stopRunning=false);
uci1 4:a91682e19d6b 83 void SetPower(const bool isCommWin);
uci1 0:664899e0b988 84
uci1 0:664899e0b988 85 //
uci1 0:664899e0b988 86 // globals
uci1 0:664899e0b988 87 //
uci1 0:664899e0b988 88 // readout objs
uci1 0:664899e0b988 89 static Ticker gForceTicker;
uci1 3:24c5f0f50bf1 90 static Ticker gHeartbeatTicker;
uci1 1:e392595b4b76 91 static Ticker gCommWinTicker;
uci1 0:664899e0b988 92 static Timer gEvtTimer;
uci1 0:664899e0b988 93 static SnConfigFrame gConf;
uci1 0:664899e0b988 94 static SnEventFrame gEvent;
uci1 0:664899e0b988 95 // parameters
uci1 0:664899e0b988 96 static bool gFirstEvt = true;
uci1 0:664899e0b988 97 static bool gReadingOut = false;
uci1 0:664899e0b988 98 static bool gCommWinOpen = false; // if it's open
uci1 1:e392595b4b76 99 static volatile bool gOpenCommWin = false; // if it should be opened
uci1 0:664899e0b988 100 static int32_t gEvtNum = 0; // num of evt written
uci1 0:664899e0b988 101 static int32_t gTrgNum[kNumTrgs] = {0}; // num of this type of trg received
uci1 0:664899e0b988 102 // i/o
uci1 1:e392595b4b76 103 static time_t gLastCommWin = 0;
uci1 3:24c5f0f50bf1 104 static const uint32_t gBufSize=SnStatusFrame::kMaxSizeOf + SnHeaderFrame::kMaxSizeOf;
uci1 6:6f002d202f59 105 //static const uint32_t gB64Bsize=BASE64ENC_LEN(gBufSize)+1;
uci1 6:6f002d202f59 106 //static char gB64Buf[gB64Bsize];
uci1 3:24c5f0f50bf1 107 static char gGenBuf[gBufSize]; // must be big enough for event or status or config!
uci1 1:e392595b4b76 108 //static SnCommWin* gComms[kNcomms] = { new SnCommAfar, new SnCommUsb(&gCpu) }; // order => priority
uci1 1:e392595b4b76 109 //static SnCommWin* gComms[kNcomms] = { new SnCommUsb(&gCpu) }; // order => priority
uci1 6:6f002d202f59 110 //static SnCommWin* gComms[kNcomms] = { new SnCommAfar(gB64Buf, gB64Bsize) }; // order => priority
uci1 6:6f002d202f59 111 //static SnCommWin* gComms[kNcomms] = { new SnCommAfarTCP(false) }; // order => priority
uci1 6:6f002d202f59 112 static SnCommWin* gComms[kNcomms] = { 0 }; // order => priority
uci1 0:664899e0b988 113
uci1 0:664899e0b988 114 void procForceTrigger() {
uci1 3:24c5f0f50bf1 115 led3=!led3;
uci1 0:664899e0b988 116 if (gReadingOut==false && gCommWinOpen==false) {
uci1 0:664899e0b988 117 gEvent.SetTrgBit(kFrcTrg);
uci1 0:664899e0b988 118 gEvent.SetTrgNum((gTrgNum[kFrcTrg])++);
uci1 0:664899e0b988 119 PIN_forceTrigger = 1; // force a trigger
uci1 0:664899e0b988 120 }
uci1 0:664899e0b988 121 }
uci1 0:664899e0b988 122
uci1 3:24c5f0f50bf1 123 void procHeartbeat() {
uci1 3:24c5f0f50bf1 124 if (gReadingOut==false && gCommWinOpen==false) {
uci1 3:24c5f0f50bf1 125 PIN_heartbeat = 1; // heartbeat pulse
uci1 3:24c5f0f50bf1 126 PIN_heartbeat = 0;
uci1 3:24c5f0f50bf1 127 }
uci1 3:24c5f0f50bf1 128 }
uci1 3:24c5f0f50bf1 129
uci1 0:664899e0b988 130 void procCommWin() {
uci1 0:664899e0b988 131 if (gReadingOut==false && gCommWinOpen==false) {
uci1 1:e392595b4b76 132 if ( (time(0) - gLastCommWin) > gConf.GetCommWinPeriod() ) {
uci1 1:e392595b4b76 133 led3=!led3;
uci1 1:e392595b4b76 134 gOpenCommWin = true;
uci1 1:e392595b4b76 135 }
uci1 0:664899e0b988 136 }
uci1 0:664899e0b988 137 }
uci1 0:664899e0b988 138
uci1 1:e392595b4b76 139 uint32_t GetTimeoutTime(const uint32_t startTime,
uci1 1:e392595b4b76 140 const uint32_t delta) {
uci1 1:e392595b4b76 141 const uint32_t lst = time(0)-startTime;
uci1 1:e392595b4b76 142 const uint32_t lio =
uci1 1:e392595b4b76 143 ((lst+delta) < gConf.GetCommWinDuration()) ?
uci1 1:e392595b4b76 144 lst+delta : gConf.GetCommWinDuration();
uci1 1:e392595b4b76 145 return lio+startTime;
uci1 1:e392595b4b76 146 }
uci1 1:e392595b4b76 147
uci1 0:664899e0b988 148
uci1 0:664899e0b988 149 // TODO: add block-id's to output file? (config block, event block, file header block, etc.)
uci1 0:664899e0b988 150
uci1 1:e392595b4b76 151 // TODO: HEARTBEAT!
uci1 1:e392595b4b76 152
uci1 1:e392595b4b76 153 // TODO: make websocket URL settable in the config (i.e. via SBD?)
uci1 1:e392595b4b76 154
uci1 0:664899e0b988 155 int main() {
uci1 1:e392595b4b76 156 {
uci1 2:e67f7c158087 157 led1=1; wait(0.2);
uci1 2:e67f7c158087 158 led1=0; led2=1; wait(0.2);
uci1 2:e67f7c158087 159 led2=0; led3=1; wait(0.2);
uci1 2:e67f7c158087 160 led3=0; led4=1; wait(0.2);
uci1 1:e392595b4b76 161 led4=0;
uci1 1:e392595b4b76 162 }
uci1 1:e392595b4b76 163
uci1 0:664899e0b988 164 led2=1;
uci1 0:664899e0b988 165 //wait_ms(100);
uci1 1:e392595b4b76 166
uci1 3:24c5f0f50bf1 167 printf("\n\n\n\n\n\nstarting\r\n");
uci1 1:e392595b4b76 168
uci1 0:664899e0b988 169 // a failsafe
uci1 0:664899e0b988 170 Watchdog::kick(kWDFailsafe);
uci1 0:664899e0b988 171
uci1 1:e392595b4b76 172 // set the clock to the BS time, if it's not set
uci1 1:e392595b4b76 173 if ( (static_cast<int32_t>(time(0)))<0 ) {
uci1 1:e392595b4b76 174 set_time(kBStime);
uci1 1:e392595b4b76 175 }
uci1 1:e392595b4b76 176 printf("time = %d\r\n",(int32_t)time(0));
uci1 1:e392595b4b76 177 gLastCommWin = time(0); // prevent comm win proc
uci1 0:664899e0b988 178
uci1 0:664899e0b988 179 gForceTicker.detach();
uci1 0:664899e0b988 180 gFirstEvt = true;
uci1 0:664899e0b988 181
uci1 4:a91682e19d6b 182 // (probably) power down comms and power up cards,amps
uci1 4:a91682e19d6b 183 SetPower(false);
uci1 4:a91682e19d6b 184
uci1 3:24c5f0f50bf1 185 printf("Using config %s\r\n",gConf.GetLabel());
uci1 1:e392595b4b76 186 SetConfigAndMakeOutputFile(); // setup defaults in case no communication
uci1 4:a91682e19d6b 187
uci1 0:664899e0b988 188 //
uci1 0:664899e0b988 189 // get config
uci1 0:664899e0b988 190 //
uci1 3:24c5f0f50bf1 191 //printf("open window\r\n");
uci1 2:e67f7c158087 192 OpenCommWin();
uci1 3:24c5f0f50bf1 193
uci1 0:664899e0b988 194 // get ready to trigger
uci1 0:664899e0b988 195 PIN_spi.format( 16, 1 ); // change to data readout format
uci1 0:664899e0b988 196
uci1 0:664899e0b988 197 led2=0;
uci1 0:664899e0b988 198
uci1 0:664899e0b988 199 // the main event loop. wait for triggers in SendClock
uci1 3:24c5f0f50bf1 200 gEvtTimer.start();
uci1 0:664899e0b988 201 while( true )
uci1 0:664899e0b988 202 {
uci1 0:664899e0b988 203 // in here, we wait for triggers from the MB-FPGA
uci1 0:664899e0b988 204 Watchdog::kick(); // don't reset!
uci1 1:e392595b4b76 205
uci1 1:e392595b4b76 206 led1 = !led1;
uci1 1:e392595b4b76 207
uci1 1:e392595b4b76 208 printf("calling wait trig\r\n");
uci1 1:e392595b4b76 209 printf("gFirstEvt=%s\r\n",gFirstEvt?"true":"false");
uci1 5:9cea89700c66 210 printf("readingout=%d\r\n",(int)gReadingOut);
uci1 1:e392595b4b76 211
uci1 0:664899e0b988 212 PIN_lockRegisters = 0; // allow data to come from DFPGA
uci1 0:664899e0b988 213 WaitTrigAndSendClock();
uci1 0:664899e0b988 214 PIN_lockRegisters = 1; // block registers during readout
uci1 1:e392595b4b76 215
uci1 3:24c5f0f50bf1 216 const int32_t etms = gEvtTimer.read_ms(); // time since last trigger
uci1 3:24c5f0f50bf1 217 gEvtTimer.reset(); gEvtTimer.start(); // start counter from this trigger
uci1 1:e392595b4b76 218
uci1 1:e392595b4b76 219 printf("wait trig send clock exited\r\n");
uci1 1:e392595b4b76 220
uci1 0:664899e0b988 221 Watchdog::kick(); // don't reset!
uci1 0:664899e0b988 222
uci1 1:e392595b4b76 223 if (gReadingOut) {
uci1 1:e392595b4b76 224 //
uci1 1:e392595b4b76 225 // got trigger. read registers to mbed and build the event
uci1 1:e392595b4b76 226 //
uci1 1:e392595b4b76 227
uci1 1:e392595b4b76 228 led4=1;
uci1 1:e392595b4b76 229 printf("readout\r\n");
uci1 1:e392595b4b76 230
uci1 1:e392595b4b76 231 // read data & calc CRC
uci1 1:e392595b4b76 232 gEvent.ReadWaveforms(PIN_spi, PIN_selCardHiBit, PIN_selCardLoBit);
uci1 1:e392595b4b76 233 gEvent.SetCurMbedTime();
uci1 1:e392595b4b76 234 // TODO: no way to check for external trigger?
uci1 1:e392595b4b76 235 if (gEvent.IsForcedTrg()==false) {
uci1 1:e392595b4b76 236 gEvent.SetTrgBit(kThmTrg);
uci1 1:e392595b4b76 237 gEvent.SetTrgNum((gTrgNum[kThmTrg])++);
uci1 1:e392595b4b76 238 } // else already set by procForceTrigger
uci1 1:e392595b4b76 239 // (no need to calc if we throw this event away)
uci1 1:e392595b4b76 240
uci1 1:e392595b4b76 241 Watchdog::kick(); // don't reset!
uci1 1:e392595b4b76 242
uci1 1:e392595b4b76 243 printf("gFirstEvt=%s\r\n",gFirstEvt?"true":"false");
uci1 1:e392595b4b76 244
uci1 1:e392595b4b76 245 if ( gEvent.IsForcedTrg() || gFirstEvt ||
uci1 1:e392595b4b76 246 (etms>gConf.GetEvtThrtlPeriodMs()) ) {
uci1 1:e392595b4b76 247
uci1 1:e392595b4b76 248 led2=1;
uci1 1:e392595b4b76 249
uci1 1:e392595b4b76 250 PIN_lockRegisters = 0; // done reading, unlock so we can talk to SD card.
uci1 1:e392595b4b76 251
uci1 1:e392595b4b76 252 SaveEvent(etms);
uci1 3:24c5f0f50bf1 253
uci1 3:24c5f0f50bf1 254 if (gEvtNum>=(gConf.GetFirstEvt()+gConf.GetEvtsPerFile())) {
uci1 3:24c5f0f50bf1 255 MakeOutputFile(gConf.IsSingleSeqRunMode());
uci1 3:24c5f0f50bf1 256 }
uci1 3:24c5f0f50bf1 257 /*
uci1 1:e392595b4b76 258 } else {
uci1 1:e392595b4b76 259 printf("forced=%s, gFirstEvt=%s, e>t %d>%hu %s\r\n",
uci1 1:e392595b4b76 260 gEvent.IsForcedTrg()?"true":"false", gFirstEvt?"true":"false",
uci1 1:e392595b4b76 261 etms, gConf.GetEvtThrtlPeriodMs(),
uci1 1:e392595b4b76 262 etms>gConf.GetEvtThrtlPeriodMs() ? "true":"false");
uci1 3:24c5f0f50bf1 263 */
uci1 1:e392595b4b76 264 }
uci1 1:e392595b4b76 265 }
uci1 1:e392595b4b76 266 printf("past reading out\r\n");
uci1 1:e392595b4b76 267
uci1 1:e392595b4b76 268 led4=0; led2=0;
uci1 1:e392595b4b76 269
uci1 0:664899e0b988 270 if (gOpenCommWin) {
uci1 1:e392595b4b76 271 printf("gOpenComWin=%s, opening\r\n",gOpenCommWin?"true":"false");
uci1 0:664899e0b988 272 OpenCommWin();
uci1 0:664899e0b988 273 gOpenCommWin=false;
uci1 1:e392595b4b76 274 } else {
uci1 1:e392595b4b76 275 printf("gOpenCommWin=false\r\n");
uci1 0:664899e0b988 276 }
uci1 0:664899e0b988 277 }
uci1 0:664899e0b988 278
uci1 0:664899e0b988 279 }
uci1 0:664899e0b988 280
uci1 0:664899e0b988 281 //
uci1 0:664899e0b988 282 // save the event
uci1 0:664899e0b988 283 //
uci1 0:664899e0b988 284 void SaveEvent(const int32_t etms) {
uci1 0:664899e0b988 285 // write the event
uci1 0:664899e0b988 286
uci1 3:24c5f0f50bf1 287 printf("save event\r\n");
uci1 3:24c5f0f50bf1 288
uci1 0:664899e0b988 289 // set the event number & dt
uci1 3:24c5f0f50bf1 290 gEvent.SetEvtNum(gEvtNum);
uci1 0:664899e0b988 291 gEvent.SetDTms(etms);
uci1 0:664899e0b988 292
uci1 0:664899e0b988 293 // save to SD
uci1 1:e392595b4b76 294 SnSDUtils::WriteEventTo(SnSDUtils::GetCurFile(), gGenBuf, gEvent, gConf);
uci1 0:664899e0b988 295
uci1 0:664899e0b988 296 // reset
uci1 0:664899e0b988 297 gEvent.ClearEvent();
uci1 0:664899e0b988 298
uci1 3:24c5f0f50bf1 299 // increment event number
uci1 3:24c5f0f50bf1 300 ++gEvtNum;
uci1 3:24c5f0f50bf1 301
uci1 1:e392595b4b76 302 printf("gEvtNum=%d\r\n",gEvtNum);
uci1 3:24c5f0f50bf1 303 }
uci1 3:24c5f0f50bf1 304
uci1 3:24c5f0f50bf1 305 void MakeOutputFile(const bool stopRunning) {
uci1 3:24c5f0f50bf1 306 SnSDUtils::CloseOutputFile(SnSDUtils::GetCurFile());
uci1 3:24c5f0f50bf1 307 if (stopRunning) {
uci1 2:e67f7c158087 308 while (true) {
uci1 1:e392595b4b76 309 led3 = 1; led4=1;
uci1 0:664899e0b988 310 wait(0.5);
uci1 1:e392595b4b76 311 led3 = 0; led4=0;
uci1 0:664899e0b988 312 wait(0.5);
uci1 1:e392595b4b76 313 Watchdog::kick();
uci1 0:664899e0b988 314 }
uci1 0:664899e0b988 315 }
uci1 3:24c5f0f50bf1 316 SnSDUtils::OpenNewOutputFile(gConf.GetMacAddress(),
uci1 4:a91682e19d6b 317 gConf.GetRun(),
uci1 4:a91682e19d6b 318 PIN_vADC1.read_u16(),
uci1 4:a91682e19d6b 319 PIN_vADC2.read_u16());
uci1 3:24c5f0f50bf1 320 printf("made output file with run %u\r\n",gConf.GetRun());
uci1 3:24c5f0f50bf1 321 printf("filename=%s\r\n",SnSDUtils::GetCurFileName());
uci1 3:24c5f0f50bf1 322 SnSDUtils::WriteConfig(SnSDUtils::GetCurFile(), gConf);
uci1 0:664899e0b988 323 }
uci1 0:664899e0b988 324
uci1 0:664899e0b988 325 //
uci1 4:a91682e19d6b 326 // power stuff
uci1 4:a91682e19d6b 327 //
uci1 4:a91682e19d6b 328 void SetPower(const bool isCommWin) {
uci1 4:a91682e19d6b 329 if (isCommWin) {
uci1 5:9cea89700c66 330 PIN_turn_on_system = gConf.GetPowPinSetting(SnConfigFrame::kCardComWin);
uci1 4:a91682e19d6b 331 wait_ms(10);
uci1 5:9cea89700c66 332 PIN_turn_on_amps = gConf.GetPowPinSetting(SnConfigFrame::kAmpsComWin);
uci1 4:a91682e19d6b 333 wait_ms(10);
uci1 5:9cea89700c66 334 PIN_iridSbd_power = gConf.GetPowPinSetting(SnConfigFrame::kIridComWin);
uci1 4:a91682e19d6b 335 wait_ms(10);
uci1 5:9cea89700c66 336 PIN_afar_power = gConf.GetPowPinSetting(SnConfigFrame::kAfarComWin);
uci1 4:a91682e19d6b 337 wait_ms(10);
uci1 4:a91682e19d6b 338 } else {
uci1 5:9cea89700c66 339 PIN_turn_on_system = gConf.GetPowPinSetting(SnConfigFrame::kCardDatTak);
uci1 4:a91682e19d6b 340 wait_ms(10);
uci1 5:9cea89700c66 341 PIN_turn_on_amps = gConf.GetPowPinSetting(SnConfigFrame::kAmpsDatTak);
uci1 4:a91682e19d6b 342 wait_ms(10);
uci1 5:9cea89700c66 343 PIN_iridSbd_power = gConf.GetPowPinSetting(SnConfigFrame::kIridDatTak);
uci1 4:a91682e19d6b 344 wait_ms(10);
uci1 5:9cea89700c66 345 PIN_afar_power = gConf.GetPowPinSetting(SnConfigFrame::kAfarDatTak);
uci1 4:a91682e19d6b 346 wait_ms(10);
uci1 4:a91682e19d6b 347 }
uci1 6:6f002d202f59 348 printf("set power (iscom %d, pw %hhu): cards %d, amps %d, irid %d, afar %d\r\n",
uci1 6:6f002d202f59 349 isCommWin, gConf.GetPowerMode(), PIN_turn_on_system.read(), PIN_turn_on_amps.read(),
uci1 6:6f002d202f59 350 PIN_iridSbd_power.read(), PIN_afar_power.read());
uci1 4:a91682e19d6b 351 }
uci1 4:a91682e19d6b 352
uci1 4:a91682e19d6b 353 //
uci1 0:664899e0b988 354 // set configuration
uci1 0:664899e0b988 355 //
uci1 1:e392595b4b76 356 void SetConfigAndMakeOutputFile() {
uci1 1:e392595b4b76 357 printf("SetConfigAndMakeOutputFile\r\n");
uci1 1:e392595b4b76 358
uci1 0:664899e0b988 359 // restart watchdog
uci1 0:664899e0b988 360 Watchdog::kick(gConf.GetWatchdogPeriod());
uci1 0:664899e0b988 361
uci1 1:e392595b4b76 362 // block (thermal) triggers during configuration
uci1 1:e392595b4b76 363 PIN_enableThermTrig = 0;
uci1 1:e392595b4b76 364 PIN_ADC_CS = 1;
uci1 1:e392595b4b76 365 PIN_DoNotRestartAllClocks = 1;
uci1 1:e392595b4b76 366 PIN_forceTrigger = 0;
uci1 3:24c5f0f50bf1 367 PIN_heartbeat = 0;
uci1 1:e392595b4b76 368 wait_ms(20);
uci1 1:e392595b4b76 369
uci1 0:664899e0b988 370 // reset event, timers, trigger counters
uci1 0:664899e0b988 371 gEvent.ClearEvent();
uci1 0:664899e0b988 372 gEvtNum = gConf.GetFirstEvt();
uci1 0:664899e0b988 373 memset(gTrgNum, 0, sizeof(int32_t)*kNumTrgs);
uci1 0:664899e0b988 374
uci1 0:664899e0b988 375 // make new output file
uci1 3:24c5f0f50bf1 376 MakeOutputFile();
uci1 0:664899e0b988 377
uci1 0:664899e0b988 378 // TODO: turn on amps individually, when that's possible
uci1 6:6f002d202f59 379 // PIN_turn_on_amps = gConf.IsEachAmpOn() ? 0 : 1;
uci1 0:664899e0b988 380
uci1 0:664899e0b988 381 // Set PLA value(s)
uci1 0:664899e0b988 382 PIN_spi.format( 16, 0 ); // change mode for DAC & PLA value setting
uci1 1:e392595b4b76 383 PIN_spi.frequency(1000000);
uci1 0:664899e0b988 384 PIN_MajLogHiBit=1;
uci1 0:664899e0b988 385 PIN_MajLogLoBit=1;
uci1 0:664899e0b988 386 PIN_enableThermTrig=0;
uci1 0:664899e0b988 387
uci1 0:664899e0b988 388 uint16_t hi, lo;
uci1 0:664899e0b988 389 PIN_PLA_cs=1;
uci1 1:e392595b4b76 390 wait(4);
uci1 0:664899e0b988 391 for (uint8_t pi=0; pi<kNplas; pi++) {
uci1 0:664899e0b988 392 if (pi < gConf.GetNumPlas()) {
uci1 0:664899e0b988 393 SnConfigFrame::GetHiLoPlas(gConf.GetPla(pi), hi, lo);
uci1 0:664899e0b988 394 PIN_spi.write(hi);
uci1 0:664899e0b988 395 PIN_spi.write(lo);
uci1 3:24c5f0f50bf1 396 printf("pla hi %hu, lo %hu\r\n",hi,lo);
uci1 0:664899e0b988 397 } else {
uci1 0:664899e0b988 398 PIN_spi.write(kNoTrigPla); // hi
uci1 0:664899e0b988 399 PIN_spi.write(kNoTrigPla); // lo
uci1 3:24c5f0f50bf1 400 printf("pla hi %hu, lo %hu\r\n",kNoTrigPla,kNoTrigPla);
uci1 0:664899e0b988 401 }
uci1 1:e392595b4b76 402 Watchdog::kick();
uci1 0:664899e0b988 403 }
uci1 0:664899e0b988 404 wait(3);
uci1 0:664899e0b988 405 PIN_PLA_cs=0;
uci1 0:664899e0b988 406 wait(3);
uci1 0:664899e0b988 407
uci1 0:664899e0b988 408 // DAC values
uci1 0:664899e0b988 409 //
uci1 0:664899e0b988 410 // first 12 bits = DAC value
uci1 0:664899e0b988 411 // next 2 bits = DAC ID
uci1 0:664899e0b988 412 // last 2 bits = dFPGA ID
uci1 0:664899e0b988 413 //
uci1 0:664899e0b988 414 // But FPGA uses "gray encoding" which means only 1 bit
uci1 0:664899e0b988 415 // can change at a time (of the last 4 bits). So even tho
uci1 0:664899e0b988 416 // the card/dac# is encoded, the order is also important
uci1 0:664899e0b988 417 // 0000 (dac0,card0), 0001 (dac0,card1), 0011 (dac0,card3), 0010 (dac0,card2),
uci1 0:664899e0b988 418 // 0110 (dac1,card2), 0111 (dac1,card3), 0101 (dac1,card1), etc.
uci1 1:e392595b4b76 419 printf("setting dacs\r\n");
uci1 1:e392595b4b76 420 uint16_t dv=0;
uci1 0:664899e0b988 421 for (uint8_t i=0, gri=0; i<kTotDacs; i++) {
uci1 0:664899e0b988 422 // get the gray-codes for this iteration
uci1 0:664899e0b988 423 gri = SnBitUtils::binToGray(i);
uci1 0:664899e0b988 424
uci1 0:664899e0b988 425 // build bit word
uci1 0:664899e0b988 426 dv = static_cast<int>(gConf.GetDac(gri & 0x0003u, gri >> 2u));
uci1 0:664899e0b988 427 dv <<= 4u;
uci1 0:664899e0b988 428 dv |= gri;
uci1 0:664899e0b988 429
uci1 1:e392595b4b76 430 printf("dac %04x\r\n",dv);
uci1 1:e392595b4b76 431
uci1 0:664899e0b988 432 // send to FPGA
uci1 0:664899e0b988 433 PIN_start_fpga=1;
uci1 0:664899e0b988 434 PIN_spi.write(dv);
uci1 0:664899e0b988 435 PIN_start_fpga=0;
uci1 1:e392595b4b76 436
uci1 1:e392595b4b76 437 Watchdog::kick();
uci1 1:e392595b4b76 438
uci1 0:664899e0b988 439 }
uci1 1:e392595b4b76 440 printf("dacs set\r\n");
uci1 0:664899e0b988 441 wait_ms(20);
uci1 0:664899e0b988 442
uci1 0:664899e0b988 443 // Majority Logic Trigger selection (# of cards)
uci1 0:664899e0b988 444 SnBitUtils::SetChanNumBits(gConf.GetNumCardsMajLog() - 1u,
uci1 0:664899e0b988 445 PIN_MajLogHiBit, PIN_MajLogLoBit);
uci1 0:664899e0b988 446
uci1 0:664899e0b988 447 // Enable thermal trigger?
uci1 0:664899e0b988 448 PIN_enableThermTrig = gConf.IsThermTrigEnabled();
uci1 0:664899e0b988 449
uci1 0:664899e0b988 450 PIN_spi.format( 16, 1 ); // back to trigger mode
uci1 1:e392595b4b76 451 PIN_spi.frequency( 10000000 ); // Max is 12.5 MHz
uci1 1:e392595b4b76 452
uci1 1:e392595b4b76 453 // force a trigger every...
uci1 1:e392595b4b76 454 gForceTicker.detach();
uci1 3:24c5f0f50bf1 455 if (gConf.GetForceTrigPeriod()>0) {
uci1 3:24c5f0f50bf1 456 gForceTicker.attach(&procForceTrigger,
uci1 3:24c5f0f50bf1 457 gConf.GetForceTrigPeriod() > kAbsMaxTimer ?
uci1 3:24c5f0f50bf1 458 kAbsMaxTimer : gConf.GetForceTrigPeriod()); // force period has a maximum
uci1 3:24c5f0f50bf1 459 }
uci1 3:24c5f0f50bf1 460 // heartbeat every ...
uci1 3:24c5f0f50bf1 461 gHeartbeatTicker.detach();
uci1 3:24c5f0f50bf1 462 if (gConf.GetHeartbeatPeriod()>0) {
uci1 3:24c5f0f50bf1 463 gHeartbeatTicker.attach(&procHeartbeat,
uci1 3:24c5f0f50bf1 464 gConf.GetHeartbeatPeriod() > kAbsMaxTimer ?
uci1 3:24c5f0f50bf1 465 kAbsMaxTimer : gConf.GetHeartbeatPeriod());
uci1 3:24c5f0f50bf1 466 }
uci1 1:e392595b4b76 467 // proc a comm win every...
uci1 1:e392595b4b76 468 gCommWinTicker.detach();
uci1 1:e392595b4b76 469 gCommWinTicker.attach(&procCommWin,
uci1 1:e392595b4b76 470 gConf.GetCommWinPeriod() > kAbsMaxTimer ?
uci1 1:e392595b4b76 471 kCommWinLongPrdTk : gConf.GetCommWinPeriod()); // periodic check if above max
uci1 1:e392595b4b76 472 printf("attach comm win ticker %u\r\n",
uci1 1:e392595b4b76 473 gConf.GetCommWinPeriod() > kAbsMaxTimer ?
uci1 1:e392595b4b76 474 kCommWinLongPrdTk : gConf.GetCommWinPeriod());
uci1 0:664899e0b988 475
uci1 0:664899e0b988 476 Watchdog::kick(); // don't reset!
uci1 0:664899e0b988 477
uci1 0:664899e0b988 478 }
uci1 0:664899e0b988 479
uci1 0:664899e0b988 480 //
uci1 0:664899e0b988 481 // readout functions
uci1 0:664899e0b988 482 //
uci1 0:664899e0b988 483 void WaitTrigAndSendClock() {
uci1 1:e392595b4b76 484
uci1 1:e392595b4b76 485 printf("WaitTrigAndSendClock\r\n");
uci1 6:6f002d202f59 486 printf("wait trig: (pw %hhu): cards %d, amps %d, irid %d, afar %d\r\n",
uci1 6:6f002d202f59 487 gConf.GetPowerMode(), PIN_turn_on_system.read(), PIN_turn_on_amps.read(),
uci1 6:6f002d202f59 488 PIN_iridSbd_power.read(), PIN_afar_power.read());
uci1 6:6f002d202f59 489
uci1 0:664899e0b988 490 if (gFirstEvt==false) {
uci1 0:664899e0b988 491 PIN_DoNotRestartAllClocks = 0;
uci1 0:664899e0b988 492 wait_us(1);
uci1 0:664899e0b988 493 PIN_DoNotRestartAllClocks = 1;
uci1 0:664899e0b988 494 //led3 = !led3; // toggle send clock led
uci1 0:664899e0b988 495 } else {
uci1 0:664899e0b988 496 gFirstEvt = false;
uci1 0:664899e0b988 497 }
uci1 0:664899e0b988 498
uci1 0:664899e0b988 499 //
uci1 0:664899e0b988 500 // wait for a trigger here.
uci1 0:664899e0b988 501 //
uci1 0:664899e0b988 502 gReadingOut = false; // this will allow forced triggers (see procForceTrigger())
uci1 0:664899e0b988 503 while ( PIN_a_sf_clk == 1 ) {
uci1 0:664899e0b988 504 if (gOpenCommWin) {
uci1 1:e392595b4b76 505 return; // break out to open comms
uci1 0:664899e0b988 506 }
uci1 0:664899e0b988 507 }
uci1 0:664899e0b988 508 PIN_forceTrigger=0; // necessary for forced triggers, harmless for other triggers
uci1 0:664899e0b988 509 gReadingOut = true; // disallow new forced triggers
uci1 0:664899e0b988 510 //
uci1 0:664899e0b988 511 // collect data from daughter cards
uci1 0:664899e0b988 512 //
uci1 0:664899e0b988 513 // TODO: what if some card (set of channels) doesn't respond?
uci1 0:664899e0b988 514 // currently, will wait forever?
uci1 0:664899e0b988 515 // also, if ch1 is dead, will wait forever (due to FPGA code)
uci1 0:664899e0b988 516 for( uint8_t i = 0; i < kNsamps; i++ ) {
uci1 0:664899e0b988 517 if( PIN_a_sf_clk == 1 ) {
uci1 0:664899e0b988 518 if( i == 0 )
uci1 0:664899e0b988 519 wait_us( 1 );
uci1 0:664899e0b988 520
uci1 0:664899e0b988 521 PIN_ADC_CS = 0;
uci1 0:664899e0b988 522 PIN_spi.write( 0x00 );
uci1 0:664899e0b988 523 PIN_ADC_CS = 1;
uci1 0:664899e0b988 524 } else {
uci1 0:664899e0b988 525 i--;
uci1 0:664899e0b988 526 }
uci1 0:664899e0b988 527 }
uci1 0:664899e0b988 528 }
uci1 0:664899e0b988 529
uci1 0:664899e0b988 530 SnCommWin::ECommWinResult OpenCommWin() {
uci1 0:664899e0b988 531 // loop through each comm mode:
uci1 0:664899e0b988 532 // a) try to connect
uci1 0:664899e0b988 533 // b) if connected, listen for config
uci1 0:664899e0b988 534 // c) if config requests data, send it
uci1 3:24c5f0f50bf1 535
uci1 3:24c5f0f50bf1 536 gLastCommWin = time(0);
uci1 3:24c5f0f50bf1 537 if (gConf.GetCommWinDuration()==0) {
uci1 3:24c5f0f50bf1 538 // TODO: set min so this is not possible
uci1 3:24c5f0f50bf1 539 return SnCommWin::kOkNoMsg;
uci1 3:24c5f0f50bf1 540 }
uci1 0:664899e0b988 541
uci1 0:664899e0b988 542 gCommWinOpen = true;
uci1 0:664899e0b988 543 Watchdog::kick(); // don't reset!
uci1 0:664899e0b988 544
uci1 3:24c5f0f50bf1 545 printf("opening comm window at %d\r\n", (int32_t)gLastCommWin);
uci1 3:24c5f0f50bf1 546
uci1 3:24c5f0f50bf1 547 // close the file so that the data is all written out.
uci1 3:24c5f0f50bf1 548 // and open it back up at the beginning (for reading)
uci1 3:24c5f0f50bf1 549 SnSDUtils::CloseOutputFile(SnSDUtils::GetCurFile());
uci1 3:24c5f0f50bf1 550 SnSDUtils::OpenExistingFile(SnSDUtils::GetCurFileName(), true);
uci1 0:664899e0b988 551
uci1 4:a91682e19d6b 552 // (probably) power down cards,amps and power up comms
uci1 4:a91682e19d6b 553 SetPower(true);
uci1 0:664899e0b988 554
uci1 0:664899e0b988 555 const uint32_t conto = (gConf.GetCommWinDuration() < kConnectTimeout) ?
uci1 0:664899e0b988 556 gConf.GetCommWinDuration() : kConnectTimeout;
uci1 0:664899e0b988 557 const uint32_t listo = (gConf.GetCommWinDuration() < kListenTimeout) ?
uci1 0:664899e0b988 558 gConf.GetCommWinDuration() : kListenTimeout;
uci1 0:664899e0b988 559
uci1 0:664899e0b988 560 SnCommWin::ECommWinResult res = SnCommWin::kUndefFail;
uci1 0:664899e0b988 561
uci1 1:e392595b4b76 562 bool gotNewConfig=false;
uci1 1:e392595b4b76 563 bool sendStat[kNcomms];
uci1 1:e392595b4b76 564 for (uint8_t i=0; i<kNcomms; i++) {
uci1 1:e392595b4b76 565 sendStat[i]=true;
uci1 1:e392595b4b76 566 }
uci1 1:e392595b4b76 567 bool* ss = sendStat;
uci1 0:664899e0b988 568 SnCommWin** cw = gComms;
uci1 1:e392595b4b76 569 for (uint8_t i=0; ((time(0)-gLastCommWin)<gConf.GetCommWinDuration()); i++, cw++, ss++) {
uci1 1:e392595b4b76 570 Watchdog::kick(); // don't reset!
uci1 1:e392595b4b76 571 if (i==kNcomms) {
uci1 1:e392595b4b76 572 i=0;
uci1 1:e392595b4b76 573 cw = gComms;
uci1 1:e392595b4b76 574 ss = sendStat;
uci1 1:e392595b4b76 575 }
uci1 7:079617408fec 576 if ((*cw)==0) {
uci1 7:079617408fec 577 continue;
uci1 7:079617408fec 578 }
uci1 0:664899e0b988 579 // open window and (mabye) send status update
uci1 1:e392595b4b76 580 printf("calling OpenWindow. ss=%d\r\n",(int)(*ss));
uci1 1:e392595b4b76 581 printf("gtt=%u, ct=%d, lcw=%d, dur=%u\r\n",GetTimeoutTime(gLastCommWin,conto),
uci1 1:e392595b4b76 582 time(0), gLastCommWin, gConf.GetCommWinDuration());
uci1 0:664899e0b988 583 const SnCommWin::ECommWinResult conres = (*cw)->OpenWindow(
uci1 2:e67f7c158087 584 GetTimeoutTime(gLastCommWin, conto), *ss, gConf, gEvent, gGenBuf);
uci1 0:664899e0b988 585 if (conres>=SnCommWin::kConnected) {
uci1 1:e392595b4b76 586 Watchdog::kick(); // don't reset!
uci1 0:664899e0b988 587 // connected. listen for config
uci1 1:e392595b4b76 588 *ss = false; // don't send status next time
uci1 0:664899e0b988 589 const SnCommWin::ECommWinResult cfgres = (*cw)->GetConfig(
uci1 3:24c5f0f50bf1 590 gConf, GetTimeoutTime(gLastCommWin, listo), gGenBuf, gBufSize);
uci1 0:664899e0b988 591 if (cfgres>=SnCommWin::kOkWithMsg) {
uci1 1:e392595b4b76 592 Watchdog::kick(); // don't reset!
uci1 3:24c5f0f50bf1 593 printf("received config (%u)!\r\n",gConf.SizeOf());
uci1 1:e392595b4b76 594 char* b = gGenBuf;
uci1 1:e392595b4b76 595 gConf.WriteTo(b);
uci1 3:24c5f0f50bf1 596 const uint32_t csz = gConf.SizeOf();
uci1 3:24c5f0f50bf1 597 for (uint32_t i=0; i<csz; i++) {
uci1 1:e392595b4b76 598 printf("%02x ",gGenBuf[i]);
uci1 1:e392595b4b76 599 }
uci1 1:e392595b4b76 600 printf("\r\n");
uci1 0:664899e0b988 601 // send data if need be (files, some events, etc)
uci1 3:24c5f0f50bf1 602 printf("send data = %d\r\n", gConf.GetCommSendData());
uci1 0:664899e0b988 603 if (gConf.GetCommSendData()!=0) {
uci1 3:24c5f0f50bf1 604 printf("sending data\r\n");
uci1 3:24c5f0f50bf1 605 res = (*cw)->SendData(gConf, gEvent, gGenBuf, gBufSize,
uci1 1:e392595b4b76 606 GetTimeoutTime(gLastCommWin, gConf.GetCommWinDuration()));
uci1 0:664899e0b988 607 } else {
uci1 0:664899e0b988 608 // don't send anything
uci1 0:664899e0b988 609 res = cfgres;
uci1 0:664899e0b988 610 }
uci1 1:e392595b4b76 611 printf("Got config!\r\n");
uci1 1:e392595b4b76 612 gotNewConfig=true;
uci1 1:e392595b4b76 613 Watchdog::kick(); // don't reset!
uci1 0:664899e0b988 614 break;
uci1 0:664899e0b988 615 }
uci1 0:664899e0b988 616 }
uci1 0:664899e0b988 617
uci1 0:664899e0b988 618 Watchdog::kick(); // don't reset!
uci1 0:664899e0b988 619
uci1 0:664899e0b988 620 }
uci1 0:664899e0b988 621
uci1 4:a91682e19d6b 622 // (probably) power down comms and power up cards,amps
uci1 4:a91682e19d6b 623 SetPower(false);
uci1 4:a91682e19d6b 624
uci1 1:e392595b4b76 625 gFirstEvt = true;
uci1 4:a91682e19d6b 626
uci1 1:e392595b4b76 627 // reset config with system powered (for DAC/PLA setting)
uci1 1:e392595b4b76 628 if (gotNewConfig) {
uci1 1:e392595b4b76 629 printf("calling SetConfigAndMakeOutputFile\r\n");
uci1 1:e392595b4b76 630 SetConfigAndMakeOutputFile();
uci1 1:e392595b4b76 631 // TODO: remove
uci1 1:e392595b4b76 632 }
uci1 1:e392595b4b76 633 printf("closing comm win at %d\r\n",(int32_t)time(0));
uci1 1:e392595b4b76 634
uci1 0:664899e0b988 635 gCommWinOpen = false;
uci1 0:664899e0b988 636 return res;
uci1 0:664899e0b988 637 }