|
|
|
@ -1,6 +1,9 @@
|
|
|
|
|
/*
|
|
|
|
|
Vario function for ez430 chronos watch. |
|
|
|
|
Copyright (C) 2010 Marc Poulhiès <dkm@kataplop.net> |
|
|
|
|
Altivario function for ez430 chronos watch. |
|
|
|
|
|
|
|
|
|
Copyright (C) 2011, Marc Bongartz <mbong@free.fr> |
|
|
|
|
|
|
|
|
|
Build environment Copyright (C) 2010 Marc Poulhi<E8>s <dkm@kataplop.net> |
|
|
|
|
|
|
|
|
|
This program is free software: you can redistribute it and/or modify |
|
|
|
|
it under the terms of the GNU General Public License as published by |
|
|
|
@ -55,152 +58,499 @@
|
|
|
|
|
#ifdef CONFIG_VARIO |
|
|
|
|
|
|
|
|
|
// driver
|
|
|
|
|
#include "altitude.h" |
|
|
|
|
#include "display.h" |
|
|
|
|
#include "vti_ps.h" |
|
|
|
|
#include "ports.h" |
|
|
|
|
#include "timer.h" |
|
|
|
|
|
|
|
|
|
#include "stopwatch.h" |
|
|
|
|
#include "buzzer.h" |
|
|
|
|
|
|
|
|
|
// logic
|
|
|
|
|
#include "user.h" |
|
|
|
|
#include "altitude.h" |
|
|
|
|
#include "vario.h" |
|
|
|
|
|
|
|
|
|
#include "menu.h" |
|
|
|
|
|
|
|
|
|
struct vario svario; |
|
|
|
|
|
|
|
|
|
void hist_add(s16 alt); |
|
|
|
|
u8 hist_ready(void); |
|
|
|
|
//
|
|
|
|
|
// Module internal definitions.
|
|
|
|
|
//
|
|
|
|
|
// Vario compile time options, saving space if needed.
|
|
|
|
|
#define VARIO_ALT_PA 0 /* 32 bytes - display vario in Pascal */ |
|
|
|
|
#define VARIO_PA 1 /* 30 bytes - display pressure in hPa */ |
|
|
|
|
#define VARIO_VZ 1 /* 110 bytes - display Vz min/ max */ |
|
|
|
|
#define VARIO_ALTMAX 1 /* 64 bytes - display max altitude */ |
|
|
|
|
#define VARIO_F_TIME 1 /* 216 bytes - display flight time */ |
|
|
|
|
//
|
|
|
|
|
// Global struct with all our variables.
|
|
|
|
|
//
|
|
|
|
|
struct |
|
|
|
|
{ |
|
|
|
|
u32 pressure; // updated by altitude.c - need a mutex ?
|
|
|
|
|
u32 prev_pa; // pressure at last scan
|
|
|
|
|
u8 p_valid; // mutex for pressure field
|
|
|
|
|
u8 view_mode; // view mode, controlled by "v" key
|
|
|
|
|
u8 beep_mode; // beeper mode, controlled by "#" key
|
|
|
|
|
struct |
|
|
|
|
{ |
|
|
|
|
#if VARIO_VZ |
|
|
|
|
s16 vzmin; // Vz min in Pascal
|
|
|
|
|
s16 vzmax; // Vz max in Pascal
|
|
|
|
|
#endif |
|
|
|
|
#if VARIO_ALTMAX |
|
|
|
|
u16 altmax; // altitude max - 32767m should be enough.
|
|
|
|
|
#endif |
|
|
|
|
#if VARIO_F_TIME |
|
|
|
|
struct { |
|
|
|
|
u8 hh; // 00-99
|
|
|
|
|
u8 mm; // 00-59
|
|
|
|
|
u8 ss; // 00-59
|
|
|
|
|
} f_time; // flight time
|
|
|
|
|
#endif |
|
|
|
|
} stats; |
|
|
|
|
} G_vario; |
|
|
|
|
|
|
|
|
|
#define HIST_GET_OLD() svario.hist_alts[(svario.hist_pos+1)%VARIO_HIST_SIZE] |
|
|
|
|
#define HIST_GET_NEW() svario.hist_alts[svario.hist_pos] |
|
|
|
|
//
|
|
|
|
|
// Note the beepmode enum changes are reflected in the beepmode symbol.
|
|
|
|
|
// For visual feedback during settings, the beeper2 symbol is turned on
|
|
|
|
|
// when beepmode ASCENT_0 or BOTH are selected. Update the corresponding
|
|
|
|
|
// logic if you change the beepmode enum order or add a new enum value.
|
|
|
|
|
//
|
|
|
|
|
enum |
|
|
|
|
{ |
|
|
|
|
VARIO_BEEPMODE_OFF = 0, // default beep mode
|
|
|
|
|
VARIO_BEEPMODE_ASCENT_0, // ascent only, beep at zero
|
|
|
|
|
VARIO_BEEPMODE_ASCENT_1, // ascent only, beep at one
|
|
|
|
|
VARIO_BEEPMODE_BOTH, // ascent and descent
|
|
|
|
|
VARIO_BEEPMODE_MAX |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
enum
|
|
|
|
|
{ |
|
|
|
|
VARIO_VIEWMODE_ALT_M = 0, // Vario in m/s, default view mode
|
|
|
|
|
#if VARIO_ALT_PA |
|
|
|
|
VARIO_VIEWMODE_ALT_PA, // Vario in Pascal
|
|
|
|
|
#endif |
|
|
|
|
#if VARIO_PA |
|
|
|
|
VARIO_VIEWMODE_PA, // Display current pressure
|
|
|
|
|
#endif |
|
|
|
|
#if VARIO_VZ |
|
|
|
|
VARIO_VIEWMODE_VZMAX, // Max Vario (positive)
|
|
|
|
|
VARIO_VIEWMODE_VZMIN, // Max Vario (positive)
|
|
|
|
|
#endif |
|
|
|
|
#if VARIO_ALTMAX |
|
|
|
|
VARIO_VIEWMODE_ALT_MAX, // Max altitude
|
|
|
|
|
#endif |
|
|
|
|
#if VARIO_F_TIME |
|
|
|
|
VARIO_VIEWMODE_F_TIME, // Flight time (since stats reset)
|
|
|
|
|
#endif |
|
|
|
|
VARIO_VIEWMODE_MAX |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* called every sec |
|
|
|
|
*/ |
|
|
|
|
void vario_tick() |
|
|
|
|
//
|
|
|
|
|
// Clear statistics
|
|
|
|
|
//
|
|
|
|
|
static inline void |
|
|
|
|
_clear_stats( void ) |
|
|
|
|
{ |
|
|
|
|
if (is_altitude_measurement()){ |
|
|
|
|
hist_add(sAlt.altitude); |
|
|
|
|
if (!hist_ready()){ |
|
|
|
|
display_symbol(LCD_ICON_RECORD, SEG_ON_BLINK_ON); |
|
|
|
|
} else { |
|
|
|
|
display_symbol(LCD_ICON_RECORD, SEG_OFF); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
display_vario(0, 0); |
|
|
|
|
#if 0000 // We save 10 bytes by using memset() if VZ, ALTMAX and F_TIME are enabled.
|
|
|
|
|
#if VARIO_VZ |
|
|
|
|
G_vario.stats.vzmin = 0; |
|
|
|
|
G_vario.stats.vzmax = 0; |
|
|
|
|
#endif |
|
|
|
|
#if VARIO_ALTMAX |
|
|
|
|
G_vario.stats.altmax = 0; |
|
|
|
|
#endif |
|
|
|
|
#if VARIO_F_TIME |
|
|
|
|
G_vario.stats.f_time.hh = 0; |
|
|
|
|
G_vario.stats.f_time.mm = 0; |
|
|
|
|
G_vario.stats.f_time.ss = 0; |
|
|
|
|
#endif |
|
|
|
|
#else // initialise individual fields or use memset ?
|
|
|
|
|
memset( &G_vario.stats, 0, sizeof( G_vario.stats ) ); |
|
|
|
|
#endif // using memset.
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
u8 is_vario(void) |
|
|
|
|
// "v" button press changes display mode
|
|
|
|
|
extern void |
|
|
|
|
sx_vario(u8 line) |
|
|
|
|
{ |
|
|
|
|
return (svario.state == VARIO_RUN && (ptrMenu_L2 == &menu_L2_Vario)); |
|
|
|
|
G_vario.view_mode++; |
|
|
|
|
G_vario.view_mode %= VARIO_VIEWMODE_MAX; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void update_vario() |
|
|
|
|
//
|
|
|
|
|
// Long "#" press will turn on/off vario sound if in vario display,
|
|
|
|
|
// or clear stats if in stats view mode.
|
|
|
|
|
//
|
|
|
|
|
extern void |
|
|
|
|
mx_vario(u8 line) |
|
|
|
|
{ |
|
|
|
|
switch( G_vario.view_mode ) |
|
|
|
|
{ |
|
|
|
|
case VARIO_VIEWMODE_ALT_M: |
|
|
|
|
#if VARIO_ALT_PA |
|
|
|
|
case VARIO_VIEWMODE_ALT_PA: |
|
|
|
|
#endif |
|
|
|
|
G_vario.beep_mode++; |
|
|
|
|
G_vario.beep_mode %= VARIO_BEEPMODE_MAX; |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
#if VARIO_VZ |
|
|
|
|
case VARIO_VIEWMODE_VZMAX: |
|
|
|
|
case VARIO_VIEWMODE_VZMIN: |
|
|
|
|
#endif |
|
|
|
|
# if VARIO_ALTMAX |
|
|
|
|
case VARIO_VIEWMODE_ALT_MAX: |
|
|
|
|
#endif |
|
|
|
|
#if VARIO_F_TIME |
|
|
|
|
case VARIO_VIEWMODE_F_TIME: |
|
|
|
|
#endif |
|
|
|
|
_clear_stats(); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
#if VARIO_PA |
|
|
|
|
case VARIO_VIEWMODE_PA: // no settings for pressure display
|
|
|
|
|
#endif |
|
|
|
|
case VARIO_VIEWMODE_MAX: |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void start_vario() |
|
|
|
|
//
|
|
|
|
|
// Mutex for accessing G_vario.pressure from altitude.c (write) and vario.c (read)
|
|
|
|
|
// This prevents badly timed updates, for example on button press. It also helped
|
|
|
|
|
// me figure a problem with calls to display_vario() from interrupt level.
|
|
|
|
|
//
|
|
|
|
|
extern void |
|
|
|
|
vario_p_write( u32 p ) |
|
|
|
|
{ |
|
|
|
|
|
|
|
|
|
svario.state = VARIO_RUN; |
|
|
|
|
|
|
|
|
|
display_symbol(LCD_ICON_HEART, SEG_ON_BLINK_ON); |
|
|
|
|
if ( !G_vario.p_valid ) |
|
|
|
|
{
|
|
|
|
|
G_vario.pressure = p; |
|
|
|
|
G_vario.p_valid++; |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
//
|
|
|
|
|
// Pressure has not been read by the vario (called once per second)
|
|
|
|
|
// since last write from altimeter (called about once every second in
|
|
|
|
|
// ultra low power mode, more often for other modes, or on demand for
|
|
|
|
|
// low power with external trigger mode), average in the new pressure
|
|
|
|
|
// value.
|
|
|
|
|
//
|
|
|
|
|
G_vario.pressure = (G_vario.pressure + p) >> 1; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void stop_vario() |
|
|
|
|
int vario_p_read( u32 *retp ) |
|
|
|
|
{ |
|
|
|
|
svario.state = VARIO_STOP; |
|
|
|
|
|
|
|
|
|
display_symbol(LCD_ICON_HEART, SEG_OFF); |
|
|
|
|
|
|
|
|
|
// Call draw routine immediately
|
|
|
|
|
display_vario(LINE2, DISPLAY_LINE_UPDATE_FULL); |
|
|
|
|
if ( G_vario.p_valid ) |
|
|
|
|
{ |
|
|
|
|
*retp = G_vario.pressure; |
|
|
|
|
G_vario.p_valid = 0; |
|
|
|
|
return 0; // success, a new pressure value is available.
|
|
|
|
|
} |
|
|
|
|
return 1; // error, no new pressure value available.
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void sx_vario(u8 line) |
|
|
|
|
//
|
|
|
|
|
// Produce a sound depending on the ascent/descent rate.
|
|
|
|
|
//
|
|
|
|
|
void chirp( s16 pdiff ) |
|
|
|
|
{ |
|
|
|
|
if (button.flag.down) |
|
|
|
|
{ |
|
|
|
|
if (svario.state == VARIO_STOP){ |
|
|
|
|
start_vario(); |
|
|
|
|
} else { |
|
|
|
|
stop_vario(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
const u8 center_steps = 8; |
|
|
|
|
const u8 range_steps = 5; |
|
|
|
|
u8 bsteps; |
|
|
|
|
u8 nchirps; |
|
|
|
|
u16 on_time; |
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Buzzer steps (see driver/buzzer) 3..23 provide a frequency
|
|
|
|
|
// of 4096Hz..682Hz, well within the human audible range. But
|
|
|
|
|
// the lower frequencies have a rather faint volume, may not
|
|
|
|
|
// be ideal in flight. Using 3..13 (4096..1170Hz).
|
|
|
|
|
//
|
|
|
|
|
bsteps = center_steps - (pdiff % range_steps); // buzzer steps
|
|
|
|
|
if ( pdiff < 0 ) pdiff *= -1; // need positive value now
|
|
|
|
|
nchirps = 1 + (pdiff / range_steps); // number of chirps.
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Make sure we make our noises in less than 1s, before the next
|
|
|
|
|
// update comes along.
|
|
|
|
|
//
|
|
|
|
|
if ( nchirps > 50 ) nchirps = 50; // Wouah, 25m/s - up or down?
|
|
|
|
|
on_time = 500 / nchirps; // 500ms on time max, half for off time
|
|
|
|
|
|
|
|
|
|
start_buzzer_steps( nchirps,
|
|
|
|
|
CONV_MS_TO_TICKS( on_time ), |
|
|
|
|
CONV_MS_TO_TICKS( on_time / 2 ), |
|
|
|
|
bsteps ); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void mx_vario(u8 line) |
|
|
|
|
//
|
|
|
|
|
// _display_signed() - display a signed value on the second line.
|
|
|
|
|
//
|
|
|
|
|
// If is_fraction is false, display value on the second line, nnnnnn
|
|
|
|
|
// Otherwise display value as fraction on the second line, nnnn.nn
|
|
|
|
|
//
|
|
|
|
|
// Used to display pressure (in Pascal) as hPa and cm/s as m/s.
|
|
|
|
|
//
|
|
|
|
|
static void |
|
|
|
|
_display_signed( s32 value, u8 is_fraction ) |
|
|
|
|
{ |
|
|
|
|
u8 *str; |
|
|
|
|
int i; |
|
|
|
|
int is_neg; |
|
|
|
|
|
|
|
|
|
is_neg = ( value < 0 ); |
|
|
|
|
if ( is_neg ) |
|
|
|
|
{ |
|
|
|
|
is_neg = 1; |
|
|
|
|
value *= -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
str = itoa( value, 6, (is_fraction) ? 3 : 5 ); |
|
|
|
|
|
|
|
|
|
for ( i = 0; (is_neg && (str[i] == ' ')); i++ ) |
|
|
|
|
{ |
|
|
|
|
if (str[i+1] != ' ') |
|
|
|
|
str[i] = '-'; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
display_chars( LCD_SEG_L2_5_0, str, SEG_ON ); |
|
|
|
|
|
|
|
|
|
if ( is_fraction ) |
|
|
|
|
display_symbol( LCD_SEG_L2_DP, SEG_ON ); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void display_vario(u8 line, u8 update) |
|
|
|
|
//
|
|
|
|
|
// Convert barometric value to vz.
|
|
|
|
|
// This really depends on altitude and temp, also humidity, but for
|
|
|
|
|
// a rough estimation we can take 1Pa = 10cm (0.1m)
|
|
|
|
|
//
|
|
|
|
|
// TBS -- allow non-metric display...
|
|
|
|
|
//
|
|
|
|
|
static inline s32 |
|
|
|
|
_pascal_to_vz( s32 pa ) |
|
|
|
|
{ |
|
|
|
|
|
|
|
|
|
if (svario.state == VARIO_STOP) { |
|
|
|
|
display_chars(LCD_SEG_L2_5_0, (u8*) " idle", SEG_ON); |
|
|
|
|
} else if (is_altitude_measurement()){ |
|
|
|
|
if (!hist_ready()) { |
|
|
|
|
display_chars(LCD_SEG_L2_5_0, (u8*)" wait", SEG_ON_BLINK_ON); |
|
|
|
|
} else { |
|
|
|
|
u8 *str; |
|
|
|
|
|
|
|
|
|
s16 diff = HIST_GET_OLD() - HIST_GET_NEW(); |
|
|
|
|
u8 is_neg = 0; |
|
|
|
|
u8 i; |
|
|
|
|
|
|
|
|
|
if (diff == 0){ |
|
|
|
|
display_chars(LCD_SEG_L2_5_0, (u8*) " 0", SEG_ON); |
|
|
|
|
} else { |
|
|
|
|
if (diff < 0){ |
|
|
|
|
is_neg = 1; |
|
|
|
|
diff = diff*(-1); |
|
|
|
|
} |
|
|
|
|
diff = diff / VARIO_HIST_SIZE; |
|
|
|
|
|
|
|
|
|
str = itoa(diff, 6, 7); |
|
|
|
|
|
|
|
|
|
for (i=0; i<7; i++){ |
|
|
|
|
if (str[i] == '0' || str[i] == ' '){ |
|
|
|
|
if (is_neg) |
|
|
|
|
str[i] = '-'; |
|
|
|
|
else |
|
|
|
|
str[i] = ' '; |
|
|
|
|
} else { |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
display_chars(LCD_SEG_L2_5_0, str, SEG_ON); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
display_chars(LCD_SEG_L2_5_0, (u8*) " NOALT", SEG_ON); |
|
|
|
|
} |
|
|
|
|
return pa * 10; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
u8 hist_ready(void) { |
|
|
|
|
return (svario.hist_count == VARIO_HIST_SIZE); |
|
|
|
|
//
|
|
|
|
|
// Common function to turn off various symbols we use in our view modes.
|
|
|
|
|
//
|
|
|
|
|
void |
|
|
|
|
_display_l2_clean( void )
|
|
|
|
|
{ |
|
|
|
|
#if ( VARIO_VZ || VARIO_ALTMAX ) |
|
|
|
|
display_symbol( LCD_SYMB_MAX, SEG_OFF); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#if VARIO_F_TIME |
|
|
|
|
display_symbol(LCD_SEG_L2_COL1, SEG_OFF); |
|
|
|
|
display_symbol(LCD_SEG_L2_COL0, SEG_OFF); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* s8 hist_size(void) { */ |
|
|
|
|
/* if (svario.previous_end == -1) return 0; */ |
|
|
|
|
/* if (svario.previous_end == svario.previous_start) return VARIO_HIST_SIZE; */ |
|
|
|
|
/* return ((svario.previous_end-svario.previous_start)>0 ? VARIO_HIST_SIZE-svario.previous_end+svario.previous_start : svario.previous_start-svario.previous_end); */ |
|
|
|
|
/* } */ |
|
|
|
|
//
|
|
|
|
|
// Vario display update function. Theorethically called once per second.
|
|
|
|
|
// In practice, this also gets called on button presses, so careful if
|
|
|
|
|
// you rely on it for a 1Hz frequency.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
void hist_add(s16 alt) { |
|
|
|
|
if (svario.hist_count != VARIO_HIST_SIZE) svario.hist_count++; |
|
|
|
|
extern void |
|
|
|
|
display_vario( u8 line, u8 update ) |
|
|
|
|
{ |
|
|
|
|
static u8 _idone; // initialisation helper
|
|
|
|
|
static u8 _vbeat; // heartbeat
|
|
|
|
|
|
|
|
|
|
u32 pressure; |
|
|
|
|
|
|
|
|
|
switch( update ) |
|
|
|
|
{ |
|
|
|
|
case DISPLAY_LINE_CLEAR: |
|
|
|
|
|
|
|
|
|
stop_buzzer(); |
|
|
|
|
display_symbol( LCD_ICON_BEEPER1, SEG_OFF ); |
|
|
|
|
display_symbol( LCD_ICON_BEEPER2, SEG_OFF ); |
|
|
|
|
display_symbol( LCD_ICON_RECORD, SEG_OFF ); |
|
|
|
|
_display_l2_clean(); |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
case DISPLAY_LINE_UPDATE_FULL: |
|
|
|
|
|
|
|
|
|
display_symbol( LCD_ICON_BEEPER1, |
|
|
|
|
( G_vario.beep_mode ) ? SEG_ON : SEG_OFF ); |
|
|
|
|
|
|
|
|
|
display_symbol( LCD_ICON_BEEPER2, |
|
|
|
|
( ( G_vario.beep_mode == VARIO_BEEPMODE_ASCENT_0 ) |
|
|
|
|
|| ( G_vario.beep_mode == VARIO_BEEPMODE_BOTH )) |
|
|
|
|
? SEG_ON : SEG_OFF ); |
|
|
|
|
//
|
|
|
|
|
// fall through to partial update
|
|
|
|
|
//
|
|
|
|
|
case DISPLAY_LINE_UPDATE_PARTIAL: |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#if VARIO_F_TIME |
|
|
|
|
// Update flight time regardless of whether we do have an altitude.
|
|
|
|
|
//
|
|
|
|
|
// Be careful to only update the time when a time update is active,
|
|
|
|
|
// ie, not because this refresh is due to a DOWN button press.
|
|
|
|
|
//
|
|
|
|
|
if ( display.flag.update_time ) |
|
|
|
|
{ |
|
|
|
|
G_vario.stats.f_time.ss++; |
|
|
|
|
if ( G_vario.stats.f_time.ss > 59 ) |
|
|
|
|
{ |
|
|
|
|
G_vario.stats.f_time.ss = 0; |
|
|
|
|
G_vario.stats.f_time.mm++; |
|
|
|
|
if ( G_vario.stats.f_time.mm > 59 ) |
|
|
|
|
{ |
|
|
|
|
G_vario.stats.f_time.mm = 0; |
|
|
|
|
G_vario.stats.f_time.hh++; |
|
|
|
|
} |
|
|
|
|
// Reset flight time after 19 hours, more will not fit on lcd !
|
|
|
|
|
if ( G_vario.stats.f_time.hh > 19 ) |
|
|
|
|
G_vario.stats.f_time.hh = 0; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Partial or full update. Make sure pressure sensor is being sampled, ie,
|
|
|
|
|
// that line 1 is in altimeter mode.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
if ( is_altitude_measurement() ) |
|
|
|
|
{ |
|
|
|
|
s16 diff; |
|
|
|
|
|
|
|
|
|
if ( vario_p_read( &pressure ) ) |
|
|
|
|
{ |
|
|
|
|
// Happens during key presses, never mind.
|
|
|
|
|
return; // no data, wait for update
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// If this is the very first time we are here, we have no previous
|
|
|
|
|
// pressure, handle that situation.
|
|
|
|
|
//
|
|
|
|
|
if ( !_idone ) |
|
|
|
|
{ |
|
|
|
|
diff = 0; |
|
|
|
|
++_idone; |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
//
|
|
|
|
|
// Calculate difference in Pascal - we will need it anyway for the
|
|
|
|
|
// buzzer. Pressure decreases with altitude, ensure going lower is
|
|
|
|
|
// negative.
|
|
|
|
|
//
|
|
|
|
|
diff = G_vario.prev_pa - pressure; |
|
|
|
|
|
|
|
|
|
#if VARIO_VZ |
|
|
|
|
// update stats as we may want to see these after the flight.
|
|
|
|
|
|
|
|
|
|
if ( diff > G_vario.stats.vzmax ) G_vario.stats.vzmax = diff; |
|
|
|
|
if ( diff < G_vario.stats.vzmin ) G_vario.stats.vzmin = diff; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#if VARIO_ALTMAX |
|
|
|
|
// Peek at current altitude in altimeter data.
|
|
|
|
|
if ( G_vario.stats.altmax < sAlt.altitude ) |
|
|
|
|
G_vario.stats.altmax = sAlt.altitude; |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
_display_l2_clean(); |
|
|
|
|
// Pulse the vario heartbeat indicator.
|
|
|
|
|
++_vbeat; |
|
|
|
|
display_symbol( LCD_ICON_RECORD, ( _vbeat & 1 ) ? SEG_ON : SEG_OFF ); |
|
|
|
|
|
|
|
|
|
// Now see what value to display.
|
|
|
|
|
|
|
|
|
|
switch( G_vario.view_mode ) |
|
|
|
|
{ |
|
|
|
|
case VARIO_VIEWMODE_ALT_M: |
|
|
|
|
//
|
|
|
|
|
// convert the difference in Pa to a vertical velocity.
|
|
|
|
|
//
|
|
|
|
|
_display_signed( _pascal_to_vz( diff ), 1 ); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
#if VARIO_ALT_PA |
|
|
|
|
case VARIO_VIEWMODE_ALT_PA: |
|
|
|
|
//
|
|
|
|
|
// display raw difference in Pascal.
|
|
|
|
|
//
|
|
|
|
|
_display_signed( diff, 0 ); |
|
|
|
|
break; |
|
|
|
|
#endif |
|
|
|
|
#if VARIO_PA |
|
|
|
|
case VARIO_VIEWMODE_PA: |
|
|
|
|
//
|
|
|
|
|
// display pressure as hhhh.pp (hPa and Pa)
|
|
|
|
|
//
|
|
|
|
|
_display_signed( pressure, 1 ); |
|
|
|
|
break; |
|
|
|
|
#endif |
|
|
|
|
#if VARIO_VZ |
|
|
|
|
case VARIO_VIEWMODE_VZMAX: |
|
|
|
|
display_symbol( LCD_SYMB_MAX, SEG_ON); |
|
|
|
|
_display_signed( _pascal_to_vz( G_vario.stats.vzmax ), 1 ); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case VARIO_VIEWMODE_VZMIN: |
|
|
|
|
display_symbol( LCD_SYMB_MAX, SEG_ON); |
|
|
|
|
_display_signed( _pascal_to_vz( G_vario.stats.vzmin ), 1 ); |
|
|
|
|
break; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#if VARIO_ALTMAX |
|
|
|
|
case VARIO_VIEWMODE_ALT_MAX: |
|
|
|
|
display_symbol( LCD_SYMB_MAX, SEG_ON); |
|
|
|
|
_display_signed( G_vario.stats.altmax, 0 ); |
|
|
|
|
break; |
|
|
|
|
#endif |
|
|
|
|
#if VARIO_F_TIME |
|
|
|
|
case VARIO_VIEWMODE_F_TIME: |
|
|
|
|
display_chars(LCD_SEG_L2_5_0, itoa(G_vario.stats.f_time.hh,2,0), SEG_ON); |
|
|
|
|
display_chars(LCD_SEG_L2_3_0, itoa(G_vario.stats.f_time.mm,2,0), SEG_ON); |
|
|
|
|
display_chars(LCD_SEG_L2_1_0, itoa(G_vario.stats.f_time.ss,2,0), SEG_ON); |
|
|
|
|
display_symbol(LCD_SEG_L2_COL1, SEG_ON); |
|
|
|
|
display_symbol(LCD_SEG_L2_COL0, SEG_ON); |
|
|
|
|
break; |
|
|
|
|
#endif |
|
|
|
|
case VARIO_VIEWMODE_MAX: |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
} // switch view mode
|
|
|
|
|
|
|
|
|
|
// If beeper is enabled, beep.
|
|
|
|
|
switch ( G_vario.beep_mode ) |
|
|
|
|
{ |
|
|
|
|
case VARIO_BEEPMODE_ASCENT_0: |
|
|
|
|
if ( diff >= 0 ) chirp( diff ); |
|
|
|
|
break; |
|
|
|
|
case VARIO_BEEPMODE_ASCENT_1: |
|
|
|
|
if ( diff > 0 ) chirp( diff ); |
|
|
|
|
break; |
|
|
|
|
case VARIO_BEEPMODE_BOTH: |
|
|
|
|
if ( diff ) chirp( diff ); |
|
|
|
|
break; |
|
|
|
|
case VARIO_BEEPMODE_OFF: |
|
|
|
|
case VARIO_BEEPMODE_MAX: |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// update previous pressure measurement.
|
|
|
|
|
|
|
|
|
|
svario.hist_alts[svario.hist_pos] = alt; |
|
|
|
|
svario.hist_pos = (svario.hist_pos+1)%VARIO_HIST_SIZE; |
|
|
|
|
} |
|
|
|
|
G_vario.prev_pa = pressure; |
|
|
|
|
|
|
|
|
|
void reset_vario(void) |
|
|
|
|
{ |
|
|
|
|
svario.state = VARIO_STOP; |
|
|
|
|
svario.hist_pos = svario.hist_count = 0; |
|
|
|
|
} // L1 is in altimeter mode
|
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
_display_l2_clean(); |
|
|
|
|
display_chars(LCD_SEG_L2_5_0, (u8*) " NOALT", SEG_ON); |
|
|
|
|
_idone = 0; // avoid false peaks when re-enabling the altimeter
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#endif /* CONFIG_VARIO */ |
|
|
|
|