Compare commits

..

36 Commits

Author SHA1 Message Date
Pascal Langer
5b8a08ab22 OMP: added telemetry 2020-09-18 16:13:45 +02:00
Ben Lye
313b03fb84 Disable PPM/serial in builds as needed 2020-09-17 10:13:00 +01:00
Pascal Langer
5639def6fb Update DSM FwdPrg.lua 2020-09-15 12:05:26 +02:00
Pascal Langer
15a254879c DSM_RX: bind with other radio modules off 2020-09-15 12:03:16 +02:00
pascallanger
5baa9bd256 Update README.md 2020-09-13 11:34:23 +02:00
Pascal Langer
d5346c0eaf Add DISABLE_FLASH_SIZE_CHECK 2020-09-09 16:47:32 +02:00
Pascal Langer
a2213fd6dc DSM Forward Programming: work in progress 2020-09-09 10:45:14 +02:00
Pascal Langer
9b07f12f90 AFHDS2A: add sub proto 2020-09-08 08:49:38 +02:00
Pascal Langer
c9b49483e0 NanoRF 2020-09-07 22:58:37 +02:00
Pascal Langer
e2972a5823 AFHDS2A: enable 16 channels on SBUS 2020-09-07 20:31:47 +02:00
Pascal Langer
d5b3ed832d Update Multiprotocol.ino 2020-09-04 10:59:31 +02:00
Pascal Langer
9fcc030c15 STM32: test flash size 2020-09-04 10:39:30 +02:00
pascallanger
fc81b7ee5a Update Protocols_Details.md 2020-09-03 17:28:54 +02:00
Pascal Langer
f168abc2bb Fixed frame size 2020-08-31 22:21:21 +02:00
pascallanger
fe6778635e Add Realacc R11 protocol 2020-08-30 14:57:56 +02:00
Pascal Langer
65a6c19d02 OMP doc 2020-08-30 14:35:44 +02:00
pascallanger
a32b5561a1 Update Protocols_Details.md 2020-08-30 14:30:28 +02:00
pascallanger
4b4393952e Update README.md 2020-08-24 14:41:10 +02:00
Pascal Langer
ea205b1e69 Bayanf: fix telemetry batt 2020-08-20 19:00:06 +02:00
pascallanger
748140cdee Update Protocols_Details.md 2020-08-18 12:02:08 +02:00
Pascal Langer
e8037c857f OMP fixes 2020-08-17 08:26:42 +02:00
Pascal Langer
15e37cefee OMP: fix? 2020-08-16 18:48:40 +02:00
Pascal Langer
b1e4daf1c2 OMP: new protocol intial release
Untested!!!
2020-08-15 16:17:18 +02:00
Pascal Langer
4e0fccfc63 Update Protocols_Details.md 2020-08-14 19:40:25 +02:00
Pascal Langer
48b90029c4 V761: Work with any ID. Tested on Eachine RX. 2020-08-14 19:39:24 +02:00
Pascal Langer
8b189af2f9 R9: small change 2020-08-13 21:21:34 +02:00
Pascal Langer
030cdd35a2 Update REALACC_nrf24l01.ino 2020-08-11 00:02:19 +02:00
Pascal Langer
3789998ba9 Update ZSX_nrf24l01.ino 2020-08-10 23:54:51 +02:00
Pascal Langer
ea24ab6032 New protocol Realacc 2020-08-10 23:54:33 +02:00
Pascal Langer
1408431649 XN297Dump: increase the number of RF channels to look for 2020-08-10 22:52:50 +02:00
Pascal Langer
6810372064 RadioLink: enable Range test mode 2020-08-10 20:30:19 +02:00
Pascal Langer
708e2ac5f6 V761 bug fix: the model was not reconnecting unless you did a bind first 2020-08-07 15:18:15 +02:00
Pascal Langer
2178f6761d RadioLink: update A2=Batt telemetry value 2020-08-07 15:11:59 +02:00
Pascal Langer
aa5fd82004 Update FrSky_Rx_cc2500.ino 2020-08-05 09:50:40 +02:00
Pascal Langer
660282db2e RX protocols: abort RX bind as requested 2020-08-04 10:42:35 +02:00
Ben Lye
fdd357619b Fix folder structure inside LUA script zip file 2020-08-03 22:39:10 +01:00
26 changed files with 1327 additions and 98 deletions

View File

