Compare commits

...

21 Commits

Author SHA1 Message Date
Andre Bernet 3b324d076a Release notes updated 2014-09-10 20:41:00 +02:00
Andre Bernet 91c922d5fb Wording / French translations 2014-09-10 20:27:43 +02:00
Andre Bernet eac918c2da SG switch warning was unreachable on Taranis 2014-09-10 20:13:26 +02:00
Andre Bernet b5f9c0ec84 On Taranis S3 was only hidden when the cursor was in the pot positions line 2014-09-10 20:05:50 +02:00
bsongis d1f54b099b Compilation failure 2014-09-10 20:04:41 +02:00
bsongis 7b98ad55c0 #1692 - We flush the queue instead of stopping the audio (the TADA sound
is cut otherwise)
2014-09-10 19:56:46 +02:00
bsongis d2cb7cb3dd Fixes #1697 2014-09-10 19:28:55 +02:00
bsongis be190b8bb1 Support for Lua dump files removed 2014-09-10 16:19:34 +02:00
bsongis 4b2c02b2c5 The Lua Wizard was broken in 2.0.11 2014-09-10 15:35:06 +02:00
bsongis 142d3fee1a Small alignment problem in protocols on 9X/9XR 2014-09-10 12:12:16 +02:00
bsongis 6a5e938ead Fixes #1692 2014-09-10 12:11:53 +02:00
bsongis 2d9ae108ff Fixes #1566 2014-09-10 12:07:14 +02:00
bsongis bae84e4e8c Navigation bug in protocol selection (9X/9XR only) 2014-09-10 11:51:39 +02:00
bsongis f4944eefdb Fixes the neutral value for PXX as described in #1694 2014-09-10 11:51:00 +02:00
bsongis 5d598cc6a1 Version and release notes updated 2014-09-10 11:32:36 +02:00
bsongis 945808d69b Fixes #1695 2014-09-10 11:32:36 +02:00
Bertrand Songis dbe512e45a Update DONATIONS.txt 2014-09-10 10:58:32 +02:00
bsongis 11efb5121e Fixes #1690 2014-09-10 08:16:57 +02:00
Bertrand Songis f6274f38aa Update DONATIONS.txt 2014-09-09 21:58:17 +02:00
Bertrand Songis cd1f20b8a0 Update DONATIONS.txt 2014-09-09 10:41:57 +02:00
Bertrand Songis e61b931ddb Update DONATIONS.txt 2014-09-09 07:13:13 +02:00
26 changed files with 1015 additions and 1038 deletions
+4
View File
@@ -589,3 +589,7 @@ Raimo Ruotsalainen
Brian Harris
Sebastian Blüml
Efisio Maxia
Jeff Theobald
Anthony Rizzo
Rodney Huddleston
Dietmar Drees
+6
View File
@@ -1,3 +1,9 @@
<h2>Version 2.0.11</h2>
<ul>
<li>Limits EEPROM export was broken (all boards except Taranis)</li>
<li>Fix issue when a GVAR was used as Offset</li>
</ul>
<h2>Version 2.0.10</h2>
<ul>
<li>Taranis is now the default board in General Settings</li>
+1 -1
View File
@@ -2,7 +2,7 @@ PROJECT( companion )
SET( C9X_VERSION_MAJOR "2" )
SET( C9X_VERSION_MINOR "0" )
SET( C9X_VERSION_REVISION "10" )
SET( C9X_VERSION_REVISION "11" )
SET( C9X_VERSION ${C9X_VERSION_MAJOR}.${C9X_VERSION_MINOR}.${C9X_VERSION_REVISION} )
CMAKE_MINIMUM_REQUIRED( VERSION 2.8 )
@@ -1039,6 +1039,8 @@ class MixField: public TransformedField {
mix.curve = CurveReference(CurveReference::CURVE_REF_DIFF, smallGvarToC9x(_curveParam));
else if (_curveParam > 6)
mix.curve = CurveReference(CurveReference::CURVE_REF_CUSTOM, _curveParam-6);
else if (_curveParam < 0)
mix.curve = CurveReference(CurveReference::CURVE_REF_CUSTOM, _curveParam);
else
mix.curve = CurveReference(CurveReference::CURVE_REF_FUNC, _curveParam);
}
@@ -1098,7 +1100,7 @@ class InputField: public TransformedField {
internalField.Append(new SignedField<6>(expo.carryTrim, "CarryTrim"));
internalField.Append(new UnsignedField<2>(expo.mode, "Mode"));
internalField.Append(new ZCharField<8>(expo.name));
internalField.Append(new SignedField<8>(expo.offset, "Offset"));
internalField.Append(new SignedField<8>(_offset, "Offset"));
internalField.Append(new CurveReferenceField(expo.curve, board, version));
internalField.Append(new SpareBitsField<8>());
}
@@ -1153,6 +1155,10 @@ class InputField: public TransformedField {
{
_weight = smallGvarToEEPROM(expo.weight);
if (IS_TARANIS(board) && version >= 216) {
_offset = smallGvarToEEPROM(expo.offset);
}
if (!IS_TARANIS(board) || version < 216) {
if (expo.curve.type==CurveReference::CURVE_REF_FUNC && expo.curve.value) {
_curveMode = true;
@@ -1184,6 +1190,10 @@ class InputField: public TransformedField {
expo.weight = smallGvarToC9x(_weight);
if (IS_TARANIS(board) && version >= 216) {
expo.offset = smallGvarToC9x(_offset);
}
if (!IS_TARANIS(board) || version < 216) {
if (!_curveMode)
expo.curve = CurveReference(CurveReference::CURVE_REF_EXPO, smallGvarToC9x(_curveParam));
@@ -1201,6 +1211,7 @@ class InputField: public TransformedField {
unsigned int version;
bool _curveMode;
int _weight;
int _offset;
int _curveParam;
};
+7 -8
View File
@@ -186,14 +186,14 @@ GVarGroup::GVarGroup(QCheckBox *weightGV, QAbstractSpinBox *weightSB, QComboBox
}
if (sb) {
sb->setMinimum(step*mini);
sb->setMaximum(step*maxi);
sb->setValue(step*val);
sb->setMinimum(mini);
sb->setMaximum(maxi);
sb->setValue(val);
}
else {
dsb->setMinimum(step*mini);
dsb->setMaximum(step*maxi);
dsb->setValue(step*val);
dsb->setMinimum(mini*step);
dsb->setMaximum(maxi*step);
dsb->setValue(val*step);
}
connect(weightSB, SIGNAL(editingFinished()), this, SLOT(valuesChanged()));
@@ -217,7 +217,7 @@ void GVarGroup::valuesChanged()
if (weightGV->isChecked())
weight = weightCB->itemData(weightCB->currentIndex()).toInt();
else if (sb)
weight = sb->value()/step;
weight = sb->value();
else
weight = dsb->value()/step;
}
@@ -1022,7 +1022,6 @@ QString index2version(int index)
int qunlink(const QString & fileName)
{
qDebug() << "unlinking "<< fileName;
QByteArray ba = fileName.toLatin1();
return unlink(ba.constData());
}
+1 -1
View File
@@ -42,7 +42,7 @@ class GVarGroup: public QObject {
Q_OBJECT
public:
GVarGroup(QCheckBox *weightGV, QAbstractSpinBox *weightSB, QComboBox *weightCB, int & weight, const int deflt, const int mini, const int maxi, const double step=1, bool allowGVars=true);
GVarGroup(QCheckBox *weightGV, QAbstractSpinBox *weightSB, QComboBox *weightCB, int & weight, const int deflt, const int mini, const int maxi, const double step=1.0, bool allowGVars=true);
protected slots:
void gvarCBChanged(int);
+15 -19
View File
@@ -11,17 +11,17 @@ LimitsGroup::LimitsGroup(FirmwareInterface * firmware, QGridLayout *gridLayout,
firmware(firmware),
spinbox(new QDoubleSpinBox()),
value(value),
step(1.0)
displayStep(0.1)
{
bool allowGVars = false;
int internalStep = 1;
spinbox->setProperty("index", row);
spinbox->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
spinbox->setAccelerated(true);
if (firmware->getCapability(PPMUnitMicroseconds)) {
step = 5.12;
displayStep = 0.512;
spinbox->setDecimals(1);
spinbox->setSuffix("us");
}
@@ -31,15 +31,14 @@ LimitsGroup::LimitsGroup(FirmwareInterface * firmware, QGridLayout *gridLayout,
}
if (IS_TARANIS(firmware->getBoard()) || deflt == 0 /*it's the offset*/) {
min *= 10;
max *= 10;
deflt *= 10;
step /= 10;
spinbox->setDecimals(1);
allowGVars = true;
}
spinbox->setSingleStep(step);
else {
internalStep *= 10;
}
spinbox->setSingleStep(displayStep*internalStep);
QHBoxLayout * horizontalLayout = new QHBoxLayout();
QCheckBox * gv = new QCheckBox(QObject::tr("GV"));
@@ -48,7 +47,7 @@ LimitsGroup::LimitsGroup(FirmwareInterface * firmware, QGridLayout *gridLayout,
horizontalLayout->addWidget(cb);
horizontalLayout->addWidget(spinbox);
gridLayout->addLayout(horizontalLayout, row, col, 1, 1);
gvarGroup = new GVarGroup(gv, spinbox, cb, value, deflt, min, max, step, allowGVars);
gvarGroup = new GVarGroup(gv, spinbox, cb, value, deflt, min, max, displayStep, allowGVars);
}
LimitsGroup::~LimitsGroup()
@@ -58,17 +57,14 @@ LimitsGroup::~LimitsGroup()
void LimitsGroup::updateMinMax(int max)
{
if (IS_TARANIS(firmware->getBoard())) {
max *= 10;
}
if (spinbox->maximum() == 0) {
spinbox->setMinimum(-step*max);
spinbox->setMinimum(-max*displayStep);
if (value < -max) {
value = -max;
}
}
if (spinbox->minimum() == 0) {
spinbox->setMaximum(step*max);
spinbox->setMaximum(max*displayStep);
if (value > max) {
value = max;
}
@@ -120,13 +116,13 @@ Channels::Channels(QWidget * parent, ModelData & model, GeneralSettings & genera
}
// Channel offset
limitsGroups << new LimitsGroup(firmware, gridLayout, i+1, col++, model.limitData[i].offset, -100, 100, 0);
limitsGroups << new LimitsGroup(firmware, gridLayout, i+1, col++, model.limitData[i].offset, -1000, 1000, 0);
// Channel min
limitsGroups << new LimitsGroup(firmware, gridLayout, i+1, col++, model.limitData[i].min, -model.getChannelsMax(), 0, -100);
limitsGroups << new LimitsGroup(firmware, gridLayout, i+1, col++, model.limitData[i].min, -model.getChannelsMax()*10, 0, -1000);
// Channel max
limitsGroups << new LimitsGroup(firmware, gridLayout, i+1, col++, model.limitData[i].max, 0, model.getChannelsMax(), 100);
limitsGroups << new LimitsGroup(firmware, gridLayout, i+1, col++, model.limitData[i].max, 0, model.getChannelsMax()*10, 1000);
// Channel inversion
QComboBox * invCB = new QComboBox(this);
@@ -211,7 +207,7 @@ void Channels::refreshExtendedLimits()
int channelMax = model.getChannelsMax();
foreach(LimitsGroup *group, limitsGroups) {
group->updateMinMax(channelMax);
group->updateMinMax(10*channelMax);
}
emit modified();
+1 -1
View File
@@ -19,7 +19,7 @@ class LimitsGroup
QDoubleSpinBox * spinbox;
GVarGroup * gvarGroup;
int & value;
double step;
double displayStep;
};
class Channels : public ModelPanel
+4 -4
View File
@@ -239,7 +239,7 @@ void LogicalSwitchesPanel::edited()
updateTimerParam(cswitchOffset[i], model.customSw[i].val2, 0.1);
break;
case LS_FAMILY_STAY:
cswitchOffset2[i]->setSpecialValueText(tr("(no release)"));
cswitchOffset2[i]->setSpecialValueText(tr("(instant)"));
if (sender() == cswitchOffset[i]) {
model.customSw[i].val2 = TimToVal(cswitchOffset[i]->value());
updateTimerParam(cswitchOffset[i], model.customSw[i].val2, 0.0);
@@ -249,7 +249,7 @@ void LogicalSwitchesPanel::edited()
}
updateTimerParam(cswitchOffset2[i], model.customSw[i].val2+model.customSw[i].val3, cswitchOffset[i]->value()-0.1);
if (model.customSw[i].val3 == 0) {
cswitchOffset2[i]->setSuffix("(infinite)");
cswitchOffset2[i]->setSuffix("(release)");
}
else {
cswitchOffset2[i]->setSuffix("");
@@ -334,9 +334,9 @@ void LogicalSwitchesPanel::setSwitchWidgetVisibility(int i)
populateSwitchCB(cswitchSource1[i], RawSwitch(model.customSw[i].val1), generalSettings, LogicalSwitchesContext);
updateTimerParam(cswitchOffset[i], model.customSw[i].val2, 0.0);
updateTimerParam(cswitchOffset2[i], model.customSw[i].val2+model.customSw[i].val3, cswitchOffset[i]->value()-0.1);
cswitchOffset2[i]->setSpecialValueText(tr("(no release)"));
cswitchOffset2[i]->setSpecialValueText(tr("(instant)"));
if (model.customSw[i].val3 == 0) {
cswitchOffset2[i]->setSuffix(tr("(infinite)"));
cswitchOffset2[i]->setSuffix(tr("(release)"));
}
else {
cswitchOffset2[i]->setSuffix("");
File diff suppressed because it is too large Load Diff
+10
View File
@@ -1,3 +1,13 @@
<h2>Version 2.0.11 / 2014-09-10</h2>
[9XR-PRO]
<ul>
<li>Audio broken (since we changed the ARM GCC compiler)
[Taranis]
<ul>
<li> Switch warning didn't allow access to SG
<li> Pot warning would show S3 when the cursor wasn't on the Pot Warning line
<h2>Version 2.0.10 / 2014-09-08</h2>
[All]
<ul>
+3 -4
View File
@@ -300,7 +300,7 @@ SHELL = sh
IMG2LBM = -python ../util/img2lbm.py
BIN2LBM = -python ../util/bin2lbm.py
TRANSLATE = -python ../util/translate.py
VERSION = 2.0.10
VERSION = 2.0.11
SRC =
CPPSRC =
@@ -735,10 +735,9 @@ ifeq ($(PCB), TARANIS)
CPPDEFS += -DLUA
INCDIRS += lua/src
CPPSRC += lua.cpp
LUASRC = lua/src/lapi.c lua/src/lcode.c lua/src/lctype.c lua/src/ldebug.c lua/src/ldo.c lua/src/ldump.c lua/src/lfunc.c lua/src/lgc.c lua/src/llex.c lua/src/lmem.c \
lua/src/lobject.c lua/src/lopcodes.c lua/src/lparser.c lua/src/lstate.c lua/src/lstring.c lua/src/ltable.c lua/src/ltm.c lua/src/lundump.c lua/src/lvm.c lua/src/lzio.c \
LUASRC = lua/src/lapi.c lua/src/lcode.c lua/src/lctype.c lua/src/ldebug.c lua/src/ldo.c lua/src/lfunc.c lua/src/lgc.c lua/src/llex.c lua/src/lmem.c \
lua/src/lobject.c lua/src/lopcodes.c lua/src/lparser.c lua/src/lstate.c lua/src/lstring.c lua/src/ltable.c lua/src/ltm.c lua/src/lvm.c lua/src/lzio.c \
lua/src/lbaselib.c lua/src/linit.c lua/src/lmathlib.c lua/src/loadlib.c lua/src/lauxlib.c lua/src/ltablib.c lua/src/lcorolib.c
# lua/src/loslib.c lua/src/lbitlib.c lua/src/lstrlib.c lua/src/liolib.c lua/src/ldblib.c
SRC += $(LUASRC)
LUADEP = lua_exports.cpp
endif
+9
View File
@@ -928,6 +928,15 @@ void AudioQueue::stopAll()
CoLeaveMutexSection(audioMutex);
}
void AudioQueue::flush()
{
CoEnterMutexSection(audioMutex);
widx = ridx; // clean the queue
varioContext.clear();
backgroundContext.clear();
CoLeaveMutexSection(audioMutex);
}
void audioEvent(uint8_t e, uint16_t f)
{
#if defined(HAPTIC)
+3
View File
@@ -163,6 +163,8 @@ class AudioQueue {
void stopAll();
void flush();
void pause(uint16_t tLen);
void stopSD();
@@ -328,6 +330,7 @@ void pushPrompt(uint16_t prompt, uint8_t id=0);
#define PLAY_FILE(f, flags, id) audioQueue.playFile((f), (flags), (id))
#define STOP_PLAY(id) audioQueue.stopPlay((id))
#define AUDIO_RESET() audioQueue.stopAll()
#define AUDIO_FLUSH() audioQueue.flush()
#if defined(SDCARD)
extern tmr10ms_t timeAutomaticPromptsSilence;
+1
View File
@@ -154,6 +154,7 @@ void audioDefevent(uint8_t e);
#define AUDIO_HEARTBEAT() audio.heartbeat()
#define IS_AUDIO_BUSY() audio.busy()
#define AUDIO_RESET()
#define AUDIO_FLUSH()
#define PLAY_PHASE_OFF(phase)
#define PLAY_PHASE_ON(phase)
+1
View File
@@ -99,6 +99,7 @@ void beep(uint8_t val);
#define IS_AUDIO_BUSY() (g_beepCnt || beepAgain || beepOn)
#define AUDIO_RESET()
#define AUDIO_FLUSH()
#define PLAY_PHASE_OFF(phase)
#define PLAY_PHASE_ON(phase)
+1
View File
@@ -385,6 +385,7 @@ void eeLoadModel(uint8_t id)
read32_eeprom_data((File_system[id+1].block_no << 12) + sizeof(struct t_eeprom_header), (uint8_t *)&g_model, size) ;
}
AUDIO_FLUSH();
flightReset();
logicalSwitchesReset();
+1
View File
@@ -969,6 +969,7 @@ void eeLoadModel(uint8_t id)
eeCheck(true);
}
AUDIO_FLUSH();
flightReset();
logicalSwitchesReset();
+4 -4
View File
@@ -1325,8 +1325,8 @@ void menuModelSetup(uint8_t event)
uint8_t x = MODEL_SETUP_2ND_COLUMN+5*FW;
for (uint8_t i=0; i<NUM_POTS ; i++) {
#if !defined(REVPLUS)
if (attr && i == POT3-POT1) {
if (m_posHorz==i+1) REPEAT_LAST_CURSOR_MOVE();
if (i == POT3-POT1) {
if (attr && (m_posHorz==i+1)) REPEAT_LAST_CURSOR_MOVE();
continue;
}
#endif
@@ -1353,7 +1353,7 @@ void menuModelSetup(uint8_t event)
uint8_t x = MODEL_SETUP_2ND_COLUMN+i*FW;
#if defined(PCBTARANIS) && !defined(REVPLUS)
if (i == POT3) {
if (m_posHorz == POT3) REPEAT_LAST_CURSOR_MOVE();
if (attr && m_posHorz == POT3) REPEAT_LAST_CURSOR_MOVE();
continue;
}
else if (i > POT3) {
@@ -1621,7 +1621,7 @@ void menuModelSetup(uint8_t event)
if (IS_PPM_PROTOCOL(protocol)) {
lcd_putsiAtt(MODEL_SETUP_2ND_COLUMN+7*FW, y, STR_NCHANNELS, g_model.ppmNCH+2, m_posHorz!=0 ? attr : 0);
}
else if (attr) {
else if (m_posHorz>0 && attr) {
MOVE_CURSOR_FROM_HERE();
}
if (attr && (editMode>0 || p1valdiff || (!IS_PPM_PROTOCOL(protocol) && !IS_DSM2_PROTOCOL(protocol)))) {
+11 -10
View File
@@ -1715,16 +1715,17 @@ void luaError(uint8_t error)
void luaExec(const char *filename)
{
luaInit();
standaloneScript.state = SCRIPT_NOFILE;
int result = luaLoad(filename, standaloneScript);
// TODO the same with run ...
if (result == SCRIPT_OK) {
luaState = INTERPRETER_RUNNING_STANDALONE_SCRIPT;
}
else {
luaError(result);
luaState = INTERPRETER_RELOAD_PERMANENT_SCRIPTS;
if (L) {
standaloneScript.state = SCRIPT_NOFILE;
int result = luaLoad(filename, standaloneScript);
// TODO the same with run ...
if (result == SCRIPT_OK) {
luaState = INTERPRETER_RUNNING_STANDALONE_SCRIPT;
}
else {
luaError(result);
luaState = INTERPRETER_RELOAD_PERMANENT_SCRIPTS;
}
}
}
+2 -2
View File
@@ -993,7 +993,7 @@ LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
return status;
}
#if 0
LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) {
int status;
TValue *o;
@@ -1007,7 +1007,7 @@ LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) {
lua_unlock(L);
return status;
}
#endif
LUA_API int lua_status (lua_State *L) {
return L->status;
+4 -1
View File
@@ -634,11 +634,14 @@ static void f_parser (lua_State *L, void *ud) {
Closure *cl;
struct SParser *p = cast(struct SParser *, ud);
int c = zgetc(p->z); /* read first character */
#if 0
if (c == LUA_SIGNATURE[0]) {
checkmode(L, p->mode, "binary");
cl = luaU_undump(L, p->z, &p->buff, p->name);
}
else {
else
#endif
{
checkmode(L, p->mode, "text");
cl = luaY_parser(L, p->z, &p->buff, &p->dyd, p->name, c);
}
+3 -6
View File
@@ -1490,12 +1490,9 @@ enum AUDIO_SOUNDS {
uint8_t outputsCount;
ScriptOutput outputs[MAX_SCRIPT_OUTPUTS];
};
enum InterpreterState {
INTERPRETER_RUNNING_PERMANENT_SCRIPTS,
INTERPRETER_RUNNING_STANDALONE_SCRIPT,
INTERPRETER_RELOAD_PERMANENT_SCRIPTS,
INTERPRETER_PANIC,
};
#define INTERPRETER_RUNNING_STANDALONE_SCRIPT 1
#define INTERPRETER_RELOAD_PERMANENT_SCRIPTS 2
#define INTERPRETER_PANIC 255
extern uint8_t luaState;
extern uint8_t luaScriptsCount;
extern ScriptInternalData standaloneScript;
+3 -2
View File
@@ -308,9 +308,10 @@ void putPcmHead()
putPcmPart( 0xC0 ) ;
}
uint16_t scaleForPXX(uint8_t i)
uint16_t scaleForPXX( uint8_t i )
{
return channelOutputs[i] * 3 / 4 + 2250 ;
int16_t value = ( ( i < 16 ) ? channelOutputs[i] * 3 / 4 : 0 ) + 1024;
return limit<uint16_t>(1, value, 2046);
}
void setupPulsesPXX()
+2
View File
@@ -107,6 +107,7 @@ bool dacQueue(AudioBuffer *buffer)
return false;
}
#pragma GCC optimize ("O1")
extern "C" void DAC_IRQHandler()
{
AudioBuffer *nextBuffer = audioQueue.getNextFilledBuffer();
@@ -118,6 +119,7 @@ extern "C" void DAC_IRQHandler()
dacStop();
}
}
#pragma GCC optimize ("O2")
// Sound routines
void audioInit()
+10 -2
View File
@@ -522,7 +522,11 @@
#define TR_TTRIM TR("T-Trim", INDENT "Trim Idle Only")
#define TR_BEEPCTR TR("Ctr Beep", "Center Beep")
#define TR_PROTO TR(INDENT "Proto", INDENT "Protocol")
#define TR_PPMFRAME TR(INDENT "PPM frame", INDENT "PPM frame")
#if defined(CPUARM)
#define TR_PPMFRAME INDENT "PPM frame"
#else
#define TR_PPMFRAME "PPM frame"
#endif
#define TR_MS "ms"
#define TR_SWITCH "Switch"
#define TR_TRIMS "Trims"
@@ -680,7 +684,11 @@
#define TR_MENUTEMPLATES "TEMPLATES"
#define TR_MENUSTAT "STATS"
#define TR_MENUDEBUG "DEBUG"
#define TR_RXNUM TR(INDENT "RxNum", INDENT "Receiver No.")
#if defined(CPUARM)
#define TR_RXNUM TR(INDENT "RxNum", INDENT "Receiver No.")
#else
#define TR_RXNUM "RxNum"
#endif
#define TR_SYNCMENU "[Sync]"
#define TR_LIMIT INDENT "Limit"
#define TR_MINRSSI "Min Rssi"