examples/DS401_Slave_Gui/main.cpp
author Robert Lehmann <robert.lehmann@sitec-systems.de>
Tue, 28 Jul 2015 16:36:55 +0200
changeset 793 72e9e1064432
parent 641 404a51700f40
permissions -rw-r--r--
timers_unix: Fix termination problem of WaitReceiveTaskEnd

The function pthread_kill sends the Signal thread and to the own process.
If you use this construct than the application which calls uses the
canfestival api will terminate at the call of canClose. To avoid that
use pthread_cancel instead of pthread_kill. To use the pthread_cancel call
you need to set the cancel ability in the thread function. That means
you need to call pthread_setcancelstate and pthread_setcanceltype.
For the termination of the thread at any time it is important to set the
cancel type to PTHREAD_CANCEL_ASYNCHRONOUS.
#if defined(WIN32) && !defined(__CYGWIN__)
#include <windows.h>
#include "getopt.h"
#endif

#include <wx/wxprec.h>
#include <wx/wx.h>
#include <wx/textctrl.h>
#include <wx/spinctrl.h>
#include <wx/tglbtn.h>
#include <wx/slider.h>
#include <iostream>
#include <wx/brush.h>
#include <sstream>
#include <string.h>
#include <wx/listbox.h>
#include <wx/dynarray.h>
#include <wx/dcclient.h>
#include <wx/gauge.h>
#include <wx/spinctrl.h>

//#include "monicone.xpm"

//#if defined(WIN32) && !defined(__CYGWIN__)
//#include <windows.h>
//extern "C"
//{
//#include "getopt.h"
//}
//#endif

#include "main.h"
#include "TestSlaveGui.h"
extern "C"
{
#include "canfestival.h"
#include "ObjDict.h"
}
#include "wx/wxprec.h"

#ifdef __BORLANDC__
#pragma hdrstop
#endif

#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif


wxTextCtrl *textLog;
int node_id_ext;
int to_start = 0;
int openInput = 0;
int openOutput = 0;

MyFrame *frame;
#define MAXLENGTH_BUSNAME 32
#define MAXLENGTH_BAUDRATE 8
char _busname[MAXLENGTH_BUSNAME] = "vcan0";
char _baudrate[MAXLENGTH_BAUDRATE] = "500K";
s_BOARD SlaveBoard = { _busname, _baudrate };

#define MAXLENGTH_LIBPATH 1024
char LibraryPath[MAXLENGTH_LIBPATH] = "libcanfestival_can_virtual.so";

#if defined(WIN32)
#define LIB_EXTENT wxT("*.dll")
#else
#define LIB_EXTENT wxT("*.so")
#endif

// Declare some IDs. These are arbitrary.
const int BOOKCTRL = 100;
const int FILE_QUIT = wxID_EXIT;
const int HELP_ABOUT = wxID_ABOUT;
const int ADD = 105;
const int REMOVE = 108;
const int QUIT = 109;
const int FREQBOX = 110;
const int START = 112;
const int TEXTBOX1 = 113;
const int STOP = 114;
const int LOAD = 115;
const int INBT1 = 118;
const int INBT2 = 119;
const int INBT3 = 120;
const int INBT4 = 121;
const int INBT5 = 122;
const int INBT6 = 123;
const int INBT7 = 124;
const int INBT8 = 125;
const int INS1 = 126;
const int INS2 = 127;
const int INS3 = 128;
const int INS4 = 129;
const int INS5 = 135;
const int INS6 = 136;
const int INS7 = 137;
const int INS8 = 138;
const int TIMER_ID = 130;
const int INST1 = 131;
const int INST2 = 132;
const int INST3 = 133;
const int INST4 = 134;
const int INST5 = 135;
const int INST6 = 136;
const int INST7 = 137;
const int INST8 = 138;

