rllib  1
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros
Public Types | Public Member Functions | Private Types | Private Member Functions | Private Attributes | List of all members
rlDF1 Class Reference

#include <rldf1.h>

Collaboration diagram for rlDF1:
Collaboration graph
[legend]

Public Types

enum  DF1ret {
  retERROR_TNS = -6, retERROR_STS = -5, retERROR_CRC = -4, retERROR_NAC = -3,
  retERROR = -2, retNORESPONSE = -1, retSUCCESS = 0
}
 
enum  CPUMODE { PROGRAM = 0, TEST, RUN, NOCHANGE }
 

Public Member Functions

 rlDF1 (unsigned char src=0, int timeout=1000)
 
virtual ~rlDF1 ()
 
void registerSerial (rlSerial *serial)
 
int cmdSetCPUMode (unsigned char destination, unsigned char mode)
 
int cmdDiagnosticStatus (unsigned char destination, unsigned char *data)
 
int cmdLogicalRead (unsigned char destination, unsigned char nsize, unsigned char filetype, unsigned char filenum, unsigned char adr, unsigned char sadr, unsigned char *buffer)
 
int cmdLogicalWrite (unsigned char destination, unsigned char nsize, unsigned char filetype, unsigned char filenum, unsigned char adr, unsigned char sadr, unsigned char *buffer)
 
int requests ()
 
int responses ()
 
void clearStats ()
 

Private Types

enum  DF1BytePos {
  POS_DST =0, POS_SRC =1, POS_CMD =2, POS_STS =3,
  POS_TNSL =4, POS_TNSH =5, POS_DATA =6
}
 
enum  DF1ControlChars {
  SOH = 0x01, STX = 0x02, ETX = 0x03, EOT = 0x04,
  ENQ = 0x05, ACK = 0x06, DLE = 0x10, NAC = 0x15
}
 
enum  DF1Flags { FLAG_TIMEOUT =-1, FLAG_DATA =0, FLAG_CONTROL =1 }
 

Private Member Functions

int sendCommand (unsigned char destination, unsigned char cmd, unsigned char sts, unsigned char *cdata, unsigned char len)
 
int receiveAnswer (unsigned char &destination, unsigned char &cmd, unsigned char &sts, unsigned char *cdata, unsigned char &len)
 
int writeBuffer (unsigned char *buffer, int len)
 
int writeBuffer (df1Buffer &buffer)
 
int getSymbol (unsigned char *c)
 
int get (unsigned char *c)
 
int sendENQ ()
 
int sendACK ()
 
int sendNAC ()
 

Private Attributes

rlSerialtty
 
bool active
 
unsigned short tns
 
int nRequests
 
int nResponses
 
unsigned char source
 
int timeout
 

Detailed Description

Definition at line 38 of file rldf1.h.

Member Enumeration Documentation

      Command: Set CPU mode ( See page 7-26 )
      destination = destination ID
      mode = CPUMODE value
Enumerator:
PROGRAM 
TEST 
RUN 
NOCHANGE 

Definition at line 67 of file rldf1.h.

{
PROGRAM = 0,
RUN,
};
enum rlDF1::DF1BytePos
private
      Functions for Data Link Layer.
      Internal Use ONLY.
Enumerator:
POS_DST 
POS_SRC 
POS_CMD 
POS_STS 
POS_TNSL 
POS_TNSH 
POS_DATA 

Definition at line 158 of file rldf1.h.

{
POS_DST =0,
POS_SRC =1,
POS_CMD =2,
POS_STS =3,
};
enum rlDF1::DF1ControlChars
private
Enumerator:
SOH 

Page 2-6 of Ref Manual.

STX 
ETX 
EOT 
ENQ 
ACK 
DLE 
NAC 

Definition at line 167 of file rldf1.h.

{
SOH = 0x01,
STX = 0x02,
ETX = 0x03,
EOT = 0x04,
ENQ = 0x05,
ACK = 0x06,
DLE = 0x10,
NAC = 0x15
};
enum rlDF1::DF1Flags
private
Enumerator:
FLAG_TIMEOUT 
FLAG_DATA 
FLAG_CONTROL 

Definition at line 177 of file rldf1.h.

Enumerator:
retERROR_TNS 
retERROR_STS 
retERROR_CRC 
retERROR_NAC 
retERROR 
retNORESPONSE 
retSUCCESS 

Definition at line 51 of file rldf1.h.

{
retERROR = -2,
};

Constructor & Destructor Documentation

rlDF1::rlDF1 ( unsigned char  src = 0,
int  timeout = 1000 
)
    Initialize class
    src = id of local device
    timeout = receive timeout in ms

Get a random TNS

Definition at line 145 of file rldf1.cpp.

