rusEFI
The most advanced open source ECU
state_sequence.h
Go to the documentation of this file.
1 /**
2  * @file state_sequence.h
3  *
4  * @date May 18, 2014
5  * @author Andrey Belomutskiy, (c) 2012-2020
6  */
7 
8 #pragma once
9 
10 #include <stdint.h>
11 #include "rusefi_enums.h"
12 #include <rusefi/expected.h>
13 
14 enum class TriggerValue : uint8_t {
15  FALL = 0,
16  RISE = 1
17 };
18 
19 // see also 'HW_EVENT_TYPES'
20 typedef enum {
26 
27 /**
28  * This layer has two primary usages:
29  * 1) 'simple' PWM generation is used to produce actuator square control wave
30  * 2) 'complex' PWM generation is used for trigger simulator.
31  * Some triggers like Nissan 360 slot optical wheel need a lot of points to describe the shape of the wave.
32  * Looks like 252 is explained by 60 tooth * 2 (number of fronts) * 2 (number of crank rotations within engine cycle)
33  */
34 #ifndef PWM_PHASE_MAX_COUNT
35 // as of April 2020, trigger which requires most array length is REMIX_66_2_2_2
36 // we can probably reduce RAM usage if we have more custom logic of triggers with large number of tooth while
37 // pretty easy logic. like we do not need to REALLY have an array to remember the shape of evenly spaces 360 or 60/2 trigger :)
38 // todo https://github.com/rusefi/rusefi/issues/3003
39 #define PWM_PHASE_MAX_COUNT 280
40 #endif /* PWM_PHASE_MAX_COUNT */
41 #define PWM_PHASE_MAX_WAVE_PER_PWM 2
42 
44 
45 /**
46  * This class represents multi-channel logical signals with shared time axis
47  *
48  * This is a semi-abstract interface so that implementations can exist for either regularized
49  * patterns (60-2, etc) or completely arbitrary patterns stored in arrays.
50  */
52 public:
53  /**
54  * values in the (0..1] range which refer to points within the period at at which pin state
55  * should be changed So, in the simplest case we turn pin off at 0.3 and turn it on at 1 -
56  * that would give us a 70% duty cycle PWM
57  */
58  virtual float getSwitchTime(int phaseIndex) const = 0;
59  virtual pin_state_t getChannelState(int channelIndex, int phaseIndex) const = 0;
60 
61  // Make sure the switch times are in order and end at the very end.
62  void checkSwitchTimes(float scale) const;
63 
64  // Find the exact angle, or unexpected if it doesn't exist
65  expected<int> findAngleMatch(float angle) const;
66 
67  // returns the index at which given value would need to be inserted into sorted array
68  int findInsertionAngle(float angle) const;
69 
70  uint16_t phaseCount = 0; // Number of timestamps
71  uint16_t waveCount = 0; // Number of waveforms
72 };
73 
74 template<unsigned max_phase>
76 public:
77  float getSwitchTime(int phaseIndex) const override {
78  return switchTimes[phaseIndex];
79  }
80 
81  pin_state_t getChannelState(int channelIndex, int phaseIndex) const override {
82  if (channelIndex >= waveCount) {
83  // todo: would be nice to get this asserting working
84  //criticalError("channel index %d/%d", channelIndex, waveCount);
85  }
86  return ((waveForm[phaseIndex] >> channelIndex) & 1) ? TriggerValue::RISE : TriggerValue::FALL;
87  }
88 
89  void reset() {
90  waveCount = 0;
91  }
92 
93  void setSwitchTime(const int phaseIndex, const float value) {
94  switchTimes[phaseIndex] = value;
95  }
96 
97  void setChannelState(const int channelIndex, const int phaseIndex, pin_state_t state) {
98  if (channelIndex >= waveCount) {
99  // todo: would be nice to get this asserting working
100  //criticalError("channel index %d/%d", channelIndex, waveCount);
101  }
102  uint8_t & ref = waveForm[phaseIndex];
103  ref = (ref & ~(1U << channelIndex)) | ((state == TriggerValue::RISE ? 1 : 0) << channelIndex);
104  }
105 
106 private:
107  float switchTimes[max_phase];
108  uint8_t waveForm[max_phase];
109 };
110 
void checkSwitchTimes(float scale) const
virtual float getSwitchTime(int phaseIndex) const =0
virtual pin_state_t getChannelState(int channelIndex, int phaseIndex) const =0
int findInsertionAngle(float angle) const
expected< int > findAngleMatch(float angle) const
pin_state_t getChannelState(int channelIndex, int phaseIndex) const override
float getSwitchTime(int phaseIndex) const override
void setSwitchTime(const int phaseIndex, const float value)
void setChannelState(const int channelIndex, const int phaseIndex, pin_state_t state)
Fundamental rusEFI enumerable types live here.
static ScState state
TriggerValue pin_state_t
trigger_event_e
@ SHAFT_SECONDARY_RISING
@ SHAFT_SECONDARY_FALLING
@ SHAFT_PRIMARY_FALLING
@ SHAFT_PRIMARY_RISING
TriggerValue