tmc2130: Refactor code for setting/changing currents

- Always re-calculate the Vsense flag when the currents are changed
- Make sure Hold current is not larger than Run current
- Added SetCurrents() function from MMU FW
- Added MotorCurrents structure from MMU FW
- Various code size optimisations e.g. in power panic

Change in memory:
Flash: -10 bytes
SRAM: +4 bytes
This commit is contained in:
Guðni Már Gilbert 2023-07-22 00:24:30 +00:00 committed by DRracer
parent a87faba2bd
commit 3819f7a473
4 changed files with 98 additions and 53 deletions

View File

@ -1084,10 +1084,10 @@ void setup()
farm_mode_init();
#ifdef TMC2130
if( FarmOrUserECool() ){
//increased extruder current (PFW363)
tmc2130_current_h[E_AXIS] = TMC2130_CURRENTS_FARM;
tmc2130_current_r[E_AXIS] = TMC2130_CURRENTS_FARM;
if(FarmOrUserECool()) {
//increased extruder current (PFW363)
currents[E_AXIS].iRun = TMC2130_CURRENTS_FARM;
currents[E_AXIS].iHold = TMC2130_CURRENTS_FARM;
}
#endif //TMC2130
@ -4090,7 +4090,7 @@ void process_commands()
tmc2130_chopper_config[axis].hstr = chop1 & 7;
tmc2130_chopper_config[axis].hend = chop2 & 15;
tmc2130_chopper_config[axis].tbl = chop3 & 3;
tmc2130_setup_chopper(axis, tmc2130_mres[axis], tmc2130_current_h[axis], tmc2130_current_r[axis]);
tmc2130_setup_chopper(axis, tmc2130_mres[axis]);
//printf_P(_N("TMC_SET_CHOP_%c %d %d %d %d\n"), "xyze"[axis], chop0, chop1, chop2, chop3);
}
}
@ -8066,9 +8066,9 @@ Sigma_Exit:
}
long cur_mA = code_value_long();
uint8_t val = tmc2130_cur2val(cur_mA);
tmc2130_set_current_h(i, val);
tmc2130_set_current_r(i, val);
//if (i == E_AXIS) printf_P(PSTR("E-axis current=%ldmA\n"), cur_mA);
currents[i].iHold = val;
currents[i].iRun = val;
tmc2130_setup_chopper(i, tmc2130_mres[i]);
}
}
#else //TMC2130
@ -8140,10 +8140,12 @@ Sigma_Exit:
*/
case 911:
{
if (code_seen('X')) tmc2130_set_current_h(0, code_value());
if (code_seen('Y')) tmc2130_set_current_h(1, code_value());
if (code_seen('Z')) tmc2130_set_current_h(2, code_value());
if (code_seen('E')) tmc2130_set_current_h(3, code_value());
for (uint8_t axis = 0; axis < NUM_AXIS; axis++) {
if (code_seen(axis_codes[axis])) {
currents[axis].iHold = code_value_uint8();
tmc2130_setup_chopper(axis, tmc2130_mres[axis]);
}
}
}
break;
@ -8162,10 +8164,12 @@ Sigma_Exit:
*/
case 912:
{
if (code_seen('X')) tmc2130_set_current_r(0, code_value());
if (code_seen('Y')) tmc2130_set_current_r(1, code_value());
if (code_seen('Z')) tmc2130_set_current_r(2, code_value());
if (code_seen('E')) tmc2130_set_current_r(3, code_value());
for (uint8_t axis = 0; axis < NUM_AXIS; axis++) {
if (code_seen(axis_codes[axis])) {
currents[axis].iRun = code_value_uint8();
tmc2130_setup_chopper(axis, tmc2130_mres[axis]);
}
}
}
break;

View File

