9#ifdef AS5047U_HEADER_INCLUDED
20template <
typename SpiType>
22 this->frame_format_ = format;
37template <
typename SpiType>
42 for (uint8_t i = 0; i <= retries; ++i) {
43 val = this->
template ReadReg<AS5047U_REG::ANGLECOM>().bits.ANGLECOM_value;
44 auto err = GetStickyErrorFlags();
45 if ((
static_cast<uint16_t
>(err) & retryMask) == 0U) {
52template <
typename SpiType>
56 return static_cast<float>(GetAngle(retries));
58 return GetAngleDegrees(retries);
60 return GetAngleRadians(retries);
62 return static_cast<float>(GetAngle(retries));
66template <
typename SpiType>
68 return static_cast<float>(GetAngle(retries)) * Angle::DEG_PER_LSB;
71template <
typename SpiType>
73 return static_cast<float>(GetAngle(retries)) * Angle::RAD_PER_LSB;
76template <
typename SpiType>
81 for (uint8_t i = 0; i <= retries; ++i) {
82 val = this->
template ReadReg<AS5047U_REG::ANGLEUNC>().bits.ANGLEUNC_value;
83 auto err = GetStickyErrorFlags();
84 if ((
static_cast<uint16_t
>(err) & retryMask) == 0U) {
91template <
typename SpiType>
96 for (uint8_t i = 0; i <= retries; ++i) {
97 auto v = this->
template ReadReg<AS5047U_REG::VEL>().bits.VEL_value;
98 val =
static_cast<int16_t
>((
static_cast<int16_t
>(v << 2)) >> 2);
99 auto err = GetStickyErrorFlags();
100 if ((
static_cast<uint16_t
>(err) & retryMask) == 0U) {
107template <
typename SpiType>
111 return static_cast<float>(GetVelocity(retries));
113 return GetVelocityDegPerSec(retries);
115 return GetVelocityRadPerSec(retries);
117 return GetVelocityRPM(retries);
119 return static_cast<float>(GetVelocity(retries));
123template <
typename SpiType>
125 return GetVelocity(retries) * Velocity::DEG_PER_LSB;
128template <
typename SpiType>
130 return GetVelocity(retries) * Velocity::RAD_PER_LSB;
133template <
typename SpiType>
135 return GetVelocity(retries) * Velocity::RPM_PER_LSB;
138template <
typename SpiType>
143 for (uint8_t i = 0; i <= retries; ++i) {
144 val = this->
template ReadReg<AS5047U_REG::AGC>().bits.AGC_value;
145 auto err = GetStickyErrorFlags();
146 if ((
static_cast<uint16_t
>(err) & retryMask) == 0U) {
153template <
typename SpiType>
158 for (uint8_t i = 0; i <= retries; ++i) {
159 val = this->
template ReadReg<AS5047U_REG::MAG>().bits.MAG_value;
160 auto err = GetStickyErrorFlags();
161 if ((
static_cast<uint16_t
>(err) & retryMask) == 0U) {
168template <
typename SpiType>
171 for (uint8_t i = 0; i <= retries; ++i) {
172 val = this->
template ReadReg<AS5047U_REG::ERRFL>().value;
180template <
typename SpiType>
188 for (uint8_t i = 0; i <= retries; ++i) {
189 m = this->
template ReadReg<AS5047U_REG::ZPOSM>().bits.ZPOSM_bits;
190 auto err = GetStickyErrorFlags();
191 if ((
static_cast<uint16_t
>(err) & retryMask) == 0U) {
197 for (uint8_t i = 0; i <= retries; ++i) {
198 l = this->
template ReadReg<AS5047U_REG::ZPOSL>().bits.ZPOSL_bits;
199 auto err = GetStickyErrorFlags();
200 if ((
static_cast<uint16_t
>(err) & retryMask) == 0U) {
205 return static_cast<uint16_t
>((m << 6) | l);
208template <
typename SpiType>
214 return this->
template WriteReg(m, retries) && this->
template WriteReg(l, retries);
217template <
typename SpiType>
219 resolution_bits = std::clamp(resolution_bits, uint8_t(10), uint8_t(14));
221 static constexpr uint8_t kBitsToAbires[] = {2, 1, 0, 3, 4};
222 auto s3 = this->
template ReadReg<AS5047U_REG::SETTINGS3>();
223 s3.bits.ABIRES = kBitsToAbires[resolution_bits - 10];
224 return this->
template WriteReg(s3, retries);
227template <
typename SpiType>
229 pairs = std::clamp(pairs, uint8_t(1), uint8_t(7));
230 auto s3 = this->
template ReadReg<AS5047U_REG::SETTINGS3>();
231 s3.bits.UVWPP =
static_cast<uint8_t
>(pairs - 1);
232 return this->
template WriteReg(s3, retries);
235template <
typename SpiType>
237 auto s2 = this->
template ReadReg<AS5047U_REG::SETTINGS2>();
238 s2.bits.IWIDTH = (lsb_len == 1) ? 1 : 0;
239 return this->
template WriteReg(s2, retries);
253template <
typename SpiType>
255 auto dis = this->
template ReadReg<AS5047U_REG::DISABLE>();
256 auto s2 = this->
template ReadReg<AS5047U_REG::SETTINGS2>();
257 dis.bits.ABI_off = abi ? 0 : 1;
258 dis.bits.UVW_off = uvw ? 0 : 1;
262 }
else if (!abi && uvw) {
269 return this->
template WriteReg(dis, retries) && this->
template WriteReg(s2, retries);
272template <
typename SpiType>
274 auto s2 = this->
template ReadReg<AS5047U_REG::SETTINGS2>();
275 s2.bits.DAECDIS = enable ? 0 : 1;
276 return this->
template WriteReg(s2, retries);
279template <
typename SpiType>
281 auto dis = this->
template ReadReg<AS5047U_REG::DISABLE>();
282 dis.bits.FILTER_disable = enable ? 0 : 1;
283 return this->
template WriteReg(dis, retries);
286template <
typename SpiType>
288 k_min = std::min(k_min, uint8_t(7));
289 k_max = std::min(k_max, uint8_t(7));
290 auto s1 = this->
template ReadReg<AS5047U_REG::SETTINGS1>();
291 s1.bits.K_min = k_min;
292 s1.bits.K_max = k_max;
293 return this->
template WriteReg(s1, retries);
296template <
typename SpiType>
298 if (!SetAdaptiveFilter(
true, retries)) {
303 uint8_t k_min_code = 0;
304 uint8_t k_max_code = 0;
319 return SetFilterParameters(k_min_code, k_max_code, retries);
322template <
typename SpiType>
326 auto dis = this->
template ReadReg<AS5047U_REG::DISABLE>();
327 for (uint8_t i = 0; i < retries; ++i) {
328 if ((
static_cast<uint16_t
>(GetStickyErrorFlags()) & retryMask) == 0) {
331 dis = this->
template ReadReg<AS5047U_REG::DISABLE>();
333 return (dis.bits.FILTER_disable == 0);
336template <
typename SpiType>
340 auto s1 = this->
template ReadReg<AS5047U_REG::SETTINGS1>();
341 for (uint8_t i = 0; i < retries; ++i) {
342 if ((
static_cast<uint16_t
>(GetStickyErrorFlags()) & retryMask) == 0) {
345 s1 = this->
template ReadReg<AS5047U_REG::SETTINGS1>();
347 return {s1.bits.K_min, s1.bits.K_max};
350template <
typename SpiType>
352 auto s2 = this->
template ReadReg<AS5047U_REG::SETTINGS2>();
353 s2.bits.NOISESET = enable ? 1 : 0;
354 return this->
template WriteReg(s2, retries);
357template <
typename SpiType>
366 SetZeroPosition(GetAngle());
369 uint16_t volatile_shadow[5];
370 for (uint16_t a = 0x0016; a <= 0x001A; ++a) {
371 volatile_shadow[a - 0x0016] = readRegister(a);
375 auto ecc = this->
template ReadReg<AS5047U_REG::ECC>();
377 this->
template WriteReg(ecc);
378 auto key = this->
template ReadReg<AS5047U_REG::ECC_Checksum>().bits.ECC_s;
379 ecc.bits.ECC_chsum = key;
380 this->
template WriteReg(ecc);
383 for (uint16_t a = 0x0016; a <= 0x001A; ++a) {
384 if (readRegister(a) != volatile_shadow[a - 0x0016]) {
385 this->frame_format_ = backup;
393 this->
template WriteReg(p);
395 this->
template WriteReg(p);
398 for (uint16_t i = 0; i < 15000; ++i) {
400 this->frame_format_ = backup;
404 this->
template WriteReg(p);
408 this->
template WriteReg(p);
410 this->
template WriteReg(p);
413 for (uint16_t a = 0x0016; a <= 0x001A; ++a) {
414 if (readRegister(a) != volatile_shadow[a - 0x0016]) {
415 this->frame_format_ = backup;
424 this->frame_format_ = backup;
428template <
typename SpiType>
431 if (err_fl & (1u << 0))
433 if (err_fl & (1u << 1))
435 if (err_fl & (1u << 2))
437 if (err_fl & (1u << 3))
439 if (err_fl & (1u << 4))
441 if (err_fl & (1u << 5))
443 if (err_fl & (1u << 6))
445 if (err_fl & (1u << 7))
447 if (err_fl & (1u << 9))
449 if (err_fl & (1u << 10))
453template <
typename SpiType>
455 uint16_t val = sticky_errors_.exchange(0);
460template <
typename SpiType>
462 this->pad_byte_ = pad;
465template <
typename SpiType>
468 auto s3 = this->
template ReadReg<AS5047U_REG::SETTINGS3>();
469 s3.bits.HYS =
static_cast<uint8_t
>(hysteresis);
470 return this->
template WriteReg(s3, retries);
473template <
typename SpiType>
475 auto s3 = this->
template ReadReg<AS5047U_REG::SETTINGS3>();
479template <
typename SpiType>
482 auto s2 = this->
template ReadReg<AS5047U_REG::SETTINGS2>();
483 s2.bits.Data_select =
static_cast<uint8_t
>(source);
484 return this->
template WriteReg(s2, retries);
487template <
typename SpiType>
489 auto s2 = this->
template ReadReg<AS5047U_REG::SETTINGS2>();
493template <
typename SpiType>
495 return this->
template ReadReg<AS5047U_REG::DIA>();
510template <
typename SpiType>
516 uint16_t cmd =
static_cast<uint16_t
>(0x4000 | (address & 0x3FFF));
517 const uint8_t tx[2] = {
static_cast<uint8_t
>(cmd >> 8),
static_cast<uint8_t
>(cmd & 0xFF)};
519 spi_.transfer(tx, rx, 2);
522 const uint8_t tx_nop[2] = {0x40, 0x00};
524 spi_.transfer(tx_nop, rx_data, 2);
527 uint16_t raw = (
static_cast<uint16_t
>(rx_data[0]) << 8) | rx_data[1];
528 result = raw & 0x3FFF;
532 uint16_t crc_input =
static_cast<uint16_t
>((1 << 14) | (address & 0x3FFF));
533 uint8_t crc = ComputeCRC8(crc_input);
534 const uint8_t tx_cmd[3] = {
535 static_cast<uint8_t
>(((address >> 8) & 0x3F) | 0x40),
536 static_cast<uint8_t
>(address & 0xFF), crc};
538 spi_.transfer(tx_cmd, rx_cmd, 3);
542 uint16_t nop_crc_input =
static_cast<uint16_t
>((1 << 14) | (nop_addr & 0x3FFF));
543 uint8_t crc_nop = ComputeCRC8(nop_crc_input);
544 const uint8_t tx_nop[3] = {
static_cast<uint8_t
>(((nop_addr >> 8) & 0x3F) | 0x40),
545 static_cast<uint8_t
>(nop_addr & 0xFF), crc_nop};
546 uint8_t rx_data_frame[3];
547 spi_.transfer(tx_nop, rx_data_frame, 3);
550 uint16_t raw = (
static_cast<uint16_t
>(rx_data_frame[0]) << 8) | rx_data_frame[1];
551 uint8_t crc_device = rx_data_frame[2];
552 uint8_t crc_calc = ComputeCRC8(raw);
553 if (crc_device != crc_calc) {
556 result = raw & 0x3FFF;
561 uint16_t crc_input =
static_cast<uint16_t
>((1 << 14) | (address & 0x3FFF));
562 uint8_t crc = ComputeCRC8(crc_input);
563 const uint8_t tx_cmd[4] = {
565 static_cast<uint8_t
>(((address >> 8) & 0x3F) | 0x40),
566 static_cast<uint8_t
>(address & 0xFF), crc};
568 spi_.transfer(tx_cmd, rx_cmd, 4);
572 uint16_t nop_crc_input =
static_cast<uint16_t
>((1 << 14) | (nop_addr & 0x3FFF));
573 uint8_t crc_nop = ComputeCRC8(nop_crc_input);
574 const uint8_t tx_nop[4] = {this->pad_byte_,
575 static_cast<uint8_t
>(((nop_addr >> 8) & 0x3F) | 0x40),
576 static_cast<uint8_t
>(nop_addr & 0xFF), crc_nop};
577 uint8_t rx_data_frame[4];
578 spi_.transfer(tx_nop, rx_data_frame, 4);
581 uint16_t raw = (
static_cast<uint16_t
>(rx_data_frame[0] & 0x3Fu) << 8) | rx_data_frame[1];
582 uint16_t crc_payload_32 = (
static_cast<uint16_t
>(rx_data_frame[0]) << 8) | rx_data_frame[1];
583 uint8_t crc_device = rx_data_frame[2];
584 uint8_t crc_calc = ComputeCRC8(crc_payload_32);
585 if (crc_device != crc_calc) {
588 result = raw & 0x3FFF;
594template <
typename SpiType>
595uint16_t AS5047U<SpiType>::readRegister(uint16_t address)
const {
596 uint16_t val = rawReadRegister(address);
598 updateStickyErrors(err);
602template <
typename SpiType>
603bool AS5047U<SpiType>::writeRegister(uint16_t address, uint16_t value, uint8_t retries)
const {
604 bool success =
false;
620 const uint16_t expected = value & 0x3FFF;
622 const uint16_t nop_crc_input =
static_cast<uint16_t
>((1 << 14) | (nop_addr & 0x3FFF));
623 const uint8_t crc_nop = ComputeCRC8(nop_crc_input);
625 for (uint8_t attempt = 0; attempt <= retries; ++attempt) {
628 uint16_t cmd_payload =
static_cast<uint16_t
>(address & 0x3FFF);
629 uint8_t cmd_crc = ComputeCRC8(cmd_payload);
630 const uint8_t tx_cmd[3] = {
static_cast<uint8_t
>((address >> 8) & 0x3F),
631 static_cast<uint8_t
>(address & 0xFF), cmd_crc};
633 spi_.transfer(tx_cmd, rx_cmd, 3);
635 uint16_t data_payload = value & 0x3FFF;
636 uint8_t data_crc = ComputeCRC8(data_payload);
637 const uint8_t tx_data[3] = {
static_cast<uint8_t
>((data_payload >> 8) & 0xFF),
638 static_cast<uint8_t
>(data_payload & 0xFF), data_crc};
640 spi_.transfer(tx_data, rx_data, 3);
644 const uint8_t tx_nop[3] = {
static_cast<uint8_t
>(((nop_addr >> 8) & 0x3F) | 0x40),
645 static_cast<uint8_t
>(nop_addr & 0xFF), crc_nop};
647 spi_.transfer(tx_nop, rx_nop, 3);
648 uint16_t read_back = (
static_cast<uint16_t
>(rx_nop[0] & 0x3Fu) << 8) | rx_nop[1];
649 if (read_back == expected) {
653 auto errfl = this->
template ReadReg<AS5047U_REG::ERRFL>();
654 updateStickyErrors(errfl.value);
655 printf(
"AS5047U write verify failed: addr=0x%04X expected=0x%04X read_back=0x%04X "
656 "ERRFL=0x%04X (CRC_error=%u Framing_error=%u Command_error=%u)\n",
657 static_cast<unsigned>(address),
static_cast<unsigned>(expected),
658 static_cast<unsigned>(read_back),
static_cast<unsigned>(errfl.value),
659 static_cast<unsigned>(errfl.bits.CRC_error),
660 static_cast<unsigned>(errfl.bits.Framing_error),
661 static_cast<unsigned>(errfl.bits.Command_error));
664 uint16_t cmd_payload =
static_cast<uint16_t
>(address & 0x3FFF);
665 uint8_t cmd_crc = ComputeCRC8(cmd_payload);
666 const uint8_t tx_cmd[4] = {this->pad_byte_,
667 static_cast<uint8_t
>((address >> 8) & 0x3F),
668 static_cast<uint8_t
>(address & 0xFF), cmd_crc};
670 spi_.transfer(tx_cmd, rx_cmd, 4);
672 uint16_t data_payload = value & 0x3FFF;
673 uint8_t data_crc = ComputeCRC8(data_payload);
674 const uint8_t tx_data[4] = {this->pad_byte_,
static_cast<uint8_t
>((data_payload >> 8) & 0xFF),
675 static_cast<uint8_t
>(data_payload & 0xFF), data_crc};
677 spi_.transfer(tx_data, rx_data, 4);
680 const uint8_t tx_nop[4] = {this->pad_byte_,
681 static_cast<uint8_t
>(((nop_addr >> 8) & 0x3F) | 0x40),
682 static_cast<uint8_t
>(nop_addr & 0xFF), crc_nop};
684 spi_.transfer(tx_nop, rx_nop, 4);
685 uint16_t read_back = (
static_cast<uint16_t
>(rx_nop[0] & 0x3Fu) << 8) | rx_nop[1];
686 if (read_back == expected) {
690 auto errfl = this->
template ReadReg<AS5047U_REG::ERRFL>();
691 updateStickyErrors(errfl.value);
692 printf(
"AS5047U write verify failed: addr=0x%04X expected=0x%04X read_back=0x%04X "
693 "ERRFL=0x%04X (CRC_error=%u Framing_error=%u Command_error=%u)\n",
694 static_cast<unsigned>(address),
static_cast<unsigned>(expected),
695 static_cast<unsigned>(read_back),
static_cast<unsigned>(errfl.value),
696 static_cast<unsigned>(errfl.bits.CRC_error),
697 static_cast<unsigned>(errfl.bits.Framing_error),
698 static_cast<unsigned>(errfl.bits.Command_error));
709template <
typename SpiType>
711 printf(
"\n=== AS5047U Comprehensive Status ===\n");
713 printf(
"Angle (COM) : %u\n", GetAngle());
714 printf(
"Angle (UNC) : %u\n", GetRawAngle());
715 printf(
"Velocity : %d counts (%.3f deg/s, %.3f rad/s, %.3f RPM)\n", GetVelocity(),
716 GetVelocityDegPerSec(), GetVelocityRadPerSec(), GetVelocityRPM());
717 printf(
"AGC : %u\n", GetAGC());
718 printf(
"Magnitude : %u\n", GetMagnitude());
720 uint16_t err = GetErrorFlags();
721 printf(
"ERRFL : 0x%04X\n", err);
723 auto dia = this->
template ReadReg<AS5047U_REG::DIA>();
724 printf(
"DIA (0x3FF5): 0x%04X\n", dia.value);
725 printf(
" VDD_mode : %u\n", dia.bits.VDD_mode);
726 printf(
" LoopsFinished : %u\n", dia.bits.LoopsFinished);
727 printf(
" CORDIC_overflow : %u\n", dia.bits.CORDIC_overflow_flag);
728 printf(
" Comp_l : %u\n", dia.bits.Comp_l);
729 printf(
" Comp_h : %u\n", dia.bits.Comp_h);
730 printf(
" MagHalf_flag : %u\n", dia.bits.MagHalf_flag);
731 printf(
" CosOff_fin : %u\n", dia.bits.CosOff_fin);
732 printf(
" SinOff_fin : %u\n", dia.bits.SinOff_fin);
733 printf(
" OffComp_finished : %u\n", dia.bits.OffComp_finished);
734 printf(
" AGC_finished : %u\n", dia.bits.AGC_finished);
735 printf(
" SPI_cnt : %u\n", dia.bits.SPI_cnt);
737 auto dis = this->
template ReadReg<AS5047U_REG::DISABLE>();
738 printf(
"DISABLE (0x0015): 0x%04X UVW_off=%u ABI_off=%u FILTER_disable=%u\n", dis.value,
739 dis.bits.UVW_off, dis.bits.ABI_off, dis.bits.FILTER_disable);
740 auto s1 = this->
template ReadReg<AS5047U_REG::SETTINGS1>();
741 printf(
"SETTINGS1(0x0016): K_max=%u K_min=%u Dia3_en=%u Dia4_en=%u\n", s1.bits.K_max,
742 s1.bits.K_min, s1.bits.Dia3_en, s1.bits.Dia4_en);
743 auto s2 = this->
template ReadReg<AS5047U_REG::SETTINGS2>();
744 printf(
"SETTINGS2(0x0019): IWIDTH=%u NOISESET=%u DIR=%u UVW_ABI=%u "
745 "DAECDIS=%u ABI_DEC=%u "
746 "Data_select=%u PWMon=%u\n",
747 s2.bits.IWIDTH, s2.bits.NOISESET, s2.bits.DIR, s2.bits.UVW_ABI, s2.bits.DAECDIS,
748 s2.bits.ABI_DEC, s2.bits.Data_select, s2.bits.PWMon);
749 auto s3 = this->
template ReadReg<AS5047U_REG::SETTINGS3>();
750 printf(
"SETTINGS3(0x001A): UVWPP=%u HYS=%u ABIRES=%u\n", s3.bits.UVWPP, s3.bits.HYS,
753 auto sind = this->
template ReadReg<AS5047U_REG::SINDATA>();
754 printf(
"SINDATA(0x3FFA): %d\n", sind.bits.SINDATA);
755 auto eccsum = this->
template ReadReg<AS5047U_REG::ECC_Checksum>();
756 printf(
"ECC_Checksum(0x3FD0): %u\n", eccsum.bits.ECC_s);
757 auto prog = this->
template ReadReg<AS5047U_REG::PROG>();
758 printf(
"PROG(0x0003): PROGEN=%u PROGOTP=%u OTPREF=%u PROGVER=%u\n", prog.bits.PROGEN,
759 prog.bits.PROGOTP, prog.bits.OTPREF, prog.bits.PROGVER);
761 printf(
"FrameFormat : %u PadByte=0x%02X\n",
static_cast<uint8_t
>(this->frame_format_),
763 printf(
"========================================\n\n");
Driver for AMS AS5047U Magnetic Rotary Position Sensor (C++21)
AS5047U_Error
Definition as5047u.hpp:21
@ CommandError
Invalid SPI command received.
@ P2ramWarning
ECC corrected 1 bit in P2RAM customer area.
@ OffCompError
Internal offset compensation not finished.
@ P2ramError
ECC detected 2+ uncorrectable errors in P2RAM.
@ AgcWarning
AGC reached minimum (0) or maximum (255) value.
@ FramingError
SPI framing error.
@ WatchdogError
Internal oscillator or watchdog not working proper.
@ CrcError
CRC error during SPI communication.
@ MagHalf
Magnetic field is half of regulated value (AGC=255)
@ CordicOverflow
CORDIC algorithm overflow.
FilterPreset
Presets for the adaptive velocity/angle filter (Dynamic Filter System).
Definition as5047u_types.hpp:26
FrameFormat
Supported SPI frame formats for AS5047U communication.
Definition as5047u_types.hpp:12
AS5047U magnetic rotary sensor driver class.
Definition as5047u.hpp:83
float GetVelocityDegPerSec(uint8_t retries=AS5047U_CFG::CRC_RETRIES) const
Get rotational velocity in degrees per second.
Definition as5047u.ipp:124
bool SetAdaptiveFilter(bool enable, uint8_t retries=AS5047U_CFG::CRC_RETRIES)
Enable/disable the adaptive filter (Dynamic Filter System).
Definition as5047u.ipp:280
uint16_t GetRawAngle(uint8_t retries=AS5047U_CFG::CRC_RETRIES) const
Read the 14-bit absolute angle without dynamic compensation (raw angle).
Definition as5047u.ipp:77
void SetPad(uint8_t pad) noexcept
Set the daisy-chain pad byte for 32-bit SPI frames.
Definition as5047u.ipp:461
bool ProgramOTP()
Permanently program current settings into OTP memory.
Definition as5047u.ipp:358
AS5047U_REG::SETTINGS3::Hysteresis GetHysteresis() const
Get current incremental output hysteresis setting.
Definition as5047u.ipp:474
uint16_t GetMagnitude(uint8_t retries=AS5047U_CFG::CRC_RETRIES) const
Read the current magnetic field magnitude (14-bit value).
Definition as5047u.ipp:154
uint16_t GetErrorFlags(uint8_t retries=AS5047U_CFG::CRC_RETRIES) const
Read and clear error flags.
Definition as5047u.ipp:169
bool SetDynamicAngleCompensation(bool enable, uint8_t retries=AS5047U_CFG::CRC_RETRIES)
Enable/disable Dynamic Angle Error Compensation (DAEC).
Definition as5047u.ipp:273
AS5047U_REG::SETTINGS2::AngleOutputSource GetAngleOutputSource() const
Get currently selected angle output source for 0x3FFF reads.
Definition as5047u.ipp:488
bool SetFilterPreset(FilterPreset preset, uint8_t retries=AS5047U_CFG::CRC_RETRIES)
Set adaptive filter from a preset (easiest way to configure filter).
Definition as5047u.ipp:297
uint16_t GetAngle(uint8_t retries=AS5047U_CFG::CRC_RETRIES) const
Read the 14-bit absolute angle with dynamic compensation (DAEC active).
Definition as5047u.ipp:38
bool ConfigureInterface(bool abi, bool uvw, bool pwm, uint8_t retries=AS5047U_CFG::CRC_RETRIES)
Configure interface outputs (ABI, UVW) and PWM output.
Definition as5047u.ipp:254
float GetVelocityRPM(uint8_t retries=AS5047U_CFG::CRC_RETRIES) const
Get rotational velocity in revolutions per minute.
Definition as5047u.ipp:134
void SetFrameFormat(FrameFormat format) noexcept
Set the SPI frame format (16, 24, or 32-bit).
Definition as5047u.ipp:21
bool SetABIResolution(uint8_t resolution_bits, uint8_t retries=AS5047U_CFG::CRC_RETRIES)
Set the ABI (incremental encoder) resolution.
Definition as5047u.ipp:218
float GetAngleDegrees(uint8_t retries=AS5047U_CFG::CRC_RETRIES) const
Read absolute angle in degrees.
Definition as5047u.ipp:67
bool SetUVWPolePairs(uint8_t pairs, uint8_t retries=AS5047U_CFG::CRC_RETRIES)
Set the number of pole pairs for UVW commutation outputs.
Definition as5047u.ipp:228
uint16_t GetZeroPosition(uint8_t retries=AS5047U_CFG::CRC_RETRIES) const
Get the currently configured soft zero position offset (14-bit).
Definition as5047u.ipp:181
bool Set150CTemperatureMode(bool enable, uint8_t retries=AS5047U_CFG::CRC_RETRIES)
Set temperature mode for 150°C operation (NOISESET bit).
Definition as5047u.ipp:351
bool SetHysteresis(AS5047U_REG::SETTINGS3::Hysteresis hysteresis, uint8_t retries=AS5047U_CFG::CRC_RETRIES)
Set incremental output hysteresis level.
Definition as5047u.ipp:466
std::pair< uint8_t, uint8_t > GetFilterParameters(uint8_t retries=AS5047U_CFG::CRC_RETRIES) const
Read current K_min and K_max register codes (0–7 each).
Definition as5047u.ipp:337
bool GetAdaptiveFilterEnabled(uint8_t retries=AS5047U_CFG::CRC_RETRIES) const
Read whether the adaptive filter is enabled.
Definition as5047u.ipp:323
void DumpStatus() const
Dump formatted status and diagnostics using printf.
Definition as5047u.ipp:710
bool SetZeroPosition(uint16_t angle_lsb, uint8_t retries=AS5047U_CFG::CRC_RETRIES)
Set a new zero reference position (soft offset).
Definition as5047u.ipp:209
bool SetAngleOutputSource(AS5047U_REG::SETTINGS2::AngleOutputSource source, uint8_t retries=AS5047U_CFG::CRC_RETRIES)
Select which angle register (0x3FFF) is returned on reads.
Definition as5047u.ipp:480
bool SetFilterParameters(uint8_t k_min, uint8_t k_max, uint8_t retries=AS5047U_CFG::CRC_RETRIES)
Set adaptive filter parameters (K_min and K_max as 3-bit register codes).
Definition as5047u.ipp:287
int16_t GetVelocity(uint8_t retries=AS5047U_CFG::CRC_RETRIES) const
Read the current rotational velocity (signed 14-bit).
Definition as5047u.ipp:92
AS5047U_Error GetStickyErrorFlags() const
Retrieve and clear the accumulated sticky error flags.
Definition as5047u.ipp:454
AS5047U_REG::DIA GetDiagnostics() const
Read the full diagnostic register (DIA).
Definition as5047u.ipp:494
float GetAngleRadians(uint8_t retries=AS5047U_CFG::CRC_RETRIES) const
Read absolute angle in radians.
Definition as5047u.ipp:72
bool SetIndexPulseLength(uint8_t lsb_len, uint8_t retries=AS5047U_CFG::CRC_RETRIES)
Set the index pulse width for ABI output.
Definition as5047u.ipp:236
float GetVelocityRadPerSec(uint8_t retries=AS5047U_CFG::CRC_RETRIES) const
Get rotational velocity in radians per second.
Definition as5047u.ipp:129
uint8_t GetAGC(uint8_t retries=AS5047U_CFG::CRC_RETRIES) const
Read the current Automatic Gain Control (AGC) value (0-255).
Definition as5047u.ipp:139
Definition as5047u.ipp:17
VelocityUnit
Units for velocity-returning APIs.
Definition as5047u.hpp:58
AngleUnit
Units for angle-returning APIs.
Definition as5047u.hpp:51
DIA – Diagnostic register (0x3FF5, read-only)
Definition as5047u_registers.hpp:180
static constexpr uint16_t ADDRESS
Definition as5047u_registers.hpp:81
static constexpr uint16_t ADDRESS
Definition as5047u_registers.hpp:42
PROG – OTP programming control register (0x0003, default 0x0000)
Definition as5047u_registers.hpp:132
static constexpr uint16_t ADDRESS
Definition as5047u_registers.hpp:133
struct AS5047U_REG::PROG::@6::@8 bits
uint16_t PROGEN
Definition as5047u_registers.hpp:137
AngleOutputSource
Angle data source for 0x3FFF output (Data_select bit)
Definition as5047u_registers.hpp:644
Hysteresis
Incremental output hysteresis (HYS) settings:
Definition as5047u_registers.hpp:714
ZPOSL – Zero Position LSB register (0x0017, default 0x0000)
Definition as5047u_registers.hpp:505
struct AS5047U_REG::ZPOSL::@42::@44 bits
uint16_t ZPOSL_bits
Definition as5047u_registers.hpp:510
ZPOSM – Zero Position MSB register (0x0016, default 0x0000)
Definition as5047u_registers.hpp:482
struct AS5047U_REG::ZPOSM::@39::@41 bits
uint16_t ZPOSM_bits
Definition as5047u_registers.hpp:487