#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h> //snprintf
-#if defined( _MSCVER_ )
+#if defined( _MSC_VER ) || defined(__MINGW32__)
# include <io.h> //lseek, read, write
#endif
SG_USING_STD(string);
-#ifdef _MSC_VER
-# define snprintf _snprintf
-#endif
-
// Lock the ATC 610 hardware
static int ATC610xLock( int fd ) {
// rewind
}
+// Turn a lamp on or off
+void ATC610xSetLamp( int fd, int channel, bool value ) {
+ // lamp channels 0-63 are written to LampPort0, channels 64-127
+ // are written to LampPort1
+
+ // bits 0-6 are the lamp address
+ // bit 7 is the value (on/off)
+
+ int result;
+
+ // Write the value
+ unsigned char buf[3];
+ buf[0] = channel;
+ buf[1] = value;
+ buf[2] = 0;
+ result = write( fd, buf, 2 );
+ if ( result != 2 ) {
+ SG_LOG( SG_IO, SG_ALERT, "Write failed" );
+ exit( -1 );
+ }
+}
+
+
// Open and initialize ATC 610x hardware
bool FGATC610x::open() {
if ( is_enabled() ) {
snprintf( lock_file, 256, "/proc/atc610x/board%d/lock", board );
snprintf( analog_in_file, 256, "/proc/atc610x/board%d/analog_in", board );
+ snprintf( lamps_file, 256, "/proc/atc610x/board%d/lamps", board );
snprintf( radios_file, 256, "/proc/atc610x/board%d/radios", board );
snprintf( stepper_file, 256, "/proc/atc610x/board%d/steppers", board );
snprintf( switches_file, 256, "/proc/atc610x/board%d/switches", board );
exit( -1 );
}
+ lamps_fd = ::open( lamps_file, O_WRONLY );
+ if ( lamps_fd == -1 ) {
+ SG_LOG( SG_IO, SG_ALERT, "errno = " << errno );
+ char msg[256];
+ snprintf( msg, 256, "Error opening %s", lamps_file );
+ perror( msg );
+ exit( -1 );
+ }
+
radios_fd = ::open( radios_file, O_RDWR );
if ( radios_fd == -1 ) {
SG_LOG( SG_IO, SG_ALERT, "errno = " << errno );
// Release the hardware
ATC610xRelease( lock_fd );
+ SG_LOG( SG_IO, SG_ALERT,
+ " - Waiting for compass to come home." );
+
bool home = false;
- while ( ! home ) {
- SG_LOG( SG_IO, SG_DEBUG, "Checking if compass home ..." );
+ int timeout = 900; // about 30 seconds
+ while ( ! home && timeout > 0 ) {
+ if ( timeout % 150 == 0 ) {
+ SG_LOG( SG_IO, SG_INFO, "waiting for compass = " << timeout );
+ } else {
+ SG_LOG( SG_IO, SG_DEBUG, "Checking if compass home ..." );
+ }
while ( ATC610xLock( lock_fd ) <= 0 );
ATC610xRelease( lock_fd );
-#if defined( _MSCVER_ )
+#if defined( _MSC_VER )
ulMilliSecondSleep(33);
+#elif defined (WIN32) && !defined(__CYGWIN__)
+ Sleep (33);
#else
usleep(33);
#endif
+
+ --timeout;
}
compass_position = 0.0;
ATC610xRelease( lock_fd );
+ /////////////////////////////////////////////////////////////////////
+ // Blank the lamps
+ /////////////////////////////////////////////////////////////////////
+
+ for ( int i = 0; i < 128; ++i ) {
+ ATC610xSetLamp( lamps_fd, i, false );
+ }
+
/////////////////////////////////////////////////////////////////////
// Finished initing hardware
/////////////////////////////////////////////////////////////////////
nav2_stby_freq
= fgGetNode( "/radios/nav[1]/frequencies/standby-mhz", true );
- adf_freq = fgGetNode( "/radios/adf/frequencies/selected-khz", true );
- adf_stby_freq = fgGetNode( "/radios/adf/frequencies/standby-khz", true );
+ adf_on_off_vol = fgGetNode( "/radios/kr-87/on-off-volume", true );
+ adf_adf_btn = fgGetNode( "/radios/kr-87/adf-btn", true );
+ adf_bfo_btn = fgGetNode( "/radios/kr-87/bfo-btn", true );
+ adf_freq = fgGetNode( "/radios/kr-87/frequencies/selected-khz", true );
+ adf_stby_freq = fgGetNode( "/radios/kr-87/frequencies/standby-khz", true );
+ adf_stby_mode = fgGetNode( "/radios/kr-87/stby-mode", true );
+ adf_timer_mode = fgGetNode( "/radios/kr-87/timer-mode", true );
+ adf_count_mode = fgGetNode( "/radios/kr-87/count-mode", true );
+ adf_flight_timer = fgGetNode( "/radios/kr-87/flight-timer", true );
+ adf_elapsed_timer = fgGetNode( "/radios/kr-87/elapsed-timer", true );
+
+ inner = fgGetNode( "/radios/marker-beacon/inner", true );
+ middle = fgGetNode( "/radios/marker-beacon/middle", true );
+ outer = fgGetNode( "/radios/marker-beacon/outer", true );
return true;
}
// adf volume
tmp = (float)analog_in_data[26] / 1024.0f;
- fgSetFloat( "/radios/adf/volume", tmp );
+ fgSetFloat( "/radios/kr-87/on-off-volume", tmp );
// nav2 obs tuner
tmp = (float)analog_in_data[29] * 360.0f / 1024.0f;
}
+/////////////////////////////////////////////////////////////////////
+// Write the lights
+/////////////////////////////////////////////////////////////////////
+
+bool FGATC610x::do_lights( double dt ) {
+
+ // Marker beacons
+ ATC610xSetLamp( lamps_fd, 4, inner->getBoolValue() );
+ ATC610xSetLamp( lamps_fd, 5, middle->getBoolValue() );
+ ATC610xSetLamp( lamps_fd, 3, outer->getBoolValue() );
+
+ // ADF annunciators
+ if ( adf_on_off_vol->getDoubleValue() >= 0.01 ) {
+ ATC610xSetLamp( lamps_fd, 11, !adf_adf_btn->getBoolValue() ); // ANT
+ ATC610xSetLamp( lamps_fd, 12, adf_adf_btn->getBoolValue() ); // ADF
+ ATC610xSetLamp( lamps_fd, 13, adf_bfo_btn->getBoolValue() ); // BFO
+ ATC610xSetLamp( lamps_fd, 14, !adf_stby_mode->getBoolValue() ); // FRQ
+ ATC610xSetLamp( lamps_fd, 15, adf_stby_mode->getBoolValue() &&
+ !adf_timer_mode->getBoolValue() ); // FLT
+
+ // ET needs to blink when we are in ET set countdown time
+ if ( adf_count_mode->getIntValue() < 2 ) {
+ ATC610xSetLamp( lamps_fd, 16, adf_stby_mode->getBoolValue() &&
+ adf_timer_mode->getBoolValue() ); // ET
+ } else {
+ et_flash_time += dt;
+ if ( et_flash && et_flash_time > 0.5 ) {
+ et_flash = false;
+ et_flash_time -= 0.5;
+ } else if ( !et_flash && et_flash_time > 0.2 ) {
+ et_flash = true;
+ et_flash_time -= 0.2;
+ }
+ ATC610xSetLamp( lamps_fd, 16, et_flash ); // ET
+ }
+ } else {
+ ATC610xSetLamp( lamps_fd, 11, false ); // ANT
+ ATC610xSetLamp( lamps_fd, 12, false ); // ADF
+ ATC610xSetLamp( lamps_fd, 13, false ); // BFO
+ ATC610xSetLamp( lamps_fd, 14, false ); // FRQ
+ ATC610xSetLamp( lamps_fd, 15, false ); // FLT
+ ATC610xSetLamp( lamps_fd, 16, false ); // ET
+ }
+
+ return true;
+}
+
+
/////////////////////////////////////////////////////////////////////
// Read radio switches
/////////////////////////////////////////////////////////////////////
bool FGATC610x::do_radio_switches() {
- float freq, inc;
+ double freq, coarse_freq, fine_freq, value;
+ int diff;
ATC610xReadRadios( radios_fd, radio_switch_data );
static int last_nav1_swap;
if ( nav1_swap && (last_nav1_swap != nav1_swap) ) {
float tmp = nav1_freq->getFloatValue();
- fgSetFloat( "/radios/nav[0]/frequencies/selected-mhz",
+ fgSetFloat( "/radios/nav[0]/freqencies/selected-mhz",
nav1_stby_freq->getFloatValue() );
fgSetFloat( "/radios/nav[0]/frequencies/standby-mhz", tmp );
}
last_nav2_swap = nav2_swap;
// Com1 Tuner
- int com1_tuner_fine = (radio_switch_data[5] >> 4) & 0x0f;
- int com1_tuner_course = radio_switch_data[5] & 0x0f;
- // cout << "com1 = " << com1_tuner_fine << " " << com1_tuner_course << endl;
+ int com1_tuner_fine = ((radio_switch_data[5] >> 4) & 0x0f) - 1;
+ int com1_tuner_coarse = (radio_switch_data[5] & 0x0f) - 1;
static int last_com1_tuner_fine = com1_tuner_fine;
- static int last_com1_tuner_course = com1_tuner_course;
- inc = 0.0;
+ static int last_com1_tuner_coarse = com1_tuner_coarse;
+
+ freq = com1_stby_freq->getFloatValue();
+ coarse_freq = (int)freq;
+ fine_freq = (int)((freq - coarse_freq) * 40 + 0.5);
+
if ( com1_tuner_fine != last_com1_tuner_fine ) {
- if ( com1_tuner_fine == 0x0c && last_com1_tuner_fine == 0x01 ) {
- inc = -0.025;
- } else if ( com1_tuner_fine == 0x01 && last_com1_tuner_fine == 0x0c ) {
- inc = -0.025;
- } else if ( com1_tuner_fine > last_com1_tuner_fine ) {
- inc = 0.025;
- } else {
- inc = -0.025;
- }
- }
- if ( com1_tuner_course != last_com1_tuner_course ) {
- if ( com1_tuner_course == 0x0c && last_com1_tuner_course == 0x01 ) {
- inc = -1.0;
- } else if ( com1_tuner_course == 0x01
- && last_com1_tuner_course == 0x0c ) {
- inc = -1.0;
- } else if ( com1_tuner_course > last_com1_tuner_course ) {
- inc = 1.0;
- } else {
- inc = -1.0;
- }
- }
+ diff = com1_tuner_fine - last_com1_tuner_fine;
+ if ( abs(diff) > 4 ) {
+ // roll over
+ if ( com1_tuner_fine < last_com1_tuner_fine ) {
+ // going up
+ diff = 12 - last_com1_tuner_fine + com1_tuner_fine;
+ } else {
+ // going down
+ diff = com1_tuner_fine - 12 - last_com1_tuner_fine;
+ }
+ }
+ fine_freq += diff;
+ }
+ while ( fine_freq >= 40.0 ) { fine_freq -= 40.0; }
+ while ( fine_freq < 0.0 ) { fine_freq += 40.0; }
+
+ if ( com1_tuner_coarse != last_com1_tuner_coarse ) {
+ diff = com1_tuner_coarse - last_com1_tuner_coarse;
+ if ( abs(diff) > 4 ) {
+ // roll over
+ if ( com1_tuner_coarse < last_com1_tuner_coarse ) {
+ // going up
+ diff = 12 - last_com1_tuner_coarse + com1_tuner_coarse;
+ } else {
+ // going down
+ diff = com1_tuner_coarse - 12 - last_com1_tuner_coarse;
+ }
+ }
+ coarse_freq += diff;
+ }
+ if ( coarse_freq < 118.0 ) { coarse_freq += 19.0; }
+ if ( coarse_freq > 136.0 ) { coarse_freq -= 19.0; }
+
last_com1_tuner_fine = com1_tuner_fine;
- last_com1_tuner_course = com1_tuner_course;
+ last_com1_tuner_coarse = com1_tuner_coarse;
- freq = com1_stby_freq->getFloatValue() + inc;
- if ( freq < 0.0 ) {
- freq = 140.0;
- }
- if ( freq > 140.0 ) {
- freq = 0.0;
- }
- fgSetFloat( "/radios/comm[0]/frequencies/standby-mhz", freq );
+ fgSetFloat( "/radios/comm[0]/frequencies/standby-mhz",
+ coarse_freq + fine_freq / 40.0 );
// Com2 Tuner
- int com2_tuner_fine = (radio_switch_data[13] >> 4) & 0x0f;
- int com2_tuner_course = radio_switch_data[13] & 0x0f;
+ int com2_tuner_fine = ((radio_switch_data[13] >> 4) & 0x0f) - 1;
+ int com2_tuner_coarse = (radio_switch_data[13] & 0x0f) - 1;
static int last_com2_tuner_fine = com2_tuner_fine;
- static int last_com2_tuner_course = com2_tuner_course;
- inc = 0.0;
+ static int last_com2_tuner_coarse = com2_tuner_coarse;
+
+ freq = com2_stby_freq->getFloatValue();
+ coarse_freq = (int)freq;
+ fine_freq = (int)((freq - coarse_freq) * 40 + 0.5);
+
if ( com2_tuner_fine != last_com2_tuner_fine ) {
- if ( com2_tuner_fine == 0x0c && last_com2_tuner_fine == 0x01 ) {
- inc = -0.025;
- } else if ( com2_tuner_fine == 0x01 && last_com2_tuner_fine == 0x0c ) {
- inc = -0.025;
- } else if ( com2_tuner_fine > last_com2_tuner_fine ) {
- inc = 0.025;
- } else {
- inc = -0.025;
- }
- }
- if ( com2_tuner_course != last_com2_tuner_course ) {
- if ( com2_tuner_course == 0x0c && last_com2_tuner_course == 0x01 ) {
- inc = -1.0;
- } else if ( com2_tuner_course == 0x01
- && last_com2_tuner_course == 0x0c ) {
- inc = -1.0;
- } else if ( com2_tuner_course > last_com2_tuner_course ) {
- inc = 1.0;
- } else {
- inc = -1.0;
- }
- }
+ diff = com2_tuner_fine - last_com2_tuner_fine;
+ if ( abs(diff) > 4 ) {
+ // roll over
+ if ( com2_tuner_fine < last_com2_tuner_fine ) {
+ // going up
+ diff = 12 - last_com2_tuner_fine + com2_tuner_fine;
+ } else {
+ // going down
+ diff = com2_tuner_fine - 12 - last_com2_tuner_fine;
+ }
+ }
+ fine_freq += diff;
+ }
+ while ( fine_freq >= 40.0 ) { fine_freq -= 40.0; }
+ while ( fine_freq < 0.0 ) { fine_freq += 40.0; }
+
+ if ( com2_tuner_coarse != last_com2_tuner_coarse ) {
+ diff = com2_tuner_coarse - last_com2_tuner_coarse;
+ if ( abs(diff) > 4 ) {
+ // roll over
+ if ( com2_tuner_coarse < last_com2_tuner_coarse ) {
+ // going up
+ diff = 12 - last_com2_tuner_coarse + com2_tuner_coarse;
+ } else {
+ // going down
+ diff = com2_tuner_coarse - 12 - last_com2_tuner_coarse;
+ }
+ }
+ coarse_freq += diff;
+ }
+ if ( coarse_freq < 118.0 ) { coarse_freq += 19.0; }
+ if ( coarse_freq > 136.0 ) { coarse_freq -= 19.0; }
+
last_com2_tuner_fine = com2_tuner_fine;
- last_com2_tuner_course = com2_tuner_course;
+ last_com2_tuner_coarse = com2_tuner_coarse;
- freq = com2_stby_freq->getFloatValue() + inc;
- if ( freq < 0.0 ) {
- freq = 140.0;
- }
- if ( freq > 140.0 ) {
- freq = 0.0;
- }
- fgSetFloat( "/radios/comm[1]/frequencies/standby-mhz", freq );
+ fgSetFloat( "/radios/comm[1]/frequencies/standby-mhz",
+ coarse_freq + fine_freq / 40.0 );
// Nav1 Tuner
- int nav1_tuner_fine = (radio_switch_data[9] >> 4) & 0x0f;
- int nav1_tuner_course = radio_switch_data[9] & 0x0f;
+ int nav1_tuner_fine = ((radio_switch_data[9] >> 4) & 0x0f) - 1;
+ int nav1_tuner_coarse = (radio_switch_data[9] & 0x0f) - 1;
static int last_nav1_tuner_fine = nav1_tuner_fine;
- static int last_nav1_tuner_course = nav1_tuner_course;
- inc = 0.0;
+ static int last_nav1_tuner_coarse = nav1_tuner_coarse;
+
+ freq = nav1_stby_freq->getFloatValue();
+ coarse_freq = (int)freq;
+ fine_freq = (int)((freq - coarse_freq) * 20 + 0.5);
+
if ( nav1_tuner_fine != last_nav1_tuner_fine ) {
- if ( nav1_tuner_fine == 0x0c && last_nav1_tuner_fine == 0x01 ) {
- inc = -0.05;
- } else if ( nav1_tuner_fine == 0x01 && last_nav1_tuner_fine == 0x0c ) {
- inc = -0.05;
- } else if ( nav1_tuner_fine > last_nav1_tuner_fine ) {
- inc = 0.05;
- } else {
- inc = -0.05;
- }
- }
- if ( nav1_tuner_course != last_nav1_tuner_course ) {
- if ( nav1_tuner_course == 0x0c && last_nav1_tuner_course == 0x01 ) {
- inc = -1.0;
- } else if ( nav1_tuner_course == 0x01
- && last_nav1_tuner_course == 0x0c ) {
- inc = -1.0;
- } else if ( nav1_tuner_course > last_nav1_tuner_course ) {
- inc = 1.0;
- } else {
- inc = -1.0;
- }
- }
+ diff = nav1_tuner_fine - last_nav1_tuner_fine;
+ if ( abs(diff) > 4 ) {
+ // roll over
+ if ( nav1_tuner_fine < last_nav1_tuner_fine ) {
+ // going up
+ diff = 12 - last_nav1_tuner_fine + nav1_tuner_fine;
+ } else {
+ // going down
+ diff = nav1_tuner_fine - 12 - last_nav1_tuner_fine;
+ }
+ }
+ fine_freq += diff;
+ }
+ while ( fine_freq >= 20.0 ) { fine_freq -= 20.0; }
+ while ( fine_freq < 0.0 ) { fine_freq += 20.0; }
+
+ if ( nav1_tuner_coarse != last_nav1_tuner_coarse ) {
+ diff = nav1_tuner_coarse - last_nav1_tuner_coarse;
+ if ( abs(diff) > 4 ) {
+ // roll over
+ if ( nav1_tuner_coarse < last_nav1_tuner_coarse ) {
+ // going up
+ diff = 12 - last_nav1_tuner_coarse + nav1_tuner_coarse;
+ } else {
+ // going down
+ diff = nav1_tuner_coarse - 12 - last_nav1_tuner_coarse;
+ }
+ }
+ coarse_freq += diff;
+ }
+ if ( coarse_freq < 108.0 ) { coarse_freq += 10.0; }
+ if ( coarse_freq > 117.0 ) { coarse_freq -= 10.0; }
+
last_nav1_tuner_fine = nav1_tuner_fine;
- last_nav1_tuner_course = nav1_tuner_course;
+ last_nav1_tuner_coarse = nav1_tuner_coarse;
- freq = nav1_stby_freq->getFloatValue() + inc;
- if ( freq < 108.0 ) {
- freq = 117.95;
- }
- if ( freq > 117.95 ) {
- freq = 108.0;
- }
- fgSetFloat( "/radios/nav[0]/frequencies/standby-mhz", freq );
+ fgSetFloat( "/radios/nav[0]/frequencies/standby-mhz",
+ coarse_freq + fine_freq / 20.0 );
// Nav2 Tuner
- int nav2_tuner_fine = (radio_switch_data[17] >> 4) & 0x0f;
- int nav2_tuner_course = radio_switch_data[17] & 0x0f;
+ int nav2_tuner_fine = ((radio_switch_data[17] >> 4) & 0x0f) - 1;
+ int nav2_tuner_coarse = (radio_switch_data[17] & 0x0f) - 1;
static int last_nav2_tuner_fine = nav2_tuner_fine;
- static int last_nav2_tuner_course = nav2_tuner_course;
- inc = 0.0;
+ static int last_nav2_tuner_coarse = nav2_tuner_coarse;
+
+ freq = nav2_stby_freq->getFloatValue();
+ coarse_freq = (int)freq;
+ fine_freq = (int)((freq - coarse_freq) * 20 + 0.5);
+
if ( nav2_tuner_fine != last_nav2_tuner_fine ) {
- if ( nav2_tuner_fine == 0x0c && last_nav2_tuner_fine == 0x01 ) {
- inc = -0.05;
- } else if ( nav2_tuner_fine == 0x01 && last_nav2_tuner_fine == 0x0c ) {
- inc = -0.05;
- } else if ( nav2_tuner_fine > last_nav2_tuner_fine ) {
- inc = 0.05;
- } else {
- inc = -0.05;
- }
- }
- if ( nav2_tuner_course != last_nav2_tuner_course ) {
- if ( nav2_tuner_course == 0x0c && last_nav2_tuner_course == 0x01 ) {
- inc = -1.0;
- } else if ( nav2_tuner_course == 0x01
- && last_nav2_tuner_course == 0x0c ) {
- inc = -1.0;
- } else if ( nav2_tuner_course > last_nav2_tuner_course ) {
- inc = 1.0;
- } else {
- inc = -1.0;
- }
- }
+ diff = nav2_tuner_fine - last_nav2_tuner_fine;
+ if ( abs(diff) > 4 ) {
+ // roll over
+ if ( nav2_tuner_fine < last_nav2_tuner_fine ) {
+ // going up
+ diff = 12 - last_nav2_tuner_fine + nav2_tuner_fine;
+ } else {
+ // going down
+ diff = nav2_tuner_fine - 12 - last_nav2_tuner_fine;
+ }
+ }
+ fine_freq += diff;
+ }
+ while ( fine_freq >= 20.0 ) { fine_freq -= 20.0; }
+ while ( fine_freq < 0.0 ) { fine_freq += 20.0; }
+
+ if ( nav2_tuner_coarse != last_nav2_tuner_coarse ) {
+ diff = nav2_tuner_coarse - last_nav2_tuner_coarse;
+ if ( abs(diff) > 4 ) {
+ // roll over
+ if ( nav2_tuner_coarse < last_nav2_tuner_coarse ) {
+ // going up
+ diff = 12 - last_nav2_tuner_coarse + nav2_tuner_coarse;
+ } else {
+ // going down
+ diff = nav2_tuner_coarse - 12 - last_nav2_tuner_coarse;
+ }
+ }
+ coarse_freq += diff;
+ }
+ if ( coarse_freq < 108.0 ) { coarse_freq += 10.0; }
+ if ( coarse_freq > 117.0 ) { coarse_freq -= 10.0; }
+
last_nav2_tuner_fine = nav2_tuner_fine;
- last_nav2_tuner_course = nav2_tuner_course;
+ last_nav2_tuner_coarse = nav2_tuner_coarse;
- freq = nav2_stby_freq->getFloatValue() + inc;
- if ( freq < 108.0 ) {
- freq = 117.95;
- }
- if ( freq > 117.95 ) {
- freq = 108.0;
- }
- fgSetFloat( "/radios/nav[1]/frequencies/standby-mhz", freq );
+ fgSetFloat( "/radios/nav[1]/frequencies/standby-mhz",
+ coarse_freq + fine_freq / 20.0);
// ADF Tuner
- int adf_tuner_fine = (radio_switch_data[21] >> 4) & 0x0f;
- int adf_tuner_course = radio_switch_data[21] & 0x0f;
- // cout << "adf = " << adf_tuner_fine << " " << adf_tuner_course << endl;
+ int adf_tuner_fine = ((radio_switch_data[21] >> 4) & 0x0f) - 1;
+ int adf_tuner_coarse = (radio_switch_data[21] & 0x0f) - 1;
static int last_adf_tuner_fine = adf_tuner_fine;
- static int last_adf_tuner_course = adf_tuner_course;
- inc = 0.0;
- if ( adf_tuner_fine != last_adf_tuner_fine ) {
- if ( adf_tuner_fine == 0x0c && last_adf_tuner_fine == 0x01 ) {
- inc = -1.0;
- } else if ( adf_tuner_fine == 0x01 && last_adf_tuner_fine == 0x0c ) {
- inc = -1.0;
- } else if ( adf_tuner_fine > last_adf_tuner_fine ) {
- inc = 1.0;
- } else {
- inc = -1.0;
- }
+ static int last_adf_tuner_coarse = adf_tuner_coarse;
+
+ if ( adf_count_mode->getIntValue() == 2 ) {
+ // tune count down timer
+ value = adf_elapsed_timer->getDoubleValue();
+ } else {
+ // tune frequency
+ if ( adf_stby_mode->getIntValue() == 1 ) {
+ value = adf_freq->getFloatValue();
+ } else {
+ value = adf_stby_freq->getFloatValue();
+ }
}
- if ( adf_tuner_course != last_adf_tuner_course ) {
- if ( adf_tuner_course == 0x0c && last_adf_tuner_course == 0x01 ) {
- inc = -25.0;
- } else if ( adf_tuner_course == 0x01
- && last_adf_tuner_course == 0x0c ) {
- inc = -25.0;
- } else if ( adf_tuner_course > last_adf_tuner_course ) {
- inc = 25.0;
- } else {
- inc = -25.0;
- }
+
+ if ( adf_tuner_fine != last_adf_tuner_fine ) {
+ diff = adf_tuner_fine - last_adf_tuner_fine;
+ if ( abs(diff) > 4 ) {
+ // roll over
+ if ( adf_tuner_fine < last_adf_tuner_fine ) {
+ // going up
+ diff = 12 - last_adf_tuner_fine + adf_tuner_fine;
+ } else {
+ // going down
+ diff = adf_tuner_fine - 12 - last_adf_tuner_fine;
+ }
+ }
+ value += diff;
+ }
+
+ if ( adf_tuner_coarse != last_adf_tuner_coarse ) {
+ diff = adf_tuner_coarse - last_adf_tuner_coarse;
+ if ( abs(diff) > 4 ) {
+ // roll over
+ if ( adf_tuner_coarse < last_adf_tuner_coarse ) {
+ // going up
+ diff = 12 - last_adf_tuner_coarse + adf_tuner_coarse;
+ } else {
+ // going down
+ diff = adf_tuner_coarse - 12 - last_adf_tuner_coarse;
+ }
+ }
+ if ( adf_count_mode->getIntValue() == 2 ) {
+ value += 60 * diff;
+ } else {
+ value += 25 * diff;
+ }
+ }
+ if ( adf_count_mode->getIntValue() == 2 ) {
+ if ( value < 0 ) { value += 3600; }
+ if ( value > 3599 ) { value -= 3600; }
+ } else {
+ if ( value < 200 ) { value += 1600; }
+ if ( value > 1799 ) { value -= 1600; }
}
+
last_adf_tuner_fine = adf_tuner_fine;
- last_adf_tuner_course = adf_tuner_course;
+ last_adf_tuner_coarse = adf_tuner_coarse;
- freq = adf_freq->getFloatValue() + inc;
- if ( freq < 100.0 ) {
- freq = 1299;
- }
- if ( freq > 1299 ) {
- freq = 100.0;
- }
- fgSetFloat( "/radios/adf/frequencies/selected-khz", freq );
+ if ( adf_count_mode->getIntValue() == 2 ) {
+ fgSetFloat( "/radios/kr-87/elapsed-timer", value );
+ } else {
+ if ( adf_stby_mode->getIntValue() == 1 ) {
+ fgSetFloat( "/radios/kr-87/frequencies/selected-khz", value );
+ } else {
+ fgSetFloat( "/radios/kr-87/frequencies/standby-khz", value );
+ }
+ }
+
+ // ADF Modes
+ fgSetInt( "/radios/kr-87/adf-btn", !(radio_switch_data[23] & 0x01) );
+ fgSetInt( "/radios/kr-87/bfo-btn", !(radio_switch_data[23] >> 1 & 0x01) );
+ fgSetInt( "/radios/kr-87/frq-btn", !(radio_switch_data[23] >> 2 & 0x01) );
+ fgSetInt( "/radios/kr-87/flt-et-btn", !(radio_switch_data[23] >> 3 & 0x01) );
+ fgSetInt( "/radios/kr-87/set-rst-btn", !(radio_switch_data[23] >> 4 & 0x01) );
+ /* cout << "adf = " << !(radio_switch_data[23] & 0x01)
+ << " bfo = " << !(radio_switch_data[23] >> 1 & 0x01)
+ << " stby = " << !(radio_switch_data[23] >> 2 & 0x01)
+ << " timer = " << !(radio_switch_data[23] >> 3 & 0x01)
+ << " set/rst = " << !(radio_switch_data[23] >> 4 & 0x01)
+ << endl; */
return true;
}
// the 0x00 in the upper nibble of the 6th byte of each display
// turns on the decimal point
- // ADF standby frequency
- float adf_stby = adf_stby_freq->getFloatValue();
- if ( fabs(adf_stby) > 999.99 ) {
- adf_stby = 0.0;
- }
- sprintf(digits, "%03.0f", adf_stby);
- for ( i = 0; i < 6; ++i ) {
- digits[i] -= '0';
- }
- radio_display_data[30] = digits[2] << 4 | 0x0f;
- radio_display_data[31] = digits[0] << 4 | digits[1];
-
- // ADF in use frequency
- float adf = adf_freq->getFloatValue();
- if ( fabs(adf) > 999.99 ) {
- adf = 0.0;
- }
- sprintf(digits, "%03.0f", adf);
- for ( i = 0; i < 6; ++i ) {
- digits[i] -= '0';
+ // ADF standby frequency / timer
+ if ( adf_on_off_vol->getDoubleValue() >= 0.01 ) {
+ if ( adf_stby_mode->getIntValue() == 0 ) {
+ // frequency
+ float adf_stby = adf_stby_freq->getFloatValue();
+ if ( fabs(adf_stby) > 1799 ) {
+ adf_stby = 1799;
+ }
+ sprintf(digits, "%04.0f", adf_stby);
+ for ( i = 0; i < 6; ++i ) {
+ digits[i] -= '0';
+ }
+ radio_display_data[30] = digits[3] << 4 | 0x0f;
+ radio_display_data[31] = digits[1] << 4 | digits[2];
+ if ( digits[0] == 0 ) {
+ radio_display_data[32] = 0xff;
+ } else {
+ radio_display_data[32] = 0xf0 | digits[0];
+ }
+ } else {
+ // timer
+ double time;
+ int hours, min, sec;
+ if ( adf_timer_mode->getIntValue() == 0 ) {
+ time = adf_flight_timer->getDoubleValue();
+ } else {
+ time = adf_elapsed_timer->getDoubleValue();
+ }
+ // cout << time << endl;
+ hours = (int)(time / 3600.0);
+ time -= hours * 3600.00;
+ min = (int)(time / 60.0);
+ time -= min * 60.0;
+ sec = (int)time;
+ int big, small;
+ if ( hours > 0 ) {
+ big = hours;
+ if ( big > 99 ) {
+ big = 99;
+ }
+ small = min;
+ } else {
+ big = min;
+ small = sec;
+ }
+ if ( big > 99 ) {
+ big = 99;
+ }
+ // cout << big << ":" << small << endl;
+ sprintf(digits, "%02d%02d", big, small);
+ for ( i = 0; i < 6; ++i ) {
+ digits[i] -= '0';
+ }
+ radio_display_data[30] = digits[3] << 4 | 0x0f;
+ radio_display_data[31] = digits[1] << 4 | digits[2];
+ radio_display_data[32] = 0xf0 | digits[0];
+ }
+
+ // ADF in use frequency
+ float adf = adf_freq->getFloatValue();
+ if ( fabs(adf) > 1799 ) {
+ adf = 1799;
+ }
+ sprintf(digits, "%04.0f", adf);
+ for ( i = 0; i < 6; ++i ) {
+ digits[i] -= '0';
+ }
+ radio_display_data[33] = digits[2] << 4 | digits[3];
+ if ( digits[0] == 0 ) {
+ radio_display_data[34] = 0xf0 | digits[1];
+ } else {
+ radio_display_data[34] = digits[0] << 4 | digits[1];
+ }
+ } else {
+ radio_display_data[30] = 0xff;
+ radio_display_data[31] = 0xff;
+ radio_display_data[32] = 0xff;
+ radio_display_data[33] = 0xff;
+ radio_display_data[34] = 0xff;
}
- radio_display_data[33] = digits[1] << 4 | digits[2];
- radio_display_data[34] = 0xf0 | digits[0];
+
ATC610xSetRadios( radios_fd, radio_display_data );
update_switch_matrix( board, switch_data, switch_matrix );
// magnetos and starter switch
+ int magnetos = 0;
+ bool starter = false;
if ( switch_matrix[board][3][1] == 1 ) {
- fgSetInt( "/controls/magnetos[0]", 3 );
- fgSetBool( "/controls/starter[0]", true );
+ magnetos = 3;
+ starter = true;
} else if ( switch_matrix[board][2][1] == 1 ) {
- fgSetInt( "/controls/magnetos[0]", 3 );
- fgSetBool( "/controls/starter[0]", false );
+ magnetos = 3;
+ starter = false;
} else if ( switch_matrix[board][1][1] == 1 ) {
- fgSetInt( "/controls/magnetos[0]", 2 );
- fgSetBool( "/controls/starter[0]", false );
+ magnetos = 2;
+ starter = false;
} else if ( switch_matrix[board][0][1] == 1 ) {
- fgSetInt( "/controls/magnetos[0]", 1 );
- fgSetBool( "/controls/starter[0]", false );
+ magnetos = 1;
+ starter = false;
} else {
- fgSetInt( "/controls/magnetos[0]", 0 );
- fgSetBool( "/controls/starter[0]", false );
+ magnetos = 0;
+ starter = false;
}
// flaps
+ float flaps = 0.0;
if ( switch_matrix[board][6][3] == 1 ) {
- fgSetFloat( "/controls/flaps", 1.0 );
+ flaps = 1.0;
} else if ( switch_matrix[board][5][3] == 1 ) {
- fgSetFloat( "/controls/flaps", 0.66 );
+ flaps = 2.0 / 3.0;
} else if ( switch_matrix[board][4][3] == 1 ) {
- fgSetFloat( "/controls/flaps", 0.33 );
+ flaps = 1.0 / 3.0;
} else if ( switch_matrix[board][4][3] == 0 ) {
- fgSetFloat( "/controls/flaps", 0.0 );
+ flaps = 0.0;
+ }
+
+ // do a bit of filtering on the magneto/starter switch and the
+ // flap lever because these are not well debounced in hardware
+ static int mag1, mag2, mag3;
+ mag3 = mag2;
+ mag2 = mag1;
+ mag1 = magnetos;
+ if ( mag1 == mag2 && mag2 == mag3 ) {
+ fgSetInt( "/controls/magnetos[0]", magnetos );
+ }
+
+ static bool start1, start2, start3;
+ start3 = start2;
+ start2 = start1;
+ start1 = starter;
+ if ( start1 == start2 && start2 == start3 ) {
+ fgSetBool( "/controls/starter[0]", starter );
+ }
+
+ static float flap1, flap2, flap3;
+ flap3 = flap2;
+ flap2 = flap1;
+ flap1 = flaps;
+ if ( flap1 == flap2 && flap2 == flap3 ) {
+ fgSetFloat( "/controls/flaps", flaps );
}
return true;
bool FGATC610x::process() {
+ SGTimeStamp current;
+ current.stamp();
+
+ double dt = (double)(current - last_time_stamp) / 1000000;
+ last_time_stamp.stamp();
// Lock the hardware, skip if it's not ready yet
if ( ATC610xLock( lock_fd ) > 0 ) {
do_analog_in();
+ do_lights( dt );
do_radio_switches();
do_radio_display();
do_steppers();