34#define REG_STATUS 0x34
35#define REG_HIGH_LIMIT_STATUS 0x35
36#define REG_LOW_LIMIT_STATUS 0x36
37#define REG_CRIT_LIMIT_STATUS 0x37
38#define REG_INTERNAL_DIODE_HIGH_BYTE 0x38
39#define REG_INTERNAL_DIODE_LOW_BYTE 0x39
40#define REG_EXTERNAL_DIODE_HIGH_BYTE 0x3A
41#define REG_EXTERNAL_DIODE_LOW_BYTE 0x3B
42#define REG_AVERAGING_CONTROL 0x40
43#define REG_CONFIGURATION 0x03
44#define REG_CONVERSION_RATE 0x04
45#define REG_INTERNAL_DIODE_HIGH_LIM 0x05
46#define REG_INTERNAL_DIODE_LOW_LIM 0x06
47#define REG_EXTERNAL_DIODE_HIGH_LIM_HIGH_BYTE 0x07
48#define REG_EXTERNAL_DIODE_LOW_LIM_HIGH_BYTE 0x08
49#define REG_EXTERNAL_DIODE_HIGH_LIM_LOW_BYTE 0x13
50#define REG_EXTERNAL_DIODE_LOW_LIM_LOW_BYTE 0x14
51#define REG_EXTERNAL_DIODE_TCRIT_LIM 0x19
52#define REG_CHANNEL_MASK_REG 0x1F
53#define REG_INTERNAL_DIODE_TCRIT_LIM 0x20
54#define REG_TCRIT_HYSTERISIS 0x21
55#define REG_TCRIT_CONSECUTIVE_ALERT 0x22
56#define REG_EXTERNAL_DIODE_BETA_CONFIG 0x25
57#define REG_EXTERNAL_DIODE_IDEALITY_FACTOR 0x25
58#define REG_ONE_SHOT 0x0F
59#define REG_EXTERNAL_DIODE_FAULT 0x1B
60#define REG_PRODUCT_FEATURES 0xFC
61#define REG_PRODUCT_ID 0xFD
62#define REG_MICROCHIP_ID 0xFE
63#define REG_REVISION 0xFF
64#define VOLTAGE_SAMPLING_CONFIG 0x50
65#define CURRENT_SENSE_SAMPLING_CONFIG 0x51
66#define PEAK_DETECTION_CONFIG 0x52
67#define SENCE_VOLTAGE_HIGH_BYTE 0x54
68#define SENCE_VOLTAGE_LOW_BYTE 0x55
69#define SOURCE_VOLTAGE_HIGH_BYTE 0x58
70#define SOURCE_VOLTAGE_LOW_BYTE 0x59
71#define POWER_RATIO_VOLTAGE_HIGH_BYTE 0x5B
72#define POWER_RATIO_VOLTAGE_LOW_BYTE 0x5C
73#define SENCE_VOLTAGE_HIGH_LIM 0x60
74#define SENCE_VOLTAGE_LOW_LIM 0x61
75#define SOURCE_VOLTAGE_HIGH_LIM 0x64
76#define SOURCE_VOLTAGE_LOW_LIM 0x65
77#define SENCE_VOLTAGE_V_CRIT 0x66
78#define SOURCE_VOLTAGE_V_CRIT 0x68
79#define SENSE_V_CRIT_HYSTERISIS 0x69
80#define SOURCE_V_CRIT_HYSTERISIS 0x6A
163 set_conversion_rate(rate);
164 set_averaging_control(avrg_temp);
166 set_int_temp_high_lim();
167 set_int_temp_low_lim();
168 set_ext_temp_high_lim();
169 set_ext_temp_low_lim();
172 set_consecutive_alert(alert_crit, alert_lim);
173 set_beta_configuration(beta);
174 set_ideality_factor(i_factor);
176 set_voltage_sampling_config(v_source_spike, avrg_i_sense);
177 set_current_sense_sampling_config(v_sense_spike, avrg_i_sense, i_sampling,
179 set_peak_detection_config(thres, dur);
199 :
emc1702(name, i2c, addr, m_dummy)
204emc1702::get_measurements(sensor_mode m)
206 float temperature_internal;
207 float temperature_external;
210 float source_voltage;
213 if (get_crit_limit_status()) {
216 if (get_sensor_info() == 0) {
217 throw emc1702_incorrect_sensor_info(__FILE__, __LINE__);
219 temperature_internal = get_temperature_internal();
220 temperature_external = get_temperature_external();
229 if (get_crit_limit_status()) {
230 throw emc1702_thermal_shutdown_needed(__FILE__, __LINE__);
232 if (get_sensor_info() == 0) {
233 throw emc1702_incorrect_sensor_info(__FILE__, __LINE__);
242 if (get_crit_limit_status()) {
243 throw emc1702_thermal_shutdown_needed(__FILE__, __LINE__);
245 if (get_sensor_info() == 0) {
246 throw emc1702_incorrect_sensor_info(__FILE__, __LINE__);
248 temperature_internal = get_temperature_internal();
249 temperature_external = get_temperature_external();
254 if (get_crit_limit_status()) {
255 throw emc1702_thermal_shutdown_needed(__FILE__, __LINE__);
257 if (get_sensor_info() == 0) {
258 throw emc1702_incorrect_sensor_info(__FILE__, __LINE__);
266 throw inval_arg_exception(__FILE__, __LINE__);
283 return (get_temperature_internal() + get_temperature_external()) / 2;
287emc1702::get_temperature_internal()
const
289 uint8_t
buf[2] = {0, 0};
291 uint16_t bit_value = ((
buf[0] << 8) |
buf[1]) >> 5;
292 bool sign = (bit_value >> 10) != 0;
294 bit_value = ~bit_value + 1;
297 float temp_value =
static_cast<float>((bit_value >> 3) & 0x7F);
298 temp_value +=
static_cast<float>(bit_value & 0x07) * 0.125f;
301 temp_value = -temp_value;
308emc1702::get_temperature_external()
const
310 uint8_t
buf[2] = {0, 0};
312 uint16_t bit_value = ((
buf[0] << 8) |
buf[1]) >> 5;
313 bool sign = (bit_value >> 10) != 0;
315 bit_value = ~bit_value + 1;
318 float temp_value =
static_cast<float>((bit_value >> 3) & 0x7F);
319 temp_value +=
static_cast<float>(bit_value & 0x07) * 0.125f;
322 temp_value = -temp_value;
333 s = {.busy = 0, .crit = 0, .diode_fault = 0, .low = 0, .high = 0, .peak = 0};
340 s.diode_fault =
buf & (1 << 2);
342 s.low =
buf & (1 << 3);
344 s.high =
buf & (1 << 4);
347 s.peak =
buf & (1 << 6);
348 s.busy =
buf & (1 << 7);
362 buf =
static_cast<uint8_t
>(m);
373emc1702::set_conversion_rate(conversion_rate r)
const
386 buf =
static_cast<uint8_t
>(r);
396emc1702::set_int_temp_high_lim(
float int_temp_high_lim)
const
400 if (int_temp_high_lim >= 127.0f) {
402 }
else if (int_temp_high_lim <= -128.0f) {
405 if (int_temp_high_lim >= 0.0f) {
406 buf =
static_cast<uint8_t
>(abs(round(int_temp_high_lim)));
408 buf =
static_cast<uint8_t
>(abs(round(int_temp_high_lim)));
418emc1702::set_int_temp_low_lim(
float int_temp_low_lim)
const
422 if (int_temp_low_lim >= 127.0f) {
424 }
else if (int_temp_low_lim <= -128.0f) {
427 if (int_temp_low_lim >= 0.0f) {
428 buf =
static_cast<uint8_t
>(abs(round(int_temp_low_lim)));
430 buf =
static_cast<uint8_t
>(abs(round(int_temp_low_lim)));
440emc1702::set_ext_temp_high_lim(
float ext_temp_high_lim)
const
444 buf[0] =
static_cast<uint8_t
>(floor(std::abs(ext_temp_high_lim)));
445 if (ext_temp_high_lim < 0.0f) {
448 float floatingPart = std::abs(ext_temp_high_lim) -
449 static_cast<int>(std::abs(ext_temp_high_lim));
450 buf[1] =
static_cast<int>(floatingPart * 8.0f);
457emc1702::set_ext_temp_low_lim(
float ext_temp_low_lim)
const
461 buf[0] =
static_cast<uint8_t
>(floor(std::abs(ext_temp_low_lim)));
462 if (ext_temp_low_lim < 0.0f) {
466 std::abs(ext_temp_low_lim) -
static_cast<int>(std::abs(ext_temp_low_lim));
467 buf[1] =
static_cast<int>(floatingPart * 8.0f);
474emc1702::get_one_shot_meas()
const
484emc1702::set_t_crit(
float ext_t_crit,
float int_t_crit,
485 float t_crit_hysterisis)
const
489 if (ext_t_crit >= 127.0f) {
491 }
else if (ext_t_crit <= -128.0f) {
494 if (ext_t_crit >= 0.0f) {
495 buf =
static_cast<uint8_t
>(abs(round(ext_t_crit)));
497 buf =
static_cast<uint8_t
>(abs(round(ext_t_crit)));
505 if (int_t_crit >= 127.0f) {
507 }
else if (int_t_crit <= -128.0f) {
510 if (int_t_crit >= 0) {
511 buf =
static_cast<uint8_t
>(abs(round(int_t_crit)));
513 buf =
static_cast<uint8_t
>(abs(round(int_t_crit)));
521 if (t_crit_hysterisis < 0.0f) {
522 throw inval_arg_exception(__FILE__, __LINE__);
523 }
else if (t_crit_hysterisis >= 127.0f) {
526 buf =
static_cast<uint8_t
>(abs(round(t_crit_hysterisis)));
532emc1702::get_diode_fault()
const
540 diode_fault = (
buf & 0b10);
545emc1702::set_consecutive_alert(consecutive_alert_diode_fault c,
546 consecutive_alert_diode_fault l)
const
557 buf =
static_cast<uint8_t
>(l);
560 throw inval_arg_exception(__FILE__, __LINE__);
567 buf |= (
static_cast<uint8_t
>(c) << 3);
571 throw inval_arg_exception(__FILE__, __LINE__);
577emc1702::set_beta_configuration(beta_config b)
const
599 buf =
static_cast<uint8_t
>(b);
603 throw inval_arg_exception(__FILE__, __LINE__);
609emc1702::set_ideality_factor(ideality_factor i)
const
622 buf =
static_cast<uint8_t
>(i);
626 throw inval_arg_exception(__FILE__, __LINE__);
632emc1702::get_high_limit_status()
const
643 i_high = (
buf & 0b01);
645 e_high = (
buf & 0b10);
647 vsrc_high =
buf & (1 << 6);
649 vsense_high =
buf & (1 << 7);
650 etl::vector<bool, 4> v = {i_high, e_high, vsrc_high, vsense_high};
655emc1702::get_low_limit_status()
const
666 i_low = (
buf & 0b01);
668 e_low = (
buf & 0b10);
670 vsrc_low =
buf & (1 << 6);
672 vsense_low =
buf & (1 << 7);
673 etl::vector<bool, 4> v = {i_low, e_low, vsrc_low, vsense_low};
678emc1702::get_crit_limit_status()
const
689 i_crit = (
buf & 0b01);
691 e_crit = (
buf & 0b10);
693 vsrc_crit =
buf & (1 << 6);
695 vsense_crit =
buf & (1 << 7);
697 bool thermal_shutdown_needed = (i_crit || e_crit || vsrc_crit || vsense_crit);
698 return thermal_shutdown_needed;
702emc1702::set_averaging_control(averaging_control a)
const
711 buf =
static_cast<uint8_t
>(a);
715 throw inval_arg_exception(__FILE__, __LINE__);
722emc1702::get_sensor_info()
const
725 uint8_t
buf[4] = {0, 0, 0, 0};
729 if ((
buf[1] == 0b00111001) && (
buf[2] == 0b01011101) &&
730 (
buf[3] == 0b10000010)) {
737emc1702::set_voltage_sampling_config(consecutive_alert_voltage v,
738 averaging_control s)
const
746 buf =
static_cast<uint8_t
>(v);
749 throw inval_arg_exception(__FILE__, __LINE__);
757 buf |=
static_cast<uint8_t
>(s);
761 throw inval_arg_exception(__FILE__, __LINE__);
767emc1702::set_current_sense_sampling_config(consecutive_alert_current v,
769 current_sampling_time t,
770 max_expected_voltage m)
const
778 buf =
static_cast<uint8_t
>(v);
781 throw inval_arg_exception(__FILE__, __LINE__);
788 buf |= (
static_cast<uint8_t
>(i) << 4);
791 throw inval_arg_exception(__FILE__, __LINE__);
797 buf |=
static_cast<uint8_t
>(t);
800 throw inval_arg_exception(__FILE__, __LINE__);
807 buf |=
static_cast<uint8_t
>(m);
811 throw inval_arg_exception(__FILE__, __LINE__);
817emc1702::set_peak_detection_config(peak_detection_threshold t,
818 peak_detection_duration d)
838 buf =
static_cast<uint8_t
>(t);
841 throw inval_arg_exception(__FILE__, __LINE__);
861 buf |=
static_cast<uint8_t
>(d);
865 throw inval_arg_exception(__FILE__, __LINE__);
871emc1702::get_fsc()
const
876 uint8_t r = (buf1 & 0b11);
913 int16_t bit_value = ((
buf[0] << 8) |
buf[1]) >> 4;
914 sign = (bit_value >> 11) != 0;
916 bit_value = ~bit_value + 1;
918 return (get_fsc() * bit_value / 2047.0f);
935 int16_t bit_value = ((
buf[0] << 8) |
buf[1]) >> 5;
936 float source_voltage =
fsv * bit_value / 2047.0f;
937 return source_voltage;
947 uint8_t
buf[2] = {0, 0};
949 uint16_t bit_value = ((
buf[0] << 8) |
buf[1]);
950 return (get_fsc() *
fsv * bit_value / 65535.0f);
955emc1702::set_v_sense_lim(
float v_sense_lim_low,
float v_sense_lim_high)
const
960 if (v_sense_lim_low >= 2032.0f) {
962 }
else if (v_sense_lim_low <= -2033.0f) {
965 if (v_sense_lim_low >= 0) {
967 static_cast<uint8_t
>(floor((v_sense_lim_low / 16.0f) + 0.5f) * 16.0f);
970 static_cast<uint8_t
>(floor((v_sense_lim_low / 16.0f) + 0.5f) * 16.0f);
977 if (v_sense_lim_high >= 2032.0f) {
979 }
else if (v_sense_lim_high <= -2033.0f) {
982 if (v_sense_lim_high >= 0.0f) {
983 buf =
static_cast<uint8_t
>(floor((v_sense_lim_high / 16.0f) + 0.5f) *
986 buf =
static_cast<uint8_t
>(floor((v_sense_lim_high / 16.0f) + 0.5f) *
996emc1702::set_v_source_lim(
float v_source_lim_low,
float v_source_lim_high)
const
998 uint8_t
buf[2] = {0, 0};
999 if (v_source_lim_low < 0) {
1000 throw inval_arg_exception(__FILE__, __LINE__);
1001 }
else if (v_source_lim_low >= 23.9063f) {
1002 buf[1] = 0b11111111;
1004 buf[1] =
static_cast<uint8_t
>(round(v_source_lim_low * 10.67f));
1006 if (v_source_lim_high < 0) {
1007 throw inval_arg_exception(__FILE__, __LINE__);
1008 }
else if (v_source_lim_high >= 23.9063f) {
1009 buf[0] = 0b11111111;
1011 buf[0] =
static_cast<uint8_t
>(round(v_source_lim_high * 10.67f));
1017emc1702::set_v_crit_lim(
float v_sense_lim_crit,
float v_source_lim_crit,
1018 float v_sense_hysterisis,
1019 float v_source_hysterisis)
const
1023 if (v_sense_lim_crit >= 2032.0f) {
1025 }
else if (v_sense_lim_crit <= -2033.0f) {
1028 if (v_sense_lim_crit >= 0.0f) {
1029 buf =
static_cast<uint8_t
>(floor((v_sense_lim_crit / 16.0f) + 0.5f) *
1032 buf =
static_cast<uint8_t
>(floor((v_sense_lim_crit / 16.0f) + 0.5f) *
1040 if (v_sense_hysterisis >= 496.0f) {
1042 }
else if (v_sense_hysterisis < 0.0f) {
1043 throw inval_arg_exception(__FILE__, __LINE__);
1045 buf =
static_cast<uint8_t
>(floor((v_sense_hysterisis / 16.0f) + 0.5f) *
1050 if (v_source_lim_crit < 0.0f) {
1051 throw inval_arg_exception(__FILE__, __LINE__);
1052 }
else if (v_source_lim_crit >= 23.9063f) {
1055 buf =
static_cast<uint8_t
>(round(v_source_lim_crit * 10.67f));
1058 if (v_source_hysterisis < 0.0f) {
1059 throw inval_arg_exception(__FILE__, __LINE__);
1060 }
else if (v_source_hysterisis >= 2.9063f) {
1063 buf =
static_cast<uint8_t
>(round(v_source_hysterisis * 10.67f));
1074 return m_alert.get();
virtual void read(uint16_t addr, uint8_t *rx, size_t rxlen, const uint8_t *tx, size_t txlen)=0
Performs an I2C read operation.
virtual void write(uint16_t addr, const uint8_t *tx, size_t len)=0
Performs an I2C write operation.
Exception thrown when the EMC1702 has not be initialized properly.
Exception thrown when a thermal shutdown is required.
ideality_factor
Settings to set the Ideality Factor in the External Diode Ideality Factor Registers.
float get_sense_current() const
Retrieves current measurement from the EMC1702 sensor.
float get_temperature_average() const
Retrieves temperature from the EMC1702 sensor by averaging the internal and external diode measuremen...
averaging_control
Settings to set the digital averaging on mesurements in the Averaging Control Register,...
sensor_mode
Selects the mode of operation of the EMC1702 sensor.
conversion_rate
Settings to set the frequency of measurements in the Conversion Rate Register.
void get_status(status &s)
consecutive_alert_voltage
Settings to set the threshold for consecutive voltage out-of-limit measurements in the Voltage Sampli...
emc1702(const char *name, bsp::i2c &i2c, uint16_t addr, bsp::gpio &alert)
Constructs an EMC1702 sensor object with an ALERT GPIO pin.
current_sampling_time
Settings to set the Current Sensing Sampling Time in the Current Sense Sampling Configuration Registe...
static constexpr float fsv
Full Scale Voltage in volts.
static constexpr float r_sense
External sense resistor value in Ohms.
max_expected_voltage
Settings to set the Current Sense maximum expected voltage (full scale range) in the Current Sense Sa...
@ CURRENT_SENSOR_RANGE_20_mV
@ CURRENT_SENSOR_RANGE_80_mV
@ CURRENT_SENSOR_RANGE_10_mV
@ CURRENT_SENSOR_RANGE_40_mV
consecutive_alert_current
Settings to set the threshold for consecutive current out-of-limit measurements in the Current Sense ...
float get_source_voltage() const
Retrieves source voltage measurement from the EMC1702 sensor.
peak_detection_duration
Settings to set the peak detector minimum time threshold in the Peak Detection Configuration Register...
peak_detection_threshold
Settings to set the peak detector threshold level in the Peak Detection Configuration Register.
beta_config
Settings to set the Beta Compensation factor in the Beta Configuration Registers.
void set_config(sensor_mode m) const
consecutive_alert_diode_fault
Settings to set the threshold for consecutive diode fault alerts in the Consecutive Alert Register.
Generic exception indicating an invalid argument.
#define POWER_RATIO_VOLTAGE_HIGH_BYTE
#define REG_INTERNAL_DIODE_HIGH_LIM
#define REG_EXTERNAL_DIODE_TCRIT_LIM
#define VOLTAGE_SAMPLING_CONFIG
#define SOURCE_VOLTAGE_HIGH_BYTE
#define SOURCE_VOLTAGE_HIGH_LIM
#define PEAK_DETECTION_CONFIG
#define REG_CRIT_LIMIT_STATUS
#define REG_TCRIT_HYSTERISIS
#define REG_CONVERSION_RATE
#define SENCE_VOLTAGE_LOW_LIM
#define REG_AVERAGING_CONTROL
#define REG_TCRIT_CONSECUTIVE_ALERT
#define REG_EXTERNAL_DIODE_BETA_CONFIG
#define SENSE_V_CRIT_HYSTERISIS
#define REG_EXTERNAL_DIODE_HIGH_LIM_HIGH_BYTE
#define SENCE_VOLTAGE_HIGH_LIM
#define REG_HIGH_LIMIT_STATUS
#define REG_INTERNAL_DIODE_HIGH_BYTE
#define REG_EXTERNAL_DIODE_IDEALITY_FACTOR
#define REG_INTERNAL_DIODE_TCRIT_LIM
#define REG_PRODUCT_FEATURES
#define REG_EXTERNAL_DIODE_HIGH_BYTE
#define SENCE_VOLTAGE_V_CRIT
#define REG_EXTERNAL_DIODE_FAULT
#define REG_EXTERNAL_DIODE_LOW_LIM_HIGH_BYTE
#define REG_INTERNAL_DIODE_LOW_LIM
#define SOURCE_VOLTAGE_V_CRIT
#define SOURCE_V_CRIT_HYSTERISIS
#define SENCE_VOLTAGE_HIGH_BYTE
#define REG_LOW_LIMIT_STATUS
#define CURRENT_SENSE_SAMPLING_CONFIG
#define REG_CONFIGURATION