MAX22200 Driver
API reference
Loading...
Searching...
No Matches
max22200_types.hpp
Go to the documentation of this file.
1
66#pragma once
68#include <array>
69#include <cstdint>
70
71namespace max22200 {
72
73// ============================================================================
74// Enumerations
75// ============================================================================
76
98enum class DriveMode : uint8_t {
99 CDR = 0,
100 VDR = 1
101};
102
123enum class SideMode : uint8_t {
124 LOW_SIDE = 0,
125 HIGH_SIDE = 1
126};
127
159enum class ChannelMode : uint8_t {
160 INDEPENDENT = 0,
161 PARALLEL = 1,
162 HBRIDGE = 2
163};
164
211enum class ChopFreq : uint8_t {
212 FMAIN_DIV4 = 0,
213 FMAIN_DIV3 = 1,
214 FMAIN_DIV2 = 2,
215 FMAIN = 3
216};
217
224inline uint32_t getChopFreqKhz(bool master_clock_80khz, ChopFreq cf) {
225 switch (cf) {
226 case ChopFreq::FMAIN_DIV4: return master_clock_80khz ? 20u : 25u;
227 case ChopFreq::FMAIN_DIV3: return master_clock_80khz ? 26u : 33u;
228 case ChopFreq::FMAIN_DIV2: return master_clock_80khz ? 40u : 50u;
229 case ChopFreq::FMAIN: return master_clock_80khz ? 80u : 100u;
230 default: return 25u;
231 }
232}
233
240inline float getChopFreqKhzExact(bool master_clock_80khz, ChopFreq cf) {
241 const float fmain_khz = master_clock_80khz ? 80.0f : 100.0f;
242 switch (cf) {
243 case ChopFreq::FMAIN_DIV4: return fmain_khz / 4.0f;
244 case ChopFreq::FMAIN_DIV3: return fmain_khz / 3.0f;
245 case ChopFreq::FMAIN_DIV2: return fmain_khz / 2.0f;
246 case ChopFreq::FMAIN: return fmain_khz;
247 default: return fmain_khz / 4.0f;
248 }
249}
250
257inline uint8_t currentMaToRaw(uint32_t full_scale_current_ma, uint32_t ma) {
258 if (full_scale_current_ma == 0) return 0;
259 if (ma >= full_scale_current_ma) return 127;
260 uint32_t raw = (ma * 127u + full_scale_current_ma / 2u) / full_scale_current_ma;
261 return raw > 127u ? 127u : static_cast<uint8_t>(raw);
262}
263
273inline uint8_t dutyPercentToRaw(float percent) {
274 if (!(percent > 0.0f)) return 0; // also catches NaN
275 if (percent >= 100.0f) return 100;
276 const uint32_t raw = static_cast<uint32_t>(percent + 0.5f);
277 return raw > 100u ? 100u : static_cast<uint8_t>(raw);
278}
279
285inline float dutyRawToPercent(uint8_t raw) {
286 return raw >= 100u ? 100.0f : static_cast<float>(raw);
287}
288
296inline uint8_t hitTimeMsToRaw(float ms, bool master_clock_80khz, ChopFreq cf) {
297 uint32_t fchop_khz = getChopFreqKhz(master_clock_80khz, cf);
298 if (ms < 0.0f || ms >= 1000000.0f) return 255;
299 if (ms == 0.0f) return 0;
300 float fchop_hz = static_cast<float>(fchop_khz) * 1000.0f;
301 uint32_t raw = static_cast<uint32_t>((ms / 1000.0f) * fchop_hz / 40.0f + 0.5f);
302 if (raw > 254u) return 255;
303 if (raw == 0u) return 1;
304 return static_cast<uint8_t>(raw);
305}
306
313inline float getMaxHitTimeMs(bool master_clock_80khz, ChopFreq cf) {
314 const uint32_t fchop_khz = getChopFreqKhz(master_clock_80khz, cf);
315 const float fchop_hz = static_cast<float>(fchop_khz) * 1000.0f;
316 return (254.0f * 40.0f / fchop_hz) * 1000.0f;
317}
318
322enum class FaultType : uint8_t {
323 OCP = 0,
324 HHF = 1,
325 OLF = 2,
326 DPM = 3,
327 OVT = 4,
328 UVM = 5,
329 COMER = 6
330};
331
337inline const char *FaultTypeToStr(FaultType ft) {
338 switch (ft) {
339 case FaultType::OCP: return "Overcurrent";
340 case FaultType::HHF: return "HIT not reached";
341 case FaultType::OLF: return "Open-load";
342 case FaultType::DPM: return "Plunger movement";
343 case FaultType::OVT: return "Overtemperature";
344 case FaultType::UVM: return "Undervoltage";
345 case FaultType::COMER: return "Communication error";
346 default: return "Unknown fault";
347 }
348}
349
350// ============================================================================
351// Structures
352// ============================================================================
353
403 // ── User Units (Primary Storage) ──────────────────────────────────────────
404 // CDR: setpoint in mA. VDR: setpoint in duty % (0–100). Use accessors for intent-revealing names.
405
411
412 // ── Register Fields (Direct Mapping) ─────────────────────────────────────
424
435
452
459 static ChannelConfig makeSolenoidVdr(float hit_pct, float hold_pct, float hit_time_ms) {
463 c.hit_setpoint = hit_pct;
464 c.hold_setpoint = hold_pct;
467 return c;
468 }
469
470 // ── Mode-aware accessors (same storage; use for clear intent at call site) ─
472 void set_hit_ma(float ma) { hit_setpoint = ma; }
474 void set_hold_ma(float ma) { hold_setpoint = ma; }
476 void set_hit_duty_percent(float pct) { hit_setpoint = pct; }
478 void set_hold_duty_percent(float pct) { hold_setpoint = pct; }
480 float hit_ma() const { return hit_setpoint; }
482 float hold_ma() const { return hold_setpoint; }
484 float hit_duty_percent() const { return hit_setpoint; }
486 float hold_duty_percent() const { return hold_setpoint; }
487
497 uint32_t toRegister(uint32_t board_ifs_ma = 0, bool master_clock_80khz = false) const {
498 // Effective IFS for CDR: HFS=1 halves the scale (datasheet KFS 7.5k vs 15k)
499 const uint32_t ifs_ma = (drive_mode == DriveMode::CDR && half_full_scale && board_ifs_ma >= 2u)
500 ? (board_ifs_ma / 2u)
501 : board_ifs_ma;
502
503 // Convert hit_setpoint to raw 7-bit
504 uint8_t hit_raw;
505 if (drive_mode == DriveMode::CDR) {
506 // CDR: hit_setpoint is in mA (relative to effective IFS for this channel)
507 if (ifs_ma == 0) {
508 hit_raw = 0; // Invalid IFS
509 } else if (hit_setpoint >= static_cast<float>(ifs_ma)) {
510 hit_raw = 127;
511 } else {
512 uint32_t ma = static_cast<uint32_t>(hit_setpoint + 0.5f);
513 hit_raw = currentMaToRaw(ifs_ma, ma);
514 }
515 } else {
516 // VDR: hit_setpoint is duty percent (0-100)
518 }
519
520 // Convert hold_setpoint to raw 7-bit
521 uint8_t hold_raw;
522 if (drive_mode == DriveMode::CDR) {
523 // CDR: hold_setpoint is in mA
524 if (ifs_ma == 0) {
525 hold_raw = 0;
526 } else if (hold_setpoint >= static_cast<float>(ifs_ma)) {
527 hold_raw = 127;
528 } else {
529 uint32_t ma = static_cast<uint32_t>(hold_setpoint + 0.5f);
530 hold_raw = currentMaToRaw(ifs_ma, ma);
531 }
532 } else {
533 // VDR: hold_setpoint is duty percent (0-100)
535 }
536
537 // Convert hit_time_ms to raw 8-bit (master_clock_80khz from parameter, not stored on config)
538 uint8_t hit_time_raw = hitTimeMsToRaw(hit_time_ms, master_clock_80khz, chop_freq);
539
540 // Build register value
541 uint32_t val = 0;
543 val |= (static_cast<uint32_t>(hold_raw & 0x7F) << CfgChReg::HOLD_SHIFT);
545 val |= (static_cast<uint32_t>(hit_raw & 0x7F) << CfgChReg::HIT_SHIFT);
546 val |= (static_cast<uint32_t>(hit_time_raw) << CfgChReg::HITT_SHIFT);
549 val |= (static_cast<uint32_t>(chop_freq) << CfgChReg::FREQ_CFG_SHIFT);
554 return val;
555 }
556
566 void fromRegister(uint32_t val, uint32_t board_ifs_ma, bool master_clock_80khz_param) {
567 // Parse register fields
568 half_full_scale = (val & CfgChReg::HFS_BIT) != 0;
569 uint8_t hold_raw = static_cast<uint8_t>((val >> CfgChReg::HOLD_SHIFT) & 0x7F);
571 uint8_t hit_raw = static_cast<uint8_t>((val >> CfgChReg::HIT_SHIFT) & 0x7F);
572 uint8_t hit_time_raw = static_cast<uint8_t>((val >> CfgChReg::HITT_SHIFT) & 0xFF);
575 chop_freq = static_cast<ChopFreq>((val >> CfgChReg::FREQ_CFG_SHIFT) & 0x03);
580
581 // Convert raw → user units (master_clock_80khz_param used for hit_time only; not stored on config)
582 if (drive_mode == DriveMode::CDR) {
583 // CDR: raw → mA (use effective IFS when HFS=1)
584 const uint32_t effective_ifs = half_full_scale && board_ifs_ma >= 2u
585 ? (board_ifs_ma / 2u)
586 : board_ifs_ma;
587 if (effective_ifs > 0) {
588 hit_setpoint = (static_cast<float>(hit_raw) / 127.0f) * static_cast<float>(effective_ifs);
589 hold_setpoint = (static_cast<float>(hold_raw) / 127.0f) * static_cast<float>(effective_ifs);
590 } else {
591 hit_setpoint = 0.0f;
592 hold_setpoint = 0.0f;
593 }
594 } else {
595 // VDR: the field is the duty cycle in percent (datasheet Table 3); 100 and above is 100 %
598 }
599
600 // Convert hit_time raw → ms
601 if (hit_time_raw == 0) {
602 hit_time_ms = 0.0f;
603 } else if (hit_time_raw == 255) {
604 hit_time_ms = -1.0f; // Continuous (infinite)
605 } else {
606 uint32_t fchop_khz = getChopFreqKhz(master_clock_80khz_param, chop_freq);
607 float fchop_hz = static_cast<float>(fchop_khz) * 1000.0f;
608 hit_time_ms = (static_cast<float>(hit_time_raw) * 40.0f / fchop_hz) * 1000.0f;
609 }
610 }
611
612 // ── Inline probe helpers (human-readable, compiler can optimize away) ─────
613
615 bool isCdr() const { return drive_mode == DriveMode::CDR; }
617 bool isVdr() const { return drive_mode == DriveMode::VDR; }
619 bool isLowSide() const { return side_mode == SideMode::LOW_SIDE; }
621 bool isHighSide() const { return side_mode == SideMode::HIGH_SIDE; }
623 bool hasHitTime() const { return hit_time_ms > 0.0f; }
625 bool isContinuousHit() const { return hit_time_ms < 0.0f || hit_time_ms >= 1000000.0f; }
627 bool isTriggeredBySpi() const { return !trigger_from_pin; }
629 bool isTriggeredByPin() const { return trigger_from_pin; }
631 bool isHalfFullScale() const { return half_full_scale; }
641 ChopFreq getChopFreq() const { return chop_freq; }
642};
643
684 // Byte 3 (bits 31:24)
688
689 // Byte 2 (bits 23:16) — fault masks (1=masked, 0=signaled on FAULT pin)
698
699 // Byte 1 (bits 15:8) — channel-pair mode
704
705 // Byte 0 (bits 7:0) — fault flags (read-only) + ACTIVE
706 bool active;
707
708 // Read-only fault flags (populated on read, cleared by reading STATUS or FAULT register)
716
730
737 uint32_t toRegister() const {
738 uint32_t val = 0;
739 val |= (static_cast<uint32_t>(channels_on_mask) << StatusReg::ONCH_SHIFT);
748 val |= (static_cast<uint32_t>(channel_pair_mode_76) << StatusReg::CM76_SHIFT);
749 val |= (static_cast<uint32_t>(channel_pair_mode_54) << StatusReg::CM54_SHIFT);
750 val |= (static_cast<uint32_t>(channel_pair_mode_32) << StatusReg::CM32_SHIFT);
751 val |= (static_cast<uint32_t>(channel_pair_mode_10) << StatusReg::CM10_SHIFT);
752 if (active) val |= StatusReg::ACTIVE_BIT;
753 return val;
754 }
755
760 void fromRegister(uint32_t val) {
761 channels_on_mask = static_cast<uint8_t>((val >> StatusReg::ONCH_SHIFT) & 0xFF);
770 channel_pair_mode_76 = static_cast<ChannelMode>((val >> StatusReg::CM76_SHIFT) & 0x03);
771 channel_pair_mode_54 = static_cast<ChannelMode>((val >> StatusReg::CM54_SHIFT) & 0x03);
772 channel_pair_mode_32 = static_cast<ChannelMode>((val >> StatusReg::CM32_SHIFT) & 0x03);
773 channel_pair_mode_10 = static_cast<ChannelMode>((val >> StatusReg::CM10_SHIFT) & 0x03);
774 overtemperature = (val & StatusReg::OVT_BIT) != 0;
775 overcurrent = (val & StatusReg::OCP_BIT) != 0;
776 open_load_fault = (val & StatusReg::OLF_BIT) != 0;
777 hit_not_reached = (val & StatusReg::HHF_BIT) != 0;
780 undervoltage = (val & StatusReg::UVM_BIT) != 0;
781 active = (val & StatusReg::ACTIVE_BIT) != 0;
782 }
783
792
793 // ── Inline probe helpers ─────────────────────────────────────────────────
794
795 bool hasOvertemperature() const { return overtemperature; }
796 bool hasOvercurrent() const { return overcurrent; }
797 bool hasOpenLoadFault() const { return open_load_fault; }
798 bool hasHitNotReached() const { return hit_not_reached; }
801 bool hasUndervoltage() const { return undervoltage; }
802 bool isActive() const { return active; }
803 bool isChannelOn(uint8_t ch) const {
804 return ch < 8u && (channels_on_mask & (1u << ch)) != 0u;
805 }
806 uint8_t channelCountOn() const {
807 uint8_t n = 0;
808 for (uint8_t i = 0; i < 8; i++) {
809 if (channels_on_mask & (1u << i)) n++;
810 }
811 return n;
812 }
813
821
822 bool is80KHzBase() const { return master_clock_80khz; }
823 bool is100KHzBase() const { return !master_clock_80khz; }
824
829 uint8_t getChannelsOnMask() const { return channels_on_mask; }
830};
831
864
867
872 void fromRegister(uint32_t val) {
873 overcurrent_channel_mask = static_cast<uint8_t>((val >> FaultReg::OCP_SHIFT) & 0xFF);
874 hit_not_reached_channel_mask = static_cast<uint8_t>((val >> FaultReg::HHF_SHIFT) & 0xFF);
875 open_load_fault_channel_mask = static_cast<uint8_t>((val >> FaultReg::OLF_SHIFT) & 0xFF);
876 plunger_movement_fault_channel_mask = static_cast<uint8_t>((val >> FaultReg::DPM_SHIFT) & 0xFF);
877 }
878
886
890 uint8_t getFaultCount() const {
891 uint8_t count = 0;
892 for (uint8_t i = 0; i < 8; i++) {
893 if (overcurrent_channel_mask & (1u << i)) count++;
894 if (hit_not_reached_channel_mask & (1u << i)) count++;
895 if (open_load_fault_channel_mask & (1u << i)) count++;
896 if (plunger_movement_fault_channel_mask & (1u << i)) count++;
897 }
898 return count;
899 }
900
901 // ── Inline probe helpers (human-readable, compiler can optimize away) ─────
902
903 bool hasOvercurrent() const { return overcurrent_channel_mask != 0; }
904 bool hasHitNotReached() const { return hit_not_reached_channel_mask != 0; }
905 bool hasOpenLoadFault() const { return open_load_fault_channel_mask != 0; }
911 bool hasOvercurrentOnChannel(uint8_t ch) const {
912 return ch < NUM_CHANNELS_ && (overcurrent_channel_mask & (1u << ch)) != 0u;
913 }
914 bool hasHitNotReachedOnChannel(uint8_t ch) const {
915 return ch < NUM_CHANNELS_ && (hit_not_reached_channel_mask & (1u << ch)) != 0u;
916 }
917 bool hasOpenLoadFaultOnChannel(uint8_t ch) const {
918 return ch < NUM_CHANNELS_ && (open_load_fault_channel_mask & (1u << ch)) != 0u;
919 }
920 bool hasPlungerMovementFaultOnChannel(uint8_t ch) const {
921 return ch < NUM_CHANNELS_ && (plunger_movement_fault_channel_mask & (1u << ch)) != 0u;
922 }
927};
928
966
973enum class FullBridgeState : uint8_t {
974 HiZ = 0,
975 Forward = 1,
976 Reverse = 2,
977 Brake = 3
978};
979
985enum class DriverStatus : uint8_t {
986 OK = 0,
991 TIMEOUT
992};
993
999inline const char *DriverStatusToStr(DriverStatus s) {
1000 switch (s) {
1001 case DriverStatus::OK:
1002 return "OK";
1004 return "INITIALIZATION_ERROR";
1006 return "COMMUNICATION_ERROR";
1008 return "INVALID_PARAMETER";
1010 return "HARDWARE_FAULT";
1012 return "TIMEOUT";
1013 default:
1014 return "UNKNOWN";
1015 }
1016}
1017
1024enum class ChannelState : uint8_t {
1025 DISABLED = 0,
1026 ENABLED,
1027 HIT_PHASE,
1028 HOLD_PHASE,
1029 FAULT
1030};
1031
1035using ChannelConfigArray = std::array<ChannelConfig, NUM_CHANNELS_>;
1036
1047using FaultCallback = void (*)(uint8_t channel, FaultType fault_type,
1048 void *user_data);
1049
1060using StateChangeCallback = void (*)(uint8_t channel, ChannelState old_state,
1061 ChannelState new_state, void *user_data);
1062
1093
1095
1110 BoardConfig(float rref_kohm, bool hfs)
1112 const float kfs = hfs ? 7.5f : 15.0f; // KFS in kΩ
1113 full_scale_current_ma = static_cast<uint32_t>((kfs * 1000.0f) / rref_kohm + 0.5f);
1114 }
1115
1117 bool hasMaxCurrentLimit() const { return max_current_ma > 0u; }
1119 bool hasMaxDutyLimit() const { return max_duty_percent > 0u; }
1121 bool hasIfsConfigured() const { return full_scale_current_ma > 0u; }
1125 uint32_t getMaxCurrentLimitMa() const { return max_current_ma; }
1127 uint8_t getMaxDutyLimitPercent() const { return max_duty_percent; }
1128};
1129
1137 uint8_t min_percent;
1138 uint8_t max_percent;
1139
1141
1143 uint8_t getMinPercent() const { return min_percent; }
1145 uint8_t getMaxPercent() const { return max_percent; }
1147 bool inRange(float percent) const {
1148 return percent >= static_cast<float>(min_percent) && percent <= static_cast<float>(max_percent);
1149 }
1151 float clamp(float percent) const {
1152 if (percent <= static_cast<float>(min_percent)) return static_cast<float>(min_percent);
1153 if (percent >= static_cast<float>(max_percent)) return static_cast<float>(max_percent);
1154 return percent;
1155 }
1156};
1157
1168 uint32_t fault_events;
1169 uint32_t state_changes;
1170 uint32_t uptime_ms;
1171
1175
1176 float getSuccessRate() const {
1177 if (total_transfers == 0) return 100.0f;
1178 return ((float)(total_transfers - failed_transfers) / total_transfers) * 100.0f;
1179 }
1180
1182 bool hasFailures() const { return failed_transfers != 0u; }
1184 bool isHealthy() const { return failed_transfers == 0u; }
1186 uint32_t getTotalTransfers() const { return total_transfers; }
1188 uint32_t getFailedTransfers() const { return failed_transfers; }
1190 uint32_t getFaultEvents() const { return fault_events; }
1192 uint32_t getStateChanges() const { return state_changes; }
1194 uint32_t getUptimeMs() const { return uptime_ms; }
1195};
1196
1197} // namespace max22200
Register definitions and constants for MAX22200 IC.
constexpr uint32_t DPM_EN_BIT
DPM_EN bit (0=disabled, 1=enabled)
Definition max22200_registers.hpp:408
constexpr uint32_t HITT_SHIFT
HIT time bit shift.
Definition max22200_registers.hpp:388
constexpr uint32_t HOLD_SHIFT
HOLD current bit shift.
Definition max22200_registers.hpp:377
constexpr uint32_t OL_EN_BIT
OL_EN bit (0=disabled, 1=enabled)
Definition max22200_registers.hpp:405
constexpr uint32_t SRC_BIT
SRC bit (0=fast, 1=slew-rate controlled)
Definition max22200_registers.hpp:402
constexpr uint32_t FREQ_CFG_SHIFT
FREQ_CFG bit shift.
Definition max22200_registers.hpp:398
constexpr uint32_t HIT_SHIFT
HIT current bit shift.
Definition max22200_registers.hpp:384
constexpr uint32_t VDRNCDR_BIT
VDRnCDR bit (0=CDR, 1=VDR)
Definition max22200_registers.hpp:392
constexpr uint32_t TRGNSPI_BIT
TRGnSPI bit (0=SPI ONCH, 1=TRIG pin)
Definition max22200_registers.hpp:381
constexpr uint32_t HHF_EN_BIT
HHF_EN bit (0=disabled, 1=enabled)
Definition max22200_registers.hpp:411
constexpr uint32_t HFS_BIT
HFS bit (0=1x full-scale, 1=0.5x half-scale)
Definition max22200_registers.hpp:374
constexpr uint32_t HSNLS_BIT
HSnLS bit (0=low-side, 1=high-side)
Definition max22200_registers.hpp:395
constexpr uint32_t DPM_TDEB_SHIFT
DPM_TDEB bit shift (bits 7:4)
Definition max22200_registers.hpp:526
constexpr uint32_t DPM_ISTART_SHIFT
DPM_ISTART bit shift (bits 14:8)
Definition max22200_registers.hpp:524
constexpr uint32_t DPM_IPTH_SHIFT
DPM_IPTH bit shift (bits 3:0)
Definition max22200_registers.hpp:528
constexpr uint32_t OCP_SHIFT
OCP bit shift (bits 31:24)
Definition max22200_registers.hpp:455
constexpr uint32_t DPM_SHIFT
DPM bit shift (bits 7:0)
Definition max22200_registers.hpp:461
constexpr uint32_t OLF_SHIFT
OLF bit shift (bits 15:8)
Definition max22200_registers.hpp:459
constexpr uint32_t HHF_SHIFT
HHF bit shift (bits 23:16)
Definition max22200_registers.hpp:457
constexpr uint32_t M_UVM_BIT
UVM fault mask.
Definition max22200_registers.hpp:245
constexpr uint32_t OVT_BIT
Overtemperature fault flag (read-only)
Definition max22200_registers.hpp:259
constexpr uint32_t M_OVT_BIT
OVT fault mask (1=masked, 0=signaled)
Definition max22200_registers.hpp:239
constexpr uint32_t CM32_SHIFT
CM32 bit shift (bits 11:10)
Definition max22200_registers.hpp:253
constexpr uint32_t M_DPM_BIT
DPM fault mask.
Definition max22200_registers.hpp:243
constexpr uint32_t CM54_SHIFT
CM54 bit shift (bits 13:12)
Definition max22200_registers.hpp:251
constexpr uint32_t HHF_BIT
HIT current not reached flag (read-only)
Definition max22200_registers.hpp:262
constexpr uint32_t M_HHF_BIT
HHF fault mask.
Definition max22200_registers.hpp:242
constexpr uint32_t OCP_BIT
Overcurrent fault flag (read-only)
Definition max22200_registers.hpp:260
constexpr uint32_t M_COMF_BIT
Communication fault mask (reset value = 1, masked by default)
Definition max22200_registers.hpp:244
constexpr uint32_t OLF_BIT
Open-load fault flag (read-only)
Definition max22200_registers.hpp:261
constexpr uint32_t CM76_SHIFT
CM76 bit shift (bits 15:14)
Definition max22200_registers.hpp:249
constexpr uint32_t M_OCP_BIT
OCP fault mask.
Definition max22200_registers.hpp:240
constexpr uint32_t ACTIVE_BIT
Global enable bit (write: 0=low-power, 1=normal operation)
Definition max22200_registers.hpp:268
constexpr uint32_t FREQM_BIT
Master frequency (0=100kHz, 1=80kHz)
Definition max22200_registers.hpp:246
constexpr uint32_t CM10_SHIFT
CM10 bit shift (bits 9:8)
Definition max22200_registers.hpp:255
constexpr uint32_t DPM_BIT
Plunger movement detection flag (read-only)
Definition max22200_registers.hpp:263
constexpr uint32_t UVM_BIT
Undervoltage flag (read-only, set at POR, cleared by read)
Definition max22200_registers.hpp:267
constexpr uint32_t COMER_BIT
Definition max22200_registers.hpp:264
constexpr uint32_t ONCH_SHIFT
ONCH bit shift (bits 31:24)
Definition max22200_registers.hpp:235
constexpr uint32_t M_OLF_BIT
OLF fault mask.
Definition max22200_registers.hpp:241
Definition max22200.hpp:78
uint8_t currentMaToRaw(uint32_t full_scale_current_ma, uint32_t ma)
Convert current in mA to 7-bit raw value (0–127) for CDR.
Definition max22200_types.hpp:257
const char * DriverStatusToStr(DriverStatus s)
Return a human-readable string for DriverStatus (for logging and tests)
Definition max22200_types.hpp:999
std::array< ChannelConfig, NUM_CHANNELS_ > ChannelConfigArray
Array type for channel configurations.
Definition max22200_types.hpp:1035
DriveMode
Drive mode enumeration (VDRnCDR bit in CFG_CHx[7])
Definition max22200_types.hpp:98
@ VDR
Voltage Drive Regulation (VDRnCDR = 1) — low-side or high-side.
@ CDR
Current Drive Regulation (VDRnCDR = 0) — low-side only.
ChannelMode
Channel-pair mode (CMxy bits in STATUS[15:8])
Definition max22200_types.hpp:159
@ HBRIDGE
Channels in H-bridge mode (CMxy = 10) — bidirectional drive.
@ INDEPENDENT
Channels independently controlled (CMxy = 00)
@ PARALLEL
Channels in parallel mode (CMxy = 01) — double current.
void(*)(uint8_t channel, FaultType fault_type, void *user_data) FaultCallback
Callback function type for fault events.
Definition max22200_types.hpp:1048
ChannelState
Logical channel state for application callbacks.
Definition max22200_types.hpp:1024
@ DISABLED
Channel OFF (ONCHx = 0)
@ HIT_PHASE
Application-defined: channel in HIT excitation window.
@ ENABLED
Channel ON, not necessarily in HIT or HOLD phase.
@ HOLD_PHASE
Application-defined: channel in HOLD regulation.
const char * FaultTypeToStr(FaultType ft)
Human-readable fault type name (for logging and tests)
Definition max22200_types.hpp:337
uint8_t dutyPercentToRaw(float percent)
Convert a VDR duty cycle in percent to the 7-bit HIT/HOLD field.
Definition max22200_types.hpp:273
SideMode
High-side / Low-side selection (HSnLS bit in CFG_CHx[6])
Definition max22200_types.hpp:123
@ HIGH_SIDE
High-side driver (HSnLS = 1) — VDR only, no CDR/HFS/SRC/DPM.
@ LOW_SIDE
Low-side driver (HSnLS = 0) — supports CDR and VDR.
uint8_t hitTimeMsToRaw(float ms, bool master_clock_80khz, ChopFreq cf)
Convert HIT time in ms to 8-bit raw value (0–255)
Definition max22200_types.hpp:296
DriverStatus
Driver operation result codes.
Definition max22200_types.hpp:985
@ TIMEOUT
Reserved for timed operations (not currently returned)
@ HARDWARE_FAULT
Reserved for hardware fault detection (not currently returned)
@ INITIALIZATION_ERROR
SPI/GPIO setup or ENABLE sequencing failed during init.
@ COMMUNICATION_ERROR
SPI transfer failed or COMER fault byte (0x04) detected.
@ OK
Operation completed successfully.
@ INVALID_PARAMETER
Channel index, IFS, or unit conversion argument out of range.
FullBridgeState
Full-bridge state for a channel pair (datasheet Table 7)
Definition max22200_types.hpp:973
@ Forward
ONCHx=1, ONCHy=0 — forward (control from CFG_CHy)
@ Reverse
ONCHx=0, ONCHy=1 — reverse (control from CFG_CHx)
@ Brake
ONCHx=1, ONCHy=1 — brake (both outputs driven to GND)
@ HiZ
ONCHx=0, ONCHy=0 — high impedance (both switches off)
uint32_t getChopFreqKhz(bool master_clock_80khz, ChopFreq cf)
Get chopping frequency in kHz for conversion (FREQM + FREQ_CFG)
Definition max22200_types.hpp:224
FaultType
Fault type enumeration.
Definition max22200_types.hpp:322
@ HHF
HIT current not reached (HHF)
@ OCP
Overcurrent protection (OCP)
@ UVM
Undervoltage lockout (UVM, from STATUS)
@ OVT
Overtemperature (OVT, from STATUS)
@ OLF
Open-load detection (OLF)
@ DPM
Detection of plunger movement (DPM)
@ COMER
Communication error (COMER, from STATUS)
void(*)(uint8_t channel, ChannelState old_state, ChannelState new_state, void *user_data) StateChangeCallback
Callback function type for channel state changes.
Definition max22200_types.hpp:1061
float getChopFreqKhzExact(bool master_clock_80khz, ChopFreq cf)
Exact chopping frequency in kHz (FREQM + FREQ_CFG, datasheet Table 1)
Definition max22200_types.hpp:240
float dutyRawToPercent(uint8_t raw)
Convert the 7-bit VDR HIT/HOLD field to a duty cycle in percent (datasheet Table 3)
Definition max22200_types.hpp:285
ChopFreq
Chopping frequency setting (FREQ_CFG bits in CFG_CHx[5:4])
Definition max22200_types.hpp:211
@ FMAIN_DIV2
FreqMain / 2 (fCHOP = 50kHz if FREQM=0, 40kHz if FREQM=1). With SRC=1 use only if FREQM=1 (40kHz).
@ FMAIN
FreqMain (fCHOP = 100kHz if FREQM=0, 80kHz if FREQM=1). Not valid with SRC=1.
@ FMAIN_DIV4
FreqMain / 4 (fCHOP = 25kHz if FREQM=0, 20kHz if FREQM=1). Valid with SRC=1.
@ FMAIN_DIV3
FreqMain / 3 (fCHOP = 33.33kHz if FREQM=0, 26.66kHz if FREQM=1). Valid with SRC=1.
constexpr uint8_t NUM_CHANNELS_
Number of channels on the MAX22200.
Definition max22200_registers.hpp:60
float getMaxHitTimeMs(bool master_clock_80khz, ChopFreq cf)
Maximum representable HIT time in ms for raw values 1–254 (255 = continuous).
Definition max22200_types.hpp:313
@ FAULT
nFAULT pin — active-low open-drain fault output (read via GpioRead)
Board/scale configuration for unit-based APIs.
Definition max22200_types.hpp:1089
uint32_t full_scale_current_ma
Full-scale current in mA (from RREF: IFS = KFS×1000/RREF)
Definition max22200_types.hpp:1090
BoardConfig()
Definition max22200_types.hpp:1094
BoardConfig(float rref_kohm, bool hfs)
Construct BoardConfig from RREF resistor value.
Definition max22200_types.hpp:1110
uint32_t max_current_ma
Max current limit in mA (0 = no limit, applies to all channels)
Definition max22200_types.hpp:1091
bool hasMaxCurrentLimit() const
True if a max current limit is configured (0 = no limit)
Definition max22200_types.hpp:1117
bool hasIfsConfigured() const
True if IFS is configured (non-zero)
Definition max22200_types.hpp:1121
uint8_t max_duty_percent
Max duty limit in percent (0 = no limit, applies to VDR mode)
Definition max22200_types.hpp:1092
bool hasMaxDutyLimit() const
True if a max duty limit is configured (0 = no limit)
Definition max22200_types.hpp:1119
uint32_t getMaxCurrentLimitMa() const
Max current limit in mA (0 = no limit)
Definition max22200_types.hpp:1125
uint32_t getFullScaleCurrentMa() const
Full-scale current in mA (IFS from RREF)
Definition max22200_types.hpp:1123
uint8_t getMaxDutyLimitPercent() const
Max duty limit in percent (0 = no limit)
Definition max22200_types.hpp:1127
Channel configuration structure.
Definition max22200_types.hpp:402
float hold_setpoint
HOLD setpoint: CDR = mA, VDR = duty % (0–100)
Definition max22200_types.hpp:407
bool isPlungerMovementDetectionEnabled() const
true when plunger movement detection (DPM_EN) is enabled
Definition max22200_types.hpp:637
void set_hold_ma(float ma)
Set HOLD setpoint in mA (CDR mode)
Definition max22200_types.hpp:474
bool isTriggeredByPin() const
true when channel is controlled via TRIGA/TRIGB pin (TRGnSPI = 1)
Definition max22200_types.hpp:629
float hold_duty_percent() const
HOLD duty cycle in percent (VDR); same storage as hold_setpoint.
Definition max22200_types.hpp:486
bool open_load_detection_enabled
Open-load detection enable.
Definition max22200_types.hpp:421
bool isCdr() const
true when drive_mode is CDR
Definition max22200_types.hpp:615
void fromRegister(uint32_t val, uint32_t board_ifs_ma, bool master_clock_80khz_param)
Parse a 32-bit register value into user units.
Definition max22200_types.hpp:566
float hold_ma() const
HOLD setpoint in mA (CDR) or percent (VDR)
Definition max22200_types.hpp:482
bool half_full_scale
Definition max22200_types.hpp:413
uint32_t toRegister(uint32_t board_ifs_ma=0, bool master_clock_80khz=false) const
Build 32-bit register value from user units.
Definition max22200_types.hpp:497
bool isSlewRateControlEnabled() const
true when SRC (slew rate control) is enabled
Definition max22200_types.hpp:633
static ChannelConfig makeSolenoidCdr(float hit_ma, float hold_ma, float hit_time_ms)
Preset: solenoid in CDR mode (low-side, currents in mA)
Definition max22200_types.hpp:442
bool trigger_from_pin
Definition max22200_types.hpp:415
float hit_ma() const
HIT setpoint in mA (CDR) or percent (VDR)
Definition max22200_types.hpp:480
void set_hit_duty_percent(float pct)
Set HIT duty cycle in percent (VDR mode, 0–100)
Definition max22200_types.hpp:476
bool hit_current_check_enabled
HIT current check enable (HHF fault if IHIT not reached)
Definition max22200_types.hpp:423
bool isHitCurrentCheckEnabled() const
true when HIT current check (HHF_EN) is enabled
Definition max22200_types.hpp:639
float hit_duty_percent() const
HIT duty cycle in percent (VDR); same storage as hit_setpoint.
Definition max22200_types.hpp:484
void set_hit_ma(float ma)
Set HIT setpoint in mA (CDR mode)
Definition max22200_types.hpp:472
float hit_time_ms
Definition max22200_types.hpp:408
bool hasHitTime() const
true when hit_time_ms > 0 (finite HIT window)
Definition max22200_types.hpp:623
SideMode side_mode
Side mode: LOW_SIDE (CDR/VDR) or HIGH_SIDE (VDR only)
Definition max22200_types.hpp:418
bool plunger_movement_detection_enabled
Plunger movement detection enable (low-side only)
Definition max22200_types.hpp:422
bool slew_rate_control_enabled
Slew rate control enable; reduces EMI; fCHOP < 50 kHz.
Definition max22200_types.hpp:420
bool isTriggeredBySpi() const
true when channel is controlled via SPI ONCH (TRGnSPI = 0)
Definition max22200_types.hpp:627
bool isVdr() const
true when drive_mode is VDR
Definition max22200_types.hpp:617
bool isHalfFullScale() const
true when HFS bit is set (half full-scale, low-side only)
Definition max22200_types.hpp:631
bool isHighSide() const
true when side_mode is HIGH_SIDE
Definition max22200_types.hpp:621
bool isLowSide() const
true when side_mode is LOW_SIDE
Definition max22200_types.hpp:619
ChopFreq getChopFreq() const
Chopping frequency config (FREQ_CFG); see ChopFreq enum.
Definition max22200_types.hpp:641
DriveMode drive_mode
Drive mode: CDR (current) or VDR (voltage)
Definition max22200_types.hpp:417
ChannelConfig()
Default constructor — safe defaults.
Definition max22200_types.hpp:428
float hit_setpoint
HIT setpoint: CDR = mA, VDR = duty % (0–100)
Definition max22200_types.hpp:406
ChopFreq chop_freq
Chopping frequency divider (FREQ_CFG[1:0])
Definition max22200_types.hpp:419
bool isOpenLoadDetectionEnabled() const
true when open-load detection (OL_EN) is enabled
Definition max22200_types.hpp:635
bool isContinuousHit() const
true when hit_time_ms indicates continuous HIT (negative or very large)
Definition max22200_types.hpp:625
void set_hold_duty_percent(float pct)
Set HOLD duty cycle in percent (VDR mode, 0–100)
Definition max22200_types.hpp:478
static ChannelConfig makeSolenoidVdr(float hit_pct, float hold_pct, float hit_time_ms)
Preset: solenoid in VDR mode (low-side, duty percent)
Definition max22200_types.hpp:459
DPM (Detection of Plunger Movement) algorithm configuration.
Definition max22200_types.hpp:940
uint8_t getPlungerMovementCurrentThreshold() const
Definition max22200_types.hpp:964
uint8_t getPlungerMovementStartCurrent() const
Definition max22200_types.hpp:962
uint8_t plunger_movement_start_current
DPM_ISTART (0-127) — starting current for dip search.
Definition max22200_types.hpp:941
uint32_t toRegister() const
Encode writable CFG_DPM fields to a 32-bit register value.
Definition max22200_types.hpp:949
uint8_t plunger_movement_debounce_time
DPM_TDEB (0-15) — min dip duration in chopping periods.
Definition max22200_types.hpp:942
uint8_t plunger_movement_current_threshold
DPM_IPTH (0-15) — min dip amplitude threshold.
Definition max22200_types.hpp:943
uint8_t getPlungerMovementDebounceTime() const
Definition max22200_types.hpp:963
void fromRegister(uint32_t val)
Parse a 32-bit CFG_DPM register value.
Definition max22200_types.hpp:956
DpmConfig()
Definition max22200_types.hpp:945
Driver runtime statistics.
Definition max22200_types.hpp:1165
DriverStatistics()
Definition max22200_types.hpp:1172
float getSuccessRate() const
Definition max22200_types.hpp:1176
uint32_t fault_events
Reserved (not incremented by current driver)
Definition max22200_types.hpp:1168
uint32_t total_transfers
Total SPI operations attempted.
Definition max22200_types.hpp:1166
uint32_t getFailedTransfers() const
Failed SPI or validation operations.
Definition max22200_types.hpp:1188
bool hasFailures() const
true if failed_transfers > 0
Definition max22200_types.hpp:1182
uint32_t state_changes
Reserved (not incremented by current driver)
Definition max22200_types.hpp:1169
uint32_t uptime_ms
Reserved (not incremented by current driver)
Definition max22200_types.hpp:1170
uint32_t getUptimeMs() const
Uptime counter in ms (reserved, always 0 in current driver)
Definition max22200_types.hpp:1194
uint32_t failed_transfers
SPI or parameter failures counted by updateStatistics()
Definition max22200_types.hpp:1167
uint32_t getFaultEvents() const
Fault event counter (reserved, always 0 in current driver)
Definition max22200_types.hpp:1190
bool isHealthy() const
true if failed_transfers == 0
Definition max22200_types.hpp:1184
uint32_t getTotalTransfers() const
Total SPI transfer attempts.
Definition max22200_types.hpp:1186
uint32_t getStateChanges() const
State change counter (reserved, always 0 in current driver)
Definition max22200_types.hpp:1192
Duty cycle limits (δMIN, δMAX) for a given configuration.
Definition max22200_types.hpp:1136
uint8_t max_percent
Maximum duty cycle in percent (δMAX)
Definition max22200_types.hpp:1138
uint8_t getMaxPercent() const
Maximum duty cycle in percent (δMAX)
Definition max22200_types.hpp:1145
uint8_t getMinPercent() const
Minimum duty cycle in percent (δMIN)
Definition max22200_types.hpp:1143
DutyLimits()
Definition max22200_types.hpp:1140
bool inRange(float percent) const
True if percent is within [min_percent, max_percent].
Definition max22200_types.hpp:1147
uint8_t min_percent
Minimum duty cycle in percent (δMIN)
Definition max22200_types.hpp:1137
float clamp(float percent) const
Clamp percent to [min_percent, max_percent].
Definition max22200_types.hpp:1151
Per-channel fault information from FAULT register (0x09)
Definition max22200_types.hpp:859
bool hasOpenLoadFaultOnChannel(uint8_t ch) const
Definition max22200_types.hpp:917
uint8_t overcurrent_channel_mask
OCP per-channel bitmask (bit N = channel N)
Definition max22200_types.hpp:860
bool hasOvercurrent() const
Definition max22200_types.hpp:903
bool hasPlungerMovementFaultOnChannel(uint8_t ch) const
Definition max22200_types.hpp:920
bool hasPlungerMovementFault() const
Definition max22200_types.hpp:906
FaultStatus()
Definition max22200_types.hpp:865
bool hasOpenLoadFault() const
Definition max22200_types.hpp:905
bool hasOvercurrentOnChannel(uint8_t ch) const
Definition max22200_types.hpp:911
bool hasHitNotReached() const
Definition max22200_types.hpp:904
bool hasFault() const
Check if any per-channel fault is active.
Definition max22200_types.hpp:882
uint8_t plunger_movement_fault_channel_mask
DPM per-channel bitmask (bit N = channel N)
Definition max22200_types.hpp:863
void fromRegister(uint32_t val)
Parse a 32-bit FAULT register value into per-channel bitmasks.
Definition max22200_types.hpp:872
uint8_t channelsWithAnyFault() const
Definition max22200_types.hpp:923
uint8_t getFaultCount() const
Count total per-channel faults.
Definition max22200_types.hpp:890
uint8_t open_load_fault_channel_mask
OLF per-channel bitmask (bit N = channel N)
Definition max22200_types.hpp:862
bool hasHitNotReachedOnChannel(uint8_t ch) const
Definition max22200_types.hpp:914
bool hasFaultOnChannel(uint8_t ch) const
Definition max22200_types.hpp:907
uint8_t hit_not_reached_channel_mask
HHF per-channel bitmask (bit N = channel N)
Definition max22200_types.hpp:861
STATUS register structure.
Definition max22200_types.hpp:683
ChannelMode getChannelPairMode54() const
Definition max22200_types.hpp:826
bool hasPlungerMovementFault() const
Definition max22200_types.hpp:799
ChannelMode getChannelPairMode76() const
Definition max22200_types.hpp:825
bool hit_not_reached_masked
HHF fault mask; when true HHF does not assert FAULT pin.
Definition max22200_types.hpp:693
ChannelMode channel_pair_mode_10
CH0/CH1 pair mode.
Definition max22200_types.hpp:703
bool open_load_fault
OLF fault flag (read-only); load disconnected if OL enabled.
Definition max22200_types.hpp:711
bool hasUndervoltage() const
Definition max22200_types.hpp:801
bool hit_not_reached
HHF fault flag (read-only); IHIT not reached by end of tHIT.
Definition max22200_types.hpp:712
void fromRegister(uint32_t val)
Parse a 32-bit STATUS register value into this structure.
Definition max22200_types.hpp:760
bool hasOvercurrent() const
Definition max22200_types.hpp:796
bool overcurrent
OCP fault flag (read-only); output exceeded OCP level.
Definition max22200_types.hpp:710
bool is80KHzBase() const
Definition max22200_types.hpp:822
bool isOvertemperatureMasked() const
Definition max22200_types.hpp:814
bool isChannelOn(uint8_t ch) const
Definition max22200_types.hpp:803
ChannelMode channel_pair_mode_76
CH6/CH7 pair mode; change only when both CH6 and CH7 are OFF.
Definition max22200_types.hpp:700
bool isOvercurrentMasked() const
Definition max22200_types.hpp:815
bool is100KHzBase() const
Definition max22200_types.hpp:823
bool isHitNotReachedMasked() const
Definition max22200_types.hpp:817
uint8_t getChannelsOnMask() const
Definition max22200_types.hpp:829
ChannelMode getChannelPairMode32() const
Definition max22200_types.hpp:827
bool hasHitNotReached() const
Definition max22200_types.hpp:798
uint8_t channelCountOn() const
Definition max22200_types.hpp:806
bool master_clock_80khz
Master clock base (false=100kHz, true=80kHz); affects fCHOP.
Definition max22200_types.hpp:697
bool hasOvertemperature() const
Definition max22200_types.hpp:795
bool open_load_fault_masked
OLF fault mask; when true OLF does not assert FAULT pin.
Definition max22200_types.hpp:692
bool undervoltage_masked
UVM fault mask; when true UVM does not assert FAULT pin.
Definition max22200_types.hpp:696
bool communication_error
COMER flag (read-only); SPI error detected.
Definition max22200_types.hpp:714
bool communication_error_masked
COMER mask (default=true); when true COMER does not assert FAULT pin.
Definition max22200_types.hpp:695
bool isUndervoltageMasked() const
Definition max22200_types.hpp:820
bool hasOpenLoadFault() const
Definition max22200_types.hpp:797
bool overcurrent_masked
OCP fault mask; when true OCP does not assert FAULT pin.
Definition max22200_types.hpp:691
bool undervoltage
UVM fault flag (read-only); clear by reading STATUS at init.
Definition max22200_types.hpp:715
bool isActive() const
Definition max22200_types.hpp:802
bool hasCommunicationError() const
Definition max22200_types.hpp:800
bool overtemperature
OVT fault flag (read-only); die over temp.
Definition max22200_types.hpp:709
ChannelMode channel_pair_mode_54
CH4/CH5 pair mode.
Definition max22200_types.hpp:701
ChannelMode channel_pair_mode_32
CH2/CH3 pair mode.
Definition max22200_types.hpp:702
bool overtemperature_masked
OVT fault mask; when true OVT does not assert FAULT pin.
Definition max22200_types.hpp:690
bool isCommunicationErrorMasked() const
Definition max22200_types.hpp:819
uint8_t channels_on_mask
Definition max22200_types.hpp:685
bool plunger_movement_fault
DPM fault flag (read-only); no valid plunger movement.
Definition max22200_types.hpp:713
bool isOpenLoadFaultMasked() const
Definition max22200_types.hpp:816
uint32_t toRegister() const
Build 32-bit STATUS register value from writable fields.
Definition max22200_types.hpp:737
bool isPlungerMovementFaultMasked() const
Definition max22200_types.hpp:818
ChannelMode getChannelPairMode10() const
Definition max22200_types.hpp:828
bool active
Global enable (0=low-power, 1=normal); set to 1 during init.
Definition max22200_types.hpp:706
bool plunger_movement_fault_masked
DPM fault mask; when true DPM does not assert FAULT pin.
Definition max22200_types.hpp:694
StatusConfig()
Default constructor.
Definition max22200_types.hpp:720
bool hasFault() const
Check if any global fault flag in byte 0 is active.
Definition max22200_types.hpp:788