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

Logs and Telemetry decorrelated. Telemetry helpers. Possibility to reset the altitude. Flash optimizations.

This commit is contained in:
bsongis 2012-01-09 18:52:22 +00:00
parent 9e0fd2a3d2
commit a6e6a2dd12
17 changed files with 342 additions and 322 deletions

View file

@ -97,6 +97,10 @@ FRSKY_HUB = YES
# Values = YES, NO
WS_HOW_HIGH = YES
# SDCARD Logs
# Values = YES, NO
LOGS = YES
# PXX (FrSky PCM) protocol
PXX = NO
@ -216,6 +220,7 @@ ifeq ($(NAVIGATION), POTS)
CPPDEFS += -DNAVIGATION_POT1 -DNAVIGATION_POT2 -DNAVIGATION_POT3
endif
MODS =
ifeq ($(PCB), STD)
# STD PCB, so ...
@ -286,6 +291,11 @@ else
ifeq ($(PCB), V3)
CPPDEFS += -DBEEPSPKR
endif
ifeq ($(LOGS), YES)
CPPSRC += logs.cpp
CPPDEFS += -DLOGS
MODS += L
endif
ifeq ($(PCB), V4)
CPPDEFS += -DPCBV4
# Temporary hack to get stock beeper working for testing, etc ... make BEEPER=BUZZER_MOD

View file

@ -19,8 +19,6 @@
*/
#include "gruvin9x.h"
#include "frsky.h"
#include "ff.h" // TODO
// Enumerate FrSky packet codes
#define LINKPKT 0xfe
@ -57,6 +55,7 @@ struct FrskyAlarm frskyAlarms[4];
#if defined(FRSKY_HUB) || defined(WS_HOW_HIGH)
FrskyHubData frskyHubData;
int16_t baroAltitudeOffset = 0;
#endif
void frskyPushValue(uint8_t *&ptr, uint8_t value)
@ -500,100 +499,12 @@ void FrskyData::set(uint8_t value)
min = value;
}
// TODO not here!
#if defined (PCBV3)
char g_logFilename[22]; // "/G9XLOGS/M00_000.TXT\0" max required length = 21
// These global so we can close any open file from anywhere
FATFS FATFS_Obj;
FIL g_oLogFile;
#endif
void resetTelemetry()
{
memset(frskyTelemetry, 0, sizeof(frskyTelemetry));
memset(frskyRSSI, 0, sizeof(frskyRSSI));
#if defined (PCBV3)
// Determine and set log file filename
FRESULT result;
// close any file left open. E.G. Changing models with log switch still on.
if (g_oLogFile.fs) f_close(&g_oLogFile);
strcpy(g_logFilename, "/G9XLOGS/M00_000.TXT");
uint8_t num = g_eeGeneral.currModel + 1;
char *n = &g_logFilename[11];
*n = (char)((num % 10) + '0');
*(--n) = (char)((num / 10) + '0');
result = f_mount(0, &FATFS_Obj);
if (result!=FR_OK)
{
strcpy(g_logFilename, "FILE SYSTEM ERROR");
}
else
{
// Skip over any existing log files ... _000, _001, etc. (or find first gap in numbering)
while (1)
{
result = f_open(&g_oLogFile, g_logFilename, FA_OPEN_EXISTING | FA_READ);
if (result == FR_OK)
{
f_close(&g_oLogFile);
// bump log file counter (file extension)
n = &g_logFilename[15];
if (++*n > '9')
{
*n='0';
n--;
if (++*n > '9')
{
*n='0';
n--;
if (++*n > '9')
{
*n='0';
break; // Wow. We looped back around past 999 to 000! abort loop
}
}
}
}
else if (result == FR_NO_PATH)
{
if (f_mkdir("/G9XLOGS") != FR_OK)
{
result = FR_NO_PATH;
break;
}
else
continue;
}
else
break;
}
switch (result)
{
case FR_NO_PATH:
strcpy(g_logFilename, "Check /G9XLOGS folder");
break;
case FR_NOT_READY:
strcpy(g_logFilename, "DATA CARD NOT PRESENT");
break;
default:
break;
}
}
// g_logFilename should now be set appropriately.
#if defined(FRSKY_HUB) || defined(WS_HOW_HIGH)
baroAltitudeOffset = -frskyHubData.baroAltitude;
#endif
}

View file

@ -76,12 +76,18 @@ struct FrskyHubData {
int16_t accelY; // 1/256th gram (-8g ~ +8g)
int16_t accelZ; // 1/256th gram (-8g ~ +8g)
};
extern FrskyHubData frskyHubData;
#elif defined(WS_HOW_HIGH)
struct FrskyHubData {
uint16_t baroAltitude; // 0..9,999 meters
};
#endif
#if defined(FRSKY_HUB) || defined(WS_HOW_HIGH)
extern FrskyHubData frskyHubData;
extern int16_t baroAltitudeOffset;
#endif
// Global Fr-Sky telemetry data variables

View file

