/******************************************************************************/ /* Copyright 2003 MBARI Monterey Bay Aquarium Research Institute */ /******************************************************************************/ /******************************************************************************/ /* Summary : Main() for LOBO Acquistion and Telemetry Engine. L.A.T.E */ /* Filename : LOBO.C */ /* Author : Luke Coletti */ /* Project : */ /* Version : 1.0 */ /* Compiler : Aztec C68k/ROM v5.2D */ /* Created : 01/01/05 */ /* Archived : */ /******************************************************************************/ /* Modification History: */ /******************************************************************************/ // TO DO LIST: // Add Emergency Message Tag #include /* Tattletale Model 8 Definitions */ #include /* definitions and prototypes for Model 8 library */ #include /* Pico DOS / Persistor CF8 Defs. */ #include #include #include #include #include #include #include #include #include #include "lobo.h" /* Application Build Info */ char bfile[20] = __FILE__; char bdate[20] = __DATE__; char btime[20] = __TIME__; /* Local Function Declarations */ void DataAcquisitionAndTelemetry(void); int InitiateConnection(void); int InitiateServices(void); int LogLoboStatusData(FILE *fptr); /******************************************************************************/ /* Common LOBO Variables used and or shared in any build */ /******************************************************************************/ #include "lobohead.c" void main(void) { FILE *log_file; uchar Rx_char; ushort Rx_chars, Rx_loop; int i, year; float tstamp; SLPResult slprtn; InitTT8(NO_WATCHDOG, 0x0449); /* Init Model 8 set TPU into EMU mode */ InitLOBO(); printf("\n LOBO Application Code Running Enter M for menu(s)\n"); if(reset_flag == TRUE){ if(slog_mode == 1){ printf("\n Scheduled Logging will sync to the next %02hu:00 minutes after the hour.\n", sync_min); wakeup.secs = SyncNextSample(sync_min, last_sample); } else if(slog_mode == 2){ printf("\n Scheduled Logging will begin at %02hu:%02hu:00 LOCAL TIME.\n", sync_hour, sync_min); wakeup.secs = SyncStartTime(sync_hour, sync_min, tzoffset); } else wakeup.secs = sys_reset_time + (lobo_sleep * 60L); last_sample = wakeup.secs; } //start sleep processing nightynite: if( UsbActive() == TRUE ) printfUSB("\nLOBO Nightynite Next Wakeup (GMT), %s", ctime(&wakeup.secs)); //low power sleep start tserPwrDown(); ioPwrDown(); SerInFlush(); SetTickRate( TICKS_FOR_LPSLEEP ); wakeup.ticks = 0; LowPowerSleep(0L); slprtn = LowPowerSleepTill(wakeup); V2CardPower(1); SetTickRate( TICKS_PER_SECOND ); // back to one tick every 0.001 secs ioPwrUp(); tserPwrUp(); //low power sleep finish wake_time = RtcToCtm(); //we are awake now if( UsbActive() == TRUE ) printfUSB("\nLOBO Wakeup, ret code = %d, %s", slprtn, ctime(&wake_time)); //RxD is also tied to PortF Bit1, IRQ1-, and can wake us up from LPSleep //if IRQ1- is enabled, track the RxD as an input (1 is idle, 0 is a break) if(Pin(F,1) == 0){ //they're BREAKING, how rude! break_flag = 1; i=0; while( (Pin(F,1) == 0) && (i <= 500) ){ //wait for break to go away Sleep(0L); //timeout after 5 secs Sleep(10L); //sleep for 0.01 ++i; } } else break_flag = 0; if(Pin(F,2) == 0){ //is IRQ2 being asserted? printf("\nERROR - IRQ2 IS BEING ASSERTED!\n"); if( UsbActive() == TRUE ) printfUSB("\nERROR - IRQ2 IS BEING ASSERTED!\n"); } SerInFlush(); if( slprtn == sleepOK ){ if( UsbActive() == TRUE ) printfUSB("\nLOBO Awakened on Schedule Starting Sampling, code %d, %s", slprtn, ctime(&wake_time) ); last_sample = wake_time; DataAcquisitionAndTelemetry(); pdcfinfo("A:", &size, &avail); //check if we're going to run out of memory soon if( avail <= 32768 ){ //Send Emergency Transmission to LOBOSERV!!! } else if( avail < 2048 ){ //too late calling it quits! log_file = openLogFile(); if(log_file != FNULL){ tstamp = GetDOYtime(&year); fprintf(log_file,", %04d.%010f, CF8 Card memory expired with %ld BYTES available!\n", year, tstamp, avail); fclose(log_file); } ioPwrDown(); ResetToPicoDOS(); } current_time = RtcToCtm(); //where are we now wakeup.secs = current_time + (lobo_sleep*60L) - (current_time-wake_time); goto nightynite; }//end slprtn = sleepOK else if( slprtn == sleepMissed ){ //sleep set to a time of future past! if( lobo_sleep == 0 ) lobo_sleep = LOBOSLP_VAL; wakeup.secs = SyncNextSample(60, last_sample); if( UsbActive() == TRUE ){ printfUSB("\nLOBO Alarm set to a time of future past, %s", ctime(&wake_time)); printfUSB("Sample Time ReSync to, %s", ctime(&wakeup.secs)); } log_file = openLogFile(); if(log_file != FNULL){ tstamp = GetDOYtime(&year); fprintf(log_file,", %04d.%010f, Sample Time ReSync to, %s", year, tstamp, ctime(&wakeup.secs)); fclose(log_file); } goto nightynite; }//end slpret = sleepMissed else if( slprtn == sleepInterrupted ){ if( UsbActive() == TRUE ){ if(break_flag == 1) printfUSB("\nLOBO Awakened with BREAK, code %d, %s", slprtn, ctime(&wake_time) ); else printfUSB("\nLOBO Awakened without BREAK, code %d, %s", slprtn, ctime(&wake_time) ); printfUSB("Waiting for LOBO CMD, timeout in 30 secs\n"); } Rx_loop = 0; Rx_chars = 0; while( Rx_loop <= 150 ){ //timeout in 15secs Sleep(0L); Rx_char = 0; if(SerByteAvail() == 0){ Sleep(100); // sleep for 0.1 sec ++Rx_loop; continue; } else{ Rx_char=SerGetByte(); ++Rx_chars; } switch (Rx_char) { case 'M' : if( UsbActive() == TRUE ){ current_time = RtcToCtm(); printfUSB("\nControl Menu Requested, %s\n", ctime(¤t_time)); } RootMenu(); if( modem_pwr == TRUE ){ ModemPowerOff(); printf("\n Radio Power was left ON! Powering DOWN...\n"); } if( Get_K1_K8_State() ){ Set_K1_K8_State(0xFF00); //turn 'em all off! printf("\n Comm Relay(s) were left ON! Resetting...\n"); } Rx_loop = 0; // reset while loop timeout (user could need some time) SerInFlush(); break; case 'W' : if( UsbActive() == TRUE ){ current_time = RtcToCtm(); printfUSB("\nWakeup Status Requested, %s\n", ctime(¤t_time)); } printf("ACK\n"); Rx_loop = 0; // reset while loop timeout SerInFlush(); break; } // end switch } // end while if(Rx_chars == 0){ if( UsbActive() == TRUE ){ current_time = RtcToCtm(); printfUSB("\nNo chars received after wakeup, %s\n", ctime(¤t_time)); } log_file = openLogFile(); if(log_file != FNULL){ tstamp = GetDOYtime(&year); if(break_flag == TRUE) fprintf(log_file,", %04d.%010f, LOBO comms wakeup (BREAK-ON) but NO chars received\n", year, tstamp); else fprintf(log_file,", %04d.%010f, LOBO comms wakeup (BREAK-OFF) but NO chars received\n", year, tstamp); fclose(log_file); } } else{ if( UsbActive() == TRUE ){ current_time = RtcToCtm(); printfUSB("\n%d chars received, %s\n", Rx_chars, ctime(¤t_time)); } } current_time = RtcToCtm(); //where are we now if(current_time >= wakeup.secs){ if( UsbActive() == TRUE ) printfUSB("\nLOBO Alarm now behind due to comms wakeup, data resync will now occur, %s\n", ctime(¤t_time)); log_file = openLogFile(); if(log_file != FNULL){ tstamp = GetDOYtime(&year); fprintf(log_file, ", %04d.%010f, LOBO Alarm now behind due to comms wakeup, data resync will now occur\n", year, tstamp); fclose(log_file); } } goto nightynite; } //end slprtn = sleepInterrupted else{ if( UsbActive() == TRUE ){ current_time = RtcToCtm(); printfUSB("\nMYSTERY WAKEUP!, code %d, %s", slprtn, ctime(&wake_time) ); } current_time = RtcToCtm(); //where are we now if(current_time >= wakeup.secs){ if( UsbActive() == TRUE ) printfUSB("\nLOBO Alarm now behind due to MYSTERY wakeup, data resync will now occur, %s\n", ctime(¤t_time)); log_file = openLogFile(); if(log_file != FNULL){ tstamp = GetDOYtime(&year); fprintf(log_file,", %04d.%010f, LOBO Alarm now behind due to MYSTERY wakeup, data resync will now occur\n", year, tstamp); fclose(log_file); } } goto nightynite; // DON'T ASK, it's a mystery! } } // end main void DataAcquisitionAndTelemetry(void) { FILE *log_file; uchar samp_mask; int c_ret, s_ret, z_ret; log_file = openLogFile(); samp_mask = 0x01; if( (sample_enable & samp_mask) != FALSE){ if( UsbActive() == TRUE ){ current_time = RtcToCtm(); printfUSB("\nLOBO Sampling ISUS, %s\n", ctime(¤t_time)); } SampleISUS(log_file, SAMPLE); } samp_mask = samp_mask << 1; if( (sample_enable & samp_mask) != FALSE){ if( UsbActive() == TRUE ){ current_time = RtcToCtm(); printfUSB("\nLOBO Sampling SBE16, %s\n", ctime(¤t_time)); } SampleSBE16(log_file, SAMPLE); } samp_mask = samp_mask << 1; if( (sample_enable & samp_mask) != FALSE){ if( UsbActive() == TRUE ){ current_time = RtcToCtm(); printfUSB("\nLOBO Sampling SBE37, %s\n", ctime(¤t_time)); } SampleSBE37(log_file, SAMPLE); } fclose(log_file); ++samp_ctr; WrDS1994Long(SAMPCTR_PTR, samp_ctr, DS1994_ROM); if( ((samp_ctr % samps_per_xmit) == 0) || (send_again == TRUE) ){ // every n samples or when send_again, phone home... //var is toggled on MODEM CTS state change within ModemPuts() (modem.c) and sendline() (ZMODEM io_zmod.c) modem_cts_ctr = 0; //vars to be set in InitiateConnection() calls modem_connect_secs=modem_rssi_avg=modem_rssi_sd = -1.0; //vars to be set in InitiateServices() calls ping_mean=ping_min=ping_max = -1.0; server_pid = -1L; rtc_delta = -1000L; if( UsbActive() == TRUE ){ current_time = RtcToCtm(); printfUSB("\nInitiating Telemetry, %s\n", ctime(¤t_time)); } c_ret = InitiateConnection(); if( c_ret == OK ){ s_ret = InitiateServices(); log_file = openLogFile(); LogLoboStatusData(log_file); fclose(log_file); if( s_ret == OK ){ // all of the services succeeded, time to ZMODEM... z_ret = ZmodemFilesToServer(10, "*.LOG", LOBOSERV_DATA_MODE); if( z_ret == OK ){ // ZMODEM and FSTAT both succeeded send_again = FALSE; ++file_ctr; WrDS1994Long(FILECTR_PTR, file_ctr, DS1994_ROM); } else{ // either ZMODEM or FSTAT failed, let's send again at the next sample period, ZMODEM will use CRASH RECOVERY to sync the file to the end of the last successful packet send_again = TRUE; if( z_ret == DISCONNECT ) ModemLogDisconnect(); } } //end s_ret if else send_again = TRUE; // we could connect to the ACCESS POINT but one or more of the services failed ModemPowerOff(); } // end InitiateConnection() if else{ send_again = FALSE; // if we can't at least connect to the ACCESS POINT don't waste power trying to force a connect every sample period ModemPowerOff(); if( UsbActive() == TRUE ){ current_time = RtcToCtm(); printfUSB("\nLOBO Server Connection Error, %d, %s\n", c_ret, ctime(¤t_time)); } log_file = openLogFile(); LogLoboStatusData(log_file); fclose(log_file); } } } int InitiateConnection(void) { FILE *log_file; int ret, year; float tstamp; tstamp = GetDOYtime(&year); if( (ret = ModemPowerOn()) != TRUE){ log_file = openLogFile(); if(log_file != FNULL) fprintf(log_file, ", %04d.%010f, ModemPowerOn(), %d\n", year, tstamp, ret); fclose(log_file); return( -1 ); } Sleep(0); Sleep(TICKS_PER_SECOND*3); if( (ret = LinkToAccessPoint(LOBOSERV_DATA_MODE)) != OK ){ if( ret == DISCONNECT ) ModemLogDisconnect(); log_file = openLogFile(); if(log_file != FNULL) fprintf(log_file, ", %04d.%010f, LinkToAccessPoint(), %d\n", year, tstamp, ret); fclose(log_file); return( -2 ); } // if radio wasn't attached during controller power up modem_id will be zero if(modem_id == 0L) modem_id = ModemGetRadioID( modem_baud ); return( OK ); } int InitiateServices(void) { FILE *log_file; int ret, year; float tstamp; Sleep(0); Sleep(TICKS_PER_SECOND*3); if( (ret = LoboTalkMode(LOBOSERV_DATA_MODE)) <= 0 ){ if( ret == DISCONNECT ) ModemLogDisconnect(); tstamp = GetDOYtime(&year); log_file = openLogFile(); if(log_file != FNULL) fprintf(log_file, ", %04d.%010f, LoboTalkMode(), %d\n", year, tstamp, ret); fclose(log_file); return( -1 ); } Sleep(0); Sleep(TICKS_PER_SECOND*3); if( (ret = PingServer(10, &ping_mean, &ping_min, &ping_max, LOBOSERV_DATA_MODE)) <= 0 ){ if( ret == DISCONNECT ) ModemLogDisconnect(); tstamp = GetDOYtime(&year); log_file = openLogFile(); if(log_file != FNULL) fprintf(log_file, ", %04d.%010f, PingServer(), %d\n", year, tstamp, ret); fclose(log_file); return( -2 ); } Sleep(0); Sleep(TICKS_PER_SECOND*3); if( (ret = GetServerPID(&server_pid, LOBOSERV_DATA_MODE)) <= 0 ){ if( ret == DISCONNECT ) ModemLogDisconnect(); tstamp = GetDOYtime(&year); log_file = openLogFile(); if(log_file != FNULL) fprintf(log_file, ", %04d.%010f, GetServerPID(), %d\n", year, tstamp, ret); fclose(log_file); return( -3 ); } Sleep(0); Sleep(TICKS_PER_SECOND*3); if( (ret = SyncRtcToServer(&rtc_delta, LOBOSERV_DATA_MODE)) <= 0 ){ if( ret == DISCONNECT ) ModemLogDisconnect(); tstamp = GetDOYtime(&year); log_file = openLogFile(); if(log_file != FNULL) fprintf(log_file, ", %04d.%010f, SyncRtcToServer(), %d\n", year, tstamp, ret); fclose(log_file); return( -4 ); } return( OK ); } int LogLoboStatusData(FILE *fptr) { int ret, year; ushort relays; float tstamp; float battv, battsd; float temp, humi; tstamp = GetDOYtime(&year); fprintf(fptr,", %04d.%010f, ", year, tstamp); //system sample counter fprintf(fptr, "%lu, ", samp_ctr); //batt voltage mean and stdev RdBattVoltage(&battv, &battsd); fprintf(fptr, "%.2f, %.2lf, ", battv, battsd); //housing temperature and humidity read_sht75(&temp, &humi); fprintf(fptr, "%.1f, %.1f, ", temp, humi); //comm relay states relays = Get_K1_K8_State(); fprintf(fptr, "0x%02X, ", relays); //system reset event counter fprintf(fptr, "%lu, ", sys_reset_ctr); //last system reset event time fprintf(fptr, "%lu, ", sys_reset_time); //hardware watchdog event counter fprintf(fptr, "%lu, ", watchdog_ctr); //power cycle event counter fprintf(fptr, "%lu, ", DS1994_pcc); //compact FLASH total size and bytes available pdcfinfo("A:", &size, &avail); fprintf(fptr, "%ld, %ld, ", size, avail); //radio serial number fprintf(fptr, "0x%06lX, ", modem_id); //modem failed connection event counter connect_fail_ctr = (ulong)RdDS1994Long((ushort)CONNFAILCTR_PTR, DS1994_ROM); fprintf(fptr, "%lu, ", connect_fail_ctr); //last failed connection event time connect_fail_time = (ulong)RdDS1994Long( (ushort)CONNFAILTIME_PTR, DS1994_ROM); fprintf(fptr, "%lu, ", connect_fail_time); //modem dropped connection event counter carrier_drop_ctr = (ulong)RdDS1994Long((ushort)CARRDROPCTR_PTR, DS1994_ROM); fprintf(fptr, "%lu, ", carrier_drop_ctr); //last dropped connection event time carrier_drop_time = (ulong)RdDS1994Long( (ushort)CARRDROPTIME_PTR, DS1994_ROM); fprintf(fptr, "%lu, ", carrier_drop_time); //modem CTS state changes per session fprintf(fptr, "%lu, ", modem_cts_ctr); //modem elapsed timer DS1994_elp = (ulong)RdDS1994Long((ushort)ELPTVAL_PTR, DS1994_ROM); fprintf(fptr, "%lu, ", DS1994_elp); //access point connect time fprintf(fptr, "%02.4f, ", modem_connect_secs); //connection signal strength mean and stdev fprintf(fptr, "%02.4f, %02.4f, ", modem_rssi_avg, modem_rssi_sd); //server PING access time stats: min, max, mean, in millisecs fprintf(fptr, "%.0f, %.0f, %.0f, ", ping_min, ping_max, ping_mean); //server PID value fprintf(fptr, "%ld, ", server_pid); //server RTC sync value fprintf(fptr, "%ld\n", rtc_delta); return( OK ); } /******************************************************************************/ /* Common LOBO Functions used and or shared in any build */ /******************************************************************************/ #include "loboinit.c" #include "lobomenu.c" #include "loboutil.c"