Skip to content

Commit

Permalink
SX-AO-LF support for Linux. V000 firmware warning.
Browse files Browse the repository at this point in the history
  • Loading branch information
d33psky committed Mar 28, 2016
1 parent 1f798c6 commit c648042
Show file tree
Hide file tree
Showing 7 changed files with 387 additions and 4 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,8 @@ set(phd2_SRC
${phd_src_dir}/serialport_mac.h
${phd_src_dir}/serialport_win32.cpp
${phd_src_dir}/serialport_win32.h
${phd_src_dir}/serialport_posix.cpp
${phd_src_dir}/serialport_posix.h
${phd_src_dir}/serialports.h
${phd_src_dir}/socket_server.cpp
${phd_src_dir}/socket_server.h
Expand Down
2 changes: 2 additions & 0 deletions serialport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ SerialPort *SerialPort::SerialPortFactory(void)
{
#if defined(_WINDOWS_)
return new SerialPortWin32();
#elif defined(__LINUX__)
return new SerialPortPosix();
#else
return 0;
#endif
Expand Down
282 changes: 282 additions & 0 deletions serialport_posix.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,282 @@
/*
* serialport_posix.cpp
* PHD Guiding
*
* Created by Hans Lambermont
* Copyright (c) 2016 Hans Lambermont
* All rights reserved.
*
* This source code is distributed under the following "BSD" license
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name Craig Stark, Stark Labs nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/

#include "phd.h"

#if defined (__LINUX__)

#include <termios.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <errno.h>

wxArrayString SerialPortPosix::GetSerialPortList(void)
{
wxArrayString ret;

// TODO generate this list
ret.Add("/dev/ttyS0");
ret.Add("/dev/ttyS1");
ret.Add("/dev/ttyUSB0");
ret.Add("/dev/ttyUSB1");
ret.Add("/dev/sx-ao-lf");

return ret;
}

SerialPortPosix::SerialPortPosix(void)
{
m_fd = -1;
}

SerialPortPosix::~SerialPortPosix(void)
{
if (m_fd > 0) {
close(m_fd);
m_fd = -1;
}
}

bool SerialPortPosix::Connect(const wxString& portName, int baud, int dataBits, int stopBits, PARITY Parity, bool useRTS, bool useDTR)
{
bool bError = false;

try {
if ((m_fd = open(portName, O_RDWR|O_NOCTTY)) < 0) {
wxString exposeToUser = wxString::Format("open %s failed %s(%d)", portName, strerror((int)errno), (int)errno);
throw ERROR_INFO("SerialPortPosix::Connect " + exposeToUser);
}

struct termios attr;

if (tcgetattr(m_fd, &attr) < 0 ) {
wxString errorWxs = wxString::Format("tcgetattr failed %s(%d)", strerror((int)errno), (int)errno);
throw ERROR_INFO("SerialPortPosix::Connect " + errorWxs);
}

attr.c_iflag = 0; // input modes
attr.c_oflag = 0; // output modes
attr.c_cflag = CLOCAL; // CLOCAL == Ignore modem control lines.
attr.c_cflag |= CREAD ; // CREAD == Enable receiver.
switch (dataBits) {
case 7:
attr.c_cflag |= CS7; // 7 bit Character size mask.
break;
case 8:
attr.c_cflag |= CS8; // 8 bit Character size mask.
break;
default:
throw ERROR_INFO("SerialPortPosix::Connect unsupported amount of dataBits");
break;
}
switch (stopBits) {
case 1:
break;
case 2:
attr.c_cflag |= CSTOPB; // 2 stop bits
break;
default:
throw ERROR_INFO("SerialPortPosix::Connect invalid amount of stopBits");
break;
}
switch (Parity) {
case ParityNone:
break;
case ParityOdd:
attr.c_cflag |= PARENB | PARODD;
break;
case ParityEven:
attr.c_cflag |= PARENB; // Enable parity generation on output and parity checking for input.
break;
case ParityMark: // TODO, not in POSIX. CMSPAR
case ParitySpace: // TODO, not in POSIX. CMSPAR
default:
throw ERROR_INFO("SerialPortPosix::Connect invalid parity");
break;
}
attr.c_lflag &= ~ICANON; // Do not wait for a line delimiter. Work in noncanonical mode.
attr.c_lflag &= ~( ECHO | ECHOE | ISIG | IEXTEN | NOFLSH | TOSTOP); // local modes
attr.c_lflag |= NOFLSH;
attr.c_cc[VTIME] = (uint8_t)0; // timeout in deciseconds
attr.c_cc[VMIN] = (uint8_t)0; // minimum number of characters for noncanonical read

unsigned int speed = B0;
switch (baud) {
case 9600: speed = B9600; break;
case 19200: speed = B19200; break;
case 38400: speed = B38400; break;
case 57600: speed = B57600; break;
case 115200: speed = B115200; break;
case 230400: speed = B230400; break;
default:
throw ERROR_INFO("SerialPortPosix::Connect unsupported baudrate");
break;
}
if ((cfsetispeed(&attr, speed) < 0) || (cfsetospeed(&attr, speed) <0)) {
throw ERROR_INFO("cfsetispeed failed");
}

if (tcsetattr(m_fd, TCSAFLUSH, &attr) < 0 ) {
wxString errowWxs = wxString::Format("tcsetattr failed %s(%d)", strerror((int)errno), (int)errno);
throw ERROR_INFO("SerialPortPosix::Connect " + errowWxs);
}

int ioctl_ret = 0;
unsigned int argp;

if ((ioctl_ret = ioctl(m_fd, TIOCMGET, &argp) < 0)) {
throw ERROR_INFO("ioctl TIOCMGET");
}
if (useDTR) {
argp |= TIOCM_DTR;
}
if (useRTS) {
argp |= TIOCM_RTS;
}
if ((ioctl_ret = ioctl(m_fd, TIOCMSET, &argp) < 0)) {
throw ERROR_INFO("ioctl TIOCMSET");
}
}
catch (wxString Msg)
{
POSSIBLY_UNUSED(Msg);
bError = true;
}

return bError;
}

bool SerialPortPosix::Disconnect(void)
{
bool bError = false;

try {
if ( ! close(m_fd)) {
throw ERROR_INFO("SerialPortPosix: close failed");
}
} catch (wxString Msg) {
POSSIBLY_UNUSED(Msg);
bError = true;
}

m_fd = -1;

return bError;
}

bool SerialPortPosix::SetReceiveTimeout(int timeoutMilliSeconds)
{
bool bError = false;

Debug.AddLine(wxString::Format("SerialPortPosix::SetReceiveTimeout %d ms", timeoutMilliSeconds));
try {
struct termios attr;

if (tcgetattr(m_fd, &attr) < 0 ) {
throw ERROR_INFO("tcgetattr failed");
}
int timeoutDeciSeconds = (timeoutMilliSeconds + 99) / 100;
attr.c_cc[VTIME] = (uint8_t)timeoutDeciSeconds;
if (tcsetattr(m_fd, TCSAFLUSH, &attr) < 0 ) {
throw ERROR_INFO("tcsetattr failed");
}
} catch (wxString Msg) {
POSSIBLY_UNUSED(Msg);
bError = true;
}

return bError;
}

bool SerialPortPosix::Send(const unsigned char *pData, unsigned count)
{
bool bError = false;

try {
int nBytesWritten = 0;

Debug.AddBytes("SerialPortPosix::Send", pData, count);

if ((nBytesWritten = write(m_fd, pData, count)) < 0) {
throw ERROR_INFO("SerialPortPosix: write failed");
}

if (nBytesWritten != count) {
throw ERROR_INFO("SerialPortPosix: nBytesWritten != count");
}

} catch (wxString Msg) {
POSSIBLY_UNUSED(Msg);
bError = true;
}

return bError;
}

bool SerialPortPosix::Receive(unsigned char *pData, unsigned count)
{
bool bError = false;

try {
int receiveCount;

if ((receiveCount = read(m_fd, pData, count)) < 0 ) {
throw ERROR_INFO("SerialPortPosix: read Failed");
}

if (receiveCount != count) {
throw ERROR_INFO("SerialPortPosix: recieveCount " + wxString::Format(wxT("%i"),receiveCount) + " != count " + wxString::Format(wxT("%i"),count) );
}

Debug.AddBytes("SerialPortPosix::Receive", pData, receiveCount);

} catch (wxString Msg) {
POSSIBLY_UNUSED(Msg);
bError = true;
}

return bError;
}

bool SerialPortPosix::SetRTS(bool asserted)
{
return true; // TODO
}

bool SerialPortPosix::SetDTR(bool asserted)
{
return true; // TODO
}

#endif // __LINUX__
61 changes: 61 additions & 0 deletions serialport_posix.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* serialport_posix.h
* PHD Guiding
*
* Created by Hans Lambermont
* Copyright (c) 2016 Hans Lambermont
* All rights reserved.
*
* This source code is distributed under the following "BSD" license
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name Craig Stark, Stark Labs nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/

#if !defined(SERIALPORT_POSIX_H_INCLUDED) && defined (__LINUX__)
#define SERIALPORT_POSIX_H_INCLUDED

class SerialPortPosix : public SerialPort
{
int m_fd;

public:

wxArrayString GetSerialPortList(void);

SerialPortPosix(void);
virtual ~SerialPortPosix(void);

virtual bool Connect(const wxString& portName, int baud, int dataBits, int stopBits, PARITY Parity, bool useRTS, bool useDTR);
virtual bool Disconnect(void);

virtual bool Send(const unsigned char *pData, unsigned count);

virtual bool SetReceiveTimeout(int timeoutMilliSeconds);
virtual bool Receive(unsigned char *pData, unsigned count);

virtual bool SetRTS(bool asserted);
virtual bool SetDTR(bool asserted);
};

#endif // SERIALPORT_POSIX_H_INCLUDED
1 change: 1 addition & 0 deletions serialports.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include "serialport.h"
#include "serialport_win32.h"
#include "serialport_mac.h"
#include "serialport_posix.h"

#ifdef USE_LOOPBACK_SERIAL
#include "serialport_loopback.h"
Expand Down
Loading

0 comments on commit c648042

Please sign in to comment.