custom verbose can format (#1200)

* config

* ts

* default cfg

* hand generate

* tx struct helper

* add data sending

* wire up

* value_or helper

* add file

* more sensors

* header

* compactify

* add status frame

Co-authored-by: Matthew Kennedy <makenne@microsoft.com>
This commit is contained in:
Matthew Kennedy 2020-03-19 14:58:46 -07:00 committed by GitHub
parent 30cdeb0d7f
commit 7b44f618e7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 168 additions and 0 deletions

View File

@ -26,6 +26,11 @@ CanWrite::CanWrite()
void CanWrite::PeriodicTask(efitime_t nowNt) {
UNUSED(nowNt);
if (CONFIG(enableVerboseCanTx)) {
void sendCanVerbose();
sendCanVerbose();
}
// Transmit dash data, if enabled
switch (CONFIG(canNbcType)) {
case CAN_BUS_NBC_BMW:

View File

@ -0,0 +1,146 @@
#include "globalaccess.h"
#if EFI_CAN_SUPPORT
#include "engine.h"
#include "scaled_channel.h"
#include "can_msg_tx.h"
#include "sensor.h"
#include "allsensors.h"
#include "fuel_math.h"
#include "spark_logic.h"
#include "vehicle_speed.h"
EXTERN_ENGINE;
struct Status {
uint16_t warningCounter;
uint16_t lastErrorCode;
uint8_t revLimit : 1;
uint8_t mainRelay : 1;
uint8_t fuelPump : 1;
uint8_t checkEngine : 1;
uint8_t o2Heater : 1;
uint8_t pad6 : 1;
uint8_t pad7 : 1;
uint8_t pad8 : 1;
uint8_t pad[3];
};
static void populateFrame(Status& msg) {
msg.warningCounter = engine->engineState.warnings.warningCounter;
msg.lastErrorCode = engine->engineState.warnings.lastErrorCode;
msg.revLimit = GET_RPM() > CONFIG(rpmHardLimit);
msg.mainRelay = enginePins.mainRelay.getLogicValue();
msg.fuelPump = enginePins.fuelPumpRelay.getLogicValue();
msg.checkEngine = enginePins.checkEnginePin.getLogicValue();
msg.o2Heater = enginePins.o2heater.getLogicValue();
}
struct Speeds {
uint16_t rpm;
scaled_angle timing;
scaled_channel<uint8_t, 2> injDuty;
scaled_channel<uint8_t, 2> coilDuty;
scaled_channel<uint8_t> vssKph;
uint8_t pad[1];
};
static void populateFrame(Speeds& msg) {
auto rpm = GET_RPM();
msg.rpm = rpm;
auto timing = engine->engineState.timingAdvance;
msg.timing = timing > 360 ? timing - 720 : timing;
msg.injDuty = getInjectorDutyCycle(rpm);
msg.coilDuty = getCoilDutyCycle(rpm);
msg.vssKph = getVehicleSpeed();
}
struct PedalAndTps {
scaled_percent pedal;
scaled_percent tps1;
scaled_percent tps2;
uint8_t pad[2];
};
static void populateFrame(PedalAndTps& msg)
{
msg.pedal = getPedalPosition();
msg.tps1 = Sensor::get(SensorType::Tps1).value_or(-1);
msg.tps2 = Sensor::get(SensorType::Tps2).value_or(-1);
}
struct Sensors1 {
scaled_pressure map;
scaled_channel<uint8_t> clt;
scaled_channel<uint8_t> iat;
scaled_channel<uint8_t> aux1;
scaled_channel<uint8_t> aux2;
scaled_channel<uint8_t> mcuTemp;
scaled_channel<uint8_t, 2> fuelLevel;
};
static void populateFrame(Sensors1& msg) {
msg.map = getMap();
msg.clt = getCoolantTemperature() + 40;
msg.iat = getIntakeAirTemperature() + 40;
// todo: does aux temp even work?
msg.aux1 = 0 + 40;
msg.aux2 = 0 + 40;
msg.mcuTemp = getMCUInternalTemperature();
msg.fuelLevel = engine->sensors.fuelTankLevel;
}
struct Sensors2 {
scaled_afr afr;
scaled_pressure oilPressure;
scaled_angle vvtPos;
scaled_voltage vbatt;
};
static void populateFrame(Sensors2& msg) {
msg.afr = getAfr();
msg.oilPressure = Sensor::get(SensorType::OilPressure).value_or(-1);
msg.vvtPos = engine->triggerCentral.getVVTPosition();
msg.vbatt = getVBatt();
}
struct Fueling {
scaled_channel<uint16_t, 1000> cylAirmass;
scaled_channel<uint16_t, 100> estAirflow;
scaled_ms fuel_pulse;
scaled_percent stft;
};
static void populateFrame(Fueling& msg) {
msg.cylAirmass = engine->engineState.sd.airMassInOneCylinder;
msg.estAirflow = engine->engineState.airFlow;
msg.fuel_pulse = engine->actualLastInjection;
// todo
msg.stft = 0;
}
void sendCanVerbose() {
auto base = CONFIG(verboseCanBaseAddress);
transmitStruct<Status> (base + 0);
transmitStruct<Speeds> (base + 1);
transmitStruct<PedalAndTps> (base + 2);
transmitStruct<Sensors1> (base + 3);
transmitStruct<Sensors2> (base + 4);
transmitStruct<Fueling> (base + 5);
}
#endif // EFI_CAN_SUPPORT

View File

@ -35,6 +35,7 @@ CONTROLLERS_SRC_CPP = \
$(CONTROLLERS_DIR)/flash_main.cpp \
$(CONTROLLERS_DIR)/injector_central.cpp \
$(CONTROLLERS_DIR)/can/obd2.cpp \
$(CONTROLLERS_DIR)/can/can_verbose.cpp \
$(CONTROLLERS_DIR)/can/can_rx.cpp \
$(CONTROLLERS_DIR)/can/can_tx.cpp \
$(CONTROLLERS_DIR)/can/can_dash.cpp \

View File

@ -59,6 +59,11 @@ struct SensorResult {
constexpr explicit operator bool() const {
return Valid;
}
// Easy default value handling
constexpr float value_or(float valueIfInvalid) const {
return Valid ? Value : valueIfInvalid;
}
};
// Fwd declare - nobody outside of Sensor.cpp needs to see inside this type

View File

@ -83,4 +83,15 @@ public:
TData* operator->() {
return reinterpret_cast<TData*>(&m_frame.data8);
}
TData& get() {
return *reinterpret_cast<TData*>(&m_frame.data8);
}
};
template <typename TData>
void transmitStruct(uint32_t eid)
{
CanTxTyped<TData> frame(eid);
populateFrame(frame.get());
}