2010-08-09 13:28:56 +00:00
|
|
|
#ifndef NALL_SERIAL_HPP
|
|
|
|
#define NALL_SERIAL_HPP
|
|
|
|
|
2013-05-02 11:25:45 +00:00
|
|
|
#include <nall/intrinsics.hpp>
|
|
|
|
#include <nall/stdint.hpp>
|
|
|
|
#include <nall/string.hpp>
|
|
|
|
|
Update to v094r08 release.
byuu says:
Lots of changes this time around. FreeBSD stability and compilation is
still a work in progress.
FreeBSD 10 + Clang 3.3 = 108fps
FreeBSD 10 + GCC 4.7 = 130fps
Errata 1: I've been fighting that god-damned endian.h header for the
past nine WIPs now. The above WIP isn't building now because FreeBSD
isn't including headers before using certain types, and you end up with
a trillion error messages. So just delete all the endian.h includes from
nall/intrinsics.hpp to build.
Errata 2: I was trying to match g++ and g++47, so I used $(findstring
g++,$(compiler)), which ends up also matching clang++. Oops. Easy fix,
put Clang first and then else if g++ next. Not ideal, but oh well. All
it's doing for now is declaring -fwrapv twice, so you don't have to fix
it just yet. Probably just going to alias g++="g++47" and do exact
matching instead.
Errata 3: both OpenGL::term and VideoGLX::term are causing a core dump
on BSD. No idea why. The resources are initialized and valid, but
releasing them crashes the application.
Changelog:
- nall/Makefile is more flexible with overriding $(compiler), so you can
build with GCC or Clang on BSD (defaults to GCC now)
- PLATFORM_X was renamed to PLATFORM_XORG, and it's also declared with
PLATFORM_LINUX or PLATFORM_BSD
- PLATFORM_XORG probably isn't the best name ... still thinking about
what best to call LINUX|BSD|SOLARIS or ^(WINDOWS|MACOSX)
- fixed a few legitimate Clang warning messages in nall
- Compiler::VisualCPP is ugly as hell, renamed to Compiler::CL
- nall/platform includes nall/intrinsics first. Trying to move away from
testing for _WIN32, etc directly in all files. Work in progress.
- nall turns off Clang warnings that I won't "fix", because they aren't
broken. It's much less noisy to compile with warnings on now.
- phoenix gains the ability to set background and foreground colors on
various text container widgets (GTK only for now.)
- rewrote a lot of the MSU1 code to try and simplify it. Really hope
I didn't break anything ... I don't have any MSU1 test ROMs handy
- SNES coprocessor audio is now mixed as sclamp<16>(system_sample
+ coprocessor_sample) instead of sclamp<16>((sys + cop) / 2)
- allows for greater chance of aliasing (still low, SNES audio is
quiet), but doesn't cut base system volume in half anymore
- fixed Super Scope and Justifier cursor colors
- use input.xlib instead of input.x ... allows Xlib input driver to be
visible on Linux and BSD once again
- make install and make uninstall must be run as root again; no longer
using install but cp instead for BSD compatibility
- killed $(DESTDIR) ... use make prefix=$DESTDIR$prefix instead
- you can now set text/background colors for the loki console via (eg):
- settings.terminal.background-color 0x000000
- settings.terminal.foreground-color 0xffffff
2014-02-24 09:39:09 +00:00
|
|
|
#if !defined(PLATFORM_XORG) && !defined(PLATFORM_MACOSX)
|
2013-05-02 11:25:45 +00:00
|
|
|
#error "nall/serial: unsupported platform"
|
|
|
|
#endif
|
|
|
|
|
2010-08-09 13:28:56 +00:00
|
|
|
#include <sys/ioctl.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <termios.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
namespace nall {
|
2012-03-10 12:47:19 +00:00
|
|
|
|
2013-05-02 11:25:45 +00:00
|
|
|
struct serial {
|
|
|
|
bool readable() {
|
|
|
|
if(port_open == false) return false;
|
|
|
|
fd_set fdset;
|
|
|
|
FD_ZERO(&fdset);
|
|
|
|
FD_SET(port, &fdset);
|
|
|
|
timeval timeout;
|
|
|
|
timeout.tv_sec = 0;
|
|
|
|
timeout.tv_usec = 0;
|
|
|
|
int result = select(FD_SETSIZE, &fdset, nullptr, nullptr, &timeout);
|
|
|
|
if(result < 1) return false;
|
|
|
|
return FD_ISSET(port, &fdset);
|
|
|
|
}
|
|
|
|
|
|
|
|
//-1 on error, otherwise return bytes read
|
|
|
|
int read(uint8_t* data, unsigned length) {
|
|
|
|
if(port_open == false) return -1;
|
|
|
|
return ::read(port, (void*)data, length);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool writable() {
|
|
|
|
if(port_open == false) return false;
|
|
|
|
fd_set fdset;
|
|
|
|
FD_ZERO(&fdset);
|
|
|
|
FD_SET(port, &fdset);
|
|
|
|
timeval timeout;
|
|
|
|
timeout.tv_sec = 0;
|
|
|
|
timeout.tv_usec = 0;
|
|
|
|
int result = select(FD_SETSIZE, nullptr, &fdset, nullptr, &timeout);
|
|
|
|
if(result < 1) return false;
|
|
|
|
return FD_ISSET(port, &fdset);
|
|
|
|
}
|
|
|
|
|
|
|
|
//-1 on error, otherwise return bytes written
|
|
|
|
int write(const uint8_t* data, unsigned length) {
|
|
|
|
if(port_open == false) return -1;
|
|
|
|
return ::write(port, (void*)data, length);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool open(const string& portname, unsigned rate, bool flowcontrol) {
|
|
|
|
close();
|
|
|
|
|
|
|
|
port = ::open(portname, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK);
|
|
|
|
if(port == -1) return false;
|
|
|
|
|
|
|
|
if(ioctl(port, TIOCEXCL) == -1) { close(); return false; }
|
|
|
|
if(fcntl(port, F_SETFL, 0) == -1) { close(); return false; }
|
|
|
|
if(tcgetattr(port, &original_attr) == -1) { close(); return false; }
|
|
|
|
|
|
|
|
termios attr = original_attr;
|
|
|
|
cfmakeraw(&attr);
|
|
|
|
cfsetspeed(&attr, rate);
|
|
|
|
|
|
|
|
attr.c_lflag &=~ (ECHO | ECHONL | ISIG | ICANON | IEXTEN);
|
|
|
|
attr.c_iflag &=~ (BRKINT | PARMRK | INPCK | ISTRIP | INLCR | IGNCR | ICRNL | IXON | IXOFF | IXANY);
|
|
|
|
attr.c_iflag |= (IGNBRK | IGNPAR);
|
|
|
|
attr.c_oflag &=~ (OPOST);
|
|
|
|
attr.c_cflag &=~ (CSIZE | CSTOPB | PARENB | CLOCAL);
|
|
|
|
attr.c_cflag |= (CS8 | CREAD);
|
|
|
|
if(flowcontrol == false) {
|
|
|
|
attr.c_cflag &= ~CRTSCTS;
|
|
|
|
} else {
|
|
|
|
attr.c_cflag |= CRTSCTS;
|
2010-08-09 13:28:56 +00:00
|
|
|
}
|
2013-05-02 11:25:45 +00:00
|
|
|
attr.c_cc[VTIME] = attr.c_cc[VMIN] = 0;
|
|
|
|
|
|
|
|
if(tcsetattr(port, TCSANOW, &attr) == -1) { close(); return false; }
|
|
|
|
return port_open = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void close() {
|
|
|
|
if(port != -1) {
|
|
|
|
tcdrain(port);
|
|
|
|
if(port_open == true) {
|
|
|
|
tcsetattr(port, TCSANOW, &original_attr);
|
|
|
|
port_open = false;
|
2010-08-23 08:02:38 +00:00
|
|
|
}
|
2013-05-02 11:25:45 +00:00
|
|
|
::close(port);
|
|
|
|
port = -1;
|
2010-08-09 13:28:56 +00:00
|
|
|
}
|
2013-05-02 11:25:45 +00:00
|
|
|
}
|
2010-08-09 13:28:56 +00:00
|
|
|
|
2013-05-02 11:25:45 +00:00
|
|
|
serial() {
|
|
|
|
port = -1;
|
|
|
|
port_open = false;
|
|
|
|
}
|
2010-08-09 13:28:56 +00:00
|
|
|
|
2013-05-02 11:25:45 +00:00
|
|
|
~serial() {
|
|
|
|
close();
|
|
|
|
}
|
2010-08-09 13:28:56 +00:00
|
|
|
|
2013-05-02 11:25:45 +00:00
|
|
|
private:
|
|
|
|
int port;
|
|
|
|
bool port_open;
|
|
|
|
termios original_attr;
|
|
|
|
};
|
2010-08-09 13:28:56 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|