From fac694ce4bb4f40c65d334e4866e4b15b7228916 Mon Sep 17 00:00:00 2001 From: Dominic Clifton Date: Mon, 8 May 2017 19:19:59 +0100 Subject: [PATCH] Cherry-pick CF/fbb3f92 --- Makefile | 6 +- src/main/drivers/transponder_ir.c | 4 ++ src/main/drivers/transponder_ir.h | 32 +++++++++-- src/main/drivers/transponder_ir_erlt.c | 79 ++++++++++++++++++++++++++ src/main/drivers/transponder_ir_erlt.h | 21 +++++++ src/main/io/transponder_ir.c | 17 ++++-- src/main/io/transponder_ir.h | 9 +++ 7 files changed, 157 insertions(+), 11 deletions(-) create mode 100644 src/main/drivers/transponder_ir_erlt.c create mode 100644 src/main/drivers/transponder_ir_erlt.h diff --git a/Makefile b/Makefile index 0d0452beb..c39118a49 100644 --- a/Makefile +++ b/Makefile @@ -696,6 +696,9 @@ COMMON_SRC = \ drivers/system.c \ drivers/timer.c \ drivers/transponder_ir.c \ + drivers/transponder_ir_arcitimer.c \ + drivers/transponder_ir_ilap.c \ + drivers/transponder_ir_erlt.c \ fc/config.c \ fc/fc_dispatch.c \ fc/fc_hardfaults.c \ @@ -783,9 +786,6 @@ FC_SRC = \ drivers/serial_escserial.c \ drivers/sonar_hcsr04.c \ drivers/vtx_common.c \ - drivers/transponder_ir.c \ - drivers/transponder_ir_arcitimer.c \ - drivers/transponder_ir_ilap.c \ flight/navigation.c \ io/dashboard.c \ io/displayport_max7456.c \ diff --git a/src/main/drivers/transponder_ir.c b/src/main/drivers/transponder_ir.c index 6eca03232..e3e499d07 100644 --- a/src/main/drivers/transponder_ir.c +++ b/src/main/drivers/transponder_ir.c @@ -32,6 +32,7 @@ #include "transponder_ir.h" #include "drivers/transponder_ir_arcitimer.h" #include "drivers/transponder_ir_ilap.h" +#include "drivers/transponder_ir_erlt.h" volatile uint8_t transponderIrDataTransferInProgress = 0; @@ -172,6 +173,9 @@ bool transponderIrInit(const transponderProvider_e provider) case ILAP: transponderIrInitIlap(&transponder); break; + case TRANSPONDER_ERLT: + transponderIrInitERLT(&transponder); + break; default: return false; } diff --git a/src/main/drivers/transponder_ir.h b/src/main/drivers/transponder_ir.h index 0bfcdc0bf..7f4979e9f 100644 --- a/src/main/drivers/transponder_ir.h +++ b/src/main/drivers/transponder_ir.h @@ -28,6 +28,8 @@ #define TRANSPONDER_DMA_BUFFER_SIZE_ARCITIMER 155 * TRANSPONDER_TOGGLES_PER_BIT_ARCITIMER // 620 #define TRANSPONDER_TIMER_MHZ_ARCITIMER 24 #define TRANSPONDER_CARRIER_HZ_ARCITIMER 41886 +#define TRANSPONDER_TRANSMIT_DELAY_ARCITIMER 4500 +#define TRANSPONDER_TRANSMIT_JITTER_ARCITIMER 10000 /*** ******** ***/ @@ -36,12 +38,29 @@ #define TRANSPONDER_DATA_LENGTH_ILAP 6 #define TRANSPONDER_TOGGLES_PER_BIT_ILAP 11 #define TRANSPONDER_GAP_TOGGLES_ILAP 1 -#define TRANSPONDER_TOGGLES (TRANSPONDER_TOGGLES_PER_BIT_ILAP + TRANSPONDER_GAP_TOGGLES_ILAP) +#define TRANSPONDER_TOGGLES_ILAP (TRANSPONDER_TOGGLES_PER_BIT_ILAP + TRANSPONDER_GAP_TOGGLES_ILAP) #define TRANSPONDER_DMA_BUFFER_SIZE_ILAP ((TRANSPONDER_TOGGLES_PER_BIT_ILAP + 1) * TRANSPONDER_BITS_PER_BYTE_ILAP * TRANSPONDER_DATA_LENGTH_ILAP) //720 #define TRANSPONDER_TIMER_MHZ_ILAP 24 #define TRANSPONDER_CARRIER_HZ_ILAP 460750 +#define TRANSPONDER_TRANSMIT_DELAY_ILAP 4500 +#define TRANSPONDER_TRANSMIT_JITTER_ILAP 10000 /*** ******** ***/ + +/*** ERLT ***/ +#define TRANSPONDER_DATA_LENGTH_ERLT 1 + +#define ERLTBitQuiet 0 +#define ERLTCyclesForOneBit 25 +#define ERLTCyclesForZeroBit 10 +#define TRANSPONDER_DMA_BUFFER_SIZE_ERLT 200 // actually ERLT is variable length 91-196 depending on the ERLT id +#define TRANSPONDER_TIMER_MHZ_ERLT 18 +#define TRANSPONDER_CARRIER_HZ_ERLT 38000 +#define TRANSPONDER_TRANSMIT_DELAY_ERLT 22500 +#define TRANSPONDER_TRANSMIT_JITTER_ERLT 5000 +/*** ******** ***/ + + /* * Implementation note: * Using around over 700 bytes for a transponder DMA buffer is a little excessive, likely an alternative implementation that uses a fast @@ -55,6 +74,7 @@ typedef union transponderIrDMABuffer_s { uint8_t arcitimer[TRANSPONDER_DMA_BUFFER_SIZE_ARCITIMER]; // 620 uint8_t ilap[TRANSPONDER_DMA_BUFFER_SIZE_ILAP]; // 720 + uint8_t erlt[TRANSPONDER_DMA_BUFFER_SIZE_ERLT]; // 91-200 } transponderIrDMABuffer_t; #elif defined(STM32F4) @@ -62,6 +82,7 @@ typedef union transponderIrDMABuffer_s { uint32_t arcitimer[TRANSPONDER_DMA_BUFFER_SIZE_ARCITIMER]; // 620 uint32_t ilap[TRANSPONDER_DMA_BUFFER_SIZE_ILAP]; // 720 + uint32_t erlt[TRANSPONDER_DMA_BUFFER_SIZE_ERLT]; // 91-200 } transponderIrDMABuffer_t; #endif @@ -80,11 +101,14 @@ typedef struct transponder_s { } transponder_t; typedef enum { - NONE, - ARCITIMER, - ILAP + TRANSPONDER_NONE = 0, + TRANSPONDER_ILAP, + TRANSPONDER_ARCITIMER, + TRANSPONDER_ERLT } transponderProvider_e; +#define TRANSPONDER_PROVIDER_COUNT 3 + struct transponderVTable { void (*updateTransponderDMABuffer)(transponder_t *transponder, const uint8_t* transponderData); }; diff --git a/src/main/drivers/transponder_ir_erlt.c b/src/main/drivers/transponder_ir_erlt.c new file mode 100644 index 000000000..6b948fb94 --- /dev/null +++ b/src/main/drivers/transponder_ir_erlt.c @@ -0,0 +1,79 @@ +/* + * This file is part of Cleanflight. + * + * Cleanflight 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. + * + * Cleanflight 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 Cleanflight. If not, see . + */ +#include +#include +#include +#include +#include "drivers/transponder_ir.h" +#include "drivers/transponder_ir_erlt.h" + +#if defined(STM32F3) || defined(STM32F4) || defined(UNIT_TEST) + +static uint16_t dmaBufferOffset; +extern const struct transponderVTable erltTansponderVTable; + +void transponderIrInitERLT(transponder_t *transponder){ + transponder->dma_buffer_size = TRANSPONDER_DMA_BUFFER_SIZE_ERLT; + transponder->vTable = &erltTansponderVTable; + transponder->timer_hz = TRANSPONDER_TIMER_MHZ_ERLT; + transponder->timer_carrier_hz = TRANSPONDER_CARRIER_HZ_ERLT; + memset(&(transponder->transponderIrDMABuffer.erlt), 0, TRANSPONDER_DMA_BUFFER_SIZE_ERLT); +} + +void addBitToBuffer(transponder_t *transponder, uint8_t cycles, uint8_t pulsewidth) +{ + for (int i = 0; i < cycles; i++) { + transponder->transponderIrDMABuffer.erlt[dmaBufferOffset++] = pulsewidth; + } +} + +void updateTransponderDMABufferERLT(transponder_t *transponder, const uint8_t* transponderData) +{ + uint8_t byteToSend = ~(*transponderData); //transponderData is stored inverted, so invert before using + uint8_t paritysum = 0; //sum of one bits + + dmaBufferOffset = 0; //reset buffer count + + //start bit 1, always pulsed, bit value = 0 + addBitToBuffer(transponder, ERLTCyclesForZeroBit, transponder->bitToggleOne); + + //start bit 2, always not pulsed, bit value = 0 + addBitToBuffer(transponder, ERLTCyclesForZeroBit, ERLTBitQuiet); + + //add data bits, only the 6 LSB + for(int i = 5; i >= 0; i--) + { + uint8_t bv = (byteToSend >> i) & 0x01; + paritysum += bv; + addBitToBuffer(transponder, (bv ? ERLTCyclesForOneBit : ERLTCyclesForZeroBit), ((i % 2) ? transponder->bitToggleOne : ERLTBitQuiet)); + } + + //parity bit, always pulsed, bit value is zero if sum is even, one if odd + addBitToBuffer(transponder, ((paritysum % 2) ? ERLTCyclesForOneBit : ERLTCyclesForZeroBit), transponder->bitToggleOne); + + //add final zero after the pulsed parity bit to stop pulses until the next update + transponder->transponderIrDMABuffer.erlt[dmaBufferOffset++] = ERLTBitQuiet; + + //reset buffer size to that required by this ERLT id + transponder->dma_buffer_size = dmaBufferOffset; +} + +const struct transponderVTable erltTansponderVTable = { + updateTransponderDMABufferERLT, +}; + +#endif diff --git a/src/main/drivers/transponder_ir_erlt.h b/src/main/drivers/transponder_ir_erlt.h new file mode 100644 index 000000000..287305d82 --- /dev/null +++ b/src/main/drivers/transponder_ir_erlt.h @@ -0,0 +1,21 @@ +/* + * This file is part of Cleanflight. + * + * Cleanflight 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. + * + * Cleanflight 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 Cleanflight. If not, see . + */ +#pragma once + +void transponderIrInitERLT(transponder_t *transponder); +void updateTransponderDMABufferERLT(transponder_t *transponder, const uint8_t* transponderData); +void addBitToBuffer(transponder_t *transponder, uint8_t cycles, uint8_t pulsewidth); diff --git a/src/main/io/transponder_ir.c b/src/main/io/transponder_ir.c index 038419b17..dc29ad571 100644 --- a/src/main/io/transponder_ir.c +++ b/src/main/io/transponder_ir.c @@ -30,6 +30,7 @@ #include "config/parameter_group_ids.h" #include "drivers/transponder_ir.h" +#include "drivers/system.h" #include "drivers/usb_io.h" #include "fc/config.h" @@ -39,7 +40,7 @@ PG_REGISTER_WITH_RESET_TEMPLATE(transponderConfig_t, transponderConfig, PG_TRANSPONDER_CONFIG, 0); PG_RESET_TEMPLATE(transponderConfig_t, transponderConfig, - .provider = ILAP, + .provider = TRANSPONDER_ILAP, .reserved = 0, .data = { 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0x0, 0x0, 0x0 }, // Note, this is NOT a valid transponder code, it's just for testing production hardware ); @@ -53,6 +54,12 @@ static timeUs_t nextUpdateAtUs = 0; #define JITTER_DURATION_COUNT (sizeof(jitterDurations) / sizeof(uint8_t)) static uint8_t jitterDurations[] = {0,9,4,8,3,9,6,7,1,6,9,7,8,2,6}; +const transponderRequirement_t transponderRequirements[TRANSPONDER_PROVIDER_COUNT] = { + {TRANSPONDER_ILAP, TRANSPONDER_DATA_LENGTH_ILAP, TRANSPONDER_TRANSMIT_DELAY_ILAP, TRANSPONDER_TRANSMIT_JITTER_ILAP}, + {TRANSPONDER_ARCITIMER, TRANSPONDER_DATA_LENGTH_ARCITIMER, TRANSPONDER_TRANSMIT_DELAY_ARCITIMER, TRANSPONDER_TRANSMIT_JITTER_ARCITIMER}, + {TRANSPONDER_ERLT, TRANSPONDER_DATA_LENGTH_ERLT, TRANSPONDER_TRANSMIT_DELAY_ERLT, TRANSPONDER_TRANSMIT_JITTER_ERLT} +}; + void transponderUpdate(timeUs_t currentTimeUs) { static uint32_t jitterIndex = 0; @@ -66,13 +73,15 @@ void transponderUpdate(timeUs_t currentTimeUs) return; } - // TODO use a random number genenerator for random jitter? The idea here is to avoid multiple transmitters transmitting at the same time. - uint32_t jitter = (1000 * jitterDurations[jitterIndex++]); + uint8_t provider = transponderConfig()->provider; + + // TODO use a random number generator for random jitter? The idea here is to avoid multiple transmitters transmitting at the same time. + uint32_t jitter = (transponderRequirements[provider - 1].transmitJitter / 10 * jitterDurations[jitterIndex++]); if (jitterIndex >= JITTER_DURATION_COUNT) { jitterIndex = 0; } - nextUpdateAtUs = currentTimeUs + 4500 + jitter; + nextUpdateAtUs = currentTimeUs + transponderRequirements[provider - 1].transmitDelay + jitter; #ifdef REDUCE_TRANSPONDER_CURRENT_DRAW_WHEN_USB_CABLE_PRESENT // reduce current draw when USB cable is plugged in by decreasing the transponder transmit rate. diff --git a/src/main/io/transponder_ir.h b/src/main/io/transponder_ir.h index 4463648c7..155d78eb9 100644 --- a/src/main/io/transponder_ir.h +++ b/src/main/io/transponder_ir.h @@ -26,6 +26,15 @@ typedef struct transponderConfig_s { uint8_t data[9]; } transponderConfig_t; +typedef struct transponderRequirement_s { + uint8_t provider; // See transponderProvider_e + uint8_t dataLength; + uint16_t transmitDelay; + uint16_t transmitJitter; +} transponderRequirement_t; + +extern const transponderRequirement_t transponderRequirements[TRANSPONDER_PROVIDER_COUNT]; + PG_DECLARE(transponderConfig_t, transponderConfig); void transponderInit(void);