Compare commits
41 Commits
v1.3.3.33
...
pascallang
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bb9f8fdfbf | ||
|
|
8e663f2531 | ||
|
|
8c2fe5f65e | ||
|
|
7549783741 | ||
|
|
e6bafaabb7 | ||
|
|
9286ac84f6 | ||
|
|
ede40ac598 | ||
|
|
88fad2dc9f | ||
|
|
549d3ad653 | ||
|
|
62aa58d32d | ||
|
|
21a06c2925 | ||
|
|
9acb3b0e2c | ||
|
|
785edde659 | ||
|
|
7da6d52a84 | ||
|
|
61cbe45ce2 | ||
|
|
23af33e214 | ||
|
|
11db967b8a | ||
|
|
d419e2b344 | ||
|
|
2b69c1184e | ||
|
|
1ceed87298 | ||
|
|
a1737eab46 | ||
|
|
9cbcafe6cf | ||
|
|
495706314f | ||
|
|
595511979b | ||
|
|
b8d30f47be | ||
|
|
b7097bdfb7 | ||
|
|
a682b0e604 | ||
|
|
7e7b555809 | ||
|
|
62ecaa8412 | ||
|
|
5ae052317d | ||
|
|
f3331ca397 | ||
|
|
ffcfd44127 | ||
|
|
5ef944241a | ||
|
|
ab5f75b1b3 | ||
|
|
10ec4dd735 | ||
|
|
a62d1dcd2e | ||
|
|
2c9e98e341 | ||
|
|
0bf94e96b5 | ||
|
|
8d84386c7a | ||
|
|
cd721e31d8 | ||
|
|
1294ad21cf |
30
.github/workflows/main.yml
vendored
@@ -39,16 +39,26 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
board: [
|
||||
"multi4in1:avr:multiatmega328p:bootloader=none",
|
||||
"multi4in1:avr:multiatmega328p:bootloader=optiboot",
|
||||
"multi4in1:avr:multixmega32d4",
|
||||
"multi4in1:STM32F1:multi5in1t18int",
|
||||
"multi4in1:STM32F1:multistm32f103cb:debug_option=none",
|
||||
"multi4in1:STM32F1:multistm32f103cb:debug_option=native",
|
||||
"multi4in1:STM32F1:multistm32f103cb:debug_option=ftdi",
|
||||
"multi4in1:STM32F1:multistm32f103c8:debug_option=none"
|
||||
]
|
||||
include:
|
||||
- board: "multi4in1:avr:multiatmega328p:bootloader=none"
|
||||
name: "ATmega328p"
|
||||
- board: "multi4in1:avr:multiatmega328p:bootloader=optiboot"
|
||||
name: "ATmega328p (Optiboot)"
|
||||
- board: "multi4in1:avr:multixmega32d4"
|
||||
name: "OrangeRX"
|
||||
- board: "multi4in1:STM32F1:multistm32f103c8:debug_option=none"
|
||||
name: "STM32F103 (64KB)"
|
||||
- board: "multi4in1:STM32F1:multistm32f103cb:debug_option=none"
|
||||
name: "STM32F103 (128KB)"
|
||||
- board: "multi4in1:STM32F1:multistm32f103cb:debug_option=native"
|
||||
name: "STM32F103 (128KB, USB Debugging)"
|
||||
- board: "multi4in1:STM32F1:multistm32f103cb:debug_option=ftdi"
|
||||
name: "STM32F103 (128KB, Serial Debugging)"
|
||||
- board: "multi4in1:STM32F1:multi5in1t18int"
|
||||
name: "T18 5-in-1 (128KB)"
|
||||
|
||||
# Set the build name using the friendly board name
|
||||
name: ${{ matrix.name }}
|
||||
|
||||
# Set the environment variables
|
||||
env:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
local toolName = "TNS|DSM Forward Prog v0.55a (Color) |TNE"
|
||||
local VERSION = "v0.55a"
|
||||
local toolName = "TNS|DSM Forward Prog v0.56 (Color) |TNE"
|
||||
local VERSION = "v0.56"
|
||||
|
||||
---- #########################################################################
|
||||
---- # #
|
||||
1088
Lua_scripts/DSM FwdPrg_56_MIN.lua
Normal file
951
Lua_scripts/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 }
|
||||
167
Lua_scripts/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
Lua_scripts/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()
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
local Log, menuLib, modelLib, DEBUG_ON, SIMULATION_ON = ... -- Get DebugON from parameters
|
||||
local MAIN_MENU_LIB_VERSION = "0.55"
|
||||
local MAIN_MENU_LIB_VERSION = "0.56"
|
||||
local MODEL = modelLib.MODEL
|
||||
|
||||
local PHASE = menuLib.PHASE
|
||||
|
||||
@@ -547,7 +547,12 @@ function MenuLib.GetFlightModeValue(line)
|
||||
end
|
||||
else
|
||||
-- No adjustment needed
|
||||
ret=ret..(val + 1)
|
||||
if (val==190) then
|
||||
ret=ret.."Err:Out of Range"
|
||||
else
|
||||
ret=ret..(val + 1)
|
||||
end
|
||||
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
@@ -31,14 +31,15 @@ local CH_TYPE = {
|
||||
|
||||
-- Seems like Reverse Mix is complement of the 3 bits
|
||||
local CH_MIX_TYPE = {
|
||||
NORMAL = 0x00, -- 0000
|
||||
MIX_AIL_B = 0x10, -- 0001 Taileron B
|
||||
MIX_ELE_A = 0x20, -- 0010 For VTIAL and Delta-ELEVON A
|
||||
MIX_ELE_B_REV= 0x30, -- 0011 For VTIAL and Delta-ELEVON B
|
||||
MIX_ELE_B = 0x40, -- 0100 For VTIAL and Delta-ELEVON B
|
||||
MIX_ELE_A_REV= 0x50, -- 0101 For VTIAL and Delta-ELEVON A
|
||||
MIX_AIL_B_REV= 0x60, -- 0110 Taileron B Rev
|
||||
NORM_REV = 0x70 -- 0111
|
||||
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 = {
|
||||
@@ -72,8 +73,11 @@ local TAIL_TYPE = {
|
||||
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","Traileron A","Traileron B"}
|
||||
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,
|
||||
@@ -156,18 +160,18 @@ local MENU_DATA = {} -- Store the variables used in the Menus.
|
||||
|
||||
-- DEFAULT Simple Plane Port configuration (The Configuration tool will overrride this)
|
||||
MODEL.DSM_ChannelInfo= {[0]= -- Start array at position 0
|
||||
{[0]= CH_MIX_TYPE.NONE, CH_TYPE.THR}, -- Ch1 Thr (0x40)
|
||||
{[0]= CH_MIX_TYPE.NONE, CH_TYPE.AIL}, -- Ch2 Ail (0x01)
|
||||
{[0]= CH_MIX_TYPE.NONE, CH_TYPE.ELE}, -- Ch2 ElE (0x02)
|
||||
{[0]= CH_MIX_TYPE.NONE, CH_TYPE.RUD}, -- Ch4 Rud (0x04)
|
||||
{[0]= CH_MIX_TYPE.NONE, CH_TYPE.NONE}, -- Ch5 Gear (0x00)
|
||||
{[0]= CH_MIX_TYPE.NONE, CH_TYPE.NONE}, -- Ch6 Aux1 (0x00)
|
||||
{[0]= CH_MIX_TYPE.NONE, CH_TYPE.NONE}, -- Ch7 Aux2 (0x00)
|
||||
{[0]= CH_MIX_TYPE.NONE, CH_TYPE.NONE}, -- Ch8 Aux3 (0x00)
|
||||
{[0]= CH_MIX_TYPE.NONE, CH_TYPE.NONE}, -- Ch9 Aux4 (0x00)
|
||||
{[0]= CH_MIX_TYPE.NONE, CH_TYPE.NONE}, -- Ch10 Aux5 (0x00)
|
||||
{[0]= CH_MIX_TYPE.NONE, CH_TYPE.NONE}, -- Ch11 Aux6 (0x00)
|
||||
{[0]= CH_MIX_TYPE.NONE, CH_TYPE.NONE} -- Ch12 Aux7 (0x00)
|
||||
{[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)
|
||||
@@ -200,21 +204,24 @@ 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.SLAVE)>0) then s=s.."SLAVE " end
|
||||
if (bit32.band(byte2,CH_TYPE.REVERSE)>0) then s=s.."REVERSE " 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 (byte1==CH_MIX_TYPE.NORMAL) then s=s.." MIX_NOR"
|
||||
elseif (byte1==CH_MIX_TYPE.MIX_AIL_B) then s=s.." MIX_AIL_B"
|
||||
elseif (byte1==CH_MIX_TYPE.MIX_ELE_A) then s=s.." MIX_ELE_A"
|
||||
elseif (byte1==CH_MIX_TYPE.MIX_ELE_B_REV) then s=s.." MIX_ELE_B_Rev"
|
||||
elseif (byte1==CH_MIX_TYPE.MIX_ELE_B) then s=s.." MIX_ELE_B"
|
||||
elseif (byte1==CH_MIX_TYPE.MIX_ELE_A_REV) then s=s.." MIX_ELE_A_Rev"
|
||||
elseif (byte1==CH_MIX_TYPE.MIX_AIL_B_REV) then s=s.." MIX_AIL_B_Rev"
|
||||
elseif (byte1==CH_MIX_TYPE.NORM_REV) then s=s.." MIX_NOR_Rev"
|
||||
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;
|
||||
@@ -257,7 +264,7 @@ function ModelLib.ReadTxModelData()
|
||||
MODEL.modelName = table.name
|
||||
|
||||
local module = model.getModule(0) -- Internal
|
||||
if (module==nil) then module = model.getModule(1) end -- External
|
||||
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
|
||||
@@ -307,11 +314,7 @@ function ModelLib.ReadTxModelData()
|
||||
local ch = MODEL.modelOutputChannel[i]
|
||||
if (ch~=nil) then
|
||||
MODEL.TX_CH_TEXT[i] = ch.formatCh
|
||||
if LCD_W <= 128 then -- SMALLER SCREENS
|
||||
MODEL.PORT_TEXT[i] = string.format("P%i (%s) ",i+1,MODEL.TX_CH_TEXT[i])
|
||||
else
|
||||
MODEL.PORT_TEXT[i] = string.format("Port%i (%s) ",i+1,MODEL.TX_CH_TEXT[i])
|
||||
end
|
||||
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
|
||||
@@ -343,6 +346,11 @@ end
|
||||
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
|
||||
@@ -401,60 +409,45 @@ end
|
||||
function ModelLib.CreateDSMPortChannelInfo()
|
||||
local function ApplyWingMixA(b2)
|
||||
-- ELEVON
|
||||
if (b2==CH_TYPE.AIL+CH_TYPE.ELE) then return CH_MIX_TYPE.MIX_ELE_A end; -- 0x03
|
||||
if (b2==CH_TYPE.AIL+CH_TYPE.ELE+CH_TYPE.REVERSE) then return CH_MIX_TYPE.MIX_ELE_A_REV end; -- 0x23
|
||||
|
||||
-- Default normal/reverse behaviour
|
||||
if (b2==CH_TYPE.AIL+CH_TYPE.ELE+CH_TYPE.SLAVE) then return CH_MIX_TYPE.NORMAL end; -- 0x83
|
||||
if (b2==CH_TYPE.AIL+CH_TYPE.ELE+CH_TYPE.SLAVE+CH_TYPE.REVERSE) then return CH_MIX_TYPE.NORM_REV end; -- 0xA3
|
||||
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
|
||||
-- Default normal/reverse behaviour
|
||||
if (b2==CH_TYPE.AIL+CH_TYPE.ELE) then return CH_MIX_TYPE.NORMAL end; -- 0x03
|
||||
if (b2==CH_TYPE.AIL+CH_TYPE.ELE+CH_TYPE.REVERSE) then return CH_MIX_TYPE.NORM_REV end; -- 0x23
|
||||
|
||||
-- Difference with B
|
||||
if (b2==CH_TYPE.AIL+CH_TYPE.ELE+CH_TYPE.SLAVE) then return CH_MIX_TYPE.MIX_ELE_A end; -- 0x83
|
||||
if (b2==CH_TYPE.AIL+CH_TYPE.ELE+CH_TYPE.SLAVE+CH_TYPE.REVERSE) then return CH_MIX_TYPE.MIX_ELE_A_REV end; -- 0xA3
|
||||
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.NORMAL end; -- 0x06
|
||||
if (b2==CH_TYPE.RUD+CH_TYPE.ELE+CH_TYPE.REVERSE) then return CH_MIX_TYPE.NORM_REV end; -- 0x26
|
||||
|
||||
if (b2==CH_TYPE.RUD+CH_TYPE.ELE+CH_TYPE.SLAVE) then return CH_MIX_TYPE.MIX_ELE_A end; -- 0x86
|
||||
if (b2==CH_TYPE.RUD+CH_TYPE.ELE+CH_TYPE.SLAVE+CH_TYPE.REVERSE) then return CH_MIX_TYPE.MIX_ELE_A_REV end; -- 0xA6
|
||||
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.NORMAL end; -- 0x03
|
||||
if (b2==CH_TYPE.AIL+CH_TYPE.ELE+CH_TYPE.REVERSE) then return CH_MIX_TYPE.NORM_REV end; -- 0x23
|
||||
|
||||
if (b2==CH_TYPE.AIL+CH_TYPE.ELE+CH_TYPE.SLAVE) then return CH_MIX_TYPE.MIX_AIL_B end; -- 0x83
|
||||
if (b2==CH_TYPE.AIL+CH_TYPE.ELE+CH_TYPE.SLAVE+CH_TYPE.REVERSE) then return CH_MIX_TYPE.MIX_AIL_B_REV end; -- 0xA3
|
||||
|
||||
-- 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.NORMAL end; -- 0x06
|
||||
if (b2==CH_TYPE.RUD+CH_TYPE.ELE+CH_TYPE.REVERSE) then return CH_MIX_TYPE.NORM_REV end; -- 0x26
|
||||
|
||||
if (b2==CH_TYPE.RUD+CH_TYPE.ELE+CH_TYPE.SLAVE) then return CH_MIX_TYPE.MIX_ELE_B end; -- 0x86
|
||||
if (b2==CH_TYPE.RUD+CH_TYPE.ELE+CH_TYPE.SLAVE+CH_TYPE.REVERSE) then return CH_MIX_TYPE.MIX_ELE_B_REV end; -- 0xA6
|
||||
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_B end; -- 0x03
|
||||
if (b2==CH_TYPE.AIL+CH_TYPE.ELE+CH_TYPE.REVERSE) then return CH_MIX_TYPE.MIX_AIL_B_REV end; -- 0x23
|
||||
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
|
||||
|
||||
-- Default normal/reverse behaviour
|
||||
if (b2==CH_TYPE.AIL+CH_TYPE.ELE+CH_TYPE.SLAVE) then return CH_MIX_TYPE.NORMAL end; -- 0x83
|
||||
if (b2==CH_TYPE.AIL+CH_TYPE.ELE+CH_TYPE.SLAVE+CH_TYPE.REVERSE) then return CH_MIX_TYPE.NORM_REV end; -- 0xA3
|
||||
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
|
||||
|
||||
|
||||
@@ -462,7 +455,7 @@ function ModelLib.CreateDSMPortChannelInfo()
|
||||
local DSM_ChannelInfo = MODEL.DSM_ChannelInfo
|
||||
|
||||
for i=0, TX_CHANNELS-1 do
|
||||
DSM_ChannelInfo[i] = {[0]= 0x00, CH_TYPE.NONE} -- Initialize with no special function
|
||||
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]
|
||||
@@ -484,7 +477,7 @@ function ModelLib.CreateDSMPortChannelInfo()
|
||||
-- Channels in menu vars are Zero base, Channel info is 1 based
|
||||
|
||||
-- THR
|
||||
if (thrCh~=nil) then DSM_ChannelInfo[thrCh][1]= CH_TYPE.THR end
|
||||
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
|
||||
@@ -497,59 +490,36 @@ function ModelLib.CreateDSMPortChannelInfo()
|
||||
if (rRudCh~=nil) then DSM_ChannelInfo[rRudCh][1] = CH_TYPE.RUD+CH_TYPE.SLAVE end
|
||||
|
||||
-- VTAIL: RUD + ELE
|
||||
if (tailType==TAIL_TYPE.VTAIL_A) then
|
||||
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
|
||||
elseif (tailType==TAIL_TYPE.VTAIL_B) then
|
||||
DSM_ChannelInfo[lElevCh][1] = CH_TYPE.RUD+CH_TYPE.ELE+CH_TYPE.SLAVE
|
||||
DSM_ChannelInfo[rElevCh][1] = CH_TYPE.RUD+CH_TYPE.ELE
|
||||
end
|
||||
|
||||
-- TRAILERRON: 2-ELE + AIL
|
||||
if (tailType==TAIL_TYPE.TRAILERON_A) then
|
||||
-- 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
|
||||
elseif (tailType==TAIL_TYPE.TRAILERON_B) then
|
||||
DSM_ChannelInfo[lElevCh][1] = CH_TYPE.AIL+CH_TYPE.ELE+CH_TYPE.SLAVE
|
||||
DSM_ChannelInfo[rElevCh][1] = CH_TYPE.AIL+CH_TYPE.ELE
|
||||
end
|
||||
|
||||
---- ELEVON : AIL + ELE
|
||||
if (wingType==WING_TYPE.ELEVON_A) then
|
||||
DSM_ChannelInfo[lAilCh][1] = CH_TYPE.AIL+CH_TYPE.ELE
|
||||
DSM_ChannelInfo[rAilCh][1] = CH_TYPE.AIL+CH_TYPE.ELE+CH_TYPE.SLAVE
|
||||
elseif (wingType==WING_TYPE.ELEVON_B) then
|
||||
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
|
||||
|
||||
-- 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]=DSM_ChannelInfo[i][1]+CH_MIX_TYPE.NORM_REV -- ALL REVERSE is 0x70 for normal
|
||||
DSM_ChannelInfo[i][1]=DSM_ChannelInfo[i][1]+CH_TYPE.REVERSE
|
||||
end
|
||||
end
|
||||
------MIXES ---------
|
||||
|
||||
-- VTAIL: RUD + ELE
|
||||
if (tailType==TAIL_TYPE.VTAIL_A) then
|
||||
-- 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])
|
||||
elseif (tailType==TAIL_TYPE.VTAIL_B) then
|
||||
DSM_ChannelInfo[lElevCh][0] = ApplyTailMixB(DSM_ChannelInfo[lElevCh][1])
|
||||
DSM_ChannelInfo[rElevCh][0] = ApplyTailMixB(DSM_ChannelInfo[rElevCh][1])
|
||||
end
|
||||
|
||||
-- TRAILERRON: ELE + AIL
|
||||
if (tailType==TAIL_TYPE.TRAILERON_A) then
|
||||
DSM_ChannelInfo[lElevCh][1] = ApplyTailMixA(DSM_ChannelInfo[lElevCh][1])
|
||||
DSM_ChannelInfo[rElevCh][1] = ApplyTailMixA(DSM_ChannelInfo[rElevCh][1])
|
||||
elseif (tailType==TAIL_TYPE.TRAILERON_B) then
|
||||
DSM_ChannelInfo[lElevCh][1] = ApplyTailMixB(DSM_ChannelInfo[lElevCh][1])
|
||||
DSM_ChannelInfo[rElevCh][1] = ApplyTailMixB(DSM_ChannelInfo[rElevCh][1])
|
||||
end
|
||||
|
||||
---- ELEVON : AIL + ELE
|
||||
---- 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])
|
||||
@@ -558,6 +528,14 @@ function ModelLib.CreateDSMPortChannelInfo()
|
||||
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]
|
||||
@@ -618,7 +596,8 @@ function ModelLib.ST_PlaneWingInit(wingType)
|
||||
end
|
||||
|
||||
function ModelLib.ST_PlaneTailInit(tailType)
|
||||
if (MENU_DATA[MEMU_VAR.WING_TYPE]==WING_TYPE.ELEVON_A) then
|
||||
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
|
||||
|
||||
@@ -643,29 +622,29 @@ function ModelLib.ST_PlaneTailInit(tailType)
|
||||
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.PORT5
|
||||
MENU_DATA[MEMU_VAR.CH_R_RUD] = PORT.PORT4
|
||||
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.PORT6
|
||||
MENU_DATA[MEMU_VAR.CH_R_RUD] = PORT.PORT4
|
||||
elseif (tailType == TAIL_TYPE.VTAIL_A) then
|
||||
MENU_DATA[MEMU_VAR.CH_L_ELE] = PORT.PORT4
|
||||
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.VTAIL_B) then
|
||||
MENU_DATA[MEMU_VAR.CH_L_ELE] = PORT.PORT3
|
||||
MENU_DATA[MEMU_VAR.CH_R_ELE] = PORT.PORT4
|
||||
elseif (tailType == TAIL_TYPE.TRAILERON_A) then
|
||||
MENU_DATA[MEMU_VAR.CH_L_ELE] = PORT.PORT5
|
||||
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
|
||||
elseif (tailType == TAIL_TYPE.TRAILERON_B) then
|
||||
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
|
||||
|
||||
@@ -732,11 +711,11 @@ function ModelLib.ST_GliderTailInit(tailType)
|
||||
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_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
|
||||
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
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
local Log, menuLib, modelLib, DEBUG_ON, SIMULATION_ON = ... -- Get DebugON from parameters
|
||||
local SETUP_LIB_VERSION = "0.55"
|
||||
local SETUP_LIB_VERSION = "0.56"
|
||||
|
||||
local DATA_PATH = modelLib.DATA_PATH
|
||||
|
||||
@@ -53,26 +53,61 @@ local currWingType = -1 -- Current TailType selected, and to detect chan
|
||||
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 formatTXRevert(port)
|
||||
if (MODEL.modelOutputChannel[port].revert==0) then
|
||||
return " (Tx:"..menuLib.Get_List_Text(300+CH_MODE_TYPE.NORMAL)..")"
|
||||
else
|
||||
return " (Tx:"..menuLib.Get_List_Text(300+CH_MODE_TYPE.REVERSE)..")"
|
||||
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 = 0xFFF9, TextId=0 }
|
||||
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 }
|
||||
@@ -128,6 +163,7 @@ local function ST_LoadMenu(menuId)
|
||||
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
|
||||
@@ -135,7 +171,7 @@ local function ST_LoadMenu(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=208, Def=200, Val=MENU_DATA[MEMU_VAR.TAIL_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
|
||||
@@ -159,7 +195,7 @@ local function ST_LoadMenu(menuId)
|
||||
|
||||
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=9, Def=0, Val= thr }
|
||||
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 }
|
||||
|
||||
@@ -174,7 +210,7 @@ local function ST_LoadMenu(menuId)
|
||||
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 = 1
|
||||
ctx.SelLine = 0
|
||||
lastGoodMenu = menuId
|
||||
|
||||
elseif (menuId==0x1021) then
|
||||
@@ -216,14 +252,15 @@ local function ST_LoadMenu(menuId)
|
||||
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=MODEL.PORT_TEXT[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=MODEL.PORT_TEXT[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=MODEL.PORT_TEXT[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=MODEL.PORT_TEXT[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=MODEL.PORT_TEXT[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[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 }
|
||||
@@ -231,13 +268,14 @@ local function ST_LoadMenu(menuId)
|
||||
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=MODEL.PORT_TEXT[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=MODEL.PORT_TEXT[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=MODEL.PORT_TEXT[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=MODEL.PORT_TEXT[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=MODEL.PORT_TEXT[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[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 }
|
||||
@@ -321,18 +359,21 @@ local function ST_SendReceive()
|
||||
|
||||
-- DELTA has only RUDER
|
||||
if ((currWingType==WING_TYPE.ELEVON_A or currWingType==WING_TYPE.ELEVON_B) and TAIL_TYPE~=TAIL_TYPE.RUD_1) then
|
||||
currTailType = TAIL_TYPE.RUD_1
|
||||
MENU_DATA[MEMU_VAR.TAIL_TYPE] = TAIL_TYPE.RUD_1
|
||||
end
|
||||
end
|
||||
|
||||
--- Did the tail changed?
|
||||
if (currTailType ~= MENU_DATA[MEMU_VAR.TAIL_TYPE]) then
|
||||
local ntt = MENU_DATA[MEMU_VAR.TAIL_TYPE]
|
||||
if (currTailType ~= ntt) then
|
||||
if (currAircraftType==AIRCRAFT_TYPE.GLIDER) then
|
||||
currTailType = MENU_DATA[MEMU_VAR.TAIL_TYPE]
|
||||
currTailType = ntt
|
||||
modelLib.ST_GliderTailInit(currTailType)
|
||||
else
|
||||
currTailType = MENU_DATA[MEMU_VAR.TAIL_TYPE]
|
||||
modelLib.ST_PlaneTailInit(currTailType)
|
||||
if (not tailTypeCompatible(currTailType,ntt)) then
|
||||
modelLib.ST_PlaneTailInit(ntt)
|
||||
end
|
||||
currTailType = ntt
|
||||
end
|
||||
end
|
||||
|
||||
@@ -355,6 +396,7 @@ local function ST_Init_Text(rxId)
|
||||
|
||||
-- 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"
|
||||
@@ -380,8 +422,11 @@ local function ST_Init_Text(rxId)
|
||||
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] = "Traileron A"; List_Text_Img[200+TAIL_TYPE.TRAILERON_A] = "tt_traileron.png|Traileron A"
|
||||
List_Text[200+TAIL_TYPE.TRAILERON_B] = "Traileron B"; List_Text_Img[200+TAIL_TYPE.TRAILERON_B] = "tt_traileron.png|Traileron 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
|
||||
@@ -399,8 +444,9 @@ local function ST_Init()
|
||||
ST_Init_Text(0)
|
||||
|
||||
-- Setup default Data, and load a file if exist
|
||||
modelLib.ST_Default_Data()
|
||||
--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
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
|
||||
local Log, menuLib, modelLib, DEBUG_ON = ... -- Get DebugON from parameters
|
||||
local SIM_LIB_VERSION = "0.55"
|
||||
local SIM_LIB_VERSION = "0.56"
|
||||
local MSG_FILE = "/SCRIPTS/TOOLS/DSMLIB/msg_fwdp_en.txt"
|
||||
|
||||
local PHASE = menuLib.PHASE
|
||||
|
||||
@@ -6,10 +6,5 @@
|
||||
T |0x0097|DONT USE: Factory Reset
|
||||
T |0x0098|DONT USE: Factory Reset
|
||||
T |0x00A5|DONT USE: First Time Setup
|
||||
T |0x00B0|Self-Lev/Ang Dem
|
||||
T |0x00CD|Level model & capt attitude
|
||||
T |0x0190|DONT USE: Relearn Servo Settings
|
||||
T |0x020D|DONT USE: First Time SAFE Setup
|
||||
T |0x0254|Pos = Up, Neg = Down
|
||||
T |0x0267|Pos = Nose Up/Roll Right
|
||||
T |0x0268|Neg = Nose Down/Roll Left
|
||||
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.1 KiB |
BIN
Lua_scripts/DSMLIB/img/tt_taileron2.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
@@ -69,6 +69,10 @@ T |0x0053|Output Channel 3
|
||||
T |0x0054|Output Channel 4
|
||||
T |0x0055|Output Channel 5
|
||||
T |0x0056|Output Channel 6
|
||||
T |0x0057|Output Channel 7
|
||||
T |0x0058|Output Channel 8
|
||||
T |0x0059|Output Channel 9
|
||||
T |0x005A|Output Channel 10
|
||||
--
|
||||
-- FailSafe Options
|
||||
--LT|0x005E|Inh
|
||||
@@ -143,7 +147,7 @@ T |0x00A5|First Time Setup
|
||||
T |0x00AA|Capture Gyro Gains
|
||||
T |0x00AD|Gain Channel Select
|
||||
T |0x00AF|Dynamic
|
||||
LT|0x00B0|Self-Level/Angle Dem
|
||||
LT|0x00B0|Self-Level
|
||||
LT|0x00B1|Envelope
|
||||
--
|
||||
-- Flight Modes List Options
|
||||
@@ -163,9 +167,9 @@ T |0x00BE|Unknown_BE -- Used in Reset menu (0x0001) while the RX is rebooting
|
||||
--
|
||||
T |0x00C7|Calibrate Sensor
|
||||
T |0x00C8|Sensor is Calibrating.. Wait
|
||||
T |0x00CA|SAFE/Panic Mode Setup
|
||||
T |0x00CA|SAFE & Panic Mode Setup
|
||||
--
|
||||
T |0x00CD|Level model and capture attitude/m -- SPECIAL MENU to itself who is not a comment
|
||||
T |0x00CD|Level model & capt attitude/m -- SPECIAL MENU to itself who is not a comment
|
||||
T |0x00CE|Error TX Conf
|
||||
T |0x00CF|Invalid TX Ch Conf 1
|
||||
T |0x00D0|Invalid TX Ch Conf 2
|
||||
@@ -382,7 +386,7 @@ T |0x0251|Are you sure you want to ovewrite the "Target"
|
||||
T |0x0252|with the "Source" ?
|
||||
T |0x0253| -- Blank
|
||||
--
|
||||
T |0x0254|Postive = Up, Negative = Down
|
||||
T |0x0254|Pos = Up, Neg = Down
|
||||
--
|
||||
-- First time safe setup Page 1 (maybe ask to select Flight Mode cannel)
|
||||
T |0x0255|Before setting up SAFE
|
||||
@@ -404,8 +408,8 @@ T |0x0262|by "Source"
|
||||
--
|
||||
T |0x0263|Fixed/Adjustable Gains/c/b
|
||||
T |0x0266|Heading Gain/c/b
|
||||
T |0x0267|Positive = Nose Up/Roll Right
|
||||
T |0x0268|Negative = Nose Down/Roll Left
|
||||
T |0x0267|Pos = Nose Up/Roll Right
|
||||
T |0x0268|Neg = Nose Down/Roll Left
|
||||
T |0x0269|SAFE - Thr to Pitch
|
||||
T |0x026A|Use CAUTION for Yaw gain!/b
|
||||
--
|
||||
|
||||
@@ -4,255 +4,19 @@ Rewrite/Enhancements by: Francisco Arzu
|
||||
|
||||
Thanks to all the people volunteered to test it.
|
||||
|
||||
# NOTE for FC6250HX FC+RX version
|
||||
For the full size FC6250HX, Only use V0.55 or newer.
|
||||
Release Notes for
|
||||
|
||||
DO NOT use previous versions to do the Swashplate -> RX Orientation. The problem was that it did not have the orientation messages.. and you are choosing blind. The calibration will never stop until you place the RX in the right orientation, even after restarting the RX (if flashing red, is not in the right orientation.. if flashshing white is in the right orientation). If you run into this problem, and lights are blinking red, rotate the FC on the longer axis until you get white blinking.. keep it stable, will blink white faster andlet calibration finishes.. after that is back to normal.
|
||||
## COLOR Radios
|
||||
Read more [Color radios](./readme_color.md)
|
||||
|
||||
# Introduction (v0.55)
|
||||

|
||||

|
||||
|
||||
This script library enhances the original DSM Forward Programming tool. DSM Forward Programming is needed to setup many of the new Spektrum Receivers with Gyro AS3X/SAFE features. For the Gyro (/Safe) to correct the plane in flight, it needs to move the right surfaces therefore the RX needs to know the configuration of the plane (Wing Type, Tail Type, Mixers, Servo Assignments, Servo Reverse). That info tells the RX where the aileron(s) are (one or two), where the elevator(s) are (one or two), V-Tail, Delta Wing, etc.
|
||||
## Black & White Radios (Small Screens)
|
||||
Read more [black & whire radios](./readme_bw.md)
|
||||
|
||||
Since EdgeTx/OpenTx doesn’t have an equivalent setup that is stored in the radio, we have to create our own version. This info is stored inside the `/MODELS/DSMDATA` directory/folder (which needs to be created by manually).
|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
During `"Gyro Settings->initial setup"`, the RX asks the TX for model information behind the scenes. After setup, `"Gyro Settings->System Tools-> Relearn Servo Settings"` requests the TX servo configuration and stores it in the RX.
|
||||
|
||||
# Deployment
|
||||
|
||||
When upgrading from a previous version of this tool, delete your /SCRIPTS/TOOLS/DSMLIB before copying the new one (if you customized your images, inside "DSMLIB/img" do a backup first)
|
||||
|
||||
Uncompress the Zip file (ZIP version) into your local computer.
|
||||
In another window, open your TX SDCard.
|
||||
|
||||
1. The zip file has the same structure as your SDCard. If you want to copy all the content of the zip file into your SDCard top level folder, it will create all the directories and files in the right place.
|
||||
2. Make sure to check that `/MODELS/DSMDATA` is there. The script will complain at startup if it does not exist. Here the script saves the Spektrun settings for each of your models.
|
||||
|
||||
Your TX SDCard should looks like this:
|
||||
|
||||
/SCRIPTS/TOOLS/ -- you only need one of the 3 to save some space in your TOOLS screen
|
||||
DSM FwdPrg_05_BW.lua -- black/white text only
|
||||
DSM FwdPrg_05_Color.lua -- Color and touch radios
|
||||
DSM FwdPrg_05_MIN.lua -- `NEW!` Minimalistic version for radios with LOW memory (cannot setup new planes)
|
||||
|
||||
/SCRIPTS/TOOLS/DSMLIB/ -- (ALL CAPITALS) Libraries ane extra files
|
||||
DsmFwPrgLib.lua -- DSM Protocol Message and Menu engine
|
||||
DsmFwPrgSIMLib.lua -- Simulation of AR631, FC6250HX (For GUI development)
|
||||
SetupLib.lua -- Model Setup Screens
|
||||
msg_fwdp_en.txt -- `NEW!` Messages for forward programing externalized. To support other langs (english)
|
||||
... a few other files
|
||||
|
||||
/SCRIPTS/TOOLS/DSMLIB/img -- Images for RX orientations
|
||||
|
||||
Other Directories
|
||||
|
||||
/MODELS/DSMDATA --(ALL CAPITALS) Data of model config (Wing Type, Servo Assignments)
|
||||
/LOGS/dsm_log.txt --Readable log of the last RX/TX session, usefull for debugging problems
|
||||
|
||||
|
||||
|
||||
# Common Questions
|
||||
1. `RX not accepting channels higher than Ch6 for Flight-mode o Gains:`
|
||||
- V0.55 and newer: Problem solved.. Should allow you to select up to 12ch with the switch technique or with the scroller.
|
||||
|
||||
- V0.53/0.54: The RX is listening to channel changes for this options. Configure the Switch to the channel, togling once the switch will select the channel on the menu field.
|
||||
|
||||
2. `Only able to switch to Fligh-mode 2 and 3, but not 1:`
|
||||
Check that the module "Enable max throw" is OFF in you Multi-Module settings (where you do BIND), otherwise the TX signals will be out of range.
|
||||
The multi-module is already adjusting the TX/FrSky servo range internally to match Spektrum.
|
||||
|
||||
3. `Why Ch1 says Ch1 (TX:Ch3/Thr)?`:
|
||||
Radios with Multi-Module are usually configured to work the standard AETR convention. Spektrum uses TAER. The multi-module does the conversion when transmitting the signals. So `Spektrum Ch1 (Throttle)` really comes from the `TX Ch3`. We show both information (+name from the TX output). If your multi-module/radio is setup as TAER, the script will not do the re-arrangement.
|
||||
|
||||
4. `If i change the model name, the original model settings are lost.` This is correct, the model name is used to generate the file name (inside /MODEL/DSMDATA) who stores the model configuration. Currently EdgeTx and OpenTX has differt features where i could get either the Model Name or the YAML file where the EdgeTX model configuration is stored.. to keep the code compatible, the model name is used.
|
||||
|
||||
5. `Reversing a channel in my TX do not reverse the AS3X/SAFE reaction.` Correct, the chanel stick direction and the Gyro direction are two separate things.
|
||||
|
||||
5.1: First, you have setup your model so that the sticks and switches moves the surfaces in the right direction.
|
||||
|
||||
5.2: Go to the script, `Model Setup` and setup your wing type, tail type, and select the channel assigment for each surface. Leave the servo settings the same as the values in the TX to start.
|
||||
|
||||
5.3: Go to `Forward programming->Gyro Setting->Initial Setup` (New/factory reset), or `Forward programming->Gyro Setting->System Setup->Relearn Servo Settings` (not new). This will load your current Gyro servo settings into the plane's RX. This moves the current servo TX settings to the RX, so it is now in a known state.
|
||||
|
||||
5.4: Verify that the AS3X and SAFE reacts in the proper direction. You can use the Flight mode configured as "Safe Mode: Auto-Level" to see if it moves the surfaces in the right direction.
|
||||
|
||||
5.5: If a surface don't move in the right direction, go to the `Model Setup->Gyro Channel Reverse` to reverse the Gyro on the channels needed, and do again the `Forward programming->Gyro Setting->System Setup->Relearn Servo Settings` to tranfer the new settings to the RX.
|
||||
|
||||
5.6: Specktrum TX always passes the TX servo reverse as the Gyro Reverse, but on many OpenTX/EdgeTX radios, the Rud/Ail are usually reversed by default compared to Specktrum. So far i don't think that i can use this as a rule, that is why the `Gyro Channel Reverse` page exist.
|
||||
|
||||
|
||||
|
||||
---
|
||||
---
|
||||
|
||||
# Changes and fixes
|
||||
V0.55:
|
||||
1. Finally found where the TX reports to the RX how many channels is transmiting. The TX now reports itself as a 12ch radio instead of 6h. (DSM Multi-Module limit). This fixes a few things:
|
||||
|
||||
|
||||
a. Many places where you have to select channels > CH6 for Flight-Mode, Gains, Panic now works properly with the scroller. The radio is still validating that you are not selecting an invalid channel. For example, if you have an additional AIL on CH6, it will not allow you to use CH6 for FM or Gains.. it just move to the next valid one.
|
||||
|
||||
b. When setting up AIL/ELE on channels greater than CH6, on previous versions SAFE/AS3X was not moving them.. now they work up correctly. Set them up in the first in CH1-CH10. Why CH10?? Thats what fits on the reverse screen, otherwise, have to add more screens.
|
||||
|
||||
c. Some individual Gain channels was not allowing to setup on CH greater than CH6. Now is fixed.
|
||||
|
||||
2. User Interface:
|
||||
a. `RTN` Key now works as `Back` when the screen has a `Back`. Makes it easy for navigation.. Presing `RTN` on the main screen exists the tool.
|
||||
b. Much faster refresh of the menus. Optimize the process of send/recive menu data from the RX.
|
||||
|
||||
3. The TX now comunicates the SubTrim positions to the RX during `Relearn Servo Setting`. This changes the center of movement to one side or another. Really not much difference with small amounts of subtrim, previous versions where asuming subtrim of 0. When you have an extreame subtrim to one side, it was not moving simetrically.
|
||||
|
||||
4. Support for FC6250HX (the one with separate RX).. Setup Swashplate type, RX orientation works properly.. This are menu options that the smaller version that comes in the
|
||||
Blade 230S did not have.
|
||||
|
||||
|
||||
V0.54:
|
||||
1. Fix a problem in the Attitude Trim page (`Gyro Settings->System Setup->SAFE/Panic Setup->Attitude Trim`). It was not saving the values after exiting the menu. This is to change what SAFE considers "Level" flying.
|
||||
2. Wings 2-Ail 2-Flaps had a bug on the 2nd flap.
|
||||
3. New Minimalistic script (`DsmFwdPrg_05_MIN.lua`): For radios with very low memory (FrSky QX7, RM Zorro, others). It can only change existing settings, but does not have the Plane Setup menus to setup a completly new plane. In some radios, the very first time it runs (compile + run), it might give you a `not enouth memory` error.. try to run it again.
|
||||
4. External menu message file (DSMLIB/msg_fwdp_en.txt and MIN_msg_fwdp_en.txt). Intial work to do localization and different languages.
|
||||
|
||||
V0.53:
|
||||
1. Improved channel selection (Flight mode, Panic Channel, Gains Channel). Now during editing a channel, you can select any channel (>Ch4). Also, of you toggle the switch/channel it will populate the screen.
|
||||
2. Support for smaller screens (128x64) in B&W. The problem with this older radios is memory. In some, it does not have enouth memory to load the additional DSMLIB libraries.
|
||||
3. Fix formatting problem with some TX channel names who could affect the screen.. for example, rud channel should show "Ch4/rud", but shows "Ch4ud" because /r is for right justify formatting on messages. Now the formatting is only if it appears at the end of the message.
|
||||
|
||||
V0.52:
|
||||
1. Menus to be able to configure Plane in a similar way as Spektrum Radio (v0.52)
|
||||
2. Make "Gyro Settings"->"Initial Setup" works (Tested on AR631,AR637xx with PLANE type of aircraft)
|
||||
3. Properly reset and restart after initial configuration and SAFE changes.
|
||||
4. Write Log of the conversation between RX/TX. To be used for debugging a problem is reported.
|
||||
5. Provide a simulation of RX to do GUI development in Companion, and understand patterns of how the data is organized.
|
||||
|
||||
|
||||
# Tested Hardware
|
||||
- AR631/AR637xx
|
||||
- FC6250HX (Blade 230S V2 Helicopter; FC+RX in one, mini version)
|
||||
- FC6250HX (Separate RX.. use only V55 or newer of this tool)
|
||||
- AR636 (Blade 230S V1 Heli firmware 4.40)
|
||||
|
||||
- Radiomaster TX16S (All versions)
|
||||
|
||||
Please report if you have tested it with other receivers to allow us to update the documentation. Code should work up to 10 channels for the main surfaces (Ail/Ele/etc). All Spektrum RX are internally 20 channels, so you can use Ch7 for Flight Mode even if your RX is only 6 channels (See common Questions)
|
||||
|
||||
|
||||
# Messages Displayed in the GUI
|
||||
|
||||
If in a screen you get text that looks like `Unknown_XX` (ex: Unknown_D3), that message has not been setup in the script in english. If you can determine what the proper message is, you can send us a message to be added to the library.
|
||||
The `XX` represents a Hex Number (0..9,A..F) message ID.
|
||||
|
||||
|
||||
### Version 0.53 and older:
|
||||
If you want to fix it in your local copy, all messages are towards the end in the file `SCRIPT\TOOS\DSMLIB\DsmFwPrgLib.lua`. Messages for Headers are stored in `Text` and messages for Options are stored in `List_Text`. Lua scripts are text files, and can be edited with Notepad or equivalent.
|
||||
|
||||
Portion of DsmFwPrgLib.lua:
|
||||
|
||||
Text[0x0097] = "Factory Reset"
|
||||
Text[0x0098] = "Factory Reset" -- FC6250HX: Title
|
||||
Text[0x0099] = "Advanced Setup"
|
||||
Text[0x009A] = "Capture Failsafe Positions"
|
||||
Text[0x009C] = "Custom Failsafe"
|
||||
|
||||
Text[0x009F] = "Save & Reset RX" -- TODO: Find the Proper Spektrum Value ??
|
||||
|
||||
Text[0x00A5] = "First Time Setup"
|
||||
Text[0x00AA] = "Capture Gyro Gains"
|
||||
Text[0x00AD] = "Gain Channel Select"
|
||||
|
||||
-- Safe mode options, Inhibit + the values
|
||||
local safeModeOptions = {0x0003,0x00B0,0x00B1} -- inh (gap), "Self-Level/Angle Dem, Envelope
|
||||
List_Text[0x00B0] = "Self-Level/Angle Dem"
|
||||
List_Text[0x00B1] = "Envelope"
|
||||
|
||||
For example, if you get `Unknown_9D` in the GUI and your now that it should say **NEW Text**, you can edit the lua script to look like this:
|
||||
|
||||
Text[0x009A] = "Capture Failsafe Positions"
|
||||
Text[0x009C] = "Custom Failsafe"
|
||||
|
||||
Text[0x009D] = "NEW Text" -- NEW Text added for AR98xx
|
||||
|
||||
Text[0x009F] = "Save & Reset RX" -- TODO: Find the proper Spektrum text
|
||||
|
||||
### Version 0.54 and newer:
|
||||
The menu messages are stored in DSMLIB/msg_fwdp_en.txt (For english). Just add the message there. MIN_msg_fwdp_en.txt has shorter messages overrides for screens who are smaller (for minimalistic 128x64 version). The reference to the message file is at the file `/DSMLIB/DsmFwPrgLib.lua` if you want to change to use another language.
|
||||
|
||||
T |0x0097|Factory Reset
|
||||
LT|0x00B0|Self-Level/Angle Dem
|
||||
LT|0x00B1|Envelope
|
||||
|
||||
|
||||
# LOG File
|
||||
|
||||
The log file of the last use of the script is located at `/LOGS/dsm_log.txt`. **It is overridden on every start to avoid filling up the SD card**. So if you want to keep it, copy or rename it before starting the script again. (it can be renamed in the TX by browsing the SD card)
|
||||
|
||||
The log is human readable. The first number is the number of seconds since the start, and then what is the current state of the Library, and what has been sent and received. The info in the log can be easily used to create a new simulation for that RX in the future.
|
||||
|
||||
Example Log:
|
||||
|
||||
5.340 WAIT_CMD: DSM_GotoMenu(0x1010,LastSelectedLine=0)
|
||||
5.350 MENU_TITLE: SEND DSM_getMenu(MenuId=0x1010 LastSelectedLine=0)
|
||||
5.440 MENU_TITLE: RESPONSE Menu: M[Id=0x1010 P=0x0 N=0x0 B=0x1000 Text="Gyro settings"[0xF9]]
|
||||
5.490 MENU_LINES: SEND DSM_getFirstMenuLine(MenuId=0x1010)
|
||||
5.590 MENU_LINES: RESPONSE MenuLine: L[#0 T=M VId=0x1011 Text="AS3X Settings"[0x1DD] MId=0x1010 ]
|
||||
5.640 MENU_LINES: SEND DSM_getNextLine(MenuId=0x1010,LastLine=0)
|
||||
5.740 MENU_LINES: RESPONSE MenuLine: L[#1 T=M VId=0x1019 Text="SAFE Settings"[0x1E2] MId=0x1010 ]
|
||||
5.790 MENU_LINES: SEND DSM_getNextLine(MenuId=0x1010,LastLine=1)
|
||||
5.850 MENU_LINES: RESPONSE MenuLine: L[#2 T=M VId=0x1021 Text="F-Mode Setup"[0x87] MId=0x1010 ]
|
||||
5.910 MENU_LINES: SEND DSM_getNextLine(MenuId=0x1010,LastLine=2)
|
||||
5.970 MENU_LINES: RESPONSE MenuLine: L[#3 T=M VId=0x1022 Text="System Setup"[0x86] MId=0x1010 ]
|
||||
6.020 MENU_LINES: SEND DSM_getNextLine(MenuId=0x1010,LastLine=3
|
||||
|
||||
# Validation of data by the RX
|
||||
|
||||
The RX validates the data. if you change to an invalid channel or do a invalid number range, the RX will change it at the end of editing the field.
|
||||
|
||||
---
|
||||
# Version 0.53
|
||||
- Improve Channel selection in menus
|
||||
- Support smaller screens 128x64 in the black/white mode.
|
||||
|
||||
# Version 0.52
|
||||
- Fix Reversing of Servos
|
||||
- Properly detect Multimodule Ch settings AETR
|
||||
---
|
||||
|
||||
# Version 0.51 (volunteer testing version, not for production)
|
||||
- New Screens to Configure Model (Wing Type/Tail Tail, etc)
|
||||
- Finally got understanding that the previous unknown 0x05 lines are to send Model/Servo data to RX.
|
||||
- Fix use of AR636B (Firmware version 4.40.0 for Blade 230 heli, is the only one with Forward Programming)
|
||||
- Aircraft types: Tested With Plane type only.. Glider and other in progress
|
||||
|
||||
### Known Problems:
|
||||
- 4-Servo Wing type (Dual Ail/Tail) in planes give conflicting servo assignments by defaults.. Solution choose your own Ch.
|
||||
- Glider, Heli, Drone: Still in development. In glider, only a few wing type works.. needs to restrict menu options for the only valid one.
|
||||
|
||||
|
||||
# Version 0.5
|
||||
|
||||
- Make the code more readable and understandable
|
||||
- Separate the DSM Forwards Programming logic from the GUI
|
||||
- Log the communication with the RX on a /LOGS/dsm_log.txt to allow to debug it easier
|
||||
and see the exchange of data between the RX/TX
|
||||
- Created a black/white Text only version with only Key/Roller Inputs
|
||||
- Created a nicer GUI for EdgeTX touch screen color Radios
|
||||
- RX simulation for GUI development: turn on `SIMULATION_ON=true` in the beginning of the lua file
|
||||
- Test it on AR631, AR637xx, FC6250HX (Helicopter)
|
||||
|
||||
### Some settings that can change (top of Lua file):
|
||||
SIMULATION_ON = false -- FALSE: hide similation menu (DEFAULT), TRUE: show RX simulation menu
|
||||
DEBUG_ON = 1 -- 0=NO DEBUG, 1=HIGH LEVEL 2=LOW LEVEL (Debug logged into the /LOGS/dsm_log.txt)
|
||||
USE_SPECKTRUM_COLORS = true -- true: Use spectrum colors, false: use theme colors (default on OpenTX, OpenTX handle colors different)
|
||||
|
||||
|
||||
### Known Problems:
|
||||
1. **Incorrect List Value Options:** Some Menu List line (`LINE_TYPE.LIST_MENU1` or `L_m1` in logs), the range (min/max) of valid values seems to be incorrect, but the RX corrects the values.
|
||||
in the MINimalistic version, the RX is doing all the range validation, and will show invalid options temporarilly. In an Spektrum radio, it happens so fast, that you don't notice it, but in LUA scripts who are slower, you can see it in the screen.
|
||||
In the COLOR version, The code has hardcoded the valid ranges to avoid this problem.
|
||||
|
||||
2. Glider/Heli/Drone wing types not ready.
|
||||
|
||||
For Helicopter, use airplane normal wing and normal tail
|
||||
|
||||
|
||||
# Version 0.2
|
||||
Original Version from Pascal Langer
|
||||
|
||||
|
||||
181
Lua_scripts/DSMLIB/readme_bw.md
Normal file
@@ -0,0 +1,181 @@
|
||||
# Credits
|
||||
Code is based on the code/work by: Pascal Langer (Author of the Multi-Module)
|
||||
Rewrite/Enhancements by: Francisco Arzu
|
||||
|
||||
Thanks to all the people volunteered to test it.
|
||||
|
||||
# Introduction (v0.56 Black & White Small Radios)
|
||||
|
||||
!!!!!NEW!!!!!!: Finally was able to create the Plane Setup for Smaller Radios
|
||||
There is still significant memory limitations in some of this radios, so the Setup and FP was split in two files.
|
||||
The file 'DSM FwdPrg_56_STUP.lua' is the new one to create the planes setup that works together with 'DSM FwdPrg_56_MIN.lua'
|
||||
|
||||
# How to Use it
|
||||
|
||||
Step #1: Make sure that the /MODELS/DSMDATA folder exist.
|
||||
|
||||
Step #2: Run the "DSM FwdPrg_56_STUP" first to setup the plane wing, tail and channels to use for each surface. At the end it will ask you to "save" the configuration. That saves a file in the /MODELS/DSMDATA folder.
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
Why the RX needs to know the Plane Setup?? The AS3X/Gyro and SAFE needs to know what surfaces to move to do the proper correction in flight. It needs to know what channels are you using for ailerons, elevarors and rudders (could be 1 or 2 of each). Also if you have special Wing like a delta wing, the elevator and aileron functions are on the same channels.. same with V-Trails, Ruder/Elevator are combined. All this information is shared with the RX during "First Time Setup" as well as "Relearn Servo Setting". Older version of 0.55 MIN hardcoded this info to be a plain 4-ch regular plane, thats why we discourage to use those function.
|
||||
|
||||
|
||||
Step #3: Run the "DSM FwdPrg_56_MIN". It uses the model configuration created in step #2 to properly tell the receiver the plane configuration for initial setup. If you get "Cannot load model config", that means that the file was not created on step #2. Once it shows the intial forward programming page for your receiver, usuall "Gyro Settings and Other Settings". You can properly setup the a plane from initial setup... if you are not familiar with this step, view some of the videos. There are already multiple videos showing how to do it EdgeTX color version, or the Spektrum official videos, the menus are the same.
|
||||
|
||||
|
||||
## Dealing with Low memory
|
||||
On my FrSky QX7 (Probably the one with the lower memory compared to Radiomaster Boxter and maybe Zorro), it will give you "not enouth memory"
|
||||
the very first time you try to run it since is compiling + running. Try to run them at least 2 times again, this times wll just run (not compile).
|
||||
In some ocations that keeps giving memory problems, i have to restart the radio, and try to run it right after restart.
|
||||
|
||||
After it runs fine, and you try to run it the 2nd time and gives "not enouth memory", you have restart the radio.. for me this is random..
|
||||
sometimes i can run it many times consecutively.. but once it gives memory error, have to restart to be able to run again.
|
||||
Once it starts, it should work find after... is the statup who loads what it needs to memory.
|
||||
|
||||
I am running EdgeTX 2.9.2 (there was some memory cleanup in 2.9.0, and 2.9.1 to get a bit more memory)
|
||||
I left version 0.55 in the files, since it uses less memory, it can change the mayority of FP parameters, but cannot setup plane or Relearn Servo Settings
|
||||
(don't execute the menus who say 'DON'T USE!!').. v0.55 and v0.56 MINs can co-exist.
|
||||
|
||||
Video of how to deal with memory:
|
||||
https://www.youtube.com/watch?v=kG3RfVa_brU
|
||||
|
||||
# Deployment
|
||||
|
||||
Uncompress the Zip file (ZIP version) into your local computer.
|
||||
In another window, open your TX SDCard and go to `/SCRIPTS/TOOLS`.
|
||||
|
||||
When upgrading from a previous version of this tool, delete your `/SCRIPTS/TOOLS/DSMLIB` before copying the new one (if you customized the menu messages, inside `DSMLIB` do a backup of the message files first)
|
||||
|
||||
1. The zip file has the same structure as your SDCard. If you want to copy all the content of the zip file into your SDCard, it will create all the directories and files in the right place.
|
||||
|
||||
For the MINimalistic version, Your TX SDCard should looks like this:
|
||||
|
||||
/SCRIPTS/TOOLS
|
||||
DSM FwdPrg_56_MIN.lua -- Minimalistic version for radios with LOW memory (Can setup planes)
|
||||
DSM FwdPrg_56_STUP.lua -- `NEW!` Setup plane for minimalistic version (LOW Memory radios)
|
||||
DSM FwdPrg_55_MIN.lua -- Uses less memory than v56, but cannot do initial setup of the plane
|
||||
|
||||
/SCRIPTS/TOOLS/DSMLIB/ -- (ALL CAPITALS) Libraries ane extra files
|
||||
DsmFwPrgMIN_P1.lua -- Part1 of extra files for Min
|
||||
DsmFwPrgMIN_P2.lua -- Part2 of extra files for Min
|
||||
msg_fwdp_en.txt -- Menu messages in English (common for all radios)
|
||||
MIN_msg_fwdp_en.txt -- Menu messages in English (overrides for 128x164 resolution)
|
||||
|
||||
### Other Directories/Files
|
||||
|
||||
/LOGS/dsm_log.txt --Readable log of the last RX/TX session, usefull for debugging problems
|
||||
|
||||
# NOTE for FC6250HX FC+RX version
|
||||
For the full size FC6250HX, Only use V0.55 or newer.
|
||||
|
||||
DO NOT use previous versions to do the Setup -> Gyro Settings -> Orientation. The problem was that it did not have the orientation messages.. and you are were choosing blind. The calibration will never stop until you place the RX in the right orientation, even after restarting the RX (if flashing red, is not in the right orientation.. if flashshing white is in the right orientation). If you run into this problem, and lights are blinking red, rotate the FC on the longer axis until you get white blinking.. keep it stable, will blink white faster andlet calibration finishes.. after that is back to normal.
|
||||
|
||||
OpenTX: When you enter "forward programming" you will hear "Telemetry lost" and "Telemetry recovered".. The FC led will blink white, but when exit FP, will blink red...is not problem.. but will need to be power cycled to get blinking green again.. i think is something related to temporarilly loosing the connection with the radio..researching the OpenTX code since it only happens with this helis FC.
|
||||
|
||||
# Common Questions
|
||||
1. `RX not accepting channels higher than Ch6 for Flight-mode o Gains:`
|
||||
- All Spektrum RX are 20 channels internally, even if it only has 6 external Ch/Ports to connect servos.
|
||||
|
||||
- Make sure that when you bind your RX, you select the proper range of channels to use.. By default, ch1-ch8.
|
||||
|
||||
- You have to mapped a Switch/Slider to the channel, togling/moving will select the channel on the menu field.
|
||||
|
||||
- The RX validates the channels, and it does not detect signal on a channel, it will not allow to select it..that is why is important to move the switch/slider, so that the RX knows that is a valid channel.
|
||||
|
||||
|
||||
# Changes and fixes
|
||||
|
||||
v0.56:
|
||||
1. Fix Tail-Type "Taileron" functionality that was not working. Also validated V-Tail and Delta wings.
|
||||
2. Added Taileron and two Rudder config (Many Freewing Jets like F18,F16, etc)
|
||||
3. Gyro-Reverse Screen now shows what is the channel/port used for (Ail, Ele, Rud, etc)
|
||||
4. COLOR ONLY: Gyro-Reverse Screen now shows what information that shared with the RX about each channel (Role, Slave, Reverse).
|
||||
5. NEW!! Initial version of Plane Setup for B&W radios
|
||||
|
||||
V0.55:
|
||||
1. Finally found where the TX reports to the RX how many channels is transmiting. The TX now reports itself as a 12ch radio instead of 6h. (DSM Multi-Module limit). This fixes a few things:
|
||||
|
||||
a. Many places where you have to select channels > CH6 for Flight-Mode, Gains, Panic now works properly with the scroller. The radio is still validating that you are not selecting an invalid channel. For example, if you have an additional AIL on CH6, it will not allow you to use CH6 for FM or Gains.. it just move to the next valid one.
|
||||
|
||||
b. When setting up AIL/ELE on channels greater than CH6, on previous versions SAFE/AS3X was not moving them.. now they work up correctly. Set them up in the first in CH1-CH10. Why CH10?? Thats what fits on the reverse screen, otherwise, have to add more screens.
|
||||
|
||||
c. Some individual Gain channels was not allowing to setup on CH greater than CH6. Now is fixed.
|
||||
|
||||
2. User Interface:
|
||||
a. `RTN` Key now works as `Back` when the screen has a `Back`. Makes it easy for navigation.. Presing `RTN` on the main screen exists the tool.
|
||||
b. Much faster refresh of the menus. Optimize the process of send/recive menu data from the RX.
|
||||
|
||||
3. Support for FC6250HX (the one with separate RX).. Setup Swashplate type, RX orientation works properly.. This are menu options that the smaller version that comes in the
|
||||
Blade 230S did not have.
|
||||
|
||||
V0.54 Beta:
|
||||
- First version for the small screens, and limited memory. Only can change existing values, it cannot setup a brand new plane or new RX from Zero
|
||||
- Fix problem on editing the SAFE Mode Attitude Trim
|
||||
- First version with externalize merges, so that it can be translated to other languages
|
||||
|
||||
# Tested Radios and RXs
|
||||
- Radio: FrSky QX7: Due to limited memory, could be that the first time is does not start (not enouth memory to compile+run), but try again after a fresh TX restart.
|
||||
|
||||
- AR631/AR637xx
|
||||
- FC6250HX (Blade 230S V2 Helicopter)
|
||||
- FC6250HX (Separate RX.. use only V55 or newer of this tool)
|
||||
- AR636 (Blade 230S V1 Heli firmware 4.40)
|
||||
|
||||
Please report if you have tested it with other receivers to allow us to update the documentation. Code should work up to 10 channels for the main surfaces (Ail/Ele/etc). All Spektrum RX are internally 20 channels, so you can use Ch7 for Flight Mode even if your RX is only 6 channels (See common Questions)
|
||||
|
||||
# Messages Displayed in the GUI
|
||||
|
||||
If in a screen you get text that looks like `Unknown_XX` (ex: Unknown_D3), that message has not been setup in the script in english. If you can determine what the proper message is, you can send us a message to be added to the library.
|
||||
The `XX` represents a Hex Number (0..9,A..F) message ID.
|
||||
|
||||
If you want to fix it in your local copy, all messages are in the file `SCRIPT\TOOS\DSMLIB\msg_fwdp_en.txt`. (english version)
|
||||
|
||||
Example::
|
||||
|
||||
T |0x0080|Orientation
|
||||
T |0x0082|Heading
|
||||
T |0x0085|Frame Rate
|
||||
T |0x0086|System Setup
|
||||
T |0x0087|F-Mode Setup
|
||||
T |0x0088|Enabled F-Modes
|
||||
T |0x0089|Gain Channel
|
||||
T |0x008A|Gain Sensitivity/r -- Right Align
|
||||
T |0x008B|Panic
|
||||
T |0x008E|Panic Delay
|
||||
|
||||
For example, if you get `Unknown_9D` in the GUI and your now that it should say **NEW Text**, you can edit the lua script to look like this:
|
||||
T |0x009D|NEW Text -- NEW Text added for AR98xx
|
||||
|
||||
# Local Language Support
|
||||
Some settings that can change (top of Lua file):
|
||||
`local LANGUAGE = "en"`
|
||||
|
||||
If you want to translate the menu messages to another language (like french), copy the file `msg_fwdp_en.txt` into `msg_fwdp_fr.txt`, translate it, and change the language in the lua file to `"fr"`.
|
||||
|
||||
|
||||
# LOG File
|
||||
|
||||
The log file of the last use of the script is located at `/LOGS/dsm_log.txt`. **It is overridden on every start to avoid filling up the SD card**. So if you want to keep it, copy or rename it before starting the script again. (it can be renamed in the TX by browsing the SD card)
|
||||
|
||||
The log is human readable, and can help use debug problems remotrly
|
||||
|
||||
|
||||
# Validation of data by the RX
|
||||
|
||||
When you change a value in the GUI, the RX validates that the value is valid. This applies to channels as well as values.
|
||||
|
||||
|
||||
---
|
||||
# Version 0.54
|
||||
First version for Small Radios
|
||||
|
||||
### Known Problems:
|
||||
- Currently cannot setup a plane from scratch.. (Working on it).
|
||||
- The first time you run it, it will give you "not enouth memory", but should work the 2nd time after the first compilation (creation of .luac). After that, it should start right away.
|
||||
|
||||
# Version 0.2
|
||||
Original Version from Pascal Langer
|
||||
|
||||
284
Lua_scripts/DSMLIB/readme_color.md
Normal file
@@ -0,0 +1,284 @@
|
||||
# Credits
|
||||
Code is based on the code/work by: Pascal Langer (Author of the Multi-Module)
|
||||
Rewrite/Enhancements by: Francisco Arzu
|
||||
|
||||
Thanks to all the people volunteered to test it.
|
||||
|
||||
# Introduction (v0.56)
|
||||
|
||||
NOTE: Unless you use special tail types, probably not worth the upgrade. The changes are mostly cosmetic on the Gyro Reverse page to show extra information.
|
||||
|
||||
In 0.56, focused on validating and fixing the Wing and Tail type special mixing. Vtail/Delta was working but Taileron was not. The Gyro Reverse screen now show what type of servo information is sharing with the TX. This affects the Gyro AS3X and SAFE behaviour, you still needs to set your TX with the proper mixes to do V-Tail/Taileron/etc.
|
||||
|
||||
- The first is the "Role" of the port (`Ail/Ele/Rud/Thr`). Combination is posible for for special types of wing/tails: Vtail:`EleRud`, Delta & Taileron: `AilEle`.
|
||||
- The `-` (Minus) is Reverse.
|
||||
- Information is if it the Master or Slave (Master is implicit)
|
||||
- The type of mix applied: for V-Tail, the left/right Elevators (`EleRud`) uses `M_Rud` (Mix Rudder), For Delta, the left/right Ailerons (`AilEle`) uses `M_Ele` (Mix Elevator), and finally the Tailerons, the the left/right Elevators (`AilEle`) uses `M_Ail` (Mix Aileron). Looks like the Mixes are for the entire RX and only needs to be set in one of the ports, The difference between the "A" and "B" configuration is just if the mix is set on the Master or Slave port (like Taileron_A or Taileron_B) and affects the direction.. sometimes you have to try both. Start by setting the right direction for the primary roll, and then use the A/B configurations. For exmaple, in Taileron, the primary roll is Elevators, the secondary roll is Aileron (Mix Aileron). Below is a Taileron example: Two independent Elevators and 2 independent ailerons.
|
||||
|
||||

|
||||

|
||||
|
||||
|
||||
With spektrum constantly updating its firmware, you only need to update the message file if you see in the screen any message "Unknown_xyz".
|
||||
|
||||
|
||||
This script library enhances the original DSM Forward Programming tool. DSM Forward Programming is needed to setup many of the new Spektrum Receivers with Gyro AS3X/SAFE features. For the Gyro (/Safe) to correct the plane in flight, it needs to move the right surfaces therefore the RX needs to know the configuration of the plane (Wing Type, Tail Type, Mixers, Servo Assignments, Servo Reverse). That info tells the RX where the aileron(s) are (one or two), where the elevator(s) are (one or two), V-Tail, Delta Wing, etc.
|
||||
|
||||
Since EdgeTx/OpenTx doesn’t have an equivalent setup that is stored in the radio, we have to create our own version. This info is stored inside the `/MODELS/DSMDATA` directory/folder (which needs to be created by manually).
|
||||
|
||||
During `"Gyro Settings->initial setup"`, the RX asks the TX for model information behind the scenes. After setup, `"Gyro Settings->System Tools-> Relearn Servo Settings"` requests the TX servo configuration and stores it in the RX.
|
||||
|
||||
# Deployment
|
||||
|
||||
When upgrading from a previous version of this tool, delete your /SCRIPTS/TOOLS/DSMLIB before copying the new one (if you customized your images, inside "DSMLIB/img" do a backup first). Also you can delete the previous DSM_FwdProg*.* from /SCRIPTS/TOOLS.
|
||||
|
||||
Uncompress the Zip file (ZIP version) into your local computer.
|
||||
In another window, open your TX SDCard.
|
||||
|
||||
1. The zip file has the same structure as your SDCard. If you want to copy all the content of the zip file into your SDCard top level folder, it will create all the directories and files in the right place.
|
||||
2. Make sure to check that `/MODELS/DSMDATA` is there. The script will complain at startup if it does not exist. Here the script saves the Spektrun settings for each of your models.
|
||||
|
||||
Your TX SDCard should looks like this:
|
||||
|
||||
/SCRIPTS/TOOLS/ -- you only need one of the 3 to save some space in your TOOLS screen
|
||||
DSM FwdPrg_56_Color.lua -- Color and touch radios
|
||||
|
||||
|
||||
/SCRIPTS/TOOLS/DSMLIB/ -- (ALL CAPITALS) Libraries ane extra files
|
||||
DsmFwPrgLib.lua -- DSM Protocol Message and Menu engine
|
||||
DsmFwPrgSIMLib.lua -- Simulation of AR631, FC6250HX (For GUI development)
|
||||
SetupLib.lua -- Model Setup Screens
|
||||
msg_fwdp_en.txt -- `NEW!` Messages for forward programing externalized. To support other langs (english)
|
||||
... a few other files
|
||||
|
||||
/SCRIPTS/TOOLS/DSMLIB/img -- Images for RX orientations
|
||||
|
||||
Other Directories
|
||||
|
||||
/MODELS/DSMDATA --(ALL CAPITALS) Data of model config (Wing Type, Servo Assignments)
|
||||
/LOGS/dsm_log.txt --Readable log of the last RX/TX session, usefull for debugging problems
|
||||
|
||||
# NOTE for FC6250HX FC+RX version
|
||||
For the full size FC6250HX, Only use V0.55 or newer.
|
||||
|
||||
DO NOT use previous versions to do the Setup -> Gyro Settings -> Orientation. The problem was that it did not have the orientation messages.. and you are were choosing blind. The calibration will never stop until you place the RX in the right orientation, even after restarting the RX (if flashing red, is not in the right orientation.. if flashshing white is in the right orientation). If you run into this problem, and lights are blinking red, rotate the FC on the longer axis until you get white blinking.. keep it stable, will blink white faster andlet calibration finishes.. after that is back to normal.
|
||||
|
||||
OpenTX: When you enter "forward programming" you will hear "Telemetry lost" and "Telemetry recovered".. The FC led will blink white, but when exit FP, will blink red...is not problem.. but will need to be power cycled to get blinking green again.. i think is something related to temporarilly loosing the connection with the radio..researching the OpenTX code since it only happens with this helis FC.
|
||||
|
||||
# Common Questions
|
||||
1. `RX not accepting channels higher than Ch6 for Flight-mode o Gains:`
|
||||
- V0.55 and newer: Problem solved.. Should allow you to select up to 12ch with the switch technique or with the scroller.
|
||||
|
||||
- V0.53/0.54: The RX is listening to channel changes for this options. Configure the Switch to the channel, togling once the switch will select the channel on the menu field.
|
||||
|
||||
2. `Only able to switch to Fligh-mode 2 and 3, but not 1:`
|
||||
Check that the module "Enable max throw" is OFF in you Multi-Module settings (where you do BIND), otherwise the TX signals will be out of range.
|
||||
The multi-module is already adjusting the TX/FrSky servo range internally to match Spektrum.
|
||||
|
||||
3. `Why Ch1 says Ch1 (TX:Ch3/Thr)?`:
|
||||
Radios with Multi-Module are usually configured to work the standard AETR convention. Spektrum uses TAER. The multi-module does the conversion when transmitting the signals. So `Spektrum Ch1 (Throttle)` really comes from the `TX Ch3`. We show both information (+name from the TX output). If your multi-module/radio is setup as TAER, the script will not do the re-arrangement.
|
||||
|
||||
4. `If i change the model name, the original model settings are lost.` This is correct, the model name is used to generate the file name (inside /MODEL/DSMDATA) who stores the model configuration. Currently EdgeTx and OpenTX has differt features where i could get either the Model Name or the YAML file where the EdgeTX model configuration is stored.. to keep the code compatible, the model name is used.
|
||||
|
||||
5. `Reversing a channel in my TX do not reverse the AS3X/SAFE reaction.` Correct, the chanel stick direction and the Gyro direction are two separate things.
|
||||
|
||||
5.1: First, you have setup your model so that the sticks and switches moves the surfaces in the right direction.
|
||||
|
||||
5.2: Go to the script, `Model Setup` and setup your wing type, tail type, and select the channel assigment for each surface. Leave the servo settings the same as the values in the TX to start.
|
||||
|
||||
5.3: Go to `Forward programming->Gyro Setting->Initial Setup` (New/factory reset), or `Forward programming->Gyro Setting->System Setup->Relearn Servo Settings` (not new). This will load your current Gyro servo settings into the plane's RX. This moves the current servo TX settings to the RX, so it is now in a known state.
|
||||
|
||||
5.4: Verify that the AS3X and SAFE reacts in the proper direction. You can use the Flight mode configured as "Safe Mode: Auto-Level" to see if it moves the surfaces in the right direction.
|
||||
|
||||
5.5: If a surface don't move in the right direction, go to the `Model Setup->Gyro Channel Reverse` to reverse the Gyro on the channels needed, and do again the `Forward programming->Gyro Setting->System Setup->Relearn Servo Settings` to tranfer the new settings to the RX.
|
||||
|
||||
5.6: Specktrum TX always passes the TX servo reverse as the Gyro Reverse, but on many OpenTX/EdgeTX radios, the Rud/Ail are usually reversed by default compared to Specktrum. So far i don't think that i can use this as a rule, that is why the `Gyro Channel Reverse` page exist.
|
||||
|
||||
|
||||
|
||||
---
|
||||
---
|
||||
|
||||
# Changes and fixes
|
||||
V0.56:
|
||||
|
||||
1. Fix Tail-Type "Taileron" functionality that was not working. Also validated V-Tail and Delta wings.
|
||||
2. Added Taileron and two Rudder config (Many Freewing Jets like F18,F16, etc)
|
||||
3. Gyro-Reverse Screen now shows what is the channel/port used for (Ail, Ele, Rud, etc)
|
||||
4. COLOR ONLY: Gyro-Reverse Screen now shows what information that shared with the RX about each channel (Role, Slave, Reverse).
|
||||
5. NEW!! Initial version of Plane Setup for B&W radios
|
||||
|
||||
V0.55a:
|
||||
1. Fix loading external messages file for OpenTX.
|
||||
|
||||
V0.55:
|
||||
1. Finally found where the TX reports to the RX how many channels is transmiting. The TX now reports itself as a 12ch radio instead of 6h. (DSM Multi-Module limit). This fixes a few things:
|
||||
|
||||
|
||||
a. Many places where you have to select channels > CH6 for Flight-Mode, Gains, Panic now works properly with the scroller. The radio is still validating that you are not selecting an invalid channel. For example, if you have an additional AIL on CH6, it will not allow you to use CH6 for FM or Gains.. it just move to the next valid one.
|
||||
|
||||
b. When setting up AIL/ELE on channels greater than CH6, on previous versions SAFE/AS3X was not moving them.. now they work up correctly. Set them up in the first in CH1-CH10. Why CH10?? Thats what fits on the reverse screen, otherwise, have to add more screens.
|
||||
|
||||
c. Some individual Gain channels was not allowing to setup on CH greater than CH6. Now is fixed.
|
||||
|
||||
2. User Interface:
|
||||
a. `RTN` Key now works as `Back` when the screen has a `Back`. Makes it easy for navigation.. Presing `RTN` on the main screen exists the tool.
|
||||
b. Much faster refresh of the menus. Optimize the process of send/recive menu data from the RX.
|
||||
|
||||
3. The TX now comunicates the SubTrim positions to the RX during `Relearn Servo Setting`. This changes the center of movement to one side or another. Really not much difference with small amounts of subtrim, previous versions where asuming subtrim of 0. When you have an extreame subtrim to one side, it was not moving simetrically.
|
||||
|
||||
4. Support for FC6250HX (the one with separate RX).. Setup Swashplate type, RX orientation works properly.. This are menu options that the smaller version that comes in the
|
||||
Blade 230S did not have.
|
||||
|
||||
|
||||
V0.54:
|
||||
1. Fix a problem in the Attitude Trim page (`Gyro Settings->System Setup->SAFE/Panic Setup->Attitude Trim`). It was not saving the values after exiting the menu. This is to change what SAFE considers "Level" flying.
|
||||
2. Wings 2-Ail 2-Flaps had a bug on the 2nd flap.
|
||||
3. New Minimalistic script (`DsmFwdPrg_05_MIN.lua`): For radios with very low memory (FrSky QX7, RM Zorro, others). It can only change existing settings, but does not have the Plane Setup menus to setup a completly new plane. In some radios, the very first time it runs (compile + run), it might give you a `not enouth memory` error.. try to run it again.
|
||||
4. External menu message file (DSMLIB/msg_fwdp_en.txt and MIN_msg_fwdp_en.txt). Intial work to do localization and different languages.
|
||||
|
||||
V0.53:
|
||||
1. Improved channel selection (Flight mode, Panic Channel, Gains Channel). Now during editing a channel, you can select any channel (>Ch4). Also, of you toggle the switch/channel it will populate the screen.
|
||||
2. Support for smaller screens (128x64) in B&W. The problem with this older radios is memory. In some, it does not have enouth memory to load the additional DSMLIB libraries.
|
||||
3. Fix formatting problem with some TX channel names who could affect the screen.. for example, rud channel should show "Ch4/rud", but shows "Ch4ud" because /r is for right justify formatting on messages. Now the formatting is only if it appears at the end of the message.
|
||||
|
||||
V0.52:
|
||||
1. Menus to be able to configure Plane in a similar way as Spektrum Radio (v0.52)
|
||||
2. Make "Gyro Settings"->"Initial Setup" works (Tested on AR631,AR637xx with PLANE type of aircraft)
|
||||
3. Properly reset and restart after initial configuration and SAFE changes.
|
||||
4. Write Log of the conversation between RX/TX. To be used for debugging a problem is reported.
|
||||
5. Provide a simulation of RX to do GUI development in Companion, and understand patterns of how the data is organized.
|
||||
|
||||
|
||||
# Tested Hardware
|
||||
- AR631/AR637xx
|
||||
- FC6250HX (Blade 230S V2 Helicopter; FC+RX in one, mini version)
|
||||
- FC6250HX (Separate RX.. use only V55 or newer of this tool)
|
||||
- AR636 (Blade 230S V1 Heli firmware 4.40)
|
||||
|
||||
- Radiomaster TX16S (All versions)
|
||||
|
||||
Please report if you have tested it with other receivers to allow us to update the documentation. Code should work up to 10 channels for the main surfaces (Ail/Ele/etc). All Spektrum RX are internally 20 channels, so you can use Ch7 for Flight Mode even if your RX is only 6 channels (See common Questions)
|
||||
|
||||
|
||||
# Messages Displayed in the GUI
|
||||
|
||||
If in a screen you get text that looks like `Unknown_XX` (ex: Unknown_D3), that message has not been setup in the script in english. If you can determine what the proper message is, you can send us a message to be added to the library.
|
||||
The `XX` represents a Hex Number (0..9,A..F) message ID.
|
||||
|
||||
|
||||
### Version 0.53 and older:
|
||||
If you want to fix it in your local copy, all messages are towards the end in the file `SCRIPT\TOOS\DSMLIB\DsmFwPrgLib.lua`. Messages for Headers are stored in `Text` and messages for Options are stored in `List_Text`. Lua scripts are text files, and can be edited with Notepad or equivalent.
|
||||
|
||||
Portion of DsmFwPrgLib.lua:
|
||||
|
||||
Text[0x0097] = "Factory Reset"
|
||||
Text[0x0098] = "Factory Reset" -- FC6250HX: Title
|
||||
Text[0x0099] = "Advanced Setup"
|
||||
Text[0x009A] = "Capture Failsafe Positions"
|
||||
Text[0x009C] = "Custom Failsafe"
|
||||
|
||||
Text[0x009F] = "Save & Reset RX" -- TODO: Find the Proper Spektrum Value ??
|
||||
|
||||
Text[0x00A5] = "First Time Setup"
|
||||
Text[0x00AA] = "Capture Gyro Gains"
|
||||
Text[0x00AD] = "Gain Channel Select"
|
||||
|
||||
-- Safe mode options, Inhibit + the values
|
||||
local safeModeOptions = {0x0003,0x00B0,0x00B1} -- inh (gap), "Self-Level/Angle Dem, Envelope
|
||||
List_Text[0x00B0] = "Self-Level/Angle Dem"
|
||||
List_Text[0x00B1] = "Envelope"
|
||||
|
||||
For example, if you get `Unknown_9D` in the GUI and your now that it should say **NEW Text**, you can edit the lua script to look like this:
|
||||
|
||||
Text[0x009A] = "Capture Failsafe Positions"
|
||||
Text[0x009C] = "Custom Failsafe"
|
||||
|
||||
Text[0x009D] = "NEW Text" -- NEW Text added for AR98xx
|
||||
|
||||
Text[0x009F] = "Save & Reset RX" -- TODO: Find the proper Spektrum text
|
||||
|
||||
### Version 0.54 and newer:
|
||||
The menu messages are stored in DSMLIB/msg_fwdp_en.txt (For english). Just add the message there. MIN_msg_fwdp_en.txt has shorter messages overrides for screens who are smaller (for minimalistic 128x64 version). The reference to the message file is at the file `/DSMLIB/DsmFwPrgLib.lua` if you want to change to use another language.
|
||||
|
||||
T |0x0097|Factory Reset
|
||||
LT|0x00B0|Self-Level/Angle Dem
|
||||
LT|0x00B1|Envelope
|
||||
|
||||
|
||||
# LOG File
|
||||
|
||||
The log file of the last use of the script is located at `/LOGS/dsm_log.txt`. **It is overridden on every start to avoid filling up the SD card**. So if you want to keep it, copy or rename it before starting the script again. (it can be renamed in the TX by browsing the SD card)
|
||||
|
||||
The log is human readable. The first number is the number of seconds since the start, and then what is the current state of the Library, and what has been sent and received. The info in the log can be easily used to create a new simulation for that RX in the future.
|
||||
|
||||
Example Log:
|
||||
|
||||
5.340 WAIT_CMD: DSM_GotoMenu(0x1010,LastSelectedLine=0)
|
||||
5.350 MENU_TITLE: SEND DSM_getMenu(MenuId=0x1010 LastSelectedLine=0)
|
||||
5.440 MENU_TITLE: RESPONSE Menu: M[Id=0x1010 P=0x0 N=0x0 B=0x1000 Text="Gyro settings"[0xF9]]
|
||||
5.490 MENU_LINES: SEND DSM_getFirstMenuLine(MenuId=0x1010)
|
||||
5.590 MENU_LINES: RESPONSE MenuLine: L[#0 T=M VId=0x1011 Text="AS3X Settings"[0x1DD] MId=0x1010 ]
|
||||
5.640 MENU_LINES: SEND DSM_getNextLine(MenuId=0x1010,LastLine=0)
|
||||
5.740 MENU_LINES: RESPONSE MenuLine: L[#1 T=M VId=0x1019 Text="SAFE Settings"[0x1E2] MId=0x1010 ]
|
||||
5.790 MENU_LINES: SEND DSM_getNextLine(MenuId=0x1010,LastLine=1)
|
||||
5.850 MENU_LINES: RESPONSE MenuLine: L[#2 T=M VId=0x1021 Text="F-Mode Setup"[0x87] MId=0x1010 ]
|
||||
5.910 MENU_LINES: SEND DSM_getNextLine(MenuId=0x1010,LastLine=2)
|
||||
5.970 MENU_LINES: RESPONSE MenuLine: L[#3 T=M VId=0x1022 Text="System Setup"[0x86] MId=0x1010 ]
|
||||
6.020 MENU_LINES: SEND DSM_getNextLine(MenuId=0x1010,LastLine=3
|
||||
|
||||
# Validation of data by the RX
|
||||
|
||||
The RX validates the data. if you change to an invalid channel or do a invalid number range, the RX will change it at the end of editing the field.
|
||||
|
||||
---
|
||||
# Version 0.53
|
||||
- Improve Channel selection in menus
|
||||
- Support smaller screens 128x64 in the black/white mode.
|
||||
|
||||
# Version 0.52
|
||||
- Fix Reversing of Servos
|
||||
- Properly detect Multimodule Ch settings AETR
|
||||
---
|
||||
|
||||
# Version 0.51 (volunteer testing version, not for production)
|
||||
- New Screens to Configure Model (Wing Type/Tail Tail, etc)
|
||||
- Finally got understanding that the previous unknown 0x05 lines are to send Model/Servo data to RX.
|
||||
- Fix use of AR636B (Firmware version 4.40.0 for Blade 230 heli, is the only one with Forward Programming)
|
||||
- Aircraft types: Tested With Plane type only.. Glider and other in progress
|
||||
|
||||
### Known Problems:
|
||||
- 4-Servo Wing type (Dual Ail/Tail) in planes give conflicting servo assignments by defaults.. Solution choose your own Ch.
|
||||
- Glider, Heli, Drone: Still in development. In glider, only a few wing type works.. needs to restrict menu options for the only valid one.
|
||||
|
||||
|
||||
# Version 0.5
|
||||
|
||||
- Make the code more readable and understandable
|
||||
- Separate the DSM Forwards Programming logic from the GUI
|
||||
- Log the communication with the RX on a /LOGS/dsm_log.txt to allow to debug it easier
|
||||
and see the exchange of data between the RX/TX
|
||||
- Created a black/white Text only version with only Key/Roller Inputs
|
||||
- Created a nicer GUI for EdgeTX touch screen color Radios
|
||||
- RX simulation for GUI development: turn on `SIMULATION_ON=true` in the beginning of the lua file
|
||||
- Test it on AR631, AR637xx, FC6250HX (Helicopter)
|
||||
|
||||
### Some settings that can change (top of Lua file):
|
||||
SIMULATION_ON = false -- FALSE: hide similation menu (DEFAULT), TRUE: show RX simulation menu
|
||||
DEBUG_ON = 1 -- 0=NO DEBUG, 1=HIGH LEVEL 2=LOW LEVEL (Debug logged into the /LOGS/dsm_log.txt)
|
||||
USE_SPECKTRUM_COLORS = true -- true: Use spectrum colors, false: use theme colors (default on OpenTX, OpenTX handle colors different)
|
||||
|
||||
|
||||
### Known Problems:
|
||||
1. **Incorrect List Value Options:** Some Menu List line (`LINE_TYPE.LIST_MENU1` or `L_m1` in logs), the range (min/max) of valid values seems to be incorrect, but the RX corrects the values.
|
||||
in the MINimalistic version, the RX is doing all the range validation, and will show invalid options temporarilly. In an Spektrum radio, it happens so fast, that you don't notice it, but in LUA scripts who are slower, you can see it in the screen.
|
||||
In the COLOR version, The code has hardcoded the valid ranges to avoid this problem.
|
||||
|
||||
2. Glider/Heli/Drone wing types not ready.
|
||||
|
||||
For Helicopter, use airplane normal wing and normal tail
|
||||
|
||||
|
||||
# Version 0.2
|
||||
Original Version from Pascal Langer
|
||||
|
||||
@@ -198,7 +198,7 @@
|
||||
81,0,E010r5,E010r5,1,Flip,LED,CALIB,HLess,RTH,GLIDE
|
||||
82,0,LOLI,Std,0,CH5,CH6,CH7,CH8,1SwSePpPw,2SwSePw,3SwSe,4SwSe,5SwSeSb,6SwSe,7SwSePw,8SwSe
|
||||
83,0,E129,E129,1,TakLan,EmStop,TrimA,TrimE,TrimR
|
||||
83,1,E129,C186,1,TakLan,EmStop,TrimA,TrimE,TrimR
|
||||
83,1,E129,C186,1,TakLan,EmStop,TrimA,TrimE,TrimR,Loop,Flip
|
||||
84,0,JOYSWAY,Std,0
|
||||
85,0,E016H,Std,1,Stop,Flip,n-a,HLess,RTH
|
||||
87,0,IKEA
|
||||
@@ -209,3 +209,5 @@
|
||||
92,0,MT99xx2,PA18,0,MODE,FLIP,RTH
|
||||
93,0,Kyosho2,KT-17,0
|
||||
94,0,Scorpio
|
||||
95,0,Bluefly,HP100,0,CH5,CH6,CH7,CH8
|
||||
96,0,BumbleB
|
||||
|
||||
@@ -135,10 +135,14 @@ local function Config_Draw_Edit( event )
|
||||
Edit = 0
|
||||
elseif event == EVT_VIRTUAL_PREV then
|
||||
-- Change value
|
||||
Menu_value[Edit_pos] = Menu_value[Edit_pos] - 1
|
||||
if Menu_value[Edit_pos] > 0 then
|
||||
Menu_value[Edit_pos] = Menu_value[Edit_pos] - 1
|
||||
end
|
||||
elseif event == EVT_VIRTUAL_NEXT then
|
||||
-- Change value
|
||||
Menu_value[Edit_pos] = Menu_value[Edit_pos] + 1
|
||||
if Menu_value[Edit_pos] < 255 then
|
||||
Menu_value[Edit_pos] = Menu_value[Edit_pos] + 1
|
||||
end
|
||||
end
|
||||
--Blink
|
||||
Blink = Blink + 1
|
||||
@@ -319,9 +323,6 @@ local function Config_Draw_Menu()
|
||||
--Read line from buffer
|
||||
for i = 0, 20-1, 1 do
|
||||
value=multiBuffer( line*20+13+i )
|
||||
if value == 0 then
|
||||
break -- end of line
|
||||
end
|
||||
if value > 0x80 and Menu[line].field_type == 0 then
|
||||
-- Read field type
|
||||
Menu[line].field_type = bitand(value, 0xF0)
|
||||
@@ -334,6 +335,9 @@ local function Config_Draw_Menu()
|
||||
else
|
||||
if Menu[line].field_type == 0 then
|
||||
-- Text
|
||||
if value == 0 then
|
||||
break -- end of line
|
||||
end
|
||||
Menu[line].text = Menu[line].text .. string.char(value)
|
||||
else
|
||||
-- Menu specific fields
|
||||
|
||||
@@ -58,15 +58,11 @@ This is the Graupner HoTT adapted version of the Model Locator script using RSSI
|
||||
|
||||
The OpenTX sensor "RSSI" is populated by the individual OpenTX telemetry protocol implementations and returns a value from 0..100 (percent) originating from the early FrSky implementation. It turns out that FrSky did not really provide a genuine signal strength indicator in units of dbm but a link quality indicator in 0..100%. With Graupner HoTT the link quality indicator is not a good basis for the model locator as it is very non-linear and doesn't change much with distance. Using the Graupner HoTT telemetry sensor "Rssi" which is a true signal strength indicator serves the purpose of locating a model much better as it varies much more with distance.
|
||||
|
||||
## DSM Forward Programming
|
||||
## DSM Tools for EdgeTX and OpenTx
|
||||
|
||||
This is a work in progress. It's available for color(+touch) and B&W screens.
|
||||
Collection of EdgeTx/OpenTX Tools to use with Spektrum Receivers including forward programming. Located on the radio SD card under \SCRIPTS\TOOLS, make sure to copy the DSMLIB folder!
|
||||
|
||||
Work on OpenTX and EdgeTX. Located on the radio SD card under \SCRIPTS\TOOLS, make sure to copy the DSMLIB folder along with DSM FwdPrg_05_Color.lua or DSM FwdPrg_05_BW.lua.
|
||||
|
||||
[](https://www.youtube.com/watch?v=sjIaDw5j9nE)
|
||||
|
||||
If some text appears as Unknown_xxx, please report xxx and what the exact text display should be.
|
||||
Frank is maintaining these awesome tools, check out his [repository](https://github.com/frankiearzu/DSMTools). Feel free to ask questions or open issues there.
|
||||
|
||||
## DSM PID Flight log gain parameters for Blade micros
|
||||
|
||||
|
||||
196
Multiprotocol/BUMBLEB_ccnrf.ino
Normal file
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
This project is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Multiprotocol is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if defined(BUMBLEB_CCNRF_INO)
|
||||
|
||||
#include "iface_xn297.h"
|
||||
|
||||
#define FORCE_BUMBLEB_ORIGINAL_ID
|
||||
#define BUMBLEB_TELEM_DEBUG
|
||||
|
||||
#define BUMBLEB_PACKET_PERIOD 10200
|
||||
#define BUMBLEB_RF_BIND_CHANNEL 42
|
||||
#define BUMBLEB_RF_NUM_CHANNELS 2
|
||||
#define BUMBLEB_PAYLOAD_SIZE 7
|
||||
|
||||
static void __attribute__((unused)) BUMBLEB_send_packet()
|
||||
{
|
||||
packet[6] = 0x00;
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
packet[0] = rx_tx_addr[0];
|
||||
packet[1] = rx_tx_addr[1];
|
||||
packet[2] = 0x54; //???
|
||||
packet[3] = 0x58; //???
|
||||
hopping_frequency_no ^= 0x01;
|
||||
packet[4] = hopping_frequency[hopping_frequency_no];
|
||||
}
|
||||
else
|
||||
{
|
||||
//hopping frequency
|
||||
XN297_Hopping(hopping_frequency_no);
|
||||
hopping_frequency_no ^= 0x01;
|
||||
packet[0] = 0x20
|
||||
|GET_FLAG(CH6_SW,0x80); // High rate
|
||||
packet[1] = convert_channel_8b_limit_deadband(AILERON,0xBF,0xA0,0x81,40); // Aileron: Max values:BD..A0..82
|
||||
if(packet[1] < 0xA0)
|
||||
packet[1] = 0x20 - packet[1]; // Reverse low part of aileron
|
||||
packet[2] = convert_channel_8b(CH5)>>2; // 01..20..3F
|
||||
if(CH7_SW) // Drive trim from aileron
|
||||
{
|
||||
uint8_t ch=convert_channel_8b(AILERON);
|
||||
if(ch > 0x5A && ch < 0x80-0x07)
|
||||
packet[2] = ch - 0x5A;
|
||||
else if(ch < 0x5A)
|
||||
{
|
||||
if(ch < 0x5A-0x20)
|
||||
packet[2] = 0;
|
||||
else
|
||||
packet[2] = ch - (0x5A-0x20);
|
||||
}
|
||||
else if(packet[1] == 0x89)
|
||||
packet[2] = 0x20;
|
||||
else if(ch > 0xA5)
|
||||
{
|
||||
if(ch > 0xA9+0x1F)
|
||||
packet[2] = 0x3F;
|
||||
else
|
||||
packet[2] = ch - 0x89;
|
||||
}
|
||||
else if(ch > 0xA5-0x1F)
|
||||
packet[2] = ch - (0xA5-0x1F-0x20);
|
||||
}
|
||||
else
|
||||
packet[2] = convert_channel_8b(CH5)>>2; // 01..20..3F
|
||||
packet[3] = convert_channel_8b(THROTTLE)>>2; // 00..3F
|
||||
packet[4] = hopping_frequency[hopping_frequency_no];
|
||||
}
|
||||
|
||||
packet[5] = packet[0];
|
||||
for(uint8_t i=1;i<BUMBLEB_PAYLOAD_SIZE-2;i++)
|
||||
packet[5] += packet[i];
|
||||
|
||||
#if 0
|
||||
debug("P:");
|
||||
for(uint8_t i=0;i<BUMBLEB_PAYLOAD_SIZE;i++)
|
||||
debug(" %02X", packet[i]);
|
||||
debugln("");
|
||||
#endif
|
||||
|
||||
XN297_SetPower(); // Set tx_power
|
||||
XN297_SetFreqOffset(); // Set frequency offset
|
||||
XN297_SetTxRxMode(TX_EN);
|
||||
XN297_WritePayload(packet, BUMBLEB_PAYLOAD_SIZE);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) BUMBLEB_RF_init()
|
||||
{
|
||||
//Config CC2500
|
||||
XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_250K);
|
||||
XN297_SetTXAddr((uint8_t*)"\x55\x55\x55\x55\x55", 5);
|
||||
XN297_HoppingCalib(BUMBLEB_RF_NUM_CHANNELS); // Calibrate all channels
|
||||
XN297_RFChannel(BUMBLEB_RF_BIND_CHANNEL); // Set bind channel
|
||||
XN297_SetRXAddr(rx_tx_addr, BUMBLEB_PAYLOAD_SIZE);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) BUMBLEB_initialize_txid()
|
||||
{
|
||||
calc_fh_channels(BUMBLEB_RF_NUM_CHANNELS);
|
||||
rx_tx_addr[0] = rx_tx_addr[2];
|
||||
rx_tx_addr[1] = rx_tx_addr[3];
|
||||
#ifdef FORCE_BUMBLEB_ORIGINAL_ID
|
||||
rx_tx_addr[0] = 0x33;
|
||||
rx_tx_addr[1] = 0x65;
|
||||
hopping_frequency[0] = 2;
|
||||
hopping_frequency[1] = 40;
|
||||
#endif
|
||||
rx_tx_addr[2] = rx_tx_addr[3] = rx_tx_addr[4] = 0x55;
|
||||
}
|
||||
|
||||
enum {
|
||||
BUMBLEB_BIND = 0x00,
|
||||
BUMBLEB_BINDRX = 0x01,
|
||||
BUMBLEB_DATA = 0x02,
|
||||
};
|
||||
|
||||
#define BUMBLEB_WRITE_TIME 850
|
||||
|
||||
uint16_t BUMBLEB_callback()
|
||||
{
|
||||
bool rx;
|
||||
switch(phase)
|
||||
{
|
||||
case BUMBLEB_BIND:
|
||||
rx = XN297_IsRX(); // Needed for the NRF24L01 since otherwise the bit gets cleared
|
||||
|
||||
BUMBLEB_send_packet();
|
||||
|
||||
if( rx )
|
||||
{ // a packet has been received
|
||||
#ifdef BUMBLEB_TELEM_DEBUG
|
||||
debug("RX :");
|
||||
#endif
|
||||
if(XN297_ReadPayload(packet_in, BUMBLEB_PAYLOAD_SIZE))
|
||||
{ // packet with good CRC
|
||||
#ifdef BUMBLEB_TELEM_DEBUG
|
||||
debug("OK :");
|
||||
for(uint8_t i=0;i<BUMBLEB_PAYLOAD_SIZE;i++)
|
||||
debug(" %02X",packet_in[i]);
|
||||
#endif
|
||||
// packet_in = 4F 71 55 52 58 61 AA
|
||||
rx_tx_addr[2] = packet_in[0];
|
||||
rx_tx_addr[3] = packet_in[1];
|
||||
//rx_tx_addr[4] = packet_in[2]; // to test with other planes...
|
||||
XN297_SetTXAddr(rx_tx_addr, 5);
|
||||
BIND_DONE;
|
||||
phase = BUMBLEB_DATA;
|
||||
break;
|
||||
}
|
||||
}
|
||||
phase++;
|
||||
return BUMBLEB_WRITE_TIME;
|
||||
case BUMBLEB_BINDRX:
|
||||
{
|
||||
uint16_t start=(uint16_t)micros();
|
||||
while ((uint16_t)((uint16_t)micros()-(uint16_t)start) < 500)
|
||||
{
|
||||
if(XN297_IsPacketSent())
|
||||
break;
|
||||
}
|
||||
}
|
||||
XN297_SetTxRxMode(RX_EN);
|
||||
phase = BUMBLEB_BIND;
|
||||
return BUMBLEB_PACKET_PERIOD-BUMBLEB_WRITE_TIME;
|
||||
case BUMBLEB_DATA:
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(BUMBLEB_PACKET_PERIOD);
|
||||
#endif
|
||||
BUMBLEB_send_packet();
|
||||
break;
|
||||
}
|
||||
return BUMBLEB_PACKET_PERIOD;
|
||||
}
|
||||
|
||||
void BUMBLEB_init()
|
||||
{
|
||||
BUMBLEB_initialize_txid();
|
||||
BUMBLEB_RF_init();
|
||||
hopping_frequency_no = 0;
|
||||
|
||||
BIND_IN_PROGRESS; // autobind protocol
|
||||
phase = BUMBLEB_BIND;
|
||||
}
|
||||
|
||||
#endif
|
||||
118
Multiprotocol/Bluefly_ccnrf.ino
Normal file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
This project is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Multiprotocol is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
// compatible with BLUEFLY HP100
|
||||
|
||||
#if defined(BLUEFLY_CCNRF_INO)
|
||||
|
||||
#include "iface_nrf250k.h"
|
||||
|
||||
#define BLUEFLY_PACKET_PERIOD 6000
|
||||
#define BLUEFLY_PACKET_SIZE 12
|
||||
#define BLUEFLY_RF_BIND_CHANNEL 81
|
||||
#define BLUEFLY_NUM_RF_CHANNELS 15
|
||||
#define BLUEFLY_BIND_COUNT 800
|
||||
#define BLUEFLY_TXID_SIZE 5
|
||||
|
||||
static void __attribute__((unused)) BLUEFLY_send_packet()
|
||||
{
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
memset(packet, 0x55, BLUEFLY_PACKET_SIZE);
|
||||
memcpy(packet, rx_tx_addr, BLUEFLY_TXID_SIZE);
|
||||
packet[5] = hopping_frequency[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
NRF250K_Hopping(hopping_frequency_no);
|
||||
hopping_frequency_no++;
|
||||
if(hopping_frequency_no >= BLUEFLY_NUM_RF_CHANNELS);
|
||||
hopping_frequency_no = 0;
|
||||
|
||||
packet[8] = packet[9] = 0;
|
||||
for(uint8_t i=0; i<8 ; i++)
|
||||
{
|
||||
uint16_t ch = convert_channel_16b_limit(CH_AETR[i], 0, 1000);
|
||||
packet[ i] = ch;
|
||||
ch &= 0x300;
|
||||
ch >>= 2;
|
||||
packet[8 + (i>3?0:1)] = (packet[8 + (i>3?0:1)] >> 2) | ch;
|
||||
}
|
||||
// Checksum
|
||||
uint8_t l, h, t;
|
||||
l = h = 0xff;
|
||||
for (uint8_t i=0; i<10; ++i)
|
||||
{
|
||||
h ^= packet[i];
|
||||
h ^= h >> 4;
|
||||
t = h;
|
||||
h = l;
|
||||
l = t;
|
||||
t = (l<<4) | (l>>4);
|
||||
h ^= ((t<<2) | (t>>6)) & 0x1f;
|
||||
h ^= t & 0xf0;
|
||||
l ^= ((t<<1) | (t>>7)) & 0xe0;
|
||||
}
|
||||
packet[10] = h;
|
||||
packet[11] = l;
|
||||
}
|
||||
|
||||
NRF250K_WritePayload(packet, BLUEFLY_PACKET_SIZE);
|
||||
NRF250K_SetPower(); // Set tx_power
|
||||
NRF250K_SetFreqOffset(); // Set frequency offset
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) BLUEFLY_RF_init()
|
||||
{
|
||||
NRF250K_Init();
|
||||
NRF250K_SetTXAddr((uint8_t *)"\x32\xAA\x45\x45\x78", BLUEFLY_TXID_SIZE); // BLUEFLY Bind address
|
||||
NRF250K_HoppingCalib(BLUEFLY_NUM_RF_CHANNELS); // Calibrate all channels
|
||||
NRF250K_RFChannel(BLUEFLY_RF_BIND_CHANNEL); // Set bind channel
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) BLUEFLY_initialize_txid()
|
||||
{
|
||||
uint8_t start = (rx_tx_addr[3] % 47) + 2;
|
||||
for(uint8_t i=0;i<BLUEFLY_NUM_RF_CHANNELS;i++)
|
||||
hopping_frequency[i] = start + i*2;
|
||||
hopping_frequency_no=0;
|
||||
}
|
||||
|
||||
uint16_t BLUEFLY_callback()
|
||||
{
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(BLUEFLY_PACKET_PERIOD);
|
||||
#endif
|
||||
if(bind_counter)
|
||||
{
|
||||
bind_counter--;
|
||||
if (bind_counter == 0)
|
||||
{
|
||||
BIND_DONE;
|
||||
NRF250K_SetTXAddr(rx_tx_addr, BLUEFLY_TXID_SIZE);
|
||||
}
|
||||
}
|
||||
BLUEFLY_send_packet();
|
||||
return BLUEFLY_PACKET_PERIOD;
|
||||
}
|
||||
|
||||
void BLUEFLY_init(void)
|
||||
{
|
||||
BLUEFLY_initialize_txid();
|
||||
BLUEFLY_RF_init();
|
||||
|
||||
bind_counter = IS_BIND_IN_PROGRESS ? BLUEFLY_BIND_COUNT : 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -195,11 +195,11 @@ void CYRF_ConfigSOPCode(const uint8_t *sopcodes)
|
||||
CYRF_WriteRegisterMulti(CYRF_22_SOP_CODE, sopcodes, 8);
|
||||
}
|
||||
|
||||
void CYRF_ConfigDataCode(const uint8_t *datacodes, uint8_t len)
|
||||
void CYRF_ConfigDataCode(const uint8_t *datacodes)
|
||||
{
|
||||
//NOTE: This can also be implemented as:
|
||||
//for(i = 0; i < len; i++) WriteRegister)0x23, datacodes[i];
|
||||
CYRF_WriteRegisterMulti(CYRF_23_DATA_CODE, datacodes, len);
|
||||
//for(i = 0; i < 16; i++) WriteRegister)0x23, datacodes[i];
|
||||
CYRF_WriteRegisterMulti(CYRF_23_DATA_CODE, datacodes, 16);
|
||||
}
|
||||
|
||||
void CYRF_WritePreamble(uint32_t preamble)
|
||||
|
||||
@@ -4,9 +4,45 @@
|
||||
|
||||
uint8_t sop_col;
|
||||
|
||||
const uint8_t PROGMEM DSM_pncodes[5][9][8] = {
|
||||
const uint8_t PROGMEM DSM_pncodes[][8] = {
|
||||
/* Note these are in order transmitted (LSB 1st) */
|
||||
{ /* Row 0 */
|
||||
/* Row 1 */
|
||||
/* Col 0 */ {0x83, 0xF7, 0xA8, 0x2D, 0x7A, 0x44, 0x64, 0xD3},
|
||||
/* Col 1 */ {0x3F, 0x2C, 0x4E, 0xAA, 0x71, 0x48, 0x7A, 0xC9},
|
||||
/* Col 2 */ {0x17, 0xFF, 0x9E, 0x21, 0x36, 0x90, 0xC7, 0x82},
|
||||
/* Col 3 */ {0xBC, 0x5D, 0x9A, 0x5B, 0xEE, 0x7F, 0x42, 0xEB},
|
||||
/* Col 4 */ {0x24, 0xF5, 0xDD, 0xF8, 0x7A, 0x77, 0x74, 0xE7},
|
||||
/* Col 5 */ {0x3D, 0x70, 0x7C, 0x94, 0xDC, 0x84, 0xAD, 0x95},
|
||||
/* Col 6 */ {0x1E, 0x6A, 0xF0, 0x37, 0x52, 0x7B, 0x11, 0xD4},
|
||||
/* Col 7 */ {0x62, 0xF5, 0x2B, 0xAA, 0xFC, 0x33, 0xBF, 0xAF},
|
||||
/* Row 2 */
|
||||
/* Col 0 */ {0x40, 0x56, 0x32, 0xD9, 0x0F, 0xD9, 0x5D, 0x97},
|
||||
/* Col 1 */ {0x8E, 0x4A, 0xD0, 0xA9, 0xA7, 0xFF, 0x20, 0xCA},
|
||||
/* Col 2 */ {0x4C, 0x97, 0x9D, 0xBF, 0xB8, 0x3D, 0xB5, 0xBE},
|
||||
/* Col 3 */ {0x0C, 0x5D, 0x24, 0x30, 0x9F, 0xCA, 0x6D, 0xBD},
|
||||
/* Col 4 */ {0x50, 0x14, 0x33, 0xDE, 0xF1, 0x78, 0x95, 0xAD},
|
||||
/* Col 5 */ {0x0C, 0x3C, 0xFA, 0xF9, 0xF0, 0xF2, 0x10, 0xC9},
|
||||
/* Col 6 */ {0xF4, 0xDA, 0x06, 0xDB, 0xBF, 0x4E, 0x6F, 0xB3},
|
||||
/* Col 7 */ {0x9E, 0x08, 0xD1, 0xAE, 0x59, 0x5E, 0xE8, 0xF0},
|
||||
/* Row 3 */
|
||||
/* Col 0 */ {0xC0, 0x90, 0x8F, 0xBB, 0x7C, 0x8E, 0x2B, 0x8E},
|
||||
/* Col 1 */ {0x80, 0x69, 0x26, 0x80, 0x08, 0xF8, 0x49, 0xE7},
|
||||
/* Col 2 */ {0x7D, 0x2D, 0x49, 0x54, 0xD0, 0x80, 0x40, 0xC1},
|
||||
/* Col 3 */ {0xB6, 0xF2, 0xE6, 0x1B, 0x80, 0x5A, 0x36, 0xB4},
|
||||
/* Col 4 */ {0x42, 0xAE, 0x9C, 0x1C, 0xDA, 0x67, 0x05, 0xF6},
|
||||
/* Col 5 */ {0x9B, 0x75, 0xF7, 0xE0, 0x14, 0x8D, 0xB5, 0x80},
|
||||
/* Col 6 */ {0xBF, 0x54, 0x98, 0xB9, 0xB7, 0x30, 0x5A, 0x88},
|
||||
/* Col 7 */ {0x35, 0xD1, 0xFC, 0x97, 0x23, 0xD4, 0xC9, 0x88},
|
||||
/* Row 4 */
|
||||
/* Col 0 */ {0xE1, 0xD6, 0x31, 0x26, 0x5F, 0xBD, 0x40, 0x93}, // Wrong values used by Orange TX/RX Row 3 Col 8: {0x88, 0xE1, 0xD6, 0x31, 0x26, 0x5F, 0xBD, 0x40}
|
||||
/* Col 1 */ {0xDC, 0x68, 0x08, 0x99, 0x97, 0xAE, 0xAF, 0x8C},
|
||||
/* Col 2 */ {0xC3, 0x0E, 0x01, 0x16, 0x0E, 0x32, 0x06, 0xBA},
|
||||
/* Col 3 */ {0xE0, 0x83, 0x01, 0xFA, 0xAB, 0x3E, 0x8F, 0xAC},
|
||||
/* Col 4 */ {0x5C, 0xD5, 0x9C, 0xB8, 0x46, 0x9C, 0x7D, 0x84},
|
||||
/* Col 5 */ {0xF1, 0xC6, 0xFE, 0x5C, 0x9D, 0xA5, 0x4F, 0xB7},
|
||||
/* Col 6 */ {0x58, 0xB5, 0xB3, 0xDD, 0x0E, 0x28, 0xF1, 0xB0},
|
||||
/* Col 7 */ {0x5F, 0x30, 0x3B, 0x56, 0x96, 0x45, 0xF4, 0xA1},
|
||||
/* Row 0 */
|
||||
/* Col 0 */ {0x03, 0xBC, 0x6E, 0x8A, 0xEF, 0xBD, 0xFE, 0xF8},
|
||||
/* Col 1 */ {0x88, 0x17, 0x13, 0x3B, 0x2D, 0xBF, 0x06, 0xD6},
|
||||
/* Col 2 */ {0xF1, 0x94, 0x30, 0x21, 0xA1, 0x1C, 0x88, 0xA9},
|
||||
@@ -16,59 +52,15 @@ const uint8_t PROGMEM DSM_pncodes[5][9][8] = {
|
||||
/* Col 6 */ {0xEF, 0x03, 0x95, 0x89, 0xB4, 0x71, 0x61, 0x9D},
|
||||
/* Col 7 */ {0x40, 0xBA, 0x97, 0xD5, 0x86, 0x4F, 0xCC, 0xD1},
|
||||
/* Col 8 */ {0xD7, 0xA1, 0x54, 0xB1, 0x5E, 0x89, 0xAE, 0x86}
|
||||
},
|
||||
{ /* Row 1 */
|
||||
/* Col 0 */ {0x83, 0xF7, 0xA8, 0x2D, 0x7A, 0x44, 0x64, 0xD3},
|
||||
/* Col 1 */ {0x3F, 0x2C, 0x4E, 0xAA, 0x71, 0x48, 0x7A, 0xC9},
|
||||
/* Col 2 */ {0x17, 0xFF, 0x9E, 0x21, 0x36, 0x90, 0xC7, 0x82},
|
||||
/* Col 3 */ {0xBC, 0x5D, 0x9A, 0x5B, 0xEE, 0x7F, 0x42, 0xEB},
|
||||
/* Col 4 */ {0x24, 0xF5, 0xDD, 0xF8, 0x7A, 0x77, 0x74, 0xE7},
|
||||
/* Col 5 */ {0x3D, 0x70, 0x7C, 0x94, 0xDC, 0x84, 0xAD, 0x95},
|
||||
/* Col 6 */ {0x1E, 0x6A, 0xF0, 0x37, 0x52, 0x7B, 0x11, 0xD4},
|
||||
/* Col 7 */ {0x62, 0xF5, 0x2B, 0xAA, 0xFC, 0x33, 0xBF, 0xAF},
|
||||
/* Col 8 */ {0x40, 0x56, 0x32, 0xD9, 0x0F, 0xD9, 0x5D, 0x97}
|
||||
},
|
||||
{ /* Row 2 */
|
||||
/* Col 0 */ {0x40, 0x56, 0x32, 0xD9, 0x0F, 0xD9, 0x5D, 0x97},
|
||||
/* Col 1 */ {0x8E, 0x4A, 0xD0, 0xA9, 0xA7, 0xFF, 0x20, 0xCA},
|
||||
/* Col 2 */ {0x4C, 0x97, 0x9D, 0xBF, 0xB8, 0x3D, 0xB5, 0xBE},
|
||||
/* Col 3 */ {0x0C, 0x5D, 0x24, 0x30, 0x9F, 0xCA, 0x6D, 0xBD},
|
||||
/* Col 4 */ {0x50, 0x14, 0x33, 0xDE, 0xF1, 0x78, 0x95, 0xAD},
|
||||
/* Col 5 */ {0x0C, 0x3C, 0xFA, 0xF9, 0xF0, 0xF2, 0x10, 0xC9},
|
||||
/* Col 6 */ {0xF4, 0xDA, 0x06, 0xDB, 0xBF, 0x4E, 0x6F, 0xB3},
|
||||
/* Col 7 */ {0x9E, 0x08, 0xD1, 0xAE, 0x59, 0x5E, 0xE8, 0xF0},
|
||||
/* Col 8 */ {0xC0, 0x90, 0x8F, 0xBB, 0x7C, 0x8E, 0x2B, 0x8E}
|
||||
},
|
||||
{ /* Row 3 */
|
||||
/* Col 0 */ {0xC0, 0x90, 0x8F, 0xBB, 0x7C, 0x8E, 0x2B, 0x8E},
|
||||
/* Col 1 */ {0x80, 0x69, 0x26, 0x80, 0x08, 0xF8, 0x49, 0xE7},
|
||||
/* Col 2 */ {0x7D, 0x2D, 0x49, 0x54, 0xD0, 0x80, 0x40, 0xC1},
|
||||
/* Col 3 */ {0xB6, 0xF2, 0xE6, 0x1B, 0x80, 0x5A, 0x36, 0xB4},
|
||||
/* Col 4 */ {0x42, 0xAE, 0x9C, 0x1C, 0xDA, 0x67, 0x05, 0xF6},
|
||||
/* Col 5 */ {0x9B, 0x75, 0xF7, 0xE0, 0x14, 0x8D, 0xB5, 0x80},
|
||||
/* Col 6 */ {0xBF, 0x54, 0x98, 0xB9, 0xB7, 0x30, 0x5A, 0x88},
|
||||
/* Col 7 */ {0x35, 0xD1, 0xFC, 0x97, 0x23, 0xD4, 0xC9, 0x88},
|
||||
/* Col 8 */ {0xE1, 0xD6, 0x31, 0x26, 0x5F, 0xBD, 0x40, 0x93}
|
||||
// Wrong values used by Orange TX/RX
|
||||
// /* Col 8 */ {0x88, 0xE1, 0xD6, 0x31, 0x26, 0x5F, 0xBD, 0x40}
|
||||
},
|
||||
{ /* Row 4 */
|
||||
/* Col 0 */ {0xE1, 0xD6, 0x31, 0x26, 0x5F, 0xBD, 0x40, 0x93},
|
||||
/* Col 1 */ {0xDC, 0x68, 0x08, 0x99, 0x97, 0xAE, 0xAF, 0x8C},
|
||||
/* Col 2 */ {0xC3, 0x0E, 0x01, 0x16, 0x0E, 0x32, 0x06, 0xBA},
|
||||
/* Col 3 */ {0xE0, 0x83, 0x01, 0xFA, 0xAB, 0x3E, 0x8F, 0xAC},
|
||||
/* Col 4 */ {0x5C, 0xD5, 0x9C, 0xB8, 0x46, 0x9C, 0x7D, 0x84},
|
||||
/* Col 5 */ {0xF1, 0xC6, 0xFE, 0x5C, 0x9D, 0xA5, 0x4F, 0xB7},
|
||||
/* Col 6 */ {0x58, 0xB5, 0xB3, 0xDD, 0x0E, 0x28, 0xF1, 0xB0},
|
||||
/* Col 7 */ {0x5F, 0x30, 0x3B, 0x56, 0x96, 0x45, 0xF4, 0xA1},
|
||||
/* Col 8 */ {0x03, 0xBC, 0x6E, 0x8A, 0xEF, 0xBD, 0xFE, 0xF8}
|
||||
},
|
||||
};
|
||||
|
||||
static void __attribute__((unused)) DSM_read_code(uint8_t *buf, uint8_t row, uint8_t col, uint8_t len)
|
||||
static void __attribute__((unused)) DSM_read_code(uint8_t *buf, uint8_t row, uint8_t col)
|
||||
{
|
||||
for(uint8_t i=0;i<len;i++)
|
||||
buf[i]=pgm_read_byte_near( &DSM_pncodes[row][col][i] );
|
||||
row--;
|
||||
if(row>4)
|
||||
row = 4;
|
||||
for(uint8_t i=0;i<8;i++)
|
||||
buf[i]=pgm_read_byte_near( &DSM_pncodes[row*8+col][i] );
|
||||
}
|
||||
|
||||
const uint8_t PROGMEM DSM_init_vals[][2] = {
|
||||
@@ -137,11 +129,11 @@ static void __attribute__((unused)) DSM_set_sop_data_crc(bool ch2, bool dsmx)
|
||||
debug_time();
|
||||
debug(" crc:%04X,row:%d,col:%d,rf:%02X",(~seed)&0xffff,pn_row,sop_col,hopping_frequency[hopping_frequency_no]);
|
||||
#endif
|
||||
DSM_read_code(code,pn_row,sop_col,8); // pn_row between 0 and 4, sop_col between 1 and 7
|
||||
DSM_read_code(code,pn_row,sop_col); // pn_row between 0 and 4, sop_col between 0 and 7
|
||||
CYRF_ConfigSOPCode(code);
|
||||
DSM_read_code(code,pn_row,7 - sop_col,8); // 7-sop_col between 0 and 6
|
||||
DSM_read_code(code+8,pn_row,7 - sop_col + 1,8); // 7-sop_col+1 between 1 and 7
|
||||
CYRF_ConfigDataCode(code, 16);
|
||||
DSM_read_code(code,pn_row,7 - sop_col); // 7-sop_col between 0 and 7
|
||||
DSM_read_code(code+8,pn_row,7 - sop_col + 1); // 7-sop_col+1 between 1 and 8
|
||||
CYRF_ConfigDataCode(code);
|
||||
|
||||
CYRF_ConfigRFChannel(hopping_frequency[hopping_frequency_no]);
|
||||
hopping_frequency_no++;
|
||||
|
||||
@@ -39,8 +39,8 @@ static void __attribute__((unused)) DSM_RX_RF_init()
|
||||
{
|
||||
//64 SDR Mode is configured so only the 8 first values are needed but need to write 16 values...
|
||||
uint8_t code[16];
|
||||
DSM_read_code(code,0,8,8);
|
||||
CYRF_ConfigDataCode(code, 16);
|
||||
DSM_read_code(code,0,8);
|
||||
CYRF_ConfigDataCode(code);
|
||||
CYRF_ConfigRFChannel(1);
|
||||
CYRF_SetTxRxMode(RX_EN); // Force end state read
|
||||
CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x83); // Prepare to receive
|
||||
@@ -277,7 +277,7 @@ uint16_t DSM_RX_callback()
|
||||
eeprom_write_byte((EE_ADDR)temp, DSM_rx_type);
|
||||
CYRF_WriteRegister(CYRF_29_RX_ABORT, 0x20); // Abort RX operation
|
||||
CYRF_SetTxRxMode(TX_EN); // Force end state TX
|
||||
CYRF_ConfigDataCode((const uint8_t *)"\x98\x88\x1B\xE4\x30\x79\x03\x84", 16);
|
||||
CYRF_ConfigDataCode((const uint8_t *)"\x98\x88\x1B\xE4\x30\x79\x03\x84");
|
||||
CYRF_WriteRegister(CYRF_29_RX_ABORT, 0x00); // Clear abort RX
|
||||
DSM_RX_build_bind_packet();
|
||||
bind_counter=500;
|
||||
|
||||
@@ -18,16 +18,22 @@
|
||||
#include "iface_cyrf6936.h"
|
||||
|
||||
//#define DSM_DEBUG_FWD_PGM
|
||||
|
||||
//#define DEBUG_BIND 1
|
||||
//#define DSM_GR300
|
||||
|
||||
#define CLONE_BIT_MASK 0x20
|
||||
|
||||
#define DSM_BIND_CHANNEL 0x0d //13 This can be any odd channel
|
||||
|
||||
//During binding we will send BIND_COUNT/2 packets
|
||||
//During binding we will send BIND_COUNT packets
|
||||
//One packet each 10msec
|
||||
#define DSM_BIND_COUNT 300
|
||||
//
|
||||
// Most RXs seems to work properly with a long BIND send count (3s): Spektrum, OrangeRX.
|
||||
// Lemon-RX G2s seems to have a timeout waiting for the channel to get quiet after the
|
||||
// first good BIND packet.. If using 3s (300), Lemon-RX will not transmit the BIND-Response packet.
|
||||
|
||||
#define DSM_BIND_COUNT 180 // About 1.8s
|
||||
#define DSM_BIND_COUNT_READ 600 // About 4.2s of waiting for Response
|
||||
|
||||
enum {
|
||||
DSM_BIND_WRITE=0,
|
||||
@@ -118,8 +124,8 @@ static void __attribute__((unused)) DSM_initialize_bind_phase()
|
||||
CYRF_ConfigRFChannel(DSM_BIND_CHANNEL); //This seems to be random?
|
||||
//64 SDR Mode is configured so only the 8 first values are needed but need to write 16 values...
|
||||
uint8_t code[16];
|
||||
DSM_read_code(code,0,8,8);
|
||||
CYRF_ConfigDataCode(code, 16);
|
||||
DSM_read_code(code,0,8);
|
||||
CYRF_ConfigDataCode(code);
|
||||
DSM_build_bind_packet();
|
||||
}
|
||||
|
||||
@@ -292,11 +298,14 @@ uint16_t DSM_callback()
|
||||
return 10000;
|
||||
#if defined DSM_TELEMETRY
|
||||
case DSM_BIND_CHECK:
|
||||
//64 SDR Mode is configured so only the 8 first values are needed but we need to write 16 values...
|
||||
CYRF_ConfigDataCode((const uint8_t *)"\x98\x88\x1B\xE4\x30\x79\x03\x84", 16);
|
||||
#if DEBUG_BIND
|
||||
debugln("Bind Check");
|
||||
#endif
|
||||
//64 SDR Mode is configured so only the 8 first values are needed
|
||||
CYRF_ConfigDataCode((const uint8_t *)"\x98\x88\x1B\xE4\x30\x79\x03\x84");
|
||||
CYRF_SetTxRxMode(RX_EN); //Receive mode
|
||||
CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x87); //Prepare to receive
|
||||
bind_counter=2*DSM_BIND_COUNT; //Timeout of 4.2s if no packet received
|
||||
bind_counter=DSM_BIND_COUNT_READ; //Timeout of 4.2s if no packet received
|
||||
phase++; // change from BIND_CHECK to BIND_READ
|
||||
return 2000;
|
||||
case DSM_BIND_READ:
|
||||
@@ -312,10 +321,12 @@ uint16_t DSM_callback()
|
||||
CYRF_ReadDataPacketLen(packet_in+1, 10);
|
||||
if(DSM_Check_RX_packet())
|
||||
{
|
||||
debug("Bind");
|
||||
for(uint8_t i=0;i<10;i++)
|
||||
debug(" %02X",packet_in[i+1]);
|
||||
debugln("");
|
||||
#if DEBUG_BIND
|
||||
debug("Bind");
|
||||
for(uint8_t i=0;i<10;i++)
|
||||
debug(" %02X",packet_in[i+1]);
|
||||
debugln("");
|
||||
#endif
|
||||
packet_in[0]=0x80;
|
||||
packet_in[6]&=0x0F; // It looks like there is a flag 0x40 being added by some receivers
|
||||
if(packet_in[6]>12) packet_in[6]=12;
|
||||
@@ -340,6 +351,9 @@ uint16_t DSM_callback()
|
||||
}
|
||||
if( --bind_counter == 0 )
|
||||
{ // Exit if no answer has been received for some time
|
||||
#if DEBUG_BIND
|
||||
debugln("Bind Read TIMEOUT");
|
||||
#endif
|
||||
phase++; // DSM_CHANSEL
|
||||
return 7000 ;
|
||||
}
|
||||
@@ -539,19 +553,23 @@ void DSM_init()
|
||||
if(eeprom_read_byte((EE_ADDR)DSM_CLONE_EEPROM_OFFSET+4)==0xF0)
|
||||
{
|
||||
//read cloned ID from EEPROM
|
||||
debugln("Using cloned ID");
|
||||
uint16_t temp = DSM_CLONE_EEPROM_OFFSET;
|
||||
for(uint8_t i=0;i<4;i++)
|
||||
cyrfmfg_id[i] = eeprom_read_byte((EE_ADDR)temp++);
|
||||
debug("Clone ID=")
|
||||
for(uint8_t i=0;i<4;i++)
|
||||
debug("%02x ", cyrfmfg_id[i]);
|
||||
debugln("");
|
||||
#if DEBUG_BIND
|
||||
debugln("Using cloned ID");
|
||||
debug("Clone ID=")
|
||||
for(uint8_t i=0;i<4;i++)
|
||||
debug("%02x ", cyrfmfg_id[i]);
|
||||
debugln("");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
SUB_PROTO_INVALID;
|
||||
debugln("No valid cloned ID");
|
||||
#if DEBUG_BIND
|
||||
debugln("No valid cloned ID");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -609,10 +627,13 @@ void DSM_init()
|
||||
{
|
||||
DSM_initialize_bind_phase();
|
||||
phase = DSM_BIND_WRITE;
|
||||
bind_counter=DSM_BIND_COUNT;
|
||||
bind_counter=DSM_BIND_COUNT;
|
||||
#if DEBUG_BIND
|
||||
debugln("Bind Started: write count=%d",bind_counter);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
phase = DSM_CHANSEL;//
|
||||
phase = DSM_CHANSEL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -53,9 +53,11 @@ static void __attribute__((unused)) E129_build_data_packet()
|
||||
packet[15] = bit_reverse(rx_tx_addr[0]);
|
||||
packet[16] = bit_reverse(rx_tx_addr[1]);
|
||||
}
|
||||
//packet[ 3] = 0x00; // E129 Mode: short press=0x20->0x00->0x20->..., long press=0x10->0x30->0x10->... => C186 throttle trim is doing the same:up=short press and down=long press
|
||||
packet[ 4] = GET_FLAG(CH5_SW, 0x20) // Take off/Land 0x20
|
||||
| GET_FLAG(CH6_SW, 0x04); // Emergency stop 0x04
|
||||
packet[ 3] = GET_FLAG(CH10_SW, 0x40) // C159 loop flight 0x40, flag 0x04 is also set on this heli
|
||||
| GET_FLAG(CH11_SW, 0x08); // C129V2 flip
|
||||
// Other flags in packet[3] => E129 Mode: short press=0x20->0x00->0x20->..., long press=0x10->0x30->0x10->... => C186 throttle trim is doing the same:up=short press and down=long press
|
||||
packet[ 4] = GET_FLAG(CH5_SW, 0x20) // Take off/Land 0x20
|
||||
| GET_FLAG(CH6_SW, 0x04); // Emergency stop 0x04
|
||||
//Channels and trims
|
||||
uint16_t val = convert_channel_10b(AILERON,false);
|
||||
uint8_t trim = convert_channel_8b(CH7) & 0xFC;
|
||||
@@ -80,13 +82,11 @@ static void __attribute__((unused)) E129_build_data_packet()
|
||||
packet[12] = val; // channel (0x000...0x200...0x3FF)
|
||||
}
|
||||
//Check
|
||||
if(sub_protocol == E129_E129)
|
||||
packet[packet_length-2] = packet[0] + packet[1];
|
||||
else
|
||||
packet[packet_length-2] = 0x24 + packet[0] + (packet[1]&0x03); // ??
|
||||
for(uint8_t i=2;i<packet_length-2;i++)
|
||||
for(uint8_t i=0;i<packet_length-2;i++)
|
||||
packet[packet_length-2] += packet[i];
|
||||
|
||||
if(sub_protocol == E129_C186)
|
||||
packet[packet_length-2] -= 0x80;
|
||||
|
||||
RF2500_BuildPayload(packet);
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ enum PktState {
|
||||
};
|
||||
|
||||
const uint8_t PROGMEM j6pro_bind_sop_code[] = {0x62, 0xdf, 0xc1, 0x49, 0xdf, 0xb1, 0xc0, 0x49};
|
||||
//const uint8_t j6pro_data_code[] = {0x02, 0xf9, 0x93, 0x97, 0x02, 0xfa, 0x5c, 0xe3, 0x01, 0x2b, 0xf1, 0xdb, 0x01, 0x32, 0xbe, 0x6f}; // unneeded since this is the default table after a reset
|
||||
const uint8_t j6pro_data_code[] = {0x02, 0xf9, 0x93, 0x97, 0x02, 0xfa, 0x5c, 0xe3, 0x01, 0x2b, 0xf1, 0xdb, 0x01, 0x32, 0xbe, 0x6f}; // unneeded since this is the default table after a reset
|
||||
|
||||
static void __attribute__((unused)) j6pro_build_bind_packet()
|
||||
{
|
||||
@@ -84,7 +84,9 @@ static void __attribute__((unused)) j6pro_cyrf_init()
|
||||
CYRF_WriteRegister(CYRF_10_FRAMING_CFG, 0xee);
|
||||
CYRF_WriteRegister(CYRF_1F_TX_OVERRIDE, 0x00);
|
||||
CYRF_WriteRegister(CYRF_1E_RX_OVERRIDE, 0x00);
|
||||
//CYRF_ConfigDataCode(j6pro_data_code, 16);
|
||||
|
||||
//Same as default reset but issues if not configured...
|
||||
CYRF_ConfigDataCode(j6pro_data_code);
|
||||
CYRF_WritePreamble(0x333302);
|
||||
|
||||
CYRF_GetMfgData(cyrfmfg_id);
|
||||
|
||||
@@ -17,26 +17,64 @@
|
||||
|
||||
#include "iface_cyrf6936.h"
|
||||
|
||||
#define LOSI_FORCE_ID
|
||||
//#define LOSI_FORCE_ID
|
||||
|
||||
const uint8_t PROGMEM LOSI_bind_sop_code[] = {0x62, 0xdf, 0xc1, 0x49, 0xdf, 0xb1, 0xc0, 0x49};
|
||||
const uint8_t LOSI_data_code[][16] = {
|
||||
{ 0xD7, 0xA1, 0x54, 0xB1, 0x5E, 0x89, 0xAE, 0x86, 0xC9, 0x2C, 0x06, 0x93, 0x86, 0xB9, 0x9E, 0xD7 }, //bind
|
||||
/* { 0xE1, 0xD6, 0x31, 0x26, 0x5F, 0xBD, 0x40, 0x93, 0xDC, 0x68, 0x08, 0x99, 0x97, 0xAE, 0xAF, 0x8C },
|
||||
{ 0xDC, 0x68, 0x08, 0x99, 0x97, 0xAE, 0xAF, 0x8C, 0xC3, 0x0E, 0x01, 0x16, 0x0E, 0x32, 0x06, 0xBA },
|
||||
{ 0xC3, 0x0E, 0x01, 0x16, 0x0E, 0x32, 0x06, 0xBA, 0xE0, 0x83, 0x01, 0xFA, 0xAB, 0x3E, 0x8F, 0xAC },
|
||||
{ 0xE0, 0x83, 0x01, 0xFA, 0xAB, 0x3E, 0x8F, 0xAC, 0x5C, 0xD5, 0x9C, 0xB8, 0x46, 0x9C, 0x7D, 0x84 },
|
||||
{ 0x5C, 0xD5, 0x9C, 0xB8, 0x46, 0x9C, 0x7D, 0x84, 0xF1, 0xC6, 0xFE, 0x5C, 0x9D, 0xA5, 0x4F, 0xB7 },
|
||||
{ 0xF1, 0xC6, 0xFE, 0x5C, 0x9D, 0xA5, 0x4F, 0xB7, 0x58, 0xB5, 0xB3, 0xDD, 0x0E, 0x28, 0xF1, 0xB0 },
|
||||
{ 0x58, 0xB5, 0xB3, 0xDD, 0x0E, 0x28, 0xF1, 0xB0, 0x5F, 0x30, 0x3B, 0x56, 0x96, 0x45, 0xF4, 0xA1 },*/
|
||||
{ 0x5F, 0x30, 0x3B, 0x56, 0x96, 0x45, 0xF4, 0xA1, 0x03, 0xBC, 0x6E, 0x8A, 0xEF, 0xBD, 0xFE, 0xF8 } //normal
|
||||
};
|
||||
/* Using DSM.ino data codes since they are the same
|
||||
const uint8_t LOSI_data_code[][8] = {
|
||||
//(Freq-1)%5=0
|
||||
{ 0x83, 0xF7, 0xA8, 0x2D, 0x7A, 0x44, 0x64, 0xD3 },
|
||||
{ 0x3F, 0x2C, 0x4E, 0xAA, 0x71, 0x48, 0x7A, 0xC9 },
|
||||
{ 0x17, 0xFF, 0x9E, 0x21, 0x36, 0x90, 0xC7, 0x82 },
|
||||
{ 0xBC, 0x5D, 0x9A, 0x5B, 0xEE, 0x7F, 0x42, 0xEB },
|
||||
{ 0x24, 0xF5, 0xDD, 0xF8, 0x7A, 0x77, 0x74, 0xE7 },
|
||||
{ 0x3D, 0x70, 0x7C, 0x94, 0xDC, 0x84, 0xAD, 0x95 },
|
||||
{ 0x1E, 0x6A, 0xF0, 0x37, 0x52, 0x7B, 0x11, 0xD4 },
|
||||
{ 0x62, 0xF5, 0x2B, 0xAA, 0xFC, 0x33, 0xBF, 0xAF },
|
||||
//(Freq-1)%5=1
|
||||
{ 0x40, 0x56, 0x32, 0xD9, 0x0F, 0xD9, 0x5D, 0x97 },
|
||||
{ 0x8E, 0x4A, 0xD0, 0xA9, 0xA7, 0xFF, 0x20, 0xCA },
|
||||
{ 0x4C, 0x97, 0x9D, 0xBF, 0xB8, 0x3D, 0xB5, 0xBE },
|
||||
{ 0x0C, 0x5D, 0x24, 0x30, 0x9F, 0xCA, 0x6D, 0xBD },
|
||||
{ 0x50, 0x14, 0x33, 0xDE, 0xF1, 0x78, 0x95, 0xAD },
|
||||
{ 0x0C, 0x3C, 0xFA, 0xF9, 0xF0, 0xF2, 0x10, 0xC9 },
|
||||
{ 0xF4, 0xDA, 0x06, 0xDB, 0xBF, 0x4E, 0x6F, 0xB3 },
|
||||
{ 0x9E, 0x08, 0xD1, 0xAE, 0x59, 0x5E, 0xE8, 0xF0 },
|
||||
//(Freq-1)%5=2
|
||||
{ 0xC0, 0x90, 0x8F, 0xBB, 0x7C, 0x8E, 0x2B, 0x8E },
|
||||
{ 0x80, 0x69, 0x26, 0x80, 0x08, 0xF8, 0x49, 0xE7 },
|
||||
{ 0x7D, 0x2D, 0x49, 0x54, 0xD0, 0x80, 0x40, 0xC1 },
|
||||
{ 0xB6, 0xF2, 0xE6, 0x1B, 0x80, 0x5A, 0x36, 0xB4 },
|
||||
{ 0x42, 0xAE, 0x9C, 0x1C, 0xDA, 0x67, 0x05, 0xF6 },
|
||||
{ 0x9B, 0x75, 0xF7, 0xE0, 0x14, 0x8D, 0xB5, 0x80 },
|
||||
{ 0xBF, 0x54, 0x98, 0xB9, 0xB7, 0x30, 0x5A, 0x88 },
|
||||
{ 0x35, 0xD1, 0xFC, 0x97, 0x23, 0xD4, 0xC9, 0x88 },
|
||||
//(Freq-1)%5=3
|
||||
{ 0xE1, 0xD6, 0x31, 0x26, 0x5F, 0xBD, 0x40, 0x93 },
|
||||
{ 0xDC, 0x68, 0x08, 0x99, 0x97, 0xAE, 0xAF, 0x8C },
|
||||
{ 0xC3, 0x0E, 0x01, 0x16, 0x0E, 0x32, 0x06, 0xBA },
|
||||
{ 0xE0, 0x83, 0x01, 0xFA, 0xAB, 0x3E, 0x8F, 0xAC },
|
||||
{ 0x5C, 0xD5, 0x9C, 0xB8, 0x46, 0x9C, 0x7D, 0x84 },
|
||||
{ 0xF1, 0xC6, 0xFE, 0x5C, 0x9D, 0xA5, 0x4F, 0xB7 },
|
||||
{ 0x58, 0xB5, 0xB3, 0xDD, 0x0E, 0x28, 0xF1, 0xB0 },
|
||||
{ 0x5F, 0x30, 0x3B, 0x56, 0x96, 0x45, 0xF4, 0xA1 },
|
||||
//(Freq-1)%5=4
|
||||
{ 0x03, 0xBC, 0x6E, 0x8A, 0xEF, 0xBD, 0xFE, 0xF8 },
|
||||
{ 0x88, 0x17, 0x13, 0x3B, 0x2D, 0xBF, 0x06, 0xD6 },
|
||||
{ 0xF1, 0x94, 0x30, 0x21, 0xA1, 0x1C, 0x88, 0xA9 },
|
||||
{ 0xD0, 0xD2, 0x8E, 0xBC, 0x82, 0x2F, 0xE3, 0xB4 },
|
||||
{ 0x8C, 0xFA, 0x47, 0x9B, 0x83, 0xA5, 0x66, 0xD0 },
|
||||
{ 0x07, 0xBD, 0x9F, 0x26, 0xC8, 0x31, 0x0F, 0xB8 },
|
||||
{ 0xEF, 0x03, 0x95, 0x89, 0xB4, 0x71, 0x61, 0x9D },
|
||||
{ 0x40, 0xBA, 0x97, 0xD5, 0x86, 0x4F, 0xCC, 0xD1 },
|
||||
//Bind
|
||||
{ 0xD7, 0xA1, 0x54, 0xB1, 0x5E, 0x89, 0xAE, 0x86 }
|
||||
};*/
|
||||
|
||||
static uint16_t __attribute__((unused)) LOSI_check(uint16_t val)
|
||||
{
|
||||
const uint8_t PROGMEM tab[] = { 0xF1, 0xDA, 0xB6, 0xC8 };
|
||||
uint8_t res = 0x0B, tmp;
|
||||
uint16_t calc = val>>2; // don't care about the 2 first bits
|
||||
uint8_t res = crc8, tmp;
|
||||
uint16_t calc = val>>2; // don't care about the 2 first bits
|
||||
for(uint8_t i=0; i<5; i++)
|
||||
{
|
||||
tmp=pgm_read_byte_near(&tab[i&0x03]);
|
||||
@@ -56,8 +94,11 @@ static void __attribute__((unused)) LOSI_send_packet()
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
memcpy(&packet[4], rx_tx_addr, 4);
|
||||
packet[8] = 0x05; // CRC?
|
||||
packet[9] = 0x52; // CRC?
|
||||
crc = 0x0170;
|
||||
for(uint8_t i=0; i < 8; i++)
|
||||
crc += packet[i];
|
||||
packet[8] = crc >> 8;
|
||||
packet[9] = crc;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -88,60 +129,89 @@ static void __attribute__((unused)) LOSI_cyrf_init()
|
||||
CYRF_WriteRegister(CYRF_1B_TX_OFFSET_LSB, 0x55);
|
||||
CYRF_WriteRegister(CYRF_1C_TX_OFFSET_MSB, 0x05);
|
||||
//CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x24);
|
||||
CYRF_SetPower(0x38);
|
||||
CYRF_SetPower(0x38); // 64 SDR mode -> 8 bytes data code
|
||||
CYRF_WriteRegister(CYRF_12_DATA64_THOLD, 0x0A);
|
||||
CYRF_WriteRegister(CYRF_39_ANALOG_CTRL, 0x01);
|
||||
CYRF_WritePreamble(0x333304);
|
||||
//CYRF_WriteRegister(CYRF_27_CLK_OVERRIDE, 0x00);
|
||||
CYRF_WriteRegister(CYRF_10_FRAMING_CFG, 0x4A);
|
||||
CYRF_WriteRegister(CYRF_1F_TX_OVERRIDE, 0x04); // No CRC
|
||||
CYRF_WriteRegister(CYRF_1F_TX_OVERRIDE, 0x04); // No CRC
|
||||
//CYRF_WriteRegister(CYRF_1E_RX_OVERRIDE, 0x14);
|
||||
//CYRF_WriteRegister(CYRF_14_EOP_CTRL, 0x02);
|
||||
uint8_t code[16];
|
||||
DSM_read_code(code,0,8); // Load bind data code by default
|
||||
CYRF_ConfigDataCode(code);
|
||||
}
|
||||
|
||||
uint16_t LOSI_callback()
|
||||
{
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(19738);
|
||||
telemetry_set_input_sync(packet_period);
|
||||
#endif
|
||||
LOSI_send_packet();
|
||||
if(bind_counter)
|
||||
{
|
||||
bind_counter--;
|
||||
if(bind_counter==0)
|
||||
{
|
||||
BIND_DONE;
|
||||
CYRF_ConfigDataCode(LOSI_data_code[1], 16); // Load normal data code
|
||||
// Load normal data code
|
||||
uint8_t code[16];
|
||||
DSM_read_code(code,hopping_frequency[0] % 5,(rx_tx_addr[0] + rx_tx_addr[1] + rx_tx_addr[2]) % 8);
|
||||
CYRF_ConfigDataCode(code);
|
||||
packet_period = 19738;
|
||||
}
|
||||
return 8763;
|
||||
}
|
||||
return 19738;
|
||||
LOSI_send_packet();
|
||||
return packet_period;
|
||||
}
|
||||
|
||||
void LOSI_init()
|
||||
{
|
||||
LOSI_cyrf_init();
|
||||
//CYRF_FindBestChannels(hopping_frequency, 1, 0, 0x13, 75); // 75 is unknown since dump stops at 0x27, this routine resets the CRC Seed to 0
|
||||
//CYRF_ConfigRFChannel(hopping_frequency[0] | 1); // Only odd channels
|
||||
|
||||
CYRF_FindBestChannels(hopping_frequency, 1, 0, 0x07, 0x4F); // 0x07 and 0x4F are unknown limits, this routine resets the CRC Seed to 0
|
||||
hopping_frequency[0] |= 1; // Only odd channels are used, integrated in CYRF code...
|
||||
|
||||
crc8 = 0;
|
||||
crc8 = (uint16_t)LOSI_check(((rx_tx_addr[2]&0x0F) << 8) + rx_tx_addr[3]) >> 12;
|
||||
|
||||
#ifdef LOSI_FORCE_ID
|
||||
/*
|
||||
rx_tx_addr[0] = 0x47;
|
||||
rx_tx_addr[1] = 0x52;
|
||||
rx_tx_addr[2] = 0xAE;
|
||||
rx_tx_addr[3] = 0xAA;
|
||||
CYRF_ConfigRFChannel(0x27);
|
||||
crc8 = 0x0B;
|
||||
num_ch = 0x07;
|
||||
//Data codes for hopping_frequency[0] % 5
|
||||
//{ 0x40, 0xBA, 0x97, 0xD5, 0x86, 0x4F, 0xCC, 0xD1, 0xD7, 0xA1, 0x54, 0xB1, 0x5E, 0x89, 0xAE, 0x86 },
|
||||
//{ 0x62, 0xF5, 0x2B, 0xAA, 0xFC, 0x33, 0xBF, 0xAF, 0x40, 0x56, 0x32, 0xD9, 0x0F, 0xD9, 0x5D, 0x97 },
|
||||
//{ 0x9E, 0x08, 0xD1, 0xAE, 0x59, 0x5E, 0xE8, 0xF0, 0xC0, 0x90, 0x8F, 0xBB, 0x7C, 0x8E, 0x2B, 0x8E },
|
||||
//{ 0x35, 0xD1, 0xFC, 0x97, 0x23, 0xD4, 0xC9, 0x88, 0xE1, 0xD6, 0x31, 0x26, 0x5F, 0xBD, 0x40, 0x93 },
|
||||
//{ 0x5F, 0x30, 0x3B, 0x56, 0x96, 0x45, 0xF4, 0xA1, 0x03, 0xBC, 0x6E, 0x8A, 0xEF, 0xBD, 0xFE, 0xF8 }
|
||||
*/
|
||||
rx_tx_addr[0] = 0x56;
|
||||
rx_tx_addr[1] = 0x52;
|
||||
rx_tx_addr[2] = 0x22;
|
||||
rx_tx_addr[3] = 0x8A;
|
||||
crc8 = 0x0F;
|
||||
num_ch = 0x02;
|
||||
//Data codes for hopping_frequency[0] % 5
|
||||
//{ 0xF1, 0x94, 0x30, 0x21, 0xA1, 0x1C, 0x88, 0xA9, 0xD0, 0xD2, 0x8E, 0xBC, 0x82, 0x2F, 0xE3, 0xB4 },
|
||||
//{ 0x17, 0xFF, 0x9E, 0x21, 0x36, 0x90, 0xC7, 0x82, 0xBC, 0x5D, 0x9A, 0x5B, 0xEE, 0x7F, 0x42, 0xEB },
|
||||
//{ 0x4C, 0x97, 0x9D, 0xBF, 0xB8, 0x3D, 0xB5, 0xBE, 0x0C, 0x5D, 0x24, 0x30, 0x9F, 0xCA, 0x6D, 0xBD },
|
||||
//{ 0x7D, 0x2D, 0x49, 0x54, 0xD0, 0x80, 0x40, 0xC1, 0xB6, 0xF2, 0xE6, 0x1B, 0x80, 0x5A, 0x36, 0xB4 },
|
||||
//{ 0xC3, 0x0E, 0x01, 0x16, 0x0E, 0x32, 0x06, 0xBA, 0xE0, 0x83, 0x01, 0xFA, 0xAB, 0x3E, 0x8F, 0xAC }
|
||||
|
||||
// Note: crc8=00..0F and num_ch=00..07
|
||||
// num_ch = (rx_tx_addr[0] + rx_tx_addr[1] + rx_tx_addr[2]) % 8;
|
||||
// crc8 = (uint16_t)LOSI_check(((rx_tx_addr[2]&0x0F) << 8) + rx_tx_addr[3]) >> 12;
|
||||
#endif
|
||||
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
bind_counter = 300;
|
||||
CYRF_ConfigDataCode(LOSI_data_code[0], 16); // Load bind data code
|
||||
}
|
||||
else
|
||||
{
|
||||
CYRF_ConfigDataCode(LOSI_data_code[1], 16); // Load normal data code
|
||||
bind_counter = 0;
|
||||
}
|
||||
CYRF_ConfigRFChannel(hopping_frequency[0]);
|
||||
|
||||
bind_counter = IS_BIND_IN_PROGRESS?300:1;
|
||||
packet_period = 8763;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -421,7 +421,7 @@ uint16_t MLINK_callback()
|
||||
|
||||
|
||||
case MLINK_PREP_DATA:
|
||||
CYRF_ConfigDataCode(MLINK_Data_Code,16);
|
||||
CYRF_ConfigDataCode(MLINK_Data_Code);
|
||||
MLINK_CRC_Init += 0xED;
|
||||
hopping_frequency_no = 0x00;
|
||||
CYRF_ConfigRFChannel(hopping_frequency[hopping_frequency_no]);
|
||||
@@ -597,7 +597,7 @@ void MLINK_init()
|
||||
{
|
||||
packet_count = 0;
|
||||
bind_counter = MLINK_BIND_COUNT;
|
||||
CYRF_ConfigDataCode((uint8_t*)"\x6F\xBE\x32\x01\xDB\xF1\x2B\x01\xE3\x5C\xFA\x02\x97\x93\xF9\x02",16); //Bind data code
|
||||
CYRF_ConfigDataCode((uint8_t*)"\x6F\xBE\x32\x01\xDB\xF1\x2B\x01\xE3\x5C\xFA\x02\x97\x93\xF9\x02"); //Bind data code
|
||||
CYRF_ConfigRFChannel(MLINK_BIND_CHANNEL);
|
||||
phase = MLINK_BIND_TX;
|
||||
}
|
||||
|
||||
@@ -91,3 +91,5 @@
|
||||
92,MT99xx,PA18
|
||||
93,Kyosho2,KT-17
|
||||
94,Scorpio
|
||||
95,BlueFly
|
||||
96,BumbleB
|
||||
|
||||
@@ -106,6 +106,8 @@ const char STR_LOSI[] ="Losi";
|
||||
const char STR_MOULDKG[] ="MouldKg";
|
||||
const char STR_XERALL[] ="Xerall";
|
||||
const char STR_SCORPIO[] ="Scorpio";
|
||||
const char STR_BLUEFLY[] ="BlueFly";
|
||||
const char STR_BUMBLEB[] ="BumbleB";
|
||||
|
||||
const char STR_SUBTYPE_FLYSKY[] = "\x04""Std\0""V9x9""V6x6""V912""CX20";
|
||||
const char STR_SUBTYPE_HUBSAN[] = "\x04""H107""H301""H501";
|
||||
@@ -222,6 +224,12 @@ const mm_protocol_definition multi_protocols[] = {
|
||||
#if defined(BAYANG_RX_NRF24L01_INO)
|
||||
{PROTO_BAYANG_RX, STR_BAYANG_RX, STR_CPPM, NBR_CPPM, OPTION_NONE, 0, 0, SW_NRF, BAYANG_RX_init, BAYANG_RX_callback },
|
||||
#endif
|
||||
#if defined(BLUEFLY_CCNRF_INO)
|
||||
{PROTO_BLUEFLY, STR_BLUEFLY, NO_SUBTYPE, 0, OPTION_RFTUNE, 0, 0, SW_NRF, BLUEFLY_init, BLUEFLY_callback },
|
||||
#endif
|
||||
#if defined(BUMBLEB_CCNRF_INO)
|
||||
{PROTO_BUMBLEB, STR_BUMBLEB, NO_SUBTYPE, 0, OPTION_RFTUNE, 0, 0, SW_NRF, BUMBLEB_init, BUMBLEB_callback },
|
||||
#endif
|
||||
#if defined(BUGS_A7105_INO)
|
||||
{PROTO_BUGS, STR_BUGS, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_A7105, BUGS_init, BUGS_callback },
|
||||
#endif
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#define VERSION_MAJOR 1
|
||||
#define VERSION_MINOR 3
|
||||
#define VERSION_REVISION 3
|
||||
#define VERSION_PATCH_LEVEL 33
|
||||
#define VERSION_PATCH_LEVEL 43
|
||||
|
||||
#define MODE_SERIAL 0
|
||||
|
||||
@@ -122,6 +122,9 @@ enum PROTOCOLS
|
||||
PROTO_MT99XX2 = 92, // =>NRF24L01, extension of MT99XX protocol
|
||||
PROTO_KYOSHO2 = 93, // =>NRF24L01
|
||||
PROTO_SCORPIO = 94, // =>CYRF6936
|
||||
PROTO_BLUEFLY = 95, // =>CC2500 & NRF24L01
|
||||
PROTO_BUMBLEB = 96, // =>CC2500 & NRF24L01
|
||||
|
||||
|
||||
PROTO_NANORF = 126, // =>NRF24L01
|
||||
PROTO_TEST = 127, // =>CC2500
|
||||
@@ -829,8 +832,9 @@ enum {
|
||||
#define FRSKYX2_CLONE_EEPROM_OFFSET 873 // (1) format + (3) TX ID, 4 bytes, end is 877
|
||||
#define DSM_RX_EEPROM_OFFSET 877 // (4) TX ID + format, 5 bytes, end is 882
|
||||
#define MOULDKG_EEPROM_OFFSET 882 // RX ID, 3 bytes per model, end is 882+64*3=1074
|
||||
#define DSM_CLONE_EEPROM_OFFSET 1074 // (4) TX ID, (1) Initialized, end is 1079
|
||||
//#define CONFIG_EEPROM_OFFSET 1079 // Current configuration of the multimodule
|
||||
#define DSM_CLONE_EEPROM_OFFSET 1074 // (4) TX ID, (1) Initialized, end is 1079
|
||||
#define TRAXXAS_EEPROM_OFFSET 1079 // RX ID, 2 bytes per model id, end is 1079+128=1207
|
||||
//#define CONFIG_EEPROM_OFFSET 1207 // Current configuration of the multimodule
|
||||
|
||||
/* STM32 Flash Size */
|
||||
#ifndef DISABLE_FLASH_SIZE_CHECK
|
||||
|
||||
@@ -291,8 +291,10 @@ const uint8_t PROGMEM pelikan_lite_hopp[][PELIKAN_NUM_RF_CHAN] = {
|
||||
#endif
|
||||
#ifdef PELIKAN_SCX24_FORCE_HOP
|
||||
const uint8_t PROGMEM pelikan_scx24_hopp[][PELIKAN_NUM_RF_CHAN] = {
|
||||
{ 0x1E,0x32,0x46,0x5A,0x44,0x58,0x2E,0x42,0x56,0x2C,0x40,0x54,0x2A,0x3E,0x52,0x28,0x3C,0x50,0x26,0x3A,0x4E,0x24,0x38,0x4C,0x22,0x36,0x4A,0x20,0x1A },
|
||||
{ 0x2C,0x44,0x1E,0x52,0x56,0x22,0x3A,0x3E,0x34,0x4C,0x26,0x5A,0x50,0x2A,0x42,0x38,0x2E,0x46,0x20,0x54,0x4A,0x24,0x3C,0x32,0x28,0x40,0x58,0x1B,0x4E }
|
||||
/*TX1*/ { 0x1E,0x32,0x46,0x5A,0x44,0x58,0x2E,0x42,0x56,0x2C,0x40,0x54,0x2A,0x3E,0x52,0x28,0x3C,0x50,0x26,0x3A,0x4E,0x24,0x38,0x4C,0x22,0x36,0x4A,0x20,0x1A },
|
||||
/*TX2*/ { 0x2C,0x44,0x1E,0x52,0x56,0x22,0x3A,0x3E,0x34,0x4C,0x26,0x5A,0x50,0x2A,0x42,0x38,0x2E,0x46,0x20,0x54,0x4A,0x24,0x3C,0x32,0x28,0x40,0x58,0x1B,0x4E },
|
||||
/*TX3*/ { 0x3C,0x4C,0x1E,0x4A,0x5A,0x2C,0x58,0x2A,0x3A,0x56,0x28,0x38,0x26,0x36,0x46,0x34,0x44,0x54,0x42,0x52,0x24,0x50,0x22,0x32,0x4E,0x20,0x40,0x3E,0x17 },
|
||||
/*TX4*/ { 0x46,0x32,0x1E,0x58,0x44,0x5A,0x56,0x42,0x2E,0x54,0x40,0x2C,0x52,0x3E,0x2A,0x50,0x3C,0x28,0x4E,0x3A,0x26,0x4C,0x38,0x24,0x4A,0x36,0x22,0x20,0x1A }
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -345,18 +347,26 @@ void PELIKAN_init()
|
||||
{
|
||||
#if defined(PELIKAN_SCX24_FORCE_HOP)
|
||||
// Hop frequency table
|
||||
uint8_t num=rx_tx_addr[3] & 0x01;
|
||||
if(num)
|
||||
{//1
|
||||
rx_tx_addr[0]=0x10; // hopping freq TX2
|
||||
rx_tx_addr[1]=0x63; // hopping freq TX2
|
||||
uint8_t num=rx_tx_addr[3] & 0x03;
|
||||
switch(num)
|
||||
{
|
||||
case 1:
|
||||
rx_tx_addr[0]=0x10; // hopping freq TX2
|
||||
rx_tx_addr[1]=0x63; // hopping freq TX2
|
||||
break;
|
||||
case 2:
|
||||
rx_tx_addr[0]=0x81; // hopping freq TX3
|
||||
rx_tx_addr[1]=0x63; // hopping freq TX3
|
||||
break;
|
||||
case 3:
|
||||
rx_tx_addr[0]=0x36; // hopping freq TX4
|
||||
rx_tx_addr[1]=0x5C; // hopping freq TX4
|
||||
break;
|
||||
default:
|
||||
rx_tx_addr[0]=0x12; // hopping freq TX1
|
||||
rx_tx_addr[1]=0x46; // hopping freq TX1
|
||||
break;
|
||||
}
|
||||
else
|
||||
{//0
|
||||
rx_tx_addr[0]=0x12; // hopping freq TX1
|
||||
rx_tx_addr[1]=0x46; // hopping freq TX1
|
||||
}
|
||||
|
||||
for(uint8_t i=0;i<PELIKAN_NUM_RF_CHAN;i++)
|
||||
hopping_frequency[i]=pgm_read_byte_near(&pelikan_scx24_hopp[num][i]);
|
||||
#endif
|
||||
@@ -366,6 +376,10 @@ void PELIKAN_init()
|
||||
rx_tx_addr[3]=0x19; // TX1
|
||||
rx_tx_addr[2]=0x80; // TX2
|
||||
rx_tx_addr[3]=0x22; // TX2
|
||||
rx_tx_addr[2]=0x30; // TX3
|
||||
rx_tx_addr[3]=0x18; // TX3
|
||||
rx_tx_addr[2]=0x30; // TX4
|
||||
rx_tx_addr[3]=0x17; // TX4
|
||||
#endif
|
||||
A7105_WriteReg(A7105_0E_DATA_RATE,0x03);
|
||||
if(IS_BIND_DONE)
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "iface_cyrf6936.h"
|
||||
|
||||
//#define TRAXXAS_FORCE_ID
|
||||
//#define TRAXXAS_DEBUG
|
||||
|
||||
#define TRAXXAS_CHANNEL 0x05
|
||||
#define TRAXXAS_BIND_CHANNEL 0x2B
|
||||
@@ -65,8 +66,9 @@ static void __attribute__((unused)) TRAXXAS_cyrf_data_config()
|
||||
CYRF_WriteRegister(CYRF_15_CRC_SEED_LSB, 0x1B);
|
||||
CYRF_WriteRegister(CYRF_16_CRC_SEED_MSB, 0x3F);
|
||||
#else
|
||||
CYRF_WriteRegister(CYRF_15_CRC_SEED_LSB, cyrfmfg_id[0]+0xB6);
|
||||
CYRF_WriteRegister(CYRF_16_CRC_SEED_MSB, cyrfmfg_id[1]+0x5D);
|
||||
uint16_t addr=TRAXXAS_EEPROM_OFFSET+RX_num*2;
|
||||
CYRF_WriteRegister(CYRF_15_CRC_SEED_LSB, cyrfmfg_id[0] - eeprom_read_byte((EE_ADDR)(addr + 0)));
|
||||
CYRF_WriteRegister(CYRF_16_CRC_SEED_MSB, cyrfmfg_id[1] - eeprom_read_byte((EE_ADDR)(addr + 1)));
|
||||
#endif
|
||||
CYRF_ConfigRFChannel(TRAXXAS_CHANNEL);
|
||||
CYRF_SetTxRxMode(TX_EN);
|
||||
@@ -76,6 +78,8 @@ static void __attribute__((unused)) TRAXXAS_send_data_packet()
|
||||
{
|
||||
packet[0] = 0x01;
|
||||
memset(&packet[1],0x00,TRAXXAS_PACKET_SIZE-1);
|
||||
//Next RF channel ? 0x00 -> keep current, 0x0E change to F=15
|
||||
//packet[1]
|
||||
//Steering
|
||||
uint16_t ch = convert_channel_16b_nolimit(RUDDER,500,1000,false);
|
||||
packet[2]=ch>>8;
|
||||
@@ -115,22 +119,35 @@ uint16_t TRAXXAS_callback()
|
||||
status = CYRF_ReadRegister(CYRF_07_RX_IRQ_STATUS);
|
||||
if((status & 0x03) == 0x02) // RXC=1, RXE=0 then 2nd check is required (debouncing)
|
||||
status |= CYRF_ReadRegister(CYRF_07_RX_IRQ_STATUS);
|
||||
debugln("s=%02X",status);
|
||||
#ifdef TRAXXAS_DEBUG
|
||||
debugln("s=%02X",status);
|
||||
#endif
|
||||
CYRF_WriteRegister(CYRF_07_RX_IRQ_STATUS, 0x80); // need to set RXOW before data read
|
||||
if((status & 0x07) == 0x02)
|
||||
{ // Data received with no errors
|
||||
len=CYRF_ReadRegister(CYRF_09_RX_COUNT);
|
||||
debugln("L=%02X",len)
|
||||
#ifdef TRAXXAS_DEBUG
|
||||
debugln("L=%02X",len)
|
||||
#endif
|
||||
if(len==TRAXXAS_PACKET_SIZE)
|
||||
{
|
||||
CYRF_ReadDataPacketLen(packet, TRAXXAS_PACKET_SIZE);
|
||||
debug("RX=");
|
||||
for(uint8_t i=0;i<TRAXXAS_PACKET_SIZE;i++)
|
||||
debug(" %02X",packet[i]);
|
||||
debugln("");
|
||||
#ifdef TRAXXAS_DEBUG
|
||||
debug("RX=");
|
||||
for(uint8_t i=0;i<TRAXXAS_PACKET_SIZE;i++)
|
||||
debug(" %02X",packet[i]);
|
||||
debugln("");
|
||||
#endif
|
||||
// Store RX ID
|
||||
uint16_t addr=TRAXXAS_EEPROM_OFFSET+RX_num*2;
|
||||
for(uint8_t i=0;i<2;i++)
|
||||
eeprom_write_byte((EE_ADDR)(addr+i),packet[i+1]);
|
||||
// Replace RX ID by TX ID
|
||||
for(uint8_t i=0;i<6;i++)
|
||||
packet[i+1]=cyrfmfg_id[i];
|
||||
packet[10]=0x01;
|
||||
packet[7 ] = 0xEE; // Not needed ??
|
||||
packet[10] = 0x01; // Must change otherwise bind doesn't complete
|
||||
packet[13] = 0x05; // Not needed ??
|
||||
packet_count=12;
|
||||
CYRF_SetTxRxMode(TX_EN);
|
||||
phase=TRAXXAS_BIND_TX1;
|
||||
@@ -150,10 +167,12 @@ uint16_t TRAXXAS_callback()
|
||||
return 700;
|
||||
case TRAXXAS_BIND_TX1:
|
||||
CYRF_WriteDataPacketLen(packet, TRAXXAS_PACKET_SIZE);
|
||||
debug("P=");
|
||||
for(uint8_t i=0;i<TRAXXAS_PACKET_SIZE;i++)
|
||||
debug(" %02X",packet[i]);
|
||||
debugln("");
|
||||
#ifdef TRAXXAS_DEBUG
|
||||
debug("P=");
|
||||
for(uint8_t i=0;i<TRAXXAS_PACKET_SIZE;i++)
|
||||
debug(" %02X",packet[i]);
|
||||
debugln("");
|
||||
#endif
|
||||
if(--packet_count==0) // Switch to normal mode
|
||||
phase=TRAXXAS_PREP_DATA;
|
||||
break;
|
||||
@@ -179,7 +198,7 @@ void TRAXXAS_init()
|
||||
|
||||
//Read CYRF ID
|
||||
CYRF_GetMfgData(cyrfmfg_id);
|
||||
cyrfmfg_id[0]+=RX_num;
|
||||
//cyrfmfg_id[0]+=RX_num; // Not needed since the TX and RX have to match
|
||||
|
||||
#ifdef TRAXXAS_FORCE_ID // data taken from TX dump
|
||||
cyrfmfg_id[0]=0x65; // CYRF MFG ID
|
||||
@@ -197,6 +216,13 @@ void TRAXXAS_init()
|
||||
}
|
||||
else
|
||||
phase = TRAXXAS_PREP_DATA;
|
||||
|
||||
//
|
||||
// phase = TRAXXAS_BIND_TX1;
|
||||
// TRAXXAS_cyrf_bind_config();
|
||||
// CYRF_SetTxRxMode(TX_EN);
|
||||
// memcpy(packet,(uint8_t *)"\x02\x4A\xA3\x2D\x1A\x49\xFE\x06\x00\x00\x02\x01\x06\x06\x00\x00",TRAXXAS_PACKET_SIZE);
|
||||
// memcpy(packet,(uint8_t *)"\x02\xFF\xFF\xFF\xFF\xFF\xFF\x01\x01\x01\x02\x01\x06\x00\x00\x00",TRAXXAS_PACKET_SIZE);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -207,7 +233,15 @@ CRC_SEED_LSB: 0x5A
|
||||
CRC_SEED_MSB: 0x5A
|
||||
RX1: 0x02 0x4A 0xA3 0x2D 0x1A 0x49 0xFE 0x06 0x00 0x00 0x02 0x01 0x06 0x06 0x00 0x00
|
||||
TX1: 0x02 0x65 0xE2 0x5E 0x55 0x4D 0xFE 0xEE 0x00 0x00 0x01 0x01 0x06 0x05 0x00 0x00
|
||||
Note: RX cyrfmfg_id is 0x4A,0xA3,0x2D,0x1A,0x49,0xFE and TX cyrfmfg_id is 0x65,0xE2,0x5E,0x55,0x4D,0xFE
|
||||
Notes:
|
||||
- RX cyrfmfg_id is 0x4A,0xA3,0x2D,0x1A,0x49,0xFE and TX cyrfmfg_id is 0x65,0xE2,0x5E,0x55,0x4D,0xFE
|
||||
- P[7] changes from 0x06 to 0xEE but not needed to complete the bind -> doesn't care??
|
||||
- P[8..9]=0x00 unchanged??
|
||||
- P[10] needs to be set to 0x01 to complete the bind -> normal packet P[0]??
|
||||
- P[11] unchanged ?? -> no bind if set to 0x00 or 0x81
|
||||
- P[12] unchanged ?? -> no bind if set to 0x05 or 0x86
|
||||
- P[13] changes from 0x06 to 0x05 but not needed to complete the bind -> doesn't care??
|
||||
- P[14..15]=0x00 unchanged??
|
||||
|
||||
Bind phase 2 (looks like normal mode?)
|
||||
CHANNEL: 0x05
|
||||
@@ -231,5 +265,13 @@ SOP_CODE: 0xA1 0x78 0xDC 0x3C 0x9E 0x82 0xDC 0x3C
|
||||
CRC_SEED_LSB: 0x1B
|
||||
CRC_SEED_MSB: 0x3F
|
||||
TX3: 0x01 0x00 0x02 0xA8 0x03 0xE7 0x02 0x08 0x00 0x00 0x01 0x01 0x02 0xEE 0x00 0x00
|
||||
|
||||
CRC_SEED:
|
||||
TX ID: \x65\xE2\x5E\x55\x4D\xFE
|
||||
RX ID: \x4A\xA3\x2D\x1A\x49\xFE CRC 0x1B 0x3F => CRC: 65-4A=1B E2-A3=3F
|
||||
RX ID: \x4B\xA3\x2D\x1A\x49\xFE CRC 0x1A 0x3F => CRC: 65-4B=1A E2-A3=3F
|
||||
RX ID: \x00\x00\x2D\x1A\x49\xFE CRC 0x65 0xE2 => CRC: 65-00=65 E2-00=E2
|
||||
RX ID: \x00\xFF\x2D\x1A\x49\xFE CRC 0x65 0xE3 => CRC: 65-00=65 E2-FF=E3
|
||||
RX ID: \xFF\x00\x2D\x1A\x49\xFE CRC 0x66 0xE2 => CRC: 65-FF=66 E2-00=E2
|
||||
*/
|
||||
#endif
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
// flags going to packet[2]
|
||||
#define V911S_FLAG_CALIB 0x01
|
||||
#define A220_FLAG_6G3D 0x04
|
||||
#define A280_FLAG_6GSENIOR 0x08
|
||||
#define A280_FLAG_LIGHT 0x20
|
||||
|
||||
static void __attribute__((unused)) V911S_send_packet()
|
||||
{
|
||||
@@ -74,7 +76,9 @@ static void __attribute__((unused)) V911S_send_packet()
|
||||
{
|
||||
packet[ 1]=GET_FLAG(!CH6_SW,E119_FLAG_EXPERT) // short press on left button
|
||||
|GET_FLAG( CH5_SW,E119_FLAG_CALIB); // short press on right button
|
||||
packet[ 2]=GET_FLAG( CH7_SW,A220_FLAG_6G3D); // short press on right button
|
||||
packet[ 2]=GET_FLAG( CH7_SW,A220_FLAG_6G3D) // short press on right button
|
||||
|GET_FLAG( CH8_SW,A280_FLAG_6GSENIOR) // -100% - 6G, +100% - Senior mode (turn off gyro)
|
||||
|GET_FLAG( CH9_SW,A280_FLAG_LIGHT); // cycle the light through on-flash-off when the CH9 value is changed from -100% to 100%
|
||||
}
|
||||
|
||||
//packet[3..6]=trims TAER signed
|
||||
|
||||
@@ -340,6 +340,8 @@
|
||||
#undef ZSX_NRF24L01_INO
|
||||
#endif
|
||||
#if ( not defined(CC2500_INSTALLED) && not defined(NRF24L01_INSTALLED) ) || defined MULTI_EU
|
||||
#undef BLUEFLY_CCNRF_INO
|
||||
#undef BUMBLEB_CCNRF_INO
|
||||
#undef GD00X_CCNRF_INO
|
||||
#undef KF606_CCNRF_INO
|
||||
#undef MJXQ_CCNRF_INO
|
||||
@@ -351,6 +353,9 @@
|
||||
#undef V911S_CCNRF_INO
|
||||
#undef XK_CCNRF_INO
|
||||
#endif
|
||||
#if not defined(DSM_CYRF6936_INO)
|
||||
#undef LOSI_CYRF6936_INO
|
||||
#endif
|
||||
#if not defined(STM32_BOARD)
|
||||
//RF2500 emulation does not work on atmega...
|
||||
#undef E010R5_CYRF6936_INO
|
||||
|
||||
@@ -191,7 +191,7 @@
|
||||
//#define E01X_CYRF6936_INO
|
||||
#define E129_CYRF6936_INO
|
||||
#define J6PRO_CYRF6936_INO
|
||||
//#define LOSI_CYRF6936_INO
|
||||
#define LOSI_CYRF6936_INO //Need DSM to be enabled
|
||||
#define MLINK_CYRF6936_INO
|
||||
#define SCORPIO_CYRF6936_INO
|
||||
#define TRAXXAS_CYRF6936_INO
|
||||
@@ -255,6 +255,7 @@
|
||||
#define ZSX_NRF24L01_INO
|
||||
|
||||
//The protocols below need either a CC2500 or NRF24L01 to be installed
|
||||
#define BLUEFLY_CCNRF_INO
|
||||
#define GD00X_CCNRF_INO
|
||||
#define KF606_CCNRF_INO
|
||||
#define MJXQ_CCNRF_INO
|
||||
@@ -567,6 +568,8 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
|
||||
QX100
|
||||
PROTO_BAYANG_RX
|
||||
NONE
|
||||
PROTO_BLUEFLY
|
||||
NONE
|
||||
PROTO_BUGS
|
||||
NONE
|
||||
PROTO_BUGSMINI
|
||||
|
||||
@@ -85,7 +85,7 @@ void CYRF_SetPower(u8 power);
|
||||
void CYRF_ConfigCRCSeed(u16 crc);
|
||||
static void CYRF_StartReceive();
|
||||
void CYRF_ConfigSOPCode(const u8 *sopcodes);
|
||||
void CYRF_ConfigDataCode(const u8 *datacodes, u8 len);
|
||||
void CYRF_ConfigDataCode(const u8 *datacodes);
|
||||
static u8 CYRF_ReadRSSI(u32 dodummyread);
|
||||
static void CYRF_ReadDataPacket(u8 dpbuffer[]);
|
||||
void CYRF_WriteDataPacket(const u8 dpbuffer[]);
|
||||
|
||||
@@ -65,6 +65,7 @@ Protocol Name|Protocol Number|Sub_Proto 0|Sub_Proto 1|Sub_Proto 2|Sub_Proto 3|Su
|
||||
[Assan](Protocols_Details.md#ASSAN---24)|24|||||||||NRF24L01|
|
||||
[Bayang](Protocols_Details.md#BAYANG---14)|14|Bayang|H8S3D|X16_AH|IRDRONE|DHD_D4|QX100|||NRF24L01|XN297
|
||||
[Bayang RX](Protocols_Details.md#BAYANG-RX---59)|59|Multi|CPPM|||||||NRF24L01|XN297
|
||||
[BlueFly](Protocols_Details.md#BLUEFLY---95)|95|||||||||NRF24L01|
|
||||
[Bugs](Protocols_Details.md#BUGS---41)|41|||||||||A7105|
|
||||
[BugsMini](Protocols_Details.md#BUGSMINI---42)|42|BUGSMINI|BUGS3H|||||||NRF24L01|XN297
|
||||
[Cabell](Protocols_Details.md#Cabell---34)|34|Cabell_V3|C_TELEM|-|-|-|-|F_SAFE|UNBIND|NRF24L01|
|
||||
@@ -325,7 +326,9 @@ CH1|CH2|CH3|CH4
|
||||
## Kyosho - *73*
|
||||
|
||||
### Sub_protocol FHSS - *0*
|
||||
Surface protocol called FHSS introduced in 2017. Transmitters: KT-531P, KT-431PT...
|
||||
Surface protocol called FHSS introduced in 2017. Transmitter: KT-531P. Models: Mini-Z
|
||||
|
||||
Extended limits supported
|
||||
|
||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13|CH14
|
||||
---|---|---|---|---|---|---|---|---|----|----|----|----|----
|
||||
@@ -358,11 +361,11 @@ Models: TX: CADET 4 LITE
|
||||
**Only 1 frequency hopping table**
|
||||
|
||||
### Sub_protocol SCX24 - *2*
|
||||
TX: Axial AX-4 2.4GHz transmitter and Panda Hobby 3CH Smart Radio 2.4GHz (MT-305A)
|
||||
TX: Axial AX-4 2.4GHz transmitter, HPI TF-41 and Panda Hobby 3CH Smart Radio 2.4GHz (MT-305A)
|
||||
|
||||
Models: Axial SCX24: Deadbolt, Jeep Wranger Rubicon, Chevrolet 1967 C10, B-17 Betty and Panda Hobby: Tetra K1, X1, X2
|
||||
Models: Axial SCX24: Deadbolt, Jeep Wranger Rubicon, Chevrolet 1967 C10, B-17 Betty, HPI RF-50 and Panda Hobby: Tetra K1, X1, X2
|
||||
|
||||
**Only 2 frequency hopping tables**
|
||||
**Only 4 frequency hopping tables**
|
||||
|
||||
Extended limits supported
|
||||
|
||||
@@ -616,10 +619,18 @@ Calib is the same as the original radio with both sticks down and to the left in
|
||||
Models: Eachine E129/E130 and Twister Ninja 250
|
||||
|
||||
### Sub_protocol C186 - *1*
|
||||
Models: C186/E120, C127/E110, K127, C159
|
||||
Models: C186/E120, C127/E110, K127, C159, C189, C129v2
|
||||
|
||||
The FC of the heli seems to store the trims Trim A/E/R=CH7..9. If you use these trims, make sure to center them after powering off the heli or they will be added to the previous trims and over correct.
|
||||
|
||||
CH10|CH11
|
||||
---|---
|
||||
Loop|Flip
|
||||
|
||||
Loop: circular flight on the C159 (others?)
|
||||
|
||||
Flip: flip/aerobatic on the C129v2 (others?)
|
||||
|
||||
## J6Pro - *22*
|
||||
|
||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12
|
||||
@@ -629,8 +640,6 @@ A|E|T|R|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12
|
||||
## Losi - *89*
|
||||
TX: LSR-3000
|
||||
|
||||
**Only 1 ID available**. More IDs can be added if you dump your original TX.
|
||||
|
||||
Extended limits supported
|
||||
|
||||
CH1|CH2|CH3
|
||||
@@ -1024,6 +1033,17 @@ If a CC2500 is installed it will be used for all the below protocols. Option in
|
||||
|
||||
If only a NRF24L01 is installed then these protocols might be problematic because they are using the XN297L emulation with a transmission speed of 250kbps which doesn't work very well with every NRF24L01, this is an hardware issue with the authenticity and accuracy of the components.
|
||||
|
||||
## BLUEFLY - *95*
|
||||
Model: HP100
|
||||
|
||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
||||
---|---|---|---|---|---|---|---
|
||||
A|E|T|R|CH5|CH6|CH7|CH8
|
||||
|
||||
TRIM: either use this channel for trim only or add a mixer with aileron to increase the roll rate.
|
||||
|
||||
RATE: -100% high rate, +100% low rate
|
||||
|
||||
## GD00X - *47*
|
||||
Model: GD005 C-17 Transport, GD006 DA62 and ZC-Z50
|
||||
|
||||
@@ -1370,9 +1390,11 @@ Models: WLtoys V911S, XK A110
|
||||
### Sub_protocol E119 - *1*
|
||||
Models: Eachine E119, JJRC W01-J3, XK A220 P-40, XK A800 R2, F959S R2, A160 R2, A280
|
||||
|
||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7
|
||||
---|---|---|---|---|---|---
|
||||
A|E|T|R|CALIB|RATE|6G_3D
|
||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
|
||||
---|---|---|---|---|---|---|---|---
|
||||
A|E|T|R|CALIB|RATE|6G_3D|6GSENIOR|LIGHT
|
||||
|
||||
A280 -> 6GSENIOR: -100% - 6G, +100% - Senior mode (turn off gyro), LIGHT: cycle the light through on-flash-off when the CH9 value is changed from -100% to 100%
|
||||
|
||||
## XK - *62*
|
||||
|
||||
@@ -1392,7 +1414,7 @@ If a CC2500 is installed it will be used for this sub protocol. Option in this c
|
||||
If only a NRF24L01 is installed then this sub protocol might be problematic because it is using the xn297L emulation with a transmission speed of 250kbps which doesn't work very well with every NRF24L01, this is an hardware issue with the authenticity and accuracy of the components.
|
||||
|
||||
### Sub_protocol X420 - *1*
|
||||
Models: XK X420/X520 (TX=X4)
|
||||
Models: XK X420/X520 (TX=X4), WLtoys 284131/284161/284010
|
||||
|
||||
***
|
||||
# NRF24L01 RF Module
|
||||
@@ -1647,13 +1669,13 @@ Only 8 TX IDs available
|
||||
Model: FX620 SU35
|
||||
|
||||
### Sub_protocol 9630 - *2*
|
||||
Model: FX9630 and QIDI-550
|
||||
Model: FX9630, FX9603 and QIDI-550
|
||||
|
||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
|
||||
---|---|---|---|---|---|---|---|---
|
||||
A|E|T|R|RATE|GYRO|TrimR|TrimA|TrimE
|
||||
|
||||
FX9630 Gyro: -100%=6G small throw, 0%=6G large throw, +100%=3D
|
||||
FX9630 and FX9603 Gyro: -100%=6G small throw, 0%=6G large throw, +100%=3D
|
||||
|
||||
QIDI-550 Gyro: -100%=3D, 0%=6G, +100%=Torque
|
||||
|
||||
@@ -1942,7 +1964,7 @@ CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11
|
||||
A|E|T|R|FLIP|LIGHT|PICTURE|VIDEO|HEADLESS|MAG_CAL_X|MAG_CAL_Y
|
||||
|
||||
### Sub_protocol V2x2 - *0*
|
||||
Models: WLToys V202/252/272, JXD 385/388, JJRC H6C, Yizhan Tarantula X6 ...
|
||||
Models: WLToys V202/252/272/A959/K969/K979/K989/K999, JXD 385/388, JJRC H6C, Yizhan Tarantula X6 ...
|
||||
|
||||
PICTURE: also automatic Missile Launcher and Hoist in one direction
|
||||
|
||||
@@ -1973,6 +1995,8 @@ AUTO: Land=-100% Takeoff=+100%
|
||||
The model can work with a none centered throttle.
|
||||
|
||||
## Tiger - *61*
|
||||
Models: Tiger Drone 1400782, WLToys 124016 / 124017 / 144010 and Eachine EAT14
|
||||
|
||||
Autobind protocol
|
||||
|
||||
**Only 1 ID**
|
||||
|
||||
@@ -86,6 +86,7 @@ buildEachRFModule() {
|
||||
buildReleaseFiles(){
|
||||
if [[ "$BOARD" =~ ":avr:multixmega32d4" ]]; then
|
||||
build_release_orx;
|
||||
build_release_extras;
|
||||
elif [[ "$BOARD" =~ ":avr:multiatmega328p:bootloader=none" ]]; then
|
||||
build_release_avr_noboot;
|
||||
elif [[ "$BOARD" =~ ":avr:multiatmega328p:bootloader=optiboot" ]]; then
|
||||
|
||||
@@ -22,6 +22,7 @@ mv build/Multiprotocol.ino.bin ./binaries/mm-avr-usbasp-aetr-CC2500-inv-v$MULTI_
|
||||
printf "\e[33;1mBuilding mm-avr-usbasp-aetr-CYRF6936-inv-v$MULTI_VERSION.bin\e[0m\n";
|
||||
opt_disable $ALL_PROTOCOLS;
|
||||
opt_enable $CYRF6936_PROTOCOLS;
|
||||
opt_disable E01X_CYRF6936_INO LOSI_CYRF6936_INO
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/mm-avr-usbasp-aetr-CYRF6936-inv-v$MULTI_VERSION.bin;
|
||||
|
||||
@@ -22,6 +22,7 @@ mv build/Multiprotocol.ino.bin ./binaries/mm-avr-txflash-aetr-CC2500-inv-v$MULTI
|
||||
printf "\e[33;1mBuilding mm-avr-txflash-aetr-CYRF6936-inv-v$MULTI_VERSION.bin\e[0m\n";
|
||||
opt_disable $ALL_PROTOCOLS;
|
||||
opt_enable $CYRF6936_PROTOCOLS;
|
||||
opt_disable E01X_CYRF6936_INO LOSI_CYRF6936_INO
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/mm-avr-txflash-aetr-CYRF6936-inv-v$MULTI_VERSION.bin;
|
||||
|
||||
15
buildroot/bin/build_release_extras
Normal file
@@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
source ./buildroot/bin/buildFunctions;
|
||||
exitcode=0;
|
||||
|
||||
printf "\e[33;1mPackaging ancilliary files for v$MULTI_VERSION\e[0m\n";
|
||||
cp Multiprotocol/Multi.txt ./binaries/Multi.txt;
|
||||
|
||||
mkdir -p SCRIPTS/TOOLS;
|
||||
cp -r Lua_scripts/* SCRIPTS/TOOLS/;
|
||||
find SCRIPTS/TOOLS -type f -name "*.md" -delete
|
||||
|
||||
zip -q -r ./binaries/MultiLuaScripts.zip SCRIPTS/TOOLS/*;
|
||||
|
||||
exit $exitcode;
|
||||
@@ -16,11 +16,4 @@ buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/mm-orangerx-aetr-blue-inv-v$MULTI_VERSION.bin;
|
||||
|
||||
printf "\e[33;1mPackaging ancilliary files for v$MULTI_VERSION\e[0m\n";
|
||||
cp Multiprotocol/Multi.txt ./binaries/Multi.txt;
|
||||
mkdir -p SCRIPTS/TOOLS;
|
||||
cp Lua_scripts/*.lua SCRIPTS/TOOLS/;
|
||||
cp Lua_scripts/*.txt SCRIPTS/TOOLS/;
|
||||
zip -q ./binaries/MultiLuaScripts.zip SCRIPTS/TOOLS/*;
|
||||
|
||||
exit $exitcode;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
source ./buildroot/bin/buildFunctions;
|
||||
exitcode=0;
|
||||
|
||||
# CC2500-only 64Kb builds
|
||||
# CC2500-only 64Kb FCC builds
|
||||
printf "\e[33;1mBuilding mm-stm-cc2500-64-aetr-v$MULTI_VERSION.bin\e[0m\n";
|
||||
opt_enable $ALL_PROTOCOLS;
|
||||
opt_disable IKEAANSLUTA_CC2500_INO;
|
||||
@@ -28,4 +28,24 @@ buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-cc2500-64-reta-v$MULTI_VERSION.bin;
|
||||
|
||||
# CC2500-only 64Kb LBT/EU builds
|
||||
printf "\e[33;1mBuilding mm-stm-cc2500-64-aetr-lbt-v$MULTI_VERSION.bin\e[0m\n";
|
||||
opt_replace RETA AETR;
|
||||
opt_add MULTI_EU;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-cc2500-64-aetr-lbt-v$MULTI_VERSION.bin;
|
||||
|
||||
printf "\e[33;1mBuilding mm-stm-cc2500-64-taer-lbt-v$MULTI_VERSION.bin\e[0m\n";
|
||||
opt_replace AETR TAER;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-cc2500-64-taer-lbt-v$MULTI_VERSION.bin;
|
||||
|
||||
printf "\e[33;1mBuilding mm-stm-cc2500-64-reta-lbt-v$MULTI_VERSION.bin\e[0m\n";
|
||||
opt_replace TAER RETA;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-cc2500-64-reta-lbt-v$MULTI_VERSION.bin;
|
||||
|
||||
exit $exitcode;
|
||||
|
||||
@@ -3,11 +3,7 @@
|
||||
source ./buildroot/bin/buildFunctions;
|
||||
exitcode=0;
|
||||
|
||||
# Builds for the DIY 5-in-1 module exceed the 120KB working capacity of the STM32F103CB
|
||||
# To work around this we have to disable some protocols in the builds for this module
|
||||
#DIY_5IN1_DISABLED="MOULDKG_NRF24L01_INO";
|
||||
|
||||
# Generic 4-in-1 builds
|
||||
# Generic 4-in-1 FCC builds
|
||||
printf "\e[33;1mBuilding mm-stm-serial-aetr-v$MULTI_VERSION.bin\e[0m\n";
|
||||
opt_disable ENABLE_PPM;
|
||||
buildMulti;
|
||||
@@ -26,10 +22,30 @@ buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-serial-reta-v$MULTI_VERSION.bin;
|
||||
|
||||
# Generic 4-in-1 LBT/EU builds
|
||||
printf "\e[33;1mBuilding mm-stm-serial-aetr-lbt-v$MULTI_VERSION.bin\e[0m\n";
|
||||
opt_replace RETA AETR;
|
||||
opt_add MULTI_EU;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-serial-aetr-lbt-v$MULTI_VERSION.bin;
|
||||
|
||||
printf "\e[33;1mBuilding mm-stm-serial-taer-lbt-v$MULTI_VERSION.bin\e[0m\n";
|
||||
opt_replace AETR TAER;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-serial-taer-lbt-v$MULTI_VERSION.bin;
|
||||
|
||||
printf "\e[33;1mBuilding mm-stm-serial-reta-lbt-v$MULTI_VERSION.bin\e[0m\n";
|
||||
opt_replace TAER RETA;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-serial-reta-lbt-v$MULTI_VERSION.bin;
|
||||
|
||||
# DIY 5-in-1 builds
|
||||
printf "\e[33;1mBuilding mm-stm-5in1-aetr-v$MULTI_VERSION.bin\e[0m\n";
|
||||
opt_remove MULTI_EU;
|
||||
opt_replace RETA AETR;
|
||||
#opt_disable $DIY_5IN1_DISABLED;
|
||||
opt_enable SX1276_INSTALLED;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
@@ -52,7 +68,6 @@ printf "\e[33;1mBuilding mm-tlite5in1-aetr-v$MULTI_VERSION.bin\e[0m\n";
|
||||
opt_replace RETA AETR;
|
||||
opt_disable INVERT_TELEMETRY;
|
||||
opt_disable SX1276_INSTALLED;
|
||||
#opt_enable $DIY_5IN1_DISABLED;
|
||||
opt_enable "MULTI_5IN1_INTERNAL JP_TLite"
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
@@ -70,7 +85,7 @@ buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/mm-tlite5in1-reta-v$MULTI_VERSION.bin;
|
||||
|
||||
# CC2500-only builds
|
||||
# CC2500-only FCC builds
|
||||
printf "\e[33;1mBuilding mm-stm-cc2500-aetr-v$MULTI_VERSION.bin\e[0m\n";
|
||||
opt_replace RETA AETR;
|
||||
opt_disable "MULTI_5IN1_INTERNAL JP_TLite"
|
||||
@@ -94,11 +109,32 @@ buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-cc2500-reta-v$MULTI_VERSION.bin;
|
||||
|
||||
# CC2500-only LBT/EU builds
|
||||
printf "\e[33;1mBuilding mm-stm-cc2500-aetr-lbt-v$MULTI_VERSION.bin\e[0m\n";
|
||||
opt_replace RETA AETR;
|
||||
opt_add MULTI_EU;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-cc2500-aetr-lbt-v$MULTI_VERSION.bin;
|
||||
|
||||
printf "\e[33;1mBuilding mm-stm-cc2500-taer-lbt-v$MULTI_VERSION.bin\e[0m\n";
|
||||
opt_replace AETR TAER;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-cc2500-taer-lbt-v$MULTI_VERSION.bin;
|
||||
|
||||
printf "\e[33;1mBuilding mm-stm-cc2500-reta-lbt-v$MULTI_VERSION.bin\e[0m\n";
|
||||
opt_replace TAER RETA;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-cc2500-reta-lbt-v$MULTI_VERSION.bin;
|
||||
|
||||
# 4-in-1 PPM builds
|
||||
printf "\e[33;1mBuilding mm-stm-ppm-aetr-v$MULTI_VERSION.bin\e[0m\n";
|
||||
opt_enable A7105_INSTALLED;
|
||||
opt_enable CYRF6936_INSTALLED;
|
||||
opt_enable NRF24L01_INSTALLED;
|
||||
opt_remove MULTI_EU;
|
||||
opt_enable ENABLE_PPM;
|
||||
opt_disable ENABLE_SERIAL;
|
||||
opt_replace RETA AETR;
|
||||
|
||||
5
buildroot/bin/opt_remove
Normal file
@@ -0,0 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
SED=$(which gsed || which sed)
|
||||
|
||||
eval "${SED} -i '/#define \b${1}/d' Multiprotocol/_Config.h"
|
||||