// Attach the event handlers. Put this after MyFrame declaration.
BEGIN_EVENT_TABLE (MyFrame, wxFrame)
EVT_BUTTON (STOP, MyFrame::OnStop)
EVT_BUTTON (LOAD, MyFrame::OnLoad)
EVT_BUTTON (START, MyFrame::OnStart)
EVT_TOGGLEBUTTON (INBT1, MyFrame::OnInbt1)
EVT_TOGGLEBUTTON (INBT2, MyFrame::OnInbt2)
EVT_TOGGLEBUTTON (INBT3, MyFrame::OnInbt3)
EVT_TOGGLEBUTTON (INBT4, MyFrame::OnInbt4)
EVT_TOGGLEBUTTON (INBT5, MyFrame::OnInbt5)
EVT_TOGGLEBUTTON (INBT6, MyFrame::OnInbt6)
EVT_TOGGLEBUTTON (INBT7, MyFrame::OnInbt7)
EVT_TOGGLEBUTTON (INBT8, MyFrame::OnInbt8)
EVT_COMMAND_SCROLL (INS1, MyFrame::OnIns1)
EVT_COMMAND_SCROLL (INS2, MyFrame::OnIns2)
EVT_COMMAND_SCROLL (INS3, MyFrame::OnIns3)
EVT_COMMAND_SCROLL (INS4, MyFrame::OnIns4)
EVT_COMMAND_SCROLL (INS5, MyFrame::OnIns5)
EVT_COMMAND_SCROLL (INS6, MyFrame::OnIns6)
EVT_COMMAND_SCROLL (INS7, MyFrame::OnIns7)
EVT_COMMAND_SCROLL (INS8, MyFrame::OnIns8)
EVT_SPINCTRL (INST1, MyFrame::OnInst1)
EVT_SPINCTRL (INST2, MyFrame::OnInst2)
EVT_SPINCTRL (INST3, MyFrame::OnInst3)
EVT_SPINCTRL (INST4, MyFrame::OnInst4)
EVT_SPINCTRL (INST5, MyFrame::OnInst5)
EVT_SPINCTRL (INST6, MyFrame::OnInst6)
EVT_SPINCTRL (INST7, MyFrame::OnInst7)
EVT_SPINCTRL (INST8, MyFrame::OnInst8)
EVT_LISTBOX (FREQBOX, MyFrame::OnFreqBoxClick)
EVT_MENU (FILE_QUIT, MyFrame::OnQuit)
EVT_BUTTON (QUIT, MyFrame::OnQuit) EVT_MENU (HELP_ABOUT, MyFrame::OnAbout)
EVT_TIMER (TIMER_ID, MyFrame::OnTimer)
END_EVENT_TABLE ()IMPLEMENT_APP_NO_MAIN (MyApp);
IMPLEMENT_WX_THEME_SUPPORT;

     void
     help ()
{
  printf ("**************************************************************\n");
  printf ("*  DS-401 Slave GUI                                          *\n");
  printf ("*                                                            *\n");
  printf ("*   Usage:                                                   *\n");
  printf ("*   ./DS401_Slave_Gui [OPTIONS]                              *\n");
  printf ("*                                                            *\n");
  printf ("*   OPTIONS:                                                 *\n");
  printf
    ("*     -l : Can library [\"libcanfestival_can_virtual.so\"]     *\n");
  printf ("*                                                            *\n");
  printf ("*    Slave:                                                  *\n");
  printf ("*     -i : Node id format [0x01 , 0x7F]                      *\n");
  printf ("*                                                            *\n");
  printf ("*    CAN bus:                                                *\n");
  printf
    ("*     -b : bus name [\"1\"]                                    *\n");
  printf ("*     -B : 1M,500K,250K,125K,100K,50K,20K,10K                *\n");
  printf ("*                                                            *\n");
  printf ("**************************************************************\n");
}


int
main (int argc, char **argv)
{

  int c;
  extern char *optarg;
  char *snodeid;
  while ((c = getopt (argc, argv, "-b:B:l:i:sIO")) != EOF)
    {
      switch (c)
	{
	case 'b':
	  if (optarg[0] == 0)
	    {
	      help ();
	      exit (1);
	    }
	  SlaveBoard.busname = optarg;
	  break;
	case 'B':
	  if (optarg[0] == 0)
	    {
	      help ();
	      exit (1);
	    }
	  SlaveBoard.baudrate = optarg;
	  break;
	case 'l':
	  if (optarg[0] == 0)
	    {
	      help ();
	      exit (1);
	    }
	  strncpy (LibraryPath, optarg, MAXLENGTH_LIBPATH);
	  break;
	case 'i':
	  if (optarg[0] == 0)
	    {
	      help ();
	      exit (1);
	    }
	  snodeid = optarg;
	  sscanf (snodeid, "%x", &node_id_ext);
	  break;
	case 's':
	  to_start = 1;
	  break;
	case 'I':
	  openInput = 1;
	  break;
	case 'O':
	  openOutput = 1;
	  break;
	default:
	  help ();
	  exit (1);
	}
    }
  wxEntry (argc, argv);
}


bool
MyApp::OnInit ()
{
  frame = new MyFrame (wxString::Format(wxT("CanOpen virtual DS-401 - Id : %d"),node_id_ext));
  frame->Show (true);
  if(openInput) frame->book->SetSelection(2);
  else if(openOutput) frame->book->SetSelection(3);
  return true;
}

