RS-232, controlling the RTS pin

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

RS-232, controlling the RTS pin

Doug Carter
I've been using a C program to control a custom radio on FreeBSD
(5.2-5.4) for some time.  This program uses the RS-232 RTS pin to
key the half duplex radio transmitter.  I am attempting to port
this program to OpenBSD 3.8.

On the OpenBSD machine the serial port (cua00) sends and receives
bytes just fine but my code to switch the RTS pin does not seem
to work.  I never see any state change on the RTS pin.  

My question is: Does OpenBSD support RTS control (not flow
control)?  If so, is the control done differently than under
FreeBSD?


The relevent C code fragments. First I call 'lockLINX' as part of
the serial port setup then call 'Transmit' and 'Receive' as
appropiate for my half duplex communicaiton:


#define LINX      "cua00"
lockLINX()
{
int error_limit = 0;
for(;;)
   {
   if(error_limit++ == 200) return(0);  // give up
   if(uu_lock(LINX) == 0)  // 0 == good lock
      {
      if((SIO_fd = open("/dev/" LINX, O_RDWR | O_FSYNC)) > 2)
         break;  // valid fd
      }
   usleep(50U * 1000U);
   }
tcgetattr(SIO_fd,&oldtio);       /* save current serial port
settings */
memset(&newtio, 0, sizeof(newtio)); /* clear struct for new port
settings */
newtio.c_ispeed      = BAUDRATE;
newtio.c_ospeed      = BAUDRATE;
newtio.c_cflag       = CLOCAL | CS8 | CREAD;
newtio.c_iflag       = IGNPAR | IGNBRK | IGNCR;
newtio.c_oflag       = 0;
newtio.c_lflag       = 0;
newtio.c_cc[VTIME]   = 2;
newtio.c_cc[VMIN]    = 0;
tcsetattr(SIO_fd,TCSANOW,&newtio);                                              
tcflush(SIO_fd, TCIFLUSH);                                                      
return(1);
}


void
Transmit()  // set LINX RTS line high to key transmitter
{
ioctl(SIO_fd, TIOCMGET, &UART_status);
UART_status |= TIOCM_RTS;
ioctl(SIO_fd, TIOCMSET, &UART_status);
usleep(1000U);  // give the RTS line time to settle
sleep(2);
}


void
Receive()      // set LINX RTS line low to unkey transmitter
{
ioctl(SIO_fd, TIOCMGET, &UART_status);
UART_status &= ~TIOCM_RTS;
ioctl(SIO_fd, TIOCMSET, &UART_status);
}

--
Doug Carter

Reply | Threaded
Open this post in threaded view
|

Re: RS-232, controlling the RTS pin

Alexandre Ratchov
On Sat, Dec 03, 2005 at 06:42:54PM -0600, Doug Carter wrote:

> I've been using a C program to control a custom radio on FreeBSD
> (5.2-5.4) for some time.  This program uses the RS-232 RTS pin to
> key the half duplex radio transmitter.  I am attempting to port
> this program to OpenBSD 3.8.
>
> On the OpenBSD machine the serial port (cua00) sends and receives
> bytes just fine but my code to switch the RTS pin does not seem
> to work.  I never see any state change on the RTS pin.  
>
> My question is: Does OpenBSD support RTS control (not flow
> control)?  If so, is the control done differently than under
> FreeBSD?
>
> The relevent C code fragments. First I call 'lockLINX' as part of
> the serial port setup then call 'Transmit' and 'Receive' as
> appropiate for my half duplex communicaiton:
>
>
> #define LINX      "cua00"
> lockLINX()
> {
> int error_limit = 0;
> for(;;)
>    {
>    if(error_limit++ == 200) return(0);  // give up
>    if(uu_lock(LINX) == 0)  // 0 == good lock
>       {
>       if((SIO_fd = open("/dev/" LINX, O_RDWR | O_FSYNC)) > 2)
>          break;  // valid fd
>       }
>    usleep(50U * 1000U);
>    }
> tcgetattr(SIO_fd,&oldtio);       /* save current serial port
> settings */
> memset(&newtio, 0, sizeof(newtio)); /* clear struct for new port
> settings */
> newtio.c_ispeed      = BAUDRATE;
> newtio.c_ospeed      = BAUDRATE;
> newtio.c_cflag       = CLOCAL | CS8 | CREAD;
> newtio.c_iflag       = IGNPAR | IGNBRK | IGNCR;
> newtio.c_oflag       = 0;
> newtio.c_lflag       = 0;
> newtio.c_cc[VTIME]   = 2;
> newtio.c_cc[VMIN]    = 0;
> tcsetattr(SIO_fd,TCSANOW,&newtio);                                              
> tcflush(SIO_fd, TCIFLUSH);                                                      
> return(1);
> }
>
>
> void
> Transmit()  // set LINX RTS line high to key transmitter
> {
> ioctl(SIO_fd, TIOCMGET, &UART_status);
> UART_status |= TIOCM_RTS;
> ioctl(SIO_fd, TIOCMSET, &UART_status);
> usleep(1000U);  // give the RTS line time to settle
> sleep(2);
> }
>
>
> void
> Receive()      // set LINX RTS line low to unkey transmitter
> {
> ioctl(SIO_fd, TIOCMGET, &UART_status);
> UART_status &= ~TIOCM_RTS;
> ioctl(SIO_fd, TIOCMSET, &UART_status);
> }
>

hello,

some times ago, i played with a microcontroller programmer that used
the RTS pin of the serial port. I have no more the hardware to test it
on openbsd 3.8 but it worked fine on older releases. I used the
following fragment of code to deal with the RTS bit:

int pic_fd;

void
pic_open(char *devname) {
        pic_fd = open(devname, O_RDWR);
        if (pic_fd < 0) {
                perror("open");
                exit(1);
        }
}

void
pic_write_rb6(unsigned val) {
        int state;
        state = TIOCM_RTS;
        if (val) {
                if (ioctl(pic_fd, TIOCMBIS, &state) < 0) {
                        perror("pic_write_rb6: ioctl(TIOCMBIS)");
                        exit(1);
                }
        } else {
                if (ioctl(pic_fd, TIOCMBIC, &state) < 0) {
                        perror("pic_write_rb6: ioctl(TIOCMBIC)");
                        exit(1);
                }
        }
}


regards,

--
Alexandre