Merge pull request #495 from EdgeTX/main

Merge from main
This commit is contained in:
richardclli
2021-07-24 00:23:37 +08:00
committed by GitHub
49 changed files with 2395 additions and 474 deletions
+2
View File
@@ -4,12 +4,14 @@ on:
push:
branches:
- '2.4'
- 'main'
paths-ignore:
- '**.md'
- '.github/ISSUE_TEMPLATE/**'
pull_request:
branches:
- '2.4'
- 'main'
paths-ignore:
- '**.md'
- '.github/ISSUE_TEMPLATE/**'
+2 -2
View File
@@ -1,7 +1,7 @@
project(OpenTX)
set(VERSION_MAJOR "2")
set(VERSION_MINOR "4")
set(VERSION_MINOR "5")
set(VERSION_REVISION "0")
set(VERSION_SUFFIX $ENV{OPENTX_VERSION_SUFFIX})
set(VERSION_FAMILY ${VERSION_MAJOR}.${VERSION_MINOR})
@@ -47,7 +47,7 @@ today(DATE)
now(TIME)
git_id(GIT_STR)
message(STATUS "OpenTX ${VERSION} @ ${GIT_STR}")
message(STATUS "EdgeTX ${VERSION} @ ${GIT_STR}")
# options shared by all targets
+16
View File
@@ -672,6 +672,22 @@ PACK(struct ModelData {
return thrTrimSw + MIXSRC_FIRST_TRIM;
}
}
void setThrottleStickTrimSource(int16_t src)
{
// The order here is TERA, so that 0 (default) means Throttle
switch (src) {
case MIXSRC_TrimThr:
thrTrimSw = 0;
break;
case MIXSRC_TrimRud:
thrTrimSw = 2;
break;
default:
thrTrimSw = src - MIXSRC_FIRST_TRIM;
break;
}
}
});
/*
+7 -6
View File
@@ -631,12 +631,13 @@ void menuModelSetup(event_t event)
case ITEM_MODEL_SETUP_THROTTLE_TRACE:
{
lcdDrawTextAlignedLeft(y, STR_TTRACE);
if (attr) CHECK_INCDEC_MODELVAR_ZERO(event, g_model.thrTraceSrc, NUM_POTS+NUM_SLIDERS+MAX_OUTPUT_CHANNELS);
uint8_t idx = g_model.thrTraceSrc + MIXSRC_Thr;
if (idx > MIXSRC_Thr)
idx += 1;
if (idx >= MIXSRC_FIRST_POT+NUM_POTS+NUM_SLIDERS)
idx += MIXSRC_CH1 - MIXSRC_FIRST_POT - NUM_POTS - NUM_SLIDERS;
if (attr)
CHECK_INCDEC_MODELVAR_ZERO_CHECK(
event, g_model.thrTraceSrc,
NUM_POTS + NUM_SLIDERS + MAX_OUTPUT_CHANNELS,
isThrottleSourceAvailable);
uint8_t idx = throttleSource2Source(g_model.thrTraceSrc);
drawSource(MODEL_SETUP_2ND_COLUMN, y, idx, attr);
break;
}
+7 -6
View File
@@ -606,12 +606,13 @@ void menuModelSetup(event_t event)
case ITEM_MODEL_SETUP_THROTTLE_TRACE:
{
lcdDrawTextAlignedLeft(y, STR_TTRACE);
if (attr) CHECK_INCDEC_MODELVAR_ZERO_CHECK(event, g_model.thrTraceSrc, NUM_POTS+NUM_SLIDERS+MAX_OUTPUT_CHANNELS, isThrottleSourceAvailable);
uint8_t idx = g_model.thrTraceSrc + MIXSRC_Thr;
if (idx > MIXSRC_Thr)
idx += 1;
if (idx >= MIXSRC_FIRST_POT+NUM_POTS+NUM_SLIDERS)
idx += MIXSRC_CH1 - MIXSRC_FIRST_POT - NUM_POTS - NUM_SLIDERS;
if (attr)
CHECK_INCDEC_MODELVAR_ZERO_CHECK(
event, g_model.thrTraceSrc,
NUM_POTS + NUM_SLIDERS + MAX_OUTPUT_CHANNELS,
isThrottleSourceAvailable);
uint8_t idx = throttleSource2Source(g_model.thrTraceSrc);
drawSource(MODEL_SETUP_2ND_COLUMN, y, idx, attr);
break;
}
+1
View File
@@ -77,6 +77,7 @@ endmacro(add_gui_src)
if(LUA)
add_gui_src(standalone_lua.cpp)
add_gui_src(model_mixer_scripts.cpp)
endif()
if(HELI)
+3 -1
View File
@@ -27,6 +27,9 @@
// TODO common code, not in target
enum LcdColorIndex
{
// this one first for when colour is not set
DEFAULT_COLOR_INDEX,
ALARM_COLOR_INDEX,
BARGRAPH1_COLOR_INDEX,
BARGRAPH2_COLOR_INDEX,
@@ -38,7 +41,6 @@ enum LcdColorIndex
CURVE_CURSOR_COLOR_INDEX,
CUSTOM_COLOR_INDEX,
DEFAULT_BGCOLOR_INDEX,
DEFAULT_COLOR_INDEX,
DISABLE_COLOR_INDEX,
EDIT_MARKER_COLOR_INDEX,
FIELD_BGCOLOR_INDEX,
+8 -1
View File
@@ -416,6 +416,12 @@ void drawSensorCustomValue(BitmapBuffer * dc, coord_t x, coord_t y, uint8_t sens
}
}
// libopemui defines TIMOUR as zero
#if !TIMHOUR
#undef TIMEHOUR
#define TIMEHOUR 0x2000
#endif
void drawTimer(BitmapBuffer * dc, coord_t x, coord_t y, int32_t tme, LcdFlags flags)
{
char str[LEN_TIMER_STRING];
@@ -437,7 +443,8 @@ void drawSourceCustomValue(BitmapBuffer * dc, coord_t x, coord_t y, source_t sou
}
else if (source >= MIXSRC_FIRST_TIMER || source == MIXSRC_TX_TIME) {
// TODO if (value < 0) flags |= BLINK|INVERS;
// TODO drawTimer(dc, x, y, value, flags);
if (source == MIXSRC_TX_TIME) flags |= TIMEHOUR;
drawTimer(dc, x, y, value, flags);
}
else if (source == MIXSRC_TX_VOLTAGE) {
dc->drawNumber(x, y, value, flags|PREC1);
+1 -1
View File
@@ -36,7 +36,7 @@
#define GET_SET_DEFAULT(value) GET_DEFAULT(value), SET_DEFAULT(value)
#define GET_SET_INVERTED(value) GET_INVERTED(value), SET_INVERTED(value)
#define GET_SET_VALUE_WITH_OFFSET(value, offset) GET_VALUE_WITH_OFFSET(value, offset), SET_VALUE_WITH_OFFSET(value, offset)
#define GET_SET_WITH_OFFSET(value, offset) GET_VALUE_WITH_OFFSET(value, offset), SET_VALUE_WITH_OFFSET(value, offset)
#define GET_SET_WITH_OFFSET(value, offset) GET_VALUE_WITH_OFFSET(value, offset), SET_VALUE_WITH_OFFSET(value, offset)
#define GET_SET_BF(value, offset, bits) GET_VALUE_WITH_BF(value, offset, bits), SET_VALUE_WITH_BF(value, offset, bits)
#endif // _GETSET_HELPERS_H_
+14 -5
View File
@@ -25,7 +25,7 @@ void MainViewTrim::checkEvents()
{
Window::checkEvents();
int8_t stickIndex = CONVERT_MODE(idx);
int8_t newValue = getTrimValue(mixerCurrentFlightMode, stickIndex);
int newValue = getTrimValue(mixerCurrentFlightMode, stickIndex);
if (value != newValue) {
value = newValue;
invalidate();
@@ -43,6 +43,10 @@ void MainViewHorizontalTrim::paint(BitmapBuffer * dc)
trimMin = TRIM_MIN;
trimMax = TRIM_MAX;
}
int16_t dispVal = value;
if (dispVal < trimMin) dispVal = trimMin;
if (dispVal > trimMax) dispVal = trimMax;
// Trim line
dc->drawSolidFilledRect(
@@ -50,7 +54,7 @@ void MainViewHorizontalTrim::paint(BitmapBuffer * dc)
width() - TRIM_SQUARE_SIZE + 1, TRIM_LINE_WIDTH, DEFAULT_COLOR);
// Trim square
coord_t x = divRoundClosest((width() - TRIM_SQUARE_SIZE) * (value - trimMin),
coord_t x = divRoundClosest((width() - TRIM_SQUARE_SIZE) * (dispVal - trimMin),
trimMax - trimMin);
drawTrimSquare(dc, x, 0,
(value < TRIM_MIN || value > TRIM_MAX)
@@ -85,15 +89,20 @@ void MainViewVerticalTrim::paint(BitmapBuffer * dc)
trimMax = TRIM_MAX;
}
int16_t dispVal = value;
if (dispVal < trimMin) dispVal = trimMin;
if (dispVal > trimMax) dispVal = trimMax;
// Trim line
dc->drawSolidFilledRect((width() - TRIM_LINE_WIDTH) / 2, TRIM_SQUARE_SIZE / 2,
TRIM_LINE_WIDTH, height() - TRIM_SQUARE_SIZE + 1,
DEFAULT_COLOR);
// Trim square
coord_t y = height() - TRIM_SQUARE_SIZE -
divRoundClosest((height() - TRIM_SQUARE_SIZE) * (value - trimMin),
trimMax - trimMin);
coord_t y =
height() - TRIM_SQUARE_SIZE -
divRoundClosest((height() - TRIM_SQUARE_SIZE) * (dispVal - trimMin),
trimMax - trimMin);
drawTrimSquare(dc, 0, y,
(value < TRIM_MIN || value > TRIM_MAX)
? HIGHLIGHT_COLOR /* TODO add a color */
+4
View File
@@ -29,6 +29,7 @@
#include "model_gvars.h"
#include "model_curves.h"
#include "model_logical_switches.h"
#include "model_mixer_scripts.h"
#include "special_functions.h"
#include "model_telemetry.h"
@@ -47,5 +48,8 @@ ModelMenu::ModelMenu():
addTab(new ModelGVarsPage());
addTab(new ModelLogicalSwitchesPage());
addTab(new SpecialFunctionsPage(g_model.customFn));
#if defined(LUA)
addTab(new ModelMixerScriptsPage());
#endif
addTab(new ModelTelemetryPage());
}
+12 -13
View File
@@ -56,20 +56,19 @@ void copyExpo(uint8_t source, uint8_t dest, int8_t input)
pauseMixerCalculations();
ExpoData sourceExpo;
memcpy(&sourceExpo, expoAddress(source), sizeof(ExpoData));
ExpoData * expo = expoAddress(dest);
if(input == PASTE_AFTER) {
memmove(expo+2, expo+1, (MAX_EXPOS-(source+1))*sizeof(ExpoData));
memcpy(expo+1, &sourceExpo, sizeof(ExpoData));
(expo+1)->chn = (expo)->chn;
}
else if(input == PASTE_BEFORE) {
memmove(expo+1, expo, (MAX_EXPOS-(source+1))*sizeof(ExpoData));
ExpoData *expo = expoAddress(dest);
size_t trailingExpos = MAX_EXPOS - (dest + 1);
if (input == PASTE_AFTER) {
trailingExpos--;
memmove(expo + 2, expo + 1, trailingExpos * sizeof(ExpoData));
memcpy(expo + 1, &sourceExpo, sizeof(ExpoData));
(expo + 1)->chn = (expo)->chn;
} else if (input == PASTE_BEFORE) {
memmove(expo + 1, expo, trailingExpos * sizeof(ExpoData));
memcpy(expo, &sourceExpo, sizeof(ExpoData));
expo->chn = (expo+1)->chn;
}
else {
memmove(expo+1, expo, (MAX_EXPOS-(source+1))*sizeof(ExpoData));
expo->chn = (expo + 1)->chn;
} else {
memmove(expo + 1, expo, trailingExpos * sizeof(ExpoData));
memcpy(expo, &sourceExpo, sizeof(ExpoData));
expo->chn = input;
}
@@ -144,14 +144,14 @@ class LogicalSwitchEditPage: public Page
new StaticText(logicalSwitchOneWindow, grid.getLabelSlot(), STR_V1);
auto timer = new NumberEdit(logicalSwitchOneWindow, grid.getFieldSlot(), -128, 122, GET_SET_DEFAULT(cs->v1));
timer->setDisplayHandler([](BitmapBuffer * dc, LcdFlags flags, int32_t value) {
dc->drawNumber(FIELD_PADDING_LEFT, FIELD_PADDING_TOP, lswTimerValue(value), flags | PREC1);
drawTimer(dc, FIELD_PADDING_LEFT, FIELD_PADDING_TOP, value, flags);
});
grid.nextLine();
new StaticText(logicalSwitchOneWindow, grid.getLabelSlot(), STR_V2);
timer = new NumberEdit(logicalSwitchOneWindow, grid.getFieldSlot(), -128, 122, GET_SET_DEFAULT(cs->v2));
timer->setDisplayHandler([](BitmapBuffer * dc, LcdFlags flags, int32_t value) {
dc->drawNumber(FIELD_PADDING_LEFT, FIELD_PADDING_TOP, lswTimerValue(value), flags | PREC1);
drawTimer(dc, FIELD_PADDING_LEFT, FIELD_PADDING_TOP, value, flags);
});
grid.nextLine();
}
@@ -0,0 +1,314 @@
/*
* Copyright (C) EdgeTX
*
* Based on code named
* opentx - https://github.com/opentx/opentx
* 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"
#include "model_mixer_scripts.h"
#include "dataconstants.h"
#include "lua/lua_api.h"
#include "translations.h"
#include "menus.h"
#include "libopenui.h"
#include <string.h>
#define SET_DIRTY() storageDirty(EE_MODEL)
class ScriptEditWindow : public Page {
public:
explicit ScriptEditWindow(uint8_t idx) :
Page(ICON_MODEL_LUA_SCRIPTS),
idx(idx)
{
buildBody(&body);
buildHeader(&header);
}
protected:
uint8_t idx;
bool update = false;
void checkEvents() override
{
if (update) {
TRACE("rebuilding ScriptEditWindow...");
rebuildBody(&body);
update = false;
}
// note: 'update' is set from Page::checkEvents()
Page::checkEvents();
}
void buildHeader(Window * window)
{
new StaticText(window,
{PAGE_TITLE_LEFT, PAGE_TITLE_TOP, LCD_W - PAGE_TITLE_LEFT,
PAGE_LINE_HEIGHT},
STR_MENUCUSTOMSCRIPTS, 0, FOCUS_COLOR);
new StaticText(window,
{PAGE_TITLE_LEFT, PAGE_TITLE_TOP + PAGE_LINE_HEIGHT,
LCD_W - PAGE_TITLE_LEFT, PAGE_LINE_HEIGHT},
std::string("LUA") + std::to_string(idx + 1), 0, FOCUS_COLOR);
}
void buildBody(FormWindow * window, bool focusScript = false)
{
FormGridLayout grid;
grid.spacer(PAGE_PADDING);
ScriptData* sd = &(g_model.scriptsData[idx]);
// Filename
new StaticText(window, grid.getLabelSlot(), STR_SCRIPT);
auto fc = new FileChoice(
window, grid.getFieldSlot(), SCRIPTS_MIXES_PATH, SCRIPTS_EXT,
LEN_SCRIPT_FILENAME,
[=]() { return std::string(sd->file, LEN_SCRIPT_FILENAME); },
[=](std::string newValue) {
strncpy(sd->file, newValue.c_str(), LEN_SCRIPT_FILENAME);
if (newValue.empty()) { memset((void*)sd, 0, sizeof(ScriptData)); }
storageDirty(EE_MODEL);
LUA_LOAD_MODEL_SCRIPT(idx); // async reload...
update = true;
}, true);
grid.nextLine();
// Custom name
new StaticText(window, grid.getLabelSlot(), STR_NAME);
new ModelTextEdit(window, grid.getFieldSlot(), sd->name, sizeof(sd->name));
grid.nextLine();
// scriptInputsOutputs
ScriptInputsOutputs& sio = scriptInputsOutputs[idx];
if (sio.inputsCount > 0) {
new Subtitle(window, grid.getLineSlot(), STR_INPUTS);
grid.nextLine();
auto gInputs =
new FormGroup(window, grid.getFieldSlot(),
FORM_BORDER_FOCUS_ONLY | PAINT_CHILDREN_FIRST);
GridLayout inputsGrid(gInputs);
for (int i = 0; i < sio.inputsCount; i++) {
ScriptInput& si = sio.inputs[i];
new StaticText(window, grid.getLabelSlot(true), si.name);
grid.nextLine();
if (si.type == INPUT_TYPE_VALUE) {
new NumberEdit(gInputs, inputsGrid.getSlot(), si.min - si.def,
si.max - si.def,
GET_SET_WITH_OFFSET(sd->inputs[i].value, si.def));
} else {
new SourceChoice(gInputs, inputsGrid.getSlot(), 0,
MIXSRC_LAST_TELEM,
GET_SET_DEFAULT(sd->inputs[i].source));
}
inputsGrid.nextLine();
}
gInputs->setHeight(inputsGrid.getWindowHeight());
}
if (sio.outputsCount > 0) {
new Subtitle(window, grid.getLabelSlot(), STR_OUTPUTS);
grid.nextLine();
auto gOutputs =
new FormGroup(window, grid.getLineSlot(),
FORM_BORDER_FOCUS_ONLY | PAINT_CHILDREN_FIRST);
FormGridLayout outputsGrid(gOutputs->width());
for (int i = 0; i < sio.outputsCount; i++) {
ScriptOutput* so = &(sio.outputs[i]);
new DynamicText(gOutputs, outputsGrid.getLabelSlot(), [=]() {
char s[16];
getSourceString(s,
MIXSRC_FIRST_LUA + (idx * MAX_SCRIPT_OUTPUTS) + i);
return std::string(s, sizeof(s) - 1);
});
new DynamicNumber<int>(gOutputs, outputsGrid.getFieldSlot(),
[=]() { return calcRESXto1000(so->value); });
outputsGrid.nextLine();
}
gOutputs->setHeight(outputsGrid.getWindowHeight());
grid.addWindow(gOutputs);
}
window->setInnerHeight(grid.getWindowHeight());
if (focusScript) { fc->setFocus(); }
}
void rebuildBody(FormWindow * window)
{
coord_t scrollPosition = window->getScrollPositionY();
window->clear();
buildBody(window);
window->setScrollPositionY(scrollPosition);
}
};
constexpr char SCRIPT_STATUS_ERROR[] = "(error)";
constexpr char SCRIPT_STATUS_KILLED[] = "(killed)";
class ScriptLineButton : public Button
{
public:
ScriptLineButton(FormGroup* parent, const rect_t& rect,
const ScriptData& scriptData,
const ScriptInternalData* runtimeData) :
Button(parent, rect), scriptData(scriptData), runtimeData(runtimeData)
{
}
void paint(BitmapBuffer* dc) override
{
LcdFlags textColor = DEFAULT_COLOR;
LcdFlags bgColor = FIELD_BGCOLOR;
dc->drawSolidFilledRect(0, 0, width(), height(), bgColor);
if (runtimeData) {
coord_t x = 2*FIELD_PADDING_LEFT;
coord_t y = FIELD_PADDING_TOP;
x = dc->drawSizedText(x, y, scriptData.name, sizeof(scriptData.name), textColor);
x += 4*FIELD_PADDING_LEFT;
dc->drawSizedText(x, y, scriptData.file, sizeof(scriptData.file), textColor);
x = width() - 2*FIELD_PADDING_LEFT;
y = FIELD_PADDING_TOP;
textColor |= RIGHT;
switch (runtimeData->state) {
case SCRIPT_SYNTAX_ERROR:
dc->drawSizedText(x, y, SCRIPT_STATUS_ERROR,
sizeof(SCRIPT_STATUS_ERROR), textColor);
break;
case SCRIPT_KILLED:
dc->drawSizedText(x, y, SCRIPT_STATUS_KILLED,
sizeof(SCRIPT_STATUS_KILLED), textColor);
break;
default:
dc->drawNumber(x, y, runtimeData->instructions, textColor, 0, nullptr, "%");
break;
}
}
// bounding rect
if (hasFocus())
dc->drawSolidRect(0, 0, rect.w, rect.h, 2, FOCUS_BGCOLOR);
else
dc->drawSolidRect(0, 0, rect.w, rect.h, 1, FIELD_FRAME_COLOR);
}
protected:
const ScriptData& scriptData;
const ScriptInternalData* runtimeData;
};
ModelMixerScriptsPage::ModelMixerScriptsPage() :
PageTab(STR_MENUCUSTOMSCRIPTS, ICON_MODEL_LUA_SCRIPTS)
{
}
void ModelMixerScriptsPage::rebuild(FormWindow * window, int8_t focusIdx)
{
coord_t scrollPosition = window->getScrollPositionY();
window->clear();
build(window, focusIdx);
window->setScrollPositionY(scrollPosition);
}
void ModelMixerScriptsPage::build(FormWindow * window, int8_t focusIdx)
{
FormGridLayout grid;
grid.spacer(PAGE_PADDING);
grid.setLabelWidth(66);
int8_t scriptIdx = 0;
for (int8_t idx = 0; idx < MAX_SCRIPTS; idx++) {
ScriptInternalData* runtimeData = nullptr;
ScriptData &sd = g_model.scriptsData[idx];
if (sd.file[0] != '\0') {
runtimeData = &(scriptInternalData[scriptIdx++]);
}
// LUAx label
auto txt = new StaticText(window, grid.getLabelSlot(),
std::string("LUA") + std::to_string(idx + 1),
BUTTON_BACKGROUND, CENTERED);
Button* button = new ScriptLineButton(window, grid.getFieldSlot(), sd, runtimeData);
button->setPressHandler([=]() -> uint8_t {
Menu* menu = new Menu(window);
menu->addLine(STR_EDIT, [=]() { editLine(window, idx); });
if (runtimeData != nullptr) {
menu->addLine(STR_RESET, [=]() {
memset((void*)&sd, 0, sizeof(sd));
// TODO: anything else? reload scripts???
storageDirty(EE_MODEL);
rebuild(window, idx);
});
return 0;
}
return 0;
});
button->setFocusHandler([=](bool focus) {
if (focus) {
txt->setBackgroundColor(FOCUS_BGCOLOR);
txt->setTextFlags(FOCUS_COLOR | CENTERED);
} else {
txt->setBackgroundColor(FIELD_FRAME_COLOR);
txt->setTextFlags(CENTERED);
}
txt->invalidate();
});
if (focusIdx == idx) {
button->setFocus(SET_FOCUS_DEFAULT);
txt->setBackgroundColor(FOCUS_BGCOLOR);
txt->setTextFlags(FOCUS_COLOR | CENTERED);
txt->invalidate();
}
txt->setHeight(button->height());
grid.spacer(button->height() + 5);
}
grid.nextLine();
window->setInnerHeight(grid.getWindowHeight());
}
void ModelMixerScriptsPage::editLine(FormWindow * window, uint8_t idx)
{
Window::clearFocus();
Window * editWindow = new ScriptEditWindow(idx);
editWindow->setCloseHandler([=]() {
rebuild(window, idx);
});
}
@@ -0,0 +1,39 @@
/*
* Copyright (C) EdgeTX
*
* Based on code named
* opentx - https://github.com/opentx/opentx
* 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.
*/
#pragma once
#include "tabsgroup.h"
class ModelMixerScriptsPage: public PageTab {
public:
ModelMixerScriptsPage();
virtual void build(FormWindow * window) override
{
build(window, 0);
}
protected:
void build(FormWindow * window, int8_t focusIdx);
void rebuild(FormWindow * window, int8_t focusIdx);
void editLine(FormWindow * window, uint8_t idx);
};
+14 -16
View File
@@ -89,7 +89,7 @@ class MixEditWindow : public Page
// Mix name
new StaticText(window, grid.getLabelSlot(), STR_MIXNAME);
new RadioTextEdit(window, grid.getFieldSlot(), mix->name,
new ModelTextEdit(window, grid.getFieldSlot(), mix->name,
sizeof(mix->name));
grid.nextLine();
@@ -531,24 +531,22 @@ void copyMix(uint8_t source, uint8_t dest, int8_t ch)
pauseMixerCalculations();
MixData sourceMix;
memcpy(&sourceMix, mixAddress(source), sizeof(MixData));
MixData * mix = mixAddress(dest);
if(ch == PASTE_AFTER) {
memmove(mix+2, mix+1, (MAX_MIXERS-(source+1))*sizeof(MixData));
memcpy(mix+1, &sourceMix, sizeof(MixData));
(mix+1)->destCh = (mix)->destCh;
}
else if(ch == PASTE_BEFORE) {
memmove(mix+1, mix, (MAX_MIXERS-(source+1))*sizeof(MixData));
MixData *mix = mixAddress(dest);
size_t trailingMixes = MAX_MIXERS - (dest + 1);
if (ch == PASTE_AFTER) {
trailingMixes--;
memmove(mix + 2, mix + 1, trailingMixes * sizeof(MixData));
memcpy(mix + 1, &sourceMix, sizeof(MixData));
(mix + 1)->destCh = (mix)->destCh;
} else if (ch == PASTE_BEFORE) {
memmove(mix + 1, mix, trailingMixes * sizeof(MixData));
memcpy(mix, &sourceMix, sizeof(MixData));
mix->destCh = (mix+1)->destCh;
}
else {
memmove(mix+1, mix, (MAX_MIXERS-(source+1))*sizeof(MixData));
mix->destCh = (mix + 1)->destCh;
} else {
memmove(mix + 1, mix, trailingMixes * sizeof(MixData));
memcpy(mix, &sourceMix, sizeof(MixData));
mix->destCh = ch;
mix->destCh = ch;
}
//memmove(mix + 1, mix, (MAX_MIXERS - (dest + 1)) * sizeof(MixData));
resumeMixerCalculations();
storageDirty(EE_MODEL);
}
+2 -2
View File
@@ -60,7 +60,7 @@ class OutputEditWindow : public Page {
// Name
new StaticText(window, grid.getLabelSlot(), STR_NAME);
new RadioTextEdit(window, grid.getFieldSlot(), output->name, sizeof(output->name));
new ModelTextEdit(window, grid.getFieldSlot(), output->name, sizeof(output->name));
grid.nextLine();
// Offset
@@ -130,7 +130,7 @@ class OutputLineButton : public Button {
LcdFlags bgColor = FIELD_BGCOLOR;
dc->drawSolidFilledRect(0, 0, width(), height(), bgColor);
// first line
dc->drawNumber(FIELD_PADDING_LEFT, FIELD_PADDING_TOP, output->min - 1000,
PREC1 | textColor);
+2 -1
View File
@@ -245,7 +245,8 @@ class ModelCategoryPageBody : public FormWindow
modelslist.setCurrentModel(model);
modelslist.setCurrentCategory(category);
update();
this->onEvent(EVT_KEY_FIRST(KEY_EXIT));
checkAll();
});
}
menu->addLine(STR_CREATE_MODEL, getCreateModelAction());
+161 -51
View File
@@ -630,22 +630,42 @@ class ModuleWindow : public FormGroup {
// Multi type (CUSTOM, brand A, brand B,...)
int multiRfProto = g_model.moduleData[moduleIdx].getMultiProtocol();
rfChoice = new Choice(this, grid.getFieldSlot(g_model.moduleData[moduleIdx].multi.customProto ? 3 : 2, 0), STR_MULTI_PROTOCOLS, MODULE_SUBTYPE_MULTI_FIRST, MODULE_SUBTYPE_MULTI_LAST,
GET_DEFAULT(multiRfProto),
[=](int32_t newValue) {
g_model.moduleData[moduleIdx].setMultiProtocol(newValue);
g_model.moduleData[moduleIdx].subType = 0;
if (mmSubProtocol != nullptr) mmSubProtocol->invalidate();
resetMultiProtocolsOptions(moduleIdx);
SET_DIRTY();
update();
rfChoice->setFocus(SET_FOCUS_DEFAULT);
});
rfChoice = new Choice(
this,
grid.getFieldSlot(
g_model.moduleData[moduleIdx].multi.customProto ? 3 : 2, 0),
STR_MULTI_PROTOCOLS, MODULE_SUBTYPE_MULTI_FIRST,
MODULE_SUBTYPE_MULTI_LAST, GET_DEFAULT(multiRfProto),
[=](int32_t newValue) {
g_model.moduleData[moduleIdx].setMultiProtocol(newValue);
g_model.moduleData[moduleIdx].subType = 0;
if (mmSubProtocol != nullptr) mmSubProtocol->invalidate(); // always null ???
resetMultiProtocolsOptions(moduleIdx);
SET_DIRTY();
update();
rfChoice->setFocus(SET_FOCUS_DEFAULT);// really valid ???
});
// Subtype (D16, DSMX,...)
const mm_protocol_definition * pdef = getMultiProtocolDefinition(g_model.moduleData[moduleIdx].getMultiProtocol());
if (pdef->maxSubtype > 0)
mmSubProtocol = new Choice(this, grid.getFieldSlot(2, 1), pdef->subTypeString, 0, pdef->maxSubtype,GET_SET_DEFAULT(g_model.moduleData[moduleIdx].subType));
if (MULTIMODULE_HAS_SUBTYPE(moduleIdx)) {
// Subtype (D16, DSMX,...)
const mm_protocol_definition *pdef = getMultiProtocolDefinition(
g_model.moduleData[moduleIdx].getMultiProtocol());
if (pdef->maxSubtype > 0) {
mmSubProtocol = new Choice(
this, grid.getFieldSlot(2, 1), pdef->subTypeString, 0,
pdef->maxSubtype,
[=]() { return g_model.moduleData[moduleIdx].subType; },
[=](int16_t newValue) {
g_model.moduleData[moduleIdx].subType = newValue;
resetMultiProtocolsOptions(moduleIdx);
SET_DIRTY();
// update(); ??? how to set focus properly ???
update();
//mmSubProtocol->setFocus(SET_FOCUS_DEFAULT);
});
}
}
grid.nextLine();
// Multimodule status
@@ -664,46 +684,122 @@ class ModuleWindow : public FormGroup {
new StaticText(this, grid.getFieldSlot(), statusText);
}*/
// Multi optional feature row
const uint8_t multi_proto = g_model.moduleData[moduleIdx].getMultiProtocol();
if (pdef->optionsstr) {
grid.nextLine();
new StaticText(this, grid.getLabelSlot(true), pdef->optionsstr);
if (multi_proto == MODULE_SUBTYPE_MULTI_FS_AFHDS2A) {
auto edit = new NumberEdit(this, grid.getFieldSlot(2,0), 50, 400,
GET_DEFAULT(50 + 5 * g_model.moduleData[moduleIdx].multi.optionValue),
SET_VALUE(g_model.moduleData[moduleIdx].multi.optionValue, (newValue- 50) / 5));
edit->setStep(5);
}
else if (multi_proto == MODULE_SUBTYPE_MULTI_OLRS) {
new NumberEdit(this, grid.getFieldSlot(2,0), -1, 7, GET_SET_DEFAULT(g_model.moduleData[moduleIdx].multi.optionValue));
}
else {
new NumberEdit(this, grid.getFieldSlot(2,0), -128, 127, GET_SET_DEFAULT(g_model.moduleData[moduleIdx].multi.optionValue));
if (MULTIMODULE_PROTOCOL_KNOWN(moduleIdx)) {
// Multi optional feature row
const char *title = getMultiOptionTitleStatic(moduleIdx);
if (title != nullptr) {
grid.nextLine();
new StaticText(this, grid.getLabelSlot(true), title);
//Show RSSI next to RF Freq Fine Tune
if (getMultiOptionTitle(moduleIdx) == STR_MULTI_RFTUNE)
{
new DynamicNumber<int>(this, grid.getFieldSlot(2, 1), [] {
return (int)TELEMETRY_RSSI();}, 0, "RSSI: ", " db");
// int optionValue =
// g_model.moduleData[moduleIdx].multi.optionValue;
int8_t min, max;
getMultiOptionValues(multi_proto, min, max);
if (title == STR_MULTI_RFPOWER) {
new Choice(this, grid.getFieldSlot(2, 0), STR_MULTI_POWER, 0, 15,
GET_SET_DEFAULT(
g_model.moduleData[moduleIdx].multi.optionValue));
} else if (title == STR_MULTI_TELEMETRY) {
new Choice(this, grid.getFieldSlot(2, 0),
STR_MULTI_TELEMETRY_MODE, min, max,
GET_SET_DEFAULT(
g_model.moduleData[moduleIdx].multi.optionValue));
} else if (title == STR_MULTI_WBUS) {
new Choice(this, grid.getFieldSlot(2, 0), STR_MULTI_WBUS_MODE, 0,
1,
GET_SET_DEFAULT(
g_model.moduleData[moduleIdx].multi.optionValue));
} else if (multi_proto == MODULE_SUBTYPE_MULTI_FS_AFHDS2A) {
auto edit = new NumberEdit(
this, grid.getFieldSlot(2, 0), 50, 400,
GET_DEFAULT(
50 + 5 * g_model.moduleData[moduleIdx].multi.optionValue),
SET_VALUE(g_model.moduleData[moduleIdx].multi.optionValue,
(newValue - 50) / 5));
edit->setStep(5);
} else if (multi_proto == MODULE_SUBTYPE_MULTI_DSM2) {
new CheckBox(
this, grid.getFieldSlot(2, 0),
[=]() {
return g_model.moduleData[moduleIdx].multi.optionValue &
0x01;
},
[=](int16_t newValue) {
g_model.moduleData[moduleIdx].multi.optionValue =
(g_model.moduleData[moduleIdx].multi.optionValue &
0xFE) +
newValue;
});
} else {
if (min == 0 && max == 1) {
new CheckBox(
this, grid.getFieldSlot(2, 0),
GET_SET_DEFAULT(
g_model.moduleData[moduleIdx].multi.optionValue));
} else {
new NumberEdit(
this, grid.getFieldSlot(2, 0), -128, 127,
GET_SET_DEFAULT(
g_model.moduleData[moduleIdx].multi.optionValue));
// Show RSSI next to RF Freq Fine Tune
if (title == STR_MULTI_RFTUNE) {
new DynamicNumber<int>(
this, grid.getFieldSlot(2, 1),
[] { return (int)TELEMETRY_RSSI(); }, 0, "RSSI: ", " db");
}
}
}
}
}
// Bind on power up
grid.nextLine();
new StaticText(this, grid.getLabelSlot(true),g_model.moduleData[moduleIdx].getMultiProtocol() == MODULE_SUBTYPE_MULTI_DSM2 ? STR_MULTI_DSM_AUTODTECT : STR_MULTI_AUTOBIND);
new CheckBox(this, grid.getFieldSlot(), GET_SET_DEFAULT(g_model.moduleData[moduleIdx].multi.autoBindMode));
if (multi_proto == MODULE_SUBTYPE_MULTI_DSM2) {
const char* servoRates[] = { "22ms", "11ms" };
new StaticText(this, grid.getLabelSlot(true), STR_MULTI_SERVOFREQ);
new Choice(
this, grid.getFieldSlot(), servoRates, 0, 1,
[=]() {
return (g_model.moduleData[moduleIdx].multi.optionValue & 0x02) >> 1;
},
[=](int16_t newValue) {
g_model.moduleData[moduleIdx].multi.optionValue =
(g_model.moduleData[moduleIdx].multi.optionValue & 0xFD) +
(newValue << 1);
});
} else {
// Bind on power up
new StaticText(this, grid.getLabelSlot(true), STR_MULTI_AUTOBIND);
new CheckBox(this, grid.getFieldSlot(),
GET_SET_DEFAULT(
g_model.moduleData[moduleIdx].multi.autoBindMode));
}
// Low power mode
grid.nextLine();
new StaticText(this, grid.getLabelSlot(true), STR_MULTI_LOWPOWER);
new CheckBox(this, grid.getFieldSlot(), GET_SET_DEFAULT(g_model.moduleData[moduleIdx].multi.lowPowerMode));
new CheckBox(
this, grid.getFieldSlot(),
GET_SET_DEFAULT(g_model.moduleData[moduleIdx].multi.lowPowerMode));
// Disable telemetry
grid.nextLine();
new StaticText(this, grid.getLabelSlot(true), STR_DISABLE_TELEM);
new CheckBox(this, grid.getFieldSlot(), GET_SET_DEFAULT(g_model.moduleData[moduleIdx].multi.disableMapping));
new CheckBox(this, grid.getFieldSlot(),
GET_SET_DEFAULT(
g_model.moduleData[moduleIdx].multi.disableTelemetry));
if (MULTI_DISABLE_CHAN_MAP_ROW_STATIC(moduleIdx) != HIDDEN_ROW) {
// Disable channel mapping
grid.nextLine();
new StaticText(this, grid.getLabelSlot(true), STR_DISABLE_CH_MAP);
new CheckBox(this, grid.getFieldSlot(),
GET_SET_DEFAULT(g_model.moduleData[moduleIdx].multi.disableMapping));
}
}
#endif
#if defined(AFHDS3)
@@ -1021,15 +1117,16 @@ void ModelSetupPage::build(FormWindow * window)
// Model name
new StaticText(window, grid.getLabelSlot(), STR_MODELNAME);
auto text = new RadioTextEdit(window, grid.getFieldSlot(), g_model.header.name, sizeof(g_model.header.name),
0, MODEL_NAME_EXTRA_CHARS);
auto text =
new ModelTextEdit(window, grid.getFieldSlot(), g_model.header.name,
sizeof(g_model.header.name), 0, MODEL_NAME_EXTRA_CHARS);
text->setChangeHandler([=] {
modelslist.load();
auto model = modelslist.getCurrentModel();
if (model) {
model->setModelName(g_model.header.name);
}
SET_DIRTY();
modelslist.load();
auto model = modelslist.getCurrentModel();
if (model) {
model->setModelName(g_model.header.name);
}
SET_DIRTY();
});
grid.nextLine();
@@ -1139,7 +1236,17 @@ void ModelSetupPage::build(FormWindow * window)
// Throttle source
new StaticText(window, grid.getLabelSlot(true), STR_TTRACE);
new SourceChoice(window, grid.getFieldSlot(), 0, MIXSRC_LAST_CH, GET_SET_DEFAULT(g_model.thrTraceSrc));
auto sc = new SourceChoice(
window, grid.getFieldSlot(), 0, MIXSRC_LAST_CH,
[=]() { return throttleSource2Source(g_model.thrTraceSrc); },
[=](int16_t src) {
int16_t val = source2ThrottleSource(src);
if (val >= 0) {
g_model.thrTraceSrc = val;
SET_DIRTY();
}
});
sc->setAvailableHandler(isThrottleSourceAvailable);
grid.nextLine();
// Throttle trim
@@ -1149,7 +1256,10 @@ void ModelSetupPage::build(FormWindow * window)
// Throttle trim source
new StaticText(window, grid.getLabelSlot(true), STR_TTRIM_SW);
new SourceChoice(window, grid.getFieldSlot(), 0, NUM_TRIMS - 1, GET_SET_DEFAULT( g_model.thrTrimSw));
new SourceChoice(
window, grid.getFieldSlot(), MIXSRC_FIRST_TRIM, MIXSRC_LAST_TRIM,
[=]() { return g_model.getThrottleStickTrimSource(); },
[=](int16_t src) { g_model.setThrottleStickTrimSource(src); });
grid.nextLine();
}
+7 -7
View File
@@ -32,19 +32,19 @@ class DebugInfoNumber : public Window
public:
DebugInfoNumber(Window * parent, const rect_t & rect, std::function<T()> numberHandler, LcdFlags textFlags = 0, const char * prefix = nullptr, const char * suffix = nullptr):
Window(parent, rect, 0, textFlags),
numberHandler(std::move(numberHandler)),
prefix(prefix),
suffix(suffix)
{
coord_t prefixSize = getTextWidth(prefix, 0, HEADER_COLOR | FONT(XS));
new StaticText(this, {0, 0, prefixSize, rect.h}, prefix, 0, HEADER_COLOR | FONT(XS));
new DynamicNumber<uint32_t>(this, {prefixSize, 0, rect.w - prefixSize, rect.h}, [] {
return menusStack.available();
});
coord_t prefixSize = 0;
if (prefix != nullptr) {
prefixSize = getTextWidth(prefix, 0, HEADER_COLOR | FONT(XS));
new StaticText(this, {0, 0, prefixSize, rect.h}, prefix, 0, HEADER_COLOR | FONT(XS));
}
new DynamicNumber<uint32_t>(this, {prefixSize, 0, rect.w - prefixSize, rect.h},
numberHandler);
}
protected:
std::function<T()> numberHandler;
const char * prefix;
const char * suffix;
};
+3 -3
View File
@@ -75,13 +75,13 @@ class ViewTextWindow : public Page
}
}
void paint(BitmapBuffer* dc)
void paint(BitmapBuffer* dc) override
{
Page::paint(dc);
drawVerticalScrollbar(dc);
}
#endif
virtual void checkEvents();
void checkEvents() override;
#if defined(DEBUG_WINDOWS)
std::string getName() const override { return "ViewTextWindow"; };
@@ -123,4 +123,4 @@ bool isInSetup;
};
};
void readModelNotes();
void readModelNotes();
+2 -2
View File
@@ -75,7 +75,7 @@ class OutputsWidget: public Widget
dc->drawSizedText(barLft + 23, barTop, g_model.limitData[curChan - 1].name, sizeof(g_model.limitData[curChan - 1].name), FONT(XS) | DEFAULT_COLOR | LEFT);
}
else {
drawSource(dc, barLft + 1, barTop, curChan, FONT(XS) | DEFAULT_COLOR | LEFT);
drawSource(dc, barLft + 1, barTop, MIXSRC_FIRST_CH+curChan-1, FONT(XS) | DEFAULT_COLOR | LEFT);
}
}
return lastChan - 1;
@@ -111,7 +111,7 @@ class OutputsWidget: public Widget
lastRefresh = now;
invalidate();
}
invalidate();
}
+6
View File
@@ -21,6 +21,12 @@
#include "opentx.h"
#include "widgets_container_impl.h"
// libopemui defines TIMOUR as zero
#ifdef TIMEHOUR
#undef TIMEHOUR
#define TIMEHOUR 0x2000
#endif
class TimerWidget: public Widget
{
public:
+36 -21
View File
@@ -86,30 +86,45 @@ class ValueWidget: public Widget
if (timerState.val < 0) {
color = ALARM_COLOR;
}
drawSource(dc, NUMBERS_PADDING, 2, field, color);
drawSource(dc, NUMBERS_PADDING + 1, 3, field, COLOR2FLAGS(BLACK));
drawTimer(dc, xValue, yValue, abs(timerState.val), attrValue | FONT(XL) | color);
}
if (field == MIXSRC_TX_TIME) {
drawTimer(dc, xValue, yValue, getValue(MIXSRC_TX_TIME),
attrValue | FONT(XL) | color);
}
if (field >= MIXSRC_FIRST_TELEM) {
TelemetryItem & telemetryItem = telemetryItems[(field - MIXSRC_FIRST_TELEM) / 3];
if (!telemetryItem.isAvailable() || telemetryItem.isOld()) {
color = TEXT_DISABLE_COLOR;
if (persistentData->options[2].value.boolValue) {
drawSource(dc, xLabel + 1, yLabel + 1, field, attrLabel | COLOR2FLAGS(BLACK));
drawTimer(dc, xValue + 1, yValue + 1, abs(timerState.val),
attrValue | FONT(STD) | COLOR2FLAGS(BLACK));
}
}
drawSource(dc, xLabel, yLabel, field, attrLabel | color);
drawTimer(dc, xValue, yValue, abs(timerState.val),
attrValue | FONT(STD) | color);
if (persistentData->options[2].value.boolValue) {
drawSource(dc,xLabel + 1, yLabel + 1, field, attrLabel | COLOR2FLAGS(BLACK));
drawSourceValue(dc, xValue + 1, yValue + 1, field, attrValue | COLOR2FLAGS(BLACK));
}
} else if (field == MIXSRC_TX_TIME) {
int32_t tme = getValue(MIXSRC_TX_TIME);
if (persistentData->options[2].value.boolValue) {
drawSource(dc, xLabel + 1, yLabel + 1, field, COLOR2FLAGS(BLACK));
drawTimer(dc, xValue + 1, yValue + 1, tme,
attrValue | FONT(STD) | COLOR2FLAGS(BLACK));
}
drawSource(dc, xLabel, yLabel, field, attrLabel | color);
drawTimer(dc, xValue, yValue, tme,
attrValue | FONT(STD) | color);
} else {
drawSource(dc, xLabel, yLabel, field, attrLabel | color);
drawSourceValue(dc, xValue, yValue, field, attrValue | color);
if (field >= MIXSRC_FIRST_TELEM) {
TelemetryItem& telemetryItem =
telemetryItems[(field - MIXSRC_FIRST_TELEM) / 3];
if (!telemetryItem.isAvailable() || telemetryItem.isOld()) {
color = TEXT_DISABLE_COLOR;
}
}
if (persistentData->options[2].value.boolValue) {
drawSource(dc, xLabel + 1, yLabel + 1, field,
attrLabel | COLOR2FLAGS(BLACK));
drawSourceValue(dc, xValue + 1, yValue + 1, field,
attrValue | COLOR2FLAGS(BLACK));
}
drawSource(dc, xLabel, yLabel, field, attrLabel | color);
drawSourceValue(dc, xValue, yValue, field, attrValue | color);
}
}
void checkEvents() override
+17 -10
View File
@@ -442,12 +442,15 @@ bool isSwitch2POSWarningStateAvailable(int state)
// return isSwitchAvailable(swtch, TimersContext);
//}
bool isThrottleSourceAvailable(int source)
bool isThrottleSourceAvailable(int src)
{
if (source >= THROTTLE_SOURCE_FIRST_POT && source < THROTTLE_SOURCE_FIRST_POT+NUM_POTS+NUM_SLIDERS && !IS_POT_SLIDER_AVAILABLE(POT1+source-THROTTLE_SOURCE_FIRST_POT))
return false;
else
return true;
#if !defined(LIBOPENUI)
src = throttleSource2Source(src);
#endif
return isSourceAvailable(src) &&
((src == MIXSRC_Thr) ||
((src >= MIXSRC_FIRST_POT) && (src <= MIXSRC_LAST_POT)) ||
((src >= MIXSRC_FIRST_CH) && (src <= MIXSRC_LAST_CH)));
}
bool isLogicalSwitchFunctionAvailable(int function)
@@ -1097,6 +1100,13 @@ const mm_protocol_definition *getMultiProtocolDefinition (uint8_t protocol)
#endif
#if defined(MULTIMODULE)
const char * getMultiOptionTitleStatic(uint8_t moduleIdx)
{
const uint8_t multi_proto = g_model.moduleData[moduleIdx].getMultiProtocol();
const mm_protocol_definition * pdef = getMultiProtocolDefinition(multi_proto);
return pdef->optionsstr;
}
const char * getMultiOptionTitle(uint8_t moduleIdx)
{
MultiModuleStatus &status = getMultiModuleStatus(moduleIdx);
@@ -1107,10 +1117,7 @@ const char * getMultiOptionTitle(uint8_t moduleIdx)
}
return mm_options_strings::options[status.optionDisp];
}
else {
const uint8_t multi_proto = g_model.moduleData[moduleIdx].getMultiProtocol();
const mm_protocol_definition * pdef = getMultiProtocolDefinition(multi_proto);
return pdef->optionsstr;
}
return getMultiOptionTitleStatic(moduleIdx);
}
#endif
+17 -8
View File
@@ -220,6 +220,21 @@ inline uint8_t IF_ALLOW_RACING_MODE(int)
#endif
#if defined(MULTIMODULE)
inline uint8_t MULTI_DISABLE_CHAN_MAP_ROW_STATIC(uint8_t moduleIdx)
{
if (!isModuleMultimodule(moduleIdx))
return HIDDEN_ROW;
uint8_t protocol = g_model.moduleData[moduleIdx].getMultiProtocol();
if (protocol < MODULE_SUBTYPE_MULTI_LAST) {
const mm_protocol_definition * pdef = getMultiProtocolDefinition(protocol);
if (pdef->disable_ch_mapping)
return 0;
}
return HIDDEN_ROW;
}
inline uint8_t MULTI_DISABLE_CHAN_MAP_ROW(uint8_t moduleIdx)
{
if (!isModuleMultimodule(moduleIdx))
@@ -230,14 +245,7 @@ inline uint8_t MULTI_DISABLE_CHAN_MAP_ROW(uint8_t moduleIdx)
return status.supportsDisableMapping() == true ? 0 : HIDDEN_ROW;
}
uint8_t protocol = g_model.moduleData[moduleIdx].getMultiProtocol();
if (protocol < MODULE_SUBTYPE_MULTI_LAST) {
const mm_protocol_definition * pdef = getMultiProtocolDefinition(protocol);
if (pdef->disable_ch_mapping)
return 0;
}
return HIDDEN_ROW;
return MULTI_DISABLE_CHAN_MAP_ROW_STATIC(moduleIdx);
}
inline bool isMultiProtocolSelectable(int protocol)
@@ -355,6 +363,7 @@ inline uint8_t MODULE_OPTION_ROW(uint8_t moduleIdx) {
void editStickHardwareSettings(coord_t x, coord_t y, int idx, event_t event,
LcdFlags flags, uint8_t old_editMode);
const char * getMultiOptionTitleStatic(uint8_t moduleIdx);
const char *getMultiOptionTitle(uint8_t moduleIdx);
const char * writeScreenshot();
+2 -1
View File
@@ -374,7 +374,8 @@ bool luaFindFieldByName(const char * name, LuaField & field, unsigned int flags)
for (int i = 0; i < MAX_TELEMETRY_SENSORS; i++) {
if (isTelemetryFieldAvailable(i)) {
const char* sensorName = g_model.telemetrySensors[i].label;
if ((len <= TELEM_LABEL_LEN) && !strncmp(sensorName, name, len)) {
int len = strnlen(sensorName, TELEM_LABEL_LEN);
if (!strncmp(sensorName, name, len)) {
if (name[len] == '\0') {
field.id = MIXSRC_FIRST_TELEM + 3 * i;
field.desc[0] = '\0';
+2 -2
View File
@@ -77,7 +77,7 @@ void setDefaultGVars()
#endif
}
void setVendorSpecificModelDefaults()
void setVendorSpecificModelDefaults(uint8_t id)
{
#if defined(FRSKY_RELEASE)
g_model.moduleData[INTERNAL_MODULE].type = IS_PXX2_INTERNAL_ENABLED() ? MODULE_TYPE_ISRM_PXX2 : MODULE_TYPE_XJT_PXX1;
@@ -132,7 +132,7 @@ void setModelDefaults(uint8_t id)
memset(&g_model, 0, sizeof(g_model));
applyDefaultTemplate();
setVendorSpecificModelDefaults();
setVendorSpecificModelDefaults(id);
strAppendUnsigned(strAppend(g_model.header.name, STR_MODEL), id + 1, 2);
-26
View File
@@ -229,32 +229,6 @@ enum SwashType {
#include "pulses/modules_constants.h"
enum ThrottleSources {
THROTTLE_SOURCE_THR,
THROTTLE_SOURCE_FIRST_POT,
#if defined(PCBX9E)
THROTTLE_SOURCE_F1 = THROTTLE_SOURCE_FIRST_POT,
THROTTLE_SOURCE_F2,
THROTTLE_SOURCE_F3,
THROTTLE_SOURCE_F4,
THROTTLE_SOURCE_S1,
THROTTLE_SOURCE_S2,
THROTTLE_SOURCE_LS,
THROTTLE_SOURCE_RS,
#elif defined(PCBTARANIS)
THROTTLE_SOURCE_S1 = THROTTLE_SOURCE_FIRST_POT,
THROTTLE_SOURCE_S2,
THROTTLE_SOURCE_S3,
THROTTLE_SOURCE_LS,
THROTTLE_SOURCE_RS,
#else
THROTTLE_SOURCE_P1 = THROTTLE_SOURCE_FIRST_POT,
THROTTLE_SOURCE_P2,
THROTTLE_SOURCE_P3,
#endif
THROTTLE_SOURCE_CH1,
};
enum DisplayTrims
{
DISPLAY_TRIMS_NEVER,
+11 -5
View File
@@ -1007,21 +1007,26 @@ void checkTrims()
else
#endif
{
if (before>TRIM_MIN && after<=TRIM_MIN) {
int16_t tMax = g_model.extendedTrims ? TRIM_EXTENDED_MAX : TRIM_MAX;
int16_t tMin = g_model.extendedTrims ? TRIM_EXTENDED_MIN : TRIM_MIN;
if (before > tMin && after <= tMin) {
beepTrim = true;
AUDIO_TRIM_MIN();
killEvents(event);
}
else if (before<TRIM_MAX && after>=TRIM_MAX) {
else if (before < tMax && after >= tMax) {
beepTrim = true;
AUDIO_TRIM_MAX();
killEvents(event);
}
if ((before<after && after>TRIM_MAX) || (before>after && after<TRIM_MIN)) {
if (!g_model.extendedTrims) after = before;
// Allow only move into the right direction if over the limits
if ((before < after && after > tMax) || // increasing over tMax
(before > after && after < tMin)) { // decreasing under tMin
after = before;
}
// Clip at hard limits
if (after < TRIM_EXTENDED_MIN) {
after = TRIM_EXTENDED_MIN;
}
@@ -1590,7 +1595,8 @@ void instantTrim()
}
}
if (addTrim && abs(delta) >= INSTANT_TRIM_MARGIN) {
int16_t trim = limit<int16_t>(TRIM_EXTENDED_MIN, (delta + trims[stick]) / 2, TRIM_EXTENDED_MAX);
int16_t trim = limit<int16_t>(
TRIM_EXTENDED_MIN, (delta + trims[stick]) / 2, TRIM_EXTENDED_MAX);
setTrimValue(trimFlightMode, stick, trim);
}
}
+5 -1
View File
@@ -285,6 +285,8 @@ void enablePulsesExternalModule(uint8_t protocol)
extmoduleSerialStart();
mixerSchedulerSetPeriod(EXTERNAL_MODULE, MULTIMODULE_PERIOD);
#endif
getMultiModuleStatus(EXTERNAL_MODULE).failsafeChecked = false;
getMultiModuleStatus(EXTERNAL_MODULE).flags = 0;
break;
#endif
@@ -309,7 +311,7 @@ void enablePulsesExternalModule(uint8_t protocol)
#if defined(AFHDS3)
case PROTOCOL_CHANNELS_AFHDS3:
extmodulePulsesData.afhds3.init(EXTERNAL_MODULE);
extmoduleSerialStart(/*AFHDS3_BAUDRATE, AFHDS3_COMMAND_TIMEOUT * 2000, false*/);
extmoduleSerialStart();
mixerSchedulerSetPeriod(EXTERNAL_MODULE, AFHDS3_COMMAND_TIMEOUT * 1000 /* us */);
break;
#endif
@@ -491,6 +493,8 @@ static void enablePulsesInternalModule(uint8_t protocol)
intmodulePulsesData.multi.initFrame();
intmoduleSerialStart(MULTIMODULE_BAUDRATE, true, USART_Parity_Even, USART_StopBits_2, USART_WordLength_9b);
mixerSchedulerSetPeriod(INTERNAL_MODULE, MULTIMODULE_PERIOD);
getMultiModuleStatus(INTERNAL_MODULE).failsafeChecked = false;
getMultiModuleStatus(INTERNAL_MODULE).flags = 0;
break;
#endif
+1
View File
@@ -58,6 +58,7 @@ void preModelLoad()
#endif
#if defined(HARDWARE_EXTERNAL_MODULE)
stopPulsesExternalModule();
RTOS_WAIT_MS(200);
#endif
stopTrainer();
+10
View File
@@ -89,6 +89,16 @@ int zchar2str(char * dest, const char * src, int size)
return size+1;
}
int strnlen(const char *src, int max_size)
{
for (int i=0; i<max_size; i++) {
if (src[i] == '\0')
return i;
}
return max_size;
}
unsigned int effectiveLen(const char * str, unsigned int size)
{
while (size > 0) {
+1
View File
@@ -30,6 +30,7 @@ char char2lower(char c);
int8_t char2zchar(char c);
void str2zchar(char *dest, const char *src, int size);
int zchar2str(char *dest, const char *src, int size);
int strnlen(const char *src, int max_size);
char * strAppend(char * dest, const char * source, int len = 0);
char * strAppendUnsigned(char * dest, uint32_t value, uint8_t digits = 0, uint8_t radix = 10);
+1 -1
View File
@@ -238,7 +238,7 @@ set(TARGET_SRC
)
if(HARDWARE_TOUCH)
set(TOUCH_DRIVER tp_gt911.cpp)
set(TOUCH_DRIVER tp_gt911.cpp i2c_driver.cpp)
add_definitions(-DHARDWARE_TOUCH)
endif()
+9 -7
View File
@@ -326,19 +326,21 @@ void extmoduleSendNextFrame()
#if defined(EXTMODULE_USART) && defined(EXTMODULE_TX_INVERT_GPIO)
extmoduleSendBuffer(extmodulePulsesData.afhds3.getData(), extmodulePulsesData.afhds3.getSize());
#else
if (EXTMODULE_TIMER_DMA_STREAM->CR & DMA_SxCR_EN)
return;
const uint16_t* dataPtr = extmodulePulsesData.afhds3.getData();
uint32_t dataSize = extmodulePulsesData.afhds3.getSize();
//Peripheral data size
//we know that afdhds3 uses 2 byte values!
uint32_t dmaSize = (EXTMODULE_TIMER_DMA_SIZE & (DMA_SxCR_PSIZE_0 | DMA_SxCR_PSIZE_1)) | DMA_SxCR_MSIZE_0;
EXTMODULE_TIMER->CCR2 = dataPtr[dataSize -1] - 4000; // 2mS in advance
EXTMODULE_TIMER_DMA_STREAM->CR &= ~DMA_SxCR_EN; // Disable DMA
EXTMODULE_TIMER_DMA_STREAM->CR |= EXTMODULE_TIMER_DMA_CHANNEL | DMA_SxCR_DIR_0 | DMA_SxCR_MINC | dmaSize | DMA_SxCR_PL_0 | DMA_SxCR_PL_1;
EXTMODULE_TIMER_DMA_STREAM->CR |= EXTMODULE_TIMER_DMA_CHANNEL | DMA_SxCR_DIR_0 | DMA_SxCR_MINC | DMA_SxCR_PSIZE_0 | DMA_SxCR_MSIZE_0 | DMA_SxCR_PL_0 | DMA_SxCR_PL_1;
EXTMODULE_TIMER_DMA_STREAM->PAR = CONVERT_PTR_UINT(&EXTMODULE_TIMER->ARR);
EXTMODULE_TIMER_DMA_STREAM->M0AR = CONVERT_PTR_UINT(dataPtr);
EXTMODULE_TIMER_DMA_STREAM->NDTR = (uint32_t)dataSize;
EXTMODULE_TIMER_DMA_STREAM->NDTR = dataSize;
EXTMODULE_TIMER_DMA_STREAM->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE; // Enable DMA
// re-init timer
EXTMODULE_TIMER->EGR = TIM_PSCReloadMode_Immediate;
EXTMODULE_TIMER->CR1 |= TIM_CR1_CEN;
#endif
}
break;
+1 -1
View File
@@ -728,7 +728,7 @@
#define I2C_SCL_GPIO_PinSource GPIO_PinSource8
#define I2C_SDA_GPIO_PinSource GPIO_PinSource9
#endif
#define I2C_SPEED 400000
#define I2C_CLK_RATE 400000
// Haptic
#define HAPTIC_PWM
File diff suppressed because it is too large Load Diff
+385
View File
@@ -0,0 +1,385 @@
/*
* Copyright (C) EdgeTX
*
* Based on code named
* OpenTX - https://github.com/opentx/opentx
* 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.
*
* The content of this file partially stems from STM32F4 HAL by STMicroelectronics.
*/
#pragma once
#include <stdint.h>
#define __IO volatile /*!< Defines 'read / write' permissions */
#define GPIO_NUMBER 16U
#define GPIO_GET_INDEX(__GPIOx__) (uint8_t)(((__GPIOx__) == (GPIOA))? 0U :\
((__GPIOx__) == (GPIOB))? 1U :\
((__GPIOx__) == (GPIOC))? 2U :\
((__GPIOx__) == (GPIOD))? 3U :\
((__GPIOx__) == (GPIOE))? 4U :\
((__GPIOx__) == (GPIOF))? 5U :\
((__GPIOx__) == (GPIOG))? 6U :\
((__GPIOx__) == (GPIOH))? 7U :\
((__GPIOx__) == (GPIOI))? 8U :\
((__GPIOx__) == (GPIOJ))? 9U : 10U)
#define HAL_MAX_DELAY 0xFFFFFFFFU
/* AHB1 Peripheral Clock Enable Disable
* @brief Enable or disable the AHB1 peripheral clock.
* @note After reset, the peripheral clock (used for registers read/write access)
* is disabled and the application software has to enable this clock before
* using it.
*/
#define __HAL_RCC_GPIOA_CLK_ENABLE() do { \
__IO uint32_t tmpreg = 0x00U; \
SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOAEN);\
/* Delay after an RCC peripheral clock enabling */ \
tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOAEN);\
UNUSED(tmpreg); \
} while(0U)
#define __HAL_RCC_GPIOB_CLK_ENABLE() do { \
__IO uint32_t tmpreg = 0x00U; \
SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOBEN);\
/* Delay after an RCC peripheral clock enabling */ \
tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOBEN);\
UNUSED(tmpreg); \
} while(0U)
#define __HAL_RCC_GPIOC_CLK_ENABLE() do { \
__IO uint32_t tmpreg = 0x00U; \
SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOCEN);\
/* Delay after an RCC peripheral clock enabling */ \
tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOCEN);\
UNUSED(tmpreg); \
} while(0U)
#define __HAL_RCC_GPIOH_CLK_ENABLE() do { \
__IO uint32_t tmpreg = 0x00U; \
SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOHEN);\
/* Delay after an RCC peripheral clock enabling */ \
tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOHEN);\
UNUSED(tmpreg); \
} while(0U)
#define __HAL_RCC_GPIOA_CLK_DISABLE() (RCC->AHB1ENR &= ~(RCC_AHB1ENR_GPIOAEN))
#define __HAL_RCC_GPIOB_CLK_DISABLE() (RCC->AHB1ENR &= ~(RCC_AHB1ENR_GPIOBEN))
#define __HAL_RCC_GPIOC_CLK_DISABLE() (RCC->AHB1ENR &= ~(RCC_AHB1ENR_GPIOCEN))
#define __HAL_RCC_GPIOH_CLK_DISABLE() (RCC->AHB1ENR &= ~(RCC_AHB1ENR_GPIOHEN))
/* APB1 Peripheral Clock Enable Disable
* @brief Enable or disable the Low Speed APB (APB1) peripheral clock.
* @note After reset, the peripheral clock (used for registers read/write access)
* is disabled and the application software has to enable this clock before
* using it.
*/
#define __HAL_RCC_I2C1_CLK_ENABLE() do { \
__IO uint32_t tmpreg = 0x00U; \
SET_BIT(RCC->APB1ENR, RCC_APB1ENR_I2C1EN);\
/* Delay after an RCC peripheral clock enabling */ \
tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_I2C1EN);\
UNUSED(tmpreg); \
} while(0U)
#define __HAL_RCC_I2C2_CLK_ENABLE() do { \
__IO uint32_t tmpreg = 0x00U; \
SET_BIT(RCC->APB1ENR, RCC_APB1ENR_I2C2EN);\
/* Delay after an RCC peripheral clock enabling */ \
tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_I2C2EN);\
UNUSED(tmpreg); \
} while(0U)
#define __HAL_RCC_I2C3_CLK_ENABLE() do { \
__IO uint32_t tmpreg = 0x00U; \
SET_BIT(RCC->APB1ENR, RCC_APB1ENR_I2C3EN);\
/* Delay after an RCC peripheral clock enabling */ \
tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_I2C3EN);\
UNUSED(tmpreg); \
} while(0U)
#define __HAL_RCC_I2C1_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_I2C1EN))
#define __HAL_RCC_I2C2_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_I2C2EN))
#define __HAL_RCC_I2C3_CLK_DISABLE() (RCC->APB1ENR &= ~(RCC_APB1ENR_I2C3EN))
#define __HAL_LOCK(__HANDLE__) \
do{ \
if((__HANDLE__)->Lock == HAL_LOCKED) \
{ \
return HAL_BUSY; \
} \
else \
{ \
(__HANDLE__)->Lock = HAL_LOCKED; \
} \
}while (0U)
#define __HAL_UNLOCK(__HANDLE__) \
do{ \
(__HANDLE__)->Lock = HAL_UNLOCKED; \
}while (0U)
/* Enable the specified I2C peripheral.
* @param __HANDLE__ specifies the I2C Handle.
* @retval None
*/
#define __HAL_I2C_ENABLE(__HANDLE__) SET_BIT((__HANDLE__)->Instance->CR1, I2C_CR1_PE)
/* Disable the specified I2C peripheral.
* @param __HANDLE__ specifies the I2C Handle.
* @retval None
*/
#define __HAL_I2C_DISABLE(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->CR1, I2C_CR1_PE)
// I2C Private Constants
#define I2C_FLAG_MASK 0x0000FFFFU
#define I2C_MIN_PCLK_FREQ_STANDARD 2000000U /*!< 2 MHz */
#define I2C_MIN_PCLK_FREQ_FAST 4000000U /*!< 4 MHz */
#define I2C_TIMEOUT_FLAG 35U /*!< Timeout 35 ms */
#define I2C_TIMEOUT_BUSY_FLAG 25U /*!< Timeout 25 ms */
#define I2C_TIMEOUT_STOP_FLAG 5U /*!< Timeout 5 ms */
#define I2C_NO_OPTION_FRAME 0xFFFF0000U /*!< XferOptions default value */
// I2C Private Macros
#define I2C_MIN_PCLK_FREQ(__PCLK__, __SPEED__) (((__SPEED__) <= 100000U) ? ((__PCLK__) < I2C_MIN_PCLK_FREQ_STANDARD) : ((__PCLK__) < I2C_MIN_PCLK_FREQ_FAST))
#define I2C_CCR_CALCULATION(__PCLK__, __SPEED__, __COEFF__) (((((__PCLK__) - 1U)/((__SPEED__) * (__COEFF__))) + 1U) & I2C_CCR_CCR)
#define I2C_FREQRANGE(__PCLK__) ((__PCLK__)/1000000U)
#define I2C_RISE_TIME(__FREQRANGE__, __SPEED__) (((__SPEED__) <= 100000U) ? ((__FREQRANGE__) + 1U) : ((((__FREQRANGE__) * 300U) / 1000U) + 1U))
#define I2C_SPEED_STANDARD(__PCLK__, __SPEED__) ((I2C_CCR_CALCULATION((__PCLK__), (__SPEED__), 2U) < 4U)? 4U:I2C_CCR_CALCULATION((__PCLK__), (__SPEED__), 2U))
#define I2C_SPEED_FAST(__PCLK__, __SPEED__, __DUTYCYCLE__) (((__DUTYCYCLE__) == I2C_DUTYCYCLE_2)? I2C_CCR_CALCULATION((__PCLK__), (__SPEED__), 3U) : (I2C_CCR_CALCULATION((__PCLK__), (__SPEED__), 25U) | I2C_DUTYCYCLE_16_9))
#define I2C_SPEED(__PCLK__, __SPEED__, __DUTYCYCLE__) (((__SPEED__) <= 100000U)? (I2C_SPEED_STANDARD((__PCLK__), (__SPEED__))) : \
((I2C_SPEED_FAST((__PCLK__), (__SPEED__), (__DUTYCYCLE__)) & I2C_CCR_CCR) == 0U)? 1U : \
((I2C_SPEED_FAST((__PCLK__), (__SPEED__), (__DUTYCYCLE__))) | I2C_CCR_FS))
#define I2C_7BIT_ADD_WRITE(__ADDRESS__) ((uint8_t)((__ADDRESS__) & (uint8_t)(~I2C_OAR1_ADD0)))
#define I2C_7BIT_ADD_READ(__ADDRESS__) ((uint8_t)((__ADDRESS__) | I2C_OAR1_ADD0))
#define I2C_10BIT_ADDRESS(__ADDRESS__) ((uint8_t)((uint16_t)((__ADDRESS__) & (uint16_t)0x00FF)))
#define I2C_10BIT_HEADER_WRITE(__ADDRESS__) ((uint8_t)((uint16_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)0x0300)) >> 7) | (uint16_t)0x00F0)))
#define I2C_10BIT_HEADER_READ(__ADDRESS__) ((uint8_t)((uint16_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)0x0300)) >> 7) | (uint16_t)(0x00F1))))
#define I2C_MEM_ADD_MSB(__ADDRESS__) ((uint8_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)0xFF00)) >> 8)))
#define I2C_MEM_ADD_LSB(__ADDRESS__) ((uint8_t)((uint16_t)((__ADDRESS__) & (uint16_t)0x00FF)))
// I2C duty cycle in fast mode
#define I2C_DUTYCYCLE_2 0x00000000U
#define I2C_DUTYCYCLE_16_9 I2C_CCR_DUTY
// I2C addressing mode
#define I2C_ADDRESSINGMODE_7BIT 0x00004000U
#define I2C_ADDRESSINGMODE_10BIT (I2C_OAR1_ADDMODE | 0x00004000U)
// I2C dual addressing mode
#define I2C_DUALADDRESS_DISABLE 0x00000000U
#define I2C_DUALADDRESS_ENABLE I2C_OAR2_ENDUAL
// I2C general call addressing mode
#define I2C_GENERALCALL_DISABLE 0x00000000U
#define I2C_GENERALCALL_ENABLE I2C_CR1_ENGC
// I2C nostretch mode
#define I2C_NOSTRETCH_DISABLE 0x00000000U
#define I2C_NOSTRETCH_ENABLE I2C_CR1_NOSTRETCH
// I2C Error Code definition
#define HAL_I2C_ERROR_NONE 0x00000000U /*!< No error */
#define HAL_I2C_ERROR_BERR 0x00000001U /*!< BERR error */
#define HAL_I2C_ERROR_ARLO 0x00000002U /*!< ARLO error */
#define HAL_I2C_ERROR_AF 0x00000004U /*!< AF error */
#define HAL_I2C_ERROR_OVR 0x00000008U /*!< OVR error */
#define HAL_I2C_ERROR_DMA 0x00000010U /*!< DMA transfer error */
#define HAL_I2C_ERROR_TIMEOUT 0x00000020U /*!< Timeout Error */
#define HAL_I2C_ERROR_SIZE 0x00000040U /*!< Size Management error */
#define HAL_I2C_ERROR_DMA_PARAM 0x00000080U /*!< DMA Parameter Error */
#define HAL_I2C_WRONG_START 0x00000200U /*!< Wrong start Error */
// I2C XferOptions definition
#define I2C_FIRST_FRAME 0x00000001U
#define I2C_FIRST_AND_NEXT_FRAME 0x00000002U
#define I2C_NEXT_FRAME 0x00000004U
#define I2C_FIRST_AND_LAST_FRAME 0x00000008U
#define I2C_LAST_FRAME_NO_STOP 0x00000010U
#define I2C_LAST_FRAME 0x00000020U
// I2C states
#define I2C_STATE_MSK ((uint32_t)((uint32_t)((uint32_t)HAL_I2C_STATE_BUSY_TX | (uint32_t)HAL_I2C_STATE_BUSY_RX) & (uint32_t)(~((uint32_t)HAL_I2C_STATE_READY)))) /*!< Mask State define, keep only RX and TX bits */
#define I2C_STATE_NONE ((uint32_t)(HAL_I2C_MODE_NONE)) /*!< Default Value */
#define I2C_STATE_MASTER_BUSY_TX ((uint32_t)(((uint32_t)HAL_I2C_STATE_BUSY_TX & I2C_STATE_MSK) | (uint32_t)HAL_I2C_MODE_MASTER)) /*!< Master Busy TX, combinaison of State LSB and Mode enum */
#define I2C_STATE_MASTER_BUSY_RX ((uint32_t)(((uint32_t)HAL_I2C_STATE_BUSY_RX & I2C_STATE_MSK) | (uint32_t)HAL_I2C_MODE_MASTER)) /*!< Master Busy RX, combinaison of State LSB and Mode enum */
#define I2C_STATE_SLAVE_BUSY_TX ((uint32_t)(((uint32_t)HAL_I2C_STATE_BUSY_TX & I2C_STATE_MSK) | (uint32_t)HAL_I2C_MODE_SLAVE)) /*!< Slave Busy TX, combinaison of State LSB and Mode enum */
#define I2C_STATE_SLAVE_BUSY_RX ((uint32_t)(((uint32_t)HAL_I2C_STATE_BUSY_RX & I2C_STATE_MSK) | (uint32_t)HAL_I2C_MODE_SLAVE)) /*!< Slave Busy RX, combinaison of State LSB and Mode enum */
// I2C Analog Filter
#define I2C_ANALOGFILTER_ENABLE 0x00000000U
#define I2C_ANALOGFILTER_DISABLE I2C_FLTR_ANOFF
/* Clears the I2C ADDR pending flag.
* @param __HANDLE__ specifies the I2C Handle.
* This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral.
* @retval None
*/
#define __HAL_I2C_CLEAR_ADDRFLAG(__HANDLE__) \
do{ \
__IO uint32_t tmpreg = 0x00U; \
tmpreg = (__HANDLE__)->Instance->SR1; \
tmpreg = (__HANDLE__)->Instance->SR2; \
UNUSED(tmpreg); \
} while(0)
/* Clears the I2C pending flags which are cleared by writing 0 in a specific bit.
* @param __HANDLE__ specifies the I2C Handle.
* @param __FLAG__ specifies the flag to clear.
* This parameter can be any combination of the following values:
* @arg I2C_FLAG_OVR: Overrun/Underrun flag (Slave mode)
* @arg I2C_FLAG_AF: Acknowledge failure flag
* @arg I2C_FLAG_ARLO: Arbitration lost flag (Master mode)
* @arg I2C_FLAG_BERR: Bus error flag
* @retval None
*/
#define __HAL_I2C_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->SR1 = (uint16_t)(~((__FLAG__) & I2C_FLAG_MASK)))
// HAL Status structures definition
typedef enum
{
HAL_OK = 0x00U,
HAL_ERROR = 0x01U,
HAL_BUSY = 0x02U,
HAL_TIMEOUT = 0x03U
} HAL_StatusTypeDef;
// HAL lock structures definition
typedef enum
{
HAL_UNLOCKED = 0x00U,
HAL_LOCKED = 0x01U
} HAL_LockTypeDef;
/* HAL State structure definition
* HAL I2C State value coding follow below described bitmap :
* b7-b6 Error information
* 00 : No Error
* 01 : Abort (Abort user request on going)
* 10 : Timeout
* 11 : Error
* b5 Peripheral initialization status
* 0 : Reset (Peripheral not initialized)
* 1 : Init done (Peripheral initialized and ready to use. HAL I2C Init function called)
* b4 (not used)
* x : Should be set to 0
* b3
* 0 : Ready or Busy (No Listen mode ongoing)
* 1 : Listen (Peripheral in Address Listen Mode)
* b2 Intrinsic process state
* 0 : Ready
* 1 : Busy (Peripheral busy with some configuration or internal operations)
* b1 Rx state
* 0 : Ready (no Rx operation ongoing)
* 1 : Busy (Rx operation ongoing)
* b0 Tx state
* 0 : Ready (no Tx operation ongoing)
* 1 : Busy (Tx operation ongoing)
*/
typedef enum
{
HAL_I2C_STATE_RESET = 0x00U, /*!< Peripheral is not yet Initialized */
HAL_I2C_STATE_READY = 0x20U, /*!< Peripheral Initialized and ready for use */
HAL_I2C_STATE_BUSY = 0x24U, /*!< An internal process is ongoing */
HAL_I2C_STATE_BUSY_TX = 0x21U, /*!< Data Transmission process is ongoing */
HAL_I2C_STATE_BUSY_RX = 0x22U, /*!< Data Reception process is ongoing */
HAL_I2C_STATE_LISTEN = 0x28U, /*!< Address Listen Mode is ongoing */
HAL_I2C_STATE_BUSY_TX_LISTEN = 0x29U, /*!< Address Listen Mode and Data Transmission
process is ongoing */
HAL_I2C_STATE_BUSY_RX_LISTEN = 0x2AU, /*!< Address Listen Mode and Data Reception
process is ongoing */
HAL_I2C_STATE_ABORT = 0x60U, /*!< Abort user request ongoing */
HAL_I2C_STATE_TIMEOUT = 0xA0U, /*!< Timeout state */
HAL_I2C_STATE_ERROR = 0xE0U /*!< Error */
} HAL_I2C_StateTypeDef;
/* HAL Mode structure definition
* HAL I2C Mode value coding follow below described bitmap :
* b7 (not used)
* x : Should be set to 0
* b6
* 0 : None
* 1 : Memory (HAL I2C communication is in Memory Mode)
* b5
* 0 : None
* 1 : Slave (HAL I2C communication is in Slave Mode)
* b4
* 0 : None
* 1 : Master (HAL I2C communication is in Master Mode)
* b3-b2-b1-b0 (not used)
* xxxx : Should be set to 0000
*/
typedef enum
{
HAL_I2C_MODE_NONE = 0x00U, /*!< No I2C communication on going */
HAL_I2C_MODE_MASTER = 0x10U, /*!< I2C communication is in Master Mode */
HAL_I2C_MODE_SLAVE = 0x20U, /*!< I2C communication is in Slave Mode */
HAL_I2C_MODE_MEM = 0x40U /*!< I2C communication is in Memory Mode */
} HAL_I2C_ModeTypeDef;
// I2C configuration structure definition
typedef struct
{
uint32_t ClockSpeed; /*!< Specifies the clock frequency.
This parameter must be set to a value lower than 400kHz */
uint32_t DutyCycle; /*!< Specifies the I2C fast mode duty cycle.
This parameter can be a value of @ref I2C_duty_cycle_in_fast_mode */
uint32_t OwnAddress1; /*!< Specifies the first device own address.
This parameter can be a 7-bit or 10-bit address. */
uint32_t AddressingMode; /*!< Specifies if 7-bit or 10-bit addressing mode is selected.
This parameter can be a value of @ref I2C_addressing_mode */
uint32_t DualAddressMode; /*!< Specifies if dual addressing mode is selected.
This parameter can be a value of @ref I2C_dual_addressing_mode */
uint32_t OwnAddress2; /*!< Specifies the second device own address if dual addressing mode is selected
This parameter can be a 7-bit address. */
uint32_t GeneralCallMode; /*!< Specifies if general call mode is selected.
This parameter can be a value of @ref I2C_general_call_addressing_mode */
uint32_t NoStretchMode; /*!< Specifies if nostretch mode is selected.
This parameter can be a value of @ref I2C_nostretch_mode */
} HAL_I2C_InitTypeDef; // WARNING: renamed from I2C_InitTypeDef due to conflict
// I2C handle structure definition
typedef struct
{
I2C_TypeDef *Instance; /*!< I2C registers base address */
HAL_I2C_InitTypeDef Init; /*!< I2C communication parameters (MOD!) */
uint8_t *pBuffPtr; /*!< Pointer to I2C transfer buffer */
uint16_t XferSize; /*!< I2C transfer size */
__IO uint16_t XferCount; /*!< I2C transfer counter */
__IO uint32_t XferOptions; /*!< I2C transfer options */
__IO uint32_t PreviousState; /*!< I2C communication Previous state and mode
context for internal usage */
//DMA_HandleTypeDef *hdmatx; /*!< I2C Tx DMA handle parameters */
//DMA_HandleTypeDef *hdmarx; /*!< I2C Rx DMA handle parameters */
HAL_LockTypeDef Lock; /*!< I2C locking object */
__IO HAL_I2C_StateTypeDef State; /*!< I2C communication state */
__IO HAL_I2C_ModeTypeDef Mode; /*!< I2C communication mode */
__IO uint32_t ErrorCode; /*!< I2C Error code */
__IO uint32_t Devaddress; /*!< I2C Target device address */
__IO uint32_t Memaddress; /*!< I2C Target memory address */
__IO uint32_t MemaddSize; /*!< I2C Target memory address size */
__IO uint32_t EventCount; /*!< I2C Event counter */
} I2C_HandleTypeDef;
HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c);
HAL_StatusTypeDef HAL_I2C_DeInit(I2C_HandleTypeDef *hi2c);
HAL_StatusTypeDef HAL_I2CEx_ConfigAnalogFilter(I2C_HandleTypeDef *hi2c, uint32_t AnalogFilter);
HAL_StatusTypeDef HAL_I2CEx_ConfigDigitalFilter(I2C_HandleTypeDef *hi2c, uint32_t DigitalFilter);
HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout);
HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout);
+80 -252
View File
@@ -19,6 +19,7 @@
*/
#include "opentx.h"
#include "i2c_driver.h"
#include "tp_gt911.h"
#include "touch.h"
@@ -409,6 +410,8 @@ struct TouchData touchData;
uint16_t touchGT911fwver = 0;
uint32_t touchGT911hiccups = 0;
I2C_HandleTypeDef hi2c1;
static void TOUCH_AF_ExtiStop(void)
{
SYSCFG_EXTILineConfig(TOUCH_INT_EXTI_PortSource, TOUCH_INT_EXTI_PinSource1);
@@ -484,267 +487,75 @@ void TOUCH_AF_INT_Change(void)
GPIO_Init(TOUCH_INT_GPIO, &GPIO_InitStructure);
}
void I2C_Init()
void I2C_Init_Radio(void)
{
TRACE("I2C Init");
I2C_DeInit(I2C);
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;
I2C_InitStructure.I2C_ClockSpeed = I2C_SPEED;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = 0x00;
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_Init(I2C, &I2C_InitStructure);
I2C_Cmd(I2C, ENABLE);
GPIO_PinAFConfig(I2C_GPIO, I2C_SCL_GPIO_PinSource, I2C_GPIO_AF);
GPIO_PinAFConfig(I2C_GPIO, I2C_SDA_GPIO_PinSource, I2C_GPIO_AF);
GPIO_InitStructure.GPIO_Pin = I2C_SCL_GPIO_PIN | I2C_SDA_GPIO_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(I2C_GPIO, &GPIO_InitStructure);
hi2c1.Instance = I2C;
hi2c1.Init.ClockSpeed = I2C_CLK_RATE;
hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_16_9;
hi2c1.Init.OwnAddress1 = 0;
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c1.Init.OwnAddress2 = 0;
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if (HAL_I2C_Init(&hi2c1) != HAL_OK)
{
TRACE("I2C ERROR: HAL_I2C_Init() failed");
}
// Configure Analogue filter
if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
{
TRACE("I2C ERROR: HAL_I2CEx_ConfigAnalogFilter() failed");
}
// Configure Digital filter
if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK)
{
TRACE("I2C ERROR: HAL_I2CEx_ConfigDigitalFilter() failed");
}
}
bool I2C_WaitFlag(uint32_t flag)
bool I2C_GT911_WriteRegister(uint16_t reg, uint8_t * buf, uint8_t len)
{
uint32_t timeout = I2C_TIMEOUT_MAX;
while (!I2C_GetFlagStatus(I2C, flag)) {
if ((timeout--) == 0) return false;
}
return true;
}
uint8_t uAddrAndBuf[258];
uAddrAndBuf[0] = (uint8_t)((reg & 0xFF00) >> 8);
uAddrAndBuf[1] = (uint8_t)(reg & 0x00FF);
bool I2C_WaitEvent(uint32_t event)
{
uint32_t timeout = I2C_TIMEOUT_MAX;
while (!I2C_CheckEvent(I2C, event)) {
if ((timeout--) == 0) return false;
}
return true;
}
bool I2C_WaitEventCleared(uint32_t event)
{
uint32_t timeout = I2C_TIMEOUT_MAX;
while (I2C_CheckEvent(I2C, event)) {
if ((timeout--) == 0) return false;
}
return true;
}
uint8_t I2C_GT911_WriteRegister(uint16_t reg, uint8_t * buf, uint8_t len)
{
if (!I2C_WaitEventCleared(I2C_FLAG_BUSY))
{
TRACE("I2C WRITE ERROR: busy timeout");
return false;
}
I2C_GenerateSTART(I2C, ENABLE);
if (!I2C_WaitEvent(I2C_EVENT_MASTER_MODE_SELECT))
{
TRACE("I2C WRITE ERROR: could not issue start");
return false;
}
I2C_Send7bitAddress(I2C, GT_CMD_WR, I2C_Direction_Transmitter);
if (!I2C_WaitEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
{
TRACE("I2C WRITE ERROR: could not send device address");
return false;
}
I2C_SendData(I2C, (uint8_t)((reg & 0xFF00) >> 8));
if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING))
{
TRACE("I2C WRITE ERROR: could not send register high address");
return false;
}
I2C_SendData(I2C, (uint8_t)(reg & 0x00FF));
if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING))
{
TRACE("I2C WRITE ERROR: could not send register low address");
return false;
}
/* While there is data to be written */
while (len--) {
I2C_SendData(I2C, *buf);
if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING))
if (len > 0)
{
TRACE("I2C WRITE ERROR: could not send data with %u bytes remaining", len+1 );
return false;
for (int i = 0;i < len;i++)
{
uAddrAndBuf[i + 2] = buf[i];
}
}
buf++;
}
if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED))
{
TRACE("I2C WRITE ERROR: waiting for BTF failed.");
return false;
}
I2C_GenerateSTOP(I2C, ENABLE);
return true;
if (HAL_I2C_Master_Transmit(&hi2c1, GT911_I2C_ADDR << 1, uAddrAndBuf, len + 2, 100) != HAL_OK)
{
TRACE("I2C ERROR: WriteRegister failed");
return false;
}
return true;
}
bool I2C_GT911_ReadRegister(u16 reg, uint8_t * buf, uint8_t len)
bool I2C_GT911_ReadRegister(uint16_t reg, uint8_t * buf, uint8_t len)
{
if (!I2C_WaitEventCleared(I2C_FLAG_BUSY))
{
TRACE("I2C READ ERROR: busy timeout");
return false;
}
uint8_t uRegAddr[2];
uRegAddr[0] = (uint8_t)((reg & 0xFF00) >> 8);
uRegAddr[1] = (uint8_t)(reg & 0x00FF);
I2C_GenerateSTART(I2C, ENABLE);
if (!I2C_WaitEvent(I2C_EVENT_MASTER_MODE_SELECT))
{
TRACE("I2C READ ERROR: could not issue first step start");
return false;
}
I2C_Send7bitAddress(I2C, GT_CMD_WR, I2C_Direction_Transmitter);
if (!I2C_WaitEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
{
TRACE("I2C READ ERROR: could not send first step device address");
return false;
}
I2C_SendData(I2C, (uint8_t)((reg & 0xFF00) >> 8));
if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING))
{
TRACE("I2C READ ERROR: could not send register high address");
return false;
}
I2C_SendData(I2C, (uint8_t)(reg & 0x00FF));
if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED))
{
TRACE("I2C READ ERROR: could not send register low address");
return false;
}
// According to GP911 data sheet, repeated start is not listed, so we do full stop.
// See chapter 6.1.c, page 12, diagram for reading data
I2C_GenerateSTOP(I2C, ENABLE);
if (!I2C_WaitEventCleared(I2C_FLAG_BUSY))
{
TRACE("I2C READ ERROR: timeout waiting for first stop");
return false;
}
// Enable Acknowledgement, clear POS flag
I2C_AcknowledgeConfig(I2C, ENABLE);
I2C_NACKPositionConfig(I2C, I2C_NACKPosition_Current);
I2C_GenerateSTART(I2C, ENABLE);
if (!I2C_WaitEvent(I2C_EVENT_MASTER_MODE_SELECT))
{
TRACE("I2C READ ERROR: could not issue second step start");
return false;
}
I2C_Send7bitAddress(I2C, GT_CMD_RD, I2C_Direction_Receiver);
if (!I2C_WaitEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
{
TRACE("I2C READ ERROR: could not send second step device address");
return false;
}
if (len == 1) {
// Clear Ack bit
I2C_AcknowledgeConfig(I2C, DISABLE);
// EV6_1 -- must be atomic -- Clear ADDR, generate STOP
__disable_irq();
(void) I2C->SR2;
I2C_GenerateSTOP(I2C,ENABLE);
__enable_irq();
// Receive data EV7
if(!I2C_WaitFlag(I2C_FLAG_RXNE)) {
TRACE("I2C READ ERROR: timeout waiting for RxNE");
I2C_Init();
return false;
}
*buf++ = I2C_ReceiveData(I2C);
}
else if (len == 2) {
// Set POS flag
I2C_NACKPositionConfig(I2C, I2C_NACKPosition_Next);
// EV6_1 -- must be atomic and in this order
__disable_irq();
(void) I2C->SR2; // Clear ADDR flag
I2C_AcknowledgeConfig(I2C, DISABLE); // Clear Ack bit
__enable_irq();
// EV7_3 -- Wait for BTF, program stop, read data twice
if (!I2C_WaitFlag(I2C_FLAG_BTF)) {
TRACE("I2C READ ERROR: timeout waiting for BTF");
I2C_Init();
return false;
}
__disable_irq();
I2C_GenerateSTOP(I2C,ENABLE);
*buf++ = I2C->DR;
__enable_irq();
*buf++ = I2C->DR;
}
else {
(void) I2C->SR2; // Clear ADDR flag
while (len-- != 3) {
// EV7 -- cannot guarantee 1 transfer completion time, wait for BTF
// instead of RXNE
if (!I2C_WaitFlag(I2C_FLAG_BTF)) {
TRACE("I2C READ ERROR: timeout waiting for BTF");
I2C_Init();
if (HAL_I2C_Master_Transmit(&hi2c1, GT911_I2C_ADDR << 1, uRegAddr, 2, 10) != HAL_OK)
{
TRACE("I2C ERROR: ReadRegister write reg address failed");
return false;
}
*buf++ = I2C_ReceiveData(I2C);
}
// Data N-2 in DR, data N-1 in shift register,
// SCL stretched low until data N-2 is read
if (!I2C_WaitFlag(I2C_FLAG_BTF)) {
TRACE("I2C READ ERROR: timeout waiting for BTF");
I2C_Init();
return false;
if (HAL_I2C_Master_Receive(&hi2c1, GT911_I2C_ADDR << 1, buf, len, 100) != HAL_OK)
{
TRACE("I2C ERROR: ReadRegister read reg address failed");
return false;
}
I2C_AcknowledgeConfig(I2C, DISABLE); // clear ack bit
*buf++ = I2C_ReceiveData(I2C); // receive byte N-2
// Wait for BTF, program stop, read data twice
if (!I2C_WaitFlag(I2C_FLAG_BTF)) {
TRACE("I2C READ ERROR: timeout waiting for BTF");
I2C_Init();
return false;
}
__disable_irq();
I2C_GenerateSTOP(I2C,ENABLE);
*buf++ = I2C->DR;
__enable_irq();
*buf++ = I2C->DR;
}
return true;
return true;
}
bool I2C_GT911_SendConfig(void)
@@ -791,7 +602,7 @@ bool touchPanelInit(void)
TRACE("Touchpanel init start ...");
TOUCH_AF_GPIOConfig(); //SET RST=OUT INT=OUT INT=LOW
I2C_Init();
I2C_Init_Radio();
TPRST_LOW();
TPINT_HIGH();
@@ -827,7 +638,7 @@ bool touchPanelInit(void)
}
TRACE("Chip config Ver:%x", tmp[0]);
if (tmp[0] <= GT911_CFG_NUMER) //Config ver
if (tmp[0] < GT911_CFG_NUMER) //Config ver
{
TRACE("Sending new config %d", GT911_CFG_NUMER);
if (!I2C_GT911_SendConfig())
@@ -864,6 +675,23 @@ bool touchPanelInit(void)
}
}
bool I2C_ReInit(void)
{
TRACE("I2C ReInit");
touchPanelDeInit();
if (HAL_I2C_DeInit(&hi2c1) != HAL_OK)
TRACE("I2C ReInit - I2C DeInit failed");
// If DeInit fails, try to re-init anyway
if (!touchPanelInit())
{
TRACE("I2C ReInit - touchPanelInit failed");
return false;
}
return true;
}
#if defined(SIMU) || defined(SEMIHOSTING) || defined(DEBUG)
static const char* event2str(uint8_t ev)
{
@@ -888,10 +716,10 @@ void touchPanelRead()
{
uint8_t state = 0;
// if (!touchEventOccured)
// return;
if (!touchEventOccured)
return;
// touchEventOccured = false;
touchEventOccured = false;
uint32_t startReadStatus = RTOS_GET_MS();
do {
@@ -899,8 +727,8 @@ void touchPanelRead()
//ledRed();
touchGT911hiccups++;
TRACE("GT911 I2C read XY error");
touchPanelDeInit();
touchPanelInit();
if (!I2C_ReInit())
TRACE("I2C ReInit failed");
return;
}
@@ -921,8 +749,8 @@ void touchPanelRead()
//ledRed();
touchGT911hiccups++;
TRACE("GT911 I2C data read error");
touchPanelDeInit();
touchPanelInit();
if (!I2C_ReInit())
TRACE("I2C ReInit failed");
return;
}
if (touchState.event == TE_NONE || touchState.event == TE_UP ||
+17 -16
View File
@@ -30,28 +30,29 @@ extern bool touchPanelInit();
void touchPanelRead();
bool touchPanelEventOccured();
#define GT911_TIMEOUT 3 // 3ms
#define GT911_TIMEOUT 3 // 3ms
#define GT911_MAX_TP 5
#define GT911_CFG_NUMER 0x6C
#define GT911_CFG_NUMER 0x6D
//I2C
#define GT_CMD_WR 0X28
#define GT_CMD_RD 0X29
#define I2C_TIMEOUT_MAX 1000
#define GT911_I2C_ADDR 0x14
//#define GT_CMD_WR 0x28
//#define GT_CMD_RD 0x29
//#define I2C_TIMEOUT_MAX 1000
//GT9147
#define GT_CTRL_REG 0X8040
#define GT_CFGS_REG 0X8047
#define GT_CHECK_REG 0X80FF
#define GT_PID_REG 0X8140
//GT911
#define GT_CTRL_REG 0x8040
#define GT_CFGS_REG 0x8047
#define GT_CHECK_REG 0x80FF
#define GT_PID_REG 0x8140
#define GT_GSTID_REG 0X814E
#define GT_TP1_REG 0X8150
#define GT_TP2_REG 0X8158
#define GT_TP3_REG 0X8160
#define GT_TP4_REG 0X8168
#define GT_TP5_REG 0X8170
#define GT_GSTID_REG 0x814E
#define GT_TP1_REG 0x8150
#define GT_TP2_REG 0x8158
#define GT_TP3_REG 0x8160
#define GT_TP4_REG 0x8168
#define GT_TP5_REG 0x8170
#define GT911_READ_XY_REG 0x814E
#define GT911_CLEARBUF_REG 0x814E
+1 -1
View File
@@ -1968,7 +1968,7 @@
#define I2C_SDA_GPIO_PinSource GPIO_PinSource7
#define I2C_ADDRESS_VOLUME 0x5C
#endif
#define I2C_SPEED 400000
#define I2C_CLK_RATE 400000
#define I2C_ADDRESS_EEPROM 0xA2
#define I2C_FLASH_PAGESIZE 64
+1 -1
View File
@@ -37,7 +37,7 @@ void i2cInit()
GPIO_ResetBits(I2C_WP_GPIO, I2C_WP_GPIO_PIN);
I2C_InitTypeDef I2C_InitStructure;
I2C_InitStructure.I2C_ClockSpeed = I2C_SPEED;
I2C_InitStructure.I2C_ClockSpeed = I2C_CLK_RATE;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = 0x00;
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.0 KiB

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

After

Width:  |  Height:  |  Size: 8.8 KiB

+19
View File
@@ -174,3 +174,22 @@ void evalTimers(int16_t throttle, uint8_t tick10ms)
}
}
}
int16_t throttleSource2Source(int16_t thrSrc)
{
if (thrSrc == 0) return (int16_t)MIXSRC_Thr;
if (--thrSrc < NUM_POTS + NUM_SLIDERS)
return (int16_t)(thrSrc + MIXSRC_FIRST_POT);
return (int16_t)(thrSrc - (NUM_POTS + NUM_SLIDERS) + MIXSRC_FIRST_CH);
}
int16_t source2ThrottleSource(int16_t src)
{
if (src == MIXSRC_Thr)
return 0;
else if (src <= MIXSRC_LAST_POT)
return src - MIXSRC_FIRST_POT + 1;
else if (src <= MIXSRC_LAST_CH)
return src - MIXSRC_FIRST_CH + NUM_POTS + NUM_SLIDERS + 1;
return -1;
}
+3
View File
@@ -62,4 +62,7 @@ static inline tmr10ms_t get_tmr10ms()
return g_tmr10ms;
}
int16_t throttleSource2Source(int16_t thrSrc);
int16_t source2ThrottleSource(int16_t src);
#endif // _TIMERS_H_
+1 -1
View File
@@ -166,7 +166,7 @@
#define TR_CSWEQUAL "a=x\0 "
#define LEN_VCSWFUNC "\005"
#define TR_VCSWFUNC "---\0 " TR_CSWEQUAL "a~x\0 ""a>x\0 ""a<x\0 " TR_CSWRANGE "|a|>x""|a|<x""AND\0 ""OR\0 ""XOR\0 " TR_CSWSTAY "a=b\0 ""a>b\0 ""a<b\0 ""Δ}x\0 ""|Δ|}x" TR_CSWTIMER TR_CSWSTICKY
#define TR_VCSWFUNC "---\0 " TR_CSWEQUAL "a~x\0 ""a>x\0 ""a<x\0 " TR_CSWRANGE "|a|>x""|a|<x""AND\0 ""OR\0 ""XOR\0 " TR_CSWSTAY "a=b\0 ""a>b\0 ""a<b\0 " STR_CHAR_DELTA "}x\0 " "|" STR_CHAR_DELTA "|}x" TR_CSWTIMER TR_CSWSTICKY
#define LEN_VFSWFUNC "\012"