153 lines
3.1 KiB
C++
153 lines
3.1 KiB
C++
|
|
#include "pch.h"
|
|
|
|
#include "protected_gpio.h"
|
|
#include "gpio/gpio_ext.h"
|
|
|
|
#define PROTECTED_CHANNEL_COUNT 8
|
|
|
|
class ProtectedGpio {
|
|
public:
|
|
int setPadMode(iomode_t mode);
|
|
int set(bool value);
|
|
int get() const;
|
|
brain_pin_diag_e getDiag() const;
|
|
|
|
void configure(const ProtectedGpioConfig& config);
|
|
void check(efitick_t nowNt);
|
|
|
|
private:
|
|
OutputPin m_output;
|
|
|
|
const ProtectedGpioConfig* m_config;
|
|
};
|
|
|
|
void ProtectedGpio::configure(const ProtectedGpioConfig& config) {
|
|
m_config = &config;
|
|
}
|
|
|
|
int ProtectedGpio::setPadMode(iomode_t mode) {
|
|
if (mode == PAL_MODE_OUTPUT_PUSHPULL) {
|
|
m_output.initPin("protected", m_config->Pin);
|
|
} else {
|
|
m_output.deInit();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int ProtectedGpio::set(bool value) {
|
|
if (!m_config) {
|
|
return -1;
|
|
}
|
|
|
|
// TODO: operate state machine to handle overcurrent
|
|
m_output.setValue(value);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int ProtectedGpio::get() const {
|
|
return m_output.getLogicValue();
|
|
}
|
|
|
|
void ProtectedGpio::check(efitick_t /*nowNt*/) {
|
|
if (!m_config) {
|
|
return;
|
|
}
|
|
|
|
float senseVolts = getVoltage("protected", m_config->SenseChannel);
|
|
float amps = senseVolts * m_config->AmpsPerVolt;
|
|
|
|
// TODO: smarter state machine
|
|
if (amps > m_config->MaximumAllowedCurrent) {
|
|
m_output.setValue(false);
|
|
}
|
|
}
|
|
|
|
brain_pin_diag_e ProtectedGpio::getDiag() const {
|
|
// TODO: return PIN_OVERLOAD if there's a problem
|
|
return PIN_OK;
|
|
}
|
|
|
|
class ProtectedGpios : public GpioChip {
|
|
public:
|
|
int init() override { return 0; }
|
|
int setPadMode(size_t pin, iomode_t mode) override;
|
|
int writePad(size_t pin, int value) override;
|
|
int readPad(size_t pin) override;
|
|
|
|
brain_pin_diag_e getDiag(size_t pin) override;
|
|
|
|
void configure(const ProtectedGpioConfig* const configs);
|
|
void check(efitick_t nowNt);
|
|
|
|
private:
|
|
ProtectedGpio m_channels[PROTECTED_CHANNEL_COUNT];
|
|
};
|
|
|
|
int ProtectedGpios::setPadMode(size_t pin, iomode_t mode) {
|
|
if (pin >= PROTECTED_CHANNEL_COUNT) {
|
|
return -1;
|
|
}
|
|
|
|
return m_channels[pin].setPadMode(mode);
|
|
}
|
|
|
|
int ProtectedGpios::writePad(size_t pin, int value) {
|
|
if (pin >= PROTECTED_CHANNEL_COUNT) {
|
|
return -1;
|
|
}
|
|
|
|
return m_channels[pin].set(value);
|
|
}
|
|
|
|
int ProtectedGpios::readPad(size_t pin) {
|
|
if (pin >= PROTECTED_CHANNEL_COUNT) {
|
|
return -1;
|
|
}
|
|
|
|
return m_channels[pin].get();
|
|
}
|
|
|
|
brain_pin_diag_e ProtectedGpios::getDiag(size_t pin) {
|
|
if (pin >= PROTECTED_CHANNEL_COUNT) {
|
|
return PIN_INVALID;
|
|
}
|
|
|
|
return m_channels[pin].getDiag();
|
|
}
|
|
|
|
void ProtectedGpios::configure(const ProtectedGpioConfig* const configs) {
|
|
for (size_t i = 0; i < efi::size(m_channels); i++) {
|
|
m_channels[i].configure(configs[i]);
|
|
}
|
|
}
|
|
|
|
void ProtectedGpios::check(efitick_t nowNt) {
|
|
for (size_t i = 0; i < efi::size(m_channels); i++) {
|
|
m_channels[i].check(nowNt);
|
|
}
|
|
}
|
|
|
|
static ProtectedGpios protectedGpios;
|
|
static bool didInit = false;
|
|
|
|
int protectedGpio_add(brain_pin_e base, const ProtectedGpioConfig* const configs) {
|
|
protectedGpios.configure(configs);
|
|
|
|
int result = gpiochip_register(base, "protected", protectedGpios, PROTECTED_CHANNEL_COUNT);
|
|
|
|
if (result == static_cast<int>(base)) {
|
|
didInit = true;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
void protectedGpio_check(efitick_t nowNt) {
|
|
if (didInit) {
|
|
protectedGpios.check(nowNt);
|
|
}
|
|
}
|