rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
protected_gpio.cpp
Go to the documentation of this file.
1
2#include "pch.h"
3
4#include "protected_gpio.h"
5#include "gpio/gpio_ext.h"
6
7#define PROTECTED_CHANNEL_COUNT 8
8
9class ProtectedGpio {
10public:
11 int setPadMode(iomode_t mode);
12 int set(bool value);
13 int get() const;
14 brain_pin_diag_e getDiag() const;
15
16 void configure(const ProtectedGpioConfig& config);
17 void check(efitick_t nowNt);
18
19private:
20 OutputPin m_output;
21
22 const ProtectedGpioConfig* m_config;
23};
24
25void ProtectedGpio::configure(const ProtectedGpioConfig& p_config) {
26 m_config = &p_config;
27}
28
29int ProtectedGpio::setPadMode(iomode_t mode) {
30 if (mode == PAL_MODE_OUTPUT_PUSHPULL) {
31 m_output.initPin("protected", m_config->Pin);
32 } else {
33 m_output.deInit();
34 }
35
36 return 0;
37}
38
39int ProtectedGpio::set(bool value) {
40 if (!m_config) {
41 return -1;
42 }
43
44 // TODO: operate state machine to handle overcurrent
45 m_output.setValue(value);
46
47 return 0;
48}
49
50int ProtectedGpio::get() const {
51 return m_output.getLogicValue();
52}
53
54void ProtectedGpio::check(efitick_t /*nowNt*/) {
55 if (!m_config) {
56 return;
57 }
58
59 auto senseVolts = adcGetRawVoltage("protected", m_config->SenseChannel);
60 if (senseVolts) {
61 float amps = senseVolts.value_or(0) * m_config->AmpsPerVolt;
62
63 // TODO: smarter state machine
64 if (amps > m_config->MaximumAllowedCurrent) {
65 m_output.setValue(false);
66 }
67 } else {
68 /* shutdown if failed to measure current */
69 m_output.setValue(false);
70 }
71}
72
73brain_pin_diag_e ProtectedGpio::getDiag() const {
74 // TODO: return PIN_OVERLOAD if there's a problem
75 return PIN_OK;
76}
77
78class ProtectedGpios : public GpioChip {
79public:
80 int init() override { return 0; }
81 int setPadMode(size_t pin, iomode_t mode) override;
82 int writePad(size_t pin, int value) override;
83 int readPad(size_t pin) override;
84
85 brain_pin_diag_e getDiag(size_t pin) override;
86
87 void configure(const ProtectedGpioConfig* const configs);
88 void check(efitick_t nowNt);
89
90private:
91 ProtectedGpio m_channels[PROTECTED_CHANNEL_COUNT];
92};
93
94int ProtectedGpios::setPadMode(size_t pin, iomode_t mode) {
95 if (pin >= PROTECTED_CHANNEL_COUNT) {
96 return -1;
97 }
98
99 return m_channels[pin].setPadMode(mode);
100}
101
102int ProtectedGpios::writePad(size_t pin, int value) {
103 if (pin >= PROTECTED_CHANNEL_COUNT) {
104 return -1;
105 }
106
107 return m_channels[pin].set(value);
108}
109
110int ProtectedGpios::readPad(size_t pin) {
111 if (pin >= PROTECTED_CHANNEL_COUNT) {
112 return -1;
113 }
114
115 return m_channels[pin].get();
116}
117
118brain_pin_diag_e ProtectedGpios::getDiag(size_t pin) {
119 if (pin >= PROTECTED_CHANNEL_COUNT) {
120 return PIN_UNKNOWN;
121 }
122
123 return m_channels[pin].getDiag();
124}
125
126void ProtectedGpios::configure(const ProtectedGpioConfig* const configs) {
127 for (size_t i = 0; i < efi::size(m_channels); i++) {
128 m_channels[i].configure(configs[i]);
129 }
130}
131
132void ProtectedGpios::check(efitick_t nowNt) {
133 for (size_t i = 0; i < efi::size(m_channels); i++) {
134 m_channels[i].check(nowNt);
135 }
136}
137
138static ProtectedGpios protectedGpios;
139static bool didInit = false;
140
141int protectedGpio_add(brain_pin_e base, const ProtectedGpioConfig* const configs) {
142 protectedGpios.configure(configs);
143
144 int result = gpiochip_register(base, "protected", protectedGpios, PROTECTED_CHANNEL_COUNT);
145
146 if (result == static_cast<int>(base)) {
147 didInit = true;
148 }
149
150 return result;
151}
152
153void protectedGpio_check(efitick_t nowNt) {
154 if (didInit) {
155 protectedGpios.check(nowNt);
156 }
157}
expected< float > adcGetRawVoltage(const char *msg, adc_channel_e hwChannel)
Single output pin reference and state.
Definition efi_output.h:49
int gpiochip_register(brain_pin_e base, const char *name, GpioChip &gpioChip, size_t size)
Register gpiochip.
Definition core.cpp:186
static constexpr persistent_config_s * config
uint32_t iomode_t
Digital I/O modes.
Definition hal_pal_lld.h:83
int protectedGpio_add(brain_pin_e base, const ProtectedGpioConfig *const configs)
static bool didInit
static ProtectedGpios protectedGpios
void protectedGpio_check(efitick_t nowNt)
brain_pin_diag_e
static void check(SensorType type)
brain_pin_e pin
Definition stm32_adc.cpp:15
virtual brain_pin_diag_e getDiag(size_t)
Definition gpio_ext.h:31
virtual int writePad(size_t, int)
Definition gpio_ext.h:28
virtual int readPad(size_t)
Definition gpio_ext.h:29
virtual int init()=0
virtual int setPadMode(size_t, iomode_t)
Definition gpio_ext.h:27