MyFrame::MyFrame (const wxString & title):wxFrame (NULL, wxID_ANY, title, wxDefaultPosition, wxSize (800, 740),
	 wxDEFAULT_FRAME_STYLE, wxT ("frame")), m_timer (this,
							 TIMER_ID)
{
  wxMenu *
    fileMenu = new wxMenu;
  wxMenu *
    helpMenu = new wxMenu;
  wxPanel *
    panel;
  wxButton *
    quit;
  wxButton *
    load;
  wxBoxSizer *
    mysizer;
  wxBoxSizer *
    mysssizer;
  wxBoxSizer *
    myhsizer;
  wxBoxSizer *
    mybsizer;
  wxBoxSizer *
    myentrysizer;
  wxListBox *
    freqlist;
  wxStaticBox *
    namebox;
  wxStaticBox *
    freqbox;

// SetIcon(wxICON(monicone));
  SetBackgroundColour (wxSystemSettings::GetColour (wxSYS_COLOUR_BTNFACE));
  helpMenu->Append (HELP_ABOUT, _T ("&About...\tF1"),
		    _T ("Show about dialog"));
  fileMenu->Append (FILE_QUIT, _T ("E&xit\tAlt-X"), _T ("Quit this program"));
  wxMenuBar *
    menuBar = new wxMenuBar ();
  menuBar->Append (fileMenu, _T ("&File"));
  menuBar->Append (helpMenu, _T ("&Help"));
  SetMenuBar (menuBar);
  CreateStatusBar (2);
  SetStatusText (_T ("DS-401 GUI."), 0);
  SetStatusText (_T ("Welcome."), 1);

  book = new wxNotebook (this, BOOKCTRL);

  panel = new wxPanel (book);
  book->AddPage (panel, _T ("Configuration"), true);
  mysizer = new wxBoxSizer (wxVERTICAL);
  panel->SetSizer (mysizer);
  wxString
    choices[] = {
    _T ("10K"), _T ("20K"), _T ("50K"), _T ("100K"),
    _T ("125K"), _T ("250K"), _T ("500K"), _T ("1M")
  };

  myhsizer =
    new wxStaticBoxSizer (new
			  wxStaticBox (panel, wxID_ANY, _T ("Bus driver")),
			  wxHORIZONTAL);
  mysizer->Add (myhsizer, 0, wxEXPAND | wxALL, 5);
  load = new wxButton (panel, LOAD, _T ("Load can driver"));
  myhsizer->Add (load, 0, wxLEFT, 5);
  drivername =
    new wxTextCtrl (panel, wxID_ANY,
		    wxString ((const char *) LibraryPath, wxConvLocal));
  myhsizer->Add (drivername, 1, wxEXPAND | wxALL, 5);
  myentrysizer = new wxBoxSizer (wxHORIZONTAL);
  mysizer->Add (myentrysizer, 0, wxEXPAND | wxALL, 5);
  myhsizer =
    new wxStaticBoxSizer (new wxStaticBox (panel, wxID_ANY, _T ("Bus name")),
			  wxHORIZONTAL);
  myentrysizer->Add (myhsizer, 0, wxEXPAND | wxALL, 5);
  busname =
    new wxTextCtrl (panel, wxID_ANY,
		    wxString ((const char *) SlaveBoard.busname,
			      wxConvLocal));
  myhsizer->Add (busname, 0, wxLEFT, 5);
  myhsizer =
    new wxStaticBoxSizer (new
			  wxStaticBox (panel, wxID_ANY,
				       _T ("Node ID (Decimal)")), wxHORIZONTAL);
  myentrysizer->Add (myhsizer, 0, wxEXPAND | wxALL, 5);
  node_id =
    new wxSpinCtrl (panel, wxID_ANY, wxEmptyString, wxDefaultPosition,
		    wxDefaultSize, wxSP_ARROW_KEYS, 1, 127, node_id_ext,
		    _T ("wxSpinCtrl"));
  myhsizer->Add (node_id, 0, wxRIGHT, 5);
  myhsizer =
    new wxStaticBoxSizer (new wxStaticBox (panel, wxID_ANY, _T ("Baudrate")),
			  wxHORIZONTAL);
  mysizer->Add (myhsizer, wxEXPAND | wxALL, wxEXPAND | wxALL, 5);
  freqlist =
    new wxListBox (panel, FREQBOX, wxDefaultPosition, wxDefaultSize, 8,
		   choices, wxLB_SINGLE | wxLB_HSCROLL);
  myhsizer->Add (freqlist, wxEXPAND | wxALL, wxEXPAND | wxALL, 5);
  quit = new wxButton (panel, QUIT, _T ("QUIT"));
  mysizer->Add (quit, 0, wxALL, 5);


  panel = new wxPanel (book);
  book->AddPage (panel, wxT ("Inputs"), true);
  mysizer = new wxBoxSizer (wxVERTICAL);
  panel->SetSizer (mysizer);
  myhsizer =
    new wxStaticBoxSizer (new
			  wxStaticBox (panel, wxID_ANY,
				       _T ("Read Inputs UNSIGNED8")),
			  wxHORIZONTAL);
  mysizer->Add (myhsizer, 0, wxEXPAND | wxALL, 30);
  inbt1 = new wxToggleButton (panel, INBT1, wxT ("1"));
  inbt2 = new wxToggleButton (panel, INBT2, wxT ("2"));
  inbt3 = new wxToggleButton (panel, INBT3, wxT ("3"));
  inbt4 = new wxToggleButton (panel, INBT4, wxT ("4"));
  inbt5 = new wxToggleButton (panel, INBT5, wxT ("5"));
  inbt6 = new wxToggleButton (panel, INBT6, wxT ("6"));
  inbt7 = new wxToggleButton (panel, INBT7, wxT ("7"));
  inbt8 = new wxToggleButton (panel, INBT8, wxT ("8"));
  myhsizer->Add (inbt1, wxEXPAND | wxALL, 0, 5);
  myhsizer->Add (inbt2, wxEXPAND | wxALL, 0, 5);
  myhsizer->Add (inbt3, wxEXPAND | wxALL, 0, 5);
  myhsizer->Add (inbt4, wxEXPAND | wxALL, 0, 5);
  myhsizer->Add (inbt5, wxEXPAND | wxALL, 0, 5);
  myhsizer->Add (inbt6, wxEXPAND | wxALL, 0, 5);
  myhsizer->Add (inbt7, wxEXPAND | wxALL, 0, 5);
  myhsizer->Add (inbt8, wxEXPAND | wxALL, 0, 5);
  myhsizer =
    new wxStaticBoxSizer (new
			  wxStaticBox (panel, wxID_ANY,
				       _T ("Analogue Inputs INTEGER16")),
			  wxVERTICAL);
  mysizer->Add (myhsizer, wxEXPAND | wxALL, wxEXPAND | wxALL, 30);
  mysssizer = new wxBoxSizer (wxHORIZONTAL);
  myhsizer->Add (mysssizer, 0, wxEXPAND | wxALL, 0);
  inst1 =
    new wxSpinCtrl (panel, INST1, wxEmptyString, wxDefaultPosition,
		    wxDefaultSize, wxSP_ARROW_KEYS, -32768, 32767, 0,
		    _T ("0"));
  inst2 =
    new wxSpinCtrl (panel, INST2, wxEmptyString, wxDefaultPosition,
		    wxDefaultSize, wxSP_ARROW_KEYS, -32768, 32767, 0,
		    _T ("0"));
  inst3 =
    new wxSpinCtrl (panel, INST3, wxEmptyString, wxDefaultPosition,
		    wxDefaultSize, wxSP_ARROW_KEYS, -32768, 32767, 0,
		    _T ("0"));
  inst4 =
    new wxSpinCtrl (panel, INST4, wxEmptyString, wxDefaultPosition,
		    wxDefaultSize, wxSP_ARROW_KEYS, -32768, 32767, 0,
		    _T ("0"));
  inst5 =
    new wxSpinCtrl (panel, INST5, wxEmptyString, wxDefaultPosition,
		    wxDefaultSize, wxSP_ARROW_KEYS, -32768, 32767, 0,
		    _T ("0"));
  inst6 =
    new wxSpinCtrl (panel, INST6, wxEmptyString, wxDefaultPosition,
		    wxDefaultSize, wxSP_ARROW_KEYS, -32768, 32767, 0,
		    _T ("0"));
  inst7 =
    new wxSpinCtrl (panel, INST7, wxEmptyString, wxDefaultPosition,
		    wxDefaultSize, wxSP_ARROW_KEYS, -32768, 32767, 0,
		    _T ("0"));
  inst8 =
    new wxSpinCtrl (panel, INST8, wxEmptyString, wxDefaultPosition,
		    wxDefaultSize, wxSP_ARROW_KEYS, -32768, 32767, 0,
		    _T ("0"));
  mysssizer->Add (inst1, wxALL, 0, 5);
  mysssizer->Add (inst2, wxALL, 0, 5);
  mysssizer->Add (inst3, wxALL, 0, 5);
  mysssizer->Add (inst4, wxALL, 0, 5);
  mysssizer->Add (inst5, wxALL, 0, 5);
  mysssizer->Add (inst6, wxALL, 0, 5);
  mysssizer->Add (inst7, wxALL, 0, 5);
  mysssizer->Add (inst8, wxALL, 0, 5);
  mysssizer = new wxBoxSizer (wxHORIZONTAL);
  myhsizer->Add (mysssizer, wxEXPAND | wxALL, wxEXPAND | wxALL, 0);
  ins1 =
    new wxSlider (panel, INS1, 0, -32768, 32767, wxDefaultPosition,
		  wxDefaultSize, wxSL_VERTICAL | wxSL_INVERSE,
		  wxDefaultValidator, wxT ("slider"));
  ins2 =
    new wxSlider (panel, INS2, 0, -32768, 32767, wxDefaultPosition,
		  wxDefaultSize, wxSL_VERTICAL | wxSL_INVERSE,
		  wxDefaultValidator, wxT ("slider"));
  ins3 =
    new wxSlider (panel, INS3, 0, -32768, 32767, wxDefaultPosition,
		  wxDefaultSize, wxSL_VERTICAL | wxSL_INVERSE,
		  wxDefaultValidator, wxT ("slider"));
  ins4 =
    new wxSlider (panel, INS4, 0, -32768, 32767, wxDefaultPosition,
		  wxDefaultSize, wxSL_VERTICAL | wxSL_INVERSE,
		  wxDefaultValidator, wxT ("slider"));
  ins5 =
    new wxSlider (panel, INS5, 0, -32768, 32767, wxDefaultPosition,
		  wxDefaultSize, wxSL_VERTICAL | wxSL_INVERSE,
		  wxDefaultValidator, wxT ("slider"));
  ins6 =
    new wxSlider (panel, INS6, 0, -32768, 32767, wxDefaultPosition,
		  wxDefaultSize, wxSL_VERTICAL | wxSL_INVERSE,
		  wxDefaultValidator, wxT ("slider"));
  ins7 =
    new wxSlider (panel, INS7, 0, -32768, 32767, wxDefaultPosition,
		  wxDefaultSize, wxSL_VERTICAL | wxSL_INVERSE,
		  wxDefaultValidator, wxT ("slider"));
  ins8 =
    new wxSlider (panel, INS8, 0, -32768, 32767, wxDefaultPosition,
		  wxDefaultSize, wxSL_VERTICAL | wxSL_INVERSE,
		  wxDefaultValidator, wxT ("slider"));
  mysssizer->Add (ins1, wxEXPAND | wxALL, wxEXPAND | wxALL, 15);
  mysssizer->Add (ins2, wxEXPAND | wxALL, wxEXPAND | wxALL, 15);
  mysssizer->Add (ins3, wxEXPAND | wxALL, wxEXPAND | wxALL, 15);
  mysssizer->Add (ins4, wxEXPAND | wxALL, wxEXPAND | wxALL, 15);
  mysssizer->Add (ins5, wxEXPAND | wxALL, wxEXPAND | wxALL, 15);
  mysssizer->Add (ins6, wxEXPAND | wxALL, wxEXPAND | wxALL, 15);
  mysssizer->Add (ins7, wxEXPAND | wxALL, wxEXPAND | wxALL, 15);
  mysssizer->Add (ins8, wxEXPAND | wxALL, wxEXPAND | wxALL, 15);
  quit = new wxButton (panel, QUIT, _T ("QUIT"));
  mysizer->Add (quit, 0, wxALL, 5);

  panel = new wxPanel (book);
  book->AddPage (panel, wxT ("Outputs"), true);
  mysizer = new wxBoxSizer (wxVERTICAL);
  panel->SetSizer (mysizer);
  myhsizer =
    new wxStaticBoxSizer (new
			  wxStaticBox (panel, wxID_ANY,
				       _T ("Write Outputs UNSIGNED8")),
			  wxHORIZONTAL);
  mysizer->Add (myhsizer, 0, wxEXPAND | wxALL, 30);
  outbt1 = new wxToggleButton (panel, wxID_ANY, wxT ("1"));
  outbt2 = new wxToggleButton (panel, wxID_ANY, wxT ("2"));
  outbt3 = new wxToggleButton (panel, wxID_ANY, wxT ("3"));
  outbt4 = new wxToggleButton (panel, wxID_ANY, wxT ("4"));
  outbt5 = new wxToggleButton (panel, wxID_ANY, wxT ("5"));
  outbt6 = new wxToggleButton (panel, wxID_ANY, wxT ("6"));
  outbt7 = new wxToggleButton (panel, wxID_ANY, wxT ("7"));
  outbt8 = new wxToggleButton (panel, wxID_ANY, wxT ("8"));
  myhsizer->Add (outbt1, wxEXPAND | wxALL, 0, 5);
  myhsizer->Add (outbt2, wxEXPAND | wxALL, 0, 5);
  myhsizer->Add (outbt3, wxEXPAND | wxALL, 0, 5);
  myhsizer->Add (outbt4, wxEXPAND | wxALL, 0, 5);
  myhsizer->Add (outbt5, wxEXPAND | wxALL, 0, 5);
  myhsizer->Add (outbt6, wxEXPAND | wxALL, 0, 5);
  myhsizer->Add (outbt7, wxEXPAND | wxALL, 0, 5);
  myhsizer->Add (outbt8, wxEXPAND | wxALL, 0, 5);
  myhsizer =
    new wxStaticBoxSizer (new
			  wxStaticBox (panel, wxID_ANY,
				       _T ("Analogue Output INTEGER16")),
			  wxVERTICAL);
  mysizer->Add (myhsizer, wxEXPAND | wxALL, wxEXPAND | wxALL, 30);
  mysssizer = new wxBoxSizer (wxHORIZONTAL);
  myhsizer->Add (mysssizer, 0, wxEXPAND | wxALL, 0);
  outst1 =
    new wxStaticText (panel, wxID_ANY, wxT ("label"), wxDefaultPosition,
		      wxDefaultSize, 0, wxT ("staticText"));
  outst2 =
    new wxStaticText (panel, wxID_ANY, wxT ("label"), wxDefaultPosition,
		      wxDefaultSize, 0, wxT ("staticText"));
  outst3 =
    new wxStaticText (panel, wxID_ANY, wxT ("label"), wxDefaultPosition,
		      wxDefaultSize, 0, wxT ("staticText"));
  outst4 =
    new wxStaticText (panel, wxID_ANY, wxT ("label"), wxDefaultPosition,
		      wxDefaultSize, 0, wxT ("staticText"));
  mysssizer->Add (outst1, wxEXPAND | wxALL, wxEXPAND | wxALL, 5);
  mysssizer->Add (outst2, wxEXPAND | wxALL, wxEXPAND | wxALL, 5);
  mysssizer->Add (outst3, wxEXPAND | wxALL, wxEXPAND | wxALL, 5);
  mysssizer->Add (outst4, wxEXPAND | wxALL, wxEXPAND | wxALL, 5);
  mysssizer = new wxBoxSizer (wxHORIZONTAL);
  myhsizer->Add (mysssizer, wxEXPAND | wxALL, wxEXPAND | wxALL, 0);
  outs1 =
    new wxGauge (panel, wxID_ANY, 65535, wxDefaultPosition, wxDefaultSize,
		 wxSL_VERTICAL | wxSL_INVERSE, wxDefaultValidator,
		 wxT ("gauge"));
  outs2 =
    new wxGauge (panel, wxID_ANY, 65535, wxDefaultPosition, wxDefaultSize,
		 wxSL_VERTICAL | wxSL_INVERSE, wxDefaultValidator,
		 wxT ("gauge"));
  outs3 =
    new wxGauge (panel, wxID_ANY, 65535, wxDefaultPosition, wxDefaultSize,
		 wxSL_VERTICAL | wxSL_INVERSE, wxDefaultValidator,
		 wxT ("gauge"));
  outs4 =
    new wxGauge (panel, wxID_ANY, 65535, wxDefaultPosition, wxDefaultSize,
		 wxSL_VERTICAL | wxSL_INVERSE, wxDefaultValidator,
		 wxT ("gauge"));
  mysssizer->Add (outs1, wxEXPAND | wxALL, wxEXPAND | wxALL, 15);
  mysssizer->Add (outs2, wxEXPAND | wxALL, wxEXPAND | wxALL, 15);
  mysssizer->Add (outs3, wxEXPAND | wxALL, wxEXPAND | wxALL, 15);
  mysssizer->Add (outs4, wxEXPAND | wxALL, wxEXPAND | wxALL, 15);
  quit = new wxButton (panel, QUIT, _T ("QUIT"));
  mysizer->Add (quit, 0, wxALL, 5);

  wxString
    choice[] = {
    _T ("Analogue Out 1"), _T ("Analogue Out 2"),
    _T ("Analogue Out 3"), _T ("Analogue Out 4"),
    _T ("Bool Out 1"), _T ("Bool Out 2"),
    _T ("Bool Out 3"), _T ("Bool Out 4"),
    _T ("Bool Out 5"), _T ("Bool Out 6"),
    _T ("Bool Out 7"), _T ("Bool Out 8"),
    _T ("Analogue Input 1"), _T ("Analogue Input 2"),
    _T ("Analogue Input 3"), _T ("Analogue Input 4"),
    _T ("Analogue Input 5"), _T ("Analogue Input 6"),
    _T ("Analogue Input 7"), _T ("Analogue Input 8"),
    _T ("Bool Input 1"), _T ("Bool Input 2"),
    _T ("Bool Input 3"), _T ("Bool Input 4"),
    _T ("Bool Input 5"), _T ("Bool Input 6"),
    _T ("Bool Input 7"), _T ("Bool Input 8"),
  };

  panel = new wxPanel (book);
  book->InsertPage (0, panel, wxT ("Control"), true);
  mysizer = new wxBoxSizer (wxVERTICAL);
  panel->SetSizer (mysizer);
  myhsizer = new wxBoxSizer (wxHORIZONTAL);
  myhsizer =
    new wxStaticBoxSizer (new
			  wxStaticBox (panel, wxID_ANY,
				       _T ("Control your node")),
			  wxHORIZONTAL);
  mysizer->Add (myhsizer, 0, wxALL, 5);
  start = new wxButton (panel, START, _T ("START"));
  stop = new wxButton (panel, STOP, _T ("STOP"));
  stop->Enable (false);
  myhsizer->Add (start, 0, wxRIGHT, 5);
  myhsizer->Add (stop, 0, wxLEFT, 5);
  myhsizer =
    new wxStaticBoxSizer (new
			  wxStaticBox (panel, wxID_ANY, _T ("Operation log")),
			  wxHORIZONTAL);
  mysizer->Add (myhsizer, wxALL, wxEXPAND | wxALL, 5);
  textLog =
    new wxTextCtrl (panel, TEXTBOX1, _T (""), wxDefaultPosition,
		    wxDefaultSize, wxTE_MULTILINE, wxDefaultValidator,
		    wxTextCtrlNameStr);
  myhsizer->Add (textLog, wxALL, wxEXPAND | wxALL, 5);
  quit = new wxButton (panel, QUIT, _T ("QUIT"));
  mysizer->Add (quit, 0, wxALL, 5);

  m_timer.Start (100);
  if (to_start)
    {
      Start ();
    }
}

