1
0
Fork 0
mirror of https://github.com/opentx/opentx.git synced 2025-07-25 01:05:10 +03:00

Fixes #3233: Added ADC jitter measurement (use MEASURE_JITTER=YES to enable), Added ADC jitter filter (use JITTER_FILTER=No to disable) (ported from master)

This commit is contained in:
Damjan Adamic 2016-01-19 17:13:11 +01:00
parent c46c1f887a
commit 4aa6bd12ca
6 changed files with 256 additions and 150 deletions

View file

@ -16,6 +16,8 @@ option(DANGEROUS_MODULE_FUNCTIONS "Dangerous module functions (RangeCheck / Bind
option(FAI "Competition mode (no telemetry)" OFF)
option(AUTOSOURCE "Automatic source detection in menus" ON)
option(AUTOSWITCH "Automatic switch detection in menus" ON)
option(JITTER_MEASURE "Enable ADC jitter measurement" OFF)
option(JITTER_FILTER "Enable ADC jitter filtering" ON)
enable_language(ASM)
set(OPT s)
@ -650,6 +652,15 @@ if(AUTOSWITCH)
add_definitions(-DAUTOSWITCH)
endif()
if(JITTER_MEASURE)
add_definitions(-DJITTER_MEASURE)
endif()
if(JITTER_FILTER)
add_definitions(-DJITTER_FILTER)
endif()
if(SDCARD STREQUAL YES)
add_definitions(-DSDCARD)
include_directories(${FATFS_DIR} ${FATFS_DIR}/option)

View file

@ -383,6 +383,14 @@ WARNINGS_AS_ERRORS = NO
# Values = NO, YES
LUA_COMPILER = NO
# Enable ADC jitter measurement
# Values = NO, YES
JITTER_MEASURE = NO
# Enable ADC jitter filtering
# Values = NO, YES
JITTER_FILTER = YES
#------- END BUILD OPTIONS ---------------------------
# Define programs and commands.
@ -1079,6 +1087,12 @@ ifeq ($(PCB), TARANIS)
ifeq ($(WATCHDOG_TEST), YES)
CPPDEFS += -DWATCHDOG_TEST
endif
ifeq ($(JITTER_MEASURE), YES)
CPPDEFS += -DJITTER_MEASURE
endif
ifeq ($(JITTER_FILTER), YES)
CPPDEFS += -DJITTER_FILTER
endif
endif
ifeq ($(PCB), FLAMENCO)

View file

@ -20,139 +20,169 @@
#ifndef _DEBUG_H_
#define _DEBUG_H_
#include <inttypes.h>
#include "rtc.h"
#include "dump.h"
#if defined(CLI)
#include "cli.h"
#elif defined(CPUARM)
#include "serial.h"
#endif
#if defined(__cplusplus)
extern "C" {
#endif
#if defined(SIMU)
typedef void (*traceCallbackFunc)(const char * text);
extern traceCallbackFunc traceCallback;
void debugPrintf(const char * format, ...);
#elif defined(DEBUG) && defined(CLI) && defined(USB_SERIAL)
#define debugPrintf(...) do { if (cliTracesEnabled) serialPrintf(__VA_ARGS__); } while(0)
#elif defined(DEBUG) && defined(CLI)
uint8_t serial2TracesEnabled();
#define debugPrintf(...) do { if (serial2TracesEnabled() && cliTracesEnabled) serialPrintf(__VA_ARGS__); } while(0)
#elif defined(DEBUG) && defined(CPUARM)
uint8_t serial2TracesEnabled();
#define debugPrintf(...) do { if (serial2TracesEnabled()) serialPrintf(__VA_ARGS__); } while(0)
#else
#define debugPrintf(...)
#endif
#if defined(__cplusplus)
}
#endif
#define TRACE(...) do { debugPrintf(__VA_ARGS__); debugPrintf("\r\n"); } while(0)
#define DUMP(data, size) dump(data, size)
#define TRACE_DEBUG(...) debugPrintf("-D- " __VA_ARGS__)
#define TRACE_DEBUG_WP(...) debugPrintf(__VA_ARGS__)
#define TRACE_INFO(...) debugPrintf("-I- " __VA_ARGS__)
#define TRACE_INFO_WP(...) debugPrintf(__VA_ARGS__)
#define TRACE_WARNING(...) debugPrintf("-W- " __VA_ARGS__)
#define TRACE_WARNING_WP(...) debugPrintf(__VA_ARGS__)
#define TRACE_ERROR(...) debugPrintf("-E- " __VA_ARGS__)
#if defined(DEBUG) && !defined(SIMU)
#define TIME_MEASURE_START(id) uint16_t t0 ## id = getTmr2MHz()
#define TIME_MEASURE_STOP(id) TRACE("Measure(" # id ") = %.1fus", float((uint16_t)(getTmr2MHz() - t0 ## id))/2)
#else
#define TIME_MEASURE_START(id)
#define TIME_MEASURE_STOP(id)
#endif
#if defined(DEBUG_TRACE_BUFFER)
#define TRACE_BUFFER_LEN 50
enum TraceEvent {
trace_start = 1,
sd_wait_ready = 10,
sd_rcvr_datablock,
sd_xmit_datablock_wait_ready,
sd_xmit_datablock_rcvr_spi,
sd_send_cmd_wait_ready,
sd_send_cmd_rcvr_spi,
sd_SD_ReadSectors = 16,
sd_disk_read,
sd_SD_WriteSectors,
sd_disk_write,
sd_disk_ioctl_CTRL_SYNC = 20,
sd_disk_ioctl_GET_SECTOR_COUNT,
sd_disk_ioctl_MMC_GET_CSD,
sd_disk_ioctl_MMC_GET_CID,
sd_disk_ioctl_MMC_GET_OCR,
sd_disk_ioctl_MMC_GET_SDSTAT_1,
sd_disk_ioctl_MMC_GET_SDSTAT_2,
sd_spi_reset,
ff_f_write_validate = 30,
ff_f_write_flag,
ff_f_write_clst,
ff_f_write_sync_window,
ff_f_write_disk_write_dirty,
ff_f_write_clust2sect,
ff_f_write_disk_write,
ff_f_write_disk_read,
ff_f_write_move_window,
audio_getNextFilledBuffer_skip = 50,
};
struct TraceElement {
gtime_t time;
uint8_t time_ms;
uint8_t event;
uint32_t data;
};
void trace_event(enum TraceEvent event, uint32_t data);
void trace_event_i(enum TraceEvent event, uint32_t data);
const struct TraceElement * getTraceElement(uint16_t idx);
void dumpTraceBuffer();
#define TRACE_EVENT(condition, event, data) if (condition) { trace_event(event, data); }
#define TRACEI_EVENT(condition, event, data) if (condition) { trace_event_i(event, data); }
#else // #if defined(DEBUG_TRACE_BUFFER)
#define TRACE_EVENT(condition, event, data)
#define TRACEI_EVENT(condition, event, data)
#endif // #if defined(DEBUG_TRACE_BUFFER)
#if defined(TRACE_SD_CARD)
#define TRACE_SD_CARD_EVENT(condition, event, data) TRACE_EVENT(condition, event, data)
#else
#define TRACE_SD_CARD_EVENT(condition, event, data)
#endif
#if defined(TRACE_FATFS)
#define TRACE_FATFS_EVENT(condition, event, data) TRACE_EVENT(condition, event, data)
#else
#define TRACE_FATFS_EVENT(condition, event, data)
#endif
#if defined(TRACE_AUDIO)
#define TRACE_AUDIO_EVENT(condition, event, data) TRACE_EVENT(condition, event, data)
#define TRACEI_AUDIO_EVENT(condition, event, data) TRACEI_EVENT(condition, event, data)
#else
#define TRACE_AUDIO_EVENT(condition, event, data)
#define TRACEI_AUDIO_EVENT(condition, event, data)
#endif
#include <inttypes.h>
#include "rtc.h"
#include "dump.h"
#if defined(CLI)
#include "cli.h"
#elif defined(CPUARM)
#include "serial.h"
#endif
#if defined(__cplusplus)
extern "C" {
#endif
#if defined(SIMU)
typedef void (*traceCallbackFunc)(const char * text);
extern traceCallbackFunc traceCallback;
void debugPrintf(const char * format, ...);
#elif defined(DEBUG) && defined(CLI) && defined(USB_SERIAL)
#define debugPrintf(...) do { if (cliTracesEnabled) serialPrintf(__VA_ARGS__); } while(0)
#elif defined(DEBUG) && defined(CLI)
uint8_t serial2TracesEnabled();
#define debugPrintf(...) do { if (serial2TracesEnabled() && cliTracesEnabled) serialPrintf(__VA_ARGS__); } while(0)
#elif defined(DEBUG) && defined(CPUARM)
uint8_t serial2TracesEnabled();
#define debugPrintf(...) do { if (serial2TracesEnabled()) serialPrintf(__VA_ARGS__); } while(0)
#else
#define debugPrintf(...)
#endif
#if defined(__cplusplus)
}
#endif
#define TRACE(...) do { debugPrintf(__VA_ARGS__); debugPrintf("\r\n"); } while(0)
#define DUMP(data, size) dump(data, size)
#define TRACE_DEBUG(...) debugPrintf("-D- " __VA_ARGS__)
#define TRACE_DEBUG_WP(...) debugPrintf(__VA_ARGS__)
#define TRACE_INFO(...) debugPrintf("-I- " __VA_ARGS__)
#define TRACE_INFO_WP(...) debugPrintf(__VA_ARGS__)
#define TRACE_WARNING(...) debugPrintf("-W- " __VA_ARGS__)
#define TRACE_WARNING_WP(...) debugPrintf(__VA_ARGS__)
#define TRACE_ERROR(...) debugPrintf("-E- " __VA_ARGS__)
#if defined(DEBUG) && !defined(SIMU)
#define TIME_MEASURE_START(id) uint16_t t0 ## id = getTmr2MHz()
#define TIME_MEASURE_STOP(id) TRACE("Measure(" # id ") = %.1fus", float((uint16_t)(getTmr2MHz() - t0 ## id))/2)
#else
#define TIME_MEASURE_START(id)
#define TIME_MEASURE_STOP(id)
#endif
#if defined(DEBUG_TRACE_BUFFER)
#define TRACE_BUFFER_LEN 50
enum TraceEvent {
trace_start = 1,
sd_wait_ready = 10,
sd_rcvr_datablock,
sd_xmit_datablock_wait_ready,
sd_xmit_datablock_rcvr_spi,
sd_send_cmd_wait_ready,
sd_send_cmd_rcvr_spi,
sd_SD_ReadSectors = 16,
sd_disk_read,
sd_SD_WriteSectors,
sd_disk_write,
sd_disk_ioctl_CTRL_SYNC = 20,
sd_disk_ioctl_GET_SECTOR_COUNT,
sd_disk_ioctl_MMC_GET_CSD,
sd_disk_ioctl_MMC_GET_CID,
sd_disk_ioctl_MMC_GET_OCR,
sd_disk_ioctl_MMC_GET_SDSTAT_1,
sd_disk_ioctl_MMC_GET_SDSTAT_2,
sd_spi_reset,
ff_f_write_validate = 30,
ff_f_write_flag,
ff_f_write_clst,
ff_f_write_sync_window,
ff_f_write_disk_write_dirty,
ff_f_write_clust2sect,
ff_f_write_disk_write,
ff_f_write_disk_read,
ff_f_write_move_window,
audio_getNextFilledBuffer_skip = 50,
};
struct TraceElement {
gtime_t time;
uint8_t time_ms;
uint8_t event;
uint32_t data;
};
void trace_event(enum TraceEvent event, uint32_t data);
void trace_event_i(enum TraceEvent event, uint32_t data);
const struct TraceElement * getTraceElement(uint16_t idx);
void dumpTraceBuffer();
#define TRACE_EVENT(condition, event, data) if (condition) { trace_event(event, data); }
#define TRACEI_EVENT(condition, event, data) if (condition) { trace_event_i(event, data); }
#else // #if defined(DEBUG_TRACE_BUFFER)
#define TRACE_EVENT(condition, event, data)
#define TRACEI_EVENT(condition, event, data)
#endif // #if defined(DEBUG_TRACE_BUFFER)
#if defined(TRACE_SD_CARD)
#define TRACE_SD_CARD_EVENT(condition, event, data) TRACE_EVENT(condition, event, data)
#else
#define TRACE_SD_CARD_EVENT(condition, event, data)
#endif
#if defined(TRACE_FATFS)
#define TRACE_FATFS_EVENT(condition, event, data) TRACE_EVENT(condition, event, data)
#else
#define TRACE_FATFS_EVENT(condition, event, data)
#endif
#if defined(TRACE_AUDIO)
#define TRACE_AUDIO_EVENT(condition, event, data) TRACE_EVENT(condition, event, data)
#define TRACEI_AUDIO_EVENT(condition, event, data) TRACEI_EVENT(condition, event, data)
#else
#define TRACE_AUDIO_EVENT(condition, event, data)
#define TRACEI_AUDIO_EVENT(condition, event, data)
#endif
#if defined(JITTER_MEASURE) && defined(__cplusplus)
template<class T> class JitterMeter {
public:
T min;
T max;
T measured;
JitterMeter() : min(~(T)0), max(0), measured(0) {};
void reset() {
// store mesaurement
measured = max - min;
//reset - begin new measurement
min = ~(T)0;
max = 0;
};
void measure(T value) {
if (value > max) max = value;
if (value < min) min = value;
};
T get() const {
return measured;
};
};
#endif // defined(JITTER_MEASURE)
#endif // _DEBUG_H_

View file

@ -27,28 +27,26 @@ void menuGeneralDiagAna(uint8_t event)
STICK_SCROLL_DISABLE();
for (int i=0; i<NUM_STICKS+NUM_POTS; i++) {
#if (NUM_STICKS+NUM_POTS) > 9
coord_t y = MENU_HEADER_HEIGHT + 1 + (i/3)*FH;
const uint8_t x_coord[] = {0, 70, 154};
uint8_t x = x_coord[i%3];
coord_t y = MENU_HEADER_HEIGHT + 1 + (i/2)*FH;
uint8_t x = i&1 ? LCD_W/2 + FW : 0;
lcdDrawNumber(x, y, i+1, LEADING0|LEFT, 2);
lcdDrawChar(x+2*FW-2, y, ':');
#else
coord_t y = MENU_HEADER_HEIGHT + 1 + (i/2)*FH;
uint8_t x = i&1 ? 64+5 : 0;
drawStringWithIndex(x, y, PSTR("A"), i+1);
lcdDrawChar(lcdNextPos, y, ':');
#endif
lcdDrawHexNumber(x+3*FW-1, y, anaIn(i));
#if defined(JITTER_MEASURE)
lcdDrawNumber(x+10*FW-1, y, rawJitter[i].get());
lcdDrawNumber(x+13*FW-1, y, avgJitter[i].get());
lcdDraw8bitsNumber(x+17*FW-1, y, (int16_t)calibratedStick[CONVERT_MODE(i)]*25/256);
#else
lcdDraw8bitsNumber(x+10*FW-1, y, (int16_t)calibratedStick[CONVERT_MODE(i)]*25/256);
#endif
}
lcd_putsLeft(MENU_HEADER_HEIGHT+1+5*FH, STR_BATT_CALIB);
lcd_putsLeft(MENU_HEADER_HEIGHT+1+6*FH, STR_BATT_CALIB);
static int32_t adcBatt;
adcBatt = ((adcBatt * 7) + anaIn(TX_VOLTAGE)) / 8;
uint32_t batCalV = (adcBatt + (adcBatt*g_eeGeneral.txVoltageCalibration)/128) * BATT_SCALE;
batCalV >>= 11;
batCalV += 2; // because of the diode
putsVolts(LEN_CALIB_FIELDS*FW+4*FW, MENU_HEADER_HEIGHT+1+5*FH, batCalV, s_editMode > 0 ? BLINK|INVERS : INVERS);
putsVolts(LEN_CALIB_FIELDS*FW+4*FW, MENU_HEADER_HEIGHT+1+6*FH, batCalV, s_editMode > 0 ? BLINK|INVERS : INVERS);
if (s_editMode > 0) CHECK_INCDEC_GENVAR(event, g_eeGeneral.txVoltageCalibration, -127, 127);
}

