summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart <lekaiser@uos.de>2020-07-25 20:50:23 +0200
committerLennart <lekaiser@uos.de>2020-07-25 20:50:23 +0200
commit714e5788be7b89f937fe8dbf270b8035c4f7d436 (patch)
treee05ae1a2b421840847ae28d053a26d8538fe89c1
parent5c4045862bf55be0b8dc755ac3d5c5bd24b5fedf (diff)
parentd0ea0a521a582549dfd9a98b47e7c12d8bcd0de6 (diff)
Merge branch 'master' into state-duration-timers
-rw-r--r--Makefile5
-rw-r--r--include/arch.h2
-rw-r--r--include/arch/msp430fr5969lp/driver/gpio.h5
-rw-r--r--include/arch/msp430fr5994lp/driver/timed_resistive_load.h72
-rw-r--r--include/driver/mmsubstate.h24
-rw-r--r--model/driver/mmsubstate.dfa85
-rw-r--r--model/driver/timed_resistive_load.dfa50
-rw-r--r--src/arch/msp430fr5994lp/Makefile.inc16
-rw-r--r--src/arch/msp430fr5994lp/driver/timed_resistive_load.cc85
-rw-r--r--src/driver/mmsubstate.cc41
10 files changed, 384 insertions, 1 deletions
diff --git a/Makefile b/Makefile
index 45501e2..98779b1 100644
--- a/Makefile
+++ b/Makefile
@@ -88,6 +88,11 @@ ifneq ($(findstring mmsimple,${drivers}), )
COMMON_FLAGS += -DDRIVER_MMSIMPLE
endif
+ifneq ($(findstring mmsubstate,${drivers}), )
+ CXX_TARGETS += src/driver/mmsubstate.cc
+ COMMON_FLAGS += -DDRIVER_MMSUBSTATE
+endif
+
ifneq ($(findstring nrf24l01,${drivers}), )
CXX_TARGETS += src/driver/nrf24l01.cc
ifeq (${arch}, msp430fr5994lp)
diff --git a/include/arch.h b/include/arch.h
index 877af62..1911271 100644
--- a/include/arch.h
+++ b/include/arch.h
@@ -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);
diff --git a/include/arch/msp430fr5969lp/driver/gpio.h b/include/arch/msp430fr5969lp/driver/gpio.h
index d279e31..65b5567 100644
--- a/include/arch/msp430fr5969lp/driver/gpio.h
+++ b/include/arch/msp430fr5969lp/driver/gpio.h
@@ -66,14 +66,19 @@ class GPIO {
inline void input(unsigned char const pin) {
if (pin < p2_0) {
P1DIR &= ~(1 << pin);
+ P1REN &= ~(1 << pin);
} else if (pin < p3_0) {
P2DIR &= ~(1 << (pin - p2_0));
+ P2REN &= ~(1 << (pin - p2_0));
} else if (pin < p4_0) {
P3DIR &= ~(1 << (pin - p3_0));
+ P3REN &= ~(1 << (pin - p3_0));
} else if (pin < pj_0) {
P4DIR &= ~(1 << (pin - p4_0));
+ P4REN &= ~(1 << (pin - p4_0));
} else if (pin < PIN_INVALID) {
PJDIR &= ~(1 << (pin - pj_0));
+ PJREN &= ~(1 << (pin - pj_0));
}
}
inline void input(unsigned char const pin, unsigned char const pull) {
diff --git a/include/arch/msp430fr5994lp/driver/timed_resistive_load.h b/include/arch/msp430fr5994lp/driver/timed_resistive_load.h
new file mode 100644
index 0000000..6e7996c
--- /dev/null
+++ b/include/arch/msp430fr5994lp/driver/timed_resistive_load.h
@@ -0,0 +1,72 @@
+#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
diff --git a/include/driver/mmsubstate.h b/include/driver/mmsubstate.h
new file mode 100644
index 0000000..3338dbc
--- /dev/null
+++ b/include/driver/mmsubstate.h
@@ -0,0 +1,24 @@
+#ifndef MMSUBSTATE_H
+#define MMSUBSTATE_H
+
+class MicroMoodySubstate {
+ private:
+ MicroMoodySubstate(const MicroMoodySubstate &copy);
+
+ unsigned char const address;
+ unsigned char txbuf[3];
+
+ public:
+ MicroMoodySubstate(unsigned char const addr) : address(addr) {}
+
+ void sleep();
+ void noSubstates(unsigned char power1, unsigned char power2);
+ void twoSubstates(unsigned char switchDutarion, unsigned char power);
+ void fourSubstates(unsigned char switchDutarion, unsigned char power);
+ void eightSubstates(unsigned char switchDutarion, unsigned char power);
+ void setSubstates(unsigned char substateCount, unsigned char switchDuration, unsigned char power);
+};
+
+extern MicroMoodySubstate moody;
+
+#endif
diff --git a/model/driver/mmsubstate.dfa b/model/driver/mmsubstate.dfa
new file mode 100644
index 0000000..6fb0c62
--- /dev/null
+++ b/model/driver/mmsubstate.dfa
@@ -0,0 +1,85 @@
+codegen:
+ instance: moody
+ includes:
+ - driver/i2c.h
+ - driver/mmsubstate.h
+ flags:
+ - arch_drivers=i2c
+ - drivers=mmsubstate
+ setup:
+ i2c.setup();
+
+parameters:
+ - substate_count
+ - substate_duration
+ - substate_power
+ - static_p1
+ - static_p2
+
+states:
+ - UNINITIALIZED
+ - SLEEP
+ - STATIC
+ - SUB2
+ - SUB8
+ - SUBVAR
+
+transition:
+ sleep:
+ src: [UNINITIALIZED, STATIC, SUB2, SUB8, SUBVAR]
+ dst: SLEEP
+ set_param:
+ substate_count: 0
+ substate_duration: 0
+ substate_power: 0
+ noSubstates:
+ src: [SLEEP, STATIC, SUB2, SUB8, SUBVAR]
+ dst: STATIC
+ arguments:
+ - name: power1
+ values: [30, 50, 80]
+ parameter: static_p1
+ - name: power2
+ values: [30, 50, 80]
+ parameter: static_p2
+ set_param:
+ substate_count: 0
+ substate_duration: 0
+ substate_power: 0
+ twoSubstates:
+ src: [SLEEP, STATIC, SUB2, SUB8, SUBVAR]
+ dst: SUB2
+ set_param:
+ substate_count: 2
+ arguments:
+ - name: switchDuration
+ values: [5, 10, 15, 20]
+ parameter: substate_duration
+ - name: power
+ values: [50, 100, 150]
+ parameter: substate_power
+ eightSubstates:
+ src: [SLEEP, STATIC, SUB2, SUB8, SUBVAR]
+ dst: SUB8
+ set_param:
+ substate_count: 8
+ arguments:
+ - name: switchDuration
+ values: [5, 10, 15, 20]
+ parameter: substate_duration
+ - name: power
+ values: [50, 100, 150]
+ parameter: substate_power
+ setSubstates:
+ src: [SLEEP, STATIC, SUB2, SUB8, SUBVAR]
+ dst: SUBVAR
+ arguments:
+ - name: substateCount
+ values: [2, 4, 10, 12]
+ parameter: substate_count
+ - name: switchDuration
+ values: [5, 10, 15, 20]
+ parameter: substate_duration
+ - name: power
+ values: [255]
+ parameter: substate_power
diff --git a/model/driver/timed_resistive_load.dfa b/model/driver/timed_resistive_load.dfa
new file mode 100644
index 0000000..cb7efab
--- /dev/null
+++ b/model/driver/timed_resistive_load.dfa
@@ -0,0 +1,50 @@
+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]
diff --git a/src/arch/msp430fr5994lp/Makefile.inc b/src/arch/msp430fr5994lp/Makefile.inc
index 8348d8e..e9d666f 100644
--- a/src/arch/msp430fr5994lp/Makefile.inc
+++ b/src/arch/msp430fr5994lp/Makefile.inc
@@ -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
diff --git a/src/arch/msp430fr5994lp/driver/timed_resistive_load.cc b/src/arch/msp430fr5994lp/driver/timed_resistive_load.cc
new file mode 100644
index 0000000..2c46be2
--- /dev/null
+++ b/src/arch/msp430fr5994lp/driver/timed_resistive_load.cc
@@ -0,0 +1,85 @@
+#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;
diff --git a/src/driver/mmsubstate.cc b/src/driver/mmsubstate.cc
new file mode 100644
index 0000000..b701f0b
--- /dev/null
+++ b/src/driver/mmsubstate.cc
@@ -0,0 +1,41 @@
+#include "driver/mmsubstate.h"
+#if defined(MULTIPASS_ARCH_HAS_I2C) && !defined(DRIVER_SOFTI2C)
+#include "driver/i2c.h"
+#else
+#include "driver/soft_i2c.h"
+#endif
+
+void MicroMoodySubstate::setSubstates(unsigned char substateCount, unsigned char switchDuration, unsigned char power)
+{
+ txbuf[0] = substateCount;
+ txbuf[1] = power;
+ txbuf[2] = switchDuration;
+ i2c.xmit(address, 3, txbuf, 0, txbuf);
+}
+
+void MicroMoodySubstate::sleep()
+{
+ setSubstates(1, 0, 0);
+}
+
+void MicroMoodySubstate::noSubstates(unsigned char power1, unsigned char power2)
+{
+ setSubstates(1, power1, power2);
+}
+
+void MicroMoodySubstate::twoSubstates(unsigned char switchDuration, unsigned char power)
+{
+ setSubstates(2, switchDuration, power);
+}
+
+void MicroMoodySubstate::fourSubstates(unsigned char switchDuration, unsigned char power)
+{
+ setSubstates(4, switchDuration, power);
+}
+
+void MicroMoodySubstate::eightSubstates(unsigned char switchDuration, unsigned char power)
+{
+ setSubstates(8, switchDuration, power);
+}
+
+MicroMoodySubstate moody(0x11);