Files
paparazzi/sw/airborne/modules/hott/hott.c
T
2016-03-31 18:09:36 +02:00

298 lines
7.7 KiB
C

/*
* Copyright (C) 2013 Sergey Krukowski <softsr@yahoo.de>
*
* This file is part of paparazzi.
*
* paparazzi 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 2, or (at your option)
* any later version.
*
* paparazzi 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 paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/** @file hott.c
*
* Graupner HOTT telemetry control module.
*/
#include "hott/hott.h"
#if HOTT_SIM_GAM_SENSOR
#include "hott/hott_gam.h"
#endif
#if HOTT_SIM_EAM_SENSOR
#include "hott/hott_eam.h"
#endif
#if HOTT_SIM_GPS_SENSOR
#include "hott/hott_gps.h"
#endif
#if HOTT_SIM_VARIO_SENSOR
#include "hott/hott_vario.h"
#endif
#include "mcu_periph/sys_time.h"
#include "mcu_periph/uart.h"
#define HOTT_TEXT_MODE_REQUEST_ID 0x7f
#define HOTT_BINARY_MODE_REQUEST_ID 0x80
//Sensor Ids
//Graupner #33600 GPS Module
#define HOTT_TELEMETRY_GPS_SENSOR_ID 0x8A
//Graupner #33601 Vario Module
#define HOTT_TELEMETRY_VARIO_SENSOR_ID 0x89
static uint32_t hott_event_timer; // 1ms software timer
static bool hott_telemetry_is_sending = false;
static uint16_t hott_telemetry_sendig_msgs_id = 0;
#if HOTT_SIM_GPS_SENSOR
bool HOTT_REQ_UPDATE_GPS = false;
#endif
#if HOTT_SIM_EAM_SENSOR
bool HOTT_REQ_UPDATE_EAM = false;
#endif
#if HOTT_SIM_VARIO_SENSOR
bool HOTT_REQ_UPDATE_VARIO = false;
#endif
#if HOTT_SIM_GAM_SENSOR
bool HOTT_REQ_UPDATE_GAM = false;
#endif
// HoTT serial send buffer pointer
static int8_t *hott_msg_ptr = 0;
// Len of HoTT serial buffer
static int16_t hott_msg_len = 0;
#if HOTT_SIM_GAM_SENSOR
static struct HOTT_GAM_MSG hott_gam_msg;
#endif
#if HOTT_SIM_EAM_SENSOR
static struct HOTT_EAM_MSG hott_eam_msg;
#endif
#if HOTT_SIM_GPS_SENSOR
static struct HOTT_GPS_MSG hott_gps_msg;
#endif
#if HOTT_SIM_VARIO_SENSOR
static struct HOTT_VARIO_MSG hott_vario_msg;
#endif
/**
* Initializes a HoTT GPS message (Receiver answer type !Not Smartbox)
*/
static void hott_msgs_init(void)
{
#if HOTT_SIM_EAM_SENSOR
hott_init_eam_msg(&hott_eam_msg);
#endif
#if HOTT_SIM_GAM_SENSOR
hott_init_gam_msg(&hott_gam_msg);
#endif
#if HOTT_SIM_GPS_SENSOR
hott_init_gps_msg(&hott_gam_msg);
#endif
#if HOTT_SIM_VARIO_SENSOR
hott_init_vario_msg(&hott_gam_msg);
#endif
#if HOTT_SIM_TEXTMODE
hott_init_text_msg(&hott_gam_msg);
#endif
}
static void hott_enable_transmitter(void)
{
//enables serial transmitter, disables receiver
uart_periph_set_mode(&HOTT_PORT, TRUE, FALSE, FALSE);
}
static void hott_enable_receiver(void)
{
//enables serial receiver, disables transmitter
uart_periph_set_mode(&HOTT_PORT, TRUE, TRUE, FALSE);
}
void hott_init(void)
{
hott_msgs_init();
}
/**/
void hott_periodic(void)
{
#if HOTT_SIM_EAM_SENSOR
if ((hott_telemetry_sendig_msgs_id != HOTT_TELEMETRY_EAM_SENSOR_ID) &&
HOTT_REQ_UPDATE_EAM == TRUE) {
hott_update_eam_msg(&hott_eam_msg);
HOTT_REQ_UPDATE_EAM = false;
}
#endif
#if HOTT_SIM_GAM_SENSOR
if ((hott_telemetry_sendig_msgs_id != HOTT_TELEMETRY_GAM_SENSOR_ID) &&
HOTT_REQ_UPDATE_GAM == TRUE) {
hott_update_gam_msg(&hott_gam_msg);
HOTT_REQ_UPDATE_GAM = false;
}
#endif
#if HOTT_SIM_GPS_SENSOR
if ((hott_telemetry_sendig_msgs_id != HOTT_TELEMETRY_GPS_SENSOR_ID) &&
HOTT_REQ_UPDATE_GPS == TRUE) {
hott_update_gps_msg(&hott_gam_msg);
HOTT_REQ_UPDATE_GPS = false;
}
#endif
#if HOTT_SIM_VARIO_SENSOR
if ((hott_telemetry_sendig_msgs_id != HOTT_TELEMETRY_VARIO_SENSOR_ID) &&
HOTT_REQ_UPDATE_VARIO == TRUE) {
hott_update_vario_msg(&hott_gam_msg);
HOTT_REQ_UPDATE_VARIO = false;
}
#endif
}
static void hott_send_msg(int8_t *buffer, int16_t len)
{
if (hott_telemetry_is_sending == TRUE) { return; }
hott_msg_ptr = buffer;
hott_msg_len = len + 1; //len + 1 byte for crc
hott_telemetry_sendig_msgs_id = buffer[1]; //HoTT msgs id is the 2. byte
}
static void hott_send_telemetry_data(void)
{
static int16_t msg_crc = 0;
if (!hott_telemetry_is_sending) {
hott_telemetry_is_sending = true;
hott_enable_transmitter();
}
if (hott_msg_len == 0) {
hott_msg_ptr = 0;
hott_telemetry_is_sending = false;
hott_telemetry_sendig_msgs_id = 0;
msg_crc = 0;
hott_enable_receiver();
while (uart_char_available(&HOTT_PORT)) {
uart_getch(&HOTT_PORT);
}
} else {
--hott_msg_len;
if (hott_msg_len != 0) {
msg_crc += *hott_msg_ptr;
uart_put_byte(&HOTT_PORT, 0, *hott_msg_ptr++);
} else {
uart_put_byte(&HOTT_PORT, 0, (int8_t)msg_crc);
}
}
}
static void hott_check_serial_data(uint32_t tnow)
{
static uint32_t hott_serial_request_timer = 0;
if (hott_telemetry_is_sending == TRUE) { return; }
if (uart_char_available(&HOTT_PORT) > 1) {
if (uart_char_available(&HOTT_PORT) == 2) {
if (hott_serial_request_timer == 0) {
hott_serial_request_timer = tnow;
return;
} else {
if (tnow - hott_serial_request_timer < 4600) { //wait ca. 5ms
return;
}
hott_serial_request_timer = 0;
}
uint8_t c = uart_getch(&HOTT_PORT);
uint8_t addr = uart_getch(&HOTT_PORT);
switch (c) {
#if HOTT_SIM_TEXTMODE
case HOTT_TEXT_MODE_REQUEST_ID:
//Text mode, handle only if not armed!
if (!autopilot_motors_on) {
hott_txt_msg.start_byte = 0x7b;
hott_txt_msg.stop_byte = 0x7d;
uint8_t tmp = (addr >> 4); // Sensor type
if (tmp == (HOTT_SIM_TEXTMODE_ADDRESS & 0x0f)) {
HOTT_Clear_Text_Screen();
HOTT_HandleTextMode(addr);
hott_send_text_msg();
}
}
break;
#endif
case HOTT_BINARY_MODE_REQUEST_ID:
#if HOTT_SIM_EAM_SENSOR
if (addr == HOTT_TELEMETRY_EAM_SENSOR_ID) {
hott_send_msg((int8_t *)&hott_eam_msg, sizeof(struct HOTT_EAM_MSG));
HOTT_REQ_UPDATE_EAM = true;
break;
}
#endif
#if HOTT_SIM_GAM_SENSOR
if (addr == HOTT_TELEMETRY_GAM_SENSOR_ID) {
hott_send_msg((int8_t *)&hott_gam_msg, sizeof(struct HOTT_GAM_MSG));
HOTT_REQ_UPDATE_GAM = true;
break;
}
#endif
#if HOTT_SIM_GPS_SENSOR
if (addr == HOTT_TELEMETRY_GPS_SENSOR_ID) {
hott_send_msg((int8_t *)&hott_gps_msg, sizeof(struct HOTT_GPS_MSG));
HOTT_REQ_UPDATE_GPS = true;
break;
}
#endif
#if HOTT_SIM_VARIO_SENSOR
if (addr == HOTT_TELEMETRY_VARIO_SENSOR_ID) {
hott_send_msg((int8_t *)&hott_vario_msg, sizeof(struct HOTT_VARIO_MSG));
HOTT_REQ_UPDATE_VARIO = true;
break;
}
#endif
break; // HOTT_BINARY_MODE_REQUEST_ID:
default:
break;
}
} else {
while (uart_char_available(&HOTT_PORT)) {
uart_getch(&HOTT_PORT);
}
hott_serial_request_timer = 0;
}
}
}
static void hott_periodic_event(uint32_t tnow)
{
static uint32_t hott_serial_timer;
hott_check_serial_data(tnow);
if (hott_msg_ptr == 0) { return; }
if (hott_telemetry_is_sending) {
if (tnow - hott_serial_timer < 3000) { //delay ca. 3,5 mS. 19200 baud = 520uS / int8_t + 3ms required delay
return;
}
} else {
tnow = get_sys_time_usec();
}
hott_send_telemetry_data();
hott_serial_timer = tnow;
}
void hott_event(void)
{
if (SysTimeTimer(hott_event_timer) > 1000) {
SysTimeTimerStart(hott_event_timer);
hott_periodic_event(hott_event_timer);
}
}