void
MyFrame::OnQuit (wxCommandEvent & WXUNUSED (event))
{
  Close (true);
}

void
MyFrame::Start ()
{
  if (main_can (SlaveBoard, LibraryPath))
    {
      printf ("[KO]\n");
      fflush(stdout);
      *textLog <<
	wxT
	("----------------------------------------------------Initialization [KO]\n");
    }
  else
    {
      printf ("[OK]\n");
      fflush(stdout);
      *textLog <<
	wxT
	("----------------------------------------------------Initialization [OK]\n");
      stop->Enable (true);
      start->Enable (false);
    }
}

void
MyFrame::OnStart (wxCommandEvent & WXUNUSED (event))
{
  wxString s;
  
  node_id_ext = node_id->GetValue ();
  s = busname->GetValue ();
  strncpy (SlaveBoard.busname, s.mb_str (), MAXLENGTH_BUSNAME);
  *textLog << wxT ("-- Bus name: ------> ") << s << wxT ("\n");
  *textLog << wxT ("-- Node ID: -------> ") << node_id->
    GetValue () << wxT ("\n");
  SetTitle(wxString::Format(wxT("CanOpen virtual DS-401 - Id : %d"),node_id->
		    GetValue ()));
  Start ();
}


void
MyFrame::OnStop (wxCommandEvent & WXUNUSED (event))
{

  *textLog <<
    wxT
    ("----------------------------------------------------Slave [STOPPED]") <<
    wxT ("\n");
  stop_slave ();
  stop->Enable (false);
  start->Enable (true);
}

