1
0
Fork 0
mirror of https://github.com/opentx/opentx.git synced 2025-07-24 16:55:20 +03:00

Merge branch 'next' into kilrah/antennaselection

Conflicts:
	radio/src/myeeprom.h
This commit is contained in:
Andre Bernet 2016-03-22 15:31:44 +04:00
commit 1efad1ac38
66 changed files with 1048 additions and 635 deletions

View file

@ -19,7 +19,7 @@ option(AUTOSOURCE "Automatic source detection in menus" ON)
option(AUTOSWITCH "Automatic switch detection in menus" ON)
option(JITTER_MEASURE "Enable ADC jitter measurement" OFF)
option(JITTER_FILTER "Enable ADC jitter filtering" ON)
option(WATCHDOG_DISABLED "Disable hardware Watchdog on Horus" ON) # TODO remove it when it's OK
option(WATCHDOG_DISABLED "Disable hardware Watchdog on Horus" OFF) # TODO remove it when it's OK
enable_language(ASM)
set(OPT s)
@ -441,6 +441,7 @@ if(CPU_FAMILY STREQUAL STM32)
foreach(FILE ${STM32USB_SRC})
set(FIRMWARE_SRC ${FIRMWARE_SRC} ${STM32USB_DIR}/${FILE})
endforeach()
set(SRC ${SRC} sbus.cpp)
endif()
if(ARCH STREQUAL ARM)
@ -510,7 +511,6 @@ if(ARCH STREQUAL ARM)
main_arm.cpp
tasks_arm.cpp
audio_arm.cpp
sbus.cpp
telemetry/telemetry.cpp
telemetry/frsky.cpp
telemetry/frsky_d_arm.cpp

View file

@ -498,11 +498,13 @@ int cliDebugVars(const char ** argv)
#if defined(PCBHORUS)
extern uint32_t ioMutexReq, ioMutexRel;
extern uint32_t sdReadRetries;
serialPrint("ioMutexReq=%d", ioMutexReq);
serialPrint("ioMutexRel=%d", ioMutexRel);
serialPrint("sdReadRetries=%d", sdReadRetries);
#elif defined(PCBTARANIS)
serialPrint("telemetryErrors=%d", telemetryErrors);
#endif
return 0;
}

View file

