/* * Copyright (C) 2017 Inria * * This file is subject to the terms and conditions of the GNU Lesser General * Public License v2.1. See the file LICENSE in the top level directory for more * details. */ /** * @ingroup drivers_dynamixel * @{ * * @file * @brief Dynamixel messages writer * * @author Loïc Dauphin * * @} */ #include "dynamixel_writer.h" #include "dynamixel_crc.h" #include #define LOW(v) (v & 0xFF) #define HIGH(v) ((v >> 8) & 0xFF) void dynamixel_writer_init(dynamixel_writer_t *writer, uint8_t *buffer, size_t limit) { writer->buffer = buffer; writer->size = 0; writer->limit = limit; } const uint8_t *dynamixel_writer_get_data(const dynamixel_writer_t *writer) { return (const uint8_t*)writer->buffer; } size_t dynamixel_writer_get_size(const dynamixel_writer_t *writer) { return writer->size; } void dynamixel_writer_ping_make(dynamixel_writer_t *writer, uint8_t id) { const size_t len = 3; if (len + 7 <= writer->limit) { writer->size = len + 7; writer->buffer[0] = DXL_HEADER[0]; writer->buffer[1] = DXL_HEADER[1]; writer->buffer[2] = DXL_HEADER[2]; writer->buffer[3] = 0x00; /* reserved */ writer->buffer[4] = id; writer->buffer[5] = LOW(len); writer->buffer[6] = HIGH(len); writer->buffer[7] = DXL_INST_PING; uint16_t crc = dynamixel_crc_update(0, writer->buffer, 8); writer->buffer[8] = LOW(crc); writer->buffer[9] = HIGH(crc); } else { writer->size = 0; } } void dynamixel_writer_write_make(dynamixel_writer_t *writer, uint8_t id, uint16_t reg, const uint8_t *buffer, size_t size) { const size_t len = 5 + size; if (len + 7 <= writer->limit) { writer->size = len + 7; writer->buffer[0] = DXL_HEADER[0]; writer->buffer[1] = DXL_HEADER[1]; writer->buffer[2] = DXL_HEADER[2]; writer->buffer[3] = 0x00; /* reserved */ writer->buffer[4] = id; writer->buffer[5] = LOW(len); writer->buffer[6] = HIGH(len); writer->buffer[7] = DXL_INST_WRITE; writer->buffer[8] = LOW(reg); writer->buffer[9] = HIGH(reg); memcpy(&writer->buffer[10], buffer, size); uint16_t crc = dynamixel_crc_update(0, writer->buffer, len + 5); writer->buffer[writer->size - 2] = LOW(crc); writer->buffer[writer->size - 1] = HIGH(crc); } else { writer->size = 0; } } void dynamixel_writer_read_make(dynamixel_writer_t *writer, uint8_t id, uint16_t reg, size_t size) { const size_t len = 7; if (len + 7 <= writer->limit) { writer->size = len + 7; writer->buffer[0] = DXL_HEADER[0]; writer->buffer[1] = DXL_HEADER[1]; writer->buffer[2] = DXL_HEADER[2]; writer->buffer[3] = 0x00; /* reserved */ writer->buffer[4] = id; writer->buffer[5] = LOW(len); writer->buffer[6] = HIGH(len); writer->buffer[7] = DXL_INST_READ; writer->buffer[8] = LOW(reg); writer->buffer[9] = HIGH(reg); writer->buffer[10] = LOW(size); writer->buffer[11] = HIGH(size); uint16_t crc = dynamixel_crc_update(0, writer->buffer, 12); writer->buffer[12] = LOW(crc); writer->buffer[13] = HIGH(crc); } else { writer->size = 0; } }