Arianna autonomous DAQ firmware
Dependencies: mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW
main.cpp@31:b5bd3b189150, 2013-01-23 (annotated)
- Committer:
- uci1
- Date:
- Wed Jan 23 19:29:01 2013 +0000
- Revision:
- 31:b5bd3b189150
- Parent:
- 30:f869ed4bcc08
- Child:
- 32:20877f862cf0
Added option in SnConstants to allow for proper switching of peripheral power in stations that have the Afar and Iridium power lines spliced together. Afar, SBD and Twitter comms enabled. Afar and Iridium powered together.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
uci1 | 0:664899e0b988 | 1 | #include "mbed.h" |
uci1 | 22:f957c4f840ad | 2 | // start a watchdog as soon as possible |
uci1 | 22:f957c4f840ad | 3 | #include "Watchdog.h" |
uci1 | 22:f957c4f840ad | 4 | Watchdog::SnKickStarter gKickStarter(WDFAILSAFE); |
uci1 | 0:664899e0b988 | 5 | |
uci1 | 31:b5bd3b189150 | 6 | #define DISABLE_CONFIG_SAFETYNETS |
uci1 | 31:b5bd3b189150 | 7 | |
uci1 | 25:57b2627fe756 | 8 | #define ENABLE_AFAR_COMM |
uci1 | 28:484943132bb0 | 9 | #define ENABLE_SBD_COMM |
uci1 | 25:57b2627fe756 | 10 | //#define ENABLE_USB_COMM |
uci1 | 28:484943132bb0 | 11 | #define ENABLE_AFAR_TWITTER |
uci1 | 25:57b2627fe756 | 12 | |
uci1 | 18:55f1581f2ee4 | 13 | //#define USE_RTOS_TIMER |
uci1 | 18:55f1581f2ee4 | 14 | //#define USE_ETH_INTERFACE |
uci1 | 12:d472f9811262 | 15 | //#define EVT_TIME_PROFILE |
uci1 | 14:2736b57bbbed | 16 | //#define DEBUG |
uci1 | 16:744ce85aede2 | 17 | //#define SSNOTIFY |
uci1 | 15:f2569d8e4176 | 18 | #define USE_MODSERIAL |
uci1 | 12:d472f9811262 | 19 | |
uci1 | 0:664899e0b988 | 20 | #include <stdint.h> |
uci1 | 0:664899e0b988 | 21 | #include "SDFileSystem.h" |
uci1 | 15:f2569d8e4176 | 22 | #ifdef USE_MODSERIAL |
uci1 | 0:664899e0b988 | 23 | #include "MODSERIAL.h" |
uci1 | 18:55f1581f2ee4 | 24 | #define MODSERIAL_RX_BUF_SIZE 512 |
uci1 | 18:55f1581f2ee4 | 25 | #define MODSERIAL_TX_BUF_SIZE 512 |
uci1 | 15:f2569d8e4176 | 26 | #endif |
uci1 | 21:ce51bb0ba4a5 | 27 | #include "FATDirHandle.h" |
uci1 | 21:ce51bb0ba4a5 | 28 | #include "EthernetPowerControl.h" |
uci1 | 0:664899e0b988 | 29 | #include "SnConstants.h" |
uci1 | 0:664899e0b988 | 30 | #include "SnBitUtils.h" |
uci1 | 0:664899e0b988 | 31 | #include "SnSDUtils.h" |
uci1 | 0:664899e0b988 | 32 | #include "SnConfigFrame.h" |
uci1 | 0:664899e0b988 | 33 | #include "SnEventFrame.h" |
uci1 | 0:664899e0b988 | 34 | #include "SnStatusFrame.h" |
uci1 | 2:e67f7c158087 | 35 | #include "SnHeaderFrame.h" |
uci1 | 22:f957c4f840ad | 36 | #include "SnHeartbeatFrame.h" |
uci1 | 0:664899e0b988 | 37 | #include "SnCommWin.h" |
uci1 | 18:55f1581f2ee4 | 38 | #ifdef USE_ETH_INTERFACE |
uci1 | 7:079617408fec | 39 | #include "SnCommAfarTCP.h" |
uci1 | 18:55f1581f2ee4 | 40 | #else |
uci1 | 18:55f1581f2ee4 | 41 | #include "SnCommAfarNetIf.h" |
uci1 | 28:484943132bb0 | 42 | #ifdef ENABLE_AFAR_TWITTER |
uci1 | 28:484943132bb0 | 43 | #include "SnCommAfarNetIfTwitter.h" |
uci1 | 28:484943132bb0 | 44 | #endif |
uci1 | 18:55f1581f2ee4 | 45 | #endif |
uci1 | 0:664899e0b988 | 46 | #include "SnCommUsb.h" |
uci1 | 15:f2569d8e4176 | 47 | #include "SnCommSBD.h" |
uci1 | 1:e392595b4b76 | 48 | #include "SnBase64.h" |
uci1 | 8:95a325df1f6b | 49 | #ifdef USE_RTOS_TIMER |
uci1 | 8:95a325df1f6b | 50 | #include "RtosTimer.h" |
uci1 | 8:95a325df1f6b | 51 | #endif |
uci1 | 0:664899e0b988 | 52 | |
uci1 | 31:b5bd3b189150 | 53 | |
uci1 | 0:664899e0b988 | 54 | // |
uci1 | 0:664899e0b988 | 55 | // MBED PINS (ordered by number) |
uci1 | 0:664899e0b988 | 56 | // |
uci1 | 0:664899e0b988 | 57 | // leds (for debugging) |
uci1 | 0:664899e0b988 | 58 | DigitalOut led1(LED1); |
uci1 | 0:664899e0b988 | 59 | DigitalOut led2(LED2); |
uci1 | 0:664899e0b988 | 60 | DigitalOut led3(LED3); |
uci1 | 0:664899e0b988 | 61 | DigitalOut led4(LED4); |
uci1 | 0:664899e0b988 | 62 | // Set up power pins - Note that it's Zero for "on" |
uci1 | 1:e392595b4b76 | 63 | DigitalOut PIN_turn_on_system(p17); // this turns on system |
uci1 | 0:664899e0b988 | 64 | DigitalOut PIN_turn_on_amps(p25); |
uci1 | 15:f2569d8e4176 | 65 | // SD card select |
uci1 | 15:f2569d8e4176 | 66 | DigitalOut PIN_SD_CS(p8); |
uci1 | 0:664899e0b988 | 67 | // Activate/select chip by falling edge |
uci1 | 0:664899e0b988 | 68 | DigitalOut PIN_ADC_CS( p9 ); |
uci1 | 0:664899e0b988 | 69 | // clock signal to activate PLA setting |
uci1 | 0:664899e0b988 | 70 | DigitalOut PIN_PLA_cs(p10); |
uci1 | 0:664899e0b988 | 71 | // To force a trigger |
uci1 | 0:664899e0b988 | 72 | DigitalOut PIN_forceTrigger(p11); //modification |
uci1 | 0:664899e0b988 | 73 | // To suppress thermal triggers |
uci1 | 0:664899e0b988 | 74 | DigitalOut PIN_enableThermTrig(p12); |
uci1 | 0:664899e0b988 | 75 | // Restart clock on all FPGAs. |
uci1 | 0:664899e0b988 | 76 | DigitalOut PIN_DoNotRestartAllClocks( p13 ); |
uci1 | 0:664899e0b988 | 77 | // This tells the DFPGAs to store the data on motherboard FPGA and |
uci1 | 0:664899e0b988 | 78 | // read it out. |
uci1 | 0:664899e0b988 | 79 | DigitalIn PIN_a_sf_clk( p14 ); |
uci1 | 0:664899e0b988 | 80 | DigitalIn PIN_rst_a_sf(p15); |
uci1 | 1:e392595b4b76 | 81 | // afar power |
uci1 | 1:e392595b4b76 | 82 | DigitalOut PIN_afar_power(p16); |
uci1 | 4:a91682e19d6b | 83 | // batter voltage/current measurement |
uci1 | 4:a91682e19d6b | 84 | AnalogIn PIN_vADC1(p19); |
uci1 | 4:a91682e19d6b | 85 | AnalogIn PIN_vADC2(p18); |
uci1 | 0:664899e0b988 | 86 | // Lock daughter card registeres (during data readout). |
uci1 | 0:664899e0b988 | 87 | DigitalOut PIN_lockRegisters( p20 ); |
uci1 | 1:e392595b4b76 | 88 | // iridium (SBD) power |
uci1 | 1:e392595b4b76 | 89 | DigitalOut PIN_iridSbd_power(p21); |
uci1 | 0:664899e0b988 | 90 | // Majority logic pins |
uci1 | 0:664899e0b988 | 91 | DigitalOut PIN_MajLogHiBit(p22); |
uci1 | 0:664899e0b988 | 92 | DigitalOut PIN_MajLogLoBit(p23); |
uci1 | 0:664899e0b988 | 93 | // Tell FPGA to be ready to accept DAC values |
uci1 | 0:664899e0b988 | 94 | DigitalOut PIN_start_fpga(p26); |
uci1 | 0:664899e0b988 | 95 | // Two bits to the select the daughter card for readout |
uci1 | 0:664899e0b988 | 96 | DigitalOut PIN_selCardHiBit( p29 ); |
uci1 | 0:664899e0b988 | 97 | DigitalOut PIN_selCardLoBit( p30 ); |
uci1 | 0:664899e0b988 | 98 | // To launch a heartbeat pulse |
uci1 | 0:664899e0b988 | 99 | DigitalOut PIN_heartbeat(p24); |
uci1 | 0:664899e0b988 | 100 | // Setup SPI pins |
uci1 | 0:664899e0b988 | 101 | SPI PIN_spi( p5, p6, p7 ); |
uci1 | 0:664899e0b988 | 102 | // The SD card |
uci1 | 3:24c5f0f50bf1 | 103 | |
uci1 | 3:24c5f0f50bf1 | 104 | // this needs to be first in case some other global uses a print statement |
uci1 | 15:f2569d8e4176 | 105 | #ifdef USE_MODSERIAL |
uci1 | 16:744ce85aede2 | 106 | #define SERIAL_TYPE MODSERIAL |
uci1 | 15:f2569d8e4176 | 107 | #else |
uci1 | 16:744ce85aede2 | 108 | #define SERIAL_TYPE Serial |
uci1 | 15:f2569d8e4176 | 109 | #endif |
uci1 | 16:744ce85aede2 | 110 | static SERIAL_TYPE gCpu( USBTX, USBRX // defined here so it might be used for debugging output |
uci1 | 16:744ce85aede2 | 111 | #ifdef USE_MODSERIAL |
uci1 | 16:744ce85aede2 | 112 | ,MODSERIAL_TX_BUF_SIZE, |
uci1 | 16:744ce85aede2 | 113 | MODSERIAL_RX_BUF_SIZE |
uci1 | 16:744ce85aede2 | 114 | #endif |
uci1 | 16:744ce85aede2 | 115 | ); |
uci1 | 16:744ce85aede2 | 116 | static SERIAL_TYPE gSBDport(p28, p27, "sbd"); |
uci1 | 21:ce51bb0ba4a5 | 117 | static SDFileSystem sd(p5, p6, p7, p8, SnSDUtils::kSDdir+1); // no leading '/' |
uci1 | 25:57b2627fe756 | 118 | static LocalFileSystem local((SnCommWin::kLocalDir)+1); // no leading '/' |
uci1 | 0:664899e0b988 | 119 | |
uci1 | 0:664899e0b988 | 120 | // |
uci1 | 0:664899e0b988 | 121 | // fwd declare fcns |
uci1 | 0:664899e0b988 | 122 | // |
uci1 | 0:664899e0b988 | 123 | void ReadAllRegisters(); |
uci1 | 0:664899e0b988 | 124 | void ReadRegister(const uint8_t chan, int16_t* dev); |
uci1 | 22:f957c4f840ad | 125 | void SaveHeartbeat(); |
uci1 | 0:664899e0b988 | 126 | void SaveEvent(const int32_t etms); |
uci1 | 0:664899e0b988 | 127 | void WaitTrigAndSendClock(); |
uci1 | 1:e392595b4b76 | 128 | void SetConfigAndMakeOutputFile(); |
uci1 | 13:7a1fb885a8e4 | 129 | SnCommWin::ECommWinResult OpenCommWin(const bool forceReconfig=false); |
uci1 | 3:24c5f0f50bf1 | 130 | void MakeOutputFile(const bool stopRunning=false); |
uci1 | 4:a91682e19d6b | 131 | void SetPower(const bool isCommWin); |
uci1 | 8:95a325df1f6b | 132 | void procForceTrigger(); |
uci1 | 8:95a325df1f6b | 133 | void procHeartbeat(); |
uci1 | 8:95a325df1f6b | 134 | void procPowerCheck(); |
uci1 | 8:95a325df1f6b | 135 | void procCommWin(); |
uci1 | 8:95a325df1f6b | 136 | #ifdef USE_RTOS_TIMER |
uci1 | 8:95a325df1f6b | 137 | void procForceTrigger(void const *) { return procForceTrigger(); } |
uci1 | 8:95a325df1f6b | 138 | void procHeartbeat(void const *) { return procHeartbeat(); } |
uci1 | 8:95a325df1f6b | 139 | void procPowerCheck(void const *) { return procPowerCheck(); } |
uci1 | 8:95a325df1f6b | 140 | void procCommWin(void const *) { return procCommWin(); } |
uci1 | 8:95a325df1f6b | 141 | #endif |
uci1 | 0:664899e0b988 | 142 | |
uci1 | 0:664899e0b988 | 143 | // |
uci1 | 0:664899e0b988 | 144 | // globals |
uci1 | 0:664899e0b988 | 145 | // |
uci1 | 0:664899e0b988 | 146 | // readout objs |
uci1 | 8:95a325df1f6b | 147 | // TODO: use RtosTimer instead of Ticker? |
uci1 | 8:95a325df1f6b | 148 | #ifdef USE_RTOS_TIMER |
uci1 | 8:95a325df1f6b | 149 | static rtos::RtosTimer* gForceTicker; |
uci1 | 8:95a325df1f6b | 150 | static rtos::RtosTimer* gHeartbeatTicker; |
uci1 | 8:95a325df1f6b | 151 | static rtos::RtosTimer* gCommWinTicker; |
uci1 | 8:95a325df1f6b | 152 | static rtos::RtosTimer* gPowerCheckTicker; |
uci1 | 8:95a325df1f6b | 153 | #else |
uci1 | 0:664899e0b988 | 154 | static Ticker gForceTicker; |
uci1 | 3:24c5f0f50bf1 | 155 | static Ticker gHeartbeatTicker; |
uci1 | 1:e392595b4b76 | 156 | static Ticker gCommWinTicker; |
uci1 | 8:95a325df1f6b | 157 | static Ticker gPowerCheckTicker; |
uci1 | 8:95a325df1f6b | 158 | #endif |
uci1 | 12:d472f9811262 | 159 | static Timer gTrgTimer; |
uci1 | 16:744ce85aede2 | 160 | static Timer gAdcToMBtimer; |
uci1 | 31:b5bd3b189150 | 161 | #ifdef DISABLE_CONFIG_SAFETYNETS |
uci1 | 31:b5bd3b189150 | 162 | static SnConfigFrame gConf(false); |
uci1 | 31:b5bd3b189150 | 163 | #else |
uci1 | 0:664899e0b988 | 164 | static SnConfigFrame gConf; |
uci1 | 31:b5bd3b189150 | 165 | #endif |
uci1 | 0:664899e0b988 | 166 | static SnEventFrame gEvent; |
uci1 | 8:95a325df1f6b | 167 | static SnPowerFrame gPower; |
uci1 | 0:664899e0b988 | 168 | // parameters |
uci1 | 21:ce51bb0ba4a5 | 169 | static bool gCardsPowered = false; |
uci1 | 0:664899e0b988 | 170 | static bool gFirstEvt = true; |
uci1 | 15:f2569d8e4176 | 171 | static volatile bool gReadingOut = false; |
uci1 | 15:f2569d8e4176 | 172 | static volatile bool gCommWinOpen = false; // if it's open |
uci1 | 1:e392595b4b76 | 173 | static volatile bool gOpenCommWin = false; // if it should be opened |
uci1 | 8:95a325df1f6b | 174 | static volatile bool gCheckPower = false; // if it should be checked |
uci1 | 8:95a325df1f6b | 175 | static uint32_t gPowNum = 0; |
uci1 | 8:95a325df1f6b | 176 | static uint32_t gEvtNum = 0; // num of evt written |
uci1 | 8:95a325df1f6b | 177 | static uint32_t gTrgNum[kNumTrgs] = {0}; // num of this type of trg received |
uci1 | 0:664899e0b988 | 178 | // i/o |
uci1 | 21:ce51bb0ba4a5 | 179 | static time_t gLastCommWin = 0; // time |
uci1 | 22:f957c4f840ad | 180 | static uint32_t gCommWinChecks = 0; |
uci1 | 22:f957c4f840ad | 181 | static uint32_t gNcommWinChecks = 0; |
uci1 | 22:f957c4f840ad | 182 | // heartbeat |
uci1 | 22:f957c4f840ad | 183 | static time_t gLastHrtbt = 0; |
uci1 | 23:ccf39298f205 | 184 | static volatile bool gHrtbtFired = false; |
uci1 | 22:f957c4f840ad | 185 | static uint32_t gHrtbtNum = 0; |
uci1 | 22:f957c4f840ad | 186 | // rates |
uci1 | 22:f957c4f840ad | 187 | static double gThmDtSum = 0; // sum of all time diffs between thermal trigs |
uci1 | 22:f957c4f840ad | 188 | static double gEvtDtSum = 0; // sum of all time diffs between events |
uci1 | 22:f957c4f840ad | 189 | static uint32_t gThmNumDt = 0; // number of thermal trig time diffs added up |
uci1 | 22:f957c4f840ad | 190 | static uint32_t gEvtNumDt = 0; // number of event time diffs added up |
uci1 | 10:3c93db1cfb12 | 191 | // this should be bigger than anything that will actually be used |
uci1 | 10:3c93db1cfb12 | 192 | static const uint32_t gBufSize=SnStatusFrame::kMaxSizeOf + (2u*SnHeaderFrame::kMaxSizeOf) + SnPowerFrame::kMaxSizeOf; |
uci1 | 6:6f002d202f59 | 193 | //static const uint32_t gB64Bsize=BASE64ENC_LEN(gBufSize)+1; |
uci1 | 6:6f002d202f59 | 194 | //static char gB64Buf[gB64Bsize]; |
uci1 | 3:24c5f0f50bf1 | 195 | static char gGenBuf[gBufSize]; // must be big enough for event or status or config! |
uci1 | 11:de443350ec4a | 196 | static SnCommWin* gComms[kNcomms] = { 0 }; // order => priority. afar uses RTOS, and must be made inside main |
uci1 | 28:484943132bb0 | 197 | #if defined(ENABLE_AFAR_TWITTER) && defined(ENABLE_AFAR_COMM) |
uci1 | 28:484943132bb0 | 198 | static SnCommAfarNetIfTwitter* gTwit = 0; |
uci1 | 28:484943132bb0 | 199 | #endif |
uci1 | 0:664899e0b988 | 200 | |
uci1 | 0:664899e0b988 | 201 | void procForceTrigger() { |
uci1 | 0:664899e0b988 | 202 | if (gReadingOut==false && gCommWinOpen==false) { |
uci1 | 15:f2569d8e4176 | 203 | led3=!led3; |
uci1 | 12:d472f9811262 | 204 | #ifdef DEBUG |
uci1 | 8:95a325df1f6b | 205 | printf("proc force\r\n"); |
uci1 | 12:d472f9811262 | 206 | #endif |
uci1 | 0:664899e0b988 | 207 | gEvent.SetTrgBit(kFrcTrg); |
uci1 | 21:ce51bb0ba4a5 | 208 | gEvent.SetTrgNum(++(gTrgNum[kFrcTrg])); |
uci1 | 23:ccf39298f205 | 209 | //PIN_forceTrigger = 0; |
uci1 | 0:664899e0b988 | 210 | PIN_forceTrigger = 1; // force a trigger |
uci1 | 21:ce51bb0ba4a5 | 211 | PIN_forceTrigger = 0; |
uci1 | 21:ce51bb0ba4a5 | 212 | #ifdef DEBUG |
uci1 | 21:ce51bb0ba4a5 | 213 | printf("PIN_forceTrigge=%d, PIN_turn_on_system=%d, " |
uci1 | 21:ce51bb0ba4a5 | 214 | "PIN_a_sf_clk=%d\r\n", |
uci1 | 21:ce51bb0ba4a5 | 215 | PIN_forceTrigger.read(), PIN_turn_on_system.read(), |
uci1 | 21:ce51bb0ba4a5 | 216 | PIN_a_sf_clk.read()); |
uci1 | 21:ce51bb0ba4a5 | 217 | #endif |
uci1 | 0:664899e0b988 | 218 | } |
uci1 | 0:664899e0b988 | 219 | } |
uci1 | 0:664899e0b988 | 220 | |
uci1 | 3:24c5f0f50bf1 | 221 | void procHeartbeat() { |
uci1 | 3:24c5f0f50bf1 | 222 | if (gReadingOut==false && gCommWinOpen==false) { |
uci1 | 12:d472f9811262 | 223 | #ifdef DEBUG |
uci1 | 8:95a325df1f6b | 224 | printf("proc heartbeat\r\n"); |
uci1 | 12:d472f9811262 | 225 | #endif |
uci1 | 23:ccf39298f205 | 226 | //PIN_heartbeat = 0; |
uci1 | 3:24c5f0f50bf1 | 227 | PIN_heartbeat = 1; // heartbeat pulse |
uci1 | 3:24c5f0f50bf1 | 228 | PIN_heartbeat = 0; |
uci1 | 22:f957c4f840ad | 229 | gLastHrtbt = time(0); |
uci1 | 22:f957c4f840ad | 230 | gHrtbtFired = true; |
uci1 | 22:f957c4f840ad | 231 | ++gHrtbtNum; |
uci1 | 3:24c5f0f50bf1 | 232 | } |
uci1 | 3:24c5f0f50bf1 | 233 | } |
uci1 | 3:24c5f0f50bf1 | 234 | |
uci1 | 8:95a325df1f6b | 235 | void procPowerCheck() { |
uci1 | 12:d472f9811262 | 236 | #ifdef DEBUG |
uci1 | 8:95a325df1f6b | 237 | printf("proc power\r\n"); |
uci1 | 12:d472f9811262 | 238 | #endif |
uci1 | 8:95a325df1f6b | 239 | gCheckPower=true; |
uci1 | 8:95a325df1f6b | 240 | } |
uci1 | 8:95a325df1f6b | 241 | |
uci1 | 0:664899e0b988 | 242 | void procCommWin() { |
uci1 | 22:f957c4f840ad | 243 | ++gCommWinChecks; |
uci1 | 27:efc4d654b139 | 244 | //if ( (time(0) - gLastCommWin) > gConf.GetCommWinPeriod() ) { |
uci1 | 22:f957c4f840ad | 245 | #ifdef DEBUG |
uci1 | 27:efc4d654b139 | 246 | printf("<><><><><><> gCommWinChecks=%u, gNcommWinChecks=%u\r\n", |
uci1 | 27:efc4d654b139 | 247 | gCommWinChecks, gNcommWinChecks); |
uci1 | 22:f957c4f840ad | 248 | #endif |
uci1 | 27:efc4d654b139 | 249 | if ( gCommWinChecks >= gNcommWinChecks ) { |
uci1 | 12:d472f9811262 | 250 | #ifdef DEBUG |
uci1 | 27:efc4d654b139 | 251 | printf("proc comm win.\r\n"); |
uci1 | 12:d472f9811262 | 252 | #endif |
uci1 | 27:efc4d654b139 | 253 | led3=!led3; |
uci1 | 27:efc4d654b139 | 254 | gOpenCommWin = true; |
uci1 | 0:664899e0b988 | 255 | } |
uci1 | 0:664899e0b988 | 256 | } |
uci1 | 0:664899e0b988 | 257 | |
uci1 | 21:ce51bb0ba4a5 | 258 | bool AreCardsPowered(const bool checkPin) { |
uci1 | 21:ce51bb0ba4a5 | 259 | #ifdef DEBUG |
uci1 | 21:ce51bb0ba4a5 | 260 | printf("acp: PIN_turn_on_system=%d, gCardsPowered=%d\r\n", |
uci1 | 21:ce51bb0ba4a5 | 261 | PIN_turn_on_system.read(), gCardsPowered); |
uci1 | 21:ce51bb0ba4a5 | 262 | #endif |
uci1 | 21:ce51bb0ba4a5 | 263 | if (checkPin) { |
uci1 | 21:ce51bb0ba4a5 | 264 | gCardsPowered = (PIN_turn_on_system.read()==0); |
uci1 | 16:744ce85aede2 | 265 | } |
uci1 | 21:ce51bb0ba4a5 | 266 | return gCardsPowered; |
uci1 | 8:95a325df1f6b | 267 | } |
uci1 | 0:664899e0b988 | 268 | |
uci1 | 8:95a325df1f6b | 269 | void GetAvePowerReading() { |
uci1 | 8:95a325df1f6b | 270 | // use one measurement as the assumed average |
uci1 | 8:95a325df1f6b | 271 | // in order to reduce computational errors |
uci1 | 8:95a325df1f6b | 272 | int32_t v1, v2; |
uci1 | 8:95a325df1f6b | 273 | const uint16_t aaveV1 = PIN_vADC1.read_u16(); |
uci1 | 8:95a325df1f6b | 274 | const uint16_t aaveV2 = PIN_vADC2.read_u16(); |
uci1 | 8:95a325df1f6b | 275 | float n=0, ave1=0, ave2=0, rms1=0, rms2=0; |
uci1 | 8:95a325df1f6b | 276 | for (uint16_t i=0; i<kNvoltsAve; i++) { |
uci1 | 8:95a325df1f6b | 277 | v1 = PIN_vADC1.read_u16() - aaveV1; |
uci1 | 8:95a325df1f6b | 278 | v2 = PIN_vADC2.read_u16() - aaveV2; |
uci1 | 8:95a325df1f6b | 279 | n += 1; |
uci1 | 8:95a325df1f6b | 280 | ave1 += v1; |
uci1 | 8:95a325df1f6b | 281 | rms1 += v1*v1; |
uci1 | 8:95a325df1f6b | 282 | ave2 += v2; |
uci1 | 8:95a325df1f6b | 283 | rms2 += v2*v2; |
uci1 | 8:95a325df1f6b | 284 | } |
uci1 | 8:95a325df1f6b | 285 | rms1 -= (ave1*ave1)/n; |
uci1 | 8:95a325df1f6b | 286 | rms2 -= (ave2*ave2)/n; |
uci1 | 8:95a325df1f6b | 287 | rms1 /= n-1; |
uci1 | 8:95a325df1f6b | 288 | rms2 /= n-1; |
uci1 | 9:a1a39573dd43 | 289 | rms1 = sqrt(rms1); |
uci1 | 9:a1a39573dd43 | 290 | rms2 = sqrt(rms2); |
uci1 | 8:95a325df1f6b | 291 | ave1 /= n; |
uci1 | 8:95a325df1f6b | 292 | ave2 /= n; |
uci1 | 8:95a325df1f6b | 293 | ave1 += aaveV1; |
uci1 | 8:95a325df1f6b | 294 | ave2 += aaveV2; |
uci1 | 8:95a325df1f6b | 295 | gPower.Set(ave1, ave2, rms1, rms2, time(0)); |
uci1 | 8:95a325df1f6b | 296 | } |
uci1 | 0:664899e0b988 | 297 | |
uci1 | 8:95a325df1f6b | 298 | void CheckPower(const bool isCommWin) { |
uci1 | 12:d472f9811262 | 299 | #ifdef DEBUG |
uci1 | 8:95a325df1f6b | 300 | printf("CheckPower\r\n"); |
uci1 | 12:d472f9811262 | 301 | #endif |
uci1 | 8:95a325df1f6b | 302 | // read power |
uci1 | 8:95a325df1f6b | 303 | GetAvePowerReading(); |
uci1 | 8:95a325df1f6b | 304 | // save to disk |
uci1 | 8:95a325df1f6b | 305 | FILE* cf = SnSDUtils::GetCurFile(); |
uci1 | 8:95a325df1f6b | 306 | if (cf!=0) { |
uci1 | 11:de443350ec4a | 307 | PIN_lockRegisters = 0; // unlock so we can talk to SD card. |
uci1 | 12:d472f9811262 | 308 | #ifdef DEBUG |
uci1 | 8:95a325df1f6b | 309 | printf("writing power. v1=%g, v2=%g, r1=%g, r2=%g, t=%u, pownum=%u\r\n", |
uci1 | 8:95a325df1f6b | 310 | gPower.GetAveV1(), gPower.GetAveV2(), |
uci1 | 8:95a325df1f6b | 311 | gPower.GetRmsV1(), gPower.GetRmsV2(), gPower.GetTime(), |
uci1 | 8:95a325df1f6b | 312 | gPowNum); |
uci1 | 12:d472f9811262 | 313 | #endif |
uci1 | 8:95a325df1f6b | 314 | SnSDUtils::WritePowerTo(cf, gPower, gPowNum); |
uci1 | 8:95a325df1f6b | 315 | } |
uci1 | 8:95a325df1f6b | 316 | // do we need to change modes? |
uci1 | 8:95a325df1f6b | 317 | bool changed = false; |
uci1 | 8:95a325df1f6b | 318 | if (gConf.IsLowPowerMode()) { |
uci1 | 8:95a325df1f6b | 319 | if (gPower.GetAveV1() > gConf.GetBatVoltLowPwr()) { |
uci1 | 12:d472f9811262 | 320 | #ifdef DEBUG |
uci1 | 8:95a325df1f6b | 321 | printf("chaing to normal power!\r\n"); |
uci1 | 12:d472f9811262 | 322 | #endif |
uci1 | 8:95a325df1f6b | 323 | gConf.ChangeToNormPower(); |
uci1 | 8:95a325df1f6b | 324 | changed = true; |
uci1 | 8:95a325df1f6b | 325 | } |
uci1 | 8:95a325df1f6b | 326 | } else { |
uci1 | 8:95a325df1f6b | 327 | if (gPower.GetAveV1() < gConf.GetBatVoltLowPwr()) { |
uci1 | 12:d472f9811262 | 328 | #ifdef DEBUG |
uci1 | 8:95a325df1f6b | 329 | printf("chaing to low power!\r\n"); |
uci1 | 12:d472f9811262 | 330 | #endif |
uci1 | 8:95a325df1f6b | 331 | gConf.ChangeToLowPower(); |
uci1 | 8:95a325df1f6b | 332 | changed = true; |
uci1 | 8:95a325df1f6b | 333 | } |
uci1 | 8:95a325df1f6b | 334 | } |
uci1 | 8:95a325df1f6b | 335 | if (changed) { |
uci1 | 31:b5bd3b189150 | 336 | SetPower(isCommWin); // TODO: This will fail if isCommWin==false? (currently not possible, but..) |
uci1 | 12:d472f9811262 | 337 | #ifdef DEBUG |
uci1 | 8:95a325df1f6b | 338 | printf("Using config %s\r\n",gConf.GetLabel()); |
uci1 | 12:d472f9811262 | 339 | #endif |
uci1 | 8:95a325df1f6b | 340 | SetConfigAndMakeOutputFile(); // setup defaults in case no communication |
uci1 | 8:95a325df1f6b | 341 | } |
uci1 | 8:95a325df1f6b | 342 | // checking done |
uci1 | 8:95a325df1f6b | 343 | gCheckPower = false; |
uci1 | 8:95a325df1f6b | 344 | } |
uci1 | 8:95a325df1f6b | 345 | |
uci1 | 10:3c93db1cfb12 | 346 | void ResetCountersClearEvt() { |
uci1 | 12:d472f9811262 | 347 | const uint32_t evtStartCurSeq = (SnSDUtils::GetCurSeqNum()) // no -1; start with seq=0 |
uci1 | 12:d472f9811262 | 348 | * gConf.GetEvtsPerFile(); |
uci1 | 10:3c93db1cfb12 | 349 | gEvent.ClearEvent(); |
uci1 | 12:d472f9811262 | 350 | gEvtNum = gConf.GetFirstEvt() + evtStartCurSeq; |
uci1 | 12:d472f9811262 | 351 | gPowNum = evtStartCurSeq; |
uci1 | 10:3c93db1cfb12 | 352 | memset(gTrgNum, 0, sizeof(uint32_t)*kNumTrgs); |
uci1 | 22:f957c4f840ad | 353 | // reset rate counters |
uci1 | 22:f957c4f840ad | 354 | gThmDtSum = 0; |
uci1 | 22:f957c4f840ad | 355 | gThmNumDt = 0; |
uci1 | 22:f957c4f840ad | 356 | gEvtDtSum = 0; |
uci1 | 22:f957c4f840ad | 357 | gEvtNumDt = 0; |
uci1 | 22:f957c4f840ad | 358 | // reset heartbeat counters |
uci1 | 22:f957c4f840ad | 359 | gLastHrtbt = 0; |
uci1 | 22:f957c4f840ad | 360 | gHrtbtFired = false; |
uci1 | 22:f957c4f840ad | 361 | gHrtbtNum = 0; |
uci1 | 13:7a1fb885a8e4 | 362 | #ifdef DEBUG |
uci1 | 13:7a1fb885a8e4 | 363 | printf("Reset: gEvtNum=%u, gPowNum=%u, evtStartCS=%u\r\n", |
uci1 | 13:7a1fb885a8e4 | 364 | gEvtNum, gPowNum, evtStartCurSeq); |
uci1 | 13:7a1fb885a8e4 | 365 | #endif |
uci1 | 10:3c93db1cfb12 | 366 | } |
uci1 | 10:3c93db1cfb12 | 367 | |
uci1 | 10:3c93db1cfb12 | 368 | void GetRates(float& thmrate, float& evtrate) { |
uci1 | 10:3c93db1cfb12 | 369 | thmrate = evtrate = 0; |
uci1 | 22:f957c4f840ad | 370 | #ifdef DEBUG |
uci1 | 22:f957c4f840ad | 371 | printf("** Getting rates: gThmNumDt=%d, gThmDtSum=%g, " |
uci1 | 22:f957c4f840ad | 372 | "gEvtNumDt=%d, gEvtDtSum=%g\r\n", |
uci1 | 22:f957c4f840ad | 373 | gThmNumDt, gThmDtSum, gEvtNumDt, gEvtDtSum); |
uci1 | 22:f957c4f840ad | 374 | #endif |
uci1 | 22:f957c4f840ad | 375 | |
uci1 | 22:f957c4f840ad | 376 | thmrate = (gThmDtSum>0.0) ? static_cast<float>(gThmNumDt) / (gThmDtSum/1e3) |
uci1 | 22:f957c4f840ad | 377 | : 0; |
uci1 | 22:f957c4f840ad | 378 | evtrate = (gEvtDtSum>0.0) ? static_cast<float>(gEvtNumDt) / (gEvtDtSum/1e3) |
uci1 | 22:f957c4f840ad | 379 | : 0; |
uci1 | 22:f957c4f840ad | 380 | } |
uci1 | 22:f957c4f840ad | 381 | |
uci1 | 22:f957c4f840ad | 382 | void AddToRate(const float dt, const bool isThm) { |
uci1 | 22:f957c4f840ad | 383 | if (isThm) { |
uci1 | 22:f957c4f840ad | 384 | gThmDtSum += dt; |
uci1 | 22:f957c4f840ad | 385 | gThmNumDt += 1u; |
uci1 | 22:f957c4f840ad | 386 | } else { |
uci1 | 22:f957c4f840ad | 387 | gEvtDtSum += dt; |
uci1 | 22:f957c4f840ad | 388 | gEvtNumDt += 1u; |
uci1 | 10:3c93db1cfb12 | 389 | } |
uci1 | 22:f957c4f840ad | 390 | #ifdef DEBUG |
uci1 | 22:f957c4f840ad | 391 | printf("** AddToRate: dt=%g, isThm=%d\r\n",dt,(int)isThm); |
uci1 | 22:f957c4f840ad | 392 | printf("** AddToRate: gThmNumDt=%d, gThmDtSum=%g, " |
uci1 | 22:f957c4f840ad | 393 | "gEvtNumDt=%d, gEvtDtSum=%g\r\n", |
uci1 | 22:f957c4f840ad | 394 | gThmNumDt, gThmDtSum, gEvtNumDt, gEvtDtSum); |
uci1 | 22:f957c4f840ad | 395 | #endif |
uci1 | 10:3c93db1cfb12 | 396 | } |
uci1 | 10:3c93db1cfb12 | 397 | |
uci1 | 8:95a325df1f6b | 398 | bool IsSeqComplete() { |
uci1 | 12:d472f9811262 | 399 | #ifdef DEBUG |
uci1 | 12:d472f9811262 | 400 | printf("IsSeqComplete: eps=%u, cntpow=%d, fe=%u, pow=%u, evt=%u, seq=%hu\r\n", |
uci1 | 10:3c93db1cfb12 | 401 | gConf.GetEvtsPerFile(), (int)gConf.IsCountingPowerReadings(), |
uci1 | 12:d472f9811262 | 402 | gConf.GetFirstEvt(), gPowNum, gEvtNum, SnSDUtils::GetCurSeqNum()); |
uci1 | 12:d472f9811262 | 403 | #endif |
uci1 | 8:95a325df1f6b | 404 | if (gConf.GetEvtsPerFile()>0) { |
uci1 | 12:d472f9811262 | 405 | const uint32_t evtEndCurSeq = (SnSDUtils::GetCurSeqNum()+1) // account for seq=0 |
uci1 | 12:d472f9811262 | 406 | * gConf.GetEvtsPerFile(); |
uci1 | 12:d472f9811262 | 407 | #ifdef DEBUG |
uci1 | 12:d472f9811262 | 408 | printf("evtEndCurSeq=%u\r\n",evtEndCurSeq); |
uci1 | 12:d472f9811262 | 409 | #endif |
uci1 | 8:95a325df1f6b | 410 | if (gConf.IsCountingPowerReadings()) { |
uci1 | 12:d472f9811262 | 411 | return (gPowNum>=evtEndCurSeq); |
uci1 | 8:95a325df1f6b | 412 | } else { |
uci1 | 12:d472f9811262 | 413 | // first event num is a one-time per run offset, not one per sequence |
uci1 | 12:d472f9811262 | 414 | return (gEvtNum>=(gConf.GetFirstEvt()+evtEndCurSeq)); |
uci1 | 8:95a325df1f6b | 415 | } |
uci1 | 12:d472f9811262 | 416 | } else { |
uci1 | 12:d472f9811262 | 417 | return false; |
uci1 | 8:95a325df1f6b | 418 | } |
uci1 | 8:95a325df1f6b | 419 | } |
uci1 | 1:e392595b4b76 | 420 | |
uci1 | 8:95a325df1f6b | 421 | #ifdef USE_RTOS_TIMER |
uci1 | 8:95a325df1f6b | 422 | void stopTicker(rtos::RtosTimer* tik) { |
uci1 | 8:95a325df1f6b | 423 | if (tik!=0) { |
uci1 | 8:95a325df1f6b | 424 | tik->stop(); |
uci1 | 8:95a325df1f6b | 425 | } |
uci1 | 8:95a325df1f6b | 426 | } |
uci1 | 8:95a325df1f6b | 427 | #else |
uci1 | 8:95a325df1f6b | 428 | void stopTicker(Ticker& tik) { |
uci1 | 8:95a325df1f6b | 429 | tik.detach(); |
uci1 | 8:95a325df1f6b | 430 | } |
uci1 | 8:95a325df1f6b | 431 | #endif |
uci1 | 8:95a325df1f6b | 432 | |
uci1 | 8:95a325df1f6b | 433 | #ifdef USE_RTOS_TIMER |
uci1 | 18:55f1581f2ee4 | 434 | float resetTicker(rtos::RtosTimer* tik, const float timSec, |
uci1 | 18:55f1581f2ee4 | 435 | const float maxTimSec) { |
uci1 | 8:95a325df1f6b | 436 | if (tik!=0) { |
uci1 | 8:95a325df1f6b | 437 | tik->stop(); |
uci1 | 8:95a325df1f6b | 438 | if (timSec>0) { |
uci1 | 18:55f1581f2ee4 | 439 | float tp = timSec > maxTimSec ? maxTimSec : timSec; |
uci1 | 8:95a325df1f6b | 440 | tp *= 1000u; // ms |
uci1 | 8:95a325df1f6b | 441 | tik->start(tp); |
uci1 | 8:95a325df1f6b | 442 | return tp; |
uci1 | 8:95a325df1f6b | 443 | } |
uci1 | 8:95a325df1f6b | 444 | } |
uci1 | 8:95a325df1f6b | 445 | return 0; |
uci1 | 8:95a325df1f6b | 446 | } |
uci1 | 8:95a325df1f6b | 447 | #else |
uci1 | 18:55f1581f2ee4 | 448 | float resetTicker(Ticker& tik, const float timSec, |
uci1 | 18:55f1581f2ee4 | 449 | const float maxTimSec, void (*fptr)(void)) { |
uci1 | 8:95a325df1f6b | 450 | tik.detach(); |
uci1 | 8:95a325df1f6b | 451 | if (timSec>0) { |
uci1 | 18:55f1581f2ee4 | 452 | const float tp = timSec > maxTimSec ? maxTimSec : timSec; |
uci1 | 8:95a325df1f6b | 453 | tik.attach(fptr, tp); |
uci1 | 8:95a325df1f6b | 454 | return tp; |
uci1 | 8:95a325df1f6b | 455 | } |
uci1 | 8:95a325df1f6b | 456 | return 0; |
uci1 | 8:95a325df1f6b | 457 | } |
uci1 | 8:95a325df1f6b | 458 | #endif |
uci1 | 8:95a325df1f6b | 459 | |
uci1 | 15:f2569d8e4176 | 460 | void StopAllTickers() { |
uci1 | 8:95a325df1f6b | 461 | stopTicker(gForceTicker); |
uci1 | 8:95a325df1f6b | 462 | stopTicker(gHeartbeatTicker); |
uci1 | 8:95a325df1f6b | 463 | stopTicker(gCommWinTicker); |
uci1 | 8:95a325df1f6b | 464 | stopTicker(gPowerCheckTicker); |
uci1 | 15:f2569d8e4176 | 465 | } |
uci1 | 15:f2569d8e4176 | 466 | |
uci1 | 15:f2569d8e4176 | 467 | void ResetAllTickers() { |
uci1 | 15:f2569d8e4176 | 468 | #ifdef USE_RTOS_TIMER |
uci1 | 18:55f1581f2ee4 | 469 | const float ftp = resetTicker(gForceTicker, gConf.GetForceTrigPeriod(), |
uci1 | 18:55f1581f2ee4 | 470 | kAbsMaxTimer); |
uci1 | 25:57b2627fe756 | 471 | wait_ms(131); // make it less likely for multiple triggers to fire too close together |
uci1 | 18:55f1581f2ee4 | 472 | const float hbp = resetTicker(gHeartbeatTicker, gConf.GetHeartbeatPeriod(), |
uci1 | 18:55f1581f2ee4 | 473 | kAbsMaxTimer); |
uci1 | 25:57b2627fe756 | 474 | wait_ms(173); // make it less likely for multiple triggers to fire too close together |
uci1 | 18:55f1581f2ee4 | 475 | const float cwp = resetTicker(gCommWinTicker, gConf.GetCommWinPeriod(), |
uci1 | 18:55f1581f2ee4 | 476 | kCommWinLongPrdTk); |
uci1 | 25:57b2627fe756 | 477 | wait_ms(169); // make it less likely for multiple triggers to fire too close together |
uci1 | 18:55f1581f2ee4 | 478 | const float pcp = resetTicker(gPowerCheckTicker, gConf.GetVoltCheckPeriod(), |
uci1 | 18:55f1581f2ee4 | 479 | kAbsMaxTimer); |
uci1 | 15:f2569d8e4176 | 480 | #else |
uci1 | 18:55f1581f2ee4 | 481 | const float ftp = resetTicker(gForceTicker, gConf.GetForceTrigPeriod(), |
uci1 | 18:55f1581f2ee4 | 482 | kAbsMaxTimer, &procForceTrigger); |
uci1 | 25:57b2627fe756 | 483 | wait_ms(131); // make it less likely for multiple triggers to fire too close together |
uci1 | 18:55f1581f2ee4 | 484 | const float hbp = resetTicker(gHeartbeatTicker, gConf.GetHeartbeatPeriod(), |
uci1 | 18:55f1581f2ee4 | 485 | kAbsMaxTimer, &procHeartbeat); |
uci1 | 25:57b2627fe756 | 486 | wait_ms(173); // make it less likely for multiple triggers to fire too close together |
uci1 | 18:55f1581f2ee4 | 487 | const float cwp = resetTicker(gCommWinTicker, gConf.GetCommWinPeriod(), |
uci1 | 18:55f1581f2ee4 | 488 | kCommWinLongPrdTk, &procCommWin); |
uci1 | 25:57b2627fe756 | 489 | wait_ms(169); // make it less likely for multiple triggers to fire too close together |
uci1 | 18:55f1581f2ee4 | 490 | const float pcp = resetTicker(gPowerCheckTicker, gConf.GetVoltCheckPeriod(), |
uci1 | 18:55f1581f2ee4 | 491 | kAbsMaxTimer, &procPowerCheck); |
uci1 | 15:f2569d8e4176 | 492 | #endif |
uci1 | 15:f2569d8e4176 | 493 | #ifdef DEBUG |
uci1 | 18:55f1581f2ee4 | 494 | printf("attach force trig %g\r\n",ftp); |
uci1 | 18:55f1581f2ee4 | 495 | printf("attach heart beat %g\r\n",hbp); |
uci1 | 18:55f1581f2ee4 | 496 | printf("attach comm win %g\r\n",cwp); |
uci1 | 18:55f1581f2ee4 | 497 | printf("attach power chk %g\r\n",pcp); |
uci1 | 15:f2569d8e4176 | 498 | #endif |
uci1 | 15:f2569d8e4176 | 499 | } |
uci1 | 15:f2569d8e4176 | 500 | |
uci1 | 15:f2569d8e4176 | 501 | void StopRunning() { |
uci1 | 15:f2569d8e4176 | 502 | #if defined(DEBUG) || defined(SSNOTIFY) |
uci1 | 15:f2569d8e4176 | 503 | printf("stop running\r\n"); |
uci1 | 15:f2569d8e4176 | 504 | #endif |
uci1 | 15:f2569d8e4176 | 505 | StopAllTickers(); |
uci1 | 17:4687bf932b8c | 506 | OpenCommWin(); |
uci1 | 8:95a325df1f6b | 507 | while (true) { |
uci1 | 8:95a325df1f6b | 508 | led3 = 1; led4=1; |
uci1 | 8:95a325df1f6b | 509 | wait(0.5); |
uci1 | 8:95a325df1f6b | 510 | led3 = 0; led4=0; |
uci1 | 8:95a325df1f6b | 511 | wait(0.5); |
uci1 | 22:f957c4f840ad | 512 | // don't kick the watchdog |
uci1 | 22:f957c4f840ad | 513 | // if we do, the station is unrecoverable without physical access |
uci1 | 8:95a325df1f6b | 514 | } |
uci1 | 8:95a325df1f6b | 515 | } |
uci1 | 1:e392595b4b76 | 516 | |
uci1 | 0:664899e0b988 | 517 | int main() { |
uci1 | 22:f957c4f840ad | 518 | // a failsafe |
uci1 | 22:f957c4f840ad | 519 | Watchdog::kick(WDFAILSAFE); |
uci1 | 27:efc4d654b139 | 520 | |
uci1 | 1:e392595b4b76 | 521 | { |
uci1 | 25:57b2627fe756 | 522 | gCpu.baud(CPUBAUD_SN); |
uci1 | 18:55f1581f2ee4 | 523 | #if defined(SSNOTIFY) || defined(DEBUG) |
uci1 | 15:f2569d8e4176 | 524 | printf("main: start\r\n"); |
uci1 | 15:f2569d8e4176 | 525 | #endif |
uci1 | 2:e67f7c158087 | 526 | led1=1; wait(0.2); |
uci1 | 2:e67f7c158087 | 527 | led1=0; led2=1; wait(0.2); |
uci1 | 2:e67f7c158087 | 528 | led2=0; led3=1; wait(0.2); |
uci1 | 2:e67f7c158087 | 529 | led3=0; led4=1; wait(0.2); |
uci1 | 1:e392595b4b76 | 530 | led4=0; |
uci1 | 1:e392595b4b76 | 531 | } |
uci1 | 25:57b2627fe756 | 532 | |
uci1 | 18:55f1581f2ee4 | 533 | #ifdef DEBUG |
uci1 | 21:ce51bb0ba4a5 | 534 | printf("initializing SD card..\r\n"); |
uci1 | 21:ce51bb0ba4a5 | 535 | #endif |
uci1 | 21:ce51bb0ba4a5 | 536 | // initialize the SD card. this should prevent the issue with |
uci1 | 21:ce51bb0ba4a5 | 537 | // seq 0 being overwritten upon power up or the SD card first |
uci1 | 21:ce51bb0ba4a5 | 538 | // being insterted |
uci1 | 21:ce51bb0ba4a5 | 539 | sd.disk_initialize(); |
uci1 | 25:57b2627fe756 | 540 | |
uci1 | 21:ce51bb0ba4a5 | 541 | #ifdef DEBUG |
uci1 | 18:55f1581f2ee4 | 542 | printf("making comm objects\r\n"); |
uci1 | 18:55f1581f2ee4 | 543 | #endif |
uci1 | 25:57b2627fe756 | 544 | |
uci1 | 25:57b2627fe756 | 545 | uint8_t comi(0); |
uci1 | 25:57b2627fe756 | 546 | #ifdef ENABLE_AFAR_COMM |
uci1 | 25:57b2627fe756 | 547 | // RTOS stuff must be made inside main for some reason |
uci1 | 18:55f1581f2ee4 | 548 | #ifdef USE_ETH_INTERFACE |
uci1 | 25:57b2627fe756 | 549 | gComms[comi++] = new SnCommAfarTCP(gConf); |
uci1 | 18:55f1581f2ee4 | 550 | #else |
uci1 | 25:57b2627fe756 | 551 | gComms[comi++] = new SnCommAfarNetIf(gConf); |
uci1 | 28:484943132bb0 | 552 | #ifdef ENABLE_AFAR_TWITTER |
uci1 | 28:484943132bb0 | 553 | gTwit = new SnCommAfarNetIfTwitter(gConf); |
uci1 | 28:484943132bb0 | 554 | #endif |
uci1 | 25:57b2627fe756 | 555 | #endif |
uci1 | 18:55f1581f2ee4 | 556 | #endif |
uci1 | 25:57b2627fe756 | 557 | #ifdef ENABLE_SBD_COMM |
uci1 | 25:57b2627fe756 | 558 | gComms[comi++] = new SnCommSBD(&gSBDport, &gCpu); |
uci1 | 25:57b2627fe756 | 559 | #endif |
uci1 | 25:57b2627fe756 | 560 | #ifdef ENABLE_USB_COMM |
uci1 | 25:57b2627fe756 | 561 | gComms[comi++] = new SnCommUsb(&gCpu); |
uci1 | 25:57b2627fe756 | 562 | #endif |
uci1 | 18:55f1581f2ee4 | 563 | |
uci1 | 18:55f1581f2ee4 | 564 | #ifdef DEBUG |
uci1 | 28:484943132bb0 | 565 | printf("made comm objects\r\n"); |
uci1 | 18:55f1581f2ee4 | 566 | #endif |
uci1 | 28:484943132bb0 | 567 | |
uci1 | 8:95a325df1f6b | 568 | #ifdef USE_RTOS_TIMER |
uci1 | 8:95a325df1f6b | 569 | gForceTicker = new rtos::RtosTimer(&procForceTrigger); |
uci1 | 8:95a325df1f6b | 570 | gHeartbeatTicker = new rtos::RtosTimer(&procHeartbeat); |
uci1 | 8:95a325df1f6b | 571 | gCommWinTicker = new rtos::RtosTimer(&procCommWin); |
uci1 | 8:95a325df1f6b | 572 | gPowerCheckTicker = new rtos::RtosTimer(&procPowerCheck); |
uci1 | 8:95a325df1f6b | 573 | #endif |
uci1 | 8:95a325df1f6b | 574 | |
uci1 | 0:664899e0b988 | 575 | led2=1; |
uci1 | 0:664899e0b988 | 576 | //wait_ms(100); |
uci1 | 1:e392595b4b76 | 577 | |
uci1 | 12:d472f9811262 | 578 | #ifdef DEBUG |
uci1 | 3:24c5f0f50bf1 | 579 | printf("\n\n\n\n\n\nstarting\r\n"); |
uci1 | 12:d472f9811262 | 580 | #endif |
uci1 | 1:e392595b4b76 | 581 | |
uci1 | 1:e392595b4b76 | 582 | // set the clock to the BS time, if it's not set |
uci1 | 1:e392595b4b76 | 583 | if ( (static_cast<int32_t>(time(0)))<0 ) { |
uci1 | 1:e392595b4b76 | 584 | set_time(kBStime); |
uci1 | 1:e392595b4b76 | 585 | } |
uci1 | 12:d472f9811262 | 586 | #ifdef DEBUG |
uci1 | 1:e392595b4b76 | 587 | printf("time = %d\r\n",(int32_t)time(0)); |
uci1 | 12:d472f9811262 | 588 | #endif |
uci1 | 1:e392595b4b76 | 589 | gLastCommWin = time(0); // prevent comm win proc |
uci1 | 0:664899e0b988 | 590 | |
uci1 | 8:95a325df1f6b | 591 | #ifdef USE_RTOS_TIMER |
uci1 | 8:95a325df1f6b | 592 | gForceTicker->stop(); |
uci1 | 8:95a325df1f6b | 593 | #else |
uci1 | 0:664899e0b988 | 594 | gForceTicker.detach(); |
uci1 | 8:95a325df1f6b | 595 | #endif |
uci1 | 0:664899e0b988 | 596 | gFirstEvt = true; |
uci1 | 0:664899e0b988 | 597 | |
uci1 | 4:a91682e19d6b | 598 | // (probably) power down comms and power up cards,amps |
uci1 | 4:a91682e19d6b | 599 | SetPower(false); |
uci1 | 4:a91682e19d6b | 600 | |
uci1 | 0:664899e0b988 | 601 | // |
uci1 | 0:664899e0b988 | 602 | // get config |
uci1 | 0:664899e0b988 | 603 | // |
uci1 | 12:d472f9811262 | 604 | #ifdef DEBUG |
uci1 | 8:95a325df1f6b | 605 | printf("call OpenCommWin\r\n"); |
uci1 | 12:d472f9811262 | 606 | #endif |
uci1 | 13:7a1fb885a8e4 | 607 | OpenCommWin(true); // alwasy configure, even if no new config |
uci1 | 3:24c5f0f50bf1 | 608 | |
uci1 | 0:664899e0b988 | 609 | // get ready to trigger |
uci1 | 0:664899e0b988 | 610 | PIN_spi.format( 16, 1 ); // change to data readout format |
uci1 | 15:f2569d8e4176 | 611 | PIN_spi.frequency( 10000000 ); // Max is 12.5 MHz |
uci1 | 0:664899e0b988 | 612 | |
uci1 | 0:664899e0b988 | 613 | led2=0; |
uci1 | 0:664899e0b988 | 614 | |
uci1 | 0:664899e0b988 | 615 | // the main event loop. wait for triggers in SendClock |
uci1 | 21:ce51bb0ba4a5 | 616 | AreCardsPowered(true); |
uci1 | 12:d472f9811262 | 617 | gTrgTimer.start(); |
uci1 | 12:d472f9811262 | 618 | register int32_t etms=0; // time between written events |
uci1 | 0:664899e0b988 | 619 | while( true ) |
uci1 | 0:664899e0b988 | 620 | { |
uci1 | 0:664899e0b988 | 621 | // in here, we wait for triggers from the MB-FPGA |
uci1 | 0:664899e0b988 | 622 | Watchdog::kick(); // don't reset! |
uci1 | 1:e392595b4b76 | 623 | |
uci1 | 1:e392595b4b76 | 624 | led1 = !led1; |
uci1 | 1:e392595b4b76 | 625 | |
uci1 | 12:d472f9811262 | 626 | #ifdef DEBUG |
uci1 | 1:e392595b4b76 | 627 | printf("calling wait trig\r\n"); |
uci1 | 1:e392595b4b76 | 628 | printf("gFirstEvt=%s\r\n",gFirstEvt?"true":"false"); |
uci1 | 5:9cea89700c66 | 629 | printf("readingout=%d\r\n",(int)gReadingOut); |
uci1 | 12:d472f9811262 | 630 | #endif |
uci1 | 0:664899e0b988 | 631 | PIN_lockRegisters = 0; // allow data to come from DFPGA |
uci1 | 0:664899e0b988 | 632 | WaitTrigAndSendClock(); |
uci1 | 0:664899e0b988 | 633 | PIN_lockRegisters = 1; // block registers during readout |
uci1 | 1:e392595b4b76 | 634 | |
uci1 | 12:d472f9811262 | 635 | #ifdef EVT_TIME_PROFILE |
uci1 | 12:d472f9811262 | 636 | Timer prof; |
uci1 | 12:d472f9811262 | 637 | prof.start(); |
uci1 | 12:d472f9811262 | 638 | int befReadWv=0, aftReadWv=0, befSaveEvt=0, aftSaveEvt=0, |
uci1 | 12:d472f9811262 | 639 | befChkPow=0, aftChkPow=0, befNewSeq=0, aftNewSeq=0, endOfLoop=0; |
uci1 | 12:d472f9811262 | 640 | #endif |
uci1 | 12:d472f9811262 | 641 | |
uci1 | 1:e392595b4b76 | 642 | if (gReadingOut) { |
uci1 | 12:d472f9811262 | 643 | |
uci1 | 12:d472f9811262 | 644 | const int32_t ttms = gTrgTimer.read_ms(); // time since last trigger |
uci1 | 12:d472f9811262 | 645 | gTrgTimer.reset(); gTrgTimer.start(); // restart trigger timer |
uci1 | 12:d472f9811262 | 646 | etms += ttms; |
uci1 | 8:95a325df1f6b | 647 | |
uci1 | 8:95a325df1f6b | 648 | Watchdog::kick(); // don't reset! |
uci1 | 15:f2569d8e4176 | 649 | |
uci1 | 1:e392595b4b76 | 650 | // |
uci1 | 1:e392595b4b76 | 651 | // got trigger. read registers to mbed and build the event |
uci1 | 1:e392595b4b76 | 652 | // |
uci1 | 1:e392595b4b76 | 653 | |
uci1 | 1:e392595b4b76 | 654 | led4=1; |
uci1 | 1:e392595b4b76 | 655 | |
uci1 | 22:f957c4f840ad | 656 | if ( gEvent.IsForcedTrg() || gFirstEvt || |
uci1 | 22:f957c4f840ad | 657 | (etms>gConf.GetEvtThrtlPeriodMs()) ) { |
uci1 | 22:f957c4f840ad | 658 | |
uci1 | 22:f957c4f840ad | 659 | // read data & calc CRC |
uci1 | 12:d472f9811262 | 660 | #ifdef EVT_TIME_PROFILE |
uci1 | 22:f957c4f840ad | 661 | prof.stop(); befReadWv=prof.read_us(); prof.start(); |
uci1 | 12:d472f9811262 | 662 | #endif |
uci1 | 12:d472f9811262 | 663 | |
uci1 | 22:f957c4f840ad | 664 | // get the data to the MBED |
uci1 | 22:f957c4f840ad | 665 | gEvent.ReadWaveforms(PIN_spi, PIN_selCardHiBit, PIN_selCardLoBit); |
uci1 | 15:f2569d8e4176 | 666 | |
uci1 | 12:d472f9811262 | 667 | #ifdef EVT_TIME_PROFILE |
uci1 | 22:f957c4f840ad | 668 | prof.stop(); aftReadWv=prof.read_us(); prof.start(); |
uci1 | 12:d472f9811262 | 669 | #endif |
uci1 | 12:d472f9811262 | 670 | |
uci1 | 22:f957c4f840ad | 671 | gEvent.SetCurMbedTime(); |
uci1 | 22:f957c4f840ad | 672 | // TODO: no way to check for external trigger? |
uci1 | 22:f957c4f840ad | 673 | if (gEvent.IsForcedTrg()==false) { |
uci1 | 22:f957c4f840ad | 674 | gEvent.SetTrgBit(kThmTrg); |
uci1 | 22:f957c4f840ad | 675 | gEvent.SetTrgNum(++(gTrgNum[kThmTrg])); |
uci1 | 22:f957c4f840ad | 676 | AddToRate(ttms, true); |
uci1 | 22:f957c4f840ad | 677 | } // else already set by procForceTrigger |
uci1 | 22:f957c4f840ad | 678 | // (no need to calc if we throw this event away) |
uci1 | 22:f957c4f840ad | 679 | |
uci1 | 22:f957c4f840ad | 680 | Watchdog::kick(); // don't reset! |
uci1 | 22:f957c4f840ad | 681 | |
uci1 | 12:d472f9811262 | 682 | #ifdef DEBUG |
uci1 | 22:f957c4f840ad | 683 | printf("gFirstEvt=%s\r\n",gFirstEvt?"true":"false"); |
uci1 | 12:d472f9811262 | 684 | #endif |
uci1 | 1:e392595b4b76 | 685 | |
uci1 | 1:e392595b4b76 | 686 | led2=1; |
uci1 | 22:f957c4f840ad | 687 | /* |
uci1 | 21:ce51bb0ba4a5 | 688 | gRecentCountTime = static_cast<uint32_t>(time(0)); |
uci1 | 21:ce51bb0ba4a5 | 689 | gRecentEvtNum = gEvtNum; |
uci1 | 21:ce51bb0ba4a5 | 690 | // do start time second so that if we get only one event, |
uci1 | 21:ce51bb0ba4a5 | 691 | // the delta(t) will be less than 0 and the rates not calculated |
uci1 | 21:ce51bb0ba4a5 | 692 | if (gDoResetLastCount) { |
uci1 | 21:ce51bb0ba4a5 | 693 | gLastCountReset = static_cast<uint32_t>(time(0)); // to calc rates |
uci1 | 21:ce51bb0ba4a5 | 694 | gLastEventReset = gEvtNum; |
uci1 | 21:ce51bb0ba4a5 | 695 | gDoResetLastCount = false; |
uci1 | 21:ce51bb0ba4a5 | 696 | } |
uci1 | 22:f957c4f840ad | 697 | */ |
uci1 | 21:ce51bb0ba4a5 | 698 | |
uci1 | 1:e392595b4b76 | 699 | PIN_lockRegisters = 0; // done reading, unlock so we can talk to SD card. |
uci1 | 1:e392595b4b76 | 700 | |
uci1 | 12:d472f9811262 | 701 | #ifdef EVT_TIME_PROFILE |
uci1 | 12:d472f9811262 | 702 | prof.stop(); befSaveEvt=prof.read_us(); prof.start(); |
uci1 | 12:d472f9811262 | 703 | #endif |
uci1 | 12:d472f9811262 | 704 | |
uci1 | 1:e392595b4b76 | 705 | SaveEvent(etms); |
uci1 | 22:f957c4f840ad | 706 | AddToRate(etms, false); |
uci1 | 12:d472f9811262 | 707 | etms=0; |
uci1 | 8:95a325df1f6b | 708 | |
uci1 | 12:d472f9811262 | 709 | #ifdef EVT_TIME_PROFILE |
uci1 | 12:d472f9811262 | 710 | prof.stop(); aftSaveEvt=prof.read_us(); prof.start(); |
uci1 | 12:d472f9811262 | 711 | #endif |
uci1 | 1:e392595b4b76 | 712 | } |
uci1 | 1:e392595b4b76 | 713 | } |
uci1 | 12:d472f9811262 | 714 | #ifdef DEBUG |
uci1 | 1:e392595b4b76 | 715 | printf("past reading out\r\n"); |
uci1 | 12:d472f9811262 | 716 | #endif |
uci1 | 1:e392595b4b76 | 717 | |
uci1 | 23:ccf39298f205 | 718 | if (gHrtbtFired) { |
uci1 | 23:ccf39298f205 | 719 | SaveHeartbeat(); |
uci1 | 23:ccf39298f205 | 720 | gHrtbtFired=false; |
uci1 | 23:ccf39298f205 | 721 | } |
uci1 | 23:ccf39298f205 | 722 | |
uci1 | 1:e392595b4b76 | 723 | led4=0; led2=0; |
uci1 | 12:d472f9811262 | 724 | |
uci1 | 12:d472f9811262 | 725 | #ifdef EVT_TIME_PROFILE |
uci1 | 12:d472f9811262 | 726 | prof.stop(); befChkPow=prof.read_us(); prof.start(); |
uci1 | 12:d472f9811262 | 727 | #endif |
uci1 | 8:95a325df1f6b | 728 | // check the power? |
uci1 | 8:95a325df1f6b | 729 | if (gCheckPower) { |
uci1 | 12:d472f9811262 | 730 | #ifdef DEBUG |
uci1 | 8:95a325df1f6b | 731 | printf("call check power\r\n"); |
uci1 | 12:d472f9811262 | 732 | #endif |
uci1 | 8:95a325df1f6b | 733 | CheckPower(false); |
uci1 | 8:95a325df1f6b | 734 | } |
uci1 | 12:d472f9811262 | 735 | #ifdef EVT_TIME_PROFILE |
uci1 | 12:d472f9811262 | 736 | prof.stop(); aftChkPow=prof.read_us(); prof.start(); |
uci1 | 12:d472f9811262 | 737 | #endif |
uci1 | 8:95a325df1f6b | 738 | |
uci1 | 21:ce51bb0ba4a5 | 739 | // open comm win? |
uci1 | 21:ce51bb0ba4a5 | 740 | if (gOpenCommWin) { |
uci1 | 21:ce51bb0ba4a5 | 741 | #ifdef DEBUG |
uci1 | 21:ce51bb0ba4a5 | 742 | printf("gOpenComWin=%s, opening\r\n",gOpenCommWin?"true":"false"); |
uci1 | 21:ce51bb0ba4a5 | 743 | #endif |
uci1 | 21:ce51bb0ba4a5 | 744 | OpenCommWin(); |
uci1 | 21:ce51bb0ba4a5 | 745 | gOpenCommWin=false; |
uci1 | 22:f957c4f840ad | 746 | gFirstEvt = true; |
uci1 | 22:f957c4f840ad | 747 | gTrgTimer.reset(); |
uci1 | 22:f957c4f840ad | 748 | etms=0; |
uci1 | 21:ce51bb0ba4a5 | 749 | } else { |
uci1 | 21:ce51bb0ba4a5 | 750 | #ifdef DEBUG |
uci1 | 27:efc4d654b139 | 751 | printf("gOpenCommWin=false, gCommWinChecks=%u, gNcommWinChecks=%u\r\n", |
uci1 | 27:efc4d654b139 | 752 | gCommWinChecks, gNcommWinChecks); |
uci1 | 21:ce51bb0ba4a5 | 753 | #endif |
uci1 | 21:ce51bb0ba4a5 | 754 | } |
uci1 | 21:ce51bb0ba4a5 | 755 | |
uci1 | 12:d472f9811262 | 756 | #ifdef EVT_TIME_PROFILE |
uci1 | 12:d472f9811262 | 757 | prof.stop(); befNewSeq=prof.read_us(); prof.start(); |
uci1 | 12:d472f9811262 | 758 | #endif |
uci1 | 8:95a325df1f6b | 759 | // make new seq? |
uci1 | 8:95a325df1f6b | 760 | if (IsSeqComplete()) { |
uci1 | 12:d472f9811262 | 761 | #ifdef DEBUG |
uci1 | 10:3c93db1cfb12 | 762 | printf("seq complete. sngseq=%d\r\n",gConf.IsSingleSeqRunMode()); |
uci1 | 12:d472f9811262 | 763 | #endif |
uci1 | 8:95a325df1f6b | 764 | MakeOutputFile(gConf.IsSingleSeqRunMode()); |
uci1 | 22:f957c4f840ad | 765 | gFirstEvt = true; |
uci1 | 22:f957c4f840ad | 766 | gTrgTimer.reset(); |
uci1 | 22:f957c4f840ad | 767 | etms=0; |
uci1 | 8:95a325df1f6b | 768 | } |
uci1 | 12:d472f9811262 | 769 | #ifdef EVT_TIME_PROFILE |
uci1 | 12:d472f9811262 | 770 | prof.stop(); aftNewSeq=prof.read_us(); prof.start(); |
uci1 | 12:d472f9811262 | 771 | #endif |
uci1 | 12:d472f9811262 | 772 | |
uci1 | 12:d472f9811262 | 773 | #ifdef EVT_TIME_PROFILE |
uci1 | 12:d472f9811262 | 774 | prof.stop(); endOfLoop=prof.read_us(); prof.start(); |
uci1 | 12:d472f9811262 | 775 | printf("befReadWv=%d, aftReadWv=%d, befSaveEvt=%d, aftSaveEvt=%d, " |
uci1 | 12:d472f9811262 | 776 | "befChkPow=%d, aftChkPow=%d, befNewSeq=%d, aftNewSeq=%d, endOfLoop=%d\r\n", |
uci1 | 12:d472f9811262 | 777 | befReadWv, aftReadWv, befSaveEvt, aftSaveEvt, |
uci1 | 12:d472f9811262 | 778 | befChkPow, aftChkPow, befNewSeq, aftNewSeq, endOfLoop); |
uci1 | 12:d472f9811262 | 779 | #endif |
uci1 | 15:f2569d8e4176 | 780 | |
uci1 | 15:f2569d8e4176 | 781 | // get ready to trigger |
uci1 | 15:f2569d8e4176 | 782 | PIN_spi.format( 16, 1 ); // change to data readout format |
uci1 | 15:f2569d8e4176 | 783 | PIN_spi.frequency( 10000000 ); // Max is 12.5 MHz |
uci1 | 22:f957c4f840ad | 784 | |
uci1 | 21:ce51bb0ba4a5 | 785 | // reset event |
uci1 | 22:f957c4f840ad | 786 | // clear after comm win, so full event can be sent with status |
uci1 | 22:f957c4f840ad | 787 | // but don't clear counters or trigger bits, as |
uci1 | 22:f957c4f840ad | 788 | gEvent.ClearEvent(true); |
uci1 | 21:ce51bb0ba4a5 | 789 | |
uci1 | 0:664899e0b988 | 790 | } |
uci1 | 0:664899e0b988 | 791 | |
uci1 | 0:664899e0b988 | 792 | } |
uci1 | 0:664899e0b988 | 793 | |
uci1 | 0:664899e0b988 | 794 | // |
uci1 | 22:f957c4f840ad | 795 | // save a heartbeat tag |
uci1 | 22:f957c4f840ad | 796 | // |
uci1 | 22:f957c4f840ad | 797 | void SaveHeartbeat() { |
uci1 | 22:f957c4f840ad | 798 | if (gHrtbtNum>0) { |
uci1 | 22:f957c4f840ad | 799 | #ifdef DEBUG |
uci1 | 22:f957c4f840ad | 800 | printf("save heartbeat #%u, time %u\r\n", |
uci1 | 22:f957c4f840ad | 801 | gHrtbtNum-1, gLastHrtbt); |
uci1 | 22:f957c4f840ad | 802 | #endif |
uci1 | 22:f957c4f840ad | 803 | // save to SD |
uci1 | 22:f957c4f840ad | 804 | PIN_lockRegisters = 0; // unlock so we can talk to SD card. |
uci1 | 22:f957c4f840ad | 805 | SnSDUtils::WriteHeartbeatTo(SnSDUtils::GetCurFile(), |
uci1 | 22:f957c4f840ad | 806 | gLastHrtbt, gHrtbtNum-1); // -1 so it counts from 0 |
uci1 | 22:f957c4f840ad | 807 | } |
uci1 | 22:f957c4f840ad | 808 | } |
uci1 | 22:f957c4f840ad | 809 | |
uci1 | 22:f957c4f840ad | 810 | // |
uci1 | 0:664899e0b988 | 811 | // save the event |
uci1 | 0:664899e0b988 | 812 | // |
uci1 | 0:664899e0b988 | 813 | void SaveEvent(const int32_t etms) { |
uci1 | 0:664899e0b988 | 814 | // write the event |
uci1 | 12:d472f9811262 | 815 | |
uci1 | 12:d472f9811262 | 816 | #ifdef DEBUG |
uci1 | 3:24c5f0f50bf1 | 817 | printf("save event\r\n"); |
uci1 | 12:d472f9811262 | 818 | #endif |
uci1 | 3:24c5f0f50bf1 | 819 | |
uci1 | 0:664899e0b988 | 820 | // set the event number & dt |
uci1 | 3:24c5f0f50bf1 | 821 | gEvent.SetEvtNum(gEvtNum); |
uci1 | 0:664899e0b988 | 822 | gEvent.SetDTms(etms); |
uci1 | 0:664899e0b988 | 823 | |
uci1 | 0:664899e0b988 | 824 | // save to SD |
uci1 | 11:de443350ec4a | 825 | PIN_lockRegisters = 0; // unlock so we can talk to SD card. |
uci1 | 1:e392595b4b76 | 826 | SnSDUtils::WriteEventTo(SnSDUtils::GetCurFile(), gGenBuf, gEvent, gConf); |
uci1 | 0:664899e0b988 | 827 | |
uci1 | 3:24c5f0f50bf1 | 828 | // increment event number |
uci1 | 3:24c5f0f50bf1 | 829 | ++gEvtNum; |
uci1 | 3:24c5f0f50bf1 | 830 | |
uci1 | 12:d472f9811262 | 831 | #ifdef DEBUG |
uci1 | 8:95a325df1f6b | 832 | printf("gEvtNum=%u\r\n",gEvtNum); |
uci1 | 12:d472f9811262 | 833 | #endif |
uci1 | 3:24c5f0f50bf1 | 834 | } |
uci1 | 3:24c5f0f50bf1 | 835 | |
uci1 | 3:24c5f0f50bf1 | 836 | void MakeOutputFile(const bool stopRunning) { |
uci1 | 10:3c93db1cfb12 | 837 | PIN_lockRegisters = 0; // unlock so we can talk to SD card. |
uci1 | 12:d472f9811262 | 838 | #ifdef DEBUG |
uci1 | 10:3c93db1cfb12 | 839 | printf("closing output file. gEvtNum=%u, gPowNum=%u, stop=%d\r\n", |
uci1 | 10:3c93db1cfb12 | 840 | gEvtNum,gPowNum,(int)stopRunning); |
uci1 | 12:d472f9811262 | 841 | #endif |
uci1 | 13:7a1fb885a8e4 | 842 | |
uci1 | 3:24c5f0f50bf1 | 843 | SnSDUtils::CloseOutputFile(SnSDUtils::GetCurFile()); |
uci1 | 13:7a1fb885a8e4 | 844 | |
uci1 | 12:d472f9811262 | 845 | #ifdef DEBUG |
uci1 | 10:3c93db1cfb12 | 846 | printf("file closed\r\n"); |
uci1 | 12:d472f9811262 | 847 | #endif |
uci1 | 3:24c5f0f50bf1 | 848 | if (stopRunning) { |
uci1 | 8:95a325df1f6b | 849 | StopRunning(); |
uci1 | 0:664899e0b988 | 850 | } |
uci1 | 8:95a325df1f6b | 851 | FILE* cf = SnSDUtils::OpenNewOutputFile(gConf.GetMacAddress(), |
uci1 | 8:95a325df1f6b | 852 | gConf.GetRun()); |
uci1 | 13:7a1fb885a8e4 | 853 | // reset event, timers, trigger counters |
uci1 | 13:7a1fb885a8e4 | 854 | ResetCountersClearEvt(); |
uci1 | 8:95a325df1f6b | 855 | if (cf!=0) { |
uci1 | 8:95a325df1f6b | 856 | wait_ms(200); |
uci1 | 8:95a325df1f6b | 857 | GetAvePowerReading(); |
uci1 | 12:d472f9811262 | 858 | #ifdef DEBUG |
uci1 | 8:95a325df1f6b | 859 | printf("writing power. v1=%g, v2=%g, r1=%g, r2=%g, t=%u, pownum=%u\r\n", |
uci1 | 8:95a325df1f6b | 860 | gPower.GetAveV1(), gPower.GetAveV2(), |
uci1 | 8:95a325df1f6b | 861 | gPower.GetRmsV1(), gPower.GetRmsV2(), gPower.GetTime(), |
uci1 | 8:95a325df1f6b | 862 | gPowNum); |
uci1 | 12:d472f9811262 | 863 | #endif |
uci1 | 8:95a325df1f6b | 864 | SnSDUtils::WritePowerTo(cf, gPower, gPowNum); |
uci1 | 8:95a325df1f6b | 865 | } |
uci1 | 12:d472f9811262 | 866 | #ifdef DEBUG |
uci1 | 3:24c5f0f50bf1 | 867 | printf("made output file with run %u\r\n",gConf.GetRun()); |
uci1 | 3:24c5f0f50bf1 | 868 | printf("filename=%s\r\n",SnSDUtils::GetCurFileName()); |
uci1 | 12:d472f9811262 | 869 | #endif |
uci1 | 3:24c5f0f50bf1 | 870 | SnSDUtils::WriteConfig(SnSDUtils::GetCurFile(), gConf); |
uci1 | 19:74155d652c37 | 871 | #ifdef DEBUG |
uci1 | 19:74155d652c37 | 872 | printf("write config to file\r\n"); |
uci1 | 19:74155d652c37 | 873 | #endif |
uci1 | 0:664899e0b988 | 874 | } |
uci1 | 0:664899e0b988 | 875 | |
uci1 | 0:664899e0b988 | 876 | // |
uci1 | 4:a91682e19d6b | 877 | // power stuff |
uci1 | 4:a91682e19d6b | 878 | // |
uci1 | 4:a91682e19d6b | 879 | void SetPower(const bool isCommWin) { |
uci1 | 21:ce51bb0ba4a5 | 880 | #ifdef DEBUG |
uci1 | 30:f869ed4bcc08 | 881 | printf("set power. isCommWin=%s\r\n",(isCommWin)?"true":"false"); |
uci1 | 21:ce51bb0ba4a5 | 882 | printf("bef: pconp=%u (%08x), pcenet=%u (%08x)\r\n", |
uci1 | 21:ce51bb0ba4a5 | 883 | LPC_SC->PCONP, LPC_SC->PCONP, LPC1768_PCONP_PCENET, LPC1768_PCONP_PCENET); |
uci1 | 21:ce51bb0ba4a5 | 884 | printf("pcenet bef power: status=%d\r\n",Peripheral_GetStatus(LPC1768_PCONP_PCENET)); |
uci1 | 21:ce51bb0ba4a5 | 885 | #endif |
uci1 | 30:f869ed4bcc08 | 886 | |
uci1 | 30:f869ed4bcc08 | 887 | SnConfigFrame::EPowerModeBit cardpb(SnConfigFrame::kCardDatTak), |
uci1 | 30:f869ed4bcc08 | 888 | ampspb(SnConfigFrame::kAmpsDatTak), |
uci1 | 30:f869ed4bcc08 | 889 | iridpb(SnConfigFrame::kIridDatTak), |
uci1 | 30:f869ed4bcc08 | 890 | afarpb(SnConfigFrame::kAfarDatTak); |
uci1 | 4:a91682e19d6b | 891 | if (isCommWin) { |
uci1 | 30:f869ed4bcc08 | 892 | cardpb = SnConfigFrame::kCardComWin; |
uci1 | 30:f869ed4bcc08 | 893 | ampspb = SnConfigFrame::kAmpsComWin; |
uci1 | 30:f869ed4bcc08 | 894 | iridpb = SnConfigFrame::kIridComWin; |
uci1 | 30:f869ed4bcc08 | 895 | afarpb = SnConfigFrame::kAfarComWin; |
uci1 | 30:f869ed4bcc08 | 896 | } |
uci1 | 30:f869ed4bcc08 | 897 | // TODO: turn on amps individually, when that's possible |
uci1 | 30:f869ed4bcc08 | 898 | PIN_turn_on_system = gConf.GetPowPinSetting(cardpb); |
uci1 | 30:f869ed4bcc08 | 899 | wait_ms(10); |
uci1 | 30:f869ed4bcc08 | 900 | PIN_turn_on_amps = gConf.GetPowPinSetting(ampspb); |
uci1 | 30:f869ed4bcc08 | 901 | wait_ms(10); |
uci1 | 30:f869ed4bcc08 | 902 | PIN_iridSbd_power = (kIridAfarPwrSame) |
uci1 | 30:f869ed4bcc08 | 903 | ? gConf.GetPowPinSetting(iridpb, false) // leave the iridium relay off. use afar relay. |
uci1 | 30:f869ed4bcc08 | 904 | : gConf.GetPowPinSetting(iridpb); |
uci1 | 30:f869ed4bcc08 | 905 | wait_ms(10); |
uci1 | 21:ce51bb0ba4a5 | 906 | #ifdef DEBUG |
uci1 | 30:f869ed4bcc08 | 907 | printf("afar pin=%d, com powsetting=%d\r\n",PIN_afar_power.read(), |
uci1 | 30:f869ed4bcc08 | 908 | gConf.GetPowPinSetting(afarpb)); |
uci1 | 21:ce51bb0ba4a5 | 909 | #endif |
uci1 | 30:f869ed4bcc08 | 910 | if (gConf.IsPoweredFor(afarpb)) { |
uci1 | 21:ce51bb0ba4a5 | 911 | #ifdef DEBUG |
uci1 | 30:f869ed4bcc08 | 912 | printf("PHY cowin powering up\r\n"); |
uci1 | 21:ce51bb0ba4a5 | 913 | #endif |
uci1 | 30:f869ed4bcc08 | 914 | PHY_PowerUp(); wait(1); |
uci1 | 21:ce51bb0ba4a5 | 915 | #ifdef DEBUG |
uci1 | 30:f869ed4bcc08 | 916 | printf("PHY cowin powered up\r\n"); |
uci1 | 21:ce51bb0ba4a5 | 917 | #endif |
uci1 | 4:a91682e19d6b | 918 | } else { |
uci1 | 21:ce51bb0ba4a5 | 919 | #ifdef DEBUG |
uci1 | 30:f869ed4bcc08 | 920 | printf("PHY cowin powering down\r\n"); |
uci1 | 21:ce51bb0ba4a5 | 921 | #endif |
uci1 | 30:f869ed4bcc08 | 922 | PHY_PowerDown(); wait(1); |
uci1 | 21:ce51bb0ba4a5 | 923 | #ifdef DEBUG |
uci1 | 30:f869ed4bcc08 | 924 | printf("PHY cowin powered down\r\n"); |
uci1 | 21:ce51bb0ba4a5 | 925 | #endif |
uci1 | 30:f869ed4bcc08 | 926 | } |
uci1 | 21:ce51bb0ba4a5 | 927 | #ifdef DEBUG |
uci1 | 30:f869ed4bcc08 | 928 | printf("PHY done\r\n"); |
uci1 | 21:ce51bb0ba4a5 | 929 | #endif |
uci1 | 30:f869ed4bcc08 | 930 | wait_ms(100); |
uci1 | 30:f869ed4bcc08 | 931 | int afpp = gConf.GetPowPinSetting(afarpb); |
uci1 | 30:f869ed4bcc08 | 932 | if (kIridAfarPwrSame) { |
uci1 | 30:f869ed4bcc08 | 933 | afpp |= gConf.GetPowPinSetting(iridpb); |
uci1 | 4:a91682e19d6b | 934 | } |
uci1 | 30:f869ed4bcc08 | 935 | PIN_afar_power = afpp; |
uci1 | 16:744ce85aede2 | 936 | wait(1.5); // let things power up |
uci1 | 12:d472f9811262 | 937 | #ifdef DEBUG |
uci1 | 21:ce51bb0ba4a5 | 938 | printf("aft: pconp=%u (%08x), pcenet=%u (%08x)\r\n", |
uci1 | 21:ce51bb0ba4a5 | 939 | LPC_SC->PCONP, LPC_SC->PCONP, LPC1768_PCONP_PCENET, LPC1768_PCONP_PCENET); |
uci1 | 21:ce51bb0ba4a5 | 940 | #endif |
uci1 | 21:ce51bb0ba4a5 | 941 | #ifdef DEBUG |
uci1 | 16:744ce85aede2 | 942 | printf("power word (%hhu): ",gConf.GetPowerMode()); SnBitUtils::printBits(gConf.GetPowerMode(),true); |
uci1 | 6:6f002d202f59 | 943 | printf("set power (iscom %d, pw %hhu): cards %d, amps %d, irid %d, afar %d\r\n", |
uci1 | 6:6f002d202f59 | 944 | isCommWin, gConf.GetPowerMode(), PIN_turn_on_system.read(), PIN_turn_on_amps.read(), |
uci1 | 6:6f002d202f59 | 945 | PIN_iridSbd_power.read(), PIN_afar_power.read()); |
uci1 | 21:ce51bb0ba4a5 | 946 | printf("pcenet aft power: status=%d\r\n",Peripheral_GetStatus(LPC1768_PCONP_PCENET)); |
uci1 | 12:d472f9811262 | 947 | #endif |
uci1 | 4:a91682e19d6b | 948 | } |
uci1 | 4:a91682e19d6b | 949 | |
uci1 | 4:a91682e19d6b | 950 | // |
uci1 | 0:664899e0b988 | 951 | // set configuration |
uci1 | 0:664899e0b988 | 952 | // |
uci1 | 1:e392595b4b76 | 953 | void SetConfigAndMakeOutputFile() { |
uci1 | 12:d472f9811262 | 954 | #ifdef DEBUG |
uci1 | 1:e392595b4b76 | 955 | printf("SetConfigAndMakeOutputFile\r\n"); |
uci1 | 12:d472f9811262 | 956 | #endif |
uci1 | 1:e392595b4b76 | 957 | |
uci1 | 0:664899e0b988 | 958 | // restart watchdog |
uci1 | 0:664899e0b988 | 959 | Watchdog::kick(gConf.GetWatchdogPeriod()); |
uci1 | 0:664899e0b988 | 960 | |
uci1 | 1:e392595b4b76 | 961 | // block (thermal) triggers during configuration |
uci1 | 1:e392595b4b76 | 962 | PIN_enableThermTrig = 0; |
uci1 | 1:e392595b4b76 | 963 | PIN_ADC_CS = 1; |
uci1 | 1:e392595b4b76 | 964 | PIN_DoNotRestartAllClocks = 1; |
uci1 | 1:e392595b4b76 | 965 | PIN_forceTrigger = 0; |
uci1 | 3:24c5f0f50bf1 | 966 | PIN_heartbeat = 0; |
uci1 | 1:e392595b4b76 | 967 | wait_ms(20); |
uci1 | 1:e392595b4b76 | 968 | |
uci1 | 22:f957c4f840ad | 969 | gCommWinChecks = 0; |
uci1 | 22:f957c4f840ad | 970 | gNcommWinChecks = gConf.GetCommWinPeriod() / kCommWinLongPrdTk; |
uci1 | 22:f957c4f840ad | 971 | |
uci1 | 21:ce51bb0ba4a5 | 972 | if (AreCardsPowered(true)) { |
uci1 | 8:95a325df1f6b | 973 | // Set PLA value(s) |
uci1 | 8:95a325df1f6b | 974 | PIN_spi.format( 16, 0 ); // change mode for DAC & PLA value setting |
uci1 | 8:95a325df1f6b | 975 | PIN_spi.frequency(1000000); |
uci1 | 8:95a325df1f6b | 976 | PIN_MajLogHiBit=1; |
uci1 | 8:95a325df1f6b | 977 | PIN_MajLogLoBit=1; |
uci1 | 8:95a325df1f6b | 978 | PIN_enableThermTrig=0; |
uci1 | 0:664899e0b988 | 979 | |
uci1 | 8:95a325df1f6b | 980 | uint16_t hi, lo; |
uci1 | 8:95a325df1f6b | 981 | PIN_PLA_cs=1; |
uci1 | 8:95a325df1f6b | 982 | wait(4); |
uci1 | 8:95a325df1f6b | 983 | for (uint8_t pi=0; pi<kNplas; pi++) { |
uci1 | 8:95a325df1f6b | 984 | if (pi < gConf.GetNumPlas()) { |
uci1 | 8:95a325df1f6b | 985 | SnConfigFrame::GetHiLoPlas(gConf.GetPla(pi), hi, lo); |
uci1 | 8:95a325df1f6b | 986 | PIN_spi.write(hi); |
uci1 | 8:95a325df1f6b | 987 | PIN_spi.write(lo); |
uci1 | 12:d472f9811262 | 988 | #ifdef DEBUG |
uci1 | 8:95a325df1f6b | 989 | printf("pla hi %hu, lo %hu\r\n",hi,lo); |
uci1 | 12:d472f9811262 | 990 | #endif |
uci1 | 8:95a325df1f6b | 991 | } else { |
uci1 | 8:95a325df1f6b | 992 | PIN_spi.write(kNoTrigPla); // hi |
uci1 | 8:95a325df1f6b | 993 | PIN_spi.write(kNoTrigPla); // lo |
uci1 | 12:d472f9811262 | 994 | #ifdef DEBUG |
uci1 | 8:95a325df1f6b | 995 | printf("pla hi %hu, lo %hu\r\n",kNoTrigPla,kNoTrigPla); |
uci1 | 12:d472f9811262 | 996 | #endif |
uci1 | 8:95a325df1f6b | 997 | } |
uci1 | 8:95a325df1f6b | 998 | Watchdog::kick(); |
uci1 | 0:664899e0b988 | 999 | } |
uci1 | 8:95a325df1f6b | 1000 | wait(3); |
uci1 | 8:95a325df1f6b | 1001 | PIN_PLA_cs=0; |
uci1 | 8:95a325df1f6b | 1002 | wait(3); |
uci1 | 0:664899e0b988 | 1003 | |
uci1 | 8:95a325df1f6b | 1004 | // DAC values |
uci1 | 8:95a325df1f6b | 1005 | // |
uci1 | 8:95a325df1f6b | 1006 | // first 12 bits = DAC value |
uci1 | 8:95a325df1f6b | 1007 | // next 2 bits = DAC ID |
uci1 | 8:95a325df1f6b | 1008 | // last 2 bits = dFPGA ID |
uci1 | 8:95a325df1f6b | 1009 | // |
uci1 | 8:95a325df1f6b | 1010 | // But FPGA uses "gray encoding" which means only 1 bit |
uci1 | 8:95a325df1f6b | 1011 | // can change at a time (of the last 4 bits). So even tho |
uci1 | 8:95a325df1f6b | 1012 | // the card/dac# is encoded, the order is also important |
uci1 | 8:95a325df1f6b | 1013 | // 0000 (dac0,card0), 0001 (dac0,card1), 0011 (dac0,card3), 0010 (dac0,card2), |
uci1 | 8:95a325df1f6b | 1014 | // 0110 (dac1,card2), 0111 (dac1,card3), 0101 (dac1,card1), etc. |
uci1 | 12:d472f9811262 | 1015 | #ifdef DEBUG |
uci1 | 8:95a325df1f6b | 1016 | printf("setting dacs\r\n"); |
uci1 | 12:d472f9811262 | 1017 | #endif |
uci1 | 8:95a325df1f6b | 1018 | uint16_t dv=0; |
uci1 | 8:95a325df1f6b | 1019 | for (uint8_t i=0, gri=0; i<kTotDacs; i++) { |
uci1 | 8:95a325df1f6b | 1020 | // get the gray-codes for this iteration |
uci1 | 8:95a325df1f6b | 1021 | gri = SnBitUtils::binToGray(i); |
uci1 | 8:95a325df1f6b | 1022 | |
uci1 | 8:95a325df1f6b | 1023 | // build bit word |
uci1 | 8:95a325df1f6b | 1024 | dv = static_cast<int>(gConf.GetDac(gri & 0x0003u, gri >> 2u)); |
uci1 | 8:95a325df1f6b | 1025 | dv <<= 4u; |
uci1 | 8:95a325df1f6b | 1026 | dv |= gri; |
uci1 | 8:95a325df1f6b | 1027 | |
uci1 | 12:d472f9811262 | 1028 | #ifdef DEBUG |
uci1 | 8:95a325df1f6b | 1029 | printf("dac %04x\r\n",dv); |
uci1 | 12:d472f9811262 | 1030 | #endif |
uci1 | 8:95a325df1f6b | 1031 | |
uci1 | 8:95a325df1f6b | 1032 | // send to FPGA |
uci1 | 8:95a325df1f6b | 1033 | PIN_start_fpga=1; |
uci1 | 8:95a325df1f6b | 1034 | PIN_spi.write(dv); |
uci1 | 8:95a325df1f6b | 1035 | PIN_start_fpga=0; |
uci1 | 8:95a325df1f6b | 1036 | |
uci1 | 8:95a325df1f6b | 1037 | Watchdog::kick(); |
uci1 | 8:95a325df1f6b | 1038 | |
uci1 | 8:95a325df1f6b | 1039 | } |
uci1 | 12:d472f9811262 | 1040 | #ifdef DEBUG |
uci1 | 8:95a325df1f6b | 1041 | printf("dacs set\r\n"); |
uci1 | 12:d472f9811262 | 1042 | #endif |
uci1 | 8:95a325df1f6b | 1043 | wait_ms(20); |
uci1 | 8:95a325df1f6b | 1044 | } else { |
uci1 | 12:d472f9811262 | 1045 | #ifdef DEBUG |
uci1 | 8:95a325df1f6b | 1046 | printf("cards off. skipping PLA and DAC setting\r\n"); |
uci1 | 12:d472f9811262 | 1047 | #endif |
uci1 | 0:664899e0b988 | 1048 | } |
uci1 | 0:664899e0b988 | 1049 | |
uci1 | 0:664899e0b988 | 1050 | // Majority Logic Trigger selection (# of cards) |
uci1 | 0:664899e0b988 | 1051 | SnBitUtils::SetChanNumBits(gConf.GetNumCardsMajLog() - 1u, |
uci1 | 0:664899e0b988 | 1052 | PIN_MajLogHiBit, PIN_MajLogLoBit); |
uci1 | 0:664899e0b988 | 1053 | |
uci1 | 0:664899e0b988 | 1054 | // Enable thermal trigger? |
uci1 | 0:664899e0b988 | 1055 | PIN_enableThermTrig = gConf.IsThermTrigEnabled(); |
uci1 | 0:664899e0b988 | 1056 | |
uci1 | 0:664899e0b988 | 1057 | PIN_spi.format( 16, 1 ); // back to trigger mode |
uci1 | 1:e392595b4b76 | 1058 | PIN_spi.frequency( 10000000 ); // Max is 12.5 MHz |
uci1 | 1:e392595b4b76 | 1059 | |
uci1 | 8:95a325df1f6b | 1060 | // make new output file |
uci1 | 8:95a325df1f6b | 1061 | // put after PLA/DAC, in case they affect the power readings |
uci1 | 8:95a325df1f6b | 1062 | wait_ms(200); |
uci1 | 8:95a325df1f6b | 1063 | MakeOutputFile(); |
uci1 | 8:95a325df1f6b | 1064 | |
uci1 | 21:ce51bb0ba4a5 | 1065 | // reset tickers |
uci1 | 21:ce51bb0ba4a5 | 1066 | ResetAllTickers(); |
uci1 | 0:664899e0b988 | 1067 | |
uci1 | 0:664899e0b988 | 1068 | Watchdog::kick(); // don't reset! |
uci1 | 8:95a325df1f6b | 1069 | |
uci1 | 12:d472f9811262 | 1070 | #ifdef DEBUG |
uci1 | 8:95a325df1f6b | 1071 | printf("set config done\r\n"); |
uci1 | 12:d472f9811262 | 1072 | #endif |
uci1 | 0:664899e0b988 | 1073 | } |
uci1 | 0:664899e0b988 | 1074 | |
uci1 | 0:664899e0b988 | 1075 | // |
uci1 | 0:664899e0b988 | 1076 | // readout functions |
uci1 | 0:664899e0b988 | 1077 | // |
uci1 | 0:664899e0b988 | 1078 | void WaitTrigAndSendClock() { |
uci1 | 1:e392595b4b76 | 1079 | |
uci1 | 12:d472f9811262 | 1080 | #ifdef DEBUG |
uci1 | 1:e392595b4b76 | 1081 | printf("WaitTrigAndSendClock\r\n"); |
uci1 | 6:6f002d202f59 | 1082 | printf("wait trig: (pw %hhu): cards %d, amps %d, irid %d, afar %d\r\n", |
uci1 | 6:6f002d202f59 | 1083 | gConf.GetPowerMode(), PIN_turn_on_system.read(), PIN_turn_on_amps.read(), |
uci1 | 6:6f002d202f59 | 1084 | PIN_iridSbd_power.read(), PIN_afar_power.read()); |
uci1 | 21:ce51bb0ba4a5 | 1085 | printf("cards powered=%d\r\n",(int)AreCardsPowered(true)); |
uci1 | 12:d472f9811262 | 1086 | #endif |
uci1 | 0:664899e0b988 | 1087 | |
uci1 | 15:f2569d8e4176 | 1088 | PIN_spi.format( 16, 1 ); // back to trigger mode |
uci1 | 15:f2569d8e4176 | 1089 | PIN_spi.frequency( 10000000 ); // Max is 12.5 MHz |
uci1 | 15:f2569d8e4176 | 1090 | |
uci1 | 21:ce51bb0ba4a5 | 1091 | if (AreCardsPowered(false)) { |
uci1 | 8:95a325df1f6b | 1092 | |
uci1 | 21:ce51bb0ba4a5 | 1093 | #ifdef DEBUG |
uci1 | 21:ce51bb0ba4a5 | 1094 | printf("gFirstEvt=%s\r\n",gFirstEvt?"true":"false"); |
uci1 | 21:ce51bb0ba4a5 | 1095 | #endif |
uci1 | 8:95a325df1f6b | 1096 | if (gFirstEvt==false) { |
uci1 | 8:95a325df1f6b | 1097 | PIN_DoNotRestartAllClocks = 0; |
uci1 | 8:95a325df1f6b | 1098 | wait_us(1); |
uci1 | 8:95a325df1f6b | 1099 | PIN_DoNotRestartAllClocks = 1; |
uci1 | 8:95a325df1f6b | 1100 | //led3 = !led3; // toggle send clock led |
uci1 | 8:95a325df1f6b | 1101 | } else { |
uci1 | 8:95a325df1f6b | 1102 | gFirstEvt = false; |
uci1 | 8:95a325df1f6b | 1103 | } |
uci1 | 8:95a325df1f6b | 1104 | |
uci1 | 8:95a325df1f6b | 1105 | // |
uci1 | 8:95a325df1f6b | 1106 | // wait for a trigger here. |
uci1 | 8:95a325df1f6b | 1107 | // |
uci1 | 12:d472f9811262 | 1108 | #ifdef DEBUG |
uci1 | 8:95a325df1f6b | 1109 | printf("starting wait for trig\r\n"); |
uci1 | 12:d472f9811262 | 1110 | #endif |
uci1 | 16:744ce85aede2 | 1111 | |
uci1 | 8:95a325df1f6b | 1112 | gReadingOut = false; // this will allow forced triggers (see procForceTrigger()) |
uci1 | 8:95a325df1f6b | 1113 | while ( PIN_a_sf_clk == 1 ) { |
uci1 | 8:95a325df1f6b | 1114 | if (gOpenCommWin || gCheckPower) { |
uci1 | 12:d472f9811262 | 1115 | #ifdef DEBUG |
uci1 | 8:95a325df1f6b | 1116 | printf("break com=%d, pow=%d\r\n",gOpenCommWin,gCheckPower); |
uci1 | 12:d472f9811262 | 1117 | #endif |
uci1 | 8:95a325df1f6b | 1118 | return; // break out to open comms or check power |
uci1 | 8:95a325df1f6b | 1119 | } |
uci1 | 0:664899e0b988 | 1120 | } |
uci1 | 21:ce51bb0ba4a5 | 1121 | //PIN_forceTrigger=0; // necessary for forced triggers, harmless for other triggers |
uci1 | 8:95a325df1f6b | 1122 | gReadingOut = true; // disallow new forced triggers |
uci1 | 28:484943132bb0 | 1123 | /* |
uci1 | 21:ce51bb0ba4a5 | 1124 | #ifdef DEBUG |
uci1 | 21:ce51bb0ba4a5 | 1125 | printf("after wait for trig. PIN_a_sf_clk=%d\r\n", |
uci1 | 21:ce51bb0ba4a5 | 1126 | PIN_a_sf_clk.read()); |
uci1 | 21:ce51bb0ba4a5 | 1127 | #endif |
uci1 | 28:484943132bb0 | 1128 | */ |
uci1 | 15:f2569d8e4176 | 1129 | // we can't be interrupted before data arrives at the MB FPGA |
uci1 | 15:f2569d8e4176 | 1130 | //StopAllTickers(); |
uci1 | 15:f2569d8e4176 | 1131 | /* |
uci1 | 15:f2569d8e4176 | 1132 | procForceTrigger(); |
uci1 | 15:f2569d8e4176 | 1133 | procHeartbeat(); |
uci1 | 15:f2569d8e4176 | 1134 | procPowerCheck(); |
uci1 | 15:f2569d8e4176 | 1135 | procCommWin(); |
uci1 | 15:f2569d8e4176 | 1136 | */ |
uci1 | 16:744ce85aede2 | 1137 | |
uci1 | 23:ccf39298f205 | 1138 | //wait_us(5); |
uci1 | 16:744ce85aede2 | 1139 | |
uci1 | 8:95a325df1f6b | 1140 | // |
uci1 | 8:95a325df1f6b | 1141 | // collect data from daughter cards |
uci1 | 8:95a325df1f6b | 1142 | // |
uci1 | 8:95a325df1f6b | 1143 | // TODO: what if some card (set of channels) doesn't respond? |
uci1 | 8:95a325df1f6b | 1144 | // currently, will wait forever? |
uci1 | 8:95a325df1f6b | 1145 | // also, if ch1 is dead, will wait forever (due to FPGA code) |
uci1 | 16:744ce85aede2 | 1146 | gAdcToMBtimer.start(); |
uci1 | 16:744ce85aede2 | 1147 | for( uint8_t i = 0; i < 128; ++i ) { |
uci1 | 16:744ce85aede2 | 1148 | while (PIN_a_sf_clk==1) {} |
uci1 | 16:744ce85aede2 | 1149 | while (PIN_a_sf_clk==0) {} |
uci1 | 16:744ce85aede2 | 1150 | /* |
uci1 | 16:744ce85aede2 | 1151 | if ((i == 10)&&(gEvtNum % 20)) { |
uci1 | 16:744ce85aede2 | 1152 | wait_us(8); |
uci1 | 16:744ce85aede2 | 1153 | } |
uci1 | 16:744ce85aede2 | 1154 | */ |
uci1 | 16:744ce85aede2 | 1155 | PIN_ADC_CS = 0; |
uci1 | 16:744ce85aede2 | 1156 | PIN_spi.write( 0x00 ); |
uci1 | 16:744ce85aede2 | 1157 | PIN_ADC_CS = 1; |
uci1 | 16:744ce85aede2 | 1158 | /* |
uci1 | 8:95a325df1f6b | 1159 | if( PIN_a_sf_clk == 1 ) { |
uci1 | 8:95a325df1f6b | 1160 | if( i == 0 ) |
uci1 | 8:95a325df1f6b | 1161 | wait_us( 1 ); |
uci1 | 8:95a325df1f6b | 1162 | |
uci1 | 8:95a325df1f6b | 1163 | PIN_ADC_CS = 0; |
uci1 | 8:95a325df1f6b | 1164 | PIN_spi.write( 0x00 ); |
uci1 | 8:95a325df1f6b | 1165 | PIN_ADC_CS = 1; |
uci1 | 8:95a325df1f6b | 1166 | } else { |
uci1 | 8:95a325df1f6b | 1167 | i--; |
uci1 | 8:95a325df1f6b | 1168 | } |
uci1 | 16:744ce85aede2 | 1169 | */ |
uci1 | 0:664899e0b988 | 1170 | } |
uci1 | 16:744ce85aede2 | 1171 | gAdcToMBtimer.stop(); |
uci1 | 16:744ce85aede2 | 1172 | #ifdef DEBUG |
uci1 | 16:744ce85aede2 | 1173 | printf("total time = %d us\r\n", gAdcToMBtimer.read_us()); |
uci1 | 16:744ce85aede2 | 1174 | #endif |
uci1 | 16:744ce85aede2 | 1175 | if ( kAdcToMBtimeCut < gAdcToMBtimer.read_us() ) { |
uci1 | 16:744ce85aede2 | 1176 | gEvent.SetTrgBit(kAdcToMBflag); |
uci1 | 16:744ce85aede2 | 1177 | } |
uci1 | 16:744ce85aede2 | 1178 | gAdcToMBtimer.reset(); |
uci1 | 15:f2569d8e4176 | 1179 | |
uci1 | 15:f2569d8e4176 | 1180 | // restart the timers |
uci1 | 15:f2569d8e4176 | 1181 | //ResetAllTickers(); |
uci1 | 8:95a325df1f6b | 1182 | } else { |
uci1 | 8:95a325df1f6b | 1183 | // cards have no power. don't try reading out |
uci1 | 8:95a325df1f6b | 1184 | gReadingOut=false; |
uci1 | 0:664899e0b988 | 1185 | } |
uci1 | 0:664899e0b988 | 1186 | } |
uci1 | 0:664899e0b988 | 1187 | |
uci1 | 13:7a1fb885a8e4 | 1188 | SnCommWin::ECommWinResult OpenCommWin(const bool forceReconfig) { |
uci1 | 0:664899e0b988 | 1189 | // loop through each comm mode: |
uci1 | 0:664899e0b988 | 1190 | // a) try to connect |
uci1 | 0:664899e0b988 | 1191 | // b) if connected, listen for config |
uci1 | 0:664899e0b988 | 1192 | // c) if config requests data, send it |
uci1 | 16:744ce85aede2 | 1193 | /* |
uci1 | 16:744ce85aede2 | 1194 | for (int i=0; i<5; i++) { |
uci1 | 16:744ce85aede2 | 1195 | led4=1; |
uci1 | 16:744ce85aede2 | 1196 | led3=1; |
uci1 | 16:744ce85aede2 | 1197 | wait(0.5); |
uci1 | 16:744ce85aede2 | 1198 | led4=0; |
uci1 | 16:744ce85aede2 | 1199 | led3=0; |
uci1 | 16:744ce85aede2 | 1200 | wait(0.5); |
uci1 | 16:744ce85aede2 | 1201 | } |
uci1 | 16:744ce85aede2 | 1202 | */ |
uci1 | 3:24c5f0f50bf1 | 1203 | gLastCommWin = time(0); |
uci1 | 13:7a1fb885a8e4 | 1204 | |
uci1 | 0:664899e0b988 | 1205 | SnCommWin::ECommWinResult res = SnCommWin::kUndefFail; |
uci1 | 0:664899e0b988 | 1206 | |
uci1 | 21:ce51bb0ba4a5 | 1207 | // get the trigger rates |
uci1 | 21:ce51bb0ba4a5 | 1208 | float thmrate=0, evtrate=0; |
uci1 | 21:ce51bb0ba4a5 | 1209 | GetRates(thmrate, evtrate); |
uci1 | 22:f957c4f840ad | 1210 | #ifdef DEBUG |
uci1 | 22:f957c4f840ad | 1211 | printf("thmrate=%g, evtrate=%g\r\n",thmrate,evtrate); |
uci1 | 22:f957c4f840ad | 1212 | #endif |
uci1 | 21:ce51bb0ba4a5 | 1213 | |
uci1 | 21:ce51bb0ba4a5 | 1214 | StopAllTickers(); |
uci1 | 13:7a1fb885a8e4 | 1215 | |
uci1 | 13:7a1fb885a8e4 | 1216 | if (gConf.GetCommWinDuration()==0) { |
uci1 | 13:7a1fb885a8e4 | 1217 | // TODO: set min so this is not possible |
uci1 | 13:7a1fb885a8e4 | 1218 | res = SnCommWin::kOkNoMsg; |
uci1 | 13:7a1fb885a8e4 | 1219 | } else { |
uci1 | 13:7a1fb885a8e4 | 1220 | |
uci1 | 13:7a1fb885a8e4 | 1221 | gCommWinOpen = true; |
uci1 | 1:e392595b4b76 | 1222 | Watchdog::kick(); // don't reset! |
uci1 | 13:7a1fb885a8e4 | 1223 | |
uci1 | 13:7a1fb885a8e4 | 1224 | #ifdef DEBUG |
uci1 | 13:7a1fb885a8e4 | 1225 | printf("opening comm window at %d\r\n", (int32_t)gLastCommWin); |
uci1 | 16:744ce85aede2 | 1226 | printf("duration=%u\r\n",gConf.GetCommWinDuration()); |
uci1 | 13:7a1fb885a8e4 | 1227 | #endif |
uci1 | 13:7a1fb885a8e4 | 1228 | |
uci1 | 13:7a1fb885a8e4 | 1229 | // close the file so that the data is all written out. |
uci1 | 13:7a1fb885a8e4 | 1230 | // and open it back up at the beginning (for reading) |
uci1 | 12:d472f9811262 | 1231 | #ifdef DEBUG |
uci1 | 13:7a1fb885a8e4 | 1232 | printf("close & open file. gEvtNum=%u, gPowNum=%u\r\n",gEvtNum,gPowNum); |
uci1 | 25:57b2627fe756 | 1233 | printf("curfile=%p, filename=%s\r\n",SnSDUtils::GetCurFile(), |
uci1 | 25:57b2627fe756 | 1234 | SnSDUtils::GetCurFileName()); |
uci1 | 12:d472f9811262 | 1235 | #endif |
uci1 | 13:7a1fb885a8e4 | 1236 | PIN_lockRegisters = 0; // unlock so we can talk to SD card. |
uci1 | 25:57b2627fe756 | 1237 | #ifdef DEBUG |
uci1 | 25:57b2627fe756 | 1238 | printf("closing output file\r\n"); |
uci1 | 25:57b2627fe756 | 1239 | #endif |
uci1 | 13:7a1fb885a8e4 | 1240 | SnSDUtils::CloseOutputFile(SnSDUtils::GetCurFile()); |
uci1 | 25:57b2627fe756 | 1241 | #ifdef DEBUG |
uci1 | 25:57b2627fe756 | 1242 | printf("open existing file (%d)\r\n",strlen(SnSDUtils::GetCurFileName())); |
uci1 | 25:57b2627fe756 | 1243 | #endif |
uci1 | 25:57b2627fe756 | 1244 | SnSDUtils::OpenExistingFile(SnSDUtils::GetCurFileName(), true, false); |
uci1 | 13:7a1fb885a8e4 | 1245 | |
uci1 | 21:ce51bb0ba4a5 | 1246 | #ifdef DEBUG |
uci1 | 21:ce51bb0ba4a5 | 1247 | printf("setting power\r\n"); |
uci1 | 21:ce51bb0ba4a5 | 1248 | #endif |
uci1 | 13:7a1fb885a8e4 | 1249 | // (probably) power down cards,amps and power up comms |
uci1 | 13:7a1fb885a8e4 | 1250 | SetPower(true); |
uci1 | 13:7a1fb885a8e4 | 1251 | |
uci1 | 25:57b2627fe756 | 1252 | // time to recount files for the status update |
uci1 | 25:57b2627fe756 | 1253 | SnStatusFrame::fgRecalcFiles = true; |
uci1 | 25:57b2627fe756 | 1254 | |
uci1 | 28:484943132bb0 | 1255 | #if defined(ENABLE_AFAR_TWITTER) && defined(ENABLE_AFAR_COMM) |
uci1 | 28:484943132bb0 | 1256 | bool doTwitter = false; |
uci1 | 28:484943132bb0 | 1257 | #endif |
uci1 | 28:484943132bb0 | 1258 | |
uci1 | 21:ce51bb0ba4a5 | 1259 | #ifdef DEBUG |
uci1 | 21:ce51bb0ba4a5 | 1260 | printf("start loop over comms\r\n"); |
uci1 | 21:ce51bb0ba4a5 | 1261 | #endif |
uci1 | 13:7a1fb885a8e4 | 1262 | bool sendStat[kNcomms]; |
uci1 | 13:7a1fb885a8e4 | 1263 | for (uint8_t i=0; i<kNcomms; i++) { |
uci1 | 13:7a1fb885a8e4 | 1264 | sendStat[i]=true; |
uci1 | 13:7a1fb885a8e4 | 1265 | } |
uci1 | 13:7a1fb885a8e4 | 1266 | bool* ss = sendStat; |
uci1 | 13:7a1fb885a8e4 | 1267 | SnCommWin** cw = gComms; |
uci1 | 13:7a1fb885a8e4 | 1268 | for (uint8_t i=0; ((time(0)-gLastCommWin)<gConf.GetCommWinDuration()); i++, cw++, ss++) { |
uci1 | 1:e392595b4b76 | 1269 | Watchdog::kick(); // don't reset! |
uci1 | 13:7a1fb885a8e4 | 1270 | if (i==kNcomms) { |
uci1 | 13:7a1fb885a8e4 | 1271 | i=0; |
uci1 | 13:7a1fb885a8e4 | 1272 | cw = gComms; |
uci1 | 13:7a1fb885a8e4 | 1273 | ss = sendStat; |
uci1 | 13:7a1fb885a8e4 | 1274 | } |
uci1 | 27:efc4d654b139 | 1275 | // skip if no comm object |
uci1 | 13:7a1fb885a8e4 | 1276 | if ((*cw)==0) { |
uci1 | 13:7a1fb885a8e4 | 1277 | continue; |
uci1 | 13:7a1fb885a8e4 | 1278 | } |
uci1 | 27:efc4d654b139 | 1279 | // skip if no power for this comm |
uci1 | 27:efc4d654b139 | 1280 | // THIS IS VITAL! For example, if the ethernet |
uci1 | 27:efc4d654b139 | 1281 | // port is powered down, making an Ethernet obejct |
uci1 | 27:efc4d654b139 | 1282 | // (done in netif) will stall forever waiting for the clock. |
uci1 | 27:efc4d654b139 | 1283 | // Do it here to keep all PIN usage in main.cpp |
uci1 | 27:efc4d654b139 | 1284 | bool havePower=false; |
uci1 | 27:efc4d654b139 | 1285 | switch ((*cw)->GetCommType()) { |
uci1 | 27:efc4d654b139 | 1286 | case SnConfigFrame::kIrid: |
uci1 | 27:efc4d654b139 | 1287 | havePower = gConf.IsPoweredFor(SnConfigFrame::kIridComWin) |
uci1 | 30:f869ed4bcc08 | 1288 | && ( (kIridAfarPwrSame) |
uci1 | 30:f869ed4bcc08 | 1289 | ? PIN_afar_power.read() |
uci1 | 30:f869ed4bcc08 | 1290 | : PIN_iridSbd_power.read() == |
uci1 | 27:efc4d654b139 | 1291 | gConf.GetPowPinSetting(SnConfigFrame::kIridComWin)); |
uci1 | 27:efc4d654b139 | 1292 | break; |
uci1 | 27:efc4d654b139 | 1293 | case SnConfigFrame::kAfar: |
uci1 | 27:efc4d654b139 | 1294 | havePower = gConf.IsPoweredFor(SnConfigFrame::kAfarComWin) |
uci1 | 27:efc4d654b139 | 1295 | && (PIN_afar_power.read() == |
uci1 | 27:efc4d654b139 | 1296 | gConf.GetPowPinSetting(SnConfigFrame::kAfarComWin)); |
uci1 | 27:efc4d654b139 | 1297 | break; |
uci1 | 27:efc4d654b139 | 1298 | case SnConfigFrame::kUSB: |
uci1 | 27:efc4d654b139 | 1299 | havePower = true; // USB always on (for now) |
uci1 | 27:efc4d654b139 | 1300 | break; |
uci1 | 27:efc4d654b139 | 1301 | case SnConfigFrame::kSDcard: // shouldn't happen. skip it |
uci1 | 27:efc4d654b139 | 1302 | default: // unknown.. skip it |
uci1 | 27:efc4d654b139 | 1303 | break; |
uci1 | 27:efc4d654b139 | 1304 | }; |
uci1 | 27:efc4d654b139 | 1305 | if (havePower==false) { |
uci1 | 27:efc4d654b139 | 1306 | continue; |
uci1 | 27:efc4d654b139 | 1307 | } |
uci1 | 27:efc4d654b139 | 1308 | |
uci1 | 16:744ce85aede2 | 1309 | const uint32_t conto = |
uci1 | 16:744ce85aede2 | 1310 | (gConf.GetCommWinDuration() < (*cw)->GetConnectTimeout()) ? |
uci1 | 16:744ce85aede2 | 1311 | gConf.GetCommWinDuration() : (*cw)->GetConnectTimeout(); |
uci1 | 16:744ce85aede2 | 1312 | const uint32_t listo = |
uci1 | 16:744ce85aede2 | 1313 | (gConf.GetCommWinDuration() < (*cw)->GetListenTimeout()) ? |
uci1 | 16:744ce85aede2 | 1314 | gConf.GetCommWinDuration() : (*cw)->GetListenTimeout(); |
uci1 | 16:744ce85aede2 | 1315 | |
uci1 | 16:744ce85aede2 | 1316 | // update power reading in case we want to send it in status |
uci1 | 16:744ce85aede2 | 1317 | GetAvePowerReading(); |
uci1 | 21:ce51bb0ba4a5 | 1318 | |
uci1 | 13:7a1fb885a8e4 | 1319 | // open window and (mabye) send status update |
uci1 | 12:d472f9811262 | 1320 | #ifdef DEBUG |
uci1 | 13:7a1fb885a8e4 | 1321 | printf("calling OpenWindow. ss=%d\r\n",(int)(*ss)); |
uci1 | 21:ce51bb0ba4a5 | 1322 | printf("gtt=%u, ct=%d, lcw=%d, dur=%u\r\n",gConf.GetTimeoutTime(gLastCommWin,conto), |
uci1 | 13:7a1fb885a8e4 | 1323 | time(0), gLastCommWin, gConf.GetCommWinDuration()); |
uci1 | 12:d472f9811262 | 1324 | #endif |
uci1 | 13:7a1fb885a8e4 | 1325 | const SnCommWin::ECommWinResult conres = (*cw)->OpenWindow( |
uci1 | 21:ce51bb0ba4a5 | 1326 | gConf.GetTimeoutTime(gLastCommWin, conto), *ss, gConf, gEvent, gPower, |
uci1 | 13:7a1fb885a8e4 | 1327 | SnSDUtils::GetCurSeqNum(), thmrate, evtrate, |
uci1 | 13:7a1fb885a8e4 | 1328 | gGenBuf); |
uci1 | 13:7a1fb885a8e4 | 1329 | if (conres>=SnCommWin::kConnected) { |
uci1 | 1:e392595b4b76 | 1330 | Watchdog::kick(); // don't reset! |
uci1 | 13:7a1fb885a8e4 | 1331 | // connected. listen for config |
uci1 | 13:7a1fb885a8e4 | 1332 | *ss = false; // don't send status next time |
uci1 | 28:484943132bb0 | 1333 | |
uci1 | 28:484943132bb0 | 1334 | #if defined(ENABLE_AFAR_TWITTER) && defined(ENABLE_AFAR_COMM) |
uci1 | 28:484943132bb0 | 1335 | if ((*cw)->GetCommType()==SnConfigFrame::kAfar) { |
uci1 | 28:484943132bb0 | 1336 | // if we connected by Afar |
uci1 | 28:484943132bb0 | 1337 | doTwitter = true; |
uci1 | 28:484943132bb0 | 1338 | } |
uci1 | 28:484943132bb0 | 1339 | #endif |
uci1 | 28:484943132bb0 | 1340 | |
uci1 | 12:d472f9811262 | 1341 | #ifdef DEBUG |
uci1 | 21:ce51bb0ba4a5 | 1342 | printf("get conf gtt=%u\r\n",gConf.GetTimeoutTime(gLastCommWin, listo)); |
uci1 | 12:d472f9811262 | 1343 | #endif |
uci1 | 13:7a1fb885a8e4 | 1344 | const SnCommWin::ECommWinResult cfgres = (*cw)->GetConfig( |
uci1 | 21:ce51bb0ba4a5 | 1345 | gConf, gConf.GetTimeoutTime(gLastCommWin, listo), gGenBuf, gBufSize); |
uci1 | 16:744ce85aede2 | 1346 | |
uci1 | 13:7a1fb885a8e4 | 1347 | if (cfgres>=SnCommWin::kOkWithMsg) { |
uci1 | 13:7a1fb885a8e4 | 1348 | Watchdog::kick(); // don't reset! |
uci1 | 16:744ce85aede2 | 1349 | |
uci1 | 12:d472f9811262 | 1350 | #ifdef DEBUG |
uci1 | 13:7a1fb885a8e4 | 1351 | printf("received config!\r\n"); |
uci1 | 13:7a1fb885a8e4 | 1352 | printf("send data = %d\r\n", gConf.GetCommSendData()); |
uci1 | 12:d472f9811262 | 1353 | #endif |
uci1 | 13:7a1fb885a8e4 | 1354 | // send data if need be (files, some events, etc) |
uci1 | 21:ce51bb0ba4a5 | 1355 | const uint32_t winto = gConf.GetTimeoutTime(gLastCommWin, |
uci1 | 21:ce51bb0ba4a5 | 1356 | gConf.GetCommWinDuration()); |
uci1 | 13:7a1fb885a8e4 | 1357 | const uint32_t gtt = gConf.IsObeyingTimeout() ? winto : 0; |
uci1 | 13:7a1fb885a8e4 | 1358 | if (gConf.GetCommSendData()!=0) { |
uci1 | 12:d472f9811262 | 1359 | #ifdef DEBUG |
uci1 | 13:7a1fb885a8e4 | 1360 | printf("sending data, gtt=%u. lcw=%u, dur=%u, obey=%s\r\n", |
uci1 | 21:ce51bb0ba4a5 | 1361 | gConf.GetTimeoutTime(gLastCommWin, gConf.GetCommWinDuration()), |
uci1 | 13:7a1fb885a8e4 | 1362 | gLastCommWin, gConf.GetCommWinDuration(), |
uci1 | 13:7a1fb885a8e4 | 1363 | gConf.IsObeyingTimeout() ? "true" : "false"); |
uci1 | 12:d472f9811262 | 1364 | #endif |
uci1 | 16:744ce85aede2 | 1365 | |
uci1 | 13:7a1fb885a8e4 | 1366 | res = (*cw)->SendData(gConf, gEvent, gPower, gGenBuf, gBufSize, |
uci1 | 21:ce51bb0ba4a5 | 1367 | gtt, gConf.GetCommWinDuration()); |
uci1 | 13:7a1fb885a8e4 | 1368 | } else { |
uci1 | 13:7a1fb885a8e4 | 1369 | // don't send anything |
uci1 | 13:7a1fb885a8e4 | 1370 | res = cfgres; |
uci1 | 13:7a1fb885a8e4 | 1371 | } |
uci1 | 13:7a1fb885a8e4 | 1372 | #ifdef DEBUG |
uci1 | 13:7a1fb885a8e4 | 1373 | printf("Got config!\r\n"); |
uci1 | 13:7a1fb885a8e4 | 1374 | #endif |
uci1 | 13:7a1fb885a8e4 | 1375 | Watchdog::kick(); // don't reset! |
uci1 | 13:7a1fb885a8e4 | 1376 | break; |
uci1 | 13:7a1fb885a8e4 | 1377 | } |
uci1 | 21:ce51bb0ba4a5 | 1378 | } else { |
uci1 | 21:ce51bb0ba4a5 | 1379 | (*cw)->CloseConn(gConf.GetTimeoutTime(gLastCommWin, listo)); |
uci1 | 21:ce51bb0ba4a5 | 1380 | } // if connected |
uci1 | 13:7a1fb885a8e4 | 1381 | |
uci1 | 13:7a1fb885a8e4 | 1382 | Watchdog::kick(); // don't reset! |
uci1 | 21:ce51bb0ba4a5 | 1383 | } // end loop over comms |
uci1 | 28:484943132bb0 | 1384 | |
uci1 | 28:484943132bb0 | 1385 | // check Iridium time & close the connection(s) |
uci1 | 15:f2569d8e4176 | 1386 | cw = gComms; |
uci1 | 15:f2569d8e4176 | 1387 | for (uint8_t i=0; i<kNcomms; i++, cw++) { |
uci1 | 15:f2569d8e4176 | 1388 | if ((*cw)==0) { |
uci1 | 15:f2569d8e4176 | 1389 | continue; |
uci1 | 15:f2569d8e4176 | 1390 | } |
uci1 | 28:484943132bb0 | 1391 | // check Iridium time |
uci1 | 16:744ce85aede2 | 1392 | if ((*cw)->GetCommType()==SnConfigFrame::kIrid) { |
uci1 | 16:744ce85aede2 | 1393 | #ifdef DEBUG |
uci1 | 16:744ce85aede2 | 1394 | printf("try to set iridium time\r\n"); |
uci1 | 16:744ce85aede2 | 1395 | #endif |
uci1 | 16:744ce85aede2 | 1396 | // set the clock before closing connection |
uci1 | 16:744ce85aede2 | 1397 | const bool con = |
uci1 | 21:ce51bb0ba4a5 | 1398 | (*cw)->Connect(gConf.GetTimeoutTime(gLastCommWin, |
uci1 | 16:744ce85aede2 | 1399 | gConf.GetCommWinDuration())); |
uci1 | 16:744ce85aede2 | 1400 | if (con) { |
uci1 | 16:744ce85aede2 | 1401 | const uint32_t nt = (*cw)->TrySetSysTimeUnix( |
uci1 | 21:ce51bb0ba4a5 | 1402 | gConf.GetTimeoutTime(gLastCommWin,gConf.GetCommWinDuration())); |
uci1 | 16:744ce85aede2 | 1403 | } |
uci1 | 16:744ce85aede2 | 1404 | } |
uci1 | 28:484943132bb0 | 1405 | // close the connection |
uci1 | 21:ce51bb0ba4a5 | 1406 | (*cw)->CloseConn(gConf.GetTimeoutTime(gLastCommWin,gConf.GetCommWinDuration())); |
uci1 | 15:f2569d8e4176 | 1407 | Watchdog::kick(); // don't reset! |
uci1 | 28:484943132bb0 | 1408 | // after normal Afar connection closed, try to tweet |
uci1 | 31:b5bd3b189150 | 1409 | #if defined(ENABLE_AFAR_TWITTER) && defined(ENABLE_AFAR_COMM) |
uci1 | 28:484943132bb0 | 1410 | if ((*cw)->GetCommType()==SnConfigFrame::kAfar) { |
uci1 | 28:484943132bb0 | 1411 | // tweet |
uci1 | 28:484943132bb0 | 1412 | #ifdef DEBUG |
uci1 | 28:484943132bb0 | 1413 | printf("for twitter: gTwit=%p, doTwitter=%d\r\n",gTwit,(int)doTwitter); |
uci1 | 28:484943132bb0 | 1414 | #endif |
uci1 | 28:484943132bb0 | 1415 | // send a twitter update |
uci1 | 28:484943132bb0 | 1416 | if ( (gTwit!=0) && doTwitter ) { |
uci1 | 28:484943132bb0 | 1417 | const uint32_t conto = |
uci1 | 28:484943132bb0 | 1418 | (gConf.GetCommWinDuration() < gTwit->GetConnectTimeout()) ? |
uci1 | 28:484943132bb0 | 1419 | gConf.GetCommWinDuration() : gTwit->GetConnectTimeout(); |
uci1 | 28:484943132bb0 | 1420 | const uint32_t listo = |
uci1 | 28:484943132bb0 | 1421 | (gConf.GetCommWinDuration() < gTwit->GetListenTimeout()) ? |
uci1 | 28:484943132bb0 | 1422 | gConf.GetCommWinDuration() : gTwit->GetListenTimeout(); |
uci1 | 28:484943132bb0 | 1423 | #ifdef DEBUG |
uci1 | 28:484943132bb0 | 1424 | printf("open twit window. conto=%u, listo=%u\r\n", |
uci1 | 28:484943132bb0 | 1425 | conto, listo); |
uci1 | 28:484943132bb0 | 1426 | #endif |
uci1 | 28:484943132bb0 | 1427 | const SnCommWin::ECommWinResult conres = gTwit->OpenWindow( |
uci1 | 28:484943132bb0 | 1428 | gConf.GetTimeoutTime(gLastCommWin, conto), false, gConf, |
uci1 | 28:484943132bb0 | 1429 | gEvent, gPower, |
uci1 | 28:484943132bb0 | 1430 | SnSDUtils::GetCurSeqNum(), thmrate, evtrate, |
uci1 | 28:484943132bb0 | 1431 | gGenBuf); |
uci1 | 28:484943132bb0 | 1432 | if (conres>=SnCommWin::kConnected) { |
uci1 | 28:484943132bb0 | 1433 | Watchdog::kick(); // don't reset! |
uci1 | 28:484943132bb0 | 1434 | gTwit->Tweet(gConf, thmrate, evtrate, gGenBuf, |
uci1 | 28:484943132bb0 | 1435 | gConf.GetTimeoutTime(time(0), listo)); |
uci1 | 28:484943132bb0 | 1436 | } |
uci1 | 28:484943132bb0 | 1437 | } |
uci1 | 28:484943132bb0 | 1438 | } |
uci1 | 28:484943132bb0 | 1439 | #endif |
uci1 | 28:484943132bb0 | 1440 | } |
uci1 | 28:484943132bb0 | 1441 | } // if duration >0 |
uci1 | 28:484943132bb0 | 1442 | |
uci1 | 28:484943132bb0 | 1443 | /* not working. must use DEFCONF.DAT to change IP's. |
uci1 | 28:484943132bb0 | 1444 | // change comm parameters (IP addresses) |
uci1 | 28:484943132bb0 | 1445 | #ifdef DEBUG |
uci1 | 28:484943132bb0 | 1446 | printf("set comm params\r\n"); |
uci1 | 28:484943132bb0 | 1447 | #endif |
uci1 | 28:484943132bb0 | 1448 | for (uint8_t cc=0; cc<kNcomms; cc++) { |
uci1 | 28:484943132bb0 | 1449 | if (gComms[cc]!=0) { |
uci1 | 28:484943132bb0 | 1450 | gComms[cc]->Set(gConf); |
uci1 | 15:f2569d8e4176 | 1451 | } |
uci1 | 0:664899e0b988 | 1452 | } |
uci1 | 28:484943132bb0 | 1453 | */ |
uci1 | 28:484943132bb0 | 1454 | |
uci1 | 4:a91682e19d6b | 1455 | // (probably) power down comms and power up cards,amps |
uci1 | 4:a91682e19d6b | 1456 | SetPower(false); |
uci1 | 4:a91682e19d6b | 1457 | |
uci1 | 1:e392595b4b76 | 1458 | // reset config with system powered (for DAC/PLA setting) |
uci1 | 12:d472f9811262 | 1459 | #ifdef DEBUG |
uci1 | 21:ce51bb0ba4a5 | 1460 | printf("calling SetConfigAndMakeOutputFile\r\n"); |
uci1 | 12:d472f9811262 | 1461 | #endif |
uci1 | 22:f957c4f840ad | 1462 | |
uci1 | 21:ce51bb0ba4a5 | 1463 | SetConfigAndMakeOutputFile(); |
uci1 | 21:ce51bb0ba4a5 | 1464 | |
uci1 | 12:d472f9811262 | 1465 | #ifdef DEBUG |
uci1 | 1:e392595b4b76 | 1466 | printf("closing comm win at %d\r\n",(int32_t)time(0)); |
uci1 | 12:d472f9811262 | 1467 | #endif |
uci1 | 1:e392595b4b76 | 1468 | |
uci1 | 0:664899e0b988 | 1469 | gCommWinOpen = false; |
uci1 | 0:664899e0b988 | 1470 | return res; |
uci1 | 0:664899e0b988 | 1471 | } |