17#define MAX_TMC_DRIVERS 3
20 .
name =
"TMC4671 (CS 1)",
31 .
name =
"TMC4671 (CS 2)" ,
68#ifdef TMC4671_SPI_DATA_IDLENESS
95 this->
flashAddrs =
TMC4671FlashAddrs({ADR_TMC1_MOTCONF, ADR_TMC1_CPR, ADR_TMC1_ENCA, ADR_TMC1_OFFSETFLUX, ADR_TMC1_TORQUE_P, ADR_TMC1_TORQUE_I, ADR_TMC1_FLUX_P, ADR_TMC1_FLUX_I,ADR_TMC1_ADC_I0_OFS,ADR_TMC1_ADC_I1_OFS,ADR_TMC1_ENC_OFFSET,ADR_TMC1_PHIE_OFS,ADR_TMC1_TRQ_FILT});
96 }
else if (address == 2)
98 this->
flashAddrs =
TMC4671FlashAddrs({ADR_TMC2_MOTCONF, ADR_TMC2_CPR, ADR_TMC2_ENCA, ADR_TMC2_OFFSETFLUX, ADR_TMC2_TORQUE_P, ADR_TMC2_TORQUE_I, ADR_TMC2_FLUX_P, ADR_TMC2_FLUX_I,ADR_TMC2_ADC_I0_OFS,ADR_TMC2_ADC_I1_OFS,ADR_TMC2_ENC_OFFSET,ADR_TMC2_PHIE_OFS,ADR_TMC2_TRQ_FILT});
99 }
else if (address == 3)
101 this->
flashAddrs =
TMC4671FlashAddrs({ADR_TMC3_MOTCONF, ADR_TMC3_CPR, ADR_TMC3_ENCA, ADR_TMC3_OFFSETFLUX, ADR_TMC3_TORQUE_P, ADR_TMC3_TORQUE_I, ADR_TMC3_FLUX_P, ADR_TMC3_FLUX_I,ADR_TMC3_ADC_I0_OFS,ADR_TMC3_ADC_I1_OFS,ADR_TMC3_ENC_OFFSET,ADR_TMC3_PHIE_OFS,ADR_TMC3_TRQ_FILT});
194 return (intV > 10000) && (
getExtV() > 10000) && (intV < 78000);
225 return(
readReg(0) == 0x34363731);
233 uint32_t agpiA_VM =
readReg(0x02);
356 int32_t adcval = ((
readReg(0x02)) & 0xffff) - 0x7fff;
361 float r = hwconf->
thermistor_R2 * (((float)43252 / (
float)adcval));
377 for(uint8_t i = 0;i<50;i++){
379 total += (ft.first+ft.second);
382 return(abs(total / 50) < 100);
461 static uint8_t powerCheckCounter = 0;
464 powerCheckCounter = 0;
537 uint32_t tick = HAL_GetTick();
543 bool tmc_en = ((pins >> 15) & 0x01) && pins != 0xffffffff;
569 bool tmc_en = ((pins >> 15) & 0x01) && pins != 0xffffffff;
683 int16_t targetflux_p = targetflux * 0.75;
685 uint16_t fluxI = 0,fluxP = 100;
686 writeReg(0x54, fluxI | (fluxP << 16));
689 while(fluxP < 20000){
690 writeReg(0x54, fluxI | (fluxP << 16));
693 if(flux > targetflux_p){
695 }
else if(flux > targetflux * 0.5){
706 uint32_t measuretime = 50;
707 uint16_t step_i = 64;
710 while(fluxI < 20000){
711 writeReg(0x54, fluxI | (fluxP << 16));
712 uint32_t tick = HAL_GetTick();
713 int32_t peakflux = 0;
716 while(HAL_GetTick() - tick < measuretime){
718 peakflux = std::max<int32_t>(peakflux, flux);
721 uint8_t timeout = 100;
722 while(timeout-- && flux > 10){
727 if(peakflux > (targetflux + ( targetflux * 0.03)))
732 if(peakflux < targetflux*0.95){
743 if(fluxP && fluxP < 20000 && fluxI && fluxI < 20000){
744 newpids.
fluxP = fluxP;
746 newpids.
fluxI = fluxI;
781 if(newState != this->
state){
793 int32_t actualPos =
readReg(0x6B);
794 int32_t targetPos =
readReg(0x68);
795 if( abs(targetPos - actualPos) < tolerance){
803 int32_t npos = (int32_t)
readReg(0x28);
804 int32_t npos_M = (npos * 0xffff) /
abnconf.
cpr;
809 uint32_t phiEphiM =
readReg(0x29);
810 int16_t phiE = ((phiEphiM >> 16) & 0xffff);
811 int16_t phiM = phiEphiM & 0xffff;
845 int32_t timeout = 1000;
880 updateReg(0x25, zeroEncoder ? 1 : 0, 0x1, 9);
935 int64_t phiE_t = (int64_t)
drvEncoder->getPosAbs() * 0xffff;
939 int32_t phiE = (phiE_t / (int64_t)
drvEncoder->getCpr());
966 uint8_t phiEoffsetReg = 0;
968 phiEoffsetReg = 0x29;
974 phiEoffsetReg = 0x45;
995 int16_t phiE_abn_old = 0;
998 while(still < 30 && c++ < 1000){
1000 if(abs(phiE_enc - phiE_abn_old) < 100){
1005 phiE_abn_old = phiE_enc;
1016 int16_t phiEoffset = phiEpos-phiE_enc;
1018 if(phiEoffset == 0){
1024 updateReg(phiEoffsetReg, phiEoffset, 0xffff, 16);
1065 uint32_t minVal_0 = 0xffff, minVal_1 = 0xffff, minVal_2 = 0xffff;
1066 uint32_t maxVal_0 = 0, maxVal_1 = 0, maxVal_2 = 0;
1067 int32_t minpos = -0x8fff/std::max<int32_t>(1,std::min<int32_t>(this->
aencconf.
cpr/4,20)), maxpos = 0x8fff/std::max<int32_t>(1,std::min<int32_t>(this->
aencconf.
cpr/4,20));
1068 uint32_t speed = std::max<uint32_t>(1,20/std::max<uint32_t>(1,this->
aencconf.
cpr/10));
1078 int32_t initialDirPos = 0;
1102 initialDirPos =
readReg(0x41);
1112 uint32_t aencUX =
readReg(0x02)>>16;
1114 uint32_t aencWY_VN =
readReg(0x02) ;
1115 uint32_t aencWY = aencWY_VN >> 16;
1116 uint32_t aencVN = aencWY_VN & 0xffff;
1118 minVal_0 = std::min(minVal_0,aencUX);
1119 minVal_1 = std::min(minVal_1,aencVN);
1120 minVal_2 = std::min(minVal_2,aencWY);
1122 maxVal_0 = std::max(maxVal_0,aencUX);
1123 maxVal_1 = std::max(maxVal_1,aencVN);
1124 maxVal_2 = std::max(maxVal_2,aencWY);
1135 int32_t newDirPos =
readReg(0x41);
1152 return (int16_t)(
readReg(0x2A)>>16);
1154 return (int16_t)(
readReg(0x46)>>16);
1156 return (int16_t)(
readReg(0x39)>>16);
1175 const uint16_t maxcount = 50;
1176 const uint16_t maxfail = 10;
1178 const int16_t targetAngle = 0x3FFF;
1191 int16_t phiE_enc = 0;
1192 uint16_t failcount = 0;
1193 int16_t revCount = 0;
1194 for(int16_t angle = 0;angle<targetAngle;angle+=0x00ff){
1199 int16_t
err = abs(phiE_enc - angle);
1200 int16_t nErr = abs(phiE_enc + angle);
1202 while(
err > 2000 && nErr > 2000 && c++ < 50){
1204 err = abs(phiE_enc - angle);
1205 nErr = abs(angle - phiE_enc);
1213 if(failcount > maxfail){
1235 for(int16_t angle = targetAngle;angle>0;angle -= 0x00ff){
1240 int16_t
err = abs(phiE_enc - angle);
1241 int16_t nErr = abs(phiE_enc + angle);
1243 while(
err > 2500 && nErr > 2500 && c++ < 50){
1245 err = abs(phiE_enc - angle);
1246 nErr = abs(angle - phiE_enc);
1254 if(failcount > maxfail){
1263 if(revCount > maxcount){
1294 (encconf.
bpol << 1) |
1295 (encconf.
npol << 2) |
1298 (encconf.
rdir << 12));
1325 uint32_t mode = encconf.
uvwmode & 0x1;
1326 mode |= (encconf.
rdir & 0x1) << 12;
1361 uint16_t measuretime_idle = time;
1362 uint32_t measurements_idle = 0;
1377 uint32_t tick = HAL_GetTick();
1378 while(HAL_GetTick() - tick < measuretime_idle){
1380 uint32_t adcraw =
readReg(0x02);
1381 uint16_t rawA = adcraw & 0xffff;
1382 uint16_t rawB = (adcraw >> 16) & 0xffff;
1384 if(abs(lastrawA-rawA) < 10000 && abs(lastrawB-rawB) < 10000){
1387 measurements_idle++;
1395 int32_t offsetAidle = totalA / (measurements_idle);
1396 int32_t offsetBidle = totalB / (measurements_idle);
1399 if(totalA < 100 || totalB < 100 || ((abs(offsetAidle - 0x7fff) > TMC_ADCOFFSETFAIL) || (abs(offsetBidle - 0x7fff) > TMC_ADCOFFSETFAIL)) ){
1593 writeReg(0x52, (uint8_t)type & 0xff);
1612 updateReg(0x63, (uint8_t)mode, 0xff, 0);
1744 if(dissipationFlux != 0){
1745 flux = dissipationFlux;
1765 uint32_t vselMode = ((uint8_t)vsel & 0xff) | ((mode & 0xff) << 8);
1775 uint8_t modeReg = 0;
1781 modeReg = 0b1100111;
break;
1783 modeReg = 0b0000111;
break;
1785 modeReg = 0b0000001;
break;
1787 modeReg = 0b0010001;
break;
1789 modeReg = 0b0001001;
break;
1791 modeReg = 0b0011001;
break;
1809 uint32_t reg = pins << 16;
1819 std::string reply =
"";
1821 uint32_t nameInt =
readReg(0);
1822 if(nameInt == 0 || nameInt == 0xffffffff){
1823 reply =
"No driver connected";
1824 return std::pair<uint32_t,std::string>(0,reply);
1827 nameInt = __REV(nameInt);
1828 char*
name =
reinterpret_cast<char*
>(&nameInt);
1829 std::string namestring = std::string(
name,
sizeof(nameInt));
1832 uint32_t versionInt =
readReg(0);
1834 std::string versionstring = std::to_string((versionInt >> 16) && 0xffff) +
"." + std::to_string((versionInt) && 0xffff);
1836 reply +=
"TMC" + namestring +
" v" + versionstring;
1837 return std::pair<uint32_t,std::string>(versionInt,reply);
1844 return static_cast<Encoder*
>(
this);
1867 int32_t tmcpos =
readReg(0x6B);
1868 int32_t
offset = (tmcpos -
pos) % 0xffff;
1896 pos = (int16_t)
readReg(0x2A) & 0xffff;
1955 updateReg(0x09, adc_I0_offset, 0xffff, 0);
1956 updateReg(0x08, adc_I1_offset, 0xffff, 0);
1963 updateReg(0x09, adc_I0_scale, 0xffff, 16);
1964 updateReg(0x08, adc_I1_scale, 0xffff, 16);
1981 updateReg(0x63, (uint8_t)mode, 0xff, 16);
1990 updateReg(0x63, sequential ? 1 : 0, 0x1, 31);
2020 uint32_t mtype = poles | ( ((uint8_t)motor&0xff) << 16);
2047 return readReg(0x64) && 0xffff;
2067 uint16_t startFlux =
readReg(0x64) & 0xffff;
2068 int32_t stepsize = (target - startFlux) / std::max<uint16_t>(1, time_ms/2);
2070 stepsize = startFlux < target ? 1 : -1;
2072 uint16_t flux = startFlux;
2073 while(abs(target - flux) >= abs(stepsize)){
2095 curPids = {(uint16_t)(f&0xffff),(uint16_t)(f>>16),(uint16_t)(t&0xffff),(uint16_t)(t>>16),(uint16_t)(v&0xffff),(uint16_t)(v>>16),(uint16_t)(p&0xffff),(uint16_t)(p>>16)};
2268 uint32_t val = low | (high << 16);
2290 int16_t phiE_abn =
readReg(0x2A)>>16;
2291 int16_t phiE_abn_old = 0;
2292 int16_t rcount=0,c = 0;
2293 uint16_t highcount = 0;
2296 for(int16_t p = 0;p<0x0fff;p+=0x2f){
2300 phiE_abn_old = phiE_abn;
2303 if(phiE_abn < phiE_abn_old){
2306 if((
readReg(0x76) & 0x04) >> 2){
2316 bool npol = highcount > c/2;
2342 int16_t phiE_enc_old = 0;
2343 int16_t rcount=0,c = 0;
2346 for(int16_t p = 0;p<0x0fff;p+=0x2f){
2350 phiE_enc_old = phiE_enc;
2353 if(phiE_enc < phiE_enc_old){
2388 uint32_t bbmr = bbmL | (bbmH << 8);
2426 maxcnt =
clip(maxcnt, 255, 4095);
2445 uint32_t dat = mdecA | (mdecB << 16);
2451 updateReg(0x04, mclkA == 0 ? 0 : 1, 0x1, 4);
2452 updateReg(0x04, mclkB == 0 ? 0 : 1, 0x1, 20);
2462 uint32_t tfluxa =
readReg(0x69);
2463 int16_t af = (tfluxa & 0xffff);
2464 int16_t at = (tfluxa >> 16);
2465 return std::pair<int16_t,int16_t>(af,at);
2472 uint32_t tfluxa =
readReg(0x69);
2473 int16_t af = (tfluxa & 0xffff);
2481 uint32_t tfluxa =
readReg(0x69);
2482 int16_t at = (tfluxa >> 16);
2490 uint8_t req[5] = {(uint8_t)(0x7F & reg),0,0,0,0};
2506 spi_buf[0] = (uint8_t)(0x80 | reg);
2518 spi_buf[0] = (uint8_t)(0x80 | reg);
2523#ifdef TMC4671_ALLOW_DMA
2532 uint32_t t =
readReg(reg) & ~(mask << shift);
2533 t |= ((dat & mask) << shift);
2550 uint32_t flags =
readReg(0x7C);
2618 mot.
svpwm = !(val & 0x4);
2624 uint16_t val = (uint8_t)mconf.
motor_type & 0x3;
2625 val |= !mconf.
svpwm ? 0x4 : 0;
2626 val |= ((uint8_t)mconf.
enctype & 0x7) << 3;
2700 .thermistor_R2 = 1500,
2701 .thermistor_R = 10000,
2702 .thermistor_Beta = 4300,
2703 .temperatureEnabled =
true,
2705 .currentScaler = 2.5 / (0x7fff * 0.066),
2706 .brakeLimLow = 50700,
2707 .brakeLimHigh = 50900,
2708 .vmScaler = (2.5 / 0x7fff) * ((1.5+71.5)/1.5),
2709 .vSenseMult = VOLTAGE_MULT_DEFAULT,
2720 .thermistor_R2 = 1500,
2721 .thermistor_R = 10000,
2722 .thermistor_Beta = 4300,
2723 .temperatureEnabled =
true,
2725 .currentScaler = 2.5 / (0x7fff * 0.1),
2726 .brakeLimLow = 50700,
2727 .brakeLimHigh = 50900,
2728 .vmScaler = (2.5 / 0x7fff) * ((1.5+71.5)/1.5),
2729 .vSenseMult = VOLTAGE_MULT_DEFAULT,
2741 .thermistor_R2 = 1500,
2742 .thermistor_R = 10000,
2743 .thermistor_Beta = 4300,
2744 .temperatureEnabled =
true,
2746 .currentScaler = 2.5 / (0x7fff * 0.04),
2747 .brakeLimLow = 50700,
2748 .brakeLimHigh = 50900,
2749 .vmScaler = (2.5 / 0x7fff) * ((1.5+71.5)/1.5),
2750 .vSenseMult = VOLTAGE_MULT_DEFAULT,
2762 .thermistor_R2 = 1500,
2763 .thermistor_R = 10000,
2764 .thermistor_Beta = 4300,
2765 .temperatureEnabled =
true,
2767 .currentScaler = 2.5 / (0x7fff * 0.08),
2768 .brakeLimLow = 50700,
2769 .brakeLimHigh = 50900,
2770 .vmScaler = (2.5 / 0x7fff) * ((1.5+71.5)/1.5),
2771 .vSenseMult = VOLTAGE_MULT_DEFAULT,
2783 .thermistor_R2 = 1500,
2784 .thermistor_R = 22000,
2785 .thermistor_Beta = 4300,
2786 .temperatureEnabled =
true,
2788 .currentScaler = 2.5 / (0x7fff * 60.0 * 0.0015),
2789 .brakeLimLow = 50700,
2790 .brakeLimHigh = 50900,
2791 .vmScaler = (2.5 / 0x7fff) * ((1.5+71.5)/1.5),
2792 .vSenseMult = VOLTAGE_MULT_DEFAULT,
2808 .thermistor_Beta = 0,
2809 .temperatureEnabled =
false,
2811 .currentScaler = 2.5 / (0x7fff * 60.0 * 0.0015),
2812 .brakeLimLow = 52400,
2813 .brakeLimHigh = 52800,
2814 .vmScaler = (2.5 / 0x7fff) * ((1.5+71.5)/1.5),
2815 .vSenseMult = VOLTAGE_MULT_DEFAULT,
2910 replies.emplace_back((uint32_t)
getState());
2929 replies.emplace_back(
"NONE=0,DC=1,2Ph Stepper=2,3Ph BLDC=3");
2940 replies.emplace_back(
"NONE=0,ABN=1,SinCos=2,Analog UVW=3,Hall=4,External=5");
2942 replies.emplace_back(
"NONE=0,ABN=1,SinCos=2,Analog UVW=3,Hall=4");
2957 replies.emplace_back( std::to_string((uint8_t)v.first) +
":" + v.second,(uint8_t)v.first);
3054 std::pair<uint32_t,std::string> ver =
getTmcType();
3055 replies.emplace_back(ver.second,ver.first);
3074 replies.emplace_back((uint8_t)this->
getPhiEtype());
3078 replies.emplace_back(
"ext=1,openloop=2,abn=3,hall=5,aenc=6,aencE=7");
3117 replies.emplace_back((int32_t)(this->
getTemp()*100.0));
3157 replies.emplace_back(
"OFF=0,Lowpass=1,Notch=2,Peak=3");
3221 extEncUpdater = std::make_unique<TMC_ExternalEncoderUpdateThread>(
this);
3241 if(tmc->usingExternalEncoder() && !tmc->spiPort.isTaken()){
3242 tmc->writeRegAsync(0x1C, (tmc->getPhiEfromExternalEncoder()));
3248 if(tmc->initialized)
TIM_HandleTypeDef TIM_TMC
const std::vector< std::pair< TMC_HW_Ver, std::string > > tmcHwVersionNames
static CommandStatus handleGetFuncSetFunc(const ParsedCommand &cmd, std::vector< CommandReply > &replies, TVal(cls1::*getfunc)(), void(cls2::*setfunc)(TVal), cls *obj)
void registerCommand(const char *cmd, const ID cmdid, const char *help=nullptr, uint32_t flags=0)
virtual void setCommandsEnabled(bool enable)
static CommandStatus handleGetSet(const ParsedCommand &cmd, std::vector< CommandReply > &replies, TVal &value)
void broadcastCommandReply(CommandReply reply, uint32_t cmdId, CMDtype type)
static void clearError(const Error &error)
static void addError(const Error &error)
std::shared_ptr< Encoder > drvEncoder
void transmitReceive(const uint8_t *txbuf, uint8_t *rxbuf, uint16_t size, SPIDevice *device, uint16_t timeout)
void transmit_IT(const uint8_t *buf, uint16_t size, SPIDevice *device)
bool isPinFree(OutputPin pin)
std::pair< uint32_t, float > getClosestPrescaler(float clock)
SPI_HandleTypeDef * getPortHandle()
void transmit(const uint8_t *buf, uint16_t size, SPIDevice *device, uint16_t timeout)
void transmit_DMA(const uint8_t *buf, uint16_t size, SPIDevice *device)
OutputPin * getCsPin(uint16_t idx)
void configurePort(SPI_InitTypeDef *config)
TMC_ExternalEncoderUpdateThread(TMC4671 *tmc)
void writeReg(uint8_t reg, uint32_t dat)
static ClassIdentifier info
void beginSpiTransfer(SPIPort *port)
void setFluxTorque(int16_t flux, int16_t torque)
void saveFlash() override
void setBBM(uint8_t bbml, uint8_t bbmh)
int16_t controlFluxDissipate()
int16_t externalEncoderPhieOffset
TMC_ControlState getState()
void setExternalEncoderAllowed(bool allow)
bool externalEncoderAllowed()
bool allowExternalEncoder
void setLimits(TMC4671Limits limits)
void runOpenLoop(uint16_t ud, uint16_t uq, int32_t speed, int32_t accel, bool torqueMode=false)
bool hasIntegratedEncoder() override
volatile bool encoderIndexHitFlag
void setupFeedForwardVelocity(int32_t gain, int32_t constant)
CommandStatus command(const ParsedCommand &cmd, std::vector< CommandReply > &replies)
uint8_t calibrationFailCount
bool fullCalibrationInProgress
void setEncoderIndexFlagEnabled(bool enabled, bool zeroEncoder=false)
void initializeWithPower()
void setPos(int32_t pos) override
void bangInitEnc(int16_t power)
bool reachedPosition(uint16_t tolerance)
void setPids(TMC4671PIDConf pids)
MotionMode lastMotionMode
const float fluxDissipationLimit
TMC_ControlState requestedState
bool usingExternalEncoder()
void setUdUq(int16_t ud, int16_t uq)
void changeState(TMC_ControlState newState, bool force=false)
const Error lowVoltageError
void setVelSel(VelSelection vsel, uint8_t mode=0)
void setEncoderType(EncoderType_TMC type)
TIM_HandleTypeDef * externalEncoderTimer
TMC4671BiquadFilters curFilters
MotionMode getMotionMode()
TMC_ControlState laststate
void setBrakeLimits(uint16_t low, uint16_t high)
TMC4671PidPrecision pidPrecision
bool recalibrationRequired
uint16_t encodeEncHallMisc()
void setPhiE_ext(int16_t phiE)
int32_t getTargetVelocity()
void timerElapsed(TIM_HandleTypeDef *htim)
void setStatusFlags(uint32_t flags)
void setFluxTorqueFF(int16_t flux, int16_t torque)
void setBiquadVel(const TMC4671Biquad &filter)
void restoreEncHallMisc(uint16_t val)
static uint16_t encodeMotToInt(TMC4671MotConf mconf)
void setTorque(int16_t torque)
bool calibrateAdcOffset(uint16_t time=500)
int32_t getPosAbs() override
void setStatusMask(StatusFlags mask)
void zeroAbnUsingPhiM(bool offsetPhiE=false)
void setSequentialPI(bool sequential)
const float fluxFilterFreq
const Error indexNotHitError
void setup_AENC(TMC4671AENCConf encconf)
Encoder * getEncoder() override
void setGpioPins(uint8_t pins)
void setMotionMode(MotionMode mode, bool force=false)
void setTargetPos(int32_t pos)
void setMotorType(MotorType motor, uint16_t poles)
int32_t getPos() override
void rampFlux(uint16_t target, uint16_t time_ms)
void setPwm(uint8_t val, uint16_t maxcnt, uint8_t bbmL, uint8_t bbmH)
void setGpioMode(TMC_GpioMode mode)
void endSpiTransfer(SPIPort *port)
void errorCallback(const Error &error, bool cleared)
bool motorEnabledRequested
void setHwType(TMC_HW_Ver type)
void setTorqueFilter(TMC4671Biquad_conf &conf)
void emergencyStop(bool reset)
std::pair< int32_t, int32_t > getActualTorqueFlux()
void setup_HALL(TMC4671HALLConf hallconf)
TMC_StartupType startupType
void setTmcPos(int32_t pos)
void setFFMode(FFMode mode)
void setTargetVelocity(int32_t vel)
void setupFeedForwardTorque(int32_t gain, int32_t constant)
void setPhiEtype(PhiE type)
TMC4671(SPIPort &spiport, OutputPin cspin, uint8_t address=1)
void setOpenLoopSpeedAccel(int32_t speed, uint32_t accel)
TMC4671Limits getLimits()
void restoreFlash() override
void updateReg(uint8_t reg, uint32_t dat, uint32_t mask, uint8_t shift)
void setup_ABN_Enc(TMC4671ABNConf encconf)
void setAdcOffset(uint32_t adc_I0_offset, uint32_t adc_I1_offset)
void setPwmMaxCnt(uint16_t maxcnt)
void setCpr(uint32_t cpr)
const Error communicationError
void setBiquadTorque(const TMC4671Biquad &filter)
void setBiquadFlux(const TMC4671Biquad &filter)
uint32_t posToEnc(uint32_t pos)
StatusFlags readFlags(bool maskedOnly=true)
void setUqUdLimit(uint16_t limit)
std::pair< uint32_t, std::string > getTmcType()
void setAddress(uint8_t address)
void exti(uint16_t GPIO_Pin)
void initAdc(uint16_t mdecA, uint16_t mdecB, uint32_t mclkA, uint32_t mclkB)
TMC4671Biquad_conf torqueFilterConf
void setPosSel(PosSelection psel)
void setPwmFreq(float freq)
void writeRegAsync(uint8_t reg, uint32_t dat)
int16_t getPhiEfromExternalEncoder()
std::unique_ptr< TMC_ExternalEncoderUpdateThread > extEncUpdater
void setSvPwm(bool enable)
TMC4671FlashAddrs flashAddrs
const ClassIdentifier getInfo()
Command handlers always have class infos. Works well with ChoosableClass.
void setFlux(int16_t flux)
void setPidPrecision(TMC4671PidPrecision setting)
EncoderType getEncoderType() override
MotionMode nextMotionMode
uint32_t readReg(uint8_t reg)
int32_t getActualTorque()
void setBiquadPos(const TMC4671Biquad &filter)
void setAdcScale(uint32_t adc_I0_scale, uint32_t adc_I1_scale)
bool findEncoderIndex(int32_t speed=10, uint16_t power=2500, bool offsetPhiM=false, bool zeroCount=false)
void setEncoder(std::shared_ptr< Encoder > &encoder) override
uint32_t encToPos(uint32_t enc)
void setPositionExt(int32_t pos)
static TMC4671MotConf decodeMotFromInt(uint16_t val)
void setTorqueLimit(uint16_t limit)
static ClassIdentifier info
static bool isCreatable()
static bool isCreatable()
static ClassIdentifier info
uint32_t WaitForNotification(TickType_t Timeout=portMAX_DELAY)
void Delay(const TickType_t Delay)
bool Flash_Write(uint16_t adr, uint16_t dat)
bool Flash_Read(uint16_t adr, uint16_t *buf, bool checkempty=true)
void blinkClipLed(uint16_t period, uint16_t blinks)
static void * memcpy(void *dst, const void *src, size_t n)
SPI_InitTypeDef peripheral
bool cspol
CSPOL=true === active low.
int16_t posOffsetFromIndex
float fluxDissipationScaler
uint16_t pid_torque_flux_ddt
TMC4671HardwareTypeConf hwconf
bool enableFluxDissipation
void setVSenseMult(float vSenseMultiplier)