void
MyFrame::OnLoad (wxCommandEvent & WXUNUSED (event))
{
  wxFileDialog fd (this, wxT ("Choose a can driver library"), wxT (""),
		   wxT (""), LIB_EXTENT);

  if (fd.ShowModal () == wxID_OK)
    {
      drivername->Clear ();
      drivername->AppendText (fd.GetPath ());
      *textLog << wxT ("LibraryPath: ") << fd.GetPath () << wxT ("\n");
      strncpy (LibraryPath, fd.GetPath ().mb_str (), MAXLENGTH_LIBPATH);
      printf ("path=%s", LibraryPath);
    }
}

void
MyFrame::OnInbt1 (wxCommandEvent & WXUNUSED (event))
{
  Read_Inputs_8_Bit[0] = Read_Inputs_8_Bit[0] ^ 0x1;
}

void
MyFrame::OnInbt2 (wxCommandEvent & WXUNUSED (event))
{
  Read_Inputs_8_Bit[0] = Read_Inputs_8_Bit[0] ^ 0x2;
}

void
MyFrame::OnInbt3 (wxCommandEvent & WXUNUSED (event))
{
  Read_Inputs_8_Bit[0] = Read_Inputs_8_Bit[0] ^ 0x4;
}

void
MyFrame::OnInbt4 (wxCommandEvent & WXUNUSED (event))
{
  Read_Inputs_8_Bit[0] = Read_Inputs_8_Bit[0] ^ 0x8;
}