@ -150,49 +150,53 @@ enum CurveType {
#define MAX_POINTS 17
#if defined(PCBHORUS)
#define LEN_MODEL_NAME 15
#define LEN_TIMER_NAME 8
#define LEN_FLIGHT_MODE_NAME 10
#define LEN_BITMAP_NAME 10
#define LEN_EXPOMIX_NAME 6
#define LEN_CHANNEL_NAME 6
#define LEN_INPUT_NAME 4
#define LEN_CURVE_NAME 3
#define MAX_CURVES 32
#define NUM_POINTS 512
#define LEN_MODEL_NAME 15
#define LEN_TIMER_NAME 8
#define LEN_FLIGHT_MODE_NAME 10
#define LEN_BITMAP_NAME 10
#define LEN_EXPOMIX_NAME 6
#define LEN_CHANNEL_NAME 6
#define LEN_INPUT_NAME 4
#define LEN_CURVE_NAME 3
#define LEN_CFN_NAME 10
#define MAX_CURVES 32
#define NUM_POINTS 512
#elif defined(PCBFLAMENCO)
#define LEN_MODEL_NAME 12
#define LEN_TIMER_NAME 8
#define LEN_FLIGHT_MODE_NAME 10
#define LEN_EXPOMIX_NAME 6
#define LEN_CHANNEL_NAME 6
#define LEN_INPUT_NAME 4
#define LEN_CURVE_NAME 3
#define MAX_CURVES 32
#define NUM_POINTS 512
#define LEN_MODEL_NAME 12
#define LEN_TIMER_NAME 8
#define LEN_FLIGHT_MODE_NAME 10
#define LEN_EXPOMIX_NAME 6
#define LEN_CHANNEL_NAME 6
#define LEN_INPUT_NAME 4
#define LEN_CURVE_NAME 3
#define LEN_CFN_NAME 8
#define MAX_CURVES 32
#define NUM_POINTS 512
#elif defined(PCBTARANIS)
#define LEN_MODEL_NAME 12
#define LEN_TIMER_NAME 8
#define LEN_FLIGHT_MODE_NAME 10
#define LEN_BITMAP_NAME 10
#define LEN_EXPOMIX_NAME 8
#define LEN_CHANNEL_NAME 6
#define LEN_INPUT_NAME 4
#define LEN_CURVE_NAME 3
#define MAX_CURVES 32
#define NUM_POINTS 512
#define LEN_MODEL_NAME 12
#define LEN_TIMER_NAME 8
#define LEN_FLIGHT_MODE_NAME 10
#define LEN_BITMAP_NAME 10
#define LEN_EXPOMIX_NAME 8
#define LEN_CHANNEL_NAME 6
#define LEN_INPUT_NAME 4
#define LEN_CURVE_NAME 3
#define LEN_CFN_NAME 8
#define MAX_CURVES 32
#define NUM_POINTS 512
#elif defined(CPUARM)
#define LEN_MODEL_NAME 10
#define LEN_TIMER_NAME 3
#define LEN_FLIGHT_MODE_NAME 6
#define LEN_EXPOMIX_NAME 6
#define MAX_CURVES 16
#define NUM_POINTS 512
#define LEN_MODEL_NAME 10
#define LEN_TIMER_NAME 3
#define LEN_FLIGHT_MODE_NAME 6
#define LEN_EXPOMIX_NAME 6
#define LEN_CFN_NAME 6
#define MAX_CURVES 16
#define NUM_POINTS 512
#else
#define LEN_MODEL_NAME 10
#define LEN_FLIGHT_MODE_NAME 6
#define MAX_CURVES 8
#define NUM_POINTS (112-MAX_CURVES)
#define LEN_MODEL_NAME 10
#define LEN_FLIGHT_MODE_NAME 6
#define MAX_CURVES 8
#define NUM_POINTS (112-MAX_CURVES)
#endif
#if defined(PCBTARANIS) || defined(PCBSKY9X) || defined(PCBHORUS)
@ -265,6 +269,36 @@ enum BeeperMode {
e_mode_all
};
#if defined(PCBFLAMENCO)
enum ModuleIndex {
EXTERNAL_MODULE,
TRAINER_MODULE,
};
enum TrainerMode {
TRAINER_MODE_MASTER,
TRAINER_MODE_SLAVE
};
#elif defined(PCBTARANIS) || defined(PCBHORUS)
enum ModuleIndex {
INTERNAL_MODULE,
EXTERNAL_MODULE,
TRAINER_MODULE
};
enum TrainerMode {
TRAINER_MODE_MASTER_TRAINER_JACK,
TRAINER_MODE_SLAVE,
TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE,
TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE,
TRAINER_MODE_MASTER_BATTERY_COMPARTMENT,
};
#elif defined(PCBSKY9X)
enum ModuleIndex {
EXTERNAL_MODULE,
EXTRA_MODULE,
TRAINER_MODULE
};
#endif
enum UartModes {
#if defined(CLI) || defined(DEBUG)
UART_MODE_DEBUG,
@ -498,7 +532,7 @@ enum PotsWarnMode {
#define GVAR_MIN -GVAR_MAX
#endif
#define RESERVE_RANGE_FOR_GVARS 10
#define RESERVE_RANGE_FOR_GVARS 10
// even we do not spend space in EEPROM for 10 GVARS, we reserve the space inside the range of values, like offset, weight, etc.
#if defined(PCBSTD) && defined(GVARS)
@ -513,12 +547,6 @@ enum PotsWarnMode {
#endif
#endif
#if defined(PCBTARANIS)
#define LEN_CFN_NAME 8
#elif defined(CPUARM)
#define LEN_CFN_NAME 6
#endif
enum SwitchSources {
SWSRC_NONE = 0,

50
radio/src/definitions.h Normal file
View file

@ -0,0 +1,50 @@
/*
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* 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.
*/
#ifndef _DEFINITIONS_H_
#define _DEFINITIONS_H_
#if defined(SIMU)
#define __ALIGNED
#else
#define __ALIGNED __attribute__((aligned(32)))
#endif
#if defined(SIMU)
#define __DMA
#elif defined(STM32F4) && !defined(BOOT)
#define __DMA __attribute__((section(".ram"), aligned(32)))
#else
#define __DMA __ALIGNED
#endif
#if defined(PCBHORUS) && !defined(SIMU)
#define __SDRAM __attribute__((section(".sdram"), aligned(32)))
#else
#define __SDRAM __DMA
#endif
#if defined(SIMU) || defined(CPUARM) || GCC_VERSION < 472
typedef int32_t int24_t;
#else
typedef __int24 int24_t;
#endif
#endif // _DEFINITIONS_H_

77
radio/src/dmafifo.h Normal file
View file

@ -0,0 +1,77 @@
/*
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* 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.
*/
#ifndef _DMA_FIFO_H_
#define _DMA_FIFO_H_
#include "definitions.h"
template <int N>
class DMAFifo
{
public:
DMAFifo(DMA_Stream_TypeDef * stream):
stream(stream),
ridx(0)
{
}
void clear()
{
ridx = 0;
}
uint32_t size()
{
return N;
}
bool isEmpty()
{
#if defined(SIMU)
return true;
#endif
return (ridx == N - stream->NDTR);
}
bool pop(uint8_t & element)
{
if (isEmpty()) {
return false;
}
else {
element = fifo[ridx];
ridx = (ridx+1) & (N-1);
return true;
}
}
uint8_t * buffer()
{
return fifo;
}
protected:
uint8_t fifo[N];
DMA_Stream_TypeDef * stream;
volatile uint32_t ridx;
};
#endif // _DMA_FIFO_H_

View file

@ -2,7 +2,7 @@
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
@ -36,7 +36,8 @@ class Fifo
widx = ridx = 0;
}
void push(T element) {
void push(T element)
{
uint32_t next = (widx+1) & (N-1);
if (next != ridx) {
fifo[widx] = element;
@ -44,7 +45,8 @@ class Fifo
}
}
bool pop(T & element) {
bool pop(T & element)
{
if (isEmpty()) {
return false;
}
@ -55,16 +57,19 @@ class Fifo
}
}
bool isEmpty() {
bool isEmpty()
{
return (ridx == widx);
}
bool isFull() {
bool isFull()
{
uint32_t next = (widx+1) & (N-1);
return (next == ridx);
}
void flush() {
void flush()
{
while (!isEmpty()) {};
}

View file

@ -2,7 +2,7 @@
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
@ -157,7 +157,7 @@ bool isSourceAvailable(int source)
if (source>=MIXSRC_FIRST_SWITCH && source<=MIXSRC_LAST_SWITCH) {
return SWITCH_EXISTS(source-MIXSRC_FIRST_SWITCH);
}
#if !defined(HELI)
if (source>=MIXSRC_CYC1 && source<=MIXSRC_CYC3)
return false;
@ -227,7 +227,7 @@ bool isInputSourceAvailable(int source)
if (source>=MIXSRC_FIRST_SWITCH && source<=MIXSRC_LAST_SWITCH)
return SWITCH_EXISTS(source-MIXSRC_FIRST_SWITCH);
if (source>=MIXSRC_FIRST_CH && source<=MIXSRC_LAST_CH)
return true;
@ -470,6 +470,16 @@ bool isRfProtocolAvailable(int protocol)
return true;
}
#if defined(PCBHORUS) || defined(PCBTARANIS)
bool isTrainerModeAvailable(int mode)
{
if (IS_EXTERNAL_MODULE_PRESENT() && (mode == TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE || mode == TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE))
return false;
else
return true;
}
#endif
bool modelHasNotes()
{
char filename[sizeof(MODELS_PATH)+1+sizeof(g_model.header.name)+sizeof(TEXT_EXT)] = MODELS_PATH "/";

View file

@ -46,6 +46,7 @@ bool isSwitchAvailableInMixes(int swtch);
bool isSwitchAvailableInTimers(int swtch);
bool isModuleAvailable(int module);
bool isRfProtocolAvailable(int protocol);
bool isTrainerModeAvailable(int mode);
bool isSensorUnit(int sensor, uint8_t unit);
bool isCellsSensor(int sensor);

View file

@ -274,9 +274,9 @@ void BitmapBuffer::drawSizedText(coord_t x, coord_t y, const pm_char * s, uint8_
if (FONTSIZE(flags) == TINSIZE)
drawSolidFilledRect(x-INVERT_HORZ_MARGIN+2, y-INVERT_VERT_MARGIN+2, width+2*INVERT_HORZ_MARGIN-5, INVERT_LINE_HEIGHT-7, TEXT_INVERTED_BGCOLOR);
else if (FONTSIZE(flags) == SMLSIZE)
drawSolidFilledRect(x-INVERT_HORZ_MARGIN+1, y-INVERT_VERT_MARGIN, width+2*INVERT_HORZ_MARGIN-2, INVERT_LINE_HEIGHT, TEXT_INVERTED_BGCOLOR);
drawSolidFilledRect(x-INVERT_HORZ_MARGIN, y+1, width+2*INVERT_HORZ_MARGIN-2, INVERT_LINE_HEIGHT-5, TEXT_INVERTED_BGCOLOR);
else
drawSolidFilledRect(x-INVERT_HORZ_MARGIN, y/*-INVERT_VERT_MARGIN*/, width+2*INVERT_HORZ_MARGIN, INVERT_LINE_HEIGHT, TEXT_INVERTED_BGCOLOR);
drawSolidFilledRect(x-INVERT_HORZ_MARGIN, y, width+2*INVERT_HORZ_MARGIN, INVERT_LINE_HEIGHT, TEXT_INVERTED_BGCOLOR);
}
char str[256];

View file

@ -96,10 +96,15 @@ const uint8_t LBM_STATS_DEBUG_ICON[] = {
#include "mask_stats_debug.lbm"
};
const uint8_t LBM_STATS_ANALOGS_ICON[] = {
#include "mask_analogs.lbm"
};
const uint8_t * const LBM_STATS_ICONS[] = {
LBM_STATS_ICON,
LBM_STATS_GRAPH_ICON,
LBM_STATS_TIME_ICON,
LBM_STATS_ANALOGS_ICON,
#if defined(DEBUG_TRACE_BUFFER)
LBM_STATS_DEBUG_ICON
#endif

View file

@ -51,6 +51,7 @@ extern const uint8_t LBM_MIXER_ICON[];
extern const uint8_t LBM_CURVES_ICON[];
extern const uint8_t LBM_LUA_SCRIPTS_ICON[];
extern const uint8_t LBM_TELEMETRY_ICON[];
extern const uint8_t LBM_STATS_ANALOGS_ICON[];
// UI (theme / layout / widgets bitmaps
extern const uint8_t LBM_MAINVIEWS_ICON[];

View file

@ -20,7 +20,7 @@
#include <math.h>
#include <stdio.h>
#include "../../opentx.h"
#include "opentx.h"
#if defined(SIMU)
display_t displayBuf[DISPLAY_BUFFER_SIZE];

View file

@ -46,6 +46,7 @@ enum menuGeneralHwItems {
ITEM_SETUP_HW_SH,
ITEM_SETUP_HW_BLUETOOTH,
// ITEM_SETUP_HW_UART3_MODE,
ITEM_SETUP_HW_BAT_CAL,
ITEM_SETUP_HW_MAX
};
@ -175,6 +176,12 @@ bool menuGeneralHardware(evt_t event)
}
break;
#endif
case ITEM_SETUP_HW_BAT_CAL:
lcdDrawText(MENUS_MARGIN_LEFT, y, "Battery cal.");
lcdDrawNumber(HW_SETTINGS_COLUMN, y, getBatteryVoltage(), attr|LEFT|PREC2, 0, NULL, "V");
if (attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.txVoltageCalibration, -127, 127);
break;
}
}

View file

@ -329,7 +329,7 @@ bool menuGeneralSetup(evt_t event)
case ITEM_SETUP_BATTERY_WARNING:
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_BATTERYWARNING);
putsValueWithUnit(RADIO_SETUP_2ND_COLUMN, y, g_eeGeneral.vBatWarn, UNIT_VOLTS, attr|PREC1|LEFT);
if (attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.vBatWarn, 27, 42); // 2.7-4.2V
if (attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.vBatWarn, 40, 120); //4-12V
break;
#if 0

View file

@ -19,7 +19,7 @@
*/
#include <stdio.h>
#include "../../opentx.h"
#include "opentx.h"
uint8_t s_curveChan;

View file

@ -18,12 +18,12 @@
* GNU General Public License for more details.
*/
#include "../../opentx.h"
#include "opentx.h"
#define MODEL_CUSTOM_FUNC_1ST_COLUMN 50
#define MODEL_CUSTOM_FUNC_2ND_COLUMN 100
#define MODEL_CUSTOM_FUNC_2ND_COLUMN_EXT 180
#define MODEL_CUSTOM_FUNC_3RD_COLUMN 300
#define MODEL_CUSTOM_FUNC_1ST_COLUMN 60
#define MODEL_CUSTOM_FUNC_2ND_COLUMN 120
#define MODEL_CUSTOM_FUNC_2ND_COLUMN_EXT (lcdNextPos + 5)
#define MODEL_CUSTOM_FUNC_3RD_COLUMN 295
#define MODEL_CUSTOM_FUNC_4TH_COLUMN 440
#define MODEL_CUSTOM_FUNC_4TH_COLUMN_ONOFF 450

View file

@ -2,7 +2,7 @@
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
@ -19,7 +19,7 @@
*/
#include <stdio.h>
#include "../../opentx.h"
#include "opentx.h"
enum LogicalSwitchFields {
LS_FIELD_FUNCTION,
@ -33,28 +33,25 @@ enum LogicalSwitchFields {
LS_FIELD_LAST = LS_FIELD_COUNT-1
};
#define CSW_1ST_COLUMN 42
#define CSW_2ND_COLUMN 90
#define CSW_3RD_COLUMN 140
#define CSW_4TH_COLUMN 200
#define CSW_5TH_COLUMN 245
#define CSW_6TH_COLUMN 300
#define CSW_1ST_COLUMN 50
#define CSW_2ND_COLUMN 120
#define CSW_3RD_COLUMN 200
#define CSW_4TH_COLUMN 280
#define CSW_5TH_COLUMN 340
#define CSW_6TH_COLUMN 390
void putsEdgeDelayParam(coord_t x, coord_t y, LogicalSwitchData *cs, uint8_t lattr, uint8_t rattr)
{
char s[32];
div_t left = div(lswTimerValue(cs->v2), 10);
char sleft[10];
sprintf(sleft, "%d.%d", left.quot, left.rem);
div_t right = div(lswTimerValue(cs->v2+cs->v3), 10);
char sright[10];
sprintf(sright, "%d.%d", right.quot, right.rem);
sprintf(s, "[%s:%s]", sleft, sright);
lcdDrawText(x-4, y, s);
/* if (cs->v3 < 0)
lcdDrawText(lcdLastPos+3, y, "<<", rattr);
lcdDrawChar(x, y, '[');
lcdDrawNumber(lcdNextPos+3, y, lswTimerValue(cs->v2), LEFT|PREC1|lattr);
lcdDrawChar(lcdNextPos+3, y, ':');
if (cs->v3 < 0)
lcdDrawText(lcdNextPos+3, y, "<<", rattr);
else if (cs->v3 == 0)
lcdDrawText(lcdLastPos+3, y, "--", rattr); */
lcdDrawText(lcdNextPos+3, y, "--", rattr);
else
lcdDrawNumber(lcdNextPos+3, y, lswTimerValue(cs->v2+cs->v3), LEFT|PREC1|rattr);
lcdDrawChar(lcdNextPos+3, y, ']');
}
void onLogicalSwitchesMenu(const char *result)
@ -173,7 +170,7 @@ bool menuModelLogicalSwitches(evt_t event)
INCDEC_ENABLE_CHECK(NULL);
}
v2_max = getMaximumValue(v1_val);
v2_min = - v2_min;
v2_min = - v2_max;
putsChannelValue(CSW_3RD_COLUMN, y, v1_val, v1_val <= MIXSRC_LAST_CH ? calc100toRESX(cs->v2) : cs->v2, LEFT|attr2);
}

View file

@ -730,88 +730,114 @@ bool menuModelSetup(evt_t event)
bool menuModelFailsafe(evt_t event)
{
static bool longNames = false;
bool newLongNames = false;
uint8_t ch = 0;
uint8_t channelStart = g_model.moduleData[g_moduleIdx].channelsStart;
if (event == EVT_KEY_LONG(KEY_ENTER) && s_editMode) {
START_NO_HIGHLIGHT();
g_model.moduleData[g_moduleIdx].failsafeChannels[menuVerticalPosition] = channelOutputs[menuVerticalPosition];
storageDirty(EE_MODEL);
AUDIO_WARNING1();
SEND_FAILSAFE_NOW(g_moduleIdx);
if (event == EVT_KEY_LONG(KEY_ENTER)) {
killEvents(event);
event = 0;
if (s_editMode) {
g_model.moduleData[g_moduleIdx].failsafeChannels[menuVerticalPosition] = channelOutputs[menuVerticalPosition+channelStart];
storageDirty(EE_MODEL);
AUDIO_WARNING1();
s_editMode = 0;
SEND_FAILSAFE_NOW(g_moduleIdx);
}
else {
int16_t & failsafe = g_model.moduleData[g_moduleIdx].failsafeChannels[menuVerticalPosition];
if (failsafe < FAILSAFE_CHANNEL_HOLD)
failsafe = FAILSAFE_CHANNEL_HOLD;
else if (failsafe == FAILSAFE_CHANNEL_HOLD)
failsafe = FAILSAFE_CHANNEL_NOPULSE;
else
failsafe = 0;
storageDirty(EE_MODEL);
AUDIO_WARNING1();
SEND_FAILSAFE_NOW(g_moduleIdx);
}
}
SIMPLE_SUBMENU_NOTITLE(NUM_CHNOUT);
SIMPLE_SUBMENU_WITH_OPTIONS("FAILSAFE", LBM_STATS_ANALOGS_ICON, NUM_CHANNELS(g_moduleIdx), OPTION_MENU_NO_SCROLLBAR);
drawStringWithIndex(50, 3+FH, "Module", g_moduleIdx+1, MENU_TITLE_COLOR);
#define COL_W (LCD_W/2)
const uint8_t SLIDER_W = 64;
// Column separator
// TODO lcdDrawSolidVerticalLine(LCD_W/2, FH, LCD_H-FH);
const uint8_t SLIDER_W = 128;
if (menuVerticalPosition >= 16) {
ch = 16;
}
unsigned int lim = g_model.extendedLimits ? 640*2 : 512*2;
// TODO lcd_putsCenter(0, FAILSAFESET);
// TODO lcdInvertLine(0);
for (uint8_t col=0; col<2; col++) {
for (uint8_t line=0; line<8; line++) {
coord_t x = col*(LCD_W/2);
coord_t y = MENU_CONTENT_TOP - FH + line*(FH+4);
int32_t channelValue = channelOutputs[ch+channelStart];
int32_t failsafeValue = 0;
bool failsafeEditable = false;
for (int col=0; col<2; col++) {
coord_t x = col*COL_W+1;
// Channels
for (int line=0; line<8; line++) {
coord_t y = 9+line*7;
int32_t val;
int ofs = (col ? 0 : 1);
if (ch < g_model.moduleData[g_moduleIdx].channelsStart || ch >= NUM_CHANNELS(g_moduleIdx) + g_model.moduleData[g_moduleIdx].channelsStart)
val = 0;
else if (s_editMode && menuVerticalPosition == ch)
val = channelOutputs[ch];
else
val = g_model.moduleData[g_moduleIdx].failsafeChannels[8*col+line];
// Channel name if present, number if not
uint8_t lenLabel = ZLEN(g_model.limitData[ch].name);
if (lenLabel > 4) {
newLongNames = longNames = true;
if (ch < NUM_CHANNELS(g_moduleIdx)) {
failsafeValue = g_model.moduleData[g_moduleIdx].failsafeChannels[8*col+line];
failsafeEditable = true;
}
if (lenLabel > 0)
lcdDrawSizedText(x+1-ofs, y, g_model.limitData[ch].name, sizeof(g_model.limitData[ch].name), ZCHAR | SMLSIZE);
else
putsChn(x+1-ofs, y, ch+1, SMLSIZE);
if (failsafeEditable) {
// Channel name if present, number if not
uint8_t lenLabel = ZLEN(g_model.limitData[ch+channelStart].name);
if (lenLabel > 0) {
putsChn(x+MENUS_MARGIN_LEFT, y-3, ch+1, TINSIZE);
lcdDrawSizedText(x+MENUS_MARGIN_LEFT, y+5, g_model.limitData[ch+channelStart].name, sizeof(g_model.limitData[ch+channelStart].name), ZCHAR|SMLSIZE);
}
else {
putsChn(x+MENUS_MARGIN_LEFT, y, ch+1, 0);
}
// Value
LcdFlags flags = TINSIZE;
if (menuVerticalPosition == ch && !NO_HIGHLIGHT()) {
flags |= INVERS;
if (s_editMode)
flags |= BLINK;
}
// Value
LcdFlags flags = RIGHT;
if (menuVerticalPosition == ch) {
flags |= INVERS;
if (s_editMode) {
if (failsafeValue == FAILSAFE_CHANNEL_HOLD || failsafeValue == FAILSAFE_CHANNEL_NOPULSE) {
s_editMode = 0;
}
else {
flags |= BLINK;
CHECK_INCDEC_MODELVAR(event, g_model.moduleData[g_moduleIdx].failsafeChannels[8*col+line], -lim, +lim);
}
}
}
x += COL_W-4-MENUS_MARGIN_LEFT-SLIDER_W;
if (failsafeValue == FAILSAFE_CHANNEL_HOLD) {
lcdDrawText(x, y+2, "HOLD", flags|SMLSIZE);
failsafeValue = 0;
}
else if (failsafeValue == FAILSAFE_CHANNEL_NOPULSE) {
lcdDrawText(x, y+2, "NONE", flags|SMLSIZE);
failsafeValue = 0;
}
else {
#if defined(PPM_UNIT_US)
uint8_t wbar = (longNames ? SLIDER_W-10 : SLIDER_W);
lcdDrawNumber(x+COL_W-4-wbar-ofs, y, PPM_CH_CENTER(ch)+val/2, flags|RIGHT);
lcdDrawNumber(x, y, PPM_CH_CENTER(ch)+failsafeValue/2, flags);
#elif defined(PPM_UNIT_PERCENT_PREC1)
uint8_t wbar = (longNames ? SLIDER_W-16 : SLIDER_W-6);
lcdDrawNumber(x+COL_W-4-wbar-ofs, y, calcRESXto1000(val), PREC1|flags|RIGHT);
lcdDrawNumber(x, y, calcRESXto1000(failsafeValue), PREC1|flags);
#else
uint8_t wbar = (longNames ? SLIDER_W-10 : SLIDER_W);
lcdDrawNumber(x+COL_W-4-wbar-ofs, y, calcRESXto1000(val)/10, flags|RIGHT);
lcdDrawNumber(x, y, calcRESXto1000(failsafeValue)/10, flags);
#endif
}
// Gauge
lcdDrawRect(x+COL_W-3-wbar-ofs, y, wbar+1, 6);
uint16_t lim = g_model.extendedLimits ? 640*2 : 512*2;
uint8_t len = limit((uint8_t)1, uint8_t((abs(val) * wbar/2 + lim/2) / lim), uint8_t(wbar/2));
coord_t x0 = (val>0) ? x+COL_W-ofs-3-wbar/2 : x+COL_W-ofs-2-wbar/2-len;
lcdDrawSolidFilledRect(x0, y+1, len, 4, LINE_COLOR);
// Gauge
x += 4;
lcdDrawRect(x, y+3, SLIDER_W+1, 12);
unsigned int lenChannel = limit((uint8_t)1, uint8_t((abs(channelValue) * SLIDER_W/2 + lim/2) / lim), uint8_t(SLIDER_W/2));
unsigned int lenFailsafe = limit((uint8_t)1, uint8_t((abs(failsafeValue) * SLIDER_W/2 + lim/2) / lim), uint8_t(SLIDER_W/2));
x += SLIDER_W/2;
coord_t xChannel = (channelValue>0) ? x : x+1-lenChannel;
coord_t xFailsafe = (failsafeValue>0) ? x : x+1-lenFailsafe;
lcdDrawSolidFilledRect(xChannel, y+4, lenChannel, 5, TEXT_COLOR);
lcdDrawSolidFilledRect(xFailsafe, y+9, lenFailsafe, 5, ALARM_COLOR);
}
ch++;
}
}
longNames = newLongNames;
return true;
}

View file

@ -18,7 +18,7 @@
* GNU General Public License for more details.
*/
#include "../../opentx.h"
#include "opentx.h"
enum menuModelTelemetryItems {
ITEM_TELEMETRY_PROTOCOL_TYPE,

View file

@ -18,7 +18,7 @@
* GNU General Public License for more details.
*/
#include "../../opentx.h"
#include "opentx.h"
MenuHandlerFunc menuHandlers[5];
evt_t menuEvent = 0;

View file

@ -148,6 +148,7 @@ enum EnumTabDiag
{
e_StatsGraph,
e_StatsDebug,
e_StatsAnalogs,
#if defined(DEBUG_TRACE_BUFFER)
e_StatsTraces,
#endif
@ -155,11 +156,13 @@ enum EnumTabDiag
bool menuStatsGraph(evt_t event);
bool menuStatsDebug(evt_t event);
bool menuStatsAnalogs(evt_t event);
bool menuStatsTraces(evt_t event);
static const MenuHandlerFunc menuTabStats[] PROGMEM = {
menuStatsGraph,
menuStatsDebug,
menuStatsAnalogs,
#if defined(DEBUG_TRACE_BUFFER)
menuStatsTraces,
#endif
@ -316,13 +319,14 @@ bool check_submenu_simple(check_event_t event, uint8_t maxrow);
if (!check(event, 0, NULL, 0, mstate_tab, DIM(mstate_tab)-1, lines_count)) return false; \
drawScreenTemplate(title, icon, options);
#define SIMPLE_SUBMENU_NOTITLE(lines_count) \
if (!check_submenu_simple(event, lines_count)) return false
#define SIMPLE_SUBMENU(title, icon, lines_count) \
SIMPLE_SUBMENU_NOTITLE(lines_count); \
if (!check_submenu_simple(event, lines_count)) return false; \
drawScreenTemplate(title, icon)
#define SIMPLE_SUBMENU_WITH_OPTIONS(title, icon, lines_count, options) \
if (!check_submenu_simple(event, lines_count)) return false; \
drawScreenTemplate(title, icon, options)
typedef int select_menu_value_t;
select_menu_value_t selectMenuItem(coord_t x, coord_t y, const pm_char * values, select_menu_value_t value, select_menu_value_t min, select_menu_value_t max, LcdFlags attr, evt_t event);

View file

@ -47,18 +47,18 @@ bool menuStatsGraph(evt_t event)
putsTimer(MENU_STATS_COLUMN3, MENU_CONTENT_TOP, g_eeGeneral.globalTimer+sessionTimer, TIMEHOUR);
lcdDrawText(MENUS_MARGIN_LEFT, MENU_CONTENT_TOP+FH, "Throttle");
putsTimer(MENU_STATS_COLUMN1, MENU_CONTENT_TOP+FH, s_timeCumThr);
lcdDrawText(MENU_STATS_COLUMN2, MENU_CONTENT_TOP+FH, "Throttle %");
putsTimer(MENU_STATS_COLUMN3, MENU_CONTENT_TOP+FH, s_timeCum16ThrP/16);
putsTimer(MENU_STATS_COLUMN1, MENU_CONTENT_TOP+FH, s_timeCumThr, TIMEHOUR);
lcdDrawText(MENU_STATS_COLUMN2, MENU_CONTENT_TOP+FH, "Throttle %", TIMEHOUR);
putsTimer(MENU_STATS_COLUMN3, MENU_CONTENT_TOP+FH, s_timeCum16ThrP/16, TIMEHOUR);
lcdDrawText(MENUS_MARGIN_LEFT, MENU_CONTENT_TOP+2*FH, "Timers");
lcdDrawText(MENU_STATS_COLUMN1, MENU_CONTENT_TOP+2*FH, "[1]", HEADER_COLOR);
putsTimer(lcdNextPos+5, MENU_CONTENT_TOP+2*FH, timersStates[0].val);
putsTimer(lcdNextPos+5, MENU_CONTENT_TOP+2*FH, timersStates[0].val, TIMEHOUR);
lcdDrawText(MENU_STATS_COLUMN2, MENU_CONTENT_TOP+2*FH, "[2]", HEADER_COLOR);
putsTimer(lcdNextPos+10, MENU_CONTENT_TOP+2*FH, timersStates[1].val);
putsTimer(lcdNextPos+5, MENU_CONTENT_TOP+2*FH, timersStates[1].val, TIMEHOUR);
#if TIMERS > 2
lcdDrawText(MENU_STATS_COLUMN3, MENU_CONTENT_TOP+2*FH, "[3]", HEADER_COLOR);
putsTimer(lcdNextPos+10, MENU_CONTENT_TOP+2*FH, timersStates[2].val);
putsTimer(lcdNextPos+5, MENU_CONTENT_TOP+2*FH, timersStates[2].val, TIMEHOUR);
#endif
const coord_t x = 10;
@ -129,10 +129,10 @@ bool menuStatsDebug(evt_t event)
#if defined(LUA)
lcdDrawText(MENUS_MARGIN_LEFT, MENU_CONTENT_TOP+3*FH, "Lua duration");
lcdDrawNumber(MENU_STATS_COLUMN1, MENU_CONTENT_TOP+4*FH, 10*maxLuaDuration, LEFT, 0, NULL, "ms");
lcdDrawNumber(MENU_STATS_COLUMN1, MENU_CONTENT_TOP+3*FH, 10*maxLuaDuration, LEFT, 0, NULL, "ms");
lcdDrawText(MENUS_MARGIN_LEFT, MENU_CONTENT_TOP+4*FH, "Lua interval");
lcdDrawNumber(MENU_STATS_COLUMN1, MENU_CONTENT_TOP+5*FH, 10*maxLuaInterval, LEFT, 0, NULL, "ms");
lcdDrawNumber(MENU_STATS_COLUMN1, MENU_CONTENT_TOP+4*FH, 10*maxLuaInterval, LEFT, 0, NULL, "ms");
#endif
lcdDrawText(LCD_W/2, MENU_FOOTER_TOP+2, STR_MENUTORESET, CENTERED);
@ -140,6 +140,28 @@ bool menuStatsDebug(evt_t event)
return true;
}
bool menuStatsAnalogs(evt_t event)
{
MENU("Analogs", LBM_STATS_ICONS, menuTabStats, e_StatsAnalogs, 0, { 0 });
for (int i=0; i<NUM_STICKS+NUM_POTS; i++) {
coord_t y = MENU_CONTENT_TOP + (i/2)*FH;
coord_t x = MENUS_MARGIN_LEFT + (i & 1 ? LCD_W/2 : 0);
lcdDrawNumber(x, y, i+1, LEADING0|LEFT, 2, NULL, ":");
lcdDrawHexNumber(x+40, y, anaIn(i));
#if defined(JITTER_MEASURE)
lcdDrawNumber(x+100, y, rawJitter[i].get());
lcdDrawNumber(x+140, y, avgJitter[i].get());
lcdDrawNumber(x+180, y, (int16_t)calibratedStick[CONVERT_MODE(i)]*25/256);
#else
lcdDrawNumber(x+100, y, (int16_t)calibratedStick[CONVERT_MODE(i)]*25/256);
#endif
}
return true;
}
#if defined(DEBUG_TRACE_BUFFER)
#define STATS_TRACES_INDEX_POS MENUS_MARGIN_LEFT
#define STATS_TRACES_TIME_POS MENUS_MARGIN_LEFT + 4*10

View file

@ -257,7 +257,7 @@ void drawVerticalSlider(coord_t x, coord_t y, int len, int val, int min, int max
}
} */
}
y += len - (val - min) * len / (max - min) - 5;
y += len - divRoundClosest(len * (val - min), max - min) - 5;
if (options & OPTION_SLIDER_TRIM_BUTTON) {
drawVerticalTrimPosition(x, y - 2, val);
}
@ -272,7 +272,7 @@ void drawVerticalSlider(coord_t x, coord_t y, int len, int val, int min, int max
void drawHorizontalSlider(coord_t x, coord_t y, int len, int val, int min, int max, uint8_t steps, uint32_t options)
{
int w = (val - min) * len / (max - min);
int w = divRoundClosest(len * (val - min), max - min);
if (options & OPTION_SLIDER_TICKS) {
if (steps) {
int delta = len / steps;

View file

@ -66,9 +66,11 @@ class ModelBitmapWidget: public Widget
virtual void refresh()
{
if (memcmp(bitmapFilename, g_model.header.bitmap, sizeof(g_model.header.bitmap)) != 0) {
if (memcmp(bitmapFilename, g_model.header.bitmap, sizeof(g_model.header.bitmap)) != 0 ||
memcmp(modelName, g_model.header.name, sizeof(g_model.header.name)) != 0) {
refreshBuffer();
memcpy(bitmapFilename, g_model.header.bitmap, sizeof(g_model.header.bitmap));
memcpy(modelName, g_model.header.name, sizeof(g_model.header.name));
}
if (buffer) {
@ -78,6 +80,7 @@ class ModelBitmapWidget: public Widget
protected:
char bitmapFilename[sizeof(g_model.header.bitmap)];
char modelName[sizeof(g_model.header.name)];
BitmapBuffer * buffer;
};

View file

@ -55,7 +55,12 @@ void TimerWidget::refresh()
else {
lcdDrawBitmapPattern(zone.x + 3, zone.y + 4, LBM_TIMER, MAINVIEW_GRAPHICS_COLOR);
}
putsTimer(zone.x + 76, zone.y + 31, abs(timerState.val), TEXT_COLOR | DBLSIZE | LEFT);
if (abs(timerState.val) >= 3600) {
putsTimer(zone.x + 70, zone.y + 31, abs(timerState.val), TEXT_COLOR | MIDSIZE | LEFT | TIMEHOUR);
}
else {
putsTimer(zone.x + 76, zone.y + 31, abs(timerState.val), TEXT_COLOR | DBLSIZE | LEFT);
}
if (ZLEN(timerData.name) > 0) {
lcdDrawSizedText(zone.x + 78, zone.y + 20, timerData.name, LEN_TIMER_NAME, ZCHAR | SMLSIZE | TEXT_COLOR);
}
@ -64,10 +69,20 @@ void TimerWidget::refresh()
else {
drawStringWithIndex(zone.x, zone.y, "TMR", index + 1, SMLSIZE | TEXT_INVERTED_COLOR);
if (zone.w > 100 && zone.h > 40) {
putsTimer(zone.x, zone.y + 16, abs(timerState.val), TEXT_INVERTED_COLOR | LEFT | MIDSIZE);
if (abs(timerState.val) >= 3600) {
putsTimer(zone.x, zone.y + 16, abs(timerState.val), TEXT_INVERTED_COLOR | LEFT | TIMEHOUR);
}
else {
putsTimer(zone.x, zone.y + 16, abs(timerState.val), TEXT_INVERTED_COLOR | LEFT | MIDSIZE);
}
}
else {
putsTimer(zone.x, zone.y + 14, abs(timerState.val), TEXT_INVERTED_COLOR | LEFT);
if (abs(timerState.val) >= 3600) {
putsTimer(zone.x, zone.y + 14, abs(timerState.val), TEXT_INVERTED_COLOR | LEFT | SMLSIZE | TIMEHOUR);
}
else {
putsTimer(zone.x, zone.y + 14, abs(timerState.val), TEXT_INVERTED_COLOR | LEFT);
}
}
}
}

View file

@ -295,11 +295,6 @@ void lcdDrawHexNumber(coord_t x, coord_t y, uint32_t val, LcdFlags flags)
}
}
void lcdDraw8bitsNumber(coord_t x, coord_t y, int8_t val)
{
lcdDrawNumber(x, y, val);
}
void lcdDrawNumber(coord_t x, coord_t y, int32_t val, LcdFlags flags)
{
lcdDrawNumber(x, y, val, flags, 0);

View file

@ -140,7 +140,6 @@ void lcdDrawHexNumber(coord_t x, coord_t y, uint32_t val, LcdFlags mode=0);
void lcdDrawNumber(coord_t x, coord_t y, int32_t val, LcdFlags mode, uint8_t len);
void lcdDrawNumber(coord_t x, coord_t y, int32_t val, LcdFlags mode=0);
void lcdDraw8bitsNumber(coord_t x, coord_t y, int8_t val);
void drawStringWithIndex(coord_t x, coord_t y, const pm_char *str, uint8_t idx, LcdFlags att=0);
void putsModelName(coord_t x, coord_t y, char *name, uint8_t id, LcdFlags att);

View file

@ -35,18 +35,13 @@ void menuGeneralDiagAna(uint8_t event)
#if defined(JITTER_MEASURE)
lcdDrawNumber(x+10*FW-1, y, rawJitter[i].get());
lcdDrawNumber(x+13*FW-1, y, avgJitter[i].get());
lcdDraw8bitsNumber(x+17*FW-1, y, (int16_t)calibratedStick[CONVERT_MODE(i)]*25/256);
lcdDrawNumber(x+17*FW-1, y, (int16_t)calibratedStick[CONVERT_MODE(i)]*25/256);
#else
lcdDraw8bitsNumber(x+10*FW-1, y, (int16_t)calibratedStick[CONVERT_MODE(i)]*25/256);
lcdDrawNumber(x+10*FW-1, y, (int16_t)calibratedStick[CONVERT_MODE(i)]*25/256);
#endif
}
lcd_putsLeft(MENU_HEADER_HEIGHT+1+6*FH, STR_BATT_CALIB);
static int32_t adcBatt;
adcBatt = ((adcBatt * 7) + anaIn(TX_VOLTAGE)) / 8;
uint32_t batCalV = (adcBatt + (adcBatt*g_eeGeneral.txVoltageCalibration)/128) * BATT_SCALE;
batCalV >>= 11;
batCalV += 2; // because of the diode
putsVolts(LEN_CALIB_FIELDS*FW+4*FW, MENU_HEADER_HEIGHT+1+6*FH, batCalV, s_editMode > 0 ? BLINK|INVERS : INVERS);
putsVolts(LEN_CALIB_FIELDS*FW+4*FW, MENU_HEADER_HEIGHT+1+6*FH, getBatteryVoltage(), (s_editMode > 0 ? BLINK : 0) | INVERS | PREC2);
if (s_editMode > 0) CHECK_INCDEC_GENVAR(event, g_eeGeneral.txVoltageCalibration, -127, 127);
}

View file

@ -77,10 +77,16 @@ void menuGeneralVersion(uint8_t event)
exit(0);
#endif
}
if (event == EVT_ENTRY) {
getCPUUniqueID(reusableBuffer.version.id);
}
SIMPLE_MENU(STR_MENUVERSION, menuTabGeneral, e_Vers, 1);
lcd_putsLeft(MENU_HEADER_HEIGHT+1, vers_stamp);
lcd_putsLeft(MENU_HEADER_HEIGHT+4*FH+1, "UID\037\033:");
lcdDrawText(5*FW+3, MENU_HEADER_HEIGHT+4*FH+1, reusableBuffer.version.id);
lcd_putsLeft(MENU_HEADER_HEIGHT+5*FH+1, STR_EEBACKUP);
lcd_putsLeft(MENU_HEADER_HEIGHT+6*FH+1, STR_FACTORYRESET);

View file

@ -2,7 +2,7 @@
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
@ -18,7 +18,7 @@
* GNU General Public License for more details.
*/
#include "../../opentx.h"
#include "opentx.h"
enum LogicalSwitchFields {
LS_FIELD_FUNCTION,

View file

@ -2,7 +2,7 @@
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
@ -18,7 +18,7 @@
* GNU General Public License for more details.
*/
#include "../../opentx.h"
#include "opentx.h"
uint8_t g_moduleIdx;
void menuModelFailsafe(uint8_t event);
@ -219,16 +219,16 @@ void menuModelSetup(uint8_t event)
MENU_TAB({ 0, 0, TIMERS_ROWS, TOPLCD_ROWS 0, 1, 0, 0,
LABEL(Throttle), 0, 0, 0,
LABEL(PreflightCheck), 0, 0, SW_WARN_ITEMS(), POT_WARN_ITEMS(), NAVIGATION_LINE_BY_LINE|(NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS-1), 0,
LABEL(InternalModule),
INTERNAL_MODULE_MODE_ROWS,
LABEL(InternalModule),
INTERNAL_MODULE_MODE_ROWS,
INTERNAL_MODULE_CHANNELS_ROWS,
IF_INTERNAL_MODULE_ON(IS_MODULE_XJT(INTERNAL_MODULE) ? (HAS_RF_PROTOCOL_MODELINDEX(g_model.moduleData[INTERNAL_MODULE].rfProtocol) ? (uint8_t)2 : (uint8_t)1) : (IS_MODULE_PPM(INTERNAL_MODULE) ? (uint8_t)1 : HIDDEN_ROW)),
IF_INTERNAL_MODULE_ON((IS_MODULE_XJT(INTERNAL_MODULE)) ? FAILSAFE_ROWS(INTERNAL_MODULE) : HIDDEN_ROW),
LABEL(ExternalModule),
(IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE)) ? (uint8_t)1 : (uint8_t)0,
IF_INTERNAL_MODULE_ON((IS_MODULE_XJT(INTERNAL_MODULE)) ? FAILSAFE_ROWS(INTERNAL_MODULE) : HIDDEN_ROW),
LABEL(ExternalModule),
(IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE)) ? (uint8_t)1 : (uint8_t)0,
EXTERNAL_MODULE_CHANNELS_ROWS,
(IS_MODULE_XJT(EXTERNAL_MODULE) && !HAS_RF_PROTOCOL_MODELINDEX(g_model.moduleData[EXTERNAL_MODULE].rfProtocol)) ? (uint8_t)1 : (IS_MODULE_PPM(EXTERNAL_MODULE) || IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE)) ? (uint8_t)2 : HIDDEN_ROW,
IF_EXTERNAL_MODULE_XJT(FAILSAFE_ROWS(EXTERNAL_MODULE)),
IF_EXTERNAL_MODULE_XJT(FAILSAFE_ROWS(EXTERNAL_MODULE)),
LABEL(Trainer), 0, TRAINER_CHANNELS_ROWS(), IF_TRAINER_ON(2)});
#else
MENU_TAB({ 0, 0, TIMERS_ROWS, TOPLCD_ROWS 0, 1, 0, 0, LABEL(Throttle), 0, 0, 0, LABEL(PreflightCheck), 0, 0, SW_WARN_ITEMS(), POT_WARN_ITEMS(),
@ -613,7 +613,7 @@ void menuModelSetup(uint8_t event)
case ITEM_MODEL_INTERNAL_MODULE_MODE:
lcd_putsLeft(y, STR_MODE);
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_TARANIS_PROTOCOLS, g_model.moduleData[INTERNAL_MODULE].type, menuHorizontalPosition==0 ? attr : 0);
if (IS_MODULE_XJT(INTERNAL_MODULE))
if (IS_MODULE_XJT(INTERNAL_MODULE))
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+5*FW, y, STR_XJT_PROTOCOLS, 1+g_model.moduleData[INTERNAL_MODULE].rfProtocol, menuHorizontalPosition==1 ? attr : 0);
if (attr && s_editMode>0) {
switch (menuHorizontalPosition) {
@ -625,7 +625,7 @@ void menuModelSetup(uint8_t event)
g_model.moduleData[INTERNAL_MODULE].channelsCount = 0;
}
break;
case 1:
case 1:
g_model.moduleData[INTERNAL_MODULE].rfProtocol = checkIncDec(event, g_model.moduleData[INTERNAL_MODULE].rfProtocol, RF_PROTO_X16, RF_PROTO_LAST, EE_MODEL, isRfProtocolAvailable);
if (checkIncDec_Ret) {
g_model.moduleData[INTERNAL_MODULE].channelsStart = 0;
@ -649,7 +649,9 @@ void menuModelSetup(uint8_t event)
break;
#endif
case ITEM_MODEL_TRAINER_MODE:
g_model.trainerMode = selectMenuItem(MODEL_SETUP_2ND_COLUMN, y, STR_MODE, STR_VTRAINERMODES, g_model.trainerMode, 0, HAS_WIRELESS_TRAINER_HARDWARE() ? TRAINER_MODE_MASTER_BATTERY_COMPARTMENT : TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE, attr, event);
lcd_putsLeft(y, STR_MODE);
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_VTRAINERMODES, g_model.trainerMode, attr);
if (attr) g_model.trainerMode = checkIncDec(event, g_model.trainerMode, 0, HAS_WIRELESS_TRAINER_HARDWARE() ? TRAINER_MODE_MASTER_BATTERY_COMPARTMENT : TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE, EE_MODEL, isTrainerModeAvailable);
break;
case ITEM_MODEL_EXTERNAL_MODULE_LABEL:
@ -666,7 +668,7 @@ void menuModelSetup(uint8_t event)
if (attr && s_editMode>0) {
switch (menuHorizontalPosition) {
case 0:
g_model.moduleData[EXTERNAL_MODULE].type = checkIncDec(event, g_model.moduleData[EXTERNAL_MODULE].type, MODULE_TYPE_NONE, MODULE_TYPE_COUNT-1, EE_MODEL, isModuleAvailable);
g_model.moduleData[EXTERNAL_MODULE].type = checkIncDec(event, g_model.moduleData[EXTERNAL_MODULE].type, MODULE_TYPE_NONE, IS_TRAINER_EXTERNAL_MODULE() ? 0 : MODULE_TYPE_COUNT-1, EE_MODEL, isModuleAvailable);
if (checkIncDec_Ret) {
g_model.moduleData[EXTERNAL_MODULE].rfProtocol = 0;
g_model.moduleData[EXTERNAL_MODULE].channelsStart = 0;
@ -709,7 +711,7 @@ void menuModelSetup(uint8_t event)
break;
case 1:
CHECK_INCDEC_MODELVAR(event, moduleData.channelsCount, -4, min<int8_t>(MAX_CHANNELS(moduleIdx), 32-8-moduleData.channelsStart));
#if defined(TARANIS_INTERNAL_PPM)
if ((k == ITEM_MODEL_EXTERNAL_MODULE_CHANNELS && g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_PPM) || (k == ITEM_MODEL_INTERNAL_MODULE_CHANNELS && g_model.moduleData[INTERNAL_MODULE].type == MODULE_TYPE_PPM) || (k == ITEM_MODEL_TRAINER_CHANNELS)) {
SET_DEFAULT_PPM_FRAME_LENGTH(moduleIdx);
@ -875,8 +877,11 @@ void menuModelFailsafe(uint8_t event)
#define COL_W (LCD_W/2)
const uint8_t SLIDER_W = 64;
// Column separator
lcdDrawSolidVerticalLine(LCD_W/2, FH, LCD_H-FH);
if (NUM_CHANNELS(g_moduleIdx) > 8) {
// Column separator
lcdDrawSolidVerticalLine(LCD_W/2, FH, LCD_H-FH);
}
lcd_putsCenter(0*FH, FAILSAFESET);
lcdInvertLine(0);
@ -949,7 +954,7 @@ void menuModelFailsafe(uint8_t event)
lcdDrawNumber(x+COL_W-4-wbar-ofs, y, calcRESXto1000(failsafeValue)/10, flags);
#endif
}
// Gauge
lcdDrawRect(x+COL_W-3-wbar-ofs, y, wbar+1, 6);
unsigned int lenChannel = limit((uint8_t)1, uint8_t((abs(channelValue) * wbar/2 + lim/2) / lim), uint8_t(wbar/2));
@ -960,7 +965,7 @@ void menuModelFailsafe(uint8_t event)
lcdDrawHorizontalLine(xChannel, y+2, lenChannel, DOTTED, 0);
lcdDrawSolidHorizontalLine(xFailsafe, y+3, lenFailsafe);
lcdDrawSolidHorizontalLine(xFailsafe, y+4, lenFailsafe);
}
}
ch++;
}
}

View file

@ -333,7 +333,7 @@ swsrc_t switchMenuItem(coord_t x, coord_t y, swsrc_t value, LcdFlags attr, uint8
#else
#define GVAR_MENU_ITEM(x, y, v, min, max, lcdattr, editflags, event) editGVarFieldValue(x, y, v, min, max, lcdattr, event)
int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, uint8_t event);
#define displayGVar(x, y, v, min, max) lcdDraw8bitsNumber(x, y, v)
#define displayGVar(x, y, v, min, max) lcdDrawNumber(x, y, v)
#endif
extern uint8_t s_curveChan;

View file

@ -98,6 +98,71 @@ void checkEeprom()
}
#endif
#define BAT_AVG_SAMPLES 8
void checkBatteryAlarms()
{
// TRACE("checkBatteryAlarms()");
if (IS_TXBATT_WARNING() && g_vbat100mV>50) {
AUDIO_TX_BATTERY_LOW();
// TRACE("checkBatteryAlarms(): battery low");
}
#if defined(PCBSKY9X)
else if (g_eeGeneral.temperatureWarn && getTemperature() >= g_eeGeneral.temperatureWarn) {
AUDIO_TX_TEMP_HIGH();
}
else if (g_eeGeneral.mAhWarn && (g_eeGeneral.mAhUsed + Current_used * (488 + g_eeGeneral.txCurrentCalibration)/8192/36) / 500 >= g_eeGeneral.mAhWarn) { // TODO move calculation into board file
AUDIO_TX_MAH_HIGH();
}
#endif
}
void checkBattery()
{
static uint32_t batSum;
static uint8_t sampleCount;
// filter battery voltage by averaging it
if (g_vbat100mV == 0) {
g_vbat100mV = (getBatteryVoltage() + 5) / 10;
batSum = 0;
sampleCount = 0;
}
else {
batSum += getBatteryVoltage();
// TRACE("checkBattery(): sampled = %d", getBatteryVoltage());
if (++sampleCount >= BAT_AVG_SAMPLES) {
g_vbat100mV = (batSum + BAT_AVG_SAMPLES * 5 ) / (BAT_AVG_SAMPLES * 10);
batSum = 0;
sampleCount = 0;
// TRACE("checkBattery(): g_vbat100mV = %d", g_vbat100mV);
}
}
}
void periodicTick_1s()
{
checkBattery();
}
void periodicTick_10s()
{
checkBatteryAlarms();
}
void periodicTick()
{
static uint8_t count10s;
static uint32_t lastTime;
if ( (get_tmr10ms() - lastTime) >= 100 ) {
lastTime += 100;
periodicTick_1s();
if (++count10s >= 10) {
count10s = 0;
periodicTick_10s();
}
}
}
#if defined(GUI) && defined(COLORLCD)
void guiMain(evt_t evt)
{
@ -328,7 +393,7 @@ void perMain()
writeLogs();
handleUsbConnection();
checkTrainerSettings();
checkBattery();
periodicTick();
evt_t evt = getEvent(false);
if (evt && (g_eeGeneral.backlightMode & e_backlight_mode_keys)) backlightOn(); // on keypress turn the light on

View file

@ -55,39 +55,11 @@
#define SET_DEFAULT_PPM_FRAME_LENGTH(idx) g_model.moduleData[idx].ppmFrameLength = 4 * max((int8_t)0, g_model.moduleData[idx].channelsCount)
#if defined(PCBFLAMENCO)
enum ModuleIndex {
EXTERNAL_MODULE,
TRAINER_MODULE,
};
enum TrainerMode {
TRAINER_MODE_MASTER,
TRAINER_MODE_SLAVE
};
#elif defined(PCBTARANIS) || defined(PCBHORUS)
enum ModuleIndex {
INTERNAL_MODULE,
EXTERNAL_MODULE,
TRAINER_MODULE
};
enum TrainerMode {
TRAINER_MODE_MASTER_TRAINER_JACK,
TRAINER_MODE_SLAVE,
TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE,
TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE,
TRAINER_MODE_MASTER_BATTERY_COMPARTMENT,
};
#if defined(PCBTARANIS) || defined(PCBHORUS)
#define IS_TRAINER_EXTERNAL_MODULE() (g_model.trainerMode == TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE || g_model.trainerMode == TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE)
#define HAS_WIRELESS_TRAINER_HARDWARE() (g_eeGeneral.serial2Mode==UART_MODE_SBUS_TRAINER/* || g_eeGeneral.serial2Mode==UART_MODE_CPPM_TRAINER*/)
#elif defined(PCBSKY9X)
enum ModuleIndex {
EXTERNAL_MODULE,
EXTRA_MODULE,
TRAINER_MODULE
};
#endif
#if defined(VOICE)
#define IS_PLAY_FUNC(func) ((func) >= FUNC_PLAY_SOUND && func <= FUNC_PLAY_VALUE)
#else
@ -539,7 +511,7 @@ enum AntennaTypes {
XJT_EXTERNAL_ANTENNA
};
#define IS_PULSES_EXTERNAL_MODULE() (g_model.moduleData[EXTERNAL_MODULE].type != MODULE_TYPE_NONE)
#define IS_EXTERNAL_MODULE_PRESENT() (g_model.moduleData[EXTERNAL_MODULE].type != MODULE_TYPE_NONE)
enum FailsafeModes {
FAILSAFE_NOT_SET,

View file

@ -1509,10 +1509,14 @@ uint16_t BandGap ;
JitterMeter<uint16_t> rawJitter[NUMBER_ANALOG];
JitterMeter<uint16_t> avgJitter[NUMBER_ANALOG];
tmr10ms_t jitterResetTime = 0;
#if defined(PCBTARANIS)
#if defined(PCBHORUS)
#define JITTER_MEASURE_ACTIVE() (menuHandlers[menuLevel] == menuStatsAnalogs)
#elif defined(PCBTARANIS)
#define JITTER_MEASURE_ACTIVE() (menuHandlers[menuLevel] == menuGeneralDiagAna)
#elif defined(CLI)
#define JITTER_MEASURE_ACTIVE() (1)
#else
#define JITTER_MEASURE_ACTIVE() (0)
#endif
#endif
@ -1765,10 +1769,7 @@ void doMixerCalculations()
// handle tick10ms overrun
// correct overflow handling costs a lot of code; happens only each 11 min;
// therefore forget the exact calculation and use only 1 instead; good compromise
#if !defined(CPUARM)
lastTMR = tmr10ms;
#endif
getADC();
@ -1778,10 +1779,6 @@ void doMixerCalculations()
getSwitchesPosition(!s_mixer_first_run_done);
#if defined(CPUARM)
lastTMR = tmr10ms;
#endif
#if defined(PCBSKY9X) && !defined(REVA) && !defined(SIMU)
Current_analogue = (Current_analogue*31 + s_anaFilt[8] ) >> 5 ;
if (Current_analogue > Current_max)
@ -2160,6 +2157,7 @@ uint8_t getSticksNavigationEvent()
}
#endif
#if !defined(CPUARM)
void checkBattery()
{
static uint8_t counter = 0;
@ -2173,14 +2171,7 @@ void checkBattery()
if (counter-- == 0) {
counter = 10;
int32_t instant_vbat = anaIn(TX_VOLTAGE);
#if defined(PCBTARANIS) || defined(PCBFLAMENCO) || defined(PCBHORUS)
instant_vbat = (instant_vbat + instant_vbat*(g_eeGeneral.txVoltageCalibration)/128) * BATT_SCALE;
instant_vbat >>= 11;
instant_vbat += 2; // because of the diode
#elif defined(PCBSKY9X)
instant_vbat = (instant_vbat + instant_vbat*(g_eeGeneral.txVoltageCalibration)/128) * 4191;
instant_vbat /= 55296;
#elif defined(CPUM2560)
#if defined(CPUM2560)
instant_vbat = (instant_vbat*1112 + instant_vbat*g_eeGeneral.txVoltageCalibration + (BandGap<<2)) / (BandGap<<3);
#else
instant_vbat = (instant_vbat*16 + instant_vbat*g_eeGeneral.txVoltageCalibration/8) / BandGap;
@ -2218,17 +2209,11 @@ void checkBattery()
if (IS_TXBATT_WARNING() && g_vbat100mV>50) {
AUDIO_TX_BATTERY_LOW();
}
#if defined(PCBSKY9X)
else if (g_eeGeneral.temperatureWarn && getTemperature() >= g_eeGeneral.temperatureWarn) {
AUDIO_TX_TEMP_HIGH();
}
else if (g_eeGeneral.mAhWarn && (g_eeGeneral.mAhUsed + Current_used * (488 + g_eeGeneral.txCurrentCalibration)/8192/36) / 500 >= g_eeGeneral.mAhWarn) {
AUDIO_TX_MAH_HIGH();
}
#endif
}
}
}
#endif // #if !defined(CPUARM)
#if !defined(SIMU) && !defined(CPUARM)
@ -2678,9 +2663,13 @@ int main()
#if defined(CPUM2560) || defined(CPUM2561)
uint8_t mcusr = MCUSR; // save the WDT (etc) flags
MCUSR = 0; // must be zeroed before disabling the WDT
MCUCR = 0x80 ; // Disable JTAG port that can interfere with POT3
MCUCR = 0x80 ; // Must be done twice
#elif defined(PCBSTD)
uint8_t mcusr = MCUCSR;
MCUCSR = 0;
MCUCSR = 0x80 ; // Disable JTAG port that can interfere with POT3
MCUCSR = 0x80 ; // Must be done twice
#endif
#if defined(PCBTARANIS)
g_eeGeneral.contrast = 30;
@ -2753,6 +2742,11 @@ int main()
if ((shutdown_state=pwrCheck()) > e_power_trainer)
break;
#endif
#if defined(SIMU)
sleep(5/*ms*/);
if (main_thread_running == 0)
return 0;
#endif
perMain();

View file

@ -25,6 +25,7 @@
#include <string.h>
#include <stddef.h>
#include <stdlib.h>
#include "definitions.h"
#if defined(SIMU)
#define SWITCH_SIMU(a, b) (a)
@ -203,32 +204,6 @@
#define ROTARY_ENCODER_NAVIGATION
#endif
#if defined(SIMU)
#define __ALIGNED
#else
#define __ALIGNED __attribute__((aligned(32)))
#endif
#if defined(SIMU)
#define __DMA
#elif defined(STM32F4) && !defined(BOOT)
#define __DMA __attribute__((section(".ram"), aligned(32)))
#else
#define __DMA __ALIGNED
#endif
#if defined(PCBHORUS) && !defined(SIMU)
#define __SDRAM __attribute__((section(".sdram"), aligned(32)))
#else
#define __SDRAM __DMA
#endif
#if defined(SIMU) || defined(CPUARM) || GCC_VERSION < 472
typedef int32_t int24_t;
#else
typedef __int24 int24_t;
#endif
#if defined(FAI)
#define IS_FAI_ENABLED() true
#define IF_FAI_CHOICE(x)
@ -1559,6 +1534,13 @@ union ReusableBuffer
char originalName[SD_SCREEN_FILE_LENGTH+1];
} sdmanager;
#endif
#if defined(PCBTARANIS)
struct
{
char id[27];
} version;
#endif
};
extern union ReusableBuffer reusableBuffer;

View file

@ -68,7 +68,7 @@ PACK(struct Dsm2PulsesData {
});
#endif
#define CROSSFIRE_BAUDRATE 400000
#define CROSSFIRE_BAUDRATE 921600
#define CROSSFIRE_FRAME_LEN 25
#define CROSSFIRE_CHANNELS_COUNT 16
PACK(struct CrossfirePulsesData {

View file

@ -2,7 +2,7 @@
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
@ -33,7 +33,6 @@
#define SBUS_CH_CENTER 0x3E0
Fifo<uint8_t, 32> sbusFifo;
uint8_t SbusFrame[SBUS_MAX_FRAME_SIZE];
uint16_t SbusTimer ;
uint8_t SbusIndex = 0 ;
@ -74,9 +73,10 @@ void processSbusFrame(uint8_t * sbus, int16_t * pulses, uint32_t size)
void processSbusInput()
{
#if !defined(SIMU)
uint8_t rxchar;
uint32_t active = 0;
while (sbusFifo.pop(rxchar)) {
while (sbusGetByte(&rxchar)) {
active = 1;
SbusFrame[SbusIndex++] = rxchar;
if (SbusIndex > SBUS_MAX_FRAME_SIZE-1) {
@ -95,4 +95,5 @@ void processSbusInput()
}
}
}
#endif
}

View file

@ -26,6 +26,5 @@
#define SBUS_MAX_FRAME_SIZE 28
void processSbusInput();
void processSbusFrame(uint8_t * sbus, int16_t * pulses, uint32_t size);
#endif // _SBUS_H_

View file

@ -544,9 +544,15 @@ uint16_t anaIn(uint8_t chan)
return th9xSim->sliders[chan]->getValue();
else if (chan<NUM_STICKS+NUM_POTS)
return th9xSim->knobs[chan-NUM_STICKS]->getValue();
#if defined(PCBTARANIS) || defined(PCBFLAMENCO) || defined(PCBHORUS)
#if defined(PCBHORUS)
else if (chan == TX_VOLTAGE)
return 1000;
return 1737; //~10.6V
#elif (defined(PCBTARANIS) && defined(REV9E))
else if (chan == TX_VOLTAGE)
return 1420; //~10.6V
#elif defined(PCBTARANIS) || defined(PCBFLAMENCO)
else if (chan == TX_VOLTAGE)
return 1000; //~7.4V
#elif defined(PCBSKY9X)
else if (chan == TX_VOLTAGE)
return 5.1*1500/11.3;

View file

@ -41,6 +41,8 @@
const pm_char date_stamp[] PROGMEM = "DATE" TAB ": " DATE;
const pm_char time_stamp[] PROGMEM = "TIME" TAB ": " TIME;
const pm_char eeprom_stamp[] PROGMEM = "EEPR" TAB ": " EEPROM_STR;
#elif defined(PCBTARANIS)
const pm_char vers_stamp[] PROGMEM = "FW\037\033: " "opentx-" FLAVOUR "\036VERS\037\033: " VERSION "\036DATE\037\033: " DATE " " TIME "\036EEPR\037\033: " EEPROM_STR;
#else
const pm_char vers_stamp[] PROGMEM = "FW\037\033: " "opentx-" FLAVOUR "\036VERS\037\033: " VERSION "\036DATE\037\033: " DATE "\036TIME\037\033: " TIME "\036EEPR\037\033: " EEPROM_STR;
#endif

View file

@ -157,9 +157,9 @@ char * strAppendUnsigned(char * dest, uint32_t value, uint8_t digits, uint8_t ra
}
uint8_t idx = digits;
while(idx > 0) {
div_t qr = div(value, radix);
dest[--idx] = (qr.rem >= 10 ? 'A'-10 : '0') + qr.rem;
value = qr.quot;
uint32_t rem = value % radix;
dest[--idx] = (rem >= 10 ? 'A'-10 : '0') + rem;
value /= radix;
}
dest[digits] = '\0';
return &dest[digits];

View file

@ -20,12 +20,6 @@
#include "../../opentx.h"
const uint8_t volumeScale[VOLUME_LEVEL_MAX+1] = {
254, 127, 110, 100, 90, 80, 70, 60, 50, 40,
30, 20, 19, 18, 17, 16, 15, 14, 13, 12,
11, 10, 5, 0
};
#if !defined(SIMU)
#define VS_WRITE_COMMAND 0x02
@ -414,13 +408,24 @@ bool audioPushBuffer(AudioBuffer * buffer)
}
}
// adjust this value for a volume level just above the silence
// values is attenuation in dB, higher value - less volume
// max value is 126
#define VOLUME_MIN_DB 40
void setScaledVolume(uint8_t volume)
{
if (volume > VOLUME_LEVEL_MAX) {
volume = VOLUME_LEVEL_MAX;
}
setVolume(volumeScale[volume]);
// maximum volume is 0x00 and total silence is 0xFE
if (volume == 0) {
setVolume(0xFE); // silence
}
else {
uint32_t vol = (VOLUME_MIN_DB * 2) - ((uint32_t)volume * (VOLUME_MIN_DB * 2)) / VOLUME_LEVEL_MAX;
setVolume(vol);
}
}
void setVolume(uint8_t volume)

View file

@ -266,3 +266,9 @@ void checkTrainerSettings()
}
}
}
uint16_t getBatteryVoltage()
{
int32_t instant_vbat = anaIn(TX_VOLTAGE); // using filtered ADC value on purpose
return (uint16_t)((instant_vbat * (1000 + g_eeGeneral.txVoltageCalibration) ) / 1637);
}

View file

@ -242,12 +242,7 @@ extern uint16_t adcValues[NUMBER_ANALOG];
void adcInit(void);
void adcRead(void);
uint16_t getAnalogValue(uint8_t index);
#if defined(REV3)
#define BATT_SCALE 120
#else
#define BATT_SCALE 150
#endif
uint16_t getBatteryVoltage(); // returns current battery voltage in 10mV steps
#if defined(__cplusplus) && !defined(SIMU)
extern "C" {
@ -308,6 +303,7 @@ int32_t getVolume(void);
void telemetryPortInit(uint32_t baudrate);
void telemetryPortSetDirectionOutput(void);
void sportSendBuffer(uint8_t * buffer, uint32_t count);
int telemetryGetByte(uint8_t * byte);
// Haptic driver
void hapticInit(void);
@ -318,12 +314,14 @@ void hapticOn(uint32_t pwmPercent);
// Second serial port driver
#define DEBUG_BAUDRATE 115200
extern uint8_t serial2Mode;
void serial2Init(unsigned int mode, unsigned int protocol);
void serial2Putc(char c);
#define serial2TelemetryInit(protocol) serial2Init(UART_MODE_TELEMETRY, protocol)
void serial2SbusInit(void);
void serial2Stop(void);
#define USART_FLAG_ERRORS (USART_FLAG_ORE | USART_FLAG_NE | USART_FLAG_FE | USART_FLAG_PE)
int sbusGetByte(uint8_t * byte);
#if defined(USB_JOYSTICK) && !defined(SIMU)
void usbJoystickUpdate(void);
@ -332,4 +330,12 @@ void usbJoystickUpdate(void);
extern uint8_t currentTrainerMode;
void checkTrainerSettings(void);
#if defined(__cplusplus)
#include "fifo.h"
#include "dmafifo.h"
extern DMAFifo<512> telemetryFifo;
extern DMAFifo<32> serial2RxFifo;
extern Fifo<uint8_t, 32> sbusFifo;
#endif
#endif // _BOARD_HORUS_H_

View file

@ -151,9 +151,11 @@
#define SERIAL_USART USART3
#define SERIAL_USART_IRQHandler USART3_IRQHandler
#define SERIAL_USART_IRQn USART3_IRQn
#define SERIAL_DMA_Stream_RX DMA1_Stream1
#define SERIAL_DMA_Channel_RX DMA_Channel_4
// Telemetry
#define TELEMETRY_RCC_AHB1Periph RCC_AHB1Periph_GPIOD
#define TELEMETRY_RCC_AHB1Periph (RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_DMA1)
#define TELEMETRY_RCC_APB1Periph RCC_APB1Periph_USART2
#define TELEMETRY_GPIO_DIR GPIOD
#define TELEMETRY_DIR_GPIO_PIN GPIO_Pin_4 // PD.04
@ -164,8 +166,13 @@
#define TELEMETRY_GPIO_PinSource_RX GPIO_PinSource6
#define TELEMETRY_GPIO_AF GPIO_AF_USART2
#define TELEMETRY_USART USART2
#define TELEMETRY_USART_IRQHandler USART2_IRQHandler
#define TELEMETRY_USART_IRQn USART2_IRQn
#define TELEMETRY_DMA_Stream_RX DMA1_Stream5
#define TELEMETRY_DMA_Channel_RX DMA_Channel_4
#define TELEMETRY_DMA_Stream_TX DMA1_Stream6
#define TELEMETRY_DMA_Channel_TX DMA_Channel_4
#define TELEMETRY_DMA_TX_Stream_IRQ DMA1_Stream6_IRQn
#define TELEMETRY_DMA_TX_IRQHandler DMA1_Stream6_IRQHandler
#define TELEMETRY_DMA_TX_FLAG_TC DMA_IT_TCIF6
// Heartbeat
#define HEARTBEAT_RCC_AHB1Periph RCC_AHB1Periph_GPIOD

View file

@ -2,7 +2,7 @@
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
@ -18,7 +18,7 @@
* GNU General Public License for more details.
*/
#include "../../opentx.h"
#include "opentx.h"
void setupPulses(unsigned int port);
void setupPulsesPPM(unsigned int port);
@ -188,7 +188,7 @@ extern "C" void TIM1_CC_IRQHandler()
DMA_InitStructure.DMA_BufferSize = (uint8_t *)modulePulsesData[INTERNAL_MODULE].pxx.ptr - (uint8_t *)modulePulsesData[INTERNAL_MODULE].pxx.pulses;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
@ -309,35 +309,6 @@ void intmodulePxxStart()
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
#if 0
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = TIM_RF_PRIO;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; /* Not used as 4 bits are used for the pre-emption priority. */;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init( &NVIC_InitStructure );
// open heartbit ---------------------
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOD, &GPIO_InitStructure);
/* Connect EXTI Line12 to PD12 pin */
EXTI_InitTypeDef EXTI_InitStructure;
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOD, EXTI_PinSource12);
EXTI_InitStructure.EXTI_Line = EXTI_Line12;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;///////
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
EXTI15_10_Interrupt_Handler = EXTI15_10_IRQHandler_pxx;
#endif
// TX Pin
GPIO_PinAFConfig(INTMODULE_TX_GPIO, INTMODULE_TX_GPIO_PinSource, INTMODULE_GPIO_AF);
GPIO_InitStructure.GPIO_Pin = INTMODULE_TX_GPIO_PIN;
@ -529,7 +500,7 @@ static void extmodulePpmStart()
// Hardware timer in PWM mode is used for PPM generation
// Output is OFF if CNT<CCR1(delay) and ON if bigger
// CCR1 register defines duration of pulse length and is constant
// AAR register defines duration of each pulse, it is
// AAR register defines duration of each pulse, it is
// updated after every pulse in Update interrupt handler.
// CCR2 register defines duration of no pulses (time between two pulse trains)
// it is calculated every round to have PPM period constant.
@ -622,7 +593,7 @@ extern "C" void TIM2_IRQHandler()
EXTMODULE_TIMER->ARR = *modulePulsesData[EXTERNAL_MODULE].ppm.ptr++ ;
if (*modulePulsesData[EXTERNAL_MODULE].ppm.ptr == 0) {
// we reached the end of PPM pulses
// enable CC2 interrupt (which comes before Update in any case)
// enable CC2 interrupt (which comes before Update in any case)
// to start new PPM cycle and setup pulses
EXTMODULE_TIMER->SR &= ~TIM_SR_CC2IF ; // Clear CC1 flag
EXTMODULE_TIMER->DIER |= TIM_DIER_CC2IE ; // Enable CC1 interrupt

View file

@ -39,11 +39,6 @@ void pwrInit()
GPIO_Init(AUDIO_SHUTDOWN_GPIO, &GPIO_InitStructure);
// Init Module PWR
GPIO_ResetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN);
GPIO_InitStructure.GPIO_Pin = EXTMODULE_PWR_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_Init(EXTMODULE_PWR_GPIO, &GPIO_InitStructure);
// TODO not here
GPIO_ResetBits(INTMODULE_PWR_GPIO, INTMODULE_PWR_GPIO_PIN);
GPIO_InitStructure.GPIO_Pin = INTMODULE_PWR_GPIO_PIN;
@ -112,4 +107,4 @@ void pwrResetHandler()
pwrOn();
}
}
}

