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:
parent
30cdeb0d7f
commit
7b44f618e7
|
@ -26,6 +26,11 @@ CanWrite::CanWrite()
|
||||||
void CanWrite::PeriodicTask(efitime_t nowNt) {
|
void CanWrite::PeriodicTask(efitime_t nowNt) {
|
||||||
UNUSED(nowNt);
|
UNUSED(nowNt);
|
||||||
|
|
||||||
|
if (CONFIG(enableVerboseCanTx)) {
|
||||||
|
void sendCanVerbose();
|
||||||
|
sendCanVerbose();
|
||||||
|
}
|
||||||
|
|
||||||
// Transmit dash data, if enabled
|
// Transmit dash data, if enabled
|
||||||
switch (CONFIG(canNbcType)) {
|
switch (CONFIG(canNbcType)) {
|
||||||
case CAN_BUS_NBC_BMW:
|
case CAN_BUS_NBC_BMW:
|
||||||
|
|
|
@ -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
|
|
@ -35,6 +35,7 @@ CONTROLLERS_SRC_CPP = \
|
||||||
$(CONTROLLERS_DIR)/flash_main.cpp \
|
$(CONTROLLERS_DIR)/flash_main.cpp \
|
||||||
$(CONTROLLERS_DIR)/injector_central.cpp \
|
$(CONTROLLERS_DIR)/injector_central.cpp \
|
||||||
$(CONTROLLERS_DIR)/can/obd2.cpp \
|
$(CONTROLLERS_DIR)/can/obd2.cpp \
|
||||||
|
$(CONTROLLERS_DIR)/can/can_verbose.cpp \
|
||||||
$(CONTROLLERS_DIR)/can/can_rx.cpp \
|
$(CONTROLLERS_DIR)/can/can_rx.cpp \
|
||||||
$(CONTROLLERS_DIR)/can/can_tx.cpp \
|
$(CONTROLLERS_DIR)/can/can_tx.cpp \
|
||||||
$(CONTROLLERS_DIR)/can/can_dash.cpp \
|
$(CONTROLLERS_DIR)/can/can_dash.cpp \
|
||||||
|
|
|
@ -59,6 +59,11 @@ struct SensorResult {
|
||||||
constexpr explicit operator bool() const {
|
constexpr explicit operator bool() const {
|
||||||
return Valid;
|
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
|
// Fwd declare - nobody outside of Sensor.cpp needs to see inside this type
|
||||||
|
|
|
@ -83,4 +83,15 @@ public:
|
||||||
TData* operator->() {
|
TData* operator->() {
|
||||||
return reinterpret_cast<TData*>(&m_frame.data8);
|
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());
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue