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