{
source = src;
timeout=_timeout;
tty = NULL;
active = false;
nRequests = 0;
tns = (unsigned short) time((time_t *)0);
}
rlDF1::~rlDF1 ( )
virtual

Definition at line 156 of file rldf1.cpp.

{
}

Member Function Documentation

void rlDF1::clearStats ( )
inline

Definition at line 206 of file rldf1.h.

int rlDF1::cmdDiagnosticStatus ( unsigned char  destination,
unsigned char *  data 
)
        Command: Diagnostic Status
        Reads a block of status information from an interface module.
        The function returns the status information in data.
        (see Chapter 10, “Diagnostic Status Information.”)
        destination = destination ID
        data = buffer for data return
        returns the number of valid bytes in data or Error Code

Definition at line 257 of file rldf1.cpp.

{
unsigned char cdat[256];
cdat[0]=0x03;
int ret = sendCommand( destination, 0x06, 0x00, cdat, 1);
if (ret==retSUCCESS) {
unsigned char dest,cmd,sts,len;
ret = receiveAnswer( dest, cmd, sts, cdat, len);
if ( ret == retSUCCESS ) {
for (int i=0;i<len;i++) buffer[i]=cdat[i];
ret = len;
}
}
return ret;
}
int rlDF1::cmdLogicalRead ( unsigned char  destination,
unsigned char  nsize,
unsigned char  filetype,
unsigned char  filenum,
unsigned char  adr,
unsigned char  sadr,
unsigned char *  buffer 
)
        Command: protected typed logical read with three address fields
        *Most Important command*. Reads data from a logical address.
        Parameters:
            destination = destination ID
            nsize = size of data to be read
            filetype = Type of file with number filenum
                            84 hex: status
                            85 hex: bit
                            86 hex: timer
                            87 hex: counter
                            88 hex: control
                            89 hex: integer
                            8A hex: floating point
                            8B hex: output logical by slot
                            8C hex: input logical by slot
                            8D hex: string
                            8E hex: ASCII
                            8F hex: BCD
            filenum = filenumber in PLC memory
            adr  = Elements Address (see Manual)
            sadr = Subelements Address (see Manual)
            data = buffer for data return
        returns the number of valid bytes in data or Error Code

Definition at line 273 of file rldf1.cpp.

{
unsigned char cdat[256];
cdat[0]=0xA2;
cdat[1]=nsize;
cdat[2]=filenum;
cdat[3]=filetype;
cdat[4]=adr;
cdat[5]=sadr;
int ret = sendCommand( destination , 0x0F, 0x00, cdat, 6);
if (ret==retSUCCESS) {
unsigned char dest,cmd,sts,len;
ret = receiveAnswer( dest, cmd, sts, cdat, len);
if ( ret == retSUCCESS ) {
for (int i=0;i<len;i++) buffer[i]=cdat[i];
ret = len;
}
if (sts!=0) ret = retERROR_STS;
}
return ret;
}
int rlDF1::cmdLogicalWrite ( unsigned char  destination,
unsigned char  nsize,
unsigned char  filetype,
unsigned char  filenum,
unsigned char  adr,
unsigned char  sadr,
unsigned char *  buffer 
)
        Command: protected typed logical write with three address fields
        *Most Important command*. Writes data to a logical address.
        Parameters:
            destination = destination ID
            nsize = size of data to write
            filetype = Type of file with number filenum
                            84 hex: status
                            85 hex: bit
                            86 hex: timer
                            87 hex: counter
                            88 hex: control
                            89 hex: integer
                            8A hex: floating point
                            8B hex: output logical by slot
                            8C hex: input logical by slot
                            8D hex: string
                            8E hex: ASCII
                            8F hex: BCD
            filenum = filenumber in PLC memory
            adr  = Elements Address (see Manual)
            sadr = Subelements Address (see Manual)
            data = buffer of data to write
        returns Error Code

Definition at line 294 of file rldf1.cpp.

{
unsigned char cdat[256];
cdat[0]=0xAA;
cdat[1]=nsize;
cdat[2]=filenum;
cdat[3]=filetype;
cdat[4]=adr;
cdat[5]=sadr;
for (int i=0;i<nsize;i++) cdat[6+i] = buffer[i];
int ret = sendCommand( destination, 0x0F, 0x00, cdat, 6+nsize);
if (ret==retSUCCESS) {
unsigned char dest,cmd,sts,len;
ret = receiveAnswer( dest, cmd, sts, cdat, len);
if ( ret == retSUCCESS ) {
for ( int i=0;i<len;i++) buffer[i] = cdat[i];
ret = len;
}
if (sts!=0) ret = retERROR_STS;
}
return ret;
}
int rlDF1::cmdSetCPUMode ( unsigned char  destination,
unsigned char  mode 
)

