mirror of
https://github.com/pascallanger/DIY-Multiprotocol-TX-Module.git
synced 2025-11-26 05:59:41 +00:00
Compare commits
132 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
41e31eae6d | ||
|
|
dcf20951ba | ||
|
|
6e9ebfd695 | ||
|
|
c36b112437 | ||
|
|
24fbd44f5b | ||
|
|
d0db7829e5 | ||
|
|
58ed8ca60f | ||
|
|
4d2c8ef04e | ||
|
|
438e85c551 | ||
|
|
06b336ee59 | ||
|
|
a93adeb75e | ||
|
|
802e69563e | ||
|
|
a8897df3f2 | ||
|
|
7157d3d906 | ||
|
|
96b8a500b4 | ||
|
|
51a3ef8ee9 | ||
|
|
652d6604e7 | ||
|
|
b9028ab4b4 | ||
|
|
62c509b03c | ||
|
|
1648a0780a | ||
|
|
3b1af68ed6 | ||
|
|
aeed7bac57 | ||
|
|
2bb76a40f3 | ||
|
|
0c129a45aa | ||
|
|
2a383c7285 | ||
|
|
34f16b0b66 | ||
|
|
a9d9c4cdfa | ||
|
|
4a1c986dd0 | ||
|
|
756e9b3213 | ||
|
|
61a284863e | ||
|
|
39410c290b | ||
|
|
9e0684b6cb | ||
|
|
13add5b9f2 | ||
|
|
475cd1af98 | ||
|
|
04d08c6d67 | ||
|
|
6295bb1bbc | ||
|
|
931ba2bd68 | ||
|
|
769fb4ff94 | ||
|
|
aa7c18a2bd | ||
|
|
f95cfa1261 | ||
|
|
8c12aaf2c1 | ||
|
|
94f73bd54f | ||
|
|
9b3549d4a9 | ||
|
|
7bc05cb63c | ||
|
|
84780a9d90 | ||
|
|
37e029c612 | ||
|
|
c47ed8aca8 | ||
|
|
5bb0752d5e | ||
|
|
4a626eaf14 | ||
|
|
47de19c8a5 | ||
|
|
3d4cfa30ac | ||
|
|
d658bee05a | ||
|
|
820c181394 | ||
|
|
c9774f557e | ||
|
|
b17618a5a8 | ||
|
|
03d0adbd74 | ||
|
|
905ee4b1ed | ||
|
|
dbc33951a4 | ||
|
|
732e66cab2 | ||
|
|
0dab92552a | ||
|
|
047952537a | ||
|
|
d4bf1fb36e | ||
|
|
ff817cd098 | ||
|
|
04ea44ed4b | ||
|
|
e23c8e2216 | ||
|
|
afb4802a2c | ||
|
|
3a5d341514 | ||
|
|
b6bcab1604 | ||
|
|
0a998d2dc5 | ||
|
|
7927bc601e | ||
|
|
f8cc913898 | ||
|
|
a5428bc180 | ||
|
|
c0285f81f0 | ||
|
|
600049898a | ||
|
|
0e1db8f06b | ||
|
|
ec83f1e5a3 | ||
|
|
f8f7769d9c | ||
|
|
4dacac29c6 | ||
|
|
593f3b87f1 | ||
|
|
bb70116df0 | ||
|
|
d7c24d62ed | ||
|
|
07df1a8959 | ||
|
|
ca9e2870ab | ||
|
|
99ca6fa36c | ||
|
|
3d82560f71 | ||
|
|
44d362aeb4 | ||
|
|
3d4ed5ad11 | ||
|
|
ca3c2bbdc8 | ||
|
|
90c226c748 | ||
|
|
b757283f41 | ||
|
|
b3132c7bf1 | ||
|
|
9ba56f040a | ||
|
|
ac71b4d981 | ||
|
|
6bb2c06cf6 | ||
|
|
2ad3c727fd | ||
|
|
d36af55b84 | ||
|
|
f19bb05c7a | ||
|
|
08ea8818fb | ||
|
|
59c541d013 | ||
|
|
37e2b5f41c | ||
|
|
614a330cf2 | ||
|
|
9106548859 | ||
|
|
2f07e79e50 | ||
|
|
2233f6f862 | ||
|
|
ae842f0bdc | ||
|
|
4b36656246 | ||
|
|
ea282489f9 | ||
|
|
6f2d9430d0 | ||
|
|
bccd9dc0d9 | ||
|
|
af919fb940 | ||
|
|
7dab0de3c5 | ||
|
|
2c0525421a | ||
|
|
0844ec2efd | ||
|
|
49c3af12f9 | ||
|
|
96d335f458 | ||
|
|
eae412fe41 | ||
|
|
0270420531 | ||
|
|
93bb117961 | ||
|
|
29d1fb00b1 | ||
|
|
5a49d99c4f | ||
|
|
d66bf1a5b3 | ||
|
|
b41dccef67 | ||
|
|
addf2c5143 | ||
|
|
ff829f1f7b | ||
|
|
7ee72976c4 | ||
|
|
dc18e8e5b2 | ||
|
|
97de2aaf3d | ||
|
|
3b8b2ef376 | ||
|
|
d496f62719 | ||
|
|
fc978f95ef | ||
|
|
596e8c9b55 | ||
|
|
0cf58c2990 |
12
.github/FUNDING.yml
vendored
Normal file
12
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: [pascallanger]
|
||||
patreon: # Replace with a single Patreon username
|
||||
open_collective: # Replace with a single Open Collective username
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
liberapay: # Replace with a single Liberapay username
|
||||
issuehunt: # Replace with a single IssueHunt username
|
||||
otechie: # Replace with a single Otechie username
|
||||
custom: https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=VF2K9T23DRY56&lc=US&item_name=DIY%20Multiprotocol¤cy_code=EUR&bn=PP%2dDonationsBF%3abtn_donate_SM%2egif%3aNonHosted
|
||||
1
.github/workflows/main.yml
vendored
1
.github/workflows/main.yml
vendored
@@ -101,6 +101,7 @@ jobs:
|
||||
echo "CYRF6936_PROTOCOLS=$(echo $CYRF6936_PROTOCOLS)" >> $GITHUB_ENV
|
||||
echo "NRF24L01_PROTOCOLS=$(echo $NRF24L01_PROTOCOLS)" >> $GITHUB_ENV
|
||||
echo "SX1276_PROTOCOLS=$(echo $SX1276_PROTOCOLS)" >> $GITHUB_ENV
|
||||
echo "CCNRF_INO_PROTOCOLS=$(echo $CCNRF_INO_PROTOCOLS)" >> $GITHUB_ENV
|
||||
echo "ALL_PROTOCOLS=$(echo $ALL_PROTOCOLS)" >> $GITHUB_ENV
|
||||
|
||||
# Get all the RF modules for this board
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
14,4,Bayang,DHD_D4,1,Flip,RTH,Pict,Video,HLess,Invert,Rates,TakeOf,EmStop
|
||||
14,5,Bayang,QX100,1,Flip,RTH,Pict,Video,HLess,Invert,Rates,TakeOf,EmStop
|
||||
59,0,BayangRX,RX,1,AnAux1,AnAux2,Flip,RTH,Pict,Video
|
||||
59,1,BayangRX,CPPM,1,AnAux1,AnAux2,Flip,RTH,Pict,Video
|
||||
41,0,Bugs,3-6-8,0,Arm,Angle,Flip,Pict,Video,LED
|
||||
42,0,BugsMini,Mini,0,Arm,Angle,Flip,Pict,Video,LED
|
||||
42,1,BugsMini,3H,0,Arm,Angle,Flip,Pict,Video,LED,AltHol
|
||||
@@ -28,15 +29,16 @@
|
||||
7,3,Devo,6CH,0,CH5,CH6
|
||||
7,4,Devo,7CH,0,CH5,CH6,CH7
|
||||
33,0,DM022,Std,1,Flip,LED,Cam1,Cam2,HLess,RTH,RLow
|
||||
6,0,DSM,2_22,0,CH5,CH6,CH7,CH8,CH9,CH10,CH11,CH12,n-a,ThKill
|
||||
6,1,DSM,2_11,0,CH5,CH6,CH7,CH8,CH9,CH10,CH11,CH12,n-a,ThKill
|
||||
6,2,DSM,X_22,0,CH5,CH6,CH7,CH8,CH9,CH10,CH11,CH12,n-a,ThKill
|
||||
6,3,DSM,X_11,0,CH5,CH6,CH7,CH8,CH9,CH10,CH11,CH12,n-a,ThKill
|
||||
6,0,DSM,2_1F,0,CH5,CH6,CH7,CH8,CH9,CH10,CH11,CH12,n-a,ThKill
|
||||
6,1,DSM,2_2F,0,CH5,CH6,CH7,CH8,CH9,CH10,CH11,CH12,n-a,ThKill
|
||||
6,2,DSM,X_1F,0,CH5,CH6,CH7,CH8,CH9,CH10,CH11,CH12,n-a,ThKill
|
||||
6,3,DSM,X_2F,0,CH5,CH6,CH7,CH8,CH9,CH10,CH11,CH12,n-a,ThKill
|
||||
6,4,DSM,AUTO,0,CH5,CH6,CH7,CH8,CH9,CH10,CH11,CH12,n-a,ThKill
|
||||
6,5,DSM,R_1F,0,AUX3,AUX4,AUX5
|
||||
70,0,DSM_RX,RX,0,CH5,CH6,CH7,CH8,CH9,CH10,CH11,CH12
|
||||
70,1,DSM_RX,CPPM,0,CH5,CH6,CH7,CH8,CH9,CH10,CH11,CH12
|
||||
45,0,E01X,E012,1,n-a,Flip,n-a,HLess,RTH
|
||||
45,1,E01X,E015,1,Arm,Flip,LED,HLess,RTH
|
||||
45,2,E01X,E016H,1,Stop,Flip,n-a,HLess,RTH
|
||||
16,0,ESKY,Std,0,Gyro,Pitch
|
||||
16,1,ESKY,ET4,0,Gyro,Pitch
|
||||
35,0,ESKY150,4CH,0
|
||||
@@ -54,6 +56,7 @@
|
||||
28,4,Flysky_AFHDS2A,PWM_IB16,0,CH5,CH6,CH7,CH8,CH9,CH10,CH11,CH12,CH13,CH14,CH15,CH16
|
||||
28,5,Flysky_AFHDS2A,PPM_IB16,0,CH5,CH6,CH7,CH8,CH9,CH10,CH11,CH12,CH13,CH14,CH15,CH16
|
||||
56,0,Flysky2A_RX,RX,0,CH5,CH6,CH7,CH8,CH9,CH10,CH11,CH12,CH13,CH14
|
||||
56,1,Flysky2A_RX,CPPM,0,CH5,CH6,CH7,CH8,CH9,CH10,CH11,CH12,CH13,CH14
|
||||
53,0,Height,5ch,0,Gear
|
||||
53,1,Height,8ch,0,Gear,Gyro,Flap,Light
|
||||
25,0,FrSkyV,V8,0,CH5,CH6,CH7,CH8
|
||||
@@ -80,6 +83,7 @@
|
||||
55,0,FrSkyRX,RX,0,CH5,CH6,CH7,CH8,CH9,CH10,CH11,CH12,CH13,CH14,CH15,CH16
|
||||
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,P38,1
|
||||
20,0,FY326,FY326,1,Flip,RTH,HLess,Expert,Calib
|
||||
20,1,FY326,FY319,1,Flip,RTH,HLess,Expert,Calib
|
||||
@@ -124,11 +128,13 @@
|
||||
17,2,MT99XX,YZ,1,Flip,LED,Pict,Video,HLess
|
||||
17,3,MT99XX,LS,1,Flip,Invert,Pict,Video,HLess
|
||||
17,4,MT99XX,FY805,1,Flip,n-a,n-a,n-a,HLess
|
||||
17,5,MT99XX,A180,1,3D_6G
|
||||
17,5,MT99XX,A180,0,3D_6G
|
||||
17,6,MT99XX,Dragon,0,Mode,RTH
|
||||
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
|
||||
60,2,Pelikan,SCX24,0
|
||||
51,0,Potensic,A20,1,TakLan,Emerg,Mode,HLess
|
||||
66,0,Propel,74-Z,1,LEDs,RollCW,RolCCW,Fire,Weapon,Calib,AltHol,TakeOf,Land,Train
|
||||
29,0,Q2x2,Q222,1,Flip,LED,Mod2,Mod1,HLess,RTH,XCal,YCal
|
||||
@@ -182,5 +188,11 @@
|
||||
79,0,WFLY2,RF20x,0,CH5,CH6,CH7,CH8,CH9,CH10
|
||||
80,0,E016Hv2,E016Hv2,1,TakLan,EmStop,Flip,Calib,HLess,RTH
|
||||
81,0,E010r5,E010r5,1,Flip,LED,CALIB,HLess,RTH,GLIDE
|
||||
82,0,LOLI,LOLI,0,CH5,CH6,CH7,CH8,1SwSePpPw,2SwSePw,3SwSe,4SwSe,5SwSeSb,6SwSe,7SwSePw,8SwSe
|
||||
82,0,LOLI,Std,0,CH5,CH6,CH7,CH8,1SwSePpPw,2SwSePw,3SwSe,4SwSe,5SwSeSb,6SwSe,7SwSePw,8SwSe
|
||||
83,0,E129,E129,1,TakLan,EmStop,TrimA,TrimE,TrimR
|
||||
84,0,JOYSWAY,Std,0
|
||||
85,0,E016H,Std,1,Stop,Flip,n-a,HLess,RTH
|
||||
87,0,IKEA
|
||||
89,0,LOSI
|
||||
90,0,MouldKg,Analog
|
||||
90,1,MouldKg,Digit,E,F
|
||||
@@ -280,11 +280,27 @@ local function Multi_Init()
|
||||
end
|
||||
|
||||
--Exceptions on first 4 channels...
|
||||
if ( protocol == 73 or (protocol == 74 and sub_protocol == 0) ) then -- Kyosho or RadioLink Surface
|
||||
if ( protocol == 73 or (protocol == 74 and sub_protocol == 0) or (protocol == 60 and sub_protocol == 2) or protocol == 89) then -- Kyosho or RadioLink Surface or Pelikan/SCX24 or Losi
|
||||
channel_names[1] = "ST"
|
||||
channel_names[2] = "THR"
|
||||
channel_names[3] = "CH3"
|
||||
channel_names[4] = "CH4"
|
||||
if(protocol == 60 and sub_protocol == 2) then
|
||||
channel_names[4] = "n-a"
|
||||
else
|
||||
channel_names[4] = "CH4"
|
||||
end
|
||||
end
|
||||
if ( protocol == 6 and sub_protocol == 5 ) then -- DSMR
|
||||
channel_names[1] = "ST"
|
||||
channel_names[2] = "THR"
|
||||
channel_names[3] = "AUX1"
|
||||
channel_names[4] = "AUX2"
|
||||
end
|
||||
if ( protocol == 90 ) then -- Mould King
|
||||
channel_names[1] = "A"
|
||||
channel_names[2] = "B"
|
||||
channel_names[3] = "C"
|
||||
channel_names[4] = "D"
|
||||
end
|
||||
|
||||
--Check MultiChan.txt
|
||||
|
||||
525
Lua_scripts/MultiConfig.lua
Normal file
525
Lua_scripts/MultiConfig.lua
Normal file
@@ -0,0 +1,525 @@
|
||||
---- #########################################################################
|
||||
---- # #
|
||||
---- # 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 Config description
|
||||
-- To start operation:
|
||||
-- Write 0xFF at address 4 will request the buffer to be cleared
|
||||
-- Write "Conf" at address 0..3
|
||||
-- Read
|
||||
-- Read at address 12 gives the current config page
|
||||
-- Read at address 13..172 gives the current data of the page = 8 lines * 20 caracters
|
||||
-- Write
|
||||
-- Write at address 5..11 the command
|
||||
-- Write 0x01 at address 4 will send the command to the module
|
||||
-- !! Before exiting the script must write 0 at address 0 for normal operation !!
|
||||
--###############################################################################
|
||||
|
||||
local Version = "v0.2"
|
||||
local Focus = -1
|
||||
local Page = 0
|
||||
local Edit = -1
|
||||
local Edit_pos = 1
|
||||
local Menu = { {text = "", field_type = 0, field_len = 0, field_value = {}, field_text = ""},
|
||||
{text = "", field_type = 0, field_len = 0, field_value = {}, field_text = ""},
|
||||
{text = "", field_type = 0, field_len = 0, field_value = {}, field_text = ""},
|
||||
{text = "", field_type = 0, field_len = 0, field_value = {}, field_text = ""},
|
||||
{text = "", field_type = 0, field_len = 0, field_value = {}, field_text = ""},
|
||||
{text = "", field_type = 0, field_len = 0, field_value = {}, field_text = ""},
|
||||
{text = "", field_type = 0, field_len = 0, field_value = {}, field_text = ""} }
|
||||
local Menu_value = {}
|
||||
local Blink = 0
|
||||
local ModuleNumber = 0
|
||||
local ModuleType = ""
|
||||
local Module = {}
|
||||
local InitialProtocol = 0
|
||||
|
||||
function bitand(a, b)
|
||||
local result = 0
|
||||
local bitval = 1
|
||||
while a > 0 and b > 0 do
|
||||
if a % 2 == 1 and b % 2 == 1 then -- test the rightmost bits
|
||||
result = result + bitval -- set the current bit
|
||||
end
|
||||
bitval = bitval * 2 -- shift left
|
||||
a = math.floor(a/2) -- shift right
|
||||
b = math.floor(b/2)
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
local function Config_Send(page, line, value)
|
||||
local i
|
||||
i = (page*16) + line
|
||||
multiBuffer( 5, i )
|
||||
for i = 1 , 6 , 1 do
|
||||
multiBuffer( 5+i, value[i] )
|
||||
end
|
||||
multiBuffer( 4, 1 )
|
||||
end
|
||||
|
||||
local function Config_Release()
|
||||
--Set the protocol back to what it was
|
||||
Module.protocol = InitialProtocol
|
||||
model.setModule(ModuleNumber, Module)
|
||||
|
||||
--Stop requesting updates
|
||||
local i
|
||||
for i = 3 , 0 , -1 do
|
||||
multiBuffer( i, 0 )
|
||||
end
|
||||
end
|
||||
|
||||
local function Config_Page( )
|
||||
Config_Send(Page, 0, { 0, 0, 0, 0, 0, 0 })
|
||||
end
|
||||
|
||||
local function Config_Draw_Edit( event )
|
||||
local i
|
||||
local text
|
||||
|
||||
if Menu[Focus].field_type == 0xD0 then
|
||||
-- Editable Hex value
|
||||
if Edit == -1 then
|
||||
-- Init
|
||||
Edit = 0
|
||||
Edit_pos = 1
|
||||
Blink = 0
|
||||
for i = 1, Menu[Focus].field_len, 1 do
|
||||
Menu_value[i] = Menu[Focus].field_value[i]
|
||||
end
|
||||
end
|
||||
if Edit == 0 then
|
||||
-- Not editing value
|
||||
if event == EVT_VIRTUAL_ENTER then
|
||||
if Edit_pos > Menu[Focus].field_len then
|
||||
-- Save or Cancel
|
||||
Edit = -1
|
||||
if Edit_pos == Menu[Focus].field_len + 1 then
|
||||
-- Save
|
||||
Config_Send(Page, Focus, Menu_value)
|
||||
end
|
||||
return
|
||||
else
|
||||
-- Switch to edit mode
|
||||
Edit = 1
|
||||
end
|
||||
elseif event == EVT_VIRTUAL_PREV and Edit_pos > 1 then
|
||||
-- Move cursor
|
||||
Edit_pos = Edit_pos - 1
|
||||
elseif event == EVT_VIRTUAL_NEXT and Edit_pos < Menu[Focus].field_len + 2 then
|
||||
-- Move cursor
|
||||
Edit_pos = Edit_pos + 1
|
||||
end
|
||||
else
|
||||
-- Editing value
|
||||
if event == EVT_VIRTUAL_ENTER then
|
||||
-- End edit
|
||||
Edit = 0
|
||||
elseif event == EVT_VIRTUAL_PREV then
|
||||
-- Change value
|
||||
Menu_value[Edit_pos] = Menu_value[Edit_pos] - 1
|
||||
elseif event == EVT_VIRTUAL_NEXT then
|
||||
-- Change value
|
||||
Menu_value[Edit_pos] = Menu_value[Edit_pos] + 1
|
||||
end
|
||||
--Blink
|
||||
Blink = Blink + 1
|
||||
if Blink > 30 then
|
||||
Blink = 0
|
||||
end
|
||||
end
|
||||
--Display
|
||||
if LCD_W == 480 then
|
||||
lcd.drawRectangle(160-1, 100-1, 160+2, 55+2, TEXT_COLOR)
|
||||
lcd.drawFilledRectangle(160, 100, 160, 55, TEXT_BGCOLOR)
|
||||
else
|
||||
lcd.clear()
|
||||
end
|
||||
for i = 1, Menu[Focus].field_len, 1 do
|
||||
if i==Edit_pos and (Edit ~= 1 or Blink > 15) then
|
||||
attrib = INVERS
|
||||
else
|
||||
attrib = 0
|
||||
end
|
||||
if LCD_W == 480 then
|
||||
lcd.drawText(170+12*2*(i-1), 110, string.format('%02X', Menu_value[i]), attrib)
|
||||
else
|
||||
lcd.drawText(17+6*2*(i-1), 10, string.format('%02X', Menu_value[i]), attrib + SMLSIZE)
|
||||
end
|
||||
end
|
||||
if Edit_pos == Menu[Focus].field_len + 1 then
|
||||
attrib = INVERS
|
||||
else
|
||||
attrib = 0
|
||||
end
|
||||
if LCD_W == 480 then
|
||||
lcd.drawText(170, 130, "Save", attrib)
|
||||
else
|
||||
lcd.drawText(17, 30, "Save", attrib + SMLSIZE)
|
||||
end
|
||||
if Edit_pos == Menu[Focus].field_len + 2 then
|
||||
attrib = INVERS
|
||||
else
|
||||
attrib = 0
|
||||
end
|
||||
if LCD_W == 480 then
|
||||
lcd.drawText(260, 130, "Cancel", attrib)
|
||||
else
|
||||
lcd.drawText(77, 30, "Cancel", attrib + SMLSIZE)
|
||||
end
|
||||
|
||||
elseif Menu[Focus].field_type == 0x90 then
|
||||
-- Action text
|
||||
if Edit == -1 then
|
||||
-- Init
|
||||
Edit = 0
|
||||
Edit_pos = 2
|
||||
end
|
||||
if event == EVT_VIRTUAL_ENTER then
|
||||
-- Exit
|
||||
Edit = -1
|
||||
if Edit_pos == 1 then
|
||||
-- Yes
|
||||
Config_Send(Page, Focus, { 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA } )
|
||||
end
|
||||
return
|
||||
elseif event == EVT_VIRTUAL_PREV and Edit_pos > 1 then
|
||||
-- Switch to Yes
|
||||
Edit_pos = Edit_pos - 1
|
||||
elseif event == EVT_VIRTUAL_NEXT and Edit_pos < 2 then
|
||||
-- Switch to No
|
||||
Edit_pos = Edit_pos + 1
|
||||
end
|
||||
-- Display
|
||||
if LCD_W == 480 then
|
||||
lcd.drawRectangle(160-1, 100-1, 160+2, 55+2, TEXT_COLOR)
|
||||
lcd.drawFilledRectangle(160, 100, 160, 55, TEXT_BGCOLOR)
|
||||
else
|
||||
lcd.clear()
|
||||
end
|
||||
if LCD_W == 480 then
|
||||
lcd.drawText(170, 110, Menu[Focus].field_text .. "?")
|
||||
else
|
||||
lcd.drawText(17, 10, Menu[Focus].field_text .. "?", SMLSIZE)
|
||||
end
|
||||
if Edit_pos == 1 then
|
||||
attrib = INVERS
|
||||
else
|
||||
attrib = 0
|
||||
end
|
||||
if LCD_W == 480 then
|
||||
lcd.drawText(170, 130, "Yes", attrib)
|
||||
else
|
||||
lcd.drawText(17, 30, "Yes", attrib + SMLSIZE)
|
||||
end
|
||||
if Edit_pos == 2 then
|
||||
attrib = INVERS
|
||||
else
|
||||
attrib = 0
|
||||
end
|
||||
if LCD_W == 480 then
|
||||
lcd.drawText(260, 130, "No", attrib)
|
||||
else
|
||||
lcd.drawText(77, 30, "No", attrib)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function Config_Next_Prev( event )
|
||||
-- Next Prev on main menu
|
||||
local line
|
||||
if event == EVT_VIRTUAL_PREV then
|
||||
for line = Focus - 1, 1, -1 do
|
||||
if Menu[line].field_type >= 0x80 and Menu[line].field_type ~= 0xA0 and Menu[line].field_type ~= 0xC0 then
|
||||
Focus = line
|
||||
break
|
||||
end
|
||||
end
|
||||
elseif event == EVT_VIRTUAL_NEXT then
|
||||
for line = Focus + 1, 7, 1 do
|
||||
if Menu[line].field_type >= 0x80 and Menu[line].field_type ~= 0xA0 and Menu[line].field_type ~= 0xC0 then
|
||||
Focus = line
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function Config_Draw_Menu()
|
||||
-- Main menu
|
||||
local i
|
||||
local value
|
||||
local line
|
||||
local length
|
||||
local text
|
||||
|
||||
lcd.clear()
|
||||
|
||||
if LCD_W == 480 then
|
||||
--Draw title
|
||||
lcd.drawFilledRectangle(0, 0, LCD_W, 30, TITLE_BGCOLOR)
|
||||
lcd.drawText(1, 5, "Multi Config " .. Version, MENU_TITLE_COLOR)
|
||||
if multiBuffer(13) == 0x00 then
|
||||
lcd.drawText(10,50,"No Config telemetry...", BLINK)
|
||||
end
|
||||
else
|
||||
--Draw on LCD_W=128
|
||||
lcd.drawText(1, 0, "Multi Config " .. Version, SMLSIZE)
|
||||
if multiBuffer(13) == 0x00 then
|
||||
lcd.drawText(2,17,"No Config telemetry...",SMLSIZE)
|
||||
end
|
||||
end
|
||||
|
||||
if multiBuffer(13) ~= 0x00 then
|
||||
if LCD_W == 480 then
|
||||
--Draw firmware version and channels order
|
||||
local ch_order = multiBuffer(17)
|
||||
local channel_names = {}
|
||||
channel_names[bitand(ch_order,3)+1] = "A"
|
||||
ch_order = math.floor(ch_order/4)
|
||||
channel_names[bitand(ch_order,3)+1] = "E"
|
||||
ch_order = math.floor(ch_order/4)
|
||||
channel_names[bitand(ch_order,3)+1] = "T"
|
||||
ch_order = math.floor(ch_order/4)
|
||||
channel_names[bitand(ch_order,3)+1] = "R"
|
||||
lcd.drawText(150, 5, ModuleType.." v" .. multiBuffer(13) .. "." .. multiBuffer(14) .. "." .. multiBuffer(15) .. "." .. multiBuffer(16) .. " " .. channel_names[1] .. channel_names[2] .. channel_names[3] .. channel_names[4], MENU_TITLE_COLOR)
|
||||
else
|
||||
lcd.drawText(76, 0, "/Fw" .. multiBuffer(13) .. "." .. multiBuffer(14) .. "." .. multiBuffer(15) .. "." .. multiBuffer(16),SMLSIZE) -- .. " " .. channel_names[1] .. channel_names[2] .. channel_names[3] .. channel_names[4])
|
||||
end
|
||||
|
||||
--Draw Menu
|
||||
for line = 1, 7, 1 do
|
||||
--Clear line info
|
||||
Menu[line].text = ""
|
||||
Menu[line].field_type = 0
|
||||
Menu[line].field_len = 0
|
||||
for i = 1, 7, 1 do
|
||||
Menu[line].field_value[i] = 0
|
||||
end
|
||||
Menu[line].field_text = ""
|
||||
length = 0
|
||||
--Read line from buffer
|
||||
for i = 0, 20-1, 1 do
|
||||
value=multiBuffer( line*20+13+i )
|
||||
if value == 0 then
|
||||
break -- end of line
|
||||
end
|
||||
if value > 0x80 and Menu[line].field_type == 0 then
|
||||
-- Read field type
|
||||
Menu[line].field_type = bitand(value, 0xF0)
|
||||
Menu[line].field_len = bitand(value, 0x0F)
|
||||
length = Menu[line].field_len
|
||||
if Menu[line].field_type ~= 0xA0 and Menu[line].field_type ~= 0xC0 and Focus == -1 then
|
||||
-- First actionnable field if nothing was selected
|
||||
Focus = line;
|
||||
end
|
||||
else
|
||||
if Menu[line].field_type == 0 then
|
||||
-- Text
|
||||
Menu[line].text = Menu[line].text .. string.char(value)
|
||||
else
|
||||
-- Menu specific fields
|
||||
length = length - 1
|
||||
if Menu[line].field_type == 0x80 or Menu[line].field_type == 0x90 then
|
||||
Menu[line].field_text = Menu[line].field_text .. string.char(value)
|
||||
else
|
||||
Menu[line].field_value[Menu[line].field_len-length] = value
|
||||
end
|
||||
if length == 0 then
|
||||
-- End of fields
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
-- Display menu text
|
||||
if Menu[line].text ~= "" then
|
||||
if Menu[line].field_type == 0xA0 or Menu[line].field_type == 0xB0 or Menu[line].field_type == 0xC0 or Menu[line].field_type == 0xD0 then
|
||||
Menu[line].text = Menu[line].text .. ":"
|
||||
end
|
||||
if LCD_W == 480 then
|
||||
lcd.drawText(10,32+20*line,Menu[line].text )
|
||||
else
|
||||
lcd.drawText(2,1+8*line,Menu[line].text,SMLSIZE)
|
||||
end
|
||||
end
|
||||
-- Display specific fields
|
||||
if line == Focus then
|
||||
attrib = INVERS
|
||||
else
|
||||
attrib = 0
|
||||
end
|
||||
if Menu[line].field_type == 0x80 or Menu[line].field_type == 0x90 then
|
||||
-- Text
|
||||
if LCD_W == 480 then
|
||||
lcd.drawText(10+9*#Menu[line].text, 32+20*line, Menu[line].field_text, attrib)
|
||||
else
|
||||
lcd.drawText(2+5*#Menu[line].text, 1+8*line, Menu[line].field_text, SMLSIZE + attrib)
|
||||
end
|
||||
elseif Menu[line].field_type == 0xA0 or Menu[line].field_type == 0xB0 then
|
||||
-- Decimal value
|
||||
value = 0
|
||||
for i = 1, Menu[line].field_len, 1 do
|
||||
value = value*256 + value
|
||||
end
|
||||
if LCD_W == 480 then
|
||||
lcd.drawText(10+9*#Menu[line].text, 32+20*line, value, attrib)
|
||||
else
|
||||
lcd.drawText(2+5*#Menu[line].text, 1+8*line, value, SMLSIZE + attrib)
|
||||
end
|
||||
elseif Menu[line].field_type == 0xC0 or Menu[line].field_type == 0xD0 then
|
||||
-- Hex value
|
||||
text=""
|
||||
for i = 1, Menu[line].field_len, 1 do
|
||||
text = text .. string.format('%02X ', Menu[line].field_value[i])
|
||||
end
|
||||
if LCD_W == 480 then
|
||||
lcd.drawText(10+9*#Menu[line].text, 32+20*line, text, attrib)
|
||||
else
|
||||
lcd.drawText(2+5*#Menu[line].text, 1+8*line, text, SMLSIZE + attrib)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Init
|
||||
local function Config_Init()
|
||||
--Find Multi module
|
||||
Module_int = model.getModule(0)
|
||||
Module_ext = model.getModule(1)
|
||||
if Module_int["Type"] ~= 6 and Module_ext["Type"] ~= 6 then
|
||||
error("No Multi module detected...")
|
||||
return 2
|
||||
end
|
||||
if Module_int["Type"] == 6 and Module_ext["Type"] == 6 then
|
||||
error("Two Multi modules detected, turn on only the one to be configured.")
|
||||
return 2
|
||||
end
|
||||
if Module_int["Type"] == 6 then
|
||||
ModuleNumber = 0
|
||||
ModuleType = "Internal"
|
||||
else
|
||||
ModuleNumber = 1
|
||||
ModuleType = "External"
|
||||
end
|
||||
--Get Module settings and set it to config protocol
|
||||
Module = model.getModule(ModuleNumber)
|
||||
InitialProtocol = Module.protocol
|
||||
Module.protocol = 86
|
||||
model.setModule(ModuleNumber, Module)
|
||||
--pause while waiting for the module to switch to config
|
||||
for i = 0, 10, 1 do end
|
||||
|
||||
--Set protocol to talk to
|
||||
multiBuffer( 0, string.byte('C') )
|
||||
--test if value has been written
|
||||
if multiBuffer( 0 ) ~= string.byte('C') then
|
||||
error("Not enough memory!")
|
||||
return 2
|
||||
end
|
||||
|
||||
--Request init of the buffer
|
||||
multiBuffer( 4, 0xFF )
|
||||
multiBuffer(13, 0x00 )
|
||||
|
||||
--Continue buffer init
|
||||
multiBuffer( 1, string.byte('o') )
|
||||
multiBuffer( 2, string.byte('n') )
|
||||
multiBuffer( 3, string.byte('f') )
|
||||
|
||||
-- Test set
|
||||
-- multiBuffer( 12, 0 )
|
||||
-- multiBuffer( 13, 1 )
|
||||
-- multiBuffer( 14, 3 )
|
||||
-- multiBuffer( 15, 2 )
|
||||
-- multiBuffer( 16, 62 )
|
||||
-- multiBuffer( 17, 0 + 1*4 + 2*16 + 3*64)
|
||||
|
||||
-- multiBuffer( 33, string.byte('G') )
|
||||
-- multiBuffer( 34, string.byte('l') )
|
||||
-- multiBuffer( 35, string.byte('o') )
|
||||
-- multiBuffer( 36, string.byte('b') )
|
||||
-- multiBuffer( 37, string.byte('a') )
|
||||
-- multiBuffer( 38, string.byte('l') )
|
||||
-- multiBuffer( 39, string.byte(' ') )
|
||||
-- multiBuffer( 40, string.byte('I') )
|
||||
-- multiBuffer( 41, string.byte('D') )
|
||||
-- multiBuffer( 42, 0xD0 + 4 )
|
||||
-- multiBuffer( 43, 0x12 )
|
||||
-- multiBuffer( 44, 0x34 )
|
||||
-- multiBuffer( 45, 0x56 )
|
||||
-- multiBuffer( 46, 0x78 )
|
||||
-- multiBuffer( 47, 0x9A )
|
||||
-- multiBuffer( 48, 0xBC )
|
||||
|
||||
-- multiBuffer( 53, 0x90 + 9 )
|
||||
-- multiBuffer( 54, string.byte('R') )
|
||||
-- multiBuffer( 55, string.byte('e') )
|
||||
-- multiBuffer( 56, string.byte('s') )
|
||||
-- multiBuffer( 57, string.byte('e') )
|
||||
-- multiBuffer( 58, string.byte('t') )
|
||||
-- multiBuffer( 59, string.byte(' ') )
|
||||
-- multiBuffer( 60, string.byte('G') )
|
||||
-- multiBuffer( 61, string.byte('I') )
|
||||
-- multiBuffer( 62, string.byte('D') )
|
||||
-- multiBuffer( 63, 0x00 )
|
||||
end
|
||||
|
||||
-- Main
|
||||
local function Config_Run(event)
|
||||
if event == nil then
|
||||
error("Cannot be run as a model script!")
|
||||
return 2
|
||||
elseif event == EVT_VIRTUAL_EXIT then
|
||||
Config_Release()
|
||||
return 2
|
||||
else
|
||||
Config_Draw_Menu()
|
||||
if ( event == EVT_VIRTUAL_PREV_PAGE or event == EVT_VIRTUAL_NEXT_PAGE ) and Edit < 1 then
|
||||
-- Not editing, ok to change page
|
||||
if event == EVT_VIRTUAL_PREV_PAGE then
|
||||
killEvents(event)
|
||||
if Page > 0 then
|
||||
--Page = Page - 1
|
||||
--Config_Page()
|
||||
end
|
||||
else
|
||||
--Page = Page + 1
|
||||
--Config_Page()
|
||||
end
|
||||
end
|
||||
if Focus > 0 then
|
||||
-- At least one line has an action
|
||||
if Edit >= 0 then
|
||||
-- Currently editing
|
||||
Config_Draw_Edit( event )
|
||||
elseif event == EVT_VIRTUAL_ENTER then
|
||||
-- Switch to edit
|
||||
Config_Draw_Edit( 0 )
|
||||
elseif event == EVT_VIRTUAL_PREV or event == EVT_VIRTUAL_NEXT then
|
||||
-- Main menu selection
|
||||
Config_Next_Prev( event )
|
||||
end
|
||||
end
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
||||
return { init=Config_Init, run=Config_Run }
|
||||
@@ -13,6 +13,17 @@ If you like this project and want to support further development please consider
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
## MultiConfig
|
||||
|
||||
Enables to modify on a Multi module the Global ID, Cyrf ID or format the EEPROM.
|
||||
|
||||
Notes:
|
||||
- Supported from Multi v1.3.2.85 or above and OpenTX 2.3.12 or above
|
||||
- The Multi module to be configured must be active, if there is a second Multi module in the radio it must be off
|
||||
- Located on the radio SD card under \SCRIPTS\TOOLS
|
||||
|
||||
[](https://www.youtube.com/watch?v=lGyCV2kpqHU)
|
||||
|
||||
## MultiChannelsUpdater
|
||||
|
||||
Automatically name the channels based on the loaded Multi protocol and sub protocol including the module channel order convention.
|
||||
|
||||
@@ -29,7 +29,7 @@ void A7105_WriteData(uint8_t len, uint8_t channel)
|
||||
A7105_CSN_on;
|
||||
if(protocol!=PROTO_WFLY2)
|
||||
{
|
||||
if(!(protocol==PROTO_FLYSKY || protocol==PROTO_KYOSHO))
|
||||
if(!(protocol==PROTO_FLYSKY || (protocol==PROTO_KYOSHO && sub_protocol==KYOSHO_HYPE)))
|
||||
{
|
||||
A7105_Strobe(A7105_STANDBY); //Force standby mode, ie cancel any TX or RX...
|
||||
A7105_SetTxRxMode(TX_EN); //Switch to PA
|
||||
@@ -210,6 +210,11 @@ void A7105_AdjustLOBaseFreq(uint8_t cmd)
|
||||
offset=(int16_t)FORCE_KYOSHO_TUNING;
|
||||
#endif
|
||||
break;
|
||||
case PROTO_JOYSWAY:
|
||||
#ifdef FORCE_JOYSWAY_TUNING
|
||||
offset=(int16_t)FORCE_JOYSWAY_TUNING;
|
||||
#endif
|
||||
break;
|
||||
case PROTO_WFLY2:
|
||||
#ifdef FORCE_WFLY2_TUNING
|
||||
offset=(int16_t)FORCE_WFLY2_TUNING;
|
||||
@@ -341,6 +346,14 @@ const uint8_t PROGMEM WFLY2_A7105_regs[] = {
|
||||
0x01, 0x0f // 30 - 31
|
||||
};
|
||||
#endif
|
||||
#ifdef JOYSWAY_A7105_INO
|
||||
const uint8_t PROGMEM JOYSWAY_A7105_regs[] = {
|
||||
0xff, 0x62, 0xff, 0x0F, 0x00, 0xff, 0xff ,0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0xF5, 0x00, 0x15, // 00 - 0f
|
||||
0x9E, 0x4B, 0x00, 0x03, 0x56, 0x2B, 0x12, 0x4A, 0x02, 0x80, 0x80, 0x00, 0x0E, 0x91, 0x03, 0x0F, // 10 - 1f
|
||||
0x16, 0x2A, 0x00, 0xff, 0xff, 0xff, 0x3A, 0x06, 0x1F, 0x47, 0x80, 0x01, 0x05, 0x45, 0x18, 0x00, // 20 - 2f
|
||||
0x01, 0x0f // 30 - 31
|
||||
};
|
||||
#endif
|
||||
|
||||
#define ID_NORMAL 0x55201041
|
||||
#define ID_PLUS 0xAA201041
|
||||
@@ -349,6 +362,13 @@ void A7105_Init(void)
|
||||
uint8_t *A7105_Regs=0;
|
||||
uint8_t vco_calibration0, vco_calibration1;
|
||||
|
||||
#ifdef JOYSWAY_A7105_INO
|
||||
if(protocol==PROTO_JOYSWAY)
|
||||
{
|
||||
A7105_Regs=(uint8_t*)JOYSWAY_A7105_regs;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifdef WFLY2_A7105_INO
|
||||
if(protocol==PROTO_WFLY2)
|
||||
{
|
||||
@@ -479,9 +499,17 @@ void A7105_Init(void)
|
||||
vco_calibration1=0x02;
|
||||
break;
|
||||
case PROTO_PELIKAN:
|
||||
if(sub_protocol == PELIKAN_SCX24)
|
||||
{
|
||||
vco_calibration1=0x0A;
|
||||
break;
|
||||
}
|
||||
case PROTO_KYOSHO: //sub_protocol Hype
|
||||
vco_calibration1=0x0C;
|
||||
break;
|
||||
case PROTO_JOYSWAY:
|
||||
vco_calibration1=0x09;
|
||||
break;
|
||||
default:
|
||||
vco_calibration1=0x0A;
|
||||
break;
|
||||
|
||||
@@ -28,7 +28,7 @@ enum {
|
||||
AFHDS2A_RX_DATA
|
||||
};
|
||||
|
||||
static void __attribute__((unused)) AFHDS2A_Rx_build_telemetry_packet()
|
||||
static void __attribute__((unused)) AFHDS2A_RX_build_telemetry_packet()
|
||||
{
|
||||
uint32_t bits = 0;
|
||||
uint8_t bitsavailable = 0;
|
||||
@@ -56,13 +56,13 @@ static void __attribute__((unused)) AFHDS2A_Rx_build_telemetry_packet()
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t __attribute__((unused)) AFHDS2A_Rx_data_ready()
|
||||
static uint8_t __attribute__((unused)) AFHDS2A_RX_data_ready()
|
||||
{
|
||||
// check if FECF+CRCF Ok
|
||||
return !(A7105_ReadReg(A7105_00_MODE) & (1 << 5 | 1 << 6 | 1 << 0));
|
||||
}
|
||||
|
||||
uint16_t initAFHDS2A_Rx()
|
||||
void AFHDS2A_RX_init()
|
||||
{
|
||||
uint8_t i;
|
||||
A7105_Init();
|
||||
@@ -84,12 +84,11 @@ uint16_t initAFHDS2A_Rx()
|
||||
hopping_frequency[i] = eeprom_read_byte((EE_ADDR)temp++);
|
||||
phase = AFHDS2A_RX_DATA;
|
||||
}
|
||||
return 1000;
|
||||
}
|
||||
|
||||
#define AFHDS2A_RX_WAIT_WRITE 0x80
|
||||
|
||||
uint16_t AFHDS2A_Rx_callback()
|
||||
uint16_t AFHDS2A_RX_callback()
|
||||
{
|
||||
static int8_t read_retry;
|
||||
int16_t temp;
|
||||
@@ -105,9 +104,13 @@ uint16_t AFHDS2A_Rx_callback()
|
||||
|
||||
switch(phase) {
|
||||
case AFHDS2A_RX_BIND1:
|
||||
if(IS_BIND_DONE) return initAFHDS2A_Rx(); // Abort bind
|
||||
if(IS_BIND_DONE)
|
||||
{
|
||||
AFHDS2A_RX_init(); // Abort bind
|
||||
break;
|
||||
}
|
||||
debugln("bind p=%d", phase+1);
|
||||
if (AFHDS2A_Rx_data_ready()) {
|
||||
if (AFHDS2A_RX_data_ready()) {
|
||||
A7105_ReadData(AFHDS2A_RX_TXPACKET_SIZE);
|
||||
if ((packet[0] == 0xbb && packet[9] == 0x01) || (packet[0] == 0xbc && packet[9] <= 0x02)) {
|
||||
memcpy(rx_id, &packet[1], 4); // TX id actually
|
||||
@@ -121,9 +124,13 @@ uint16_t AFHDS2A_Rx_callback()
|
||||
return 10000;
|
||||
|
||||
case AFHDS2A_RX_BIND2:
|
||||
if(IS_BIND_DONE) return initAFHDS2A_Rx(); // Abort bind
|
||||
if(IS_BIND_DONE)
|
||||
{
|
||||
AFHDS2A_RX_init(); // Abort bind
|
||||
break;
|
||||
}
|
||||
// got 2nd bind packet from tx ?
|
||||
if (AFHDS2A_Rx_data_ready()) {
|
||||
if (AFHDS2A_RX_data_ready()) {
|
||||
A7105_ReadData(AFHDS2A_RX_TXPACKET_SIZE);
|
||||
if ((packet[0] == 0xBC && packet[9] == 0x02 && packet[10] == 0x00) &&
|
||||
(memcmp(rx_id, &packet[1], 4) == 0) &&
|
||||
@@ -156,7 +163,8 @@ uint16_t AFHDS2A_Rx_callback()
|
||||
{
|
||||
debugln("done");
|
||||
BIND_DONE;
|
||||
return initAFHDS2A_Rx(); // Restart protocol
|
||||
AFHDS2A_RX_init(); // Restart protocol
|
||||
break;
|
||||
}
|
||||
phase |= AFHDS2A_RX_WAIT_WRITE;
|
||||
return 1700;
|
||||
@@ -173,14 +181,18 @@ uint16_t AFHDS2A_Rx_callback()
|
||||
return 10000;
|
||||
|
||||
case AFHDS2A_RX_DATA:
|
||||
if (AFHDS2A_Rx_data_ready()) {
|
||||
if (AFHDS2A_RX_data_ready()) {
|
||||
A7105_ReadData(AFHDS2A_RX_TXPACKET_SIZE);
|
||||
if (memcmp(&packet[1], rx_id, 4) == 0 && memcmp(&packet[5], rx_tx_addr, 4) == 0) {
|
||||
if (packet[0] == 0x58 && packet[37] == 0x00 && telemetry_link == 0) { // standard packet, send channels to TX
|
||||
if (packet[0] == 0x58 && packet[37] == 0x00 && (telemetry_link&0x7F) == 0) { // standard packet, send channels to TX
|
||||
int rssi = min(A7105_ReadReg(A7105_1D_RSSI_THOLD),160);
|
||||
RX_RSSI = map16b(rssi, 160, 8, 0, 128);
|
||||
AFHDS2A_Rx_build_telemetry_packet();
|
||||
AFHDS2A_RX_build_telemetry_packet();
|
||||
telemetry_link = 1;
|
||||
#ifdef SEND_CPPM
|
||||
if(sub_protocol>0)
|
||||
telemetry_link |= 0x80; // Disable telemetry output
|
||||
#endif
|
||||
}
|
||||
rx_data_started = true;
|
||||
read_retry = 10; // hop to next channel
|
||||
|
||||
@@ -277,7 +277,7 @@ static void AFHDS2A_build_packet(uint8_t type)
|
||||
#define AFHDS2A_WRITE_TIME 1700
|
||||
#endif
|
||||
|
||||
uint16_t ReadAFHDS2A()
|
||||
uint16_t AFHDS2A_callback()
|
||||
{
|
||||
static uint8_t packet_type;
|
||||
static uint16_t packet_counter;
|
||||
@@ -293,8 +293,8 @@ uint16_t ReadAFHDS2A()
|
||||
case AFHDS2A_BIND3:
|
||||
AFHDS2A_build_bind_packet();
|
||||
A7105_WriteData(AFHDS2A_TXPACKET_SIZE, packet_count%2 ? 0x0d : 0x8c);
|
||||
if(!(A7105_ReadReg(A7105_00_MODE) & (1<<5 | 1<<6)))
|
||||
{ // FECF+CRCF Ok
|
||||
if(!(A7105_ReadReg(A7105_00_MODE) & (1<<5))) // removed FECF check due to issues with fs-x6b -> & (1<<5 | 1<<6)
|
||||
{ // CRCF Ok
|
||||
A7105_ReadData(AFHDS2A_RXPACKET_SIZE);
|
||||
if(packet[0] == 0xbc && packet[9] == 0x01)
|
||||
{
|
||||
@@ -310,14 +310,14 @@ uint16_t ReadAFHDS2A()
|
||||
}
|
||||
phase = AFHDS2A_BIND4;
|
||||
packet_count++;
|
||||
return 3850;
|
||||
break;
|
||||
}
|
||||
}
|
||||
packet_count++;
|
||||
if(IS_BIND_DONE)
|
||||
{ // exit bind if asked to do so from the GUI
|
||||
phase = AFHDS2A_BIND4;
|
||||
return 3850;
|
||||
break;
|
||||
}
|
||||
phase |= AFHDS2A_WAIT_WRITE;
|
||||
return AFHDS2A_WRITE_TIME;
|
||||
@@ -348,7 +348,7 @@ uint16_t ReadAFHDS2A()
|
||||
phase = AFHDS2A_DATA_INIT;
|
||||
BIND_DONE;
|
||||
}
|
||||
return 3850;
|
||||
break;
|
||||
case AFHDS2A_DATA_INIT:
|
||||
packet_counter=0;
|
||||
packet_type = AFHDS2A_PACKET_STICKS;
|
||||
@@ -358,8 +358,7 @@ uint16_t ReadAFHDS2A()
|
||||
telemetry_set_input_sync(3850);
|
||||
#endif
|
||||
AFHDS2A_build_packet(packet_type);
|
||||
if((A7105_ReadReg(A7105_00_MODE) & 0x01)==0) // Check if something has been received...
|
||||
data_rx=1; // Yes
|
||||
data_rx=A7105_ReadReg(A7105_00_MODE); // Check if something has been received...
|
||||
A7105_WriteData(AFHDS2A_TXPACKET_SIZE, hopping_frequency[hopping_frequency_no++]);
|
||||
if(hopping_frequency_no >= AFHDS2A_NUMFREQ)
|
||||
hopping_frequency_no = 0;
|
||||
@@ -377,8 +376,8 @@ uint16_t ReadAFHDS2A()
|
||||
#endif
|
||||
packet_type = AFHDS2A_PACKET_STICKS; // todo : check for settings changes
|
||||
}
|
||||
if(!(A7105_ReadReg(A7105_00_MODE) & (1<<5 | 1<<6)) && data_rx==1)
|
||||
{ // RX+FECF+CRCF Ok
|
||||
if(!(A7105_ReadReg(A7105_00_MODE) & (1<<5)) && !(data_rx & 1)) // removed FECF check due to issues with fs-x6b -> & (1<<5 | 1<<6)
|
||||
{ // RX+CRCF Ok
|
||||
A7105_ReadData(AFHDS2A_RXPACKET_SIZE);
|
||||
if(packet[0] == 0xAA && packet[9] == 0xFC)
|
||||
packet_type=AFHDS2A_PACKET_SETTINGS; // RX is asking for settings
|
||||
@@ -417,10 +416,10 @@ uint16_t ReadAFHDS2A()
|
||||
phase &= ~AFHDS2A_WAIT_WRITE;
|
||||
return 3850-AFHDS2A_WRITE_TIME;
|
||||
}
|
||||
return 3850; // never reached, please the compiler
|
||||
return 3850;
|
||||
}
|
||||
|
||||
uint16_t initAFHDS2A()
|
||||
void AFHDS2A_init()
|
||||
{
|
||||
A7105_Init();
|
||||
|
||||
@@ -446,6 +445,5 @@ uint16_t initAFHDS2A()
|
||||
num_ch=17;
|
||||
else
|
||||
num_ch=14;
|
||||
return 50000;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -33,19 +33,14 @@ enum {
|
||||
ASSAN_DATA5
|
||||
};
|
||||
|
||||
void ASSAN_init()
|
||||
void ASSAN_RF_init()
|
||||
{
|
||||
NRF24L01_Initialize();
|
||||
//Specifics to ASSAN
|
||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x02); // 4 bytes rx/tx address
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, (uint8_t *)"\x80\x80\x80\xB8", ASSAN_ADDRESS_LENGTH); // Bind address
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, (uint8_t *)"\x80\x80\x80\xB8", ASSAN_ADDRESS_LENGTH); // Bind address
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, (uint8_t *)"\x80\x80\x80\xB8", ASSAN_ADDRESS_LENGTH); // Bind address
|
||||
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_WriteReg(NRF24L01_11_RX_PW_P0, ASSAN_PACKET_SIZE);
|
||||
NRF24L01_SetPower();
|
||||
}
|
||||
|
||||
void ASSAN_send_packet()
|
||||
@@ -169,17 +164,16 @@ static void __attribute__((unused)) ASSAN_initialize_txid()
|
||||
hopping_frequency[1]=freq2;
|
||||
}
|
||||
|
||||
uint16_t initASSAN()
|
||||
void ASSAN_init()
|
||||
{
|
||||
ASSAN_initialize_txid();
|
||||
ASSAN_init();
|
||||
ASSAN_RF_init();
|
||||
hopping_frequency_no = 0;
|
||||
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
phase=ASSAN_BIND0;
|
||||
else
|
||||
phase=ASSAN_DATA0;
|
||||
return 1000;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
#if defined(BUGSMINI_NRF24L01_INO)
|
||||
|
||||
#include "iface_nrf24l01.h"
|
||||
#include "iface_xn297.h"
|
||||
|
||||
#define BUGSMINI_INITIAL_WAIT 500
|
||||
#define BUGSMINI_PACKET_INTERVAL 6840
|
||||
@@ -57,22 +57,10 @@ enum {
|
||||
#define BUGSMINI_FLAG_ANGLE 0x02 // angle/acro mode (set is angle mode)
|
||||
#define BUGSMINI_FLAG_ALTHOLD 0x04 // angle/altitude hold mode (set is altitude mode)
|
||||
|
||||
static void __attribute__((unused)) BUGSMINI_init()
|
||||
static void __attribute__((unused)) BUGSMINI_RF_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_WriteReg(NRF24L01_11_RX_PW_P0, BUGSMINI_RX_PAYLOAD_SIZE); // bytes of data payload for rx pipe 1
|
||||
NRF24L01_WriteReg(NRF24L01_06_RF_SETUP, 0x07);
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_1M);
|
||||
NRF24L01_SetPower();
|
||||
NRF24L01_Activate(0x73); // Activate feature register
|
||||
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x00); // Disable dynamic payload length on all pipes
|
||||
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x00); // Set feature bits on
|
||||
XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M);
|
||||
//XN297_HoppingCalib(BUGSMINI_NUM_RF_CHANNELS*2);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) BUGSMINI_check_arming()
|
||||
@@ -95,7 +83,7 @@ static void __attribute__((unused)) BUGSMINI_check_arming()
|
||||
}
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) BUGSMINI_send_packet(uint8_t bind)
|
||||
static void __attribute__((unused)) BUGSMINI_send_packet()
|
||||
{
|
||||
BUGSMINI_check_arming(); // sets globals arm_flags and armed
|
||||
|
||||
@@ -107,7 +95,7 @@ static void __attribute__((unused)) BUGSMINI_send_packet(uint8_t bind)
|
||||
packet[1] = BUGSMINI_txid[0];
|
||||
packet[2] = BUGSMINI_txid[1];
|
||||
packet[3] = BUGSMINI_txid[2];
|
||||
if(bind)
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
packet[4] = 0x00;
|
||||
packet[5] = 0x7d;
|
||||
@@ -159,15 +147,14 @@ static void __attribute__((unused)) BUGSMINI_send_packet(uint8_t bind)
|
||||
hopping_frequency_no++;
|
||||
if(hopping_frequency_no >= BUGSMINI_NUM_RF_CHANNELS)
|
||||
hopping_frequency_no = 0;
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, bind ? hopping_frequency[hopping_frequency_no+BUGSMINI_NUM_RF_CHANNELS] : hopping_frequency[hopping_frequency_no]);
|
||||
XN297_Hopping(IS_BIND_IN_PROGRESS ? hopping_frequency[hopping_frequency_no+BUGSMINI_NUM_RF_CHANNELS] : hopping_frequency[hopping_frequency_no]);
|
||||
}
|
||||
|
||||
// Power on, TX mode, 2byte CRC
|
||||
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||
NRF24L01_FlushTx();
|
||||
// Send
|
||||
XN297_SetPower();
|
||||
XN297_SetTxRxMode(TXRX_OFF);
|
||||
XN297_SetTxRxMode(TX_EN);
|
||||
XN297_WritePayload(packet, BUGSMINI_TX_PAYLOAD_SIZE);
|
||||
NRF24L01_SetPower();
|
||||
}
|
||||
|
||||
// compute final address for the rxid received during bind
|
||||
@@ -231,37 +218,37 @@ static void __attribute__((unused)) BUGSMINI_make_address()
|
||||
// Something wrong happened if we arrive here....
|
||||
}
|
||||
|
||||
#if defined(BUGS_HUB_TELEMETRY)
|
||||
static void __attribute__((unused)) BUGSMINI_update_telemetry()
|
||||
{
|
||||
#if defined(BUGS_HUB_TELEMETRY)
|
||||
uint8_t checksum = 0x6d;
|
||||
for(uint8_t i=1; i<12; i++)
|
||||
checksum += packet[i];
|
||||
if(packet[0] == checksum)
|
||||
checksum += packet_in[i];
|
||||
if(packet_in[0] == checksum)
|
||||
{
|
||||
RX_RSSI = packet[3];
|
||||
RX_RSSI = packet_in[3];
|
||||
if(sub_protocol==BUGS3H)
|
||||
{
|
||||
if(packet[11] & 0x40)
|
||||
if(packet_in[11] & 0x40)
|
||||
v_lipo1 = 0x40; // Warning
|
||||
else if(packet[11] & 0x80)
|
||||
else if(packet_in[11] & 0x80)
|
||||
v_lipo1 = 0x20; // Critical
|
||||
else
|
||||
v_lipo1 = 0x80; // Ok
|
||||
}
|
||||
else
|
||||
{
|
||||
if(packet[11] & 0x80)
|
||||
if(packet_in[11] & 0x80)
|
||||
v_lipo1 = 0x80; // Ok
|
||||
else if(packet[11] & 0x40)
|
||||
else if(packet_in[11] & 0x40)
|
||||
v_lipo1 = 0x40; // Warning
|
||||
else
|
||||
v_lipo1 = 0x20; // Critical
|
||||
}
|
||||
telemetry_link=1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
uint16_t BUGSMINI_callback()
|
||||
{
|
||||
@@ -269,58 +256,52 @@ uint16_t BUGSMINI_callback()
|
||||
switch(phase)
|
||||
{
|
||||
case BUGSMINI_BIND1:
|
||||
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR))
|
||||
if( XN297_IsRX() )
|
||||
{ // RX fifo data ready
|
||||
XN297_ReadPayload(packet, BUGSMINI_RX_PAYLOAD_SIZE);
|
||||
XN297_ReadPayload(packet, BUGSMINI_RX_PAYLOAD_SIZE); // Not checking the CRC??
|
||||
base_adr=BUGSMINI_EEPROM_OFFSET+(RX_num&0x0F)*2;
|
||||
eeprom_write_byte((EE_ADDR)(base_adr+0),packet[1]); // Save rxid in EEPROM
|
||||
eeprom_write_byte((EE_ADDR)(base_adr+1),packet[2]); // Save rxid in EEPROM
|
||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
eeprom_write_byte((EE_ADDR)(base_adr+0),packet[1]); // Save rxid in EEPROM
|
||||
eeprom_write_byte((EE_ADDR)(base_adr+1),packet[2]); // Save rxid in EEPROM
|
||||
BUGSMINI_make_address();
|
||||
XN297_SetTXAddr(rx_tx_addr, 5);
|
||||
XN297_SetRXAddr(rx_tx_addr, 5);
|
||||
XN297_SetRXAddr(rx_tx_addr, BUGSMINI_RX_PAYLOAD_SIZE);
|
||||
phase = BUGSMINI_DATA1;
|
||||
BIND_DONE;
|
||||
return BUGSMINI_PACKET_INTERVAL;
|
||||
break;
|
||||
}
|
||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
BUGSMINI_send_packet(1);
|
||||
BUGSMINI_send_packet();
|
||||
phase = BUGSMINI_BIND2;
|
||||
return BUGSMINI_WRITE_WAIT;
|
||||
case BUGSMINI_BIND2:
|
||||
// switch to RX mode
|
||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||
NRF24L01_SetTxRxMode(RX_EN);
|
||||
NRF24L01_FlushRx();
|
||||
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO)
|
||||
| _BV(NRF24L01_00_PWR_UP) | _BV(NRF24L01_00_PRIM_RX));
|
||||
XN297_SetTxRxMode(TXRX_OFF);
|
||||
XN297_SetTxRxMode(RX_EN);
|
||||
phase = BUGSMINI_BIND1;
|
||||
return BUGSMINI_PACKET_INTERVAL - BUGSMINI_WRITE_WAIT;
|
||||
case BUGSMINI_DATA1:
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(BUGSMINI_PACKET_INTERVAL);
|
||||
#endif
|
||||
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR))
|
||||
{ // RX fifo data ready => read only 12 bytes to not overwrite channel change flag
|
||||
XN297_ReadPayload(packet, 12);
|
||||
BUGSMINI_update_telemetry();
|
||||
}
|
||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
BUGSMINI_send_packet(0);
|
||||
#if defined(BUGS_HUB_TELEMETRY)
|
||||
if( XN297_IsRX() )
|
||||
{
|
||||
XN297_ReadPayload(packet_in, BUGSMINI_RX_PAYLOAD_SIZE); // Not checking the CRC??
|
||||
BUGSMINI_update_telemetry();
|
||||
}
|
||||
#endif
|
||||
BUGSMINI_send_packet();
|
||||
#if not defined(BUGS_HUB_TELEMETRY)
|
||||
break;
|
||||
#else
|
||||
phase = BUGSMINI_DATA2;
|
||||
return BUGSMINI_WRITE_WAIT;
|
||||
case BUGSMINI_DATA2:
|
||||
// switch to RX mode
|
||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||
NRF24L01_FlushRx();
|
||||
NRF24L01_SetTxRxMode(RX_EN);
|
||||
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO)
|
||||
| _BV(NRF24L01_00_PWR_UP) | _BV(NRF24L01_00_PRIM_RX));
|
||||
XN297_SetTxRxMode(TXRX_OFF);
|
||||
XN297_SetTxRxMode(RX_EN);
|
||||
phase = BUGSMINI_DATA1;
|
||||
return BUGSMINI_PACKET_INTERVAL - BUGSMINI_WRITE_WAIT;
|
||||
#endif
|
||||
}
|
||||
return BUGSMINI_PACKET_INTERVAL;
|
||||
}
|
||||
@@ -357,28 +338,27 @@ static void __attribute__((unused)) BUGSMINI_initialize_txid()
|
||||
BUGSMINI_txhash = pgm_read_byte_near( &BUGSMINI_tx_hash[rx_tx_addr[3]%BUGSMINI_NUM_TX_RF_MAPS] );
|
||||
}
|
||||
|
||||
uint16_t initBUGSMINI()
|
||||
void BUGSMINI_init()
|
||||
{
|
||||
BUGSMINI_initialize_txid();
|
||||
BUGSMINI_RF_init();
|
||||
memset(packet, (uint8_t)0, BUGSMINI_TX_PAYLOAD_SIZE);
|
||||
BUGSMINI_init();
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
XN297_SetTXAddr((const uint8_t*)"mjxRC", 5);
|
||||
XN297_SetRXAddr((const uint8_t*)"mjxRC", 5);
|
||||
XN297_SetRXAddr((const uint8_t*)"mjxRC", BUGSMINI_RX_PAYLOAD_SIZE);
|
||||
phase = BUGSMINI_BIND1;
|
||||
}
|
||||
else
|
||||
{
|
||||
BUGSMINI_make_address();
|
||||
XN297_SetTXAddr(rx_tx_addr, 5);
|
||||
XN297_SetRXAddr(rx_tx_addr, 5);
|
||||
XN297_SetRXAddr(rx_tx_addr, BUGSMINI_RX_PAYLOAD_SIZE);
|
||||
phase = BUGSMINI_DATA1;
|
||||
}
|
||||
armed = 0;
|
||||
arm_flags = BUGSMINI_FLAG_DISARM; // initial value from captures
|
||||
arm_channel_previous = BUGSMINI_CH_SW_ARM;
|
||||
return BUGSMINI_INITIAL_WAIT;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -15,7 +15,7 @@ Multiprotocol is distributed in the hope that it will be useful,
|
||||
|
||||
#if defined(BAYANG_RX_NRF24L01_INO)
|
||||
|
||||
#include "iface_nrf24l01.h"
|
||||
#include "iface_xn297.h"
|
||||
|
||||
#define BAYANG_RX_PACKET_SIZE 15
|
||||
#define BAYANG_RX_RF_NUM_CHANNELS 4
|
||||
@@ -27,28 +27,15 @@ enum {
|
||||
BAYANG_RX_DATA
|
||||
};
|
||||
|
||||
static void __attribute__((unused)) Bayang_Rx_init_nrf24l01()
|
||||
static void __attribute__((unused)) Bayang_Rx_RF_init()
|
||||
{
|
||||
const uint8_t bind_address[BAYANG_RX_ADDRESS_LENGTH] = { 0,0,0,0,0 };
|
||||
NRF24L01_Initialize();
|
||||
XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M);
|
||||
XN297_SetTXAddr(bind_address, BAYANG_RX_ADDRESS_LENGTH);
|
||||
XN297_SetRXAddr(bind_address, BAYANG_RX_ADDRESS_LENGTH);
|
||||
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_WriteReg(NRF24L01_11_RX_PW_P0, BAYANG_RX_PACKET_SIZE + 2); // 2 extra bytes for xn297 crc
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, BAYANG_RX_RF_BIND_CHANNEL);
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps
|
||||
NRF24L01_SetPower();
|
||||
NRF24L01_Activate(0x73); // Activate feature register
|
||||
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x00); // Disable dynamic payload length on all pipes
|
||||
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x01);
|
||||
NRF24L01_Activate(0x73);
|
||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||
NRF24L01_FlushRx();
|
||||
NRF24L01_SetTxRxMode(RX_EN);
|
||||
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP) | _BV(NRF24L01_00_PRIM_RX));
|
||||
XN297_SetRXAddr(bind_address, BAYANG_RX_PACKET_SIZE);
|
||||
XN297_RFChannel(BAYANG_RX_RF_BIND_CHANNEL);
|
||||
XN297_SetTxRxMode(TXRX_OFF);
|
||||
XN297_SetTxRxMode(RX_EN);
|
||||
}
|
||||
|
||||
static uint8_t __attribute__((unused)) Bayang_Rx_check_validity() {
|
||||
@@ -98,10 +85,10 @@ static void __attribute__((unused)) Bayang_Rx_build_telemetry_packet()
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t initBayang_Rx()
|
||||
void BAYANG_RX_init()
|
||||
{
|
||||
uint8_t i;
|
||||
Bayang_Rx_init_nrf24l01();
|
||||
Bayang_Rx_RF_init();
|
||||
hopping_frequency_no = 0;
|
||||
rx_data_started = false;
|
||||
rx_data_received = false;
|
||||
@@ -115,90 +102,101 @@ uint16_t initBayang_Rx()
|
||||
rx_tx_addr[i] = eeprom_read_byte((EE_ADDR)temp++);
|
||||
for (i = 0; i < BAYANG_RX_RF_NUM_CHANNELS; i++)
|
||||
hopping_frequency[i] = eeprom_read_byte((EE_ADDR)temp++);
|
||||
//XN297_HoppingCalib(BAYANG_RX_RF_NUM_CHANNELS);
|
||||
XN297_SetTXAddr(rx_tx_addr, BAYANG_RX_ADDRESS_LENGTH);
|
||||
XN297_SetRXAddr(rx_tx_addr, BAYANG_RX_ADDRESS_LENGTH);
|
||||
XN297_SetRXAddr(rx_tx_addr, BAYANG_RX_PACKET_SIZE);
|
||||
phase = BAYANG_RX_DATA;
|
||||
}
|
||||
return 1000;
|
||||
}
|
||||
|
||||
uint16_t Bayang_Rx_callback()
|
||||
uint16_t BAYANG_RX_callback()
|
||||
{
|
||||
uint8_t i;
|
||||
static int8_t read_retry;
|
||||
|
||||
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()) {
|
||||
// store tx info into eeprom
|
||||
uint16_t temp = BAYANG_RX_EEPROM_OFFSET;
|
||||
for (i = 0; i < 5; i++) {
|
||||
rx_tx_addr[i] = packet[i + 1];
|
||||
eeprom_write_byte((EE_ADDR)temp++, rx_tx_addr[i]);
|
||||
}
|
||||
for (i = 0; i < 4; i++) {
|
||||
hopping_frequency[i] = packet[i + 6];
|
||||
eeprom_write_byte((EE_ADDR)temp++, hopping_frequency[i]);
|
||||
}
|
||||
XN297_SetTXAddr(rx_tx_addr, BAYANG_RX_ADDRESS_LENGTH);
|
||||
XN297_SetRXAddr(rx_tx_addr, BAYANG_RX_ADDRESS_LENGTH);
|
||||
BIND_DONE;
|
||||
phase = BAYANG_RX_DATA;
|
||||
}
|
||||
NRF24L01_FlushRx();
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||
}
|
||||
break;
|
||||
case BAYANG_RX_DATA:
|
||||
if (NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR)) {
|
||||
if (XN297_ReadPayload(packet, BAYANG_RX_PACKET_SIZE) && packet[0] == 0xA5 && Bayang_Rx_check_validity()) {
|
||||
if (telemetry_link == 0) {
|
||||
Bayang_Rx_build_telemetry_packet();
|
||||
telemetry_link = 1;
|
||||
}
|
||||
rx_data_started = true;
|
||||
rx_data_received = true;
|
||||
read_retry = 8;
|
||||
pps_counter++;
|
||||
}
|
||||
}
|
||||
// packets per second
|
||||
if (millis() - pps_timer >= 1000) {
|
||||
pps_timer = millis();
|
||||
debugln("%d pps", pps_counter);
|
||||
RX_LQI = pps_counter >> 1;
|
||||
pps_counter = 0;
|
||||
}
|
||||
// frequency hopping
|
||||
if (read_retry++ >= 8) {
|
||||
hopping_frequency_no++;
|
||||
if (hopping_frequency_no >= BAYANG_RX_RF_NUM_CHANNELS)
|
||||
hopping_frequency_no = 0;
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no]);
|
||||
NRF24L01_FlushRx();
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||
if (rx_data_started)
|
||||
switch (phase)
|
||||
{
|
||||
case BAYANG_RX_BIND:
|
||||
if(IS_BIND_DONE)
|
||||
{
|
||||
if(rx_data_received)
|
||||
{ // In sync
|
||||
rx_data_received = false;
|
||||
read_retry = 5;
|
||||
return 1500;
|
||||
BAYANG_RX_init(); // Abort bind
|
||||
break;
|
||||
}
|
||||
if ( XN297_IsRX() )
|
||||
{
|
||||
debugln("RX");
|
||||
// data received from TX
|
||||
if (XN297_ReadPayload(packet, BAYANG_RX_PACKET_SIZE) && ( packet[0] == 0xA4 || packet[0] == 0xA2 ) && Bayang_Rx_check_validity())
|
||||
{
|
||||
// store tx info into eeprom
|
||||
uint16_t temp = BAYANG_RX_EEPROM_OFFSET;
|
||||
for (i = 0; i < 5; i++) {
|
||||
rx_tx_addr[i] = packet[i + 1];
|
||||
eeprom_write_byte((EE_ADDR)temp++, rx_tx_addr[i]);
|
||||
}
|
||||
for (i = 0; i < 4; i++) {
|
||||
hopping_frequency[i] = packet[i + 6];
|
||||
eeprom_write_byte((EE_ADDR)temp++, hopping_frequency[i]);
|
||||
}
|
||||
//XN297_HoppingCalib(BAYANG_RX_RF_NUM_CHANNELS);
|
||||
XN297_SetTXAddr(rx_tx_addr, BAYANG_RX_ADDRESS_LENGTH);
|
||||
XN297_SetRXAddr(rx_tx_addr, BAYANG_RX_PACKET_SIZE);
|
||||
BIND_DONE;
|
||||
phase = BAYANG_RX_DATA;
|
||||
}
|
||||
XN297_SetTxRxMode(RX_EN);
|
||||
}
|
||||
break;
|
||||
case BAYANG_RX_DATA:
|
||||
if ( XN297_IsRX() ) {
|
||||
if (XN297_ReadPayload(packet, BAYANG_RX_PACKET_SIZE) && packet[0] == 0xA5 && Bayang_Rx_check_validity()) {
|
||||
if ((telemetry_link & 0x7F) == 0) {
|
||||
Bayang_Rx_build_telemetry_packet();
|
||||
telemetry_link = 1;
|
||||
#ifdef SEND_CPPM
|
||||
if(sub_protocol>0)
|
||||
telemetry_link |= 0x80; // Disable telemetry output
|
||||
#endif
|
||||
}
|
||||
rx_data_started = true;
|
||||
rx_data_received = true;
|
||||
read_retry = 8;
|
||||
pps_counter++;
|
||||
}
|
||||
}
|
||||
// packets per second
|
||||
if (millis() - pps_timer >= 1000) {
|
||||
pps_timer = millis();
|
||||
debugln("%d pps", pps_counter);
|
||||
RX_LQI = pps_counter >> 1;
|
||||
pps_counter = 0;
|
||||
}
|
||||
// frequency hopping
|
||||
if (read_retry++ >= 8) {
|
||||
hopping_frequency_no++;
|
||||
if (hopping_frequency_no >= BAYANG_RX_RF_NUM_CHANNELS)
|
||||
hopping_frequency_no = 0;
|
||||
XN297_Hopping(hopping_frequency_no);
|
||||
XN297_SetTxRxMode(RX_EN);
|
||||
if (rx_data_started)
|
||||
{
|
||||
if(rx_data_received)
|
||||
{ // In sync
|
||||
rx_data_received = false;
|
||||
read_retry = 5;
|
||||
return 1500;
|
||||
}
|
||||
else
|
||||
{ // packet lost
|
||||
read_retry = 0;
|
||||
if(RX_LQI==0) // communication lost
|
||||
rx_data_started=false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // packet lost
|
||||
read_retry = 0;
|
||||
if(RX_LQI==0) // communication lost
|
||||
rx_data_started=false;
|
||||
}
|
||||
read_retry = -16; // retry longer until first packet is caught
|
||||
}
|
||||
else
|
||||
read_retry = -16; // retry longer until first packet is caught
|
||||
}
|
||||
return 250;
|
||||
return 250;
|
||||
}
|
||||
return 1000;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ Multiprotocol is distributed in the hope that it will be useful,
|
||||
|
||||
#if defined(BAYANG_NRF24L01_INO)
|
||||
|
||||
#include "iface_nrf24l01.h"
|
||||
#include "iface_xn297.h"
|
||||
|
||||
#define BAYANG_BIND_COUNT 1000
|
||||
#define BAYANG_PACKET_PERIOD 2000
|
||||
@@ -97,6 +97,8 @@ static void __attribute__((unused)) BAYANG_send_packet()
|
||||
}
|
||||
else
|
||||
{
|
||||
XN297_Hopping(hopping_frequency_no++);
|
||||
hopping_frequency_no%=BAYANG_RF_NUM_CHANNELS;
|
||||
uint16_t val;
|
||||
uint8_t dyntrim = 1;
|
||||
switch (sub_protocol)
|
||||
@@ -192,28 +194,18 @@ static void __attribute__((unused)) BAYANG_send_packet()
|
||||
for (uint8_t i=0; i < BAYANG_PACKET_SIZE-1; i++)
|
||||
packet[14] += packet[i];
|
||||
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, IS_BIND_IN_PROGRESS ? rf_ch_num:hopping_frequency[hopping_frequency_no++]);
|
||||
hopping_frequency_no%=BAYANG_RF_NUM_CHANNELS;
|
||||
|
||||
// Power on, TX mode, 2byte CRC
|
||||
// Why CRC0? xn297 does not interpret it - either 16-bit CRC or nothing
|
||||
NRF24L01_FlushTx();
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
||||
// Send
|
||||
XN297_SetPower();
|
||||
XN297_SetTxRxMode(TX_EN);
|
||||
XN297_WritePayload(packet, BAYANG_PACKET_SIZE);
|
||||
|
||||
NRF24L01_SetPower(); // Set tx_power
|
||||
}
|
||||
|
||||
#ifdef BAYANG_HUB_TELEMETRY
|
||||
static void __attribute__((unused)) BAYANG_check_rx(void)
|
||||
{
|
||||
if (NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR))
|
||||
if( XN297_IsRX() )
|
||||
{ // data received from model
|
||||
XN297_ReadPayload(packet, BAYANG_PACKET_SIZE);
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 255);
|
||||
|
||||
NRF24L01_FlushRx();
|
||||
XN297_ReadPayload(packet, BAYANG_PACKET_SIZE); // Strange can't test the CRC since it seems to be disabled on telemetry packets...
|
||||
uint8_t check = packet[0];
|
||||
for (uint8_t i=1; i < BAYANG_PACKET_SIZE-1; i++)
|
||||
check += packet[i];
|
||||
@@ -233,8 +225,8 @@ static void __attribute__((unused)) BAYANG_check_rx(void)
|
||||
telemetry_link=1;
|
||||
#if defined HUB_TELEMETRY
|
||||
// Multiplexed P, I, D values in packet[8] and packet[9].
|
||||
// The two most significant bits specify which term is sent.
|
||||
// Remaining 14 bits represent the value: 0 .. 16383
|
||||
// The two most significant bits specify which term is sent.
|
||||
// Remaining 14 bits represent the value: 0 .. 16383
|
||||
frsky_send_user_frame(0x24+(packet[8]>>6), packet[9], packet[8] & 0x3F ); //0x24 = ACCEL_X_ID, so ACCEL_X_ID=P, ACCEL_Y_ID=I, ACCEL_Z_ID=D
|
||||
#endif
|
||||
telemetry_counter++;
|
||||
@@ -242,41 +234,21 @@ static void __attribute__((unused)) BAYANG_check_rx(void)
|
||||
telemetry_link=0; // Don't send anything yet
|
||||
}
|
||||
}
|
||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||
XN297_SetTxRxMode(TXRX_OFF);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void __attribute__((unused)) BAYANG_init()
|
||||
static void __attribute__((unused)) BAYANG_RF_init()
|
||||
{
|
||||
NRF24L01_Initialize();
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
|
||||
XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M);
|
||||
XN297_SetTXAddr((uint8_t *)"\x00\x00\x00\x00\x00", BAYANG_ADDRESS_LENGTH);
|
||||
|
||||
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_WriteReg(NRF24L01_11_RX_PW_P0, BAYANG_PACKET_SIZE);
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps
|
||||
NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x00); // No retransmits
|
||||
NRF24L01_SetPower();
|
||||
NRF24L01_Activate(0x73); // Activate feature register
|
||||
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x00); // Disable dynamic payload length on all pipes
|
||||
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x01);
|
||||
NRF24L01_Activate(0x73);
|
||||
//XN297_HoppingCalib(BAYANG_RF_NUM_CHANNELS);
|
||||
|
||||
switch (sub_protocol)
|
||||
{
|
||||
case X16_AH:
|
||||
case IRDRONE:
|
||||
rf_ch_num = BAYANG_RF_BIND_CHANNEL_X16_AH;
|
||||
break;
|
||||
default:
|
||||
rf_ch_num = BAYANG_RF_BIND_CHANNEL;
|
||||
break;
|
||||
}
|
||||
//Set bind channel
|
||||
uint8_t ch = BAYANG_RF_BIND_CHANNEL;
|
||||
if(sub_protocol == X16_AH || sub_protocol == IRDRONE)
|
||||
ch = BAYANG_RF_BIND_CHANNEL_X16_AH;
|
||||
XN297_RFChannel(ch);
|
||||
}
|
||||
|
||||
enum {
|
||||
@@ -301,7 +273,7 @@ uint16_t BAYANG_callback()
|
||||
{
|
||||
XN297_SetTXAddr(rx_tx_addr, BAYANG_ADDRESS_LENGTH);
|
||||
#ifdef BAYANG_HUB_TELEMETRY
|
||||
XN297_SetRXAddr(rx_tx_addr, BAYANG_ADDRESS_LENGTH);
|
||||
XN297_SetRXAddr(rx_tx_addr, BAYANG_PACKET_SIZE);
|
||||
#endif
|
||||
BIND_DONE;
|
||||
phase++; //WRITE
|
||||
@@ -336,9 +308,9 @@ uint16_t BAYANG_callback()
|
||||
// switch radio to rx as soon as packet is sent
|
||||
start=(uint16_t)micros();
|
||||
while ((uint16_t)((uint16_t)micros()-(uint16_t)start) < 1000) // Wait max 1ms
|
||||
if((NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_TX_DS)))
|
||||
if(XN297_IsPacketSent())
|
||||
break;
|
||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, 0x03);
|
||||
XN297_SetTxRxMode(RX_EN);
|
||||
phase++; // READ
|
||||
return BAYANG_PACKET_TELEM_PERIOD - BAYANG_CHECK_DELAY - BAYANG_READ_DELAY;
|
||||
case BAYANG_READ:
|
||||
@@ -363,15 +335,14 @@ static void __attribute__((unused)) BAYANG_initialize_txid()
|
||||
hopping_frequency_no=0;
|
||||
}
|
||||
|
||||
uint16_t initBAYANG(void)
|
||||
void BAYANG_init(void)
|
||||
{
|
||||
BIND_IN_PROGRESS; // autobind protocol
|
||||
phase=BAYANG_BIND;
|
||||
bind_counter = BAYANG_BIND_COUNT;
|
||||
BAYANG_initialize_txid();
|
||||
BAYANG_init();
|
||||
BAYANG_RF_init();
|
||||
packet_count=0;
|
||||
return BAYANG_INITIAL_WAIT+BAYANG_PACKET_PERIOD;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -315,7 +315,7 @@ static void __attribute__((unused)) BUGS_increment_counts()
|
||||
// FIFO config is one less than desired value
|
||||
#define BUGS_FIFO_SIZE_RX 15
|
||||
#define BUGS_FIFO_SIZE_TX 21
|
||||
uint16_t ReadBUGS(void)
|
||||
uint16_t BUGS_callback(void)
|
||||
{
|
||||
uint8_t mode, base_adr;
|
||||
uint16_t rxid;
|
||||
@@ -437,7 +437,7 @@ uint16_t ReadBUGS(void)
|
||||
return packet_period;
|
||||
}
|
||||
|
||||
uint16_t initBUGS(void)
|
||||
void BUGS_init(void)
|
||||
{
|
||||
uint16_t rxid=0;
|
||||
uint8_t base_adr=BUGS_EEPROM_OFFSET+(RX_num&0x0F)*2;
|
||||
@@ -459,8 +459,6 @@ uint16_t initBUGS(void)
|
||||
armed = 0;
|
||||
arm_flags = BUGS_FLAG_DISARM; // initial value from captures
|
||||
arm_channel_previous = BUGS_CH_SW_ARM;
|
||||
|
||||
return 10000;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -190,7 +190,9 @@ static void __attribute__((unused)) CABELL_send_packet(uint8_t bindMode)
|
||||
}
|
||||
TxPacket.option = (bindMode) ? (option & (~CABELL_OPTION_MASK_CHANNEL_REDUCTION)) : option; //remove channel reduction if in bind mode
|
||||
}
|
||||
TxPacket.reserved = 0;
|
||||
|
||||
rf_ch_num = CABELL_getNextChannel (hopping_frequency,CABELL_RADIO_CHANNELS, rf_ch_num);
|
||||
TxPacket.reserved = rf_ch_num & 0x3F;
|
||||
TxPacket.modelNum = RX_num;
|
||||
uint16_t checkSum = TxPacket.modelNum + TxPacket.option + TxPacket.RxMode + TxPacket.reserved; // Start Calculate checksum
|
||||
|
||||
@@ -244,7 +246,6 @@ static void __attribute__((unused)) CABELL_send_packet(uint8_t bindMode)
|
||||
TxPacket.checkSum_LSB = checkSum & 0x00FF;
|
||||
|
||||
// Set channel for next transmission
|
||||
rf_ch_num = CABELL_getNextChannel (hopping_frequency,CABELL_RADIO_CHANNELS, rf_ch_num);
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH,rf_ch_num);
|
||||
|
||||
//NRF24L01_FlushTx(); //just in case things got hung up
|
||||
@@ -255,7 +256,7 @@ static void __attribute__((unused)) CABELL_send_packet(uint8_t bindMode)
|
||||
*p |= (packet_count++)<<7; // This causes the 8th bit of the first byte to toggle with each xmit so consecutive payloads are not identical.
|
||||
// This is a work around for a reported bug in clone NRF24L01 chips that mis-took this case for a re-transmit of the same packet.
|
||||
|
||||
CABELL_SetPower();
|
||||
NRF24L01_SetPower();
|
||||
NRF24L01_WritePayload((uint8_t*)&TxPacket, packetSize);
|
||||
|
||||
#if defined CABELL_HUB_TELEMETRY
|
||||
@@ -279,39 +280,44 @@ static void __attribute__((unused)) CABELL_send_packet(uint8_t bindMode)
|
||||
static void __attribute__((unused)) CABELL_getChannelSequence (uint8_t outArray[], uint8_t numChannels, uint64_t permutation)
|
||||
{
|
||||
/* This procedure initializes an array with the sequence progression of channels.
|
||||
* This is not the actual channels itself, but the sequence base to be used within bands of
|
||||
* This is not the actual channels itself, but the sequence base to be used within bands of
|
||||
* channels.
|
||||
*
|
||||
*
|
||||
* There are numChannels! permutations for arranging the channels
|
||||
* one of these permutations will be calculated based on the permutation input
|
||||
* permutation should be between 1 and numChannels! but the routine will constrain it
|
||||
* if these bounds are exceeded. Typically the radio's unique TX ID should be used.
|
||||
*
|
||||
*
|
||||
* The maximum numChannels is 20. Anything larger than this will cause the uint64_t
|
||||
* variables to overflow, yielding unknown results (possibly infinite loop?). Therefor
|
||||
* this routine constrains the value.
|
||||
*/
|
||||
*/
|
||||
uint8_t i; //iterator counts numChannels
|
||||
uint64_t indexOfNextSequenceValue;
|
||||
uint64_t numChannelsFactorial=1;
|
||||
uint32_t indexOfNextSequenceValue;
|
||||
uint32_t numChannelsFactorial=1;
|
||||
uint32_t perm32 ;
|
||||
uint8_t sequenceValue;
|
||||
|
||||
numChannels = constrain(numChannels,1,20);
|
||||
numChannels = constrain(numChannels,1,9);
|
||||
|
||||
for (i = 1; i <= numChannels;i++)
|
||||
{
|
||||
numChannelsFactorial *= i; // Calculate n!
|
||||
outArray[i-1] = i-1; // Initialize array with the sequence
|
||||
numChannelsFactorial *= i; // Calculate n!
|
||||
outArray[i-1] = i-1; // Initialize array with the sequence
|
||||
}
|
||||
|
||||
permutation = (permutation % numChannelsFactorial) + 1; // permutation must be between 1 and n! or this algorithm will infinite loop
|
||||
perm32 = permutation >> 8 ; // Shift 40 bit input to 32 bit
|
||||
perm32 = (perm32 % numChannelsFactorial); // permutation must be between 1 and n! or this algorithm will infinite loop
|
||||
perm32 <<= 8 ; // Shift back 8 bits
|
||||
perm32 += permutation & 0x00FF ; // Tack on least 8 bits
|
||||
perm32 = (perm32 % numChannelsFactorial) + 1; // permutation must be between 1 and n! or this algorithm will infinite loop
|
||||
|
||||
//Rearrange the array elements based on the permutation selected
|
||||
for (i=0, permutation--; i<numChannels; i++ )
|
||||
for (i=0, perm32--; i<numChannels; i++ )
|
||||
{
|
||||
numChannelsFactorial /= ((uint64_t)numChannels)-i;
|
||||
indexOfNextSequenceValue = i+(permutation/numChannelsFactorial);
|
||||
permutation %= numChannelsFactorial;
|
||||
numChannelsFactorial /= numChannels-i;
|
||||
indexOfNextSequenceValue = i+(perm32/numChannelsFactorial);
|
||||
perm32 %= numChannelsFactorial;
|
||||
|
||||
//Copy the value in the selected array position
|
||||
sequenceValue = outArray[indexOfNextSequenceValue];
|
||||
@@ -356,48 +362,18 @@ static void __attribute__((unused)) CABELL_setAddress()
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
static void __attribute__((unused)) CABELL_init()
|
||||
static void __attribute__((unused)) CABELL_RF_init()
|
||||
{
|
||||
NRF24L01_Initialize();
|
||||
CABELL_SetPower();
|
||||
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_250K); // slower data rate gives better range/reliability
|
||||
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowledgment on all data pipes
|
||||
NRF24L01_SetTxRxMode(TX_EN); //Power up and 16 bit CRC
|
||||
|
||||
CABELL_setAddress();
|
||||
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||
NRF24L01_FlushTx();
|
||||
NRF24L01_FlushRx();
|
||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01);
|
||||
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, 0x20); // 32 byte packet length
|
||||
NRF24L01_WriteReg(NRF24L01_12_RX_PW_P1, 0x20); // 32 byte packet length
|
||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03);
|
||||
NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x5F); // no retransmits
|
||||
NRF24L01_Activate(0x73); // Activate feature register
|
||||
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x3F); // Enable dynamic payload length on all pipes
|
||||
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x04); // Enable dynamic Payload Length
|
||||
NRF24L01_Activate(0x73);
|
||||
prev_power = NRF_POWER_0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
static void CABELL_SetPower() // This over-ride the standard Set Power to allow an flag in option to indicate max power setting
|
||||
// Note that on many modules max power may actually be worse than the normal high power setting
|
||||
// test and only use max if it helps the range
|
||||
{
|
||||
if(IS_BIND_DONE && !IS_RANGE_FLAG_on && ((option & CABELL_OPTION_MASK_MAX_POWER_OVERRIDE) != 0))
|
||||
{ // If we are not in range or bind mode and power setting override is in effect, then set max power, else standard power logic
|
||||
if(prev_power != NRF_POWER_3) // prev_power is global variable for NRF24L01; NRF_POWER_3 is max power
|
||||
{
|
||||
uint8_t rf_setup = NRF24L01_ReadReg(NRF24L01_06_RF_SETUP);
|
||||
rf_setup = (rf_setup & 0xF9) | (NRF_POWER_3 << 1);
|
||||
NRF24L01_WriteReg(NRF24L01_06_RF_SETUP, rf_setup);
|
||||
prev_power=NRF_POWER_3;
|
||||
}
|
||||
}
|
||||
else
|
||||
NRF24L01_SetPower();
|
||||
NRF24L01_SetTxRxMode(TX_EN); // Clear data ready, data sent, retransmit and enable CRC 16bits, ready for TX
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
@@ -414,7 +390,7 @@ uint16_t CABELL_callback()
|
||||
else if (bind_counter == 0)
|
||||
{
|
||||
BIND_DONE;
|
||||
CABELL_init(); // non-bind address
|
||||
CABELL_RF_init(); // non-bind address
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -425,17 +401,15 @@ uint16_t CABELL_callback()
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------
|
||||
uint16_t initCABELL(void)
|
||||
void CABELL_init(void)
|
||||
{
|
||||
if (IS_BIND_DONE)
|
||||
bind_counter = 0;
|
||||
else
|
||||
bind_counter = CABELL_BIND_COUNT;
|
||||
CABELL_init();
|
||||
CABELL_RF_init();
|
||||
|
||||
packet_period = CABELL_PACKET_PERIOD;
|
||||
|
||||
return packet_period;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -195,6 +195,7 @@ void __attribute__((unused)) CC2500_250K_Init()
|
||||
// TX Power = 0
|
||||
// Whitening = false
|
||||
// Fast Frequency Hopping - no PLL auto calibration
|
||||
/* //Previous config
|
||||
CC2500_WriteReg(CC2500_08_PKTCTRL0, 0x01); // Packet Automation Control
|
||||
CC2500_WriteReg(CC2500_0B_FSCTRL1, 0x0A); // Frequency Synthesizer Control
|
||||
CC2500_WriteReg(CC2500_0C_FSCTRL0, option); // Frequency offset hack
|
||||
@@ -217,6 +218,42 @@ void __attribute__((unused)) CC2500_250K_Init()
|
||||
CC2500_WriteReg(CC2500_23_FSCAL3, 0xEA); // Frequency Synthesizer Calibration
|
||||
CC2500_WriteReg(CC2500_25_FSCAL1, 0x00); // Frequency Synthesizer Calibration
|
||||
CC2500_WriteReg(CC2500_26_FSCAL0, 0x11); // Frequency Synthesizer Calibration
|
||||
*/
|
||||
CC2500_WriteReg(CC2500_07_PKTCTRL1, 0x05); // Packet Automation Control, address check true auto append RSSI & LQI
|
||||
CC2500_WriteReg(CC2500_08_PKTCTRL0, 0x00); // Packet Automation Control, fixed packet len
|
||||
CC2500_WriteReg(CC2500_0B_FSCTRL1, 0x0A); // Frequency Synthesizer Control (IF Frequency)
|
||||
CC2500_WriteReg(CC2500_0C_FSCTRL0, 0x00); // Frequency Synthesizer Control
|
||||
CC2500_WriteReg(CC2500_0D_FREQ2, 0x5C); // Frequency Control Word, High Byte
|
||||
CC2500_WriteReg(CC2500_0E_FREQ1, 0x4E); // Frequency Control Word, Middle Byte
|
||||
CC2500_WriteReg(CC2500_0F_FREQ0, 0xC5); // Frequency Control Word, Low Byte
|
||||
CC2500_WriteReg(CC2500_10_MDMCFG4, 0x3D); // Modem Configuration Set to 406kHz BW filter
|
||||
CC2500_WriteReg(CC2500_11_MDMCFG3, 0x3B); // Modem Configuration
|
||||
CC2500_WriteReg(CC2500_12_MDMCFG2, 0x10); // Modem Configuration, GFSK, no preambule and no sync word -> TX by default
|
||||
CC2500_WriteReg(CC2500_13_MDMCFG1, 0x03); // Modem Configuration, 2 bytes of preamble
|
||||
CC2500_WriteReg(CC2500_14_MDMCFG0, 0xA4); // Modem Configuration
|
||||
CC2500_WriteReg(CC2500_15_DEVIATN, 0x62); // Modem Deviation Setting
|
||||
CC2500_WriteReg(CC2500_18_MCSM0, 0x08); // Main Radio Control State Machine Configuration
|
||||
CC2500_WriteReg(CC2500_19_FOCCFG, 0x1D); // Frequency Offset Compensation Configuration
|
||||
CC2500_WriteReg(CC2500_1A_BSCFG, 0x1C); // Bit Synchronization Configuration
|
||||
CC2500_WriteReg(CC2500_1B_AGCCTRL2, 0xC7); // AGC Control
|
||||
CC2500_WriteReg(CC2500_1C_AGCCTRL1, 0x00); // AGC Control
|
||||
CC2500_WriteReg(CC2500_1D_AGCCTRL0, 0xB0); // AGC Control
|
||||
CC2500_WriteReg(CC2500_21_FREND1, 0xB6); // Front End RX Configuration
|
||||
CC2500_WriteReg(CC2500_23_FSCAL3, 0xEA); // Frequency Synthesizer Calibration
|
||||
CC2500_WriteReg(CC2500_25_FSCAL1, 0x00); // Frequency Synthesizer Calibration
|
||||
CC2500_WriteReg(CC2500_26_FSCAL0, 0x11); // Frequency Synthesizer Calibration
|
||||
|
||||
//Prep RX
|
||||
// Set first 3 bytes of rx addr in [0]->SYNC1, [1]->SYNC0 and [2]->ADDR
|
||||
// CC2500_WriteReg(CC2500_04_SYNC1, [0]); // Sync word, high byte
|
||||
// CC2500_WriteReg(CC2500_05_SYNC0, [1]); // Sync word, low byte
|
||||
// CC2500_WriteReg(CC2500_09_ADDR, [2]); // Set addr
|
||||
//RX
|
||||
// CC2500_WriteReg(CC2500_12_MDMCFG2, 0x12); // Modem Configuration, GFSK, 16/16 Sync Word TX&RX
|
||||
//TX
|
||||
// CC2500_WriteReg(CC2500_12_MDMCFG2, 0x10); // Modem Configuration, GFSK, no preambule and no sync word
|
||||
// need to set packet length before sending/receiving
|
||||
// CC2500_WriteReg(CC2500_06_PKTLEN, cc2500_packet_len); // Packet len, fix packet len
|
||||
|
||||
CC2500_SetTxRxMode(TX_EN);
|
||||
CC2500_SetPower();
|
||||
@@ -250,87 +287,4 @@ void __attribute__((unused)) CC2500_250K_RFChannel(uint8_t number)
|
||||
CC2500_Strobe(CC2500_SCAL);
|
||||
delayMicroseconds(900);
|
||||
}
|
||||
|
||||
//NRF emulation layer with CRC16 enabled
|
||||
uint8_t cc2500_nrf_tx_addr[5], cc2500_nrf_addr_len;
|
||||
void __attribute__((unused)) CC2500_250K_NRF_SetTXAddr(uint8_t* addr, uint8_t len)
|
||||
{
|
||||
cc2500_nrf_addr_len = len;
|
||||
memcpy(cc2500_nrf_tx_addr, addr, len);
|
||||
}
|
||||
void __attribute__((unused)) CC2500_250K_NRF_WritePayload(uint8_t* msg, uint8_t len)
|
||||
{
|
||||
#if defined(ESKY150V2_CC2500_INO)
|
||||
uint8_t buf[158];
|
||||
#else
|
||||
uint8_t buf[35];
|
||||
#endif
|
||||
uint8_t last = 0;
|
||||
uint8_t i;
|
||||
|
||||
//nrf preamble
|
||||
if(cc2500_nrf_tx_addr[cc2500_nrf_addr_len - 1] & 0x80)
|
||||
buf[0]=0xAA;
|
||||
else
|
||||
buf[0]=0x55;
|
||||
last++;
|
||||
// address
|
||||
for (i = 0; i < cc2500_nrf_addr_len; ++i)
|
||||
buf[last++] = cc2500_nrf_tx_addr[cc2500_nrf_addr_len - i - 1];
|
||||
// payload
|
||||
for (i = 0; i < len; ++i)
|
||||
buf[last++] = msg[i];
|
||||
|
||||
// crc
|
||||
crc = 0xffff;
|
||||
for (uint8_t i = 1; i < last; ++i)
|
||||
crc16_update( buf[i], 8);
|
||||
buf[last++] = crc >> 8;
|
||||
buf[last++] = crc & 0xff;
|
||||
buf[last++] = 0;
|
||||
|
||||
//for(uint8_t i=0;i<last;i++)
|
||||
// debug("%02X ",buf[i]);
|
||||
//debugln("");
|
||||
// stop TX/RX
|
||||
CC2500_Strobe(CC2500_SIDLE);
|
||||
// flush tx FIFO
|
||||
CC2500_Strobe(CC2500_SFTX);
|
||||
// packet length
|
||||
CC2500_WriteReg(CC2500_3F_TXFIFO, last);
|
||||
// transmit nrf packet
|
||||
uint8_t *buff=buf;
|
||||
uint8_t status;
|
||||
if(last>63)
|
||||
{
|
||||
CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, buff, 63);
|
||||
CC2500_Strobe(CC2500_STX);
|
||||
last-=63;
|
||||
buff+=63;
|
||||
while(last)
|
||||
{//Loop until all the data is sent
|
||||
do
|
||||
{// Wait for the FIFO to become available
|
||||
status=CC2500_ReadReg(CC2500_3A_TXBYTES | CC2500_READ_BURST);
|
||||
}
|
||||
while((status&0x7F)>31 && (status&0x80)==0);
|
||||
if(last>31)
|
||||
{//Send 31 bytes
|
||||
CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, buff, 31);
|
||||
last-=31;
|
||||
buff+=31;
|
||||
}
|
||||
else
|
||||
{//Send last bytes
|
||||
CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, buff, last);
|
||||
last=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{//Send packet
|
||||
CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, buff, last);
|
||||
CC2500_Strobe(CC2500_STX);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -644,37 +644,24 @@ static uint8_t crtp_log_setup_state_machine()
|
||||
return state_machine_completed;
|
||||
}
|
||||
|
||||
static int cflie_init()
|
||||
static void CFLIE_RF_init()
|
||||
{
|
||||
NRF24L01_Initialize();
|
||||
|
||||
// CRC, radio on
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
||||
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x01); // Auto Acknowledgement for data pipe 0
|
||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0
|
||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, TX_ADDR_SIZE-2); // 5-byte RX/TX address
|
||||
NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x13); // 3 retransmits, 500us delay
|
||||
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, rf_ch_num); // Defined in initialize_rx_tx_addr
|
||||
NRF24L01_SetBitrate(data_rate); // Defined in initialize_rx_tx_addr
|
||||
|
||||
NRF24L01_SetPower();
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
|
||||
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, rx_tx_addr, TX_ADDR_SIZE);
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, rx_tx_addr, TX_ADDR_SIZE);
|
||||
|
||||
// this sequence necessary for module from stock tx
|
||||
NRF24L01_ReadReg(NRF24L01_1D_FEATURE);
|
||||
NRF24L01_Activate(0x73); // Activate feature register
|
||||
NRF24L01_ReadReg(NRF24L01_1D_FEATURE);
|
||||
|
||||
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x01); // Enable Dynamic Payload Length on pipe 0
|
||||
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x06); // Enable Dynamic Payload Length, enable Payload with ACK
|
||||
|
||||
// 50ms delay in callback
|
||||
return 50000;
|
||||
NRF24L01_SetTxRxMode(TX_EN); // Clear data ready, data sent, retransmit and enable CRC 16bits, ready for TX
|
||||
}
|
||||
|
||||
// TODO: Fix telemetry
|
||||
@@ -749,7 +736,7 @@ static int cflie_init()
|
||||
// }
|
||||
// }
|
||||
|
||||
static uint16_t cflie_callback()
|
||||
static uint16_t CFLIE_callback()
|
||||
{
|
||||
switch (phase) {
|
||||
case CFLIE_INIT_SEARCH:
|
||||
@@ -799,7 +786,7 @@ static uint16_t cflie_callback()
|
||||
}
|
||||
|
||||
// Generate address to use from TX id and manufacturer id (STM32 unique id)
|
||||
static uint8_t initialize_rx_tx_addr()
|
||||
static uint8_t CFLIE_initialize_rx_tx_addr()
|
||||
{
|
||||
rx_tx_addr[0] =
|
||||
rx_tx_addr[1] =
|
||||
@@ -844,19 +831,15 @@ static uint8_t initialize_rx_tx_addr()
|
||||
return CFLIE_INIT_SEARCH;
|
||||
}
|
||||
|
||||
uint16_t initCFlie(void)
|
||||
void CFLIE_init(void)
|
||||
{
|
||||
BIND_IN_PROGRESS; // autobind protocol
|
||||
|
||||
phase = initialize_rx_tx_addr();
|
||||
phase = CFLIE_initialize_rx_tx_addr();
|
||||
crtp_log_setup_state = CFLIE_CRTP_LOG_SETUP_STATE_INIT;
|
||||
packet_count=0;
|
||||
|
||||
int delay = cflie_init();
|
||||
|
||||
// debugln("CFlie init!");
|
||||
|
||||
return delay;
|
||||
CFLIE_RF_init();
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
#if defined(CG023_NRF24L01_INO)
|
||||
|
||||
#include "iface_nrf24l01.h"
|
||||
#include "iface_xn297.h"
|
||||
|
||||
#define CG023_PACKET_PERIOD 8200 // Timeout for callback in uSec
|
||||
#define CG023_INITIAL_WAIT 500
|
||||
@@ -49,7 +49,7 @@ enum YD829_FLAGS {
|
||||
YD829_FLAG_STILL = 0x80,
|
||||
};
|
||||
|
||||
static void __attribute__((unused)) CG023_send_packet(uint8_t bind)
|
||||
static void __attribute__((unused)) CG023_send_packet()
|
||||
{
|
||||
// throttle : 0x00 - 0xFF
|
||||
throttle=convert_channel_8b(THROTTLE);
|
||||
@@ -62,10 +62,16 @@ static void __attribute__((unused)) CG023_send_packet(uint8_t bind)
|
||||
// aileron : 0x43 - 0x7F - 0xBB
|
||||
aileron = convert_channel_16b_limit(AILERON, 0x43, 0xBB);
|
||||
|
||||
if (bind)
|
||||
if (IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
packet[0]= 0xaa;
|
||||
XN297_RFChannel(CG023_RF_BIND_CHANNEL);
|
||||
}
|
||||
else
|
||||
{
|
||||
packet[0]= 0x55;
|
||||
XN297_RFChannel(hopping_frequency_no);
|
||||
}
|
||||
// transmitter id
|
||||
packet[1] = rx_tx_addr[0];
|
||||
packet[2] = rx_tx_addr[1];
|
||||
@@ -85,7 +91,7 @@ static void __attribute__((unused)) CG023_send_packet(uint8_t bind)
|
||||
if(sub_protocol==CG023)
|
||||
{
|
||||
// rate
|
||||
packet[13] = CG023_FLAG_RATE_HIGH
|
||||
packet[13] = CG023_FLAG_RATE_HIGH
|
||||
| GET_FLAG(CH5_SW,CG023_FLAG_FLIP)
|
||||
| GET_FLAG(CH6_SW,CG023_FLAG_LED_OFF)
|
||||
| GET_FLAG(CH7_SW,CG023_FLAG_STILL)
|
||||
@@ -95,7 +101,7 @@ static void __attribute__((unused)) CG023_send_packet(uint8_t bind)
|
||||
else
|
||||
{// YD829
|
||||
// rate
|
||||
packet[13] = YD829_FLAG_RATE_HIGH
|
||||
packet[13] = YD829_FLAG_RATE_HIGH
|
||||
| GET_FLAG(CH5_SW,YD829_FLAG_FLIP)
|
||||
| GET_FLAG(CH7_SW,YD829_FLAG_STILL)
|
||||
| GET_FLAG(CH8_SW,YD829_FLAG_VIDEO)
|
||||
@@ -103,79 +109,52 @@ static void __attribute__((unused)) CG023_send_packet(uint8_t bind)
|
||||
}
|
||||
packet[14] = 0;
|
||||
|
||||
// Power on, TX mode, 2byte CRC
|
||||
// Why CRC0? xn297 does not interpret it - either 16-bit CRC or nothing
|
||||
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
||||
if (bind)
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, CG023_RF_BIND_CHANNEL);
|
||||
else
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency_no);
|
||||
|
||||
// clear packet status bits and TX FIFO
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||
NRF24L01_FlushTx();
|
||||
// Send
|
||||
XN297_SetTxRxMode(TX_EN);
|
||||
XN297_SetPower();
|
||||
XN297_WritePayload(packet, CG023_PACKET_SIZE);
|
||||
|
||||
NRF24L01_SetPower(); // Set tx_power
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) CG023_init()
|
||||
static void __attribute__((unused)) CG023_RF_init()
|
||||
{
|
||||
NRF24L01_Initialize();
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
XN297_SetTXAddr((uint8_t *)"\x26\xA8\x67\x35\xCC", 5);
|
||||
XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M);
|
||||
|
||||
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_WriteReg(NRF24L01_04_SETUP_RETR, 0x00); // no retransmits
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps
|
||||
NRF24L01_SetPower();
|
||||
XN297_SetTXAddr((uint8_t *)"\x26\xA8\x67\x35\xCC", 5);
|
||||
}
|
||||
|
||||
uint16_t CG023_callback()
|
||||
{
|
||||
if(IS_BIND_DONE)
|
||||
{
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(packet_period);
|
||||
#endif
|
||||
CG023_send_packet(0);
|
||||
}
|
||||
else
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(packet_period);
|
||||
#endif
|
||||
if(bind_counter)
|
||||
{
|
||||
bind_counter--;
|
||||
if (bind_counter == 0)
|
||||
BIND_DONE;
|
||||
else
|
||||
{
|
||||
CG023_send_packet(1);
|
||||
bind_counter--;
|
||||
}
|
||||
}
|
||||
CG023_send_packet();
|
||||
return packet_period;
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) CG023_initialize_txid()
|
||||
{
|
||||
rx_tx_addr[0]= 0x80 | (rx_tx_addr[0] % 0x40);
|
||||
if( rx_tx_addr[0] == 0xAA) // avoid using same freq for bind and data channel
|
||||
if( rx_tx_addr[0] == 0xAA) // avoid using same freq for bind and data channel
|
||||
rx_tx_addr[0] ++;
|
||||
hopping_frequency_no = rx_tx_addr[0] - 0x7D; // rf channel for data packets
|
||||
}
|
||||
|
||||
uint16_t initCG023(void)
|
||||
void CG023_init(void)
|
||||
{
|
||||
BIND_IN_PROGRESS; // autobind protocol
|
||||
bind_counter = CG023_BIND_COUNT;
|
||||
CG023_initialize_txid();
|
||||
CG023_init();
|
||||
CG023_RF_init();
|
||||
if(sub_protocol==CG023)
|
||||
packet_period=CG023_PACKET_PERIOD;
|
||||
else // YD829
|
||||
packet_period=YD829_PACKET_PERIOD;
|
||||
return CG023_INITIAL_WAIT+YD829_PACKET_PERIOD;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
#if defined(CX10_NRF24L01_INO)
|
||||
|
||||
#include "iface_nrf24l01.h"
|
||||
#include "iface_xn297.h"
|
||||
|
||||
#define CX10_BIND_COUNT 4360 // 6 seconds
|
||||
#define CX10_PACKET_SIZE 15
|
||||
@@ -46,12 +46,12 @@ enum {
|
||||
CX10_DATA
|
||||
};
|
||||
|
||||
static void __attribute__((unused)) CX10_Write_Packet(uint8_t bind)
|
||||
static void __attribute__((unused)) CX10_Write_Packet()
|
||||
{
|
||||
uint8_t offset = 0;
|
||||
if(sub_protocol == CX10_BLUE)
|
||||
offset = 4;
|
||||
packet[0] = bind ? 0xAA : 0x55;
|
||||
packet[0] = IS_BIND_IN_PROGRESS ? 0xAA : 0x55;
|
||||
packet[1] = rx_tx_addr[0];
|
||||
packet[2] = rx_tx_addr[1];
|
||||
packet[3] = rx_tx_addr[2];
|
||||
@@ -62,57 +62,57 @@ static void __attribute__((unused)) CX10_Write_Packet(uint8_t bind)
|
||||
uint16_t throttle=convert_channel_16b_limit(THROTTLE,1000,2000);
|
||||
uint16_t rudder= convert_channel_16b_limit(RUDDER ,2000,1000);
|
||||
// Channel 5 - flip flag
|
||||
packet[12+offset] = GET_FLAG(CH5_SW,CX10_FLAG_FLIP); // flip flag applied on rudder
|
||||
packet[12+offset] = GET_FLAG(CH5_SW,CX10_FLAG_FLIP); // flip flag applied on rudder
|
||||
|
||||
// Channel 6 - rate mode is 2 lsb of packet 13
|
||||
if(CH6_SW) // rate 3 / headless on CX-10A
|
||||
if(CH6_SW) // rate 3 / headless on CX-10A
|
||||
flags = 0x02;
|
||||
else
|
||||
if(Channel_data[CH6] < CHANNEL_MIN_COMMAND)
|
||||
flags = 0x00; // rate 1
|
||||
flags = 0x00; // rate 1
|
||||
else
|
||||
flags = 0x01; // rate 2
|
||||
uint8_t flags2=0; // packet 14
|
||||
flags = 0x01; // rate 2
|
||||
uint8_t flags2=0; // packet 14
|
||||
|
||||
uint8_t video_state=packet[14] & 0x21;
|
||||
switch(sub_protocol)
|
||||
{
|
||||
case CX10_BLUE:
|
||||
flags |= GET_FLAG(!CH7_SW, 0x10) // Channel 7 - picture
|
||||
|GET_FLAG( CH8_SW, 0x08); // Channel 8 - video
|
||||
flags |= GET_FLAG(!CH7_SW, 0x10) // Channel 7 - picture
|
||||
|GET_FLAG( CH8_SW, 0x08); // Channel 8 - video
|
||||
break;
|
||||
case F_Q282:
|
||||
case F_Q242:
|
||||
case F_Q222:
|
||||
memcpy(&packet[15], "\x10\x10\xaa\xaa\x00\x00", 6);
|
||||
//FLIP|LED|PICTURE|VIDEO|HEADLESS|RTH|XCAL|YCAL
|
||||
flags2 = GET_FLAG(CH5_SW, 0x80) // Channel 5 - FLIP
|
||||
|GET_FLAG(!CH6_SW, 0x40) // Channel 6 - LED
|
||||
|GET_FLAG(CH9_SW, 0x08) // Channel 9 - HEADLESS
|
||||
|GET_FLAG(CH11_SW, 0x04) // Channel 11 - XCAL
|
||||
|GET_FLAG(CH12_SW, 0x02); // Channel 12 - YCAL or Start/Stop motors on JXD 509
|
||||
flags2 = GET_FLAG(CH5_SW, 0x80) // Channel 5 - FLIP
|
||||
|GET_FLAG(!CH6_SW, 0x40) // Channel 6 - LED
|
||||
|GET_FLAG(CH9_SW, 0x08) // Channel 9 - HEADLESS
|
||||
|GET_FLAG(CH11_SW, 0x04) // Channel 11 - XCAL
|
||||
|GET_FLAG(CH12_SW, 0x02); // Channel 12 - YCAL or Start/Stop motors on JXD 509
|
||||
|
||||
if(sub_protocol==F_Q242)
|
||||
{
|
||||
flags=2;
|
||||
flags2|= GET_FLAG(CH7_SW,0x01) // Channel 7 - picture
|
||||
|GET_FLAG(CH8_SW,0x10); // Channel 8 - video
|
||||
flags2|= GET_FLAG(CH7_SW,0x01) // Channel 7 - picture
|
||||
|GET_FLAG(CH8_SW,0x10); // Channel 8 - video
|
||||
packet[17]=0x00;
|
||||
packet[18]=0x00;
|
||||
}
|
||||
else
|
||||
{ // F_Q282 & F_Q222
|
||||
flags=3; // expert
|
||||
if(CH8_SW) // Channel 8 - F_Q282 video / F_Q222 Module 1
|
||||
flags=3; // expert
|
||||
if(CH8_SW) // Channel 8 - F_Q282 video / F_Q222 Module 1
|
||||
{
|
||||
if (!(video_state & 0x20)) video_state ^= 0x21;
|
||||
}
|
||||
else
|
||||
if (video_state & 0x20) video_state &= 0x01;
|
||||
flags2 |= video_state
|
||||
|GET_FLAG(CH7_SW,0x10); // Channel 7 - F_Q282 picture / F_Q222 Module 2
|
||||
|GET_FLAG(CH7_SW,0x10); // Channel 7 - F_Q282 picture / F_Q222 Module 2
|
||||
}
|
||||
if(CH10_SW) flags |=0x80; // Channel 10 - RTH
|
||||
if(CH10_SW) flags |=0x80; // Channel 10 - RTH
|
||||
break;
|
||||
case DM007:
|
||||
aileron = 3000 - aileron;
|
||||
@@ -128,16 +128,16 @@ static void __attribute__((unused)) CX10_Write_Packet(uint8_t bind)
|
||||
if(CH8_SW) packet[12] &= ~CX10_FLAG_FLIP;
|
||||
case JC3015_1:
|
||||
//FLIP|MODE|PICTURE|VIDEO
|
||||
flags2= GET_FLAG(CH7_SW,_BV(3)) // Channel 7
|
||||
|GET_FLAG(CH8_SW,_BV(4)); // Channel 8
|
||||
flags2= GET_FLAG(CH7_SW,_BV(3)) // Channel 7
|
||||
|GET_FLAG(CH8_SW,_BV(4)); // Channel 8
|
||||
break;
|
||||
case MK33041:
|
||||
elevator = 3000 - elevator;
|
||||
//FLIP|MODE|PICTURE|VIDEO|HEADLESS|RTH
|
||||
flags|=GET_FLAG(CH7_SW,_BV(7)) // Channel 7 - picture
|
||||
|GET_FLAG(CH10_SW,_BV(2)); // Channel 10 - rth
|
||||
flags2=GET_FLAG(CH8_SW,_BV(0)) // Channel 8 - video
|
||||
|GET_FLAG(CH9_SW,_BV(5)); // Channel 9 - headless
|
||||
flags|=GET_FLAG(CH7_SW,_BV(7)) // Channel 7 - picture
|
||||
|GET_FLAG(CH10_SW,_BV(2)); // Channel 10 - rth
|
||||
flags2=GET_FLAG(CH8_SW,_BV(0)) // Channel 8 - video
|
||||
|GET_FLAG(CH9_SW,_BV(5)); // Channel 9 - headless
|
||||
break;
|
||||
}
|
||||
packet[5+offset] = lowByte(aileron);
|
||||
@@ -151,39 +151,23 @@ static void __attribute__((unused)) CX10_Write_Packet(uint8_t bind)
|
||||
packet[13+offset]=flags;
|
||||
packet[14+offset]=flags2;
|
||||
|
||||
// Power on, TX mode, 2byte CRC
|
||||
// Why CRC0? xn297 does not interpret it - either 16-bit CRC or nothing
|
||||
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
||||
if (bind)
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, CX10_RF_BIND_CHANNEL);
|
||||
else
|
||||
// Send
|
||||
if(IS_BIND_DONE)
|
||||
{
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no++]);
|
||||
XN297_Hopping(hopping_frequency_no++);
|
||||
hopping_frequency_no %= CX10_NUM_RF_CHANNELS;
|
||||
}
|
||||
// clear packet status bits and TX FIFO
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||
NRF24L01_FlushTx();
|
||||
|
||||
XN297_SetPower();
|
||||
XN297_SetTxRxMode(TX_EN);
|
||||
XN297_WritePayload(packet, packet_length);
|
||||
NRF24L01_SetPower();
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) CX10_init()
|
||||
static void __attribute__((unused)) CX10_RF_init()
|
||||
{
|
||||
NRF24L01_Initialize();
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
XN297_SetTXAddr((uint8_t *)"\xcc\xcc\xcc\xcc\xcc",5);
|
||||
XN297_SetRXAddr((uint8_t *)"\xcc\xcc\xcc\xcc\xcc",5);
|
||||
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 Acknowledgment on all data pipes
|
||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 only
|
||||
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, packet_length); // rx pipe 0 (used only for blue board)
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, CX10_RF_BIND_CHANNEL);
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps
|
||||
NRF24L01_SetPower();
|
||||
XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M);
|
||||
XN297_SetTXAddr((uint8_t *)"\xcc\xcc\xcc\xcc\xcc", 5);
|
||||
XN297_SetRXAddr((uint8_t *)"\xcc\xcc\xcc\xcc\xcc", packet_length);
|
||||
XN297_RFChannel(CX10_RF_BIND_CHANNEL);
|
||||
}
|
||||
|
||||
uint16_t CX10_callback()
|
||||
@@ -197,43 +181,39 @@ uint16_t CX10_callback()
|
||||
}
|
||||
else
|
||||
{
|
||||
CX10_Write_Packet(1);
|
||||
CX10_Write_Packet();
|
||||
bind_counter--;
|
||||
}
|
||||
break;
|
||||
case CX10_BIND2:
|
||||
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR))
|
||||
// switch to TX mode
|
||||
if( XN297_IsRX() )
|
||||
{ // RX fifo data ready
|
||||
XN297_ReadPayload(packet, packet_length);
|
||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
if(packet[9] == 1)
|
||||
debugln("RX");
|
||||
if(XN297_ReadPayload(packet, packet_length) && packet[9] == 1)
|
||||
{
|
||||
BIND_DONE;
|
||||
XN297_SetTxRxMode(TXRX_OFF);
|
||||
phase = CX10_DATA;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// switch to TX mode
|
||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||
NRF24L01_FlushTx();
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
CX10_Write_Packet(1);
|
||||
XN297_SetTxRxMode(TXRX_OFF);
|
||||
CX10_Write_Packet();
|
||||
// wait for packet to be sent
|
||||
while( (NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_TX_DS)) == 0); //delayMicroseconds(400);
|
||||
// switch to RX mode
|
||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||
NRF24L01_FlushRx();
|
||||
NRF24L01_SetTxRxMode(RX_EN);
|
||||
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP) | _BV(NRF24L01_00_PRIM_RX));
|
||||
while( !XN297_IsPacketSent()); //delayMicroseconds(400);
|
||||
}
|
||||
// switch to RX mode
|
||||
XN297_SetTxRxMode(TXRX_OFF);
|
||||
XN297_SetTxRxMode(RX_EN);
|
||||
break;
|
||||
case CX10_DATA:
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(packet_period);
|
||||
#endif
|
||||
CX10_Write_Packet(0);
|
||||
CX10_Write_Packet();
|
||||
break;
|
||||
}
|
||||
return packet_period;
|
||||
@@ -261,9 +241,13 @@ static void __attribute__((unused)) CX10_initialize_txid()
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t initCX10(void)
|
||||
void CX10_init(void)
|
||||
{
|
||||
BIND_IN_PROGRESS; // autobind protocol
|
||||
|
||||
if(protocol == PROTO_Q2X2)
|
||||
sub_protocol|=0x08; // Increase the number of sub_protocols for CX-10
|
||||
|
||||
if(sub_protocol==CX10_BLUE)
|
||||
{
|
||||
packet_length = CX10A_PACKET_SIZE;
|
||||
@@ -286,8 +270,7 @@ uint16_t initCX10(void)
|
||||
bind_counter = CX10_BIND_COUNT;
|
||||
}
|
||||
CX10_initialize_txid();
|
||||
CX10_init();
|
||||
return CX10_INITIAL_WAIT+packet_period;
|
||||
CX10_RF_init();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -79,13 +79,24 @@ uint8_t CYRF_Reset()
|
||||
void CYRF_GetMfgData(uint8_t data[])
|
||||
{
|
||||
#ifndef FORCE_CYRF_ID
|
||||
/* Fuses power on */
|
||||
CYRF_WriteRegister(CYRF_25_MFG_ID, 0xFF);
|
||||
if(eeprom_read_byte((EE_ADDR)EEPROM_CID_INIT_OFFSET)==0xf0)
|
||||
{//read Cyrf ID from EEPROM
|
||||
for(uint8_t i=0;i<6;i++)
|
||||
data[i] = eeprom_read_byte((EE_ADDR)EEPROM_CID_OFFSET+i);
|
||||
}
|
||||
else
|
||||
{//read Cyrf ID and store it EEPROM
|
||||
/* Fuses power on */
|
||||
CYRF_WriteRegister(CYRF_25_MFG_ID, 0xFF);
|
||||
|
||||
CYRF_ReadRegisterMulti(CYRF_25_MFG_ID, data, 6);
|
||||
CYRF_ReadRegisterMulti(CYRF_25_MFG_ID, data, 6);
|
||||
for(uint8_t i=0;i<6;i++)
|
||||
eeprom_write_byte((EE_ADDR)EEPROM_CID_OFFSET+i, data[i]);
|
||||
eeprom_write_byte((EE_ADDR)EEPROM_CID_INIT_OFFSET, 0xf0);
|
||||
|
||||
/* Fuses power off */
|
||||
CYRF_WriteRegister(CYRF_25_MFG_ID, 0x00);
|
||||
/* Fuses power off */
|
||||
CYRF_WriteRegister(CYRF_25_MFG_ID, 0x00);
|
||||
}
|
||||
#else
|
||||
memcpy(data,FORCE_CYRF_ID,6);
|
||||
#endif
|
||||
@@ -258,7 +269,7 @@ void CYRF_FindBestChannels(uint8_t *channels, uint8_t len, uint8_t minspace, uin
|
||||
delayMilliseconds(1);
|
||||
for(i = 0; i < NUM_FREQ; i++)
|
||||
{
|
||||
CYRF_ConfigRFChannel(i);
|
||||
CYRF_ConfigRFChannel(protocol==PROTO_LOSI?i|1:i);
|
||||
delayMicroseconds(270); //slow channel require 270usec for synthesizer to settle
|
||||
if( !(CYRF_ReadRegister(CYRF_05_RX_CTRL) & 0x80)) {
|
||||
CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x80); //Prepare to receive
|
||||
|
||||
@@ -71,7 +71,7 @@ static void __attribute__((unused)) CORONA_rf_init()
|
||||
}
|
||||
|
||||
// Generate id and hopping freq
|
||||
static void __attribute__((unused)) CORONA_init()
|
||||
static void __attribute__((unused)) CORONA_TXID_init()
|
||||
{
|
||||
#ifdef CORONA_FORCE_ID
|
||||
// Example of ID and channels taken from dumps
|
||||
@@ -255,7 +255,7 @@ static uint16_t __attribute__((unused)) CORONA_build_packet()
|
||||
return packet_period;
|
||||
}
|
||||
|
||||
uint16_t ReadCORONA()
|
||||
uint16_t CORONA_callback()
|
||||
{
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(22000);
|
||||
@@ -276,7 +276,7 @@ uint16_t ReadCORONA()
|
||||
return packet_period;
|
||||
}
|
||||
|
||||
uint16_t initCORONA()
|
||||
void CORONA_init()
|
||||
{
|
||||
switch(sub_protocol)
|
||||
{
|
||||
@@ -293,9 +293,8 @@ uint16_t initCORONA()
|
||||
state=400; // Used by V2 to send RF channels + ID for 2.65s at startup
|
||||
hopping_frequency_no=0;
|
||||
fdv3_id_send = 0;
|
||||
CORONA_init();
|
||||
CORONA_TXID_init();
|
||||
CORONA_rf_init();
|
||||
return 10000;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
#if defined(DM002_NRF24L01_INO)
|
||||
|
||||
#include "iface_nrf24l01.h"
|
||||
#include "iface_xn297.h"
|
||||
|
||||
#define DM002_PACKET_PERIOD 6100 // Timeout for callback in uSec
|
||||
#define DM002_INITIAL_WAIT 500
|
||||
@@ -24,7 +24,6 @@
|
||||
#define DM002_RF_BIND_CHANNEL 0x27
|
||||
#define DM002_BIND_COUNT 655 // 4 seconds
|
||||
|
||||
|
||||
enum DM002_FLAGS {
|
||||
// flags going to packet[9]
|
||||
DM002_FLAG_FLIP = 0x01,
|
||||
@@ -37,10 +36,10 @@ enum DM002_FLAGS {
|
||||
DM002_FLAG_CAMERA2 = 0x80,
|
||||
};
|
||||
|
||||
static void __attribute__((unused)) DM002_send_packet(uint8_t bind)
|
||||
static void __attribute__((unused)) DM002_send_packet()
|
||||
{
|
||||
memcpy(packet+5,(uint8_t *)"\x00\x7F\x7F\x7F\x00\x00\x00",7);
|
||||
if(bind)
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
packet[0] = 0xAA;
|
||||
packet[1] = rx_tx_addr[0];
|
||||
@@ -75,63 +74,40 @@ static void __attribute__((unused)) DM002_send_packet(uint8_t bind)
|
||||
packet_count&=0x0F;
|
||||
packet[10] = packet_count;
|
||||
packet_count++;
|
||||
XN297_Hopping(hopping_frequency_no);
|
||||
}
|
||||
//CRC
|
||||
for(uint8_t i=0;i<DM002_PACKET_SIZE-1;i++)
|
||||
packet[11]+=packet[i];
|
||||
|
||||
// Power on, TX mode, 2byte CRC
|
||||
// Why CRC0? xn297 does not interpret it - either 16-bit CRC or nothing
|
||||
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
||||
if (bind)
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, DM002_RF_BIND_CHANNEL);
|
||||
else
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no]);
|
||||
// clear packet status bits and TX FIFO
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||
NRF24L01_FlushTx();
|
||||
//Send
|
||||
XN297_SetPower();
|
||||
XN297_SetTxRxMode(TX_EN);
|
||||
XN297_WritePayload(packet, DM002_PACKET_SIZE);
|
||||
|
||||
NRF24L01_SetPower(); // Set tx_power
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) DM002_init()
|
||||
static void __attribute__((unused)) DM002_RF_init()
|
||||
{
|
||||
NRF24L01_Initialize();
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M);
|
||||
XN297_SetTXAddr((uint8_t *)"\x26\xA8\x67\x35\xCC", 5);
|
||||
|
||||
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_RFChannel(DM002_RF_BIND_CHANNEL);
|
||||
}
|
||||
|
||||
uint16_t DM002_callback()
|
||||
{
|
||||
if(IS_BIND_DONE)
|
||||
{
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(DM002_PACKET_PERIOD);
|
||||
#endif
|
||||
DM002_send_packet(0);
|
||||
}
|
||||
else
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(DM002_PACKET_PERIOD);
|
||||
#endif
|
||||
if (bind_counter)
|
||||
{
|
||||
bind_counter--;
|
||||
if (bind_counter == 0)
|
||||
{
|
||||
BIND_DONE;
|
||||
XN297_SetTXAddr(rx_tx_addr, 5);
|
||||
}
|
||||
else
|
||||
{
|
||||
DM002_send_packet(1);
|
||||
bind_counter--;
|
||||
}
|
||||
}
|
||||
DM002_send_packet();
|
||||
return DM002_PACKET_PERIOD;
|
||||
}
|
||||
|
||||
@@ -155,13 +131,12 @@ static void __attribute__((unused)) DM002_initialize_txid()
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t initDM002(void)
|
||||
void DM002_init(void)
|
||||
{
|
||||
BIND_IN_PROGRESS; // autobind protocol
|
||||
bind_counter = DM002_BIND_COUNT;
|
||||
DM002_initialize_txid();
|
||||
DM002_init();
|
||||
return DM002_INITIAL_WAIT;
|
||||
DM002_RF_init();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -117,7 +117,9 @@ static void __attribute__((unused)) DSM_cyrf_configdata()
|
||||
|
||||
static uint8_t __attribute__((unused)) DSM_get_pn_row(uint8_t channel, bool dsmx)
|
||||
{
|
||||
return (dsmx ? (channel - 2) % 5 : channel % 5);
|
||||
if(protocol == PROTO_DSM && sub_protocol == DSMR)
|
||||
return (channel + 2) % 5;
|
||||
return (dsmx ? (channel - 2) % 5 : channel % 5);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) DSM_set_sop_data_crc(bool ch2, bool dsmx)
|
||||
@@ -127,10 +129,14 @@ static void __attribute__((unused)) DSM_set_sop_data_crc(bool ch2, bool dsmx)
|
||||
if(ch2)
|
||||
CYRF_ConfigCRCSeed(seed); //CH2
|
||||
else
|
||||
CYRF_ConfigCRCSeed(~seed); //CH1
|
||||
CYRF_ConfigCRCSeed(~seed); //CH1, DSMR only use CH1
|
||||
|
||||
uint8_t pn_row = DSM_get_pn_row(hopping_frequency[hopping_frequency_no], dsmx);
|
||||
uint8_t code[16];
|
||||
#if 0
|
||||
debug_time();
|
||||
debug(" crc:%04X,row:%d,col:%d,rf:%02X",(~seed)&0xffff,pn_row,sop_col,hopping_frequency[hopping_frequency_no]);
|
||||
#endif
|
||||
DSM_read_code(code,pn_row,sop_col,8); // pn_row between 0 and 4, sop_col between 1 and 7
|
||||
CYRF_ConfigSOPCode(code);
|
||||
DSM_read_code(code,pn_row,7 - sop_col,8); // 7-sop_col between 0 and 6
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
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,
|
||||
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.
|
||||
@@ -31,7 +31,7 @@ enum {
|
||||
DSM_RX_DATA_CH2,
|
||||
};
|
||||
|
||||
static void __attribute__((unused)) DSM_Rx_init()
|
||||
static void __attribute__((unused)) DSM_RX_RF_init()
|
||||
{
|
||||
DSM_cyrf_config();
|
||||
rx_disable_lna = IS_POWER_FLAG_on;
|
||||
@@ -63,7 +63,7 @@ uint16_t convert_channel_DSM_nolimit(int32_t val)
|
||||
return (uint16_t)val;
|
||||
}
|
||||
|
||||
static uint8_t __attribute__((unused)) DSM_Rx_check_packet()
|
||||
static uint8_t __attribute__((unused)) DSM_RX_check_packet()
|
||||
{
|
||||
uint8_t rx_status=CYRF_ReadRegister(CYRF_07_RX_IRQ_STATUS);
|
||||
if((rx_status & 0x03) == 0x02) // RXC=1, RXE=0 then 2nd check is required (debouncing)
|
||||
@@ -99,7 +99,7 @@ static uint8_t __attribute__((unused)) DSM_Rx_check_packet()
|
||||
return rx_status; // Return error code
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) DSM_Rx_build_telemetry_packet()
|
||||
static void __attribute__((unused)) DSM_RX_build_telemetry_packet()
|
||||
{
|
||||
uint8_t nbr_bits = 11;
|
||||
if((DSM_rx_type&0xF0) == 0x00)
|
||||
@@ -155,9 +155,13 @@ static void __attribute__((unused)) DSM_Rx_build_telemetry_packet()
|
||||
packet_in[idx++] = bits & 0xff;
|
||||
// Send telemetry
|
||||
telemetry_link = 1;
|
||||
#ifdef SEND_CPPM
|
||||
if(sub_protocol>0)
|
||||
telemetry_link |= 0x80; // Disable telemetry output
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool __attribute__((unused)) DSM_Rx_bind_check_validity()
|
||||
static bool __attribute__((unused)) DSM_RX_bind_check_validity()
|
||||
{
|
||||
uint16_t sum = 384 - 0x10;//
|
||||
for(uint8_t i = 0; i < 8; i++)
|
||||
@@ -173,7 +177,7 @@ static bool __attribute__((unused)) DSM_Rx_bind_check_validity()
|
||||
return true;
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) DSM_Rx_build_bind_packet()
|
||||
static void __attribute__((unused)) DSM_RX_build_bind_packet()
|
||||
{
|
||||
uint16_t sum = 384 - 0x10;//
|
||||
packet[0] = 0xff ^ cyrfmfg_id[0]; // ID
|
||||
@@ -205,7 +209,7 @@ static void __attribute__((unused)) DSM_abort_channel_rx(uint8_t ch)
|
||||
CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x83); // Prepare to receive
|
||||
}
|
||||
|
||||
uint16_t DSM_Rx_callback()
|
||||
uint16_t DSM_RX_callback()
|
||||
{
|
||||
uint8_t rx_status;
|
||||
static uint8_t read_retry=0;
|
||||
@@ -232,7 +236,7 @@ uint16_t DSM_Rx_callback()
|
||||
if(len==16)
|
||||
{
|
||||
CYRF_ReadDataPacketLen(packet_in, 16);
|
||||
if(DSM_Rx_bind_check_validity())
|
||||
if(DSM_RX_bind_check_validity())
|
||||
{
|
||||
// store tx info into eeprom
|
||||
uint16_t temp = DSM_RX_EEPROM_OFFSET;
|
||||
@@ -257,6 +261,7 @@ uint16_t DSM_Rx_callback()
|
||||
&0x80 => false=DSM2, true=DSMX
|
||||
&0xF0 => false=1024, true=2048 */
|
||||
DSM_rx_type=packet_in[12];
|
||||
debugln(", num_ch=%d, type=%02X",num_ch, DSM_rx_type);
|
||||
switch(DSM_rx_type)
|
||||
{
|
||||
case 0x01:
|
||||
@@ -274,12 +279,11 @@ uint16_t DSM_Rx_callback()
|
||||
break;
|
||||
}
|
||||
eeprom_write_byte((EE_ADDR)temp, DSM_rx_type);
|
||||
debugln(", num_ch=%d, type=%02X",num_ch, DSM_rx_type);
|
||||
CYRF_WriteRegister(CYRF_29_RX_ABORT, 0x20); // Abort RX operation
|
||||
CYRF_SetTxRxMode(TX_EN); // Force end state TX
|
||||
CYRF_ConfigDataCode((const uint8_t *)"\x98\x88\x1B\xE4\x30\x79\x03\x84", 16);
|
||||
CYRF_WriteRegister(CYRF_29_RX_ABORT, 0x00); // Clear abort RX
|
||||
DSM_Rx_build_bind_packet();
|
||||
DSM_RX_build_bind_packet();
|
||||
bind_counter=500;
|
||||
phase++; // DSM_RX_BIND2;
|
||||
return 1000;
|
||||
@@ -301,11 +305,11 @@ uint16_t DSM_Rx_callback()
|
||||
if(read_retry==0)
|
||||
{
|
||||
packet_count=0;
|
||||
hopping_frequency_no++; // Change channel
|
||||
hopping_frequency_no++; // Change channel
|
||||
hopping_frequency_no %= 0x50;
|
||||
hopping_frequency_no |= 0x01; // Odd channels only
|
||||
hopping_frequency_no |= 0x01; // Odd channels only
|
||||
CYRF_ConfigRFChannel(hopping_frequency_no);
|
||||
DSM_abort_channel_rx(0); // Abort RX operation and receive
|
||||
DSM_abort_channel_rx(0); // Abort RX operation and receive
|
||||
}
|
||||
}
|
||||
return 1000;
|
||||
@@ -346,7 +350,7 @@ uint16_t DSM_Rx_callback()
|
||||
break;
|
||||
case DSM2_RX_SCAN: // Scan for DSM2 frequencies
|
||||
//Received something ?
|
||||
rx_status = DSM_Rx_check_packet();
|
||||
rx_status = DSM_RX_check_packet();
|
||||
if(rx_status == 0x02)
|
||||
{ // data received with no errors
|
||||
debugln("CH%d:Found %d",rf_ch_num+1,hopping_frequency[rf_ch_num]);
|
||||
@@ -401,13 +405,13 @@ uint16_t DSM_Rx_callback()
|
||||
pps_counter = 0;
|
||||
}
|
||||
//Received something ?
|
||||
rx_status = DSM_Rx_check_packet();
|
||||
rx_status = DSM_RX_check_packet();
|
||||
if(rx_status == 0x02)
|
||||
{ // data received with no errors
|
||||
#ifdef DSM_DEBUG_RF
|
||||
debugln("CH1:RX");
|
||||
#endif
|
||||
DSM_Rx_build_telemetry_packet();
|
||||
DSM_RX_build_telemetry_packet();
|
||||
rx_data_started = true;
|
||||
pps_counter++;
|
||||
DSM_abort_channel_rx(2); // Abort RX operation, set sop&data&seed&rf using CH2, DSM2/X and receive
|
||||
@@ -452,13 +456,13 @@ uint16_t DSM_Rx_callback()
|
||||
}
|
||||
return 500;
|
||||
case DSM_RX_DATA_CH2:
|
||||
rx_status = DSM_Rx_check_packet();
|
||||
rx_status = DSM_RX_check_packet();
|
||||
if(rx_status == 0x02)
|
||||
{ // data received with no errors
|
||||
#ifdef DSM_DEBUG_RF
|
||||
debugln("CH2:RX");
|
||||
#endif
|
||||
DSM_Rx_build_telemetry_packet();
|
||||
DSM_RX_build_telemetry_packet();
|
||||
pps_counter++;
|
||||
}
|
||||
#ifdef DSM_DEBUG_RF
|
||||
@@ -476,9 +480,9 @@ uint16_t DSM_Rx_callback()
|
||||
return 10000;
|
||||
}
|
||||
|
||||
uint16_t initDSM_Rx()
|
||||
void DSM_RX_init()
|
||||
{
|
||||
DSM_Rx_init();
|
||||
DSM_RX_RF_init();
|
||||
hopping_frequency_no = 0;
|
||||
|
||||
if (IS_BIND_IN_PROGRESS)
|
||||
@@ -499,7 +503,6 @@ uint16_t initDSM_Rx()
|
||||
debugln(", type=%02X", DSM_rx_type);
|
||||
phase = DSM_RX_DATA_PREP;
|
||||
}
|
||||
return 15000;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -86,21 +86,24 @@ static void __attribute__((unused)) DSM_build_bind_packet()
|
||||
if(sub_protocol==DSM_AUTO)
|
||||
packet[11] = 12;
|
||||
else
|
||||
packet[11] = num_ch;
|
||||
packet[11] = num_ch; // DX5 DSMR sends 0x48...
|
||||
|
||||
if (sub_protocol==DSM2_22)
|
||||
packet[12]=num_ch<8?0x01:0x02; // DSM2/1024 1 or 2 packets depending on the number of channels
|
||||
else if(sub_protocol==DSM2_11)
|
||||
packet[12]=0x12; // DSM2/2048 2 packets
|
||||
else if(sub_protocol==DSMX_22)
|
||||
if (sub_protocol==DSMR)
|
||||
packet[12] = 0xa2;
|
||||
else if (sub_protocol==DSM2_1F)
|
||||
packet[12] = num_ch<8?0x01:0x02; // DSM2/1024 1 or 2 packets depending on the number of channels
|
||||
else if(sub_protocol==DSM2_2F)
|
||||
packet[12] = 0x12; // DSM2/2048 2 packets
|
||||
else if(sub_protocol==DSMX_1F)
|
||||
#if defined DSM_TELEMETRY
|
||||
packet[12] = 0xb2; // DSMX/2048 2 packets
|
||||
#else
|
||||
packet[12] = num_ch<8? 0xa2 : 0xb2; // DSMX/2048 1 or 2 packets depending on the number of channels
|
||||
#endif
|
||||
else // DSMX_11 && DSM_AUTO
|
||||
packet[12]=0xb2; // DSMX/2048 2 packets
|
||||
else // DSMX_2F && DSM_AUTO
|
||||
packet[12] = 0xb2; // DSMX/2048 2 packets
|
||||
|
||||
|
||||
packet[13] = 0x00; //???
|
||||
for(i = 8; i < 14; i++)
|
||||
sum += packet[i];
|
||||
@@ -126,6 +129,9 @@ static void __attribute__((unused)) DSM_update_channels()
|
||||
if(num_ch<3 || num_ch>12)
|
||||
num_ch=6; // Default to 6 channels if invalid choice...
|
||||
|
||||
if(sub_protocol==DSMR && num_ch>7)
|
||||
num_ch=7; // Max 7 channels in DSMR
|
||||
|
||||
// Create channel map based on number of channels and refresh rate
|
||||
uint8_t idx=num_ch-3;
|
||||
if((option & 0x40) && num_ch>7 && num_ch<12)
|
||||
@@ -141,17 +147,30 @@ static void __attribute__((unused)) DSM_build_data_packet(uint8_t upper)
|
||||
if(prev_option!=option)
|
||||
DSM_update_channels();
|
||||
|
||||
if (sub_protocol==DSMX_11 || sub_protocol==DSMX_22 )
|
||||
if (sub_protocol==DSMX_2F || sub_protocol==DSMX_1F)
|
||||
{//DSMX
|
||||
packet[0] = cyrfmfg_id[2];
|
||||
packet[1] = cyrfmfg_id[3];
|
||||
}
|
||||
else
|
||||
{//DSM2
|
||||
{//DSM2 && DSMR
|
||||
packet[0] = (0xff ^ cyrfmfg_id[2]);
|
||||
packet[1] = (0xff ^ cyrfmfg_id[3]);
|
||||
if(sub_protocol==DSM2_22)
|
||||
bits=10; // Only DSM2_22 is using a resolution of 1024
|
||||
if(sub_protocol==DSM2_1F)
|
||||
bits=10; // Only DSM2_1F is using a resolution of 1024
|
||||
}
|
||||
|
||||
if(sub_protocol == DSMR)
|
||||
{
|
||||
for (uint8_t i = 0; i < 7; i++)
|
||||
{
|
||||
uint16_t value = 0x0000;
|
||||
if(i < num_ch)
|
||||
value=Channel_data[i]<<1;
|
||||
packet[i*2+2] = (value >> 8) & 0xff;
|
||||
packet[i*2+3] = (value >> 0) & 0xff;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef DSM_THROTTLE_KILL_CH
|
||||
@@ -179,18 +198,18 @@ static void __attribute__((unused)) DSM_build_data_packet(uint8_t upper)
|
||||
else
|
||||
#endif
|
||||
#ifdef DSM_MAX_THROW
|
||||
value=Channel_data[CH_TAER[idx]]; // -100%..+100% => 1024..1976us and -125%..+125% => 904..2096us based on Redcon 6 channel DSM2 RX
|
||||
value=Channel_data[CH_TAER[idx]]; // -100%..+100% => 1024..1976us and -125%..+125% => 904..2096us based on Redcon 6 channel DSM2 RX
|
||||
#else
|
||||
if(option & 0x80)
|
||||
value=Channel_data[CH_TAER[idx]]; // -100%..+100% => 1024..1976us and -125%..+125% => 904..2096us based on Redcon 6 channel DSM2 RX
|
||||
value=Channel_data[CH_TAER[idx]]; // -100%..+100% => 1024..1976us and -125%..+125% => 904..2096us based on Redcon 6 channel DSM2 RX
|
||||
else
|
||||
value=convert_channel_16b_nolimit(CH_TAER[idx],0x156,0x6AA,false); // -100%..+100% => 1100..1900us and -125%..+125% => 1000..2000us based on a DX8 G2 dump
|
||||
#endif
|
||||
if(bits==10) value>>=1;
|
||||
value |= (upper && i==0 ? 0x8000 : 0) | (idx << bits);
|
||||
}
|
||||
packet[i*2+2] = (value >> 8) & 0xff;
|
||||
packet[i*2+3] = (value >> 0) & 0xff;
|
||||
packet[i*2+2] = value >> 8;
|
||||
packet[i*2+3] = value;
|
||||
}
|
||||
#ifdef DSM_FWD_PGM
|
||||
if(upper==0 && DSM_SerialRX && (DSM_SerialRX_val[0]&0xF8)==0x70 )
|
||||
@@ -228,7 +247,7 @@ static uint8_t __attribute__((unused)) DSM_Check_RX_packet()
|
||||
return result;
|
||||
}
|
||||
|
||||
uint16_t ReadDsm()
|
||||
uint16_t DSM_callback()
|
||||
{
|
||||
#define DSM_CH1_CH2_DELAY 4010 // Time between write of channel 1 and channel 2
|
||||
#ifdef STM32_BOARD
|
||||
@@ -319,26 +338,32 @@ uint16_t ReadDsm()
|
||||
DSM_cyrf_configdata();
|
||||
CYRF_SetTxRxMode(TX_EN);
|
||||
hopping_frequency_no = 0;
|
||||
phase = DSM_CH1_WRITE_A; // in fact phase++
|
||||
DSM_set_sop_data_crc(phase==DSM_CH1_CHECK_A||phase==DSM_CH1_CHECK_B, sub_protocol==DSMX_11||sub_protocol==DSMX_22);
|
||||
phase = DSM_CH1_WRITE_A; // in fact phase++
|
||||
if(sub_protocol == DSMR)
|
||||
DSM_set_sop_data_crc(false, true);
|
||||
else
|
||||
DSM_set_sop_data_crc(true, sub_protocol==DSMX_2F||sub_protocol==DSMX_1F); //prep CH1
|
||||
return 10000;
|
||||
case DSM_CH1_WRITE_A:
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(11000); // Always request 11ms spacing even if we don't use half of it in 22ms mode
|
||||
telemetry_set_input_sync(11000); // Always request 11ms spacing even if we don't use half of it in 22ms mode
|
||||
#endif
|
||||
CYRF_SetPower(0x28); //Keep transmit power in sync
|
||||
if(sub_protocol == DSMR)
|
||||
CYRF_SetPower(0x08); //Keep transmit power in sync
|
||||
else
|
||||
CYRF_SetPower(0x28); //Keep transmit power in sync
|
||||
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:
|
||||
CYRF_ReadRegister(CYRF_04_TX_IRQ_STATUS); // clear IRQ flags
|
||||
CYRF_ReadRegister(CYRF_04_TX_IRQ_STATUS); // clear IRQ flags
|
||||
CYRF_WriteDataPacket(packet);
|
||||
#if 0
|
||||
for(uint8_t i=0;i<16;i++)
|
||||
debug(" %02X", packet[i]);
|
||||
debugln("");
|
||||
#endif
|
||||
phase++; // change from WRITE to CHECK mode
|
||||
phase++; // change from WRITE to CHECK mode
|
||||
return DSM_WRITE_DELAY;
|
||||
case DSM_CH1_CHECK_A:
|
||||
case DSM_CH1_CHECK_B:
|
||||
@@ -349,7 +374,7 @@ uint16_t ReadDsm()
|
||||
if((CYRF_ReadRegister(CYRF_02_TX_CTRL) & 0x80) == 0x00)
|
||||
break;
|
||||
|
||||
if(phase==DSM_CH1_CHECK_A || phase==DSM_CH1_CHECK_B)
|
||||
if((phase==DSM_CH1_CHECK_A || phase==DSM_CH1_CHECK_B) && sub_protocol!=DSMR)
|
||||
{
|
||||
#if defined DSM_TELEMETRY
|
||||
// reset cyrf6936 if freezed after switching from TX to RX
|
||||
@@ -361,14 +386,19 @@ uint16_t ReadDsm()
|
||||
CYRF_SetTxRxMode(TX_EN);
|
||||
}
|
||||
#endif
|
||||
DSM_set_sop_data_crc(phase==DSM_CH1_CHECK_A||phase==DSM_CH1_CHECK_B, sub_protocol==DSMX_11 || sub_protocol==DSMX_22);
|
||||
phase++; // change from CH1_CHECK to CH2_WRITE
|
||||
DSM_set_sop_data_crc(true, sub_protocol==DSMX_2F||sub_protocol==DSMX_1F); // prep CH2
|
||||
phase++; // change from CH1_CHECK to CH2_WRITE
|
||||
return DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY;
|
||||
}
|
||||
#if defined DSM_TELEMETRY
|
||||
phase++; // change from CH2_CHECK to CH2_READ
|
||||
CYRF_SetTxRxMode(RX_EN); //Receive mode
|
||||
CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x87); //0x80??? //Prepare to receive
|
||||
if(sub_protocol==DSMR)
|
||||
{
|
||||
phase = DSM_CH2_READ_B;
|
||||
return 11000 - DSM_WRITE_DELAY - DSM_READ_DELAY;
|
||||
}
|
||||
#ifdef DSM_GR300
|
||||
if(num_ch==3)
|
||||
return timing - DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY - DSM_READ_DELAY;
|
||||
@@ -400,7 +430,7 @@ uint16_t ReadDsm()
|
||||
telemetry_link=1;
|
||||
}
|
||||
CYRF_WriteRegister(CYRF_29_RX_ABORT, 0x20); // Abort RX operation
|
||||
if (phase == DSM_CH2_READ_A && (sub_protocol==DSM2_22 || sub_protocol==DSMX_22) && num_ch < 8) // 22ms mode
|
||||
if (phase == DSM_CH2_READ_A && (sub_protocol==DSM2_1F || sub_protocol==DSMX_1F) && num_ch < 8) // 22ms mode
|
||||
{
|
||||
CYRF_SetTxRxMode(RX_EN); // Force end state read
|
||||
CYRF_WriteRegister(CYRF_29_RX_ABORT, 0x00); // Clear abort RX operation
|
||||
@@ -418,14 +448,14 @@ uint16_t ReadDsm()
|
||||
phase = DSM_CH1_WRITE_A; //Transmit lower
|
||||
CYRF_SetTxRxMode(TX_EN); //TX mode
|
||||
CYRF_WriteRegister(CYRF_29_RX_ABORT, 0x00); //Clear abort RX operation
|
||||
DSM_set_sop_data_crc(phase==DSM_CH1_CHECK_A||phase==DSM_CH1_CHECK_B, sub_protocol==DSMX_11||sub_protocol==DSMX_22);
|
||||
DSM_set_sop_data_crc(false, sub_protocol==DSMX_2F||sub_protocol==DSMX_1F||sub_protocol==DSMR);
|
||||
return DSM_READ_DELAY;
|
||||
#else
|
||||
// No telemetry
|
||||
DSM_set_sop_data_crc(phase==DSM_CH1_CHECK_A||phase==DSM_CH1_CHECK_B, sub_protocol==DSMX_11||sub_protocol==DSMX_22);
|
||||
DSM_set_sop_data_crc(phase==DSM_CH1_CHECK_A||phase==DSM_CH1_CHECK_B, sub_protocol==DSMX_2F||sub_protocol==DSMX_1F);
|
||||
if (phase == DSM_CH2_CHECK_A)
|
||||
{
|
||||
if(num_ch > 7 || sub_protocol==DSM2_11 || sub_protocol==DSMX_11)
|
||||
if(num_ch > 7 || sub_protocol==DSM2_2F || sub_protocol==DSMX_2F)
|
||||
phase = DSM_CH1_WRITE_B; //11ms mode or upper to transmit change from CH2_CHECK_A to CH1_WRITE_A
|
||||
else
|
||||
{ //Normal mode 22ms
|
||||
@@ -449,25 +479,65 @@ uint16_t ReadDsm()
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t initDsm()
|
||||
|
||||
const uint8_t PROGMEM DSMR_ID_FREQ[][4 + 23] = {
|
||||
{ 0x71, 0x74, 0x1c, 0xe4, 0x11, 0x2f, 0x17, 0x3d, 0x23, 0x3b, 0x0f, 0x21, 0x25, 0x49, 0x1d, 0x13, 0x4d, 0x1f, 0x41, 0x4b, 0x47, 0x05, 0x27, 0x15, 0x19, 0x3f, 0x07 },
|
||||
{ 0xfe, 0xfe, 0xfe, 0xfe, 0x45, 0x31, 0x33, 0x4b, 0x11, 0x29, 0x49, 0x3f, 0x09, 0x13, 0x47, 0x21, 0x1d, 0x43, 0x1f, 0x05, 0x41, 0x19, 0x1b, 0x2d, 0x15, 0x4d, 0x0f },
|
||||
{ 0xfe, 0xff, 0xff, 0xff, 0x2a, 0x06, 0x22, 0x28, 0x16, 0x24, 0x38, 0x0e, 0x32, 0x2e, 0x14, 0x3a, 0x04, 0x44, 0x0c, 0x42, 0x1c, 0x4a, 0x10, 0x36, 0x3c, 0x48, 0x26 },
|
||||
{ 0xff, 0xfe, 0xff, 0xff, 0x28, 0x34, 0x48, 0x46, 0x3a, 0x12, 0x18, 0x32, 0x14, 0x42, 0x16, 0x40, 0x22, 0x44, 0x1c, 0x0a, 0x36, 0x20, 0x10, 0x0c, 0x3c, 0x26, 0x2e },
|
||||
{ 0xff, 0xff, 0xfe, 0xff, 0x3c, 0x16, 0x04, 0x48, 0x1e, 0x4a, 0x10, 0x18, 0x22, 0x28, 0x38, 0x40, 0x20, 0x06, 0x3e, 0x42, 0x30, 0x1a, 0x2c, 0x1c, 0x46, 0x14, 0x34 },
|
||||
{ 0xff, 0xff, 0xff, 0xfe, 0x4d, 0x39, 0x1b, 0x13, 0x45, 0x2f, 0x0d, 0x3d, 0x0b, 0x11, 0x47, 0x2d, 0x19, 0x1d, 0x23, 0x35, 0x33, 0x3b, 0x21, 0x31, 0x17, 0x0f, 0x43 },
|
||||
{ 0xff, 0xff, 0xff, 0xff, 0x14, 0x28, 0x2e, 0x32, 0x3e, 0x10, 0x38, 0x0e, 0x12, 0x06, 0x2c, 0x26, 0x30, 0x4c, 0x34, 0x16, 0x04, 0x3a, 0x42, 0x48, 0x36, 0x46, 0x1a },
|
||||
{ 0x00, 0xff, 0xff, 0xff, 0x3e, 0x30, 0x42, 0x24, 0x06, 0x0e, 0x14, 0x1c, 0x08, 0x10, 0x20, 0x22, 0x04, 0x32, 0x0c, 0x44, 0x3c, 0x46, 0x4a, 0x26, 0x4c, 0x48, 0x1e },
|
||||
{ 0xff, 0x00, 0xff, 0xff, 0x38, 0x0e, 0x22, 0x2a, 0x44, 0x3a, 0x4a, 0x3e, 0x16, 0x20, 0x36, 0x24, 0x46, 0x18, 0x1e, 0x12, 0x1c, 0x30, 0x2c, 0x14, 0x06, 0x0c, 0x40 },
|
||||
{ 0x00, 0x00, 0xff, 0xff, 0x06, 0x4c, 0x26, 0x08, 0x46, 0x3e, 0x30, 0x12, 0x38, 0x1c, 0x04, 0x4a, 0x2c, 0x1a, 0x20, 0x3a, 0x18, 0x36, 0x28, 0x2e, 0x22, 0x40, 0x10 },
|
||||
{ 0xff, 0xff, 0x00, 0xff, 0x12, 0x06, 0x3c, 0x2a, 0x22, 0x38, 0x48, 0x4c, 0x32, 0x44, 0x26, 0x16, 0x0c, 0x28, 0x2c, 0x36, 0x1c, 0x1a, 0x42, 0x10, 0x08, 0x4a, 0x34 },
|
||||
{ 0x00, 0xff, 0x00, 0xff, 0x04, 0x4c, 0x4a, 0x28, 0x2a, 0x24, 0x14, 0x1e, 0x40, 0x48, 0x44, 0x2c, 0x2e, 0x1a, 0x12, 0x46, 0x3a, 0x0e, 0x18, 0x1c, 0x20, 0x10, 0x42 },
|
||||
{ 0xff, 0x00, 0x00, 0xff, 0x06, 0x10, 0x14, 0x16, 0x48, 0x18, 0x44, 0x2c, 0x0a, 0x26, 0x24, 0x42, 0x36, 0x30, 0x38, 0x3e, 0x0c, 0x3c, 0x34, 0x46, 0x2a, 0x32, 0x0e },
|
||||
{ 0x00, 0x00, 0x00, 0xff, 0x2c, 0x0a, 0x46, 0x28, 0x38, 0x24, 0x14, 0x06, 0x04, 0x10, 0x18, 0x30, 0x12, 0x20, 0x3a, 0x1a, 0x32, 0x3c, 0x3e, 0x4a, 0x1e, 0x44, 0x36 },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x45, 0x23, 0x07, 0x37, 0x4b, 0x13, 0x3d, 0x31, 0x19, 0x2b, 0x2f, 0x2d, 0x1f, 0x4d, 0x3f, 0x1b, 0x43, 0x27, 0x3b, 0x11, 0x05, 0x0d, 0x17 },
|
||||
{ 0xff, 0xff, 0xff, 0x00, 0x0b, 0x4b, 0x1d, 0x39, 0x09, 0x0f, 0x49, 0x25, 0x07, 0x35, 0x3b, 0x05, 0x33, 0x17, 0x2d, 0x11, 0x2b, 0x29, 0x1f, 0x45, 0x1b, 0x41, 0x47 },
|
||||
{ 0x00, 0xff, 0xff, 0x00, 0x41, 0x35, 0x11, 0x25, 0x29, 0x27, 0x33, 0x47, 0x4d, 0x31, 0x05, 0x37, 0x15, 0x1f, 0x23, 0x07, 0x1b, 0x0f, 0x3b, 0x49, 0x19, 0x3f, 0x0b },
|
||||
{ 0xff, 0x00, 0xff, 0x00, 0x25, 0x47, 0x05, 0x0b, 0x45, 0x1f, 0x2b, 0x27, 0x2d, 0x09, 0x07, 0x43, 0x49, 0x29, 0x4d, 0x39, 0x33, 0x41, 0x17, 0x0f, 0x15, 0x19, 0x3b },
|
||||
{ 0x00, 0x00, 0xff, 0x00, 0x3b, 0x05, 0x21, 0x0d, 0x1b, 0x43, 0x17, 0x2d, 0x1d, 0x25, 0x4b, 0x35, 0x4d, 0x3f, 0x07, 0x09, 0x37, 0x41, 0x15, 0x1f, 0x0f, 0x27, 0x29 },
|
||||
{ 0xff, 0xff, 0x00, 0x00, 0x2b, 0x35, 0x1b, 0x1d, 0x0f, 0x47, 0x09, 0x0d, 0x45, 0x41, 0x21, 0x11, 0x2f, 0x43, 0x27, 0x33, 0x4b, 0x37, 0x13, 0x19, 0x4d, 0x23, 0x17 },
|
||||
{ 0x00, 0xff, 0x00, 0x00, 0x1b, 0x1d, 0x33, 0x13, 0x2b, 0x27, 0x09, 0x41, 0x25, 0x17, 0x19, 0x2d, 0x4b, 0x37, 0x45, 0x11, 0x21, 0x0d, 0x3d, 0x4d, 0x07, 0x39, 0x43 },
|
||||
{ 0xff, 0x00, 0x00, 0x00, 0x37, 0x27, 0x43, 0x4b, 0x39, 0x13, 0x07, 0x0d, 0x25, 0x17, 0x29, 0x1b, 0x1d, 0x45, 0x19, 0x2d, 0x0b, 0x3d, 0x15, 0x47, 0x1f, 0x21, 0x4d } };
|
||||
|
||||
void DSM_init()
|
||||
{
|
||||
CYRF_GetMfgData(cyrfmfg_id);
|
||||
//Model match
|
||||
cyrfmfg_id[3]^=RX_num;
|
||||
if(sub_protocol == DSMR)
|
||||
{
|
||||
uint8_t row = rx_tx_addr[3]%22;
|
||||
for(uint8_t i=0; i< 4; i++)
|
||||
cyrfmfg_id[i] = pgm_read_byte_near(&DSMR_ID_FREQ[row][i]);
|
||||
for(uint8_t i=0; i< 23; i++)
|
||||
hopping_frequency[i] = pgm_read_byte_near(&DSMR_ID_FREQ[row][i+4]);
|
||||
}
|
||||
else
|
||||
{
|
||||
CYRF_GetMfgData(cyrfmfg_id);
|
||||
//Model match
|
||||
cyrfmfg_id[3]^=RX_num;
|
||||
}
|
||||
|
||||
//Calc sop_col
|
||||
sop_col = (cyrfmfg_id[0] + cyrfmfg_id[1] + cyrfmfg_id[2] + 2) & 0x07;
|
||||
|
||||
//Fix for OrangeRX using wrong DSM_pncodes by preventing access to "Col 8"
|
||||
if(sop_col==0)
|
||||
if(sop_col==0 && sub_protocol != DSMR)
|
||||
{
|
||||
cyrfmfg_id[rx_tx_addr[0]%3]^=0x01; //Change a bit so sop_col will be different from 0
|
||||
sop_col = (cyrfmfg_id[0] + cyrfmfg_id[1] + cyrfmfg_id[2] + 2) & 0x07;
|
||||
}
|
||||
|
||||
//Calc CRC seed
|
||||
seed = (cyrfmfg_id[0] << 8) + cyrfmfg_id[1];
|
||||
|
||||
//Hopping frequencies
|
||||
if (sub_protocol == DSMX_11 || sub_protocol == DSMX_22)
|
||||
if (sub_protocol == DSMX_2F || sub_protocol == DSMX_1F)
|
||||
DSM_calc_dsmx_channel();
|
||||
else
|
||||
else if(sub_protocol != DSMR)
|
||||
{
|
||||
uint8_t tmpch[10];
|
||||
CYRF_FindBestChannels(tmpch, 10, 5, 3, 75);
|
||||
@@ -482,6 +552,7 @@ uint16_t initDsm()
|
||||
}
|
||||
hopping_frequency[1] = tmpch[idx];
|
||||
}
|
||||
|
||||
//
|
||||
DSM_cyrf_config();
|
||||
CYRF_SetTxRxMode(TX_EN);
|
||||
@@ -496,7 +567,6 @@ uint16_t initDsm()
|
||||
}
|
||||
else
|
||||
phase = DSM_CHANSEL;//
|
||||
return 10000;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -163,29 +163,148 @@ static void __attribute__((unused)) DEVO_build_data_pkt()
|
||||
}
|
||||
|
||||
#if defined DEVO_HUB_TELEMETRY
|
||||
static void __attribute__((unused)) DEVO_parse_telemetry_packet()
|
||||
static uint32_t __attribute__((unused)) DEVO_text_to_int(uint8_t *ptr, uint8_t len)
|
||||
{
|
||||
uint32_t value = 0;
|
||||
for(uint8_t i = 0; i < len; i++)
|
||||
value = value * 10 + (ptr[i] - '0');
|
||||
return value;
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) DEVO_float_to_ints(uint8_t *ptr, uint16_t *value, uint16_t *decimal)
|
||||
{
|
||||
bool seen_decimal = false;
|
||||
*value = 0;
|
||||
*decimal = 0;
|
||||
for(uint8_t i = 0; i < 7; i++)
|
||||
{
|
||||
if(ptr[i] == '.')
|
||||
{
|
||||
seen_decimal = true;
|
||||
continue;
|
||||
}
|
||||
if(ptr[i] < '0' || ptr[i] > '9')
|
||||
{
|
||||
if(*value != 0 || seen_decimal)
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(seen_decimal)
|
||||
*decimal = *decimal * 10 + (ptr[i] - '0');
|
||||
else
|
||||
*value = *value * 10 + (ptr[i] - '0');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) DEVO_parse_telemetry_packet()
|
||||
{ // Telemetry packets every 2.4ms
|
||||
DEVO_scramble_pkt(); //This will unscramble the packet
|
||||
|
||||
debugln("RX");
|
||||
if ((((uint32_t)packet[15] << 16) | ((uint32_t)packet[14] << 8) | packet[13]) != (MProtocol_id & 0x00ffffff))
|
||||
return; // ID does not match
|
||||
|
||||
//RSSI
|
||||
TX_RSSI = CYRF_ReadRegister(CYRF_13_RSSI) & 0x1F;
|
||||
TX_RSSI = (TX_RSSI << 1) + TX_RSSI;
|
||||
RX_RSSI = TX_RSSI;
|
||||
telemetry_link = 1;
|
||||
|
||||
//TODO: FW telemetry https://github.com/DeviationTX/deviation/blob/5efb6a28bea697af9a61b5a0ed2528cc8d203f90/src/protocol/devo_cyrf6936.c#L232
|
||||
|
||||
debug("P[0]=%02X",packet[0]);
|
||||
|
||||
if (packet[0] == 0x30) // Volt packet
|
||||
|
||||
if((telemetry_link & 3) != 0)
|
||||
{
|
||||
v_lipo1 = packet[1] << 1;
|
||||
v_lipo2 = packet[3] << 1;
|
||||
debugln("S%d",telemetry_link);
|
||||
return; // Previous telemetry not sent yet...
|
||||
}
|
||||
|
||||
//Debug telem RX
|
||||
//for(uint8_t i=0;i<12;i++)
|
||||
// debug("%02X ",packet[i]);
|
||||
//debugln("");
|
||||
|
||||
#if defined HUB_TELEMETRY
|
||||
//Telemetry https://github.com/DeviationTX/deviation/blob/5efb6a28bea697af9a61b5a0ed2528cc8d203f90/src/protocol/devo_cyrf6936.c#L232
|
||||
uint16_t val, dec;
|
||||
switch(packet[0])
|
||||
{
|
||||
case 0x30: // Volt and RPM packet
|
||||
//RSSI and voltage
|
||||
TX_RSSI = CYRF_ReadRegister(CYRF_13_RSSI) & 0x1F;
|
||||
TX_RSSI = (TX_RSSI << 1) + TX_RSSI;
|
||||
RX_RSSI = TX_RSSI;
|
||||
telemetry_link |= 1;
|
||||
v_lipo1 = packet[1] << 1;
|
||||
v_lipo2 = packet[3] << 1;
|
||||
//packet[5] = 127; // 12.7V
|
||||
if(packet[5] != 0)
|
||||
{
|
||||
val = (packet[5]*11)/21; // OpenTX strange transformation??
|
||||
dec = val;
|
||||
val /= 10;
|
||||
dec -= val*10;
|
||||
frsky_send_user_frame(0x3A, val, 0x00); // volt3
|
||||
frsky_send_user_frame(0x3B, dec, 0x00); // volt3
|
||||
}
|
||||
val = packet[7] * 120; // change to RPM
|
||||
frsky_send_user_frame(0x03, val, val>>8); // RPM
|
||||
break;
|
||||
case 0x31: // Temperature packet
|
||||
//memcpy(&packet[1],"\x29\x2A\x2B\x00\x00\x00\x00\x00\x00\x00\x00\x00",12); // 21°, 22°, 23°
|
||||
for(uint8_t i=0; i<2;i++)
|
||||
if(packet[i+1]!=0xff)
|
||||
{
|
||||
val = packet[i+1];
|
||||
val -= 20;
|
||||
frsky_send_user_frame(0x02 + i*3, val, val>>8); // temp 1 & 2
|
||||
}
|
||||
break;
|
||||
// GPS Data
|
||||
case 0x32: // Longitude
|
||||
//memcpy(&packet[1],"\x30\x33\x30\x32\x30\x2e\x38\x32\x37\x30\x45\xfb",12); // 030°20.8270E
|
||||
val = DEVO_text_to_int(&packet[1], 3)*100 + DEVO_text_to_int(&packet[4], 2); // dddmm
|
||||
frsky_send_user_frame(0x12 , val, val>>8);
|
||||
val = DEVO_text_to_int(&packet[7], 4); // .mmmm
|
||||
frsky_send_user_frame(0x12+8, val, val>>8);
|
||||
frsky_send_user_frame(0x1A+8, packet[11], 0x00); // 'E'/'W'
|
||||
break;
|
||||
case 0x33: // Latitude
|
||||
//memcpy(&packet[1],"\x35\x39\x35\x34\x2e\x37\x37\x37\x36\x4e\x07\x00",12); // 59°54.776N
|
||||
val = DEVO_text_to_int(&packet[1], 2)*100 + DEVO_text_to_int(&packet[3], 2); // ddmm
|
||||
frsky_send_user_frame(0x13 , val, val>>8);
|
||||
val = DEVO_text_to_int(&packet[6], 4); // .mmmm
|
||||
frsky_send_user_frame(0x13+8, val, val>>8);
|
||||
frsky_send_user_frame(0x1B+8, packet[10], 0x00); // 'N'/'S'
|
||||
break;
|
||||
case 0x34: // Altitude
|
||||
//memcpy(&packet[1],"\x31\x32\x2e\x38\x00\x00\x00\x4d\x4d\x4e\x45\xfb",12); // 12.8 MMNE
|
||||
DEVO_float_to_ints(&packet[1], &val, &dec);
|
||||
frsky_send_user_frame(0x10, val, val>>8);
|
||||
frsky_send_user_frame(0x21, dec, dec>>8);
|
||||
break;
|
||||
case 0x35: // Speed
|
||||
//memcpy(&packet[1],"\x00\x00\x00\x00\x00\x00\x30\x2e\x30\x30\x00\x00",12); // 0.0
|
||||
DEVO_float_to_ints(&packet[1], &val, &dec);
|
||||
frsky_send_user_frame(0x11 , val, val>>8);
|
||||
frsky_send_user_frame(0x11+8, dec, dec>>8);
|
||||
break;
|
||||
case 0x36: // Time
|
||||
//memcpy(&packet[1],"\x31\x38\x32\x35\x35\x32\x31\x35\x31\x30\x31\x32",12); // "182552151012" = 2012-10-15 18:25:52 (UTC)
|
||||
if(packet[1]!=0)
|
||||
{
|
||||
frsky_send_user_frame(0x15, DEVO_text_to_int(&packet[9], 2), DEVO_text_to_int(&packet[7], 2)); // month, day
|
||||
val = 2000 + DEVO_text_to_int(&packet[11], 2); // year
|
||||
frsky_send_user_frame(0x16, val, val>>8);
|
||||
frsky_send_user_frame(0x17, DEVO_text_to_int(&packet[1], 2), DEVO_text_to_int(&packet[3], 2)); // hour, min
|
||||
frsky_send_user_frame(0x18, DEVO_text_to_int(&packet[5], 2), 0x00); // second
|
||||
}
|
||||
break;
|
||||
}
|
||||
#else
|
||||
if(packet[0] == 0x30)
|
||||
{
|
||||
TX_RSSI = CYRF_ReadRegister(CYRF_13_RSSI) & 0x1F;
|
||||
TX_RSSI = (TX_RSSI << 1) + TX_RSSI;
|
||||
RX_RSSI = TX_RSSI;
|
||||
telemetry_link |= 1;
|
||||
v_lipo1 = packet[1] << 1;
|
||||
v_lipo2 = packet[3] << 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -294,7 +413,7 @@ static void __attribute__((unused)) DEVO_BuildPacket()
|
||||
packet_count = 0;
|
||||
}
|
||||
|
||||
uint16_t devo_callback()
|
||||
uint16_t DEVO_callback()
|
||||
{
|
||||
static uint8_t txState=0;
|
||||
|
||||
@@ -404,8 +523,23 @@ uint16_t devo_callback()
|
||||
#endif
|
||||
}
|
||||
|
||||
uint16_t DevoInit()
|
||||
void DEVO_init()
|
||||
{
|
||||
#ifdef ENABLE_PPM
|
||||
if(mode_select) //PPM mode
|
||||
{
|
||||
if(IS_BIND_BUTTON_FLAG_on)
|
||||
{
|
||||
eeprom_write_byte((EE_ADDR)(MODELMODE_EEPROM_OFFSET+RX_num),0x00); // reset to autobind mode for the current model
|
||||
option=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
option=eeprom_read_byte((EE_ADDR)(MODELMODE_EEPROM_OFFSET+RX_num)); // load previous mode: autobind or fixed id
|
||||
if(option!=1) option=0; // if not fixed id mode then it should be autobind
|
||||
}
|
||||
}
|
||||
#endif //ENABLE_PPM
|
||||
switch(sub_protocol)
|
||||
{
|
||||
case 1:
|
||||
@@ -453,7 +587,6 @@ uint16_t DevoInit()
|
||||
bind_counter = 0;
|
||||
DEVO_cyrf_set_bound_sop_code();
|
||||
}
|
||||
return 2400;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
#define E010R5_FORCE_ID
|
||||
|
||||
#define E010R5_BIND_CH 0x2D //45
|
||||
#define E010R5_PAYLOAD_SIZE 14
|
||||
|
||||
|
||||
@@ -51,15 +50,12 @@ static void __attribute__((unused)) E010R5_build_data_packet()
|
||||
RF2500_BuildPayload(packet);
|
||||
}
|
||||
|
||||
uint16_t ReadE010R5()
|
||||
uint16_t E010R5_callback()
|
||||
{
|
||||
//Bind
|
||||
if(bind_counter)
|
||||
{
|
||||
bind_counter--;
|
||||
if(bind_counter==0)
|
||||
if(--bind_counter==0)
|
||||
BIND_DONE;
|
||||
}
|
||||
|
||||
//Send packet
|
||||
RF2500_SendPayload();
|
||||
@@ -90,7 +86,7 @@ uint16_t ReadE010R5()
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t initE010R5()
|
||||
void E010R5_init()
|
||||
{
|
||||
BIND_IN_PROGRESS; // Autobind protocol
|
||||
bind_counter = 2600;
|
||||
@@ -99,33 +95,49 @@ uint16_t initE010R5()
|
||||
RF2500_Init(E010R5_PAYLOAD_SIZE, false); // 14 bytes, not scrambled
|
||||
RF2500_SetTXAddr((uint8_t*)"\x0E\x54\x96\xEE"); // Same address for bind and normal packets
|
||||
|
||||
rx_tx_addr[0]=0x00;
|
||||
hopping_frequency[0]=0x35; //53
|
||||
#ifdef E010R5_FORCE_ID
|
||||
switch(rx_tx_addr[3]%3)
|
||||
switch(rx_tx_addr[3]%5)
|
||||
{
|
||||
case 0:
|
||||
//TX1
|
||||
hopping_frequency[0]=0x35; //53
|
||||
hopping_frequency[1]=0x30; //48
|
||||
//hopping_frequency[0]=0x35; //53
|
||||
hopping_frequency[1]=0x30; //48
|
||||
rx_tx_addr[1]=0x45;
|
||||
rx_tx_addr[2]=0x46;
|
||||
break;
|
||||
case 1:
|
||||
//TX2
|
||||
hopping_frequency[0]=0x35; //53
|
||||
hopping_frequency[1]=0x3C; //60
|
||||
//hopping_frequency[0]=0x35; //53
|
||||
hopping_frequency[1]=0x3C; //60
|
||||
rx_tx_addr[1]=0x1B;
|
||||
rx_tx_addr[2]=0x9E;
|
||||
break;
|
||||
case 2:
|
||||
//TX4
|
||||
hopping_frequency[0]=0x30; //48
|
||||
hopping_frequency[1]=0x38; //56
|
||||
rx_tx_addr[1]=0x2E;
|
||||
rx_tx_addr[2]=0xAE;
|
||||
break;
|
||||
case 3:
|
||||
//TX5
|
||||
//hopping_frequency[0]=0x35; //53
|
||||
hopping_frequency[1]=0x41; //65
|
||||
rx_tx_addr[0]=0x0D;
|
||||
rx_tx_addr[1]=0xB9;
|
||||
rx_tx_addr[2]=0xFC;
|
||||
break;
|
||||
default:
|
||||
//TX3
|
||||
hopping_frequency[0]=0x30; //48
|
||||
hopping_frequency[1]=0x38; //56
|
||||
hopping_frequency[0]=0x30; //48
|
||||
hopping_frequency[1]=0x38; //56
|
||||
rx_tx_addr[1]=0x17;
|
||||
rx_tx_addr[2]=0x0D;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
rx_tx_addr[0]=0x00;
|
||||
// This is the same as the E010 v1...
|
||||
hopping_frequency[2]=hopping_frequency[0]+0x10;
|
||||
hopping_frequency[3]=hopping_frequency[1]+0x10;
|
||||
@@ -134,8 +146,6 @@ uint16_t initE010R5()
|
||||
RF2500_RFChannel(hopping_frequency[0]);
|
||||
hopping_frequency_no=0;
|
||||
packet_count=0;
|
||||
|
||||
return 3400;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -124,7 +124,7 @@ uint16_t E016HV2_callback()
|
||||
return E016HV2_PACKET_PERIOD;
|
||||
}
|
||||
|
||||
uint16_t initE016HV2()
|
||||
void E016HV2_init()
|
||||
{
|
||||
//Config CC2500
|
||||
CC2500_250K_Init();
|
||||
@@ -152,7 +152,6 @@ uint16_t initE016HV2()
|
||||
flags=0;
|
||||
bind_counter = E016HV2_BIND_COUNT;
|
||||
BIND_IN_PROGRESS; // Autobind protocol
|
||||
return E016HV2_INITIAL_WAIT;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
154
Multiprotocol/E016H_nrf24l01.ino
Normal file
154
Multiprotocol/E016H_nrf24l01.ino
Normal file
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
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 E016H
|
||||
|
||||
#if defined(E016H_NRF24L01_INO)
|
||||
|
||||
#include "iface_xn297.h"
|
||||
|
||||
//Protocols constants
|
||||
#define E016H_BIND_COUNT 500
|
||||
#define E016H_ADDRESS_LENGTH 5
|
||||
|
||||
#define E016H_PACKET_PERIOD 4080
|
||||
#define E016H_PACKET_SIZE 10
|
||||
#define E016H_BIND_CHANNEL 80
|
||||
#define E016H_NUM_CHANNELS 4
|
||||
|
||||
//Channels
|
||||
#define E016H_STOP_SW CH5_SW
|
||||
#define E016H_FLIP_SW CH6_SW
|
||||
#define E016H_HEADLESS_SW CH8_SW
|
||||
#define E016H_RTH_SW CH9_SW
|
||||
|
||||
// E016H flags packet[1]
|
||||
#define E016H_FLAG_CALIBRATE 0x80
|
||||
#define E016H_FLAG_STOP 0x20
|
||||
#define E016H_FLAG_FLIP 0x04
|
||||
// E016H flags packet[3]
|
||||
#define E016H_FLAG_HEADLESS 0x10
|
||||
#define E016H_FLAG_RTH 0x04
|
||||
// E016H flags packet[7]
|
||||
#define E016H_FLAG_TAKEOFF 0x80
|
||||
#define E016H_FLAG_HIGHRATE 0x08
|
||||
|
||||
static void __attribute__((unused)) E016H_send_packet()
|
||||
{
|
||||
uint8_t can_flip = 0, calibrate = 1;
|
||||
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
memcpy(packet, &rx_tx_addr[1], 4);
|
||||
memcpy(&packet[4], hopping_frequency, 4);
|
||||
packet[8] = 0x23;
|
||||
}
|
||||
else
|
||||
{
|
||||
// trim commands
|
||||
packet[0] = 0;
|
||||
// aileron
|
||||
uint16_t val = convert_channel_16b_limit(AILERON, 0, 0x3ff);
|
||||
can_flip |= (val < 0x100) || (val > 0x300);
|
||||
packet[1] = val >> 8;
|
||||
packet[2] = val & 0xff;
|
||||
if(val < 0x300) calibrate = 0;
|
||||
// elevator
|
||||
val = convert_channel_16b_limit(ELEVATOR, 0x3ff, 0);
|
||||
can_flip |= (val < 0x100) || (val > 0x300);
|
||||
packet[3] = val >> 8;
|
||||
packet[4] = val & 0xff;
|
||||
if(val < 0x300) calibrate = 0;
|
||||
// throttle
|
||||
val = convert_channel_16b_limit(THROTTLE, 0, 0x3ff);
|
||||
packet[5] = val >> 8;
|
||||
packet[6] = val & 0xff;
|
||||
if(val > 0x100) calibrate = 0;
|
||||
// rudder
|
||||
val = convert_channel_16b_limit(RUDDER, 0, 0x3ff);
|
||||
packet[7] = val >> 8;
|
||||
packet[8] = val & 0xff;
|
||||
if(val > 0x100) calibrate = 0;
|
||||
// flags
|
||||
packet[1] |= GET_FLAG(E016H_STOP_SW, E016H_FLAG_STOP)
|
||||
| (can_flip ? GET_FLAG(E016H_FLIP_SW, E016H_FLAG_FLIP) : 0)
|
||||
| (calibrate ? E016H_FLAG_CALIBRATE : 0);
|
||||
packet[3] |= GET_FLAG(E016H_HEADLESS_SW, E016H_FLAG_HEADLESS)
|
||||
| GET_FLAG(E016H_RTH_SW, E016H_FLAG_RTH);
|
||||
packet[7] |= E016H_FLAG_HIGHRATE;
|
||||
// frequency hopping
|
||||
XN297_Hopping(hopping_frequency_no++ & 0x03);
|
||||
}
|
||||
// checksum
|
||||
packet[9] = packet[0];
|
||||
for (uint8_t i=1; i < E016H_PACKET_SIZE-1; i++)
|
||||
packet[9] += packet[i];
|
||||
|
||||
// Send
|
||||
XN297_SetPower();
|
||||
XN297_SetTxRxMode(TX_EN);
|
||||
XN297_WritePayload(packet, E016H_PACKET_SIZE);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) E016H_RF_init()
|
||||
{
|
||||
XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M);
|
||||
XN297_SetTXAddr((uint8_t *)"\x5a\x53\x46\x30\x31", 5); // bind address
|
||||
//XN297_HoppingCalib(E016H_NUM_CHANNELS);
|
||||
XN297_RFChannel(E016H_BIND_CHANNEL);
|
||||
}
|
||||
|
||||
uint16_t E016H_callback()
|
||||
{
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(packet_period);
|
||||
#endif
|
||||
if(bind_counter)
|
||||
{
|
||||
bind_counter--;
|
||||
if (bind_counter == 0)
|
||||
{
|
||||
XN297_SetTXAddr(rx_tx_addr, E016H_ADDRESS_LENGTH);
|
||||
BIND_DONE;
|
||||
}
|
||||
}
|
||||
E016H_send_packet();
|
||||
return E016H_PACKET_PERIOD;
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) E016H_initialize_txid()
|
||||
{
|
||||
// tx id
|
||||
rx_tx_addr[0] = 0xa5;
|
||||
rx_tx_addr[1] = 0x00;
|
||||
|
||||
// rf channels
|
||||
uint32_t lfsr=random(0xfefefefe);
|
||||
for(uint8_t i=0; i<E016H_NUM_CHANNELS; i++)
|
||||
{
|
||||
hopping_frequency[i] = (lfsr & 0xFF) % 80;
|
||||
lfsr>>=8;
|
||||
}
|
||||
}
|
||||
|
||||
void E016H_init()
|
||||
{
|
||||
BIND_IN_PROGRESS;
|
||||
E016H_initialize_txid();
|
||||
E016H_RF_init();
|
||||
bind_counter = E016H_BIND_COUNT;
|
||||
hopping_frequency_no = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -33,11 +33,6 @@
|
||||
#define E015_PACKET_SIZE 10
|
||||
#define E015_BIND_PACKET_SIZE 9
|
||||
|
||||
#define E016H_PACKET_PERIOD 4080
|
||||
#define E016H_PACKET_SIZE 10
|
||||
#define E016H_BIND_CHANNEL 80
|
||||
#define E016H_NUM_CHANNELS 4
|
||||
|
||||
//Channels
|
||||
#define E01X_ARM_SW CH5_SW
|
||||
#define E016H_STOP_SW CH5_SW
|
||||
@@ -64,17 +59,6 @@
|
||||
#define E015_FLAG_EXPERT 0x02
|
||||
#define E015_FLAG_INTERMEDIATE 0x01
|
||||
|
||||
// E016H flags packet[1]
|
||||
#define E016H_FLAG_CALIBRATE 0x80
|
||||
#define E016H_FLAG_STOP 0x20
|
||||
#define E016H_FLAG_FLIP 0x04
|
||||
// E016H flags packet[3]
|
||||
#define E016H_FLAG_HEADLESS 0x10
|
||||
#define E016H_FLAG_RTH 0x04
|
||||
// E016H flags packet[7]
|
||||
#define E016H_FLAG_TAKEOFF 0x80
|
||||
#define E016H_FLAG_HIGHRATE 0x08
|
||||
|
||||
static void __attribute__((unused)) E015_check_arming()
|
||||
{
|
||||
uint8_t arm_channel = E01X_ARM_SW;
|
||||
@@ -95,14 +79,13 @@ static void __attribute__((unused)) E015_check_arming()
|
||||
}
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) E01X_send_packet(uint8_t bind)
|
||||
static void __attribute__((unused)) E01X_send_packet()
|
||||
{
|
||||
uint8_t can_flip = 0, calibrate = 1;
|
||||
if(sub_protocol==E012)
|
||||
{
|
||||
packet_length=E012_PACKET_SIZE;
|
||||
packet[0] = rx_tx_addr[1];
|
||||
if(bind)
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
packet[1] = 0xaa;
|
||||
memcpy(&packet[2], hopping_frequency, E012_NUM_RF_CHANNELS);
|
||||
@@ -132,9 +115,9 @@ static void __attribute__((unused)) E01X_send_packet(uint8_t bind)
|
||||
packet[13] = 0x56;
|
||||
packet[14] = rx_tx_addr[2];
|
||||
}
|
||||
else if(sub_protocol==E015)
|
||||
else
|
||||
{ // E015
|
||||
if(bind)
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
packet[0] = 0x18;
|
||||
packet[1] = 0x04;
|
||||
@@ -170,72 +153,14 @@ static void __attribute__((unused)) E01X_send_packet(uint8_t bind)
|
||||
packet_length=E015_PACKET_SIZE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // E016H
|
||||
packet_length=E016H_PACKET_SIZE;
|
||||
if(bind)
|
||||
{
|
||||
rf_ch_num=E016H_BIND_CHANNEL;
|
||||
memcpy(packet, &rx_tx_addr[1], 4);
|
||||
memcpy(&packet[4], hopping_frequency, 4);
|
||||
packet[8] = 0x23;
|
||||
}
|
||||
else
|
||||
{
|
||||
// trim commands
|
||||
packet[0] = 0;
|
||||
// aileron
|
||||
uint16_t val = convert_channel_16b_limit(AILERON, 0, 0x3ff);
|
||||
can_flip |= (val < 0x100) || (val > 0x300);
|
||||
packet[1] = val >> 8;
|
||||
packet[2] = val & 0xff;
|
||||
if(val < 0x300) calibrate = 0;
|
||||
// elevator
|
||||
val = convert_channel_16b_limit(ELEVATOR, 0x3ff, 0);
|
||||
can_flip |= (val < 0x100) || (val > 0x300);
|
||||
packet[3] = val >> 8;
|
||||
packet[4] = val & 0xff;
|
||||
if(val < 0x300) calibrate = 0;
|
||||
// throttle
|
||||
val = convert_channel_16b_limit(THROTTLE, 0, 0x3ff);
|
||||
packet[5] = val >> 8;
|
||||
packet[6] = val & 0xff;
|
||||
if(val > 0x100) calibrate = 0;
|
||||
// rudder
|
||||
val = convert_channel_16b_limit(RUDDER, 0, 0x3ff);
|
||||
packet[7] = val >> 8;
|
||||
packet[8] = val & 0xff;
|
||||
if(val > 0x100) calibrate = 0;
|
||||
// flags
|
||||
packet[1] |= GET_FLAG(E016H_STOP_SW, E016H_FLAG_STOP)
|
||||
| (can_flip ? GET_FLAG(E01X_FLIP_SW, E016H_FLAG_FLIP) : 0)
|
||||
| (calibrate ? E016H_FLAG_CALIBRATE : 0);
|
||||
packet[3] |= GET_FLAG(E01X_HEADLESS_SW, E016H_FLAG_HEADLESS)
|
||||
| GET_FLAG(E01X_RTH_SW, E016H_FLAG_RTH);
|
||||
packet[7] |= E016H_FLAG_HIGHRATE;
|
||||
// frequency hopping
|
||||
rf_ch_num=hopping_frequency[hopping_frequency_no++ & 0x03];
|
||||
}
|
||||
// checksum
|
||||
packet[9] = packet[0];
|
||||
for (uint8_t i=1; i < E016H_PACKET_SIZE-1; i++)
|
||||
packet[9] += packet[i];
|
||||
}
|
||||
|
||||
// Power on, TX mode, CRC enabled
|
||||
if(sub_protocol==E016H)
|
||||
XN297_Configure( _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
||||
else //E012 & E015
|
||||
HS6200_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
||||
HS6200_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, rf_ch_num);
|
||||
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||
NRF24L01_FlushTx();
|
||||
|
||||
if(sub_protocol==E016H)
|
||||
XN297_WritePayload(packet, packet_length);
|
||||
else
|
||||
HS6200_WritePayload(packet, packet_length);
|
||||
HS6200_WritePayload(packet, packet_length);
|
||||
|
||||
// Check and adjust transmission power. We do this after
|
||||
// transmission to not bother with timeout after power
|
||||
@@ -244,55 +169,31 @@ static void __attribute__((unused)) E01X_send_packet(uint8_t bind)
|
||||
NRF24L01_SetPower();
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) E01X_init()
|
||||
static void __attribute__((unused)) E01X_RF_init()
|
||||
{
|
||||
NRF24L01_Initialize();
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
|
||||
if(sub_protocol==E012)
|
||||
HS6200_SetTXAddr((uint8_t *)"\x55\x42\x9C\x8F\xC9", E01X_ADDRESS_LENGTH);
|
||||
else if(sub_protocol==E015)
|
||||
else //E015
|
||||
HS6200_SetTXAddr((uint8_t *)"\x62\x54\x79\x38\x53", E01X_ADDRESS_LENGTH);
|
||||
else //E016H
|
||||
XN297_SetTXAddr((uint8_t *)"\x5a\x53\x46\x30\x31", 5); // bind address
|
||||
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_03_SETUP_AW, 0x03);
|
||||
NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x00); // no retransmits
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1 Mbps
|
||||
NRF24L01_SetPower();
|
||||
NRF24L01_Activate(0x73); // Activate feature register
|
||||
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x00); // Disable dynamic payload length on all pipes
|
||||
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x01); // Set feature bits on
|
||||
NRF24L01_Activate(0x73);
|
||||
}
|
||||
|
||||
uint16_t E01X_callback()
|
||||
{
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(packet_period);
|
||||
#endif
|
||||
if(bind_counter)
|
||||
{
|
||||
bind_counter--;
|
||||
if (bind_counter == 0)
|
||||
{
|
||||
if(sub_protocol==E016H)
|
||||
XN297_SetTXAddr(rx_tx_addr, E01X_ADDRESS_LENGTH);
|
||||
else
|
||||
HS6200_SetTXAddr(rx_tx_addr, E01X_ADDRESS_LENGTH);
|
||||
HS6200_SetTXAddr(rx_tx_addr, E01X_ADDRESS_LENGTH);
|
||||
BIND_DONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
E01X_send_packet(1);
|
||||
bind_counter--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(packet_period);
|
||||
#endif
|
||||
E01X_send_packet(0);
|
||||
}
|
||||
E01X_send_packet();
|
||||
return packet_period;
|
||||
}
|
||||
|
||||
@@ -307,22 +208,7 @@ static void __attribute__((unused)) E012_initialize_txid()
|
||||
}
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) E016H_initialize_txid()
|
||||
{
|
||||
// tx id
|
||||
rx_tx_addr[0] = 0xa5;
|
||||
rx_tx_addr[1] = 0x00;
|
||||
|
||||
// rf channels
|
||||
uint32_t lfsr=random(0xfefefefe);
|
||||
for(uint8_t i=0; i<E016H_NUM_CHANNELS; i++)
|
||||
{
|
||||
hopping_frequency[i] = (lfsr & 0xFF) % 80;
|
||||
lfsr>>=8;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t initE01X()
|
||||
void E01X_init()
|
||||
{
|
||||
BIND_IN_PROGRESS;
|
||||
if(sub_protocol==E012)
|
||||
@@ -330,7 +216,7 @@ uint16_t initE01X()
|
||||
E012_initialize_txid();
|
||||
packet_period=E012_PACKET_PERIOD;
|
||||
}
|
||||
else if(sub_protocol==E015)
|
||||
else //E015
|
||||
{
|
||||
packet_period=E015_PACKET_PERIOD;
|
||||
rf_ch_num=E015_RF_CHANNEL;
|
||||
@@ -338,15 +224,9 @@ uint16_t initE01X()
|
||||
arm_flags = 0;
|
||||
arm_channel_previous = E01X_ARM_SW;
|
||||
}
|
||||
else
|
||||
{ // E016H
|
||||
E016H_initialize_txid();
|
||||
packet_period=E016H_PACKET_PERIOD;
|
||||
}
|
||||
E01X_init();
|
||||
E01X_RF_init();
|
||||
bind_counter = E01X_BIND_COUNT;
|
||||
hopping_frequency_no = 0;
|
||||
return E01X_INITIAL_WAIT;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -51,7 +51,7 @@ static void __attribute__((unused)) E129_build_data_packet()
|
||||
packet[ 6] = val; // channel (0x000...0x200...0x3FF)
|
||||
val = convert_channel_10b(ELEVATOR,false);
|
||||
trim = convert_channel_8b(CH8) & 0xFC;
|
||||
packet[ 7] = trim | (val >>8); // Trim (0x00..0x1F..0x3E) << 2 | channel >> 8
|
||||
packet[ 7] = trim | (val >>8); // Trim (0x00..0x1F..0x3E) << 2 | channel >> 8
|
||||
packet[ 8] = val; // channel (0x000...0x200...0x3FF)
|
||||
if(packet_count>200)
|
||||
val = convert_channel_10b(THROTTLE,false);
|
||||
@@ -74,7 +74,7 @@ static void __attribute__((unused)) E129_build_data_packet()
|
||||
RF2500_BuildPayload(packet);
|
||||
}
|
||||
|
||||
uint16_t ReadE129()
|
||||
uint16_t E129_callback()
|
||||
{
|
||||
//Set RF channel
|
||||
if(phase==0)
|
||||
@@ -92,14 +92,11 @@ uint16_t ReadE129()
|
||||
|
||||
//Bind
|
||||
if(bind_counter)
|
||||
{
|
||||
bind_counter--;
|
||||
if(bind_counter==0)
|
||||
if(--bind_counter==0)
|
||||
{
|
||||
BIND_DONE;
|
||||
RF2500_SetTXAddr(rx_tx_addr); // 4 bytes of address
|
||||
}
|
||||
}
|
||||
|
||||
//Build packet
|
||||
E129_build_data_packet();
|
||||
@@ -115,7 +112,7 @@ uint16_t ReadE129()
|
||||
return 5200-1260;
|
||||
}
|
||||
|
||||
uint16_t initE129()
|
||||
void E129_init()
|
||||
{
|
||||
BIND_IN_PROGRESS; // Autobind protocol
|
||||
bind_counter = 384; // ~2sec
|
||||
@@ -146,7 +143,6 @@ uint16_t initE129()
|
||||
hopping_frequency_no=0;
|
||||
packet_count=0;
|
||||
phase=0;
|
||||
return 1260;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#define ESKY150_BINDING_PACKET_PERIOD 2000
|
||||
#define ESKY150_SENDING_PACKET_PERIOD 4800
|
||||
|
||||
static void __attribute__((unused)) ESKY150_init()
|
||||
static void __attribute__((unused)) ESKY150_RF_init()
|
||||
{
|
||||
//Original TX always sets for channelx 0x22 and 0x4a
|
||||
// Use channels 2..79
|
||||
@@ -31,25 +31,16 @@ static void __attribute__((unused)) ESKY150_init()
|
||||
hopping_frequency[1] = hopping_frequency[0] + 40;
|
||||
|
||||
NRF24L01_Initialize();
|
||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, (_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO)));
|
||||
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknoledgement
|
||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0
|
||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x02); // 4-byte RX/TX address
|
||||
NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0); // Disable retransmit
|
||||
NRF24L01_SetPower();
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_2M);
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
|
||||
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, ESKY150_PAYLOADSIZE); // bytes of data payload for pipe 0
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, rx_tx_addr, ESKY150_TX_ADDRESS_SIZE);
|
||||
|
||||
NRF24L01_Activate(0x73);
|
||||
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 1); // Dynamic payload for data pipe 0
|
||||
// Enable: Dynamic Payload Length, Payload with ACK , W_TX_PAYLOAD_NOACK
|
||||
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, _BV(NRF2401_1D_EN_DPL) | _BV(NRF2401_1D_EN_ACK_PAY) | _BV(NRF2401_1D_EN_DYN_ACK));
|
||||
NRF24L01_Activate(0x73);
|
||||
NRF24L01_FlushTx();
|
||||
// Turn radio power on
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
|
||||
NRF24L01_SetTxRxMode(TX_EN); // Clear data ready, data sent, retransmit and enable CRC 16bits, ready for TX
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) ESKY150_bind_init()
|
||||
@@ -171,16 +162,15 @@ uint16_t ESKY150_callback()
|
||||
return ESKY150_SENDING_PACKET_PERIOD;
|
||||
}
|
||||
|
||||
uint16_t initESKY150(void)
|
||||
void ESKY150_init(void)
|
||||
{
|
||||
ESKY150_init();
|
||||
ESKY150_RF_init();
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
bind_counter=3000;
|
||||
ESKY150_bind_init();
|
||||
}
|
||||
hopping_frequency_no=0;
|
||||
return 10000;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
#if defined(ESKY150V2_CC2500_INO)
|
||||
|
||||
#include "iface_cc2500.h"
|
||||
#include "iface_nrf250k.h"
|
||||
|
||||
//#define ESKY150V2_FORCE_ID
|
||||
|
||||
@@ -74,7 +74,7 @@ static void __attribute__((unused)) ESKY150V2_send_packet()
|
||||
packet[4+2*i] = channel;
|
||||
packet[5+2*i] = channel>>8;
|
||||
}
|
||||
CC2500_250K_NRF_WritePayload(packet, ESKY150V2_PAYLOADSIZE);
|
||||
NRF250K_WritePayload(packet, ESKY150V2_PAYLOADSIZE);
|
||||
}
|
||||
|
||||
uint16_t ESKY150V2_callback()
|
||||
@@ -91,12 +91,12 @@ uint16_t ESKY150V2_callback()
|
||||
BIND_DONE; //Need full power for bind to work...
|
||||
CC2500_SetPower(); //Set power level
|
||||
BIND_IN_PROGRESS;
|
||||
CC2500_250K_NRF_WritePayload(packet, ESKY150V2_BINDPAYLOADSIZE);
|
||||
NRF250K_WritePayload(packet, ESKY150V2_BINDPAYLOADSIZE);
|
||||
if (--bind_counter == 0)
|
||||
{
|
||||
BIND_DONE;
|
||||
// Change TX address from bind to normal mode
|
||||
CC2500_250K_NRF_SetTXAddr(rx_tx_addr, ESKY150V2_TXID_SIZE);
|
||||
NRF250K_SetTXAddr(rx_tx_addr, ESKY150V2_TXID_SIZE);
|
||||
memset(packet,0x00,ESKY150V2_PAYLOADSIZE);
|
||||
}
|
||||
return 30000; //ESKY150V2_BINDING_PACKET_PERIOD;
|
||||
@@ -104,7 +104,7 @@ uint16_t ESKY150V2_callback()
|
||||
return ESKY150V2_PACKET_PERIOD;
|
||||
}
|
||||
|
||||
uint16_t initESKY150V2()
|
||||
void ESKY150V2_init()
|
||||
{
|
||||
CC2500_250K_Init();
|
||||
ESKY150V2_set_freq();
|
||||
@@ -118,7 +118,7 @@ uint16_t initESKY150V2()
|
||||
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
CC2500_250K_NRF_SetTXAddr((uint8_t *)"\x73\x73\x74\x63", ESKY150V2_TXID_SIZE); //Bind address
|
||||
NRF250K_SetTXAddr((uint8_t *)"\x73\x73\x74\x63", ESKY150V2_TXID_SIZE); //Bind address
|
||||
CC2500_250K_Hopping(ESKY150V2_NFREQCHANNELS); //Bind channel
|
||||
memcpy(packet,"\x73\x73\x74\x63", ESKY150V2_TXID_SIZE);
|
||||
memcpy(&packet[ESKY150V2_TXID_SIZE],rx_tx_addr, ESKY150V2_TXID_SIZE);
|
||||
@@ -132,8 +132,7 @@ uint16_t initESKY150V2()
|
||||
bind_counter=100;
|
||||
}
|
||||
else
|
||||
CC2500_250K_NRF_SetTXAddr(rx_tx_addr, ESKY150V2_TXID_SIZE);
|
||||
return 50000;
|
||||
NRF250K_SetTXAddr(rx_tx_addr, ESKY150V2_TXID_SIZE);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -35,14 +35,10 @@ static void __attribute__((unused)) ESKY_set_data_address()
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, rx_tx_addr, 4);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) ESKY_init()
|
||||
static void __attribute__((unused)) ESKY_RF_init()
|
||||
{
|
||||
NRF24L01_Initialize();
|
||||
|
||||
// 2-bytes CRC, radio off
|
||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO));
|
||||
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowledgement
|
||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0
|
||||
if (IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x01); // 3-byte RX/TX address for bind packets
|
||||
@@ -51,11 +47,7 @@ static void __attribute__((unused)) ESKY_init()
|
||||
}
|
||||
else
|
||||
ESKY_set_data_address();
|
||||
NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0); // No auto retransmission
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, 50); // Channel 50 for bind packets
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps
|
||||
NRF24L01_SetPower();
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
|
||||
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, ESKY_PAYLOAD_SIZE); // bytes of data payload for pipe 0
|
||||
NRF24L01_WriteReg(NRF24L01_12_RX_PW_P1, ESKY_PAYLOAD_SIZE);
|
||||
NRF24L01_WriteReg(NRF24L01_13_RX_PW_P2, ESKY_PAYLOAD_SIZE);
|
||||
@@ -65,7 +57,7 @@ static void __attribute__((unused)) ESKY_init()
|
||||
NRF24L01_WriteReg(NRF24L01_17_FIFO_STATUS, 0x00); // Just in case, no real bits to write here
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) ESKY_init2()
|
||||
static void __attribute__((unused)) ESKY_TXID_init()
|
||||
{
|
||||
NRF24L01_FlushTx();
|
||||
if(sub_protocol==ESKY_STD)
|
||||
@@ -187,7 +179,7 @@ uint16_t ESKY_callback()
|
||||
return ESKY_STD_PACKET_PERIOD;
|
||||
}
|
||||
|
||||
uint16_t initESKY(void)
|
||||
void ESKY_init(void)
|
||||
{
|
||||
bind_counter = ESKY_BIND_COUNT;
|
||||
rx_tx_addr[2] = rx_tx_addr[3]; // Model match
|
||||
@@ -200,10 +192,9 @@ uint16_t initESKY(void)
|
||||
}
|
||||
#endif
|
||||
rx_tx_addr[3] = 0xBB;
|
||||
ESKY_init();
|
||||
ESKY_init2();
|
||||
ESKY_RF_init();
|
||||
ESKY_TXID_init();
|
||||
packet_count=0;
|
||||
return 50000;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -81,11 +81,11 @@ static void __attribute__((unused)) ssv_pack_dpl(uint8_t addr[], uint8_t pid, ui
|
||||
*len += 4;
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) FQ777_send_packet(uint8_t bind)
|
||||
static void __attribute__((unused)) FQ777_send_packet()
|
||||
{
|
||||
uint8_t packet_len = FQ777_PACKET_SIZE;
|
||||
uint8_t packet_ori[8];
|
||||
if (bind)
|
||||
if (IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
// 4,5,6 = address fields
|
||||
// last field is checksum of address fields
|
||||
@@ -138,7 +138,7 @@ static void __attribute__((unused)) FQ777_send_packet(uint8_t bind)
|
||||
packet_count++;
|
||||
}
|
||||
|
||||
ssv_pack_dpl( (0 == bind) ? rx_tx_addr : FQ777_bind_addr, hopping_frequency_no, &packet_len, packet_ori, packet);
|
||||
ssv_pack_dpl( IS_BIND_IN_PROGRESS ? FQ777_bind_addr : rx_tx_addr, hopping_frequency_no, &packet_len, packet_ori, packet);
|
||||
|
||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG,_BV(NRF24L01_00_PWR_UP));
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no++]);
|
||||
@@ -150,30 +150,21 @@ static void __attribute__((unused)) FQ777_send_packet(uint8_t bind)
|
||||
NRF24L01_WritePayload(packet, packet_len);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) FQ777_init()
|
||||
static void __attribute__((unused)) FQ777_RF_init()
|
||||
{
|
||||
NRF24L01_Initialize();
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, FQ777_bind_addr, 5);
|
||||
NRF24L01_FlushTx();
|
||||
NRF24L01_FlushRx();
|
||||
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowledgement on all data pipes
|
||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x00);
|
||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03);
|
||||
NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x00); // no retransmits
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_250K);
|
||||
NRF24L01_SetPower();
|
||||
NRF24L01_Activate(0x73); // Activate feature register
|
||||
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x00); // Disable dynamic payload length on all pipes
|
||||
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x01);
|
||||
NRF24L01_Activate(0x73);
|
||||
}
|
||||
|
||||
uint16_t FQ777_callback()
|
||||
{
|
||||
if(bind_counter!=0)
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(FQ777_PACKET_PERIOD);
|
||||
#endif
|
||||
if(bind_counter)
|
||||
{
|
||||
FQ777_send_packet(1);
|
||||
bind_counter--;
|
||||
if (bind_counter == 0)
|
||||
{
|
||||
@@ -181,17 +172,11 @@ uint16_t FQ777_callback()
|
||||
BIND_DONE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(FQ777_PACKET_PERIOD);
|
||||
#endif
|
||||
FQ777_send_packet(0);
|
||||
}
|
||||
FQ777_send_packet();
|
||||
return FQ777_PACKET_PERIOD;
|
||||
}
|
||||
|
||||
uint16_t initFQ777(void)
|
||||
void FQ777_init(void)
|
||||
{
|
||||
BIND_IN_PROGRESS; // autobind protocol
|
||||
bind_counter = FQ777_BIND_COUNT;
|
||||
@@ -204,8 +189,7 @@ uint16_t initFQ777(void)
|
||||
rx_tx_addr[2] = 0x00;
|
||||
rx_tx_addr[3] = 0xe7;
|
||||
rx_tx_addr[4] = 0x67;
|
||||
FQ777_init();
|
||||
return FQ777_INITIAL_WAIT;
|
||||
FQ777_RF_init();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -16,7 +16,7 @@ Multiprotocol is distributed in the hope that it will be useful,
|
||||
|
||||
#if defined(FX816_NRF24L01_INO)
|
||||
|
||||
#include "iface_nrf24l01.h"
|
||||
#include "iface_xn297.h"
|
||||
|
||||
#define FX816_INITIAL_WAIT 500
|
||||
#define FX816_PACKET_PERIOD 10000
|
||||
@@ -27,7 +27,14 @@ Multiprotocol is distributed in the hope that it will be useful,
|
||||
|
||||
static void __attribute__((unused)) FX816_send_packet()
|
||||
{
|
||||
packet[0] = IS_BIND_IN_PROGRESS?0x55:0xAA;
|
||||
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);
|
||||
@@ -44,37 +51,18 @@ static void __attribute__((unused)) FX816_send_packet()
|
||||
val+=packet[i];
|
||||
packet[5]=val;
|
||||
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, IS_BIND_IN_PROGRESS ? FX816_RF_BIND_CHANNEL:hopping_frequency[hopping_frequency_no++]);
|
||||
hopping_frequency_no%=FX816_RF_NUM_CHANNELS;
|
||||
|
||||
// clear packet status bits and TX FIFO
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||
NRF24L01_FlushTx();
|
||||
// Send
|
||||
XN297_SetPower();
|
||||
XN297_SetTxRxMode(TX_EN);
|
||||
XN297_WritePayload(packet, FX816_PAYLOAD_SIZE);
|
||||
|
||||
// Power on, TX mode, 2byte CRC
|
||||
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
||||
|
||||
NRF24L01_SetPower(); // Set tx_power
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) FX816_init()
|
||||
static void __attribute__((unused)) FX816_RF_init()
|
||||
{
|
||||
NRF24L01_Initialize();
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M);
|
||||
XN297_SetTXAddr((uint8_t *)"\xcc\xcc\xcc\xcc\xcc", 5);
|
||||
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_WriteReg(NRF24L01_04_SETUP_RETR, 0x00); // No retransmits
|
||||
NRF24L01_SetPower();
|
||||
NRF24L01_Activate(0x73); // Activate feature register
|
||||
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x00); // Disable dynamic payload length on all pipes
|
||||
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x01);
|
||||
NRF24L01_Activate(0x73);
|
||||
//XN297_HoppingCalib(FX816_RF_NUM_CHANNELS);
|
||||
XN297_RFChannel(FX816_RF_BIND_CHANNEL);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) FX816_initialize_txid()
|
||||
@@ -93,21 +81,20 @@ uint16_t FX816_callback()
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(FX816_PACKET_PERIOD);
|
||||
#endif
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
if(bind_counter)
|
||||
if(--bind_counter==0)
|
||||
BIND_DONE;
|
||||
FX816_send_packet();
|
||||
return FX816_PACKET_PERIOD;
|
||||
}
|
||||
|
||||
uint16_t initFX816()
|
||||
void FX816_init()
|
||||
{
|
||||
BIND_IN_PROGRESS; // autobind protocol
|
||||
FX816_initialize_txid();
|
||||
FX816_init();
|
||||
FX816_RF_init();
|
||||
hopping_frequency_no = 0;
|
||||
bind_counter=FX816_BIND_COUNT;
|
||||
return FX816_INITIAL_WAIT;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -88,34 +88,25 @@ static void __attribute__((unused)) FY326_send_packet(uint8_t bind)
|
||||
NRF24L01_SetPower(); // Set tx_power
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) FY326_init()
|
||||
static void __attribute__((unused)) FY326_RF_init()
|
||||
{
|
||||
NRF24L01_Initialize();
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
|
||||
if(sub_protocol==FY319)
|
||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // Five-byte rx/tx address
|
||||
else
|
||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x01); // Three-byte rx/tx address
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, (uint8_t *)"\x15\x59\x23\xc6\x29", 5);
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, (uint8_t *)"\x15\x59\x23\xc6\x29", 5);
|
||||
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 Acknowledgement on all data pipes
|
||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 only
|
||||
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, FY326_PACKET_SIZE);
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, FY326_RF_BIND_CHANNEL);
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_250K);
|
||||
NRF24L01_SetPower();
|
||||
|
||||
NRF24L01_Activate(0x73);
|
||||
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x3f);
|
||||
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x07);
|
||||
NRF24L01_Activate(0x73);
|
||||
|
||||
//Switch to RX
|
||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||
NRF24L01_FlushRx();
|
||||
NRF24L01_SetTxRxMode(RX_EN);
|
||||
}
|
||||
|
||||
@@ -209,20 +200,19 @@ static void __attribute__((unused)) FY326_initialize_txid()
|
||||
hopping_frequency[i]=rx_tx_addr[0] & ~0x80;
|
||||
}
|
||||
|
||||
uint16_t initFY326(void)
|
||||
void FY326_init(void)
|
||||
{
|
||||
BIND_IN_PROGRESS; // autobind protocol
|
||||
rxid = 0xAA;
|
||||
bind_counter = FY326_BIND_COUNT;
|
||||
FY326_initialize_txid();
|
||||
FY326_init();
|
||||
FY326_RF_init();
|
||||
if(sub_protocol==FY319)
|
||||
{
|
||||
phase=FY319_BIND1;
|
||||
}
|
||||
else
|
||||
phase=FY326_BIND1;
|
||||
return FY326_INITIAL_WAIT;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
108
Multiprotocol/Fake_nrf24l01.ino
Normal file
108
Multiprotocol/Fake_nrf24l01.ino
Normal file
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
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(FAKE_NRF24L01_INO)
|
||||
|
||||
#include "iface_nrf250k.h"
|
||||
|
||||
static void __attribute__((unused)) FAKE_send_packet()
|
||||
{
|
||||
for(uint8_t i=0;i<5;i++)
|
||||
packet[i]=i;
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, (_BV(NRF24L01_07_RX_DR) | _BV(NRF24L01_07_TX_DS) | _BV(NRF24L01_07_MAX_RT)));
|
||||
NRF24L01_FlushTx();
|
||||
NRF24L01_WritePayload(packet, 5);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) FAKE_init()
|
||||
{
|
||||
// BIND_IN_PROGRESS;
|
||||
|
||||
//CC2500
|
||||
option=1;
|
||||
XN297L_Init();
|
||||
CC2500_WriteReg(CC2500_07_PKTCTRL1, 0x01); // Packet Automation Control
|
||||
CC2500_WriteReg(CC2500_08_PKTCTRL0, 0x00); // Packet Automation Control
|
||||
CC2500_WriteReg(CC2500_12_MDMCFG2, 0x12); // Modem Configuration
|
||||
CC2500_WriteReg(CC2500_13_MDMCFG1, 0x13); // Modem Configuration
|
||||
CC2500_WriteReg(CC2500_04_SYNC1, 0x11);
|
||||
CC2500_WriteReg(CC2500_05_SYNC0, 0x33);
|
||||
CC2500_WriteReg(CC2500_09_ADDR, 0x99);
|
||||
CC2500_WriteReg(CC2500_06_PKTLEN, 10);
|
||||
|
||||
CC2500_SetTxRxMode(RX_EN);
|
||||
CC2500_Strobe(CC2500_SIDLE);
|
||||
CC2500_Strobe(CC2500_SRX);
|
||||
//CC2500_SetTxRxMode(TX_EN);
|
||||
XN297L_RFChannel(0);
|
||||
|
||||
//NRF
|
||||
/* option=0;
|
||||
PE1_on; //NRF24L01 antenna RF3 by default
|
||||
PE2_off; //NRF24L01 antenna RF3 by default
|
||||
NRF24L01_Initialize();
|
||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, 0x7f);
|
||||
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00);//0x3f); // AA on all pipes
|
||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x3f); // Enable all pipes
|
||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5-byte address
|
||||
NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x36); // retransmit 1ms, 6 times
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_250K); // 1Mbps
|
||||
NRF24L01_SetPower();
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, (uint8_t *)"\x99\x33\x11\xAA\xAA", 5); //Bind address
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, (uint8_t *)"\x99\x33\x11\xAA\xAA", 5); //Bind address
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, 0);
|
||||
NRF24L01_Activate(0x73); // Activate feature register
|
||||
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x3f); // Enable dynamic payload length
|
||||
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x07); // Enable all features
|
||||
*/
|
||||
/*NRF24L01_FlushTx();
|
||||
NRF24L01_SetTxRxMode(TX_EN);*/
|
||||
}
|
||||
|
||||
uint16_t FAKE_callback()
|
||||
{
|
||||
len = CC2500_ReadReg(CC2500_3B_RXBYTES | CC2500_READ_BURST) & 0x7F;
|
||||
if(len) debug("L=%d, ",len);
|
||||
if(len && len < sizeof(packet_in))
|
||||
{
|
||||
CC2500_ReadData(packet_in, len);
|
||||
debug("P:");
|
||||
for(uint8_t i=0;i<len;i++)
|
||||
debug(" %02X", packet_in[i]);
|
||||
}
|
||||
if(len) debugln("");
|
||||
CC2500_Strobe(CC2500_SFRX);
|
||||
CC2500_Strobe(CC2500_SIDLE);
|
||||
CC2500_Strobe(CC2500_SRX);
|
||||
|
||||
option=0;
|
||||
//FAKE_send_packet();
|
||||
|
||||
PE1_off; //antenna RF2
|
||||
PE2_on;
|
||||
/*packet[0]=0x99;
|
||||
for(uint8_t i=1;i<5;i++)
|
||||
packet[i]=i;
|
||||
CC2500_WriteData(packet, 5);*/
|
||||
return 10000;
|
||||
}
|
||||
|
||||
uint16_t initFAKE()
|
||||
{
|
||||
FAKE_init();
|
||||
return 5000;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -12,7 +12,7 @@
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
// Last sync with hexfet new_protocols/flysky_a7105.c dated 2015-09-28
|
||||
// Last sync with hexfet new_protocols/FLYSKY_a7105.c dated 2015-09-28
|
||||
|
||||
#if defined(FLYSKY_A7105_INO)
|
||||
|
||||
@@ -53,7 +53,7 @@ enum {
|
||||
const uint8_t PROGMEM V912_X17_SEQ[10] = { 0x14, 0x31, 0x40, 0x49, 0x49, // sometime first byte is 0x15 ?
|
||||
0x49, 0x49, 0x49, 0x49, 0x49, };
|
||||
|
||||
static void __attribute__((unused)) flysky_apply_extension_flags()
|
||||
static void __attribute__((unused)) FLYSKY_apply_extension_flags()
|
||||
{
|
||||
switch(sub_protocol)
|
||||
{
|
||||
@@ -129,7 +129,7 @@ static void __attribute__((unused)) flysky_apply_extension_flags()
|
||||
}
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) flysky_build_packet(uint8_t init)
|
||||
static void __attribute__((unused)) FLYSKY_send_packet()
|
||||
{
|
||||
uint8_t i;
|
||||
//servodata timing range for flysky.
|
||||
@@ -137,7 +137,7 @@ static void __attribute__((unused)) flysky_build_packet(uint8_t init)
|
||||
//+100% =~ 0x07ca//=1994us(max)
|
||||
//Center = 0x5d9//=1497us(center)
|
||||
//channel order AIL;ELE;THR;RUD;CH5;CH6;CH7;CH8
|
||||
packet[0] = init ? 0xaa : 0x55;
|
||||
packet[0] = IS_BIND_IN_PROGRESS ? 0xaa : 0x55;
|
||||
packet[1] = rx_tx_addr[3];
|
||||
packet[2] = rx_tx_addr[2];
|
||||
packet[3] = rx_tx_addr[1];
|
||||
@@ -150,36 +150,32 @@ static void __attribute__((unused)) flysky_build_packet(uint8_t init)
|
||||
packet[5 + i*2]=temp&0xFF; //low byte of servo timing(1000-2000us)
|
||||
packet[6 + i*2]=(temp>>8)&0xFF; //high byte of servo timing(1000-2000us)
|
||||
}
|
||||
flysky_apply_extension_flags();
|
||||
FLYSKY_apply_extension_flags();
|
||||
|
||||
A7105_SetPower();
|
||||
A7105_WriteData(21, IS_BIND_IN_PROGRESS ? 0x01:hopping_frequency[hopping_frequency_no & 0x0F]);
|
||||
hopping_frequency_no++;
|
||||
}
|
||||
|
||||
uint16_t ReadFlySky()
|
||||
uint16_t FLYSKY_callback()
|
||||
{
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(packet_period);
|
||||
#endif
|
||||
#ifndef FORCE_FLYSKY_TUNING
|
||||
A7105_AdjustLOBaseFreq(1);
|
||||
#endif
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
if(bind_counter)
|
||||
{
|
||||
flysky_build_packet(1);
|
||||
A7105_WriteData(21, 1);
|
||||
bind_counter--;
|
||||
if (bind_counter==0)
|
||||
BIND_DONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(packet_period);
|
||||
#endif
|
||||
flysky_build_packet(0);
|
||||
A7105_WriteData(21, hopping_frequency[hopping_frequency_no & 0x0F]);
|
||||
A7105_SetPower();
|
||||
}
|
||||
hopping_frequency_no++;
|
||||
FLYSKY_send_packet();
|
||||
return packet_period;
|
||||
}
|
||||
|
||||
const uint8_t PROGMEM tx_channels[8][4] = {
|
||||
const uint8_t PROGMEM FLYSKY_tx_channels[8][4] = {
|
||||
{ 0x12, 0x34, 0x56, 0x78},
|
||||
{ 0x18, 0x27, 0x36, 0x45},
|
||||
{ 0x41, 0x82, 0x36, 0x57},
|
||||
@@ -190,7 +186,7 @@ const uint8_t PROGMEM tx_channels[8][4] = {
|
||||
{ 0x71, 0x86, 0x43, 0x52}
|
||||
};
|
||||
|
||||
uint16_t initFlySky()
|
||||
void FLYSKY_init()
|
||||
{
|
||||
uint8_t chanrow;
|
||||
uint8_t chanoffset;
|
||||
@@ -208,7 +204,7 @@ uint16_t initFlySky()
|
||||
chanoffset=rx_tx_addr[3]/16;
|
||||
for(uint8_t i=0;i<16;i++)
|
||||
{
|
||||
temp=pgm_read_byte_near(&tx_channels[chanrow>>1][i>>2]);
|
||||
temp=pgm_read_byte_near(&FLYSKY_tx_channels[chanrow>>1][i>>2]);
|
||||
if(i&0x02)
|
||||
temp&=0x0F;
|
||||
else
|
||||
@@ -242,6 +238,5 @@ uint16_t initFlySky()
|
||||
bind_counter = FLYSKY_BIND_COUNT;
|
||||
else
|
||||
bind_counter = 0;
|
||||
return 2400;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -508,7 +508,7 @@ static void __attribute__((unused)) FrSkyX_set_start(uint8_t ch )
|
||||
CC2500_WriteReg(CC2500_0A_CHANNR, hopping_frequency[ch]);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) FrSkyX_init()
|
||||
static void __attribute__((unused)) FrSkyX_RF_init()
|
||||
{
|
||||
if(protocol==PROTO_FRSKYL)
|
||||
FRSKY_init_cc2500(FRSKYL_cc2500_conf);
|
||||
|
||||
@@ -17,12 +17,12 @@
|
||||
|
||||
#include "iface_cc2500.h"
|
||||
|
||||
static void __attribute__((unused)) frsky2way_init(uint8_t bind)
|
||||
static void __attribute__((unused)) FRSKYD_RF_init()
|
||||
{
|
||||
FRSKY_init_cc2500(FRSKYD_cc2500_conf);
|
||||
|
||||
CC2500_WriteReg(CC2500_1B_AGCCTRL2, bind ? 0x43 : 0x03);
|
||||
CC2500_WriteReg(CC2500_09_ADDR, bind ? 0x03 : rx_tx_addr[3]);
|
||||
CC2500_WriteReg(CC2500_1B_AGCCTRL2, IS_BIND_IN_PROGRESS ? 0x43 : 0x03);
|
||||
CC2500_WriteReg(CC2500_09_ADDR, IS_BIND_IN_PROGRESS ? 0x03 : rx_tx_addr[3]);
|
||||
CC2500_WriteReg(CC2500_07_PKTCTRL1, 0x05);
|
||||
CC2500_Strobe(CC2500_SIDLE); // Go to idle...
|
||||
//
|
||||
@@ -32,7 +32,7 @@ static void __attribute__((unused)) frsky2way_init(uint8_t bind)
|
||||
//#######END INIT########
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) frsky2way_build_bind_packet()
|
||||
static void __attribute__((unused)) FRSKYD_build_bind_packet()
|
||||
{
|
||||
//11 03 01 d7 2d 00 00 1e 3c 5b 78 00 00 00 00 00 00 01
|
||||
//11 03 01 19 3e 00 02 8e 2f bb 5c 00 00 00 00 00 00 01
|
||||
@@ -57,7 +57,7 @@ static void __attribute__((unused)) frsky2way_build_bind_packet()
|
||||
packet[17] = rx_tx_addr[1];
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) frsky2way_data_frame()
|
||||
static void __attribute__((unused)) FRSKYD_data_frame()
|
||||
{//pachet[4] is telemetry user frame counter(hub)
|
||||
//11 d7 2d 22 00 01 c9 c9 ca ca 88 88 ca ca c9 ca 88 88
|
||||
//11 57 12 00 00 01 f2 f2 f2 f2 06 06 ca ca ca ca 18 18
|
||||
@@ -94,7 +94,7 @@ static void __attribute__((unused)) frsky2way_data_frame()
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t initFrSky_2way()
|
||||
void FRSKYD_init(void)
|
||||
{
|
||||
//FrskyD init hop
|
||||
if (sub_protocol==DCLONE)
|
||||
@@ -116,21 +116,20 @@ uint16_t initFrSky_2way()
|
||||
packet_count=0;
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
frsky2way_init(1);
|
||||
FRSKYD_RF_init();
|
||||
state = FRSKY_BIND;
|
||||
}
|
||||
else
|
||||
{
|
||||
state = FRSKY_BIND_DONE;
|
||||
}
|
||||
return 10000;
|
||||
}
|
||||
|
||||
uint16_t ReadFrSky_2way()
|
||||
uint16_t FRSKYD_callback(void)
|
||||
{
|
||||
if (state < FRSKY_BIND_DONE)
|
||||
{
|
||||
frsky2way_build_bind_packet();
|
||||
FRSKYD_build_bind_packet();
|
||||
CC2500_Strobe(CC2500_SIDLE);
|
||||
CC2500_WriteReg(CC2500_0A_CHANNR, 0x00);
|
||||
CC2500_WriteReg(CC2500_23_FSCAL3, 0x89);
|
||||
@@ -144,10 +143,10 @@ uint16_t ReadFrSky_2way()
|
||||
}
|
||||
if (state == FRSKY_BIND_DONE)
|
||||
{
|
||||
state = FRSKY_DATA2;
|
||||
frsky2way_init(0);
|
||||
counter = 0;
|
||||
BIND_DONE;
|
||||
FRSKYD_RF_init();
|
||||
counter = 0;
|
||||
state = FRSKY_DATA2;
|
||||
}
|
||||
else
|
||||
if (state == FRSKY_DATA5)
|
||||
@@ -206,7 +205,7 @@ uint16_t ReadFrSky_2way()
|
||||
CC2500_SetFreqOffset();
|
||||
CC2500_WriteReg(CC2500_23_FSCAL3, 0x89);
|
||||
CC2500_Strobe(CC2500_SFRX);
|
||||
frsky2way_data_frame();
|
||||
FRSKYD_data_frame();
|
||||
CC2500_WriteData(packet, packet[0]+1);
|
||||
state++;
|
||||
}
|
||||
|
||||
@@ -137,7 +137,7 @@ static void __attribute__((unused)) FrSkyL_encode_packet(bool type)
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t ReadFrSkyL()
|
||||
uint16_t FRSKYL_callback()
|
||||
{
|
||||
static uint8_t written=0, send=0;
|
||||
switch(send)
|
||||
@@ -212,7 +212,7 @@ uint16_t ReadFrSkyL()
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint16_t initFrSkyL()
|
||||
void FRSKYL_init()
|
||||
{
|
||||
set_rx_tx_addr(MProtocol_id_master);
|
||||
rx_tx_addr[1]=0x02; // ID related, hw version?
|
||||
@@ -227,7 +227,7 @@ uint16_t initFrSkyL()
|
||||
while(!FrSkyX_chanskip)
|
||||
FrSkyX_chanskip=random(0xfefefefe)%47;
|
||||
|
||||
FrSkyX_init();
|
||||
FrSkyX_RF_init();
|
||||
|
||||
//Prepare frame
|
||||
memset(FrSkyL_buffer,0x00,FRSKYL_PACKET_LEN-3);
|
||||
@@ -253,6 +253,5 @@ uint16_t initFrSkyL()
|
||||
state = FRSKY_DATA1;
|
||||
FrSkyX_initialize_data(0);
|
||||
}
|
||||
return 10000;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -157,7 +157,7 @@ static void __attribute__((unused)) FrSkyR9_build_EU_packet()
|
||||
packet[13] = FrSkyR9_CRC8(packet, 13);
|
||||
}
|
||||
|
||||
uint16_t initFrSkyR9()
|
||||
void FRSKYR9_init()
|
||||
{
|
||||
//Check frequencies
|
||||
#ifdef DISP_FREQ_TABLE
|
||||
@@ -205,7 +205,14 @@ uint16_t initFrSkyR9()
|
||||
SX1276_SetDetectionThreshold(SX1276_MODEM_DETECTION_THRESHOLD_SF6);
|
||||
SX1276_SetLna(1, true);
|
||||
SX1276_SetHopPeriod(0); // 0 = disabled, we hop frequencies manually
|
||||
SX1276_SetPaDac(true);
|
||||
//RF Power
|
||||
SX1276_SetPaDac(false); // Disable 20dBm mode
|
||||
#if MULTI_5IN1_INTERNAL == JP_T18
|
||||
SX1276_SetPaConfig(true, 7, 0); // Lowest power for the T18: 2dBm
|
||||
#else
|
||||
SX1276_SetPaConfig(true, 7, option); // Use PA_HP on PA_BOOST, power=17-(15-option) dBm with option equal or lower to 15
|
||||
#endif
|
||||
SX1276_SetOcp(true,27); // Set OCP to max 240mA
|
||||
SX1276_SetTxRxMode(TX_EN); // Set RF switch to TX
|
||||
//Enable all IRQ flags
|
||||
SX1276_WriteReg(SX1276_11_IRQFLAGSMASK,0x00);
|
||||
@@ -213,10 +220,9 @@ uint16_t initFrSkyR9()
|
||||
|
||||
hopping_frequency_no=0;
|
||||
phase=FRSKYR9_FREQ;
|
||||
return 20000; // Start calling FrSkyR9_callback in 20 milliseconds
|
||||
}
|
||||
|
||||
uint16_t FrSkyR9_callback()
|
||||
uint16_t FRSKYR9_callback()
|
||||
{
|
||||
switch (phase)
|
||||
{
|
||||
@@ -227,8 +233,14 @@ uint16_t FrSkyR9_callback()
|
||||
FrSkyR9_set_frequency(); // Set current center frequency
|
||||
//Set power
|
||||
// max power: 15dBm (10.8 + 0.6 * MaxPower [dBm])
|
||||
// output_power: 2 dBm (17-(15-OutputPower) (if pa_boost_pin == true))
|
||||
SX1276_SetPaConfig(true, 7, 0); // Lowest power for the T18
|
||||
// output_power: 2 dBm ( (if pa_boost_pin == true))
|
||||
#if MULTI_5IN1_INTERNAL != JP_T18
|
||||
if(option != prev_option)
|
||||
{ // Set RF power if it has changed
|
||||
SX1276_SetPaConfig(true, 7, option); // Use PA_HP on PA_BOOST, power=17-(15-option) dBm with option equal or lower to 15
|
||||
prev_option = option;
|
||||
}
|
||||
#endif
|
||||
//Build packet
|
||||
if( packet_length == 26 )
|
||||
FrSkyR9_build_packet();
|
||||
|
||||
@@ -113,7 +113,7 @@ static void __attribute__((unused)) FRSKYV_build_data_packet()
|
||||
packet[14] = FRSKYV_crc8(crc8, packet, 14);
|
||||
}
|
||||
|
||||
uint16_t ReadFRSKYV()
|
||||
uint16_t FRSKYV_callback(void)
|
||||
{
|
||||
if(IS_BIND_DONE)
|
||||
{ // Normal operation
|
||||
@@ -148,7 +148,7 @@ uint16_t ReadFRSKYV()
|
||||
return 53460;
|
||||
}
|
||||
|
||||
uint16_t initFRSKYV()
|
||||
void FRSKYV_init(void)
|
||||
{
|
||||
//ID is 15 bits. Using rx_tx_addr[2] and rx_tx_addr[3] since we want to use RX_Num for model match
|
||||
rx_tx_addr[2]&=0x7F;
|
||||
@@ -158,7 +158,6 @@ uint16_t initFRSKYV()
|
||||
seed = 1;
|
||||
binding_idx=0;
|
||||
phase = FRSKYV_DATA1;
|
||||
return 10000;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -19,17 +19,14 @@
|
||||
|
||||
static void __attribute__((unused)) FrSkyX_build_bind_packet()
|
||||
{
|
||||
uint8_t packet_size = 0x1D;
|
||||
if(protocol==PROTO_FRSKYX && (FrSkyFormat & 2 ))
|
||||
packet_size=0x20; // FrSkyX V1 LBT
|
||||
//Header
|
||||
packet[0] = packet_size; // Number of bytes in the packet (after this one)
|
||||
packet[1] = 0x03; // Bind packet
|
||||
packet[2] = 0x01; // Bind packet
|
||||
packet[0] = packet_length; // Number of bytes in the packet (after this one)
|
||||
packet[1] = 0x03; // Bind packet
|
||||
packet[2] = 0x01; // Bind packet
|
||||
|
||||
//ID
|
||||
packet[3] = rx_tx_addr[3]; // ID
|
||||
packet[4] = rx_tx_addr[2]; // ID
|
||||
packet[3] = rx_tx_addr[3]; // ID
|
||||
packet[4] = rx_tx_addr[2]; // ID
|
||||
|
||||
if(protocol==PROTO_FRSKYX)
|
||||
{
|
||||
@@ -40,10 +37,10 @@ static void __attribute__((unused)) FrSkyX_build_bind_packet()
|
||||
packet[8] = hopping_frequency[idx++];
|
||||
packet[9] = hopping_frequency[idx++];
|
||||
packet[10] = hopping_frequency[idx++];
|
||||
packet[11] = rx_tx_addr[1]; // Unknown but constant ID?
|
||||
packet[11] = rx_tx_addr[1]; // ID
|
||||
packet[12] = RX_num;
|
||||
//
|
||||
memset(&packet[13], 0, packet_size - 14);
|
||||
memset(&packet[13], 0, packet_length - 14);
|
||||
if(binding_idx&0x01)
|
||||
memcpy(&packet[13],(void *)"\x55\xAA\x5A\xA5",4); // Telem off
|
||||
if(binding_idx&0x02)
|
||||
@@ -52,30 +49,34 @@ static void __attribute__((unused)) FrSkyX_build_bind_packet()
|
||||
else
|
||||
{
|
||||
//packet 1D 03 01 0E 1C 02 00 00 32 0B 00 00 A8 26 28 01 A1 00 00 00 3E F6 87 C7 00 00 00 00 C9 C9
|
||||
packet[5] = rx_tx_addr[1]; // Unknown but constant ID?
|
||||
//Unknown bytes
|
||||
if(state & 0x01)
|
||||
memcpy(&packet[7],"\x00\x18\x0A\x00\x00\xE0\x02\x0B\x01\xD3\x08\x00\x00\x4C\xFE\x87\xC7",17);
|
||||
else
|
||||
memcpy(&packet[7],"\x27\xAD\x02\x00\x00\x64\xC8\x46\x00\x64\x00\x00\x00\xFB\xF6\x87\xC7",17);
|
||||
//ID
|
||||
packet[5] = rx_tx_addr[1]; // ID
|
||||
packet[6] = RX_num;
|
||||
//Bind flags
|
||||
packet[7]=0;
|
||||
if(binding_idx&0x01)
|
||||
packet[7] |= 0x40; // Telem off
|
||||
if(binding_idx&0x02)
|
||||
packet[7] |= 0x80; // CH9-16
|
||||
//Unknown bytes
|
||||
memcpy(&packet[8],"\x32\x0B\x00\x00\xA8\x26\x28\x01\xA1\x00\x00\x00\x3E\xF6\x87\xC7",16);
|
||||
packet[20]^= 0x0E ^ rx_tx_addr[3]; // Update the ID
|
||||
packet[21]^= 0x1C ^ rx_tx_addr[2]; // Update the ID
|
||||
//Replace the ID
|
||||
packet[20] ^= 0x0E ^ rx_tx_addr[3]; // Update the ID
|
||||
packet[21] ^= 0x1C ^ rx_tx_addr[2]; // Update the ID
|
||||
//Xor
|
||||
for(uint8_t i=3; i<packet_size-1; i++)
|
||||
for(uint8_t i=3; i<packet_length-1; i++)
|
||||
packet[i] ^= 0xA7;
|
||||
}
|
||||
//CRC
|
||||
uint16_t lcrc = FrSkyX_crc(&packet[3], packet_size-4);
|
||||
packet[packet_size-1] = lcrc >> 8;
|
||||
packet[packet_size] = lcrc;
|
||||
uint16_t lcrc = FrSkyX_crc(&packet[3], packet_length-4);
|
||||
packet[packet_length-1] = lcrc >> 8;
|
||||
packet[packet_length] = lcrc;
|
||||
|
||||
/*//Debug
|
||||
debug("Bind:");
|
||||
for(uint8_t i=0;i<=packet_size;i++)
|
||||
for(uint8_t i=0;i<=packet_length;i++)
|
||||
debug(" %02X",packet[i]);
|
||||
debugln("");*/
|
||||
}
|
||||
@@ -85,11 +86,8 @@ static void __attribute__((unused)) FrSkyX_build_packet()
|
||||
//0x1D 0xB3 0xFD 0x02 0x56 0x07 0x15 0x00 0x00 0x00 0x04 0x40 0x00 0x04 0x40 0x00 0x04 0x40 0x00 0x04 0x40 0x08 0x00 0x00 0x00 0x00 0x00 0x00 0x96 0x12
|
||||
// data frames sent every 9ms; failsafe every 9 seconds
|
||||
//
|
||||
uint8_t packet_size = 0x1D;
|
||||
if(protocol==PROTO_FRSKYX && (FrSkyFormat & 2 ))
|
||||
packet_size=0x20; // FrSkyX V1 LBT
|
||||
//Header
|
||||
packet[0] = packet_size; // Number of bytes in the packet (after this one)
|
||||
packet[0] = packet_length; // Number of bytes in the packet (after this one)
|
||||
packet[1] = rx_tx_addr[3]; // ID
|
||||
packet[2] = rx_tx_addr[2]; // ID
|
||||
packet[3] = rx_tx_addr[1]; // Unknown but constant ID?
|
||||
@@ -102,21 +100,21 @@ static void __attribute__((unused)) FrSkyX_build_packet()
|
||||
FrSkyX_channels(7); // Set packet[7]=failsafe, packet[8]=0?? and packet[9..20]=channels data
|
||||
|
||||
//Sequence and send SPort
|
||||
FrSkyX_seq_sport(21,packet_size-2); //21=RX|TXseq, 22=bytes count, 23..packet_size-2=data
|
||||
FrSkyX_seq_sport(21,packet_length-2); //21=RX|TXseq, 22=bytes count, 23..packet_length-2=data
|
||||
|
||||
//CRC
|
||||
uint16_t lcrc = FrSkyX_crc(&packet[3], packet_size-4);
|
||||
packet[packet_size-1] = lcrc >> 8;
|
||||
packet[packet_size] = lcrc;
|
||||
uint16_t lcrc = FrSkyX_crc(&packet[3], packet_length-4);
|
||||
packet[packet_length-1] = lcrc >> 8;
|
||||
packet[packet_length] = lcrc;
|
||||
|
||||
/*//Debug
|
||||
debug("Norm:");
|
||||
for(uint8_t i=0;i<=packet_size;i++)
|
||||
for(uint8_t i=0;i<=packet_length;i++)
|
||||
debug(" %02X",packet[i]);
|
||||
debugln("");*/
|
||||
}
|
||||
|
||||
uint16_t ReadFrSkyX()
|
||||
uint16_t FRSKYX_callback()
|
||||
{
|
||||
switch(state)
|
||||
{
|
||||
@@ -132,7 +130,7 @@ uint16_t ReadFrSkyX()
|
||||
state = FRSKY_BIND_DONE;
|
||||
else
|
||||
state++;
|
||||
return 9000;
|
||||
break;
|
||||
case FRSKY_BIND_DONE:
|
||||
FrSkyX_initialize_data(0);
|
||||
hopping_frequency_no=0;
|
||||
@@ -238,49 +236,51 @@ uint16_t ReadFrSkyX()
|
||||
state = FRSKY_DATA1;
|
||||
return 400; // FCC & LBT
|
||||
}
|
||||
return 1;
|
||||
return 9000;
|
||||
}
|
||||
|
||||
uint16_t initFrSkyX()
|
||||
void FRSKYX_init()
|
||||
{
|
||||
set_rx_tx_addr(MProtocol_id_master);
|
||||
FrSkyFormat = sub_protocol;
|
||||
|
||||
if (sub_protocol==XCLONE_16||sub_protocol==XCLONE_8)
|
||||
Frsky_init_clone();
|
||||
else if(protocol==PROTO_FRSKYX)
|
||||
{
|
||||
Frsky_init_hop();
|
||||
rx_tx_addr[1]=0x02; // ID related, hw version?
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef FRSKYX2_FORCE_ID
|
||||
rx_tx_addr[3]=0x0E;
|
||||
rx_tx_addr[2]=0x1C;
|
||||
FrSkyX_chanskip=18;
|
||||
#endif
|
||||
if(protocol==PROTO_FRSKYX)
|
||||
Frsky_init_hop();
|
||||
else
|
||||
{
|
||||
#ifdef FRSKYX2_FORCE_ID
|
||||
rx_tx_addr[3]=0x0E;
|
||||
rx_tx_addr[2]=0x1C;
|
||||
FrSkyX_chanskip=18;
|
||||
#endif
|
||||
FrSkyX2_init_hop();
|
||||
}
|
||||
rx_tx_addr[1]=0x02; // ID related, hw version?
|
||||
FrSkyX2_init_hop();
|
||||
}
|
||||
|
||||
if(protocol==PROTO_FRSKYX && (FrSkyFormat & 2 ))
|
||||
packet_length = 0x20; // FrSkyX V1 LBT
|
||||
else
|
||||
packet_length = 0x1D;
|
||||
|
||||
packet_count=0;
|
||||
while(!FrSkyX_chanskip)
|
||||
FrSkyX_chanskip=random(0xfefefefe)%47;
|
||||
|
||||
FrSkyX_init();
|
||||
FrSkyX_RF_init();
|
||||
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
memset(packet, 0, packet_length);
|
||||
state = FRSKY_BIND;
|
||||
FrSkyX_initialize_data(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
state = FRSKY_DATA1;
|
||||
FrSkyX_initialize_data(0);
|
||||
}
|
||||
state = FRSKY_BIND_DONE;
|
||||
FrSkyX_telem_init();
|
||||
return 10000;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -40,7 +40,7 @@ enum {
|
||||
FRSKY_RX_DATA,
|
||||
};
|
||||
|
||||
const PROGMEM uint8_t frsky_rx_common_reg[][2] = {
|
||||
const PROGMEM uint8_t FRSKY_RX_common_reg[][2] = {
|
||||
{CC2500_02_IOCFG0, 0x01},
|
||||
{CC2500_18_MCSM0, 0x18},
|
||||
{CC2500_07_PKTCTRL1, 0x05},
|
||||
@@ -68,7 +68,7 @@ const PROGMEM uint8_t frsky_rx_common_reg[][2] = {
|
||||
{CC2500_09_ADDR, 0x03},
|
||||
};
|
||||
|
||||
const PROGMEM uint8_t frsky_rx_d16fcc_reg[][2] = {
|
||||
const PROGMEM uint8_t FRSKY_RX_d16fcc_reg[][2] = {
|
||||
{CC2500_17_MCSM1, 0x0C},
|
||||
{CC2500_0E_FREQ1, 0x76},
|
||||
{CC2500_0F_FREQ0, 0x27},
|
||||
@@ -81,7 +81,7 @@ const PROGMEM uint8_t frsky_rx_d16fcc_reg[][2] = {
|
||||
{CC2500_15_DEVIATN, 0x51},
|
||||
};
|
||||
|
||||
const PROGMEM uint8_t frsky_rx_d16lbt_reg[][2] = {
|
||||
const PROGMEM uint8_t FRSKY_RX_d16lbt_reg[][2] = {
|
||||
{CC2500_17_MCSM1, 0x0E},
|
||||
{CC2500_0E_FREQ1, 0x80},
|
||||
{CC2500_0F_FREQ0, 0x00},
|
||||
@@ -94,7 +94,7 @@ const PROGMEM uint8_t frsky_rx_d16lbt_reg[][2] = {
|
||||
{CC2500_15_DEVIATN, 0x53},
|
||||
};
|
||||
|
||||
const PROGMEM uint8_t frsky_rx_d8_reg[][2] = {
|
||||
const PROGMEM uint8_t FRSKY_RX_d8_reg[][2] = {
|
||||
{CC2500_17_MCSM1, 0x0C},
|
||||
{CC2500_0E_FREQ1, 0x76},
|
||||
{CC2500_0F_FREQ0, 0x27},
|
||||
@@ -107,32 +107,32 @@ const PROGMEM uint8_t frsky_rx_d8_reg[][2] = {
|
||||
{CC2500_15_DEVIATN, 0x42},
|
||||
};
|
||||
|
||||
static uint8_t frsky_rx_chanskip;
|
||||
static int8_t frsky_rx_finetune;
|
||||
static uint8_t frsky_rx_format;
|
||||
static uint8_t FRSKY_RX_chanskip;
|
||||
static int8_t FRSKY_RX_finetune;
|
||||
static uint8_t FRSKY_RX_format;
|
||||
|
||||
static void __attribute__((unused)) frsky_rx_strobe_rx()
|
||||
static void __attribute__((unused)) FRSKY_RX_strobe_rx()
|
||||
{
|
||||
CC2500_Strobe(CC2500_SIDLE);
|
||||
CC2500_Strobe(CC2500_SFRX);
|
||||
CC2500_Strobe(CC2500_SRX);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) frsky_rx_initialise_cc2500() {
|
||||
const uint8_t frsky_rx_length[] = { FRSKY_RX_D8_LENGTH, FRSKY_RX_D16FCC_LENGTH, FRSKY_RX_D16LBT_LENGTH, FRSKY_RX_D16v2_LENGTH, FRSKY_RX_D16v2_LENGTH };
|
||||
packet_length = frsky_rx_length[frsky_rx_format];
|
||||
static void __attribute__((unused)) FRSKY_RX_initialise_cc2500() {
|
||||
const uint8_t FRSKY_RX_length[] = { FRSKY_RX_D8_LENGTH, FRSKY_RX_D16FCC_LENGTH, FRSKY_RX_D16LBT_LENGTH, FRSKY_RX_D16v2_LENGTH, FRSKY_RX_D16v2_LENGTH };
|
||||
packet_length = FRSKY_RX_length[FRSKY_RX_format];
|
||||
CC2500_Reset();
|
||||
CC2500_Strobe(CC2500_SIDLE);
|
||||
for (uint8_t i = 0; i < sizeof(frsky_rx_common_reg) / 2; i++)
|
||||
CC2500_WriteReg(pgm_read_byte_near(&frsky_rx_common_reg[i][0]), pgm_read_byte_near(&frsky_rx_common_reg[i][1]));
|
||||
for (uint8_t i = 0; i < sizeof(FRSKY_RX_common_reg) / 2; i++)
|
||||
CC2500_WriteReg(pgm_read_byte_near(&FRSKY_RX_common_reg[i][0]), pgm_read_byte_near(&FRSKY_RX_common_reg[i][1]));
|
||||
|
||||
switch (frsky_rx_format)
|
||||
switch (FRSKY_RX_format)
|
||||
{
|
||||
case FRSKY_RX_D16v2FCC:
|
||||
case FRSKY_RX_D16FCC:
|
||||
for (uint8_t i = 0; i < sizeof(frsky_rx_d16fcc_reg) / 2; i++)
|
||||
CC2500_WriteReg(pgm_read_byte_near(&frsky_rx_d16fcc_reg[i][0]), pgm_read_byte_near(&frsky_rx_d16fcc_reg[i][1]));
|
||||
if(frsky_rx_format==FRSKY_RX_D16v2FCC)
|
||||
for (uint8_t i = 0; i < sizeof(FRSKY_RX_d16fcc_reg) / 2; i++)
|
||||
CC2500_WriteReg(pgm_read_byte_near(&FRSKY_RX_d16fcc_reg[i][0]), pgm_read_byte_near(&FRSKY_RX_d16fcc_reg[i][1]));
|
||||
if(FRSKY_RX_format==FRSKY_RX_D16v2FCC)
|
||||
{
|
||||
CC2500_WriteReg(CC2500_08_PKTCTRL0, 0x05); // Enable CRC
|
||||
CC2500_WriteReg(CC2500_17_MCSM1, 0x0E); // Go/Stay in RX mode
|
||||
@@ -141,36 +141,36 @@ static void __attribute__((unused)) frsky_rx_initialise_cc2500() {
|
||||
break;
|
||||
case FRSKY_RX_D16v2LBT:
|
||||
case FRSKY_RX_D16LBT:
|
||||
for (uint8_t i = 0; i < sizeof(frsky_rx_d16lbt_reg) / 2; i++)
|
||||
CC2500_WriteReg(pgm_read_byte_near(&frsky_rx_d16lbt_reg[i][0]), pgm_read_byte_near(&frsky_rx_d16lbt_reg[i][1]));
|
||||
if(frsky_rx_format==FRSKY_RX_D16v2LBT)
|
||||
for (uint8_t i = 0; i < sizeof(FRSKY_RX_d16lbt_reg) / 2; i++)
|
||||
CC2500_WriteReg(pgm_read_byte_near(&FRSKY_RX_d16lbt_reg[i][0]), pgm_read_byte_near(&FRSKY_RX_d16lbt_reg[i][1]));
|
||||
if(FRSKY_RX_format==FRSKY_RX_D16v2LBT)
|
||||
CC2500_WriteReg(CC2500_08_PKTCTRL0, 0x05); // Enable CRC
|
||||
break;
|
||||
case FRSKY_RX_D8:
|
||||
for (uint8_t i = 0; i < sizeof(frsky_rx_d8_reg) / 2; i++)
|
||||
CC2500_WriteReg(pgm_read_byte_near(&frsky_rx_d8_reg[i][0]), pgm_read_byte_near(&frsky_rx_d8_reg[i][1]));
|
||||
for (uint8_t i = 0; i < sizeof(FRSKY_RX_d8_reg) / 2; i++)
|
||||
CC2500_WriteReg(pgm_read_byte_near(&FRSKY_RX_d8_reg[i][0]), pgm_read_byte_near(&FRSKY_RX_d8_reg[i][1]));
|
||||
CC2500_WriteReg(CC2500_23_FSCAL3, 0x89);
|
||||
break;
|
||||
}
|
||||
CC2500_WriteReg(CC2500_0A_CHANNR, 0); // bind channel
|
||||
rx_disable_lna = IS_POWER_FLAG_on;
|
||||
CC2500_SetTxRxMode(rx_disable_lna ? TXRX_OFF : RX_EN); // lna disable / enable
|
||||
frsky_rx_strobe_rx();
|
||||
FRSKY_RX_strobe_rx();
|
||||
delayMicroseconds(1000); // wait for RX to activate
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) frsky_rx_set_channel(uint8_t channel)
|
||||
static void __attribute__((unused)) FRSKY_RX_set_channel(uint8_t channel)
|
||||
{
|
||||
CC2500_WriteReg(CC2500_0A_CHANNR, hopping_frequency[channel]);
|
||||
if(frsky_rx_format == FRSKY_RX_D8)
|
||||
if(FRSKY_RX_format == FRSKY_RX_D8)
|
||||
CC2500_WriteReg(CC2500_23_FSCAL3, 0x89);
|
||||
CC2500_WriteReg(CC2500_25_FSCAL1, calData[channel]);
|
||||
frsky_rx_strobe_rx();
|
||||
FRSKY_RX_strobe_rx();
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) frsky_rx_calibrate()
|
||||
static void __attribute__((unused)) FRSKY_RX_calibrate()
|
||||
{
|
||||
frsky_rx_strobe_rx();
|
||||
FRSKY_RX_strobe_rx();
|
||||
for (unsigned c = 0; c < 47; c++)
|
||||
{
|
||||
CC2500_Strobe(CC2500_SIDLE);
|
||||
@@ -193,7 +193,7 @@ static uint8_t __attribute__((unused)) frskyx_rx_check_crc_id(bool bind,bool ini
|
||||
uint8_t offset=bind?3:1;
|
||||
|
||||
// Check D8 checksum
|
||||
if (frsky_rx_format == FRSKY_RX_D8)
|
||||
if (FRSKY_RX_format == FRSKY_RX_D8)
|
||||
{
|
||||
if((packet[packet_length+1] & 0x80) != 0x80) // Check CRC_OK flag in status byte 2
|
||||
return false; // Bad CRC
|
||||
@@ -210,7 +210,7 @@ static uint8_t __attribute__((unused)) frskyx_rx_check_crc_id(bool bind,bool ini
|
||||
}
|
||||
|
||||
// Check D16v2 checksum
|
||||
if (frsky_rx_format == FRSKY_RX_D16v2LBT || frsky_rx_format == FRSKY_RX_D16v2FCC)
|
||||
if (FRSKY_RX_format == FRSKY_RX_D16v2LBT || FRSKY_RX_format == FRSKY_RX_D16v2FCC)
|
||||
if((packet[packet_length+1] & 0x80) != 0x80) // Check CRC_OK flag in status byte 2
|
||||
return false;
|
||||
//debugln("HW Checksum ok");
|
||||
@@ -222,12 +222,12 @@ static uint8_t __attribute__((unused)) frskyx_rx_check_crc_id(bool bind,bool ini
|
||||
return false; // Bad CRC
|
||||
//debugln("Checksum ok");
|
||||
|
||||
if (bind && (frsky_rx_format == FRSKY_RX_D16v2LBT || frsky_rx_format == FRSKY_RX_D16v2FCC))
|
||||
if (bind && (FRSKY_RX_format == FRSKY_RX_D16v2LBT || FRSKY_RX_format == FRSKY_RX_D16v2FCC))
|
||||
for(uint8_t i=3; i<packet_length-2; i++) //unXOR bind packet
|
||||
packet[i] ^= 0xA7;
|
||||
|
||||
uint8_t offset2=0;
|
||||
if (bind && (frsky_rx_format == FRSKY_RX_D16LBT || frsky_rx_format == FRSKY_RX_D16FCC))
|
||||
if (bind && (FRSKY_RX_format == FRSKY_RX_D16LBT || FRSKY_RX_format == FRSKY_RX_D16FCC))
|
||||
offset2=6;
|
||||
if(init)
|
||||
{//Save TXID
|
||||
@@ -248,7 +248,7 @@ static uint8_t __attribute__((unused)) frskyx_rx_check_crc_id(bool bind,bool ini
|
||||
return true; // Full match
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) frsky_rx_build_telemetry_packet()
|
||||
static void __attribute__((unused)) FRSKY_RX_build_telemetry_packet()
|
||||
{
|
||||
uint16_t raw_channel[8];
|
||||
uint32_t bits = 0;
|
||||
@@ -256,7 +256,7 @@ static void __attribute__((unused)) frsky_rx_build_telemetry_packet()
|
||||
uint8_t idx = 0;
|
||||
uint8_t i;
|
||||
|
||||
if (frsky_rx_format == FRSKY_RX_D8)
|
||||
if (FRSKY_RX_format == FRSKY_RX_D8)
|
||||
{// decode D8 channels
|
||||
raw_channel[0] = ((packet[10] & 0x0F) << 8 | packet[6]);
|
||||
raw_channel[1] = ((packet[10] & 0xF0) << 4 | packet[7]);
|
||||
@@ -299,7 +299,7 @@ static void __attribute__((unused)) frsky_rx_build_telemetry_packet()
|
||||
packet_in[idx++] = RX_LQI;
|
||||
packet_in[idx++] = RX_RSSI;
|
||||
packet_in[idx++] = 0; // start channel
|
||||
packet_in[idx++] = frsky_rx_format == FRSKY_RX_D8 ? 8 : 16; // number of channels in packet
|
||||
packet_in[idx++] = FRSKY_RX_format == FRSKY_RX_D8 ? 8 : 16; // number of channels in packet
|
||||
|
||||
// pack channels
|
||||
for (i = 0; i < packet_in[3]; i++) {
|
||||
@@ -313,29 +313,29 @@ static void __attribute__((unused)) frsky_rx_build_telemetry_packet()
|
||||
}
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) frsky_rx_data()
|
||||
static void __attribute__((unused)) FRSKY_RX_data()
|
||||
{
|
||||
uint16_t temp = FRSKY_RX_EEPROM_OFFSET;
|
||||
frsky_rx_format = eeprom_read_byte((EE_ADDR)temp++) % FRSKY_RX_FORMATS;
|
||||
FRSKY_RX_format = eeprom_read_byte((EE_ADDR)temp++) % FRSKY_RX_FORMATS;
|
||||
rx_tx_addr[3] = eeprom_read_byte((EE_ADDR)temp++);
|
||||
rx_tx_addr[2] = eeprom_read_byte((EE_ADDR)temp++);
|
||||
rx_tx_addr[1] = eeprom_read_byte((EE_ADDR)temp++);
|
||||
rx_tx_addr[0] = RX_num;
|
||||
frsky_rx_finetune = eeprom_read_byte((EE_ADDR)temp++);
|
||||
debug("format=%d, ", frsky_rx_format);
|
||||
FRSKY_RX_finetune = eeprom_read_byte((EE_ADDR)temp++);
|
||||
debug("format=%d, ", FRSKY_RX_format);
|
||||
debug("addr[3]=%02X, ", rx_tx_addr[3]);
|
||||
debug("addr[2]=%02X, ", rx_tx_addr[2]);
|
||||
debug("addr[1]=%02X, ", rx_tx_addr[1]);
|
||||
debug("rx_num=%02X, ", rx_tx_addr[0]);
|
||||
debugln("tune=%d", (int8_t)frsky_rx_finetune);
|
||||
if(frsky_rx_format != FRSKY_RX_D16v2LBT && frsky_rx_format != FRSKY_RX_D16v2FCC)
|
||||
debugln("tune=%d", (int8_t)FRSKY_RX_finetune);
|
||||
if(FRSKY_RX_format != FRSKY_RX_D16v2LBT && FRSKY_RX_format != FRSKY_RX_D16v2FCC)
|
||||
{//D8 & D16v1
|
||||
for (uint8_t ch = 0; ch < 47; ch++)
|
||||
hopping_frequency[ch] = eeprom_read_byte((EE_ADDR)temp++);
|
||||
}
|
||||
else
|
||||
{
|
||||
FrSkyFormat=frsky_rx_format == FRSKY_RX_D16v2FCC?0:2;
|
||||
FrSkyFormat=FRSKY_RX_format == FRSKY_RX_D16v2FCC?0:2;
|
||||
FrSkyX2_init_hop();
|
||||
}
|
||||
debug("ch:");
|
||||
@@ -343,20 +343,20 @@ static void __attribute__((unused)) frsky_rx_data()
|
||||
debug(" %02X", hopping_frequency[ch]);
|
||||
debugln("");
|
||||
|
||||
frsky_rx_initialise_cc2500();
|
||||
frsky_rx_calibrate();
|
||||
FRSKY_RX_initialise_cc2500();
|
||||
FRSKY_RX_calibrate();
|
||||
CC2500_WriteReg(CC2500_18_MCSM0, 0x08); // FS_AUTOCAL = manual
|
||||
CC2500_WriteReg(CC2500_09_ADDR, rx_tx_addr[3]); // set address
|
||||
CC2500_WriteReg(CC2500_07_PKTCTRL1, 0x05); // check address
|
||||
if (option == 0)
|
||||
CC2500_WriteReg(CC2500_0C_FSCTRL0, frsky_rx_finetune);
|
||||
CC2500_WriteReg(CC2500_0C_FSCTRL0, FRSKY_RX_finetune);
|
||||
else
|
||||
CC2500_WriteReg(CC2500_0C_FSCTRL0, option);
|
||||
frsky_rx_set_channel(hopping_frequency_no);
|
||||
FRSKY_RX_set_channel(hopping_frequency_no);
|
||||
phase = FRSKY_RX_DATA;
|
||||
}
|
||||
|
||||
uint16_t initFrSky_Rx()
|
||||
void FRSKY_RX_init()
|
||||
{
|
||||
if(sub_protocol == FRSKY_ERASE)
|
||||
{
|
||||
@@ -371,26 +371,25 @@ uint16_t initFrSky_Rx()
|
||||
}
|
||||
else
|
||||
{
|
||||
frsky_rx_chanskip = 1;
|
||||
FRSKY_RX_chanskip = 1;
|
||||
hopping_frequency_no = 0;
|
||||
rx_data_started = false;
|
||||
frsky_rx_finetune = 0;
|
||||
FRSKY_RX_finetune = 0;
|
||||
telemetry_link = 0;
|
||||
packet_count = 0;
|
||||
if (IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
frsky_rx_format = FRSKY_RX_D8;
|
||||
frsky_rx_initialise_cc2500();
|
||||
FRSKY_RX_format = FRSKY_RX_D8;
|
||||
FRSKY_RX_initialise_cc2500();
|
||||
phase = FRSKY_RX_TUNE_START;
|
||||
debugln("FRSKY_RX_TUNE_START");
|
||||
}
|
||||
else
|
||||
frsky_rx_data();
|
||||
FRSKY_RX_data();
|
||||
}
|
||||
return 1000;
|
||||
}
|
||||
|
||||
uint16_t FrSky_Rx_callback()
|
||||
uint16_t FRSKY_RX_callback()
|
||||
{
|
||||
static int8_t read_retry = 0;
|
||||
static int8_t tune_low, tune_high;
|
||||
@@ -405,12 +404,13 @@ uint16_t FrSky_Rx_callback()
|
||||
return 10000; // Nothing to do...
|
||||
}
|
||||
|
||||
if(IS_BIND_DONE && phase != FRSKY_RX_DATA) return initFrSky_Rx(); // Abort bind
|
||||
if(IS_BIND_DONE && phase != FRSKY_RX_DATA)
|
||||
FRSKY_RX_init(); // Abort bind
|
||||
|
||||
if ((prev_option != option) && (phase >= FRSKY_RX_DATA))
|
||||
{
|
||||
if (option == 0)
|
||||
CC2500_WriteReg(CC2500_0C_FSCTRL0, frsky_rx_finetune);
|
||||
CC2500_WriteReg(CC2500_0C_FSCTRL0, FRSKY_RX_finetune);
|
||||
else
|
||||
CC2500_WriteReg(CC2500_0C_FSCTRL0, option);
|
||||
prev_option = option;
|
||||
@@ -431,20 +431,20 @@ uint16_t FrSky_Rx_callback()
|
||||
CC2500_ReadData(packet, len);
|
||||
if(frskyx_rx_check_crc_id(true,true))
|
||||
{
|
||||
frsky_rx_finetune = -127;
|
||||
CC2500_WriteReg(CC2500_0C_FSCTRL0, frsky_rx_finetune);
|
||||
FRSKY_RX_finetune = -127;
|
||||
CC2500_WriteReg(CC2500_0C_FSCTRL0, FRSKY_RX_finetune);
|
||||
phase = FRSKY_RX_TUNE_LOW;
|
||||
debugln("FRSKY_RX_TUNE_LOW");
|
||||
frsky_rx_strobe_rx();
|
||||
FRSKY_RX_strobe_rx();
|
||||
state = 0;
|
||||
return 1000;
|
||||
}
|
||||
}
|
||||
frsky_rx_format = (frsky_rx_format + 1) % FRSKY_RX_FORMATS; // switch to next format (D8, D16FCC, D16LBT, D16v2FCC, D16v2LBT)
|
||||
frsky_rx_initialise_cc2500();
|
||||
frsky_rx_finetune += 10;
|
||||
CC2500_WriteReg(CC2500_0C_FSCTRL0, frsky_rx_finetune);
|
||||
frsky_rx_strobe_rx();
|
||||
FRSKY_RX_format = (FRSKY_RX_format + 1) % FRSKY_RX_FORMATS; // switch to next format (D8, D16FCC, D16LBT, D16v2FCC, D16v2LBT)
|
||||
FRSKY_RX_initialise_cc2500();
|
||||
FRSKY_RX_finetune += 10;
|
||||
CC2500_WriteReg(CC2500_0C_FSCTRL0, FRSKY_RX_finetune);
|
||||
FRSKY_RX_strobe_rx();
|
||||
return 18000;
|
||||
|
||||
case FRSKY_RX_TUNE_LOW:
|
||||
@@ -452,18 +452,18 @@ uint16_t FrSky_Rx_callback()
|
||||
{
|
||||
CC2500_ReadData(packet, len);
|
||||
if(frskyx_rx_check_crc_id(true,false)) {
|
||||
tune_low = frsky_rx_finetune;
|
||||
frsky_rx_finetune = 127;
|
||||
CC2500_WriteReg(CC2500_0C_FSCTRL0, frsky_rx_finetune);
|
||||
tune_low = FRSKY_RX_finetune;
|
||||
FRSKY_RX_finetune = 127;
|
||||
CC2500_WriteReg(CC2500_0C_FSCTRL0, FRSKY_RX_finetune);
|
||||
phase = FRSKY_RX_TUNE_HIGH;
|
||||
debugln("FRSKY_RX_TUNE_HIGH");
|
||||
frsky_rx_strobe_rx();
|
||||
FRSKY_RX_strobe_rx();
|
||||
return 1000;
|
||||
}
|
||||
}
|
||||
frsky_rx_finetune += 1;
|
||||
CC2500_WriteReg(CC2500_0C_FSCTRL0, frsky_rx_finetune);
|
||||
frsky_rx_strobe_rx();
|
||||
FRSKY_RX_finetune += 1;
|
||||
CC2500_WriteReg(CC2500_0C_FSCTRL0, FRSKY_RX_finetune);
|
||||
FRSKY_RX_strobe_rx();
|
||||
return 18000;
|
||||
|
||||
case FRSKY_RX_TUNE_HIGH:
|
||||
@@ -471,9 +471,9 @@ uint16_t FrSky_Rx_callback()
|
||||
{
|
||||
CC2500_ReadData(packet, len);
|
||||
if(frskyx_rx_check_crc_id(true,false)) {
|
||||
tune_high = frsky_rx_finetune;
|
||||
frsky_rx_finetune = (tune_low + tune_high) / 2;
|
||||
CC2500_WriteReg(CC2500_0C_FSCTRL0, (int8_t)frsky_rx_finetune);
|
||||
tune_high = FRSKY_RX_finetune;
|
||||
FRSKY_RX_finetune = (tune_low + tune_high) / 2;
|
||||
CC2500_WriteReg(CC2500_0C_FSCTRL0, (int8_t)FRSKY_RX_finetune);
|
||||
if(tune_low < tune_high)
|
||||
{
|
||||
phase = FRSKY_RX_BIND;
|
||||
@@ -484,13 +484,13 @@ uint16_t FrSky_Rx_callback()
|
||||
phase = FRSKY_RX_TUNE_START;
|
||||
debugln("FRSKY_RX_TUNE_START");
|
||||
}
|
||||
frsky_rx_strobe_rx();
|
||||
FRSKY_RX_strobe_rx();
|
||||
return 1000;
|
||||
}
|
||||
}
|
||||
frsky_rx_finetune -= 1;
|
||||
CC2500_WriteReg(CC2500_0C_FSCTRL0, frsky_rx_finetune);
|
||||
frsky_rx_strobe_rx();
|
||||
FRSKY_RX_finetune -= 1;
|
||||
CC2500_WriteReg(CC2500_0C_FSCTRL0, FRSKY_RX_finetune);
|
||||
FRSKY_RX_strobe_rx();
|
||||
return 18000;
|
||||
|
||||
case FRSKY_RX_BIND:
|
||||
@@ -498,7 +498,7 @@ uint16_t FrSky_Rx_callback()
|
||||
{
|
||||
CC2500_ReadData(packet, len);
|
||||
if(frskyx_rx_check_crc_id(true,false)) {
|
||||
if(frsky_rx_format != FRSKY_RX_D16v2LBT && frsky_rx_format != FRSKY_RX_D16v2FCC)
|
||||
if(FRSKY_RX_format != FRSKY_RX_D16v2LBT && FRSKY_RX_format != FRSKY_RX_D16v2FCC)
|
||||
{// D8 & D16v1
|
||||
if(packet[5] <= 0x2D)
|
||||
{
|
||||
@@ -517,27 +517,27 @@ uint16_t FrSky_Rx_callback()
|
||||
uint16_t temp = FRSKY_RX_EEPROM_OFFSET;
|
||||
if(sub_protocol==FRSKY_CLONE)
|
||||
{
|
||||
if(frsky_rx_format==FRSKY_RX_D8)
|
||||
if(FRSKY_RX_format==FRSKY_RX_D8)
|
||||
temp=FRSKYD_CLONE_EEPROM_OFFSET;
|
||||
else if(frsky_rx_format == FRSKY_RX_D16FCC || frsky_rx_format == FRSKY_RX_D16LBT)
|
||||
else if(FRSKY_RX_format == FRSKY_RX_D16FCC || FRSKY_RX_format == FRSKY_RX_D16LBT)
|
||||
temp=FRSKYX_CLONE_EEPROM_OFFSET;
|
||||
else
|
||||
temp=FRSKYX2_CLONE_EEPROM_OFFSET;
|
||||
}
|
||||
eeprom_write_byte((EE_ADDR)temp++, frsky_rx_format);
|
||||
eeprom_write_byte((EE_ADDR)temp++, FRSKY_RX_format);
|
||||
eeprom_write_byte((EE_ADDR)temp++, rx_tx_addr[3]);
|
||||
eeprom_write_byte((EE_ADDR)temp++, rx_tx_addr[2]);
|
||||
eeprom_write_byte((EE_ADDR)temp++, rx_tx_addr[1]);
|
||||
if(sub_protocol==FRSKY_RX)
|
||||
eeprom_write_byte((EE_ADDR)temp++, frsky_rx_finetune);
|
||||
if(frsky_rx_format != FRSKY_RX_D16v2FCC && frsky_rx_format != FRSKY_RX_D16v2LBT)
|
||||
if(sub_protocol == FRSKY_RX || sub_protocol == FRSKY_CPPM) // FRSKY_RX, FRSKY_CPPM
|
||||
eeprom_write_byte((EE_ADDR)temp++, FRSKY_RX_finetune);
|
||||
if(FRSKY_RX_format != FRSKY_RX_D16v2FCC && FRSKY_RX_format != FRSKY_RX_D16v2LBT)
|
||||
for (ch = 0; ch < 47; ch++)
|
||||
eeprom_write_byte((EE_ADDR)temp++, hopping_frequency[ch]);
|
||||
frsky_rx_data();
|
||||
FRSKY_RX_data();
|
||||
debugln("FRSKY_RX_DATA");
|
||||
}
|
||||
}
|
||||
frsky_rx_strobe_rx();
|
||||
FRSKY_RX_strobe_rx();
|
||||
}
|
||||
return 1000;
|
||||
|
||||
@@ -554,31 +554,35 @@ uint16_t FrSky_Rx_callback()
|
||||
RX_RSSI += 128;
|
||||
bool chanskip_valid=true;
|
||||
// hop to next channel
|
||||
if (frsky_rx_format != FRSKY_RX_D8)
|
||||
if (FRSKY_RX_format != FRSKY_RX_D8)
|
||||
{//D16v1 & D16v2
|
||||
if(rx_data_started)
|
||||
{
|
||||
if(frsky_rx_chanskip != (((packet[4] & 0xC0) >> 6) | ((packet[5] & 0x3F) << 2)))
|
||||
if(FRSKY_RX_chanskip != (((packet[4] & 0xC0) >> 6) | ((packet[5] & 0x3F) << 2)))
|
||||
{
|
||||
chanskip_valid=false; // chanskip value has changed which surely indicates a bad frame
|
||||
packet_count++;
|
||||
if(packet_count>5) // the TX must have changed chanskip...
|
||||
frsky_rx_chanskip = ((packet[4] & 0xC0) >> 6) | ((packet[5] & 0x3F) << 2); // chanskip init
|
||||
FRSKY_RX_chanskip = ((packet[4] & 0xC0) >> 6) | ((packet[5] & 0x3F) << 2); // chanskip init
|
||||
}
|
||||
else
|
||||
packet_count=0;
|
||||
}
|
||||
else
|
||||
frsky_rx_chanskip = ((packet[4] & 0xC0) >> 6) | ((packet[5] & 0x3F) << 2); // chanskip init
|
||||
FRSKY_RX_chanskip = ((packet[4] & 0xC0) >> 6) | ((packet[5] & 0x3F) << 2); // chanskip init
|
||||
}
|
||||
hopping_frequency_no = (hopping_frequency_no + frsky_rx_chanskip) % 47;
|
||||
frsky_rx_set_channel(hopping_frequency_no);
|
||||
hopping_frequency_no = (hopping_frequency_no + FRSKY_RX_chanskip) % 47;
|
||||
FRSKY_RX_set_channel(hopping_frequency_no);
|
||||
if(chanskip_valid)
|
||||
{
|
||||
if (telemetry_link == 0)
|
||||
if ((telemetry_link & 0x7F) == 0)
|
||||
{ // send channels to TX
|
||||
frsky_rx_build_telemetry_packet();
|
||||
FRSKY_RX_build_telemetry_packet();
|
||||
telemetry_link = 1;
|
||||
#ifdef SEND_CPPM
|
||||
if(sub_protocol == FRSKY_CPPM)
|
||||
telemetry_link |= 0x80; // Disable telemetry output
|
||||
#endif
|
||||
}
|
||||
pps_counter++;
|
||||
}
|
||||
@@ -602,8 +606,8 @@ uint16_t FrSky_Rx_callback()
|
||||
|
||||
// skip channel if no packet received in time
|
||||
if (read_retry++ >= 9) {
|
||||
hopping_frequency_no = (hopping_frequency_no + frsky_rx_chanskip) % 47;
|
||||
frsky_rx_set_channel(hopping_frequency_no);
|
||||
hopping_frequency_no = (hopping_frequency_no + FRSKY_RX_chanskip) % 47;
|
||||
FRSKY_RX_set_channel(hopping_frequency_no);
|
||||
if(rx_data_started)
|
||||
read_retry = 0;
|
||||
else
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
#include "iface_cc2500.h"
|
||||
|
||||
//#define SFHSS_DEBUG_TIMING
|
||||
|
||||
#define SFHSS_COARSE 0
|
||||
|
||||
#define SFHSS_PACKET_LEN 13
|
||||
@@ -124,7 +126,7 @@ static void __attribute__((unused)) SFHSS_calc_next_chan()
|
||||
// Channel values are 12-bit values between 1020 and 2020, 1520 is the middle.
|
||||
// Futaba @140% is 2070...1520...970
|
||||
// Values grow down and to the right.
|
||||
static void __attribute__((unused)) SFHSS_build_data_packet()
|
||||
static void __attribute__((unused)) SFHSS_send_packet()
|
||||
{
|
||||
uint16_t ch[4];
|
||||
// command.bit0 is the packet number indicator: =0 -> SFHSS_DATA1, =1 -> SFHSS_DATA2
|
||||
@@ -200,15 +202,17 @@ static void __attribute__((unused)) SFHSS_build_data_packet()
|
||||
packet[10] = (ch[2] << 7) | ((ch[3] >> 5) & 0x7F );
|
||||
packet[11] = (ch[3] << 3) | ((fhss_code >> 2) & 0x07 );
|
||||
packet[12] = (fhss_code << 6) | command;
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) SFHSS_send_packet()
|
||||
{
|
||||
CC2500_WriteData(packet, SFHSS_PACKET_LEN);
|
||||
}
|
||||
|
||||
uint16_t ReadSFHSS()
|
||||
uint16_t SFHSS_callback()
|
||||
{
|
||||
#ifdef SFHSS_DEBUG_TIMING
|
||||
static uint16_t prev_adjust_timing=1024;
|
||||
uint16_t adjust_timing = (Channel_data[CH15]>>3) - (1024>>3); // +-102 @ 100%
|
||||
#endif
|
||||
|
||||
switch(phase)
|
||||
{
|
||||
case SFHSS_START:
|
||||
@@ -235,16 +239,27 @@ uint16_t ReadSFHSS()
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(6800);
|
||||
#endif
|
||||
SFHSS_build_data_packet();
|
||||
SFHSS_send_packet();
|
||||
phase = SFHSS_DATA2;
|
||||
#ifdef SFHSS_DEBUG_TIMING
|
||||
return SFHSS_DATA2_TIMING - adjust_timing;
|
||||
#else
|
||||
return SFHSS_DATA2_TIMING; // original 1650
|
||||
#endif
|
||||
case SFHSS_DATA2:
|
||||
SFHSS_build_data_packet();
|
||||
SFHSS_send_packet();
|
||||
SFHSS_calc_next_chan();
|
||||
phase = SFHSS_TUNE;
|
||||
return (SFHSS_PACKET_PERIOD -2000 -SFHSS_DATA2_TIMING); // original 2000
|
||||
#ifdef SFHSS_DEBUG_TIMING
|
||||
if(prev_adjust_timing != adjust_timing)
|
||||
{
|
||||
debugln("A:%d",(uint16_t)(SFHSS_DATA2_TIMING - adjust_timing));
|
||||
prev_adjust_timing = adjust_timing;
|
||||
}
|
||||
return SFHSS_PACKET_PERIOD -2000 -(SFHSS_DATA2_TIMING - adjust_timing);
|
||||
#else
|
||||
return SFHSS_PACKET_PERIOD -2000 -SFHSS_DATA2_TIMING; // original 2000
|
||||
#endif
|
||||
case SFHSS_TUNE:
|
||||
phase = SFHSS_DATA1;
|
||||
SFHSS_tune_freq();
|
||||
@@ -285,7 +300,7 @@ static void __attribute__((unused)) SFHSS_get_tx_id()
|
||||
rx_tx_addr[1] = fixed_id >> 0;
|
||||
}
|
||||
|
||||
uint16_t initSFHSS()
|
||||
void SFHSS_init()
|
||||
{
|
||||
BIND_DONE; // Not a TX bind protocol
|
||||
SFHSS_get_tx_id();
|
||||
@@ -294,7 +309,6 @@ uint16_t initSFHSS()
|
||||
|
||||
SFHSS_rf_init();
|
||||
phase = SFHSS_START;
|
||||
return 10000;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -14,9 +14,9 @@ Multiprotocol is distributed in the hope that it will be useful,
|
||||
*/
|
||||
// Compatible with GD005 C-17 and GD006 DA62 planes.
|
||||
|
||||
#if defined(GD00X_NRF24L01_INO)
|
||||
#if defined(GD00X_CCNRF_INO)
|
||||
|
||||
#include "iface_nrf250k.h"
|
||||
#include "iface_xn297.h"
|
||||
|
||||
//#define FORCE_GD00X_ORIGINAL_ID
|
||||
|
||||
@@ -113,7 +113,7 @@ static void __attribute__((unused)) GD00X_send_packet()
|
||||
|
||||
if(IS_BIND_DONE)
|
||||
{
|
||||
XN297L_Hopping(hopping_frequency_no);
|
||||
XN297_Hopping(hopping_frequency_no);
|
||||
if(sub_protocol==GD_V1)
|
||||
{
|
||||
hopping_frequency_no++;
|
||||
@@ -121,21 +121,22 @@ static void __attribute__((unused)) GD00X_send_packet()
|
||||
}
|
||||
}
|
||||
|
||||
XN297L_WritePayload(packet, packet_length);
|
||||
|
||||
XN297L_SetPower(); // Set tx_power
|
||||
XN297L_SetFreqOffset(); // Set frequency offset
|
||||
// Send
|
||||
XN297_SetFreqOffset();
|
||||
XN297_SetPower();
|
||||
XN297_SetTxRxMode(TX_EN);
|
||||
XN297_WritePayload(packet, packet_length);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) GD00X_init()
|
||||
static void __attribute__((unused)) GD00X_RF_init()
|
||||
{
|
||||
XN297L_Init();
|
||||
XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_250K);
|
||||
if(sub_protocol==GD_V1)
|
||||
XN297L_SetTXAddr((uint8_t*)"\xcc\xcc\xcc\xcc\xcc", 5);
|
||||
XN297_SetTXAddr((uint8_t*)"\xcc\xcc\xcc\xcc\xcc", 5);
|
||||
else
|
||||
XN297L_SetTXAddr((uint8_t*)"GDKNx", 5);
|
||||
XN297L_HoppingCalib(sub_protocol==GD_V1?GD00X_RF_NUM_CHANNELS:GD00X_V2_RF_NUM_CHANNELS); // Calibrate all channels
|
||||
XN297L_RFChannel(sub_protocol==GD_V1?GD00X_RF_BIND_CHANNEL:GD00X_V2_RF_BIND_CHANNEL); // Set bind channel
|
||||
XN297_SetTXAddr((uint8_t*)"GDKNx", 5);
|
||||
XN297_HoppingCalib(sub_protocol==GD_V1?GD00X_RF_NUM_CHANNELS:GD00X_V2_RF_NUM_CHANNELS); // Calibrate all channels
|
||||
XN297_RFChannel(sub_protocol==GD_V1?GD00X_RF_BIND_CHANNEL:GD00X_V2_RF_BIND_CHANNEL); // Set bind channel
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) GD00X_initialize_txid()
|
||||
@@ -204,28 +205,27 @@ static void __attribute__((unused)) GD00X_initialize_txid()
|
||||
|
||||
uint16_t GD00X_callback()
|
||||
{
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
if(--bind_counter==0)
|
||||
BIND_DONE;
|
||||
GD00X_send_packet();
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(packet_period);
|
||||
#endif
|
||||
if(bind_counter)
|
||||
if(--bind_counter==0)
|
||||
BIND_DONE;
|
||||
GD00X_send_packet();
|
||||
return packet_period;
|
||||
}
|
||||
|
||||
uint16_t initGD00X()
|
||||
void GD00X_init()
|
||||
{
|
||||
BIND_IN_PROGRESS; // autobind protocol
|
||||
GD00X_initialize_txid();
|
||||
GD00X_init();
|
||||
GD00X_RF_init();
|
||||
hopping_frequency_no = 0;
|
||||
bind_counter=GD00X_BIND_COUNT;
|
||||
packet_period=sub_protocol==GD_V1?GD00X_PACKET_PERIOD:GD00X_V2_BIND_PACKET_PERIOD;
|
||||
packet_length=sub_protocol==GD_V1?GD00X_PAYLOAD_SIZE:GD00X_V2_PAYLOAD_SIZE;
|
||||
packet_count=0;
|
||||
len=0;
|
||||
return GD00X_INITIAL_WAIT;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -19,7 +19,7 @@ Multiprotocol is distributed in the hope that it will be useful,
|
||||
|
||||
#if defined(GW008_NRF24L01_INO)
|
||||
|
||||
#include "iface_nrf24l01.h"
|
||||
#include "iface_xn297.h"
|
||||
|
||||
#define GW008_INITIAL_WAIT 500
|
||||
#define GW008_PACKET_PERIOD 2400
|
||||
@@ -32,10 +32,10 @@ enum {
|
||||
GW008_DATA
|
||||
};
|
||||
|
||||
static void __attribute__((unused)) GW008_send_packet(uint8_t bind)
|
||||
static void __attribute__((unused)) GW008_send_packet()
|
||||
{
|
||||
packet[0] = rx_tx_addr[0];
|
||||
if(bind)
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
packet[1] = 0x55;
|
||||
packet[2] = hopping_frequency[0];
|
||||
@@ -47,6 +47,9 @@ static void __attribute__((unused)) GW008_send_packet(uint8_t bind)
|
||||
}
|
||||
else
|
||||
{
|
||||
XN297_Hopping((hopping_frequency_no++)/2);
|
||||
hopping_frequency_no %= 8;
|
||||
|
||||
packet[1] = 0x01 | GET_FLAG(CH5_SW, 0x40); // flip
|
||||
packet[2] = convert_channel_16b_limit(AILERON , 200, 0); // aileron
|
||||
packet[3] = convert_channel_16b_limit(ELEVATOR, 0, 200); // elevator
|
||||
@@ -63,38 +66,21 @@ static void __attribute__((unused)) GW008_send_packet(uint8_t bind)
|
||||
}
|
||||
packet[14] = rx_tx_addr[1];
|
||||
|
||||
// Power on, TX mode, CRC enabled
|
||||
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, bind ? GW008_RF_BIND_CHANNEL : hopping_frequency[(hopping_frequency_no++)/2]);
|
||||
hopping_frequency_no %= 8;
|
||||
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||
NRF24L01_FlushTx();
|
||||
// Send
|
||||
XN297_SetPower();
|
||||
XN297_SetTxRxMode(TX_EN);
|
||||
XN297_WriteEnhancedPayload(packet, GW008_PAYLOAD_SIZE, 0);
|
||||
|
||||
NRF24L01_SetPower(); // Set tx_power
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) GW008_init()
|
||||
static void __attribute__((unused)) GW008_RF_init()
|
||||
{
|
||||
NRF24L01_Initialize();
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M);
|
||||
|
||||
XN297_SetTXAddr((uint8_t*)"\xcc\xcc\xcc\xcc\xcc", 5);
|
||||
XN297_SetRXAddr((uint8_t*)"\xcc\xcc\xcc\xcc\xcc", 5);
|
||||
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);
|
||||
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, GW008_PAYLOAD_SIZE+2); // payload + 2 bytes for pcf
|
||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03);
|
||||
NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x00); // no retransmits
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_1M);
|
||||
NRF24L01_SetPower();
|
||||
NRF24L01_Activate(0x73); // Activate feature register
|
||||
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x00); // Disable dynamic payload length on all pipes
|
||||
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x01); // Set feature bits on
|
||||
NRF24L01_Activate(0x73);
|
||||
XN297_SetRXAddr((uint8_t*)"\xcc\xcc\xcc\xcc\xcc", GW008_PAYLOAD_SIZE);
|
||||
|
||||
//XN297_HoppingCalib(8);
|
||||
XN297_RFChannel(GW008_RF_BIND_CHANNEL);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) GW008_initialize_txid()
|
||||
@@ -109,53 +95,48 @@ uint16_t GW008_callback()
|
||||
switch(phase)
|
||||
{
|
||||
case GW008_BIND1:
|
||||
if((NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR)) && // RX fifo data ready
|
||||
if(XN297_IsRX() && // RX fifo data ready
|
||||
XN297_ReadEnhancedPayload(packet, GW008_PAYLOAD_SIZE) == GW008_PAYLOAD_SIZE && // check payload size
|
||||
packet[0] == rx_tx_addr[0] && packet[14] == rx_tx_addr[1]) // check tx id
|
||||
{
|
||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
XN297_SetTxRxMode(TXRX_OFF);
|
||||
XN297_SetTxRxMode(TX_EN);
|
||||
rx_tx_addr[2] = packet[13];
|
||||
BIND_DONE;
|
||||
phase = GW008_DATA;
|
||||
}
|
||||
else
|
||||
{
|
||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
GW008_send_packet(1);
|
||||
XN297_SetTxRxMode(TXRX_OFF);
|
||||
XN297_SetTxRxMode(TX_EN);
|
||||
GW008_send_packet();
|
||||
phase = GW008_BIND2;
|
||||
return 850; // minimum value 750 for STM32
|
||||
}
|
||||
break;
|
||||
case GW008_BIND2:
|
||||
// switch to RX mode
|
||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||
NRF24L01_FlushRx();
|
||||
NRF24L01_SetTxRxMode(RX_EN);
|
||||
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO)
|
||||
| _BV(NRF24L01_00_PWR_UP) | _BV(NRF24L01_00_PRIM_RX));
|
||||
XN297_SetTxRxMode(TXRX_OFF);
|
||||
XN297_SetTxRxMode(RX_EN);
|
||||
phase = GW008_BIND1;
|
||||
return 5000;
|
||||
break;
|
||||
case GW008_DATA:
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(GW008_PACKET_PERIOD);
|
||||
#endif
|
||||
GW008_send_packet(0);
|
||||
GW008_send_packet();
|
||||
break;
|
||||
}
|
||||
return GW008_PACKET_PERIOD;
|
||||
}
|
||||
|
||||
uint16_t initGW008()
|
||||
void GW008_init()
|
||||
{
|
||||
BIND_IN_PROGRESS; // autobind protocol
|
||||
GW008_initialize_txid();
|
||||
phase = GW008_BIND1;
|
||||
GW008_init();
|
||||
GW008_RF_init();
|
||||
hopping_frequency_no = 0;
|
||||
return GW008_INITIAL_WAIT;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
#if defined(H8_3D_NRF24L01_INO)
|
||||
|
||||
#include "iface_nrf24l01.h"
|
||||
#include "iface_xn297.h"
|
||||
|
||||
#define H8_3D_PACKET_PERIOD 1800
|
||||
#define H20H_PACKET_PERIOD 9340
|
||||
@@ -50,7 +50,7 @@ enum H8_3D_FLAGS_2 {
|
||||
H8_3D_FLAG_CAM_UP = 0x04,
|
||||
};
|
||||
|
||||
static void __attribute__((unused)) H8_3D_send_packet(uint8_t bind)
|
||||
static void __attribute__((unused)) H8_3D_send_packet()
|
||||
{
|
||||
if(sub_protocol==H20H)
|
||||
packet[0] = 0x14;
|
||||
@@ -63,7 +63,7 @@ static void __attribute__((unused)) H8_3D_send_packet(uint8_t bind)
|
||||
packet[4] = rx_tx_addr[3];
|
||||
packet[8] = rx_tx_addr[0]+rx_tx_addr[1]+rx_tx_addr[2]+rx_tx_addr[3]; // txid checksum
|
||||
memset(&packet[9], 0, 10);
|
||||
if (bind)
|
||||
if (IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
packet[5] = 0x00;
|
||||
packet[6] = 0x00;
|
||||
@@ -122,18 +122,16 @@ static void __attribute__((unused)) H8_3D_send_packet(uint8_t bind)
|
||||
sum += packet[i];
|
||||
packet[19] = sum; // data checksum
|
||||
|
||||
// Power on, TX mode, 2byte CRC
|
||||
// Why CRC0? xn297 does not interpret it - either 16-bit CRC or nothing
|
||||
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
||||
// RF channel
|
||||
if(sub_protocol!=H20H)
|
||||
{ // H8_3D, H20MINI, H30MINI
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, bind ? hopping_frequency[0] : hopping_frequency[hopping_frequency_no++]);
|
||||
XN297_RFChannel(IS_BIND_IN_PROGRESS ? hopping_frequency[0] : hopping_frequency[hopping_frequency_no++]);
|
||||
hopping_frequency_no %= H8_3D_RF_NUM_CHANNELS;
|
||||
}
|
||||
else
|
||||
{ //H20H
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, bind ? H20H_BIND_RF : hopping_frequency[packet_count>>3]);
|
||||
if(!bind)
|
||||
{ // H20H
|
||||
XN297_RFChannel(IS_BIND_IN_PROGRESS ? H20H_BIND_RF : hopping_frequency[packet_count>>3]);
|
||||
if(IS_BIND_DONE)
|
||||
{
|
||||
packet_count++;
|
||||
if(packet_count>15)
|
||||
@@ -147,55 +145,39 @@ static void __attribute__((unused)) H8_3D_send_packet(uint8_t bind)
|
||||
}
|
||||
}
|
||||
|
||||
// clear packet status bits and TX FIFO
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||
NRF24L01_FlushTx();
|
||||
// Send
|
||||
XN297_SetPower();
|
||||
XN297_SetTxRxMode(TX_EN);
|
||||
XN297_WritePayload(packet, H8_3D_PACKET_SIZE);
|
||||
|
||||
NRF24L01_SetPower(); // Set tx_power
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) H8_3D_init()
|
||||
static void __attribute__((unused)) H8_3D_RF_init()
|
||||
{
|
||||
NRF24L01_Initialize();
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M);
|
||||
|
||||
if(sub_protocol==H20H)
|
||||
XN297_SetTXAddr((uint8_t *)"\xEE\xDD\xCC\xBB\x11", 5);
|
||||
else // H8_3D, H20MINI, H30MINI
|
||||
XN297_SetTXAddr((uint8_t *)"\xC4\x57\x09\x65\x21", 5);
|
||||
|
||||
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_WriteReg(NRF24L01_04_SETUP_RETR, 0x00); // no retransmits
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps
|
||||
NRF24L01_SetPower();
|
||||
}
|
||||
|
||||
uint16_t H8_3D_callback()
|
||||
{
|
||||
if(IS_BIND_DONE)
|
||||
{
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(packet_period);
|
||||
#endif
|
||||
H8_3D_send_packet(0);
|
||||
}
|
||||
else
|
||||
if(bind_counter)
|
||||
{
|
||||
bind_counter--;
|
||||
if (bind_counter == 0)
|
||||
{
|
||||
BIND_DONE;
|
||||
packet_count=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
H8_3D_send_packet(1);
|
||||
bind_counter--;
|
||||
}
|
||||
}
|
||||
#ifdef MULTI_SYNC
|
||||
else
|
||||
telemetry_set_input_sync(packet_period);
|
||||
#endif
|
||||
|
||||
H8_3D_send_packet();
|
||||
return packet_period;
|
||||
}
|
||||
|
||||
@@ -238,12 +220,12 @@ static void __attribute__((unused)) H8_3D_initialize_txid()
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t initH8_3D(void)
|
||||
void H8_3D_init(void)
|
||||
{
|
||||
BIND_IN_PROGRESS; // autobind protocol
|
||||
bind_counter = H8_3D_BIND_COUNT;
|
||||
H8_3D_initialize_txid();
|
||||
H8_3D_init();
|
||||
H8_3D_RF_init();
|
||||
switch(sub_protocol)
|
||||
{
|
||||
case H8_3D:
|
||||
@@ -257,7 +239,6 @@ uint16_t initH8_3D(void)
|
||||
packet_period=H20MINI_PACKET_PERIOD;
|
||||
break;
|
||||
}
|
||||
return H8_3D_INITIAL_WAIT;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -137,7 +137,7 @@ const uint8_t PROGMEM HOTT_hop[][HOTT_NUM_RF_CHANNELS]=
|
||||
};
|
||||
const uint16_t PROGMEM HOTT_hop_val[] = { 0xC06B, 0xC34A, 0xDB24, 0x8E09, 0x272E, 0x217F, 0x155B, 0xEDE8, 0x1D31, 0x0986, 0x56F7, 0x6454, 0xC42D, 0x01D2, 0xC253, 0x1180 };
|
||||
|
||||
static void __attribute__((unused)) HOTT_init()
|
||||
static void __attribute__((unused)) HOTT_TXID_init()
|
||||
{
|
||||
packet[0] = pgm_read_word_near( &HOTT_hop_val[num_ch] );
|
||||
packet[1] = pgm_read_word_near( &HOTT_hop_val[num_ch] )>>8;
|
||||
@@ -227,6 +227,8 @@ static void __attribute__((unused)) HOTT_prep_data_packet()
|
||||
}
|
||||
upper ^= 0x01; // toggle between CH9..CH12 and CH13..16
|
||||
|
||||
packet[28] = 0x80; // no sensor
|
||||
packet[29] = 0x02; // 0x02 when bind starts then when RX replies cycle in sequence 0x1A/22/2A/0A/12, 0x02 during normal packets, 0x01->text config menu, 0x0A->no more RX telemetry
|
||||
#ifdef HOTT_FW_TELEMETRY
|
||||
if(IS_BIND_DONE)
|
||||
{
|
||||
@@ -244,25 +246,23 @@ static void __attribute__((unused)) HOTT_prep_data_packet()
|
||||
}
|
||||
else
|
||||
packet[28] = HoTT_SerialRX_val | 0x0F; // no button pressed
|
||||
packet[29] = 0x01; // 0x01->Text config menu
|
||||
}
|
||||
else
|
||||
packet[28] = 0x0F; // RX, no button pressed
|
||||
if(sub_protocol == HOTT_SYNC)
|
||||
packet[29] = ((HOTT_sensor_seq+1)<<3) | 1; // Telemetry packet sequence
|
||||
else
|
||||
packet[29] = 0x01; // 0x01->Text config menu
|
||||
}
|
||||
else
|
||||
{
|
||||
packet[28] = 0x89+HOTT_sensor_cur; // 0x89/8A/8B/8C/8D/8E during normal packets
|
||||
if(sub_protocol == HOTT_SYNC)
|
||||
packet[29] = ((HOTT_sensor_seq+1)<<3) | 2; // Telemetry packet sequence
|
||||
else
|
||||
packet[29] = 0x02;
|
||||
//debugln("28=%02X,29=%02X",packet[28],packet[29]);
|
||||
}
|
||||
//debugln("28=%02X,29=%02X",packet[28],packet[29]);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
packet[28] = 0x80; // no sensor
|
||||
packet[29] = 0x02; // unknown 0x02 when bind starts then when RX replies cycle in sequence 0x1A/22/2A/0A/12, 0x02 during normal packets, 0x01->text config menu, 0x0A->no more RX telemetry
|
||||
}
|
||||
|
||||
CC2500_WriteReg(CC2500_06_PKTLEN, HOTT_TX_PACKET_LEN);
|
||||
CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, packet, HOTT_TX_PACKET_LEN);
|
||||
@@ -277,7 +277,7 @@ static void __attribute__((unused)) HOTT_prep_data_packet()
|
||||
rf_ch_num=hopping_frequency[hopping_frequency_no];
|
||||
}
|
||||
|
||||
uint16_t ReadHOTT()
|
||||
uint16_t HOTT_callback()
|
||||
{
|
||||
switch(phase)
|
||||
{
|
||||
@@ -350,7 +350,7 @@ uint16_t ReadHOTT()
|
||||
CC2500_Strobe(CC2500_SFRX);
|
||||
//RX
|
||||
if(packet[29] & 0xF8)
|
||||
{// binary telemetry
|
||||
{// Sync telemetry
|
||||
CC2500_WriteReg(CC2500_04_SYNC1, 0x2C);
|
||||
CC2500_WriteReg(CC2500_05_SYNC0, 0x6E);
|
||||
}
|
||||
@@ -383,7 +383,7 @@ uint16_t ReadHOTT()
|
||||
for(uint8_t i=0; i<5; i++)
|
||||
eeprom_write_byte((EE_ADDR)(addr+i),packet_in[5+i]);
|
||||
BIND_DONE;
|
||||
HOTT_init();
|
||||
HOTT_TXID_init();
|
||||
}
|
||||
#ifdef HOTT_FW_TELEMETRY
|
||||
else
|
||||
@@ -413,8 +413,10 @@ uint16_t ReadHOTT()
|
||||
packet_in[0]= packet_in[HOTT_RX_PACKET_LEN];
|
||||
packet_in[1]= TX_LQI;
|
||||
bool send_telem=true;
|
||||
if(packet[29]==1)
|
||||
HOTT_sensor_seq++; // Increment RX sequence counter
|
||||
if(packet[29] & 1)
|
||||
{ //Text mode
|
||||
HOTT_sensor_seq %= 19; // 19 pages in Text mode
|
||||
HOTT_sensor_pages = 0;
|
||||
HOTT_sensor_valid = false;
|
||||
packet_in[10] = 0x80; // Marking telem Text mode
|
||||
@@ -424,7 +426,6 @@ uint16_t ReadHOTT()
|
||||
}
|
||||
else
|
||||
{ //Binary sensor
|
||||
HOTT_sensor_seq++; // Increment RX sequence counter
|
||||
HOTT_sensor_seq %= 5; // 5 pages in binary mode per sensor
|
||||
if(state==0 && HOTT_sensor_ok[0]==false && HOTT_sensor_ok[1]==false && HOTT_sensor_ok[2]==false && HOTT_sensor_ok[3]==false && HOTT_sensor_ok[4]==false && HOTT_sensor_ok[5]==false)
|
||||
HOTT_sensor_seq=0; // No sensors always ask page 0
|
||||
@@ -509,10 +510,10 @@ uint16_t ReadHOTT()
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t initHOTT()
|
||||
void HOTT_init()
|
||||
{
|
||||
num_ch=random(0xfefefefe)%16;
|
||||
HOTT_init();
|
||||
HOTT_TXID_init();
|
||||
HOTT_rf_init();
|
||||
#ifdef HOTT_FW_TELEMETRY
|
||||
HoTT_SerialRX_val=0;
|
||||
@@ -527,7 +528,6 @@ uint16_t initHOTT()
|
||||
state=HOTT_SENSOR_SEARCH_PERIOD;
|
||||
#endif
|
||||
phase = HOTT_START;
|
||||
return 10000;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -41,7 +41,7 @@ static void __attribute__((unused)) HEIGHT_build_packet()
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t ReadHeight()
|
||||
uint16_t HEIGHT_callback()
|
||||
{
|
||||
#ifndef FORCE_HEIGHT_TUNING
|
||||
A7105_AdjustLOBaseFreq(1);
|
||||
@@ -78,7 +78,7 @@ uint16_t ReadHeight()
|
||||
return 1500;
|
||||
}
|
||||
|
||||
uint16_t initHeight()
|
||||
void HEIGHT_init()
|
||||
{
|
||||
A7105_Init();
|
||||
|
||||
@@ -94,7 +94,6 @@ uint16_t initHeight()
|
||||
|
||||
phase=255;
|
||||
bind_counter = HEIGHT_BIND_COUNT;
|
||||
return 2400;
|
||||
}
|
||||
#endif
|
||||
// Normal packet is 8 bytes: 0xA5 0xAF 0x59 0x84 0x7A 0x00 0x80 0xFF
|
||||
|
||||
@@ -24,44 +24,7 @@
|
||||
//
|
||||
uint8_t bind_buf_arry[4][10];
|
||||
|
||||
// HiSky protocol uses TX id as an address for nRF24L01, and uses frequency hopping sequence
|
||||
// which does not depend on this id and is passed explicitly in binding sequence. So we are free
|
||||
// to generate this sequence as we wish. It should be in the range [02..77]
|
||||
static void __attribute__((unused)) calc_fh_channels()
|
||||
{
|
||||
uint8_t idx = 0;
|
||||
uint32_t rnd = MProtocol_id;
|
||||
|
||||
while (idx < HISKY_FREQUENCE_NUM)
|
||||
{
|
||||
uint8_t i;
|
||||
uint8_t count_2_26 = 0, count_27_50 = 0, count_51_74 = 0;
|
||||
|
||||
rnd = rnd * 0x0019660D + 0x3C6EF35F; // Randomization
|
||||
// Use least-significant byte. 73 is prime, so channels 76..77 are unused
|
||||
uint8_t next_ch = ((rnd >> 8) % 73) + 2;
|
||||
// Keep the distance 2 between the channels - either odd or even
|
||||
if (((next_ch ^ (uint8_t)rx_tx_addr[3]) & 0x01 )== 0)
|
||||
continue;
|
||||
// Check that it's not duplicated and spread uniformly
|
||||
for (i = 0; i < idx; i++) {
|
||||
if(hopping_frequency[i] == next_ch)
|
||||
break;
|
||||
if(hopping_frequency[i] <= 26)
|
||||
count_2_26++;
|
||||
else if (hopping_frequency[i] <= 50)
|
||||
count_27_50++;
|
||||
else
|
||||
count_51_74++;
|
||||
}
|
||||
if (i != idx)
|
||||
continue;
|
||||
if ( (next_ch <= 26 && count_2_26 < 8) || (next_ch >= 27 && next_ch <= 50 && count_27_50 < 8) || (next_ch >= 51 && count_51_74 < 8) )
|
||||
hopping_frequency[idx++] = next_ch;//find hopping frequency
|
||||
}
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) build_binding_packet(void)
|
||||
static void __attribute__((unused)) HISKY_build_binding_packet(void)
|
||||
{
|
||||
uint8_t i;
|
||||
uint16_t sum=0;
|
||||
@@ -95,28 +58,21 @@ static void __attribute__((unused)) build_binding_packet(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) hisky_init()
|
||||
static void __attribute__((unused)) HISKY_RF_init()
|
||||
{
|
||||
NRF24L01_Initialize();
|
||||
|
||||
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowledgement
|
||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable p0 rx
|
||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5-byte RX/TX address (byte -2)
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, 81); // binding packet must be set in channel 81
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, rx_tx_addr, 5);
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, rx_tx_addr, 5);
|
||||
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, 10); // payload size = 10
|
||||
if(sub_protocol==HK310)
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_250K); // 250Kbps
|
||||
else
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps
|
||||
NRF24L01_SetPower(); // Set power
|
||||
NRF24L01_SetTxRxMode(TX_EN); // TX mode, 2-bytes CRC, radio on
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_250K); // 250Kbps
|
||||
}
|
||||
|
||||
// HiSky channel sequence: AILE ELEV THRO RUDD GEAR PITCH, channel data value is from 0 to 1000
|
||||
// Channel 7 - Gyro mode, 0 - 6 axis, 3 - 3 axis
|
||||
static void __attribute__((unused)) build_ch_data()
|
||||
static void __attribute__((unused)) HISKY_build_ch_data()
|
||||
{
|
||||
uint16_t temp;
|
||||
uint8_t i,j;
|
||||
@@ -133,7 +89,7 @@ static void __attribute__((unused)) build_ch_data()
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t hisky_cb()
|
||||
uint16_t HISKY_callback()
|
||||
{
|
||||
phase++;
|
||||
if(sub_protocol==HK310)
|
||||
@@ -223,7 +179,7 @@ uint16_t hisky_cb()
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(9000);
|
||||
#endif
|
||||
build_ch_data();
|
||||
HISKY_build_ch_data();
|
||||
break;
|
||||
case 8:
|
||||
break;
|
||||
@@ -236,7 +192,7 @@ uint16_t hisky_cb()
|
||||
return 1000; // send 1 binding packet and 1 data packet per 9ms
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) initialize_tx_id()
|
||||
static void __attribute__((unused)) HISKY_initialize_tx_id()
|
||||
{
|
||||
//Generate frequency hopping table
|
||||
if(sub_protocol==HK310)
|
||||
@@ -248,14 +204,17 @@ static void __attribute__((unused)) initialize_tx_id()
|
||||
hopping_frequency[i]=hopping_frequency_no++; // Sequential order hop channels...
|
||||
}
|
||||
else
|
||||
calc_fh_channels();
|
||||
calc_fh_channels(HISKY_FREQUENCE_NUM);
|
||||
// HiSky air protocol uses TX id as an address for nRF24L01, and uses frequency hopping sequence
|
||||
// which does not depend on this id and is passed explicitly in binding sequence. So we are free
|
||||
// to generate this sequence as we wish. It should be in the range [02..77]
|
||||
}
|
||||
|
||||
uint16_t initHiSky()
|
||||
void HISKY_init()
|
||||
{
|
||||
initialize_tx_id();
|
||||
build_binding_packet();
|
||||
hisky_init();
|
||||
HISKY_initialize_tx_id();
|
||||
HISKY_build_binding_packet();
|
||||
HISKY_RF_init();
|
||||
phase = 0;
|
||||
hopping_frequency_no = 0;
|
||||
binding_idx = 0;
|
||||
@@ -264,7 +223,6 @@ uint16_t initHiSky()
|
||||
bind_counter = HISKY_BIND_COUNT;
|
||||
else
|
||||
bind_counter = 0;
|
||||
return 1000;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -55,7 +55,8 @@ static void __attribute__((unused)) HITEC_CC2500_init()
|
||||
CC2500_WriteReg(i, pgm_read_byte_near(&HITEC_init_values[i]));
|
||||
|
||||
CC2500_WriteReg(CC2500_0C_FSCTRL0, option);
|
||||
|
||||
prev_option = option;
|
||||
|
||||
CC2500_SetTxRxMode(TX_EN);
|
||||
CC2500_SetPower();
|
||||
}
|
||||
@@ -219,7 +220,7 @@ static void __attribute__((unused)) HITEC_send_packet()
|
||||
packet[23] >>= 1; // packet sequence
|
||||
}
|
||||
|
||||
uint16_t ReadHITEC()
|
||||
uint16_t HITEC_callback()
|
||||
{
|
||||
switch(phase)
|
||||
{
|
||||
@@ -389,7 +390,7 @@ uint16_t ReadHITEC()
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t initHITEC()
|
||||
void HITEC_init()
|
||||
{
|
||||
HITEC_RF_channels();
|
||||
#ifdef HITEC_FORCE_ID // ID and channels taken from dump
|
||||
@@ -399,7 +400,6 @@ uint16_t initHITEC()
|
||||
memcpy((void *)hopping_frequency,(void *)"\x00\x3A\x4A\x32\x0C\x58\x2A\x10\x26\x20\x08\x60\x68\x70\x78\x80\x88\x56\x5E\x66\x6E",HITEC_NUM_FREQUENCE);
|
||||
#endif
|
||||
phase = HITEC_START;
|
||||
return 10000;
|
||||
}
|
||||
|
||||
/* Full telemetry
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
#if defined(HONTAI_NRF24L01_INO)
|
||||
|
||||
#include "iface_nrf24l01.h"
|
||||
#include "iface_xn297.h" // mix of nrf and xn297 at 1Mb...
|
||||
|
||||
#define HONTAI_BIND_COUNT 80
|
||||
#define HONTAI_PACKET_PERIOD 13500
|
||||
@@ -34,40 +34,21 @@ enum{
|
||||
HONTAI_FLAG_CALIBRATE = 0x20,
|
||||
};
|
||||
|
||||
// proudly swiped from http://www.drdobbs.com/implementing-the-ccitt-cyclical-redundan/199904926
|
||||
#define HONTAI_POLY 0x8408
|
||||
static void __attribute__((unused)) crc16(uint8_t *data_p, uint8_t length)
|
||||
static void __attribute__((unused)) HONTAI_send_packet()
|
||||
{
|
||||
crc = 0xffff;
|
||||
|
||||
length -= 2;
|
||||
do
|
||||
{
|
||||
for (uint8_t i = 0, data = (uint8_t)*data_p++;
|
||||
i < 8;
|
||||
i++, data >>= 1)
|
||||
{
|
||||
if ((crc & 0x01) ^ (data & 0x01))
|
||||
crc = (crc >> 1) ^ HONTAI_POLY;
|
||||
else
|
||||
crc >>= 1;
|
||||
}
|
||||
} while (--length);
|
||||
|
||||
crc = ~crc;
|
||||
*data_p++ = crc & 0xff;
|
||||
*data_p = crc >> 8;
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) HONTAI_send_packet(uint8_t bind)
|
||||
{
|
||||
if (bind)
|
||||
if (IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
memcpy(packet, rx_tx_addr, 5);
|
||||
memset(&packet[5], 0, 3);
|
||||
packet_length = HONTAI_BIND_PACKET_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*if(sub_protocol == JJRCX1)
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no++]);
|
||||
else*/
|
||||
XN297_Hopping(hopping_frequency_no++);
|
||||
hopping_frequency_no %= 3;
|
||||
memset(packet,0,HONTAI_PACKET_SIZE);
|
||||
packet[3] = convert_channel_16b_limit(THROTTLE, 0, 127) << 1; // Throttle
|
||||
packet[4] = convert_channel_16b_limit(AILERON, 63, 0); // Aileron
|
||||
@@ -125,60 +106,56 @@ static void __attribute__((unused)) HONTAI_send_packet(uint8_t bind)
|
||||
packet[6] |= GET_FLAG(CH9_SW, 0x40); // Headless
|
||||
break;
|
||||
}
|
||||
packet_length = HONTAI_PACKET_SIZE;
|
||||
}
|
||||
crc16(packet, bind ? HONTAI_BIND_PACKET_SIZE:HONTAI_PACKET_SIZE);
|
||||
|
||||
// CRC 16 bits reflected in and out
|
||||
crc=0xFFFF;
|
||||
for(uint8_t i=0; i< packet_length-2; i++)
|
||||
crc16_update(bit_reverse(packet[i]),8);
|
||||
crc ^= 0xFFFF;
|
||||
packet[packet_length-2]=bit_reverse(crc>>8);
|
||||
packet[packet_length-1]=bit_reverse(crc);
|
||||
|
||||
// Power on, TX mode, 2byte CRC
|
||||
if(sub_protocol == JJRCX1)
|
||||
/*if(sub_protocol == JJRCX1)
|
||||
{
|
||||
NRF24L01_SetPower();
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
else
|
||||
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
||||
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, bind ? HONTAI_RF_BIND_CHANNEL : hopping_frequency[hopping_frequency_no++]);
|
||||
hopping_frequency_no %= 3;
|
||||
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||
NRF24L01_FlushTx();
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||
NRF24L01_FlushTx();
|
||||
}
|
||||
else*/
|
||||
{
|
||||
XN297_SetPower();
|
||||
XN297_SetTxRxMode(TX_EN);
|
||||
}
|
||||
|
||||
if(sub_protocol == JJRCX1)
|
||||
NRF24L01_WritePayload(packet, bind ? HONTAI_BIND_PACKET_SIZE:HONTAI_PACKET_SIZE);
|
||||
NRF24L01_WritePayload(packet, packet_length);
|
||||
else
|
||||
XN297_WritePayload(packet, bind ? HONTAI_BIND_PACKET_SIZE:HONTAI_PACKET_SIZE);
|
||||
|
||||
NRF24L01_SetPower();
|
||||
XN297_WritePayload(packet, packet_length);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) HONTAI_init()
|
||||
static void __attribute__((unused)) HONTAI_RF_init()
|
||||
{
|
||||
NRF24L01_Initialize();
|
||||
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
|
||||
if(sub_protocol == JJRCX1)
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, (uint8_t*)"\xd2\xb5\x99\xb3\x4a", 5);
|
||||
else
|
||||
XN297_SetTXAddr((const uint8_t*)"\xd2\xb5\x99\xb3\x4a", 5);
|
||||
|
||||
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_SetBitrate(NRF24L01_BR_1M); // 1Mbps
|
||||
NRF24L01_SetPower();
|
||||
NRF24L01_Activate(0x73); // Activate feature register
|
||||
XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M); // this will select the nrf and initialize it, therefore both sub protocols can use common instructions
|
||||
if(sub_protocol == JJRCX1)
|
||||
{
|
||||
//NRF24L01_Initialize();
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, (uint8_t*)"\xd2\xb5\x99\xb3\x4a", 5);
|
||||
NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0xff); // JJRC uses dynamic payload length
|
||||
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x3f); // match other stock settings even though AA disabled...
|
||||
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x07);
|
||||
//NRF24L01_WriteReg(NRF24L01_05_RF_CH, HONTAI_RF_BIND_CHANNEL);
|
||||
}
|
||||
else
|
||||
{
|
||||
NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x00); // no retransmits
|
||||
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x00); // Disable dynamic payload length on all pipes
|
||||
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x00);
|
||||
XN297_SetTXAddr((const uint8_t*)"\xd2\xb5\x99\xb3\x4a", 5);
|
||||
//XN297_HoppingCalib(3);
|
||||
}
|
||||
NRF24L01_Activate(0x73); // Deactivate feature register
|
||||
XN297_RFChannel(HONTAI_RF_BIND_CHANNEL);
|
||||
}
|
||||
|
||||
const uint8_t PROGMEM HONTAI_hopping_frequency_nonels[][3] = {
|
||||
@@ -202,9 +179,9 @@ static void __attribute__((unused)) HONTAI_init2()
|
||||
data_tx_addr[3] = pgm_read_byte_near( &HONTAI_addr_vals[3][(rx_tx_addr[4] >> 4) & 0x0f]);
|
||||
data_tx_addr[4] = 0x24;
|
||||
if(sub_protocol == JJRCX1)
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, data_tx_addr, sizeof(data_tx_addr));
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, data_tx_addr, 5);
|
||||
else
|
||||
XN297_SetTXAddr(data_tx_addr, sizeof(data_tx_addr));
|
||||
XN297_SetTXAddr(data_tx_addr, 5);
|
||||
|
||||
//Hopping frequency table
|
||||
for(uint8_t i=0;i<3;i++)
|
||||
@@ -231,9 +208,11 @@ static void __attribute__((unused)) HONTAI_initialize_txid()
|
||||
|
||||
uint16_t HONTAI_callback()
|
||||
{
|
||||
if(bind_counter!=0)
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(packet_period);
|
||||
#endif
|
||||
if(bind_counter)
|
||||
{
|
||||
HONTAI_send_packet(1);
|
||||
bind_counter--;
|
||||
if (bind_counter == 0)
|
||||
{
|
||||
@@ -241,24 +220,16 @@ uint16_t HONTAI_callback()
|
||||
BIND_DONE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(packet_period);
|
||||
#endif
|
||||
HONTAI_send_packet(0);
|
||||
}
|
||||
|
||||
HONTAI_send_packet();
|
||||
return packet_period;
|
||||
}
|
||||
|
||||
uint16_t initHONTAI()
|
||||
void HONTAI_init()
|
||||
{
|
||||
BIND_IN_PROGRESS; // autobind protocol
|
||||
bind_counter = HONTAI_BIND_COUNT;
|
||||
HONTAI_initialize_txid();
|
||||
HONTAI_init();
|
||||
HONTAI_RF_init();
|
||||
packet_period = sub_protocol == FQ777_951 ? FQ777_951_PACKET_PERIOD : HONTAI_PACKET_PERIOD;
|
||||
return HONTAI_INITIAL_WAIT;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -285,7 +285,7 @@ static uint8_t __attribute__((unused)) hubsan_check_integrity()
|
||||
}
|
||||
#endif
|
||||
|
||||
uint16_t ReadHubsan()
|
||||
uint16_t HUBSAN_callback()
|
||||
{
|
||||
#ifdef HUBSAN_HUB_TELEMETRY
|
||||
static uint8_t rfMode=0;
|
||||
@@ -446,7 +446,7 @@ uint16_t ReadHubsan()
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t initHubsan()
|
||||
void HUBSAN_init()
|
||||
{
|
||||
const uint8_t allowed_ch[] = {0x14, 0x1e, 0x28, 0x32, 0x3c, 0x46, 0x50, 0x5a, 0x64, 0x6e, 0x78, 0x82};
|
||||
A7105_Init();
|
||||
@@ -467,7 +467,6 @@ uint16_t initHubsan()
|
||||
}
|
||||
packet_count=0;
|
||||
bind_phase=0;
|
||||
return 10000;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
122
Multiprotocol/IKEA_Ansluta_cc2500.ino
Normal file
122
Multiprotocol/IKEA_Ansluta_cc2500.ino
Normal file
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
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/>.
|
||||
*/
|
||||
// This module makes it possible to bind to and control the IKEA "Ansluta" line
|
||||
// of remote-controlled lights.
|
||||
// To bind, first switch the receiver into binding mode, then the TX.
|
||||
// Once bound, the TX can send one of three commands:
|
||||
// lights off, lights dimmed 50% and lights on.
|
||||
// Those are mapped to throttle ranges 0..0x55, 0x56..0xAA, 0xAB..0xFF.
|
||||
#if defined(IKEAANSLUTA_CC2500_INO)
|
||||
|
||||
#include "iface_cc2500.h"
|
||||
|
||||
#define IKEAANSLUTA_BIND_COUNT 30 // ~ 2sec autobind/65ms per loop = 30 binding packets
|
||||
|
||||
// Commands
|
||||
#define IKEAANSLUTA_LIGHT_OFF 0x01
|
||||
#define IKEAANSLUTA_LIGHT_DIM 0x02 // 50% dimmed light
|
||||
#define IKEAANSLUTA_LIGHT_ON 0x03
|
||||
#define IKEAANSLUTA_PAIR 0xFF
|
||||
|
||||
void IKEAANSLUTA_send_command(uint8_t command){
|
||||
CC2500_Strobe(CC2500_SIDLE);
|
||||
packet[4] = option;
|
||||
packet[5] = command;
|
||||
CC2500_WriteData(packet, 8);
|
||||
}
|
||||
|
||||
uint16_t IKEAANSLUTA_callback(void)
|
||||
{
|
||||
if (bind_counter) {
|
||||
IKEAANSLUTA_send_command(IKEAANSLUTA_PAIR);
|
||||
if(--bind_counter == 0) {
|
||||
BIND_DONE;
|
||||
CC2500_SetPower();
|
||||
}
|
||||
}
|
||||
else {
|
||||
uint8_t throttle = convert_channel_8b(THROTTLE);
|
||||
uint8_t cmd = throttle <= 0x55 ? IKEAANSLUTA_LIGHT_OFF :
|
||||
throttle <= 0xAA ? IKEAANSLUTA_LIGHT_DIM :
|
||||
IKEAANSLUTA_LIGHT_ON;
|
||||
IKEAANSLUTA_send_command(cmd);
|
||||
}
|
||||
return 65535; // 65ms loop cycle is more than enough here (we could make it even longer if not for uint16_t)
|
||||
}
|
||||
|
||||
// Register initialization values as a continuous memory block (to save on flash memory)
|
||||
const PROGMEM uint8_t IKEAANSLUTA_init_values[] = {
|
||||
0xFF, // CC2500_06_PKTLEN
|
||||
0x04, // CC2500_07_PKTCTRL1
|
||||
0x05, // CC2500_08_PKTCTRL0
|
||||
0x00, // CC2500_09_ADDR (unused, default)
|
||||
0x10, // CC2500_0A_CHANNR
|
||||
0x09, // CC2500_0B_FSCTRL1
|
||||
0x00, // CC2500_0C_FSCTRL0
|
||||
0x5D, // CC2500_0D_FREQ2
|
||||
0x93, // CC2500_0E_FREQ1
|
||||
0xB1, // CC2500_0F_FREQ0
|
||||
0x2D, // CC2500_10_MDMCFG4
|
||||
0x3B, // CC2500_11_MDMCFG3
|
||||
0x73, // CC2500_12_MDMCFG2
|
||||
0xA2, // CC2500_13_MDMCFG1
|
||||
0xF8, // CC2500_14_MDMCFG0
|
||||
0x01, // CC2500_15_DEVIATN
|
||||
0x07, // CC2500_16_MCSM2
|
||||
0x30, // CC2500_17_MCSM1
|
||||
0x18, // CC2500_18_MCSM0
|
||||
0x1D, // CC2500_19_FOCCFG
|
||||
0x1C, // CC2500_1A_BSCFG
|
||||
0xC7, // CC2500_1B_AGCCTRL2
|
||||
0x00, // CC2500_1C_AGCCTRL1
|
||||
0xB2, // CC2500_1D_AGCCTRL0
|
||||
0x87, // CC2500_1E_WOREVT1 (unused, default)
|
||||
0x6b, // CC2500_1F_WOREVT0 (unused, default)
|
||||
0xf8, // CC2500_20_WORCTRL (unused, default)
|
||||
0xB6, // CC2500_21_FREND1
|
||||
0x10, // CC2500_22_FREND0
|
||||
0xEA, // CC2500_23_FSCAL3
|
||||
0x0A, // CC2500_24_FSCAL2
|
||||
0x00, // CC2500_25_FSCAL1
|
||||
0x11, // CC2500_26_FSCAL0
|
||||
0x41, // CC2500_27_RCCTRL1
|
||||
0x00, // CC2500_28_RCCTRL0
|
||||
};
|
||||
|
||||
void IKEAANSLUTA_init(void)
|
||||
{
|
||||
if (IS_BIND_DONE) bind_counter = 0;
|
||||
else bind_counter = IKEAANSLUTA_BIND_COUNT;
|
||||
|
||||
// All packets we send are the same
|
||||
packet[0] = 0x06;
|
||||
packet[1] = 0x55;
|
||||
packet[2] = 0x01;
|
||||
// Bytes 3&4 are the transmitter address (to which the RX binds)
|
||||
// Byte 5 is the command.
|
||||
packet[3] = rx_tx_addr[3]; // <pseudorandom tx-fixed value> + <rx_num>
|
||||
// packet[4] = option;
|
||||
// packet[5] = 0x00; // Command goes here
|
||||
packet[6] = 0xAA;
|
||||
packet[7] = 0xFF;
|
||||
|
||||
// Configure & initialize CC2500
|
||||
for (uint8_t i = 0; i <= CC2500_28_RCCTRL0-CC2500_06_PKTLEN; ++i)
|
||||
CC2500_WriteReg(CC2500_06_PKTLEN+i, pgm_read_byte_near(&IKEAANSLUTA_init_values[i]));
|
||||
CC2500_SetTxRxMode(TX_EN);
|
||||
CC2500_SetPower();
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -126,7 +126,7 @@ static void __attribute__((unused)) j6pro_set_radio_channels()
|
||||
hopping_frequency[3] = hopping_frequency[0];
|
||||
}
|
||||
|
||||
uint16_t ReadJ6Pro()
|
||||
uint16_t J6PRO_callback()
|
||||
{
|
||||
uint16_t start;
|
||||
|
||||
@@ -226,7 +226,7 @@ uint16_t ReadJ6Pro()
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t initJ6Pro()
|
||||
void J6PRO_init()
|
||||
{
|
||||
j6pro_cyrf_init();
|
||||
|
||||
@@ -234,7 +234,6 @@ uint16_t initJ6Pro()
|
||||
phase = J6PRO_BIND;
|
||||
else
|
||||
phase = J6PRO_CHANSEL;
|
||||
return 2400;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
#if defined(JJRC345_NRF24L01_INO)
|
||||
|
||||
#include "iface_nrf24l01.h"
|
||||
#include "iface_xn297.h"
|
||||
|
||||
//#define JJRC345_FORCE_ID
|
||||
|
||||
@@ -71,7 +71,7 @@ static void __attribute__((unused)) JJRC345_send_packet()
|
||||
}
|
||||
else
|
||||
{ //00 41 00 0A 00 80 80 80 00 00 40 46 00 49 F1 18
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no]);
|
||||
XN297_Hopping(hopping_frequency_no);
|
||||
hopping_frequency_no++;
|
||||
hopping_frequency_no %= JJRC345_NUM_CHANNELS;
|
||||
packet[1] = hopping_frequency[hopping_frequency_no]; // next packet will be sent on this channel
|
||||
@@ -121,28 +121,18 @@ static void __attribute__((unused)) JJRC345_send_packet()
|
||||
packet[14] = rx_tx_addr[2];
|
||||
packet[15] = rx_tx_addr[3];
|
||||
|
||||
// Power on, TX mode
|
||||
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||
NRF24L01_FlushTx();
|
||||
// Send
|
||||
XN297_SetPower();
|
||||
XN297_SetTxRxMode(TX_EN);
|
||||
XN297_WritePayload(packet, JJRC345_PACKET_SIZE);
|
||||
|
||||
NRF24L01_SetPower(); // Set tx_power
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) JJRC345_init()
|
||||
static void __attribute__((unused)) JJRC345_RF_init()
|
||||
{
|
||||
NRF24L01_Initialize();
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M);
|
||||
XN297_SetTXAddr((uint8_t*)"\xcc\xcc\xcc\xcc\xcc", 5);
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, sub_protocol == JJRC345 ? JJRC345_RF_BIND_CHANNEL:SKYTMBLR_RF_BIND_CHANNEL); // Bind channel
|
||||
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); // 1 Mbps
|
||||
NRF24L01_SetPower();
|
||||
//XN297_HoppingCalib(JJRC345_NUM_CHANNELS);
|
||||
XN297_RFChannel(sub_protocol == JJRC345 ? JJRC345_RF_BIND_CHANNEL:SKYTMBLR_RF_BIND_CHANNEL); // Bind channel
|
||||
}
|
||||
|
||||
uint16_t JJRC345_callback()
|
||||
@@ -150,11 +140,10 @@ uint16_t JJRC345_callback()
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(JJRC345_PACKET_PERIOD);
|
||||
#endif
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
if(bind_counter)
|
||||
{
|
||||
if (bind_counter)
|
||||
bind_counter--;
|
||||
else
|
||||
bind_counter--;
|
||||
if (bind_counter==0)
|
||||
BIND_DONE;
|
||||
}
|
||||
JJRC345_send_packet();
|
||||
@@ -183,13 +172,12 @@ static void __attribute__((unused)) JJRC345_initialize_txid()
|
||||
#endif
|
||||
}
|
||||
|
||||
uint16_t initJJRC345(void)
|
||||
void JJRC345_init(void)
|
||||
{
|
||||
BIND_IN_PROGRESS; // autobind protocol
|
||||
bind_counter = JJRC345_BIND_COUNT;
|
||||
JJRC345_initialize_txid();
|
||||
JJRC345_init();
|
||||
return JJRC345_INITIAL_WAIT;
|
||||
JJRC345_RF_init();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
115
Multiprotocol/Joysway_a7105.ino
Normal file
115
Multiprotocol/Joysway_a7105.ino
Normal file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
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(JOYSWAY_A7105_INO)
|
||||
|
||||
#include "iface_a7105.h"
|
||||
|
||||
//#define JOYSWAY_FORCE_ID
|
||||
|
||||
static void __attribute__((unused)) JOYSWAY_send_packet()
|
||||
{
|
||||
static uint8_t next_ch = 0x30;
|
||||
|
||||
//RF frequency
|
||||
if (packet_count == 254)
|
||||
{
|
||||
packet_count = 0;
|
||||
A7105_WriteID(0x5475c52a);
|
||||
rf_ch_num = 0x0a;
|
||||
}
|
||||
else if (packet_count == 2)
|
||||
{
|
||||
A7105_WriteID(MProtocol_id);
|
||||
rf_ch_num = 0x30;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (packet_count & 0x01)
|
||||
rf_ch_num = 0x30;
|
||||
else
|
||||
rf_ch_num = next_ch;
|
||||
}
|
||||
if (! (packet_count & 0x01))
|
||||
{
|
||||
next_ch++;
|
||||
if (next_ch >= 0x45)
|
||||
next_ch = 0x30;
|
||||
}
|
||||
|
||||
//Payload
|
||||
packet[0] = packet_count == 0 ? 0xdd : 0xff;
|
||||
//ID
|
||||
packet[1] = rx_tx_addr[0];
|
||||
packet[2] = rx_tx_addr[1];
|
||||
packet[3] = rx_tx_addr[2];
|
||||
packet[4] = rx_tx_addr[3];
|
||||
packet[5] = 0x00;
|
||||
//Channels
|
||||
for (uint8_t i = 0; i < 4; i++)
|
||||
packet[ 6 + (i & 0x01) + ((i & 0x02)<<1)] = convert_channel_16b_limit(i, 0x00, 0xCC);
|
||||
packet[8] = 0x64;
|
||||
packet[9] = 0x64;
|
||||
packet[12] = 0x64;
|
||||
packet[13] = 0x64;
|
||||
packet[14] = packet_count == 0 ? 0x30 : 0xaa;
|
||||
//Check
|
||||
uint8_t value = 0;
|
||||
for (uint8_t i = 0; i < 15; i++)
|
||||
value += packet[i];
|
||||
packet[15] = value;
|
||||
|
||||
//Send
|
||||
#if 0
|
||||
debug("ch=%02X P=",rf_ch_num);
|
||||
for(uint8_t i=0; i<16; i++)
|
||||
debug("%02X ", packet[i]);
|
||||
debugln("");
|
||||
#endif
|
||||
A7105_WriteData(16, rf_ch_num);
|
||||
A7105_SetPower();
|
||||
packet_count++;
|
||||
}
|
||||
|
||||
uint16_t JOYSWAY_callback()
|
||||
{
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(6000);
|
||||
#endif
|
||||
#ifndef FORCE_JOYSWAY_TUNING
|
||||
A7105_AdjustLOBaseFreq(1);
|
||||
#endif
|
||||
|
||||
JOYSWAY_send_packet();
|
||||
return 6000;
|
||||
}
|
||||
|
||||
void JOYSWAY_init()
|
||||
{
|
||||
BIND_DONE; // not a bind protocol
|
||||
|
||||
MProtocol_id &= 0x00FFFFFF;
|
||||
MProtocol_id |= 0xF8000000;
|
||||
#ifdef JOYSWAY_FORCE_ID
|
||||
MProtocol_id = 0xf82dcaa0;
|
||||
#endif
|
||||
|
||||
set_rx_tx_addr(MProtocol_id);
|
||||
|
||||
A7105_Init();
|
||||
|
||||
packet_count = 2;
|
||||
}
|
||||
#endif
|
||||
@@ -14,9 +14,9 @@ Multiprotocol is distributed in the hope that it will be useful,
|
||||
*/
|
||||
// Compatible with KF606 plane.
|
||||
|
||||
#if defined(KF606_NRF24L01_INO)
|
||||
#if defined(KF606_CCNRF_INO)
|
||||
|
||||
#include "iface_nrf250k.h"
|
||||
#include "iface_xn297.h"
|
||||
|
||||
//#define FORCE_KF606_ORIGINAL_ID
|
||||
|
||||
@@ -45,14 +45,15 @@ static void __attribute__((unused)) KF606_send_packet()
|
||||
}
|
||||
if(IS_BIND_DONE)
|
||||
{
|
||||
XN297L_Hopping(hopping_frequency_no);
|
||||
XN297_Hopping(hopping_frequency_no);
|
||||
hopping_frequency_no ^= 1; // 2 RF channels
|
||||
}
|
||||
|
||||
XN297L_WritePayload(packet, KF606_PAYLOAD_SIZE);
|
||||
|
||||
XN297L_SetPower(); // Set tx_power
|
||||
XN297L_SetFreqOffset(); // Set frequency offset
|
||||
// Send
|
||||
XN297_SetPower();
|
||||
XN297_SetFreqOffset();
|
||||
XN297_SetTxRxMode(TX_EN);
|
||||
XN297_WritePayload(packet, KF606_PAYLOAD_SIZE);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) KF606_initialize_txid()
|
||||
@@ -76,12 +77,12 @@ static void __attribute__((unused)) KF606_initialize_txid()
|
||||
#endif
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) KF606_init()
|
||||
static void __attribute__((unused)) KF606_RF_init()
|
||||
{
|
||||
XN297L_Init();
|
||||
XN297L_SetTXAddr((uint8_t*)"\xe7\xe7\xe7\xe7\xe7", 5);
|
||||
XN297L_HoppingCalib(KF606_RF_NUM_CHANNELS); // Calibrate all channels
|
||||
XN297L_RFChannel(KF606_RF_BIND_CHANNEL); // Set bind channel
|
||||
XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_250K);
|
||||
XN297_SetTXAddr((uint8_t*)"\xe7\xe7\xe7\xe7\xe7", 5);
|
||||
XN297_HoppingCalib(KF606_RF_NUM_CHANNELS); // Calibrate all channels
|
||||
XN297_RFChannel(KF606_RF_BIND_CHANNEL); // Set bind channel
|
||||
}
|
||||
|
||||
uint16_t KF606_callback()
|
||||
@@ -89,7 +90,7 @@ uint16_t KF606_callback()
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(KF606_PACKET_PERIOD);
|
||||
#endif
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
if(bind_counter)
|
||||
if(--bind_counter==0)
|
||||
{
|
||||
BIND_DONE;
|
||||
@@ -99,14 +100,13 @@ uint16_t KF606_callback()
|
||||
return KF606_PACKET_PERIOD;
|
||||
}
|
||||
|
||||
uint16_t initKF606()
|
||||
void KF606_init()
|
||||
{
|
||||
BIND_IN_PROGRESS; // autobind protocol
|
||||
KF606_initialize_txid();
|
||||
KF606_init();
|
||||
KF606_RF_init();
|
||||
hopping_frequency_no = 0;
|
||||
bind_counter=KF606_BIND_COUNT;
|
||||
return KF606_INITIAL_WAIT;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -239,40 +239,25 @@ static void __attribute__((unused)) kn_calculate_freqency_hopping_channels()
|
||||
// V977 needs payload length in the packet. We should configure 24L01 to enable Packet Control Field(PCF)
|
||||
// Some RX reg settings are actually for enable PCF
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
static void __attribute__((unused)) kn_init()
|
||||
static void __attribute__((unused)) KN_RF_init()
|
||||
{
|
||||
kn_calculate_tx_addr();
|
||||
kn_calculate_freqency_hopping_channels();
|
||||
|
||||
NRF24L01_Initialize();
|
||||
|
||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO));
|
||||
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknoledgement
|
||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0
|
||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5-byte RX/TX address
|
||||
NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0); // Disable retransmit
|
||||
NRF24L01_SetPower();
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
|
||||
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, 0x20); // bytes of data payload for pipe 0
|
||||
|
||||
|
||||
NRF24L01_Activate(0x73);
|
||||
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 1); // Dynamic payload for data pipe 0
|
||||
// Enable: Dynamic Payload Length to enable PCF
|
||||
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, _BV(NRF2401_1D_EN_DPL));
|
||||
|
||||
NRF24L01_SetPower();
|
||||
|
||||
NRF24L01_FlushTx();
|
||||
// Turn radio power on
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_1M); //USE1MBPS_YES ? NRF24L01_BR_1M : NRF24L01_BR_250K;
|
||||
NRF24L01_SetTxRxMode(TX_EN); // Clear data ready, data sent, retransmit and enable CRC 16bits, ready for TX
|
||||
}
|
||||
|
||||
//================================================================================================
|
||||
// Private Functions
|
||||
//================================================================================================
|
||||
uint16_t initKN()
|
||||
void KN_init()
|
||||
{
|
||||
if(sub_protocol==WLTOYS)
|
||||
{
|
||||
@@ -288,13 +273,11 @@ uint16_t initKN()
|
||||
packet_count = KN_FX_PACKET_SEND_COUNT;
|
||||
seed = KN_FX_PACKET_SEND_COUNT * KN_FX_SENDING_PACKET_PERIOD;
|
||||
}
|
||||
kn_init();
|
||||
KN_RF_init();
|
||||
phase = IS_BIND_IN_PROGRESS ? KN_PHASE_PRE_BIND : KN_PHASE_PRE_SEND;
|
||||
|
||||
return KN_INIT_WAIT_MS;
|
||||
}
|
||||
|
||||
uint16_t kn_callback()
|
||||
uint16_t KN_callback()
|
||||
{
|
||||
switch (phase)
|
||||
{
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
//Kyosho constants & variables
|
||||
#define KYOSHO_BIND_COUNT 2500
|
||||
|
||||
static void __attribute__((unused)) kyosho_send_packet()
|
||||
static void __attribute__((unused)) KYOSHO_send_packet()
|
||||
{
|
||||
//ID
|
||||
packet[1] = rx_tx_addr[0];
|
||||
@@ -77,7 +77,7 @@ static void __attribute__((unused)) kyosho_send_packet()
|
||||
A7105_WriteData(37, rf_ch_num);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) kyosho_hype_send_packet()
|
||||
static void __attribute__((unused)) KYOSHO_hype_send_packet()
|
||||
{
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
@@ -124,7 +124,7 @@ static void __attribute__((unused)) kyosho_hype_send_packet()
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t ReadKyosho()
|
||||
uint16_t KYOSHO_callback()
|
||||
{
|
||||
#ifndef FORCE_KYOSHO_TUNING
|
||||
A7105_AdjustLOBaseFreq(1);
|
||||
@@ -151,13 +151,13 @@ uint16_t ReadKyosho()
|
||||
#endif
|
||||
}
|
||||
if(sub_protocol==KYOSHO_FHSS)
|
||||
kyosho_send_packet();
|
||||
KYOSHO_send_packet();
|
||||
else//HYPE
|
||||
kyosho_hype_send_packet();
|
||||
KYOSHO_hype_send_packet();
|
||||
return packet_period;
|
||||
}
|
||||
|
||||
uint16_t initKyosho()
|
||||
void KYOSHO_init()
|
||||
{
|
||||
A7105_Init();
|
||||
|
||||
@@ -197,6 +197,5 @@ uint16_t initKyosho()
|
||||
|
||||
packet_sent=0;
|
||||
packet_period=3852; //FHSS
|
||||
return 2000;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -21,23 +21,14 @@ Multiprotocol is distributed in the hope that it will be useful,
|
||||
#define LOLI_PACKET_SIZE 11
|
||||
#define LOLI_NUM_CHANNELS 5
|
||||
|
||||
static void __attribute__((unused)) LOLI_init()
|
||||
static void __attribute__((unused)) LOLI_RF_init()
|
||||
{
|
||||
NRF24L01_Initialize();
|
||||
NRF24L01_FlushTx();
|
||||
NRF24L01_FlushRx();
|
||||
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_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5-bytes RX/TX address
|
||||
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, (uint8_t*)"LOVE!", 5);
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, (uint8_t*)"LOVE!", 5);
|
||||
NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x00); // No retransmits
|
||||
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, LOLI_PACKET_SIZE); // RX FIFO size
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_250K); // 250Kbps
|
||||
|
||||
NRF24L01_SetPower();
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
}
|
||||
|
||||
// flags going to packet[1] for packet type 0xa2 (Rx config)
|
||||
@@ -175,14 +166,11 @@ uint16_t LOLI_callback()
|
||||
{
|
||||
case LOLI_BIND1:
|
||||
if(bind_counter)
|
||||
{
|
||||
bind_counter--;
|
||||
if(bind_counter==0)
|
||||
if(--bind_counter==0)
|
||||
{
|
||||
phase=LOLI_PREP_DATA;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// send bind packet
|
||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
@@ -290,7 +278,7 @@ uint16_t LOLI_callback()
|
||||
return 20000;
|
||||
}
|
||||
|
||||
uint16_t initLOLI()
|
||||
void LOLI_init()
|
||||
{
|
||||
rx_tx_addr[1] %= 0x30;
|
||||
calc_fh_channels(LOLI_NUM_CHANNELS);
|
||||
@@ -306,9 +294,7 @@ uint16_t initLOLI()
|
||||
else
|
||||
phase = LOLI_PREP_DATA;
|
||||
|
||||
LOLI_init();
|
||||
|
||||
return 500;
|
||||
LOLI_RF_init();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
147
Multiprotocol/Losi_cyrf6936.ino
Normal file
147
Multiprotocol/Losi_cyrf6936.ino
Normal file
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
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(LOSI_CYRF6936_INO)
|
||||
|
||||
#include "iface_cyrf6936.h"
|
||||
|
||||
#define LOSI_FORCE_ID
|
||||
|
||||
const uint8_t PROGMEM LOSI_bind_sop_code[] = {0x62, 0xdf, 0xc1, 0x49, 0xdf, 0xb1, 0xc0, 0x49};
|
||||
const uint8_t LOSI_data_code[][16] = {
|
||||
{ 0xD7, 0xA1, 0x54, 0xB1, 0x5E, 0x89, 0xAE, 0x86, 0xC9, 0x2C, 0x06, 0x93, 0x86, 0xB9, 0x9E, 0xD7 }, //bind
|
||||
/* { 0xE1, 0xD6, 0x31, 0x26, 0x5F, 0xBD, 0x40, 0x93, 0xDC, 0x68, 0x08, 0x99, 0x97, 0xAE, 0xAF, 0x8C },
|
||||
{ 0xDC, 0x68, 0x08, 0x99, 0x97, 0xAE, 0xAF, 0x8C, 0xC3, 0x0E, 0x01, 0x16, 0x0E, 0x32, 0x06, 0xBA },
|
||||
{ 0xC3, 0x0E, 0x01, 0x16, 0x0E, 0x32, 0x06, 0xBA, 0xE0, 0x83, 0x01, 0xFA, 0xAB, 0x3E, 0x8F, 0xAC },
|
||||
{ 0xE0, 0x83, 0x01, 0xFA, 0xAB, 0x3E, 0x8F, 0xAC, 0x5C, 0xD5, 0x9C, 0xB8, 0x46, 0x9C, 0x7D, 0x84 },
|
||||
{ 0x5C, 0xD5, 0x9C, 0xB8, 0x46, 0x9C, 0x7D, 0x84, 0xF1, 0xC6, 0xFE, 0x5C, 0x9D, 0xA5, 0x4F, 0xB7 },
|
||||
{ 0xF1, 0xC6, 0xFE, 0x5C, 0x9D, 0xA5, 0x4F, 0xB7, 0x58, 0xB5, 0xB3, 0xDD, 0x0E, 0x28, 0xF1, 0xB0 },
|
||||
{ 0x58, 0xB5, 0xB3, 0xDD, 0x0E, 0x28, 0xF1, 0xB0, 0x5F, 0x30, 0x3B, 0x56, 0x96, 0x45, 0xF4, 0xA1 },*/
|
||||
{ 0x5F, 0x30, 0x3B, 0x56, 0x96, 0x45, 0xF4, 0xA1, 0x03, 0xBC, 0x6E, 0x8A, 0xEF, 0xBD, 0xFE, 0xF8 } //normal
|
||||
};
|
||||
|
||||
static uint16_t __attribute__((unused)) LOSI_check(uint16_t val)
|
||||
{
|
||||
const uint8_t PROGMEM tab[] = { 0xF1, 0xDA, 0xB6, 0xC8 };
|
||||
uint8_t res = 0x0B, tmp;
|
||||
uint16_t calc = val>>2; // don't care about the 2 first bits
|
||||
for(uint8_t i=0; i<5; i++)
|
||||
{
|
||||
tmp=pgm_read_byte_near(&tab[i&0x03]);
|
||||
if(calc&0x0001)
|
||||
res ^= tmp>>4;
|
||||
calc >>= 1;
|
||||
if(calc&0x0001)
|
||||
res ^= tmp;
|
||||
calc >>= 1;
|
||||
}
|
||||
return val ^ (res<<12);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) LOSI_send_packet()
|
||||
{
|
||||
memcpy(packet, rx_tx_addr, 4);
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
memcpy(&packet[4], rx_tx_addr, 4);
|
||||
packet[8] = 0x05; // CRC?
|
||||
packet[9] = 0x52; // CRC?
|
||||
}
|
||||
else
|
||||
{
|
||||
for(uint8_t i=0; i<3; i++)
|
||||
{
|
||||
uint16_t val = LOSI_check(Channel_data[i]<<1);
|
||||
packet[4+i*2] = val >> 8;
|
||||
packet[5+i*2] = val;
|
||||
}
|
||||
}
|
||||
|
||||
CYRF_SetPower(0x38);
|
||||
CYRF_WriteDataPacketLen(packet, 0x0A);
|
||||
#if 0
|
||||
for(uint8_t i=0; i < 0x0A; i++)
|
||||
debug("%02X ", packet[i]);
|
||||
debugln();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) LOSI_cyrf_init()
|
||||
{
|
||||
/* Initialise CYRF chip */
|
||||
CYRF_WriteRegister(CYRF_28_CLK_EN, 0x02);
|
||||
CYRF_WriteRegister(CYRF_32_AUTO_CAL_TIME, 0x3C);
|
||||
CYRF_WriteRegister(CYRF_35_AUTOCAL_OFFSET, 0x14);
|
||||
CYRF_WriteRegister(CYRF_06_RX_CFG, 0x48);
|
||||
CYRF_WriteRegister(CYRF_1B_TX_OFFSET_LSB, 0x55);
|
||||
CYRF_WriteRegister(CYRF_1C_TX_OFFSET_MSB, 0x05);
|
||||
//CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x24);
|
||||
CYRF_SetPower(0x38);
|
||||
CYRF_WriteRegister(CYRF_12_DATA64_THOLD, 0x0A);
|
||||
CYRF_WriteRegister(CYRF_39_ANALOG_CTRL, 0x01);
|
||||
CYRF_WritePreamble(0x333304);
|
||||
//CYRF_WriteRegister(CYRF_27_CLK_OVERRIDE, 0x00);
|
||||
CYRF_WriteRegister(CYRF_10_FRAMING_CFG, 0x4A);
|
||||
CYRF_WriteRegister(CYRF_1F_TX_OVERRIDE, 0x04); // No CRC
|
||||
//CYRF_WriteRegister(CYRF_1E_RX_OVERRIDE, 0x14);
|
||||
//CYRF_WriteRegister(CYRF_14_EOP_CTRL, 0x02);
|
||||
}
|
||||
|
||||
uint16_t LOSI_callback()
|
||||
{
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(19738);
|
||||
#endif
|
||||
LOSI_send_packet();
|
||||
if(bind_counter)
|
||||
{
|
||||
bind_counter--;
|
||||
if(bind_counter==0)
|
||||
{
|
||||
BIND_DONE;
|
||||
CYRF_ConfigDataCode(LOSI_data_code[1], 16); // Load normal data code
|
||||
}
|
||||
return 8763;
|
||||
}
|
||||
return 19738;
|
||||
}
|
||||
|
||||
void LOSI_init()
|
||||
{
|
||||
LOSI_cyrf_init();
|
||||
//CYRF_FindBestChannels(hopping_frequency, 1, 0, 0x13, 75); // 75 is unknown since dump stops at 0x27, this routine resets the CRC Seed to 0
|
||||
//CYRF_ConfigRFChannel(hopping_frequency[0] | 1); // Only odd channels
|
||||
|
||||
#ifdef LOSI_FORCE_ID
|
||||
rx_tx_addr[0] = 0x47;
|
||||
rx_tx_addr[1] = 0x52;
|
||||
rx_tx_addr[2] = 0xAE;
|
||||
rx_tx_addr[3] = 0xAA;
|
||||
CYRF_ConfigRFChannel(0x27);
|
||||
#endif
|
||||
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
bind_counter = 300;
|
||||
CYRF_ConfigDataCode(LOSI_data_code[0], 16); // Load bind data code
|
||||
}
|
||||
else
|
||||
{
|
||||
CYRF_ConfigDataCode(LOSI_data_code[1], 16); // Load normal data code
|
||||
bind_counter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -15,10 +15,9 @@
|
||||
// compatible with MJX WLH08, X600, X800, H26D, Eachine E010
|
||||
// Last sync with hexfet new_protocols/mjxq_nrf24l01.c dated 2016-01-17
|
||||
|
||||
#if defined(MJXQ_NRF24L01_INO)
|
||||
#if defined(MJXQ_CCNRF_INO)
|
||||
|
||||
#include "iface_nrf24l01.h"
|
||||
#include "iface_nrf250k.h"
|
||||
#include "iface_xn297.h"
|
||||
|
||||
#define MJXQ_BIND_COUNT 150
|
||||
#define MJXQ_PACKET_PERIOD 4000 // Timeout for callback in uSec
|
||||
@@ -103,6 +102,12 @@ static uint8_t __attribute__((unused)) MJXQ_pan_tilt_value()
|
||||
#define MJXQ_CHAN2TRIM(X) (((X) & 0x80 ? (X) : 0x7f - (X)) >> 1)
|
||||
static void __attribute__((unused)) MJXQ_send_packet(uint8_t bind)
|
||||
{
|
||||
//RF freq
|
||||
hopping_frequency_no++;
|
||||
XN297_Hopping(hopping_frequency_no / 2);
|
||||
hopping_frequency_no %= 2 * MJXQ_RF_NUM_CHANNELS; // channels repeated
|
||||
|
||||
//Build packet
|
||||
packet[0] = convert_channel_8b(THROTTLE);
|
||||
packet[1] = convert_channel_s8b(RUDDER);
|
||||
packet[4] = 0x40; // rudder does not work well with dyntrim
|
||||
@@ -192,38 +197,29 @@ static void __attribute__((unused)) MJXQ_send_packet(uint8_t bind)
|
||||
uint8_t sum = packet[0];
|
||||
for (uint8_t i=1; i < MJXQ_PACKET_SIZE-1; i++) sum += packet[i];
|
||||
packet[15] = sum;
|
||||
hopping_frequency_no++;
|
||||
if (sub_protocol == E010 || sub_protocol == PHOENIX)
|
||||
|
||||
// Send
|
||||
XN297_SetTxRxMode(TX_EN);
|
||||
XN297_SetPower();
|
||||
#ifdef NRF24L01_INSTALLED
|
||||
if (sub_protocol == H26D || sub_protocol == H26WH)
|
||||
{
|
||||
XN297L_Hopping(hopping_frequency_no / 2);
|
||||
XN297L_SetFreqOffset();
|
||||
XN297L_SetPower();
|
||||
XN297L_WritePayload(packet, MJXQ_PACKET_SIZE);
|
||||
//NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no / 2]);
|
||||
//NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||
//NRF24L01_FlushTx();
|
||||
//NRF24L01_SetTxRxMode(TX_EN);
|
||||
//NRF24L01_SetPower();
|
||||
NRF24L01_WritePayload(packet, MJXQ_PACKET_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no / 2]);
|
||||
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||
NRF24L01_FlushTx();
|
||||
|
||||
// Power on, TX mode, 2byte CRC and send packet
|
||||
if (sub_protocol == H26D || sub_protocol == H26WH)
|
||||
{
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
NRF24L01_WritePayload(packet, MJXQ_PACKET_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
||||
XN297_WritePayload(packet, MJXQ_PACKET_SIZE);
|
||||
}
|
||||
NRF24L01_SetPower();
|
||||
#endif
|
||||
{//E010, PHOENIX, WLH08, X600, X800
|
||||
XN297_SetFreqOffset();
|
||||
XN297_WritePayload(packet, MJXQ_PACKET_SIZE);
|
||||
}
|
||||
hopping_frequency_no %= 2 * MJXQ_RF_NUM_CHANNELS; // channels repeated
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) MJXQ_init()
|
||||
static void __attribute__((unused)) MJXQ_RF_init()
|
||||
{
|
||||
uint8_t addr[MJXQ_ADDRESS_LENGTH];
|
||||
memcpy(addr, "\x6d\x6a\x77\x77\x77", MJXQ_ADDRESS_LENGTH);
|
||||
@@ -239,32 +235,20 @@ static void __attribute__((unused)) MJXQ_init()
|
||||
}
|
||||
if (sub_protocol == E010 || sub_protocol == PHOENIX)
|
||||
{
|
||||
XN297L_Init();
|
||||
XN297L_SetTXAddr(addr, sizeof(addr));
|
||||
XN297L_HoppingCalib(MJXQ_RF_NUM_CHANNELS);
|
||||
XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_250K);
|
||||
XN297_SetTXAddr(addr, MJXQ_ADDRESS_LENGTH);
|
||||
XN297_HoppingCalib(MJXQ_RF_NUM_CHANNELS);
|
||||
}
|
||||
else
|
||||
{
|
||||
NRF24L01_Initialize();
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
|
||||
XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M); // this will select the nrf and initialize it, therefore both H26 sub protocols can use common instructions
|
||||
#ifdef NRF24L01_INSTALLED
|
||||
if (sub_protocol == H26D || sub_protocol == H26WH)
|
||||
{
|
||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5-byte RX/TX address
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, addr, MJXQ_ADDRESS_LENGTH);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
XN297_SetTXAddr(addr, MJXQ_ADDRESS_LENGTH);
|
||||
|
||||
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 Acknowledgment on all data pipes
|
||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 only
|
||||
NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x00); // no retransmits
|
||||
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, MJXQ_PACKET_SIZE);
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps
|
||||
NRF24L01_SetPower();
|
||||
//NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, MJXQ_PACKET_SIZE); // no RX???
|
||||
}
|
||||
}
|
||||
|
||||
@@ -285,7 +269,7 @@ static void __attribute__((unused)) MJXQ_init2()
|
||||
hopping_frequency[i]=pgm_read_byte_near( &E010_map_rfchan[rx_tx_addr[3]&0x0F][i] );
|
||||
hopping_frequency[i+2]=hopping_frequency[i]+0x10;
|
||||
}
|
||||
XN297L_HoppingCalib(MJXQ_RF_NUM_CHANNELS);
|
||||
XN297_HoppingCalib(MJXQ_RF_NUM_CHANNELS);
|
||||
break;
|
||||
case WLH08:
|
||||
// do nothing
|
||||
@@ -350,14 +334,13 @@ uint16_t MJXQ_callback()
|
||||
return MJXQ_PACKET_PERIOD;
|
||||
}
|
||||
|
||||
uint16_t initMJXQ(void)
|
||||
void MJXQ_init(void)
|
||||
{
|
||||
BIND_IN_PROGRESS; // autobind protocol
|
||||
bind_counter = MJXQ_BIND_COUNT;
|
||||
MJXQ_initialize_txid();
|
||||
MJXQ_init();
|
||||
MJXQ_RF_init();
|
||||
packet_count=0;
|
||||
return MJXQ_INITIAL_WAIT+MJXQ_PACKET_PERIOD;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -257,38 +257,91 @@ static void __attribute__((unused)) MLINK_send_data_packet()
|
||||
#ifdef MLINK_HUB_TELEMETRY
|
||||
static void __attribute__((unused)) MLINK_Send_Telemetry()
|
||||
{ // not sure how MLINK telemetry works, the 2 RXs I have are sending something completly different...
|
||||
RX_RSSI = TX_LQI;
|
||||
telemetry_counter += 2; // TX LQI counter
|
||||
telemetry_link = 1;
|
||||
|
||||
if(packet_in[0]==0x13)
|
||||
{ // RX-9-DR : 13 1A C8 00 01 64 00
|
||||
v_lipo1 = packet_in[5*2]; // Rx_Batt*20
|
||||
}
|
||||
|
||||
if(packet_in[0]==0x03)
|
||||
{ // RX-5 : 03 15 23 00 00 01 02
|
||||
//Incoming packet values
|
||||
RX_RSSI = packet_in[2*2]<<1; // Looks to be the RX RSSI value
|
||||
RX_LQI = packet_in[5*2]; // Looks to be connection lost
|
||||
uint8_t id;
|
||||
for(uint8_t i=1; i<5; i+=3)
|
||||
{//2 sensors per packet
|
||||
id=0x00;
|
||||
switch(packet_in[i]&0x0F)
|
||||
{
|
||||
case 1: //voltage
|
||||
if((packet_in[i]&0xF0) == 0x00)
|
||||
v_lipo1 = packet_in[i+1]; // Rx_Batt*20
|
||||
else
|
||||
v_lipo2 = packet_in[i+1];
|
||||
break;
|
||||
case 2: //current
|
||||
id = 0x28;
|
||||
break;
|
||||
case 3: //vario
|
||||
id = 0x30;
|
||||
break;
|
||||
case 5: //rpm
|
||||
id = 0x03;
|
||||
break;
|
||||
case 6: //temp
|
||||
id = 0x02;
|
||||
break;
|
||||
case 10: //lqi
|
||||
RX_RSSI=RX_LQI=packet_in[i+1]>>1;
|
||||
break;
|
||||
}
|
||||
#if defined HUB_TELEMETRY
|
||||
if(id)
|
||||
{
|
||||
uint16_t val=((packet_in[i+2]&0x80)<<8)|((packet_in[i+2]&0x7F)<<7)|(packet_in[i+1]>>1); //remove the alarm LSB bit, move the sign bit to MSB
|
||||
frsky_send_user_frame(id, val, val>>8);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
if(packet_in[0]==0x03)
|
||||
{ // RX-5 : 03 15 23 00 00 01 02
|
||||
//Incoming packet values
|
||||
RX_RSSI = packet_in[2]<<1; // Looks to be the RX RSSI value
|
||||
RX_LQI = packet_in[5]; // Looks to be connection lost
|
||||
}
|
||||
else
|
||||
RX_RSSI = TX_LQI;
|
||||
|
||||
// Read TX RSSI
|
||||
TX_RSSI = CYRF_ReadRegister(CYRF_13_RSSI)&0x1F;
|
||||
|
||||
telemetry_counter++; // TX LQI counter
|
||||
telemetry_link = 1;
|
||||
|
||||
if(telemetry_lost)
|
||||
{
|
||||
telemetry_lost = 0;
|
||||
packet_count = 100;
|
||||
packet_count = 50;
|
||||
telemetry_counter = 100;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
uint16_t ReadMLINK()
|
||||
#ifdef MLINK_FW_TELEMETRY
|
||||
static void __attribute__((unused)) MLINK_Send_Telemetry()
|
||||
{
|
||||
telemetry_counter += 2; // TX LQI counter
|
||||
telemetry_link = 4;
|
||||
|
||||
// Read TX RSSI
|
||||
TX_RSSI = CYRF_ReadRegister(CYRF_13_RSSI)&0x1F;
|
||||
|
||||
if(telemetry_lost)
|
||||
{
|
||||
telemetry_lost = 0;
|
||||
packet_count = 50;
|
||||
telemetry_counter = 100;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
uint16_t MLINK_callback()
|
||||
{
|
||||
uint8_t status;//,len,sum=0,check=0;
|
||||
uint8_t status;
|
||||
uint16_t start;
|
||||
|
||||
switch(phase)
|
||||
@@ -373,7 +426,7 @@ uint16_t ReadMLINK()
|
||||
hopping_frequency_no = 0x00;
|
||||
CYRF_ConfigRFChannel(hopping_frequency[hopping_frequency_no]);
|
||||
CYRF_SetPower(0x38);
|
||||
#ifdef MLINK_HUB_TELEMETRY
|
||||
#if defined(MLINK_HUB_TELEMETRY) || defined(MLINK_FW_TELEMETRY)
|
||||
packet_count = 0;
|
||||
telemetry_lost = 1;
|
||||
#endif
|
||||
@@ -414,10 +467,10 @@ uint16_t ReadMLINK()
|
||||
phase=MLINK_SEND1;
|
||||
return 4470;
|
||||
case MLINK_RX:
|
||||
#ifdef MLINK_HUB_TELEMETRY
|
||||
#if defined(MLINK_HUB_TELEMETRY) || defined(MLINK_FW_TELEMETRY)
|
||||
//TX LQI calculation
|
||||
packet_count++;
|
||||
if(packet_count>=100)
|
||||
if(packet_count>=50)
|
||||
{
|
||||
packet_count=0;
|
||||
TX_LQI=telemetry_counter;
|
||||
@@ -435,7 +488,7 @@ uint16_t ReadMLINK()
|
||||
if( len && len <= MLINK_PACKET_SIZE )
|
||||
{
|
||||
CYRF_ReadDataPacketLen(packet_in, len*2);
|
||||
#ifdef MLINK_HUB_TELEMETRY
|
||||
#if defined(MLINK_HUB_TELEMETRY) || defined(MLINK_FW_TELEMETRY)
|
||||
if(len==MLINK_PACKET_SIZE)
|
||||
{
|
||||
for(uint8_t i=0;i<8;i++)
|
||||
@@ -443,8 +496,9 @@ uint16_t ReadMLINK()
|
||||
crc8=bit_reverse(MLINK_CRC_Init);
|
||||
for(uint8_t i=0;i<MLINK_PACKET_SIZE-1;i++)
|
||||
{
|
||||
crc8_update(bit_reverse(packet_in[i<<1]));
|
||||
debug(" %02X",packet_in[i<<1]);
|
||||
packet_in[i]=packet_in[i<<1];
|
||||
crc8_update(bit_reverse(packet_in[i]));
|
||||
debug(" %02X",packet_in[i]);
|
||||
}
|
||||
if(packet_in[14] == bit_reverse(crc8)) // Packet CRC is ok
|
||||
MLINK_Send_Telemetry();
|
||||
@@ -478,7 +532,7 @@ static void __attribute__((unused)) MLINK_shuffle_freqs(uint32_t seed, uint8_t *
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t initMLINK()
|
||||
void MLINK_init()
|
||||
{
|
||||
MLINK_cyrf_config();
|
||||
|
||||
@@ -549,8 +603,6 @@ uint16_t initMLINK()
|
||||
}
|
||||
else
|
||||
phase = MLINK_PREP_DATA;
|
||||
|
||||
return 10000;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -15,19 +15,28 @@
|
||||
// compatible with MT99xx, Eachine H7, Yi Zhan i6S and LS114/124
|
||||
// Last sync with Goebish mt99xx_nrf24l01.c dated 2016-01-29
|
||||
|
||||
#if defined(MT99XX_NRF24L01_INO)
|
||||
#if defined(MT99XX_CCNRF_INO)
|
||||
|
||||
#include "iface_nrf24l01.h"
|
||||
#include "iface_xn297.h"
|
||||
|
||||
#define MT99XX_BIND_COUNT 928
|
||||
#define MT99XX_PACKET_PERIOD_FY805 2460
|
||||
#define MT99XX_PACKET_PERIOD_MT 2625
|
||||
#define MT99XX_PACKET_PERIOD_YZ 3125
|
||||
#define MT99XX_PACKET_PERIOD_A180 3400 // timing changes between the packets 2 x 27220 then 1x 26080, it seems that it is only on the first RF channel which jitters by 1.14ms but hard to pinpoint with XN297dump
|
||||
#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_INITIAL_WAIT 500
|
||||
#define MT99XX_PACKET_SIZE 9
|
||||
|
||||
//#define FORCE_A180_ID
|
||||
//#define FORCE_DRAGON_ID
|
||||
|
||||
enum {
|
||||
MT99XX_DATA,
|
||||
MT99XX_RX,
|
||||
MT99XX_CHECK,
|
||||
};
|
||||
|
||||
enum{
|
||||
// flags going to packet[6] (MT99xx, H7)
|
||||
@@ -59,10 +68,11 @@ enum{
|
||||
FLAG_A180_RATE = 0x02,
|
||||
};
|
||||
|
||||
enum {
|
||||
MT99XX_INIT = 0,
|
||||
MT99XX_BIND,
|
||||
MT99XX_DATA
|
||||
enum{
|
||||
// flags going to packet[6] (DRAGON)
|
||||
FLAG_DRAGON_RATE = 0x01,
|
||||
FLAG_DRAGON_RTH = 0x80,
|
||||
FLAG_DRAGON_UNK = 0x04,
|
||||
};
|
||||
|
||||
const uint8_t h7_mys_byte[] = {
|
||||
@@ -79,6 +89,10 @@ const uint8_t ls_mys_byte[] = {
|
||||
|
||||
const uint8_t yz_p4_seq[] = {0xa0, 0x20, 0x60};
|
||||
|
||||
#ifdef MT99XX_HUB_TELEMETRY
|
||||
const uint8_t DRAGON_seq[] = {0x20, 0x60, 0x20, 0x80};
|
||||
#endif
|
||||
|
||||
static void __attribute__((unused)) MT99XX_send_packet()
|
||||
{
|
||||
static uint8_t seq_num=0;
|
||||
@@ -108,7 +122,7 @@ static void __attribute__((unused)) MT99XX_send_packet()
|
||||
break;
|
||||
case A180:
|
||||
packet_period = MT99XX_PACKET_PERIOD_A180;
|
||||
default: // MT99 & H7 & A180
|
||||
default: // MT99 & H7 & A180 & DRAGON
|
||||
packet[1] = 0x14;
|
||||
packet[2] = 0x03;
|
||||
packet[3] = 0x25;
|
||||
@@ -123,7 +137,7 @@ static void __attribute__((unused)) MT99XX_send_packet()
|
||||
else
|
||||
{
|
||||
if(sub_protocol != YZ)
|
||||
{ // MT99XX & H7 & LS & FY805 & A180
|
||||
{ // MT99XX & H7 & LS & FY805 & A180 & DRAGON
|
||||
packet[0] = convert_channel_16b_limit(THROTTLE,0xE1,0x00); // throttle
|
||||
packet[1] = convert_channel_16b_limit(RUDDER ,0x00,0xE1); // rudder
|
||||
packet[2] = convert_channel_16b_limit(AILERON ,0xE1,0x00); // aileron
|
||||
@@ -167,6 +181,37 @@ static void __attribute__((unused)) MT99XX_send_packet()
|
||||
| GET_FLAG( CH5_SW, FLAG_A180_3D6G );
|
||||
packet[7] = 0x00;
|
||||
break;
|
||||
case DRAGON:
|
||||
if(CH5_SW) // Advanced mode
|
||||
packet[5] |= 0x80;
|
||||
else
|
||||
if(Channel_data[CH5] > CHANNEL_MIN_COMMAND) // Beginner mode
|
||||
packet[5] |= 0x40;
|
||||
packet[6] = FLAG_DRAGON_RATE
|
||||
| GET_FLAG( CH6_SW, FLAG_DRAGON_RTH );
|
||||
|
||||
#ifdef MT99XX_HUB_TELEMETRY
|
||||
//Telemetry
|
||||
if(hopping_frequency_no == 0)
|
||||
{
|
||||
seq_num++;
|
||||
seq_num &= 0x03;
|
||||
packet_count++;
|
||||
if(packet_count > 11)
|
||||
packet_count = 0;
|
||||
}
|
||||
if(packet_count > 10) // Telemetry packet request every 10 or 11 packets
|
||||
{
|
||||
packet[6] |= 0x04; // Request telemetry flag
|
||||
phase = MT99XX_RX;
|
||||
}
|
||||
packet[7] = DRAGON_seq[seq_num]; // seq: 20 80 20 60 20 80 20 60... 80 changes to 80+batt from telem
|
||||
if(seq_num==3)
|
||||
packet[7] |= v_lipo1;
|
||||
#else
|
||||
packet[7] = 0x20;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
uint8_t result=crc8;
|
||||
for(uint8_t i=0; i<8; i++)
|
||||
@@ -186,7 +231,7 @@ static void __attribute__((unused)) MT99XX_send_packet()
|
||||
seq_num = 0;
|
||||
packet_count=0;
|
||||
}
|
||||
packet[4] = yz_p4_seq[seq_num];
|
||||
packet[4] = yz_p4_seq[seq_num];
|
||||
packet[5] = 0x02 // expert ? (0=unarmed, 1=normal)
|
||||
| GET_FLAG(CH8_SW, 0x10) //VIDEO
|
||||
| GET_FLAG(CH5_SW, 0x80) //FLIP
|
||||
@@ -200,48 +245,40 @@ static void __attribute__((unused)) MT99XX_send_packet()
|
||||
}
|
||||
}
|
||||
|
||||
//RF freq
|
||||
if(sub_protocol == LS)
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, 0x2D); // LS always transmits on the same channel
|
||||
XN297_RFChannel(0x2D); // LS always transmits on the same channel
|
||||
else
|
||||
if(sub_protocol==FY805)
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, 0x4B); // FY805 always transmits on the same channel
|
||||
else // MT99 & H7 & YZ & A180
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no]);
|
||||
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||
NRF24L01_FlushTx();
|
||||
XN297_WritePayload(packet, MT99XX_PACKET_SIZE);
|
||||
XN297_RFChannel(0x4B); // FY805 always transmits on the same channel
|
||||
else // MT99 & H7 & YZ & A180 & DRAGON
|
||||
XN297_Hopping(hopping_frequency_no);
|
||||
|
||||
hopping_frequency_no++;
|
||||
if(sub_protocol == YZ || sub_protocol == A180)
|
||||
if(sub_protocol == YZ || sub_protocol == A180 || sub_protocol == DRAGON )
|
||||
hopping_frequency_no++; // skip every other channel
|
||||
|
||||
if(hopping_frequency_no > 15)
|
||||
hopping_frequency_no = 0;
|
||||
|
||||
NRF24L01_SetPower();
|
||||
// Send
|
||||
XN297_SetPower();
|
||||
XN297_SetFreqOffset();
|
||||
XN297_SetTxRxMode(TX_EN);
|
||||
XN297_WritePayload(packet, MT99XX_PACKET_SIZE);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) MT99XX_init()
|
||||
static void __attribute__((unused)) MT99XX_RF_init()
|
||||
{
|
||||
NRF24L01_Initialize();
|
||||
if(sub_protocol == YZ)
|
||||
XN297_SetScrambledMode(XN297_UNSCRAMBLED);
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
NRF24L01_FlushTx();
|
||||
XN297_Configure(XN297_CRCEN, XN297_UNSCRAMBLED, XN297_250K);
|
||||
else
|
||||
XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M);
|
||||
XN297_SetTXAddr((uint8_t *)"\xCC\xCC\xCC\xCC\xCC", 5);
|
||||
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_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5 bytes address
|
||||
NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x00); // no auto retransmit
|
||||
if(sub_protocol == YZ)
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_250K); // 250Kbps (nRF24L01+ only)
|
||||
else
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps
|
||||
NRF24L01_SetPower();
|
||||
|
||||
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP) );
|
||||
XN297_HoppingCalib(16);
|
||||
#ifdef MT99XX_HUB_TELEMETRY
|
||||
XN297_SetRXAddr(rx_tx_addr, MT99XX_PACKET_SIZE);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) MT99XX_initialize_txid()
|
||||
@@ -272,7 +309,16 @@ static void __attribute__((unused)) MT99XX_initialize_txid()
|
||||
//channel_offset = 0x03;
|
||||
break;
|
||||
#endif
|
||||
default: //MT99 & H7 & A180
|
||||
#ifdef FORCE_DRAGON_ID
|
||||
case DRAGON:
|
||||
rx_tx_addr[0] = 0x6C; // Laurie ID
|
||||
rx_tx_addr[1] = 0x00;
|
||||
rx_tx_addr[2] = 0x22;
|
||||
//crc8 = 0x8E
|
||||
//channel_offset = 0x06
|
||||
break;
|
||||
#endif
|
||||
default: //MT99 & H7 & A180 & DRAGON
|
||||
rx_tx_addr[2] = 0x00;
|
||||
break;
|
||||
}
|
||||
@@ -293,40 +339,86 @@ static void __attribute__((unused)) MT99XX_initialize_txid()
|
||||
|
||||
uint16_t MT99XX_callback()
|
||||
{
|
||||
if(bind_counter)
|
||||
switch(phase)
|
||||
{
|
||||
bind_counter--;
|
||||
if (bind_counter == 0)
|
||||
{
|
||||
// set tx address for data packets
|
||||
XN297_SetTXAddr(rx_tx_addr, 5);
|
||||
uint8_t channel_offset = (((crc8 & 0xf0)>>4) + (crc8 & 0x0f)) % 8;
|
||||
for(uint8_t i=0;i<16;i++)
|
||||
hopping_frequency[i] += channel_offset;
|
||||
BIND_DONE;
|
||||
}
|
||||
case MT99XX_DATA:
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(packet_period);
|
||||
#endif
|
||||
if(bind_counter)
|
||||
{
|
||||
bind_counter--;
|
||||
if (bind_counter == 0)
|
||||
{
|
||||
// set tx address for data packets
|
||||
XN297_SetTXAddr(rx_tx_addr, 5);
|
||||
// set rf channels
|
||||
uint8_t channel_offset = ((crc8>>4) + (crc8 & 0x0f)) % 8;
|
||||
for(uint8_t i=0;i<16;i++)
|
||||
hopping_frequency[i] += channel_offset;
|
||||
XN297_HoppingCalib(16);
|
||||
BIND_DONE;
|
||||
}
|
||||
}
|
||||
MT99XX_send_packet();
|
||||
break;
|
||||
#ifdef MT99XX_HUB_TELEMETRY
|
||||
case MT99XX_RX:
|
||||
//Switch to RX
|
||||
XN297_SetTxRxMode(TXRX_OFF);
|
||||
XN297_SetTxRxMode(RX_EN);
|
||||
phase++;
|
||||
return MT99XX_PACKET_PERIOD_DRAGON_TELEM - MT99XX_PACKET_PERIOD_DRAGON - 500;
|
||||
case MT99XX_CHECK:
|
||||
//Check telem
|
||||
if(XN297_IsRX())
|
||||
{
|
||||
//debug("RX");
|
||||
if(XN297_ReadPayload(packet_in, MT99XX_PACKET_SIZE))
|
||||
{
|
||||
// C=48 S=Y A= 6C 00 22 CC CC P(9)= 6C 00 22 27 00 00 00 00 60
|
||||
// C=48 S=Y A= 6C 00 22 CC CC P(9)= 6C 00 22 28 00 00 00 00 61
|
||||
// C=18 S=Y A= 6C 00 22 CC CC P(9)= 6C 00 22 24 00 00 00 00 5D
|
||||
// 6C 00 22 = TX address, 27/28/24=vbatt, check = sum(P[0..7]) + AB
|
||||
// D2 EE 00 25 00 00 00 00 90 -> check also + AB
|
||||
//for(uint8_t i=0; i<MT99XX_PACKET_SIZE; i++)
|
||||
// debug(" %02X",packet_in[i]);
|
||||
uint8_t check=0xAB;
|
||||
for(uint8_t i=0; i<8; i++)
|
||||
check += packet_in[i];
|
||||
if(packet_in[8] == check && packet_in[0] == rx_tx_addr[0] && packet_in[1] == rx_tx_addr[1] && packet_in[2] == rx_tx_addr[2])
|
||||
{ // checksum and address are ok
|
||||
// debug(" OK");
|
||||
v_lipo1 = packet_in[3] & 0x7F; // Batt
|
||||
v_lipo2 = packet_in[3] & 0x80; // Low batt flag
|
||||
RX_RSSI=100;
|
||||
telemetry_link = 1;
|
||||
}
|
||||
}
|
||||
//debugln("");
|
||||
}
|
||||
//Switch to TX
|
||||
XN297_SetTxRxMode(TXRX_OFF);
|
||||
XN297_SetTxRxMode(TX_EN);
|
||||
phase=MT99XX_DATA;
|
||||
return 500;
|
||||
#endif
|
||||
}
|
||||
#ifdef MULTI_SYNC
|
||||
else
|
||||
telemetry_set_input_sync(packet_period);
|
||||
#endif
|
||||
|
||||
MT99XX_send_packet();
|
||||
return packet_period;
|
||||
return packet_period;
|
||||
}
|
||||
|
||||
uint16_t initMT99XX(void)
|
||||
void MT99XX_init(void)
|
||||
{
|
||||
if(sub_protocol != A180)
|
||||
if(sub_protocol != A180 && sub_protocol != DRAGON)
|
||||
BIND_IN_PROGRESS; // autobind protocol
|
||||
bind_counter = MT99XX_BIND_COUNT;
|
||||
|
||||
MT99XX_initialize_txid();
|
||||
MT99XX_init();
|
||||
MT99XX_RF_init();
|
||||
|
||||
packet_period = MT99XX_PACKET_PERIOD_MT;
|
||||
|
||||
packet_count=0;
|
||||
return MT99XX_INITIAL_WAIT+MT99XX_PACKET_PERIOD_MT;
|
||||
phase=MT99XX_DATA;
|
||||
}
|
||||
#endif
|
||||
241
Multiprotocol/MouldKg_nrf24l01.ino
Normal file
241
Multiprotocol/MouldKg_nrf24l01.ino
Normal file
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
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(MOULDKG_NRF24L01_INO)
|
||||
|
||||
#include "iface_xn297.h"
|
||||
|
||||
//#define FORCE_MOULDKG_ORIGINAL_ID
|
||||
|
||||
#define MOULDKG_PACKET_PERIOD 5000
|
||||
#define MOULDKG_BIND_PACKET_PERIOD 12000
|
||||
#define MOULDKG_TX_BIND_CHANNEL 11
|
||||
#define MOULDKG_RX_BIND_CHANNEL 76
|
||||
#define MOULDKG_PAYLOAD_SIZE_DIGIT 5
|
||||
#define MOULDKG_PAYLOAD_SIZE_ANALOG 10
|
||||
#define MOULDKG_BIND_PAYLOAD_SIZE 7
|
||||
#define MOULDKG_BIND_COUNT 300
|
||||
#define MOULDKG_RF_NUM_CHANNELS 4
|
||||
|
||||
enum {
|
||||
MOULDKG_BINDTX=0,
|
||||
MOULDKG_BINDRX,
|
||||
MOULDKG_PREP_DATA,
|
||||
MOULDKG_PREP_DATA1,
|
||||
MOULDKG_DATA,
|
||||
};
|
||||
|
||||
uint8_t MOULDKG_RX_id[4*3];
|
||||
|
||||
static void __attribute__((unused)) MOULDKG_send_packet()
|
||||
{
|
||||
uint8_t len = MOULDKG_BIND_PAYLOAD_SIZE;
|
||||
memcpy(&packet[1],rx_tx_addr,3);
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
packet[0] = 0xC0;
|
||||
memset(&packet[4], 0x00, 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t n = num_ch<<2;
|
||||
if(sub_protocol == MOULDKG_ANALOG)
|
||||
{
|
||||
packet[0] = 0x36;
|
||||
uint8_t ch[]={ 1,0,2,3 };
|
||||
for(uint8_t i=0;i<4;i++)
|
||||
packet[i+4] = convert_channel_8b(ch[i]+n);
|
||||
len = MOULDKG_PAYLOAD_SIZE_ANALOG;
|
||||
}
|
||||
else
|
||||
{//DIGIT
|
||||
len = MOULDKG_PAYLOAD_SIZE_DIGIT;
|
||||
uint8_t val=0;
|
||||
if(packet_count&1)
|
||||
{
|
||||
packet[0] = 0x31;
|
||||
//Button B
|
||||
if(Channel_data[CH2+n]>CHANNEL_MAX_COMMAND) val |= 0x40;
|
||||
else if(Channel_data[CH2+n]<CHANNEL_MIN_COMMAND) val |= 0x80;
|
||||
//Button C
|
||||
if(Channel_data[CH3+n]>CHANNEL_MAX_COMMAND) val |= 0x10;
|
||||
else if(Channel_data[CH3+n]<CHANNEL_MIN_COMMAND) val |= 0x20;
|
||||
}
|
||||
else
|
||||
{
|
||||
packet[0] = 0x30;
|
||||
val = 0x60;
|
||||
// | GET_FLAG(CH5_SW, 0x80) // Button E
|
||||
// | GET_FLAG(CH6_SW, 0x10); // Button F
|
||||
}
|
||||
//Button A
|
||||
if(Channel_data[CH1+n]>CHANNEL_MAX_COMMAND) val |= 0x01;
|
||||
else if(Channel_data[CH1+n]<CHANNEL_MIN_COMMAND) val |= 0x02;
|
||||
//Button D
|
||||
if(Channel_data[CH4+n]>CHANNEL_MAX_COMMAND) val |= 0x04;
|
||||
else if(Channel_data[CH4+n]<CHANNEL_MIN_COMMAND) val |= 0x08;
|
||||
packet[4]= val;
|
||||
}
|
||||
}
|
||||
|
||||
// Send
|
||||
XN297_SetPower();
|
||||
XN297_SetTxRxMode(TX_EN);
|
||||
XN297_WritePayload(packet, len);
|
||||
#if 0
|
||||
for(uint8_t i=0; i < len; i++)
|
||||
debug("%02X ", packet[i]);
|
||||
debugln();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) MOULDKG_initialize_txid()
|
||||
{
|
||||
//rx_tx_addr[0] = rx_tx_addr[3]; // Use RX_num;
|
||||
|
||||
#ifdef FORCE_MOULDKG_ORIGINAL_ID
|
||||
rx_tx_addr[0]=0x57;
|
||||
rx_tx_addr[1]=0x1B;
|
||||
rx_tx_addr[2]=0xF8;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) MOULDKG_RF_init()
|
||||
{
|
||||
XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M);
|
||||
XN297_SetTXAddr((uint8_t*)"KDH", 3);
|
||||
XN297_SetRXAddr((uint8_t*)"KDH", MOULDKG_BIND_PAYLOAD_SIZE);
|
||||
}
|
||||
|
||||
uint16_t MOULDKG_callback()
|
||||
{
|
||||
uint8_t rf,n;
|
||||
uint16_t addr;
|
||||
switch(phase)
|
||||
{
|
||||
case MOULDKG_BINDTX:
|
||||
if(XN297_IsRX())
|
||||
{
|
||||
//Example: TX: C=11 S=Y A= 4B 44 48 P(7)= C0 37 02 4F 00 00 00
|
||||
// RX: C=76 S=Y A= 4B 44 48 P(7)= 5A 37 02 4F 03 0D 8E
|
||||
// 03 0D 8E => RF channels 0F,1C,39,3C
|
||||
XN297_ReadPayload(packet_in, MOULDKG_BIND_PAYLOAD_SIZE);
|
||||
for(uint8_t i=0; i < MOULDKG_BIND_PAYLOAD_SIZE; i++)
|
||||
debug("%02X ", packet_in[i]);
|
||||
debugln();
|
||||
//Not sure if I should test packet_in[0]
|
||||
if(memcmp(&packet_in[1],&packet[1],3)==0)
|
||||
{//TX ID match
|
||||
if(option == 0)
|
||||
{
|
||||
memcpy(MOULDKG_RX_id,&packet_in[4],3);
|
||||
phase = MOULDKG_PREP_DATA1;
|
||||
}
|
||||
else
|
||||
{// Store RX ID
|
||||
addr=MOULDKG_EEPROM_OFFSET+RX_num*3;
|
||||
for(uint8_t i=0;i<3;i++)
|
||||
eeprom_write_byte((EE_ADDR)(addr+i),packet_in[4+i]);
|
||||
phase = MOULDKG_PREP_DATA;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
XN297_RFChannel(MOULDKG_TX_BIND_CHANNEL); // Set TX bind channel
|
||||
XN297_SetTxRxMode(TXRX_OFF);
|
||||
MOULDKG_send_packet();
|
||||
phase++;
|
||||
return 600;
|
||||
case MOULDKG_BINDRX:
|
||||
//Wait for the packet transmission to finish
|
||||
while(XN297_IsPacketSent()==false);
|
||||
//Switch to RX
|
||||
XN297_SetTxRxMode(TXRX_OFF);
|
||||
XN297_RFChannel(MOULDKG_RX_BIND_CHANNEL); // Set RX bind channel
|
||||
XN297_SetTxRxMode(RX_EN);
|
||||
phase = MOULDKG_BINDTX;
|
||||
return MOULDKG_BIND_PACKET_PERIOD-600;
|
||||
case MOULDKG_PREP_DATA:
|
||||
addr=MOULDKG_EEPROM_OFFSET+RX_num*3;
|
||||
debug("RXID: ");
|
||||
for(uint8_t i=0;i<3*4;i++)
|
||||
{ // load 4 consecutive RX IDs
|
||||
MOULDKG_RX_id[i]=eeprom_read_byte((EE_ADDR)(addr+i));
|
||||
debug(" %02X",MOULDKG_RX_id[i]);
|
||||
}
|
||||
debugln("");
|
||||
case MOULDKG_PREP_DATA1:
|
||||
//Switch to normal mode
|
||||
BIND_DONE;
|
||||
XN297_SetTxRxMode(TXRX_OFF);
|
||||
phase = MOULDKG_DATA;
|
||||
break;
|
||||
case MOULDKG_DATA:
|
||||
#ifdef MULTI_SYNC
|
||||
if(num_ch==0)
|
||||
telemetry_set_input_sync(MOULDKG_PACKET_PERIOD);
|
||||
#endif
|
||||
if(option == 0) option++;
|
||||
if(num_ch<option)
|
||||
{
|
||||
//Set RX ID address
|
||||
n = num_ch*3;
|
||||
XN297_SetTXAddr(&MOULDKG_RX_id[n], 3);
|
||||
//Set frequency based on current RX ID and packet number
|
||||
rf = 0x0C;
|
||||
if(packet_count & 0x04)
|
||||
{
|
||||
n++;
|
||||
rf += 0x20;
|
||||
}
|
||||
if(packet_count & 0x02)
|
||||
rf += 0x10 + (MOULDKG_RX_id[n] >> 4);
|
||||
else
|
||||
rf += MOULDKG_RX_id[n] & 0x0F;
|
||||
XN297_RFChannel(rf);
|
||||
#if 1
|
||||
debugln("num_ch=%d,packet_count=%d,rf=%02X,ID=%02X %02X %02X",num_ch,packet_count,rf,MOULDKG_RX_id[num_ch*3],MOULDKG_RX_id[num_ch*3+1],MOULDKG_RX_id[num_ch*3+2]);
|
||||
#endif
|
||||
MOULDKG_send_packet();
|
||||
if(num_ch==0)
|
||||
packet_count++;
|
||||
}
|
||||
num_ch++;
|
||||
num_ch &= 0x03;
|
||||
break;
|
||||
}
|
||||
return MOULDKG_PACKET_PERIOD/4;
|
||||
}
|
||||
|
||||
void MOULDKG_init()
|
||||
{
|
||||
if(option == 0)
|
||||
BIND_IN_PROGRESS;
|
||||
MOULDKG_initialize_txid();
|
||||
MOULDKG_RF_init();
|
||||
bind_counter = MOULDKG_BIND_COUNT;
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
phase = MOULDKG_BINDTX;
|
||||
else
|
||||
phase = MOULDKG_PREP_DATA;
|
||||
packet_count = 0;
|
||||
num_ch = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// Analog
|
||||
// Bind TX: C=11 S=Y A= 4B 44 48 P(7)= C0 46 01 00 00 00 00
|
||||
// Bind RX: 5A 46 01 00 63 82 4E
|
||||
// Norm: C=15 S=Y A= 63 82 4E P(10)= 36 46 01 00 80 80 80 80 00 00
|
||||
@@ -3,7 +3,7 @@
|
||||
3,FrskyD,D8,Cloned
|
||||
4,Hisky,Hisky,HK310
|
||||
5,V2x2,V2x2,JXD506,MR101
|
||||
6,DSM,DSM2_1F,DSM2_2F,DSMX_1F,DSMX_2F,AUTO
|
||||
6,DSM,DSM2_1F,DSM2_2F,DSMX_1F,DSMX_2F,AUTO,DSMR_1F
|
||||
7,Devo,8CH,10CH,12CH,6CH,7CH
|
||||
8,YD717,YD717,SKYWLKR,SYMAX4,XINXUN,NIHUI
|
||||
9,KN,WLTOYS,FEILUN
|
||||
@@ -14,7 +14,7 @@
|
||||
14,Bayang,Bayang,H8S3D,X16_AH,IRDRONE,DHD_D4,QX100
|
||||
15,FrskyX,CH_16,CH_8,EU_16,EU_8,Cloned,Clon_8
|
||||
16,ESky,Std,ET4
|
||||
17,MT99xx,MT,H7,YZ,LS,FY805,A180
|
||||
17,MT99xx,MT,H7,YZ,LS,FY805,A180,Dragon
|
||||
18,MJXq,WLH08,X600,X800,H26D,E010,H26WH,PHOENIX
|
||||
19,Shenqi
|
||||
20,FY326,FY326,FY319
|
||||
@@ -42,7 +42,7 @@
|
||||
42,BUGSMINI,BUGSMINI,BUGS3H
|
||||
43,Traxxas,RX6519
|
||||
44,NCC1701
|
||||
45,E01X,E012,E015,E016H
|
||||
45,E01X,E012,E015
|
||||
46,V911S,V911S,E119
|
||||
47,GD00x,GD_V1,GD_V2
|
||||
48,V761,3CH,4CH
|
||||
@@ -52,12 +52,12 @@
|
||||
52,ZSX,280
|
||||
53,Height,5ch,8ch
|
||||
54,Scanner
|
||||
55,Frsky_RX,RX,CloneTX,EraseTX
|
||||
56,AFHDS2A_RX
|
||||
55,Frsky_RX,Multi,CloneTX,EraseTX,CPPM
|
||||
56,AFHDS2A_RX,Multi,CPPM
|
||||
57,HoTT,Sync,No_Sync
|
||||
58,FX816,P38
|
||||
59,Bayang_RX
|
||||
60,Pelikan,Pro,Lite
|
||||
59,Bayang_RX,Multi,CPPM
|
||||
60,Pelikan,Pro,Lite,SCX24
|
||||
61,Tiger
|
||||
62,XK,X450,X420
|
||||
63,XN_DUMP,250K,1M,2M,AUTO
|
||||
@@ -67,7 +67,7 @@
|
||||
67,LR12,LR12,LR12_6ch
|
||||
68,Skyartec
|
||||
69,ESKYv2,150V2
|
||||
70,DSM_RX
|
||||
70,DSM_RX,Multi,CPPM
|
||||
71,JJRC345,JJRC345,SkyTmblr
|
||||
72,Q90C
|
||||
73,Kyosho,FHSS,Hype
|
||||
@@ -80,4 +80,9 @@
|
||||
80,E016H,E016Hv2
|
||||
81,E010r5
|
||||
82,LOLI
|
||||
83,E129
|
||||
83,E129
|
||||
84,JOYSWAY
|
||||
85,E016H
|
||||
87,IKEA
|
||||
89,Losi
|
||||
90,MouldKg,Analog,Digit
|
||||
192
Multiprotocol/Multi_Config.ino
Normal file
192
Multiprotocol/Multi_Config.ino
Normal file
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
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(MULTI_CONFIG_INO)
|
||||
|
||||
#ifdef CYRF6936_INSTALLED
|
||||
#include "iface_cyrf6936.h"
|
||||
#endif
|
||||
|
||||
void CONFIG_write_GID(uint32_t id)
|
||||
{
|
||||
for(uint8_t i=0;i<4;i++)
|
||||
eeprom_write_byte((EE_ADDR)EEPROM_ID_OFFSET+i,id >> (i*8));
|
||||
//eeprom_write_byte((EE_ADDR)(EEPROM_ID_OFFSET+10),0xf0);
|
||||
}
|
||||
|
||||
void CONFIG_write_CID(uint8_t *data)
|
||||
{
|
||||
for(uint8_t i=0;i<6;i++)
|
||||
eeprom_write_byte((EE_ADDR)EEPROM_CID_OFFSET+i, data[i]);
|
||||
//eeprom_write_byte((EE_ADDR)EEPROM_CID_INIT_OFFSET, 0xf0);
|
||||
}
|
||||
uint16_t CONFIG_callback()
|
||||
{
|
||||
static uint8_t line=0, page=0;
|
||||
uint32_t id=0;
|
||||
// [0] = page<<4|line number
|
||||
// [1..6] = max 6 bytes
|
||||
if(CONFIG_SerialRX)
|
||||
{
|
||||
debug("config");
|
||||
for(uint8_t i=0; i<7; i++)
|
||||
debug("%02X ",CONFIG_SerialRX_val[i]);
|
||||
debugln("");
|
||||
CONFIG_SerialRX = false;
|
||||
switch(CONFIG_SerialRX_val[0]&0x0F)
|
||||
{
|
||||
//case 0:
|
||||
// Page change
|
||||
// break;
|
||||
case 1:
|
||||
for(uint8_t i=0; i<4; i++)
|
||||
{
|
||||
id <<= 8;
|
||||
id |= CONFIG_SerialRX_val[i+1];
|
||||
}
|
||||
debugln("Update ID to %lx", id);
|
||||
CONFIG_write_GID(id);
|
||||
break;
|
||||
case 2:
|
||||
if(CONFIG_SerialRX_val[1]==0xAA)
|
||||
{
|
||||
#define STM32_UUID ((uint32_t *)0x1FFFF7E8)
|
||||
id = STM32_UUID[0] ^ STM32_UUID[1] ^ STM32_UUID[2];
|
||||
debugln("Reset GID to %lx", id);
|
||||
CONFIG_write_GID(id);
|
||||
}
|
||||
break;
|
||||
#ifdef CYRF6936_INSTALLED
|
||||
case 4:
|
||||
debug("Update CID to ");
|
||||
for(uint8_t i=0; i<6; i++)
|
||||
debug("%02X ",CONFIG_SerialRX_val[i+1]);
|
||||
debugln("");
|
||||
CONFIG_write_CID(&CONFIG_SerialRX_val[1]);
|
||||
case 5:
|
||||
if(CONFIG_SerialRX_val[1]==0xAA)
|
||||
{
|
||||
uint8_t data[6];
|
||||
CYRF_WriteRegister(CYRF_25_MFG_ID, 0xFF); /* Fuses power on */
|
||||
CYRF_ReadRegisterMulti(CYRF_25_MFG_ID, data, 6);
|
||||
CYRF_WriteRegister(CYRF_25_MFG_ID, 0x00); /* Fuses power off */
|
||||
debug("Reset CID to ");
|
||||
for(uint8_t i=0; i<6; i++)
|
||||
debug("%02X ",data[i]);
|
||||
debugln("");
|
||||
CONFIG_write_CID(data);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case 7:
|
||||
if(CONFIG_SerialRX_val[1]==0xAA)
|
||||
{
|
||||
debugln("Format EE");
|
||||
#if defined(STM32_BOARD)
|
||||
EEPROM.format();
|
||||
#else
|
||||
for (uint16_t i = 0; i < 512; i++)
|
||||
eeprom_write_byte((EE_ADDR)i, 0xFF);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( telemetry_link )
|
||||
return 10000;
|
||||
// [0] = page<<4|line number
|
||||
// line=0: VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION, VERSION_PATCH_LEVEL, Channel order:RUDDER<<6|THROTTLE<<4|ELEVATOR<<2|AILERON
|
||||
// [1..21] = max 20 characters, any displayable chars followed by:
|
||||
// 0x00 : end of line
|
||||
// 0x80+len: selectable text to follow
|
||||
// 0x90+len: selectable text to follow with "Are you sure?"
|
||||
// 0xA0+len: not editable dec value
|
||||
// 0xB0+len: editable dec value
|
||||
// 0xC0+len: not editable hex value
|
||||
// 0xD0+len: editable hex value
|
||||
memset(&packet_in[1],0,20);
|
||||
do
|
||||
{
|
||||
packet_in[0] = (page<<4) | line;
|
||||
switch(line)
|
||||
{
|
||||
case 0:
|
||||
packet_in[1]=VERSION_MAJOR;
|
||||
packet_in[2]=VERSION_MINOR;
|
||||
packet_in[3]=VERSION_REVISION;
|
||||
packet_in[4]=VERSION_PATCH_LEVEL;
|
||||
packet_in[5]=RUDDER<<6|THROTTLE<<4|ELEVATOR<<2|AILERON;
|
||||
break;
|
||||
case 1:
|
||||
//Global ID
|
||||
#ifndef FORCE_GLOBAL_ID
|
||||
memcpy(&packet_in[1],"Global ID",9);
|
||||
packet_in[10] = 0xD0 + 4;
|
||||
#else
|
||||
memcpy(&packet_in[1],"Fixed ID ",9);
|
||||
packet_in[10] = 0xC0 + 4;
|
||||
#endif
|
||||
MProtocol_id_master = random_id(EEPROM_ID_OFFSET,false);
|
||||
set_rx_tx_addr(MProtocol_id_master);
|
||||
for(uint8_t i=0; i<4; i++)
|
||||
packet_in[11+i]=rx_tx_addr[i];
|
||||
break;
|
||||
#if defined(STM32_BOARD) && not defined(FORCE_GLOBAL_ID)
|
||||
case 2:
|
||||
//Reset global ID
|
||||
packet_in[1] = 0x90+9;
|
||||
memcpy(&packet_in[2],"Reset GID",9);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CYRF6936_INSTALLED
|
||||
case 4:
|
||||
//Cyrf ID
|
||||
#ifndef FORCE_CYRF_ID
|
||||
memcpy(&packet_in[1],"Cyrf ID",7);
|
||||
packet_in[8] = 0xD0 + 6;
|
||||
CYRF_GetMfgData(&packet_in[9]);
|
||||
#else
|
||||
memcpy(&packet_in[1],"Fixed CID",9);
|
||||
packet_in[10] = 0xC0 + 6;
|
||||
CYRF_GetMfgData(&packet_in[11]);
|
||||
#endif
|
||||
break;
|
||||
#ifndef FORCE_CYRF_ID
|
||||
case 5:
|
||||
//Reset Cyrf ID
|
||||
packet_in[1] = 0x90+9;
|
||||
memcpy(&packet_in[2],"Reset CID",9);
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
case 7:
|
||||
packet_in[1] = 0x90+13;
|
||||
memcpy(&packet_in[2],"Format EEPROM",13);
|
||||
break;
|
||||
}
|
||||
line++;
|
||||
line %= 8;
|
||||
}
|
||||
while(packet_in[1]==0); // next line if empty
|
||||
telemetry_link = 1;
|
||||
return 10000;
|
||||
}
|
||||
|
||||
void CONFIG_init()
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,429 +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/>.
|
||||
*/
|
||||
|
||||
#if defined(MULTI_NAMES)
|
||||
|
||||
const char STR_FLYSKY[] ="FlySky";
|
||||
const char STR_HUBSAN[] ="Hubsan";
|
||||
const char STR_FRSKYD[] ="FrSky D";
|
||||
const char STR_HISKY[] ="Hisky";
|
||||
const char STR_V2X2[] ="V2x2";
|
||||
const char STR_DSM[] ="DSM";
|
||||
const char STR_DSM_RX[] ="DSM_RX";
|
||||
const char STR_DEVO[] ="Devo";
|
||||
const char STR_YD717[] ="YD717";
|
||||
const char STR_KN[] ="KN";
|
||||
const char STR_SYMAX[] ="SymaX";
|
||||
const char STR_SLT[] ="SLT";
|
||||
const char STR_CX10[] ="CX10";
|
||||
const char STR_CG023[] ="CG023";
|
||||
const char STR_BAYANG[] ="Bayang";
|
||||
const char STR_FRSKYL[] ="FrSky L";
|
||||
const char STR_FRSKYX[] ="FrSky X";
|
||||
const char STR_FRSKYX2[] ="FrSkyX2";
|
||||
const char STR_ESKY[] ="ESky";
|
||||
const char STR_MT99XX[] ="MT99XX";
|
||||
const char STR_MJXQ[] ="MJXq";
|
||||
const char STR_SHENQI[] ="Shenqi";
|
||||
const char STR_FY326[] ="FY326";
|
||||
const char STR_FUTABA[] ="Futaba";
|
||||
const char STR_J6PRO[] ="J6 Pro";
|
||||
const char STR_JJRC345[] ="JJRC345";
|
||||
const char STR_FQ777[] ="FQ777";
|
||||
const char STR_ASSAN[] ="Assan";
|
||||
const char STR_FRSKYV[] ="FrSky V";
|
||||
const char STR_HONTAI[] ="Hontai";
|
||||
const char STR_AFHDS2A[] ="FlSky2A";
|
||||
const char STR_Q2X2[] ="Q2x2";
|
||||
const char STR_WK2x01[] ="Walkera";
|
||||
const char STR_Q303[] ="Q303";
|
||||
const char STR_Q90C[] ="Q90C";
|
||||
const char STR_GW008[] ="GW008";
|
||||
const char STR_DM002[] ="DM002";
|
||||
const char STR_CABELL[] ="Cabell";
|
||||
const char STR_ESKY150[] ="Esky150";
|
||||
const char STR_ESKY150V2[] ="EskyV2";
|
||||
const char STR_H8_3D[] ="H8 3D";
|
||||
const char STR_CORONA[] ="Corona";
|
||||
const char STR_CFLIE[] ="CFlie";
|
||||
const char STR_HITEC[] ="Hitec";
|
||||
const char STR_WFLY[] ="WFLY";
|
||||
const char STR_WFLY2[] ="WFLY2";
|
||||
const char STR_BUGS[] ="Bugs";
|
||||
const char STR_BUGSMINI[] ="BugMini";
|
||||
const char STR_TRAXXAS[] ="Traxxas";
|
||||
const char STR_NCC1701[] ="NCC1701";
|
||||
const char STR_E01X[] ="E01X";
|
||||
const char STR_V911S[] ="V911S";
|
||||
const char STR_GD00X[] ="GD00x";
|
||||
const char STR_V761[] ="V761";
|
||||
const char STR_KF606[] ="KF606";
|
||||
const char STR_REDPINE[] ="Redpine";
|
||||
const char STR_POTENSIC[] ="Potensi";
|
||||
const char STR_ZSX[] ="ZSX";
|
||||
const char STR_HEIGHT[] ="Height";
|
||||
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_BAYANG_RX[] ="BayanRX";
|
||||
const char STR_PELIKAN[] ="Pelikan";
|
||||
const char STR_TIGER[] ="Tiger";
|
||||
const char STR_XK[] ="XK";
|
||||
const char STR_XN297DUMP[] ="XN297DP";
|
||||
const char STR_FRSKYR9[] ="FrSkyR9";
|
||||
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_MLINK[] ="M-Link";
|
||||
const char STR_TEST[] ="Test";
|
||||
const char STR_NANORF[] ="NanoRF";
|
||||
const char STR_E016HV2[] ="E016Hv2";
|
||||
const char STR_E010R5[] ="E010r5";
|
||||
const char STR_LOLI[] ="LOLI";
|
||||
const char STR_E129[] ="E129";
|
||||
|
||||
const char STR_SUBTYPE_FLYSKY[] = "\x04""Std\0""V9x9""V6x6""V912""CX20";
|
||||
const char STR_SUBTYPE_HUBSAN[] = "\x04""H107""H301""H501";
|
||||
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";
|
||||
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";
|
||||
const char STR_SUBTYPE_SYMAX[] = "\x03""Std""X5C";
|
||||
const char STR_SUBTYPE_SLT[] = "\x06""V1_6ch""V2_8ch""Q100\0 ""Q200\0 ""MR100\0";
|
||||
const char STR_SUBTYPE_CX10[] = "\x07""Green\0 ""Blue\0 ""DM007\0 ""-\0 ""JC3015a""JC3015b""MK33041";
|
||||
const char STR_SUBTYPE_CG023[] = "\x05""Std\0 ""YD829";
|
||||
const char STR_SUBTYPE_BAYANG[] = "\x07""Std\0 ""H8S3D\0 ""X16 AH\0""IRDrone""DHD D4\0""QX100\0 ";
|
||||
const char STR_SUBTYPE_MT99[] = "\x05""MT99\0""H7\0 ""YZ\0 ""LS\0 ""FY805""A180\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""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";
|
||||
const char STR_SUBTYPE_CABELL[] = "\x07""V3\0 ""V3 Telm""-\0 ""-\0 ""-\0 ""-\0 ""F-Safe\0""Unbind\0";
|
||||
const char STR_SUBTYPE_H83D[] = "\x07""Std\0 ""H20H\0 ""H20Mini""H30Mini";
|
||||
const char STR_SUBTYPE_CORONA[] = "\x05""V1\0 ""V2\0 ""FD V3";
|
||||
const char STR_SUBTYPE_HITEC[] = "\x07""Optima\0""Opt Hub""Minima\0";
|
||||
const char STR_SUBTYPE_BUGS_MINI[] = "\x06""Std\0 ""Bugs3H";
|
||||
const char STR_SUBTYPE_TRAXXAS[] = "\x04""6519";
|
||||
const char STR_SUBTYPE_E01X[] = "\x05""E012\0""E015\0""E016H";
|
||||
const char STR_SUBTYPE_GD00X[] = "\x05""GD_V1""GD_V2";
|
||||
const char STR_SUBTYPE_REDPINE[] = "\x04""Fast""Slow";
|
||||
const char STR_SUBTYPE_POTENSIC[] = "\x03""A20";
|
||||
const char STR_SUBTYPE_ZSX[] = "\x07""280JJRC";
|
||||
const char STR_SUBTYPE_HEIGHT[] = "\x03""5ch""8ch";
|
||||
const char STR_SUBTYPE_FX816[] = "\x03""P38";
|
||||
const char STR_SUBTYPE_XN297DUMP[] = "\x07""250Kbps""1Mbps\0 ""2Mbps\0 ""Auto\0 ""NRF\0 ";
|
||||
const char STR_SUBTYPE_ESKY150[] = "\x03""4ch""7ch";
|
||||
const char STR_SUBTYPE_ESKY150V2[] = "\x05""150V2";
|
||||
const char STR_SUBTYPE_V911S[] = "\x05""V911S""E119\0";
|
||||
const char STR_SUBTYPE_XK[] = "\x04""X450""X420";
|
||||
const char STR_SUBTYPE_FRSKYR9[] = "\x07""915MHz\0""868MHz\0""915 8ch""868 8ch""FCC\0 ""--\0 ""FCC 8ch""-- 8ch\0";
|
||||
const char STR_SUBTYPE_ESKY[] = "\x03""Std""ET4";
|
||||
const char STR_SUBTYPE_PROPEL[] = "\x04""74-Z";
|
||||
const char STR_SUBTYPE_FRSKY_RX[] = "\x07""RX\0 ""CloneTX""EraseTX";
|
||||
const char STR_SUBTYPE_FRSKYL[] = "\x08""LR12\0 ""LR12 6ch";
|
||||
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[] = "\x04""Pro\0""Lite";
|
||||
const char STR_SUBTYPE_V761[] = "\x03""3ch""4ch";
|
||||
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_FUTABA[] = "\x05""SFHSS";
|
||||
const char STR_SUBTYPE_JJRC345[] = "\x08""JJRC345\0""SkyTmblr";
|
||||
|
||||
enum
|
||||
{
|
||||
OPTION_NONE,
|
||||
OPTION_OPTION,
|
||||
OPTION_RFTUNE,
|
||||
OPTION_VIDFREQ,
|
||||
OPTION_FIXEDID,
|
||||
OPTION_TELEM,
|
||||
OPTION_SRVFREQ,
|
||||
OPTION_MAXTHR,
|
||||
OPTION_RFCHAN,
|
||||
OPTION_RFPOWER,
|
||||
};
|
||||
|
||||
#define NO_SUBTYPE nullptr
|
||||
|
||||
const mm_protocol_definition multi_protocols[] = {
|
||||
// Protocol number, Protocol String, Number of sub_protocols, Sub_protocol strings, Option type
|
||||
#if defined(ASSAN_NRF24L01_INO)
|
||||
{PROTO_ASSAN, STR_ASSAN, 0, NO_SUBTYPE, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(BAYANG_NRF24L01_INO)
|
||||
{PROTO_BAYANG, STR_BAYANG, 6, STR_SUBTYPE_BAYANG, OPTION_TELEM },
|
||||
#endif
|
||||
#if defined(BAYANG_RX_NRF24L01_INO)
|
||||
{PROTO_BAYANG_RX, STR_BAYANG_RX, 0, NO_SUBTYPE, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(BUGS_A7105_INO)
|
||||
{PROTO_BUGS, STR_BUGS, 0, NO_SUBTYPE, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(BUGSMINI_NRF24L01_INO)
|
||||
{PROTO_BUGSMINI, STR_BUGSMINI, 2, STR_SUBTYPE_BUGS_MINI, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(CABELL_NRF24L01_INO)
|
||||
{PROTO_CABELL, STR_CABELL, 8, STR_SUBTYPE_CABELL, OPTION_OPTION },
|
||||
#endif
|
||||
#if defined(CFLIE_NRF24L01_INO)
|
||||
{PROTO_CFLIE, STR_CFLIE, 0, NO_SUBTYPE, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(CG023_NRF24L01_INO)
|
||||
{PROTO_CG023, STR_CG023, 2, STR_SUBTYPE_CG023, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(CORONA_CC2500_INO)
|
||||
{PROTO_CORONA, STR_CORONA, 3, STR_SUBTYPE_CORONA, OPTION_RFTUNE },
|
||||
#endif
|
||||
#if defined(CX10_NRF24L01_INO)
|
||||
{PROTO_CX10, STR_CX10, 7, STR_SUBTYPE_CX10, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(DEVO_CYRF6936_INO)
|
||||
{PROTO_DEVO, STR_DEVO, 5, STR_SUBTYPE_DEVO, OPTION_FIXEDID },
|
||||
#endif
|
||||
#if defined(DM002_NRF24L01_INO)
|
||||
{PROTO_DM002, STR_DM002, 0, NO_SUBTYPE, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(DSM_CYRF6936_INO)
|
||||
{PROTO_DSM, STR_DSM, 5, STR_SUBTYPE_DSM, OPTION_MAXTHR },
|
||||
#endif
|
||||
#if defined(DSM_RX_CYRF6936_INO)
|
||||
{PROTO_DSM_RX, STR_DSM_RX, 0, NO_SUBTYPE, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(E010R5_CYRF6936_INO)
|
||||
{PROTO_E010R5, STR_E010R5, 0, NO_SUBTYPE, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(E016HV2_CC2500_INO)
|
||||
{PROTO_E016HV2, STR_E016HV2, 0, NO_SUBTYPE, OPTION_RFTUNE },
|
||||
#endif
|
||||
#if defined(E01X_NRF24L01_INO)
|
||||
{PROTO_E01X, STR_E01X, 3, STR_SUBTYPE_E01X, OPTION_OPTION },
|
||||
#endif
|
||||
#if defined(E129_CYRF6936_INO)
|
||||
{PROTO_E129, STR_E129, 0, NO_SUBTYPE, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(ESKY_NRF24L01_INO)
|
||||
{PROTO_ESKY, STR_ESKY, 2, STR_SUBTYPE_ESKY, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(ESKY150_NRF24L01_INO)
|
||||
{PROTO_ESKY150, STR_ESKY150, 2, STR_SUBTYPE_ESKY150, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(ESKY150V2_CC2500_INO)
|
||||
{PROTO_ESKY150V2, STR_ESKY150V2, 1, STR_SUBTYPE_ESKY150V2, OPTION_RFTUNE },
|
||||
#endif
|
||||
#if defined(FLYSKY_A7105_INO)
|
||||
{PROTO_FLYSKY, STR_FLYSKY, 5, STR_SUBTYPE_FLYSKY, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(AFHDS2A_A7105_INO)
|
||||
{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(FQ777_NRF24L01_INO)
|
||||
{PROTO_FQ777, STR_FQ777, 0, NO_SUBTYPE, OPTION_NONE },
|
||||
#endif
|
||||
//OpenTX 2.3.x issue: DO NOT CHANGE ORDER below
|
||||
#if defined(FRSKY_RX_CC2500_INO)
|
||||
{PROTO_FRSKY_RX, STR_FRSKY_RX, 3, STR_SUBTYPE_FRSKY_RX, OPTION_RFTUNE },
|
||||
#endif
|
||||
#if defined(FRSKYD_CC2500_INO)
|
||||
{PROTO_FRSKYD, STR_FRSKYD, 2, STR_SUBTYPE_FRSKYD, OPTION_RFTUNE },
|
||||
#endif
|
||||
#if defined(FRSKYV_CC2500_INO)
|
||||
{PROTO_FRSKYV, STR_FRSKYV, 0, NO_SUBTYPE, OPTION_RFTUNE },
|
||||
#endif
|
||||
#if defined(FRSKYX_CC2500_INO)
|
||||
{PROTO_FRSKYX, STR_FRSKYX, 6, STR_SUBTYPE_FRSKYX, OPTION_RFTUNE },
|
||||
{PROTO_FRSKYX2, STR_FRSKYX2, 6, STR_SUBTYPE_FRSKYX, OPTION_RFTUNE },
|
||||
#endif
|
||||
//OpenTX 2.3.x issue: DO NOT CHANGE ORDER above
|
||||
#if defined(FRSKYL_CC2500_INO)
|
||||
{PROTO_FRSKYL, STR_FRSKYL, 2, STR_SUBTYPE_FRSKYL, OPTION_RFTUNE },
|
||||
#endif
|
||||
#if defined(FRSKYR9_SX1276_INO)
|
||||
{PROTO_FRSKY_R9, STR_FRSKYR9, 8, STR_SUBTYPE_FRSKYR9, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(FUTABA_CC2500_INO)
|
||||
{PROTO_FUTABA, STR_FUTABA, 1, STR_SUBTYPE_FUTABA, OPTION_RFTUNE },
|
||||
#endif
|
||||
#if defined(FX816_NRF24L01_INO)
|
||||
{PROTO_FX816, STR_FX816, 1, STR_SUBTYPE_FX816, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(FY326_NRF24L01_INO)
|
||||
{PROTO_FY326, STR_FY326, 2, STR_SUBTYPE_FY326, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(GD00X_NRF24L01_INO)
|
||||
{PROTO_GD00X, STR_GD00X, 2, STR_SUBTYPE_GD00X, OPTION_RFTUNE },
|
||||
#endif
|
||||
#if defined(GW008_NRF24L01_INO)
|
||||
{PROTO_GW008, STR_GW008, 0, NO_SUBTYPE, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(H8_3D_NRF24L01_INO)
|
||||
{PROTO_H8_3D, STR_H8_3D, 4, STR_SUBTYPE_H83D, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(HEIGHT_A7105_INO)
|
||||
{PROTO_HEIGHT, STR_HEIGHT, 2, STR_SUBTYPE_HEIGHT, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(HISKY_NRF24L01_INO)
|
||||
{PROTO_HISKY, STR_HISKY, 2, STR_SUBTYPE_HISKY, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(HITEC_CC2500_INO)
|
||||
{PROTO_HITEC, STR_HITEC, 3, STR_SUBTYPE_HITEC, OPTION_RFTUNE },
|
||||
#endif
|
||||
#if defined(HONTAI_NRF24L01_INO)
|
||||
{PROTO_HONTAI, STR_HONTAI, 4, STR_SUBTYPE_HONTAI, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(HOTT_CC2500_INO)
|
||||
{PROTO_HOTT, STR_HOTT, 2, STR_SUBTYPE_HOTT, OPTION_RFTUNE },
|
||||
#endif
|
||||
#if defined(HUBSAN_A7105_INO)
|
||||
{PROTO_HUBSAN, STR_HUBSAN, 3, STR_SUBTYPE_HUBSAN, OPTION_VIDFREQ },
|
||||
#endif
|
||||
#if defined(J6PRO_CYRF6936_INO)
|
||||
{PROTO_J6PRO, STR_J6PRO, 0, NO_SUBTYPE, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(JJRC345_NRF24L01_INO)
|
||||
{PROTO_JJRC345, STR_JJRC345, 2, STR_SUBTYPE_JJRC345, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(KF606_NRF24L01_INO)
|
||||
{PROTO_KF606, STR_KF606, 0, NO_SUBTYPE, OPTION_RFTUNE },
|
||||
#endif
|
||||
#if defined(KN_NRF24L01_INO)
|
||||
{PROTO_KN, STR_KN, 2, STR_SUBTYPE_KN, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(KYOSHO_A7105_INO)
|
||||
{PROTO_KYOSHO, STR_KYOSHO, 2, STR_SUBTYPE_KYOSHO, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(LOLI_NRF24L01_INO)
|
||||
{PROTO_LOLI, STR_LOLI, 0, NO_SUBTYPE, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(MJXQ_NRF24L01_INO)
|
||||
{PROTO_MJXQ, STR_MJXQ, 7, STR_SUBTYPE_MJXQ, OPTION_RFTUNE },
|
||||
#endif
|
||||
#if defined(MLINK_CYRF6936_INO)
|
||||
{PROTO_MLINK, STR_MLINK, 0, NO_SUBTYPE, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(MT99XX_NRF24L01_INO)
|
||||
{PROTO_MT99XX, STR_MT99XX, 6, STR_SUBTYPE_MT99, OPTION_NONE },
|
||||
#endif
|
||||
#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
|
||||
#if defined(POTENSIC_NRF24L01_INO)
|
||||
{PROTO_POTENSIC, STR_POTENSIC, 1, STR_SUBTYPE_POTENSIC, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(PROPEL_NRF24L01_INO)
|
||||
{PROTO_PROPEL, STR_PROPEL, 1, STR_SUBTYPE_PROPEL, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(CX10_NRF24L01_INO)
|
||||
{PROTO_Q2X2, STR_Q2X2, 3, STR_SUBTYPE_Q2X2, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(Q303_NRF24L01_INO)
|
||||
{PROTO_Q303, STR_Q303, 4, STR_SUBTYPE_Q303, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(Q90C_NRF24L01_INO)
|
||||
{PROTO_Q90C, STR_Q90C, 0, NO_SUBTYPE, OPTION_RFTUNE },
|
||||
#endif
|
||||
#if defined(RLINK_CC2500_INO)
|
||||
{PROTO_RLINK, STR_RLINK, 3, 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
|
||||
#if defined(SHENQI_NRF24L01_INO)
|
||||
{PROTO_SHENQI, STR_SHENQI, 0, NO_SUBTYPE, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(SKYARTEC_CC2500_INO)
|
||||
{PROTO_SKYARTEC, STR_SKYARTEC, 0, NO_SUBTYPE, OPTION_RFTUNE },
|
||||
#endif
|
||||
#if defined(SLT_NRF24L01_INO)
|
||||
{PROTO_SLT, STR_SLT, 5, STR_SUBTYPE_SLT, OPTION_RFTUNE },
|
||||
#endif
|
||||
#if defined(SYMAX_NRF24L01_INO)
|
||||
{PROTO_SYMAX, STR_SYMAX, 2, STR_SUBTYPE_SYMAX, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(TIGER_NRF24L01_INO)
|
||||
{PROTO_TIGER, STR_TIGER , 0, NO_SUBTYPE, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(TRAXXAS_CYRF6936_INO)
|
||||
{PROTO_TRAXXAS, STR_TRAXXAS, 1, STR_SUBTYPE_TRAXXAS, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(V2X2_NRF24L01_INO)
|
||||
{PROTO_V2X2, STR_V2X2, 3, STR_SUBTYPE_V2X2, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(V761_NRF24L01_INO)
|
||||
{PROTO_V761, STR_V761, 2, STR_SUBTYPE_V761, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(V911S_NRF24L01_INO)
|
||||
{PROTO_V911S, STR_V911S, 2, STR_SUBTYPE_V911S, OPTION_RFTUNE },
|
||||
#endif
|
||||
#if defined(WK2x01_CYRF6936_INO)
|
||||
{PROTO_WK2x01, STR_WK2x01, 6, STR_SUBTYPE_WK2x01, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(WFLY_CYRF6936_INO)
|
||||
{PROTO_WFLY, STR_WFLY, 1, STR_SUBTYPE_WFLY, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(WFLY2_A7105_INO)
|
||||
{PROTO_WFLY2, STR_WFLY2, 1, STR_SUBTYPE_WFLY2, OPTION_OPTION },
|
||||
#endif
|
||||
#if defined(XK_NRF24L01_INO)
|
||||
{PROTO_XK, STR_XK , 2, STR_SUBTYPE_XK, OPTION_RFTUNE },
|
||||
#endif
|
||||
#if defined(XN297DUMP_NRF24L01_INO)
|
||||
{PROTO_XN297DUMP, STR_XN297DUMP, 5, STR_SUBTYPE_XN297DUMP, OPTION_RFCHAN },
|
||||
#endif
|
||||
#if defined(YD717_NRF24L01_INO)
|
||||
{PROTO_YD717, STR_YD717, 5, STR_SUBTYPE_YD717, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(ZSX_NRF24L01_INO)
|
||||
{PROTO_ZSX, STR_ZSX, 1, STR_SUBTYPE_ZSX, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(TEST_CC2500_INO)
|
||||
{PROTO_TEST, STR_TEST, 0, NO_SUBTYPE, OPTION_RFTUNE },
|
||||
#endif
|
||||
#if defined(NANORF_NRF24L01_INO)
|
||||
{PROTO_NANORF, STR_NANORF, 0, NO_SUBTYPE, OPTION_NONE },
|
||||
#endif
|
||||
{0x00, nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
|
||||
#endif
|
||||
467
Multiprotocol/Multi_Protos.ino
Normal file
467
Multiprotocol/Multi_Protos.ino
Normal file
@@ -0,0 +1,467 @@
|
||||
/*
|
||||
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/>.
|
||||
*/
|
||||
|
||||
const char STR_FLYSKY[] ="FlySky";
|
||||
const char STR_HUBSAN[] ="Hubsan";
|
||||
const char STR_FRSKYD[] ="FrSky D";
|
||||
const char STR_HISKY[] ="Hisky";
|
||||
const char STR_V2X2[] ="V2x2";
|
||||
const char STR_DSM[] ="DSM";
|
||||
const char STR_DSM_RX[] ="DSM_RX";
|
||||
const char STR_DEVO[] ="Devo";
|
||||
const char STR_YD717[] ="YD717";
|
||||
const char STR_KN[] ="KN";
|
||||
const char STR_SYMAX[] ="SymaX";
|
||||
const char STR_SLT[] ="SLT";
|
||||
const char STR_CX10[] ="CX10";
|
||||
const char STR_CG023[] ="CG023";
|
||||
const char STR_BAYANG[] ="Bayang";
|
||||
const char STR_FRSKYL[] ="FrSky L";
|
||||
const char STR_FRSKYX[] ="FrSky X";
|
||||
const char STR_FRSKYX2[] ="FrSkyX2";
|
||||
const char STR_ESKY[] ="ESky";
|
||||
const char STR_MT99XX[] ="MT99XX";
|
||||
const char STR_MJXQ[] ="MJXq";
|
||||
const char STR_SHENQI[] ="Shenqi";
|
||||
const char STR_FY326[] ="FY326";
|
||||
const char STR_FUTABA[] ="Futaba";
|
||||
const char STR_J6PRO[] ="J6 Pro";
|
||||
const char STR_JJRC345[] ="JJRC345";
|
||||
const char STR_JOYSWAY[] ="JOYSWAY";
|
||||
const char STR_FQ777[] ="FQ777";
|
||||
const char STR_ASSAN[] ="Assan";
|
||||
const char STR_FRSKYV[] ="FrSky V";
|
||||
const char STR_HONTAI[] ="Hontai";
|
||||
const char STR_AFHDS2A[] ="FlSky2A";
|
||||
const char STR_Q2X2[] ="Q2x2";
|
||||
const char STR_WK2x01[] ="Walkera";
|
||||
const char STR_Q303[] ="Q303";
|
||||
const char STR_Q90C[] ="Q90C";
|
||||
const char STR_GW008[] ="GW008";
|
||||
const char STR_DM002[] ="DM002";
|
||||
const char STR_CABELL[] ="Cabell";
|
||||
const char STR_ESKY150[] ="Esky150";
|
||||
const char STR_ESKY150V2[] ="EskyV2";
|
||||
const char STR_H8_3D[] ="H8 3D";
|
||||
const char STR_CORONA[] ="Corona";
|
||||
const char STR_CFLIE[] ="CFlie";
|
||||
const char STR_HITEC[] ="Hitec";
|
||||
const char STR_WFLY[] ="WFLY";
|
||||
const char STR_WFLY2[] ="WFLY2";
|
||||
const char STR_BUGS[] ="Bugs";
|
||||
const char STR_BUGSMINI[] ="BugMini";
|
||||
const char STR_TRAXXAS[] ="Traxxas";
|
||||
const char STR_NCC1701[] ="NCC1701";
|
||||
const char STR_E01X[] ="E01X";
|
||||
const char STR_V911S[] ="V911S";
|
||||
const char STR_GD00X[] ="GD00x";
|
||||
const char STR_V761[] ="V761";
|
||||
const char STR_KF606[] ="KF606";
|
||||
const char STR_REDPINE[] ="Redpine";
|
||||
const char STR_POTENSIC[] ="Potensi";
|
||||
const char STR_ZSX[] ="ZSX";
|
||||
const char STR_HEIGHT[] ="Height";
|
||||
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_BAYANG_RX[] ="BayanRX";
|
||||
const char STR_PELIKAN[] ="Pelikan";
|
||||
const char STR_TIGER[] ="Tiger";
|
||||
const char STR_XK[] ="XK";
|
||||
const char STR_XN297DUMP[] ="XN297DP";
|
||||
const char STR_FRSKYR9[] ="FrSkyR9";
|
||||
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_MLINK[] ="M-Link";
|
||||
const char STR_TEST[] ="Test";
|
||||
const char STR_NANORF[] ="NanoRF";
|
||||
const char STR_E016HV2[] ="E016Hv2";
|
||||
const char STR_E010R5[] ="E010r5";
|
||||
const char STR_LOLI[] ="LOLI";
|
||||
const char STR_E129[] ="E129";
|
||||
const char STR_E016H[] ="E016H";
|
||||
const char STR_IKEAANSLUTA[]="Ansluta";
|
||||
const char STR_CONFIG[] ="Config";
|
||||
const char STR_LOSI[] ="Losi";
|
||||
const char STR_MOULDKG[] ="MouldKg";
|
||||
|
||||
const char STR_SUBTYPE_FLYSKY[] = "\x04""Std\0""V9x9""V6x6""V912""CX20";
|
||||
const char STR_SUBTYPE_HUBSAN[] = "\x04""H107""H301""H501";
|
||||
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";
|
||||
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";
|
||||
const char STR_SUBTYPE_SYMAX[] = "\x03""Std""X5C";
|
||||
const char STR_SUBTYPE_SLT[] = "\x06""V1_6ch""V2_8ch""Q100\0 ""Q200\0 ""MR100\0";
|
||||
const char STR_SUBTYPE_CX10[] = "\x07""Green\0 ""Blue\0 ""DM007\0 ""-\0 ""JC3015a""JC3015b""MK33041";
|
||||
const char STR_SUBTYPE_CG023[] = "\x05""Std\0 ""YD829";
|
||||
const char STR_SUBTYPE_BAYANG[] = "\x07""Std\0 ""H8S3D\0 ""X16 AH\0""IRDrone""DHD D4\0""QX100\0 ";
|
||||
const char STR_SUBTYPE_MT99[] = "\x06""MT99\0 ""H7\0 ""YZ\0 ""LS\0 ""FY805\0""A180\0 ""Dragon";
|
||||
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""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";
|
||||
const char STR_SUBTYPE_CABELL[] = "\x07""V3\0 ""V3 Telm""-\0 ""-\0 ""-\0 ""-\0 ""F-Safe\0""Unbind\0";
|
||||
const char STR_SUBTYPE_H83D[] = "\x07""Std\0 ""H20H\0 ""H20Mini""H30Mini";
|
||||
const char STR_SUBTYPE_CORONA[] = "\x05""V1\0 ""V2\0 ""FD V3";
|
||||
const char STR_SUBTYPE_HITEC[] = "\x07""Optima\0""Opt Hub""Minima\0";
|
||||
const char STR_SUBTYPE_BUGS_MINI[] = "\x06""Std\0 ""Bugs3H";
|
||||
const char STR_SUBTYPE_TRAXXAS[] = "\x04""6519";
|
||||
const char STR_SUBTYPE_E01X[] = "\x05""E012\0""E015\0";
|
||||
const char STR_SUBTYPE_GD00X[] = "\x05""GD_V1""GD_V2";
|
||||
const char STR_SUBTYPE_REDPINE[] = "\x04""Fast""Slow";
|
||||
const char STR_SUBTYPE_POTENSIC[] = "\x03""A20";
|
||||
const char STR_SUBTYPE_ZSX[] = "\x07""280JJRC";
|
||||
const char STR_SUBTYPE_HEIGHT[] = "\x03""5ch""8ch";
|
||||
const char STR_SUBTYPE_FX816[] = "\x03""P38";
|
||||
const char STR_SUBTYPE_XN297DUMP[] = "\x07""250Kbps""1Mbps\0 ""2Mbps\0 ""Auto\0 ""NRF\0 ""CC2500\0";
|
||||
const char STR_SUBTYPE_ESKY150[] = "\x03""4ch""7ch";
|
||||
const char STR_SUBTYPE_ESKY150V2[] = "\x05""150V2";
|
||||
const char STR_SUBTYPE_V911S[] = "\x05""V911S""E119\0";
|
||||
const char STR_SUBTYPE_XK[] = "\x04""X450""X420";
|
||||
const char STR_SUBTYPE_FRSKYR9[] = "\x07""915MHz\0""868MHz\0""915 8ch""868 8ch""FCC\0 ""--\0 ""FCC 8ch""-- 8ch\0";
|
||||
const char STR_SUBTYPE_ESKY[] = "\x03""Std""ET4";
|
||||
const char STR_SUBTYPE_PROPEL[] = "\x04""74-Z";
|
||||
const char STR_SUBTYPE_FRSKYL[] = "\x08""LR12\0 ""LR12 6ch";
|
||||
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_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_FUTABA[] = "\x05""SFHSS";
|
||||
const char STR_SUBTYPE_JJRC345[] = "\x08""JJRC345\0""SkyTmblr";
|
||||
const char STR_SUBTYPE_MOULKG[] = "\x06""Analog""Digit\0";
|
||||
|
||||
#define NO_SUBTYPE nullptr
|
||||
|
||||
#ifdef SEND_CPPM
|
||||
const char STR_SUB_FRSKY_RX[] = "\x07""Multi\0 ""CloneTX""EraseTX""CPPM\0 ";
|
||||
#define FRCPPM 4
|
||||
const char STR_CPPM[] = "\x05""Multi""CPPM\0";
|
||||
#define NBR_CPPM 2
|
||||
#else
|
||||
const char STR_SUB_FRSKY_RX[] = "\x07""Multi\0 ""CloneTX""EraseTX";
|
||||
#define FRCPPM 3
|
||||
#define STR_CPPM NO_SUBTYPE
|
||||
#define NBR_CPPM 0
|
||||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
OPTION_NONE,
|
||||
OPTION_OPTION,
|
||||
OPTION_RFTUNE,
|
||||
OPTION_VIDFREQ,
|
||||
OPTION_FIXEDID,
|
||||
OPTION_TELEM,
|
||||
OPTION_SRVFREQ,
|
||||
OPTION_MAXTHR,
|
||||
OPTION_RFCHAN,
|
||||
OPTION_RFPOWER,
|
||||
OPTION_WBUS,
|
||||
};
|
||||
|
||||
const mm_protocol_definition multi_protocols[] = {
|
||||
// Protocol number, Protocol String, Sub_protocol strings, Number of sub_protocols, Option type, Failsafe, ChMap, RF switch, Init, Callback
|
||||
#if defined(MULTI_CONFIG_INO)
|
||||
{PROTO_CONFIG, STR_CONFIG, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, 0, CONFIG_init, CONFIG_callback },
|
||||
#endif
|
||||
#if defined(ASSAN_NRF24L01_INO)
|
||||
{PROTO_ASSAN, STR_ASSAN, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_NRF, ASSAN_init, ASSAN_callback },
|
||||
#endif
|
||||
#if defined(BAYANG_NRF24L01_INO)
|
||||
{PROTO_BAYANG, STR_BAYANG, STR_SUBTYPE_BAYANG, 6, OPTION_TELEM, 0, 0, SW_NRF, BAYANG_init, BAYANG_callback },
|
||||
#endif
|
||||
#if defined(BAYANG_RX_NRF24L01_INO)
|
||||
{PROTO_BAYANG_RX, STR_BAYANG_RX, STR_CPPM, NBR_CPPM, OPTION_NONE, 0, 0, SW_NRF, BAYANG_RX_init, BAYANG_RX_callback },
|
||||
#endif
|
||||
#if defined(BUGS_A7105_INO)
|
||||
{PROTO_BUGS, STR_BUGS, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_A7105, BUGS_init, BUGS_callback },
|
||||
#endif
|
||||
#if defined(BUGSMINI_NRF24L01_INO)
|
||||
{PROTO_BUGSMINI, STR_BUGSMINI, STR_SUBTYPE_BUGS_MINI, 2, OPTION_NONE, 0, 0, SW_NRF, BUGSMINI_init, BUGSMINI_callback },
|
||||
#endif
|
||||
#if defined(CABELL_NRF24L01_INO)
|
||||
{PROTO_CABELL, STR_CABELL, STR_SUBTYPE_CABELL, 8, OPTION_OPTION, 0, 0, SW_NRF, CABELL_init, CABELL_callback },
|
||||
#endif
|
||||
#if defined(CFLIE_NRF24L01_INO)
|
||||
{PROTO_CFLIE, STR_CFLIE, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_NRF, CFLIE_init, CFLIE_callback }, // review protocol
|
||||
#endif
|
||||
#if defined(CG023_NRF24L01_INO)
|
||||
{PROTO_CG023, STR_CG023, STR_SUBTYPE_CG023, 2, OPTION_NONE, 0, 0, SW_NRF, CG023_init, CG023_callback },
|
||||
#endif
|
||||
#if defined(CORONA_CC2500_INO)
|
||||
{PROTO_CORONA, STR_CORONA, STR_SUBTYPE_CORONA, 3, OPTION_RFTUNE, 0, 0, SW_CC2500, CORONA_init, CORONA_callback },
|
||||
#endif
|
||||
#if defined(CX10_NRF24L01_INO)
|
||||
{PROTO_CX10, STR_CX10, STR_SUBTYPE_CX10, 7, OPTION_NONE, 0, 0, SW_NRF, CX10_init, CX10_callback },
|
||||
#endif
|
||||
#if defined(DEVO_CYRF6936_INO)
|
||||
{PROTO_DEVO, STR_DEVO, STR_SUBTYPE_DEVO, 5, OPTION_FIXEDID, 1, 1, SW_CYRF, DEVO_init, DEVO_callback },
|
||||
#endif
|
||||
#if defined(DM002_NRF24L01_INO)
|
||||
{PROTO_DM002, STR_DM002, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_NRF, DM002_init, DM002_callback },
|
||||
#endif
|
||||
#if defined(DSM_CYRF6936_INO)
|
||||
{PROTO_DSM, STR_DSM, STR_SUBTYPE_DSM, 6, OPTION_MAXTHR, 0, 1, SW_CYRF, DSM_init, DSM_callback },
|
||||
#endif
|
||||
#if defined(DSM_RX_CYRF6936_INO)
|
||||
{PROTO_DSM_RX, STR_DSM_RX, STR_CPPM, NBR_CPPM, OPTION_NONE, 0, 1, SW_CYRF, DSM_RX_init, DSM_RX_callback },
|
||||
#endif
|
||||
#if defined(E010R5_CYRF6936_INO)
|
||||
{PROTO_E010R5, STR_E010R5, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_CYRF, E010R5_init, E010R5_callback },
|
||||
#endif
|
||||
#if defined(E016H_NRF24L01_INO)
|
||||
{PROTO_E016H, STR_E016H, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_NRF, E016H_init, E016H_callback },
|
||||
#endif
|
||||
#if defined(E016HV2_CC2500_INO)
|
||||
{PROTO_E016HV2, STR_E016HV2, NO_SUBTYPE, 0, OPTION_RFTUNE, 0, 0, SW_CC2500, E016HV2_init, E016HV2_callback },
|
||||
#endif
|
||||
#if defined(E01X_NRF24L01_INO)
|
||||
{PROTO_E01X, STR_E01X, STR_SUBTYPE_E01X, 2, OPTION_OPTION, 0, 0, SW_NRF, E01X_init, E01X_callback },
|
||||
#endif
|
||||
#if defined(E129_CYRF6936_INO)
|
||||
{PROTO_E129, STR_E129, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_CYRF, E129_init, E129_callback },
|
||||
#endif
|
||||
#if defined(ESKY_NRF24L01_INO)
|
||||
{PROTO_ESKY, STR_ESKY, STR_SUBTYPE_ESKY, 2, OPTION_NONE, 0, 1, SW_NRF, ESKY_init, ESKY_callback },
|
||||
#endif
|
||||
#if defined(ESKY150_NRF24L01_INO)
|
||||
{PROTO_ESKY150, STR_ESKY150, STR_SUBTYPE_ESKY150, 2, OPTION_NONE, 0, 0, SW_NRF, ESKY150_init, ESKY150_callback },
|
||||
#endif
|
||||
#if defined(ESKY150V2_CC2500_INO)
|
||||
{PROTO_ESKY150V2, STR_ESKY150V2, STR_SUBTYPE_ESKY150V2, 1, OPTION_RFTUNE, 0, 1, SW_CC2500, ESKY150V2_init, ESKY150V2_callback },
|
||||
#endif
|
||||
#if defined(FLYSKY_A7105_INO)
|
||||
{PROTO_FLYSKY, STR_FLYSKY, STR_SUBTYPE_FLYSKY, 5, OPTION_NONE, 0, 1, SW_A7105, FLYSKY_init, FLYSKY_callback },
|
||||
#endif
|
||||
#if defined(AFHDS2A_A7105_INO)
|
||||
{PROTO_AFHDS2A, STR_AFHDS2A, STR_SUBTYPE_AFHDS2A, 8, OPTION_SRVFREQ, 1, 1, SW_A7105, AFHDS2A_init, AFHDS2A_callback },
|
||||
#endif
|
||||
#if defined(AFHDS2A_RX_A7105_INO)
|
||||
{PROTO_AFHDS2A_RX, STR_AFHDS2A_RX,STR_CPPM, NBR_CPPM, OPTION_NONE, 0, 0, SW_A7105, AFHDS2A_RX_init, AFHDS2A_RX_callback },
|
||||
#endif
|
||||
#if defined(FQ777_NRF24L01_INO)
|
||||
{PROTO_FQ777, STR_FQ777, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_NRF, FQ777_init, FQ777_callback },
|
||||
#endif
|
||||
//OpenTX 2.3.x issue: DO NOT CHANGE ORDER below
|
||||
#if defined(FRSKY_RX_CC2500_INO)
|
||||
{PROTO_FRSKY_RX, STR_FRSKY_RX, STR_SUB_FRSKY_RX, FRCPPM, OPTION_RFTUNE, 0, 0, SW_CC2500, FRSKY_RX_init, FRSKY_RX_callback },
|
||||
#endif
|
||||
#if defined(FRSKYD_CC2500_INO)
|
||||
{PROTO_FRSKYD, STR_FRSKYD, STR_SUBTYPE_FRSKYD, 2, OPTION_RFTUNE, 0, 0, SW_CC2500, FRSKYD_init, FRSKYD_callback },
|
||||
#endif
|
||||
#if defined(FRSKYV_CC2500_INO)
|
||||
{PROTO_FRSKYV, STR_FRSKYV, NO_SUBTYPE, 0, OPTION_RFTUNE, 0, 0, SW_CC2500, FRSKYV_init, FRSKYV_callback },
|
||||
#endif
|
||||
#if defined(FRSKYX_CC2500_INO)
|
||||
{PROTO_FRSKYX, STR_FRSKYX, STR_SUBTYPE_FRSKYX, 6, OPTION_RFTUNE, 1, 0, SW_CC2500, FRSKYX_init, FRSKYX_callback },
|
||||
{PROTO_FRSKYX2, STR_FRSKYX2, STR_SUBTYPE_FRSKYX, 6, OPTION_RFTUNE, 1, 0, SW_CC2500, FRSKYX_init, FRSKYX_callback },
|
||||
#endif
|
||||
//OpenTX 2.3.x issue: DO NOT CHANGE ORDER above
|
||||
#if defined(FRSKYL_CC2500_INO)
|
||||
{PROTO_FRSKYL, STR_FRSKYL, STR_SUBTYPE_FRSKYL, 2, OPTION_RFTUNE, 0, 0, SW_CC2500, FRSKYL_init, FRSKYL_callback },
|
||||
#endif
|
||||
#if defined(FRSKYR9_SX1276_INO)
|
||||
#if MULTI_5IN1_INTERNAL == T18
|
||||
{PROTO_FRSKY_R9, STR_FRSKYR9, STR_SUBTYPE_FRSKYR9, 8, OPTION_NONE, 1, 0, 0, FRSKYR9_init, FRSKYR9_callback },
|
||||
#else // DIY & T-Lite
|
||||
{PROTO_FRSKY_R9, STR_FRSKYR9, STR_SUBTYPE_FRSKYR9, 8, OPTION_RFPOWER, 1, 0, 0, FRSKYR9_init, FRSKYR9_callback },
|
||||
#endif
|
||||
#endif
|
||||
#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, STR_SUBTYPE_FX816, 1, OPTION_NONE, 0, 0, SW_NRF, FX816_init, FX816_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 },
|
||||
#endif
|
||||
#if defined(GD00X_CCNRF_INO)
|
||||
{PROTO_GD00X, STR_GD00X, STR_SUBTYPE_GD00X, 2, OPTION_RFTUNE, 0, 0, SW_NRF, GD00X_init, GD00X_callback },
|
||||
#endif
|
||||
#if defined(GW008_NRF24L01_INO)
|
||||
{PROTO_GW008, STR_GW008, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_NRF, GW008_init, GW008_callback },
|
||||
#endif
|
||||
#if defined(H8_3D_NRF24L01_INO)
|
||||
{PROTO_H8_3D, STR_H8_3D, STR_SUBTYPE_H83D, 4, OPTION_NONE, 0, 0, SW_NRF, H8_3D_init, H8_3D_callback },
|
||||
#endif
|
||||
#if defined(HEIGHT_A7105_INO)
|
||||
{PROTO_HEIGHT, STR_HEIGHT, STR_SUBTYPE_HEIGHT, 2, OPTION_NONE, 0, 0, SW_A7105, HEIGHT_init, HEIGHT_callback },
|
||||
#endif
|
||||
#if defined(HISKY_NRF24L01_INO)
|
||||
{PROTO_HISKY, STR_HISKY, STR_SUBTYPE_HISKY, 2, OPTION_NONE, 1, 1, SW_NRF, HISKY_init, HISKY_callback },
|
||||
#endif
|
||||
#if defined(HITEC_CC2500_INO)
|
||||
{PROTO_HITEC, STR_HITEC, STR_SUBTYPE_HITEC, 3, OPTION_RFTUNE, 0, 0, SW_CC2500, HITEC_init, HITEC_callback },
|
||||
#endif
|
||||
#if defined(HONTAI_NRF24L01_INO)
|
||||
{PROTO_HONTAI, STR_HONTAI, STR_SUBTYPE_HONTAI, 4, OPTION_NONE, 0, 0, SW_NRF, HONTAI_init, HONTAI_callback },
|
||||
#endif
|
||||
#if defined(HOTT_CC2500_INO)
|
||||
{PROTO_HOTT, STR_HOTT, STR_SUBTYPE_HOTT, 2, OPTION_RFTUNE, 1, 0, SW_CC2500, HOTT_init, HOTT_callback },
|
||||
#endif
|
||||
#if defined(HUBSAN_A7105_INO)
|
||||
{PROTO_HUBSAN, STR_HUBSAN, STR_SUBTYPE_HUBSAN, 3, OPTION_VIDFREQ, 0, 0, SW_A7105, HUBSAN_init, HUBSAN_callback },
|
||||
#endif
|
||||
#if defined(IKEAANSLUTA_CC2500_INO)
|
||||
{PROTO_IKEAANSLUTA,STR_IKEAANSLUTA,NO_SUBTYPE, 0, OPTION_OPTION, 0, 0, SW_CC2500, IKEAANSLUTA_init,IKEAANSLUTA_callback },
|
||||
#endif
|
||||
#if defined(J6PRO_CYRF6936_INO)
|
||||
{PROTO_J6PRO, STR_J6PRO, NO_SUBTYPE, 0, OPTION_NONE, 0, 1, SW_CYRF, J6PRO_init, J6PRO_callback },
|
||||
#endif
|
||||
#if defined(JJRC345_NRF24L01_INO)
|
||||
{PROTO_JJRC345, STR_JJRC345, STR_SUBTYPE_JJRC345, 2, OPTION_NONE, 0, 0, SW_NRF, JJRC345_init, JJRC345_callback },
|
||||
#endif
|
||||
#if defined(JOYSWAY_A7105_INO)
|
||||
{PROTO_JOYSWAY, STR_JOYSWAY, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_A7105, JOYSWAY_init, JOYSWAY_callback },
|
||||
#endif
|
||||
#if defined(KF606_CCNRF_INO)
|
||||
{PROTO_KF606, STR_KF606, NO_SUBTYPE, 0, OPTION_RFTUNE, 0, 0, SW_NRF, KF606_init, KF606_callback },
|
||||
#endif
|
||||
#if defined(KN_NRF24L01_INO)
|
||||
{PROTO_KN, STR_KN, STR_SUBTYPE_KN, 2, OPTION_NONE, 0, 0, SW_NRF, KN_init, KN_callback },
|
||||
#endif
|
||||
#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(LOLI_NRF24L01_INO)
|
||||
{PROTO_LOLI, STR_LOLI, NO_SUBTYPE, 0, OPTION_NONE, 1, 0, SW_NRF, LOLI_init, LOLI_callback },
|
||||
#endif
|
||||
#if defined(LOSI_CYRF6936_INO)
|
||||
{PROTO_LOSI, STR_LOSI, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_CYRF, LOSI_init, LOSI_callback },
|
||||
#endif
|
||||
#if defined(MJXQ_CCNRF_INO)
|
||||
{PROTO_MJXQ, STR_MJXQ, STR_SUBTYPE_MJXQ, 7, OPTION_NONE, 0, 0, SW_NRF, MJXQ_init, MJXQ_callback },
|
||||
#endif
|
||||
#if defined(MLINK_CYRF6936_INO)
|
||||
{PROTO_MLINK, STR_MLINK, NO_SUBTYPE, 0, OPTION_NONE, 1, 0, SW_CYRF, MLINK_init, MLINK_callback },
|
||||
#endif
|
||||
#if defined(MOULDKG_NRF24L01_INO)
|
||||
{PROTO_MOULDKG, STR_MOULDKG, STR_SUBTYPE_MOULKG, 2, OPTION_OPTION, 0, 0, SW_NRF, MOULDKG_init, MOULDKG_callback },
|
||||
#endif
|
||||
#if defined(MT99XX_CCNRF_INO)
|
||||
{PROTO_MT99XX, STR_MT99XX, STR_SUBTYPE_MT99, 7, OPTION_NONE, 0, 0, SW_NRF, MT99XX_init, MT99XX_callback },
|
||||
#endif
|
||||
#if defined(NCC1701_NRF24L01_INO)
|
||||
{PROTO_NCC1701, STR_NCC1701, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_NRF, NCC_init, NCC_callback },
|
||||
#endif
|
||||
#if defined(OMP_CCNRF_INO)
|
||||
{PROTO_OMP, STR_OMP, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_NRF, OMP_init, OMP_callback },
|
||||
#endif
|
||||
#if defined(PELIKAN_A7105_INO)
|
||||
{PROTO_PELIKAN, STR_PELIKAN, STR_SUBTYPE_PELIKAN, 3, OPTION_NONE, 0, 1, SW_A7105, PELIKAN_init, PELIKAN_callback },
|
||||
#endif
|
||||
#if defined(POTENSIC_NRF24L01_INO)
|
||||
{PROTO_POTENSIC, STR_POTENSIC, STR_SUBTYPE_POTENSIC, 1, OPTION_NONE, 0, 0, SW_NRF, POTENSIC_init, POTENSIC_callback },
|
||||
#endif
|
||||
#if defined(PROPEL_NRF24L01_INO)
|
||||
{PROTO_PROPEL, STR_PROPEL, STR_SUBTYPE_PROPEL, 1, OPTION_NONE, 0, 0, SW_NRF, PROPEL_init, PROPEL_callback },
|
||||
#endif
|
||||
#if defined(CX10_NRF24L01_INO)
|
||||
{PROTO_Q2X2, STR_Q2X2, STR_SUBTYPE_Q2X2, 3, OPTION_NONE, 0, 0, SW_NRF, CX10_init, CX10_callback },
|
||||
#endif
|
||||
#if defined(Q303_CCNRF_INO)
|
||||
{PROTO_Q303, STR_Q303, STR_SUBTYPE_Q303, 4, OPTION_NONE, 0, 0, SW_NRF, Q303_init, Q303_callback },
|
||||
#endif
|
||||
#if defined(Q90C_CCNRF_INO)
|
||||
{PROTO_Q90C, STR_Q90C, NO_SUBTYPE, 0, OPTION_RFTUNE, 0, 0, SW_NRF, Q90C_init, Q90C_callback },
|
||||
#endif
|
||||
#if defined(RLINK_CC2500_INO)
|
||||
{PROTO_RLINK, STR_RLINK, STR_SUBTYPE_RLINK, 3, OPTION_RFTUNE, 0, 0, SW_CC2500, RLINK_init, RLINK_callback },
|
||||
#endif
|
||||
#if defined(REALACC_NRF24L01_INO)
|
||||
{PROTO_REALACC, STR_REALACC, STR_SUBTYPE_REALACC, 1, OPTION_NONE, 0, 0, SW_NRF, REALACC_init, REALACC_callback },
|
||||
#endif
|
||||
#if defined(REDPINE_CC2500_INO)
|
||||
{PROTO_REDPINE, STR_REDPINE, STR_SUBTYPE_REDPINE, 2, OPTION_RFTUNE, 0, 0, SW_CC2500, REDPINE_init, REDPINE_callback },
|
||||
#endif
|
||||
#if defined(SCANNER_CC2500_INO)
|
||||
{PROTO_SCANNER, STR_SCANNER, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_CC2500, SCANNER_init, SCANNER_callback },
|
||||
#endif
|
||||
#if defined(SHENQI_NRF24L01_INO)
|
||||
{PROTO_SHENQI, STR_SHENQI, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_NRF, SHENQI_init, SHENQI_callback },
|
||||
#endif
|
||||
#if defined(SKYARTEC_CC2500_INO)
|
||||
{PROTO_SKYARTEC, STR_SKYARTEC, NO_SUBTYPE, 0, OPTION_RFTUNE, 0, 1, SW_CC2500, SKYARTEC_init, SKYARTEC_callback },
|
||||
#endif
|
||||
#if defined(SLT_CCNRF_INO)
|
||||
{PROTO_SLT, STR_SLT, STR_SUBTYPE_SLT, 5, OPTION_RFTUNE, 0, 1, SW_NRF, SLT_init, SLT_callback },
|
||||
#endif
|
||||
#if defined(SYMAX_NRF24L01_INO)
|
||||
{PROTO_SYMAX, STR_SYMAX, STR_SUBTYPE_SYMAX, 2, OPTION_NONE, 0, 0, SW_NRF, SYMAX_init, SYMAX_callback },
|
||||
#endif
|
||||
#if defined(TIGER_NRF24L01_INO)
|
||||
{PROTO_TIGER, STR_TIGER, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_NRF, TIGER_init, TIGER_callback },
|
||||
#endif
|
||||
#if defined(TRAXXAS_CYRF6936_INO)
|
||||
{PROTO_TRAXXAS, STR_TRAXXAS, STR_SUBTYPE_TRAXXAS, 1, OPTION_NONE, 0, 0, SW_CYRF, TRAXXAS_init, TRAXXAS_callback },
|
||||
#endif
|
||||
#if defined(V2X2_NRF24L01_INO)
|
||||
{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 },
|
||||
#endif
|
||||
#if defined(V911S_CCNRF_INO)
|
||||
{PROTO_V911S, STR_V911S, STR_SUBTYPE_V911S, 2, OPTION_RFTUNE, 0, 0, SW_NRF, V911S_init, V911S_callback },
|
||||
#endif
|
||||
#if defined(WK2x01_CYRF6936_INO)
|
||||
{PROTO_WK2x01, STR_WK2x01, STR_SUBTYPE_WK2x01, 6, OPTION_NONE, 1, 1, SW_CYRF, WK_init, WK_callback },
|
||||
#endif
|
||||
#if defined(WFLY_CYRF6936_INO)
|
||||
{PROTO_WFLY, STR_WFLY, STR_SUBTYPE_WFLY, 1, OPTION_NONE, 1, 0, SW_CYRF, WFLY_init, WFLY_callback },
|
||||
#endif
|
||||
#if defined(WFLY2_A7105_INO)
|
||||
{PROTO_WFLY2, STR_WFLY2, STR_SUBTYPE_WFLY2, 1, OPTION_OPTION, 1, 0, SW_A7105, WFLY2_init, WFLY2_callback },
|
||||
// {PROTO_WFLY2, STR_WFLY2, STR_SUBTYPE_WFLY2, 1, OPTION_WBUS, 1, 0, SW_A7105, WFLY2_init, WFLY2_callback },// crash OpenTX...
|
||||
#endif
|
||||
#if defined(XK_CCNRF_INO)
|
||||
{PROTO_XK, STR_XK, STR_SUBTYPE_XK, 2, OPTION_RFTUNE, 0, 0, SW_NRF, XK_init, XK_callback },
|
||||
#endif
|
||||
#if defined(XN297DUMP_NRF24L01_INO)
|
||||
{PROTO_XN297DUMP, STR_XN297DUMP, STR_SUBTYPE_XN297DUMP, 6, OPTION_RFCHAN, 0, 0, SW_NRF, XN297Dump_init, XN297Dump_callback },
|
||||
#endif
|
||||
#if defined(YD717_NRF24L01_INO)
|
||||
{PROTO_YD717, STR_YD717, STR_SUBTYPE_YD717, 5, OPTION_NONE, 0, 0, SW_NRF, YD717_init, YD717_callback },
|
||||
#endif
|
||||
#if defined(ZSX_NRF24L01_INO)
|
||||
{PROTO_ZSX, STR_ZSX, STR_SUBTYPE_ZSX, 1, OPTION_NONE, 0, 0, SW_NRF, ZSX_init, ZSX_callback },
|
||||
#endif
|
||||
#if defined(TEST_CC2500_INO)
|
||||
{PROTO_TEST, STR_TEST, NO_SUBTYPE, 0, OPTION_RFTUNE, 0, 0, SW_NRF, TEST_init, TEST_callback },
|
||||
#endif
|
||||
#if defined(NANORF_NRF24L01_INO)
|
||||
{PROTO_NANORF, STR_NANORF, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_NRF, NANORF_init, NANORF_callback },
|
||||
#endif
|
||||
{0xFF, nullptr, nullptr, 0, 0, 0, 0, 0, nullptr, nullptr }
|
||||
};
|
||||
@@ -19,14 +19,15 @@
|
||||
#define VERSION_MAJOR 1
|
||||
#define VERSION_MINOR 3
|
||||
#define VERSION_REVISION 2
|
||||
#define VERSION_PATCH_LEVEL 30
|
||||
#define VERSION_PATCH_LEVEL 86
|
||||
|
||||
#define MODE_SERIAL 0
|
||||
|
||||
//******************
|
||||
// Protocols
|
||||
//******************
|
||||
enum PROTOCOLS
|
||||
{
|
||||
MODE_SERIAL = 0, // Serial commands
|
||||
PROTO_FLYSKY = 1, // =>A7105
|
||||
PROTO_HUBSAN = 2, // =>A7105
|
||||
PROTO_FRSKYD = 3, // =>CC2500
|
||||
@@ -109,6 +110,13 @@ enum PROTOCOLS
|
||||
PROTO_E010R5 = 81, // =>CYRF6936
|
||||
PROTO_LOLI = 82, // =>NRF24L01
|
||||
PROTO_E129 = 83, // =>CYRF6936
|
||||
PROTO_JOYSWAY = 84, // =>A7105
|
||||
PROTO_E016H = 85, // =>NRF24L01
|
||||
PROTO_CONFIG = 86, // Module config
|
||||
PROTO_IKEAANSLUTA = 87, // =>CC2500
|
||||
PROTO_WILLIFM = 88, // 27/35ab/40/41/72 MHz module external project
|
||||
PROTO_LOSI = 89, // =>CYRF6936
|
||||
PROTO_MOULDKG = 90, // =>NRF24L01
|
||||
|
||||
PROTO_NANORF = 126, // =>NRF24L01
|
||||
PROTO_TEST = 127, // =>CC2500
|
||||
@@ -148,11 +156,12 @@ enum Hisky
|
||||
};
|
||||
enum DSM
|
||||
{
|
||||
DSM2_22 = 0,
|
||||
DSM2_11 = 1,
|
||||
DSMX_22 = 2,
|
||||
DSMX_11 = 3,
|
||||
DSM_AUTO = 4,
|
||||
DSM2_1F = 0,
|
||||
DSM2_2F = 1,
|
||||
DSMX_1F = 2,
|
||||
DSMX_2F = 3,
|
||||
DSM_AUTO = 4,
|
||||
DSMR = 5,
|
||||
};
|
||||
enum YD717
|
||||
{
|
||||
@@ -220,6 +229,7 @@ enum MT99XX
|
||||
LS = 3,
|
||||
FY805 = 4,
|
||||
A180 = 5,
|
||||
DRAGON = 6,
|
||||
};
|
||||
enum MJXQ
|
||||
{
|
||||
@@ -351,6 +361,8 @@ enum XN297DUMP
|
||||
XN297DUMP_1M = 1,
|
||||
XN297DUMP_2M = 2,
|
||||
XN297DUMP_AUTO = 3,
|
||||
XN297DUMP_NRF = 4,
|
||||
XN297DUMP_CC2500 = 5,
|
||||
};
|
||||
enum FRSKY_R9
|
||||
{
|
||||
@@ -374,6 +386,7 @@ enum FRSKY_RX
|
||||
FRSKY_RX = 0,
|
||||
FRSKY_CLONE = 1,
|
||||
FRSKY_ERASE = 2,
|
||||
FRSKY_CPPM = 3,
|
||||
};
|
||||
|
||||
enum FRSKYL
|
||||
@@ -392,6 +405,7 @@ enum PELIKAN
|
||||
{
|
||||
PELIKAN_PRO = 0,
|
||||
PELIKAN_LITE= 1,
|
||||
PELIKAN_SCX24=2,
|
||||
};
|
||||
|
||||
enum V761
|
||||
@@ -425,12 +439,19 @@ enum RLINK
|
||||
RLINK_DUMBORC = 2,
|
||||
};
|
||||
|
||||
enum MOULDKG
|
||||
{
|
||||
MOULDKG_ANALOG = 0,
|
||||
MOULDKG_DIGIT = 1,
|
||||
};
|
||||
|
||||
#define NONE 0
|
||||
#define P_HIGH 1
|
||||
#define P_LOW 0
|
||||
#define AUTOBIND 1
|
||||
#define NO_AUTOBIND 0
|
||||
|
||||
//PPM protocols
|
||||
struct PPM_Parameters
|
||||
{
|
||||
uint8_t protocol;
|
||||
@@ -442,6 +463,33 @@ struct PPM_Parameters
|
||||
uint32_t chan_order;
|
||||
};
|
||||
|
||||
//Callback
|
||||
typedef uint16_t (*uint16_function_t) (void); //pointer to a function with no parameters which return an uint16_t integer
|
||||
typedef void (*void_function_t ) (void); //pointer to a function with no parameters which returns nothing
|
||||
|
||||
//Protocols definition
|
||||
struct __attribute__((__packed__)) mm_protocol_definition {
|
||||
uint8_t protocol;
|
||||
const char *ProtoString;
|
||||
const char *SubProtoString;
|
||||
uint8_t nbrSubProto : 4;
|
||||
uint8_t optionType : 4;
|
||||
uint8_t failSafe : 1;
|
||||
uint8_t chMap : 1;
|
||||
uint8_t rfSwitch : 2;
|
||||
void_function_t Init;
|
||||
uint16_function_t CallBack;
|
||||
};
|
||||
extern const mm_protocol_definition multi_protocols[];
|
||||
|
||||
enum RF_SWITCH
|
||||
{
|
||||
SW_A7105 = 0, //antenna RF1
|
||||
SW_CC2500 = 1, //antenna RF2
|
||||
SW_NRF = 2, //antenna RF3
|
||||
SW_CYRF = 3, //antenna RF4
|
||||
};
|
||||
|
||||
// Telemetry
|
||||
enum MultiPacketTypes
|
||||
{
|
||||
@@ -459,17 +507,13 @@ enum MultiPacketTypes
|
||||
MULTI_TELEMETRY_AFHDS2A_AC = 12,
|
||||
MULTI_TELEMETRY_RX_CHANNELS = 13,
|
||||
MULTI_TELEMETRY_HOTT = 14,
|
||||
MULTI_TELEMETRY_MLINK = 15,
|
||||
MULTI_TELEMETRY_CONFIG = 16,
|
||||
};
|
||||
|
||||
// Macros
|
||||
#define NOP() __asm__ __volatile__("nop")
|
||||
|
||||
//***************
|
||||
//*** Tests ***
|
||||
//***************
|
||||
#define IS_FAILSAFE_PROTOCOL ( (protocol==PROTO_HISKY && sub_protocol==HK310) || protocol==PROTO_AFHDS2A || protocol==PROTO_DEVO || protocol==PROTO_FUTABA || protocol==PROTO_WK2x01 || protocol== PROTO_HOTT || protocol==PROTO_FRSKYX || protocol==PROTO_FRSKYX2 || protocol==PROTO_FRSKY_R9 || protocol==PROTO_WFLY2 || protocol==PROTO_LOLI || protocol==PROTO_MLINK)
|
||||
#define IS_CHMAP_PROTOCOL ( (protocol==PROTO_HISKY && sub_protocol==HK310) || protocol==PROTO_AFHDS2A || protocol==PROTO_DEVO || protocol==PROTO_FUTABA || protocol==PROTO_WK2x01 || protocol== PROTO_DSM || protocol==PROTO_SLT || protocol==PROTO_FLYSKY || (protocol==PROTO_KYOSHO && sub_protocol==KYOSHO_HYPE) || protocol==PROTO_ESKY || protocol==PROTO_J6PRO || protocol==PROTO_PELIKAN || protocol==PROTO_SKYARTEC || protocol==PROTO_ESKY150V2 || protocol==PROTO_DSM_RX)
|
||||
|
||||
//***************
|
||||
//*** Flags ***
|
||||
//***************
|
||||
@@ -558,6 +602,11 @@ enum MultiPacketTypes
|
||||
#define DISABLE_TELEM_on protocol_flags3 |= _BV(3)
|
||||
#define IS_DISABLE_TELEM_on ( ( protocol_flags3 & _BV(3) ) !=0 )
|
||||
#define IS_DISABLE_TELEM_off ( ( protocol_flags3 & _BV(3) ) ==0 )
|
||||
//Valid/invalid sub_proto
|
||||
#define SUB_PROTO_VALID protocol_flags3 &= ~_BV(6)
|
||||
#define SUB_PROTO_INVALID protocol_flags3 |= _BV(6)
|
||||
#define IS_SUB_PROTO_INVALID ( ( protocol_flags3 & _BV(6) ) !=0 )
|
||||
#define IS_SUB_PROTO_VALID ( ( protocol_flags3 & _BV(6) ) ==0 )
|
||||
//LBT power
|
||||
#define LBT_POWER_off protocol_flags3 &= ~_BV(7)
|
||||
#define LBT_POWER_on protocol_flags3 |= _BV(7)
|
||||
@@ -710,6 +759,10 @@ enum CYRF_POWER
|
||||
#define CYRF_RANGE_POWER CYRF_POWER_1 // 1/30 of the full power distance
|
||||
#define CYRF_BIND_POWER CYRF_POWER_0
|
||||
|
||||
// SX1276
|
||||
#define JP_T18 1
|
||||
#define JP_TLite 2
|
||||
|
||||
enum TXRX_State {
|
||||
TXRX_OFF,
|
||||
TX_EN,
|
||||
@@ -730,6 +783,8 @@ enum {
|
||||
#define SPEED_125K 3
|
||||
|
||||
/** EEPROM Layout */
|
||||
#define EEPROM_CID_INIT_OFFSET 0 // 1 byte flag that Cyrf ID is initialized
|
||||
#define EEPROM_CID_OFFSET 1 // 6 bytes Cyrf ID
|
||||
#define EEPROM_ID_OFFSET 10 // Module ID (4 bytes)
|
||||
#define EEPROM_BANK_OFFSET 15 // Current bank number (1 byte)
|
||||
#define EEPROM_ID_VALID_OFFSET 20 // 1 byte flag that ID is valid
|
||||
@@ -746,7 +801,8 @@ enum {
|
||||
#define FRSKYX_CLONE_EEPROM_OFFSET 822 // (1) format + (3) TX ID + (47) channels, 51 bytes, end is 873
|
||||
#define FRSKYX2_CLONE_EEPROM_OFFSET 873 // (1) format + (3) TX ID, 4 bytes, end is 877
|
||||
#define DSM_RX_EEPROM_OFFSET 877 // (4) TX ID + format, 5 bytes, end is 882
|
||||
//#define CONFIG_EEPROM_OFFSET 882 // Current configuration of the multimodule
|
||||
#define MOULDKG_EEPROM_OFFSET 882 // RX ID, 3 bytes per model, end is 882+64*3=1074
|
||||
//#define CONFIG_EEPROM_OFFSET 1074 // Current configuration of the multimodule
|
||||
|
||||
/* STM32 Flash Size */
|
||||
#ifndef DISABLE_FLASH_SIZE_CHECK
|
||||
@@ -857,6 +913,8 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
||||
E010R5 81
|
||||
LOLI 82
|
||||
E129 83
|
||||
JOYSWAY 84
|
||||
E016H 85
|
||||
BindBit=> 0x80 1=Bind/0=No
|
||||
AutoBindBit=> 0x40 1=Yes /0=No
|
||||
RangeCheck=> 0x20 1=Yes /0=No
|
||||
@@ -877,10 +935,10 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
||||
Hisky 0
|
||||
HK310 1
|
||||
sub_protocol==DSM
|
||||
DSM2_22 0
|
||||
DSM2_11 1
|
||||
DSMX_22 2
|
||||
DSMX_11 3
|
||||
DSM2_1F 0
|
||||
DSM2_2F 1
|
||||
DSMX_1F 2
|
||||
DSMX_2F 3
|
||||
DSM_AUTO 4
|
||||
sub_protocol==YD717
|
||||
YD717 0
|
||||
@@ -1002,7 +1060,6 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
||||
sub_protocol==E01X
|
||||
E012 0
|
||||
E015 1
|
||||
E016H 2
|
||||
sub_protocol==GD00X
|
||||
GD_V1 0
|
||||
GD_V2 1
|
||||
@@ -1044,6 +1101,7 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
||||
sub_protocol==PELIKAN
|
||||
PELIKAN_PRO 0
|
||||
PELIKAN_LITE 1
|
||||
PELIKAN_SCX24 2
|
||||
sub_protocol==V761
|
||||
V761_3CH 0
|
||||
V761_4CH 1
|
||||
@@ -1086,35 +1144,8 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
||||
DSM: Stream[27..33] Forward Programming
|
||||
*/
|
||||
/*
|
||||
Multimodule Status
|
||||
Based on #define MULTI_STATUS
|
||||
|
||||
Serial: 100000 Baud 8e2 (same as input)
|
||||
|
||||
Format: header (2 bytes) + data (variable)
|
||||
[0] = 'M' (0x4d)
|
||||
[1] Length (excluding the 2 header bytes)
|
||||
[2-xx] data
|
||||
|
||||
Type = 0x01 Multimodule Status:
|
||||
[2] Flags
|
||||
0x01 = Input signal detected
|
||||
0x02 = Serial mode enabled
|
||||
0x04 = Protocol is valid
|
||||
0x08 = Module is in binding mode
|
||||
0x10 = Module waits a bind event to load the protocol
|
||||
0x20 = Current protocol supports failsafe
|
||||
0x40 = Current protocol supports disable channel mapping
|
||||
0x80 = Data buffer is almost full
|
||||
[3] major
|
||||
[4] minor
|
||||
[5] revision
|
||||
[6] patchlevel,
|
||||
version of multi code, should be displayed as major.minor.revision.patchlevel
|
||||
*/
|
||||
/*
|
||||
Multiprotocol telemetry/command definition for OpenTX
|
||||
Based on #define MULTI_TELEMETRY enables OpenTX to get the multimodule status and select the correct telemetry type automatically.
|
||||
Multiprotocol telemetry/command definition for OpenTX and erskyTX
|
||||
Based on #define MULTI_TELEMETRY enables OpenTX and erskyTX to get the multimodule status and select the correct telemetry type automatically.
|
||||
|
||||
Serial: 100000 Baud 8e2 (same as input)
|
||||
|
||||
@@ -1155,16 +1186,17 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
||||
[11] Prev valid protocol number, can be used to skip invalid protocols
|
||||
[12..18] Protocol name [7], not null terminated if prototcol len == 7
|
||||
[19>>4] Option text to be displayed:
|
||||
OPTION_NONE 0
|
||||
OPTION_OPTION 1
|
||||
OPTION_RFTUNE 2
|
||||
OPTION_VIDFREQ 3
|
||||
OPTION_FIXEDID 4
|
||||
OPTION_TELEM 5
|
||||
OPTION_SRVFREQ 6
|
||||
OPTION_MAXTHR 7
|
||||
OPTION_RFCHAN 8
|
||||
OPTION_RFPOWER 9
|
||||
OPTION_NONE 0 Hidden field
|
||||
OPTION_OPTION 1 "Option:" value=-128..0(default)..127
|
||||
OPTION_RFTUNE 2 "RF freq tune:" value=-128..0(default)..127
|
||||
OPTION_VIDFREQ 3 "Video freq:" value=-128..0(default)..127
|
||||
OPTION_FIXEDID 4 "ID type:" value="Auto":0(default), "Fixed":1
|
||||
OPTION_TELEM 5 "Telem:" value="Off":0(default), "On":1, "Off+Aux":2, "On+Aux":3
|
||||
OPTION_SRVFREQ 6 "Servo freq(Hz):" value="50":0(default).."400":70 => display=50+5*option with option=0..70
|
||||
OPTION_MAXTHR 7 "Max throw:" value="Disabled":0, "Enabled":1
|
||||
OPTION_RFCHAN 8 "Select RF chan:" value=-128..0(default)..127
|
||||
OPTION_RFPOWER 9 "RF power:" "1.6mW":0(default),"2.0mW":1,"2.5mW":2,"3.2mW":3,"4.0mW":4,"5.0mW":5,"6.3mW":6,"7.9mW":7,"10mW\0":8,"13mW\0":9,"16mW\0":10,"20mW\0":11,"25mW\0":12,"32mW\0":13,"40mW\0":14,"50mW\0":15
|
||||
OPTION_WBUS 10 "Output:" "WBUS":0(default),"PPM":1
|
||||
[19&0x0F] Number of sub protocols
|
||||
[20..27] Sub protocol name [8], not null terminated if sub prototcol len == 8
|
||||
If the current protocol is invalid [12..27] are all 0x00.
|
||||
@@ -1238,4 +1270,14 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
||||
data[3] = page
|
||||
data[4-13] = data
|
||||
|
||||
Type 0x0F M-Link telemetry
|
||||
length: 10
|
||||
data[0] = TX_RSSI
|
||||
data[1] = TX_LQI
|
||||
data[2] = telem_type
|
||||
data[3-9] = data
|
||||
|
||||
Type 0x10 Config telemetry
|
||||
length: 22
|
||||
data[0..21] = Config data
|
||||
*/
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -31,25 +31,16 @@ enum {
|
||||
NCC_RX3,
|
||||
};
|
||||
|
||||
static void __attribute__((unused)) NCC_init()
|
||||
static void __attribute__((unused)) NCC_RF_init()
|
||||
{
|
||||
NRF24L01_Initialize();
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
|
||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5-byte RX/TX address
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, (uint8_t*)"\xE7\xE7\xC7\xD7\x67",5);
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, (uint8_t*)"\xE7\xE7\xC7\xD7\x67",5);
|
||||
|
||||
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 Acknowledgment on all data pipes
|
||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 only
|
||||
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, NCC_RX_PACKET_LEN); // Enable rx pipe 0
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_250K); // NRF24L01_BR_1M, NRF24L01_BR_2M, NRF24L01_BR_250K
|
||||
NRF24L01_SetPower();
|
||||
NRF24L01_FlushRx();
|
||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, (0 << NRF24L01_00_EN_CRC) // switch to TX mode and disable CRC
|
||||
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, NCC_RX_PACKET_LEN); // Enable rx pipe 0
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_250K); // NRF24L01_BR_1M, NRF24L01_BR_2M, NRF24L01_BR_250K
|
||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, (0 << NRF24L01_00_EN_CRC) // switch to TX mode and disable CRC
|
||||
| (1 << NRF24L01_00_CRCO)
|
||||
| (1 << NRF24L01_00_PWR_UP)
|
||||
| (0 << NRF24L01_00_PRIM_RX));
|
||||
@@ -247,7 +238,7 @@ const uint8_t PROGMEM NCC_TX_DATA[][6]= {
|
||||
{ 0xC2, 0x93, 0x55, 0x44, 0x4C, 0x0B },
|
||||
};
|
||||
|
||||
uint16_t initNCC(void)
|
||||
void NCC_init(void)
|
||||
{
|
||||
BIND_IN_PROGRESS; // autobind protocol
|
||||
|
||||
@@ -269,9 +260,8 @@ uint16_t initNCC(void)
|
||||
hopping_frequency[4]=0x08; // bind channel 1
|
||||
hopping_frequency[5]=0x2A; // bind channel 2
|
||||
hopping_frequency_no=4; // start with bind
|
||||
NCC_init();
|
||||
NCC_RF_init();
|
||||
phase=NCC_BIND_TX1;
|
||||
return 10000;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
#ifdef NRF24L01_INSTALLED
|
||||
#include "iface_nrf24l01.h"
|
||||
|
||||
#include "iface_xn297.h"
|
||||
|
||||
//---------------------------
|
||||
// NRF24L01+ SPI Specific Functions
|
||||
@@ -28,7 +28,19 @@ void NRF24L01_Initialize()
|
||||
{
|
||||
rf_setup = 0x09;
|
||||
prev_power = 0x00; // Make sure prev_power is inline with current power
|
||||
XN297_SetScrambledMode(XN297_SCRAMBLED);
|
||||
|
||||
//Load most likely default NRF config
|
||||
NRF24L01_FlushTx();
|
||||
NRF24L01_FlushRx();
|
||||
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_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5 bytes rx/tx address
|
||||
NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x00); // no retransmits
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps
|
||||
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x00); // Disable dynamic payload length on all pipes
|
||||
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x01); // Set feature bits off and enable the command NRF24L01_B0_TX_PYLD_NOACK
|
||||
NRF24L01_SetPower();
|
||||
NRF24L01_SetTxRxMode(TX_EN); // Clear data ready, data sent, retransmit and enable CRC 16bits, ready for TX
|
||||
}
|
||||
|
||||
void NRF24L01_WriteReg(uint8_t reg, uint8_t data)
|
||||
@@ -117,13 +129,13 @@ static uint8_t NRF24L01_GetDynamicPayloadSize()
|
||||
return len;
|
||||
}
|
||||
|
||||
void NRF24L01_Activate(uint8_t code)
|
||||
/*void NRF24L01_Activate(uint8_t code)
|
||||
{
|
||||
NRF_CSN_off;
|
||||
SPI_Write(ACTIVATE);
|
||||
SPI_Write(code);
|
||||
NRF_CSN_on;
|
||||
}
|
||||
}*/
|
||||
|
||||
void NRF24L01_SetBitrate(uint8_t bitrate)
|
||||
{
|
||||
@@ -183,11 +195,11 @@ void NRF24L01_SetPower()
|
||||
|
||||
void NRF24L01_SetTxRxMode(enum TXRX_State mode)
|
||||
{
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, (1 << NRF24L01_07_RX_DR) //reset the flag(s)
|
||||
| (1 << NRF24L01_07_TX_DS)
|
||||
| (1 << NRF24L01_07_MAX_RT));
|
||||
if(mode == TX_EN) {
|
||||
NRF_CE_off;
|
||||
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_WriteReg(NRF24L01_00_CONFIG, (1 << NRF24L01_00_EN_CRC) // switch to TX mode
|
||||
| (1 << NRF24L01_00_CRCO)
|
||||
| (1 << NRF24L01_00_PWR_UP));
|
||||
@@ -198,9 +210,6 @@ void NRF24L01_SetTxRxMode(enum TXRX_State mode)
|
||||
if (mode == RX_EN)
|
||||
{
|
||||
NRF_CE_off;
|
||||
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_WriteReg(NRF24L01_00_CONFIG, (1 << NRF24L01_00_EN_CRC) // switch to RX mode
|
||||
| (1 << NRF24L01_00_CRCO)
|
||||
| (1 << NRF24L01_00_PWR_UP)
|
||||
@@ -217,13 +226,6 @@ void NRF24L01_SetTxRxMode(enum TXRX_State mode)
|
||||
|
||||
void NRF24L01_Reset()
|
||||
{
|
||||
//** not in deviation but needed to hot switch between models
|
||||
NRF24L01_Activate(0x73); // Activate feature register
|
||||
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x00); // Disable dynamic payload length on all pipes
|
||||
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x00); // Set feature bits off
|
||||
NRF24L01_Activate(0x73);
|
||||
//**
|
||||
|
||||
NRF24L01_FlushTx();
|
||||
NRF24L01_FlushRx();
|
||||
NRF24L01_Strobe(0xff); // NOP
|
||||
@@ -244,319 +246,6 @@ uint8_t NRF24L01_packet_ack()
|
||||
return PKT_PENDING;
|
||||
}
|
||||
|
||||
|
||||
///////////////
|
||||
// XN297 emulation layer
|
||||
uint8_t xn297_scramble_enabled=XN297_SCRAMBLED; //enabled by default
|
||||
uint8_t xn297_addr_len;
|
||||
uint8_t xn297_tx_addr[5];
|
||||
uint8_t xn297_rx_addr[5];
|
||||
uint8_t xn297_crc = 0;
|
||||
|
||||
// xn297 address / pcf / payload scramble table
|
||||
const uint8_t xn297_scramble[] = {
|
||||
0xE3, 0xB1, 0x4B, 0xEA, 0x85, 0xBC, 0xE5, 0x66,
|
||||
0x0D, 0xAE, 0x8C, 0x88, 0x12, 0x69, 0xEE, 0x1F,
|
||||
0xC7, 0x62, 0x97, 0xD5, 0x0B, 0x79, 0xCA, 0xCC,
|
||||
0x1B, 0x5D, 0x19, 0x10, 0x24, 0xD3, 0xDC, 0x3F,
|
||||
0x8E, 0xC5, 0x2F, 0xAA, 0x16, 0xF3, 0x95 };
|
||||
|
||||
// scrambled, standard mode crc xorout table
|
||||
const uint16_t PROGMEM xn297_crc_xorout_scrambled[] = {
|
||||
0x0000, 0x3448, 0x9BA7, 0x8BBB, 0x85E1, 0x3E8C,
|
||||
0x451E, 0x18E6, 0x6B24, 0xE7AB, 0x3828, 0x814B,
|
||||
0xD461, 0xF494, 0x2503, 0x691D, 0xFE8B, 0x9BA7,
|
||||
0x8B17, 0x2920, 0x8B5F, 0x61B1, 0xD391, 0x7401,
|
||||
0x2138, 0x129F, 0xB3A0, 0x2988, 0x23CA, 0xC0CB,
|
||||
0x0C6C, 0xB329, 0xA0A1, 0x0A16, 0xA9D0 };
|
||||
|
||||
// unscrambled, standard mode crc xorout table
|
||||
const uint16_t PROGMEM xn297_crc_xorout[] = {
|
||||
0x0000, 0x3D5F, 0xA6F1, 0x3A23, 0xAA16, 0x1CAF,
|
||||
0x62B2, 0xE0EB, 0x0821, 0xBE07, 0x5F1A, 0xAF15,
|
||||
0x4F0A, 0xAD24, 0x5E48, 0xED34, 0x068C, 0xF2C9,
|
||||
0x1852, 0xDF36, 0x129D, 0xB17C, 0xD5F5, 0x70D7,
|
||||
0xB798, 0x5133, 0x67DB, 0xD94E, 0x0A5B, 0xE445,
|
||||
0xE6A5, 0x26E7, 0xBDAB, 0xC379, 0x8E20 };
|
||||
|
||||
// scrambled enhanced mode crc xorout table
|
||||
const uint16_t PROGMEM xn297_crc_xorout_scrambled_enhanced[] = {
|
||||
0x0000, 0x7EBF, 0x3ECE, 0x07A4, 0xCA52, 0x343B,
|
||||
0x53F8, 0x8CD0, 0x9EAC, 0xD0C0, 0x150D, 0x5186,
|
||||
0xD251, 0xA46F, 0x8435, 0xFA2E, 0x7EBD, 0x3C7D,
|
||||
0x94E0, 0x3D5F, 0xA685, 0x4E47, 0xF045, 0xB483,
|
||||
0x7A1F, 0xDEA2, 0x9642, 0xBF4B, 0x032F, 0x01D2,
|
||||
0xDC86, 0x92A5, 0x183A, 0xB760, 0xA953 };
|
||||
|
||||
// unscrambled enhanced mode crc xorout table
|
||||
// unused so far
|
||||
#ifdef XN297DUMP_NRF24L01_INO
|
||||
const uint16_t xn297_crc_xorout_enhanced[] = {
|
||||
0x0000, 0x8BE6, 0xD8EC, 0xB87A, 0x42DC, 0xAA89,
|
||||
0x83AF, 0x10E4, 0xE83E, 0x5C29, 0xAC76, 0x1C69,
|
||||
0xA4B2, 0x5961, 0xB4D3, 0x2A50, 0xCB27, 0x5128,
|
||||
0x7CDB, 0x7A14, 0xD5D2, 0x57D7, 0xE31D, 0xCE42,
|
||||
0x648D, 0xBF2D, 0x653B, 0x190C, 0x9117, 0x9A97,
|
||||
0xABFC, 0xE68E, 0x0DE7, 0x28A2, 0x1965 };
|
||||
#endif
|
||||
|
||||
void XN297_SetTXAddr(const uint8_t* addr, uint8_t len)
|
||||
{
|
||||
if (len > 5) len = 5;
|
||||
if (len < 3) len = 3;
|
||||
uint8_t buf[] = { 0x55, 0x0F, 0x71, 0x0C, 0x00 }; // bytes for XN297 preamble 0xC710F55 (28 bit)
|
||||
xn297_addr_len = len;
|
||||
if (xn297_addr_len < 4)
|
||||
for (uint8_t i = 0; i < 4; ++i)
|
||||
buf[i] = buf[i+1];
|
||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, len-2);
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, buf, 5);
|
||||
// Receive address is complicated. We need to use scrambled actual address as a receive address
|
||||
// but the TX code now assumes fixed 4-byte transmit address for preamble. We need to adjust it
|
||||
// first. Also, if the scrambled address begins with 1 nRF24 will look for preamble byte 0xAA
|
||||
// instead of 0x55 to ensure enough 0-1 transitions to tune the receiver. Still need to experiment
|
||||
// with receiving signals.
|
||||
memcpy(xn297_tx_addr, addr, len);
|
||||
}
|
||||
|
||||
void XN297_SetRXAddr(const uint8_t* addr, uint8_t len)
|
||||
{
|
||||
if (len > 5) len = 5;
|
||||
if (len < 3) len = 3;
|
||||
uint8_t buf[] = { 0, 0, 0, 0, 0 };
|
||||
memcpy(buf, addr, len);
|
||||
memcpy(xn297_rx_addr, addr, len);
|
||||
for (uint8_t i = 0; i < xn297_addr_len; ++i)
|
||||
{
|
||||
buf[i] = xn297_rx_addr[i];
|
||||
if(xn297_scramble_enabled)
|
||||
buf[i] ^= xn297_scramble[xn297_addr_len-i-1];
|
||||
}
|
||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, len-2);
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, buf, 5);
|
||||
}
|
||||
|
||||
void XN297_Configure(uint8_t flags)
|
||||
{
|
||||
xn297_crc = !!(flags & _BV(NRF24L01_00_EN_CRC));
|
||||
flags &= ~(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO));
|
||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, flags & 0xFF);
|
||||
}
|
||||
|
||||
void XN297_SetScrambledMode(const uint8_t mode)
|
||||
{
|
||||
xn297_scramble_enabled = mode;
|
||||
}
|
||||
|
||||
void XN297_WritePayload(uint8_t* msg, uint8_t len)
|
||||
{
|
||||
uint8_t buf[32];
|
||||
uint8_t last = 0;
|
||||
|
||||
if (xn297_addr_len < 4)
|
||||
{
|
||||
// If address length (which is defined by receive address length)
|
||||
// is less than 4 the TX address can't fit the preamble, so the last
|
||||
// byte goes here
|
||||
buf[last++] = 0x55;
|
||||
}
|
||||
for (uint8_t i = 0; i < xn297_addr_len; ++i)
|
||||
{
|
||||
buf[last] = xn297_tx_addr[xn297_addr_len-i-1];
|
||||
if(xn297_scramble_enabled)
|
||||
buf[last] ^= xn297_scramble[i];
|
||||
last++;
|
||||
}
|
||||
for (uint8_t i = 0; i < len; ++i)
|
||||
{
|
||||
// bit-reverse bytes in packet
|
||||
buf[last] = bit_reverse(msg[i]);
|
||||
if(xn297_scramble_enabled)
|
||||
buf[last] ^= xn297_scramble[xn297_addr_len+i];
|
||||
last++;
|
||||
}
|
||||
if (xn297_crc)
|
||||
{
|
||||
uint8_t offset = xn297_addr_len < 4 ? 1 : 0;
|
||||
crc = 0xb5d2;
|
||||
for (uint8_t i = offset; i < last; ++i)
|
||||
crc16_update( buf[i], 8);
|
||||
if(xn297_scramble_enabled)
|
||||
crc ^= pgm_read_word(&xn297_crc_xorout_scrambled[xn297_addr_len - 3 + len]);
|
||||
else
|
||||
crc ^= pgm_read_word(&xn297_crc_xorout[xn297_addr_len - 3 + len]);
|
||||
buf[last++] = crc >> 8;
|
||||
buf[last++] = crc & 0xff;
|
||||
}
|
||||
NRF24L01_WritePayload(buf, last);
|
||||
}
|
||||
|
||||
void XN297_WriteEnhancedPayload(uint8_t* msg, uint8_t len, uint8_t noack)
|
||||
{
|
||||
uint8_t packet[32];
|
||||
uint8_t scramble_index=0;
|
||||
uint8_t last = 0;
|
||||
static uint8_t pid=0;
|
||||
|
||||
// address
|
||||
if (xn297_addr_len < 4)
|
||||
{
|
||||
// If address length (which is defined by receive address length)
|
||||
// is less than 4 the TX address can't fit the preamble, so the last
|
||||
// byte goes here
|
||||
packet[last++] = 0x55;
|
||||
}
|
||||
for (uint8_t i = 0; i < xn297_addr_len; ++i)
|
||||
{
|
||||
packet[last] = xn297_tx_addr[xn297_addr_len-i-1];
|
||||
if(xn297_scramble_enabled)
|
||||
packet[last] ^= xn297_scramble[scramble_index++];
|
||||
last++;
|
||||
}
|
||||
|
||||
// pcf
|
||||
packet[last] = (len << 1) | (pid>>1);
|
||||
if(xn297_scramble_enabled)
|
||||
packet[last] ^= xn297_scramble[scramble_index++];
|
||||
last++;
|
||||
packet[last] = (pid << 7) | (noack << 6);
|
||||
|
||||
// payload
|
||||
packet[last]|= bit_reverse(msg[0]) >> 2; // first 6 bit of payload
|
||||
if(xn297_scramble_enabled)
|
||||
packet[last] ^= xn297_scramble[scramble_index++];
|
||||
|
||||
for (uint8_t i = 0; i < len-1; ++i)
|
||||
{
|
||||
last++;
|
||||
packet[last] = (bit_reverse(msg[i]) << 6) | (bit_reverse(msg[i+1]) >> 2);
|
||||
if(xn297_scramble_enabled)
|
||||
packet[last] ^= xn297_scramble[scramble_index++];
|
||||
}
|
||||
|
||||
last++;
|
||||
packet[last] = bit_reverse(msg[len-1]) << 6; // last 2 bit of payload
|
||||
if(xn297_scramble_enabled)
|
||||
packet[last] ^= xn297_scramble[scramble_index++] & 0xc0;
|
||||
|
||||
// crc
|
||||
if (xn297_crc)
|
||||
{
|
||||
uint8_t offset = xn297_addr_len < 4 ? 1 : 0;
|
||||
crc = 0xb5d2;
|
||||
for (uint8_t i = offset; i < last; ++i)
|
||||
crc16_update( packet[i], 8);
|
||||
crc16_update( packet[last] & 0xc0, 2);
|
||||
if (xn297_scramble_enabled)
|
||||
crc ^= pgm_read_word(&xn297_crc_xorout_scrambled_enhanced[xn297_addr_len-3+len]);
|
||||
//else
|
||||
// crc ^= pgm_read_word(&xn297_crc_xorout_enhanced[xn297_addr_len - 3 + len]);
|
||||
|
||||
packet[last++] |= (crc >> 8) >> 2;
|
||||
packet[last++] = ((crc >> 8) << 6) | ((crc & 0xff) >> 2);
|
||||
packet[last++] = (crc & 0xff) << 6;
|
||||
}
|
||||
NRF24L01_WritePayload(packet, last);
|
||||
|
||||
pid++;
|
||||
if(pid>3)
|
||||
pid=0;
|
||||
}
|
||||
|
||||
boolean XN297_ReadPayload(uint8_t* msg, uint8_t len)
|
||||
{ //!!! Don't forget if using CRC to do a +2 on any of the used NRF24L01_11_RX_PW_Px !!!
|
||||
uint8_t buf[32];
|
||||
if (xn297_crc)
|
||||
NRF24L01_ReadPayload(buf, len+2); // Read payload + CRC
|
||||
else
|
||||
NRF24L01_ReadPayload(buf, len);
|
||||
// Decode payload
|
||||
for(uint8_t i=0; i<len; i++)
|
||||
{
|
||||
uint8_t b_in=buf[i];
|
||||
if(xn297_scramble_enabled)
|
||||
b_in ^= xn297_scramble[i+xn297_addr_len];
|
||||
msg[i] = bit_reverse(b_in);
|
||||
}
|
||||
if (!xn297_crc)
|
||||
return true; // No CRC so OK by default...
|
||||
|
||||
// Calculate CRC
|
||||
crc = 0xb5d2;
|
||||
//process address
|
||||
for (uint8_t i = 0; i < xn297_addr_len; ++i)
|
||||
{
|
||||
uint8_t b_in=xn297_rx_addr[xn297_addr_len-i-1];
|
||||
if(xn297_scramble_enabled)
|
||||
b_in ^= xn297_scramble[i];
|
||||
crc16_update( b_in, 8);
|
||||
}
|
||||
//process payload
|
||||
for (uint8_t i = 0; i < len; ++i)
|
||||
crc16_update( buf[i], 8);
|
||||
//xorout
|
||||
if(xn297_scramble_enabled)
|
||||
crc ^= pgm_read_word(&xn297_crc_xorout_scrambled[xn297_addr_len - 3 + len]);
|
||||
else
|
||||
crc ^= pgm_read_word(&xn297_crc_xorout[xn297_addr_len - 3 + len]);
|
||||
//test
|
||||
if( (crc >> 8) == buf[len] && (crc & 0xff) == buf[len+1])
|
||||
return true; // CRC OK
|
||||
return false; // CRC NOK
|
||||
}
|
||||
|
||||
uint8_t XN297_ReadEnhancedPayload(uint8_t* msg, uint8_t len)
|
||||
{ //!!! Don't forget do a +2 and if using CRC add +4 on any of the used NRF24L01_11_RX_PW_Px !!!
|
||||
uint8_t buffer[32];
|
||||
uint8_t pcf_size; // pcf payload size
|
||||
if (xn297_crc)
|
||||
NRF24L01_ReadPayload(buffer, len+4); // Read pcf + payload + CRC
|
||||
else
|
||||
NRF24L01_ReadPayload(buffer, len+2); // Read pcf + payload
|
||||
pcf_size = buffer[0];
|
||||
if(xn297_scramble_enabled)
|
||||
pcf_size ^= xn297_scramble[xn297_addr_len];
|
||||
pcf_size = pcf_size >> 1;
|
||||
for(int i=0; i<len; i++)
|
||||
{
|
||||
msg[i] = bit_reverse((buffer[i+1] << 2) | (buffer[i+2] >> 6));
|
||||
if(xn297_scramble_enabled)
|
||||
msg[i] ^= bit_reverse((xn297_scramble[xn297_addr_len+i+1] << 2) |
|
||||
(xn297_scramble[xn297_addr_len+i+2] >> 6));
|
||||
}
|
||||
|
||||
if (!xn297_crc)
|
||||
return pcf_size; // No CRC so OK by default...
|
||||
|
||||
// Calculate CRC
|
||||
crc = 0xb5d2;
|
||||
//process address
|
||||
for (uint8_t i = 0; i < xn297_addr_len; ++i)
|
||||
{
|
||||
uint8_t b_in=xn297_rx_addr[xn297_addr_len-i-1];
|
||||
if(xn297_scramble_enabled)
|
||||
b_in ^= xn297_scramble[i];
|
||||
crc16_update( b_in, 8);
|
||||
}
|
||||
//process payload
|
||||
for (uint8_t i = 0; i < len+1; ++i)
|
||||
crc16_update( buffer[i], 8);
|
||||
crc16_update( buffer[len+1] & 0xc0, 2);
|
||||
//xorout
|
||||
if (xn297_scramble_enabled)
|
||||
crc ^= pgm_read_word(&xn297_crc_xorout_scrambled_enhanced[xn297_addr_len-3+len]);
|
||||
#ifdef XN297DUMP_NRF24L01_INO
|
||||
else
|
||||
crc ^= pgm_read_word(&xn297_crc_xorout_enhanced[xn297_addr_len - 3 + len]);
|
||||
#endif
|
||||
uint16_t crcxored=(buffer[len+1]<<10)|(buffer[len+2]<<2)|(buffer[len+3]>>6) ;
|
||||
if( crc == crcxored)
|
||||
return pcf_size; // CRC OK
|
||||
return 0; // CRC NOK
|
||||
}
|
||||
|
||||
// End of XN297 emulation
|
||||
|
||||
//
|
||||
// HS6200 emulation layer
|
||||
///////////////////////////
|
||||
|
||||
@@ -12,321 +12,108 @@
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifdef NRF24L01_INSTALLED
|
||||
#if defined(CC2500_INSTALLED) || defined(NRF24L01_INSTALLED)
|
||||
|
||||
#include "iface_nrf250k.h"
|
||||
|
||||
static void __attribute__((unused)) XN297L_Init()
|
||||
{
|
||||
prev_option = option;
|
||||
#ifdef CC2500_INSTALLED
|
||||
if(option==0)
|
||||
#endif
|
||||
{//NRF
|
||||
debugln("Using NRF");
|
||||
PE1_on; //NRF24L01 antenna RF3 by default
|
||||
PE2_off; //NRF24L01 antenna RF3 by default
|
||||
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_250K); // 250Kbps
|
||||
NRF24L01_SetPower();
|
||||
return;
|
||||
}
|
||||
//CC2500
|
||||
#ifdef CC2500_INSTALLED
|
||||
debugln("Using CC2500");
|
||||
xn297_scramble_enabled=XN297_SCRAMBLED; //enabled by default
|
||||
PE1_off; // antenna RF2
|
||||
PE2_on;
|
||||
CC2500_250K_Init();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) XN297L_SetTXAddr(const uint8_t* addr, uint8_t len)
|
||||
{
|
||||
#ifdef CC2500_INSTALLED
|
||||
if(option==0)
|
||||
#endif
|
||||
{//NRF
|
||||
XN297_SetTXAddr(addr,len);
|
||||
return;
|
||||
}
|
||||
//CC2500
|
||||
#ifdef CC2500_INSTALLED
|
||||
if (len > 5) len = 5;
|
||||
if (len < 3) len = 3;
|
||||
xn297_addr_len = len;
|
||||
memcpy(xn297_tx_addr, addr, len);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) XN297L_WritePayload(uint8_t* msg, uint8_t len)
|
||||
{
|
||||
#ifdef CC2500_INSTALLED
|
||||
if(option==0)
|
||||
#endif
|
||||
{//NRF
|
||||
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||
NRF24L01_FlushTx();
|
||||
XN297_WritePayload(msg, len);
|
||||
return;
|
||||
}
|
||||
//CC2500
|
||||
#ifdef CC2500_INSTALLED
|
||||
uint8_t buf[32];
|
||||
uint8_t last = 0;
|
||||
uint8_t i;
|
||||
|
||||
// address
|
||||
for (i = 0; i < xn297_addr_len; ++i)
|
||||
{
|
||||
buf[last] = xn297_tx_addr[xn297_addr_len - i - 1];
|
||||
if(xn297_scramble_enabled)
|
||||
buf[last] ^= xn297_scramble[i];
|
||||
last++;
|
||||
}
|
||||
|
||||
// payload
|
||||
for (i = 0; i < len; ++i) {
|
||||
// bit-reverse bytes in packet
|
||||
buf[last] = bit_reverse(msg[i]);
|
||||
if(xn297_scramble_enabled)
|
||||
buf[last] ^= xn297_scramble[xn297_addr_len+i];
|
||||
last++;
|
||||
}
|
||||
|
||||
// crc
|
||||
crc = 0xb5d2;
|
||||
for (uint8_t i = 0; i < last; ++i)
|
||||
crc16_update( buf[i], 8);
|
||||
if(xn297_scramble_enabled)
|
||||
crc ^= pgm_read_word(&xn297_crc_xorout_scrambled[xn297_addr_len - 3 + len]);
|
||||
else
|
||||
crc ^= pgm_read_word(&xn297_crc_xorout[xn297_addr_len - 3 + len]);
|
||||
buf[last++] = crc >> 8;
|
||||
buf[last++] = crc & 0xff;
|
||||
|
||||
// stop TX/RX
|
||||
CC2500_Strobe(CC2500_SIDLE);
|
||||
// flush tx FIFO
|
||||
CC2500_Strobe(CC2500_SFTX);
|
||||
// packet length
|
||||
CC2500_WriteReg(CC2500_3F_TXFIFO, last + 3);
|
||||
// xn297L preamble
|
||||
CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, (uint8_t*)"\x71\x0f\x55", 3);
|
||||
// xn297 packet
|
||||
CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, buf, last);
|
||||
// transmit
|
||||
CC2500_Strobe(CC2500_STX);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) XN297L_WriteEnhancedPayload(uint8_t* msg, uint8_t len, uint8_t noack)
|
||||
{
|
||||
#ifdef CC2500_INSTALLED
|
||||
if(option==0)
|
||||
#endif
|
||||
{//NRF
|
||||
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||
NRF24L01_FlushTx();
|
||||
XN297_WriteEnhancedPayload(msg, len, noack);
|
||||
return;
|
||||
}
|
||||
//CC2500
|
||||
#ifdef CC2500_INSTALLED
|
||||
uint8_t buf[32];
|
||||
uint8_t scramble_index=0;
|
||||
uint8_t last = 0;
|
||||
static uint8_t pid=0;
|
||||
|
||||
// address
|
||||
for (uint8_t i = 0; i < xn297_addr_len; ++i)
|
||||
{
|
||||
buf[last] = xn297_tx_addr[xn297_addr_len-i-1];
|
||||
if(xn297_scramble_enabled)
|
||||
buf[last] ^= xn297_scramble[scramble_index++];
|
||||
last++;
|
||||
}
|
||||
|
||||
// pcf
|
||||
buf[last] = (len << 1) | (pid>>1);
|
||||
if(xn297_scramble_enabled)
|
||||
buf[last] ^= xn297_scramble[scramble_index++];
|
||||
last++;
|
||||
buf[last] = (pid << 7) | (noack << 6);
|
||||
|
||||
// payload
|
||||
buf[last]|= bit_reverse(msg[0]) >> 2; // first 6 bit of payload
|
||||
if(xn297_scramble_enabled)
|
||||
buf[last] ^= xn297_scramble[scramble_index++];
|
||||
|
||||
for (uint8_t i = 0; i < len-1; ++i)
|
||||
{
|
||||
last++;
|
||||
buf[last] = (bit_reverse(msg[i]) << 6) | (bit_reverse(msg[i+1]) >> 2);
|
||||
if(xn297_scramble_enabled)
|
||||
buf[last] ^= xn297_scramble[scramble_index++];
|
||||
}
|
||||
|
||||
last++;
|
||||
buf[last] = bit_reverse(msg[len-1]) << 6; // last 2 bit of payload
|
||||
if(xn297_scramble_enabled)
|
||||
buf[last] ^= xn297_scramble[scramble_index++] & 0xc0;
|
||||
|
||||
// crc
|
||||
//if (xn297_crc)
|
||||
{
|
||||
crc = 0xb5d2;
|
||||
for (uint8_t i = 0; i < last; ++i)
|
||||
crc16_update( buf[i], 8);
|
||||
crc16_update( buf[last] & 0xc0, 2);
|
||||
if (xn297_scramble_enabled)
|
||||
crc ^= pgm_read_word(&xn297_crc_xorout_scrambled_enhanced[xn297_addr_len-3+len]);
|
||||
//else
|
||||
// crc ^= pgm_read_word(&xn297_crc_xorout_enhanced[xn297_addr_len - 3 + len]);
|
||||
|
||||
buf[last++] |= (crc >> 8) >> 2;
|
||||
buf[last++] = ((crc >> 8) << 6) | ((crc & 0xff) >> 2);
|
||||
buf[last++] = (crc & 0xff) << 6;
|
||||
}
|
||||
|
||||
pid++;
|
||||
pid &= 3;
|
||||
|
||||
// stop TX/RX
|
||||
CC2500_Strobe(CC2500_SIDLE);
|
||||
// flush tx FIFO
|
||||
CC2500_Strobe(CC2500_SFTX);
|
||||
// packet length
|
||||
CC2500_WriteReg(CC2500_3F_TXFIFO, last + 3);
|
||||
// xn297L preamble
|
||||
CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, (uint8_t*)"\x71\x0F\x55", 3);
|
||||
// xn297 packet
|
||||
CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, buf, last);
|
||||
// transmit
|
||||
CC2500_Strobe(CC2500_STX);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) XN297L_HoppingCalib(uint8_t num_freq)
|
||||
{ //calibrate hopping frequencies
|
||||
#ifdef CC2500_INSTALLED
|
||||
if(option==0)
|
||||
#endif
|
||||
return; //NRF
|
||||
#ifdef CC2500_INSTALLED
|
||||
CC2500_250K_HoppingCalib(num_freq);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) XN297L_Hopping(uint8_t index)
|
||||
{
|
||||
#ifdef CC2500_INSTALLED
|
||||
if(option==0)
|
||||
#endif
|
||||
{//NRF
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[index]);
|
||||
return;
|
||||
}
|
||||
#ifdef CC2500_INSTALLED
|
||||
CC2500_250K_Hopping(index);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) XN297L_RFChannel(uint8_t number)
|
||||
{ //change channel
|
||||
#ifdef CC2500_INSTALLED
|
||||
if(option==0)
|
||||
#endif
|
||||
{//NRF
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, number);
|
||||
return;
|
||||
}
|
||||
#ifdef CC2500_INSTALLED
|
||||
CC2500_250K_RFChannel(number);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) XN297L_SetPower()
|
||||
{
|
||||
#ifdef CC2500_INSTALLED
|
||||
if(option==0)
|
||||
#endif
|
||||
{//NRF
|
||||
NRF24L01_SetPower();
|
||||
return;
|
||||
}
|
||||
#ifdef CC2500_INSTALLED
|
||||
CC2500_SetPower();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) XN297L_SetFreqOffset()
|
||||
{ // Frequency offset
|
||||
#ifdef CC2500_INSTALLED
|
||||
if(option==0 && prev_option==0)
|
||||
#endif
|
||||
return; //NRF
|
||||
#ifdef CC2500_INSTALLED
|
||||
if (prev_option != option)
|
||||
{
|
||||
if(prev_option==0 || option==0)
|
||||
CHANGE_PROTOCOL_FLAG_on; // switch from NRF <-> CC2500
|
||||
CC2500_SetFreqOffset();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
uint8_t cc2500_nrf_tx_addr[5], cc2500_nrf_addr_len;
|
||||
|
||||
static void __attribute__((unused)) NRF250K_SetTXAddr(uint8_t* addr, uint8_t len)
|
||||
{
|
||||
if (len > 5) len = 5;
|
||||
if (len < 3) len = 3;
|
||||
#ifdef CC2500_INSTALLED
|
||||
if(option==0)
|
||||
#endif
|
||||
{//NRF
|
||||
#if defined(CC2500_INSTALLED)
|
||||
cc2500_nrf_addr_len = len;
|
||||
memcpy(cc2500_nrf_tx_addr, addr, len);
|
||||
#elif defined(NRF24L01_INSTALLED)
|
||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, len-2);
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, addr, len);
|
||||
return;
|
||||
}
|
||||
//CC2500
|
||||
#ifdef CC2500_INSTALLED
|
||||
CC2500_250K_NRF_SetTXAddr(addr, len);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) NRF250K_WritePayload(uint8_t* msg, uint8_t len)
|
||||
{
|
||||
#ifdef CC2500_INSTALLED
|
||||
if(option==0)
|
||||
#endif
|
||||
{//NRF
|
||||
NRF24L01_FlushTx();
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, _BV(NRF24L01_07_TX_DS) | _BV(NRF24L01_07_RX_DR) | _BV(NRF24L01_07_MAX_RT));
|
||||
NRF24L01_WritePayload(msg, len);
|
||||
return;
|
||||
}
|
||||
//CC2500
|
||||
#ifdef CC2500_INSTALLED
|
||||
CC2500_250K_NRF_WritePayload(msg, len);
|
||||
#if defined(CC2500_INSTALLED)
|
||||
#if defined(ESKY150V2_CC2500_INO)
|
||||
uint8_t buf[158];
|
||||
#else
|
||||
uint8_t buf[35];
|
||||
#endif
|
||||
uint8_t last = 0;
|
||||
uint8_t i;
|
||||
|
||||
//nrf preamble
|
||||
if(cc2500_nrf_tx_addr[cc2500_nrf_addr_len - 1] & 0x80)
|
||||
buf[0]=0xAA;
|
||||
else
|
||||
buf[0]=0x55;
|
||||
last++;
|
||||
// address
|
||||
for (i = 0; i < cc2500_nrf_addr_len; ++i)
|
||||
buf[last++] = cc2500_nrf_tx_addr[cc2500_nrf_addr_len - i - 1];
|
||||
// payload
|
||||
for (i = 0; i < len; ++i)
|
||||
buf[last++] = msg[i];
|
||||
|
||||
// crc
|
||||
crc = 0xffff;
|
||||
for (uint8_t i = 1; i < last; ++i)
|
||||
crc16_update( buf[i], 8);
|
||||
buf[last++] = crc >> 8;
|
||||
buf[last++] = crc & 0xff;
|
||||
buf[last++] = 0;
|
||||
|
||||
//for(uint8_t i=0;i<last;i++)
|
||||
// debug("%02X ",buf[i]);
|
||||
//debugln("");
|
||||
// stop TX/RX
|
||||
CC2500_Strobe(CC2500_SIDLE);
|
||||
// flush tx FIFO
|
||||
CC2500_Strobe(CC2500_SFTX);
|
||||
// packet length
|
||||
CC2500_WriteReg(CC2500_3F_TXFIFO, last);
|
||||
// transmit nrf packet
|
||||
uint8_t *buff=buf;
|
||||
uint8_t status;
|
||||
if(last>63)
|
||||
{
|
||||
CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, buff, 63);
|
||||
CC2500_Strobe(CC2500_STX);
|
||||
last-=63;
|
||||
buff+=63;
|
||||
while(last)
|
||||
{//Loop until all the data is sent
|
||||
do
|
||||
{// Wait for the FIFO to become available
|
||||
status=CC2500_ReadReg(CC2500_3A_TXBYTES | CC2500_READ_BURST);
|
||||
}
|
||||
while((status&0x7F)>31 && (status&0x80)==0);
|
||||
if(last>31)
|
||||
{//Send 31 bytes
|
||||
CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, buff, 31);
|
||||
last-=31;
|
||||
buff+=31;
|
||||
}
|
||||
else
|
||||
{//Send last bytes
|
||||
CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, buff, last);
|
||||
last=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{//Send packet
|
||||
CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, buff, last);
|
||||
CC2500_Strobe(CC2500_STX);
|
||||
}
|
||||
#elif defined(NRF24L01_INSTALLED)
|
||||
if(len<=32)
|
||||
{
|
||||
NRF24L01_FlushTx();
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, _BV(NRF24L01_07_TX_DS) | _BV(NRF24L01_07_RX_DR) | _BV(NRF24L01_07_MAX_RT));
|
||||
NRF24L01_WritePayload(msg, len);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static boolean __attribute__((unused)) NRF250K_IsPacketSent()
|
||||
{
|
||||
#ifdef CC2500_INSTALLED
|
||||
if(option==0)
|
||||
#endif
|
||||
{ //NRF
|
||||
return NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_TX_DS);
|
||||
}
|
||||
return true; // don't know on the CC2500 how to detect if the packet has been transmitted...
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -42,19 +42,12 @@ static void __attribute__((unused)) NANORF_send_packet()
|
||||
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) NANORF_init()
|
||||
static void __attribute__((unused)) NANORF_RF_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()
|
||||
@@ -63,11 +56,10 @@ uint16_t NANORF_callback()
|
||||
return NANORF_PACKET_PERIOD;
|
||||
}
|
||||
|
||||
uint16_t initNANORF()
|
||||
void NANORF_init()
|
||||
{
|
||||
BIND_DONE;
|
||||
NANORF_init();
|
||||
return NANORF_INITIAL_WAIT;
|
||||
NANORF_RF_init();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -13,9 +13,9 @@ Multiprotocol is distributed in the hope that it will be useful,
|
||||
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if defined(OMP_CC2500_INO)
|
||||
#if defined(OMP_CCNRF_INO)
|
||||
|
||||
#include "iface_nrf250k.h"
|
||||
#include "iface_xn297.h"
|
||||
|
||||
//#define FORCE_OMP_ORIGINAL_ID
|
||||
//#define OMP_TELEM_DEBUG
|
||||
@@ -29,12 +29,6 @@ Multiprotocol is distributed in the hope that it will be useful,
|
||||
|
||||
static void __attribute__((unused)) OMP_send_packet()
|
||||
{
|
||||
#ifdef OMP_HUB_TELEMETRY
|
||||
if(option==0)
|
||||
prev_option=option=1; // Select the CC2500 by default
|
||||
PE1_off; PE2_on; // CC2500 antenna RF2
|
||||
#endif
|
||||
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
memcpy(packet,"BND",3);
|
||||
@@ -50,15 +44,12 @@ static void __attribute__((unused)) OMP_send_packet()
|
||||
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);
|
||||
XN297_Hopping(hopping_frequency_no);
|
||||
hopping_frequency_no++;
|
||||
hopping_frequency_no &= OMP_RF_NUM_CHANNELS-1; // 8 RF channels
|
||||
|
||||
@@ -101,31 +92,22 @@ static void __attribute__((unused)) OMP_send_packet()
|
||||
packet[15] = 0x04;
|
||||
}
|
||||
|
||||
XN297L_SetPower(); // Set tx_power
|
||||
XN297L_SetFreqOffset(); // Set frequency offset
|
||||
XN297L_WriteEnhancedPayload(packet, OMP_PAYLOAD_SIZE, packet_sent!=0);
|
||||
XN297_SetPower(); // Set tx_power
|
||||
XN297_SetFreqOffset(); // Set frequency offset
|
||||
XN297_SetTxRxMode(TX_EN);
|
||||
XN297_WriteEnhancedPayload(packet, OMP_PAYLOAD_SIZE, packet_sent!=0);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) OMP_init()
|
||||
static void __attribute__((unused)) OMP_RF_init()
|
||||
{
|
||||
//Config CC2500
|
||||
#ifdef OMP_HUB_TELEMETRY
|
||||
if(option==0)
|
||||
prev_option=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
|
||||
XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_250K);
|
||||
XN297_SetTXAddr((uint8_t*)"FLPBD", 5);
|
||||
XN297_HoppingCalib(OMP_RF_NUM_CHANNELS); // Calibrate all channels
|
||||
XN297_RFChannel(OMP_RF_BIND_CHANNEL); // Set bind channel
|
||||
|
||||
#ifdef OMP_HUB_TELEMETRY
|
||||
//Config NRF
|
||||
prev_option=option=0; // Select the NRF
|
||||
XN297L_Init();
|
||||
XN297_Configure(_BV(NRF24L01_00_EN_CRC));
|
||||
XN297_SetRXAddr(rx_tx_addr, 5); // Set the RX address
|
||||
NRF24L01_SetTxRxMode(TXRX_OFF); // Turn it off for now
|
||||
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, OMP_PAYLOAD_SIZE + 4); // packet length +4 bytes of PCF+CRC
|
||||
XN297_SetRXAddr(rx_tx_addr, OMP_PAYLOAD_SIZE);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -169,6 +151,8 @@ enum {
|
||||
|
||||
uint16_t OMP_callback()
|
||||
{
|
||||
bool rx;
|
||||
|
||||
switch(phase)
|
||||
{
|
||||
case OMP_BIND:
|
||||
@@ -178,23 +162,29 @@ uint16_t OMP_callback()
|
||||
return OMP_PACKET_PERIOD;
|
||||
case OMP_PREPDATA:
|
||||
BIND_DONE;
|
||||
XN297L_SetTXAddr(rx_tx_addr, 5);
|
||||
XN297_SetTXAddr(rx_tx_addr, 5);
|
||||
phase++; // OMP_DATA
|
||||
case OMP_DATA:
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(OMP_PACKET_PERIOD);
|
||||
#endif
|
||||
#ifdef OMP_HUB_TELEMETRY
|
||||
rx = XN297_IsRX(); // Needed for the NRF24L01 since otherwise the bit gets cleared
|
||||
#endif
|
||||
OMP_send_packet();
|
||||
#ifdef OMP_HUB_TELEMETRY
|
||||
if(packet_sent == 0)
|
||||
{
|
||||
phase++; // OMP_RX
|
||||
phase++; // OMP_RX
|
||||
return OMP_WRITE_TIME;
|
||||
}
|
||||
else if(packet_sent == 1)
|
||||
{
|
||||
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR))
|
||||
if( rx )
|
||||
{ // a packet has been received
|
||||
#ifdef OMP_TELEM_DEBUG
|
||||
debug("RX :");
|
||||
#endif
|
||||
if(XN297_ReadEnhancedPayload(packet_in, OMP_PAYLOAD_SIZE) == OMP_PAYLOAD_SIZE)
|
||||
{ // packet with good CRC and length
|
||||
#ifdef OMP_TELEM_DEBUG
|
||||
@@ -240,7 +230,7 @@ uint16_t OMP_callback()
|
||||
debugln("");
|
||||
#endif
|
||||
}
|
||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||
XN297_SetTxRxMode(TXRX_OFF);
|
||||
packet_count++;
|
||||
if(packet_count>=100)
|
||||
{//LQI calculation
|
||||
@@ -256,21 +246,15 @@ uint16_t OMP_callback()
|
||||
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)
|
||||
if(XN297_IsPacketSent())
|
||||
break;
|
||||
}
|
||||
}
|
||||
NRF_CE_on;
|
||||
PE1_on;PE2_off; // NRF24L01 antenna RF3
|
||||
XN297_SetTxRxMode(RX_EN);
|
||||
phase = OMP_DATA;
|
||||
return OMP_PACKET_PERIOD-OMP_WRITE_TIME;
|
||||
#endif
|
||||
@@ -278,10 +262,10 @@ uint16_t OMP_callback()
|
||||
return OMP_PACKET_PERIOD;
|
||||
}
|
||||
|
||||
uint16_t initOMP()
|
||||
void OMP_init()
|
||||
{
|
||||
OMP_initialize_txid();
|
||||
OMP_init();
|
||||
OMP_RF_init();
|
||||
hopping_frequency_no = 0;
|
||||
packet_sent = 0;
|
||||
#ifdef OMP_HUB_TELEMETRY
|
||||
@@ -295,7 +279,6 @@ uint16_t initOMP()
|
||||
}
|
||||
else
|
||||
phase = OMP_PREPDATA;
|
||||
return OMP_INITIAL_WAIT;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -13,7 +13,7 @@ Multiprotocol is distributed in the hope that it will be useful,
|
||||
|
||||
#if defined(POTENSIC_NRF24L01_INO)
|
||||
|
||||
#include "iface_nrf24l01.h"
|
||||
#include "iface_xn297.h"
|
||||
|
||||
//#define FORCE_POTENSIC_ORIGINAL_ID
|
||||
|
||||
@@ -61,36 +61,25 @@ static void __attribute__((unused)) POTENSIC_send_packet()
|
||||
}
|
||||
POTENSIC_set_checksum();
|
||||
packet[9] = hopping_frequency_no;
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no&0x03]);
|
||||
|
||||
//RF channel
|
||||
XN297_Hopping(hopping_frequency_no&0x03);
|
||||
hopping_frequency_no++;
|
||||
// Power on, TX mode, 2byte CRC
|
||||
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||
NRF24L01_FlushTx();
|
||||
|
||||
// Send
|
||||
XN297_SetPower();
|
||||
XN297_SetTxRxMode(TX_EN);
|
||||
XN297_WritePayload(packet, POTENSIC_PACKET_SIZE);
|
||||
NRF24L01_SetPower();
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) POTENSIC_init()
|
||||
static void __attribute__((unused)) POTENSIC_RF_init()
|
||||
{
|
||||
NRF24L01_Initialize();
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
NRF24L01_FlushTx();
|
||||
NRF24L01_FlushRx();
|
||||
XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M);
|
||||
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
XN297_SetTXAddr((uint8_t*)"\x01\x01\x01\x01\x06", 5); // Bind address
|
||||
else
|
||||
XN297_SetTXAddr(rx_tx_addr,5); // Normal address
|
||||
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_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // set address length (5 bytes)
|
||||
NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x00); // no retransmits
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps
|
||||
NRF24L01_SetPower();
|
||||
NRF24L01_Activate(0x73); // Activate feature register
|
||||
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x00); // Disable dynamic payload length on all pipes
|
||||
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x01);
|
||||
NRF24L01_Activate(0x73);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) POTENSIC_initialize_txid()
|
||||
@@ -103,26 +92,25 @@ static void __attribute__((unused)) POTENSIC_initialize_txid()
|
||||
|
||||
uint16_t POTENSIC_callback()
|
||||
{
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(POTENSIC_PACKET_PERIOD);
|
||||
#endif
|
||||
if(bind_counter)
|
||||
if(--bind_counter==0)
|
||||
{
|
||||
BIND_DONE;
|
||||
XN297_SetTXAddr(rx_tx_addr,5);
|
||||
}
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(POTENSIC_PACKET_PERIOD);
|
||||
#endif
|
||||
POTENSIC_send_packet();
|
||||
return POTENSIC_PACKET_PERIOD;
|
||||
}
|
||||
|
||||
uint16_t initPOTENSIC(void)
|
||||
void POTENSIC_init(void)
|
||||
{
|
||||
bind_counter = POTENSIC_BIND_COUNT;
|
||||
POTENSIC_initialize_txid();
|
||||
POTENSIC_init();
|
||||
POTENSIC_RF_init();
|
||||
hopping_frequency_no = 0;
|
||||
return POTENSIC_INITIAL_WAIT;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -20,97 +20,143 @@
|
||||
|
||||
//#define PELIKAN_FORCE_ID
|
||||
//#define PELIKAN_LITE_FORCE_ID
|
||||
#define PELIKAN_LITE_FORCE_HOP
|
||||
#define PELIKAN_LITE_FORCE_HOP // hop sequence creation is unknown
|
||||
//#define PELIKAN_SCX24_FORCE_ID
|
||||
#define PELIKAN_SCX24_FORCE_HOP // hop sequence creation is unknown
|
||||
|
||||
#define PELIKAN_BIND_COUNT 400
|
||||
#define PELIKAN_BIND_COUNT 400 // 3sec
|
||||
#define PELIKAN_BIND_RF 0x3C
|
||||
#define PELIKAN_NUM_RF_CHAN 0x1D
|
||||
#define PELIKAN_PACKET_PERIOD 7980
|
||||
#define PELIKAN_LITE_PACKET_PERIOD 18000
|
||||
#define PELIKAN_SCX24_PACKET_PERIOD 15069
|
||||
|
||||
static void __attribute__((unused)) pelikan_build_packet()
|
||||
{
|
||||
static boolean upper=false;
|
||||
packet[0] = 0x15;
|
||||
uint8_t sum;
|
||||
uint16_t channel;
|
||||
|
||||
if(sub_protocol == PELIKAN_SCX24)
|
||||
packet[0] = 0x11;
|
||||
else //PELIKAN_PRO & PELIKAN_LITE
|
||||
packet[0] = 0x15;
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
packet[1] = 0x04; //version??
|
||||
packet[2] = rx_tx_addr[0];
|
||||
packet[3] = rx_tx_addr[1];
|
||||
packet[4] = rx_tx_addr[2];
|
||||
packet[5] = rx_tx_addr[3];
|
||||
if(sub_protocol==PELIKAN_PRO)
|
||||
packet[6] = 0x05; //sub version??
|
||||
else //PELIKAN_LITE
|
||||
packet[6] = 0x03; //sub version??
|
||||
packet[7] = 0x00; //??
|
||||
packet[8] = 0x55; //??
|
||||
|
||||
if(sub_protocol == PELIKAN_SCX24)
|
||||
{
|
||||
packet[1] = 0x65; //??
|
||||
packet[6] = 0x55; //??
|
||||
packet[7] = 0xAA; //??
|
||||
}
|
||||
else
|
||||
{//PELIKAN_PRO & PELIKAN_LITE
|
||||
packet[1] = 0x04; //version??
|
||||
if(sub_protocol==PELIKAN_PRO)
|
||||
packet[6] = 0x05; //sub version??
|
||||
else //PELIKAN_LITE
|
||||
packet[6] = 0x03; //sub version??
|
||||
packet[7] = 0x00; //??
|
||||
}
|
||||
packet[8] = 0x55; //??
|
||||
packet_length = 10;
|
||||
}
|
||||
else
|
||||
{
|
||||
//ID
|
||||
packet[1] = rx_tx_addr[0];
|
||||
packet[7] = rx_tx_addr[1];
|
||||
packet[12] = rx_tx_addr[2];
|
||||
packet[13] = rx_tx_addr[3];
|
||||
//Channels
|
||||
uint8_t offset=upper?4:0;
|
||||
uint16_t channel=convert_channel_16b_nolimit(CH_AETR[offset++], 153, 871,false);
|
||||
uint8_t top=(channel>>2) & 0xC0;
|
||||
packet[2] = channel;
|
||||
channel=convert_channel_16b_nolimit(CH_AETR[offset++], 153, 871,false);
|
||||
top|=(channel>>4) & 0x30;
|
||||
packet[3] = channel;
|
||||
channel=convert_channel_16b_nolimit(CH_AETR[offset++], 153, 871,false);
|
||||
top|=(channel>>6) & 0x0C;
|
||||
packet[4] = channel;
|
||||
channel=convert_channel_16b_nolimit(CH_AETR[offset], 153, 871,false);
|
||||
top|=(channel>>8) & 0x03;
|
||||
packet[5] = channel;
|
||||
packet[6] = top;
|
||||
//Check
|
||||
crc8=0x15;
|
||||
for(uint8_t i=1;i<8;i++)
|
||||
crc8+=packet[i];
|
||||
packet[8]=crc8;
|
||||
//Low/Up channel flag
|
||||
packet[9]=upper?0xAA:0x00;
|
||||
upper=!upper;
|
||||
//Hopping counters
|
||||
if(sub_protocol==PELIKAN_LITE || ++packet_count>4)
|
||||
if(sub_protocol == PELIKAN_SCX24)
|
||||
{
|
||||
packet_count=0;
|
||||
if(++hopping_frequency_no>=PELIKAN_NUM_RF_CHAN)
|
||||
hopping_frequency_no=0;
|
||||
//ID
|
||||
packet[4] = rx_tx_addr[1];
|
||||
//Channels
|
||||
channel = Channel_data[0]; //STEERING: 1B1..23B..2C5 ???
|
||||
packet[2] = channel >> 9;
|
||||
packet[3] = channel >> 1;
|
||||
channel = Channel_data[1]; //THROTTLE: 0DB..1FF..30E
|
||||
packet[5] = channel >> 9;
|
||||
packet[6] = channel >> 1;
|
||||
channel = Channel_data[2]; //CH3: 055..3AA
|
||||
packet[7] = channel >> 9;
|
||||
packet[8] = channel >> 1;
|
||||
//Hopping counters
|
||||
if(++packet_count>2)
|
||||
{
|
||||
packet_count=0;
|
||||
if(++hopping_frequency_no>=PELIKAN_NUM_RF_CHAN)
|
||||
hopping_frequency_no=0;
|
||||
}
|
||||
//Length
|
||||
packet_length = 14;
|
||||
}
|
||||
packet[10]=hopping_frequency_no;
|
||||
packet[11]=packet_count;
|
||||
|
||||
packet_length = 15;
|
||||
else
|
||||
{//PELIKAN_PRO & PELIKAN_LITE
|
||||
//ID
|
||||
packet[7] = rx_tx_addr[1];
|
||||
//Channels
|
||||
uint8_t offset=upper?4:0;
|
||||
channel=convert_channel_16b_nolimit(CH_AETR[offset++], 153, 871,false);
|
||||
uint8_t top=(channel>>2) & 0xC0;
|
||||
packet[2] = channel;
|
||||
channel=convert_channel_16b_nolimit(CH_AETR[offset++], 153, 871,false);
|
||||
top|=(channel>>4) & 0x30;
|
||||
packet[3] = channel;
|
||||
channel=convert_channel_16b_nolimit(CH_AETR[offset++], 153, 871,false);
|
||||
top|=(channel>>6) & 0x0C;
|
||||
packet[4] = channel;
|
||||
channel=convert_channel_16b_nolimit(CH_AETR[offset], 153, 871,false);
|
||||
top|=(channel>>8) & 0x03;
|
||||
packet[5] = channel;
|
||||
packet[6] = top;
|
||||
//Check
|
||||
sum=0x00;
|
||||
for(uint8_t i=0;i<8;i++)
|
||||
sum+=packet[i];
|
||||
packet[8]=sum;
|
||||
//Low/Up channel flag
|
||||
packet[9]=upper?0xAA:0x00;
|
||||
upper=!upper;
|
||||
//Hopping counters
|
||||
if(sub_protocol==PELIKAN_LITE || ++packet_count>4)
|
||||
{
|
||||
packet_count=0;
|
||||
if(++hopping_frequency_no>=PELIKAN_NUM_RF_CHAN)
|
||||
hopping_frequency_no=0;
|
||||
}
|
||||
//Length
|
||||
packet_length = 15;
|
||||
}
|
||||
//Hopping
|
||||
packet[packet_length-5] = hopping_frequency_no;
|
||||
packet[packet_length-4] = packet_count;
|
||||
//ID
|
||||
packet[packet_length-3] = rx_tx_addr[2];
|
||||
packet[packet_length-2] = rx_tx_addr[3];
|
||||
}
|
||||
|
||||
//Check
|
||||
crc8=0x15;
|
||||
for(uint8_t i=1; i<packet_length-1 ;i++)
|
||||
crc8+=packet[i];
|
||||
packet[packet_length-1]=crc8;
|
||||
sum=0x00;
|
||||
for(uint8_t i=0; i<packet_length-1 ;i++)
|
||||
sum+=packet[i];
|
||||
packet[packet_length-1] = sum;
|
||||
|
||||
//Send
|
||||
#ifdef DEBUG_SERIAL
|
||||
if(packet[9]==0x00)
|
||||
{
|
||||
debug("C: %02X P(%d):",IS_BIND_IN_PROGRESS?PELIKAN_BIND_RF:hopping_frequency[hopping_frequency_no],packet_length);
|
||||
for(uint8_t i=0;i<packet_length;i++)
|
||||
debug(" %02X",packet[i]);
|
||||
debugln("");
|
||||
}
|
||||
debug("C: %02X P(%d):",IS_BIND_IN_PROGRESS?PELIKAN_BIND_RF:hopping_frequency[hopping_frequency_no],packet_length);
|
||||
for(uint8_t i=0;i<packet_length;i++)
|
||||
debug(" %02X",packet[i]);
|
||||
debugln("");
|
||||
#endif
|
||||
A7105_WriteData(packet_length, IS_BIND_IN_PROGRESS?PELIKAN_BIND_RF:hopping_frequency[hopping_frequency_no]);
|
||||
A7105_SetPower();
|
||||
}
|
||||
|
||||
uint16_t ReadPelikan()
|
||||
uint16_t PELIKAN_callback()
|
||||
{
|
||||
if(phase==0)
|
||||
{
|
||||
@@ -125,17 +171,19 @@ uint16_t ReadPelikan()
|
||||
BIND_DONE;
|
||||
A7105_Strobe(A7105_STANDBY);
|
||||
if(sub_protocol==PELIKAN_PRO)
|
||||
A7105_WriteReg(A7105_03_FIFOI,0x28);
|
||||
A7105_WriteReg(A7105_03_FIFOI,0x28); //????
|
||||
else if(sub_protocol==PELIKAN_SCX24)
|
||||
A7105_WriteReg(A7105_03_FIFOI,0x0D);
|
||||
else//PELIKAN_LITE
|
||||
A7105_WriteID(MProtocol_id);
|
||||
}
|
||||
}
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(sub_protocol==PELIKAN_PRO?PELIKAN_PACKET_PERIOD:PELIKAN_LITE_PACKET_PERIOD);
|
||||
telemetry_set_input_sync(packet_period);
|
||||
#endif
|
||||
pelikan_build_packet();
|
||||
if(sub_protocol==PELIKAN_PRO || IS_BIND_IN_PROGRESS)
|
||||
return PELIKAN_PACKET_PERIOD;
|
||||
if(IS_BIND_IN_PROGRESS || sub_protocol != PELIKAN_LITE)
|
||||
return packet_period;
|
||||
//PELIKAN_LITE
|
||||
phase++;
|
||||
return 942;
|
||||
@@ -241,19 +289,26 @@ const uint8_t PROGMEM pelikan_lite_hopp[][PELIKAN_NUM_RF_CHAN] = {
|
||||
{ 0x46,0x2A,0x3E,0x5A,0x5C,0x24,0x4E,0x32,0x54,0x26,0x2C,0x34,0x56,0x1E,0x3A,0x3C,0x50,0x4A,0x2E,0x42,0x20,0x52,0x28,0x22,0x44,0x58,0x36,0x38,0x4C }
|
||||
};
|
||||
#endif
|
||||
#ifdef PELIKAN_SCX24_FORCE_HOP
|
||||
const uint8_t PROGMEM pelikan_scx24_hopp[][PELIKAN_NUM_RF_CHAN] = {
|
||||
{ 0x1E,0x32,0x46,0x5A,0x44,0x58,0x2E,0x42,0x56,0x2C,0x40,0x54,0x2A,0x3E,0x52,0x28,0x3C,0x50,0x26,0x3A,0x4E,0x24,0x38,0x4C,0x22,0x36,0x4A,0x20,0x1A },
|
||||
{ 0x2C,0x44,0x1E,0x52,0x56,0x22,0x3A,0x3E,0x34,0x4C,0x26,0x5A,0x50,0x2A,0x42,0x38,0x2E,0x46,0x20,0x54,0x4A,0x24,0x3C,0x32,0x28,0x40,0x58,0x1B,0x4E }
|
||||
};
|
||||
#endif
|
||||
|
||||
uint16_t initPelikan()
|
||||
void PELIKAN_init()
|
||||
{
|
||||
A7105_Init();
|
||||
if(IS_BIND_IN_PROGRESS || sub_protocol==PELIKAN_LITE)
|
||||
A7105_WriteReg(A7105_03_FIFOI,0x10);
|
||||
|
||||
pelikan_init_hop();
|
||||
bind_counter = PELIKAN_BIND_COUNT;
|
||||
|
||||
//ID from dump
|
||||
#if defined(PELIKAN_FORCE_ID)
|
||||
if(sub_protocol==PELIKAN_PRO)
|
||||
{
|
||||
if(sub_protocol==PELIKAN_PRO)
|
||||
{
|
||||
pelikan_init_hop();
|
||||
//ID from dump
|
||||
#if defined(PELIKAN_FORCE_ID)
|
||||
rx_tx_addr[0]=0x0D; // hopping freq
|
||||
rx_tx_addr[1]=0xF4; // hopping freq
|
||||
rx_tx_addr[2]=0x50; // ID
|
||||
@@ -261,16 +316,14 @@ uint16_t initPelikan()
|
||||
// Fill frequency table
|
||||
for(uint8_t i=0;i<PELIKAN_NUM_RF_CHAN;i++)
|
||||
hopping_frequency[i]=pgm_read_byte_near(&pelikan_hopp[0][i]);
|
||||
}
|
||||
#endif
|
||||
#if defined(PELIKAN_LITE_FORCE_ID) || defined(PELIKAN_LITE_FORCE_HOP)
|
||||
#endif
|
||||
packet_period = PELIKAN_PACKET_PERIOD;
|
||||
}
|
||||
else
|
||||
{
|
||||
bind_counter >>= 1;
|
||||
if(sub_protocol==PELIKAN_LITE)
|
||||
{
|
||||
#if defined(PELIKAN_LITE_FORCE_ID)
|
||||
// ID
|
||||
rx_tx_addr[2]=0x60;
|
||||
rx_tx_addr[3]=0x18;
|
||||
#endif
|
||||
#if defined(PELIKAN_LITE_FORCE_HOP)
|
||||
// Hop frequency table
|
||||
rx_tx_addr[0]=0x04; // hopping freq
|
||||
@@ -278,16 +331,52 @@ uint16_t initPelikan()
|
||||
for(uint8_t i=0;i<PELIKAN_NUM_RF_CHAN;i++)
|
||||
hopping_frequency[i]=pgm_read_byte_near(&pelikan_lite_hopp[0][i]);
|
||||
#endif
|
||||
#if defined(PELIKAN_LITE_FORCE_ID)
|
||||
// ID
|
||||
rx_tx_addr[2]=0x60;
|
||||
rx_tx_addr[3]=0x18;
|
||||
#endif
|
||||
MProtocol_id = ((uint32_t)rx_tx_addr[0]<<24)|((uint32_t)rx_tx_addr[1]<<16)|((uint32_t)rx_tx_addr[2]<<8)|(rx_tx_addr[3]);
|
||||
if(IS_BIND_DONE)
|
||||
A7105_WriteID(MProtocol_id);
|
||||
packet_period = PELIKAN_LITE_PACKET_PERIOD;
|
||||
}
|
||||
#endif
|
||||
else// if(sub_protocol==PELIKAN_SCX24)
|
||||
{
|
||||
#if defined(PELIKAN_SCX24_FORCE_HOP)
|
||||
// Hop frequency table
|
||||
uint8_t num=rx_tx_addr[3] & 0x01;
|
||||
if(num)
|
||||
{//1
|
||||
rx_tx_addr[0]=0x10; // hopping freq TX2
|
||||
rx_tx_addr[1]=0x63; // hopping freq TX2
|
||||
}
|
||||
else
|
||||
{//0
|
||||
rx_tx_addr[0]=0x12; // hopping freq TX1
|
||||
rx_tx_addr[1]=0x46; // hopping freq TX1
|
||||
}
|
||||
|
||||
MProtocol_id=((uint32_t)rx_tx_addr[0]<<24)|((uint32_t)rx_tx_addr[1]<<16)|((uint32_t)rx_tx_addr[2]<<8)|(rx_tx_addr[3]);
|
||||
if(sub_protocol==PELIKAN_LITE && IS_BIND_DONE)
|
||||
A7105_WriteID(MProtocol_id);
|
||||
for(uint8_t i=0;i<PELIKAN_NUM_RF_CHAN;i++)
|
||||
hopping_frequency[i]=pgm_read_byte_near(&pelikan_scx24_hopp[num][i]);
|
||||
#endif
|
||||
#if defined(PELIKAN_SCX24_FORCE_ID)
|
||||
// ID
|
||||
rx_tx_addr[2]=0x80; // TX1
|
||||
rx_tx_addr[3]=0x19; // TX1
|
||||
rx_tx_addr[2]=0x80; // TX2
|
||||
rx_tx_addr[3]=0x22; // TX2
|
||||
#endif
|
||||
A7105_WriteReg(A7105_0E_DATA_RATE,0x03);
|
||||
if(IS_BIND_DONE)
|
||||
A7105_WriteReg(A7105_03_FIFOI,0x0D);
|
||||
packet_period = PELIKAN_SCX24_PACKET_PERIOD;
|
||||
}
|
||||
}
|
||||
|
||||
hopping_frequency_no=PELIKAN_NUM_RF_CHAN;
|
||||
packet_count=5;
|
||||
phase=0;
|
||||
return 2400;
|
||||
hopping_frequency_no = PELIKAN_NUM_RF_CHAN;
|
||||
packet_count = 5;
|
||||
phase = 0;
|
||||
bind_counter = PELIKAN_BIND_COUNT;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -155,27 +155,21 @@ static void __attribute__((unused)) PROPEL_data_packet()
|
||||
NRF24L01_WritePayload(packet, PROPEL_PACKET_SIZE);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) PROPEL_init()
|
||||
static void __attribute__((unused)) PROPEL_RF_init()
|
||||
{
|
||||
NRF24L01_Initialize();
|
||||
|
||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, 0x7f);
|
||||
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x3f); // AA on all pipes
|
||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x3f); // Enable all pipes
|
||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5-byte address
|
||||
NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x36); // retransmit 1ms, 6 times
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps
|
||||
NRF24L01_SetPower();
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x07); // ?? match protocol capture
|
||||
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x3f); // AA on all pipes
|
||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x3f); // Enable all pipes
|
||||
NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x36); // retransmit 1ms, 6 times
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, (uint8_t *)"\x99\x77\x55\x33\x11", PROPEL_ADDRESS_LENGTH); //Bind address
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, (uint8_t *)"\x99\x77\x55\x33\x11", PROPEL_ADDRESS_LENGTH); //Bind address
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, PROPEL_BIND_RF_CHANNEL);
|
||||
NRF24L01_Activate(0x73); // Activate feature register
|
||||
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x3f); // Enable dynamic payload length
|
||||
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x07); // Enable all features
|
||||
// Beken 2425 register bank 1 initialized here in stock tx capture
|
||||
// Hopefully won't matter for nRF compatibility
|
||||
NRF24L01_FlushTx();
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x3f); // Enable dynamic payload length
|
||||
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x07); // Enable all features
|
||||
|
||||
NRF24L01_SetTxRxMode(TX_EN); // Clear data ready, data sent, retransmit and enable CRC 16bits, ready for TX
|
||||
}
|
||||
|
||||
const uint8_t PROGMEM PROPEL_hopping []= { 0x47,0x36,0x27,0x44,0x33,0x0D,0x3C,0x2E,0x1B,0x39,0x2A,0x18 };
|
||||
@@ -281,14 +275,13 @@ uint16_t PROPEL_callback()
|
||||
return PROPEL_PACKET_PERIOD;
|
||||
}
|
||||
|
||||
uint16_t initPROPEL()
|
||||
void PROPEL_init()
|
||||
{
|
||||
BIND_IN_PROGRESS; // autobind protocol
|
||||
PROPEL_initialize_txid();
|
||||
PROPEL_init();
|
||||
PROPEL_RF_init();
|
||||
hopping_frequency_no = 0;
|
||||
phase=PROPEL_BIND1;
|
||||
return PROPEL_INITIAL_WAIT;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -13,9 +13,9 @@
|
||||
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if defined(Q303_NRF24L01_INO)
|
||||
#if defined(Q303_CCNRF_INO)
|
||||
|
||||
#include "iface_nrf24l01.h"
|
||||
#include "iface_xn297.h"
|
||||
|
||||
#define Q303_BIND_COUNT 1500
|
||||
#define Q303_INITIAL_WAIT 500
|
||||
@@ -174,10 +174,10 @@ static uint8_t __attribute__((unused)) cx35_lastButton()
|
||||
return command;
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) Q303_send_packet(uint8_t bind)
|
||||
static void __attribute__((unused)) Q303_send_packet()
|
||||
{
|
||||
uint16_t aileron, elevator, throttle, rudder, slider;
|
||||
if(bind)
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
packet[0] = 0xaa;
|
||||
memcpy(&packet[1], rx_tx_addr + 1, 4);
|
||||
@@ -185,6 +185,11 @@ static void __attribute__((unused)) Q303_send_packet(uint8_t bind)
|
||||
}
|
||||
else
|
||||
{
|
||||
//RF freq
|
||||
XN297_Hopping(hopping_frequency_no++);
|
||||
hopping_frequency_no %= rf_ch_num;
|
||||
|
||||
//Build packet
|
||||
packet[0] = 0x55;
|
||||
// sticks
|
||||
switch(sub_protocol)
|
||||
@@ -267,51 +272,27 @@ static void __attribute__((unused)) Q303_send_packet(uint8_t bind)
|
||||
}
|
||||
}
|
||||
|
||||
// Power on, TX mode, CRC enabled
|
||||
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
||||
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, bind ? Q303_RF_BIND_CHANNEL : hopping_frequency[hopping_frequency_no++]);
|
||||
hopping_frequency_no %= rf_ch_num;
|
||||
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||
NRF24L01_FlushTx();
|
||||
|
||||
// Send
|
||||
XN297_SetPower();
|
||||
XN297_SetFreqOffset();
|
||||
XN297_SetTxRxMode(TX_EN);
|
||||
XN297_WritePayload(packet, packet_length);
|
||||
|
||||
NRF24L01_SetPower(); // Set tx_power
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) Q303_init()
|
||||
static void __attribute__((unused)) Q303_RF_init()
|
||||
{
|
||||
const uint8_t bind_address[] = {0xcc,0xcc,0xcc,0xcc,0xcc};
|
||||
|
||||
NRF24L01_Initialize();
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
switch(sub_protocol)
|
||||
if(sub_protocol==Q303)
|
||||
{
|
||||
case CX35:
|
||||
case CX10D:
|
||||
case CX10WD:
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_1M);
|
||||
break;
|
||||
case Q303:
|
||||
XN297_SetScrambledMode(XN297_UNSCRAMBLED);
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_250K);
|
||||
break;
|
||||
XN297_Configure(XN297_CRCEN, XN297_UNSCRAMBLED, XN297_250K);
|
||||
XN297_HoppingCalib(rf_ch_num);
|
||||
}
|
||||
else
|
||||
XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M);
|
||||
|
||||
XN297_SetTXAddr(bind_address, 5);
|
||||
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);
|
||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03);
|
||||
NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x00); // no retransmits
|
||||
NRF24L01_SetPower();
|
||||
NRF24L01_Activate(0x73); // Activate feature register
|
||||
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x00); // Disable dynamic payload length on all pipes
|
||||
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x01); // Set feature bits on
|
||||
NRF24L01_Activate(0x73);
|
||||
XN297_RFChannel(Q303_RF_BIND_CHANNEL);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) Q303_initialize_txid()
|
||||
@@ -353,34 +334,27 @@ static void __attribute__((unused)) Q303_initialize_txid()
|
||||
|
||||
uint16_t Q303_callback()
|
||||
{
|
||||
if(IS_BIND_DONE)
|
||||
{
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(packet_period);
|
||||
#endif
|
||||
Q303_send_packet(0);
|
||||
}
|
||||
else
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(packet_period);
|
||||
#endif
|
||||
if(bind_counter)
|
||||
{
|
||||
bind_counter--;
|
||||
if (bind_counter == 0)
|
||||
{
|
||||
XN297_SetTXAddr(rx_tx_addr, 5);
|
||||
packet_count = 0;
|
||||
BIND_DONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
Q303_send_packet(1);
|
||||
bind_counter--;
|
||||
}
|
||||
}
|
||||
Q303_send_packet();
|
||||
return packet_period;
|
||||
}
|
||||
|
||||
uint16_t initQ303()
|
||||
void Q303_init()
|
||||
{
|
||||
Q303_initialize_txid();
|
||||
Q303_init();
|
||||
Q303_RF_init();
|
||||
bind_counter = Q303_BIND_COUNT;
|
||||
switch(sub_protocol)
|
||||
{
|
||||
@@ -407,7 +381,6 @@ uint16_t initQ303()
|
||||
}
|
||||
hopping_frequency_no = 0;
|
||||
BIND_IN_PROGRESS; // autobind protocol
|
||||
return Q303_INITIAL_WAIT;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -14,9 +14,9 @@ Multiprotocol is distributed in the hope that it will be useful,
|
||||
*/
|
||||
// Compatible with Q90C quad.
|
||||
|
||||
#if defined(Q90C_NRF24L01_INO)
|
||||
#if defined(Q90C_CCNRF_INO)
|
||||
|
||||
#include "iface_nrf250k.h"
|
||||
#include "iface_xn297.h"
|
||||
|
||||
//#define FORCE_Q90C_ORIGINAL_ID
|
||||
|
||||
@@ -51,7 +51,7 @@ static void __attribute__((unused)) Q90C_send_packet()
|
||||
}
|
||||
else
|
||||
{
|
||||
XN297L_Hopping(hopping_frequency_no++); // RF Freq
|
||||
XN297_Hopping(hopping_frequency_no++); // RF Freq
|
||||
hopping_frequency_no %= Q90C_RF_NUM_CHANNELS;
|
||||
packet[0]= convert_channel_8b(THROTTLE); // 0..255
|
||||
// A,E,R have weird scaling, 0x00-0xff range (unsigned) but center isn't 7f or 80
|
||||
@@ -108,9 +108,11 @@ static void __attribute__((unused)) Q90C_send_packet()
|
||||
packet[11] = sum ^ crc8;
|
||||
}
|
||||
|
||||
XN297L_SetFreqOffset(); // Set frequency offset
|
||||
XN297L_SetPower(); // Set tx_power
|
||||
XN297L_WriteEnhancedPayload(packet, Q90C_PACKET_SIZE, 0);
|
||||
// Send
|
||||
XN297_SetFreqOffset(); // Set frequency offset
|
||||
XN297_SetPower(); // Set tx_power
|
||||
XN297_SetTxRxMode(TX_EN);
|
||||
XN297_WriteEnhancedPayload(packet, Q90C_PACKET_SIZE, 0);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) Q90C_initialize_txid()
|
||||
@@ -131,15 +133,15 @@ static void __attribute__((unused)) Q90C_initialize_txid()
|
||||
crc8=rx_tx_addr[0]^rx_tx_addr[1]^rx_tx_addr[2]^rx_tx_addr[3];
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) Q90C_init()
|
||||
static void __attribute__((unused)) Q90C_RF_init()
|
||||
{
|
||||
XN297L_Init();
|
||||
XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_250K);
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
XN297L_SetTXAddr((uint8_t*)"\x4F\x43\x54\x81\x81", Q90C_ADDRESS_LENGTH);
|
||||
XN297_SetTXAddr((uint8_t*)"\x4F\x43\x54\x81\x81", Q90C_ADDRESS_LENGTH);
|
||||
else
|
||||
XN297L_SetTXAddr(rx_tx_addr, Q90C_ADDRESS_LENGTH);
|
||||
XN297L_HoppingCalib(Q90C_RF_NUM_CHANNELS); // Calibrate all channels
|
||||
XN297L_RFChannel(Q90C_RF_BIND_CHANNEL); // Set bind channel
|
||||
XN297_SetTXAddr(rx_tx_addr, Q90C_ADDRESS_LENGTH);
|
||||
XN297_HoppingCalib(Q90C_RF_NUM_CHANNELS); // Calibrate all channels
|
||||
XN297_RFChannel(Q90C_RF_BIND_CHANNEL); // Set bind channel
|
||||
}
|
||||
|
||||
uint16_t Q90C_callback()
|
||||
@@ -147,20 +149,20 @@ uint16_t Q90C_callback()
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(Q90C_PACKET_PERIOD);
|
||||
#endif
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
if(bind_counter)
|
||||
if(--bind_counter==0)
|
||||
{
|
||||
BIND_DONE;
|
||||
XN297L_SetTXAddr(rx_tx_addr, Q90C_ADDRESS_LENGTH);
|
||||
XN297_SetTXAddr(rx_tx_addr, Q90C_ADDRESS_LENGTH);
|
||||
}
|
||||
Q90C_send_packet();
|
||||
return Q90C_PACKET_PERIOD;
|
||||
}
|
||||
|
||||
uint16_t initQ90C()
|
||||
void Q90C_init()
|
||||
{
|
||||
Q90C_initialize_txid();
|
||||
Q90C_init();
|
||||
Q90C_RF_init();
|
||||
hopping_frequency_no = 0;
|
||||
packet_count = 0;
|
||||
bind_counter=Q90C_BIND_COUNT;
|
||||
@@ -170,7 +172,6 @@ uint16_t initQ90C()
|
||||
Q90C_VTX=CH6_SW;
|
||||
packet[8] = 0x00;
|
||||
packet[9] = 0x00;
|
||||
return Q90C_INITIAL_WAIT;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -16,7 +16,7 @@ Multiprotocol is distributed in the hope that it will be useful,
|
||||
|
||||
#if defined(REALACC_NRF24L01_INO)
|
||||
|
||||
#include "iface_nrf24l01.h"
|
||||
#include "iface_xn297.h"
|
||||
|
||||
#define FORCE_REALACC_ORIGINAL_ID
|
||||
|
||||
@@ -51,7 +51,7 @@ static void __attribute__((unused)) REALACC_send_packet()
|
||||
| GET_FLAG(CH5_SW, 0x01) // Flip
|
||||
| GET_FLAG(CH6_SW, 0x80); // Light
|
||||
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency_no);
|
||||
XN297_Hopping(hopping_frequency_no);
|
||||
hopping_frequency_no++;
|
||||
hopping_frequency_no %= REALACC_RF_NUM_CHANNELS;
|
||||
XN297_WriteEnhancedPayload(packet, REALACC_PAYLOAD_SIZE,0);
|
||||
@@ -86,19 +86,11 @@ static void __attribute__((unused)) REALACC_initialize_txid()
|
||||
#endif
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) REALACC_init()
|
||||
static void __attribute__((unused)) REALACC_RF_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_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M);
|
||||
XN297_SetTXAddr((uint8_t*)"MAIN", 4);
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, REALACC_BIND_RF_CHANNEL); // Set bind channel
|
||||
XN297_RFChannel(REALACC_BIND_RF_CHANNEL); // Set bind channel
|
||||
}
|
||||
|
||||
uint16_t REALACC_callback()
|
||||
@@ -106,10 +98,8 @@ 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();
|
||||
XN297_SetPower();
|
||||
XN297_SetTxRxMode(TX_EN);
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
REALACC_send_bind_packet();
|
||||
@@ -124,14 +114,13 @@ uint16_t REALACC_callback()
|
||||
return REALACC_PACKET_PERIOD;
|
||||
}
|
||||
|
||||
uint16_t initREALACC()
|
||||
void REALACC_init()
|
||||
{
|
||||
BIND_IN_PROGRESS; // autobind protocol
|
||||
REALACC_initialize_txid();
|
||||
REALACC_init();
|
||||
REALACC_RF_init();
|
||||
bind_counter=REALACC_BIND_COUNT;
|
||||
hopping_frequency_no=0;
|
||||
return REALACC_INITIAL_WAIT;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -95,7 +95,7 @@ static void __attribute__((unused)) RLINK_hop()
|
||||
hopping_frequency[rf_ch_num]=12*16+inc;
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) RLINK_init()
|
||||
static void __attribute__((unused)) RLINK_TXID_init()
|
||||
{
|
||||
#ifdef RLINK_FORCE_ID
|
||||
//surface RC6GS
|
||||
@@ -158,6 +158,9 @@ static void __attribute__((unused)) RLINK_send_packet()
|
||||
// header
|
||||
if(packet_count>3)
|
||||
packet[1] = 0x02; // 0x02 telemetry request flag
|
||||
else
|
||||
packet[1] = 0x00; // no telemetry
|
||||
|
||||
switch(sub_protocol)
|
||||
{
|
||||
case RLINK_SURFACE:
|
||||
@@ -296,14 +299,13 @@ uint16_t RLINK_callback()
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t initRLINK()
|
||||
void RLINK_init()
|
||||
{
|
||||
BIND_DONE; // Not a TX bind protocol
|
||||
RLINK_init();
|
||||
RLINK_TXID_init();
|
||||
RLINK_rf_init();
|
||||
packet_count = 0;
|
||||
phase = RLINK_DATA;
|
||||
return 10000;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -96,13 +96,13 @@ static void REDPINE_data_frame() {
|
||||
packet[10] = REDPINE_LOOPTIME_SLOW;
|
||||
}
|
||||
|
||||
static uint16_t ReadREDPINE()
|
||||
uint16_t REDPINE_callback()
|
||||
{
|
||||
CC2500_SetFreqOffset();
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
if (state == REDPINE_BIND) {
|
||||
REDPINE_init(0);
|
||||
REDPINE_RF_init(0);
|
||||
}
|
||||
REDPINE_set_channel(49);
|
||||
CC2500_SetTxRxMode(TX_EN);
|
||||
@@ -114,7 +114,7 @@ static uint16_t ReadREDPINE()
|
||||
if(--bind_counter==0)
|
||||
{
|
||||
BIND_DONE;
|
||||
REDPINE_init(sub_protocol);
|
||||
REDPINE_RF_init(sub_protocol);
|
||||
}
|
||||
return 4000;
|
||||
}
|
||||
@@ -171,7 +171,7 @@ static const uint8_t REDPINE_init_data[][3] = {
|
||||
{CC2500_3E_PATABLE, 0xff, 0xff}
|
||||
};
|
||||
|
||||
static void REDPINE_init(uint8_t format)
|
||||
static void REDPINE_RF_init(uint8_t format)
|
||||
{
|
||||
CC2500_Reset();
|
||||
|
||||
@@ -195,7 +195,7 @@ static void REDPINE_init(uint8_t format)
|
||||
}
|
||||
}
|
||||
|
||||
static uint16_t initREDPINE()
|
||||
void REDPINE_init()
|
||||
{
|
||||
hopping_frequency_no = 0;
|
||||
// Used from kn_nrf24l01.c : kn_calculate_freqency_hopping_channels
|
||||
@@ -228,8 +228,7 @@ static uint16_t initREDPINE()
|
||||
packet_period = REDPINE_LOOPTIME_SLOW*1000;
|
||||
|
||||
bind_counter=REDPINE_BIND;
|
||||
REDPINE_init(sub_protocol);
|
||||
REDPINE_RF_init(sub_protocol);
|
||||
CC2500_SetTxRxMode(TX_EN); // enable PA
|
||||
return 10000;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -29,15 +29,9 @@ const uint8_t PROGMEM SHENQI_Freq[] = {
|
||||
10,60,10,50,30,40,
|
||||
20,10,40,30,60,20 };
|
||||
|
||||
void SHENQI_init()
|
||||
void SHENQI_RF_init()
|
||||
{
|
||||
NRF24L01_Initialize();
|
||||
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_SetBitrate(NRF24L01_BR_1M); // 1Mbps
|
||||
NRF24L01_SetPower();
|
||||
|
||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5 bytes rx/tx address
|
||||
|
||||
LT8900_Config(4, 8, _BV(LT8900_CRC_ON)|_BV(LT8900_PACKET_LENGTH_EN), 0xAA);
|
||||
LT8900_SetChannel(2);
|
||||
@@ -116,14 +110,13 @@ uint16_t SHENQI_callback()
|
||||
return packet_period;
|
||||
}
|
||||
|
||||
uint16_t initSHENQI()
|
||||
void SHENQI_init()
|
||||
{
|
||||
BIND_IN_PROGRESS; // autobind protocol
|
||||
SHENQI_init();
|
||||
SHENQI_RF_init();
|
||||
hopping_frequency_no = 0;
|
||||
packet_count=0;
|
||||
packet_period=500;
|
||||
return 1000;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,282 +1,281 @@
|
||||
/*
|
||||
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/>.
|
||||
*/
|
||||
// Last sync with deviation main github branch
|
||||
|
||||
#if defined(SLT_NRF24L01_INO)
|
||||
|
||||
#include "iface_nrf250k.h"
|
||||
|
||||
//#define SLT_Q200_FORCE_ID
|
||||
|
||||
// For code readability
|
||||
#define SLT_PAYLOADSIZE_V1 7
|
||||
#define SLT_PAYLOADSIZE_V2 11
|
||||
#define SLT_NFREQCHANNELS 15
|
||||
#define SLT_TXID_SIZE 4
|
||||
#define SLT_BIND_CHANNEL 0x50
|
||||
|
||||
enum{
|
||||
// flags going to packet[6] (Q200)
|
||||
FLAG_Q200_FMODE = 0x20,
|
||||
FLAG_Q200_VIDON = 0x10,
|
||||
FLAG_Q200_FLIP = 0x08,
|
||||
FLAG_Q200_VIDOFF= 0x04,
|
||||
};
|
||||
|
||||
enum{
|
||||
// flags going to packet[6] (MR100 & Q100)
|
||||
FLAG_MR100_FMODE = 0x20,
|
||||
FLAG_MR100_FLIP = 0x04,
|
||||
FLAG_MR100_VIDEO = 0x02,
|
||||
FLAG_MR100_PICTURE = 0x01,
|
||||
};
|
||||
|
||||
enum {
|
||||
SLT_BUILD=0,
|
||||
SLT_DATA1,
|
||||
SLT_DATA2,
|
||||
SLT_DATA3,
|
||||
SLT_BIND1,
|
||||
SLT_BIND2,
|
||||
};
|
||||
|
||||
static void __attribute__((unused)) SLT_init()
|
||||
{
|
||||
NRF250K_Init();
|
||||
NRF250K_SetTXAddr(rx_tx_addr, SLT_TXID_SIZE);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) SLT_set_freq(void)
|
||||
{
|
||||
// Frequency hopping sequence generation
|
||||
for (uint8_t i = 0; i < SLT_TXID_SIZE; ++i)
|
||||
{
|
||||
uint8_t next_i = (i+1) % SLT_TXID_SIZE; // is & 3 better than % 4 ?
|
||||
uint8_t base = i < 2 ? 0x03 : 0x10;
|
||||
hopping_frequency[i*4 + 0] = (rx_tx_addr[i] & 0x3f) + base;
|
||||
hopping_frequency[i*4 + 1] = (rx_tx_addr[i] >> 2) + base;
|
||||
hopping_frequency[i*4 + 2] = (rx_tx_addr[i] >> 4) + (rx_tx_addr[next_i] & 0x03)*0x10 + base;
|
||||
hopping_frequency[i*4 + 3] = (rx_tx_addr[i] >> 6) + (rx_tx_addr[next_i] & 0x0f)*0x04 + base;
|
||||
}
|
||||
|
||||
// Unique freq
|
||||
uint8_t max_freq=0x50; //V1 and V2
|
||||
if(sub_protocol==Q200)
|
||||
max_freq=45;
|
||||
for (uint8_t i = 0; i < SLT_NFREQCHANNELS; ++i)
|
||||
{
|
||||
if(sub_protocol==Q200 && hopping_frequency[i] >= max_freq)
|
||||
hopping_frequency[i] = hopping_frequency[i] - max_freq + 0x03;
|
||||
uint8_t done = 0;
|
||||
while (!done)
|
||||
{
|
||||
done = 1;
|
||||
for (uint8_t j = 0; j < i; ++j)
|
||||
if (hopping_frequency[i] == hopping_frequency[j])
|
||||
{
|
||||
done = 0;
|
||||
hopping_frequency[i] += 7;
|
||||
if (hopping_frequency[i] >= max_freq)
|
||||
hopping_frequency[i] = hopping_frequency[i] - max_freq + 0x03;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Bind channel
|
||||
hopping_frequency[SLT_NFREQCHANNELS]=SLT_BIND_CHANNEL;
|
||||
|
||||
//Calib all channels
|
||||
NRF250K_HoppingCalib(SLT_NFREQCHANNELS+1);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) SLT_wait_radio()
|
||||
{
|
||||
if (packet_sent)
|
||||
while (!NRF250K_IsPacketSent());
|
||||
packet_sent = 0;
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) SLT_send_packet(uint8_t len)
|
||||
{
|
||||
SLT_wait_radio();
|
||||
NRF250K_WritePayload(packet, len);
|
||||
packet_sent = 1;
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) SLT_build_packet()
|
||||
{
|
||||
static uint8_t calib_counter=0;
|
||||
|
||||
// Set radio channel - once per packet batch
|
||||
NRF250K_SetFreqOffset(); // Set frequency offset
|
||||
NRF250K_Hopping(hopping_frequency_no);
|
||||
if (++hopping_frequency_no >= SLT_NFREQCHANNELS)
|
||||
hopping_frequency_no = 0;
|
||||
|
||||
// aileron, elevator, throttle, rudder, gear, pitch
|
||||
uint8_t e = 0; // byte where extension 2 bits for every 10-bit channel are packed
|
||||
for (uint8_t i = 0; i < 4; ++i)
|
||||
{
|
||||
uint16_t v = convert_channel_10b(CH_AETR[i], false);
|
||||
if(sub_protocol>SLT_V2 && (i==CH2 || i==CH3) )
|
||||
v=1023-v; // reverse throttle and elevator channels for Q100/Q200/MR100 protocols
|
||||
packet[i] = v;
|
||||
e = (e >> 2) | (uint8_t) ((v >> 2) & 0xC0);
|
||||
}
|
||||
// Extra bits for AETR
|
||||
packet[4] = e;
|
||||
// 8-bit channels
|
||||
packet[5] = convert_channel_8b(CH5);
|
||||
packet[6] = convert_channel_8b(CH6);
|
||||
if(sub_protocol!=SLT_V1)
|
||||
{
|
||||
if(sub_protocol==Q200)
|
||||
packet[6] = GET_FLAG(CH9_SW , FLAG_Q200_FMODE)
|
||||
|GET_FLAG(CH10_SW, FLAG_Q200_FLIP)
|
||||
|GET_FLAG(CH11_SW, FLAG_Q200_VIDON)
|
||||
|GET_FLAG(CH12_SW, FLAG_Q200_VIDOFF);
|
||||
else if(sub_protocol==MR100 || sub_protocol==Q100)
|
||||
packet[6] = GET_FLAG(CH9_SW , FLAG_MR100_FMODE)
|
||||
|GET_FLAG(CH10_SW, FLAG_MR100_FLIP)
|
||||
|GET_FLAG(CH11_SW, FLAG_MR100_VIDEO) // Does not exist on the Q100 but...
|
||||
|GET_FLAG(CH12_SW, FLAG_MR100_PICTURE); // Does not exist on the Q100 but...
|
||||
packet[7]=convert_channel_8b(CH7);
|
||||
packet[8]=convert_channel_8b(CH8);
|
||||
packet[9]=0xAA; //normal mode for Q100/Q200, unknown for V2/MR100
|
||||
packet[10]=0x00; //normal mode for Q100/Q200, unknown for V2/MR100
|
||||
if((sub_protocol==Q100 || sub_protocol==Q200) && CH13_SW)
|
||||
{//Calibrate
|
||||
packet[9]=0x77; //enter calibration
|
||||
if(calib_counter>=20 && calib_counter<=25) // 7 packets for Q100 / 3 packets for Q200
|
||||
packet[10]=0x20; //launch calibration
|
||||
calib_counter++;
|
||||
if(calib_counter>250) calib_counter=250;
|
||||
}
|
||||
else
|
||||
calib_counter=0;
|
||||
}
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) SLT_send_bind_packet()
|
||||
{
|
||||
SLT_wait_radio();
|
||||
NRF250K_Hopping(SLT_NFREQCHANNELS); //Bind channel
|
||||
BIND_IN_PROGRESS; //Limit TX power to bind level
|
||||
NRF250K_SetPower();
|
||||
BIND_DONE;
|
||||
NRF250K_SetTXAddr((uint8_t *)"\x7E\xB8\x63\xA9", SLT_TXID_SIZE);
|
||||
memcpy((void*)packet,(void*)rx_tx_addr,SLT_TXID_SIZE);
|
||||
if(phase==SLT_BIND2)
|
||||
SLT_send_packet(SLT_TXID_SIZE);
|
||||
else // SLT_BIND1
|
||||
SLT_send_packet(SLT_PAYLOADSIZE_V2);
|
||||
}
|
||||
|
||||
#define SLT_TIMING_BUILD 1000
|
||||
#define SLT_V1_TIMING_PACKET 1000
|
||||
#define SLT_V2_TIMING_PACKET 2042
|
||||
#define SLT_V1_TIMING_BIND2 1000
|
||||
#define SLT_V2_TIMING_BIND1 6507
|
||||
#define SLT_V2_TIMING_BIND2 2112
|
||||
uint16_t SLT_callback()
|
||||
{
|
||||
switch (phase)
|
||||
{
|
||||
case SLT_BUILD:
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(sub_protocol==SLT_V1?20000:13730);
|
||||
#endif
|
||||
SLT_build_packet();
|
||||
NRF250K_SetPower(); //Change power level
|
||||
NRF250K_SetTXAddr(rx_tx_addr, SLT_TXID_SIZE);
|
||||
phase++;
|
||||
return SLT_TIMING_BUILD;
|
||||
case SLT_DATA1:
|
||||
case SLT_DATA2:
|
||||
phase++;
|
||||
if(sub_protocol==SLT_V1)
|
||||
{
|
||||
SLT_send_packet(SLT_PAYLOADSIZE_V1);
|
||||
return SLT_V1_TIMING_PACKET;
|
||||
}
|
||||
else //V2
|
||||
{
|
||||
SLT_send_packet(SLT_PAYLOADSIZE_V2);
|
||||
return SLT_V2_TIMING_PACKET;
|
||||
}
|
||||
case SLT_DATA3:
|
||||
if(sub_protocol==SLT_V1)
|
||||
SLT_send_packet(SLT_PAYLOADSIZE_V1);
|
||||
else //V2
|
||||
SLT_send_packet(SLT_PAYLOADSIZE_V2);
|
||||
if (++packet_count >= 100)
|
||||
{// Send bind packet
|
||||
packet_count = 0;
|
||||
if(sub_protocol==SLT_V1)
|
||||
{
|
||||
phase=SLT_BIND2;
|
||||
return SLT_V1_TIMING_BIND2;
|
||||
}
|
||||
else //V2
|
||||
{
|
||||
phase=SLT_BIND1;
|
||||
return SLT_V2_TIMING_BIND1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{// Continue to send normal packets
|
||||
phase = SLT_BUILD;
|
||||
if(sub_protocol==SLT_V1)
|
||||
return 20000-SLT_TIMING_BUILD;
|
||||
else //V2
|
||||
return 13730-SLT_TIMING_BUILD;
|
||||
}
|
||||
case SLT_BIND1:
|
||||
SLT_send_bind_packet();
|
||||
phase++;
|
||||
return SLT_V2_TIMING_BIND2;
|
||||
case SLT_BIND2:
|
||||
SLT_send_bind_packet();
|
||||
phase = SLT_BUILD;
|
||||
if(sub_protocol==SLT_V1)
|
||||
return 20000-SLT_TIMING_BUILD-SLT_V1_TIMING_BIND2;
|
||||
else //V2
|
||||
return 13730-SLT_TIMING_BUILD-SLT_V2_TIMING_BIND1-SLT_V2_TIMING_BIND2;
|
||||
}
|
||||
return 19000;
|
||||
}
|
||||
|
||||
uint16_t initSLT()
|
||||
{
|
||||
BIND_DONE; // Not a TX bind protocol
|
||||
packet_count = 0;
|
||||
packet_sent = 0;
|
||||
hopping_frequency_no = 0;
|
||||
if(sub_protocol==Q200)
|
||||
{ //Q200: Force high part of the ID otherwise it won't bind
|
||||
rx_tx_addr[0]=0x01;
|
||||
rx_tx_addr[1]=0x02;
|
||||
#ifdef SLT_Q200_FORCE_ID // ID taken from TX dumps
|
||||
rx_tx_addr[0]=0x01;rx_tx_addr[1]=0x02;rx_tx_addr[2]=0x6A;rx_tx_addr[3]=0x31;
|
||||
/* rx_tx_addr[0]=0x01;rx_tx_addr[1]=0x02;rx_tx_addr[2]=0x0B;rx_tx_addr[3]=0x57;*/
|
||||
#endif
|
||||
}
|
||||
SLT_init();
|
||||
SLT_set_freq();
|
||||
phase = SLT_BUILD;
|
||||
return 50000;
|
||||
}
|
||||
|
||||
#endif
|
||||
/*
|
||||
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/>.
|
||||
*/
|
||||
// Last sync with deviation main github branch
|
||||
|
||||
#if defined(SLT_CCNRF_INO)
|
||||
|
||||
#include "iface_nrf250k.h"
|
||||
|
||||
//#define SLT_Q200_FORCE_ID
|
||||
|
||||
// For code readability
|
||||
#define SLT_PAYLOADSIZE_V1 7
|
||||
#define SLT_PAYLOADSIZE_V2 11
|
||||
#define SLT_NFREQCHANNELS 15
|
||||
#define SLT_TXID_SIZE 4
|
||||
#define SLT_BIND_CHANNEL 0x50
|
||||
|
||||
enum{
|
||||
// flags going to packet[6] (Q200)
|
||||
FLAG_Q200_FMODE = 0x20,
|
||||
FLAG_Q200_VIDON = 0x10,
|
||||
FLAG_Q200_FLIP = 0x08,
|
||||
FLAG_Q200_VIDOFF= 0x04,
|
||||
};
|
||||
|
||||
enum{
|
||||
// flags going to packet[6] (MR100 & Q100)
|
||||
FLAG_MR100_FMODE = 0x20,
|
||||
FLAG_MR100_FLIP = 0x04,
|
||||
FLAG_MR100_VIDEO = 0x02,
|
||||
FLAG_MR100_PICTURE = 0x01,
|
||||
};
|
||||
|
||||
enum {
|
||||
SLT_BUILD=0,
|
||||
SLT_DATA1,
|
||||
SLT_DATA2,
|
||||
SLT_DATA3,
|
||||
SLT_BIND1,
|
||||
SLT_BIND2,
|
||||
};
|
||||
|
||||
static void __attribute__((unused)) SLT_RF_init()
|
||||
{
|
||||
NRF250K_Init();
|
||||
NRF250K_SetTXAddr(rx_tx_addr, SLT_TXID_SIZE);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) SLT_set_freq(void)
|
||||
{
|
||||
// Frequency hopping sequence generation
|
||||
for (uint8_t i = 0; i < SLT_TXID_SIZE; ++i)
|
||||
{
|
||||
uint8_t next_i = (i+1) % SLT_TXID_SIZE; // is & 3 better than % 4 ?
|
||||
uint8_t base = i < 2 ? 0x03 : 0x10;
|
||||
hopping_frequency[i*4 + 0] = (rx_tx_addr[i] & 0x3f) + base;
|
||||
hopping_frequency[i*4 + 1] = (rx_tx_addr[i] >> 2) + base;
|
||||
hopping_frequency[i*4 + 2] = (rx_tx_addr[i] >> 4) + (rx_tx_addr[next_i] & 0x03)*0x10 + base;
|
||||
hopping_frequency[i*4 + 3] = (rx_tx_addr[i] >> 6) + (rx_tx_addr[next_i] & 0x0f)*0x04 + base;
|
||||
}
|
||||
|
||||
// Unique freq
|
||||
uint8_t max_freq=0x50; //V1 and V2
|
||||
if(sub_protocol==Q200)
|
||||
max_freq=45;
|
||||
for (uint8_t i = 0; i < SLT_NFREQCHANNELS; ++i)
|
||||
{
|
||||
if(sub_protocol==Q200 && hopping_frequency[i] >= max_freq)
|
||||
hopping_frequency[i] = hopping_frequency[i] - max_freq + 0x03;
|
||||
uint8_t done = 0;
|
||||
while (!done)
|
||||
{
|
||||
done = 1;
|
||||
for (uint8_t j = 0; j < i; ++j)
|
||||
if (hopping_frequency[i] == hopping_frequency[j])
|
||||
{
|
||||
done = 0;
|
||||
hopping_frequency[i] += 7;
|
||||
if (hopping_frequency[i] >= max_freq)
|
||||
hopping_frequency[i] = hopping_frequency[i] - max_freq + 0x03;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Bind channel
|
||||
hopping_frequency[SLT_NFREQCHANNELS]=SLT_BIND_CHANNEL;
|
||||
|
||||
//Calib all channels
|
||||
NRF250K_HoppingCalib(SLT_NFREQCHANNELS+1);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) SLT_wait_radio()
|
||||
{
|
||||
if (packet_sent)
|
||||
while (!NRF250K_IsPacketSent());
|
||||
packet_sent = 0;
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) SLT_send_packet(uint8_t len)
|
||||
{
|
||||
SLT_wait_radio();
|
||||
NRF250K_WritePayload(packet, len);
|
||||
packet_sent = 1;
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) SLT_build_packet()
|
||||
{
|
||||
static uint8_t calib_counter=0;
|
||||
|
||||
// Set radio channel - once per packet batch
|
||||
NRF250K_SetFreqOffset(); // Set frequency offset
|
||||
NRF250K_Hopping(hopping_frequency_no);
|
||||
if (++hopping_frequency_no >= SLT_NFREQCHANNELS)
|
||||
hopping_frequency_no = 0;
|
||||
|
||||
// aileron, elevator, throttle, rudder, gear, pitch
|
||||
uint8_t e = 0; // byte where extension 2 bits for every 10-bit channel are packed
|
||||
for (uint8_t i = 0; i < 4; ++i)
|
||||
{
|
||||
uint16_t v = convert_channel_10b(CH_AETR[i], false);
|
||||
if(sub_protocol>SLT_V2 && (i==CH2 || i==CH3) )
|
||||
v=1023-v; // reverse throttle and elevator channels for Q100/Q200/MR100 protocols
|
||||
packet[i] = v;
|
||||
e = (e >> 2) | (uint8_t) ((v >> 2) & 0xC0);
|
||||
}
|
||||
// Extra bits for AETR
|
||||
packet[4] = e;
|
||||
// 8-bit channels
|
||||
packet[5] = convert_channel_8b(CH5);
|
||||
packet[6] = convert_channel_8b(CH6);
|
||||
if(sub_protocol!=SLT_V1)
|
||||
{
|
||||
if(sub_protocol==Q200)
|
||||
packet[6] = GET_FLAG(CH9_SW , FLAG_Q200_FMODE)
|
||||
|GET_FLAG(CH10_SW, FLAG_Q200_FLIP)
|
||||
|GET_FLAG(CH11_SW, FLAG_Q200_VIDON)
|
||||
|GET_FLAG(CH12_SW, FLAG_Q200_VIDOFF);
|
||||
else if(sub_protocol==MR100 || sub_protocol==Q100)
|
||||
packet[6] = GET_FLAG(CH9_SW , FLAG_MR100_FMODE)
|
||||
|GET_FLAG(CH10_SW, FLAG_MR100_FLIP)
|
||||
|GET_FLAG(CH11_SW, FLAG_MR100_VIDEO) // Does not exist on the Q100 but...
|
||||
|GET_FLAG(CH12_SW, FLAG_MR100_PICTURE); // Does not exist on the Q100 but...
|
||||
packet[7]=convert_channel_8b(CH7);
|
||||
packet[8]=convert_channel_8b(CH8);
|
||||
packet[9]=0xAA; //normal mode for Q100/Q200, unknown for V2/MR100
|
||||
packet[10]=0x00; //normal mode for Q100/Q200, unknown for V2/MR100
|
||||
if((sub_protocol==Q100 || sub_protocol==Q200) && CH13_SW)
|
||||
{//Calibrate
|
||||
packet[9]=0x77; //enter calibration
|
||||
if(calib_counter>=20 && calib_counter<=25) // 7 packets for Q100 / 3 packets for Q200
|
||||
packet[10]=0x20; //launch calibration
|
||||
calib_counter++;
|
||||
if(calib_counter>250) calib_counter=250;
|
||||
}
|
||||
else
|
||||
calib_counter=0;
|
||||
}
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) SLT_send_bind_packet()
|
||||
{
|
||||
SLT_wait_radio();
|
||||
NRF250K_Hopping(SLT_NFREQCHANNELS); //Bind channel
|
||||
BIND_IN_PROGRESS; //Limit TX power to bind level
|
||||
NRF250K_SetPower();
|
||||
BIND_DONE;
|
||||
NRF250K_SetTXAddr((uint8_t *)"\x7E\xB8\x63\xA9", SLT_TXID_SIZE);
|
||||
memcpy((void*)packet,(void*)rx_tx_addr,SLT_TXID_SIZE);
|
||||
if(phase==SLT_BIND2)
|
||||
SLT_send_packet(SLT_TXID_SIZE);
|
||||
else // SLT_BIND1
|
||||
SLT_send_packet(SLT_PAYLOADSIZE_V2);
|
||||
}
|
||||
|
||||
#define SLT_TIMING_BUILD 1000
|
||||
#define SLT_V1_TIMING_PACKET 1000
|
||||
#define SLT_V2_TIMING_PACKET 2042
|
||||
#define SLT_V1_TIMING_BIND2 1000
|
||||
#define SLT_V2_TIMING_BIND1 6507
|
||||
#define SLT_V2_TIMING_BIND2 2112
|
||||
uint16_t SLT_callback()
|
||||
{
|
||||
switch (phase)
|
||||
{
|
||||
case SLT_BUILD:
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(sub_protocol==SLT_V1?20000:13730);
|
||||
#endif
|
||||
SLT_build_packet();
|
||||
NRF250K_SetPower(); //Change power level
|
||||
NRF250K_SetTXAddr(rx_tx_addr, SLT_TXID_SIZE);
|
||||
phase++;
|
||||
return SLT_TIMING_BUILD;
|
||||
case SLT_DATA1:
|
||||
case SLT_DATA2:
|
||||
phase++;
|
||||
if(sub_protocol==SLT_V1)
|
||||
{
|
||||
SLT_send_packet(SLT_PAYLOADSIZE_V1);
|
||||
return SLT_V1_TIMING_PACKET;
|
||||
}
|
||||
else //V2
|
||||
{
|
||||
SLT_send_packet(SLT_PAYLOADSIZE_V2);
|
||||
return SLT_V2_TIMING_PACKET;
|
||||
}
|
||||
case SLT_DATA3:
|
||||
if(sub_protocol==SLT_V1)
|
||||
SLT_send_packet(SLT_PAYLOADSIZE_V1);
|
||||
else //V2
|
||||
SLT_send_packet(SLT_PAYLOADSIZE_V2);
|
||||
if (++packet_count >= 100)
|
||||
{// Send bind packet
|
||||
packet_count = 0;
|
||||
if(sub_protocol==SLT_V1)
|
||||
{
|
||||
phase=SLT_BIND2;
|
||||
return SLT_V1_TIMING_BIND2;
|
||||
}
|
||||
else //V2
|
||||
{
|
||||
phase=SLT_BIND1;
|
||||
return SLT_V2_TIMING_BIND1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{// Continue to send normal packets
|
||||
phase = SLT_BUILD;
|
||||
if(sub_protocol==SLT_V1)
|
||||
return 20000-SLT_TIMING_BUILD;
|
||||
else //V2
|
||||
return 13730-SLT_TIMING_BUILD;
|
||||
}
|
||||
case SLT_BIND1:
|
||||
SLT_send_bind_packet();
|
||||
phase++;
|
||||
return SLT_V2_TIMING_BIND2;
|
||||
case SLT_BIND2:
|
||||
SLT_send_bind_packet();
|
||||
phase = SLT_BUILD;
|
||||
if(sub_protocol==SLT_V1)
|
||||
return 20000-SLT_TIMING_BUILD-SLT_V1_TIMING_BIND2;
|
||||
else //V2
|
||||
return 13730-SLT_TIMING_BUILD-SLT_V2_TIMING_BIND1-SLT_V2_TIMING_BIND2;
|
||||
}
|
||||
return 19000;
|
||||
}
|
||||
|
||||
void SLT_init()
|
||||
{
|
||||
BIND_DONE; // Not a TX bind protocol
|
||||
packet_count = 0;
|
||||
packet_sent = 0;
|
||||
hopping_frequency_no = 0;
|
||||
if(sub_protocol==Q200)
|
||||
{ //Q200: Force high part of the ID otherwise it won't bind
|
||||
rx_tx_addr[0]=0x01;
|
||||
rx_tx_addr[1]=0x02;
|
||||
#ifdef SLT_Q200_FORCE_ID // ID taken from TX dumps
|
||||
rx_tx_addr[0]=0x01;rx_tx_addr[1]=0x02;rx_tx_addr[2]=0x6A;rx_tx_addr[3]=0x31;
|
||||
/* rx_tx_addr[0]=0x01;rx_tx_addr[1]=0x02;rx_tx_addr[2]=0x0B;rx_tx_addr[3]=0x57;*/
|
||||
#endif
|
||||
}
|
||||
SLT_RF_init();
|
||||
SLT_set_freq();
|
||||
phase = SLT_BUILD;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -230,11 +230,16 @@ void SX1276_SetPaConfig(bool pa_boost_pin, uint8_t max_power, uint8_t output_pow
|
||||
uint8_t data = 0x00;
|
||||
data = data | (pa_boost_pin << 7);
|
||||
data = data | (max_power << 4);
|
||||
data = data | output_power;
|
||||
data = data | (output_power & 0x0F);
|
||||
|
||||
SX1276_WriteReg(SX1276_09_PACONFIG, data);
|
||||
}
|
||||
|
||||
void SX1276_SetOcp(bool OcpOn, uint8_t OcpTrim)
|
||||
{
|
||||
SX1276_WriteReg(SX1276_0B_OCP, (OcpOn << 5) | OcpTrim);
|
||||
}
|
||||
|
||||
void SX1276_WritePayloadToFifo(uint8_t* payload, uint8_t length)
|
||||
{
|
||||
SX1276_WriteReg(SX1276_22_PAYLOAD_LENGTH, length);
|
||||
|
||||
@@ -93,7 +93,7 @@ static int __attribute__((unused)) Scanner_scan_rssi()
|
||||
return rssi_rel;
|
||||
}
|
||||
|
||||
uint16_t Scanner_callback()
|
||||
uint16_t SCANNER_callback()
|
||||
{
|
||||
uint8_t rssi,max_rssi;
|
||||
|
||||
@@ -131,7 +131,7 @@ uint16_t Scanner_callback()
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t initScanner(void)
|
||||
void SCANNER_init(void)
|
||||
{
|
||||
rf_ch_num = 0;
|
||||
telemetry_link = 0;
|
||||
@@ -141,7 +141,6 @@ uint16_t initScanner(void)
|
||||
CC2500_Strobe(CC2500_SIDLE);
|
||||
CC2500_SetTxRxMode(RX_EN);
|
||||
CC2500_Strobe(CC2500_SRX); // Receive mode
|
||||
return 1250;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -120,7 +120,7 @@ static void __attribute__((unused)) SKYARTEC_send_bind_packet()
|
||||
CC2500_WriteData(packet, 12);
|
||||
}
|
||||
|
||||
uint16_t ReadSKYARTEC()
|
||||
uint16_t SKYARTEC_callback()
|
||||
{
|
||||
if (phase & 0x01)
|
||||
{
|
||||
@@ -154,7 +154,7 @@ uint16_t ReadSKYARTEC()
|
||||
return 3000;
|
||||
}
|
||||
|
||||
uint16_t initSKYARTEC()
|
||||
void SKYARTEC_init()
|
||||
{
|
||||
SKYARTEC_rf_init();
|
||||
|
||||
@@ -168,7 +168,6 @@ uint16_t initSKYARTEC()
|
||||
|
||||
bind_counter = 250;
|
||||
phase = SKYARTEC_PKT1;
|
||||
return 10000;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -189,23 +189,17 @@ static void __attribute__((unused)) SYMAX_send_packet(uint8_t bind)
|
||||
NRF24L01_SetPower(); // Set tx_power
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) symax_init()
|
||||
static void __attribute__((unused)) symax_rf_init()
|
||||
{
|
||||
NRF24L01_Initialize();
|
||||
//
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
//
|
||||
NRF24L01_ReadReg(NRF24L01_07_STATUS);
|
||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO));
|
||||
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknoledgement
|
||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x3F); // 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, 0xff); // 4mS retransmit t/o, 15 tries (retries w/o AA?)
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, 0x08);
|
||||
|
||||
if (sub_protocol==SYMAX5C)
|
||||
{
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_1M);
|
||||
//NRF24L01_SetBitrate(NRF24L01_BR_1M);
|
||||
packet_length = 16;
|
||||
}
|
||||
else
|
||||
@@ -214,8 +208,6 @@ static void __attribute__((unused)) symax_init()
|
||||
packet_length = 10;
|
||||
}
|
||||
//
|
||||
NRF24L01_SetPower();
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
|
||||
NRF24L01_WriteReg(NRF24L01_08_OBSERVE_TX, 0x00);
|
||||
NRF24L01_WriteReg(NRF24L01_09_CD, 0x00);
|
||||
NRF24L01_WriteReg(NRF24L01_0C_RX_ADDR_P2, 0xC3); // LSB byte of pipe 2 receive address
|
||||
@@ -231,14 +223,6 @@ static void __attribute__((unused)) symax_init()
|
||||
NRF24L01_WriteReg(NRF24L01_17_FIFO_STATUS, 0x00); // Just in case, no real bits to write here
|
||||
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR , sub_protocol==SYMAX5C ? (uint8_t *)"\x6D\x6A\x73\x73\x73" : (uint8_t *)"\xAB\xAC\xAD\xAE\xAF" ,5);
|
||||
|
||||
NRF24L01_ReadReg(NRF24L01_07_STATUS);
|
||||
NRF24L01_FlushTx();
|
||||
NRF24L01_ReadReg(NRF24L01_07_STATUS);
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x0e);
|
||||
NRF24L01_ReadReg(NRF24L01_00_CONFIG);
|
||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, 0x0c);
|
||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, 0x0e); // power on
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) symax_init1()
|
||||
@@ -331,7 +315,7 @@ static uint8_t chans_data_x5c[] = {0x1d, 0x2f, 0x26, 0x3d, 0x15, 0x2b, 0x25, 0x2
|
||||
packet_count = 0;
|
||||
}
|
||||
|
||||
uint16_t symax_callback()
|
||||
uint16_t SYMAX_callback()
|
||||
{
|
||||
switch (phase)
|
||||
{
|
||||
@@ -368,14 +352,13 @@ uint16_t symax_callback()
|
||||
return SYMAX_PACKET_PERIOD;
|
||||
}
|
||||
|
||||
uint16_t initSymax()
|
||||
void SYMAX_init()
|
||||
{
|
||||
packet_count = 0;
|
||||
flags = 0;
|
||||
BIND_IN_PROGRESS; // autobind protocol
|
||||
symax_init();
|
||||
symax_rf_init();
|
||||
phase = SYMAX_INIT1;
|
||||
return SYMAX_INITIAL_WAIT;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -43,7 +43,7 @@ uint16_t TEST_callback()
|
||||
return TEST_PACKET_PERIOD>>1;
|
||||
}
|
||||
|
||||
uint16_t initTEST()
|
||||
void TEST_init()
|
||||
{
|
||||
option=1;
|
||||
|
||||
@@ -57,7 +57,6 @@ uint16_t initTEST()
|
||||
phase=0;
|
||||
for(uint8_t i=0; i<TEST_PAYLOAD_SIZE; i++)
|
||||
packet[i]= i;
|
||||
return TEST_INITIAL_WAIT;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -97,7 +97,7 @@ static void __attribute__((unused)) TRAXXAS_send_data_packet()
|
||||
CYRF_WriteDataPacketLen(packet, TRAXXAS_PACKET_SIZE);
|
||||
}
|
||||
|
||||
uint16_t ReadTRAXXAS()
|
||||
uint16_t TRAXXAS_callback()
|
||||
{
|
||||
uint8_t status;
|
||||
|
||||
@@ -171,10 +171,8 @@ uint16_t ReadTRAXXAS()
|
||||
return 13940;
|
||||
}
|
||||
|
||||
uint16_t initTRAXXAS()
|
||||
void TRAXXAS_init()
|
||||
{
|
||||
CYRF_Reset();
|
||||
|
||||
//Config CYRF registers
|
||||
for(uint8_t i = 0; i < sizeof(TRAXXAS_init_vals) / 2; i++)
|
||||
CYRF_WriteRegister(pgm_read_byte_near(&TRAXXAS_init_vals[i][0]), pgm_read_byte_near(&TRAXXAS_init_vals[i][1]));
|
||||
@@ -199,7 +197,6 @@ uint16_t initTRAXXAS()
|
||||
}
|
||||
else
|
||||
phase = TRAXXAS_PREP_DATA;
|
||||
return 1000;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
uint8_t RetrySequence ;
|
||||
|
||||
#if ( defined(MULTI_TELEMETRY) || defined(MULTI_STATUS) )
|
||||
#ifdef MULTI_TELEMETRY
|
||||
uint32_t lastMulti = 0;
|
||||
#define MULTI_TIME 500 //in ms
|
||||
#ifdef MULTI_SYNC
|
||||
@@ -28,7 +28,7 @@ uint8_t RetrySequence ;
|
||||
uint32_t lastInputSync = 0;
|
||||
uint16_t inputDelay = 0;
|
||||
#endif // MULTI_SYNC
|
||||
#endif // MULTI_TELEMETRY/MULTI_STATUS
|
||||
#endif // MULTI_TELEMETRY
|
||||
|
||||
#if defined SPORT_TELEMETRY
|
||||
#define FRSKY_SPORT_PACKET_SIZE 8
|
||||
@@ -53,6 +53,14 @@ uint8_t RetrySequence ;
|
||||
#if defined HUB_TELEMETRY
|
||||
#define USER_MAX_BYTES 6
|
||||
uint8_t prev_index;
|
||||
|
||||
struct t_FrSkyD_User_Frame
|
||||
{
|
||||
uint8_t ID;
|
||||
uint8_t low;
|
||||
uint8_t high;
|
||||
} FrSkyD_User_Frame[8];
|
||||
uint8_t FrSkyD_User_Frame_Start=0, FrSkyD_User_Frame_End=0;
|
||||
#endif // HUB_TELEMETRY
|
||||
|
||||
#define START_STOP 0x7e
|
||||
@@ -62,16 +70,12 @@ uint8_t RetrySequence ;
|
||||
uint8_t pktx[MAX_PKTX];
|
||||
uint8_t frame[18];
|
||||
|
||||
#if ( defined(MULTI_TELEMETRY) || defined(MULTI_STATUS) )
|
||||
#ifdef MULTI_TELEMETRY
|
||||
static void multi_send_header(uint8_t type, uint8_t len)
|
||||
{
|
||||
Serial_write('M');
|
||||
#ifdef MULTI_TELEMETRY
|
||||
Serial_write('P');
|
||||
Serial_write(type);
|
||||
#else
|
||||
(void)type;
|
||||
#endif
|
||||
Serial_write('P');
|
||||
Serial_write(type);
|
||||
Serial_write(len);
|
||||
}
|
||||
|
||||
@@ -119,15 +123,7 @@ static void telemetry_set_input_sync(uint16_t refreshRate)
|
||||
|
||||
static void multi_send_status()
|
||||
{
|
||||
#ifdef MULTI_TELEMETRY
|
||||
#ifdef MULTI_NAMES
|
||||
multi_send_header(MULTI_TELEMETRY_STATUS, 24);
|
||||
#else
|
||||
multi_send_header(MULTI_TELEMETRY_STATUS, 5);
|
||||
#endif
|
||||
#else
|
||||
multi_send_header(MULTI_TELEMETRY_STATUS, 5);
|
||||
#endif
|
||||
multi_send_header(MULTI_TELEMETRY_STATUS, 24);
|
||||
|
||||
// Build flags
|
||||
uint8_t flags=0;
|
||||
@@ -138,34 +134,36 @@ static void multi_send_status()
|
||||
if (remote_callback != 0)
|
||||
{
|
||||
flags |= 0x04;
|
||||
#ifdef MULTI_NAMES
|
||||
if(multi_protocols_index == 0xFF)
|
||||
{
|
||||
if(protocol!=PROTO_SCANNER)
|
||||
flags &= ~0x04; //Invalid protocol
|
||||
}
|
||||
else if(sub_protocol&0x07)
|
||||
{
|
||||
uint8_t nbr=multi_protocols[multi_protocols_index].nbrSubProto;
|
||||
//if(protocol==PROTO_DSM) nbr++; //Auto sub_protocol
|
||||
if((sub_protocol&0x07)>=nbr)
|
||||
flags &= ~0x04; //Invalid sub protocol
|
||||
}
|
||||
#else
|
||||
if(remote_callback==0)
|
||||
if(multi_protocols_index == 0xFF)
|
||||
{
|
||||
if(protocol!=PROTO_SCANNER)
|
||||
flags &= ~0x04; //Invalid protocol
|
||||
#endif
|
||||
}
|
||||
else if(IS_SUB_PROTO_INVALID)
|
||||
{
|
||||
flags &= ~0x04; //Invalid sub protocol
|
||||
}
|
||||
else if(sub_protocol&0x07)
|
||||
{
|
||||
uint8_t nbr=multi_protocols[multi_protocols_index].nbrSubProto;
|
||||
//if(protocol==PROTO_DSM) nbr++; //Auto sub_protocol
|
||||
if((sub_protocol&0x07)>=nbr )
|
||||
flags &= ~0x04; //Invalid sub protocol
|
||||
}
|
||||
if (IS_WAIT_BIND_on)
|
||||
flags |= 0x10;
|
||||
else
|
||||
if (IS_BIND_IN_PROGRESS)
|
||||
flags |= 0x08;
|
||||
if(IS_CHMAP_PROTOCOL)
|
||||
flags |= 0x40; //Disable_ch_mapping supported
|
||||
#ifdef FAILSAFE_ENABLE
|
||||
if(IS_FAILSAFE_PROTOCOL)
|
||||
flags |= 0x20; //Failsafe supported
|
||||
#endif
|
||||
if(multi_protocols_index != 0xFF)
|
||||
{
|
||||
if(multi_protocols[multi_protocols_index].chMap)
|
||||
flags |= 0x40; //Disable_ch_mapping supported
|
||||
#ifdef FAILSAFE_ENABLE
|
||||
if(multi_protocols[multi_protocols_index].failSafe)
|
||||
flags |= 0x20; //Failsafe supported
|
||||
#endif
|
||||
}
|
||||
if(IS_DATA_BUFFER_LOW_on)
|
||||
flags |= 0x80;
|
||||
}
|
||||
@@ -177,89 +175,112 @@ static void multi_send_status()
|
||||
Serial_write(VERSION_REVISION);
|
||||
Serial_write(VERSION_PATCH_LEVEL);
|
||||
|
||||
#ifdef MULTI_TELEMETRY
|
||||
// Channel order
|
||||
Serial_write(RUDDER<<6|THROTTLE<<4|ELEVATOR<<2|AILERON);
|
||||
#endif
|
||||
// Channel order
|
||||
Serial_write(RUDDER<<6|THROTTLE<<4|ELEVATOR<<2|AILERON);
|
||||
|
||||
#ifdef MULTI_NAMES
|
||||
if(multi_protocols_index == 0xFF) // selection out of list... send first available protocol
|
||||
if(multi_protocols_index == 0xFF) // selection out of list... send first available protocol
|
||||
{
|
||||
Serial_write(multi_protocols[0].protocol); // begining of list
|
||||
Serial_write(multi_protocols[0].protocol); // begining of list
|
||||
for(uint8_t i=0;i<16;i++)
|
||||
Serial_write(0x00); // everything else is invalid
|
||||
}
|
||||
else
|
||||
{
|
||||
// Protocol next/prev
|
||||
if(multi_protocols[multi_protocols_index+1].protocol != 0xFF)
|
||||
{
|
||||
Serial_write(multi_protocols[0].protocol); // begining of list
|
||||
Serial_write(multi_protocols[0].protocol); // begining of list
|
||||
for(uint8_t i=0;i<16;i++)
|
||||
Serial_write(0x00); // everything else is invalid
|
||||
if(multi_protocols[multi_protocols_index+1].protocol == PROTO_SCANNER )//|| multi_protocols[multi_protocols_index+1].protocol == PROTO_CONFIG )
|
||||
{// if next is scanner
|
||||
if(multi_protocols[multi_protocols_index+2].protocol != 0xFF)
|
||||
Serial_write(multi_protocols[multi_protocols_index+2].protocol); // skip to next protocol number
|
||||
else
|
||||
Serial_write(multi_protocols[multi_protocols_index].protocol); // or end of list
|
||||
}
|
||||
else
|
||||
Serial_write(multi_protocols[multi_protocols_index+1].protocol); // next protocol number
|
||||
}
|
||||
else
|
||||
Serial_write(multi_protocols[multi_protocols_index].protocol); // end of list
|
||||
if(multi_protocols_index>0 && multi_protocols[multi_protocols_index-1].protocol != 0)
|
||||
{
|
||||
// Protocol next/prev
|
||||
if(multi_protocols[multi_protocols_index+1].protocol != 0)
|
||||
Serial_write(multi_protocols[multi_protocols_index+1].protocol); // next protocol number
|
||||
else
|
||||
Serial_write(multi_protocols[multi_protocols_index].protocol); // end of list
|
||||
if(multi_protocols_index>0)
|
||||
Serial_write(multi_protocols[multi_protocols_index-1].protocol); // prev protocol number
|
||||
else
|
||||
Serial_write(multi_protocols[multi_protocols_index].protocol); // begining of list
|
||||
// Protocol
|
||||
for(uint8_t i=0;i<7;i++)
|
||||
Serial_write(multi_protocols[multi_protocols_index].ProtoString[i]); // protocol name
|
||||
// Sub-protocol
|
||||
uint8_t nbr=multi_protocols[multi_protocols_index].nbrSubProto;
|
||||
Serial_write(nbr | (multi_protocols[multi_protocols_index].optionType<<4)); // number of sub protocols && option type
|
||||
uint8_t j=0;
|
||||
if(nbr && (sub_protocol&0x07)<nbr)
|
||||
{
|
||||
uint8_t len=multi_protocols[multi_protocols_index].SubProtoString[0];
|
||||
uint8_t offset=len*(sub_protocol&0x07)+1;
|
||||
for(;j<len;j++)
|
||||
Serial_write(multi_protocols[multi_protocols_index].SubProtoString[j+offset]); // current sub protocol name
|
||||
if(multi_protocols[multi_protocols_index-1].protocol == PROTO_SCANNER )//|| multi_protocols[multi_protocols_index-1].protocol == PROTO_CONFIG )
|
||||
{// if prev is scanner
|
||||
if(multi_protocols_index > 1)
|
||||
Serial_write(multi_protocols[multi_protocols_index-2].protocol); // skip to prev protocol number
|
||||
else
|
||||
Serial_write(multi_protocols[multi_protocols_index].protocol); // begining of list
|
||||
}
|
||||
for(;j<8;j++)
|
||||
Serial_write(0x00);
|
||||
else
|
||||
Serial_write(multi_protocols[multi_protocols_index-1].protocol); // prev protocol number
|
||||
}
|
||||
// Channels function
|
||||
//TODO
|
||||
#endif
|
||||
else
|
||||
Serial_write(multi_protocols[multi_protocols_index].protocol); // begining of list
|
||||
// Protocol
|
||||
for(uint8_t i=0;i<7;i++)
|
||||
Serial_write(multi_protocols[multi_protocols_index].ProtoString[i]); // protocol name
|
||||
// Sub-protocol
|
||||
uint8_t nbr=multi_protocols[multi_protocols_index].nbrSubProto;
|
||||
if(option_override>0x0F)
|
||||
Serial_write(nbr | (multi_protocols[multi_protocols_index].optionType<<4)); // number of sub protocols && option type
|
||||
else
|
||||
Serial_write(nbr | (option_override<<4)); // number of sub protocols && option_override type
|
||||
uint8_t j=0;
|
||||
if(nbr && (sub_protocol&0x07)<nbr)
|
||||
{
|
||||
uint8_t len=multi_protocols[multi_protocols_index].SubProtoString[0];
|
||||
uint8_t offset=len*(sub_protocol&0x07)+1;
|
||||
for(;j<len;j++)
|
||||
Serial_write(multi_protocols[multi_protocols_index].SubProtoString[j+offset]); // current sub protocol name
|
||||
}
|
||||
for(;j<8;j++)
|
||||
Serial_write(0x00);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MULTI_CONFIG_INO
|
||||
void CONFIG_frame()
|
||||
{
|
||||
multi_send_header(MULTI_TELEMETRY_CONFIG, 21);
|
||||
for (uint8_t i = 0; i < 21; i++) // Config data
|
||||
Serial_write(packet_in[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MLINK_FW_TELEMETRY
|
||||
void MLINK_frame()
|
||||
{
|
||||
multi_send_header(MULTI_TELEMETRY_MLINK, 10);
|
||||
Serial_write(TX_RSSI); // RSSI
|
||||
Serial_write(TX_LQI); // LQI
|
||||
for (uint8_t i = 0; i < 8; i++) // followed by 8 bytes of telemetry data
|
||||
Serial_write(packet_in[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DSM_TELEMETRY
|
||||
#ifdef MULTI_TELEMETRY
|
||||
void DSM_frame()
|
||||
void DSM_frame()
|
||||
{
|
||||
if (packet_in[0] == 0x80)
|
||||
{
|
||||
if (packet_in[0] == 0x80)
|
||||
{
|
||||
multi_send_header(MULTI_TELEMETRY_DSMBIND, 10);
|
||||
for (uint8_t i = 1; i < 11; i++) // 10 bytes of DSM bind response
|
||||
Serial_write(packet_in[i]);
|
||||
multi_send_header(MULTI_TELEMETRY_DSMBIND, 10);
|
||||
for (uint8_t i = 1; i < 11; i++) // 10 bytes of DSM bind response
|
||||
Serial_write(packet_in[i]);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
multi_send_header(MULTI_TELEMETRY_DSM, 17);
|
||||
for (uint8_t i = 0; i < 17; i++) // RSSI value followed by 16 bytes of telemetry data
|
||||
Serial_write(packet_in[i]);
|
||||
}
|
||||
}
|
||||
#else
|
||||
void DSM_frame()
|
||||
else
|
||||
{
|
||||
Serial_write(0xAA); // Telemetry packet
|
||||
for (uint8_t i = 0; i < 17; i++) // RSSI value followed by 16 bytes of telemetry data
|
||||
multi_send_header(MULTI_TELEMETRY_DSM, 17);
|
||||
for (uint8_t i = 0; i < 17; i++) // RSSI value followed by 16 bytes of telemetry data
|
||||
Serial_write(packet_in[i]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SCANNER_TELEMETRY
|
||||
void spectrum_scanner_frame()
|
||||
{
|
||||
#if defined MULTI_TELEMETRY
|
||||
multi_send_header(MULTI_TELEMETRY_SCANNER, SCAN_CHANS_PER_PACKET + 1);
|
||||
#else
|
||||
Serial_write(0xAA); // Telemetry packet
|
||||
#endif
|
||||
multi_send_header(MULTI_TELEMETRY_SCANNER, SCAN_CHANS_PER_PACKET + 1);
|
||||
Serial_write(packet_in[0]); // start channel
|
||||
for(uint8_t ch = 0; ch < SCAN_CHANS_PER_PACKET; ch++)
|
||||
Serial_write(packet_in[ch+1]); // RSSI power levels
|
||||
@@ -274,11 +295,7 @@ static void multi_send_status()
|
||||
len = 4 + (len / 8);
|
||||
else
|
||||
len = 5 + (len / 8);
|
||||
#if defined MULTI_TELEMETRY
|
||||
multi_send_header(MULTI_TELEMETRY_RX_CHANNELS, len);
|
||||
#else
|
||||
Serial_write(0xAA); // Telemetry packet
|
||||
#endif
|
||||
multi_send_header(MULTI_TELEMETRY_RX_CHANNELS, len);
|
||||
for (uint8_t i = 0; i < len; i++)
|
||||
Serial_write(packet_in[i]); // pps, rssi, ch start, ch count, 16x ch data
|
||||
}
|
||||
@@ -287,11 +304,7 @@ static void multi_send_status()
|
||||
#ifdef AFHDS2A_FW_TELEMETRY
|
||||
void AFHDSA_short_frame()
|
||||
{
|
||||
#if defined MULTI_TELEMETRY
|
||||
multi_send_header(packet_in[29]==0xAA?MULTI_TELEMETRY_AFHDS2A:MULTI_TELEMETRY_AFHDS2A_AC, 29);
|
||||
#else
|
||||
Serial_write(packet_in[29]); // Telemetry packet 0xAA or 0xAC
|
||||
#endif
|
||||
multi_send_header(packet_in[29]==0xAA?MULTI_TELEMETRY_AFHDS2A:MULTI_TELEMETRY_AFHDS2A_AC, 29);
|
||||
for (uint8_t i = 0; i < 29; i++) // RSSI value followed by 4*7 bytes of telemetry data
|
||||
Serial_write(packet_in[i]);
|
||||
}
|
||||
@@ -300,11 +313,7 @@ static void multi_send_status()
|
||||
#ifdef HITEC_FW_TELEMETRY
|
||||
void HITEC_short_frame()
|
||||
{
|
||||
#if defined MULTI_TELEMETRY
|
||||
multi_send_header(MULTI_TELEMETRY_HITEC, 8);
|
||||
#else
|
||||
Serial_write(0xAA); // Telemetry packet
|
||||
#endif
|
||||
multi_send_header(MULTI_TELEMETRY_HITEC, 8);
|
||||
for (uint8_t i = 0; i < 8; i++) // TX RSSI and TX LQI values followed by frame number and 5 bytes of telemetry data
|
||||
Serial_write(packet_in[i]);
|
||||
}
|
||||
@@ -313,24 +322,20 @@ static void multi_send_status()
|
||||
#ifdef HOTT_FW_TELEMETRY
|
||||
void HOTT_short_frame()
|
||||
{
|
||||
#if defined MULTI_TELEMETRY
|
||||
multi_send_header(MULTI_TELEMETRY_HOTT, 14);
|
||||
#else
|
||||
Serial_write(0xAA); // Telemetry packet
|
||||
#endif
|
||||
multi_send_header(MULTI_TELEMETRY_HOTT, 14);
|
||||
for (uint8_t i = 0; i < 14; i++) // TX RSSI and TX LQI values followed by frame number and telemetry data
|
||||
Serial_write(packet_in[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MULTI_TELEMETRY
|
||||
static void multi_send_frskyhub()
|
||||
{
|
||||
multi_send_header(MULTI_TELEMETRY_HUB, 9);
|
||||
for (uint8_t i = 0; i < 9; i++)
|
||||
Serial_write(frame[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //MULTI_TELEMETRY
|
||||
|
||||
void frskySendStuffed()
|
||||
{
|
||||
@@ -517,6 +522,9 @@ void init_frskyd_link_telemetry()
|
||||
TX_RSSI=0;
|
||||
RX_LQI=0;
|
||||
TX_LQI=0;
|
||||
#if defined HUB_TELEMETRY
|
||||
FrSkyD_User_Frame_Start=FrSkyD_User_Frame_End=0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void frsky_link_frame()
|
||||
@@ -531,7 +539,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_OMP, PROTO_WFLY2, PROTO_LOLI
|
||||
{//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, PROTO_WFLY2, PROTO_LOLI, PROTO_MLINK, PROTO_MT99XX
|
||||
frame[1] = v_lipo1;
|
||||
frame[2] = v_lipo2;
|
||||
frame[3] = RX_RSSI;
|
||||
@@ -594,7 +602,7 @@ packet_in[6]|(counter++)|00 01 02 03 04 05 06 07 08 09
|
||||
0A 0F 5E 3A 06 00 5E 5E 3B 09 00 5E
|
||||
05 10 5E 06 16 72 5E 5E 3A 06 00 5E
|
||||
*/
|
||||
static void __attribute__((unused)) frsky_send_user_frame(uint8_t ID, uint8_t low, uint8_t high)
|
||||
static void __attribute__((unused)) frsky_write_user_frame(uint8_t ID, uint8_t low, uint8_t high)
|
||||
{
|
||||
telemetry_in_buffer[6] = 0x04; // number of bytes in the payload
|
||||
telemetry_in_buffer[7] = 0x00; // unknown?
|
||||
@@ -615,7 +623,32 @@ static void __attribute__((unused)) frsky_send_user_frame(uint8_t ID, uint8_t lo
|
||||
telemetry_in_buffer[pos++] = value;
|
||||
value = high;
|
||||
}
|
||||
telemetry_link |= 2; // request to send frame
|
||||
telemetry_link |= 2; // request to send frame
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) frsky_send_user_frame(uint8_t ID, uint8_t low, uint8_t high)
|
||||
{
|
||||
if(telemetry_link&2)
|
||||
{ // add to buffer
|
||||
uint8_t test = (FrSkyD_User_Frame_End + 1) & 0x07;
|
||||
if(test == FrSkyD_User_Frame_Start)
|
||||
return; // buffer full...
|
||||
FrSkyD_User_Frame_End = test;
|
||||
FrSkyD_User_Frame[FrSkyD_User_Frame_End].ID = ID;
|
||||
FrSkyD_User_Frame[FrSkyD_User_Frame_End].low = low;
|
||||
FrSkyD_User_Frame[FrSkyD_User_Frame_End].high = high;
|
||||
}
|
||||
else // send to TX direct
|
||||
frsky_write_user_frame(ID, low, high);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) frsky_check_user_frame()
|
||||
{
|
||||
if((telemetry_link&2) || FrSkyD_User_Frame_Start == FrSkyD_User_Frame_End)
|
||||
return; // need to wait that the last frame is sent or buffer is empty
|
||||
frsky_write_user_frame(FrSkyD_User_Frame[FrSkyD_User_Frame_Start].ID, FrSkyD_User_Frame[FrSkyD_User_Frame_Start].low, FrSkyD_User_Frame[FrSkyD_User_Frame_Start].high);
|
||||
FrSkyD_User_Frame_Start++;
|
||||
FrSkyD_User_Frame_Start &= 0x07;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -877,7 +910,7 @@ void TelemetryUpdate()
|
||||
debugln("TEL_BUF %d",t);
|
||||
*/
|
||||
#endif
|
||||
#if defined(MULTI_TELEMETRY) || defined(MULTI_STATUS)
|
||||
#ifdef MULTI_TELEMETRY
|
||||
uint32_t now = millis();
|
||||
if ((IS_SEND_MULTI_STATUS_on || ((now - lastMulti) > MULTI_TIME))&& protocol != PROTO_SCANNER)
|
||||
{
|
||||
@@ -923,67 +956,84 @@ void TelemetryUpdate()
|
||||
}
|
||||
#endif // SPORT_TELEMETRY
|
||||
|
||||
#if defined DSM_TELEMETRY
|
||||
if(telemetry_link && protocol == PROTO_DSM)
|
||||
{ // DSM
|
||||
DSM_frame();
|
||||
telemetry_link=0;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if defined AFHDS2A_FW_TELEMETRY
|
||||
if(telemetry_link == 2 && protocol == PROTO_AFHDS2A)
|
||||
{
|
||||
AFHDSA_short_frame();
|
||||
telemetry_link=0;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if defined HITEC_FW_TELEMETRY
|
||||
if(telemetry_link == 2 && protocol == PROTO_HITEC)
|
||||
{
|
||||
HITEC_short_frame();
|
||||
telemetry_link=0;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if defined HOTT_FW_TELEMETRY
|
||||
if(telemetry_link == 2 && protocol == PROTO_HOTT)
|
||||
{
|
||||
HOTT_short_frame();
|
||||
telemetry_link=0;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined SCANNER_TELEMETRY
|
||||
if (telemetry_link && protocol == PROTO_SCANNER)
|
||||
{
|
||||
spectrum_scanner_frame();
|
||||
telemetry_link = 0;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined (FRSKY_RX_TELEMETRY) || defined(AFHDS2A_RX_TELEMETRY) || defined (BAYANG_RX_TELEMETRY) || defined (DSM_RX_CYRF6936_INO)
|
||||
if ((telemetry_link & 1) && (protocol == PROTO_FRSKY_RX || protocol == PROTO_AFHDS2A_RX || protocol == PROTO_BAYANG_RX || protocol == PROTO_DSM_RX) )
|
||||
{
|
||||
receiver_channels_frame();
|
||||
telemetry_link &= ~1;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if( telemetry_link & 1 )
|
||||
{ // FrSkyD + Hubsan + AFHDS2A + Bayang + Cabell + Hitec + Bugs + BugsMini + NCC1701 + PROPEL + RLINK + OMP
|
||||
// FrSkyX telemetry if in PPM
|
||||
frsky_link_frame();
|
||||
return;
|
||||
}
|
||||
#ifdef MULTI_TELEMETRY
|
||||
#if defined MULTI_CONFIG_INO
|
||||
if(telemetry_link && protocol == PROTO_CONFIG)
|
||||
{
|
||||
CONFIG_frame();
|
||||
telemetry_link=0;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if defined MLINK_FW_TELEMETRY
|
||||
if(telemetry_link && protocol == PROTO_MLINK)
|
||||
{
|
||||
MLINK_frame();
|
||||
telemetry_link=0;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if defined DSM_TELEMETRY
|
||||
if(telemetry_link && protocol == PROTO_DSM)
|
||||
{ // DSM
|
||||
DSM_frame();
|
||||
telemetry_link=0;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if defined AFHDS2A_FW_TELEMETRY
|
||||
if(telemetry_link == 2 && protocol == PROTO_AFHDS2A)
|
||||
{
|
||||
AFHDSA_short_frame();
|
||||
telemetry_link=0;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if defined HITEC_FW_TELEMETRY
|
||||
if(telemetry_link == 2 && protocol == PROTO_HITEC)
|
||||
{
|
||||
HITEC_short_frame();
|
||||
telemetry_link=0;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if defined HOTT_FW_TELEMETRY
|
||||
if(telemetry_link == 2 && protocol == PROTO_HOTT)
|
||||
{
|
||||
HOTT_short_frame();
|
||||
telemetry_link=0;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if defined SCANNER_TELEMETRY
|
||||
if (telemetry_link && protocol == PROTO_SCANNER)
|
||||
{
|
||||
spectrum_scanner_frame();
|
||||
telemetry_link = 0;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if defined (FRSKY_RX_TELEMETRY) || defined(AFHDS2A_RX_TELEMETRY) || defined (BAYANG_RX_TELEMETRY) || defined (DSM_RX_CYRF6936_INO)
|
||||
if ((telemetry_link & 1) && (protocol == PROTO_FRSKY_RX || protocol == PROTO_AFHDS2A_RX || protocol == PROTO_BAYANG_RX || protocol == PROTO_DSM_RX) )
|
||||
{
|
||||
receiver_channels_frame();
|
||||
telemetry_link &= ~1;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#endif //MULTI_TELEMETRY
|
||||
|
||||
if( telemetry_link & 1 )
|
||||
{ // FrSkyD + Hubsan + AFHDS2A + Bayang + Cabell + Hitec + Bugs + BugsMini + NCC1701 + PROPEL + RLINK + OMP + MLINK + DEVO
|
||||
// FrSkyX telemetry if in PPM
|
||||
frsky_link_frame();
|
||||
return;
|
||||
}
|
||||
#if defined HUB_TELEMETRY
|
||||
if((telemetry_link & 2) && ( protocol == PROTO_FRSKYD || protocol == PROTO_BAYANG ) )
|
||||
{ // FrSkyD
|
||||
if((telemetry_link & 2) && ( protocol == PROTO_FRSKYD || protocol == PROTO_BAYANG || protocol == PROTO_MLINK || protocol == PROTO_DEVO ) )
|
||||
{ // FrSkyD + Bayang + MLINK + DEVO
|
||||
frsky_user_frame();
|
||||
frsky_check_user_frame();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@@ -1023,7 +1073,6 @@ void TelemetryUpdate()
|
||||
#else
|
||||
#ifdef STM32_BOARD
|
||||
usart3_begin(9600,SERIAL_8N1); //USART3
|
||||
USART3_BASE->CR1 &= ~ USART_CR1_RE; //disable RX leave TX enabled
|
||||
#else
|
||||
UBRR0H = 0x00;
|
||||
UBRR0L = 0x67;
|
||||
@@ -1044,7 +1093,6 @@ void TelemetryUpdate()
|
||||
#else
|
||||
#ifdef STM32_BOARD
|
||||
usart3_begin(57600,SERIAL_8N1); //USART3
|
||||
USART3_BASE->CR1 &= ~ USART_CR1_RE; //disable RX leave TX enabled
|
||||
#else
|
||||
UBRR0H = 0x00;
|
||||
UBRR0L = 0x22;
|
||||
@@ -1065,7 +1113,6 @@ void TelemetryUpdate()
|
||||
#else
|
||||
#ifdef STM32_BOARD
|
||||
usart3_begin(125000,SERIAL_8N1); //USART3
|
||||
USART3_BASE->CR1 &= ~ USART_CR1_RE; //disable RX leave TX enabled
|
||||
#else
|
||||
UBRR0H = 0x00;
|
||||
UBRR0L = 0x07;
|
||||
|
||||
@@ -16,7 +16,7 @@ Multiprotocol is distributed in the hope that it will be useful,
|
||||
|
||||
#if defined(TIGER_NRF24L01_INO)
|
||||
|
||||
#include "iface_nrf24l01.h"
|
||||
#include "iface_xn297.h"
|
||||
|
||||
#define TIGER_FORCE_ID
|
||||
|
||||
@@ -66,7 +66,7 @@ static void __attribute__((unused)) TIGER_send_packet()
|
||||
packet[TIGER_PAYLOAD_SIZE-1]=crc8;
|
||||
|
||||
//Hopping frequency
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no>>1]);
|
||||
XN297_Hopping(hopping_frequency_no>>1);
|
||||
hopping_frequency_no++;
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
@@ -79,34 +79,16 @@ static void __attribute__((unused)) TIGER_send_packet()
|
||||
hopping_frequency_no=2*TIGER_BIND_RF_NUM_CHANNELS;
|
||||
}
|
||||
|
||||
//Clear packet status bits and TX FIFO
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||
NRF24L01_FlushTx();
|
||||
//Send packet
|
||||
//Send
|
||||
XN297_SetPower();
|
||||
XN297_SetTxRxMode(TX_EN);
|
||||
XN297_WritePayload(packet, TIGER_PAYLOAD_SIZE);
|
||||
//Set tx_power
|
||||
NRF24L01_SetPower();
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) TIGER_init()
|
||||
static void __attribute__((unused)) TIGER_RF_init()
|
||||
{
|
||||
NRF24L01_Initialize();
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M);
|
||||
XN297_SetTXAddr((uint8_t *)"\x68\x94\xA6\xD5\xC3", 5);
|
||||
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_WriteReg(NRF24L01_04_SETUP_RETR, 0x00); // No retransmits
|
||||
NRF24L01_SetPower();
|
||||
NRF24L01_Activate(0x73); // Activate feature register
|
||||
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x00); // Disable dynamic payload length on all pipes
|
||||
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x01);
|
||||
NRF24L01_Activate(0x73);
|
||||
// Power on, TX mode, 2byte CRC
|
||||
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) TIGER_initialize_txid()
|
||||
@@ -132,7 +114,7 @@ uint16_t TIGER_callback()
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(TIGER_PACKET_PERIOD);
|
||||
#endif
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
if(bind_counter)
|
||||
if(--bind_counter==0)
|
||||
{
|
||||
BIND_DONE;
|
||||
@@ -142,14 +124,13 @@ uint16_t TIGER_callback()
|
||||
return TIGER_PACKET_PERIOD;
|
||||
}
|
||||
|
||||
uint16_t initTIGER()
|
||||
void TIGER_init()
|
||||
{
|
||||
BIND_IN_PROGRESS; // autobind protocol
|
||||
TIGER_initialize_txid();
|
||||
TIGER_init();
|
||||
TIGER_RF_init();
|
||||
hopping_frequency_no = 0;
|
||||
bind_counter=TIGER_BIND_COUNT;
|
||||
return TIGER_INITIAL_WAIT;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -70,38 +70,15 @@ const uint8_t PROGMEM freq_hopping[][16] = {
|
||||
0x18, 0x2A, 0x21, 0x38, 0x10, 0x26, 0x20, 0x1F } // 03
|
||||
};
|
||||
|
||||
static void __attribute__((unused)) v202_init()
|
||||
static void __attribute__((unused)) V2X2_RF_init()
|
||||
{
|
||||
NRF24L01_Initialize();
|
||||
|
||||
// 2-bytes CRC, radio off
|
||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO));
|
||||
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknoledgement
|
||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x3F); // Enable all data pipes
|
||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5-byte RX/TX address
|
||||
// NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0xFF); // 4ms retransmit t/o, 15 tries
|
||||
// NRF24L01_WriteReg(NRF24L01_05_RF_CH, 0x08); // Channel 8
|
||||
NRF24L01_SetBitrate(sub_protocol==V2X2_MR101?NRF24L01_BR_250K:NRF24L01_BR_1M);
|
||||
NRF24L01_SetPower();
|
||||
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
|
||||
// NRF24L01_WriteReg(NRF24L01_08_OBSERVE_TX, 0x00); // no write bits in this field
|
||||
// NRF24L01_WriteReg(NRF24L01_00_CD, 0x00); // same
|
||||
// NRF24L01_WriteReg(NRF24L01_0C_RX_ADDR_P2, 0xC3); // LSB byte of pipe 2 receive address
|
||||
// NRF24L01_WriteReg(NRF24L01_0D_RX_ADDR_P3, 0xC4);
|
||||
// NRF24L01_WriteReg(NRF24L01_0E_RX_ADDR_P4, 0xC5);
|
||||
// NRF24L01_WriteReg(NRF24L01_0F_RX_ADDR_P5, 0xC6);
|
||||
// NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, V2X2_PAYLOADSIZE); // bytes of data payload for pipe 1
|
||||
// NRF24L01_WriteReg(NRF24L01_12_RX_PW_P1, V2X2_PAYLOADSIZE);
|
||||
// NRF24L01_WriteReg(NRF24L01_13_RX_PW_P2, V2X2_PAYLOADSIZE);
|
||||
// NRF24L01_WriteReg(NRF24L01_14_RX_PW_P3, V2X2_PAYLOADSIZE);
|
||||
// NRF24L01_WriteReg(NRF24L01_15_RX_PW_P4, V2X2_PAYLOADSIZE);
|
||||
// NRF24L01_WriteReg(NRF24L01_16_RX_PW_P5, V2X2_PAYLOADSIZE);
|
||||
// NRF24L01_WriteReg(NRF24L01_17_FIFO_STATUS, 0x00); // Just in case, no real bits to write here
|
||||
if(sub_protocol==V2X2_MR101)
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_250K);
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, (uint8_t *)"\x66\x88\x68\x68\x68", 5);
|
||||
// NRF24L01_WriteRegisterMulti(NRF24L01_0B_RX_ADDR_P1, (uint8_t *)"\x88\x66\x86\x86\x86", 5);
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, (uint8_t *)"\x66\x88\x68\x68\x68", 5);
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, (uint8_t *)"\x66\x88\x68\x68\x68", 5);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) V2X2_set_tx_id(void)
|
||||
@@ -241,15 +218,14 @@ static void __attribute__((unused)) V2X2_send_packet()
|
||||
NRF24L01_SetPower();
|
||||
}
|
||||
|
||||
uint16_t ReadV2x2()
|
||||
uint16_t V2X2_callback()
|
||||
{
|
||||
//if (packet_sent && NRF24L01_packet_ack() != PKT_ACKED)
|
||||
// return V2X2_PACKET_CHKTIME;
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(V2X2_PACKET_PERIOD);
|
||||
#endif
|
||||
V2X2_send_packet();
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
if(bind_counter)
|
||||
{
|
||||
if (--bind_counter == 0)
|
||||
{
|
||||
@@ -264,11 +240,12 @@ uint16_t ReadV2x2()
|
||||
hopping_frequency_no = 0;
|
||||
}
|
||||
}
|
||||
V2X2_send_packet();
|
||||
// Packet every 4ms
|
||||
return V2X2_PACKET_PERIOD;
|
||||
}
|
||||
|
||||
uint16_t initV2x2()
|
||||
void V2X2_init()
|
||||
{
|
||||
if(sub_protocol==V2X2_MR101)
|
||||
BIND_IN_PROGRESS;
|
||||
@@ -276,9 +253,8 @@ uint16_t initV2x2()
|
||||
hopping_frequency_no = 0;
|
||||
bind_counter = V2X2_BIND_COUNT;
|
||||
|
||||
v202_init();
|
||||
V2X2_RF_init();
|
||||
V2X2_set_tx_id();
|
||||
return 50000;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -15,7 +15,7 @@ Multiprotocol is distributed in the hope that it will be useful,
|
||||
|
||||
#if defined(V761_NRF24L01_INO)
|
||||
|
||||
#include "iface_nrf24l01.h"
|
||||
#include "iface_xn297.h"
|
||||
|
||||
//#define V761_FORCE_ID
|
||||
|
||||
@@ -115,30 +115,16 @@ static void __attribute__((unused)) V761_send_packet()
|
||||
hopping_frequency_no = 0;
|
||||
}
|
||||
V761_set_checksum();
|
||||
// Power on, TX mode, 2byte CRC
|
||||
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||
NRF24L01_FlushTx();
|
||||
|
||||
// Send
|
||||
XN297_SetPower();
|
||||
XN297_SetTxRxMode(TX_EN);
|
||||
XN297_WritePayload(packet, V761_PACKET_SIZE);
|
||||
NRF24L01_SetPower();
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) V761_init()
|
||||
static void __attribute__((unused)) V761_RF_init()
|
||||
{
|
||||
NRF24L01_Initialize();
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
NRF24L01_FlushTx();
|
||||
NRF24L01_FlushRx();
|
||||
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_WriteReg(NRF24L01_03_SETUP_AW, 0x02); // set address length (4 bytes)
|
||||
NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x00); // no retransmits
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps
|
||||
NRF24L01_SetPower();
|
||||
NRF24L01_Activate(0x73); // Activate feature register
|
||||
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x00); // Disable dynamic payload length on all pipes
|
||||
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x01);
|
||||
NRF24L01_Activate(0x73);
|
||||
XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) V761_initialize_txid()
|
||||
@@ -187,7 +173,7 @@ uint16_t V761_callback()
|
||||
if(bind_counter)
|
||||
bind_counter--;
|
||||
packet_count ++;
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, V761_BIND_FREQ);
|
||||
XN297_RFChannel(V761_BIND_FREQ);
|
||||
XN297_SetTXAddr((uint8_t*)"\x34\x43\x10\x10", 4);
|
||||
V761_send_packet();
|
||||
if(packet_count >= 20)
|
||||
@@ -200,7 +186,7 @@ uint16_t V761_callback()
|
||||
if(bind_counter)
|
||||
bind_counter--;
|
||||
packet_count ++;
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[0]);
|
||||
XN297_Hopping(0);
|
||||
XN297_SetTXAddr(rx_tx_addr, 4);
|
||||
V761_send_packet();
|
||||
if(bind_counter == 0)
|
||||
@@ -224,7 +210,7 @@ uint16_t V761_callback()
|
||||
return V761_PACKET_PERIOD;
|
||||
}
|
||||
|
||||
uint16_t initV761(void)
|
||||
void V761_init(void)
|
||||
{
|
||||
V761_initialize_txid();
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
@@ -238,10 +224,9 @@ uint16_t initV761(void)
|
||||
phase = V761_DATA;
|
||||
}
|
||||
|
||||
V761_init();
|
||||
V761_RF_init();
|
||||
hopping_frequency_no = 0;
|
||||
packet_count = 0;
|
||||
return V761_INITIAL_WAIT;
|
||||
}
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user