2017-03-22 15:52:59 +01:00
/**
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* @ addtogroup OpenPilotModules OpenPilot Modules
* @ {
2017-03-24 07:01:47 +01:00
* @ addtogroup UAVOHoTTBridge UAVO to HoTT Bridge Telemetry Module
2017-03-22 15:52:59 +01:00
* @ {
*
2017-03-28 07:58:50 +02:00
* @ file uavohottbridge . c
2019-02-17 04:15:44 +01:00
* @ author The LibrePilot Project , http : //www.librepilot.org Copyright (C) 2017-2019.
2017-03-24 07:01:47 +01:00
* Tau Labs , http : //taulabs.org, Copyright (C) 2013-2014
* @ brief sends telemery data on HoTT request
2017-03-22 15:52:59 +01:00
*
* @ see The GNU Public License ( GPL ) Version 3
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* 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
* the Free Software Foundation ; either version 3 of the License , or
* ( at your option ) any later version .
*
* 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 .
*
* You should have received a copy of the GNU General Public License along
* with this program ; if not , write to the Free Software Foundation , Inc . ,
* 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
*
* Additional note on redistribution : The copyright and license notices above
* must be maintained in each individual source file that is a derivative work
* of this source file ; otherwise redistribution is prohibited .
*/
# include "openpilot.h"
# include "hwsettings.h"
# include "taskinfo.h"
# include "callbackinfo.h"
2017-03-24 07:01:47 +01:00
# include "hottbridgesettings.h"
# include "attitudestate.h"
2019-03-24 22:51:15 +01:00
# include "accelstate.h"
2017-03-24 07:01:47 +01:00
# include "barosensor.h"
# include "flightbatterystate.h"
2017-03-22 15:52:59 +01:00
# include "flightstatus.h"
2017-03-24 07:01:47 +01:00
# include "gyrosensor.h"
# include "gpspositionsensor.h"
# include "gpstime.h"
2019-02-14 23:39:42 +01:00
# include "airspeedstate.h"
2017-03-24 07:01:47 +01:00
# include "homelocation.h"
2017-03-22 15:52:59 +01:00
# include "positionstate.h"
2017-03-24 07:01:47 +01:00
# include "systemalarms.h"
2017-03-22 15:52:59 +01:00
# include "velocitystate.h"
# include "hottbridgestatus.h"
2017-03-24 07:01:47 +01:00
# include "hottbridgesettings.h"
2019-02-17 04:15:44 +01:00
# include "revosettings.h"
2019-02-21 13:54:25 +01:00
# include "gpssettings.h"
# include "homelocation.h"
2017-03-22 15:52:59 +01:00
# include "objectpersistence.h"
# include "pios_sensors.h"
2017-03-24 07:01:47 +01:00
# include "uavohottbridge.h"
2017-03-22 15:52:59 +01:00
2017-04-13 15:12:40 +02:00
# include "pios_board_io.h"
2017-03-24 07:01:47 +01:00
# if defined(PIOS_INCLUDE_HOTT_BRIDGE)
2017-03-22 15:52:59 +01:00
# if defined(PIOS_HoTT_STACK_SIZE)
2017-03-24 07:01:47 +01:00
# define STACK_SIZE_BYTES PIOS_HoTT_STACK_SIZE
2017-03-22 15:52:59 +01:00
# else
2017-03-24 07:01:47 +01:00
# define STACK_SIZE_BYTES 2048
2017-03-22 15:52:59 +01:00
# endif
2017-03-24 07:01:47 +01:00
# define TASK_PRIORITY CALLBACK_TASK_AUXILIARY
2017-03-22 15:52:59 +01:00
static bool module_enabled = false ;
2017-03-24 07:01:47 +01:00
// Private variables
static bool module_enabled ;
static struct telemetrydata * telestate ;
static HoTTBridgeStatusData status ;
// Private functions
static void uavoHoTTBridgeTask ( void * parameters ) ;
static uint16_t build_VARIO_message ( struct hott_vario_message * msg ) ;
static uint16_t build_GPS_message ( struct hott_gps_message * msg ) ;
static uint16_t build_GAM_message ( struct hott_gam_message * msg ) ;
static uint16_t build_EAM_message ( struct hott_eam_message * msg ) ;
static uint16_t build_ESC_message ( struct hott_esc_message * msg ) ;
2019-02-21 13:54:25 +01:00
static bool build_TEXT_message ( struct hott_text_message * msg , uint8_t page , uint8_t current_line , int8_t value_change , uint8_t step_change , bool edit_line , bool exit_menu ) ;
static char * reverse_pixels ( char * line , uint8_t from_char , uint8_t to_char ) ;
static uint8_t get_page ( uint8_t page , bool next ) ;
static int16_t get_new_value ( int16_t current_value , int8_t value_change , uint8_t step , int16_t min , int16_t max ) ;
2017-03-24 07:01:47 +01:00
static uint8_t calc_checksum ( uint8_t * data , uint16_t size ) ;
static uint8_t generate_warning ( ) ;
2019-02-21 13:54:25 +01:00
static void store_settings ( uint8_t page ) ;
2017-03-24 07:01:47 +01:00
static void update_telemetrydata ( ) ;
static void convert_long2gps ( int32_t value , uint8_t * dir , uword_t * min , uword_t * sec ) ;
static uint8_t scale_float2uint8 ( float value , float scale , float offset ) ;
static int8_t scale_float2int8 ( float value , float scale , float offset ) ;
static uword_t scale_float2uword ( float value , float scale , float offset ) ;
2017-03-22 15:52:59 +01:00
/**
2017-03-24 07:01:47 +01:00
* Module start routine automatically called after initialization routine
* @ return 0 when was successful
2017-03-22 15:52:59 +01:00
*/
2017-03-24 07:01:47 +01:00
static int32_t uavoHoTTBridgeStart ( void )
2017-03-22 15:52:59 +01:00
{
2017-03-24 07:01:47 +01:00
status . TxPackets = 0 ;
status . RxPackets = 0 ;
status . TxFail = 0 ;
status . RxFail = 0 ;
2017-03-22 15:52:59 +01:00
2017-03-24 07:01:47 +01:00
// Start task
if ( module_enabled ) {
xTaskHandle taskHandle ;
xTaskCreate ( uavoHoTTBridgeTask , " uavoHoTTBridge " , STACK_SIZE_BYTES / 4 , NULL , TASK_PRIORITY , & taskHandle ) ;
PIOS_TASK_MONITOR_RegisterTask ( TASKINFO_RUNNING_UAVOHOTTBRIDGE , taskHandle ) ;
2017-03-22 15:52:59 +01:00
}
2017-03-24 07:01:47 +01:00
return 0 ;
2017-03-22 15:52:59 +01:00
}
2017-03-24 07:01:47 +01:00
/**
* Module initialization routine
* @ return 0 when initialization was successful
*/
static int32_t uavoHoTTBridgeInitialize ( void )
2017-03-22 15:52:59 +01:00
{
2017-03-24 07:01:47 +01:00
if ( PIOS_COM_HOTT ) {
module_enabled = true ;
// HoTT telemetry baudrate is fixed to 19200
PIOS_COM_ChangeBaud ( PIOS_COM_HOTT , 19200 ) ;
2017-04-17 00:50:08 +02:00
bool param = true ;
PIOS_COM_Ioctl ( PIOS_COM_HOTT , PIOS_IOCTL_USART_SET_HALFDUPLEX , & param ) ;
2017-03-24 07:01:47 +01:00
HoTTBridgeStatusInitialize ( ) ;
// allocate memory for telemetry data
telestate = ( struct telemetrydata * ) pios_malloc ( sizeof ( * telestate ) ) ;
if ( telestate = = NULL ) {
// there is not enough free memory. the module could not run.
module_enabled = false ;
return - 1 ;
}
} else {
module_enabled = false ;
2017-03-22 15:52:59 +01:00
}
2017-03-24 07:01:47 +01:00
return 0 ;
2017-03-22 15:52:59 +01:00
}
2017-03-24 07:01:47 +01:00
MODULE_INITCALL ( uavoHoTTBridgeInitialize , uavoHoTTBridgeStart ) ;
2017-03-22 15:52:59 +01:00
/**
2017-03-24 07:01:47 +01:00
* Main task . It does not return .
2017-03-22 15:52:59 +01:00
*/
2017-03-24 07:01:47 +01:00
static void uavoHoTTBridgeTask ( __attribute__ ( ( unused ) ) void * parameters )
2017-03-22 15:52:59 +01:00
{
2017-03-24 07:01:47 +01:00
uint8_t rx_buffer [ 2 ] ;
uint8_t tx_buffer [ HOTT_MAX_MESSAGE_LENGTH ] ;
uint16_t message_size ;
// clear all state values
memset ( telestate , 0 , sizeof ( * telestate ) ) ;
// initialize timer variables
portTickType lastSysTime = xTaskGetTickCount ( ) ;
// idle delay between telemetry request and answer
uint32_t idledelay = IDLE_TIME ;
// data delay between transmitted bytes
uint32_t datadelay = DATA_TIME ;
// work on hott telemetry. endless loop.
while ( 1 ) {
// clear message size on every loop before processing
message_size = 0 ;
// shift receiver buffer. make room for one byte.
rx_buffer [ 1 ] = rx_buffer [ 0 ] ;
// wait for a byte of telemetry request in data delay interval
while ( PIOS_COM_ReceiveBuffer ( PIOS_COM_HOTT , rx_buffer , 1 , 0 ) = = 0 ) {
vTaskDelayUntil ( & lastSysTime , datadelay / portTICK_RATE_MS ) ;
}
// set start trigger point
lastSysTime = xTaskGetTickCount ( ) ;
// examine received data stream
if ( rx_buffer [ 1 ] = = HOTT_BINARY_ID ) {
// first received byte looks like a binary request. check second received byte for a sensor id.
switch ( rx_buffer [ 0 ] ) {
case HOTT_VARIO_ID :
message_size = build_VARIO_message ( ( struct hott_vario_message * ) tx_buffer ) ;
break ;
case HOTT_GPS_ID :
message_size = build_GPS_message ( ( struct hott_gps_message * ) tx_buffer ) ;
break ;
case HOTT_GAM_ID :
message_size = build_GAM_message ( ( struct hott_gam_message * ) tx_buffer ) ;
break ;
case HOTT_EAM_ID :
message_size = build_EAM_message ( ( struct hott_eam_message * ) tx_buffer ) ;
break ;
case HOTT_ESC_ID :
message_size = build_ESC_message ( ( struct hott_esc_message * ) tx_buffer ) ;
break ;
default :
message_size = 0 ;
}
} else if ( rx_buffer [ 1 ] = = HOTT_TEXT_ID ) {
// first received byte looks like a text request. check second received byte for a valid button.
2019-02-21 13:54:25 +01:00
uint8_t id_key = rx_buffer [ 0 ] & 0x0F ;
uint8_t id_sensor = rx_buffer [ 0 ] > > 4 ;
static bool edit_line = false ;
bool exit_menu = false ;
bool is_saved = false ;
2019-02-17 04:15:44 +01:00
2019-02-26 20:36:53 +01:00
int8_t value_change = 0 ;
2019-02-21 13:54:25 +01:00
static uint8_t step_change = 0 ;
2019-02-17 04:15:44 +01:00
2019-02-21 13:54:25 +01:00
// define allowed edited lines for Main, GPS config, Vario, Gps, General, Electric and Esc pages
uint8_t min_line [ ] = { 2 , 2 , 2 , 2 , 2 , 2 , 2 } ;
uint8_t max_line [ ] = { 6 , 5 , 7 , 7 , 7 , 7 , 7 } ;
2019-02-17 04:15:44 +01:00
2019-02-21 13:54:25 +01:00
static uint8_t page = HOTTTEXT_PAGE_MAIN ;
2019-02-17 04:15:44 +01:00
static uint8_t last_page = 0 ;
static uint8_t current_line = 0 ;
// select page to display from text request
switch ( id_sensor ) {
case ( HOTT_VARIO_ID & 0x0f ) :
2019-02-21 13:54:25 +01:00
page = HOTTTEXT_PAGE_VARIO ;
2017-03-24 07:01:47 +01:00
break ;
2019-02-17 04:15:44 +01:00
case ( HOTT_GPS_ID & 0x0f ) :
2019-02-21 13:54:25 +01:00
page = HOTTTEXT_PAGE_GPS ;
2019-02-17 04:15:44 +01:00
break ;
case ( HOTT_GAM_ID & 0x0f ) :
2019-02-21 13:54:25 +01:00
page = HOTTTEXT_PAGE_GENERAL ;
2019-02-17 04:15:44 +01:00
break ;
case ( HOTT_EAM_ID & 0x0f ) :
2019-02-21 13:54:25 +01:00
page = HOTTTEXT_PAGE_ELECTRIC ;
2019-02-17 04:15:44 +01:00
break ;
case ( HOTT_ESC_ID & 0x0f ) :
2019-02-21 13:54:25 +01:00
page = HOTTTEXT_PAGE_ESC ;
2019-02-17 04:15:44 +01:00
}
// menu keys
2019-02-21 13:54:25 +01:00
if ( edit_line ) {
switch ( id_key ) {
case HOTT_KEY_DEC : // up
value_change - - ;
break ;
case HOTT_KEY_INC : // down
value_change + + ;
break ;
case HOTT_KEY_PREV : // left
2019-02-26 20:36:53 +01:00
if ( step_change < 3 ) {
2019-02-21 13:54:25 +01:00
step_change + + ;
}
break ;
case HOTT_KEY_NEXT : // right
if ( step_change > 0 ) {
step_change - - ;
}
break ;
case HOTT_KEY_SET : // Set
value_change = 0 ;
step_change = 0 ;
if ( ! is_saved ) {
store_settings ( page ) ;
edit_line = false ; // exit edit mode
}
break ;
default :
value_change = 0 ;
}
} else {
switch ( id_key ) {
case HOTT_KEY_DEC : // up
current_line - - ;
break ;
case HOTT_KEY_INC : // down
current_line + + ;
break ;
case HOTT_KEY_PREV : // left
exit_menu = ( page = = HOTTTEXT_PAGE_MAIN ) ? true : false ;
page = get_page ( page , false ) ;
break ;
case HOTT_KEY_NEXT : // right
exit_menu = false ;
current_line = 0 ;
page = get_page ( page , true ) ;
break ;
case HOTT_KEY_SET : // Set
edit_line = true ; // enter edit mode
break ;
}
}
// new page
if ( page ! = last_page ) {
last_page = page ;
2019-02-17 04:15:44 +01:00
current_line = 0 ;
2019-02-21 13:54:25 +01:00
edit_line = false ;
2019-02-17 04:15:44 +01:00
}
// keep current line between min/max limits
if ( current_line > max_line [ page ] ) {
current_line = max_line [ page ] ;
}
if ( current_line < min_line [ page ] ) {
current_line = min_line [ page ] ;
}
2019-02-21 13:54:25 +01:00
status . RxFail = step_change ;
status . TxFail = value_change ;
2019-02-17 04:15:44 +01:00
2019-02-26 20:36:53 +01:00
is_saved = build_TEXT_message ( ( struct hott_text_message * ) tx_buffer , page , current_line , value_change , step_change , edit_line , exit_menu ) ;
message_size = sizeof ( tx_buffer ) ;
2019-02-21 13:54:25 +01:00
if ( is_saved ) {
// is already saved, exit edit mode
edit_line = false ;
2017-03-24 07:01:47 +01:00
}
2017-03-22 15:52:59 +01:00
}
2017-03-24 07:01:47 +01:00
// check if a message is in the transmit buffer.
if ( message_size > 0 ) {
status . RxPackets + + ;
2017-03-22 15:52:59 +01:00
2017-03-24 07:01:47 +01:00
// check idle line before transmit. pause, then check receiver buffer
vTaskDelayUntil ( & lastSysTime , idledelay / portTICK_RATE_MS ) ;
2017-03-22 15:52:59 +01:00
2017-03-24 07:01:47 +01:00
if ( PIOS_COM_ReceiveBuffer ( PIOS_COM_HOTT , rx_buffer , 1 , 0 ) = = 0 ) {
// nothing received means idle line. ready to transmit the requested message
for ( int i = 0 ; i < message_size ; i + + ) {
// send message content with pause between each byte
PIOS_COM_SendCharNonBlocking ( PIOS_COM_HOTT , tx_buffer [ i ] ) ;
// grab possible incoming loopback data and throw it away
PIOS_COM_ReceiveBuffer ( PIOS_COM_HOTT , rx_buffer , sizeof ( rx_buffer ) , 0 ) ;
vTaskDelayUntil ( & lastSysTime , datadelay / portTICK_RATE_MS ) ;
}
status . TxPackets + + ;
2017-03-22 15:52:59 +01:00
2017-03-24 07:01:47 +01:00
// after transmitting the message, any loopback data needs to be cleaned up.
vTaskDelayUntil ( & lastSysTime , idledelay / portTICK_RATE_MS ) ;
PIOS_COM_ReceiveBuffer ( PIOS_COM_HOTT , tx_buffer , message_size , 0 ) ;
} else {
status . RxFail + + ;
}
HoTTBridgeStatusSet ( & status ) ;
}
}
2017-03-22 15:52:59 +01:00
}
/**
2017-03-24 07:01:47 +01:00
* Build requested answer messages .
* \ return value sets message size
2017-03-22 15:52:59 +01:00
*/
2017-03-24 07:01:47 +01:00
uint16_t build_VARIO_message ( struct hott_vario_message * msg )
2017-03-22 15:52:59 +01:00
{
2017-03-24 07:01:47 +01:00
update_telemetrydata ( ) ;
if ( telestate - > Settings . Sensor . VARIO = = HOTTBRIDGESETTINGS_SENSOR_DISABLED ) {
return 0 ;
2017-03-22 15:52:59 +01:00
}
2017-03-24 07:01:47 +01:00
// clear message buffer
memset ( msg , 0 , sizeof ( * msg ) ) ;
// message header
msg - > start = HOTT_START ;
msg - > stop = HOTT_STOP ;
msg - > sensor_id = HOTT_VARIO_ID ;
msg - > warning = generate_warning ( ) ;
msg - > sensor_text_id = HOTT_VARIO_TEXT_ID ;
// alarm inverse bits. invert display areas on limits
msg - > alarm_inverse | = ( telestate - > Settings . Limit . MinHeight > telestate - > altitude ) ? VARIO_INVERT_ALT : 0 ;
msg - > alarm_inverse | = ( telestate - > Settings . Limit . MaxHeight < telestate - > altitude ) ? VARIO_INVERT_ALT : 0 ;
msg - > alarm_inverse | = ( telestate - > Settings . Limit . MaxHeight < telestate - > altitude ) ? VARIO_INVERT_MAX : 0 ;
msg - > alarm_inverse | = ( telestate - > Settings . Limit . MinHeight > telestate - > altitude ) ? VARIO_INVERT_MIN : 0 ;
msg - > alarm_inverse | = ( telestate - > Settings . Limit . NegDifference1 > telestate - > climbrate1s ) ? VARIO_INVERT_CR1S : 0 ;
msg - > alarm_inverse | = ( telestate - > Settings . Limit . PosDifference1 < telestate - > climbrate1s ) ? VARIO_INVERT_CR1S : 0 ;
msg - > alarm_inverse | = ( telestate - > Settings . Limit . NegDifference2 > telestate - > climbrate3s ) ? VARIO_INVERT_CR3S : 0 ;
msg - > alarm_inverse | = ( telestate - > Settings . Limit . PosDifference2 < telestate - > climbrate3s ) ? VARIO_INVERT_CR3S : 0 ;
msg - > alarm_inverse | = ( telestate - > Settings . Limit . NegDifference2 > telestate - > climbrate10s ) ? VARIO_INVERT_CR10S : 0 ;
msg - > alarm_inverse | = ( telestate - > Settings . Limit . PosDifference2 < telestate - > climbrate10s ) ? VARIO_INVERT_CR10S : 0 ;
// altitude relative to ground
msg - > altitude = scale_float2uword ( telestate - > altitude , 1 , OFFSET_ALTITUDE ) ;
msg - > min_altitude = scale_float2uword ( telestate - > min_altitude , 1 , OFFSET_ALTITUDE ) ;
msg - > max_altitude = scale_float2uword ( telestate - > max_altitude , 1 , OFFSET_ALTITUDE ) ;
// climbrate
msg - > climbrate = scale_float2uword ( telestate - > climbrate1s , M_TO_CM , OFFSET_CLIMBRATE ) ;
msg - > climbrate3s = scale_float2uword ( telestate - > climbrate3s , M_TO_CM , OFFSET_CLIMBRATE ) ;
msg - > climbrate10s = scale_float2uword ( telestate - > climbrate10s , M_TO_CM , OFFSET_CLIMBRATE ) ;
// compass
msg - > compass = scale_float2int8 ( telestate - > Attitude . Yaw , DEG_TO_UINT , 0 ) ;
// statusline
memcpy ( msg - > ascii , telestate - > statusline , sizeof ( msg - > ascii ) ) ;
// free display characters
msg - > ascii1 = 0 ;
msg - > ascii2 = 0 ;
msg - > ascii3 = 0 ;
msg - > checksum = calc_checksum ( ( uint8_t * ) msg , sizeof ( * msg ) ) ;
return sizeof ( * msg ) ;
2017-03-22 15:52:59 +01:00
}
2017-03-24 07:01:47 +01:00
uint16_t build_GPS_message ( struct hott_gps_message * msg )
2017-03-22 15:52:59 +01:00
{
2017-03-24 07:01:47 +01:00
update_telemetrydata ( ) ;
2017-03-22 15:52:59 +01:00
2017-03-24 07:01:47 +01:00
if ( telestate - > Settings . Sensor . GPS = = HOTTBRIDGESETTINGS_SENSOR_DISABLED ) {
return 0 ;
}
2017-03-22 15:52:59 +01:00
2017-03-24 07:01:47 +01:00
// clear message buffer
memset ( msg , 0 , sizeof ( * msg ) ) ;
// message header
msg - > start = HOTT_START ;
msg - > stop = HOTT_STOP ;
msg - > sensor_id = HOTT_GPS_ID ;
msg - > warning = generate_warning ( ) ;
msg - > sensor_text_id = HOTT_GPS_TEXT_ID ;
// alarm inverse bits. invert display areas on limits
msg - > alarm_inverse1 | = ( telestate - > Settings . Limit . MaxDistance < telestate - > homedistance ) ? GPS_INVERT_HDIST : 0 ;
msg - > alarm_inverse1 | = ( telestate - > Settings . Limit . MinSpeed > telestate - > GPS . Groundspeed ) ? GPS_INVERT_SPEED : 0 ;
msg - > alarm_inverse1 | = ( telestate - > Settings . Limit . MaxSpeed < telestate - > GPS . Groundspeed ) ? GPS_INVERT_SPEED : 0 ;
msg - > alarm_inverse1 | = ( telestate - > Settings . Limit . MinHeight > telestate - > altitude ) ? GPS_INVERT_ALT : 0 ;
msg - > alarm_inverse1 | = ( telestate - > Settings . Limit . MaxHeight < telestate - > altitude ) ? GPS_INVERT_ALT : 0 ;
msg - > alarm_inverse1 | = ( telestate - > Settings . Limit . NegDifference1 > telestate - > climbrate1s ) ? GPS_INVERT_CR1S : 0 ;
msg - > alarm_inverse1 | = ( telestate - > Settings . Limit . PosDifference1 < telestate - > climbrate1s ) ? GPS_INVERT_CR1S : 0 ;
msg - > alarm_inverse1 | = ( telestate - > Settings . Limit . NegDifference2 > telestate - > climbrate3s ) ? GPS_INVERT_CR3S : 0 ;
msg - > alarm_inverse1 | = ( telestate - > Settings . Limit . PosDifference2 < telestate - > climbrate3s ) ? GPS_INVERT_CR3S : 0 ;
msg - > alarm_inverse2 | = ( telestate - > SysAlarms . Alarm . GPS ! = SYSTEMALARMS_ALARM_OK ) ? GPS_INVERT2_POS : 0 ;
// gps direction, groundspeed and postition
msg - > flight_direction = scale_float2uint8 ( telestate - > GPS . Heading , DEG_TO_UINT , 0 ) ;
msg - > gps_speed = scale_float2uword ( telestate - > GPS . Groundspeed , MS_TO_KMH , 0 ) ;
convert_long2gps ( telestate - > GPS . Latitude , & msg - > latitude_ns , & msg - > latitude_min , & msg - > latitude_sec ) ;
convert_long2gps ( telestate - > GPS . Longitude , & msg - > longitude_ew , & msg - > longitude_min , & msg - > longitude_sec ) ;
// homelocation distance, course and state
msg - > distance = scale_float2uword ( telestate - > homedistance , 1 , 0 ) ;
msg - > home_direction = scale_float2uint8 ( telestate - > homecourse , DEG_TO_UINT , 0 ) ;
msg - > ascii5 = ( telestate - > Home . Set ? ' H ' : ' - ' ) ;
// altitude relative to ground and climb rate
msg - > altitude = scale_float2uword ( telestate - > altitude , 1 , OFFSET_ALTITUDE ) ;
msg - > climbrate = scale_float2uword ( telestate - > climbrate1s , M_TO_CM , OFFSET_CLIMBRATE ) ;
msg - > climbrate3s = scale_float2uint8 ( telestate - > climbrate3s , 1 , OFFSET_CLIMBRATE3S ) ;
// number of satellites,gps fix and state
msg - > gps_num_sat = telestate - > GPS . Satellites ;
switch ( telestate - > GPS . Status ) {
case GPSPOSITIONSENSOR_STATUS_FIX2D :
msg - > gps_fix_char = ' 2 ' ;
break ;
case GPSPOSITIONSENSOR_STATUS_FIX3D :
2017-06-23 19:42:58 +02:00
case GPSPOSITIONSENSOR_STATUS_FIX3DDGNSS :
2017-03-24 07:01:47 +01:00
msg - > gps_fix_char = ' 3 ' ;
break ;
default :
msg - > gps_fix_char = 0 ;
}
switch ( telestate - > SysAlarms . Alarm . GPS ) {
case SYSTEMALARMS_ALARM_UNINITIALISED :
msg - > ascii6 = 0 ;
// if there is no gps, show compass flight direction
msg - > flight_direction = scale_float2int8 ( ( telestate - > Attitude . Yaw > 0 ) ? telestate - > Attitude . Yaw : 360 + telestate - > Attitude . Yaw , DEG_TO_UINT , 0 ) ;
break ;
case SYSTEMALARMS_ALARM_OK :
msg - > ascii6 = ' . ' ;
break ;
case SYSTEMALARMS_ALARM_WARNING :
msg - > ascii6 = ' ? ' ;
break ;
case SYSTEMALARMS_ALARM_ERROR :
case SYSTEMALARMS_ALARM_CRITICAL :
msg - > ascii6 = ' ! ' ;
break ;
default :
msg - > ascii6 = 0 ;
}
2017-03-22 15:52:59 +01:00
2017-03-24 07:01:47 +01:00
// model angles
msg - > angle_roll = scale_float2int8 ( telestate - > Attitude . Roll , DEG_TO_UINT , 0 ) ;
msg - > angle_nick = scale_float2int8 ( telestate - > Attitude . Pitch , DEG_TO_UINT , 0 ) ;
msg - > angle_compass = scale_float2int8 ( telestate - > Attitude . Yaw , DEG_TO_UINT , 0 ) ;
// gps time
msg - > gps_hour = telestate - > GPStime . Hour ;
msg - > gps_min = telestate - > GPStime . Minute ;
msg - > gps_sec = telestate - > GPStime . Second ;
msg - > gps_msec = 0 ;
// gps MSL (NN) altitude MSL
msg - > msl = scale_float2uword ( telestate - > GPS . Altitude , 1 , 0 ) ;
// free display chararacter
msg - > ascii4 = 0 ;
msg - > checksum = calc_checksum ( ( uint8_t * ) msg , sizeof ( * msg ) ) ;
return sizeof ( * msg ) ;
2017-03-22 15:52:59 +01:00
}
2017-03-24 07:01:47 +01:00
uint16_t build_GAM_message ( struct hott_gam_message * msg )
2017-03-22 15:52:59 +01:00
{
2017-03-24 07:01:47 +01:00
update_telemetrydata ( ) ;
2017-03-22 15:52:59 +01:00
2017-03-24 07:01:47 +01:00
if ( telestate - > Settings . Sensor . GAM = = HOTTBRIDGESETTINGS_SENSOR_DISABLED ) {
return 0 ;
2017-03-22 15:52:59 +01:00
}
2017-03-24 07:01:47 +01:00
// clear message buffer
memset ( msg , 0 , sizeof ( * msg ) ) ;
// message header
msg - > start = HOTT_START ;
msg - > stop = HOTT_STOP ;
msg - > sensor_id = HOTT_GAM_ID ;
msg - > warning = generate_warning ( ) ;
msg - > sensor_text_id = HOTT_GAM_TEXT_ID ;
// alarm inverse bits. invert display areas on limits
msg - > alarm_inverse2 | = ( telestate - > Settings . Limit . MaxCurrent < telestate - > Battery . Current ) ? GAM_INVERT2_CURRENT : 0 ;
msg - > alarm_inverse2 | = ( telestate - > Settings . Limit . MinPowerVoltage > telestate - > Battery . Voltage ) ? GAM_INVERT2_VOLTAGE : 0 ;
msg - > alarm_inverse2 | = ( telestate - > Settings . Limit . MaxPowerVoltage < telestate - > Battery . Voltage ) ? GAM_INVERT2_VOLTAGE : 0 ;
msg - > alarm_inverse2 | = ( telestate - > Settings . Limit . MinHeight > telestate - > altitude ) ? GAM_INVERT2_ALT : 0 ;
msg - > alarm_inverse2 | = ( telestate - > Settings . Limit . MaxHeight < telestate - > altitude ) ? GAM_INVERT2_ALT : 0 ;
msg - > alarm_inverse2 | = ( telestate - > Settings . Limit . NegDifference1 > telestate - > climbrate1s ) ? GAM_INVERT2_CR1S : 0 ;
msg - > alarm_inverse2 | = ( telestate - > Settings . Limit . PosDifference1 < telestate - > climbrate1s ) ? GAM_INVERT2_CR1S : 0 ;
msg - > alarm_inverse2 | = ( telestate - > Settings . Limit . NegDifference2 > telestate - > climbrate3s ) ? GAM_INVERT2_CR3S : 0 ;
msg - > alarm_inverse2 | = ( telestate - > Settings . Limit . PosDifference2 < telestate - > climbrate3s ) ? GAM_INVERT2_CR3S : 0 ;
// temperatures
msg - > temperature1 = scale_float2uint8 ( telestate - > Gyro . temperature , 1 , OFFSET_TEMPERATURE ) ;
msg - > temperature2 = scale_float2uint8 ( telestate - > Baro . Temperature , 1 , OFFSET_TEMPERATURE ) ;
// altitude
msg - > altitude = scale_float2uword ( telestate - > altitude , 1 , OFFSET_ALTITUDE ) ;
// climbrate
msg - > climbrate = scale_float2uword ( telestate - > climbrate1s , M_TO_CM , OFFSET_CLIMBRATE ) ;
msg - > climbrate3s = scale_float2uint8 ( telestate - > climbrate3s , 1 , OFFSET_CLIMBRATE3S ) ;
// main battery
float voltage = ( telestate - > Battery . Voltage > 0 ) ? telestate - > Battery . Voltage : 0 ;
float current = ( telestate - > Battery . Current > 0 ) ? telestate - > Battery . Current : 0 ;
float energy = ( telestate - > Battery . ConsumedEnergy > 0 ) ? telestate - > Battery . ConsumedEnergy : 0 ;
msg - > voltage = scale_float2uword ( voltage , 10 , 0 ) ;
msg - > current = scale_float2uword ( current , 10 , 0 ) ;
msg - > capacity = scale_float2uword ( energy , 0.1f , 0 ) ;
2019-02-18 18:21:55 +01:00
// simulate individual cell voltage
uint8_t cell_voltage = ( telestate - > Battery . Voltage > 0 ) ? scale_float2uint8 ( telestate - > Battery . Voltage / telestate - > Battery . NbCells , 50 , 0 ) : 0 ;
msg - > cell1 = ( telestate - > Battery . NbCells > = 1 ) ? cell_voltage : 0 ;
msg - > cell2 = ( telestate - > Battery . NbCells > = 2 ) ? cell_voltage : 0 ;
msg - > cell3 = ( telestate - > Battery . NbCells > = 3 ) ? cell_voltage : 0 ;
msg - > cell4 = ( telestate - > Battery . NbCells > = 4 ) ? cell_voltage : 0 ;
msg - > cell5 = ( telestate - > Battery . NbCells > = 5 ) ? cell_voltage : 0 ;
msg - > cell6 = ( telestate - > Battery . NbCells > = 6 ) ? cell_voltage : 0 ;
msg - > min_cell_volt = cell_voltage ;
msg - > min_cell_volt_num = telestate - > Battery . NbCells ;
// apply main voltage to batt1 voltage
msg - > batt1_voltage = msg - > voltage ;
2019-02-14 23:39:42 +01:00
// AirSpeed
float airspeed = ( telestate - > Airspeed . TrueAirspeed > 0 ) ? telestate - > Airspeed . TrueAirspeed : 0 ;
msg - > speed = scale_float2uword ( airspeed , MS_TO_KMH , 0 ) ;
2017-03-24 07:01:47 +01:00
// pressure kPa to 0.1Bar
msg - > pressure = scale_float2uint8 ( telestate - > Baro . Pressure , 0.1f , 0 ) ;
msg - > checksum = calc_checksum ( ( uint8_t * ) msg , sizeof ( * msg ) ) ;
return sizeof ( * msg ) ;
2017-03-22 15:52:59 +01:00
}
2017-03-24 07:01:47 +01:00
uint16_t build_EAM_message ( struct hott_eam_message * msg )
2017-03-22 15:52:59 +01:00
{
2017-03-24 07:01:47 +01:00
update_telemetrydata ( ) ;
if ( telestate - > Settings . Sensor . EAM = = HOTTBRIDGESETTINGS_SENSOR_DISABLED ) {
return 0 ;
}
// clear message buffer
memset ( msg , 0 , sizeof ( * msg ) ) ;
// message header
msg - > start = HOTT_START ;
msg - > stop = HOTT_STOP ;
msg - > sensor_id = HOTT_EAM_ID ;
msg - > warning = generate_warning ( ) ;
msg - > sensor_text_id = HOTT_EAM_TEXT_ID ;
// alarm inverse bits. invert display areas on limits
msg - > alarm_inverse1 | = ( telestate - > Settings . Limit . MaxUsedCapacity < telestate - > Battery . ConsumedEnergy ) ? EAM_INVERT_CAPACITY : 0 ;
msg - > alarm_inverse1 | = ( telestate - > Settings . Limit . MaxCurrent < telestate - > Battery . Current ) ? EAM_INVERT_CURRENT : 0 ;
msg - > alarm_inverse1 | = ( telestate - > Settings . Limit . MinPowerVoltage > telestate - > Battery . Voltage ) ? EAM_INVERT_VOLTAGE : 0 ;
msg - > alarm_inverse1 | = ( telestate - > Settings . Limit . MaxPowerVoltage < telestate - > Battery . Voltage ) ? EAM_INVERT_VOLTAGE : 0 ;
msg - > alarm_inverse2 | = ( telestate - > Settings . Limit . MinHeight > telestate - > altitude ) ? EAM_INVERT2_ALT : 0 ;
msg - > alarm_inverse2 | = ( telestate - > Settings . Limit . MaxHeight < telestate - > altitude ) ? EAM_INVERT2_ALT : 0 ;
msg - > alarm_inverse2 | = ( telestate - > Settings . Limit . NegDifference1 > telestate - > climbrate1s ) ? EAM_INVERT2_CR1S : 0 ;
msg - > alarm_inverse2 | = ( telestate - > Settings . Limit . PosDifference1 < telestate - > climbrate1s ) ? EAM_INVERT2_CR1S : 0 ;
msg - > alarm_inverse2 | = ( telestate - > Settings . Limit . NegDifference2 > telestate - > climbrate3s ) ? EAM_INVERT2_CR3S : 0 ;
msg - > alarm_inverse2 | = ( telestate - > Settings . Limit . PosDifference2 < telestate - > climbrate3s ) ? EAM_INVERT2_CR3S : 0 ;
// main battery
float voltage = ( telestate - > Battery . Voltage > 0 ) ? telestate - > Battery . Voltage : 0 ;
float current = ( telestate - > Battery . Current > 0 ) ? telestate - > Battery . Current : 0 ;
float energy = ( telestate - > Battery . ConsumedEnergy > 0 ) ? telestate - > Battery . ConsumedEnergy : 0 ;
2019-02-16 12:27:26 +01:00
msg - > voltage = scale_float2uword ( voltage , 10 , 0 ) ;
msg - > current = scale_float2uword ( current , 10 , 0 ) ;
msg - > capacity = scale_float2uword ( energy , 0.1f , 0 ) ;
2017-03-24 07:01:47 +01:00
2019-02-18 18:21:55 +01:00
// simulate individual cell voltage
uint8_t cell_voltage = ( telestate - > Battery . Voltage > 0 ) ? scale_float2uint8 ( telestate - > Battery . Voltage / telestate - > Battery . NbCells , 50 , 0 ) : 0 ;
msg - > cell1_H = ( telestate - > Battery . NbCells > = 1 ) ? cell_voltage : 0 ;
msg - > cell2_H = ( telestate - > Battery . NbCells > = 2 ) ? cell_voltage : 0 ;
msg - > cell3_H = ( telestate - > Battery . NbCells > = 3 ) ? cell_voltage : 0 ;
msg - > cell4_H = ( telestate - > Battery . NbCells > = 4 ) ? cell_voltage : 0 ;
msg - > cell5_H = ( telestate - > Battery . NbCells > = 5 ) ? cell_voltage : 0 ;
msg - > cell6_H = ( telestate - > Battery . NbCells > = 6 ) ? cell_voltage : 0 ;
msg - > cell7_H = ( telestate - > Battery . NbCells > = 7 ) ? cell_voltage : 0 ;
// apply main voltage to batt1 voltage
msg - > batt1_voltage = msg - > voltage ;
2019-02-14 23:39:42 +01:00
// AirSpeed
float airspeed = ( telestate - > Airspeed . TrueAirspeed > 0 ) ? telestate - > Airspeed . TrueAirspeed : 0 ;
2019-02-16 12:27:26 +01:00
msg - > speed = scale_float2uword ( airspeed , MS_TO_KMH , 0 ) ;
2019-02-14 23:39:42 +01:00
2017-03-24 07:01:47 +01:00
// temperatures
msg - > temperature1 = scale_float2uint8 ( telestate - > Gyro . temperature , 1 , OFFSET_TEMPERATURE ) ;
msg - > temperature2 = scale_float2uint8 ( telestate - > Baro . Temperature , 1 , OFFSET_TEMPERATURE ) ;
// altitude
msg - > altitude = scale_float2uword ( telestate - > altitude , 1 , OFFSET_ALTITUDE ) ;
// climbrate
msg - > climbrate = scale_float2uword ( telestate - > climbrate1s , M_TO_CM , OFFSET_CLIMBRATE ) ;
msg - > climbrate3s = scale_float2uint8 ( telestate - > climbrate3s , 1 , OFFSET_CLIMBRATE3S ) ;
// flight time
float flighttime = ( telestate - > Battery . EstimatedFlightTime < = 5999 ) ? telestate - > Battery . EstimatedFlightTime : 5999 ;
msg - > electric_min = flighttime / 60 ;
msg - > electric_sec = flighttime - 60 * msg - > electric_min ;
msg - > checksum = calc_checksum ( ( uint8_t * ) msg , sizeof ( * msg ) ) ;
return sizeof ( * msg ) ;
2017-03-22 15:52:59 +01:00
}
2017-03-24 07:01:47 +01:00
uint16_t build_ESC_message ( struct hott_esc_message * msg )
2017-03-22 15:52:59 +01:00
{
2017-03-24 07:01:47 +01:00
update_telemetrydata ( ) ;
2017-03-22 15:52:59 +01:00
2017-03-24 07:01:47 +01:00
if ( telestate - > Settings . Sensor . ESC = = HOTTBRIDGESETTINGS_SENSOR_DISABLED ) {
return 0 ;
}
// clear message buffer
memset ( msg , 0 , sizeof ( * msg ) ) ;
// message header
msg - > start = HOTT_START ;
msg - > stop = HOTT_STOP ;
msg - > sensor_id = HOTT_ESC_ID ;
msg - > warning = 0 ;
msg - > sensor_text_id = HOTT_ESC_TEXT_ID ;
2019-02-21 13:54:25 +01:00
// main battery
2017-03-24 07:01:47 +01:00
float voltage = ( telestate - > Battery . Voltage > 0 ) ? telestate - > Battery . Voltage : 0 ;
float current = ( telestate - > Battery . Current > 0 ) ? telestate - > Battery . Current : 0 ;
float max_current = ( telestate - > Battery . PeakCurrent > 0 ) ? telestate - > Battery . PeakCurrent : 0 ;
float energy = ( telestate - > Battery . ConsumedEnergy > 0 ) ? telestate - > Battery . ConsumedEnergy : 0 ;
msg - > batt_voltage = scale_float2uword ( voltage , 10 , 0 ) ;
msg - > current = scale_float2uword ( current , 10 , 0 ) ;
msg - > max_current = scale_float2uword ( max_current , 10 , 0 ) ;
msg - > batt_capacity = scale_float2uword ( energy , 0.1f , 0 ) ;
// temperatures
msg - > temperatureESC = scale_float2uint8 ( telestate - > Gyro . temperature , 1 , OFFSET_TEMPERATURE ) ;
msg - > max_temperatureESC = scale_float2uint8 ( 0 , 1 , OFFSET_TEMPERATURE ) ;
msg - > temperatureMOT = scale_float2uint8 ( telestate - > Baro . Temperature , 1 , OFFSET_TEMPERATURE ) ;
msg - > max_temperatureMOT = scale_float2uint8 ( 0 , 1 , OFFSET_TEMPERATURE ) ;
msg - > checksum = calc_checksum ( ( uint8_t * ) msg , sizeof ( * msg ) ) ;
return sizeof ( * msg ) ;
2017-03-22 15:52:59 +01:00
}
2019-02-21 13:54:25 +01:00
bool build_TEXT_message ( struct hott_text_message * msg , uint8_t page , uint8_t current_line , int8_t value_change , uint8_t step , bool edit_mode , bool exit_menu )
2017-03-22 15:52:59 +01:00
{
2017-03-24 07:01:47 +01:00
// clear message buffer
memset ( msg , 0 , sizeof ( * msg ) ) ;
2017-03-22 15:52:59 +01:00
2017-03-24 07:01:47 +01:00
// message header
2019-02-17 04:15:44 +01:00
msg - > start = HOTT_TEXT_START ;
2017-03-24 07:01:47 +01:00
msg - > stop = HOTT_STOP ;
2019-02-17 04:15:44 +01:00
msg - > sensor_id = ( exit_menu = = true ) ? 0x01 : 0x00 ; // exit menu / normal
msg - > warning = 0 ;
HoTTBridgeSettingsSensorData sensor ;
2019-02-21 13:54:25 +01:00
HoTTBridgeSettingsLimitData alarmLimits ;
HoTTBridgeSettingsWarningData alarmWarning ;
2019-02-17 04:15:44 +01:00
RevoSettingsFusionAlgorithmOptions revoFusionAlgo ;
2019-02-21 13:54:25 +01:00
HomeLocationSetOptions homeSet ;
GPSSettingsData gpsSettings ;
2017-03-22 15:52:59 +01:00
2019-02-21 13:54:25 +01:00
bool storedtoflash = false ;
bool ekf_enabled = false ;
2019-02-17 04:15:44 +01:00
// page title
2019-02-21 13:54:25 +01:00
snprintf ( msg - > text [ 0 ] , HOTT_TEXT_COLUMNS , " %s " , hottTextPageTitle [ page ] ) ; // line 1
2019-02-17 04:15:44 +01:00
// compute page content
switch ( page ) {
2019-02-21 13:54:25 +01:00
case HOTTTEXT_PAGE_VARIO : // Vario page
if ( RevoSettingsHandle ( ) ! = NULL ) {
RevoSettingsFusionAlgorithmGet ( & revoFusionAlgo ) ;
}
if ( HoTTBridgeSettingsHandle ( ) ! = NULL ) {
HoTTBridgeSettingsWarningGet ( & alarmWarning ) ;
HoTTBridgeSettingsLimitGet ( & alarmLimits ) ;
}
bool edit_altitudebeep = ( edit_mode & & ( current_line = = 2 ) ) ;
bool edit_maxheight = ( edit_mode & & ( current_line = = 3 ) ) ;
bool edit_minheight = ( edit_mode & & ( current_line = = 4 ) ) ;
bool edit_minheight_value = ( edit_mode & & ( current_line = = 5 ) ) ;
bool edit_maxheight_value = ( edit_mode & & ( current_line = = 6 ) ) ;
if ( edit_altitudebeep ) {
if ( alarmWarning . AltitudeBeep = = HOTTBRIDGESETTINGS_WARNING_DISABLED ) {
alarmWarning . AltitudeBeep = HOTTBRIDGESETTINGS_WARNING_ENABLED ;
} else {
alarmWarning . AltitudeBeep = HOTTBRIDGESETTINGS_WARNING_DISABLED ;
}
HoTTBridgeSettingsWarningSet ( & alarmWarning ) ;
UAVObjSave ( HoTTBridgeSettingsHandle ( ) , 0 ) ;
storedtoflash = true ;
}
if ( edit_minheight ) {
if ( alarmWarning . MinHeight = = HOTTBRIDGESETTINGS_WARNING_DISABLED ) {
alarmWarning . MinHeight = HOTTBRIDGESETTINGS_WARNING_ENABLED ;
} else {
alarmWarning . MinHeight = HOTTBRIDGESETTINGS_WARNING_DISABLED ;
}
HoTTBridgeSettingsWarningSet ( & alarmWarning ) ;
UAVObjSave ( HoTTBridgeSettingsHandle ( ) , 0 ) ;
storedtoflash = true ;
}
if ( edit_maxheight ) {
if ( alarmWarning . MaxHeight = = HOTTBRIDGESETTINGS_WARNING_DISABLED ) {
alarmWarning . MaxHeight = HOTTBRIDGESETTINGS_WARNING_ENABLED ;
} else {
alarmWarning . MaxHeight = HOTTBRIDGESETTINGS_WARNING_DISABLED ;
}
HoTTBridgeSettingsWarningSet ( & alarmWarning ) ;
UAVObjSave ( HoTTBridgeSettingsHandle ( ) , 0 ) ;
storedtoflash = true ;
}
if ( edit_minheight_value ) {
step = ( step > 2 ) ? 2 : step ;
// -500 to 500m
alarmLimits . MinHeight = get_new_value ( ( int16_t ) alarmLimits . MinHeight , value_change , step , - 500 , 500 ) ;
HoTTBridgeSettingsLimitSet ( & alarmLimits ) ;
}
if ( edit_maxheight_value ) {
step = ( step > 2 ) ? 2 : step ;
// -500 to 1500m
alarmLimits . MaxHeight = get_new_value ( ( int16_t ) alarmLimits . MaxHeight , value_change , step , - 500 , 1500 ) ;
HoTTBridgeSettingsLimitSet ( & alarmLimits ) ;
}
char * txt_fusionalgo = " " ;
2019-02-17 04:15:44 +01:00
// check current algo status
switch ( revoFusionAlgo ) {
case REVOSETTINGS_FUSIONALGORITHM_INS13INDOOR :
case REVOSETTINGS_FUSIONALGORITHM_TESTINGINSINDOORCF :
txt_fusionalgo = " * EKF INDOOR NOGPS * " ;
ekf_enabled = true ;
break ;
case REVOSETTINGS_FUSIONALGORITHM_GPSNAVIGATIONINS13 :
case REVOSETTINGS_FUSIONALGORITHM_GPSNAVIGATIONINS13CF :
txt_fusionalgo = " * EKF OUTDOOR GPS * " ;
ekf_enabled = true ;
break ;
case REVOSETTINGS_FUSIONALGORITHM_BASICCOMPLEMENTARY :
case REVOSETTINGS_FUSIONALGORITHM_COMPLEMENTARYMAG :
case REVOSETTINGS_FUSIONALGORITHM_COMPLEMENTARYMAGGPSOUTDOOR :
default :
txt_fusionalgo = " * BASIC ALGO * " ;
ekf_enabled = false ;
}
2019-02-21 13:54:25 +01:00
if ( edit_mode & & ( current_line = = 7 ) ) {
2019-02-17 04:15:44 +01:00
// check if a GPS is available
bool gps_ok = ( telestate - > SysAlarms . Alarm . GPS ! = SYSTEMALARMS_ALARM_UNINITIALISED ) & & ( telestate - > SysAlarms . Alarm . GPS ! = SYSTEMALARMS_ALARM_ERROR ) ;
if ( gps_ok ) {
if ( ekf_enabled ) {
revoFusionAlgo = REVOSETTINGS_FUSIONALGORITHM_BASICCOMPLEMENTARY ; // move to Basic (no mag needed)
} else {
revoFusionAlgo = REVOSETTINGS_FUSIONALGORITHM_GPSNAVIGATIONINS13CF ; // move to ekf
}
} else {
// without GPS
if ( ekf_enabled ) {
revoFusionAlgo = REVOSETTINGS_FUSIONALGORITHM_BASICCOMPLEMENTARY ; // move to Basic (no mag needed)
} else {
revoFusionAlgo = REVOSETTINGS_FUSIONALGORITHM_TESTINGINSINDOORCF ; // move to ekf
}
}
RevoSettingsFusionAlgorithmSet ( & revoFusionAlgo ) ;
UAVObjSave ( RevoSettingsHandle ( ) , 0 ) ;
2019-02-21 13:54:25 +01:00
storedtoflash = true ;
}
snprintf ( msg - > text [ 1 ] , HOTT_TEXT_COLUMNS , " Altitude speak [%1s] " , ( ( alarmWarning . AltitudeBeep = = HOTTBRIDGESETTINGS_WARNING_DISABLED ) ? " " : " * " ) ) ; // line 2
snprintf ( msg - > text [ 2 ] , HOTT_TEXT_COLUMNS , " MaxHeight warn [%1s] " , ( ( alarmWarning . MaxHeight = = HOTTBRIDGESETTINGS_WARNING_DISABLED ) ? " " : " * " ) ) ; // line 3
snprintf ( msg - > text [ 3 ] , HOTT_TEXT_COLUMNS , " MinHeight warn [%1s] " , ( ( alarmWarning . MinHeight = = HOTTBRIDGESETTINGS_WARNING_DISABLED ) ? " " : " * " ) ) ; // line 4
snprintf ( msg - > text [ 4 ] , HOTT_TEXT_COLUMNS , " Max height %4d " , ( int16_t ) alarmLimits . MaxHeight ) ; // line 5
snprintf ( msg - > text [ 5 ] , HOTT_TEXT_COLUMNS , " Min height %4d " , ( int16_t ) alarmLimits . MinHeight ) ; // line 6
snprintf ( msg - > text [ 6 ] , HOTT_TEXT_COLUMNS , " Use EKF algo [%1s] " , ( ( ekf_enabled ) ? " * " : " " ) ) ; // line 7
snprintf ( msg - > text [ 7 ] , HOTT_TEXT_COLUMNS , " %s " , txt_fusionalgo ) ; // line 8
if ( current_line > 1 ) {
msg - > text [ current_line - 1 ] [ 0 ] = ' > ' ;
}
if ( edit_minheight_value ) {
reverse_pixels ( ( char * ) msg - > text [ current_line - 1 ] , 16 + ( 3 - step ) , 20 - step ) ;
}
if ( edit_maxheight_value ) {
reverse_pixels ( ( char * ) msg - > text [ current_line - 1 ] , 16 + ( 3 - step ) , 20 - step ) ;
}
break ;
case HOTTTEXT_PAGE_GPS : // GPS page
if ( HoTTBridgeSettingsHandle ( ) ! = NULL ) {
HoTTBridgeSettingsWarningGet ( & alarmWarning ) ;
HoTTBridgeSettingsLimitGet ( & alarmLimits ) ;
}
bool edit_maxdistance = ( edit_mode & & ( current_line = = 2 ) ) ;
bool edit_maxspeed = ( edit_mode & & ( current_line = = 3 ) ) ;
bool edit_minspeed = ( edit_mode & & ( current_line = = 4 ) ) ;
bool edit_maxdistance_value = ( edit_mode & & ( current_line = = 5 ) ) ;
bool edit_maxspeed_value = ( edit_mode & & ( current_line = = 6 ) ) ;
bool edit_minspeed_value = ( edit_mode & & ( current_line = = 7 ) ) ;
if ( edit_maxdistance ) {
if ( alarmWarning . MaxDistance = = HOTTBRIDGESETTINGS_WARNING_DISABLED ) {
alarmWarning . MaxDistance = HOTTBRIDGESETTINGS_WARNING_ENABLED ;
} else {
alarmWarning . MaxDistance = HOTTBRIDGESETTINGS_WARNING_DISABLED ;
}
HoTTBridgeSettingsWarningSet ( & alarmWarning ) ;
UAVObjSave ( HoTTBridgeSettingsHandle ( ) , 0 ) ;
storedtoflash = true ;
}
if ( edit_minspeed ) {
if ( alarmWarning . MinSpeed = = HOTTBRIDGESETTINGS_WARNING_DISABLED ) {
alarmWarning . MinSpeed = HOTTBRIDGESETTINGS_WARNING_ENABLED ;
} else {
alarmWarning . MinSpeed = HOTTBRIDGESETTINGS_WARNING_DISABLED ;
}
HoTTBridgeSettingsWarningSet ( & alarmWarning ) ;
UAVObjSave ( HoTTBridgeSettingsHandle ( ) , 0 ) ;
storedtoflash = true ;
}
if ( edit_maxspeed ) {
if ( alarmWarning . MaxSpeed = = HOTTBRIDGESETTINGS_WARNING_DISABLED ) {
alarmWarning . MaxSpeed = HOTTBRIDGESETTINGS_WARNING_ENABLED ;
} else {
alarmWarning . MaxSpeed = HOTTBRIDGESETTINGS_WARNING_DISABLED ;
}
HoTTBridgeSettingsWarningSet ( & alarmWarning ) ;
UAVObjSave ( HoTTBridgeSettingsHandle ( ) , 0 ) ;
storedtoflash = true ;
}
if ( edit_maxdistance_value ) {
step = ( step > 3 ) ? 3 : step ;
// 10m to 9000m
alarmLimits . MaxDistance = get_new_value ( ( uint16_t ) alarmLimits . MaxDistance , value_change , step , 10 , 9000 ) ;
HoTTBridgeSettingsLimitSet ( & alarmLimits ) ;
}
if ( edit_maxspeed_value ) {
step = ( step > 2 ) ? 2 : step ;
alarmLimits . MaxSpeed = get_new_value ( ( int16_t ) alarmLimits . MaxSpeed , value_change , step , 0 , 600 ) ;
HoTTBridgeSettingsLimitSet ( & alarmLimits ) ;
}
if ( edit_minspeed_value ) {
step = ( step > 2 ) ? 2 : step ;
alarmLimits . MinSpeed = get_new_value ( ( int16_t ) alarmLimits . MinSpeed , value_change , step , 0 , 600 ) ;
HoTTBridgeSettingsLimitSet ( & alarmLimits ) ;
}
snprintf ( msg - > text [ 1 ] , HOTT_TEXT_COLUMNS , " MaxDist warn [%1s] " , ( ( alarmWarning . MaxDistance = = HOTTBRIDGESETTINGS_WARNING_DISABLED ) ? " " : " * " ) ) ; // line 2
snprintf ( msg - > text [ 2 ] , HOTT_TEXT_COLUMNS , " MaxSpeed warn [%1s] " , ( ( alarmWarning . MaxSpeed = = HOTTBRIDGESETTINGS_WARNING_DISABLED ) ? " " : " * " ) ) ; // line 3
snprintf ( msg - > text [ 3 ] , HOTT_TEXT_COLUMNS , " MinSpeed warn [%1s] " , ( ( alarmWarning . MinSpeed = = HOTTBRIDGESETTINGS_WARNING_DISABLED ) ? " " : " * " ) ) ; // line 4
snprintf ( msg - > text [ 4 ] , HOTT_TEXT_COLUMNS , " Max distance %4d " , ( uint16_t ) alarmLimits . MaxDistance ) ; // line 5
snprintf ( msg - > text [ 5 ] , HOTT_TEXT_COLUMNS , " Max speed %4d " , ( int16_t ) alarmLimits . MaxSpeed ) ; // line 6
snprintf ( msg - > text [ 6 ] , HOTT_TEXT_COLUMNS , " Min speed %4d " , ( int16_t ) alarmLimits . MinSpeed ) ; // line 7
snprintf ( msg - > text [ 7 ] , HOTT_TEXT_COLUMNS , " " ) ; // line 8
if ( current_line > 1 ) {
msg - > text [ current_line - 1 ] [ 0 ] = ' > ' ;
}
if ( edit_maxdistance_value ) {
reverse_pixels ( ( char * ) msg - > text [ current_line - 1 ] , 16 + ( 3 - step ) , 20 - step ) ;
2019-02-17 04:15:44 +01:00
}
2019-02-21 13:54:25 +01:00
if ( edit_maxspeed_value ) {
reverse_pixels ( ( char * ) msg - > text [ current_line - 1 ] , 16 + ( 3 - step ) , 20 - step ) ;
}
if ( edit_minspeed_value ) {
reverse_pixels ( ( char * ) msg - > text [ current_line - 1 ] , 16 + ( 3 - step ) , 20 - step ) ;
}
break ;
case HOTTTEXT_PAGE_GENERAL : // General Air page
case HOTTTEXT_PAGE_ELECTRIC : // Electric Air page
case HOTTTEXT_PAGE_ESC : // Esc page
if ( HoTTBridgeSettingsHandle ( ) ! = NULL ) {
HoTTBridgeSettingsWarningGet ( & alarmWarning ) ;
HoTTBridgeSettingsLimitGet ( & alarmLimits ) ;
}
bool edit_minvoltage = ( edit_mode & & ( current_line = = 2 ) ) ;
bool edit_maxcurrent = ( edit_mode & & ( current_line = = 3 ) ) ;
bool edit_maxusedcapacity = ( edit_mode & & ( current_line = = 4 ) ) ;
bool edit_minvoltage_value = ( edit_mode & & ( current_line = = 5 ) ) ;
bool edit_maxcurrent_value = ( edit_mode & & ( current_line = = 6 ) ) ;
bool edit_maxusedcapacity_value = ( edit_mode & & ( current_line = = 7 ) ) ;
2019-02-17 04:15:44 +01:00
2019-02-21 13:54:25 +01:00
if ( edit_minvoltage ) {
if ( alarmWarning . MinPowerVoltage = = HOTTBRIDGESETTINGS_WARNING_DISABLED ) {
alarmWarning . MinPowerVoltage = HOTTBRIDGESETTINGS_WARNING_ENABLED ;
} else {
alarmWarning . MinPowerVoltage = HOTTBRIDGESETTINGS_WARNING_DISABLED ;
}
HoTTBridgeSettingsWarningSet ( & alarmWarning ) ;
UAVObjSave ( HoTTBridgeSettingsHandle ( ) , 0 ) ;
storedtoflash = true ;
}
if ( edit_maxcurrent ) {
if ( alarmWarning . MaxCurrent = = HOTTBRIDGESETTINGS_WARNING_DISABLED ) {
alarmWarning . MaxCurrent = HOTTBRIDGESETTINGS_WARNING_ENABLED ;
} else {
alarmWarning . MaxCurrent = HOTTBRIDGESETTINGS_WARNING_DISABLED ;
}
HoTTBridgeSettingsWarningSet ( & alarmWarning ) ;
UAVObjSave ( HoTTBridgeSettingsHandle ( ) , 0 ) ;
storedtoflash = true ;
}
if ( edit_maxusedcapacity ) {
if ( alarmWarning . MaxUsedCapacity = = HOTTBRIDGESETTINGS_WARNING_DISABLED ) {
alarmWarning . MaxUsedCapacity = HOTTBRIDGESETTINGS_WARNING_ENABLED ;
} else {
alarmWarning . MaxUsedCapacity = HOTTBRIDGESETTINGS_WARNING_DISABLED ;
}
HoTTBridgeSettingsWarningSet ( & alarmWarning ) ;
UAVObjSave ( HoTTBridgeSettingsHandle ( ) , 0 ) ;
storedtoflash = true ;
}
2019-02-17 04:15:44 +01:00
2019-02-21 13:54:25 +01:00
if ( edit_minvoltage_value ) {
step = ( step > 2 ) ? 2 : step ;
// 3V to 50V
alarmLimits . MinPowerVoltage = ( float ) ( get_new_value ( ( uint16_t ) ( alarmLimits . MinPowerVoltage * 10 ) , value_change , step , 30 , 500 ) / 10.0f ) ;
HoTTBridgeSettingsLimitSet ( & alarmLimits ) ;
}
if ( edit_maxcurrent_value ) {
step = ( step > 2 ) ? 2 : step ;
// 1A to 300A
alarmLimits . MaxCurrent = get_new_value ( ( uint16_t ) ( alarmLimits . MaxCurrent ) , value_change , step , 1 , 300 ) ;
HoTTBridgeSettingsLimitSet ( & alarmLimits ) ;
}
if ( edit_maxusedcapacity_value ) {
step = ( step > 3 ) ? 3 : step ;
// 100mAh to 30000mAh
alarmLimits . MaxUsedCapacity = ( float ) ( get_new_value ( ( uint16_t ) alarmLimits . MaxUsedCapacity , value_change , step , 100 , 30000 ) ) ;
HoTTBridgeSettingsLimitSet ( & alarmLimits ) ;
}
2019-02-17 04:15:44 +01:00
2019-02-21 13:54:25 +01:00
snprintf ( msg - > text [ 1 ] , HOTT_TEXT_COLUMNS , " MinVoltage warn [%1s] " , ( ( alarmWarning . MinPowerVoltage = = HOTTBRIDGESETTINGS_WARNING_DISABLED ) ? " " : " * " ) ) ; // line 2
snprintf ( msg - > text [ 2 ] , HOTT_TEXT_COLUMNS , " MaxCurrent warn [%1s] " , ( ( alarmWarning . MaxCurrent = = HOTTBRIDGESETTINGS_WARNING_DISABLED ) ? " " : " * " ) ) ; // line 3
snprintf ( msg - > text [ 3 ] , HOTT_TEXT_COLUMNS , " MaxUsedmAH warn [%1s] " , ( ( alarmWarning . MaxUsedCapacity = = HOTTBRIDGESETTINGS_WARNING_DISABLED ) ? " " : " * " ) ) ; // line 4
snprintf ( msg - > text [ 4 ] , HOTT_TEXT_COLUMNS , " Min voltage %2d.%d " , ( uint16_t ) ( alarmLimits . MinPowerVoltage ) , ( uint16_t ) ( alarmLimits . MinPowerVoltage * 10 ) % 10 ) ; // line 5
snprintf ( msg - > text [ 5 ] , HOTT_TEXT_COLUMNS , " Max current %3d " , ( uint16_t ) alarmLimits . MaxCurrent ) ; // line 6
snprintf ( msg - > text [ 6 ] , HOTT_TEXT_COLUMNS , " Max used mAH %5d " , ( uint16_t ) alarmLimits . MaxUsedCapacity ) ; // line 7
snprintf ( msg - > text [ 7 ] , HOTT_TEXT_COLUMNS , " " ) ; // line 8
2019-02-17 04:15:44 +01:00
if ( current_line > 1 ) {
msg - > text [ current_line - 1 ] [ 0 ] = ' > ' ;
}
2019-02-21 13:54:25 +01:00
if ( edit_minvoltage_value ) {
if ( step > 0 ) {
step + = 1 ;
}
reverse_pixels ( ( char * ) msg - > text [ current_line - 1 ] , 15 + ( 4 - step ) , 20 - step ) ;
}
if ( edit_maxcurrent_value ) {
reverse_pixels ( ( char * ) msg - > text [ current_line - 1 ] , 16 + ( 3 - step ) , 20 - step ) ;
}
if ( edit_maxusedcapacity_value ) {
reverse_pixels ( ( char * ) msg - > text [ current_line - 1 ] , 15 + ( 4 - step ) , 20 - step ) ;
}
2019-02-17 04:15:44 +01:00
break ;
2019-02-21 13:54:25 +01:00
case HOTTTEXT_PAGE_GPSCONFIG : // GPS config page
if ( GPSSettingsHandle ( ) ! = NULL ) {
GPSSettingsGet ( & gpsSettings ) ;
}
if ( HomeLocationHandle ( ) ! = NULL ) {
UAVObjLoad ( HomeLocationHandle ( ) , 0 ) ; // load from flash
HomeLocationSetGet ( & homeSet ) ;
}
bool edit_savehome = ( edit_mode & & ( current_line = = 2 ) ) ;
bool edit_minsat_value = ( edit_mode & & ( current_line = = 3 ) ) ;
bool edit_maxpdop_value = ( edit_mode & & ( current_line = = 4 ) ) ;
bool edit_ubxrate_value = ( edit_mode & & ( current_line = = 5 ) ) ;
if ( edit_minsat_value ) {
gpsSettings . MinSatellites = get_new_value ( gpsSettings . MinSatellites , value_change , 0 , 4 , 9 ) ;
GPSSettingsSet ( & gpsSettings ) ;
}
if ( edit_maxpdop_value ) {
step = ( step > 2 ) ? 2 : step ;
// 1.0 to 10.0
gpsSettings . MaxPDOP = ( float ) ( get_new_value ( ( uint16_t ) ( gpsSettings . MaxPDOP * 10 ) , value_change , step , 10 , 100 ) / 10.0f ) ;
GPSSettingsSet ( & gpsSettings ) ;
}
if ( edit_ubxrate_value ) {
gpsSettings . UbxRate = get_new_value ( gpsSettings . UbxRate , value_change , 0 , 1 , 15 ) ;
GPSSettingsSet ( & gpsSettings ) ;
}
char * home_set_perm = ( homeSet = = HOMELOCATION_SET_FALSE ) ? " NEVER " : " ISSET " ;
snprintf ( msg - > text [ 1 ] , HOTT_TEXT_COLUMNS , " Home status %s " , home_set_perm ) ; // line 2
snprintf ( msg - > text [ 2 ] , HOTT_TEXT_COLUMNS , " Min satellites %d " , gpsSettings . MinSatellites ) ; // line 3
snprintf ( msg - > text [ 3 ] , HOTT_TEXT_COLUMNS , " Max PDOP %2d.%d " , ( uint16_t ) ( gpsSettings . MaxPDOP ) , ( uint16_t ) ( gpsSettings . MaxPDOP * 10 ) % 10 ) ; // line 4
snprintf ( msg - > text [ 4 ] , HOTT_TEXT_COLUMNS , " UBX Rate %2d " , gpsSettings . UbxRate ) ; // line 5
2019-02-17 04:15:44 +01:00
snprintf ( msg - > text [ 5 ] , HOTT_TEXT_COLUMNS , " " ) ; // line 6
snprintf ( msg - > text [ 6 ] , HOTT_TEXT_COLUMNS , " " ) ; // line 7
snprintf ( msg - > text [ 7 ] , HOTT_TEXT_COLUMNS , " " ) ; // line 8
2019-02-21 13:54:25 +01:00
if ( current_line > 1 ) {
msg - > text [ current_line - 1 ] [ 0 ] = ' > ' ;
}
if ( edit_savehome ) {
if ( homeSet = = HOMELOCATION_SET_TRUE ) {
homeSet = HOMELOCATION_SET_FALSE ;
HomeLocationSetSet ( & homeSet ) ;
UAVObjSave ( HomeLocationHandle ( ) , 0 ) ;
storedtoflash = true ;
}
}
if ( edit_minsat_value ) {
reverse_pixels ( ( char * ) msg - > text [ current_line - 1 ] , 19 , 20 ) ;
}
if ( edit_maxpdop_value ) {
if ( step > 0 ) {
step + = 1 ;
}
reverse_pixels ( ( char * ) msg - > text [ current_line - 1 ] , 15 + ( 4 - step ) , 20 - step ) ;
}
if ( edit_ubxrate_value ) {
reverse_pixels ( ( char * ) msg - > text [ current_line - 1 ] , 18 , 20 ) ;
}
2019-02-17 04:15:44 +01:00
break ;
default :
2019-02-21 13:54:25 +01:00
case HOTTTEXT_PAGE_MAIN : // Main page where HoTT modules can be started
if ( HoTTBridgeSettingsHandle ( ) ! = NULL ) {
HoTTBridgeSettingsSensorGet ( & sensor ) ;
}
if ( edit_mode ) {
2019-02-17 04:15:44 +01:00
switch ( current_line ) {
case 2 :
if ( sensor . VARIO = = HOTTBRIDGESETTINGS_SENSOR_DISABLED ) {
sensor . VARIO = HOTTBRIDGESETTINGS_SENSOR_ENABLED ;
} else {
sensor . VARIO = HOTTBRIDGESETTINGS_SENSOR_DISABLED ;
}
break ;
case 3 :
if ( sensor . GPS = = HOTTBRIDGESETTINGS_SENSOR_DISABLED ) {
sensor . GPS = HOTTBRIDGESETTINGS_SENSOR_ENABLED ;
} else {
sensor . GPS = HOTTBRIDGESETTINGS_SENSOR_DISABLED ;
}
break ;
case 4 :
if ( sensor . EAM = = HOTTBRIDGESETTINGS_SENSOR_DISABLED ) {
sensor . EAM = HOTTBRIDGESETTINGS_SENSOR_ENABLED ;
// no need to emulate General module
sensor . GAM = HOTTBRIDGESETTINGS_SENSOR_DISABLED ;
} else {
sensor . EAM = HOTTBRIDGESETTINGS_SENSOR_DISABLED ;
}
break ;
case 5 :
if ( sensor . GAM = = HOTTBRIDGESETTINGS_SENSOR_DISABLED ) {
sensor . GAM = HOTTBRIDGESETTINGS_SENSOR_ENABLED ;
// no need to emulate Electric module
sensor . EAM = HOTTBRIDGESETTINGS_SENSOR_DISABLED ;
} else {
sensor . GAM = HOTTBRIDGESETTINGS_SENSOR_DISABLED ;
}
break ;
case 6 :
if ( sensor . ESC = = HOTTBRIDGESETTINGS_SENSOR_DISABLED ) {
sensor . ESC = HOTTBRIDGESETTINGS_SENSOR_ENABLED ;
} else {
sensor . ESC = HOTTBRIDGESETTINGS_SENSOR_DISABLED ;
}
}
HoTTBridgeSettingsSensorSet ( & sensor ) ;
UAVObjSave ( HoTTBridgeSettingsHandle ( ) , 0 ) ;
2019-02-21 13:54:25 +01:00
storedtoflash = true ;
2019-02-17 04:15:44 +01:00
}
// create Main page content
2019-02-21 13:54:25 +01:00
snprintf ( msg - > text [ 1 ] , HOTT_TEXT_COLUMNS , " VARIO module [%1s] " , ( ( sensor . VARIO = = HOTTBRIDGESETTINGS_SENSOR_DISABLED ) ? " " : " * " ) ) ; // line 2
snprintf ( msg - > text [ 2 ] , HOTT_TEXT_COLUMNS , " GPS module [%1s] " , ( ( sensor . GPS = = HOTTBRIDGESETTINGS_SENSOR_DISABLED ) ? " " : " * " ) ) ; // line 3
snprintf ( msg - > text [ 3 ] , HOTT_TEXT_COLUMNS , " ELECTRIC module [%1s] " , ( ( sensor . EAM = = HOTTBRIDGESETTINGS_SENSOR_DISABLED ) ? " " : " * " ) ) ; // line 4
snprintf ( msg - > text [ 4 ] , HOTT_TEXT_COLUMNS , " GENERAL module [%1s] " , ( ( sensor . GAM = = HOTTBRIDGESETTINGS_SENSOR_DISABLED ) ? " " : " * " ) ) ; // line 5
snprintf ( msg - > text [ 5 ] , HOTT_TEXT_COLUMNS , " ESC module [%1s] " , ( ( sensor . ESC = = HOTTBRIDGESETTINGS_SENSOR_DISABLED ) ? " " : " * " ) ) ; // line 6
2019-02-17 04:15:44 +01:00
snprintf ( msg - > text [ 6 ] , HOTT_TEXT_COLUMNS , " Select module " ) ;
snprintf ( msg - > text [ 7 ] , HOTT_TEXT_COLUMNS , " to be emulated " ) ;
if ( current_line > 1 ) {
msg - > text [ current_line - 1 ] [ 0 ] = ' > ' ;
}
// break;
}
msg - > stop = HOTT_STOP ;
msg - > checksum = calc_checksum ( ( uint8_t * ) msg , sizeof ( * msg ) ) ;
2019-02-21 13:54:25 +01:00
return storedtoflash ;
}
/**
* get next / previous page to display
*/
uint8_t get_page ( uint8_t page , bool next )
{
HoTTBridgeSettingsSensorData sensor ;
if ( HoTTBridgeSettingsHandle ( ) ! = NULL ) {
HoTTBridgeSettingsSensorGet ( & sensor ) ;
}
if ( next ) {
switch ( page ) {
case HOTTTEXT_PAGE_MAIN :
if ( sensor . GPS = = HOTTBRIDGESETTINGS_SENSOR_ENABLED ) {
page = HOTTTEXT_PAGE_GPSCONFIG ;
break ;
}
case HOTTTEXT_PAGE_GPSCONFIG :
if ( sensor . VARIO = = HOTTBRIDGESETTINGS_SENSOR_ENABLED ) {
page = HOTTTEXT_PAGE_VARIO ;
break ;
}
case HOTTTEXT_PAGE_VARIO :
if ( sensor . GPS = = HOTTBRIDGESETTINGS_SENSOR_ENABLED ) {
page = HOTTTEXT_PAGE_GPS ;
break ;
}
case HOTTTEXT_PAGE_GPS :
if ( sensor . GAM = = HOTTBRIDGESETTINGS_SENSOR_ENABLED ) {
page = HOTTTEXT_PAGE_GENERAL ;
break ;
}
case HOTTTEXT_PAGE_GENERAL :
if ( sensor . EAM = = HOTTBRIDGESETTINGS_SENSOR_ENABLED ) {
page = HOTTTEXT_PAGE_ELECTRIC ;
break ;
}
case HOTTTEXT_PAGE_ELECTRIC :
if ( sensor . ESC = = HOTTBRIDGESETTINGS_SENSOR_ENABLED ) {
page = HOTTTEXT_PAGE_ESC ;
break ;
}
case HOTTTEXT_PAGE_ESC :
break ;
default :
page = HOTTTEXT_PAGE_MAIN ;
}
} else {
switch ( page ) {
case HOTTTEXT_PAGE_ESC :
if ( sensor . EAM = = HOTTBRIDGESETTINGS_SENSOR_ENABLED ) {
page = HOTTTEXT_PAGE_ELECTRIC ;
break ;
}
case HOTTTEXT_PAGE_ELECTRIC :
if ( sensor . GAM = = HOTTBRIDGESETTINGS_SENSOR_ENABLED ) {
page = HOTTTEXT_PAGE_GENERAL ;
break ;
}
case HOTTTEXT_PAGE_GENERAL :
if ( sensor . GPS = = HOTTBRIDGESETTINGS_SENSOR_ENABLED ) {
page = HOTTTEXT_PAGE_GPS ;
break ;
}
case HOTTTEXT_PAGE_GPS :
if ( sensor . VARIO = = HOTTBRIDGESETTINGS_SENSOR_ENABLED ) {
page = HOTTTEXT_PAGE_VARIO ;
break ;
}
case HOTTTEXT_PAGE_VARIO :
if ( sensor . GPS = = HOTTBRIDGESETTINGS_SENSOR_ENABLED ) {
page = HOTTTEXT_PAGE_GPSCONFIG ;
break ;
}
case HOTTTEXT_PAGE_GPSCONFIG :
page = HOTTTEXT_PAGE_MAIN ;
break ;
case HOTTTEXT_PAGE_MAIN :
default :
page = HOTTTEXT_PAGE_MAIN ;
}
}
return page ;
}
/**
* get new value for edited field
*/
int16_t get_new_value ( int16_t current_value , int8_t value_change , uint8_t step , int16_t min , int16_t max )
{
uint16_t increment [ ] = { 1 , 10 , 100 , 1000 , 10000 } ;
int16_t new_value = 0 ;
new_value = current_value + ( value_change * increment [ step ] ) ;
if ( new_value < min ) {
new_value = min ;
}
if ( new_value > max ) {
new_value = max ;
}
return new_value ;
}
/**
* store settings to onboard flash
*/
void store_settings ( uint8_t page )
{
switch ( page ) {
case HOTTTEXT_PAGE_MAIN :
case HOTTTEXT_PAGE_VARIO :
case HOTTTEXT_PAGE_GPS :
case HOTTTEXT_PAGE_GENERAL :
case HOTTTEXT_PAGE_ELECTRIC :
case HOTTTEXT_PAGE_ESC :
UAVObjSave ( HoTTBridgeSettingsHandle ( ) , 0 ) ;
break ;
case HOTTTEXT_PAGE_GPSCONFIG :
UAVObjSave ( GPSSettingsHandle ( ) , 0 ) ;
break ;
}
2017-03-22 15:52:59 +01:00
}
2017-03-24 07:01:47 +01:00
/**
* update telemetry data
* this is called on every telemetry request
* calling interval is 200 ms depending on TX
* 200 ms telemetry request is used as time base for timed calculations ( 5 Hz interval )
*/
void update_telemetrydata ( )
2017-03-22 15:52:59 +01:00
{
2017-03-24 07:01:47 +01:00
// update all available data
if ( HoTTBridgeSettingsHandle ( ) ! = NULL ) {
HoTTBridgeSettingsGet ( & telestate - > Settings ) ;
}
if ( AttitudeStateHandle ( ) ! = NULL ) {
AttitudeStateGet ( & telestate - > Attitude ) ;
}
2019-03-24 22:51:15 +01:00
if ( AccelStateHandle ( ) ! = NULL ) {
AccelStateGet ( & telestate - > Accel ) ;
}
2017-03-24 07:01:47 +01:00
if ( BaroSensorHandle ( ) ! = NULL ) {
BaroSensorGet ( & telestate - > Baro ) ;
}
if ( FlightBatteryStateHandle ( ) ! = NULL ) {
FlightBatteryStateGet ( & telestate - > Battery ) ;
}
if ( FlightStatusHandle ( ) ! = NULL ) {
FlightStatusGet ( & telestate - > FlightStatus ) ;
}
if ( GPSPositionSensorHandle ( ) ! = NULL ) {
GPSPositionSensorGet ( & telestate - > GPS ) ;
}
2019-02-14 23:39:42 +01:00
if ( AirspeedStateHandle ( ) ! = NULL ) {
AirspeedStateGet ( & telestate - > Airspeed ) ;
}
2017-03-24 07:01:47 +01:00
if ( GPSTimeHandle ( ) ! = NULL ) {
GPSTimeGet ( & telestate - > GPStime ) ;
}
if ( GyroSensorHandle ( ) ! = NULL ) {
GyroSensorGet ( & telestate - > Gyro ) ;
}
if ( HomeLocationHandle ( ) ! = NULL ) {
HomeLocationGet ( & telestate - > Home ) ;
}
if ( PositionStateHandle ( ) ! = NULL ) {
PositionStateGet ( & telestate - > Position ) ;
}
if ( SystemAlarmsHandle ( ) ! = NULL ) {
SystemAlarmsGet ( & telestate - > SysAlarms ) ;
}
if ( VelocityStateHandle ( ) ! = NULL ) {
VelocityStateGet ( & telestate - > Velocity ) ;
}
// send actual climbrate value to ring buffer as mm per 0.2s values
uint8_t n = telestate - > climbrate_pointer ;
2019-03-24 22:51:15 +01:00
// DEBUG_PRINTF(3, "Current pointer: %d\r\n", n);
2017-03-24 07:01:47 +01:00
telestate - > climbratebuffer [ telestate - > climbrate_pointer + + ] = - telestate - > Velocity . Down * 200 ;
telestate - > climbrate_pointer % = climbratesize ;
2019-03-24 22:51:15 +01:00
// DEBUG_PRINTF(3, "Next pointer: %d\r\n", telestate->climbrate_pointer);
bool display_G = ( n > 25 ) ;
2017-03-24 07:01:47 +01:00
// calculate avarage climbrates in meters per 1, 3 and 10 second(s) based on 200ms interval
telestate - > climbrate1s = 0 ;
telestate - > climbrate3s = 0 ;
telestate - > climbrate10s = 0 ;
for ( uint8_t i = 0 ; i < climbratesize ; i + + ) {
2019-03-24 22:51:15 +01:00
// DEBUG_PRINTF(3, "%d ", n);
2017-03-24 07:01:47 +01:00
telestate - > climbrate1s + = ( i < 5 ) ? telestate - > climbratebuffer [ n ] : 0 ;
telestate - > climbrate3s + = ( i < 15 ) ? telestate - > climbratebuffer [ n ] : 0 ;
telestate - > climbrate10s + = ( i < 50 ) ? telestate - > climbratebuffer [ n ] : 0 ;
n + = climbratesize - 1 ;
n % = climbratesize ;
}
telestate - > climbrate1s = telestate - > climbrate1s / 1000 ;
telestate - > climbrate3s = telestate - > climbrate3s / 1000 ;
telestate - > climbrate10s = telestate - > climbrate10s / 1000 ;
// set altitude offset and clear min/max values when arming
if ( ( telestate - > FlightStatus . Armed = = FLIGHTSTATUS_ARMED_ARMING ) | | ( ( telestate - > last_armed ! = FLIGHTSTATUS_ARMED_ARMED ) & & ( telestate - > FlightStatus . Armed = = FLIGHTSTATUS_ARMED_ARMED ) ) ) {
telestate - > min_altitude = 0 ;
telestate - > max_altitude = 0 ;
2019-02-26 20:36:53 +01:00
telestate - > max_distance = 0 ;
2017-03-22 15:52:59 +01:00
}
2019-02-26 20:36:53 +01:00
telestate - > last_armed = telestate - > FlightStatus . Armed ;
2017-03-22 15:52:59 +01:00
2017-03-24 07:01:47 +01:00
// calculate altitude relative to start position
2019-02-26 20:36:53 +01:00
telestate - > altitude = - telestate - > Position . Down ;
// gps home position and course
telestate - > homedistance = sqrtf ( telestate - > Position . North * telestate - > Position . North + telestate - > Position . East * telestate - > Position . East ) ;
telestate - > homecourse = acosf ( - telestate - > Position . North / telestate - > homedistance ) / 3.14159265f * 180 ;
if ( telestate - > Position . East > 0 ) {
telestate - > homecourse = 360 - telestate - > homecourse ;
}
// calculate current 3D speed
float speed_3d = sqrtf ( ( telestate - > Velocity . North * telestate - > Velocity . North ) + ( telestate - > Velocity . East * telestate - > Velocity . East ) + ( telestate - > Velocity . Down * telestate - > Velocity . Down ) ) * MS_TO_KMH ;
2017-03-24 07:01:47 +01:00
2019-03-24 22:51:15 +01:00
// Normal Acceleration (G unit)
float nz_alpha = 0.7f ;
telestate - > current_G = ( ( 1 - nz_alpha ) * ( - telestate - > Accel . z / 9.81f ) ) + ( telestate - > current_G * nz_alpha ) ;
2019-02-16 12:53:36 +01:00
// check and set min/max values when armed
// and without receiver input for standalone board used as sensor
if ( ( telestate - > FlightStatus . Armed = = FLIGHTSTATUS_ARMED_ARMED ) | | ( ( telestate - > SysAlarms . Alarm . Attitude = = SYSTEMALARMS_ALARM_OK ) & & ( telestate - > SysAlarms . Alarm . Receiver ! = SYSTEMALARMS_ALARM_OK ) ) ) {
2017-03-24 07:01:47 +01:00
if ( telestate - > min_altitude > telestate - > altitude ) {
telestate - > min_altitude = telestate - > altitude ;
}
if ( telestate - > max_altitude < telestate - > altitude ) {
telestate - > max_altitude = telestate - > altitude ;
2017-03-22 15:52:59 +01:00
}
2019-02-26 20:36:53 +01:00
if ( telestate - > max_distance < telestate - > homedistance ) {
telestate - > max_distance = telestate - > homedistance ;
}
if ( telestate - > max_speed < speed_3d ) {
telestate - > max_speed = speed_3d ;
}
2019-03-24 22:51:15 +01:00
if ( telestate - > max_G < telestate - > current_G ) {
telestate - > max_G = telestate - > current_G ;
}
if ( telestate - > min_G > telestate - > current_G ) {
telestate - > min_G = telestate - > current_G ;
}
2017-03-24 07:01:47 +01:00
}
// statusline
const char * txt_unknown = " unknown " ;
const char * txt_manual = " Manual " ;
const char * txt_stabilized1 = " Stabilized1 " ;
const char * txt_stabilized2 = " Stabilized2 " ;
const char * txt_stabilized3 = " Stabilized3 " ;
const char * txt_stabilized4 = " Stabilized4 " ;
const char * txt_stabilized5 = " Stabilized5 " ;
const char * txt_stabilized6 = " Stabilized6 " ;
const char * txt_positionhold = " PositionHold " ;
const char * txt_courselock = " CourseLock " ;
const char * txt_velocityroam = " VelocityRoam " ;
const char * txt_homeleash = " HomeLeash " ;
const char * txt_absoluteposition = " AbsolutePosition " ;
const char * txt_returntobase = " ReturnToBase " ;
const char * txt_land = " Land " ;
const char * txt_pathplanner = " PathPlanner " ;
const char * txt_poi = " PointOfInterest " ;
const char * txt_autocruise = " AutoCruise " ;
const char * txt_autotakeoff = " AutoTakeOff " ;
const char * txt_autotune = " Autotune " ;
const char * txt_disarmed = " Disarmed " ;
const char * txt_arming = " Arming " ;
const char * txt_armed = " Armed " ;
const char * txt_flightmode ;
switch ( telestate - > FlightStatus . FlightMode ) {
case FLIGHTSTATUS_FLIGHTMODE_MANUAL :
txt_flightmode = txt_manual ;
break ;
case FLIGHTSTATUS_FLIGHTMODE_STABILIZED1 :
txt_flightmode = txt_stabilized1 ;
break ;
case FLIGHTSTATUS_FLIGHTMODE_STABILIZED2 :
txt_flightmode = txt_stabilized2 ;
break ;
case FLIGHTSTATUS_FLIGHTMODE_STABILIZED3 :
txt_flightmode = txt_stabilized3 ;
break ;
case FLIGHTSTATUS_FLIGHTMODE_STABILIZED4 :
txt_flightmode = txt_stabilized4 ;
break ;
case FLIGHTSTATUS_FLIGHTMODE_STABILIZED5 :
txt_flightmode = txt_stabilized5 ;
break ;
case FLIGHTSTATUS_FLIGHTMODE_STABILIZED6 :
txt_flightmode = txt_stabilized6 ;
break ;
case FLIGHTSTATUS_FLIGHTMODE_POSITIONHOLD :
txt_flightmode = txt_positionhold ;
break ;
case FLIGHTSTATUS_FLIGHTMODE_COURSELOCK :
txt_flightmode = txt_courselock ;
break ;
case FLIGHTSTATUS_FLIGHTMODE_VELOCITYROAM :
txt_flightmode = txt_velocityroam ;
break ;
case FLIGHTSTATUS_FLIGHTMODE_HOMELEASH :
txt_flightmode = txt_homeleash ;
break ;
case FLIGHTSTATUS_FLIGHTMODE_ABSOLUTEPOSITION :
txt_flightmode = txt_absoluteposition ;
break ;
case FLIGHTSTATUS_FLIGHTMODE_RETURNTOBASE :
txt_flightmode = txt_returntobase ;
break ;
case FLIGHTSTATUS_FLIGHTMODE_LAND :
txt_flightmode = txt_land ;
break ;
case FLIGHTSTATUS_FLIGHTMODE_PATHPLANNER :
txt_flightmode = txt_pathplanner ;
break ;
case FLIGHTSTATUS_FLIGHTMODE_POI :
txt_flightmode = txt_poi ;
break ;
case FLIGHTSTATUS_FLIGHTMODE_AUTOCRUISE :
txt_flightmode = txt_autocruise ;
break ;
case FLIGHTSTATUS_FLIGHTMODE_AUTOTAKEOFF :
txt_flightmode = txt_autotakeoff ;
break ;
case FLIGHTSTATUS_FLIGHTMODE_AUTOTUNE :
txt_flightmode = txt_autotune ;
break ;
default :
txt_flightmode = txt_unknown ;
}
const char * txt_armstate ;
switch ( telestate - > FlightStatus . Armed ) {
case FLIGHTSTATUS_ARMED_DISARMED :
txt_armstate = txt_disarmed ;
break ;
case FLIGHTSTATUS_ARMED_ARMING :
txt_armstate = txt_arming ;
break ;
case FLIGHTSTATUS_ARMED_ARMED :
txt_armstate = txt_armed ;
break ;
default :
txt_armstate = txt_unknown ;
2017-03-22 15:52:59 +01:00
}
2017-03-24 07:01:47 +01:00
snprintf ( telestate - > statusline , sizeof ( telestate - > statusline ) , " %12s,%8s " , txt_flightmode , txt_armstate ) ;
2019-02-26 20:36:53 +01:00
snprintf ( telestate - > statusline , sizeof ( telestate - > statusline ) , " Max %3dkmh Dst %4dm " , ( uint16_t ) telestate - > max_speed , ( uint16_t ) telestate - > max_distance ) ;
// "Max 200kmh"
// "Dst 1000m "
2019-03-24 22:51:15 +01:00
if ( display_G ) {
snprintf ( telestate - > statusline , sizeof ( telestate - > statusline ) , " MaxG %2d.%d MinG %2d.%d " , ( int8_t ) ( telestate - > max_G ) , ( int8_t ) ( telestate - > max_G * 10 ) % 10 , ( int8_t ) ( telestate - > min_G ) , ( int8_t ) abs ( telestate - > min_G * 10 ) % 10 ) ;
}
2017-03-22 15:52:59 +01:00
}
2017-03-24 07:01:47 +01:00
/**
* generate warning beeps or spoken announcements
*/
uint8_t generate_warning ( )
2017-03-22 15:52:59 +01:00
{
2019-02-16 12:27:26 +01:00
bool gps_ok = ( telestate - > SysAlarms . Alarm . GPS = = SYSTEMALARMS_ALARM_OK ) ;
2017-03-24 07:01:47 +01:00
// set warning tone with hardcoded priority
if ( ( telestate - > Settings . Warning . MinSpeed = = HOTTBRIDGESETTINGS_WARNING_ENABLED ) & &
2019-02-16 12:27:26 +01:00
( telestate - > Settings . Limit . MinSpeed > telestate - > GPS . Groundspeed * MS_TO_KMH ) & & gps_ok ) {
return HOTT_TONE_A ; // minimum speed
2017-03-24 07:01:47 +01:00
}
if ( ( telestate - > Settings . Warning . NegDifference2 = = HOTTBRIDGESETTINGS_WARNING_ENABLED ) & &
( telestate - > Settings . Limit . NegDifference2 > telestate - > climbrate3s ) ) {
return HOTT_TONE_B ; // sink rate 3s
}
if ( ( telestate - > Settings . Warning . NegDifference1 = = HOTTBRIDGESETTINGS_WARNING_ENABLED ) & &
( telestate - > Settings . Limit . NegDifference1 > telestate - > climbrate1s ) ) {
return HOTT_TONE_C ; // sink rate 1s
}
if ( ( telestate - > Settings . Warning . MaxDistance = = HOTTBRIDGESETTINGS_WARNING_ENABLED ) & &
2019-02-16 12:27:26 +01:00
( telestate - > Settings . Limit . MaxDistance < telestate - > homedistance ) & & gps_ok ) {
2017-03-24 07:01:47 +01:00
return HOTT_TONE_D ; // maximum distance
}
if ( ( telestate - > Settings . Warning . MinSensor1Temp = = HOTTBRIDGESETTINGS_WARNING_ENABLED ) & &
( telestate - > Settings . Limit . MinSensor1Temp > telestate - > Gyro . temperature ) ) {
return HOTT_TONE_F ; // minimum temperature sensor 1
}
if ( ( telestate - > Settings . Warning . MinSensor2Temp = = HOTTBRIDGESETTINGS_WARNING_ENABLED ) & &
( telestate - > Settings . Limit . MinSensor2Temp > telestate - > Baro . Temperature ) ) {
return HOTT_TONE_G ; // minimum temperature sensor 2
}
if ( ( telestate - > Settings . Warning . MaxSensor1Temp = = HOTTBRIDGESETTINGS_WARNING_ENABLED ) & &
( telestate - > Settings . Limit . MaxSensor1Temp < telestate - > Gyro . temperature ) ) {
return HOTT_TONE_H ; // maximum temperature sensor 1
}
if ( ( telestate - > Settings . Warning . MaxSensor2Temp = = HOTTBRIDGESETTINGS_WARNING_ENABLED ) & &
( telestate - > Settings . Limit . MaxSensor2Temp < telestate - > Baro . Temperature ) ) {
return HOTT_TONE_I ; // maximum temperature sensor 2
}
if ( ( telestate - > Settings . Warning . MaxSpeed = = HOTTBRIDGESETTINGS_WARNING_ENABLED ) & &
2019-02-16 12:27:26 +01:00
( telestate - > Settings . Limit . MaxSpeed < telestate - > GPS . Groundspeed * MS_TO_KMH ) & & gps_ok ) {
2017-03-24 07:01:47 +01:00
return HOTT_TONE_L ; // maximum speed
}
if ( ( telestate - > Settings . Warning . PosDifference2 = = HOTTBRIDGESETTINGS_WARNING_ENABLED ) & &
( telestate - > Settings . Limit . PosDifference2 > telestate - > climbrate3s ) ) {
return HOTT_TONE_M ; // climb rate 3s
}
if ( ( telestate - > Settings . Warning . PosDifference1 = = HOTTBRIDGESETTINGS_WARNING_ENABLED ) & &
( telestate - > Settings . Limit . PosDifference1 > telestate - > climbrate1s ) ) {
return HOTT_TONE_N ; // climb rate 1s
}
if ( ( telestate - > Settings . Warning . MinHeight = = HOTTBRIDGESETTINGS_WARNING_ENABLED ) & &
( telestate - > Settings . Limit . MinHeight > telestate - > altitude ) ) {
return HOTT_TONE_O ; // minimum height
}
if ( ( telestate - > Settings . Warning . MinPowerVoltage = = HOTTBRIDGESETTINGS_WARNING_ENABLED ) & &
( telestate - > Settings . Limit . MinPowerVoltage > telestate - > Battery . Voltage ) ) {
return HOTT_TONE_P ; // minimum input voltage
}
if ( ( telestate - > Settings . Warning . MaxUsedCapacity = = HOTTBRIDGESETTINGS_WARNING_ENABLED ) & &
( telestate - > Settings . Limit . MaxUsedCapacity < telestate - > Battery . ConsumedEnergy ) ) {
return HOTT_TONE_V ; // capacity
}
if ( ( telestate - > Settings . Warning . MaxCurrent = = HOTTBRIDGESETTINGS_WARNING_ENABLED ) & &
( telestate - > Settings . Limit . MaxCurrent < telestate - > Battery . Current ) ) {
return HOTT_TONE_W ; // maximum current
}
if ( ( telestate - > Settings . Warning . MaxPowerVoltage = = HOTTBRIDGESETTINGS_WARNING_ENABLED ) & &
( telestate - > Settings . Limit . MaxPowerVoltage < telestate - > Battery . Voltage ) ) {
return HOTT_TONE_X ; // maximum input voltage
}
if ( ( telestate - > Settings . Warning . MaxHeight = = HOTTBRIDGESETTINGS_WARNING_ENABLED ) & &
( telestate - > Settings . Limit . MaxHeight < telestate - > altitude ) ) {
return HOTT_TONE_Z ; // maximum height
}
// altitude beeps when crossing altitude limits at 20,40,60,80,100,200,400,600,800 and 1000 meters
if ( telestate - > Settings . Warning . AltitudeBeep = = HOTTBRIDGESETTINGS_WARNING_ENABLED ) {
// update altitude when checked for beeps
float last = telestate - > altitude_last ;
float actual = telestate - > altitude ;
telestate - > altitude_last = telestate - > altitude ;
if ( ( ( last < 20 ) & & ( actual > = 20 ) ) | | ( ( last > 20 ) & & ( actual < = 20 ) ) ) {
return HOTT_TONE_20M ;
}
if ( ( ( last < 40 ) & & ( actual > = 40 ) ) | | ( ( last > 40 ) & & ( actual < = 40 ) ) ) {
return HOTT_TONE_40M ;
}
if ( ( ( last < 60 ) & & ( actual > = 60 ) ) | | ( ( last > 60 ) & & ( actual < = 60 ) ) ) {
return HOTT_TONE_60M ;
}
if ( ( ( last < 80 ) & & ( actual > = 80 ) ) | | ( ( last > 80 ) & & ( actual < = 80 ) ) ) {
return HOTT_TONE_80M ;
}
if ( ( ( last < 100 ) & & ( actual > = 100 ) ) | | ( ( last > 100 ) & & ( actual < = 100 ) ) ) {
return HOTT_TONE_100M ;
}
if ( ( ( last < 200 ) & & ( actual > = 200 ) ) | | ( ( last > 200 ) & & ( actual < = 200 ) ) ) {
return HOTT_TONE_200M ;
}
if ( ( ( last < 400 ) & & ( actual > = 400 ) ) | | ( ( last > 400 ) & & ( actual < = 400 ) ) ) {
return HOTT_TONE_400M ;
}
if ( ( ( last < 600 ) & & ( actual > = 600 ) ) | | ( ( last > 600 ) & & ( actual < = 600 ) ) ) {
return HOTT_TONE_600M ;
}
if ( ( ( last < 800 ) & & ( actual > = 800 ) ) | | ( ( last > 800 ) & & ( actual < = 800 ) ) ) {
return HOTT_TONE_800M ;
}
if ( ( ( last < 1000 ) & & ( actual > = 1000 ) ) | | ( ( last > 1000 ) & & ( actual < = 1000 ) ) ) {
return HOTT_TONE_1000M ;
}
}
// there is no warning
return 0 ;
2017-03-22 15:52:59 +01:00
}
2017-03-24 07:01:47 +01:00
2019-02-21 13:54:25 +01:00
/**
* reverse pixels
*/
char * reverse_pixels ( char * line , uint8_t from_char , uint8_t to_char )
{
for ( int i = from_char ; i < to_char ; i + + ) {
if ( line [ i ] = = 0 ) {
line [ i ] = ( uint8_t ) ( 0x80 + 0x20 ) ;
} else {
line [ i ] = ( 0x80 + line [ i ] ) ;
}
}
return line ;
}
2017-03-24 07:01:47 +01:00
/**
* calculate checksum of data buffer
*/
uint8_t calc_checksum ( uint8_t * data , uint16_t size )
2017-03-22 15:52:59 +01:00
{
2017-03-24 07:01:47 +01:00
uint16_t sum = 0 ;
for ( int i = 0 ; i < size ; i + + ) {
sum + = data [ i ] ;
}
return sum ;
2017-03-22 15:52:59 +01:00
}
/**
2017-03-24 07:01:47 +01:00
* scale float value with scale and offset to unsigned byte
2017-03-22 15:52:59 +01:00
*/
2017-03-24 07:01:47 +01:00
uint8_t scale_float2uint8 ( float value , float scale , float offset )
2017-03-22 15:52:59 +01:00
{
2017-03-24 07:01:47 +01:00
uint16_t temp = ( uint16_t ) roundf ( value * scale + offset ) ;
uint8_t result ;
result = ( uint8_t ) temp & 0xff ;
return result ;
2017-03-22 15:52:59 +01:00
}
/**
2017-03-24 07:01:47 +01:00
* scale float value with scale and offset to signed byte ( int8_t )
2017-03-22 15:52:59 +01:00
*/
2017-03-24 07:01:47 +01:00
int8_t scale_float2int8 ( float value , float scale , float offset )
2017-03-22 15:52:59 +01:00
{
2017-03-24 07:01:47 +01:00
int8_t result = ( int8_t ) roundf ( value * scale + offset ) ;
2017-03-22 15:52:59 +01:00
2017-03-24 07:01:47 +01:00
return result ;
2017-03-22 15:52:59 +01:00
}
/**
2017-03-24 07:01:47 +01:00
* scale float value with scale and offset to word
2017-03-22 15:52:59 +01:00
*/
2017-03-24 07:01:47 +01:00
uword_t scale_float2uword ( float value , float scale , float offset )
2017-03-22 15:52:59 +01:00
{
2017-03-24 07:01:47 +01:00
uint16_t temp = ( uint16_t ) roundf ( value * scale + offset ) ;
uword_t result ;
2017-03-22 15:52:59 +01:00
2017-03-24 07:01:47 +01:00
result . l = ( uint8_t ) temp & 0xff ;
result . h = ( uint8_t ) ( temp > > 8 ) & 0xff ;
return result ;
2017-03-22 15:52:59 +01:00
}
/**
2017-03-24 07:01:47 +01:00
* convert dword gps value into HoTT gps format and write result to given pointers
2017-03-22 15:52:59 +01:00
*/
2017-03-24 07:01:47 +01:00
void convert_long2gps ( int32_t value , uint8_t * dir , uword_t * min , uword_t * sec )
2017-03-22 15:52:59 +01:00
{
2017-03-24 07:01:47 +01:00
// convert gps decigrad value into degrees, minutes and seconds
uword_t temp ;
uint32_t absvalue = abs ( value ) ;
uint16_t degrees = ( absvalue / 10000000 ) ;
uint32_t seconds = ( absvalue - degrees * 10000000 ) * 6 ;
uint16_t minutes = seconds / 1000000 ;
seconds % = 1000000 ;
seconds = seconds / 100 ;
uint16_t degmin = degrees * 100 + minutes ;
// write results
* dir = ( value < 0 ) ? 1 : 0 ;
temp . l = ( uint8_t ) degmin & 0xff ;
temp . h = ( uint8_t ) ( degmin > > 8 ) & 0xff ;
* min = temp ;
temp . l = ( uint8_t ) seconds & 0xff ;
temp . h = ( uint8_t ) ( seconds > > 8 ) & 0xff ;
* sec = temp ;
2017-03-22 15:52:59 +01:00
}
2017-03-24 07:01:47 +01:00
# endif // PIOS_INCLUDE_HOTT_BRIDGE
2017-03-22 15:52:59 +01:00
/**
* @ }
* @ }
*/