rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
pwm_generator_logic.h
Go to the documentation of this file.
1/**
2 * @file pwm_generator_logic.h
3 *
4 * @date Mar 2, 2014
5 * @author Andrey Belomutskiy, (c) 2012-2020
6 */
7
8#pragma once
9
10#include "state_sequence.h"
11#include "global.h"
12#include "scheduler.h"
13#include "efi_gpio.h"
14
15#define PERCENT_TO_DUTY(x) (x) * 0.01
16
17#define NAN_FREQUENCY_SLEEP_PERIOD_MS 100
18
19typedef struct {
20 /**
21 * a copy so that all phases are executed on the same period, even if another thread
22 * would be adjusting PWM parameters
23 */
24 float periodNt;
25 /**
26 * Iteration counter
27 */
29 /**
30 * Start time of current iteration
31 */
32 efitick_t startNt;
35
36class PwmConfig;
37
39typedef void (pwm_gen_callback)(int stateIndex, PwmConfig* pwm);
40
46
47/**
48 * @brief Multi-channel software PWM output configuration
49 */
50class PwmConfig {
51public:
52 PwmConfig();
53
54 void weComplexInit(
55 Scheduler *executor,
56 MultiChannelStateSequence const * seq,
57 pwm_cycle_callback *pwmCycleCallback,
58 pwm_gen_callback *callback);
59
61
62 /**
63 * We need to handle zero duty cycle and 100% duty cycle in a special way
64 */
66 bool isStopRequested = false;
67
68 /**
69 * @param use NAN frequency to pause PWM
70 */
71 void setFrequency(float frequency);
72
73 void handleCycleStart();
74 const char *m_name;
75
76 // todo: 'outputPins' should be extracted away from here since technically one can want PWM scheduler without actual pin output
77 OutputPin *outputPins[PWM_PHASE_MAX_WAVE_PER_PWM];
79 efitick_t togglePwmState();
80 void stop();
81 void applyPwmValue(OutputPin *output, int stateIndex, int channelIndex = 0);
82
84
86
88
89 /**
90 * this callback is invoked before each wave generation cycle
91 */
93
94 /**
95 * this main callback is invoked when it's time to switch level on any of the output channels
96 */
98private:
99 /**
100 * float value of PWM period
101 * PWM generation is not happening while this value is NAN
102 */
103 float periodNt;
104
105 // Set if we are very far behind schedule and need to reset back to the beginning of a cycle to find our way
106 bool forceCycleStart = true;
107};
108
109struct hardware_pwm;
110
111struct IPwm {
112 virtual void setSimplePwmDutyCycle(float dutyCycle) = 0;
113};
114
115class SimplePwm : public PwmConfig, public IPwm {
116public:
117 SimplePwm();
118 SimplePwm(const char *name);
119 void setSimplePwmDutyCycle(float dutyCycle) override;
122};
123
124/**
125 * default implementation of pwm_gen_callback which simply toggles the pins
126 *
127 */
128void applyPinState(int stateIndex, PwmConfig* state) /* pwm_gen_callback */;
129
130#define PWM_MAX_DUTY 1
131
132/**
133 * Start a one-channel software PWM driver.
134 *
135 * This method should be called after scheduling layer is started by initSignalExecutor()
136 */
137void startSimplePwm(SimplePwm *state, const char *msg,
138 Scheduler *executor,
139 OutputPin *output,
140 float frequency, float dutyCycle, pwm_gen_callback *callback = NULL);
141
142/**
143 * initialize GPIO pin and start a one-channel software PWM driver.
144 *
145 * This method should be called after scheduling layer is started by initSignalExecutor()
146 */
148 const char *msg,
149 Scheduler *executor,
150 brain_pin_e brainPin, OutputPin *output,
151 float frequency, float dutyCycle, pwm_gen_callback *callback = NULL);
152
153void startSimplePwmHard(SimplePwm *state, const char *msg,
154 Scheduler *executor,
155 brain_pin_e brainPin, OutputPin *output, float frequency,
156 float dutyCycle);
157
159
Single output pin reference and state.
Definition efi_output.h:49
Multi-channel software PWM output configuration.
pwm_mode_e mode
pwm_gen_callback * m_stateChangeCallback
Scheduler * m_executor
OutputPin * outputPins[PWM_PHASE_MAX_WAVE_PER_PWM]
scheduling_s scheduling
void weComplexInit(Scheduler *executor, MultiChannelStateSequence const *seq, pwm_cycle_callback *pwmCycleCallback, pwm_gen_callback *callback)
MultiChannelStateSequence const * multiChannelStateSequence
efitick_t togglePwmState()
void setFrequency(float frequency)
const char * m_name
pwm_config_safe_state_s safe
pwm_cycle_callback * m_pwmCycleCallback
void applyPwmValue(OutputPin *output, int stateIndex, int channelIndex=0)
hardware_pwm * hardPwm
void setSimplePwmDutyCycle(float dutyCycle) override
MultiChannelStateSequenceWithData< 2 > seq
EFI-related GPIO code.
static float frequency
Definition init_flex.cpp:21
void startSimplePwmExt(SimplePwm *state, const char *msg, Scheduler *executor, brain_pin_e brainPin, OutputPin *output, float frequency, float dutyCycle, pwm_gen_callback *callback=NULL)
void applyPinState(int stateIndex, PwmConfig *state)
void() pwm_gen_callback(int stateIndex, PwmConfig *pwm)
void() pwm_cycle_callback(PwmConfig *state)
@ PM_NORMAL
void startSimplePwmHard(SimplePwm *state, const char *msg, Scheduler *executor, brain_pin_e brainPin, OutputPin *output, float frequency, float dutyCycle)
void copyPwmParameters(PwmConfig *state, MultiChannelStateSequence const *seq)
void startSimplePwm(SimplePwm *state, const char *msg, Scheduler *executor, OutputPin *output, float frequency, float dutyCycle, pwm_gen_callback *callback=NULL)
state("state", SensorCategory.SENSOR_INPUTS, FieldType.INT8, 1871, 1.0, -1.0, -1.0, "")
virtual void setSimplePwmDutyCycle(float dutyCycle)=0