Initial Commit
3
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
/FIRMWARE/*.bin
|
||||
*.wav
|
||||
.DS_Store
|
||||
682
BACKUP/CAR2-2023-10-06.yml
Executable file
|
|
@ -0,0 +1,682 @@
|
|||
semver: 2.10.0
|
||||
header:
|
||||
name: "CAR2"
|
||||
timers:
|
||||
0:
|
||||
start: 300
|
||||
swtch: "L1"
|
||||
value: 187
|
||||
mode: ON
|
||||
countdownBeep: 2
|
||||
minuteBeep: 1
|
||||
persistent: 2
|
||||
countdownStart: 1
|
||||
showElapsed: 0
|
||||
extraHaptic: 0
|
||||
name: "Tsb"
|
||||
telemetryProtocol: 0
|
||||
thrTrim: 0
|
||||
noGlobalFunctions: 0
|
||||
displayTrims: 2
|
||||
ignoreSensorIds: 0
|
||||
trimInc: 0
|
||||
disableThrottleWarning: 0
|
||||
displayChecklist: 0
|
||||
extendedLimits: 1
|
||||
extendedTrims: 0
|
||||
throttleReversed: 0
|
||||
enableCustomThrottleWarning: 0
|
||||
disableTelemetryWarning: 0
|
||||
showInstanceIds: 0
|
||||
customThrottleWarningPosition: 0
|
||||
beepANACenter: 0
|
||||
mixData:
|
||||
-
|
||||
weight: 100
|
||||
destCh: 0
|
||||
srcRaw: I0
|
||||
carryTrim: 0
|
||||
mixWarn: 0
|
||||
mltpx: ADD
|
||||
offset: 0
|
||||
swtch: "NONE"
|
||||
flightModes: 000000000
|
||||
delayUp: 0
|
||||
delayDown: 0
|
||||
speedUp: 0
|
||||
speedDown: 0
|
||||
name: ""
|
||||
-
|
||||
weight: 100
|
||||
destCh: 1
|
||||
srcRaw: I1
|
||||
carryTrim: 0
|
||||
mixWarn: 0
|
||||
mltpx: ADD
|
||||
offset: 0
|
||||
swtch: "NONE"
|
||||
flightModes: 000000000
|
||||
delayUp: 0
|
||||
delayDown: 0
|
||||
speedUp: 0
|
||||
speedDown: 0
|
||||
name: ""
|
||||
-
|
||||
weight: 100
|
||||
destCh: 2
|
||||
srcRaw: I2
|
||||
carryTrim: 0
|
||||
mixWarn: 0
|
||||
mltpx: ADD
|
||||
offset: 0
|
||||
swtch: "NONE"
|
||||
flightModes: 000000000
|
||||
delayUp: 0
|
||||
delayDown: 0
|
||||
speedUp: 0
|
||||
speedDown: 0
|
||||
name: ""
|
||||
-
|
||||
weight: 100
|
||||
destCh: 3
|
||||
srcRaw: SB
|
||||
carryTrim: 0
|
||||
mixWarn: 0
|
||||
mltpx: ADD
|
||||
offset: 0
|
||||
swtch: "NONE"
|
||||
flightModes: 000000000
|
||||
delayUp: 0
|
||||
delayDown: 0
|
||||
speedUp: 0
|
||||
speedDown: 0
|
||||
name: ""
|
||||
-
|
||||
weight: 100
|
||||
destCh: 4
|
||||
srcRaw: I4
|
||||
carryTrim: 0
|
||||
mixWarn: 0
|
||||
mltpx: ADD
|
||||
offset: 0
|
||||
swtch: "NONE"
|
||||
flightModes: 000000000
|
||||
delayUp: 0
|
||||
delayDown: 0
|
||||
speedUp: 0
|
||||
speedDown: 0
|
||||
name: ""
|
||||
-
|
||||
weight: 100
|
||||
destCh: 5
|
||||
srcRaw: I5
|
||||
carryTrim: 0
|
||||
mixWarn: 0
|
||||
mltpx: ADD
|
||||
offset: 0
|
||||
swtch: "NONE"
|
||||
flightModes: 000000000
|
||||
delayUp: 0
|
||||
delayDown: 0
|
||||
speedUp: 0
|
||||
speedDown: 0
|
||||
name: ""
|
||||
-
|
||||
weight: 100
|
||||
destCh: 6
|
||||
srcRaw: SC
|
||||
carryTrim: 0
|
||||
mixWarn: 0
|
||||
mltpx: ADD
|
||||
offset: 0
|
||||
swtch: "NONE"
|
||||
flightModes: 000000000
|
||||
delayUp: 0
|
||||
delayDown: 0
|
||||
speedUp: 0
|
||||
speedDown: 0
|
||||
name: ""
|
||||
-
|
||||
weight: 100
|
||||
destCh: 7
|
||||
srcRaw: SD
|
||||
carryTrim: 0
|
||||
mixWarn: 0
|
||||
mltpx: ADD
|
||||
offset: 0
|
||||
swtch: "NONE"
|
||||
flightModes: 000000000
|
||||
delayUp: 0
|
||||
delayDown: 0
|
||||
speedUp: 0
|
||||
speedDown: 0
|
||||
name: ""
|
||||
limitData:
|
||||
0:
|
||||
min: 0
|
||||
max: 0
|
||||
ppmCenter: 0
|
||||
offset: 0
|
||||
symetrical: 0
|
||||
revert: 1
|
||||
curve: 0
|
||||
name: ""
|
||||
expoData:
|
||||
-
|
||||
mode: 3
|
||||
scale: 0
|
||||
trimSource: 0
|
||||
srcRaw: TH
|
||||
chn: 0
|
||||
swtch: "NONE"
|
||||
flightModes: 000000000
|
||||
weight: 100
|
||||
name: ""
|
||||
offset: 0
|
||||
curve:
|
||||
type: 1
|
||||
value: 0
|
||||
-
|
||||
mode: 3
|
||||
scale: 0
|
||||
trimSource: 0
|
||||
srcRaw: ST
|
||||
chn: 1
|
||||
swtch: "NONE"
|
||||
flightModes: 000000000
|
||||
weight: 100
|
||||
name: ""
|
||||
offset: 0
|
||||
curve:
|
||||
type: 1
|
||||
value: 0
|
||||
-
|
||||
mode: 3
|
||||
scale: 0
|
||||
trimSource: 0
|
||||
srcRaw: SA
|
||||
chn: 2
|
||||
swtch: "NONE"
|
||||
flightModes: 000000000
|
||||
weight: 100
|
||||
name: ""
|
||||
offset: 0
|
||||
curve:
|
||||
type: 1
|
||||
value: 0
|
||||
-
|
||||
mode: 3
|
||||
scale: 0
|
||||
trimSource: 0
|
||||
srcRaw: SB
|
||||
chn: 3
|
||||
swtch: "NONE"
|
||||
flightModes: 000000000
|
||||
weight: 100
|
||||
name: ""
|
||||
offset: 0
|
||||
curve:
|
||||
type: 1
|
||||
value: 0
|
||||
-
|
||||
mode: 3
|
||||
scale: 0
|
||||
trimSource: 0
|
||||
srcRaw: P1
|
||||
chn: 4
|
||||
swtch: "NONE"
|
||||
flightModes: 000000000
|
||||
weight: 100
|
||||
name: ""
|
||||
offset: 0
|
||||
curve:
|
||||
type: 1
|
||||
value: 0
|
||||
-
|
||||
mode: 3
|
||||
scale: 0
|
||||
trimSource: 0
|
||||
srcRaw: P2
|
||||
chn: 5
|
||||
swtch: "NONE"
|
||||
flightModes: 000000000
|
||||
weight: 100
|
||||
name: ""
|
||||
offset: 0
|
||||
curve:
|
||||
type: 1
|
||||
value: 0
|
||||
-
|
||||
mode: 3
|
||||
scale: 0
|
||||
trimSource: 0
|
||||
srcRaw: SC
|
||||
chn: 6
|
||||
swtch: "NONE"
|
||||
flightModes: 000000000
|
||||
weight: 100
|
||||
name: ""
|
||||
offset: 0
|
||||
curve:
|
||||
type: 1
|
||||
value: 0
|
||||
-
|
||||
mode: 3
|
||||
scale: 0
|
||||
trimSource: 0
|
||||
srcRaw: SD
|
||||
chn: 7
|
||||
swtch: "NONE"
|
||||
flightModes: 000000000
|
||||
weight: 100
|
||||
name: ""
|
||||
offset: 0
|
||||
curve:
|
||||
type: 1
|
||||
value: 0
|
||||
curves:
|
||||
31:
|
||||
type: 1
|
||||
smooth: 0
|
||||
points: -1
|
||||
name: "CNT"
|
||||
points:
|
||||
155:
|
||||
val: -100
|
||||
158:
|
||||
val: 100
|
||||
159:
|
||||
val: -1
|
||||
160:
|
||||
val: 1
|
||||
logicalSw:
|
||||
0:
|
||||
func: FUNC_STICKY
|
||||
def: "SB0,SB0"
|
||||
andsw: "NONE"
|
||||
delay: 0
|
||||
duration: 0
|
||||
1:
|
||||
func: FUNC_VNEG
|
||||
def: "I0,-5"
|
||||
andsw: "NONE"
|
||||
delay: 0
|
||||
duration: 0
|
||||
2:
|
||||
func: FUNC_VPOS
|
||||
def: "TH,5"
|
||||
andsw: "NONE"
|
||||
delay: 0
|
||||
duration: 0
|
||||
3:
|
||||
func: FUNC_VNEG
|
||||
def: "I0,-75"
|
||||
andsw: "NONE"
|
||||
delay: 0
|
||||
duration: 0
|
||||
4:
|
||||
func: FUNC_AND
|
||||
def: "!L3,!L2"
|
||||
andsw: "NONE"
|
||||
delay: 0
|
||||
duration: 0
|
||||
customFn:
|
||||
0:
|
||||
swtch: "L1"
|
||||
func: PLAY_TRACK
|
||||
def: "start,1x"
|
||||
1:
|
||||
swtch: "!L1"
|
||||
func: PLAY_TRACK
|
||||
def: "stop,1x"
|
||||
2:
|
||||
swtch: "L2"
|
||||
func: RGB_LED
|
||||
def: "red"
|
||||
3:
|
||||
swtch: "L3"
|
||||
func: RGB_LED
|
||||
def: "blue"
|
||||
4:
|
||||
swtch: "L4"
|
||||
func: RGB_LED
|
||||
def: "police"
|
||||
5:
|
||||
swtch: "L5"
|
||||
func: RGB_LED
|
||||
def: "green"
|
||||
thrTraceSrc: TH
|
||||
switchWarningState: AuBuCuDu
|
||||
rssiSource: none
|
||||
rfAlarms:
|
||||
warning: 45
|
||||
critical: 42
|
||||
thrTrimSw: 0
|
||||
potsWarnMode: WARN_OFF
|
||||
jitterFilter: GLOBAL
|
||||
moduleData:
|
||||
0:
|
||||
type: TYPE_CROSSFIRE
|
||||
subType: 0
|
||||
channelsStart: 0
|
||||
channelsCount: 16
|
||||
failsafeMode: NOT_SET
|
||||
mod:
|
||||
crsf:
|
||||
telemetryBaudrate: 0
|
||||
trainerData:
|
||||
mode: SLAVE
|
||||
channelsStart: 0
|
||||
channelsCount: 0
|
||||
frameLength: 0
|
||||
delay: 0
|
||||
pulsePol: 0
|
||||
inputNames:
|
||||
0:
|
||||
val: "Th"
|
||||
1:
|
||||
val: "St"
|
||||
2:
|
||||
val: "Sa"
|
||||
3:
|
||||
val: "Sb"
|
||||
potsWarnEnabled: 0
|
||||
telemetrySensors:
|
||||
0:
|
||||
id1:
|
||||
id: 20
|
||||
id2:
|
||||
instance: 0
|
||||
label: "1RSS"
|
||||
subId: 0
|
||||
type: TYPE_CUSTOM
|
||||
unit: 17
|
||||
prec: 0
|
||||
autoOffset: 0
|
||||
filter: 0
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
1:
|
||||
id1:
|
||||
id: 20
|
||||
id2:
|
||||
instance: 1
|
||||
label: "2RSS"
|
||||
subId: 0
|
||||
type: TYPE_CUSTOM
|
||||
unit: 17
|
||||
prec: 0
|
||||
autoOffset: 0
|
||||
filter: 0
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
2:
|
||||
id1:
|
||||
id: 20
|
||||
id2:
|
||||
instance: 2
|
||||
label: "RQly"
|
||||
subId: 0
|
||||
type: TYPE_CUSTOM
|
||||
unit: 13
|
||||
prec: 0
|
||||
autoOffset: 0
|
||||
filter: 0
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
3:
|
||||
id1:
|
||||
id: 20
|
||||
id2:
|
||||
instance: 3
|
||||
label: "RSNR"
|
||||
subId: 0
|
||||
type: TYPE_CUSTOM
|
||||
unit: 17
|
||||
prec: 0
|
||||
autoOffset: 0
|
||||
filter: 0
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
4:
|
||||
id1:
|
||||
id: 20
|
||||
id2:
|
||||
instance: 4
|
||||
label: "ANT"
|
||||
subId: 0
|
||||
type: TYPE_CUSTOM
|
||||
unit: 0
|
||||
prec: 0
|
||||
autoOffset: 0
|
||||
filter: 0
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
5:
|
||||
id1:
|
||||
id: 20
|
||||
id2:
|
||||
instance: 5
|
||||
label: "RFMD"
|
||||
subId: 0
|
||||
type: TYPE_CUSTOM
|
||||
unit: 0
|
||||
prec: 0
|
||||
autoOffset: 0
|
||||
filter: 0
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
6:
|
||||
id1:
|
||||
id: 20
|
||||
id2:
|
||||
instance: 6
|
||||
label: "TPWR"
|
||||
subId: 0
|
||||
type: TYPE_CUSTOM
|
||||
unit: 16
|
||||
prec: 0
|
||||
autoOffset: 0
|
||||
filter: 0
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
7:
|
||||
id1:
|
||||
id: 20
|
||||
id2:
|
||||
instance: 7
|
||||
label: "TRSS"
|
||||
subId: 0
|
||||
type: TYPE_CUSTOM
|
||||
unit: 17
|
||||
prec: 0
|
||||
autoOffset: 0
|
||||
filter: 0
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
8:
|
||||
id1:
|
||||
id: 20
|
||||
id2:
|
||||
instance: 8
|
||||
label: "TQly"
|
||||
subId: 0
|
||||
type: TYPE_CUSTOM
|
||||
unit: 13
|
||||
prec: 0
|
||||
autoOffset: 0
|
||||
filter: 0
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
9:
|
||||
id1:
|
||||
id: 20
|
||||
id2:
|
||||
instance: 9
|
||||
label: "TSNR"
|
||||
subId: 0
|
||||
type: TYPE_CUSTOM
|
||||
unit: 17
|
||||
prec: 0
|
||||
autoOffset: 0
|
||||
filter: 0
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
10:
|
||||
id1:
|
||||
id: 8
|
||||
id2:
|
||||
instance: 0
|
||||
label: "RxBt"
|
||||
subId: 0
|
||||
type: TYPE_CUSTOM
|
||||
unit: 1
|
||||
prec: 1
|
||||
autoOffset: 0
|
||||
filter: 0
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
11:
|
||||
id1:
|
||||
id: 8
|
||||
id2:
|
||||
instance: 1
|
||||
label: "Curr"
|
||||
subId: 0
|
||||
type: TYPE_CUSTOM
|
||||
unit: 2
|
||||
prec: 1
|
||||
autoOffset: 0
|
||||
filter: 0
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
12:
|
||||
id1:
|
||||
id: 8
|
||||
id2:
|
||||
instance: 2
|
||||
label: "Capa"
|
||||
subId: 0
|
||||
type: TYPE_CUSTOM
|
||||
unit: 14
|
||||
prec: 0
|
||||
autoOffset: 0
|
||||
filter: 0
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
13:
|
||||
id1:
|
||||
id: 8
|
||||
id2:
|
||||
instance: 3
|
||||
label: "Bat%"
|
||||
subId: 0
|
||||
type: TYPE_CUSTOM
|
||||
unit: 13
|
||||
prec: 0
|
||||
autoOffset: 0
|
||||
filter: 0
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
screens:
|
||||
0:
|
||||
type: VALUES
|
||||
u:
|
||||
lines:
|
||||
0:
|
||||
sources:
|
||||
0:
|
||||
val: tele(10)
|
||||
1:
|
||||
val: tele(2)
|
||||
1:
|
||||
sources:
|
||||
0:
|
||||
val: Tmr1
|
||||
1:
|
||||
val: tele(6)
|
||||
view: 0
|
||||
modelRegistrationID: "*\x15*\x15!\x03%\x07"
|
||||
usbJoystickExtMode: 0
|
||||
usbJoystickIfMode: JOYSTICK
|
||||
usbJoystickCircularCut: 0
|
||||
radioGFDisabled: GLOBAL
|
||||
radioTrainerDisabled: GLOBAL
|
||||
modelHeliDisabled: GLOBAL
|
||||
modelFMDisabled: GLOBAL
|
||||
modelCurvesDisabled: GLOBAL
|
||||
modelGVDisabled: GLOBAL
|
||||
modelLSDisabled: GLOBAL
|
||||
modelSFDisabled: GLOBAL
|
||||
modelCustomScriptsDisabled: GLOBAL
|
||||
modelTelemetryDisabled: GLOBAL
|
||||
2
FIRMWARE/readme.txt
Executable file
|
|
@ -0,0 +1,2 @@
|
|||
You can put firmware for your modules or radio in this folder.
|
||||
Files in this folder are NOT automatically applied.
|
||||
1
LOGS/readme.txt
Executable file
|
|
@ -0,0 +1 @@
|
|||
Logs files created by "SD Logs" special function will be stored in this directory.
|
||||
3
MODELS/README.txt
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
Model configuration files go in this directory. On colorlcd radios, there is
|
||||
also a `models.yml` file which controls which models are shown, and in what
|
||||
order they are shown.
|
||||
525
MODELS/model00.yml
Normal file
|
|
@ -0,0 +1,525 @@
|
|||
semver: 2.11.1
|
||||
header:
|
||||
name: KRATON
|
||||
bitmap: ""
|
||||
labels: ""
|
||||
modelId:
|
||||
0:
|
||||
val: 0
|
||||
timers:
|
||||
0:
|
||||
swtch: L1
|
||||
mode: OFF
|
||||
name: ""
|
||||
minuteBeep: 0
|
||||
countdownBeep: 0
|
||||
start: 0
|
||||
persistent: 0
|
||||
countdownStart: 0
|
||||
value: 297
|
||||
showElapsed: 0
|
||||
extraHaptic: 0
|
||||
noGlobalFunctions: 0
|
||||
thrTrim: 0
|
||||
trimInc: 0
|
||||
displayTrims: 2
|
||||
ignoreSensorIds: 0
|
||||
showInstanceIds: 0
|
||||
disableThrottleWarning: 0
|
||||
enableCustomThrottleWarning: 0
|
||||
customThrottleWarningPosition: 0
|
||||
beepANACenter: 0
|
||||
extendedLimits: 1
|
||||
extendedTrims: 0
|
||||
throttleReversed: 0
|
||||
checklistInteractive: 0
|
||||
flightModeData:
|
||||
0:
|
||||
trim:
|
||||
3:
|
||||
value: 2
|
||||
mode: 0
|
||||
name: 100pct
|
||||
fadeIn: 0
|
||||
fadeOut: 0
|
||||
gvars:
|
||||
0:
|
||||
val: 100
|
||||
1:
|
||||
swtch: "!L2"
|
||||
name: Disarmed
|
||||
fadeIn: 0
|
||||
fadeOut: 0
|
||||
gvars:
|
||||
0:
|
||||
val: 0
|
||||
2:
|
||||
swtch: SA1
|
||||
name: 60pct
|
||||
fadeIn: 0
|
||||
fadeOut: 0
|
||||
gvars:
|
||||
0:
|
||||
val: 60
|
||||
3:
|
||||
swtch: SA2
|
||||
name: 30pct
|
||||
fadeIn: 0
|
||||
fadeOut: 0
|
||||
gvars:
|
||||
0:
|
||||
val: 30
|
||||
mixData:
|
||||
- destCh: 0
|
||||
srcRaw: I0
|
||||
weight: 100
|
||||
swtch: NONE
|
||||
curve:
|
||||
type: 0
|
||||
value: 0
|
||||
delayPrec: 0
|
||||
delayUp: 0
|
||||
delayDown: 0
|
||||
speedPrec: 0
|
||||
speedUp: 0
|
||||
speedDown: 0
|
||||
carryTrim: 0
|
||||
mltpx: ADD
|
||||
mixWarn: 0
|
||||
flightModes: 000000000
|
||||
offset: 0
|
||||
name: ""
|
||||
- destCh: 1
|
||||
srcRaw: I1
|
||||
weight: gv(0)
|
||||
swtch: NONE
|
||||
curve:
|
||||
type: 0
|
||||
value: 0
|
||||
delayPrec: 0
|
||||
delayUp: 0
|
||||
delayDown: 0
|
||||
speedPrec: 0
|
||||
speedUp: 0
|
||||
speedDown: 0
|
||||
carryTrim: 0
|
||||
mltpx: ADD
|
||||
mixWarn: 0
|
||||
flightModes: 000000000
|
||||
offset: 0
|
||||
name: ""
|
||||
expoData:
|
||||
- srcRaw: ST
|
||||
scale: 0
|
||||
mode: 3
|
||||
chn: 0
|
||||
swtch: NONE
|
||||
flightModes: 000000000
|
||||
weight: 100
|
||||
offset: 0
|
||||
curve:
|
||||
type: 1
|
||||
value: 0
|
||||
trimSource: 0
|
||||
name: ""
|
||||
- srcRaw: TH
|
||||
scale: 0
|
||||
mode: 3
|
||||
chn: 1
|
||||
swtch: NONE
|
||||
flightModes: 000000000
|
||||
weight: 100
|
||||
offset: 0
|
||||
curve:
|
||||
type: 1
|
||||
value: 0
|
||||
trimSource: 0
|
||||
name: ""
|
||||
inputNames:
|
||||
0:
|
||||
val: St
|
||||
1:
|
||||
val: Th
|
||||
curves:
|
||||
31:
|
||||
type: 1
|
||||
smooth: 0
|
||||
points: -1
|
||||
name: CNT
|
||||
points:
|
||||
155:
|
||||
val: -100
|
||||
156:
|
||||
val: 0
|
||||
157:
|
||||
val: 0
|
||||
158:
|
||||
val: 100
|
||||
159:
|
||||
val: -1
|
||||
160:
|
||||
val: 1
|
||||
logicalSw:
|
||||
0:
|
||||
func: FUNC_EDGE
|
||||
def: SC2,0,-
|
||||
delay: 0
|
||||
duration: 0
|
||||
andsw: NONE
|
||||
lsPersist: 0
|
||||
lsState: 0
|
||||
1:
|
||||
func: FUNC_STICKY
|
||||
def: L1,L1
|
||||
delay: 0
|
||||
duration: 0
|
||||
andsw: NONE
|
||||
lsPersist: 0
|
||||
lsState: 0
|
||||
customFn:
|
||||
0:
|
||||
swtch: "!L2"
|
||||
func: RGB_LED
|
||||
def: rgbLop,1,On
|
||||
1:
|
||||
swtch: SA0
|
||||
func: RGB_LED
|
||||
def: green,1,On
|
||||
2:
|
||||
swtch: SA1
|
||||
func: RGB_LED
|
||||
def: yellow,1,On
|
||||
3:
|
||||
swtch: SA2
|
||||
func: RGB_LED
|
||||
def: orange,1,On
|
||||
thrTraceSrc: TH
|
||||
thrTrimSw: 0
|
||||
potsWarnMode: WARN_OFF
|
||||
potsWarnEnabled: 0
|
||||
jitterFilter: GLOBAL
|
||||
displayChecklist: 0
|
||||
gvars:
|
||||
0:
|
||||
name: TH
|
||||
min: 0
|
||||
max: 0
|
||||
popup: 0
|
||||
prec: 0
|
||||
unit: 0
|
||||
telemetryProtocol: 0
|
||||
varioData:
|
||||
source: none
|
||||
centerSilent: 0
|
||||
centerMax: 0
|
||||
centerMin: 0
|
||||
min: 0
|
||||
max: 0
|
||||
rssiSource: none
|
||||
rfAlarms:
|
||||
warning: 45
|
||||
critical: 42
|
||||
disableTelemetryWarning: 0
|
||||
moduleData:
|
||||
0:
|
||||
type: TYPE_MULTIMODULE
|
||||
subType: 6,4
|
||||
channelsStart: 0
|
||||
channelsCount: 16
|
||||
failsafeMode: NOT_SET
|
||||
mod:
|
||||
multi:
|
||||
disableTelemetry: 0
|
||||
disableMapping: 0
|
||||
autoBindMode: 1
|
||||
lowPowerMode: 0
|
||||
optionValue: 0
|
||||
trainerData:
|
||||
mode: OFF
|
||||
channelsStart: 0
|
||||
channelsCount: -8
|
||||
frameLength: 0
|
||||
delay: 0
|
||||
pulsePol: 0
|
||||
telemetrySensors:
|
||||
0:
|
||||
type: TYPE_CUSTOM
|
||||
id1:
|
||||
id: 20
|
||||
subId: 0
|
||||
id2:
|
||||
instance: 0
|
||||
label: 1RSS
|
||||
unit: 17
|
||||
prec: 0
|
||||
autoOffset: 0
|
||||
filter: 0
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
1:
|
||||
type: TYPE_CUSTOM
|
||||
id1:
|
||||
id: 20
|
||||
subId: 0
|
||||
id2:
|
||||
instance: 1
|
||||
label: 2RSS
|
||||
unit: 17
|
||||
prec: 0
|
||||
autoOffset: 0
|
||||
filter: 0
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
2:
|
||||
type: TYPE_CUSTOM
|
||||
id1:
|
||||
id: 20
|
||||
subId: 0
|
||||
id2:
|
||||
instance: 2
|
||||
label: RQly
|
||||
unit: 13
|
||||
prec: 0
|
||||
autoOffset: 0
|
||||
filter: 0
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
3:
|
||||
type: TYPE_CUSTOM
|
||||
id1:
|
||||
id: 20
|
||||
subId: 0
|
||||
id2:
|
||||
instance: 3
|
||||
label: RSNR
|
||||
unit: 17
|
||||
prec: 0
|
||||
autoOffset: 0
|
||||
filter: 0
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
4:
|
||||
type: TYPE_CUSTOM
|
||||
id1:
|
||||
id: 20
|
||||
subId: 0
|
||||
id2:
|
||||
instance: 4
|
||||
label: ANT
|
||||
unit: 0
|
||||
prec: 0
|
||||
autoOffset: 0
|
||||
filter: 0
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
5:
|
||||
type: TYPE_CUSTOM
|
||||
id1:
|
||||
id: 20
|
||||
subId: 0
|
||||
id2:
|
||||
instance: 5
|
||||
label: RFMD
|
||||
unit: 0
|
||||
prec: 0
|
||||
autoOffset: 0
|
||||
filter: 0
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
6:
|
||||
type: TYPE_CUSTOM
|
||||
id1:
|
||||
id: 20
|
||||
subId: 0
|
||||
id2:
|
||||
instance: 6
|
||||
label: TPWR
|
||||
unit: 16
|
||||
prec: 0
|
||||
autoOffset: 0
|
||||
filter: 0
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
7:
|
||||
type: TYPE_CUSTOM
|
||||
id1:
|
||||
id: 20
|
||||
subId: 0
|
||||
id2:
|
||||
instance: 7
|
||||
label: TRSS
|
||||
unit: 17
|
||||
prec: 0
|
||||
autoOffset: 0
|
||||
filter: 0
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
8:
|
||||
type: TYPE_CUSTOM
|
||||
id1:
|
||||
id: 20
|
||||
subId: 0
|
||||
id2:
|
||||
instance: 8
|
||||
label: TQly
|
||||
unit: 13
|
||||
prec: 0
|
||||
autoOffset: 0
|
||||
filter: 0
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
9:
|
||||
type: TYPE_CUSTOM
|
||||
id1:
|
||||
id: 20
|
||||
subId: 0
|
||||
id2:
|
||||
instance: 9
|
||||
label: TSNR
|
||||
unit: 17
|
||||
prec: 0
|
||||
autoOffset: 0
|
||||
filter: 0
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
10:
|
||||
type: TYPE_CUSTOM
|
||||
id1:
|
||||
id: 8
|
||||
subId: 0
|
||||
id2:
|
||||
instance: 0
|
||||
label: RxBt
|
||||
unit: 1
|
||||
prec: 1
|
||||
autoOffset: 0
|
||||
filter: 0
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
11:
|
||||
type: TYPE_CUSTOM
|
||||
id1:
|
||||
id: 8
|
||||
subId: 0
|
||||
id2:
|
||||
instance: 1
|
||||
label: Curr
|
||||
unit: 2
|
||||
prec: 1
|
||||
autoOffset: 0
|
||||
filter: 0
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
12:
|
||||
type: TYPE_CUSTOM
|
||||
id1:
|
||||
id: 8
|
||||
subId: 0
|
||||
id2:
|
||||
instance: 2
|
||||
label: Capa
|
||||
unit: 14
|
||||
prec: 0
|
||||
autoOffset: 0
|
||||
filter: 0
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
13:
|
||||
type: TYPE_CUSTOM
|
||||
id1:
|
||||
id: 8
|
||||
subId: 0
|
||||
id2:
|
||||
instance: 3
|
||||
label: Bat
|
||||
unit: 13
|
||||
prec: 0
|
||||
autoOffset: 0
|
||||
filter: 0
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
modelRegistrationID: "*\x15*\x15!\x03%\x07"
|
||||
hatsMode: GLOBAL
|
||||
usbJoystickExtMode: 0
|
||||
usbJoystickIfMode: JOYSTICK
|
||||
usbJoystickCircularCut: 0
|
||||
radioGFDisabled: GLOBAL
|
||||
radioTrainerDisabled: GLOBAL
|
||||
modelHeliDisabled: GLOBAL
|
||||
modelFMDisabled: GLOBAL
|
||||
modelCurvesDisabled: GLOBAL
|
||||
modelGVDisabled: GLOBAL
|
||||
modelLSDisabled: GLOBAL
|
||||
modelSFDisabled: GLOBAL
|
||||
modelCustomScriptsDisabled: GLOBAL
|
||||
modelTelemetryDisabled: GLOBAL
|
||||
395
MODELS/model01.yml
Normal file
|
|
@ -0,0 +1,395 @@
|
|||
semver: 2.11.1
|
||||
header:
|
||||
name: DT4.18
|
||||
bitmap: ""
|
||||
labels: ""
|
||||
modelId:
|
||||
0:
|
||||
val: 0
|
||||
noGlobalFunctions: 0
|
||||
thrTrim: 0
|
||||
trimInc: 0
|
||||
displayTrims: 2
|
||||
ignoreSensorIds: 0
|
||||
showInstanceIds: 0
|
||||
disableThrottleWarning: 0
|
||||
enableCustomThrottleWarning: 0
|
||||
customThrottleWarningPosition: 0
|
||||
beepANACenter: 0
|
||||
extendedLimits: 0
|
||||
extendedTrims: 0
|
||||
throttleReversed: 1
|
||||
checklistInteractive: 0
|
||||
flightModeData:
|
||||
0:
|
||||
trim:
|
||||
0:
|
||||
value: 6
|
||||
mode: 0
|
||||
4:
|
||||
value: -2
|
||||
mode: 0
|
||||
name: 100pct
|
||||
fadeIn: 0
|
||||
fadeOut: 0
|
||||
gvars:
|
||||
0:
|
||||
val: 100
|
||||
1:
|
||||
val: 100
|
||||
1:
|
||||
swtch: "!L2"
|
||||
name: Disarm
|
||||
fadeIn: 0
|
||||
fadeOut: 0
|
||||
gvars:
|
||||
0:
|
||||
val: 0
|
||||
1:
|
||||
val: 0
|
||||
2:
|
||||
swtch: SA1
|
||||
name: 60pct
|
||||
fadeIn: 0
|
||||
fadeOut: 0
|
||||
gvars:
|
||||
0:
|
||||
val: 60
|
||||
3:
|
||||
swtch: SA2
|
||||
name: 30pct
|
||||
fadeIn: 0
|
||||
fadeOut: 0
|
||||
gvars:
|
||||
0:
|
||||
val: 30
|
||||
mixData:
|
||||
- destCh: 0
|
||||
srcRaw: I1
|
||||
weight: 100
|
||||
swtch: NONE
|
||||
curve:
|
||||
type: 0
|
||||
value: 0
|
||||
delayPrec: 0
|
||||
delayUp: 0
|
||||
delayDown: 0
|
||||
speedPrec: 0
|
||||
speedUp: 0
|
||||
speedDown: 0
|
||||
carryTrim: 0
|
||||
mltpx: ADD
|
||||
mixWarn: 0
|
||||
flightModes: 000000000
|
||||
offset: 0
|
||||
name: ""
|
||||
- destCh: 1
|
||||
srcRaw: I0
|
||||
weight: gv(0)
|
||||
swtch: NONE
|
||||
curve:
|
||||
type: 0
|
||||
value: 0
|
||||
delayPrec: 0
|
||||
delayUp: 0
|
||||
delayDown: 0
|
||||
speedPrec: 0
|
||||
speedUp: 0
|
||||
speedDown: 0
|
||||
carryTrim: 0
|
||||
mltpx: ADD
|
||||
mixWarn: 0
|
||||
flightModes: 000000000
|
||||
offset: 0
|
||||
name: ""
|
||||
- destCh: 7
|
||||
srcRaw: P2
|
||||
weight: 100
|
||||
swtch: NONE
|
||||
curve:
|
||||
type: 0
|
||||
value: 0
|
||||
delayPrec: 0
|
||||
delayUp: 0
|
||||
delayDown: 0
|
||||
speedPrec: 0
|
||||
speedUp: 0
|
||||
speedDown: 0
|
||||
carryTrim: 0
|
||||
mltpx: ADD
|
||||
mixWarn: 0
|
||||
flightModes: 000000000
|
||||
offset: 0
|
||||
name: Gyro
|
||||
expoData:
|
||||
- srcRaw: TH
|
||||
scale: 0
|
||||
mode: 3
|
||||
chn: 0
|
||||
swtch: NONE
|
||||
flightModes: 000000000
|
||||
weight: 100
|
||||
offset: 0
|
||||
curve:
|
||||
type: 1
|
||||
value: 0
|
||||
trimSource: 0
|
||||
name: ""
|
||||
- srcRaw: ST
|
||||
scale: 0
|
||||
mode: 3
|
||||
chn: 1
|
||||
swtch: NONE
|
||||
flightModes: 000000000
|
||||
weight: 100
|
||||
offset: 0
|
||||
curve:
|
||||
type: 1
|
||||
value: 0
|
||||
trimSource: 0
|
||||
name: ""
|
||||
inputNames:
|
||||
0:
|
||||
val: TH
|
||||
1:
|
||||
val: ST
|
||||
logicalSw:
|
||||
0:
|
||||
func: FUNC_EDGE
|
||||
def: SC2,0,-
|
||||
delay: 0
|
||||
duration: 0
|
||||
andsw: NONE
|
||||
lsPersist: 0
|
||||
lsState: 0
|
||||
1:
|
||||
func: FUNC_STICKY
|
||||
def: L1,L1
|
||||
delay: 0
|
||||
duration: 0
|
||||
andsw: NONE
|
||||
lsPersist: 0
|
||||
lsState: 0
|
||||
customFn:
|
||||
0:
|
||||
swtch: "!L2"
|
||||
func: RGB_LED
|
||||
def: rgbLop,1,On
|
||||
1:
|
||||
swtch: SA0
|
||||
func: RGB_LED
|
||||
def: green,1,On
|
||||
2:
|
||||
swtch: SA1
|
||||
func: RGB_LED
|
||||
def: yellow,1,On
|
||||
3:
|
||||
swtch: SA2
|
||||
func: RGB_LED
|
||||
def: orange,1,On
|
||||
thrTraceSrc: TH
|
||||
thrTrimSw: 0
|
||||
potsWarnMode: WARN_OFF
|
||||
potsWarnEnabled: 0
|
||||
jitterFilter: GLOBAL
|
||||
displayChecklist: 0
|
||||
gvars:
|
||||
0:
|
||||
name: THR
|
||||
min: 0
|
||||
max: 0
|
||||
popup: 0
|
||||
prec: 0
|
||||
unit: 0
|
||||
1:
|
||||
name: ST
|
||||
min: 0
|
||||
max: 0
|
||||
popup: 0
|
||||
prec: 0
|
||||
unit: 0
|
||||
telemetryProtocol: 0
|
||||
screens:
|
||||
0:
|
||||
type: BARS
|
||||
u:
|
||||
bars:
|
||||
0:
|
||||
source: tele(2)
|
||||
barMin: 0
|
||||
barMax: 0
|
||||
1:
|
||||
source: tele(3)
|
||||
barMin: 0
|
||||
barMax: 0
|
||||
2:
|
||||
source: tele(4)
|
||||
barMin: 0
|
||||
barMax: 0
|
||||
3:
|
||||
source: tele(5)
|
||||
barMin: 0
|
||||
barMax: 0
|
||||
varioData:
|
||||
source: none
|
||||
centerSilent: 0
|
||||
centerMax: 0
|
||||
centerMin: 0
|
||||
min: 0
|
||||
max: 0
|
||||
rssiSource: none
|
||||
rfAlarms:
|
||||
warning: 45
|
||||
critical: 42
|
||||
disableTelemetryWarning: 0
|
||||
moduleData:
|
||||
0:
|
||||
type: TYPE_MULTIMODULE
|
||||
subType: 74,0
|
||||
channelsStart: 0
|
||||
channelsCount: 16
|
||||
failsafeMode: NOT_SET
|
||||
mod:
|
||||
multi:
|
||||
disableTelemetry: 0
|
||||
disableMapping: 0
|
||||
autoBindMode: 0
|
||||
lowPowerMode: 0
|
||||
optionValue: 0
|
||||
trainerData:
|
||||
mode: OFF
|
||||
channelsStart: 0
|
||||
channelsCount: -8
|
||||
frameLength: 0
|
||||
delay: 0
|
||||
pulsePol: 0
|
||||
telemetrySensors:
|
||||
0:
|
||||
type: TYPE_CUSTOM
|
||||
id1:
|
||||
id: 241
|
||||
subId: 0
|
||||
id2:
|
||||
instance: 0
|
||||
label: A1
|
||||
unit: 1
|
||||
prec: 1
|
||||
autoOffset: 0
|
||||
filter: 1
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 132
|
||||
offset: 0
|
||||
1:
|
||||
type: TYPE_CUSTOM
|
||||
id1:
|
||||
id: 242
|
||||
subId: 0
|
||||
id2:
|
||||
instance: 0
|
||||
label: A2
|
||||
unit: 1
|
||||
prec: 1
|
||||
autoOffset: 0
|
||||
filter: 1
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 132
|
||||
offset: 0
|
||||
2:
|
||||
type: TYPE_CUSTOM
|
||||
id1:
|
||||
id: 240
|
||||
subId: 0
|
||||
id2:
|
||||
instance: 0
|
||||
label: RSSI
|
||||
unit: 0
|
||||
prec: 0
|
||||
autoOffset: 0
|
||||
filter: 1
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
3:
|
||||
type: TYPE_CUSTOM
|
||||
id1:
|
||||
id: 65534
|
||||
subId: 0
|
||||
id2:
|
||||
instance: 0
|
||||
label: TRSS
|
||||
unit: 17
|
||||
prec: 0
|
||||
autoOffset: 0
|
||||
filter: 1
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
4:
|
||||
type: TYPE_CUSTOM
|
||||
id1:
|
||||
id: 65532
|
||||
subId: 0
|
||||
id2:
|
||||
instance: 0
|
||||
label: RQly
|
||||
unit: 0
|
||||
prec: 0
|
||||
autoOffset: 0
|
||||
filter: 1
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
5:
|
||||
type: TYPE_CUSTOM
|
||||
id1:
|
||||
id: 65533
|
||||
subId: 0
|
||||
id2:
|
||||
instance: 0
|
||||
label: TQly
|
||||
unit: 0
|
||||
prec: 0
|
||||
autoOffset: 0
|
||||
filter: 1
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
modelRegistrationID: ANNIKA
|
||||
hatsMode: GLOBAL
|
||||
usbJoystickExtMode: 0
|
||||
usbJoystickIfMode: JOYSTICK
|
||||
usbJoystickCircularCut: 0
|
||||
radioGFDisabled: GLOBAL
|
||||
radioTrainerDisabled: GLOBAL
|
||||
modelHeliDisabled: GLOBAL
|
||||
modelFMDisabled: GLOBAL
|
||||
modelCurvesDisabled: GLOBAL
|
||||
modelGVDisabled: GLOBAL
|
||||
modelLSDisabled: GLOBAL
|
||||
modelSFDisabled: GLOBAL
|
||||
modelCustomScriptsDisabled: GLOBAL
|
||||
modelTelemetryDisabled: GLOBAL
|
||||
550
MODELS/model02.yml
Normal file
|
|
@ -0,0 +1,550 @@
|
|||
semver: 2.11.1
|
||||
header:
|
||||
name: ARX100
|
||||
bitmap: ""
|
||||
labels: ""
|
||||
modelId:
|
||||
0:
|
||||
val: 0
|
||||
timers:
|
||||
0:
|
||||
swtch: L1
|
||||
mode: OFF
|
||||
name: ""
|
||||
minuteBeep: 0
|
||||
countdownBeep: 0
|
||||
start: 0
|
||||
persistent: 0
|
||||
countdownStart: 0
|
||||
value: 297
|
||||
showElapsed: 0
|
||||
extraHaptic: 0
|
||||
noGlobalFunctions: 0
|
||||
thrTrim: 0
|
||||
trimInc: 0
|
||||
displayTrims: 2
|
||||
ignoreSensorIds: 0
|
||||
showInstanceIds: 0
|
||||
disableThrottleWarning: 0
|
||||
enableCustomThrottleWarning: 0
|
||||
customThrottleWarningPosition: 0
|
||||
beepANACenter: 0
|
||||
extendedLimits: 1
|
||||
extendedTrims: 0
|
||||
throttleReversed: 0
|
||||
checklistInteractive: 0
|
||||
flightModeData:
|
||||
0:
|
||||
trim:
|
||||
0:
|
||||
value: -82
|
||||
mode: 0
|
||||
1:
|
||||
value: -22
|
||||
mode: 0
|
||||
4:
|
||||
value: 6
|
||||
mode: 0
|
||||
name: 100pct
|
||||
fadeIn: 0
|
||||
fadeOut: 0
|
||||
gvars:
|
||||
0:
|
||||
val: 100
|
||||
1:
|
||||
swtch: "!L2"
|
||||
name: Disarm
|
||||
fadeIn: 0
|
||||
fadeOut: 0
|
||||
gvars:
|
||||
0:
|
||||
val: 0
|
||||
2:
|
||||
swtch: SA1
|
||||
name: 60pct
|
||||
fadeIn: 0
|
||||
fadeOut: 0
|
||||
gvars:
|
||||
0:
|
||||
val: 60
|
||||
3:
|
||||
swtch: SA2
|
||||
name: 30pct
|
||||
fadeIn: 0
|
||||
fadeOut: 0
|
||||
gvars:
|
||||
0:
|
||||
val: 30
|
||||
mixData:
|
||||
- destCh: 0
|
||||
srcRaw: I0
|
||||
weight: gv(0)
|
||||
swtch: NONE
|
||||
curve:
|
||||
type: 0
|
||||
value: 0
|
||||
delayPrec: 0
|
||||
delayUp: 0
|
||||
delayDown: 0
|
||||
speedPrec: 0
|
||||
speedUp: 0
|
||||
speedDown: 0
|
||||
carryTrim: 0
|
||||
mltpx: ADD
|
||||
mixWarn: 0
|
||||
flightModes: 000000000
|
||||
offset: 0
|
||||
name: ""
|
||||
- destCh: 1
|
||||
srcRaw: I1
|
||||
weight: 100
|
||||
swtch: NONE
|
||||
curve:
|
||||
type: 0
|
||||
value: 0
|
||||
delayPrec: 0
|
||||
delayUp: 0
|
||||
delayDown: 0
|
||||
speedPrec: 0
|
||||
speedUp: 0
|
||||
speedDown: 0
|
||||
carryTrim: 0
|
||||
mltpx: ADD
|
||||
mixWarn: 0
|
||||
flightModes: 000000000
|
||||
offset: 0
|
||||
name: ""
|
||||
limitData:
|
||||
0:
|
||||
min: 0
|
||||
max: 0
|
||||
revert: 0
|
||||
offset: 0
|
||||
ppmCenter: 0
|
||||
symetrical: 0
|
||||
name: ""
|
||||
curve: 0
|
||||
1:
|
||||
min: 0
|
||||
max: 0
|
||||
revert: 0
|
||||
offset: 0
|
||||
ppmCenter: 0
|
||||
symetrical: 0
|
||||
name: ""
|
||||
curve: 0
|
||||
expoData:
|
||||
- srcRaw: TH
|
||||
scale: 0
|
||||
mode: 3
|
||||
chn: 0
|
||||
swtch: NONE
|
||||
flightModes: 000000000
|
||||
weight: 100
|
||||
offset: 0
|
||||
curve:
|
||||
type: 0
|
||||
value: 0
|
||||
trimSource: 0
|
||||
name: ""
|
||||
- srcRaw: ST
|
||||
scale: 0
|
||||
mode: 3
|
||||
chn: 1
|
||||
swtch: NONE
|
||||
flightModes: 000000000
|
||||
weight: 100
|
||||
offset: 0
|
||||
curve:
|
||||
type: 0
|
||||
value: 0
|
||||
trimSource: 0
|
||||
name: ""
|
||||
inputNames:
|
||||
0:
|
||||
val: TH
|
||||
1:
|
||||
val: ST
|
||||
curves:
|
||||
31:
|
||||
type: 1
|
||||
smooth: 0
|
||||
points: -1
|
||||
name: CNT
|
||||
points:
|
||||
155:
|
||||
val: -100
|
||||
156:
|
||||
val: 0
|
||||
157:
|
||||
val: 0
|
||||
158:
|
||||
val: 100
|
||||
159:
|
||||
val: -1
|
||||
160:
|
||||
val: 1
|
||||
logicalSw:
|
||||
0:
|
||||
func: FUNC_EDGE
|
||||
def: SC2,0,-
|
||||
delay: 0
|
||||
duration: 0
|
||||
andsw: NONE
|
||||
lsPersist: 0
|
||||
lsState: 0
|
||||
1:
|
||||
func: FUNC_STICKY
|
||||
def: L1,L1
|
||||
delay: 0
|
||||
duration: 0
|
||||
andsw: NONE
|
||||
lsPersist: 0
|
||||
lsState: 0
|
||||
customFn:
|
||||
0:
|
||||
swtch: "!L2"
|
||||
func: RGB_LED
|
||||
def: rgbLop,1,On
|
||||
1:
|
||||
swtch: SA0
|
||||
func: RGB_LED
|
||||
def: green,1,On
|
||||
2:
|
||||
swtch: SA1
|
||||
func: RGB_LED
|
||||
def: yellow,1,On
|
||||
3:
|
||||
swtch: SA2
|
||||
func: RGB_LED
|
||||
def: orange,1,On
|
||||
thrTraceSrc: TH
|
||||
thrTrimSw: 0
|
||||
potsWarnMode: WARN_OFF
|
||||
potsWarnEnabled: 0
|
||||
jitterFilter: GLOBAL
|
||||
displayChecklist: 0
|
||||
gvars:
|
||||
0:
|
||||
name: THR
|
||||
min: 0
|
||||
max: 0
|
||||
popup: 0
|
||||
prec: 0
|
||||
unit: 0
|
||||
telemetryProtocol: 0
|
||||
varioData:
|
||||
source: none
|
||||
centerSilent: 0
|
||||
centerMax: 0
|
||||
centerMin: 0
|
||||
min: 0
|
||||
max: 0
|
||||
rssiSource: none
|
||||
rfAlarms:
|
||||
warning: 45
|
||||
critical: 42
|
||||
disableTelemetryWarning: 0
|
||||
moduleData:
|
||||
0:
|
||||
type: TYPE_MULTIMODULE
|
||||
subType: 1,0
|
||||
channelsStart: 0
|
||||
channelsCount: 16
|
||||
failsafeMode: NOT_SET
|
||||
mod:
|
||||
multi:
|
||||
disableTelemetry: 0
|
||||
disableMapping: 0
|
||||
autoBindMode: 0
|
||||
lowPowerMode: 0
|
||||
optionValue: 0
|
||||
trainerData:
|
||||
mode: OFF
|
||||
channelsStart: 0
|
||||
channelsCount: -8
|
||||
frameLength: 0
|
||||
delay: 0
|
||||
pulsePol: 0
|
||||
telemetrySensors:
|
||||
0:
|
||||
type: TYPE_CUSTOM
|
||||
id1:
|
||||
id: 20
|
||||
subId: 0
|
||||
id2:
|
||||
instance: 0
|
||||
label: 1RSS
|
||||
unit: 17
|
||||
prec: 0
|
||||
autoOffset: 0
|
||||
filter: 0
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
1:
|
||||
type: TYPE_CUSTOM
|
||||
id1:
|
||||
id: 20
|
||||
subId: 0
|
||||
id2:
|
||||
instance: 1
|
||||
label: 2RSS
|
||||
unit: 17
|
||||
prec: 0
|
||||
autoOffset: 0
|
||||
filter: 0
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
2:
|
||||
type: TYPE_CUSTOM
|
||||
id1:
|
||||
id: 20
|
||||
subId: 0
|
||||
id2:
|
||||
instance: 2
|
||||
label: RQly
|
||||
unit: 13
|
||||
prec: 0
|
||||
autoOffset: 0
|
||||
filter: 0
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
3:
|
||||
type: TYPE_CUSTOM
|
||||
id1:
|
||||
id: 20
|
||||
subId: 0
|
||||
id2:
|
||||
instance: 3
|
||||
label: RSNR
|
||||
unit: 17
|
||||
prec: 0
|
||||
autoOffset: 0
|
||||
filter: 0
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
4:
|
||||
type: TYPE_CUSTOM
|
||||
id1:
|
||||
id: 20
|
||||
subId: 0
|
||||
id2:
|
||||
instance: 4
|
||||
label: ANT
|
||||
unit: 0
|
||||
prec: 0
|
||||
autoOffset: 0
|
||||
filter: 0
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
5:
|
||||
type: TYPE_CUSTOM
|
||||
id1:
|
||||
id: 20
|
||||
subId: 0
|
||||
id2:
|
||||
instance: 5
|
||||
label: RFMD
|
||||
unit: 0
|
||||
prec: 0
|
||||
autoOffset: 0
|
||||
filter: 0
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
6:
|
||||
type: TYPE_CUSTOM
|
||||
id1:
|
||||
id: 20
|
||||
subId: 0
|
||||
id2:
|
||||
instance: 6
|
||||
label: TPWR
|
||||
unit: 16
|
||||
prec: 0
|
||||
autoOffset: 0
|
||||
filter: 0
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
7:
|
||||
type: TYPE_CUSTOM
|
||||
id1:
|
||||
id: 20
|
||||
subId: 0
|
||||
id2:
|
||||
instance: 7
|
||||
label: TRSS
|
||||
unit: 17
|
||||
prec: 0
|
||||
autoOffset: 0
|
||||
filter: 0
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
8:
|
||||
type: TYPE_CUSTOM
|
||||
id1:
|
||||
id: 20
|
||||
subId: 0
|
||||
id2:
|
||||
instance: 8
|
||||
label: TQly
|
||||
unit: 13
|
||||
prec: 0
|
||||
autoOffset: 0
|
||||
filter: 0
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
9:
|
||||
type: TYPE_CUSTOM
|
||||
id1:
|
||||
id: 20
|
||||
subId: 0
|
||||
id2:
|
||||
instance: 9
|
||||
label: TSNR
|
||||
unit: 17
|
||||
prec: 0
|
||||
autoOffset: 0
|
||||
filter: 0
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
10:
|
||||
type: TYPE_CUSTOM
|
||||
id1:
|
||||
id: 8
|
||||
subId: 0
|
||||
id2:
|
||||
instance: 0
|
||||
label: RxBt
|
||||
unit: 1
|
||||
prec: 1
|
||||
autoOffset: 0
|
||||
filter: 0
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
11:
|
||||
type: TYPE_CUSTOM
|
||||
id1:
|
||||
id: 8
|
||||
subId: 0
|
||||
id2:
|
||||
instance: 1
|
||||
label: Curr
|
||||
unit: 2
|
||||
prec: 1
|
||||
autoOffset: 0
|
||||
filter: 0
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
12:
|
||||
type: TYPE_CUSTOM
|
||||
id1:
|
||||
id: 8
|
||||
subId: 0
|
||||
id2:
|
||||
instance: 2
|
||||
label: Capa
|
||||
unit: 14
|
||||
prec: 0
|
||||
autoOffset: 0
|
||||
filter: 0
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
13:
|
||||
type: TYPE_CUSTOM
|
||||
id1:
|
||||
id: 8
|
||||
subId: 0
|
||||
id2:
|
||||
instance: 3
|
||||
label: Bat
|
||||
unit: 13
|
||||
prec: 0
|
||||
autoOffset: 0
|
||||
filter: 0
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
modelRegistrationID: "*\x15*\x15!\x03%\x07"
|
||||
hatsMode: GLOBAL
|
||||
usbJoystickExtMode: 0
|
||||
usbJoystickIfMode: JOYSTICK
|
||||
usbJoystickCircularCut: 0
|
||||
radioGFDisabled: GLOBAL
|
||||
radioTrainerDisabled: GLOBAL
|
||||
modelHeliDisabled: GLOBAL
|
||||
modelFMDisabled: GLOBAL
|
||||
modelCurvesDisabled: GLOBAL
|
||||
modelGVDisabled: GLOBAL
|
||||
modelLSDisabled: GLOBAL
|
||||
modelSFDisabled: GLOBAL
|
||||
modelCustomScriptsDisabled: GLOBAL
|
||||
modelTelemetryDisabled: GLOBAL
|
||||
251
MODELS/model03.yml
Normal file
|
|
@ -0,0 +1,251 @@
|
|||
semver: 2.11.1
|
||||
header:
|
||||
name: MOJAVE
|
||||
bitmap: ""
|
||||
labels: ""
|
||||
modelId:
|
||||
0:
|
||||
val: 0
|
||||
noGlobalFunctions: 0
|
||||
thrTrim: 0
|
||||
trimInc: 0
|
||||
displayTrims: 0
|
||||
ignoreSensorIds: 0
|
||||
showInstanceIds: 0
|
||||
disableThrottleWarning: 0
|
||||
enableCustomThrottleWarning: 0
|
||||
customThrottleWarningPosition: 0
|
||||
beepANACenter: 0
|
||||
extendedLimits: 0
|
||||
extendedTrims: 0
|
||||
throttleReversed: 0
|
||||
checklistInteractive: 0
|
||||
flightModeData:
|
||||
0:
|
||||
name: 100pct
|
||||
fadeIn: 0
|
||||
fadeOut: 0
|
||||
gvars:
|
||||
0:
|
||||
val: 100
|
||||
1:
|
||||
swtch: "!L2"
|
||||
name: Disarm
|
||||
fadeIn: 0
|
||||
fadeOut: 0
|
||||
gvars:
|
||||
0:
|
||||
val: 0
|
||||
2:
|
||||
swtch: SA1
|
||||
name: 60pct
|
||||
fadeIn: 0
|
||||
fadeOut: 0
|
||||
gvars:
|
||||
0:
|
||||
val: 60
|
||||
3:
|
||||
swtch: SA2
|
||||
name: 30pct
|
||||
fadeIn: 0
|
||||
fadeOut: 0
|
||||
gvars:
|
||||
0:
|
||||
val: 30
|
||||
mixData:
|
||||
- destCh: 0
|
||||
srcRaw: I1
|
||||
weight: 100
|
||||
swtch: NONE
|
||||
curve:
|
||||
type: 0
|
||||
value: 0
|
||||
delayPrec: 0
|
||||
delayUp: 0
|
||||
delayDown: 0
|
||||
speedPrec: 0
|
||||
speedUp: 0
|
||||
speedDown: 0
|
||||
carryTrim: 0
|
||||
mltpx: ADD
|
||||
mixWarn: 0
|
||||
flightModes: 000000000
|
||||
offset: 0
|
||||
name: ""
|
||||
- destCh: 1
|
||||
srcRaw: I0
|
||||
weight: gv(0)
|
||||
swtch: NONE
|
||||
curve:
|
||||
type: 0
|
||||
value: 0
|
||||
delayPrec: 0
|
||||
delayUp: 0
|
||||
delayDown: 0
|
||||
speedPrec: 0
|
||||
speedUp: 0
|
||||
speedDown: 0
|
||||
carryTrim: 0
|
||||
mltpx: ADD
|
||||
mixWarn: 0
|
||||
flightModes: 000000000
|
||||
offset: 0
|
||||
name: ""
|
||||
- destCh: 3
|
||||
srcRaw: P2
|
||||
weight: 25
|
||||
swtch: NONE
|
||||
curve:
|
||||
type: 0
|
||||
value: 0
|
||||
delayPrec: 0
|
||||
delayUp: 0
|
||||
delayDown: 0
|
||||
speedPrec: 0
|
||||
speedUp: 0
|
||||
speedDown: 0
|
||||
carryTrim: 0
|
||||
mltpx: ADD
|
||||
mixWarn: 0
|
||||
flightModes: 000000000
|
||||
offset: -10
|
||||
name: DSC
|
||||
limitData:
|
||||
3:
|
||||
min: 0
|
||||
max: 0
|
||||
revert: 0
|
||||
offset: 0
|
||||
ppmCenter: 0
|
||||
symetrical: 0
|
||||
name: ""
|
||||
curve: 0
|
||||
expoData:
|
||||
- srcRaw: TH
|
||||
scale: 0
|
||||
mode: 3
|
||||
chn: 0
|
||||
swtch: NONE
|
||||
flightModes: 000000000
|
||||
weight: 100
|
||||
offset: 0
|
||||
curve:
|
||||
type: 1
|
||||
value: 0
|
||||
trimSource: 0
|
||||
name: ""
|
||||
- srcRaw: ST
|
||||
scale: 0
|
||||
mode: 3
|
||||
chn: 1
|
||||
swtch: NONE
|
||||
flightModes: 000000000
|
||||
weight: 100
|
||||
offset: 0
|
||||
curve:
|
||||
type: 1
|
||||
value: 0
|
||||
trimSource: 0
|
||||
name: ""
|
||||
inputNames:
|
||||
0:
|
||||
val: TH
|
||||
1:
|
||||
val: ST
|
||||
logicalSw:
|
||||
0:
|
||||
func: FUNC_EDGE
|
||||
def: SC2,0,-
|
||||
delay: 0
|
||||
duration: 0
|
||||
andsw: NONE
|
||||
lsPersist: 0
|
||||
lsState: 0
|
||||
1:
|
||||
func: FUNC_STICKY
|
||||
def: L1,L1
|
||||
delay: 0
|
||||
duration: 0
|
||||
andsw: NONE
|
||||
lsPersist: 0
|
||||
lsState: 0
|
||||
customFn:
|
||||
0:
|
||||
swtch: L2
|
||||
func: RGB_LED
|
||||
def: rgbLop,1,On
|
||||
1:
|
||||
swtch: SA0
|
||||
func: RGB_LED
|
||||
def: green,1,On
|
||||
2:
|
||||
swtch: SA1
|
||||
func: RGB_LED
|
||||
def: yellow,1,On
|
||||
3:
|
||||
swtch: SA2
|
||||
func: RGB_LED
|
||||
def: orange,1,On
|
||||
thrTraceSrc: TH
|
||||
thrTrimSw: 0
|
||||
potsWarnMode: WARN_OFF
|
||||
potsWarnEnabled: 0
|
||||
jitterFilter: GLOBAL
|
||||
displayChecklist: 0
|
||||
gvars:
|
||||
0:
|
||||
name: TH
|
||||
min: 0
|
||||
max: 0
|
||||
popup: 0
|
||||
prec: 0
|
||||
unit: 0
|
||||
telemetryProtocol: 0
|
||||
varioData:
|
||||
source: none
|
||||
centerSilent: 0
|
||||
centerMax: 0
|
||||
centerMin: 0
|
||||
min: 0
|
||||
max: 0
|
||||
rssiSource: none
|
||||
rfAlarms:
|
||||
warning: 45
|
||||
critical: 42
|
||||
disableTelemetryWarning: 0
|
||||
moduleData:
|
||||
0:
|
||||
type: TYPE_MULTIMODULE
|
||||
subType: 11,5
|
||||
channelsStart: 0
|
||||
channelsCount: 16
|
||||
failsafeMode: NOT_SET
|
||||
mod:
|
||||
multi:
|
||||
disableTelemetry: 0
|
||||
disableMapping: 0
|
||||
autoBindMode: 0
|
||||
lowPowerMode: 0
|
||||
optionValue: 0
|
||||
trainerData:
|
||||
mode: OFF
|
||||
channelsStart: 0
|
||||
channelsCount: -8
|
||||
frameLength: 0
|
||||
delay: 0
|
||||
pulsePol: 0
|
||||
modelRegistrationID: MOJAVE
|
||||
hatsMode: GLOBAL
|
||||
usbJoystickExtMode: 0
|
||||
usbJoystickIfMode: JOYSTICK
|
||||
usbJoystickCircularCut: 0
|
||||
radioGFDisabled: GLOBAL
|
||||
radioTrainerDisabled: GLOBAL
|
||||
modelHeliDisabled: GLOBAL
|
||||
modelFMDisabled: GLOBAL
|
||||
modelCurvesDisabled: GLOBAL
|
||||
modelGVDisabled: GLOBAL
|
||||
modelLSDisabled: GLOBAL
|
||||
modelSFDisabled: GLOBAL
|
||||
modelCustomScriptsDisabled: GLOBAL
|
||||
modelTelemetryDisabled: GLOBAL
|
||||
232
MODELS/model04.yml
Normal file
|
|
@ -0,0 +1,232 @@
|
|||
semver: 2.11.1
|
||||
header:
|
||||
name: GRANITE
|
||||
bitmap: ""
|
||||
labels: ""
|
||||
modelId:
|
||||
0:
|
||||
val: 0
|
||||
noGlobalFunctions: 0
|
||||
thrTrim: 0
|
||||
trimInc: 0
|
||||
displayTrims: 0
|
||||
ignoreSensorIds: 0
|
||||
showInstanceIds: 0
|
||||
disableThrottleWarning: 0
|
||||
enableCustomThrottleWarning: 0
|
||||
customThrottleWarningPosition: 0
|
||||
beepANACenter: 0
|
||||
extendedLimits: 0
|
||||
extendedTrims: 0
|
||||
throttleReversed: 0
|
||||
checklistInteractive: 0
|
||||
flightModeData:
|
||||
0:
|
||||
name: 100pct
|
||||
fadeIn: 0
|
||||
fadeOut: 0
|
||||
gvars:
|
||||
0:
|
||||
val: 100
|
||||
1:
|
||||
swtch: "!L2"
|
||||
name: Disarm
|
||||
fadeIn: 0
|
||||
fadeOut: 0
|
||||
gvars:
|
||||
0:
|
||||
val: 0
|
||||
2:
|
||||
swtch: SA1
|
||||
name: 60pct
|
||||
fadeIn: 0
|
||||
fadeOut: 0
|
||||
gvars:
|
||||
0:
|
||||
val: 60
|
||||
3:
|
||||
swtch: SA2
|
||||
name: 30pct
|
||||
fadeIn: 0
|
||||
fadeOut: 0
|
||||
gvars:
|
||||
0:
|
||||
val: 30
|
||||
mixData:
|
||||
- destCh: 0
|
||||
srcRaw: I0
|
||||
weight: gv(0)
|
||||
swtch: NONE
|
||||
curve:
|
||||
type: 0
|
||||
value: 0
|
||||
delayPrec: 0
|
||||
delayUp: 0
|
||||
delayDown: 0
|
||||
speedPrec: 0
|
||||
speedUp: 0
|
||||
speedDown: 0
|
||||
carryTrim: 0
|
||||
mltpx: ADD
|
||||
mixWarn: 0
|
||||
flightModes: 000000000
|
||||
offset: 0
|
||||
name: ""
|
||||
- destCh: 1
|
||||
srcRaw: I1
|
||||
weight: 100
|
||||
swtch: NONE
|
||||
curve:
|
||||
type: 0
|
||||
value: 0
|
||||
delayPrec: 0
|
||||
delayUp: 0
|
||||
delayDown: 0
|
||||
speedPrec: 0
|
||||
speedUp: 0
|
||||
speedDown: 0
|
||||
carryTrim: 0
|
||||
mltpx: ADD
|
||||
mixWarn: 0
|
||||
flightModes: 000000000
|
||||
offset: 0
|
||||
name: ""
|
||||
limitData:
|
||||
1:
|
||||
min: 0
|
||||
max: 0
|
||||
revert: 1
|
||||
offset: 0
|
||||
ppmCenter: 0
|
||||
symetrical: 0
|
||||
name: ""
|
||||
curve: 0
|
||||
expoData:
|
||||
- srcRaw: TH
|
||||
scale: 0
|
||||
mode: 3
|
||||
chn: 0
|
||||
swtch: NONE
|
||||
flightModes: 000000000
|
||||
weight: 100
|
||||
offset: 0
|
||||
curve:
|
||||
type: 1
|
||||
value: 0
|
||||
trimSource: 0
|
||||
name: ""
|
||||
- srcRaw: ST
|
||||
scale: 0
|
||||
mode: 3
|
||||
chn: 1
|
||||
swtch: NONE
|
||||
flightModes: 000000000
|
||||
weight: 100
|
||||
offset: 0
|
||||
curve:
|
||||
type: 1
|
||||
value: 0
|
||||
trimSource: 0
|
||||
name: ""
|
||||
inputNames:
|
||||
0:
|
||||
val: TH
|
||||
1:
|
||||
val: ST
|
||||
logicalSw:
|
||||
0:
|
||||
func: FUNC_EDGE
|
||||
def: SC2,0,-
|
||||
delay: 0
|
||||
duration: 0
|
||||
andsw: NONE
|
||||
lsPersist: 0
|
||||
lsState: 0
|
||||
1:
|
||||
func: FUNC_STICKY
|
||||
def: L1,L1
|
||||
delay: 0
|
||||
duration: 0
|
||||
andsw: NONE
|
||||
lsPersist: 0
|
||||
lsState: 0
|
||||
customFn:
|
||||
0:
|
||||
swtch: L2
|
||||
func: RGB_LED
|
||||
def: rgbLop,1,On
|
||||
1:
|
||||
swtch: SA0
|
||||
func: RGB_LED
|
||||
def: green,1,On
|
||||
2:
|
||||
swtch: SA1
|
||||
func: RGB_LED
|
||||
def: yellow,1,On
|
||||
3:
|
||||
swtch: SA2
|
||||
func: RGB_LED
|
||||
def: orange,1,On
|
||||
thrTraceSrc: TH
|
||||
thrTrimSw: 0
|
||||
potsWarnMode: WARN_OFF
|
||||
potsWarnEnabled: 0
|
||||
jitterFilter: GLOBAL
|
||||
displayChecklist: 0
|
||||
gvars:
|
||||
0:
|
||||
name: TH
|
||||
min: 0
|
||||
max: 0
|
||||
popup: 0
|
||||
prec: 0
|
||||
unit: 0
|
||||
telemetryProtocol: 0
|
||||
varioData:
|
||||
source: none
|
||||
centerSilent: 0
|
||||
centerMax: 0
|
||||
centerMin: 0
|
||||
min: 0
|
||||
max: 0
|
||||
rssiSource: none
|
||||
rfAlarms:
|
||||
warning: 45
|
||||
critical: 42
|
||||
disableTelemetryWarning: 0
|
||||
moduleData:
|
||||
0:
|
||||
type: TYPE_MULTIMODULE
|
||||
subType: 1,0
|
||||
channelsStart: 0
|
||||
channelsCount: 16
|
||||
failsafeMode: NOT_SET
|
||||
mod:
|
||||
multi:
|
||||
disableTelemetry: 0
|
||||
disableMapping: 0
|
||||
autoBindMode: 0
|
||||
lowPowerMode: 0
|
||||
optionValue: 0
|
||||
trainerData:
|
||||
mode: OFF
|
||||
channelsStart: 0
|
||||
channelsCount: -8
|
||||
frameLength: 0
|
||||
delay: 0
|
||||
pulsePol: 0
|
||||
modelRegistrationID: ANNIKA
|
||||
hatsMode: GLOBAL
|
||||
usbJoystickExtMode: 0
|
||||
usbJoystickIfMode: JOYSTICK
|
||||
usbJoystickCircularCut: 0
|
||||
radioGFDisabled: GLOBAL
|
||||
radioTrainerDisabled: GLOBAL
|
||||
modelHeliDisabled: GLOBAL
|
||||
modelFMDisabled: GLOBAL
|
||||
modelCurvesDisabled: GLOBAL
|
||||
modelGVDisabled: GLOBAL
|
||||
modelLSDisabled: GLOBAL
|
||||
modelSFDisabled: GLOBAL
|
||||
modelCustomScriptsDisabled: GLOBAL
|
||||
modelTelemetryDisabled: GLOBAL
|
||||
383
MODELS/model05.yml
Normal file
|
|
@ -0,0 +1,383 @@
|
|||
semver: 2.11.1
|
||||
header:
|
||||
name: RAIDER
|
||||
bitmap: ""
|
||||
labels: ""
|
||||
modelId:
|
||||
0:
|
||||
val: 0
|
||||
noGlobalFunctions: 0
|
||||
thrTrim: 0
|
||||
trimInc: 0
|
||||
displayTrims: 2
|
||||
ignoreSensorIds: 0
|
||||
showInstanceIds: 0
|
||||
disableThrottleWarning: 0
|
||||
enableCustomThrottleWarning: 0
|
||||
customThrottleWarningPosition: 0
|
||||
beepANACenter: 0
|
||||
extendedLimits: 0
|
||||
extendedTrims: 0
|
||||
throttleReversed: 0
|
||||
checklistInteractive: 0
|
||||
flightModeData:
|
||||
0:
|
||||
trim:
|
||||
0:
|
||||
value: -64
|
||||
mode: 0
|
||||
name: 100pct
|
||||
fadeIn: 0
|
||||
fadeOut: 0
|
||||
gvars:
|
||||
0:
|
||||
val: 100
|
||||
1:
|
||||
swtch: "!L2"
|
||||
name: Disarm
|
||||
fadeIn: 0
|
||||
fadeOut: 0
|
||||
gvars:
|
||||
0:
|
||||
val: 0
|
||||
1:
|
||||
val: 0
|
||||
2:
|
||||
swtch: SA1
|
||||
name: 60pct
|
||||
fadeIn: 0
|
||||
fadeOut: 0
|
||||
gvars:
|
||||
0:
|
||||
val: 60
|
||||
3:
|
||||
swtch: SA2
|
||||
name: 30pct
|
||||
fadeIn: 0
|
||||
fadeOut: 0
|
||||
gvars:
|
||||
0:
|
||||
val: 30
|
||||
mixData:
|
||||
- destCh: 0
|
||||
srcRaw: I1
|
||||
weight: 100
|
||||
swtch: NONE
|
||||
curve:
|
||||
type: 0
|
||||
value: 0
|
||||
delayPrec: 0
|
||||
delayUp: 0
|
||||
delayDown: 0
|
||||
speedPrec: 0
|
||||
speedUp: 0
|
||||
speedDown: 0
|
||||
carryTrim: 0
|
||||
mltpx: ADD
|
||||
mixWarn: 0
|
||||
flightModes: 000000000
|
||||
offset: 0
|
||||
name: ""
|
||||
- destCh: 1
|
||||
srcRaw: I0
|
||||
weight: gv(0)
|
||||
swtch: NONE
|
||||
curve:
|
||||
type: 0
|
||||
value: 0
|
||||
delayPrec: 0
|
||||
delayUp: 0
|
||||
delayDown: 0
|
||||
speedPrec: 0
|
||||
speedUp: 0
|
||||
speedDown: 0
|
||||
carryTrim: 0
|
||||
mltpx: ADD
|
||||
mixWarn: 0
|
||||
flightModes: 000000000
|
||||
offset: 0
|
||||
name: ""
|
||||
- destCh: 7
|
||||
srcRaw: P2
|
||||
weight: 100
|
||||
swtch: NONE
|
||||
curve:
|
||||
type: 0
|
||||
value: 0
|
||||
delayPrec: 0
|
||||
delayUp: 0
|
||||
delayDown: 0
|
||||
speedPrec: 0
|
||||
speedUp: 0
|
||||
speedDown: 0
|
||||
carryTrim: 0
|
||||
mltpx: ADD
|
||||
mixWarn: 0
|
||||
flightModes: 000000000
|
||||
offset: 0
|
||||
name: Gyro
|
||||
expoData:
|
||||
- srcRaw: TH
|
||||
scale: 0
|
||||
mode: 3
|
||||
chn: 0
|
||||
swtch: NONE
|
||||
flightModes: 000000000
|
||||
weight: 100
|
||||
offset: 0
|
||||
curve:
|
||||
type: 1
|
||||
value: 0
|
||||
trimSource: 0
|
||||
name: ""
|
||||
- srcRaw: ST
|
||||
scale: 0
|
||||
mode: 3
|
||||
chn: 1
|
||||
swtch: NONE
|
||||
flightModes: 000000000
|
||||
weight: 100
|
||||
offset: 0
|
||||
curve:
|
||||
type: 1
|
||||
value: 0
|
||||
trimSource: 0
|
||||
name: ""
|
||||
inputNames:
|
||||
0:
|
||||
val: TH
|
||||
1:
|
||||
val: ST
|
||||
logicalSw:
|
||||
0:
|
||||
func: FUNC_EDGE
|
||||
def: SC2,0,-
|
||||
delay: 0
|
||||
duration: 0
|
||||
andsw: NONE
|
||||
lsPersist: 0
|
||||
lsState: 0
|
||||
1:
|
||||
func: FUNC_STICKY
|
||||
def: L1,L1
|
||||
delay: 0
|
||||
duration: 0
|
||||
andsw: NONE
|
||||
lsPersist: 0
|
||||
lsState: 1
|
||||
customFn:
|
||||
0:
|
||||
swtch: "!L2"
|
||||
func: RGB_LED
|
||||
def: rgbLop,1,On
|
||||
1:
|
||||
swtch: SA0
|
||||
func: RGB_LED
|
||||
def: green,1,On
|
||||
2:
|
||||
swtch: SA1
|
||||
func: RGB_LED
|
||||
def: yellow,1,On
|
||||
3:
|
||||
swtch: SA2
|
||||
func: RGB_LED
|
||||
def: orange,1,On
|
||||
thrTraceSrc: TH
|
||||
thrTrimSw: 0
|
||||
potsWarnMode: WARN_OFF
|
||||
potsWarnEnabled: 0
|
||||
jitterFilter: GLOBAL
|
||||
displayChecklist: 0
|
||||
gvars:
|
||||
0:
|
||||
name: THR
|
||||
min: 0
|
||||
max: 0
|
||||
popup: 0
|
||||
prec: 0
|
||||
unit: 0
|
||||
telemetryProtocol: 0
|
||||
screens:
|
||||
0:
|
||||
type: BARS
|
||||
u:
|
||||
bars:
|
||||
0:
|
||||
source: tele(2)
|
||||
barMin: 0
|
||||
barMax: 0
|
||||
1:
|
||||
source: tele(3)
|
||||
barMin: 0
|
||||
barMax: 0
|
||||
2:
|
||||
source: tele(4)
|
||||
barMin: 0
|
||||
barMax: 0
|
||||
3:
|
||||
source: tele(5)
|
||||
barMin: 0
|
||||
barMax: 0
|
||||
varioData:
|
||||
source: none
|
||||
centerSilent: 0
|
||||
centerMax: 0
|
||||
centerMin: 0
|
||||
min: 0
|
||||
max: 0
|
||||
rssiSource: none
|
||||
rfAlarms:
|
||||
warning: 45
|
||||
critical: 42
|
||||
disableTelemetryWarning: 0
|
||||
moduleData:
|
||||
0:
|
||||
type: TYPE_MULTIMODULE
|
||||
subType: 74,0
|
||||
channelsStart: 0
|
||||
channelsCount: 16
|
||||
failsafeMode: NOT_SET
|
||||
mod:
|
||||
multi:
|
||||
disableTelemetry: 0
|
||||
disableMapping: 0
|
||||
autoBindMode: 0
|
||||
lowPowerMode: 0
|
||||
optionValue: 0
|
||||
trainerData:
|
||||
mode: OFF
|
||||
channelsStart: 0
|
||||
channelsCount: -8
|
||||
frameLength: 0
|
||||
delay: 0
|
||||
pulsePol: 0
|
||||
telemetrySensors:
|
||||
0:
|
||||
type: TYPE_CUSTOM
|
||||
id1:
|
||||
id: 241
|
||||
subId: 0
|
||||
id2:
|
||||
instance: 0
|
||||
label: A1
|
||||
unit: 1
|
||||
prec: 1
|
||||
autoOffset: 0
|
||||
filter: 1
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 132
|
||||
offset: 0
|
||||
1:
|
||||
type: TYPE_CUSTOM
|
||||
id1:
|
||||
id: 242
|
||||
subId: 0
|
||||
id2:
|
||||
instance: 0
|
||||
label: A2
|
||||
unit: 1
|
||||
prec: 1
|
||||
autoOffset: 0
|
||||
filter: 1
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 132
|
||||
offset: 0
|
||||
2:
|
||||
type: TYPE_CUSTOM
|
||||
id1:
|
||||
id: 240
|
||||
subId: 0
|
||||
id2:
|
||||
instance: 0
|
||||
label: RSSI
|
||||
unit: 0
|
||||
prec: 0
|
||||
autoOffset: 0
|
||||
filter: 1
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
3:
|
||||
type: TYPE_CUSTOM
|
||||
id1:
|
||||
id: 65534
|
||||
subId: 0
|
||||
id2:
|
||||
instance: 0
|
||||
label: TRSS
|
||||
unit: 17
|
||||
prec: 0
|
||||
autoOffset: 0
|
||||
filter: 1
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
4:
|
||||
type: TYPE_CUSTOM
|
||||
id1:
|
||||
id: 65532
|
||||
subId: 0
|
||||
id2:
|
||||
instance: 0
|
||||
label: RQly
|
||||
unit: 0
|
||||
prec: 0
|
||||
autoOffset: 0
|
||||
filter: 1
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
5:
|
||||
type: TYPE_CUSTOM
|
||||
id1:
|
||||
id: 65533
|
||||
subId: 0
|
||||
id2:
|
||||
instance: 0
|
||||
label: TQly
|
||||
unit: 0
|
||||
prec: 0
|
||||
autoOffset: 0
|
||||
filter: 1
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
modelRegistrationID: ANNIKA
|
||||
hatsMode: GLOBAL
|
||||
usbJoystickExtMode: 0
|
||||
usbJoystickIfMode: JOYSTICK
|
||||
usbJoystickCircularCut: 0
|
||||
radioGFDisabled: GLOBAL
|
||||
radioTrainerDisabled: GLOBAL
|
||||
modelHeliDisabled: GLOBAL
|
||||
modelFMDisabled: GLOBAL
|
||||
modelCurvesDisabled: GLOBAL
|
||||
modelGVDisabled: GLOBAL
|
||||
modelLSDisabled: GLOBAL
|
||||
modelSFDisabled: GLOBAL
|
||||
modelCustomScriptsDisabled: GLOBAL
|
||||
modelTelemetryDisabled: GLOBAL
|
||||
383
MODELS/model06.yml
Executable file
|
|
@ -0,0 +1,383 @@
|
|||
semver: 2.11.1
|
||||
header:
|
||||
name: "RAIDER"
|
||||
telemetryProtocol: 0
|
||||
thrTrim: 0
|
||||
noGlobalFunctions: 0
|
||||
displayTrims: 2
|
||||
ignoreSensorIds: 0
|
||||
trimInc: 0
|
||||
disableThrottleWarning: 0
|
||||
displayChecklist: 0
|
||||
extendedLimits: 0
|
||||
extendedTrims: 0
|
||||
throttleReversed: 0
|
||||
enableCustomThrottleWarning: 0
|
||||
disableTelemetryWarning: 0
|
||||
showInstanceIds: 0
|
||||
checklistInteractive: 0
|
||||
customThrottleWarningPosition: 0
|
||||
beepANACenter: 0
|
||||
mixData:
|
||||
-
|
||||
destCh: 0
|
||||
srcRaw: "I1"
|
||||
carryTrim: 0
|
||||
mixWarn: 0
|
||||
mltpx: ADD
|
||||
delayPrec: 0
|
||||
speedPrec: 0
|
||||
flightModes: 000000000
|
||||
weight: 100
|
||||
offset: 0
|
||||
swtch: "NONE"
|
||||
delayUp: 0
|
||||
delayDown: 0
|
||||
speedUp: 0
|
||||
speedDown: 0
|
||||
name: ""
|
||||
-
|
||||
destCh: 1
|
||||
srcRaw: "I0"
|
||||
carryTrim: 0
|
||||
mixWarn: 0
|
||||
mltpx: ADD
|
||||
delayPrec: 0
|
||||
speedPrec: 0
|
||||
flightModes: 000000000
|
||||
weight: 100
|
||||
offset: 0
|
||||
swtch: "NONE"
|
||||
delayUp: 0
|
||||
delayDown: 0
|
||||
speedUp: 0
|
||||
speedDown: 0
|
||||
name: ""
|
||||
-
|
||||
destCh: 7
|
||||
srcRaw: "P2"
|
||||
carryTrim: 0
|
||||
mixWarn: 0
|
||||
mltpx: ADD
|
||||
delayPrec: 0
|
||||
speedPrec: 0
|
||||
flightModes: 000000000
|
||||
weight: 100
|
||||
offset: 0
|
||||
swtch: "NONE"
|
||||
delayUp: 0
|
||||
delayDown: 0
|
||||
speedUp: 0
|
||||
speedDown: 0
|
||||
name: "Gyro"
|
||||
expoData:
|
||||
-
|
||||
mode: 3
|
||||
scale: 0
|
||||
trimSource: 0
|
||||
srcRaw: "TH"
|
||||
weight: "gv(0)"
|
||||
offset: 0
|
||||
swtch: "NONE"
|
||||
curve:
|
||||
type: 1
|
||||
value: 0
|
||||
chn: 0
|
||||
flightModes: 000000000
|
||||
name: ""
|
||||
-
|
||||
mode: 3
|
||||
scale: 0
|
||||
trimSource: 0
|
||||
srcRaw: "ST"
|
||||
weight: "gv(1)"
|
||||
offset: 0
|
||||
swtch: "NONE"
|
||||
curve:
|
||||
type: 1
|
||||
value: 0
|
||||
chn: 1
|
||||
flightModes: 000000000
|
||||
name: ""
|
||||
logicalSw:
|
||||
0:
|
||||
func: FUNC_EDGE
|
||||
def: "SC2,0,-"
|
||||
andsw: "NONE"
|
||||
lsPersist: 0
|
||||
lsState: 0
|
||||
delay: 0
|
||||
duration: 0
|
||||
1:
|
||||
func: FUNC_STICKY
|
||||
def: "L1,L1"
|
||||
andsw: "NONE"
|
||||
lsPersist: 0
|
||||
lsState: 1
|
||||
delay: 0
|
||||
duration: 0
|
||||
flightModeData:
|
||||
0:
|
||||
trim:
|
||||
0:
|
||||
value: -64
|
||||
mode: 0
|
||||
name: "No Lim"
|
||||
swtch: "NONE"
|
||||
fadeIn: 0
|
||||
fadeOut: 0
|
||||
gvars:
|
||||
0:
|
||||
val: 100
|
||||
1:
|
||||
val: 100
|
||||
2:
|
||||
val: 0
|
||||
3:
|
||||
val: 0
|
||||
4:
|
||||
val: 0
|
||||
5:
|
||||
val: 0
|
||||
6:
|
||||
val: 0
|
||||
7:
|
||||
val: 0
|
||||
8:
|
||||
val: 0
|
||||
1:
|
||||
name: "Disarm"
|
||||
swtch: "!L2"
|
||||
fadeIn: 0
|
||||
fadeOut: 0
|
||||
gvars:
|
||||
0:
|
||||
val: 0
|
||||
1:
|
||||
val: 0
|
||||
2:
|
||||
name: "60 Lim"
|
||||
swtch: "SA1"
|
||||
fadeIn: 0
|
||||
fadeOut: 0
|
||||
gvars:
|
||||
0:
|
||||
val: 60
|
||||
3:
|
||||
name: "30 Lim"
|
||||
swtch: "SA2"
|
||||
fadeIn: 0
|
||||
fadeOut: 0
|
||||
gvars:
|
||||
0:
|
||||
val: 30
|
||||
thrTraceSrc: TH
|
||||
switchWarning:
|
||||
SA:
|
||||
pos: up
|
||||
FL1:
|
||||
pos: up
|
||||
FL2:
|
||||
pos: up
|
||||
gvars:
|
||||
0:
|
||||
name: "THR"
|
||||
min: 0
|
||||
max: 0
|
||||
popup: 0
|
||||
prec: 0
|
||||
unit: 0
|
||||
1:
|
||||
name: "ST"
|
||||
min: 0
|
||||
max: 0
|
||||
popup: 0
|
||||
prec: 0
|
||||
unit: 0
|
||||
rssiSource: none
|
||||
rfAlarms:
|
||||
warning: 45
|
||||
critical: 42
|
||||
thrTrimSw: 0
|
||||
potsWarnMode: WARN_OFF
|
||||
jitterFilter: GLOBAL
|
||||
moduleData:
|
||||
0:
|
||||
type: TYPE_MULTIMODULE
|
||||
subType: 74,0
|
||||
channelsStart: 0
|
||||
channelsCount: 16
|
||||
failsafeMode: NOT_SET
|
||||
mod:
|
||||
multi:
|
||||
disableTelemetry: 0
|
||||
disableMapping: 0
|
||||
autoBindMode: 0
|
||||
lowPowerMode: 0
|
||||
receiverTelemetryOff: 0
|
||||
receiverHigherChannels: 0
|
||||
optionValue: 0
|
||||
trainerData:
|
||||
mode: OFF
|
||||
channelsStart: 0
|
||||
channelsCount: -8
|
||||
frameLength: 0
|
||||
delay: 0
|
||||
pulsePol: 0
|
||||
inputNames:
|
||||
0:
|
||||
val: "TH"
|
||||
1:
|
||||
val: "ST"
|
||||
potsWarnEnabled: 0
|
||||
telemetrySensors:
|
||||
0:
|
||||
id1:
|
||||
id: 241
|
||||
id2:
|
||||
instance: 0
|
||||
label: "A1"
|
||||
subId: 0
|
||||
type: TYPE_CUSTOM
|
||||
unit: 1
|
||||
prec: 1
|
||||
autoOffset: 0
|
||||
filter: 1
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 132
|
||||
offset: 0
|
||||
1:
|
||||
id1:
|
||||
id: 242
|
||||
id2:
|
||||
instance: 0
|
||||
label: "A2"
|
||||
subId: 0
|
||||
type: TYPE_CUSTOM
|
||||
unit: 1
|
||||
prec: 1
|
||||
autoOffset: 0
|
||||
filter: 1
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 132
|
||||
offset: 0
|
||||
2:
|
||||
id1:
|
||||
id: 240
|
||||
id2:
|
||||
instance: 0
|
||||
label: "RSSI"
|
||||
subId: 0
|
||||
type: TYPE_CUSTOM
|
||||
unit: 0
|
||||
prec: 0
|
||||
autoOffset: 0
|
||||
filter: 1
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
3:
|
||||
id1:
|
||||
id: 65534
|
||||
id2:
|
||||
instance: 0
|
||||
label: "TRSS"
|
||||
subId: 0
|
||||
type: TYPE_CUSTOM
|
||||
unit: 17
|
||||
prec: 0
|
||||
autoOffset: 0
|
||||
filter: 1
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
4:
|
||||
id1:
|
||||
id: 65532
|
||||
id2:
|
||||
instance: 0
|
||||
label: "RQly"
|
||||
subId: 0
|
||||
type: TYPE_CUSTOM
|
||||
unit: 0
|
||||
prec: 0
|
||||
autoOffset: 0
|
||||
filter: 1
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
5:
|
||||
id1:
|
||||
id: 65533
|
||||
id2:
|
||||
instance: 0
|
||||
label: "TQly"
|
||||
subId: 0
|
||||
type: TYPE_CUSTOM
|
||||
unit: 0
|
||||
prec: 0
|
||||
autoOffset: 0
|
||||
filter: 1
|
||||
logs: 1
|
||||
persistent: 0
|
||||
onlyPositive: 0
|
||||
cfg:
|
||||
custom:
|
||||
ratio: 0
|
||||
offset: 0
|
||||
screens:
|
||||
0:
|
||||
type: BARS
|
||||
u:
|
||||
bars:
|
||||
0:
|
||||
source: tele(2)
|
||||
barMin: 0
|
||||
barMax: 0
|
||||
1:
|
||||
source: tele(3)
|
||||
barMin: 0
|
||||
barMax: 0
|
||||
2:
|
||||
source: tele(4)
|
||||
barMin: 0
|
||||
barMax: 0
|
||||
3:
|
||||
source: tele(5)
|
||||
barMin: 0
|
||||
barMax: 0
|
||||
view: 0
|
||||
modelRegistrationID: "ANNIKA"
|
||||
usbJoystickExtMode: 0
|
||||
usbJoystickIfMode: JOYSTICK
|
||||
usbJoystickCircularCut: 0
|
||||
radioGFDisabled: GLOBAL
|
||||
radioTrainerDisabled: GLOBAL
|
||||
modelHeliDisabled: GLOBAL
|
||||
modelFMDisabled: GLOBAL
|
||||
modelCurvesDisabled: GLOBAL
|
||||
modelGVDisabled: GLOBAL
|
||||
modelLSDisabled: GLOBAL
|
||||
modelSFDisabled: GLOBAL
|
||||
modelCustomScriptsDisabled: GLOBAL
|
||||
modelTelemetryDisabled: GLOBAL
|
||||
1
RADIO/README.txt
Executable file
|
|
@ -0,0 +1 @@
|
|||
Radio specific configuration files are stored in this directory.
|
||||
183
RADIO/radio.yml
Executable file
|
|
@ -0,0 +1,183 @@
|
|||
checksum: 12551
|
||||
semver: 2.11.1
|
||||
board: mt12
|
||||
calib:
|
||||
ST:
|
||||
mid: 1052
|
||||
spanNeg: 703
|
||||
spanPos: 743
|
||||
TH:
|
||||
mid: 764
|
||||
spanNeg: 560
|
||||
spanPos: 1012
|
||||
P1:
|
||||
mid: 1023
|
||||
spanNeg: 1005
|
||||
spanPos: 1007
|
||||
P2:
|
||||
mid: 1026
|
||||
spanNeg: 1008
|
||||
spanPos: 1004
|
||||
P3:
|
||||
mid: 935
|
||||
spanNeg: 664
|
||||
spanPos: 543
|
||||
P4:
|
||||
mid: 1099
|
||||
spanNeg: 631
|
||||
spanPos: 561
|
||||
currModelFilename: model1.yml
|
||||
vBatWarn: 66
|
||||
txVoltageCalibration: -7
|
||||
vBatMin: 64
|
||||
vBatMax: 84
|
||||
backlightColor: 0
|
||||
contrast: 18
|
||||
currModel: 0
|
||||
backlightMode: backlight_mode_all
|
||||
trainer:
|
||||
calib:
|
||||
0:
|
||||
val: 0
|
||||
1:
|
||||
val: 0
|
||||
2:
|
||||
val: 0
|
||||
3:
|
||||
val: 0
|
||||
mix:
|
||||
0:
|
||||
srcChn: 3
|
||||
mode: REPL
|
||||
studWeight: 100
|
||||
1:
|
||||
srcChn: 1
|
||||
mode: REPL
|
||||
studWeight: 100
|
||||
2:
|
||||
srcChn: 2
|
||||
mode: REPL
|
||||
studWeight: 100
|
||||
3:
|
||||
srcChn: 0
|
||||
mode: REPL
|
||||
studWeight: 100
|
||||
PPM_Multiplier: 0
|
||||
view: 1
|
||||
fai: 0
|
||||
disableMemoryWarning: 0
|
||||
beepMode: mode_all
|
||||
alarmsFlash: 0
|
||||
disableAlarmWarning: 0
|
||||
disableRssiPoweroffAlarm: 0
|
||||
disableTrainerPoweroffAlarm: 0
|
||||
USBMode: 0
|
||||
hatsMode: SWITCHABLE
|
||||
stickDeadZone: 0
|
||||
jackMode: 0
|
||||
hapticMode: mode_nokeys
|
||||
stickMode: 1
|
||||
timezone: -5
|
||||
timezoneMinutes: 0
|
||||
adjustRTC: 1
|
||||
inactivityTimer: 30
|
||||
internalModuleBaudrate: 5
|
||||
internalModule: TYPE_MULTIMODULE
|
||||
splashMode: 2
|
||||
lightAutoOff: 12
|
||||
templateSetup: 21
|
||||
hapticLength: 1
|
||||
speakerPitch: 0
|
||||
hapticStrength: 2
|
||||
beepLength: 2
|
||||
gpsFormat: 0
|
||||
speakerVolume: 4
|
||||
backlightBright: 0
|
||||
blOffBright: 0
|
||||
switchesDelay: 0
|
||||
globalTimer: 43671
|
||||
bluetoothName: 94832Q-
|
||||
bluetoothBaudrate: 0
|
||||
bluetoothMode: OFF
|
||||
countryCode: 0
|
||||
noJitterFilter: 0
|
||||
disableRtcWarning: 1
|
||||
audioMuteEnable: 0
|
||||
keysBacklight: 0
|
||||
rotEncMode: 0
|
||||
imperial: 0
|
||||
ppmunit: 0
|
||||
ttsLanguage: en
|
||||
beepVolume: 4
|
||||
wavVolume: 4
|
||||
varioVolume: 2
|
||||
varioPitch: 0
|
||||
varioRange: 0
|
||||
varioRepeat: 0
|
||||
backgroundVolume: 3
|
||||
dontPlayHello: 0
|
||||
invertLCD: 0
|
||||
serialPort:
|
||||
VCP:
|
||||
mode: CLI
|
||||
power: 0
|
||||
antennaMode: MODE_PER_MODEL
|
||||
pwrOnSpeed: 1
|
||||
pwrOffSpeed: 1
|
||||
pwrOffIfInactive: 0
|
||||
disablePwrOnOffHaptic: 0
|
||||
sticksConfig:
|
||||
0:
|
||||
name: ""
|
||||
1:
|
||||
name: ""
|
||||
potsConfig:
|
||||
P1:
|
||||
name: ""
|
||||
type: with_detent
|
||||
inv: 0
|
||||
P2:
|
||||
name: ""
|
||||
type: with_detent
|
||||
inv: 0
|
||||
P3:
|
||||
name: ""
|
||||
type: axis_x
|
||||
inv: 0
|
||||
P4:
|
||||
name: ""
|
||||
type: axis_y
|
||||
inv: 0
|
||||
switchConfig:
|
||||
SA:
|
||||
type: 3pos
|
||||
name: ""
|
||||
SB:
|
||||
type: toggle
|
||||
name: ""
|
||||
SC:
|
||||
type: toggle
|
||||
name: ""
|
||||
SD:
|
||||
type: toggle
|
||||
name: ""
|
||||
FL1:
|
||||
type: 2pos
|
||||
name: ""
|
||||
FL2:
|
||||
type: 2pos
|
||||
name: ""
|
||||
ownerRegistrationID: ANNIKA
|
||||
imuMax: 0
|
||||
imuOffset: 0
|
||||
uartSampleMode: 0
|
||||
radioGFDisabled: 0
|
||||
radioTrainerDisabled: 0
|
||||
modelHeliDisabled: 0
|
||||
modelFMDisabled: 0
|
||||
modelCurvesDisabled: 0
|
||||
modelGVDisabled: 0
|
||||
modelLSDisabled: 0
|
||||
modelSFDisabled: 0
|
||||
modelCustomScriptsDisabled: 0
|
||||
modelTelemetryDisabled: 0
|
||||
1
SCREENSHOTS/readme.txt
Executable file
|
|
@ -0,0 +1 @@
|
|||
Screenshots created by "Screenshot" special function will be stored in this directory.
|
||||
1
SCRIPTS/FUNCTIONS/readme.txt
Executable file
|
|
@ -0,0 +1 @@
|
|||
This directory is for Lua functions scripts.
|
||||
1
SCRIPTS/MIXES/readme.txt
Executable file
|
|
@ -0,0 +1 @@
|
|||
This directory is for Lua mixer scripts.
|
||||
68
SCRIPTS/RGBLED/Bback.lua
Executable file
|
|
@ -0,0 +1,68 @@
|
|||
local function init()
|
||||
colorChangeTime = getTime() -- Initialize time
|
||||
phase = 0
|
||||
currentLed = 0 -- Current lit LED position
|
||||
scroll_oldtime = getTime() -- Initialize scroll_oldtime
|
||||
scroll_cycle = 0 -- Initialize scroll_cycle
|
||||
end
|
||||
|
||||
-- Function to generate smooth cyclic colors
|
||||
local function getColor(phase, length)
|
||||
local position = (phase % length) / length
|
||||
local r, g, b = 0, 0, 0
|
||||
local maxBrightness = 255 -- Maximum brightness value
|
||||
|
||||
-- RGB color transition: red -> green -> blue -> red
|
||||
if position < 1/3 then
|
||||
-- From red to green
|
||||
r = maxBrightness * (1 - 3 * position)
|
||||
g = maxBrightness * (3 * position)
|
||||
elseif position < 2/3 then
|
||||
-- From green to blue
|
||||
position = position - 1/3
|
||||
g = maxBrightness * (1 - 3 * position)
|
||||
b = maxBrightness * (3 * position)
|
||||
else
|
||||
-- From blue to red
|
||||
position = position - 2/3
|
||||
b = maxBrightness * (1 - 3 * position)
|
||||
r = maxBrightness * (3 * position)
|
||||
end
|
||||
|
||||
-- Skip colors that are close to the background color
|
||||
local bg_r, bg_g, bg_b = 0, 0, 72 -- Background color
|
||||
local threshold = 30 -- Color difference threshold
|
||||
if math.abs(r - bg_r) < threshold and math.abs(g - bg_g) < threshold and math.abs(b - bg_b) < threshold then
|
||||
return getColor((phase + 1) % length, length) -- Skip this color and get the next one
|
||||
end
|
||||
|
||||
return r, g, b
|
||||
end
|
||||
|
||||
local colorPhase = 0 -- Initialize color phase
|
||||
|
||||
local function run()
|
||||
for i=LED_STRIP_LENGTH - 1, 0, -1 do -- Reverse iteration
|
||||
if (i == scroll_cycle) then
|
||||
local r, g, b = getColor(colorPhase, 255)
|
||||
setRGBLedColor(i, r, g, b)
|
||||
else
|
||||
setRGBLedColor(i, 0, 0, 72)
|
||||
end
|
||||
end
|
||||
if ((getTime() - scroll_oldtime) > 8) then
|
||||
scroll_oldtime = getTime()
|
||||
scroll_cycle = scroll_cycle - 1 -- Decrement scroll_cycle
|
||||
if (scroll_cycle < 0) then
|
||||
scroll_cycle = LED_STRIP_LENGTH - 1 -- Reset scroll_cycle to the end of the strip
|
||||
end
|
||||
end
|
||||
colorPhase = (colorPhase + 1) % 255 -- Update color phase
|
||||
applyRGBLedColors()
|
||||
end
|
||||
|
||||
local function background()
|
||||
-- Called periodically while the Special Function switch is off
|
||||
end
|
||||
|
||||
return { run=run, background=background, init=init }
|
||||
68
SCRIPTS/RGBLED/Bfwrd.lua
Executable file
|
|
@ -0,0 +1,68 @@
|
|||
local function init()
|
||||
colorChangeTime = getTime() -- Initialize time
|
||||
phase = 0
|
||||
currentLed = 0 -- Current lit LED position
|
||||
scroll_oldtime = getTime() -- Initialize scroll_oldtime
|
||||
scroll_cycle = 0 -- Initialize scroll_cycle
|
||||
end
|
||||
|
||||
-- Function to generate smooth cyclic colors
|
||||
local function getColor(phase, length)
|
||||
local position = (phase % length) / length
|
||||
local r, g, b = 0, 0, 0
|
||||
local maxBrightness = 255 -- Maximum brightness value
|
||||
|
||||
-- RGB color transition: red -> green -> blue -> red
|
||||
if position < 1/3 then
|
||||
-- From red to green
|
||||
r = maxBrightness * (1 - 3 * position)
|
||||
g = maxBrightness * (3 * position)
|
||||
elseif position < 2/3 then
|
||||
-- From green to blue
|
||||
position = position - 1/3
|
||||
g = maxBrightness * (1 - 3 * position)
|
||||
b = maxBrightness * (3 * position)
|
||||
else
|
||||
-- From blue to red
|
||||
position = position - 2/3
|
||||
b = maxBrightness * (1 - 3 * position)
|
||||
r = maxBrightness * (3 * position)
|
||||
end
|
||||
|
||||
-- Skip colors that are close to the background color
|
||||
local bg_r, bg_g, bg_b = 0, 0, 72 -- Background color
|
||||
local threshold = 30 -- Color difference threshold
|
||||
if math.abs(r - bg_r) < threshold and math.abs(g - bg_g) < threshold and math.abs(b - bg_b) < threshold then
|
||||
return getColor((phase + 1) % length, length) -- Skip this color and get the next one
|
||||
end
|
||||
|
||||
return r, g, b
|
||||
end
|
||||
|
||||
local colorPhase = 0 -- Initialize color phase
|
||||
|
||||
local function run()
|
||||
for i=0, LED_STRIP_LENGTH - 1, 1 do
|
||||
if (i == scroll_cycle) then
|
||||
local r, g, b = getColor(colorPhase, 255)
|
||||
setRGBLedColor(i, r, g, b)
|
||||
else
|
||||
setRGBLedColor(i, 0, 0, 72)
|
||||
end
|
||||
end
|
||||
if ((getTime() - scroll_oldtime) > 8) then
|
||||
scroll_oldtime = getTime()
|
||||
scroll_cycle = scroll_cycle + 1
|
||||
if (scroll_cycle >= LED_STRIP_LENGTH) then
|
||||
scroll_cycle = 0
|
||||
end
|
||||
end
|
||||
colorPhase = (colorPhase + 1) % 255 -- Update color phase
|
||||
applyRGBLedColors()
|
||||
end
|
||||
|
||||
local function background()
|
||||
-- Called periodically while the Special Function switch is off
|
||||
end
|
||||
|
||||
return { run=run, background=background, init=init }
|
||||
68
SCRIPTS/RGBLED/Pback.lua
Executable file
|
|
@ -0,0 +1,68 @@
|
|||
local function init()
|
||||
colorChangeTime = getTime() -- Initialize time
|
||||
phase = 0
|
||||
currentLed = 0 -- Current lit LED position
|
||||
scroll_oldtime = getTime() -- Initialize scroll_oldtime
|
||||
scroll_cycle = 0 -- Initialize scroll_cycle
|
||||
end
|
||||
|
||||
-- Function to generate smooth cyclic colors
|
||||
local function getColor(phase, length)
|
||||
local position = (phase % length) / length
|
||||
local r, g, b = 0, 0, 0
|
||||
local maxBrightness = 255 -- Maximum brightness value
|
||||
|
||||
-- RGB color transition: red -> green -> blue -> red
|
||||
if position < 1/3 then
|
||||
-- From red to green
|
||||
r = maxBrightness * (1 - 3 * position)
|
||||
g = maxBrightness * (3 * position)
|
||||
elseif position < 2/3 then
|
||||
-- From green to blue
|
||||
position = position - 1/3
|
||||
g = maxBrightness * (1 - 3 * position)
|
||||
b = maxBrightness * (3 * position)
|
||||
else
|
||||
-- From blue to red
|
||||
position = position - 2/3
|
||||
b = maxBrightness * (1 - 3 * position)
|
||||
r = maxBrightness * (3 * position)
|
||||
end
|
||||
|
||||
-- Skip colors that are close to the background color
|
||||
local bg_r, bg_g, bg_b = 72, 0, 72 -- Background color
|
||||
local threshold = 30 -- Color difference threshold
|
||||
if math.abs(r - bg_r) < threshold and math.abs(g - bg_g) < threshold and math.abs(b - bg_b) < threshold then
|
||||
return getColor((phase + 1) % length, length) -- Skip this color and get the next one
|
||||
end
|
||||
|
||||
return r, g, b
|
||||
end
|
||||
|
||||
local colorPhase = 0 -- Initialize color phase
|
||||
|
||||
local function run()
|
||||
for i=LED_STRIP_LENGTH - 1, 0, -1 do -- Reverse iteration
|
||||
if (i == scroll_cycle) then
|
||||
local r, g, b = getColor(colorPhase, 255)
|
||||
setRGBLedColor(i, r, g, b)
|
||||
else
|
||||
setRGBLedColor(i, 72, 0, 72)
|
||||
end
|
||||
end
|
||||
if ((getTime() - scroll_oldtime) > 8) then
|
||||
scroll_oldtime = getTime()
|
||||
scroll_cycle = scroll_cycle - 1 -- Decrement scroll_cycle
|
||||
if (scroll_cycle < 0) then
|
||||
scroll_cycle = LED_STRIP_LENGTH - 1 -- Reset scroll_cycle to the end of the strip
|
||||
end
|
||||
end
|
||||
colorPhase = (colorPhase + 1) % 255 -- Update color phase
|
||||
applyRGBLedColors()
|
||||
end
|
||||
|
||||
local function background()
|
||||
-- Called periodically while the Special Function switch is off
|
||||
end
|
||||
|
||||
return { run=run, background=background, init=init }
|
||||
BIN
SCRIPTS/RGBLED/Pback.luac
Executable file
68
SCRIPTS/RGBLED/Pfwrd.lua
Executable file
|
|
@ -0,0 +1,68 @@
|
|||
local function init()
|
||||
colorChangeTime = getTime() -- Initialize time
|
||||
phase = 0
|
||||
currentLed = 0 -- Current lit LED position
|
||||
scroll_oldtime = getTime() -- Initialize scroll_oldtime
|
||||
scroll_cycle = 0 -- Initialize scroll_cycle
|
||||
end
|
||||
|
||||
-- Function to generate smooth cyclic colors
|
||||
local function getColor(phase, length)
|
||||
local position = (phase % length) / length
|
||||
local r, g, b = 0, 0, 0
|
||||
local maxBrightness = 255 -- Maximum brightness value
|
||||
|
||||
-- RGB color transition: red -> green -> blue -> red
|
||||
if position < 1/3 then
|
||||
-- From red to green
|
||||
r = maxBrightness * (1 - 3 * position)
|
||||
g = maxBrightness * (3 * position)
|
||||
elseif position < 2/3 then
|
||||
-- From green to blue
|
||||
position = position - 1/3
|
||||
g = maxBrightness * (1 - 3 * position)
|
||||
b = maxBrightness * (3 * position)
|
||||
else
|
||||
-- From blue to red
|
||||
position = position - 2/3
|
||||
b = maxBrightness * (1 - 3 * position)
|
||||
r = maxBrightness * (3 * position)
|
||||
end
|
||||
|
||||
-- Skip colors that are close to the background color
|
||||
local bg_r, bg_g, bg_b = 72, 0, 72 -- Background color
|
||||
local threshold = 30 -- Color difference threshold
|
||||
if math.abs(r - bg_r) < threshold and math.abs(g - bg_g) < threshold and math.abs(b - bg_b) < threshold then
|
||||
return getColor((phase + 1) % length, length) -- Skip this color and get the next one
|
||||
end
|
||||
|
||||
return r, g, b
|
||||
end
|
||||
|
||||
local colorPhase = 0 -- Initialize color phase
|
||||
|
||||
local function run()
|
||||
for i=0, LED_STRIP_LENGTH - 1, 1 do
|
||||
if (i == scroll_cycle) then
|
||||
local r, g, b = getColor(colorPhase, 255)
|
||||
setRGBLedColor(i, r, g, b)
|
||||
else
|
||||
setRGBLedColor(i, 72, 0, 72)
|
||||
end
|
||||
end
|
||||
if ((getTime() - scroll_oldtime) > 8) then
|
||||
scroll_oldtime = getTime()
|
||||
scroll_cycle = scroll_cycle + 1
|
||||
if (scroll_cycle >= LED_STRIP_LENGTH) then
|
||||
scroll_cycle = 0
|
||||
end
|
||||
end
|
||||
colorPhase = (colorPhase + 1) % 255 -- Update color phase
|
||||
applyRGBLedColors()
|
||||
end
|
||||
|
||||
local function background()
|
||||
-- Called periodically while the Special Function switch is off
|
||||
end
|
||||
|
||||
return { run=run, background=background, init=init }
|
||||
BIN
SCRIPTS/RGBLED/Pfwrd.luac
Executable file
1
SCRIPTS/RGBLED/README.md
Executable file
|
|
@ -0,0 +1 @@
|
|||
This folder contains sample RGB Lua scripts, for radios which support this capability.
|
||||
16
SCRIPTS/RGBLED/blue.lua
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
local function init()
|
||||
end
|
||||
|
||||
local function run()
|
||||
for i=0, LED_STRIP_LENGTH - 1, 1
|
||||
do
|
||||
setRGBLedColor(i, 0, 0, 128)
|
||||
end
|
||||
applyRGBLedColors()
|
||||
end
|
||||
|
||||
local function background()
|
||||
-- Called periodically while the Special Function switch is off
|
||||
end
|
||||
|
||||
return { run=run, background=background, init=init }
|
||||
BIN
SCRIPTS/RGBLED/blue.luac
Executable file
52
SCRIPTS/RGBLED/flow.lua
Executable file
|
|
@ -0,0 +1,52 @@
|
|||
local function init()
|
||||
colorChangeTime = getTime() -- Initialize time
|
||||
phase = 0
|
||||
end
|
||||
|
||||
local minBrightness = 0 -- Minimum brightness value
|
||||
local maxBrightness = 255 -- Maximum brightness value
|
||||
|
||||
local function getColor(phase, length)
|
||||
local position = (phase % length) / length
|
||||
local r, g, b = minBrightness, minBrightness, minBrightness
|
||||
|
||||
-- RGB color transition: red -> green -> blue -> red
|
||||
if position < 1/3 then
|
||||
-- From red to green
|
||||
r = maxBrightness * (1 - 32 * position)
|
||||
g = maxBrightness * (32 * position)
|
||||
elseif position < 2/3 then
|
||||
-- From green to blue
|
||||
position = position - 1/3
|
||||
g = maxBrightness * (1 - 32 * position)
|
||||
b = maxBrightness * (32 * position)
|
||||
else
|
||||
-- From blue to red
|
||||
position = position - 2/3
|
||||
b = maxBrightness * (1 - 32 * position)
|
||||
r = maxBrightness * (32 * position)
|
||||
end
|
||||
|
||||
return r, g, b
|
||||
end
|
||||
|
||||
local colorChangeTime = 0 -- The time of the last color change
|
||||
|
||||
local function run()
|
||||
if ((getTime() - colorChangeTime) > 1) then -- Use an interval of 2 time units
|
||||
colorChangeTime = getTime()
|
||||
phase = (phase + 1) % 255 -- Update color phase
|
||||
|
||||
for i = 0, LED_STRIP_LENGTH - 1, 1 do
|
||||
local r, g, b = getColor(phase + i * 64, 255) -- Increase phase offset for each LED
|
||||
setRGBLedColor(i, r, g, b)
|
||||
end
|
||||
applyRGBLedColors()
|
||||
end
|
||||
end
|
||||
|
||||
local function background()
|
||||
-- Called periodically while the Special Function switch is off
|
||||
end
|
||||
|
||||
return { run=run, background=background, init=init }
|
||||
16
SCRIPTS/RGBLED/green.lua
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
local function init()
|
||||
end
|
||||
|
||||
local function run()
|
||||
for i=0, LED_STRIP_LENGTH - 1, 1
|
||||
do
|
||||
setRGBLedColor(i, 0, 255, 0)
|
||||
end
|
||||
applyRGBLedColors()
|
||||
end
|
||||
|
||||
local function background()
|
||||
-- Called periodically while the Special Function switch is off
|
||||
end
|
||||
|
||||
return { run=run, background=background, init=init }
|
||||
BIN
SCRIPTS/RGBLED/green.luac
Executable file
16
SCRIPTS/RGBLED/off.lua
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
local function init()
|
||||
end
|
||||
|
||||
local function run()
|
||||
for i=0, LED_STRIP_LENGTH - 1, 1
|
||||
do
|
||||
setRGBLedColor(i, 0, 0, 0)
|
||||
end
|
||||
applyRGBLedColors()
|
||||
end
|
||||
|
||||
local function background()
|
||||
-- Called periodically while the Special Function switch is off
|
||||
end
|
||||
|
||||
return { run=run, background=background, init=init }
|
||||
16
SCRIPTS/RGBLED/orange.lua
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
local function init()
|
||||
end
|
||||
|
||||
local function run()
|
||||
for i=0, LED_STRIP_LENGTH - 1, 1
|
||||
do
|
||||
setRGBLedColor(i, 255, 100, 0) -- Change RGB values to represent orange color
|
||||
end
|
||||
applyRGBLedColors()
|
||||
end
|
||||
|
||||
local function background()
|
||||
-- Called periodically while the Special Function switch is off
|
||||
end
|
||||
|
||||
return { run=run, background=background, init=init }
|
||||
BIN
SCRIPTS/RGBLED/orange.luac
Normal file
26
SCRIPTS/RGBLED/police.lua
Executable file
|
|
@ -0,0 +1,26 @@
|
|||
local function init()
|
||||
police_oldtime = getTime()
|
||||
police_cycle = 0
|
||||
end
|
||||
|
||||
local function run()
|
||||
for i=0, LED_STRIP_LENGTH - 1, 1
|
||||
do
|
||||
if (i % 2 == police_cycle) then
|
||||
setRGBLedColor(i, 0, 0, 50)
|
||||
else
|
||||
setRGBLedColor(i, 50, 0, 0)
|
||||
end
|
||||
end
|
||||
if ((getTime() - police_oldtime) > 8) then
|
||||
police_oldtime = getTime()
|
||||
police_cycle = 1 - police_cycle
|
||||
end
|
||||
applyRGBLedColors()
|
||||
end
|
||||
|
||||
local function background()
|
||||
-- Called periodically while the Special Function switch is off
|
||||
end
|
||||
|
||||
return { run=run, background=background, init=init }
|
||||
BIN
SCRIPTS/RGBLED/police.luac
Executable file
16
SCRIPTS/RGBLED/purple.lua
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
local function init()
|
||||
end
|
||||
|
||||
local function run()
|
||||
for i=0, LED_STRIP_LENGTH - 1, 1
|
||||
do
|
||||
setRGBLedColor(i, 255, 0, 255) -- Set to purple color
|
||||
end
|
||||
applyRGBLedColors()
|
||||
end
|
||||
|
||||
local function background()
|
||||
-- Called periodically while the Special Function switch is off
|
||||
end
|
||||
|
||||
return { run=run, background=background, init=init }
|
||||
52
SCRIPTS/RGBLED/rainbw.lua
Executable file
|
|
@ -0,0 +1,52 @@
|
|||
local function init()
|
||||
colorChangeTime = getTime() -- Initialize time
|
||||
phase = 0
|
||||
end
|
||||
|
||||
local minBrightness = 0 -- Minimum brightness value
|
||||
local maxBrightness = 255 -- Maximum brightness value
|
||||
|
||||
local function getColor(phase, length)
|
||||
local position = (phase % length) / length
|
||||
local r, g, b = minBrightness, minBrightness, minBrightness
|
||||
|
||||
-- RGB color transition: red -> green -> blue -> red
|
||||
if position < 1/3 then
|
||||
-- From red to green
|
||||
r = maxBrightness * (1 - 3 * position)
|
||||
g = maxBrightness * (3 * position)
|
||||
elseif position < 2/3 then
|
||||
-- From green to blue
|
||||
position = position - 1/3
|
||||
g = maxBrightness * (1 - 3 * position)
|
||||
b = maxBrightness * (3 * position)
|
||||
else
|
||||
-- From blue to red
|
||||
position = position - 2/3
|
||||
b = maxBrightness * (1 - 3 * position)
|
||||
r = maxBrightness * (3 * position)
|
||||
end
|
||||
|
||||
return r, g, b
|
||||
end
|
||||
|
||||
local colorChangeTime = 0 -- The time of the last color change
|
||||
|
||||
local function run()
|
||||
if ((getTime() - colorChangeTime) > 2) then -- Use an interval of 4 time units
|
||||
colorChangeTime = getTime()
|
||||
phase = (phase + 1) % 255 -- Update color phase
|
||||
|
||||
for i = 0, LED_STRIP_LENGTH - 1, 1 do
|
||||
local r, g, b = getColor(phase + i * 64, 255) -- Increase phase offset for each LED
|
||||
setRGBLedColor(i, r, g, b)
|
||||
end
|
||||
applyRGBLedColors()
|
||||
end
|
||||
end
|
||||
|
||||
local function background()
|
||||
-- Called periodically while the Special Function switch is off
|
||||
end
|
||||
|
||||
return { run=run, background=background, init=init }
|
||||
BIN
SCRIPTS/RGBLED/rainbw.luac
Executable file
16
SCRIPTS/RGBLED/red.lua
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
local function init()
|
||||
end
|
||||
|
||||
local function run()
|
||||
for i=0, LED_STRIP_LENGTH - 1, 1
|
||||
do
|
||||
setRGBLedColor(i, 50, 0, 0)
|
||||
end
|
||||
applyRGBLedColors()
|
||||
end
|
||||
|
||||
local function background()
|
||||
-- Called periodically while the Special Function switch is off
|
||||
end
|
||||
|
||||
return { run=run, background=background, init=init }
|
||||
BIN
SCRIPTS/RGBLED/red.luac
Executable file
53
SCRIPTS/RGBLED/rgbLop.lua
Executable file
|
|
@ -0,0 +1,53 @@
|
|||
local function init()
|
||||
cycleTime = getTime() -- Initialize time
|
||||
phase = 0
|
||||
end
|
||||
|
||||
-- Function to generate smooth cyclic colors
|
||||
local function getColor(phase, length)
|
||||
local position = (phase % length) / length
|
||||
local r, g, b = 5, 5, 5
|
||||
local maxBrightness = 255 -- Maximum brightness value
|
||||
local minBrightness = 0 -- Minimum brightness value
|
||||
|
||||
-- RGB color transition: red -> green -> blue -> red
|
||||
if position < 1/3 then
|
||||
-- From red to green
|
||||
r = minBrightness + (maxBrightness - minBrightness) * (1 - 3 * position)
|
||||
g = maxBrightness * (3 * position)
|
||||
b = minBrightness
|
||||
elseif position < 2/3 then
|
||||
-- From green to blue
|
||||
position = position - 1/3
|
||||
g = minBrightness + (maxBrightness - minBrightness) * (1 - 3 * position)
|
||||
b = maxBrightness * (3 * position)
|
||||
r = minBrightness
|
||||
else
|
||||
-- From blue to red
|
||||
position = position - 2/3
|
||||
b = minBrightness + (maxBrightness - minBrightness) * (1 - 3 * position)
|
||||
r = maxBrightness * (3 * position)
|
||||
g = minBrightness
|
||||
end
|
||||
|
||||
return math.max(0, math.min(r, maxBrightness)), math.max(0, math.min(g, maxBrightness)), math.max(0, math.min(b, maxBrightness))
|
||||
end
|
||||
|
||||
local function run()
|
||||
if ((getTime() - cycleTime) > 2) then -- Use an interval of 8 time units
|
||||
cycleTime = getTime()
|
||||
phase = phase + 1 -- Update color phase
|
||||
end
|
||||
|
||||
for i = 0, LED_STRIP_LENGTH - 1, 1 do
|
||||
local r, g, b = getColor(phase, 255)
|
||||
setRGBLedColor(i, r, g, b)
|
||||
end
|
||||
applyRGBLedColors()
|
||||
end
|
||||
|
||||
local function background()
|
||||
-- Called periodically while the Special Function switch is off
|
||||
end
|
||||
|
||||
return { run=run, background=background, init=init }
|
||||
BIN
SCRIPTS/RGBLED/rgbLop.luac
Normal file
77
SCRIPTS/RGBLED/runner.lua
Executable file
|
|
@ -0,0 +1,77 @@
|
|||
local function init()
|
||||
colorChangeTime = getTime() -- Initialize time
|
||||
phase = 0
|
||||
currentLed = 0 -- Current lit LED position
|
||||
end
|
||||
|
||||
local minBrightness = 0 -- Minimum brightness value
|
||||
local maxBrightness = 255 -- Maximum brightness value
|
||||
|
||||
local function getColor(phase, length)
|
||||
local position = (phase % length) / length
|
||||
local r, g, b = minBrightness, minBrightness, minBrightness
|
||||
|
||||
-- RGB color transition: red -> green -> blue -> red
|
||||
if position < 1/3 then
|
||||
-- From red to green
|
||||
r = maxBrightness * (1 - 3 * position)
|
||||
g = maxBrightness * (3 * position)
|
||||
elseif position < 2/3 then
|
||||
-- From green to blue
|
||||
position = position - 1/3
|
||||
g = maxBrightness * (1 - 3 * position)
|
||||
b = maxBrightness * (3 * position)
|
||||
else
|
||||
-- From blue to red
|
||||
position = position - 2/3
|
||||
b = maxBrightness * (1 - 3 * position)
|
||||
r = maxBrightness * (3 * position)
|
||||
end
|
||||
|
||||
return r, g, b
|
||||
end
|
||||
|
||||
local maxBackgroundBrightness = 255 -- Maximum brightness value for the background
|
||||
|
||||
local function run()
|
||||
if ((getTime() - colorChangeTime) > 2) then -- Use an interval of 4 time units
|
||||
colorChangeTime = getTime()
|
||||
phase = phase + 1 -- Update color phase
|
||||
currentLed = (currentLed + 1) % LED_STRIP_LENGTH -- Move to the next LED
|
||||
end
|
||||
|
||||
for i = 0, LED_STRIP_LENGTH - 1, 1 do
|
||||
local r, g, b = getColor(phase, 255)
|
||||
if i <= currentLed then
|
||||
setRGBLedColor(i, r, g, b)
|
||||
else
|
||||
-- Set the background color to the opposite of the main color in the RGB color space
|
||||
local bg_r = (r + 128) % 256
|
||||
local bg_g = (g + 128) % 256
|
||||
local bg_b = (b + 128) % 256
|
||||
|
||||
-- Ensure the brightness of the background color does not exceed 72
|
||||
bg_r = math.min(bg_r, maxBackgroundBrightness)
|
||||
bg_g = math.min(bg_g, maxBackgroundBrightness)
|
||||
bg_b = math.min(bg_b, maxBackgroundBrightness)
|
||||
|
||||
-- Ensure at least one color channel is always off
|
||||
if bg_r > bg_g and bg_r > bg_b then
|
||||
bg_r = 0
|
||||
elseif bg_g > bg_r and bg_g > bg_b then
|
||||
bg_g = 0
|
||||
else
|
||||
bg_b = 0
|
||||
end
|
||||
|
||||
setRGBLedColor(i, bg_r, bg_g, bg_b)
|
||||
end
|
||||
end
|
||||
applyRGBLedColors()
|
||||
end
|
||||
|
||||
local function background()
|
||||
-- Called periodically while the Special Function switch is off
|
||||
end
|
||||
|
||||
return { run=run, background=background, init=init }
|
||||
BIN
SCRIPTS/RGBLED/runner.luac
Executable file
16
SCRIPTS/RGBLED/sapp.lua
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
local function init()
|
||||
end
|
||||
|
||||
local function run()
|
||||
for i=0, LED_STRIP_LENGTH - 1, 1
|
||||
do
|
||||
setRGBLedColor(i, 0, 255, 255) -- Set to sapphire color
|
||||
end
|
||||
applyRGBLedColors()
|
||||
end
|
||||
|
||||
local function background()
|
||||
-- Called periodically while the Special Function switch is off
|
||||
end
|
||||
|
||||
return { run=run, background=background, init=init }
|
||||
16
SCRIPTS/RGBLED/white.lua
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
local function init()
|
||||
end
|
||||
|
||||
local function run()
|
||||
for i=0, LED_STRIP_LENGTH - 1, 1
|
||||
do
|
||||
setRGBLedColor(i, 255, 255, 255) -- Set to white color
|
||||
end
|
||||
applyRGBLedColors()
|
||||
end
|
||||
|
||||
local function background()
|
||||
-- Called periodically while the Special Function switch is off
|
||||
end
|
||||
|
||||
return { run=run, background=background, init=init }
|
||||
16
SCRIPTS/RGBLED/yellow.lua
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
local function init()
|
||||
end
|
||||
|
||||
local function run()
|
||||
for i=0, LED_STRIP_LENGTH - 1, 1
|
||||
do
|
||||
setRGBLedColor(i, 255, 255, 0)
|
||||
end
|
||||
applyRGBLedColors()
|
||||
end
|
||||
|
||||
local function background()
|
||||
-- Called periodically while the Special Function switch is off
|
||||
end
|
||||
|
||||
return { run=run, background=background, init=init }
|
||||
BIN
SCRIPTS/RGBLED/yellow.luac
Normal file
63
SCRIPTS/TELEMETRY/gplusl.lua
Executable file
|
|
@ -0,0 +1,63 @@
|
|||
-- This code was originally written by Miami Mike to calculate the Open Location Code (Google+Code)
|
||||
-- It was altered by ChrisOhara to permanently store the last received GPS coordinates by background function.
|
||||
-- So that it can display the last position as Google+Code even after connection to receiver is lost.
|
||||
-- Works on taranis
|
||||
|
||||
local mid = LCD_W / 2
|
||||
local map = {[0] =
|
||||
"2", "3", "4", "5", "6", "7", "8", "9", "C", "F",
|
||||
"G", "H", "J", "M", "P", "Q", "R", "V", "W", "X"}
|
||||
|
||||
local my_gpsId
|
||||
local latitude, longitude = 0.0, 0.0
|
||||
local lat = 0
|
||||
local lon = 0
|
||||
local pluscode = ""
|
||||
|
||||
|
||||
local function init_func()
|
||||
my_gpsId = getFieldInfo("GPS") and getFieldInfo("GPS").id or nil;
|
||||
end
|
||||
|
||||
|
||||
local function getcode(lat, lon)
|
||||
local int = math.floor(lat)
|
||||
local codepair = map[int]
|
||||
lat = 20 * (lat - int)
|
||||
int = math.floor(lon)
|
||||
codepair = codepair .. map[int]
|
||||
lon = 20 * (lon - int)
|
||||
return lat, lon, codepair
|
||||
end
|
||||
|
||||
|
||||
local function bg_func()
|
||||
if getValue(my_gpsId) ~= 0 then
|
||||
local gps = getValue(my_gpsId)
|
||||
latitude, longitude = gps.lat, gps.lon
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function run_func()
|
||||
lat = (latitude + 90) / 20
|
||||
lon = (longitude + 180) / 20
|
||||
pluscode = ""
|
||||
for i = 1, 4 do
|
||||
lat, lon, codepair = getcode(lat, lon)
|
||||
pluscode = pluscode .. codepair
|
||||
end
|
||||
pluscode = pluscode .. "+"
|
||||
lat, lon, codepair = getcode(lat, lon)
|
||||
pluscode = pluscode .. codepair
|
||||
pluscode = pluscode .. map[4 * math.floor(lat / 5) + math.floor(lon / 4)]
|
||||
lcd.clear()
|
||||
lcd.drawText(mid - 53, 5, "GPS coordinates are")
|
||||
lcd.drawText(mid - 44, 15, latitude.. ", " .. longitude)
|
||||
lcd.drawText(mid- 49, 35, "Google Plus Code is")
|
||||
lcd.drawText(mid - 32, 45, pluscode) -- full 12 characters
|
||||
--- lcd.drawText(mid - 20, 45, string.sub(pluscode, 5, 12)) -- shortened version
|
||||
return 0
|
||||
end
|
||||
|
||||
return {run=run_func, init=init_func, background=bg_func}
|
||||
2
SCRIPTS/TELEMETRY/readme.txt
Executable file
|
|
@ -0,0 +1,2 @@
|
|||
This directory is for Lua telemetry scripts.
|
||||
Those scripts can be selected using DISPLAY screen in MODEL SETUP.
|
||||
BIN
SCRIPTS/TOOLS/BREAKOUT/gfx/gover1.bmp
Executable file
|
After Width: | Height: | Size: 574 B |
BIN
SCRIPTS/TOOLS/BREAKOUT/gfx/gover2.bmp
Executable file
|
After Width: | Height: | Size: 574 B |
BIN
SCRIPTS/TOOLS/BREAKOUT/gfx/splash1.bmp
Executable file
|
After Width: | Height: | Size: 574 B |
BIN
SCRIPTS/TOOLS/BREAKOUT/gfx/splash2.bmp
Executable file
|
After Width: | Height: | Size: 574 B |
BIN
SCRIPTS/TOOLS/BREAKOUT/gfx/up1.bmp
Executable file
|
After Width: | Height: | Size: 574 B |
BIN
SCRIPTS/TOOLS/BREAKOUT/gfx/up2.bmp
Executable file
|
After Width: | Height: | Size: 574 B |
1046
SCRIPTS/TOOLS/DSM FwdPrg_55_MIN.lua
Normal file
790
SCRIPTS/TOOLS/DSM FwdPrg_56_Color.lua
Normal file
|
|
@ -0,0 +1,790 @@
|
|||
local toolName = "TNS|DSM Forward Prog v0.56 (Color) |TNE"
|
||||
local VERSION = "v0.56"
|
||||
|
||||
---- #########################################################################
|
||||
---- # #
|
||||
---- # Copyright (C) OpenTX #
|
||||
-----# #
|
||||
---- # 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. #
|
||||
---- # #
|
||||
---- #########################################################################
|
||||
------------------------------------------------------------------------------
|
||||
-- This script library is a rewrite of the original DSM forward programming Lua
|
||||
-- Script. The goal is to make it easier to understand, mantain, and to
|
||||
-- separate the GUI from the DSM Forward programming engine/logic
|
||||
-- in this way, GUIs can evolve independent. OpenTX Gui, EdgeTx GUI, Small Radios, etc.
|
||||
|
||||
-- Code is based on the code/work by: Pascal Langer (Author of the Multi-Module)
|
||||
-- Rewrite/Enhancements By: Francisco Arzu
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
local SIMULATION_ON = true -- false: dont show simulation menu, TRUE: show simulation menu
|
||||
local DEBUG_ON = 1 -- 0=NO DEBUG, 1=HIGH LEVEL 2=LOW LEVEL (Debug logged into the /LOGS/dsm.log)
|
||||
local USE_SPECKTRUM_COLORS = true -- true: Use spectrum colors, false: use theme colors (default on OpenTX)
|
||||
local DSMLIB_PATH = "/SCRIPTS/TOOLS/DSMLIB/"
|
||||
local IMAGE_PATH = DSMLIB_PATH .. "img/"
|
||||
|
||||
local Log = assert(loadScript(DSMLIB_PATH.."DsmLogLib.lua"), "Not-Found: DSMLIB/DsmLogLib.lua")()
|
||||
local menuLib = assert(loadScript(DSMLIB_PATH.."DsmMenuLib.lua"), "Not-Found: DSMLIB/DsmMenuLib.lua")(Log, DEBUG_ON)
|
||||
local modelLib = assert(loadScript(DSMLIB_PATH.."DsmModelLib.lua"), "Not-Found: DSMLIB/DsmModelLib.lua")(Log, DEBUG_ON)
|
||||
local menuProcessor = assert(loadScript(DSMLIB_PATH.."DsmMainMenuLib.lua"), "Not-Found: DSMLIB/DsmMainMenuLib.lua")(Log, menuLib, modelLib, DEBUG_ON, SIMULATION_ON)
|
||||
|
||||
local PHASE = menuLib.PHASE
|
||||
local LINE_TYPE = menuLib.LINE_TYPE
|
||||
local DISP_ATTR = menuLib.DISP_ATTR
|
||||
local DSM_Context = menuLib.DSM_Context
|
||||
|
||||
|
||||
local lastRefresh=0 -- Last time the screen was refreshed
|
||||
local REFRESH_GUI_MS = 300/10 -- 300ms.. Screen Refresh Rate.. to not waste CPU time (in 10ms units to be compatible with getTime())
|
||||
local originalValue = nil
|
||||
|
||||
local touchButtonArea = {}
|
||||
local EDIT_BUTTON = { DEFAULT=1001, DEC_10=1002, DEC_1=1003, INC_1=1004, INC_10=5, OK=1006, ESC=1007 }
|
||||
|
||||
local IS_EDGETX = false -- DEFAULT until Init changed it
|
||||
|
||||
local LCD_Y_MENU_TITLE = 20
|
||||
local LCD_W_MENU_TITLE = LCD_W-100
|
||||
|
||||
local LCD_X_LINE_MENU = 30
|
||||
local LCD_W_LINE_MENU = 350
|
||||
|
||||
local LCD_X_LINE_TITLE = 30
|
||||
local LCD_X_LINE_VALUE = 230
|
||||
local LCD_X_LINE_DEBUG = 390
|
||||
|
||||
|
||||
local LCD_Y_LINE_START = LCD_Y_MENU_TITLE + 30
|
||||
local LCD_Y_LINE_HEIGHT = 27
|
||||
|
||||
local LCD_Y_LOWER_BUTTONS = LCD_Y_LINE_START + 3 + (7 * LCD_Y_LINE_HEIGHT)
|
||||
|
||||
-- TOOL BG COLOR
|
||||
local LCD_TOOL_BGCOLOR = TEXT_BGCOLOR
|
||||
-- TOOL HEADER
|
||||
local LCD_TOOL_HDR_COLOR = MENU_TITLE_COLOR
|
||||
local LCD_TOOL_HDR_BGCOLOR = TITLE_BGCOLOR
|
||||
-- MENU HEADER
|
||||
local LCD_MENU_COLOR = MENU_TITLE_COLOR
|
||||
local LCD_MENU_BGCOLOR = MENU_TITLE_BGCOLOR
|
||||
-- LINE SELECTED
|
||||
local LCD_SELECTED_COLOR = TEXT_INVERTED_COLOR
|
||||
local LCD_SELECTED_BGCOLOR = TEXT_INVERTED_BGCOLOR
|
||||
local LCD_EDIT_BGCOLOR = MENU_TITLE_BGCOLOR -- WARNING_COLOR
|
||||
-- NORMAL TEXT
|
||||
local LCD_NORMAL_COLOR = TEXT_COLOR
|
||||
local LCD_DISABLE_COLOR = TEXT_DISABLE_COLOR
|
||||
local LCD_DEBUG_COLOR = LINE_COLOR
|
||||
-- NORMAL BOX FRAME COLOR
|
||||
local LCD_BOX_COLOR = TEXT_DISABLE_COLOR
|
||||
|
||||
|
||||
local warningScreenON = true
|
||||
|
||||
|
||||
--------------------- lcd.sizeText replacement -------------------------------------------------
|
||||
-- EdgeTx dont have lcd.sizeText, so we do an equivalent one using the string length and 5px per character
|
||||
local function my_lcd_sizeText(s)
|
||||
if (s==nil) then return 20 end
|
||||
-- return: If IS_EDGETX then lcd.sizeText() else string.len()
|
||||
return (IS_EDGETX and lcd.sizeText(s)) or (string.len(s)*10)
|
||||
end
|
||||
|
||||
|
||||
local function GUI_SwitchToRX()
|
||||
-- Force to refresh DSM Info in MODEL (dsmLib pointing to the setup Script)
|
||||
-- local dsmChannelInfo, description = modelLib.CreateDSMPortChannelInfo()
|
||||
|
||||
menuProcessor.done()
|
||||
Log.LOG_close() -- Reset the log
|
||||
Log.LOG_open()
|
||||
|
||||
menuProcessor = nil
|
||||
collectgarbage("collect")
|
||||
|
||||
modelLib.ReadTxModelData()
|
||||
modelLib.ST_LoadFileData()
|
||||
modelLib.CreateDSMPortChannelInfo()
|
||||
|
||||
local dsmLib = assert(loadScript(DSMLIB_PATH.."DsmFwPrgLib.lua"),"Not-Found: DSMLIB/DsmFwPrgLib.lua")
|
||||
menuProcessor = dsmLib(Log, menuLib, modelLib, DEBUG_ON)
|
||||
|
||||
dsmLib = nil
|
||||
collectgarbage("collect")
|
||||
|
||||
menuProcessor.init(toolName) -- Initialize Library
|
||||
DSM_Context.Refresh_Display = true
|
||||
end
|
||||
|
||||
local function GUI_SwitchToSIM()
|
||||
menuProcessor.done()
|
||||
Log.LOG_close()
|
||||
|
||||
menuProcessor = nil
|
||||
collectgarbage("collect")
|
||||
|
||||
local simLib = assert(loadScript(DSMLIB_PATH.."DsmSimMenuLib.lua"), "Not-Found: DSMLIB/DsmSimMenuLib.lua")
|
||||
menuProcessor = simLib(Log, menuLib, modelLib, DEBUG_ON)
|
||||
|
||||
simLib = nil
|
||||
collectgarbage("collect")
|
||||
|
||||
menuProcessor.init(toolName) -- Initialize Library
|
||||
DSM_Context.Refresh_Display = true
|
||||
end
|
||||
|
||||
local function GUI_SwitchToSetupMenu()
|
||||
menuProcessor.done()
|
||||
|
||||
menuProcessor = nil
|
||||
collectgarbage("collect")
|
||||
|
||||
local setupLib = assert(loadScript(DSMLIB_PATH.."DsmSetupMenuLib.lua"), "Not-Found: DSMLIB/DsmSetupMenuLib.lua")
|
||||
menuProcessor = setupLib(Log, menuLib, modelLib, DEBUG_ON, SIMULATION_ON)
|
||||
|
||||
setupLib = nil
|
||||
collectgarbage("collect")
|
||||
|
||||
menuProcessor.init(toolName) -- Initialize Library
|
||||
DSM_Context.Refresh_Display = true
|
||||
end
|
||||
|
||||
local function GUI_SwitchToMainMenu()
|
||||
print("SWITCHING TO MAIN MENU")
|
||||
menuProcessor.done()
|
||||
|
||||
menuProcessor = nil
|
||||
collectgarbage("collect")
|
||||
|
||||
local mainMenuLib = assert(loadScript(DSMLIB_PATH.."DsmMainMenuLib.lua"), "Not-Found: DSMLIB/DsmMainMenuLib.lua")
|
||||
menuProcessor = mainMenuLib(Log, menuLib, modelLib, DEBUG_ON, SIMULATION_ON)
|
||||
|
||||
mainMenuLib = nil
|
||||
collectgarbage("collect")
|
||||
|
||||
menuProcessor.init(toolName) -- Initialize Library
|
||||
DSM_Context.Refresh_Display = true
|
||||
end
|
||||
|
||||
|
||||
--------------------- Toucch Button Helpers ------------------------------------------------------------
|
||||
local function GUI_addTouchButton(x,y,w,h,line)
|
||||
-- Add new button info to end of the array
|
||||
touchButtonArea[#touchButtonArea+1] = {x=x, y=y, w=w, h=h, line=line}
|
||||
end
|
||||
|
||||
local function GUI_getTouchButton(x,y)
|
||||
for i = 1, #touchButtonArea do
|
||||
local button = touchButtonArea[i]
|
||||
-- is the coordinate inside the button area??
|
||||
if (x >= button.x and x <= (button.x+button.w) and y >= button.y and (y <= button.y+button.h)) then
|
||||
return button.line
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
local function GUI_clearTouchButtons()
|
||||
touchButtonArea = {}
|
||||
end
|
||||
|
||||
---------- Return Color to display Menu Lines ----------------------------------------------------------------
|
||||
local function GUI_GetTextColor(lineNum)
|
||||
local ctx = DSM_Context
|
||||
local txtColor = LCD_NORMAL_COLOR
|
||||
-- Gray Out any other line except the one been edited
|
||||
if (ctx.isEditing() and ctx.EditLine~=lineNum) then txtColor=LCD_DISABLE_COLOR end
|
||||
return txtColor
|
||||
end
|
||||
|
||||
local function GUI_GetFrameColor(lineNum) -- Frame Color for Value/Menu Boxes
|
||||
local ctx = DSM_Context
|
||||
local txtColor = LCD_BOX_COLOR
|
||||
-- Gray Out any other line except the one been edited
|
||||
if (ctx.EditLine~=lineNum) then txtColor=LCD_DISABLE_COLOR end
|
||||
return txtColor
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------------------------------
|
||||
-- Display Text inside a Rectangle. Inv: true means solid rectangle, false=only perimeter
|
||||
local function GUI_Display_Boxed_Text(lineNum,x,y,w,h,text,inv, isNumber)
|
||||
local ctx = DSM_Context
|
||||
local txtColor = GUI_GetTextColor(lineNum)
|
||||
local frameColor = GUI_GetFrameColor(lineNum)
|
||||
-- If editing this lineNum, chose EDIT Color, else SELECTED Color
|
||||
local selectedBGColor = (ctx.EditLine==lineNum and LCD_EDIT_BGCOLOR) or LCD_SELECTED_BGCOLOR
|
||||
|
||||
if (inv) then
|
||||
txtColor = LCD_SELECTED_COLOR
|
||||
lcd.drawFilledRectangle(x-5, y-2, w, h, selectedBGColor)
|
||||
else
|
||||
lcd.drawRectangle(x-5, y-2, w, h, frameColor)
|
||||
end
|
||||
if (isNumber) then
|
||||
lcd.drawNumber(x+w-10 , y, text, txtColor + RIGHT)
|
||||
else
|
||||
lcd.drawText(x , y, text, txtColor)
|
||||
end
|
||||
end
|
||||
|
||||
------ Display Pre/Next/Back buttons
|
||||
local function GUI_Diplay_Button(x,y,w,h,text,selected)
|
||||
GUI_Display_Boxed_Text(-1,x,y,w,h,text,selected, false)
|
||||
end
|
||||
|
||||
------ Display MENU type of lines (Navigation, SubHeaders, and plain text comments)
|
||||
local function GUI_Display_Line_Menu(lineNum,line,selected)
|
||||
-- Menu Lines can be navidation to other Menus (if Selectable)
|
||||
-- Or SubHeaders or Messages
|
||||
|
||||
local txtColor = GUI_GetTextColor(lineNum)
|
||||
local y = LCD_Y_LINE_START+(LCD_Y_LINE_HEIGHT*lineNum)
|
||||
local x = LCD_X_LINE_MENU
|
||||
|
||||
if menuLib.isSelectableLine(line) then -- Draw Selectable Menus in Boxes
|
||||
GUI_Display_Boxed_Text(lineNum,x, y, LCD_W_LINE_MENU, LCD_Y_LINE_HEIGHT, line.Text,selected, false)
|
||||
GUI_addTouchButton(x, y, LCD_W_LINE_MENU, LCD_Y_LINE_HEIGHT,lineNum)
|
||||
else
|
||||
-- Non Selectable Menu Lines, plain text
|
||||
-- Can be use for sub headers or just regular text lines (like warnings)
|
||||
|
||||
local bold = (menuLib.isDisplayAttr(line.TextAttr,DISP_ATTR._BOLD) and BOLD) or 0
|
||||
|
||||
if menuLib.isDisplayAttr(line.TextAttr,DISP_ATTR._RIGHT) then -- Right Align???
|
||||
local tw = my_lcd_sizeText(line.Text)+4
|
||||
x = LCD_X_LINE_VALUE - tw -- Right
|
||||
elseif menuLib.isDisplayAttr(line.TextAttr,DISP_ATTR._CENTER) then -- Center??
|
||||
local tw = my_lcd_sizeText(line.Text)
|
||||
x = x + (LCD_X_LINE_VALUE - LCD_X_LINE_MENU)/2 - tw/2 -- Center - 1/2 Text
|
||||
end
|
||||
|
||||
lcd.drawText(x, y, line.Text, txtColor + bold)
|
||||
end
|
||||
end
|
||||
|
||||
------ Display NAME : VALUES type of lines
|
||||
local function GUI_Display_Line_Value(lineNum, line, value, selected, editing)
|
||||
-- This Displays Name and Value Pairs
|
||||
local txtColor = GUI_GetTextColor(lineNum)
|
||||
local bold = 0
|
||||
local y = LCD_Y_LINE_START+(LCD_Y_LINE_HEIGHT*lineNum)
|
||||
local x = LCD_X_LINE_TITLE
|
||||
|
||||
---------- NAME Part
|
||||
local header = line.Text
|
||||
-- ONLY do this for Flight Mode (Right Align or Centered)
|
||||
if (menuLib.isFlightModeLine(line)) then
|
||||
-- Display Header + Value together
|
||||
header = menuLib.GetFlightModeValue(line)
|
||||
|
||||
-- Bold Text???
|
||||
bold = (menuLib.isDisplayAttr(line.TextAttr,DISP_ATTR._BOLD) and BOLD) or 0
|
||||
|
||||
if menuLib.isDisplayAttr(line.TextAttr,DISP_ATTR._RIGHT) then -- Right Align
|
||||
local tw = my_lcd_sizeText(header)+4
|
||||
x = LCD_X_LINE_VALUE - tw -- Right
|
||||
elseif menuLib.isDisplayAttr(line.TextAttr,DISP_ATTR._CENTER) then -- Centered
|
||||
local tw = my_lcd_sizeText(header)
|
||||
x = x + (LCD_X_LINE_VALUE - LCD_X_LINE_TITLE)/2 - tw/2 -- Center - 1/2 Text
|
||||
end
|
||||
else
|
||||
-- No Flight Mode, no effects here
|
||||
header = header .. ":"
|
||||
end
|
||||
|
||||
lcd.drawText(x, y, header, txtColor + bold) -- display Line Header
|
||||
|
||||
|
||||
--------- VALUE PART, Skip for Flight Mode since already show the value
|
||||
if (value==nil) then return end
|
||||
|
||||
if not menuLib.isFlightModeLine(line) then
|
||||
if menuLib.isSelectableLine(line) then
|
||||
--if (editing) then -- Any Special color/effect when editing??
|
||||
-- value = "["..value .. "]"
|
||||
--end
|
||||
-- Can select/edit value, Box it
|
||||
local tw = math.max(my_lcd_sizeText(value)+10,45) -- Width of the Text in the lcd
|
||||
GUI_Display_Boxed_Text(lineNum,LCD_X_LINE_VALUE,y,tw,LCD_Y_LINE_HEIGHT,value,selected, not menuLib.isListLine(line))
|
||||
GUI_addTouchButton(LCD_X_LINE_VALUE,y,tw,LCD_Y_LINE_HEIGHT,lineNum)
|
||||
|
||||
lcd.drawText(LCD_X_LINE_VALUE+tw+5, y, (line.Format or ""), txtColor + bold)
|
||||
else -- Not Editable, Plain Text
|
||||
lcd.drawText(LCD_X_LINE_VALUE, y, value, txtColor)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local function GUI_Display_Menu(menu)
|
||||
local ctx = DSM_Context
|
||||
local w= LCD_W_MENU_TITLE
|
||||
|
||||
-- Center Header
|
||||
local tw = my_lcd_sizeText(menu.Text)
|
||||
local x = w/2 - tw/2 -- Center of Screen - Center of Text
|
||||
|
||||
lcd.drawFilledRectangle(0, LCD_Y_MENU_TITLE-2, w, LCD_Y_LINE_HEIGHT-2, LCD_MENU_BGCOLOR)
|
||||
lcd.drawText(x,LCD_Y_MENU_TITLE,menu.Text, LCD_MENU_COLOR + BOLD)
|
||||
|
||||
-- Back Button
|
||||
if menu.BackId ~= 0 then
|
||||
GUI_Diplay_Button(437-5,LCD_Y_MENU_TITLE+3,47,LCD_Y_LINE_HEIGHT,"Back",ctx.SelLine == menuLib.BACK_BUTTON)
|
||||
GUI_addTouchButton(437-5,LCD_Y_MENU_TITLE+3,47,LCD_Y_LINE_HEIGHT,menuLib.BACK_BUTTON)
|
||||
end
|
||||
-- Next Button
|
||||
if menu.NextId ~= 0 then
|
||||
GUI_Diplay_Button(437-5,LCD_Y_LOWER_BUTTONS,47,LCD_Y_LINE_HEIGHT,"Next",ctx.SelLine == menuLib.NEXT_BUTTON)
|
||||
GUI_addTouchButton(437-5,LCD_Y_LOWER_BUTTONS,47,LCD_Y_LINE_HEIGHT,menuLib.NEXT_BUTTON)
|
||||
end
|
||||
-- Prev Button
|
||||
if menu.PrevId ~= 0 then
|
||||
GUI_Diplay_Button(10,LCD_Y_LOWER_BUTTONS,47,LCD_Y_LINE_HEIGHT,"Prev",ctx.SelLine == menuLib.PREV_BUTTON)
|
||||
GUI_addTouchButton(10,LCD_Y_LOWER_BUTTONS,47,LCD_Y_LINE_HEIGHT,menuLib.PREV_BUTTON)
|
||||
end
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
-- Display the EDIT mode buttons when editing a value
|
||||
|
||||
local function GUI_Display_Edit_Buttons(line)
|
||||
GUI_clearTouchButtons() -- Only this buttons can be touched
|
||||
local x = 15 -- Inittial X position
|
||||
local w = 55 -- Width of the buttons
|
||||
|
||||
local showPrev = line.Val > line.Min
|
||||
local showNext = line.Val < line.Max
|
||||
|
||||
GUI_Diplay_Button(x,LCD_Y_LOWER_BUTTONS,w,LCD_Y_LINE_HEIGHT,"ESC",true)
|
||||
GUI_addTouchButton(x,LCD_Y_LOWER_BUTTONS,w,LCD_Y_LINE_HEIGHT,EDIT_BUTTON.ESC)
|
||||
|
||||
x=x+w+10
|
||||
GUI_Diplay_Button(x,LCD_Y_LOWER_BUTTONS,w,LCD_Y_LINE_HEIGHT," Def",true)
|
||||
GUI_addTouchButton(x,LCD_Y_LOWER_BUTTONS,w,LCD_Y_LINE_HEIGHT,EDIT_BUTTON.DEFAULT)
|
||||
|
||||
x=x+w+10
|
||||
if (not menuLib.isListLine(line)) then
|
||||
GUI_Diplay_Button(x,LCD_Y_LOWER_BUTTONS,w,LCD_Y_LINE_HEIGHT," << ",showPrev)
|
||||
GUI_addTouchButton(x,LCD_Y_LOWER_BUTTONS,w,LCD_Y_LINE_HEIGHT,EDIT_BUTTON.DEC_10)
|
||||
end
|
||||
|
||||
x=x+w+10
|
||||
GUI_Diplay_Button(x,LCD_Y_LOWER_BUTTONS,w,LCD_Y_LINE_HEIGHT," <",showPrev)
|
||||
GUI_addTouchButton(x,LCD_Y_LOWER_BUTTONS,w,LCD_Y_LINE_HEIGHT,EDIT_BUTTON.DEC_1)
|
||||
|
||||
x=x+w+10
|
||||
GUI_Diplay_Button(x,LCD_Y_LOWER_BUTTONS,w,LCD_Y_LINE_HEIGHT," >",showNext)
|
||||
GUI_addTouchButton(x,LCD_Y_LOWER_BUTTONS,w,LCD_Y_LINE_HEIGHT,EDIT_BUTTON.INC_1)
|
||||
|
||||
x=x+w+10
|
||||
if (not menuLib.isListLine(line)) then
|
||||
GUI_Diplay_Button(x,LCD_Y_LOWER_BUTTONS,w,LCD_Y_LINE_HEIGHT," >>",showNext)
|
||||
GUI_addTouchButton(x,LCD_Y_LOWER_BUTTONS,w,LCD_Y_LINE_HEIGHT,EDIT_BUTTON.INC_10)
|
||||
end
|
||||
|
||||
x=x+w+10
|
||||
GUI_Diplay_Button(x,LCD_Y_LOWER_BUTTONS,w,LCD_Y_LINE_HEIGHT," OK",true)
|
||||
GUI_addTouchButton(x,LCD_Y_LOWER_BUTTONS,w,LCD_Y_LINE_HEIGHT,EDIT_BUTTON.OK)
|
||||
|
||||
end
|
||||
|
||||
local function GUI_ShowBitmap(x,y,imgData)
|
||||
-- imgData format "bitmap.png|alt message"
|
||||
local f = string.gmatch(imgData, '([^%|]+)') -- Iterator over values split by '|'
|
||||
local imgName, imgMsg = f(), f()
|
||||
|
||||
lcd.drawText(x, y, imgMsg or "") -- Alternate Image MSG
|
||||
|
||||
local imgPath = IMAGE_PATH .. (imgName or "")
|
||||
local bitmap = Bitmap.open(imgPath)
|
||||
if (bitmap~=nil) then
|
||||
lcd.drawBitmap(bitmap, x,y+20)
|
||||
end
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
local function GUI_Display()
|
||||
local ctx = DSM_Context
|
||||
lcd.clear(LCD_TOOL_BGCOLOR)
|
||||
GUI_clearTouchButtons()
|
||||
|
||||
if LCD_W ~= 480 then
|
||||
-- Different Resolution.. Maybe just adjusting some of the constants will work, adjust it in DSM_Init??
|
||||
-- LCD_X_LINE_TITLE, LCD_Y_LINE_START, etc
|
||||
lcd.drawText(LCD_X_LINE_TITLE,100,"Only supported in Color Radios of 480 resolution", BLINK)
|
||||
return
|
||||
end
|
||||
|
||||
local header = "DSM Forward Programming "..VERSION.." "
|
||||
if ctx.Phase ~= PHASE.RX_VERSION then
|
||||
header = header .. ctx.RX.Name.." v"..ctx.RX.Version
|
||||
end
|
||||
|
||||
--Draw title
|
||||
lcd.drawFilledRectangle(0, 0, LCD_W, 17, LCD_TOOL_HDR_BGCOLOR)
|
||||
lcd.drawText(5, 0, header, LCD_TOOL_HDR_COLOR + SMLSIZE)
|
||||
|
||||
-- Getting RX Version
|
||||
if ctx.Phase == PHASE.RX_VERSION then
|
||||
if (ctx.isReset) then
|
||||
lcd.drawText(LCD_X_LINE_TITLE,100, menuLib.Get_Text(0x301), BLINK) -- Resetting...
|
||||
else
|
||||
lcd.drawText(LCD_X_LINE_TITLE,100,menuLib.Get_Text(0x300), BLINK) -- Not valid RX
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
local menu = ctx.Menu
|
||||
if menu.Text == nil then return end
|
||||
|
||||
----- Draw RX Menu ---------
|
||||
GUI_Display_Menu(menu)
|
||||
|
||||
-- Sending TX Information???
|
||||
if (ctx.Phase==PHASE.MENU_REQ_TX_INFO) then
|
||||
--lcd.drawFilledRectangle(x-5, y-2, w, h, selectedBGColor)
|
||||
--lcd.drawRectangle(x-5, y-2, w, h, frameColor)
|
||||
lcd.drawText(LCD_X_LINE_TITLE,100, "Sending CH"..(ctx.CurLine+1)) -- Channel Info
|
||||
return
|
||||
end
|
||||
|
||||
for i = 0, menuLib.MAX_MENU_LINES do
|
||||
local line = ctx.MenuLines[i]
|
||||
|
||||
if line ~= nil and line.Type ~= 0 then
|
||||
if line.Type == LINE_TYPE.MENU then
|
||||
GUI_Display_Line_Menu(i, line, i == ctx.SelLine)
|
||||
else
|
||||
local value = nil
|
||||
if line.Val ~= nil then
|
||||
value = line.Val
|
||||
if menuLib.isListLine(line) then -- for Lists of Strings, get the text
|
||||
value = menuLib.Get_List_Text(line.Val + line.TextStart) -- TextStart is the initial offset for text
|
||||
-- Complentary IMAGE for this value to Display??
|
||||
local offset = 0
|
||||
if (line.Type==LINE_TYPE.LIST_MENU_ORI) then offset = offset + 0x100 end --FH6250 hack
|
||||
|
||||
local imgData = menuLib.Get_List_Text_Img(line.Val + line.TextStart + offset)
|
||||
|
||||
if (imgData and i == ctx.SelLine) then -- Optional Image and Msg for selected value
|
||||
GUI_ShowBitmap(LCD_X_LINE_TITLE,LCD_Y_LINE_START, imgData)
|
||||
end
|
||||
end
|
||||
end -- if Line[i]~=nil
|
||||
GUI_Display_Line_Value(i, line, value, i == ctx.SelLine, i == ctx.EditLine)
|
||||
end
|
||||
end -- if ~MENU
|
||||
end -- for
|
||||
|
||||
if IS_EDGETX and ctx.isEditing() then
|
||||
-- Display Touch button for Editing values
|
||||
GUI_Display_Edit_Buttons(ctx.MenuLines[ctx.EditLine])
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function GUI_RotEncVal(line, dir) -- return encoder speed to inc or dec values
|
||||
|
||||
if menuLib.isListLine(line) then return dir end
|
||||
|
||||
local inc = 0
|
||||
local Speed = getRotEncSpeed()
|
||||
|
||||
if Speed == ROTENC_MIDSPEED then inc = (5 * dir)
|
||||
elseif Speed == ROTENC_HIGHSPEED then inc = (15 * dir)
|
||||
else inc = dir end
|
||||
|
||||
return inc
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------------
|
||||
-- Translate Tap/Touch of EDIT buttons to equivalent Key events
|
||||
local function GUI_Translate_Edit_Buttons(button)
|
||||
local event = EVT_TOUCH_TAP
|
||||
local editInc = nil
|
||||
|
||||
if (button==EDIT_BUTTON.ESC) then -- ESC
|
||||
event = EVT_VIRTUAL_EXIT
|
||||
elseif (button==EDIT_BUTTON.DEFAULT) then -- Default
|
||||
event = EVT_VIRTUAL_ENTER_LONG
|
||||
elseif (button==EDIT_BUTTON.DEC_10) then -- -10
|
||||
event = EVT_VIRTUAL_PREV
|
||||
editInc = -10
|
||||
elseif (button==EDIT_BUTTON.DEC_1) then -- -1
|
||||
event = EVT_VIRTUAL_PREV
|
||||
editInc = -1
|
||||
elseif (button==EDIT_BUTTON.INC_1) then -- +1
|
||||
event = EVT_VIRTUAL_NEXT
|
||||
editInc = 1
|
||||
elseif (button==EDIT_BUTTON.INC_10) then -- + 10
|
||||
event = EVT_VIRTUAL_NEXT
|
||||
editInc = 10
|
||||
elseif (button==EDIT_BUTTON.OK) then -- OK
|
||||
event = EVT_VIRTUAL_ENTER
|
||||
else
|
||||
|
||||
end
|
||||
|
||||
return event, editInc
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
-- Handle Events comming from the GUI
|
||||
local function GUI_HandleEvent(event, touchState)
|
||||
local ctx = DSM_Context
|
||||
local menu = ctx.Menu
|
||||
local menuLines = ctx.MenuLines
|
||||
local editInc = nil
|
||||
|
||||
if (IS_EDGETX) then
|
||||
if (event == EVT_TOUCH_TAP and ctx.isEditing()) then -- Touch and Editing
|
||||
local button = GUI_getTouchButton(touchState.x, touchState.y)
|
||||
if (button) then
|
||||
event, editInc = GUI_Translate_Edit_Buttons(button)
|
||||
end
|
||||
end
|
||||
|
||||
if (event == EVT_TOUCH_TAP or event == EVT_TOUCH_FIRST) and not ctx.isEditing() then -- Touch and NOT editing
|
||||
if (DEBUG_ON) then Log.LOG_write("%s: EVT_TOUCH_TAP %d,%d\n",menuLib.phase2String(ctx.Phase),touchState.x, touchState.y) end
|
||||
local button = GUI_getTouchButton(touchState.x, touchState.y)
|
||||
if button then
|
||||
-- Found a valid line
|
||||
ctx.SelLine = button
|
||||
ctx.Refresh_Display=true
|
||||
if event == EVT_TOUCH_TAP then -- EVT_TOUCH_FIRST only move focus
|
||||
event = EVT_VIRTUAL_ENTER
|
||||
end
|
||||
end
|
||||
end
|
||||
end -- IS_EDGETX
|
||||
|
||||
if event == EVT_VIRTUAL_EXIT then
|
||||
ctx.Refresh_Display=true
|
||||
if (DEBUG_ON) then Log.LOG_write("%s: EVT_VIRTUAL_EXIT\n",menuLib.phase2String(ctx.Phase)) end
|
||||
if ctx.Phase == PHASE.RX_VERSION then
|
||||
menuLib.ChangePhase(PHASE.EXIT_DONE) -- Just Exit the Script
|
||||
else
|
||||
if ctx.isEditing() then -- Editing a Line, need to restore original value
|
||||
local line = ctx.MenuLines[ctx.EditLine]
|
||||
line.Val = originalValue
|
||||
menuLib.Value_Write_Validate(line)
|
||||
elseif (menu.BackId > 0 ) then -- Back??
|
||||
ctx.SelLine = menuLib.BACK_BUTTON
|
||||
event = EVT_VIRTUAL_ENTER
|
||||
else
|
||||
menuLib.ChangePhase(PHASE.EXIT)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if ctx.Phase == PHASE.RX_VERSION then return end
|
||||
|
||||
if event == EVT_VIRTUAL_NEXT then
|
||||
ctx.Refresh_Display=true
|
||||
if (DEBUG_ON) then Log.LOG_write("%s: EVT_VIRTUAL_NEXT\n",menuLib.phase2String(ctx.Phase)) end
|
||||
if ctx.isEditing() then -- Editing a Line, need to inc the value
|
||||
local line=ctx.MenuLines[ctx.EditLine]
|
||||
menuLib.Value_Add(line, editInc or GUI_RotEncVal(line, 1))
|
||||
else -- not editing, move selected line to NEXT
|
||||
menuLib.MoveSelectionLine(1)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if event == EVT_VIRTUAL_PREV then
|
||||
ctx.Refresh_Display=true
|
||||
if (DEBUG_ON) then Log.LOG_write("%s: EVT_VIRTUAL_PREV\n",menuLib.phase2String(ctx.Phase)) end
|
||||
if ctx.isEditing() then -- Editiing a line, need to dec the value
|
||||
local line=ctx.MenuLines[ctx.EditLine]
|
||||
menuLib.Value_Add(line, editInc or GUI_RotEncVal(line, -1))
|
||||
else -- not editing, move selected line to PREV
|
||||
menuLib.MoveSelectionLine(-1)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if event == EVT_VIRTUAL_ENTER_LONG then
|
||||
ctx.Refresh_Display=true
|
||||
if (DEBUG_ON) then Log.LOG_write("%s: EVT_VIRTUAL_ENTER_LONG\n",menuLib.phase2String(ctx.Phase)) end
|
||||
if ctx.isEditing() then
|
||||
-- reset the value to default
|
||||
menuLib.Value_Default(menuLines[ctx.EditLine]) -- Update value in RX if needed
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if event == EVT_VIRTUAL_ENTER then
|
||||
ctx.Refresh_Display=true
|
||||
if (DEBUG_ON) then Log.LOG_write("%s: EVT_VIRTUAL_ENTER, SelLine=%d\n",menuLib.phase2String(ctx.Phase), ctx.SelLine) end
|
||||
if ctx.SelLine == menuLib.BACK_BUTTON then -- Back
|
||||
if (menu.BackId==0xFFF9) then
|
||||
-- SPECIAL Main Menu
|
||||
GUI_SwitchToMainMenu()
|
||||
else
|
||||
menuLib.GotoMenu(menu.BackId,0x80)
|
||||
end
|
||||
elseif ctx.SelLine == menuLib.NEXT_BUTTON then -- Next
|
||||
menuLib.GotoMenu(menu.NextId,0x82)
|
||||
elseif ctx.SelLine == menuLib.PREV_BUTTON then -- Prev
|
||||
menuLib.GotoMenu(menu.PrevId,0x81)
|
||||
elseif menuLines[ctx.SelLine].ValId ~= 0 then -- Menu or Value
|
||||
|
||||
if menuLines[ctx.SelLine].Type == LINE_TYPE.MENU then -- Navigate to Menu
|
||||
if (menuLines[ctx.SelLine].ValId==0xFFF1) then
|
||||
-- SPECIAL Simulation menu to Simulator
|
||||
GUI_SwitchToSIM()
|
||||
elseif (menuLines[ctx.SelLine].ValId==0xFFF2) then
|
||||
-- SPECIAL Simulation menu to go to RX
|
||||
GUI_SwitchToRX()
|
||||
elseif (menuLines[ctx.SelLine].ValId==0xFFF3) then
|
||||
-- SPECIAL Settup Menu
|
||||
GUI_SwitchToSetupMenu()
|
||||
elseif (menuLines[ctx.SelLine].ValId==0xFFF9) then
|
||||
-- SPECIAL Settup Menu
|
||||
GUI_SwitchToMainMenu()
|
||||
else
|
||||
menuLib.GotoMenu(menuLines[ctx.SelLine].ValId, ctx.SelLine) -- ValId is the MenuId to navigate to
|
||||
end
|
||||
else -- Enter on a Value
|
||||
if ctx.isEditing() then -- already editing a Line????
|
||||
menuLib.Value_Write_Validate(menuLines[ctx.SelLine])
|
||||
else -- Edit the current value
|
||||
ctx.EditLine = ctx.SelLine
|
||||
originalValue = menuLines[ctx.SelLine].Val
|
||||
menuLib.ChangePhase(PHASE.VALUE_CHANGING_WAIT)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function init_colors()
|
||||
-- osName in OpenTX is nil, otherwise is EDGETX
|
||||
local ver, radio, maj, minor, rev, osname = getVersion()
|
||||
if (osname==nil) then osname = "OpenTX" end -- OTX 2.3.14 and below returns nil
|
||||
|
||||
IS_EDGETX = string.sub(osname,1,1) == 'E'
|
||||
|
||||
if (IS_EDGETX and USE_SPECKTRUM_COLORS) then
|
||||
-- SPECKTRUM COLORS (only works on EDGETX)
|
||||
LCD_TOOL_BGCOLOR = LIGHTWHITE
|
||||
-- TOOL HEADER
|
||||
LCD_TOOL_HDR_COLOR = WHITE
|
||||
LCD_TOOL_HDR_BGCOLOR = DARKBLUE
|
||||
-- MENU HEADER
|
||||
LCD_MENU_COLOR = WHITE
|
||||
LCD_MENU_BGCOLOR = DARKGREY
|
||||
-- LINE SELECTED
|
||||
LCD_SELECTED_COLOR = WHITE
|
||||
LCD_SELECTED_BGCOLOR = ORANGE
|
||||
LCD_EDIT_BGCOLOR = RED
|
||||
-- NORMAL TEXT
|
||||
LCD_NORMAL_COLOR = BLACK
|
||||
LCD_DISABLE_COLOR = LIGHTGREY
|
||||
LCD_DEBUG_COLOR = BLUE
|
||||
-- NORMAL BOX FRAME COLOR
|
||||
LCD_BOX_COLOR = LIGHTGREY
|
||||
end
|
||||
end
|
||||
|
||||
local function GUI_Warning(event,touchState)
|
||||
lcd.clear(LCD_TOOL_BGCOLOR)
|
||||
local header = "DSM Forward Programming "..VERSION.." "
|
||||
--Draw title
|
||||
lcd.drawFilledRectangle(0, 0, LCD_W, 17, LCD_TOOL_HDR_BGCOLOR)
|
||||
lcd.drawText(5, 0, header, LCD_TOOL_HDR_COLOR + SMLSIZE)
|
||||
|
||||
lcd.drawText(100,20,"INFO", BOLD)
|
||||
lcd.drawText(5,40,"DSM Forward programing shares TX Servo/Output settings", 0)
|
||||
lcd.drawText(5,60,"with the RX. Make sure you setup your plane first in ", 0)
|
||||
lcd.drawText(5,80,"the TX before your start Fwrd programming your RX.", 0)
|
||||
lcd.drawText(5,100,"Wing & Tail type can be configured using this tool.", 0)
|
||||
|
||||
lcd.drawText(5,150,"TX Gyro Servo settings are sent to the RX during 'Initial Setup'", 0)
|
||||
lcd.drawText(5,170,"as well as when using RX 'Relearn Servo Settings'", 0)
|
||||
lcd.drawText(5,200,"ALWAYS TEST Gyro reactions after this conditions before flying.", BOLD)
|
||||
|
||||
lcd.drawText(100,250," OK ", INVERS + BOLD)
|
||||
|
||||
if event == EVT_VIRTUAL_EXIT or event == EVT_VIRTUAL_ENTER or event == EVT_TOUCH_TAP then
|
||||
warningScreenON = false
|
||||
end
|
||||
|
||||
return 0
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
-- Init
|
||||
local function DSM_Init()
|
||||
Log.LOG_open()
|
||||
|
||||
init_colors()
|
||||
modelLib.ReadTxModelData()
|
||||
modelLib.ST_LoadFileData()
|
||||
modelLib.CreateDSMPortChannelInfo()
|
||||
|
||||
menuLib.Init()
|
||||
menuProcessor.init()
|
||||
return 0
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
-- Main
|
||||
local function DSM_Run(event,touchState)
|
||||
local ctx = DSM_Context
|
||||
|
||||
if event == nil then
|
||||
error("Cannot be run as a model script!")
|
||||
Log.LOG_close()
|
||||
return 2
|
||||
end
|
||||
|
||||
if (warningScreenON) then
|
||||
return GUI_Warning(event,touchState)
|
||||
end
|
||||
|
||||
GUI_HandleEvent(event,touchState)
|
||||
|
||||
local ret = menuProcessor.run() -- Handle Send and Receive DSM Forward Programming Messages
|
||||
|
||||
if ctx.Phase == PHASE.INIT then return 0 end
|
||||
|
||||
|
||||
local refreshInterval = REFRESH_GUI_MS
|
||||
|
||||
-- When using LCD BLINK attribute, we need faster refresh for BLINK to SHOW on LCD
|
||||
if (ctx.Phase == PHASE.RX_VERSION or ctx.Phase==PHASE.MENU_REQ_TX_INFO) then -- Requesting RX Message Version usea BLINK?
|
||||
ctx.Refresh_Display=true
|
||||
refreshInterval = 20 -- 200ms
|
||||
end
|
||||
|
||||
if (not IS_EDGETX) then -- OPENTX NEEDS REFRESH ON EVERY CYCLE
|
||||
GUI_Display()
|
||||
-- Refresh display only if needed and no faster than 300ms, utilize more CPU to speedup DSM communications
|
||||
elseif (ctx.Refresh_Display and (getTime()-lastRefresh) > refreshInterval) then --300ms from last refresh
|
||||
GUI_Display()
|
||||
ctx.Refresh_Display=false
|
||||
lastRefresh=getTime()
|
||||
end
|
||||
|
||||
if ctx.Phase == PHASE.EXIT_DONE then
|
||||
Log.LOG_close()
|
||||
return 2
|
||||
else
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
return { init=DSM_Init, run=DSM_Run }
|
||||
1088
SCRIPTS/TOOLS/DSM FwdPrg_56_MIN.lua
Normal file
951
SCRIPTS/TOOLS/DSM FwdPrg_56_STUP.lua
Normal file
|
|
@ -0,0 +1,951 @@
|
|||
local toolName = "TNS|DSM Frwd Prog v0.56a (MIN-SETUP)|TNE"
|
||||
|
||||
---- #########################################################################
|
||||
---- # #
|
||||
---- # Copyright (C) OpenTX #
|
||||
-----# #
|
||||
---- # 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. #
|
||||
---- # #
|
||||
---- #########################################################################
|
||||
|
||||
|
||||
local VERSION = "v0.56"
|
||||
local DSMLIB_PATH = "/SCRIPTS/TOOLS/DSMLIB/"
|
||||
local DATA_PATH = "/MODELS/DSMDATA"
|
||||
|
||||
local LOG_FILE = "/LOGS/dsm_min_log.txt"
|
||||
|
||||
-- Phase
|
||||
local PH_INIT = 0
|
||||
local PH_RX_VER, PH_TITLE = 1, 2
|
||||
local PH_VAL_CHANGING, PH_VAL_EDITING, PH_VAL_EDIT_END = 6, 7, 8
|
||||
local PH_WAIT_CMD, PH_EXIT_REQ, PH_EXIT_DONE = 9, 10, 11
|
||||
|
||||
-- Line Types
|
||||
local LT_MENU, LT_LIST_NC = 0x1C, 0x6C
|
||||
|
||||
local Phase = PH_INIT
|
||||
|
||||
local Text = {}
|
||||
local List_Text = {}
|
||||
local List_Text_Img = {}
|
||||
|
||||
local originalValue = 0
|
||||
|
||||
local ctx_SelLine = 0 -- Current Selected Line
|
||||
local ctx_EditLine = nil -- Current Editing Line
|
||||
|
||||
local Menu = { MenuId = 0, Text = "", TextId = 0, PrevId = 0, NextId = 0, BackId = 0 }
|
||||
local MenuLines = {}
|
||||
|
||||
local logFile = nil
|
||||
|
||||
local LCD_W_BUTTONS = 19
|
||||
local LCD_H_BUTTONS = 10
|
||||
|
||||
local LCD_X_MAX = 128
|
||||
local LCD_X_RIGHT_BUTTONS = LCD_X_MAX - LCD_W_BUTTONS - 1
|
||||
|
||||
local LCD_Y_LINE_HEIGHT = 7
|
||||
local LCD_Y_LOWER_BUTTONS = (8 * LCD_Y_LINE_HEIGHT) + 2
|
||||
|
||||
local TEXT_ATTR = SMLSIZE
|
||||
|
||||
local TX_CHANNELS = 12
|
||||
|
||||
local AT_PLANE = 0
|
||||
|
||||
local aircraft_type_text = {[0]="Plane","Heli","Glider","Drone"}
|
||||
|
||||
local WT_A1 = 0
|
||||
local WT_A2 = 1
|
||||
local WT_FLPR = 2
|
||||
local WT_A1_F1 = 3
|
||||
local WT_A2_F1 = 4
|
||||
local WT_A2_F2 = 5
|
||||
local WT_ELEVON_A = 6
|
||||
local WT_ELEVON_B = 7
|
||||
|
||||
local wing_type_text = {[0]="Normal","Dual Ail","Flapperon", "Ail + Flp","Dual Ail + Flp","Dual Ail/Flp","Elevon A","Elevon B"}
|
||||
|
||||
local TT_R1 = 0
|
||||
local TT_R1_E1 = 1
|
||||
local TT_R1_E2 = 2
|
||||
local TT_R2_E1 = 3
|
||||
local TT_R2_E2 = 4
|
||||
local TT_VT_A = 5
|
||||
local TT_VT_B = 6
|
||||
local TT_TLRN_A = 7
|
||||
local TT_TLRN_B = 8
|
||||
local TT_TLRN_A_R2 = 9
|
||||
local TT_TLRN_B_R2 = 10
|
||||
|
||||
local tail_type_text = {[0]="Rud Only","Normal","Rud + Dual Ele","Dual Rud + Elv","Dual Rud/Ele",
|
||||
"VTail A","VTail B","Taileron A","Taileron B",
|
||||
"Taileron A + Dual Rud","Taileron B + Dual Rud"
|
||||
}
|
||||
|
||||
local MT_NORMAL = 0
|
||||
local MT_REVERSE = 1
|
||||
|
||||
local P1 = 0
|
||||
local P2 = 1
|
||||
local P3 = 2
|
||||
local P4 = 3
|
||||
local P5 = 4
|
||||
local P6 = 5
|
||||
local P7 = 6
|
||||
local P8 = 7
|
||||
--local P9 = 8
|
||||
--local P10 = 9
|
||||
|
||||
local MV_AIRCRAFT_TYPE = 1001
|
||||
local MV_WING_TYPE = 1002
|
||||
local MV_TAIL_TYPE = 1003
|
||||
|
||||
local MV_CH_BASE = 1010
|
||||
local MV_CH_THR = 1010
|
||||
|
||||
local MV_CH_L_AIL = 1011
|
||||
local MV_CH_R_AIL = 1012
|
||||
local MV_CH_L_FLP = 1013
|
||||
local MV_CH_R_FLP = 1014
|
||||
|
||||
local MV_CH_L_RUD = 1015
|
||||
local MV_CH_R_RUD = 1016
|
||||
local MV_CH_L_ELE = 1017
|
||||
local MV_CH_R_ELE = 1018
|
||||
|
||||
local MV_PORT_BASE = 1020
|
||||
local MV_P1_MODE = 1020
|
||||
--local MV_P2_MODE = 1021
|
||||
--local MV_P3_MODE = 1022
|
||||
--local MV_P4_MODE = 1023
|
||||
--local MV_P5_MODE = 1024
|
||||
local MV_P6_MODE = 1025
|
||||
--local MV_P7_MODE = 1026
|
||||
--local MV_P8_MODE = 1027
|
||||
--local MV_P9_MODE = 1028
|
||||
--local MV_P10_MODE = 1029
|
||||
|
||||
local MV_DATA_END = 1040
|
||||
|
||||
-- MENU DATA Management
|
||||
local M_DB = {} -- Store the variables used in the Menus.
|
||||
|
||||
local lastGoodMenu=0
|
||||
|
||||
local currATyp = -1
|
||||
local currTTyp = -1
|
||||
local currWTyp = -1
|
||||
|
||||
local menuDataChanged = false
|
||||
|
||||
local MODEL = {
|
||||
modelName = "", -- The name of the model comming from OTX/ETX
|
||||
hashName = nil,
|
||||
modelOutputChannel = {}, -- Output information from OTX/ETX
|
||||
|
||||
TX_CH_TEXT= { },
|
||||
PORT_TEXT = { },
|
||||
|
||||
DSM_ChannelInfo = {} -- Data Created by DSM Configuration Script
|
||||
}
|
||||
|
||||
local function gc()
|
||||
collectgarbage("collect")
|
||||
end
|
||||
|
||||
--[[
|
||||
local function gcTable(t)
|
||||
if type(t)=="table" then
|
||||
for i,v in pairs(t) do
|
||||
if type(v) == "table" then
|
||||
gcTable(v)
|
||||
end
|
||||
t[i] = nil
|
||||
end
|
||||
end
|
||||
gc()
|
||||
return t
|
||||
end
|
||||
--]]
|
||||
|
||||
local function LOG_open()
|
||||
logFile = io.open(LOG_FILE, "w") -- Truncate Log File
|
||||
end
|
||||
|
||||
local function LOG_write(...)
|
||||
if (logFile == nil) then LOG_open() end
|
||||
local str = string.format(...)
|
||||
io.write(logFile, str)
|
||||
end
|
||||
|
||||
local function LOG_close()
|
||||
if (logFile ~= nil) then io.close(logFile) end
|
||||
end
|
||||
|
||||
-- Saves MENU_DATA to a file
|
||||
local function ST_SaveFileData()
|
||||
local fname = MODEL.hashName
|
||||
|
||||
print("Saving File:"..fname)
|
||||
local dataFile = assert(io.open(DATA_PATH .. "/" .. fname, "w"),"Please create "..DATA_PATH.." folder") -- write File
|
||||
|
||||
-- Foreach MENU_DATA with a value write Var_Id:Value into file
|
||||
for i = 0, MV_DATA_END do
|
||||
if (M_DB[i]~=nil) then
|
||||
io.write(dataFile,string.format("%s:%s\n",i,M_DB[i]))
|
||||
end
|
||||
end
|
||||
io.close(dataFile)
|
||||
end
|
||||
|
||||
local function tailTypeCompatible(a,b)
|
||||
|
||||
local function normalize(tt)
|
||||
if (tt==TT_TLRN_A or tt==TT_TLRN_B) then
|
||||
return TT_TLRN_A
|
||||
elseif (tt==TT_TLRN_A_R2 or tt==TT_TLRN_B_R2) then
|
||||
return TT_TLRN_A_R2
|
||||
elseif (tt==TT_VT_A or tt==TT_VT_B) then
|
||||
return TT_VT_A
|
||||
else
|
||||
return tt
|
||||
end
|
||||
end
|
||||
|
||||
return (normalize(a)==normalize(b))
|
||||
end
|
||||
|
||||
local function ST_PlaneWingInit(wingType)
|
||||
--print("Change Plane WingType:"..wing_type_text[wingType])
|
||||
|
||||
M_DB[MV_WING_TYPE] = wingType
|
||||
|
||||
-- Clear all Wing Data
|
||||
M_DB[MV_CH_L_AIL] = nil
|
||||
M_DB[MV_CH_R_AIL] = nil
|
||||
M_DB[MV_CH_L_FLP] = nil
|
||||
M_DB[MV_CH_R_FLP] = nil
|
||||
|
||||
M_DB[MV_CH_THR] = P1
|
||||
|
||||
-- Default Channel Assisgments for each Wing type
|
||||
|
||||
if (wingType==WT_A1) then
|
||||
M_DB[MV_CH_L_AIL] = P2
|
||||
elseif (wingType==WT_A2 or wingType==WT_FLPR) then
|
||||
M_DB[MV_CH_L_AIL] = P6
|
||||
M_DB[MV_CH_R_AIL] = P2
|
||||
elseif (wingType==WT_A1_F1) then
|
||||
M_DB[MV_CH_L_AIL] = P2
|
||||
M_DB[MV_CH_L_FLP] = P6
|
||||
elseif (wingType==WT_A2_F1) then
|
||||
M_DB[MV_CH_L_AIL] = P6
|
||||
M_DB[MV_CH_R_AIL] = P2
|
||||
M_DB[MV_CH_L_FLP] = P5
|
||||
elseif (wingType==WT_A2_F2) then
|
||||
M_DB[MV_CH_L_AIL] = P6
|
||||
M_DB[MV_CH_R_AIL] = P2
|
||||
M_DB[MV_CH_R_FLP] = P5
|
||||
M_DB[MV_CH_L_FLP] = P7
|
||||
elseif (wingType==WT_ELEVON_A) then
|
||||
M_DB[MV_CH_L_AIL] = P2
|
||||
M_DB[MV_CH_R_AIL] = P3
|
||||
elseif (wingType==WT_ELEVON_B) then
|
||||
M_DB[MV_CH_L_AIL] = P3
|
||||
M_DB[MV_CH_R_AIL] = P2
|
||||
else -- Assume normal
|
||||
print("ERROR: Invalid Wing Type")
|
||||
end
|
||||
end
|
||||
|
||||
local function ST_PlaneTailInit(tailType)
|
||||
if (M_DB[MV_WING_TYPE]==WT_ELEVON_A or
|
||||
M_DB[MV_WING_TYPE]==WT_ELEVON_B) then
|
||||
tailType = TT_R1 -- Delta only have ruder
|
||||
end
|
||||
|
||||
--print("Change Plane Tail Type:"..tail_type_text[tailType])
|
||||
|
||||
-- Clear all data for Tail
|
||||
M_DB[MV_TAIL_TYPE] = tailType
|
||||
M_DB[MV_CH_L_ELE] = nil
|
||||
M_DB[MV_CH_R_ELE] = nil
|
||||
M_DB[MV_CH_L_RUD] = nil
|
||||
M_DB[MV_CH_R_RUD] = nil
|
||||
|
||||
-- Setup Channels for different Tail types
|
||||
if (tailType == TT_R1) then
|
||||
M_DB[MV_CH_L_RUD] = P4
|
||||
elseif (tailType == TT_R1_E1) then
|
||||
M_DB[MV_CH_L_ELE] = P3
|
||||
M_DB[MV_CH_L_RUD] = P4
|
||||
elseif (tailType == TT_R1_E2) then
|
||||
M_DB[MV_CH_L_ELE] = P5
|
||||
M_DB[MV_CH_R_ELE] = P3
|
||||
M_DB[MV_CH_L_RUD] = P4
|
||||
elseif (tailType == TT_R2_E1) then
|
||||
M_DB[MV_CH_L_ELE] = P3
|
||||
M_DB[MV_CH_L_RUD] = P4
|
||||
M_DB[MV_CH_R_RUD] = P5
|
||||
elseif (tailType == TT_R2_E2) then
|
||||
M_DB[MV_CH_L_ELE] = P5
|
||||
M_DB[MV_CH_R_ELE] = P3
|
||||
M_DB[MV_CH_L_RUD] = P4
|
||||
M_DB[MV_CH_R_RUD] = P6
|
||||
elseif (tailType == TT_VT_A or tailType == TT_VT_B) then
|
||||
M_DB[MV_CH_L_ELE] = P3
|
||||
M_DB[MV_CH_R_ELE] = P4
|
||||
elseif (tailType == TT_TLRN_A or tailType == TT_TLRN_B or
|
||||
tailType == TT_TLRN_A_R2 or tailType == TT_TLRN_B_R2) then
|
||||
M_DB[MV_CH_L_RUD] = P4
|
||||
M_DB[MV_CH_L_ELE] = P5
|
||||
M_DB[MV_CH_R_ELE] = P3
|
||||
else -- Assume Normal
|
||||
print("ERROR:invalid Tail Type")
|
||||
end
|
||||
|
||||
if (tailType == TT_TLRN_A_R2 or tailType == TT_TLRN_B_R2) then
|
||||
M_DB[MV_CH_R_RUD] = P8
|
||||
end
|
||||
end
|
||||
|
||||
local function ST_AircraftInit(aircraftType)
|
||||
M_DB[MV_AIRCRAFT_TYPE] = aircraftType
|
||||
ST_PlaneWingInit(WT_A1)
|
||||
ST_PlaneTailInit(TT_R1_E1)
|
||||
end
|
||||
|
||||
|
||||
-- Setup Initial Default Data for the Menus
|
||||
local function ST_Default_Data()
|
||||
ST_AircraftInit(AT_PLANE)
|
||||
|
||||
for i=0,9 do
|
||||
M_DB[MV_P1_MODE+i] = MT_NORMAL + MODEL.modelOutputChannel[P1+i].revert
|
||||
end
|
||||
end
|
||||
|
||||
local function MenuLinePostProcessing(line)
|
||||
line.MenuId = Menu.MenuId
|
||||
|
||||
if line.Type == LT_MENU then
|
||||
-- nothing to do on menu entries
|
||||
line.Val=nil
|
||||
elseif line.Type == LT_LIST_NC then
|
||||
-- Normalize Min/Max to be relative to Zero
|
||||
line.TextStart = line.Min
|
||||
line.Def = line.Def - line.Min -- normalize default value
|
||||
line.Max = line.Max - line.Min -- normalize max index
|
||||
line.Min = 0 -- min index
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function portUse(p)
|
||||
local out = nil
|
||||
if p==M_DB[MV_CH_THR] then out = "Thr"
|
||||
elseif p == M_DB[MV_CH_L_AIL] then
|
||||
out=(M_DB[MV_CH_R_AIL] and "Ail_L") or "Ail"
|
||||
elseif p == M_DB[MV_CH_R_AIL] then out="Ail_R"
|
||||
elseif p == M_DB[MV_CH_L_ELE] then
|
||||
out=(M_DB[MV_CH_R_ELE] and "Ele_L") or "Ele"
|
||||
elseif p == M_DB[MV_CH_R_ELE] then out="Ele_R"
|
||||
elseif p == M_DB[MV_CH_L_RUD] then
|
||||
out=(M_DB[MV_CH_R_RUD] and "Rud_L") or "Rud"
|
||||
elseif p == M_DB[MV_CH_R_RUD] then out="Rud-R"
|
||||
elseif p == M_DB[MV_CH_L_FLP] then
|
||||
out=(M_DB[MV_CH_R_FLP] and "Flp_L") or "Flp"
|
||||
elseif p == M_DB[MV_CH_R_FLP] then out="Flp_R"
|
||||
else
|
||||
out = ""
|
||||
end
|
||||
return out
|
||||
end
|
||||
|
||||
-- Creates the menus to Render with the GUI
|
||||
local function ST_LoadMenu(menuId)
|
||||
|
||||
local function Header(p)
|
||||
return MODEL.PORT_TEXT[p].." "..portUse(p)
|
||||
end
|
||||
|
||||
local function generateGyroReverse(menuId, P_BASE, V_BASE)
|
||||
for i=0,4 do
|
||||
MenuLines[i] = { Type = LT_LIST_NC, Text=Header(P_BASE+i), TextId = 0, ValId = V_BASE+i, Min=45, Max=46, Def=45, Val=M_DB[V_BASE+i] }
|
||||
end
|
||||
|
||||
MenuLines[5] = { Type = LT_MENU, Text="Only TAER affects AS3X/SAFE react dir", TextId = 0, ValId = menuId }
|
||||
MenuLines[6] = { Type = LT_MENU, Text="If changes, RX 'Relearn Servo'", TextId = 0, ValId = menuId }
|
||||
|
||||
ctx_SelLine = 0
|
||||
end
|
||||
|
||||
-- Begin
|
||||
for i = 0, 6 do -- clear menu
|
||||
MenuLines[i] = { MenuId = 0, lineNum = 0, Type = 0 }
|
||||
end
|
||||
|
||||
|
||||
if (menuId==0x1000) then -- MAIN MENU
|
||||
Menu = { MenuId = 0x1000, Text = "Save-Exit ("..MODEL.modelName..")", PrevId = 0, NextId = 0, BackId = 0, TextId=0 }
|
||||
|
||||
if (true) then
|
||||
MenuLines[4] = { Type = LT_MENU, Text="Save Changes", TextId = 0, ValId = 0x1005 }
|
||||
MenuLines[5] = { Type = LT_MENU, Text="Discard Changes", TextId = 0, ValId = 0xFFF9 }
|
||||
ctx_SelLine = 4
|
||||
end
|
||||
lastGoodMenu = menuId
|
||||
elseif (menuId==0x1001) then -- MODEL SETUP
|
||||
local backId = 0xFFF9 -- No changes, just exit
|
||||
local title = "Setup ("..MODEL.modelName..")"
|
||||
if (menuDataChanged) then
|
||||
backId = 0x1000 -- Go to Save menu
|
||||
title = title.." *"
|
||||
end
|
||||
Menu = { MenuId = 0x1001, Text = title, PrevId = 0, NextId = 0, BackId = backId, TextId=0 }
|
||||
MenuLines[0] = { Type = LT_MENU, Text = "Aircraft Setup", ValId = 0x1010,TextId=0 }
|
||||
MenuLines[1] = { Type = LT_MENU, Text = "Wing & Tail Channels ", ValId = 0x1020, TextId=0 }
|
||||
MenuLines[3] = { Type = LT_MENU, Text = "Gyro Channel Reverse", ValId = 0x1030, TextId=0 }
|
||||
MenuLines[5] = { Type = LT_MENU, Text = "WARNING: Changing of Aircraft", ValId = 0x1001, TextId=0 }
|
||||
MenuLines[6] = { Type = LT_MENU, Text = "deletes prev Ch/Port assgmt.", ValId = 0x1001, TextId=0 }
|
||||
|
||||
ctx_SelLine = 0
|
||||
lastGoodMenu = menuId
|
||||
elseif (menuId==0x1005) then
|
||||
ST_SaveFileData()
|
||||
menuDataChanged = false
|
||||
|
||||
local msg1 = "Data saved to: "
|
||||
local msg2 = " ../DSMLIB/"..MODEL.hashName
|
||||
|
||||
Menu = { MenuId = 0x1005, Text = "Config Saved", PrevId = 0, NextId = 0, BackId = 0, TextId=0 }
|
||||
MenuLines[2] = { Type = LT_MENU, Text=msg1, TextId = 0, ValId = 0x1005 }
|
||||
MenuLines[3] = { Type = LT_MENU, Text=msg2, TextId = 0, ValId = 0x1005 }
|
||||
MenuLines[6] = { Type = LT_MENU, Text="Complete", TextId = 0, ValId = 0xFFF9 }
|
||||
ctx_SelLine = 6
|
||||
lastGoodMenu = menuId
|
||||
elseif (menuId==0x1010) then
|
||||
Menu = { MenuId = 0x1010, Text = "Aircraft", PrevId = 0, NextId = 0x1011, BackId = 0x1001, TextId=0 }
|
||||
MenuLines[5] = { Type = LT_LIST_NC, Text="Aircraft Type", TextId = 0, ValId = MV_AIRCRAFT_TYPE, Min=15, Max=15, Def=15, Val=M_DB[MV_AIRCRAFT_TYPE] }
|
||||
ctx_SelLine = 5
|
||||
lastGoodMenu = menuId
|
||||
elseif (menuId==0x1011) then
|
||||
Menu = { MenuId = 0x1011, Text = "Model Type: "..aircraft_type_text[currATyp], PrevId = 0, NextId = 0x1020, BackId = 0x1010, TextId=0 }
|
||||
MenuLines[5] = { Type = LT_LIST_NC, Text="Wing Type", TextId = 0, ValId = MV_WING_TYPE, Min=20, Max=27, Def=20, Val=M_DB[MV_WING_TYPE] }
|
||||
MenuLines[6] = { Type = LT_LIST_NC, Text="Tail Type", TextId = 0, ValId = MV_TAIL_TYPE, Min=30, Max=40, Def=30, Val=M_DB[MV_TAIL_TYPE] }
|
||||
ctx_SelLine = 5
|
||||
lastGoodMenu = menuId
|
||||
elseif (menuId==0x1020) then
|
||||
------ WING SETUP -------
|
||||
local thr = M_DB[MV_CH_THR]
|
||||
local leftAil = M_DB[MV_CH_L_AIL]
|
||||
local rightAil = M_DB[MV_CH_R_AIL]
|
||||
local leftFlap = M_DB[MV_CH_L_FLP]
|
||||
local rightFlap = M_DB[MV_CH_R_FLP]
|
||||
|
||||
local thrText = "Thr"
|
||||
local leftAilText = "Left Ail"
|
||||
local rightAilText = "Right Ail"
|
||||
local leftFlapText = "Left Flap"
|
||||
local rightFlapText = "Right Flap"
|
||||
|
||||
if (rightAil==nil) then leftAilText = "Aileron" end
|
||||
if (rightFlap==nil) then leftFlapText = "Flap" end
|
||||
|
||||
local title = aircraft_type_text[currATyp].." Wing:"..wing_type_text[currWTyp]
|
||||
|
||||
Menu = { MenuId = 0x1020, Text = title, PrevId = 0, NextId = 0x1021, BackId = 0x1011, TextId=0 }
|
||||
|
||||
MenuLines[0] = { Type = LT_LIST_NC, Text=thrText, TextId = 0, ValId = MV_CH_THR, Min=0, Max=10, Def=0, Val= thr }
|
||||
|
||||
MenuLines[2] = { Type = LT_LIST_NC, Text=leftAilText, TextId = 0, ValId = MV_CH_L_AIL, Min=0, Max=9, Def=0, Val= leftAil }
|
||||
|
||||
if (rightAil) then
|
||||
MenuLines[3] = { Type = LT_LIST_NC, Text=rightAilText, TextId = 0, ValId = MV_CH_R_AIL, Min=0, Max=9, Def=0, Val= rightAil }
|
||||
end
|
||||
|
||||
if (leftFlap) then
|
||||
MenuLines[4] = { Type = LT_LIST_NC, Text=leftFlapText, TextId = 0, ValId = MV_CH_L_FLP, Min=0, Max=9, Def=0, Val= leftFlap }
|
||||
end
|
||||
if (rightFlap) then
|
||||
MenuLines[5] = { Type = LT_LIST_NC, Text=rightFlapText, TextId = 0, ValId = MV_CH_R_FLP, Min=0, Max=9, Def=0, Val= rightFlap }
|
||||
end
|
||||
|
||||
ctx_SelLine = 0
|
||||
lastGoodMenu = menuId
|
||||
|
||||
elseif (menuId==0x1021) then
|
||||
------ TAIL SETUP -------
|
||||
local leftRud = M_DB[MV_CH_L_RUD]
|
||||
local rightRud = M_DB[MV_CH_R_RUD]
|
||||
local leftEle = M_DB[MV_CH_L_ELE]
|
||||
local rightEle = M_DB[MV_CH_R_ELE]
|
||||
|
||||
local leftRudText = "Left Rud"
|
||||
local rightRudText = "Right Rud"
|
||||
|
||||
local leftElvText = "Left Ele"
|
||||
local rightElvText = "Right Ele"
|
||||
|
||||
if (rightRud==nil) then leftRudText = "Rud" end
|
||||
if (rightEle==nil) then leftElvText = "Ele" end
|
||||
|
||||
local title = aircraft_type_text[currATyp].." Tail:"..tail_type_text[currTTyp]
|
||||
|
||||
Menu = { MenuId = 0x1021, Text = title, PrevId = 0, NextId = 0x1001, BackId = 0x1020, TextId=0 }
|
||||
if (leftRud) then
|
||||
MenuLines[1] = { Type = LT_LIST_NC, Text=leftRudText, TextId = 0, ValId = MV_CH_L_RUD, Min=0, Max=9, Def=0, Val= leftRud}
|
||||
end
|
||||
|
||||
if (rightRud) then
|
||||
MenuLines[2] = { Type = LT_LIST_NC, Text=rightRudText, TextId = 0, ValId = MV_CH_R_RUD, Min=0, Max=9, Def=0, Val=rightRud }
|
||||
end
|
||||
|
||||
if (leftEle) then
|
||||
MenuLines[4] = { Type = LT_LIST_NC, Text=leftElvText, TextId = 0, ValId = MV_CH_L_ELE, Min=0, Max=9, Def=0, Val=leftEle }
|
||||
end
|
||||
|
||||
if (rightEle) then
|
||||
MenuLines[5] = { Type = LT_LIST_NC, Text=rightElvText, TextId = 0, ValId = MV_CH_R_ELE, Min=0, Max=9, Def=0, Val=rightEle }
|
||||
end
|
||||
|
||||
ctx_SelLine = 1
|
||||
lastGoodMenu = menuId
|
||||
|
||||
elseif (menuId==0x1030) then
|
||||
Menu = { MenuId = 0x1030, Text = "Gyro Reverse (Port 1-5)", PrevId = 0, NextId = 0x1031, BackId = 0x1001, TextId=0 }
|
||||
generateGyroReverse(menuId,P1,MV_P1_MODE)
|
||||
lastGoodMenu = menuId
|
||||
elseif (menuId==0x1031) then
|
||||
Menu = { MenuId = 0x1031, Text = "Gyro Reverse (Port 6-10)", PrevId = 0x1030, NextId = 0, BackId = 0x1001, TextId=0 }
|
||||
generateGyroReverse(menuId,P6,MV_P6_MODE)
|
||||
lastGoodMenu = menuId
|
||||
elseif (menuId==0xFFF9) then
|
||||
ChangePhase(PH_EXIT_DONE)
|
||||
return
|
||||
else
|
||||
Menu = { MenuId = 0x0002, Text = "NOT IMPLEMENTED", TextId = 0, PrevId = 0, NextId = 0, BackId = lastGoodMenu }
|
||||
ctx_SelLine = -1 -- BACK BUTTON
|
||||
end
|
||||
|
||||
for i = 0, 6 do
|
||||
if (MenuLines[i].Type > 0) then
|
||||
MenuLinePostProcessing(MenuLines[i])
|
||||
end
|
||||
end
|
||||
gc()
|
||||
end
|
||||
|
||||
-- Inital List and Image Text for this menus
|
||||
local function ST_Init_Text(rxId)
|
||||
-- Channel Names use the Port Text Retrived from OTX/ETX
|
||||
local p = 0
|
||||
|
||||
for i = 0, 9 do List_Text[i] = MODEL.PORT_TEXT[i] end
|
||||
List_Text[10] = "--"
|
||||
|
||||
-- Aircraft Type
|
||||
List_Text[15+AT_PLANE] = "Airplane";
|
||||
|
||||
-- Wing Types
|
||||
p = 20+WT_A1; List_Text[p] = "Single Ail"; --List_Text_Img[p] = "x.png|Single Aileron"
|
||||
p = 20+WT_A2; List_Text[p] = "Dual Ail"; --List_Text_Img[p] = "x.png|Dual Aileron"
|
||||
p = 20+WT_FLPR; List_Text[p] = "Flaperon"; --List_Text_Img[p] = "x.png|Flaperon"
|
||||
p = 20+WT_A1_F1; List_Text[p] = "Ail + Flap"; --List_Text_Img[p] = "x.png|Aileron + Flap"
|
||||
p = 20+WT_A2_F1; List_Text[p] = "Dual Ail + Flap"; --List_Text_Img[p] = "x.png|Dual Aileron + Flap"
|
||||
p = 20+WT_A2_F2; List_Text[p] = "Dual Ail + Dual Flap"; --List_Text_Img[p] = "x.png|Dual Aileron + Dual Flap"
|
||||
p = 20+WT_ELEVON_A; List_Text[p] = "Delta A"; --List_Text_Img[p] = "x.png|Delta/Elevon A"
|
||||
p = 20+WT_ELEVON_B; List_Text[p] = "Delta B"; --List_Text_Img[p] = "x.png|Delta/Elevon B"
|
||||
|
||||
-- Tail Types
|
||||
p = 30+TT_R1; List_Text[p] = "Rudder Only"; --List_Text_Img[p] = "x.png|Rudder Only"
|
||||
p = 30+TT_R1_E1; List_Text[p] = "Rud + Ele"; --List_Text_Img[p] = "x.png|Tail Normal"
|
||||
p = 30+TT_R1_E2; List_Text[p] = "Rud + Dual Ele"; --List_Text_Img[p] = "x.png|Rud + Dual Ele"
|
||||
p = 30+TT_R2_E1; List_Text[p] = "Dual Rud + Ele"; --List_Text_Img[p] = "x.png|Dual Rud + Ele"
|
||||
p = 30+TT_R2_E2; List_Text[p] = "Dual Rud + Dual Ele"; --List_Text_Img[p] = "x.png|Dual Rud + Dual Elev"
|
||||
p = 30+TT_VT_A; List_Text[p] = "V-Tail A"; --List_Text_Img[p] = "x.png|V-Tail A"
|
||||
p = 30+TT_VT_B; List_Text[p] = "V-Tail B"; --List_Text_Img[p] = "x.png|V-Tail B"
|
||||
p = 30+TT_TLRN_A; List_Text[p] = "Taileron A"; --List_Text_Img[p] = "x.png|Taileron A"
|
||||
p = 30+TT_TLRN_B; List_Text[p] = "Taileron B"; --List_Text_Img[p] = "x.png|Taileron B"
|
||||
p = 30+TT_TLRN_A_R2; List_Text[p] = "Taileron A + 2x Rud"; --List_Text_Img[p] = "x.png|Taileron A + Dual Rud"
|
||||
p = 30+TT_TLRN_B_R2; List_Text[p] = "Taileron B + 2x Rud"; --List_Text_Img[p] = "x.png|Taileron B + Dual Rud"
|
||||
|
||||
-- Servo Reverse
|
||||
List_Text[45+MT_NORMAL] = "Normal"
|
||||
List_Text[45+MT_REVERSE] = "Reverse"
|
||||
end
|
||||
|
||||
-- Initial Setup
|
||||
local function ST_Init()
|
||||
ST_Init_Text(0)
|
||||
gc()
|
||||
|
||||
-- Setup default Data if no data loaded
|
||||
menuDataChanged = false
|
||||
if (M_DB[MV_AIRCRAFT_TYPE]==nil) then
|
||||
ST_Default_Data()
|
||||
menuDataChanged = true
|
||||
end
|
||||
|
||||
currATyp = M_DB[MV_AIRCRAFT_TYPE]
|
||||
currWTyp = M_DB[MV_WING_TYPE]
|
||||
currTTyp = M_DB[MV_TAIL_TYPE]
|
||||
|
||||
Phase = PH_RX_VER
|
||||
end
|
||||
|
||||
----- Line Type
|
||||
|
||||
local function isSelectable(line)
|
||||
if (line.Type == LT_MENU and line.ValId == line.MenuId) then return false end -- Menu to same page
|
||||
if (line.Type ~= LT_MENU and line.Max == 0) then return false end -- Read only data line
|
||||
if (line.Type ~= 0 and line.TextId < 0x8000) then return true end -- Not Flight Mode
|
||||
return false;
|
||||
end
|
||||
|
||||
local function isListLine(line)
|
||||
return line.Type==LT_LIST_NC
|
||||
end
|
||||
|
||||
local function isEditing()
|
||||
return ctx_EditLine ~= nil
|
||||
end
|
||||
|
||||
-----------------------
|
||||
local function Get_Text(index)
|
||||
local out = Text[index] or string.format("Unknown_%X", index)
|
||||
return out
|
||||
end
|
||||
|
||||
local function Get_Text_Value(index)
|
||||
local out = List_Text[index] or Get_Text(index)
|
||||
return out
|
||||
end
|
||||
|
||||
function ChangePhase(newPhase)
|
||||
Phase = newPhase
|
||||
end
|
||||
|
||||
local function Value_Add(dir)
|
||||
local line = MenuLines[ctx_SelLine]
|
||||
local inc = dir
|
||||
|
||||
line.Val = line.Val + inc
|
||||
|
||||
if line.Val > line.Max then
|
||||
line.Val = line.Max
|
||||
elseif line.Val < line.Min then
|
||||
line.Val = line.Min
|
||||
end
|
||||
end
|
||||
--------------
|
||||
|
||||
local function GotoMenu(menuId, lastSelectedLine)
|
||||
Menu.MenuId = menuId
|
||||
ctx_SelLine = lastSelectedLine
|
||||
ChangePhase(PH_TITLE)
|
||||
end
|
||||
|
||||
local function DSM_HandleEvent(event)
|
||||
if event == EVT_VIRTUAL_EXIT then
|
||||
if Phase == PH_RX_VER then
|
||||
Phase = PH_EXIT_DONE -- Exit program
|
||||
else
|
||||
if isEditing() then -- Editing a Line, need to restore original value
|
||||
MenuLines[ctx_EditLine].Val = originalValue
|
||||
event = EVT_VIRTUAL_ENTER
|
||||
else
|
||||
if (Menu.BackId > 0 ) then -- Back??
|
||||
ctx_SelLine = -1 --Back Button
|
||||
event = EVT_VIRTUAL_ENTER
|
||||
else
|
||||
ChangePhase(PH_EXIT_REQ)
|
||||
end
|
||||
end
|
||||
end
|
||||
end -- Exit
|
||||
|
||||
if Phase == PH_RX_VER then return end -- nothing else to do
|
||||
|
||||
if event == EVT_VIRTUAL_NEXT then
|
||||
if isEditing() then -- Editting?
|
||||
Value_Add(1)
|
||||
else
|
||||
if ctx_SelLine < 7 then -- On a regular line
|
||||
local num = ctx_SelLine -- Find the prev selectable
|
||||
for i = ctx_SelLine + 1, 6, 1 do
|
||||
local line = MenuLines[i]
|
||||
if isSelectable(line) then
|
||||
ctx_SelLine = i
|
||||
break
|
||||
end
|
||||
end
|
||||
if num == ctx_SelLine then -- No Selectable Line
|
||||
if Menu.NextId ~= 0 then
|
||||
ctx_SelLine = 7 -- Next
|
||||
elseif Menu.PrevId ~= 0 then
|
||||
ctx_SelLine = 8 -- Prev
|
||||
end
|
||||
end
|
||||
elseif Menu.PrevId ~= 0 then
|
||||
ctx_SelLine = 8 -- Prev
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if event == EVT_VIRTUAL_PREV then
|
||||
if isEditing() then -- In Edit Mode
|
||||
Value_Add(-1)
|
||||
else
|
||||
if ctx_SelLine == 8 and Menu.NextId ~= 0 then
|
||||
ctx_SelLine = 7 -- Next
|
||||
elseif ctx_SelLine > 0 then
|
||||
if ctx_SelLine > 6 then
|
||||
ctx_SelLine = 7 --NEXT
|
||||
end
|
||||
local num = ctx_SelLine -- Find Prev Selectable line
|
||||
for i = ctx_SelLine - 1, 0, -1 do
|
||||
local line = MenuLines[i]
|
||||
if isSelectable(line) then
|
||||
ctx_SelLine = i
|
||||
break
|
||||
end
|
||||
end
|
||||
if num == ctx_SelLine then -- No Selectable Line
|
||||
if (Menu.BackId > 0) then
|
||||
ctx_SelLine = -1 -- Back
|
||||
end
|
||||
end
|
||||
else
|
||||
ctx_SelLine = -1 -- Back
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
if event == EVT_VIRTUAL_ENTER then
|
||||
if ctx_SelLine == -1 then -- Back
|
||||
GotoMenu(Menu.BackId, 0x80)
|
||||
elseif ctx_SelLine == 7 then -- Next
|
||||
GotoMenu(Menu.NextId, 0x82)
|
||||
elseif ctx_SelLine == 8 then -- Prev
|
||||
GotoMenu(Menu.PrevId, 0x81)
|
||||
elseif ctx_SelLine >= 0 and MenuLines[ctx_SelLine].Type == LT_MENU then
|
||||
GotoMenu(MenuLines[ctx_SelLine].ValId, ctx_SelLine) -- ValId is the next menu
|
||||
else
|
||||
-- value entry
|
||||
if isEditing() then
|
||||
ctx_EditLine = nil -- Done Editting
|
||||
ChangePhase(PH_VAL_EDIT_END)
|
||||
else -- Start Editing
|
||||
ctx_EditLine = ctx_SelLine
|
||||
originalValue = MenuLines[ctx_SelLine].Val
|
||||
ChangePhase(PH_VAL_EDITING)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function DSM_Send_Receive()
|
||||
|
||||
if Phase == PH_RX_VER then -- request RX version
|
||||
Phase = PH_TITLE
|
||||
Menu.MenuId = 0x01001
|
||||
Refresh_Display = true
|
||||
elseif Phase == PH_WAIT_CMD then
|
||||
|
||||
elseif Phase == PH_TITLE then -- request menu title
|
||||
ST_LoadMenu(Menu.MenuId)
|
||||
if (Phase~=PH_EXIT_DONE) then
|
||||
Phase = PH_WAIT_CMD
|
||||
end
|
||||
Refresh_Display = true
|
||||
elseif Phase == PH_VAL_EDIT_END then -- send value
|
||||
local line = MenuLines[ctx_SelLine] -- Updated Value of SELECTED line
|
||||
|
||||
-- Update the menu data from the line
|
||||
if (M_DB[line.ValId] ~= line.Val ) then
|
||||
M_DB[line.ValId] = line.Val
|
||||
print(string.format("MENU_DATA[%d/%s]=%d",line.ValId,line.Text, line.Val))
|
||||
menuDataChanged=true
|
||||
end
|
||||
|
||||
-- Did the Wing type change?
|
||||
local wt = M_DB[MV_WING_TYPE]
|
||||
if (currWTyp ~= wt) then
|
||||
currWTyp = wt
|
||||
ST_PlaneWingInit(currWTyp)
|
||||
|
||||
-- DELTA has only RUDER
|
||||
if (currWTyp==WT_ELEVON_A or currWTyp==WT_ELEVON_B) then
|
||||
M_DB[MV_TAIL_TYPE] = TT_R1
|
||||
end
|
||||
end
|
||||
|
||||
--- Did the tail changed?
|
||||
local tt = M_DB[MV_TAIL_TYPE]
|
||||
if (currTTyp ~= tt) then
|
||||
if (not tailTypeCompatible(currTTyp,tt)) then
|
||||
ST_PlaneTailInit(tt)
|
||||
end
|
||||
currTTyp = tt
|
||||
end
|
||||
|
||||
Phase = PH_WAIT_CMD
|
||||
elseif Phase == PH_EXIT_REQ then
|
||||
Phase=PH_EXIT_DONE
|
||||
end
|
||||
end
|
||||
|
||||
-----
|
||||
|
||||
local function showBitmap(x, y, imgDesc)
|
||||
local f = string.gmatch(imgDesc, '([^%|]+)') -- Iterator over values split by '|'
|
||||
local imgName, imgMsg = f(), f()
|
||||
|
||||
f = string.gmatch(imgMsg or "", '([^%:]+)') -- Iterator over values split by ':'
|
||||
local p1, p2 = f(), f()
|
||||
|
||||
lcd.drawText(x, y, p1 or "", TEXT_ATTR) -- Alternate Image MSG
|
||||
lcd.drawText(x, y + LCD_Y_LINE_HEIGHT, p2 or "", TEXT_ATTR) -- Alternate Image MSG
|
||||
gc()
|
||||
end
|
||||
|
||||
|
||||
local function drawButton(x, y, text, active)
|
||||
local attr = TEXT_ATTR
|
||||
if (active) then attr = attr + INVERS end
|
||||
lcd.drawText(x, y, text, attr)
|
||||
end
|
||||
|
||||
local function DSM_Display()
|
||||
lcd.clear()
|
||||
--Draw RX Menu
|
||||
if Phase == PH_RX_VER then
|
||||
return
|
||||
end
|
||||
|
||||
-- display Program version or RX version
|
||||
local msg = "FProg "..VERSION
|
||||
lcd.drawText(40, LCD_Y_LOWER_BUTTONS, msg, TEXT_ATTR)
|
||||
|
||||
if Menu.MenuId == 0 then return end; -- No Title yet
|
||||
|
||||
-- Got a Menu
|
||||
lcd.drawText(1, 0, Menu.Text, TEXT_ATTR + INVERS)
|
||||
|
||||
local y = LCD_Y_LINE_HEIGHT + 2
|
||||
for i = 0, 6 do
|
||||
local attrib = TEXT_ATTR
|
||||
if (i == ctx_SelLine) then attrib = attrib + INVERS end -- Selected Line
|
||||
|
||||
local line = MenuLines[i]
|
||||
|
||||
if line ~= nil and line.Type ~= 0 then
|
||||
local heading = line.Text
|
||||
|
||||
local text = nil
|
||||
if line.Type ~= LT_MENU then -- list/value
|
||||
if line.Val ~= nil then
|
||||
if isListLine(line) then
|
||||
local textId = line.Val + line.TextStart
|
||||
text = Get_Text_Value(textId)
|
||||
|
||||
--local imgDesc = List_Text_Img[textId]
|
||||
|
||||
--if (imgDesc and i == ctx_SelLine) then -- Optional Image and Msg for selected value
|
||||
-- showBitmap(1, 20, imgDesc)
|
||||
--end
|
||||
else
|
||||
text = line.Val
|
||||
end
|
||||
end -- if is Value
|
||||
|
||||
if (ctx_EditLine == i) then -- Editing a Line
|
||||
attrib = BLINK + INVERS + TEXT_ATTR
|
||||
end
|
||||
lcd.drawText(LCD_X_MAX, y, text or "--", attrib + RIGHT) -- display value
|
||||
--lcd.drawText(LCD_X_MAX, y, line.Format or "", TEXT_ATTR + RIGHT) -- display Format
|
||||
attrib = TEXT_ATTR
|
||||
end
|
||||
|
||||
lcd.drawText(1, y, heading, attrib) -- display text
|
||||
end
|
||||
y = y + LCD_Y_LINE_HEIGHT
|
||||
end -- for
|
||||
|
||||
if Menu.BackId~=0 then
|
||||
drawButton(LCD_X_RIGHT_BUTTONS, 0, "Back", ctx_SelLine == -1)
|
||||
end
|
||||
|
||||
if Menu.NextId~=0 then
|
||||
drawButton(LCD_X_RIGHT_BUTTONS, LCD_Y_LOWER_BUTTONS, "Next", ctx_SelLine == 7)
|
||||
end
|
||||
|
||||
if Menu.PrevId~=0 then
|
||||
drawButton(1, LCD_Y_LOWER_BUTTONS, "Prev", ctx_SelLine == 8)
|
||||
end
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
-- Init
|
||||
local function DSM_Init()
|
||||
--LOG_open()
|
||||
ST_Init()
|
||||
gc()
|
||||
|
||||
if (LCD_W > 128) then
|
||||
TEXT_ATTR = 0
|
||||
LCD_Y_LINE_HEIGHT = 25
|
||||
LCD_X_MAX = 300
|
||||
LCD_X_RIGHT_BUTTONS = LCD_X_MAX - 30
|
||||
|
||||
LCD_Y_LOWER_BUTTONS = (8 * LCD_Y_LINE_HEIGHT) + 2
|
||||
end
|
||||
|
||||
Phase = PH_RX_VER
|
||||
end
|
||||
|
||||
-- Main
|
||||
|
||||
local function DSM_Run(event)
|
||||
if event == nil then
|
||||
error("Cannot be run as a model script!")
|
||||
return 2
|
||||
end
|
||||
|
||||
DSM_Display()
|
||||
DSM_HandleEvent(event)
|
||||
DSM_Send_Receive()
|
||||
gc()
|
||||
|
||||
if Phase == PH_EXIT_DONE then
|
||||
LOG_close()
|
||||
return 2
|
||||
else
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
||||
---
|
||||
-- Load Model Config
|
||||
gc()
|
||||
local r = assert(loadScript(DSMLIB_PATH.."DsmMIN_P1.lua"), "Not-Found: DSMLIB/DsmMIN_P1.lua")
|
||||
(MODEL,M_DB, LOG_write)
|
||||
gc()
|
||||
----
|
||||
return { init = DSM_Init, run = DSM_Run }
|
||||
813
SCRIPTS/TOOLS/DSMLIB/DsmFwPrgLib.lua
Normal file
|
|
@ -0,0 +1,813 @@
|
|||
---- #########################################################################
|
||||
---- # #
|
||||
---- # Copyright (C) OpenTX/EdgeTx #
|
||||
-----# #
|
||||
---- # 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. #
|
||||
---- # #
|
||||
---- #########################################################################
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- This script library is a rewrite of the original DSM forward programming Lua
|
||||
-- Script. The goal is to make it easier to understand, mantain, and to
|
||||
-- separate the GUI from the DSM Forward programming engine/logic
|
||||
-- in this way, GUIs can evolve independent. OpenTX Gui, EdgeTx GUI, Small Radios, etc.
|
||||
|
||||
-- Code is based on the code/work by: Pascal Langer (Author of the Multi-Module)
|
||||
-- Rewrite/Enhancements By: Francisco Arzu
|
||||
--
|
||||
------------------------------------------------------------------------------
|
||||
--###############################################################################
|
||||
-- Multi buffer for DSM description
|
||||
-- Multi_Buffer[0..2]=="DSM" -> Lua script is running
|
||||
-- Multi_Buffer[3]==0x70+len -> TX to RX data ready to be sent
|
||||
-- Multi_Buffer[4..9]=6 bytes of TX to RX data
|
||||
-- Multi_Buffer[10..25]=16 bytes of RX to TX data
|
||||
--
|
||||
-- To start operation:
|
||||
-- Write 0x00 at address 3
|
||||
-- Write 0x00 at address 10
|
||||
-- Write "DSM" at address 0..2
|
||||
--###############################################################################
|
||||
|
||||
|
||||
local Log, menuLib, modelLib, DEBUG_ON = ... -- Get Debug_ON from parameters. -- 0=NO DEBUG, 1=HIGH LEVEL 2=MORE DETAILS
|
||||
local LIB_VERSION = "0.55"
|
||||
local MSG_FILE = "/SCRIPTS/TOOLS/DSMLIB/msg_fwdp_en.txt"
|
||||
|
||||
local PHASE = menuLib.PHASE
|
||||
local LINE_TYPE = menuLib.LINE_TYPE
|
||||
|
||||
local CH_TYPE = modelLib.CH_TYPE
|
||||
local CH_MIX_TYPE = modelLib.CH_MIX_TYPE
|
||||
|
||||
local DISP_ATTR = menuLib.DISP_ATTR
|
||||
local DSM_Context = menuLib.DSM_Context
|
||||
local MODEL = modelLib.MODEL
|
||||
|
||||
local MAX_MENU_LINES = menuLib.MAX_MENU_LINES
|
||||
local BACK_BUTTON = menuLib.BACK_BUTTON
|
||||
local NEXT_BUTTON = menuLib.NEXT_BUTTON
|
||||
local PREV_BUTTON = menuLib.PREV_BUTTON
|
||||
|
||||
|
||||
local SEND_TIMEOUT = 2000 / 10 -- Home many 10ms intervals to wait on sending data to tx to keep connection open (2s)
|
||||
local TXInactivityTime = 0 -- Next time to do heartbeat after inactivity
|
||||
local RXInactivityTime = 0 -- To check RX disconnection
|
||||
|
||||
|
||||
local TxInfo_Type = 0
|
||||
local TxInfo_Step = 0
|
||||
local Change_Step = 0
|
||||
|
||||
local IS_EDGETX = false
|
||||
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
|
||||
local function multiBuffer2String() -- used for debug
|
||||
local i
|
||||
local rxAnswer = "RX:"
|
||||
for i = 10, 25 do
|
||||
rxAnswer = rxAnswer .. string.format(" %02X", multiBuffer(i))
|
||||
end
|
||||
return rxAnswer
|
||||
end
|
||||
|
||||
---------------- DSM Values <-> Int16 Manipulation --------------------------------------------------------
|
||||
|
||||
local function int16_LSB(number) -- Less Significat byte
|
||||
local r,x = bit32.band(number, 0xFF)
|
||||
return r
|
||||
end
|
||||
|
||||
local function int16_MSB(number) -- Most signifcant byte
|
||||
return bit32.rshift(number, 8)
|
||||
end
|
||||
|
||||
local function Dsm_to_Int16(lsb, msb) -- Componse an Int16 value
|
||||
return bit32.lshift(msb, 8) + lsb
|
||||
end
|
||||
|
||||
local function Dsm_to_SInt16(lsb,msb) -- Componse a SIGNED Int16 value
|
||||
local value = bit32.lshift(msb, 8) + lsb
|
||||
if value >= 0x8000 then -- Negative value??
|
||||
return value - 0x10000
|
||||
end
|
||||
return value
|
||||
end
|
||||
|
||||
local function sInt16ToDsm(value) -- Convent to SIGNED DSM Value
|
||||
if value < 0 then
|
||||
value = 0x10000 + value
|
||||
end
|
||||
return value
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
local function DSM_send(...)
|
||||
local arg = { ... }
|
||||
|
||||
for i = 1, #arg do
|
||||
multiBuffer(3 + i, arg[i])
|
||||
end
|
||||
multiBuffer(3, 0x70 + #arg)
|
||||
|
||||
|
||||
if (DEBUG_ON > 1) then
|
||||
local str = ""
|
||||
for i = 1, #arg do
|
||||
str = str .. string.format("%02X ", arg[i])
|
||||
end
|
||||
LOG_write("DSM_SEND: [%s]\n", str)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------------------------
|
||||
local function DSM_StartConnection()
|
||||
if (DEBUG_ON) then Log.LOG_write("DSM_StartConnection()\n") end
|
||||
|
||||
--Set protocol to talk to
|
||||
multiBuffer( 0, string.byte('D') )
|
||||
--test if value has been written
|
||||
if multiBuffer( 0 ) ~= string.byte('D') then
|
||||
if (DEBUG_ON) then Log.LOG_write("Not Enouth memory\n") end
|
||||
error("Not enough memory!")
|
||||
return 2
|
||||
end
|
||||
--Init TX buffer
|
||||
multiBuffer( 3, 0x00 )
|
||||
--Init RX buffer
|
||||
multiBuffer( 10, 0x00 )
|
||||
--Init telemetry
|
||||
multiBuffer( 0, string.byte('D') )
|
||||
multiBuffer( 1, string.byte('S') )
|
||||
multiBuffer( 2, string.byte('M') )
|
||||
|
||||
return 0
|
||||
end
|
||||
|
||||
local function DSM_ReleaseConnection()
|
||||
if (DEBUG_ON) then Log.LOG_write("DSM_ReleaseConnection()\n") end
|
||||
multiBuffer(0, 0)
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------------------------------
|
||||
-- REEQUEST Messages to RX
|
||||
|
||||
local function DSM_sendHeartbeat()
|
||||
-- keep connection open
|
||||
if (DEBUG_ON) then Log.LOG_write("SEND DSM_sendHeartbeat()\n") end
|
||||
DSM_send(0x00, 0x04, 0x00, 0x00)
|
||||
end
|
||||
|
||||
local function DSM_getRxVerson()
|
||||
local TX_CAP=0x14 -- Capabilities??
|
||||
local TX_MAX_CH = modelLib.TX_CHANNELS - 6 --number of channels after 6 (6Ch=0, 10ch=4, etc)
|
||||
|
||||
if (DEBUG_ON) then Log.LOG_write("SEND DSM_getRxVersion(Ch:0x%X,Cap:0x%X)\n",TX_MAX_CH,TX_CAP) end
|
||||
DSM_send(0x11, 0x06, TX_MAX_CH, TX_CAP, 0x00, 0x00)
|
||||
end
|
||||
|
||||
local function DSM_getMainMenu()
|
||||
local TX_CAP=0x14 -- Capabilities??
|
||||
local TX_MAX_CH = modelLib.TX_CHANNELS - 6 --number of channels after 6 (6Ch=0, 10ch=4, etc)
|
||||
|
||||
if (DEBUG_ON) then Log.LOG_write("SEND DSM_getMainMenu(Ch:0x%X,Cap:0x%X) -- TX_Channels=%d\n",TX_MAX_CH,TX_CAP,TX_MAX_CH+6) end
|
||||
DSM_send(0x12, 0x06, TX_MAX_CH, TX_CAP, 0x00, 0x00) -- first menu only
|
||||
end
|
||||
|
||||
local function DSM_getMenu(menuId, latSelLine)
|
||||
if (DEBUG_ON) then Log.LOG_write("SEND DSM_getMenu(MenuId=0x%X LastSelectedLine=%s)\n", menuId, latSelLine) end
|
||||
DSM_send(0x16, 0x06, int16_MSB(menuId), int16_LSB(menuId), 0x00, latSelLine)
|
||||
end
|
||||
|
||||
local function DSM_getFirstMenuLine(menuId)
|
||||
if (DEBUG_ON) then Log.LOG_write("SEND DSM_getFirstMenuLine(MenuId=0x%X)\n", menuId) end
|
||||
DSM_send(0x13, 0x04, int16_MSB(menuId), int16_LSB(menuId)) -- line 0
|
||||
end
|
||||
|
||||
local function DSM_getNextMenuLine(menuId, curLine)
|
||||
if (DEBUG_ON) then Log.LOG_write("SEND DSM_getNextLine(MenuId=0x%X,LastLine=%s)\n", menuId, curLine) end
|
||||
DSM_send(0x14, 0x06, int16_MSB(menuId), int16_LSB(menuId), 0x00, curLine) -- line X
|
||||
end
|
||||
|
||||
local function DSM_getNextMenuValue(menuId, valId, text)
|
||||
if (DEBUG_ON) then Log.LOG_write("SEND DSM_getNextMenuValue(MenuId=0x%X, LastValueId=0x%X) Extra: Text=\"%s\"\n", menuId, valId,
|
||||
text)
|
||||
end
|
||||
DSM_send(0x15, 0x06, int16_MSB(menuId), int16_LSB(menuId), int16_MSB(valId), int16_LSB(valId)) -- line X
|
||||
end
|
||||
|
||||
local function DSM_updateMenuValue(valId, val, text, line)
|
||||
local value = sInt16ToDsm(val)
|
||||
if (DEBUG_ON) then Log.LOG_write("SEND DSM_updateValue(ValueId=0x%X,val=%d) Extra: Text=\"%s\" Value=%s\n", valId, val, text, menuLib.lineValue2String(line)) end
|
||||
DSM_send(0x18, 0x06, int16_MSB(valId), int16_LSB(valId), int16_MSB(value), int16_LSB(value)) -- send current value
|
||||
end
|
||||
|
||||
local function DSM_validateMenuValue(valId, text, line)
|
||||
if (DEBUG_ON) then Log.LOG_write("SEND DSM_validateValue(ValueId=0x%X) Extra: Text=\"%s\" Value=%s\n", valId, text, menuLib.lineValue2String(line)) end
|
||||
DSM_send(0x19, 0x04, int16_MSB(valId), int16_LSB(valId))
|
||||
end
|
||||
|
||||
local function DSM_editingValue(lineNum, text, line)
|
||||
if (DEBUG_ON) then Log.LOG_write("SEND DSM_editingValue(lineNo=0x%X) Extra: Text=\"%s\" Val=%s\n", lineNum, text, menuLib.lineValue2String(line)) end
|
||||
DSM_send(0x1A, 0x04, int16_MSB(lineNum), int16_LSB(lineNum))
|
||||
end
|
||||
|
||||
local function DSM_editingValueEnd(lineNum, text, line)
|
||||
if (DEBUG_ON) then Log.LOG_write("SEND DSM_editingValueEnd(lineNo=0x%X) Extra: Text=\"%s\" Value=%s\n", lineNum, text, menuLib.lineValue2String(line)) end
|
||||
DSM_send(0x1B, 0x04, int16_MSB(lineNum), int16_LSB(lineNum))
|
||||
end
|
||||
|
||||
-- Send the functionality of the RX channel Port (channel)
|
||||
local function DSM_sendTxChInfo_20(portNo)
|
||||
local b1,b2 = MODEL.DSM_ChannelInfo[portNo][0] or 0, MODEL.DSM_ChannelInfo[portNo][1] or 0
|
||||
|
||||
if (DEBUG_ON) then Log.LOG_write("CALL DSM_TxChInfo(#%d DATA= %02X %02X %02X %02X) %s\n", portNo,
|
||||
portNo, portNo, b1, b2, modelLib.channelType2String(b1,b2)) -- DATA part
|
||||
end
|
||||
DSM_send(0x20, 0x06, portNo, portNo, b1, b2)
|
||||
end
|
||||
|
||||
local function DSM_sendTxSubtrim_21(portNo)
|
||||
local usage = MODEL.DSM_ChannelInfo[portNo][1] or 0
|
||||
local leftTravel = math.abs(math.floor(MODEL.modelOutputChannel[portNo].min/10))
|
||||
local rightTravel = math.abs(math.floor(MODEL.modelOutputChannel[portNo].max/10))
|
||||
local subTrim = math.floor(MODEL.modelOutputChannel[portNo].offset/10)
|
||||
|
||||
-- Center at 100%: 142-1906 (0 8E 07 72)
|
||||
local left = 142
|
||||
local right = 1906
|
||||
|
||||
if (bit32.band(usage,CH_TYPE.THR)>0) then
|
||||
left = 0
|
||||
right = 2047
|
||||
end
|
||||
|
||||
left = math.floor (left - (leftTravel -100) *8.8 + subTrim*2)
|
||||
right = math.floor (right + (rightTravel -100) *8.8 + subTrim*2)
|
||||
|
||||
if (left<0) then left=0 end
|
||||
if (right>2027) then right=2047 end
|
||||
|
||||
local b1,b2,b3,b4 = int16_MSB(left), int16_LSB(left), int16_MSB(right), int16_LSB(right)
|
||||
|
||||
if (DEBUG_ON) then Log.LOG_write("CALL DSM_TxSubtrim(#%d DATA=%02X %02X %02X %02X) Range(%d - %d) ER L/R:(%d - %d)x8 ST:(%d)x2\n", portNo,
|
||||
b1,b2,b3,b4, left, right, leftTravel-100, rightTravel-100, subTrim) -- DATA part
|
||||
end
|
||||
DSM_send(0x21, 0x06, b1,b2,b3,b4) -- Port is not send anywhere, since the previous 0x20 type message have it.
|
||||
end
|
||||
|
||||
local function DSM_sendTxServoTravel_23(portNo)
|
||||
local leftTravel = math.abs(math.floor(MODEL.modelOutputChannel[portNo].min/10))
|
||||
local rightTravel = math.abs(math.floor(MODEL.modelOutputChannel[portNo].max/10))
|
||||
local debugInfo = string.format("Travel L/R (%d - %d)",leftTravel,rightTravel)
|
||||
|
||||
if (DEBUG_ON) then Log.LOG_write("CALL DSM_TxServoTravel(#%d DATA= %02X %02X %02X %02X) %s\n", portNo,
|
||||
0x00, leftTravel, 0x00, rightTravel, debugInfo) -- DATA part
|
||||
end
|
||||
DSM_send(0x23, 0x06, 0x00, leftTravel, 0x00, rightTravel)
|
||||
end
|
||||
|
||||
local function DSM_sentTxInfo(menuId,portNo)
|
||||
-- TxInfo_Type=0 : AR636B Main Menu (Send port/Channel info + SubTrim + Travel)
|
||||
-- TxInfo_Type=1 : AR630-637 Famly Main Menu (Only Send Port/Channel usage Msg 0x20)
|
||||
-- TxInfo_Type=1F : AR630-637 Initial Setup/Relearn Servo Settings (Send port/Channel info + SubTrim + Travel +0x24/Unknown)
|
||||
|
||||
if (TxInfo_Step == 0) then
|
||||
-- AR630 family: Both TxInfo_Type (ManinMenu=0x1, Other First Time Configuration = 0x1F)
|
||||
DSM_sendTxChInfo_20(portNo)
|
||||
|
||||
if (TxInfo_Type == 0x1F) then
|
||||
TxInfo_Step = 1
|
||||
end
|
||||
if (TxInfo_Type == 0x00) then
|
||||
TxInfo_Step = 2
|
||||
end
|
||||
elseif (TxInfo_Step == 1) then
|
||||
DSM_sendTxServoTravel_23(portNo)
|
||||
TxInfo_Step = 2
|
||||
elseif (TxInfo_Step == 2) then
|
||||
DSM_sendTxSubtrim_21(portNo)
|
||||
|
||||
if (TxInfo_Type == 0x00) then
|
||||
TxInfo_Step = 5 -- End Step
|
||||
else
|
||||
TxInfo_Step = 3
|
||||
end
|
||||
elseif (TxInfo_Step == 3) then
|
||||
-- 24,6: 0 83 5A B5
|
||||
if (DEBUG_ON) then Log.LOG_write("CALL DSM_TxInfo24(#%d DATA=0x24 0x06 %02X %02X %02X %02X)\n", portNo,
|
||||
0x00, 0x83, 0x5A, 0xB5) -- DATA part
|
||||
end
|
||||
DSM_send(0x24, 0x06, 0x00, 0x83, 0x5A, 0xB5) -- Still Uknown
|
||||
TxInfo_Step = 4
|
||||
|
||||
elseif (TxInfo_Step == 4) then
|
||||
-- 24,6: 6 80 25 4B
|
||||
if (DEBUG_ON) then Log.LOG_write("CALL DSM_TxInfo24(#%d DATA=0x24 0x06 %02X %02X %02X %02X)\n", portNo,
|
||||
0x06, 0x80, 0x25, 0x4B) -- DATA part
|
||||
end
|
||||
DSM_send(0x24, 0x06, 0x06, 0x80, 0x25, 0x4B) -- Still Uknown
|
||||
TxInfo_Step = 5
|
||||
elseif (TxInfo_Step == 5) then
|
||||
-- 22,4: 0 0
|
||||
if (DEBUG_ON) then Log.LOG_write("CALL DSM_TxInfo_End(#%d)\n", portNo)
|
||||
end
|
||||
DSM_send(0x22, 0x04, 0x00, 0x00)
|
||||
TxInfo_Step = 0
|
||||
end
|
||||
|
||||
if (TxInfo_Step > 0) then
|
||||
DSM_Context.SendDataToRX = 1 -- keep Transmitig
|
||||
end
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------------------------------------
|
||||
|
||||
local function DSM_sendRequest()
|
||||
-- Send the proper Request message depending on the Phase
|
||||
|
||||
local ctx = DSM_Context
|
||||
if (DEBUG_ON) then Log.LOG_write("%3.3f %s: ", menuLib.getElapsedTime(), menuLib.phase2String(ctx.Phase)) end
|
||||
|
||||
if ctx.Phase == PHASE.RX_VERSION then -- request RX version
|
||||
DSM_getRxVerson()
|
||||
|
||||
elseif ctx.Phase == PHASE.WAIT_CMD then -- keep connection open
|
||||
DSM_sendHeartbeat()
|
||||
|
||||
elseif ctx.Phase == PHASE.MENU_TITLE then -- request menu title
|
||||
if ctx.Menu.MenuId == 0 then -- First time loading a menu ?
|
||||
DSM_getMainMenu()
|
||||
else
|
||||
DSM_getMenu(ctx.Menu.MenuId, ctx.SelLine)
|
||||
|
||||
if (ctx.Menu.MenuId == 0x0001) then -- Executed the Reset Menu??
|
||||
if (DEBUG_ON) then Log.LOG_write("RX Reset!!!\n") end
|
||||
-- Start again retriving RX info
|
||||
ctx.Menu.MenuId = 0
|
||||
ctx.isReset = true
|
||||
ctx.Phase = PHASE.RX_VERSION
|
||||
end
|
||||
end
|
||||
|
||||
elseif ctx.Phase == PHASE.MENU_REQ_TX_INFO then
|
||||
DSM_sentTxInfo(ctx.Menu.MenuId, ctx.CurLine)
|
||||
|
||||
elseif ctx.Phase == PHASE.MENU_LINES then -- request next menu lines
|
||||
if ctx.CurLine == -1 then -- No previous menu line loaded ?
|
||||
DSM_getFirstMenuLine(ctx.Menu.MenuId)
|
||||
else
|
||||
DSM_getNextMenuLine(ctx.Menu.MenuId, ctx.CurLine)
|
||||
end
|
||||
|
||||
elseif ctx.Phase == PHASE.MENU_VALUES then -- request menu values
|
||||
local line = ctx.MenuLines[ctx.CurLine]
|
||||
DSM_getNextMenuValue(ctx.Menu.MenuId, line.ValId, line.Text)
|
||||
|
||||
elseif ctx.Phase == PHASE.VALUE_CHANGING then -- send value
|
||||
local line = ctx.MenuLines[ctx.SelLine] -- Updated Value of SELECTED line
|
||||
|
||||
if (Change_Step==0) then
|
||||
DSM_updateMenuValue(line.ValId, line.Val, line.Text, line)
|
||||
|
||||
if line.Type == menuLib.LINE_TYPE.LIST_MENU then -- Validation on every Step??
|
||||
Change_Step=1; ctx.SendDataToRX=1 -- Send inmediatly after
|
||||
else
|
||||
ctx.Phase = PHASE.VALUE_CHANGING_WAIT
|
||||
end
|
||||
else
|
||||
DSM_validateMenuValue(line.ValId, line.Text, line)
|
||||
Change_Step=0
|
||||
ctx.Phase = PHASE.VALUE_CHANGING_WAIT
|
||||
end
|
||||
|
||||
elseif ctx.Phase == PHASE.VALUE_CHANGING_WAIT then
|
||||
local line = ctx.MenuLines[ctx.SelLine]
|
||||
DSM_editingValue(line.lineNum, line.Text, line)
|
||||
elseif ctx.Phase == PHASE.VALUE_CHANGE_END then -- send value
|
||||
local line = ctx.MenuLines[ctx.SelLine] -- Update Value of SELECTED line
|
||||
|
||||
if (Change_Step==0) then
|
||||
DSM_updateMenuValue(line.ValId, line.Val, line.Text, line)
|
||||
Change_Step=1; ctx.SendDataToRX=1 -- Send inmediatly after
|
||||
elseif (Change_Step==1) then
|
||||
DSM_validateMenuValue(line.ValId, line.Text, line)
|
||||
Change_Step=2; ctx.SendDataToRX=1 -- Send inmediatly after
|
||||
else
|
||||
DSM_editingValueEnd(line.lineNum, line.Text, line)
|
||||
Change_Step=0
|
||||
ctx.Phase = PHASE.WAIT_CMD
|
||||
end
|
||||
elseif ctx.Phase == PHASE.EXIT then
|
||||
if (DEBUG_ON) then Log.LOG_write("CALL DSM_TX_Exit()\n") end
|
||||
DSM_send(0x1F, 0x02, 0xFF, 0xFF) -- 0xAA
|
||||
end
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------------------------------------
|
||||
-- Parsing Responses
|
||||
|
||||
local function DSM_parseRxVersion()
|
||||
--ex: 0x09 0x01 0x00 0x15 0x02 0x22 0x01 0x00 0x14 v2.22.1 00 14?? 8ch SAFE
|
||||
-- 0x09 0x01 0x00 0x18 0x05 0x06 0x34 0x00 0x12 v5.6.52 00 12??? 6ch FC6250
|
||||
local rxId = multiBuffer(13)
|
||||
DSM_Context.RX.Id = rxId
|
||||
DSM_Context.RX.Name = menuLib.Get_RxName(rxId)
|
||||
DSM_Context.RX.Version = multiBuffer(14) .. "." .. multiBuffer(15) .. "." .. multiBuffer(16)
|
||||
if (DEBUG_ON) then Log.LOG_write("RESPONSE Receiver=%s Version %s Cap:0x%02X\n",
|
||||
DSM_Context.RX.Name, DSM_Context.RX.Version, multiBuffer(18)) end
|
||||
end
|
||||
|
||||
local function DSM_parseMenu()
|
||||
--ex: 0x09 0x02 0x4F 0x10 0xA5 0x00 0x00 0x00 0x50 0x10 0x10 0x10 0x00 0x00 0x00 0x00
|
||||
-- MenuID TextID PrevID NextID BackID
|
||||
local ctx = DSM_Context
|
||||
local menu = ctx.Menu
|
||||
menu.MenuId = Dsm_to_Int16(multiBuffer(12), multiBuffer(13))
|
||||
menu.TextId = Dsm_to_Int16(multiBuffer(14), multiBuffer(15))
|
||||
menu.Text = menuLib.Get_Text(menu.TextId)
|
||||
menu.PrevId = Dsm_to_Int16(multiBuffer(16), multiBuffer(17))
|
||||
menu.NextId = Dsm_to_Int16(multiBuffer(18), multiBuffer(19))
|
||||
menu.BackId = Dsm_to_Int16(multiBuffer(20), multiBuffer(21))
|
||||
for i = 0, MAX_MENU_LINES do -- clear menu
|
||||
ctx.MenuLines[i] = { MenuId = 0, lineNum = 0, Type = 0, Text = "", TextId = 0, ValId = 0, Min=0, Max=0, Def=0, Val=nil }
|
||||
end
|
||||
ctx.CurLine = -1
|
||||
|
||||
menuLib.MenuPostProcessing(menu)
|
||||
|
||||
if (DEBUG_ON) then Log.LOG_write("RESPONSE Menu: %s\n", menuLib.menu2String(menu)) end
|
||||
return menu
|
||||
end
|
||||
|
||||
|
||||
local function DSM_parseMenuLine()
|
||||
--ex: 0x09 0x03 0x00 0x10 0x00 0x1C 0xF9 0x00 0x10 0x10 0x00 0x00 0x00 0x00 0x03 0x00
|
||||
--ex: 0x09 0x03 0x61 0x10 0x00 0x6C 0x50 0x00 0x00 0x10 0x36 0x00 0x49 0x00 0x36 0x00
|
||||
--ex: 0x09 0x03 0x65 0x10 0x00 0x0C 0x51 0x00 0x00 0x10 0x00 0x00 0xF4 0x00 0x2E 0x00
|
||||
-- MenuLSB MenuMSB line Type TextID NextLSB NextMSB Val_Min Val_Max Val_Def
|
||||
|
||||
local ctx = DSM_Context
|
||||
local i = multiBuffer(14)
|
||||
local type = multiBuffer(15)
|
||||
local line = ctx.MenuLines[i]
|
||||
|
||||
-- are we trying to override existing line
|
||||
if (line.Type > 0 and type == 0) then
|
||||
if (DEBUG_ON) then Log.LOG_write("RESPONSE MenuLine: ERROR. Trying to ZERO Override: %s\n", menuLib.menuLine2String(line)) end
|
||||
return ctx.MenuLines[ctx.CurLine]
|
||||
end
|
||||
|
||||
ctx.CurLine = i
|
||||
|
||||
line.lineNum = i
|
||||
line.MenuId = Dsm_to_Int16(multiBuffer(12), multiBuffer(13))
|
||||
line.Type = type
|
||||
line.TextId = Dsm_to_Int16(multiBuffer(16), multiBuffer(17))
|
||||
line.Text = nil -- Fill at Post processing
|
||||
line.ValId = Dsm_to_Int16(multiBuffer(18), multiBuffer(19))
|
||||
|
||||
-- Singed int values
|
||||
line.Min = Dsm_to_SInt16(multiBuffer(20), multiBuffer(21))
|
||||
line.Max = Dsm_to_SInt16(multiBuffer(22), multiBuffer(23))
|
||||
line.Def = Dsm_to_SInt16(multiBuffer(24), multiBuffer(25))
|
||||
|
||||
line.Val=nil
|
||||
|
||||
menuLib.MenuLinePostProcessing(line)
|
||||
|
||||
if (DEBUG_ON) then Log.LOG_write("RESPONSE MenuLine: %s\n", menuLib.menuLine2String(line)) end
|
||||
|
||||
if (line.MenuId~=ctx.Menu.MenuId) then
|
||||
-- Going Back too fast: Stil receiving lines from previous menu
|
||||
ctx.Menu.MenuId = line.MenuId
|
||||
Log.LOG_write("WARNING: Overriding current Menu from Line\n")
|
||||
end
|
||||
|
||||
return line
|
||||
end
|
||||
|
||||
local function DSM_parseMenuValue()
|
||||
--ex: 0x09 0x04 0x53 0x10 0x00 0x10 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
--ex: 0x09 0x04 0x61 0x10 0x02 0x10 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
-- MenuLSB MenuMSB ValLSB ValMSB V_LSB V_MSB
|
||||
|
||||
-- Identify the line and update the value
|
||||
local ctx = DSM_Context
|
||||
local menuId = Dsm_to_Int16(multiBuffer(12), multiBuffer(13))
|
||||
local valId = Dsm_to_Int16(multiBuffer(14), multiBuffer(15))
|
||||
local value = Dsm_to_SInt16(multiBuffer(16), multiBuffer(17)) --Signed int
|
||||
|
||||
local updatedLine = nil
|
||||
for i = 0, MAX_MENU_LINES do -- Find the menu line for this value
|
||||
local line = ctx.MenuLines[i]
|
||||
if line ~= nil and line.Type ~= 0 then
|
||||
if line.Type ~= LINE_TYPE.MENU and line.ValId == valId then -- identifier of ValueId stored in the line
|
||||
line.Val = value
|
||||
ctx.CurLine = i
|
||||
updatedLine = line
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if (updatedLine == nil) then
|
||||
if (DEBUG_ON) then Log.LOG_write("RESPONSE MenuValue: ERROR, Cant find Menu Line with MenuId=%X, ValID=%X to update\n", menuId, valId) end
|
||||
else
|
||||
if (DEBUG_ON) then Log.LOG_write("RESPONSE MenuValue: UPDATED: %s\n", menuLib.menuLine2String(updatedLine))
|
||||
end
|
||||
end
|
||||
return updatedLine ~= nil
|
||||
end
|
||||
|
||||
local function DSM_parseReqTxInfo()
|
||||
local portNo = multiBuffer(12)
|
||||
TxInfo_Type = multiBuffer(13)
|
||||
if (DEBUG_ON) then Log.LOG_write("RESPONSE ReqTXChannelInfo(#%d %s InfoType=0x%0X)\n",
|
||||
portNo, MODEL.PORT_TEXT[portNo], TxInfo_Type) end
|
||||
|
||||
TxInfo_Step = 0
|
||||
|
||||
return portNo
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
local function DSM_processResponse()
|
||||
local ctx = DSM_Context
|
||||
local cmd = multiBuffer(11) -- Response Command
|
||||
|
||||
if (DEBUG_ON > 1) then Log.LOG_write("%s: RESPONSE %s \n", menuLib.phase2String(ctx.Phase), multiBuffer2String()) end
|
||||
if (DEBUG_ON and cmd > 0x00) then Log.LOG_write("%3.3f %s: ", menuLib.getElapsedTime(), menuLib.phase2String(ctx.Phase)) end
|
||||
|
||||
if cmd == 0x01 then -- read version
|
||||
DSM_parseRxVersion()
|
||||
--Lib.Init_Text(DSM_Context.RX.Id)
|
||||
ctx.isReset = false -- no longer resetting
|
||||
ctx.Phase = PHASE.MENU_TITLE
|
||||
ctx.Menu.MenuId = 0
|
||||
|
||||
elseif cmd == 0x02 then -- read menu title
|
||||
local menu = DSM_parseMenu()
|
||||
|
||||
-- Update Selected Line navigation
|
||||
if menu.NextId ~= 0 then
|
||||
ctx.SelLine = NEXT_BUTTON -- highlight Next
|
||||
else
|
||||
ctx.SelLine = BACK_BUTTON -- highlight Back
|
||||
end
|
||||
|
||||
if (ctx.Menu.MenuId == 0x0001) then -- Still in RESETTING MENU???
|
||||
-- Star from Start
|
||||
if (DEBUG_ON) then Log.LOG_write("RX Reset: Still not done, restart again!!!\n") end
|
||||
ctx.Menu.MenuId = 0
|
||||
ctx.Phase = PHASE.RX_VERSION
|
||||
else
|
||||
ctx.Phase = PHASE.MENU_LINES
|
||||
end
|
||||
|
||||
|
||||
elseif cmd == 0x03 then -- menu lines
|
||||
local line = DSM_parseMenuLine()
|
||||
|
||||
-- Update Selected line navigation
|
||||
if (ctx.SelLine == BACK_BUTTON or ctx.SelLine == NEXT_BUTTON or ctx.SelLine == PREV_BUTTON)
|
||||
and menuLib.isSelectableLine(line) then -- Auto select the current line
|
||||
ctx.SelLine = line.lineNum
|
||||
end
|
||||
|
||||
ctx.Phase = PHASE.MENU_LINES
|
||||
|
||||
elseif cmd == 0x04 then -- read menu values
|
||||
if DSM_parseMenuValue() then
|
||||
ctx.Phase = PHASE.MENU_VALUES
|
||||
else
|
||||
ctx.Phase = PHASE.WAIT_CMD
|
||||
end
|
||||
|
||||
elseif cmd == 0x05 then -- Request TX Info
|
||||
local portNo = DSM_parseReqTxInfo()
|
||||
ctx.CurLine = portNo
|
||||
ctx.Phase = PHASE.MENU_REQ_TX_INFO
|
||||
|
||||
elseif cmd == 0xA7 then -- answer to EXIT command
|
||||
if (DEBUG_ON) then Log.LOG_write("RESPONSE RX Exit\n") end
|
||||
if (ctx.Phase==PHASE.EXIT) then -- Expected RX Exit
|
||||
ctx.Phase = PHASE.EXIT_DONE
|
||||
else -- UnExpected RX Exit
|
||||
DSM_ReleaseConnection()
|
||||
error("RX Connection Drop")
|
||||
end
|
||||
|
||||
elseif cmd == 0x00 then -- NULL response (or RX heartbeat)
|
||||
-- 09 00 01 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
-- 09 00 7E 00 20 9E 28 00 20 9E 28 00 20 8D 7E : After TX Heartbeat one of this (FC6250)
|
||||
-- 09 00 18 00 20 08 00 00 00 08 00 00 00 98 AE AR8360T
|
||||
if (DEBUG_ON) then Log.LOG_write("%3.3f %s: RESPONSE RX Heartbeat --Context: 0x%02X\n",
|
||||
menuLib.getElapsedTime(), menuLib.phase2String(ctx.Phase), multiBuffer(12)) end
|
||||
else
|
||||
if (DEBUG_ON) then Log.LOG_write("RESPONSE Unknown Command (0x%X) DATA=%s\n", cmd, multiBuffer2String()) end
|
||||
end
|
||||
|
||||
return cmd
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
local function DSM_Send_Receive()
|
||||
local ctx = DSM_Context
|
||||
|
||||
-- Receive part: Process incoming messages if there is nothing to send
|
||||
if ctx.SendDataToRX == 0 and multiBuffer(10) == 0x09 then
|
||||
local cmd = DSM_processResponse()
|
||||
|
||||
multiBuffer(10, 0x00) -- Clear Response Buffer to know that we are done with the response
|
||||
RXInactivityTime = getTime() + SEND_TIMEOUT*4 -- Reset RX Inactivity timeout
|
||||
|
||||
if (cmd > 0x00) then -- RX HeartBeat ??
|
||||
-- Only change to SEND mode if we received a valid response (Ignore heartbeat)
|
||||
ctx.SendDataToRX = 1
|
||||
ctx.Refresh_Display = true
|
||||
end
|
||||
else
|
||||
if (getTime() > RXInactivityTime and ctx.Phase ~= PHASE.RX_VERSION and ctx.Phase ~= PHASE.EXIT_DONE) then
|
||||
if (ctx.isEditing()) then -- If Editing, Extend Timeout
|
||||
RXInactivityTime = getTime() + SEND_TIMEOUT*4
|
||||
else
|
||||
if (DEBUG_ON) then Log.LOG_write("%3.3f %s: RX INACTIVITY TIMEOUT\n", menuLib.getElapsedTime(), menuLib.phase2String(ctx.Phase)) end
|
||||
DSM_ReleaseConnection()
|
||||
error("RX Disconnected")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-----TX Part --------------------------------------
|
||||
if ctx.SendDataToRX == 1 then -- Need to send a request
|
||||
ctx.SendDataToRX = 0
|
||||
DSM_sendRequest()
|
||||
TXInactivityTime = getTime() + SEND_TIMEOUT -- Reset Inactivity timeout
|
||||
else
|
||||
-- Check if enouth time has passed from last transmit/receive activity
|
||||
if getTime() > TXInactivityTime then
|
||||
ctx.SendDataToRX = 1 -- Switch to Send mode to send heartbeat
|
||||
ctx.Refresh_Display = true
|
||||
|
||||
-- Only change to WAIT_CMD if we are NOT wating for RX version
|
||||
if ctx.Phase ~= PHASE.RX_VERSION then
|
||||
-- Phase = If IsEditing then VALUE_CHANGING_WAIT else WAIT_CMD
|
||||
ctx.Phase = (ctx.isEditing() and PHASE.VALUE_CHANGING_WAIT) or PHASE.WAIT_CMD
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Init
|
||||
local function DSM_Init(toolName)
|
||||
local dateTime = getDateTime()
|
||||
local dateStr = dateTime.year.."-"..dateTime.mon.."-"..dateTime.day.." "..dateTime.hour..":"..dateTime.min
|
||||
|
||||
local ver, radio, maj, minor, rev, osname = getVersion()
|
||||
|
||||
if (osname==nil) then osname = "OpenTX" end -- OTX 2.3.14 and below returns nil
|
||||
|
||||
IS_EDGETX = string.sub(osname,1,1) == 'E'
|
||||
|
||||
if (DEBUG_ON) then
|
||||
Log.LOG_write("---------------DSM New Session %s ----------------\n", toolName, dateStr)
|
||||
Log.LOG_write("Radio Info: %s\n", radio .. " " .. (osname or "OpenTx") .. " " .. ver)
|
||||
Log.LOG_write("Date : %s\n", dateStr)
|
||||
Log.LOG_write("DsmLib Version : %s\n", LIB_VERSION)
|
||||
end
|
||||
end
|
||||
|
||||
local function DSM_Init_Text_Exceptions()
|
||||
-- Apply special restrictions to some Values
|
||||
|
||||
local function getTxChText(ch)
|
||||
return " ("..(MODEL.TX_CH_TEXT[ch] or "--")..")"
|
||||
end
|
||||
|
||||
local List_Values = menuLib.List_Values
|
||||
local List_Text = menuLib.List_Text
|
||||
local Text = menuLib.Text
|
||||
|
||||
Log.LOG_write("Initializing TEXT Exception\n")
|
||||
|
||||
-- Channel selection for SAFE MODE and GAINS on FC6250HX
|
||||
--List_Text[0x000C] = "Inhibit?" --?
|
||||
for i = 0, 7 do
|
||||
List_Text[0x000D + i] = "Ch"..(i+5) ..getTxChText(i+4)
|
||||
end -- Aux channels (Ch5 and Greater)
|
||||
|
||||
-- Servo Output values..
|
||||
local servoOutputValues = {0x0003,0x002D,0x002E,0x002F} --Inh (GAP), 5.5ms, 11ms, 22ms. Fixing L_m1 with 0..244 range!
|
||||
--List_Text[0x002D] = "5.5ms"
|
||||
--[0x002E] = "11ms"
|
||||
--List_Text[0x002F] = "22ms"
|
||||
|
||||
-- Gain Values
|
||||
local gainValues = {0x0032,0x0033,0x0034} -- 1X, 2X, 4X -- Fixing L_m1 with 0..244 range!
|
||||
--List_Text[0x0032] = "1 X"
|
||||
--[0x0033] = "2 X"
|
||||
-- List_Text[0x0034] = "4 X"
|
||||
|
||||
-- List of Channels for Safe, Gains, Panic, except FC6250HX that uses other range (0x00C..0x015)
|
||||
-- the valid range Starts with GEAR if enabled (Thr,Ail,Ele,Rud are not valid, the RX reject them )
|
||||
-- Valid Values: Inhibit? (GAP), Gear,Aux1..Aux7,X-Plus-1..XPlus-8
|
||||
local channelValues = {0x0035,0x0036,0x0037,0x0038,0x0039,0x003A,0x003B,0x003C,0x003D,0x003E,0x003F,
|
||||
0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049}
|
||||
|
||||
--List_Text[0x0035] = "Inhibit?"
|
||||
for i = 0, 11 do
|
||||
List_Text[0x0036 + i] = "Ch"..(i+1) .. getTxChText(i)
|
||||
end -- Channels on AR637T
|
||||
|
||||
for i = 1, 8 do -- 41..49
|
||||
List_Text[0x0041 + i] = "Ch"..(i+12)
|
||||
end
|
||||
|
||||
-- Flight mode channel selection
|
||||
--Text[0x0078] = "FM Channel"
|
||||
List_Values[0x0078]=channelValues
|
||||
|
||||
-- Gain channel selection
|
||||
--Text[0x0089] = "Gain Channel"
|
||||
List_Values[0x0089]=channelValues
|
||||
|
||||
-- Gain Sensitivity selection
|
||||
--Text[0x008A] = "Gain Sensitivity/r";
|
||||
List_Values[0x008A]=gainValues -- Right Alight, (L_M1 was wide open range 0->244)
|
||||
|
||||
-- Safe mode options, Ihnibit + this values
|
||||
local safeModeOptions = {0x0003,0x00B0,0x00B1} -- inh (gap), "Self-Level/Angle Dem, Envelope
|
||||
--List_Text[0x00B0] = "Self-Level/Angle Dem"
|
||||
--List_Text[0x00B1] = "Envelope"
|
||||
|
||||
--Text[0x00D2] = "Panic Channel"
|
||||
List_Values[0x00D2]=channelValues
|
||||
|
||||
--Inh, Self-Level/Angle Dem, Envelope -- (L_M was wide open range 0->244)
|
||||
--Text[0x01F8] = "Safe Mode";
|
||||
List_Values[0x01F8]=safeModeOptions
|
||||
end
|
||||
|
||||
-- Initial Setup
|
||||
local function FP_Init(toolname)
|
||||
DSM_Context.Phase = PHASE.INIT
|
||||
|
||||
DSM_Init(toolname)
|
||||
menuLib.clearAllText()
|
||||
end
|
||||
|
||||
local initStep=0
|
||||
local FileState = {}
|
||||
|
||||
local function Message_Init()
|
||||
lcd.clear()
|
||||
if (initStep == 0) then
|
||||
if (IS_EDGETX) then
|
||||
-- Load all messages at once
|
||||
menuLib.LoadTextFromFile(MSG_FILE,13)
|
||||
initStep=1
|
||||
|
||||
else
|
||||
-- load messages incrementally to avoid "CPU Limit"
|
||||
lcd.drawText(30, 50, "Loading Msg file: "..(FileState.lineNo or 0))
|
||||
if (menuLib.INC_LoadTextFromFile(MSG_FILE, FileState)==1) then
|
||||
initStep=1
|
||||
end
|
||||
end
|
||||
elseif (initStep == 1) then
|
||||
DSM_Init_Text_Exceptions()
|
||||
|
||||
DSM_Context.Phase = PHASE.RX_VERSION
|
||||
DSM_StartConnection()
|
||||
end
|
||||
end
|
||||
|
||||
local function FP_Run()
|
||||
if (DSM_Context.Phase==PHASE.INIT) then
|
||||
Message_Init()
|
||||
return 0
|
||||
end
|
||||
|
||||
return DSM_Send_Receive()
|
||||
end
|
||||
|
||||
local function FP_Done()
|
||||
local ctx = menuLib.DSM_Context
|
||||
ctx.Phase = PHASE.EXIT_DONE
|
||||
DSM_ReleaseConnection()
|
||||
end
|
||||
|
||||
return { init=FP_Init, run=FP_Run, done=FP_Done }
|
||||
33
SCRIPTS/TOOLS/DSMLIB/DsmLogLib.lua
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
local LogLib = { }
|
||||
|
||||
local LOG_FILE = "/LOGS/dsm_log.txt"
|
||||
local logFile = nil
|
||||
local logCount=0
|
||||
|
||||
function LogLib.LOG_open()
|
||||
logFile = io.open(LOG_FILE, "w") -- Truncate Log File
|
||||
end
|
||||
|
||||
function LogLib.LOG_write(...)
|
||||
if (logFile==nil) then LogLib.LOG_open() end
|
||||
local str = string.format(...)
|
||||
|
||||
if (str==nil) then return end
|
||||
|
||||
io.write(logFile, str)
|
||||
|
||||
str = string.gsub(str,"\n"," ") -- Elimitate return from line, since print will do it
|
||||
print(str)
|
||||
|
||||
if (logCount > 10) then -- Close an re-open the file
|
||||
io.close(logFile)
|
||||
logFile = io.open(LOG_FILE, "a")
|
||||
logCount =0
|
||||
end
|
||||
end
|
||||
|
||||
function LogLib.LOG_close()
|
||||
if (logFile~=nil) then io.close(logFile) end
|
||||
end
|
||||
|
||||
return LogLib
|
||||
167
SCRIPTS/TOOLS/DSMLIB/DsmMIN_P1.lua
Normal file
|
|
@ -0,0 +1,167 @@
|
|||
local MODEL, M_DATA, LOG_write = ...
|
||||
|
||||
--[[
|
||||
local MODEL = {
|
||||
modelName = "", -- The name of the model comming from OTX/ETX
|
||||
hashName = "",
|
||||
modelOutputChannel = {}, -- Output information from OTX/ETX
|
||||
|
||||
TX_CH_TEXT= { [0]=""},
|
||||
PORT_TEXT = { [0]=""},
|
||||
|
||||
DSM_ChannelInfo = {} -- Data Created by DSM Configuration Script
|
||||
}
|
||||
|
||||
-- MENU DATA Management
|
||||
local M_DATA = {} -- Store the variables used in the Menus.
|
||||
|
||||
--]]
|
||||
|
||||
local DATA_PATH = "/MODELS/DSMDATA"
|
||||
local TX_CHANNELS = 12
|
||||
|
||||
local MV_DATA_END = 1040
|
||||
|
||||
|
||||
local function hashName(mName)
|
||||
local c=10000;
|
||||
|
||||
local prefix = string.gsub(mName,"%.","_") -- Change any "." to "_"
|
||||
prefix = string.gsub(prefix,"% ","_") -- Change any space to "_"
|
||||
prefix = string.sub(prefix,1,5) -- Take the first 5 characters
|
||||
|
||||
-- Simple Hash of the Model Name adding each character
|
||||
for i = 1, #mName do
|
||||
local ch = string.byte(mName,i,i)
|
||||
c=c+ch
|
||||
end
|
||||
|
||||
return (prefix .. c) -- Return Prefix + Hash
|
||||
end
|
||||
|
||||
-- Load Menu Data from a file
|
||||
local function ST_LoadFileData()
|
||||
local fname = hashName(MODEL.modelName)..".txt"
|
||||
MODEL.hashName = fname
|
||||
|
||||
-- Clear Menu Data
|
||||
for i = 0, MV_DATA_END do
|
||||
M_DATA[i]=nil
|
||||
end
|
||||
|
||||
print("Loading File:"..fname)
|
||||
|
||||
local dataFile = io.open(DATA_PATH .. "/".. fname, "r") -- read File
|
||||
-- cannot read file???
|
||||
if (dataFile==nil) then return 0 end
|
||||
|
||||
local line = io.read(dataFile, 5000)
|
||||
io.close(dataFile)
|
||||
|
||||
if #line == 0 then return 0 end -- No data??
|
||||
|
||||
-- Process the input, each line is "Var_Id : Value" format
|
||||
-- Store it into MANU_DATA
|
||||
local i=0
|
||||
for k, v in string.gmatch(line, "(%d+):(%d+)") do
|
||||
M_DATA[k+0]=v+0 -- do aritmentic to convert string to number
|
||||
i=i+1
|
||||
end
|
||||
|
||||
-- Return 0 if no lines processed, 1 otherwise
|
||||
if (i > 0) then return 1 else return 0 end
|
||||
end
|
||||
|
||||
local function getModuleChannelOrder(num)
|
||||
--Determine fist 4 channels order
|
||||
local ch_n={}
|
||||
local st_n = {[0]= "R", "E", "T", "A" }
|
||||
local c_ord=num -- ch order
|
||||
if (c_ord == -1) then
|
||||
ch_n[0] = st_n[3]
|
||||
ch_n[1] = st_n[1]
|
||||
ch_n[2] = st_n[2]
|
||||
ch_n[3] = st_n[0]
|
||||
else
|
||||
ch_n[bit32.band(c_ord,3)] = st_n[3]
|
||||
c_ord = math.floor(c_ord/4)
|
||||
ch_n[bit32.band(c_ord,3)] = st_n[1]
|
||||
c_ord = math.floor(c_ord/4)
|
||||
ch_n[bit32.band(c_ord,3)] = st_n[2]
|
||||
c_ord = math.floor(c_ord/4)
|
||||
ch_n[bit32.band(c_ord,3)] = st_n[0]
|
||||
end
|
||||
|
||||
local s = ""
|
||||
for i=0,3 do
|
||||
s=s..ch_n[i]
|
||||
end
|
||||
return s
|
||||
end
|
||||
|
||||
local function ReadTxModelData()
|
||||
local TRANSLATE_AETR_TO_TAER=false
|
||||
local table = model.getInfo() -- Get the model name
|
||||
MODEL.modelName = table.name
|
||||
|
||||
local module = model.getModule(0) -- Internal
|
||||
if (module==nil or module.Type~=6) then module = model.getModule(1) end -- External
|
||||
if (module~=nil) then
|
||||
if (module.Type==6 ) then -- MULTI-MODULE
|
||||
local chOrder = module.channelsOrder
|
||||
local s = getModuleChannelOrder(chOrder)
|
||||
LOG_write("MultiChannel Ch Order: [%s] %s\n",chOrder,s)
|
||||
|
||||
if (s=="AETR") then TRANSLATE_AETR_TO_TAER=true
|
||||
else TRANSLATE_AETR_TO_TAER=false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Read Ch1 to Ch10
|
||||
local i= 0
|
||||
for i = 0, TX_CHANNELS-1 do
|
||||
local ch = model.getOutput(i) -- Zero base
|
||||
if (ch~=nil) then
|
||||
MODEL.modelOutputChannel[i] = ch
|
||||
if (string.len(ch.name)==0) then
|
||||
ch.formatCh = string.format("TX:Ch%i",i+1)
|
||||
else
|
||||
ch.formatCh = string.format("TX:Ch%i/%s",i+1,ch.name or "--")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Translate AETR to TAER
|
||||
|
||||
if (TRANSLATE_AETR_TO_TAER) then
|
||||
LOG_write("Applying AETR -> TAER translation\n")
|
||||
local ail = MODEL.modelOutputChannel[0]
|
||||
local elv = MODEL.modelOutputChannel[1]
|
||||
local thr = MODEL.modelOutputChannel[2]
|
||||
|
||||
MODEL.modelOutputChannel[0] = thr
|
||||
MODEL.modelOutputChannel[1] = ail
|
||||
MODEL.modelOutputChannel[2] = elv
|
||||
end
|
||||
|
||||
-- Create the Port Text to be used
|
||||
LOG_write("Ports/Channels:\n")
|
||||
for i = 0, TX_CHANNELS-1 do
|
||||
local ch = MODEL.modelOutputChannel[i]
|
||||
if (ch~=nil) then
|
||||
MODEL.TX_CH_TEXT[i] = ch.formatCh
|
||||
MODEL.PORT_TEXT[i] = string.format("P%i (%s) ",i+1,MODEL.TX_CH_TEXT[i])
|
||||
LOG_write("Port%d %s [%d,%d] Rev=%d, Off=%d, ppmC=%d, syn=%d\n",i+1,MODEL.TX_CH_TEXT[i],math.floor(ch.min/10),math.floor(ch.max/10), ch.revert, ch.offset, ch.ppmCenter, ch.symetrical)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Main Program
|
||||
|
||||
LOG_write("Reading Model Info\n")
|
||||
ReadTxModelData()
|
||||
local r = ST_LoadFileData()
|
||||
return r
|
||||
|
||||
|
||||
282
SCRIPTS/TOOLS/DSMLIB/DsmMIN_P2.lua
Normal file
|
|
@ -0,0 +1,282 @@
|
|||
local MODEL, M_DATA, LOG_write = ...
|
||||
|
||||
--[[
|
||||
local MODEL = {
|
||||
modelName = "", -- The name of the model comming from OTX/ETX
|
||||
hashName = "",
|
||||
modelOutputChannel = {}, -- Output information from OTX/ETX
|
||||
|
||||
TX_CH_TEXT= { [0]=""},
|
||||
PORT_TEXT = { [0]=""},
|
||||
|
||||
DSM_ChannelInfo = {} -- Data Created by DSM Configuration Script
|
||||
}
|
||||
|
||||
-- MENU DATA Management
|
||||
local M_DATA = {} -- Store the variables used in the Menus.
|
||||
|
||||
--]]
|
||||
|
||||
|
||||
local TX_CHANNELS = 12
|
||||
|
||||
local AT_PLANE = 0
|
||||
|
||||
local aircraft_type_text = {[0]="Plane","Heli","Glider","Drone"}
|
||||
|
||||
--[[
|
||||
local WT_A1 = 0
|
||||
local WT_A2 = 1
|
||||
local WT_FLPR = 2
|
||||
local WT_A1_F1 = 3
|
||||
local WT_A2_F1 = 4
|
||||
local WT_A2_F2 = 5
|
||||
--]]
|
||||
local WT_ELEVON_A = 6
|
||||
local WT_ELEVON_B = 7
|
||||
|
||||
local wing_type_text = {[0]="Normal","Dual Ail","Flapperon", "Ail + Flp","Dual Ail + Flp","Dual Ail/Flp","Elevon A","Elevon B"}
|
||||
|
||||
--[[
|
||||
local TT_R1 = 0
|
||||
local TT_R1_E1 = 1
|
||||
local TT_R1_E2 = 2
|
||||
local TT_R2_E1 = 3
|
||||
local TT_R2_E2 = 4
|
||||
--]]
|
||||
|
||||
local TT_VT_A = 5
|
||||
local TT_VT_B = 6
|
||||
local TT_TLRN_A = 7
|
||||
local TT_TLRN_B = 8
|
||||
local TT_TLRN_A_R2 = 9
|
||||
local TT_TLRN_B_R2 = 10
|
||||
|
||||
local tail_type_text = {[0]="Rud Only","Normal","Rud + Dual Ele","Dual Rud + Elv","Dual Rud/Ele",
|
||||
"VTail A","VTail B","Taileron A","Taileron B","Taileron A + Dual Rud","Taileron B + Dual Rud"}
|
||||
|
||||
|
||||
local MV_AIRCRAFT_TYPE = 1001
|
||||
local MV_WING_TYPE = 1002
|
||||
local MV_TAIL_TYPE = 1003
|
||||
|
||||
local MV_CH_BASE = 1010
|
||||
local MV_CH_THR = 1010
|
||||
local MV_CH_L_AIL = 1011
|
||||
local MV_CH_R_AIL = 1012
|
||||
local MV_CH_L_FLP = 1013
|
||||
local MV_CH_R_FLP = 1014
|
||||
|
||||
local MV_CH_L_RUD = 1015
|
||||
local MV_CH_R_RUD = 1016
|
||||
local MV_CH_L_ELE = 1017
|
||||
local MV_CH_R_ELE = 1018
|
||||
|
||||
local MV_PORT_BASE = 1020
|
||||
|
||||
local MV_DATA_END = 1040
|
||||
|
||||
--Channel Types --
|
||||
local CT_NONE = 0x00
|
||||
local CT_AIL = 0x01
|
||||
local CT_ELE = 0x02
|
||||
local CT_RUD = 0x04
|
||||
local CT_REVERSE = 0x20
|
||||
local CT_THR = 0x40
|
||||
local CT_SLAVE = 0x80
|
||||
|
||||
-- Seems like Reverse Mix is complement of the 3 bits
|
||||
local CMT_NORM = 0x00 -- 0000
|
||||
local CMT_AIL = 0x10 -- 0001 Taileron
|
||||
local CMT_ELE = 0x20 -- 0010 For VTIAL and Delta-ELEVON
|
||||
local CMT_RUD = 0x30 -- 0011 For VTIAL
|
||||
local CMT_RUD_REV = 0x40 -- 0100 For VTIAL
|
||||
local CMT_ELE_REV = 0x50 -- 0101 For VTIAL and Delta-ELEVON A
|
||||
local CMT_AIL_REV = 0x60 -- 0110 Taileron
|
||||
local CMT_NORM_REV = 0x70 -- 0111
|
||||
|
||||
local MT_NORMAL = 0
|
||||
local MT_REVERSE = 1
|
||||
|
||||
local function channelType2String(byte1, byte2)
|
||||
local s = ""
|
||||
|
||||
if (byte2==0) then return s end;
|
||||
|
||||
if (bit32.band(byte2,CT_AIL)>0) then s=s.."Ail" end
|
||||
if (bit32.band(byte2,CT_ELE)>0) then s=s.."Ele" end
|
||||
if (bit32.band(byte2,CT_RUD)>0) then s=s.."Rud" end
|
||||
if (bit32.band(byte2,CT_THR)>0) then s=s.."Thr" end
|
||||
|
||||
if (bit32.band(byte2,CT_REVERSE)>0) then s=s.."-" end
|
||||
|
||||
if (bit32.band(byte2,CT_SLAVE)>0) then s=s.." Slv" end
|
||||
|
||||
if (byte1==CMT_NORM) then s=s.." "
|
||||
elseif (byte1==CMT_AIL) then s=s.." M_Ail"
|
||||
elseif (byte1==CMT_ELE) then s=s.." M_Ele"
|
||||
elseif (byte1==CMT_RUD) then s=s.." M_Rud"
|
||||
elseif (byte1==CMT_RUD_REV) then s=s.." M_Rud-"
|
||||
elseif (byte1==CMT_ELE_REV) then s=s.." M_Ele-"
|
||||
elseif (byte1==CMT_AIL_REV) then s=s.." M_Ail-"
|
||||
elseif (byte1==CMT_NORM_REV) then s=s.." M-"
|
||||
end
|
||||
|
||||
return s;
|
||||
end
|
||||
|
||||
-- This Creates the Servo Settings that will be used to pass to
|
||||
-- Forward programming
|
||||
local function CreateDSMPortChannelInfo()
|
||||
local function ApplyWingMixA(b2)
|
||||
-- ELEVON
|
||||
if (b2==CT_AIL+CT_ELE) then return CMT_ELE end; -- 0x03
|
||||
if (b2==CT_AIL+CT_ELE+CT_SLAVE) then return CMT_NORM end; -- 0x83
|
||||
end
|
||||
|
||||
local function ApplyWingMixB(b2)
|
||||
-- ELEVON
|
||||
if (b2==CT_AIL+CT_ELE) then return CMT_NORM end; -- 0x03
|
||||
if (b2==CT_AIL+CT_ELE+CT_SLAVE) then return CMT_ELE end; -- 0x83
|
||||
end
|
||||
|
||||
local function ApplyTailMixA(b2)
|
||||
-- VTAIL
|
||||
-- Default normal/reverse behaviour
|
||||
if (b2==CT_RUD+CT_ELE) then return CMT_NORM end; -- 0x06
|
||||
if (b2==CT_RUD+CT_ELE+CT_SLAVE) then return CMT_ELE end; -- 0x86
|
||||
|
||||
--TAILERON
|
||||
-- Default normal/reverse behaviour
|
||||
if (b2==CT_AIL+CT_ELE) then return CMT_NORM end; -- 0x03
|
||||
if (b2==CT_AIL+CT_ELE+CT_SLAVE) then return CMT_AIL end; -- 0x83
|
||||
end
|
||||
|
||||
local function ApplyTailMixB(b2)
|
||||
-- VTAIL
|
||||
-- Default normal/reverse behaviour
|
||||
if (b2==CT_RUD+CT_ELE) then return CMT_NORM end; -- 0x06
|
||||
if (b2==CT_RUD+CT_ELE+CT_SLAVE) then return CMT_RUD end; -- 0x86
|
||||
|
||||
--TAILERON
|
||||
if (b2==CT_AIL+CT_ELE) then return CMT_AIL end; -- 0x03
|
||||
if (b2==CT_AIL+CT_ELE+CT_SLAVE) then return CMT_NORM end; -- 0x83
|
||||
end
|
||||
|
||||
local function reverseMix(b)
|
||||
if (b==CMT_NORM) then return CMT_NORM_REV end;
|
||||
if (b==CMT_AIL) then return CMT_AIL_REV end;
|
||||
if (b==CMT_ELE) then return CMT_ELE_REV end;
|
||||
if (b==CMT_RUD) then return CMT_RUD_REV end;
|
||||
return b
|
||||
end
|
||||
|
||||
local DSM_Ch = MODEL.DSM_ChannelInfo
|
||||
|
||||
for i=0, TX_CHANNELS-1 do
|
||||
DSM_Ch[i] = {[0]= CMT_NORM, CT_NONE, nil} -- Initialize with no special function
|
||||
end
|
||||
|
||||
--local aircraftType = M_DATA[MV_AIRCRAFT_TYPE]
|
||||
local wingType = M_DATA[MV_WING_TYPE]
|
||||
local tailType = M_DATA[MV_TAIL_TYPE]
|
||||
|
||||
local thrCh = M_DATA[MV_CH_THR]
|
||||
local lAilCh = M_DATA[MV_CH_L_AIL]
|
||||
local rAilCh = M_DATA[MV_CH_R_AIL]
|
||||
|
||||
local lElevCh = M_DATA[MV_CH_L_ELE]
|
||||
local rElevCh = M_DATA[MV_CH_R_ELE]
|
||||
|
||||
local lRudCh = M_DATA[MV_CH_L_RUD]
|
||||
local rRudCh = M_DATA[MV_CH_R_RUD]
|
||||
|
||||
-- Channels in menu vars are Zero base, Channel info is 1 based
|
||||
|
||||
-- THR
|
||||
if (thrCh~=nil and thrCh < 10) then DSM_Ch[thrCh][1]= CT_THR end
|
||||
|
||||
-- AIL (Left and Right)
|
||||
if (lAilCh~=nil) then DSM_Ch[lAilCh][1] = CT_AIL end
|
||||
if (rAilCh~=nil) then DSM_Ch[rAilCh][1] = CT_AIL+CT_SLAVE end
|
||||
-- ELE (Left and Right)
|
||||
if (lElevCh~=nil) then DSM_Ch[lElevCh][1] = CT_ELE end
|
||||
if (rElevCh~=nil) then DSM_Ch[rElevCh][1] = CT_ELE+CT_SLAVE end
|
||||
-- RUD (Left and Right)
|
||||
if (lRudCh~=nil) then DSM_Ch[lRudCh][1] = CT_RUD end
|
||||
if (rRudCh~=nil) then DSM_Ch[rRudCh][1] = CT_RUD+CT_SLAVE end
|
||||
|
||||
-- VTAIL: RUD + ELE
|
||||
if (tailType==TT_VT_A) then
|
||||
DSM_Ch[lElevCh][1] = CT_RUD+CT_ELE
|
||||
DSM_Ch[rElevCh][1] = CT_RUD+CT_ELE+CT_SLAVE
|
||||
elseif (tailType==TT_VT_B) then
|
||||
DSM_Ch[lElevCh][1] = CT_RUD+CT_ELE+CT_SLAVE
|
||||
DSM_Ch[rElevCh][1] = CT_RUD+CT_ELE
|
||||
end
|
||||
|
||||
-- TAILERRON: 2-ELE + AIL
|
||||
if (tailType==TT_TLRN_A or tailType==TT_TLRN_A_R2) then
|
||||
DSM_Ch[lElevCh][1] = CT_AIL+CT_ELE
|
||||
DSM_Ch[rElevCh][1] = CT_AIL+CT_ELE+CT_SLAVE
|
||||
elseif (tailType==TT_TLRN_B or tailType==TT_TLRN_B_R2) then
|
||||
DSM_Ch[lElevCh][1] = CT_AIL+CT_ELE+CT_SLAVE
|
||||
DSM_Ch[rElevCh][1] = CT_AIL+CT_ELE
|
||||
end
|
||||
|
||||
---- ELEVON : AIL + ELE
|
||||
if (wingType==WT_ELEVON_A) then
|
||||
DSM_Ch[lAilCh][1] = CT_AIL+CT_ELE
|
||||
DSM_Ch[rAilCh][1] = CT_AIL+CT_ELE+CT_SLAVE
|
||||
elseif (wingType==WT_ELEVON_B) then
|
||||
DSM_Ch[lAilCh][1] = CT_AIL+CT_ELE+CT_SLAVE
|
||||
DSM_Ch[rAilCh][1] = CT_AIL+CT_ELE
|
||||
end
|
||||
|
||||
------MIXES ---------
|
||||
|
||||
-- TAIL Mixes (Elevator and VTail)
|
||||
if (tailType==TT_VT_A or tailType==TT_TLRN_A or tailType==TT_TLRN_A_R2) then
|
||||
DSM_Ch[lElevCh][0] = ApplyTailMixA(DSM_Ch[lElevCh][1])
|
||||
DSM_Ch[rElevCh][0] = ApplyTailMixA(DSM_Ch[rElevCh][1])
|
||||
elseif (tailType==TT_VT_B or tailType==TT_TLRN_B or tailType==TT_TLRN_B_R2) then
|
||||
DSM_Ch[lElevCh][0] = ApplyTailMixB(DSM_Ch[lElevCh][1])
|
||||
DSM_Ch[rElevCh][0] = ApplyTailMixB(DSM_Ch[rElevCh][1])
|
||||
end
|
||||
|
||||
---- ELEVON : AIL + ELE
|
||||
if (wingType==WT_ELEVON_A) then
|
||||
DSM_Ch[lAilCh][0] = ApplyWingMixA(DSM_Ch[lAilCh][1])
|
||||
DSM_Ch[rAilCh][0] = ApplyWingMixA(DSM_Ch[rAilCh][1])
|
||||
elseif (wingType==WT_ELEVON_B) then
|
||||
DSM_Ch[lAilCh][0] = ApplyWingMixB(DSM_Ch[lAilCh][1])
|
||||
DSM_Ch[rAilCh][0] = ApplyWingMixB(DSM_Ch[rAilCh][1])
|
||||
end
|
||||
|
||||
-- Apply Gyro Reverse as needed for each channel as long as it is used
|
||||
for i=0, TX_CHANNELS-1 do
|
||||
if (M_DATA[MV_PORT_BASE+i]==MT_REVERSE and DSM_Ch[i][1]>0) then
|
||||
DSM_Ch[i][0]=reverseMix(DSM_Ch[i][0])
|
||||
DSM_Ch[i][1]=DSM_Ch[i][1]+CT_REVERSE
|
||||
end
|
||||
end
|
||||
|
||||
-- Show how it looks
|
||||
for i=0, 9 do
|
||||
local b1,b2 = DSM_Ch[i][0], DSM_Ch[i][1]
|
||||
local s1 = channelType2String(b1,b2)
|
||||
local s = string.format("%s (%02X %02X) %s\n", MODEL.PORT_TEXT[i],
|
||||
b1, b2,s1)
|
||||
DSM_Ch[i][2]=s1
|
||||
LOG_write(s)
|
||||
end
|
||||
|
||||
--MODEL.AirWingTailDesc = string.format("Aircraft(%s) Wing(%s) Tail(%s)",aircraft_type_text[aircraftType],wing_type_text[wingType],tail_type_text[tailType])
|
||||
end
|
||||
|
||||
-- Main Program
|
||||
|
||||
LOG_write("Creating DSMPort Info\n")
|
||||
CreateDSMPortChannelInfo()
|
||||
|
||||
|
||||
90
SCRIPTS/TOOLS/DSMLIB/DsmMainMenuLib.lua
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
local Log, menuLib, modelLib, DEBUG_ON, SIMULATION_ON = ... -- Get DebugON from parameters
|
||||
local MAIN_MENU_LIB_VERSION = "0.56"
|
||||
local MODEL = modelLib.MODEL
|
||||
|
||||
local PHASE = menuLib.PHASE
|
||||
local LINE_TYPE = menuLib.LINE_TYPE
|
||||
|
||||
local lastGoodMenu=0
|
||||
|
||||
-- Creates the menus to Render with the GUI
|
||||
local function ST_LoadMenu(menuId)
|
||||
local ctx = menuLib.DSM_Context
|
||||
menuLib.clearMenuLines()
|
||||
|
||||
if (menuId==0x1000) then -- MAIN MENU
|
||||
ctx.Menu = { MenuId = 0x1000, Text = "Main Menu ("..MODEL.modelName..")", PrevId = 0, NextId = 0, BackId = 0, TextId=0 }
|
||||
ctx.MenuLines[0] = { Type = LINE_TYPE.MENU, Text = "Model Setup", ValId = 0xFFF3,TextId=0 }
|
||||
|
||||
if (SIMULATION_ON) then
|
||||
ctx.MenuLines[4] = { Type = LINE_TYPE.MENU, Text = "RX Simulator (GUI dev only)", ValId = 0xFFF1, TextId=0 } -- Menu 0xFFF2 to SIMULATOR
|
||||
end
|
||||
ctx.MenuLines[6] = { Type = LINE_TYPE.MENU, Text = "Forward Programming RX", ValId = 0xFFF2, TextId=0 } -- Menu 0xFFF2 to Real RX
|
||||
ctx.SelLine = 6
|
||||
|
||||
lastGoodMenu = menuId
|
||||
else
|
||||
--print("NOT IMPLEMENTED")
|
||||
ctx.Menu = { MenuId = 0x0002, Text = "NOT IMPLEMENTED", TextId = 0, PrevId = 0, NextId = 0, BackId = lastGoodMenu }
|
||||
ctx.SelLine = menuLib.BACK_BUTTON
|
||||
end
|
||||
|
||||
menuLib.PostProcessMenu()
|
||||
end
|
||||
|
||||
local function Main_Send_Receive()
|
||||
local ctx = menuLib.DSM_Context
|
||||
|
||||
if ctx.Phase == PHASE.RX_VERSION then -- Just Init RX Version
|
||||
ctx.RX.Name = "Main Menu"
|
||||
ctx.RX.Version = MAIN_MENU_LIB_VERSION
|
||||
ctx.Phase = PHASE.MENU_TITLE
|
||||
ctx.Menu.MenuId = 0
|
||||
|
||||
ctx.Refresh_Display = true
|
||||
elseif ctx.Phase == PHASE.WAIT_CMD then
|
||||
|
||||
elseif ctx.Phase == PHASE.MENU_TITLE then -- request menu title
|
||||
if ctx.Menu.MenuId == 0 then -- First time loading a menu ?
|
||||
ST_LoadMenu(0x01000)
|
||||
else
|
||||
ST_LoadMenu(ctx.Menu.MenuId)
|
||||
end
|
||||
ctx.Phase = PHASE.WAIT_CMD
|
||||
ctx.Refresh_Display = true
|
||||
|
||||
elseif ctx.Phase == PHASE.VALUE_CHANGING then -- send value
|
||||
local line = ctx.MenuLines[ctx.SelLine] -- Updated Value of SELECTED line
|
||||
--if (DEBUG_ON) then Log.LOG_write("%3.3f %s: ", menuLib.getElapsedTime(), menuLib.phase2String(ctx.Phase)) end
|
||||
--if (DEBUG_ON) then Log.LOG_write("SEND SIM_updateMenuValue(ValueId=0x%X Text=\"%s\" Value=%s)\n", line.ValId, line.Text, menuLib.lineValue2String(line)) end
|
||||
ctx.Phase = PHASE.VALUE_CHANGING_WAIT
|
||||
|
||||
elseif ctx.Phase == PHASE.VALUE_CHANGING_WAIT then
|
||||
local line = ctx.MenuLines[ctx.SelLine]
|
||||
|
||||
elseif ctx.Phase == PHASE.VALUE_CHANGE_END then -- send value
|
||||
local line = ctx.MenuLines[ctx.SelLine] -- Updated Value of SELECTED line
|
||||
--if (DEBUG_ON) then Log.LOG_write("%3.3f %s: ", menuLib.getElapsedTime(), menuLib.phase2String(ctx.Phase)) end
|
||||
--if (DEBUG_ON) then Log.LOG_write("SEND SIM_updateMenuValue(ValueId=0x%X Text=\"%s\" Value=%s)\n", line.ValId, line.Text, menuLib.lineValue2String(line)) end
|
||||
--if (DEBUG_ON) then Log.LOG_write("SEND SIM_validateMenuValue(ValueId=0x%X Text=\"%s\" Value=%s)\n", line.ValId, line.Text, menuLib.lineValue2String(line)) end
|
||||
ctx.Phase = PHASE.WAIT_CMD
|
||||
|
||||
elseif ctx.Phase == PHASE.EXIT then
|
||||
ctx.Phase=PHASE.EXIT_DONE
|
||||
return 1
|
||||
end
|
||||
|
||||
return 0
|
||||
end
|
||||
|
||||
local function Main_Init()
|
||||
local ctx = menuLib.DSM_Context
|
||||
ctx.Phase = PHASE.RX_VERSION
|
||||
end
|
||||
|
||||
local function Main_Done()
|
||||
local ctx = menuLib.DSM_Context
|
||||
ctx.Phase = PHASE.EXIT_DONE
|
||||
end
|
||||
|
||||
return { init=Main_Init, run=Main_Send_Receive, done=Main_Done }
|
||||
788
SCRIPTS/TOOLS/DSMLIB/DsmMenuLib.lua
Normal file
|
|
@ -0,0 +1,788 @@
|
|||
--- #########################################################################
|
||||
---- # #
|
||||
---- # Copyright (C) OpenTX/EdgeTx #
|
||||
-----# #
|
||||
---- # 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. #
|
||||
---- # #
|
||||
---- #########################################################################
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- This script library is a rewrite of the original DSM forward programming Lua
|
||||
-- Script. The goal is to make it easier to understand, mantain, and to
|
||||
-- separate the GUI from the DSM Forward programming engine/logic
|
||||
-- in this way, GUIs can evolve independent. OpenTX Gui, EdgeTx GUI, Small Radios, etc.
|
||||
|
||||
-- Code is based on the code/work by: Pascal Langer (Author of the Multi-Module)
|
||||
-- Rewrite/Enhancements By: Francisco Arzu
|
||||
|
||||
local Log, DEBUG_ON = ... -- Parameters
|
||||
|
||||
|
||||
local MenuLib = { }
|
||||
|
||||
local PHASE = {
|
||||
INIT = 0,
|
||||
RX_VERSION = 1,
|
||||
WAIT_CMD = 2,
|
||||
MENU_TITLE = 3,
|
||||
MENU_REQ_TX_INFO = 4,
|
||||
MENU_LINES = 5,
|
||||
MENU_VALUES = 6,
|
||||
VALUE_CHANGING = 7,
|
||||
VALUE_CHANGING_WAIT = 8,
|
||||
VALUE_CHANGE_END = 9,
|
||||
EXIT = 10,
|
||||
EXIT_DONE = 11
|
||||
}
|
||||
|
||||
local LINE_TYPE = {
|
||||
MENU = 0x1C,
|
||||
LIST_MENU = 0x0C, -- List: INC Change + Validate
|
||||
LIST_MENU_NC = 0x6C, -- List: No Incremental Change
|
||||
LIST_MENU_NC2 = 0x6D, -- List: No Incremental Change (Frame Rate Herz)
|
||||
LIST_MENU_TOG = 0x4C, -- List: Incremental Change, sometimes bolean/Toggle menu (if only 2 values)
|
||||
LIST_MENU_ORI = 0xCC, -- List: Incremental Change, Orientation Heli
|
||||
|
||||
VALUE_NUM_I8_NC = 0x60, -- 8 bit number, no incremental change
|
||||
VALUE_PERCENT = 0xC0, -- 8 bit number, Signed, percent
|
||||
VALUE_DEGREES = 0xE0, -- 8 bit number, Signed, Degress
|
||||
VALUE_NUM_I8 = 0x40, -- 8 bit number
|
||||
VALUE_NUM_I16 = 0x41, -- 16 Bit number
|
||||
VALUE_NUM_SI16 = 0xC1, -- 16 bit number, Signed
|
||||
|
||||
LT_EMPTY = 0x00
|
||||
}
|
||||
|
||||
-- Bug in Lua compiler, confusing with global BOLD and RIGHT
|
||||
local DISP_ATTR = {
|
||||
_BOLD = 0x01, _RIGHT=0x02, _CENTER=0x04, PERCENT = 0x10, DEGREES=0x20, FORCED_MENU = 0x40
|
||||
}
|
||||
|
||||
--RX IDs--
|
||||
local RX = {
|
||||
AR636B = 0x0001,
|
||||
SPM4651T = 0x0014,
|
||||
AR637T = 0x0015,
|
||||
AR637TA = 0x0016,
|
||||
FC6250HX = 0x0018,
|
||||
AR630 = 0x0019,
|
||||
AR8360T = 0x001A,
|
||||
AR10360T = 0x001C,
|
||||
AR631 = 0x001E
|
||||
}
|
||||
|
||||
local DSM_Context = {
|
||||
Phase = PHASE.INIT,
|
||||
Menu = { MenuId = 0, Text = "", TextId = 0, PrevId = 0, NextId = 0, BackId = 0 },
|
||||
MenuLines = {},
|
||||
RX = { Id=0, Name = "", Version = "" },
|
||||
Refresh_Display = true,
|
||||
SendDataToRX = 1,
|
||||
|
||||
SelLine = 0, -- Current Selected Line
|
||||
EditLine = nil, -- Current Editing Line
|
||||
CurLine = -1, -- Current Line Requested/Parsed via h message protocol
|
||||
isReset = false -- false when starting from scracts, true when starting from Reset
|
||||
}
|
||||
|
||||
function DSM_Context.isEditing() return DSM_Context.EditLine~=nil end
|
||||
|
||||
local MAX_MENU_LINES = 6
|
||||
local BACK_BUTTON = -1 -- Tread it as a display line #-1
|
||||
local NEXT_BUTTON = MAX_MENU_LINES + 1 -- Tread it as a display line #7
|
||||
local PREV_BUTTON = MAX_MENU_LINES + 2 -- Tread it as a display line #7
|
||||
|
||||
-- Text Arrays for Display Text and Debuging
|
||||
local PhaseText = {}
|
||||
local LineTypeText = {}
|
||||
|
||||
local Text = {} -- Text for Menu and Menu Lines (Headers only)
|
||||
local List_Text = {} -- Messages for List Options (values only)
|
||||
local List_Text_Img = {} -- If the Text has Attached Images
|
||||
local List_Values = {} -- Additiona restrictions on List Values when non contiguos (L_M1 lines has this problem)
|
||||
local Flight_Mode = {[0]="Fligh Mode"}
|
||||
local RxName = {}
|
||||
|
||||
local StartTime = 0
|
||||
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
-- Get Elapsed Time since we started running the Script. Return a float in format: Seconds.Milliseconds
|
||||
function MenuLib.getElapsedTime()
|
||||
local t = getTime()
|
||||
if (StartTime == 0) then StartTime = t end
|
||||
|
||||
return ((t - StartTime) * 10) / 1000
|
||||
end
|
||||
|
||||
------------- Line Type helper functions ------------------------------------------------------------------
|
||||
|
||||
-- Check if the text are Flight modes, who will be treated different for Display
|
||||
function MenuLib.isFlightModeLine(line)
|
||||
return (line.TextId >= 0x8000 and line.TextId <= 0x8003)
|
||||
end
|
||||
|
||||
function MenuLib.isSelectableLine(line) -- is the display line Selectable??
|
||||
-- values who are not selectable
|
||||
if (line.Type == 0) then return false end -- Empty Line
|
||||
if (line.Type == LINE_TYPE.MENU and line.ValId == line.MenuId and bit32.band(line.TextAttr, DISP_ATTR.FORCED_MENU)==0) then return false end -- Menu that navigates to Itself?
|
||||
if (line.Min==0 and line.Max==0 and line.Def==0) then return false end -- Values with no Range are only for display
|
||||
if (line.Type == LINE_TYPE.VALUE_NUM_I8_NC and MenuLib.isFlightModeLine(line)) then return false end -- Flight mode is not Selectable
|
||||
return true
|
||||
end
|
||||
|
||||
function MenuLib.isEditableLine(line) -- is the display line editable??
|
||||
-- values who are not editable
|
||||
if (line.Type == 0 or line.Type == LINE_TYPE.MENU) then return false end -- Menus are not editable
|
||||
if (line.Min==0 and line.Max==0 and line.Def==0) then return false end -- Values with no Range are only for display
|
||||
if (line.Type == LINE_TYPE.VALUE_NUM_I8_NC and MenuLib.isFlightModeLine(line)) then return false end -- Flight mode is not Editable
|
||||
-- any other is Editable
|
||||
return true
|
||||
end
|
||||
|
||||
function MenuLib.isListLine(line) -- is it a List of options??
|
||||
if (line.Type == LINE_TYPE.LIST_MENU_NC or line.Type == LINE_TYPE.LIST_MENU or
|
||||
line.Type == LINE_TYPE.LIST_MENU_TOG or line.Type == LINE_TYPE.LIST_MENU_NC2 or
|
||||
line.Type == LINE_TYPE.LIST_MENU_ORI) then return true end
|
||||
return false
|
||||
end
|
||||
|
||||
function MenuLib.isPercentValueLineByMinMax(line)
|
||||
return
|
||||
(line.Min == 0 and line.Max == 100) or ( line.Min == -100 and line.Max == 100) or
|
||||
( line.Min == 0 and line.Max == 150) or ( line.Min == -150 and line.Max == 150)
|
||||
end
|
||||
|
||||
function MenuLib.isPercentValueLine(line) -- is it a Percent value??
|
||||
if (line.Type == LINE_TYPE.VALUE_PERCENT) then return true end
|
||||
return false
|
||||
end
|
||||
|
||||
function MenuLib.isNumberValueLine(line) -- is it a number ??
|
||||
if (MenuLib.isListLine(line) or line.Type == LINE_TYPE.MENU or line.Type == 0) then return false
|
||||
else return true end
|
||||
end
|
||||
|
||||
function MenuLib.isIncrementalValueUpdate(line)
|
||||
if (line.Type == LINE_TYPE.LIST_MENU_NC or line.Type == LINE_TYPE.LIST_MENU_NC2 or
|
||||
line.Type == LINE_TYPE.VALUE_NUM_I8_NC or line.Type == LINE_TYPE.VALUE_DEGREES) then return false end
|
||||
return true
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
function MenuLib.Get_Text(index)
|
||||
if (index >= 0x8000) then
|
||||
return Flight_Mode[0]
|
||||
end
|
||||
|
||||
local out = Text[index] -- Find in regular header first
|
||||
if out== nil then
|
||||
out = List_Text[index] -- Try list values, don't think is necesary, but just playing Safe
|
||||
end
|
||||
if out == nil then -- unknown...
|
||||
out = "Unknown_" .. string.format("%X", index)
|
||||
end
|
||||
return out
|
||||
end
|
||||
|
||||
function MenuLib.Get_List_Text(index)
|
||||
local out = List_Text[index] -- Try to find the message in List_Text
|
||||
if out == nil then
|
||||
out = Text[index] -- Try list headers, don't think is necesary, but just playing Safe
|
||||
end
|
||||
if out == nil then -- unknown...
|
||||
out = "UnknownLT_" .. string.format("%X", index)
|
||||
end
|
||||
return out
|
||||
end
|
||||
|
||||
function MenuLib.Get_List_Text_Img(index)
|
||||
local out = List_Text_Img[index]
|
||||
return out
|
||||
end
|
||||
|
||||
function MenuLib.Get_List_Values(index)
|
||||
local out = List_Values[index]
|
||||
return out
|
||||
end
|
||||
|
||||
function MenuLib.Get_RxName(index)
|
||||
local out = RxName[index]
|
||||
return out or ("RX_" .. string.format("%X", index))
|
||||
end
|
||||
|
||||
----------- Debugging 2-String functions -------------------------------------------------------------------
|
||||
|
||||
function MenuLib.phase2String(index)
|
||||
local out = PhaseText[index]
|
||||
return out or ("Phase_" .. string.format("%X", index))
|
||||
end
|
||||
|
||||
function MenuLib.lineType2String(index)
|
||||
local out = LineTypeText[index]
|
||||
return out or ("LT_" .. string.format("%X", index or 0xFF))
|
||||
end
|
||||
|
||||
function MenuLib.lineValue2String(l)
|
||||
if (DEBUG_ON == 0) then
|
||||
return ""
|
||||
end
|
||||
if (l ~= nil and l.Val ~= nil) then
|
||||
local value = l.Val
|
||||
if MenuLib.isListLine(l) then
|
||||
value = value .. "|\"" .. MenuLib.Get_List_Text(l.Val + l.TextStart) .. "\""
|
||||
else
|
||||
value = value..(l.Format or "")
|
||||
end
|
||||
return value
|
||||
end
|
||||
return "nil"
|
||||
end
|
||||
|
||||
function MenuLib.menu2String(m)
|
||||
local txt = "Menu[]"
|
||||
if (m ~= nil) then
|
||||
txt = string.format("M[Id=0x%X P=0x%X N=0x%X B=0x%X Text=\"%s\"[0x%X]]",
|
||||
m.MenuId, m.PrevId, m.NextId, m.BackId, m.Text, m.TextId)
|
||||
end
|
||||
return txt
|
||||
end
|
||||
|
||||
function MenuLib.menuLine2String(l)
|
||||
local txt = "Line[]"
|
||||
if (l ~= nil) then
|
||||
local value = ""
|
||||
local range = ""
|
||||
if l.Type~=LINE_TYPE.MENU then
|
||||
value = "Val="..MenuLib.lineValue2String(l)
|
||||
if MenuLib.isListLine(l) then
|
||||
range = string.format("NL=(%s->%s,%s,S=%s) ",l.Min, l.Max, l.Def, l.TextStart )
|
||||
range = range .. (l.MinMaxOrig or "")
|
||||
else
|
||||
range = string.format("[%s->%s,%s]",l.Min, l.Max, l.Def)
|
||||
end
|
||||
end
|
||||
|
||||
txt = string.format("L[#%s T=%s VId=0x%X Text=\"%s\"[0x%X] %s %s MId=0x%X A=0x%X]",
|
||||
l.lineNum, MenuLib.lineType2String(l.Type), l.ValId,
|
||||
l.Text, l.TextId,
|
||||
value,
|
||||
range,
|
||||
l.MenuId,
|
||||
l.TextAttr
|
||||
)
|
||||
end
|
||||
return txt
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------------------------------------
|
||||
-- Post Procssing Line from Raw values receive by RX or Simulation
|
||||
|
||||
function MenuLib.isDisplayAttr(attr, bit)
|
||||
return (bit32.band(attr,bit)>0)
|
||||
end
|
||||
|
||||
function MenuLib.ExtractDisplayAttr(text1, attr)
|
||||
local text = text1, pos;
|
||||
|
||||
for i=1,2 do
|
||||
text, pos = string.gsub(text, "/c$", "")
|
||||
if (pos>0) then -- CENTER
|
||||
attr = bit32.bor(attr, DISP_ATTR._CENTER)
|
||||
end
|
||||
|
||||
text, pos = string.gsub(text, "/r$", "")
|
||||
if (pos>0) then -- RIGHT
|
||||
attr = bit32.bor(attr, DISP_ATTR._RIGHT)
|
||||
end
|
||||
|
||||
text, pos = string.gsub(text, "/p$", "")
|
||||
if (pos>0) then -- Percent TEXT
|
||||
attr = bit32.bor(attr, DISP_ATTR.PERCENT)
|
||||
end
|
||||
|
||||
text, pos = string.gsub(text, "/b$", "")
|
||||
if (pos>0) then -- BOLD TEXT
|
||||
attr = bit32.bor(attr, DISP_ATTR._BOLD)
|
||||
end
|
||||
|
||||
text, pos = string.gsub(text, "/m$", "")
|
||||
if (pos>0) then -- FORCED MENU Button
|
||||
attr = bit32.bor(attr, DISP_ATTR.FORCED_MENU)
|
||||
end
|
||||
end
|
||||
|
||||
return text, attr
|
||||
end
|
||||
|
||||
function MenuLib.MenuPostProcessing(menu)
|
||||
menu.Text, menu.TextAttr = MenuLib.ExtractDisplayAttr(menu.Text,menu.TextAttr or 0)
|
||||
end
|
||||
|
||||
function MenuLib.MenuLinePostProcessing(line)
|
||||
if (line.Text==nil) then
|
||||
line.Text = MenuLib.Get_Text(line.TextId) -- Get Textual Line headeing text
|
||||
end
|
||||
|
||||
-- Text formatting options
|
||||
line.Text, line.TextAttr = MenuLib.ExtractDisplayAttr(line.Text,line.TextAttr or 0)
|
||||
|
||||
if line.Type == LINE_TYPE.MENU then
|
||||
-- nothing to do on menu entries
|
||||
line.Val=nil
|
||||
elseif MenuLib.isListLine(line) then
|
||||
-- Original Range for Debugging
|
||||
line.MinMaxOrig = "[" .. line.Min .. "->" .. line.Max .. "," .. line.Def .. "]"
|
||||
|
||||
-- Normalize Min/Max to be relative to Zero
|
||||
line.TextStart = line.Min
|
||||
line.Def = line.Def - line.Min -- normalize default value
|
||||
line.Max = line.Max - line.Min -- normalize max index
|
||||
line.Min = 0 -- min index
|
||||
else -- default to numerical value
|
||||
if MenuLib.isPercentValueLine(line) or MenuLib.isPercentValueLineByMinMax(line) then
|
||||
-- either explicit Percent or NO-Change value, but range is %Percent
|
||||
line.Format ="%"
|
||||
line.TextAttr = bit32.bor(line.TextAttr,DISP_ATTR.PERCENT)
|
||||
elseif (line.Type == LINE_TYPE.VALUE_DEGREES) then
|
||||
line.Format ="o"
|
||||
line.TextAttr = bit32.bor(line.TextAttr,DISP_ATTR.DEGREES)
|
||||
end
|
||||
end
|
||||
|
||||
line.MinMaxDebug = MenuLib.lineType2String(line.Type).." "..(line.MinMaxOrig or "")
|
||||
end
|
||||
|
||||
|
||||
function MenuLib.ChangePhase(newPhase)
|
||||
DSM_Context.Phase = newPhase
|
||||
DSM_Context.SendDataToRX = 1
|
||||
end
|
||||
|
||||
function MenuLib.Value_Add(line, inc)
|
||||
if (DEBUG_ON) then Log.LOG_write("%3.3f %s: DSM_Value_Add(%s,%s)\n",
|
||||
MenuLib.getElapsedTime(), MenuLib.phase2String(DSM_Context.Phase), inc, MenuLib.menuLine2String(line)) end
|
||||
|
||||
local skipIncrement = false
|
||||
local values = nil
|
||||
local origVal = line.Val
|
||||
|
||||
-- Use local validation for LIST_MENU1 when the range is wide open
|
||||
-- Also use if for some LIST_MENU0 that the Range seems incorrect
|
||||
if (MenuLib.isListLine(line)) then -- and line.Type==LINE_TYPE.LIST_MENU1 and line.Min==0 and line.Max==244) then
|
||||
values = MenuLib.Get_List_Values(line.TextId)
|
||||
end
|
||||
|
||||
|
||||
if (values~=nil) then -- Inc/Dec based on a list of predefined Values Local to Script (values not contiguous),
|
||||
-- locate current value in values array
|
||||
-- Values are Zero normalized to the Start of the List (line.TextStart)
|
||||
for i = 1, #values do
|
||||
if ((values[i]-line.TextStart)==origVal) then
|
||||
skipIncrement = true
|
||||
if (inc==-1 and i > 1) then -- PREV
|
||||
line.Val = values[i-1]-line.TextStart
|
||||
elseif (inc==1 and i < #values) then -- NEXT
|
||||
line.Val = values[i+1]-line.TextStart
|
||||
end
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if not skipIncrement then
|
||||
-- Do it Sequentially
|
||||
line.Val = line.Val + inc
|
||||
|
||||
if line.Val > line.Max then
|
||||
line.Val = line.Max
|
||||
elseif line.Val < line.Min then
|
||||
line.Val = line.Min
|
||||
end
|
||||
end
|
||||
|
||||
if (origVal~=line.Val and MenuLib.isIncrementalValueUpdate(line)) then
|
||||
-- Update RX value on every change
|
||||
MenuLib.ChangePhase(PHASE.VALUE_CHANGING)
|
||||
end
|
||||
end
|
||||
|
||||
function MenuLib.Value_Default(line)
|
||||
local origVal = line.Val
|
||||
if (DEBUG_ON) then Log.LOG_write("%3.3f %s: DSM_Value_Default(%s)\n",
|
||||
MenuLib.getElapsedTime(), MenuLib.phase2String(DSM_Context.Phase), MenuLib.menuLine2String(line)) end
|
||||
|
||||
line.Val = line.Def
|
||||
if (origVal~=line.Val and MenuLib.isIncrementalValueUpdate(line)) then
|
||||
-- Update RX value on every change
|
||||
MenuLib.ChangePhase(PHASE.VALUE_CHANGING)
|
||||
end
|
||||
end
|
||||
|
||||
function MenuLib.Value_Write_Validate(line)
|
||||
if (DEBUG_ON) then Log.LOG_write("%3.3f %s: DSM_Value_Write_Validate(%s)\n",
|
||||
MenuLib.getElapsedTime(), MenuLib.phase2String(DSM_Context.Phase), MenuLib.menuLine2String(line)) end
|
||||
|
||||
MenuLib.ChangePhase(PHASE.VALUE_CHANGE_END) -- Update + Validate value in RX
|
||||
DSM_Context.EditLine = nil -- Exit Edit Mode (By clearing the line editing)
|
||||
end
|
||||
|
||||
function MenuLib.GotoMenu(menuId, lastSelectedLine)
|
||||
if (DEBUG_ON) then Log.LOG_write("%3.3f %s: DSM_GotoMenu(0x%X,LastSelectedLine=%d)\n",
|
||||
MenuLib.getElapsedTime(), MenuLib.phase2String(DSM_Context.Phase), menuId, lastSelectedLine) end
|
||||
|
||||
DSM_Context.Menu.MenuId = menuId
|
||||
DSM_Context.SelLine = lastSelectedLine
|
||||
-- Request to load the menu Again
|
||||
MenuLib.ChangePhase(PHASE.MENU_TITLE)
|
||||
end
|
||||
|
||||
function MenuLib.MoveSelectionLine(dir)
|
||||
local ctx = DSM_Context
|
||||
local menu = ctx.Menu
|
||||
local menuLines = ctx.MenuLines
|
||||
|
||||
if (dir == 1) then -- NEXT
|
||||
if ctx.SelLine <= MAX_MENU_LINES then
|
||||
local num = ctx.SelLine
|
||||
for i = ctx.SelLine + 1, MAX_MENU_LINES, 1 do
|
||||
if MenuLib.isSelectableLine(menuLines[i]) then
|
||||
ctx.SelLine = i
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if num == ctx.SelLine then
|
||||
if menu.NextId ~= 0 then -- Next
|
||||
ctx.SelLine = NEXT_BUTTON
|
||||
elseif menu.PrevId ~= 0 then -- Prev
|
||||
ctx.SelLine = PREV_BUTTON
|
||||
end
|
||||
end
|
||||
elseif menu.PrevId ~= 0 then -- Prev
|
||||
ctx.SelLine = PREV_BUTTON
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if (dir == -1) then -- PREV
|
||||
if ctx.SelLine == PREV_BUTTON and menu.NextId ~= 0 then
|
||||
ctx.SelLine = NEXT_BUTTON
|
||||
elseif ctx.SelLine > 0 then
|
||||
if ctx.SelLine > MAX_MENU_LINES then
|
||||
ctx.SelLine = NEXT_BUTTON
|
||||
end
|
||||
local num = ctx.SelLine
|
||||
for i = ctx.SelLine - 1, 0, -1 do
|
||||
if MenuLib.isSelectableLine(menuLines[i]) then
|
||||
ctx.SelLine = i
|
||||
break
|
||||
end
|
||||
end
|
||||
if num == ctx.SelLine then -- can't find previous selectable line, then SELECT Back
|
||||
if (menu.BackId ~= 0) then ctx.SelLine = BACK_BUTTON end
|
||||
end
|
||||
else
|
||||
if (menu.BackId ~= 0) then ctx.SelLine = BACK_BUTTON end -- Back
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- Clear each line of the menu
|
||||
function MenuLib.clearMenuLines()
|
||||
local ctx = DSM_Context
|
||||
for i = 0, MAX_MENU_LINES do -- clear menu
|
||||
ctx.MenuLines[i] = { MenuId = 0, lineNum = 0, Type = 0, Text = "", TextId = 0, ValId = 0, Min=0, Max=0, Def=0, TextStart=0, Val=nil }
|
||||
end
|
||||
end
|
||||
|
||||
-- Post processing needed for each menu
|
||||
function MenuLib.PostProcessMenu()
|
||||
local ctx = DSM_Context
|
||||
|
||||
if (ctx.Menu.Text==nil) then
|
||||
ctx.Menu.Text = MenuLib.Get_Text(ctx.Menu.TextId)
|
||||
MenuLib.MenuPostProcessing (ctx.Menu)
|
||||
end
|
||||
|
||||
--if (DEBUG_ON) then Log.LOG_write("SIM RESPONSE Menu: %s\n", MenuLib.menu2String(ctx.Menu)) end
|
||||
|
||||
for i = 0, MenuLib.MAX_MENU_LINES do -- clear menu
|
||||
local line = ctx.MenuLines[i]
|
||||
if (line.Type~=0) then
|
||||
line.MenuId = ctx.Menu.MenuId
|
||||
line.lineNum = i
|
||||
MenuLib.MenuLinePostProcessing(line) -- Do the same post processing as if they come from the RX
|
||||
--if (DEBUG_ON) then Log.LOG_write("SIM RESPONSE MenuLine: %s\n", MenuLib.menuLine2String(line)) end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
function MenuLib.GetFlightModeValue(line)
|
||||
local ret = line.Text.." "
|
||||
local val = line.Val
|
||||
|
||||
if (val==nil) then return ret.."--" end
|
||||
|
||||
-- Adjust the displayed value for Flight mode line as needed
|
||||
if (DSM_Context.RX.Id == RX.FC6250HX) then
|
||||
-- Helicopter Flights modes
|
||||
if (val==0) then ret = ret .. "1 / HOLD"
|
||||
elseif (val==1) then ret = ret .. "2 / Normal"
|
||||
elseif (val==2) then ret = ret .. "3 / Stunt 1"
|
||||
elseif (val==3) then ret = ret .. "4 / Stunt 2"
|
||||
elseif (val==4) then ret = ret .. "5 / Panic"
|
||||
else
|
||||
ret = ret .. " " .. (val + 1)
|
||||
end
|
||||
else
|
||||
-- No adjustment needed
|
||||
if (val==190) then
|
||||
ret=ret.."Err:Out of Range"
|
||||
else
|
||||
ret=ret..(val + 1)
|
||||
end
|
||||
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
function MenuLib.Init()
|
||||
print("MenuLib.Init()")
|
||||
-- Phase Names
|
||||
PhaseText[PHASE.INIT] = "INIT"
|
||||
PhaseText[PHASE.RX_VERSION] = "RX_VERSION"
|
||||
PhaseText[PHASE.WAIT_CMD] = "WAIT_CMD"
|
||||
PhaseText[PHASE.MENU_TITLE] = "MENU_TITLE"
|
||||
PhaseText[PHASE.MENU_REQ_TX_INFO] = "MENU_REQ_TX_INFO"
|
||||
PhaseText[PHASE.MENU_LINES] = "MENU_LINES"
|
||||
PhaseText[PHASE.MENU_VALUES] = "MENU_VALUES"
|
||||
PhaseText[PHASE.VALUE_CHANGING] = "VALUE_CHANGING"
|
||||
PhaseText[PHASE.VALUE_CHANGING_WAIT] = "VALUE_EDITING"
|
||||
PhaseText[PHASE.VALUE_CHANGE_END] = "VALUE_CHANGE_END"
|
||||
PhaseText[PHASE.EXIT] = "EXIT"
|
||||
PhaseText[PHASE.EXIT_DONE] = "EXIT_DONE"
|
||||
|
||||
|
||||
-- Line Types
|
||||
LineTypeText[LINE_TYPE.MENU] = "M"
|
||||
LineTypeText[LINE_TYPE.LIST_MENU_NC] = "LM_nc"
|
||||
LineTypeText[LINE_TYPE.LIST_MENU] = "LM"
|
||||
LineTypeText[LINE_TYPE.LIST_MENU_TOG] = "LM_tog"
|
||||
LineTypeText[LINE_TYPE.LIST_MENU_NC2] = "LM_nc2"
|
||||
LineTypeText[LINE_TYPE.LIST_MENU_ORI] = "LM_ori"
|
||||
LineTypeText[LINE_TYPE.VALUE_NUM_I8_NC] = "V_nc"
|
||||
LineTypeText[LINE_TYPE.VALUE_PERCENT] = "V_%"
|
||||
LineTypeText[LINE_TYPE.VALUE_DEGREES] = "V_de"
|
||||
LineTypeText[LINE_TYPE.VALUE_NUM_I8] = "V_i8"
|
||||
LineTypeText[LINE_TYPE.VALUE_NUM_I16] = "V_i16"
|
||||
LineTypeText[LINE_TYPE.VALUE_NUM_SI16] = "V_s16"
|
||||
LineTypeText[LINE_TYPE.LT_EMPTY] = "Z"
|
||||
|
||||
DSM_Context.Phase = PHASE.RX_VERSION
|
||||
end
|
||||
|
||||
function MenuLib.clearAllText()
|
||||
local function clearTable(t)
|
||||
for i, v in ipairs(t) do t[i] = nil end
|
||||
end
|
||||
|
||||
clearTable(Text)
|
||||
clearTable(List_Text)
|
||||
clearTable(List_Text_Img)
|
||||
clearTable(List_Values)
|
||||
end
|
||||
|
||||
function MenuLib.LoadTextFromFile(fileName, mem)
|
||||
local function rtrim(s)
|
||||
local n = string.len(s)
|
||||
while n > 0 and string.find(s, "^%s", n) do n = n - 1 end
|
||||
return string.sub(s, 1, n)
|
||||
end
|
||||
|
||||
--print(string.format("Loading messages from [%s]",fileName))
|
||||
local dataFile = io.open(fileName, "r") -- read File
|
||||
-- cannot read file???
|
||||
assert(dataFile, "Cannot load Message file:" .. fileName)
|
||||
|
||||
local data = io.read(dataFile, mem * 1024) -- read up to 10k characters (newline char also counts!)
|
||||
io.close(dataFile)
|
||||
|
||||
collectgarbage("collect")
|
||||
|
||||
local lineNo = 0
|
||||
for line in string.gmatch(data, "[^\r\n]+") do
|
||||
lineNo = lineNo + 1
|
||||
--print(string.format("Line [%d]: %s",lineNo,line))
|
||||
|
||||
-- Remove Comments
|
||||
local s = string.find(line, "--", 1, true)
|
||||
if (s ~= nil) then
|
||||
line = string.sub(line, 1, s - 1)
|
||||
end
|
||||
|
||||
line = rtrim(line)
|
||||
|
||||
if (string.len(line) > 0) then
|
||||
local a, b, c = string.match(line, "%s*(%a*)%s*|%s*(%w*)%s*|(.*)%s*")
|
||||
--print(string.format("[%s] [%s] [%s]",a,b,c))
|
||||
if (a ~= nil) then
|
||||
local index = tonumber(b)
|
||||
|
||||
if (index == nil) then
|
||||
assert(false, string.format("%s:%d: Invalid Hex num [%s]", fileName, lineNo, b))
|
||||
elseif (a == "T") then
|
||||
Text[index] = c
|
||||
elseif (a == "LT") then
|
||||
List_Text[index] = c
|
||||
elseif (a == "LI") then
|
||||
List_Text_Img[index] = c
|
||||
elseif (a == "FM") then
|
||||
Flight_Mode[0] = c
|
||||
elseif (a == "RX") then
|
||||
RxName[index] = c
|
||||
else
|
||||
assert(false, string.format("%s:%d: Invalid Line Type [%s]", fileName, lineNo, a))
|
||||
end
|
||||
end
|
||||
end
|
||||
if (lineNo % 50 == 0) then
|
||||
collectgarbage("collect")
|
||||
end
|
||||
end -- For
|
||||
|
||||
--print(string.format("Loaded [%d] messages",lineNo))
|
||||
data = nil
|
||||
end
|
||||
|
||||
function MenuLib.INC_LoadTextFromFile(fileName, FileState)
|
||||
-----------------------
|
||||
local function rtrim(s)
|
||||
local n = string.len(s)
|
||||
while n > 0 and string.find(s, "^%s", n) do n = n - 1 end
|
||||
return string.sub(s, 1, n)
|
||||
end
|
||||
|
||||
local function GetTextInfoFromFile(pos)
|
||||
local dataFile = io.open(fileName, "r")
|
||||
io.seek(dataFile,pos)
|
||||
local buff = io.read(dataFile, 100)
|
||||
io.close(dataFile)
|
||||
|
||||
local line=""
|
||||
local index=""
|
||||
local type=""
|
||||
|
||||
local pipe=0
|
||||
local comment=0
|
||||
local newPos = pos
|
||||
|
||||
-- Parse the line:
|
||||
-- Format: TT|0x999|Text -- Comment
|
||||
for i=1,#buff do
|
||||
newPos=newPos+1
|
||||
local ch = string.sub(buff,i,i)
|
||||
|
||||
if (pipe < 2 and ch=="|") then pipe=pipe+1 -- Count pipes pos (Type | Index | .....)
|
||||
elseif (ch=="\r") then -- Ignore CR
|
||||
elseif (ch=="\n") then break -- LF, end of line
|
||||
elseif (ch=="-") then -- March comments
|
||||
comment=comment+1
|
||||
if (comment==2) then pipe=6 end -- Comment part of line
|
||||
else
|
||||
-- regular char
|
||||
comment=0
|
||||
if (pipe==0) then type=type..ch -- in TT (Type)
|
||||
elseif (pipe==1) then index=index..ch -- in Index
|
||||
elseif (pipe<6) then line=line..ch end -- in Text
|
||||
end -- Regular char
|
||||
end -- For
|
||||
|
||||
return type, index, rtrim(line), newPos
|
||||
end
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
if (FileState.state==nil) then -- Initial State
|
||||
FileState.state=1
|
||||
FileState.lineNo=0
|
||||
FileState.filePos=0
|
||||
end
|
||||
|
||||
if FileState.state==1 then
|
||||
for l=1,10 do -- do 10 lines at a time
|
||||
local type, sIndex, text
|
||||
local lineStart = FileState.filePos
|
||||
|
||||
type, sIndex, text, FileState.filePos = GetTextInfoFromFile(FileState.filePos)
|
||||
|
||||
--print(string.format("T=%s, I=%s, T=%s LS=%d, FP=%d",type,sIndex,text,lineStart, FileState.filePos))
|
||||
|
||||
if (lineStart==FileState.filePos) then -- EOF
|
||||
FileState.state=2 --EOF State
|
||||
return 1
|
||||
end
|
||||
FileState.lineNo = FileState.lineNo + 1
|
||||
|
||||
type = rtrim(type)
|
||||
|
||||
if (string.len(type) > 0 and string.len(sIndex) > 0) then
|
||||
local index = tonumber(sIndex)
|
||||
|
||||
if (index == nil) then
|
||||
assert(false, string.format("%s:%d: Invalid Hex num [%s]", fileName, FileState.lineNo, sIndex))
|
||||
elseif (type == "T") then
|
||||
Text[index] = text
|
||||
elseif (type == "LT") then
|
||||
List_Text[index] = text
|
||||
elseif (type == "LI") then
|
||||
List_Text_Img[index] = text
|
||||
elseif (type == "FM") then
|
||||
Flight_Mode[0] = text
|
||||
elseif (type == "RX") then
|
||||
RxName[index] = text
|
||||
else
|
||||
assert(false, string.format("%s:%d: Invalid Line Type [%s]", fileName, FileState.lineNo, type))
|
||||
end
|
||||
end
|
||||
end -- for
|
||||
end -- if
|
||||
|
||||
return 0
|
||||
end
|
||||
|
||||
|
||||
-- Export some Constants and Variables
|
||||
MenuLib.PHASE = PHASE
|
||||
MenuLib.LINE_TYPE = LINE_TYPE
|
||||
MenuLib.DISP_ATTR = DISP_ATTR
|
||||
MenuLib.RX = RX
|
||||
|
||||
MenuLib.MAX_MENU_LINES = MAX_MENU_LINES
|
||||
MenuLib.BACK_BUTTON = BACK_BUTTON
|
||||
MenuLib.NEXT_BUTTON = NEXT_BUTTON
|
||||
MenuLib.PREV_BUTTON = PREV_BUTTON
|
||||
|
||||
MenuLib.DSM_Context = DSM_Context
|
||||
|
||||
MenuLib.Text = Text
|
||||
MenuLib.List_Text = List_Text
|
||||
MenuLib.List_Text_Img = List_Text_Img
|
||||
MenuLib.List_Values = List_Values
|
||||
|
||||
MenuLib.LOG_open = Log.LOG_open
|
||||
MenuLib.LOG_write = Log.LOG_write
|
||||
MenuLib.LOG_Close = Log.LOG_close
|
||||
|
||||
|
||||
return MenuLib
|
||||
789
SCRIPTS/TOOLS/DSMLIB/DsmModelLib.lua
Normal file
|
|
@ -0,0 +1,789 @@
|
|||
|
||||
local Log, DEBUG_ON = ...
|
||||
|
||||
local DATA_PATH = "/MODELS/DSMDATA" -- Path to store model settings files
|
||||
local TX_CHANNELS = 12
|
||||
|
||||
-- MODEL information from ETX/OTX
|
||||
local ModelLib = {}
|
||||
|
||||
local MODEL = {
|
||||
modelName = "", -- The name of the model comming from OTX/ETX
|
||||
modelOutputChannel = {}, -- Output information from OTX/ETX
|
||||
AirWingTailDesc = "",
|
||||
|
||||
TX_CH_TEXT = {},
|
||||
PORT_TEXT = {},
|
||||
DSM_ChannelInfo = {} -- Data Created by DSM Configuration Script
|
||||
}
|
||||
|
||||
--Channel Types --
|
||||
local CH_TYPE = {
|
||||
NONE = 0x00,
|
||||
AIL = 0x01,
|
||||
ELE = 0x02,
|
||||
RUD = 0x04,
|
||||
|
||||
REVERSE = 0x20,
|
||||
THR = 0x40,
|
||||
SLAVE = 0x80,
|
||||
}
|
||||
|
||||
-- Seems like Reverse Mix is complement of the 3 bits
|
||||
local CH_MIX_TYPE = {
|
||||
MIX_NORM = 0x00, -- 0000
|
||||
MIX_AIL = 0x10, -- 0001 Taileron
|
||||
MIX_ELE = 0x20, -- 0010 For VTIAL and Delta-ELEVON
|
||||
MIX_RUD = 0x30, -- 0011 For VTIAL
|
||||
|
||||
MIX_RUD_REV = 0x40, -- 0100 For VTIAL
|
||||
MIX_ELE_REV = 0x50, -- 0101 For VTIAL and Delta-ELEVON A
|
||||
MIX_AIL_REV = 0x60, -- 0110 Taileron
|
||||
MIX_NORM_REV = 0x70 -- 0111
|
||||
}
|
||||
|
||||
local AIRCRAFT_TYPE = {
|
||||
PLANE = 0,
|
||||
HELI = 1,
|
||||
GLIDER = 2,
|
||||
DRONE = 3
|
||||
}
|
||||
local aircraft_type_text = {[0]="Plane","Heli","Glider","Drone"}
|
||||
|
||||
local WING_TYPE = {
|
||||
AIL_1 = 0, --1
|
||||
AIL_2 = 1, --2
|
||||
FLAPERON = 2, --2
|
||||
AIL_1_FLP_1 = 3, --2
|
||||
AIL_2_FLP_1 = 4, --3
|
||||
AIL_2_FLP_2 = 5, --4
|
||||
ELEVON_A = 6, --2
|
||||
ELEVON_B = 7 --2
|
||||
}
|
||||
|
||||
local wing_type_text = {[0]="Normal","Dual Ail","Flapperon", "Ail + Flp","Dual Ail + Flp","Dual Ail/Flp","Elevon A","Elevon B"}
|
||||
|
||||
local TAIL_TYPE = {
|
||||
RUD_1 = 0, -- 1
|
||||
RUD_1_ELEV_1 = 1, -- 2
|
||||
RUD_1_ELEV_2 = 2, -- 3
|
||||
RUD_2_ELEV_1 = 3, -- 3
|
||||
RUD_2_ELEV_2 = 4, -- 4
|
||||
VTAIL_A = 5, -- 2
|
||||
VTAIL_B = 6, -- 2
|
||||
TRAILERON_A = 7, -- 3
|
||||
TRAILERON_B = 8, -- 3
|
||||
TRAILERON_A_R2 = 9, -- 3
|
||||
TRAILERON_B_R2 = 10 -- 3
|
||||
}
|
||||
local tail_type_text = {[0]="Rud Only","Normal","Rud + Dual Ele","Dual Rud + Elv","Dual Rud/Ele",
|
||||
"VTail A","VTail B","Taileron A","Taileron B","Taileron A + 2x Rud","Taileron B + 2x Rud"}
|
||||
|
||||
local CH_MODE_TYPE = {
|
||||
NORMAL = 0,
|
||||
REVERSE = 1,
|
||||
USE_TX = 3
|
||||
}
|
||||
|
||||
local PORT = {
|
||||
PORT1 = 0,
|
||||
PORT2 = 1,
|
||||
PORT3 = 2,
|
||||
PORT4 = 3,
|
||||
PORT5 = 4,
|
||||
PORT6 = 5,
|
||||
PORT7 = 6,
|
||||
PORT8 = 7,
|
||||
PORT9 = 8,
|
||||
PORT10 = 9,
|
||||
PORT11 = 10,
|
||||
PORT12 = 11
|
||||
}
|
||||
|
||||
local MEMU_VAR = {
|
||||
AIRCRAFT_TYPE = 1001,
|
||||
WING_TYPE = 1002,
|
||||
TAIL_TYPE = 1003,
|
||||
|
||||
CH_BASE = 1010,
|
||||
CH_THR = 1010,
|
||||
|
||||
CH_L_AIL = 1011,
|
||||
CH_R_AIL = 1012,
|
||||
CH_L_FLP = 1013,
|
||||
CH_R_FLP = 1014,
|
||||
|
||||
CH_L_RUD = 1015,
|
||||
CH_R_RUD = 1016,
|
||||
CH_L_ELE = 1017,
|
||||
CH_R_ELE = 1018,
|
||||
|
||||
PORT_BASE = 1020,
|
||||
PORT1_MODE = 1020,
|
||||
PORT2_MODE = 1021,
|
||||
PORT3_MODE = 1022,
|
||||
PORT4_MODE = 1023,
|
||||
PORT5_MODE = 1024,
|
||||
PORT6_MODE = 1025,
|
||||
PORT7_MODE = 1026,
|
||||
PORT8_MODE = 1027,
|
||||
PORT9_MODE = 1028,
|
||||
PORT10_MODE = 1029,
|
||||
PORT11_MODE = 1030,
|
||||
PORT12_MODE = 1031,
|
||||
|
||||
DATA_END = 1040
|
||||
}
|
||||
|
||||
|
||||
-- MENU DATA Management
|
||||
local MENU_DATA = {} -- Store the variables used in the Menus.
|
||||
|
||||
|
||||
---- DSM_ChannelInfo ---------------------------------
|
||||
-- First byte describe Special Mixing (Vtail/Elevon = 0x20)
|
||||
--VTAIL
|
||||
--(0x00 0x06) CH_TYPE.ELE+CH_TYPE.RUD (0x02+0x04 = 0x06)
|
||||
--(0x20 0x86) CH_TYPE.ELE+CH_TYPE.RUD+CH_TYPE.SLAVE (0x02+0x04+0x80 = 0x86)
|
||||
|
||||
-- The 2nd byte describes the functionality of the port
|
||||
--
|
||||
-- Single Example: CH_TYPE.AIL (0x01) Aileron
|
||||
-- Reverse Example: CH_TYPE.AIL+CH_TYPE.REVERSE (0x01+0x20=0x21) Reverse Aileron
|
||||
-- Slave Example: CH_TYPE.AIL+CH_TYPE.SLAVE (0x01+0x80) -- 2nd servo Aileron
|
||||
|
||||
-- Elevon Example: CH_TYPE.AIL+CH_TYPE.ELE (0x01+0x02 = 0x03) -- Elevon
|
||||
-- Elevon Example: CH_TYPE.AIL+CH_TYPE.ELE+CH_TYPE.SLAVE (0x01+0x02+0x80 = 0x83) -- Slave Elevon
|
||||
|
||||
-- RudElv (VTail) Example: CH_TYPE.ELE+CH_TYPE.RUD (0x02+0x04 = 0x06) -- Rudevator
|
||||
-- RudElv (VTail) Example: CH_TYPE.ELE+CH_TYPE.RUD+CH_TYPE.SLAVE (0x02+0x04+0x80 = 0x86) -- Rudevator Slave
|
||||
|
||||
-- DEFAULT Simple Plane Port configuration (The Configuration tool will overrride this)
|
||||
MODEL.DSM_ChannelInfo= {[0]= -- Start array at position 0
|
||||
{[0]= CH_MIX_TYPE.MIX_NORM, CH_TYPE.THR}, -- Ch1 Thr (0x40)
|
||||
{[0]= CH_MIX_TYPE.MIX_NORM, CH_TYPE.AIL}, -- Ch2 Ail (0x01)
|
||||
{[0]= CH_MIX_TYPE.MIX_NORM, CH_TYPE.ELE}, -- Ch2 ElE (0x02)
|
||||
{[0]= CH_MIX_TYPE.MIX_NORM, CH_TYPE.RUD}, -- Ch4 Rud (0x04)
|
||||
{[0]= CH_MIX_TYPE.MIX_NORM, CH_TYPE.NONE}, -- Ch5 Gear (0x00)
|
||||
{[0]= CH_MIX_TYPE.MIX_NORM, CH_TYPE.NONE}, -- Ch6 Aux1 (0x00)
|
||||
{[0]= CH_MIX_TYPE.MIX_NORM, CH_TYPE.NONE}, -- Ch7 Aux2 (0x00)
|
||||
{[0]= CH_MIX_TYPE.MIX_NORM, CH_TYPE.NONE}, -- Ch8 Aux3 (0x00)
|
||||
{[0]= CH_MIX_TYPE.MIX_NORM, CH_TYPE.NONE}, -- Ch9 Aux4 (0x00)
|
||||
{[0]= CH_MIX_TYPE.MIX_NORM, CH_TYPE.NONE}, -- Ch10 Aux5 (0x00)
|
||||
{[0]= CH_MIX_TYPE.MIX_NORM, CH_TYPE.NONE}, -- Ch11 Aux6 (0x00)
|
||||
{[0]= CH_MIX_TYPE.MIX_NORM, CH_TYPE.NONE} -- Ch12 Aux7 (0x00)
|
||||
}
|
||||
|
||||
function ModelLib.printChannelSummary(a,w,t)
|
||||
-- Summary
|
||||
print("CHANNEL INFORMATION")
|
||||
print("Aircraft:".. (aircraft_type_text[MENU_DATA[MEMU_VAR.AIRCRAFT_TYPE]] or "--"))
|
||||
print("Wing Type:".. (wing_type_text[MENU_DATA[MEMU_VAR.WING_TYPE]] or "--"))
|
||||
print("Tail Type:".. (tail_type_text[MENU_DATA[MEMU_VAR.TAIL_TYPE]] or "--"))
|
||||
print("Thr:".. (MODEL.PORT_TEXT[(MENU_DATA[MEMU_VAR.CH_THR] or 30)] or "--")) -- use fake ch30 for non existing channels
|
||||
print("LAil:".. (MODEL.PORT_TEXT[(MENU_DATA[MEMU_VAR.CH_L_AIL] or 30)] or "--"))
|
||||
print("RAil:".. (MODEL.PORT_TEXT[(MENU_DATA[MEMU_VAR.CH_R_AIL] or 30)] or "--"))
|
||||
print("LFlp:".. (MODEL.PORT_TEXT[(MENU_DATA[MEMU_VAR.CH_L_FLP] or 30)] or "--"))
|
||||
print("RFlp:".. (MODEL.PORT_TEXT[(MENU_DATA[MEMU_VAR.CH_R_FLP] or 30)] or "--"))
|
||||
print("LEle:".. (MODEL.PORT_TEXT[(MENU_DATA[MEMU_VAR.CH_L_ELE] or 30)] or "--"))
|
||||
print("REle:".. (MODEL.PORT_TEXT[(MENU_DATA[MEMU_VAR.CH_R_ELE] or 30)] or "--"))
|
||||
print("LRud:".. (MODEL.PORT_TEXT[(MENU_DATA[MEMU_VAR.CH_L_RUD] or 30)] or "--"))
|
||||
print("RRud:".. (MODEL.PORT_TEXT[(MENU_DATA[MEMU_VAR.CH_R_RUD] or 30)] or "--"))
|
||||
end
|
||||
|
||||
function ModelLib.printServoReverseInfo()
|
||||
print("SERVO Normal/Reverse INFORMATION")
|
||||
for i=0, TX_CHANNELS-1 do
|
||||
local s="--"
|
||||
if (MENU_DATA[MEMU_VAR.PORT1_MODE+i] or 0) == 0 then s="NORMAL" else s="REVERSE" end
|
||||
print(string.format("Port%d: %s", i+1, s))
|
||||
end
|
||||
end
|
||||
|
||||
function ModelLib.channelType2String(byte1, byte2)
|
||||
local s = ""
|
||||
|
||||
if (byte2==0) then return s end;
|
||||
|
||||
if (bit32.band(byte2,CH_TYPE.AIL)>0) then s=s.."Ail" end
|
||||
if (bit32.band(byte2,CH_TYPE.ELE)>0) then s=s.."Ele" end
|
||||
if (bit32.band(byte2,CH_TYPE.RUD)>0) then s=s.."Rud" end
|
||||
if (bit32.band(byte2,CH_TYPE.THR)>0) then s=s.."Thr" end
|
||||
|
||||
if (bit32.band(byte2,CH_TYPE.REVERSE)>0) then s=s.."-" end
|
||||
|
||||
if (bit32.band(byte2,CH_TYPE.SLAVE)>0) then s=s.." Slv" end
|
||||
|
||||
if (byte1==CH_MIX_TYPE.MIX_NORM) then s=s.." "
|
||||
elseif (byte1==CH_MIX_TYPE.MIX_AIL) then s=s.." M_Ail"
|
||||
elseif (byte1==CH_MIX_TYPE.MIX_ELE) then s=s.." M_Ele"
|
||||
elseif (byte1==CH_MIX_TYPE.MIX_RUD) then s=s.." M_Rud"
|
||||
elseif (byte1==CH_MIX_TYPE.MIX_RUD_REV) then s=s.." M_Rud-"
|
||||
elseif (byte1==CH_MIX_TYPE.MIX_ELE_REV) then s=s.." M_Ele-"
|
||||
elseif (byte1==CH_MIX_TYPE.MIX_AIL_REV) then s=s.." M_Ail-"
|
||||
elseif (byte1==CH_MIX_TYPE.MIX_NORM_REV) then s=s.." M-"
|
||||
end
|
||||
|
||||
return s;
|
||||
end
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------------------------
|
||||
-- Read the model information from OTX/ETX
|
||||
|
||||
local function getModuleChannelOrder(num)
|
||||
--Determine fist 4 channels order
|
||||
local channel_names={}
|
||||
local stick_names = {[0]= "R", "E", "T", "A" }
|
||||
local ch_order=num
|
||||
if (ch_order == -1) then
|
||||
channel_names[0] = stick_names[3]
|
||||
channel_names[1] = stick_names[1]
|
||||
channel_names[2] = stick_names[2]
|
||||
channel_names[3] = stick_names[0]
|
||||
else
|
||||
channel_names[bit32.band(ch_order,3)] = stick_names[3]
|
||||
ch_order = math.floor(ch_order/4)
|
||||
channel_names[bit32.band(ch_order,3)] = stick_names[1]
|
||||
ch_order = math.floor(ch_order/4)
|
||||
channel_names[bit32.band(ch_order,3)] = stick_names[2]
|
||||
ch_order = math.floor(ch_order/4)
|
||||
channel_names[bit32.band(ch_order,3)] = stick_names[0]
|
||||
end
|
||||
|
||||
local s = ""
|
||||
for i=0,3 do
|
||||
s=s..channel_names[i]
|
||||
end
|
||||
return s
|
||||
end
|
||||
|
||||
function ModelLib.ReadTxModelData()
|
||||
local TRANSLATE_AETR_TO_TAER=false
|
||||
local table = model.getInfo() -- Get the model name
|
||||
MODEL.modelName = table.name
|
||||
|
||||
local module = model.getModule(0) -- Internal
|
||||
if (module==nil or module.Type~=6) then module = model.getModule(1) end -- External
|
||||
if (module~=nil) then
|
||||
if (module.Type==6 ) then -- MULTI-MODULE
|
||||
local chOrder = module.channelsOrder
|
||||
local s = getModuleChannelOrder(chOrder)
|
||||
Log.LOG_write("MultiChannel Ch Order: [%s] %s\n",chOrder,s)
|
||||
|
||||
if (s=="AETR") then TRANSLATE_AETR_TO_TAER=true
|
||||
else TRANSLATE_AETR_TO_TAER=false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Log.LOG_write("MODEL NAME = %s\n",MODEL.modelName)
|
||||
|
||||
-- Read Ch1 to Ch10
|
||||
local i= 0
|
||||
for i = 0, TX_CHANNELS-1 do
|
||||
local ch = model.getOutput(i) -- Zero base
|
||||
if (ch~=nil) then
|
||||
MODEL.modelOutputChannel[i] = ch
|
||||
if (string.len(ch.name)==0) then
|
||||
ch.formatCh = string.format("TX:Ch%i",i+1)
|
||||
else
|
||||
ch.formatCh = string.format("TX:Ch%i/%s",i+1,ch.name or "--")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Translate AETR to TAER
|
||||
-- TODO: Check if there is a way to know how to the TX is configured, since if it is
|
||||
-- already TAER, is not needed
|
||||
|
||||
if (TRANSLATE_AETR_TO_TAER) then
|
||||
Log.LOG_write("Applying AETR -> TAER translation\n")
|
||||
local ail = MODEL.modelOutputChannel[0]
|
||||
local elv = MODEL.modelOutputChannel[1]
|
||||
local thr = MODEL.modelOutputChannel[2]
|
||||
|
||||
MODEL.modelOutputChannel[0] = thr
|
||||
MODEL.modelOutputChannel[1] = ail
|
||||
MODEL.modelOutputChannel[2] = elv
|
||||
end
|
||||
|
||||
-- Create the Port Text to be used
|
||||
Log.LOG_write("Ports/Channels:\n")
|
||||
for i = 0, TX_CHANNELS-1 do
|
||||
local ch = MODEL.modelOutputChannel[i]
|
||||
if (ch~=nil) then
|
||||
MODEL.TX_CH_TEXT[i] = ch.formatCh
|
||||
MODEL.PORT_TEXT[i] = string.format("P%i (%s) ",i+1,MODEL.TX_CH_TEXT[i])
|
||||
|
||||
Log.LOG_write("Port%d %s [%d,%d] Rev=%d, Off=%d, ppmC=%d, syn=%d\n",i+1,MODEL.TX_CH_TEXT[i],math.floor(ch.min/10),math.floor(ch.max/10), ch.revert, ch.offset, ch.ppmCenter, ch.symetrical)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
----------------------- FILE MANAGEMENT ---------------------------------------------
|
||||
-- Create a fairly unique name for a model..combination of name and a hash
|
||||
-- TODO: Check with ETX why we can't get the filename used to store the model info
|
||||
-- Improvement request??
|
||||
|
||||
function ModelLib.hashName(mName)
|
||||
local c=10000;
|
||||
|
||||
local prefix = string.gsub(mName,"%.","_") -- Change any "." to "_"
|
||||
prefix = string.gsub(prefix,"% ","_") -- Change any space to "_"
|
||||
prefix = string.sub(prefix,1,5) -- Take the first 5 characters
|
||||
|
||||
-- Simple Hash of the Model Name adding each character
|
||||
for i = 1, #mName do
|
||||
local ch = string.byte(mName,i,i)
|
||||
c=c+ch
|
||||
end
|
||||
|
||||
return (prefix .. c) -- Return Prefix + Hash
|
||||
end
|
||||
|
||||
-- Load Menu Data from a file
|
||||
function ModelLib.ST_LoadFileData()
|
||||
local fname = ModelLib.hashName(MODEL.modelName)..".txt"
|
||||
|
||||
-- Clear Menu Data
|
||||
for i = 0, MEMU_VAR.DATA_END do
|
||||
MENU_DATA[i]=nil
|
||||
end
|
||||
|
||||
print("Loading File:"..fname)
|
||||
|
||||
local dataFile = io.open(DATA_PATH .. "/".. fname, "r") -- read File
|
||||
-- cannot read file???
|
||||
if (dataFile==nil) then return 0 end
|
||||
|
||||
local line = io.read(dataFile, 5000)
|
||||
io.close(dataFile)
|
||||
|
||||
if #line == 0 then return 0 end -- No data??
|
||||
|
||||
-- Process the input, each line is "Var_Id : Value" format
|
||||
-- Store it into MANU_DATA
|
||||
local i=0
|
||||
for k, v in string.gmatch(line, "(%d+):(%d+)") do
|
||||
--print(string.format("Read MENU_DATA[%d]:[%d]",k, v))
|
||||
MENU_DATA[k+0]=v+0 -- do aritmentic to convert string to number
|
||||
i=i+1
|
||||
end
|
||||
|
||||
local currAircraftType = MENU_DATA[MEMU_VAR.AIRCRAFT_TYPE]
|
||||
local currWingType = MENU_DATA[MEMU_VAR.WING_TYPE]
|
||||
local currTailType = MENU_DATA[MEMU_VAR.TAIL_TYPE]
|
||||
|
||||
print("Validation")
|
||||
print(string.format("AIRCRAFT_TYPE(%d)=%s", MEMU_VAR.AIRCRAFT_TYPE,aircraft_type_text[currAircraftType]))
|
||||
print(string.format("WING_TYPE(%d)=%s", MEMU_VAR.WING_TYPE, wing_type_text[currWingType]))
|
||||
print(string.format("TAIL_TYPE(%d)=%s", MEMU_VAR.TAIL_TYPE, tail_type_text[currTailType]))
|
||||
|
||||
ModelLib.printChannelSummary()
|
||||
ModelLib.printServoReverseInfo()
|
||||
|
||||
-- Return 0 if no lines processed, 1 otherwise
|
||||
if (i > 0) then return 1 else return 0 end
|
||||
end
|
||||
|
||||
-- Saves MENU_DATA to a file
|
||||
function ModelLib.ST_SaveFileData()
|
||||
local fname = ModelLib.hashName(MODEL.modelName)..".txt"
|
||||
|
||||
print("Saving File:"..fname)
|
||||
local dataFile = assert(io.open(DATA_PATH .. "/" .. fname, "w"),"Please create "..DATA_PATH.." folder") -- write File
|
||||
|
||||
-- Foreach MENU_DATA with a value write Var_Id:Value into file
|
||||
for i = 0, MEMU_VAR.DATA_END do
|
||||
if (MENU_DATA[i]~=nil) then
|
||||
--print(string.format("Write MENU_DATA[%s] : %s",i,MENU_DATA[i]))
|
||||
io.write(dataFile,string.format("%s:%s\n",i,MENU_DATA[i]))
|
||||
end
|
||||
end
|
||||
io.close(dataFile)
|
||||
end
|
||||
|
||||
-- This Creates the Servo Settings that will be used to pass to
|
||||
-- Forward programming
|
||||
function ModelLib.CreateDSMPortChannelInfo()
|
||||
local function ApplyWingMixA(b2)
|
||||
-- ELEVON
|
||||
if (b2==CH_TYPE.AIL+CH_TYPE.ELE) then return CH_MIX_TYPE.MIX_ELE end; -- 0x03
|
||||
if (b2==CH_TYPE.AIL+CH_TYPE.ELE+CH_TYPE.SLAVE) then return CH_MIX_TYPE.MIX_NORM end; -- 0x83
|
||||
end
|
||||
|
||||
local function ApplyWingMixB(b2)
|
||||
-- ELEVON
|
||||
if (b2==CH_TYPE.AIL+CH_TYPE.ELE) then return CH_MIX_TYPE.MIX_NORM end; -- 0x03
|
||||
if (b2==CH_TYPE.AIL+CH_TYPE.ELE+CH_TYPE.SLAVE) then return CH_MIX_TYPE.MIX_ELE end; -- 0x83
|
||||
end
|
||||
|
||||
local function ApplyTailMixA(b2)
|
||||
-- VTAIL
|
||||
-- Default normal/reverse behaviour
|
||||
if (b2==CH_TYPE.RUD+CH_TYPE.ELE) then return CH_MIX_TYPE.MIX_NORM end; -- 0x06
|
||||
if (b2==CH_TYPE.RUD+CH_TYPE.ELE+CH_TYPE.SLAVE) then return CH_MIX_TYPE.MIX_ELE end; -- 0x86
|
||||
|
||||
--TAILERON
|
||||
-- Default normal/reverse behaviour
|
||||
if (b2==CH_TYPE.AIL+CH_TYPE.ELE) then return CH_MIX_TYPE.MIX_NORM end; -- 0x03
|
||||
if (b2==CH_TYPE.AIL+CH_TYPE.ELE+CH_TYPE.SLAVE) then return CH_MIX_TYPE.MIX_AIL end; -- 0x83
|
||||
end
|
||||
|
||||
local function ApplyTailMixB(b2)
|
||||
-- VTAIL
|
||||
-- Default normal/reverse behaviour
|
||||
if (b2==CH_TYPE.RUD+CH_TYPE.ELE) then return CH_MIX_TYPE.MIX_NORM end; -- 0x06
|
||||
if (b2==CH_TYPE.RUD+CH_TYPE.ELE+CH_TYPE.SLAVE) then return CH_MIX_TYPE.MIX_RUD end; -- 0x86
|
||||
|
||||
--TAILERON
|
||||
if (b2==CH_TYPE.AIL+CH_TYPE.ELE) then return CH_MIX_TYPE.MIX_AIL end; -- 0x03
|
||||
if (b2==CH_TYPE.AIL+CH_TYPE.ELE+CH_TYPE.SLAVE) then return CH_MIX_TYPE.MIX_NORM end; -- 0x83
|
||||
end
|
||||
|
||||
local function reverseMix(b)
|
||||
if (b==CH_MIX_TYPE.MIX_NORM) then return CH_MIX_TYPE.MIX_NORM_REV end;
|
||||
if (b==CH_MIX_TYPE.MIX_AIL) then return CH_MIX_TYPE.MIX_AIL_REV end;
|
||||
if (b==CH_MIX_TYPE.MIX_ELE) then return CH_MIX_TYPE.MIX_ELE_REV end;
|
||||
if (b==CH_MIX_TYPE.MIX_RUD) then return CH_MIX_TYPE.MIX_RUD_REV end;
|
||||
return b
|
||||
end
|
||||
|
||||
|
||||
|
||||
local DSM_ChannelInfo = MODEL.DSM_ChannelInfo
|
||||
|
||||
for i=0, TX_CHANNELS-1 do
|
||||
DSM_ChannelInfo[i] = {[0]= CH_MIX_TYPE.MIX_NORM, CH_TYPE.NONE} -- Initialize with no special function
|
||||
end
|
||||
|
||||
local aircraftType = MENU_DATA[MEMU_VAR.AIRCRAFT_TYPE]
|
||||
local wingType = MENU_DATA[MEMU_VAR.WING_TYPE]
|
||||
local tailType = MENU_DATA[MEMU_VAR.TAIL_TYPE]
|
||||
|
||||
local thrCh = MENU_DATA[MEMU_VAR.CH_THR]
|
||||
local lAilCh = MENU_DATA[MEMU_VAR.CH_L_AIL]
|
||||
local rAilCh = MENU_DATA[MEMU_VAR.CH_R_AIL]
|
||||
local lflapCh = MENU_DATA[MEMU_VAR.CH_L_FLP]
|
||||
local rflapCh = MENU_DATA[MEMU_VAR.CH_R_FLP]
|
||||
|
||||
local lElevCh = MENU_DATA[MEMU_VAR.CH_L_ELE]
|
||||
local rElevCh = MENU_DATA[MEMU_VAR.CH_R_ELE]
|
||||
|
||||
local lRudCh = MENU_DATA[MEMU_VAR.CH_L_RUD]
|
||||
local rRudCh = MENU_DATA[MEMU_VAR.CH_R_RUD]
|
||||
|
||||
-- Channels in menu vars are Zero base, Channel info is 1 based
|
||||
|
||||
-- THR
|
||||
if (thrCh~=nil and thrCh < 10) then DSM_ChannelInfo[thrCh][1]= CH_TYPE.THR end
|
||||
|
||||
-- AIL (Left and Right)
|
||||
if (lAilCh~=nil) then DSM_ChannelInfo[lAilCh][1] = CH_TYPE.AIL end
|
||||
if (rAilCh~=nil) then DSM_ChannelInfo[rAilCh][1] = CH_TYPE.AIL+CH_TYPE.SLAVE end
|
||||
-- ELE (Left and Right)
|
||||
if (lElevCh~=nil) then DSM_ChannelInfo[lElevCh][1] = CH_TYPE.ELE end
|
||||
if (rElevCh~=nil) then DSM_ChannelInfo[rElevCh][1] = CH_TYPE.ELE+CH_TYPE.SLAVE end
|
||||
-- RUD (Left and Right)
|
||||
if (lRudCh~=nil) then DSM_ChannelInfo[lRudCh][1] = CH_TYPE.RUD end
|
||||
if (rRudCh~=nil) then DSM_ChannelInfo[rRudCh][1] = CH_TYPE.RUD+CH_TYPE.SLAVE end
|
||||
|
||||
-- VTAIL: RUD + ELE
|
||||
if (tailType==TAIL_TYPE.VTAIL_A or tailType==TAIL_TYPE.VTAIL_B) then
|
||||
DSM_ChannelInfo[lElevCh][1] = CH_TYPE.RUD+CH_TYPE.ELE
|
||||
DSM_ChannelInfo[rElevCh][1] = CH_TYPE.RUD+CH_TYPE.ELE+CH_TYPE.SLAVE
|
||||
end
|
||||
|
||||
-- TAILERRON: 2-ELE + AIL
|
||||
if (tailType==TAIL_TYPE.TRAILERON_A or tailType==TAIL_TYPE.TRAILERON_A_R2 or
|
||||
tailType==TAIL_TYPE.TRAILERON_B or tailType==TAIL_TYPE.TRAILERON_B_R2) then
|
||||
DSM_ChannelInfo[lElevCh][1] = CH_TYPE.AIL+CH_TYPE.ELE
|
||||
DSM_ChannelInfo[rElevCh][1] = CH_TYPE.AIL+CH_TYPE.ELE+CH_TYPE.SLAVE
|
||||
end
|
||||
|
||||
---- ELEVON : AIL + ELE
|
||||
if (wingType==WING_TYPE.ELEVON_A or wingType==WING_TYPE.ELEVON_B) then
|
||||
DSM_ChannelInfo[lAilCh][1] = CH_TYPE.AIL+CH_TYPE.ELE
|
||||
DSM_ChannelInfo[rAilCh][1] = CH_TYPE.AIL+CH_TYPE.ELE+CH_TYPE.SLAVE
|
||||
end
|
||||
|
||||
------MIXES ---------
|
||||
|
||||
-- TAIL Mixes (Elevator and VTail)
|
||||
if (tailType==TAIL_TYPE.VTAIL_A or tailType==TAIL_TYPE.TRAILERON_A or tailType==TAIL_TYPE.TRAILERON_A_R2) then
|
||||
DSM_ChannelInfo[lElevCh][0] = ApplyTailMixA(DSM_ChannelInfo[lElevCh][1])
|
||||
DSM_ChannelInfo[rElevCh][0] = ApplyTailMixA(DSM_ChannelInfo[rElevCh][1])
|
||||
elseif (tailType==TAIL_TYPE.VTAIL_B or tailType==TAIL_TYPE.TRAILERON_B or tailType==TAIL_TYPE.TRAILERON_B_R2) then
|
||||
DSM_ChannelInfo[lElevCh][0] = ApplyTailMixA(DSM_ChannelInfo[lElevCh][1])
|
||||
DSM_ChannelInfo[rElevCh][0] = ApplyTailMixA(DSM_ChannelInfo[rElevCh][1])
|
||||
end
|
||||
|
||||
---- Wing Mixes
|
||||
if (wingType==WING_TYPE.ELEVON_A) then
|
||||
DSM_ChannelInfo[lAilCh][0] = ApplyWingMixA(DSM_ChannelInfo[lAilCh][1])
|
||||
DSM_ChannelInfo[rAilCh][0] = ApplyWingMixA(DSM_ChannelInfo[rAilCh][1])
|
||||
elseif (wingType==WING_TYPE.ELEVON_B) then
|
||||
DSM_ChannelInfo[lAilCh][0] = ApplyWingMixB(DSM_ChannelInfo[lAilCh][1])
|
||||
DSM_ChannelInfo[rAilCh][0] = ApplyWingMixB(DSM_ChannelInfo[rAilCh][1])
|
||||
end
|
||||
|
||||
-- Apply Gyro Reverse as needed for each channel as long as it is used
|
||||
for i=0, TX_CHANNELS-1 do
|
||||
if (MENU_DATA[MEMU_VAR.PORT_BASE+i]==CH_MODE_TYPE.REVERSE and DSM_ChannelInfo[i][1]>0) then
|
||||
DSM_ChannelInfo[i][0]=reverseMix(DSM_ChannelInfo[i][0])
|
||||
DSM_ChannelInfo[i][1]=DSM_ChannelInfo[i][1]+CH_TYPE.REVERSE
|
||||
end
|
||||
end
|
||||
|
||||
-- Show how it looks
|
||||
for i=0, 9 do
|
||||
local b1,b2 = DSM_ChannelInfo[i][0], DSM_ChannelInfo[i][1]
|
||||
print(string.format("%s (%02X %02X) %s", MODEL.PORT_TEXT[i],
|
||||
b1, b2, ModelLib.channelType2String(b1,b2)))
|
||||
end
|
||||
|
||||
MODEL.AirWingTailDesc = string.format("Aircraft(%s) Wing(%s) Tail(%s)",aircraft_type_text[aircraftType],wing_type_text[wingType],tail_type_text[tailType])
|
||||
end
|
||||
|
||||
function ModelLib.ST_PlaneWingInit(wingType)
|
||||
print("Change Plane WingType:"..wing_type_text[wingType])
|
||||
|
||||
MENU_DATA[MEMU_VAR.WING_TYPE] = wingType
|
||||
|
||||
-- Clear all Wing Data
|
||||
MENU_DATA[MEMU_VAR.CH_L_AIL] = nil
|
||||
MENU_DATA[MEMU_VAR.CH_R_AIL] = nil
|
||||
MENU_DATA[MEMU_VAR.CH_L_FLP] = nil
|
||||
MENU_DATA[MEMU_VAR.CH_R_FLP] = nil
|
||||
|
||||
MENU_DATA[MEMU_VAR.CH_THR] = PORT.PORT1
|
||||
|
||||
-- Default Channel Assisgments for each Wing type
|
||||
|
||||
if (wingType==WING_TYPE.AIL_1) then
|
||||
MENU_DATA[MEMU_VAR.CH_L_AIL] = PORT.PORT2
|
||||
elseif (wingType==WING_TYPE.AIL_2) then
|
||||
MENU_DATA[MEMU_VAR.CH_L_AIL] = PORT.PORT6
|
||||
MENU_DATA[MEMU_VAR.CH_R_AIL] = PORT.PORT2
|
||||
elseif (wingType==WING_TYPE.FLAPERON) then
|
||||
MENU_DATA[MEMU_VAR.CH_L_AIL] = PORT.PORT6
|
||||
MENU_DATA[MEMU_VAR.CH_R_AIL] = PORT.PORT2
|
||||
elseif (wingType==WING_TYPE.AIL_1_FLP_1) then
|
||||
MENU_DATA[MEMU_VAR.CH_L_AIL] = PORT.PORT2
|
||||
MENU_DATA[MEMU_VAR.CH_L_FLP] = PORT.PORT6
|
||||
elseif (wingType==WING_TYPE.AIL_2_FLP_1) then
|
||||
MENU_DATA[MEMU_VAR.CH_L_AIL] = PORT.PORT6
|
||||
MENU_DATA[MEMU_VAR.CH_R_AIL] = PORT.PORT2
|
||||
MENU_DATA[MEMU_VAR.CH_L_FLP] = PORT.PORT5
|
||||
elseif (wingType==WING_TYPE.AIL_2_FLP_2) then
|
||||
MENU_DATA[MEMU_VAR.CH_L_AIL] = PORT.PORT6
|
||||
MENU_DATA[MEMU_VAR.CH_R_AIL] = PORT.PORT2
|
||||
MENU_DATA[MEMU_VAR.CH_R_FLP] = PORT.PORT5
|
||||
MENU_DATA[MEMU_VAR.CH_L_FLP] = PORT.PORT7
|
||||
elseif (wingType==WING_TYPE.ELEVON_A) then
|
||||
MENU_DATA[MEMU_VAR.CH_L_AIL] = PORT.PORT2
|
||||
MENU_DATA[MEMU_VAR.CH_R_AIL] = PORT.PORT3
|
||||
elseif (wingType==WING_TYPE.ELEVON_B) then
|
||||
MENU_DATA[MEMU_VAR.CH_L_AIL] = PORT.PORT3
|
||||
MENU_DATA[MEMU_VAR.CH_R_AIL] = PORT.PORT2
|
||||
else -- Assume normal
|
||||
print("ERROR: Invalid Wing Type")
|
||||
end
|
||||
|
||||
|
||||
ModelLib.printChannelSummary()
|
||||
end
|
||||
|
||||
function ModelLib.ST_PlaneTailInit(tailType)
|
||||
if (MENU_DATA[MEMU_VAR.WING_TYPE]==WING_TYPE.ELEVON_A or
|
||||
MENU_DATA[MEMU_VAR.WING_TYPE]==WING_TYPE.ELEVON_B) then
|
||||
tailType = TAIL_TYPE.RUD_1 -- Delta only have ruder
|
||||
end
|
||||
|
||||
print("Change Plane Tail Type:"..tail_type_text[tailType])
|
||||
|
||||
-- Clear all data for Tail
|
||||
MENU_DATA[MEMU_VAR.TAIL_TYPE] = tailType
|
||||
MENU_DATA[MEMU_VAR.CH_L_ELE] = nil
|
||||
MENU_DATA[MEMU_VAR.CH_R_ELE] = nil
|
||||
MENU_DATA[MEMU_VAR.CH_L_RUD] = nil
|
||||
MENU_DATA[MEMU_VAR.CH_R_RUD] = nil
|
||||
|
||||
-- Setup Channels for different Tail types
|
||||
if (tailType == TAIL_TYPE.RUD_1) then
|
||||
MENU_DATA[MEMU_VAR.CH_L_RUD] = PORT.PORT4
|
||||
elseif (tailType == TAIL_TYPE.RUD_1_ELEV_1) then
|
||||
MENU_DATA[MEMU_VAR.CH_L_ELE] = PORT.PORT3
|
||||
MENU_DATA[MEMU_VAR.CH_L_RUD] = PORT.PORT4
|
||||
elseif (tailType == TAIL_TYPE.RUD_1_ELEV_2) then
|
||||
MENU_DATA[MEMU_VAR.CH_L_ELE] = PORT.PORT5
|
||||
MENU_DATA[MEMU_VAR.CH_R_ELE] = PORT.PORT3
|
||||
MENU_DATA[MEMU_VAR.CH_L_RUD] = PORT.PORT4
|
||||
elseif (tailType == TAIL_TYPE.RUD_2_ELEV_1) then
|
||||
MENU_DATA[MEMU_VAR.CH_L_ELE] = PORT.PORT3
|
||||
MENU_DATA[MEMU_VAR.CH_L_RUD] = PORT.PORT4
|
||||
MENU_DATA[MEMU_VAR.CH_R_RUD] = PORT.PORT5
|
||||
elseif (tailType == TAIL_TYPE.RUD_2_ELEV_2) then
|
||||
MENU_DATA[MEMU_VAR.CH_L_ELE] = PORT.PORT5
|
||||
MENU_DATA[MEMU_VAR.CH_R_ELE] = PORT.PORT3
|
||||
MENU_DATA[MEMU_VAR.CH_L_RUD] = PORT.PORT4
|
||||
MENU_DATA[MEMU_VAR.CH_R_RUD] = PORT.PORT6
|
||||
elseif (tailType == TAIL_TYPE.VTAIL_A or tailType == TAIL_TYPE.VTAIL_B) then
|
||||
MENU_DATA[MEMU_VAR.CH_L_ELE] = PORT.PORT4
|
||||
MENU_DATA[MEMU_VAR.CH_R_ELE] = PORT.PORT3
|
||||
elseif (tailType == TAIL_TYPE.TRAILERON_A or tailType==TAIL_TYPE.TRAILERON_A_R2 or
|
||||
tailType == TAIL_TYPE.TRAILERON_B or tailType==TAIL_TYPE.TRAILERON_B_R2) then
|
||||
MENU_DATA[MEMU_VAR.CH_L_RUD] = PORT.PORT4
|
||||
MENU_DATA[MEMU_VAR.CH_L_ELE] = PORT.PORT5
|
||||
MENU_DATA[MEMU_VAR.CH_R_ELE] = PORT.PORT3
|
||||
else -- Assume Normal
|
||||
print("ERROR:invalid Tail Type")
|
||||
end
|
||||
|
||||
if (tailType == TAIL_TYPE.TRAILERON_A_R2 or tailType==TAIL_TYPE.TRAILERON_B_R2) then
|
||||
MENU_DATA[MEMU_VAR.CH_R_RUD] = PORT.PORT7
|
||||
end
|
||||
|
||||
ModelLib.printChannelSummary()
|
||||
end
|
||||
|
||||
function ModelLib.ST_GliderWingInit(wingType)
|
||||
print("Change Glider WingType:"..wing_type_text[wingType])
|
||||
|
||||
MENU_DATA[MEMU_VAR.WING_TYPE] = wingType
|
||||
|
||||
-- Clear all Wing Data
|
||||
MENU_DATA[MEMU_VAR.CH_L_AIL] = nil
|
||||
MENU_DATA[MEMU_VAR.CH_R_AIL] = nil
|
||||
MENU_DATA[MEMU_VAR.CH_L_FLP] = nil
|
||||
MENU_DATA[MEMU_VAR.CH_R_FLP] = nil
|
||||
MENU_DATA[MEMU_VAR.CH_THR] = PORT.PORT6
|
||||
|
||||
-- Default Channel Assisgments for each Wing type
|
||||
|
||||
if (wingType==WING_TYPE.AIL_1) then
|
||||
MENU_DATA[MEMU_VAR.CH_L_AIL] = PORT.PORT1
|
||||
elseif (wingType==WING_TYPE.AIL_2) then
|
||||
MENU_DATA[MEMU_VAR.CH_L_AIL] = PORT.PORT1
|
||||
MENU_DATA[MEMU_VAR.CH_R_AIL] = PORT.PORT2
|
||||
elseif (wingType==WING_TYPE.AIL_2_FLP_1) then
|
||||
MENU_DATA[MEMU_VAR.CH_L_AIL] = PORT.PORT1
|
||||
MENU_DATA[MEMU_VAR.CH_R_AIL] = PORT.PORT2
|
||||
MENU_DATA[MEMU_VAR.CH_L_FLP] = PORT.PORT5
|
||||
elseif (wingType==WING_TYPE.AIL_2_FLP_2) then
|
||||
MENU_DATA[MEMU_VAR.CH_L_AIL] = PORT.PORT1
|
||||
MENU_DATA[MEMU_VAR.CH_R_AIL] = PORT.PORT2
|
||||
MENU_DATA[MEMU_VAR.CH_L_FLP] = PORT.PORT5
|
||||
MENU_DATA[MEMU_VAR.CH_R_FLP] = PORT.PORT6
|
||||
MENU_DATA[MEMU_VAR.CH_THR] = PORT.PORT7
|
||||
elseif (wingType==WING_TYPE.ELEVON_A) then
|
||||
MENU_DATA[MEMU_VAR.CH_L_AIL] = PORT.PORT1
|
||||
MENU_DATA[MEMU_VAR.CH_R_AIL] = PORT.PORT2
|
||||
elseif (wingType==WING_TYPE.ELEVON_B) then
|
||||
MENU_DATA[MEMU_VAR.CH_L_AIL] = PORT.PORT2
|
||||
MENU_DATA[MEMU_VAR.CH_R_AIL] = PORT.PORT1
|
||||
else -- Assume normal
|
||||
print("ERROR: Invalid Wing Type")
|
||||
end
|
||||
|
||||
ModelLib.printChannelSummary()
|
||||
end
|
||||
|
||||
function ModelLib.ST_GliderTailInit(tailType)
|
||||
if (MENU_DATA[MEMU_VAR.WING_TYPE]==WING_TYPE.ELEVON_A) then
|
||||
tailType = TAIL_TYPE.RUD_1 -- Delta only have ruder
|
||||
end
|
||||
|
||||
print("Change Glider Tail Type:"..tail_type_text[tailType])
|
||||
|
||||
-- Clear all data for Tail
|
||||
MENU_DATA[MEMU_VAR.TAIL_TYPE] = tailType
|
||||
MENU_DATA[MEMU_VAR.CH_L_ELE] = nil
|
||||
MENU_DATA[MEMU_VAR.CH_R_ELE] = nil
|
||||
MENU_DATA[MEMU_VAR.CH_L_RUD] = nil
|
||||
MENU_DATA[MEMU_VAR.CH_R_RUD] = nil
|
||||
|
||||
-- Setup Channels for different Tail types
|
||||
if (tailType == TAIL_TYPE.RUD_1) then
|
||||
MENU_DATA[MEMU_VAR.CH_L_RUD] = PORT.PORT4
|
||||
elseif (tailType == TAIL_TYPE.RUD_1_ELEV_1) then
|
||||
MENU_DATA[MEMU_VAR.CH_L_ELE] = PORT.PORT3
|
||||
MENU_DATA[MEMU_VAR.CH_L_RUD] = PORT.PORT4
|
||||
elseif (tailType == TAIL_TYPE.VTAIL_A) then
|
||||
MENU_DATA[MEMU_VAR.CH_L_ELE] = PORT.PORT4
|
||||
MENU_DATA[MEMU_VAR.CH_R_ELE] = PORT.PORT3
|
||||
elseif (tailType == TAIL_TYPE.VTAIL_B) then
|
||||
MENU_DATA[MEMU_VAR.CH_L_ELE] = PORT.PORT3
|
||||
MENU_DATA[MEMU_VAR.CH_R_ELE] = PORT.PORT4
|
||||
else -- Assume Normal
|
||||
print("ERROR: Invalid Tail Type")
|
||||
end
|
||||
|
||||
ModelLib.printChannelSummary()
|
||||
end
|
||||
|
||||
|
||||
function ModelLib.ST_AircraftInit(aircraftType)
|
||||
MENU_DATA[MEMU_VAR.AIRCRAFT_TYPE] = aircraftType
|
||||
|
||||
print("Change Aircraft:".. aircraft_type_text[aircraftType])
|
||||
|
||||
-- Setup Default Aircraft Wing/Tail
|
||||
if (aircraftType==AIRCRAFT_TYPE.PLANE) then
|
||||
ModelLib.ST_PlaneWingInit(WING_TYPE.AIL_1)
|
||||
ModelLib.ST_PlaneTailInit(TAIL_TYPE.RUD_1_ELEV_1)
|
||||
elseif (aircraftType==AIRCRAFT_TYPE.GLIDER) then
|
||||
ModelLib.ST_GliderWingInit(WING_TYPE.AIL_1)
|
||||
ModelLib.ST_GliderTailInit(TAIL_TYPE.RUD_1_ELEV_1)
|
||||
else
|
||||
ModelLib.ST_PlaneWingInit(WING_TYPE.AIL_1)
|
||||
ModelLib.ST_PlaneTailInit(TAIL_TYPE.RUD_1_ELEV_1)
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
-- Setup Initial Default Data for the Menus
|
||||
function ModelLib.ST_Default_Data()
|
||||
print("Initializing Menu DATA")
|
||||
ModelLib.ST_AircraftInit(AIRCRAFT_TYPE.PLANE)
|
||||
|
||||
print("Initializing Servo Reverse from TX output settings")
|
||||
|
||||
MENU_DATA[MEMU_VAR.PORT1_MODE] = CH_MODE_TYPE.NORMAL + MODEL.modelOutputChannel[PORT.PORT1].revert
|
||||
MENU_DATA[MEMU_VAR.PORT2_MODE] = CH_MODE_TYPE.NORMAL + MODEL.modelOutputChannel[PORT.PORT2].revert
|
||||
MENU_DATA[MEMU_VAR.PORT3_MODE] = CH_MODE_TYPE.NORMAL + MODEL.modelOutputChannel[PORT.PORT3].revert
|
||||
MENU_DATA[MEMU_VAR.PORT4_MODE] = CH_MODE_TYPE.NORMAL + MODEL.modelOutputChannel[PORT.PORT4].revert
|
||||
MENU_DATA[MEMU_VAR.PORT5_MODE] = CH_MODE_TYPE.NORMAL + MODEL.modelOutputChannel[PORT.PORT5].revert
|
||||
MENU_DATA[MEMU_VAR.PORT6_MODE] = CH_MODE_TYPE.NORMAL + MODEL.modelOutputChannel[PORT.PORT6].revert
|
||||
MENU_DATA[MEMU_VAR.PORT7_MODE] = CH_MODE_TYPE.NORMAL + MODEL.modelOutputChannel[PORT.PORT7].revert
|
||||
MENU_DATA[MEMU_VAR.PORT8_MODE] = CH_MODE_TYPE.NORMAL + MODEL.modelOutputChannel[PORT.PORT8].revert
|
||||
MENU_DATA[MEMU_VAR.PORT9_MODE] = CH_MODE_TYPE.NORMAL + MODEL.modelOutputChannel[PORT.PORT9].revert
|
||||
MENU_DATA[MEMU_VAR.PORT10_MODE] = CH_MODE_TYPE.NORMAL + MODEL.modelOutputChannel[PORT.PORT10].revert
|
||||
|
||||
ModelLib.printServoReverseInfo()
|
||||
|
||||
end
|
||||
|
||||
|
||||
ModelLib.TX_CHANNELS = TX_CHANNELS
|
||||
ModelLib.MODEL = MODEL
|
||||
ModelLib.CH_TYPE = CH_TYPE
|
||||
ModelLib.CH_MODE_TYPE = CH_MODE_TYPE
|
||||
ModelLib.AIRCRAFT_TYPE = AIRCRAFT_TYPE
|
||||
ModelLib.WING_TYPE = WING_TYPE
|
||||
ModelLib.TAIL_TYPE = TAIL_TYPE
|
||||
ModelLib.MENU_DATA = MENU_DATA
|
||||
ModelLib.MEMU_VAR = MEMU_VAR
|
||||
ModelLib.PORT = PORT
|
||||
ModelLib.DATA_PATH = DATA_PATH
|
||||
|
||||
ModelLib.aircraft_type_text = aircraft_type_text
|
||||
ModelLib.wing_type_text = wing_type_text
|
||||
ModelLib.tail_type_text = tail_type_text
|
||||
|
||||
|
||||
return ModelLib
|
||||
|
||||
467
SCRIPTS/TOOLS/DSMLIB/DsmSetupMenuLib.lua
Normal file
|
|
@ -0,0 +1,467 @@
|
|||
---- #########################################################################
|
||||
---- # #
|
||||
---- # Copyright (C) OpenTX #
|
||||
-----# #
|
||||
---- # 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. #
|
||||
---- # #
|
||||
---- #########################################################################
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
-- This scrip does the airplane Setup similar to how a a Spektrum radio does
|
||||
-- it. You can select the plane type, the Wing type, etc.
|
||||
-- This settings are needed for ForwardProgramming to send the TX aircraft
|
||||
-- configuration to the RX when in Initial Setup
|
||||
-- Author: Francisco Arzu
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
local Log, menuLib, modelLib, DEBUG_ON, SIMULATION_ON = ... -- Get DebugON from parameters
|
||||
local SETUP_LIB_VERSION = "0.56"
|
||||
|
||||
local DATA_PATH = modelLib.DATA_PATH
|
||||
|
||||
local PHASE = menuLib.PHASE
|
||||
local LINE_TYPE = menuLib.LINE_TYPE
|
||||
|
||||
local MODEL = modelLib.MODEL
|
||||
|
||||
local AIRCRAFT_TYPE = modelLib.AIRCRAFT_TYPE
|
||||
local WING_TYPE = modelLib.WING_TYPE
|
||||
local TAIL_TYPE = modelLib.TAIL_TYPE
|
||||
local CH_MODE_TYPE = modelLib.CH_MODE_TYPE
|
||||
local PORT = modelLib.PORT
|
||||
local MEMU_VAR = modelLib.MEMU_VAR
|
||||
local MENU_DATA = modelLib.MENU_DATA
|
||||
|
||||
local SetupLib = {}
|
||||
|
||||
local lastGoodMenu=0
|
||||
|
||||
------------------- Model Setup Helper functions ----------------------
|
||||
local currAircraftType = -1 -- Current AircraftType selected, and to detect change
|
||||
local currTailType = -1 -- Current WingType selected, and to detect change
|
||||
local currWingType = -1 -- Current TailType selected, and to detect change
|
||||
|
||||
local menuDataChanged = false -- Flag to notify if any data has changed
|
||||
|
||||
|
||||
local function tailTypeCompatible(a,b)
|
||||
|
||||
local function normalize(tt)
|
||||
if (tt==TAIL_TYPE.TRAILERON_A or tt==TAIL_TYPE.TRAILERON_B) then
|
||||
return TAIL_TYPE.TRAILERON_A
|
||||
elseif (tt==TAIL_TYPE.TRAILERON_A_R2 or tt==TAIL_TYPE.TRAILERON_B_R2) then
|
||||
return TAIL_TYPE.TRAILERON_A_R2
|
||||
elseif (tt==TAIL_TYPE.VTAIL_A or tt==TAIL_TYPE.VTAIL_B) then
|
||||
return TAIL_TYPE.VTAIL_A
|
||||
else
|
||||
return tt
|
||||
end
|
||||
end
|
||||
|
||||
return (normalize(a)==normalize(b))
|
||||
end
|
||||
|
||||
|
||||
-- Creates the menus to Render with the GUI
|
||||
local function ST_LoadMenu(menuId)
|
||||
local ctx = menuLib.DSM_Context
|
||||
|
||||
local function portUse(p)
|
||||
local out = ""
|
||||
if p==MENU_DATA[MEMU_VAR.CH_THR] then out = "Thr"
|
||||
elseif p == MENU_DATA[MEMU_VAR.CH_L_AIL] then
|
||||
out=(MENU_DATA[MEMU_VAR.CH_R_AIL] and "Ail_L") or "Ail"
|
||||
elseif p == MENU_DATA[MEMU_VAR.CH_R_AIL] then out="Ail_R"
|
||||
elseif p == MENU_DATA[MEMU_VAR.CH_L_ELE] then
|
||||
out=(MENU_DATA[MEMU_VAR.CH_R_ELE] and "Ele_L") or "Ele"
|
||||
elseif p == MENU_DATA[MEMU_VAR.CH_R_ELE] then out="Ele_R"
|
||||
elseif p == MENU_DATA[MEMU_VAR.CH_L_RUD] then
|
||||
out=(MENU_DATA[MEMU_VAR.CH_R_RUD] and "Rud_L") or "Rud"
|
||||
elseif p == MENU_DATA[MEMU_VAR.CH_R_RUD] then out="Rud_R"
|
||||
elseif p == MENU_DATA[MEMU_VAR.CH_L_FLP] then
|
||||
out=(MENU_DATA[MEMU_VAR.CH_R_FLP] and "Flp_L") or "Flp"
|
||||
elseif p == MENU_DATA[MEMU_VAR.CH_R_FLP] then out="Flp_R"
|
||||
end
|
||||
return out
|
||||
end
|
||||
|
||||
local function formatTXRevert(port)
|
||||
local out = " " .. modelLib.channelType2String(MODEL.DSM_ChannelInfo[port][0], MODEL.DSM_ChannelInfo[port][1]);
|
||||
return out
|
||||
end
|
||||
|
||||
local function Header(p)
|
||||
return MODEL.PORT_TEXT[p].." "..portUse(p)
|
||||
end
|
||||
|
||||
menuLib.clearMenuLines()
|
||||
|
||||
|
||||
if (menuId==0x1000) then -- MAIN MENU
|
||||
ctx.Menu = { MenuId = 0x1000, Text = "Save-Exit ("..MODEL.modelName..")", PrevId = 0, NextId = 0, BackId = 0, TextId=0 }
|
||||
|
||||
if (true) then
|
||||
ctx.MenuLines[4] = { Type = LINE_TYPE.MENU, Text="Save Changes", TextId = 0, ValId = 0x1005 }
|
||||
ctx.MenuLines[5] = { Type = LINE_TYPE.MENU, Text="Discard Changes", TextId = 0, ValId = 0x1006 }
|
||||
ctx.SelLine = 4
|
||||
end
|
||||
lastGoodMenu = menuId
|
||||
elseif (menuId==0x1001) then -- MODEL SETUP
|
||||
local backId = 0xFFF9 -- No changes, just exit
|
||||
local title = "Model Setup ("..MODEL.modelName..")"
|
||||
if (menuDataChanged) then
|
||||
backId = 0x1000 -- Go to Save menu
|
||||
title = title.." *"
|
||||
end
|
||||
ctx.Menu = { MenuId = 0x1001, Text = title, PrevId = 0, NextId = 0, BackId = backId, TextId=0 }
|
||||
ctx.MenuLines[0] = { Type = LINE_TYPE.MENU, Text = "Aircraft Type Setup", ValId = 0x1010,TextId=0 }
|
||||
ctx.MenuLines[1] = { Type = LINE_TYPE.MENU, Text = "Wing & Tail Channels ", ValId = 0x1020, TextId=0 }
|
||||
ctx.MenuLines[3] = { Type = LINE_TYPE.MENU, Text = "Gyro Channel Reverse", ValId = 0x1030, TextId=0 }
|
||||
ctx.MenuLines[5] = { Type = LINE_TYPE.MENU, Text = "WARNING: Changing of Aircraft or Wing will", ValId = 0x1001, TextId=0 }
|
||||
ctx.MenuLines[6] = { Type = LINE_TYPE.MENU, Text = "delete previous Channel/Port assigments.", ValId = 0x1001, TextId=0 }
|
||||
|
||||
ctx.SelLine = 0
|
||||
lastGoodMenu = menuId
|
||||
elseif (menuId==0x1005) then
|
||||
modelLib.printChannelSummary()
|
||||
modelLib.ST_SaveFileData()
|
||||
menuDataChanged = false
|
||||
|
||||
|
||||
local msg1 = "Data saved to: "
|
||||
local msg2 = " "..DATA_PATH.."/"..modelLib.hashName(MODEL.modelName)..".txt"
|
||||
|
||||
ctx.Menu = { MenuId = 0x1005, Text = "Config Saved", PrevId = 0, NextId = 0, BackId = 0, TextId=0 }
|
||||
ctx.MenuLines[2] = { Type = LINE_TYPE.MENU, Text=msg1, TextId = 0, ValId = 0x1005 }
|
||||
ctx.MenuLines[3] = { Type = LINE_TYPE.MENU, Text=msg2, TextId = 0, ValId = 0x1005 }
|
||||
ctx.MenuLines[6] = { Type = LINE_TYPE.MENU, Text="Complete", TextId = 0, ValId = 0xFFF9 }
|
||||
ctx.SelLine = 6
|
||||
lastGoodMenu = menuId
|
||||
elseif (menuId==0x1006) then
|
||||
modelLib.ST_LoadFileData()
|
||||
menuDataChanged = false
|
||||
currAircraftType = MENU_DATA[MEMU_VAR.AIRCRAFT_TYPE]
|
||||
currWingType = MENU_DATA[MEMU_VAR.WING_TYPE]
|
||||
currTailType = MENU_DATA[MEMU_VAR.TAIL_TYPE]
|
||||
|
||||
local msg1 = "Data restored from: "
|
||||
local msg2 = " "..DATA_PATH.."/"..modelLib.hashName(MODEL.modelName)..".txt"
|
||||
|
||||
ctx.Menu = { MenuId = 0x1006, Text = "Discart Changes", PrevId = 0, NextId = 0, BackId = 0, TextId=0 }
|
||||
ctx.MenuLines[2] = { Type = LINE_TYPE.MENU, Text=msg1, TextId = 0, ValId = 0x1006 }
|
||||
ctx.MenuLines[3] = { Type = LINE_TYPE.MENU, Text=msg2, TextId = 0, ValId = 0x1006 }
|
||||
ctx.MenuLines[6] = { Type = LINE_TYPE.MENU, Text="Complete", TextId = 0, ValId = 0xFFF9 }
|
||||
ctx.SelLine = 6
|
||||
lastGoodMenu = menuId
|
||||
elseif (menuId==0x1010) then
|
||||
modelLib.printChannelSummary()
|
||||
ctx.Menu = { MenuId = 0x1010, Text = "Aircraft Type", PrevId = 0, NextId = 0x1011, BackId = 0x1001, TextId=0 }
|
||||
ctx.MenuLines[5] = { Type = LINE_TYPE.LIST_MENU_NC, Text="Aircraft Type", TextId = 0, ValId = MEMU_VAR.AIRCRAFT_TYPE, Min=50, Max=53, Def=50, Val=MENU_DATA[MEMU_VAR.AIRCRAFT_TYPE] }
|
||||
ctx.SelLine = 5
|
||||
lastGoodMenu = menuId
|
||||
elseif (menuId==0x1011) then
|
||||
ctx.Menu = { MenuId = 0x1011, Text = "Model Type:"..modelLib.aircraft_type_text[currAircraftType], PrevId = 0, NextId = 0x1020, BackId = 0x1010, TextId=0 }
|
||||
ctx.MenuLines[5] = { Type = LINE_TYPE.LIST_MENU_NC, Text="Wing Type", TextId = 0, ValId = MEMU_VAR.WING_TYPE, Min=100, Max=107, Def=100, Val=MENU_DATA[MEMU_VAR.WING_TYPE] }
|
||||
ctx.MenuLines[6] = { Type = LINE_TYPE.LIST_MENU_NC, Text="Tail Type", TextId = 0, ValId = MEMU_VAR.TAIL_TYPE, Min=200, Max=210, Def=200, Val=MENU_DATA[MEMU_VAR.TAIL_TYPE] }
|
||||
ctx.SelLine = 5
|
||||
lastGoodMenu = menuId
|
||||
elseif (menuId==0x1020) then
|
||||
------ WING SETUP -------
|
||||
local thr = MENU_DATA[MEMU_VAR.CH_THR]
|
||||
local leftAil = MENU_DATA[MEMU_VAR.CH_L_AIL]
|
||||
local rightAil = MENU_DATA[MEMU_VAR.CH_R_AIL]
|
||||
local leftFlap = MENU_DATA[MEMU_VAR.CH_L_FLP]
|
||||
local rightFlap = MENU_DATA[MEMU_VAR.CH_R_FLP]
|
||||
|
||||
local thrText = "Thr"
|
||||
local leftAilText = "Left Aileron"
|
||||
local rightAilText = "Right Aileron"
|
||||
local leftFlapText = "Left Flap"
|
||||
local rightFlapText = "Right Flap"
|
||||
|
||||
if (rightAil==nil) then leftAilText = "Aileron" end
|
||||
if (rightFlap==nil) then leftFlapText = "Flap" end
|
||||
|
||||
local title = modelLib.aircraft_type_text[currAircraftType].." Wing:"..modelLib.wing_type_text[currWingType]
|
||||
|
||||
ctx.Menu = { MenuId = 0x1020, Text = title, PrevId = 0, NextId = 0x1021, BackId = 0x1011, TextId=0 }
|
||||
|
||||
ctx.MenuLines[0] = { Type = LINE_TYPE.LIST_MENU_NC, Text=thrText, TextId = 0, ValId = MEMU_VAR.CH_THR, Min=0, Max=10, Def=0, Val= thr }
|
||||
|
||||
ctx.MenuLines[2] = { Type = LINE_TYPE.LIST_MENU_NC, Text=leftAilText, TextId = 0, ValId = MEMU_VAR.CH_L_AIL, Min=0, Max=9, Def=0, Val= leftAil }
|
||||
|
||||
if (rightAil~=nil) then
|
||||
ctx.MenuLines[3] = { Type = LINE_TYPE.LIST_MENU_NC, Text=rightAilText, TextId = 0, ValId = MEMU_VAR.CH_R_AIL, Min=0, Max=9, Def=0, Val= rightAil }
|
||||
end
|
||||
|
||||
if (leftFlap~=nil) then
|
||||
ctx.MenuLines[4] = { Type = LINE_TYPE.LIST_MENU_NC, Text=leftFlapText, TextId = 0, ValId = MEMU_VAR.CH_L_FLP, Min=0, Max=9, Def=0, Val= leftFlap }
|
||||
end
|
||||
if (rightFlap~=nil) then
|
||||
ctx.MenuLines[5] = { Type = LINE_TYPE.LIST_MENU_NC, Text=rightFlapText, TextId = 0, ValId = MEMU_VAR.CH_R_FLP, Min=0, Max=9, Def=0, Val= rightFlap }
|
||||
end
|
||||
|
||||
ctx.SelLine = 0
|
||||
lastGoodMenu = menuId
|
||||
|
||||
elseif (menuId==0x1021) then
|
||||
------ TAIL SETUP -------
|
||||
local leftRud = MENU_DATA[MEMU_VAR.CH_L_RUD]
|
||||
local rightRud = MENU_DATA[MEMU_VAR.CH_R_RUD]
|
||||
local leftEle = MENU_DATA[MEMU_VAR.CH_L_ELE]
|
||||
local rightEle = MENU_DATA[MEMU_VAR.CH_R_ELE]
|
||||
|
||||
local leftRudText = "Left Rudder"
|
||||
local rightRudText = "Right Rudder"
|
||||
|
||||
local leftElvText = "Left Elevator"
|
||||
local rightElvText = "Right Elevator"
|
||||
|
||||
if (rightRud==nil) then leftRudText = "Rudder" end
|
||||
if (rightEle==nil) then leftElvText = "Elevator" end
|
||||
|
||||
local title = modelLib.aircraft_type_text[currAircraftType].." Tail:"..modelLib.tail_type_text[currTailType]
|
||||
|
||||
ctx.Menu = { MenuId = 0x1021, Text = title, PrevId = 0, NextId = 0x1001, BackId = 0x1020, TextId=0 }
|
||||
if (leftRud~=nil) then
|
||||
ctx.MenuLines[1] = { Type = LINE_TYPE.LIST_MENU_NC, Text=leftRudText, TextId = 0, ValId = MEMU_VAR.CH_L_RUD, Min=0, Max=9, Def=0, Val= leftRud}
|
||||
end
|
||||
|
||||
if (rightRud~=nil) then
|
||||
ctx.MenuLines[2] = { Type = LINE_TYPE.LIST_MENU_NC, Text=rightRudText, TextId = 0, ValId = MEMU_VAR.CH_R_RUD, Min=0, Max=9, Def=0, Val=rightRud }
|
||||
end
|
||||
|
||||
if (leftEle~=nil) then
|
||||
ctx.MenuLines[4] = { Type = LINE_TYPE.LIST_MENU_NC, Text=leftElvText, TextId = 0, ValId = MEMU_VAR.CH_L_ELE, Min=0, Max=9, Def=0, Val=leftEle }
|
||||
end
|
||||
|
||||
if (rightEle~=nil) then
|
||||
ctx.MenuLines[5] = { Type = LINE_TYPE.LIST_MENU_NC, Text=rightElvText, TextId = 0, ValId = MEMU_VAR.CH_R_ELE, Min=0, Max=9, Def=0, Val=rightEle }
|
||||
end
|
||||
|
||||
ctx.SelLine = 1
|
||||
lastGoodMenu = menuId
|
||||
|
||||
elseif (menuId==0x1030) then
|
||||
modelLib.CreateDSMPortChannelInfo()
|
||||
modelLib.printChannelSummary()
|
||||
|
||||
ctx.Menu = { MenuId = 0x1030, Text = "Gyro Channel Reverse (Port 1-5)", PrevId = 0, NextId = 0x1031, BackId = 0x1001, TextId=0 }
|
||||
ctx.MenuLines[0] = { Type = LINE_TYPE.LIST_MENU_NC, Text=Header(PORT.PORT1), TextId = 0, ValId = MEMU_VAR.PORT1_MODE, Min=300, Max=301, Def=300, Val=MENU_DATA[MEMU_VAR.PORT1_MODE], Format = formatTXRevert(PORT.PORT1) }
|
||||
ctx.MenuLines[1] = { Type = LINE_TYPE.LIST_MENU_NC, Text=Header(PORT.PORT2), TextId = 0, ValId = MEMU_VAR.PORT2_MODE, Min=300, Max=301, Def=300, Val=MENU_DATA[MEMU_VAR.PORT2_MODE], Format = formatTXRevert(PORT.PORT2) }
|
||||
ctx.MenuLines[2] = { Type = LINE_TYPE.LIST_MENU_NC, Text=Header(PORT.PORT3), TextId = 0, ValId = MEMU_VAR.PORT3_MODE, Min=300, Max=301, Def=300, Val=MENU_DATA[MEMU_VAR.PORT3_MODE], Format = formatTXRevert(PORT.PORT3) }
|
||||
ctx.MenuLines[3] = { Type = LINE_TYPE.LIST_MENU_NC, Text=Header(PORT.PORT4), TextId = 0, ValId = MEMU_VAR.PORT4_MODE, Min=300, Max=301, Def=300, Val=MENU_DATA[MEMU_VAR.PORT4_MODE], Format = formatTXRevert(PORT.PORT4) }
|
||||
ctx.MenuLines[4] = { Type = LINE_TYPE.LIST_MENU_NC, Text=Header(PORT.PORT5), TextId = 0, ValId = MEMU_VAR.PORT5_MODE, Min=300, Max=301, Def=300, Val=MENU_DATA[MEMU_VAR.PORT5_MODE], Format = formatTXRevert(PORT.PORT5) }
|
||||
|
||||
ctx.MenuLines[5] = { Type = LINE_TYPE.MENU, Text="Only Thr/Ail/Rud/Ele. This affects AS3X/SAFE reaction dir./b", TextId = 0, ValId = 0x1030 }
|
||||
ctx.MenuLines[6] = { Type = LINE_TYPE.MENU, Text="Any changes, use RX 'Relearn Servo Settings'/b", TextId = 0, ValId = 0x1030 }
|
||||
|
||||
ctx.SelLine = 0
|
||||
lastGoodMenu = menuId
|
||||
elseif (menuId==0x1031) then
|
||||
modelLib.CreateDSMPortChannelInfo()
|
||||
modelLib.printChannelSummary()
|
||||
ctx.Menu = { MenuId = 0x1031, Text = "Gyro Channel Reverse (Port 6-10)", PrevId = 0x1030, NextId = 0, BackId = 0x1001, TextId=0 }
|
||||
ctx.MenuLines[0] = { Type = LINE_TYPE.LIST_MENU_NC, Text=Header(PORT.PORT6), TextId = 0, ValId = MEMU_VAR.PORT6_MODE, Min=300, Max=301, Def=300, Val=MENU_DATA[MEMU_VAR.PORT6_MODE], Format = formatTXRevert(PORT.PORT6) }
|
||||
ctx.MenuLines[1] = { Type = LINE_TYPE.LIST_MENU_NC, Text=Header(PORT.PORT7), TextId = 0, ValId = MEMU_VAR.PORT7_MODE, Min=300, Max=301, Def=300, Val=MENU_DATA[MEMU_VAR.PORT7_MODE], Format = formatTXRevert(PORT.PORT7) }
|
||||
ctx.MenuLines[2] = { Type = LINE_TYPE.LIST_MENU_NC, Text=Header(PORT.PORT8), TextId = 0, ValId = MEMU_VAR.PORT8_MODE, Min=300, Max=301, Def=300, Val=MENU_DATA[MEMU_VAR.PORT8_MODE], Format = formatTXRevert(PORT.PORT8) }
|
||||
ctx.MenuLines[3] = { Type = LINE_TYPE.LIST_MENU_NC, Text=Header(PORT.PORT9), TextId = 0, ValId = MEMU_VAR.PORT9_MODE, Min=300, Max=301, Def=300, Val=MENU_DATA[MEMU_VAR.PORT9_MODE], Format = formatTXRevert(PORT.PORT9) }
|
||||
ctx.MenuLines[4] = { Type = LINE_TYPE.LIST_MENU_NC, Text=Header(PORT.PORT10), TextId = 0, ValId = MEMU_VAR.PORT10_MODE, Min=300, Max=301, Def=300, Val=MENU_DATA[MEMU_VAR.PORT10_MODE], Format = formatTXRevert(PORT.PORT10) }
|
||||
|
||||
ctx.MenuLines[5] = { Type = LINE_TYPE.MENU, Text="Only Thr/Ail/Rud/Ele. This affects AS3X/SAFE reaction dir./b", TextId = 0, ValId = 0x1031 }
|
||||
ctx.MenuLines[6] = { Type = LINE_TYPE.MENU, Text="Any changes, use RX 'Relearn Servo Settings'/b", TextId = 0, ValId = 0x1031 }
|
||||
|
||||
ctx.SelLine = 0
|
||||
lastGoodMenu = menuId
|
||||
else
|
||||
print("NOT IMPLEMENTED")
|
||||
ctx.Menu = { MenuId = 0x0002, Text = "NOT IMPLEMENTED", TextId = 0, PrevId = 0, NextId = 0, BackId = lastGoodMenu }
|
||||
ctx.SelLine = menuLib.BACK_BUTTON
|
||||
end
|
||||
|
||||
menuLib.PostProcessMenu()
|
||||
end
|
||||
|
||||
-- ST_SendReceive
|
||||
-- Main state machine for the Setup menu
|
||||
|
||||
local function ST_SendReceive()
|
||||
local ctx = menuLib.DSM_Context
|
||||
--if (DEBUG_ON>1) then Log.LOG_write("%3.3f %s: ", menuLib.getElapsedTime(), menuLib.phase2String(ctx.Phase)) end
|
||||
|
||||
if ctx.Phase == PHASE.RX_VERSION then -- request RX version
|
||||
ctx.RX.Name = "MODEL SETUP"
|
||||
ctx.RX.Version = SETUP_LIB_VERSION
|
||||
ctx.Phase = PHASE.MENU_TITLE
|
||||
ctx.Menu.MenuId = 0x01001
|
||||
|
||||
ctx.Refresh_Display = true
|
||||
|
||||
|
||||
elseif ctx.Phase == PHASE.WAIT_CMD then
|
||||
|
||||
elseif ctx.Phase == PHASE.MENU_TITLE then -- request menu title
|
||||
ST_LoadMenu(ctx.Menu.MenuId)
|
||||
ctx.Phase = PHASE.WAIT_CMD
|
||||
ctx.Refresh_Display = true
|
||||
|
||||
elseif ctx.Phase == PHASE.VALUE_CHANGING then -- send value
|
||||
local line = ctx.MenuLines[ctx.SelLine] -- Updated Value of SELECTED line
|
||||
|
||||
if (MENU_DATA[line.ValId] ~= line.Val ) then
|
||||
MENU_DATA[line.ValId] = line.Val
|
||||
print(string.format("MENU_DATA[%d/%s]=%d",line.ValId,line.Text, line.Val))
|
||||
menuDataChanged=true
|
||||
end
|
||||
|
||||
ctx.Phase = PHASE.VALUE_CHANGING_WAIT
|
||||
|
||||
elseif ctx.Phase == PHASE.VALUE_CHANGING_WAIT then
|
||||
local line = ctx.MenuLines[ctx.SelLine]
|
||||
|
||||
elseif ctx.Phase == PHASE.VALUE_CHANGE_END then -- send value
|
||||
local line = ctx.MenuLines[ctx.SelLine] -- Updated Value of SELECTED line
|
||||
|
||||
-- Update the menu data from the line
|
||||
if (MENU_DATA[line.ValId] ~= line.Val ) then
|
||||
MENU_DATA[line.ValId] = line.Val
|
||||
print(string.format("MENU_DATA[%d/%s]=%d",line.ValId,line.Text, line.Val))
|
||||
menuDataChanged=true
|
||||
end
|
||||
|
||||
-- Did the aircraft type change?
|
||||
if (currAircraftType ~= MENU_DATA[MEMU_VAR.AIRCRAFT_TYPE]) then
|
||||
currAircraftType = MENU_DATA[MEMU_VAR.AIRCRAFT_TYPE]
|
||||
modelLib.ST_AircraftInit(currAircraftType)
|
||||
currWingType = MENU_DATA[MEMU_VAR.WING_TYPE]
|
||||
currTailType = MENU_DATA[MEMU_VAR.TAIL_TYPE]
|
||||
end
|
||||
|
||||
-- Did the Wing type change?
|
||||
if (currWingType ~= MENU_DATA[MEMU_VAR.WING_TYPE]) then
|
||||
if (currAircraftType==AIRCRAFT_TYPE.GLIDER) then
|
||||
currWingType = MENU_DATA[MEMU_VAR.WING_TYPE]
|
||||
modelLib.ST_GliderWingInit(currWingType)
|
||||
else
|
||||
currWingType = MENU_DATA[MEMU_VAR.WING_TYPE]
|
||||
modelLib.ST_PlaneWingInit(currWingType)
|
||||
|
||||
end
|
||||
|
||||
-- DELTA has only RUDER
|
||||
if ((currWingType==WING_TYPE.ELEVON_A or currWingType==WING_TYPE.ELEVON_B) and TAIL_TYPE~=TAIL_TYPE.RUD_1) then
|
||||
MENU_DATA[MEMU_VAR.TAIL_TYPE] = TAIL_TYPE.RUD_1
|
||||
end
|
||||
end
|
||||
|
||||
--- Did the tail changed?
|
||||
local ntt = MENU_DATA[MEMU_VAR.TAIL_TYPE]
|
||||
if (currTailType ~= ntt) then
|
||||
if (currAircraftType==AIRCRAFT_TYPE.GLIDER) then
|
||||
currTailType = ntt
|
||||
modelLib.ST_GliderTailInit(currTailType)
|
||||
else
|
||||
if (not tailTypeCompatible(currTailType,ntt)) then
|
||||
modelLib.ST_PlaneTailInit(ntt)
|
||||
end
|
||||
currTailType = ntt
|
||||
end
|
||||
end
|
||||
|
||||
ctx.Phase = PHASE.WAIT_CMD
|
||||
elseif ctx.Phase == PHASE.EXIT then
|
||||
ctx.Phase=PHASE.EXIT_DONE
|
||||
end
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
|
||||
-- Inital List and Image Text for this menus
|
||||
local function ST_Init_Text(rxId)
|
||||
menuLib.clearAllText()
|
||||
|
||||
local List_Values = menuLib.List_Values
|
||||
local List_Text = menuLib.List_Text
|
||||
local Text = menuLib.Text
|
||||
local List_Text_Img = menuLib.List_Text_Img
|
||||
|
||||
-- Channel Names use the Port Text Retrived from OTX/ETX
|
||||
for i = 0, 9 do List_Text[i] = MODEL.PORT_TEXT[i] end
|
||||
List_Text[10]="--"
|
||||
|
||||
-- Aircraft Type
|
||||
List_Text[50+AIRCRAFT_TYPE.PLANE] = "Airplane"; --List_Text_Img[50+AIRCRAFT_TYPE.PLANE] = "at_plane.png|Airplane"
|
||||
List_Text[50+AIRCRAFT_TYPE.GLIDER] = "Glider (Partial work)"; --List_Text_Img[50+AIRCRAFT_TYPE.GLIDER] = "at_glider.png|Glider"
|
||||
List_Text[50+AIRCRAFT_TYPE.HELI] = "Helicopter (Not done)"; --List_Text_Img[50+AIRCRAFT_TYPE.HELI] = "at_heli.png|Helicopter"
|
||||
List_Text[50+AIRCRAFT_TYPE.DRONE] = "Drone (not done)"; --List_Text_Img[50+AIRCRAFT_TYPE.DRONE] = "at_drone.png|Drone"
|
||||
|
||||
-- Wing Types
|
||||
List_Text[100+WING_TYPE.AIL_1] = "Single Ail"; List_Text_Img[100+WING_TYPE.AIL_1] = "wt_1ail.png|Single Aileron"
|
||||
List_Text[100+WING_TYPE.AIL_2] = "Dual Ail"; List_Text_Img[100+WING_TYPE.AIL_2] = "wt_2ail.png|Dual Aileron"
|
||||
List_Text[100+WING_TYPE.FLAPERON] = "Flaperon"; List_Text_Img[100+WING_TYPE.FLAPERON] = "wt_flaperon.png|Flaperon"
|
||||
List_Text[100+WING_TYPE.AIL_1_FLP_1] = "Ail + Flap"; List_Text_Img[100+WING_TYPE.AIL_1_FLP_1] = "wt_1ail_1flp.png|Aileron + Flap"
|
||||
List_Text[100+WING_TYPE.AIL_2_FLP_1] = "Dual Ail + Flap"; List_Text_Img[100+WING_TYPE.AIL_2_FLP_1] = "wt_2ail_1flp.png|Dual Aileron + Flap"
|
||||
List_Text[100+WING_TYPE.AIL_2_FLP_2] = "Dual Ail + Dual Flap"; List_Text_Img[100+WING_TYPE.AIL_2_FLP_2] = "wt_2ail_2flp.png|Dual Aileron + Dual Flap"
|
||||
List_Text[100+WING_TYPE.ELEVON_A] = "Delta/Elevon A"; List_Text_Img[100+WING_TYPE.ELEVON_A] = "wt_elevon.png|Delta/Elevon A"
|
||||
List_Text[100+WING_TYPE.ELEVON_B] = "Delta/Elevon B"; List_Text_Img[100+WING_TYPE.ELEVON_B] = "wt_elevon.png|Delta/Elevon B"
|
||||
|
||||
-- Tail Types
|
||||
List_Text[200+TAIL_TYPE.RUD_1] = "Rudder Only"; List_Text_Img[200+TAIL_TYPE.RUD_1] = "tt_1rud.png|Rudder Only"
|
||||
List_Text[200+TAIL_TYPE.RUD_1_ELEV_1] = "Rud + Ele"; List_Text_Img[200+TAIL_TYPE.RUD_1_ELEV_1] = "tt_1rud_1ele.png|Tail Normal"
|
||||
List_Text[200+TAIL_TYPE.RUD_1_ELEV_2] = "Rud + Dual Ele"; List_Text_Img[200+TAIL_TYPE.RUD_1_ELEV_2] = "tt_1rud_2ele.png|Rud + Dual Elev"
|
||||
List_Text[200+TAIL_TYPE.RUD_2_ELEV_1] = "Dual Rud + Ele"; List_Text_Img[200+TAIL_TYPE.RUD_2_ELEV_1] = "tt_2rud_1ele.png|Dual Rud + Elev"
|
||||
List_Text[200+TAIL_TYPE.RUD_2_ELEV_2] = "Dual Rud + Dual Ele"; List_Text_Img[200+TAIL_TYPE.RUD_2_ELEV_2] = "tt_2rud_2ele.png|Dual Rud + Dual Elev"
|
||||
List_Text[200+TAIL_TYPE.VTAIL_A] = "V-Tail A"; List_Text_Img[200+TAIL_TYPE.VTAIL_A] = "tt_vtail.png|V-Tail A"
|
||||
List_Text[200+TAIL_TYPE.VTAIL_B] = "V-Tail B"; List_Text_Img[200+TAIL_TYPE.VTAIL_B] = "tt_vtail.png|V-Tail B"
|
||||
List_Text[200+TAIL_TYPE.TRAILERON_A] = "Taileron A"; List_Text_Img[200+TAIL_TYPE.TRAILERON_A] = "tt_taileron.png|Taileron A"
|
||||
List_Text[200+TAIL_TYPE.TRAILERON_B] = "Taileron B"; List_Text_Img[200+TAIL_TYPE.TRAILERON_B] = "tt_taileron.png|Taileron B"
|
||||
List_Text[200+TAIL_TYPE.TRAILERON_A_R2] = "Taileron A + 2x Rud"; List_Text_Img[200+TAIL_TYPE.TRAILERON_A_R2] = "tt_taileron2.png|Taileron A + Dual Rud"
|
||||
List_Text[200+TAIL_TYPE.TRAILERON_B_R2] = "Taileron B + 2x Rud"; List_Text_Img[200+TAIL_TYPE.TRAILERON_B_R2] = "tt_taileron2.png|Taileron B + Dual Rud"
|
||||
|
||||
|
||||
-- Servo Reverse
|
||||
if (LCD_W > 128) then
|
||||
List_Text[300+CH_MODE_TYPE.NORMAL] = "Normal "
|
||||
List_Text[300+CH_MODE_TYPE.REVERSE] = "Reverse"
|
||||
else
|
||||
List_Text[300+CH_MODE_TYPE.NORMAL] = "Nor"
|
||||
List_Text[300+CH_MODE_TYPE.REVERSE] = "Rev"
|
||||
end
|
||||
end
|
||||
|
||||
-- Initial Setup
|
||||
local function ST_Init()
|
||||
-- Initialize text (use RX_ID 0)
|
||||
ST_Init_Text(0)
|
||||
|
||||
-- Setup default Data, and load a file if exist
|
||||
--modelLib.ST_Default_Data()
|
||||
if (modelLib.ST_LoadFileData()==0) then -- Did not load a file
|
||||
modelLib.ST_Default_Data()
|
||||
modelLib.ST_SaveFileData() -- Save Defaults
|
||||
end
|
||||
menuDataChanged = false
|
||||
currAircraftType = MENU_DATA[MEMU_VAR.AIRCRAFT_TYPE]
|
||||
currWingType = MENU_DATA[MEMU_VAR.WING_TYPE]
|
||||
currTailType = MENU_DATA[MEMU_VAR.TAIL_TYPE]
|
||||
|
||||
local ctx = menuLib.DSM_Context
|
||||
ctx.Phase = PHASE.RX_VERSION
|
||||
end
|
||||
|
||||
local function ST_Done()
|
||||
local ctx = menuLib.DSM_Context
|
||||
ctx.Phase = PHASE.EXIT_DONE
|
||||
end
|
||||
|
||||
|
||||
return { init=ST_Init, run=ST_SendReceive, done=ST_Done }
|
||||
1596
SCRIPTS/TOOLS/DSMLIB/DsmSimMenuLib.lua
Normal file
10
SCRIPTS/TOOLS/DSMLIB/MIN_msg_fwdp_en.txt
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
-- OVERRIDES Messges for MIN 128x64 screns
|
||||
-- FORMAT <LineType>|<Msg#>|<Text>
|
||||
-- Line Type: Text for Menus (T), List_Text Options (LT), List_Text_Image (LI), Flight Mode (FM), RX Name (RX)
|
||||
-- IMPORTANT: NO EMPTY LINES
|
||||
--
|
||||
T |0x0097|DONT USE: Factory Reset
|
||||
T |0x0098|DONT USE: Factory Reset
|
||||
T |0x00A5|DONT USE: First Time Setup
|
||||
T |0x0190|DONT USE: Relearn Servo Settings
|
||||
T |0x020D|DONT USE: First Time SAFE Setup
|
||||
BIN
SCRIPTS/TOOLS/DSMLIB/img/h_rx_pos_1.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
SCRIPTS/TOOLS/DSMLIB/img/h_rx_pos_2.png
Normal file
|
After Width: | Height: | Size: 862 B |
BIN
SCRIPTS/TOOLS/DSMLIB/img/h_rx_pos_3.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
SCRIPTS/TOOLS/DSMLIB/img/h_rx_pos_4.png
Normal file
|
After Width: | Height: | Size: 866 B |
BIN
SCRIPTS/TOOLS/DSMLIB/img/h_rx_pos_5.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
SCRIPTS/TOOLS/DSMLIB/img/h_rx_pos_6.png
Normal file
|
After Width: | Height: | Size: 880 B |
BIN
SCRIPTS/TOOLS/DSMLIB/img/h_rx_pos_7.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
SCRIPTS/TOOLS/DSMLIB/img/h_rx_pos_8.png
Normal file
|
After Width: | Height: | Size: 863 B |
BIN
SCRIPTS/TOOLS/DSMLIB/img/h_swp_3_120.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
SCRIPTS/TOOLS/DSMLIB/img/h_swp_3_120inv.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
SCRIPTS/TOOLS/DSMLIB/img/h_swp_3_135.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
SCRIPTS/TOOLS/DSMLIB/img/h_swp_3_135inv.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
SCRIPTS/TOOLS/DSMLIB/img/h_swp_3_140.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
SCRIPTS/TOOLS/DSMLIB/img/h_swp_3_140inv.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
SCRIPTS/TOOLS/DSMLIB/img/h_swp_3_90.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
SCRIPTS/TOOLS/DSMLIB/img/h_swp_3_90inv.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
SCRIPTS/TOOLS/DSMLIB/img/h_swp_norm.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
SCRIPTS/TOOLS/DSMLIB/img/rx_pos_1.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
SCRIPTS/TOOLS/DSMLIB/img/rx_pos_10.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
SCRIPTS/TOOLS/DSMLIB/img/rx_pos_11.png
Normal file
|
After Width: | Height: | Size: 3 KiB |
BIN
SCRIPTS/TOOLS/DSMLIB/img/rx_pos_12.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
SCRIPTS/TOOLS/DSMLIB/img/rx_pos_13.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
SCRIPTS/TOOLS/DSMLIB/img/rx_pos_14.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
SCRIPTS/TOOLS/DSMLIB/img/rx_pos_15.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
SCRIPTS/TOOLS/DSMLIB/img/rx_pos_16.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
SCRIPTS/TOOLS/DSMLIB/img/rx_pos_17.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
SCRIPTS/TOOLS/DSMLIB/img/rx_pos_18.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
SCRIPTS/TOOLS/DSMLIB/img/rx_pos_19.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
SCRIPTS/TOOLS/DSMLIB/img/rx_pos_2.png
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
BIN
SCRIPTS/TOOLS/DSMLIB/img/rx_pos_20.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
SCRIPTS/TOOLS/DSMLIB/img/rx_pos_21.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |