diff options
-rw-r--r-- | Makefile | 5 | ||||
-rw-r--r-- | include/arch.h | 2 | ||||
-rw-r--r-- | include/arch/msp430fr5969lp/driver/gpio.h | 5 | ||||
-rw-r--r-- | include/arch/msp430fr5994lp/driver/timed_resistive_load.h | 72 | ||||
-rw-r--r-- | include/driver/mmsubstate.h | 24 | ||||
-rw-r--r-- | model/driver/mmsubstate.dfa | 85 | ||||
-rw-r--r-- | model/driver/timed_resistive_load.dfa | 50 | ||||
-rw-r--r-- | src/arch/msp430fr5994lp/Makefile.inc | 16 | ||||
-rw-r--r-- | src/arch/msp430fr5994lp/driver/timed_resistive_load.cc | 85 | ||||
-rw-r--r-- | src/driver/mmsubstate.cc | 41 |
10 files changed, 384 insertions, 1 deletions
@@ -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 ©); + + 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 ©); + + 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); |