1#![no_std]
2
3pub mod commands;
4pub mod error;
5pub mod formats;
6pub mod status;
7pub mod vout_mode;
8
9use embedded_hal_async::i2c::I2c;
10use heapless::Vec;
11use smbus_adapter::SmbusAdaptor;
12
13pub use commands::CommandCode;
14pub use error::PmbusError;
15pub use formats::{DirectCoefficients, Linear11, ULinear16};
16pub use status::*;
17pub use vout_mode::{VoutMode, VoutModeType};
18
19macro_rules! pmbus_send_byte {
25 ($name:ident, $cmd:ident) => {
26 pub async fn $name(&mut self, addr: u8) -> Result<(), BUS::Error> {
27 self.send_cmd(addr, CommandCode::$cmd).await
28 }
29 };
30}
31
32macro_rules! pmbus_byte_rw {
34 ($set:ident, $get:ident, $cmd:ident) => {
35 pub async fn $set(&mut self, addr: u8, data: u8) -> Result<(), BUS::Error> {
36 self.write_cmd_byte(addr, CommandCode::$cmd, data).await
37 }
38 pub async fn $get(&mut self, addr: u8) -> Result<u8, BUS::Error> {
39 self.read_cmd_byte(addr, CommandCode::$cmd).await
40 }
41 };
42}
43
44macro_rules! pmbus_write_byte_only {
46 ($name:ident, $cmd:ident) => {
47 pub async fn $name(&mut self, addr: u8, data: u8) -> Result<(), BUS::Error> {
48 self.write_cmd_byte(addr, CommandCode::$cmd, data).await
49 }
50 };
51}
52
53macro_rules! pmbus_read_byte_only {
55 ($name:ident, $cmd:ident) => {
56 pub async fn $name(&mut self, addr: u8) -> Result<u8, BUS::Error> {
57 self.read_cmd_byte(addr, CommandCode::$cmd).await
58 }
59 };
60}
61
62macro_rules! pmbus_word_rw {
64 ($set:ident, $get:ident, $cmd:ident) => {
65 pub async fn $set(&mut self, addr: u8, data: u16) -> Result<(), BUS::Error> {
66 self.write_cmd_word(addr, CommandCode::$cmd, data).await
67 }
68 pub async fn $get(&mut self, addr: u8) -> Result<u16, BUS::Error> {
69 self.read_cmd_word(addr, CommandCode::$cmd).await
70 }
71 };
72}
73
74macro_rules! pmbus_read_word_only {
76 ($name:ident, $cmd:ident) => {
77 pub async fn $name(&mut self, addr: u8) -> Result<u16, BUS::Error> {
78 self.read_cmd_word(addr, CommandCode::$cmd).await
79 }
80 };
81}
82
83macro_rules! pmbus_block_rw {
85 ($set:ident, $get:ident, $cmd:ident) => {
86 pub async fn $set(&mut self, addr: u8, data: &[u8]) -> Result<(), BUS::Error> {
87 self.block_write_cmd(addr, CommandCode::$cmd, data).await
88 }
89 pub async fn $get(&mut self, addr: u8) -> Result<Vec<u8, 32>, BUS::Error> {
90 self.block_read_cmd(addr, CommandCode::$cmd).await
91 }
92 };
93}
94
95macro_rules! pmbus_block_read_only {
97 ($name:ident, $cmd:ident) => {
98 pub async fn $name(&mut self, addr: u8) -> Result<Vec<u8, 32>, BUS::Error> {
99 self.block_read_cmd(addr, CommandCode::$cmd).await
100 }
101 };
102}
103
104pub struct PmbusAdaptor<BUS: I2c> {
113 smbus: SmbusAdaptor<BUS>,
114}
115
116impl<BUS: I2c + 'static> PmbusAdaptor<BUS> {
117 pub fn new(smbus: SmbusAdaptor<BUS>) -> Self {
119 Self { smbus }
120 }
121
122 pub fn release(self) -> SmbusAdaptor<BUS> {
124 self.smbus
125 }
126
127 pub fn inner(&mut self) -> &mut SmbusAdaptor<BUS> {
129 &mut self.smbus
130 }
131
132 async fn send_cmd(&mut self, addr: u8, cmd: CommandCode) -> Result<(), BUS::Error> {
137 self.smbus.send_byte(addr, cmd.code()).await
138 }
139
140 async fn write_cmd_byte(
141 &mut self,
142 addr: u8,
143 cmd: CommandCode,
144 data: u8,
145 ) -> Result<(), BUS::Error> {
146 self.smbus.write_byte(addr, cmd.code(), data).await
147 }
148
149 async fn read_cmd_byte(&mut self, addr: u8, cmd: CommandCode) -> Result<u8, BUS::Error> {
150 self.smbus.read_byte(addr, cmd.code()).await
151 }
152
153 async fn write_cmd_word(
154 &mut self,
155 addr: u8,
156 cmd: CommandCode,
157 data: u16,
158 ) -> Result<(), BUS::Error> {
159 self.smbus.write_word(addr, cmd.code(), data).await
160 }
161
162 async fn read_cmd_word(&mut self, addr: u8, cmd: CommandCode) -> Result<u16, BUS::Error> {
163 self.smbus.read_word(addr, cmd.code()).await
164 }
165
166 async fn block_write_cmd(
167 &mut self,
168 addr: u8,
169 cmd: CommandCode,
170 data: &[u8],
171 ) -> Result<(), BUS::Error> {
172 self.smbus.block_write(addr, cmd.code(), data).await
173 }
174
175 async fn block_read_cmd(
176 &mut self,
177 addr: u8,
178 cmd: CommandCode,
179 ) -> Result<Vec<u8, 32>, BUS::Error> {
180 self.smbus.block_read(addr, cmd.code()).await
181 }
182
183 async fn block_process_call_cmd(
184 &mut self,
185 addr: u8,
186 cmd: CommandCode,
187 data: &[u8],
188 ) -> Result<Vec<u8, 32>, BUS::Error> {
189 self.smbus
190 .block_read_process_call(addr, cmd.code(), data)
191 .await
192 }
193
194 pmbus_send_byte!(clear_faults, ClearFaults);
199 pmbus_send_byte!(store_default_all, StoreDefaultAll);
200 pmbus_send_byte!(restore_default_all, RestoreDefaultAll);
201 pmbus_send_byte!(store_user_all, StoreUserAll);
202 pmbus_send_byte!(restore_user_all, RestoreUserAll);
203
204 pmbus_byte_rw!(set_page, get_page, Page);
209 pmbus_byte_rw!(set_operation, get_operation, Operation);
210 pmbus_byte_rw!(set_on_off_config, get_on_off_config, OnOffConfig);
211 pmbus_byte_rw!(set_phase, get_phase, Phase);
212 pmbus_byte_rw!(set_write_protect, get_write_protect, WriteProtect);
213 pmbus_byte_rw!(set_power_mode, get_power_mode, PowerMode);
214 pmbus_byte_rw!(set_fan_config_12, get_fan_config_12, FanConfig12);
215 pmbus_byte_rw!(set_fan_config_34, get_fan_config_34, FanConfig34);
216
217 pmbus_byte_rw!(
219 set_vout_ov_fault_response,
220 get_vout_ov_fault_response,
221 VoutOvFaultResponse
222 );
223 pmbus_byte_rw!(
224 set_vout_uv_fault_response,
225 get_vout_uv_fault_response,
226 VoutUvFaultResponse
227 );
228 pmbus_byte_rw!(
229 set_iout_oc_fault_response,
230 get_iout_oc_fault_response,
231 IoutOcFaultResponse
232 );
233 pmbus_byte_rw!(
234 set_iout_oc_lv_fault_response,
235 get_iout_oc_lv_fault_response,
236 IoutOcLvFaultResponse
237 );
238 pmbus_byte_rw!(
239 set_iout_uc_fault_response,
240 get_iout_uc_fault_response,
241 IoutUcFaultResponse
242 );
243 pmbus_byte_rw!(
244 set_ot_fault_response,
245 get_ot_fault_response,
246 OtFaultResponse
247 );
248 pmbus_byte_rw!(
249 set_ut_fault_response,
250 get_ut_fault_response,
251 UtFaultResponse
252 );
253 pmbus_byte_rw!(
254 set_vin_ov_fault_response,
255 get_vin_ov_fault_response,
256 VinOvFaultResponse
257 );
258 pmbus_byte_rw!(
259 set_vin_uv_fault_response,
260 get_vin_uv_fault_response,
261 VinUvFaultResponse
262 );
263 pmbus_byte_rw!(
264 set_iin_oc_fault_response,
265 get_iin_oc_fault_response,
266 IinOcFaultResponse
267 );
268 pmbus_byte_rw!(
269 set_ton_max_fault_response,
270 get_ton_max_fault_response,
271 TonMaxFaultResponse
272 );
273 pmbus_byte_rw!(
274 set_pout_op_fault_response,
275 get_pout_op_fault_response,
276 PoutOpFaultResponse
277 );
278
279 pmbus_write_byte_only!(store_default_code, StoreDefaultCode);
281 pmbus_write_byte_only!(restore_default_code, RestoreDefaultCode);
282 pmbus_write_byte_only!(store_user_code, StoreUserCode);
283 pmbus_write_byte_only!(restore_user_code, RestoreUserCode);
284
285 pmbus_read_byte_only!(get_capability, Capability);
287 pmbus_read_byte_only!(get_pmbus_revision, PmbusRevision);
288 pmbus_read_byte_only!(get_mfr_pin_accuracy, MfrPinAccuracy);
289
290 pmbus_word_rw!(set_vout_command, get_vout_command, VoutCommand);
296 pmbus_word_rw!(set_vout_trim, get_vout_trim, VoutTrim);
297 pmbus_word_rw!(set_vout_cal_offset, get_vout_cal_offset, VoutCalOffset);
298 pmbus_word_rw!(set_vout_max, get_vout_max, VoutMax);
299 pmbus_word_rw!(set_vout_margin_high, get_vout_margin_high, VoutMarginHigh);
300 pmbus_word_rw!(set_vout_margin_low, get_vout_margin_low, VoutMarginLow);
301 pmbus_word_rw!(
302 set_vout_transition_rate,
303 get_vout_transition_rate,
304 VoutTransitionRate
305 );
306 pmbus_word_rw!(set_vout_droop, get_vout_droop, VoutDroop);
307 pmbus_word_rw!(set_vout_scale_loop, get_vout_scale_loop, VoutScaleLoop);
308 pmbus_word_rw!(
309 set_vout_scale_monitor,
310 get_vout_scale_monitor,
311 VoutScaleMonitor
312 );
313 pmbus_word_rw!(set_vout_min, get_vout_min, VoutMin);
314
315 pmbus_word_rw!(set_pout_max, get_pout_max, PoutMax);
317 pmbus_word_rw!(set_max_duty, get_max_duty, MaxDuty);
318 pmbus_word_rw!(set_frequency_switch, get_frequency_switch, FrequencySwitch);
319 pmbus_word_rw!(set_vin_on, get_vin_on, VinOn);
320 pmbus_word_rw!(set_vin_off, get_vin_off, VinOff);
321 pmbus_word_rw!(set_interleave, get_interleave, Interleave);
322 pmbus_word_rw!(set_iout_cal_gain, get_iout_cal_gain, IoutCalGain);
323 pmbus_word_rw!(set_iout_cal_offset, get_iout_cal_offset, IoutCalOffset);
324
325 pmbus_word_rw!(set_fan_command_1, get_fan_command_1, FanCommand1);
327 pmbus_word_rw!(set_fan_command_2, get_fan_command_2, FanCommand2);
328 pmbus_word_rw!(set_fan_command_3, get_fan_command_3, FanCommand3);
329 pmbus_word_rw!(set_fan_command_4, get_fan_command_4, FanCommand4);
330
331 pmbus_word_rw!(
333 set_vout_ov_fault_limit,
334 get_vout_ov_fault_limit,
335 VoutOvFaultLimit
336 );
337 pmbus_word_rw!(
338 set_vout_ov_warn_limit,
339 get_vout_ov_warn_limit,
340 VoutOvWarnLimit
341 );
342 pmbus_word_rw!(
343 set_vout_uv_warn_limit,
344 get_vout_uv_warn_limit,
345 VoutUvWarnLimit
346 );
347 pmbus_word_rw!(
348 set_vout_uv_fault_limit,
349 get_vout_uv_fault_limit,
350 VoutUvFaultLimit
351 );
352 pmbus_word_rw!(
353 set_iout_oc_fault_limit,
354 get_iout_oc_fault_limit,
355 IoutOcFaultLimit
356 );
357 pmbus_word_rw!(
358 set_iout_oc_lv_fault_limit,
359 get_iout_oc_lv_fault_limit,
360 IoutOcLvFaultLimit
361 );
362 pmbus_word_rw!(
363 set_iout_oc_warn_limit,
364 get_iout_oc_warn_limit,
365 IoutOcWarnLimit
366 );
367 pmbus_word_rw!(
368 set_iout_uc_fault_limit,
369 get_iout_uc_fault_limit,
370 IoutUcFaultLimit
371 );
372 pmbus_word_rw!(set_ot_fault_limit, get_ot_fault_limit, OtFaultLimit);
373 pmbus_word_rw!(set_ot_warn_limit, get_ot_warn_limit, OtWarnLimit);
374 pmbus_word_rw!(set_ut_warn_limit, get_ut_warn_limit, UtWarnLimit);
375 pmbus_word_rw!(set_ut_fault_limit, get_ut_fault_limit, UtFaultLimit);
376 pmbus_word_rw!(
377 set_vin_ov_fault_limit,
378 get_vin_ov_fault_limit,
379 VinOvFaultLimit
380 );
381 pmbus_word_rw!(set_vin_ov_warn_limit, get_vin_ov_warn_limit, VinOvWarnLimit);
382 pmbus_word_rw!(set_vin_uv_warn_limit, get_vin_uv_warn_limit, VinUvWarnLimit);
383 pmbus_word_rw!(
384 set_vin_uv_fault_limit,
385 get_vin_uv_fault_limit,
386 VinUvFaultLimit
387 );
388 pmbus_word_rw!(
389 set_iin_oc_fault_limit,
390 get_iin_oc_fault_limit,
391 IinOcFaultLimit
392 );
393 pmbus_word_rw!(set_iin_oc_warn_limit, get_iin_oc_warn_limit, IinOcWarnLimit);
394 pmbus_word_rw!(set_power_good_on, get_power_good_on, PowerGoodOn);
395 pmbus_word_rw!(set_power_good_off, get_power_good_off, PowerGoodOff);
396 pmbus_word_rw!(set_ton_delay, get_ton_delay, TonDelay);
397 pmbus_word_rw!(set_ton_rise, get_ton_rise, TonRise);
398 pmbus_word_rw!(
399 set_ton_max_fault_limit,
400 get_ton_max_fault_limit,
401 TonMaxFaultLimit
402 );
403 pmbus_word_rw!(set_toff_delay, get_toff_delay, ToffDelay);
404 pmbus_word_rw!(set_toff_fall, get_toff_fall, ToffFall);
405 pmbus_word_rw!(
406 set_toff_max_warn_limit,
407 get_toff_max_warn_limit,
408 ToffMaxWarnLimit
409 );
410 pmbus_word_rw!(
411 set_pout_op_fault_limit,
412 get_pout_op_fault_limit,
413 PoutOpFaultLimit
414 );
415 pmbus_word_rw!(
416 set_pout_op_warn_limit,
417 get_pout_op_warn_limit,
418 PoutOpWarnLimit
419 );
420 pmbus_word_rw!(set_pin_op_warn_limit, get_pin_op_warn_limit, PinOpWarnLimit);
421
422 pmbus_word_rw!(set_zone_config, get_zone_config, ZoneConfig);
424 pmbus_word_rw!(set_zone_active, get_zone_active, ZoneActive);
425 pmbus_word_rw!(set_read_kwh_config, get_read_kwh_config, ReadKwhConfig);
426
427 pmbus_word_rw!(set_mfr_vin_min, get_mfr_vin_min, MfrVinMin);
429 pmbus_word_rw!(set_mfr_vin_max, get_mfr_vin_max, MfrVinMax);
430 pmbus_word_rw!(set_mfr_iin_max, get_mfr_iin_max, MfrIinMax);
431 pmbus_word_rw!(set_mfr_pin_max, get_mfr_pin_max, MfrPinMax);
432 pmbus_word_rw!(set_mfr_vout_min, get_mfr_vout_min, MfrVoutMin);
433 pmbus_word_rw!(set_mfr_vout_max, get_mfr_vout_max, MfrVoutMax);
434 pmbus_word_rw!(set_mfr_iout_max, get_mfr_iout_max, MfrIoutMax);
435 pmbus_word_rw!(set_mfr_pout_max, get_mfr_pout_max, MfrPoutMax);
436 pmbus_word_rw!(set_mfr_tambient_max, get_mfr_tambient_max, MfrTambientMax);
437 pmbus_word_rw!(set_mfr_tambient_min, get_mfr_tambient_min, MfrTambientMin);
438 pmbus_word_rw!(set_mfr_max_temp_1, get_mfr_max_temp_1, MfrMaxTemp1);
439 pmbus_word_rw!(set_mfr_max_temp_2, get_mfr_max_temp_2, MfrMaxTemp2);
440 pmbus_word_rw!(set_mfr_max_temp_3, get_mfr_max_temp_3, MfrMaxTemp3);
441
442 pmbus_read_word_only!(read_vin, ReadVin);
447 pmbus_read_word_only!(read_iin, ReadIin);
448 pmbus_read_word_only!(read_vcap, ReadVcap);
449 pmbus_read_word_only!(read_vout, ReadVout);
450 pmbus_read_word_only!(read_iout, ReadIout);
451 pmbus_read_word_only!(read_temperature_1, ReadTemperature1);
452 pmbus_read_word_only!(read_temperature_2, ReadTemperature2);
453 pmbus_read_word_only!(read_temperature_3, ReadTemperature3);
454 pmbus_read_word_only!(read_fan_speed_1, ReadFanSpeed1);
455 pmbus_read_word_only!(read_fan_speed_2, ReadFanSpeed2);
456 pmbus_read_word_only!(read_fan_speed_3, ReadFanSpeed3);
457 pmbus_read_word_only!(read_fan_speed_4, ReadFanSpeed4);
458 pmbus_read_word_only!(read_duty_cycle, ReadDutyCycle);
459 pmbus_read_word_only!(read_frequency, ReadFrequency);
460 pmbus_read_word_only!(read_pout, ReadPout);
461 pmbus_read_word_only!(read_pin, ReadPin);
462
463 pmbus_block_rw!(set_mfr_id, get_mfr_id, MfrId);
468 pmbus_block_rw!(set_mfr_model, get_mfr_model, MfrModel);
469 pmbus_block_rw!(set_mfr_revision, get_mfr_revision, MfrRevision);
470 pmbus_block_rw!(set_mfr_location, get_mfr_location, MfrLocation);
471 pmbus_block_rw!(set_mfr_date, get_mfr_date, MfrDate);
472 pmbus_block_rw!(set_mfr_serial, get_mfr_serial, MfrSerial);
473 pmbus_block_read_only!(get_app_profile_support, AppProfileSupport);
474 pmbus_block_read_only!(get_ic_device_id, IcDeviceId);
475 pmbus_block_read_only!(get_ic_device_rev, IcDeviceRev);
476 pmbus_block_read_only!(get_mfr_efficiency_ll, MfrEfficiencyLl);
477 pmbus_block_read_only!(get_mfr_efficiency_hl, MfrEfficiencyHl);
478 pmbus_block_read_only!(read_ein, ReadEin);
479 pmbus_block_read_only!(read_eout, ReadEout);
480
481 pub async fn set_user_data(
487 &mut self,
488 addr: u8,
489 index: u8,
490 data: &[u8],
491 ) -> Result<(), BUS::Error> {
492 let code = CommandCode::UserData00.code() + (index & 0x0F);
493 self.smbus.block_write(addr, code, data).await
494 }
495
496 pub async fn get_user_data(&mut self, addr: u8, index: u8) -> Result<Vec<u8, 32>, BUS::Error> {
498 let code = CommandCode::UserData00.code() + (index & 0x0F);
499 self.smbus.block_read(addr, code).await
500 }
501
502 pub async fn get_status_byte(&mut self, addr: u8) -> Result<StatusByte, BUS::Error> {
508 let raw = self.read_cmd_byte(addr, CommandCode::StatusByte).await?;
509 Ok(StatusByte::from_raw(raw))
510 }
511
512 pub async fn set_status_byte(
514 &mut self,
515 addr: u8,
516 status: StatusByte,
517 ) -> Result<(), BUS::Error> {
518 self.write_cmd_byte(addr, CommandCode::StatusByte, status.bits())
519 .await
520 }
521
522 pub async fn get_status_word(&mut self, addr: u8) -> Result<StatusWord, BUS::Error> {
524 let raw = self.read_cmd_word(addr, CommandCode::StatusWord).await?;
525 Ok(StatusWord::from_raw(raw))
526 }
527
528 pub async fn set_status_word(
530 &mut self,
531 addr: u8,
532 status: StatusWord,
533 ) -> Result<(), BUS::Error> {
534 self.write_cmd_word(addr, CommandCode::StatusWord, status.bits())
535 .await
536 }
537
538 pub async fn get_status_vout(&mut self, addr: u8) -> Result<StatusVout, BUS::Error> {
540 let raw = self.read_cmd_byte(addr, CommandCode::StatusVout).await?;
541 Ok(StatusVout::from_raw(raw))
542 }
543
544 pub async fn set_status_vout(
546 &mut self,
547 addr: u8,
548 status: StatusVout,
549 ) -> Result<(), BUS::Error> {
550 self.write_cmd_byte(addr, CommandCode::StatusVout, status.bits())
551 .await
552 }
553
554 pub async fn get_status_iout(&mut self, addr: u8) -> Result<StatusIout, BUS::Error> {
556 let raw = self.read_cmd_byte(addr, CommandCode::StatusIout).await?;
557 Ok(StatusIout::from_raw(raw))
558 }
559
560 pub async fn set_status_iout(
562 &mut self,
563 addr: u8,
564 status: StatusIout,
565 ) -> Result<(), BUS::Error> {
566 self.write_cmd_byte(addr, CommandCode::StatusIout, status.bits())
567 .await
568 }
569
570 pub async fn get_status_input(&mut self, addr: u8) -> Result<StatusInput, BUS::Error> {
572 let raw = self.read_cmd_byte(addr, CommandCode::StatusInput).await?;
573 Ok(StatusInput::from_raw(raw))
574 }
575
576 pub async fn set_status_input(
578 &mut self,
579 addr: u8,
580 status: StatusInput,
581 ) -> Result<(), BUS::Error> {
582 self.write_cmd_byte(addr, CommandCode::StatusInput, status.bits())
583 .await
584 }
585
586 pub async fn get_status_temperature(
588 &mut self,
589 addr: u8,
590 ) -> Result<StatusTemperature, BUS::Error> {
591 let raw = self
592 .read_cmd_byte(addr, CommandCode::StatusTemperature)
593 .await?;
594 Ok(StatusTemperature::from_raw(raw))
595 }
596
597 pub async fn set_status_temperature(
599 &mut self,
600 addr: u8,
601 status: StatusTemperature,
602 ) -> Result<(), BUS::Error> {
603 self.write_cmd_byte(addr, CommandCode::StatusTemperature, status.bits())
604 .await
605 }
606
607 pub async fn get_status_cml(&mut self, addr: u8) -> Result<StatusCml, BUS::Error> {
609 let raw = self.read_cmd_byte(addr, CommandCode::StatusCml).await?;
610 Ok(StatusCml::from_raw(raw))
611 }
612
613 pub async fn set_status_cml(&mut self, addr: u8, status: StatusCml) -> Result<(), BUS::Error> {
615 self.write_cmd_byte(addr, CommandCode::StatusCml, status.bits())
616 .await
617 }
618
619 pub async fn get_status_other(&mut self, addr: u8) -> Result<StatusOther, BUS::Error> {
621 let raw = self.read_cmd_byte(addr, CommandCode::StatusOther).await?;
622 Ok(StatusOther::from_raw(raw))
623 }
624
625 pub async fn set_status_other(
627 &mut self,
628 addr: u8,
629 status: StatusOther,
630 ) -> Result<(), BUS::Error> {
631 self.write_cmd_byte(addr, CommandCode::StatusOther, status.bits())
632 .await
633 }
634
635 pub async fn get_status_mfr_specific(&mut self, addr: u8) -> Result<u8, BUS::Error> {
637 self.read_cmd_byte(addr, CommandCode::StatusMfrSpecific)
638 .await
639 }
640
641 pub async fn set_status_mfr_specific(&mut self, addr: u8, data: u8) -> Result<(), BUS::Error> {
643 self.write_cmd_byte(addr, CommandCode::StatusMfrSpecific, data)
644 .await
645 }
646
647 pub async fn get_status_fans_12(&mut self, addr: u8) -> Result<StatusFans12, BUS::Error> {
649 let raw = self.read_cmd_byte(addr, CommandCode::StatusFans12).await?;
650 Ok(StatusFans12::from_raw(raw))
651 }
652
653 pub async fn set_status_fans_12(
655 &mut self,
656 addr: u8,
657 status: StatusFans12,
658 ) -> Result<(), BUS::Error> {
659 self.write_cmd_byte(addr, CommandCode::StatusFans12, status.bits())
660 .await
661 }
662
663 pub async fn get_status_fans_34(&mut self, addr: u8) -> Result<StatusFans34, BUS::Error> {
665 let raw = self.read_cmd_byte(addr, CommandCode::StatusFans34).await?;
666 Ok(StatusFans34::from_raw(raw))
667 }
668
669 pub async fn set_status_fans_34(
671 &mut self,
672 addr: u8,
673 status: StatusFans34,
674 ) -> Result<(), BUS::Error> {
675 self.write_cmd_byte(addr, CommandCode::StatusFans34, status.bits())
676 .await
677 }
678
679 pub async fn get_vout_mode(&mut self, addr: u8) -> Result<VoutMode, BUS::Error> {
685 let raw = self.read_cmd_byte(addr, CommandCode::VoutMode).await?;
686 Ok(VoutMode::from_raw(raw))
687 }
688
689 pub async fn set_vout_mode(&mut self, addr: u8, mode: VoutMode) -> Result<(), BUS::Error> {
691 self.write_cmd_byte(addr, CommandCode::VoutMode, mode.to_raw())
692 .await
693 }
694
695 pub async fn get_coefficients(
699 &mut self,
700 addr: u8,
701 query: u8,
702 ) -> Result<DirectCoefficients, PmbusError<BUS::Error>> {
703 let resp = self
704 .block_process_call_cmd(addr, CommandCode::Coefficients, &[query])
705 .await?;
706 if resp.len() < 6 {
708 return Err(PmbusError::InvalidResponseLength);
709 }
710 DirectCoefficients::from_coefficients_response(&resp[1..6])
711 .ok_or(PmbusError::InvalidResponseLength)
712 }
713
714 pub async fn query(&mut self, addr: u8, command: u8) -> Result<u8, BUS::Error> {
716 self.smbus
717 .process_call(addr, CommandCode::Query.code(), command as u16)
718 .await
719 .map(|w| w as u8)
720 }
721
722 pub async fn get_smbalert_mask(
724 &mut self,
725 addr: u8,
726 status_register: u8,
727 ) -> Result<u8, BUS::Error> {
728 self.smbus
729 .process_call(
730 addr,
731 CommandCode::SmbalertMask.code(),
732 status_register as u16,
733 )
734 .await
735 .map(|w| w as u8)
736 }
737
738 pub async fn set_smbalert_mask(&mut self, addr: u8, data: u16) -> Result<(), BUS::Error> {
740 self.write_cmd_word(addr, CommandCode::SmbalertMask, data)
741 .await
742 }
743
744 pub async fn page_plus_read(
746 &mut self,
747 addr: u8,
748 page: u8,
749 command: u8,
750 ) -> Result<Vec<u8, 32>, BUS::Error> {
751 self.block_process_call_cmd(addr, CommandCode::PagePlusRead, &[page, command])
752 .await
753 }
754
755 pub async fn page_plus_write(&mut self, addr: u8, data: &[u8]) -> Result<(), BUS::Error> {
757 self.block_write_cmd(addr, CommandCode::PagePlusWrite, data)
758 .await
759 }
760
761 pub async fn read_kwh_in(&mut self, addr: u8) -> Result<u32, BUS::Error> {
763 let mut buf = [0u8; 4];
764 self.smbus
765 .write_read(addr, &[CommandCode::ReadKwhIn.code()], &mut buf)
766 .await?;
767 Ok(u32::from_le_bytes(buf))
768 }
769
770 pub async fn read_kwh_out(&mut self, addr: u8) -> Result<u32, BUS::Error> {
772 let mut buf = [0u8; 4];
773 self.smbus
774 .write_read(addr, &[CommandCode::ReadKwhOut.code()], &mut buf)
775 .await?;
776 Ok(u32::from_le_bytes(buf))
777 }
778
779 pub async fn raw_read_byte(&mut self, addr: u8, code: u8) -> Result<u8, BUS::Error> {
785 self.smbus.read_byte(addr, code).await
786 }
787
788 pub async fn raw_write_byte(&mut self, addr: u8, code: u8, data: u8) -> Result<(), BUS::Error> {
790 self.smbus.write_byte(addr, code, data).await
791 }
792
793 pub async fn raw_read_word(&mut self, addr: u8, code: u8) -> Result<u16, BUS::Error> {
795 self.smbus.read_word(addr, code).await
796 }
797
798 pub async fn raw_write_word(
800 &mut self,
801 addr: u8,
802 code: u8,
803 data: u16,
804 ) -> Result<(), BUS::Error> {
805 self.smbus.write_word(addr, code, data).await
806 }
807
808 pub async fn raw_block_read(&mut self, addr: u8, code: u8) -> Result<Vec<u8, 32>, BUS::Error> {
810 self.smbus.block_read(addr, code).await
811 }
812
813 pub async fn raw_block_write(
815 &mut self,
816 addr: u8,
817 code: u8,
818 data: &[u8],
819 ) -> Result<(), BUS::Error> {
820 self.smbus.block_write(addr, code, data).await
821 }
822
823 pub async fn extended_read_byte(
829 &mut self,
830 addr: u8,
831 prefix: u8,
832 ext_cmd: u8,
833 ) -> Result<u8, BUS::Error> {
834 let mut buf = [0u8; 1];
835 self.smbus
836 .write_read(addr, &[prefix, ext_cmd], &mut buf)
837 .await?;
838 Ok(buf[0])
839 }
840
841 pub async fn extended_write_byte(
843 &mut self,
844 addr: u8,
845 prefix: u8,
846 ext_cmd: u8,
847 data: u8,
848 ) -> Result<(), BUS::Error> {
849 self.smbus.write(addr, &[prefix, ext_cmd, data]).await
850 }
851
852 pub async fn extended_read_word(
854 &mut self,
855 addr: u8,
856 prefix: u8,
857 ext_cmd: u8,
858 ) -> Result<u16, BUS::Error> {
859 let mut buf = [0u8; 2];
860 self.smbus
861 .write_read(addr, &[prefix, ext_cmd], &mut buf)
862 .await?;
863 Ok(u16::from_le_bytes(buf))
864 }
865
866 pub async fn extended_write_word(
868 &mut self,
869 addr: u8,
870 prefix: u8,
871 ext_cmd: u8,
872 data: u16,
873 ) -> Result<(), BUS::Error> {
874 let bytes = data.to_le_bytes();
875 self.smbus
876 .write(addr, &[prefix, ext_cmd, bytes[0], bytes[1]])
877 .await
878 }
879}