void
MyFrame::OnInbt5 (wxCommandEvent & WXUNUSED (event))
{
  Read_Inputs_8_Bit[0] = Read_Inputs_8_Bit[0] ^ 0x10;
}

void
MyFrame::OnInbt6 (wxCommandEvent & WXUNUSED (event))
{
  Read_Inputs_8_Bit[0] = Read_Inputs_8_Bit[0] ^ 0x20;
}

void
MyFrame::OnInbt7 (wxCommandEvent & WXUNUSED (event))
{
  Read_Inputs_8_Bit[0] = Read_Inputs_8_Bit[0] ^ 0x40;
}

void
MyFrame::OnInbt8 (wxCommandEvent & WXUNUSED (event))
{
  Read_Inputs_8_Bit[0] = Read_Inputs_8_Bit[0] ^ 0x80;
}



void
MyFrame::OnIns1 (wxScrollEvent & event)
{
  Read_Analogue_Input_16_Bit[0] = ins1->GetValue ();
  inst1->SetValue (ins1->GetValue ());
}

void
MyFrame::OnIns2 (wxScrollEvent & event)
{
  Read_Analogue_Input_16_Bit[1] = ins2->GetValue ();
  inst2->SetValue (ins2->GetValue ());
}

void
MyFrame::OnIns3 (wxScrollEvent & event)
{
  Read_Analogue_Input_16_Bit[2] = ins3->GetValue ();
  inst3->SetValue (ins3->GetValue ());
}

