@@ -85,21 +85,29 @@ AS5047Settings1 AS5047::readSettings1(){
8585
8686void 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
9393AS5047Settings2 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+
103111AS5047Diagnostics 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
113121void 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
119128void 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
127186uint16_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+
138232uint16_t AS5047::spi_transfer16 (uint16_t outdata) {
139233 if (nCS>=0 )
140234 digitalWrite (nCS, 0 );
0 commit comments