text: /*******************************************************************************
  * Copyright 2017 ROBOTIS CO., LTD.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
  *     http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  *******************************************************************************/
  
  /* Author: Ryu Woon Jung (Leon) */
  
  #ifndef DYNAMIXEL_SDK_INCLUDE_DYNAMIXEL_SDK_PACKETHANDLER_C_H_
  #define DYNAMIXEL_SDK_INCLUDE_DYNAMIXEL_SDK_PACKETHANDLER_C_H_
  
  
  #include <stdio.h>
  #include <stdint.h>
  #include "robotis_def.h"
  #include "port_handler.h"
  
  #if defined(__APPLE__)
  #undef reboot
  #define reboot rebootDXL
  #endif
  
  #define BROADCAST_ID        0xFE    // 254
  #define MAX_ID              0xFC    // 252
  
  /* Macro for Control Table Value */
  #define DXL_MAKEWORD(a, b)  ((uint16_t)(((uint8_t)(((uint64_t)(a)) & 0xff)) | ((uint16_t)((uint8_t)(((uint64_t)(b)) & 0xff))) << 8))
  #define DXL_MAKEDWORD(a, b) ((uint32_t)(((uint16_t)(((uint64_t)(a)) & 0xffff)) | ((uint32_t)((uint16_t)(((uint64_t)(b)) & 0xffff))) << 16))
  #define DXL_LOWORD(l)       ((uint16_t)(((uint64_t)(l)) & 0xffff))
  #define DXL_HIWORD(l)       ((uint16_t)((((uint64_t)(l)) >> 16) & 0xffff))
  #define DXL_LOBYTE(w)       ((uint8_t)(((uint64_t)(w)) & 0xff))
  #define DXL_HIBYTE(w)       ((uint8_t)((((uint64_t)(w)) >> 8) & 0xff))
  
  /* Instruction for DXL Protocol */
  #define INST_PING           1
  #define INST_READ           2
  #define INST_WRITE          3
  #define INST_REG_WRITE      4
  #define INST_ACTION         5
  #define INST_FACTORY_RESET  6
  #define INST_SYNC_WRITE     131     // 0x83
  #define INST_BULK_READ      146     // 0x92
  // --- Only for 2.0 --- //
  #define INST_REBOOT         8
  #define INST_CLEAR          16      // 0x10
  #define INST_STATUS         85      // 0x55
  #define INST_SYNC_READ      130     // 0x82
  #define INST_BULK_WRITE     147     // 0x93
  
  // Communication Result
  #define COMM_SUCCESS        0       // tx or rx packet communication success
  #define COMM_PORT_BUSY      -1000   // Port is busy (in use)
  #define COMM_TX_FAIL        -1001   // Failed transmit instruction packet
  #define COMM_RX_FAIL        -1002   // Failed get status packet
  #define COMM_TX_ERROR       -2000   // Incorrect instruction packet
  #define COMM_RX_WAITING     -3000   // Now recieving status packet
  #define COMM_RX_TIMEOUT     -3001   // There is no status packet
  #define COMM_RX_CORRUPT     -3002   // Incorrect status packet
  #define COMM_NOT_AVAILABLE  -9000   //
  
  typedef struct
  {
    uint8_t     *data_write;
    uint8_t     *data_read;
    uint8_t     *tx_packet;
    uint8_t     *rx_packet;
    uint8_t     error;
    int         communication_result;
    uint8_t     *broadcast_ping_id_list;
  }PacketData;
  
  PacketData *packetData;
  
  WINDECLSPEC void        packetHandler       ();
  
  WINDECLSPEC const char *getTxRxResult       (int protocol_version, int result);
  WINDECLSPEC const char *getRxPacketError    (int protocol_version, uint8_t error);
  
  WINDECLSPEC int         getLastTxRxResult   (int port_num, int protocol_version);
  WINDECLSPEC uint8_t     getLastRxPacketError    (int port_num, int protocol_version);
  
  WINDECLSPEC void        setDataWrite        (int port_num, int protocol_version, uint16_t data_length, uint16_t data_pos, uint32_t data);
  WINDECLSPEC uint32_t    getDataRead         (int port_num, int protocol_version, uint16_t data_length, uint16_t data_pos);
  
  WINDECLSPEC void        txPacket            (int port_num, int protocol_version);
  
  WINDECLSPEC void        rxPacket            (int port_num, int protocol_version);
  
  WINDECLSPEC void        txRxPacket          (int port_num, int protocol_version);
  
  WINDECLSPEC void        ping                (int port_num, int protocol_version, uint8_t id);
  
  WINDECLSPEC uint16_t    pingGetModelNum     (int port_num, int protocol_version, uint8_t id);
  
  // broadcastPing
  WINDECLSPEC void        broadcastPing       (int port_num, int protocol_version);
  WINDECLSPEC uint8_t     getBroadcastPingResult  (int port_num, int protocol_version, int id);
  
  #if defined(__APPLE__)
  WINDECLSPEC void        rebootDXL           (int port_num, int protocol_version, uint8_t id);
  #else
  WINDECLSPEC void        reboot              (int port_num, int protocol_version, uint8_t id);
  #endif
  
  WINDECLSPEC void        clearMultiTurn      (int port_num, int protocol_version, uint8_t id);
  
  WINDECLSPEC void        factoryReset        (int port_num, int protocol_version, uint8_t id, uint8_t option);
  
  WINDECLSPEC void        readTx              (int port_num, int protocol_version, uint8_t id, uint16_t address, uint16_t length);
  WINDECLSPEC void        readRx              (int port_num, int protocol_version, uint16_t length);
  WINDECLSPEC void        readTxRx            (int port_num, int protocol_version, uint8_t id, uint16_t address, uint16_t length);
  
  WINDECLSPEC void        read1ByteTx         (int port_num, int protocol_version, uint8_t id, uint16_t address);
  WINDECLSPEC uint8_t     read1ByteRx         (int port_num, int protocol_version);
  WINDECLSPEC uint8_t     read1ByteTxRx       (int port_num, int protocol_version, uint8_t id, uint16_t address);
  
  WINDECLSPEC void        read2ByteTx         (int port_num, int protocol_version, uint8_t id, uint16_t address);
  WINDECLSPEC uint16_t    read2ByteRx         (int port_num, int protocol_version);
  WINDECLSPEC uint16_t    read2ByteTxRx       (int port_num, int protocol_version, uint8_t id, uint16_t address);
  
  WINDECLSPEC void        read4ByteTx         (int port_num, int protocol_version, uint8_t id, uint16_t address);
  WINDECLSPEC uint32_t    read4ByteRx         (int port_num, int protocol_version);
  WINDECLSPEC uint32_t    read4ByteTxRx       (int port_num, int protocol_version, uint8_t id, uint16_t address);
  
  WINDECLSPEC void    writeTxOnly             (int port_num, int protocol_version, uint8_t id, uint16_t address, uint16_t length);
  WINDECLSPEC void    writeTxRx               (int port_num, int protocol_version, uint8_t id, uint16_t address, uint16_t length);
  
  WINDECLSPEC void    write1ByteTxOnly        (int port_num, int protocol_version, uint8_t id, uint16_t address, uint8_t data);
  WINDECLSPEC void    write1ByteTxRx          (int port_num, int protocol_version, uint8_t id, uint16_t address, uint8_t data);
  
  WINDECLSPEC void    write2ByteTxOnly        (int port_num, int protocol_version, uint8_t id, uint16_t address, uint16_t data);
  WINDECLSPEC void    write2ByteTxRx          (int port_num, int protocol_version, uint8_t id, uint16_t address, uint16_t data);
  
  WINDECLSPEC void    write4ByteTxOnly        (int port_num, int protocol_version, uint8_t id, uint16_t address, uint32_t data);
  WINDECLSPEC void    write4ByteTxRx          (int port_num, int protocol_version, uint8_t id, uint16_t address, uint32_t data);
  
  WINDECLSPEC void    regWriteTxOnly          (int port_num, int protocol_version, uint8_t id, uint16_t address, uint16_t length);
  WINDECLSPEC void    regWriteTxRx            (int port_num, int protocol_version, uint8_t id, uint16_t address, uint16_t length);
  
  WINDECLSPEC void    syncReadTx              (int port_num, int protocol_version, uint16_t start_address, uint16_t data_length, uint16_t param_length);
  // syncReadRx   -> GroupSyncRead
  // syncReadTxRx -> GroupSyncRead
  
  WINDECLSPEC void    syncWriteTxOnly         (int port_num, int protocol_version, uint16_t start_address, uint16_t data_length, uint16_t param_length);
  
  WINDECLSPEC void    bulkReadTx              (int port_num, int protocol_version, uint16_t param_length);
  // bulkReadRx   -> GroupBulkRead
  // bulkReadTxRx -> GroupBulkRead
  
  WINDECLSPEC void    bulkWriteTxOnly         (int port_num, int protocol_version, uint16_t param_length);
  
  #endif /* DYNAMIXEL_SDK_INCLUDE_DYNAMIXEL_SDK_PACKETHANDLER_C_H_ */
  