Arianna autonomous DAQ firmware

Dependencies:   mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW

Committer:
uci1
Date:
Tue Jul 24 02:07:23 2012 +0000
Revision:
2:e67f7c158087
Parent:
1:e392595b4b76
Child:
3:24c5f0f50bf1
added header to i/o. still lots of debugging prints.

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