|
|
@ -12,6 +12,14 @@ using namespace feite; |
|
|
|
ZLOGE(TAG, "motor[%d] do %s fail", id, #func); \ |
|
|
|
return false; \ |
|
|
|
} |
|
|
|
|
|
|
|
static void dumphex(char* tag, uint8_t* data, uint8_t len) { |
|
|
|
printf("%s:", tag); |
|
|
|
for (int i = 0; i < len; i++) { |
|
|
|
printf("%02x ", data[i]); |
|
|
|
} |
|
|
|
printf("\n"); |
|
|
|
} |
|
|
|
void FeiTeServoMotor::initialize(UART_HandleTypeDef* uart, DMA_HandleTypeDef* hdma_rx, DMA_HandleTypeDef* hdma_tx) { |
|
|
|
m_uart = uart; |
|
|
|
m_hdma_rx = hdma_rx; |
|
|
@ -81,9 +89,91 @@ bool FeiTeServoMotor::triggerAysncWrite(uint8_t id) { |
|
|
|
cmd_header->len = 2; |
|
|
|
cmd_header->cmd = 5; |
|
|
|
cmd_header->data[0] = checksum((uint8_t*)cmd_header, sizeof(cmd_header_t) + 1); |
|
|
|
HAL_UART_Transmit(m_uart, m_txbuf, sizeof(cmd_header_t) + 1, 1000); |
|
|
|
|
|
|
|
// HAL_UART_Transmit(m_uart, m_txbuf, sizeof(cmd_header_t) + 1, 1000);
|
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
bool FeiTeServoMotor::rotate(uint8_t id, int16_t speed, uint16_t torque) { |
|
|
|
DO(setmode(id, kMotorMode)); |
|
|
|
if (torque == 0) torque = 1000; |
|
|
|
DO(write_u16(id, kRegServoTorqueLimit, torque)); |
|
|
|
DO(write_s16(id, kRegServoRunSpeed, 15, speed)); |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
bool FeiTeServoMotor::moveTo(uint8_t id, int16_t pos, int16_t speed, uint16_t torque) { |
|
|
|
/**
|
|
|
|
* @brief ÉèÖÃŤ¾Ø |
|
|
|
*/ |
|
|
|
DO(setmode(id, kServoMode)); |
|
|
|
if (torque == 0) torque = 1000; |
|
|
|
DO(write_u16(id, kRegServoTorqueLimit, torque)); |
|
|
|
DO(write_s16(id, kRegServoRunSpeed, 15, speed)); |
|
|
|
DO(setTargetPos(id, pos)); |
|
|
|
return true; |
|
|
|
} |
|
|
|
uint16_t abs16(int16_t val) { |
|
|
|
if (val < 0) { |
|
|
|
return -val; |
|
|
|
} else { |
|
|
|
return val; |
|
|
|
} |
|
|
|
} |
|
|
|
bool FeiTeServoMotor::moveWithTorque(uint8_t id, int16_t torque) { |
|
|
|
DO(setmode(id, kOpenMotorMode)); |
|
|
|
if (torque == 0) torque = 1000; |
|
|
|
DO(write_u16(id, kRegServoTorqueLimit, abs16(torque))); |
|
|
|
DO(write_s16(id, kRegServoRunTime, 15, torque)); |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
static int16_t tosign16(uint16_t* d, int signoff) { |
|
|
|
uint16_t sign = (*d >> signoff) & 0x01; |
|
|
|
uint16_t val = *d & (~(1 << signoff)); |
|
|
|
if (sign == 0) { |
|
|
|
return val; |
|
|
|
} else { |
|
|
|
return -val; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
bool FeiTeServoMotor::read_status(uint8_t id, status_t* status) { |
|
|
|
// kRegServoCurrentPos
|
|
|
|
bool suc = read_reg(id, kRegServoCurrentPos, (uint8_t*)status, sizeof(status_t)); |
|
|
|
status->vel = tosign16((uint16_t*)&status->vel, 15); |
|
|
|
if (!suc) return false; |
|
|
|
return true; |
|
|
|
} |
|
|
|
bool FeiTeServoMotor::read_detailed_status(uint8_t id, detailed_status_t* detailed_status) { |
|
|
|
bool suc = read_reg(id, kRegServoCurrentPos, (uint8_t*)detailed_status, sizeof(*detailed_status)); |
|
|
|
if (!suc) return false; |
|
|
|
detailed_status->vel = tosign16((uint16_t*)&detailed_status->vel, 15); |
|
|
|
detailed_status->torque = tosign16((uint16_t*)&detailed_status->torque, 10); |
|
|
|
|
|
|
|
return true; |
|
|
|
} |
|
|
|
void FeiTeServoMotor::dump_status(status_t* status) { |
|
|
|
ZLOGI(TAG, "===========status==========="); |
|
|
|
ZLOGI(TAG, "= status->pos :%d", status->pos); |
|
|
|
ZLOGI(TAG, "= status->vel :%d", status->vel); |
|
|
|
ZLOGI(TAG, "= status->torque :%d", status->torque); |
|
|
|
ZLOGI(TAG, "="); |
|
|
|
} |
|
|
|
#define BIT_IN_BYTE(byte, off) ((byte >> off) & 0x01)
|
|
|
|
void FeiTeServoMotor::dump_detailed_status(detailed_status_t* detailed_status) { |
|
|
|
ZLOGI(TAG, "===========detailed_status==========="); |
|
|
|
ZLOGI(TAG, "= detailed_status->pos :%d", detailed_status->pos); |
|
|
|
ZLOGI(TAG, "= detailed_status->vel :%d", detailed_status->vel); |
|
|
|
ZLOGI(TAG, "= detailed_status->torque :%d", detailed_status->torque); |
|
|
|
ZLOGI(TAG, "= detailed_status->voltage :%d", detailed_status->voltage); |
|
|
|
ZLOGI(TAG, "= detailed_status->temperature:%d", detailed_status->temperature); |
|
|
|
ZLOGI(TAG, "= detailed_status->state :%d:%d:%d:%d:%d:%d", BIT_IN_BYTE(detailed_status->state, 0), BIT_IN_BYTE(detailed_status->state, 1), BIT_IN_BYTE(detailed_status->state, 2), BIT_IN_BYTE(detailed_status->state, 3), BIT_IN_BYTE(detailed_status->state, 4), |
|
|
|
BIT_IN_BYTE(detailed_status->state, 5)); |
|
|
|
ZLOGI(TAG, "= detailed_status->moveflag :%d", detailed_status->moveflag); |
|
|
|
ZLOGI(TAG, "= detailed_status->current :%d", detailed_status->current); |
|
|
|
ZLOGI(TAG, "="); |
|
|
|
} |
|
|
|
|
|
|
|
bool FeiTeServoMotor::reCalibration(int id, int16_t pos) { |
|
|
|
if (pos < 0 || pos > 4095) { |
|
|
@ -123,19 +213,9 @@ bool FeiTeServoMotor::reCalibration(int id, int16_t pos) { |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
#define DO(func) \
|
|
|
|
if (!(func)) { \ |
|
|
|
ZLOGE(TAG, "motor[%d] do %s fail", id, #func); \ |
|
|
|
return false; \ |
|
|
|
} |
|
|
|
|
|
|
|
static void dumphex(char* tag, uint8_t* data, uint8_t len) { |
|
|
|
printf("%s:", tag); |
|
|
|
for (int i = 0; i < len; i++) { |
|
|
|
printf("%02x ", data[i]); |
|
|
|
} |
|
|
|
printf("\n"); |
|
|
|
} |
|
|
|
/*******************************************************************************
|
|
|
|
* BASEFUNC * |
|
|
|
*******************************************************************************/ |
|
|
|
bool FeiTeServoMotor::write_u8(uint8_t id, feite::reg_add_e add, uint8_t regval) { return write_reg(id, false, add, ®val, 1); } |
|
|
|
bool FeiTeServoMotor::read_u8(uint8_t id, feite::reg_add_e add, uint8_t& regval) { return read_reg(id, add, ®val, 1); } |
|
|
|
bool FeiTeServoMotor::write_u16(uint8_t id, feite::reg_add_e add, uint16_t regval) { return write_reg(id, false, add, (uint8_t*)®val, 2); } |
|
|
|