import math from ScEpTIC.emulator.energy import energy_utils from ScEpTIC.emulator.energy.mcu.options import MCUClockCycleAction, ADCPowerState from ScEpTIC.emulator.energy.options import OpModeName from ScEpTIC.emulator.energy.voltage_drawner import VoltageDrawner class Camera0V7620Model(VoltageDrawner): """ Energy model of a OV7620 camera. """ STATES = ['on', 'off'] CC_SET = 1 CC_READ = 1 t_wakeup = '200m' t_ready = '350m' resistance = '42' READ_DATA = 2000 def __init__(self): self.state = 'off' self.resistance = energy_utils.str_to_float(self.resistance) self.system_model = None def attach_system_model(self, system_model): self.system_model = system_model def set_state(self, state): """ Set state (off, on) """ if state not in self.STATES: raise Exception('Camera0V7620 - Invalid state') self.state = state def simulate_set_state(self, state): ticks = 0 # activate sensor for _ in range(self.CC_SET): ticks += self.system_model.run_step(MCUClockCycleAction.NO_MEMORY_ACCESS, OpModeName.SIMULATE_SENSOR) # enter LPM and wait for camera to be on if state == 'on' and self.state == 'off': ticks += self.system_model.run_step(MCUClockCycleAction.LPM_ENTER, OpModeName.LPM_ENTER) lpm_start_time = self.system_model.get_simulation_time() wait_time = energy_utils.str_to_float(self.t_wakeup) + energy_utils.str_to_float(self.t_ready) lpm_end_time = lpm_start_time + wait_time while self.system_model.get_simulation_time() < lpm_end_time: ticks += self.system_model.run_step(MCUClockCycleAction.LPM_NOP, OpModeName.SIMULATE_SENSOR) ticks += self.system_model.run_step(MCUClockCycleAction.LPM_EXIT, OpModeName.LPM_EXIT) self.set_state(state) return ticks def simulate_read(self, word_size): #print(f"Camera: read {math.ceil(self.READ_DATA/word_size)} words") # Activate the sensor ticks = self.simulate_set_state('on') # cycles to transfer data cycles = self.CC_READ + math.ceil(self.READ_DATA / word_size) for _ in range(cycles): ticks += self.system_model.run_step(MCUClockCycleAction.NO_MEMORY_ACCESS, OpModeName.SIMULATE_SENSOR) # Deactivate the sensor ticks += self.simulate_set_state('off') return ticks def get_drained_energy(self, t): """ Calculates the energy consumed by the component. :param t: elapsed time :return: the consumed energy """ voltage = self.voltage_source.get_voltage() if self.state == 'off': return 0.0 energy_from_R = energy_utils.energy_from_R_t(voltage, self.resistance, t) return energy_from_R