View file

@ -2,7 +2,7 @@
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
@ -22,10 +22,9 @@
uint8_t serial2Mode = 0;
Fifo<uint8_t, 512> serial2TxFifo;
extern Fifo<uint8_t, 512> telemetryFifo;
extern Fifo<uint8_t, 32> sbusFifo;
DMAFifo<32> serial2RxFifo __DMA (SERIAL_DMA_Stream_RX);
void uart3Setup(unsigned int baudrate)
void uart3Setup(unsigned int baudrate, bool dma)
{
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
@ -39,42 +38,69 @@ void uart3Setup(unsigned int baudrate)
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(SERIAL_GPIO, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = baudrate;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_Init(SERIAL_USART, &USART_InitStructure);
USART_Cmd(SERIAL_USART, ENABLE);
USART_ITConfig(SERIAL_USART, USART_IT_RXNE, ENABLE);
USART_ITConfig(SERIAL_USART, USART_IT_TXE, DISABLE);
NVIC_SetPriority(SERIAL_USART_IRQn, 7);
NVIC_EnableIRQ(SERIAL_USART_IRQn);
if (dma) {
DMA_InitTypeDef DMA_InitStructure;
serial2RxFifo.clear();
USART_ITConfig(SERIAL_USART, USART_IT_RXNE, DISABLE);
USART_ITConfig(SERIAL_USART, USART_IT_TXE, DISABLE);
DMA_InitStructure.DMA_Channel = SERIAL_DMA_Channel_RX;
DMA_InitStructure.DMA_PeripheralBaseAddr = CONVERT_PTR_UINT(&SERIAL_USART->DR);
DMA_InitStructure.DMA_Memory0BaseAddr = CONVERT_PTR_UINT(serial2RxFifo.buffer());
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = serial2RxFifo.size();
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(SERIAL_DMA_Stream_RX, &DMA_InitStructure);
USART_DMACmd(SERIAL_USART, USART_DMAReq_Rx, ENABLE);
USART_Cmd(SERIAL_USART, ENABLE);
DMA_Cmd(SERIAL_DMA_Stream_RX, ENABLE);
}
else {
#if !defined(USB_SERIAL) && defined(CLI)
USART_Cmd(SERIAL_USART, ENABLE);
USART_ITConfig(SERIAL_USART, USART_IT_RXNE, ENABLE);
USART_ITConfig(SERIAL_USART, USART_IT_TXE, DISABLE);
NVIC_SetPriority(SERIAL_USART_IRQn, 7);
NVIC_EnableIRQ(SERIAL_USART_IRQn);
#endif
}
}
void serial2Init(unsigned int mode, unsigned int protocol)
{
USART_DeInit(SERIAL_USART);
serial2Stop();
serial2Mode = mode;
switch (mode) {
case UART_MODE_TELEMETRY_MIRROR:
uart3Setup(FRSKY_SPORT_BAUDRATE);
uart3Setup(FRSKY_SPORT_BAUDRATE, false);
break;
#if !defined(USB_SERIAL) && (defined(DEBUG) || defined(CLI))
case UART_MODE_DEBUG:
uart3Setup(DEBUG_BAUDRATE);
uart3Setup(DEBUG_BAUDRATE, false);
break;
#endif
case UART_MODE_TELEMETRY:
if (protocol == PROTOCOL_FRSKY_D_SECONDARY) {
uart3Setup(FRSKY_D_BAUDRATE);
uart3Setup(FRSKY_D_BAUDRATE, true);
}
break;
}
@ -89,18 +115,20 @@ void serial2Putc(char c)
void serial2SbusInit()
{
uart3Setup(100000);
// TODO is it possible on Horus?
uart3Setup(SBUS_BAUDRATE, true);
SERIAL_USART->CR1 |= USART_CR1_M | USART_CR1_PCE ;
}
void serial2Stop()
{
DMA_DeInit(SERIAL_DMA_Stream_RX);
USART_DeInit(SERIAL_USART);
}
uint8_t serial2TracesEnabled()
{
return 1; // (serial2Mode == 0);
return 1; // TODO (serial2Mode == 0);
}
#if !defined(SIMU)
@ -118,29 +146,21 @@ extern "C" void SERIAL_USART_IRQHandler(void)
}
}
#if !defined(USB_SERIAL) && defined(CLI)
// Receive
uint32_t status = SERIAL_USART->SR;
while (status & (USART_FLAG_RXNE | USART_FLAG_ERRORS)) {
uint8_t data = SERIAL_USART->DR;
if (!(status & USART_FLAG_ERRORS)) {
switch (serial2Mode) {
case UART_MODE_TELEMETRY:
telemetryFifo.push(data);
break;
case UART_MODE_SBUS_TRAINER:
sbusFifo.push(data);
break;
#if defined(CLI)
case UART_MODE_DEBUG:
cliRxFifo.push(data);
break;
#endif
}
}
status = SERIAL_USART->SR;
}
}
#endif
}
#endif