Definition at line 240 of file rldf1.cpp.

{
unsigned char cdat[256];
cdat[0]=0x3A;
cdat[1]=mode;
int ret = sendCommand( destination, 0x0F, 0x00, cdat, 2);
if (ret==retSUCCESS) {
unsigned char dest,cmd,sts,len;
ret = receiveAnswer( dest, cmd, sts, cdat, len);
if (sts!=0) {
printf("\nSet CPU Mode Execution Error! STS:%02X",sts);
}
}
return ret;
}
int rlDF1::get ( unsigned char *  c)
private

Definition at line 203 of file rldf1.cpp.

{
int ret = tty->readBlock( c, 1, timeout);
if (ret<=0) return FLAG_TIMEOUT;
return FLAG_DATA;
}
int rlDF1::getSymbol ( unsigned char *  c)
private

Definition at line 184 of file rldf1.cpp.

{
int ret = tty->readBlock( c, 1, timeout);
if (ret<=0) return FLAG_TIMEOUT;
if (*c!=DLE) {
return FLAG_DATA;
} else {
ret = tty->readBlock( c, 1, timeout);
if (ret<=0) return FLAG_TIMEOUT;
if (*c==DLE) {
return FLAG_DATA;
} else {
return FLAG_CONTROL;
}
}
}
int rlDF1::receiveAnswer ( unsigned char &  destination,
unsigned char &  cmd,
unsigned char &  sts,
unsigned char *  cdata,
unsigned char &  len 
)
private

CRC LOW

CRC HI

Definition at line 386 of file rldf1.cpp.

{
int ret;
static unsigned char response=NAC;
df1Buffer msg;
int flag;
unsigned char rxc;
DBGPRINTF("\n\tDF1::receiveAnswer >");
while(1) {
flag = getSymbol(&rxc);
if ( flag == FLAG_TIMEOUT ) {
DBGPRINTF("\nreceiveAnswer() Timeout....");
break;
} else if ( ( flag==FLAG_CONTROL) && ( rxc == STX) ) {
DBGPRINTF(" DLE STX >")
msg.reset();
while ( (flag=getSymbol(&rxc))==FLAG_DATA ) {
DBGPRINTF("[%02X]", rxc);
msg.write(rxc);
}
if ( rxc != ETX ) {
DBGPRINTF(" [NO ETX] ");
response = NAC;
continue;
}
DBGPRINTF(" ETX \n\t");
flag = get(&rxc);
if ( flag == FLAG_TIMEOUT) {
response = NAC;
continue;
}
DBGPRINTF(" CRCLH:[%02X", rxc);
unsigned short crc = (unsigned short)rxc;
flag = get(&rxc);
if ( flag == FLAG_TIMEOUT) {
response = NAC;
continue;
}
DBGPRINTF(":%02X] ", rxc);
crc += ( (unsigned short)rxc )<<8;
if ( crc != computeCRC( msg.data(), msg.length() ) ) {
DBGPRINTF(" [CRC ERROR] ");
response = NAC;
continue;
}
unsigned short tns_ = (unsigned short)msg[POS_TNSL];
tns_ += ( (unsigned short)msg[POS_TNSH] )<<8;
DBGPRINTF(" TNS:[%04X] ", tns_);
if ( tns_ != tns ) {
DBGPRINTF(" [TNS ERROR] ");
response = ACK;
ret = retERROR_TNS;
break;
}
/* STS is a software error. Handle it in upper layer!
if ( msg[POS_STS]!=0 ) {
DBGPRINTF(" [STS=%02X != 0] ",msg[POS_STS]);
sendACK();
response = ACK;
ret = retERROR_STS;
break;
}
*/
destination = msg[POS_DST];
cmd = msg[POS_CMD];
sts = msg[POS_STS];
len = msg.length()-6;
for (int i=0; i<len; i++) cdata[i] = msg[i + POS_DATA];
response = ACK;
ret = retSUCCESS;
break;
} else if ( ( flag==FLAG_CONTROL) && ( rxc == ENQ) ) {
if (response==ACK) sendACK(); else sendNAC();
ret = retERROR;
break;
} else {
response = NAC;
}
}
return ret;
}
void rlDF1::registerSerial ( rlSerial serial)

Definition at line 160 of file rldf1.cpp.

{
tty = serial;
}
int rlDF1::requests ( )
inline
    Some statistics...

Definition at line 204 of file rldf1.h.

{return nRequests;};
int rlDF1::responses ( )
inline

Definition at line 205 of file rldf1.h.

{return nResponses;};
int rlDF1::sendACK ( )
private

Definition at line 220 of file rldf1.cpp.

