Arianna autonomous DAQ firmware
Dependencies: mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW
main.cpp@125:ce4045184366, 2019-06-05 (annotated)
- Committer:
- uci1
- Date:
- Wed Jun 05 17:29:31 2019 +0000
- Revision:
- 125:ce4045184366
- Parent:
- 123:6267de54c8ba
Added SnRateListner proto-class, publishing this version of the code in order to enable exporting of most recent features.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
uci1 | 0:664899e0b988 | 1 | #include "mbed.h" |
uci1 | 56:0bba0ef15697 | 2 | |
uci1 | 56:0bba0ef15697 | 3 | const uint32_t gPowerOnTime( time(0) ); |
uci1 | 56:0bba0ef15697 | 4 | |
uci1 | 22:f957c4f840ad | 5 | // start a watchdog as soon as possible |
uci1 | 22:f957c4f840ad | 6 | #include "Watchdog.h" |
uci1 | 22:f957c4f840ad | 7 | Watchdog::SnKickStarter gKickStarter(WDFAILSAFE); |
uci1 | 0:664899e0b988 | 8 | |
uci1 | 84:80b15993944e | 9 | // CHIPBOARD is defined in SnPreCompOptions.h |
uci1 | 56:0bba0ef15697 | 10 | |
uci1 | 0:664899e0b988 | 11 | #include <stdint.h> |
uci1 | 37:ff95e7070f26 | 12 | #include "SnConstants.h" |
uci1 | 37:ff95e7070f26 | 13 | |
uci1 | 67:ec999336fcd1 | 14 | #ifndef USE_INTERFACE_CHIP |
uci1 | 116:8099b754fbb4 | 15 | #include "SnUIDtoMac.h" |
uci1 | 67:ec999336fcd1 | 16 | extern "C" void mbed_mac_address(char * mac) { |
uci1 | 67:ec999336fcd1 | 17 | #ifdef DEBUG |
uci1 | 67:ec999336fcd1 | 18 | printf("calling MY mbed_mac_address\r\n"); |
uci1 | 67:ec999336fcd1 | 19 | #endif |
uci1 | 116:8099b754fbb4 | 20 | // to avoid calling the interface chip, the mac address may be hard coded (ugh!) |
uci1 | 116:8099b754fbb4 | 21 | |
uci1 | 116:8099b754fbb4 | 22 | // even though SnConfigFrame will cache the mac address, |
uci1 | 116:8099b754fbb4 | 23 | // it appears some low level code (in Ethernet?) calls this |
uci1 | 116:8099b754fbb4 | 24 | // function. altho searching the code for mbed_mac_address doesn't |
uci1 | 116:8099b754fbb4 | 25 | // find it, this function still gets called. |
uci1 | 116:8099b754fbb4 | 26 | // so -- cache the result and return it. |
uci1 | 116:8099b754fbb4 | 27 | static char cachedMac[sizeof(uint64_t)]; |
uci1 | 116:8099b754fbb4 | 28 | static bool cached = false; |
uci1 | 116:8099b754fbb4 | 29 | if (cached) { |
uci1 | 116:8099b754fbb4 | 30 | memmove(mac, cachedMac, sizeof(uint64_t)); |
uci1 | 116:8099b754fbb4 | 31 | #ifdef DEBUG |
uci1 | 116:8099b754fbb4 | 32 | printf("using cached mac=%02X%02X%02X%02X%02X%02X\r\n", |
uci1 | 116:8099b754fbb4 | 33 | mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]); |
uci1 | 116:8099b754fbb4 | 34 | #endif |
uci1 | 116:8099b754fbb4 | 35 | } else { |
uci1 | 116:8099b754fbb4 | 36 | SnUIDtoMac::GetMacAddress(mac); |
uci1 | 116:8099b754fbb4 | 37 | memmove(cachedMac, mac, sizeof(uint64_t)); |
uci1 | 116:8099b754fbb4 | 38 | cached = true; |
uci1 | 116:8099b754fbb4 | 39 | #ifdef DEBUG |
uci1 | 116:8099b754fbb4 | 40 | printf("got new mac mac=%02X%02X%02X%02X%02X%02X\r\n", |
uci1 | 116:8099b754fbb4 | 41 | mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]); |
uci1 | 116:8099b754fbb4 | 42 | #endif |
uci1 | 116:8099b754fbb4 | 43 | } |
uci1 | 67:ec999336fcd1 | 44 | }; |
uci1 | 116:8099b754fbb4 | 45 | #endif // USE_INTERFACE_CHIP |
uci1 | 67:ec999336fcd1 | 46 | |
uci1 | 84:80b15993944e | 47 | #ifdef DEBUG |
uci1 | 84:80b15993944e | 48 | #include "SnMemMonitor.h" |
uci1 | 84:80b15993944e | 49 | #endif |
uci1 | 84:80b15993944e | 50 | |
uci1 | 0:664899e0b988 | 51 | #include "SDFileSystem.h" |
uci1 | 15:f2569d8e4176 | 52 | #ifdef USE_MODSERIAL |
uci1 | 119:b3d7699d0eb0 | 53 | #define MODSERIAL_RX_BUF_SIZE 512//Geoffs512 |
uci1 | 119:b3d7699d0eb0 | 54 | #define MODSERIAL_TX_BUF_SIZE 512//Geoffs512 |
uci1 | 0:664899e0b988 | 55 | #include "MODSERIAL.h" |
uci1 | 56:0bba0ef15697 | 56 | #endif // USE_MODSERIAL |
uci1 | 21:ce51bb0ba4a5 | 57 | #include "FATDirHandle.h" |
uci1 | 21:ce51bb0ba4a5 | 58 | #include "EthernetPowerControl.h" |
uci1 | 0:664899e0b988 | 59 | #include "SnBitUtils.h" |
uci1 | 0:664899e0b988 | 60 | #include "SnSDUtils.h" |
uci1 | 0:664899e0b988 | 61 | #include "SnConfigFrame.h" |
uci1 | 0:664899e0b988 | 62 | #include "SnEventFrame.h" |
uci1 | 0:664899e0b988 | 63 | #include "SnStatusFrame.h" |
uci1 | 2:e67f7c158087 | 64 | #include "SnHeaderFrame.h" |
uci1 | 22:f957c4f840ad | 65 | #include "SnHeartbeatFrame.h" |
uci1 | 40:1324da35afd4 | 66 | #include "SnClockSetFrame.h" |
uci1 | 41:d6f5e2f09e07 | 67 | #include "SnSignalStrengthFrame.h" |
uci1 | 0:664899e0b988 | 68 | #include "SnCommWin.h" |
uci1 | 41:d6f5e2f09e07 | 69 | #ifdef ENABLE_AFAR_COMM |
uci1 | 18:55f1581f2ee4 | 70 | #ifdef USE_ETH_INTERFACE |
uci1 | 7:079617408fec | 71 | #include "SnCommAfarTCP.h" |
uci1 | 18:55f1581f2ee4 | 72 | #else |
uci1 | 37:ff95e7070f26 | 73 | #include "SnCommWinAfar.h" |
uci1 | 28:484943132bb0 | 74 | #ifdef ENABLE_AFAR_TWITTER |
uci1 | 37:ff95e7070f26 | 75 | #include "SnCommWinTwitter.h" |
uci1 | 41:d6f5e2f09e07 | 76 | #endif // ENABLE_AFAR_TWITTER |
uci1 | 41:d6f5e2f09e07 | 77 | #endif // USE_ETH_INTERFACE |
uci1 | 41:d6f5e2f09e07 | 78 | #endif // ENABLE_AFAR_COMM |
uci1 | 41:d6f5e2f09e07 | 79 | #ifdef ENABLE_USB_COMM |
uci1 | 41:d6f5e2f09e07 | 80 | #include "SnCommWinUsb.h" |
uci1 | 56:0bba0ef15697 | 81 | #endif // ENABLE_USB_COMM |
uci1 | 41:d6f5e2f09e07 | 82 | #ifdef ENABLE_SBD_COMM |
uci1 | 37:ff95e7070f26 | 83 | #include "SnCommWinSBD.h" |
uci1 | 56:0bba0ef15697 | 84 | #endif // ENABLE_SBD_COMM |
uci1 | 41:d6f5e2f09e07 | 85 | //#include "SnBase64.h" |
uci1 | 8:95a325df1f6b | 86 | #ifdef USE_RTOS_TIMER |
uci1 | 8:95a325df1f6b | 87 | #include "RtosTimer.h" |
uci1 | 56:0bba0ef15697 | 88 | #endif // USE_RTOS_TIMER |
uci1 | 56:0bba0ef15697 | 89 | #include "DS1820.h" |
uci1 | 84:80b15993944e | 90 | #include "SnL1SingleFreqSupp.h" |
uci1 | 0:664899e0b988 | 91 | |
uci1 | 40:1324da35afd4 | 92 | extern "C" void mbed_reset(); |
uci1 | 31:b5bd3b189150 | 93 | |
uci1 | 0:664899e0b988 | 94 | // |
uci1 | 0:664899e0b988 | 95 | // MBED PINS (ordered by number) |
uci1 | 0:664899e0b988 | 96 | // |
uci1 | 0:664899e0b988 | 97 | // leds (for debugging) |
uci1 | 67:ec999336fcd1 | 98 | DigitalOut led1(LED1,1); |
uci1 | 67:ec999336fcd1 | 99 | DigitalOut led2(LED2,1); |
uci1 | 67:ec999336fcd1 | 100 | DigitalOut led3(LED3,1); |
uci1 | 67:ec999336fcd1 | 101 | DigitalOut led4(LED4,1); |
uci1 | 56:0bba0ef15697 | 102 | |
uci1 | 116:8099b754fbb4 | 103 | #ifndef CHIPBOARD |
uci1 | 116:8099b754fbb4 | 104 | #error CHIPBOARD is not defined! Define it in SnPreCompOptions.h |
uci1 | 116:8099b754fbb4 | 105 | #endif |
uci1 | 116:8099b754fbb4 | 106 | |
uci1 | 56:0bba0ef15697 | 107 | // Set up power pins - Note that it's Zero for "on" in ATWD2013, but high for "on" in SST2014 |
uci1 | 56:0bba0ef15697 | 108 | #if CHIPBOARD==ATWD4CH |
uci1 | 56:0bba0ef15697 | 109 | DigitalOut PIN_turn_on_system(p17,1); // this turns off the system |
uci1 | 56:0bba0ef15697 | 110 | DigitalOut PIN_turn_on_amps(p25,1); // this turns off the amps |
uci1 | 56:0bba0ef15697 | 111 | #else |
uci1 | 56:0bba0ef15697 | 112 | DigitalOut PIN_turn_on_system(p17,0); // this turns off the system |
uci1 | 56:0bba0ef15697 | 113 | DigitalOut PIN_turn_on_amps(p25,0); // this turns off the amps |
uci1 | 56:0bba0ef15697 | 114 | #endif // ATWD4CH |
uci1 | 15:f2569d8e4176 | 115 | // SD card select |
uci1 | 56:0bba0ef15697 | 116 | DigitalOut PIN_SD_CS(p8,0); |
uci1 | 56:0bba0ef15697 | 117 | #if CHIPBOARD==ATWD4CH |
uci1 | 0:664899e0b988 | 118 | // Activate/select chip by falling edge |
uci1 | 56:0bba0ef15697 | 119 | DigitalOut PIN_ADC_CS(p9,0); |
uci1 | 0:664899e0b988 | 120 | // clock signal to activate PLA setting |
uci1 | 56:0bba0ef15697 | 121 | DigitalOut PIN_PLA_cs(p10,0); |
uci1 | 56:0bba0ef15697 | 122 | #else |
uci1 | 56:0bba0ef15697 | 123 | I2C PIN_i2c(p9, p10); |
uci1 | 56:0bba0ef15697 | 124 | #endif // ATWD4CH |
uci1 | 0:664899e0b988 | 125 | // To force a trigger |
uci1 | 56:0bba0ef15697 | 126 | DigitalOut PIN_forceTrigger(p11,0); //modification |
uci1 | 0:664899e0b988 | 127 | // To suppress thermal triggers |
uci1 | 56:0bba0ef15697 | 128 | DigitalOut PIN_enableThermTrig(p12,0); |
uci1 | 56:0bba0ef15697 | 129 | #if CHIPBOARD==ATWD4CH |
uci1 | 0:664899e0b988 | 130 | // Restart clock on all FPGAs. |
uci1 | 56:0bba0ef15697 | 131 | DigitalOut PIN_DoNotRestartAllClocks(p13,0); |
uci1 | 56:0bba0ef15697 | 132 | #else |
uci1 | 56:0bba0ef15697 | 133 | DigitalOut PIN_ResetChips(p13,0); |
uci1 | 56:0bba0ef15697 | 134 | #endif // ATWD4CH |
uci1 | 56:0bba0ef15697 | 135 | #if CHIPBOARD==ATWD4CH |
uci1 | 0:664899e0b988 | 136 | // This tells the DFPGAs to store the data on motherboard FPGA and |
uci1 | 0:664899e0b988 | 137 | // read it out. |
uci1 | 56:0bba0ef15697 | 138 | DigitalIn PIN_a_sf_clk(p14); |
uci1 | 0:664899e0b988 | 139 | DigitalIn PIN_rst_a_sf(p15); |
uci1 | 56:0bba0ef15697 | 140 | #else |
uci1 | 56:0bba0ef15697 | 141 | DigitalIn PIN_dataReady(p14); // when triggered data is stored in the mb FPGA and ready for readout by mbed |
uci1 | 56:0bba0ef15697 | 142 | #endif // ATWD4CH |
uci1 | 1:e392595b4b76 | 143 | // afar power |
uci1 | 56:0bba0ef15697 | 144 | DigitalOut PIN_afar_power(p16,0); |
uci1 | 4:a91682e19d6b | 145 | // batter voltage/current measurement |
uci1 | 4:a91682e19d6b | 146 | AnalogIn PIN_vADC1(p19); |
uci1 | 4:a91682e19d6b | 147 | AnalogIn PIN_vADC2(p18); |
uci1 | 56:0bba0ef15697 | 148 | #if CHIPBOARD==ATWD4CH |
uci1 | 0:664899e0b988 | 149 | // Lock daughter card registeres (during data readout). |
uci1 | 56:0bba0ef15697 | 150 | DigitalOut PIN_lockRegisters(p20,0); |
uci1 | 56:0bba0ef15697 | 151 | #else |
uci1 | 56:0bba0ef15697 | 152 | DigitalOut PIN_readingData(p20,0); |
uci1 | 56:0bba0ef15697 | 153 | #endif // ATWD4CH |
uci1 | 1:e392595b4b76 | 154 | // iridium (SBD) power |
uci1 | 56:0bba0ef15697 | 155 | DigitalOut PIN_iridSbd_power(p21,0); |
uci1 | 0:664899e0b988 | 156 | // Majority logic pins |
uci1 | 56:0bba0ef15697 | 157 | DigitalOut PIN_MajLogHiBit(p22,0); |
uci1 | 56:0bba0ef15697 | 158 | DigitalOut PIN_MajLogLoBit(p23,0); |
uci1 | 56:0bba0ef15697 | 159 | // To launch a heartbeat pulse |
uci1 | 56:0bba0ef15697 | 160 | DigitalOut PIN_heartbeat(p24,0); |
uci1 | 56:0bba0ef15697 | 161 | #if CHIPBOARD==ATWD4CH |
uci1 | 0:664899e0b988 | 162 | // Tell FPGA to be ready to accept DAC values |
uci1 | 56:0bba0ef15697 | 163 | DigitalOut PIN_start_fpga(p26,0); |
uci1 | 56:0bba0ef15697 | 164 | #else |
uci1 | 56:0bba0ef15697 | 165 | DigitalIn PIN_unused26(p26); |
uci1 | 56:0bba0ef15697 | 166 | #endif // ATWD4CH |
uci1 | 56:0bba0ef15697 | 167 | #if CHIPBOARD==ATWD4CH |
uci1 | 0:664899e0b988 | 168 | // Two bits to the select the daughter card for readout |
uci1 | 56:0bba0ef15697 | 169 | DigitalOut PIN_selCardHiBit(p29,0); |
uci1 | 56:0bba0ef15697 | 170 | DigitalOut PIN_selCardLoBit(p30,0); |
uci1 | 56:0bba0ef15697 | 171 | #else |
uci1 | 56:0bba0ef15697 | 172 | DigitalOut PIN_dualOrSingleThresholds(p29, 1); // 1 = dual (hi AND lo thresh crossings) |
uci1 | 56:0bba0ef15697 | 173 | DigitalOut PIN_differentialTrigSignal(p30, 1); // 1 = chip sends one trigger signal per channel with reduced noise, 0 = chip sends each comparator signal separately |
uci1 | 56:0bba0ef15697 | 174 | #endif // ATWD4CH |
uci1 | 0:664899e0b988 | 175 | // Setup SPI pins |
uci1 | 0:664899e0b988 | 176 | SPI PIN_spi( p5, p6, p7 ); |
uci1 | 3:24c5f0f50bf1 | 177 | |
uci1 | 114:554fa3a956b4 | 178 | #if CHIPBOARD!=ATWD4CH |
uci1 | 56:0bba0ef15697 | 179 | PinName gThermPinName(p15); |
uci1 | 56:0bba0ef15697 | 180 | DS1820 PIN_therm(gThermPinName, gThermPinName, false); // be default, on external power |
uci1 | 56:0bba0ef15697 | 181 | #endif |
uci1 | 41:d6f5e2f09e07 | 182 | |
uci1 | 41:d6f5e2f09e07 | 183 | // we have to do this shit because Serial and MODSERIAL don't have virtual functions |
uci1 | 41:d6f5e2f09e07 | 184 | // so calling, e.g. readable from a Serial* will call Serial::readable instead of MODSERIAL::readable |
uci1 | 41:d6f5e2f09e07 | 185 | // and the comms will wait forever |
uci1 | 15:f2569d8e4176 | 186 | #ifdef USE_MODSERIAL |
uci1 | 41:d6f5e2f09e07 | 187 | #define MAIN_SERIALTYPE AjK::MODSERIAL |
uci1 | 15:f2569d8e4176 | 188 | #else |
uci1 | 41:d6f5e2f09e07 | 189 | #define MAIN_SERIALTYPE Serial |
uci1 | 56:0bba0ef15697 | 190 | #endif // USE_MODSERIAL |
uci1 | 41:d6f5e2f09e07 | 191 | |
uci1 | 116:8099b754fbb4 | 192 | //#if defined(DEBUG) || defined(ENABLE_USB_COMM) || defined(EVT_TIME_PROFILE) |
uci1 | 41:d6f5e2f09e07 | 193 | // this needs to be first in case some other global uses a print statement |
uci1 | 41:d6f5e2f09e07 | 194 | static MAIN_SERIALTYPE gCpu( USBTX, USBRX ); // defined here so it might be used for debugging output |
uci1 | 116:8099b754fbb4 | 195 | //#endif // DEBUG or ENABLE_USB_COMM |
uci1 | 41:d6f5e2f09e07 | 196 | |
uci1 | 41:d6f5e2f09e07 | 197 | static MAIN_SERIALTYPE gSBDport(p28, p27, |
uci1 | 16:744ce85aede2 | 198 | #ifdef USE_MODSERIAL |
uci1 | 41:d6f5e2f09e07 | 199 | MODSERIAL_TX_BUF_SIZE, MODSERIAL_RX_BUF_SIZE, |
uci1 | 56:0bba0ef15697 | 200 | #endif // USE_MODSERIAL |
uci1 | 41:d6f5e2f09e07 | 201 | "sbd"); |
uci1 | 41:d6f5e2f09e07 | 202 | |
uci1 | 56:0bba0ef15697 | 203 | // The SD card |
uci1 | 21:ce51bb0ba4a5 | 204 | static SDFileSystem sd(p5, p6, p7, p8, SnSDUtils::kSDdir+1); // no leading '/' |
uci1 | 67:ec999336fcd1 | 205 | |
uci1 | 67:ec999336fcd1 | 206 | // local file system is still created even if USE_INTERFACE_CHIP is not defined |
uci1 | 67:ec999336fcd1 | 207 | // this is done to allow the mbed to be reprogrammed remotely |
uci1 | 25:57b2627fe756 | 208 | static LocalFileSystem local((SnCommWin::kLocalDir)+1); // no leading '/' |
uci1 | 0:664899e0b988 | 209 | |
uci1 | 0:664899e0b988 | 210 | // |
uci1 | 0:664899e0b988 | 211 | // fwd declare fcns |
uci1 | 0:664899e0b988 | 212 | // |
uci1 | 0:664899e0b988 | 213 | void ReadAllRegisters(); |
uci1 | 0:664899e0b988 | 214 | void ReadRegister(const uint8_t chan, int16_t* dev); |
uci1 | 22:f957c4f840ad | 215 | void SaveHeartbeat(); |
uci1 | 116:8099b754fbb4 | 216 | bool SaveEvent(const int32_t etms); |
uci1 | 0:664899e0b988 | 217 | void WaitTrigAndSendClock(); |
uci1 | 1:e392595b4b76 | 218 | void SetConfigAndMakeOutputFile(); |
uci1 | 122:c1b5023eac69 | 219 | SnCommWin::ECommWinResult OpenCommWin(const bool isStartupWin=false); |
uci1 | 3:24c5f0f50bf1 | 220 | void MakeOutputFile(const bool stopRunning=false); |
uci1 | 84:80b15993944e | 221 | bool IsPowerAllowedFor(const bool isCommWin, |
uci1 | 84:80b15993944e | 222 | const uint8_t devicesInUse, |
uci1 | 84:80b15993944e | 223 | const SnConfigFrame::EDatPackBit b); |
uci1 | 84:80b15993944e | 224 | void SetPower(const bool isCommWin, |
uci1 | 84:80b15993944e | 225 | const uint8_t devicesInUse); |
uci1 | 84:80b15993944e | 226 | void CheckPower(const bool isCommWin, |
uci1 | 84:80b15993944e | 227 | const bool saveReading=true, |
uci1 | 84:80b15993944e | 228 | const uint8_t devicesInUse= |
uci1 | 84:80b15993944e | 229 | SnConfigFrame::kIrid | |
uci1 | 84:80b15993944e | 230 | SnConfigFrame::kAfar); |
uci1 | 84:80b15993944e | 231 | void CheckTemp(); |
uci1 | 84:80b15993944e | 232 | void UpdateTemperature(); |
uci1 | 84:80b15993944e | 233 | bool AreCardsPowered(const bool checkPin); |
uci1 | 84:80b15993944e | 234 | void GetAvePowerReading(); |
uci1 | 114:554fa3a956b4 | 235 | #if CHIPBOARD!=ATWD4CH |
uci1 | 84:80b15993944e | 236 | void InitTempProbe(); |
uci1 | 84:80b15993944e | 237 | #endif |
uci1 | 84:80b15993944e | 238 | void ResetCountersClearEvt(); |
uci1 | 116:8099b754fbb4 | 239 | /* |
uci1 | 84:80b15993944e | 240 | void CalcRate(const uint32_t numtrgs, |
uci1 | 84:80b15993944e | 241 | const double tottime_ms, |
uci1 | 84:80b15993944e | 242 | float& rate); |
uci1 | 84:80b15993944e | 243 | void GetRates(float& thmrate, float& evtrate); |
uci1 | 116:8099b754fbb4 | 244 | void AddToRate(const double dt, const bool isThm, |
uci1 | 116:8099b754fbb4 | 245 | const uint32_t nev=1u); |
uci1 | 116:8099b754fbb4 | 246 | */ |
uci1 | 84:80b15993944e | 247 | bool IsSeqComplete(); |
uci1 | 116:8099b754fbb4 | 248 | void PrepForSeqClose(); |
uci1 | 116:8099b754fbb4 | 249 | void PrepForNewSeq(double& etms); |
uci1 | 116:8099b754fbb4 | 250 | float GetSeqLivetime(); |
uci1 | 8:95a325df1f6b | 251 | void procForceTrigger(); |
uci1 | 8:95a325df1f6b | 252 | void procHeartbeat(); |
uci1 | 8:95a325df1f6b | 253 | void procPowerCheck(); |
uci1 | 56:0bba0ef15697 | 254 | void procTempCheck(); |
uci1 | 8:95a325df1f6b | 255 | void procCommWin(); |
uci1 | 40:1324da35afd4 | 256 | #ifdef USE_RTOS |
uci1 | 8:95a325df1f6b | 257 | void procForceTrigger(void const *) { return procForceTrigger(); } |
uci1 | 8:95a325df1f6b | 258 | void procHeartbeat(void const *) { return procHeartbeat(); } |
uci1 | 8:95a325df1f6b | 259 | void procPowerCheck(void const *) { return procPowerCheck(); } |
uci1 | 8:95a325df1f6b | 260 | void procCommWin(void const *) { return procCommWin(); } |
uci1 | 56:0bba0ef15697 | 261 | void procTempCheck(void const *) { return procTempCheck(); } |
uci1 | 56:0bba0ef15697 | 262 | #endif // USE_RTOS |
uci1 | 0:664899e0b988 | 263 | |
uci1 | 119:b3d7699d0eb0 | 264 | #if CHIPBOARD==ATWD4CH |
uci1 | 119:b3d7699d0eb0 | 265 | void SetAtwdPlas(); |
uci1 | 119:b3d7699d0eb0 | 266 | void SetAtwdDACs(); |
uci1 | 119:b3d7699d0eb0 | 267 | #else |
uci1 | 119:b3d7699d0eb0 | 268 | void SetSstDACs(); |
uci1 | 119:b3d7699d0eb0 | 269 | #endif |
uci1 | 119:b3d7699d0eb0 | 270 | |
uci1 | 0:664899e0b988 | 271 | // |
uci1 | 0:664899e0b988 | 272 | // globals |
uci1 | 0:664899e0b988 | 273 | // |
uci1 | 0:664899e0b988 | 274 | // readout objs |
uci1 | 8:95a325df1f6b | 275 | // TODO: use RtosTimer instead of Ticker? |
uci1 | 40:1324da35afd4 | 276 | #ifdef USE_RTOS |
uci1 | 8:95a325df1f6b | 277 | static rtos::RtosTimer* gForceTicker; |
uci1 | 8:95a325df1f6b | 278 | static rtos::RtosTimer* gHeartbeatTicker; |
uci1 | 8:95a325df1f6b | 279 | static rtos::RtosTimer* gCommWinTicker; |
uci1 | 8:95a325df1f6b | 280 | static rtos::RtosTimer* gPowerCheckTicker; |
uci1 | 56:0bba0ef15697 | 281 | static rtos::RtosTimer* gTempCheckTicker; |
uci1 | 8:95a325df1f6b | 282 | #else |
uci1 | 0:664899e0b988 | 283 | static Ticker gForceTicker; |
uci1 | 3:24c5f0f50bf1 | 284 | static Ticker gHeartbeatTicker; |
uci1 | 1:e392595b4b76 | 285 | static Ticker gCommWinTicker; |
uci1 | 8:95a325df1f6b | 286 | static Ticker gPowerCheckTicker; |
uci1 | 56:0bba0ef15697 | 287 | static Ticker gTempCheckTicker; |
uci1 | 56:0bba0ef15697 | 288 | #endif // USE_RTOS |
uci1 | 40:1324da35afd4 | 289 | static Timer gAllTrgTimer; |
uci1 | 116:8099b754fbb4 | 290 | static Timer gTrgLiveTimer; // in case the sequence is "short" |
uci1 | 116:8099b754fbb4 | 291 | //static Timer gThmTrgTimer; |
uci1 | 16:744ce85aede2 | 292 | static Timer gAdcToMBtimer; |
uci1 | 67:ec999336fcd1 | 293 | |
uci1 | 116:8099b754fbb4 | 294 | static Timer gSinceClkSet; // this timer can roll over; the offline software accounts for it |
uci1 | 41:d6f5e2f09e07 | 295 | static SnClockSetFrame gClkSet; |
uci1 | 41:d6f5e2f09e07 | 296 | static SnSignalStrengthFrame gSigStr; |
uci1 | 31:b5bd3b189150 | 297 | #ifdef DISABLE_CONFIG_SAFETYNETS |
uci1 | 31:b5bd3b189150 | 298 | static SnConfigFrame gConf(false); |
uci1 | 98:ce72ef143b9b | 299 | static SnConfigFrame gConfCopy(false); |
uci1 | 31:b5bd3b189150 | 300 | #else |
uci1 | 0:664899e0b988 | 301 | static SnConfigFrame gConf; |
uci1 | 98:ce72ef143b9b | 302 | static SnConfigFrame gConfCopy; |
uci1 | 56:0bba0ef15697 | 303 | #endif // DISABLE_CONFIG_SAFETYNETS |
uci1 | 0:664899e0b988 | 304 | static SnEventFrame gEvent; |
uci1 | 84:80b15993944e | 305 | //static SnEventFrame gLastEvent; |
uci1 | 8:95a325df1f6b | 306 | static SnPowerFrame gPower; |
uci1 | 56:0bba0ef15697 | 307 | static SnTempFrame gTemperature; |
uci1 | 0:664899e0b988 | 308 | // parameters |
uci1 | 21:ce51bb0ba4a5 | 309 | static bool gCardsPowered = false; |
uci1 | 0:664899e0b988 | 310 | static bool gFirstEvt = true; |
uci1 | 56:0bba0ef15697 | 311 | static volatile bool gReadingOut = false; // if data is being read from the FPGA |
uci1 | 15:f2569d8e4176 | 312 | static volatile bool gCommWinOpen = false; // if it's open |
uci1 | 1:e392595b4b76 | 313 | static volatile bool gOpenCommWin = false; // if it should be opened |
uci1 | 8:95a325df1f6b | 314 | static volatile bool gCheckPower = false; // if it should be checked |
uci1 | 56:0bba0ef15697 | 315 | static volatile bool gCheckTemp = false; // if it should be checked |
uci1 | 8:95a325df1f6b | 316 | static uint32_t gPowNum = 0; |
uci1 | 8:95a325df1f6b | 317 | static uint32_t gEvtNum = 0; // num of evt written |
uci1 | 84:80b15993944e | 318 | static volatile bool gForcedTrig = false; // forced trigger bit |
uci1 | 84:80b15993944e | 319 | static volatile bool gAdcToMBflag = false; // flag in case getting the ADC values took too long |
uci1 | 84:80b15993944e | 320 | //static uint32_t gTrgNum[kNumTrgs] = {0}; // num of this type of trg received |
uci1 | 84:80b15993944e | 321 | static uint32_t gNumThmTrigs = 0; // number of thermal triggers counted |
uci1 | 84:80b15993944e | 322 | static uint32_t gNumFrcTrigs = 0; // number of forced triggers counted |
uci1 | 116:8099b754fbb4 | 323 | static uint32_t gNumSavedEvts = 0; // number of events saved. differs from gEvtNum as this one always starts at 0, no matter the current sequence number |
uci1 | 84:80b15993944e | 324 | static uint8_t gL1ScaledownCount = 0; // write an event every X L1 failures |
uci1 | 0:664899e0b988 | 325 | // i/o |
uci1 | 21:ce51bb0ba4a5 | 326 | static time_t gLastCommWin = 0; // time |
uci1 | 22:f957c4f840ad | 327 | static uint32_t gCommWinChecks = 0; |
uci1 | 22:f957c4f840ad | 328 | static uint32_t gNcommWinChecks = 0; |
uci1 | 40:1324da35afd4 | 329 | static uint16_t gConsecCommFails = 0; |
uci1 | 22:f957c4f840ad | 330 | // heartbeat |
uci1 | 84:80b15993944e | 331 | static SnHeartbeatFrame gHrtbt; |
uci1 | 22:f957c4f840ad | 332 | static time_t gLastHrtbt = 0; |
uci1 | 23:ccf39298f205 | 333 | static volatile bool gHrtbtFired = false; |
uci1 | 22:f957c4f840ad | 334 | static uint32_t gHrtbtNum = 0; |
uci1 | 22:f957c4f840ad | 335 | // rates |
uci1 | 116:8099b754fbb4 | 336 | //static double gThmDtSum = 0; // sum of all time diffs between thermal trigs |
uci1 | 116:8099b754fbb4 | 337 | //static double gEvtDtSum = 0; // sum of all time diffs between events |
uci1 | 116:8099b754fbb4 | 338 | //static uint32_t gThmNumDt = 0; // number of thermal trig time diffs added up |
uci1 | 116:8099b754fbb4 | 339 | //static uint32_t gEvtNumDt = 0; // number of event time diffs added up |
uci1 | 10:3c93db1cfb12 | 340 | // this should be bigger than anything that will actually be used |
uci1 | 40:1324da35afd4 | 341 | static const uint32_t gBufSize=SnStatusFrame::kMaxSizeOf + (2u*SnHeaderFrame::kMaxSizeOf) + SnPowerFrame::kMaxSizeOf |
uci1 | 116:8099b754fbb4 | 342 | + SnEventFrame::kMaxSizeOf // this is too big, because max status frame already includes an ATWD 4*128samp event (as of status i/o v9) |
uci1 | 116:8099b754fbb4 | 343 | //- SnEventFrame::kMaxSizeOfV1 // so we should be able to do this.. but requires long term testing as of 2016-04-26 |
uci1 | 119:b3d7699d0eb0 | 344 | + 256;//Geoffs+ 256; // some breathing room |
uci1 | 3:24c5f0f50bf1 | 345 | static char gGenBuf[gBufSize]; // must be big enough for event or status or config! |
uci1 | 11:de443350ec4a | 346 | static SnCommWin* gComms[kNcomms] = { 0 }; // order => priority. afar uses RTOS, and must be made inside main |
uci1 | 28:484943132bb0 | 347 | #if defined(ENABLE_AFAR_TWITTER) && defined(ENABLE_AFAR_COMM) |
uci1 | 28:484943132bb0 | 348 | static SnCommAfarNetIfTwitter* gTwit = 0; |
uci1 | 28:484943132bb0 | 349 | #endif |
uci1 | 84:80b15993944e | 350 | static float gChanFFT[kNsamps] = { 0 }; // only one chan at a time to save RAM |
uci1 | 84:80b15993944e | 351 | // status update data cache and flags |
uci1 | 84:80b15993944e | 352 | static SnClockSetFrame gStTrgStartClk; |
uci1 | 84:80b15993944e | 353 | static SnClockSetFrame gStTrgStopClk; |
uci1 | 84:80b15993944e | 354 | static SnPowerFrame gStPower; |
uci1 | 84:80b15993944e | 355 | static SnTempFrame gStTemperature; |
uci1 | 84:80b15993944e | 356 | static volatile bool gStNewPower(false); |
uci1 | 84:80b15993944e | 357 | static volatile bool gStNewEvent(false); |
uci1 | 84:80b15993944e | 358 | static volatile bool gStNewHeartbeat(false); |
uci1 | 84:80b15993944e | 359 | static volatile bool gStNewTemperature(false); |
uci1 | 0:664899e0b988 | 360 | |
uci1 | 84:80b15993944e | 361 | #ifdef EVT_TIME_PROFILE |
uci1 | 84:80b15993944e | 362 | Timer gProfiler; |
uci1 | 84:80b15993944e | 363 | #endif |
uci1 | 67:ec999336fcd1 | 364 | |
uci1 | 0:664899e0b988 | 365 | void procForceTrigger() { |
uci1 | 0:664899e0b988 | 366 | if (gReadingOut==false && gCommWinOpen==false) { |
uci1 | 15:f2569d8e4176 | 367 | led3=!led3; |
uci1 | 12:d472f9811262 | 368 | #ifdef DEBUG |
uci1 | 8:95a325df1f6b | 369 | printf("proc force\r\n"); |
uci1 | 56:0bba0ef15697 | 370 | #if CHIPBOARD==ATWD4CH |
uci1 | 47:fbe956b10a91 | 371 | printf("PIN_forceTrigge=%d, PIN_turn_on_system=%d, " |
uci1 | 47:fbe956b10a91 | 372 | "PIN_a_sf_clk=%d\r\n", |
uci1 | 47:fbe956b10a91 | 373 | PIN_forceTrigger.read(), PIN_turn_on_system.read(), |
uci1 | 47:fbe956b10a91 | 374 | PIN_a_sf_clk.read()); |
uci1 | 56:0bba0ef15697 | 375 | #else |
uci1 | 56:0bba0ef15697 | 376 | printf("PIN_forceTrigge=%d, PIN_turn_on_system=%d, " |
uci1 | 56:0bba0ef15697 | 377 | "PIN_dataReady=%d\r\n", |
uci1 | 56:0bba0ef15697 | 378 | PIN_forceTrigger.read(), PIN_turn_on_system.read(), |
uci1 | 56:0bba0ef15697 | 379 | PIN_dataReady.read()); |
uci1 | 56:0bba0ef15697 | 380 | #endif // ATWD4CH |
uci1 | 12:d472f9811262 | 381 | #endif |
uci1 | 84:80b15993944e | 382 | gForcedTrig = true; |
uci1 | 84:80b15993944e | 383 | ++gNumFrcTrigs; |
uci1 | 84:80b15993944e | 384 | // ++(gTrgNum[kFrcTrg]); |
uci1 | 84:80b15993944e | 385 | // gEvent.SetTrgBit(kFrcTrg); |
uci1 | 84:80b15993944e | 386 | // gEvent.SetTrgNum(++(gTrgNum[kFrcTrg])); |
uci1 | 23:ccf39298f205 | 387 | //PIN_forceTrigger = 0; |
uci1 | 0:664899e0b988 | 388 | PIN_forceTrigger = 1; // force a trigger |
uci1 | 21:ce51bb0ba4a5 | 389 | PIN_forceTrigger = 0; |
uci1 | 0:664899e0b988 | 390 | } |
uci1 | 0:664899e0b988 | 391 | } |
uci1 | 0:664899e0b988 | 392 | |
uci1 | 3:24c5f0f50bf1 | 393 | void procHeartbeat() { |
uci1 | 3:24c5f0f50bf1 | 394 | if (gReadingOut==false && gCommWinOpen==false) { |
uci1 | 12:d472f9811262 | 395 | #ifdef DEBUG |
uci1 | 8:95a325df1f6b | 396 | printf("proc heartbeat\r\n"); |
uci1 | 12:d472f9811262 | 397 | #endif |
uci1 | 67:ec999336fcd1 | 398 | led3=!led3; |
uci1 | 23:ccf39298f205 | 399 | //PIN_heartbeat = 0; |
uci1 | 3:24c5f0f50bf1 | 400 | PIN_heartbeat = 1; // heartbeat pulse |
uci1 | 3:24c5f0f50bf1 | 401 | PIN_heartbeat = 0; |
uci1 | 22:f957c4f840ad | 402 | gLastHrtbt = time(0); |
uci1 | 22:f957c4f840ad | 403 | gHrtbtFired = true; |
uci1 | 22:f957c4f840ad | 404 | ++gHrtbtNum; |
uci1 | 3:24c5f0f50bf1 | 405 | } |
uci1 | 3:24c5f0f50bf1 | 406 | } |
uci1 | 3:24c5f0f50bf1 | 407 | |
uci1 | 8:95a325df1f6b | 408 | void procPowerCheck() { |
uci1 | 12:d472f9811262 | 409 | #ifdef DEBUG |
uci1 | 8:95a325df1f6b | 410 | printf("proc power\r\n"); |
uci1 | 12:d472f9811262 | 411 | #endif |
uci1 | 67:ec999336fcd1 | 412 | led3=!led3; |
uci1 | 8:95a325df1f6b | 413 | gCheckPower=true; |
uci1 | 8:95a325df1f6b | 414 | } |
uci1 | 8:95a325df1f6b | 415 | |
uci1 | 56:0bba0ef15697 | 416 | void procTempCheck() { |
uci1 | 56:0bba0ef15697 | 417 | #ifdef DEBUG |
uci1 | 56:0bba0ef15697 | 418 | printf("proc temp check\r\n"); |
uci1 | 56:0bba0ef15697 | 419 | #endif |
uci1 | 67:ec999336fcd1 | 420 | led3=!led3; |
uci1 | 56:0bba0ef15697 | 421 | gCheckTemp=true; |
uci1 | 56:0bba0ef15697 | 422 | } |
uci1 | 56:0bba0ef15697 | 423 | |
uci1 | 0:664899e0b988 | 424 | void procCommWin() { |
uci1 | 22:f957c4f840ad | 425 | ++gCommWinChecks; |
uci1 | 27:efc4d654b139 | 426 | //if ( (time(0) - gLastCommWin) > gConf.GetCommWinPeriod() ) { |
uci1 | 22:f957c4f840ad | 427 | #ifdef DEBUG |
uci1 | 27:efc4d654b139 | 428 | printf("<><><><><><> gCommWinChecks=%u, gNcommWinChecks=%u\r\n", |
uci1 | 27:efc4d654b139 | 429 | gCommWinChecks, gNcommWinChecks); |
uci1 | 22:f957c4f840ad | 430 | #endif |
uci1 | 27:efc4d654b139 | 431 | if ( gCommWinChecks >= gNcommWinChecks ) { |
uci1 | 12:d472f9811262 | 432 | #ifdef DEBUG |
uci1 | 27:efc4d654b139 | 433 | printf("proc comm win.\r\n"); |
uci1 | 12:d472f9811262 | 434 | #endif |
uci1 | 27:efc4d654b139 | 435 | led3=!led3; |
uci1 | 27:efc4d654b139 | 436 | gOpenCommWin = true; |
uci1 | 0:664899e0b988 | 437 | } |
uci1 | 0:664899e0b988 | 438 | } |
uci1 | 0:664899e0b988 | 439 | |
uci1 | 21:ce51bb0ba4a5 | 440 | bool AreCardsPowered(const bool checkPin) { |
uci1 | 21:ce51bb0ba4a5 | 441 | #ifdef DEBUG |
uci1 | 56:0bba0ef15697 | 442 | printf("acp call: PIN_turn_on_system=%d, gCardsPowered=%d\r\n", |
uci1 | 21:ce51bb0ba4a5 | 443 | PIN_turn_on_system.read(), gCardsPowered); |
uci1 | 21:ce51bb0ba4a5 | 444 | #endif |
uci1 | 21:ce51bb0ba4a5 | 445 | if (checkPin) { |
uci1 | 56:0bba0ef15697 | 446 | #if CHIPBOARD==ATWD4CH |
uci1 | 21:ce51bb0ba4a5 | 447 | gCardsPowered = (PIN_turn_on_system.read()==0); |
uci1 | 56:0bba0ef15697 | 448 | #else |
uci1 | 56:0bba0ef15697 | 449 | gCardsPowered = (PIN_turn_on_system.read()==1); |
uci1 | 56:0bba0ef15697 | 450 | #endif // ATWD4CH |
uci1 | 16:744ce85aede2 | 451 | } |
uci1 | 56:0bba0ef15697 | 452 | #ifdef DEBUG |
uci1 | 56:0bba0ef15697 | 453 | printf("acp return: PIN_turn_on_system=%d, gCardsPowered=%d\r\n", |
uci1 | 56:0bba0ef15697 | 454 | PIN_turn_on_system.read(), gCardsPowered); |
uci1 | 56:0bba0ef15697 | 455 | #endif |
uci1 | 21:ce51bb0ba4a5 | 456 | return gCardsPowered; |
uci1 | 8:95a325df1f6b | 457 | } |
uci1 | 0:664899e0b988 | 458 | |
uci1 | 8:95a325df1f6b | 459 | void GetAvePowerReading() { |
uci1 | 8:95a325df1f6b | 460 | // use one measurement as the assumed average |
uci1 | 8:95a325df1f6b | 461 | // in order to reduce computational errors |
uci1 | 8:95a325df1f6b | 462 | int32_t v1, v2; |
uci1 | 8:95a325df1f6b | 463 | const uint16_t aaveV1 = PIN_vADC1.read_u16(); |
uci1 | 8:95a325df1f6b | 464 | const uint16_t aaveV2 = PIN_vADC2.read_u16(); |
uci1 | 8:95a325df1f6b | 465 | float n=0, ave1=0, ave2=0, rms1=0, rms2=0; |
uci1 | 56:0bba0ef15697 | 466 | for (uint16_t i=0; i<kNvoltsAve; ++i) { |
uci1 | 8:95a325df1f6b | 467 | v1 = PIN_vADC1.read_u16() - aaveV1; |
uci1 | 8:95a325df1f6b | 468 | v2 = PIN_vADC2.read_u16() - aaveV2; |
uci1 | 8:95a325df1f6b | 469 | n += 1; |
uci1 | 8:95a325df1f6b | 470 | ave1 += v1; |
uci1 | 8:95a325df1f6b | 471 | rms1 += v1*v1; |
uci1 | 8:95a325df1f6b | 472 | ave2 += v2; |
uci1 | 8:95a325df1f6b | 473 | rms2 += v2*v2; |
uci1 | 8:95a325df1f6b | 474 | } |
uci1 | 8:95a325df1f6b | 475 | rms1 -= (ave1*ave1)/n; |
uci1 | 8:95a325df1f6b | 476 | rms2 -= (ave2*ave2)/n; |
uci1 | 8:95a325df1f6b | 477 | rms1 /= n-1; |
uci1 | 8:95a325df1f6b | 478 | rms2 /= n-1; |
uci1 | 9:a1a39573dd43 | 479 | rms1 = sqrt(rms1); |
uci1 | 9:a1a39573dd43 | 480 | rms2 = sqrt(rms2); |
uci1 | 8:95a325df1f6b | 481 | ave1 /= n; |
uci1 | 8:95a325df1f6b | 482 | ave2 /= n; |
uci1 | 8:95a325df1f6b | 483 | ave1 += aaveV1; |
uci1 | 8:95a325df1f6b | 484 | ave2 += aaveV2; |
uci1 | 8:95a325df1f6b | 485 | gPower.Set(ave1, ave2, rms1, rms2, time(0)); |
uci1 | 56:0bba0ef15697 | 486 | #ifdef DEBUG |
uci1 | 56:0bba0ef15697 | 487 | printf("ave power. v1=%g, v2=%g, r1=%g, r2=%g, t=%u\r\n", |
uci1 | 56:0bba0ef15697 | 488 | gPower.GetAveV1(), gPower.GetAveV2(), |
uci1 | 56:0bba0ef15697 | 489 | gPower.GetRmsV1(), gPower.GetRmsV2(), gPower.GetTime()); |
uci1 | 56:0bba0ef15697 | 490 | #endif |
uci1 | 8:95a325df1f6b | 491 | } |
uci1 | 0:664899e0b988 | 492 | |
uci1 | 114:554fa3a956b4 | 493 | #if CHIPBOARD!=ATWD4CH |
uci1 | 56:0bba0ef15697 | 494 | void InitTempProbe() { |
uci1 | 56:0bba0ef15697 | 495 | #ifdef DEBUG |
uci1 | 56:0bba0ef15697 | 496 | printf("setting temp probe power mode\r\n"); |
uci1 | 56:0bba0ef15697 | 497 | #endif |
uci1 | 56:0bba0ef15697 | 498 | // set power style for temperature probe |
uci1 | 56:0bba0ef15697 | 499 | PIN_therm.set_use_parasite_power( gConf.IsTempUsingParasitePower() ); |
uci1 | 56:0bba0ef15697 | 500 | // setup the probe |
uci1 | 56:0bba0ef15697 | 501 | #ifdef DEBUG |
uci1 | 56:0bba0ef15697 | 502 | printf("calling therm probe search_ROM_setup\r\n"); |
uci1 | 56:0bba0ef15697 | 503 | #endif |
uci1 | 56:0bba0ef15697 | 504 | PIN_therm.search_ROM_setup(); |
uci1 | 56:0bba0ef15697 | 505 | const int tsr = PIN_therm.search_ROM(); // this is necessary for some reason |
uci1 | 56:0bba0ef15697 | 506 | #ifdef DEBUG |
uci1 | 56:0bba0ef15697 | 507 | printf("search ROM = %d\r\n", tsr); |
uci1 | 56:0bba0ef15697 | 508 | #endif |
uci1 | 56:0bba0ef15697 | 509 | } |
uci1 | 56:0bba0ef15697 | 510 | #endif |
uci1 | 56:0bba0ef15697 | 511 | |
uci1 | 56:0bba0ef15697 | 512 | void UpdateTemperature() { |
uci1 | 56:0bba0ef15697 | 513 | // ask chip to convert temperature |
uci1 | 114:554fa3a956b4 | 514 | #if CHIPBOARD!=ATWD4CH |
uci1 | 56:0bba0ef15697 | 515 | PIN_therm.convert_temperature(true, DS1820::all_devices); |
uci1 | 56:0bba0ef15697 | 516 | gTemperature.SetTempAndTime( PIN_therm.temperature('c'), time(0) ); |
uci1 | 56:0bba0ef15697 | 517 | #ifdef DEBUG |
uci1 | 56:0bba0ef15697 | 518 | printf("TTTTTTTT temp = %g at %u\r\n", gTemperature.GetTemperature(), |
uci1 | 56:0bba0ef15697 | 519 | gTemperature.GetTime()); |
uci1 | 56:0bba0ef15697 | 520 | #endif |
uci1 | 67:ec999336fcd1 | 521 | #else |
uci1 | 67:ec999336fcd1 | 522 | return; // do nothing |
uci1 | 67:ec999336fcd1 | 523 | #endif |
uci1 | 56:0bba0ef15697 | 524 | } |
uci1 | 56:0bba0ef15697 | 525 | |
uci1 | 56:0bba0ef15697 | 526 | void CheckTemp() { |
uci1 | 56:0bba0ef15697 | 527 | #ifdef DEBUG |
uci1 | 56:0bba0ef15697 | 528 | printf("CheckTemp\r\n"); |
uci1 | 56:0bba0ef15697 | 529 | #endif |
uci1 | 56:0bba0ef15697 | 530 | UpdateTemperature(); |
uci1 | 56:0bba0ef15697 | 531 | // save to disk |
uci1 | 56:0bba0ef15697 | 532 | FILE* cf = SnSDUtils::GetCurFile(); |
uci1 | 56:0bba0ef15697 | 533 | if (cf!=0) { |
uci1 | 56:0bba0ef15697 | 534 | #if CHIPBOARD==ATWD4CH |
uci1 | 56:0bba0ef15697 | 535 | PIN_lockRegisters = 0; // unlock so we can talk to the SD card |
uci1 | 56:0bba0ef15697 | 536 | #else |
uci1 | 56:0bba0ef15697 | 537 | PIN_readingData = 0; // unlock so we can talk to the SD card |
uci1 | 56:0bba0ef15697 | 538 | #endif // ATWD4CH |
uci1 | 56:0bba0ef15697 | 539 | #ifdef DEBUG |
uci1 | 56:0bba0ef15697 | 540 | printf("writing temp. temp = %g at %u\r\n", |
uci1 | 56:0bba0ef15697 | 541 | gTemperature.GetTemperature(), |
uci1 | 56:0bba0ef15697 | 542 | gTemperature.GetTime()); |
uci1 | 56:0bba0ef15697 | 543 | #endif |
uci1 | 56:0bba0ef15697 | 544 | SnSDUtils::WriteTempTo(cf, gTemperature); |
uci1 | 56:0bba0ef15697 | 545 | } |
uci1 | 56:0bba0ef15697 | 546 | gCheckTemp = false; |
uci1 | 56:0bba0ef15697 | 547 | } |
uci1 | 56:0bba0ef15697 | 548 | |
uci1 | 56:0bba0ef15697 | 549 | void CheckPower(const bool isCommWin, |
uci1 | 84:80b15993944e | 550 | const bool saveReading, |
uci1 | 84:80b15993944e | 551 | const uint8_t devicesInUse) { |
uci1 | 12:d472f9811262 | 552 | #ifdef DEBUG |
uci1 | 8:95a325df1f6b | 553 | printf("CheckPower\r\n"); |
uci1 | 12:d472f9811262 | 554 | #endif |
uci1 | 8:95a325df1f6b | 555 | // read power |
uci1 | 8:95a325df1f6b | 556 | GetAvePowerReading(); |
uci1 | 56:0bba0ef15697 | 557 | if (saveReading) { |
uci1 | 56:0bba0ef15697 | 558 | // save to disk |
uci1 | 56:0bba0ef15697 | 559 | FILE* cf = SnSDUtils::GetCurFile(); |
uci1 | 56:0bba0ef15697 | 560 | if (cf!=0) { |
uci1 | 56:0bba0ef15697 | 561 | #if CHIPBOARD==ATWD4CH |
uci1 | 56:0bba0ef15697 | 562 | PIN_lockRegisters = 0; // unlock so we can talk to the SD card |
uci1 | 56:0bba0ef15697 | 563 | #else |
uci1 | 56:0bba0ef15697 | 564 | PIN_readingData = 0; // unlock so we can talk to the SD card |
uci1 | 56:0bba0ef15697 | 565 | #endif // ATWD4CH |
uci1 | 12:d472f9811262 | 566 | #ifdef DEBUG |
uci1 | 56:0bba0ef15697 | 567 | printf("writing power. v1=%g, v2=%g, r1=%g, r2=%g, t=%u, pownum=%u\r\n", |
uci1 | 56:0bba0ef15697 | 568 | gPower.GetAveV1(), gPower.GetAveV2(), |
uci1 | 56:0bba0ef15697 | 569 | gPower.GetRmsV1(), gPower.GetRmsV2(), gPower.GetTime(), |
uci1 | 56:0bba0ef15697 | 570 | gPowNum); |
uci1 | 12:d472f9811262 | 571 | #endif |
uci1 | 56:0bba0ef15697 | 572 | SnSDUtils::WritePowerTo(cf, gPower, gPowNum); |
uci1 | 56:0bba0ef15697 | 573 | } |
uci1 | 8:95a325df1f6b | 574 | } |
uci1 | 8:95a325df1f6b | 575 | // do we need to change modes? |
uci1 | 8:95a325df1f6b | 576 | bool changed = false; |
uci1 | 8:95a325df1f6b | 577 | if (gConf.IsLowPowerMode()) { |
uci1 | 56:0bba0ef15697 | 578 | #ifdef DEBUG |
uci1 | 56:0bba0ef15697 | 579 | printf("in low pwr. v1=%g, fromLP=%hu\r\n", |
uci1 | 56:0bba0ef15697 | 580 | gPower.GetAveV1(), gConf.GetBatVoltFromLowPwr()); |
uci1 | 56:0bba0ef15697 | 581 | #endif |
uci1 | 39:2f17131d22a5 | 582 | if (gPower.GetAveV1() > gConf.GetBatVoltFromLowPwr()) { |
uci1 | 12:d472f9811262 | 583 | #ifdef DEBUG |
uci1 | 8:95a325df1f6b | 584 | printf("chaing to normal power!\r\n"); |
uci1 | 12:d472f9811262 | 585 | #endif |
uci1 | 8:95a325df1f6b | 586 | gConf.ChangeToNormPower(); |
uci1 | 8:95a325df1f6b | 587 | changed = true; |
uci1 | 8:95a325df1f6b | 588 | } |
uci1 | 8:95a325df1f6b | 589 | } else { |
uci1 | 56:0bba0ef15697 | 590 | #ifdef DEBUG |
uci1 | 56:0bba0ef15697 | 591 | printf("in normal pwr. v1=%g, toLP=%hu\r\n", |
uci1 | 56:0bba0ef15697 | 592 | gPower.GetAveV1(), gConf.GetBatVoltToLowPwr()); |
uci1 | 56:0bba0ef15697 | 593 | #endif |
uci1 | 39:2f17131d22a5 | 594 | if (gPower.GetAveV1() < gConf.GetBatVoltToLowPwr()) { |
uci1 | 12:d472f9811262 | 595 | #ifdef DEBUG |
uci1 | 8:95a325df1f6b | 596 | printf("chaing to low power!\r\n"); |
uci1 | 12:d472f9811262 | 597 | #endif |
uci1 | 8:95a325df1f6b | 598 | gConf.ChangeToLowPower(); |
uci1 | 8:95a325df1f6b | 599 | changed = true; |
uci1 | 8:95a325df1f6b | 600 | } |
uci1 | 8:95a325df1f6b | 601 | } |
uci1 | 8:95a325df1f6b | 602 | if (changed) { |
uci1 | 84:80b15993944e | 603 | SetPower(isCommWin, devicesInUse); // TODO: This will fail if isCommWin==false? (currently not possible, but..) |
uci1 | 12:d472f9811262 | 604 | #ifdef DEBUG |
uci1 | 8:95a325df1f6b | 605 | printf("Using config %s\r\n",gConf.GetLabel()); |
uci1 | 12:d472f9811262 | 606 | #endif |
uci1 | 8:95a325df1f6b | 607 | SetConfigAndMakeOutputFile(); // setup defaults in case no communication |
uci1 | 8:95a325df1f6b | 608 | } |
uci1 | 8:95a325df1f6b | 609 | // checking done |
uci1 | 8:95a325df1f6b | 610 | gCheckPower = false; |
uci1 | 8:95a325df1f6b | 611 | } |
uci1 | 8:95a325df1f6b | 612 | |
uci1 | 84:80b15993944e | 613 | void ResetCounters() { |
uci1 | 12:d472f9811262 | 614 | const uint32_t evtStartCurSeq = (SnSDUtils::GetCurSeqNum()) // no -1; start with seq=0 |
uci1 | 12:d472f9811262 | 615 | * gConf.GetEvtsPerFile(); |
uci1 | 84:80b15993944e | 616 | // gEvent.ClearEvent(); |
uci1 | 40:1324da35afd4 | 617 | gEvtNum = evtStartCurSeq; |
uci1 | 12:d472f9811262 | 618 | gPowNum = evtStartCurSeq; |
uci1 | 84:80b15993944e | 619 | // memset(gTrgNum, 0, sizeof(uint32_t)*kNumTrgs); |
uci1 | 116:8099b754fbb4 | 620 | gNumSavedEvts = 0; |
uci1 | 84:80b15993944e | 621 | gNumThmTrigs = 0; |
uci1 | 84:80b15993944e | 622 | gNumFrcTrigs = 0; |
uci1 | 84:80b15993944e | 623 | gForcedTrig = false; |
uci1 | 22:f957c4f840ad | 624 | // reset rate counters |
uci1 | 116:8099b754fbb4 | 625 | // gThmDtSum = 0; |
uci1 | 116:8099b754fbb4 | 626 | // gThmNumDt = 0; |
uci1 | 116:8099b754fbb4 | 627 | // gEvtDtSum = 0; |
uci1 | 116:8099b754fbb4 | 628 | // gEvtNumDt = 0; |
uci1 | 22:f957c4f840ad | 629 | // reset heartbeat counters |
uci1 | 22:f957c4f840ad | 630 | gLastHrtbt = 0; |
uci1 | 22:f957c4f840ad | 631 | gHrtbtFired = false; |
uci1 | 22:f957c4f840ad | 632 | gHrtbtNum = 0; |
uci1 | 84:80b15993944e | 633 | // reset status data caches |
uci1 | 84:80b15993944e | 634 | gStNewPower = false; |
uci1 | 84:80b15993944e | 635 | gStNewEvent = false; |
uci1 | 84:80b15993944e | 636 | gStNewHeartbeat = false; |
uci1 | 84:80b15993944e | 637 | gStNewTemperature = false; |
uci1 | 84:80b15993944e | 638 | |
uci1 | 13:7a1fb885a8e4 | 639 | #ifdef DEBUG |
uci1 | 13:7a1fb885a8e4 | 640 | printf("Reset: gEvtNum=%u, gPowNum=%u, evtStartCS=%u\r\n", |
uci1 | 13:7a1fb885a8e4 | 641 | gEvtNum, gPowNum, evtStartCurSeq); |
uci1 | 13:7a1fb885a8e4 | 642 | #endif |
uci1 | 10:3c93db1cfb12 | 643 | } |
uci1 | 10:3c93db1cfb12 | 644 | |
uci1 | 116:8099b754fbb4 | 645 | /* |
uci1 | 56:0bba0ef15697 | 646 | void CalcRate(const uint32_t numtrgs, |
uci1 | 56:0bba0ef15697 | 647 | const double tottime_ms, |
uci1 | 56:0bba0ef15697 | 648 | float& rate) { |
uci1 | 56:0bba0ef15697 | 649 | rate = 0; |
uci1 | 56:0bba0ef15697 | 650 | if (numtrgs>1) { |
uci1 | 56:0bba0ef15697 | 651 | if (tottime_ms>0.0) { |
uci1 | 56:0bba0ef15697 | 652 | rate = static_cast<float>(numtrgs) |
uci1 | 56:0bba0ef15697 | 653 | / (tottime_ms/1e3); |
uci1 | 56:0bba0ef15697 | 654 | } else { |
uci1 | 56:0bba0ef15697 | 655 | // lots of triggers in 0 time |
uci1 | 56:0bba0ef15697 | 656 | rate = 1e6; |
uci1 | 56:0bba0ef15697 | 657 | } |
uci1 | 56:0bba0ef15697 | 658 | } |
uci1 | 56:0bba0ef15697 | 659 | } |
uci1 | 56:0bba0ef15697 | 660 | |
uci1 | 10:3c93db1cfb12 | 661 | void GetRates(float& thmrate, float& evtrate) { |
uci1 | 10:3c93db1cfb12 | 662 | thmrate = evtrate = 0; |
uci1 | 22:f957c4f840ad | 663 | #ifdef DEBUG |
uci1 | 22:f957c4f840ad | 664 | printf("** Getting rates: gThmNumDt=%d, gThmDtSum=%g, " |
uci1 | 22:f957c4f840ad | 665 | "gEvtNumDt=%d, gEvtDtSum=%g\r\n", |
uci1 | 22:f957c4f840ad | 666 | gThmNumDt, gThmDtSum, gEvtNumDt, gEvtDtSum); |
uci1 | 22:f957c4f840ad | 667 | #endif |
uci1 | 22:f957c4f840ad | 668 | |
uci1 | 56:0bba0ef15697 | 669 | CalcRate(gThmNumDt, gThmDtSum, thmrate); |
uci1 | 56:0bba0ef15697 | 670 | CalcRate(gEvtNumDt, gEvtDtSum, evtrate); |
uci1 | 22:f957c4f840ad | 671 | } |
uci1 | 22:f957c4f840ad | 672 | |
uci1 | 116:8099b754fbb4 | 673 | |
uci1 | 116:8099b754fbb4 | 674 | void AddToRate(const double dt, const bool isThm, |
uci1 | 116:8099b754fbb4 | 675 | const uint32_t nev) { |
uci1 | 116:8099b754fbb4 | 676 | // isThm==true => specifically a thermal trigger, not necessarily saved |
uci1 | 116:8099b754fbb4 | 677 | // isThm==false => ANY event (thermal or forced) that gets saved |
uci1 | 22:f957c4f840ad | 678 | if (isThm) { |
uci1 | 22:f957c4f840ad | 679 | gThmDtSum += dt; |
uci1 | 116:8099b754fbb4 | 680 | gThmNumDt += nev; |
uci1 | 22:f957c4f840ad | 681 | } else { |
uci1 | 22:f957c4f840ad | 682 | gEvtDtSum += dt; |
uci1 | 116:8099b754fbb4 | 683 | gEvtNumDt += nev; |
uci1 | 10:3c93db1cfb12 | 684 | } |
uci1 | 22:f957c4f840ad | 685 | #ifdef DEBUG |
uci1 | 22:f957c4f840ad | 686 | printf("** AddToRate: dt=%g, isThm=%d\r\n",dt,(int)isThm); |
uci1 | 22:f957c4f840ad | 687 | printf("** AddToRate: gThmNumDt=%d, gThmDtSum=%g, " |
uci1 | 22:f957c4f840ad | 688 | "gEvtNumDt=%d, gEvtDtSum=%g\r\n", |
uci1 | 22:f957c4f840ad | 689 | gThmNumDt, gThmDtSum, gEvtNumDt, gEvtDtSum); |
uci1 | 22:f957c4f840ad | 690 | #endif |
uci1 | 10:3c93db1cfb12 | 691 | } |
uci1 | 116:8099b754fbb4 | 692 | */ |
uci1 | 10:3c93db1cfb12 | 693 | |
uci1 | 8:95a325df1f6b | 694 | bool IsSeqComplete() { |
uci1 | 12:d472f9811262 | 695 | #ifdef DEBUG |
uci1 | 84:80b15993944e | 696 | printf("IsSeqComplete: eps=%hu, cntpow=%d, pow=%u, evt=%u, seq=%hu\r\n", |
uci1 | 10:3c93db1cfb12 | 697 | gConf.GetEvtsPerFile(), (int)gConf.IsCountingPowerReadings(), |
uci1 | 40:1324da35afd4 | 698 | gPowNum, gEvtNum, SnSDUtils::GetCurSeqNum()); |
uci1 | 12:d472f9811262 | 699 | #endif |
uci1 | 8:95a325df1f6b | 700 | if (gConf.GetEvtsPerFile()>0) { |
uci1 | 12:d472f9811262 | 701 | const uint32_t evtEndCurSeq = (SnSDUtils::GetCurSeqNum()+1) // account for seq=0 |
uci1 | 12:d472f9811262 | 702 | * gConf.GetEvtsPerFile(); |
uci1 | 12:d472f9811262 | 703 | #ifdef DEBUG |
uci1 | 12:d472f9811262 | 704 | printf("evtEndCurSeq=%u\r\n",evtEndCurSeq); |
uci1 | 12:d472f9811262 | 705 | #endif |
uci1 | 8:95a325df1f6b | 706 | if (gConf.IsCountingPowerReadings()) { |
uci1 | 12:d472f9811262 | 707 | return (gPowNum>=evtEndCurSeq); |
uci1 | 8:95a325df1f6b | 708 | } else { |
uci1 | 12:d472f9811262 | 709 | // first event num is a one-time per run offset, not one per sequence |
uci1 | 40:1324da35afd4 | 710 | return (gEvtNum>=evtEndCurSeq); |
uci1 | 8:95a325df1f6b | 711 | } |
uci1 | 12:d472f9811262 | 712 | } else { |
uci1 | 12:d472f9811262 | 713 | return false; |
uci1 | 8:95a325df1f6b | 714 | } |
uci1 | 8:95a325df1f6b | 715 | } |
uci1 | 1:e392595b4b76 | 716 | |
uci1 | 40:1324da35afd4 | 717 | #ifdef USE_RTOS |
uci1 | 8:95a325df1f6b | 718 | void stopTicker(rtos::RtosTimer* tik) { |
uci1 | 8:95a325df1f6b | 719 | if (tik!=0) { |
uci1 | 8:95a325df1f6b | 720 | tik->stop(); |
uci1 | 8:95a325df1f6b | 721 | } |
uci1 | 8:95a325df1f6b | 722 | } |
uci1 | 8:95a325df1f6b | 723 | #else |
uci1 | 8:95a325df1f6b | 724 | void stopTicker(Ticker& tik) { |
uci1 | 8:95a325df1f6b | 725 | tik.detach(); |
uci1 | 8:95a325df1f6b | 726 | } |
uci1 | 56:0bba0ef15697 | 727 | #endif // USE_RTOS |
uci1 | 8:95a325df1f6b | 728 | |
uci1 | 40:1324da35afd4 | 729 | #ifdef USE_RTOS |
uci1 | 18:55f1581f2ee4 | 730 | float resetTicker(rtos::RtosTimer* tik, const float timSec, |
uci1 | 18:55f1581f2ee4 | 731 | const float maxTimSec) { |
uci1 | 8:95a325df1f6b | 732 | if (tik!=0) { |
uci1 | 8:95a325df1f6b | 733 | tik->stop(); |
uci1 | 8:95a325df1f6b | 734 | if (timSec>0) { |
uci1 | 18:55f1581f2ee4 | 735 | float tp = timSec > maxTimSec ? maxTimSec : timSec; |
uci1 | 8:95a325df1f6b | 736 | tp *= 1000u; // ms |
uci1 | 8:95a325df1f6b | 737 | tik->start(tp); |
uci1 | 8:95a325df1f6b | 738 | return tp; |
uci1 | 8:95a325df1f6b | 739 | } |
uci1 | 8:95a325df1f6b | 740 | } |
uci1 | 8:95a325df1f6b | 741 | return 0; |
uci1 | 8:95a325df1f6b | 742 | } |
uci1 | 8:95a325df1f6b | 743 | #else |
uci1 | 18:55f1581f2ee4 | 744 | float resetTicker(Ticker& tik, const float timSec, |
uci1 | 18:55f1581f2ee4 | 745 | const float maxTimSec, void (*fptr)(void)) { |
uci1 | 8:95a325df1f6b | 746 | tik.detach(); |
uci1 | 8:95a325df1f6b | 747 | if (timSec>0) { |
uci1 | 18:55f1581f2ee4 | 748 | const float tp = timSec > maxTimSec ? maxTimSec : timSec; |
uci1 | 8:95a325df1f6b | 749 | tik.attach(fptr, tp); |
uci1 | 8:95a325df1f6b | 750 | return tp; |
uci1 | 8:95a325df1f6b | 751 | } |
uci1 | 8:95a325df1f6b | 752 | return 0; |
uci1 | 8:95a325df1f6b | 753 | } |
uci1 | 56:0bba0ef15697 | 754 | #endif // USE_RTOS |
uci1 | 8:95a325df1f6b | 755 | |
uci1 | 15:f2569d8e4176 | 756 | void StopAllTickers() { |
uci1 | 8:95a325df1f6b | 757 | stopTicker(gForceTicker); |
uci1 | 8:95a325df1f6b | 758 | stopTicker(gHeartbeatTicker); |
uci1 | 8:95a325df1f6b | 759 | stopTicker(gCommWinTicker); |
uci1 | 8:95a325df1f6b | 760 | stopTicker(gPowerCheckTicker); |
uci1 | 56:0bba0ef15697 | 761 | stopTicker(gTempCheckTicker); |
uci1 | 15:f2569d8e4176 | 762 | } |
uci1 | 15:f2569d8e4176 | 763 | |
uci1 | 15:f2569d8e4176 | 764 | void ResetAllTickers() { |
uci1 | 40:1324da35afd4 | 765 | #ifdef USE_RTOS |
uci1 | 18:55f1581f2ee4 | 766 | const float ftp = resetTicker(gForceTicker, gConf.GetForceTrigPeriod(), |
uci1 | 18:55f1581f2ee4 | 767 | kAbsMaxTimer); |
uci1 | 40:1324da35afd4 | 768 | Thread::wait(131); // make it less likely for multiple triggers to fire too close together |
uci1 | 18:55f1581f2ee4 | 769 | const float hbp = resetTicker(gHeartbeatTicker, gConf.GetHeartbeatPeriod(), |
uci1 | 18:55f1581f2ee4 | 770 | kAbsMaxTimer); |
uci1 | 40:1324da35afd4 | 771 | Thread::wait(173); // make it less likely for multiple triggers to fire too close together |
uci1 | 18:55f1581f2ee4 | 772 | const float cwp = resetTicker(gCommWinTicker, gConf.GetCommWinPeriod(), |
uci1 | 18:55f1581f2ee4 | 773 | kCommWinLongPrdTk); |
uci1 | 40:1324da35afd4 | 774 | Thread::wait(169); // make it less likely for multiple triggers to fire too close together |
uci1 | 18:55f1581f2ee4 | 775 | const float pcp = resetTicker(gPowerCheckTicker, gConf.GetVoltCheckPeriod(), |
uci1 | 18:55f1581f2ee4 | 776 | kAbsMaxTimer); |
uci1 | 56:0bba0ef15697 | 777 | Thread::wait(143); // make it less likely for multiple triggers to fire too close together |
uci1 | 56:0bba0ef15697 | 778 | const float ctp = resetTicker(gTempCheckTicker, gConf.GetTempCheckPeriod(), |
uci1 | 56:0bba0ef15697 | 779 | kAbsMaxTimer); |
uci1 | 15:f2569d8e4176 | 780 | #else |
uci1 | 18:55f1581f2ee4 | 781 | const float ftp = resetTicker(gForceTicker, gConf.GetForceTrigPeriod(), |
uci1 | 18:55f1581f2ee4 | 782 | kAbsMaxTimer, &procForceTrigger); |
uci1 | 25:57b2627fe756 | 783 | wait_ms(131); // make it less likely for multiple triggers to fire too close together |
uci1 | 18:55f1581f2ee4 | 784 | const float hbp = resetTicker(gHeartbeatTicker, gConf.GetHeartbeatPeriod(), |
uci1 | 18:55f1581f2ee4 | 785 | kAbsMaxTimer, &procHeartbeat); |
uci1 | 25:57b2627fe756 | 786 | wait_ms(173); // make it less likely for multiple triggers to fire too close together |
uci1 | 18:55f1581f2ee4 | 787 | const float cwp = resetTicker(gCommWinTicker, gConf.GetCommWinPeriod(), |
uci1 | 18:55f1581f2ee4 | 788 | kCommWinLongPrdTk, &procCommWin); |
uci1 | 25:57b2627fe756 | 789 | wait_ms(169); // make it less likely for multiple triggers to fire too close together |
uci1 | 18:55f1581f2ee4 | 790 | const float pcp = resetTicker(gPowerCheckTicker, gConf.GetVoltCheckPeriod(), |
uci1 | 18:55f1581f2ee4 | 791 | kAbsMaxTimer, &procPowerCheck); |
uci1 | 56:0bba0ef15697 | 792 | wait_ms(143); // make it less likely for multiple triggers to fire too close together |
uci1 | 56:0bba0ef15697 | 793 | const float ctp = resetTicker(gTempCheckTicker, gConf.GetTempCheckPeriod(), |
uci1 | 56:0bba0ef15697 | 794 | kAbsMaxTimer, &procTempCheck); |
uci1 | 56:0bba0ef15697 | 795 | #endif // USE_RTOS |
uci1 | 15:f2569d8e4176 | 796 | #ifdef DEBUG |
uci1 | 18:55f1581f2ee4 | 797 | printf("attach force trig %g\r\n",ftp); |
uci1 | 18:55f1581f2ee4 | 798 | printf("attach heart beat %g\r\n",hbp); |
uci1 | 18:55f1581f2ee4 | 799 | printf("attach comm win %g\r\n",cwp); |
uci1 | 18:55f1581f2ee4 | 800 | printf("attach power chk %g\r\n",pcp); |
uci1 | 56:0bba0ef15697 | 801 | printf("attach temp chk %g\r\n",ctp); |
uci1 | 15:f2569d8e4176 | 802 | #endif |
uci1 | 15:f2569d8e4176 | 803 | } |
uci1 | 61:42cbfc02e0e0 | 804 | /* |
uci1 | 56:0bba0ef15697 | 805 | void UponBrownout() { |
uci1 | 56:0bba0ef15697 | 806 | // signal brownout by all LEDs off |
uci1 | 56:0bba0ef15697 | 807 | led1 = led2 = led3 = led4 = 0; |
uci1 | 56:0bba0ef15697 | 808 | // note that debug printing here is pointless, |
uci1 | 56:0bba0ef15697 | 809 | // since power over USB will prevent brownout |
uci1 | 56:0bba0ef15697 | 810 | |
uci1 | 56:0bba0ef15697 | 811 | // close the current file |
uci1 | 56:0bba0ef15697 | 812 | #if CHIPBOARD==ATWD4CH |
uci1 | 56:0bba0ef15697 | 813 | PIN_lockRegisters = 0; // unlock so we can talk to the SD card |
uci1 | 56:0bba0ef15697 | 814 | #else |
uci1 | 56:0bba0ef15697 | 815 | PIN_readingData = 0; // unlock so we can talk to the SD card |
uci1 | 56:0bba0ef15697 | 816 | #endif |
uci1 | 56:0bba0ef15697 | 817 | SnSDUtils::WriteTrigWaitWinTime(SnSDUtils::GetCurFile(), |
uci1 | 56:0bba0ef15697 | 818 | gClkSet, |
uci1 | 56:0bba0ef15697 | 819 | false); |
uci1 | 56:0bba0ef15697 | 820 | SnSDUtils::CloseOutputFile(SnSDUtils::GetCurFile()); |
uci1 | 56:0bba0ef15697 | 821 | |
uci1 | 56:0bba0ef15697 | 822 | // change to low power settings |
uci1 | 56:0bba0ef15697 | 823 | gConf.ChangeToLowPower(); |
uci1 | 56:0bba0ef15697 | 824 | // actually power stuff down |
uci1 | 56:0bba0ef15697 | 825 | SetPower(gCommWinOpen); |
uci1 | 56:0bba0ef15697 | 826 | |
uci1 | 56:0bba0ef15697 | 827 | // goodnight |
uci1 | 56:0bba0ef15697 | 828 | Sleep(); |
uci1 | 56:0bba0ef15697 | 829 | } |
uci1 | 61:42cbfc02e0e0 | 830 | */ |
uci1 | 15:f2569d8e4176 | 831 | void StopRunning() { |
uci1 | 15:f2569d8e4176 | 832 | #if defined(DEBUG) || defined(SSNOTIFY) |
uci1 | 15:f2569d8e4176 | 833 | printf("stop running\r\n"); |
uci1 | 15:f2569d8e4176 | 834 | #endif |
uci1 | 15:f2569d8e4176 | 835 | StopAllTickers(); |
uci1 | 17:4687bf932b8c | 836 | OpenCommWin(); |
uci1 | 8:95a325df1f6b | 837 | while (true) { |
uci1 | 8:95a325df1f6b | 838 | led3 = 1; led4=1; |
uci1 | 40:1324da35afd4 | 839 | #ifdef USE_RTOS |
uci1 | 40:1324da35afd4 | 840 | Thread::wait(500); |
uci1 | 40:1324da35afd4 | 841 | #else |
uci1 | 8:95a325df1f6b | 842 | wait(0.5); |
uci1 | 56:0bba0ef15697 | 843 | #endif // USE_RTOS |
uci1 | 8:95a325df1f6b | 844 | led3 = 0; led4=0; |
uci1 | 40:1324da35afd4 | 845 | #ifdef USE_RTOS |
uci1 | 40:1324da35afd4 | 846 | Thread::wait(500); |
uci1 | 40:1324da35afd4 | 847 | #else |
uci1 | 8:95a325df1f6b | 848 | wait(0.5); |
uci1 | 56:0bba0ef15697 | 849 | #endif // USE_RTOS |
uci1 | 22:f957c4f840ad | 850 | // don't kick the watchdog |
uci1 | 22:f957c4f840ad | 851 | // if we do, the station is unrecoverable without physical access |
uci1 | 8:95a325df1f6b | 852 | } |
uci1 | 8:95a325df1f6b | 853 | } |
uci1 | 1:e392595b4b76 | 854 | |
uci1 | 40:1324da35afd4 | 855 | |
uci1 | 56:0bba0ef15697 | 856 | int InitSDCard() { |
uci1 | 40:1324da35afd4 | 857 | #ifdef DEBUG |
uci1 | 40:1324da35afd4 | 858 | printf("initializing SD card..\r\n"); |
uci1 | 40:1324da35afd4 | 859 | #endif |
uci1 | 76:f8383f0292c2 | 860 | int ret = 1; // always fail if ignoring the SD card (1==fail) |
uci1 | 76:f8383f0292c2 | 861 | if (gConf.IsIgnoringSDcard()==false) { |
uci1 | 76:f8383f0292c2 | 862 | // initialize the SD card. this should prevent the issue with |
uci1 | 76:f8383f0292c2 | 863 | // seq 0 being overwritten upon power up or the SD card first |
uci1 | 76:f8383f0292c2 | 864 | // being insterted |
uci1 | 63:4820a4460f00 | 865 | ret = sd.disk_initialize(); |
uci1 | 76:f8383f0292c2 | 866 | // may need to try a bunch of times to get it to init |
uci1 | 76:f8383f0292c2 | 867 | for (int i=0; i<25 && (ret!=0); ++i) { |
uci1 | 76:f8383f0292c2 | 868 | ret = sd.disk_initialize(); |
uci1 | 76:f8383f0292c2 | 869 | #ifdef DEBUG |
uci1 | 76:f8383f0292c2 | 870 | printf("called disk_initialize (ret=%d)\r\n",ret); |
uci1 | 76:f8383f0292c2 | 871 | #endif |
uci1 | 76:f8383f0292c2 | 872 | } |
uci1 | 76:f8383f0292c2 | 873 | } |
uci1 | 56:0bba0ef15697 | 874 | #ifdef DEBUG |
uci1 | 76:f8383f0292c2 | 875 | printf("init SD card %d..\r\n", ret); |
uci1 | 56:0bba0ef15697 | 876 | #endif |
uci1 | 56:0bba0ef15697 | 877 | return ret; |
uci1 | 40:1324da35afd4 | 878 | } |
uci1 | 40:1324da35afd4 | 879 | |
uci1 | 0:664899e0b988 | 880 | int main() { |
uci1 | 22:f957c4f840ad | 881 | // a failsafe |
uci1 | 62:4b59c1eb429f | 882 | //Watchdog::kick(WDFAILSAFE); |
uci1 | 62:4b59c1eb429f | 883 | #ifdef DEBUG |
uci1 | 63:4820a4460f00 | 884 | printf("Restart watchdog with time [%u] at [%u]\r\n", |
uci1 | 63:4820a4460f00 | 885 | gConf.GetWatchdogPeriod(), time(0)); |
uci1 | 84:80b15993944e | 886 | printf("Free memory = %d\r\n", FreeMem()); |
uci1 | 114:554fa3a956b4 | 887 | printf("CHIPBOARD=%d\r\n", int(CHIPBOARD)); |
uci1 | 62:4b59c1eb429f | 888 | #endif |
uci1 | 62:4b59c1eb429f | 889 | Watchdog::kick(gConf.GetWatchdogPeriod()); |
uci1 | 56:0bba0ef15697 | 890 | |
uci1 | 116:8099b754fbb4 | 891 | //#if defined(DEBUG) || defined(ENABLE_USB_COMM) || defined(EVT_TIME_PROFILE) |
uci1 | 56:0bba0ef15697 | 892 | gCpu.baud(CPUBAUD_SN); |
uci1 | 116:8099b754fbb4 | 893 | //#endif // DEBUG or ENABLE_USB_COMM |
uci1 | 56:0bba0ef15697 | 894 | |
uci1 | 1:e392595b4b76 | 895 | { |
uci1 | 18:55f1581f2ee4 | 896 | #if defined(SSNOTIFY) || defined(DEBUG) |
uci1 | 41:d6f5e2f09e07 | 897 | printf("\n\n\n\n\nmain: start\r\n"); |
uci1 | 15:f2569d8e4176 | 898 | #endif |
uci1 | 67:ec999336fcd1 | 899 | led1=led2=led3=led4=0; |
uci1 | 40:1324da35afd4 | 900 | #ifdef USE_RTOS |
uci1 | 40:1324da35afd4 | 901 | led1=1; Thread::wait(200); |
uci1 | 40:1324da35afd4 | 902 | led1=0; led2=1; Thread::wait(200); |
uci1 | 40:1324da35afd4 | 903 | led2=0; led3=1; Thread::wait(200); |
uci1 | 40:1324da35afd4 | 904 | led3=0; led4=1; Thread::wait(200); |
uci1 | 40:1324da35afd4 | 905 | #else |
uci1 | 2:e67f7c158087 | 906 | led1=1; wait(0.2); |
uci1 | 2:e67f7c158087 | 907 | led1=0; led2=1; wait(0.2); |
uci1 | 2:e67f7c158087 | 908 | led2=0; led3=1; wait(0.2); |
uci1 | 2:e67f7c158087 | 909 | led3=0; led4=1; wait(0.2); |
uci1 | 56:0bba0ef15697 | 910 | #endif // USE_RTOS |
uci1 | 1:e392595b4b76 | 911 | led4=0; |
uci1 | 1:e392595b4b76 | 912 | } |
uci1 | 67:ec999336fcd1 | 913 | |
uci1 | 67:ec999336fcd1 | 914 | // signal startup before first comm win |
uci1 | 67:ec999336fcd1 | 915 | led2 = led1 = 1; |
uci1 | 25:57b2627fe756 | 916 | |
uci1 | 56:0bba0ef15697 | 917 | // don't initialize yet, but give SnSDUtils a pointer to |
uci1 | 56:0bba0ef15697 | 918 | // the function that initializes it, so it can call the fcn later |
uci1 | 40:1324da35afd4 | 919 | SnSDUtils::fgDoInit = &InitSDCard; |
uci1 | 56:0bba0ef15697 | 920 | |
uci1 | 63:4820a4460f00 | 921 | // check in case we need to go to low power |
uci1 | 63:4820a4460f00 | 922 | //wait(4); // TODO: the vADCs read high for first ~4-5sec |
uci1 | 63:4820a4460f00 | 923 | CheckPower(false, false); |
uci1 | 63:4820a4460f00 | 924 | #ifdef DEBUG |
uci1 | 63:4820a4460f00 | 925 | printf("startup power: cards %d, amps %d, irid %d, afar %d\r\n", |
uci1 | 63:4820a4460f00 | 926 | PIN_turn_on_system.read(), PIN_turn_on_amps.read(), |
uci1 | 63:4820a4460f00 | 927 | PIN_iridSbd_power.read(), PIN_afar_power.read()); |
uci1 | 63:4820a4460f00 | 928 | #endif |
uci1 | 63:4820a4460f00 | 929 | |
uci1 | 61:42cbfc02e0e0 | 930 | /* |
uci1 | 56:0bba0ef15697 | 931 | // Note: the brownout isn't useful since it sees either 5V or nothing on our board |
uci1 | 56:0bba0ef15697 | 932 | // set up the brownout interrupt |
uci1 | 56:0bba0ef15697 | 933 | NVIC_SetVector(BOD_IRQn, (uint32_t)&UponBrownout); |
uci1 | 56:0bba0ef15697 | 934 | // Enable Brown Out Detect Interrupt |
uci1 | 56:0bba0ef15697 | 935 | NVIC_EnableIRQ(BOD_IRQn); |
uci1 | 61:42cbfc02e0e0 | 936 | */ |
uci1 | 56:0bba0ef15697 | 937 | |
uci1 | 21:ce51bb0ba4a5 | 938 | #ifdef DEBUG |
uci1 | 18:55f1581f2ee4 | 939 | printf("making comm objects\r\n"); |
uci1 | 18:55f1581f2ee4 | 940 | #endif |
uci1 | 25:57b2627fe756 | 941 | |
uci1 | 25:57b2627fe756 | 942 | uint8_t comi(0); |
uci1 | 114:554fa3a956b4 | 943 | #ifdef ENABLE_USB_COMM |
uci1 | 114:554fa3a956b4 | 944 | #ifdef DEBUG |
uci1 | 114:554fa3a956b4 | 945 | printf("makin SnCommWinUsb\r\n"); |
uci1 | 114:554fa3a956b4 | 946 | #endif |
uci1 | 114:554fa3a956b4 | 947 | gComms[comi++] = new SnCommWinUsb(&gCpu); |
uci1 | 114:554fa3a956b4 | 948 | #endif // ENABLE_USB_COMM |
uci1 | 25:57b2627fe756 | 949 | #ifdef ENABLE_AFAR_COMM |
uci1 | 25:57b2627fe756 | 950 | // RTOS stuff must be made inside main for some reason |
uci1 | 18:55f1581f2ee4 | 951 | #ifdef USE_ETH_INTERFACE |
uci1 | 41:d6f5e2f09e07 | 952 | #ifdef DEBUG |
uci1 | 41:d6f5e2f09e07 | 953 | printf("making SnCommAfarTCP\r\n"); |
uci1 | 41:d6f5e2f09e07 | 954 | #endif |
uci1 | 25:57b2627fe756 | 955 | gComms[comi++] = new SnCommAfarTCP(gConf); |
uci1 | 18:55f1581f2ee4 | 956 | #else |
uci1 | 41:d6f5e2f09e07 | 957 | #ifdef DEBUG |
uci1 | 41:d6f5e2f09e07 | 958 | printf("making SnCommWinAfar\r\n"); |
uci1 | 41:d6f5e2f09e07 | 959 | #endif |
uci1 | 37:ff95e7070f26 | 960 | //gComms[comi++] = new SnCommAfarNetIf(gConf); |
uci1 | 37:ff95e7070f26 | 961 | gComms[comi++] = new SnCommWinAfar(gConf); |
uci1 | 28:484943132bb0 | 962 | #ifdef ENABLE_AFAR_TWITTER |
uci1 | 41:d6f5e2f09e07 | 963 | #ifdef DEBUG |
uci1 | 41:d6f5e2f09e07 | 964 | printf("making SnCommAfarNetIfTwitter\r\n"); |
uci1 | 41:d6f5e2f09e07 | 965 | #endif |
uci1 | 28:484943132bb0 | 966 | gTwit = new SnCommAfarNetIfTwitter(gConf); |
uci1 | 56:0bba0ef15697 | 967 | #endif // ENABLE_AFAR_TWITTER |
uci1 | 56:0bba0ef15697 | 968 | #endif // USE_ETH_INTERFACE |
uci1 | 56:0bba0ef15697 | 969 | #endif // ENABLE_AFAR_COMM |
uci1 | 25:57b2627fe756 | 970 | #ifdef ENABLE_SBD_COMM |
uci1 | 41:d6f5e2f09e07 | 971 | #ifdef DEBUG |
uci1 | 41:d6f5e2f09e07 | 972 | printf("making SnCommWinSBD\r\n"); |
uci1 | 41:d6f5e2f09e07 | 973 | #endif |
uci1 | 40:1324da35afd4 | 974 | gComms[comi++] = new SnCommWinSBD(&gSBDport); |
uci1 | 56:0bba0ef15697 | 975 | #endif // ENABLE_SBD_COMM |
uci1 | 18:55f1581f2ee4 | 976 | |
uci1 | 18:55f1581f2ee4 | 977 | #ifdef DEBUG |
uci1 | 28:484943132bb0 | 978 | printf("made comm objects\r\n"); |
uci1 | 41:d6f5e2f09e07 | 979 | #ifdef USE_MODSERIAL |
uci1 | 41:d6f5e2f09e07 | 980 | printf("using MODSERIAL\r\n"); |
uci1 | 56:0bba0ef15697 | 981 | #endif // USE_MODSERIAL |
uci1 | 18:55f1581f2ee4 | 982 | #endif |
uci1 | 40:1324da35afd4 | 983 | |
uci1 | 40:1324da35afd4 | 984 | if (comi!=kNcomms) { |
uci1 | 40:1324da35afd4 | 985 | error("comi=[%hhu] != kNcomms=[%hhu]\r\n", |
uci1 | 40:1324da35afd4 | 986 | comi, kNcomms); |
uci1 | 40:1324da35afd4 | 987 | // will die here with blue lights of death |
uci1 | 40:1324da35afd4 | 988 | } |
uci1 | 40:1324da35afd4 | 989 | |
uci1 | 40:1324da35afd4 | 990 | #ifdef USE_RTOS |
uci1 | 8:95a325df1f6b | 991 | gForceTicker = new rtos::RtosTimer(&procForceTrigger); |
uci1 | 8:95a325df1f6b | 992 | gHeartbeatTicker = new rtos::RtosTimer(&procHeartbeat); |
uci1 | 8:95a325df1f6b | 993 | gCommWinTicker = new rtos::RtosTimer(&procCommWin); |
uci1 | 8:95a325df1f6b | 994 | gPowerCheckTicker = new rtos::RtosTimer(&procPowerCheck); |
uci1 | 56:0bba0ef15697 | 995 | gTempCheckTicker = new rtos::RtosTimer(&procTempCheck); |
uci1 | 56:0bba0ef15697 | 996 | #endif // USE_RTOS |
uci1 | 67:ec999336fcd1 | 997 | |
uci1 | 1:e392595b4b76 | 998 | // set the clock to the BS time, if it's not set |
uci1 | 1:e392595b4b76 | 999 | if ( (static_cast<int32_t>(time(0)))<0 ) { |
uci1 | 1:e392595b4b76 | 1000 | set_time(kBStime); |
uci1 | 1:e392595b4b76 | 1001 | } |
uci1 | 12:d472f9811262 | 1002 | #ifdef DEBUG |
uci1 | 1:e392595b4b76 | 1003 | printf("time = %d\r\n",(int32_t)time(0)); |
uci1 | 12:d472f9811262 | 1004 | #endif |
uci1 | 1:e392595b4b76 | 1005 | gLastCommWin = time(0); // prevent comm win proc |
uci1 | 0:664899e0b988 | 1006 | |
uci1 | 40:1324da35afd4 | 1007 | #ifdef USE_RTOS |
uci1 | 8:95a325df1f6b | 1008 | gForceTicker->stop(); |
uci1 | 8:95a325df1f6b | 1009 | #else |
uci1 | 0:664899e0b988 | 1010 | gForceTicker.detach(); |
uci1 | 56:0bba0ef15697 | 1011 | #endif // USE_RTOS |
uci1 | 0:664899e0b988 | 1012 | gFirstEvt = true; |
uci1 | 56:0bba0ef15697 | 1013 | |
uci1 | 67:ec999336fcd1 | 1014 | |
uci1 | 67:ec999336fcd1 | 1015 | #ifdef DEBUG |
uci1 | 67:ec999336fcd1 | 1016 | printf("MAC=%012llX\r\n", (gConf.GetMacAddress())>>16); // 64 -> 48 bits |
uci1 | 67:ec999336fcd1 | 1017 | printf("my ip = %s\r\n", gConf.GetMbedIP()); |
uci1 | 67:ec999336fcd1 | 1018 | printf("my mask = %s\r\n", gConf.GetMbedMask()); |
uci1 | 67:ec999336fcd1 | 1019 | printf("my gate = %s\r\n", gConf.GetMbedGate()); |
uci1 | 67:ec999336fcd1 | 1020 | printf("remote server = %s : %hu\r\n", |
uci1 | 67:ec999336fcd1 | 1021 | gConf.GetRemoteServer(), gConf.GetRemotePort()); |
uci1 | 84:80b15993944e | 1022 | for (uint8_t i=0; i<SnConfigFrame::kNumDatStreams; ++i) { |
uci1 | 84:80b15993944e | 1023 | printf("data stream %hhu (%s): connectTO=%hhu, listenTO=%hhu\r\n", |
uci1 | 84:80b15993944e | 1024 | i, SnConfigFrame::GetDataStreamNameOfIdx(i), |
uci1 | 84:80b15993944e | 1025 | gConf.GetCommWinConnectTOofIdx(i), |
uci1 | 84:80b15993944e | 1026 | gConf.GetCommWinListenTOofIdx(i)); |
uci1 | 84:80b15993944e | 1027 | } |
uci1 | 67:ec999336fcd1 | 1028 | #endif |
uci1 | 67:ec999336fcd1 | 1029 | |
uci1 | 4:a91682e19d6b | 1030 | // (probably) power down comms and power up cards,amps |
uci1 | 84:80b15993944e | 1031 | SetPower(false, SnConfigFrame::kIrid | SnConfigFrame::kAfar); |
uci1 | 56:0bba0ef15697 | 1032 | // check power again to see if voltages drooped |
uci1 | 56:0bba0ef15697 | 1033 | CheckPower(false, false); |
uci1 | 4:a91682e19d6b | 1034 | |
uci1 | 0:664899e0b988 | 1035 | // |
uci1 | 0:664899e0b988 | 1036 | // get config |
uci1 | 0:664899e0b988 | 1037 | // |
uci1 | 12:d472f9811262 | 1038 | #ifdef DEBUG |
uci1 | 84:80b15993944e | 1039 | printf("run mode\r\n"); |
uci1 | 84:80b15993944e | 1040 | printf("IsCountingPowerReadings=%d\r\n",(int)gConf.IsCountingPowerReadings()); |
uci1 | 84:80b15993944e | 1041 | printf("IsSingleSeqRunMode=%d\r\n",(int)gConf.IsSingleSeqRunMode()); |
uci1 | 84:80b15993944e | 1042 | printf("IsDualThresholdMode=%d\r\n",(int)gConf.IsDualThresholdMode()); |
uci1 | 84:80b15993944e | 1043 | printf("IsDifferentialTrigMode=%d\r\n",(int)gConf.IsDifferentialTrigMode()); |
uci1 | 84:80b15993944e | 1044 | printf("IsSBDonlyLowPwrMode=%d\r\n",(int)gConf.IsSBDonlyLowPwrMode()); |
uci1 | 84:80b15993944e | 1045 | printf("IsRunSeqListOneCommWinOnly=%d\r\n",(int)gConf.IsRunSeqListOneCommWinOnly()); |
uci1 | 84:80b15993944e | 1046 | printf("IsIgnoringSDcard=%d\r\n",(int)gConf.IsIgnoringSDcard()); |
uci1 | 84:80b15993944e | 1047 | printf("IsCommPowerSimple=%d\r\n",(int)gConf.IsCommPowerSimple()); |
uci1 | 8:95a325df1f6b | 1048 | printf("call OpenCommWin\r\n"); |
uci1 | 84:80b15993944e | 1049 | printf("Free memory = %d\r\n", FreeMem()); |
uci1 | 12:d472f9811262 | 1050 | #endif |
uci1 | 67:ec999336fcd1 | 1051 | led2 = led1 = 0; // back to "normal" for comm win |
uci1 | 122:c1b5023eac69 | 1052 | SnCommWin::ECommWinResult firstRes = OpenCommWin(true); // is the startup config |
uci1 | 122:c1b5023eac69 | 1053 | |
uci1 | 122:c1b5023eac69 | 1054 | #if defined(USE_INTERFACE_CHIP) || defined(LOAD_DEFAULT_CONFIG_FROM_SD) |
uci1 | 122:c1b5023eac69 | 1055 | if (firstRes<=SnCommWin::kAllFails) { |
uci1 | 122:c1b5023eac69 | 1056 | // initial communication failed -- try to load default config from file |
uci1 | 122:c1b5023eac69 | 1057 | gConf.SetFromDefaultConfFile(); |
uci1 | 122:c1b5023eac69 | 1058 | } |
uci1 | 122:c1b5023eac69 | 1059 | #endif |
uci1 | 122:c1b5023eac69 | 1060 | |
uci1 | 0:664899e0b988 | 1061 | // get ready to trigger |
uci1 | 0:664899e0b988 | 1062 | PIN_spi.format( 16, 1 ); // change to data readout format |
uci1 | 15:f2569d8e4176 | 1063 | PIN_spi.frequency( 10000000 ); // Max is 12.5 MHz |
uci1 | 0:664899e0b988 | 1064 | |
uci1 | 41:d6f5e2f09e07 | 1065 | // read and cache the dCard power pin setting, |
uci1 | 41:d6f5e2f09e07 | 1066 | // so we can use the cached value later |
uci1 | 37:ff95e7070f26 | 1067 | AreCardsPowered(true); // TODO: should this be an if? |
uci1 | 56:0bba0ef15697 | 1068 | register double etms=0; // time between written events |
uci1 | 41:d6f5e2f09e07 | 1069 | |
uci1 | 41:d6f5e2f09e07 | 1070 | // the main event loop. wait for triggers in SendClock |
uci1 | 41:d6f5e2f09e07 | 1071 | while ( true ) { |
uci1 | 0:664899e0b988 | 1072 | // in here, we wait for triggers from the MB-FPGA |
uci1 | 0:664899e0b988 | 1073 | Watchdog::kick(); // don't reset! |
uci1 | 1:e392595b4b76 | 1074 | |
uci1 | 67:ec999336fcd1 | 1075 | led1 = 1; // signal normal running (i.e. waiting) |
uci1 | 1:e392595b4b76 | 1076 | |
uci1 | 12:d472f9811262 | 1077 | #ifdef DEBUG |
uci1 | 1:e392595b4b76 | 1078 | printf("calling wait trig\r\n"); |
uci1 | 1:e392595b4b76 | 1079 | printf("gFirstEvt=%s\r\n",gFirstEvt?"true":"false"); |
uci1 | 5:9cea89700c66 | 1080 | printf("readingout=%d\r\n",(int)gReadingOut); |
uci1 | 84:80b15993944e | 1081 | printf("Free memory = %d\r\n", FreeMem()); |
uci1 | 12:d472f9811262 | 1082 | #endif |
uci1 | 40:1324da35afd4 | 1083 | if (gFirstEvt) { |
uci1 | 41:d6f5e2f09e07 | 1084 | #ifdef DEBUG |
uci1 | 41:d6f5e2f09e07 | 1085 | printf("WriteTrigWaitWinTime (start)\r\n"); |
uci1 | 41:d6f5e2f09e07 | 1086 | #endif |
uci1 | 97:9f3fe603e8b5 | 1087 | gClkSet.UpdateClock( gSinceClkSet ); |
uci1 | 40:1324da35afd4 | 1088 | SnSDUtils::WriteTrigWaitWinTime(SnSDUtils::GetCurFile(), |
uci1 | 40:1324da35afd4 | 1089 | gClkSet, |
uci1 | 40:1324da35afd4 | 1090 | true); |
uci1 | 116:8099b754fbb4 | 1091 | // gThmTrgTimer.reset(); gThmTrgTimer.start(); |
uci1 | 40:1324da35afd4 | 1092 | gAllTrgTimer.reset(); gAllTrgTimer.start(); |
uci1 | 116:8099b754fbb4 | 1093 | gTrgLiveTimer.reset(); gTrgLiveTimer.start(); |
uci1 | 84:80b15993944e | 1094 | gStTrgStartClk = gClkSet; |
uci1 | 114:554fa3a956b4 | 1095 | #if CHIPBOARD!=ATWD4CH |
uci1 | 56:0bba0ef15697 | 1096 | // reset in case a trigger arrived before we were ready |
uci1 | 56:0bba0ef15697 | 1097 | // this is mostly to ensure that the chip gets reset on soft |
uci1 | 56:0bba0ef15697 | 1098 | // reboot, in case it got stopped prior to the reboot |
uci1 | 116:8099b754fbb4 | 1099 | if (gConf.IsSkippingTrgStartReset()==false) { |
uci1 | 116:8099b754fbb4 | 1100 | #ifdef DEBUG |
uci1 | 116:8099b754fbb4 | 1101 | printf("-----------------------------------------\r\n"); |
uci1 | 116:8099b754fbb4 | 1102 | printf("trigger start reset\r\n"); |
uci1 | 56:0bba0ef15697 | 1103 | #endif |
uci1 | 116:8099b754fbb4 | 1104 | PIN_ResetChips = 1; |
uci1 | 116:8099b754fbb4 | 1105 | PIN_ResetChips = 0; |
uci1 | 116:8099b754fbb4 | 1106 | } |
uci1 | 116:8099b754fbb4 | 1107 | #ifdef DEBUG |
uci1 | 116:8099b754fbb4 | 1108 | else { |
uci1 | 116:8099b754fbb4 | 1109 | printf("-----------------------------------------\r\n"); |
uci1 | 116:8099b754fbb4 | 1110 | printf("SKIP trig start reset\r\n"); |
uci1 | 116:8099b754fbb4 | 1111 | } |
uci1 | 116:8099b754fbb4 | 1112 | #endif // DEBUG |
uci1 | 116:8099b754fbb4 | 1113 | #endif // not atwd4ch |
uci1 | 40:1324da35afd4 | 1114 | } |
uci1 | 76:f8383f0292c2 | 1115 | |
uci1 | 56:0bba0ef15697 | 1116 | #if CHIPBOARD==ATWD4CH |
uci1 | 56:0bba0ef15697 | 1117 | PIN_lockRegisters = 0; // allow data to come from DFPGA |
uci1 | 56:0bba0ef15697 | 1118 | WaitTrigAndSendClock(); // wait for trigger and move data to MB. this returns immediately if cards are powered off |
uci1 | 56:0bba0ef15697 | 1119 | PIN_lockRegisters = 1; // block registers during readout |
uci1 | 114:554fa3a956b4 | 1120 | #else // ATWD4CH |
uci1 | 56:0bba0ef15697 | 1121 | PIN_readingData = 0; // not reading yet |
uci1 | 56:0bba0ef15697 | 1122 | WaitTrigAndSendClock(); // wait for trigger. this returns immediately if cards are powered off |
uci1 | 56:0bba0ef15697 | 1123 | // PIN_readingData will be set high by SnEventFrame::ReadWaveformsSST |
uci1 | 114:554fa3a956b4 | 1124 | #endif // not ATWD4CH |
uci1 | 12:d472f9811262 | 1125 | #ifdef EVT_TIME_PROFILE |
uci1 | 84:80b15993944e | 1126 | gProfiler.start(); |
uci1 | 84:80b15993944e | 1127 | int befSaveEvt=0, aftSaveEvt=0, |
uci1 | 12:d472f9811262 | 1128 | befChkPow=0, aftChkPow=0, befNewSeq=0, aftNewSeq=0, endOfLoop=0; |
uci1 | 56:0bba0ef15697 | 1129 | #endif // EVT_TIME_PROFILE |
uci1 | 12:d472f9811262 | 1130 | |
uci1 | 1:e392595b4b76 | 1131 | if (gReadingOut) { |
uci1 | 67:ec999336fcd1 | 1132 | |
uci1 | 67:ec999336fcd1 | 1133 | led1 = 0; led4 = 1; // signal reading out |
uci1 | 67:ec999336fcd1 | 1134 | |
uci1 | 116:8099b754fbb4 | 1135 | // const double ttms = gThmTrgTimer.read_us() / 1e3; // for rate calculation |
uci1 | 56:0bba0ef15697 | 1136 | const double atms = gAllTrgTimer.read_us() / 1e3; // for throttle |
uci1 | 116:8099b754fbb4 | 1137 | /* |
uci1 | 100:3a27edf9ce16 | 1138 | if (gForcedTrig==false) { |
uci1 | 40:1324da35afd4 | 1139 | // don't reset if not a thermal trigger |
uci1 | 40:1324da35afd4 | 1140 | gThmTrgTimer.reset(); gThmTrgTimer.start(); |
uci1 | 40:1324da35afd4 | 1141 | } |
uci1 | 116:8099b754fbb4 | 1142 | */ |
uci1 | 40:1324da35afd4 | 1143 | gAllTrgTimer.reset(); gAllTrgTimer.start(); // restart trigger timer |
uci1 | 40:1324da35afd4 | 1144 | etms += atms; // time between events |
uci1 | 8:95a325df1f6b | 1145 | |
uci1 | 8:95a325df1f6b | 1146 | Watchdog::kick(); // don't reset! |
uci1 | 15:f2569d8e4176 | 1147 | |
uci1 | 1:e392595b4b76 | 1148 | // |
uci1 | 1:e392595b4b76 | 1149 | // got trigger. read registers to mbed and build the event |
uci1 | 1:e392595b4b76 | 1150 | // |
uci1 | 1:e392595b4b76 | 1151 | |
uci1 | 50:163ec8d88aa9 | 1152 | // TODO: no way to check for external trigger? |
uci1 | 84:80b15993944e | 1153 | if (gForcedTrig==false) { |
uci1 | 84:80b15993944e | 1154 | // ++(gTrgNum[kThmTrg]); |
uci1 | 84:80b15993944e | 1155 | ++gNumThmTrigs; |
uci1 | 116:8099b754fbb4 | 1156 | // AddToRate(ttms, true); |
uci1 | 84:80b15993944e | 1157 | } |
uci1 | 1:e392595b4b76 | 1158 | |
uci1 | 84:80b15993944e | 1159 | if ( gForcedTrig || gFirstEvt || |
uci1 | 56:0bba0ef15697 | 1160 | (etms>=gConf.GetEvtThrtlPeriodMs()) ) { |
uci1 | 1:e392595b4b76 | 1161 | |
uci1 | 12:d472f9811262 | 1162 | #ifdef EVT_TIME_PROFILE |
uci1 | 84:80b15993944e | 1163 | gProfiler.stop(); befSaveEvt=gProfiler.read_us(); gProfiler.start(); |
uci1 | 56:0bba0ef15697 | 1164 | #endif // EVT_TIME_PROFILE |
uci1 | 84:80b15993944e | 1165 | |
uci1 | 84:80b15993944e | 1166 | // want to keep this event. save it (and check if it passes L1) |
uci1 | 116:8099b754fbb4 | 1167 | const bool saved = SaveEvent(etms); |
uci1 | 116:8099b754fbb4 | 1168 | if (saved) { |
uci1 | 116:8099b754fbb4 | 1169 | // AddToRate(etms, false); |
uci1 | 116:8099b754fbb4 | 1170 | ++gNumSavedEvts; |
uci1 | 116:8099b754fbb4 | 1171 | etms=0; |
uci1 | 116:8099b754fbb4 | 1172 | } |
uci1 | 84:80b15993944e | 1173 | |
uci1 | 12:d472f9811262 | 1174 | #ifdef EVT_TIME_PROFILE |
uci1 | 84:80b15993944e | 1175 | gProfiler.stop(); aftSaveEvt=gProfiler.read_us(); gProfiler.start(); |
uci1 | 56:0bba0ef15697 | 1176 | #endif // EVT_TIME_PROFILE |
uci1 | 116:8099b754fbb4 | 1177 | |
uci1 | 56:0bba0ef15697 | 1178 | } else { |
uci1 | 114:554fa3a956b4 | 1179 | #if CHIPBOARD!=ATWD4CH |
uci1 | 116:8099b754fbb4 | 1180 | // got a trigger, but don't want the event. reset the chip to continue triggering |
uci1 | 116:8099b754fbb4 | 1181 | #ifdef DEBUG |
uci1 | 116:8099b754fbb4 | 1182 | printf(">>>>>>> THROW EVENT AWAY! forced=%s, first=%s, " |
uci1 | 116:8099b754fbb4 | 1183 | "etms=%g, throttle=%hu, etms>=thr=%s\r\n", |
uci1 | 116:8099b754fbb4 | 1184 | (gForcedTrig ? "true" : "false"), |
uci1 | 116:8099b754fbb4 | 1185 | (gFirstEvt ? "true" : "false"), |
uci1 | 116:8099b754fbb4 | 1186 | etms, gConf.GetEvtThrtlPeriodMs(), |
uci1 | 116:8099b754fbb4 | 1187 | (etms>=gConf.GetEvtThrtlPeriodMs() ? "true" : "false")); |
uci1 | 116:8099b754fbb4 | 1188 | #endif // DEBUG |
uci1 | 56:0bba0ef15697 | 1189 | PIN_ResetChips = 1; |
uci1 | 56:0bba0ef15697 | 1190 | PIN_ResetChips = 0; |
uci1 | 12:d472f9811262 | 1191 | #endif |
uci1 | 1:e392595b4b76 | 1192 | } |
uci1 | 67:ec999336fcd1 | 1193 | |
uci1 | 84:80b15993944e | 1194 | // done with this event. |
uci1 | 84:80b15993944e | 1195 | // reset flags from the "old" event |
uci1 | 84:80b15993944e | 1196 | gForcedTrig = false; |
uci1 | 84:80b15993944e | 1197 | gAdcToMBflag = false; |
uci1 | 84:80b15993944e | 1198 | |
uci1 | 67:ec999336fcd1 | 1199 | led1 = 1; led4 = 0; // end signal reading out |
uci1 | 67:ec999336fcd1 | 1200 | |
uci1 | 1:e392595b4b76 | 1201 | } |
uci1 | 12:d472f9811262 | 1202 | #ifdef DEBUG |
uci1 | 1:e392595b4b76 | 1203 | printf("past reading out\r\n"); |
uci1 | 12:d472f9811262 | 1204 | #endif |
uci1 | 1:e392595b4b76 | 1205 | |
uci1 | 23:ccf39298f205 | 1206 | if (gHrtbtFired) { |
uci1 | 67:ec999336fcd1 | 1207 | led1 = 1; led4 = 1; // signal saving transient |
uci1 | 84:80b15993944e | 1208 | gHrtbt.SetTime( gLastHrtbt ); |
uci1 | 84:80b15993944e | 1209 | // -1 so we start counting at 0 |
uci1 | 84:80b15993944e | 1210 | // counting inside proc so we have a record of the number of proc's |
uci1 | 84:80b15993944e | 1211 | // even if we are saving/triggering slower than they're firing |
uci1 | 84:80b15993944e | 1212 | gHrtbt.SetNum( (gHrtbtNum>0) ? (gHrtbtNum - 1) : 0 ); |
uci1 | 23:ccf39298f205 | 1213 | SaveHeartbeat(); |
uci1 | 23:ccf39298f205 | 1214 | gHrtbtFired=false; |
uci1 | 84:80b15993944e | 1215 | gStNewHeartbeat = true; |
uci1 | 67:ec999336fcd1 | 1216 | led1 = 1; led4 = 0; // end signal saving transient |
uci1 | 23:ccf39298f205 | 1217 | } |
uci1 | 12:d472f9811262 | 1218 | |
uci1 | 12:d472f9811262 | 1219 | #ifdef EVT_TIME_PROFILE |
uci1 | 84:80b15993944e | 1220 | gProfiler.stop(); befChkPow=gProfiler.read_us(); gProfiler.start(); |
uci1 | 56:0bba0ef15697 | 1221 | #endif // EVT_TIME_PROFILE |
uci1 | 8:95a325df1f6b | 1222 | // check the power? |
uci1 | 8:95a325df1f6b | 1223 | if (gCheckPower) { |
uci1 | 12:d472f9811262 | 1224 | #ifdef DEBUG |
uci1 | 8:95a325df1f6b | 1225 | printf("call check power\r\n"); |
uci1 | 12:d472f9811262 | 1226 | #endif |
uci1 | 67:ec999336fcd1 | 1227 | led1 = 1; led4 = 1; // signal saving transient |
uci1 | 8:95a325df1f6b | 1228 | CheckPower(false); |
uci1 | 84:80b15993944e | 1229 | gStPower = gPower; |
uci1 | 84:80b15993944e | 1230 | gStNewPower = true; |
uci1 | 67:ec999336fcd1 | 1231 | led1 = 1; led4 = 0; // end signal saving transient |
uci1 | 8:95a325df1f6b | 1232 | } |
uci1 | 12:d472f9811262 | 1233 | #ifdef EVT_TIME_PROFILE |
uci1 | 84:80b15993944e | 1234 | gProfiler.stop(); aftChkPow=gProfiler.read_us(); gProfiler.start(); |
uci1 | 56:0bba0ef15697 | 1235 | #endif // EVT_TIME_PROFILE |
uci1 | 56:0bba0ef15697 | 1236 | |
uci1 | 56:0bba0ef15697 | 1237 | if (gCheckTemp) { |
uci1 | 56:0bba0ef15697 | 1238 | #ifdef DEBUG |
uci1 | 56:0bba0ef15697 | 1239 | printf("call check temp\r\n"); |
uci1 | 12:d472f9811262 | 1240 | #endif |
uci1 | 67:ec999336fcd1 | 1241 | led1 = 1; led4 = 1; // signal saving transient |
uci1 | 56:0bba0ef15697 | 1242 | CheckTemp(); |
uci1 | 84:80b15993944e | 1243 | gStTemperature = gTemperature; |
uci1 | 84:80b15993944e | 1244 | gStNewTemperature = true; |
uci1 | 67:ec999336fcd1 | 1245 | led1 = 1; led4 = 0; // end signal saving transient |
uci1 | 56:0bba0ef15697 | 1246 | } |
uci1 | 8:95a325df1f6b | 1247 | |
uci1 | 21:ce51bb0ba4a5 | 1248 | // open comm win? |
uci1 | 21:ce51bb0ba4a5 | 1249 | if (gOpenCommWin) { |
uci1 | 21:ce51bb0ba4a5 | 1250 | #ifdef DEBUG |
uci1 | 21:ce51bb0ba4a5 | 1251 | printf("gOpenComWin=%s, opening\r\n",gOpenCommWin?"true":"false"); |
uci1 | 21:ce51bb0ba4a5 | 1252 | #endif |
uci1 | 116:8099b754fbb4 | 1253 | PrepForSeqClose(); |
uci1 | 67:ec999336fcd1 | 1254 | led1 = 0; // signal not waiting |
uci1 | 21:ce51bb0ba4a5 | 1255 | OpenCommWin(); |
uci1 | 67:ec999336fcd1 | 1256 | led1 = 1; // end signal not waiting |
uci1 | 21:ce51bb0ba4a5 | 1257 | gOpenCommWin=false; |
uci1 | 116:8099b754fbb4 | 1258 | PrepForNewSeq(etms); |
uci1 | 116:8099b754fbb4 | 1259 | |
uci1 | 21:ce51bb0ba4a5 | 1260 | } else { |
uci1 | 21:ce51bb0ba4a5 | 1261 | #ifdef DEBUG |
uci1 | 27:efc4d654b139 | 1262 | printf("gOpenCommWin=false, gCommWinChecks=%u, gNcommWinChecks=%u\r\n", |
uci1 | 27:efc4d654b139 | 1263 | gCommWinChecks, gNcommWinChecks); |
uci1 | 21:ce51bb0ba4a5 | 1264 | #endif |
uci1 | 21:ce51bb0ba4a5 | 1265 | } |
uci1 | 21:ce51bb0ba4a5 | 1266 | |
uci1 | 12:d472f9811262 | 1267 | #ifdef EVT_TIME_PROFILE |
uci1 | 84:80b15993944e | 1268 | gProfiler.stop(); befNewSeq=gProfiler.read_us(); gProfiler.start(); |
uci1 | 56:0bba0ef15697 | 1269 | #endif // EVT_TIME_PROFILE |
uci1 | 8:95a325df1f6b | 1270 | // make new seq? |
uci1 | 8:95a325df1f6b | 1271 | if (IsSeqComplete()) { |
uci1 | 12:d472f9811262 | 1272 | #ifdef DEBUG |
uci1 | 10:3c93db1cfb12 | 1273 | printf("seq complete. sngseq=%d\r\n",gConf.IsSingleSeqRunMode()); |
uci1 | 12:d472f9811262 | 1274 | #endif |
uci1 | 67:ec999336fcd1 | 1275 | led1 = 1; led2 = 1; led4 = 1; // signal saving file |
uci1 | 116:8099b754fbb4 | 1276 | PrepForSeqClose(); |
uci1 | 8:95a325df1f6b | 1277 | MakeOutputFile(gConf.IsSingleSeqRunMode()); |
uci1 | 116:8099b754fbb4 | 1278 | PrepForNewSeq(etms); |
uci1 | 67:ec999336fcd1 | 1279 | led1 = 1; led2 = 0; led4 = 0; // end signal saving file |
uci1 | 8:95a325df1f6b | 1280 | } |
uci1 | 12:d472f9811262 | 1281 | #ifdef EVT_TIME_PROFILE |
uci1 | 84:80b15993944e | 1282 | gProfiler.stop(); aftNewSeq=gProfiler.read_us(); gProfiler.start(); |
uci1 | 56:0bba0ef15697 | 1283 | #endif // EVT_TIME_PROFILE |
uci1 | 12:d472f9811262 | 1284 | |
uci1 | 12:d472f9811262 | 1285 | #ifdef EVT_TIME_PROFILE |
uci1 | 84:80b15993944e | 1286 | gProfiler.stop(); endOfLoop=gProfiler.read_us(); gProfiler.start(); |
uci1 | 84:80b15993944e | 1287 | printf("befSaveEvt=%d, aftSaveEvt=%d, " |
uci1 | 12:d472f9811262 | 1288 | "befChkPow=%d, aftChkPow=%d, befNewSeq=%d, aftNewSeq=%d, endOfLoop=%d\r\n", |
uci1 | 84:80b15993944e | 1289 | befSaveEvt, aftSaveEvt, |
uci1 | 12:d472f9811262 | 1290 | befChkPow, aftChkPow, befNewSeq, aftNewSeq, endOfLoop); |
uci1 | 56:0bba0ef15697 | 1291 | #endif // EVT_TIME_PROFILE |
uci1 | 41:d6f5e2f09e07 | 1292 | |
uci1 | 41:d6f5e2f09e07 | 1293 | /* |
uci1 | 15:f2569d8e4176 | 1294 | // get ready to trigger |
uci1 | 15:f2569d8e4176 | 1295 | PIN_spi.format( 16, 1 ); // change to data readout format |
uci1 | 15:f2569d8e4176 | 1296 | PIN_spi.frequency( 10000000 ); // Max is 12.5 MHz |
uci1 | 41:d6f5e2f09e07 | 1297 | */ |
uci1 | 22:f957c4f840ad | 1298 | |
uci1 | 21:ce51bb0ba4a5 | 1299 | // reset event |
uci1 | 22:f957c4f840ad | 1300 | // clear after comm win, so full event can be sent with status |
uci1 | 22:f957c4f840ad | 1301 | // but don't clear counters or trigger bits, as |
uci1 | 84:80b15993944e | 1302 | // gEvent.ClearEvent(true); |
uci1 | 21:ce51bb0ba4a5 | 1303 | |
uci1 | 41:d6f5e2f09e07 | 1304 | } // end while (true) |
uci1 | 0:664899e0b988 | 1305 | |
uci1 | 0:664899e0b988 | 1306 | } |
uci1 | 0:664899e0b988 | 1307 | |
uci1 | 116:8099b754fbb4 | 1308 | float GetSeqLivetime() { |
uci1 | 116:8099b754fbb4 | 1309 | const float dt = gStTrgStopClk.GetCurTime() - gStTrgStartClk.GetCurTime(); |
uci1 | 116:8099b754fbb4 | 1310 | if ( dt < kAbsMaxTimer ) { |
uci1 | 116:8099b754fbb4 | 1311 | // the timer should be valid (not rolled over) |
uci1 | 116:8099b754fbb4 | 1312 | return gTrgLiveTimer.read(); |
uci1 | 116:8099b754fbb4 | 1313 | } else { |
uci1 | 116:8099b754fbb4 | 1314 | // lose the sub-second resolution, but who cares |
uci1 | 116:8099b754fbb4 | 1315 | return dt; |
uci1 | 116:8099b754fbb4 | 1316 | } |
uci1 | 116:8099b754fbb4 | 1317 | } |
uci1 | 116:8099b754fbb4 | 1318 | |
uci1 | 116:8099b754fbb4 | 1319 | void PrepForSeqClose() { |
uci1 | 116:8099b754fbb4 | 1320 | #ifdef DEBUG |
uci1 | 116:8099b754fbb4 | 1321 | printf("WriteTrigWaitWinTime (stop)\r\n"); |
uci1 | 116:8099b754fbb4 | 1322 | #endif |
uci1 | 116:8099b754fbb4 | 1323 | // add on time since last trigger/event so rates are better calculated |
uci1 | 116:8099b754fbb4 | 1324 | // do not increment trigger/event counters, however |
uci1 | 116:8099b754fbb4 | 1325 | // AddToRate( gThmTrgTimer.read_us() / 1e3, true, 0 ); |
uci1 | 116:8099b754fbb4 | 1326 | // AddToRate( gAllTrgTimer.read_us() / 1e3, false, 0 ); |
uci1 | 116:8099b754fbb4 | 1327 | gTrgLiveTimer.stop(); |
uci1 | 116:8099b754fbb4 | 1328 | // write the trigger stop time |
uci1 | 116:8099b754fbb4 | 1329 | gClkSet.UpdateClock( gSinceClkSet ); |
uci1 | 116:8099b754fbb4 | 1330 | SnSDUtils::WriteTrigWaitWinTime(SnSDUtils::GetCurFile(), |
uci1 | 116:8099b754fbb4 | 1331 | gClkSet, |
uci1 | 116:8099b754fbb4 | 1332 | false); |
uci1 | 116:8099b754fbb4 | 1333 | // save copy of trig stop time so it can be sent in status data pack |
uci1 | 116:8099b754fbb4 | 1334 | gStTrgStopClk = gClkSet; |
uci1 | 116:8099b754fbb4 | 1335 | } |
uci1 | 116:8099b754fbb4 | 1336 | |
uci1 | 116:8099b754fbb4 | 1337 | void PrepForNewSeq(double& etms) { |
uci1 | 116:8099b754fbb4 | 1338 | // reset timers, first event flag and the time since last saved event |
uci1 | 116:8099b754fbb4 | 1339 | gFirstEvt = true; |
uci1 | 116:8099b754fbb4 | 1340 | gAllTrgTimer.reset(); |
uci1 | 116:8099b754fbb4 | 1341 | // gThmTrgTimer.reset(); |
uci1 | 116:8099b754fbb4 | 1342 | gTrgLiveTimer.reset(); |
uci1 | 116:8099b754fbb4 | 1343 | etms=0; |
uci1 | 116:8099b754fbb4 | 1344 | } |
uci1 | 116:8099b754fbb4 | 1345 | |
uci1 | 116:8099b754fbb4 | 1346 | |
uci1 | 116:8099b754fbb4 | 1347 | |
uci1 | 0:664899e0b988 | 1348 | // |
uci1 | 22:f957c4f840ad | 1349 | // save a heartbeat tag |
uci1 | 22:f957c4f840ad | 1350 | // |
uci1 | 22:f957c4f840ad | 1351 | void SaveHeartbeat() { |
uci1 | 22:f957c4f840ad | 1352 | #ifdef DEBUG |
uci1 | 84:80b15993944e | 1353 | printf("save heartbeat #%u, time %u\r\n", |
uci1 | 84:80b15993944e | 1354 | gHrtbt.GetNum(), gHrtbt.GetTime()); |
uci1 | 22:f957c4f840ad | 1355 | #endif |
uci1 | 84:80b15993944e | 1356 | // save to SD |
uci1 | 56:0bba0ef15697 | 1357 | #if CHIPBOARD==ATWD4CH |
uci1 | 84:80b15993944e | 1358 | PIN_lockRegisters = 0; // unlock so we can talk to the SD card |
uci1 | 56:0bba0ef15697 | 1359 | #else |
uci1 | 84:80b15993944e | 1360 | PIN_readingData = 0; // unlock so we can talk to the SD card |
uci1 | 56:0bba0ef15697 | 1361 | #endif |
uci1 | 84:80b15993944e | 1362 | SnSDUtils::WriteHeartbeatTo(SnSDUtils::GetCurFile(), gHrtbt); |
uci1 | 22:f957c4f840ad | 1363 | } |
uci1 | 22:f957c4f840ad | 1364 | |
uci1 | 22:f957c4f840ad | 1365 | // |
uci1 | 0:664899e0b988 | 1366 | // save the event |
uci1 | 0:664899e0b988 | 1367 | // |
uci1 | 116:8099b754fbb4 | 1368 | bool SaveEvent(const int32_t etms) { |
uci1 | 0:664899e0b988 | 1369 | // write the event |
uci1 | 116:8099b754fbb4 | 1370 | bool didSave = false; |
uci1 | 12:d472f9811262 | 1371 | |
uci1 | 12:d472f9811262 | 1372 | #ifdef DEBUG |
uci1 | 84:80b15993944e | 1373 | // check that the event is still the same as gLastEvent |
uci1 | 84:80b15993944e | 1374 | /* |
uci1 | 84:80b15993944e | 1375 | bool esame = gEvent.GetMbedTime() == gLastEvent.GetMbedTime(); |
uci1 | 84:80b15993944e | 1376 | esame &= gEvent.GetEvtNum() == gLastEvent.GetEvtNum(); |
uci1 | 84:80b15993944e | 1377 | esame &= gEvent.GetDTms() == gLastEvent.GetDTms(); |
uci1 | 84:80b15993944e | 1378 | esame &= gEvent.GetTrgNum() == gLastEvent.GetTrgNum(); |
uci1 | 84:80b15993944e | 1379 | esame &= gEvent.GetTrgBits() == gLastEvent.GetTrgBits(); |
uci1 | 84:80b15993944e | 1380 | esame &= gEvent.GetCRC() == gLastEvent.GetCRC(); |
uci1 | 84:80b15993944e | 1381 | for (uint16_t i=0; i<kTotSamps; ++i) { |
uci1 | 84:80b15993944e | 1382 | esame &= (gEvent.GetData())[i] == (gLastEvent.GetData())[i]; |
uci1 | 84:80b15993944e | 1383 | } |
uci1 | 84:80b15993944e | 1384 | #if CHIPBOARD!=ATWD4CH |
uci1 | 84:80b15993944e | 1385 | for (uint16_t i=0; i<kNstopBytes; ++i) { |
uci1 | 84:80b15993944e | 1386 | esame &= (gEvent.GetStop())[i] == (gLastEvent.GetStop())[i]; |
uci1 | 84:80b15993944e | 1387 | } |
uci1 | 84:80b15993944e | 1388 | printf("EEEEEEEE event==lastEvt = %s\r\n", (esame?"true":"false")); |
uci1 | 84:80b15993944e | 1389 | #endif |
uci1 | 84:80b15993944e | 1390 | */ |
uci1 | 84:80b15993944e | 1391 | #endif |
uci1 | 84:80b15993944e | 1392 | |
uci1 | 84:80b15993944e | 1393 | // ok, now we can overwrite the old gEvent data |
uci1 | 84:80b15993944e | 1394 | // reset event |
uci1 | 84:80b15993944e | 1395 | gEvent.ClearEvent(true, true); |
uci1 | 84:80b15993944e | 1396 | |
uci1 | 84:80b15993944e | 1397 | // read data & calc CRC |
uci1 | 84:80b15993944e | 1398 | #ifdef EVT_TIME_PROFILE |
uci1 | 84:80b15993944e | 1399 | int befReadWv=0, aftReadWv=0, befWriteEvt=0, aftWriteEvt=0; |
uci1 | 116:8099b754fbb4 | 1400 | int befL1=0, aftL1=0; |
uci1 | 84:80b15993944e | 1401 | gProfiler.stop(); befReadWv=gProfiler.read_us(); gProfiler.start(); |
uci1 | 84:80b15993944e | 1402 | #endif // EVT_TIME_PROFILE |
uci1 | 84:80b15993944e | 1403 | |
uci1 | 84:80b15993944e | 1404 | #if CHIPBOARD==ATWD4CH |
uci1 | 84:80b15993944e | 1405 | // get the data to the MBED |
uci1 | 84:80b15993944e | 1406 | gEvent.ReadWaveformsATWD(PIN_spi, PIN_selCardHiBit, PIN_selCardLoBit); |
uci1 | 84:80b15993944e | 1407 | #else |
uci1 | 84:80b15993944e | 1408 | gEvent.ReadWaveformsSST(PIN_spi, PIN_readingData); |
uci1 | 116:8099b754fbb4 | 1409 | // reset the digitizer so it will continue waiting for a trigger |
uci1 | 84:80b15993944e | 1410 | PIN_ResetChips = 1; |
uci1 | 84:80b15993944e | 1411 | // wait_us(1); |
uci1 | 84:80b15993944e | 1412 | PIN_ResetChips = 0; |
uci1 | 84:80b15993944e | 1413 | #endif //ATWD4CH |
uci1 | 84:80b15993944e | 1414 | |
uci1 | 84:80b15993944e | 1415 | #ifdef EVT_TIME_PROFILE |
uci1 | 84:80b15993944e | 1416 | gProfiler.stop(); aftReadWv=gProfiler.read_us(); gProfiler.start(); |
uci1 | 84:80b15993944e | 1417 | #endif // EVT_TIME_PROFILE |
uci1 | 84:80b15993944e | 1418 | |
uci1 | 84:80b15993944e | 1419 | gEvent.SetCurMbedTime(); |
uci1 | 84:80b15993944e | 1420 | |
uci1 | 84:80b15993944e | 1421 | Watchdog::kick(); // don't reset! |
uci1 | 84:80b15993944e | 1422 | |
uci1 | 84:80b15993944e | 1423 | #ifdef DEBUG |
uci1 | 84:80b15993944e | 1424 | printf("gFirstEvt=%s\r\n",gFirstEvt?"true":"false"); |
uci1 | 84:80b15993944e | 1425 | #endif |
uci1 | 84:80b15993944e | 1426 | |
uci1 | 84:80b15993944e | 1427 | #if CHIPBOARD==ATWD4CH |
uci1 | 84:80b15993944e | 1428 | PIN_lockRegisters = 0; // done reading, unlock so we can talk to the SD card |
uci1 | 84:80b15993944e | 1429 | #else |
uci1 | 84:80b15993944e | 1430 | // (this is redundant; it's already set low by SnEventFrame) |
uci1 | 84:80b15993944e | 1431 | PIN_readingData = 0; // done reading, unlock so we can talk to the SD card |
uci1 | 84:80b15993944e | 1432 | #endif // ATWD4CH |
uci1 | 84:80b15993944e | 1433 | |
uci1 | 84:80b15993944e | 1434 | #ifdef DEBUG |
uci1 | 84:80b15993944e | 1435 | printf("waveform read out. save event (%u)\r\n", gEvtNum); |
uci1 | 12:d472f9811262 | 1436 | #endif |
uci1 | 3:24c5f0f50bf1 | 1437 | |
uci1 | 0:664899e0b988 | 1438 | // set the event number & dt |
uci1 | 3:24c5f0f50bf1 | 1439 | gEvent.SetEvtNum(gEvtNum); |
uci1 | 0:664899e0b988 | 1440 | gEvent.SetDTms(etms); |
uci1 | 84:80b15993944e | 1441 | // set trigger bits |
uci1 | 84:80b15993944e | 1442 | if (gForcedTrig) { |
uci1 | 84:80b15993944e | 1443 | gEvent.SetTrgBit(kForced); |
uci1 | 84:80b15993944e | 1444 | // gEvent.SetTrgNum(gTrgNum[kFrcTrg]); |
uci1 | 84:80b15993944e | 1445 | gEvent.SetTrgNum(gNumFrcTrigs); |
uci1 | 84:80b15993944e | 1446 | } else { |
uci1 | 84:80b15993944e | 1447 | gEvent.SetTrgBit(kThermal); |
uci1 | 84:80b15993944e | 1448 | // gEvent.SetTrgNum(gTrgNum[kThmTrg]); |
uci1 | 84:80b15993944e | 1449 | gEvent.SetTrgNum(gNumThmTrigs); |
uci1 | 84:80b15993944e | 1450 | } |
uci1 | 84:80b15993944e | 1451 | if (gAdcToMBflag) { |
uci1 | 84:80b15993944e | 1452 | gEvent.SetTrgBit(kAdcToMBflag); |
uci1 | 84:80b15993944e | 1453 | } |
uci1 | 0:664899e0b988 | 1454 | |
uci1 | 84:80b15993944e | 1455 | // this is in the config too, but doesn't hurt to flip the bit |
uci1 | 84:80b15993944e | 1456 | // in the event |
uci1 | 84:80b15993944e | 1457 | if (gConf.IsL1TrigApplied()) { |
uci1 | 84:80b15993944e | 1458 | gEvent.SetTrgBit(kL1TrgApplied); |
uci1 | 84:80b15993944e | 1459 | } |
uci1 | 84:80b15993944e | 1460 | |
uci1 | 84:80b15993944e | 1461 | // ---- |
uci1 | 84:80b15993944e | 1462 | // L1 check(s) go here! |
uci1 | 84:80b15993944e | 1463 | bool L1okToSave = true; |
uci1 | 84:80b15993944e | 1464 | |
uci1 | 84:80b15993944e | 1465 | #ifdef DEBUG |
uci1 | 84:80b15993944e | 1466 | Timer l1timer; |
uci1 | 84:80b15993944e | 1467 | l1timer.start(); |
uci1 | 84:80b15993944e | 1468 | printf("L1 single freq supp ratio = %hhu (%g)\r\n", |
uci1 | 84:80b15993944e | 1469 | gConf.GetSingleFreqSuppRatioRaw(), |
uci1 | 84:80b15993944e | 1470 | gConf.GetSingleFreqSuppRatio()); |
uci1 | 84:80b15993944e | 1471 | #endif |
uci1 | 84:80b15993944e | 1472 | |
uci1 | 116:8099b754fbb4 | 1473 | #ifdef EVT_TIME_PROFILE |
uci1 | 116:8099b754fbb4 | 1474 | gProfiler.stop(); befL1=gProfiler.read_us(); gProfiler.start(); |
uci1 | 116:8099b754fbb4 | 1475 | #endif // EVT_TIME_PROFILE |
uci1 | 116:8099b754fbb4 | 1476 | |
uci1 | 84:80b15993944e | 1477 | // TODO: move the FFT calculation out here so that |
uci1 | 84:80b15993944e | 1478 | // other L1's could use it too. haven't done this already |
uci1 | 84:80b15993944e | 1479 | // in order to save RAM and not cache the whole thing when |
uci1 | 84:80b15993944e | 1480 | // we only have one L1 cut. |
uci1 | 84:80b15993944e | 1481 | |
uci1 | 84:80b15993944e | 1482 | // check L1 single frequency suppression cut |
uci1 | 84:80b15993944e | 1483 | if ( gConf.IsSingleFreqSuppEnabled() ) { |
uci1 | 84:80b15993944e | 1484 | const EL1TrigStatus passL1SingleFreqSupp = |
uci1 | 84:80b15993944e | 1485 | SnL1SingleFreqSupp::ProcessEvent(gEvent, gChanFFT, |
uci1 | 84:80b15993944e | 1486 | gConf.GetSingleFreqSuppRatio()); |
uci1 | 84:80b15993944e | 1487 | #ifdef DEBUG |
uci1 | 84:80b15993944e | 1488 | l1timer.stop(); |
uci1 | 84:80b15993944e | 1489 | printf("L1 single freq supp took [%d] us\r\n", |
uci1 | 84:80b15993944e | 1490 | l1timer.read_us()); |
uci1 | 84:80b15993944e | 1491 | printf("passL1SingleFreqSupp=%s\r\n", |
uci1 | 84:80b15993944e | 1492 | passL1SingleFreqSupp==kL1Pass ? "pass" |
uci1 | 84:80b15993944e | 1493 | : passL1SingleFreqSupp==kL1Fail ? "fail" |
uci1 | 84:80b15993944e | 1494 | : "other"); |
uci1 | 84:80b15993944e | 1495 | #endif |
uci1 | 84:80b15993944e | 1496 | if (passL1SingleFreqSupp==kL1Pass) { |
uci1 | 84:80b15993944e | 1497 | gEvent.SetTrgBit(kSingleFreqSupp); |
uci1 | 84:80b15993944e | 1498 | } else if ( (passL1SingleFreqSupp==kL1Fail) && |
uci1 | 84:80b15993944e | 1499 | gConf.IsL1TrigApplied() ) { |
uci1 | 84:80b15993944e | 1500 | L1okToSave = false; |
uci1 | 84:80b15993944e | 1501 | } |
uci1 | 84:80b15993944e | 1502 | // else if kL1UnableToProcess, the bit won't get set |
uci1 | 84:80b15993944e | 1503 | // but the event can/will be saved |
uci1 | 84:80b15993944e | 1504 | } |
uci1 | 84:80b15993944e | 1505 | |
uci1 | 84:80b15993944e | 1506 | |
uci1 | 84:80b15993944e | 1507 | // NO MORE L1 checks below here! (or the scaledown won't work) |
uci1 | 84:80b15993944e | 1508 | // ----- |
uci1 | 84:80b15993944e | 1509 | |
uci1 | 84:80b15993944e | 1510 | #ifdef EVT_TIME_PROFILE |
uci1 | 116:8099b754fbb4 | 1511 | gProfiler.stop(); aftL1=gProfiler.read_us(); gProfiler.start(); |
uci1 | 84:80b15993944e | 1512 | gProfiler.stop(); befWriteEvt=gProfiler.read_us(); gProfiler.start(); |
uci1 | 84:80b15993944e | 1513 | #endif // EVT_TIME_PROFILE |
uci1 | 84:80b15993944e | 1514 | |
uci1 | 0:664899e0b988 | 1515 | // save to SD |
uci1 | 56:0bba0ef15697 | 1516 | #if CHIPBOARD==ATWD4CH |
uci1 | 56:0bba0ef15697 | 1517 | PIN_lockRegisters = 0; // unlock so we can talk to the SD card |
uci1 | 56:0bba0ef15697 | 1518 | #else |
uci1 | 56:0bba0ef15697 | 1519 | PIN_readingData = 0; // unlock so we can talk to the SD card |
uci1 | 56:0bba0ef15697 | 1520 | #endif |
uci1 | 116:8099b754fbb4 | 1521 | |
uci1 | 84:80b15993944e | 1522 | // scale down to override L1 trigger failures |
uci1 | 84:80b15993944e | 1523 | if ( (L1okToSave==false) && (gConf.GetL1Scaledown()!=0) ) { |
uci1 | 84:80b15993944e | 1524 | ++gL1ScaledownCount; |
uci1 | 84:80b15993944e | 1525 | |
uci1 | 116:8099b754fbb4 | 1526 | // check with >= in case the config changes |
uci1 | 116:8099b754fbb4 | 1527 | if ( gL1ScaledownCount >= gConf.GetL1Scaledown() ) { |
uci1 | 84:80b15993944e | 1528 | gL1ScaledownCount = 0; |
uci1 | 84:80b15993944e | 1529 | L1okToSave = true; |
uci1 | 116:8099b754fbb4 | 1530 | gEvent.SetTrgBit(kL1Scaledown); |
uci1 | 84:80b15993944e | 1531 | #ifdef DEBUG |
uci1 | 84:80b15993944e | 1532 | printf("))) L1 scaledown!\r\n"); |
uci1 | 84:80b15993944e | 1533 | #endif |
uci1 | 84:80b15993944e | 1534 | } |
uci1 | 84:80b15993944e | 1535 | } |
uci1 | 84:80b15993944e | 1536 | |
uci1 | 84:80b15993944e | 1537 | #ifdef DEBUG |
uci1 | 84:80b15993944e | 1538 | printf("L1 scaledown count = %hhu, scaledown=%hhu, L1okToSave=%s\r\n", |
uci1 | 84:80b15993944e | 1539 | gL1ScaledownCount, |
uci1 | 84:80b15993944e | 1540 | gConf.GetL1Scaledown(), |
uci1 | 84:80b15993944e | 1541 | L1okToSave ? "true" : "false"); |
uci1 | 84:80b15993944e | 1542 | printf("event trigger bits = "); |
uci1 | 84:80b15993944e | 1543 | SnBitUtils::printBits(gEvent.GetTrgBits(), true); |
uci1 | 84:80b15993944e | 1544 | #endif |
uci1 | 0:664899e0b988 | 1545 | |
uci1 | 84:80b15993944e | 1546 | // always save forced triggers |
uci1 | 84:80b15993944e | 1547 | if (L1okToSave || gForcedTrig) { |
uci1 | 84:80b15993944e | 1548 | SnSDUtils::WriteEventTo(SnSDUtils::GetCurFile(), gGenBuf, gEvent, gConf); |
uci1 | 84:80b15993944e | 1549 | |
uci1 | 84:80b15993944e | 1550 | // a good event |
uci1 | 84:80b15993944e | 1551 | gStNewEvent = true; |
uci1 | 84:80b15993944e | 1552 | |
uci1 | 116:8099b754fbb4 | 1553 | // mark that the event was actually accepted |
uci1 | 116:8099b754fbb4 | 1554 | didSave = true; |
uci1 | 116:8099b754fbb4 | 1555 | |
uci1 | 84:80b15993944e | 1556 | // send it? |
uci1 | 84:80b15993944e | 1557 | if ( gConf.IsCommWindowEachEvent() ) { |
uci1 | 84:80b15993944e | 1558 | #ifdef DEBUG |
uci1 | 84:80b15993944e | 1559 | printf("COMM EACH EVENT => gOpenCommWin = true\r\n"); |
uci1 | 84:80b15993944e | 1560 | #endif |
uci1 | 84:80b15993944e | 1561 | gOpenCommWin = true; |
uci1 | 84:80b15993944e | 1562 | } |
uci1 | 84:80b15993944e | 1563 | } |
uci1 | 84:80b15993944e | 1564 | |
uci1 | 84:80b15993944e | 1565 | #ifdef EVT_TIME_PROFILE |
uci1 | 84:80b15993944e | 1566 | gProfiler.stop(); aftWriteEvt=gProfiler.read_us(); gProfiler.start(); |
uci1 | 84:80b15993944e | 1567 | printf("befReadWv=%d, aftReadWv=%d, befWriteEvt=%d, aftWriteEvt=%d\r\n", |
uci1 | 84:80b15993944e | 1568 | befReadWv, aftReadWv, befWriteEvt, aftWriteEvt); |
uci1 | 116:8099b754fbb4 | 1569 | printf("befL1=%d, aftL1=%d\r\n", befL1, aftL1); |
uci1 | 84:80b15993944e | 1570 | #endif // EVT_TIME_PROFILE |
uci1 | 84:80b15993944e | 1571 | |
uci1 | 40:1324da35afd4 | 1572 | // make a copy in case we need to send it with the status |
uci1 | 40:1324da35afd4 | 1573 | // (copy it because we are going to clear this event while |
uci1 | 40:1324da35afd4 | 1574 | // waiting for the next trigger) |
uci1 | 84:80b15993944e | 1575 | // gEvent.CopyTo(gLastEvent); |
uci1 | 40:1324da35afd4 | 1576 | |
uci1 | 3:24c5f0f50bf1 | 1577 | // increment event number |
uci1 | 3:24c5f0f50bf1 | 1578 | ++gEvtNum; |
uci1 | 3:24c5f0f50bf1 | 1579 | |
uci1 | 12:d472f9811262 | 1580 | #ifdef DEBUG |
uci1 | 84:80b15993944e | 1581 | printf("next gEvtNum=%u\r\n",gEvtNum); |
uci1 | 12:d472f9811262 | 1582 | #endif |
uci1 | 116:8099b754fbb4 | 1583 | |
uci1 | 116:8099b754fbb4 | 1584 | return didSave; |
uci1 | 3:24c5f0f50bf1 | 1585 | } |
uci1 | 3:24c5f0f50bf1 | 1586 | |
uci1 | 3:24c5f0f50bf1 | 1587 | void MakeOutputFile(const bool stopRunning) { |
uci1 | 56:0bba0ef15697 | 1588 | #if CHIPBOARD==ATWD4CH |
uci1 | 56:0bba0ef15697 | 1589 | PIN_lockRegisters = 0; // unlock so we can talk to the SD card |
uci1 | 56:0bba0ef15697 | 1590 | #else |
uci1 | 56:0bba0ef15697 | 1591 | PIN_readingData = 0; // unlock so we can talk to the SD card |
uci1 | 56:0bba0ef15697 | 1592 | #endif |
uci1 | 12:d472f9811262 | 1593 | #ifdef DEBUG |
uci1 | 10:3c93db1cfb12 | 1594 | printf("closing output file. gEvtNum=%u, gPowNum=%u, stop=%d\r\n", |
uci1 | 10:3c93db1cfb12 | 1595 | gEvtNum,gPowNum,(int)stopRunning); |
uci1 | 12:d472f9811262 | 1596 | #endif |
uci1 | 13:7a1fb885a8e4 | 1597 | |
uci1 | 3:24c5f0f50bf1 | 1598 | SnSDUtils::CloseOutputFile(SnSDUtils::GetCurFile()); |
uci1 | 13:7a1fb885a8e4 | 1599 | |
uci1 | 12:d472f9811262 | 1600 | #ifdef DEBUG |
uci1 | 10:3c93db1cfb12 | 1601 | printf("file closed\r\n"); |
uci1 | 12:d472f9811262 | 1602 | #endif |
uci1 | 3:24c5f0f50bf1 | 1603 | if (stopRunning) { |
uci1 | 8:95a325df1f6b | 1604 | StopRunning(); |
uci1 | 0:664899e0b988 | 1605 | } |
uci1 | 56:0bba0ef15697 | 1606 | FILE* cf = SnSDUtils::OpenNewOutputFile(SnConfigFrame::GetMacAddress(), |
uci1 | 40:1324da35afd4 | 1607 | gConf.GetRun(), |
uci1 | 76:f8383f0292c2 | 1608 | gConf.GetFirstSeq(), |
uci1 | 76:f8383f0292c2 | 1609 | gConf.IsSendingFilesRunSeqList()); |
uci1 | 13:7a1fb885a8e4 | 1610 | // reset event, timers, trigger counters |
uci1 | 84:80b15993944e | 1611 | ResetCounters(); |
uci1 | 8:95a325df1f6b | 1612 | if (cf!=0) { |
uci1 | 40:1324da35afd4 | 1613 | #ifdef USE_RTOS |
uci1 | 40:1324da35afd4 | 1614 | Thread::wait(200); |
uci1 | 40:1324da35afd4 | 1615 | #else |
uci1 | 8:95a325df1f6b | 1616 | wait_ms(200); |
uci1 | 40:1324da35afd4 | 1617 | #endif |
uci1 | 8:95a325df1f6b | 1618 | GetAvePowerReading(); |
uci1 | 12:d472f9811262 | 1619 | #ifdef DEBUG |
uci1 | 8:95a325df1f6b | 1620 | printf("writing power. v1=%g, v2=%g, r1=%g, r2=%g, t=%u, pownum=%u\r\n", |
uci1 | 8:95a325df1f6b | 1621 | gPower.GetAveV1(), gPower.GetAveV2(), |
uci1 | 8:95a325df1f6b | 1622 | gPower.GetRmsV1(), gPower.GetRmsV2(), gPower.GetTime(), |
uci1 | 8:95a325df1f6b | 1623 | gPowNum); |
uci1 | 12:d472f9811262 | 1624 | #endif |
uci1 | 8:95a325df1f6b | 1625 | SnSDUtils::WritePowerTo(cf, gPower, gPowNum); |
uci1 | 8:95a325df1f6b | 1626 | } |
uci1 | 12:d472f9811262 | 1627 | #ifdef DEBUG |
uci1 | 3:24c5f0f50bf1 | 1628 | printf("made output file with run %u\r\n",gConf.GetRun()); |
uci1 | 3:24c5f0f50bf1 | 1629 | printf("filename=%s\r\n",SnSDUtils::GetCurFileName()); |
uci1 | 12:d472f9811262 | 1630 | #endif |
uci1 | 3:24c5f0f50bf1 | 1631 | SnSDUtils::WriteConfig(SnSDUtils::GetCurFile(), gConf); |
uci1 | 19:74155d652c37 | 1632 | #ifdef DEBUG |
uci1 | 19:74155d652c37 | 1633 | printf("write config to file\r\n"); |
uci1 | 19:74155d652c37 | 1634 | #endif |
uci1 | 0:664899e0b988 | 1635 | } |
uci1 | 0:664899e0b988 | 1636 | |
uci1 | 40:1324da35afd4 | 1637 | bool PowerDownCommPeriph(const SnConfigFrame::EDatPackBit type) { |
uci1 | 67:ec999336fcd1 | 1638 | #ifdef DEBUG |
uci1 | 67:ec999336fcd1 | 1639 | printf("PowerDownCommPeriph: type=%d\r\n",(int)type); |
uci1 | 67:ec999336fcd1 | 1640 | #endif |
uci1 | 40:1324da35afd4 | 1641 | SnCommWin** cw = gComms; |
uci1 | 56:0bba0ef15697 | 1642 | for (uint8_t i=0; i<kNcomms; ++i, ++cw) { |
uci1 | 40:1324da35afd4 | 1643 | if ((*cw)==0) { |
uci1 | 40:1324da35afd4 | 1644 | continue; |
uci1 | 40:1324da35afd4 | 1645 | } else if ((*cw)->GetCommType()==type) { |
uci1 | 67:ec999336fcd1 | 1646 | #ifdef DEBUG |
uci1 | 67:ec999336fcd1 | 1647 | printf("calling PowerDown\r\n"); |
uci1 | 67:ec999336fcd1 | 1648 | #endif |
uci1 | 40:1324da35afd4 | 1649 | return (*cw)->PowerDown(gConf.GetTimeoutTime(time(0), |
uci1 | 84:80b15993944e | 1650 | gConf.GetCommWinConnectTO(type))); |
uci1 | 40:1324da35afd4 | 1651 | } |
uci1 | 40:1324da35afd4 | 1652 | } |
uci1 | 40:1324da35afd4 | 1653 | return false; |
uci1 | 40:1324da35afd4 | 1654 | } |
uci1 | 40:1324da35afd4 | 1655 | |
uci1 | 0:664899e0b988 | 1656 | // |
uci1 | 4:a91682e19d6b | 1657 | // power stuff |
uci1 | 4:a91682e19d6b | 1658 | // |
uci1 | 67:ec999336fcd1 | 1659 | bool IsCurrentlyPowered(const SnConfigFrame::EPowerModeBit p, |
uci1 | 67:ec999336fcd1 | 1660 | DigitalOut& pin) { |
uci1 | 67:ec999336fcd1 | 1661 | // check if the current pin value is equal to |
uci1 | 67:ec999336fcd1 | 1662 | // what it should be if the peripheral is on |
uci1 | 67:ec999336fcd1 | 1663 | return gConf.GetPowPinSetting(p, true) == pin.read(); |
uci1 | 67:ec999336fcd1 | 1664 | } |
uci1 | 67:ec999336fcd1 | 1665 | |
uci1 | 84:80b15993944e | 1666 | void ChangeCardPower(const bool isCommWin, |
uci1 | 84:80b15993944e | 1667 | const bool isOn) { |
uci1 | 67:ec999336fcd1 | 1668 | // change cards power |
uci1 | 67:ec999336fcd1 | 1669 | const SnConfigFrame::EPowerModeBit pbit = (isCommWin) |
uci1 | 67:ec999336fcd1 | 1670 | ? SnConfigFrame::kCardComWin |
uci1 | 67:ec999336fcd1 | 1671 | : SnConfigFrame::kCardDatTak; |
uci1 | 84:80b15993944e | 1672 | const int value = gConf.GetPowPinSetting(pbit, isOn); |
uci1 | 21:ce51bb0ba4a5 | 1673 | #ifdef DEBUG |
uci1 | 67:ec999336fcd1 | 1674 | printf("setting cards pin power to %d (comm=%d)\r\n", |
uci1 | 67:ec999336fcd1 | 1675 | value, static_cast<int>(isCommWin)); |
uci1 | 21:ce51bb0ba4a5 | 1676 | #endif |
uci1 | 67:ec999336fcd1 | 1677 | PIN_turn_on_system = value; |
uci1 | 40:1324da35afd4 | 1678 | #ifdef USE_RTOS |
uci1 | 40:1324da35afd4 | 1679 | Thread::wait(10); |
uci1 | 40:1324da35afd4 | 1680 | #else |
uci1 | 30:f869ed4bcc08 | 1681 | wait_ms(10); |
uci1 | 40:1324da35afd4 | 1682 | #endif |
uci1 | 67:ec999336fcd1 | 1683 | } |
uci1 | 67:ec999336fcd1 | 1684 | |
uci1 | 84:80b15993944e | 1685 | void ChangeAmpsPower(const bool isCommWin, |
uci1 | 84:80b15993944e | 1686 | const bool isOn) { |
uci1 | 40:1324da35afd4 | 1687 | // change amps power |
uci1 | 67:ec999336fcd1 | 1688 | const SnConfigFrame::EPowerModeBit pbit = (isCommWin) |
uci1 | 67:ec999336fcd1 | 1689 | ? SnConfigFrame::kAmpsComWin |
uci1 | 67:ec999336fcd1 | 1690 | : SnConfigFrame::kAmpsDatTak; |
uci1 | 84:80b15993944e | 1691 | const int value = gConf.GetPowPinSetting(pbit, isOn); |
uci1 | 40:1324da35afd4 | 1692 | #ifdef DEBUG |
uci1 | 67:ec999336fcd1 | 1693 | printf("setting amps pin power to %d (comm=%d)\r\n", |
uci1 | 67:ec999336fcd1 | 1694 | value, static_cast<int>(isCommWin)); |
uci1 | 40:1324da35afd4 | 1695 | #endif |
uci1 | 67:ec999336fcd1 | 1696 | PIN_turn_on_amps = value; |
uci1 | 40:1324da35afd4 | 1697 | #ifdef USE_RTOS |
uci1 | 40:1324da35afd4 | 1698 | Thread::wait(10); |
uci1 | 40:1324da35afd4 | 1699 | #else |
uci1 | 30:f869ed4bcc08 | 1700 | wait_ms(10); |
uci1 | 40:1324da35afd4 | 1701 | #endif |
uci1 | 67:ec999336fcd1 | 1702 | } |
uci1 | 67:ec999336fcd1 | 1703 | |
uci1 | 84:80b15993944e | 1704 | void ChangeIridPower(const bool isCommWin, |
uci1 | 84:80b15993944e | 1705 | const bool isOn) { |
uci1 | 67:ec999336fcd1 | 1706 | // change iridium power setting |
uci1 | 67:ec999336fcd1 | 1707 | // if going from ON to OFF, call the special |
uci1 | 67:ec999336fcd1 | 1708 | // power down procedure, so as not to lose |
uci1 | 67:ec999336fcd1 | 1709 | // the non-volatile memory settings |
uci1 | 67:ec999336fcd1 | 1710 | |
uci1 | 67:ec999336fcd1 | 1711 | const SnConfigFrame::EPowerModeBit ibit = (isCommWin) |
uci1 | 67:ec999336fcd1 | 1712 | ? SnConfigFrame::kIridComWin |
uci1 | 67:ec999336fcd1 | 1713 | : SnConfigFrame::kIridDatTak; |
uci1 | 67:ec999336fcd1 | 1714 | const SnConfigFrame::EPowerModeBit abit = (isCommWin) |
uci1 | 67:ec999336fcd1 | 1715 | ? SnConfigFrame::kAfarComWin |
uci1 | 67:ec999336fcd1 | 1716 | : SnConfigFrame::kAfarDatTak; |
uci1 | 67:ec999336fcd1 | 1717 | |
uci1 | 67:ec999336fcd1 | 1718 | // these checks are complicated because the iridium might |
uci1 | 67:ec999336fcd1 | 1719 | // be powered off the Afar (12V) relay, |
uci1 | 67:ec999336fcd1 | 1720 | // rather than the iridium (5V) relay |
uci1 | 67:ec999336fcd1 | 1721 | const bool iridFromOn = (kIridPwrFromAfar) ? |
uci1 | 67:ec999336fcd1 | 1722 | IsCurrentlyPowered(abit, PIN_afar_power) : |
uci1 | 67:ec999336fcd1 | 1723 | IsCurrentlyPowered(ibit, PIN_iridSbd_power); |
uci1 | 84:80b15993944e | 1724 | if ( iridFromOn && (isOn==false) ) { |
uci1 | 40:1324da35afd4 | 1725 | #ifdef DEBUG |
uci1 | 40:1324da35afd4 | 1726 | printf("calling PowerDown for Iridium\r\n"); |
uci1 | 40:1324da35afd4 | 1727 | #endif |
uci1 | 40:1324da35afd4 | 1728 | PowerDownCommPeriph(SnConfigFrame::kIrid); |
uci1 | 40:1324da35afd4 | 1729 | } |
uci1 | 67:ec999336fcd1 | 1730 | const int value = (kIridPwrFromAfar) |
uci1 | 67:ec999336fcd1 | 1731 | ? gConf.GetPowPinSetting(ibit, false) // leave the iridium relay off. use afar relay. |
uci1 | 84:80b15993944e | 1732 | : gConf.GetPowPinSetting(ibit, isOn); |
uci1 | 40:1324da35afd4 | 1733 | #ifdef DEBUG |
uci1 | 67:ec999336fcd1 | 1734 | printf("setting iridium pin power to %d (comm=%d)\r\n", |
uci1 | 67:ec999336fcd1 | 1735 | value, static_cast<int>(isCommWin)); |
uci1 | 40:1324da35afd4 | 1736 | #endif |
uci1 | 67:ec999336fcd1 | 1737 | PIN_iridSbd_power = value; |
uci1 | 40:1324da35afd4 | 1738 | #ifdef USE_RTOS |
uci1 | 40:1324da35afd4 | 1739 | Thread::wait(10); |
uci1 | 40:1324da35afd4 | 1740 | #else |
uci1 | 30:f869ed4bcc08 | 1741 | wait_ms(10); |
uci1 | 40:1324da35afd4 | 1742 | #endif |
uci1 | 67:ec999336fcd1 | 1743 | |
uci1 | 67:ec999336fcd1 | 1744 | } |
uci1 | 67:ec999336fcd1 | 1745 | |
uci1 | 84:80b15993944e | 1746 | void ChangeAfarPower(const bool isCommWin, |
uci1 | 84:80b15993944e | 1747 | const bool isOn) { |
uci1 | 67:ec999336fcd1 | 1748 | // change the AFAR relay power setting |
uci1 | 67:ec999336fcd1 | 1749 | // also power up or down the ethernet PHY port |
uci1 | 67:ec999336fcd1 | 1750 | // as appropriate |
uci1 | 67:ec999336fcd1 | 1751 | // the procedure is complicated by the fact that |
uci1 | 67:ec999336fcd1 | 1752 | // the iridium may be powered off the Afar (12V) relay, |
uci1 | 67:ec999336fcd1 | 1753 | // in which case we need to turn this relay on if |
uci1 | 67:ec999336fcd1 | 1754 | // *either* Afar or iridium want power |
uci1 | 67:ec999336fcd1 | 1755 | #ifdef DEBUG |
uci1 | 67:ec999336fcd1 | 1756 | printf("bef: pconp=%u (%08x), pcenet=%u (%08x)\r\n", |
uci1 | 67:ec999336fcd1 | 1757 | LPC_SC->PCONP, LPC_SC->PCONP, LPC1768_PCONP_PCENET, LPC1768_PCONP_PCENET); |
uci1 | 67:ec999336fcd1 | 1758 | printf("pcenet bef power: status=%d\r\n",Peripheral_GetStatus(LPC1768_PCONP_PCENET)); |
uci1 | 67:ec999336fcd1 | 1759 | #endif |
uci1 | 67:ec999336fcd1 | 1760 | |
uci1 | 67:ec999336fcd1 | 1761 | const SnConfigFrame::EPowerModeBit abit = (isCommWin) |
uci1 | 67:ec999336fcd1 | 1762 | ? SnConfigFrame::kAfarComWin |
uci1 | 67:ec999336fcd1 | 1763 | : SnConfigFrame::kAfarDatTak; |
uci1 | 67:ec999336fcd1 | 1764 | |
uci1 | 67:ec999336fcd1 | 1765 | const bool afarFromOn = IsCurrentlyPowered(abit, PIN_afar_power); |
uci1 | 67:ec999336fcd1 | 1766 | |
uci1 | 40:1324da35afd4 | 1767 | // change ethernet PHY port power |
uci1 | 21:ce51bb0ba4a5 | 1768 | #ifdef DEBUG |
uci1 | 67:ec999336fcd1 | 1769 | printf("afar pin=%d, afarFromOn=%d, afarToOn=%d\r\n", |
uci1 | 67:ec999336fcd1 | 1770 | PIN_afar_power.read(), static_cast<int>(afarFromOn), |
uci1 | 84:80b15993944e | 1771 | static_cast<int>(isOn)); |
uci1 | 21:ce51bb0ba4a5 | 1772 | #endif |
uci1 | 84:80b15993944e | 1773 | if (isOn) { |
uci1 | 21:ce51bb0ba4a5 | 1774 | #ifdef DEBUG |
uci1 | 30:f869ed4bcc08 | 1775 | printf("PHY cowin powering up\r\n"); |
uci1 | 21:ce51bb0ba4a5 | 1776 | #endif |
uci1 | 40:1324da35afd4 | 1777 | PHY_PowerUp(); |
uci1 | 40:1324da35afd4 | 1778 | #ifdef USE_RTOS |
uci1 | 40:1324da35afd4 | 1779 | Thread::wait(1000); |
uci1 | 40:1324da35afd4 | 1780 | #else |
uci1 | 40:1324da35afd4 | 1781 | wait(1); |
uci1 | 40:1324da35afd4 | 1782 | #endif |
uci1 | 21:ce51bb0ba4a5 | 1783 | #ifdef DEBUG |
uci1 | 30:f869ed4bcc08 | 1784 | printf("PHY cowin powered up\r\n"); |
uci1 | 21:ce51bb0ba4a5 | 1785 | #endif |
uci1 | 4:a91682e19d6b | 1786 | } else { |
uci1 | 40:1324da35afd4 | 1787 | // change afar power |
uci1 | 40:1324da35afd4 | 1788 | // power down periph if going from on to off |
uci1 | 40:1324da35afd4 | 1789 | // change afar power |
uci1 | 40:1324da35afd4 | 1790 | if (afarFromOn) { |
uci1 | 40:1324da35afd4 | 1791 | PowerDownCommPeriph(SnConfigFrame::kAfar); |
uci1 | 40:1324da35afd4 | 1792 | } |
uci1 | 21:ce51bb0ba4a5 | 1793 | #ifdef DEBUG |
uci1 | 30:f869ed4bcc08 | 1794 | printf("PHY cowin powering down\r\n"); |
uci1 | 21:ce51bb0ba4a5 | 1795 | #endif |
uci1 | 40:1324da35afd4 | 1796 | PHY_PowerDown(); |
uci1 | 40:1324da35afd4 | 1797 | #ifdef USE_RTOS |
uci1 | 40:1324da35afd4 | 1798 | Thread::wait(1000); |
uci1 | 40:1324da35afd4 | 1799 | #else |
uci1 | 40:1324da35afd4 | 1800 | wait(1); |
uci1 | 40:1324da35afd4 | 1801 | #endif |
uci1 | 21:ce51bb0ba4a5 | 1802 | #ifdef DEBUG |
uci1 | 30:f869ed4bcc08 | 1803 | printf("PHY cowin powered down\r\n"); |
uci1 | 21:ce51bb0ba4a5 | 1804 | #endif |
uci1 | 30:f869ed4bcc08 | 1805 | } |
uci1 | 21:ce51bb0ba4a5 | 1806 | #ifdef DEBUG |
uci1 | 30:f869ed4bcc08 | 1807 | printf("PHY done\r\n"); |
uci1 | 21:ce51bb0ba4a5 | 1808 | #endif |
uci1 | 40:1324da35afd4 | 1809 | #ifdef USE_RTOS |
uci1 | 40:1324da35afd4 | 1810 | Thread::wait(100); |
uci1 | 40:1324da35afd4 | 1811 | #else |
uci1 | 30:f869ed4bcc08 | 1812 | wait_ms(100); |
uci1 | 40:1324da35afd4 | 1813 | #endif |
uci1 | 67:ec999336fcd1 | 1814 | |
uci1 | 40:1324da35afd4 | 1815 | // change afar power |
uci1 | 84:80b15993944e | 1816 | const int value = gConf.GetPowPinSetting(abit, isOn); |
uci1 | 67:ec999336fcd1 | 1817 | PIN_afar_power = value; |
uci1 | 40:1324da35afd4 | 1818 | #ifdef USE_RTOS |
uci1 | 40:1324da35afd4 | 1819 | Thread::wait(1500); |
uci1 | 40:1324da35afd4 | 1820 | #else |
uci1 | 40:1324da35afd4 | 1821 | wait(1.5); |
uci1 | 40:1324da35afd4 | 1822 | #endif |
uci1 | 12:d472f9811262 | 1823 | #ifdef DEBUG |
uci1 | 21:ce51bb0ba4a5 | 1824 | printf("aft: pconp=%u (%08x), pcenet=%u (%08x)\r\n", |
uci1 | 21:ce51bb0ba4a5 | 1825 | LPC_SC->PCONP, LPC_SC->PCONP, LPC1768_PCONP_PCENET, LPC1768_PCONP_PCENET); |
uci1 | 67:ec999336fcd1 | 1826 | printf("pcenet aft power: status=%d\r\n",Peripheral_GetStatus(LPC1768_PCONP_PCENET)); |
uci1 | 21:ce51bb0ba4a5 | 1827 | #endif |
uci1 | 67:ec999336fcd1 | 1828 | |
uci1 | 67:ec999336fcd1 | 1829 | } |
uci1 | 67:ec999336fcd1 | 1830 | |
uci1 | 84:80b15993944e | 1831 | bool IsPowerAllowedFor(const bool isCommWin, |
uci1 | 84:80b15993944e | 1832 | const uint8_t devicesInUse, |
uci1 | 84:80b15993944e | 1833 | const SnConfigFrame::EDatPackBit b) { |
uci1 | 84:80b15993944e | 1834 | if (isCommWin && (gConf.IsCommPowerSimple()==false)) { |
uci1 | 84:80b15993944e | 1835 | return ( (devicesInUse & b)!=0 ); |
uci1 | 84:80b15993944e | 1836 | } |
uci1 | 84:80b15993944e | 1837 | return true; |
uci1 | 84:80b15993944e | 1838 | } |
uci1 | 84:80b15993944e | 1839 | |
uci1 | 84:80b15993944e | 1840 | void SetPower(const bool isCommWin, |
uci1 | 84:80b15993944e | 1841 | const uint8_t devicesInUse) { |
uci1 | 84:80b15993944e | 1842 | // devicesInUse could really just be a second set of "power mode" bits |
uci1 | 84:80b15993944e | 1843 | // where the bit being on means "I want to change power for this device" |
uci1 | 84:80b15993944e | 1844 | // but then.. how to handle the possibility that the bit word contains, |
uci1 | 84:80b15993944e | 1845 | // for example, both bits AfarDatTak and AfarComWin being on? |
uci1 | 84:80b15993944e | 1846 | // so instead, we keep the "isCommWin" boolean which forces the separation |
uci1 | 84:80b15993944e | 1847 | // and deviceInUse is only applied when isCommWin==true |
uci1 | 84:80b15993944e | 1848 | // |
uci1 | 84:80b15993944e | 1849 | // multiple devices can be specified by, e.g., kIrid | kAfar |
uci1 | 67:ec999336fcd1 | 1850 | #ifdef DEBUG |
uci1 | 67:ec999336fcd1 | 1851 | printf("set power. isCommWin=%s\r\n",(isCommWin)?"true":"false"); |
uci1 | 67:ec999336fcd1 | 1852 | printf("WD reset = %d\r\n",(int)Watchdog::didWatchdogReset()); |
uci1 | 67:ec999336fcd1 | 1853 | printf("power word (%hhu): ",gConf.GetPowerMode()); SnBitUtils::printBits(gConf.GetPowerMode(),true); |
uci1 | 67:ec999336fcd1 | 1854 | printf("IsPoweredFor CardDatTak = %d\r\n",(int)gConf.IsPoweredFor(SnConfigFrame::kCardDatTak)); |
uci1 | 67:ec999336fcd1 | 1855 | printf("IsPoweredFor AmpsDatTak = %d\r\n",(int)gConf.IsPoweredFor(SnConfigFrame::kAmpsDatTak)); |
uci1 | 67:ec999336fcd1 | 1856 | printf("IsPoweredFor IridDatTak = %d\r\n",(int)gConf.IsPoweredFor(SnConfigFrame::kIridDatTak)); |
uci1 | 67:ec999336fcd1 | 1857 | printf("IsPoweredFor AfarDatTak = %d\r\n",(int)gConf.IsPoweredFor(SnConfigFrame::kAfarDatTak)); |
uci1 | 67:ec999336fcd1 | 1858 | printf("IsPoweredFor CardComWin = %d\r\n",(int)gConf.IsPoweredFor(SnConfigFrame::kCardComWin)); |
uci1 | 67:ec999336fcd1 | 1859 | printf("IsPoweredFor AmpsComWin = %d\r\n",(int)gConf.IsPoweredFor(SnConfigFrame::kAmpsComWin)); |
uci1 | 67:ec999336fcd1 | 1860 | printf("IsPoweredFor IridComWin = %d\r\n",(int)gConf.IsPoweredFor(SnConfigFrame::kIridComWin)); |
uci1 | 67:ec999336fcd1 | 1861 | printf("IsPoweredFor AfarComWin = %d\r\n",(int)gConf.IsPoweredFor(SnConfigFrame::kAfarComWin)); |
uci1 | 84:80b15993944e | 1862 | printf("devicesInUse = %hhu\r\n", (uint8_t)devicesInUse); |
uci1 | 84:80b15993944e | 1863 | printf("IsCommPowerSimple = %s\r\n", (gConf.IsCommPowerSimple() ? "true" : "false")); |
uci1 | 67:ec999336fcd1 | 1864 | #endif |
uci1 | 67:ec999336fcd1 | 1865 | |
uci1 | 67:ec999336fcd1 | 1866 | const SnConfigFrame::EPowerModeBit cardpb = (isCommWin) |
uci1 | 67:ec999336fcd1 | 1867 | ? SnConfigFrame::kCardComWin |
uci1 | 67:ec999336fcd1 | 1868 | : SnConfigFrame::kCardDatTak; |
uci1 | 67:ec999336fcd1 | 1869 | const SnConfigFrame::EPowerModeBit ampspb = (isCommWin) |
uci1 | 67:ec999336fcd1 | 1870 | ? SnConfigFrame::kAmpsComWin |
uci1 | 67:ec999336fcd1 | 1871 | : SnConfigFrame::kAmpsDatTak; |
uci1 | 67:ec999336fcd1 | 1872 | const SnConfigFrame::EPowerModeBit iridpb = (isCommWin) |
uci1 | 67:ec999336fcd1 | 1873 | ? SnConfigFrame::kIridComWin |
uci1 | 67:ec999336fcd1 | 1874 | : SnConfigFrame::kIridDatTak; |
uci1 | 67:ec999336fcd1 | 1875 | const SnConfigFrame::EPowerModeBit afarpb = (isCommWin) |
uci1 | 67:ec999336fcd1 | 1876 | ? SnConfigFrame::kAfarComWin |
uci1 | 67:ec999336fcd1 | 1877 | : SnConfigFrame::kAfarDatTak; |
uci1 | 67:ec999336fcd1 | 1878 | |
uci1 | 67:ec999336fcd1 | 1879 | // |
uci1 | 67:ec999336fcd1 | 1880 | // FIRST turn the things off that should be off. |
uci1 | 67:ec999336fcd1 | 1881 | // this prevents short periods of high power usage |
uci1 | 67:ec999336fcd1 | 1882 | // |
uci1 | 67:ec999336fcd1 | 1883 | |
uci1 | 84:80b15993944e | 1884 | const bool cardToOn = gConf.IsPoweredFor(cardpb); |
uci1 | 84:80b15993944e | 1885 | const bool ampsToOn = gConf.IsPoweredFor(ampspb); |
uci1 | 84:80b15993944e | 1886 | |
uci1 | 84:80b15993944e | 1887 | // these are complicated because iridium might |
uci1 | 67:ec999336fcd1 | 1888 | // be powered off of the afar line |
uci1 | 84:80b15993944e | 1889 | // also ignore the devices in use if we're not in a comm window |
uci1 | 67:ec999336fcd1 | 1890 | const bool iridToOn = (kIridPwrFromAfar) ? |
uci1 | 84:80b15993944e | 1891 | (gConf.IsPoweredFor(afarpb) && IsPowerAllowedFor(isCommWin, devicesInUse, SnConfigFrame::kIrid)) : |
uci1 | 84:80b15993944e | 1892 | (gConf.IsPoweredFor(iridpb) && IsPowerAllowedFor(isCommWin, devicesInUse, SnConfigFrame::kIrid)); |
uci1 | 84:80b15993944e | 1893 | const bool afarToOn = (kIridPwrFromAfar) ? |
uci1 | 84:80b15993944e | 1894 | ( (gConf.IsPoweredFor(afarpb) && IsPowerAllowedFor(isCommWin, devicesInUse, SnConfigFrame::kAfar)) |
uci1 | 84:80b15993944e | 1895 | ||(gConf.IsPoweredFor(iridpb) && IsPowerAllowedFor(isCommWin, devicesInUse, SnConfigFrame::kIrid)) ) : |
uci1 | 84:80b15993944e | 1896 | (gConf.IsPoweredFor(afarpb) && IsPowerAllowedFor(isCommWin, devicesInUse, SnConfigFrame::kAfar)); |
uci1 | 67:ec999336fcd1 | 1897 | |
uci1 | 84:80b15993944e | 1898 | if (cardToOn==false) { |
uci1 | 67:ec999336fcd1 | 1899 | #ifdef DEBUG |
uci1 | 67:ec999336fcd1 | 1900 | printf("power down cards\r\n"); |
uci1 | 67:ec999336fcd1 | 1901 | #endif |
uci1 | 84:80b15993944e | 1902 | ChangeCardPower(isCommWin, cardToOn); |
uci1 | 67:ec999336fcd1 | 1903 | } |
uci1 | 84:80b15993944e | 1904 | if (ampsToOn==false) { |
uci1 | 67:ec999336fcd1 | 1905 | #ifdef DEBUG |
uci1 | 67:ec999336fcd1 | 1906 | printf("power down amps\r\n"); |
uci1 | 67:ec999336fcd1 | 1907 | printf("ampspb=%d, is powered for =%d\r\n", |
uci1 | 67:ec999336fcd1 | 1908 | (int)ampspb, |
uci1 | 67:ec999336fcd1 | 1909 | (int)(gConf.IsPoweredFor(ampspb))); |
uci1 | 67:ec999336fcd1 | 1910 | printf("is powered amps dat tak = %d, amps com win = %d\r\n", |
uci1 | 67:ec999336fcd1 | 1911 | (int)(gConf.IsPoweredFor(SnConfigFrame::kAmpsDatTak)), |
uci1 | 67:ec999336fcd1 | 1912 | (int)(gConf.IsPoweredFor(SnConfigFrame::kAmpsComWin))); |
uci1 | 67:ec999336fcd1 | 1913 | #endif |
uci1 | 84:80b15993944e | 1914 | ChangeAmpsPower(isCommWin, ampsToOn); |
uci1 | 67:ec999336fcd1 | 1915 | } |
uci1 | 67:ec999336fcd1 | 1916 | if (iridToOn==false) { |
uci1 | 67:ec999336fcd1 | 1917 | #ifdef DEBUG |
uci1 | 67:ec999336fcd1 | 1918 | printf("power down irid\r\n"); |
uci1 | 67:ec999336fcd1 | 1919 | #endif |
uci1 | 84:80b15993944e | 1920 | ChangeIridPower(isCommWin, iridToOn); |
uci1 | 67:ec999336fcd1 | 1921 | } |
uci1 | 67:ec999336fcd1 | 1922 | if (afarToOn==false) { |
uci1 | 67:ec999336fcd1 | 1923 | #ifdef DEBUG |
uci1 | 67:ec999336fcd1 | 1924 | printf("power down afar\r\n"); |
uci1 | 67:ec999336fcd1 | 1925 | #endif |
uci1 | 84:80b15993944e | 1926 | ChangeAfarPower(isCommWin, afarToOn); |
uci1 | 67:ec999336fcd1 | 1927 | } |
uci1 | 67:ec999336fcd1 | 1928 | |
uci1 | 67:ec999336fcd1 | 1929 | // |
uci1 | 67:ec999336fcd1 | 1930 | // THEN turn on things that want to go on |
uci1 | 67:ec999336fcd1 | 1931 | // |
uci1 | 84:80b15993944e | 1932 | if (cardToOn) { |
uci1 | 67:ec999336fcd1 | 1933 | #ifdef DEBUG |
uci1 | 67:ec999336fcd1 | 1934 | printf("power ON cards\r\n"); |
uci1 | 67:ec999336fcd1 | 1935 | #endif |
uci1 | 84:80b15993944e | 1936 | ChangeCardPower(isCommWin, cardToOn); |
uci1 | 67:ec999336fcd1 | 1937 | } |
uci1 | 84:80b15993944e | 1938 | if (ampsToOn) { |
uci1 | 67:ec999336fcd1 | 1939 | #ifdef DEBUG |
uci1 | 67:ec999336fcd1 | 1940 | printf("power ON amps\r\n"); |
uci1 | 67:ec999336fcd1 | 1941 | #endif |
uci1 | 84:80b15993944e | 1942 | ChangeAmpsPower(isCommWin, ampsToOn); |
uci1 | 67:ec999336fcd1 | 1943 | } |
uci1 | 67:ec999336fcd1 | 1944 | if (iridToOn) { |
uci1 | 67:ec999336fcd1 | 1945 | #ifdef DEBUG |
uci1 | 67:ec999336fcd1 | 1946 | printf("power ON iridium\r\n"); |
uci1 | 67:ec999336fcd1 | 1947 | #endif |
uci1 | 84:80b15993944e | 1948 | ChangeIridPower(isCommWin, iridToOn); |
uci1 | 67:ec999336fcd1 | 1949 | } |
uci1 | 67:ec999336fcd1 | 1950 | if (afarToOn) { |
uci1 | 67:ec999336fcd1 | 1951 | #ifdef DEBUG |
uci1 | 67:ec999336fcd1 | 1952 | printf("power ON afar\r\n"); |
uci1 | 67:ec999336fcd1 | 1953 | #endif |
uci1 | 84:80b15993944e | 1954 | ChangeAfarPower(isCommWin, afarToOn); |
uci1 | 67:ec999336fcd1 | 1955 | } |
uci1 | 67:ec999336fcd1 | 1956 | |
uci1 | 21:ce51bb0ba4a5 | 1957 | #ifdef DEBUG |
uci1 | 16:744ce85aede2 | 1958 | printf("power word (%hhu): ",gConf.GetPowerMode()); SnBitUtils::printBits(gConf.GetPowerMode(),true); |
uci1 | 6:6f002d202f59 | 1959 | printf("set power (iscom %d, pw %hhu): cards %d, amps %d, irid %d, afar %d\r\n", |
uci1 | 6:6f002d202f59 | 1960 | isCommWin, gConf.GetPowerMode(), PIN_turn_on_system.read(), PIN_turn_on_amps.read(), |
uci1 | 6:6f002d202f59 | 1961 | PIN_iridSbd_power.read(), PIN_afar_power.read()); |
uci1 | 12:d472f9811262 | 1962 | #endif |
uci1 | 4:a91682e19d6b | 1963 | } |
uci1 | 4:a91682e19d6b | 1964 | |
uci1 | 4:a91682e19d6b | 1965 | // |
uci1 | 119:b3d7699d0eb0 | 1966 | // trigger board setup |
uci1 | 119:b3d7699d0eb0 | 1967 | // |
uci1 | 119:b3d7699d0eb0 | 1968 | #if CHIPBOARD==ATWD4CH |
uci1 | 119:b3d7699d0eb0 | 1969 | void SetAtwdPlas() { |
uci1 | 119:b3d7699d0eb0 | 1970 | uint16_t hi, lo; |
uci1 | 119:b3d7699d0eb0 | 1971 | PIN_PLA_cs=1; |
uci1 | 119:b3d7699d0eb0 | 1972 | #ifdef USE_RTOS |
uci1 | 119:b3d7699d0eb0 | 1973 | Thread::wait(4000); |
uci1 | 119:b3d7699d0eb0 | 1974 | #else |
uci1 | 119:b3d7699d0eb0 | 1975 | wait(4); |
uci1 | 119:b3d7699d0eb0 | 1976 | #endif |
uci1 | 119:b3d7699d0eb0 | 1977 | for (uint8_t pi=0; pi<kNplas; ++pi) { |
uci1 | 119:b3d7699d0eb0 | 1978 | if (pi < gConf.GetNumPlas()) { |
uci1 | 119:b3d7699d0eb0 | 1979 | SnConfigFrame::GetHiLoPlas(gConf.GetPla(pi), hi, lo); |
uci1 | 119:b3d7699d0eb0 | 1980 | PIN_spi.write(hi); |
uci1 | 119:b3d7699d0eb0 | 1981 | PIN_spi.write(lo); |
uci1 | 119:b3d7699d0eb0 | 1982 | #ifdef DEBUG |
uci1 | 119:b3d7699d0eb0 | 1983 | printf("pla hi %hu, lo %hu\r\n",hi,lo); |
uci1 | 119:b3d7699d0eb0 | 1984 | #endif |
uci1 | 119:b3d7699d0eb0 | 1985 | } else { |
uci1 | 119:b3d7699d0eb0 | 1986 | PIN_spi.write(kNoTrigPla); // hi |
uci1 | 119:b3d7699d0eb0 | 1987 | PIN_spi.write(kNoTrigPla); // lo |
uci1 | 119:b3d7699d0eb0 | 1988 | #ifdef DEBUG |
uci1 | 119:b3d7699d0eb0 | 1989 | printf("pla hi %hu, lo %hu\r\n",kNoTrigPla,kNoTrigPla); |
uci1 | 119:b3d7699d0eb0 | 1990 | #endif |
uci1 | 119:b3d7699d0eb0 | 1991 | } |
uci1 | 119:b3d7699d0eb0 | 1992 | Watchdog::kick(); |
uci1 | 119:b3d7699d0eb0 | 1993 | } |
uci1 | 119:b3d7699d0eb0 | 1994 | #ifdef USE_RTOS |
uci1 | 119:b3d7699d0eb0 | 1995 | Thread::wait(3000); |
uci1 | 119:b3d7699d0eb0 | 1996 | #else |
uci1 | 119:b3d7699d0eb0 | 1997 | wait(3); |
uci1 | 119:b3d7699d0eb0 | 1998 | #endif |
uci1 | 119:b3d7699d0eb0 | 1999 | PIN_PLA_cs=0; |
uci1 | 119:b3d7699d0eb0 | 2000 | #ifdef USE_RTOS |
uci1 | 119:b3d7699d0eb0 | 2001 | Thread::wait(3000); |
uci1 | 119:b3d7699d0eb0 | 2002 | #else |
uci1 | 119:b3d7699d0eb0 | 2003 | wait(3); |
uci1 | 119:b3d7699d0eb0 | 2004 | #endif |
uci1 | 119:b3d7699d0eb0 | 2005 | } |
uci1 | 119:b3d7699d0eb0 | 2006 | |
uci1 | 119:b3d7699d0eb0 | 2007 | void SetAtwdDACs() { |
uci1 | 119:b3d7699d0eb0 | 2008 | // DAC values |
uci1 | 119:b3d7699d0eb0 | 2009 | // |
uci1 | 119:b3d7699d0eb0 | 2010 | // first 12 bits = DAC value |
uci1 | 119:b3d7699d0eb0 | 2011 | // next 2 bits = DAC ID |
uci1 | 119:b3d7699d0eb0 | 2012 | // last 2 bits = dFPGA ID |
uci1 | 119:b3d7699d0eb0 | 2013 | // |
uci1 | 119:b3d7699d0eb0 | 2014 | // But FPGA uses "gray encoding" which means only 1 bit |
uci1 | 119:b3d7699d0eb0 | 2015 | // can change at a time (of the last 4 bits). So even tho |
uci1 | 119:b3d7699d0eb0 | 2016 | // the card/dac# is encoded, the order is also important |
uci1 | 119:b3d7699d0eb0 | 2017 | // 0000 (dac0,card0), 0001 (dac0,card1), 0011 (dac0,card3), 0010 (dac0,card2), |
uci1 | 119:b3d7699d0eb0 | 2018 | // 0110 (dac1,card2), 0111 (dac1,card3), 0101 (dac1,card1), etc. |
uci1 | 119:b3d7699d0eb0 | 2019 | #ifdef DEBUG |
uci1 | 119:b3d7699d0eb0 | 2020 | printf("setting dacs\r\n"); |
uci1 | 119:b3d7699d0eb0 | 2021 | #endif |
uci1 | 119:b3d7699d0eb0 | 2022 | uint16_t dv=0; |
uci1 | 119:b3d7699d0eb0 | 2023 | for (uint8_t i=0, gri=0; i<kTotDacs; ++i) { |
uci1 | 119:b3d7699d0eb0 | 2024 | // get the gray-codes for this iteration |
uci1 | 119:b3d7699d0eb0 | 2025 | gri = SnBitUtils::binToGray(i); |
uci1 | 119:b3d7699d0eb0 | 2026 | |
uci1 | 119:b3d7699d0eb0 | 2027 | // build bit word |
uci1 | 119:b3d7699d0eb0 | 2028 | dv = static_cast<int>(gConf.GetDac(gri & 0x0003u, gri >> 2u)); |
uci1 | 119:b3d7699d0eb0 | 2029 | dv <<= 4u; |
uci1 | 119:b3d7699d0eb0 | 2030 | dv |= gri; |
uci1 | 119:b3d7699d0eb0 | 2031 | |
uci1 | 119:b3d7699d0eb0 | 2032 | #ifdef DEBUG |
uci1 | 119:b3d7699d0eb0 | 2033 | printf("dac %04x\r\n",dv); |
uci1 | 119:b3d7699d0eb0 | 2034 | #endif |
uci1 | 119:b3d7699d0eb0 | 2035 | |
uci1 | 119:b3d7699d0eb0 | 2036 | // send to FPGA |
uci1 | 119:b3d7699d0eb0 | 2037 | PIN_start_fpga=1; |
uci1 | 119:b3d7699d0eb0 | 2038 | PIN_spi.write(dv); |
uci1 | 119:b3d7699d0eb0 | 2039 | PIN_start_fpga=0; |
uci1 | 119:b3d7699d0eb0 | 2040 | |
uci1 | 119:b3d7699d0eb0 | 2041 | Watchdog::kick(); |
uci1 | 119:b3d7699d0eb0 | 2042 | |
uci1 | 119:b3d7699d0eb0 | 2043 | } |
uci1 | 119:b3d7699d0eb0 | 2044 | } |
uci1 | 119:b3d7699d0eb0 | 2045 | #endif // ATWD4CH |
uci1 | 119:b3d7699d0eb0 | 2046 | |
uci1 | 119:b3d7699d0eb0 | 2047 | #if CHIPBOARD!=ATWD4CH |
uci1 | 119:b3d7699d0eb0 | 2048 | void SetSstDACs() { |
uci1 | 119:b3d7699d0eb0 | 2049 | // set and/or & differential pins |
uci1 | 119:b3d7699d0eb0 | 2050 | // set DACs via I2C |
uci1 | 119:b3d7699d0eb0 | 2051 | |
uci1 | 119:b3d7699d0eb0 | 2052 | uint16_t dv=0; |
uci1 | 119:b3d7699d0eb0 | 2053 | uint8_t dn=0; |
uci1 | 119:b3d7699d0eb0 | 2054 | uint8_t cmdAndDac[3]; |
uci1 | 119:b3d7699d0eb0 | 2055 | uint8_t dadr=0; |
uci1 | 119:b3d7699d0eb0 | 2056 | for (uint8_t ch=0; ch<kNchans; ++ch) { |
uci1 | 119:b3d7699d0eb0 | 2057 | dadr = kLTC2657Adrs[ ch / kChansPerLTC2657 ]; |
uci1 | 119:b3d7699d0eb0 | 2058 | for (uint8_t dc=0; dc<kNchanDacs; ++dc) { |
uci1 | 119:b3d7699d0eb0 | 2059 | bool dok = false; |
uci1 | 119:b3d7699d0eb0 | 2060 | for (uint8_t tries = 0; (tries<kMaxDacSetTries) && (dok==false); ++tries) { |
uci1 | 119:b3d7699d0eb0 | 2061 | #ifdef DEBUG |
uci1 | 119:b3d7699d0eb0 | 2062 | printf("start i2c for dc=%hhu, ch=%hhu, try=%hhu, dok=%s\r\n", |
uci1 | 119:b3d7699d0eb0 | 2063 | dc, ch, tries, (dok ? "true" : "false")); |
uci1 | 119:b3d7699d0eb0 | 2064 | printf("address 0x%hhx (%hhd) ", dadr, dadr); |
uci1 | 119:b3d7699d0eb0 | 2065 | SnBitUtils::printBits(dadr, true); |
uci1 | 119:b3d7699d0eb0 | 2066 | #endif |
uci1 | 119:b3d7699d0eb0 | 2067 | // build data to send |
uci1 | 119:b3d7699d0eb0 | 2068 | // blame the engineers for this bizzare mapping from |
uci1 | 119:b3d7699d0eb0 | 2069 | // chan, threshold -> DAC number |
uci1 | 123:6267de54c8ba | 2070 | #if (CHIPBOARD==SST8CH) || (CHIPBOARD==SST8CH_1GHz) |
uci1 | 123:6267de54c8ba | 2071 | dn = (kChansPerLTC2657*kNchanDacs)-(dc*kChansPerLTC2657)-kChansPerLTC2657+(ch % kChansPerLTC2657); |
uci1 | 123:6267de54c8ba | 2072 | #else |
uci1 | 119:b3d7699d0eb0 | 2073 | dn = ((kChansPerLTC2657*kNchanDacs)-1)-(dc*kChansPerLTC2657)-(ch % kChansPerLTC2657); |
uci1 | 123:6267de54c8ba | 2074 | #endif |
uci1 | 119:b3d7699d0eb0 | 2075 | if (dn>7) { // invalid code for LTC2657 dac chip |
uci1 | 119:b3d7699d0eb0 | 2076 | printf("kTotDacs=%hu, dc=%hhu, ch=%hhu, kChansPerLTC2657=%hhu, dn=%hhu\n", |
uci1 | 119:b3d7699d0eb0 | 2077 | kTotDacs, dc, ch, kChansPerLTC2657, dn); |
uci1 | 119:b3d7699d0eb0 | 2078 | error("chan/dac combination too big for 3 bits!"); |
uci1 | 119:b3d7699d0eb0 | 2079 | } |
uci1 | 119:b3d7699d0eb0 | 2080 | dn |= (kUpdateDacCmd<<4); // prefix with update DAC value command |
uci1 | 119:b3d7699d0eb0 | 2081 | #ifdef DEBUG |
uci1 | 119:b3d7699d0eb0 | 2082 | printf("dn=%hhu ", dn); |
uci1 | 119:b3d7699d0eb0 | 2083 | SnBitUtils::printBits(dn, true); |
uci1 | 119:b3d7699d0eb0 | 2084 | #endif |
uci1 | 119:b3d7699d0eb0 | 2085 | |
uci1 | 119:b3d7699d0eb0 | 2086 | #ifdef DEBUG |
uci1 | 119:b3d7699d0eb0 | 2087 | printf("%d bit dacs\n", static_cast<int>(DAC_BITS)); |
uci1 | 119:b3d7699d0eb0 | 2088 | #endif |
uci1 | 119:b3d7699d0eb0 | 2089 | dv = (gConf.GetDac(ch, dc)); |
uci1 | 119:b3d7699d0eb0 | 2090 | #if DAC_BITS==12 |
uci1 | 119:b3d7699d0eb0 | 2091 | dv = dv << 4; // put 0's at the end (12 bits of num then 4 zero bits) |
uci1 | 119:b3d7699d0eb0 | 2092 | #elif DAC_BITS==16 |
uci1 | 119:b3d7699d0eb0 | 2093 | // no shift required for 16 bit dacs |
uci1 | 119:b3d7699d0eb0 | 2094 | #else |
uci1 | 119:b3d7699d0eb0 | 2095 | #error DAC_BITS has invalid value! Must be either 12 or 16. |
uci1 | 119:b3d7699d0eb0 | 2096 | #endif // DAC_BITS |
uci1 | 119:b3d7699d0eb0 | 2097 | |
uci1 | 119:b3d7699d0eb0 | 2098 | #ifdef DEBUG |
uci1 | 119:b3d7699d0eb0 | 2099 | printf("dv=%hu\r\n",dv); |
uci1 | 119:b3d7699d0eb0 | 2100 | printf("ch=%hhu, dc=%hhu, dac=%hu\r\n",ch,dc,gConf.GetDac(ch,dc)); |
uci1 | 119:b3d7699d0eb0 | 2101 | #endif |
uci1 | 119:b3d7699d0eb0 | 2102 | // mbed i2c.write seems to send it "backwards" from a (low endian) bit |
uci1 | 119:b3d7699d0eb0 | 2103 | // point of view.. i guess it's forwards from an intuitive pov? |
uci1 | 119:b3d7699d0eb0 | 2104 | cmdAndDac[0] = dn; |
uci1 | 119:b3d7699d0eb0 | 2105 | cmdAndDac[1] = (dv & 0xFF00u) >> 8; // 8 MSBs of dac first |
uci1 | 119:b3d7699d0eb0 | 2106 | cmdAndDac[2] = (dv & 0x00FFu); // 8 LSBs of dac second |
uci1 | 119:b3d7699d0eb0 | 2107 | |
uci1 | 119:b3d7699d0eb0 | 2108 | #ifdef DEBUG |
uci1 | 119:b3d7699d0eb0 | 2109 | printf("cmdAndDac[0]="); SnBitUtils::printBits(cmdAndDac[2],true); |
uci1 | 119:b3d7699d0eb0 | 2110 | printf("cmdAndDac[1]="); SnBitUtils::printBits(cmdAndDac[1],true); |
uci1 | 119:b3d7699d0eb0 | 2111 | printf("cmdAndDac[2]="); SnBitUtils::printBits(cmdAndDac[0],true); |
uci1 | 119:b3d7699d0eb0 | 2112 | #endif |
uci1 | 119:b3d7699d0eb0 | 2113 | // try to send it |
uci1 | 119:b3d7699d0eb0 | 2114 | // TODO: if no ACK, is just re-trying the whole thing good enough? |
uci1 | 119:b3d7699d0eb0 | 2115 | dok = PIN_i2c.write(dadr, |
uci1 | 119:b3d7699d0eb0 | 2116 | reinterpret_cast<char*>(cmdAndDac), |
uci1 | 119:b3d7699d0eb0 | 2117 | 3*sizeof(uint8_t))==0; |
uci1 | 119:b3d7699d0eb0 | 2118 | } // end try loop |
uci1 | 119:b3d7699d0eb0 | 2119 | } |
uci1 | 119:b3d7699d0eb0 | 2120 | } |
uci1 | 119:b3d7699d0eb0 | 2121 | } |
uci1 | 119:b3d7699d0eb0 | 2122 | #endif |
uci1 | 119:b3d7699d0eb0 | 2123 | |
uci1 | 119:b3d7699d0eb0 | 2124 | // |
uci1 | 0:664899e0b988 | 2125 | // set configuration |
uci1 | 0:664899e0b988 | 2126 | // |
uci1 | 1:e392595b4b76 | 2127 | void SetConfigAndMakeOutputFile() { |
uci1 | 12:d472f9811262 | 2128 | #ifdef DEBUG |
uci1 | 1:e392595b4b76 | 2129 | printf("SetConfigAndMakeOutputFile\r\n"); |
uci1 | 12:d472f9811262 | 2130 | #endif |
uci1 | 1:e392595b4b76 | 2131 | |
uci1 | 0:664899e0b988 | 2132 | // restart watchdog |
uci1 | 62:4b59c1eb429f | 2133 | #ifdef DEBUG |
uci1 | 62:4b59c1eb429f | 2134 | printf("Restart watchdog with time [%u]\r\n", |
uci1 | 62:4b59c1eb429f | 2135 | gConf.GetWatchdogPeriod()); |
uci1 | 62:4b59c1eb429f | 2136 | #endif |
uci1 | 0:664899e0b988 | 2137 | Watchdog::kick(gConf.GetWatchdogPeriod()); |
uci1 | 0:664899e0b988 | 2138 | |
uci1 | 1:e392595b4b76 | 2139 | // block (thermal) triggers during configuration |
uci1 | 1:e392595b4b76 | 2140 | PIN_enableThermTrig = 0; |
uci1 | 56:0bba0ef15697 | 2141 | #if CHIPBOARD==ATWD4CH |
uci1 | 1:e392595b4b76 | 2142 | PIN_ADC_CS = 1; |
uci1 | 1:e392595b4b76 | 2143 | PIN_DoNotRestartAllClocks = 1; |
uci1 | 56:0bba0ef15697 | 2144 | #endif |
uci1 | 1:e392595b4b76 | 2145 | PIN_forceTrigger = 0; |
uci1 | 3:24c5f0f50bf1 | 2146 | PIN_heartbeat = 0; |
uci1 | 40:1324da35afd4 | 2147 | #ifdef USE_RTOS |
uci1 | 40:1324da35afd4 | 2148 | Thread::wait(20); |
uci1 | 40:1324da35afd4 | 2149 | #else |
uci1 | 1:e392595b4b76 | 2150 | wait_ms(20); |
uci1 | 40:1324da35afd4 | 2151 | #endif |
uci1 | 1:e392595b4b76 | 2152 | |
uci1 | 22:f957c4f840ad | 2153 | gCommWinChecks = 0; |
uci1 | 22:f957c4f840ad | 2154 | gNcommWinChecks = gConf.GetCommWinPeriod() / kCommWinLongPrdTk; |
uci1 | 22:f957c4f840ad | 2155 | |
uci1 | 21:ce51bb0ba4a5 | 2156 | if (AreCardsPowered(true)) { |
uci1 | 8:95a325df1f6b | 2157 | // Set PLA value(s) |
uci1 | 56:0bba0ef15697 | 2158 | PIN_spi.format( 16, 0 ); // change mode for DAC & PLA value setting (with ATWD4CH) |
uci1 | 8:95a325df1f6b | 2159 | PIN_spi.frequency(1000000); |
uci1 | 8:95a325df1f6b | 2160 | PIN_MajLogHiBit=1; |
uci1 | 8:95a325df1f6b | 2161 | PIN_MajLogLoBit=1; |
uci1 | 8:95a325df1f6b | 2162 | PIN_enableThermTrig=0; |
uci1 | 119:b3d7699d0eb0 | 2163 | |
uci1 | 119:b3d7699d0eb0 | 2164 | // set DACs (and PLAs if needed) |
uci1 | 56:0bba0ef15697 | 2165 | #if CHIPBOARD==ATWD4CH |
uci1 | 119:b3d7699d0eb0 | 2166 | SetAtwdPlas(); |
uci1 | 119:b3d7699d0eb0 | 2167 | SetAtwdDACs(); |
uci1 | 56:0bba0ef15697 | 2168 | #else // SST |
uci1 | 119:b3d7699d0eb0 | 2169 | SetSstDACs(); |
uci1 | 56:0bba0ef15697 | 2170 | #endif // CHIPBOARD |
uci1 | 56:0bba0ef15697 | 2171 | |
uci1 | 12:d472f9811262 | 2172 | #ifdef DEBUG |
uci1 | 8:95a325df1f6b | 2173 | printf("dacs set\r\n"); |
uci1 | 12:d472f9811262 | 2174 | #endif |
uci1 | 40:1324da35afd4 | 2175 | #ifdef USE_RTOS |
uci1 | 40:1324da35afd4 | 2176 | Thread::wait(20); |
uci1 | 40:1324da35afd4 | 2177 | #else |
uci1 | 8:95a325df1f6b | 2178 | wait_ms(20); |
uci1 | 40:1324da35afd4 | 2179 | #endif |
uci1 | 8:95a325df1f6b | 2180 | } else { |
uci1 | 12:d472f9811262 | 2181 | #ifdef DEBUG |
uci1 | 8:95a325df1f6b | 2182 | printf("cards off. skipping PLA and DAC setting\r\n"); |
uci1 | 12:d472f9811262 | 2183 | #endif |
uci1 | 0:664899e0b988 | 2184 | } |
uci1 | 56:0bba0ef15697 | 2185 | |
uci1 | 114:554fa3a956b4 | 2186 | #if CHIPBOARD!=ATWD4CH |
uci1 | 56:0bba0ef15697 | 2187 | // set the SST triggering run mode |
uci1 | 56:0bba0ef15697 | 2188 | PIN_dualOrSingleThresholds = gConf.IsDualThresholdMode(); |
uci1 | 56:0bba0ef15697 | 2189 | PIN_differentialTrigSignal = gConf.IsDifferentialTrigMode(); |
uci1 | 56:0bba0ef15697 | 2190 | #endif |
uci1 | 0:664899e0b988 | 2191 | |
uci1 | 0:664899e0b988 | 2192 | // Majority Logic Trigger selection (# of cards) |
uci1 | 0:664899e0b988 | 2193 | SnBitUtils::SetChanNumBits(gConf.GetNumCardsMajLog() - 1u, |
uci1 | 0:664899e0b988 | 2194 | PIN_MajLogHiBit, PIN_MajLogLoBit); |
uci1 | 0:664899e0b988 | 2195 | |
uci1 | 0:664899e0b988 | 2196 | // Enable thermal trigger? |
uci1 | 0:664899e0b988 | 2197 | PIN_enableThermTrig = gConf.IsThermTrigEnabled(); |
uci1 | 0:664899e0b988 | 2198 | |
uci1 | 114:554fa3a956b4 | 2199 | #if CHIPBOARD!=ATWD4CH |
uci1 | 56:0bba0ef15697 | 2200 | InitTempProbe(); |
uci1 | 56:0bba0ef15697 | 2201 | #endif |
uci1 | 56:0bba0ef15697 | 2202 | |
uci1 | 0:664899e0b988 | 2203 | PIN_spi.format( 16, 1 ); // back to trigger mode |
uci1 | 1:e392595b4b76 | 2204 | PIN_spi.frequency( 10000000 ); // Max is 12.5 MHz |
uci1 | 1:e392595b4b76 | 2205 | |
uci1 | 8:95a325df1f6b | 2206 | // make new output file |
uci1 | 8:95a325df1f6b | 2207 | // put after PLA/DAC, in case they affect the power readings |
uci1 | 40:1324da35afd4 | 2208 | #ifdef USE_RTOS |
uci1 | 40:1324da35afd4 | 2209 | Thread::wait(200); |
uci1 | 40:1324da35afd4 | 2210 | #else |
uci1 | 8:95a325df1f6b | 2211 | wait_ms(200); |
uci1 | 40:1324da35afd4 | 2212 | #endif |
uci1 | 8:95a325df1f6b | 2213 | MakeOutputFile(); |
uci1 | 8:95a325df1f6b | 2214 | |
uci1 | 21:ce51bb0ba4a5 | 2215 | // reset tickers |
uci1 | 21:ce51bb0ba4a5 | 2216 | ResetAllTickers(); |
uci1 | 0:664899e0b988 | 2217 | |
uci1 | 0:664899e0b988 | 2218 | Watchdog::kick(); // don't reset! |
uci1 | 8:95a325df1f6b | 2219 | |
uci1 | 12:d472f9811262 | 2220 | #ifdef DEBUG |
uci1 | 8:95a325df1f6b | 2221 | printf("set config done\r\n"); |
uci1 | 12:d472f9811262 | 2222 | #endif |
uci1 | 0:664899e0b988 | 2223 | } |
uci1 | 0:664899e0b988 | 2224 | |
uci1 | 0:664899e0b988 | 2225 | // |
uci1 | 0:664899e0b988 | 2226 | // readout functions |
uci1 | 0:664899e0b988 | 2227 | // |
uci1 | 0:664899e0b988 | 2228 | void WaitTrigAndSendClock() { |
uci1 | 1:e392595b4b76 | 2229 | |
uci1 | 12:d472f9811262 | 2230 | #ifdef DEBUG |
uci1 | 1:e392595b4b76 | 2231 | printf("WaitTrigAndSendClock\r\n"); |
uci1 | 6:6f002d202f59 | 2232 | printf("wait trig: (pw %hhu): cards %d, amps %d, irid %d, afar %d\r\n", |
uci1 | 6:6f002d202f59 | 2233 | gConf.GetPowerMode(), PIN_turn_on_system.read(), PIN_turn_on_amps.read(), |
uci1 | 6:6f002d202f59 | 2234 | PIN_iridSbd_power.read(), PIN_afar_power.read()); |
uci1 | 21:ce51bb0ba4a5 | 2235 | printf("cards powered=%d\r\n",(int)AreCardsPowered(true)); |
uci1 | 12:d472f9811262 | 2236 | #endif |
uci1 | 15:f2569d8e4176 | 2237 | |
uci1 | 21:ce51bb0ba4a5 | 2238 | #ifdef DEBUG |
uci1 | 41:d6f5e2f09e07 | 2239 | printf("gFirstEvt=%s\r\n",gFirstEvt?"true":"false"); |
uci1 | 21:ce51bb0ba4a5 | 2240 | #endif |
uci1 | 41:d6f5e2f09e07 | 2241 | if (AreCardsPowered(false)) { |
uci1 | 41:d6f5e2f09e07 | 2242 | |
uci1 | 41:d6f5e2f09e07 | 2243 | PIN_spi.format( 16, 1 ); // back to trigger mode |
uci1 | 41:d6f5e2f09e07 | 2244 | PIN_spi.frequency( 10000000 ); // Max is 12.5 MHz |
uci1 | 8:95a325df1f6b | 2245 | |
uci1 | 47:fbe956b10a91 | 2246 | if (gFirstEvt==false) { |
uci1 | 56:0bba0ef15697 | 2247 | #if CHIPBOARD==ATWD4CH |
uci1 | 47:fbe956b10a91 | 2248 | PIN_DoNotRestartAllClocks = 0; |
uci1 | 47:fbe956b10a91 | 2249 | wait_us(1); |
uci1 | 47:fbe956b10a91 | 2250 | PIN_DoNotRestartAllClocks = 1; |
uci1 | 56:0bba0ef15697 | 2251 | #endif |
uci1 | 47:fbe956b10a91 | 2252 | } else { |
uci1 | 47:fbe956b10a91 | 2253 | gFirstEvt = false; |
uci1 | 47:fbe956b10a91 | 2254 | } |
uci1 | 47:fbe956b10a91 | 2255 | |
uci1 | 8:95a325df1f6b | 2256 | // |
uci1 | 8:95a325df1f6b | 2257 | // wait for a trigger here. |
uci1 | 8:95a325df1f6b | 2258 | // |
uci1 | 12:d472f9811262 | 2259 | #ifdef DEBUG |
uci1 | 8:95a325df1f6b | 2260 | printf("starting wait for trig\r\n"); |
uci1 | 12:d472f9811262 | 2261 | #endif |
uci1 | 16:744ce85aede2 | 2262 | |
uci1 | 8:95a325df1f6b | 2263 | gReadingOut = false; // this will allow forced triggers (see procForceTrigger()) |
uci1 | 56:0bba0ef15697 | 2264 | #if CHIPBOARD==ATWD4CH |
uci1 | 56:0bba0ef15697 | 2265 | while ( PIN_a_sf_clk == 1 ) { // wait for trigger |
uci1 | 56:0bba0ef15697 | 2266 | #else |
uci1 | 56:0bba0ef15697 | 2267 | while ( PIN_dataReady==0 ) { // wait for data in mb fpga |
uci1 | 56:0bba0ef15697 | 2268 | #endif |
uci1 | 56:0bba0ef15697 | 2269 | if (gOpenCommWin || gCheckPower || gCheckTemp) { |
uci1 | 12:d472f9811262 | 2270 | #ifdef DEBUG |
uci1 | 56:0bba0ef15697 | 2271 | printf("break com=%d, pow=%d, tmp=%d\r\n", |
uci1 | 56:0bba0ef15697 | 2272 | gOpenCommWin,gCheckPower,gCheckTemp); |
uci1 | 12:d472f9811262 | 2273 | #endif |
uci1 | 8:95a325df1f6b | 2274 | return; // break out to open comms or check power |
uci1 | 8:95a325df1f6b | 2275 | } |
uci1 | 0:664899e0b988 | 2276 | } |
uci1 | 8:95a325df1f6b | 2277 | gReadingOut = true; // disallow new forced triggers |
uci1 | 56:0bba0ef15697 | 2278 | |
uci1 | 15:f2569d8e4176 | 2279 | // we can't be interrupted before data arrives at the MB FPGA |
uci1 | 15:f2569d8e4176 | 2280 | //StopAllTickers(); |
uci1 | 16:744ce85aede2 | 2281 | |
uci1 | 23:ccf39298f205 | 2282 | //wait_us(5); |
uci1 | 56:0bba0ef15697 | 2283 | |
uci1 | 56:0bba0ef15697 | 2284 | #if CHIPBOARD==ATWD4CH |
uci1 | 56:0bba0ef15697 | 2285 | // ATWD |
uci1 | 8:95a325df1f6b | 2286 | // |
uci1 | 8:95a325df1f6b | 2287 | // collect data from daughter cards |
uci1 | 8:95a325df1f6b | 2288 | // |
uci1 | 8:95a325df1f6b | 2289 | // TODO: what if some card (set of channels) doesn't respond? |
uci1 | 8:95a325df1f6b | 2290 | // currently, will wait forever? |
uci1 | 8:95a325df1f6b | 2291 | // also, if ch1 is dead, will wait forever (due to FPGA code) |
uci1 | 16:744ce85aede2 | 2292 | gAdcToMBtimer.start(); |
uci1 | 56:0bba0ef15697 | 2293 | for( uint16_t i = 0; i < kNsamps; ++i ) { |
uci1 | 16:744ce85aede2 | 2294 | while (PIN_a_sf_clk==1) {} |
uci1 | 16:744ce85aede2 | 2295 | while (PIN_a_sf_clk==0) {} |
uci1 | 56:0bba0ef15697 | 2296 | |
uci1 | 16:744ce85aede2 | 2297 | PIN_ADC_CS = 0; |
uci1 | 16:744ce85aede2 | 2298 | PIN_spi.write( 0x00 ); |
uci1 | 16:744ce85aede2 | 2299 | PIN_ADC_CS = 1; |
uci1 | 0:664899e0b988 | 2300 | } |
uci1 | 16:744ce85aede2 | 2301 | gAdcToMBtimer.stop(); |
uci1 | 16:744ce85aede2 | 2302 | #ifdef DEBUG |
uci1 | 16:744ce85aede2 | 2303 | printf("total time = %d us\r\n", gAdcToMBtimer.read_us()); |
uci1 | 16:744ce85aede2 | 2304 | #endif |
uci1 | 16:744ce85aede2 | 2305 | if ( kAdcToMBtimeCut < gAdcToMBtimer.read_us() ) { |
uci1 | 84:80b15993944e | 2306 | // gEvent.SetTrgBit(kAdcToMBflag); |
uci1 | 84:80b15993944e | 2307 | gAdcToMBflag = true; |
uci1 | 16:744ce85aede2 | 2308 | } |
uci1 | 16:744ce85aede2 | 2309 | gAdcToMBtimer.reset(); |
uci1 | 15:f2569d8e4176 | 2310 | |
uci1 | 56:0bba0ef15697 | 2311 | #else |
uci1 | 56:0bba0ef15697 | 2312 | // For SST, data is already in the mb FPGA, so no need to do anything here |
uci1 | 56:0bba0ef15697 | 2313 | #endif |
uci1 | 56:0bba0ef15697 | 2314 | |
uci1 | 8:95a325df1f6b | 2315 | } else { |
uci1 | 8:95a325df1f6b | 2316 | // cards have no power. don't try reading out |
uci1 | 8:95a325df1f6b | 2317 | gReadingOut=false; |
uci1 | 47:fbe956b10a91 | 2318 | // set gFirstEvt to false even if cards are powered off. |
uci1 | 47:fbe956b10a91 | 2319 | // otherwise, if cards ARE powered off, it will always be |
uci1 | 47:fbe956b10a91 | 2320 | // true and the "start trigger" clock will be written continuously |
uci1 | 47:fbe956b10a91 | 2321 | gFirstEvt = false; |
uci1 | 0:664899e0b988 | 2322 | } |
uci1 | 56:0bba0ef15697 | 2323 | |
uci1 | 0:664899e0b988 | 2324 | } |
uci1 | 0:664899e0b988 | 2325 | |
uci1 | 40:1324da35afd4 | 2326 | bool IsPinPowered(const SnCommWin* cw) { |
uci1 | 40:1324da35afd4 | 2327 | bool havePower = false; |
uci1 | 40:1324da35afd4 | 2328 | switch (cw->GetCommType()) { |
uci1 | 40:1324da35afd4 | 2329 | case SnConfigFrame::kIrid: |
uci1 | 40:1324da35afd4 | 2330 | havePower = gConf.IsPoweredFor(SnConfigFrame::kIridComWin) |
uci1 | 40:1324da35afd4 | 2331 | && ( (kIridPwrFromAfar) |
uci1 | 40:1324da35afd4 | 2332 | ? PIN_afar_power.read() |
uci1 | 40:1324da35afd4 | 2333 | : PIN_iridSbd_power.read() == |
uci1 | 40:1324da35afd4 | 2334 | gConf.GetPowPinSetting(SnConfigFrame::kIridComWin)); |
uci1 | 40:1324da35afd4 | 2335 | break; |
uci1 | 40:1324da35afd4 | 2336 | case SnConfigFrame::kAfar: |
uci1 | 40:1324da35afd4 | 2337 | havePower = gConf.IsPoweredFor(SnConfigFrame::kAfarComWin) |
uci1 | 40:1324da35afd4 | 2338 | && (PIN_afar_power.read() == |
uci1 | 40:1324da35afd4 | 2339 | gConf.GetPowPinSetting(SnConfigFrame::kAfarComWin)); |
uci1 | 40:1324da35afd4 | 2340 | break; |
uci1 | 40:1324da35afd4 | 2341 | case SnConfigFrame::kUSB: |
uci1 | 40:1324da35afd4 | 2342 | havePower = true; // USB always on (for now) |
uci1 | 40:1324da35afd4 | 2343 | break; |
uci1 | 40:1324da35afd4 | 2344 | case SnConfigFrame::kSDcard: // shouldn't happen. skip it |
uci1 | 40:1324da35afd4 | 2345 | default: // unknown.. skip it |
uci1 | 40:1324da35afd4 | 2346 | break; |
uci1 | 40:1324da35afd4 | 2347 | }; |
uci1 | 40:1324da35afd4 | 2348 | return havePower; |
uci1 | 40:1324da35afd4 | 2349 | } |
uci1 | 40:1324da35afd4 | 2350 | |
uci1 | 40:1324da35afd4 | 2351 | |
uci1 | 122:c1b5023eac69 | 2352 | SnCommWin::ECommWinResult OpenCommWin(const bool isStartupWin) { |
uci1 | 0:664899e0b988 | 2353 | // loop through each comm mode: |
uci1 | 0:664899e0b988 | 2354 | // a) try to connect |
uci1 | 0:664899e0b988 | 2355 | // b) if connected, listen for config |
uci1 | 0:664899e0b988 | 2356 | // c) if config requests data, send it |
uci1 | 67:ec999336fcd1 | 2357 | |
uci1 | 67:ec999336fcd1 | 2358 | led2 = 1; |
uci1 | 67:ec999336fcd1 | 2359 | |
uci1 | 3:24c5f0f50bf1 | 2360 | gLastCommWin = time(0); |
uci1 | 13:7a1fb885a8e4 | 2361 | |
uci1 | 0:664899e0b988 | 2362 | SnCommWin::ECommWinResult res = SnCommWin::kUndefFail; |
uci1 | 0:664899e0b988 | 2363 | |
uci1 | 21:ce51bb0ba4a5 | 2364 | // get the trigger rates |
uci1 | 116:8099b754fbb4 | 2365 | // float thmrate=0, evtrate=0; |
uci1 | 116:8099b754fbb4 | 2366 | // GetRates(thmrate, evtrate); |
uci1 | 116:8099b754fbb4 | 2367 | const float seqlive = GetSeqLivetime(); |
uci1 | 22:f957c4f840ad | 2368 | #ifdef DEBUG |
uci1 | 56:0bba0ef15697 | 2369 | printf("config=%s\r\n", gConf.GetLabel()); |
uci1 | 116:8099b754fbb4 | 2370 | // printf("thmrate=%g, evtrate=%g\r\n",thmrate,evtrate); |
uci1 | 116:8099b754fbb4 | 2371 | printf("SEQ livetime = %g\r\n", seqlive); |
uci1 | 84:80b15993944e | 2372 | printf("Free memory = %d\r\n", FreeMem()); |
uci1 | 22:f957c4f840ad | 2373 | #endif |
uci1 | 21:ce51bb0ba4a5 | 2374 | |
uci1 | 21:ce51bb0ba4a5 | 2375 | StopAllTickers(); |
uci1 | 40:1324da35afd4 | 2376 | |
uci1 | 13:7a1fb885a8e4 | 2377 | if (gConf.GetCommWinDuration()==0) { |
uci1 | 13:7a1fb885a8e4 | 2378 | // TODO: set min so this is not possible |
uci1 | 13:7a1fb885a8e4 | 2379 | res = SnCommWin::kOkNoMsg; |
uci1 | 13:7a1fb885a8e4 | 2380 | } else { |
uci1 | 13:7a1fb885a8e4 | 2381 | |
uci1 | 13:7a1fb885a8e4 | 2382 | gCommWinOpen = true; |
uci1 | 1:e392595b4b76 | 2383 | Watchdog::kick(); // don't reset! |
uci1 | 13:7a1fb885a8e4 | 2384 | |
uci1 | 13:7a1fb885a8e4 | 2385 | #ifdef DEBUG |
uci1 | 13:7a1fb885a8e4 | 2386 | printf("opening comm window at %d\r\n", (int32_t)gLastCommWin); |
uci1 | 16:744ce85aede2 | 2387 | printf("duration=%u\r\n",gConf.GetCommWinDuration()); |
uci1 | 13:7a1fb885a8e4 | 2388 | #endif |
uci1 | 13:7a1fb885a8e4 | 2389 | |
uci1 | 13:7a1fb885a8e4 | 2390 | // close the file so that the data is all written out. |
uci1 | 13:7a1fb885a8e4 | 2391 | // and open it back up at the beginning (for reading) |
uci1 | 12:d472f9811262 | 2392 | #ifdef DEBUG |
uci1 | 13:7a1fb885a8e4 | 2393 | printf("close & open file. gEvtNum=%u, gPowNum=%u\r\n",gEvtNum,gPowNum); |
uci1 | 25:57b2627fe756 | 2394 | printf("curfile=%p, filename=%s\r\n",SnSDUtils::GetCurFile(), |
uci1 | 25:57b2627fe756 | 2395 | SnSDUtils::GetCurFileName()); |
uci1 | 12:d472f9811262 | 2396 | #endif |
uci1 | 40:1324da35afd4 | 2397 | |
uci1 | 40:1324da35afd4 | 2398 | if (isStartupWin==false) { |
uci1 | 56:0bba0ef15697 | 2399 | #if CHIPBOARD==ATWD4CH |
uci1 | 56:0bba0ef15697 | 2400 | PIN_lockRegisters = 0; // unlock so we can talk to the SD card |
uci1 | 56:0bba0ef15697 | 2401 | #else |
uci1 | 56:0bba0ef15697 | 2402 | PIN_readingData = 0; // unlock so we can talk to the SD card |
uci1 | 56:0bba0ef15697 | 2403 | #endif |
uci1 | 25:57b2627fe756 | 2404 | #ifdef DEBUG |
uci1 | 40:1324da35afd4 | 2405 | printf("closing output file\r\n"); |
uci1 | 25:57b2627fe756 | 2406 | #endif |
uci1 | 40:1324da35afd4 | 2407 | SnSDUtils::CloseOutputFile(SnSDUtils::GetCurFile()); |
uci1 | 25:57b2627fe756 | 2408 | #ifdef DEBUG |
uci1 | 40:1324da35afd4 | 2409 | printf("open existing file (%d)\r\n",strlen(SnSDUtils::GetCurFileName())); |
uci1 | 25:57b2627fe756 | 2410 | #endif |
uci1 | 40:1324da35afd4 | 2411 | SnSDUtils::OpenExistingFile(SnSDUtils::GetCurFileName(), true, false); |
uci1 | 40:1324da35afd4 | 2412 | } |
uci1 | 40:1324da35afd4 | 2413 | |
uci1 | 21:ce51bb0ba4a5 | 2414 | #ifdef DEBUG |
uci1 | 21:ce51bb0ba4a5 | 2415 | printf("setting power\r\n"); |
uci1 | 21:ce51bb0ba4a5 | 2416 | #endif |
uci1 | 84:80b15993944e | 2417 | // (probably) power down cards,amps |
uci1 | 84:80b15993944e | 2418 | // don't power up comms yet (only as needed for use) |
uci1 | 84:80b15993944e | 2419 | SetPower(true, 0); |
uci1 | 13:7a1fb885a8e4 | 2420 | |
uci1 | 25:57b2627fe756 | 2421 | // time to recount files for the status update |
uci1 | 40:1324da35afd4 | 2422 | // for the startup win, don't access SD card in case we |
uci1 | 40:1324da35afd4 | 2423 | // rebooted due to a problem with the SD card |
uci1 | 40:1324da35afd4 | 2424 | SnStatusFrame::fgRecalcFiles = !isStartupWin; |
uci1 | 25:57b2627fe756 | 2425 | |
uci1 | 28:484943132bb0 | 2426 | #if defined(ENABLE_AFAR_TWITTER) && defined(ENABLE_AFAR_COMM) |
uci1 | 28:484943132bb0 | 2427 | bool doTwitter = false; |
uci1 | 28:484943132bb0 | 2428 | #endif |
uci1 | 28:484943132bb0 | 2429 | |
uci1 | 21:ce51bb0ba4a5 | 2430 | #ifdef DEBUG |
uci1 | 21:ce51bb0ba4a5 | 2431 | printf("start loop over comms\r\n"); |
uci1 | 21:ce51bb0ba4a5 | 2432 | #endif |
uci1 | 84:80b15993944e | 2433 | bool needToConnect=true; // still need to talk to the outside |
uci1 | 84:80b15993944e | 2434 | bool sendStat[kNcomms]; // if need to send status over this peripheral |
uci1 | 84:80b15993944e | 2435 | bool needClos[kNcomms]; // if need to call CloseConn on this peripheral |
uci1 | 56:0bba0ef15697 | 2436 | for (uint8_t i=0; i<kNcomms; ++i) { |
uci1 | 13:7a1fb885a8e4 | 2437 | sendStat[i]=true; |
uci1 | 84:80b15993944e | 2438 | needClos[i]=true; |
uci1 | 13:7a1fb885a8e4 | 2439 | } |
uci1 | 13:7a1fb885a8e4 | 2440 | bool* ss = sendStat; |
uci1 | 84:80b15993944e | 2441 | bool* nc = needClos; |
uci1 | 13:7a1fb885a8e4 | 2442 | SnCommWin** cw = gComms; |
uci1 | 84:80b15993944e | 2443 | for (uint8_t i=0; needToConnect && ((time(0)-gLastCommWin)<gConf.GetCommWinDuration()); |
uci1 | 84:80b15993944e | 2444 | ++i, ++cw, ++ss, ++nc) { |
uci1 | 1:e392595b4b76 | 2445 | Watchdog::kick(); // don't reset! |
uci1 | 13:7a1fb885a8e4 | 2446 | if (i==kNcomms) { |
uci1 | 13:7a1fb885a8e4 | 2447 | i=0; |
uci1 | 13:7a1fb885a8e4 | 2448 | cw = gComms; |
uci1 | 13:7a1fb885a8e4 | 2449 | ss = sendStat; |
uci1 | 84:80b15993944e | 2450 | nc = needClos; |
uci1 | 13:7a1fb885a8e4 | 2451 | } |
uci1 | 27:efc4d654b139 | 2452 | // skip if no comm object |
uci1 | 13:7a1fb885a8e4 | 2453 | if ((*cw)==0) { |
uci1 | 13:7a1fb885a8e4 | 2454 | continue; |
uci1 | 13:7a1fb885a8e4 | 2455 | } |
uci1 | 84:80b15993944e | 2456 | |
uci1 | 84:80b15993944e | 2457 | const SnConfigFrame::EDatPackBit ctype = (*cw)->GetCommType(); |
uci1 | 84:80b15993944e | 2458 | |
uci1 | 84:80b15993944e | 2459 | // power up for this device |
uci1 | 84:80b15993944e | 2460 | if (gConf.IsCommPowerSimple()==false) { |
uci1 | 84:80b15993944e | 2461 | SetPower(true, ctype); |
uci1 | 84:80b15993944e | 2462 | } |
uci1 | 84:80b15993944e | 2463 | |
uci1 | 27:efc4d654b139 | 2464 | // skip if no power for this comm |
uci1 | 27:efc4d654b139 | 2465 | // THIS IS VITAL! For example, if the ethernet |
uci1 | 27:efc4d654b139 | 2466 | // port is powered down, making an Ethernet obejct |
uci1 | 27:efc4d654b139 | 2467 | // (done in netif) will stall forever waiting for the clock. |
uci1 | 27:efc4d654b139 | 2468 | // Do it here to keep all PIN usage in main.cpp |
uci1 | 40:1324da35afd4 | 2469 | const bool havePower=IsPinPowered(*cw); |
uci1 | 27:efc4d654b139 | 2470 | if (havePower==false) { |
uci1 | 27:efc4d654b139 | 2471 | continue; |
uci1 | 27:efc4d654b139 | 2472 | } |
uci1 | 40:1324da35afd4 | 2473 | |
uci1 | 40:1324da35afd4 | 2474 | // always apply safety nets to connection and listen so |
uci1 | 40:1324da35afd4 | 2475 | // that we don't accidently shut down comms (i.e. with |
uci1 | 40:1324da35afd4 | 2476 | // connectTO or listnTO being 0) |
uci1 | 40:1324da35afd4 | 2477 | gConf.ApplyConnectListenSafetyNets(); |
uci1 | 84:80b15993944e | 2478 | |
uci1 | 16:744ce85aede2 | 2479 | const uint32_t conto = |
uci1 | 84:80b15993944e | 2480 | (gConf.GetCommWinDuration() < gConf.GetCommWinConnectTO(ctype)) ? |
uci1 | 84:80b15993944e | 2481 | gConf.GetCommWinDuration() : gConf.GetCommWinConnectTO(ctype); |
uci1 | 16:744ce85aede2 | 2482 | const uint32_t listo = |
uci1 | 84:80b15993944e | 2483 | (gConf.GetCommWinDuration() < gConf.GetCommWinListenTO(ctype)) ? |
uci1 | 84:80b15993944e | 2484 | gConf.GetCommWinDuration() : gConf.GetCommWinListenTO(ctype); |
uci1 | 40:1324da35afd4 | 2485 | |
uci1 | 84:80b15993944e | 2486 | // |
uci1 | 84:80b15993944e | 2487 | // try to connect to the outside if we haven't yet |
uci1 | 84:80b15993944e | 2488 | // |
uci1 | 16:744ce85aede2 | 2489 | // update power reading in case we want to send it in status |
uci1 | 16:744ce85aede2 | 2490 | GetAvePowerReading(); |
uci1 | 56:0bba0ef15697 | 2491 | |
uci1 | 56:0bba0ef15697 | 2492 | // update temperature in case we want to send it in status |
uci1 | 56:0bba0ef15697 | 2493 | if (isStartupWin) { |
uci1 | 114:554fa3a956b4 | 2494 | #if CHIPBOARD!=ATWD4CH |
uci1 | 56:0bba0ef15697 | 2495 | InitTempProbe(); |
uci1 | 56:0bba0ef15697 | 2496 | #endif |
uci1 | 56:0bba0ef15697 | 2497 | } |
uci1 | 56:0bba0ef15697 | 2498 | UpdateTemperature(); |
uci1 | 21:ce51bb0ba4a5 | 2499 | |
uci1 | 13:7a1fb885a8e4 | 2500 | // open window and (mabye) send status update |
uci1 | 12:d472f9811262 | 2501 | #ifdef DEBUG |
uci1 | 84:80b15993944e | 2502 | printf("Free memory = %d\r\n", FreeMem()); |
uci1 | 84:80b15993944e | 2503 | printf("calling OpenWindow. ss=%d. ctype=%hhu (%s)\r\n", |
uci1 | 84:80b15993944e | 2504 | (int)(*ss),(uint8_t)ctype,SnConfigFrame::GetDataStreamName(ctype)); |
uci1 | 40:1324da35afd4 | 2505 | printf("conto=%u, listo=%u, dur=%u, connTO=%u, lisTO=%u\r\n", |
uci1 | 40:1324da35afd4 | 2506 | conto,listo,gConf.GetCommWinDuration(), |
uci1 | 84:80b15993944e | 2507 | gConf.GetCommWinConnectTO(ctype), gConf.GetCommWinListenTO(ctype)); |
uci1 | 84:80b15993944e | 2508 | printf("stopAt=%u, current=%d, lastComWin=%d, dt~%u\r\n", |
uci1 | 84:80b15993944e | 2509 | gConf.GetTimeoutTime(gLastCommWin,conto), |
uci1 | 84:80b15993944e | 2510 | time(0), gLastCommWin, |
uci1 | 84:80b15993944e | 2511 | gConf.GetTimeoutTime(gLastCommWin,conto)-time(0)); |
uci1 | 12:d472f9811262 | 2512 | #endif |
uci1 | 84:80b15993944e | 2513 | |
uci1 | 84:80b15993944e | 2514 | // |
uci1 | 84:80b15993944e | 2515 | // open the connection and send the status update (if the |
uci1 | 84:80b15993944e | 2516 | // status has not yet been sent over this peripheral) |
uci1 | 84:80b15993944e | 2517 | // |
uci1 | 84:80b15993944e | 2518 | const SnCommWin::ECommWinResult conres = (*cw)->OpenWindow( *ss, |
uci1 | 116:8099b754fbb4 | 2519 | gConf, gPower, gEvent, SnSDUtils::GetCurSeqNum(), |
uci1 | 116:8099b754fbb4 | 2520 | // thmrate, evtrate, |
uci1 | 116:8099b754fbb4 | 2521 | gNumThmTrigs, gNumSavedEvts, seqlive, |
uci1 | 84:80b15993944e | 2522 | gPowerOnTime, gTemperature, |
uci1 | 84:80b15993944e | 2523 | gGenBuf, gConf.GetTimeoutTime(gLastCommWin, conto)); |
uci1 | 84:80b15993944e | 2524 | |
uci1 | 56:0bba0ef15697 | 2525 | #ifdef DEBUG |
uci1 | 56:0bba0ef15697 | 2526 | printf("conres = %d\r\n",static_cast<int>(conres)); |
uci1 | 56:0bba0ef15697 | 2527 | #endif |
uci1 | 13:7a1fb885a8e4 | 2528 | if (conres>=SnCommWin::kConnected) { |
uci1 | 1:e392595b4b76 | 2529 | Watchdog::kick(); // don't reset! |
uci1 | 13:7a1fb885a8e4 | 2530 | // connected. listen for config |
uci1 | 13:7a1fb885a8e4 | 2531 | *ss = false; // don't send status next time |
uci1 | 84:80b15993944e | 2532 | *nc = true; // will need to close this connection |
uci1 | 40:1324da35afd4 | 2533 | |
uci1 | 40:1324da35afd4 | 2534 | // clear watchdog reset bit now that we've told someone |
uci1 | 40:1324da35afd4 | 2535 | Watchdog::clearResetFlag(); |
uci1 | 40:1324da35afd4 | 2536 | |
uci1 | 28:484943132bb0 | 2537 | #if defined(ENABLE_AFAR_TWITTER) && defined(ENABLE_AFAR_COMM) |
uci1 | 84:80b15993944e | 2538 | if (ctype==SnConfigFrame::kAfar) { |
uci1 | 28:484943132bb0 | 2539 | // if we connected by Afar |
uci1 | 28:484943132bb0 | 2540 | doTwitter = true; |
uci1 | 28:484943132bb0 | 2541 | } |
uci1 | 28:484943132bb0 | 2542 | #endif |
uci1 | 28:484943132bb0 | 2543 | |
uci1 | 12:d472f9811262 | 2544 | #ifdef DEBUG |
uci1 | 21:ce51bb0ba4a5 | 2545 | printf("get conf gtt=%u\r\n",gConf.GetTimeoutTime(gLastCommWin, listo)); |
uci1 | 12:d472f9811262 | 2546 | #endif |
uci1 | 98:ce72ef143b9b | 2547 | // copy old config |
uci1 | 98:ce72ef143b9b | 2548 | gConfCopy = gConf; |
uci1 | 98:ce72ef143b9b | 2549 | |
uci1 | 84:80b15993944e | 2550 | // |
uci1 | 84:80b15993944e | 2551 | // ask for a new config |
uci1 | 84:80b15993944e | 2552 | // |
uci1 | 13:7a1fb885a8e4 | 2553 | const SnCommWin::ECommWinResult cfgres = (*cw)->GetConfig( |
uci1 | 21:ce51bb0ba4a5 | 2554 | gConf, gConf.GetTimeoutTime(gLastCommWin, listo), gGenBuf, gBufSize); |
uci1 | 56:0bba0ef15697 | 2555 | #ifdef DEBUG |
uci1 | 56:0bba0ef15697 | 2556 | printf("cfgres = %d\r\n",static_cast<int>(cfgres)); |
uci1 | 56:0bba0ef15697 | 2557 | #endif |
uci1 | 13:7a1fb885a8e4 | 2558 | if (cfgres>=SnCommWin::kOkWithMsg) { |
uci1 | 13:7a1fb885a8e4 | 2559 | Watchdog::kick(); // don't reset! |
uci1 | 16:744ce85aede2 | 2560 | |
uci1 | 12:d472f9811262 | 2561 | #ifdef DEBUG |
uci1 | 13:7a1fb885a8e4 | 2562 | printf("received config!\r\n"); |
uci1 | 13:7a1fb885a8e4 | 2563 | printf("send data = %d\r\n", gConf.GetCommSendData()); |
uci1 | 12:d472f9811262 | 2564 | #endif |
uci1 | 84:80b15993944e | 2565 | |
uci1 | 21:ce51bb0ba4a5 | 2566 | const uint32_t winto = gConf.GetTimeoutTime(gLastCommWin, |
uci1 | 21:ce51bb0ba4a5 | 2567 | gConf.GetCommWinDuration()); |
uci1 | 40:1324da35afd4 | 2568 | //const uint32_t gtt = gConf.IsObeyingTimeout() ? winto : 0; |
uci1 | 40:1324da35afd4 | 2569 | |
uci1 | 84:80b15993944e | 2570 | // |
uci1 | 84:80b15993944e | 2571 | // send status data -- do this after getting the config! |
uci1 | 84:80b15993944e | 2572 | // (avoid a situation where sending all this data causes a timeout, |
uci1 | 84:80b15993944e | 2573 | // thereby preventing a new config from being accepted) |
uci1 | 84:80b15993944e | 2574 | // |
uci1 | 98:ce72ef143b9b | 2575 | res = (*cw)->SendStatusData(gConf, gConfCopy, |
uci1 | 84:80b15993944e | 2576 | gStTrgStartClk, gStTrgStopClk, |
uci1 | 84:80b15993944e | 2577 | gStPower, gEvent, gStTemperature, |
uci1 | 84:80b15993944e | 2578 | gHrtbt, gStNewPower, gStNewEvent, |
uci1 | 84:80b15993944e | 2579 | gStNewHeartbeat, gStNewTemperature, |
uci1 | 84:80b15993944e | 2580 | gGenBuf, winto); |
uci1 | 84:80b15993944e | 2581 | #ifdef DEBUG |
uci1 | 84:80b15993944e | 2582 | printf("SendStatusData res=%d\r\n", |
uci1 | 84:80b15993944e | 2583 | static_cast<int32_t>(res)); |
uci1 | 84:80b15993944e | 2584 | #endif |
uci1 | 84:80b15993944e | 2585 | |
uci1 | 84:80b15993944e | 2586 | // |
uci1 | 40:1324da35afd4 | 2587 | // check if there are any requests before sending data |
uci1 | 84:80b15993944e | 2588 | // |
uci1 | 40:1324da35afd4 | 2589 | if (gConf.IsWaitingHndShkBeforeSendData()) { |
uci1 | 40:1324da35afd4 | 2590 | // send handshake request |
uci1 | 40:1324da35afd4 | 2591 | (*cw)->SendHndshkReq(gGenBuf, winto); |
uci1 | 40:1324da35afd4 | 2592 | // wait for response |
uci1 | 40:1324da35afd4 | 2593 | uint8_t hndshk(0); uint32_t hndshkLen(0); |
uci1 | 40:1324da35afd4 | 2594 | res = (*cw)->WaitHandshake(gConf, winto, gGenBuf, gBufSize, hndshk, |
uci1 | 40:1324da35afd4 | 2595 | &hndshkLen); |
uci1 | 56:0bba0ef15697 | 2596 | #ifdef DEBUG |
uci1 | 56:0bba0ef15697 | 2597 | printf("WaitHandshake res = %d\r\n",static_cast<int>(res)); |
uci1 | 56:0bba0ef15697 | 2598 | #endif |
uci1 | 40:1324da35afd4 | 2599 | // handle response |
uci1 | 40:1324da35afd4 | 2600 | if (SnCommWin::kOkWithMsg==res) { |
uci1 | 40:1324da35afd4 | 2601 | res = (*cw)->HandleHandshake(SnSDUtils::GetCurFile(), |
uci1 | 40:1324da35afd4 | 2602 | SnSDUtils::GetCurFileName(), |
uci1 | 84:80b15993944e | 2603 | gConf, gEvent, gPower, gGenBuf, gBufSize, |
uci1 | 84:80b15993944e | 2604 | // gConf, gLastEvent, gPower, gGenBuf, gBufSize, |
uci1 | 40:1324da35afd4 | 2605 | winto, hndshk, hndshkLen); |
uci1 | 56:0bba0ef15697 | 2606 | #ifdef DEBUG |
uci1 | 56:0bba0ef15697 | 2607 | printf("HandleHandshake res = %d\r\n",static_cast<int>(res)); |
uci1 | 56:0bba0ef15697 | 2608 | #endif |
uci1 | 40:1324da35afd4 | 2609 | } |
uci1 | 84:80b15993944e | 2610 | } // if handshake before data |
uci1 | 84:80b15993944e | 2611 | |
uci1 | 84:80b15993944e | 2612 | // |
uci1 | 84:80b15993944e | 2613 | // send data if need be (files, some events, etc) |
uci1 | 84:80b15993944e | 2614 | // |
uci1 | 13:7a1fb885a8e4 | 2615 | if (gConf.GetCommSendData()!=0) { |
uci1 | 12:d472f9811262 | 2616 | #ifdef DEBUG |
uci1 | 40:1324da35afd4 | 2617 | printf("sending data, winto=%u. lcw=%u, dur=%u, obey=%s\r\n", |
uci1 | 40:1324da35afd4 | 2618 | winto, |
uci1 | 13:7a1fb885a8e4 | 2619 | gLastCommWin, gConf.GetCommWinDuration(), |
uci1 | 13:7a1fb885a8e4 | 2620 | gConf.IsObeyingTimeout() ? "true" : "false"); |
uci1 | 12:d472f9811262 | 2621 | #endif |
uci1 | 16:744ce85aede2 | 2622 | |
uci1 | 84:80b15993944e | 2623 | res = (*cw)->SendData(gConf, |
uci1 | 84:80b15993944e | 2624 | // gLastEvent, gPower, gGenBuf, gBufSize, |
uci1 | 84:80b15993944e | 2625 | gEvent, gPower, gGenBuf, gBufSize, |
uci1 | 40:1324da35afd4 | 2626 | winto); |
uci1 | 56:0bba0ef15697 | 2627 | #ifdef DEBUG |
uci1 | 56:0bba0ef15697 | 2628 | printf("SendData res = %d\r\n",static_cast<int>(res)); |
uci1 | 56:0bba0ef15697 | 2629 | #endif |
uci1 | 56:0bba0ef15697 | 2630 | |
uci1 | 13:7a1fb885a8e4 | 2631 | } else { |
uci1 | 13:7a1fb885a8e4 | 2632 | // don't send anything |
uci1 | 13:7a1fb885a8e4 | 2633 | res = cfgres; |
uci1 | 84:80b15993944e | 2634 | } // if send data |
uci1 | 13:7a1fb885a8e4 | 2635 | #ifdef DEBUG |
uci1 | 13:7a1fb885a8e4 | 2636 | printf("Got config!\r\n"); |
uci1 | 13:7a1fb885a8e4 | 2637 | #endif |
uci1 | 13:7a1fb885a8e4 | 2638 | Watchdog::kick(); // don't reset! |
uci1 | 84:80b15993944e | 2639 | |
uci1 | 84:80b15993944e | 2640 | // need to close this connection |
uci1 | 84:80b15993944e | 2641 | *nc = true; |
uci1 | 84:80b15993944e | 2642 | // stop trying to connect to outside |
uci1 | 84:80b15993944e | 2643 | // don't break immediately, so that we can close conn and |
uci1 | 84:80b15993944e | 2644 | // maybe tweet (pff..) |
uci1 | 84:80b15993944e | 2645 | needToConnect = false; |
uci1 | 84:80b15993944e | 2646 | |
uci1 | 84:80b15993944e | 2647 | } // if config recvd ok with message |
uci1 | 84:80b15993944e | 2648 | |
uci1 | 84:80b15993944e | 2649 | // |
uci1 | 84:80b15993944e | 2650 | // stupid legacy twitter crap. |
uci1 | 84:80b15993944e | 2651 | // |
uci1 | 84:80b15993944e | 2652 | // after normal Afar connection closed, try to tweet |
uci1 | 84:80b15993944e | 2653 | #if defined(ENABLE_AFAR_TWITTER) && defined(ENABLE_AFAR_COMM) |
uci1 | 84:80b15993944e | 2654 | if (ctype==SnConfigFrame::kAfar) { |
uci1 | 84:80b15993944e | 2655 | // tweet |
uci1 | 84:80b15993944e | 2656 | #ifdef DEBUG |
uci1 | 84:80b15993944e | 2657 | printf("for twitter: gTwit=%p, doTwitter=%d\r\n",gTwit,(int)doTwitter); |
uci1 | 84:80b15993944e | 2658 | #endif |
uci1 | 84:80b15993944e | 2659 | // send a twitter update |
uci1 | 84:80b15993944e | 2660 | if ( (gTwit!=0) && doTwitter ) { |
uci1 | 84:80b15993944e | 2661 | const uint32_t conto = |
uci1 | 84:80b15993944e | 2662 | (gConf.GetCommWinDuration() < gTwit->GetConnectTimeout()) ? |
uci1 | 84:80b15993944e | 2663 | gConf.GetCommWinDuration() : gTwit->GetConnectTimeout(); |
uci1 | 84:80b15993944e | 2664 | const uint32_t listo = |
uci1 | 84:80b15993944e | 2665 | (gConf.GetCommWinDuration() < gTwit->GetListenTimeout()) ? |
uci1 | 84:80b15993944e | 2666 | gConf.GetCommWinDuration() : gTwit->GetListenTimeout(); |
uci1 | 84:80b15993944e | 2667 | #ifdef DEBUG |
uci1 | 84:80b15993944e | 2668 | printf("open twit window. conto=%u, listo=%u\r\n", |
uci1 | 84:80b15993944e | 2669 | conto, listo); |
uci1 | 84:80b15993944e | 2670 | #endif |
uci1 | 84:80b15993944e | 2671 | const SnCommWin::ECommWinResult conres = gTwit->OpenWindow( |
uci1 | 84:80b15993944e | 2672 | gConf.GetTimeoutTime(gLastCommWin, conto), false, gConf, |
uci1 | 84:80b15993944e | 2673 | // gLastEvent, gPower, |
uci1 | 84:80b15993944e | 2674 | gEvent, gPower, |
uci1 | 84:80b15993944e | 2675 | SnSDUtils::GetCurSeqNum(), thmrate, evtrate, |
uci1 | 84:80b15993944e | 2676 | gGenBuf); |
uci1 | 84:80b15993944e | 2677 | if (conres>=SnCommWin::kConnected) { |
uci1 | 84:80b15993944e | 2678 | Watchdog::kick(); // don't reset! |
uci1 | 84:80b15993944e | 2679 | gTwit->Tweet(gConf, thmrate, evtrate, gGenBuf, |
uci1 | 84:80b15993944e | 2680 | gConf.GetTimeoutTime(time(0), listo)); |
uci1 | 84:80b15993944e | 2681 | } |
uci1 | 84:80b15993944e | 2682 | } |
uci1 | 84:80b15993944e | 2683 | } // end tweet block |
uci1 | 84:80b15993944e | 2684 | #endif |
uci1 | 84:80b15993944e | 2685 | |
uci1 | 21:ce51bb0ba4a5 | 2686 | } else { |
uci1 | 40:1324da35afd4 | 2687 | // OpenWindow did not connect |
uci1 | 21:ce51bb0ba4a5 | 2688 | (*cw)->CloseConn(gConf.GetTimeoutTime(gLastCommWin, listo)); |
uci1 | 84:80b15993944e | 2689 | *nc = false; |
uci1 | 84:80b15993944e | 2690 | #ifdef DEBUG |
uci1 | 84:80b15993944e | 2691 | printf("no connect close conn. i=%d, nc=%s\r\n", |
uci1 | 84:80b15993944e | 2692 | (int32_t)i, (*nc) ? "true" : "false"); |
uci1 | 84:80b15993944e | 2693 | #endif |
uci1 | 21:ce51bb0ba4a5 | 2694 | } // if connected |
uci1 | 13:7a1fb885a8e4 | 2695 | |
uci1 | 13:7a1fb885a8e4 | 2696 | Watchdog::kick(); // don't reset! |
uci1 | 84:80b15993944e | 2697 | |
uci1 | 84:80b15993944e | 2698 | if (*nc) { |
uci1 | 84:80b15993944e | 2699 | // need to close this connection |
uci1 | 84:80b15993944e | 2700 | #ifdef DEBUG |
uci1 | 84:80b15993944e | 2701 | printf("close conn extra time. i=%d, nc=%s\r\n", |
uci1 | 84:80b15993944e | 2702 | (int32_t)i, (*nc) ? "true" : "false"); |
uci1 | 84:80b15993944e | 2703 | #endif |
uci1 | 84:80b15993944e | 2704 | const uint32_t extraDiscTime = gLastCommWin |
uci1 | 84:80b15993944e | 2705 | + gConf.GetCommWinConnectTO((*cw)->GetCommType()); |
uci1 | 84:80b15993944e | 2706 | (*cw)->CloseConn( |
uci1 | 116:8099b754fbb4 | 2707 | gConf.GetTimeoutTime(extraDiscTime, gConf.GetCommWinDuration()), |
uci1 | 116:8099b754fbb4 | 2708 | gGenBuf, true); // send the "closing window" signal |
uci1 | 84:80b15993944e | 2709 | *nc = false; |
uci1 | 84:80b15993944e | 2710 | } |
uci1 | 84:80b15993944e | 2711 | |
uci1 | 84:80b15993944e | 2712 | Watchdog::kick(); // don't reset! |
uci1 | 21:ce51bb0ba4a5 | 2713 | } // end loop over comms |
uci1 | 28:484943132bb0 | 2714 | |
uci1 | 84:80b15993944e | 2715 | |
uci1 | 41:d6f5e2f09e07 | 2716 | // check Iridium time, send Iridium signal strength, and close the connection(s) |
uci1 | 15:f2569d8e4176 | 2717 | cw = gComms; |
uci1 | 84:80b15993944e | 2718 | nc = needClos; |
uci1 | 84:80b15993944e | 2719 | for (uint8_t i=0; i<kNcomms; ++i, ++cw, ++nc) { |
uci1 | 15:f2569d8e4176 | 2720 | if ((*cw)==0) { |
uci1 | 15:f2569d8e4176 | 2721 | continue; |
uci1 | 15:f2569d8e4176 | 2722 | } |
uci1 | 84:80b15993944e | 2723 | |
uci1 | 84:80b15993944e | 2724 | const SnConfigFrame::EDatPackBit ctype = (*cw)->GetCommType(); |
uci1 | 84:80b15993944e | 2725 | |
uci1 | 84:80b15993944e | 2726 | // check Iridium time |
uci1 | 84:80b15993944e | 2727 | if (ctype==SnConfigFrame::kIrid) { |
uci1 | 40:1324da35afd4 | 2728 | |
uci1 | 84:80b15993944e | 2729 | // power up for this device |
uci1 | 84:80b15993944e | 2730 | if (gConf.IsCommPowerSimple()==false) { |
uci1 | 84:80b15993944e | 2731 | SetPower(true, ctype); |
uci1 | 84:80b15993944e | 2732 | } |
uci1 | 84:80b15993944e | 2733 | const bool havePower=IsPinPowered(*cw); |
uci1 | 84:80b15993944e | 2734 | if (havePower==false) { |
uci1 | 84:80b15993944e | 2735 | continue; |
uci1 | 84:80b15993944e | 2736 | } |
uci1 | 84:80b15993944e | 2737 | |
uci1 | 16:744ce85aede2 | 2738 | #ifdef DEBUG |
uci1 | 16:744ce85aede2 | 2739 | printf("try to set iridium time\r\n"); |
uci1 | 16:744ce85aede2 | 2740 | #endif |
uci1 | 16:744ce85aede2 | 2741 | // set the clock before closing connection |
uci1 | 41:d6f5e2f09e07 | 2742 | const uint32_t totime = |
uci1 | 41:d6f5e2f09e07 | 2743 | gConf.GetTimeoutTime(gLastCommWin, |
uci1 | 41:d6f5e2f09e07 | 2744 | gConf.GetCommWinDuration()); |
uci1 | 41:d6f5e2f09e07 | 2745 | #ifdef DEBUG |
uci1 | 41:d6f5e2f09e07 | 2746 | printf("totime=%u, ctime=%u\r\n",totime,time(0)); |
uci1 | 41:d6f5e2f09e07 | 2747 | #endif |
uci1 | 41:d6f5e2f09e07 | 2748 | const bool con = (*cw)->Connect(totime); |
uci1 | 84:80b15993944e | 2749 | *nc = true; |
uci1 | 84:80b15993944e | 2750 | |
uci1 | 16:744ce85aede2 | 2751 | if (con) { |
uci1 | 40:1324da35afd4 | 2752 | uint32_t prvTime(0), setTime(0); |
uci1 | 41:d6f5e2f09e07 | 2753 | const bool gottime = (*cw)->TrySetSysTimeUnix( |
uci1 | 41:d6f5e2f09e07 | 2754 | totime, prvTime, setTime); |
uci1 | 41:d6f5e2f09e07 | 2755 | if (gottime) { |
uci1 | 84:80b15993944e | 2756 | gClkSet.SetClocks( prvTime, setTime, time(0), |
uci1 | 84:80b15993944e | 2757 | gSinceClkSet.read_us() ); |
uci1 | 84:80b15993944e | 2758 | gSinceClkSet.reset(); |
uci1 | 84:80b15993944e | 2759 | gSinceClkSet.start(); |
uci1 | 41:d6f5e2f09e07 | 2760 | #ifdef DEBUG |
uci1 | 84:80b15993944e | 2761 | // printf("sig str: totime=%u, ctime=%u\r\n",totime,time(0)); |
uci1 | 84:80b15993944e | 2762 | printf("sig str: totime=%u, ctime=%u\r\n",totime,gClkSet.GetCurTime()); |
uci1 | 41:d6f5e2f09e07 | 2763 | #endif |
uci1 | 41:d6f5e2f09e07 | 2764 | // got time; now send signal strength |
uci1 | 41:d6f5e2f09e07 | 2765 | (*cw)->SendSignalStrength( gGenBuf, gSigStr, totime ); |
uci1 | 84:80b15993944e | 2766 | } // if got the iridium system time |
uci1 | 84:80b15993944e | 2767 | } // if connected (again, possibly) |
uci1 | 84:80b15993944e | 2768 | } // if iridium |
uci1 | 84:80b15993944e | 2769 | |
uci1 | 84:80b15993944e | 2770 | if (*nc) { |
uci1 | 84:80b15993944e | 2771 | |
uci1 | 84:80b15993944e | 2772 | // power up for this device |
uci1 | 84:80b15993944e | 2773 | if (gConf.IsCommPowerSimple()==false) { |
uci1 | 84:80b15993944e | 2774 | SetPower(true, ctype); |
uci1 | 16:744ce85aede2 | 2775 | } |
uci1 | 84:80b15993944e | 2776 | const bool havePower=IsPinPowered(*cw); |
uci1 | 84:80b15993944e | 2777 | if (havePower==false) { |
uci1 | 84:80b15993944e | 2778 | continue; |
uci1 | 84:80b15993944e | 2779 | } |
uci1 | 84:80b15993944e | 2780 | |
uci1 | 28:484943132bb0 | 2781 | #ifdef DEBUG |
uci1 | 84:80b15993944e | 2782 | printf("last loop close conn. i=%d, nc=%s\r\n", |
uci1 | 84:80b15993944e | 2783 | (int32_t)i, (*nc) ? "true" : "false"); |
uci1 | 28:484943132bb0 | 2784 | #endif |
uci1 | 84:80b15993944e | 2785 | |
uci1 | 84:80b15993944e | 2786 | const uint32_t extraDiscTime = gLastCommWin |
uci1 | 84:80b15993944e | 2787 | + gConf.GetCommWinConnectTO((*cw)->GetCommType()); |
uci1 | 84:80b15993944e | 2788 | (*cw)->CloseConn(gConf.GetTimeoutTime(extraDiscTime, gConf.GetCommWinDuration())); |
uci1 | 116:8099b754fbb4 | 2789 | // no "close window" signal sent here... |
uci1 | 84:80b15993944e | 2790 | *nc = false; |
uci1 | 84:80b15993944e | 2791 | } |
uci1 | 84:80b15993944e | 2792 | } // end loop: check time, close conns |
uci1 | 40:1324da35afd4 | 2793 | |
uci1 | 84:80b15993944e | 2794 | /* |
uci1 | 40:1324da35afd4 | 2795 | // close connections |
uci1 | 40:1324da35afd4 | 2796 | cw = gComms; |
uci1 | 56:0bba0ef15697 | 2797 | for (uint8_t i=0; i<kNcomms; ++i, ++cw) { |
uci1 | 40:1324da35afd4 | 2798 | if ((*cw)==0) { |
uci1 | 40:1324da35afd4 | 2799 | continue; |
uci1 | 40:1324da35afd4 | 2800 | } else { |
uci1 | 40:1324da35afd4 | 2801 | } |
uci1 | 28:484943132bb0 | 2802 | } |
uci1 | 84:80b15993944e | 2803 | */ |
uci1 | 84:80b15993944e | 2804 | |
uci1 | 28:484943132bb0 | 2805 | } // if duration >0 |
uci1 | 28:484943132bb0 | 2806 | |
uci1 | 28:484943132bb0 | 2807 | /* not working. must use DEFCONF.DAT to change IP's. |
uci1 | 28:484943132bb0 | 2808 | // change comm parameters (IP addresses) |
uci1 | 28:484943132bb0 | 2809 | #ifdef DEBUG |
uci1 | 28:484943132bb0 | 2810 | printf("set comm params\r\n"); |
uci1 | 28:484943132bb0 | 2811 | #endif |
uci1 | 28:484943132bb0 | 2812 | for (uint8_t cc=0; cc<kNcomms; cc++) { |
uci1 | 28:484943132bb0 | 2813 | if (gComms[cc]!=0) { |
uci1 | 28:484943132bb0 | 2814 | gComms[cc]->Set(gConf); |
uci1 | 15:f2569d8e4176 | 2815 | } |
uci1 | 0:664899e0b988 | 2816 | } |
uci1 | 28:484943132bb0 | 2817 | */ |
uci1 | 40:1324da35afd4 | 2818 | |
uci1 | 40:1324da35afd4 | 2819 | |
uci1 | 40:1324da35afd4 | 2820 | // check if we missed too many consecutive connections |
uci1 | 40:1324da35afd4 | 2821 | if (res<=SnCommWin::kAllFails) { |
uci1 | 40:1324da35afd4 | 2822 | ++gConsecCommFails; |
uci1 | 40:1324da35afd4 | 2823 | #ifdef DEBUG |
uci1 | 56:0bba0ef15697 | 2824 | printf("res=%d, gConsecCommFails=%hu, kMaxConsecCommFails=%hu\r\n", |
uci1 | 56:0bba0ef15697 | 2825 | static_cast<int>(res), gConsecCommFails,kMaxConsecCommFails); |
uci1 | 40:1324da35afd4 | 2826 | #endif |
uci1 | 40:1324da35afd4 | 2827 | if (gConsecCommFails>kMaxConsecCommFails) { |
uci1 | 40:1324da35afd4 | 2828 | #ifdef DEBUG |
uci1 | 40:1324da35afd4 | 2829 | printf("rebooting\r\n"); |
uci1 | 40:1324da35afd4 | 2830 | #endif |
uci1 | 40:1324da35afd4 | 2831 | // goodbye cruel world, it's over. walk on by... |
uci1 | 40:1324da35afd4 | 2832 | mbed_reset(); |
uci1 | 40:1324da35afd4 | 2833 | } |
uci1 | 40:1324da35afd4 | 2834 | } else { |
uci1 | 40:1324da35afd4 | 2835 | gConsecCommFails=0; |
uci1 | 40:1324da35afd4 | 2836 | } |
uci1 | 28:484943132bb0 | 2837 | |
uci1 | 4:a91682e19d6b | 2838 | // (probably) power down comms and power up cards,amps |
uci1 | 84:80b15993944e | 2839 | SetPower(false, SnConfigFrame::kIrid | SnConfigFrame::kAfar); |
uci1 | 4:a91682e19d6b | 2840 | |
uci1 | 1:e392595b4b76 | 2841 | // reset config with system powered (for DAC/PLA setting) |
uci1 | 12:d472f9811262 | 2842 | #ifdef DEBUG |
uci1 | 21:ce51bb0ba4a5 | 2843 | printf("calling SetConfigAndMakeOutputFile\r\n"); |
uci1 | 12:d472f9811262 | 2844 | #endif |
uci1 | 76:f8383f0292c2 | 2845 | |
uci1 | 76:f8383f0292c2 | 2846 | if (gConf.IsRunSeqListOneCommWinOnly()) { |
uci1 | 76:f8383f0292c2 | 2847 | SnSDUtils::ClearRunSeqList(gConf.IsSendingFilesRunSeqList()); |
uci1 | 76:f8383f0292c2 | 2848 | } |
uci1 | 22:f957c4f840ad | 2849 | |
uci1 | 21:ce51bb0ba4a5 | 2850 | SetConfigAndMakeOutputFile(); |
uci1 | 21:ce51bb0ba4a5 | 2851 | |
uci1 | 56:0bba0ef15697 | 2852 | // check power in case we should be in low power mode |
uci1 | 56:0bba0ef15697 | 2853 | // but don't save this reading to the file |
uci1 | 56:0bba0ef15697 | 2854 | // (there's already one near the beginning) |
uci1 | 56:0bba0ef15697 | 2855 | CheckPower(false, false); |
uci1 | 56:0bba0ef15697 | 2856 | |
uci1 | 12:d472f9811262 | 2857 | #ifdef DEBUG |
uci1 | 1:e392595b4b76 | 2858 | printf("closing comm win at %d\r\n",(int32_t)time(0)); |
uci1 | 84:80b15993944e | 2859 | printf("Free memory = %d\r\n", FreeMem()); |
uci1 | 12:d472f9811262 | 2860 | #endif |
uci1 | 67:ec999336fcd1 | 2861 | |
uci1 | 67:ec999336fcd1 | 2862 | led2 = 0; |
uci1 | 1:e392595b4b76 | 2863 | |
uci1 | 0:664899e0b988 | 2864 | gCommWinOpen = false; |
uci1 | 0:664899e0b988 | 2865 | return res; |
uci1 | 0:664899e0b988 | 2866 | } |