uStepper S
uStepperDriver.cpp
Go to the documentation of this file.
1 /********************************************************************************************
2 * File: uStepperDriver.cpp *
3 * Version: 2.0.0 *
4 * Date: March 30th, 2020 *
5 * Author: Thomas Hørring Olsen *
6 * *
7 *********************************************************************************************
8 * (C) 2020 *
9 * *
10 * uStepper ApS *
11 * www.ustepper.com *
12 * administration@ustepper.com *
13 * *
14 * The code contained in this file is released under the following open source license: *
15 * *
16 * Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International *
17 * *
18 * The code in this file is provided without warranty of any kind - use at own risk! *
19 * neither uStepper ApS nor the author, can be held responsible for any damage *
20 * caused by the use of the code contained in this file ! *
21 * *
22 ********************************************************************************************/
32 #include <uStepperS.h>
33 
34 extern uStepperS * pointer;
35 
37 }
38 
39 
40 void uStepperDriver::reset( void ){
41 
42  // Reset stallguard
43  this->writeRegister( TCOOLTHRS, 0 );
44  this->writeRegister( THIGH, 0);
45  this->writeRegister( COOLCONF, 0 );
46  this->writeRegister( SW_MODE, 0 );
47  this->clearStall();
48 
49  this->writeRegister(XACTUAL, 0);
50  this->writeRegister(XTARGET, 0);
51 
52  this->writeRegister( IHOLD_IRUN,0 );
53  this->writeRegister( CHOPCONF, 0 );
54  this->writeRegister( GCONF, 0 );
55  this->writeRegister( PWMCONF, 0 );
56  this->writeRegister( TPWMTHRS, 0 );
57 
58  this->writeRegister( RAMPMODE, 0 );
59  this->writeRegister( VSTART, 0 );
60  this->writeRegister( A1, 0 );
61  this->writeRegister( V1, 0 );
62  this->writeRegister( AMAX, 0 );
63  this->writeRegister( VMAX, 0 );
64  this->writeRegister( D1, 0 );
65  this->writeRegister( VSTOP, 0 );
66 
67 }
68 
69 void uStepperDriver::init( uStepperS * _pointer ){
70 
71  this->pointer = _pointer;
72  this->chipSelect(true); // Set CS HIGH
73 
74  // First clear previous defined registers
75  this->reset();
76 
77  /* Set motor current */
78  this->writeRegister( IHOLD_IRUN, IHOLD( this->holdCurrent) | IRUN( this->current) | IHOLDDELAY( this->holdDelay) );
79 
80  this->enableStealth();
81 
82  /* Set all-round chopper configuration */
83  this->writeRegister( CHOPCONF, TOFF(2) | TBL(2) | HSTRT_TFD(4) | HEND(0));
84 
85  /* Set startup ramp mode */
87 
88  /* Reset position */
89  this->writeRegister(XACTUAL, 0);
90  this->writeRegister(XTARGET, 0);
91 
92  this->setDeceleration( 0xFFFE );
93  this->setAcceleration( 0xFFFE );
94 
95  this->stop();
96 
97  while(this->readRegister(VACTUAL) != 0);
98 }
99 
101 {
102  while(TCNT1 > 15900); //If interrupt is just about to happen, wait for it to finish
103  this->readRegister(XACTUAL);
104 }
105 
106 void uStepperDriver::setVelocity( uint32_t velocity )
107 {
108  this->VMAX = velocity;
109 
110  if(this->VMAX > 0x7FFE00)
111  {
112  this->VMAX = 0x7FFE00;
113  }
114 
115  this->writeRegister(VMAX_REG, this->VMAX);
116 }
117 
118 void uStepperDriver::setAcceleration( uint32_t acceleration )
119 {
120  this->AMAX = acceleration;
121 
122  if(this->AMAX > 0xFFFE)
123  {
124  this->AMAX = 0xFFFE;
125  }
126 
127  this->writeRegister(AMAX_REG, this->AMAX);
128 }
129 
130 void uStepperDriver::setDeceleration( uint32_t deceleration )
131 {
132  this->DMAX = deceleration;
133 
134  if(this->DMAX > 0xFFFE)
135  {
136  this->DMAX = 0xFFFE;
137  }
138 
139  this->writeRegister(DMAX_REG, this->DMAX);
140 }
141 
142 void uStepperDriver::setCurrent( uint8_t current )
143 {
144  this->current = current;
145  this->updateCurrent();
146 }
147 
148 void uStepperDriver::setHoldCurrent( uint8_t current )
149 {
150  this->holdCurrent = current;
151  this->updateCurrent();
152 }
153 
155 {
156  this->writeRegister( IHOLD_IRUN, IHOLD( this->holdCurrent) | IRUN( this->current) | IHOLDDELAY( this->holdDelay) );
157 }
158 
159 void uStepperDriver::setPosition( int32_t position )
160 {
161  this->mode = DRIVER_POSITION;
163  this->writeRegister(XTARGET, position);
164  this->xTarget = position;
165 }
166 
167 void uStepperDriver::setShaftDirection( bool direction )
168 {
169  // Read the register to save the settings
170  int32_t value = this->readRegister( GCONF );
171  // Update the direction bit
172  if(direction == 1){
173  value |= (0x01 << 4);
174  }else{
175  value &= ~(0x01 << 4);
176  }
177  this->writeRegister( GCONF, value );
178 }
179 
180 void uStepperDriver::setDirection( bool direction )
181 {
182  this->mode = DRIVER_VELOCITY;
183  if(direction){
185  }else{
187  }
188 }
189 
190 void uStepperDriver::setRampMode( uint8_t mode ){
191 
192  switch(mode){
193  case POSITIONING_MODE:
194  // Positioning mode
195  this->writeRegister(VSTART_REG, this->VSTART);
196  this->writeRegister(A1_REG, this->A1);
197  this->writeRegister(V1_REG, this->V1);
198  this->writeRegister(AMAX_REG, this->AMAX);
199  this->writeRegister(VMAX_REG, this->VMAX);
200  this->writeRegister(DMAX_REG, this->DMAX);
201  this->writeRegister(D1_REG, this->D1);
202  this->writeRegister(VSTOP_REG, this->VSTOP); /* Minimum 10 in POSITIONING_MODE */
203  this->writeRegister(RAMPMODE, POSITIONING_MODE); /* RAMPMODE = POSITIONING_MODE */
204  break;
205 
206  case VELOCITY_MODE_POS:
207  // Velocity mode (only AMAX and VMAX is used)
208  this->writeRegister(VSTART_REG, this->VSTART);
209  this->writeRegister(A1_REG, 0);
210  this->writeRegister(V1_REG, 0);
211  this->writeRegister(AMAX_REG, this->AMAX);
212  this->writeRegister(VMAX_REG, this->VMAX);
213  this->writeRegister(DMAX_REG, 0);
214  this->writeRegister(D1_REG, 0);
215  this->writeRegister(VSTOP_REG, 0);
216  this->writeRegister(RAMPMODE, VELOCITY_MODE_POS); /* RAMPMODE = VELOCITY_MODE_POS */
217  break;
218  }
219 }
220 
222 {
223  /* Set GCONF and enable stealthChop */
224  this->writeRegister( GCONF, EN_PWM_MODE(1) | I_SCALE_ANALOG(1) );
225 
226  /* Set PWMCONF for StealthChop */
227  this->writeRegister( PWMCONF, PWM_AUTOSCALE(1) | PWM_GRAD(1) | PWM_AMPL(128) | PWM_FREQ(0) | FREEWHEEL(2) );
228 
229  /* Specifies the upper velocity (lower time delay) for operation in stealthChop voltage PWM mode */
230  this->writeRegister( TPWMTHRS, 5000 );
231 }
232 
233 int32_t uStepperDriver::getVelocity( void )
234 {
235  return this->readRegister(VACTUAL);
236 }
237 
238 int32_t uStepperDriver::getPosition( void )
239 {
240  return this->readRegister(XACTUAL);
241 }
242 
243 void uStepperDriver::stop( void )
244 {
245  this->mode = DRIVER_STOP;
246  this->setVelocity(0);
247 }
248 
249 void uStepperDriver::setHome(int32_t initialSteps)
250 {
251  int32_t xActual, xTarget;
252 
253  if(this->mode == DRIVER_POSITION)
254  {
255  xActual = this->getPosition();
256  xTarget = this->readRegister(XTARGET);
257 
258  xTarget -= xActual;
259  this->xTarget = xTarget + initialSteps;
260  this->xActual = initialSteps;
261  this->writeRegister(XACTUAL, initialSteps);
262  this->writeRegister(XTARGET, this->xTarget);
263  }
264  else
265  {
266  this->xTarget = initialSteps;
267  this->xActual = initialSteps;
268  this->writeRegister(XACTUAL, initialSteps);
269  this->writeRegister(XTARGET, initialSteps);
270  }
271 
272  pointer->pidPositionStepsIssued = initialSteps;
273 }
274 
275 int32_t uStepperDriver::writeRegister( uint8_t address, uint32_t datagram ){
276 
277  // Disabled interrupts until write is complete
278  //cli();
279  TIMSK1 &= ~(1 << OCIE1A);
280  // Enable SPI mode 3 to use TMC5130
281  this->pointer->setSPIMode(3);
282 
283  uint32_t package = 0;
284 
285  // Add the value of WRITE_ACCESS to enable register write
286  address += WRITE_ACCESS;
287 
288  this->chipSelect(false);
289 
290  this->status = this->pointer->SPI(address);
291 
292  package |= this->pointer->SPI((datagram >> 24) & 0xff);
293  package <<= 8;
294  package |= this->pointer->SPI((datagram >> 16) & 0xff);
295  package <<= 8;
296  package |= this->pointer->SPI((datagram >> 8) & 0xff);
297  package <<= 8;
298  package |= this->pointer->SPI((datagram) & 0xff);
299 
300  this->chipSelect(true); // Set CS HIGH
301 
302  //sei();
303  TIMSK1 |= (1 << OCIE1A);
304  return package;
305 }
306 
307 int32_t uStepperDriver::readRegister( uint8_t address )
308 {
309  // Disabled interrupts until write is complete
310  //cli();
311  TIMSK1 &= ~(1 << OCIE1A);
312 
313  // Enable SPI mode 3 to use TMC5130
314  this->pointer->setSPIMode(3);
315 
316  // Request a reading on address
317  this->chipSelect(false);
318  this->status = this->pointer->SPI(address);
319  this->pointer->SPI(0x00);
320  this->pointer->SPI(0x00);
321  this->pointer->SPI(0x00);
322  this->pointer->SPI(0x00);
323  this->chipSelect(true);
324 
325  // Read the actual value on second request
326  int32_t value = 0;
327 
328  this->chipSelect(false);
329  this->status = this->pointer->SPI(address);
330  value |= this->pointer->SPI(0x00);
331  value <<= 8;
332  value |= this->pointer->SPI(0x00);
333  value <<= 8;
334  value |= this->pointer->SPI(0x00);
335  value <<= 8;
336  value |= this->pointer->SPI(0x00);
337  this->chipSelect(true);
338 
339  //sei();
340  TIMSK1 |= (1 << OCIE1A);
341 
342  return value;
343 }
344 
345 void uStepperDriver::chipSelect(bool state)
346 {
347  if(state == false)
348  PORTE &= ~(1 << CS_DRIVER); // Set CS LOW
349  else
350  PORTE |= (1 << CS_DRIVER); // Set CS HIGH
351 }
352 
353 void uStepperDriver::enableStallguard( int8_t threshold, bool stopOnStall )
354 {
355  // Limit threshold
356  if( threshold > 63)
357  threshold = 63;
358  else if( threshold < -64)
359  threshold = -64;
360 
361  /* Disable StealthChop for stallguard operation */
362  this->writeRegister( GCONF, EN_PWM_MODE(0) | I_SCALE_ANALOG(1) );
363 
364  // Configure COOLCONF for stallguard
365  this->writeRegister( COOLCONF, SGT(threshold) | SFILT(1) | SEMIN(5) | SEMAX(2) | SEDN(1) );
366 
367  // Limit stallguard to 10 RPM
368  int32_t stall_speed = 16777216 / pointer->rpmToVelocity * 10.0; // 16777216 = 2^24. See TSTEP in datasheet p.33
369  stall_speed = stall_speed * 1.2; // // Activate stallGuard sligthly below desired homing velocity (provide 20% tolerance)
370 
371  // Set TCOOLTHRS to max speed value (enable stallguard for all speeds)
372  this->writeRegister( TCOOLTHRS, stall_speed ); // Max value is 20bit = 0xFFFFF
373  this->writeRegister( THIGH, 0);
374 
375  // Enable automatic stop on stall dectection
376  if( stopOnStall )
377  this->writeRegister( SW_MODE, SG_STOP(1) );
378  else
379  this->writeRegister( SW_MODE, SG_STOP(0) );
380 }
381 
383 {
384  // Reenable stealthchop
385  this->writeRegister( GCONF, EN_PWM_MODE(1) | I_SCALE_ANALOG(1) );
386 
387  // Disable all stallguard configuration
388  this->writeRegister( COOLCONF, 0 );
389  this->writeRegister( TCOOLTHRS, 0 );
390  this->writeRegister( THIGH, 0);
391  this->writeRegister( SW_MODE, 0 );
392 }
393 
394 void uStepperDriver::clearStall( void )
395 {
396  // Reading the RAMP_STAT register clears the stallguard flag, telling the driver to continue.
397  this->readRegister( RAMP_STAT );
398 }
399 
400 uint16_t uStepperDriver::getStallValue( void )
401 {
402  // Get the SG_RESULT from DRV_STATUS.
403  return this->readRegister(DRV_STATUS) & 0x3FF;
404 }
XTARGET
#define XTARGET
Definition: uStepperDriver.h:65
uStepperS
Prototype of class for accessing all features of the uStepper S in a single object.
Definition: uStepperS.h:272
uStepperDriver::init
void init(uStepperS *_pointer)
Initiation of the motor driver.
Definition: uStepperDriver.cpp:68
uStepperDriver::disableStallguard
void disableStallguard(void)
Definition: uStepperDriver.cpp:381
VELOCITY_MODE_NEG
#define VELOCITY_MODE_NEG
Definition: uStepperDriver.h:133
uStepperDriver::setAcceleration
void setAcceleration(uint32_t acceleration)
Set motor acceleration.
Definition: uStepperDriver.cpp:117
uStepperDriver::VSTART
uint32_t VSTART
Definition: uStepperDriver.h:323
uStepperDriver::readRegister
int32_t readRegister(uint8_t address)
Reads a register from the motor driver.
Definition: uStepperDriver.cpp:306
IRUN
#define IRUN(n)
Definition: uStepperDriver.h:123
HSTRT_TFD
#define HSTRT_TFD(n)
Definition: uStepperDriver.h:100
uStepperDriver::mode
uint8_t mode
Definition: uStepperDriver.h:314
uStepperDriver::AMAX
uint16_t AMAX
Definition: uStepperDriver.h:328
uStepperS.h
uStepperDriver::readMotorStatus
void readMotorStatus(void)
Definition: uStepperDriver.cpp:99
DRIVER_VELOCITY
#define DRIVER_VELOCITY
Definition: uStepperDriver.h:137
uStepperDriver::getVelocity
int32_t getVelocity(void)
Returns the current speed of the motor driver.
Definition: uStepperDriver.cpp:232
uStepperDriver::pointer
uStepperS * pointer
Definition: uStepperDriver.h:316
uStepperS::rpmToVelocity
float rpmToVelocity
Definition: uStepperS.h:712
TPWMTHRS
#define TPWMTHRS
Definition: uStepperDriver.h:48
uStepperDriver::setVelocity
void setVelocity(uint32_t velocity)
Set motor velocity.
Definition: uStepperDriver.cpp:105
uStepperS::setSPIMode
void setSPIMode(uint8_t mode)
Definition: uStepperS.cpp:381
HEND
#define HEND(n)
Definition: uStepperDriver.h:99
V1_REG
#define V1_REG
Definition: uStepperDriver.h:58
uStepperDriver::clearStall
void clearStall(void)
Definition: uStepperDriver.cpp:393
CHOPCONF
#define CHOPCONF
Definition: uStepperDriver.h:84
uStepperDriver::setHome
void setHome(int32_t initialSteps=0)
Resets the internal position counter of the motor driver.
Definition: uStepperDriver.cpp:248
uStepperDriver::A1
uint16_t A1
Definition: uStepperDriver.h:327
A1_REG
#define A1_REG
Definition: uStepperDriver.h:57
EN_PWM_MODE
#define EN_PWM_MODE(n)
Definition: uStepperDriver.h:40
RAMP_STAT
#define RAMP_STAT
Definition: uStepperDriver.h:69
GCONF
#define GCONF
Definition: uStepperDriver.h:37
uStepperDriver::updateCurrent
void updateCurrent(void)
Writes the current setting registers of the motor driver
Definition: uStepperDriver.cpp:153
uStepperDriver::current
uint8_t current
Definition: uStepperDriver.h:318
uStepperDriver::VSTOP
uint32_t VSTOP
Definition: uStepperDriver.h:326
IHOLDDELAY
#define IHOLDDELAY(n)
Definition: uStepperDriver.h:122
uStepperDriver::D1
uint16_t D1
Definition: uStepperDriver.h:330
uStepperDriver::chipSelect
void chipSelect(bool state)
Definition: uStepperDriver.cpp:344
D1_REG
#define D1_REG
Definition: uStepperDriver.h:62
TCOOLTHRS
#define TCOOLTHRS
Definition: uStepperDriver.h:49
VMAX_REG
#define VMAX_REG
Definition: uStepperDriver.h:60
TOFF
#define TOFF(n)
Definition: uStepperDriver.h:101
uStepperDriver::V1
uint32_t V1
Definition: uStepperDriver.h:324
VSTOP_REG
#define VSTOP_REG
Definition: uStepperDriver.h:63
uStepperDriver::setCurrent
void setCurrent(uint8_t current)
Set motor driver current.
Definition: uStepperDriver.cpp:141
PWM_FREQ
#define PWM_FREQ(n)
Definition: uStepperDriver.h:77
uStepperDriver::holdDelay
uint8_t holdDelay
Definition: uStepperDriver.h:320
uStepperDriver::setPosition
void setPosition(int32_t position)
Set the motor position.
Definition: uStepperDriver.cpp:158
RAMPMODE
#define RAMPMODE
Definition: uStepperDriver.h:51
PWMCONF
#define PWMCONF
Definition: uStepperDriver.h:73
WRITE_ACCESS
#define WRITE_ACCESS
Definition: uStepperDriver.h:127
uStepperDriver::enableStallguard
void enableStallguard(int8_t threshold, bool stopOnStall)
Definition: uStepperDriver.cpp:352
PWM_GRAD
#define PWM_GRAD(n)
Definition: uStepperDriver.h:78
IHOLD_IRUN
#define IHOLD_IRUN
Definition: uStepperDriver.h:45
uStepperDriver::getPosition
int32_t getPosition(void)
Returns the current position of the motor driver.
Definition: uStepperDriver.cpp:237
DRV_STATUS
#define DRV_STATUS
Definition: uStepperDriver.h:120
SEMAX
#define SEMAX(n)
Definition: uStepperDriver.h:111
DRIVER_POSITION
#define DRIVER_POSITION
Definition: uStepperDriver.h:138
AMAX_REG
#define AMAX_REG
Definition: uStepperDriver.h:59
COOLCONF
#define COOLCONF
Definition: uStepperDriver.h:106
uStepperDriver::uStepperDriver
uStepperDriver(void)
Constructor.
Definition: uStepperDriver.cpp:35
IHOLD
#define IHOLD(n)
Definition: uStepperDriver.h:124
PWM_AMPL
#define PWM_AMPL(n)
Definition: uStepperDriver.h:79
XACTUAL
#define XACTUAL
Definition: uStepperDriver.h:52
SGT
#define SGT(n)
Definition: uStepperDriver.h:108
uStepperDriver::holdCurrent
uint8_t holdCurrent
Definition: uStepperDriver.h:319
TBL
#define TBL(n)
Definition: uStepperDriver.h:94
CS_DRIVER
#define CS_DRIVER
Definition: uStepperS.h:216
FREEWHEEL
#define FREEWHEEL(n)
Definition: uStepperDriver.h:75
SG_STOP
#define SG_STOP(n)
Definition: uStepperDriver.h:68
uStepperDriver::status
uint8_t status
Definition: uStepperDriver.h:311
pointer
uStepperS * pointer
Definition: uStepperS.cpp:32
uStepperDriver::getStallValue
uint16_t getStallValue(void)
Returns the load measurement used for Stall detection.
Definition: uStepperDriver.cpp:399
SEDN
#define SEDN(n)
Definition: uStepperDriver.h:110
DMAX_REG
#define DMAX_REG
Definition: uStepperDriver.h:61
uStepperDriver::stop
void stop(void)
Stops any ongoing movement with deceleration.
Definition: uStepperDriver.cpp:242
THIGH
#define THIGH
Definition: uStepperDriver.h:50
uStepperS::SPI
uint8_t SPI(uint8_t data)
Definition: uStepperS.cpp:396
uStepperDriver::reset
void reset(void)
Definition: uStepperDriver.cpp:39
uStepperDriver::enableStealth
void enableStealth(void)
Definition: uStepperDriver.cpp:220
VSTART_REG
#define VSTART_REG
Definition: uStepperDriver.h:56
uStepperDriver::setDirection
void setDirection(bool direction)
Definition: uStepperDriver.cpp:179
uStepperS::pidPositionStepsIssued
volatile int32_t pidPositionStepsIssued
Definition: uStepperS.h:744
VELOCITY_MODE_POS
#define VELOCITY_MODE_POS
Definition: uStepperDriver.h:132
uStepperDriver::xActual
volatile int32_t xActual
Definition: uStepperDriver.h:306
uStepperDriver::VMAX
uint32_t VMAX
Definition: uStepperDriver.h:325
SFILT
#define SFILT(n)
Definition: uStepperDriver.h:107
SEMIN
#define SEMIN(n)
Definition: uStepperDriver.h:113
uStepperDriver::DMAX
uint16_t DMAX
Definition: uStepperDriver.h:329
POSITIONING_MODE
#define POSITIONING_MODE
Definition: uStepperDriver.h:131
SW_MODE
#define SW_MODE
Definition: uStepperDriver.h:67
uStepperDriver::setShaftDirection
void setShaftDirection(bool direction)
Set motor driver direction.
Definition: uStepperDriver.cpp:166
VACTUAL
#define VACTUAL
Definition: uStepperDriver.h:53
uStepperDriver::setHoldCurrent
void setHoldCurrent(uint8_t current)
Set motor driver hold current.
Definition: uStepperDriver.cpp:147
uStepperDriver::setDeceleration
void setDeceleration(uint32_t deceleration)
Set motor deceleration.
Definition: uStepperDriver.cpp:129
I_SCALE_ANALOG
#define I_SCALE_ANALOG(n)
Definition: uStepperDriver.h:41
PWM_AUTOSCALE
#define PWM_AUTOSCALE(n)
Definition: uStepperDriver.h:76
DRIVER_STOP
#define DRIVER_STOP
Definition: uStepperDriver.h:136
uStepperDriver::setRampMode
void setRampMode(uint8_t mode)
Set motor driver to position mode or velocity mode.
Definition: uStepperDriver.cpp:189
uStepperDriver::xTarget
volatile int32_t xTarget
Definition: uStepperDriver.h:303
uStepperDriver::writeRegister
int32_t writeRegister(uint8_t address, uint32_t datagram)
Write a register of the motor driver.
Definition: uStepperDriver.cpp:274