View file

@ -2,7 +2,7 @@
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
@ -18,9 +18,9 @@
* GNU General Public License for more details.
*/
#include "../../opentx.h"
#include "opentx.h"
extern Fifo<uint8_t, 512> telemetryFifo;
DMAFifo<512> telemetryFifo __DMA (TELEMETRY_DMA_Stream_RX);
void telemetryPortInit(uint32_t baudrate)
{
@ -29,6 +29,13 @@ void telemetryPortInit(uint32_t baudrate)
return;
}
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TELEMETRY_DMA_TX_Stream_IRQ;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; /* Not used as 4 bits are used for the pre-emption priority. */;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
@ -47,32 +54,45 @@ void telemetryPortInit(uint32_t baudrate)
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(TELEMETRY_GPIO_DIR, &GPIO_InitStructure);
GPIO_ResetBits(TELEMETRY_GPIO_DIR, TELEMETRY_DIR_GPIO_PIN);
USART_InitStructure.USART_BaudRate = baudrate;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_Init(TELEMETRY_USART, &USART_InitStructure);
DMA_InitTypeDef DMA_InitStructure;
telemetryFifo.clear();
USART_ITConfig(TELEMETRY_USART, USART_IT_RXNE, DISABLE);
USART_ITConfig(TELEMETRY_USART, USART_IT_TXE, DISABLE);
DMA_InitStructure.DMA_Channel = TELEMETRY_DMA_Channel_RX;
DMA_InitStructure.DMA_PeripheralBaseAddr = CONVERT_PTR_UINT(&TELEMETRY_USART->DR);
DMA_InitStructure.DMA_Memory0BaseAddr = CONVERT_PTR_UINT(telemetryFifo.buffer());
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = telemetryFifo.size();
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(TELEMETRY_DMA_Stream_RX, &DMA_InitStructure);
USART_DMACmd(TELEMETRY_USART, USART_DMAReq_Rx, ENABLE);
USART_Cmd(TELEMETRY_USART, ENABLE);
USART_ITConfig(TELEMETRY_USART, USART_IT_RXNE, ENABLE);
NVIC_SetPriority(TELEMETRY_USART_IRQn, 6);
NVIC_EnableIRQ(TELEMETRY_USART_IRQn);
DMA_Cmd(TELEMETRY_DMA_Stream_RX, ENABLE);
}
struct SportTxBuffer
{
uint8_t *ptr;
uint32_t count;
} sportTxBuffer;
void telemetryPortSetDirectionOutput()
{
TELEMETRY_GPIO_DIR->BSRRL = TELEMETRY_DIR_GPIO_PIN; // output enable
TELEMETRY_USART->CR1 &= ~USART_CR1_RE; // turn off receiver
TELEMETRY_USART->CR1 &= ~USART_CR1_RE; // turn off receiver
}
void telemetryPortSetDirectionInput()
@ -81,49 +101,64 @@ void telemetryPortSetDirectionInput()
TELEMETRY_USART->CR1 |= USART_CR1_RE; // turn on receiver
}
void sportSendBuffer(uint8_t *buffer, uint32_t count)
void sportSendBuffer(uint8_t * buffer, uint32_t count)
{
sportTxBuffer.ptr = buffer ;
sportTxBuffer.count = count ;
#if 0
telemetryPortSetDirectionOutput();
TELEMETRY_USART->CR1 |= USART_CR1_TXEIE ;
DMA_InitTypeDef DMA_InitStructure;
DMA_DeInit(TELEMETRY_DMA_Stream_TX);
DMA_InitStructure.DMA_Channel = TELEMETRY_DMA_Channel_TX;
DMA_InitStructure.DMA_PeripheralBaseAddr = CONVERT_PTR_UINT(&TELEMETRY_USART->DR);
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
DMA_InitStructure.DMA_Memory0BaseAddr = CONVERT_PTR_UINT(buffer);
DMA_InitStructure.DMA_BufferSize = count;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(TELEMETRY_DMA_Stream_TX, &DMA_InitStructure);
DMA_Cmd(TELEMETRY_DMA_Stream_TX, ENABLE);
USART_DMACmd(TELEMETRY_USART, USART_DMAReq_Tx, ENABLE);
DMA_ITConfig(TELEMETRY_DMA_Stream_TX, DMA_IT_TC, ENABLE);
// enable interrupt and set it's priority
NVIC_EnableIRQ(TELEMETRY_DMA_TX_Stream_IRQ) ;
NVIC_SetPriority(TELEMETRY_DMA_TX_Stream_IRQ, 7);
#endif
}
#if !defined(SIMU)
#define USART_FLAG_ERRORS (USART_FLAG_ORE | USART_FLAG_NE | USART_FLAG_FE | USART_FLAG_PE)
extern "C" void TELEMETRY_USART_IRQHandler()
extern "C" void TELEMETRY_DMA_TX_IRQHandler(void)
{
uint32_t status;
uint8_t data;
status = TELEMETRY_USART->SR;
if (status & USART_SR_TXE) {
if (sportTxBuffer.count) {
TELEMETRY_USART->DR = *sportTxBuffer.ptr++;
if (--sportTxBuffer.count == 0) {
TELEMETRY_USART->CR1 &= ~USART_CR1_TXEIE; // stop Tx interrupt
TELEMETRY_USART->CR1 |= USART_CR1_TCIE; // enable complete interrupt
}
}
}
if ((status & USART_SR_TC) && (TELEMETRY_USART->CR1 & USART_CR1_TCIE)) {
TELEMETRY_USART->CR1 &= ~USART_CR1_TCIE ; // stop Complete interrupt
if (DMA_GetITStatus(TELEMETRY_DMA_Stream_TX, TELEMETRY_DMA_TX_FLAG_TC)) {
DMA_ClearITPendingBit(TELEMETRY_DMA_Stream_TX, TELEMETRY_DMA_TX_FLAG_TC);
telemetryPortSetDirectionInput();
while (status & (USART_FLAG_RXNE)) {
status = TELEMETRY_USART->DR;
status = TELEMETRY_USART->SR ;
}
}
while (status & (USART_FLAG_RXNE | USART_FLAG_ERRORS)) {
data = TELEMETRY_USART->DR;
if (!(status & USART_FLAG_ERRORS)) {
telemetryFifo.push(data);
}
status = TELEMETRY_USART->SR;
}
}
// TODO we should have telemetry in an higher layer, functions above should move to a sport_driver.cpp
int telemetryGetByte(uint8_t * byte)
{
// TODO I am not sure it's possible to have this cable on Horus ...
#if 0
if (telemetryProtocol == PROTOCOL_FRSKY_D_SECONDARY) {
if (serial2Mode == UART_MODE_TELEMETRY)
return serial2RxFifo.pop(*byte);
else
return 0;
}
else {
return telemetryFifo.pop(*byte);
}
#else
return telemetryFifo.pop(*byte);
#endif
}

View file

@ -2,7 +2,7 @@
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
@ -177,7 +177,7 @@ void stop_cppm_on_heartbeat_capture(void)
TRAINER_TIMER->CR1 &= ~TIM_CR1_CEN; // Stop counter
NVIC_DisableIRQ(TRAINER_TIMER_IRQn); // Stop Interrupt
if (!IS_PULSES_EXTERNAL_MODULE()) {
if (!IS_EXTERNAL_MODULE_PRESENT()) {
EXTERNAL_MODULE_OFF();
}
}
@ -221,7 +221,7 @@ void stop_sbus_on_heartbeat_capture(void)
configure_pins(HEARTBEAT_GPIO_PIN, PIN_INPUT | PIN_PORTC);
NVIC_DisableIRQ(HEARTBEAT_USART_IRQn);
#endif
if (!IS_PULSES_EXTERNAL_MODULE()) {
if (!IS_EXTERNAL_MODULE_PRESENT()) {
EXTERNAL_MODULE_OFF();
}
}
@ -246,3 +246,8 @@ extern "C" void HEARTBEAT_USART_IRQHandler()
}
}
#endif
int sbusGetByte(uint8_t * byte)
{
return false;
}

