0

I'm trying to setup half duplex communication in Ubuntu 14.04 in my program. I have my RS485 transceiver using the RTS line to toggle back and forth between transmit and receive. I'm using a speak when spoken to system and this program is the master. The problem is that the RTS isn't toggling back off when I'm done sending the package so I can receive the data. Basically I want it to turn the RTS high, send the data, turn the RTS low, then read the data. Any help would be great.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/signal.h>
#include <sys/types.h>

#define BAUDRATE B38400
#define COMPORT "/dev/ttyUSB0"
#define _POSIX_SOURCE 1
#define FALSE 0
#define TRUE 1

#define STX_KEYPAD 0xE1
#define PAYLOAD_BUFF_SIZE 256

#define CRC_HI 0xD8
#define CRC_LOW 0xC3

volatile int STOP=FALSE;

int ser_port;
int bus_address = 1;
int message_length = 0;
struct termios oldtio,newtio;
unsigned char rxbuf[256];
unsigned char tx_flags = 0;

void openCommPort();
void sendSerial();
int setRTS(int level);

int main(void)
{
     printf("Starting...\r\n");
 openCommPort();
 setRTS(1);
 printf("Sending Serial Data\r\n");
 sendSerial();
 setRTS(0);
 //close(ser_port);
 printf("All Done\r\n");

     return EXIT_SUCCESS;
}

void openCommPort()
{
   ser_port = open(COMPORT, O_RDWR | O_NOCTTY | O_NONBLOCK);
   if (ser_port == -1)
    {
       perror(COMPORT);
       perror("Unable to open port");
       exit(-1);
    }

   if(tcgetattr(ser_port,&oldtio) <0)// save current port settings
    {
       perror(COMPORT);
       perror("Couldn't get old terminal attributes");
       exit (-1);
    }

    bzero(&newtio, sizeof(newtio));

    newtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD | CRTSCTS;     

     newtio.c_iflag = IGNPAR | ICANON;

    newtio.c_oflag = 0;

       // set input mode (non-C, no echo,...)
   newtio.c_lflag = 0;

   newtio.c_cc[VTIME]    = 0;   // inter-character timer unused
   newtio.c_cc[VMIN]     = 0;   // blocking read until 5 chars received

   tcflush(ser_port, TCIFLUSH);
   tcsetattr(ser_port,TCSANOW,&newtio);
 }

void sendSerial()
{
unsigned char tx_header[6];

tx_header[0] = STX_KEYPAD;
tx_header[1] = bus_address;
tx_header[2] = tx_flags;
tx_header[3] = message_length;
tx_header[4] = CRC_HI;
tx_header[5] = CRC_LOW;

if((write(ser_port, tx_header, 6)) != 6)
 {
     printf("Error sending data!  Not all bytes sent\r\n");
 }

}

int setRTS(int level)
{
int status;

 if (ioctl(ser_port, TIOCMGET, &status) == -1)
    {
        perror("getRTS(): TIOCMSET");
        return 0;
    }


if(level)
 {
     status |= TIOCM_RTS;
 }
 else
 {
    status &= ~TIOCM_RTS;
 }

if (ioctl(ser_port, TIOCMSET, &status) == -1)
{
    perror("setRTS(): TIOCMSET");
    return 0;
}

return 1;
}
dsolimano
  • 8,870
  • 3
  • 48
  • 63
user3753729
  • 1
  • 1
  • 3
  • Maybe I'm not understanding it, but... why do you use `TIOCM_DTR` instead of `TIOCM_RTS` if the function is named `setRTS()`? – rodrigo Jun 18 '14 at 19:00
  • Typo on my part I was using `TIOCM_RTS` and not `TIOCM_DTR`. I updated the code posted above to reflect the code properly. – user3753729 Jun 18 '14 at 19:26
  • The code `sendSerial(); setRTS(0);` does not insure data is sent before calling `setRTS(0)`. It only directs code to _begin_ sending the message. Completion happens at a later time. Code need a call to some TBD function like `fflush()` that insures the outgoing buffer is empty, _then_ call `setRTS(0)`. – chux - Reinstate Monica Jun 18 '14 at 21:13

0 Answers0