@ -25,7 +25,7 @@
// MM/SD card Disk IO Support
#if defined (PCBV3)
time_t g_unixTime; // Global date/time register, incremented each second in per10ms()
gtime_t g_unixTime; // Global date/time register, incremented each second in per10ms()
#endif
/*
@ -1194,7 +1194,7 @@ uint16_t active_functions = 0; // current max = 16 functions
void evalFunctions()
{
assert(sizeof(active_functions)*8 >= FUNC_LAST);
assert(sizeof(active_functions)*8 > FUNC_MAX);
for (uint8_t i=0; i<NUM_FSW; i++) {
FuncSwData *sd = &g_model.funcSw[i];
@ -1590,65 +1590,11 @@ void perMain()
if (trimsCheckTimer > 0)
trimsCheckTimer -= 1;
#if defined (FRSKY)
/***** TEST CODE - Fr-Sky SD/MMC card / User Data experiments *****/
#if defined (PCBV3)
/* Use light switch (on) to open telemtry test log file */
static FRESULT result;
static int8_t testLogOpen = 0;
if(getSwitch(g_eeGeneral.lightSw,0))
{
// while(1); // Test WDT
if ((testLogOpen==0) // if we know we haven't started logging ...
|| ((testLogOpen==1) && !g_oLogFile.fs)) // ... or we thought we had, but the file got closed
{
result = f_mount(0, &FATFS_Obj);
if (result!=FR_OK)
{
testLogOpen = -1;
beepAgain = result - 1;
beepKey();
}
else
{
// create new log file using filename set up in pers.cpp::resetTelemetry()
result = f_open(&g_oLogFile, g_logFilename, FA_OPEN_ALWAYS | FA_WRITE);
if (result!=FR_OK)
{
testLogOpen = -2;
beepAgain = result - 1;
beepKey();
}
else
{
f_lseek(&g_oLogFile, g_oLogFile.fsize); // append
testLogOpen = 1;
beepWarn2();
}
}
}
}
else
{
if (testLogOpen==1)
{
f_close(&g_oLogFile);
beepWarn2();
}
testLogOpen = 0;
}
#ifdef DISPLAY_USER_DATA
////////////////
// Write raw user data into on-screen display line buffer
#if defined (LOGS)
doLogs();
#endif
#if defined(FRSKY) and defined(DISPLAY_USER_DATA)
char userDataRxBuffer[21]; // Temp buffer used to collect fr-sky user data
// retrieve bytes from user data buffer and insert into display string,
@ -1672,14 +1618,6 @@ void perMain()
f_putc(userDataRxBuffer[byt], &g_oLogFile);
}
////////////////
#endif
/***** END TEST CODE - Fr-Sky User Data experiments *****/
// PCBV3
#endif
// FRSKY
#endif
lcd_clear();

View file

