You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
458 lines
13 KiB
458 lines
13 KiB
// ************************************************************************************************* |
|
// |
|
// Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ |
|
// |
|
// |
|
// Redistribution and use in source and binary forms, with or without |
|
// modification, are permitted provided that the following conditions |
|
// are met: |
|
// |
|
// Redistributions of source code must retain the above copyright |
|
// notice, this list of conditions and the following disclaimer. |
|
// |
|
// Redistributions in binary form must reproduce the above copyright |
|
// notice, this list of conditions and the following disclaimer in the |
|
// documentation and/or other materials provided with the |
|
// distribution. |
|
// |
|
// Neither the name of Texas Instruments Incorporated nor the names of |
|
// its contributors may be used to endorse or promote products derived |
|
// from this software without specific prior written permission. |
|
// |
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
// |
|
// ************************************************************************************************* |
|
// Altitude measurement functions. |
|
// ************************************************************************************************* |
|
|
|
|
|
// ************************************************************************************************* |
|
// Include section |
|
|
|
// system |
|
#include "project.h" |
|
|
|
#ifdef CONFIG_ALTITUDE |
|
|
|
// driver |
|
#include "altitude.h" |
|
#include "display.h" |
|
#include "vti_ps.h" |
|
#include "ports.h" |
|
#include "timer.h" |
|
|
|
// logic |
|
#include "user.h" |
|
|
|
|
|
// ************************************************************************************************* |
|
// Prototypes section |
|
|
|
|
|
// ************************************************************************************************* |
|
// Defines section |
|
|
|
|
|
// ************************************************************************************************* |
|
// Global Variable section |
|
struct alt sAlt; |
|
|
|
|
|
// ************************************************************************************************* |
|
// Extern section |
|
|
|
// Global flag for pressure sensor initialisation status |
|
extern u8 ps_ok; |
|
|
|
|
|
// ************************************************************************************************* |
|
// @fn reset_altitude_measurement |
|
// @brief Reset altitude measurement. |
|
// @param none |
|
// @return none |
|
// ************************************************************************************************* |
|
void reset_altitude_measurement(void) |
|
{ |
|
// Menu item is not visible |
|
sAlt.state = MENU_ITEM_NOT_VISIBLE; |
|
|
|
// Clear timeout counter |
|
sAlt.timeout = 0; |
|
|
|
// Set default altitude value |
|
sAlt.altitude = 0; |
|
|
|
// Pressure sensor ok? |
|
if (ps_ok) |
|
{ |
|
// Initialise pressure table |
|
init_pressure_table(); |
|
|
|
// Do single conversion |
|
start_altitude_measurement(); |
|
stop_altitude_measurement(); |
|
|
|
// Apply calibration offset and recalculate pressure table |
|
if (sAlt.altitude_offset != 0) |
|
{ |
|
sAlt.altitude += sAlt.altitude_offset; |
|
update_pressure_table(sAlt.altitude, sAlt.pressure, sAlt.temperature); |
|
} |
|
} |
|
} |
|
|
|
#ifndef CONFIG_METRIC_ONLY |
|
// ************************************************************************************************* |
|
// @fn conv_m_to_ft |
|
// @brief Convert meters to feet |
|
// @param u16 m Meters |
|
// @return u16 Feet |
|
// ************************************************************************************************* |
|
s16 convert_m_to_ft(s16 m) |
|
{ |
|
return (((s32)328*m)/100); |
|
} |
|
|
|
|
|
// ************************************************************************************************* |
|
// @fn conv_ft_to_m |
|
// @brief Convert feet to meters |
|
// @param u16 ft Feet |
|
// @return u16 Meters |
|
// ************************************************************************************************* |
|
s16 convert_ft_to_m(s16 ft) |
|
{ |
|
return (((s32)ft*61)/200); |
|
} |
|
|
|
#endif |
|
|
|
// ************************************************************************************************* |
|
// @fn is_altitude_measurement |
|
// @brief Altitude measurement check |
|
// @param none |
|
// @return u8 1=Measurement ongoing, 0=measurement off |
|
// ************************************************************************************************* |
|
u8 is_altitude_measurement(void) |
|
{ |
|
return ((sAlt.state == MENU_ITEM_VISIBLE) && (sAlt.timeout > 0)); |
|
} |
|
|
|
|
|
// ************************************************************************************************* |
|
// @fn start_altitude_measurement |
|
// @brief Start altitude measurement |
|
// @param none |
|
// @return none |
|
// ************************************************************************************************* |
|
void start_altitude_measurement(void) |
|
{ |
|
// Show warning if pressure sensor was not initialised properly |
|
if (!ps_ok) |
|
{ |
|
display_chars(LCD_SEG_L1_2_0, (u8*)"ERR", SEG_ON); |
|
return; |
|
} |
|
|
|
// Start altitude measurement if timeout has elapsed |
|
if (sAlt.timeout == 0) |
|
{ |
|
// Enable DRDY IRQ on rising edge |
|
PS_INT_IFG &= ~PS_INT_PIN; |
|
PS_INT_IE |= PS_INT_PIN; |
|
|
|
// Start pressure sensor |
|
ps_start(); |
|
|
|
// Set timeout counter only if sensor status was OK |
|
sAlt.timeout = ALTITUDE_MEASUREMENT_TIMEOUT; |
|
|
|
// Get updated altitude |
|
while((PS_INT_IN & PS_INT_PIN) == 0); |
|
do_altitude_measurement(FILTER_OFF); |
|
} |
|
} |
|
|
|
|
|
// ************************************************************************************************* |
|
// @fn stop_altitude_measurement |
|
// @brief Stop altitude measurement |
|
// @param none |
|
// @return none |
|
// ************************************************************************************************* |
|
void stop_altitude_measurement(void) |
|
{ |
|
// Return if pressure sensor was not initialised properly |
|
if (!ps_ok) return; |
|
|
|
// Stop pressure sensor |
|
ps_stop(); |
|
|
|
// Disable DRDY IRQ |
|
PS_INT_IE &= ~PS_INT_PIN; |
|
PS_INT_IFG &= ~PS_INT_PIN; |
|
|
|
// Clear timeout counter |
|
sAlt.timeout = 0; |
|
} |
|
|
|
|
|
|
|
// ************************************************************************************************* |
|
// @fn do_altitude_measurement |
|
// @brief Perform single altitude measurement |
|
// @param none |
|
// @return none |
|
// ************************************************************************************************* |
|
void do_altitude_measurement(u8 filter) |
|
{ |
|
volatile u32 pressure; |
|
|
|
// If sensor is not ready, skip data read |
|
if ((PS_INT_IN & PS_INT_PIN) == 0) return; |
|
|
|
// Get temperature (format is *10?K) from sensor |
|
sAlt.temperature = ps_get_temp(); |
|
|
|
// Get pressure (format is 1Pa) from sensor |
|
pressure = ps_get_pa(); |
|
|
|
// Store measured pressure value |
|
if (filter == FILTER_OFF) //sAlt.pressure == 0) |
|
{ |
|
sAlt.pressure = pressure; |
|
} |
|
else |
|
{ |
|
// Filter current pressure |
|
// FIXME: find a FIXEDPOINTER way |
|
pressure = (u32)((pressure * 0.2) + (sAlt.pressure * 0.8)); |
|
|
|
// Store average pressure |
|
sAlt.pressure = pressure; |
|
} |
|
|
|
// Convert pressure (Pa) and temperature (?K) to altitude (m) |
|
#ifdef FIXEDPOINT |
|
sAlt.altitude = conv_pa_to_altitude(sAlt.pressure, sAlt.temperature); |
|
#else |
|
sAlt.altitude = conv_pa_to_meter(sAlt.pressure, sAlt.temperature); |
|
#endif |
|
} |
|
|
|
|
|
// ************************************************************************************************* |
|
// @fn sx_altitude |
|
// @brief Altitude direct function. Sx restarts altitude measurement. |
|
// @param u8 line LINE1, LINE2 |
|
// @return none |
|
// ************************************************************************************************* |
|
void sx_altitude(u8 line) |
|
{ |
|
// Function can be empty |
|
|
|
// Restarting of altitude measurement will be done by subsequent full display update |
|
} |
|
|
|
|
|
// ************************************************************************************************* |
|
// @fn mx_altitude |
|
// @brief Mx button handler to set the altitude offset. |
|
// @param u8 line LINE1 |
|
// @return none |
|
// ************************************************************************************************* |
|
void mx_altitude(u8 line) |
|
{ |
|
s32 altitude; |
|
s32 limit_high, limit_low; |
|
|
|
// Clear display |
|
clear_display_all(); |
|
|
|
// Set lower and upper limits for offset correction |
|
#ifdef CONFIG_METRIC_ONLY |
|
display_symbol(LCD_UNIT_L1_M, SEG_ON); |
|
|
|
// Convert global variable to local variable |
|
altitude = sAlt.altitude; |
|
|
|
// Limits for set_value function |
|
limit_low = -100; |
|
limit_high = 4000; |
|
#else |
|
if (sys.flag.use_metric_units) |
|
{ |
|
// Display "m" symbol |
|
display_symbol(LCD_UNIT_L1_M, SEG_ON); |
|
|
|
// Convert global variable to local variable |
|
altitude = sAlt.altitude; |
|
|
|
// Limits for set_value function |
|
limit_low = -100; |
|
limit_high = 4000; |
|
} |
|
else // English units |
|
{ |
|
// Display "ft" symbol |
|
display_symbol(LCD_UNIT_L1_FT, SEG_ON); |
|
|
|
// Convert altitude in meters to feet |
|
altitude = sAlt.altitude; |
|
|
|
// Convert from meters to feet |
|
altitude = convert_m_to_ft(altitude); |
|
|
|
// Limits for set_value function |
|
limit_low = -500; |
|
limit_high = 9999; |
|
} |
|
#endif |
|
// Loop values until all are set or user breaks set |
|
while(1) |
|
{ |
|
// Idle timeout: exit without saving |
|
if (sys.flag.idle_timeout) break; |
|
|
|
// Button STAR (short): save, then exit |
|
if (button.flag.star) |
|
{ |
|
// When using English units, convert ft back to m before updating pressure table |
|
#ifndef CONFIG_METRIC_ONLY |
|
if (!sys.flag.use_metric_units) altitude = convert_ft_to_m((s16)altitude); |
|
#endif |
|
|
|
// Update pressure table |
|
update_pressure_table((s16)altitude, sAlt.pressure, sAlt.temperature); |
|
|
|
// Set display update flag |
|
display.flag.line1_full_update = 1; |
|
|
|
break; |
|
} |
|
|
|
// Set current altitude - offset is set when leaving function |
|
set_value(&altitude, 4, 3, limit_low, limit_high, SETVALUE_DISPLAY_VALUE + SETVALUE_FAST_MODE + SETVALUE_DISPLAY_ARROWS, LCD_SEG_L1_3_0, display_value1); |
|
} |
|
|
|
// Clear button flags |
|
button.all_flags = 0; |
|
} |
|
|
|
|
|
// ************************************************************************************************* |
|
// @fn display_altitude |
|
// @brief Display routine. Supports display in meters and feet. |
|
// @param u8 line LINE1 |
|
// u8 update DISPLAY_LINE_UPDATE_FULL, DISPLAY_LINE_UPDATE_PARTIAL, DISPLAY_LINE_CLEAR |
|
// @return none |
|
// ************************************************************************************************* |
|
void display_altitude(u8 line, u8 update) |
|
{ |
|
u8 * str; |
|
#ifndef CONFIG_METRIC_ONLY |
|
s16 ft; |
|
#endif |
|
|
|
// redraw whole screen |
|
if (update == DISPLAY_LINE_UPDATE_FULL) |
|
{ |
|
// Enable pressure measurement |
|
sAlt.state = MENU_ITEM_VISIBLE; |
|
|
|
// Start measurement |
|
start_altitude_measurement(); |
|
#ifdef CONFIG_METRIC_ONLY |
|
display_symbol(LCD_UNIT_L1_M, SEG_ON); |
|
#else |
|
if (sys.flag.use_metric_units) |
|
{ |
|
// Display "m" symbol |
|
display_symbol(LCD_UNIT_L1_M, SEG_ON); |
|
} |
|
else |
|
{ |
|
// Display "ft" symbol |
|
display_symbol(LCD_UNIT_L1_FT, SEG_ON); |
|
} |
|
#endif |
|
// Display altitude |
|
display_altitude(LINE1, DISPLAY_LINE_UPDATE_PARTIAL); |
|
} |
|
else if (update == DISPLAY_LINE_UPDATE_PARTIAL) |
|
{ |
|
// Update display only while measurement is active |
|
if (sAlt.timeout > 0) |
|
{ |
|
#ifndef CONFIG_METRIC_ONLY |
|
if (sys.flag.use_metric_units) |
|
{ |
|
#endif |
|
// Display altitude in xxxx m format, allow 3 leading blank digits |
|
if (sAlt.altitude >= 0) |
|
{ |
|
str = itoa(sAlt.altitude, 4, 3); |
|
display_symbol(LCD_SYMB_ARROW_UP, SEG_ON); |
|
display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); |
|
} |
|
else |
|
{ |
|
str = itoa(sAlt.altitude*(-1), 4, 3); |
|
display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); |
|
display_symbol(LCD_SYMB_ARROW_DOWN, SEG_ON); |
|
} |
|
#ifndef CONFIG_METRIC_ONLY |
|
} |
|
else |
|
{ |
|
// Convert from meters to feet |
|
ft = convert_m_to_ft(sAlt.altitude); |
|
|
|
// Limit to 9999ft (3047m) |
|
if (ft > 9999) ft = 9999; |
|
|
|
// Display altitude in xxxx ft format, allow 3 leading blank digits |
|
if (ft >= 0) |
|
{ |
|
str = itoa(ft, 4, 3); |
|
display_symbol(LCD_SYMB_ARROW_UP, SEG_ON); |
|
display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); |
|
} |
|
else |
|
{ |
|
str = itoa(ft*(-1), 4, 3); |
|
display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); |
|
display_symbol(LCD_SYMB_ARROW_DOWN, SEG_ON); |
|
} |
|
} |
|
#endif |
|
display_chars(LCD_SEG_L1_3_0, str, SEG_ON); |
|
} |
|
} |
|
else if (update == DISPLAY_LINE_CLEAR) |
|
{ |
|
// Disable pressure measurement |
|
sAlt.state = MENU_ITEM_NOT_VISIBLE; |
|
|
|
// Stop measurement |
|
stop_altitude_measurement(); |
|
|
|
// Clean up function-specific segments before leaving function |
|
display_symbol(LCD_UNIT_L1_M, SEG_OFF); |
|
display_symbol(LCD_UNIT_L1_FT, SEG_OFF); |
|
display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); |
|
display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); |
|
} |
|
} |
|
|
|
#endif // CONFIG_ALTITUDE
|
|
|