View file

@ -57,7 +57,7 @@ uint32_t Peri1_frequency, Peri2_frequency;
GPIO_TypeDef gpioa, gpiob, gpioc, gpiod, gpioe, gpiof, gpiog, gpioh, gpioi, gpioj;
TIM_TypeDef tim1, tim2, tim3, tim4, tim5, tim6, tim7, tim8, tim9, tim10;
RCC_TypeDef rcc;
DMA_Stream_TypeDef dma2_stream2, dma2_stream6;
DMA_Stream_TypeDef dma2_stream2, dma2_stream6, dma1_stream5;
DMA_TypeDef dma2;
USART_TypeDef Usart0, Usart1, Usart2, Usart3, Usart4;
#elif defined(CPUARM)
@ -1297,6 +1297,7 @@ FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG) { ret
void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF) { }
void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct) { }
void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState) { }
void USART_DMACmd(USART_TypeDef* USARTx, uint16_t USART_DMAReq, FunctionalState NewState) { }
void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState) { }
void RCC_PLLI2SConfig(uint32_t PLLI2SN, uint32_t PLLI2SR) { }
void RCC_PLLI2SCmd(FunctionalState NewState) { }

View file

@ -93,7 +93,7 @@ extern GPIO_TypeDef gpioa, gpiob, gpioc, gpiod, gpioe, gpiof, gpiog, gpioh, gpio
extern TIM_TypeDef tim1, tim2, tim3, tim4, tim5, tim6, tim7, tim8, tim9, tim10;
extern USART_TypeDef Usart0, Usart1, Usart2, Usart3, Usart4;
extern RCC_TypeDef rcc;
extern DMA_Stream_TypeDef dma2_stream2, dma2_stream6;
extern DMA_Stream_TypeDef dma2_stream2, dma2_stream6, dma1_stream5;
extern DMA_TypeDef dma2;
#undef GPIOA
#undef GPIOB
@ -145,8 +145,10 @@ extern DMA_TypeDef dma2;
#define USART3 (&Usart3)
#undef RCC
#define RCC (&rcc)
#undef DMA1_Stream5
#undef DMA2_Stream2
#undef DMA2_Stream6
#define DMA1_Stream5 (&dma1_stream5)
#define DMA2_Stream2 (&dma2_stream2)
#define DMA2_Stream6 (&dma2_stream6)
#undef DMA2
@ -427,7 +429,9 @@ OS_TID CoCreateTask(FUNCPtr task, void *argv, uint32_t parameter, void * stk, ui
#if defined(CPUSTM32)
inline void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct) { }
#define TIM_DeInit(...)
#define TIM_TimeBaseInit(...)
#if defined(PCBHORUS)
inline void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct) { }
#endif
#define TIM_SetCompare2(...)
#define TIM_ClearFlag(...)
#define TIM_Cmd(...)
@ -449,6 +453,8 @@ inline void DMA_ITConfig(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_IT, Func
inline void DMA_StructInit(DMA_InitTypeDef* DMA_InitStruct) { }
inline void DMA_Cmd(DMA_Stream_TypeDef* DMAy_Streamx, FunctionalState NewState) { }
inline FlagStatus DMA_GetFlagStatus(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_FLAG) { return RESET; }
inline ITStatus DMA_GetITStatus(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_IT) { return RESET; }
inline void DMA_ClearITPendingBit(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_IT) { }
inline void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_I2S_DMAReq, FunctionalState NewState) { }
inline void UART3_Configure(uint32_t baudrate, uint32_t masterClock) { }
inline void NVIC_Init(NVIC_InitTypeDef *) { }

View file

@ -590,3 +590,10 @@ void checkTrainerSettings()
}
}
uint16_t getBatteryVoltage()
{
int32_t instant_vbat = anaIn(TX_VOLTAGE); // using filtered ADC value on purpose
instant_vbat = (instant_vbat + instant_vbat*(g_eeGeneral.txVoltageCalibration)/128) * 4191;
instant_vbat /= 5530;
return (uint16_t)instant_vbat;
}

View file

@ -228,6 +228,7 @@ enum Analogs {
void adcInit();
void adcRead(void);
uint16_t getAnalogValue(uint8_t index);
uint16_t getBatteryVoltage(); // returns current battery voltage in 10mV steps
void setSticksGain(uint8_t gains);
// Buzzer driver

View file

@ -27,23 +27,20 @@ void setSampleRate(uint32_t frequency)
{
register uint32_t timer = (PERI1_FREQUENCY * TIMER_MULT_APB1) / frequency - 1 ; // MCK/8 and 100 000 Hz
TIM6->CR1 &= ~TIM_CR1_CEN ;
TIM6->CNT = 0 ;
TIM6->ARR = limit<uint32_t>(2, timer, 65535) ;
TIM6->CR1 |= TIM_CR1_CEN ;
AUDIO_TIMER->CR1 &= ~TIM_CR1_CEN ;
AUDIO_TIMER->CNT = 0 ;
AUDIO_TIMER->ARR = limit<uint32_t>(2, timer, 65535) ;
AUDIO_TIMER->CR1 |= TIM_CR1_CEN ;
}
// Start TIMER6 at 100000Hz, used for DAC trigger
void dacTimerInit()
{
// Now for timer 6
RCC->APB1ENR |= RCC_APB1ENR_TIM6EN ; // Enable clock
TIM6->PSC = 0 ; // Max speed
TIM6->ARR = (PERI1_FREQUENCY * TIMER_MULT_APB1) / 100000 - 1 ; // 10 uS, 100 kHz
TIM6->CR2 = 0 ;
TIM6->CR2 = 0x20 ;
TIM6->CR1 = TIM_CR1_CEN ;
AUDIO_TIMER->PSC = 0 ; // Max speed
AUDIO_TIMER->ARR = (PERI1_FREQUENCY * TIMER_MULT_APB1) / 100000 - 1 ; // 10 uS, 100 kHz
AUDIO_TIMER->CR2 = 0 ;
AUDIO_TIMER->CR2 = 0x20 ;
AUDIO_TIMER->CR1 = TIM_CR1_CEN ;
}
// Configure DAC0 (or DAC1 for REVA)
@ -53,39 +50,36 @@ void dacInit()
{
dacTimerInit();
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN ; // Enable portA clock
configure_pins( GPIO_Pin_4, PIN_ANALOG | PIN_PORTA ) ;
RCC->APB1ENR |= RCC_APB1ENR_DACEN ; // Enable clock
RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN ; // Enable DMA1 clock
// Chan 7, 16-bit wide, Medium priority, memory increments
DMA1_Stream5->CR &= ~DMA_SxCR_EN ; // Disable DMA
DMA1->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5 | DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5 ; // Write ones to clear bits
DMA1_Stream5->CR = DMA_SxCR_CHSEL_0 | DMA_SxCR_CHSEL_1 | DMA_SxCR_CHSEL_2 | DMA_SxCR_PL_0 |
AUDIO_DMA_Stream->CR &= ~DMA_SxCR_EN ; // Disable DMA
AUDIO_DMA->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5 | DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5 ; // Write ones to clear bits
AUDIO_DMA_Stream->CR = DMA_SxCR_CHSEL_0 | DMA_SxCR_CHSEL_1 | DMA_SxCR_CHSEL_2 | DMA_SxCR_PL_0 |
DMA_SxCR_MSIZE_0 | DMA_SxCR_PSIZE_0 | DMA_SxCR_MINC | DMA_SxCR_DIR_0 | DMA_SxCR_CIRC ;
DMA1_Stream5->PAR = CONVERT_PTR_UINT(&DAC->DHR12R1);
// DMA1_Stream5->M0AR = CONVERT_PTR_UINT(Sine_values);
DMA1_Stream5->FCR = 0x05 ; //DMA_SxFCR_DMDIS | DMA_SxFCR_FTH_0 ;
// DMA1_Stream5->NDTR = 100 ;
AUDIO_DMA_Stream->PAR = CONVERT_PTR_UINT(&DAC->DHR12R1);
// AUDIO_DMA_Stream->M0AR = CONVERT_PTR_UINT(Sine_values);
AUDIO_DMA_Stream->FCR = 0x05 ; //DMA_SxFCR_DMDIS | DMA_SxFCR_FTH_0 ;
// AUDIO_DMA_Stream->NDTR = 100 ;
DAC->DHR12R1 = 2010 ;
DAC->SR = DAC_SR_DMAUDR1 ; // Write 1 to clear flag
DAC->CR = DAC_CR_TEN1 | DAC_CR_EN1 ; // Enable DAC
NVIC_EnableIRQ(TIM6_DAC_IRQn); // TODO needed?
NVIC_SetPriority(TIM6_DAC_IRQn, 7);
NVIC_EnableIRQ(DMA1_Stream5_IRQn);
NVIC_SetPriority(DMA1_Stream5_IRQn, 7);
NVIC_EnableIRQ(AUDIO_TIM_IRQn); // TODO needed?
NVIC_SetPriority(AUDIO_TIM_IRQn, 7);
NVIC_EnableIRQ(AUDIO_DMA_Stream_IRQn);
NVIC_SetPriority(AUDIO_DMA_Stream_IRQn, 7);
}
bool audioPushBuffer(AudioBuffer * buffer)
{
if (dacIdle) {
dacIdle = false;
DMA1_Stream5->CR &= ~DMA_SxCR_EN ; // Disable DMA channel
DMA1->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5 | DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5 ; // Write ones to clear bits
DMA1_Stream5->M0AR = CONVERT_PTR_UINT(buffer->data);
DMA1_Stream5->NDTR = buffer->size;
DMA1_Stream5->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE ; // Enable DMA channel and interrupt
AUDIO_DMA_Stream->CR &= ~DMA_SxCR_EN ; // Disable DMA channel
AUDIO_DMA->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5 | DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5 ; // Write ones to clear bits
AUDIO_DMA_Stream->M0AR = CONVERT_PTR_UINT(buffer->data);
AUDIO_DMA_Stream->NDTR = buffer->size;
AUDIO_DMA_Stream->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE ; // Enable DMA channel and interrupt
DAC->SR = DAC_SR_DMAUDR1 ; // Write 1 to clear flag
DAC->CR |= DAC_CR_EN1 | DAC_CR_DMAEN1 ; // Enable DAC
return true;
@ -97,15 +91,15 @@ bool audioPushBuffer(AudioBuffer * buffer)
void dacStart()
{
DMA1->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5 | DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5 ; // Write ones to clear bits
DMA1_Stream5->CR |= DMA_SxCR_CIRC | DMA_SxCR_EN ; // Enable DMA channel
AUDIO_DMA->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5 | DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5 ; // Write ones to clear bits
AUDIO_DMA_Stream->CR |= DMA_SxCR_CIRC | DMA_SxCR_EN ; // Enable DMA channel
DAC->SR = DAC_SR_DMAUDR1 ; // Write 1 to clear flag
DAC->CR |= DAC_CR_EN1 | DAC_CR_DMAEN1 ; // Enable DAC
}
void dacStop()
{
DMA1_Stream5->CR &= ~DMA_SxCR_CIRC ;
AUDIO_DMA_Stream->CR &= ~DMA_SxCR_CIRC ;
}
@ -118,13 +112,13 @@ void audioInit()
void audioEnd()
{
DAC->CR = 0 ;
TIM6->CR1 = 0 ;
AUDIO_TIMER->CR1 = 0 ;
// Also need to turn off any possible interrupts
NVIC_DisableIRQ(TIM6_DAC_IRQn) ;
NVIC_DisableIRQ(DMA1_Stream5_IRQn) ;
NVIC_DisableIRQ(AUDIO_TIM_IRQn) ;
NVIC_DisableIRQ(AUDIO_DMA_Stream_IRQn) ;
}
extern "C" void TIM6_DAC_IRQHandler()
extern "C" void AUDIO_TIM_IRQHandler()
{
DAC->CR &= ~DAC_CR_DMAEN1 ; // Stop DMA requests
#if !defined(REV9E)
@ -133,18 +127,18 @@ extern "C" void TIM6_DAC_IRQHandler()
DAC->SR = DAC_SR_DMAUDR1 ; // Write 1 to clear flag
}
extern "C" void DMA1_Stream5_IRQHandler()
extern "C" void AUDIO_DMA_Stream_IRQHandler()
{
DMA1_Stream5->CR &= ~DMA_SxCR_TCIE ; // Stop interrupt
DMA1->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5 | DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5 ; // Write ones to clear flags
DMA1_Stream5->CR &= ~DMA_SxCR_EN ; // Disable DMA channel
AUDIO_DMA_Stream->CR &= ~DMA_SxCR_TCIE ; // Stop interrupt
AUDIO_DMA->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5 | DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5 ; // Write ones to clear flags
AUDIO_DMA_Stream->CR &= ~DMA_SxCR_EN ; // Disable DMA channel
AudioBuffer * nextBuffer = audioQueue.getNextFilledBuffer();
if (nextBuffer) {
DMA1_Stream5->M0AR = CONVERT_PTR_UINT(nextBuffer->data);
DMA1_Stream5->NDTR = nextBuffer->size;
DMA1->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5 | DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5 ; // Write ones to clear bits
DMA1_Stream5->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE ; // Enable DMA channel
AUDIO_DMA_Stream->M0AR = CONVERT_PTR_UINT(nextBuffer->data);
AUDIO_DMA_Stream->NDTR = nextBuffer->size;
AUDIO_DMA->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5 | DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5 ; // Write ones to clear bits
AUDIO_DMA_Stream->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE ; // Enable DMA channel
DAC->SR = DAC_SR_DMAUDR1; // Write 1 to clear flag
}
else {

View file

@ -41,7 +41,11 @@ void watchdogInit(unsigned int duration)
void getCPUUniqueID(char * s)
{
#if defined(SIMU)
uint32_t cpu_uid[3] = { 0x12345678, 0x55AA55AA, 0x87654321};
#else
uint32_t * cpu_uid = (uint32_t *)0x1FFF7A10;
#endif
char * tmp = strAppendUnsigned(s, cpu_uid[0], 8, 16);
*tmp = ' ';
tmp = strAppendUnsigned(tmp+1, cpu_uid[1], 8, 16);
@ -121,8 +125,8 @@ extern "C" void INTERRUPT_5MS_IRQHandler()
void boardInit()
{
RCC_AHB1PeriphClockCmd(PWR_RCC_AHB1Periph | KEYS_RCC_AHB1Periph | LCD_RCC_AHB1Periph | BACKLIGHT_RCC_AHB1Periph | ADC_RCC_AHB1Periph | I2C_RCC_AHB1Periph | SD_RCC_AHB1Periph | HAPTIC_RCC_AHB1Periph | INTMODULE_RCC_AHB1Periph | EXTMODULE_RCC_AHB1Periph | TELEMETRY_RCC_AHB1Periph | SERIAL_RCC_AHB1Periph | TRAINER_RCC_AHB1Periph | HEARTBEAT_RCC_AHB1Periph, ENABLE);
RCC_APB1PeriphClockCmd(LCD_RCC_APB1Periph | BACKLIGHT_RCC_APB1Periph | INTERRUPT_5MS_APB1Periph | TIMER_2MHz_APB1Periph | I2C_RCC_APB1Periph | SD_RCC_APB1Periph | TRAINER_RCC_APB1Periph | TELEMETRY_RCC_APB1Periph | SERIAL_RCC_APB1Periph, ENABLE);
RCC_AHB1PeriphClockCmd(PWR_RCC_AHB1Periph | KEYS_RCC_AHB1Periph | LCD_RCC_AHB1Periph | AUDIO_RCC_AHB1Periph | BACKLIGHT_RCC_AHB1Periph | ADC_RCC_AHB1Periph | I2C_RCC_AHB1Periph | SD_RCC_AHB1Periph | HAPTIC_RCC_AHB1Periph | INTMODULE_RCC_AHB1Periph | EXTMODULE_RCC_AHB1Periph | TELEMETRY_RCC_AHB1Periph | SERIAL_RCC_AHB1Periph | TRAINER_RCC_AHB1Periph | HEARTBEAT_RCC_AHB1Periph, ENABLE);
RCC_APB1PeriphClockCmd(LCD_RCC_APB1Periph | AUDIO_RCC_APB1Periph | BACKLIGHT_RCC_APB1Periph | INTERRUPT_5MS_APB1Periph | TIMER_2MHz_APB1Periph | I2C_RCC_APB1Periph | SD_RCC_APB1Periph | TRAINER_RCC_APB1Periph | TELEMETRY_RCC_APB1Periph | SERIAL_RCC_APB1Periph, ENABLE);
RCC_APB2PeriphClockCmd(BACKLIGHT_RCC_APB2Periph | ADC_RCC_APB2Periph | HAPTIC_RCC_APB2Periph | INTMODULE_RCC_APB2Periph | EXTMODULE_RCC_APB2Periph | HEARTBEAT_RCC_APB2Periph, ENABLE);
#if !defined(REV9E)
@ -312,3 +316,11 @@ void checkTrainerSettings()
}
}
}
uint16_t getBatteryVoltage()
{
int32_t instant_vbat = anaIn(TX_VOLTAGE); // using filtered ADC value on purpose
instant_vbat = (instant_vbat * BATT_SCALE * (128 + g_eeGeneral.txVoltageCalibration) ) / 26214;
instant_vbat += 20; // add 0.2V because of the diode TODO check if this is needed, but removal will beak existing calibrations!!!
return (uint16_t)instant_vbat;
}

View file

@ -2,7 +2,7 @@
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
@ -212,6 +212,7 @@ void stop_cppm_on_heartbeat_capture(void);
void init_sbus_on_heartbeat_capture(void);
void stop_sbus_on_heartbeat_capture(void);
void set_trainer_ppm_parameters(uint32_t idleTime, uint32_t delay, uint32_t positive);
int sbusGetByte(uint8_t * byte);
// Keys driver
void keysInit(void);
@ -267,6 +268,7 @@ void adcInit(void);
void adcRead(void);
extern uint16_t adcValues[NUMBER_ANALOG];
uint16_t getAnalogValue(uint8_t index);
uint16_t getBatteryVoltage(); // returns current battery voltage in 10mV steps
#define BATT_SCALE 150
@ -322,7 +324,9 @@ void debugPutc(const char c);
// Telemetry driver
void telemetryPortInit(uint32_t baudrate);
void telemetryPortSetDirectionOutput(void);
void sportSendBuffer(uint8_t *buffer, uint32_t count);
void sportSendBuffer(uint8_t * buffer, uint32_t count);
int telemetryGetByte(uint8_t * byte);
extern uint32_t telemetryErrors;
// Audio driver
void audioInit(void) ;
@ -348,6 +352,7 @@ void hapticOff(void);
// Second serial port driver
#define DEBUG_BAUDRATE 115200
extern uint8_t serial2Mode;
void serial2Init(unsigned int mode, unsigned int protocol);
void serial2Putc(char c);
#define serial2TelemetryInit(protocol) serial2Init(UART_MODE_TELEMETRY, protocol)
@ -391,4 +396,12 @@ void usbJoystickUpdate(void);
extern uint8_t currentTrainerMode;
void checkTrainerSettings(void);
#if defined(__cplusplus)
#include "fifo.h"
#include "dmafifo.h"
extern Fifo<uint8_t, 32> telemetryFifo;
extern DMAFifo<32> serial2RxFifo;
extern Fifo<uint8_t, 32> sbusFifo;
#endif
#endif // _BOARD_TARANIS_H_

View file

@ -2,7 +2,7 @@
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
@ -375,12 +375,14 @@
#define SERIAL_USART USART3
#define SERIAL_USART_IRQHandler USART3_IRQHandler
#define SERIAL_USART_IRQn USART3_IRQn
#define SERIAL_DMA_Stream_RX DMA1_Stream1
#define SERIAL_DMA_Channel_RX DMA_Channel_4
// Telemetry
#define TELEMETRY_RCC_AHB1Periph RCC_AHB1Periph_GPIOD
#define TELEMETRY_RCC_AHB1Periph (RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_DMA1)
#define TELEMETRY_RCC_APB1Periph RCC_APB1Periph_USART2
#define TELEMETRY_GPIO_DIR GPIOD
#define TELEMETRY_DIR_GPIO_PIN GPIO_Pin_4 // PD.04
#define TELEMETRY_RCC_APB1Periph RCC_APB1Periph_USART2
#define TELEMETRY_GPIO GPIOD
#define TELEMETRY_TX_GPIO_PIN GPIO_Pin_5 // PD.05
#define TELEMETRY_RX_GPIO_PIN GPIO_Pin_6 // PD.06
@ -388,6 +390,11 @@
#define TELEMETRY_GPIO_PinSource_RX GPIO_PinSource6
#define TELEMETRY_GPIO_AF GPIO_AF_USART2
#define TELEMETRY_USART USART2
#define TELEMETRY_DMA_Stream_TX DMA1_Stream6
#define TELEMETRY_DMA_Channel_TX DMA_Channel_4
#define TELEMETRY_DMA_TX_Stream_IRQ DMA1_Stream6_IRQn
#define TELEMETRY_DMA_TX_IRQHandler DMA1_Stream6_IRQHandler
#define TELEMETRY_DMA_TX_FLAG_TC DMA_IT_TCIF6
#define TELEMETRY_USART_IRQHandler USART2_IRQHandler
#define TELEMETRY_USART_IRQn USART2_IRQn
@ -400,6 +407,8 @@
#define HEARTBEAT_USART USART6
#define HEARTBEAT_USART_IRQHandler USART6_IRQHandler
#define HEARTBEAT_USART_IRQn USART6_IRQn
#define HEARTBEAT_DMA_Stream DMA2_Stream2
#define HEARTBEAT_DMA_Channel DMA_Channel_5
// USB
#define USB_RCC_AHB1Periph_GPIO RCC_AHB1Periph_GPIOA
@ -481,7 +490,7 @@
#define LCD_GPIO_PIN_NCS GPIO_Pin_14 // PD.14
#define LCD_GPIO_PIN_A0 GPIO_Pin_13 // PD.13
#define LCD_GPIO_PIN_RST GPIO_Pin_12 // PD.12
#endif
#endif
// I2C Bus: EEPROM and CAT5137 digital pot for volume control
#define I2C_RCC_AHB1Periph RCC_AHB1Periph_GPIOB
@ -530,6 +539,17 @@
#define SD_DMA_Channel_SPI DMA_Channel_0
#endif
// Audio
#define AUDIO_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_DMA1)
#define AUDIO_RCC_APB1Periph (RCC_APB1Periph_TIM6 | RCC_APB1Periph_DAC)
#define AUDIO_DMA_Stream DMA1_Stream5
#define AUDIO_DMA_Stream_IRQn DMA1_Stream5_IRQn
#define AUDIO_TIM_IRQn TIM6_DAC_IRQn
#define AUDIO_TIM_IRQHandler TIM6_DAC_IRQHandler
#define AUDIO_DMA_Stream_IRQHandler DMA1_Stream5_IRQHandler
#define AUDIO_TIMER TIM6
#define AUDIO_DMA DMA1
// Haptic
#if defined(REVPLUS)
#define HAPTIC_RCC_AHB1Periph RCC_AHB1Periph_GPIOB

View file

@ -1,31 +1,30 @@
/*
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* 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.
*/
#include "../../opentx.h"
/*
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* 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.
*/
#include "opentx.h"
uint8_t serial2Mode = 0;
Fifo<uint8_t, 512> serial2TxFifo;
extern Fifo<uint8_t, 512> telemetryFifo;
extern Fifo<uint8_t, 32> sbusFifo;
DMAFifo<32> serial2RxFifo __DMA (SERIAL_DMA_Stream_RX);
void uart3Setup(unsigned int baudrate)
void uart3Setup(unsigned int baudrate, bool dma)
{
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
@ -39,42 +38,70 @@ void uart3Setup(unsigned int baudrate)
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(SERIAL_GPIO, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = baudrate;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_Init(SERIAL_USART, &USART_InitStructure);
USART_Cmd(SERIAL_USART, ENABLE);
USART_ITConfig(SERIAL_USART, USART_IT_RXNE, ENABLE);
USART_ITConfig(SERIAL_USART, USART_IT_TXE, DISABLE);
NVIC_SetPriority(SERIAL_USART_IRQn, 7);
NVIC_EnableIRQ(SERIAL_USART_IRQn);
if (dma) {
DMA_InitTypeDef DMA_InitStructure;
serial2RxFifo.clear();
USART_ITConfig(SERIAL_USART, USART_IT_RXNE, DISABLE);
USART_ITConfig(SERIAL_USART, USART_IT_TXE, DISABLE);
DMA_InitStructure.DMA_Channel = SERIAL_DMA_Channel_RX;
DMA_InitStructure.DMA_PeripheralBaseAddr = CONVERT_PTR_UINT(&SERIAL_USART->DR);
DMA_InitStructure.DMA_Memory0BaseAddr = CONVERT_PTR_UINT(serial2RxFifo.buffer());
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = serial2RxFifo.size();
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(SERIAL_DMA_Stream_RX, &DMA_InitStructure);
USART_DMACmd(SERIAL_USART, USART_DMAReq_Rx, ENABLE);
USART_Cmd(SERIAL_USART, ENABLE);
DMA_Cmd(SERIAL_DMA_Stream_RX, ENABLE);
}
else {
#if !defined(USB_SERIAL) && defined(CLI)
USART_Cmd(SERIAL_USART, ENABLE);
USART_ITConfig(SERIAL_USART, USART_IT_RXNE, ENABLE);
USART_ITConfig(SERIAL_USART, USART_IT_TXE, DISABLE);
NVIC_SetPriority(SERIAL_USART_IRQn, 7);
NVIC_EnableIRQ(SERIAL_USART_IRQn);
#endif
}
}
void serial2Init(unsigned int mode, unsigned int protocol)
{
USART_DeInit(SERIAL_USART);
serial2Stop();
serial2Mode = mode;
switch (mode) {
case UART_MODE_TELEMETRY_MIRROR:
uart3Setup(FRSKY_SPORT_BAUDRATE);
uart3Setup(FRSKY_SPORT_BAUDRATE, false);
break;
#if !defined(USB_SERIAL) && (defined(DEBUG) || defined(CLI))
case UART_MODE_DEBUG:
uart3Setup(DEBUG_BAUDRATE);
uart3Setup(DEBUG_BAUDRATE, false);
break;
#endif
case UART_MODE_TELEMETRY:
if (protocol == PROTOCOL_FRSKY_D_SECONDARY) {
uart3Setup(FRSKY_D_BAUDRATE);
uart3Setup(FRSKY_D_BAUDRATE, true);
}
break;
}
@ -89,12 +116,13 @@ void serial2Putc(char c)
void serial2SbusInit()
{
uart3Setup(SBUS_BAUDRATE);
uart3Setup(SBUS_BAUDRATE, true);
SERIAL_USART->CR1 |= USART_CR1_M | USART_CR1_PCE ;
}
void serial2Stop()
{
DMA_DeInit(SERIAL_DMA_Stream_RX);
USART_DeInit(SERIAL_USART);
}
@ -122,29 +150,21 @@ extern "C" void SERIAL_USART_IRQHandler(void)
}
}
#if !defined(USB_SERIAL) && defined(CLI)
// Receive
uint32_t status = SERIAL_USART->SR;
while (status & (USART_FLAG_RXNE | USART_FLAG_ERRORS)) {
uint8_t data = SERIAL_USART->DR;
if (!(status & USART_FLAG_ERRORS)) {
switch (serial2Mode) {
case UART_MODE_TELEMETRY:
telemetryFifo.push(data);
break;
case UART_MODE_SBUS_TRAINER:
sbusFifo.push(data);
break;
#if !defined(USB_SERIAL) && defined(CLI)
case UART_MODE_DEBUG:
cliRxFifo.push(data);
break;
#endif
}
}
status = SERIAL_USART->SR;
}
}
#endif
}
#endif

View file

@ -2,7 +2,7 @@
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
@ -18,9 +18,10 @@
* GNU General Public License for more details.
*/
#include "../../opentx.h"
#include "opentx.h"
extern Fifo<uint8_t, 512> telemetryFifo;
Fifo<uint8_t, 32> telemetryFifo;
uint32_t telemetryErrors = 0;
void telemetryPortInit(uint32_t baudrate)
{
@ -29,6 +30,13 @@ void telemetryPortInit(uint32_t baudrate)
return;
}
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TELEMETRY_DMA_TX_Stream_IRQ;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; /* Not used as 4 bits are used for the pre-emption priority. */;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
@ -41,7 +49,7 @@ void telemetryPortInit(uint32_t baudrate)
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(TELEMETRY_GPIO, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = TELEMETRY_DIR_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
@ -54,21 +62,13 @@ void telemetryPortInit(uint32_t baudrate)
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_Init(TELEMETRY_USART, &USART_InitStructure);
USART_Cmd(TELEMETRY_USART, ENABLE);
USART_ITConfig(TELEMETRY_USART, USART_IT_RXNE, ENABLE);
NVIC_SetPriority(TELEMETRY_USART_IRQn, 6);
NVIC_EnableIRQ(TELEMETRY_USART_IRQn);
}
struct SportTxBuffer
{
uint8_t *ptr;
uint32_t count;
} sportTxBuffer;
void telemetryPortSetDirectionOutput()
{
TELEMETRY_GPIO_DIR->BSRRL = TELEMETRY_DIR_GPIO_PIN; // output enable
@ -83,47 +83,69 @@ void telemetryPortSetDirectionInput()
void sportSendBuffer(uint8_t * buffer, uint32_t count)
{
sportTxBuffer.ptr = buffer;
sportTxBuffer.count = count;
telemetryPortSetDirectionOutput();
TELEMETRY_USART->CR1 |= USART_CR1_TXEIE;
DMA_InitTypeDef DMA_InitStructure;
DMA_DeInit(TELEMETRY_DMA_Stream_TX);
DMA_InitStructure.DMA_Channel = TELEMETRY_DMA_Channel_TX;
DMA_InitStructure.DMA_PeripheralBaseAddr = CONVERT_PTR_UINT(&TELEMETRY_USART->DR);
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
DMA_InitStructure.DMA_Memory0BaseAddr = CONVERT_PTR_UINT(buffer);
DMA_InitStructure.DMA_BufferSize = count;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(TELEMETRY_DMA_Stream_TX, &DMA_InitStructure);
DMA_Cmd(TELEMETRY_DMA_Stream_TX, ENABLE);
USART_DMACmd(TELEMETRY_USART, USART_DMAReq_Tx, ENABLE);
DMA_ITConfig(TELEMETRY_DMA_Stream_TX, DMA_IT_TC, ENABLE);
// enable interrupt and set it's priority
NVIC_EnableIRQ(TELEMETRY_DMA_TX_Stream_IRQ) ;
NVIC_SetPriority(TELEMETRY_DMA_TX_Stream_IRQ, 7);
}
#if !defined(SIMU)
#define USART_FLAG_ERRORS (USART_FLAG_ORE | USART_FLAG_NE | USART_FLAG_FE | USART_FLAG_PE)
extern "C" void TELEMETRY_USART_IRQHandler()
extern "C" void TELEMETRY_DMA_TX_IRQHandler(void)
{
uint32_t status;
uint8_t data;
status = TELEMETRY_USART->SR;
if (status & USART_SR_TXE) {
if (sportTxBuffer.count) {
TELEMETRY_USART->DR = *sportTxBuffer.ptr++;
if (--sportTxBuffer.count == 0) {
TELEMETRY_USART->CR1 &= ~USART_CR1_TXEIE; // stop Tx interrupt
TELEMETRY_USART->CR1 |= USART_CR1_TCIE; // enable complete interrupt
}
}
}
if ((status & USART_SR_TC) && (TELEMETRY_USART->CR1 & USART_CR1_TCIE)) {
TELEMETRY_USART->CR1 &= ~USART_CR1_TCIE ; // stop Complete interrupt
if (DMA_GetITStatus(TELEMETRY_DMA_Stream_TX, TELEMETRY_DMA_TX_FLAG_TC)) {
DMA_ClearITPendingBit(TELEMETRY_DMA_Stream_TX, TELEMETRY_DMA_TX_FLAG_TC);
telemetryPortSetDirectionInput();
while (status & (USART_FLAG_RXNE)) {
status = TELEMETRY_USART->DR;
status = TELEMETRY_USART->SR;
}
}
}
#define USART_FLAG_ERRORS (USART_FLAG_ORE | USART_FLAG_NE | USART_FLAG_FE | USART_FLAG_PE)
extern "C" void TELEMETRY_USART_IRQHandler(void)
{
uint32_t status = TELEMETRY_USART->SR;
while (status & (USART_FLAG_RXNE | USART_FLAG_ERRORS)) {
data = TELEMETRY_USART->DR;
if (!(status & USART_FLAG_ERRORS)) {
uint8_t data = TELEMETRY_USART->DR;
if (status & USART_FLAG_ERRORS) {
telemetryErrors++;
}
else {
telemetryFifo.push(data);
}
status = TELEMETRY_USART->SR;
}
}
#endif
// TODO we should have telemetry in an higher layer, functions above should move to a sport_driver.cpp
int telemetryGetByte(uint8_t * byte)
{
if (telemetryProtocol == PROTOCOL_FRSKY_D_SECONDARY) {
if (serial2Mode == UART_MODE_TELEMETRY)
return serial2RxFifo.pop(*byte);
else
return 0;
}
else {
return telemetryFifo.pop(*byte);
}
}

View file

@ -2,7 +2,7 @@
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
@ -18,9 +18,9 @@
* GNU General Public License for more details.
*/
#include "../../opentx.h"
#include "opentx.h"
extern Fifo<uint8_t, 32> sbusFifo;
DMAFifo<32> heartbeatFifo __DMA (HEARTBEAT_DMA_Stream);
#define setupTrainerPulses() setupPulsesPPM(TRAINER_MODULE)
@ -177,7 +177,7 @@ void stop_cppm_on_heartbeat_capture(void)
TRAINER_TIMER->CR1 &= ~TIM_CR1_CEN; // Stop counter
NVIC_DisableIRQ(TRAINER_TIMER_IRQn); // Stop Interrupt
if (!IS_PULSES_EXTERNAL_MODULE()) {
if (!IS_EXTERNAL_MODULE_PRESENT()) {
EXTERNAL_MODULE_OFF();
}
}
@ -204,13 +204,31 @@ void init_sbus_on_heartbeat_capture()
USART_InitStructure.USART_Parity = USART_Parity_Even;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx;
USART_Init(HEARTBEAT_USART, &USART_InitStructure);
USART_Cmd(HEARTBEAT_USART, ENABLE);
USART_ITConfig(HEARTBEAT_USART, USART_IT_RXNE, ENABLE);
NVIC_SetPriority(HEARTBEAT_USART_IRQn, 6);
NVIC_EnableIRQ(HEARTBEAT_USART_IRQn);
DMA_InitTypeDef DMA_InitStructure;
heartbeatFifo.clear();
USART_ITConfig(HEARTBEAT_USART, USART_IT_RXNE, DISABLE);
USART_ITConfig(HEARTBEAT_USART, USART_IT_TXE, DISABLE);
DMA_InitStructure.DMA_Channel = HEARTBEAT_DMA_Channel;
DMA_InitStructure.DMA_PeripheralBaseAddr = CONVERT_PTR_UINT(&HEARTBEAT_USART->DR);
DMA_InitStructure.DMA_Memory0BaseAddr = CONVERT_PTR_UINT(heartbeatFifo.buffer());
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = heartbeatFifo.size();
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(HEARTBEAT_DMA_Stream, &DMA_InitStructure);
USART_DMACmd(HEARTBEAT_USART, USART_DMAReq_Rx, ENABLE);
USART_Cmd(HEARTBEAT_USART, ENABLE);
DMA_Cmd(HEARTBEAT_DMA_Stream, ENABLE);
}
void stop_sbus_on_heartbeat_capture(void)
@ -218,28 +236,19 @@ void stop_sbus_on_heartbeat_capture(void)
configure_pins(HEARTBEAT_GPIO_PIN, PIN_INPUT | PIN_PORTC);
NVIC_DisableIRQ(HEARTBEAT_USART_IRQn);
if (!IS_PULSES_EXTERNAL_MODULE()) {
if (!IS_EXTERNAL_MODULE_PRESENT()) {
EXTERNAL_MODULE_OFF();
}
}
#if !defined(SIMU) && !defined(REV9E)
extern "C" void HEARTBEAT_USART_IRQHandler()
int sbusGetByte(uint8_t * byte)
{
uint32_t status;
uint8_t data;
status = HEARTBEAT_USART->SR;
while (status & (USART_FLAG_RXNE | USART_FLAG_ERRORS)) {
data = HEARTBEAT_USART->DR;
if (!(status & USART_FLAG_ERRORS)) {
if (currentTrainerMode == TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE)
sbusFifo.push(data);
}
status = HEARTBEAT_USART->SR;
switch (currentTrainerMode) {
case TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE:
return heartbeatFifo.pop(*byte);
case TRAINER_MODE_MASTER_BATTERY_COMPARTMENT:
return serial2RxFifo.pop(*byte);
default:
return false;
}
}
#endif

View file

@ -43,10 +43,6 @@ uint8_t frskyTxBufferCount = 0;
uint8_t telemetryState = TELEMETRY_INIT;
#endif
#if defined(PCBTARANIS) || defined(PCBFLAMENCO) || defined(PCBHORUS)
Fifo<uint8_t, 512> telemetryFifo; // TODO should be in the driver
#endif
uint8_t frskyRxBufferCount = 0;
FrskyData frskyData;

View file

@ -337,9 +337,9 @@ bool sportWaitState(SportUpdateState state, int timeout)
return true;
#else
for (int i=timeout/2; i>=0; i--) {
uint8_t data ;
while (telemetryFifo.pop(data)) {
processSerialData(data);
uint8_t byte ;
while (telemetryGetByte(&byte)) {
processSerialData(byte);
}
if (sportUpdateState == state) {
return true;
@ -358,7 +358,7 @@ void blankPacket(uint8_t *packet)
memset(packet+2, 0, 6);
}
uint8_t sportUpdatePacket[16];
uint8_t sportUpdatePacket[16] __DMA;
void writePacket(uint8_t * packet)
{

View file

@ -2,7 +2,7 @@
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
@ -21,8 +21,6 @@
#ifndef _TELEMETRY_H_
#define _TELEMETRY_H_
extern Fifo<uint8_t, 512> telemetryFifo;
enum TelemetryProtocol
{
TELEM_PROTO_FRSKY_D,

View file

@ -194,16 +194,6 @@ TEST(Lcd, vline_x_lt0)
#endif
#if defined(CPUARM)
TEST(Lcd, SmlsizeDecimalPoint)
{
lcdClear();
lcdDrawNumber(0, 1, 105, PREC1|SMLSIZE|LEFT);
lcdDrawNumber(0, LCD_H-7, 105, PREC1|SMLSIZE|LEFT|INVERS);
lcdDrawNumber(LCD_W, 1, 105, PREC2|SMLSIZE);
lcdDrawNumber(LCD_W, LCD_H-7, 105, PREC2|SMLSIZE|INVERS);
EXPECT_TRUE(checkScreenshot("SmlsizeDecimalPoint"));
}
TEST(Lcd, Smlsize)
{
lcdClear();