@ -304,7 +304,12 @@ enum EnumKeys {
#define CSWITCH_STR "---- v>ofs v<ofs |v|>ofs|v|<ofsAND OR XOR ""v1==v2 ""v1!=v2 ""v1>v2 ""v1<v2 ""v1>=v2 ""v1<=v2 "
#define CSW_LEN_FUNC 7
#define FSWITCH_STR "---- ""Trainer ""Trainer RUD ""Trainer ELE ""Trainer THR ""Trainer AIL ""Instant Trim ""Trims2Offsets ""Telemetry View"
#ifdef LOGS
#define LOGS_STR "SDCARD Logs "
#else
#define LOGS_STR
#endif
#define FSWITCH_STR "---- ""Trainer ""Trainer RUD ""Trainer ELE ""Trainer THR ""Trainer AIL ""Instant Trim ""Trims2Offsets "LOGS_STR
#define FSW_LEN_FUNC 14
#define SWASH_TYPE_STR "--- ""120 ""120X ""140 ""90 "
@ -553,6 +558,7 @@ extern uint8_t s_eeDirtyMsk;
#define FORCEINLINE inline __attribute__ ((always_inline))
#endif
/// liefert Betrag des Arguments
template<class t> FORCEINLINE t abs(t a){ return a>0?a:-a; }
/// liefert das Minimum der Argumente
@ -608,13 +614,12 @@ extern inline uint16_t get_tmr10ms()
#define TMR_VAROFS 16
#define SUB_MODE_V 1
#define SUB_MODE_H 2
#define SUB_MODE_H_DBL 3
void setupPulses();
void initTemplates();
#ifdef LOGS
extern void startLogs();
extern void doLogs();
#endif
#include "lcd.h"
extern const char stamp1[];
@ -714,7 +719,7 @@ inline void _beepSpkr(uint8_t d, uint8_t f)
#if defined (PCBV3)
#include "rtc.h"
extern void disk_timerproc(void);
extern time_t g_unixTime; // global unix timestamp -- hold current time in seconds since 1970-01-01 00:00:00
extern gtime_t g_unixTime; // global unix timestamp -- hold current time in seconds since 1970-01-01 00:00:00
extern uint8_t g_ms100; // defined in drivers.cpp
#endif

View file

@ -73,17 +73,17 @@
: ~ (~ (t) 0 << (sizeof (t) * CHAR_BIT - 1))))
#ifndef TIME_T_MIN
# define TIME_T_MIN TYPE_MINIMUM (time_t)
# define TIME_T_MIN TYPE_MINIMUM (gtime_t)
#endif
#ifndef TIME_T_MAX
# define TIME_T_MAX TYPE_MAXIMUM (time_t)
# define TIME_T_MAX TYPE_MAXIMUM (gtime_t)
#endif
#define TIME_T_MIDPOINT (SHR (TIME_T_MIN + TIME_T_MAX, 1) + 1)
/* Verify a requirement at compile-time (unlike assert, which is runtime). */
#define verify(name, assertion) struct name { char a[(assertion) ? 1 : -1]; }
verify (time_t_is_integer, TYPE_IS_INTEGER (time_t));
verify (gtime_t_is_integer, TYPE_IS_INTEGER (gtime_t));
verify (twos_complement_arithmetic, TYPE_TWOS_COMPLEMENT (int));
/* The code also assumes that signed integer overflow silently wraps
around, but this assumption can't be stated without causing a
@ -95,7 +95,6 @@ verify (base_year_is_a_multiple_of_100, TM_YEAR_BASE % 100 == 0);
#define SECS_PER_HOUR 3600ul
#define SECS_PER_DAY 86400ul
#define EOVERFLOW 0
/* Return 1 if YEAR + TM_YEAR_BASE is a leap year. */
static inline int
@ -123,7 +122,7 @@ const unsigned short int __mon_yday[2][13] =
Return nonzero if successful. */
int
__offtime (
time_t *t,
gtime_t *t,
long int offset,
struct gtm *tp)
{
@ -138,7 +137,7 @@ __offtime (
rem += SECS_PER_DAY;
--days;
}
while (rem >= SECS_PER_DAY)
while (rem >= (long int)SECS_PER_DAY)
{
rem -= SECS_PER_DAY;
++days;
@ -185,9 +184,9 @@ __offtime (
}
/* time_r function implementations */
// G: No time zones in our implementation so just do the converion from time_t to struct tm
// G: No time zones in our implementation so just do the converion from gtime_t to struct tm
struct gtm *
__localtime_r (time_t * t, struct gtm * tp)
__localtime_r (gtime_t * t, struct gtm * tp)
{
__offtime(t, 0, tp);
return tp;
@ -205,7 +204,7 @@ __localtime_r (time_t * t, struct gtm * tp)
The result may overflow. It is the caller's responsibility to
detect overflow. */
static inline time_t
static inline gtime_t
ydhms_diff (long int year1, long int yday1, int hour1, int min1, int sec1,
int year0, int yday0, int hour0, int min0, int sec0)
{
@ -223,34 +222,34 @@ ydhms_diff (long int year1, long int yday1, int hour1, int min1, int sec1,
int b400 = SHR (b100, 2);
int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
/* Compute the desired time in time_t precision. Overflow might
/* Compute the desired time in gtime_t precision. Overflow might
occur here. */
time_t tyear1 = year1;
time_t years = tyear1 - year0;
time_t days = 365 * years + yday1 - yday0 + intervening_leap_days;
time_t hours = 24 * days + hour1 - hour0;
time_t minutes = 60 * hours + min1 - min0;
time_t seconds = 60 * minutes + sec1 - sec0;
gtime_t tyear1 = year1;
gtime_t years = tyear1 - year0;
gtime_t days = 365 * years + yday1 - yday0 + intervening_leap_days;
gtime_t hours = 24 * days + hour1 - hour0;
gtime_t minutes = 60 * hours + min1 - min0;
gtime_t seconds = 60 * minutes + sec1 - sec0;
return seconds;
}
/* Return a time_t value corresponding to (YEAR-YDAY HOUR:MIN:SEC),
/* Return a gtime_t value corresponding to (YEAR-YDAY HOUR:MIN:SEC),
assuming that *T corresponds to *TP and that no clock adjustments
occurred between *TP and the desired time.
If TP is null, return a value not equal to *T; this avoids false matches.
If overflow occurs, yield the minimal or maximal value, except do not
yield a value equal to *T. */
static time_t
static gtime_t
guess_time_tm (long int year, long int yday, int hour, int min, int sec,
time_t *t, struct gtm *tp)
gtime_t *t, struct gtm *tp)
{
if (tp)
{
time_t d = ydhms_diff (year, yday, hour, min, sec,
gtime_t d = ydhms_diff (year, yday, hour, min, sec,
tp->tm_year, tp->tm_yday,
tp->tm_hour, tp->tm_min, tp->tm_sec);
time_t t1 = *t + d;
if ((t1 < *t) == (TYPE_SIGNED (time_t) ? d < 0 : TIME_T_MAX / 2 < d))
gtime_t t1 = *t + d;
if ((t1 < *t) == (TYPE_SIGNED (gtime_t) ? d < 0 : TIME_T_MAX / 2 < d))
return t1;
}
@ -268,22 +267,22 @@ guess_time_tm (long int year, long int yday, int hour, int min, int sec,
If *T is out of range for conversion, adjust it so that
it is the nearest in-range value and then convert that. */
static struct gtm *
ranged_convert (struct gtm *(*convert) (time_t *, struct gtm *),
time_t *t, struct gtm *tp)
ranged_convert (struct gtm *(*convert) (gtime_t *, struct gtm *),
gtime_t *t, struct gtm *tp)
{
struct gtm *r = convert (t, tp);
if (!r && *t)
{
time_t bad = *t;
time_t ok = 0;
gtime_t bad = *t;
gtime_t ok = 0;
/* BAD is a known unconvertible time_t, and OK is a known good one.
/* BAD is a known unconvertible gtime_t, and OK is a known good one.
Use binary search to narrow the range between BAD and OK until
they differ by 1. */
while (bad != ok + (bad < 0 ? -1 : 1))
{
time_t mid = *t = (bad < 0
gtime_t mid = *t = (bad < 0
? bad + ((ok - bad) >> 1)
: ok + ((bad - ok) >> 1));
r = convert (t, tp);
@ -305,18 +304,18 @@ ranged_convert (struct gtm *(*convert) (time_t *, struct gtm *),
return r;
}
/* Convert *TP to a time_t value, inverting
/* Convert *TP to a gtime_t value, inverting
the monotonic and mostly-unit-linear conversion function CONVERT.
Use *OFFSET to keep track of a guess at the offset of the result,
compared to what the result would be for UTC without leap seconds.
If *OFFSET's guess is correct, only one CONVERT call is needed.
This function is external because it is used also by timegm.c. */
time_t
gtime_t
__mktime_internal (struct gtm *tp,
struct gtm *(*convert) (time_t *, struct gtm *),
time_t *offset)
struct gtm *(*convert) (gtime_t *, struct gtm *),
gtime_t *offset)
{
time_t t, gt, t0, t1, t2;
gtime_t t, gt, t0, t1, t2;
struct gtm tm;
/* The maximum number of probes (calls to CONVERT) should be enough
@ -343,7 +342,7 @@ __mktime_internal (struct gtm *tp,
/* The other values need not be in range:
the remaining code handles minor overflows correctly,
assuming int and time_t arithmetic wraps around.
assuming int and gtime_t arithmetic wraps around.
Major overflows are caught at the end. */
/* Calculate day of year from year, month, and day of month.
@ -354,7 +353,7 @@ __mktime_internal (struct gtm *tp,
long int lmday = mday;
long int yday = mon_yday + lmday;
time_t guessed_offset = *offset;
gtime_t guessed_offset = *offset;
int sec_requested = sec;
@ -378,7 +377,7 @@ __mktime_internal (struct gtm *tp,
if (TIME_T_MAX / INT_MAX / 366 / 24 / 60 / 60 < 3)
{
/* time_t isn't large enough to rule out overflows, so check
/* gtime_t isn't large enough to rule out overflows, so check
for major overflows. A gross check suffices, since if t0
has overflowed, it is off by a multiple of TIME_T_MAX -
TIME_T_MIN + 1. So ignore any component of the difference
@ -414,16 +413,16 @@ __mktime_internal (struct gtm *tp,
gives a positive value of 715827882. Setting a variable
first then doing math on it seems to work.
(ghazi@caip.rutgers.edu) */
time_t time_t_max = TIME_T_MAX;
time_t time_t_min = TIME_T_MIN;
time_t overflow_threshold =
gtime_t time_t_max = TIME_T_MAX;
gtime_t time_t_min = TIME_T_MIN;
gtime_t overflow_threshold =
(time_t_max / 3 - time_t_min / 3) >> ALOG2_SECONDS_PER_BIENNIUM;
if (overflow_threshold < abs_diff)
{
/* Overflow occurred. Try repairing it; this might work if
the time zone offset is enough to undo the overflow. */
time_t repaired_t0 = -1 - t0;
gtime_t repaired_t0 = -1 - t0;
approx_biennia = SHR (repaired_t0, ALOG2_SECONDS_PER_BIENNIUM);
diff = approx_biennia - approx_requested_biennia;
abs_diff = diff < 0 ? - diff : diff;
@ -467,18 +466,18 @@ __mktime_internal (struct gtm *tp,
return t;
}
/* Convert *TP to a time_t value. */
time_t
/* Convert *TP to a gtime_t value. */
gtime_t
mktime (struct gtm *tp)
{
// no time zone stuff. Just do the math ;)
static time_t localtime_offset;
static gtime_t localtime_offset;
return __mktime_internal (tp, __localtime_r, &localtime_offset);
}
/* Fill a (struct tm) TP* from a given time_t time stamp */
time_t
filltm(time_t *t, struct gtm *tp)
/* Fill a (struct tm) TP* from a given gtime_t time stamp */
gtime_t
filltm(gtime_t *t, struct gtm *tp)
{
return __offtime(t, 0, tp);
}

View file

@ -23,16 +23,12 @@
#define g9x_time_h
#include <inttypes.h>
#include <limits.h>
#undef CHAR_BIT
#define CHAR_BIT 8
#define INT_MAX 32767
#define INT_MIN -32767
#define LONG_MAX 0x7FFFFFFFL
#define LONG_MIN ((long) 0x80000000L)
#define UINT_MAX 0xFFFFU/0xFFFFFFFFUL
#define ULONG_MAX 0xFFFFFFFFUL
typedef long int time_t;
typedef long int gtime_t;
struct gtm
{
@ -48,8 +44,8 @@ struct gtm
extern const unsigned short int __mon_yday[2][13];
extern time_t mktime(struct gtm *tp);
extern time_t filltm(time_t *t, struct gtm *tp);
extern gtime_t mktime(struct gtm *tp);
extern gtime_t filltm(gtime_t *t, struct gtm *tp);
#endif

View file

@ -387,7 +387,7 @@ void putsTime(uint8_t x,uint8_t y,int16_t tme,uint8_t att,uint8_t att2)
void putsVolts(uint8_t x, uint8_t y, uint16_t volts, uint8_t att)
{
lcd_outdezAtt(x, y, (int16_t)volts, att|PREC1|UNSIGN);
lcd_outdezAtt(x, y, (int16_t)volts, att | ((att&PREC2)==PREC2 ? 0 : PREC1));
if (~att & NO_UNIT) lcd_putcAtt(lcd_lastPos, y, 'v', att);
}
@ -492,7 +492,17 @@ void putsTmrMode(uint8_t x, uint8_t y, int8_t mode, uint8_t att)
#ifdef FRSKY
// TODO move this into frsky.cpp
void putsTelemetry(uint8_t x, uint8_t y, uint8_t val, uint8_t unit, uint8_t att)
void putsTelemetryChannel(uint8_t x, uint8_t y, uint8_t channel, uint8_t val, uint8_t att)
{
int16_t converted_value = ((int16_t)val+g_model.frsky.channels[channel].offset)*g_model.frsky.channels[channel].ratio / 255;
if (g_model.frsky.channels[channel].type == 0 && converted_value < 100) {
att |= PREC2;
converted_value = ((int16_t)val+g_model.frsky.channels[channel].offset)*g_model.frsky.channels[channel].ratio*10 / 255;
}
putsTelemetryValue(x, y, converted_value, g_model.frsky.channels[channel].type, att);
}
void putsTelemetryValue(uint8_t x, uint8_t y, int16_t val, uint8_t unit, uint8_t att)
{
if (unit == 0/*v*/) {
putsVolts(x, y, val, att);

View file

@ -99,7 +99,8 @@ extern void putsTime(uint8_t x,uint8_t y, int16_t tme, uint8_t att, uint8_t att2
#ifdef FRSKY
// TODO move this into frsky.h
extern void putsTelemetry(uint8_t x, uint8_t y, uint8_t val, uint8_t unit, uint8_t att);
void putsTelemetryChannel(uint8_t x, uint8_t y, uint8_t channel, uint8_t val, uint8_t att);
void putsTelemetryValue(uint8_t x, uint8_t y, int16_t val, uint8_t unit, uint8_t att);
#endif
extern void lcd_plot(unsigned char x, unsigned char y, uint8_t att=0);

158
src/logs.cpp Normal file
View file

@ -0,0 +1,158 @@
/*
* Authors (alphabetical order)
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
*
* Original contributors
* - Philip Moss Adapted first frsky functions from jeti.cpp code by
* - Karl Szmutny <shadow@privy.de>
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*/
#include "gruvin9x.h"
#include "ff.h"
// "/G9XLOGS/M00_000.TXT\0" max required length = 21
char g_logFilename[22];
// These global so we can close any open file from anywhere
FATFS FATFS_Obj;
FIL g_oLogFile;
int8_t g_logState = 0; // 0=closed, >0=opened, <0=error
void startLogs()
{
// Determine and set log file filename
FRESULT result;
// close any file left open. E.G. Changing models with log switch still on.
if (g_oLogFile.fs) f_close(&g_oLogFile);
g_logState = 0;
strcpy_P(g_logFilename, PSTR("/G9XLOGS/M00_000.TXT"));
uint8_t num = g_eeGeneral.currModel + 1;
char *n = &g_logFilename[11];
*n = (char)((num % 10) + '0');
*(--n) = (char)((num / 10) + '0');
result = f_mount(0, &FATFS_Obj);
if (result!=FR_OK)
{
strcpy_P(g_logFilename, PSTR("FILE SYSTEM ERROR"));
g_logState = -result;
return;
}
// Skip over any existing log files ... _000, _001, etc. (or find first gap in numbering)
while (1)
{
result = f_open(&g_oLogFile, g_logFilename, FA_OPEN_EXISTING | FA_READ);
if (result == FR_OK)
{
f_close(&g_oLogFile);
// bump log file counter (file extension)
n = &g_logFilename[15];
if (++*n > '9')
{
*n='0';
n--;
if (++*n > '9')
{
*n='0';
n--;
if (++*n > '9')
{
*n='0';
break; // Wow. We looped back around past 999 to 000! abort loop
}
}
}
}
else if (result == FR_NO_FILE /*TODO check this code*/)
{
break;
}
else if (result == FR_NO_PATH)
{
if (f_mkdir("/G9XLOGS") != FR_OK)
{
strcpy_P(g_logFilename, PSTR("Check /G9XLOGS folder"));
g_logState = -result;
return;
}
}
else
{
g_logState = -result;
if (result == FR_NOT_READY)
strcpy_P(g_logFilename, PSTR("DATA CARD NOT PRESENT"));
else
strcpy_P(g_logFilename, PSTR("DATA CARD ERROR"));
return;
}
}
// g_logFilename should now be set appropriately.
}
// TODO FORCEINLINE this function
void doLogs()
{
FRESULT result;
if (isFunctionActive(FUNC_LOGS))
{
if (g_logState==0)
{
result = f_mount(0, &FATFS_Obj);
if (result != FR_OK)
{
g_logState = -result;
beepAgain = result - 1;
beepKey();
}
else
{
// create new log file using filename set up in startLogs()
result = f_open(&g_oLogFile, g_logFilename, FA_OPEN_ALWAYS | FA_WRITE);
if (result != FR_OK)
{
g_logState = -result;
beepAgain = result - 1;
beepKey();
}
else
{
f_lseek(&g_oLogFile, g_oLogFile.fsize); // append
g_logState = 1;
beepWarn2();
}
}
}
if (g_logState>0)
{
// TODO here we write logs
}
}
else if (g_logState > 0)
{
f_close(&g_oLogFile);
beepWarn2();
g_logState = 0;
}
}

View file

@ -81,20 +81,20 @@ void doMainScreenGrphics()
}
}
void displayAltitudeLine(uint8_t x, uint8_t y, uint8_t flags)
{
lcd_puts_P(x, y, PSTR("Alt:"));
uint16_t value = frskyHubData.baroAltitude + baroAltitudeOffset;
lcd_outdezAtt(lcd_lastPos, (flags & DBLSIZE) ? y-FH : y, value, flags|LEFT|UNSIGN);
lcd_putc(lcd_lastPos, y, 'm') ;
}
void menuMainView(uint8_t event)
{
static uint8_t switchView = 255;
static bool instantTrimSwLock;
static bool trim2OfsSwLock;
uint8_t view = (switchView == 255 ? g_eeGeneral.view : switchView);
#ifdef FRSKY
bool telemViewSw = isFunctionActive(FUNC_VIEW_TELEMETRY);
if (switchView == 255 && telemViewSw) { view = switchView = e_telemetry + ALTERNATE_VIEW; }
if (switchView != 255 && !telemViewSw) { view = g_eeGeneral.view; switchView = 255; }
#endif
uint8_t view = g_eeGeneral.view;
uint8_t view_base = view & 0x0f;
switch(event)
@ -111,7 +111,6 @@ void menuMainView(uint8_t event)
break;
case EVT_KEY_BREAK(KEY_RIGHT):
case EVT_KEY_BREAK(KEY_LEFT):
if (switchView != 255) break;
#if defined(FRSKY)
#if defined(FRSKY_HUB) && defined(WS_HOW_HIGH)
tabViews[e_telemetry] = (g_model.frsky.usrProto == 0 ? 2 : (g_model.frsky.usrProto == 1 ? 4 : 3));
@ -134,14 +133,12 @@ void menuMainView(uint8_t event)
killEvents(event);
break;
case EVT_KEY_BREAK(KEY_UP):
if (switchView != 255) break;
g_eeGeneral.view = view+1;
if(g_eeGeneral.view>=MAX_VIEWS) g_eeGeneral.view=0;
eeDirty(EE_GENERAL);
beepKey();
break;
case EVT_KEY_BREAK(KEY_DOWN):
if (switchView != 255) break;
if(view>0)
g_eeGeneral.view = view - 1;
else
@ -165,21 +162,19 @@ void menuMainView(uint8_t event)
case EVT_KEY_FIRST(KEY_EXIT):
if(s_timerState==TMR_BEEPING) {
s_timerState = TMR_STOPPED;
beepKey();
}
else if (view == e_timer2) {
resetTimer2();
beepKey();
}
#ifdef FRSKY
else if (view == e_telemetry) {
else if (view_base == e_telemetry) {
resetTelemetry();
beepKey();
}
#endif
else {
resetTimer1();
}
beepKey();
break;
case EVT_KEY_LONG(KEY_EXIT):
resetTimer1();
@ -348,7 +343,7 @@ void menuMainView(uint8_t event)
static bool alarmRaised[2];
if (frskyStreaming) {
uint8_t y0, x0, val, blink;
uint8_t y0, x0, blink;
if (!displayCount) {
for (int i=0; i<2; i++) {
staticTelemetry[i] = frskyTelemetry[i].value;
@ -366,12 +361,9 @@ void menuMainView(uint8_t event)
lcd_puts_P(x0, 3*FH, PSTR("A :"));
lcd_putc(x0+FW, 3*FH, '1'+i);
x0 += 3*FW;
val = ((uint16_t)staticTelemetry[i]+g_model.frsky.channels[i].offset)*g_model.frsky.channels[i].ratio / 255;
putsTelemetry(x0, 2*FH, val, g_model.frsky.channels[i].type, blink|DBLSIZE|LEFT);
val = ((int16_t)frskyTelemetry[i].min+g_model.frsky.channels[i].offset)*g_model.frsky.channels[i].ratio / 255;
putsTelemetry(x0+FW, 4*FH, val, g_model.frsky.channels[i].type, 0);
val = ((int16_t)frskyTelemetry[i].max+g_model.frsky.channels[i].offset)*g_model.frsky.channels[i].ratio / 255;
putsTelemetry(x0+3*FW, 4*FH, val, g_model.frsky.channels[i].type, LEFT);
putsTelemetryChannel(x0, 2*FH, i, staticTelemetry[i], blink|DBLSIZE|LEFT);
putsTelemetryChannel(x0+FW, 4*FH, i, frskyTelemetry[i].min, 0);
putsTelemetryChannel(x0+3*FW, 4*FH, i, frskyTelemetry[i].max, LEFT);
x0 = 11*FW-2;
}
}
@ -423,10 +415,7 @@ void menuMainView(uint8_t event)
}
#ifdef WS_HOW_HIGH
else if (g_model.frsky.usrProto == PROTO_WS_HOW_HIGH && view == e_telemetry+2*ALTERNATE_VIEW) {
lcd_puts_P(0, 4*FH, PSTR("Alt:"));
uint16_t value = frskyHubData.baroAltitude;
lcd_outdezAtt(4*FW, 3*FH, (value * 32) / 105, DBLSIZE|LEFT);
lcd_putc(lcd_lastPos, 4*FH, 'm') ;
displayAltitudeLine(0, 4*FH, DBLSIZE);
}
#endif
#ifdef FRSKY_HUB
@ -514,13 +503,10 @@ void menuMainView(uint8_t event)
lcd_puts_P(0, y, PSTR("Volts:"));
lcd_outdezNAtt(lcd_lastPos, y, frskyHubData.volts, LEFT);
lcd_putc(lcd_lastPos, y, 'V');
y = 2*FH;
// Altitude (barometric)
lcd_puts_P(12*FW, y, PSTR("Alt:"));
lcd_outdezNAtt(lcd_lastPos, y, frskyHubData.baroAltitude, LEFT|UNSIGN);
lcd_putc(lcd_lastPos, y, 'm');
// Altitude (barometric)
displayAltitudeLine(12*FW, y, 0);
y += 2*FH;
// Acceleromter
@ -548,8 +534,7 @@ void menuMainView(uint8_t event)
blink = (alarmRaised[i] ? INVERS+BLINK : 0)|LEFT;
lcd_puts_P(x0, y0, PSTR("A :"));
lcd_putc(x0+FW, y0, '1'+i);
val = ((int16_t)staticTelemetry[i]+g_model.frsky.channels[i].offset)*g_model.frsky.channels[i].ratio / 255;
putsTelemetry(x0+3*FW, y0, val, g_model.frsky.channels[i].type, blink);
putsTelemetryChannel(x0+3*FW, y0, i, staticTelemetry[i], blink);
x0 = 13*FW-3;
}
}

View file

@ -1585,21 +1585,29 @@ void menuProcCustomSwitches(uint8_t event)
lcd_putsnAtt( 4*FW - 1, y, PSTR(CSWITCH_STR)+CSW_LEN_FUNC*cs.func,CSW_LEN_FUNC,m_posHorz==0 ? attr : 0);
uint8_t cstate = CS_STATE(cs.func);
int8_t v1_min=0, v1_max=NUM_XCHNRAW, v2_min=0, v2_max=NUM_XCHNRAW;
if(cstate == CS_VOFS)
{
putsChnRaw( 12*FW, y, cs.v1 ,m_posHorz==1 ? attr : 0);
putsChnRaw(12*FW, y, cs.v1, m_posHorz==1 ? attr : 0);
#if defined(FRSKY)
if (cs.v1 > NUM_XCHNRAW-NUM_TELEMETRY)
lcd_outdezAtt( 20*FW, y, 125+cs.v2 ,m_posHorz==2 ? attr : 0);
if (cs.v1 > NUM_XCHNRAW-NUM_TELEMETRY) {
putsTelemetryChannel(20*FW, y, cs.v1+NUM_TELEMETRY-NUM_XCHNRAW-1, 128+cs.v2, m_posHorz==2 ? attr : 0);
v2_min = -128; v2_max = 127;
}
else
#endif
{
lcd_outdezAtt( 20*FW, y, cs.v2 ,m_posHorz==2 ? attr : 0);
v2_min = -125; v2_max = 125;
}
}
else if(cstate == CS_VBOOL)
{
putsSwitches(13*FW, y, cs.v1 ,m_posHorz==1 ? attr : 0);
putsSwitches(17*FW, y, cs.v2 ,m_posHorz==2 ? attr : 0);
v1_min = -MAX_SWITCH; v1_max = MAX_SWITCH;
v2_min = -MAX_SWITCH; v2_max = MAX_SWITCH;
}
else // cstate == CS_COMP
{
@ -1607,43 +1615,20 @@ void menuProcCustomSwitches(uint8_t event)
putsChnRaw( 17*FW, y, cs.v2 ,m_posHorz==2 ? attr : 0);
}
if((s_editMode>0 || p1valdiff) && attr)
if ((s_editMode>0 || p1valdiff) && attr) {
switch (m_posHorz) {
case 0:
CHECK_INCDEC_MODELVAR( event, cs.func, 0,CS_MAXF);
if(cstate != CS_STATE(cs.func))
{
if (cstate != CS_STATE(cs.func)) {
cs.v1 = 0;
cs.v2 = 0;
}
break;
case 1:
switch (cstate) {
case (CS_VOFS):
CHECK_INCDEC_MODELVAR( event, cs.v1, 0,NUM_XCHNRAW);
break;
case (CS_VBOOL):
CHECK_INCDEC_MODELVAR( event, cs.v1, -MAX_SWITCH,MAX_SWITCH);
break;
case (CS_VCOMP):
CHECK_INCDEC_MODELVAR( event, cs.v1, 0,NUM_XCHNRAW);
break;
default:
break;
}
CHECK_INCDEC_MODELVAR(event, cs.v1, v1_min, v1_max);
break;
case 2:
switch (cstate) {
case (CS_VOFS):
CHECK_INCDEC_MODELVAR( event, cs.v2, -125,125);
break;
case (CS_VBOOL):
CHECK_INCDEC_MODELVAR( event, cs.v2, -MAX_SWITCH,MAX_SWITCH);
break;
case (CS_VCOMP):
CHECK_INCDEC_MODELVAR( event, cs.v2, 0,NUM_XCHNRAW);
break;
default:
CHECK_INCDEC_MODELVAR( event, cs.v2, v2_min, v2_max);
break;
}
}
@ -1677,7 +1662,7 @@ void menuProcFunctionSwitches(uint8_t event)
if (sd->swtch) {
lcd_putsnAtt(5*FW, y, PSTR(FSWITCH_STR)+FSW_LEN_FUNC*sd->func, FSW_LEN_FUNC, attr);
if (active) {
CHECK_INCDEC_MODELVAR( event, sd->func, 0, FUNC_LAST);
CHECK_INCDEC_MODELVAR( event, sd->func, 0, FUNC_MAX-1);
}
}
else if (attr) {
@ -1749,7 +1734,6 @@ void menuProcTelemetry(uint8_t event)
blink = (s_editMode>0) ? BLINK : INVERS ;
uint8_t subN = 1;
uint8_t t;
int16_t val;
for (int i=0; i<2; i++) {
if(s_pgOfs<subN) {
@ -1762,7 +1746,7 @@ void menuProcTelemetry(uint8_t event)
if(s_pgOfs<subN) {
y=(subN-s_pgOfs)*FH;
lcd_putsAtt(4, y, PSTR("Max"), 0);
putsTelemetry(8*FW, y, g_model.frsky.channels[i].ratio, g_model.frsky.channels[i].type, (sub==subN && m_posHorz==0 ? blink:0)|NO_UNIT|LEFT);
putsTelemetryValue(8*FW, y, g_model.frsky.channels[i].ratio, g_model.frsky.channels[i].type, (sub==subN && m_posHorz==0 ? blink:0)|NO_UNIT|LEFT);
lcd_putsnAtt(lcd_lastPos, y, PSTR("v-")+g_model.frsky.channels[i].type, 1, (sub==subN && m_posHorz==1 ? blink:0));
if (sub==subN && (s_editMode>0 || p1valdiff)) {
if (m_posHorz == 0)
@ -1776,8 +1760,7 @@ void menuProcTelemetry(uint8_t event)
if(s_pgOfs<subN) {
y=(subN-s_pgOfs)*FH;
lcd_putsAtt(4, y, PSTR("Calib"), 0);
val = ((int16_t)frskyTelemetry[i].value+g_model.frsky.channels[i].offset)*g_model.frsky.channels[i].ratio / 255;
putsTelemetry(8*FW, y, val, g_model.frsky.channels[i].type, (sub==subN ? blink:0)|LEFT);
putsTelemetryChannel(8*FW, y, i, frskyTelemetry[i].value, (sub==subN ? blink:0)|LEFT);
if(sub==subN) CHECK_INCDEC_MODELVAR(event, g_model.frsky.channels[i].offset, -127, 127);
}
subN++;
@ -1785,10 +1768,8 @@ void menuProcTelemetry(uint8_t event)
if(s_pgOfs<subN) {
y=(subN-s_pgOfs)*FH;
lcd_puts_P(4, y, PSTR("Bar"));
val = ((int16_t)g_model.frsky.channels[i].barMin+g_model.frsky.channels[i].offset)*g_model.frsky.channels[i].ratio / 255;
putsTelemetry(8*FW, y, val, g_model.frsky.channels[i].type, (sub==subN && m_posHorz==0 ? blink:0)|LEFT);
val = ((int16_t)g_model.frsky.channels[i].barMax+g_model.frsky.channels[i].offset)*g_model.frsky.channels[i].ratio / 255;
putsTelemetry(13*FW, y, val, g_model.frsky.channels[i].type, (sub==subN && m_posHorz==1 ? blink:0)|LEFT);
putsTelemetryChannel(8*FW, y, i, g_model.frsky.channels[i].barMin, (sub==subN && m_posHorz==0 ? blink:0)|LEFT);
putsTelemetryChannel(13*FW, y, i, g_model.frsky.channels[i].barMax, (sub==subN && m_posHorz==1 ? blink:0)|LEFT);
if(sub==subN && m_posHorz==0 && (s_editMode>0 || p1valdiff)) g_model.frsky.channels[i].barMin = checkIncDec(event, g_model.frsky.channels[i].barMin, 0, 255, EE_MODEL);
if(sub==subN && m_posHorz==1 && (s_editMode>0 || p1valdiff)) g_model.frsky.channels[i].barMax = checkIncDec(event, g_model.frsky.channels[i].barMax, 0, 255, EE_MODEL);
}
@ -1800,8 +1781,7 @@ void menuProcTelemetry(uint8_t event)
lcd_putsAtt(4, y, PSTR("Alarm"), 0);
lcd_putsnAtt(8*FW, y, PSTR("---YelOrgRed")+3*ALARM_LEVEL(i, j),3,(sub==subN && m_posHorz==0 ? blink:0));
lcd_putsnAtt(12*FW, y, PSTR("<>")+ALARM_GREATER(i, j),1,(sub==subN && m_posHorz==1 ? blink:0));
uint8_t alarmValue = ((uint16_t)g_model.frsky.channels[i].alarms_value[j] * g_model.frsky.channels[i].ratio) / 255;
putsTelemetry(14*FW, y, alarmValue, g_model.frsky.channels[i].type, (sub==subN && m_posHorz==2 ? blink:0) | LEFT);
putsTelemetryChannel(14*FW, y, i, g_model.frsky.channels[i].alarms_value[j], (sub==subN && m_posHorz==2 ? blink:0) | LEFT);
if(sub==subN && (s_editMode>0 || p1valdiff)) {
switch (m_posHorz) {

View file

@ -158,15 +158,20 @@ PACK(typedef struct t_SafetySwData { // Safety Switches data
int8_t val;
}) SafetySwData;
#define FUNC_TRAINER 1
#define FUNC_TRAINER_RUD 2
#define FUNC_TRAINER_ELE 3
#define FUNC_TRAINER_THR 4
#define FUNC_TRAINER_AIL 5
#define FUNC_INSTANT_TRIM 6
#define FUNC_TRIMS_2_OFS 7
#define FUNC_VIEW_TELEMETRY 8
#define FUNC_LAST 8
enum Functions {
FUNC_NONE,
FUNC_TRAINER,
FUNC_TRAINER_RUD,
FUNC_TRAINER_ELE,
FUNC_TRAINER_THR,
FUNC_TRAINER_AIL,
FUNC_INSTANT_TRIM,
FUNC_TRIMS_2_OFS,
#ifdef LOGS
FUNC_LOGS,
#endif
FUNC_MAX
};
PACK(typedef struct t_FuncSwData { // Function Switches data
int8_t swtch; //input
@ -180,8 +185,8 @@ PACK(typedef struct t_FrSkyChannelData {
uint8_t alarms_value[2]; // 0.1V steps EG. 6.6 Volts = 66. 25.1V = 251, etc.
uint8_t alarms_level:4;
uint8_t alarms_greater:2; // 0=LT(<), 1=GT(>)
uint8_t spare:2;
int8_t barMin; // minimum for bar display
uint8_t multiplier:2; // 0=no multiplier, 1=*2 multiplier
uint8_t barMin; // minimum for bar display
uint8_t barMax; // ditto for max display (would usually = ratio)
}) FrSkyChannelData;

View file

@ -299,6 +299,9 @@ void eeLoadModel(uint8_t id)
#ifdef FRSKY
resetTelemetry();
FRSKY_setModelAlarms();
#endif
#ifdef LOGS
startLogs();
#endif
}
}

View file

@ -48,9 +48,9 @@
static
void iic_delay (void)
{
int n;
for (n = 4; n; n--) PINB;
#ifndef SIMU
for (int n = 4; n; n--) PINB;
#endif
}

View file

@ -123,6 +123,9 @@ void *main_thread(void *)
while (main_thread_running) {
perMain();
frskyHubData.baroAltitude = 500;
sleep(1/*ms*/);
}
#ifdef SIMU_EXCEPTIONS

View file

@ -296,9 +296,19 @@ void Gruvin9xSim::refreshDiplay()
#else
static FXuint keys2[]={KEY_F8, KEY_F7, KEY_F4, KEY_F3, KEY_F6, KEY_F5, KEY_F1, KEY_F2 };
#endif
#ifdef PCBV4
pinj = 0;
#else
pind = 0;
#endif
for(unsigned i=0; i<DIM(keys2);i++){
if(getApp()->getKeyState(keys2[i])) pind |= (1<<i);
if(getApp()->getKeyState(keys2[i])) {
#ifdef PCBV4
pinj |= (1<<i);
#else
pind |= (1<<i);
#endif
}
}
struct SwitchKey {