View file

@ -1485,6 +1485,13 @@ uint16_t BandGap = 2040 ;
uint16_t BandGap ;
#endif
#if defined(JITTER_MEASURE)
JitterMeter<uint16_t> rawJitter[NUMBER_ANALOG];
JitterMeter<uint16_t> avgJitter[NUMBER_ANALOG];
tmr10ms_t jitterResetTime = 0;
#define JITTER_MEASURE_ACTIVE() (menuHandlers[menuLevel] == menuGeneralDiagAna)
#endif // defined(JITTER_MEASURE)
#if !defined(SIMU)
uint16_t anaIn(uint8_t chan)
{
@ -1521,10 +1528,28 @@ void getADC()
{
uint16_t temp[NUMBER_ANALOG] = { 0 };
#if defined(JITTER_MEASURE)
if (JITTER_MEASURE_ACTIVE() && jitterResetTime < get_tmr10ms()) {
for (uint32_t x=0; x<NUMBER_ANALOG; x++) {
rawJitter[x].reset();
avgJitter[x].reset();
}
jitterResetTime = get_tmr10ms() + 100; //every second
}
#endif
for (uint32_t i=0; i<4; i++) {
adcRead();
for (uint32_t x=0; x<NUMBER_ANALOG; x++) {
#if defined(JITTER_MEASURE)
uint16_t val = getAnalogValue(x);
if (JITTER_MEASURE_ACTIVE()) {
rawJitter[x].measure(val);
}
temp[x] += val;
#else
temp[x] += getAnalogValue(x);
#endif
}
#if defined(VIRTUALINPUTS)
if (calibrationState) break;
@ -1533,8 +1558,29 @@ void getADC()
for (uint32_t x=0; x<NUMBER_ANALOG; x++) {
uint16_t v = temp[x] >> 3;
#if defined(VIRTUALINPUTS)
if (calibrationState) v = temp[x] >> 1;
if (calibrationState) {
v = temp[x] >> 1;
}
#if defined(JITTER_FILTER)
else {
// jitter filter
uint16_t diff = (v > s_anaFilt[x]) ? (v - s_anaFilt[x]) : (s_anaFilt[x] - v);
if (diff < 10) {
// apply filter
v = (7 * s_anaFilt[x] + v) >> 3;
}
}
#endif
#if defined(JITTER_MEASURE)
if (JITTER_MEASURE_ACTIVE()) {
avgJitter[x].measure(v);
}
#endif
StepsCalibData * calib = (StepsCalibData *) &g_eeGeneral.calib[x];
if (!calibrationState && IS_POT_MULTIPOS(x) && calib->count>0 && calib->count<XPOTS_MULTIPOS_COUNT) {
uint8_t vShifted = (v >> 4);
@ -1546,9 +1592,11 @@ void getADC()
}
}
}
else
else
#endif
s_anaFilt[x] = v;
{
s_anaFilt[x] = v;
}
}
}
#endif

View file

@ -1758,4 +1758,9 @@ extern Clipboard clipboard;
extern uint16_t s_anaFilt[NUMBER_ANALOG];
#endif
#if defined(JITTER_MEASURE)
extern JitterMeter<uint16_t> rawJitter[NUMBER_ANALOG];
extern JitterMeter<uint16_t> avgJitter[NUMBER_ANALOG];
#endif // defined(JITTER_MEASURE)
#endif // _OPENTX_H_