uStepper S
uStepperDriver.cpp
Go to the documentation of this file.
1 /********************************************************************************************
2 * File: uStepperDriver.cpp *
3 * Version: 1.0.1 *
4 * Date: May 14th, 2019 *
5 * Author: Thomas Hørring Olsen *
6 * *
7 *********************************************************************************************
8 * (C) 2019 *
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  this->writeRegister(XACTUAL, 0);
43  this->writeRegister(XTARGET, 0);
44 
45  this->writeRegister( IHOLD_IRUN,0 );
46  this->writeRegister( CHOPCONF, 0 );
47  this->writeRegister( GCONF, 0 );
48  this->writeRegister( PWMCONF, 0 );
49  this->writeRegister( TPWMTHRS, 0 );
50 
51  this->writeRegister( RAMPMODE, 0 );
52  this->writeRegister( VSTART, 0 );
53  this->writeRegister( A1, 0 );
54  this->writeRegister( V1, 0 );
55  this->writeRegister( AMAX, 0 );
56  this->writeRegister( VMAX, 0 );
57  this->writeRegister( D1, 0 );
58  this->writeRegister( VSTOP, 0 );
59 
60 }
61 
62 void uStepperDriver::init( uStepperS * _pointer ){
63 
64  this->pointer = _pointer;
65  this->chipSelect(true); // Set CS HIGH
66 
67  // First clear previous defined registers
68  this->reset();
69 
70  /* Set motor current */
71  this->writeRegister( IHOLD_IRUN, IHOLD( this->holdCurrent) | IRUN( this->current) | IHOLDDELAY( this->holdDelay) );
72 
73  this->enableStealth();
74 
75  /* Set all-round chopper configuration */
76  this->writeRegister( CHOPCONF, TOFF(2) | TBL(2) | HSTRT_TFD(4) | HEND(0));
77  //this->writeRegister( SW_MODE, this->readRegister(SW_MODE) & ~(1 << 11));
78 
79  /* Set startup ramp mode */
81 
82  /* Reset position */
83  this->writeRegister(XACTUAL, 0);
84  this->writeRegister(XTARGET, 0);
85 }
86 
87 void uStepperDriver::readMotorStatus(void)
88 {
89  while(TCNT1 > 15900); //If interrupt is just about to happen, wait for it to finish
90  this->readRegister(XACTUAL);
91 }
92 
93 void uStepperDriver::setVelocity( uint32_t velocity )
94 {
95  this->VMAX = velocity;
96 
97  if(this->VMAX > 0x7FFE00)
98  {
99  this->VMAX = 0x7FFE00;
100  }
101 
102  this->writeRegister(VMAX_REG, this->VMAX);
103 }
104 
105 void uStepperDriver::setAcceleration( uint32_t acceleration )
106 {
107  this->AMAX = acceleration;
108 
109  if(this->AMAX > 0xFFFE)
110  {
111  this->AMAX = 0xFFFE;
112  }
113 
114  this->writeRegister(AMAX_REG, this->AMAX);
115 }
116 
117 void uStepperDriver::setDeceleration( uint32_t deceleration )
118 {
119  this->DMAX = deceleration;
120 
121  if(this->DMAX > 0xFFFE)
122  {
123  this->DMAX = 0xFFFE;
124  }
125 
126  this->writeRegister(DMAX_REG, this->DMAX);
127 }
128 
129 void uStepperDriver::setCurrent( uint8_t current )
130 {
131  this->current = current;
132  this->updateCurrent();
133 }
134 
135 void uStepperDriver::setHoldCurrent( uint8_t current )
136 {
137  this->holdCurrent = current;
138  this->updateCurrent();
139 }
140 
142 {
143  this->writeRegister( IHOLD_IRUN, IHOLD( this->holdCurrent) | IRUN( this->current) | IHOLDDELAY( this->holdDelay) );
144 }
145 
146 void uStepperDriver::setPosition( int32_t position )
147 {
148  this->mode = DRIVER_POSITION;
150  this->writeRegister(XTARGET, position);
151  this->xTarget = position;
152 }
153 
154 void uStepperDriver::setShaftDirection( bool direction )
155 {
156  // Read the register to save the settings
157  int32_t value = this->readRegister( GCONF );
158  // Update the direction bit
159  if(direction == 1){
160  value |= (0x01 << 4);
161  }else{
162  value &= ~(0x01 << 4);
163  }
164  this->writeRegister( GCONF, value );
165 }
166 
167 void uStepperDriver::setDirection( bool direction )
168 {
169  this->mode = DRIVER_VELOCITY;
170  if(direction){
172  }else{
174  }
175 }
176 
177 void uStepperDriver::setRampMode( uint8_t mode ){
178 
179  switch(mode){
180  case POSITIONING_MODE:
181  // Positioning mode
182  this->writeRegister(VSTART_REG, this->VSTART);
183  this->writeRegister(A1_REG, this->A1);
184  this->writeRegister(V1_REG, this->V1);
185  this->writeRegister(AMAX_REG, this->AMAX);
186  this->writeRegister(VMAX_REG, this->VMAX);
187  this->writeRegister(DMAX_REG, this->DMAX);
188  this->writeRegister(D1_REG, this->D1);
189  this->writeRegister(VSTOP_REG, this->VSTOP); /* Minimum 10 in POSITIONING_MODE */
190  this->writeRegister(RAMPMODE, POSITIONING_MODE); /* RAMPMODE = POSITIONING_MODE */
191  break;
192 
193  case VELOCITY_MODE_POS:
194  // Velocity mode (only AMAX and VMAX is used)
195  this->writeRegister(VSTART_REG, this->VSTART);
196  this->writeRegister(A1_REG, 0);
197  this->writeRegister(V1_REG, 0);
198  this->writeRegister(AMAX_REG, this->AMAX);
199  this->writeRegister(VMAX_REG, this->VMAX);
200  this->writeRegister(DMAX_REG, 0);
201  this->writeRegister(D1_REG, 0);
202  this->writeRegister(VSTOP_REG, 0);
203  this->writeRegister(RAMPMODE, VELOCITY_MODE_POS); /* RAMPMODE = VELOCITY_MODE_POS */
204  break;
205  }
206 }
207 
208 void uStepperDriver::enableStealth()
209 {
210  /* Set GCONF and enable stealthChop */
211  this->writeRegister( GCONF, EN_PWM_MODE(1) | I_SCALE_ANALOG(1) );
212 
213  /* Set PWMCONF for StealthChop */
214  this->writeRegister( PWMCONF, PWM_AUTOSCALE(1) | PWM_GRAD(1) | PWM_AMPL(128) | PWM_FREQ(0) | FREEWHEEL(1) );
215 
216  /* Specifies the upper velocity (lower time delay) for operation in stealthChop voltage PWM mode */
217  this->writeRegister( TPWMTHRS, 5000 );
218 }
219 
221 {
222  return this->readRegister(VACTUAL);
223 }
224 
226 {
227  return this->readRegister(XACTUAL);
228 }
229 
231 {
232  this->mode = DRIVER_STOP;
233  this->setVelocity(0);
234 }
235 
237 {
238  int32_t xActual, xTarget;
239 
240  if(this->mode == DRIVER_POSITION)
241  {
242  xActual = this->getPosition();
243  xTarget = this->readRegister(XTARGET);
244 
245  xTarget -= xActual;
246  this->xTarget = xTarget;
247  this->writeRegister(XACTUAL, 0);
248  this->writeRegister(XTARGET, xTarget);
249  }
250  else
251  {
252  this->xTarget = 0;
253  this->writeRegister(XACTUAL, 0);
254  this->writeRegister(XTARGET, 0);
255  }
256 
257  pointer->pidPositionStepsIssued = 0;
258 }
259 
260 int32_t uStepperDriver::writeRegister( uint8_t address, uint32_t datagram ){
261 
262  // Disabled interrupts until write is complete
263  //cli();
264  TIMSK1 &= ~(1 << OCIE1A);
265  // Enable SPI mode 3 to use TMC5130
266  this->pointer->setSPIMode(3);
267 
268  uint32_t package;
269 
270  // Add the value of WRITE_ACCESS to enable register write
271  address += WRITE_ACCESS;
272 
273  this->chipSelect(false);
274 
275  this->status = this->pointer->SPI(address);
276 
277  package |= this->pointer->SPI((datagram >> 24) & 0xff);
278  package <<= 8;
279  package |= this->pointer->SPI((datagram >> 16) & 0xff);
280  package <<= 8;
281  package |= this->pointer->SPI((datagram >> 8) & 0xff);
282  package <<= 8;
283  package |= this->pointer->SPI((datagram) & 0xff);
284 
285  this->chipSelect(true); // Set CS HIGH
286 
287  //sei();
288  TIMSK1 |= (1 << OCIE1A);
289  return package;
290 }
291 
292 int32_t uStepperDriver::readRegister( uint8_t address )
293 {
294  // Disabled interrupts until write is complete
295  //cli();
296  TIMSK1 &= ~(1 << OCIE1A);
297 
298  // Enable SPI mode 3 to use TMC5130
299  this->pointer->setSPIMode(3);
300 
301  // Request a reading on address
302  this->chipSelect(false);
303  this->status = this->pointer->SPI(address);
304  this->pointer->SPI(0x00);
305  this->pointer->SPI(0x00);
306  this->pointer->SPI(0x00);
307  this->pointer->SPI(0x00);
308  this->chipSelect(true);
309 
310  // Read the actual value on second request
311  int32_t value = 0;
312 
313  this->chipSelect(false);
314  this->status = this->pointer->SPI(address);
315  value |= this->pointer->SPI(0x00);
316  value <<= 8;
317  value |= this->pointer->SPI(0x00);
318  value <<= 8;
319  value |= this->pointer->SPI(0x00);
320  value <<= 8;
321  value |= this->pointer->SPI(0x00);
322  this->chipSelect(true);
323 
324  //sei();
325  TIMSK1 |= (1 << OCIE1A);
326 
327  return value;
328 }
329 
330 void uStepperDriver::chipSelect(bool state)
331 {
332  if(state == false)
333  PORTE &= ~(1 << CS_DRIVER); // Set CS LOW
334  else
335  PORTE |= (1 << CS_DRIVER); // Set CS HIGH
336 }
#define DRIVER_POSITION
volatile int32_t xTarget
#define AMAX_REG
void setHoldCurrent(uint8_t current)
Set motor driver hold current.
int32_t readRegister(uint8_t address)
Reads a register from the motor driver.
void setRampMode(uint8_t mode)
Set motor driver to position mode or velocity mode.
void init(uStepperS *_pointer)
Initiation of the motor driver.
#define XACTUAL
int32_t getVelocity(void)
Returns the current speed of the motor driver.
#define FREEWHEEL(n)
#define I_SCALE_ANALOG(n)
void setVelocity(uint32_t velocity)
Set motor velocity.
Prototype of class for accessing all features of the uStepper S in a single object.
Definition: uStepperS.h:252
#define PWMCONF
#define VELOCITY_MODE_NEG
#define PWM_GRAD(n)
#define PWM_AUTOSCALE(n)
#define TPWMTHRS
#define RAMPMODE
#define DRIVER_STOP
#define IRUN(n)
void setHome(void)
Resets the internal position counter of the motor driver.
#define XTARGET
#define GCONF
void setPosition(int32_t position)
Set the motor position.
uStepperDriver(void)
Constructor.
void updateCurrent(void)
Writes the current setting registers of the motor driver.
#define VELOCITY_MODE_POS
#define CHOPCONF
#define CS_DRIVER
Definition: uStepperS.h:193
void setCurrent(uint8_t current)
Set motor driver current.
#define DMAX_REG
int32_t getPosition(void)
Returns the current position of the motor driver.
#define VSTART_REG
#define HEND(n)
#define IHOLDDELAY(n)
void setShaftDirection(bool direction)
Set motor driver direction.
#define TOFF(n)
#define TBL(n)
#define VACTUAL
#define IHOLD(n)
#define EN_PWM_MODE(n)
#define HSTRT_TFD(n)
#define A1_REG
#define VSTOP_REG
#define DRIVER_VELOCITY
#define WRITE_ACCESS
void stop(void)
Stops any ongoing movement with deceleration.
#define POSITIONING_MODE
#define VMAX_REG
#define PWM_AMPL(n)
void setDeceleration(uint32_t deceleration)
Set motor deceleration.
Function prototypes and definitions for the uStepper S library.
#define IHOLD_IRUN
#define D1_REG
void setAcceleration(uint32_t acceleration)
Set motor acceleration.
#define V1_REG
int32_t writeRegister(uint8_t address, uint32_t datagram)
Write a register of the motor driver.
#define PWM_FREQ(n)