void
MyFrame::OnIns4 (wxScrollEvent & event)
{
  Read_Analogue_Input_16_Bit[3] = ins4->GetValue ();
  inst4->SetValue (ins4->GetValue ());
}

void
MyFrame::OnIns5 (wxScrollEvent & event)
{
  Read_Analogue_Input_16_Bit[4] = ins5->GetValue ();
  inst5->SetValue (ins5->GetValue ());
}

void
MyFrame::OnIns6 (wxScrollEvent & event)
{
  Read_Analogue_Input_16_Bit[5] = ins6->GetValue ();
  inst6->SetValue (ins6->GetValue ());
}

void
MyFrame::OnIns7 (wxScrollEvent & event)
{
  Read_Analogue_Input_16_Bit[6] = ins7->GetValue ();
  inst7->SetValue (ins7->GetValue ());
}

void
MyFrame::OnIns8 (wxScrollEvent & event)
{
  Read_Analogue_Input_16_Bit[7] = ins8->GetValue ();
  inst8->SetValue (ins8->GetValue ());
}


void
MyFrame::OnInst1 (wxSpinEvent & ev)
{
  Read_Analogue_Input_16_Bit[0] = inst1->GetValue ();
  ins1->SetValue (inst1->GetValue ());
}

void
MyFrame::OnInst2 (wxSpinEvent & ev)
{
  Read_Analogue_Input_16_Bit[1] = inst2->GetValue ();
  ins2->SetValue (inst2->GetValue ());
}

