Skip to content

Commit 87b8d9e

Browse files
author
Richard Unger
committed
AS5047U: settings, zero setting, 24bit writes+CRC
1 parent 9abb188 commit 87b8d9e

File tree

2 files changed

+65
-36
lines changed

2 files changed

+65
-36
lines changed

src/encoders/as5047u/AS5047U.cpp

Lines changed: 62 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -52,15 +52,15 @@ uint16_t AS5047U::readCorrectedAngle(){
5252
uint16_t AS5047U::readMagnitude(){
5353
uint16_t command = AS5047U_MAGNITUDE_REG | AS5047U_RW;
5454
/*uint16_t cmdresult =*/ spi_transfer16(command);
55-
uint16_t result = nop();
55+
uint16_t result = nop16();
5656
return result;
5757
}
5858

5959

6060
uint16_t AS5047U::readVelocity(){
6161
uint16_t command = AS5047U_VELOCITY_REG | AS5047U_RW;
6262
/*uint16_t cmdresult =*/ spi_transfer16(command);
63-
uint16_t result = nop();
63+
uint16_t result = nop16();
6464
return result;
6565
}
6666

@@ -78,7 +78,7 @@ AS5047UError AS5047U::clearErrorFlag(){
7878
uint16_t command = AS5047U_ERROR_REG | AS5047U_RW; // set r=1, result is 0x4001
7979
/*uint16_t cmdresult =*/ spi_transfer16(command);
8080
AS5047UError result;
81-
result.reg = nop();
81+
result.reg = nop16();
8282
return result;
8383
}
8484

@@ -87,7 +87,7 @@ AS5047USettings1 AS5047U::readSettings1(){
8787
uint16_t command = AS5047U_SETTINGS1_REG | AS5047U_RW; // set r=1, result is 0xC018
8888
/*uint16_t cmdresult =*/ spi_transfer16(command);
8989
AS5047USettings1 result = {
90-
.reg = nop()
90+
.reg = nop16()
9191
};
9292
return result;
9393
}
@@ -96,9 +96,7 @@ AS5047USettings1 AS5047U::readSettings1(){
9696

9797

9898
void AS5047U::writeSettings1(AS5047USettings1 settings){
99-
uint16_t command = AS5047U_SETTINGS1_REG; // set r=0, result is 0x0018
100-
/*uint16_t cmdresult =*/ spi_transfer16(command);
101-
/*cmdresult =*/ spi_transfer16(settings.reg);
99+
writeRegister24(AS5047U_SETTINGS1_REG, settings.reg);
102100
}
103101

104102

@@ -108,7 +106,7 @@ AS5047USettings2 AS5047U::readSettings2(){
108106
uint16_t command = AS5047U_SETTINGS2_REG | AS5047U_RW; // set r=1, result is 0x4019
109107
/*uint16_t cmdresult =*/ spi_transfer16(command);
110108
AS5047USettings2 result = {
111-
.reg = nop()
109+
.reg = nop16()
112110
};
113111
return result;
114112
}
@@ -118,9 +116,7 @@ AS5047USettings2 AS5047U::readSettings2(){
118116

119117

120118
void AS5047U::writeSettings2(AS5047USettings2 settings){
121-
uint16_t command = AS5047U_SETTINGS2_REG;
122-
/*uint16_t cmdresult =*/ spi_transfer16(command);
123-
/*cmdresult =*/ spi_transfer16(settings.reg);
119+
writeRegister24(AS5047U_SETTINGS2_REG, settings.reg);
124120
}
125121

126122

@@ -131,7 +127,7 @@ AS5047USettings3 AS5047U::readSettings3(){
131127
uint16_t command = AS5047U_SETTINGS3_REG | AS5047U_RW;
132128
/*uint16_t cmdresult =*/ spi_transfer16(command);
133129
AS5047USettings3 result = {
134-
.reg = nop()
130+
.reg = nop16()
135131
};
136132
return result;
137133
}
@@ -141,9 +137,7 @@ AS5047USettings3 AS5047U::readSettings3(){
141137

142138

143139
void AS5047U::writeSettings3(AS5047USettings3 settings){
144-
uint16_t command = AS5047U_SETTINGS3_REG;
145-
/*uint16_t cmdresult =*/ spi_transfer16(command);
146-
/*cmdresult =*/ spi_transfer16(settings.reg);
140+
writeRegister24(AS5047U_SETTINGS3_REG, settings.reg);
147141
}
148142

149143

@@ -153,7 +147,7 @@ AS5047UDiagnostics AS5047U::readDiagnostics(){
153147
uint16_t command = AS5047U_DIAGNOSTICS_REG | AS5047U_RW;
154148
/*uint16_t cmdresult =*/ spi_transfer16(command);
155149
AS5047UDiagnostics result = {
156-
.reg = nop()
150+
.reg = nop16()
157151
};
158152
return result;
159153
}
@@ -164,7 +158,7 @@ AS5047UDiagnostics AS5047U::readDiagnostics(){
164158
uint8_t AS5047U::readAGC(){
165159
uint16_t command = AS5047U_AGC_REG | AS5047U_RW;
166160
/*uint16_t cmdresult =*/ spi_transfer16(command);
167-
uint16_t result = nop();
161+
uint16_t result = nop16();
168162
return result & 0x00FF;
169163
};
170164

@@ -173,7 +167,7 @@ uint8_t AS5047U::readAGC(){
173167
uint8_t AS5047U::readECCCHK(){
174168
uint16_t command = AS5047U_ECCCHK_REG | AS5047U_RW;
175169
/*uint16_t cmdresult =*/ spi_transfer16(command);
176-
uint16_t result = nop();
170+
uint16_t result = nop16();
177171
return result & 0x007F;
178172
};
179173

@@ -184,17 +178,15 @@ AS5047UDisableSettings AS5047U::readDisableSettings(){
184178
uint16_t command = AS5047U_DISABLE_REG | AS5047U_RW;
185179
/*uint16_t cmdresult =*/ spi_transfer16(command);
186180
AS5047UDisableSettings result = {
187-
.reg = nop()
181+
.reg = nop16()
188182
};
189183
return result;
190184
};
191185

192186

193187

194188
void AS5047U::writeDisableSettings(AS5047UDisableSettings settings){
195-
uint16_t command = AS5047U_DISABLE_REG;
196-
/*uint16_t cmdresult =*/ spi_transfer16(command);
197-
/*cmdresult =*/ spi_transfer16(settings.reg);
189+
writeRegister24(AS5047U_DISABLE_REG, settings.reg);
198190
};
199191

200192

@@ -203,17 +195,15 @@ AS5047UECCSettings AS5047U::readECCSettings(){
203195
uint16_t command = AS5047U_ECC_REG | AS5047U_RW;
204196
/*uint16_t cmdresult =*/ spi_transfer16(command);
205197
AS5047UECCSettings result = {
206-
.reg = nop()
198+
.reg = nop16()
207199
};
208200
return result;
209201
};
210202

211203

212204

213205
void AS5047U::writeECCSettings(AS5047UECCSettings settings){
214-
uint16_t command = AS5047U_ECC_REG;
215-
/*uint16_t cmdresult =*/ spi_transfer16(command);
216-
/*cmdresult =*/ spi_transfer16(settings.reg);
206+
writeRegister24(AS5047U_ECC_REG, settings.reg);
217207
};
218208

219209

@@ -271,7 +261,7 @@ uint16_t AS5047U::getZero(){
271261
command = AS5047U_ZPOSL_REG | AS5047U_RW;
272262
uint16_t result = spi_transfer16(command);
273263
AS5047UZPosL posL = {
274-
.reg = nop()
264+
.reg = nop16()
275265
};
276266
return ((result&0x00FF)<<6) | posL.zposl;
277267
}
@@ -281,23 +271,19 @@ uint16_t AS5047U::getZero(){
281271
uint16_t AS5047U::setZero(uint16_t value){
282272
uint16_t command = AS5047U_ZPOSL_REG | AS5047U_RW;
283273
/*uint16_t cmdresult =*/ spi_transfer16(command);
284-
command = AS5047U_ZPOSL_REG;
285274
AS5047UZPosL posL = {
286-
.reg = spi_transfer16(command)
275+
.reg = nop16()
287276
};
288277
posL.zposl = value&0x003F;
289-
spi_transfer16(posL.reg);
290-
command = AS5047U_ZPOSM_REG;
291-
spi_transfer16(command);
292-
spi_transfer16((value>>6)&0x00FF);
293-
delayMicroseconds(50);
278+
writeRegister24(AS5047U_ZPOSL_REG, posL.reg);
279+
writeRegister24(AS5047U_ZPOSM_REG, (value>>6)&0x00FF);
294280
return getZero();
295281
}
296282

297283

298284

299285

300-
uint16_t AS5047U::nop(){
286+
uint16_t AS5047U::nop16(){
301287
uint16_t result = spi_transfer16(0xFFFF); // using 0xFFFF as nop instead of 0x0000, then next call to fastAngle will return an angle
302288
return result&AS5047U_RESULT_MASK;
303289
}
@@ -317,4 +303,45 @@ uint16_t AS5047U::spi_transfer16(uint16_t outdata) {
317303
return result;
318304
}
319305

306+
uint8_t AS5047U::calcCRC(uint16_t data){
307+
uint8_t crc = 0xC4; // Initial value
308+
for (int i = 0; i < 16; i++) {
309+
if ((crc ^ data) & 0x8000) {
310+
crc = (crc << 1) ^ 0x1D;
311+
} else {
312+
crc <<= 1;
313+
}
314+
data <<= 1;
315+
}
316+
return crc ^ 0xFF;
317+
}
318+
319+
uint16_t AS5047U::writeRegister24(uint16_t reg, uint16_t data) {
320+
uint8_t buff[3] = { (reg>>8)&0x3F, reg&0xFF, calcCRC(reg) };
321+
if (nCS>=0)
322+
digitalWrite(nCS, 0);
323+
spi->beginTransaction(settings);
324+
spi->transfer(buff, 3);
325+
spi->endTransaction();
326+
if (nCS>=0)
327+
digitalWrite(nCS, 1);
328+
errorflag = ((buff[0]&0x40)>0);
329+
warningflag = ((buff[0]&0x80)>0);
330+
331+
buff[0] = (data>>8)&0x3F;
332+
buff[1] = data&0xFF;
333+
buff[2] = calcCRC(data);
334+
if (nCS>=0)
335+
digitalWrite(nCS, 0);
336+
spi->beginTransaction(settings);
337+
spi->transfer(buff, 3);
338+
spi->endTransaction();
339+
if (nCS>=0)
340+
digitalWrite(nCS, 1);
341+
errorflag = ((buff[0]&0x40)>0);
342+
warningflag = ((buff[0]&0x80)>0);
343+
344+
delayMicroseconds(50);
320345

346+
return buff[0]<<8 | buff[1];
347+
}

src/encoders/as5047u/AS5047U.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,8 +210,10 @@ class AS5047U {
210210

211211
private:
212212

213-
uint16_t nop();
213+
uint16_t nop16();
214214
uint16_t spi_transfer16(uint16_t outdata);
215+
uint8_t calcCRC(uint16_t data);
216+
uint16_t writeRegister24(uint16_t reg, uint16_t data);
215217
SPIClass* spi;
216218
SPISettings settings;
217219
bool errorflag = false;

0 commit comments

Comments
 (0)