From c5cfbf4ecbb31adbaa2ed1a93e693b3d8800eda1 Mon Sep 17 00:00:00 2001 From: Jochen Friedrich Date: Mon, 14 Apr 2014 17:54:21 +0200 Subject: [PATCH] Initial commit --- FHEM/00_EB.pm | 152 +++++++++++++++++++++++ FHEM/18_EBN.pm | 292 ++++++++++++++++++++++++++++++++++++++++++++ ebd/AUTHORS | 0 ebd/ChangeLog | 0 ebd/Makefile.am | 1 + ebd/NEWS | 0 ebd/README | 0 ebd/configure.ac | 15 +++ ebd/src/Makefile.am | 6 + ebd/src/main.c | 245 +++++++++++++++++++++++++++++++++++++ ebd/src/rs485.c | 143 ++++++++++++++++++++++ ebd/src/rs485.h | 6 + 12 files changed, 860 insertions(+) create mode 100755 FHEM/00_EB.pm create mode 100755 FHEM/18_EBN.pm create mode 100644 ebd/AUTHORS create mode 100644 ebd/ChangeLog create mode 100644 ebd/Makefile.am create mode 100644 ebd/NEWS create mode 100644 ebd/README create mode 100644 ebd/configure.ac create mode 100644 ebd/src/Makefile.am create mode 100644 ebd/src/main.c create mode 100644 ebd/src/rs485.c create mode 100644 ebd/src/rs485.h diff --git a/FHEM/00_EB.pm b/FHEM/00_EB.pm new file mode 100755 index 0000000..9a28b1b --- /dev/null +++ b/FHEM/00_EB.pm @@ -0,0 +1,152 @@ +############################################## + +package main; + +use strict; +use warnings; +use Time::HiRes qw(gettimeofday); +use IPC::Open2; + +sub FHZ_Write($$$); +sub FHZ_Read($); +sub FHZ_Ready($); + +sub +EB_Initialize($) +{ + my ($hash) = @_; + +# Provider + $hash->{ReadyFn} = "EB_Ready"; + $hash->{ReadFn} = "EB_Read"; + $hash->{WriteFn} = "EB_Write"; + $hash->{Clients} = ":EB:EBN:"; + + my %mc = ( + "1:EBN" => "^R", + ); + $hash->{MatchList} = \%mc; + +# Normal devices + $hash->{DefFn} = "EB_Define"; + $hash->{UndefFn} = "EB_Undef"; + $hash->{SetFn} = "EB_Set"; + $hash->{AttrList}= "loglevel:0,1,2,3,4,5,6"; +} + +sub +EB_Define($$) +{ + my ($hash, $def) = @_; + my @a = split("[ \t][ \t]*", $def); + + Log 3, "$hash->{NAME} define "; + if(@a < 3 || @a > 3) { + my $msg = "wrong syntax: define EB {devicename}"; + Log 2, $msg; + Log 2, @a; + return $msg; + } + my $name = $a[0]; + my $dev = $a[2]; + + $hash->{DeviceName} = $dev; + + my($pid, $chld_out, $chld_in); + $pid = open2($chld_out, $chld_in, '/root/ebd -d '.$dev); + + $hash->{RDPIPE} = $chld_out; + $hash->{WRPIPE} = $chld_in; + $hash->{FD} = fileno($chld_out); + $hash->{PID} = $pid; + $hash->{STATE} = "Open"; + $selectlist{"$name.pipe"} = $hash; + return undef; +} + +##################################### +sub +EB_Undef($$) +{ + my ($hash, $arg) = @_; + + Log 3, "$hash->{NAME} undef"; + return if ($hash->{STATE} ne "Open"); + + EB_Write($hash,'Q',''); + + kill $hash->{PID}; + close($hash->{RDPIPE}); + close($hash->{WRPIPE}); + + delete $hash->{FD}; + delete $hash->{RDPIPE}; + delete $hash->{WRPIPE}; + delete $hash->{PID}; + + $hash->{STATE} = "Closed"; + return undef; +} + +##################################### +sub +EB_Ready($) +{ + my ($hash,$fn,$msg) = @_; + Log 5, "$hash->{NAME} ready"; + return 1; +} + +##################################### +sub +EB_Write($$$) +{ + my ($hash,$fn,$msg) = @_; + my ($buf); + + $buf = $fn . ' ' . $msg; + Log 5, "$hash->{NAME} write: " . $buf; + $buf .= "\n"; + syswrite($hash->{WRPIPE}, $buf); + + return undef; +} + +##################################### +sub +EB_Read($) +{ + my ($hash) = @_; + my ($buf, $res, $nextbyte); + + + CHAR: while (sysread($hash->{RDPIPE}, $nextbyte, 1)) { + last CHAR if $nextbyte eq "\n"; + $buf .= $nextbyte; + } + + Log 5, "$hash->{NAME} read: " . $buf; + $hash->{RAWMSG} = $buf; + Dispatch($hash, $buf, undef); + return $buf; +} + +##################################### +sub +EB_Set($@) +{ + my ($hash, @a) = @_; + + my $name = shift @a; + my $type = shift @a; + my $arg = join(" ", @a); + + return "Unknown argument $type, choose one of raw" if($type ne "raw"); + + $arg .= "\n"; + + syswrite($hash->{WRPIPE}, $arg); + return undef; +} + +1; diff --git a/FHEM/18_EBN.pm b/FHEM/18_EBN.pm new file mode 100755 index 0000000..2a8d538 --- /dev/null +++ b/FHEM/18_EBN.pm @@ -0,0 +1,292 @@ +package main; + +use strict; +use warnings; + +sub +EBN_Initialize($) +{ + my ($hash) = @_; + + $hash->{Match} = "^R"; + $hash->{DefFn} = "EBN_Define"; + $hash->{ParseFn} = "EBN_Parse"; + $hash->{GetFn} = "EBN_Get"; + $hash->{SetFn} = "EBN_Set"; + $hash->{AttrList} = "IODev loglevel:0,1,2,3,4,5,6"; + +} + +############################# +sub +EBN_Define($$) +{ + my ($hash, $def) = @_; + my @a = split("[ \t][ \t]*", $def); + + my $u = "wrong syntax: define EBN addr type"; + + return "wrong syntax: define EBN addr type" if(int(@a) != 4); + + $modules{EBN}{defptr}{$a[2]} = $hash; + $hash->{STATE} = "Defined"; + $hash->{EBTYPE} = $a[3]; + $hash->{ADDR} = $a[2]; + $hash->{channel1} = "Init"; + AssignIoPort($hash); + return undef; +} + +sub +EBN_Parse($$) +{ + my ($hash, $msg) = @_; + + # Msg format: R addr chan value + my @cmp = split(" ", $msg); + my $def = $modules{EBN}{defptr}{$cmp[1]}; + my $changed; + my $log; + my $v1; + my $v2; + my $v3; + my $v4; + + Log 5, "$hash->{NAME} parse: " . $msg; + + if($def) { + my $name = $def->{NAME}; + if ($cmp[2] == 0) { + IOWrite($def, "R", $cmp[1]. " 1 0"); + return $name; + } + +# TYPE 1: Test Node +# Channel 1: +# Bit 0 : Test LED +# Bit 1 : Exp LED +# Channel 2: +# Vcc + + $changed = 0; + $v1 = $cmp[3] & 0x1; + $v2 = $cmp[3] & 0x2; + $v3 = $cmp[3] & 0x4; + $v4 = $cmp[3] & 0x8; + + if ($def->{EBTYPE} == 1) { + if ($cmp[2] == 1) { + if (($v1 != ($def->{channel1} & 0x1)) || ($def->{channel1} eq "Init")) { + $def->{READINGS}{testled}{TIME} = TimeNow(); + $def->{READINGS}{testled}{VAL} = $v1 ? "on" : "off"; + $changed = 1; + } + if (($v2 != ($def->{channel1} & 0x2)) || ($def->{channel1} eq "Init")) { + $def->{READINGS}{expled}{TIME} = TimeNow(); + $def->{READINGS}{expled}{VAL} = $v2 ? "on" : "off"; + $changed = 1; + } + if ($def->{channel1} eq "Init") { + IOWrite($def, "R", $cmp[1]. " 2 0"); + } + $def->{channel1} = $cmp[3]; + if ($changed == 1) { + $log = "testled: " . ($v1 ? "on" : "off") . " expled: " . ($v2 ? "on" : "off"); + $def->{STATE} = $log; + push @{$def->{CHANGED}}, $log; + DoTrigger($def->{NAME}, undef); + } + } + if ($cmp[2] == 2) { + $def->{READINGS}{vcc}{TIME} = TimeNow(); + $def->{READINGS}{vcc}{VAL} = $cmp[3]; + } + } + +# TYPE 2: Alarm Node +# Channel 1: +# Bit 0 : Tuerkontakt +# Bit 1 : Buzzer aus +# Channel 2: +# Vcc + + if ($def->{EBTYPE} == 2) { + if ($cmp[2] == 1) { + if (($v1 != ($def->{channel1} & 0x1)) || ($def->{channel1} eq "Init")) { + $def->{READINGS}{tuer}{TIME} = TimeNow(); + $def->{READINGS}{tuer}{VAL} = $v1 ? "closed" : "open"; + $changed = 1; + } + if (($v2 != ($def->{channel1} & 0x2)) || ($def->{channel1} eq "Init")) { + $def->{READINGS}{buzzer}{TIME} = TimeNow(); + $def->{READINGS}{buzzer}{VAL} = $v2 ? "disabled" : "enabled"; + $changed = 1; + } + if ($def->{channel1} eq "Init") { + IOWrite($def, "R", $cmp[1]. " 2 0"); + } + $def->{channel1} = $cmp[3]; + if ($changed == 1) { + $log = "tuer: ". ($v1 ? "closed" : "open") . " buzzer: " . ($v2 ? "disabled" : "enabled"); + $def->{STATE} = $log; + push @{$def->{CHANGED}}, $log; + DoTrigger($def->{NAME}, undef); + } + } + if ($cmp[2] == 2) { + $def->{READINGS}{vcc}{TIME} = TimeNow(); + $def->{READINGS}{vcc}{VAL} = $cmp[3]; + } + } + +# TYPE 3: Relais Node +# Channel 1: +# Bit 0 : LED +# Bit 1 : Relais 1 +# Bit 2 : Relais 2 + + if ($def->{EBTYPE} == 3) { + if ($cmp[2] == 1) { + if (($v1 != ($def->{channel1} & 0x1)) || ($def->{channel1} eq "Init")) { + $def->{READINGS}{led}{TIME} = TimeNow(); + $def->{READINGS}{led}{VAL} = $v1 ? "on": "off"; + $changed = 1; + } + if (($v2 != ($def->{channel1} & 0x2)) || ($def->{channel1} eq "Init")) { + $def->{READINGS}{relais1}{TIME} = TimeNow(); + $def->{READINGS}{relais1}{VAL} = $v2 ? "on": "off"; + $changed = 1; + } + if (($v3 != ($def->{channel1} & 0x4)) || ($def->{channel1} eq "Init")) { + $def->{READINGS}{relais2}{TIME} = TimeNow(); + $def->{READINGS}{relais2}{VAL} = $v3 ? "on": "off"; + $changed = 1; + } + $def->{channel1} = $cmp[3]; + if ($changed == 1) { + $log = "led: " . ($v1 ? "on": "off") . " relais1: " . ($v2 ? "on": "off") . " relais2: " . ($v3? "on": "off"); + $def->{STATE} = $log; + push @{$def->{CHANGED}}, $log; + DoTrigger($def->{NAME}, undef); + } + } + } + + return $name; + } else { + Log 3, "EBN Unknown device $cmp[1], please define it"; + if ($cmp[2] == 0) { + return "UNDEFINED EBN_$cmp[1] EBN $cmp[1] $cmp[3]"; + } else { + return undef; + } + } +} + +sub +EBN_Get($@) +{ + my ($hash, @args) = @_; + + return 'EBN_Get needs two arguments' if (@args != 2); + + my $get = $args[1]; + my $val; + + if ( $get eq "?"){ + if ($hash->{EBTYPE} == 1) { + return "Unknown argument ?, choose one of testled expled"; + } + if ($hash->{EBTYPE} == 2) { + return "Unknown argument ?, choose one of tuer buzzer"; + } + if ($hash->{EBTYPE} == 3) { + return "Unknown argument ?, choose one of led relais1 relais2"; + } + return "EBN_Get: no such reading: $get"; + } + if (defined($hash->{READINGS}{$get})) { + $val = $hash->{READINGS}{$get}{VAL}; + } else { + return "EBN_Get: no such reading: $get"; + } + Log 3, "$args[0] $get => $val"; + + return $val; +} + +sub +EBN_Set($@) +{ + my ($hash, @args) = @_; + + my $set = $args[1]; + my $num; + my $msg; + + if ( $set eq "?"){ + if ($hash->{EBTYPE} == 1) { + return "Unknown argument ?, choose one of testled expled"; + } + if ($hash->{EBTYPE} == 2) { + return "Unknown argument ?, choose one of buzzer"; + } + if ($hash->{EBTYPE} == 3) { + return "Unknown argument ?, choose one of led relais1 relais2"; + } + return "EBN_Get: no such reading: $set"; + } + return 'EBN_Set needs three arguments' if (@args != 3); + my $val = $args[2]; + + Log 3, "$args[0] $set => $val"; + + if ($hash->{EBTYPE} == 1) { + if ($val eq "on") { + $num = 1; + } else { + $num = 0; + } + if ($set eq "testled") { + $msg = ($hash->{channel1} & 0x3FE) | $num; + } + if ($set eq "expled") { + $msg = ($hash->{channel1} & 0x3FD) | ($num << 1); + } + IOWrite($hash, "W", $hash->{ADDR} . " 1 " . $msg); + } + if ($hash->{EBTYPE} == 2) { + if ($val eq "disabled") { + $num = 1; + } else { + $num = 0; + } + if ($set eq "buzzer") { + $msg = ($hash->{channel1} & 0x3FD) | ($num << 1); + } + IOWrite($hash, "W", $hash->{ADDR} . " 1 " . $msg); + } + if (($hash->{EBTYPE} == 3) || ($hash->{EBTYPE} == 4)) { + if ($val eq "on") { + $num = 1; + } else { + $num = 0; + } + if ($set eq "led") { + $msg = ($hash->{channel1} & 0x3FE) | $num; + } + if ($set eq "relais1") { + $msg = ($hash->{channel1} & 0x3FD) | ($num << 1); + } + if ($set eq "relais2") { + $msg = ($hash->{channel1} & 0x3FB) | ($num << 2); + } + IOWrite($hash, "W", $hash->{ADDR} . " 1 " . $msg); + } + + + return undef; +} + +1; + diff --git a/ebd/AUTHORS b/ebd/AUTHORS new file mode 100644 index 0000000..e69de29 diff --git a/ebd/ChangeLog b/ebd/ChangeLog new file mode 100644 index 0000000..e69de29 diff --git a/ebd/Makefile.am b/ebd/Makefile.am new file mode 100644 index 0000000..af437a6 --- /dev/null +++ b/ebd/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = src diff --git a/ebd/NEWS b/ebd/NEWS new file mode 100644 index 0000000..e69de29 diff --git a/ebd/README b/ebd/README new file mode 100644 index 0000000..e69de29 diff --git a/ebd/configure.ac b/ebd/configure.ac new file mode 100644 index 0000000..d1c489e --- /dev/null +++ b/ebd/configure.ac @@ -0,0 +1,15 @@ +AC_INIT([src/rs485.c]) +AC_PREREQ([2.63]) +AM_INIT_AUTOMAKE(ebd, 0.0.1) + +AC_CONFIG_HEADERS([config.h]) + +AC_PROG_CC +AC_PROG_INSTALL + +AC_CONFIG_FILES([ + Makefile + src/Makefile +]) + +AC_OUTPUT diff --git a/ebd/src/Makefile.am b/ebd/src/Makefile.am new file mode 100644 index 0000000..6175e4e --- /dev/null +++ b/ebd/src/Makefile.am @@ -0,0 +1,6 @@ +bin_PROGRAMS = ebd + +AM_CFLAGS = $(DEPS_CFLAGS) + +ebd_SOURCES = main.c rs485.c +ebd_LDADD = $(DEPS_LIBS) diff --git a/ebd/src/main.c b/ebd/src/main.c new file mode 100644 index 0000000..106c70e --- /dev/null +++ b/ebd/src/main.c @@ -0,0 +1,245 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void send_ack(int addr) { + unsigned char buf[16]; + + buf[0] = 0xAA; + buf[1] = 2; + buf[2] = addr; + buf[3] = addr; + buf[4] = 1; + buf[5] = 1; + buf[6] = 0; + buf[7] = 0; + buf[8] = 0; + buf[9] = 0; + buf[10] = 0; + buf[11] = 0; + buf[12] = 0; + buf[13] = 0; + buf[14] = 0; + + rs485_crc(buf); + rs485_send(buf); +} + +void send_read_req(int addr, int channel) { + unsigned char buf[16]; + + buf[0] = 0xAA; + buf[1] = 0; + buf[2] = addr; + buf[3] = addr; + buf[4] = 1; + buf[5] = 1; + buf[6] = 0x40 + channel; + buf[7] = 0; + buf[8] = 0; + buf[9] = 0; + buf[10] = 0; + buf[11] = 0; + buf[12] = 0; + buf[13] = 0; + buf[14] = 0; + + rs485_crc(buf); + rs485_send(buf); +} + +void send_write_req(int addr, int channel, int data) { + unsigned char buf[16]; + + buf[0] = 0xAA; + buf[1] = 0; + buf[2] = addr; + buf[3] = addr; + buf[4] = 1; + buf[5] = 1; + buf[6] = 0x60 + channel + ((data & 0x300 ) >> 5); + buf[7] = data & 0xFF; + buf[8] = 0; + buf[9] = 0; + buf[10] = 0; + buf[11] = 0; + buf[12] = 0; + buf[13] = 0; + buf[14] = 0; + + rs485_crc(buf); + rs485_send(buf); +} + +void send_poll(void) { + unsigned char buf[16]; + + buf[0] = 0xAA; + buf[1] = 0; + buf[2] = 0; + buf[3] = 0; + buf[4] = 1; + buf[5] = 1; + buf[6] = 0; + buf[7] = 0; + buf[8] = 0; + buf[9] = 0; + buf[10] = 0; + buf[11] = 0; + buf[12] = 0; + buf[13] = 0; + buf[14] = 0; + + rs485_crc(buf); + rs485_send(buf); +} + +void mainloop(int fd) { + struct timeval timeout; + int rd; + fd_set rset; + fd_set wset; + fd_set eset; + int quit; + int alt; + int ret; + int req_dev; + int req_channel; + int req_data; + int req_write; + int ack_dev; + int dev_poll; + unsigned char rbuf[16]; + + alt = 0; + quit = 0; + req_dev = 0; + req_channel = 0; + ack_dev = 0; + dev_poll = 2; + + while (!quit) { + FD_ZERO(&rset); + FD_ZERO(&wset); + FD_ZERO(&eset); + FD_SET(fd, &rset); + FD_SET(0, &rset); + + timeout.tv_sec = 0; + timeout.tv_usec = 40000; + + rd = select(fd + 1, &rset, &wset, &eset, &timeout); + + if (rd == 0) { + if (alt) { + send_poll(); + alt = 0; + continue; + } + alt = 1; + + if (ack_dev) { + send_ack(ack_dev); + ack_dev = 0; + continue; + } + + if (req_dev) { + if (req_write) + send_write_req(req_dev, req_channel, req_data); + else + send_read_req(req_dev, req_channel); + req_dev = 0; + continue; + } + + send_read_req(dev_poll, 0); + dev_poll++; + if (dev_poll > 126) + dev_poll = 2; + } else { + if (FD_ISSET(fd, &rset)) { + ret = rs485_recv_loop(); + if (ret < 0) + exit(-1); + if (ret == 0) + continue; + + rs485_recv(&rbuf); + + if ((rbuf[1] == 1) && (rbuf[2] == 1)) + ack_dev = rbuf[4]; + + if ((rbuf[2] == 1) && (rbuf[6] >= 0x40) && (rbuf[6] < 0x60)) { + printf ("R %d %d %d\n", rbuf[4], (rbuf[6] - 0x40) & 0x7, rbuf[7] + (((rbuf[6] - 0x40) & 0x18) << 5)); + fflush(stdout); + } + continue; + } + if (FD_ISSET(0, &rset)) { + unsigned char a; + unsigned char ibuf[100]; + int d, c, v; + unsigned char *p; + + p = fgets(ibuf, 100, stdin); + if (p == NULL) + exit(-1); + + sscanf(ibuf, "%c %d %d %d\n", &a, &d, &c, &v); + if (a == 'Q') { + quit = 1; + continue; + } + if (a == 'R') { + req_dev = d; + req_channel = c; + req_write = 0; + continue; + } + if (a == 'W') { + req_dev = d; + req_channel = c; + req_data = v; + req_write = 1; + continue; + } + } + } + } +} + +int main(int argc, char **argv) { + + char *dev = "/dev/ttyS2"; + int c; + + int fd; + + while ((c = getopt(argc, argv, "d:")) != -1) + switch (c) { + case 'd': + dev = optarg; + break; + } + + fd = rs485_open(dev); + if (fd < 0) { + printf("RS485 open failed\n"); + return -1; + } + + mainloop(fd); + + rs485_close(); + + return 0; +} diff --git a/ebd/src/rs485.c b/ebd/src/rs485.c new file mode 100644 index 0000000..26804a7 --- /dev/null +++ b/ebd/src/rs485.c @@ -0,0 +1,143 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Driver-specific ioctls: */ +#define TIOCGRS485 0x542E +#define TIOCSRS485 0x542F + +struct serial_rs485 rs485conf; +struct termios options; + +int fd; +unsigned char inbuf[16]; +int bufp; + +static uint16_t crc_ccitt_update(uint16_t crc, uint8_t data) +{ + data ^= (crc & 0xFF); + data ^= data << 4; + + return ((((uint16_t)data << 8) | ((crc >> 8) & 0xFF)) + ^ (uint8_t)(data >> 4) ^ ((uint16_t)data << 3)); +} + +int rs485_crc(unsigned char buf[16]) +{ + uint16_t crc; + int i; + + if (buf[0] != 0xAA) + return -1; + if (buf[2] != buf[3]) + return -1; + if (buf[4] != buf[5]) + return -1; + + crc = 0xFFFF; + for (i=0; i<14; i++) + crc = crc_ccitt_update(crc, buf[i]); + buf[14] = (crc >> 8) & 0xFF; + buf[15] = crc & 0xFF; + + return 0; +} + +int rs485_send(unsigned char buf[16]) +{ + return write(fd, buf, 16); +} + +int rs485_recv(unsigned char buf[16]) +{ + int i; + if (bufp < 16) + return -1; + + for (i=0;i<16;i++) + buf[i] = inbuf[i]; + return 0; +} + +int rs485_recv_loop(void) +{ + int i; + unsigned char *p; + uint16_t crc; + + if (bufp >=16) + bufp=0; + + p = &(inbuf[bufp]); + + if (read(fd, p, 1) < 0) + return -1; + + bufp++; + + if ((bufp == 1) && (inbuf[0] != 0xAA)) + bufp = 0; + + if ((bufp == 4) && (inbuf[2] != inbuf[3])) + bufp = 0; + + if ((bufp == 6) && (inbuf[4] != inbuf[5])) + bufp = 0; + + if (bufp == 16) { + crc = 0xFFFF; + + for (i=0; i<14; i++) + crc = crc_ccitt_update(crc, inbuf[i]); + if ((inbuf[14] == ((crc >> 8) & 0xFF)) && (inbuf[15] == (crc & 0xFF))) + return 1; + else + bufp = 0; + } + return 0; +} + +int rs485_close(void) +{ + close(fd); +} + +int rs485_open(char *path) +{ + fd = open (path, O_RDWR); + if (fd < 0) { + return -1; + } + + rs485conf.flags |= SER_RS485_ENABLED; + rs485conf.flags |= (SER_RS485_RTS_ON_SEND); + rs485conf.flags |= (SER_RS485_RTS_AFTER_SEND); + //rs485conf.flags |= SER_RS485_RX_DURING_TX; + + ioctl (fd, TIOCSRS485, &rs485conf); + + bzero(&options, sizeof(options)); + cfsetspeed(&options, B9600); + options.c_cflag &= ~PARENB; + options.c_cflag &= ~CSTOPB; + options.c_cflag &= ~CSIZE; + options.c_cflag |= CS8; + options.c_cflag |= (CLOCAL | CREAD); + options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); + options.c_oflag &= ~OPOST; + options.c_cc[VMIN] = 0; + options.c_cc[VTIME] = 1; + tcflush(fd,TCIOFLUSH); + tcsetattr(fd, TCSAFLUSH, &options); + + return fd; +} diff --git a/ebd/src/rs485.h b/ebd/src/rs485.h new file mode 100644 index 0000000..b1fafb5 --- /dev/null +++ b/ebd/src/rs485.h @@ -0,0 +1,6 @@ +int rs485_crc(unsigned char buf[16]); +int rs485_send(unsigned char buf[16]); +int rs485_recv(unsigned char buf[16]); +int rs485_recv_loop(void); +int rs485_close(void); +int rs485_open(char *path);