prototype overcurrent protected driver (#4029)
* stub passthrough protected driver * plumbing * include the thing * signature * dead * tdg pdm build task * s * pdm pins * tdg * init properly * remove gaps * board doesn't fatal on start
This commit is contained in:
parent
af0fa30015
commit
c6f46128d6
|
@ -131,6 +131,22 @@
|
|||
"isDefault": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "Build Firmware (TDG PDM8)",
|
||||
"type": "shell",
|
||||
"command": "make -j12 PROJECT_BOARD=tdg-pdm8",
|
||||
"windows": {
|
||||
"command": "wsl bash -lc 'make -j12 PROJECT_BOARD=tdg-pdm8'"
|
||||
},
|
||||
"options": {
|
||||
"cwd": "${workspaceRoot}/firmware"
|
||||
},
|
||||
"problemMatcher": [],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "Build Unit Tests",
|
||||
"type": "shell",
|
||||
|
|
|
@ -5,6 +5,12 @@ PROJECT_CPU = ARCH_STM32F4
|
|||
|
||||
DDEFS += -DLED_CRITICAL_ERROR_BRAIN_PIN=Gpio::C11
|
||||
|
||||
# No serial ports for now
|
||||
DDEFS += -DTS_NO_PRIMARY=TRUE -DTS_NO_SECONDARY=TRUE
|
||||
|
||||
# No USB
|
||||
DDEFS += -DEFI_USB_SERIAL=FALSE
|
||||
|
||||
# We're running on TDG PDM hardware!
|
||||
DDEFS += -DHW_TDG_PDM8=1
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include "pch.h"
|
||||
|
||||
#include "protected_gpio.h"
|
||||
|
||||
void setSdCardConfigurationOverrides() {
|
||||
}
|
||||
|
||||
|
@ -14,3 +16,25 @@ void setBoardConfigOverrides() {
|
|||
engineConfiguration->canTxPin = Gpio::A12;
|
||||
engineConfiguration->canRxPin = Gpio::A11;
|
||||
}
|
||||
|
||||
// TODO: these are made up values
|
||||
static constexpr float AmpsPerVolt = 10;
|
||||
|
||||
// instantaneous limit is 100A
|
||||
// long-term limit is 20A
|
||||
static constexpr float MaxCurrent = 100;
|
||||
|
||||
static const ProtectedGpioConfig cfgs[] = {
|
||||
{ Gpio::A0, EFI_ADC_10, AmpsPerVolt, MaxCurrent },
|
||||
{ Gpio::A1, EFI_ADC_11, AmpsPerVolt, MaxCurrent },
|
||||
{ Gpio::A2, EFI_ADC_12, AmpsPerVolt, MaxCurrent },
|
||||
{ Gpio::A3, EFI_ADC_13, AmpsPerVolt, MaxCurrent },
|
||||
{ Gpio::C9, EFI_ADC_14, AmpsPerVolt, MaxCurrent },
|
||||
{ Gpio::A8, EFI_ADC_15, AmpsPerVolt, MaxCurrent },
|
||||
{ Gpio::A9, EFI_ADC_8, AmpsPerVolt, MaxCurrent },
|
||||
{ Gpio::A10, EFI_ADC_9, AmpsPerVolt, MaxCurrent },
|
||||
};
|
||||
|
||||
void boardInitHardware() {
|
||||
protectedGpio_add(Gpio::PROTECTED_PIN_0, cfgs);
|
||||
}
|
||||
|
|
|
@ -7,56 +7,56 @@ pins:
|
|||
ts_name: Battery Sense
|
||||
|
||||
- pin: 3/13
|
||||
id: A10
|
||||
id: PROTECTED_PIN_7
|
||||
class: outputs
|
||||
function: High Side Output
|
||||
type: hs
|
||||
ts_name: Out 8
|
||||
|
||||
- pin: 4/14
|
||||
id: A9
|
||||
id: PROTECTED_PIN_6
|
||||
class: outputs
|
||||
function: High Side Output
|
||||
type: hs
|
||||
ts_name: Out 7
|
||||
|
||||
- pin: 5/15
|
||||
id: A8
|
||||
id: PROTECTED_PIN_5
|
||||
class: outputs
|
||||
function: High Side Output
|
||||
type: hs
|
||||
ts_name: Out 6
|
||||
|
||||
- pin: 6/16
|
||||
id: C9
|
||||
id: PROTECTED_PIN_4
|
||||
class: outputs
|
||||
function: High Side Output
|
||||
type: hs
|
||||
ts_name: Out 5
|
||||
|
||||
- pin: 7/17
|
||||
id: A3
|
||||
id: PROTECTED_PIN_3
|
||||
class: outputs
|
||||
function: High Side Output
|
||||
type: hs
|
||||
ts_name: Out 4
|
||||
|
||||
- pin: 8/18
|
||||
id: A2
|
||||
id: PROTECTED_PIN_2
|
||||
class: outputs
|
||||
function: High Side Output
|
||||
type: hs
|
||||
ts_name: Out 3
|
||||
|
||||
- pin: 9/19
|
||||
id: A1
|
||||
id: PROTECTED_PIN_1
|
||||
class: outputs
|
||||
function: High Side Output
|
||||
type: hs
|
||||
ts_name: Out 2
|
||||
|
||||
- pin: 10/20
|
||||
id: A0
|
||||
id: PROTECTED_PIN_0
|
||||
class: outputs
|
||||
function: High Side Output
|
||||
type: hs
|
||||
|
|
|
@ -270,42 +270,37 @@ enum class Gpio : uint16_t {
|
|||
L9779_OUT_MRD = 247,
|
||||
L9779_PIN_KEY = 248,
|
||||
|
||||
CAN_PIN_0 = 250,
|
||||
CAN_PIN_1 = 251,
|
||||
CAN_PIN_2 = 252,
|
||||
CAN_PIN_3 = 253,
|
||||
CAN_PIN_4 = 254,
|
||||
CAN_PIN_5 = 255,
|
||||
CAN_PIN_6 = 256,
|
||||
CAN_PIN_7 = 257,
|
||||
CAN_PIN_0 = 249,
|
||||
CAN_PIN_1 = 250,
|
||||
CAN_PIN_2 = 251,
|
||||
CAN_PIN_3 = 252,
|
||||
CAN_PIN_4 = 253,
|
||||
CAN_PIN_5 = 254,
|
||||
CAN_PIN_6 = 255,
|
||||
CAN_PIN_7 = 256,
|
||||
|
||||
PROTECTED_PIN_0 = 290,
|
||||
PROTECTED_PIN_1 = 291,
|
||||
PROTECTED_PIN_2 = 292,
|
||||
PROTECTED_PIN_3 = 293,
|
||||
PROTECTED_PIN_4 = 294,
|
||||
PROTECTED_PIN_5 = 295,
|
||||
PROTECTED_PIN_6 = 296,
|
||||
PROTECTED_PIN_7 = 297,
|
||||
PROTECTED_PIN_8 = 298,
|
||||
PROTECTED_PIN_9 = 299,
|
||||
PROTECTED_PIN_10 = 300,
|
||||
PROTECTED_PIN_11 = 301,
|
||||
PROTECTED_PIN_12 = 302,
|
||||
PROTECTED_PIN_13 = 303,
|
||||
PROTECTED_PIN_14 = 304,
|
||||
PROTECTED_PIN_15 = 305,
|
||||
PROTECTED_PIN_16 = 306,
|
||||
PROTECTED_PIN_17 = 307,
|
||||
PROTECTED_PIN_0 = 257,
|
||||
PROTECTED_PIN_1 = 258,
|
||||
PROTECTED_PIN_2 = 259,
|
||||
PROTECTED_PIN_3 = 260,
|
||||
PROTECTED_PIN_4 = 261,
|
||||
PROTECTED_PIN_5 = 262,
|
||||
PROTECTED_PIN_6 = 263,
|
||||
PROTECTED_PIN_7 = 264,
|
||||
PROTECTED_PIN_8 = 265,
|
||||
PROTECTED_PIN_9 = 266,
|
||||
PROTECTED_PIN_10 = 267,
|
||||
PROTECTED_PIN_11 = 268,
|
||||
PROTECTED_PIN_12 = 269,
|
||||
PROTECTED_PIN_13 = 270,
|
||||
PROTECTED_PIN_14 = 271,
|
||||
PROTECTED_PIN_15 = 272,
|
||||
};
|
||||
|
||||
/* Please keep updating these defines */
|
||||
#ifndef BRAIN_PIN_ONCHIP_LAST
|
||||
#define BRAIN_PIN_ONCHIP_LAST Gpio::I15
|
||||
#endif
|
||||
|
||||
#define BRAIN_PIN_ONCHIP_PINS (BRAIN_PIN_ONCHIP_LAST - Gpio::A0 + 1)
|
||||
#define BRAIN_PIN_LAST Gpio::L9779_PIN_KEY
|
||||
#define BRAIN_PIN_LAST Gpio::PROTECTED_PIN_15
|
||||
#define BRAIN_PIN_TOTAL_PINS (BRAIN_PIN_LAST - Gpio::A0 + 1)
|
||||
|
||||
/**
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "AdcConfiguration.h"
|
||||
#include "mpu_util.h"
|
||||
#include "periodic_thread_controller.h"
|
||||
#include "protected_gpio.h"
|
||||
|
||||
/* Depth of the conversion buffer, channels are sampled X times each.*/
|
||||
#ifndef ADC_BUF_DEPTH_FAST
|
||||
|
@ -387,6 +388,8 @@ public:
|
|||
slowAdcCounter++;
|
||||
|
||||
AdcSubscription::UpdateSubscribers(nowNt);
|
||||
|
||||
protectedGpio_check(nowNt);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -26,4 +26,5 @@ HW_LAYER_DRIVERS_CPP = \
|
|||
$(DRIVERS_DIR)/gpio/mc33810.cpp \
|
||||
$(DRIVERS_DIR)/gpio/drv8860.cpp \
|
||||
$(DRIVERS_DIR)/gpio/l9779.cpp \
|
||||
$(DRIVERS_DIR)/gpio/protected_gpio.cpp \
|
||||
$(DRIVERS_DIR)/lcd/HD44780.cpp \
|
||||
|
|
|
@ -0,0 +1,152 @@
|
|||
|
||||
#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);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
#pragma once
|
||||
|
||||
struct ProtectedGpioConfig {
|
||||
// Output config
|
||||
brain_pin_e Pin;
|
||||
|
||||
// Sense config
|
||||
adc_channel_e SenseChannel;
|
||||
float AmpsPerVolt;
|
||||
|
||||
// Instantaneous trip current
|
||||
float MaximumAllowedCurrent;
|
||||
};
|
||||
|
||||
int protectedGpio_add(brain_pin_e base, const ProtectedGpioConfig* const configs);
|
||||
void protectedGpio_check(efitick_t nowNt);
|
Loading…
Reference in New Issue