Skip to content

Commit 9abb188

Browse files
author
Richard Unger
committed
AS5047: settings, ABI settings, zero setting
1 parent 3155956 commit 9abb188

File tree

2 files changed

+128
-6
lines changed

2 files changed

+128
-6
lines changed

src/encoders/as5047/AS5047.cpp

Lines changed: 100 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,21 +85,29 @@ AS5047Settings1 AS5047::readSettings1(){
8585

8686
void AS5047::writeSettings1(AS5047Settings1 settings){
8787
uint16_t command = AS5047_SETTINGS1_REG; // set r=0, result is 0x0018
88-
/*uint16_t cmdresult =*/ spi_transfer16(command);
89-
/*cmdresult =*/ spi_transfer16(settings.reg);
88+
spi_transfer16(command);
89+
spi_transfer16(calcParity(settings.reg));
9090
}
9191

9292

9393
AS5047Settings2 AS5047::readSettings2(){
9494
uint16_t command = AS5047_SETTINGS2_REG | AS5047_RW; // set r=1, result is 0x4019
95-
/*uint16_t cmdresult =*/ spi_transfer16(command);
95+
spi_transfer16(command);
9696
AS5047Settings2 result = {
9797
.reg = nop()
9898
};
9999
return result;
100100
}
101101

102102

103+
void AS5047::writeSettings2(AS5047Settings2 settings){
104+
uint16_t command = AS5047_SETTINGS2_REG | AS5047_PARITY; // set r=0, result is 0x8019
105+
spi_transfer16(command);
106+
spi_transfer16(calcParity(settings.reg));
107+
}
108+
109+
110+
103111
AS5047Diagnostics AS5047::readDiagnostics(){
104112
uint16_t command = AS5047_DIAGNOSTICS_REG | AS5047_PARITY | AS5047_RW; // set r=1, result is 0xFFFC
105113
/*uint16_t cmdresult =*/ spi_transfer16(command);
@@ -112,21 +120,96 @@ AS5047Diagnostics AS5047::readDiagnostics(){
112120

113121
void AS5047::enablePWM(bool enable){
114122
AS5047Settings1 settings = readSettings1();
123+
if (settings.pwmon == enable) return; // no change
115124
settings.pwmon = enable;
116125
writeSettings1(settings);
117126
}
118127

119128
void AS5047::enableABI(bool enable){
120129
AS5047Settings1 settings = readSettings1();
121-
settings.uvw_abi = enable?0:1;
130+
uint8_t val = enable?0:1;
131+
if (settings.uvw_abi == val) return; // no change
132+
settings.uvw_abi = val;
122133
writeSettings1(settings);
123134
}
124135

125136

137+
void AS5047::enableDEAC(bool enable){
138+
AS5047Settings1 settings = readSettings1();
139+
uint8_t val = enable?0:1;
140+
if (settings.daecdis == val) return; // no change
141+
settings.daecdis = enable?0:1;
142+
writeSettings1(settings);
143+
}
144+
145+
146+
void AS5047::useCorrectedAngle(bool useCorrected){
147+
AS5047Settings1 settings = readSettings1();
148+
uint8_t val = useCorrected?0:1;
149+
if (settings.dataselect == val) return; // no change
150+
settings.dataselect = val;
151+
writeSettings1(settings);
152+
}
153+
154+
155+
156+
void AS5047::setHysteresis(uint8_t hyst){
157+
if (hyst>3) hyst = 3;
158+
uint8_t val = 3-hyst;
159+
AS5047Settings2 settings = readSettings2();
160+
if (settings.hys == val) return; // no change
161+
settings.hys = val;
162+
writeSettings2(settings);
163+
}
164+
165+
166+
167+
168+
void AS5047::setABIResolution(AS5047ABIRes res){
169+
AS5047Settings1 settings = readSettings1();
170+
uint8_t val = (res>>3)&0x01;
171+
if (settings.abibin!=val || settings.uvw_abi!=0) {
172+
settings.abibin = val;
173+
settings.uvw_abi = 0;
174+
writeSettings1(settings);
175+
}
176+
AS5047Settings2 settings2 = readSettings2();
177+
val = (res&0x07);
178+
if (settings2.abires!=val) {
179+
settings2.abires = val;
180+
writeSettings2(settings2);
181+
}
182+
}
183+
184+
126185

127186
uint16_t AS5047::setZero(uint16_t value){
128-
// TODO implement me!
129-
return 0;
187+
uint16_t command = AS5047_ZPOSL_REG | AS5047_PARITY | AS5047_RW;
188+
spi_transfer16(command);
189+
AS5047ZPosL posL = {
190+
.reg = nop()
191+
};
192+
command = AS5047_ZPOSM_REG | AS5047_PARITY;
193+
spi_transfer16(command);
194+
spi_transfer16(calcParity((value>>6)&0x00FF));
195+
command = AS5047_ZPOSL_REG;
196+
posL.zposl = value&0x003F;
197+
spi_transfer16(command);
198+
spi_transfer16(calcParity(posL.reg));
199+
200+
return getZero();
201+
}
202+
203+
204+
uint16_t AS5047::getZero() {
205+
uint16_t command = AS5047_ZPOSM_REG | AS5047_RW;
206+
spi_transfer16(command);
207+
command = AS5047_ZPOSL_REG | AS5047_PARITY | AS5047_RW;
208+
uint16_t result = spi_transfer16(command);
209+
AS5047ZPosL posL = {
210+
.reg = nop()
211+
};
212+
return ((result&0x00FF)<<6) | posL.zposl;
130213
}
131214

132215

@@ -135,6 +218,17 @@ uint16_t AS5047::nop(){
135218
return result&AS5047_RESULT_MASK;
136219
}
137220

221+
222+
uint16_t AS5047::calcParity(uint16_t data){
223+
data = data & 0x7FFF;
224+
int sum = 0;
225+
for (int i=0;i<15;i++)
226+
if ((data>>i)&0x0001)
227+
sum++;
228+
return (sum&0x01)==0x01?(data|0x8000):data;
229+
}
230+
231+
138232
uint16_t AS5047::spi_transfer16(uint16_t outdata) {
139233
if (nCS>=0)
140234
digitalWrite(nCS, 0);

src/encoders/as5047/AS5047.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ union AS5047Diagnostics {
2121
uint16_t cof:1;
2222
uint16_t magh:1;
2323
uint16_t magl:1;
24+
uint16_t unused:4;
2425
};
2526
uint16_t reg;
2627
};
@@ -29,6 +30,7 @@ union AS5047Diagnostics {
2930
union AS5047ZPosM {
3031
struct {
3132
uint16_t zposm:8;
33+
uint16_t unused:8;
3234
};
3335
uint16_t reg;
3436
};
@@ -39,6 +41,7 @@ union AS5047ZPosL {
3941
uint16_t zposl:6;
4042
uint16_t comp_l_error_en:1;
4143
uint16_t comp_h_error_en:1;
44+
uint16_t unused:8;
4245
};
4346
uint16_t reg;
4447
};
@@ -54,6 +57,7 @@ union AS5047Settings1 {
5457
uint16_t abibin:1;
5558
uint16_t dataselect:1;
5659
uint16_t pwmon:1;
60+
uint16_t unused:8;
5761
};
5862
uint16_t reg;
5963
};
@@ -64,6 +68,7 @@ union AS5047Settings2 {
6468
uint16_t uvwpp:3;
6569
uint16_t hys:2;
6670
uint16_t abires:3;
71+
uint16_t unused:8;
6772
};
6873
uint16_t reg;
6974
};
@@ -76,6 +81,21 @@ struct AS5047Error {
7681
};
7782

7883

84+
enum AS5047ABIRes : uint8_t {
85+
AS5047_ABI_1024 = 0b1010,
86+
AS5047_ABI_2048 = 0b1001,
87+
AS5047_ABI_4096 = 0b1000,
88+
AS5047_ABI_100 = 0b0111,
89+
AS5047_ABI_200 = 0b0110,
90+
AS5047_ABI_400 = 0b0101,
91+
AS5047_ABI_800 = 0b0100,
92+
AS5047_ABI_1200 = 0b0011,
93+
AS5047_ABI_1600 = 0b0010,
94+
AS5047_ABI_2000 = 0b0001,
95+
AS5047_ABI_4000 = 0b0000
96+
};
97+
98+
7999
#define AS5047_CPR 16384
80100
#define AS5047_ANGLECOM_REG 0x3FFF
81101
#define AS5047_ANGLEUNC_REG 0x3FFE
@@ -120,10 +140,18 @@ class AS5047 {
120140
AS5047Settings1 readSettings1();
121141
void writeSettings1(AS5047Settings1 settings);
122142
AS5047Settings2 readSettings2();
143+
void writeSettings2(AS5047Settings2 settings);
123144
void enablePWM(bool enable);
124145
void enableABI(bool enable);
146+
void setABIResolution(AS5047ABIRes res);
147+
void enableDEAC(bool enable);
148+
void useCorrectedAngle(bool useCorrected);
149+
void setHysteresis(uint8_t hyst);
125150

126151
uint16_t setZero(uint16_t);
152+
uint16_t getZero();
153+
154+
uint16_t calcParity(uint16_t data);
127155

128156
private:
129157

0 commit comments

Comments
 (0)