Commit d0ea0a52 authored by Daniel Friesel's avatar Daniel Friesel
Browse files

add timed_resistive_load for µs-scale model generation timing benchmarks

parent e704cc11
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -10,6 +10,8 @@ class Arch {
		void setup();
		void idle_loop();
		void idle();

		// Delay functions are not exact
		void delay_us(unsigned int const us);
		void delay_ms(unsigned int const ms);
		void sleep_ms(unsigned int const ms);
+72 −0
Original line number Diff line number Diff line
#ifndef TIMED_RESISTIVE_LOAD_H
#define TIMED_RESISTIVE_LOAD_H

/*
 * Resistance at 25°c
 * R1: 986R
 * R2: 3K25
 * R3: 46K3
 * R4: 9K86
 */

class TimedResistiveLoad {
	private:
		TimedResistiveLoad(const TimedResistiveLoad &copy);

	public:
		TimedResistiveLoad() {}
		void setup();
		void switchToNone();
		void switchTo750(); // 576R (R1 || R2)
		void switchTo1K0(); // 986R (R1)
		void switchTo2K4(); // 2K44 (R2 || 4)
		void switchTo3K3(); // 3K25 (R2)
		void switchTo10K(); // 9K86 (R4)
		void switchTo47K(); // 46K3 (R3)

		/*
		 * These functions must be inline, as __delay_cycles only works with
		 * compile-time constants. So they must be part of the compilation unit
		 * which uses them and cannot easily be wrapped by a function without
		 * losing accuracy.
		 */

		inline void __attribute__((always_inline)) nop1K0(unsigned long long int const duration_us)
		{
			switchTo1K0();
			__delay_cycles(F_CPU / 1000000UL * duration_us);
			switchToNone();
		}

		inline void __attribute__((always_inline)) nop2K4(unsigned long long int const duration_us)
		{
			switchTo2K4();
			__delay_cycles(F_CPU / 1000000UL * duration_us);
			switchToNone();
		}

		inline void __attribute__((always_inline)) nop3K3(unsigned long long int const duration_us)
		{
			switchTo3K3();
			__delay_cycles(F_CPU / 1000000UL * duration_us);
			switchToNone();
		}

		inline void __attribute__((always_inline)) nop10K(unsigned long long int const duration_us)
		{
			switchTo10K();
			__delay_cycles(F_CPU / 1000000UL * duration_us);
			switchToNone();
		}

		inline void __attribute__((always_inline)) nop47K(unsigned long long int const duration_us)
		{
			switchTo47K();
			__delay_cycles(F_CPU / 1000000UL * duration_us);
			switchToNone();
		}
};

extern TimedResistiveLoad timedResistiveLoad;

#endif
+50 −0
Original line number Diff line number Diff line
codegen:
  instance: timedResistiveLoad
  includes:
    - driver/timed_resistive_load.h
  flags:
    - arch_drivers=timed_resistive_load
  setup:
    - timedResistiveLoad.setup();

states:
  - UNINITIALIZED
  - SLEEP
  - P14MW
  - P3_4MW
  - P235UW

transition:
  setup:
    src: [UNINITIALIZED]
    dst: SLEEP
  switchToNone:
    src: [UNINITIALIZED, SLEEP, P14MW, P3_4MW, P235UW]
    dst: SLEEP
  switchTo750:
    src: [UNINITIALIZED, SLEEP, P14MW, P3_4MW, P235UW]
    dst: P14MW
  switchTo3K3:
    src: [UNINITIALIZED, SLEEP, P14MW, P3_4MW, P235UW]
    dst: P3_4MW
  switchTo47K:
    src: [UNINITIALIZED, SLEEP, P14MW, P3_4MW, P235UW]
    dst: P235UW
  nop1K0:
    src: [SLEEP, P14MW, P3_4MW, P235UW]
    dst: SLEEP
    arguments:
    - name: duration_us
      values: [50, 200, 700, 1200, 5000, 23000]
  nop3K3:
    src: [SLEEP, P14MW, P3_4MW, P235UW]
    dst: SLEEP
    arguments:
    - name: duration_us
      values: [50, 200, 700, 1200, 5000, 23000]
  nop10K:
    src: [SLEEP, P14MW, P3_4MW, P235UW]
    dst: SLEEP
    arguments:
    - name: duration_us
      values: [50, 200, 700, 1200, 5000, 23000]
+15 −1
Original line number Diff line number Diff line
@@ -72,6 +72,19 @@ ifneq ($(findstring counter,${arch_drivers}), )
	CXX_TARGETS += src/arch/msp430fr5994lp/driver/counter.cc
endif

ifneq ($(findstring timed_resistive_load,${arch_drivers}), )
	CXX_TARGETS += src/arch/msp430fr5994lp/driver/timed_resistive_load.cc
	resistor1_pin ?= p3_0
	resistor2_pin ?= p3_1
	resistor3_pin ?= p3_2
	resistor4_pin ?= p3_3
	COMMON_FLAGS += -DDRIVER_TIMED_RESISTIVE_LOAD
	COMMON_FLAGS += -DTIMED_RESISTIVE_LOAD_PIN1=GPIO::${resistor1_pin}
	COMMON_FLAGS += -DTIMED_RESISTIVE_LOAD_PIN2=GPIO::${resistor2_pin}
	COMMON_FLAGS += -DTIMED_RESISTIVE_LOAD_PIN3=GPIO::${resistor3_pin}
	COMMON_FLAGS += -DTIMED_RESISTIVE_LOAD_PIN4=GPIO::${resistor4_pin}
endif

ifneq (${cpu_freq}, )
	COMMON_FLAGS += -DF_CPU=${cpu_freq}UL
else
@@ -127,7 +140,8 @@ arch_info:
	@echo "CPU   Freq: ${cpu_freq} Hz"
	@echo "Timer Freq: ${timer_freq} Hz -> $(shell src/arch/msp430fr5994lp/model.py f_timer "${cpu_freq}" "${timer_freq}")"
	@echo "I2C   Freq: ${i2c_freq} Hz"
	@echo "Counter Overflow: 65536/255"
	@echo "Counter Overflow: 65536/65535"
	@echo "sleep_ms Overflow: 250 500"
	@echo "Monitor: /dev/${SERIAL_PORT} 115200"

.PHONY: arch_clean arch_help arch_info monitor program
+85 −0
Original line number Diff line number Diff line
#include "driver/timed_resistive_load.h"
#include "driver/gpio.h"
#include "arch.h"

#ifndef TIMED_RESISTIVE_LOAD_PIN1
#error TIMED_RESISTIVE_LOAD_PIN1 must be set
#endif

#ifndef TIMED_RESISTIVE_LOAD_PIN2
#error TIMED_RESISTIVE_LOAD_PIN2 must be set
#endif

#ifndef TIMED_RESISTIVE_LOAD_PIN3
#error TIMED_RESISTIVE_LOAD_PIN3 must be set
#endif

#ifndef TIMED_RESISTIVE_LOAD_PIN4
#error TIMED_RESISTIVE_LOAD_PIN4 must be set
#endif

void TimedResistiveLoad::setup()
{
	gpio.output(TIMED_RESISTIVE_LOAD_PIN1, 0);
	gpio.output(TIMED_RESISTIVE_LOAD_PIN2, 0);
	gpio.output(TIMED_RESISTIVE_LOAD_PIN3, 0);
	gpio.output(TIMED_RESISTIVE_LOAD_PIN4, 0);
}

void TimedResistiveLoad::switchToNone()
{
	gpio.write(TIMED_RESISTIVE_LOAD_PIN1, 0);
	gpio.write(TIMED_RESISTIVE_LOAD_PIN2, 0);
	gpio.write(TIMED_RESISTIVE_LOAD_PIN3, 0);
	gpio.write(TIMED_RESISTIVE_LOAD_PIN4, 0);
}

void TimedResistiveLoad::switchTo750()
{
	gpio.write(TIMED_RESISTIVE_LOAD_PIN1, 1);
	gpio.write(TIMED_RESISTIVE_LOAD_PIN2, 1);
	gpio.write(TIMED_RESISTIVE_LOAD_PIN3, 0);
	gpio.write(TIMED_RESISTIVE_LOAD_PIN4, 0);
}

void TimedResistiveLoad::switchTo1K0()
{
	gpio.write(TIMED_RESISTIVE_LOAD_PIN1, 1);
	gpio.write(TIMED_RESISTIVE_LOAD_PIN2, 0);
	gpio.write(TIMED_RESISTIVE_LOAD_PIN3, 0);
	gpio.write(TIMED_RESISTIVE_LOAD_PIN4, 0);
}

void TimedResistiveLoad::switchTo2K4()
{
	gpio.write(TIMED_RESISTIVE_LOAD_PIN1, 0);
	gpio.write(TIMED_RESISTIVE_LOAD_PIN2, 1);
	gpio.write(TIMED_RESISTIVE_LOAD_PIN3, 0);
	gpio.write(TIMED_RESISTIVE_LOAD_PIN4, 1);
}

void TimedResistiveLoad::switchTo3K3()
{
	gpio.write(TIMED_RESISTIVE_LOAD_PIN1, 0);
	gpio.write(TIMED_RESISTIVE_LOAD_PIN2, 1);
	gpio.write(TIMED_RESISTIVE_LOAD_PIN3, 0);
	gpio.write(TIMED_RESISTIVE_LOAD_PIN4, 0);
}

void TimedResistiveLoad::switchTo10K()
{
	gpio.write(TIMED_RESISTIVE_LOAD_PIN1, 0);
	gpio.write(TIMED_RESISTIVE_LOAD_PIN2, 0);
	gpio.write(TIMED_RESISTIVE_LOAD_PIN3, 0);
	gpio.write(TIMED_RESISTIVE_LOAD_PIN4, 1);
}

void TimedResistiveLoad::switchTo47K()
{
	gpio.write(TIMED_RESISTIVE_LOAD_PIN1, 0);
	gpio.write(TIMED_RESISTIVE_LOAD_PIN2, 0);
	gpio.write(TIMED_RESISTIVE_LOAD_PIN3, 1);
	gpio.write(TIMED_RESISTIVE_LOAD_PIN4, 0);
}

TimedResistiveLoad timedResistiveLoad;