mirror of
https://github.com/pascallanger/DIY-Multiprotocol-TX-Module.git
synced 2025-12-15 12:23:16 +00:00
Compare commits
24 Commits
v1.3.3.14
...
fcc4d19430
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fcc4d19430 | ||
|
|
c80f705fa2 | ||
|
|
c95db35b41 | ||
|
|
35f3548992 | ||
|
|
58f6716035 | ||
|
|
2b15de0f90 | ||
|
|
be91409df9 | ||
|
|
4d8e440965 | ||
|
|
2d469d074e | ||
|
|
96405d27b5 | ||
|
|
75c9fb40a7 | ||
|
|
cd1c15a45a | ||
|
|
2bd50f4c8c | ||
|
|
4c2ddcbe48 | ||
|
|
d7f9ef6967 | ||
|
|
bfc8c2f9fd | ||
|
|
ce6243d6e3 | ||
|
|
80f9ff4163 | ||
|
|
d9f8a3989a | ||
|
|
416f7d5c19 | ||
|
|
eb24dd5549 | ||
|
|
ba19592973 | ||
|
|
98d8d7fb5f | ||
|
|
ad0947b0b7 |
37
.github/workflows/main.yml
vendored
37
.github/workflows/main.yml
vendored
@@ -40,14 +40,14 @@ jobs:
|
||||
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"
|
||||
"multi4in1-devel:avr:multiatmega328p:bootloader=none",
|
||||
"multi4in1-devel:avr:multiatmega328p:bootloader=optiboot",
|
||||
"multi4in1-devel:avr:multixmega32d4",
|
||||
"multi4in1-devel:STM32F1:multi5in1t18int",
|
||||
"multi4in1-devel:STM32F1:multistm32f103cb:debug_option=none",
|
||||
"multi4in1-devel:STM32F1:multistm32f103cb:debug_option=native",
|
||||
"multi4in1-devel:STM32F1:multistm32f103cb:debug_option=ftdi",
|
||||
"multi4in1-devel:STM32F1:multistm32f103c8:debug_option=none"
|
||||
]
|
||||
|
||||
# Set the environment variables
|
||||
@@ -67,15 +67,22 @@ jobs:
|
||||
echo "Event action: ${{ github.event.action }}"
|
||||
echo "Tag name: ${{ github.event.release.tag_name }}"
|
||||
|
||||
arduino-cli config init --additional-urls https://raw.githubusercontent.com/pascallanger/DIY-Multiprotocol-TX-Module-Boards/master/package_multi_4in1_board_index.json
|
||||
arduino-cli config init --additional-urls https://raw.githubusercontent.com/pascallanger/DIY-Multiprotocol-TX-Module-Boards/master/package_multi_4in1_board_index.json,https://raw.githubusercontent.com/pascallanger/DIY-Multiprotocol-TX-Module-Boards/devel/source/package_multi_4in1_board_devel_index.json
|
||||
arduino-cli core update-index
|
||||
|
||||
if [[ "$BOARD" =~ "multi4in1:avr:" ]]; then
|
||||
if [[ "$BOARD" =~ ":avr:" ]]; then
|
||||
arduino-cli core install arduino:avr;
|
||||
fi
|
||||
|
||||
if [[ "$BOARD" =~ "multi4in1-devel:avr" ]]; then
|
||||
arduino-cli core install multi4in1-devel:avr
|
||||
elif [[ "$BOARD" =~ "multi4in1:avr" ]]; then
|
||||
arduino-cli core install multi4in1:avr
|
||||
fi
|
||||
|
||||
if [[ "$BOARD" =~ "multi4in1:STM32F1:" ]]; then
|
||||
if [[ "$BOARD" =~ "multi4in1-devel:STM32F1:" ]]; then
|
||||
arduino-cli core install multi4in1-devel:STM32F1
|
||||
elif [[ "$BOARD" =~ "multi4in1:STM32F1:" ]]; then
|
||||
arduino-cli core install multi4in1:STM32F1
|
||||
fi
|
||||
|
||||
@@ -109,18 +116,18 @@ jobs:
|
||||
echo "ALL_RFMODULES=$(echo $ALL_RFMODULES)" >> $GITHUB_ENV
|
||||
|
||||
# Disable CHECK_FOR_BOOTLOADER when not needed
|
||||
if [[ "$BOARD" == "multi4in1:avr:multiatmega328p:bootloader=none" ]]; then
|
||||
if [[ "$BOARD" =~ ":avr:multiatmega328p:bootloader=none" ]]; then
|
||||
opt_disable CHECK_FOR_BOOTLOADER;
|
||||
fi
|
||||
|
||||
# Trim the build down for the Atmega328p board
|
||||
if [[ "$BOARD" =~ "multi4in1:avr:multiatmega328p:" ]]; then
|
||||
if [[ "$BOARD" =~ ":avr:multiatmega328p:" ]]; then
|
||||
opt_disable $ALL_PROTOCOLS
|
||||
opt_enable FRSKYX_CC2500_INO AFHDS2A_A7105_INO MJXQ_NRF24L01_INO DSM_CYRF6936_INO;
|
||||
fi
|
||||
|
||||
# Trim the enabled protocols down for the STM32F103CB board with debugging or the STM32F103C8 board in general
|
||||
if [[ "$BOARD" == "multi4in1:STM32F1:multistm32f103cb:debug_option=ftdi" ]] || [[ "$BOARD" == "multi4in1:STM32F1:multistm32f103cb:debug_option=native" ]] || [[ "$BOARD" =~ "multi4in1:STM32F1:multistm32f103c8" ]]; then
|
||||
if [[ "$BOARD" =~ ":STM32F1:multistm32f103cb:debug_option=ftdi" ]] || [[ "$BOARD" =~ ":STM32F1:multistm32f103cb:debug_option=native" ]] || [[ "$BOARD" =~ ":STM32F1:multistm32f103c8" ]]; then
|
||||
opt_disable $ALL_PROTOCOLS;
|
||||
opt_enable FRSKYX_CC2500_INO AFHDS2A_A7105_INO MJXQ_NRF24L01_INO DSM_CYRF6936_INO;
|
||||
fi
|
||||
@@ -133,7 +140,7 @@ jobs:
|
||||
- name: Build default configuration
|
||||
run: |
|
||||
# Skip the default build for boards where it's too large now
|
||||
if [[ "$BOARD" == "multi4in1:STM32F1:multistm32f103cb:debug_option=none" ]] || [[ "$BOARD" == "multi4in1:STM32F1:multi5in1t18int" ]]; then
|
||||
if [[ "$BOARD" =~ ":STM32F1:multistm32f103cb:debug_option=none" ]] || [[ "$BOARD" =~ ":STM32F1:multi5in1t18int" ]]; then
|
||||
printf "Not testing default build for $BOARD.";
|
||||
else
|
||||
source ./buildroot/bin/buildFunctions;
|
||||
|
||||
@@ -1,768 +0,0 @@
|
||||
local toolName = "TNS|DSM Forward Programming v0.2|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. #
|
||||
---- # #
|
||||
---- #########################################################################
|
||||
|
||||
|
||||
--###############################################################################
|
||||
-- Multi buffer for DSM description
|
||||
-- Multi_Buffer[0..2]=="DSM" -> Lua script is running
|
||||
-- Multi_Buffer[3]==0x70+len -> TX to RX data ready to be sent
|
||||
-- Multi_Buffer[4..9]=6 bytes of TX to RX data
|
||||
-- Multi_Buffer[10..25]=16 bytes of RX to TX data
|
||||
--
|
||||
-- To start operation:
|
||||
-- Write 0x00 at address 3
|
||||
-- Write 0x00 at address 10
|
||||
-- Write "DSM" at address 0..2
|
||||
--###############################################################################
|
||||
|
||||
local RX_VERSION, WAIT_CMD, MENU_TITLE, MENU_LINES, MENU_VALUES, VALUE_CHANGING, VALUE_CHANGING_WAIT, VALUE_CHANGED, EXIT, EXIT_DONE = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
|
||||
local MENU, LIST_MENU_NOCHANGING, LIST_MENU1, LIST_MENU2, VALUE_NOCHANGING = 0x1C, 0x6C, 0x0C, 0x4C, 0x60
|
||||
local Phase = RX_VERSION
|
||||
local Waiting_RX = 0
|
||||
local Text = {}
|
||||
local RxName = {}
|
||||
local Retry=100
|
||||
local Blink = 0
|
||||
local Value_Changed=0
|
||||
|
||||
local Menu = { Cur=nil, Id=nil, Title="", Prev=nil, PrevId=nil, Next=nil, NextId=nil, Back=nil, BackId=nil, CurLine=nil, SelLine=nil, EditLine=nil }
|
||||
local Line = {}
|
||||
local RX = { Name="", Version="" }
|
||||
|
||||
-- used for debug
|
||||
local rxAnswer = ""
|
||||
local debugLine = 0
|
||||
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
local function GetDebugInfo(lineNr) -- used for debug
|
||||
local i
|
||||
|
||||
debugLine = lineNr
|
||||
rxAnswer = "RX:"
|
||||
for i=10, 25 do
|
||||
rxAnswer = rxAnswer.." "..string.format("%02X", multiBuffer(i))
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
local function conv_int16(number)
|
||||
if number >= 0x8000 then
|
||||
return number - 0x10000
|
||||
end
|
||||
return number
|
||||
end
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
local function Get_Text(index)
|
||||
out = Text[index]
|
||||
if out == nil then -- unknown...
|
||||
out = "Unknown_"..string.format("%X",index)
|
||||
end
|
||||
return out
|
||||
end
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
local function Get_RxName(index)
|
||||
out = RxName[index]
|
||||
if out == nil then -- unknown...
|
||||
out = "Unknown_"..string.format("%X",index)
|
||||
end
|
||||
return out
|
||||
end
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
local function DSM_Release()
|
||||
multiBuffer( 0, 0 )
|
||||
Phase = EXIT_DONE
|
||||
end
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
local function DSM_Send(...)
|
||||
local arg = {...}
|
||||
for i = 1 , #arg do
|
||||
multiBuffer( 3+i, arg[i])
|
||||
end
|
||||
multiBuffer( 3, 0x70+#arg)
|
||||
end
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
local function Value_Add(dir)
|
||||
local line=Line[Menu.SelLine]
|
||||
Speed = getRotEncSpeed()
|
||||
if Speed == ROTENC_MIDSPEED then
|
||||
line.Val = line.Val + (5 * dir)
|
||||
elseif Speed == ROTENC_HIGHSPEED then
|
||||
line.Val = line.Val + (15 * dir)
|
||||
else
|
||||
line.Val = line.Val + dir
|
||||
end
|
||||
if line.Val > line.Max then
|
||||
line.Val = line.Max
|
||||
elseif line.Val < line.Min then
|
||||
line.Val = line.Min
|
||||
end
|
||||
if Line[Menu.SelLine].Type ~= LIST_MENU_NOCHANGING then
|
||||
Phase = VALUE_CHANGING
|
||||
Waiting_RX = 0
|
||||
end
|
||||
end
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
local function DSM_Menu(event)
|
||||
local Speed = 0
|
||||
|
||||
if event == EVT_VIRTUAL_EXIT then
|
||||
if Phase == RX_VERSION then
|
||||
DSM_Release()
|
||||
else
|
||||
Phase = EXIT
|
||||
Waiting_RX = 0
|
||||
end
|
||||
elseif event == EVT_VIRTUAL_NEXT then
|
||||
if Menu.EditLine == nil then
|
||||
-- not changing a value
|
||||
if Menu.SelLine ~= nil then
|
||||
if Menu.SelLine < 7 then
|
||||
local num = Menu.SelLine
|
||||
for i = Menu.SelLine + 1, 6, 1 do
|
||||
if Line[i].Type ~= nil and Line[i].Next ~= nil and Line[i].Type ~= VALUE_NOCHANGING then
|
||||
Menu.SelLine=i
|
||||
break
|
||||
end
|
||||
end
|
||||
if num == Menu.SelLine then
|
||||
if Menu.Next ~= 0 then -- Next
|
||||
Menu.SelLine = 7
|
||||
elseif Menu.Prev ~= 0 then -- Prev
|
||||
Menu.SelLine = 8
|
||||
end
|
||||
end
|
||||
elseif Menu.Prev ~= 0 then -- Prev
|
||||
Menu.SelLine = 8
|
||||
end
|
||||
end
|
||||
else -- need to inc the value
|
||||
Value_Add(1)
|
||||
end
|
||||
elseif event == EVT_VIRTUAL_PREV then
|
||||
if Menu.EditLine == nil then
|
||||
if Menu.SelLine ~= nil then
|
||||
if Menu.SelLine == 8 and Menu.Next ~= 0 then
|
||||
Menu.SelLine = 7
|
||||
elseif Menu.SelLine > 0 then
|
||||
if Menu.SelLine > 6 then
|
||||
Menu.SelLine = 7
|
||||
end
|
||||
local num = Menu.SelLine
|
||||
for i = Menu.SelLine-1, 0, -1 do
|
||||
if Line[i].Type ~= nil and Line[i].Next ~= nil and Line[i].Type ~= VALUE_NOCHANGING then
|
||||
Menu.SelLine=i
|
||||
break
|
||||
end
|
||||
end
|
||||
if num == Menu.SelLine then -- Back
|
||||
Menu.SelLine = -1
|
||||
end
|
||||
else
|
||||
Menu.SelLine = -1 -- Back
|
||||
end
|
||||
end
|
||||
else -- need to dec the value
|
||||
Value_Add(-1)
|
||||
end
|
||||
elseif event == EVT_VIRTUAL_ENTER_LONG then
|
||||
if Menu.EditLine ~= nil then
|
||||
-- reset the value to default
|
||||
if Line[Menu.SelLine].Type ~= LIST_MENU_NOCHANGING then
|
||||
Line[Menu.SelLine].Val = Line[Menu.SelLine].Def
|
||||
Phase = VALUE_CHANGING
|
||||
Waiting_RX = 0
|
||||
end
|
||||
end
|
||||
elseif event == EVT_VIRTUAL_ENTER then
|
||||
if Menu.SelLine == -1 then -- Back
|
||||
Menu.Cur = Menu.Back
|
||||
Menu.Id = Menu.BackId
|
||||
Menu.SelLine = 0
|
||||
Phase = MENU_TITLE
|
||||
Waiting_RX = 0
|
||||
elseif Menu.SelLine == 7 then -- Next
|
||||
Menu.Cur = Menu.Next
|
||||
Menu.Id = Menu.NextId
|
||||
Menu.SelLine = 0
|
||||
Phase = MENU_TITLE
|
||||
Waiting_RX = 0
|
||||
elseif Menu.SelLine == 8 then -- Prev
|
||||
Menu.Cur = Menu.Prev
|
||||
Menu.Id = Menu.PrevId
|
||||
Menu.SelLine = 0
|
||||
Phase = MENU_TITLE
|
||||
Waiting_RX = 0
|
||||
elseif Menu.SelLine ~= nil and Line[Menu.SelLine].Next ~= nil then
|
||||
if Line[Menu.SelLine].Type == MENU then -- Next menu exist
|
||||
Menu.Cur = Line[Menu.SelLine].Next
|
||||
Menu.Id = Line[Menu.SelLine].NextId
|
||||
Phase = MENU_TITLE
|
||||
Waiting_RX = 0
|
||||
else
|
||||
-- value entry
|
||||
if Menu.EditLine == Menu.SelLine then
|
||||
Menu.EditLine = nil
|
||||
Value_Changed = 0
|
||||
Phase = VALUE_CHANGED
|
||||
Waiting_RX = 0
|
||||
else
|
||||
Menu.EditLine = Menu.SelLine
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
local function DSM_Send_Receive()
|
||||
if Waiting_RX == 0 then
|
||||
Waiting_RX = 1
|
||||
|
||||
-- Need to send a request
|
||||
if Phase == RX_VERSION then -- request RX version
|
||||
DSM_Send(0x11,0x06,0x00,0x14,0x00,0x00)
|
||||
|
||||
elseif Phase == WAIT_CMD then -- keep connection open
|
||||
DSM_Send(0x00,0x04,0x00,0x00)
|
||||
|
||||
elseif Phase == MENU_TITLE then -- request menu title
|
||||
if Menu.Cur == nil then
|
||||
DSM_Send(0x12,0x06,0x00,0x14,0x00,0x00) -- first menu only
|
||||
Menu.Cur = 0
|
||||
else
|
||||
DSM_Send(0x16,0x06,Menu.Id,Menu.Cur,0x00,Menu.SelLine)
|
||||
end
|
||||
|
||||
elseif Phase == MENU_LINES then -- request menu lines
|
||||
if Menu.CurLine == nil then
|
||||
DSM_Send(0x13,0x04,Menu.Id,Menu.Cur) -- line 0
|
||||
elseif Menu.CurLine >= 0x80 then
|
||||
local last_byte={0x40,0x01,0x02,0x04,0x00,0x00} -- unknown...
|
||||
DSM_Send(0x20,0x06,Menu.CurLine-0x80,Menu.CurLine-0x80,0x00,last_byte[Menu.CurLine-0x80+1]) -- line X
|
||||
else
|
||||
DSM_Send(0x14,0x06,Menu.Id,Menu.Cur,0x00,Menu.CurLine) -- line X
|
||||
end
|
||||
|
||||
elseif Phase == MENU_VALUES then -- request menu values
|
||||
DSM_Send(0x15,0x06,Menu.Id,Menu.Cur,Line[Menu.CurLine].ValId,Line[Menu.CurLine].Next) -- line X
|
||||
|
||||
elseif Phase == VALUE_CHANGING then -- send value
|
||||
local value=Line[Menu.SelLine].Val
|
||||
if value < 0 then
|
||||
value = 0x10000 + value
|
||||
end
|
||||
DSM_Send(0x18,0x06,Line[Menu.SelLine].ValId,Line[Menu.SelLine].Next,bit32.rshift(value,8),bit32.band(value,0xFF)) -- send current value
|
||||
Phase = VALUE_CHANGING_WAIT
|
||||
|
||||
elseif Phase == VALUE_CHANGED then -- send value
|
||||
if Value_Changed == 0 then
|
||||
local value=Line[Menu.SelLine].Val
|
||||
if value < 0 then
|
||||
value = 0x10000 + value
|
||||
end
|
||||
DSM_Send(0x18,0x06,Line[Menu.SelLine].ValId,Line[Menu.SelLine].Next,bit32.rshift(value,8),bit32.band(value,0xFF)) -- send current value
|
||||
Value_Changed = Value_Changed + 1
|
||||
Waiting_RX = 0
|
||||
elseif Value_Changed == 1 then
|
||||
DSM_Send(0x19,0x06,Line[Menu.SelLine].ValId,Line[Menu.SelLine].Next) -- validate
|
||||
-- Value_Changed = Value_Changed + 1
|
||||
-- Waiting_RX = 0
|
||||
--elseif Value_Changed == 2 then
|
||||
-- DSM_Send(0x1B,0x06,0x10,Menu.SelLine) -- validate again?
|
||||
-- Value_Changed = Value_Changed + 1
|
||||
end
|
||||
|
||||
elseif Phase == VALUE_CHANGING_WAIT then
|
||||
DSM_Send(0x1A,0x06,Line[Menu.SelLine].ValId,Line[Menu.SelLine].Next)
|
||||
|
||||
elseif Phase == EXIT then
|
||||
DSM_Send(0x1F,0x02,0xAA)
|
||||
|
||||
end
|
||||
multiBuffer(10,0x00);
|
||||
Retry = 50
|
||||
-- -- -- -- -- -- -- -- -- -- -- -- receive part -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||
elseif multiBuffer(10) == 0x09 then
|
||||
-- Answer received
|
||||
-- GetDebugInfo(292) -- used for debug
|
||||
|
||||
--if multiBuffer(11) == 0x00 then -- waiting for commands?
|
||||
|
||||
if multiBuffer(11) == 0x01 then -- read version
|
||||
--ex: 0x09 0x01 0x00 0x15 0x02 0x22 0x01 0x00 0x14 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
RX.Name = Get_RxName(multiBuffer(13))
|
||||
RX.Version = multiBuffer(14).."."..multiBuffer(15).."."..multiBuffer(16)
|
||||
Phase = MENU_TITLE
|
||||
|
||||
elseif multiBuffer(11) == 0x02 then -- read menu title
|
||||
--ex: 0x09 0x02 0x4F 0x10 0xA5 0x00 0x00 0x00 0x50 0x10 0x10 0x10 0x00 0x00 0x00 0x00
|
||||
Menu.Cur = multiBuffer(12)
|
||||
Menu.Id = multiBuffer(13)
|
||||
Menu.Title = Get_Text(multiBuffer(14)+multiBuffer(15)*256)
|
||||
Menu.Prev = multiBuffer(16)
|
||||
Menu.PrevId = multiBuffer(17)
|
||||
Menu.Next = multiBuffer(18)
|
||||
Menu.NextId = multiBuffer(19)
|
||||
Menu.Back = multiBuffer(20)
|
||||
Menu.BackId = multiBuffer(21)
|
||||
for i = 0, 6 do -- clear menu
|
||||
Line[i] = { Menu = nil, Id = nil, Type = nil, Text="", Next = nil, NextId = nil, ValLine = nil, ValId = nil, Min, Max, Def, Val, Unit, Step }
|
||||
end
|
||||
Menu.CurLine = nil
|
||||
if Menu.Next ~= 0 then
|
||||
Menu.SelLine = 7 -- highlight Next
|
||||
else
|
||||
Menu.SelLine = -1 -- highlight Back
|
||||
end
|
||||
Blink = 0
|
||||
Phase = MENU_LINES
|
||||
|
||||
elseif multiBuffer(11) == 0x03 then -- read menu lines
|
||||
--ex: 0x09 0x03 0x00 0x10 0x00 0x1C 0xF9 0x00 0x10 0x10 0x00 0x00 0x00 0x00 0x03 0x00
|
||||
-- Menu Id line Type Text_idx Next V_Id Val_Min Val_Max Val_Def
|
||||
--ex: 0x09 0x03 0x61 0x10 0x00 0x6C 0x50 0x00 0x00 0x10 0x36 0x00 0x49 0x00 0x36 0x00
|
||||
Menu.CurLine = multiBuffer(14)
|
||||
local line = Line[Menu.CurLine]
|
||||
line.Menu = multiBuffer(12)
|
||||
line.Id = multiBuffer(13) -- not quite sure yet
|
||||
line.Type = multiBuffer(15) -- not quite sure yet: 1C is text menu only, 4C/6C is text followed by text list, C0 is text followed by percentage value, 0C new list type
|
||||
line.Text = Get_Text(multiBuffer(16)+multiBuffer(17)*256)
|
||||
--if multiBuffer(18) == Menu.Cur then
|
||||
-- line.Next = nil
|
||||
--else
|
||||
line.Next = multiBuffer(18) -- not quite sure yet: 1C=text menu=>next menu, others=>identifier of line number of the value
|
||||
--end
|
||||
if Menu.SelLine == -1 and line.Next ~= nil then -- Auto select first line of the menu
|
||||
Menu.SelLine = Menu.CurLine
|
||||
end
|
||||
line.NextId = multiBuffer(19) -- not quite sure yet
|
||||
line.ValLine = multiBuffer(18) -- not quite sure yet
|
||||
line.ValId = multiBuffer(19) -- not quite sure yet
|
||||
line.Min = conv_int16(multiBuffer(20)+multiBuffer(21)*256)
|
||||
line.Max = conv_int16(multiBuffer(22)+multiBuffer(23)*256)
|
||||
line.Def = conv_int16(multiBuffer(24)+multiBuffer(25)*256)
|
||||
if line.Type == MENU then
|
||||
-- nothing to do on menu entries
|
||||
elseif line.Type == LIST_MENU_NOCHANGING or line.Type == LIST_MENU1 or line.Type == LIST_MENU2 then
|
||||
line.Val = nil --line.Def - line.Min -- use default value not sure if needed
|
||||
line.Def = line.Min -- pointer to the start of the list in Text
|
||||
line.Max = line.Max - line.Min -- max index
|
||||
line.Min = 0 -- min index
|
||||
else -- default to numerical value
|
||||
line.Val = nil --line.Def -- use default value not sure if needed
|
||||
end
|
||||
if line.Type ~= MENU and line.Type ~= VALUE_NOCHANGING then -- updatable value to follow
|
||||
line.Text = line.Text..":"
|
||||
end
|
||||
Phase = MENU_LINES
|
||||
|
||||
elseif multiBuffer(11) == 0x04 then -- read menu values
|
||||
--ex: 0x09 0x04 0x53 0x10 0x00 0x10 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
-- Menu MeId line VaId Value
|
||||
--ex: 0x09 0x04 0x61 0x10 0x02 0x10 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
-- Identify the line and update the value
|
||||
for i = 0, 6 do
|
||||
if Line[i] ~= nil and Line[i].Type ~= nil then
|
||||
if Line[i].Type ~= MENU and Line[i].Next == multiBuffer(14) then -- identifier of line number stored in .Next
|
||||
Line[i].Val = conv_int16(multiBuffer(16)+multiBuffer(17)*256)
|
||||
Menu.CurLine = i
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
Phase = MENU_VALUES
|
||||
|
||||
elseif multiBuffer(11) == 0x05 then -- unknown... need to get through the lines...
|
||||
Menu.CurLine = 0x80 + multiBuffer(12)
|
||||
Phase = MENU_LINES
|
||||
|
||||
elseif multiBuffer(11) == 0xA7 then -- answer to EXIT command
|
||||
DSM_Release()
|
||||
|
||||
elseif multiBuffer(11) == 0x00 and Phase == VALUE_CHANGING then
|
||||
Phase = VALUE_CHANGING_WAIT
|
||||
|
||||
end
|
||||
|
||||
-- Data processed
|
||||
Waiting_RX = 0
|
||||
multiBuffer(10,0x00)
|
||||
Retry = 50
|
||||
|
||||
else
|
||||
Retry = Retry - 1
|
||||
if Retry <= 0 then
|
||||
-- Retry the RX request
|
||||
Retry = 50
|
||||
Waiting_RX = 0
|
||||
if Phase == EXIT then
|
||||
DSM_Release()
|
||||
end
|
||||
if Phase ~= RX_VERSION and Phase ~= VALUE_CHANGING_WAIT then
|
||||
Phase = WAIT_CMD
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
local function DSM_Display()
|
||||
lcd.clear()
|
||||
|
||||
if LCD_W == 480 then
|
||||
--lcd.drawText(10,55,debugLine.." "..rxAnswer) -- draw debug info
|
||||
--Draw title
|
||||
lcd.drawFilledRectangle(0, 0, LCD_W, 30, TITLE_BGCOLOR)
|
||||
lcd.drawText(1, 5, "DSM Forward Programming", MENU_TITLE_COLOR)
|
||||
--Draw RX Menu
|
||||
if Phase == RX_VERSION then
|
||||
lcd.drawText(10,50,"No compatible DSM RX...", BLINK)
|
||||
else
|
||||
if Menu.Title ~= nil then
|
||||
local attrib=0;
|
||||
lcd.drawText(80,32,Menu.Title,MIDSIZE)
|
||||
for i = 0, 6 do
|
||||
if i == Menu.SelLine then
|
||||
attrib = INVERS
|
||||
else
|
||||
attrib = 0
|
||||
end
|
||||
if Line[i] ~= nil and Line[i].Type ~= nil then
|
||||
if Line[i].Type ~= MENU then -- list/value
|
||||
if Line[i].Val ~= nil then
|
||||
local text=""
|
||||
if Line[i].Type == LIST_MENU_NOCHANGING or Line[i].Type == LIST_MENU1 or Line[i].Type == LIST_MENU2 then
|
||||
text = Get_Text(Line[i].Val+Line[i].Def)
|
||||
elseif ( Line[i].Min == 0 and Line[i].Max == 100) or ( Line[i].Min == -100 and Line[i].Max == 100) or ( Line[i].Min == 0 and Line[i].Max == 150) or ( Line[i].Min == -150 and Line[i].Max == 150) then
|
||||
text = Line[i].Val.." %"
|
||||
else
|
||||
--text = Line[i].Val .." T="..Line[i].Type -- used for debug
|
||||
text = Line[i].Val
|
||||
end
|
||||
if Menu.EditLine == Menu.SelLine then -- blink edited entry
|
||||
Blink = Blink + 1
|
||||
if Blink > 25 then
|
||||
attrib = 0
|
||||
if Blink > 50 then
|
||||
Blink = 0
|
||||
end
|
||||
end
|
||||
end
|
||||
lcd.drawText(240,32+20*(i+2), text, attrib) -- display value
|
||||
end
|
||||
attrib = 0
|
||||
end
|
||||
lcd.drawText(10,32+20*(i+2), Line[i].Text, attrib) -- display text
|
||||
end
|
||||
end
|
||||
if Menu.SelLine == -1 then
|
||||
lcd.drawText(437,32, "Back", INVERS)
|
||||
else
|
||||
lcd.drawText(437,32, "Back", 0)
|
||||
end
|
||||
lcd.drawRectangle(437-5, 32-2, 47, 25)
|
||||
if Menu.Next ~= 0 then
|
||||
if Menu.SelLine == 7 then
|
||||
lcd.drawText(437,220, "Next",INVERS)
|
||||
else
|
||||
lcd.drawText(437,220, "Next")
|
||||
end
|
||||
lcd.drawRectangle(437-5, 220-2, 47, 25)
|
||||
end
|
||||
if Menu.Prev ~= 0 then
|
||||
if Menu.SelLine == 8 then
|
||||
lcd.drawText(5,220, "Prev",INVERS)
|
||||
else
|
||||
lcd.drawText(5,220, "Prev")
|
||||
end
|
||||
lcd.drawRectangle(5-5, 220-2, 47, 25)
|
||||
end
|
||||
end
|
||||
lcd.drawText(170,252, "RX "..RX.Name.." v"..RX.Version) -- display RX info
|
||||
end
|
||||
else
|
||||
-- --Draw RX Menu on LCD_W=128
|
||||
-- if multiBuffer( 4 ) == 0xFF then
|
||||
-- lcd.drawText(2,17,"No compatible DSM RX...",SMLSIZE)
|
||||
-- else
|
||||
-- if Retry_128 ~= 0 then
|
||||
-- --Intro page
|
||||
-- Retry_128 = Retry_128 - 1
|
||||
-- lcd.drawScreenTitle("DSM Forward Programming",0,0)
|
||||
-- lcd.drawText(2,17,"Press Prev Page for previous Menu" ,SMLSIZE)
|
||||
-- else
|
||||
-- --Menu page
|
||||
-- for line = 0, 7, 1 do
|
||||
-- for i = 0, 21-1, 1 do
|
||||
-- value=multiBuffer( line*21+6+i )
|
||||
-- if value > 0x80 then
|
||||
-- value = value - 0x80
|
||||
-- lcd.drawText(2+i*6,1+8*line,string.char(value).." ",SMLSIZE+INVERS)
|
||||
-- else
|
||||
-- lcd.drawText(2+i*6,1+8*line,string.char(value),SMLSIZE)
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
end
|
||||
end
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
-- Init
|
||||
local function DSM_Init()
|
||||
--Set protocol to talk to
|
||||
multiBuffer( 0, string.byte('D') )
|
||||
--test if value has been written
|
||||
if multiBuffer( 0 ) ~= string.byte('D') then
|
||||
error("Not enough memory!")
|
||||
return 2
|
||||
end
|
||||
--Init TX buffer
|
||||
multiBuffer( 3, 0x00 )
|
||||
--Init RX buffer
|
||||
multiBuffer( 10, 0x00 )
|
||||
--Init telemetry
|
||||
multiBuffer( 0, string.byte('D') )
|
||||
multiBuffer( 1, string.byte('S') )
|
||||
multiBuffer( 2, string.byte('M') )
|
||||
|
||||
--RX names--
|
||||
RxName[0x0001]="AR636B"
|
||||
RxName[0x0014]="SPM4651T"
|
||||
RxName[0x0015]="AR637T"
|
||||
RxName[0x0016]="AR637TA"
|
||||
RxName[0x0018]="FC6250HX"
|
||||
RxName[0x001A]="AR8360T"
|
||||
RxName[0x001E]="AR631"
|
||||
|
||||
--Text to be displayed -> need to use a file instead?
|
||||
Text[0x0001]="On"
|
||||
Text[0x0002]="Off"
|
||||
Text[0x0003]="Inh"
|
||||
Text[0x0004]="Act"
|
||||
Text[0x000C]="Inhibit?" --?
|
||||
Text[0x000D]="Gear"
|
||||
|
||||
--Lists--
|
||||
Text[0x002E]="11ms"
|
||||
Text[0x002F]="22ms"
|
||||
Text[0x0032]="1 X"
|
||||
Text[0x0033]="2 X"
|
||||
Text[0x0034]="4 X"
|
||||
Text[0x0035]="Inhibit?" --?
|
||||
Text[0x0036]="Throttle"
|
||||
Text[0x0037]="Aileron"
|
||||
Text[0x0038]="Elevator"
|
||||
Text[0x0039]="Rudder"
|
||||
Text[0x003A]="Gear"
|
||||
|
||||
--******
|
||||
--This part is strange since the AR637T needs
|
||||
for i=1,7 do -- 3B..41
|
||||
Text[0x003A+i]="Aux"..i
|
||||
end
|
||||
for i=1,8 do -- 41..49
|
||||
Text[0x0041+i]="XPlus-"..i
|
||||
end
|
||||
--But FOTO-PETE reports that it should be:
|
||||
Text[0x0040]="Roll"
|
||||
Text[0x0041]="Pitch"
|
||||
Text[0x0042]="Yaw"
|
||||
Text[0x0043]="Gain" -- FC6250HX
|
||||
Text[0x0045]="Differential"
|
||||
Text[0x0046]="Priority"
|
||||
Text[0x0049]="Output Setup" -- FC6250HX
|
||||
--******
|
||||
|
||||
Text[0x004A]="Failsafe"
|
||||
Text[0x004B]="Main Menu"
|
||||
Text[0x004E]="Position"
|
||||
Text[0x0050]="Outputs"
|
||||
Text[0x0051]="Output Channel 1"
|
||||
Text[0x0052]="Output Channel 2"
|
||||
Text[0x0053]="Output Channel 3"
|
||||
Text[0x0054]="Output Channel 4"
|
||||
Text[0x0055]="Output Channel 5"
|
||||
Text[0x0056]="Output Channel 6"
|
||||
--Text[0x005E]="Inhibit"
|
||||
Text[0x005F]="Hold Last"
|
||||
Text[0x0060]="Preset"
|
||||
--Text[0x0061]="Custom"
|
||||
--Messages--
|
||||
Text[0x0071]="Proportional"
|
||||
Text[0x0072]="Integral"
|
||||
Text[0x0073]="Derivate"
|
||||
Text[0x0078]="FM Channel"
|
||||
Text[0x0080]="Orientation"
|
||||
Text[0x0082]="Heading"
|
||||
Text[0x0085]="Frame Rate"
|
||||
Text[0x0086]="System Setup"
|
||||
Text[0x0087]="F-Mode Setup"
|
||||
Text[0x0088]="Enabled F-Modes"
|
||||
Text[0x0089]="Gain Channel"
|
||||
Text[0x008A]="Gain Sensitivity"
|
||||
Text[0x008B]="Panic"
|
||||
Text[0x0090]="Apply"
|
||||
Text[0x0092]="Start"
|
||||
Text[0x0093]="Complete"
|
||||
Text[0x0094]="Done"
|
||||
Text[0x0097]="Factory Reset"
|
||||
Text[0x0099]="Advanced Setup"
|
||||
Text[0x009A]="Capture Failsafe Positions"
|
||||
Text[0x009C]="Custom Failsafe"
|
||||
Text[0x00A5]="First Time Setup"
|
||||
Text[0x00AA]="Capture Gyro Gains"
|
||||
Text[0x00AD]="Gain Channel Select"
|
||||
Text[0x00B0]="Self-Level/Angle Dem"
|
||||
Text[0x00B1]="Envelope"
|
||||
Text[0x00B5]="Inhibit"
|
||||
Text[0x00B6]="FM1"
|
||||
Text[0x00B7]="FM2"
|
||||
Text[0x00B8]="FM3"
|
||||
Text[0x00B9]="FM4"
|
||||
Text[0x00BA]="FM5"
|
||||
Text[0x00BB]="FM6"
|
||||
Text[0x00BC]="FM7"
|
||||
Text[0x00BD]="FM8"
|
||||
Text[0x00BE]="FM9"
|
||||
Text[0x00BF]="FM10"
|
||||
Text[0x00C7]="Calibrate Sensor"
|
||||
Text[0x00CA]="SAFE/Panic Mode Setup"
|
||||
Text[0x00D3]="Swashplate"
|
||||
Text[0x00D5]="Agility"
|
||||
Text[0x00D8]="Stop"
|
||||
Text[0x00DA]="SAFE"
|
||||
Text[0x00DB]="Stability"
|
||||
Text[0x00DC]="@ per sec"
|
||||
Text[0x00DD]="Tail rotor"
|
||||
Text[0x00DE]="Setup"
|
||||
Text[0x00DF]="AFR"
|
||||
Text[0x00E0]="Collective"
|
||||
Text[0x00E1]="Subtrim"
|
||||
Text[0x00E2]="Phasing"
|
||||
Text[0x00E4]="E-Ring"
|
||||
Text[0x00E7]="Left"
|
||||
Text[0x00E8]="Right"
|
||||
Text[0x00F2]="Fixed"
|
||||
Text[0x00F3]="Adjustable"
|
||||
Text[0x00F9]="Gyro settings"
|
||||
Text[0x00FE]="Stick Priority"
|
||||
Text[0x0100]="Make sure the model has been"
|
||||
Text[0x0101]="configured, including wing type,"
|
||||
Text[0x0102]="reversing, travel, trimmed, etc."
|
||||
Text[0x0103]="before continuing setup."
|
||||
Text[0x0106]="Any wing type, channel assignment,"
|
||||
Text[0x0107]="subtrim, or servo reversing changes"
|
||||
Text[0x0108]="require running through initial"
|
||||
Text[0x0109]="setup again."
|
||||
Text[0x0190]="Relearn Servo Settings"
|
||||
Text[0x019C]="Enter Receiver Bind Mode"
|
||||
Text[0x01D7]="SAFE Select Channel"
|
||||
Text[0x01DC]="AS3X"
|
||||
Text[0x01DD]="AS3X Settings"
|
||||
Text[0x01DE]="AS3X Gains"
|
||||
Text[0x01E0]="Rate Gains"
|
||||
Text[0x01E2]="SAFE Settings"
|
||||
Text[0x01E3]="SAFE Gains"
|
||||
Text[0x01E6]="Attitude Trim"
|
||||
Text[0x01E7]="Envelope"
|
||||
Text[0x01E9]="Roll Right"
|
||||
Text[0x01EA]="Roll Left"
|
||||
Text[0x01EB]="Pitch Down"
|
||||
Text[0x01EC]="Pitch Up"
|
||||
Text[0x01EE]="Throttle to Pitch"
|
||||
Text[0x01EF]="Low Thr to Pitch"
|
||||
Text[0x01F0]="High Thr to Pitch"
|
||||
Text[0x01F3]="Threshold"
|
||||
Text[0x01F4]="Angle"
|
||||
Text[0x01F6]="Failsafe Angles"
|
||||
Text[0x01F8]="Safe Mode"
|
||||
Text[0x01F9]="SAFE Select"
|
||||
Text[0x01FD]="SAFE Failsafe FMode"
|
||||
Text[0x0208]="Decay"
|
||||
Text[0x0209]="Save to Backup"
|
||||
Text[0x020A]="Restore from Backup"
|
||||
Text[0x020D]="First Time SAFE Setup"
|
||||
Text[0x021A]="Set the model level,"
|
||||
Text[0x021B]="and press Continue."
|
||||
Text[0x021C]="" -- empty??
|
||||
Text[0x021D]="" -- empty??
|
||||
Text[0x021F]="Set the model on its nose,"
|
||||
Text[0x0220]="and press Continue. If the"
|
||||
Text[0x0221]="orientation on the next"
|
||||
Text[0x0222]="screen is wrong go back"
|
||||
Text[0x0223]="and try again."
|
||||
Text[0x0224]="Continue"
|
||||
Text[0x0226]="Angle Limits"
|
||||
Text[0x0227]="Other settings"
|
||||
Text[0x0229]="Set Orientation Manually"
|
||||
Text[0x022B]="WARNING!"
|
||||
Text[0x022C]="This will reset the"
|
||||
Text[0x022D]="configuration to factory"
|
||||
Text[0x022E]="defaults. This does not"
|
||||
Text[0x022F]="affect the backup config."
|
||||
Text[0x0230]="" -- empty??
|
||||
Text[0x0231]="This will overwrite the"
|
||||
Text[0x0232]="backup memory with your"
|
||||
Text[0x0233]="current configuartion."
|
||||
Text[0x0234]="" -- blank line
|
||||
Text[0x0235]="" -- blank line
|
||||
Text[0x0236]="This will overwrite the"
|
||||
Text[0x0237]="current config with"
|
||||
Text[0x0238]="that which is in"
|
||||
Text[0x0239]="the backup memory."
|
||||
Text[0x023A]="" -- blank line
|
||||
Text[0x023D]="Copy Flight Mode Settings"
|
||||
Text[0x0240]="Utilities"
|
||||
Text[0x024C]="Gains will be captured on"
|
||||
Text[0x024D]="Captured gains will be"
|
||||
Text[0x024E]="Gains on"
|
||||
Text[0x024F]="were captured and changed"
|
||||
Text[0x0250]="from Adjustable to Fixed"
|
||||
Text[0x0254]="Postive = Up, Negative = Down"
|
||||
Text[0x0263]="Fixed/Adjustable Gains"
|
||||
Text[0x0266]="Heading Gain"
|
||||
Text[0x0267]="Positive = Nose Up/Roll Right"
|
||||
Text[0x0268]="Negative = Nose Down/Roll Left"
|
||||
Text[0x0269]="SAFE - Throttle to Pitch"
|
||||
Text[0x026A]="Use CAUTION for Yaw gain!"
|
||||
Text[0x8000]="FLIGHT MODE"
|
||||
Text[0x8001]="Flight Mode 1"
|
||||
Text[0x8002]="Flight Mode 2"
|
||||
Text[0x8003]="Flight Mode 3"
|
||||
end
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
-- Main
|
||||
local function DSM_Run(event)
|
||||
if event == nil then
|
||||
error("Cannot be run as a model script!")
|
||||
return 2
|
||||
else
|
||||
DSM_Menu(event)
|
||||
DSM_Send_Receive()
|
||||
DSM_Display()
|
||||
end
|
||||
if Phase == EXIT_DONE then
|
||||
return 2
|
||||
else
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
||||
return { init=DSM_Init, run=DSM_Run }
|
||||
439
Lua_scripts/DSM FwdPrg_05_BW.lua
Normal file
439
Lua_scripts/DSM FwdPrg_05_BW.lua
Normal file
@@ -0,0 +1,439 @@
|
||||
local toolName = "TNS|DSM Forward Prog v0.5 (Text B&W) |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 SIMULATION_ON = false -- FALSE: use real communication to DSM RX (DEFAULT), TRUE: use a simulated version of RX
|
||||
local DEBUG_ON = 1 -- 0=NO DEBUG, 1=HIGH LEVEL 2=LOW LEVEL (Debug logged into the /LOGS/dsm.log)
|
||||
local DEBUG_ON_LCD = false -- Interactive Information on LCD of Menu data from RX
|
||||
|
||||
|
||||
local dsmLib
|
||||
if (SIMULATION_ON) then
|
||||
-- library with SIMILATION VERSION. Works really well in Companion for GUI development
|
||||
dsmLib = loadScript("/SCRIPTS/TOOLS/DSMLIB/DsmFwPrgSIMLib.lua")(DEBUG_ON)
|
||||
else
|
||||
dsmLib = loadScript("/SCRIPTS/TOOLS/DSMLIB/DsmFwPrgLib.lua")(DEBUG_ON)
|
||||
end
|
||||
|
||||
local PHASE = dsmLib.PHASE
|
||||
local LINE_TYPE = dsmLib.LINE_TYPE
|
||||
local DISP_ATTR = dsmLib.DISP_ATTR
|
||||
|
||||
local DSM_Context = dsmLib.DSM_Context
|
||||
|
||||
local LCD_W_USABLE = LCD_W-10
|
||||
-- X for Menu Lines
|
||||
local LCD_X_LINE_MENU = 10
|
||||
-- X offsets for (Title: [Value] debugInfo) lines
|
||||
local LCD_X_LINE_TITLE = 10
|
||||
local LCD_X_LINE_VALUE = 230
|
||||
local LCD_X_LINE_DEBUG = 390
|
||||
|
||||
-- Line Height: make it smaller debugging info tp LCD (some space buttom)
|
||||
local LCD_Y_LINE_HEIGHT = (DEBUG_ON_LCD and 23) or 27 -- if DEBUG 23 else 27
|
||||
-- Y offsets
|
||||
local LCD_Y_MENU_TITLE = 20
|
||||
-- Y offet
|
||||
local LCD_Y_LINE_FIRST = LCD_Y_MENU_TITLE + 30
|
||||
local LCD_Y_LOWER_BUTTONS = LCD_Y_LINE_FIRST + 7 * LCD_Y_LINE_HEIGHT
|
||||
|
||||
local LCD_W_BUTTONS = 47
|
||||
local LCD_H_BUTTONS = 25
|
||||
local LCD_X_RIGHT_BUTTONS = LCD_W - LCD_W_BUTTONS - 5
|
||||
|
||||
local TEXT_SIZE = 0 -- NORMAL
|
||||
|
||||
local lastRefresh=0 -- Last time the screen was refreshed
|
||||
local REFRESH_GUI_MS = 500/10 -- 500ms.. Screen Refresh Rate.. to not use unneded CPU time (in 10ms units to be compatible with getTime())
|
||||
local originalValue = nil
|
||||
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
local function GUI_SwitchSimulationOFF()
|
||||
dsmLib.ReleaseConnection()
|
||||
dsmLib.LOG_close()
|
||||
|
||||
SIMULATION_ON = false
|
||||
dsmLib = loadScript("/SCRIPTS/TOOLS/DSMLIB/DsmFwPrgLib.lua")(DEBUG_ON)
|
||||
DSM_Context = dsmLib.DSM_Context
|
||||
|
||||
dsmLib.Init(toolName) -- Initialize Library
|
||||
dsmLib.StartConnection()
|
||||
DSM_Context.Refresh_Display = true
|
||||
end
|
||||
|
||||
local function openTx_lcd_sizeText(s)
|
||||
return string.len(s)*5
|
||||
end
|
||||
|
||||
local function GUI_Diplay_Button(x,y,w,h,text,selected)
|
||||
local attr = (selected) and INVERS or 0 -- INVERS if line Selected
|
||||
lcd.drawText(x+5,y+2, text, attr + TEXT_SIZE)
|
||||
lcd.drawRectangle(x, y, w, h, LINE_COLOR)
|
||||
end
|
||||
|
||||
local function GUI_Display_Menu(menu)
|
||||
local ctx = DSM_Context
|
||||
local w= LCD_W_USABLE - LCD_W_BUTTONS - 10 -- usable Width for the Menu/Lines
|
||||
|
||||
-- Center Header
|
||||
local tw = openTx_lcd_sizeText(menu.Text)
|
||||
local x = w/2 - tw/2 -- Center of Screen - Center of Text
|
||||
|
||||
local bold = 0
|
||||
if (TEXT_SIZE~=SMLSIZE) then -- Ignore Bold on small size screens
|
||||
bold = BOLD
|
||||
end
|
||||
lcd.drawText(x,LCD_Y_MENU_TITLE,menu.Text,bold + TEXT_SIZE)
|
||||
|
||||
-- Back
|
||||
if menu.BackId ~= 0 then
|
||||
GUI_Diplay_Button(LCD_X_RIGHT_BUTTONS,LCD_Y_MENU_TITLE,LCD_W_BUTTONS,LCD_H_BUTTONS,"Back",ctx.SelLine == dsmLib.BACK_BUTTON)
|
||||
end
|
||||
-- Next ?
|
||||
if menu.NextId ~= 0 then
|
||||
GUI_Diplay_Button(LCD_X_RIGHT_BUTTONS,LCD_Y_LOWER_BUTTONS,LCD_W_BUTTONS,LCD_H_BUTTONS,"Next",ctx.SelLine == dsmLib.NEXT_BUTTON)
|
||||
end
|
||||
-- Prev?
|
||||
if menu.PrevId ~= 0 then
|
||||
GUI_Diplay_Button(0,LCD_Y_LOWER_BUTTONS,LCD_W_BUTTONS,LCD_H_BUTTONS,"Prev",ctx.SelLine == dsmLib.PREV_BUTTON)
|
||||
end
|
||||
|
||||
-- Debug into LCD
|
||||
if (DEBUG_ON_LCD) then lcd.drawText(0,LCD_Y_MENU_TITLE,dsmLib.phase2String(ctx.Phase),TEXT_SIZE + WARNING_COLOR) end -- Phase we are in
|
||||
if (DEBUG_ON_LCD) then lcd.drawText(LCD_X_LINE_MENU,240,dsmLib.menu2String(menu),TEXT_SIZE + WARNING_COLOR) end -- Menu Info
|
||||
end
|
||||
|
||||
local function GUI_Display_Line_Menu(x,y,w,h,line,selected)
|
||||
local attr = (selected and INVERS) or 0 -- INVERS if line Selected
|
||||
local bold = 0
|
||||
local text = line.Text
|
||||
|
||||
if dsmLib.isSelectableLine(line) then
|
||||
-- Menu Line
|
||||
text = text .. " |>" --OPENTX
|
||||
else -- SubHeaders and plain text lines
|
||||
if (TEXT_SIZE~=SMLSIZE) then -- ignore bold on small size screens
|
||||
bold = (dsmLib.isDisplayAttr(line.TextAttr,DISP_ATTR.BOLD) and BOLD) or 0
|
||||
end
|
||||
|
||||
if dsmLib.isDisplayAttr(line.TextAttr,DISP_ATTR.RIGHT) then -- Right Align???
|
||||
local tw = openTx_lcd_sizeText(line.Text)+4
|
||||
x = LCD_X_LINE_VALUE - tw -- Right
|
||||
elseif dsmLib.isDisplayAttr(line.TextAttr,DISP_ATTR.CENTER) then -- Center??
|
||||
local tw = openTx_lcd_sizeText(line.Text)
|
||||
x = x + (LCD_X_LINE_VALUE - LCD_X_LINE_MENU)/2 - tw/2 -- Center - 1/2 Text
|
||||
end
|
||||
end
|
||||
|
||||
lcd.drawText(x,y, text, attr + bold + TEXT_SIZE)
|
||||
|
||||
end
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
local function GUI_Display_Line_Value(lineNum, line, value, selected, editing)
|
||||
local bold = 0
|
||||
|
||||
local y = LCD_Y_LINE_FIRST+(LCD_Y_LINE_HEIGHT*lineNum)
|
||||
local x = LCD_X_LINE_TITLE
|
||||
|
||||
---------- NAME Part
|
||||
local header = line.Text
|
||||
-- ONLY do this for Flight Mode (Right Align or Centered)
|
||||
if (dsmLib.isFlightModeText(line.TextId)) then
|
||||
-- Display Header + Value together
|
||||
header = header .. " " .. value
|
||||
|
||||
-- Flight mode display attributes
|
||||
if (TEXT_SIZE~=SMLSIZE) then -- ignore bold on small size screens
|
||||
bold = (dsmLib.isDisplayAttr(line.TextAttr,DISP_ATTR.BOLD) and BOLD) or 0
|
||||
end
|
||||
|
||||
if dsmLib.isDisplayAttr(line.TextAttr,DISP_ATTR.RIGHT) then -- Right Align
|
||||
local tw = openTx_lcd_sizeText(header)+4
|
||||
x = LCD_X_LINE_VALUE - tw -- Right
|
||||
elseif dsmLib.isDisplayAttr(line.TextAttr,DISP_ATTR.CENTER) then -- Centered
|
||||
local tw = openTx_lcd_sizeText(header)
|
||||
x = x + (LCD_X_LINE_VALUE - LCD_X_LINE_TITLE)/2 - tw/2 -- Center - 1/2 Text
|
||||
end
|
||||
else
|
||||
-- No Flight Mode, no effects here
|
||||
header = header .. ":"
|
||||
end
|
||||
|
||||
lcd.drawText(x, y, header, bold + TEXT_SIZE) -- display Line Header
|
||||
|
||||
--------- VALUE PART, Skip for Flight Mode since already show the value
|
||||
if not dsmLib.isFlightModeText(line.TextId) then
|
||||
local attrib = 0
|
||||
value = value .. (line.Format or "") -- Append % if needed
|
||||
|
||||
if selected then
|
||||
attrib = INVERS
|
||||
if editing then -- blink editing entry
|
||||
attrib = attrib + BLINK
|
||||
value = "[ " .. value .. " ]"
|
||||
end
|
||||
end
|
||||
|
||||
lcd.drawText(LCD_X_LINE_VALUE,y, value, attrib + TEXT_SIZE) -- display value
|
||||
end
|
||||
|
||||
if (DEBUG_ON_LCD) then lcd.drawText(LCD_X_LINE_DEBUG,y, line.MinMaxDebug or "", TEXT_SIZE + WARNING_COLOR) end -- display debug
|
||||
end
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
local function GUI_Display()
|
||||
local ctx = DSM_Context
|
||||
lcd.clear()
|
||||
|
||||
local header = "DSM Fwrd Programming "
|
||||
if ctx.Phase ~= PHASE.RX_VERSION then
|
||||
header = header .. "RX "..ctx.RX.Name.." v"..ctx.RX.Version
|
||||
end
|
||||
|
||||
--Draw title
|
||||
if (TEXT_SIZE~=SMLSIZE) then -- ignore tool title small size screens
|
||||
lcd.drawFilledRectangle(0, 0, LCD_W, 20, TITLE_BGCOLOR)
|
||||
lcd.drawText(5, 0, header, MENU_TITLE_COLOR + TEXT_SIZE)
|
||||
end
|
||||
--Draw RX Menu
|
||||
if ctx.Phase == PHASE.RX_VERSION then
|
||||
lcd.drawText(LCD_X_LINE_TITLE,50,"No compatible DSM RX...", BLINK + TEXT_SIZE)
|
||||
else
|
||||
local menu = ctx.Menu
|
||||
if menu.Text ~= nil then
|
||||
|
||||
GUI_Display_Menu(menu)
|
||||
|
||||
for i = 0, dsmLib.MAX_MENU_LINES do
|
||||
local line = ctx.MenuLines[i]
|
||||
|
||||
if i == ctx.SelLine then
|
||||
-- DEBUG: Display Selected Line info for ON SCREEN Debugging
|
||||
if (DEBUG_ON_LCD) then lcd.drawText(LCD_X_LINE_TITLE,255,dsmLib.menuLine2String(line),TEXT_SIZE + WARNING_COLOR) end
|
||||
end
|
||||
|
||||
if line ~= nil and line.Type ~= 0 then
|
||||
if line.Type == LINE_TYPE.MENU then
|
||||
-- Menu Line
|
||||
GUI_Display_Line_Menu(LCD_X_LINE_MENU,LCD_Y_LINE_FIRST+(LCD_Y_LINE_HEIGHT*i), 350, LCD_Y_LINE_HEIGHT, line, i == ctx.SelLine)
|
||||
else
|
||||
-- list/value line
|
||||
local value = line.Val
|
||||
if line.Val ~= nil then
|
||||
if dsmLib.isListLine(line) then -- for Lists of Strings, get the text
|
||||
value = dsmLib.Get_Text(line.Val + line.TextStart) -- TextStart is the initial offset for text
|
||||
local imgValue = dsmLib.Get_Text_Img(line.Val + line.TextStart) -- Complentary IMAGE for this value to Display??
|
||||
|
||||
if (imgValue) then -- Optional Image for a Value
|
||||
--TODO: Pending feature.. create images and put bitmap instead of a message
|
||||
--Display the image/Alternate Text
|
||||
lcd.drawText(LCD_X_LINE_TITLE, LCD_Y_LINE_FIRST+LCD_Y_LINE_HEIGHT, "Img:"..imgValue)
|
||||
end
|
||||
end
|
||||
|
||||
GUI_Display_Line_Value(i, line, value, i == ctx.SelLine, i == ctx.EditLine)
|
||||
end
|
||||
end -- if ~MENU
|
||||
end -- if Line[i]~=nil
|
||||
end -- for
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function GUI_RotEncVal(dir) -- return encoder speed to inc or dec values
|
||||
local inc = 0
|
||||
local Speed = getRotEncSpeed()
|
||||
|
||||
if Speed == ROTENC_MIDSPEED then
|
||||
inc = (5 * dir)
|
||||
elseif Speed == ROTENC_HIGHSPEED then
|
||||
inc = (15 * dir)
|
||||
else
|
||||
inc = dir
|
||||
end
|
||||
|
||||
return inc
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
local function GUI_HandleEvent(event, touchState)
|
||||
local ctx = DSM_Context
|
||||
local menu = ctx.Menu
|
||||
local menuLines = ctx.MenuLines
|
||||
|
||||
if event == EVT_VIRTUAL_EXIT then
|
||||
ctx.Refresh_Display=true
|
||||
if (DEBUG_ON) then dsmLib.LOG_write("%s: EVT_VIRTUAL_EXIT\n",dsmLib.phase2String(ctx.Phase)) end
|
||||
if ctx.Phase == PHASE.RX_VERSION then
|
||||
dsmLib.ReleaseConnection()
|
||||
else
|
||||
if ctx.isEditing() then -- Editing a Line, need to restore original value
|
||||
ctx.MenuLines[ctx.EditLine].Val = originalValue
|
||||
dsmLib.ChangePhase(PHASE.VALUE_CHANGE_END) -- Update+Validate value in RX
|
||||
ctx.EditLine = nil -- Exit Edit Mode (By clearing the line editing)
|
||||
else
|
||||
dsmLib.ChangePhase(PHASE.EXIT)
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if event == EVT_VIRTUAL_NEXT then
|
||||
ctx.Refresh_Display=true
|
||||
if (DEBUG_ON) then dsmLib.LOG_write("%s: EVT_VIRTUAL_NEXT\n",dsmLib.phase2String(ctx.Phase)) end
|
||||
if ctx.isEditing() then -- Editing a Line, need to inc the value
|
||||
local line=ctx.MenuLines[ctx.EditLine]
|
||||
dsmLib.Value_Add(line, GUI_RotEncVal(1))
|
||||
else -- not editing, move selected line to NEXT
|
||||
dsmLib.MoveSelectionLine(1)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if event == EVT_VIRTUAL_PREV then
|
||||
ctx.Refresh_Display=true
|
||||
if (DEBUG_ON) then dsmLib.LOG_write("%s: EVT_VIRTUAL_PREV\n",dsmLib.phase2String(ctx.Phase)) end
|
||||
if ctx.isEditing() then -- Editiing a line, need to dec the value
|
||||
local line=ctx.MenuLines[ctx.EditLine]
|
||||
dsmLib.Value_Add(line, GUI_RotEncVal(-1))
|
||||
else -- not editing, move selected line to PREV
|
||||
dsmLib.MoveSelectionLine(-1)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if event == EVT_VIRTUAL_ENTER_LONG then
|
||||
ctx.Refresh_Display=true
|
||||
if (DEBUG_ON) then dsmLib.LOG_write("%s: EVT_VIRTUAL_ENTER_LONG\n",dsmLib.phase2String(ctx.Phase)) end
|
||||
if ctx.isEditing() then
|
||||
-- reset the value to default
|
||||
dsmLib.Value_Default( menuLines[ctx.EditLine]) -- Update RX value as needed
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if event == EVT_VIRTUAL_ENTER then
|
||||
ctx.Refresh_Display=true
|
||||
if (DEBUG_ON) then dsmLib.LOG_write("%s: EVT_VIRTUAL_ENTER\n",dsmLib.phase2String(ctx.Phase)) end
|
||||
if ctx.SelLine == dsmLib.BACK_BUTTON then -- Back
|
||||
dsmLib.GotoMenu(menu.BackId)
|
||||
elseif ctx.SelLine == dsmLib.NEXT_BUTTON then -- Next
|
||||
dsmLib.GotoMenu(menu.NextId)
|
||||
elseif ctx.SelLine == dsmLib.PREV_BUTTON then -- Prev
|
||||
dsmLib.GotoMenu(menu.PrevId)
|
||||
elseif menuLines[ctx.SelLine].ValId ~= 0 then
|
||||
if menuLines[ctx.SelLine].Type == LINE_TYPE.MENU then -- Next menu exist
|
||||
if (SIMULATION_ON and menuLines[ctx.SelLine].ValId==0xFFFF) then
|
||||
-- SPECIAL Simulation menu to Exit Simulation and
|
||||
-- comunicate with Real RX
|
||||
GUI_SwitchSimulationOFF()
|
||||
else
|
||||
dsmLib.GotoMenu(menuLines[ctx.SelLine].ValId) -- ValId is the MenuId to navigate to
|
||||
end
|
||||
else
|
||||
-- Editing a Line????
|
||||
if ctx.isEditing() then
|
||||
-- Change the Value and exit edit
|
||||
ctx.EditLine = nil
|
||||
dsmLib.ChangePhase(PHASE.VALUE_CHANGE_END)
|
||||
else
|
||||
-- enter Edit the current line
|
||||
ctx.EditLine = ctx.SelLine
|
||||
originalValue = menuLines[ctx.SelLine].Val
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function init_screen_pos()
|
||||
if LCD_W == 480 then -- TX16
|
||||
-- use defaults in the script header
|
||||
elseif LCD_W == 128 then --TX12 (128x64) -- Still needs some work on the vertical
|
||||
DEBUG_ON_LCD = false -- no space for this
|
||||
TEXT_SIZE = SMLSIZE
|
||||
LCD_W_USABLE = 128
|
||||
|
||||
LCD_W_BUTTONS = 30
|
||||
LCD_H_BUTTONS = 17
|
||||
LCD_X_RIGHT_BUTTONS = 128 - LCD_W_BUTTONS - 5
|
||||
|
||||
LCD_X_LINE_MENU = 0
|
||||
-- X offsets for (Title: [Value] debugInfo) lines
|
||||
LCD_X_LINE_TITLE = 0
|
||||
LCD_X_LINE_VALUE = 90
|
||||
LCD_X_LINE_DEBUG = 110
|
||||
|
||||
LCD_Y_LINE_HEIGHT = 17
|
||||
LCD_Y_MENU_TITLE = 0
|
||||
LCD_Y_LINE_FIRST = LCD_Y_MENU_TITLE + 17
|
||||
LCD_Y_LOWER_BUTTONS = LCD_Y_LINE_FIRST + 7 * LCD_Y_LINE_HEIGHT
|
||||
end
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
-- Init
|
||||
local function DSM_Init()
|
||||
init_screen_pos()
|
||||
dsmLib.Init(toolName) -- Initialize Library
|
||||
return dsmLib.StartConnection()
|
||||
end
|
||||
|
||||
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
-- Main
|
||||
|
||||
|
||||
local function DSM_Run(event)
|
||||
local ctx = DSM_Context
|
||||
|
||||
if event == nil then
|
||||
error("Cannot be run as a model script!")
|
||||
dsmLib.LOG_close()
|
||||
return 2
|
||||
end
|
||||
|
||||
GUI_HandleEvent(event)
|
||||
|
||||
dsmLib.Send_Receive() -- Handle Send and Receive DSM Forward Programming Messages
|
||||
|
||||
local refreshInterval = REFRESH_GUI_MS
|
||||
-- When using LCD BLINK attribute, we need faster refresh for BLINK to SHOW on LCD
|
||||
if (ctx.EditLine or (ctx.Phase == PHASE.RX_VERSION)) then -- Editing or Requesting RX Version?
|
||||
ctx.Refresh_Display=true
|
||||
refreshInterval = 20 -- 200ms
|
||||
end
|
||||
|
||||
-- Refresh display only if needed and no faster than 500ms, utilize more CPU to speedup DSM communications
|
||||
if (ctx.Refresh_Display and (getTime()-lastRefresh) > refreshInterval) then --300ms from last refresh
|
||||
GUI_Display()
|
||||
ctx.Refresh_Display=false
|
||||
lastRefresh=getTime()
|
||||
end
|
||||
|
||||
if ctx.Phase == PHASE.EXIT_DONE then
|
||||
dsmLib.LOG_close()
|
||||
return 2
|
||||
else
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
return { init=DSM_Init, run=DSM_Run }
|
||||
627
Lua_scripts/DSM FwdPrg_05_Color.lua
Normal file
627
Lua_scripts/DSM FwdPrg_05_Color.lua
Normal file
@@ -0,0 +1,627 @@
|
||||
local toolName = "TNS|DSM Forward Prog v0.5 (Color+Touch) |TNE"
|
||||
local VERSION = "v0.5"
|
||||
|
||||
---- #########################################################################
|
||||
---- # #
|
||||
---- # 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 SIMULATION_ON = false -- FALSE: use real communication to DSM RX (DEFAULT), TRUE: use a simulated version of RX
|
||||
local DEBUG_ON = 1 -- 0=NO DEBUG, 1=HIGH LEVEL 2=LOW LEVEL (Debug logged into the /LOGS/dsm.log)
|
||||
local DEBUG_ON_LCD = false -- Interactive Information on LCD of Menu data from RX
|
||||
local USE_SPECKTRUM_COLORS = true -- true: Use spectrum colors, false: use theme colors (default on OpenTX)
|
||||
|
||||
local dsmLib
|
||||
if (SIMULATION_ON) then
|
||||
-- library with SIMILATION VERSION. Works really well in Companion for GUI development
|
||||
dsmLib = loadScript("/SCRIPTS/TOOLS/DSMLIB/DsmFwPrgSIMLib.lua")(DEBUG_ON)
|
||||
else
|
||||
dsmLib = loadScript("/SCRIPTS/TOOLS/DSMLIB/DsmFwPrgLib.lua")(DEBUG_ON)
|
||||
end
|
||||
|
||||
local PHASE = dsmLib.PHASE
|
||||
local LINE_TYPE = dsmLib.LINE_TYPE
|
||||
local DISP_ATTR = dsmLib.DISP_ATTR
|
||||
local DSM_Context = dsmLib.DSM_Context
|
||||
|
||||
|
||||
local lastRefresh=0 -- Last time the screen was refreshed
|
||||
local REFRESH_GUI_MS = 300/10 -- 300ms.. Screen Refresh Rate.. to not waste CPU time (in 10ms units to be compatible with getTime())
|
||||
local originalValue = nil
|
||||
|
||||
local touchButtonArea = {}
|
||||
local EDIT_BUTTON = { DEFAULT=1001, DEC_10=1002, DEC_1=1003, INC_1=1004, INC_10=5, OK=1006, ESC=1007 }
|
||||
|
||||
local IS_EDGETX = false -- DEFAULT until Init changed it
|
||||
|
||||
local LCD_Y_MENU_TITLE = 20
|
||||
local LCD_W_MENU_TITLE = LCD_W-100
|
||||
|
||||
local LCD_X_LINE_MENU = 30
|
||||
local LCD_W_LINE_MENU = 350
|
||||
|
||||
local LCD_X_LINE_TITLE = 30
|
||||
local LCD_X_LINE_VALUE = 230
|
||||
local LCD_X_LINE_DEBUG = 390
|
||||
|
||||
|
||||
local LCD_Y_LINE_START = LCD_Y_MENU_TITLE + 30
|
||||
local LCD_Y_LINE_HEIGHT = (DEBUG_ON_LCD and 23) or 27 -- if DEBUG 23 else 27
|
||||
|
||||
local LCD_Y_LOWER_BUTTONS = LCD_Y_LINE_START + 3 + (7 * LCD_Y_LINE_HEIGHT)
|
||||
|
||||
|
||||
-- TOOL HEADER
|
||||
local LCD_TOOL_HDR_COLOR = MENU_TITLE_COLOR
|
||||
local LCD_TOOL_HDR_BGCOLOR = TITLE_BGCOLOR
|
||||
-- MENU HEADER
|
||||
local LCD_MENU_COLOR = MENU_TITLE_COLOR
|
||||
local LCD_MENU_BGCOLOR = MENU_TITLE_BGCOLOR
|
||||
-- LINE SELECTED
|
||||
local LCD_SELECTED_COLOR = TEXT_INVERTED_COLOR
|
||||
local LCD_SELECTED_BGCOLOR = TEXT_INVERTED_BGCOLOR
|
||||
local LCD_EDIT_BGCOLOR = WARNING_COLOR
|
||||
-- NORMAL TEXT
|
||||
local LCD_NORMAL_COLOR = TEXT_COLOR
|
||||
local LCD_DISABLE_COLOR = TEXT_DISABLE_COLOR
|
||||
local LCD_DEBUG_COLOR = LINE_COLOR
|
||||
-- NORMAL BOX FRAME COLOR
|
||||
local LCD_BOX_COLOR = TEXT_DISABLE_COLOR
|
||||
|
||||
|
||||
|
||||
--------------------- lcd.sizeText replacement -------------------------------------------------
|
||||
-- EdgeTx dont have lcd.sizeText, so we do an equivalent one using the string length and 5px per character
|
||||
local function my_lcd_sizeText(s)
|
||||
print(string.format("EdgeTX=%s",IS_EDGETX))
|
||||
-- return: If IS_EDGETX then lcd.sizeText() else string.len()
|
||||
return (IS_EDGETX and lcd.sizeText(s)) or (string.len(s)*10)
|
||||
end
|
||||
|
||||
|
||||
local function GUI_SwitchSimulationOFF()
|
||||
dsmLib.ReleaseConnection()
|
||||
dsmLib.LOG_close()
|
||||
|
||||
SIMULATION_ON = false
|
||||
dsmLib = loadScript("/SCRIPTS/TOOLS/DSMLIB/DsmFwPrgLib.lua")(DEBUG_ON)
|
||||
DSM_Context = dsmLib.DSM_Context
|
||||
|
||||
dsmLib.Init(toolName) -- Initialize Library
|
||||
dsmLib.StartConnection()
|
||||
DSM_Context.Refresh_Display = true
|
||||
end
|
||||
|
||||
|
||||
--------------------- Toucch Button Helpers ------------------------------------------------------------
|
||||
local function GUI_addTouchButton(x,y,w,h,line)
|
||||
-- Add new button info to end of the array
|
||||
touchButtonArea[#touchButtonArea+1] = {x=x, y=y, w=w, h=h, line=line}
|
||||
end
|
||||
|
||||
local function GUI_getTouchButton(x,y)
|
||||
for i = 1, #touchButtonArea do
|
||||
local button = touchButtonArea[i]
|
||||
-- is the coordinate inside the button area??
|
||||
if (x >= button.x and x <= (button.x+button.w) and y >= button.y and (y <= button.y+button.h)) then
|
||||
return button.line
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
local function GUI_clearTouchButtons()
|
||||
touchButtonArea = {}
|
||||
end
|
||||
|
||||
---------- Return Color to display Menu Lines ----------------------------------------------------------------
|
||||
local function GUI_GetTextColor(lineNum)
|
||||
local ctx = DSM_Context
|
||||
local txtColor = LCD_NORMAL_COLOR
|
||||
-- Gray Out any other line except the one been edited
|
||||
if (ctx.isEditing() and ctx.EditLine~=lineNum) then txtColor=LCD_DISABLE_COLOR end
|
||||
return txtColor
|
||||
end
|
||||
|
||||
local function GUI_GetFrameColor(lineNum) -- Frame Color for Value/Menu Boxes
|
||||
local ctx = DSM_Context
|
||||
local txtColor = LCD_BOX_COLOR
|
||||
-- Gray Out any other line except the one been edited
|
||||
if (ctx.EditLine~=lineNum) then txtColor=LCD_DISABLE_COLOR end
|
||||
return txtColor
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------------------------------
|
||||
-- Display Text inside a Rectangle. Inv: true means solid rectangle, false=only perimeter
|
||||
local function GUI_Display_Boxed_Text(lineNum,x,y,w,h,text,inv)
|
||||
local ctx = DSM_Context
|
||||
local txtColor = GUI_GetTextColor(lineNum)
|
||||
local frameColor = GUI_GetFrameColor(lineNum)
|
||||
-- If editing this lineNum, chose EDIT Color, else SELECTED Color
|
||||
local selectedBGColor = (ctx.EditLine==lineNum and LCD_EDIT_BGCOLOR) or LCD_SELECTED_BGCOLOR
|
||||
|
||||
if (inv) then
|
||||
txtColor = LCD_SELECTED_COLOR
|
||||
lcd.drawFilledRectangle(x-5, y-2, w, h, selectedBGColor)
|
||||
else
|
||||
lcd.drawRectangle(x-5, y-2, w, h, frameColor)
|
||||
end
|
||||
lcd.drawText(x , y, text, txtColor)
|
||||
|
||||
end
|
||||
|
||||
------ Display Pre/Next/Back buttons
|
||||
local function GUI_Diplay_Button(x,y,w,h,text,selected)
|
||||
GUI_Display_Boxed_Text(-1,x,y,w,h,text,selected)
|
||||
end
|
||||
|
||||
------ Display MENU type of lines (Navigation, SubHeaders, and plain text comments)
|
||||
local function GUI_Display_Line_Menu(lineNum,line,selected)
|
||||
-- Menu Lines can be navidation to other Menus (if Selectable)
|
||||
-- Or SubHeaders or Messages
|
||||
|
||||
local txtColor = GUI_GetTextColor(lineNum)
|
||||
local y = LCD_Y_LINE_START+(LCD_Y_LINE_HEIGHT*lineNum)
|
||||
local x = LCD_X_LINE_MENU
|
||||
|
||||
if dsmLib.isSelectableLine(line) then -- Draw Selectable Menus in Boxes
|
||||
GUI_Display_Boxed_Text(lineNum,x, y, LCD_W_LINE_MENU, LCD_Y_LINE_HEIGHT, line.Text,selected)
|
||||
GUI_addTouchButton(x, y, LCD_W_LINE_MENU, LCD_Y_LINE_HEIGHT,lineNum)
|
||||
else
|
||||
-- Non Selectable Menu Lines, plain text
|
||||
-- Can be use for sub headers or just regular text lines (like warnings)
|
||||
|
||||
local bold = (dsmLib.isDisplayAttr(line.TextAttr,DISP_ATTR.BOLD) and BOLD) or 0
|
||||
|
||||
if dsmLib.isDisplayAttr(line.TextAttr,DISP_ATTR.RIGHT) then -- Right Align???
|
||||
local tw = my_lcd_sizeText(line.Text)+4
|
||||
x = LCD_X_LINE_VALUE - tw -- Right
|
||||
elseif dsmLib.isDisplayAttr(line.TextAttr,DISP_ATTR.CENTER) then -- Center??
|
||||
local tw = my_lcd_sizeText(line.Text)
|
||||
x = x + (LCD_X_LINE_VALUE - LCD_X_LINE_MENU)/2 - tw/2 -- Center - 1/2 Text
|
||||
end
|
||||
|
||||
lcd.drawText(x, y, line.Text, txtColor + bold)
|
||||
end
|
||||
end
|
||||
|
||||
------ Display NAME : VALUES type of lines
|
||||
local function GUI_Display_Line_Value(lineNum, line, value, selected, editing)
|
||||
-- This Displays Name and Value Pairs
|
||||
local txtColor = GUI_GetTextColor(lineNum)
|
||||
local bold = 0
|
||||
local y = LCD_Y_LINE_START+(LCD_Y_LINE_HEIGHT*lineNum)
|
||||
local x = LCD_X_LINE_TITLE
|
||||
|
||||
--if (editing) then -- Any Special color/effect when editing??
|
||||
-- value = "["..value .. "]"
|
||||
--end
|
||||
|
||||
---------- NAME Part
|
||||
local header = line.Text
|
||||
-- ONLY do this for Flight Mode (Right Align or Centered)
|
||||
if (dsmLib.isFlightModeText(line.TextId)) then
|
||||
-- Display Header + Value together
|
||||
header = header .. " " .. value
|
||||
|
||||
-- Bold Text???
|
||||
bold = (dsmLib.isDisplayAttr(line.TextAttr,DISP_ATTR.BOLD) and BOLD) or 0
|
||||
|
||||
if dsmLib.isDisplayAttr(line.TextAttr,DISP_ATTR.RIGHT) then -- Right Align
|
||||
local tw = my_lcd_sizeText(header)+4
|
||||
x = LCD_X_LINE_VALUE - tw -- Right
|
||||
elseif dsmLib.isDisplayAttr(line.TextAttr,DISP_ATTR.CENTER) then -- Centered
|
||||
local tw = my_lcd_sizeText(header)
|
||||
x = x + (LCD_X_LINE_VALUE - LCD_X_LINE_TITLE)/2 - tw/2 -- Center - 1/2 Text
|
||||
end
|
||||
else
|
||||
-- No Flight Mode, no effects here
|
||||
header = header .. ":"
|
||||
end
|
||||
|
||||
lcd.drawText(x, y, header, txtColor + bold) -- display Line Header
|
||||
|
||||
--------- VALUE PART, Skip for Flight Mode since already show the value
|
||||
if not dsmLib.isFlightModeText(line.TextId) then
|
||||
value = value .. (line.Format or "") -- Append % if needed
|
||||
|
||||
if dsmLib.isSelectableLine(line) then
|
||||
-- Can select/edit value, Box it
|
||||
local tw = my_lcd_sizeText(value)+10 -- Width of the Text in the lcd
|
||||
GUI_Display_Boxed_Text(lineNum,LCD_X_LINE_VALUE,y,tw,LCD_Y_LINE_HEIGHT,value,selected)
|
||||
GUI_addTouchButton(LCD_X_LINE_VALUE,y,tw,LCD_Y_LINE_HEIGHT,lineNum)
|
||||
else -- Not Editable, Plain Text
|
||||
lcd.drawText(LCD_X_LINE_VALUE, y, value, txtColor)
|
||||
end
|
||||
end
|
||||
|
||||
-- Debug info for line Value RANGE when Debug on LCD
|
||||
if (DEBUG_ON_LCD) then lcd.drawText(LCD_X_LINE_DEBUG, y, line.MinMaxDebug or "", SMLSIZE + LCD_DEBUG_COLOR) end -- display debug Min/Max
|
||||
end
|
||||
|
||||
local function GUI_Display_Menu(menu)
|
||||
local ctx = DSM_Context
|
||||
local w= LCD_W_MENU_TITLE
|
||||
|
||||
-- Center Header
|
||||
local tw = my_lcd_sizeText(menu.Text)
|
||||
local x = w/2 - tw/2 -- Center of Screen - Center of Text
|
||||
|
||||
lcd.drawFilledRectangle(0, LCD_Y_MENU_TITLE-2, w, LCD_Y_LINE_HEIGHT-2, LCD_MENU_BGCOLOR)
|
||||
lcd.drawText(x,LCD_Y_MENU_TITLE,menu.Text, LCD_MENU_COLOR + BOLD)
|
||||
|
||||
-- Back Button
|
||||
if menu.BackId ~= 0 then
|
||||
GUI_Diplay_Button(437-5,LCD_Y_MENU_TITLE+3,47,LCD_Y_LINE_HEIGHT,"Back",ctx.SelLine == dsmLib.BACK_BUTTON)
|
||||
GUI_addTouchButton(437-5,LCD_Y_MENU_TITLE+3,47,LCD_Y_LINE_HEIGHT,dsmLib.BACK_BUTTON)
|
||||
end
|
||||
-- Next Button
|
||||
if menu.NextId ~= 0 then
|
||||
GUI_Diplay_Button(437-5,LCD_Y_LOWER_BUTTONS,47,LCD_Y_LINE_HEIGHT,"Next",ctx.SelLine == dsmLib.NEXT_BUTTON)
|
||||
GUI_addTouchButton(437-5,LCD_Y_LOWER_BUTTONS,47,LCD_Y_LINE_HEIGHT,dsmLib.NEXT_BUTTON)
|
||||
end
|
||||
-- Prev Button
|
||||
if menu.PrevId ~= 0 then
|
||||
GUI_Diplay_Button(10,LCD_Y_LOWER_BUTTONS,47,LCD_Y_LINE_HEIGHT,"Prev",ctx.SelLine == dsmLib.PREV_BUTTON)
|
||||
GUI_addTouchButton(10,LCD_Y_LOWER_BUTTONS,47,LCD_Y_LINE_HEIGHT,dsmLib.PREV_BUTTON)
|
||||
end
|
||||
|
||||
-- Debug on LCD, Show the menu Indo and Phase we are on
|
||||
if (DEBUG_ON_LCD) then lcd.drawText(0,LCD_Y_MENU_TITLE,dsmLib.phase2String(ctx.Phase),SMLSIZE+LCD_DEBUG_COLOR) end -- Phase we are in
|
||||
if (DEBUG_ON_LCD) then lcd.drawText(0,240,dsmLib.menu2String(menu),SMLSIZE+LCD_DEBUG_COLOR) end -- Menu Info
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
-- Display the EDIT mode buttons when editing a value
|
||||
|
||||
local function GUI_Display_Edit_Buttons(line)
|
||||
GUI_clearTouchButtons() -- Only this buttons can be touched
|
||||
local x = 15 -- Inittial X position
|
||||
local w = 55 -- Width of the buttons
|
||||
|
||||
local showPrev = line.Val > line.Min
|
||||
local showNext = line.Val < line.Max
|
||||
|
||||
GUI_Diplay_Button(x,LCD_Y_LOWER_BUTTONS,w,LCD_Y_LINE_HEIGHT,"ESC",true)
|
||||
GUI_addTouchButton(x,LCD_Y_LOWER_BUTTONS,w,LCD_Y_LINE_HEIGHT,EDIT_BUTTON.ESC)
|
||||
|
||||
x=x+w+10
|
||||
GUI_Diplay_Button(x,LCD_Y_LOWER_BUTTONS,w,LCD_Y_LINE_HEIGHT," Def",true)
|
||||
GUI_addTouchButton(x,LCD_Y_LOWER_BUTTONS,w,LCD_Y_LINE_HEIGHT,EDIT_BUTTON.DEFAULT)
|
||||
|
||||
x=x+w+10
|
||||
if (not dsmLib.isListLine(line)) then
|
||||
GUI_Diplay_Button(x,LCD_Y_LOWER_BUTTONS,w,LCD_Y_LINE_HEIGHT," << ",showPrev)
|
||||
GUI_addTouchButton(x,LCD_Y_LOWER_BUTTONS,w,LCD_Y_LINE_HEIGHT,EDIT_BUTTON.DEC_10)
|
||||
end
|
||||
|
||||
x=x+w+10
|
||||
GUI_Diplay_Button(x,LCD_Y_LOWER_BUTTONS,w,LCD_Y_LINE_HEIGHT," <",showPrev)
|
||||
GUI_addTouchButton(x,LCD_Y_LOWER_BUTTONS,w,LCD_Y_LINE_HEIGHT,EDIT_BUTTON.DEC_1)
|
||||
|
||||
x=x+w+10
|
||||
GUI_Diplay_Button(x,LCD_Y_LOWER_BUTTONS,w,LCD_Y_LINE_HEIGHT," >",showNext)
|
||||
GUI_addTouchButton(x,LCD_Y_LOWER_BUTTONS,w,LCD_Y_LINE_HEIGHT,EDIT_BUTTON.INC_1)
|
||||
|
||||
x=x+w+10
|
||||
if (not dsmLib.isListLine(line)) then
|
||||
GUI_Diplay_Button(x,LCD_Y_LOWER_BUTTONS,w,LCD_Y_LINE_HEIGHT," >>",showNext)
|
||||
GUI_addTouchButton(x,LCD_Y_LOWER_BUTTONS,w,LCD_Y_LINE_HEIGHT,EDIT_BUTTON.INC_10)
|
||||
end
|
||||
|
||||
x=x+w+10
|
||||
GUI_Diplay_Button(x,LCD_Y_LOWER_BUTTONS,w,LCD_Y_LINE_HEIGHT," OK",true)
|
||||
GUI_addTouchButton(x,LCD_Y_LOWER_BUTTONS,w,LCD_Y_LINE_HEIGHT,EDIT_BUTTON.OK)
|
||||
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
local function GUI_Display()
|
||||
local ctx = DSM_Context
|
||||
lcd.clear()
|
||||
GUI_clearTouchButtons()
|
||||
|
||||
if LCD_W == 480 then
|
||||
local header = "DSM Forward Programming "..VERSION.." "
|
||||
if ctx.Phase ~= PHASE.RX_VERSION then
|
||||
header = header .. "RX "..ctx.RX.Name.." v"..ctx.RX.Version
|
||||
end
|
||||
|
||||
--Draw title
|
||||
lcd.drawFilledRectangle(0, 0, LCD_W, 17, LCD_TOOL_HDR_BGCOLOR)
|
||||
lcd.drawText(5, 0, header, LCD_TOOL_HDR_COLOR + SMLSIZE)
|
||||
--Draw RX Menu
|
||||
if ctx.Phase == PHASE.RX_VERSION then
|
||||
lcd.drawText(LCD_X_LINE_TITLE,100,"No compatible DSM RX...", BLINK)
|
||||
else
|
||||
local menu = ctx.Menu
|
||||
|
||||
|
||||
if menu.Text ~= nil then
|
||||
GUI_Display_Menu(menu)
|
||||
|
||||
for i = 0, dsmLib.MAX_MENU_LINES do
|
||||
local line = ctx.MenuLines[i]
|
||||
|
||||
if i == ctx.SelLine then
|
||||
-- DEBUG: Display Selected Line info for ON SCREEN Debugging
|
||||
if (DEBUG_ON_LCD) then lcd.drawText(0,255,dsmLib.menuLine2String(line),SMLSIZE + LCD_DEBUG_COLOR) end
|
||||
end
|
||||
|
||||
if line ~= nil and line.Type ~= 0 then
|
||||
if line.Type == LINE_TYPE.MENU then
|
||||
GUI_Display_Line_Menu(i, line, i == ctx.SelLine)
|
||||
else
|
||||
-- list/value line
|
||||
local value, imgValue = line.Val, nil
|
||||
|
||||
if line.Val ~= nil then
|
||||
if dsmLib.isListLine(line) then -- for Lists of Strings, get the text
|
||||
value = dsmLib.Get_Text(line.Val + line.TextStart) -- TextStart is the initial offset for text
|
||||
imgValue = dsmLib.Get_Text_Img(line.Val + line.TextStart) -- Complentary IMAGE for this value to Display??
|
||||
|
||||
if (imgValue) then -- Optional Image for a Value
|
||||
--TODO: Pending feature.. create images and put bitmap instead of a message
|
||||
--Display the image/Alternate Text
|
||||
lcd.drawText(LCD_X_LINE_TITLE, LCD_Y_LINE_START+LCD_Y_LINE_HEIGHT, "Img:"..imgValue)
|
||||
end
|
||||
end
|
||||
|
||||
GUI_Display_Line_Value(i, line, value, i == ctx.SelLine, i == ctx.EditLine)
|
||||
end
|
||||
end -- if ~MENU
|
||||
end -- if Line[i]~=nil
|
||||
end -- for
|
||||
|
||||
if IS_EDGETX and ctx.isEditing() then
|
||||
GUI_Display_Edit_Buttons(ctx.MenuLines[ctx.EditLine])
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
-- Different Resolution.. Maybe just adjusting some of the constants will work, adjust it in DSM_Init??
|
||||
-- LCD_X_LINE_TITLE, LCD_Y_LINE_START, etc
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
local function GUI_RotEncVal(dir) -- return encoder speed to inc or dec values
|
||||
local inc = 0
|
||||
local Speed = getRotEncSpeed()
|
||||
|
||||
if Speed == ROTENC_MIDSPEED then inc = (5 * dir)
|
||||
elseif Speed == ROTENC_HIGHSPEED then inc = (15 * dir)
|
||||
else inc = dir end
|
||||
|
||||
return inc
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------------
|
||||
-- Translate Tap/Touch of EDIT buttons to equivalent Key events
|
||||
local function GUI_Translate_Edit_Buttons(button)
|
||||
local event = EVT_TOUCH_TAP
|
||||
local editInc = nil
|
||||
|
||||
if (button==EDIT_BUTTON.ESC) then -- ESC
|
||||
event = EVT_VIRTUAL_EXIT
|
||||
elseif (button==EDIT_BUTTON.DEFAULT) then -- Default
|
||||
event = EVT_VIRTUAL_ENTER_LONG
|
||||
elseif (button==EDIT_BUTTON.DEC_10) then -- -10
|
||||
event = EVT_VIRTUAL_PREV
|
||||
editInc = -10
|
||||
elseif (button==EDIT_BUTTON.DEC_1) then -- -1
|
||||
event = EVT_VIRTUAL_PREV
|
||||
editInc = -1
|
||||
elseif (button==EDIT_BUTTON.INC_1) then -- +1
|
||||
event = EVT_VIRTUAL_NEXT
|
||||
editInc = 1
|
||||
elseif (button==EDIT_BUTTON.INC_10) then -- + 10
|
||||
event = EVT_VIRTUAL_NEXT
|
||||
editInc = 10
|
||||
elseif (button==EDIT_BUTTON.OK) then -- OK
|
||||
event = EVT_VIRTUAL_ENTER
|
||||
else
|
||||
|
||||
end
|
||||
|
||||
return event, editInc
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
-- Handle Events comming from the GUI
|
||||
local function GUI_HandleEvent(event, touchState)
|
||||
local ctx = DSM_Context
|
||||
local menu = ctx.Menu
|
||||
local menuLines = ctx.MenuLines
|
||||
local editInc = nil
|
||||
|
||||
if (IS_EDGETX) then
|
||||
if (event == EVT_TOUCH_TAP and ctx.isEditing()) then -- Touch and Editing
|
||||
local button = GUI_getTouchButton(touchState.x, touchState.y)
|
||||
if (button) then
|
||||
event, editInc = GUI_Translate_Edit_Buttons(button)
|
||||
end
|
||||
end
|
||||
|
||||
if (event == EVT_TOUCH_TAP or event == EVT_TOUCH_FIRST) and not ctx.isEditing() then -- Touch and NOT editing
|
||||
if (DEBUG_ON) then dsmLib.LOG_write("%s: EVT_TOUCH_TAP %d,%d\n",dsmLib.phase2String(ctx.Phase),touchState.x, touchState.y) end
|
||||
local button = GUI_getTouchButton(touchState.x, touchState.y)
|
||||
if button then
|
||||
-- Found a valid line
|
||||
ctx.SelLine = button
|
||||
ctx.Refresh_Display=true
|
||||
if event == EVT_TOUCH_TAP then -- EVT_TOUCH_FIRST only move focus
|
||||
event = EVT_VIRTUAL_ENTER
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if event == EVT_VIRTUAL_EXIT then
|
||||
ctx.Refresh_Display=true
|
||||
if (DEBUG_ON) then dsmLib.LOG_write("%s: EVT_VIRTUAL_EXIT\n",dsmLib.phase2String(ctx.Phase)) end
|
||||
if ctx.Phase == PHASE.RX_VERSION then
|
||||
dsmLib.ReleaseConnection() -- Just Exit the Script
|
||||
else
|
||||
if ctx.isEditing() then -- Editing a Line, need to restore original value
|
||||
ctx.MenuLines[ctx.EditLine].Val = originalValue
|
||||
dsmLib.ChangePhase(PHASE.VALUE_CHANGE_END) -- Update + Validate value in RX
|
||||
ctx.EditLine = nil -- Exit Edit Mode (By clearing the line editing)
|
||||
else
|
||||
dsmLib.ChangePhase(PHASE.EXIT)
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if event == EVT_VIRTUAL_NEXT then
|
||||
ctx.Refresh_Display=true
|
||||
if (DEBUG_ON) then dsmLib.LOG_write("%s: EVT_VIRTUAL_NEXT\n",dsmLib.phase2String(ctx.Phase)) end
|
||||
if ctx.isEditing() then -- Editing a Line, need to inc the value
|
||||
local line=ctx.MenuLines[ctx.EditLine]
|
||||
dsmLib.Value_Add(line, editInc or GUI_RotEncVal(1))
|
||||
else -- not editing, move selected line to NEXT
|
||||
dsmLib.MoveSelectionLine(1)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if event == EVT_VIRTUAL_PREV then
|
||||
ctx.Refresh_Display=true
|
||||
if (DEBUG_ON) then dsmLib.LOG_write("%s: EVT_VIRTUAL_PREV\n",dsmLib.phase2String(ctx.Phase)) end
|
||||
if ctx.isEditing() then -- Editiing a line, need to dec the value
|
||||
local line=ctx.MenuLines[ctx.EditLine]
|
||||
dsmLib.Value_Add(line, editInc or GUI_RotEncVal(-1))
|
||||
else -- not editing, move selected line to PREV
|
||||
dsmLib.MoveSelectionLine(-1)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if event == EVT_VIRTUAL_ENTER_LONG then
|
||||
ctx.Refresh_Display=true
|
||||
if (DEBUG_ON) then dsmLib.LOG_write("%s: EVT_VIRTUAL_ENTER_LONG\n",dsmLib.phase2String(ctx.Phase)) end
|
||||
if ctx.isEditing() then
|
||||
-- reset the value to default
|
||||
dsmLib.Value_Default(menuLines[ctx.EditLine]) -- Update value in RX if needed
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if event == EVT_VIRTUAL_ENTER then
|
||||
ctx.Refresh_Display=true
|
||||
if (DEBUG_ON) then dsmLib.LOG_write("%s: EVT_VIRTUAL_ENTER, SelLine=%d\n",dsmLib.phase2String(ctx.Phase), ctx.SelLine) end
|
||||
if ctx.SelLine == dsmLib.BACK_BUTTON then -- Back
|
||||
dsmLib.GotoMenu(menu.BackId)
|
||||
elseif ctx.SelLine == dsmLib.NEXT_BUTTON then -- Next
|
||||
dsmLib.GotoMenu(menu.NextId)
|
||||
elseif ctx.SelLine == dsmLib.PREV_BUTTON then -- Prev
|
||||
dsmLib.GotoMenu(menu.PrevId)
|
||||
elseif menuLines[ctx.SelLine].ValId ~= 0 then -- Menu or Value
|
||||
|
||||
if menuLines[ctx.SelLine].Type == LINE_TYPE.MENU then -- Navigate to Menu
|
||||
if (SIMULATION_ON and menuLines[ctx.SelLine].ValId==0xFFFF) then
|
||||
-- SPECIAL Simulation menu to Exit Simulation
|
||||
GUI_SwitchSimulationOFF()
|
||||
else
|
||||
dsmLib.GotoMenu(menuLines[ctx.SelLine].ValId) -- ValId is the MenuId to navigate to
|
||||
end
|
||||
else -- Enter on a Value
|
||||
if ctx.isEditing() then -- already editing a Line????
|
||||
ctx.EditLine = nil -- Exit Edit Mode (By clearing the line editing)
|
||||
dsmLib.ChangePhase(PHASE.VALUE_CHANGE_END) -- Request change the value on RX
|
||||
else -- Edit the current value
|
||||
ctx.EditLine = ctx.SelLine
|
||||
originalValue = menuLines[ctx.SelLine].Val
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function init_colors()
|
||||
-- osName in OpenTX is nil, otherwise is EDGETX
|
||||
local ver, radio, maj, minor, rev, osname = getVersion()
|
||||
IS_EDGETX = osname~=nil
|
||||
|
||||
if (IS_EDGETX and USE_SPECKTRUM_COLORS) then
|
||||
-- SPECKTRUM COLORS (only works on EDGETX)
|
||||
-- TOOL HEADER
|
||||
LCD_TOOL_HDR_COLOR = MENU_TITLE_COLOR
|
||||
LCD_TOOL_HDR_BGCOLOR = TITLE_BGCOLOR
|
||||
-- MENU HEADER
|
||||
LCD_MENU_COLOR = WHITE
|
||||
LCD_MENU_BGCOLOR = DARKGREY
|
||||
-- LINE SELECTED
|
||||
LCD_SELECTED_COLOR = WHITE
|
||||
LCD_SELECTED_BGCOLOR = ORANGE
|
||||
LCD_EDIT_BGCOLOR = RED
|
||||
-- NORMAL TEXT
|
||||
LCD_NORMAL_COLOR = BLACK
|
||||
LCD_DISABLE_COLOR = LIGHTGREY
|
||||
LCD_DEBUG_COLOR = BLUE
|
||||
-- NORMAL BOX FRAME COLOR
|
||||
LCD_BOX_COLOR = LIGHTGREY
|
||||
end
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
-- Init
|
||||
local function DSM_Init()
|
||||
init_colors()
|
||||
dsmLib.Init(toolName) -- Initialize Library
|
||||
return dsmLib.StartConnection()
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------------------------------------
|
||||
-- Main
|
||||
local function DSM_Run(event,touchState)
|
||||
local ctx = DSM_Context
|
||||
|
||||
if event == nil then
|
||||
error("Cannot be run as a model script!")
|
||||
dsmLib.LOG_close()
|
||||
return 2
|
||||
end
|
||||
|
||||
GUI_HandleEvent(event,touchState)
|
||||
|
||||
dsmLib.Send_Receive() -- Handle Send and Receive DSM Forward Programming Messages
|
||||
|
||||
local refreshInterval = REFRESH_GUI_MS
|
||||
|
||||
-- When using LCD BLINK attribute, we need faster refresh for BLINK to SHOW on LCD
|
||||
if (ctx.Phase == PHASE.RX_VERSION) then -- Requesting RX Message Version usea BLINK?
|
||||
ctx.Refresh_Display=true
|
||||
refreshInterval = 20 -- 200ms
|
||||
end
|
||||
|
||||
-- Refresh display only if needed and no faster than 300ms, utilize more CPU to speedup DSM communications
|
||||
if (ctx.Refresh_Display and (getTime()-lastRefresh) > refreshInterval) then --300ms from last refresh
|
||||
GUI_Display()
|
||||
ctx.Refresh_Display=false
|
||||
lastRefresh=getTime()
|
||||
end
|
||||
|
||||
if ctx.Phase == PHASE.EXIT_DONE then
|
||||
dsmLib.LOG_close()
|
||||
return 2
|
||||
else
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
return { init=DSM_Init, run=DSM_Run }
|
||||
1374
Lua_scripts/DSMLIB/DsmFwPrgLib.lua
Normal file
1374
Lua_scripts/DSMLIB/DsmFwPrgLib.lua
Normal file
File diff suppressed because it is too large
Load Diff
BIN
Lua_scripts/DSMLIB/DsmFwPrgLib.luac
Normal file
BIN
Lua_scripts/DSMLIB/DsmFwPrgLib.luac
Normal file
Binary file not shown.
1075
Lua_scripts/DSMLIB/DsmFwPrgSIMLib.lua
Normal file
1075
Lua_scripts/DSMLIB/DsmFwPrgSIMLib.lua
Normal file
File diff suppressed because it is too large
Load Diff
BIN
Lua_scripts/DSMLIB/DsmFwPrgSIMLib.luac
Normal file
BIN
Lua_scripts/DSMLIB/DsmFwPrgSIMLib.luac
Normal file
Binary file not shown.
53
Lua_scripts/DSMLIB/readme.txt
Normal file
53
Lua_scripts/DSMLIB/readme.txt
Normal file
@@ -0,0 +1,53 @@
|
||||
This script library is a rewrite of the original DSM forward programming Lua
|
||||
Script. The goal is to make it easier to understand, mantain, and to
|
||||
separate the GUI from the DSM Forward programming engine/logic
|
||||
in this way, GUIs can evolve independent. OpenTX Gui, EdgeTx GUI, etc.
|
||||
|
||||
Code is based on the code/work by: Pascal Langer (Author of the Multi-Module)
|
||||
Rewrite/Enhancements By: Francisco Arzu
|
||||
|
||||
|
||||
|
||||
Deployment:
|
||||
/SCRIPTS/TOOLS/DsmFwdPrg_05_BaW.lua -- OpenTX/EdgeTx version, no touch (black/white radios)
|
||||
/SCRIPTS/TOOLS/DsmFwdPrg_05_Color.lua -- EdgeTX/OpenTx Color version, +touch
|
||||
/SCRIPTS/TOOLS/DSMLIB/ -- Libraries (ALL CAPITALS) to hide them from the Tools menu
|
||||
/SCRIPTS/TOOLS/DSMLIB/DsmFwPrgLib.lub -- DSM Protocol Message and Menu engine
|
||||
/SCRIPTS/TOOLS/DSMLIB/DsmFwPrgSIMLib.lub -- Simulation of AR631 for GUI Development in Companion
|
||||
|
||||
/LOGS/dsm_log.txt -- Readable log of the last RX session, usefull for debuging new RX
|
||||
|
||||
|
||||
Version 0.5
|
||||
- Make the code more readable and understadable
|
||||
- Separate the DSM Forwards Programing logic from the GUI
|
||||
- Log the comunnication 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 version with only Key/Roller Inputs (OTX)
|
||||
- Created a nicer GUI for EdgeTX touchscreen color Radios
|
||||
- RX simulation for GUI development: turn on SIMULATION_ON=true in the beginning of the lua file
|
||||
|
||||
|
||||
Some settings that can change (top of Lua file):
|
||||
SIMULATION_ON = false -- FALSE: use real communication to DSM RX (DEFAULT), TRUE: use a simulated version of RX
|
||||
DEBUG_ON = 1 -- 0=NO DEBUG, 1=HIGH LEVEL 2=LOW LEVEL (Debug logged into the /LOGS/dsm_log.txt)
|
||||
DEBUG_ON_LCD = false -- Interactive Information on LCD of Menu data from RX
|
||||
USE_SPECKTRUM_COLORS = true -- true: Use spectrum colors, false: use theme colors (default on OpenTX)
|
||||
|
||||
|
||||
Known Problems:
|
||||
1. When trying to Factory Reset an RX, even that navigation to menus seems OK, it did not reset.
|
||||
Maybe another message needs to be sent to RX when reaching that page
|
||||
2. When initially setting a new RX, there is a point where a menu navigates to MenuID=0x0001, this seems like a
|
||||
special Save/Restart type of menu.. but it does not reset the RX. maybe another meesage needs to be send
|
||||
3. Some Menu List line types (LINE_TYPE.LIST_MENU1 or "L_m1" in logs), the range (min/max) seems to be incorrect, but cannot see in the data how to fix it
|
||||
Some of the valid values are not even sequential, very spread apart. There has to be a list of valid options somewhere (in RX or config for each field).
|
||||
4. The RX return unknow lines when requesting the Lines for a menu. Realy don't understand what they are for.
|
||||
in some menus, seems to stay stuck in the same return line or no response to the request, making the RX reset/close the connection.
|
||||
Did a fix to stop requesting the same menu line if the response is the same. This gives an empty menu, but does not reset the connection.
|
||||
|
||||
|
||||
Version 0.2
|
||||
Original Version from Pascal Langer
|
||||
|
||||
|
||||
@@ -86,7 +86,8 @@
|
||||
55,1,FrSkyRX,CloneTX,0
|
||||
55,2,FrSkyRX,EraseTX,0
|
||||
55,3,FrSkyRX,CPPM,0,CH5,CH6,CH7,CH8,CH9,CH10,CH11,CH12,CH13,CH14,CH15,CH16
|
||||
58,0,FX816,Std,1
|
||||
58,0,FX,816,1
|
||||
58,1,FX,620,1
|
||||
20,0,FY326,FY326,1,Flip,RTH,HLess,Expert,Calib
|
||||
20,1,FY326,FY319,1,Flip,RTH,HLess,Expert,Calib
|
||||
23,0,FY326,FY326,1,Flip,RTH,HLess,Expert
|
||||
@@ -171,6 +172,7 @@
|
||||
5,1,V2x2,JXD506,1,Flip,Light,Pict,Video,HLess,StaSto,Emerg,Cam_UD
|
||||
48,0,V761,3CH,0,Gyro,Calib,Flip,RtnAct,Rtn
|
||||
48,1,V761,4CH,0,Gyro,Calib,Flip,RtnAct,Rtn
|
||||
48,2,V761,TOPRC,0,Gyro,Calib,Flip,RtnAct,Rtn
|
||||
46,0,V911s,V911s,1,Calib,Rate
|
||||
46,1,V911s,E119,1,Calib,Rate,6G_3D
|
||||
22,0,WFLY,WFR0xS,0,CH5,CH6,CH7,CH8,CH9
|
||||
@@ -203,3 +205,4 @@
|
||||
90,1,MouldKg,Digit,0
|
||||
91,0,Xerall,Tank,0,FlTa,TakLan,Rate,HLess,Photo,Video,TrimR,TrimE,TrimA
|
||||
92,0,MT99xx2,PA18,0,MODE,FLIP,RTH
|
||||
93,0,Kyosho2,KT-17,0
|
||||
|
||||
@@ -60,16 +60,14 @@ The OpenTX sensor "RSSI" is populated by the individual OpenTX telemetry protoco
|
||||
|
||||
## DSM Forward Programming
|
||||
|
||||
Navigation is mainly done using the scroll wheel and ENT. Short press on ENT will edit a value. When editing a value a long ENT press will restore the value to its default. To exit the script and terminate all current operations correctly short press RTN (if you don't do this the RX might not store the changes).
|
||||
This is a work in progress. It's available for color(+touch) and B&W screens.
|
||||
|
||||
This is a work in progress. It's only available for color screens (Horus, TX16S, T16, T18...).
|
||||
|
||||
If some text appears as Unknown_xxx, please report xxx and what the exact text display should be.
|
||||
|
||||
Need OpenTX 2.3.10 nightly or above. Located on the radio SD card under \SCRIPTS\TOOLS.
|
||||
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.
|
||||
|
||||
## DSM PID Flight log gain parameters for Blade micros
|
||||
|
||||
Lua telemetry script from [feathering on RCGroups](https://www.rcgroups.com/forums/showpost.php?p=46033341&postcount=20728) to facilitate setting the Gain Parameters on the Blade 150S FBL. It doesn't use Forward Programming but instead it just reads telemetry data from the Multi-module and displays it on a telemetry display.
|
||||
|
||||
@@ -249,6 +249,10 @@ static uint8_t __attribute__((unused)) DSM_Check_RX_packet()
|
||||
|
||||
uint16_t DSM_callback()
|
||||
{
|
||||
#if defined MULTI_EU
|
||||
if(sub_protocol == DSM2_1F || sub_protocol == DSM2_2F)
|
||||
return 11000;
|
||||
#endif
|
||||
#define DSM_CH1_CH2_DELAY 4010 // Time between write of channel 1 and channel 2
|
||||
#ifdef STM32_BOARD
|
||||
#define DSM_WRITE_DELAY 1600 // Time after write to verify write complete
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
/*
|
||||
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 FEI XIONG P38 plane.
|
||||
|
||||
#if defined(FX816_NRF24L01_INO)
|
||||
|
||||
#include "iface_xn297.h"
|
||||
|
||||
#define FX816_INITIAL_WAIT 500
|
||||
#define FX816_PACKET_PERIOD 10000
|
||||
#define FX816_RF_BIND_CHANNEL 0x28 //40
|
||||
#define FX816_RF_NUM_CHANNELS 4
|
||||
#define FX816_PAYLOAD_SIZE 6
|
||||
#define FX816_BIND_COUNT 300 //3sec
|
||||
|
||||
static void __attribute__((unused)) FX816_send_packet()
|
||||
{
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
packet[0] = 0x55;
|
||||
else
|
||||
{
|
||||
XN297_Hopping(hopping_frequency_no++);
|
||||
hopping_frequency_no%=FX816_RF_NUM_CHANNELS;
|
||||
packet[0] = 0xAA;
|
||||
}
|
||||
packet[1] = rx_tx_addr[0];
|
||||
packet[2] = rx_tx_addr[1];
|
||||
uint8_t val=convert_channel_8b(AILERON);
|
||||
#define FX816_SWITCH 20
|
||||
if(val>127+FX816_SWITCH)
|
||||
packet[3] = 1;
|
||||
else if(val<127-FX816_SWITCH)
|
||||
packet[3] = 2;
|
||||
else
|
||||
packet[3] = 0;
|
||||
packet[4] = convert_channel_16b_limit(THROTTLE,0,100);
|
||||
val=0;
|
||||
for(uint8_t i=0;i<FX816_PAYLOAD_SIZE-1;i++)
|
||||
val+=packet[i];
|
||||
packet[5]=val;
|
||||
|
||||
// Send
|
||||
XN297_SetPower();
|
||||
XN297_SetTxRxMode(TX_EN);
|
||||
XN297_WritePayload(packet, FX816_PAYLOAD_SIZE);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) FX816_RF_init()
|
||||
{
|
||||
XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M);
|
||||
XN297_SetTXAddr((uint8_t *)"\xcc\xcc\xcc\xcc\xcc", 5);
|
||||
//XN297_HoppingCalib(FX816_RF_NUM_CHANNELS);
|
||||
XN297_RFChannel(FX816_RF_BIND_CHANNEL);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) FX816_initialize_txid()
|
||||
{
|
||||
//Only 8 IDs: the RX led does not indicate frame loss.
|
||||
//I didn't open the plane to find out if I could connect there so this is the best I came up with with few trial and errors...
|
||||
rx_tx_addr[0]=0x35+(rx_tx_addr[3]&0x07); //Original dump=0x35
|
||||
rx_tx_addr[1]=0x09; //Original dump=0x09
|
||||
memcpy(hopping_frequency,"\x09\x1B\x30\x42",FX816_RF_NUM_CHANNELS); //Original dump=9=0x09,27=0x1B,48=0x30,66=0x42
|
||||
for(uint8_t i=0;i<FX816_RF_NUM_CHANNELS;i++)
|
||||
hopping_frequency[i]+=rx_tx_addr[3]&0x07;
|
||||
}
|
||||
|
||||
uint16_t FX816_callback()
|
||||
{
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(FX816_PACKET_PERIOD);
|
||||
#endif
|
||||
if(bind_counter)
|
||||
if(--bind_counter==0)
|
||||
BIND_DONE;
|
||||
FX816_send_packet();
|
||||
return FX816_PACKET_PERIOD;
|
||||
}
|
||||
|
||||
void FX816_init()
|
||||
{
|
||||
BIND_IN_PROGRESS; // autobind protocol
|
||||
FX816_initialize_txid();
|
||||
FX816_RF_init();
|
||||
hopping_frequency_no = 0;
|
||||
bind_counter=FX816_BIND_COUNT;
|
||||
}
|
||||
|
||||
#endif
|
||||
177
Multiprotocol/FX_nrf24l01.ino
Normal file
177
Multiprotocol/FX_nrf24l01.ino
Normal file
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
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 FEI XIONG P38 plane.
|
||||
|
||||
#if defined(FX_NRF24L01_INO)
|
||||
|
||||
#include "iface_xn297.h"
|
||||
|
||||
#define FX_BIND_COUNT 300 //3sec
|
||||
#define FX_SWITCH 20
|
||||
#define FX_NUM_CHANNELS 4
|
||||
|
||||
#define FX816_PACKET_PERIOD 10000
|
||||
#define FX816_BIND_CHANNEL 40
|
||||
#define FX816_PAYLOAD_SIZE 6
|
||||
#define FX816_CH_OFFSET 3
|
||||
|
||||
#define FX620_PACKET_PERIOD 3250
|
||||
#define FX620_BIND_PACKET_PERIOD 4500
|
||||
#define FX620_BIND_CHANNEL 18
|
||||
#define FX620_PAYLOAD_SIZE 7
|
||||
#define FX620_CH_OFFSET 1
|
||||
|
||||
//#define FORCE_FX620_ID
|
||||
|
||||
static void __attribute__((unused)) FX_send_packet()
|
||||
{
|
||||
//Hopp
|
||||
if(IS_BIND_DONE)
|
||||
{
|
||||
XN297_Hopping(hopping_frequency_no++);
|
||||
hopping_frequency_no &= 0x03;
|
||||
}
|
||||
|
||||
memset(packet,0x00,packet_length);
|
||||
|
||||
//Channels
|
||||
uint8_t offset=sub_protocol == FX816 ? FX816_CH_OFFSET:FX620_CH_OFFSET;
|
||||
uint8_t val=convert_channel_8b(AILERON);
|
||||
if(val>127+FX_SWITCH)
|
||||
packet[offset] = sub_protocol == FX816 ? 1:0xFF;
|
||||
else if(val<127-FX_SWITCH)
|
||||
packet[offset] = sub_protocol == FX816 ? 2:0x00;
|
||||
else
|
||||
packet[offset] = sub_protocol == FX816 ? 0:0x7F;
|
||||
packet[offset+1] = convert_channel_16b_limit(THROTTLE,0,100); //FX816:0x00..0x63, FX620:0x00..0x5E but that should work
|
||||
|
||||
//Bind and specifics
|
||||
if(sub_protocol == FX816)
|
||||
{
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
packet[0] = 0x55;
|
||||
else
|
||||
packet[0] = 0xAA;
|
||||
packet[1] = rx_tx_addr[0];
|
||||
packet[2] = rx_tx_addr[1];
|
||||
}
|
||||
else //FX620
|
||||
{
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
memcpy(packet,rx_tx_addr,3);
|
||||
packet[3] = hopping_frequency[0];
|
||||
if(bind_counter > (FX_BIND_COUNT >> 1))
|
||||
packet[5] = 0x78;
|
||||
}
|
||||
else
|
||||
{
|
||||
packet[0] = 0x1F; // Is it based on ID??
|
||||
packet[5] = 0xAB; // Is it based on ID??
|
||||
}
|
||||
}
|
||||
|
||||
//Check
|
||||
val=0;
|
||||
for(uint8_t i=0;i<packet_length-1;i++)
|
||||
val+=packet[i];
|
||||
packet[packet_length-1]=val;
|
||||
|
||||
//Debug
|
||||
#if 0
|
||||
for(uint8_t i=0;i<packet_length;i++)
|
||||
debug("%02X ",packet[i]);
|
||||
debugln("");
|
||||
#endif
|
||||
|
||||
// Send
|
||||
XN297_SetPower();
|
||||
XN297_SetTxRxMode(TX_EN);
|
||||
XN297_WritePayload(packet, packet_length);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) FX_RF_init()
|
||||
{
|
||||
XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M);
|
||||
if(sub_protocol == FX816)
|
||||
{
|
||||
XN297_SetTXAddr((uint8_t *)"\xcc\xcc\xcc\xcc\xcc", 5);
|
||||
XN297_RFChannel(FX816_BIND_CHANNEL);
|
||||
packet_period = FX816_PACKET_PERIOD;
|
||||
packet_length = FX816_PAYLOAD_SIZE;
|
||||
}
|
||||
else //FX620
|
||||
{
|
||||
XN297_SetTXAddr((uint8_t *)"\xaa\xbb\xcc", 3);
|
||||
XN297_RFChannel(FX620_BIND_CHANNEL);
|
||||
packet_period = FX620_BIND_PACKET_PERIOD;
|
||||
packet_length = FX620_PAYLOAD_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) FX_initialize_txid()
|
||||
{
|
||||
if(sub_protocol == FX816)
|
||||
{
|
||||
//Only 8 IDs: the RX led does not indicate frame loss.
|
||||
//I didn't open the plane to find out if I could connect there so this is the best I came up with with few trial and errors...
|
||||
rx_tx_addr[0]=0x35+(rx_tx_addr[3]&0x07); //Original dump=0x35
|
||||
rx_tx_addr[1]=0x09; //Original dump=0x09
|
||||
memcpy(hopping_frequency,"\x09\x1B\x30\x42",FX_NUM_CHANNELS); //Original dump=9=0x09,27=0x1B,48=0x30,66=0x42
|
||||
for(uint8_t i=0;i<FX_NUM_CHANNELS;i++)
|
||||
hopping_frequency[i]+=rx_tx_addr[3]&0x07;
|
||||
}
|
||||
else//FX620
|
||||
{
|
||||
rx_tx_addr[0] = rx_tx_addr[3];
|
||||
hopping_frequency[0] = 0x18 + rx_tx_addr[3]&0x07; // just to try something
|
||||
#ifdef FORCE_FX620_ID
|
||||
memcpy(rx_tx_addr,(uint8_t*)"\x34\xA9\x32",3);
|
||||
hopping_frequency[0] = 0x18; //on dump: 24 34 44 54
|
||||
#endif
|
||||
for(uint8_t i=1;i<FX_NUM_CHANNELS;i++)
|
||||
hopping_frequency[i] = i*10 + hopping_frequency[0];
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t FX_callback()
|
||||
{
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(packet_period);
|
||||
#endif
|
||||
if(bind_counter)
|
||||
if(--bind_counter==0)
|
||||
{
|
||||
BIND_DONE;
|
||||
if(sub_protocol == FX620)
|
||||
{
|
||||
XN297_SetTXAddr(rx_tx_addr, 3);
|
||||
packet_period = FX620_PACKET_PERIOD;
|
||||
}
|
||||
}
|
||||
FX_send_packet();
|
||||
return packet_period;
|
||||
}
|
||||
|
||||
void FX_init()
|
||||
{
|
||||
BIND_IN_PROGRESS; // autobind protocol
|
||||
FX_initialize_txid();
|
||||
FX_RF_init();
|
||||
hopping_frequency_no = 0;
|
||||
bind_counter=FX_BIND_COUNT;
|
||||
}
|
||||
|
||||
#endif
|
||||
141
Multiprotocol/Kyosho2_nrf24l01.ino
Normal file
141
Multiprotocol/Kyosho2_nrf24l01.ino
Normal file
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
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(KYOSHO2_NRF24L01_INO)
|
||||
|
||||
#include "iface_nrf24l01.h"
|
||||
|
||||
#define KYOSHO2_PACKET_PERIOD 1120
|
||||
#define KYOSHO2_BIND_PACKET_PERIOD 1600
|
||||
#define KYOSHO2_BIND_COUNT 6000 // about 9sec
|
||||
#define KYOSHO2_BIND_CHANNEL 0x50
|
||||
#define KYOSHO2_PAYLOAD_SIZE 28
|
||||
#define KYOSHO2_RF_CHANNELS 15
|
||||
#define KYOSHO2_START_RF_CHANNEL 0x13 // No idea where it comes from... ID or unknown bytes during the bind?
|
||||
#define KYOSHO2_NUM_CHANNEL 10 // Only 4 on the dumps but there is space for 10 channels in the payload...
|
||||
|
||||
#define FORCE_KYOSHO2_ID
|
||||
|
||||
bool KYOSHO2_resend;
|
||||
//
|
||||
static void __attribute__((unused)) KYOSHO2_send_packet()
|
||||
{
|
||||
if(KYOSHO2_resend == true)
|
||||
{
|
||||
NRF24L01_Strobe(NRF24L01_E3_REUSE_TX_PL);
|
||||
if(IS_BIND_DONE)
|
||||
KYOSHO2_resend = false;
|
||||
return;
|
||||
}
|
||||
|
||||
memset(packet,0x00,KYOSHO2_PAYLOAD_SIZE);
|
||||
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
memcpy(packet, (uint8_t*)"\x01\x02\x05\x08\x1A\x2B\x3C\x4D", 8); // unknown bytes, parameters on how to build the rf channels?
|
||||
memcpy(&packet[8], rx_tx_addr, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(packet, rx_tx_addr, 4);
|
||||
//Hopp
|
||||
packet[6] = hopping_frequency_no + KYOSHO2_START_RF_CHANNEL;
|
||||
packet[7] = hopping_frequency[hopping_frequency_no];
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, packet[6+(rf_ch_num&0x01)]);
|
||||
rf_ch_num++;
|
||||
//Channels
|
||||
uint16_t temp;
|
||||
for (uint8_t i = 0; i< KYOSHO2_NUM_CHANNEL; i++)
|
||||
{
|
||||
temp=convert_channel_16b_limit(i,0,0x3FF);
|
||||
packet[8+i*2] = temp >> 8;
|
||||
packet[9+i*2] = temp;
|
||||
}
|
||||
}
|
||||
//Send
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, (_BV(NRF24L01_07_TX_DS) | _BV(NRF24L01_07_MAX_RT))); // Reset flags
|
||||
NRF24L01_FlushTx();
|
||||
NRF24L01_WritePayload(packet,KYOSHO2_PAYLOAD_SIZE);
|
||||
NRF24L01_SetPower();
|
||||
KYOSHO2_resend = true;
|
||||
|
||||
#if 0
|
||||
for(uint8_t i=0;i<KYOSHO2_PAYLOAD_SIZE;i++)
|
||||
debug("%02X ", packet[i]);
|
||||
debugln("");
|
||||
#endif
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) KYOSHO2_RF_init()
|
||||
{
|
||||
NRF24L01_Initialize();
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, KYOSHO2_BIND_CHANNEL);
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, (uint8_t*)"\x69\x53\x10\xAC\xEF", 5);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) KYOSHO2_initialize_tx_id()
|
||||
{
|
||||
hopping_frequency_no = rx_tx_addr[3]%KYOSHO2_RF_CHANNELS;
|
||||
hopping_frequency[0] = 0x4A;
|
||||
#ifdef FORCE_KYOSHO2_ID
|
||||
memcpy(rx_tx_addr, (uint8_t*)"\x0A\xBD\x31\xDF", 4);
|
||||
hopping_frequency[0] = 0x4A; // No idea where it comes from... ID or unknown bytes during the bind?
|
||||
#endif
|
||||
for(uint8_t i=1;i<KYOSHO2_RF_CHANNELS;i++)
|
||||
{
|
||||
if(hopping_frequency[i-1]+5 < 0x50)
|
||||
hopping_frequency[i] = hopping_frequency[i-1]+5;
|
||||
else
|
||||
hopping_frequency[i] = hopping_frequency[i-1]-0x21;
|
||||
}
|
||||
#if 0
|
||||
for(uint8_t i=0;i<KYOSHO2_RF_CHANNELS;i++)
|
||||
debugln("1:%02X, 2: %02X", i + KYOSHO2_START_RF_CHANNEL, hopping_frequency[i]);
|
||||
debugln("Selected 1:%02X, 2: %02X", hopping_frequency_no + KYOSHO2_START_RF_CHANNEL, hopping_frequency[hopping_frequency_no]);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint16_t KYOSHO2_callback()
|
||||
{
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(KYOSHO2_PACKET_PERIOD);
|
||||
#endif
|
||||
KYOSHO2_send_packet();
|
||||
if(bind_counter)
|
||||
{
|
||||
if(--bind_counter==0)
|
||||
{
|
||||
BIND_DONE;
|
||||
KYOSHO2_resend = false;
|
||||
}
|
||||
return KYOSHO2_BIND_PACKET_PERIOD;
|
||||
}
|
||||
return KYOSHO2_PACKET_PERIOD;
|
||||
}
|
||||
|
||||
void KYOSHO2_init()
|
||||
{
|
||||
KYOSHO2_initialize_tx_id();
|
||||
KYOSHO2_RF_init();
|
||||
rf_ch_num = 0;
|
||||
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
bind_counter = KYOSHO2_BIND_COUNT;
|
||||
else
|
||||
bind_counter = 0;
|
||||
KYOSHO2_resend = false;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -27,15 +27,15 @@
|
||||
#define MT99XX_PACKET_PERIOD_DRAGON 1038 // there is a pause of 2x1038 between two packets, no idea why and how since it is not even stable on a same dump...
|
||||
#define MT99XX_PACKET_PERIOD_DRAGON_TELEM 10265 // long pause to receive the telemetry packets, 3 are sent by the RX one after the other
|
||||
#define MT99XX_PACKET_PERIOD_F949G 3450
|
||||
#define MT99XX_PACKET_PERIOD_PA18 1160
|
||||
#define MT99XX_PA18_CRC 0x89 // Is it a constant???
|
||||
#define MT99XX_PACKET_PERIOD_PA18 1338
|
||||
#define MT99XX_INITIAL_WAIT 500
|
||||
#define MT99XX_PACKET_SIZE 9
|
||||
|
||||
//#define FORCE_A180_ID
|
||||
//#define FORCE_DRAGON_ID
|
||||
//#define FORCE_F949G_ID
|
||||
#define FORCE_PA18_ID
|
||||
#define FORCE_PA18_ID1
|
||||
//#define FORCE_PA18_ID2
|
||||
|
||||
enum {
|
||||
MT99XX_DATA,
|
||||
@@ -115,10 +115,10 @@ static void __attribute__((unused)) MT99XX_send_packet()
|
||||
|
||||
//Set RF freq
|
||||
if(sub_protocol == LS)
|
||||
XN297_RFChannel(0x2D); // LS always transmits on the same channel
|
||||
XN297_RFChannel(0x2D); // LS always transmits on the same channel
|
||||
else
|
||||
if(sub_protocol==FY805)
|
||||
XN297_RFChannel(0x4B); // FY805 always transmits on the same channel
|
||||
XN297_RFChannel(0x4B); // FY805 always transmits on the same channel
|
||||
else // MT99 & H7 & YZ & A180 & DRAGON & F949G & PA18
|
||||
XN297_Hopping(hopping_frequency_no);
|
||||
|
||||
@@ -154,7 +154,7 @@ static void __attribute__((unused)) MT99XX_send_packet()
|
||||
packet[6] = rx_tx_addr[2];
|
||||
if(sub_protocol == PA18+8)
|
||||
{
|
||||
packet[7] = MT99XX_PA18_CRC; // checksum offset
|
||||
packet[7] = num_ch; // checksum offset
|
||||
packet[8] = 0x55; // fixed
|
||||
}
|
||||
else
|
||||
@@ -255,10 +255,10 @@ static void __attribute__((unused)) MT99XX_send_packet()
|
||||
break;
|
||||
case PA18+8:
|
||||
if(Channel_data[CH5] > CHANNEL_MAX_COMMAND) // Expert mode
|
||||
packet[5] += 0xA0;
|
||||
packet[5] = 0xA0;
|
||||
else
|
||||
if(Channel_data[CH5] > CHANNEL_MIN_COMMAND) // Intermediate mode
|
||||
packet[5] += 0x60;
|
||||
packet[5] = 0x60;
|
||||
packet[6] = GET_FLAG( CH6_SW, FLAG_PA18_FLIP ) // Flip
|
||||
| GET_FLAG( CH7_SW, FLAG_PA18_RTH ); // RTH
|
||||
if(hopping_frequency_no == 0)
|
||||
@@ -269,7 +269,7 @@ static void __attribute__((unused)) MT99XX_send_packet()
|
||||
for(uint8_t i=0; i<8; i++)
|
||||
result += packet[i];
|
||||
if(sub_protocol == PA18+8)
|
||||
result += MT99XX_PA18_CRC;
|
||||
result += num_ch;
|
||||
packet[8] = result;
|
||||
}
|
||||
else
|
||||
@@ -337,8 +337,8 @@ static void __attribute__((unused)) MT99XX_RF_init()
|
||||
|
||||
static void __attribute__((unused)) MT99XX_initialize_txid()
|
||||
{
|
||||
rx_tx_addr[1] = rx_tx_addr[3]; // RX_Num
|
||||
|
||||
num_ch = rx_tx_addr[1]; // PA18
|
||||
rx_tx_addr[1] = rx_tx_addr[3]; // RX_Num
|
||||
switch(sub_protocol)
|
||||
{
|
||||
case YZ:
|
||||
@@ -381,20 +381,35 @@ static void __attribute__((unused)) MT99XX_initialize_txid()
|
||||
//channel_offset = 0x03
|
||||
break;
|
||||
#endif
|
||||
#ifdef FORCE_PA18_ID
|
||||
#ifdef FORCE_PA18_ID1
|
||||
case PA18+8:
|
||||
rx_tx_addr[0] = 0xC9; // zebble ID
|
||||
rx_tx_addr[1] = 0x02;
|
||||
rx_tx_addr[2] = 0x13;
|
||||
num_ch = 0x89; // additional crc init. How is this calculated? or could it be random?
|
||||
//crc8 = 0xDE
|
||||
// additional crc init of 0x89, how is this calculated???
|
||||
//channel_offset = 0x03
|
||||
//1Mb C=5 S=Y A= C9 02 13 CC CC P(9)= E1 70 70 70 20 20 00 20 1A
|
||||
//1Mb C=5 S=Y A= C9 02 13 CC CC P(9)= E1 70 70 70 20 20 00 20 1A -> 0x91 + 0x89 => 0x1A
|
||||
// S=Y A= C9 02 13 CC CC P(9)= E1 70 70 70 20 A0 00 20 9A -> 0x11 + 0x89 => 0x9A
|
||||
//bind S=Y A= CC CC CC CC CC P(9)= 20 14 03 25 C9 02 13 89 55
|
||||
break;
|
||||
#endif
|
||||
default: //MT99 & H7 & A180 & DRAGON & F949G
|
||||
#ifdef FORCE_PA18_ID2
|
||||
case PA18+8:
|
||||
rx_tx_addr[0] = 0x0E;
|
||||
rx_tx_addr[1] = 0x05;
|
||||
rx_tx_addr[2] = 0x13;
|
||||
num_ch = 0xD1; // additional crc init. How is this calculated? or could it be random?
|
||||
//crc8 = 0x28
|
||||
//channel_offset = 0x00
|
||||
//1Mb C=2 S=Y A= 0E 05 13 CC CC P(9)= E1 70 70 70 20 60 00 60 E2 -> 0x11 + 0xD1 => 0xE2
|
||||
//bind S=Y A= CC CC CC CC CC P(9)= 20 14 03 25 0E 05 13 D1 55
|
||||
break;
|
||||
#endif
|
||||
default: //MT99 & H7 & A180 & DRAGON & F949G & PA18
|
||||
rx_tx_addr[2] = 0x00;
|
||||
if(sub_protocol == PA18+8)
|
||||
rx_tx_addr[2] = 0x13;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
45,E01X,E012,E015
|
||||
46,V911S,V911S,E119
|
||||
47,GD00x,GD_V1,GD_V2
|
||||
48,V761,3CH,4CH
|
||||
48,V761,3CH,4CH,TOPRC
|
||||
49,KF606,KF606,MIG320
|
||||
50,Redpine,Fast,Slow
|
||||
51,Potensic,A20
|
||||
@@ -55,7 +55,7 @@
|
||||
55,Frsky_RX,Multi,CloneTX,EraseTX,CPPM
|
||||
56,AFHDS2A_RX,Multi,CPPM
|
||||
57,HoTT,Sync,No_Sync
|
||||
58,FX816
|
||||
58,FX,816,620
|
||||
59,Bayang_RX,Multi,CPPM
|
||||
60,Pelikan,Pro,Lite,SCX24
|
||||
61,Tiger
|
||||
@@ -88,4 +88,5 @@
|
||||
89,Losi
|
||||
90,MouldKg,Analog,Digit
|
||||
91,Xerall
|
||||
92,MT99xx,PA18
|
||||
92,MT99xx,PA18
|
||||
93,Kyosho2,KT-17
|
||||
|
||||
@@ -78,7 +78,7 @@ const char STR_SCANNER[] ="Scanner";
|
||||
const char STR_FRSKY_RX[] ="FrSkyRX";
|
||||
const char STR_AFHDS2A_RX[] ="FS2A_RX";
|
||||
const char STR_HOTT[] ="HoTT";
|
||||
const char STR_FX816[] ="FX816";
|
||||
const char STR_FX[] ="FX";
|
||||
const char STR_BAYANG_RX[] ="BayanRX";
|
||||
const char STR_PELIKAN[] ="Pelikan";
|
||||
const char STR_TIGER[] ="Tiger";
|
||||
@@ -88,6 +88,7 @@ const char STR_FRSKYR9[] ="FrSkyR9";
|
||||
const char STR_PROPEL[] ="Propel";
|
||||
const char STR_SKYARTEC[] ="Skyartc";
|
||||
const char STR_KYOSHO[] ="Kyosho";
|
||||
const char STR_KYOSHO2[] ="Kyosho2";
|
||||
const char STR_RLINK[] ="RadLink";
|
||||
const char STR_REALACC[] ="Realacc";
|
||||
const char STR_OMP[] ="OMP";
|
||||
@@ -111,7 +112,11 @@ const char STR_SUBTYPE_FRSKYD[] = "\x06""D8\0 ""Cloned";
|
||||
const char STR_SUBTYPE_FRSKYX[] = "\x07""D16\0 ""D16 8ch""LBT(EU)""LBT 8ch""Cloned\0""Clo 8ch";
|
||||
const char STR_SUBTYPE_HISKY[] = "\x05""Std\0 ""HK310";
|
||||
const char STR_SUBTYPE_V2X2[] = "\x06""Std\0 ""JXD506""MR101\0";
|
||||
const char STR_SUBTYPE_DSM[] = "\x04""2 1F""2 2F""X 1F""X 2F""Auto""R 1F";
|
||||
#ifndef MULTI_EU
|
||||
const char STR_SUBTYPE_DSM[] = "\x04""2 1F""2 2F""X 1F""X 2F""Auto""R 1F";
|
||||
#else
|
||||
const char STR_SUBTYPE_DSM[] = "\x04""--->""--->""X 1F""X 2F""Auto""R 1F";
|
||||
#endif
|
||||
const char STR_SUBTYPE_DEVO[] = "\x04""8ch\0""10ch""12ch""6ch\0""7ch\0";
|
||||
const char STR_SUBTYPE_YD717[] = "\x07""Std\0 ""SkyWlkr""Syma X4""XINXUN\0""NIHUI\0 ";
|
||||
const char STR_SUBTYPE_KN[] = "\x06""WLtoys""FeiLun";
|
||||
@@ -154,16 +159,17 @@ const char STR_SUBTYPE_WFLY[] = "\x05""WFR0x";
|
||||
const char STR_SUBTYPE_WFLY2[] = "\x05""RF20x";
|
||||
const char STR_SUBTYPE_HOTT[] = "\x07""Sync\0 ""No_Sync";
|
||||
const char STR_SUBTYPE_PELIKAN[] = "\x05""Pro\0 ""Lite\0""SCX24";
|
||||
const char STR_SUBTYPE_V761[] = "\x03""3ch""4ch";
|
||||
const char STR_SUBTYPE_V761[] = "\x05""3ch\0 ""4ch\0 ""TOPRC";
|
||||
const char STR_SUBTYPE_RLINK[] = "\x07""Surface""Air\0 ""DumboRC";
|
||||
const char STR_SUBTYPE_REALACC[] = "\x03""R11";
|
||||
const char STR_SUBTYPE_KYOSHO[] = "\x04""FHSS""Hype";
|
||||
const char STR_SUBTYPE_KYOSHO2[] = "\x05""KT-17";
|
||||
const char STR_SUBTYPE_FUTABA[] = "\x05""SFHSS";
|
||||
const char STR_SUBTYPE_JJRC345[] = "\x08""JJRC345\0""SkyTmblr";
|
||||
const char STR_SUBTYPE_MOULKG[] = "\x06""Analog""Digit\0";
|
||||
const char STR_SUBTYPE_KF606[] = "\x06""KF606\0""MIG320";
|
||||
const char STR_SUBTYPE_E129[] = "\x04""E129""C186";
|
||||
|
||||
const char STR_SUBTYPE_FX[] = "\x03""816""620";
|
||||
#define NO_SUBTYPE nullptr
|
||||
|
||||
#ifdef SEND_CPPM
|
||||
@@ -304,8 +310,8 @@ const mm_protocol_definition multi_protocols[] = {
|
||||
#if defined(FUTABA_CC2500_INO)
|
||||
{PROTO_FUTABA, STR_FUTABA, STR_SUBTYPE_FUTABA, 1, OPTION_RFTUNE, 1, 1, SW_CC2500, SFHSS_init, SFHSS_callback },
|
||||
#endif
|
||||
#if defined(FX816_NRF24L01_INO)
|
||||
{PROTO_FX816, STR_FX816, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_NRF, FX816_init, FX816_callback },
|
||||
#if defined(FX_NRF24L01_INO)
|
||||
{PROTO_FX, STR_FX, STR_SUBTYPE_FX, 2, OPTION_NONE, 0, 0, SW_NRF, FX_init, FX_callback },
|
||||
#endif
|
||||
#if defined(FY326_NRF24L01_INO)
|
||||
{PROTO_FY326, STR_FY326, STR_SUBTYPE_FY326, 2, OPTION_NONE, 0, 0, SW_NRF, FY326_init, FY326_callback },
|
||||
@@ -358,6 +364,9 @@ const mm_protocol_definition multi_protocols[] = {
|
||||
#if defined(KYOSHO_A7105_INO)
|
||||
{PROTO_KYOSHO, STR_KYOSHO, STR_SUBTYPE_KYOSHO, 2, OPTION_NONE, 0, 1, SW_A7105, KYOSHO_init, KYOSHO_callback },
|
||||
#endif
|
||||
#if defined(KYOSHO2_NRF24L01_INO)
|
||||
{PROTO_KYOSHO2, STR_KYOSHO2, STR_SUBTYPE_KYOSHO2, 1, OPTION_NONE, 0, 0, SW_NRF, KYOSHO2_init, KYOSHO2_callback },
|
||||
#endif
|
||||
#if defined(LOLI_NRF24L01_INO)
|
||||
{PROTO_LOLI, STR_LOLI, NO_SUBTYPE, 0, OPTION_NONE, 1, 0, SW_NRF, LOLI_init, LOLI_callback },
|
||||
#endif
|
||||
@@ -437,7 +446,7 @@ const mm_protocol_definition multi_protocols[] = {
|
||||
{PROTO_V2X2, STR_V2X2, STR_SUBTYPE_V2X2, 3, OPTION_NONE, 0, 0, SW_NRF, V2X2_init, V2X2_callback },
|
||||
#endif
|
||||
#if defined(V761_NRF24L01_INO)
|
||||
{PROTO_V761, STR_V761, STR_SUBTYPE_V761, 2, OPTION_NONE, 0, 0, SW_NRF, V761_init, V761_callback },
|
||||
{PROTO_V761, STR_V761, STR_SUBTYPE_V761, 3, OPTION_NONE, 0, 0, SW_NRF, V761_init, V761_callback },
|
||||
#endif
|
||||
#if defined(V911S_CCNRF_INO)
|
||||
{PROTO_V911S, STR_V911S, STR_SUBTYPE_V911S, 2, OPTION_RFTUNE, 0, 0, SW_NRF, V911S_init, V911S_callback },
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#define VERSION_MAJOR 1
|
||||
#define VERSION_MINOR 3
|
||||
#define VERSION_REVISION 3
|
||||
#define VERSION_PATCH_LEVEL 14
|
||||
#define VERSION_PATCH_LEVEL 22
|
||||
|
||||
#define MODE_SERIAL 0
|
||||
|
||||
@@ -86,7 +86,7 @@ enum PROTOCOLS
|
||||
PROTO_FRSKY_RX = 55, // =>CC2500
|
||||
PROTO_AFHDS2A_RX= 56, // =>A7105
|
||||
PROTO_HOTT = 57, // =>CC2500
|
||||
PROTO_FX816 = 58, // =>NRF24L01
|
||||
PROTO_FX = 58, // =>NRF24L01
|
||||
PROTO_BAYANG_RX = 59, // =>NRF24L01
|
||||
PROTO_PELIKAN = 60, // =>A7105
|
||||
PROTO_TIGER = 61, // =>NRF24L01
|
||||
@@ -120,6 +120,7 @@ enum PROTOCOLS
|
||||
PROTO_MOULDKG = 90, // =>NRF24L01
|
||||
PROTO_XERALL = 91, // =>NRF24L01
|
||||
PROTO_MT99XX2 = 92, // =>NRF24L01, extension of MT99XX protocol
|
||||
PROTO_KYOSHO2 = 93, // =>NRF24L01
|
||||
|
||||
PROTO_NANORF = 126, // =>NRF24L01
|
||||
PROTO_TEST = 127, // =>CC2500
|
||||
@@ -390,7 +391,6 @@ enum ESKY
|
||||
ESKY_STD = 0,
|
||||
ESKY_ET4 = 1,
|
||||
};
|
||||
|
||||
enum FRSKY_RX
|
||||
{
|
||||
FRSKY_RX = 0,
|
||||
@@ -398,74 +398,69 @@ enum FRSKY_RX
|
||||
FRSKY_ERASE = 2,
|
||||
FRSKY_CPPM = 3,
|
||||
};
|
||||
|
||||
enum FRSKYL
|
||||
{
|
||||
LR12 = 0,
|
||||
LR12_6CH = 1,
|
||||
};
|
||||
|
||||
enum HOTT
|
||||
{
|
||||
HOTT_SYNC = 0,
|
||||
HOTT_NO_SYNC= 1,
|
||||
};
|
||||
|
||||
enum PELIKAN
|
||||
{
|
||||
PELIKAN_PRO = 0,
|
||||
PELIKAN_LITE= 1,
|
||||
PELIKAN_SCX24=2,
|
||||
};
|
||||
|
||||
enum V761
|
||||
{
|
||||
V761_3CH = 0,
|
||||
V761_4CH = 1,
|
||||
V761_TOPRC = 2,
|
||||
};
|
||||
|
||||
enum HEIGHT
|
||||
{
|
||||
HEIGHT_5CH = 0,
|
||||
HEIGHT_8CH = 1,
|
||||
};
|
||||
|
||||
enum KYOSHO
|
||||
{
|
||||
KYOSHO_FHSS = 0,
|
||||
KYOSHO_HYPE = 1,
|
||||
};
|
||||
|
||||
enum JJRC345
|
||||
{
|
||||
JJRC345 = 0,
|
||||
SKYTMBLR = 1,
|
||||
};
|
||||
|
||||
enum RLINK
|
||||
{
|
||||
RLINK_SURFACE = 0,
|
||||
RLINK_AIR = 1,
|
||||
RLINK_DUMBORC = 2,
|
||||
};
|
||||
|
||||
enum MOULDKG
|
||||
{
|
||||
MOULDKG_ANALOG = 0,
|
||||
MOULDKG_DIGIT = 1,
|
||||
};
|
||||
|
||||
enum KF606
|
||||
{
|
||||
KF606_KF606 = 0,
|
||||
KF606_MIG320 = 1,
|
||||
};
|
||||
|
||||
enum E129
|
||||
{
|
||||
E129_E129 = 0,
|
||||
E129_C186 = 1,
|
||||
};
|
||||
enum FX
|
||||
{
|
||||
FX816 = 0,
|
||||
FX620 = 1,
|
||||
};
|
||||
|
||||
#define NONE 0
|
||||
#define P_HIGH 1
|
||||
@@ -911,7 +906,7 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
||||
FRSKY_RX 55
|
||||
AFHDS2A_RX 56
|
||||
HOTT 57
|
||||
FX816 58
|
||||
FX 58
|
||||
BAYANG_RX 59
|
||||
PELIKAN 60
|
||||
TIGER 61
|
||||
|
||||
@@ -25,13 +25,15 @@ Multiprotocol is distributed in the hope that it will be useful,
|
||||
#define V761_BIND_COUNT 200
|
||||
#define V761_BIND_FREQ 0x28
|
||||
#define V761_RF_NUM_CHANNELS 3
|
||||
#define TOPRC_BIND_FREQ 0x2A
|
||||
#define TOPRC_PACKET_PERIOD 14120 // Timeout for callback in uSec
|
||||
|
||||
enum
|
||||
{
|
||||
{
|
||||
V761_BIND1 = 0,
|
||||
V761_BIND2,
|
||||
V761_DATA
|
||||
};
|
||||
};
|
||||
|
||||
static void __attribute__((unused)) V761_set_checksum()
|
||||
{
|
||||
@@ -56,14 +58,11 @@ static void __attribute__((unused)) V761_send_packet()
|
||||
|
||||
if(phase != V761_DATA)
|
||||
{
|
||||
packet[0] = rx_tx_addr[0];
|
||||
packet[1] = rx_tx_addr[1];
|
||||
packet[2] = rx_tx_addr[2];
|
||||
packet[3] = rx_tx_addr[3];
|
||||
memcpy(packet, rx_tx_addr, 4);
|
||||
packet[4] = hopping_frequency[1];
|
||||
packet[5] = hopping_frequency[2];
|
||||
if(phase == V761_BIND2)
|
||||
packet[6] = 0xf0; // ?
|
||||
packet[6] = 0xF0; // ?
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -72,23 +71,22 @@ static void __attribute__((unused)) V761_send_packet()
|
||||
{
|
||||
hopping_frequency_no = 0;
|
||||
packet_count++;
|
||||
if(packet_count >= 4)
|
||||
packet_count = 0;
|
||||
packet_count &= 0x03;
|
||||
}
|
||||
|
||||
packet[0] = convert_channel_8b(THROTTLE); // Throttle
|
||||
packet[2] = convert_channel_8b(ELEVATOR)>>1; // Elevator
|
||||
|
||||
if(sub_protocol==V761_3CH)
|
||||
{
|
||||
packet[1] = convert_channel_8b(RUDDER)>>1; // Rudder
|
||||
packet[3] = convert_channel_8b(AILERON)>>1; // Aileron
|
||||
}
|
||||
else
|
||||
if(sub_protocol == V761_4CH || sub_protocol == V761_TOPRC)
|
||||
{
|
||||
packet[1] = convert_channel_8b(AILERON)>>1; // Aileron
|
||||
packet[3] = convert_channel_8b(RUDDER)>>1; // Rudder
|
||||
}
|
||||
else
|
||||
{
|
||||
packet[1] = convert_channel_8b(RUDDER)>>1; // Rudder
|
||||
packet[3] = convert_channel_8b(AILERON)>>1; // Aileron
|
||||
}
|
||||
|
||||
packet[5] = packet_count<<6; // 0X, 4X, 8X, CX
|
||||
packet[4] = 0x20; // Trims 00..20..40, 0X->20 4X->TrAil 8X->TrEle CX->TrRud
|
||||
@@ -112,7 +110,7 @@ static void __attribute__((unused)) V761_send_packet()
|
||||
packet[6] = GET_FLAG(CH7_SW, 0x20) // Flip
|
||||
|GET_FLAG(CH8_SW, 0x08) // RTH activation
|
||||
|GET_FLAG(CH9_SW, 0x10); // RTH on/off
|
||||
if(sub_protocol==V761_3CH)
|
||||
if(sub_protocol == V761_3CH)
|
||||
packet[6] |= 0x80; // Unknown, set on original V761-1 dump but not on eachine dumps, keeping for compatibility
|
||||
}
|
||||
V761_set_checksum();
|
||||
@@ -137,28 +135,36 @@ static void __attribute__((unused)) V761_RF_init()
|
||||
static void __attribute__((unused)) V761_initialize_txid()
|
||||
{
|
||||
#ifdef V761_FORCE_ID
|
||||
switch(RX_num%5)
|
||||
if(sub_protocol == V761_TOPRC)
|
||||
{ //Dump from air on TopRCHobby TX
|
||||
memcpy(rx_tx_addr,(uint8_t *)"\xD5\x01\x00\x00",4);
|
||||
memcpy(hopping_frequency,(uint8_t *)"\x2E\x41",2);
|
||||
}
|
||||
else
|
||||
{
|
||||
case 1: //Dump from air on Protonus TX
|
||||
memcpy(rx_tx_addr,(uint8_t *)"\xE8\xE4\x45\x09",4);
|
||||
memcpy(hopping_frequency,(uint8_t *)"\x0D\x21",2);
|
||||
break;
|
||||
case 2: //Dump from air on mshagg2 TX
|
||||
memcpy(rx_tx_addr,(uint8_t *)"\xAE\xD1\x45\x09",4);
|
||||
memcpy(hopping_frequency,(uint8_t *)"\x13\x1D",2);
|
||||
break;
|
||||
case 3: //Dump from air on MikeHRC Eachine TX
|
||||
memcpy(rx_tx_addr,(uint8_t *)"\x08\x03\x00\xA0",4);
|
||||
memcpy(hopping_frequency,(uint8_t *)"\x0D\x21",2);
|
||||
break;
|
||||
case 4: //Dump from air on Crashanium Eachine TX
|
||||
memcpy(rx_tx_addr,(uint8_t *)"\x58\x08\x00\xA0",4);
|
||||
memcpy(hopping_frequency,(uint8_t *)"\x0D\x31",2);
|
||||
break;
|
||||
default: //Dump from SPI
|
||||
memcpy(rx_tx_addr,(uint8_t *)"\x6f\x2c\xb1\x93",4);
|
||||
memcpy(hopping_frequency,(uint8_t *)"\x14\x1e",2);
|
||||
break;
|
||||
switch(RX_num%5)
|
||||
{
|
||||
case 1: //Dump from air on Protonus TX
|
||||
memcpy(rx_tx_addr,(uint8_t *)"\xE8\xE4\x45\x09",4);
|
||||
memcpy(hopping_frequency,(uint8_t *)"\x0D\x21",2);
|
||||
break;
|
||||
case 2: //Dump from air on mshagg2 TX
|
||||
memcpy(rx_tx_addr,(uint8_t *)"\xAE\xD1\x45\x09",4);
|
||||
memcpy(hopping_frequency,(uint8_t *)"\x13\x1D",2);
|
||||
break;
|
||||
case 3: //Dump from air on MikeHRC Eachine TX
|
||||
memcpy(rx_tx_addr,(uint8_t *)"\x08\x03\x00\xA0",4);
|
||||
memcpy(hopping_frequency,(uint8_t *)"\x0D\x21",2);
|
||||
break;
|
||||
case 4: //Dump from air on Crashanium Eachine TX
|
||||
memcpy(rx_tx_addr,(uint8_t *)"\x58\x08\x00\xA0",4);
|
||||
memcpy(hopping_frequency,(uint8_t *)"\x0D\x31",2);
|
||||
break;
|
||||
default: //Dump from SPI
|
||||
memcpy(rx_tx_addr,(uint8_t *)"\x6f\x2c\xb1\x93",4);
|
||||
memcpy(hopping_frequency,(uint8_t *)"\x14\x1e",2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
//Tested with Eachine RX
|
||||
@@ -180,8 +186,8 @@ uint16_t V761_callback()
|
||||
if(bind_counter)
|
||||
bind_counter--;
|
||||
packet_count ++;
|
||||
XN297_RFChannel(V761_BIND_FREQ);
|
||||
XN297_SetTXAddr((uint8_t*)"\x34\x43\x10\x10", 4);
|
||||
XN297_RFChannel(sub_protocol == V761_TOPRC ? TOPRC_BIND_FREQ : V761_BIND_FREQ);
|
||||
XN297_SetTXAddr(rx_id, 4);
|
||||
V761_send_packet();
|
||||
if(packet_count >= 20)
|
||||
{
|
||||
@@ -210,17 +216,28 @@ uint16_t V761_callback()
|
||||
return 15730;
|
||||
case V761_DATA:
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(V761_PACKET_PERIOD);
|
||||
telemetry_set_input_sync(packet_period);
|
||||
#endif
|
||||
V761_send_packet();
|
||||
break;
|
||||
}
|
||||
return V761_PACKET_PERIOD;
|
||||
return packet_period;
|
||||
}
|
||||
|
||||
void V761_init(void)
|
||||
{
|
||||
V761_initialize_txid();
|
||||
if(sub_protocol == V761_TOPRC)
|
||||
{
|
||||
memcpy(rx_id,(uint8_t*)"\x20\x21\x05\x0A",4);
|
||||
packet_period = TOPRC_PACKET_PERIOD;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(rx_id,(uint8_t*)"\x34\x43\x10\x10",4);
|
||||
packet_period = V761_PACKET_PERIOD;
|
||||
}
|
||||
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
bind_counter = V761_BIND_COUNT;
|
||||
@@ -231,7 +248,7 @@ void V761_init(void)
|
||||
XN297_SetTXAddr(rx_tx_addr, 4);
|
||||
phase = V761_DATA;
|
||||
}
|
||||
|
||||
|
||||
V761_RF_init();
|
||||
hopping_frequency_no = 0;
|
||||
packet_count = 0;
|
||||
|
||||
@@ -241,22 +241,27 @@
|
||||
#endif
|
||||
|
||||
//Make sure protocols are selected correctly
|
||||
#ifndef A7105_INSTALLED
|
||||
#undef AFHDS2A_A7105_INO
|
||||
#undef AFHDS2A_RX_A7105_INO
|
||||
#undef BUGS_A7105_INO
|
||||
#undef FLYSKY_A7105_INO
|
||||
#undef HEIGHT_A7105_INO
|
||||
#undef HUBSAN_A7105_INO
|
||||
#undef JOYSWAY_A7105_INO
|
||||
#undef KYOSHO_A7105_INO
|
||||
#undef PELIKAN_A7105_INO
|
||||
#undef WFLY2_A7105_INO
|
||||
#if not defined(A7105_INSTALLED) || defined MULTI_EU
|
||||
#undef AFHDS2A_A7105_INO
|
||||
#if not defined(A7105_INSTALLED)
|
||||
#undef AFHDS2A_RX_A7105_INO
|
||||
#endif
|
||||
#undef BUGS_A7105_INO
|
||||
#undef FLYSKY_A7105_INO
|
||||
#undef HEIGHT_A7105_INO
|
||||
#undef HUBSAN_A7105_INO
|
||||
#undef JOYSWAY_A7105_INO
|
||||
#undef KYOSHO_A7105_INO
|
||||
#undef PELIKAN_A7105_INO
|
||||
#undef WFLY2_A7105_INO
|
||||
#endif
|
||||
#ifndef CYRF6936_INSTALLED
|
||||
|
||||
#if not defined(CYRF6936_INSTALLED) || defined MULTI_EU
|
||||
#undef DEVO_CYRF6936_INO
|
||||
#undef DSM_CYRF6936_INO
|
||||
#undef DSM_RX_CYRF6936_INO
|
||||
#if not defined(CYRF6936_INSTALLED)
|
||||
#undef DSM_CYRF6936_INO
|
||||
#undef DSM_RX_CYRF6936_INO
|
||||
#endif
|
||||
#undef E010R5_CYRF6936_INO
|
||||
#undef E01X_CYRF6936_INO
|
||||
#undef E129_CYRF6936_INO
|
||||
@@ -267,28 +272,38 @@
|
||||
#undef WFLY_CYRF6936_INO
|
||||
#undef WK2x01_CYRF6936_INO
|
||||
#endif
|
||||
#ifndef CC2500_INSTALLED
|
||||
|
||||
#if not defined(CC2500_INSTALLED) || defined MULTI_EU
|
||||
#undef CORONA_CC2500_INO
|
||||
#undef E016HV2_CC2500_INO
|
||||
#undef ESKY150V2_CC2500_INO
|
||||
#undef FRSKYD_CC2500_INO
|
||||
#undef FRSKYL_CC2500_INO
|
||||
#undef FRSKYV_CC2500_INO
|
||||
#undef FRSKYX_CC2500_INO
|
||||
#undef FRSKY_RX_CC2500_INO
|
||||
#if not defined(CC2500_INSTALLED)
|
||||
#undef FRSKYX_CC2500_INO
|
||||
#undef FRSKY_RX_CC2500_INO
|
||||
#endif
|
||||
#undef HITEC_CC2500_INO
|
||||
#undef HOTT_CC2500_INO
|
||||
#if not defined(CC2500_INSTALLED)
|
||||
#undef HOTT_CC2500_INO
|
||||
#endif
|
||||
#undef IKEAANSLUTA_CC2500_INO
|
||||
#undef REDPINE_CC2500_INO
|
||||
#undef RLINK_CC2500_INO
|
||||
#undef SCANNER_CC2500_INO
|
||||
#if not defined(CC2500_INSTALLED)
|
||||
#undef SCANNER_CC2500_INO
|
||||
#endif
|
||||
#undef FUTABA_CC2500_INO
|
||||
#undef SKYARTEC_CC2500_INO
|
||||
#endif
|
||||
#ifndef NRF24L01_INSTALLED
|
||||
|
||||
#if not defined(NRF24L01_INSTALLED) || defined MULTI_EU
|
||||
#undef ASSAN_NRF24L01_INO
|
||||
#undef BAYANG_NRF24L01_INO
|
||||
#undef BAYANG_RX_NRF24L01_INO
|
||||
#if not defined(NRF24L01_INSTALLED)
|
||||
#undef BAYANG_RX_NRF24L01_INO
|
||||
#endif
|
||||
#undef BUGSMINI_NRF24L01_INO
|
||||
#undef CABELL_NRF24L01_INO
|
||||
#undef CFLIE_NRF24L01_INO
|
||||
@@ -299,7 +314,7 @@
|
||||
#undef ESKY_NRF24L01_INO
|
||||
#undef ESKY150_NRF24L01_INO
|
||||
#undef FQ777_NRF24L01_INO
|
||||
#undef FX816_NRF24L01_INO
|
||||
#undef FX_NRF24L01_INO
|
||||
#undef FY326_NRF24L01_INO
|
||||
#undef GW008_NRF24L01_INO
|
||||
#undef H8_3D_NRF24L01_INO
|
||||
@@ -307,6 +322,7 @@
|
||||
#undef HONTAI_NRF24L01_INO
|
||||
#undef JJRC345_NRF24L01_INO
|
||||
#undef KN_NRF24L01_INO
|
||||
#undef KYOSHO2_NRF24L01_INO
|
||||
#undef LOLI_NRF24L01_INO
|
||||
#undef MOULDKG_NRF24L01_INO
|
||||
#undef NCC1701_NRF24L01_INO
|
||||
@@ -322,7 +338,7 @@
|
||||
#undef YD717_NRF24L01_INO
|
||||
#undef ZSX_NRF24L01_INO
|
||||
#endif
|
||||
#if not defined(CC2500_INSTALLED) && not defined(NRF24L01_INSTALLED)
|
||||
#if ( not defined(CC2500_INSTALLED) && not defined(NRF24L01_INSTALLED) ) || defined MULTI_EU
|
||||
#undef GD00X_CCNRF_INO
|
||||
#undef KF606_CCNRF_INO
|
||||
#undef MJXQ_CCNRF_INO
|
||||
@@ -342,7 +358,7 @@
|
||||
#if not defined(STM32_BOARD)
|
||||
#undef SX1276_INSTALLED
|
||||
#endif
|
||||
#ifndef SX1276_INSTALLED
|
||||
#ifndef SX1276_INSTALLED || defined MULTI_EU
|
||||
#undef FRSKYR9_SX1276_INO
|
||||
#endif
|
||||
|
||||
|
||||
@@ -229,7 +229,7 @@
|
||||
#define ESKY_NRF24L01_INO
|
||||
#define ESKY150_NRF24L01_INO
|
||||
#define FQ777_NRF24L01_INO
|
||||
#define FX816_NRF24L01_INO
|
||||
#define FX_NRF24L01_INO
|
||||
#define FY326_NRF24L01_INO
|
||||
#define GW008_NRF24L01_INO
|
||||
#define HISKY_NRF24L01_INO
|
||||
@@ -237,6 +237,7 @@
|
||||
#define H8_3D_NRF24L01_INO
|
||||
#define JJRC345_NRF24L01_INO
|
||||
#define KN_NRF24L01_INO
|
||||
#define KYOSHO2_NRF24L01_INO
|
||||
#define LOLI_NRF24L01_INO
|
||||
//#define MOULDKG_NRF24L01_INO
|
||||
#define NCC1701_NRF24L01_INO
|
||||
@@ -666,8 +667,9 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
|
||||
PROTO_FRSKY_RX
|
||||
FRSKY_RX
|
||||
FRSKY_CLONE
|
||||
PROTO_FX816
|
||||
NONE
|
||||
PROTO_FX
|
||||
FX816
|
||||
FX620
|
||||
PROTO_FY326
|
||||
FY326
|
||||
FY319
|
||||
@@ -721,6 +723,8 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
|
||||
PROTO_KYOSHO
|
||||
KYOSHO_FHSS
|
||||
KYOSHO_HYPE
|
||||
PROTO_KYOSHO2
|
||||
NONE
|
||||
PROTO_LOLI
|
||||
NONE
|
||||
PROTO_LOSI
|
||||
|
||||
@@ -96,7 +96,7 @@ CFlie|38|CFlie||||||||NRF24L01|
|
||||
[FrskyX2](Protocols_Details.md#FRSKYX2---64)|64|CH_16|CH_8|EU_16|EU_8|Cloned|Cloned_8|||CC2500|
|
||||
[Frsky_RX](Protocols_Details.md#FRSKY_RX---55)|55|Multi|CloneTX|EraseTX|CPPM|||||CC2500|
|
||||
[Futaba/SFHSS](Protocols_Details.md#Futaba---21)|21|SFHSS||||||||CC2500|
|
||||
[FX816](Protocols_Details.md#FX816---58)|28|FX816||||||||NRF24L01|
|
||||
[FX](Protocols_Details.md#FX---58)|28|816|620|||||||NRF24L01|
|
||||
[FY326](Protocols_Details.md#FY326---20)|20|FY326|FY319|||||||NRF24L01|
|
||||
[GD00X](Protocols_Details.md#GD00X---47)|47|GD_V1*|GD_V2*|||||||NRF24L01|XN297L
|
||||
[GW008](Protocols_Details.md#GW008---32)|32|||||||||NRF24L01|XN297
|
||||
@@ -113,6 +113,7 @@ CFlie|38|CFlie||||||||NRF24L01|
|
||||
[KF606](Protocols_Details.md#KF606---49)|49|KF606|MIG320|||||||NRF24L01|XN297
|
||||
[KN](Protocols_Details.md#KN---9)|9|WLTOYS|FEILUN|||||||NRF24L01|
|
||||
[Kyosho](Protocols_Details.md#Kyosho---73)|73|FHSS|Hype|||||||A7105|
|
||||
[Kyosho2](Protocols_Details.md#Kyosho2---93)|93|KT-17||||||||NRF24L01|
|
||||
[LOLI](Protocols_Details.md#LOLI---82)|82|||||||||NRF24L01|
|
||||
[Losi](Protocols_Details.md#Losi---89)|89|||||||||CYRF6936|
|
||||
[MJXq](Protocols_Details.md#MJXQ---18)|18|WLH08|X600|X800|H26D|E010*|H26WH|PHOENIX*||NRF24L01|XN297
|
||||
@@ -140,7 +141,7 @@ CFlie|38|CFlie||||||||NRF24L01|
|
||||
[Tiger](Protocols_Details.md#Tiger---61)|61|||||||||NRF24L01|XN297
|
||||
[Traxxas](Protocols_Details.md#Traxxas---43)|43|6519 RX||||||||CYRF6936|
|
||||
[V2x2](Protocols_Details.md#V2X2---5)|5|V2x2|JXD506|MR101||||||NRF24L01|
|
||||
[V761](Protocols_Details.md#V761---48)|48|3CH|4CH|||||||NRF24L01|XN297
|
||||
[V761](Protocols_Details.md#V761---48)|48|3CH|4CH|TOPRC||||||NRF24L01|XN297
|
||||
[V911S](Protocols_Details.md#V911S---46)|46|V911S*|E119*|||||||NRF24L01|XN297
|
||||
[WFLY](Protocols_Details.md#WFLY---40)|40|WFR0x||||||||CYRF6936|
|
||||
[WFLY2](Protocols_Details.md#WFLY2---79)|79|RF20x||||||||A7105|
|
||||
@@ -527,7 +528,7 @@ DSMX, Resolution 2048, servo refresh rate can only be 22ms
|
||||
### Sub_protocol DSMX_2F - *3*
|
||||
DSMX, Resolution 2048, servo refresh rate can be 22 or 11ms. 11ms won't be available on all servo outputs when more than 7 channels are used.
|
||||
### Sub_protocol AUTO - *4*
|
||||
"AUTO" is recommended to automatically select the best settings for your DSM RX.
|
||||
"AUTO" is recommended to automatically select the best settings for your DSM2 and DSMX RXs.
|
||||
|
||||
### Sub_protocol DSMR_1F - *5*
|
||||
DSMR receivers
|
||||
@@ -1600,15 +1601,21 @@ A|E|T|R|FMODE|AUX6|AUX7
|
||||
|
||||
FMODE and AUX7 have 4 positions: -100%..-50%=>0, -50%..5%=>1, 5%..50%=>2, 50%..100%=>3
|
||||
|
||||
## FX816 - *58*
|
||||
Model: FEI XIONG FX P38, B17
|
||||
|
||||
Only 8 TX IDs available
|
||||
## FX - *58*
|
||||
FEI XIONG
|
||||
|
||||
CH1|CH2|CH3|CH4
|
||||
---|---|---|---
|
||||
A|-|T|-
|
||||
|
||||
### Sub_protocol 816 - *0*
|
||||
Model: FX816 P38, B17
|
||||
|
||||
Only 8 TX IDs available
|
||||
|
||||
### Sub_protocol 620 - *1*
|
||||
Model: FX620 SU35
|
||||
|
||||
## FY326 - *20*
|
||||
|
||||
### Sub_protocol FY326 - *0*
|
||||
@@ -1725,6 +1732,13 @@ Model: DF-Models SkyTumbler
|
||||
|
||||
RTH not supported
|
||||
|
||||
## KYOSHO2 - *93*
|
||||
Model: TX KT-17, Minium Edge 540, Minium Citabria
|
||||
|
||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10
|
||||
---|---|---|---|---|---|---|---|---|----
|
||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10
|
||||
|
||||
## LOLI - *82*
|
||||
LOLI3 receivers: https://github.com/wooddoor/Loli3
|
||||
|
||||
@@ -1937,14 +1951,21 @@ Flip: momentary switch: hold flip(+100%), indicate flip direction with Ele or Ai
|
||||
RTN_ACT and RTN: -100% disable, +100% enable
|
||||
|
||||
### Sub_protocol 3CH - *0*
|
||||
Model: Volantex V761-1, V761-3 and may be others
|
||||
Models: Volantex V761-1, V761-3 and may be others
|
||||
|
||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
|
||||
---|---|---|---|---|---|---|---|---
|
||||
-|E|T|R|GYRO|CALIB|FLIP|RTN_ACT|RTN
|
||||
|
||||
### Sub_protocol 4CH - *1*
|
||||
Model: Volantex V761-4+ and Eachine P51-D, F4U, F22 and may be others
|
||||
Models: Volantex V761-4+ and Eachine P51-D, F4U, F22 and may be others
|
||||
|
||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
|
||||
---|---|---|---|---|---|---|---|---
|
||||
A|E|T|R|GYRO|CALIB|FLIP|RTN_ACT|RTN
|
||||
|
||||
### Sub_protocol TOPRC - *2*
|
||||
Models: Top RC Hobby Spitfire, P51D, BF-109
|
||||
|
||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
|
||||
---|---|---|---|---|---|---|---|---
|
||||
|
||||
BIN
STM32 PCB/Flysky PL18/Casing/MPM-BF.stl
Normal file
BIN
STM32 PCB/Flysky PL18/Casing/MPM-BF.stl
Normal file
Binary file not shown.
BIN
STM32 PCB/Flysky PL18/Casing/MPM-TF.stl
Normal file
BIN
STM32 PCB/Flysky PL18/Casing/MPM-TF.stl
Normal file
Binary file not shown.
BIN
STM32 PCB/Flysky PL18/Casing/MPM.blend
Normal file
BIN
STM32 PCB/Flysky PL18/Casing/MPM.blend
Normal file
Binary file not shown.
130
STM32 PCB/Flysky PL18/PL18_multiprotocol/Multi.kicad_sym
Normal file
130
STM32 PCB/Flysky PL18/PL18_multiprotocol/Multi.kicad_sym
Normal file
@@ -0,0 +1,130 @@
|
||||
(kicad_symbol_lib (version 20211014) (generator kicad_symbol_editor)
|
||||
(symbol "MULTIRF4IN1SMT" (in_bom yes) (on_board yes)
|
||||
(property "Reference" "M" (id 0) (at -12.7 21.59 0)
|
||||
(effects (font (size 1.27 1.0795)) (justify left bottom))
|
||||
)
|
||||
(property "Value" "MULTIRF4IN1SMT" (id 1) (at -12.7 -16.51 0)
|
||||
(effects (font (size 1.778 1.5113)) (justify left top))
|
||||
)
|
||||
(property "Footprint" "Multi:MULTIRF4IN1-SMT" (id 2) (at 0 0 0)
|
||||
(effects (font (size 1.27 1.27)) hide)
|
||||
)
|
||||
(property "Datasheet" "" (id 3) (at 0 0 0)
|
||||
(effects (font (size 1.27 1.27)) hide)
|
||||
)
|
||||
(symbol "MULTIRF4IN1SMT_1_0"
|
||||
(polyline
|
||||
(pts
|
||||
(xy -12.7 -15.24)
|
||||
(xy 12.7 -15.24)
|
||||
)
|
||||
(stroke (width 0.254) (type default) (color 0 0 0 0))
|
||||
(fill (type none))
|
||||
)
|
||||
(polyline
|
||||
(pts
|
||||
(xy -12.7 20.32)
|
||||
(xy -12.7 -15.24)
|
||||
)
|
||||
(stroke (width 0.254) (type default) (color 0 0 0 0))
|
||||
(fill (type none))
|
||||
)
|
||||
(polyline
|
||||
(pts
|
||||
(xy 12.7 -15.24)
|
||||
(xy 12.7 20.32)
|
||||
)
|
||||
(stroke (width 0.254) (type default) (color 0 0 0 0))
|
||||
(fill (type none))
|
||||
)
|
||||
(polyline
|
||||
(pts
|
||||
(xy 12.7 20.32)
|
||||
(xy -12.7 20.32)
|
||||
)
|
||||
(stroke (width 0.254) (type default) (color 0 0 0 0))
|
||||
(fill (type none))
|
||||
)
|
||||
(pin bidirectional line (at 15.24 17.78 180) (length 2.54)
|
||||
(name "CE_2401" (effects (font (size 1.27 1.27))))
|
||||
(number "CE_2401" (effects (font (size 0 0))))
|
||||
)
|
||||
(pin bidirectional line (at 15.24 2.54 180) (length 2.54)
|
||||
(name "CS_2401" (effects (font (size 1.27 1.27))))
|
||||
(number "CS_2401" (effects (font (size 0 0))))
|
||||
)
|
||||
(pin bidirectional line (at 15.24 0 180) (length 2.54)
|
||||
(name "CS_2500" (effects (font (size 1.27 1.27))))
|
||||
(number "CS_2500" (effects (font (size 0 0))))
|
||||
)
|
||||
(pin bidirectional line (at 15.24 5.08 180) (length 2.54)
|
||||
(name "CS_6936" (effects (font (size 1.27 1.27))))
|
||||
(number "CS_6936" (effects (font (size 0 0))))
|
||||
)
|
||||
(pin bidirectional line (at 15.24 -2.54 180) (length 2.54)
|
||||
(name "CS_7105" (effects (font (size 1.27 1.27))))
|
||||
(number "CS_7105" (effects (font (size 0 0))))
|
||||
)
|
||||
(pin power_in line (at 15.24 -10.16 180) (length 2.54)
|
||||
(name "GND" (effects (font (size 1.27 1.27))))
|
||||
(number "GND" (effects (font (size 0 0))))
|
||||
)
|
||||
(pin power_in line (at -15.24 17.78 0) (length 2.54)
|
||||
(name "GND@1" (effects (font (size 1.27 1.27))))
|
||||
(number "GND@1" (effects (font (size 0 0))))
|
||||
)
|
||||
(pin power_in line (at -15.24 15.24 0) (length 2.54)
|
||||
(name "GND@2" (effects (font (size 1.27 1.27))))
|
||||
(number "GND@2" (effects (font (size 0 0))))
|
||||
)
|
||||
(pin power_in line (at -15.24 5.08 0) (length 2.54)
|
||||
(name "GND@3" (effects (font (size 1.27 1.27))))
|
||||
(number "GND@3" (effects (font (size 0 0))))
|
||||
)
|
||||
(pin power_in line (at -15.24 0 0) (length 2.54)
|
||||
(name "GND@4" (effects (font (size 1.27 1.27))))
|
||||
(number "GND@4" (effects (font (size 0 0))))
|
||||
)
|
||||
(pin power_in line (at -15.24 -10.16 0) (length 2.54)
|
||||
(name "GND@5" (effects (font (size 1.27 1.27))))
|
||||
(number "GND@5" (effects (font (size 0 0))))
|
||||
)
|
||||
(pin power_in line (at -15.24 -12.7 0) (length 2.54)
|
||||
(name "GND@6" (effects (font (size 1.27 1.27))))
|
||||
(number "GND@6" (effects (font (size 0 0))))
|
||||
)
|
||||
(pin bidirectional line (at 15.24 12.7 180) (length 2.54)
|
||||
(name "MISO" (effects (font (size 1.27 1.27))))
|
||||
(number "MISO" (effects (font (size 0 0))))
|
||||
)
|
||||
(pin bidirectional line (at 15.24 10.16 180) (length 2.54)
|
||||
(name "MOSI" (effects (font (size 1.27 1.27))))
|
||||
(number "MOSI" (effects (font (size 0 0))))
|
||||
)
|
||||
(pin bidirectional line (at 15.24 -7.62 180) (length 2.54)
|
||||
(name "PE1" (effects (font (size 1.27 1.27))))
|
||||
(number "PE1" (effects (font (size 0 0))))
|
||||
)
|
||||
(pin bidirectional line (at 15.24 -5.08 180) (length 2.54)
|
||||
(name "PE2" (effects (font (size 1.27 1.27))))
|
||||
(number "PE2" (effects (font (size 0 0))))
|
||||
)
|
||||
(pin output line (at -15.24 2.54 0) (length 2.54)
|
||||
(name "RF" (effects (font (size 1.27 1.27))))
|
||||
(number "RF" (effects (font (size 0 0))))
|
||||
)
|
||||
(pin bidirectional line (at 15.24 15.24 180) (length 2.54)
|
||||
(name "RST_CYFR" (effects (font (size 1.27 1.27))))
|
||||
(number "RST_CYFR" (effects (font (size 0 0))))
|
||||
)
|
||||
(pin bidirectional line (at 15.24 7.62 180) (length 2.54)
|
||||
(name "SCK" (effects (font (size 1.27 1.27))))
|
||||
(number "SCK" (effects (font (size 0 0))))
|
||||
)
|
||||
(pin power_in line (at 15.24 -12.7 180) (length 2.54)
|
||||
(name "VCC" (effects (font (size 1.27 1.27))))
|
||||
(number "VCC" (effects (font (size 0 0))))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -0,0 +1,42 @@
|
||||
(footprint "DS-B01F-A-S2" (version 20211014) (generator pcbnew)
|
||||
(layer "F.Cu")
|
||||
(tedit 59FED5CC)
|
||||
(descr "Through hole straight pin header, 1x05, 2.54mm pitch, single row")
|
||||
(tags "Through hole pin header THT 1x05 2.54mm single row")
|
||||
(attr through_hole)
|
||||
(fp_text reference "REF**" (at -0.25 -4.75) (layer "F.SilkS")
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
(tstamp d518c7db-9a4d-4905-902c-7b6d95f659cb)
|
||||
)
|
||||
(fp_text value "DS-B01F-A-S2" (at 0 12.49) (layer "F.Fab")
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
(tstamp 614f538e-5f2b-401d-b0ab-3346d3ff44e4)
|
||||
)
|
||||
(fp_text user "${REFERENCE}" (at 0 5.08 90) (layer "F.Fab")
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
(tstamp 9586cda1-48da-45c7-86f7-751657e7c25a)
|
||||
)
|
||||
(fp_line (start -4.5 13.5) (end 1.25 13.5) (layer "F.SilkS") (width 0.12) (tstamp 05393a00-de07-40a8-8064-67c0a8a1e9ef))
|
||||
(fp_line (start 1.25 -3.5) (end 1.25 13.5) (layer "F.SilkS") (width 0.12) (tstamp 09bf1fa9-9ec6-4d5c-bed9-fcd1fe76bd8e))
|
||||
(fp_line (start -4.5 -3.5) (end 1.25 -3.5) (layer "F.SilkS") (width 0.12) (tstamp 2f1dd441-3cdc-4eed-9839-dc1fa6a931ba))
|
||||
(fp_line (start -4.5 -3.5) (end -4.5 13.5) (layer "F.SilkS") (width 0.12) (tstamp 35bb1bb5-998b-4ce9-a139-e009425d4e40))
|
||||
(fp_line (start -4.5 -3.5) (end -4.5 13.5) (layer "F.CrtYd") (width 0.05) (tstamp 346ee0d3-e13a-49f6-8f6c-eb860777d6c4))
|
||||
(fp_line (start 1.25 13.5) (end 1.25 -3.5) (layer "F.CrtYd") (width 0.05) (tstamp 93808e54-10fb-4c6c-984b-3a91c36dbafa))
|
||||
(fp_line (start 1.25 -3.5) (end -4.5 -3.5) (layer "F.CrtYd") (width 0.05) (tstamp d7a0888c-6be2-4a97-ac01-de345dcd2919))
|
||||
(fp_line (start -4.5 13.5) (end 1.25 13.5) (layer "F.CrtYd") (width 0.05) (tstamp ee85719d-9f71-411e-a024-43105a50c262))
|
||||
(fp_line (start -1.27 11.43) (end -1.27 -0.635) (layer "F.Fab") (width 0.1) (tstamp 085f4818-84f1-415f-823e-e6076d0e732d))
|
||||
(fp_line (start -1.27 -0.635) (end -0.635 -1.27) (layer "F.Fab") (width 0.1) (tstamp 602c4495-9f5f-4ae3-9800-df18526e3c50))
|
||||
(fp_line (start 1.27 -1.27) (end 1.27 11.43) (layer "F.Fab") (width 0.1) (tstamp 73eb4832-b804-463c-ae2b-563755d89978))
|
||||
(fp_line (start -0.635 -1.27) (end 1.27 -1.27) (layer "F.Fab") (width 0.1) (tstamp aed66e63-a453-441e-94eb-3442ef294c72))
|
||||
(fp_line (start 1.27 11.43) (end -1.27 11.43) (layer "F.Fab") (width 0.1) (tstamp dde86203-069d-47dc-8693-34fe614da099))
|
||||
(pad "1" thru_hole rect (at 0 0) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp 174ecd2f-6484-485c-a83d-71d6a1dc733a))
|
||||
(pad "2" thru_hole oval (at 0 2.5) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp 997a59d1-7e2b-4400-b74b-3cb21ad33038))
|
||||
(pad "3" thru_hole oval (at 0 5) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp 7aa5c04b-5bd3-4c72-bbaf-9ec87c5447e0))
|
||||
(pad "4" thru_hole oval (at 0 7.5) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp 8a6c42bd-bf44-40be-9e58-41dc76d10644))
|
||||
(pad "5" thru_hole oval (at 0 10) (size 1.7 1.7) (drill 1) (layers *.Cu *.Mask) (tstamp c1741286-ba0e-4f33-8f37-5fd51504bac5))
|
||||
(model "${KICAD6_3DMODEL_DIR}/Connector_PinHeader_2.54mm.3dshapes/PinHeader_1x05_P2.54mm_Vertical.wrl"
|
||||
(offset (xyz 0 0 0))
|
||||
(scale (xyz 1 1 1))
|
||||
(rotate (xyz 0 0 0))
|
||||
)
|
||||
)
|
||||
@@ -0,0 +1,60 @@
|
||||
(footprint "MULTIRF4IN1-SMT" (version 20211014) (generator pcbnew)
|
||||
(layer "F.Cu")
|
||||
(tedit 0)
|
||||
(fp_text reference "REF**" (at 0 -0.75) (layer "F.SilkS")
|
||||
(effects (font (size 1.27 1.27) (thickness 0.15)))
|
||||
(tstamp c70c9e03-6ffa-4ea8-9291-15d2673122a0)
|
||||
)
|
||||
(fp_text value "Val**" (at 0 1) (layer "F.Fab")
|
||||
(effects (font (size 1.27 1.27) (thickness 0.15)))
|
||||
(tstamp c3246ecf-81bc-4b14-94a2-7b86227cabaf)
|
||||
)
|
||||
(fp_line (start -13 11.9) (end -13 17) (layer "F.SilkS") (width 0.12) (tstamp 21d8aff3-5b17-43c7-9d08-4e33edbcbeb9))
|
||||
(fp_line (start -13 3.4) (end -13 8.1) (layer "F.SilkS") (width 0.12) (tstamp 4a2c9e01-3f0b-4116-a39b-baa7e7b94b8a))
|
||||
(fp_line (start -13 -8.1) (end -13 -2.4) (layer "F.SilkS") (width 0.12) (tstamp 960baeae-d7ca-4f76-ac15-6cd68f041702))
|
||||
(fp_line (start 13 -17) (end 13 -13.9) (layer "F.SilkS") (width 0.12) (tstamp a22c44ee-0c9a-42e0-81e0-94f90a0da388))
|
||||
(fp_line (start 13 11.9) (end 13 17) (layer "F.SilkS") (width 0.12) (tstamp a8050edb-a9eb-479e-abea-105077de87b8))
|
||||
(fp_line (start -13 -17) (end -13 -11.9) (layer "F.SilkS") (width 0.12) (tstamp dbeb96d9-bbc7-4dae-ba00-6746209bdc43))
|
||||
(fp_line (start 13 -17) (end -13 -17) (layer "F.SilkS") (width 0.12) (tstamp de173627-aedf-48e0-8674-66cfe17b969a))
|
||||
(fp_line (start 13 17) (end -13 17) (layer "F.SilkS") (width 0.12) (tstamp edb180b5-b35e-4fa4-8440-d021574908ae))
|
||||
(pad "CE_2401" smd rect (at 12.49 -13) (size 1.52 1.27) (layers "F.Cu" "F.Paste" "F.Mask")
|
||||
(solder_mask_margin 0.1) (tstamp 177c8408-9b8a-453c-871a-7a335239833a))
|
||||
(pad "CS_2401" smd rect (at 12.49 -1) (size 1.52 1.27) (layers "F.Cu" "F.Paste" "F.Mask")
|
||||
(solder_mask_margin 0.1) (tstamp deb3cbb7-c404-4161-b154-3014395e2a30))
|
||||
(pad "CS_2500" smd rect (at 12.49 1) (size 1.52 1.27) (layers "F.Cu" "F.Paste" "F.Mask")
|
||||
(solder_mask_margin 0.1) (tstamp e8ecba2d-0746-43bc-b641-9cc180ff9253))
|
||||
(pad "CS_6936" smd rect (at 12.49 -3) (size 1.52 1.27) (layers "F.Cu" "F.Paste" "F.Mask")
|
||||
(solder_mask_margin 0.1) (tstamp 90314976-271d-4f34-b2f0-dff6de6b86e7))
|
||||
(pad "CS_7105" smd rect (at 12.49 3) (size 1.52 1.27) (layers "F.Cu" "F.Paste" "F.Mask")
|
||||
(solder_mask_margin 0.1) (tstamp 1f154bf6-42ea-456f-89ac-fed01ff7208b))
|
||||
(pad "GND" smd rect (at 12.49 9) (size 1.52 1.27) (layers "F.Cu" "F.Paste" "F.Mask")
|
||||
(solder_mask_margin 0.1) (tstamp 14373cb3-8424-453e-b0d3-1a6022ea35b1))
|
||||
(pad "GND@1" smd rect (at -12.49 -11) (size 1.52 1.27) (layers "F.Cu" "F.Paste" "F.Mask")
|
||||
(solder_mask_margin 0.1) (tstamp b15a1378-3e57-41cb-96b2-030f4848402c))
|
||||
(pad "GND@2" smd rect (at -12.49 -9) (size 1.52 1.27) (layers "F.Cu" "F.Paste" "F.Mask")
|
||||
(solder_mask_margin 0.1) (tstamp 71e83330-d2fe-4680-bbc4-fbbb511ecf3d))
|
||||
(pad "GND@3" smd rect (at -12.49 -1.5) (size 1.52 1.27) (layers "F.Cu" "F.Paste" "F.Mask")
|
||||
(solder_mask_margin 0.1) (tstamp 27f29ad7-d4f7-416a-bc00-7c36c9ffbaca))
|
||||
(pad "GND@4" smd rect (at -12.49 2.5) (size 1.52 1.27) (layers "F.Cu" "F.Paste" "F.Mask")
|
||||
(solder_mask_margin 0.1) (tstamp 6b446947-9739-4960-abfc-ef89034a0437))
|
||||
(pad "GND@5" smd rect (at -12.49 9) (size 1.52 1.27) (layers "F.Cu" "F.Paste" "F.Mask")
|
||||
(solder_mask_margin 0.1) (tstamp 589b3137-9b71-4e00-93fe-63222c56ecc3))
|
||||
(pad "GND@6" smd rect (at -12.49 11) (size 1.52 1.27) (layers "F.Cu" "F.Paste" "F.Mask")
|
||||
(solder_mask_margin 0.1) (tstamp 371c3d69-e48f-46fb-a1b6-b681b17bacb1))
|
||||
(pad "MISO" smd rect (at 12.49 -9) (size 1.52 1.27) (layers "F.Cu" "F.Paste" "F.Mask")
|
||||
(solder_mask_margin 0.1) (tstamp a1ef8d67-bdf4-443e-88f7-406670c2aef9))
|
||||
(pad "MOSI" smd rect (at 12.49 -7) (size 1.52 1.27) (layers "F.Cu" "F.Paste" "F.Mask")
|
||||
(solder_mask_margin 0.1) (tstamp d9f5d5e2-2571-4cc2-800c-f5758bd5695f))
|
||||
(pad "PE1" smd rect (at 12.49 7) (size 1.52 1.27) (layers "F.Cu" "F.Paste" "F.Mask")
|
||||
(solder_mask_margin 0.1) (tstamp 06684ce2-c9de-48bf-9621-ada44ca8a12c))
|
||||
(pad "PE2" smd rect (at 12.49 5) (size 1.52 1.27) (layers "F.Cu" "F.Paste" "F.Mask")
|
||||
(solder_mask_margin 0.1) (tstamp bd470244-7da3-4d59-894b-19e4071da146))
|
||||
(pad "RF" smd rect (at -12.49 0.5) (size 1.52 1.27) (layers "F.Cu" "F.Paste" "F.Mask")
|
||||
(solder_mask_margin 0.1) (tstamp e91e6b83-902b-42be-92fa-6ac19487af54))
|
||||
(pad "RST_CYFR" smd rect (at 12.49 -11) (size 1.52 1.27) (layers "F.Cu" "F.Paste" "F.Mask")
|
||||
(solder_mask_margin 0.1) (tstamp dc86e8ca-1f6b-4f0d-9576-5c57346768bf))
|
||||
(pad "SCK" smd rect (at 12.49 -5) (size 1.52 1.27) (layers "F.Cu" "F.Paste" "F.Mask")
|
||||
(solder_mask_margin 0.1) (tstamp 483e384c-d6af-490d-b4f9-371490f0e46f))
|
||||
(pad "VCC" smd rect (at 12.49 11) (size 1.52 1.27) (layers "F.Cu" "F.Paste" "F.Mask")
|
||||
(solder_mask_margin 0.1) (tstamp 8796d68c-81fa-42ef-ace9-9d8c76827e59))
|
||||
)
|
||||
11745
STM32 PCB/Flysky PL18/PL18_multiprotocol/PL18_multiprotocol.kicad_pcb
Normal file
11745
STM32 PCB/Flysky PL18/PL18_multiprotocol/PL18_multiprotocol.kicad_pcb
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,75 @@
|
||||
{
|
||||
"board": {
|
||||
"active_layer": 0,
|
||||
"active_layer_preset": "All Layers",
|
||||
"auto_track_width": false,
|
||||
"hidden_nets": [],
|
||||
"high_contrast_mode": 0,
|
||||
"net_color_mode": 1,
|
||||
"opacity": {
|
||||
"pads": 1.0,
|
||||
"tracks": 1.0,
|
||||
"vias": 1.0,
|
||||
"zones": 0.6
|
||||
},
|
||||
"ratsnest_display_mode": 0,
|
||||
"selection_filter": {
|
||||
"dimensions": true,
|
||||
"footprints": true,
|
||||
"graphics": true,
|
||||
"keepouts": true,
|
||||
"lockedItems": true,
|
||||
"otherItems": true,
|
||||
"pads": true,
|
||||
"text": true,
|
||||
"tracks": true,
|
||||
"vias": true,
|
||||
"zones": true
|
||||
},
|
||||
"visible_items": [
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
8,
|
||||
9,
|
||||
10,
|
||||
11,
|
||||
12,
|
||||
13,
|
||||
14,
|
||||
15,
|
||||
16,
|
||||
17,
|
||||
18,
|
||||
19,
|
||||
20,
|
||||
21,
|
||||
22,
|
||||
23,
|
||||
24,
|
||||
25,
|
||||
26,
|
||||
27,
|
||||
28,
|
||||
29,
|
||||
30,
|
||||
32,
|
||||
33,
|
||||
34,
|
||||
35,
|
||||
36
|
||||
],
|
||||
"visible_layers": "fffffff_ffffffff",
|
||||
"zone_display_mode": 0
|
||||
},
|
||||
"meta": {
|
||||
"filename": "PL18_multiprotocol.kicad_prl",
|
||||
"version": 3
|
||||
},
|
||||
"project": {
|
||||
"files": []
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,462 @@
|
||||
{
|
||||
"board": {
|
||||
"design_settings": {
|
||||
"defaults": {
|
||||
"board_outline_line_width": 0.09999999999999999,
|
||||
"copper_line_width": 0.19999999999999998,
|
||||
"copper_text_italic": false,
|
||||
"copper_text_size_h": 1.5,
|
||||
"copper_text_size_v": 1.5,
|
||||
"copper_text_thickness": 0.3,
|
||||
"copper_text_upright": false,
|
||||
"courtyard_line_width": 0.049999999999999996,
|
||||
"dimension_precision": 4,
|
||||
"dimension_units": 3,
|
||||
"dimensions": {
|
||||
"arrow_length": 1270000,
|
||||
"extension_offset": 500000,
|
||||
"keep_text_aligned": true,
|
||||
"suppress_zeroes": false,
|
||||
"text_position": 0,
|
||||
"units_format": 1
|
||||
},
|
||||
"fab_line_width": 0.09999999999999999,
|
||||
"fab_text_italic": false,
|
||||
"fab_text_size_h": 1.0,
|
||||
"fab_text_size_v": 1.0,
|
||||
"fab_text_thickness": 0.15,
|
||||
"fab_text_upright": false,
|
||||
"other_line_width": 0.15,
|
||||
"other_text_italic": false,
|
||||
"other_text_size_h": 1.0,
|
||||
"other_text_size_v": 1.0,
|
||||
"other_text_thickness": 0.15,
|
||||
"other_text_upright": false,
|
||||
"pads": {
|
||||
"drill": 0.762,
|
||||
"height": 1.524,
|
||||
"width": 1.524
|
||||
},
|
||||
"silk_line_width": 0.15,
|
||||
"silk_text_italic": false,
|
||||
"silk_text_size_h": 1.0,
|
||||
"silk_text_size_v": 1.0,
|
||||
"silk_text_thickness": 0.15,
|
||||
"silk_text_upright": false,
|
||||
"zones": {
|
||||
"45_degree_only": false,
|
||||
"min_clearance": 0.19999999999999998
|
||||
}
|
||||
},
|
||||
"diff_pair_dimensions": [
|
||||
{
|
||||
"gap": 0.0,
|
||||
"via_gap": 0.0,
|
||||
"width": 0.0
|
||||
}
|
||||
],
|
||||
"drc_exclusions": [
|
||||
"copper_edge_clearance|34900000|34735000|785ef911-e457-413e-ac63-cf1535b242cb|be0d3c71-0f5b-45b9-9c9b-72866af0f7a2",
|
||||
"copper_edge_clearance|34900000|36735000|785ef911-e457-413e-ac63-cf1535b242cb|e7b16a25-ec09-4bb5-aa09-fe00038c1f1f",
|
||||
"copper_edge_clearance|34900000|38735000|785ef911-e457-413e-ac63-cf1535b242cb|e65ad8dc-91cb-4c5d-b0fe-169b84ac0b55",
|
||||
"copper_edge_clearance|34900000|40735000|785ef911-e457-413e-ac63-cf1535b242cb|95287391-9e27-4475-a375-0f63337ce67a",
|
||||
"copper_edge_clearance|34900000|42735000|785ef911-e457-413e-ac63-cf1535b242cb|c29c966c-91b2-4b36-b1bc-6673192d38fe",
|
||||
"copper_edge_clearance|34900000|44735000|785ef911-e457-413e-ac63-cf1535b242cb|4f24c66e-64cb-408b-9295-97d993d96225",
|
||||
"copper_edge_clearance|34900000|46735000|785ef911-e457-413e-ac63-cf1535b242cb|0ddbf31e-bbeb-43d6-ae3b-cab85e65b36d",
|
||||
"copper_edge_clearance|34900000|48735000|785ef911-e457-413e-ac63-cf1535b242cb|4dcf731f-2949-4865-b539-ff1e637244c5",
|
||||
"copper_edge_clearance|34900000|50735000|785ef911-e457-413e-ac63-cf1535b242cb|34e18046-0932-48eb-854b-3707688a2215",
|
||||
"copper_edge_clearance|34900000|52735000|785ef911-e457-413e-ac63-cf1535b242cb|5c40c44b-70c5-4c30-aafc-a4724555cbb1",
|
||||
"copper_edge_clearance|34900000|54735000|785ef911-e457-413e-ac63-cf1535b242cb|bb59f967-af06-40a4-adc7-d38dcc40fc54",
|
||||
"copper_edge_clearance|34900000|56735000|785ef911-e457-413e-ac63-cf1535b242cb|27057d15-87f3-4a5e-bab7-6c1fa0d1954f",
|
||||
"copper_edge_clearance|34900000|58735000|785ef911-e457-413e-ac63-cf1535b242cb|13a669d2-833b-4c54-a87d-44fb38d91e82",
|
||||
"copper_edge_clearance|61100000|36735000|b1556ea3-f1cc-4201-b942-480142bd0c54|5bd3edee-4a1d-4d5f-8aae-d7afd4bced8c",
|
||||
"copper_edge_clearance|61100000|38735000|b1556ea3-f1cc-4201-b942-480142bd0c54|2bcfc76b-5219-4cb8-b24e-4fb83ce73dfb",
|
||||
"copper_edge_clearance|61100000|46235000|b1556ea3-f1cc-4201-b942-480142bd0c54|ad1d31a9-5733-4b73-be03-a80ca4f16773",
|
||||
"copper_edge_clearance|61100000|48235000|b1556ea3-f1cc-4201-b942-480142bd0c54|0967fce8-8cdb-4026-bedd-d620a9cd0bad",
|
||||
"copper_edge_clearance|61100000|50235000|b1556ea3-f1cc-4201-b942-480142bd0c54|7aa764ba-7abe-485a-b859-ce8f0595e5cd",
|
||||
"copper_edge_clearance|61100000|56735000|b1556ea3-f1cc-4201-b942-480142bd0c54|7dbb4403-9304-4fc0-8912-17af08ce6248",
|
||||
"copper_edge_clearance|61100000|58735000|b1556ea3-f1cc-4201-b942-480142bd0c54|425646f1-4301-496a-bd77-d52b64168923"
|
||||
],
|
||||
"meta": {
|
||||
"version": 2
|
||||
},
|
||||
"rule_severities": {
|
||||
"annular_width": "error",
|
||||
"clearance": "error",
|
||||
"copper_edge_clearance": "error",
|
||||
"courtyards_overlap": "error",
|
||||
"diff_pair_gap_out_of_range": "error",
|
||||
"diff_pair_uncoupled_length_too_long": "error",
|
||||
"drill_out_of_range": "error",
|
||||
"duplicate_footprints": "warning",
|
||||
"extra_footprint": "warning",
|
||||
"footprint_type_mismatch": "error",
|
||||
"hole_clearance": "error",
|
||||
"hole_near_hole": "error",
|
||||
"invalid_outline": "error",
|
||||
"item_on_disabled_layer": "error",
|
||||
"items_not_allowed": "error",
|
||||
"length_out_of_range": "error",
|
||||
"malformed_courtyard": "error",
|
||||
"microvia_drill_out_of_range": "error",
|
||||
"missing_courtyard": "ignore",
|
||||
"missing_footprint": "warning",
|
||||
"net_conflict": "warning",
|
||||
"npth_inside_courtyard": "ignore",
|
||||
"padstack": "error",
|
||||
"pth_inside_courtyard": "ignore",
|
||||
"shorting_items": "error",
|
||||
"silk_over_copper": "warning",
|
||||
"silk_overlap": "warning",
|
||||
"skew_out_of_range": "error",
|
||||
"through_hole_pad_without_hole": "error",
|
||||
"too_many_vias": "error",
|
||||
"track_dangling": "warning",
|
||||
"track_width": "error",
|
||||
"tracks_crossing": "error",
|
||||
"unconnected_items": "error",
|
||||
"unresolved_variable": "error",
|
||||
"via_dangling": "warning",
|
||||
"zone_has_empty_net": "error",
|
||||
"zones_intersect": "error"
|
||||
},
|
||||
"rules": {
|
||||
"allow_blind_buried_vias": false,
|
||||
"allow_microvias": false,
|
||||
"max_error": 0.005,
|
||||
"min_clearance": 0.0,
|
||||
"min_copper_edge_clearance": 0.0,
|
||||
"min_hole_clearance": 0.25,
|
||||
"min_hole_to_hole": 0.25,
|
||||
"min_microvia_diameter": 0.19999999999999998,
|
||||
"min_microvia_drill": 0.09999999999999999,
|
||||
"min_silk_clearance": 0.0,
|
||||
"min_through_hole_diameter": 0.3,
|
||||
"min_track_width": 0.19999999999999998,
|
||||
"min_via_annular_width": 0.049999999999999996,
|
||||
"min_via_diameter": 0.39999999999999997,
|
||||
"solder_mask_clearance": 0.0,
|
||||
"solder_mask_min_width": 0.0,
|
||||
"use_height_for_length_calcs": true
|
||||
},
|
||||
"track_widths": [
|
||||
0.0,
|
||||
0.4,
|
||||
0.6,
|
||||
0.603595,
|
||||
1.0
|
||||
],
|
||||
"via_dimensions": [
|
||||
{
|
||||
"diameter": 0.0,
|
||||
"drill": 0.0
|
||||
},
|
||||
{
|
||||
"diameter": 1.2,
|
||||
"drill": 0.6
|
||||
}
|
||||
],
|
||||
"zones_allow_external_fillets": false,
|
||||
"zones_use_no_outline": true
|
||||
},
|
||||
"layer_presets": []
|
||||
},
|
||||
"boards": [],
|
||||
"cvpcb": {
|
||||
"equivalence_files": []
|
||||
},
|
||||
"erc": {
|
||||
"erc_exclusions": [],
|
||||
"meta": {
|
||||
"version": 0
|
||||
},
|
||||
"pin_map": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
2,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
2,
|
||||
1,
|
||||
1,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
2,
|
||||
1,
|
||||
2,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
2,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
2,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
2,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
2,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2
|
||||
]
|
||||
],
|
||||
"rule_severities": {
|
||||
"bus_definition_conflict": "error",
|
||||
"bus_entry_needed": "error",
|
||||
"bus_label_syntax": "error",
|
||||
"bus_to_bus_conflict": "error",
|
||||
"bus_to_net_conflict": "error",
|
||||
"different_unit_footprint": "error",
|
||||
"different_unit_net": "error",
|
||||
"duplicate_reference": "error",
|
||||
"duplicate_sheet_names": "error",
|
||||
"extra_units": "error",
|
||||
"global_label_dangling": "warning",
|
||||
"hier_label_mismatch": "error",
|
||||
"label_dangling": "error",
|
||||
"lib_symbol_issues": "warning",
|
||||
"multiple_net_names": "warning",
|
||||
"net_not_bus_member": "warning",
|
||||
"no_connect_connected": "warning",
|
||||
"no_connect_dangling": "warning",
|
||||
"pin_not_connected": "error",
|
||||
"pin_not_driven": "error",
|
||||
"pin_to_pin": "warning",
|
||||
"power_pin_not_driven": "error",
|
||||
"similar_labels": "warning",
|
||||
"unannotated": "error",
|
||||
"unit_value_mismatch": "error",
|
||||
"unresolved_variable": "error",
|
||||
"wire_dangling": "error"
|
||||
}
|
||||
},
|
||||
"libraries": {
|
||||
"pinned_footprint_libs": [],
|
||||
"pinned_symbol_libs": []
|
||||
},
|
||||
"meta": {
|
||||
"filename": "PL18_multiprotocol.kicad_pro",
|
||||
"version": 1
|
||||
},
|
||||
"net_settings": {
|
||||
"classes": [
|
||||
{
|
||||
"bus_width": 12.0,
|
||||
"clearance": 0.2,
|
||||
"diff_pair_gap": 0.25,
|
||||
"diff_pair_via_gap": 0.25,
|
||||
"diff_pair_width": 0.2,
|
||||
"line_style": 0,
|
||||
"microvia_diameter": 0.3,
|
||||
"microvia_drill": 0.1,
|
||||
"name": "Default",
|
||||
"pcb_color": "rgba(0, 0, 0, 0.000)",
|
||||
"schematic_color": "rgba(0, 0, 0, 0.000)",
|
||||
"track_width": 0.25,
|
||||
"via_diameter": 0.8,
|
||||
"via_drill": 0.4,
|
||||
"wire_width": 6.0
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"version": 2
|
||||
},
|
||||
"net_colors": null
|
||||
},
|
||||
"pcbnew": {
|
||||
"last_paths": {
|
||||
"gencad": "",
|
||||
"idf": "",
|
||||
"netlist": "",
|
||||
"specctra_dsn": "",
|
||||
"step": "",
|
||||
"vrml": ""
|
||||
},
|
||||
"page_layout_descr_file": ""
|
||||
},
|
||||
"schematic": {
|
||||
"annotate_start_num": 0,
|
||||
"drawing": {
|
||||
"default_line_thickness": 6.0,
|
||||
"default_text_size": 50.0,
|
||||
"field_names": [],
|
||||
"intersheets_ref_own_page": false,
|
||||
"intersheets_ref_prefix": "",
|
||||
"intersheets_ref_short": false,
|
||||
"intersheets_ref_show": false,
|
||||
"intersheets_ref_suffix": "",
|
||||
"junction_size_choice": 3,
|
||||
"label_size_ratio": 0.375,
|
||||
"pin_symbol_size": 25.0,
|
||||
"text_offset_ratio": 0.15
|
||||
},
|
||||
"legacy_lib_dir": "",
|
||||
"legacy_lib_list": [],
|
||||
"meta": {
|
||||
"version": 1
|
||||
},
|
||||
"net_format_name": "",
|
||||
"ngspice": {
|
||||
"fix_include_paths": true,
|
||||
"fix_passive_vals": false,
|
||||
"meta": {
|
||||
"version": 0
|
||||
},
|
||||
"model_mode": 0,
|
||||
"workbook_filename": ""
|
||||
},
|
||||
"page_layout_descr_file": "",
|
||||
"plot_directory": "",
|
||||
"spice_adjust_passive_values": false,
|
||||
"spice_external_command": "spice \"%I\"",
|
||||
"subpart_first_id": 65,
|
||||
"subpart_id_separator": 0
|
||||
},
|
||||
"sheets": [
|
||||
[
|
||||
"e6b36db3-d652-4d66-bbfe-8c61f998d4b2",
|
||||
""
|
||||
]
|
||||
],
|
||||
"text_variables": {}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
86052
STM32 PCB/Flysky PL18/PL18_multiprotocol/fp-info-cache
Normal file
86052
STM32 PCB/Flysky PL18/PL18_multiprotocol/fp-info-cache
Normal file
File diff suppressed because it is too large
Load Diff
3
STM32 PCB/Flysky PL18/PL18_multiprotocol/fp-lib-table
Normal file
3
STM32 PCB/Flysky PL18/PL18_multiprotocol/fp-lib-table
Normal file
@@ -0,0 +1,3 @@
|
||||
(fp_lib_table
|
||||
(lib (name "Multi")(type "KiCad")(uri "${KIPRJMOD}/Multi.pretty")(options "")(descr ""))
|
||||
)
|
||||
3
STM32 PCB/Flysky PL18/PL18_multiprotocol/sym-lib-table
Normal file
3
STM32 PCB/Flysky PL18/PL18_multiprotocol/sym-lib-table
Normal file
@@ -0,0 +1,3 @@
|
||||
(sym_lib_table
|
||||
(lib (name "Multi")(type "KiCad")(uri "${KIPRJMOD}/Multi.kicad_sym")(options "")(descr ""))
|
||||
)
|
||||
5
STM32 PCB/Flysky PL18/README.md
Normal file
5
STM32 PCB/Flysky PL18/README.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# MPM for Flysky PL18
|
||||
|
||||
The PCB design is located in PL18_multiprotocol folder and is designed using KiCad 6.0.
|
||||
|
||||
The casing is located in Casing folder and is designed using Blender 3.3.1. The model included 2 pieces, T is the top piece and B is the bottom pieces. These 2 pieces is cloned into TF and BF respectively to apply all modifiers and make manifold for 3D printing. I have included the stl files generated for simplity.
|
||||
@@ -9,11 +9,11 @@ getMultiVersion() {
|
||||
}
|
||||
|
||||
getAllRFModules() {
|
||||
if [[ "$BOARD" =~ "multi4in1:avr:multixmega32d4" ]]; then
|
||||
if [[ "$BOARD" =~ ":avr:multixmega32d4" ]]; then
|
||||
ALL_RFMODULES=$(echo CYRF6936_INSTALLED);
|
||||
elif [[ "$BOARD" =~ "multi4in1:avr:multiatmega328p:" ]]; then
|
||||
elif [[ "$BOARD" =~ ":avr:multiatmega328p:" ]]; then
|
||||
ALL_RFMODULES=$(echo A7105_INSTALLED CYRF6936_INSTALLED CC2500_INSTALLED NRF24L01_INSTALLED);
|
||||
elif [[ "$BOARD" =~ "multi4in1:STM32F1:" ]]; then
|
||||
elif [[ "$BOARD" =~ ":STM32F1:" ]]; then
|
||||
ALL_RFMODULES=$(echo A7105_INSTALLED CYRF6936_INSTALLED CC2500_INSTALLED NRF24L01_INSTALLED SX1276_INSTALLED);
|
||||
fi
|
||||
}
|
||||
@@ -26,11 +26,11 @@ getAllProtocols() {
|
||||
CCNRF_PROTOCOLS=$(sed -n 's/[\/\/]*[[:blank:]]*#define[[:blank:]]*\([[:alnum:]_]*_CCNRF_INO\)\(.*\)/\1/p' Multiprotocol/_Config.h)
|
||||
SX1276_PROTOCOLS=$(sed -n 's/[\/\/]*[[:blank:]]*#define[[:blank:]]*\([[:alnum:]_]*_SX1276_INO\)\(.*\)/\1/p' Multiprotocol/_Config.h)
|
||||
|
||||
if [[ "$BOARD" =~ "multi4in1:avr:multixmega32d4" ]]; then
|
||||
if [[ "$BOARD" =~ ":avr:multixmega32d4" ]]; then
|
||||
ALL_PROTOCOLS=$(echo $CYRF6936_PROTOCOLS);
|
||||
elif [[ "$BOARD" =~ "multi4in1:avr:multiatmega328p:" ]]; then
|
||||
elif [[ "$BOARD" =~ ":avr:multiatmega328p:" ]]; then
|
||||
ALL_PROTOCOLS=$(echo $A7105_PROTOCOLS $CC2500_PROTOCOLS $CYRF6936_PROTOCOLS $NRF24L01_PROTOCOLS $CCNRF_PROTOCOLS);
|
||||
elif [[ "$BOARD" =~ "multi4in1:STM32F1:" ]]; then
|
||||
elif [[ "$BOARD" =~ ":STM32F1:" ]]; then
|
||||
ALL_PROTOCOLS=$(echo $A7105_PROTOCOLS $CC2500_PROTOCOLS $CYRF6936_PROTOCOLS $NRF24L01_PROTOCOLS $CCNRF_PROTOCOLS $SX1276_PROTOCOLS);
|
||||
fi
|
||||
}
|
||||
@@ -84,21 +84,21 @@ buildEachRFModule() {
|
||||
}
|
||||
|
||||
buildReleaseFiles(){
|
||||
if [[ "$BOARD" == "multi4in1:avr:multixmega32d4" ]]; then
|
||||
if [[ "$BOARD" =~ ":avr:multixmega32d4" ]]; then
|
||||
build_release_orx;
|
||||
elif [[ "$BOARD" == "multi4in1:avr:multiatmega328p:bootloader=none" ]]; then
|
||||
elif [[ "$BOARD" =~ ":avr:multiatmega328p:bootloader=none" ]]; then
|
||||
build_release_avr_noboot;
|
||||
elif [[ "$BOARD" == "multi4in1:avr:multiatmega328p:bootloader=optiboot" ]]; then
|
||||
elif [[ "$BOARD" =~ ":avr:multiatmega328p:bootloader=optiboot" ]]; then
|
||||
build_release_avr_optiboot;
|
||||
elif [[ "$BOARD" == "multi4in1:STM32F1:multistm32f103cb:debug_option=none" ]]; then
|
||||
elif [[ "$BOARD" =~ ":STM32F1:multistm32f103cb:debug_option=none" ]]; then
|
||||
build_release_stm32f1_no_debug;
|
||||
elif [[ "$BOARD" == "multi4in1:STM32F1:multistm32f103cb:debug_option=native" ]]; then
|
||||
elif [[ "$BOARD" =~ ":STM32F1:multistm32f103cb:debug_option=native" ]]; then
|
||||
build_release_stm32f1_native_debug;
|
||||
elif [[ "$BOARD" == "multi4in1:STM32F1:multistm32f103cb:debug_option=ftdi" ]]; then
|
||||
elif [[ "$BOARD" =~ ":STM32F1:multistm32f103cb:debug_option=ftdi" ]]; then
|
||||
build_release_stm32f1_serial_debug;
|
||||
elif [[ "$BOARD" == "multi4in1:STM32F1:multi5in1t18int" ]]; then
|
||||
elif [[ "$BOARD" =~ ":STM32F1:multi5in1t18int" ]]; then
|
||||
build_release_stm32f1_t18int;
|
||||
elif [[ "$BOARD" == "multi4in1:STM32F1:multistm32f103c8:debug_option=none" ]]; then
|
||||
elif [[ "$BOARD" =~ ":STM32F1:multistm32f103c8:debug_option=none" ]]; then
|
||||
build_release_stm32f1_64k;
|
||||
else
|
||||
printf "No release files for this board.";
|
||||
|
||||
@@ -20,6 +20,7 @@ Multiprotocol modules can be flashed with a precompiled firmware file (Option 1
|
||||
1. [USB Port](#usb-port)
|
||||
1. [USB-to-Serial adapter](#usb-to-serial-adapter)
|
||||
1. [Upload the firmware](#upload-the-firmware)
|
||||
1. [Option 4 - Flash via USB, using dfu-util (on Linux)](#option-4---flash-via-usb-using-dfu-util-on-linux)
|
||||
1. [Troubleshooting](#troubleshooting)
|
||||
|
||||
## Tools required
|
||||
@@ -172,6 +173,98 @@ In order to flash the bootloader the **BOOT0** jumper must be installed connecti
|
||||
### Upload the firmware
|
||||
1. In the Arduino IDE click **Sketch -> Upload**, or press **Ctrl+U**
|
||||
|
||||
## Option 4 - Flash via USB, using dfu-util (on Linux)
|
||||
|
||||
This upgrade method is only for modules that have USB connectors and
|
||||
that have the ability to enter DFU mode when plugged into a Linux
|
||||
machine.
|
||||
|
||||
[dfu-util](http://dfu-util.sourceforge.net/) is a command line tool that
|
||||
can be used to write firmware to a processor that is in the DFU
|
||||
state. Pre-built dfu-util packages are available for almost any Linux
|
||||
distribution, so simply install the dfu-util package via your system's
|
||||
package manager.
|
||||
|
||||
You now need to get your multimodule connected to your Linux machine
|
||||
and make sure that it is in DFU mode. Usually the multimodule should
|
||||
enter the DFU mode if you remove it from your radio and simply connect
|
||||
it to your Linux machine via a _proper_ USB cable. Note: Some cheap,
|
||||
loading USB cables sometimes have no data lines connected, and these
|
||||
will no work.
|
||||
|
||||
Once your multimodule is connected, run the following command in order
|
||||
to see if the DFU interface had been discovered:
|
||||
|
||||
```shell
|
||||
|
||||
# dfu-util -l -v
|
||||
dfu-util 0.11
|
||||
|
||||
Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
|
||||
Copyright 2010-2021 Tormod Volden and Stefan Schmidt
|
||||
This program is Free Software and has ABSOLUTELY NO WARRANTY
|
||||
Please report bugs to http://sourceforge.net/p/dfu-util/tickets/
|
||||
|
||||
libusb version 1.0.26 (11724)
|
||||
Found DFU: [1eaf:0003] ver=0201, devnum=69, cfg=1, intf=0, path="1-4", alt=2, name="STM32duino bootloader v1.0 Upload to Flash 0x8002000", serial="LLM 003"
|
||||
Found DFU: [1eaf:0003] ver=0201, devnum=69, cfg=1, intf=0, path="1-4", alt=1, name="STM32duino bootloader v1.0 Upload to Flash 0x8005000", serial="LLM 003"
|
||||
Found DFU: [1eaf:0003] ver=0201, devnum=69, cfg=1, intf=0, path="1-4", alt=0, name="STM32duino bootloader v1.0 ERROR. Upload to RAM not supported.", serial="LLM 003"
|
||||
```
|
||||
|
||||
If you the above didn't succeed, your module is not in DFU mode and it
|
||||
would not make any sense to continue.
|
||||
|
||||
Now that your Linux machine discovered the device with id, 1eaf:0003,
|
||||
you can can start the update process, which will take around 8 to 10
|
||||
seconds. Once done, your multimodule will be updated and you can
|
||||
simply unplug it and start using it.
|
||||
|
||||
The example below, uses a pre-compiled binary available from
|
||||
[here](https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/releases).
|
||||
|
||||
```shell
|
||||
|
||||
# dfu-util -v -R -a 2 -d 1EAF:0003 -D mm-stm-serial-aetr-v1.3.3.14.bin
|
||||
dfu-util 0.11
|
||||
|
||||
Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
|
||||
Copyright 2010-2021 Tormod Volden and Stefan Schmidt
|
||||
This program is Free Software and has ABSOLUTELY NO WARRANTY
|
||||
Please report bugs to http://sourceforge.net/p/dfu-util/tickets/
|
||||
|
||||
libusb version 1.0.26 (11724)
|
||||
dfu-util: Warning: Invalid DFU suffix signature
|
||||
dfu-util: A valid DFU suffix will be required in a future dfu-util release
|
||||
Opening DFU capable USB device...
|
||||
Device ID 1eaf:0003
|
||||
Device DFU version 0110
|
||||
DFU attributes: (0x03) bitCanDnload bitCanUpload
|
||||
Detach timeout 255 ms
|
||||
Claiming USB DFU Interface...
|
||||
Setting Alternate Interface #2 ...
|
||||
Determining device status...
|
||||
DFU state(2) = dfuIDLE, status(0) = No error condition is present
|
||||
DFU mode device DFU version 0110
|
||||
Device returned transfer size 1024
|
||||
Copying data from PC to DFU device
|
||||
Download [=========================] 100% 118668 bytes
|
||||
Download done.
|
||||
Sent a total of 118668 bytes
|
||||
DFU state(8) = dfuMANIFEST-WAIT-RESET, status(0) = No error condition is present
|
||||
Resetting USB to switch back to runtime mode
|
||||
Done!
|
||||
```
|
||||
|
||||
NOTE: The above command was taken and adapted from
|
||||
[here](https://github.com/benlye/flash-multi/blob/master/doc/Troubleshooting.md).
|
||||
|
||||
As you can see, the above process is really extremely straight
|
||||
forward. You basically only need to have dfu-util installed and you need to
|
||||
run one single command for updating your multimodule.
|
||||
|
||||
As a bonus, the dfu-util method could also be used under Mac or
|
||||
Windows, as dfu-util binaries also exist for those operating systems.
|
||||
|
||||
# Troubleshooting
|
||||
You can report your problem using the [GitHub issue](https://github.com/midelic/DIY-Multiprotocol-TX-Module/issues) system or go to the [Main thread on RCGROUPS](http://www.rcgroups.com/forums/showthread.php?t=2165676) to ask your question.
|
||||
Please provide the following information:
|
||||
|
||||
Reference in New Issue
Block a user