MP6602 library
Loading...
Searching...
No Matches
MP6602.h
Go to the documentation of this file.
1// Copyright Pololu Corporation. For more information, see http://www.pololu.com/
2
13
14#pragma once
15
16#include <Arduino.h>
17#include <SPI.h>
18
23enum class MP6602RegAddr : uint8_t
24{
25 CTRL = 0x00,
26 CTRL2 = 0x01,
27 ISET = 0x02,
28 STALL = 0x03,
29 BEMF = 0x04,
30 TSTP = 0x05,
31 OCP = 0x06,
32 FAULT = 0x07,
33};
34
35
42{
43public:
47 void setChipSelectPin(uint8_t pin)
48 {
49 csPin = pin;
50 pinMode(csPin, OUTPUT);
51 digitalWrite(csPin, HIGH);
52 }
53
55 uint16_t readReg(uint8_t address)
56 {
57 // Arduino out / MP6602 in: first 3 bits = address, 4th bit = R/W (0 for
58 // read); last 12 bits ignored
59 // Arduino in / MP6602 out: first 4 bits undefined, then 12 bits of data read
60 // out
61
62 selectChip();
63 uint16_t data = transfer16((uint16_t)(address & 0x7) << 13) & 0xFFF;
64 deselectChip();
65 return data;
66 }
67
69 uint16_t readReg(MP6602RegAddr address)
70 {
71 return readReg((uint8_t)address);
72 }
73
75 void writeReg(uint8_t address, uint16_t value)
76 {
77 // Arduino out / MP6602 in: first 3 bits = address, 4th bit = R/W (1 for
78 // write), then 12 data bits to be written
79 // Arduino in / MP6602 out: undefined
80
81 selectChip();
82 transfer16(((uint16_t)(address & 0x7) << 13) | (1 << 12) | (value & 0xFFF));
83 deselectChip();
84 }
85
87 void writeReg(MP6602RegAddr address, uint16_t value)
88 {
89 writeReg((uint8_t)address, value);
90 }
91
92private:
93
94 // Max SPI frequency is 10 MHz. We use half that (5 MHz) to leave some margin
95 // for timing inaccuracies.
96 SPISettings settings = SPISettings(5000000, MSBFIRST, SPI_MODE0);
97
98 uint16_t transfer16(uint16_t value)
99 {
100 return SPI.transfer16(value);
101 }
102
103 void selectChip()
104 {
105 digitalWrite(csPin, LOW);
106 SPI.beginTransaction(settings);
107 }
108
109 void deselectChip()
110 {
111 SPI.endTransaction();
112 digitalWrite(csPin, HIGH);
113 }
114
115 uint8_t csPin;
116};
117
118
120enum class MP6602StepMode : uint8_t
121{
122 MicroStep1 = 0b000,
123 MicroStep2 = 0b001,
124 MicroStep4 = 0b010,
125 MicroStep8 = 0b011,
126 MicroStep16 = 0b100,
127 MicroStep32 = 0b101,
128};
129
134enum class MP6602FaultBit : uint8_t
135{
136 STALL = 9,
137 OLA = 8,
138 OLB = 7,
139 OCP = 6,
140 OTS = 5,
141 OTW = 4,
142 OVP = 3,
143 VINUV = 2,
144 VCCUV = 1,
145 FLT = 0,
146};
147
152enum class MP6602OCPBit : uint8_t
153{
154 OCPAH = 3,
155 OCPAL = 2,
156 OCPBH = 1,
157 OCPBL = 0,
158};
159
160
164{
165public:
168 {
169 // All settings set to power-on defaults
170 ctrl = 0x118;
171 ctrl2 = 0x034;
172 iset = 0x249;
173 stall = 0x800;
174 bemf = 0x300;
175 }
176
179 void setChipSelectPin(uint8_t pin)
180 {
181 driver.setChipSelectPin(pin);
182 }
183
190 {
191 ctrl = 0x118;
192 ctrl2 = 0x034;
193 iset = 0x249;
194 stall = 0x800;
195 bemf = 0x300;
197
198 // Also restore the TSTP register (indexer step table position) to its reset
199 // value.
200 driver.writeReg(MP6602RegAddr::TSTP, 0x510);
201 }
202
214 {
215 return driver.readReg(MP6602RegAddr::CTRL) == (ctrl & ~(1 << 1)) && // Bit 1 (STEP) is automatically reset to 0 (always reads as 0)
216 driver.readReg(MP6602RegAddr::CTRL2) == ctrl2 &&
217 driver.readReg(MP6602RegAddr::ISET) == iset &&
218 driver.readReg(MP6602RegAddr::STALL) == stall &&
219 (driver.readReg(MP6602RegAddr::BEMF) & 0xF00) == (bemf & 0xF00); // Only verify bits 11:8, as bits 7:0 are BEMF measured value (not a driver setting) and read-only
220 }
221
230 {
231 writeCachedReg(MP6602RegAddr::CTRL2);
232 writeCachedReg(MP6602RegAddr::ISET);
233 writeCachedReg(MP6602RegAddr::STALL);
234 writeCachedReg(MP6602RegAddr::BEMF);
235
236 // CTRL is written last because it contains the EN bit, and we want to try
237 // to have all the other settings correct first.
238 writeCachedReg(MP6602RegAddr::CTRL);
239 }
240
241
247 void setCurrentMilliamps(uint16_t current)
248 {
249 if (current > 4000) { current = 4000; }
250 if (current < 125) { current = 125; }
251
252 uint8_t is = (current - 125) / 125;
253 iset = (iset & 0xFC0) | is;
254 writeCachedReg(MP6602RegAddr::ISET);
255 }
256
264 void setHoldCurrentMilliamps(uint16_t current)
265 {
266 if (current > 4000) { current = 4000; }
267 if (current < 125) { current = 125; }
268
269 uint8_t il = (current - 125) / 125;
270 iset = (iset & 0x03F) | ((uint16_t)il << 6);
271 writeCachedReg(MP6602RegAddr::ISET);
272 }
273
283 void setAutoHoldTimeMs(uint16_t time)
284 {
285 uint8_t ah;
286
287 if (time == 0) { ah = 0; } // disabled
288 else if (time <= 15) { ah = 1; } // 15.6 ms
289 else if (time <= 31) { ah = 2; } // 31.3 ms
290 else if (time <= 62) { ah = 3; } // 62.5 ms
291 else if (time <= 125) { ah = 4; } // 125 ms
292 else if (time <= 250) { ah = 5; } // 250 ms
293 else if (time <= 500) { ah = 6; } // 500 ms
294 else { ah = 7; } // 1000 ms
295
296 ctrl = (ctrl & 0x1FF) | ((uint16_t)ah << 9);
297 writeCachedReg(MP6602RegAddr::CTRL);
298 }
299
307 {
308 ctrl |= 1;
309 writeCachedReg(MP6602RegAddr::CTRL);
310 }
311
319 {
320 ctrl &= ~1;
321 writeCachedReg(MP6602RegAddr::CTRL);
322 }
323
331 void setDirection(bool value)
332 {
333 if (value)
334 {
335 ctrl |= (1 << 2);
336 }
337 else
338 {
339 ctrl &= ~(1 << 2);
340 }
341 writeCachedReg(MP6602RegAddr::CTRL);
342 }
343
348 {
349 return (ctrl >> 2) & 1;
350 }
351
355 void step()
356 {
357 driver.writeReg(MP6602RegAddr::CTRL, ctrl | (1 << 1));
358 }
359
375 {
377 {
378 // Invalid mode; pick 1/8-step by default.
380 }
381
382 ctrl = (ctrl & 0xFC7) | ((uint8_t)mode << 3);
383 writeCachedReg(MP6602RegAddr::CTRL);
384 }
385
395 void setStepMode(uint16_t mode)
396 {
398
399 switch (mode)
400 {
401 case 1: sm = MP6602StepMode::MicroStep1; break;
402 case 2: sm = MP6602StepMode::MicroStep2; break;
403 case 4: sm = MP6602StepMode::MicroStep4; break;
404 case 8: sm = MP6602StepMode::MicroStep8; break;
405 case 16: sm = MP6602StepMode::MicroStep16; break;
406 case 32: sm = MP6602StepMode::MicroStep32; break;
407
408 // Invalid mode; pick 1/8-step by default.
409 default: sm = MP6602StepMode::MicroStep8;
410 }
411
412 setStepMode(sm);
413 }
414
431 uint16_t readFault()
432 {
433 return driver.readReg(MP6602RegAddr::FAULT) & 0x3FF;
434 }
435
444 uint8_t readOCP()
445 {
446 return driver.readReg(MP6602RegAddr::OCP) & 0xF;
447 }
448
457 {
458 // Write 1 to all OCP flag bits. Upper 8 bits of OCP are reserved, so keep
459 // them the same as reset values.
460 driver.writeReg(MP6602RegAddr::OCP, 0x55F);
461
462 // Write 1 to all writable fault flag bits. Bits 11:10 are reserved, and OCP
463 // (6) and FLT (0) are read-only (OR-ed from other bits).
464 driver.writeReg(MP6602RegAddr::FAULT, 0x3BE);
465 }
466
469 uint16_t getCachedReg(MP6602RegAddr address)
470 {
471 uint16_t * cachedReg = cachedRegPtr(address);
472 if (!cachedReg) { return 0; }
473 return *cachedReg;
474 }
475
485 void setReg(MP6602RegAddr address, uint16_t value)
486 {
487 uint16_t * cachedReg = cachedRegPtr(address);
488 if (!cachedReg) { return; }
489 *cachedReg = value & 0xFFF;
490 driver.writeReg(address, value);
491 }
492
493protected:
494
495 uint16_t ctrl, ctrl2, iset, stall, bemf;
496
499 uint16_t * cachedRegPtr(MP6602RegAddr address)
500 {
501 switch (address)
502 {
503 case MP6602RegAddr::CTRL: return &ctrl;
504 case MP6602RegAddr::CTRL2: return &ctrl2;
505 case MP6602RegAddr::ISET: return &iset;
506 case MP6602RegAddr::STALL: return &stall;
507 case MP6602RegAddr::BEMF: return &bemf;
508 default: return nullptr;
509 }
510 }
511
514 {
515 uint16_t * cachedReg = cachedRegPtr(address);
516 if (!cachedReg) { return; }
517 driver.writeReg(address, *cachedReg);
518 }
519
520public:
526};
MP6602OCPBit
Definition MP6602.h:153
@ OCPBH
Bridge B high-side OCP (such as as short to ground).
Definition MP6602.h:156
@ OCPAL
Bridge A low-side OCP (such as short to VIN).
Definition MP6602.h:155
@ OCPAH
Bridge A high-side OCP (such as short to ground).
Definition MP6602.h:154
@ OCPBL
Bridge B low-side OCP (such as short to VIN).
Definition MP6602.h:157
MP6602RegAddr
Definition MP6602.h:24
MP6602StepMode
Possible arguments to setStepMode().
Definition MP6602.h:121
@ MicroStep4
1/4-step
Definition MP6602.h:124
@ MicroStep16
1/16-step
Definition MP6602.h:126
@ MicroStep8
1/8-step
Definition MP6602.h:125
@ MicroStep2
1/2-step
Definition MP6602.h:123
@ MicroStep1
Full step with 71% current.
Definition MP6602.h:122
@ MicroStep32
1/32-step
Definition MP6602.h:127
MP6602FaultBit
Definition MP6602.h:135
@ OLB
Open load on bridge B.
Definition MP6602.h:138
@ VINUV
VIN under-voltage.
Definition MP6602.h:143
@ FLT
Fault indication (logical OR of other bits in FAULT register except VCCUV and VINUV; 0 when nFAULT pi...
Definition MP6602.h:145
@ OTW
Over-temperature warning.
Definition MP6602.h:141
@ OTS
Over-temperature shutdown.
Definition MP6602.h:140
@ VCCUV
VCC under-voltage (set at start-up and reset).
Definition MP6602.h:144
@ OVP
Over-voltage protection.
Definition MP6602.h:142
@ OLA
Open load on bridge A.
Definition MP6602.h:137
void setStepMode(uint16_t mode)
Definition MP6602.h:395
uint16_t readFault()
Definition MP6602.h:431
MP6602SPI driver
Definition MP6602.h:525
void applySettings()
Definition MP6602.h:229
void setAutoHoldTimeMs(uint16_t time)
Definition MP6602.h:283
void setStepMode(MP6602StepMode mode)
Definition MP6602.h:374
uint16_t * cachedRegPtr(MP6602RegAddr address)
Definition MP6602.h:499
bool verifySettings()
Definition MP6602.h:213
void resetSettings()
Definition MP6602.h:189
MP6602()
The default constructor.
Definition MP6602.h:167
void setCurrentMilliamps(uint16_t current)
Definition MP6602.h:247
uint8_t readOCP()
Definition MP6602.h:444
uint16_t getCachedReg(MP6602RegAddr address)
Definition MP6602.h:469
void clearFaults()
Definition MP6602.h:456
void step()
Definition MP6602.h:355
void setHoldCurrentMilliamps(uint16_t current)
Definition MP6602.h:264
bool getDirection()
Definition MP6602.h:347
void writeCachedReg(MP6602RegAddr address)
Writes the cached value of the given register to the device.
Definition MP6602.h:513
void disableDriver()
Definition MP6602.h:318
void setChipSelectPin(uint8_t pin)
Definition MP6602.h:179
void enableDriver()
Definition MP6602.h:306
void setReg(MP6602RegAddr address, uint16_t value)
Definition MP6602.h:485
void setDirection(bool value)
Definition MP6602.h:331
void writeReg(MP6602RegAddr address, uint16_t value)
Writes the specified value to a register.
Definition MP6602.h:87
uint16_t readReg(uint8_t address)
Reads the register at the given address and returns its raw value.
Definition MP6602.h:55
void writeReg(uint8_t address, uint16_t value)
Writes the specified value to a register.
Definition MP6602.h:75
void setChipSelectPin(uint8_t pin)
Definition MP6602.h:47
uint16_t readReg(MP6602RegAddr address)
Reads the register at the given address and returns its raw value.
Definition MP6602.h:69