Files
simulation_core/tests/peripherals/AndesATCWDT200_Watchdog-helpers.py

49 lines
1.9 KiB
Python

import decimal
from typing import Union
def get_interrupt_timeout_seconds(control_register_value, clock_frequency):
# Robot passes values as strings, so convert them.
control_register_value = int(control_register_value.strip(), 0)
interrupt_interval_power = control_register_value & 0b1110000 # bits 7:4
# Interrupt interval starts at 2^6 when value is 0.
power_offset = 6
return get_timeout_seconds(interrupt_interval_power, power_offset, clock_frequency)
def get_reset_timeout_seconds(control_register_value, clock_frequency):
# Robot passes values as strings, so convert them.
control_register_value = int(control_register_value.strip(), 0)
reset_interval_power = control_register_value & 0b11100000000 # bits 10:8
# Reset interval starts at 2^7 when value is 0.
power_offset = 7
return get_timeout_seconds(reset_interval_power, power_offset, clock_frequency)
def get_timeout_seconds(interval_power, power_offset, clock_frequency):
# Robot passes values as strings, so convert them.
clock_frequency = int(clock_frequency.strip(), 0)
interval_cycles = pow(2, interval_power + power_offset)
seconds_per_cycle = 1 / clock_frequency
timeout_seconds = interval_cycles * seconds_per_cycle
# Round the number so we wait for slightly longer than necessary,
# otherwise we risk waiting too little due to precision loss.
return round_to_n_significant_digits(timeout_seconds, 3)
def round_to_n_significant_digits(value: Union[str, float], digits: int):
with decimal.localcontext() as context:
# Adjust precision to match the number of significant digits we want.
context.prec = digits
# Always round up, since we don't want to accidentally wait for too little time.
context.rounding = decimal.ROUND_UP
rounded_number = decimal.Decimal(value).normalize(context)
return format(rounded_number, "f")