/******************************************************************************/ /* LOBO Util Routines */ /******************************************************************************/ void *AllocateDirListingMem(ushort files) { if( (files <= 0) || (files > 255) ) return( NULL ); else return( malloc( (size_t)(sizeof(DirStrEntry)*files) ) ); } long CreateDirListing(DirStrEntry *dirlist, char *wildcard, ushort files) { char pico_cmd[85]; //PicoDOS command line buff is only 81 chars char *srchptr; ushort i; long dirlen, recs; if( (files <= 0) || (files > 255) ) return( ERROR ); if(dirlist == NULL) return( ERROR ); dirlen = (long)(files * 24L); memset(dirlist, '\0', (size_t)(sizeof(DirStrEntry)*files)); sprintf(pico_cmd, "dir %s /m %lX %lX", wildcard, dirlist, dirlen); execstr(pico_cmd); recs = 0L; i = files; while( i > 0 ){ //let's take a walk through mem and clean things up! if(dirlist->name[0]){ if(srchptr=memchr(dirlist->name, ' ', (size_t)sizeof(dirlist->name))) memset(srchptr, '\0', 1); //puts((char *) dirlist); dirlist->zterm = '\0'; ++recs; } --i; if(i != 0) ++dirlist; } return( recs ); } FILE *openLogFile( void ) { FILE *fptr; char filename[] = "yydddnnn.log"; ushort doy; current_time = RtcToCtm(); tp = localtime(¤t_time); doy = DayOfYear((int)(tp->tm_year+1900), (int)(tp->tm_mon+1), tp->tm_mday); last_doy = (ushort)RdDS1994Short((ushort)LASTDOY_PTR, DS1994_ROM); if(doy != last_doy){ if( UsbActive() == TRUE ) printfUSB("\nLast DOY = %u, Current DOY = %u\n", last_doy, doy); WrDS1994Short(LASTDOY_PTR, doy, DS1994_ROM); file_ctr = 1L; WrDS1994Long(FILECTR_PTR, file_ctr, DS1994_ROM); } if(file_ctr > 999) file_ctr = 999; sprintf(filename,"%02d%03hu%03lu.log", (tp->tm_year-100), doy, file_ctr); fptr = fopen(filename, "r"); if(fptr != FNULL){ fseek(fptr, 0L, SEEK_END); if((ftell(fptr)/1000) > lf_limit){ ++file_ctr; WrDS1994Long(FILECTR_PTR, file_ctr, DS1994_ROM); sprintf(filename,"%02d%03hu%03hu.log", (tp->tm_year-100), doy, file_ctr); } } fclose(fptr); if( UsbActive() == TRUE ) printfUSB("\nLOBO Log File %s, %s\n", filename, ctime(¤t_time)); fptr = fopen(filename, "a+"); if(fptr != FNULL) return(fptr); else return( FNULL ); } int RemoveRenameSentFile(char *fname) { char fname2[20]; char *ptr; size_t len; FILE *flash_file; flash_file = fopen(fname, "r"); if(flash_file == NULL){ printf("Could not locate file: %s\n", fname); fclose(flash_file); return(); } fclose(flash_file); if( data_mode == REMOVE_AFTER_XMIT ){ if( remove(fname) == OK) return( TRUE ); else return ( FALSE ); } else if( data_mode == RENAME_AFTER_XMIT ){ if( strcspn(fname, ".") != 0){ // file has extension ptr=memccpy(fname2, fname, '.', sizeof(fname2)-5); sprintf(ptr, "XMT"); if( UsbActive() ) printfUSB("Old Name: %s New Name: %s\n", fname, fname2); } else{ // file has no extension strcpy(fname2, fname); len=strlen(fname2); sprintf(fname2+len+1, ".XMT"); if( UsbActive() ) printfUSB("Old Name: %s New Name: %s\n", fname, fname2); } if( rename(fname, fname2) == OK ) return( TRUE ); else return ( FALSE ); } } void RdBattVoltage(float *Volts, float *StdDev) { #define READINGS 10 int i; float adval[READINGS]; float sum; float ad_vref = 4.096; float resistor_ratio = (4270.0 + 887.0) / 887.0; Set_Bit_WrLatch2(VSYS_MON_ENABLE); Sleep(0); Sleep(TICKS_PER_SECOND); AtoDReadWord(0); for(i = 0 ; i < READINGS ; i++){ adval[i] = (float)((AtoDReadWord(0) >> 3) & 0x0FFF); adval[i] = (adval[i] / 0x0FFF) * ad_vref * resistor_ratio; } Clear_Bit_WrLatch2(VSYS_MON_ENABLE); VectorSumMean(READINGS, adval, &sum, Volts); VectorStdDev(READINGS, adval, Volts, StdDev); } void InitWatchDogKeepAlive(void) { short pwmper; pwmper = TPUGetTCR1() / 10000; // 400Hz output w/4MHz TC1 clk rate CHANPRIOR(WDOG_KEEPALIVE_TPUCH, Disabled); // disable processing TPU ch *CIER &= ~(1 << WDOG_KEEPALIVE_TPUCH ); // don't want interrupts enabled FUNSEL(WDOG_KEEPALIVE_TPUCH, PWM); // channel function select PRAM[WDOG_KEEPALIVE_TPUCH][0] = OutputTCR1 | NoChangePAC | ForceLow; PRAM[WDOG_KEEPALIVE_TPUCH][2] = pwmper/2; // hi period PRAM[WDOG_KEEPALIVE_TPUCH][3] = pwmper; // period HOSTSERVREQ(WDOG_KEEPALIVE_TPUCH, 2); // issue request CHANPRIOR(WDOG_KEEPALIVE_TPUCH, LowPrior); // set channel priority while(HOSTSERVSTAT(WDOG_KEEPALIVE_TPUCH) & 3) // await reply ; } int CheckWatchDog(void) { if( (RdLatch1() & 0x0080) != FALSE) return( TRUE ); else return( FALSE ); } void EnableWatchDog(void) { Set_Bit_WrLatch2(WATCHDOG_ENABLE); Sleep(0); Sleep(TICKS_PER_SECOND); } void DisableWatchDog(void) { Clear_Bit_WrLatch2(WATCHDOG_ENABLE); Sleep(0); Sleep(TICKS_PER_SECOND); } ulong SyncStartTime(ushort sync_hr, ushort sync_min, int tzone) { time_t sync_time; //sync time in local time time_t loc_time; //current local time long delta_secs; long secsperday=86400; int hr, min, sec; loc_time = RtcToCtm() - (tzone*3600L); tp = localtime(&loc_time); hr = sync_hr - tp->tm_hour; min = sync_min - tp->tm_min; sec = 0 - tp->tm_sec; delta_secs = (hr*3600L) + (min*60L) + (sec*1L); sync_time = (ulong) (loc_time + delta_secs); if(sync_time <= (loc_time + 3600L)) //if sync time is past start tomorrow sync_time = sync_time + secsperday; tp = localtime(&sync_time); printf(" Local time logging start: %02d/%02d/%02d %02d:%02d:%02d\n", tp->tm_mon+1, tp->tm_mday, tp->tm_year+1900, tp->tm_hour, tp->tm_min, tp->tm_sec); sync_time = sync_time + (tzone*3600L); tp = localtime(&sync_time); printf(" GMT time logging start: %02d/%02d/%02d %02d:%02d:%02d\n", tp->tm_mon+1, tp->tm_mday, tp->tm_year+1900, tp->tm_hour, tp->tm_min, tp->tm_sec); return(sync_time); } ulong SyncNextSample(ushort sync_min, ulong last_sample) { long inc; time_t sync_time; struct tm *ts; if( sync_min <= 59 ) { //sync the next sample to the sync_min(s) after the hour current_time = RtcToCtm(); ts = localtime(¤t_time); if( ts->tm_min > (sync_min + 3) ){ current_time += 3600L; // increment to the next hour ts = localtime(¤t_time); } ts->tm_min = sync_min; ts->tm_sec = 0; sync_time = mktime(ts); //on a real computer mktime expects the structure to be in localtime which it isn't in this case it's GMT!!! return( sync_time ); } else { //sync forward from the last sample time, time between samples (isus_sleep) is in minutes if(lobo_sleep == 0) //make sure we won't loop forever! lobo_sleep = LOBOSLP_VAL; inc = 1L; while(1){ current_time = RtcToCtm(); sync_time = last_sample + (lobo_sleep*60L*inc); if( sync_time >= (current_time + (lobo_sleep*60L)) ) break; else ++inc; } return( sync_time ); } } float GetDOYtime(int *year) { int DOY; float fDOY; time_t timer; struct tm *dt; timer = RtcToCtm(); // get number of secs from TT8 RTC (PIC) dt = localtime(&timer); // transform epoch secs into date/time struct DOY = DayOfYear((int)(dt->tm_year+1900), (int)(dt->tm_mon+1), dt->tm_mday); fDOY = (float) DOY + (float) (dt->tm_hour/24.0) + (float) (dt->tm_min/1440.0) + (float) (dt->tm_sec/86400.0); *year = dt->tm_year+1900; return(fDOY); } ushort DayOfYear(int yy, int mm, int dd) { int K; /* Check for leap year */ if ((yy % 4 == 0) && ((yy < 1583) || (yy % 100 != 0) || (yy % 400 == 0))) K = 1; else K = 2; return (275 * mm / 9) - K * ((mm + 9) / 12) + (dd - 30); } int safegets(char *buffer, int n) { char *ptr; // ptr used for finding '\n' fgets(buffer,n,stdin); // Get n chars buffer[n+1]='\0'; // Set last char to null if( (ptr=strchr(buffer,'\n')) != NULL ) *ptr = '\0'; // Change '\n' to '\0' return strlen(buffer); // Return the length } //WARNING!!! be sure address is on a boundry that matches word alignment!!! unsigned short GetCPURegData(unsigned long val) { ; #asm movea.l %%val,a0 ;load address reg (32bits) move.w (a0),d0 ;get data via indirect memory addr (16bits) ;return from C function call #endasm } void delay( ushort ticks ) { Sleep(0L); Sleep((ulong)ticks); } void delaySecs( ushort secs ) { Sleep(0L); Sleep( (ulong)secs * TICKS_PER_SECOND ); } float CtoF(float degC) { return(9.0/5.0 * degC + 32.0); } void VectorMinMax(ushort end, float data[], float *min, float *max) { ushort i; *max = data[0]; *min = data[0]; for(i = 0; i < end ; i++){ if(data[i] > *max) *max = data[i]; else if(data[i]< *min) *min = data[i]; } } void VectorSumMean(ushort end, float data[], float *sum, float *mean) { ushort i; *sum = 0.0; *mean = 0.0; for(i = 0; i < end ; i++){ *sum += data[i]; } *mean = (*sum/end); } void VectorStdDev(ushort end, float data[], float *mean, float *stdev) { ushort i; float stdvar; stdvar = 0.0; *stdev = 0.0; for(i = 0; i < end; i++){ stdvar += pow((data[i] - *mean), 2.0); } stdvar /= (end - 1); *stdev = sqrt(stdvar); } void DisplayTimes(uchar *ROM_ID, int tzone) { time_t loc_time; //current local time double diff; /* get the current times from TT8 PIC and Dallas TIC */ pic_secs = RtcToCtm(); DS1994_secs = (time_t)RdDS1994Long((ushort)TIMEVAL_PTR, ROM_ID); loc_time = pic_secs - (tzone*3600L); tp = localtime(&pic_secs); printf(" LOBO RTC Time (GMT): %02d/%02d/%02d %02d:%02d:%02d\n", tp->tm_mon+1, tp->tm_mday, tp->tm_year+1900, tp->tm_hour, tp->tm_min, tp->tm_sec); tp = localtime(&loc_time); printf(" Adjusted Local Time: %02d/%02d/%02d %02d:%02d:%02d\n", tp->tm_mon+1, tp->tm_mday, tp->tm_year+1900, tp->tm_hour, tp->tm_min, tp->tm_sec); tp = localtime(&sys_reset_time); printf("\n LOBO Power Up (GMT): %02d/%02d/%02d %02d:%02d:%02d\n", tp->tm_mon+1, tp->tm_mday, tp->tm_year+1900, tp->tm_hour, tp->tm_min, tp->tm_sec); printf(" TZ Offset (GMT - LOCAL) : %+.2lf hrs.\n", (difftime(pic_secs, loc_time) / 3600.0)); diff = difftime(pic_secs, DS1994_secs); printf(" RTC delta (TT8 - DS1994) : %+.2lf secs.\n", diff); } void DisplayByteVal(char *msgstr, uchar ByteVal, int device) { int i; if(device == USB_DEVICE) printfUSB("%s = 0x%02Xh = ", msgstr, ByteVal); else printf("%s = 0x%02Xh = ", msgstr, ByteVal); for(i = 0; i < 8; i++){ if((ByteVal & 0x80) != 0){ if(device == USB_DEVICE) printfUSB("1"); else printf("1"); } else{ if(device == USB_DEVICE) printfUSB("0"); else printf("0"); } ByteVal = ByteVal << 1; } if(device == USB_DEVICE) printfUSB("b\n"); else printf("b\n"); } void DisplayChipSelectSettings(void) { int i; ushort type, size; ushort CSPAR0_, CSPAR1_, CSBASE_DATA, CSOPTION_DATA; ulong addr; ulong CSBASE_ADDR, CSOPTION_ADDR; CSPAR0_ = GetCPURegData(0xFFFA44); CSPAR1_ = GetCPURegData(0xFFFA46); printf("\n CS Pin Assignment Reg 0 = 0x%0.4X\n", CSPAR0_); printf(" CS Pin Assignment Reg 1 = 0x%0.4X\n", CSPAR1_); for(i = 0; i <= 5; i++){ type = (CSPAR0_ & (0x000C << i*2)) >> 2*(i+1); printf(" CS%02d Pin Assignment = %d\n", i, type); } for(i = 0; i <= 4; i++){ type = (CSPAR1_ & (0x0003 << i*2)) >> i*2; printf(" CS%02d Pin Assignment = %d\n", i+6, type); } CSBASE_ADDR = 0xFFFA4C; CSOPTION_ADDR = 0xFFFA4E; for(i = 0; i <= 10; i++){ CSBASE_DATA = GetCPURegData((CSBASE_ADDR + (ulong)(i*4))); CSOPTION_DATA = GetCPURegData((CSOPTION_ADDR + (ulong)(i*4))); addr = (ulong)(CSBASE_DATA & 0xFFF8) << 8; size = (CSBASE_DATA & 0x0007); printf(" CS%02d Base Addr = 0x%0.8lX, Block Size = %d and Option Values = 0x%0.4X\n", i, addr, size, CSOPTION_DATA); } }