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