From: drowe67 Date: Mon, 10 Jul 2017 11:16:24 +0000 (+0000) Subject: moved serial support out of fdmdv2_main, PTT test function for Hamlib and serial X-Git-Url: http://git.whiteaudio.com/gitweb/?a=commitdiff_plain;h=beb7262c4a8656f72646bc6fee5e7edd6f9453e6;p=freetel-svn-tracking.git moved serial support out of fdmdv2_main, PTT test function for Hamlib and serial git-svn-id: https://svn.code.sf.net/p/freetel/code@3289 01035d8c-6547-0410-b346-abe4f91aad63 --- diff --git a/freedv-dev/src/CMakeLists.txt b/freedv-dev/src/CMakeLists.txt index 2fa45232..ef0798b3 100644 --- a/freedv-dev/src/CMakeLists.txt +++ b/freedv-dev/src/CMakeLists.txt @@ -12,6 +12,7 @@ set(FREEDV_SOURCES fdmdv2_plot_spectrum.cpp fdmdv2_plot_waterfall.cpp hamlib.cpp + serialport.cpp topFrame.cpp sox_biquad.c comp.h diff --git a/freedv-dev/src/dlg_ptt.cpp b/freedv-dev/src/dlg_ptt.cpp index e051d5c8..61bff1d1 100644 --- a/freedv-dev/src/dlg_ptt.cpp +++ b/freedv-dev/src/dlg_ptt.cpp @@ -54,69 +54,76 @@ ComPortsDlg::ComPortsDlg(wxWindow* parent, wxWindowID id, const wxString& title, // Hamlib for CAT PTT //---------------------------------------------------------------------- -#ifdef TTT - wxStaticBoxSizer* staticBoxSizer18 = new wxStaticBoxSizer( new wxStaticBox(this, wxID_ANY, _("Hamlib Settings")), wxVERTICAL); - - wxBoxSizer* gridSizer100 = new wxBoxSizer(wxHORIZONTAL); +#ifdef PREV__ + wxStaticBoxSizer* staticBoxSizer18 = new wxStaticBoxSizer( new wxStaticBox(this, wxID_ANY, _("Hamlib Settings")), wxHORIZONTAL); /* Use Hamlib for PTT checkbox. */ + m_ckUseHamlibPTT = new wxCheckBox(this, wxID_ANY, _("Use Hamlib PTT"), wxDefaultPosition, wxSize(-1, -1), 0); m_ckUseHamlibPTT->SetValue(false); - gridSizer100->Add(m_ckUseHamlibPTT, 0, wxALIGN_CENTER_VERTICAL, 0); + staticBoxSizer18->Add(m_ckUseHamlibPTT, 0, wxALIGN_CENTER_VERTICAL, 0); /* Hamlib Rig Type combobox. */ - gridSizer100->Add(new wxStaticText(this, wxID_ANY, _("Rig Model:"), wxDefaultPosition, wxDefaultSize, 0), + + staticBoxSizer18->Add(new wxStaticText(this, wxID_ANY, _("Rig Model:"), wxDefaultPosition, wxDefaultSize, 0), 0, wxALIGN_CENTER_VERTICAL | wxLEFT, 20); m_cbRigName = new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(250, -1), 0, NULL, wxCB_DROPDOWN); - /* TODO(Joel): this is a hack. At the least, need to gurantee that m_hamLib + /* TODO(Joel): this is a hack. At the least, need to guarantee that m_hamLib * exists. */ wxGetApp().m_hamlib->populateComboBox(m_cbRigName); m_cbRigName->SetSelection(wxGetApp().m_intHamlibRig); - gridSizer100->Add(m_cbRigName, 0, wxALIGN_CENTER_VERTICAL, 0); + staticBoxSizer18->Add(m_cbRigName, 0, wxALIGN_CENTER_VERTICAL, 0); /* Hamlib Serial Port combobox. */ - gridSizer100->Add(new wxStaticText(this, wxID_ANY, _("Serial Device:"), wxDefaultPosition, wxDefaultSize, 0), + + staticBoxSizer18->Add(new wxStaticText(this, wxID_ANY, _("Serial Device:"), wxDefaultPosition, wxDefaultSize, 0), 0, wxALIGN_CENTER_VERTICAL | wxLEFT, 20); m_cbSerialPort = new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(140, -1), 0, NULL, wxCB_DROPDOWN); - gridSizer100->Add(m_cbSerialPort, 0, wxALIGN_CENTER_VERTICAL, 0); + staticBoxSizer18->Add(m_cbSerialPort, 0, wxALIGN_CENTER_VERTICAL, 0); - staticBoxSizer18->Add(gridSizer100, 1); - mainSizer->Add(staticBoxSizer18, 1); + /* Hamlib Serial Rate combobox. */ + + staticBoxSizer18->Add(new wxStaticText(this, wxID_ANY, _("Serial Rate:"), wxDefaultPosition, wxDefaultSize, 0), + 0, wxALIGN_CENTER_VERTICAL | wxLEFT, 20); + m_cbSerialRate = new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(140, -1), 0, NULL, wxCB_DROPDOWN); + staticBoxSizer18->Add(m_cbSerialRate, 0, wxALIGN_CENTER_VERTICAL, 0); + + mainSizer->Add(staticBoxSizer18, 0, wxEXPAND, 5); #endif wxStaticBoxSizer* staticBoxSizer18 = new wxStaticBoxSizer( new wxStaticBox(this, wxID_ANY, _("Hamlib Settings")), wxHORIZONTAL); + wxGridSizer* gridSizerhl = new wxGridSizer(4, 2, 0, 0); + staticBoxSizer18->Add(gridSizerhl, 1, wxEXPAND|wxALIGN_LEFT, 5); /* Use Hamlib for PTT checkbox. */ m_ckUseHamlibPTT = new wxCheckBox(this, wxID_ANY, _("Use Hamlib PTT"), wxDefaultPosition, wxSize(-1, -1), 0); m_ckUseHamlibPTT->SetValue(false); - staticBoxSizer18->Add(m_ckUseHamlibPTT, 0, wxALIGN_CENTER_VERTICAL, 0); + gridSizerhl->Add(m_ckUseHamlibPTT, 0, wxALIGN_CENTER_VERTICAL, 0); + gridSizerhl->Add(new wxStaticText(this, -1, wxT("")), 0, wxEXPAND); /* Hamlib Rig Type combobox. */ - staticBoxSizer18->Add(new wxStaticText(this, wxID_ANY, _("Rig Model:"), wxDefaultPosition, wxDefaultSize, 0), - 0, wxALIGN_CENTER_VERTICAL | wxLEFT, 20); + gridSizerhl->Add(new wxStaticText(this, wxID_ANY, _("Rig Model:"), wxDefaultPosition, wxDefaultSize, 0), + 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT, 20); m_cbRigName = new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(250, -1), 0, NULL, wxCB_DROPDOWN); - /* TODO(Joel): this is a hack. At the least, need to gurantee that m_hamLib - * exists. */ wxGetApp().m_hamlib->populateComboBox(m_cbRigName); m_cbRigName->SetSelection(wxGetApp().m_intHamlibRig); - staticBoxSizer18->Add(m_cbRigName, 0, wxALIGN_CENTER_VERTICAL, 0); + gridSizerhl->Add(m_cbRigName, 0, wxALIGN_CENTER_VERTICAL, 0); /* Hamlib Serial Port combobox. */ - staticBoxSizer18->Add(new wxStaticText(this, wxID_ANY, _("Serial Device:"), wxDefaultPosition, wxDefaultSize, 0), - 0, wxALIGN_CENTER_VERTICAL | wxLEFT, 20); + gridSizerhl->Add(new wxStaticText(this, wxID_ANY, _("Serial Device:"), wxDefaultPosition, wxDefaultSize, 0), + 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT, 20); m_cbSerialPort = new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(140, -1), 0, NULL, wxCB_DROPDOWN); - staticBoxSizer18->Add(m_cbSerialPort, 0, wxALIGN_CENTER_VERTICAL, 0); + gridSizerhl->Add(m_cbSerialPort, 0, wxALIGN_CENTER_VERTICAL, 0); /* Hamlib Serial Rate combobox. */ - staticBoxSizer18->Add(new wxStaticText(this, wxID_ANY, _("Serial Rate:"), wxDefaultPosition, wxDefaultSize, 0), - 0, wxALIGN_CENTER_VERTICAL | wxLEFT, 20); + gridSizerhl->Add(new wxStaticText(this, wxID_ANY, _("Serial Rate:"), wxDefaultPosition, wxDefaultSize, 0), + 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT, 20); m_cbSerialRate = new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(140, -1), 0, NULL, wxCB_DROPDOWN); - staticBoxSizer18->Add(m_cbSerialRate, 0, wxALIGN_CENTER_VERTICAL, 0); - + gridSizerhl->Add(m_cbSerialRate, 0, wxALIGN_CENTER_VERTICAL, 0); mainSizer->Add(staticBoxSizer18, 0, wxEXPAND, 5); @@ -194,6 +201,9 @@ ComPortsDlg::ComPortsDlg(wxWindow* parent, wxWindowID id, const wxString& title, wxBoxSizer* boxSizer12 = new wxBoxSizer(wxHORIZONTAL); + m_buttonTest = new wxButton(this, wxID_APPLY, _("Test PTT"), wxDefaultPosition, wxSize(-1,-1), 0); + boxSizer12->Add(m_buttonTest, 0, wxLEFT|wxRIGHT|wxTOP|wxBOTTOM, 5); + m_buttonOK = new wxButton(this, wxID_OK, _("OK"), wxDefaultPosition, wxSize(-1,-1), 0); m_buttonOK->SetDefault(); boxSizer12->Add(m_buttonOK, 0, wxLEFT|wxRIGHT|wxTOP|wxBOTTOM, 5); @@ -219,6 +229,7 @@ ComPortsDlg::ComPortsDlg(wxWindow* parent, wxWindowID id, const wxString& title, m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ComPortsDlg::OnOK), NULL, this); m_buttonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ComPortsDlg::OnCancel), NULL, this); m_buttonApply->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ComPortsDlg::OnApply), NULL, this); + m_buttonTest->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ComPortsDlg::OnTest), NULL, this); } //------------------------------------------------------------------------- @@ -233,6 +244,7 @@ ComPortsDlg::~ComPortsDlg() m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ComPortsDlg::OnOK), NULL, this); m_buttonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ComPortsDlg::OnCancel), NULL, this); m_buttonApply->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ComPortsDlg::OnApply), NULL, this); + m_buttonTest->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ComPortsDlg::OnTest), NULL, this); } //------------------------------------------------------------------------- @@ -360,8 +372,7 @@ void ComPortsDlg::ExchangeData(int inout) wxConfigBase *pConfig = wxConfigBase::Get(); wxString str; - if(inout == EXCHANGE_DATA_IN) - { + if(inout == EXCHANGE_DATA_IN) { m_ckLeftChannelVoxTone->SetValue(wxGetApp().m_leftChannelVoxTone); /* Hamlib */ @@ -391,12 +402,11 @@ void ComPortsDlg::ExchangeData(int inout) m_rbUseDTR->SetValue(wxGetApp().m_boolUseDTR); m_ckDTRPos->SetValue(wxGetApp().m_boolDTRPos); } - if(inout == EXCHANGE_DATA_OUT) - { + + if (inout == EXCHANGE_DATA_OUT) { wxGetApp().m_leftChannelVoxTone = m_ckLeftChannelVoxTone->GetValue(); pConfig->Write(wxT("/Rig/leftChannelVoxTone"), wxGetApp().m_leftChannelVoxTone); - /* Hamlib settings. */ wxGetApp().m_boolHamlibUseForPTT = m_ckUseHamlibPTT->GetValue(); @@ -449,9 +459,107 @@ void ComPortsDlg::ExchangeData(int inout) //------------------------------------------------------------------------- void ComPortsDlg::PTTUseHamLibClicked(wxCommandEvent& event) { - m_ckUseSerialPTT->SetValue(false); + m_ckUseSerialPTT->SetValue(false); +} + + +/* Attempt to toggle PTT for 1 second */ + +void ComPortsDlg::OnTest(wxCommandEvent& event) { + + /* Tone PTT */ + + if (m_ckLeftChannelVoxTone->GetValue()) { + wxMessageBox("Testing of tone based PTT not supported; try PTT after pressing Start on main window", + wxT("Error"), wxOK | wxICON_ERROR, this); + } + + /* Hamlib PTT */ + + if (m_ckUseHamlibPTT->GetValue()) { + + // set up current hamlib config from GUI + + int rig = m_cbRigName->GetSelection(); + wxString port = m_cbSerialPort->GetValue(); + wxString s = m_cbSerialRate->GetValue(); + int serial_rate; + if (s == "default") { + serial_rate = 0; + } else { + long tmp; + m_cbSerialRate->GetValue().ToLong(&tmp); + serial_rate = tmp; + } + + // display serial params + + fprintf(stderr, "serial rate: %d\n", serial_rate); + + // try to open rig + + Hamlib *hamlib = wxGetApp().m_hamlib; + bool status = hamlib->connect(rig, port.mb_str(wxConvUTF8), serial_rate); + if (status == false) { + wxMessageBox("Couldn't connect to Radio with hamlib", wxT("Error"), wxOK | wxICON_ERROR, this); + return; + } + else { + wxString hamlib_serial_config; + hamlib_serial_config.sprintf("Serial config: %d, %d, %d", + hamlib->get_serial_rate(), + hamlib->get_data_bits(), + hamlib->get_stop_bits()); + wxMessageBox(hamlib_serial_config, wxT("Hamlib Serial Config"), wxOK | wxICON_INFORMATION, this); + } + + // toggle PTT + + wxString hamlibError; + if (hamlib->ptt(true, hamlibError) == false) { + wxMessageBox(wxString("Hamlib PTT Error: ") + hamlibError, wxT("Error"), wxOK | wxICON_ERROR, this); + return; + } + + wxSleep(1); + + if (hamlib->ptt(false, hamlibError) == false) { + wxMessageBox(wxString("Hamlib PTT Error: ") + hamlibError, wxT("Error"), wxOK | wxICON_ERROR, this); + } + } + + /* Serial PTT */ + + if (m_ckUseSerialPTT->IsChecked()) { + Serialport *serialport = wxGetApp().m_serialport; + + wxString ctrlport; +#ifdef __WXMSW__ + ctrlport = m_listCtrlPorts->GetStringSelection(); +#endif +#if defined(__WXGTK__) || defined(__WXOSX__) + ctrlport = m_cbCtlDevicePath->GetValue(); +#endif + bool success = serialport->openport(ctrlport.c_str(), + m_rbUseRTS->GetValue(), + m_ckRTSPos->IsChecked(), + m_rbUseDTR->GetValue(), + m_ckDTRPos->IsChecked()); + + if (!success) { + wxMessageBox("Couldn't open serial port", wxT("Error"), wxOK | wxICON_ERROR, this); + } + + // assert PTT port for 1 sec + + serialport->ptt(true); + wxSleep(1); + serialport->ptt(false); + } + } + //------------------------------------------------------------------------- // PTTUseSerialClicked() //------------------------------------------------------------------------- diff --git a/freedv-dev/src/dlg_ptt.h b/freedv-dev/src/dlg_ptt.h index e4e5cda1..997d08a1 100644 --- a/freedv-dev/src/dlg_ptt.h +++ b/freedv-dev/src/dlg_ptt.h @@ -55,7 +55,6 @@ class ComPortsDlg : public wxDialog wxComboBox *m_cbRigName; wxComboBox *m_cbSerialPort; wxComboBox *m_cbSerialRate; - Hamlib *m_hamlib; /* Serial Settings */ @@ -69,8 +68,9 @@ class ComPortsDlg : public wxDialog wxRadioButton *m_rbUseRTS; wxCheckBox *m_ckDTRPos; - /* Ok - Cancel - Apply */ + /* Test - Ok - Cancel - Apply */ + wxButton* m_buttonTest; wxButton* m_buttonOK; wxButton* m_buttonCancel; wxButton* m_buttonApply; @@ -82,6 +82,8 @@ protected: void PTTUseHamLibClicked(wxCommandEvent& event); void PTTUseSerialClicked(wxCommandEvent& event); + void OnTest(wxCommandEvent& event); + void OnOK(wxCommandEvent& event); void OnCancel(wxCommandEvent& event); void OnApply(wxCommandEvent& event); diff --git a/freedv-dev/src/fdmdv2_main.cpp b/freedv-dev/src/fdmdv2_main.cpp index 77e1dc26..39f8d178 100644 --- a/freedv-dev/src/fdmdv2_main.cpp +++ b/freedv-dev/src/fdmdv2_main.cpp @@ -279,6 +279,10 @@ MainFrame::MainFrame(wxString plugInName, wxWindow *parent) : TopFrame(plugInNam wxGetApp().m_hamlib = new Hamlib(); + // Init Serialport library, but as for Hamlib we dont start talking to any rigs yet + + wxGetApp().m_serialport = new Serialport(); + tools->AppendSeparator(); wxMenuItem* m_menuItemToolsConfigDelete; m_menuItemToolsConfigDelete = new wxMenuItem(tools, wxID_ANY, wxString(_("&Restore defaults")) , wxT("Delete config file/keys and restore defaults"), wxITEM_NORMAL); @@ -439,7 +443,8 @@ MainFrame::MainFrame(wxString plugInName, wxWindow *parent) : TopFrame(plugInNam wxGetApp().m_boolRTSPos = pConfig->ReadBool(wxT("/Rig/RTSPolarity"), true); wxGetApp().m_boolUseDTR = pConfig->ReadBool(wxT("/Rig/UseDTR"), false); wxGetApp().m_boolDTRPos = pConfig->ReadBool(wxT("/Rig/DTRPolarity"), false); - com_handle = COM_HANDLE_INVALID; + + assert(wxGetApp().m_serialport != NULL); // ----------------------------------------------------------------------- @@ -656,8 +661,8 @@ MainFrame::~MainFrame() stopUDPThread(); #endif - /* TOOD(Joel): the ownership of m_hamlib is probably wrong. */ if (wxGetApp().m_hamlib) delete wxGetApp().m_hamlib; + if (wxGetApp().m_serialport) delete wxGetApp().m_serialport; //MainApp *pApp = wxGetApp(); wxConfigBase *pConfig = wxConfigBase::Get(); @@ -794,187 +799,12 @@ MainFrame::~MainFrame() delete wxConfigBase::Set((wxConfigBase *) NULL); } -//---------------------------------------------------------------- -// closeComPort() closes the currently open com port -//---------------------------------------------------------------- -void MainFrame::closeComPort(void) -{ -#ifdef _WIN32 - CloseHandle(com_handle); -#else - close(com_handle); -#endif - com_handle = COM_HANDLE_INVALID; -} - -//---------------------------------------------------------------- -// openComPort() opens the com port specified by the string -// ie: "COM1" on Windows or "/dev/ttyu0" on FreeBSD -//---------------------------------------------------------------- -bool MainFrame::openComPort(const char *name) -{ - if(com_handle != COM_HANDLE_INVALID) - closeComPort(); -#ifdef _WIN32 - { - COMMCONFIG CC; - DWORD CCsize=sizeof(CC); - COMMTIMEOUTS timeouts; - DCB dcb; - - if(GetDefaultCommConfigA(name, &CC, &CCsize)) { - CC.dcb.fOutxCtsFlow = FALSE; - CC.dcb.fOutxDsrFlow = FALSE; - CC.dcb.fDtrControl = DTR_CONTROL_DISABLE; - CC.dcb.fDsrSensitivity = FALSE; - CC.dcb.fRtsControl = RTS_CONTROL_DISABLE; - SetDefaultCommConfigA(name, &CC, CCsize); - } - - if((com_handle=CreateFileA(name - ,GENERIC_READ|GENERIC_WRITE /* Access */ - ,0 /* Share mode */ - ,NULL /* Security attributes */ - ,OPEN_EXISTING /* Create access */ - ,FILE_ATTRIBUTE_NORMAL /* File attributes */ - ,NULL /* Template */ - ))==INVALID_HANDLE_VALUE) - return false; - - if(GetCommTimeouts(com_handle, &timeouts)) { - timeouts.ReadIntervalTimeout=MAXDWORD; - timeouts.ReadTotalTimeoutMultiplier=0; - timeouts.ReadTotalTimeoutConstant=0; // No-wait read timeout - timeouts.WriteTotalTimeoutMultiplier=0; - timeouts.WriteTotalTimeoutConstant=5000; // 5 seconds - SetCommTimeouts(com_handle,&timeouts); - } - - /* Force N-8-1 mode: */ - if(GetCommState(com_handle, &dcb)==TRUE) { - dcb.ByteSize = 8; - dcb.Parity = NOPARITY; - dcb.StopBits = ONESTOPBIT; - dcb.DCBlength = sizeof(DCB); - dcb.fBinary = TRUE; - dcb.fOutxCtsFlow = FALSE; - dcb.fOutxDsrFlow = FALSE; - dcb.fDtrControl = DTR_CONTROL_DISABLE; - dcb.fDsrSensitivity = FALSE; - dcb.fTXContinueOnXoff= TRUE; - dcb.fOutX = FALSE; - dcb.fInX = FALSE; - dcb.fRtsControl = RTS_CONTROL_DISABLE; - dcb.fAbortOnError = FALSE; - SetCommState(com_handle, &dcb); - } - } -#else - { - struct termios t; - - if((com_handle=open(name, O_NONBLOCK|O_RDWR))==COM_HANDLE_INVALID) - return false; - - if(tcgetattr(com_handle, &t)==-1) { - close(com_handle); - com_handle = COM_HANDLE_INVALID; - return false; - } - - t.c_iflag = ( - IGNBRK /* ignore BREAK condition */ - | IGNPAR /* ignore (discard) parity errors */ - ); - t.c_oflag = 0; /* No output processing */ - t.c_cflag = ( - CS8 /* 8 bits */ - | CREAD /* enable receiver */ - /* - Fun snippet from the FreeBSD manpage: - - If CREAD is set, the receiver is enabled. Otherwise, no character is - received. Not all hardware supports this bit. In fact, this flag is - pretty silly and if it were not part of the termios specification it - would be omitted. - */ - | CLOCAL /* ignore modem status lines */ - ); - t.c_lflag = 0; /* No local modes */ - if(tcsetattr(com_handle, TCSANOW, &t)==-1) { - close(com_handle); - com_handle = COM_HANDLE_INVALID; - return false; - } - - } -#endif - return true; -} #ifdef _USE_ONIDLE void MainFrame::OnIdle(wxIdleEvent &evt) { } #endif -//---------------------------------------------------------------- -// (raise|lower)(RTS|DTR)() -// -// Raises/lowers the specified signal -//---------------------------------------------------------------- -void MainFrame::raiseDTR(void) -{ - if(com_handle == COM_HANDLE_INVALID) - return; -#ifdef _WIN32 - EscapeCommFunction(com_handle, SETDTR); -#else - { // For C89 happiness - int flags = TIOCM_DTR; - ioctl(com_handle, TIOCMBIS, &flags); - } -#endif -} -void MainFrame::raiseRTS(void) -{ - if(com_handle == COM_HANDLE_INVALID) - return; -#ifdef _WIN32 - EscapeCommFunction(com_handle, SETRTS); -#else - { // For C89 happiness - int flags = TIOCM_RTS; - ioctl(com_handle, TIOCMBIS, &flags); - } -#endif -} -void MainFrame::lowerDTR(void) -{ - if(com_handle == COM_HANDLE_INVALID) - return; -#ifdef _WIN32 - EscapeCommFunction(com_handle, CLRDTR); -#else - { // For C89 happiness - int flags = TIOCM_DTR; - ioctl(com_handle, TIOCMBIC, &flags); - } -#endif -} -void MainFrame::lowerRTS(void) -{ - if(com_handle == COM_HANDLE_INVALID) - return; -#ifdef _WIN32 - EscapeCommFunction(com_handle, CLRRTS); -#else - { // For C89 happiness - int flags = TIOCM_RTS; - ioctl(com_handle, TIOCMBIC, &flags); - } -#endif -} - #ifdef _USE_TIMER //---------------------------------------------------------------- @@ -1640,34 +1470,8 @@ void MainFrame::togglePTT(void) { // Serial PTT - /* Truth table: - - g_tx RTSPos RTS - ------------------- - 0 1 0 - 1 1 1 - 0 0 1 - 1 0 0 - - exclusive NOR - */ - - if(wxGetApp().m_boolUseSerialPTT && (com_handle != COM_HANDLE_INVALID)) { - if (wxGetApp().m_boolUseRTS) { - //fprintf(stderr, "g_tx: %d m_boolRTSPos: %d serialLine: %d\n", g_tx, wxGetApp().m_boolRTSPos, g_tx == wxGetApp().m_boolRTSPos); - if (g_tx == wxGetApp().m_boolRTSPos) - raiseRTS(); - else - lowerRTS(); - } - if (wxGetApp().m_boolUseDTR) { - //fprintf(stderr, "g_tx: %d m_boolDTRPos: %d serialLine: %d\n", g_tx, wxGetApp().m_boolDTRPos, g_tx == wxGetApp().m_boolDTRPos); - if (g_tx == wxGetApp().m_boolDTRPos) - raiseDTR(); - else - lowerDTR(); - } - + if (wxGetApp().m_boolUseSerialPTT && (wxGetApp().m_serialport->isopen())) { + wxGetApp().m_serialport->ptt(g_tx); } // reset level gauge @@ -2343,21 +2147,7 @@ void MainFrame::OnToolsComCfg(wxCommandEvent& event) ComPortsDlg *dlg = new ComPortsDlg(NULL); - int rv = dlg->ShowModal(); - - // test Hamlib/Serial set up - - if(rv == wxID_OK) - { - if (wxGetApp().m_boolHamlibUseForPTT) { - OpenHamlibRig(); - wxGetApp().m_hamlib->close(); - } - if (wxGetApp().m_boolUseSerialPTT) { - SetupSerialPort(); - CloseSerialPort(); - } - } + dlg->ShowModal(); delete dlg; } @@ -2595,7 +2385,7 @@ void MainFrame::OnTogBtnOnOff(wxCommandEvent& event) if (wxGetApp().m_boolHamlibUseForPTT) OpenHamlibRig(); if (wxGetApp().m_boolUseSerialPTT) { - SetupSerialPort(); + OpenSerialPort(); } // attempt to start sound cards and tx/rx processing @@ -2642,8 +2432,9 @@ void MainFrame::OnTogBtnOnOff(wxCommandEvent& event) } } - if (wxGetApp().m_boolUseSerialPTT) + if (wxGetApp().m_boolUseSerialPTT) { CloseSerialPort(); + } m_btnTogPTT->SetValue(false); VoiceKeyerProcessEvent(VK_SPACE_BAR); @@ -4036,50 +3827,42 @@ void fdmdv2_clickTune(float freq) { } //---------------------------------------------------------------- -// SetupSerialPort() +// OpenSerialPort() //---------------------------------------------------------------- -void MainFrame::SetupSerialPort(void) + +void MainFrame::OpenSerialPort(void) { - if(!wxGetApp().m_strRigCtrlPort.IsEmpty()) - { - if(openComPort(wxGetApp().m_strRigCtrlPort.c_str())) - { + Serialport *serialport = wxGetApp().m_serialport; + + if(!wxGetApp().m_strRigCtrlPort.IsEmpty()) { + serialport->openport(wxGetApp().m_strRigCtrlPort.c_str(), + wxGetApp().m_boolUseRTS, + wxGetApp().m_boolRTSPos, + wxGetApp().m_boolUseDTR, + wxGetApp().m_boolDTRPos); + if (serialport->isopen()) { // always start PTT in Rx state - SerialPTTRx(); - } - else - { - wxMessageBox("Couldn't open Serial Port", wxT("About"), wxOK | wxICON_ERROR, this); - } + serialport->ptt(false); + } + else { + wxMessageBox("Couldn't open Serial Port", wxT("About"), wxOK | wxICON_ERROR, this); + } } } -void MainFrame::SerialPTTRx(void) -{ - printf("m_boolUseRTS: %d m_boolRTSPos: %d m_boolUseDTR: %d m_boolDTRPos: %d\n", - wxGetApp().m_boolUseRTS, wxGetApp().m_boolRTSPos, wxGetApp().m_boolUseDTR, wxGetApp().m_boolDTRPos); - - if(wxGetApp().m_boolRTSPos) // RTS cleared LOW - lowerRTS(); - else // RTS cleared HIGH - raiseRTS(); - - if(wxGetApp().m_boolDTRPos) // DTR cleared LOW - lowerDTR(); - else // DTR cleared HIGH - raiseDTR(); -} //---------------------------------------------------------------- // CloseSerialPort() //---------------------------------------------------------------- + void MainFrame::CloseSerialPort(void) { - if (com_handle != COM_HANDLE_INVALID) { + Serialport *serialport = wxGetApp().m_serialport; + if (serialport->isopen()) { // always end with PTT in rx state - SerialPTTRx(); - closeComPort(); + serialport->ptt(false); + serialport->closeport(); } } diff --git a/freedv-dev/src/fdmdv2_main.h b/freedv-dev/src/fdmdv2_main.h index 4e11676a..e0740692 100644 --- a/freedv-dev/src/fdmdv2_main.h +++ b/freedv-dev/src/fdmdv2_main.h @@ -30,7 +30,6 @@ #include #include -//#include #include "wx/rawbmp.h" #include "wx/file.h" #include "wx/filename.h" @@ -53,7 +52,6 @@ #include -#include #include #include @@ -87,6 +85,8 @@ #include "sox_biquad.h" #include "comp_prim.h" #include "dlg_plugin.h" +#include "hamlib.h" +#include "serialport.h" #define _USE_TIMER 1 #define _USE_ONIDLE 1 @@ -106,13 +106,6 @@ enum { #define EXCHANGE_DATA_IN 0 #define EXCHANGE_DATA_OUT 1 -#ifdef _WIN32 -#define COM_HANDLE_INVALID INVALID_HANDLE_VALUE -typedef HANDLE com_handle_t; -#else -#define COM_HANDLE_INVALID -1 -typedef int com_handle_t; -#endif extern int g_nSoundCards; extern int g_soundCard1InDeviceNum; @@ -193,6 +186,7 @@ class MainApp : public wxApp bool m_boolRTSPos; bool m_boolUseDTR; bool m_boolDTRPos; + Serialport *m_serialport; // Play/Rec files @@ -447,7 +441,7 @@ class MainFrame : public TopFrame txRxThread* m_txRxThread; bool OpenHamlibRig(); - void SetupSerialPort(void); + void OpenSerialPort(void); void CloseSerialPort(void); void SerialPTTRx(void); @@ -498,20 +492,6 @@ class MainFrame : public TopFrame protected: -#ifdef _WIN32 -#define COM_HANDLE_INVALID INVALID_HANDLE_VALUE - com_handle_t com_handle; -#else -#define COM_HANDLE_INVALID -1 - com_handle_t com_handle; -#endif - void raiseDTR(void); - void lowerDTR(void); - void raiseRTS(void); - void lowerRTS(void); - bool openComPort(const char *port); - void closeComPort(void); - void setsnrBeta(bool snrSlow); // protected event handlers diff --git a/freedv-dev/src/hamlib.cpp b/freedv-dev/src/hamlib.cpp index 4a625606..ff80b24a 100644 --- a/freedv-dev/src/hamlib.cpp +++ b/freedv-dev/src/hamlib.cpp @@ -109,20 +109,25 @@ bool Hamlib::connect(unsigned int rig_index, const char *serial_port, const int } fprintf(stderr, "hamlib: setting serial rate: %d\n", m_rig->state.rigport.parm.serial.rate); - /* - token_t token = rig_token_lookup(m_rig, "rig_pathname"); - - if (rig_set_conf(m_rig, token, serial_port) != RIG_OK) { - return false; - } - */ - if (rig_open(m_rig) == RIG_OK) { return true; } + return false; } +int Hamlib::get_serial_rate(void) { + return m_rig->state.rigport.parm.serial.rate; +} + +int Hamlib::get_data_bits(void) { + return m_rig->state.rigport.parm.serial.data_bits; +} + +int Hamlib::get_stop_bits(void) { + return m_rig->state.rigport.parm.serial.stop_bits; +} + bool Hamlib::ptt(bool press, wxString &hamlibError) { fprintf(stderr,"Hamlib::ptt: %d\n", press); hamlibError = ""; diff --git a/freedv-dev/src/hamlib.h b/freedv-dev/src/hamlib.h index 3ce7e8b5..65af2d46 100644 --- a/freedv-dev/src/hamlib.h +++ b/freedv-dev/src/hamlib.h @@ -16,6 +16,9 @@ class Hamlib { bool connect(unsigned int rig_index, const char *serial_port, const int serial_rate); bool ptt(bool press, wxString &hamlibError); void close(void); + int get_serial_rate(void); + int get_data_bits(void); + int get_stop_bits(void); typedef std::vector riglist_t; diff --git a/freedv-dev/src/serialport.cpp b/freedv-dev/src/serialport.cpp new file mode 100644 index 00000000..ceba8e0d --- /dev/null +++ b/freedv-dev/src/serialport.cpp @@ -0,0 +1,230 @@ +#include +#include +#include +#include "serialport.h" + +Serialport::Serialport() { + com_handle = COM_HANDLE_INVALID; +} + +Serialport::~Serialport() { + if (isopen()) { + closeport(); + } +} + +// returns true if comm port opened OK, false if there was a problem + +bool Serialport::openport(const char name[], bool useRTS, bool RTSPos, bool useDTR, bool DTRPos) +{ + if (com_handle != COM_HANDLE_INVALID) { + closeport(); + } + + m_useRTS = useRTS; + m_RTSPos = RTSPos; + m_useDTR = useDTR; + m_DTRPos = DTRPos; + +#ifdef _WIN32 + { + COMMCONFIG CC; + DWORD CCsize=sizeof(CC); + COMMTIMEOUTS timeouts; + DCB dcb; + + if(GetDefaultCommConfigA(name, &CC, &CCsize)) { + CC.dcb.fOutxCtsFlow = FALSE; + CC.dcb.fOutxDsrFlow = FALSE; + CC.dcb.fDtrControl = DTR_CONTROL_DISABLE; + CC.dcb.fDsrSensitivity = FALSE; + CC.dcb.fRtsControl = RTS_CONTROL_DISABLE; + SetDefaultCommConfigA(name, &CC, CCsize); + } + + if((com_handle=CreateFileA(name + ,GENERIC_READ|GENERIC_WRITE /* Access */ + ,0 /* Share mode */ + ,NULL /* Security attributes */ + ,OPEN_EXISTING /* Create access */ + ,FILE_ATTRIBUTE_NORMAL /* File attributes */ + ,NULL /* Template */ + ))==INVALID_HANDLE_VALUE) + return false; + + if(GetCommTimeouts(com_handle, &timeouts)) { + timeouts.ReadIntervalTimeout=MAXDWORD; + timeouts.ReadTotalTimeoutMultiplier=0; + timeouts.ReadTotalTimeoutConstant=0; // No-wait read timeout + timeouts.WriteTotalTimeoutMultiplier=0; + timeouts.WriteTotalTimeoutConstant=5000; // 5 seconds + SetCommTimeouts(com_handle,&timeouts); + } + + /* Force N-8-1 mode: */ + if(GetCommState(com_handle, &dcb)==TRUE) { + dcb.ByteSize = 8; + dcb.Parity = NOPARITY; + dcb.StopBits = ONESTOPBIT; + dcb.DCBlength = sizeof(DCB); + dcb.fBinary = TRUE; + dcb.fOutxCtsFlow = FALSE; + dcb.fOutxDsrFlow = FALSE; + dcb.fDtrControl = DTR_CONTROL_DISABLE; + dcb.fDsrSensitivity = FALSE; + dcb.fTXContinueOnXoff= TRUE; + dcb.fOutX = FALSE; + dcb.fInX = FALSE; + dcb.fRtsControl = RTS_CONTROL_DISABLE; + dcb.fAbortOnError = FALSE; + SetCommState(com_handle, &dcb); + } + } +#else + { + struct termios t; + + if((com_handle=open(name, O_NONBLOCK|O_RDWR))== COM_HANDLE_INVALID) + return false; + + if(tcgetattr(com_handle, &t)==-1) { + close(com_handle); + com_handle = COM_HANDLE_INVALID; + return false; + } + + t.c_iflag = ( + IGNBRK /* ignore BREAK condition */ + | IGNPAR /* ignore (discard) parity errors */ + ); + t.c_oflag = 0; /* No output processing */ + t.c_cflag = ( + CS8 /* 8 bits */ + | CREAD /* enable receiver */ + /* + Fun snippet from the FreeBSD manpage: + + If CREAD is set, the receiver is enabled. Otherwise, no character is + received. Not all hardware supports this bit. In fact, this flag is + pretty silly and if it were not part of the termios specification it + would be omitted. + */ + | CLOCAL /* ignore modem status lines */ + ); + t.c_lflag = 0; /* No local modes */ + if(tcsetattr(com_handle, TCSANOW, &t)==-1) { + close(com_handle); + com_handle = COM_HANDLE_INVALID; + return false; + } + + } +#endif + return true; +} + + +void Serialport::closeport() +{ +#ifdef _WIN32 + CloseHandle(com_handle); +#else + close(com_handle); +#endif + com_handle = COM_HANDLE_INVALID; +} + +//---------------------------------------------------------------- +// (raise|lower)(RTS|DTR)() +// +// Raises/lowers the specified signal +//---------------------------------------------------------------- + +void Serialport::raiseDTR(void) +{ + if(com_handle == COM_HANDLE_INVALID) + return; +#ifdef _WIN32 + EscapeCommFunction(com_handle, SETDTR); +#else + { // For C89 happiness + int flags = TIOCM_DTR; + ioctl(com_handle, TIOCMBIS, &flags); + } +#endif +} + +void Serialport::raiseRTS(void) +{ + if(com_handle == COM_HANDLE_INVALID) + return; +#ifdef _WIN32 + EscapeCommFunction(com_handle, SETRTS); +#else + { // For C89 happiness + int flags = TIOCM_RTS; + ioctl(com_handle, TIOCMBIS, &flags); + } +#endif +} + +void Serialport::lowerDTR(void) +{ + if(com_handle == COM_HANDLE_INVALID) + return; +#ifdef _WIN32 + EscapeCommFunction(com_handle, CLRDTR); +#else + { // For C89 happiness + int flags = TIOCM_DTR; + ioctl(com_handle, TIOCMBIC, &flags); + } +#endif +} + +void Serialport::lowerRTS(void) +{ + if(com_handle == COM_HANDLE_INVALID) + return; +#ifdef _WIN32 + EscapeCommFunction(com_handle, CLRRTS); +#else + { // For C89 happiness + int flags = TIOCM_RTS; + ioctl(com_handle, TIOCMBIC, &flags); + } +#endif +} + +void Serialport::ptt(bool tx) { + + /* Truth table: + + g_tx RTSPos RTS + ------------------- + 0 1 0 + 1 1 1 + 0 0 1 + 1 0 0 + + exclusive NOR + */ + + if (com_handle != COM_HANDLE_INVALID) { + if (m_useRTS) { + //fprintf(stderr, "g_tx: %d m_boolRTSPos: %d serialLine: %d\n", g_tx, wxGetApp().m_boolRTSPos, g_tx == wxGetApp().m_boolRTSPos); + if (tx == m_RTSPos) + raiseRTS(); + else + lowerRTS(); + } + if (m_useDTR) { + //fprintf(stderr, "g_tx: %d m_boolDTRPos: %d serialLine: %d\n", g_tx, wxGetApp().m_boolDTRPos, g_tx == wxGetApp().m_boolDTRPos); + if (tx == m_DTRPos) + raiseDTR(); + else + lowerDTR(); + } + + } +} diff --git a/freedv-dev/src/serialport.h b/freedv-dev/src/serialport.h new file mode 100644 index 00000000..e5db10b4 --- /dev/null +++ b/freedv-dev/src/serialport.h @@ -0,0 +1,42 @@ +#ifndef SERIALPORT_H +#define SERIALPORT_H + +#ifdef _WIN32 +#include +#else +#include +#include +#include +#endif + +// Serial ports called com port for historic reasons, especially on Windows machines + +#ifdef _WIN32 +#define COM_HANDLE_INVALID INVALID_HANDLE_VALUE +typedef HANDLE com_handle_t; +#else +#define COM_HANDLE_INVALID -1 +typedef int com_handle_t; +#endif + +class Serialport { + + public: + Serialport(); + ~Serialport(); + bool openport(const char port[], bool useRTS, bool RTSPos, bool useDTR, bool DTRPos); + bool isopen() {return (com_handle != COM_HANDLE_INVALID);} + void closeport(); + void ptt(bool tx); + + private: + com_handle_t com_handle; + bool m_useRTS, m_RTSPos, m_useDTR, m_DTRPos; + + void raiseDTR(void); + void lowerDTR(void); + void raiseRTS(void); + void lowerRTS(void); +}; + +#endif /* SERIALPORT_H */