@ -61,10 +61,12 @@ void uvlo_() {
// Minimise Z and E motor currents (Hold and Run)
#ifdef TMC2130
tmc2130_set_current_h(Z_AXIS, 20);
tmc2130_set_current_r(Z_AXIS, 20);
tmc2130_set_current_h(E_AXIS, 20);
tmc2130_set_current_r(E_AXIS, 20);
currents[Z_AXIS].iHold = 20;
currents[Z_AXIS].iRun = 20;
tmc2130_setup_chopper(Z_AXIS, tmc2130_mres[Z_AXIS]);
currents[E_AXIS].iHold = 20;
currents[E_AXIS].iRun = 20;
tmc2130_setup_chopper(E_AXIS, tmc2130_mres[E_AXIS]);
#endif //TMC2130
if (!sd_print_saved_in_ram && !isPartialBackupAvailable)
@ -225,8 +227,9 @@ static void uvlo_tiny() {
disable_e0();
#ifdef TMC2130
tmc2130_set_current_h(Z_AXIS, 20);
tmc2130_set_current_r(Z_AXIS, 20);
currents[Z_AXIS].iHold = 20;
currents[Z_AXIS].iRun = 20;
tmc2130_setup_chopper(Z_AXIS, tmc2130_mres[Z_AXIS]);
#endif //TMC2130
// Stop all heaters

View File

@ -37,6 +37,13 @@ uint8_t tmc2130_current_r[4] = TMC2130_CURRENTS_R;
//running currents for homing
static uint8_t tmc2130_current_r_home[4] = TMC2130_CURRENTS_R_HOME;
MotorCurrents currents[NUM_AXIS] = {
MotorCurrents(tmc2130_current_r[0], tmc2130_current_h[0]),
MotorCurrents(tmc2130_current_r[1], tmc2130_current_h[1]),
MotorCurrents(tmc2130_current_r[2], tmc2130_current_h[2]),
MotorCurrents(tmc2130_current_r[3], tmc2130_current_h[3])
};
union ChopConfU {
struct __attribute__((packed)) S {
uint32_t toff : 4;
@ -267,9 +274,6 @@ void tmc2130_wr_THIGH(uint8_t axis, uint32_t val32);
static void tmc2130_tx(uint8_t axis, uint8_t addr, uint32_t wval);
static uint8_t tmc2130_rx(uint8_t axis, uint8_t addr, uint32_t* rval);
void tmc2130_setup_chopper(uint8_t axis, uint8_t mres, uint8_t current_h, uint8_t current_r);
uint16_t __tcoolthrs(uint8_t axis)
{
switch (axis)
@ -301,7 +305,7 @@ static void tmc2130_XYZ_reg_init(uint8_t axis)
tmc2130_wr_PWMCONF(axis, pwmconf[axis].dw);
tmc2130_wr_TPWMTHRS(axis, TMC2130_TPWMTHRS);
}
tmc2130_setup_chopper(axis, tmc2130_mres[axis], tmc2130_current_h[axis], tmc2130_current_r[axis]);
tmc2130_setup_chopper(axis, tmc2130_mres[axis]);
tmc2130_wr(axis, TMC2130_REG_TPOWERDOWN, 0x00000000);
}
@ -332,7 +336,7 @@ void tmc2130_init(TMCInitParams params)
}
// E axis
tmc2130_setup_chopper(E_AXIS, tmc2130_mres[E_AXIS], tmc2130_current_h[E_AXIS], tmc2130_current_r[E_AXIS]);
tmc2130_setup_chopper(E_AXIS, tmc2130_mres[E_AXIS]);
tmc2130_wr(E_AXIS, TMC2130_REG_TPOWERDOWN, 0x00000000);
#ifndef TMC2130_STEALTH_E
if( ! params.enableECool ){
@ -420,7 +424,8 @@ void tmc2130_home_enter(uint8_t axes_mask)
tmc2130_wr(axis, TMC2130_REG_GCONF, TMC2130_GCONF_NORMAL);
tmc2130_wr(axis, TMC2130_REG_COOLCONF, (((uint32_t)tmc2130_sg_thr_home[axis]) << 16));
tmc2130_wr(axis, TMC2130_REG_TCOOLTHRS, __tcoolthrs(axis));
tmc2130_setup_chopper(axis, tmc2130_mres[axis], tmc2130_current_h[axis], tmc2130_current_r_home[axis]);
currents[axis].iRun = tmc2130_current_r_home[axis];
tmc2130_setup_chopper(axis, tmc2130_mres[axis]);
tmc2130_wr(axis, TMC2130_REG_GCONF, TMC2130_GCONF_SGSENS); //stallguard output DIAG1, DIAG1 = pushpull
}
}
@ -516,17 +521,38 @@ static constexpr bool getIntpolBit([[maybe_unused]]const uint8_t axis, const uin
return (mres != 0); // intpol to 256 only if microsteps aren't 256
}
void tmc2130_setup_chopper(uint8_t axis, uint8_t mres, uint8_t current_h, uint8_t current_r)
{
bool vsense = 0;
if (current_r <= 31) {
vsense = 1;
} else {
current_r >>= 1;
current_h >>= 1;
}
static void SetCurrents(const uint8_t axis) {
uint8_t iHold = currents[axis].iHold;
const uint8_t iRun = currents[axis].iRun;
ChopConfU chopconf = ChopConfU(vsense, mres);
union IHoldRun {
struct S {
uint8_t iHold;
uint8_t iRun;
uint16_t iHoldDelay;
constexpr S(uint8_t ih, uint8_t ir)
: iHold(ih)
, iRun(ir)
, iHoldDelay(15 & 0x0F) {}
} s;
uint32_t dw;
constexpr IHoldRun(uint8_t ih, uint8_t ir)
: s(ih, ir) {}
};
// also, make sure iHold never exceeds iRun at runtime
IHoldRun ihold_irun((iHold > iRun ? iRun : iHold) & 0x1f, iRun & 0x1f);
tmc2130_wr(axis, TMC2130_REG_IHOLD_IRUN, ihold_irun.dw);
}
void tmc2130_setup_chopper(uint8_t axis, uint8_t mres)
{
// Update the currents, this will re-calculate the Vsense flag
currents[axis] = MotorCurrents(currents[axis].iRun, currents[axis].iHold);
// Initialise the chopper configuration
ChopConfU chopconf = ChopConfU(currents[axis].vSense, mres);
chopconf.s.intpol = getIntpolBit(axis, mres);
chopconf.s.toff = tmc2130_chopper_config[axis].toff; // toff = 3 (fchop = 27.778kHz)
@ -535,30 +561,30 @@ void tmc2130_setup_chopper(uint8_t axis, uint8_t mres, uint8_t current_h, uint8_
chopconf.s.tbl = tmc2130_chopper_config[axis].tbl; //blanking time, original value = 2
tmc2130_wr_CHOPCONF(axis, chopconf.dw);
tmc2130_wr(axis, TMC2130_REG_IHOLD_IRUN, 0x000f0000 | ((current_r & 0x1f) << 8) | (current_h & 0x1f));
SetCurrents(axis);
}
void tmc2130_set_current_h(uint8_t axis, uint8_t current)
{
// DBG(_n("tmc2130_set_current_h(axis=%d, current=%d\n"), axis, current);
tmc2130_current_h[axis] = current;
tmc2130_setup_chopper(axis, tmc2130_mres[axis], tmc2130_current_h[axis], tmc2130_current_r[axis]);
currents[axis].iHold = current;
tmc2130_setup_chopper(axis, tmc2130_mres[axis]);
}
void tmc2130_set_current_r(uint8_t axis, uint8_t current)
{
// DBG(_n("tmc2130_set_current_r(axis=%d, current=%d\n"), axis, current);
tmc2130_current_r[axis] = current;
tmc2130_setup_chopper(axis, tmc2130_mres[axis], tmc2130_current_h[axis], tmc2130_current_r[axis]);
currents[axis].iRun = current;
tmc2130_setup_chopper(axis, tmc2130_mres[axis]);
}
void tmc2130_print_currents()
{
printf_P(_n("tmc2130_print_currents()\n\tH\tR\nX\t%d\t%d\nY\t%d\t%d\nZ\t%d\t%d\nE\t%d\t%d\n"),
tmc2130_current_h[0], tmc2130_current_r[0],
tmc2130_current_h[1], tmc2130_current_r[1],
tmc2130_current_h[2], tmc2130_current_r[2],
tmc2130_current_h[3], tmc2130_current_r[3]
currents[0].iHold, currents[0].iRun,
currents[1].iHold, currents[1].iRun,
currents[2].iHold, currents[2].iRun,
currents[3].iHold, currents[3].iRun
);
}
@ -731,7 +757,7 @@ void tmc2130_set_res(uint8_t axis, uint16_t res)
{
tmc2130_mres[axis] = tmc2130_usteps2mres(res);
// uint32_t u = _micros();
tmc2130_setup_chopper(axis, tmc2130_mres[axis], tmc2130_current_h[axis], tmc2130_current_r[axis]);
tmc2130_setup_chopper(axis, tmc2130_mres[axis]);
// u = _micros() - u;
// printf_P(PSTR("tmc2130_setup_chopper %c %lu us"), "XYZE"[axis], u);
}
@ -858,7 +884,7 @@ void tmc2130_get_wave(uint8_t axis, uint8_t* data, FILE* stream)
{
uint8_t pwr = tmc2130_get_pwr(axis);
tmc2130_set_pwr(axis, 0);
tmc2130_setup_chopper(axis, tmc2130_usteps2mres(256), tmc2130_current_h[axis], tmc2130_current_r[axis]);
tmc2130_setup_chopper(axis, tmc2130_usteps2mres(256));
tmc2130_goto_step(axis, 0, 2, 100, 256);
tmc2130_set_dir(axis, tmc2130_get_inv(axis)?0:1);
for (unsigned int i = 0; i <= 255; i++)
@ -877,7 +903,7 @@ void tmc2130_get_wave(uint8_t axis, uint8_t* data, FILE* stream)
tmc2130_do_step(axis);
delayMicroseconds(100);
}
tmc2130_setup_chopper(axis, tmc2130_mres[axis], tmc2130_current_h[axis], tmc2130_current_r[axis]);
tmc2130_setup_chopper(axis, tmc2130_mres[axis]);
tmc2130_set_pwr(axis, pwr);
}

View File

@ -2,11 +2,10 @@
#define TMC2130_H
#include <stdint.h>
#include "Configuration_var.h"
//mode
extern uint8_t tmc2130_mode;
extern uint8_t tmc2130_current_h[4];
extern uint8_t tmc2130_current_r[4];
//microstep resolution (0 means 256usteps, 8 means 1ustep
extern uint8_t tmc2130_mres[4];
@ -60,6 +59,19 @@ typedef struct
extern tmc2130_chopper_config_t tmc2130_chopper_config[NUM_AXIS];
struct MotorCurrents {
bool vSense; ///< VSense current scaling
uint8_t iRun; ///< Running current
uint8_t iHold; ///< Holding current
constexpr inline __attribute__((always_inline)) MotorCurrents(uint8_t ir, uint8_t ih)
: vSense((ir < 32) ? 1 : 0)
, iRun((ir < 32) ? ir : (ir >> 1))
, iHold((ir < 32) ? ih : (ih >> 1)) {}
};
extern MotorCurrents currents[NUM_AXIS];
//initialize tmc2130
struct TMCInitParams {
@ -94,7 +106,7 @@ extern void tmc2130_sg_measure_start(uint8_t axis);
//stop current stallguard measuring and report result
extern uint16_t tmc2130_sg_measure_stop();
extern void tmc2130_setup_chopper(uint8_t axis, uint8_t mres, uint8_t current_h, uint8_t current_r);
extern void tmc2130_setup_chopper(uint8_t axis, uint8_t mres);
//set holding current for any axis (M911)
extern void tmc2130_set_current_h(uint8_t axis, uint8_t current);