X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FNetwork%2FATC-Outputs.cxx;h=97a8df77169a19635f56fcebec117f52d3178f4e;hb=8a089f6d6f9e7851e73fd118cb9a5f5583cfe517;hp=29ae37f05239bf3cab35017fbadf1269aad55386;hpb=8e9f8674a64233e98c6f630bc129a6ced0a6a357;p=flightgear.git diff --git a/src/Network/ATC-Outputs.cxx b/src/Network/ATC-Outputs.cxx index 29ae37f05..97a8df771 100644 --- a/src/Network/ATC-Outputs.cxx +++ b/src/Network/ATC-Outputs.cxx @@ -16,7 +16,7 @@ // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // // $Id$ @@ -31,22 +31,30 @@ # include # include # include +# include +# include #endif -#include STL_STRING +#include +#include + +#include #include +#include +#include #include
#include "ATC-Outputs.hxx" -SG_USING_STD(string); +using std::string; // Lock the ATC hardware static int ATCLock( int fd ) { +#if defined( unix ) || defined( __CYGWIN__ ) // rewind lseek( fd, 0, SEEK_SET ); @@ -57,11 +65,15 @@ static int ATCLock( int fd ) { } return result; +#else + return -1; +#endif } // Release the ATC hardware static int ATCRelease( int fd ) { +#if defined( unix ) || defined( __CYGWIN__ ) // rewind lseek( fd, 0, SEEK_SET ); @@ -74,6 +86,9 @@ static int ATCRelease( int fd ) { } return result; +#else + return -1; +#endif } @@ -82,6 +97,7 @@ static int ATCRelease( int fd ) { // specifies the location of the output config file (xml) FGATCOutput::FGATCOutput( const int _board, const SGPath &_config_file ) : is_open(false), + analog_out_node(NULL), lamps_out_node(NULL), radio_display_node(NULL), steppers_node(NULL) @@ -91,8 +107,30 @@ FGATCOutput::FGATCOutput( const int _board, const SGPath &_config_file ) : } +// Write analog out data +static int ATCSetAnalogOut( int fd, + unsigned char data[ATC_ANALOG_OUT_CHANNELS*2] ) +{ +#if defined( unix ) || defined( __CYGWIN__ ) + // rewind + lseek( fd, 0, SEEK_SET ); + + int result = write( fd, data, ATC_ANALOG_OUT_CHANNELS*2 ); + + if ( result != ATC_ANALOG_OUT_CHANNELS*2 ) { + SG_LOG( SG_IO, SG_DEBUG, "Write failed" ); + } + + return result; +#else + return -1; +#endif +} + + // Write a radios command static int ATCSetRadios( int fd, unsigned char data[ATC_RADIO_DISPLAY_BYTES] ) { +#if defined( unix ) || defined( __CYGWIN__ ) // rewind lseek( fd, 0, SEEK_SET ); @@ -103,6 +141,9 @@ static int ATCSetRadios( int fd, unsigned char data[ATC_RADIO_DISPLAY_BYTES] ) { } return result; +#else + return -1; +#endif } @@ -110,6 +151,7 @@ static int ATCSetRadios( int fd, unsigned char data[ATC_RADIO_DISPLAY_BYTES] ) { static int ATCSetStepper( int fd, unsigned char channel, unsigned char value ) { +#if defined( unix ) || defined( __CYGWIN__ ) // rewind lseek( fd, 0, SEEK_SET ); @@ -125,11 +167,16 @@ static int ATCSetStepper( int fd, unsigned char channel, SG_LOG( SG_IO, SG_DEBUG, "Sent cmd = " << (int)channel << " value = " << (int)value ); return result; +#else + return -1; +#endif } +#ifdef ATCFLIGHTSIM_HAVE_COMPASS // Read status of last stepper written to static unsigned char ATCReadStepper( int fd ) { +#if defined( unix ) || defined( __CYGWIN__ ) int result; // rewind @@ -145,11 +192,16 @@ static unsigned char ATCReadStepper( int fd ) { SG_LOG( SG_IO, SG_DEBUG, "Read result = " << (int)buf[0] ); return buf[0]; +#else + return 0; +#endif } +#endif // Turn a lamp on or off void ATCSetLamp( int fd, int channel, bool value ) { +#if defined( unix ) || defined( __CYGWIN__ ) // lamp channels 0-63 are written to LampPort0, channels 64-127 // are written to LampPort1 @@ -168,6 +220,7 @@ void ATCSetLamp( int fd, int channel, bool value ) { SG_LOG( SG_IO, SG_ALERT, "Write failed" ); exit( -1 ); } +#endif } @@ -203,6 +256,8 @@ bool FGATCOutput::open( int lock_fd ) { SG_LOG( SG_IO, SG_ALERT, "Initializing ATC output hardware, please wait ..." ); + snprintf( analog_out_file, 256, + "/proc/atcflightsim/board%d/analog_out", board ); snprintf( lamps_file, 256, "/proc/atcflightsim/board%d/lamps", board ); snprintf( radio_display_file, 256, @@ -216,6 +271,15 @@ bool FGATCOutput::open( int lock_fd ) { // Open the /proc files ///////////////////////////////////////////////////////////////////// + analog_out_fd = ::open( analog_out_file, O_WRONLY ); + if ( analog_out_fd == -1 ) { + SG_LOG( SG_IO, SG_ALERT, "errno = " << errno ); + char msg[256]; + snprintf( msg, 256, "Error opening %s", analog_out_file ); + perror( msg ); + exit( -1 ); + } + lamps_fd = ::open( lamps_file, O_WRONLY ); if ( lamps_fd == -1 ) { SG_LOG( SG_IO, SG_ALERT, "errno = " << errno ); @@ -245,6 +309,7 @@ bool FGATCOutput::open( int lock_fd ) { #endif +#ifdef ATCFLIGHTSIM_HAVE_COMPASS ///////////////////////////////////////////////////////////////////// // Home the compass stepper motor ///////////////////////////////////////////////////////////////////// @@ -283,9 +348,7 @@ bool FGATCOutput::open( int lock_fd ) { ATCRelease( lock_fd ); -#if defined( _MSC_VER ) - ulMilliSecondSleep(33); -#elif defined (WIN32) && !defined(__CYGWIN__) +#ifdef _WIN32 Sleep (33); #else usleep(33); @@ -295,6 +358,24 @@ bool FGATCOutput::open( int lock_fd ) { } compass_position = 0.0; +#endif + + // Lock the hardware, keep trying until we succeed + while ( ATCLock( lock_fd ) <= 0 ); + + ///////////////////////////////////////////////////////////////////// + // Zero the analog outputs + ///////////////////////////////////////////////////////////////////// + + SG_LOG( SG_IO, SG_ALERT, + " - Zeroing Analog Outputs." ); + + for ( int channel = 0; channel < ATC_ANALOG_OUT_CHANNELS; ++channel ) { + analog_out_data[2*channel] = 0; + analog_out_data[2*channel + 1] = 0; + } + ATCSetAnalogOut( analog_out_fd, analog_out_data ); + ///////////////////////////////////////////////////////////////////// // Blank the radio display @@ -308,11 +389,6 @@ bool FGATCOutput::open( int lock_fd ) { for ( int channel = 0; channel < ATC_RADIO_DISPLAY_BYTES; ++channel ) { radio_display_data[channel] = value; } - - // Lock the hardware, keep trying until we succeed - while ( ATCLock( lock_fd ) <= 0 ); - - // Set radio display ATCSetRadios( radio_display_fd, radio_display_data ); ATCRelease( lock_fd ); @@ -340,6 +416,9 @@ bool FGATCOutput::open( int lock_fd ) { char base_name[256]; + snprintf( base_name, 256, "/output/atc-board[%d]/analog-outputs", board ); + analog_out_node = fgGetNode( base_name ); + snprintf( base_name, 256, "/output/atc-board[%d]/lamps", board ); lamps_out_node = fgGetNode( base_name ); @@ -353,12 +432,80 @@ bool FGATCOutput::open( int lock_fd ) { } +///////////////////////////////////////////////////////////////////// +// Write the lanalog outputs +///////////////////////////////////////////////////////////////////// + +bool FGATCOutput::do_analog_out() { + if ( analog_out_node != NULL ) { + for ( int i = 0; i < analog_out_node->nChildren(); ++i ) { + // read the next config entry from the property tree + + SGPropertyNode *child = analog_out_node->getChild(i); + string cname = child->getName(); + int index = child->getIndex(); + string name = ""; + string type = ""; + SGPropertyNode *src_prop = NULL; + double x0 = 0.0, y0 = 0.0, x1 = 0.0, y1 = 0.0; + if ( cname == "analog-out" ) { + SGPropertyNode *prop; + prop = child->getChild( "name" ); + if ( prop != NULL ) { + name = prop->getStringValue(); + } + prop = child->getChild( "type" ); + if ( prop != NULL ) { + type = prop->getStringValue(); + } + prop = child->getChild( "prop" ); + if ( prop != NULL ) { + src_prop = fgGetNode( prop->getStringValue(), true ); + } + prop = child->getChild( "value-lo" ); + if ( prop != NULL ) { + x0 = prop->getDoubleValue(); + } + prop = child->getChild( "meter-lo" ); + if ( prop != NULL ) { + y0 = prop->getDoubleValue(); + } + prop = child->getChild( "value-hi" ); + if ( prop != NULL ) { + x1 = prop->getDoubleValue(); + } + prop = child->getChild( "meter-hi" ); + if ( prop != NULL ) { + y1 = prop->getDoubleValue(); + } + // crunch linear interpolation formula + double dx = x1 - x0; + double dy = y1 - y0; + double slope = dy / dx; + double value = src_prop->getDoubleValue(); + int meter = (value - x0) * slope + y0; + if ( meter < 0 ) { meter = 0; } + if ( meter > 1023 ) { meter = 1023; } + analog_out_data[2*index] = meter / 256; + analog_out_data[2*index + 1] = meter - analog_out_data[2*index] * 256; + } else { + SG_LOG( SG_IO, SG_DEBUG, + "Input config error, expecting 'analog-out' but found " + << cname ); + } + ATCSetAnalogOut( analog_out_fd, analog_out_data ); + } + } + + return true; +} + + ///////////////////////////////////////////////////////////////////// // Write the lights ///////////////////////////////////////////////////////////////////// bool FGATCOutput::do_lamps() { - if ( lamps_out_node != NULL ) { for ( int i = 0; i < lamps_out_node->nChildren(); ++i ) { // read the next config entry from the property tree @@ -442,7 +589,7 @@ static bool xpdr_has_power() { static SGPropertyNode *xpdr_bus_power = fgGetNode( "/systems/electrical/outputs/transponder", true ); static SGPropertyNode *xpdr_func_knob - = fgGetNode( "/instrumentation/kt-70/inputs/func-knob", true ); + = fgGetNode( "/instrumentation/transponder/inputs/func-knob", true ); return (xpdr_bus_power->getDoubleValue() > 1.0) && (xpdr_func_knob->getIntValue() > 0); @@ -506,13 +653,13 @@ bool FGATCOutput::do_radio_display() { = fgGetNode( "/instrumentation/kr-87/outputs/elapsed-timer", true ); static SGPropertyNode *xpdr_serviceable - = fgGetNode( "/instrumentation/kt-70/inputs/serviceable", true ); + = fgGetNode( "/instrumentation/transponder/inputs/serviceable", true ); static SGPropertyNode *xpdr_func_knob - = fgGetNode( "/instrumentation/kt-70/inputs/func-knob", true ); + = fgGetNode( "/instrumentation/transponder/inputs/func-knob", true ); static SGPropertyNode *xpdr_flight_level - = fgGetNode( "/instrumentation/kt-70/outputs/flight-level", true ); + = fgGetNode( "/instrumentation/transponder/outputs/flight-level", true ); static SGPropertyNode *xpdr_id_code - = fgGetNode( "/instrumentation/kt-70/outputs/id-code", true ); + = fgGetNode( "/instrumentation/transponder/outputs/id-code", true ); char digits[10]; int i; @@ -906,9 +1053,12 @@ bool FGATCOutput::process() { return false; } + do_analog_out(); do_lamps(); do_radio_display(); +#ifdef ATCFLIGHTSIM_HAVE_COMPASS do_steppers(); +#endif return true; }