From e6d4638201533b63522cf2fb40219ffadf3be435 Mon Sep 17 00:00:00 2001 From: Fredrik Arvidsson Date: Sun, 20 Dec 2015 11:08:15 +0100 Subject: [PATCH 1/4] LP-104 Adds support for Graupner HoTT SUMD/SUMH serial protocol used by receivers on Main and Flexi port. Still work in progress. Only supports CopterControl target and crashes on input :( --- flight/make/apps-defs.mk | 3 +- flight/pios/common/pios_hott.c | 419 ++++++++++++++++++ flight/pios/inc/pios_hott.h | 36 ++ flight/pios/inc/pios_hott_priv.h | 53 +++ flight/pios/pios.h | 5 + .../boards/coptercontrol/board_hw_defs.c | 80 ++++ .../coptercontrol/firmware/inc/pios_config.h | 1 + .../coptercontrol/firmware/pios_board.c | 48 ++ .../targets/boards/coptercontrol/pios_board.h | 6 + shared/uavobjectdefinition/hwsettings.xml | 4 +- .../manualcontrolsettings.xml | 2 +- 11 files changed, 653 insertions(+), 4 deletions(-) create mode 100644 flight/pios/common/pios_hott.c create mode 100644 flight/pios/inc/pios_hott.h create mode 100644 flight/pios/inc/pios_hott_priv.h diff --git a/flight/make/apps-defs.mk b/flight/make/apps-defs.mk index 45bdb0049..03e67ed47 100644 --- a/flight/make/apps-defs.mk +++ b/flight/make/apps-defs.mk @@ -34,7 +34,7 @@ FLIGHTLIBINC = $(FLIGHTLIB)/inc OPUAVOBJINC = $(OPUAVOBJ)/inc OPUAVTALKINC = $(OPUAVTALK)/inc -## PID +## PID PIDLIB =$(FLIGHTLIB)/pid PIDLIBINC =$(FLIGHTLIB)/pid @@ -86,6 +86,7 @@ SRC += $(PIOSCOMMON)/pios_rfm22b.c SRC += $(PIOSCOMMON)/pios_rfm22b_com.c SRC += $(PIOSCOMMON)/pios_rcvr.c SRC += $(PIOSCOMMON)/pios_sbus.c +SRC += $(PIOSCOMMON)/pios_hott.c SRC += $(PIOSCOMMON)/pios_srxl.c SRC += $(PIOSCOMMON)/pios_sdcard.c SRC += $(PIOSCOMMON)/pios_sensors.c diff --git a/flight/pios/common/pios_hott.c b/flight/pios/common/pios_hott.c new file mode 100644 index 000000000..aba62c708 --- /dev/null +++ b/flight/pios/common/pios_hott.c @@ -0,0 +1,419 @@ +/** + ****************************************************************************** + * @file pios_hott.c + * @author The LibrePilot Project, http://www.librepilot.org, Copyright (c) 2015 + * @author Tau Labs, http://taulabs.org, Copyright (C) 2013-2014 + * @addtogroup PIOS PIOS Core hardware abstraction layer + * @{ + * @addtogroup PIOS_HOTT Graupner HoTT receiver functions + * @{ + * @brief Graupner HoTT receiver functions for SUMD/H + *****************************************************************************/ +/* + * 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 + */ +/* Project Includes */ +#include "pios_hott_priv.h" + +#if defined(PIOS_INCLUDE_HOTT) + +#if !defined(PIOS_INCLUDE_RTC) +#error PIOS_INCLUDE_RTC must be used to use HOTT +#endif + +/** + * HOTT protocol documentation + * + * Currently known Graupner HoTT serial port settings: + * 115200bps serial stream, 8 bits, no parity, 1 stop bit + * size of each frame: 11..37 bytes + * data resolution: 14 bit + * frame period: 11ms or 22ms + * + * Currently known SUMD/SUMH frame structure: + * Section Byte_Number Byte_Name Byte_Value Remark + * Header 0 Vendor_ID 0xA8 Graupner + * Header 1 Status 0x00 valid and live SUMH data frame + * 0x01 valid and live SUMD data frame + * 0x81 valid SUMD/H data frame with + * transmitter in fail safe condition + * others invalid frame + * Header 2 N_Channels 0x02..0x20 number of transmitted channels + * Data n*2+1 Channel n MSB 0x00..0xff High Byte of channel n data + * Data n*2+2 Channel n LSB 0x00..0xff Low Byte of channel n data + * SUMD_CRC (N_Channels+1)*2+1 CRC High Byte 0x00..0xff High Byte of 16 Bit CRC + * SUMD_CRC (N_Channels+1)*2+2 CRC Low Byte 0x00..0xff Low Byte of 16 Bit CRC + * SUMH_Telemetry (N_Channels+1)*2+1 Telemetry_Req 0x00..0xff 0x00 no telemetry request + * SUMH_CRC (N_Channels+1)*2+2 CRC Byte 0x00..0xff Low Byte of all added data bytes + + * Channel Data Interpretation + * Stick Positon Channel Data Remark + * ext. low (-150%) 0x1c20 900µs + * low (-100%) 0x2260 1100µs + * neutral (0%) 0x2ee0 1500µs + * high (100%) 0x3b60 1900µs + * ext. high(150%) 0x41a0 2100µs + + * Channel Mapping (not sure) + * 1 Pitch + * 2 Aileron + * 3 Elevator + * 4 Yaw + * 5 Aux/Gyro on MX-12 + * 6 ESC + * 7 Aux/Gyr + */ + +/* HOTT frame size and contents definitions */ +#define HOTT_HEADER_LENGTH 3 +#define HOTT_CRC_LENGTH 2 +#define HOTT_MAX_CHANNELS_PER_FRAME 32 +#define HOTT_OVERHEAD_LENGTH (HOTT_HEADER_LENGTH+HOTT_CRC_LENGTH) +#define HOTT_MAX_FRAME_LENGTH (HOTT_MAX_CHANNELS_PER_FRAME*2+HOTT_OVERHEAD_LENGTH) + +#define HOTT_GRAUPNER_ID 0xA8 +#define HOTT_STATUS_LIVING_SUMH 0x00 +#define HOTT_STATUS_LIVING_SUMD 0x01 +#define HOTT_STATUS_FAILSAFE 0x81 + +/* Forward Declarations */ +static int32_t PIOS_HOTT_Get(uint32_t rcvr_id, uint8_t channel); +static uint16_t PIOS_HOTT_RxInCallback(uint32_t context, + uint8_t *buf, + uint16_t buf_len, + uint16_t *headroom, + bool *need_yield); +static void PIOS_HOTT_Supervisor(uint32_t hott_id); + +/* Local Variables */ +const struct pios_rcvr_driver pios_hott_rcvr_driver = { + .read = PIOS_HOTT_Get, +}; + +enum pios_hott_dev_magic { + PIOS_HOTT_DEV_MAGIC = 0x4853554D, +}; + +struct pios_hott_state { + uint16_t channel_data[PIOS_HOTT_NUM_INPUTS]; + uint8_t received_data[HOTT_MAX_FRAME_LENGTH]; + uint8_t receive_timer; + uint8_t failsafe_timer; + uint8_t frame_found; + uint8_t tx_connected; + uint8_t byte_count; + uint8_t frame_length; +}; + +struct pios_hott_dev { + enum pios_hott_dev_magic magic; + const struct pios_hott_cfg *cfg; + enum pios_hott_proto proto; + struct pios_hott_state state; +}; + +/* Allocate HOTT device descriptor */ +#if defined(PIOS_INCLUDE_FREERTOS) +static struct pios_hott_dev *PIOS_HOTT_Alloc(void) +{ + struct pios_hott_dev *hott_dev; + + hott_dev = (struct pios_hott_dev *)pios_malloc(sizeof(*hott_dev)); + if (!hott_dev) + return NULL; + + hott_dev->magic = PIOS_HOTT_DEV_MAGIC; + return hott_dev; +} +#else +static struct pios_hott_dev pios_hott_devs[PIOS_HOTT_MAX_DEVS]; +static uint8_t pios_hott_num_devs; +static struct pios_hott_dev *PIOS_HOTT_Alloc(void) +{ + struct pios_hott_dev *hott_dev; + + if (pios_hott_num_devs >= PIOS_HOTT_MAX_DEVS) + return NULL; + + hott_dev = &pios_hott_devs[pios_hott_num_devs++]; + hott_dev->magic = PIOS_HOTT_DEV_MAGIC; + + return hott_dev; +} +#endif + +/* Validate HOTT device descriptor */ +static bool PIOS_HOTT_Validate(struct pios_hott_dev *hott_dev) +{ + return (hott_dev->magic == PIOS_HOTT_DEV_MAGIC); +} + +/* Reset channels in case of lost signal or explicit failsafe receiver flag */ +static void PIOS_HOTT_ResetChannels(struct pios_hott_state *state) +{ + for (int i = 0; i < PIOS_HOTT_NUM_INPUTS; i++) { + state->channel_data[i] = PIOS_RCVR_TIMEOUT; + } +} + +/* Reset HOTT receiver state */ +static void PIOS_HOTT_ResetState(struct pios_hott_state *state) +{ + state->receive_timer = 0; + state->failsafe_timer = 0; + state->frame_found = 0; + state->tx_connected = 0; + PIOS_HOTT_ResetChannels(state); +} + +/** + * Check and unroll complete frame data. + * \output 0 frame data accepted + * \output -1 frame error found + */ +static int PIOS_HOTT_UnrollChannels(struct pios_hott_dev *hott_dev) +{ + struct pios_hott_state *state = &(hott_dev->state); + + /* check the header and crc for a valid HoTT SUM stream */ + uint8_t vendor = state->received_data[0]; + uint8_t status = state->received_data[1]; + if (vendor != HOTT_GRAUPNER_ID) + /* Graupner ID was expected */ + goto stream_error; + + switch (status) { + case HOTT_STATUS_LIVING_SUMH: + case HOTT_STATUS_LIVING_SUMD: + case HOTT_STATUS_FAILSAFE: + /* check crc before processing */ + if (hott_dev->proto == PIOS_HOTT_PROTO_SUMD) { + /* SUMD has 16 bit CCITT CRC */ + uint16_t crc = 0; + uint8_t *s = &(state->received_data[0]); + int len = state->byte_count - 2; + for (int n = 0; n < len; n++) { + crc ^= (uint16_t)s[n] << 8; + for (int i = 0; i < 8; i++) + crc = (crc & 0x8000) ? (crc << 1) ^ 0x1021 : (crc << 1); + } + if (crc ^ (((uint16_t)s[len] << 8) | s[len + 1])) + /* wrong crc checksum found */ + goto stream_error; + } + if (hott_dev->proto == PIOS_HOTT_PROTO_SUMH) { + /* SUMH has only 8 bit added CRC */ + uint8_t crc = 0; + uint8_t *s = &(state->received_data[0]); + int len = state->byte_count - 1; + for (int n = 0; n < len; n++) + crc += s[n]; + if (crc ^ s[len]) + /* wrong crc checksum found */ + goto stream_error; + } + /* check for a living connect */ + state->tx_connected |= (status != HOTT_STATUS_FAILSAFE); + break; + default: + /* wrong header format */ + goto stream_error; + } + + /* check initial connection since reset or timeout */ + if (!(state->tx_connected)) { + /* these are failsafe data without a first connect. ignore it */ + PIOS_HOTT_ResetChannels(state); + return 0; + } + + /* unroll channels */ + uint8_t n_channels = state->received_data[2]; + uint8_t *s = &(state->received_data[3]); + uint16_t word; + + for (int i = 0; i < HOTT_MAX_CHANNELS_PER_FRAME; i++) { + if (i < n_channels) { + word = ((uint16_t)s[0] << 8) | s[1]; + s += sizeof(uint16_t); + /* save the channel value */ + if (i < PIOS_HOTT_NUM_INPUTS) { + /* floating version. channel limits from -100..+100% are mapped to 1000..2000 */ + state->channel_data[i] = (uint16_t)(word / 6.4f - 375); + } + } else + /* this channel was not received */ + state->channel_data[i] = PIOS_RCVR_INVALID; + } + + /* all channels processed */ + return 0; + +stream_error: + /* either SUMD selected with SUMH stream found, or vice-versa */ + return -1; +} + +/* Update decoder state processing input byte from the HoTT stream */ +static void PIOS_HOTT_UpdateState(struct pios_hott_dev *hott_dev, uint8_t byte) +{ + struct pios_hott_state *state = &(hott_dev->state); + if (state->frame_found) { + /* receiving the data frame */ + if (state->byte_count < HOTT_MAX_FRAME_LENGTH) { + /* store next byte */ + state->received_data[state->byte_count++] = byte; + if (state->byte_count == HOTT_HEADER_LENGTH) { + /* 3rd byte contains the number of channels. calculate frame size */ + state->frame_length = HOTT_OVERHEAD_LENGTH + 2 * byte; + } + if (state->byte_count == state->frame_length) { + /* full frame received - process and wait for new one */ + if (!PIOS_HOTT_UnrollChannels(hott_dev)) + /* data looking good */ + state->failsafe_timer = 0; + /* prepare for the next frame */ + state->frame_found = 0; + } + } + } +} + +/* Initialise HoTT receiver interface */ +int32_t PIOS_HOTT_Init(uint32_t *hott_id, + const struct pios_com_driver *driver, + uint32_t lower_id, + enum pios_hott_proto proto) +{ + PIOS_DEBUG_Assert(hott_id); + PIOS_DEBUG_Assert(driver); + + struct pios_hott_dev *hott_dev; + + hott_dev = (struct pios_hott_dev *)PIOS_HOTT_Alloc(); + if (!hott_dev) + return -1; + + /* Bind the configuration to the device instance */ + hott_dev->proto = proto; + + PIOS_HOTT_ResetState(&(hott_dev->state)); + + *hott_id = (uint32_t)hott_dev; + + /* Set comm driver callback */ + (driver->bind_rx_cb)(lower_id, PIOS_HOTT_RxInCallback, *hott_id); + + if (!PIOS_RTC_RegisterTickCallback(PIOS_HOTT_Supervisor, *hott_id)) { + PIOS_DEBUG_Assert(0); + } + + return 0; +} + +/* Comm byte received callback */ +static uint16_t PIOS_HOTT_RxInCallback(uint32_t context, + uint8_t *buf, + uint16_t buf_len, + uint16_t *headroom, + bool *need_yield) +{ + struct pios_hott_dev *hott_dev = (struct pios_hott_dev *)context; + + bool valid = PIOS_HOTT_Validate(hott_dev); + PIOS_Assert(valid); + + /* process byte(s) and clear receive timer */ + for (uint8_t i = 0; i < buf_len; i++) { + PIOS_HOTT_UpdateState(hott_dev, buf[i]); + hott_dev->state.receive_timer = 0; + } + + /* Always signal that we can accept more data */ + if (headroom) + *headroom = HOTT_MAX_FRAME_LENGTH; + + /* We never need a yield */ + *need_yield = false; + + /* Always indicate that all bytes were consumed */ + return buf_len; +} + +/** + * Get the value of an input channel + * \param[in] channel Number of the channel desired (zero based) + * \output PIOS_RCVR_INVALID channel not available + * \output PIOS_RCVR_TIMEOUT failsafe condition or missing receiver + * \output >=0 channel value + */ +static int32_t PIOS_HOTT_Get(uint32_t rcvr_id, uint8_t channel) +{ + struct pios_hott_dev *hott_dev = (struct pios_hott_dev *)rcvr_id; + + if (!PIOS_HOTT_Validate(hott_dev)) + return PIOS_RCVR_INVALID; + + /* return error if channel is not available */ + if (channel >= PIOS_HOTT_NUM_INPUTS) + return PIOS_RCVR_INVALID; + + /* may also be PIOS_RCVR_TIMEOUT set by other function */ + return hott_dev->state.channel_data[channel]; +} + +/** + * Input data supervisor is called periodically and provides + * two functions: frame syncing and failsafe triggering. + * + * HOTT frames come at 11ms or 22ms rate at 115200bps. + * RTC timer is running at 625Hz (1.6ms). So with divider 5 it gives + * 8ms pause between frames which is good for both HOTT frame rates. + * + * Data receive function must clear the receive_timer to confirm new + * data reception. If no new data received in 100ms, we must call the + * failsafe function which clears all channels. + */ +static void PIOS_HOTT_Supervisor(uint32_t hott_id) +{ + struct pios_hott_dev *hott_dev = (struct pios_hott_dev *)hott_id; + + bool valid = PIOS_HOTT_Validate(hott_dev); + PIOS_Assert(valid); + + struct pios_hott_state *state = &(hott_dev->state); + + /* waiting for new frame if no bytes were received in 8ms */ + if (++state->receive_timer > 4) { + state->frame_found = 1; + state->byte_count = 0; + state->receive_timer = 0; + state->frame_length = HOTT_MAX_FRAME_LENGTH; + } + + /* activate failsafe if no frames have arrived in 102.4ms */ + if (++state->failsafe_timer > 64) { + PIOS_HOTT_ResetChannels(state); + state->failsafe_timer = 0; + state->tx_connected = 0; + } +} + +#endif /* PIOS_INCLUDE_HOTT */ + +/** + * @} + * @} + */ diff --git a/flight/pios/inc/pios_hott.h b/flight/pios/inc/pios_hott.h new file mode 100644 index 000000000..bea4c6887 --- /dev/null +++ b/flight/pios/inc/pios_hott.h @@ -0,0 +1,36 @@ +/** + ****************************************************************************** + * @file pios_hott.h + * @author The LibrePilot Project, http://www.librepilot.org, Copyright (c) 2015 + * @author Tau Labs, http://taulabs.org, Copyright (C) 2013 + * @addtogroup PIOS PIOS Core hardware abstraction layer + * @{ + * @addtogroup PIOS_HOTT Graupner HoTT receiver functions + * @{ + * @brief Graupner HoTT receiver functions for SUMD/H + *****************************************************************************/ +/* + * 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 + */ + +#ifndef PIOS_HOTT_H +#define PIOS_HOTT_H + +#endif /* PIOS_HOTT_H */ + +/** + * @} + * @} + */ diff --git a/flight/pios/inc/pios_hott_priv.h b/flight/pios/inc/pios_hott_priv.h new file mode 100644 index 000000000..b120d82ab --- /dev/null +++ b/flight/pios/inc/pios_hott_priv.h @@ -0,0 +1,53 @@ +/** + ****************************************************************************** + * @file pios_hott_private.h + * @author The LibrePilot Project, http://www.librepilot.org, Copyright (c) 2015 + * @author Tau Labs, http://taulabs.org, Copyright (C) 2013 + * @addtogroup PIOS PIOS Core hardware abstraction layer + * @{ + * @addtogroup PIOS_HOTT Graupner HoTT receiver functions + * @{ + * @brief Graupner HoTT receiver functions for SUMD/H + *****************************************************************************/ +/* + * 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 + */ + +#ifndef PIOS_HOTT_PRIV_H +#define PIOS_HOTT_PRIV_H + +#include +#include + +/* HOTT protocol variations */ +enum pios_hott_proto { + PIOS_HOTT_PROTO_SUMD, + PIOS_HOTT_PROTO_SUMH, +}; + +/* HOTT receiver instance configuration */ +extern const struct pios_rcvr_driver pios_hott_rcvr_driver; + +extern int32_t PIOS_HOTT_Init(uint32_t *hott_id, + const struct pios_com_driver *driver, + uint32_t lower_id, + enum pios_hott_proto proto); + +#endif /* PIOS_HOTT_PRIV_H */ + +/** + * @} + * @} + */ diff --git a/flight/pios/pios.h b/flight/pios/pios.h index ed3e8fd52..398b77ac4 100644 --- a/flight/pios/pios.h +++ b/flight/pios/pios.h @@ -1,6 +1,7 @@ /** ****************************************************************************** * @file pios.h + * @author The LibrePilot Project, http://www.librepilot.org, Copyright (c) 2015 * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010-2013 * @author PhoenixPilot, http://github.com/PhoenixPilot, Copyright (C) 2012 * @brief Main PiOS header. @@ -228,6 +229,10 @@ extern "C" { #include #endif +#ifdef PIOS_INCLUDE_HOTT +#include +#endif + #ifdef PIOS_INCLUDE_SRXL #include #endif diff --git a/flight/targets/boards/coptercontrol/board_hw_defs.c b/flight/targets/boards/coptercontrol/board_hw_defs.c index 1e464899d..f4cde50f4 100644 --- a/flight/targets/boards/coptercontrol/board_hw_defs.c +++ b/flight/targets/boards/coptercontrol/board_hw_defs.c @@ -1021,6 +1021,86 @@ static const struct pios_dsm_cfg pios_dsm_flexi_cfg = { #endif /* PIOS_INCLUDE_DSM */ +#if defined(PIOS_INCLUDE_HOTT) +/* + * HOTT USART + */ +#include + +static const struct pios_usart_cfg pios_usart_hott_main_cfg = { + .regs = USART1, + .init = { + .USART_BaudRate = 115200, + .USART_WordLength = USART_WordLength_8b, + .USART_Parity = USART_Parity_No, + .USART_StopBits = USART_StopBits_1, + .USART_HardwareFlowControl = USART_HardwareFlowControl_None, + .USART_Mode = USART_Mode_Rx, + }, + .irq = { + .init = { + .NVIC_IRQChannel = USART1_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, + .rx = { + .gpio = GPIOA, + .init = { + .GPIO_Pin = GPIO_Pin_10, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_IPU, + }, + }, + .tx = { + .gpio = GPIOA, + .init = { + .GPIO_Pin = GPIO_Pin_9, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_IN_FLOATING, + }, + }, +}; + +static const struct pios_usart_cfg pios_usart_hott_flexi_cfg = { + .regs = USART3, + .init = { + .USART_BaudRate = 115200, + .USART_WordLength = USART_WordLength_8b, + .USART_Parity = USART_Parity_No, + .USART_StopBits = USART_StopBits_1, + .USART_HardwareFlowControl = USART_HardwareFlowControl_None, + .USART_Mode = USART_Mode_Rx, + }, + .irq = { + .init = { + .NVIC_IRQChannel = USART3_IRQn, + .NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_HIGH, + .NVIC_IRQChannelSubPriority = 0, + .NVIC_IRQChannelCmd = ENABLE, + }, + }, + .rx = { + .gpio = GPIOB, + .init = { + .GPIO_Pin = GPIO_Pin_11, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_IPU, + }, + }, + .tx = { + .gpio = GPIOB, + .init = { + .GPIO_Pin = GPIO_Pin_10, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_Mode = GPIO_Mode_IN_FLOATING, + }, + }, +}; + +#endif /* PIOS_INCLUDE_HOTT */ + #if defined(PIOS_INCLUDE_SRXL) /* * SRXL USART diff --git a/flight/targets/boards/coptercontrol/firmware/inc/pios_config.h b/flight/targets/boards/coptercontrol/firmware/inc/pios_config.h index 02fcd4979..54b1d3039 100644 --- a/flight/targets/boards/coptercontrol/firmware/inc/pios_config.h +++ b/flight/targets/boards/coptercontrol/firmware/inc/pios_config.h @@ -102,6 +102,7 @@ #define PIOS_INCLUDE_DSM #define PIOS_INCLUDE_SBUS #define PIOS_INCLUDE_SRXL +#define PIOS_INCLUDE_HOTT /* #define PIOS_INCLUDE_GCSRCVR */ /* #define PIOS_INCLUDE_OPLINKRCVR */ diff --git a/flight/targets/boards/coptercontrol/firmware/pios_board.c b/flight/targets/boards/coptercontrol/firmware/pios_board.c index 659980639..ef1d2b4ec 100644 --- a/flight/targets/boards/coptercontrol/firmware/pios_board.c +++ b/flight/targets/boards/coptercontrol/firmware/pios_board.c @@ -518,6 +518,29 @@ void PIOS_Board_Init(void) } #endif /* PIOS_INCLUDE_DSM */ break; + case HWSETTINGS_CC_MAINPORT_HOTTSUMD: + case HWSETTINGS_CC_MAINPORT_HOTTSUMH: +#if defined(PIOS_INCLUDE_HOTT) + { + uint32_t pios_usart_hott_id; + if (PIOS_USART_Init(&pios_usart_hott_id, &pios_usart_hott_main_cfg)) { + PIOS_Assert(0); + } + + uint32_t pios_hott_id; + if (PIOS_HOTT_Init(&pios_hott_id, &pios_usart_com_driver, pios_usart_hott_id, + hwsettings_cc_mainport == HWSETTINGS_CC_MAINPORT_HOTTSUMD ? PIOS_HOTT_PROTO_SUMD : PIOS_HOTT_PROTO_SUMH)) { + PIOS_Assert(0); + } + + uint32_t pios_hott_rcvr_id; + if (PIOS_RCVR_Init(&pios_hott_rcvr_id, &pios_hott_rcvr_driver, pios_hott_id)) { + PIOS_Assert(0); + } + pios_rcvr_group_map[MANUALCONTROLSETTINGS_CHANNELGROUPS_HOTTMAINPORT] = pios_hott_rcvr_id; + } +#endif /* PIOS_INCLUDE_HOTT */ + break; case HWSETTINGS_CC_MAINPORT_DEBUGCONSOLE: #if defined(PIOS_INCLUDE_COM) #if defined(PIOS_INCLUDE_DEBUG_CONSOLE) @@ -674,6 +697,31 @@ void PIOS_Board_Init(void) } #endif /* PIOS_INCLUDE_DSM */ break; + + case HWSETTINGS_CC_FLEXIPORT_HOTTSUMD: + case HWSETTINGS_CC_FLEXIPORT_HOTTSUMH: +#if defined(PIOS_INCLUDE_HOTT) + { + uint32_t pios_usart_hott_id; + if (PIOS_USART_Init(&pios_usart_hott_id, &pios_usart_hott_flexi_cfg)) { + PIOS_Assert(0); + } + + uint32_t pios_hott_id; + if (PIOS_HOTT_Init(&pios_hott_id, &pios_usart_com_driver, pios_usart_hott_id, + hwsettings_cc_flexiport == HWSETTINGS_CC_FLEXIPORT_HOTTSUMD ? PIOS_HOTT_PROTO_SUMD : PIOS_HOTT_PROTO_SUMH)) { + PIOS_Assert(0); + } + + uint32_t pios_hott_rcvr_id; + if (PIOS_RCVR_Init(&pios_hott_rcvr_id, &pios_hott_rcvr_driver, pios_hott_id)) { + PIOS_Assert(0); + } + pios_rcvr_group_map[MANUALCONTROLSETTINGS_CHANNELGROUPS_HOTTFLEXIPORT] = pios_hott_rcvr_id; + } +#endif /* PIOS_INCLUDE_HOTT */ + break; + case HWSETTINGS_CC_FLEXIPORT_SRXL: #if defined(PIOS_INCLUDE_SRXL) { diff --git a/flight/targets/boards/coptercontrol/pios_board.h b/flight/targets/boards/coptercontrol/pios_board.h index 36e719378..6fad48ef9 100644 --- a/flight/targets/boards/coptercontrol/pios_board.h +++ b/flight/targets/boards/coptercontrol/pios_board.h @@ -248,6 +248,12 @@ extern uint32_t pios_com_hkosd_id; #define PIOS_SBUS_MAX_DEVS 1 #define PIOS_SBUS_NUM_INPUTS (16 + 2) +//------------------------- +// Receiver HSUM input +//------------------------- +#define PIOS_HOTT_MAX_DEVS 2 +#define PIOS_HOTT_NUM_INPUTS 32 + // ------------------------- // Receiver Multiplex SRXL input // ------------------------- diff --git a/shared/uavobjectdefinition/hwsettings.xml b/shared/uavobjectdefinition/hwsettings.xml index 9d705d2cc..9b5459678 100644 --- a/shared/uavobjectdefinition/hwsettings.xml +++ b/shared/uavobjectdefinition/hwsettings.xml @@ -2,8 +2,8 @@ Selection of optional hardware configurations. - - + + diff --git a/shared/uavobjectdefinition/manualcontrolsettings.xml b/shared/uavobjectdefinition/manualcontrolsettings.xml index b95020df9..93565d66c 100644 --- a/shared/uavobjectdefinition/manualcontrolsettings.xml +++ b/shared/uavobjectdefinition/manualcontrolsettings.xml @@ -3,7 +3,7 @@ Settings to indicate how to decode receiver input by @ref ManualControlModule. + options="PWM,PPM,DSM (MainPort),DSM (FlexiPort),S.Bus,HOTT (MainPort),HOTT (FlexiPort),SRXL,GCS,OPLink,None" defaultvalue="None"/> Date: Sun, 20 Dec 2015 11:57:46 +0100 Subject: [PATCH 2/4] LP-104 Adding support to GCS for HoTT configuration --- ground/gcs/src/plugins/config/inputchannelform.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ground/gcs/src/plugins/config/inputchannelform.cpp b/ground/gcs/src/plugins/config/inputchannelform.cpp index 962bb7006..3f5ed7956 100644 --- a/ground/gcs/src/plugins/config/inputchannelform.cpp +++ b/ground/gcs/src/plugins/config/inputchannelform.cpp @@ -161,6 +161,10 @@ void InputChannelForm::groupUpdated() case ManualControlSettings::CHANNELGROUPS_SRXL: count = 16; break; + case ManualControlSettings::CHANNELGROUPS_HOTTMAINPORT: + case ManualControlSettings::CHANNELGROUPS_HOTTFLEXIPORT: + count = 32; + break; case ManualControlSettings::CHANNELGROUPS_GCS: count = GCSReceiver::CHANNEL_NUMELEM; break; From 7a950503815c6ef7cd1715da330acd37a7849374 Mon Sep 17 00:00:00 2001 From: Fredrik Arvidsson Date: Sun, 20 Dec 2015 13:36:45 +0100 Subject: [PATCH 3/4] LP-104 Added missing code to receiver.c to detect receiver activity. This probably caused a crash on any activity of the HoTT receiver. Added 40 bytes to the receiver stack. Added options to receiver activity.xml uavo definition. --- flight/modules/Receiver/receiver.c | 6 ++++++ .../targets/boards/coptercontrol/firmware/inc/pios_config.h | 2 +- shared/uavobjectdefinition/receiveractivity.xml | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/flight/modules/Receiver/receiver.c b/flight/modules/Receiver/receiver.c index 4dfd26770..64436fa1e 100644 --- a/flight/modules/Receiver/receiver.c +++ b/flight/modules/Receiver/receiver.c @@ -658,6 +658,12 @@ static bool updateRcvrActivityCompare(uint32_t rcvr_id, struct rcvr_activity_fsm case MANUALCONTROLSETTINGS_CHANNELGROUPS_SBUS: group = RECEIVERACTIVITY_ACTIVEGROUP_SBUS; break; + case MANUALCONTROLSETTINGS_CHANNELGROUPS_HOTTMAINPORT: + group = RECEIVERACTIVITY_ACTIVEGROUP_HOTTMAINPORT; + break; + case MANUALCONTROLSETTINGS_CHANNELGROUPS_HOTTFLEXIPORT: + group = RECEIVERACTIVITY_ACTIVEGROUP_HOTTFLEXIPORT; + break; case MANUALCONTROLSETTINGS_CHANNELGROUPS_SRXL: group = RECEIVERACTIVITY_ACTIVEGROUP_SRXL; break; diff --git a/flight/targets/boards/coptercontrol/firmware/inc/pios_config.h b/flight/targets/boards/coptercontrol/firmware/inc/pios_config.h index 54b1d3039..3a62c81b4 100644 --- a/flight/targets/boards/coptercontrol/firmware/inc/pios_config.h +++ b/flight/targets/boards/coptercontrol/firmware/inc/pios_config.h @@ -166,7 +166,7 @@ /* Task stack sizes */ #define PIOS_ACTUATOR_STACK_SIZE 700 #define PIOS_MANUAL_STACK_SIZE 735 -#define PIOS_RECEIVER_STACK_SIZE 620 +#define PIOS_RECEIVER_STACK_SIZE 660 #define PIOS_STABILIZATION_STACK_SIZE 400 #ifdef DIAG_TASKS diff --git a/shared/uavobjectdefinition/receiveractivity.xml b/shared/uavobjectdefinition/receiveractivity.xml index 8724b3f51..33056be7a 100644 --- a/shared/uavobjectdefinition/receiveractivity.xml +++ b/shared/uavobjectdefinition/receiveractivity.xml @@ -2,7 +2,7 @@ Monitors which receiver channels have been active within the last second. From 5273df263c9673834b988becf3ff888df842df90 Mon Sep 17 00:00:00 2001 From: Fredrik Arvidsson Date: Sun, 20 Dec 2015 21:11:15 +0100 Subject: [PATCH 4/4] LP-104 Reverted stack size for receiver module after testing. --- flight/targets/boards/coptercontrol/firmware/inc/pios_config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flight/targets/boards/coptercontrol/firmware/inc/pios_config.h b/flight/targets/boards/coptercontrol/firmware/inc/pios_config.h index 3a62c81b4..54b1d3039 100644 --- a/flight/targets/boards/coptercontrol/firmware/inc/pios_config.h +++ b/flight/targets/boards/coptercontrol/firmware/inc/pios_config.h @@ -166,7 +166,7 @@ /* Task stack sizes */ #define PIOS_ACTUATOR_STACK_SIZE 700 #define PIOS_MANUAL_STACK_SIZE 735 -#define PIOS_RECEIVER_STACK_SIZE 660 +#define PIOS_RECEIVER_STACK_SIZE 620 #define PIOS_STABILIZATION_STACK_SIZE 400 #ifdef DIAG_TASKS