@@ -49,10 +49,10 @@ before_install:
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/multi-orangerx-aetr-blue-inv-v$MULTI_VERSION.bin;
cp Multiprotocol/Multi.txt ./binaries/Multi.txt;
mkdir -p TOOLS/SCRIPTS;
cp Lua_scripts/*.lua TOOLS/SCRIPTS/;
cp Lua_scripts/*.txt TOOLS/SCRIPTS/;
zip ./binaries/MultiLuaScripts.zip TOOLS/SCRIPTS/*;
mkdir -p SCRIPTS/TOOLS;
cp Lua_scripts/*.lua SCRIPTS/TOOLS/;
cp Lua_scripts/*.txt SCRIPTS/TOOLS/;
zip ./binaries/MultiLuaScripts.zip SCRIPTS/TOOLS/*;
return $exitcode; };
elif [[ "$BOARD" == "multi4in1:avr:multiatmega328p:bootloader=none" ]]; then
buildReleaseFiles(){
@@ -106,6 +106,7 @@ before_install:
printf "\n\e[33;1mBuilding multi-stm-erskytx-aetr-inv-v$MULTI_VERSION.bin\e[0m";
exitcode=0;
opt_enable CHECK_FOR_BOOTLOADER;
opt_disable ENABLE_PPM;
opt_enable $ALL_PROTOCOLS;
opt_enable MULTI_STATUS;
opt_disable MULTI_TELEMETRY;
@@ -173,6 +174,8 @@ before_install:
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-opentx-reta-noinv-v$MULTI_VERSION.bin;
printf "\n\e[33;1mBuilding multi-stm-ppm-aetr-noinv-v$MULTI_VERSION.bin\e[0m";
opt_enable ENABLE_PPM;
opt_disable ENABLE_SERIAL;
opt_replace RETA AETR;
opt_disable MULTI_STATUS;
opt_disable MULTI_TELEMETRY;
@@ -238,6 +241,7 @@ before_install:
elif [[ "$BOARD" == "multi4in1:STM32F1:multi5in1t18int" ]]; then
buildReleaseFiles(){
printf "\n\e[33;1mBuilding multi-t18int-opentx-aetr-noinv-v$MULTI_VERSION.bin\e[0m";
opt_disable ENABLE_PPM;
opt_disable INVERT_TELEMETRY;
exitcode=0;
buildMulti;

557
Lua_scripts/DSM FwdPrg.lua Normal file
View File

@@ -0,0 +1,557 @@
local toolName = "TNS|DSM Forward Programming|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 = 0, 1, 2, 3, 4, 5, 6, 7
local MENU, LIST_MENU_NOCHANGING, LIST_MENU2, PERCENTAGE_VALUE = 0x1C, 0x6C, 0x4C, 0xC0
local Phase = RX_VERSION
local Waiting_RX = 0
local Text = {}
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="" }
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 DSM_Release()
multiBuffer( 0, 0 )
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_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 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 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 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,Menu.CurLine) -- 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,Menu.SelLine,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,Menu.SelLine,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,Menu.SelLine) -- 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,Menu.SelLine)
end
multiBuffer(10,0x00);
Retry = 50
elseif multiBuffer(10) == 0x09 then
-- Answer received
--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_Text(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
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=>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_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 ~= 0x1C then -- 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
Menu.CurLine = multiBuffer(14)
Line[Menu.CurLine].Val = conv_int16(multiBuffer(16)+multiBuffer(17)*256)
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) == 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 ~= 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
--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_MENU2 then
text = Get_Text(Line[i].Val+Line[i].Def)
elseif Line[i].Type == PERCENTAGE_VALUE then
text = Line[i].Val.." %"
else
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, 48, 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, 48, 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, 48, 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') )
--Text to be displayed -> need to use a file instead?
--RX names--
Text[0x0014]="SPM4651T"
Text[0x0015]="AR637T"
--Lists--
Text[0x0036]="Throttle"
Text[0x0037]="Aileron"
Text[0x0038]="Elevator"
Text[0x0039]="Rudder"
Text[0x003A]="Gear"
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
Text[0x004A]="Failsafe"
Text[0x004B]="Main Menu"
Text[0x004E]="Position"
Text[0x0050]="Outputs"
--Text[0x005E]="Inhibit"
Text[0x005F]="Hold Last"
Text[0x0060]="Preset"
--Text[0x0061]="Custom"
--Messages--
Text[0x0090]="Apply"
Text[0x0093]="Complete"
Text[0x0094]="Done"
Text[0x0097]="Factory Reset"
Text[0x009A]="Capture Failsafe Positions"
Text[0x009C]="Custom Failsafe"
Text[0x00A5]="First Time Setup"
Text[0x00F9]="Gyro settings"
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[0x0104]=""
Text[0x0105]=""
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[0x010A]=""
Text[0x010B]=""
Text[0x019C]="Enter Receiver Bind Mode"
Text[0x020A]="Restore from Backup"
Text[0x0209]="Save to Backup"
Text[0x021A]="Set the model level,"
Text[0x021B]="and press Continue."
Text[0x021C]=""
Text[0x021D]=""
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[0x0229]="Set Orientation Manually"
Text[0x0227]="Other settings"
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]=""
Text[0x0231]="This will overwrite the"
Text[0x0232]="backup memory with your"
Text[0x0233]="current configuartion."
Text[0x0234]=""
Text[0x0235]=""
Text[0x0236]="This will overwrite the"
Text[0x0237]="current config with"
Text[0x0238]="that which is in"
Text[0x0239]="the backup memory."
Text[0x023A]=""
end
-- Main
local function DSM_Run(event)
if event == nil then
error("Cannot be run as a model script!")
return 2
elseif event == EVT_VIRTUAL_EXIT then
DSM_Release()
return 2
else
DSM_Menu(event)
DSM_Send_Receive()
DSM_Display()
return 0
end
end
return { init=DSM_Init, run=DSM_Run }

View File

@@ -123,6 +123,7 @@
17,3,MT99XX,LS,1,Flip,Invert,Pict,Video,HLess
17,4,MT99XX,FY805,1,Flip,n-a,n-a,n-a,HLess
44,0,NCC1701,Std,1,Warp
77,0,OMP,M2,0,THold,IdleUp,6G_3D
60,0,Pelikan,PRO_V4,0,CH5,CH6,CH7,CH8
60,1,Pelikan,LITE_V4,0,CH5,CH6,CH7,CH8
51,0,Potensic,A20,1,TakLan,Emerg,Mode,HLess
@@ -135,10 +136,11 @@
31,2,Q303,CX10D,1,Arm,Flip
31,3,Q303,CX10WD,1,Arm,Flip
72,0,Q90C,Std,0,FMode,VTX+
50,0,Redpine,Fast,0,sCH5,sCH6,sCH7,sCH8,sCH9,sCH10,sCH11,sCH12,sCH13,sCH14,sCH15,sCH16
50,1,Redpine,Slow,0,sCH5,sCH6,sCH7,sCH8,sCH9,sCH10,sCH11,sCH12,sCH13,sCH14,sCH15,sCH16
74,0,RadioLink,Surface,0,CH5,CH6,CH7,CH8,FS_CH1,FS_CH2,FS_CH3,FS_CH4,FS_CH5,FS_CH6,FS_CH7,FS_CH8
74,1,RadioLink,Air,0,CH5,CH6,CH7,CH8,FS_CH1,FS_CH2,FS_CH3,FS_CH4,FS_CH5,FS_CH6,FS_CH7,FS_CH8
76,0,Realacc,R11,1,Flip,Light,Calib,HLess,RTH,UNK
50,0,Redpine,Fast,0,sCH5,sCH6,sCH7,sCH8,sCH9,sCH10,sCH11,sCH12,sCH13,sCH14,sCH15,sCH16
50,1,Redpine,Slow,0,sCH5,sCH6,sCH7,sCH8,sCH9,sCH10,sCH11,sCH12,sCH13,sCH14,sCH15,sCH16
21,0,SFHSS,Std,0,CH5,CH6,CH7,CH8
19,0,Shenqi,Cycle,1
68,0,Skyartec,Std,0,CH5,CH6,CH7

View File

@@ -28,7 +28,7 @@ Enable text configuration of the HoTT RX and sensors: Vario, GPS, ESC, GAM and E
Need OpenTX 2.3.9 or above. Located on the radio SD card under \SCRIPTS\TOOLS.
Notes:
- Menu is used to cycle through the detected sensors.
- Menu/MDL/Model is used to cycle through the detected sensors.
- It's normal to lose the telemetry feed while using the text mode configuration. Telemetry will resume properly if the script is exited by doing a short press on the exit button.
[![Text mode video](https://img.youtube.com/vi/81wd8NlF3Qw/0.jpg)](https://www.youtube.com/watch?v=81wd8NlF3Qw)

View File

@@ -104,6 +104,7 @@ uint16_t AFHDS2A_Rx_callback()
switch(phase) {
case AFHDS2A_RX_BIND1:
if(IS_BIND_DONE) return initAFHDS2A_Rx(); // Abort bind
if (AFHDS2A_Rx_data_ready()) {
A7105_ReadData(AFHDS2A_RX_TXPACKET_SIZE);
if ((packet[0] == 0xbb && packet[9] == 0x01) || (packet[0] == 0xbc && packet[9] <= 0x02)) {
@@ -118,6 +119,7 @@ uint16_t AFHDS2A_Rx_callback()
return 10000;
case AFHDS2A_RX_BIND2:
if(IS_BIND_DONE) return initAFHDS2A_Rx(); // Abort bind
// got 2nd bind packet from tx ?
if (AFHDS2A_Rx_data_ready()) {
A7105_ReadData(AFHDS2A_RX_TXPACKET_SIZE);
@@ -143,6 +145,7 @@ uint16_t AFHDS2A_Rx_callback()
packet[9] = 0x01;
packet[10] = 0x00;
memset(&packet[11], 0xFF, 26);
A7105_SetTxRxMode(TX_EN);
A7105_WriteData(AFHDS2A_RX_RXPACKET_SIZE, packet_count++ & 1 ? 0x0D : 0x8C);
phase |= AFHDS2A_RX_WAIT_WRITE;
return 1700;
@@ -153,6 +156,7 @@ uint16_t AFHDS2A_Rx_callback()
while (micros() - pps_timer < 700) // Wait max 700µs, using serial+telemetry exit in about 120µs
if (!(A7105_ReadReg(A7105_00_MODE) & 0x01))
break;
A7105_SetTxRxMode(RX_EN);
A7105_Strobe(A7105_RX);
phase &= ~AFHDS2A_RX_WAIT_WRITE;
return 10000;

View File

@@ -129,6 +129,7 @@ uint16_t Bayang_Rx_callback()
switch (phase) {
case BAYANG_RX_BIND:
if(IS_BIND_DONE) return initBayang_Rx(); // Abort bind
if (NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR)) {
// data received from TX
if (XN297_ReadPayload(packet, BAYANG_RX_PACKET_SIZE) && ( packet[0] == 0xA4 || packet[0] == 0xA2 ) && Bayang_Rx_check_validity()) {

View File

@@ -221,9 +221,9 @@ static void __attribute__((unused)) BAYANG_check_rx(void)
if (packet[0] == 0x85 && packet[14] == check)
{
// uncompensated battery volts*100/2
v_lipo1 = (packet[3]<<7) + (packet[4]>>2);
v_lipo1 = (packet[3]<<7) + (packet[4]>>1);
// compensated battery volts*100/2
v_lipo2 = (packet[5]<<7) + (packet[6]>>2);
v_lipo2 = (packet[5]<<7) + (packet[6]>>1);
// reception in packets / sec
RX_LQI = packet[7];
RX_RSSI = RX_LQI;

View File

@@ -17,6 +17,8 @@
#include "iface_cyrf6936.h"
//#define DSM_DEBUG_FWD_PGM
//#define DSM_GR300
#define DSM_BIND_CHANNEL 0x0d //13 This can be any odd channel
@@ -151,6 +153,7 @@ static void __attribute__((unused)) DSM_build_data_packet(uint8_t upper)
if(sub_protocol==DSM2_22)
bits=10; // Only DSM2_22 is using a resolution of 1024
}
#ifdef DSM_THROTTLE_KILL_CH
uint16_t kill_ch=Channel_data[DSM_THROTTLE_KILL_CH-1];
#endif
@@ -189,6 +192,23 @@ static void __attribute__((unused)) DSM_build_data_packet(uint8_t upper)
packet[i*2+2] = (value >> 8) & 0xff;
packet[i*2+3] = (value >> 0) & 0xff;
}
#ifdef DSM_FWD_PGM
if(upper==0 && DSM_SerialRX && (DSM_SerialRX_val[0]&0xF8)==0x70 )
{ // Send forward programming data if available
for(uint8_t i=0; i<(DSM_SerialRX_val[0]&0x07);i++)
{
packet[i*2+4]=0x70+i;
packet[i*2+5]=DSM_SerialRX_val[i+1];
}
DSM_SerialRX=false;
#ifdef DSM_DEBUG_FWD_PGM
debug("FWD=");
for(uint8_t i=4; i<16;i++)
debug(" %02X",packet[i]);
debugln("");
#endif
}
#endif
}
static uint8_t __attribute__((unused)) DSM_Check_RX_packet()
@@ -307,9 +327,9 @@ uint16_t ReadDsm()
telemetry_set_input_sync(11000); // Always request 11ms spacing even if we don't use half of it in 22ms mode
#endif
case DSM_CH1_WRITE_B:
DSM_build_data_packet(phase == DSM_CH1_WRITE_B); // build lower or upper channels
case DSM_CH2_WRITE_A:
case DSM_CH2_WRITE_B:
DSM_build_data_packet(phase == DSM_CH1_WRITE_B||phase == DSM_CH2_WRITE_B); // build lower or upper channels
CYRF_ReadRegister(CYRF_04_TX_IRQ_STATUS); // clear IRQ flags
CYRF_WriteDataPacket(packet);
#if 0
@@ -368,6 +388,15 @@ uint16_t ReadDsm()
if(len>TELEMETRY_BUFFER_SIZE-2)
len=TELEMETRY_BUFFER_SIZE-2;
CYRF_ReadDataPacketLen(packet_in+1, len);
#ifdef DSM_DEBUG_FWD_PGM
//debug(" %02X", packet_in[1]);
if(packet_in[1]==9)
{
for(uint8_t i=0;i<len;i++)
debug(" %02X", packet_in[i+1]);
debugln("");
}
#endif
packet_in[0]=CYRF_ReadRegister(CYRF_13_RSSI)&0x1F;// store RSSI of the received telemetry signal
telemetry_link=1;
}

View File

@@ -207,7 +207,8 @@ uint16_t initFrSkyR9()
SX1276_SetHopPeriod(0); // 0 = disabled, we hop frequencies manually
SX1276_SetPaDac(true);
SX1276_SetTxRxMode(TX_EN); // Set RF switch to TX
//Enable all IRQ flags
SX1276_WriteReg(SX1276_11_IRQFLAGSMASK,0x00);
FrSkyX_telem_init();
hopping_frequency_no=0;
@@ -256,6 +257,8 @@ uint16_t FrSkyR9_callback()
SX1276_WriteReg(SX1276_0D_FIFOADDRPTR, 0x00);
//Set RF switch to RX
SX1276_SetTxRxMode(RX_EN);
//Clear all IRQ flags
SX1276_WriteReg(SX1276_12_REGIRQFLAGS,0xFF);
//Switch to RX
SX1276_WriteReg(SX1276_01_OPMODE, 0x85);
phase++;
@@ -294,8 +297,6 @@ uint16_t FrSkyR9_callback()
FrSkyX_telem_init(); // Reset telemetry
else
telemetry_link=1; // Send telemetry out anyway
//Clear all flags
SX1276_WriteReg(SX1276_12_REGIRQFLAGS,0xFF);
phase=FRSKYR9_FREQ;
break;
#endif

View File

@@ -358,7 +358,6 @@ static void __attribute__((unused)) frsky_rx_data()
uint16_t initFrSky_Rx()
{
state = 0;
frsky_rx_chanskip = 1;
hopping_frequency_no = 0;
rx_data_started = false;
@@ -383,6 +382,8 @@ uint16_t FrSky_Rx_callback()
static int8_t tune_low, tune_high;
uint8_t len, ch;
if(IS_BIND_DONE && phase != FRSKY_RX_DATA) return initFrSky_Rx(); // Abort bind
if ((prev_option != option) && (phase >= FRSKY_RX_DATA))
{
if (option == 0)
@@ -412,6 +413,7 @@ uint16_t FrSky_Rx_callback()
phase = FRSKY_RX_TUNE_LOW;
debugln("FRSKY_RX_TUNE_LOW");
frsky_rx_strobe_rx();
state = 0;
return 1000;
}
}
@@ -483,7 +485,7 @@ uint16_t FrSky_Rx_callback()
}
}
else
state=0x3FF; //No hop table for D16v2
state = 0x3FF; //No hop table for D16v2
if (state == 0x3FF)
{
debugln("Bind complete");

View File

@@ -71,4 +71,7 @@
71,JJRC345
72,Q90C
73,Kyosho
74,RadioLink,Surface
74,RadioLink,Surface,Air
75,---
76,Realacc,R11
77,OMP

View File

@@ -88,8 +88,10 @@ const char STR_PROPEL[] ="Propel";
const char STR_SKYARTEC[] ="Skyartc";
const char STR_KYOSHO[] ="Kyosho";
const char STR_RLINK[] ="RadLink";
const char STR_REALACC[] ="Realacc";
const char STR_OMP[] ="OMP";
const char STR_TEST[] ="Test";
const char STR_FAKE[] ="Fake";
const char STR_NANORF[] ="NanoRF";
const char STR_SUBTYPE_FLYSKY[] = "\x04""Std\0""V9x9""V6x6""V912""CX20";
const char STR_SUBTYPE_HUBSAN[] = "\x04""H107""H301""H501";
@@ -110,7 +112,7 @@ const char STR_SUBTYPE_MT99[] = "\x06""MT99\0 ""H7\0 ""YZ\0 ""LS\0 "
const char STR_SUBTYPE_MJXQ[] = "\x07""WLH08\0 ""X600\0 ""X800\0 ""H26D\0 ""E010\0 ""H26WH\0 ""Phoenix";
const char STR_SUBTYPE_FY326[] = "\x05""Std\0 ""FY319";
const char STR_SUBTYPE_HONTAI[] = "\x07""Std\0 ""JJRC X1""X5C1\0 ""FQ_951";
const char STR_SUBTYPE_AFHDS2A[] = "\x08""PWM,IBUS""PPM,IBUS""PWM,SBUS""PPM,SBUS""PWM,IB16""PPM,IB16";
const char STR_SUBTYPE_AFHDS2A[] = "\x08""PWM,IBUS""PPM,IBUS""PWM,SBUS""PPM,SBUS""PWM,IB16""PPM,IB16""PWM,SB16""PPM,SB16";
const char STR_SUBTYPE_Q2X2[] = "\x04""Q222""Q242""Q282";
const char STR_SUBTYPE_WK2x01[] = "\x06""WK2801""WK2401""W6_5_1""W6_6_1""W6_HeL""W6_HeI";
const char STR_SUBTYPE_Q303[] = "\x06""Std\0 ""CX35\0 ""CX10D\0""CX10WD";
@@ -142,6 +144,7 @@ const char STR_SUBTYPE_HOTT[] = "\x07""Sync\0 ""No_Sync";
const char STR_SUBTYPE_PELIKAN[] = "\x04""Pro\0""Lite";
const char STR_SUBTYPE_V761[] = "\x03""3ch""4ch";
const char STR_SUBTYPE_RLINK[] = "\x07""Surface""Air\0 ";
const char STR_SUBTYPE_REALACC[] = "\x03""R11";
enum
{
@@ -219,13 +222,13 @@ const mm_protocol_definition multi_protocols[] = {
{PROTO_FLYSKY, STR_FLYSKY, 5, STR_SUBTYPE_FLYSKY, OPTION_NONE },
#endif
#if defined(AFHDS2A_A7105_INO)
{PROTO_AFHDS2A, STR_AFHDS2A, 6, STR_SUBTYPE_AFHDS2A, OPTION_SRVFREQ },
{PROTO_AFHDS2A, STR_AFHDS2A, 8, STR_SUBTYPE_AFHDS2A, OPTION_SRVFREQ },
#endif
#if defined(AFHDS2A_RX_A7105_INO)
{PROTO_AFHDS2A_RX, STR_AFHDS2A_RX,0, NO_SUBTYPE, OPTION_NONE },
#endif
#if defined(HEIGHT_A7105_INO)
{PROTO_HEIGHT, STR_HEIGHT, 2, STR_SUBTYPE_HEIGHT, OPTION_NONE },
{PROTO_HEIGHT, STR_HEIGHT, 2, STR_SUBTYPE_HEIGHT, OPTION_NONE },
#endif
#if defined(FQ777_NRF24L01_INO)
{PROTO_FQ777, STR_FQ777, 0, NO_SUBTYPE, OPTION_NONE },
@@ -305,6 +308,9 @@ const mm_protocol_definition multi_protocols[] = {
#if defined(NCC1701_NRF24L01_INO)
{PROTO_NCC1701, STR_NCC1701, 0, NO_SUBTYPE, OPTION_NONE },
#endif
#if defined(OMP_CC2500_INO)
{PROTO_OMP, STR_OMP, 0, NO_SUBTYPE, OPTION_RFTUNE },
#endif
#if defined(PELIKAN_A7105_INO)
{PROTO_PELIKAN, STR_PELIKAN , 2, STR_SUBTYPE_PELIKAN, OPTION_NONE },
#endif
@@ -323,12 +329,15 @@ const mm_protocol_definition multi_protocols[] = {
#if defined(Q90C_NRF24L01_INO)
{PROTO_Q90C, STR_Q90C, 0, NO_SUBTYPE, OPTION_RFTUNE },
#endif
#if defined(REDPINE_CC2500_INO)
{PROTO_REDPINE, STR_REDPINE, 2, STR_SUBTYPE_REDPINE, OPTION_RFTUNE },
#endif
#if defined(RLINK_CC2500_INO)
{PROTO_RLINK, STR_RLINK, 2, STR_SUBTYPE_RLINK, OPTION_RFTUNE },
#endif
#if defined(REALACC_NRF24L01_INO)
{PROTO_REALACC, STR_REALACC, 1, STR_SUBTYPE_REALACC, OPTION_NONE },
#endif
#if defined(REDPINE_CC2500_INO)
{PROTO_REDPINE, STR_REDPINE, 2, STR_SUBTYPE_REDPINE, OPTION_RFTUNE },
#endif
#if defined(SCANNER_CC2500_INO)
// {PROTO_SCANNER, STR_SCANNER, 0, NO_SUBTYPE, OPTION_NONE },
#endif
@@ -383,8 +392,8 @@ const mm_protocol_definition multi_protocols[] = {
#if defined(TEST_CC2500_INO)
{PROTO_TEST, STR_TEST, 0, NO_SUBTYPE, OPTION_RFTUNE },
#endif
#if defined(FAKE_NRF24L01_INO)
{PROTO_FAKE, STR_FAKE, 0, NO_SUBTYPE, OPTION_NONE },
#if defined(NANORF_NRF24L01_INO)
{PROTO_NANORF, STR_NANORF, 0, NO_SUBTYPE, OPTION_NONE },
#endif
{0x00, nullptr, 0, nullptr, 0 }
};

View File

@@ -19,7 +19,7 @@
#define VERSION_MAJOR 1
#define VERSION_MINOR 3
#define VERSION_REVISION 1
#define VERSION_PATCH_LEVEL 49
#define VERSION_PATCH_LEVEL 65
//******************
// Protocols
@@ -101,8 +101,10 @@ enum PROTOCOLS
PROTO_Q90C = 72, // =>NRF24L01 or CC2500
PROTO_KYOSHO = 73, // =>A7105
PROTO_RLINK = 74, // =>CC2500
PROTO_REALACC = 76, // =>NRF24L01
PROTO_OMP = 77, // =>CC2500 & NRF24L01
PROTO_FAKE = 126, // =>CC2500+NRF24L01
PROTO_NANORF = 126, // =>NRF24L01
PROTO_TEST = 127, // =>CC2500
};
@@ -602,17 +604,17 @@ enum {
};
// A7105 power
// Power amp is ~+16dBm so:
// The numbers do not take into account any outside amplifier
enum A7105_POWER
{
A7105_POWER_0 = 0x00<<3 | 0x00, // TXPOWER_100uW = -23dBm == PAC=0 TBG=0
A7105_POWER_1 = 0x00<<3 | 0x01, // TXPOWER_300uW = -20dBm == PAC=0 TBG=1
A7105_POWER_2 = 0x00<<3 | 0x02, // TXPOWER_1mW = -16dBm == PAC=0 TBG=2
A7105_POWER_3 = 0x00<<3 | 0x04, // TXPOWER_3mW = -11dBm == PAC=0 TBG=4
A7105_POWER_4 = 0x01<<3 | 0x05, // TXPOWER_10mW = -6dBm == PAC=1 TBG=5
A7105_POWER_5 = 0x02<<3 | 0x07, // TXPOWER_30mW = 0dBm == PAC=2 TBG=7
A7105_POWER_6 = 0x03<<3 | 0x07, // TXPOWER_100mW = 1dBm == PAC=3 TBG=7
A7105_POWER_7 = 0x03<<3 | 0x07 // TXPOWER_150mW = 1dBm == PAC=3 TBG=7
A7105_POWER_0 = 0x00<<3 | 0x00, // -23dBm == PAC=0 TBG=0
A7105_POWER_1 = 0x00<<3 | 0x01, // -20dBm == PAC=0 TBG=1
A7105_POWER_2 = 0x00<<3 | 0x02, // -16dBm == PAC=0 TBG=2
A7105_POWER_3 = 0x00<<3 | 0x04, // -11dBm == PAC=0 TBG=4
A7105_POWER_4 = 0x01<<3 | 0x05, // -6dBm == PAC=1 TBG=5
A7105_POWER_5 = 0x02<<3 | 0x07, // 0dBm == PAC=2 TBG=7
A7105_POWER_6 = 0x03<<3 | 0x07, // +1dBm == PAC=3 TBG=7
A7105_POWER_7 = 0x03<<3 | 0x07 // +1dBm == PAC=3 TBG=7
};
#define A7105_HIGH_POWER A7105_POWER_7
#define A7105_LOW_POWER A7105_POWER_3
@@ -620,14 +622,13 @@ enum A7105_POWER
#define A7105_BIND_POWER A7105_POWER_0
// NRF Power
// Power setting is 0..3 for nRF24L01
// Claimed power amp for nRF24L01 from eBay is 20dBm.
// The numbers do not take into account any outside amplifier
enum NRF_POWER
{ // Raw w 20dBm PA
NRF_POWER_0 = 0x00, // 0 : -18dBm (16uW) 2dBm (1.6mW)
NRF_POWER_1 = 0x01, // 1 : -12dBm (60uW) 8dBm (6mW)
NRF_POWER_2 = 0x02, // 2 : -6dBm (250uW) 14dBm (25mW)
NRF_POWER_3 = 0x03 // 3 : 0dBm (1mW) 20dBm (100mW)
{
NRF_POWER_0 = 0x00, // -18dBm
NRF_POWER_1 = 0x01, // -12dBm
NRF_POWER_2 = 0x02, // -6dBm
NRF_POWER_3 = 0x03 // 0dBm
};
#define NRF_HIGH_POWER NRF_POWER_3
#define NRF_LOW_POWER NRF_POWER_1
@@ -664,6 +665,7 @@ enum CC2500_POWER
#define CC2500_BIND_POWER CC2500_POWER_1
// CYRF power
// The numbers do not take into account any outside amplifier
enum CYRF_POWER
{
CYRF_POWER_0 = 0x00, // -35dbm
@@ -809,6 +811,8 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
Q90C 72
KYOSHO 73
RLINK 74
REALACC 76
OMP 77
BindBit=> 0x80 1=Bind/0=No
AutoBindBit=> 0x40 1=Yes /0=No
RangeCheck=> 0x20 1=Yes /0=No
@@ -1028,6 +1032,7 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
FrSkyX and FrSkyX2: Stream[27] during bind Telem on=0x00,off=0x01 | CH1-8=0x00,CH9-16=0x02
FrSkyX and FrSkyX2: Stream[27..34] during normal operation unstuffed SPort data to be sent
HoTT: Stream[27] 1 byte for telemetry type
DSM: Stream[27..33] Forward Programming
*/
/*
Multimodule Status

View File

@@ -256,6 +256,10 @@ uint8_t packet_in[TELEMETRY_BUFFER_SIZE];//telemetry receiving packets
uint8_t HoTT_SerialRX_val=0;
bool HoTT_SerialRX=false;
#endif
#ifdef DSM_FWD_PGM
uint8_t DSM_SerialRX_val[7];
bool DSM_SerialRX=false;
#endif
#endif // TELEMETRY
// Callback
@@ -311,6 +315,7 @@ void setup()
#elif defined STM32_BOARD
//STM32
afio_cfg_debug_ports(AFIO_DEBUG_NONE);
pinMode(LED_pin,OUTPUT);
pinMode(LED2_pin,OUTPUT);
pinMode(A7105_CSN_pin,OUTPUT);
pinMode(CC25_CSN_pin,OUTPUT);
@@ -364,6 +369,38 @@ void setup()
//Timers
init_HWTimer(); //0.5us
//Read module flash size
#ifndef DISABLE_FLASH_SIZE_CHECK
unsigned short *flashSize = (unsigned short *) (0x1FFFF7E0);// Address register
debugln("Module Flash size: %dKB",(int)(*flashSize & 0xffff));
if((int)(*flashSize & 0xffff) < 128) // Not supported by this project
while (true) { //SOS
for(uint8_t i=0; i<3;i++)
{
LED_on;
delay(100);
LED_off;
delay(100);
}
for(uint8_t i=0; i<3;i++)
{
LED_on;
delay(500);
LED_off;
delay(100);
}
for(uint8_t i=0; i<3;i++)
{
LED_on;
delay(100);
LED_off;
delay(100);
}
LED_off;
delay(1000);
}
#endif
#else
//ATMEGA328p
// all inputs
@@ -502,7 +539,7 @@ void setup()
MProtocol_id_master=random_id(EEPROM_ID_OFFSET,false);
debugln("Module Id: %lx", MProtocol_id_master);
#ifdef ENABLE_PPM
//Protocol and interrupts initialization
if(mode_select != MODE_SERIAL)
@@ -773,7 +810,7 @@ bool Update_All()
update_led_status();
#if defined(TELEMETRY)
#if ( !( defined(MULTI_TELEMETRY) || defined(MULTI_STATUS) ) )
if((protocol == PROTO_BAYANG_RX) || (protocol == PROTO_AFHDS2A_RX) || (protocol == PROTO_FRSKY_RX) || (protocol == PROTO_SCANNER) || (protocol==PROTO_FRSKYD) || (protocol==PROTO_BAYANG) || (protocol==PROTO_NCC1701) || (protocol==PROTO_BUGS) || (protocol==PROTO_BUGSMINI) || (protocol==PROTO_HUBSAN) || (protocol==PROTO_AFHDS2A) || (protocol==PROTO_FRSKYX) || (protocol==PROTO_FRSKYX2) || (protocol==PROTO_DSM) || (protocol==PROTO_CABELL) || (protocol==PROTO_HITEC) || (protocol==PROTO_HOTT) || (protocol==PROTO_PROPEL) || (protocol==PROTO_DEVO) || (protocol==PROTO_DSM_RX) || (protocol==PROTO_FRSKY_R9) || (protocol==PROTO_RLINK))
if((protocol == PROTO_BAYANG_RX) || (protocol == PROTO_AFHDS2A_RX) || (protocol == PROTO_FRSKY_RX) || (protocol == PROTO_SCANNER) || (protocol==PROTO_FRSKYD) || (protocol==PROTO_BAYANG) || (protocol==PROTO_NCC1701) || (protocol==PROTO_BUGS) || (protocol==PROTO_BUGSMINI) || (protocol==PROTO_HUBSAN) || (protocol==PROTO_AFHDS2A) || (protocol==PROTO_FRSKYX) || (protocol==PROTO_FRSKYX2) || (protocol==PROTO_DSM) || (protocol==PROTO_CABELL) || (protocol==PROTO_HITEC) || (protocol==PROTO_HOTT) || (protocol==PROTO_PROPEL) || (protocol==PROTO_OMP) || (protocol==PROTO_DEVO) || (protocol==PROTO_DSM_RX) || (protocol==PROTO_FRSKY_R9) || (protocol==PROTO_RLINK))
#endif
if(IS_DISABLE_TELEM_off)
TelemetryUpdate();
@@ -1598,16 +1635,28 @@ static void protocol_init()
remote_callback = Q90C_callback;
break;
#endif
#if defined(REALACC_NRF24L01_INO)
case PROTO_REALACC:
next_callback=initREALACC();
remote_callback = REALACC_callback;
break;
#endif
#if defined(OMP_CC2500_INO)
case PROTO_OMP:
next_callback=initOMP();
remote_callback = OMP_callback;
break;
#endif
#if defined(TEST_CC2500_INO)
case PROTO_TEST:
next_callback=initTEST();
remote_callback = TEST_callback;
break;
#endif
#if defined(FAKE_NRF24L01_INO)
case PROTO_FAKE:
next_callback=initFAKE();
remote_callback = FAKE_callback;
#if defined(NANORF_NRF24L01_INO)
case PROTO_NANORF:
next_callback=initNANORF();
remote_callback = NANORF_callback;
break;
#endif
#endif
@@ -1915,7 +1964,7 @@ void update_serial_data()
}
#endif
#ifdef SPORT_SEND
if((protocol==PROTO_FRSKYX || protocol==PROTO_FRSKYX2 || protocol==PROTO_FRSKY_R9) && rx_len==35)
if((protocol==PROTO_FRSKYX || protocol==PROTO_FRSKYX2 || protocol==PROTO_FRSKY_R9) && rx_len==27+8)
{//Protocol waiting for 8 bytes
#define BYTE_STUFF 0x7D
#define STUFF_MASK 0x20
@@ -1959,12 +2008,19 @@ void update_serial_data()
}
#endif //SPORT_SEND
#ifdef HOTT_FW_TELEMETRY
if(protocol==PROTO_HOTT && rx_len==28)
if(protocol==PROTO_HOTT && rx_len==27+1)
{//Protocol waiting for 1 byte
HoTT_SerialRX_val=rx_ok_buff[27];
HoTT_SerialRX=true;
}
#endif
#ifdef DSM_FWD_PGM
if(protocol==PROTO_DSM && rx_len==27+7)
{//Protocol waiting for 7 bytes
memcpy(DSM_SerialRX_val, (const void *)&rx_ok_buff[27],7);
DSM_SerialRX=true;
}
#endif
}
RX_DONOTUPDATE_off;
@@ -2209,7 +2265,7 @@ void pollBoot()
#if defined(TELEMETRY)
void PPM_Telemetry_serial_init()
{
if( (protocol==PROTO_FRSKYD) || (protocol==PROTO_HUBSAN) || (protocol==PROTO_AFHDS2A) || (protocol==PROTO_BAYANG)|| (protocol==PROTO_NCC1701) || (protocol==PROTO_CABELL) || (protocol==PROTO_HITEC) || (protocol==PROTO_BUGS) || (protocol==PROTO_BUGSMINI) || (protocol==PROTO_PROPEL) || (protocol==PROTO_RLINK)
if( (protocol==PROTO_FRSKYD) || (protocol==PROTO_HUBSAN) || (protocol==PROTO_AFHDS2A) || (protocol==PROTO_BAYANG)|| (protocol==PROTO_NCC1701) || (protocol==PROTO_CABELL) || (protocol==PROTO_HITEC) || (protocol==PROTO_BUGS) || (protocol==PROTO_BUGSMINI) || (protocol==PROTO_PROPEL) || (protocol==PROTO_OMP) || (protocol==PROTO_RLINK)
#ifdef TELEMETRY_FRSKYX_TO_FRSKYD
|| (protocol==PROTO_FRSKYX) || (protocol==PROTO_FRSKYX2)
#endif
@@ -2472,7 +2528,7 @@ static void __attribute__((unused)) calc_fh_channels(uint8_t num_ch)
ISR(TIMER1_COMPB_vect)
#endif
{ // Timer1 compare B interrupt
if(rx_idx>=26 && rx_idx<RXBUFFER_SIZE)
if(rx_idx>=26 && rx_idx<=RXBUFFER_SIZE)
{
// A full frame has been received
if(!IS_RX_DONOTUPDATE_on)
@@ -2491,7 +2547,7 @@ static void __attribute__((unused)) calc_fh_channels(uint8_t num_ch)
}
#ifdef DEBUG_SERIAL
else
debugln("RX frame too short");
debugln("RX frame size incorrect");
#endif
discard_frame=true;
#ifdef STM32_BOARD

View File

@@ -0,0 +1,73 @@
/*
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(NANORF_NRF24L01_INO)
#include "iface_nrf24l01.h"
#define NANORF_PACKET_PERIOD 40000
#define NANORF_INITIAL_WAIT 500
#define NANORF_RF_CHANNEL 40
#define NANORF_PAYLOADSIZE 7
static void __attribute__((unused)) NANORF_send_packet()
{
packet[0] = convert_channel_8b(AILERON);
packet[1] = convert_channel_8b(ELEVATOR);
packet[2] = convert_channel_8b(THROTTLE);
packet[3] = convert_channel_8b(RUDDER);
packet[4] = convert_channel_8b(CH5);
packet[5] = convert_channel_8b(CH6);
packet[6] = 0;
for (uint8_t i=0; i < NANORF_PAYLOADSIZE-1; i++)
packet[6] += packet[i];
packet[6] += 0x55;
// clear packet status bits and TX FIFO
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
NRF24L01_FlushTx();
NRF24L01_WritePayload(packet, NANORF_PAYLOADSIZE);
}
static void __attribute__((unused)) NANORF_init()
{
NRF24L01_Initialize();
NRF24L01_SetTxRxMode(TX_EN);
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR , (uint8_t *)"Nano1",5);
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknoledgement
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable all data pipes (even though not used?)
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5-byte RX/TX address
NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x00); // 4mS retransmit t/o, 15 tries (retries w/o AA?)
NRF24L01_WriteReg(NRF24L01_05_RF_CH, NANORF_RF_CHANNEL);
NRF24L01_SetBitrate(NRF24L01_BR_1M);
NRF24L01_SetPower(); // Set tx_power
NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP)); //
}
uint16_t NANORF_callback()
{
NANORF_send_packet();
return NANORF_PACKET_PERIOD;
}
uint16_t initNANORF()
{
BIND_DONE;
NANORF_init();
return NANORF_INITIAL_WAIT;
}
#endif

View File

@@ -0,0 +1,262 @@
/*
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(OMP_CC2500_INO)
#include "iface_nrf250k.h"
//#define FORCE_OMP_ORIGINAL_ID
//#define OMP_TELEM_DEBUG
#define OMP_INITIAL_WAIT 500
#define OMP_PACKET_PERIOD 5000
#define OMP_RF_BIND_CHANNEL 35
#define OMP_RF_NUM_CHANNELS 8
#define OMP_PAYLOAD_SIZE 16
#define OMP_BIND_COUNT 600 //3sec
static void __attribute__((unused)) OMP_send_packet()
{
#ifdef OMP_HUB_TELEMETRY
if(option==0) option=1; // Select the CC2500 by default
PE1_off; PE2_on; // CC2500 antenna RF2
#endif
if(IS_BIND_IN_PROGRESS)
{
memcpy(packet,"BND",3);
memcpy(&packet[3],rx_tx_addr,5);
memcpy(&packet[8],hopping_frequency,8);
}
else
{
memset(packet,0x00,OMP_PAYLOAD_SIZE);
#ifdef OMP_HUB_TELEMETRY
//RX telem request every 7*5=35ms
packet_sent++;
packet_sent %= OMP_RF_NUM_CHANNELS-1; // Change telem RX channels every time
if(packet_sent==0)
{
packet[0] |= 0x40; // |0x40 to request RX telemetry
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no]);
}
#endif
//hopping frequency
packet[0 ] |= hopping_frequency_no;
XN297L_Hopping(hopping_frequency_no);
hopping_frequency_no++;
hopping_frequency_no &= OMP_RF_NUM_CHANNELS-1; // 8 RF channels
//flags
packet[1 ] = 0x08 //unknown
| GET_FLAG(CH5_SW, 0x20); // HOLD
packet[2 ] = 0x40; //unknown
if(Channel_data[CH6] > CHANNEL_MAX_COMMAND)
packet[2 ] |= 0x20; // IDLE2
else if(Channel_data[CH6] > CHANNEL_MIN_COMMAND)
packet[1 ] |= 0x40; // IDLE1
if(Channel_data[CH7] > CHANNEL_MAX_COMMAND)
packet[2 ] |= 0x08; // 3D
else if(Channel_data[CH7] > CHANNEL_MIN_COMMAND)
packet[2 ] |= 0x04; // ATTITUDE
//trims??
//packet[3..6]
//channels TAER packed 11bits
uint16_t channel=convert_channel_16b_limit(THROTTLE,0,2047);
packet[7 ] = channel;
packet[8 ] = channel>>8;
channel=convert_channel_16b_limit(AILERON,2047,0);
packet[8 ] |= channel<<3;
packet[9 ] = channel>>5;
channel=convert_channel_16b_limit(ELEVATOR,0,2047);
packet[9] |= channel<<6;
packet[10] = channel>>2;
packet[11] = channel>>10;
channel=convert_channel_16b_limit(RUDDER,2047,0);
packet[11] |= channel<<1;
packet[12] = channel>>7;
//unknown
//packet[13..15]
packet[15] = 0x04;
}
XN297L_SetPower(); // Set tx_power
XN297L_SetFreqOffset(); // Set frequency offset
XN297L_WriteEnhancedPayload(packet, OMP_PAYLOAD_SIZE, packet_sent!=0);
}
static void __attribute__((unused)) OMP_init()
{
//Config CC2500
#ifdef OMP_HUB_TELEMETRY
if(option==0)
option=1; // Select the CC2500
#endif
XN297L_Init();
XN297L_SetTXAddr((uint8_t*)"FLPBD", 5);
XN297L_HoppingCalib(OMP_RF_NUM_CHANNELS); // Calibrate all channels
XN297L_RFChannel(OMP_RF_BIND_CHANNEL); // Set bind channel
#ifdef OMP_HUB_TELEMETRY
//Config NRF
option=0; // Select the NRF
XN297L_Init();
NRF24L01_SetTxRxMode(TXRX_OFF); // Turn it off for now
XN297_SetRXAddr(rx_tx_addr, 5); // Set the RX address
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, OMP_PAYLOAD_SIZE + 2); // packet length +2 bytes of CRC
#endif
}
static void __attribute__((unused)) OMP_initialize_txid()
{
calc_fh_channels(OMP_RF_NUM_CHANNELS);
#ifdef FORCE_OMP_ORIGINAL_ID
rx_tx_addr[0]=0x4E;
rx_tx_addr[1]=0x72;
rx_tx_addr[2]=0x8E;
rx_tx_addr[3]=0x70;
rx_tx_addr[4]=0x62;
for(uint8_t i=0; i<OMP_RF_NUM_CHANNELS;i++)
hopping_frequency[i]=(i+3)*5;
#endif
}
enum {
OMP_BIND = 0x00,
OMP_PREPDATA = 0x01,
OMP_DATA = 0x02,
OMP_RX = 0x03,
};
#define OMP_WRITE_TIME 850
uint16_t OMP_callback()
{
switch(phase)
{
case OMP_BIND:
if(--bind_counter==0)
phase++; // OMP_PREPDATA
OMP_send_packet();
return OMP_PACKET_PERIOD;
case OMP_PREPDATA:
BIND_DONE;
XN297L_SetTXAddr(rx_tx_addr, 5);
phase++; // OMP_DATA
case OMP_DATA:
#ifdef MULTI_SYNC
telemetry_set_input_sync(OMP_PACKET_PERIOD);
#endif
OMP_send_packet();
#ifdef OMP_HUB_TELEMETRY
if(packet_sent == 0)
{
phase++; // OMP_RX
return OMP_WRITE_TIME;
}
else if(packet_sent == 1)
{
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR))
{ // a packet has been received
if(XN297_ReadEnhancedPayload(packet_in, 16) == 16)
{ // packet with good CRC and length
#ifdef OMP_TELEM_DEBUG
for(uint8_t i=0;i<16;i++)
debug(" %02X",packet_in[i]);
#endif
// packet_in = 01 00 98 2C 03 19 19 F0 49 02 00 00 00 00 00 00
// all bytes are fixed and unknown except 2 and 3 which represent the battery voltage: packet_in[3]*256+packet_in[2]=lipo voltage*100 in V
telemetry_counter++; //LQI
v_lipo1=((packet_in[3]<<8)+packet_in[2]-400)/50;
telemetry_link=1;
if(telemetry_lost)
{
telemetry_lost = 0;
packet_count = 100;
telemetry_counter = 100;
}
}
#ifdef OMP_TELEM_DEBUG
else
debug("Bad RX");
debugln("");
#endif
}
NRF24L01_SetTxRxMode(TXRX_OFF);
packet_count++;
if(packet_count>=100)
{//LQI calculation
packet_count=0;
TX_LQI=telemetry_counter;
RX_RSSI=telemetry_counter;
if(telemetry_counter==0)
telemetry_lost = 1;
telemetry_counter = 0;
}
}
#endif
return OMP_PACKET_PERIOD;
#ifdef OMP_HUB_TELEMETRY
case OMP_RX:
NRF24L01_WriteReg(NRF24L01_07_STATUS, (1 << NRF24L01_07_RX_DR) //reset the flag(s)
| (1 << NRF24L01_07_TX_DS)
| (1 << NRF24L01_07_MAX_RT));
NRF24L01_FlushRx();
NRF24L01_WriteReg(NRF24L01_00_CONFIG, (1 << NRF24L01_00_PWR_UP) | (1 << NRF24L01_00_PRIM_RX) ); // Start RX
{
uint16_t start=(uint16_t)micros();
while ((uint16_t)((uint16_t)micros()-(uint16_t)start) < 500)
{
if(CC2500_ReadReg(CC2500_35_MARCSTATE | CC2500_READ_BURST) != 0x13)
break;
}
}
PE1_on;PE2_off; // NRF24L01 antenna RF3
phase = OMP_DATA;
return OMP_PACKET_PERIOD-OMP_WRITE_TIME;
#endif
}
return OMP_PACKET_PERIOD;
}
uint16_t initOMP()
{
OMP_initialize_txid();
OMP_init();
hopping_frequency_no = 0;
packet_sent = 0;
#ifdef OMP_HUB_TELEMETRY
packet_count = 0;
telemetry_lost = 1;
#endif
if(IS_BIND_IN_PROGRESS)
{
bind_counter = OMP_BIND_COUNT;
phase = OMP_BIND;
}
else
phase = OMP_PREPDATA;
return OMP_INITIAL_WAIT;
}
#endif

View File

@@ -0,0 +1,157 @@
/*
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 Realacc R11
#if defined(REALACC_NRF24L01_INO)
#include "iface_nrf24l01.h"
#define FORCE_REALACC_ORIGINAL_ID
#define REALACC_INITIAL_WAIT 500
#define REALACC_PACKET_PERIOD 2268
#define REALACC_BIND_RF_CHANNEL 80
#define REALACC_BIND_PAYLOAD_SIZE 10
#define REALACC_PAYLOAD_SIZE 13
#define REALACC_BIND_COUNT 50
#define REALACC_RF_NUM_CHANNELS 5
static void __attribute__((unused)) REALACC_send_packet()
{
packet[ 0]= 0xDC;
packet[ 1]= convert_channel_8b(AILERON); // 00..80..FF
packet[ 2]= convert_channel_8b(ELEVATOR); // 00..80..FF
packet[ 3]= convert_channel_8b(THROTTLE); // 00..FF
packet[ 4]= convert_channel_8b(RUDDER); // 00..80..FF
packet[ 5]= 0x20; // Trim
packet[ 6]= 0x20; // Trim
packet[ 7]= 0x20; // Trim
packet[ 8]= 0x20; // Trim
packet[ 9]= num_ch; // Change at each power up
packet[10]= 0x04 // Flag1
| 0x02 // Rate1=0, Rate2=1, Rate3=2
| GET_FLAG(CH8_SW, 0x20); // Headless
packet[11]= 0x00 // Flag2
| GET_FLAG(CH7_SW, 0x01) // Calib
| GET_FLAG(CH9_SW, 0x20) // Return
| GET_FLAG(CH10_SW,0x80); // Unknown
packet[12]= 0x00 // Flag3
| GET_FLAG(CH5_SW, 0x01) // Flip
| GET_FLAG(CH6_SW, 0x80); // Light
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency_no);
hopping_frequency_no++;
hopping_frequency_no %= REALACC_RF_NUM_CHANNELS;
XN297_WriteEnhancedPayload(packet, REALACC_PAYLOAD_SIZE,0);
}
static void __attribute__((unused)) REALACC_send_bind_packet()
{
packet[0] = 0xB1;
memcpy(&packet[1],rx_tx_addr,4);
memcpy(&packet[5],hopping_frequency,5);
XN297_WriteEnhancedPayload(packet, REALACC_BIND_PAYLOAD_SIZE,1);
}
static void __attribute__((unused)) REALACC_initialize_txid()
{
calc_fh_channels(REALACC_RF_NUM_CHANNELS);
num_ch=random(0xfefefefe); // 00..FF
#ifdef FORCE_REALACC_ORIGINAL_ID
//Dump
rx_tx_addr[0]=0x99;
rx_tx_addr[1]=0x06;
rx_tx_addr[2]=0x00;
rx_tx_addr[3]=0x00;
hopping_frequency[0]=0x55;
hopping_frequency[1]=0x59;
hopping_frequency[2]=0x5A;
hopping_frequency[3]=0x5A;
hopping_frequency[4]=0x62;
num_ch=0xC5; // Value in dumps: C5 A2 77 F0 84 58
#endif
}
static void __attribute__((unused)) REALACC_init()
{
NRF24L01_Initialize();
NRF24L01_SetTxRxMode(TX_EN);
NRF24L01_FlushTx();
NRF24L01_FlushRx();
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowldgement on all data pipes
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 only
NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps
NRF24L01_SetPower();
XN297_SetTXAddr((uint8_t*)"MAIN", 4);
NRF24L01_WriteReg(NRF24L01_05_RF_CH, REALACC_BIND_RF_CHANNEL); // Set bind channel
}
uint16_t REALACC_callback()
{
#ifdef MULTI_SYNC
telemetry_set_input_sync(REALACC_PACKET_PERIOD);
#endif
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
NRF24L01_FlushTx();
NRF24L01_SetPower();
if(IS_BIND_IN_PROGRESS)
{
REALACC_send_bind_packet();
if(--bind_counter==0)
{
BIND_DONE;
XN297_SetTXAddr(rx_tx_addr, 4);
}
}
else
REALACC_send_packet();
return REALACC_PACKET_PERIOD;
}
uint16_t initREALACC()
{
BIND_IN_PROGRESS; // autobind protocol
REALACC_initialize_txid();
REALACC_init();
bind_counter=REALACC_BIND_COUNT;
hopping_frequency_no=0;
return REALACC_INITIAL_WAIT;
}
#endif
// XN297 speed 1Mb, scrambled, enhanced
// Bind
// Address = 4D 41 49 4E = 'MAIN'
// Channel = 80 (most likely from dump)
// P(10) = B1 99 06 00 00 55 59 5A 5A 62
// B1 indicates bind packet
// 99 06 00 00 = ID = address of normal packets
// 55 59 5A 5A 62 = 85, 89, 90, 90, 98 = RF channels to be used (kind of match previous dumps)// Normal
// Normal
// Address = 99 06 00 00
// Channels = 84, 89, 90, 90, 98 (guess from bind)
// P(13)= DC 80 80 32 80 20 20 20 20 58 04 00 00
// DC = normal packet
// 80 80 32 80 : AETR 00..80..FF
// 20 20 20 20 : Trims
// 58 : changing every time the TX restart
// 04 : |0x20=headless, |0x01=rate2, |0x02=rate3
// 00 : |0x01=calib, |0x20=return, |0x80=unknown
// 00 : |0x80=light, |0x01=flip

View File

@@ -166,7 +166,6 @@ static void __attribute__((unused)) RLINK_rf_init()
CC2500_WriteReg(CC2500_0C_FSCTRL0, option);
CC2500_SetTxRxMode(TX_EN);
CC2500_SetPower();
}
static void __attribute__((unused)) RLINK_tune_freq()
@@ -178,7 +177,7 @@ static void __attribute__((unused)) RLINK_tune_freq()
}
}
static void __attribute__((unused)) RLINK_TIMING_RFSEND_packet()
static void __attribute__((unused)) RLINK_send_packet()
{
static uint32_t pseudo=0;
uint32_t bits = 0;
@@ -262,8 +261,9 @@ uint16_t RLINK_callback()
#ifdef MULTI_SYNC
telemetry_set_input_sync(RLINK_TIMING_PROTO);
#endif
CC2500_SetPower();
RLINK_tune_freq();
RLINK_TIMING_RFSEND_packet();
RLINK_send_packet();
#if not defined RLINK_HUB_TELEMETRY
return RLINK_TIMING_PROTO;
#else
@@ -297,7 +297,7 @@ uint16_t RLINK_callback()
TX_RSSI += 128;
RX_RSSI=packet_in[7]; //Should be packet_in[7]-256 but since it's an uint8_t...
v_lipo1=packet_in[8]<<1; //RX Batt
v_lipo2=packet_in[9]<<1; //Batt
v_lipo2=packet_in[9]; //Batt
telemetry_link=1; //Send telemetry out
pps_counter++;
packet_count=0;

View File

@@ -531,7 +531,7 @@ void frsky_link_frame()
telemetry_link |= 2 ; // Send hub if available
}
else
{//PROTO_HUBSAN, PROTO_AFHDS2A, PROTO_BAYANG, PROTO_NCC1701, PROTO_CABELL, PROTO_HITEC, PROTO_BUGS, PROTO_BUGSMINI, PROTO_FRSKYX, PROTO_FRSKYX2, PROTO_PROPEL, PROTO_DEVO, PROTO_RLINK
{//PROTO_HUBSAN, PROTO_AFHDS2A, PROTO_BAYANG, PROTO_NCC1701, PROTO_CABELL, PROTO_HITEC, PROTO_BUGS, PROTO_BUGSMINI, PROTO_FRSKYX, PROTO_FRSKYX2, PROTO_PROPEL, PROTO_DEVO, PROTO_RLINK, PROTO_OMP
frame[1] = v_lipo1;
frame[2] = v_lipo2;
frame[3] = RX_RSSI;
@@ -952,7 +952,7 @@ void TelemetryUpdate()
#endif
if( telemetry_link & 1 )
{ // FrSkyD + Hubsan + AFHDS2A + Bayang + Cabell + Hitec + Bugs + BugsMini + NCC1701 + PROPEL + RLINK
{ // FrSkyD + Hubsan + AFHDS2A + Bayang + Cabell + Hitec + Bugs + BugsMini + NCC1701 + PROPEL + RLINK + OMP
// FrSkyX telemetry if in PPM
frsky_link_frame();
return;

View File

@@ -17,12 +17,12 @@ Multiprotocol is distributed in the hope that it will be useful,
#include "iface_nrf24l01.h"
//#define V761_FORCE_ID
#define V761_PACKET_PERIOD 7060 // Timeout for callback in uSec
#define V761_INITIAL_WAIT 500
#define V761_PACKET_SIZE 8
#define V761_BIND_COUNT 200
//Fx chan management
#define V761_BIND_FREQ 0x28
#define V761_RF_NUM_CHANNELS 3
@@ -143,30 +143,40 @@ static void __attribute__((unused)) V761_init()
static void __attribute__((unused)) V761_initialize_txid()
{
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); // To be checked
memcpy(hopping_frequency,(uint8_t *)"\x0D\x21",2); // To be checked
break;
case 4: //Dump from air on Crashanium Eachine TX
memcpy(rx_tx_addr,(uint8_t *)"\x58\x08\x00\xA0",4); // To be checked
memcpy(hopping_frequency,(uint8_t *)"\x0D\x31",3); // To be checked
break;
default: //Dump from SPI
memcpy(rx_tx_addr,(uint8_t *)"\x6f\x2c\xb1\x93",4);
memcpy(hopping_frequency,(uint8_t *)"\x14\x1e",3);
break;
}
#ifdef V761_FORCE_ID
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
rx_tx_addr[0]+=RX_num;
hopping_frequency[0]=(rx_tx_addr[0]&0x0F)+0x05;
hopping_frequency[1]=hopping_frequency[0]+0x05+(RX_num%0x2D);
#endif
hopping_frequency[2]=hopping_frequency[0]+0x37;
debugln("ID: %02X %02X %02X %02X , HOP: %02X %02X %02X",rx_tx_addr[0],rx_tx_addr[1],rx_tx_addr[2],rx_tx_addr[3],hopping_frequency[0],hopping_frequency[1],hopping_frequency[2]);
}
uint16_t V761_callback()
@@ -223,7 +233,11 @@ uint16_t initV761(void)
phase = V761_BIND1;
}
else
{
XN297_SetTXAddr(rx_tx_addr, 4);
phase = V761_DATA;
}
V761_init();
hopping_frequency_no = 0;
packet_count = 0;

View File

@@ -247,6 +247,7 @@
#undef FRSKY_RX_CC2500_INO
#undef HITEC_CC2500_INO
#undef HOTT_CC2500_INO
#undef OMP_CC2500_INO
#undef REDPINE_CC2500_INO
#undef RLINK_CC2500_INO
#undef SCANNER_CC2500_INO
@@ -281,10 +282,12 @@
#undef MJXQ_NRF24L01_INO
#undef MT99XX_NRF24L01_INO
#undef NCC1701_NRF24L01_INO
#undef OMP_CC2500_INO
#undef POTENSIC_NRF24L01_INO
#undef PROPEL_NRF24L01_INO
#undef Q303_NRF24L01_INO
#undef Q90C_NRF24L01_INO
#undef REALACC_NRF24L01_INO
#undef SHENQI_NRF24L01_INO
#undef SLT_NRF24L01_INO
#undef SYMAX_NRF24L01_INO
@@ -338,6 +341,7 @@
#undef BAYANG_RX_NRF24L01_INO
#undef DEVO_HUB_TELEMETRY
#undef PROPEL_HUB_TELEMETRY
#undef OMP_HUB_TELEMETRY
#undef RLINK_HUB_TELEMETRY
#undef DSM_RX_CYRF6936_INO
#else
@@ -366,6 +370,9 @@
#if not defined(DEVO_CYRF6936_INO)
#undef DEVO_HUB_TELEMETRY
#endif
#if not defined(OMP_CC2500_INO)
#undef OMP_HUB_TELEMETRY
#endif
#if not defined(PROPEL_NRF24L01_INO)
#undef PROPEL_HUB_TELEMETRY
#endif
@@ -408,7 +415,7 @@
#if not defined(HOTT_CC2500_INO)
#undef HOTT_FW_TELEMETRY
#endif
#if not defined(HOTT_FW_TELEMETRY) && not defined(DSM_TELEMETRY) && not defined(SPORT_TELEMETRY) && not defined(HUB_TELEMETRY) && not defined(HUBSAN_HUB_TELEMETRY) && not defined(BUGS_HUB_TELEMETRY) && not defined(NCC1701_HUB_TELEMETRY) && not defined(BAYANG_HUB_TELEMETRY) && not defined(CABELL_HUB_TELEMETRY) && not defined(RLINK_HUB_TELEMETRY) && not defined(AFHDS2A_HUB_TELEMETRY) && not defined(AFHDS2A_FW_TELEMETRY) && not defined(MULTI_TELEMETRY) && not defined(MULTI_STATUS) && not defined(HITEC_HUB_TELEMETRY) && not defined(HITEC_FW_TELEMETRY) && not defined(SCANNER_TELEMETRY) && not defined(FRSKY_RX_TELEMETRY) && not defined(AFHDS2A_RX_TELEMETRY) && not defined(BAYANG_RX_TELEMETRY) && not defined(DEVO_HUB_TELEMETRY) && not defined(PROPEL_HUB_TELEMETRY)
#if not defined(HOTT_FW_TELEMETRY) && not defined(DSM_TELEMETRY) && not defined(SPORT_TELEMETRY) && not defined(HUB_TELEMETRY) && not defined(HUBSAN_HUB_TELEMETRY) && not defined(BUGS_HUB_TELEMETRY) && not defined(NCC1701_HUB_TELEMETRY) && not defined(BAYANG_HUB_TELEMETRY) && not defined(CABELL_HUB_TELEMETRY) && not defined(RLINK_HUB_TELEMETRY) && not defined(AFHDS2A_HUB_TELEMETRY) && not defined(AFHDS2A_FW_TELEMETRY) && not defined(MULTI_TELEMETRY) && not defined(MULTI_STATUS) && not defined(HITEC_HUB_TELEMETRY) && not defined(HITEC_FW_TELEMETRY) && not defined(SCANNER_TELEMETRY) && not defined(FRSKY_RX_TELEMETRY) && not defined(AFHDS2A_RX_TELEMETRY) && not defined(BAYANG_RX_TELEMETRY) && not defined(DEVO_HUB_TELEMETRY) && not defined(PROPEL_HUB_TELEMETRY) && not defined(OMP_HUB_TELEMETRY)
#undef TELEMETRY
#undef INVERT_TELEMETRY
#undef MULTI_TELEMETRY

View File

@@ -23,7 +23,7 @@
// Parameters which can be modified
#define XN297DUMP_PERIOD_SCAN 50000 // 25000
#define XN297DUMP_MAX_RF_CHANNEL 84 // Default 84
#define XN297DUMP_MAX_RF_CHANNEL 127 // Default 84
// Do not touch from there
#define XN297DUMP_INITIAL_WAIT 500

View File

@@ -16,7 +16,7 @@ Multiprotocol is distributed in the hope that it will be useful,
#if defined(ZSX_NRF24L01_INO)
#include "iface_nrf250k.h"
#include "iface_nrf24l01.h"
//#define FORCE_ZSX_ORIGINAL_ID

View File

@@ -194,6 +194,7 @@
#define FRSKY_RX_CC2500_INO
#define HITEC_CC2500_INO
#define HOTT_CC2500_INO
#define OMP_CC2500_INO //Need both CC2500 and NRF
#define SCANNER_CC2500_INO
#define SFHSS_CC2500_INO
#define SKYARTEC_CC2500_INO
@@ -231,6 +232,7 @@
#define PROPEL_NRF24L01_INO
#define Q303_NRF24L01_INO
#define Q90C_NRF24L01_INO
#define REALACC_NRF24L01_INO
#define SHENQI_NRF24L01_INO
#define SLT_NRF24L01_INO
#define SYMAX_NRF24L01_INO
@@ -260,6 +262,9 @@
// For example, a value of -80% applied on channel 14 will instantly kill the motors on the X-Vert.
#define DSM_THROTTLE_KILL_CH 14
//Enable DSM Forward Programming
#define DSM_FWD_PGM
//AFHDS2A specific settings
//-------------------------
//When enabled (remove the "//"), the below setting makes LQI (Link Quality Indicator) available on one of the RX ouput channel (5-14).
@@ -313,6 +318,7 @@
#define DEVO_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
#define HUBSAN_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
#define NCC1701_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
#define OMP_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
#define PROPEL_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
#define CABELL_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
#define RLINK_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
@@ -682,6 +688,8 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
FY805
PROTO_NCC1701
NONE
PROTO_OMP
NONE
PROTO_PELIKAN
PELIKAN_PRO
PELIKAN_LITE
@@ -700,6 +708,8 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
CX10WD
PROTO_Q90C
NONE
PROTO_REALACC
NONE
PROTO_REDPINE
RED_FAST
RED_SLOW

View File

@@ -93,7 +93,7 @@ CFlie|38|CFlie||||||||NRF24L01|
[Frsky_RX](Protocols_Details.md#FRSKY_RX---55)|55|RX|CloneTX|||||||CC2500|
[FX816](Protocols_Details.md#FX816---58)|28|FX816|P38|||||||NRF24L01|
[FY326](Protocols_Details.md#FY326---20)|20|FY326|FY319|||||||NRF24L01|
[GD00X](Protocols_Details.md#GD00X---47)|47|GD_V1*|GD_V2*|||||||NRF24L01|
[GD00X](Protocols_Details.md#GD00X---47)|47|GD_V1*|GD_V2*|||||||NRF24L01|XN297L
[GW008](Protocols_Details.md#GW008---32)|32|GW008||||||||NRF24L01|XN297
[H8_3D](Protocols_Details.md#H8_3D---36)|36|H8_3D|H20H|H20Mini|H30Mini|||||NRF24L01|XN297
[Height](Protocols_Details.md#HEIGHT---53)|53|5ch|8ch|||||||A7105|
@@ -110,6 +110,7 @@ CFlie|38|CFlie||||||||NRF24L01|
[MJXq](Protocols_Details.md#MJXQ---18)|18|WLH08|X600|X800|H26D|E010*|H26WH|PHOENIX*||NRF24L01|XN297
[MT99xx](Protocols_Details.md#MT99XX---17)|17|MT|H7|YZ|LS|FY805||||NRF24L01|XN297
[NCC1701](Protocols_Details.md#NCC1701---44)|44|NCC1701||||||||NRF24L01|
[OMP](Protocols_Details.md#OMP---77)|77|||||||||CC2500&NRF24L01|XN297L
[OpenLRS](Protocols_Details.md#OpenLRS---27)|27|||||||||None|
[Pelikan](Protocols_Details.md#Pelikan---60)|60|Pro|Lite|||||||A7105|
[Potensic](Protocols_Details.md#Potensic---51)|51|A20||||||||NRF24L01|XN297
@@ -118,7 +119,8 @@ CFlie|38|CFlie||||||||NRF24L01|
[Q303](Protocols_Details.md#Q303---31)|31|Q303|CX35|CX10D|CX10WD|||||NRF24L01|XN297
[Q90C](Protocols_Details.md#Q90C---72)|72|Q90C*||||||||NRF24L01|XN297
[RadioLink](Protocols_Details.md#RadioLink---74)|74|Surface|Air|||||||CC2500|
[Redpine](Protocols_Details.md#Redpine---50)|50|FAST|SLOW|||||||NRF24L01|
[Realacc](Protocols_Details.md#Realacc---76)|76|R11||||||||NRF24L01|
[Redpine](Protocols_Details.md#Redpine---50)|50|FAST|SLOW|||||||NRF24L01|XN297
[Scanner](Protocols_Details.md#Scanner---54)|54|||||||||CC2500|
[SFHSS](Protocols_Details.md#SFHSS---21)|21|SFHSS||||||||CC2500|
[Shenqi](Protocols_Details.md#Shenqi---19)|19|Shenqi||||||||NRF24L01|LT8900
@@ -550,6 +552,24 @@ Recommended for best telemetry performance.
Telemetry compatibility mode when Sync does not work due to an old firmware on the RX.
You should definitively upgrade your receivers/sensors to the latest firmware versions: https://www.rcgroups.com/forums/showpost.php?p=44668015&postcount=18022
## OMP - *77*
Model: OMPHOBBY M2 Heli, T720 RC Glider
Telemetry supported with A1=battery voltage (you need to adjust the offset with a voltmeter since there are some large differences between the models), RX_RSSI = TQly = percentage of received telemetry packets which has nothing to do with well the RX is receiving the TX but instead how well the TX=multi module is receiving the RX.
Option for this protocol corresponds to fine frequency tuning. This value is different for each Module and **must** be accurate otherwise the link will not be stable.
Check the [Frequency Tuning page](/docs/Frequency_Tuning.md) to determine it.
This protocol is using both the CC2500 and NRF24L01 to control the model and read the telemetry.
CH1|CH2|CH3|CH4|CH5|CH6|CH7
---|---|---|---|---|---|---
A|E|T_PITCH|R|T_HOLD|IDLE|MODE
IDLE= 3 pos switch: -100% Normal, 0% Idle1, +100% Idle2
MODE= 3 pos switch -100% Attitude(?), 0% Attitude, +100% 3D
## Scanner - *54*
2.4GHz scanner accessible using the OpenTX 2.3 Spectrum Analyser tool.
@@ -573,7 +593,7 @@ Surface protocol. TXs: RC4GS,RC6GS. Compatible RXs:R7FG(Std),R6FG,R6F,R8EF,R8FM,
CH1=Steering, CH2=Throttle, CH8=Gyro gain
Telemetry: RX_RSSI (for the original value add -256), TX_RSSI, TX_QLY (0..100%), A1=RX_Batt, A2=Batt
Telemetry: RX_RSSI (for the original value add -256), TX_RSSI, TX_QLY (0..100%), A1=RX_Batt, A2=Batt/2 (adjust the ratio)
### Sub_protocol Air - *1*
Air protocol. TXs: T8FB,T8S. Compatible RXs:R8EF,R8FM,R8SM,R4FG,R4F and more
@@ -750,6 +770,7 @@ The DSM receiver protocol enables master/slave trainning, separate access from 2
Notes:
- Automatically detect DSM 2/X 11/22ms 1024/2048res
- Bind should be done with all other modules off in the radio
- Available in OpenTX 2.3.3+, Trainer Mode Master/Multi
- Channels 1..4 are remapped to the module default channel order unless on OpenTX 2.3.3+ you use the "Disable channel mapping" feature on the GUI.
- Extended limits supported
@@ -1369,6 +1390,19 @@ A|E|T|R|FMODE|VTX+
FMODE: -100% angle, 0% horizon, +100% acro
VTX+: -100%->+100% channel+
## Realacc - *76*
Model: Realacc R11
Untested protocol, let me know if it works.
Autobind protocol
### Sub_protocol R11 - *0*
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10
---|---|---|---|---|---|---|---|---|----
A|E|T|R|FLIP|LIGHT|CALIB|HLESS|RTH|UNK
## Redpine - *50*
[Link to the forum](https://www.rcgroups.com/forums/showthread.php?3236043-Redpine-Lowest-latency-RC-protocol)
@@ -1524,8 +1558,6 @@ A|E|T|R|FLIP|LIGHT
## V761 - *48*
Warning: **Only 5 IDs**, you can cycle through them using RX_Num.
Gyro: -100%=Beginer mode (Gyro on, yaw and pitch rate limited), 0%=Mid Mode ( Gyro on no rate limits), +100%=Mode Expert Gyro off
Calib: momentary switch, calib will happen one the channel goes from -100% to +100%
Flip: momentary switch: hold flip(+100%), indicate flip direction with Ele or Ail, release flip(-100%)
@@ -1617,28 +1649,28 @@ Notes:
- Power adjustment is not supported on the T18.
### Sub_protocol R9_915 - *0*
915MHz, 16 channels
FLEX 915MHz, 16 channels
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13|CH14|CH15|CH16
---|---|---|---|---|---|---|---|---|----|----|----|----|----|----|----
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13|CH14|CH15|CH16
### Sub_protocol R9_868 - *1*
868MHz, 16 channels
FLEX 868MHz, 16 channels
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13|CH14|CH15|CH16
---|---|---|---|---|---|---|---|---|----|----|----|----|----|----|----
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13|CH14|CH15|CH16
### Sub_protocol R9_915_8CH - *2*
915MHz, 8 channels
FLEX 915MHz, 8 channels
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
---|---|---|---|---|---|---|---
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
### Sub_protocol R9_868_8CH - *3*
868MHz, 8 channels
FLEX 868MHz, 8 channels
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
---|---|---|---|---|---|---|---

View File

@@ -19,11 +19,12 @@ If you like this project and want to support further development please consider
## Development status
Multiprotocol downloads: <img src=https://img.shields.io/github/downloads/pascallanger/DIY-Multiprotocol-TX-Module/total.svg>
Current Multiprotocol code check status: [![Travis Build Status for Multi](https://api.travis-ci.org/pascallanger/DIY-Multiprotocol-TX-Module.svg?branch=master)](https://travis-ci.org/pascallanger/DIY-Multiprotocol-TX-Module)
Current Multiprotocol boards check status: [![Travis Build Status for Multi Boards](https://api.travis-ci.org/pascallanger/DIY-Multiprotocol-TX-Module-Boards.svg?branch=master)](https://travis-ci.org/pascallanger/DIY-Multiprotocol-TX-Module-Boards)
## Quicklinks
* [Download latest releases of the firmware](https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/releases) and [instructions to upload .hex files](docs/Advanced_Manually_Setting_ATmega328_Fuses.md)
* [Forum on rcgroups](http://www.rcgroups.com/forums/showthread.php?t=2165676)