{
static unsigned char buf[2];
DBGPRINTF("\nsendACK()");
buf[0] = DLE;
buf[1] = ACK;
return writeBuffer( buf, 2 );
}
int rlDF1::sendCommand ( unsigned char  destination,
unsigned char  cmd,
unsigned char  sts,
unsigned char *  cdata,
unsigned char  len 
)
private
      Functions for Application Layer.
      Normally private. If you want to add new Commands do it with new public functions.
      sendCommand implements sending with retries and handling
        destination = id of remote device
        cmd = Command Code (see page 6-3)
        sts = Status Code (see page 6-6 )
        cdata = Pointer to Command Specific data packet ( Chapter 7 )
        len = Length of cdata
      receiveAnswer gets answer frame from remote.
 

SOURCE

Definition at line 319 of file rldf1.cpp.

{
df1Buffer msg;
df1Buffer fullmsg;
unsigned short crc;
tns++;
DBGPRINTF("\n\tDF1::sendCommand >");
DBGPRINTF(" Dest:%02X", destination);
DBGPRINTF(" CMD:%02X", cmd);
DBGPRINTF(" STS:%02X", sts);
DBGPRINTF(" TNS:%04X", tns);
DBGPRINTF(" DATA [%d]: ",len);
for (int i=0; i<len; i++) { DBGPRINTF("[%02X] ",cdata[i]); }
msg.write( destination );
msg.write( source );
msg.write( cmd );
msg.write( sts );
msg.write( (unsigned char)(tns&0x00FF) );
msg.write( (unsigned char)(tns>>8) );
for(int i=0; i<len; i++) msg.write( cdata[i] );
//msg.print();
crc = computeCRC( msg.data(), msg.length() );
DBGPRINTF(" [CRC=%04X] ",crc);
fullmsg.write( DLE );
fullmsg.write( STX );
for(int i=0; i<(int)msg.length(); i++) fullmsg.writeDLE( *(msg.data()+i) );
fullmsg.write( DLE );
fullmsg.write( ETX );
fullmsg.write( (unsigned char)(crc&0x00FF) );
fullmsg.write( (unsigned char)(crc>>8) );
// TRANSMIT LOOP
int naks=0;
int enq=0;
int flag;
unsigned char rxc;
int ret;
writeBuffer( fullmsg );
while(1) {
flag = getSymbol(&rxc);
if (( flag==FLAG_CONTROL )&&( rxc == ACK )) {
DBGPRINTF(" -> ACK RECEIVED");
ret = retSUCCESS;
break;
} else if (( flag==FLAG_CONTROL )&&( rxc == NAC )) {
naks++;
DBGPRINTF(" -> NAK RECEIVED:%d",naks);
if (naks>=3) {
ret = retERROR_NAC;
break;
}
writeBuffer( fullmsg );
} else if ( flag == FLAG_TIMEOUT ) {
enq++;
DBGPRINTF(" -> TIMEOUT ENQ:%d",enq);
if (enq>=3) {
break;
}
}
}
return ret;
}
int rlDF1::sendENQ ( )
private

Definition at line 211 of file rldf1.cpp.

{
static unsigned char buf[2];
DBGPRINTF("\nsendENQ()");
buf[0] = DLE;
buf[1] = ENQ;
return writeBuffer( buf, 2 );
}
int rlDF1::sendNAC ( )
private

Definition at line 229 of file rldf1.cpp.

{
static unsigned char buf[2];
DBGPRINTF("\nsendNAC()");
buf[0] = DLE;
buf[1] = NAC;
return writeBuffer( buf, 2 );
}
int rlDF1::writeBuffer ( unsigned char *  buffer,
int  len 
)
private

Definition at line 165 of file rldf1.cpp.

{
int ret=-1;
if ( tty!=NULL) {
ret = tty->writeBlock( buffer, len );
}
return ret;
}
int rlDF1::writeBuffer ( df1Buffer buffer)
private

Definition at line 174 of file rldf1.cpp.

{
int ret=-1;
if ( tty!=NULL) {
ret = tty->writeBlock( buffer.data(), buffer.length() );
}
return ret;
}

Member Data Documentation

bool rlDF1::active
private

Definition at line 192 of file rldf1.h.

int rlDF1::nRequests
private

Definition at line 195 of file rldf1.h.

int rlDF1::nResponses
private

Definition at line 196 of file rldf1.h.

unsigned char rlDF1::source
private

Definition at line 197 of file rldf1.h.

int rlDF1::timeout
private

Definition at line 198 of file rldf1.h.

unsigned short rlDF1::tns
private

Definition at line 193 of file rldf1.h.

rlSerial* rlDF1::tty
private

Definition at line 191 of file rldf1.h.


The documentation for this class was generated from the following files: