/* fixed-length 48-byte records */ #define PWSA_RECSIZE 48 /* utility macros (use these to generate access macros, not directly in code) * p is a buffer pointer of any type (pointing to the beginning of the record) * i and j are high-order and low-order (respectively) byte offsets */ #define xINT1(p,i) ( (int)((unsigned char *)(p))[i] ) #define xINT2(p,i,j) ( xINT1(p,i) << 8 | xINT1(p,j) ) /* extract fields given a pointer to a record (assumes ints >= 32-bits) * y1900 - years past 1900 (2001 = 101) * hoy - hour of year beginning with 24 (so hoy / 24 = day of year) * soh - second of hour * msec - millisecond of second * mod16 - FDS SCLK modulo 65536 (2**16) counter * mod60 - FDS SCLK modulo 60 counter (increments every 48 seconds) * line - FDS SCLK line counter (1-800) * mode - telemetry mode * sc - 1 for VG1 and 2 for VG2 (note arrays indexed with sc-1 ) */ #define PWSA_y1900(p) xINT2(p,1,0) #define PWSA_hoy(p) xINT2(p,3,2) #define PWSA_soh(p) xINT2(p,5,4) #define PWSA_msec(p) xINT2(p,7,6) #define PWSA_mod16(p) xINT2(p,9,8) #define PWSA_mod60(p) xINT2(p,11,10) #define PWSA_line(p) xINT2(p,13,12) #define PWSA_mode(p) xINT1(p,14) #define PWSA_sc(p) xINT1(p,15) /* PWSA_dn(p,c) returns data number bits as stored in the cd format given a * pointer to a record "p" and a channel number "c" (0-15). Note that * corrections must still be made for CR5A/UV5A 10-bit sums and for negative * values. For 10-bit sums, simply divide the data number by 4.0. * Some GS3 are tagged negative (for interference), but PWSA_dn will only * return the least significant 16-bits of this. After "idn = PWSA_dn(p,c);" * one might use "if (idn & 0x8000) idn = 0;" to ignore these or else * "if (idn & 0x8000) idn |= 0xFFFF0000;" to sign extend for a 32-bit * negative value. */ #define PWSA_dn(p,c) xINT2(p,((c)<<1)+17,((c)<<1)+16) /* more convenient derived time components */ #define PWSA_year(p) ( PWSA_y1900(p) + 1900 ) #define PWSA_day(p) ( PWSA_hoy(p) / 24 ) #define PWSA_hour(p) ( PWSA_hoy(p) % 24 ) #define PWSA_minute(p) ( PWSA_soh(p) / 60 ) #define PWSA_sec(p) ( PWSA_soh(p) % 60 ) #define PWSA_msod(p) ( PWSA_msec(p)+PWSA_soh(p)*1000+PWSA_hour(p)*3600000 ) /* valid telemetry modes */ #define CR2 0x01 #define CR3 0x02 #define CR4 0x03 #define CR5 0x04 #define CR6 0x05 #define CR1 0x07 #define GS10A 0x08 #define GS3 0x0A #define GS7 0x0C #define GS6 0x0E #define OC2 0x16 #define OC1 0x17 #define CR5A 0x18 #define GS10 0x19 #define GS8 0x1A #define UV5A 0x1D static const char *TLM_mode_name[32] = { "ENG0","CR2","CR3","CR4","CR5","CR6","CR7","CR1", "GS10A","0x09","GS3","0x0B","GS7","0x0D","GS6","GS4", "0x10","GS2","0x12","0x13","0x14","0x15","OC2","OC1", "CR5A","GS10","GS8","0x1B","0x1C","UV5A","0x1E","0x1F" }; /* channel frequencies in Hz (indexed 0 - 15) */ static const double PWSA_freq[16] = { 10.0, 17.8, 31.1, 56.2, 100.0, 178.0, 311.0, 562.0, 1000.0, 1780.0, 3110.0, 5620.0, 10000.0, 17800.0, 31100.0, 56200.0 }; /* channel bandwidths in Hz, indexed by sc (0 - 1) and channel (0 - 15) */ static const double PWSA_bw[2][16] = { { 2.99, 3.77, 7.50,10.06, 13.3, 29.8, 59.5, 106., 133., 211., 298., 421., 943., 2110., 4210., 5950. }, { 2.16, 3.58, 4.50, 10.7, 13.8, 28.8, 39.8, 75.9, 75.9, 151., 324., 513., 832., 1260., 2400., 3800. } }; /* effective electrical length of antenna in meters */ #define PWS_elength 7.07