#include<stdio.h> // printf()
#include<stropts.h> // ioctl()
#include<termios.h> // struct termios
#include<unistd.h> // read(), write()
#include<string.h> // strlen()
#include<fcntl.h> // O_RDWR, O_NDELAY, etc
#include <sys/ioctl.h> // TIOCMGET, TIOCM_RTS, etc.
#include <assert.h> // assert()
// "ISO485-HD_sample.c"
// JW -- Technologic Systems -- 11/09
//
// Sample code for the TS-ISO485 Half-Duplex mode
//
// TS-ISO485 jumper configuration:
// ADD2, A_HD, B_HD, Share, IRQ2 & IRQ4
//
// Test board: TS-7260
//
// NOTE:
// the following condition NEEDs to be met,
// connect terminal-1, COM-A to terminal-1, COM-B
// connect terminal-2, COM-A to terminal-2, COM-B
//
// NOTE:
// the following shell command allows IRQ sharing, which
// speeds up test:
// 'setserial /dev/tts/4 irq 33'
// (this makes BOTH ports' IRQ's the same --33)
//***********************************************
//***********************************************
//* The idea:
//* open both portA & portB (/dev/tts/4 & /dev/tts/5)
//* set the port attributes for both ports (mainly 9600 BAUD)
//* IMPORTANT: CLEAR the RTS bit on portB (/dev/tts/5),
//* (the receiving port)
//* send data to portA, receive on portB
//***********************************************
//***********************************************
// setRTS()
//
// IN: 'com': port to set
// 'state': (0)= CLEAR, (1)= SET
//
// OUT: return the value given to us
//
// Set/clear the RTS bit
//***********************************************
int setRTS(int com, int state)
{
// Get the current flag (bit status)
// the value of 'flag' determines which flags are set
// (bit == 1), RTS, DTR, etc.
int flag;
ioctl(com, TIOCMGET, &flag);
// Do we SET or CLEAR this bit (flag)?
if(state == 1)
// OR 'flag' with TCIOCM_RTS, to set the bit
flag|= TIOCM_RTS;
else
// AND 'flag' with the inverse of TCIOCM_RTS, to clear the bit
flag&= ~TIOCM_RTS;
// Set the new flag value
ioctl(com, TIOCMSET, &flag);
return(state);
}//setRTS()
//***********************************************
// setCom()
//
// IN: 'com'= port to set
//
// OUT: success
//
// Set the COM port attributes
// (9600, BAUD, 8N1)
// Flush this port
//***********************************************
int setCom(int com)
{
// This struct holds the port attributes
struct termios attr;
// Make sure this struct is zeroed out (all bits clear)
bzero(&attr, sizeof(attr));
// To the 'c_cflag' value, we OR the following flags (bits)
attr.c_cflag= (B9600 | CS8 | CLOCAL | CREAD);
// Flush all char's from this port's FIFO
tcflush(com, TCIOFLUSH);
// Set the new attributes
tcsetattr(com, TCSANOW, &attr);
return(0);
}//setCom()
//*****************************************************************************
// MAIN
int main()
{
// These are COM-A & COM-B on the TS-ISO485
int comA;
int comB;
char *portA="/dev/tts/4";
char *portB="/dev/tts/5";
// Open both ports; exit if error
comA= open(portA, O_RDWR | O_NOCTTY | O_NDELAY);
assert(comA > 0);
comB= open(portB, O_RDWR | O_NOCTTY | O_NDELAY);
assert(comB > 0);
// Get, save the attributes for both ports (good programming practice)
struct termios attrA;
struct termios attrB;
tcgetattr(comA, &attrA);
tcgetattr(comB, &attrB);
// Set the (new) attributes for both ports
setCom(comA);
setCom(comB);
// Throw away all data in FIFO before writing
tcflush(comB, TCIOFLUSH);
// IMPORTANT: CLEAR RTS on the receiving port
// else Half-Duplex is disabled by default
setRTS(comB, 0);
/********************************************************************/
// Write 12 char's, one-at-a-time
// NOTE: no error checking!
printf("Write 12 char's, read back 12 char's\n");
unsigned char tx, rx, i;
// Write 12 char's to portA
tx= 0x31;
for(i= 0; i < 12; i++)
{
printf("writing val 0x%x\n", tx);
write(comA, &tx, 1);
tx++;
}
// Block until all data is written
tcdrain(comA);
// Read back the 12 char's (from portB)
for(i= 0, tx= 0x31; i < 12; i++, tx++)
{
printf("reading byte ...");
// May need a slight delay between reads
while(read(comB, &rx, 1) != 1)
{
printf("Data not ready...\n");
usleep(10);
}
// Data read == data written?
if(rx == tx)
printf("[0x%x] - ok\n", rx);
else
printf("FAIL, expected 0x%x\n", tx);
}
printf("\n");
/********************************************************************/
// Write/read one char at a time
// NOTE: no error checking!
printf("Write/read one char at a time\n");
char *outStr= "TS-Test"; // String to write out
char inStr[8]; // String to put data in
inStr[7]= '\0'; // String terminator, just in case...
// The 7 char's in 'outStr' [TS-test]
for(i= 0; i < 7; i++)
{
// Write the next char
printf("Write: [%c]", outStr[i]);
write(comA, &outStr[i], 1);
// Block until data is written
tcdrain(comA);
// Read the next char
read(comB, &inStr[i], 1);
printf("\tRead: [%c]\n", inStr[i]);
}
/*******************************************************************/
// Restore the port attributes (good prog. practice)
tcsetattr(comA, TCSANOW, &attrA);
tcsetattr(comB, TCSANOW, &attrB);
// Close the ports (yes, good prog. practice)
close(comA);
close(comB);
return(0);
}//main()
syntax highlighted by Code2HTML, v. 0.9.1