TMCStepper
TMC2660Stepper.cpp
Go to the documentation of this file.
1 #include "TMCStepper.h"
2 #include "SW_SPI.h"
3 
4 TMC2660Stepper::TMC2660Stepper(uint16_t pinCS, float RS) :
5  _pinCS(pinCS),
6  Rsense(RS)
7  {}
8 
9 TMC2660Stepper::TMC2660Stepper(uint16_t pinCS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK) :
10  _pinCS(pinCS),
11  Rsense(default_RS)
12  {
13  SW_SPIClass *SW_SPI_Obj = new SW_SPIClass(pinMOSI, pinMISO, pinSCK);
14  TMC_SW_SPI = SW_SPI_Obj;
15  }
16 
17 TMC2660Stepper::TMC2660Stepper(uint16_t pinCS, float RS, uint16_t pinMOSI, uint16_t pinMISO, uint16_t pinSCK) :
18  _pinCS(pinCS),
19  Rsense(RS)
20  {
21  SW_SPIClass *SW_SPI_Obj = new SW_SPIClass(pinMOSI, pinMISO, pinSCK);
22  TMC_SW_SPI = SW_SPI_Obj;
23  }
24 
25 void TMC2660Stepper::switchCSpin(bool state) {
26  // Allows for overriding in child class to make use of fast io
27  digitalWrite(_pinCS, state);
28 }
29 
31  uint32_t response = 0UL;
32  uint32_t dummy = ((uint32_t)DRVCONF_register.address<<17) | DRVCONF_register.sr;
33  if (TMC_SW_SPI != nullptr) {
34  switchCSpin(LOW);
35  response |= TMC_SW_SPI->transfer((dummy >> 16) & 0xFF);
36  response <<= 8;
37  response |= TMC_SW_SPI->transfer((dummy >> 8) & 0xFF);
38  response <<= 8;
39  response |= TMC_SW_SPI->transfer(dummy & 0xFF);
40  } else {
41  SPI.beginTransaction(SPISettings(spi_speed, MSBFIRST, SPI_MODE3));
42  switchCSpin(LOW);
43  response |= SPI.transfer((dummy >> 16) & 0xFF);
44  response <<= 8;
45  response |= SPI.transfer((dummy >> 8) & 0xFF);
46  response <<= 8;
47  response |= SPI.transfer(dummy & 0xFF);
48  SPI.endTransaction();
49  }
50  switchCSpin(HIGH);
51  return response >> 4;
52 }
53 
54 void TMC2660Stepper::write(uint8_t addressByte, uint32_t config) {
55  uint32_t data = (uint32_t)addressByte<<17 | config;
56  if (TMC_SW_SPI != nullptr) {
57  switchCSpin(LOW);
58  TMC_SW_SPI->transfer((data >> 16) & 0xFF);
59  TMC_SW_SPI->transfer((data >> 8) & 0xFF);
60  TMC_SW_SPI->transfer(data & 0xFF);
61  } else {
62  SPI.beginTransaction(SPISettings(spi_speed, MSBFIRST, SPI_MODE3));
63  switchCSpin(LOW);
64  SPI.transfer((data >> 16) & 0xFF);
65  SPI.transfer((data >> 8) & 0xFF);
66  SPI.transfer(data & 0xFF);
67  SPI.endTransaction();
68  }
69  switchCSpin(HIGH);
70 }
71 
73  //set pins
74  pinMode(_pinCS, OUTPUT);
75  switchCSpin(HIGH);
76 
77  //TODO: Push shadow registers
78 
79  toff(8); //off_time(8);
80  tbl(1); //blank_time(24);
81 }
82 
83 bool TMC2660Stepper::isEnabled() { return toff() > 0; }
84 
86  uint32_t drv_status = DRVSTATUS();
87  switch (drv_status) {
88  case 0xFFCFF: return 1;
89  case 0: return 2;
90  default: return 0;
91  }
92 }
93 
94 /*
95  Requested current = mA = I_rms/1000
96  Equation for current:
97  I_rms = (CS+1)/32 * V_fs/R_sense * 1/sqrt(2)
98  Solve for CS ->
99  CS = 32*sqrt(2)*I_rms*R_sense/V_fs - 1
100 
101  Example:
102  vsense = 0b0 -> V_fs = 0.310V //Typical
103  mA = 1650mA = I_rms/1000 = 1.65A
104  R_sense = 0.100 Ohm
105  ->
106  CS = 32*sqrt(2)*1.65*0.100/0.310 - 1 = 24,09
107  CS = 24
108 */
109 
110 uint16_t TMC2660Stepper::cs2rms(uint8_t CS) {
111  return (float)(CS+1)/32.0 * (vsense() ? 0.165 : 0.310)/(Rsense+0.02) / 1.41421 * 1000;
112 }
113 
115  return cs2rms(cs());
116 }
117 void TMC2660Stepper::rms_current(uint16_t mA) {
118  uint8_t CS = 32.0*1.41421*mA/1000.0*Rsense/0.310 - 1;
119  // If Current Scale is too low, turn on high sensitivity R_sense and calculate again
120  if (CS < 16) {
121  vsense(true);
122  CS = 32.0*1.41421*mA/1000.0*Rsense/0.165 - 1;
123  } else { // If CS >= 16, turn off high_sense_r
124  vsense(false);
125  }
126 
127  if (CS > 31)
128  CS = 31;
129 
130  cs(CS);
131  //val_mA = mA;
132 }
133 
135  DRVCTRL( sdoff() ? DRVCTRL_1_register.sr : DRVCTRL_0_register.sr);
136  CHOPCONF(CHOPCONF_register.sr);
137  SMARTEN(SMARTEN_register.sr);
138  SGCSCONF(SGCSCONF_register.sr);
139  DRVCONF(DRVCONF_register.sr);
140 }
141 
142 void TMC2660Stepper::hysteresis_end(int8_t value) { hend(value+3); }
143 int8_t TMC2660Stepper::hysteresis_end() { return hend()-3; };
144 
145 void TMC2660Stepper::hysteresis_start(uint8_t value) { hstrt(value-1); }
146 uint8_t TMC2660Stepper::hysteresis_start() { return hstrt()+1; }
147 
148 void TMC2660Stepper::microsteps(uint16_t ms) {
149  switch(ms) {
150  case 256: mres(0); break;
151  case 128: mres(1); break;
152  case 64: mres(2); break;
153  case 32: mres(3); break;
154  case 16: mres(4); break;
155  case 8: mres(5); break;
156  case 4: mres(6); break;
157  case 2: mres(7); break;
158  case 0: mres(8); break;
159  default: break;
160  }
161 }
162 
164  switch(mres()) {
165  case 0: return 256;
166  case 1: return 128;
167  case 2: return 64;
168  case 3: return 32;
169  case 4: return 16;
170  case 5: return 8;
171  case 6: return 4;
172  case 7: return 2;
173  case 8: return 0;
174  }
175  return 0;
176 }
177 
178 void TMC2660Stepper::blank_time(uint8_t value) {
179  switch (value) {
180  case 16: tbl(0b00); break;
181  case 24: tbl(0b01); break;
182  case 36: tbl(0b10); break;
183  case 54: tbl(0b11); break;
184  }
185 }
186 
188  switch (tbl()) {
189  case 0b00: return 16;
190  case 0b01: return 24;
191  case 0b10: return 36;
192  case 0b11: return 54;
193  }
194  return 0;
195 }
TMC2660Stepper::switchCSpin
void switchCSpin(bool state)
Definition: TMC2660Stepper.cpp:25
TMC2660Stepper::hysteresis_start
uint8_t hysteresis_start()
Definition: TMC2660Stepper.cpp:146
TMC2660Stepper::begin
void begin()
Definition: TMC2660Stepper.cpp:72
TMC2660Stepper::microsteps
uint16_t microsteps()
Definition: TMC2660Stepper.cpp:163
TMC2660Stepper::hend
uint8_t hend()
Definition: CHOPCONF.cpp:104
TMC2660Stepper::DRVCTRL
uint32_t DRVCTRL()
Definition: DRVCTRL.cpp:9
TMC2660Stepper::toff
uint8_t toff()
Definition: CHOPCONF.cpp:102
SW_SPIClass
Definition: SW_SPI.h:6
TMC2660Stepper::isEnabled
bool isEnabled()
Definition: TMC2660Stepper.cpp:83
TMCStepper.h
TMC2660Stepper::rms_current
uint16_t rms_current()
Definition: TMC2660Stepper.cpp:114
TMC2660Stepper::tbl
uint8_t tbl()
Definition: CHOPCONF.cpp:108
TMC2660Stepper::SGCSCONF
uint32_t SGCSCONF()
Definition: SGCSCONF.cpp:7
TMC2660Stepper::DRVCONF
uint32_t DRVCONF()
Definition: DRVCONF.cpp:7
SW_SPIClass::transfer
uint8_t transfer(uint8_t ulVal)
Definition: SW_SPI.cpp:24
TMC2660Stepper::cs
uint8_t cs()
Definition: SGCSCONF.cpp:19
TMC2660Stepper::test_connection
uint8_t test_connection()
Definition: TMC2660Stepper.cpp:85
TMC2660Stepper::vsense
bool vsense()
Definition: DRVCONF.cpp:28
TMC2660Stepper::push
void push()
Definition: TMC2660Stepper.cpp:134
TMC2660Stepper::mres
uint8_t mres()
Definition: DRVCTRL.cpp:41
TMC2660Stepper::read
uint32_t read()
Definition: TMC2660Stepper.cpp:30
TMC2660Stepper::DRVSTATUS
uint32_t DRVSTATUS()
Definition: DRVSTATUS.cpp:8
TMC2660Stepper::sdoff
bool sdoff()
Definition: DRVCONF.cpp:27
TMC2660Stepper::write
void write(uint8_t addressByte, uint32_t config)
Definition: TMC2660Stepper.cpp:54
TMC2660Stepper::hstrt
uint8_t hstrt()
Definition: CHOPCONF.cpp:103
TMC2660Stepper::CHOPCONF
uint32_t CHOPCONF()
Definition: CHOPCONF.cpp:85
TMC2660Stepper::SMARTEN
uint32_t SMARTEN()
Definition: SMARTEN.cpp:7
TMC2660Stepper::TMC2660Stepper
TMC2660Stepper(uint16_t pinCS, float RS=default_RS)
Definition: TMC2660Stepper.cpp:4
TMC2660Stepper::blank_time
uint8_t blank_time()
Definition: TMC2660Stepper.cpp:187
TMC2660Stepper::cs2rms
uint16_t cs2rms(uint8_t CS)
Definition: TMC2660Stepper.cpp:110
SW_SPI.h
TMC2660Stepper::hysteresis_end
int8_t hysteresis_end()
Definition: TMC2660Stepper.cpp:143