Communicate with IAI Robotnet linear actuators

Dependents:   IAILinearActuators

Files at this revision

API Documentation at this revision

Comitter:
henryeherman
Date:
Mon Feb 24 05:54:34 2014 +0000
Commit message:
Initial commit of IAI code to mbed

Changed in this revision

linact.cpp Show annotated file Show diff for this revision Revisions of this file
linact.hpp Show annotated file Show diff for this revision Revisions of this file
linactbuf.cpp Show annotated file Show diff for this revision Revisions of this file
linactbuf.h Show annotated file Show diff for this revision Revisions of this file
linactregdefs.h Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r de88dc2515d3 linact.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/linact.cpp	Mon Feb 24 05:54:34 2014 +0000
@@ -0,0 +1,225 @@
+#include <stdio.h>
+#include <string.h>
+#include <linact.hpp>
+
+namespace IAI {
+
+
+LinearActuator::LinearActuator() {
+}
+
+LinearActuator::~LinearActuator() {
+}
+
+LinActBuf * LinearActuator::getGwStatusStr() {
+  //gwstatus = "\x3f\x03\xf7\x00\x00\x02"
+
+  buffer.reset();
+  buffer.readRegsisterStr(LINACT_GWSTATUS0, 2);
+  return &buffer;
+}
+
+
+LinActBuf * LinearActuator::getGwStartStr() {
+  //alwayson = "\x3f\x06\xf6\x00\x80\x00"
+  // The 15-bit of the GWCTRL register must be set
+  // to enable applicable control, page 163 from
+  // ROBONET(ME0208-13A-A).pdf
+  buffer.reset();
+  buffer.writeRegisterStr(GWCTRL0, GWCTRL_APP_SIG);
+  return &buffer;
+}
+
+
+unsigned short LinearActuator::getAxisReadAddress(unsigned int axisid) {
+
+  switch(axisid) {
+    case 0:
+      return AXIS0_BASE_RD;
+    case 1:
+      return AXIS1_BASE_RD;
+    case 2:
+      return AXIS2_BASE_RD;
+    case 3:
+      return AXIS3_BASE_RD;
+    case 4:
+      return AXIS4_BASE_RD;
+    default:
+      return 0;
+  }
+}
+
+unsigned short LinearActuator::getAxisWriteAddress(unsigned int axisid) {
+
+  switch(axisid) {
+    case 0:
+      return AXIS0_BASE_WR;
+    case 1:
+      return AXIS1_BASE_WR;
+    case 2:
+      return AXIS2_BASE_WR;
+    case 3:
+      return AXIS3_BASE_WR;
+    case 4:
+      return AXIS4_BASE_WR;
+    default:
+      return 0;
+  }
+}
+
+LinActBuf * LinearActuator::getAxisStatus(unsigned int axisid) {
+//axis1alarm = "\x3f\x03\xf7\x12\x00\x01"
+    unsigned short axis_temp_reg;
+    buffer.reset();
+    axis_temp_reg = getAxisReadAddress(axisid) + STATUS_SIG_OFFSET;
+    buffer.readRegsisterStr(axis_temp_reg, 1);
+    return &buffer;
+}
+
+LinActBuf * LinearActuator::getAxisPos(unsigned int axisid) {
+    unsigned short axis_temp_reg;
+    buffer.reset();
+    axis_temp_reg = getAxisReadAddress(axisid) + POS_SET_LO_OFFSET;
+    buffer.readRegsisterStr(axis_temp_reg, 2); // Read 2 to get lo and hi
+    return &buffer;
+}
+
+LinActBuf * LinearActuator::getSetAxisPos(unsigned int axisid, unsigned int position) {
+    unsigned short axis_temp_reg;
+    LinActBuf temp;
+    buffer.reset();
+    axis_temp_reg = getAxisWriteAddress(axisid) + POS_SET_LO_OFFSET;
+    temp.buf[2] = (unsigned char)((position & 0xFF000000) >> 24);
+    temp.buf[3] = (unsigned char)((position & 0x00FF0000) >> 16);
+    temp.buf[0] = (unsigned char)((position & 0x0000FF00) >> 8);
+    temp.buf[1] = (unsigned char)((position & 0x000000FF));
+    temp.len = 4;
+    buffer.writeMultiRegisterStr(axis_temp_reg, 2, temp.buf, temp.len);
+    return &buffer;
+}
+
+
+LinActBuf * LinearActuator::getAxisStart(unsigned int axisid) {
+    //startcmd0 = "\x3f\x06\xf6\x0b\x00\x11"
+    unsigned short int axisreg;
+    unsigned short value;
+    buffer.reset();
+    axisreg = getAxisWriteAddress(axisid) + CNTRL_SIG_OFFSET;
+    value = (AXIS_CTRL_SON|AXIS_CTRL_CSTR);
+    buffer.writeRegisterStr(axisreg, value);
+    return &buffer;
+}
+
+LinActBuf * LinearActuator::getAxisPause(unsigned int axisid) {
+    //pausecmd = "\x3f\x06\xf6\x0b\x00\x14"
+    unsigned short int axisreg;
+    unsigned short value;
+    buffer.reset();
+    axisreg = getAxisWriteAddress(axisid) + CNTRL_SIG_OFFSET;
+    value = (AXIS_CTRL_SON|AXIS_CTRL_STP);
+    buffer.writeRegisterStr(axisreg, value);
+    return &buffer;
+}
+
+LinActBuf * LinearActuator::getAxisReset(unsigned int axisid) {
+    // resetcmd0 = "\x3f\x06\xf6\x0b\x00\x08"
+    unsigned short int axisreg;
+    unsigned short value;
+    buffer.reset();
+    axisreg = getAxisWriteAddress(axisid) + CNTRL_SIG_OFFSET;
+    value = (AXIS_CTRL_RES);
+    buffer.writeRegisterStr(axisreg, value);
+    return &buffer;
+}
+
+LinActBuf * LinearActuator::getAxisHome(unsigned int axisid) {
+    // resetcmd0 = "\x3f\x06\xf6\x0b\x00\x08"
+    unsigned short int axisreg;
+    unsigned short value;
+    buffer.reset();
+    axisreg = getAxisWriteAddress(axisid) + CNTRL_SIG_OFFSET;
+    value = (AXIS_CTRL_HOME|AXIS_CTRL_SON);
+    buffer.writeRegisterStr(axisreg, value);
+    return &buffer;
+}
+
+LinActBuf * LinearActuator::getAxisOn(unsigned int axisid) {
+    // resetcmd0 = "\x3f\x06\xf6\x0b\x00\x08"
+    unsigned short int axisreg;
+    unsigned short value;
+    buffer.reset();
+    axisreg = getAxisWriteAddress(axisid) + CNTRL_SIG_OFFSET;
+    value = (AXIS_CTRL_SON);
+    buffer.writeRegisterStr(axisreg, value);
+    return &buffer;
+}
+
+LinActBuf * LinearActuator::getAxisBrakeRelease(unsigned int axisid) {
+    unsigned short int axisreg;
+    unsigned short value;
+    buffer.reset();
+    axisreg = getAxisWriteAddress(axisid) + CNTRL_SIG_OFFSET;
+    value = (AXIS_CTRL_BKRL);
+    buffer.writeRegisterStr(axisreg, value);
+    return &buffer;
+}
+
+float LinearActuator::getPosition() {
+    long current_pos;
+    unsigned char *payload;
+    
+    if(buffer.rxdata()==0 || checkChecksum() < 0)
+        return NOTPOSMSGERR;
+
+    payload = buffer.rxdata();
+    buffer.rxdatalen();
+
+    if(buffer.rxdatalen()!=4)
+        return NOTPOSMSGERR;
+
+    current_pos = (payload[1]<<0)+(payload[0]<<8) +
+        ((payload[2] & 0x7F)<<24)+(payload[3] <<16);
+
+    if(0x80 & payload[2]) {
+        // Check if we need to flip our sign
+        //printf("Negative\r\n");
+        current_pos = current_pos * -1;
+    }
+
+    return (float) (current_pos / 100.0);
+
+}
+
+LinActBuf * LinearActuator::getBuffer() {
+    return &buffer;
+}
+
+void LinearActuator::send() {
+    // Drive WR pin
+    for(int i=0;i<buffer.len;i++){
+        putchar(buffer.buf[i]);
+    }
+    // Stop driving WR pin to receive
+}
+
+LinActBuf * LinearActuator::receiveStdin(int len) {
+    // Fill buffer
+    for(int i=0;i<len;i++) {
+        pushByteRxBuffer(getc(stdin));
+        //printf("Inbuf.len=%d", rxbuf.len);
+    }
+    LINACTINFO("Receive: %s\r\n", buffer.rx_as_string());
+    return &buffer;
+}
+
+LinActBuf * LinearActuator::pushByteRxBuffer(char c) {
+    buffer.pushRx(c);
+    return &buffer;
+}
+
+int LinearActuator::checkChecksum() {
+    return buffer.rxvalidate();
+}
+
+
+} // End Namespace IAI
diff -r 000000000000 -r de88dc2515d3 linact.hpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/linact.hpp	Mon Feb 24 05:54:34 2014 +0000
@@ -0,0 +1,65 @@
+#ifndef LINACT_H
+#define LINACT_H
+
+#include <linactregdefs.h>
+#include <linactbuf.h>
+#include <cstdio>
+#include <cstring>
+
+
+#if DBGLINACTBUF
+#define LINACTDBG(x, ...) std::printf("[LinAct:DBG]"x"\r\n", ##__VA_ARGS__);
+#define LINACTWARN(x, ...) std::printf("[LinAct:WARN]"x"\r\n", ##__VA_ARGS__);
+#define LINACTERR(x, ...) std::printf("[LinAct:ERR]"x"\r\n", ##__VA_ARGS__);
+#else
+#define LINACTDBG(x, ...)
+#define LINACTWARN(x, ...)
+#define LINACTERR(x, ...)
+#endif
+
+#define LINACTINFO(x, ...) std::printf("[LinAct:INFO]"x"\r\n", ##__VA_ARGS__);
+
+
+
+namespace IAI {
+
+  const float NOTPOSMSGERR = -999999.0;
+
+  class LinearActuator {
+
+    public:
+        LinActBuf buffer;
+        LinearActuator();
+        ~LinearActuator();
+        unsigned short getAxisReadAddress(unsigned int axisid);
+        unsigned short getAxisWriteAddress(unsigned int axisid);
+        LinActBuf * getGwStatusStr();
+        LinActBuf * getGwStartStr();
+        LinActBuf * getAxisStatus(unsigned int axisid);
+        LinActBuf * getAxisPos(unsigned int axisid);
+        LinActBuf * getSetAxisPos(unsigned int axisid,
+                unsigned int position);
+        LinActBuf * getAxisStart(unsigned int axisid);
+        LinActBuf * getAxisPause(unsigned int axisid);
+        LinActBuf * getAxisReset(unsigned int axisid);
+        LinActBuf * getAxisHome(unsigned int axisid);
+        LinActBuf * getAxisOn(unsigned int axisid);
+        LinActBuf * getAxisBrakeRelease(unsigned int axisid);
+
+
+        float getPosition();
+
+        LinActBuf * getBuffer();
+
+        void send();
+        LinActBuf * receiveStdin(int len);
+
+        LinActBuf * pushByteRxBuffer(char c);
+
+        int checkChecksum();
+
+  };
+
+}
+
+#endif /* LINACT_H */
diff -r 000000000000 -r de88dc2515d3 linactbuf.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/linactbuf.cpp	Mon Feb 24 05:54:34 2014 +0000
@@ -0,0 +1,209 @@
+#include <linactbuf.h>
+
+
+namespace IAI {
+
+LinActBuf::LinActBuf() {
+    reset();
+}
+
+void LinActBuf::push(unsigned char value) {
+    len++;
+    *ptr = value;
+    ptr++;
+}
+
+void LinActBuf::pushRx(unsigned char value) {
+    rxlen++;
+    *rxptr = value;
+    rxptr++;
+}
+
+void LinActBuf::reset() {
+    len = 0;
+    ptr = buf;
+    buf[0] = GWADDR;
+    resetRx();
+}
+
+
+void LinActBuf::resetRx() {
+    rxlen = 0;
+    exprxlen = 0;
+    rxptr = rxbuf;
+    rxbuf[0] = 0;
+    rxmsgptr = 0;
+    datalen = 0;
+}
+
+void LinActBuf::copy(LinActBuf *other) {
+    for(int i=0;i<other->len;i++) {
+        buf[i] = other->buf[i];
+    }
+}
+
+unsigned int LinActBuf::crc_update(unsigned int crc, unsigned char a) {
+    crc ^= a;
+    //printf("CRC^=a:0x%x, a=%x\r\n", crc, a);
+    for(int i=0;i<8;i++) {
+        if(crc & 1) {
+            crc = (crc >> 1) ^ 0xA001;
+        } else {
+            crc = crc >> 1;
+        }
+    }
+    //printf("return CRC: 0x%x\r\n", crc);
+    return crc;
+}
+
+void LinActBuf::calc_crc() {
+
+    unsigned short crc = 0xffff;
+
+    for(int i=0;i<len;i++) {
+        crc = crc_update(crc, buf[i]);
+    }
+
+    if (len+2 > LINACT_BUFLEN) {
+        // this is an error so log it
+        LINBUFERR("tried to write beyond buffer length\n");
+        return;
+    }
+    //printf("0x%04x\r\n", crc);
+    buf[len] = (crc & 0xff);
+    buf[len+1] = ((crc & 0xff00) >> 8);
+    len=len+2;
+}
+
+char * LinActBuf::as_string() {
+    strbuf[0]='\0';
+    char tmpbuf[4] = "";
+    for(int i=0;i<len;i++) {
+        sprintf(tmpbuf, "%02X", (unsigned char)buf[i]);
+
+        strcat(strbuf,tmpbuf);
+        //printf("%d:%s\r\n",i, tmpbuf);
+    }
+    return strbuf;
+}
+
+char * LinActBuf::rx_as_string() {
+    rxstrbuf[0]='\0';
+    char tmpbuf[4] = "";
+    for(int i=0;i<len;i++) {
+        sprintf(tmpbuf, "%02X", (unsigned char)buf[i]);
+
+        strcat(rxstrbuf,tmpbuf);
+        //printf("%d:%s\r\n",i, tmpbuf);
+    }
+    return rxstrbuf;
+}
+
+void LinActBuf::readRegsisterStr(unsigned short startreg, unsigned short count) {
+    buf[GWADDRPOS] = GWADDR;
+    buf[CMDPOS] = LINACT_READ_MULTI;
+    buf[2] = (unsigned char)((startreg & 0xFF00) >> 8);
+    buf[3] = (unsigned char)(startreg & 0x00FF);
+    buf[4] = (unsigned char)((count & 0xFF00) >> 8);
+    buf[5] = (unsigned char)(count & 0x00FF);
+    len = 6;
+    calc_crc();
+
+    // See page 151
+    // Header + crc + 2*numreg
+    datalen = 2 * count;
+    exprxlen = 5 + datalen; // Len in bytes
+
+    rxmsgptr = rxbuf + 3;
+}
+
+void LinActBuf::writeRegisterStr(unsigned short reg, unsigned short value) {
+    buf[GWADDRPOS] = GWADDR;
+    buf[CMDPOS] = LINACT_WRITE;
+    buf[2] = (unsigned char)((reg & 0xFF00) >> 8);
+    buf[3] = (unsigned char)(reg & 0x00FF);
+    buf[4] = (unsigned char)((value & 0xFF00) >>8);
+    buf[5] = (unsigned char)(value & 0x00FF);
+    len = 6;
+    calc_crc();
+    rxmsgptr = 0;
+    // See Page 163 for expected len
+    exprxlen = 8; //Len in bytes
+}
+
+void LinActBuf::writeMultiRegisterStr(unsigned short reg,
+    unsigned short reglen, unsigned char * data, unsigned char dlen) {
+
+    buf[GWADDRPOS] = GWADDR;
+    buf[CMDPOS] = LINACT_WRITE_MULTI;
+    buf[2] = (unsigned char)((reg & 0xFF00) >> 8);
+    buf[3] = (unsigned char)(reg & 0x00FF);
+    buf[4] = (unsigned char)((reglen & 0xFF00) >> 8);
+    buf[5] = (unsigned char)(reglen & 0x00FF);
+    buf[6] = dlen;
+
+
+    for(int i=0;i<dlen;i++) {
+        buf[7+i] = data[i];
+    }
+    len = dlen+7;
+    calc_crc();
+
+    // See page 180
+    exprxlen = 8; // Len in bytes
+    rxmsgptr = 0;
+}
+
+
+unsigned char * LinActBuf::rxdata() {
+    return rxmsgptr;
+}
+
+unsigned int LinActBuf::rxdatalen() {
+    return datalen;
+}
+
+// Check the checksum
+int LinActBuf::rxvalidate() {
+
+    if(rxlen != exprxlen)
+        return RXMSGLENERR;
+
+    switch(buf[CMDPOS]) {
+        case LINACT_WRITE:
+            if((buf[len-1] == rxbuf[rxlen-1]) &&
+                    (buf[len-2] == rxbuf[rxlen-2]))
+                return RXWRCRCOK;
+        case LINACT_WRITE_MULTI:
+            if(checkrxcrc())
+                return RXMULWRCRCOK;
+        case LINACT_READ_MULTI:
+            if(checkrxcrc())
+                return RXREADCRCOK;
+        default:
+            break;
+    }
+    return RXINVALIDCRCERR;
+}
+
+int LinActBuf::checkrxcrc() {
+    unsigned short crc = 0xffff;
+
+    if (rxlen < 2)
+        return 0;
+
+    // Check all bytes but last 2
+    for(int i=0;i<(rxlen-2);i++) {
+        crc = crc_update(crc, rxbuf[i]);
+    }
+
+    if(rxbuf[rxlen-2] == (crc & 0xff) &&
+    rxbuf[rxlen-1] == ((crc & 0xff00) >> 8))
+        return 1;
+    LINBUFDBG("Expected CRC 0x%04X\r\n", crc);
+    return 0;
+}
+
+
+} // End IAI Namespace
+
diff -r 000000000000 -r de88dc2515d3 linactbuf.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/linactbuf.h	Mon Feb 24 05:54:34 2014 +0000
@@ -0,0 +1,78 @@
+#ifndef LINACTBUF_H
+#define LINACTBUF_H
+
+#include <cstdio>
+#include <cstring>
+#include <linactregdefs.h>
+
+
+#if DBGLINACTBUF
+#define LINBUFDBG(x, ...) std::printf("[LinActBuf:DBG]"x"\r\n", ##__VA_ARGS__);
+#define LINBUFWARN(x, ...) std::printf("[LinActBuf:WARN]"x"\r\n", ##__VA_ARGS__);
+#define LINBUFERR(x, ...) std::printf("[LinActBuf:ERR]"x"\r\n", ##__VA_ARGS__);
+#else
+#define LINBUFDBG(x, ...)
+#define LINBUFWARN(x, ...)
+#define LINBUFERR(x, ...)
+#endif
+
+#define LINBUFINFO(x, ...) std::printf("[LinActBuf:INFO]"x"\r\n", ##__VA_ARGS__);
+
+namespace IAI {
+
+  const int RXMSGLENERR= -2;
+  const int RXINVALIDCRCERR = -1;
+  const int RXWRCRCOK = 1;
+  const int RXMULWRCRCOK = 2;
+  const int RXREADCRCOK = 3;
+
+  const int GWADDRPOS = 0;
+  const int CMDPOS = 1;
+
+  class  LinActBuf {
+
+    unsigned char *ptr;
+    unsigned char *rxptr;
+    unsigned char *rxmsgptr;
+    public:
+        LinActBuf();
+
+        void push(unsigned char val);
+        void pushRx(unsigned char val);
+        void reset();
+        void resetRx();
+
+        unsigned int len;
+        unsigned int rxlen;
+        unsigned int exprxlen;
+        unsigned int datalen;
+
+        unsigned char buf[LINACT_BUFLEN];
+        unsigned char rxbuf[LINACT_BUFLEN];
+        char strbuf[LINACT_BUFLEN*2];
+        char rxstrbuf[LINACT_BUFLEN*2];
+        void copy(LinActBuf *other);
+        unsigned int crc_update(unsigned int crc,
+                unsigned char a);
+        void calc_crc();
+        char *as_string();
+        char *rx_as_string();
+        void readRegsisterStr(unsigned short startreg,
+                unsigned short count);
+        void writeRegisterStr(unsigned short reg,
+                unsigned short value);
+        void writeMultiRegisterStr(unsigned short reg,
+            unsigned short reglen,
+            unsigned char * data,
+            unsigned char dlen);
+
+        unsigned char * rxdata();
+        unsigned int rxdatalen();
+        int rxvalidate();
+        int checkrxcrc();
+
+  }; // End linactbuf class
+
+}; // End namespace
+
+#endif //~ end LINACTBUF_H
diff -r 000000000000 -r de88dc2515d3 linactregdefs.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/linactregdefs.h	Mon Feb 24 05:54:34 2014 +0000
@@ -0,0 +1,164 @@
+#ifndef LINACTREGDEF_H
+#define LINACTREGDEF_H
+
+#define IS_MBED
+#ifdef IS_MBED
+#include "mbed.h"
+#endif
+
+#define GWADDR       0x3f  // 63 or 0x3f fixed slave address
+#define LINACT_READ_MULTI   0x03
+#define LINACT_WRITE        0x06
+#define LINACT_WRITE_MULTI  0x10
+
+#define GWCTRL0      0xF600
+#define GWCTRL1      0xF601
+
+#define GWCTRL_APP_SIG      (1<<15)
+
+#define AXIS0_BASE_WR        0xF608
+#define AXIS1_BASE_WR        0xF60C
+#define AXIS2_BASE_WR        0xF610
+#define AXIS3_BASE_WR        0xF614
+#define AXIS4_BASE_WR        0xF608
+#define AXIS5_BASE_WR        0xF61C
+
+#define POS_SET_LO_OFFSET    0x0
+
+#define AXIS0_POS_SET_LO   (AXIS0_BASE_WR + POS_SET_LO_OFFSET)
+#define AXIS1_POS_SET_LO   (AXIS1_BASE_WR + POS_SET_LO_OFFSET)
+#define AXIS2_POS_SET_LO   (AXIS2_BASE_WR + POS_SET_LO_OFFSET)
+#define AXIS3_POS_SET_LO   (AXIS3_BASE_WR + POS_SET_LO_OFFSET)
+#define AXIS4_POS_SET_LO   (AXIS4_BASE_WR + POS_SET_LO_OFFSET)
+
+#define POS_SET_HI_OFFSET   0x1
+
+#define AXIS0_POS_SET_HI   (AXIS0_BASE_WR + POS_SET_HI_OFFSET)
+#define AXIS1_POS_SET_HI   (AXIS1_BASE_WR + POS_SET_HI_OFFSET)
+#define AXIS2_POS_SET_HI   (AXIS2_BASE_WR + POS_SET_HI_OFFSET)
+#define AXIS3_POS_SET_HI   (AXIS3_BASE_WR + POS_SET_HI_OFFSET)
+#define AXIS4_POS_SET_HI   (AXIS4_BASE_WR + POS_SET_HI_OFFSET)
+
+#define CMD_POS_SET_OFFSET  0x2
+
+#define AXIS0_CMD_POS_SET   (AXIS0_BASE_WR + CMD_POS_SET_OFFSET)
+#define AXIS1_CMD_POS_SET   (AXIS1_BASE_WR + CMD_POS_SET_OFFSET)
+#define AXIS2_CMD_POS_SET   (AXIS2_BASE_WR + CMD_POS_SET_OFFSET)
+#define AXIS3_CMD_POS_SET   (AXIS3_BASE_WR + CMD_POS_SET_OFFSET)
+#define AXIS4_CMD_POS_SET   (AXIS4_BASE_WR + CMD_POS_SET_OFFSET)
+
+#define CNTRL_SIG_OFFSET    0x3
+
+#define AXIS0_CTRL_SIG      (AXIS0_BASE_WR + CNTRL_SIG_OFFSET)
+#define AXIS1_CTRL_SIG      (AXIS1_BASE_WR + CNTRL_SIG_OFFSET)
+#define AXIS2_CTRL_SIG      (AXIS2_BASE_WR + CNTRL_SIG_OFFSET)
+#define AXIS3_CTRL_SIG      (AXIS3_BASE_WR + CNTRL_SIG_OFFSET)
+#define AXIS4_CTRL_SIG      (AXIS4_BASE_WR + CNTRL_SIG_OFFSET)
+
+#define AXIS_CTRL_BKRL      (1<<15)
+#define AXIS_CTRL_MODE      (1<<10)
+#define AXIS_CTRL_PWRT      (1<<9)
+#define AXIS_CTRL_JOGP      (1<<8)
+#define AXIS_CTRL_JOGN      (1<<7)
+#define AXIS_CTRL_JVEL      (1<<6)
+#define AXIS_CTRL_JISL      (1<<5)
+#define AXIS_CTRL_SON       (1<<4)
+#define AXIS_CTRL_RES       (1<<3)
+#define AXIS_CTRL_STP       (1<<2) // Pause command
+#define AXIS_CTRL_HOME      (1<<1)
+#define AXIS_CTRL_CSTR      (1<<0)
+
+#define LINACT_GWSTATUS0    0xF700
+#define LINACT_GWSTATUS1    0xF701
+
+#define GWSTATUS0_RUN       (1<<15)
+#define GWSTATUS0_ERRT      (1<<14)
+#define GWSTATUS0_MOD       (1<<12)
+#define GWSTATUS0_W8B16     (1<<9)
+#define GWSTATUE0_W8B8      (1<<8)
+#define GWSTATUS0_W8B4      (1<<7)
+#define GWSTATUS0_W8B2      (1<<6)
+#define GWSTATUS0_W8B1      (1<<5)
+#define GWSTATUS0_W4B16     (1<<4)
+#define GWSTATUS0_W4B8      (1<<3)
+#define GWSTATUS0_W4B4      (1<<2)
+#define GWSTATUS0_W4B2      (1<<1)
+#define GWSTATUS0_W4B1      (1<<0)
+
+#define GWSTATUS1_LNK15     (1<<15)
+#define GWSTATUS1_LNK14     (1<<14)
+#define GWSTATUS1_LNK13     (1<<13)
+#define GWSTATUS1_LNK12     (1<<12)
+#define GWSTATUS1_LNK11     (1<<11)
+#define GWSTATUS1_LNK10     (1<<10)
+#define GWSTATUS1_LNK9      (1<<9)
+#define GWSTATUS1_LNK8      (1<<8)
+#define GWSTATUS1_LNK7      (1<<7)
+#define GWSTATUS1_LNK6      (1<<6)
+#define GWSTATUS1_LNK5      (1<<5)
+#define GWSTATUS1_LNK4      (1<<4)
+#define GWSTATUS1_LNK3      (1<<3)
+#define GWSTATUS1_LNK2      (1<<2)
+#define GWSTATUS1_LNK1      (1<<1)
+#define GWSTATUS1_LNK0      (1<<0)
+
+
+
+#define AXIS0_BASE_RD       0xF708
+#define AXIS1_BASE_RD       0xF70C
+#define AXIS2_BASE_RD       0xF710
+#define AXIS3_BASE_RD       0xF714
+#define AXIS4_BASE_RD       0xF718
+
+
+#define POS_GET_LO_OFFSET   0x0
+
+#define AXIS0_POS_GET_LO    (AXIS0_BASE_RD + POS_GET_LO_OFFSET)
+#define AXIS1_POS_GET_LO    (AXIS1_BASE_RD + POS_GET_LO_OFFSET)
+#define AXIS2_POS_GET_LO    (AXIS2_BASE_RD + POS_GET_LO_OFFSET)
+#define AXIS3_POS_GET_LO    (AXIS3_BASE_RD + POS_GET_LO_OFFSET)
+#define AXIS4_POS_GET_LO    (AXIS4_BASE_RD + POS_GET_LO_OFFSET)
+
+#define POS_GET_HI_OFFSET   0x1
+
+#define AXIS0_POS_GET_HI    (AXIS0_BASE_RD + POS_GET_HI_OFFSET)
+#define AXIS1_POS_GET_HI    (AXIS1_BASE_RD + POS_GET_HI_OFFSET)
+#define AXIS2_POS_GET_HI    (AXIS2_BASE_RD + POS_GET_HI_OFFSET)
+#define AXIS3_POS_GET_HI    (AXIS3_BASE_RD + POS_GET_HI_OFFSET)
+#define AXIS4_POS_GET_HI    (AXIS4_BASE_RD + POS_GET_HI_OFFSET)
+
+#define CMPLT_POS_OFFSET    0x2
+
+#define AXIS0_CMPLT_POS     (AXIS0_BASE_RD + CMPLT_POS_OFFSET)
+#define AXIS1_CMPLT_POS     (AXIS1_BASE_RD + CMPLT_POS_OFFSET)
+#define AXIS2_CMPLT_POS     (AXIS2_BASE_RD + CMPLT_POS_OFFSET)
+#define AXIS3_CMPLT_POS     (AXIS3_BASE_RD + CMPLT_POS_OFFSET)
+#define AXIS4_CMPLT_POS     (AXIS4_BASE_RD + CMPLT_POS_OFFSET)
+
+#define STATUS_SIG_OFFSET   0x3
+
+#define AXIS0_STATUS_SIG    (AXIS0_BASE_RD + STATUS_SIG_OFFSET)
+#define AXIS1_STATUS_SIG    (AXIS1_BASE_RD + STATUS_SIG_OFFSET)
+#define AXIS2_STATUS_SIG    (AXIS2_BASE_RD + STATUS_SIG_OFFSET)
+#define AXIS3_STATUS_SIG    (AXIS3_BASE_RD + STATUS_SIG_OFFSET)
+#define AXIS4_STATUS_SIG    (AXIS4_BASE_RD + STATUS_SIG_OFFSET)
+
+#define AXIS_STATUS_EMGS    (1<<15)
+#define AXIS_STATUS_CRDY    (1<<14)
+#define AXIS_STATUS_ZONE1   (1<<13)
+#define AXIS_STATUS_ZONE2   (1<<12)
+#define AXIS_STATUS_PZONE   (1<<11)
+#define AXIS_STATUS_MODES   (1<<10)
+#define AXIS_STATUS_WEND    (1<<9)
+#define AXIS_STATUS_PSFL    (1<<5)
+#define AXIS_STATUS_SV      (1<<4)
+#define AXIS_STATUS_ALM     (1<<3)
+#define AXIS_STATUS_MOVE    (1<<2)
+#define AXIS_STATUS_HEND    (1<<1)
+#define AXIS_STATUS_PEND    (1<<0)
+
+#define LINACT_BUFLEN       (64)
+
+#define TO_HEX(i) (i <= 9 : '0' + i ? 'A' - 10 + i)
+
+#endif // end linactregdef