|
|
@ -10,8 +10,8 @@ |
|
|
|
#include "sdk/os/zos.hpp"
|
|
|
|
|
|
|
|
using namespace iflytop; |
|
|
|
#define PRV_FIELD_WRITE(address, mask, shift, value) (writeInt(address, FIELD_SET(readInt(address), mask, shift, value)))
|
|
|
|
#define PRV_FIELD_READ(address, mask, shift) FIELD_GET(readInt(address), mask, shift)
|
|
|
|
#define PRV_FIELD_WRITE(address, mask, shift, value) (tmc4361_writeInt(address, FIELD_SET(tmc4361_readInt(address), mask, shift, value)))
|
|
|
|
#define PRV_FIELD_READ(address, mask, shift) FIELD_GET(tmc4361_readInt(address), mask, shift)
|
|
|
|
|
|
|
|
#define SET_PIN(pin, val) \
|
|
|
|
if (pin) { \ |
|
|
@ -19,15 +19,15 @@ using namespace iflytop; |
|
|
|
} |
|
|
|
|
|
|
|
#if 1
|
|
|
|
void TMC4361A::readWriteArray(uint8_t *data, size_t length) { |
|
|
|
void TMC4361A::tmc4361_readWriteArray(uint8_t *data, size_t length) { |
|
|
|
m_csgpio->setState(false); |
|
|
|
// zchip_clock_early_delayus(10);
|
|
|
|
zchip_clock_early_delayus(10); |
|
|
|
HAL_SPI_TransmitReceive(m_spi, data, data, length, 1000); |
|
|
|
m_csgpio->setState(true); |
|
|
|
} |
|
|
|
void TMC4361A::writeInt(uint8_t address, int32_t value) { writeDatagram(address, BYTE(value, 3), BYTE(value, 2), BYTE(value, 1), BYTE(value, 0)); } |
|
|
|
int32_t TMC4361A::readInt(uint8_t address) { |
|
|
|
void TMC4361A::tmc4361_writeInt(uint8_t address, int32_t value) { tmc4361_writeDatagram(address, BYTE(value, 3), BYTE(value, 2), BYTE(value, 1), BYTE(value, 0)); } |
|
|
|
int32_t TMC4361A::tmc4361_readInt(uint8_t address) { |
|
|
|
CriticalContext cc; |
|
|
|
|
|
|
|
int value; |
|
|
@ -38,23 +38,23 @@ int32_t TMC4361A::readInt(uint8_t address) { |
|
|
|
if (!TMC_IS_READABLE(m_registerAccessTable[address])) return m_defaultRegisterResetState[address]; |
|
|
|
|
|
|
|
data[0] = address; |
|
|
|
readWriteArray(&data[0], 5); |
|
|
|
tmc4361_readWriteArray(&data[0], 5); |
|
|
|
|
|
|
|
data[0] = address; |
|
|
|
readWriteArray(&data[0], 5); |
|
|
|
tmc4361_readWriteArray(&data[0], 5); |
|
|
|
|
|
|
|
m_status = data[0]; |
|
|
|
value = ((uint32_t)data[1] << 24) | ((uint32_t)data[2] << 16) | (data[3] << 8) | data[4]; |
|
|
|
|
|
|
|
return value; |
|
|
|
} |
|
|
|
void TMC4361A::writeDatagram(uint8_t address, uint8_t x1, uint8_t x2, uint8_t x3, uint8_t x4) { |
|
|
|
void TMC4361A::tmc4361_writeDatagram(uint8_t address, uint8_t x1, uint8_t x2, uint8_t x3, uint8_t x4) { |
|
|
|
CriticalContext cc; |
|
|
|
|
|
|
|
int value; |
|
|
|
uint8_t data[5] = {static_cast<uint8_t>(address | static_cast<uint8_t>(TMC4361A_WRITE_BIT)), x1, x2, x3, x4}; |
|
|
|
|
|
|
|
readWriteArray(&data[0], 5); |
|
|
|
tmc4361_readWriteArray(&data[0], 5); |
|
|
|
|
|
|
|
m_status = data[0]; |
|
|
|
|
|
|
@ -65,7 +65,7 @@ void TMC4361A::writeDatagram(uint8_t address, uint8_t x1, uint8_t x2, uint8_t x3 |
|
|
|
shadowRegister[address] = value; |
|
|
|
} |
|
|
|
|
|
|
|
void TMC4361A::readWriteCover(uint8_t *data, size_t length) { |
|
|
|
void TMC4361A::tmc4361_readWriteCover(uint8_t *data, size_t length) { |
|
|
|
CriticalContext cc; |
|
|
|
// Buffering old values to not interrupt manual covering
|
|
|
|
int32_t old_high = shadowRegister[TMC4361A_COVER_HIGH_WR]; |
|
|
@ -82,20 +82,20 @@ void TMC4361A::readWriteCover(uint8_t *data, size_t length) { |
|
|
|
for (i = 0; i < length; i++) bytes[i] = data[length - i - 1]; |
|
|
|
|
|
|
|
// Send the datagram
|
|
|
|
if (length > 4) writeDatagram(TMC4361A_COVER_HIGH_WR, bytes[7], bytes[6], bytes[5], bytes[4]); |
|
|
|
writeDatagram(TMC4361A_COVER_LOW_WR, bytes[3], bytes[2], bytes[1], bytes[0]); |
|
|
|
if (length > 4) tmc4361_writeDatagram(TMC4361A_COVER_HIGH_WR, bytes[7], bytes[6], bytes[5], bytes[4]); |
|
|
|
tmc4361_writeDatagram(TMC4361A_COVER_LOW_WR, bytes[3], bytes[2], bytes[1], bytes[0]); |
|
|
|
|
|
|
|
zos_delay(10); |
|
|
|
|
|
|
|
// Read the reply
|
|
|
|
if (length > 4) { |
|
|
|
tmp = readInt(TMC4361A_COVER_DRV_HIGH_RD); |
|
|
|
tmp = tmc4361_readInt(TMC4361A_COVER_DRV_HIGH_RD); |
|
|
|
bytes[4] = BYTE(tmp, 0); |
|
|
|
bytes[5] = BYTE(tmp, 1); |
|
|
|
bytes[6] = BYTE(tmp, 2); |
|
|
|
bytes[7] = BYTE(tmp, 3); |
|
|
|
} |
|
|
|
tmp = readInt(TMC4361A_COVER_DRV_LOW_RD); |
|
|
|
tmp = tmc4361_readInt(TMC4361A_COVER_DRV_LOW_RD); |
|
|
|
bytes[0] = BYTE(tmp, 0); |
|
|
|
bytes[1] = BYTE(tmp, 1); |
|
|
|
bytes[2] = BYTE(tmp, 2); |
|
|
@ -107,7 +107,7 @@ void TMC4361A::readWriteCover(uint8_t *data, size_t length) { |
|
|
|
} |
|
|
|
|
|
|
|
// Rewriting old values to prevent interrupting manual covering. Imitating unchanged values and state.
|
|
|
|
writeInt(TMC4361A_COVER_HIGH_WR, old_high); |
|
|
|
tmc4361_writeInt(TMC4361A_COVER_HIGH_WR, old_high); |
|
|
|
shadowRegister[TMC4361A_COVER_LOW_WR] = old_low; |
|
|
|
} |
|
|
|
|
|
|
@ -116,16 +116,8 @@ TMC4361A::TMC4361A(/* args */) { |
|
|
|
m_lastCallPeriodicJobTick = 0; |
|
|
|
// m_reachtarget = false;
|
|
|
|
} |
|
|
|
/**
|
|
|
|
* @brief |
|
|
|
* 当调用TMC-API中的tmc4361A_reset/restore时候,TMC-API中的方法会初始化整个芯片的寄存器 |
|
|
|
* 当寄存器初始化完成之后,会调用这个方法?? |
|
|
|
* 我们可以在这个方法中,对芯片的部分寄存器进行初始化?? |
|
|
|
* @param state |
|
|
|
*/ |
|
|
|
void TMC4361A::tmc4361AConfigCallback(ConfigState state) {} |
|
|
|
|
|
|
|
void TMC4361A::writeSubRegister(uint8_t address, uint32_t mask, uint32_t shift, uint32_t value) { //
|
|
|
|
|
|
|
|
void TMC4361A::tmc4361_writeSubRegister(uint8_t address, uint32_t mask, uint32_t shift, uint32_t value) { //
|
|
|
|
PRV_FIELD_WRITE(address, mask, shift, value); |
|
|
|
} |
|
|
|
void TMC4361A::setAcceleration(float accelerationpps2) { |
|
|
@ -143,7 +135,7 @@ void TMC4361A::setAcceleration(float accelerationpps2) { |
|
|
|
|
|
|
|
accelerationpps2 = to_motor_acc(accelerationpps2); |
|
|
|
int32_t acc = (int32_t)accelerationpps2; |
|
|
|
writeInt(TMC4361A_AMAX, acc << 2); |
|
|
|
tmc4361_writeInt(TMC4361A_AMAX, acc << 2); |
|
|
|
} |
|
|
|
void TMC4361A::setDeceleration(float accelerationpps2) { |
|
|
|
/**
|
|
|
@ -158,7 +150,7 @@ void TMC4361A::setDeceleration(float accelerationpps2) { |
|
|
|
*/ |
|
|
|
accelerationpps2 = to_motor_acc(accelerationpps2); |
|
|
|
int32_t acc = (int32_t)accelerationpps2; |
|
|
|
writeInt(TMC4361A_DMAX, acc << 2); |
|
|
|
tmc4361_writeInt(TMC4361A_DMAX, acc << 2); |
|
|
|
} |
|
|
|
#define INIT_GPIO(m_pin, pin, ...) \
|
|
|
|
if (pin != PinNull) { \ |
|
|
@ -194,7 +186,7 @@ void TMC4361A::initialize(cfg_t *cfg) { |
|
|
|
setAcceleration(500000); |
|
|
|
setDeceleration(500000); |
|
|
|
|
|
|
|
enableIC(false); |
|
|
|
enable(false); |
|
|
|
zchip_clock_early_delayus(300 * 1000); |
|
|
|
zchip_clock_early_delayus(300 * 1000); |
|
|
|
|
|
|
@ -219,7 +211,7 @@ uint8_t TMC4361A::reset() { |
|
|
|
if (!TMC_IS_RESETTABLE(m_registerAccessTable[add])) { |
|
|
|
continue; |
|
|
|
} |
|
|
|
writeInt(add, m_defaultRegisterResetState[add]); |
|
|
|
tmc4361_writeInt(add, m_defaultRegisterResetState[add]); |
|
|
|
} |
|
|
|
|
|
|
|
uint8_t driver, dataLength; |
|
|
@ -241,21 +233,17 @@ uint8_t TMC4361A::reset() { |
|
|
|
break; |
|
|
|
} |
|
|
|
value = 0x44400040 | (dataLength << 13) | (driver << 0); |
|
|
|
writeInt(TMC4361A_SPIOUT_CONF, value); |
|
|
|
writeInt(TMC4361A_CURRENT_CONF, 0x00000003); |
|
|
|
writeInt(TMC4361A_SCALE_VALUES, 0x00000000); |
|
|
|
tmc4361_writeInt(TMC4361A_SPIOUT_CONF, value); |
|
|
|
tmc4361_writeInt(TMC4361A_CURRENT_CONF, 0x00000003); |
|
|
|
tmc4361_writeInt(TMC4361A_SCALE_VALUES, 0x00000000); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
uint8_t TMC4361A::restore() { return 1; } |
|
|
|
|
|
|
|
int32_t TMC4361A::getXACTUAL() { return to_user_pos(readInt(TMC4361A_XACTUAL)); } |
|
|
|
void TMC4361A::setXACTUAL(int32_t value) { writeInt(TMC4361A_XACTUAL, to_motor_pos(value)); } |
|
|
|
int32_t TMC4361A::getVACTUAL() { return to_user_pos(readInt(TMC4361A_VACTUAL)); } |
|
|
|
int32_t TMC4361A::getXTARGET() { return to_user_pos(readInt(TMC4361A_X_TARGET)); } |
|
|
|
int32_t TMC4361A::getENC_POS() { return to_user_pos(readInt(TMC4361A_ENC_POS)); } |
|
|
|
void TMC4361A::setENC_POS(int32_t value) { writeInt(TMC4361A_ENC_POS, to_motor_pos(value)); } |
|
|
|
int32_t TMC4361A::getENC_POS_DEV() { return to_user_pos(readInt(TMC4361A_ENC_POS_DEV_RD)); } |
|
|
|
void TMC4361A::enableIC(bool enable) { |
|
|
|
int32_t TMC4361A::getXACTUAL() { return to_user_pos(tmc4361_readInt(TMC4361A_XACTUAL)); } |
|
|
|
void TMC4361A::setXACTUAL(int32_t value) { tmc4361_writeInt(TMC4361A_XACTUAL, to_motor_pos(value)); } |
|
|
|
int32_t TMC4361A::getVACTUAL() { return to_user_pos(tmc4361_readInt(TMC4361A_VACTUAL)); } |
|
|
|
void TMC4361A::enable(bool enable) { |
|
|
|
SET_PIN(m_ennPin, !enable); |
|
|
|
SET_PIN(m_driverIC_ennPin, !enable); |
|
|
|
} |
|
|
@ -271,7 +259,7 @@ void TMC4361A::rotate(int32_t velocity) { |
|
|
|
velocity = to_motor_vel(velocity); |
|
|
|
m_motor_mode = kvelmode; |
|
|
|
PRV_FIELD_WRITE(TMC4361A_RAMPMODE, TMC4361A_OPERATION_MODE_MASK, TMC4361A_OPERATION_MODE_SHIFT, 0); |
|
|
|
writeInt(TMC4361A_VMAX, tmc4361A_discardVelocityDecimals(velocity)); |
|
|
|
tmc4361_writeInt(TMC4361A_VMAX, tmc4361A_discardVelocityDecimals(velocity)); |
|
|
|
} |
|
|
|
void TMC4361A::stop() { rotate(0); } |
|
|
|
void TMC4361A::moveTo(int32_t position, uint32_t velocityMax) { |
|
|
@ -283,46 +271,37 @@ void TMC4361A::moveTo(int32_t position, uint32_t velocityMax) { |
|
|
|
|
|
|
|
m_motor_mode = kposmode; |
|
|
|
PRV_FIELD_WRITE(TMC4361A_RAMPMODE, TMC4361A_OPERATION_MODE_MASK, TMC4361A_OPERATION_MODE_SHIFT, 1); |
|
|
|
writeInt(TMC4361A_VMAX, tmc4361A_discardVelocityDecimals(velocityMax)); |
|
|
|
writeInt(TMC4361A_X_TARGET, position); |
|
|
|
tmc4361_writeInt(TMC4361A_VMAX, tmc4361A_discardVelocityDecimals(velocityMax)); |
|
|
|
tmc4361_writeInt(TMC4361A_X_TARGET, position); |
|
|
|
} |
|
|
|
void TMC4361A::moveBy(int32_t relativePosition, uint32_t velocityMax) { |
|
|
|
relativePosition += readInt(TMC4361A_XACTUAL); |
|
|
|
relativePosition += tmc4361_readInt(TMC4361A_XACTUAL); |
|
|
|
moveTo(relativePosition, velocityMax); |
|
|
|
} |
|
|
|
|
|
|
|
int32_t TMC4361A::readICVersion() { |
|
|
|
int32_t value = readInt(TMC4361A_VERSION_NO_RD); |
|
|
|
return (value & TMC4361A_VERSION_NO_MASK) >> TMC4361A_VERSION_NO_SHIFT; |
|
|
|
tmcic_id_t TMC4361A::readICVersion() { |
|
|
|
int32_t value = tmc4361_readInt(TMC4361A_VERSION_NO_RD); |
|
|
|
return (tmcic_id_t)((value & TMC4361A_VERSION_NO_MASK) >> TMC4361A_VERSION_NO_SHIFT); |
|
|
|
} |
|
|
|
|
|
|
|
int32_t TMC4361A::readSubICVersion() { return driverIC_readICVersion(); } |
|
|
|
/*******************************************************************************
|
|
|
|
* 2160 function end * |
|
|
|
*******************************************************************************/ |
|
|
|
uint32_t TMC4361A::readEVENTS() { |
|
|
|
uint32_t value = readInt(TMC4361A_EVENTS); |
|
|
|
return value; |
|
|
|
} |
|
|
|
uint32_t TMC4361A::haspassedms(uint32_t now, uint32_t last) { |
|
|
|
if (now >= last) { |
|
|
|
return now - last; |
|
|
|
} else { |
|
|
|
return 0xFFFFFFFF - last + now; |
|
|
|
} |
|
|
|
} |
|
|
|
bool TMC4361A::isReachTarget() { |
|
|
|
uint32_t value = readInt(TMC4361A_STATUS); |
|
|
|
// printf("TMC4361A_STATUS:%08x\n", value);
|
|
|
|
uint32_t value = tmc4361_readInt(TMC4361A_STATUS); |
|
|
|
if (m_motor_mode == kposmode) { |
|
|
|
return (value & TMC4361A_TARGET_REACHED_F_MASK) > 0; |
|
|
|
} else { |
|
|
|
return (value & TMC4361A_VEL_REACHED_F_MASK) && (readInt(TMC4361A_VMAX) == 0); |
|
|
|
return (value & TMC4361A_VEL_REACHED_F_MASK) && (tmc4361_readInt(TMC4361A_VMAX) == 0); |
|
|
|
} |
|
|
|
} |
|
|
|
/*******************************************************************************
|
|
|
|
* DRIVER_IC * |
|
|
|
*******************************************************************************/ |
|
|
|
|
|
|
|
void TMC4361A::setGLOBAL_SCALER(int32_t value) { |
|
|
|
if (value > 255) value = 255; |
|
|
|
if (value != 0 && value < 32) value = 32; |
|
|
|
driverIC_writeInt(TMC2160_GLOBAL_SCALER, value); |
|
|
|
} |
|
|
|
|
|
|
|
/***********************************************************************************************************************
|
|
|
|
* DRIVERIC_OPERATION * |
|
|
|
***********************************************************************************************************************/ |
|
|
|
#define DRIVER_ID_FIELD_READ(address, mask, shift) FIELD_GET(driverIC_readInt(address), mask, shift)
|
|
|
|
#define DRIVER_ID_FIELD_WRITE(address, mask, shift, value) (driverIC_writeInt(address, FIELD_SET(driverIC_readInt(address), mask, shift, value)))
|
|
|
|
void TMC4361A::driverIC_reset() { |
|
|
@ -350,7 +329,7 @@ void TMC4361A::driverIC_reset() { |
|
|
|
void TMC4361A::driverIC_enableIC(bool enable) { SET_PIN(m_driverIC_ennPin, !enable); } |
|
|
|
void TMC4361A::driverIC_writeDatagram(uint8_t address, uint8_t x1, uint8_t x2, uint8_t x3, uint8_t x4) { |
|
|
|
uint8_t data[5] = {static_cast<uint8_t>(address | static_cast<uint8_t>(TMC2160_WRITE_BIT)), x1, x2, x3, x4}; |
|
|
|
readWriteCover(&data[0], 5); |
|
|
|
tmc4361_readWriteCover(&data[0], 5); |
|
|
|
} |
|
|
|
void TMC4361A::driverIC_writeInt(uint8_t address, int32_t value) { driverIC_writeDatagram(address, BYTE(value, 3), BYTE(value, 2), BYTE(value, 1), BYTE(value, 0)); } |
|
|
|
int32_t TMC4361A::driverIC_readInt(uint8_t address) { |
|
|
@ -361,10 +340,10 @@ int32_t TMC4361A::driverIC_readInt(uint8_t address) { |
|
|
|
uint8_t data[5]; |
|
|
|
|
|
|
|
data[0] = address; |
|
|
|
readWriteCover(&data[0], 5); |
|
|
|
tmc4361_readWriteCover(&data[0], 5); |
|
|
|
|
|
|
|
data[0] = address; |
|
|
|
readWriteCover(&data[0], 5); |
|
|
|
tmc4361_readWriteCover(&data[0], 5); |
|
|
|
|
|
|
|
return ((uint32_t)data[1] << 24) | ((uint32_t)data[2] << 16) | (data[3] << 8) | data[4]; |
|
|
|
} |
|
|
@ -380,24 +359,9 @@ uint32_t TMC4361A::driverIC_readICVersion() { |
|
|
|
} |
|
|
|
void TMC4361A::driverIC_setIHOLD_IRUN(uint8_t ihold, uint8_t irun, uint16_t iholddelay) { driverIC_writeInt(TMC2160_IHOLD_IRUN, (iholddelay << TMC2160_IHOLDDELAY_SHIFT) | (irun << TMC2160_IRUN_SHIFT) | (ihold << TMC2160_IHOLD_SHIFT)); } |
|
|
|
|
|
|
|
void TMC4361A::setGLOBAL_SCALER(int32_t value) { |
|
|
|
if (value > 255) value = 255; |
|
|
|
if (value != 0 && value < 32) value = 32; |
|
|
|
driverIC_writeInt(TMC2160_GLOBAL_SCALER, value); |
|
|
|
} |
|
|
|
|
|
|
|
// Left Virtual Limit Switch XACTUAL ≤ VIRT_STOP_LEFT 时触发
|
|
|
|
void TMC4361A::setLeftVirtualLimitSwitch(bool enable, int32_t position) { |
|
|
|
PRV_FIELD_WRITE(TMC4361A_REFERENCE_CONF, TMC4361A_VIRTUAL_LEFT_LIMIT_EN_MASK, TMC4361A_VIRTUAL_LEFT_LIMIT_EN_SHIFT, enable ? 1 : 0); |
|
|
|
writeInt(TMC4361A_VIRT_STOP_LEFT, position); |
|
|
|
} |
|
|
|
|
|
|
|
// Right Virtual Limit Switch XACTUAL ≥ VIRT_STOP_RIGHT 时触发
|
|
|
|
void TMC4361A::setRightVirtualLimitSwitch(bool enable, int32_t position) { |
|
|
|
PRV_FIELD_WRITE(TMC4361A_REFERENCE_CONF, TMC4361A_VIRTUAL_RIGHT_LIMIT_EN_MASK, TMC4361A_VIRTUAL_RIGHT_LIMIT_EN_SHIFT, enable ? 1 : 0); |
|
|
|
writeInt(TMC4361A_VIRT_STOP_RIGHT, position); |
|
|
|
} |
|
|
|
|
|
|
|
/***********************************************************************************************************************
|
|
|
|
* POS_CONVERT * |
|
|
|
***********************************************************************************************************************/ |
|
|
|
int32_t TMC4361A::to_motor_acc(int32_t acc) { //
|
|
|
|
int32_t val = acc / 60.0 * 51200; |
|
|
|
return val; |
|
|
@ -419,7 +383,13 @@ int32_t TMC4361A::to_user_vel(int32_t vel) { // |
|
|
|
int32_t val = vel * 60.0 / 51200.0; |
|
|
|
return val; |
|
|
|
} |
|
|
|
|
|
|
|
uint32_t TMC4361A::haspassedms(uint32_t now, uint32_t last) { |
|
|
|
if (now >= last) { |
|
|
|
return now - last; |
|
|
|
} else { |
|
|
|
return 0xFFFFFFFF - last + now; |
|
|
|
} |
|
|
|
} |
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|