2015-07-10 06:01:56 -07:00
|
|
|
/**
|
|
|
|
* @file wave_analyzer.cpp
|
2019-05-02 14:52:48 -07:00
|
|
|
* @brief Initialization of Input Capture pins used for rusEfi console sniffer
|
2015-07-10 06:01:56 -07:00
|
|
|
*
|
|
|
|
* This file is responsible for sniffing of external digital signals and registering
|
2019-05-02 14:52:48 -07:00
|
|
|
* these digital events in WaveChart used by the Engine Sniffer tab of rusEfi Console.
|
2015-07-10 06:01:56 -07:00
|
|
|
*
|
2018-04-01 20:28:04 -07:00
|
|
|
* this is rusEfi build-in logic analyzer
|
2015-07-10 06:01:56 -07:00
|
|
|
*
|
|
|
|
* @date Jan 7, 2013
|
2018-01-20 17:55:31 -08:00
|
|
|
* @author Andrey Belomutskiy, (c) 2012-2018
|
2015-07-10 06:01:56 -07:00
|
|
|
*/
|
|
|
|
|
2018-09-16 19:26:57 -07:00
|
|
|
#include "global.h"
|
2019-07-03 18:48:04 -07:00
|
|
|
#include "os_access.h"
|
2015-07-10 06:01:56 -07:00
|
|
|
#include "wave_analyzer.h"
|
|
|
|
#include "eficonsole.h"
|
|
|
|
#include "data_buffer.h"
|
|
|
|
#include "pin_repository.h"
|
2019-05-27 15:58:43 -07:00
|
|
|
#include "allsensors.h"
|
2015-07-10 06:01:56 -07:00
|
|
|
#include "engine_configuration.h"
|
|
|
|
#include "trigger_central.h"
|
2019-07-06 17:15:49 -07:00
|
|
|
#include "os_util.h"
|
2015-07-10 06:01:56 -07:00
|
|
|
#include "engine_math.h"
|
|
|
|
#include "engine.h"
|
|
|
|
#include "rpm_calculator.h"
|
2015-07-15 18:01:45 -07:00
|
|
|
#include "engine_sniffer.h"
|
2015-07-10 06:01:56 -07:00
|
|
|
|
2019-04-12 19:10:57 -07:00
|
|
|
#if EFI_WAVE_ANALYZER
|
2015-07-10 06:01:56 -07:00
|
|
|
|
|
|
|
EXTERN_ENGINE;
|
|
|
|
|
|
|
|
#define CHART_RESET_DELAY 1
|
|
|
|
#define MAX_ICU_COUNT 5
|
|
|
|
|
2019-04-12 19:10:57 -07:00
|
|
|
#if EFI_ENGINE_SNIFFER
|
2015-07-10 06:01:56 -07:00
|
|
|
extern WaveChart waveChart;
|
|
|
|
#endif
|
|
|
|
extern bool hasFirmwareErrorFlag;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Difference between current 1st trigger event and previous 1st trigger event.
|
|
|
|
*/
|
|
|
|
static volatile uint32_t engineCycleDurationUs;
|
|
|
|
static volatile efitime_t previousEngineCycleTimeUs = 0;
|
|
|
|
|
|
|
|
static int waveReaderCount = 0;
|
|
|
|
static WaveReader readers[MAX_ICU_COUNT];
|
|
|
|
|
|
|
|
static Logging * logger;
|
|
|
|
|
|
|
|
static void ensureInitialized(WaveReader *reader) {
|
2019-03-08 04:01:15 -08:00
|
|
|
/*may be*/UNUSED(reader);
|
2019-01-11 14:40:00 -08:00
|
|
|
efiAssertVoid(CUSTOM_ERR_6654, reader->hw != NULL && reader->hw->started, "wave analyzer NOT INITIALIZED");
|
2015-07-10 06:01:56 -07:00
|
|
|
}
|
|
|
|
|
2019-04-12 19:10:57 -07:00
|
|
|
#if EFI_WAVE_ANALYZER
|
2015-07-10 06:01:56 -07:00
|
|
|
|
|
|
|
static void waAnaWidthCallback(WaveReader *reader) {
|
|
|
|
efitick_t nowUs = getTimeNowUs();
|
2017-01-12 06:02:19 -08:00
|
|
|
reader->riseEventCounter++;
|
2015-07-10 06:01:56 -07:00
|
|
|
reader->lastActivityTimeUs = nowUs;
|
2018-09-10 19:24:50 -07:00
|
|
|
assertIsrContext(CUSTOM_ERR_6670);
|
2019-08-18 12:04:02 -07:00
|
|
|
addEngineSnifferEvent(reader->name, PROTOCOL_ES_UP);
|
2015-07-10 06:01:56 -07:00
|
|
|
|
|
|
|
uint32_t width = nowUs - reader->periodEventTimeUs;
|
|
|
|
reader->last_wave_low_widthUs = width;
|
|
|
|
|
|
|
|
reader->signalPeriodUs = nowUs - reader->widthEventTimeUs;
|
|
|
|
reader->widthEventTimeUs = nowUs;
|
|
|
|
}
|
|
|
|
|
|
|
|
void WaveReader::onFallEvent() {
|
|
|
|
efitick_t nowUs = getTimeNowUs();
|
2017-01-12 06:02:19 -08:00
|
|
|
fallEventCounter++;
|
2015-07-10 06:01:56 -07:00
|
|
|
lastActivityTimeUs = nowUs;
|
2018-09-10 19:24:50 -07:00
|
|
|
assertIsrContext(CUSTOM_ERR_6670);
|
2019-08-18 12:04:02 -07:00
|
|
|
addEngineSnifferEvent(name, PROTOCOL_ES_DOWN);
|
2015-07-10 06:01:56 -07:00
|
|
|
|
|
|
|
efitick_t width = nowUs - widthEventTimeUs;
|
|
|
|
last_wave_high_widthUs = width;
|
|
|
|
|
2019-01-13 21:01:11 -08:00
|
|
|
int revolutionCounter = engine->rpmCalculator.getRevolutionCounter();
|
2015-07-10 06:01:56 -07:00
|
|
|
|
|
|
|
totalOnTimeAccumulatorUs += width;
|
|
|
|
if (currentRevolutionCounter != revolutionCounter) {
|
|
|
|
/**
|
|
|
|
* We are here in case of a new engine cycle
|
|
|
|
*/
|
|
|
|
currentRevolutionCounter = revolutionCounter;
|
|
|
|
prevTotalOnTimeUs = totalOnTimeAccumulatorUs;
|
|
|
|
totalOnTimeAccumulatorUs = 0;
|
|
|
|
|
|
|
|
waveOffsetUs = nowUs - previousEngineCycleTimeUs;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
periodEventTimeUs = nowUs;
|
|
|
|
|
|
|
|
// uint32_t period = engineCycleDurationUs; // local copy of volatile variable
|
|
|
|
}
|
|
|
|
|
|
|
|
static void waIcuPeriodCallback(WaveReader *reader) {
|
|
|
|
reader->onFallEvent();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void setWaveModeSilent(int index, int mode) {
|
|
|
|
WaveReader *reader = &readers[index];
|
|
|
|
|
2019-04-07 15:25:46 -07:00
|
|
|
startInputDriver("wave", reader->hw, mode);
|
2015-07-10 06:01:56 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
//static int getEventCounter(int index) {
|
|
|
|
// WaveReader *reader = &readers[index];
|
|
|
|
// ensureInitialized(reader);
|
|
|
|
// return reader->eventCounter;
|
|
|
|
//}
|
|
|
|
|
|
|
|
static void initWave(const char *name, int index) {
|
2019-01-09 19:16:30 -08:00
|
|
|
brain_pin_e brainPin = CONFIGB(logicAnalyzerPins)[index];
|
2015-07-10 06:01:56 -07:00
|
|
|
|
2019-04-11 14:33:33 -07:00
|
|
|
if (brainPin == GPIO_UNASSIGNED)
|
|
|
|
return;
|
|
|
|
|
2019-01-09 19:16:30 -08:00
|
|
|
bool mode = CONFIGB(logicAnalyzerMode)[index];
|
2015-07-10 06:01:56 -07:00
|
|
|
|
|
|
|
waveReaderCount++;
|
2018-07-25 20:03:04 -07:00
|
|
|
efiAssertVoid(CUSTOM_ERR_6655, index < MAX_ICU_COUNT, "too many ICUs");
|
2015-07-10 06:01:56 -07:00
|
|
|
WaveReader *reader = &readers[index];
|
|
|
|
reader->name = name;
|
|
|
|
|
2018-01-01 08:27:15 -08:00
|
|
|
reader->hw = addWaveAnalyzerDriver("wave input", brainPin);
|
2019-01-11 12:44:24 -08:00
|
|
|
if (reader->hw != NULL) {
|
|
|
|
reader->hw->widthListeners.registerCallback((VoidInt)(void*) waAnaWidthCallback, (void*) reader);
|
2015-07-10 06:01:56 -07:00
|
|
|
|
2019-01-11 12:44:24 -08:00
|
|
|
reader->hw->periodListeners.registerCallback((VoidInt)(void*) waIcuPeriodCallback, (void*) reader);
|
|
|
|
}
|
2015-07-10 06:01:56 -07:00
|
|
|
|
|
|
|
print("wave%d input on %s\r\n", index, hwPortname(brainPin));
|
2019-04-07 15:25:46 -07:00
|
|
|
startInputDriver("wave", reader->hw, mode);
|
2015-07-10 06:01:56 -07:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
WaveReader::WaveReader() {
|
2019-10-07 22:26:35 -07:00
|
|
|
hw = nullptr;
|
2015-07-10 06:01:56 -07:00
|
|
|
last_wave_high_widthUs = 0;
|
2019-10-07 22:26:35 -07:00
|
|
|
name = nullptr;
|
2017-01-12 06:02:19 -08:00
|
|
|
fallEventCounter = riseEventCounter = 0;
|
2016-08-31 21:02:04 -07:00
|
|
|
currentRevolutionCounter = 0;
|
|
|
|
prevTotalOnTimeUs = 0;
|
|
|
|
totalOnTimeAccumulatorUs = 0;
|
|
|
|
lastActivityTimeUs = 0;
|
|
|
|
periodEventTimeUs = 0;
|
|
|
|
widthEventTimeUs = 0;
|
|
|
|
signalPeriodUs = 0;
|
|
|
|
waveOffsetUs = 0;
|
|
|
|
last_wave_low_widthUs = 0;
|
2015-07-10 06:01:56 -07:00
|
|
|
}
|
|
|
|
|
2017-05-15 20:33:22 -07:00
|
|
|
static void waTriggerEventListener(trigger_event_e ckpSignalType, uint32_t index DECLARE_ENGINE_PARAMETER_SUFFIX) {
|
2015-07-10 06:01:56 -07:00
|
|
|
(void)ckpSignalType;
|
|
|
|
if (index != 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
efitick_t nowUs = getTimeNowUs();
|
|
|
|
engineCycleDurationUs = nowUs - previousEngineCycleTimeUs;
|
|
|
|
previousEngineCycleTimeUs = nowUs;
|
|
|
|
}
|
|
|
|
|
2019-04-14 10:52:27 -07:00
|
|
|
/*
|
2015-07-10 06:01:56 -07:00
|
|
|
static uint32_t getWaveLowWidth(int index) {
|
|
|
|
WaveReader *reader = &readers[index];
|
|
|
|
ensureInitialized(reader);
|
|
|
|
return reader->last_wave_low_widthUs;
|
|
|
|
}
|
2019-04-14 10:52:27 -07:00
|
|
|
*/
|
2015-07-10 06:01:56 -07:00
|
|
|
|
|
|
|
static float getSignalOnTime(int index) {
|
|
|
|
WaveReader *reader = &readers[index];
|
|
|
|
ensureInitialized(reader);
|
|
|
|
if (getTimeNowUs() - reader->lastActivityTimeUs > 4 * US_PER_SECOND) {
|
|
|
|
return 0.0f; // dwell time has expired
|
|
|
|
}
|
|
|
|
return reader->last_wave_high_widthUs / 1000.0f;
|
|
|
|
}
|
|
|
|
|
|
|
|
static efitime_t getWaveOffset(int index) {
|
|
|
|
WaveReader *reader = &readers[index];
|
|
|
|
ensureInitialized(reader);
|
|
|
|
return reader->waveOffsetUs;
|
|
|
|
}
|
|
|
|
|
|
|
|
static float getSignalPeriodMs(int index) {
|
|
|
|
WaveReader *reader = &readers[index];
|
|
|
|
ensureInitialized(reader);
|
|
|
|
return reader->signalPeriodUs / 1000.0f;
|
|
|
|
}
|
|
|
|
|
|
|
|
//static efitime_t getWidthEventTime(int index) {
|
|
|
|
// WaveReader *reader = &readers[index];
|
|
|
|
// ensureInitialized(reader);
|
|
|
|
// return reader->widthEventTimeUs;
|
|
|
|
//}
|
|
|
|
|
|
|
|
static void reportWave(Logging *logging, int index) {
|
2019-01-11 14:40:00 -08:00
|
|
|
if (readers[index].hw == NULL) {
|
|
|
|
return;
|
|
|
|
}
|
2015-07-10 06:01:56 -07:00
|
|
|
if (readers[index].hw->started) {
|
|
|
|
// int counter = getEventCounter(index);
|
|
|
|
// debugInt2(logging, "ev", index, counter);
|
|
|
|
|
|
|
|
float dwellMs = getSignalOnTime(index);
|
|
|
|
float periodMs = getSignalPeriodMs(index);
|
|
|
|
|
|
|
|
appendPrintf(logging, "duty%d%s", index, DELIMETER);
|
|
|
|
appendFloat(logging, 100.0f * dwellMs / periodMs, 2);
|
|
|
|
appendPrintf(logging, "%s", DELIMETER);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* that's the ON time of the LAST signal
|
|
|
|
*/
|
|
|
|
appendPrintf(logging, "dwell%d%s", index, DELIMETER);
|
|
|
|
appendFloat(logging, dwellMs, 2);
|
|
|
|
appendPrintf(logging, "%s", DELIMETER);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* that's the total ON time during the previous engine cycle
|
|
|
|
*/
|
|
|
|
appendPrintf(logging, "total_dwell%d%s", index, DELIMETER);
|
|
|
|
appendFloat(logging, readers[index].prevTotalOnTimeUs / 1000.0f, 2);
|
|
|
|
appendPrintf(logging, "%s", DELIMETER);
|
|
|
|
|
|
|
|
appendPrintf(logging, "period%d%s", index, DELIMETER);
|
|
|
|
appendFloat(logging, periodMs, 2);
|
|
|
|
appendPrintf(logging, "%s", DELIMETER);
|
|
|
|
|
|
|
|
uint32_t offsetUs = getWaveOffset(index);
|
2019-01-21 18:48:58 -08:00
|
|
|
int rpm = GET_RPM();
|
2017-12-02 15:57:52 -08:00
|
|
|
if (rpm != 0) {
|
|
|
|
float oneDegreeUs = getOneDegreeTimeUs(rpm);
|
|
|
|
|
|
|
|
appendPrintf(logging, "advance%d%s", index, DELIMETER);
|
|
|
|
float angle = (offsetUs / oneDegreeUs) - tdcPosition();
|
2018-07-23 18:38:05 -07:00
|
|
|
fixAngle(angle, "waveAn", CUSTOM_ERR_6564);
|
2017-12-02 15:57:52 -08:00
|
|
|
appendFloat(logging, angle, 3);
|
|
|
|
appendPrintf(logging, "%s", DELIMETER);
|
|
|
|
}
|
2015-07-10 06:01:56 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void printWave(Logging *logging) {
|
|
|
|
reportWave(logging, 0);
|
|
|
|
reportWave(logging, 1);
|
|
|
|
}
|
|
|
|
|
2017-01-12 06:02:19 -08:00
|
|
|
void showWaveInfo(void) {
|
|
|
|
scheduleMsg(logger, "logic input #1: %d/%d", readers[0].fallEventCounter, readers[0].riseEventCounter);
|
|
|
|
}
|
|
|
|
|
2015-07-10 06:01:56 -07:00
|
|
|
void initWaveAnalyzer(Logging *sharedLogger) {
|
|
|
|
logger = sharedLogger;
|
2016-06-01 17:01:36 -07:00
|
|
|
if (hasFirmwareError()) {
|
|
|
|
return;
|
|
|
|
}
|
2019-04-12 19:10:57 -07:00
|
|
|
#if EFI_WAVE_ANALYZER
|
2019-08-18 12:04:02 -07:00
|
|
|
initWave(PROTOCOL_WA_CHANNEL_1, 0);
|
|
|
|
initWave(PROTOCOL_WA_CHANNEL_2, 1);
|
2015-07-10 06:01:56 -07:00
|
|
|
|
2017-01-09 12:01:55 -08:00
|
|
|
addTriggerEventListener(waTriggerEventListener, "wave analyzer", engine);
|
2015-07-10 06:01:56 -07:00
|
|
|
|
2017-01-12 06:02:19 -08:00
|
|
|
addConsoleAction("waveinfo", showWaveInfo);
|
|
|
|
|
2015-07-10 06:01:56 -07:00
|
|
|
addConsoleActionII("set_logic_input_mode", setWaveModeSilent);
|
|
|
|
#else
|
|
|
|
print("wave disabled\r\n");
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|