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:
Matthew Kennedy 2022-05-17 20:49:18 -07:00 committed by GitHub
parent af0fa30015
commit c6f46128d6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 251 additions and 38 deletions

16
.vscode/tasks.json vendored
View File

@ -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",

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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)
/**

View File

@ -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);
}
}
};

View File

@ -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 \

View File

@ -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);
}
}

View File

@ -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);