void
MyFrame::OnInst3 (wxSpinEvent & ev)
{
  Read_Analogue_Input_16_Bit[2] = inst3->GetValue ();
  ins3->SetValue (inst3->GetValue ());
}

void
MyFrame::OnInst4 (wxSpinEvent & ev)
{
  Read_Analogue_Input_16_Bit[3] = inst4->GetValue ();
  ins4->SetValue (inst4->GetValue ());
}

void
MyFrame::OnInst5 (wxSpinEvent & ev)
{
  Read_Analogue_Input_16_Bit[4] = inst5->GetValue ();
  ins5->SetValue (inst5->GetValue ());
}

void
MyFrame::OnInst6 (wxSpinEvent & ev)
{
  Read_Analogue_Input_16_Bit[5] = inst6->GetValue ();
  ins6->SetValue (inst6->GetValue ());
}

void
MyFrame::OnInst7 (wxSpinEvent & ev)
{
  Read_Analogue_Input_16_Bit[6] = inst7->GetValue ();
  ins7->SetValue (inst7->GetValue ());
}

void
MyFrame::OnInst8 (wxSpinEvent & ev)
{
  Read_Analogue_Input_16_Bit[7] = inst8->GetValue ();
  ins8->SetValue (inst8->GetValue ());
}


void
MyFrame::OnAbout (wxCommandEvent & WXUNUSED (event))
{
  wxString msg;
  msg.Printf (_T ("About.\n\n")
	      _T
	      ("Input-Output simulation by GRANDEMANGE Nicolas for CanFestival!!"));

  wxMessageBox (msg, _T ("About !!!"), wxOK | wxICON_INFORMATION, this);
}


void
MyFrame::OnFreqBoxClick (wxCommandEvent & event)
{
  wxString wxstr;

  wxstr = event.GetString ();
  strncpy (SlaveBoard.baudrate, wxstr.mb_str (), MAXLENGTH_BAUDRATE);
  *textLog << wxT ("Baudrate:") << event.GetString () << wxT ("\n");
}

static int
is_set (int i, wxListBox * inlist, wxArrayInt in)
{
  inlist->GetSelections (in);
  for (int j = 0; j < in.GetCount (); j++)
    {
      if (i == (in[j] + 1))
	{
	  return (i);
	}
    }
  return (0);
}

static int
get_bit (UNS8 input, int bit)
{
  return input & (((UNS8) 1) << bit - 1) ? 1 : 0;
}

void
actu_output (void)
{
  wxString tmp;

  frame->outbt1->SetValue (get_bit (Write_Outputs_8_Bit[0], 1));
  frame->outbt2->SetValue (get_bit (Write_Outputs_8_Bit[0], 2));
  frame->outbt3->SetValue (get_bit (Write_Outputs_8_Bit[0], 3));
  frame->outbt4->SetValue (get_bit (Write_Outputs_8_Bit[0], 4));
  frame->outbt5->SetValue (get_bit (Write_Outputs_8_Bit[0], 5));
  frame->outbt6->SetValue (get_bit (Write_Outputs_8_Bit[0], 6));
  frame->outbt7->SetValue (get_bit (Write_Outputs_8_Bit[0], 7));
  frame->outbt8->SetValue (get_bit (Write_Outputs_8_Bit[0], 8));

  frame->outs1->SetValue (Write_Analogue_Output_16_Bit[0] + 32768);
  frame->outs2->SetValue (Write_Analogue_Output_16_Bit[1] + 32768);
  frame->outs3->SetValue (Write_Analogue_Output_16_Bit[2] + 32768);
  frame->outs4->SetValue (Write_Analogue_Output_16_Bit[3] + 32768);
  tmp.Printf (wxT ("       %i"), Write_Analogue_Output_16_Bit[0]);
  frame->outst1->SetLabel (tmp);
  tmp.Printf (wxT ("       %i"), Write_Analogue_Output_16_Bit[1]);
  frame->outst2->SetLabel (tmp);
  tmp.Printf (wxT ("       %i"), Write_Analogue_Output_16_Bit[2]);
  frame->outst3->SetLabel (tmp);
  tmp.Printf (wxT ("       %i"), Write_Analogue_Output_16_Bit[3]);
  frame->outst4->SetLabel (tmp);
}

void
actu (void)
{
  actu_output ();
}

void
MyFrame::OnTimer (wxTimerEvent & event)
{
  actu ();			// do whatever you want to do every second here
}

void
MyFrame::OnPaint (wxPaintEvent & event)
{
  //Paint();
}