Compare commits
216 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3df836e6b8 | ||
|
|
2b8ed25843 | ||
|
|
62250d2f25 | ||
|
|
a4e9082f53 | ||
|
|
7217e8c41d | ||
|
|
a7ac093753 | ||
|
|
5503502bad | ||
|
|
5124c2a96d | ||
|
|
73d7728e08 | ||
|
|
8b7bd00a48 | ||
|
|
68a6af0eb5 | ||
|
|
693f9f58eb | ||
|
|
4a01e2d472 | ||
|
|
e4fd1f4399 | ||
|
|
0d5fcb0849 | ||
|
|
2236c256ba | ||
|
|
945ad2e7bd | ||
|
|
6f9740f03f | ||
|
|
f9fa4dff73 | ||
|
|
77bf17967d | ||
|
|
7281c0b5bf | ||
|
|
e6cab65560 | ||
|
|
cc115323e1 | ||
|
|
58665ea7a7 | ||
|
|
3920644caf | ||
|
|
25aecbf15e | ||
|
|
e18d8868d2 | ||
|
|
c6e5d00a2b | ||
|
|
7a5b4dea1a | ||
|
|
5df877f32c | ||
|
|
c5c7dda2e0 | ||
|
|
492b9e5ed4 | ||
|
|
9f721c528d | ||
|
|
7f3c80c2a9 | ||
|
|
8f789607e4 | ||
|
|
6a9b6ed4be | ||
|
|
953a97dae4 | ||
|
|
86778c5997 | ||
|
|
8c32cdf5fd | ||
|
|
d092593e5c | ||
|
|
edbf4b6908 | ||
|
|
43f688d011 | ||
|
|
054c3088c3 | ||
|
|
0cedd5bb66 | ||
|
|
1961579fe4 | ||
|
|
6906f1652e | ||
|
|
e2bbe8a422 | ||
|
|
8ea4e00d31 | ||
|
|
917e27280f | ||
|
|
ec92edfc85 | ||
|
|
afd2be6c59 | ||
|
|
a23d50bf0d | ||
|
|
cace1144db | ||
|
|
0d646ed1a6 | ||
|
|
e9b09ffecd | ||
|
|
0008633d6e | ||
|
|
396c005b0a | ||
|
|
d3c3fac4f7 | ||
|
|
cf4acc1d4c | ||
|
|
5bd95f8414 | ||
|
|
a31d9a83a3 | ||
|
|
9b24589897 | ||
|
|
8f3d634132 | ||
|
|
5ef1ccb99b | ||
|
|
e7d91bc76a | ||
|
|
e4309824c2 | ||
|
|
cc6a35ac8a | ||
|
|
1f13a6c281 | ||
|
|
69519bdf14 | ||
|
|
2e5a8f384a | ||
|
|
c803eeb26a | ||
|
|
6a7497cdf8 | ||
|
|
3067ea3a5c | ||
|
|
9a5309d84b | ||
|
|
fff18f825a | ||
|
|
e70bdd4152 | ||
|
|
cf77a1981f | ||
|
|
10e33f5d5c | ||
|
|
db442d81dd | ||
|
|
f800b4f90b | ||
|
|
712f297d86 | ||
|
|
0afed7d3a4 | ||
|
|
6a03972ff3 | ||
|
|
0e40f64c6b | ||
|
|
c83b769f28 | ||
|
|
dad3282bbb | ||
|
|
1621263fb0 | ||
|
|
2686cd0c48 | ||
|
|
b07b081a15 | ||
|
|
c5d4e8c191 | ||
|
|
928641f535 | ||
|
|
c4c5ffec4f | ||
|
|
c048e97d3a | ||
|
|
00f0719659 | ||
|
|
0482627512 | ||
|
|
5856442e0f | ||
|
|
7b281e47d6 | ||
|
|
6ef2934c18 | ||
|
|
19b931223b | ||
|
|
ca15d7108f | ||
|
|
e6e4d33847 | ||
|
|
815cf4fd99 | ||
|
|
5cf2bf2cf5 | ||
|
|
6632da0276 | ||
|
|
9b499ab7d1 | ||
|
|
d29461607b | ||
|
|
243bdf2240 | ||
|
|
cde185901a | ||
|
|
a9f35f8095 | ||
|
|
63d7e32e06 | ||
|
|
400fdb3cc6 | ||
|
|
9f1bdc901c | ||
|
|
61970b028e | ||
|
|
aee92737ca | ||
|
|
0fddd9c119 | ||
|
|
b156f66146 | ||
|
|
63e6590b65 | ||
|
|
103be7f6e0 | ||
|
|
2154b75499 | ||
|
|
6a83cb5577 | ||
|
|
70ce8e9a1f | ||
|
|
fdd0a00d5a | ||
|
|
a8cad1e70a | ||
|
|
40afd67fc6 | ||
|
|
f3b9206d67 | ||
|
|
b76dd4c8ac | ||
|
|
3eb507ebe6 | ||
|
|
fe0a1f0f94 | ||
|
|
fab3339b8d | ||
|
|
10604cf820 | ||
|
|
e297310a25 | ||
|
|
d71006f2ae | ||
|
|
7a8e099a79 | ||
|
|
822aa84fa2 | ||
|
|
948ce9e8b8 | ||
|
|
caf145c38a | ||
|
|
f964cdec98 | ||
|
|
6848fab873 | ||
|
|
72d57cae71 | ||
|
|
a23178e20e | ||
|
|
5ae4f0288b | ||
|
|
e0e51eb187 | ||
|
|
840944ea94 | ||
|
|
31ff27b1d3 | ||
|
|
a234ccbd05 | ||
|
|
6dfd54b8be | ||
|
|
edb7729b35 | ||
|
|
d434e63c22 | ||
|
|
cd7ede006c | ||
|
|
d4d0dc3dbc | ||
|
|
5c7f997e7a | ||
|
|
1623a007a4 | ||
|
|
0b19fa0bdf | ||
|
|
897c8b6ec5 | ||
|
|
d427a7fec1 | ||
|
|
b0749a1bee | ||
|
|
2406080515 | ||
|
|
ff96146b04 | ||
|
|
e3a5b2825d | ||
|
|
9fd72b5ad5 | ||
|
|
c2bf63991f | ||
|
|
a75ae7b65a | ||
|
|
507e4cb07b | ||
|
|
0f250bb04b | ||
|
|
4a315057a2 | ||
|
|
c8f44a0c4b | ||
|
|
382d853fe2 | ||
|
|
a5996c488e | ||
|
|
760642ecb3 | ||
|
|
c7a3548df0 | ||
|
|
d8acc6a5e8 | ||
|
|
431808286b | ||
|
|
747fa19259 | ||
|
|
bf61295b76 | ||
|
|
49a1ecea00 | ||
|
|
11f0e55bb1 | ||
|
|
331da37840 | ||
|
|
032e0641a5 | ||
|
|
f3d2ab61e4 | ||
|
|
e8b5f071fe | ||
|
|
ada72d6113 | ||
|
|
c2404d4f0d | ||
|
|
821732bba9 | ||
|
|
b6df650f50 | ||
|
|
e783ce5788 | ||
|
|
18af4a0724 | ||
|
|
7e6ec1dc8d | ||
|
|
4fbe0859e0 | ||
|
|
b89c23fe7c | ||
|
|
e038c49ae9 | ||
|
|
bed02c9384 | ||
|
|
96bc4f7cdf | ||
|
|
6503469ddd | ||
|
|
61a1c3742c | ||
|
|
1fb2a38bc1 | ||
|
|
22a0d79315 | ||
|
|
0cc72772a3 | ||
|
|
11f4e636e3 | ||
|
|
fef1a2e041 | ||
|
|
41a9c8e013 | ||
|
|
c1ad02b792 | ||
|
|
ab2315c951 | ||
|
|
7948e33cbc | ||
|
|
2be2dce584 | ||
|
|
69bdfe3dba | ||
|
|
d73d163a58 | ||
|
|
48a52ae5b2 | ||
|
|
078dc2ab17 | ||
|
|
6f4522caa6 | ||
|
|
3c76ce9f39 | ||
|
|
8601149051 | ||
|
|
d7ef15d435 | ||
|
|
27e3645b56 | ||
|
|
95eb4e1a22 | ||
|
|
32ea07bf5a | ||
|
|
06272575c5 |
432
.travis.yml
@@ -1,8 +1,7 @@
|
|||||||
dist: trusty
|
dist: bionic
|
||||||
sudo: true
|
sudo: true
|
||||||
#
|
|
||||||
language: c
|
language: c
|
||||||
#
|
|
||||||
env:
|
env:
|
||||||
global:
|
global:
|
||||||
- IDE_VERSION=1.8.9
|
- IDE_VERSION=1.8.9
|
||||||
@@ -13,39 +12,18 @@ env:
|
|||||||
- BOARD="multi4in1:STM32F1:multistm32f103c:debug_option=none"
|
- BOARD="multi4in1:STM32F1:multistm32f103c:debug_option=none"
|
||||||
- BOARD="multi4in1:STM32F1:multistm32f103c:debug_option=native"
|
- BOARD="multi4in1:STM32F1:multistm32f103c:debug_option=native"
|
||||||
- BOARD="multi4in1:STM32F1:multistm32f103c:debug_option=ftdi"
|
- BOARD="multi4in1:STM32F1:multistm32f103c:debug_option=ftdi"
|
||||||
#
|
|
||||||
notifications:
|
notifications:
|
||||||
email: false
|
email: false
|
||||||
#
|
|
||||||
before_install:
|
before_install:
|
||||||
#
|
|
||||||
# Fetch the tag information for the current branch
|
# Fetch the tag information for the current branch
|
||||||
- git fetch origin --tags
|
- git fetch origin --tags
|
||||||
#
|
|
||||||
# Publish the buildroot script folder
|
# Publish the buildroot script folder
|
||||||
- chmod +x ${TRAVIS_BUILD_DIR}/buildroot/bin/*
|
- chmod +x ${TRAVIS_BUILD_DIR}/buildroot/bin/*
|
||||||
- export PATH=${TRAVIS_BUILD_DIR}/buildroot/bin/:${PATH}
|
- export PATH=${TRAVIS_BUILD_DIR}/buildroot/bin/:${PATH}
|
||||||
#
|
|
||||||
# Install Arduino IDE
|
|
||||||
- wget http://downloads.arduino.cc/arduino-$IDE_VERSION-linux64.tar.xz
|
|
||||||
- tar xf arduino-$IDE_VERSION-linux64.tar.xz
|
|
||||||
- mv arduino-$IDE_VERSION $HOME/arduino-ide
|
|
||||||
- export PATH=$PATH:$HOME/arduino-ide
|
|
||||||
# Set the Multi boards package URL
|
|
||||||
- arduino --pref "boardsmanager.additional.urls=https://raw.githubusercontent.com/pascallanger/DIY-Multiprotocol-TX-Module-Boards/master/package_multi_4in1_board_index.json" --save-prefs
|
|
||||||
#
|
|
||||||
- if [[ "$BOARD" =~ "multi4in1:STM32F1:" ]]; then
|
|
||||||
arduino --install-boards multi4in1:STM32F1;
|
|
||||||
fi
|
|
||||||
#
|
|
||||||
- if [[ "$BOARD" =~ "multi4in1:avr:" ]]; then
|
|
||||||
arduino --install-boards multi4in1:avr;
|
|
||||||
fi
|
|
||||||
#
|
|
||||||
- buildMulti() { exitcode=0; BUILDCMD="arduino --verify --board $BOARD Multiprotocol/Multiprotocol.ino --pref build.path=./build/"; echo $BUILDCMD; $BUILDCMD; if [ $? -ne 0 ]; then exitcode=1; fi; echo; return $exitcode; }
|
|
||||||
- buildProtocol() { exitcode=0; opt_disable $ALL_PROTOCOLS; opt_enable $1; buildMulti; if [ $? -ne 0 ]; then exitcode=1; fi; return $exitcode; }
|
|
||||||
- buildEachProtocol() { exitcode=0; for PROTOCOL in $ALL_PROTOCOLS ; do echo Building $PROTOCOL; buildProtocol $PROTOCOL; if [ $? -ne 0 ]; then exitcode=1; fi; done; return $exitcode; }
|
|
||||||
#
|
|
||||||
# Arduino IDE adds a lot of noise caused by network traffic; firewall it
|
# Arduino IDE adds a lot of noise caused by network traffic; firewall it
|
||||||
- sudo iptables -P INPUT DROP
|
- sudo iptables -P INPUT DROP
|
||||||
- sudo iptables -P FORWARD DROP
|
- sudo iptables -P FORWARD DROP
|
||||||
@@ -53,16 +31,257 @@ before_install:
|
|||||||
- sudo iptables -A INPUT -i lo -j ACCEPT
|
- sudo iptables -A INPUT -i lo -j ACCEPT
|
||||||
- sudo iptables -A OUTPUT -o lo -j ACCEPT
|
- sudo iptables -A OUTPUT -o lo -j ACCEPT
|
||||||
- sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
|
- sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
|
||||||
#
|
|
||||||
install: true
|
# Helper functions for the builds
|
||||||
|
- buildMulti() { start_fold config_diff; travis_time_start; git diff Multiprotocol/_Config.h; end_fold config_diff; exitcode=0; BUILDCMD="arduino --verify --board $BOARD Multiprotocol/Multiprotocol.ino --pref build.path=./build/"; echo $BUILDCMD; $BUILDCMD; if [ $? -ne 0 ]; then exitcode=1; fi; echo; return $exitcode; }
|
||||||
|
- buildProtocol() { exitcode=0; opt_disable $ALL_PROTOCOLS; opt_enable $1; buildMulti; if [ $? -ne 0 ]; then exitcode=1; fi; return $exitcode; }
|
||||||
|
- buildEachProtocol() { exitcodesum=0; for PROTOCOL in $ALL_PROTOCOLS ; do printf "\e[33;1mBuilding $PROTOCOL\e[0m"; buildProtocol $PROTOCOL; if [ $? -ne 0 ]; then exitcodesum=$((exitcodesum + 1)); fi; done; return $exitcodesum; }
|
||||||
|
- buildRFModule() { exitcode=0; opt_disable $ALL_RFMODULES; opt_enable $1; buildMulti; if [ $? -ne 0 ]; then exitcode=1; fi; return $exitcode; }
|
||||||
|
- buildEachRFModule() { exitcodesum=0; for RFMODULE in $ALL_RFMODULES; do printf "\e[33;1mBuilding $RFMODULE\e[0m"; buildRFModule $RFMODULE; if [ $? -ne 0 ]; then exitcodesum=$((exitcodesum + 1)); fi; done; return $exitcodesum; }
|
||||||
|
- buildDefault() { exitcode=0; printf "\n\e[33;1mBuilding default configuration\e[0m\n"; buildMulti; if [ $? -ne 0 ]; then exitcode=1; fi; return $exitcode; }
|
||||||
|
- buildSerialOnly() { exitcode=0; printf "\n\e[33;1mBuilding serial mode only\e[0m\n"; opt_disable ENABLE_PPM; opt_enable ENABLE_SERIAL; buildMulti; if [ $? -ne 0 ]; then exitcode=1; fi; return $exitcode; }
|
||||||
|
- buildPPMOnly() { exitcode=0; printf "\n\e[33;1mBuilding PPM mode only\e[0m\n"; opt_enable ENABLE_PPM; opt_disable ENABLE_SERIAL; buildMulti; if [ $? -ne 0 ]; then exitcode=1; fi; return $exitcode; }
|
||||||
|
|
||||||
|
# Function to build the release files - dependent on board type
|
||||||
|
- if [[ "$BOARD" == "multi4in1:avr:multixmega32d4" ]]; then
|
||||||
|
buildReleaseFiles(){
|
||||||
|
exitcode=0;
|
||||||
|
printf "\n\e[33;1mBuilding multi-orangerx-aetr-green-inv-v$MULTI_VERSION.bin\e[0m";
|
||||||
|
opt_enable $ALL_PROTOCOLS;
|
||||||
|
opt_disable ORANGE_TX_BLUE;
|
||||||
|
buildMulti;
|
||||||
|
exitcode=$((exitcode+$?));
|
||||||
|
mv build/Multiprotocol.ino.bin ./binaries/multi-orangerx-aetr-green-inv-v$MULTI_VERSION.bin;
|
||||||
|
printf "\n\e[33;1mBuilding multi-orangerx-aetr-blue-inv-v$MULTI_VERSION.bin\e[0m";
|
||||||
|
opt_enable ORANGE_TX_BLUE;
|
||||||
|
buildMulti;
|
||||||
|
exitcode=$((exitcode+$?));
|
||||||
|
mv build/Multiprotocol.ino.bin ./binaries/multi-orangerx-aetr-blue-inv-v$MULTI_VERSION.bin;
|
||||||
|
cp Multiprotocol/Multi.txt ./binaries/Multi.txt;
|
||||||
|
return $exitcode; };
|
||||||
|
elif [[ "$BOARD" == "multi4in1:avr:multiatmega328p:bootloader=none" ]]; then
|
||||||
|
buildReleaseFiles(){
|
||||||
|
printf "\n\e[33;1mBuilding multi-avr-usbasp-aetr-A7105-inv-v$MULTI_VERSION.bin\e[0m";
|
||||||
|
exitcode=0;
|
||||||
|
opt_disable CHECK_FOR_BOOTLOADER;
|
||||||
|
opt_disable $ALL_PROTOCOLS;
|
||||||
|
opt_enable $A7105_PROTOCOLS;
|
||||||
|
buildMulti;
|
||||||
|
exitcode=$((exitcode+$?));
|
||||||
|
mv build/Multiprotocol.ino.bin ./binaries/multi-avr-usbasp-aetr-A7105-inv-v$MULTI_VERSION.bin;
|
||||||
|
printf "\n\e[33;1mBuilding multi-avr-usbasp-aetr-CC2500-inv-v$MULTI_VERSION.bin\e[0m";
|
||||||
|
opt_disable $ALL_PROTOCOLS;
|
||||||
|
opt_enable $CC2500_PROTOCOLS;
|
||||||
|
buildMulti;
|
||||||
|
mv build/Multiprotocol.ino.bin ./binaries/multi-avr-usbasp-aetr-CC2500-inv-v$MULTI_VERSION.bin;
|
||||||
|
printf "\n\e[33;1mBuilding multi-avr-usbasp-aetr-CYRF6936-inv-v$MULTI_VERSION.bin\e[0m";
|
||||||
|
opt_disable $ALL_PROTOCOLS;
|
||||||
|
opt_enable $CYRF6936_PROTOCOLS;
|
||||||
|
buildMulti;
|
||||||
|
exitcode=$((exitcode+$?));
|
||||||
|
mv build/Multiprotocol.ino.bin ./binaries/multi-avr-usbasp-aetr-CYRF6936-inv-v$MULTI_VERSION.bin;
|
||||||
|
return $exitcode; };
|
||||||
|
elif [[ "$BOARD" == "multi4in1:avr:multiatmega328p:bootloader=optiboot" ]]; then
|
||||||
|
buildReleaseFiles(){
|
||||||
|
printf "\n\e[33;1mBuilding multi-avr-txflash-aetr-A7105-inv-v$MULTI_VERSION.bin\e[0m";
|
||||||
|
exitcode=0;
|
||||||
|
opt_enable CHECK_FOR_BOOTLOADER;
|
||||||
|
opt_disable $ALL_PROTOCOLS;
|
||||||
|
opt_enable $A7105_PROTOCOLS;
|
||||||
|
buildMulti;
|
||||||
|
exitcode=$((exitcode+$?));
|
||||||
|
mv build/Multiprotocol.ino.bin ./binaries/multi-avr-txflash-aetr-A7105-inv-v$MULTI_VERSION.bin;
|
||||||
|
printf "\n\e[33;1mBuilding multi-avr-txflash-aetr-CC2500-inv-v$MULTI_VERSION.bin\e[0m";
|
||||||
|
opt_disable $ALL_PROTOCOLS;
|
||||||
|
opt_enable $CC2500_PROTOCOLS;
|
||||||
|
buildMulti;
|
||||||
|
exitcode=$((exitcode+$?));
|
||||||
|
mv build/Multiprotocol.ino.bin ./binaries/multi-avr-txflash-aetr-CC2500-inv-v$MULTI_VERSION.bin;
|
||||||
|
printf "\n\e[33;1mBuilding multi-avr-txflash-aetr-CYRF6936-inv-v$MULTI_VERSION.bin\e[0m";
|
||||||
|
opt_disable $ALL_PROTOCOLS;
|
||||||
|
opt_enable $CYRF6936_PROTOCOLS;
|
||||||
|
buildMulti;
|
||||||
|
exitcode=$((exitcode+$?));
|
||||||
|
mv build/Multiprotocol.ino.bin ./binaries/multi-avr-txflash-aetr-CYRF6936-inv-v$MULTI_VERSION.bin;
|
||||||
|
return $exitcode; };
|
||||||
|
elif [[ "$BOARD" == "multi4in1:STM32F1:multistm32f103c:debug_option=none" ]]; then
|
||||||
|
buildReleaseFiles(){
|
||||||
|
printf "\n\e[33;1mBuilding multi-stm-erskytx-aetr-inv-v$MULTI_VERSION.bin\e[0m";
|
||||||
|
exitcode=0;
|
||||||
|
opt_enable CHECK_FOR_BOOTLOADER;
|
||||||
|
opt_enable $ALL_PROTOCOLS;
|
||||||
|
opt_enable MULTI_STATUS;
|
||||||
|
opt_disable MULTI_TELEMETRY;
|
||||||
|
buildMulti;
|
||||||
|
exitcode=$((exitcode+$?));
|
||||||
|
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-erskytx-aetr-inv-v$MULTI_VERSION.bin;
|
||||||
|
printf "\n\e[33;1mBuilding multi-stm-erskytx-taer-inv-v$MULTI_VERSION.bin\e[0m";
|
||||||
|
opt_replace AETR TAER;
|
||||||
|
buildMulti;
|
||||||
|
exitcode=$((exitcode+$?));
|
||||||
|
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-erskytx-taer-inv-v$MULTI_VERSION.bin;
|
||||||
|
printf "\n\e[33;1mBuilding multi-stm-erskytx-reta-inv-v$MULTI_VERSION.bin\e[0m";
|
||||||
|
opt_replace TAER RETA;
|
||||||
|
buildMulti;
|
||||||
|
exitcode=$((exitcode+$?));
|
||||||
|
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-erskytx-reta-inv-v$MULTI_VERSION.bin;
|
||||||
|
printf "\n\e[33;1mBuilding multi-stm-erskytx-aetr-noinv-v$MULTI_VERSION.bin\e[0m";
|
||||||
|
opt_replace RETA AETR;
|
||||||
|
opt_disable INVERT_TELEMETRY;
|
||||||
|
buildMulti;
|
||||||
|
exitcode=$((exitcode+$?));
|
||||||
|
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-erskytx-aetr-noinv-v$MULTI_VERSION.bin;
|
||||||
|
printf "\n\e[33;1mBuilding multi-stm-erskytx-taer-noinv-v$MULTI_VERSION.bin\e[0m";
|
||||||
|
opt_replace AETR TAER;
|
||||||
|
buildMulti;
|
||||||
|
exitcode=$((exitcode+$?));
|
||||||
|
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-erskytx-taer-noinv-v$MULTI_VERSION.bin;
|
||||||
|
printf "\n\e[33;1mBuilding multi-stm-erskytx-reta-noinv-v$MULTI_VERSION.bin\e[0m";
|
||||||
|
opt_replace TAER RETA;
|
||||||
|
buildMulti;
|
||||||
|
exitcode=$((exitcode+$?));
|
||||||
|
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-erskytx-reta-noinv-v$MULTI_VERSION.bin;
|
||||||
|
printf "\n\e[33;1mBuilding multi-stm-opentx-aetr-inv-v$MULTI_VERSION.bin\e[0m";
|
||||||
|
opt_replace RETA AETR;
|
||||||
|
opt_disable MULTI_STATUS;
|
||||||
|
opt_enable MULTI_TELEMETRY;
|
||||||
|
opt_enable INVERT_TELEMETRY;
|
||||||
|
buildMulti;
|
||||||
|
exitcode=$((exitcode+$?));
|
||||||
|
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-opentx-aetr-inv-v$MULTI_VERSION.bin;
|
||||||
|
printf "\n\e[33;1mBuilding multi-stm-opentx-taer-inv-v$MULTI_VERSION.bin\e[0m";
|
||||||
|
opt_replace AETR TAER;
|
||||||
|
buildMulti;
|
||||||
|
exitcode=$((exitcode+$?));
|
||||||
|
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-opentx-taer-inv-v$MULTI_VERSION.bin;
|
||||||
|
printf "\n\e[33;1mBuilding multi-stm-opentx-reta-inv-v$MULTI_VERSION.bin\e[0m";
|
||||||
|
opt_replace TAER RETA;
|
||||||
|
buildMulti;
|
||||||
|
exitcode=$((exitcode+$?));
|
||||||
|
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-opentx-reta-inv-v$MULTI_VERSION.bin;
|
||||||
|
printf "\n\e[33;1mBuilding multi-stm-opentx-aetr-noinv-v$MULTI_VERSION.bin\e[0m";
|
||||||
|
opt_replace RETA AETR;
|
||||||
|
opt_disable INVERT_TELEMETRY;
|
||||||
|
buildMulti;
|
||||||
|
exitcode=$((exitcode+$?));
|
||||||
|
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-opentx-aetr-noinv-v$MULTI_VERSION.bin;
|
||||||
|
printf "\n\e[33;1mBuilding multi-stm-opentx-taer-noinv-v$MULTI_VERSION.bin\e[0m";
|
||||||
|
opt_replace AETR TAER;
|
||||||
|
buildMulti;
|
||||||
|
exitcode=$((exitcode+$?));
|
||||||
|
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-opentx-taer-noinv-v$MULTI_VERSION.bin;
|
||||||
|
printf "\n\e[33;1mBuilding multi-stm-opentx-reta-noinv-v$MULTI_VERSION.bin\e[0m";
|
||||||
|
opt_replace TAER RETA;
|
||||||
|
buildMulti;
|
||||||
|
exitcode=$((exitcode+$?));
|
||||||
|
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-opentx-reta-noinv-v$MULTI_VERSION.bin;
|
||||||
|
printf "\n\e[33;1mBuilding multi-stm-ppm-aetr-noinv-v$MULTI_VERSION.bin\e[0m";
|
||||||
|
opt_replace RETA AETR;
|
||||||
|
opt_disable MULTI_STATUS;
|
||||||
|
opt_disable MULTI_TELEMETRY;
|
||||||
|
opt_set NBR_BANKS 5;
|
||||||
|
buildMulti;
|
||||||
|
exitcode=$((exitcode+$?));
|
||||||
|
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-ppm-aetr-noinv-v$MULTI_VERSION.bin;
|
||||||
|
printf "\n\e[33;1mBuilding multi-stm-ppm-taer-noinv-v$MULTI_VERSION.bin\e[0m";
|
||||||
|
opt_replace AETR TAER;
|
||||||
|
buildMulti;
|
||||||
|
exitcode=$((exitcode+$?));
|
||||||
|
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-ppm-taer-noinv-v$MULTI_VERSION.bin;
|
||||||
|
printf "\n\e[33;1mBuilding multi-stm-ppm-reta-noinv-v$MULTI_VERSION.bin\e[0m";
|
||||||
|
opt_replace TAER RETA;
|
||||||
|
buildMulti;
|
||||||
|
exitcode=$((exitcode+$?));
|
||||||
|
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-ppm-reta-noinv-v$MULTI_VERSION.bin;
|
||||||
|
return $exitcode; };
|
||||||
|
elif [[ "$BOARD" == "multi4in1:STM32F1:multistm32f103c:debug_option=native" ]]; then
|
||||||
|
buildReleaseFiles(){
|
||||||
|
printf "\n\e[33;1mBuilding multi-stm-erskytx-xn297dump-inv-usbdebug-v$MULTI_VERSION.bin\e[0m";
|
||||||
|
exitcode=0;
|
||||||
|
opt_enable CHECK_FOR_BOOTLOADER;
|
||||||
|
opt_disable $ALL_PROTOCOLS;
|
||||||
|
opt_add XN297DUMP_NRF24L01_INO;
|
||||||
|
opt_enable MULTI_STATUS;
|
||||||
|
opt_disable MULTI_TELEMETRY;
|
||||||
|
opt_enable INVERT_TELEMETRY;
|
||||||
|
buildMulti;
|
||||||
|
exitcode=$((exitcode+$?));
|
||||||
|
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-erskytx-xn297dump-inv-usbdebug-v$MULTI_VERSION.bin;
|
||||||
|
printf "\n\e[33;1mBuilding multi-stm-opentx-xn297dump-inv-usbdebug-v$MULTI_VERSION.bin\e[0m";
|
||||||
|
opt_disable $ALL_PROTOCOLS;
|
||||||
|
opt_disable MULTI_STATUS;
|
||||||
|
opt_enable MULTI_TELEMETRY;
|
||||||
|
opt_enable INVERT_TELEMETRY;
|
||||||
|
buildMulti;
|
||||||
|
exitcode=$((exitcode+$?));
|
||||||
|
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-opentx-xn297dump-inv-usbdebug-v$MULTI_VERSION.bin;
|
||||||
|
return $exitcode; };
|
||||||
|
elif [[ "$BOARD" == "multi4in1:STM32F1:multistm32f103c:debug_option=ftdi" ]]; then
|
||||||
|
buildReleaseFiles(){
|
||||||
|
printf "\n\e[33;1mBuilding multi-stm-erskytx-xn297dump-inv-ftdidebug-v$MULTI_VERSION.bin\e[0m";
|
||||||
|
exitcode=0;
|
||||||
|
opt_enable CHECK_FOR_BOOTLOADER;
|
||||||
|
opt_disable $ALL_PROTOCOLS;
|
||||||
|
opt_add XN297DUMP_NRF24L01_INO;
|
||||||
|
opt_enable MULTI_STATUS;
|
||||||
|
opt_disable MULTI_TELEMETRY;
|
||||||
|
opt_enable INVERT_TELEMETRY;
|
||||||
|
buildMulti;
|
||||||
|
exitcode=$((exitcode+$?));
|
||||||
|
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-erskytx-xn297dump-inv-ftdidebug-v$MULTI_VERSION.bin;
|
||||||
|
printf "\n\e[33;1mBuilding multi-stm-opentx-xn297dump-inv-ftdidebug-v$MULTI_VERSION.bin\e[0m";
|
||||||
|
opt_disable $ALL_PROTOCOLS;
|
||||||
|
opt_disable MULTI_STATUS;
|
||||||
|
opt_enable MULTI_TELEMETRY;
|
||||||
|
opt_enable INVERT_TELEMETRY;
|
||||||
|
buildMulti;
|
||||||
|
exitcode=$((exitcode+$?));
|
||||||
|
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-opentx-xn297dump-inv-ftdidebug-v$MULTI_VERSION.bin;
|
||||||
|
return $exitcode; };
|
||||||
|
else
|
||||||
|
buildReleaseFiles() { echo "No release files for this board."; };
|
||||||
|
fi
|
||||||
|
|
||||||
|
install:
|
||||||
|
# Install Arduino IDE
|
||||||
|
- wget http://downloads.arduino.cc/arduino-$IDE_VERSION-linux64.tar.xz
|
||||||
|
- tar xf arduino-$IDE_VERSION-linux64.tar.xz
|
||||||
|
- mv arduino-$IDE_VERSION $HOME/arduino-ide
|
||||||
|
- export PATH=$PATH:$HOME/arduino-ide
|
||||||
|
|
||||||
|
# Set the Multi boards package URL
|
||||||
|
- arduino --pref "boardsmanager.additional.urls=https://raw.githubusercontent.com/pascallanger/DIY-Multiprotocol-TX-Module-Boards/master/package_multi_4in1_board_index.json" --save-prefs
|
||||||
|
|
||||||
|
# Install the STM32 board if needed
|
||||||
|
- if [[ "$BOARD" =~ "multi4in1:STM32F1:" ]]; then
|
||||||
|
arduino --install-boards multi4in1:STM32F1;
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Install the AVR board if needed
|
||||||
|
- if [[ "$BOARD" =~ "multi4in1:avr:" ]]; then
|
||||||
|
arduino --install-boards multi4in1:avr;
|
||||||
|
fi
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
#
|
|
||||||
# Change current working directory to the build dir
|
# Change current working directory to the build dir
|
||||||
- cd ${TRAVIS_BUILD_DIR}
|
- cd ${TRAVIS_BUILD_DIR}
|
||||||
|
|
||||||
|
# Create somwhere to put the exported binaries
|
||||||
|
- mkdir ./binaries
|
||||||
|
|
||||||
# Log the initial Multi config
|
# Log the initial Multi config
|
||||||
- cat Multiprotocol/_Config.h
|
- cat Multiprotocol/_Config.h
|
||||||
|
|
||||||
# Back up the configuration
|
# Back up the configuration
|
||||||
- cp Multiprotocol/_Config.h ./_Config.h.bak
|
- cp Multiprotocol/_Config.h ./_Config.h.bak
|
||||||
|
|
||||||
|
# Get the firmware version number from the source
|
||||||
|
- MAJOR_VERSION=$(grep "VERSION_MAJOR" "Multiprotocol/Multiprotocol.h" | awk -v N=3 '{gsub(/\r/,""); print $N}')
|
||||||
|
- MINOR_VERSION=$(grep "VERSION_MINOR" "Multiprotocol/Multiprotocol.h" | awk -v N=3 '{gsub(/\r/,""); print $N}')
|
||||||
|
- REVISION_VERSION=$(grep "VERSION_REVISION" "Multiprotocol//Multiprotocol.h" | awk -v N=3 '{gsub(/\r/,""); print $N}')
|
||||||
|
- PATCH_VERSION=$(grep "VERSION_PATCH" "Multiprotocol//Multiprotocol.h" | awk -v N=3 '{gsub(/\r/,""); print $N}')
|
||||||
|
- MULTI_VERSION=$MAJOR_VERSION.$MINOR_VERSION.$REVISION_VERSION.$PATCH_VERSION
|
||||||
|
|
||||||
# Derive the Multi protocols from the Multi source
|
# Derive the Multi protocols from the Multi source
|
||||||
- A7105_PROTOCOLS=$(sed -n 's/[\/\/]*[[:blank:]]*#define[[:blank:]]*\([[:alnum:]_]*_A7105_INO\)\(.*\)/\1/p' Multiprotocol/_Config.h)
|
- A7105_PROTOCOLS=$(sed -n 's/[\/\/]*[[:blank:]]*#define[[:blank:]]*\([[:alnum:]_]*_A7105_INO\)\(.*\)/\1/p' Multiprotocol/_Config.h)
|
||||||
- CC2500_PROTOCOLS=$(sed -n 's/[\/\/]*[[:blank:]]*#define[[:blank:]]*\([[:alnum:]_]*_CC2500_INO\)\(.*\)/\1/p' Multiprotocol/_Config.h)
|
- CC2500_PROTOCOLS=$(sed -n 's/[\/\/]*[[:blank:]]*#define[[:blank:]]*\([[:alnum:]_]*_CC2500_INO\)\(.*\)/\1/p' Multiprotocol/_Config.h)
|
||||||
@@ -74,131 +293,64 @@ before_script:
|
|||||||
ALL_PROTOCOLS=$(echo $A7105_PROTOCOLS $CC2500_PROTOCOLS $CYRF6936_PROTOCOLS $NRF24L01_PROTOCOLS);
|
ALL_PROTOCOLS=$(echo $A7105_PROTOCOLS $CC2500_PROTOCOLS $CYRF6936_PROTOCOLS $NRF24L01_PROTOCOLS);
|
||||||
fi
|
fi
|
||||||
- echo $ALL_PROTOCOLS
|
- echo $ALL_PROTOCOLS
|
||||||
#
|
|
||||||
|
# Declare all the installed modules
|
||||||
|
- ALL_RFMODULES=$(echo A7105_INSTALLED CYRF6936_INSTALLED CC2500_INSTALLED NRF24L01_INSTALLED);
|
||||||
|
|
||||||
# Disable CHECK_FOR_BOOTLOADER when not needed
|
# Disable CHECK_FOR_BOOTLOADER when not needed
|
||||||
- if [[ "$BOARD" == "multi4in1:avr:multiatmega328p:bootloader=none" ]]; then
|
- if [[ "$BOARD" == "multi4in1:avr:multiatmega328p:bootloader=none" ]]; then
|
||||||
opt_disable CHECK_FOR_BOOTLOADER;
|
opt_disable CHECK_FOR_BOOTLOADER;
|
||||||
fi
|
fi
|
||||||
#
|
|
||||||
# Trim the build down for the Atmega328p board
|
# Trim the enabled protocols down for the STM32 board with debugging
|
||||||
|
- if [[ "$BOARD" == "multi4in1:STM32F1:multistm32f103c:debug_option=ftdi" ]] || [[ "$BOARD" == "multi4in1:STM32F1:multistm32f103c:debug_option=native" ]]; then
|
||||||
|
opt_disable $ALL_PROTOCOLS;
|
||||||
|
opt_enable FRSKYX_CC2500_INO AFHDS2A_A7105_INO MJXQ_NRF24L01_INO DSM_CYRF6936_INO;
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Trim the enabled protocols down for the Atmega328p board
|
||||||
- if [[ "$BOARD" =~ "multi4in1:avr:multiatmega328p:" ]]; then
|
- if [[ "$BOARD" =~ "multi4in1:avr:multiatmega328p:" ]]; then
|
||||||
opt_disable $ALL_PROTOCOLS;
|
opt_disable $ALL_PROTOCOLS;
|
||||||
opt_enable FRSKYX_CC2500_INO AFHDS2A_A7105_INO MJXQ_NRF24L01_INO DSM_CYRF6936_INO;
|
opt_enable FRSKYX_CC2500_INO AFHDS2A_A7105_INO MJXQ_NRF24L01_INO DSM_CYRF6936_INO;
|
||||||
fi
|
fi
|
||||||
#
|
|
||||||
|
# Useful Travis functions
|
||||||
|
- export -f travis_fold
|
||||||
|
- export -f travis_nanoseconds
|
||||||
|
- export -f travis_time_start
|
||||||
|
- export -f travis_time_finish
|
||||||
|
- start_fold() { echo -e "travis_fold:start:$1"; }
|
||||||
|
- end_fold() { echo -e "\ntravis_fold:end:$1\r"; }
|
||||||
|
|
||||||
script:
|
script:
|
||||||
# Build with all protocols enabled for STM32; a subset of protocols for Atmega
|
# Build with default configuration - all protocols are enabled for STM32; a subset of protocols for Atmega or STM32 debugging
|
||||||
- buildMulti
|
- buildDefault
|
||||||
#
|
|
||||||
# Serial only
|
# Serial only
|
||||||
- opt_disable ENABLE_PPM
|
- buildSerialOnly
|
||||||
- opt_enable ENABLE_SERIAL
|
|
||||||
- buildMulti
|
|
||||||
#
|
|
||||||
# PPM only
|
# PPM only
|
||||||
- opt_enable ENABLE_PPM
|
- buildPPMOnly
|
||||||
- opt_disable ENABLE_SERIAL
|
|
||||||
- buildMulti
|
|
||||||
#
|
|
||||||
# Re-enable PPM and serial
|
# Re-enable PPM and serial
|
||||||
- opt_enable ENABLE_SERIAL
|
- opt_enable ENABLE_SERIAL
|
||||||
- opt_enable ENABLE_PPM
|
- opt_enable ENABLE_PPM
|
||||||
#
|
|
||||||
# Build each protocol individually
|
# Build for each RF module individually
|
||||||
- buildEachProtocol
|
- buildEachRFModule
|
||||||
before_deploy:
|
|
||||||
# Create somwhere to put the binaries
|
|
||||||
- mkdir ./binaries
|
|
||||||
# Restore the default configuration
|
# Restore the default configuration
|
||||||
- cp ./_Config.h.bak Multiprotocol/_Config.h
|
- cp ./_Config.h.bak Multiprotocol/_Config.h
|
||||||
# Build the release files for OrangeRX
|
|
||||||
- if [[ "$BOARD" == "multi4in1:avr:multixmega32d4" ]]; then
|
# Build each protocol individually
|
||||||
opt_enable $ALL_PROTOCOLS;
|
- buildEachProtocol
|
||||||
opt_disable ORANGE_TX_BLUE;
|
|
||||||
buildMulti;
|
# Restore the default configuration
|
||||||
mv build/Multiprotocol.ino.hex ./binaries/multi-orangerx-green-inv-$TRAVIS_TAG.hex;
|
- cp ./_Config.h.bak Multiprotocol/_Config.h
|
||||||
opt_enable ORANGE_TX_BLUE;
|
|
||||||
buildMulti;
|
# Builds the files for a release - always built, but only copied to Github if the test is tagged as a release
|
||||||
mv build/Multiprotocol.ino.hex ./binaries/multi-orangerx-blue-inv-$TRAVIS_TAG.hex;
|
- buildReleaseFiles
|
||||||
fi
|
|
||||||
# Build the release files for AVR without bootloader
|
|
||||||
- if [[ "$BOARD" == "multi4in1:avr:multiatmega328p:bootloader=none" ]]; then
|
|
||||||
opt_disable CHECK_FOR_BOOTLOADER;
|
|
||||||
opt_disable $ALL_PROTOCOLS;
|
|
||||||
opt_enable $A7105_PROTOCOLS;
|
|
||||||
buildMulti;
|
|
||||||
mv build/Multiprotocol.ino.hex ./binaries/multi-avr-usbasp-A7105-inv-$TRAVIS_TAG.hex;
|
|
||||||
opt_disable $ALL_PROTOCOLS;
|
|
||||||
opt_enable $CC2500_PROTOCOLS;
|
|
||||||
buildMulti;
|
|
||||||
mv build/Multiprotocol.ino.hex ./binaries/multi-avr-usbasp-CC2500-inv-$TRAVIS_TAG.hex;
|
|
||||||
opt_disable $ALL_PROTOCOLS;
|
|
||||||
opt_enable $CYRF6936_PROTOCOLS;
|
|
||||||
buildMulti;
|
|
||||||
mv build/Multiprotocol.ino.hex ./binaries/multi-avr-usbasp-CYRF6936-inv-$TRAVIS_TAG.hex;
|
|
||||||
fi
|
|
||||||
# Build the release files for AVR with bootloader
|
|
||||||
- if [[ "$BOARD" == "multi4in1:avr:multiatmega328p:bootloader=optiboot" ]]; then
|
|
||||||
opt_enable CHECK_FOR_BOOTLOADER;
|
|
||||||
opt_disable $ALL_PROTOCOLS;
|
|
||||||
opt_enable $A7105_PROTOCOLS;
|
|
||||||
buildMulti;
|
|
||||||
mv build/Multiprotocol.ino.hex ./binaries/multi-avr-txflash-A7105-inv-$TRAVIS_TAG.hex;
|
|
||||||
opt_disable $ALL_PROTOCOLS;
|
|
||||||
opt_enable $CC2500_PROTOCOLS;
|
|
||||||
buildMulti;
|
|
||||||
mv build/Multiprotocol.ino.hex ./binaries/multi-avr-txflash-CC2500-inv-$TRAVIS_TAG.hex;
|
|
||||||
opt_disable $ALL_PROTOCOLS;
|
|
||||||
opt_enable $CYRF6936_PROTOCOLS;
|
|
||||||
buildMulti;
|
|
||||||
mv build/Multiprotocol.ino.hex ./binaries/multi-avr-txflash-CYRF6936-inv-$TRAVIS_TAG.hex;
|
|
||||||
fi
|
|
||||||
# Build the release files for STM32 without debug
|
|
||||||
- if [[ "$BOARD" == "multi4in1:STM32F1:multistm32f103c:debug_option=none" ]]; then
|
|
||||||
opt_enable CHECK_FOR_BOOTLOADER;
|
|
||||||
opt_enable $ALL_PROTOCOLS;
|
|
||||||
opt_enable MULTI_STATUS;
|
|
||||||
opt_disable MULTI_TELEMETRY;
|
|
||||||
buildMulti;
|
|
||||||
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-erskytx-inv-$TRAVIS_TAG.bin;
|
|
||||||
opt_disable INVERT_TELEMETRY;
|
|
||||||
buildMulti;
|
|
||||||
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-erskytx-noinv-$TRAVIS_TAG.bin;
|
|
||||||
opt_disable MULTI_STATUS;
|
|
||||||
opt_enable MULTI_TELEMETRY;
|
|
||||||
opt_enable INVERT_TELEMETRY;
|
|
||||||
buildMulti;
|
|
||||||
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-opentx-inv-$TRAVIS_TAG.bin;
|
|
||||||
opt_disable INVERT_TELEMETRY;
|
|
||||||
buildMulti;
|
|
||||||
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-opentx-noinv-$TRAVIS_TAG.bin;
|
|
||||||
fi
|
|
||||||
# Build the release files for STM32 with Native USB debugging
|
|
||||||
- if [[ "$BOARD" == "multi4in1:STM32F1:multistm32f103c:debug_option=native" ]]; then
|
|
||||||
opt_enable CHECK_FOR_BOOTLOADER;
|
|
||||||
opt_enable $ALL_PROTOCOLS;
|
|
||||||
opt_enable MULTI_STATUS;
|
|
||||||
opt_disable MULTI_TELEMETRY;
|
|
||||||
buildMulti;
|
|
||||||
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-erskytx-inv-usbdebug-$TRAVIS_TAG.bin;
|
|
||||||
opt_disable MULTI_STATUS;
|
|
||||||
opt_enable MULTI_TELEMETRY;
|
|
||||||
buildMulti;
|
|
||||||
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-opentx-inv-usbdebug-$TRAVIS_TAG.bin;
|
|
||||||
fi
|
|
||||||
# Build the release files for STM32 with FTDI USB debugging
|
|
||||||
- if [[ "$BOARD" == "multi4in1:STM32F1:multistm32f103c:debug_option=ftdi" ]]; then
|
|
||||||
opt_enable CHECK_FOR_BOOTLOADER;
|
|
||||||
opt_enable $ALL_PROTOCOLS;
|
|
||||||
opt_enable MULTI_STATUS;
|
|
||||||
opt_disable MULTI_TELEMETRY;
|
|
||||||
buildMulti;
|
|
||||||
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-erskytx-inv-ftdidebug-$TRAVIS_TAG.bin;
|
|
||||||
opt_disable MULTI_STATUS;
|
|
||||||
opt_enable MULTI_TELEMETRY;
|
|
||||||
buildMulti;
|
|
||||||
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-opentx-inv-ftdidebug-$TRAVIS_TAG.bin;
|
|
||||||
fi
|
|
||||||
deploy:
|
deploy:
|
||||||
provider: releases
|
provider: releases
|
||||||
api_key:
|
api_key:
|
||||||
|
|||||||
@@ -134,6 +134,42 @@
|
|||||||
],
|
],
|
||||||
"toolsDependencies": []
|
"toolsDependencies": []
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "Multi 4-in-1 AVR Boards",
|
||||||
|
"architecture": "avr",
|
||||||
|
"version": "1.0.9",
|
||||||
|
"category": "Contributed",
|
||||||
|
"help": {
|
||||||
|
"online": "https://github.com/pascallanger/DIY-Multiprotocol-TX-Module"
|
||||||
|
},
|
||||||
|
"url": "https://github.com/pascallanger/DIY-Multiprotocol-TX-Module-Boards/raw/master/archives/package_multi_4in1_avr_board_v1.0.9.tar.gz",
|
||||||
|
"archiveFileName": "package_multi_4in1_avr_board_v1.0.9.tar.gz",
|
||||||
|
"checksum": "SHA-256:269c4ddcb8018be2b31f5c9e9f0814d120af492e894b8d5098a814486d56faa5",
|
||||||
|
"size": "318437",
|
||||||
|
"boards": [
|
||||||
|
{"name": "Multi 4-in-1 (Atmega328p, 3.3V, 16MHz)"},
|
||||||
|
{"name": "Multi 4-in-1 (OrangeRX)"}
|
||||||
|
],
|
||||||
|
"toolsDependencies": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Multi 4-in-1 AVR Boards",
|
||||||
|
"architecture": "avr",
|
||||||
|
"version": "1.1.0",
|
||||||
|
"category": "Contributed",
|
||||||
|
"help": {
|
||||||
|
"online": "https://github.com/pascallanger/DIY-Multiprotocol-TX-Module"
|
||||||
|
},
|
||||||
|
"url": "https://github.com/pascallanger/DIY-Multiprotocol-TX-Module-Boards/raw/master/archives/package_multi_4in1_avr_board_v1.1.0.tar.gz",
|
||||||
|
"archiveFileName": "package_multi_4in1_avr_board_v1.1.0.tar.gz",
|
||||||
|
"checksum": "SHA-256:7bacf2db754ceb890a203de5ce89d97aa787a9e6462debeb44cf04830859687a",
|
||||||
|
"size": "326431",
|
||||||
|
"boards": [
|
||||||
|
{"name": "Multi 4-in-1 (Atmega328p, 3.3V, 16MHz)"},
|
||||||
|
{"name": "Multi 4-in-1 (OrangeRX)"}
|
||||||
|
],
|
||||||
|
"toolsDependencies": []
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "Multi 4-in-1 STM32 Board",
|
"name": "Multi 4-in-1 STM32 Board",
|
||||||
"architecture": "STM32F1",
|
"architecture": "STM32F1",
|
||||||
@@ -449,6 +485,48 @@
|
|||||||
"version": "4.8.3-2014q1"
|
"version": "4.8.3-2014q1"
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "Multi 4-in-1 STM32 Board",
|
||||||
|
"architecture": "STM32F1",
|
||||||
|
"version": "1.1.6",
|
||||||
|
"category": "Contributed",
|
||||||
|
"help": {
|
||||||
|
"online": "https://github.com/pascallanger/DIY-Multiprotocol-TX-Module"
|
||||||
|
},
|
||||||
|
"url": "https://github.com/pascallanger/DIY-Multiprotocol-TX-Module-Boards/raw/master/archives/package_multi_4in1_stm32_board_v1.1.6.tar.gz",
|
||||||
|
"archiveFileName": "package_multi_4in1_stm32_board_v1.1.6.tar.gz",
|
||||||
|
"checksum": "SHA-256:d2d1ef721bbcdc3c680c6f98b4b8ab394478ac0f82d67af2f6c389a4a30789f4",
|
||||||
|
"size": "7962942",
|
||||||
|
"boards": [{
|
||||||
|
"name": "Multi 4-in-1 (STM32F103C)"
|
||||||
|
}],
|
||||||
|
"toolsDependencies": [{
|
||||||
|
"packager": "arduino",
|
||||||
|
"name": "arm-none-eabi-gcc",
|
||||||
|
"version": "4.8.3-2014q1"
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Multi 4-in-1 STM32 Board",
|
||||||
|
"architecture": "STM32F1",
|
||||||
|
"version": "1.1.7",
|
||||||
|
"category": "Contributed",
|
||||||
|
"help": {
|
||||||
|
"online": "https://github.com/pascallanger/DIY-Multiprotocol-TX-Module"
|
||||||
|
},
|
||||||
|
"url": "https://github.com/pascallanger/DIY-Multiprotocol-TX-Module-Boards/raw/master/archives/package_multi_4in1_stm32_board_v1.1.7.tar.gz",
|
||||||
|
"archiveFileName": "package_multi_4in1_stm32_board_v1.1.7.tar.gz",
|
||||||
|
"checksum": "SHA-256:37cccde7eafad3d0587d28d13d5f8b2b3244bf7c83e6819b6cb08f4f468815e2",
|
||||||
|
"size": "7966348",
|
||||||
|
"boards": [{
|
||||||
|
"name": "Multi 4-in-1 (STM32F103C)"
|
||||||
|
}],
|
||||||
|
"toolsDependencies": [{
|
||||||
|
"packager": "arduino",
|
||||||
|
"name": "arm-none-eabi-gcc",
|
||||||
|
"version": "4.8.3-2014q1"
|
||||||
|
}]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "Multi 4-in-1 OrangeRX Board - DEPRECATED, USE MULTI 4-IN-1 AVR BOARDS PACKAGE INSTEAD",
|
"name": "Multi 4-in-1 OrangeRX Board - DEPRECATED, USE MULTI 4-IN-1 AVR BOARDS PACKAGE INSTEAD",
|
||||||
"architecture": "orangerx",
|
"architecture": "orangerx",
|
||||||
|
|||||||
@@ -197,7 +197,13 @@ void A7105_AdjustLOBaseFreq(uint8_t cmd)
|
|||||||
offset=(int16_t)FORCE_FLYZONE_TUNING;
|
offset=(int16_t)FORCE_FLYZONE_TUNING;
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
case PROTO_PELIKAN:
|
||||||
|
#ifdef FORCE_PELIKAN_TUNING
|
||||||
|
offset=(int16_t)FORCE_PELIKAN_TUNING;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
case PROTO_AFHDS2A:
|
case PROTO_AFHDS2A:
|
||||||
|
case PROTO_AFHDS2A_RX:
|
||||||
#ifdef FORCE_AFHDS2A_TUNING
|
#ifdef FORCE_AFHDS2A_TUNING
|
||||||
offset=(int16_t)FORCE_AFHDS2A_TUNING;
|
offset=(int16_t)FORCE_AFHDS2A_TUNING;
|
||||||
#endif
|
#endif
|
||||||
@@ -252,7 +258,7 @@ static void __attribute__((unused)) A7105_SetVCOBand(uint8_t vb1, uint8_t vb2)
|
|||||||
A7105_WriteReg(A7105_25_VCO_SBCAL_I, vb2 | 0x08);
|
A7105_WriteReg(A7105_25_VCO_SBCAL_I, vb2 | 0x08);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef AFHDS2A_A7105_INO
|
#if defined(AFHDS2A_A7105_INO) || defined(AFHDS2A_RX_A7105_INO)
|
||||||
const uint8_t PROGMEM AFHDS2A_A7105_regs[] = {
|
const uint8_t PROGMEM AFHDS2A_A7105_regs[] = {
|
||||||
0xFF, 0x42 | (1<<5), 0x00, 0x25, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x01, 0x3c, 0x05, 0x00, 0x50, // 00 - 0f
|
0xFF, 0x42 | (1<<5), 0x00, 0x25, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x01, 0x3c, 0x05, 0x00, 0x50, // 00 - 0f
|
||||||
0x9e, 0x4b, 0x00, 0x02, 0x16, 0x2b, 0x12, 0x4f, 0x62, 0x80, 0xFF, 0xFF, 0x2a, 0x32, 0xc3, 0x1f, // 10 - 1f
|
0x9e, 0x4b, 0x00, 0x02, 0x16, 0x2b, 0x12, 0x4f, 0x62, 0x80, 0xFF, 0xFF, 0x2a, 0x32, 0xc3, 0x1f, // 10 - 1f
|
||||||
@@ -292,6 +298,14 @@ const uint8_t PROGMEM HUBSAN_A7105_regs[] = {
|
|||||||
0xFF, 0xFF // 30 - 31
|
0xFF, 0xFF // 30 - 31
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef PELIKAN_A7105_INO
|
||||||
|
const uint8_t PROGMEM PELIKAN_A7105_regs[] = {
|
||||||
|
0xff, 0x42, 0x00, 0x0F, 0x00, 0xff, 0xff ,0x00, 0x00, 0x00, 0x00, 0x01, 0x21, 0x05, 0x01, 0x50, // 00 - 0f
|
||||||
|
0x9e, 0x4b, 0x00, 0x02, 0x16, 0x2b, 0x12, 0x00, 0x62, 0x80, 0x80, 0x00, 0x0a, 0x32, 0xc3, 0x07, // 10 - 1f
|
||||||
|
0x16, 0x00, 0x00, 0xff, 0x00, 0x00, 0x3b, 0x00, 0x1f, 0x47, 0x80, 0x03, 0x01, 0x45, 0x18, 0x00, // 20 - 2f
|
||||||
|
0x01, 0x0f // 30 - 31
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
#define ID_NORMAL 0x55201041
|
#define ID_NORMAL 0x55201041
|
||||||
#define ID_PLUS 0xAA201041
|
#define ID_PLUS 0xAA201041
|
||||||
@@ -308,6 +322,14 @@ void A7105_Init(void)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef PELIKAN_A7105_INO
|
||||||
|
if(protocol==PROTO_PELIKAN)
|
||||||
|
{
|
||||||
|
A7105_Regs=(uint8_t*)PELIKAN_A7105_regs;
|
||||||
|
A7105_WriteID(0x06230623);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
#ifdef BUGS_A7105_INO
|
#ifdef BUGS_A7105_INO
|
||||||
if(protocol==PROTO_BUGS)
|
if(protocol==PROTO_BUGS)
|
||||||
A7105_Regs=(uint8_t*)BUGS_A7105_regs;
|
A7105_Regs=(uint8_t*)BUGS_A7105_regs;
|
||||||
@@ -329,7 +351,7 @@ void A7105_Init(void)
|
|||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
#ifdef AFHDS2A_A7105_INO
|
#if defined(AFHDS2A_A7105_INO) || defined(AFHDS2A_RX_A7105_INO)
|
||||||
A7105_Regs=(uint8_t*)AFHDS2A_A7105_regs;
|
A7105_Regs=(uint8_t*)AFHDS2A_A7105_regs;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -390,17 +412,21 @@ void A7105_Init(void)
|
|||||||
case PROTO_FLYZONE:
|
case PROTO_FLYZONE:
|
||||||
vco_calibration1=0x02;
|
vco_calibration1=0x02;
|
||||||
break;
|
break;
|
||||||
|
case PROTO_PELIKAN:
|
||||||
|
vco_calibration1=0x0C;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
vco_calibration1=0x0A;
|
vco_calibration1=0x0A;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
A7105_WriteReg(A7105_25_VCO_SBCAL_I,vco_calibration1); //Reset VCO Band calibration
|
A7105_WriteReg(A7105_25_VCO_SBCAL_I,vco_calibration1); //Reset VCO Band calibration
|
||||||
}
|
}
|
||||||
|
|
||||||
A7105_SetTxRxMode(TX_EN);
|
A7105_SetTxRxMode(TX_EN);
|
||||||
A7105_SetPower();
|
A7105_SetPower();
|
||||||
|
|
||||||
A7105_AdjustLOBaseFreq(0);
|
#ifdef USE_A7105_CH15_TUNING
|
||||||
|
A7105_AdjustLOBaseFreq(0);
|
||||||
|
#endif
|
||||||
|
|
||||||
A7105_Strobe(A7105_STANDBY);
|
A7105_Strobe(A7105_STANDBY);
|
||||||
}
|
}
|
||||||
|
|||||||
203
Multiprotocol/AFHDS2A_Rx_a7105.ino
Normal file
@@ -0,0 +1,203 @@
|
|||||||
|
/*
|
||||||
|
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(AFHDS2A_RX_A7105_INO)
|
||||||
|
|
||||||
|
#include "iface_a7105.h"
|
||||||
|
|
||||||
|
#define AFHDS2A_RX_TXPACKET_SIZE 38
|
||||||
|
#define AFHDS2A_RX_RXPACKET_SIZE 37
|
||||||
|
#define AFHDS2A_RX_NUMFREQ 16
|
||||||
|
|
||||||
|
enum {
|
||||||
|
AFHDS2A_RX_BIND1,
|
||||||
|
AFHDS2A_RX_BIND2,
|
||||||
|
AFHDS2A_RX_DATA
|
||||||
|
};
|
||||||
|
|
||||||
|
static void __attribute__((unused)) AFHDS2A_Rx_build_telemetry_packet()
|
||||||
|
{
|
||||||
|
uint32_t bits = 0;
|
||||||
|
uint8_t bitsavailable = 0;
|
||||||
|
uint8_t idx = 0;
|
||||||
|
|
||||||
|
packet_in[idx++] = RX_LQI; // 0 - 130
|
||||||
|
packet_in[idx++] = RX_RSSI;
|
||||||
|
packet_in[idx++] = 0; // start channel
|
||||||
|
packet_in[idx++] = 14; // number of channels in packet
|
||||||
|
// pack channels
|
||||||
|
for (uint8_t i = 0; i < 14; i++) {
|
||||||
|
uint32_t val = packet[9+i*2] | (packet[10+i*2] << 8);
|
||||||
|
if (val < 860)
|
||||||
|
val = 860;
|
||||||
|
// convert ppm (860-2140) to Multi (0-2047)
|
||||||
|
val = min(((val-860)<<3)/5, 2047);
|
||||||
|
|
||||||
|
bits |= val << bitsavailable;
|
||||||
|
bitsavailable += 11;
|
||||||
|
while (bitsavailable >= 8) {
|
||||||
|
packet_in[idx++] = bits & 0xff;
|
||||||
|
bits >>= 8;
|
||||||
|
bitsavailable -= 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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()
|
||||||
|
{
|
||||||
|
uint8_t i;
|
||||||
|
A7105_Init();
|
||||||
|
hopping_frequency_no = 0;
|
||||||
|
packet_count = 0;
|
||||||
|
rx_data_started = false;
|
||||||
|
rx_disable_lna = IS_POWER_FLAG_on;
|
||||||
|
A7105_SetTxRxMode(rx_disable_lna ? TXRX_OFF : RX_EN);
|
||||||
|
A7105_Strobe(A7105_RX);
|
||||||
|
|
||||||
|
if (IS_BIND_IN_PROGRESS) {
|
||||||
|
phase = AFHDS2A_RX_BIND1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
uint16_t temp = AFHDS2A_RX_EEPROM_OFFSET;
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
rx_id[i] = eeprom_read_byte((EE_ADDR)temp++);
|
||||||
|
for (i = 0; i < AFHDS2A_RX_NUMFREQ; i++)
|
||||||
|
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()
|
||||||
|
{
|
||||||
|
static uint32_t pps_timer = 0;
|
||||||
|
static uint16_t pps_counter = 0;
|
||||||
|
static int8_t read_retry;
|
||||||
|
int16_t temp;
|
||||||
|
uint8_t i;
|
||||||
|
|
||||||
|
#ifndef FORCE_AFHDS2A_TUNING
|
||||||
|
A7105_AdjustLOBaseFreq(1);
|
||||||
|
#endif
|
||||||
|
if (rx_disable_lna != IS_POWER_FLAG_on) {
|
||||||
|
rx_disable_lna = IS_POWER_FLAG_on;
|
||||||
|
A7105_SetTxRxMode(rx_disable_lna ? TXRX_OFF : RX_EN);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(phase) {
|
||||||
|
case AFHDS2A_RX_BIND1:
|
||||||
|
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
|
||||||
|
memcpy(hopping_frequency, &packet[11], AFHDS2A_RX_NUMFREQ);
|
||||||
|
phase = AFHDS2A_RX_BIND2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
A7105_WriteReg(A7105_0F_PLL_I, (packet_count++ & 1) ? 0x0D : 0x8C); // bind channels
|
||||||
|
A7105_SetTxRxMode(RX_EN);
|
||||||
|
A7105_Strobe(A7105_RX);
|
||||||
|
return 10000;
|
||||||
|
|
||||||
|
case AFHDS2A_RX_BIND2:
|
||||||
|
// got 2nd bind packet from tx ?
|
||||||
|
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) &&
|
||||||
|
(memcmp(rx_tx_addr, &packet[5], 4) == 0)) {
|
||||||
|
// save tx info to eeprom
|
||||||
|
temp = AFHDS2A_RX_EEPROM_OFFSET;
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
eeprom_write_byte((EE_ADDR)temp++, rx_id[i]);
|
||||||
|
for (i = 0; i < AFHDS2A_RX_NUMFREQ; i++)
|
||||||
|
eeprom_write_byte((EE_ADDR)temp++, hopping_frequency[i]);
|
||||||
|
BIND_DONE;
|
||||||
|
phase = AFHDS2A_RX_DATA;
|
||||||
|
return 3850;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// transmit response packet
|
||||||
|
packet[0] = 0xBC;
|
||||||
|
memcpy(&packet[1], rx_id, 4);
|
||||||
|
memcpy(&packet[5], rx_tx_addr, 4);
|
||||||
|
packet[9] = 0x01;
|
||||||
|
packet[10] = 0x00;
|
||||||
|
memset(&packet[11], 0xFF, 26);
|
||||||
|
A7105_WriteData(AFHDS2A_RX_RXPACKET_SIZE, packet_count++ & 1 ? 0x0D : 0x8C);
|
||||||
|
phase |= AFHDS2A_RX_WAIT_WRITE;
|
||||||
|
return 1700;
|
||||||
|
|
||||||
|
case AFHDS2A_RX_BIND2 | AFHDS2A_RX_WAIT_WRITE:
|
||||||
|
//Wait for TX completion
|
||||||
|
pps_timer = micros();
|
||||||
|
while (micros() - pps_timer < 700) // Wait max 700µs, using serial+telemetry exit in about 120µs
|
||||||
|
if (!(A7105_ReadReg(A7105_00_MODE) & 0x01))
|
||||||
|
break;
|
||||||
|
A7105_Strobe(A7105_RX);
|
||||||
|
phase &= ~AFHDS2A_RX_WAIT_WRITE;
|
||||||
|
return 10000;
|
||||||
|
|
||||||
|
case AFHDS2A_RX_DATA:
|
||||||
|
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
|
||||||
|
int rssi = min(A7105_ReadReg(A7105_1D_RSSI_THOLD),160);
|
||||||
|
RX_RSSI = map16b(rssi, 160, 8, 0, 128);
|
||||||
|
AFHDS2A_Rx_build_telemetry_packet();
|
||||||
|
telemetry_link = 1;
|
||||||
|
}
|
||||||
|
rx_data_started = true;
|
||||||
|
read_retry = 10; // hop to next channel
|
||||||
|
pps_counter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// packets per second
|
||||||
|
if (millis() - pps_timer >= 1000) {
|
||||||
|
pps_timer = millis();
|
||||||
|
debugln("%d pps", pps_counter);
|
||||||
|
RX_LQI = pps_counter / 2;
|
||||||
|
pps_counter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// frequency hopping
|
||||||
|
if (read_retry++ >= 10) {
|
||||||
|
hopping_frequency_no++;
|
||||||
|
if(hopping_frequency_no >= AFHDS2A_RX_NUMFREQ)
|
||||||
|
hopping_frequency_no = 0;
|
||||||
|
A7105_WriteReg(A7105_0F_PLL_I, hopping_frequency[hopping_frequency_no]);
|
||||||
|
A7105_Strobe(A7105_RX);
|
||||||
|
if (rx_data_started)
|
||||||
|
read_retry = 0;
|
||||||
|
else
|
||||||
|
read_retry = -127; // retry longer until first packet is catched
|
||||||
|
}
|
||||||
|
return 385;
|
||||||
|
}
|
||||||
|
return 3850; // never reached
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -78,23 +78,26 @@ enum{
|
|||||||
|
|
||||||
static void AFHDS2A_update_telemetry()
|
static void AFHDS2A_update_telemetry()
|
||||||
{
|
{
|
||||||
|
if(packet[0]==0xAA && packet[9]==0xFD)
|
||||||
|
return; // ignore packets which contain the RX configuration: FD FF 32 00 01 00 FF FF FF 05 DC 05 DE FA FF FF FF FF FF FF FF FF FF FF FF FF FF FF
|
||||||
// Read TX RSSI
|
// Read TX RSSI
|
||||||
int16_t temp=256-(A7105_ReadReg(A7105_1D_RSSI_THOLD)*8)/5; // value from A7105 is between 8 for maximum signal strength to 160 or less
|
int16_t temp=256-(A7105_ReadReg(A7105_1D_RSSI_THOLD)*8)/5; // value from A7105 is between 8 for maximum signal strength to 160 or less
|
||||||
if(temp<0) temp=0;
|
if(temp<0) temp=0;
|
||||||
else if(temp>255) temp=255;
|
else if(temp>255) temp=255;
|
||||||
TX_RSSI=temp;
|
TX_RSSI=temp;
|
||||||
// AA | TXID | rx_id | sensor id | sensor # | value 16 bit big endian | sensor id ......
|
// AA | TXID | rx_id | sensor id | sensor # | value 16 bit big endian | sensor id ......
|
||||||
// max 7 sensors per packet
|
// AC | TXID | rx_id | sensor id | sensor # | length | bytes | sensor id ......
|
||||||
#ifdef AFHDS2A_FW_TELEMETRY
|
#ifdef AFHDS2A_FW_TELEMETRY
|
||||||
if (option & 0x80)
|
if (option & 0x80)
|
||||||
{// forward 0xAA and 0xAC telemetry to TX, skip rx and tx id to save space
|
{// forward 0xAA and 0xAC telemetry to TX, skip rx and tx id to save space
|
||||||
pkt[0]= TX_RSSI;
|
packet_in[0]= TX_RSSI;
|
||||||
debug("T=");
|
debug("T(%02X)=",packet[0]);
|
||||||
for(int i=9;i < AFHDS2A_RXPACKET_SIZE; i++)
|
for(uint8_t i=9;i < AFHDS2A_RXPACKET_SIZE; i++)
|
||||||
{
|
{
|
||||||
pkt[i-8]=packet[i];
|
packet_in[i-8]=packet[i];
|
||||||
debug(" %02X",packet[i]);
|
debug(" %02X",packet[i]);
|
||||||
}
|
}
|
||||||
|
packet_in[29]=packet[0]; // 0xAA Normal telemetry, 0xAC Extended telemetry
|
||||||
telemetry_link=2;
|
telemetry_link=2;
|
||||||
debugln("");
|
debugln("");
|
||||||
return;
|
return;
|
||||||
@@ -119,7 +122,8 @@ static void AFHDS2A_update_telemetry()
|
|||||||
telemetry_link=1;
|
telemetry_link=1;
|
||||||
break;
|
break;
|
||||||
case AFHDS2A_SENSOR_RX_ERR_RATE:
|
case AFHDS2A_SENSOR_RX_ERR_RATE:
|
||||||
RX_LQI=packet[index+2];
|
if(packet[index+2]<=100)
|
||||||
|
RX_LQI=packet[index+2];
|
||||||
break;
|
break;
|
||||||
case AFHDS2A_SENSOR_RX_RSSI:
|
case AFHDS2A_SENSOR_RX_RSSI:
|
||||||
RX_RSSI = -packet[index+2];
|
RX_RSSI = -packet[index+2];
|
||||||
@@ -261,11 +265,15 @@ uint16_t ReadAFHDS2A()
|
|||||||
A7105_ReadData(AFHDS2A_RXPACKET_SIZE);
|
A7105_ReadData(AFHDS2A_RXPACKET_SIZE);
|
||||||
if(packet[0] == 0xbc && packet[9] == 0x01)
|
if(packet[0] == 0xbc && packet[9] == 0x01)
|
||||||
{
|
{
|
||||||
uint8_t temp=AFHDS2A_EEPROM_OFFSET+RX_num*4;
|
uint8_t addr;
|
||||||
|
if(RX_num<16)
|
||||||
|
addr=AFHDS2A_EEPROM_OFFSET+RX_num*4;
|
||||||
|
else
|
||||||
|
addr=AFHDS2A_EEPROM_OFFSET2+(RX_num-16)*4;
|
||||||
for(uint8_t i=0; i<4; i++)
|
for(uint8_t i=0; i<4; i++)
|
||||||
{
|
{
|
||||||
rx_id[i] = packet[5+i];
|
rx_id[i] = packet[5+i];
|
||||||
eeprom_write_byte((EE_ADDR)(temp+i),rx_id[i]);
|
eeprom_write_byte((EE_ADDR)(addr+i),rx_id[i]);
|
||||||
}
|
}
|
||||||
phase = AFHDS2A_BIND4;
|
phase = AFHDS2A_BIND4;
|
||||||
packet_count++;
|
packet_count++;
|
||||||
@@ -313,6 +321,9 @@ uint16_t ReadAFHDS2A()
|
|||||||
packet_type = AFHDS2A_PACKET_STICKS;
|
packet_type = AFHDS2A_PACKET_STICKS;
|
||||||
phase = AFHDS2A_DATA;
|
phase = AFHDS2A_DATA;
|
||||||
case AFHDS2A_DATA:
|
case AFHDS2A_DATA:
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(3850);
|
||||||
|
#endif
|
||||||
AFHDS2A_build_packet(packet_type);
|
AFHDS2A_build_packet(packet_type);
|
||||||
if((A7105_ReadReg(A7105_00_MODE) & 0x01)) // Check if something has been received...
|
if((A7105_ReadReg(A7105_00_MODE) & 0x01)) // Check if something has been received...
|
||||||
data_rx=0;
|
data_rx=0;
|
||||||
@@ -327,7 +338,10 @@ uint16_t ReadAFHDS2A()
|
|||||||
{
|
{
|
||||||
#ifdef FAILSAFE_ENABLE
|
#ifdef FAILSAFE_ENABLE
|
||||||
if(!(packet_counter % 1569) && IS_FAILSAFE_VALUES_on)
|
if(!(packet_counter % 1569) && IS_FAILSAFE_VALUES_on)
|
||||||
|
{
|
||||||
packet_type = AFHDS2A_PACKET_FAILSAFE;
|
packet_type = AFHDS2A_PACKET_FAILSAFE;
|
||||||
|
FAILSAFE_VALUES_off;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
packet_type = AFHDS2A_PACKET_STICKS; // todo : check for settings changes
|
packet_type = AFHDS2A_PACKET_STICKS; // todo : check for settings changes
|
||||||
@@ -341,13 +355,19 @@ uint16_t ReadAFHDS2A()
|
|||||||
if(packet[0] == 0xAA || packet[0] == 0xAC)
|
if(packet[0] == 0xAA || packet[0] == 0xAC)
|
||||||
{
|
{
|
||||||
if(!memcmp(&packet[1], rx_tx_addr, 4))
|
if(!memcmp(&packet[1], rx_tx_addr, 4))
|
||||||
{ // Validate TX address
|
{ // TX address validated
|
||||||
#ifdef AFHDS2A_LQI_CH
|
#ifdef AFHDS2A_LQI_CH
|
||||||
for(uint8_t sensor=0; sensor<7; sensor++)
|
if(packet[0]==0xAA && packet[9]!=0xFD)
|
||||||
{//read LQI value for RX output
|
{// Normal telemetry packet
|
||||||
uint8_t index = 9+(4*sensor);
|
for(uint8_t sensor=0; sensor<7; sensor++)
|
||||||
if(packet[index]==AFHDS2A_SENSOR_RX_ERR_RATE)
|
{//read LQI value for RX output
|
||||||
RX_LQI=packet[index+2];
|
uint8_t index = 9+(4*sensor);
|
||||||
|
if(packet[index]==AFHDS2A_SENSOR_RX_ERR_RATE && packet[index+2]<=100)
|
||||||
|
{
|
||||||
|
RX_LQI=packet[index+2];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if defined(AFHDS2A_FW_TELEMETRY) || defined(AFHDS2A_HUB_TELEMETRY)
|
#if defined(AFHDS2A_FW_TELEMETRY) || defined(AFHDS2A_HUB_TELEMETRY)
|
||||||
@@ -387,14 +407,15 @@ uint16_t initAFHDS2A()
|
|||||||
{
|
{
|
||||||
phase = AFHDS2A_DATA_INIT;
|
phase = AFHDS2A_DATA_INIT;
|
||||||
//Read RX ID from EEPROM based on RX_num, RX_num must be uniq for each RX
|
//Read RX ID from EEPROM based on RX_num, RX_num must be uniq for each RX
|
||||||
uint8_t temp=AFHDS2A_EEPROM_OFFSET+RX_num*4;
|
uint8_t addr;
|
||||||
|
if(RX_num<16)
|
||||||
|
addr=AFHDS2A_EEPROM_OFFSET+RX_num*4;
|
||||||
|
else
|
||||||
|
addr=AFHDS2A_EEPROM_OFFSET2+(RX_num-16)*4;
|
||||||
for(uint8_t i=0;i<4;i++)
|
for(uint8_t i=0;i<4;i++)
|
||||||
rx_id[i]=eeprom_read_byte((EE_ADDR)(temp+i));
|
rx_id[i]=eeprom_read_byte((EE_ADDR)(addr+i));
|
||||||
}
|
}
|
||||||
hopping_frequency_no = 0;
|
hopping_frequency_no = 0;
|
||||||
#if defined(AFHDS2A_FW_TELEMETRY) || defined(AFHDS2A_HUB_TELEMETRY)
|
|
||||||
init_frskyd_link_telemetry();
|
|
||||||
#endif
|
|
||||||
return 50000;
|
return 50000;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -127,6 +127,9 @@ uint16_t ASSAN_callback()
|
|||||||
phase=ASSAN_DATA2;
|
phase=ASSAN_DATA2;
|
||||||
return 2000;
|
return 2000;
|
||||||
case ASSAN_DATA2:
|
case ASSAN_DATA2:
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(12000);
|
||||||
|
#endif
|
||||||
case ASSAN_DATA3:
|
case ASSAN_DATA3:
|
||||||
ASSAN_send_packet();
|
ASSAN_send_packet();
|
||||||
phase++; // DATA 3 or 4
|
phase++; // DATA 3 or 4
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ static void __attribute__((unused)) BUGSMINI_make_address()
|
|||||||
uint8_t start, length, index;
|
uint8_t start, length, index;
|
||||||
|
|
||||||
//read rxid
|
//read rxid
|
||||||
uint8_t base_adr=BUGSMINI_EEPROM_OFFSET+RX_num*2;
|
uint8_t base_adr=BUGSMINI_EEPROM_OFFSET+(RX_num&0x0F)*2;
|
||||||
uint8_t rxid_high = eeprom_read_byte((EE_ADDR)(base_adr+0));
|
uint8_t rxid_high = eeprom_read_byte((EE_ADDR)(base_adr+0));
|
||||||
uint8_t rxid_low = eeprom_read_byte((EE_ADDR)(base_adr+1));
|
uint8_t rxid_low = eeprom_read_byte((EE_ADDR)(base_adr+1));
|
||||||
|
|
||||||
@@ -272,7 +272,7 @@ uint16_t BUGSMINI_callback()
|
|||||||
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR))
|
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR))
|
||||||
{ // RX fifo data ready
|
{ // RX fifo data ready
|
||||||
XN297_ReadPayload(packet, BUGSMINI_RX_PAYLOAD_SIZE);
|
XN297_ReadPayload(packet, BUGSMINI_RX_PAYLOAD_SIZE);
|
||||||
base_adr=BUGSMINI_EEPROM_OFFSET+RX_num*2;
|
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+0),packet[1]); // Save rxid in EEPROM
|
||||||
eeprom_write_byte((EE_ADDR)(base_adr+1),packet[2]); // Save rxid in EEPROM
|
eeprom_write_byte((EE_ADDR)(base_adr+1),packet[2]); // Save rxid in EEPROM
|
||||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||||
@@ -299,6 +299,9 @@ uint16_t BUGSMINI_callback()
|
|||||||
phase = BUGSMINI_BIND1;
|
phase = BUGSMINI_BIND1;
|
||||||
return BUGSMINI_PACKET_INTERVAL - BUGSMINI_WRITE_WAIT;
|
return BUGSMINI_PACKET_INTERVAL - BUGSMINI_WRITE_WAIT;
|
||||||
case BUGSMINI_DATA1:
|
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))
|
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
|
{ // RX fifo data ready => read only 12 bytes to not overwrite channel change flag
|
||||||
XN297_ReadPayload(packet, 12);
|
XN297_ReadPayload(packet, 12);
|
||||||
@@ -375,9 +378,6 @@ uint16_t initBUGSMINI()
|
|||||||
armed = 0;
|
armed = 0;
|
||||||
arm_flags = BUGSMINI_FLAG_DISARM; // initial value from captures
|
arm_flags = BUGSMINI_FLAG_DISARM; // initial value from captures
|
||||||
arm_channel_previous = BUGSMINI_CH_SW_ARM;
|
arm_channel_previous = BUGSMINI_CH_SW_ARM;
|
||||||
#ifdef BUGS_HUB_TELEMETRY
|
|
||||||
init_frskyd_link_telemetry();
|
|
||||||
#endif
|
|
||||||
return BUGSMINI_INITIAL_WAIT;
|
return BUGSMINI_INITIAL_WAIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
207
Multiprotocol/Bayang_Rx_nrf24l01.ino
Normal file
@@ -0,0 +1,207 @@
|
|||||||
|
/*
|
||||||
|
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(BAYANG_RX_NRF24L01_INO)
|
||||||
|
|
||||||
|
#include "iface_nrf24l01.h"
|
||||||
|
|
||||||
|
#define BAYANG_RX_PACKET_SIZE 15
|
||||||
|
#define BAYANG_RX_RF_NUM_CHANNELS 4
|
||||||
|
#define BAYANG_RX_RF_BIND_CHANNEL 0
|
||||||
|
#define BAYANG_RX_ADDRESS_LENGTH 5
|
||||||
|
|
||||||
|
enum {
|
||||||
|
BAYANG_RX_BIND = 0,
|
||||||
|
BAYANG_RX_DATA
|
||||||
|
};
|
||||||
|
|
||||||
|
static void __attribute__((unused)) Bayang_Rx_init_nrf24l01()
|
||||||
|
{
|
||||||
|
const uint8_t bind_address[BAYANG_RX_ADDRESS_LENGTH] = { 0,0,0,0,0 };
|
||||||
|
NRF24L01_Initialize();
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t __attribute__((unused)) Bayang_Rx_check_validity() {
|
||||||
|
uint8_t sum = packet[0];
|
||||||
|
for (uint8_t i = 1; i < BAYANG_RX_PACKET_SIZE - 1; i++)
|
||||||
|
sum += packet[i];
|
||||||
|
return sum == packet[14];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __attribute__((unused)) Bayang_Rx_build_telemetry_packet()
|
||||||
|
{
|
||||||
|
uint32_t bits = 0;
|
||||||
|
uint8_t bitsavailable = 0;
|
||||||
|
uint8_t idx = 0;
|
||||||
|
|
||||||
|
packet_in[idx++] = RX_LQI;
|
||||||
|
packet_in[idx++] = RX_LQI>>1; // no RSSI: 125..0
|
||||||
|
packet_in[idx++] = 0; // start channel
|
||||||
|
packet_in[idx++] = 10; // number of channels in packet
|
||||||
|
|
||||||
|
// convert & pack channels
|
||||||
|
for (uint8_t i = 0; i < packet_in[3]; i++) {
|
||||||
|
uint32_t val = CHANNEL_MIN_100;
|
||||||
|
if (i < 4) {
|
||||||
|
// AETR
|
||||||
|
//val = (((packet[4 + i * 2] & ~0x7C) << 8) | packet[5 + i * 2]) << 1;
|
||||||
|
val=packet[4 + i * 2]&0x03;
|
||||||
|
val=(val<<8)+packet[5 + i * 2];
|
||||||
|
val=((val+128)<<3)/5;
|
||||||
|
} else if (i == 4 || i == 5) {
|
||||||
|
val=packet[i==4?1:13];
|
||||||
|
val=((val+32)<<5)/5; // extra analog channel
|
||||||
|
} else if (((i == 6) && (packet[2] & 0x08)) || // flip
|
||||||
|
((i == 7) && (packet[2] & 0x01)) || // rth
|
||||||
|
((i == 8) && (packet[2] & 0x20)) || // picture
|
||||||
|
((i == 9) && (packet[2] & 0x10))) { // video
|
||||||
|
// set channel to 100% if feature is enabled
|
||||||
|
val = CHANNEL_MAX_100;
|
||||||
|
}
|
||||||
|
bits |= val << bitsavailable;
|
||||||
|
bitsavailable += 11;
|
||||||
|
while (bitsavailable >= 8) {
|
||||||
|
packet_in[idx++] = bits & 0xff;
|
||||||
|
bits >>= 8;
|
||||||
|
bitsavailable -= 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t initBayang_Rx()
|
||||||
|
{
|
||||||
|
uint8_t i;
|
||||||
|
Bayang_Rx_init_nrf24l01();
|
||||||
|
hopping_frequency_no = 0;
|
||||||
|
rx_data_started = false;
|
||||||
|
rx_data_received = false;
|
||||||
|
|
||||||
|
if (IS_BIND_IN_PROGRESS) {
|
||||||
|
phase = BAYANG_RX_BIND;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
uint16_t temp = BAYANG_RX_EEPROM_OFFSET;
|
||||||
|
for (i = 0; i < 5; i++)
|
||||||
|
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_SetTXAddr(rx_tx_addr, BAYANG_RX_ADDRESS_LENGTH);
|
||||||
|
XN297_SetRXAddr(rx_tx_addr, BAYANG_RX_ADDRESS_LENGTH);
|
||||||
|
phase = BAYANG_RX_DATA;
|
||||||
|
}
|
||||||
|
return 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t Bayang_Rx_callback()
|
||||||
|
{
|
||||||
|
uint8_t i;
|
||||||
|
static int8_t read_retry;
|
||||||
|
static uint16_t pps_counter;
|
||||||
|
static uint32_t pps_timer = 0;
|
||||||
|
|
||||||
|
switch (phase) {
|
||||||
|
case BAYANG_RX_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)
|
||||||
|
{
|
||||||
|
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
|
||||||
|
read_retry = -16; // retry longer until first packet is caught
|
||||||
|
}
|
||||||
|
return 250;
|
||||||
|
}
|
||||||
|
return 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -20,7 +20,8 @@ Multiprotocol is distributed in the hope that it will be useful,
|
|||||||
#include "iface_nrf24l01.h"
|
#include "iface_nrf24l01.h"
|
||||||
|
|
||||||
#define BAYANG_BIND_COUNT 1000
|
#define BAYANG_BIND_COUNT 1000
|
||||||
#define BAYANG_PACKET_PERIOD 1000
|
#define BAYANG_PACKET_PERIOD 2000
|
||||||
|
#define BAYANG_PACKET_TELEM_PERIOD 5000
|
||||||
#define BAYANG_INITIAL_WAIT 500
|
#define BAYANG_INITIAL_WAIT 500
|
||||||
#define BAYANG_PACKET_SIZE 15
|
#define BAYANG_PACKET_SIZE 15
|
||||||
#define BAYANG_RF_NUM_CHANNELS 4
|
#define BAYANG_RF_NUM_CHANNELS 4
|
||||||
@@ -46,10 +47,10 @@ enum BAYANG_OPTION_FLAGS {
|
|||||||
BAYANG_OPTION_FLAG_ANALOGAUX = 0x02,
|
BAYANG_OPTION_FLAG_ANALOGAUX = 0x02,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void __attribute__((unused)) BAYANG_send_packet(uint8_t bind)
|
static void __attribute__((unused)) BAYANG_send_packet()
|
||||||
{
|
{
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
if (bind)
|
if (IS_BIND_IN_PROGRESS)
|
||||||
{
|
{
|
||||||
#ifdef BAYANG_HUB_TELEMETRY
|
#ifdef BAYANG_HUB_TELEMETRY
|
||||||
if(option & BAYANG_OPTION_FLAG_TELEMETRY)
|
if(option & BAYANG_OPTION_FLAG_TELEMETRY)
|
||||||
@@ -186,29 +187,15 @@ static void __attribute__((unused)) BAYANG_send_packet(uint8_t bind)
|
|||||||
for (uint8_t i=0; i < BAYANG_PACKET_SIZE-1; i++)
|
for (uint8_t i=0; i < BAYANG_PACKET_SIZE-1; i++)
|
||||||
packet[14] += packet[i];
|
packet[14] += packet[i];
|
||||||
|
|
||||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, bind ? rf_ch_num:hopping_frequency[hopping_frequency_no++]);
|
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;
|
hopping_frequency_no%=BAYANG_RF_NUM_CHANNELS;
|
||||||
|
|
||||||
// clear packet status bits and TX FIFO
|
|
||||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
|
||||||
NRF24L01_FlushTx();
|
|
||||||
|
|
||||||
XN297_WritePayload(packet, BAYANG_PACKET_SIZE);
|
|
||||||
|
|
||||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
|
||||||
NRF24L01_SetTxRxMode(TX_EN);
|
|
||||||
|
|
||||||
// Power on, TX mode, 2byte CRC
|
// Power on, TX mode, 2byte CRC
|
||||||
// Why CRC0? xn297 does not interpret it - either 16-bit CRC or nothing
|
// 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));
|
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
||||||
|
XN297_WritePayload(packet, BAYANG_PACKET_SIZE);
|
||||||
#ifdef BAYANG_HUB_TELEMETRY
|
|
||||||
if (option & BAYANG_OPTION_FLAG_TELEMETRY)
|
|
||||||
{ // switch radio to rx as soon as packet is sent
|
|
||||||
while (!(NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_TX_DS)));
|
|
||||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, 0x03);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
NRF24L01_SetPower(); // Set tx_power
|
NRF24L01_SetPower(); // Set tx_power
|
||||||
}
|
}
|
||||||
@@ -233,7 +220,8 @@ static void __attribute__((unused)) BAYANG_check_rx(void)
|
|||||||
// compensated battery volts*100/2
|
// compensated battery volts*100/2
|
||||||
v_lipo2 = (packet[5]<<7) + (packet[6]>>2);
|
v_lipo2 = (packet[5]<<7) + (packet[6]>>2);
|
||||||
// reception in packets / sec
|
// reception in packets / sec
|
||||||
RX_RSSI = packet[7];
|
RX_LQI = packet[7];
|
||||||
|
RX_RSSI = RX_LQI;
|
||||||
//Flags
|
//Flags
|
||||||
//uint8_t flags = packet[3] >> 3;
|
//uint8_t flags = packet[3] >> 3;
|
||||||
// battery low: flags & 1
|
// battery low: flags & 1
|
||||||
@@ -242,6 +230,7 @@ static void __attribute__((unused)) BAYANG_check_rx(void)
|
|||||||
telemetry_link=1;
|
telemetry_link=1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -278,53 +267,73 @@ static void __attribute__((unused)) BAYANG_init()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum {
|
||||||
|
BAYANG_BIND=0,
|
||||||
|
BAYANG_WRITE,
|
||||||
|
BAYANG_CHECK,
|
||||||
|
BAYANG_READ,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define BAYANG_CHECK_DELAY 1000 // Time after write phase to check write complete
|
||||||
|
#define BAYANG_READ_DELAY 600 // Time before read phase
|
||||||
|
|
||||||
uint16_t BAYANG_callback()
|
uint16_t BAYANG_callback()
|
||||||
{
|
{
|
||||||
if(IS_BIND_DONE)
|
#ifdef BAYANG_HUB_TELEMETRY
|
||||||
|
uint16_t start;
|
||||||
|
#endif
|
||||||
|
switch(phase)
|
||||||
{
|
{
|
||||||
if(packet_count==0)
|
case BAYANG_BIND:
|
||||||
BAYANG_send_packet(0);
|
if (--bind_counter == 0)
|
||||||
packet_count++;
|
{
|
||||||
#ifdef BAYANG_HUB_TELEMETRY
|
XN297_SetTXAddr(rx_tx_addr, BAYANG_ADDRESS_LENGTH);
|
||||||
if (option & BAYANG_OPTION_FLAG_TELEMETRY)
|
#ifdef BAYANG_HUB_TELEMETRY
|
||||||
{ // telemetry is enabled
|
XN297_SetRXAddr(rx_tx_addr, BAYANG_ADDRESS_LENGTH);
|
||||||
state++;
|
#endif
|
||||||
if (state > 1000)
|
BIND_DONE;
|
||||||
{
|
phase++; //WRITE
|
||||||
//calculate telemetry reception packet rate - packets per 1000ms
|
|
||||||
TX_RSSI = telemetry_counter;
|
|
||||||
telemetry_counter = 0;
|
|
||||||
state = 0;
|
|
||||||
telemetry_lost=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (packet_count > 1)
|
|
||||||
BAYANG_check_rx();
|
|
||||||
|
|
||||||
packet_count %= 5;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
BAYANG_send_packet();
|
||||||
packet_count%=2;
|
break;
|
||||||
}
|
case BAYANG_WRITE:
|
||||||
else
|
#ifdef MULTI_SYNC
|
||||||
{
|
telemetry_set_input_sync((option & BAYANG_OPTION_FLAG_TELEMETRY)?BAYANG_PACKET_TELEM_PERIOD:BAYANG_PACKET_PERIOD);
|
||||||
if (bind_counter == 0)
|
|
||||||
{
|
|
||||||
XN297_SetTXAddr(rx_tx_addr, BAYANG_ADDRESS_LENGTH);
|
|
||||||
#ifdef BAYANG_HUB_TELEMETRY
|
|
||||||
XN297_SetRXAddr(rx_tx_addr, BAYANG_ADDRESS_LENGTH);
|
|
||||||
#endif
|
#endif
|
||||||
BIND_DONE;
|
BAYANG_send_packet();
|
||||||
}
|
#ifdef BAYANG_HUB_TELEMETRY
|
||||||
else
|
if (option & BAYANG_OPTION_FLAG_TELEMETRY)
|
||||||
{
|
{ // telemetry is enabled
|
||||||
if(packet_count==0)
|
state++;
|
||||||
BAYANG_send_packet(1);
|
if (state > 200)
|
||||||
packet_count++;
|
{
|
||||||
packet_count%=4;
|
state = 0;
|
||||||
bind_counter--;
|
//telemetry reception packet rate - packets per second
|
||||||
}
|
TX_LQI = telemetry_counter>>1;
|
||||||
|
telemetry_counter = 0;
|
||||||
|
telemetry_lost=0;
|
||||||
|
}
|
||||||
|
phase++; //CHECK
|
||||||
|
return BAYANG_CHECK_DELAY;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
#ifdef BAYANG_HUB_TELEMETRY
|
||||||
|
case BAYANG_CHECK:
|
||||||
|
// 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)))
|
||||||
|
break;
|
||||||
|
NRF24L01_WriteReg(NRF24L01_00_CONFIG, 0x03);
|
||||||
|
phase++; // READ
|
||||||
|
return BAYANG_PACKET_TELEM_PERIOD - BAYANG_CHECK_DELAY - BAYANG_READ_DELAY;
|
||||||
|
case BAYANG_READ:
|
||||||
|
BAYANG_check_rx();
|
||||||
|
phase=BAYANG_WRITE;
|
||||||
|
return BAYANG_READ_DELAY;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
return BAYANG_PACKET_PERIOD;
|
return BAYANG_PACKET_PERIOD;
|
||||||
}
|
}
|
||||||
@@ -345,14 +354,11 @@ static void __attribute__((unused)) BAYANG_initialize_txid()
|
|||||||
uint16_t initBAYANG(void)
|
uint16_t initBAYANG(void)
|
||||||
{
|
{
|
||||||
BIND_IN_PROGRESS; // autobind protocol
|
BIND_IN_PROGRESS; // autobind protocol
|
||||||
|
phase=BAYANG_BIND;
|
||||||
bind_counter = BAYANG_BIND_COUNT;
|
bind_counter = BAYANG_BIND_COUNT;
|
||||||
BAYANG_initialize_txid();
|
BAYANG_initialize_txid();
|
||||||
BAYANG_init();
|
BAYANG_init();
|
||||||
packet_count=0;
|
packet_count=0;
|
||||||
#ifdef BAYANG_HUB_TELEMETRY
|
|
||||||
init_frskyd_link_telemetry();
|
|
||||||
telemetry_lost=1; // do not send telemetry to TX right away until we have a TX_RSSI value to prevent warning message...
|
|
||||||
#endif
|
|
||||||
return BAYANG_INITIAL_WAIT+BAYANG_PACKET_PERIOD;
|
return BAYANG_INITIAL_WAIT+BAYANG_PACKET_PERIOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
184
Multiprotocol/Binary_Signature.ino
Normal file
@@ -0,0 +1,184 @@
|
|||||||
|
/*
|
||||||
|
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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/************************/
|
||||||
|
/** Firmware Signature **/
|
||||||
|
/************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
The firmware signature is appended to the compiled binary image in order to provide information
|
||||||
|
about the options used to compile the firmware file. This information is then used by Multi-module
|
||||||
|
flashing tools to verify that the image is correct / valid.
|
||||||
|
|
||||||
|
In order for the build process to determine the options used to build the firmware this file conditionally
|
||||||
|
declares 'flag' variables for the options we are interested in.
|
||||||
|
|
||||||
|
When the pre-compiler parses the source code these variables are either present or not in the parsed cpp file,
|
||||||
|
typically '$build_dir$/preproc/ctags_target_for_gcc_minus_e.cpp'.
|
||||||
|
|
||||||
|
Once the .bin file is created an additional command-line build tool scans the parsed cpp file, detects the
|
||||||
|
flags, assembles the signature, and finally appends the signature to the end of the binary file.
|
||||||
|
|
||||||
|
The signature is 24 bytes long:
|
||||||
|
multi-x[8-byte hex code]-[8-byte version number]
|
||||||
|
|
||||||
|
For example:
|
||||||
|
multi-x1234abcd-01020199
|
||||||
|
|
||||||
|
The 8-byte hex code is a 32-bit bitmask value indicating the configuration options, currently:
|
||||||
|
|
||||||
|
Bit(s) Bitmask Option Comment
|
||||||
|
1-2 0x3 Module type Read as a two-bit value indicating a number from 0-3 which maps to a module type (AVR, STM32, OrangeRX)
|
||||||
|
3-7 0x7C Channel order Read as a five-bit value indicating a number from 0-23 which maps to as channel order (AETR, TAER, RETA, etc) (right-shift two bits to read)
|
||||||
|
8 0x80 Bootloader support Indicates whether or not the firmware was built with support for the bootloader
|
||||||
|
9 0x100 CHECK_FOR_BOOTLOADER Indicates if CHECK_FOR_BOOTLOADER is defined
|
||||||
|
10 0x200 INVERT_TELEMETRY Indicates if INVERT_TELEMETRY is defined
|
||||||
|
11 0x400 MULTI_STATUS Indicates if MULTI_STATUS is defined
|
||||||
|
12 0x800 MULTI_TELEMETRY Indicates if MULTI_TELEMETRY is defined
|
||||||
|
13 0x1000 DEBUG_SERIAL Indicates if DEBUG_SERIAL is defined
|
||||||
|
|
||||||
|
The 8-byte version number is the version number zero-padded to a fixed width of two-bytes per segment and no separator.
|
||||||
|
E.g. 1.2.3.45 becomes 01020345.
|
||||||
|
|
||||||
|
Multi Telemetery Type can be read from bits 11 and 12 using the bitmask 0xC00 and right-shifting ten bits:
|
||||||
|
Telemetry Type Decimal Value Binary Value
|
||||||
|
Undefined 0 00
|
||||||
|
erSkyTX 1 01
|
||||||
|
OpenTX 2 10
|
||||||
|
|
||||||
|
Module types are mapped to the following decimal / binary values:
|
||||||
|
Module Type Decimal Value Binary Valsue
|
||||||
|
AVR 0 00
|
||||||
|
STM32 1 01
|
||||||
|
OrangeRX 2 10
|
||||||
|
|
||||||
|
Channel orders are mapped to the following decimal / binary values:
|
||||||
|
Channel Order Decimal Value Binary Value
|
||||||
|
AETR 0 00000
|
||||||
|
AERT 1 00001
|
||||||
|
ARET 2 00010
|
||||||
|
ARTE 3 00011
|
||||||
|
ATRE 4 00100
|
||||||
|
ATER 5 00101
|
||||||
|
EATR 6 00110
|
||||||
|
EART 7 00111
|
||||||
|
ERAT 8 01000
|
||||||
|
ERTA 9 01001
|
||||||
|
ETRA 10 01010
|
||||||
|
ETAR 11 01011
|
||||||
|
TEAR 12 01100
|
||||||
|
TERA 13 01101
|
||||||
|
TREA 14 01110
|
||||||
|
TRAE 15 01111
|
||||||
|
TARE 16 10000
|
||||||
|
TAER 17 10001
|
||||||
|
RETA 18 10010
|
||||||
|
REAT 19 10011
|
||||||
|
RAET 20 10100
|
||||||
|
RATE 21 10101
|
||||||
|
RTAE 22 10110
|
||||||
|
RTEA 23 10111
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Set the flags for detecting and writing the firmware signature
|
||||||
|
#if defined (CHECK_FOR_BOOTLOADER)
|
||||||
|
bool firmwareFlag_CHECK_FOR_BOOTLOADER = true;
|
||||||
|
#endif
|
||||||
|
#if defined (INVERT_TELEMETRY)
|
||||||
|
bool firmwareFlag_INVERT_TELEMETRY = true;
|
||||||
|
#endif
|
||||||
|
#if defined (MULTI_STATUS)
|
||||||
|
bool firmwareFlag_MULTI_STATUS = true;
|
||||||
|
#endif
|
||||||
|
#if defined (MULTI_TELEMETRY)
|
||||||
|
bool firmwareFlag_MULTI_TELEMETRY = true;
|
||||||
|
#endif
|
||||||
|
#if defined (DEBUG_SERIAL)
|
||||||
|
bool firmwareFlag_DEBUG_SERIAL = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Channel order flags
|
||||||
|
#if defined (AETR)
|
||||||
|
bool firmwareFlag_ChannelOrder_AETR = true;
|
||||||
|
#endif
|
||||||
|
#if defined (AERT)
|
||||||
|
bool firmwareFlag_ChannelOrder_AERT = true;
|
||||||
|
#endif
|
||||||
|
#if defined (ARET)
|
||||||
|
bool firmwareFlag_ChannelOrder_ARET = true;
|
||||||
|
#endif
|
||||||
|
#if defined (ARTE)
|
||||||
|
bool firmwareFlag_ChannelOrder_ARTE = true;
|
||||||
|
#endif
|
||||||
|
#if defined (ATRE)
|
||||||
|
bool firmwareFlag_ChannelOrder_ATRE = true;
|
||||||
|
#endif
|
||||||
|
#if defined (ATER)
|
||||||
|
bool firmwareFlag_ChannelOrder_ATER = true;
|
||||||
|
#endif
|
||||||
|
#if defined (EATR)
|
||||||
|
bool firmwareFlag_ChannelOrder_EATR = true;
|
||||||
|
#endif
|
||||||
|
#if defined (EART)
|
||||||
|
bool firmwareFlag_ChannelOrder_EART = true;
|
||||||
|
#endif
|
||||||
|
#if defined (ERAT)
|
||||||
|
bool firmwareFlag_ChannelOrder_ERAT = true;
|
||||||
|
#endif
|
||||||
|
#if defined (ERTA)
|
||||||
|
bool firmwareFlag_ChannelOrder_ERTA = true;
|
||||||
|
#endif
|
||||||
|
#if defined (ETRA)
|
||||||
|
bool firmwareFlag_ChannelOrder_ETRA = true;
|
||||||
|
#endif
|
||||||
|
#if defined (ETAR)
|
||||||
|
bool firmwareFlag_ChannelOrder_ETAR = true;
|
||||||
|
#endif
|
||||||
|
#if defined (TEAR)
|
||||||
|
bool firmwareFlag_ChannelOrder_TEAR = true;
|
||||||
|
#endif
|
||||||
|
#if defined (TERA)
|
||||||
|
bool firmwareFlag_ChannelOrder_TERA = true;
|
||||||
|
#endif
|
||||||
|
#if defined (TREA)
|
||||||
|
bool firmwareFlag_ChannelOrder_TREA = true;
|
||||||
|
#endif
|
||||||
|
#if defined (TRAE)
|
||||||
|
bool firmwareFlag_ChannelOrder_TRAE = true;
|
||||||
|
#endif
|
||||||
|
#if defined (TARE)
|
||||||
|
bool firmwareFlag_ChannelOrder_TARE = true;
|
||||||
|
#endif
|
||||||
|
#if defined (TAER)
|
||||||
|
bool firmwareFlag_ChannelOrder_TAER = true;
|
||||||
|
#endif
|
||||||
|
#if defined (RETA)
|
||||||
|
bool firmwareFlag_ChannelOrder_RETA = true;
|
||||||
|
#endif
|
||||||
|
#if defined (REAT)
|
||||||
|
bool firmwareFlag_ChannelOrder_REAT = true;
|
||||||
|
#endif
|
||||||
|
#if defined (RAET)
|
||||||
|
bool firmwareFlag_ChannelOrder_RAET = true;
|
||||||
|
#endif
|
||||||
|
#if defined (RATE)
|
||||||
|
bool firmwareFlag_ChannelOrder_RATE = true;
|
||||||
|
#endif
|
||||||
|
#if defined (RTAE)
|
||||||
|
bool firmwareFlag_ChannelOrder_RTAE = true;
|
||||||
|
#endif
|
||||||
|
#if defined (RTEA)
|
||||||
|
bool firmwareFlag_ChannelOrder_RTEA = true;
|
||||||
|
#endif
|
||||||
@@ -284,7 +284,7 @@ static void __attribute__((unused))BUGS_set_radio_data()
|
|||||||
{
|
{
|
||||||
offset=BUGS_NUM_RFCHAN;
|
offset=BUGS_NUM_RFCHAN;
|
||||||
// Read radio_id from EEPROM
|
// Read radio_id from EEPROM
|
||||||
uint8_t base_adr=BUGS_EEPROM_OFFSET+RX_num*2;
|
uint8_t base_adr=BUGS_EEPROM_OFFSET+(RX_num&0x0F)*2;
|
||||||
uint16_t rxid=0;
|
uint16_t rxid=0;
|
||||||
for(uint8_t i=0; i<2; i++)
|
for(uint8_t i=0; i<2; i++)
|
||||||
rxid|=eeprom_read_byte((EE_ADDR)(base_adr+i))<<(i*8);
|
rxid|=eeprom_read_byte((EE_ADDR)(base_adr+i))<<(i*8);
|
||||||
@@ -374,7 +374,7 @@ uint16_t ReadBUGS(void)
|
|||||||
BIND_DONE;
|
BIND_DONE;
|
||||||
// set radio_id
|
// set radio_id
|
||||||
rxid = (packet[1] << 8) + packet[2];
|
rxid = (packet[1] << 8) + packet[2];
|
||||||
base_adr=BUGS_EEPROM_OFFSET+RX_num*2;
|
base_adr=BUGS_EEPROM_OFFSET+(RX_num&0x0F)*2;
|
||||||
for(uint8_t i=0; i<2; i++)
|
for(uint8_t i=0; i<2; i++)
|
||||||
eeprom_write_byte((EE_ADDR)(base_adr+i),rxid>>(i*8)); // Save rxid in EEPROM
|
eeprom_write_byte((EE_ADDR)(base_adr+i),rxid>>(i*8)); // Save rxid in EEPROM
|
||||||
BUGS_set_radio_data();
|
BUGS_set_radio_data();
|
||||||
@@ -385,6 +385,9 @@ uint16_t ReadBUGS(void)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case BUGS_DATA_1:
|
case BUGS_DATA_1:
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(BUGS_PACKET_PERIOD);
|
||||||
|
#endif
|
||||||
A7105_SetPower();
|
A7105_SetPower();
|
||||||
BUGS_build_packet(0);
|
BUGS_build_packet(0);
|
||||||
A7105_WriteReg(A7105_03_FIFOI, BUGS_FIFO_SIZE_TX);
|
A7105_WriteReg(A7105_03_FIFOI, BUGS_FIFO_SIZE_TX);
|
||||||
@@ -437,7 +440,7 @@ uint16_t ReadBUGS(void)
|
|||||||
uint16_t initBUGS(void)
|
uint16_t initBUGS(void)
|
||||||
{
|
{
|
||||||
uint16_t rxid=0;
|
uint16_t rxid=0;
|
||||||
uint8_t base_adr=BUGS_EEPROM_OFFSET+RX_num*2;
|
uint8_t base_adr=BUGS_EEPROM_OFFSET+(RX_num&0x0F)*2;
|
||||||
for(uint8_t i=0; i<2; i++)
|
for(uint8_t i=0; i<2; i++)
|
||||||
rxid|=eeprom_read_byte((EE_ADDR)(base_adr+i))<<(i*8);
|
rxid|=eeprom_read_byte((EE_ADDR)(base_adr+i))<<(i*8);
|
||||||
if(rxid==0xffff)
|
if(rxid==0xffff)
|
||||||
@@ -456,9 +459,6 @@ uint16_t initBUGS(void)
|
|||||||
armed = 0;
|
armed = 0;
|
||||||
arm_flags = BUGS_FLAG_DISARM; // initial value from captures
|
arm_flags = BUGS_FLAG_DISARM; // initial value from captures
|
||||||
arm_channel_previous = BUGS_CH_SW_ARM;
|
arm_channel_previous = BUGS_CH_SW_ARM;
|
||||||
#ifdef BUGS_HUB_TELEMETRY
|
|
||||||
init_frskyd_link_telemetry();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return 10000;
|
return 10000;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -406,9 +406,12 @@ uint16_t CABELL_callback()
|
|||||||
if (IS_BIND_DONE)
|
if (IS_BIND_DONE)
|
||||||
{
|
{
|
||||||
CABELL_send_packet(0); // packet_period is set/adjusted in CABELL_send_packet
|
CABELL_send_packet(0); // packet_period is set/adjusted in CABELL_send_packet
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(packet_period);
|
||||||
|
#endif
|
||||||
return packet_period;
|
return packet_period;
|
||||||
}
|
}
|
||||||
if (bind_counter == 0)
|
else if (bind_counter == 0)
|
||||||
{
|
{
|
||||||
BIND_DONE;
|
BIND_DONE;
|
||||||
CABELL_init(); // non-bind address
|
CABELL_init(); // non-bind address
|
||||||
@@ -429,10 +432,6 @@ uint16_t initCABELL(void)
|
|||||||
else
|
else
|
||||||
bind_counter = CABELL_BIND_COUNT;
|
bind_counter = CABELL_BIND_COUNT;
|
||||||
CABELL_init();
|
CABELL_init();
|
||||||
#if defined CABELL_HUB_TELEMETRY
|
|
||||||
init_frskyd_link_telemetry();
|
|
||||||
telemetry_lost=1; // do not send telemetry to TX right away until we have a TX_RSSI value to prevent warning message...
|
|
||||||
#endif
|
|
||||||
|
|
||||||
packet_period = CABELL_PACKET_PERIOD;
|
packet_period = CABELL_PACKET_PERIOD;
|
||||||
|
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ static inline uint8_t crtp_create_header(uint8_t port, uint8_t channel)
|
|||||||
#define TX_ADDR_SIZE 5
|
#define TX_ADDR_SIZE 5
|
||||||
|
|
||||||
// Timeout for callback in uSec, 10ms=10000us for Crazyflie
|
// Timeout for callback in uSec, 10ms=10000us for Crazyflie
|
||||||
#define PACKET_PERIOD 10000
|
#define CFLIE_PACKET_PERIOD 10000
|
||||||
|
|
||||||
#define MAX_PACKET_SIZE 32 // CRTP is 32 bytes
|
#define MAX_PACKET_SIZE 32 // CRTP is 32 bytes
|
||||||
|
|
||||||
@@ -781,7 +781,10 @@ static uint16_t cflie_callback()
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case CFLIE_DATA:
|
case CFLIE_DATA:
|
||||||
// if (Model.proto_opts[PROTOOPTS_TELEMETRY] == TELEM_ON_CRTPLOG) {
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(CFLIE_PACKET_PERIOD);
|
||||||
|
#endif
|
||||||
|
// if (Model.proto_opts[PROTOOPTS_TELEMETRY] == TELEM_ON_CRTPLOG) {
|
||||||
// update_telemetry_crtplog();
|
// update_telemetry_crtplog();
|
||||||
// } else if (Model.proto_opts[PROTOOPTS_TELEMETRY] == TELEM_ON_ACKPKT) {
|
// } else if (Model.proto_opts[PROTOOPTS_TELEMETRY] == TELEM_ON_ACKPKT) {
|
||||||
// update_telemetry_ackpkt();
|
// update_telemetry_ackpkt();
|
||||||
@@ -792,7 +795,7 @@ static uint16_t cflie_callback()
|
|||||||
send_cmd_packet();
|
send_cmd_packet();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return PACKET_PERIOD; // Packet at standard protocol interval
|
return CFLIE_PACKET_PERIOD; // Packet at standard protocol interval
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate address to use from TX id and manufacturer id (STM32 unique id)
|
// Generate address to use from TX id and manufacturer id (STM32 unique id)
|
||||||
|
|||||||
@@ -138,7 +138,12 @@ static void __attribute__((unused)) CG023_init()
|
|||||||
uint16_t CG023_callback()
|
uint16_t CG023_callback()
|
||||||
{
|
{
|
||||||
if(IS_BIND_DONE)
|
if(IS_BIND_DONE)
|
||||||
|
{
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(packet_period);
|
||||||
|
#endif
|
||||||
CG023_send_packet(0);
|
CG023_send_packet(0);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (bind_counter == 0)
|
if (bind_counter == 0)
|
||||||
|
|||||||
@@ -229,6 +229,9 @@ uint16_t CX10_callback()
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CX10_DATA:
|
case CX10_DATA:
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(packet_period);
|
||||||
|
#endif
|
||||||
CX10_Write_Packet(0);
|
CX10_Write_Packet(0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
164
Multiprotocol/Convert.ino
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
/*
|
||||||
|
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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/************************/
|
||||||
|
/** Convert routines **/
|
||||||
|
/************************/
|
||||||
|
// Reverse a channel and store it
|
||||||
|
void reverse_channel(uint8_t num)
|
||||||
|
{
|
||||||
|
uint16_t val=2048-Channel_data[num];
|
||||||
|
if(val>=2048) val=2047;
|
||||||
|
Channel_data[num]=val;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Channel value is converted to ppm 860<->2140 -125%<->+125% and 988<->2012 -100%<->+100%
|
||||||
|
uint16_t convert_channel_ppm(uint8_t num)
|
||||||
|
{
|
||||||
|
uint16_t val=Channel_data[num];
|
||||||
|
return (((val<<2)+val)>>3)+860; //value range 860<->2140 -125%<->+125%
|
||||||
|
}
|
||||||
|
|
||||||
|
// Channel value 100% is converted to 10bit values 0<->1023
|
||||||
|
uint16_t convert_channel_10b(uint8_t num)
|
||||||
|
{
|
||||||
|
uint16_t val=Channel_data[num];
|
||||||
|
val=((val<<2)+val)>>3;
|
||||||
|
if(val<=128) return 0;
|
||||||
|
if(val>=1152) return 1023;
|
||||||
|
return val-128;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Channel value 100% is converted to 8bit values 0<->255
|
||||||
|
uint8_t convert_channel_8b(uint8_t num)
|
||||||
|
{
|
||||||
|
uint16_t val=Channel_data[num];
|
||||||
|
val=((val<<2)+val)>>5;
|
||||||
|
if(val<=32) return 0;
|
||||||
|
if(val>=288) return 255;
|
||||||
|
return val-32;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Channel value 100% is converted to 8b with deadband
|
||||||
|
uint8_t convert_channel_8b_limit_deadband(uint8_t num,uint8_t min,uint8_t mid, uint8_t max, uint8_t deadband)
|
||||||
|
{
|
||||||
|
uint16_t val=limit_channel_100(num); // 204<->1844
|
||||||
|
uint16_t db_low=CHANNEL_MID-deadband, db_high=CHANNEL_MID+deadband; // 1024+-deadband
|
||||||
|
int32_t calc;
|
||||||
|
uint8_t out;
|
||||||
|
if(val>=db_low && val<=db_high)
|
||||||
|
return mid;
|
||||||
|
else if(val<db_low)
|
||||||
|
{
|
||||||
|
val-=CHANNEL_MIN_100;
|
||||||
|
calc=mid-min;
|
||||||
|
calc*=val;
|
||||||
|
calc/=(db_low-CHANNEL_MIN_100);
|
||||||
|
out=calc;
|
||||||
|
out+=min;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
val-=db_high;
|
||||||
|
calc=max-mid;
|
||||||
|
calc*=val;
|
||||||
|
calc/=(CHANNEL_MAX_100-db_high+1);
|
||||||
|
out=calc;
|
||||||
|
out+=mid;
|
||||||
|
if(max>min) out++; else out--;
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Channel value 100% is converted to value scaled
|
||||||
|
int16_t convert_channel_16b_limit(uint8_t num,int16_t min,int16_t max)
|
||||||
|
{
|
||||||
|
int32_t val=limit_channel_100(num); // 204<->1844
|
||||||
|
val=(val-CHANNEL_MIN_100)*(max-min)/(CHANNEL_MAX_100-CHANNEL_MIN_100)+min;
|
||||||
|
return (uint16_t)val;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Channel value -125%<->125% is scaled to 16bit value with no limit
|
||||||
|
int16_t convert_channel_16b_nolimit(uint8_t num, int16_t min, int16_t max)
|
||||||
|
{
|
||||||
|
int32_t val=Channel_data[num]; // 0<->2047
|
||||||
|
val=(val-CHANNEL_MIN_100)*(max-min)/(CHANNEL_MAX_100-CHANNEL_MIN_100)+min;
|
||||||
|
return (uint16_t)val;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Channel value is converted sign + magnitude 8bit values
|
||||||
|
uint8_t convert_channel_s8b(uint8_t num)
|
||||||
|
{
|
||||||
|
uint8_t ch;
|
||||||
|
ch = convert_channel_8b(num);
|
||||||
|
return (ch < 128 ? 127-ch : ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Channel value is limited to 100%
|
||||||
|
uint16_t limit_channel_100(uint8_t num)
|
||||||
|
{
|
||||||
|
if(Channel_data[num]>=CHANNEL_MAX_100)
|
||||||
|
return CHANNEL_MAX_100;
|
||||||
|
if (Channel_data[num]<=CHANNEL_MIN_100)
|
||||||
|
return CHANNEL_MIN_100;
|
||||||
|
return Channel_data[num];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Channel value is converted for HK310
|
||||||
|
void convert_channel_HK310(uint8_t num, uint8_t *low, uint8_t *high)
|
||||||
|
{
|
||||||
|
uint16_t temp=0xFFFF-(3440+((Channel_data[num]*5)>>1))/3;
|
||||||
|
*low=(uint8_t)(temp&0xFF);
|
||||||
|
*high=(uint8_t)(temp>>8);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef FAILSAFE_ENABLE
|
||||||
|
// Failsafe value is converted for HK310
|
||||||
|
void convert_failsafe_HK310(uint8_t num, uint8_t *low, uint8_t *high)
|
||||||
|
{
|
||||||
|
uint16_t temp=0xFFFF-(3440+((Failsafe_data[num]*5)>>1))/3;
|
||||||
|
*low=(uint8_t)(temp&0xFF);
|
||||||
|
*high=(uint8_t)(temp>>8);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Channel value for FrSky (PPM is multiplied by 1.5)
|
||||||
|
uint16_t convert_channel_frsky(uint8_t num)
|
||||||
|
{
|
||||||
|
uint16_t val=Channel_data[num];
|
||||||
|
return ((val*15)>>4)+1290;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 0-2047, 0 = 817, 1024 = 1500, 2047 = 2182
|
||||||
|
//64=860,1024=1500,1984=2140//Taranis 125%
|
||||||
|
static uint16_t __attribute__((unused)) FrSkyX_scaleForPXX( uint8_t i )
|
||||||
|
{ //mapped 860,2140(125%) range to 64,1984(PXX values);
|
||||||
|
uint16_t chan_val=convert_channel_frsky(i)-1226;
|
||||||
|
if(i>7) chan_val|=2048; // upper channels offset
|
||||||
|
return chan_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef FAILSAFE_ENABLE
|
||||||
|
static uint16_t __attribute__((unused)) FrSkyX_scaleForPXX_FS( uint8_t i )
|
||||||
|
{ //mapped 1,2046(125%) range to 64,1984(PXX values);
|
||||||
|
uint16_t chan_val=((Failsafe_data[i]*15)>>4)+64;
|
||||||
|
if(Failsafe_data[i]==FAILSAFE_CHANNEL_NOPULSES)
|
||||||
|
chan_val=FAILSAFE_CHANNEL_NOPULSES;
|
||||||
|
else if(Failsafe_data[i]==FAILSAFE_CHANNEL_HOLD)
|
||||||
|
chan_val=FAILSAFE_CHANNEL_HOLD;
|
||||||
|
if(i>7) chan_val|=2048; // upper channels offset
|
||||||
|
return chan_val;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -258,6 +258,9 @@ static uint16_t __attribute__((unused)) CORONA_build_packet()
|
|||||||
|
|
||||||
uint16_t ReadCORONA()
|
uint16_t ReadCORONA()
|
||||||
{
|
{
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(22000);
|
||||||
|
#endif
|
||||||
// Tune frequency if it has been changed
|
// Tune frequency if it has been changed
|
||||||
if ( prev_option != option )
|
if ( prev_option != option )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -113,7 +113,12 @@ static void __attribute__((unused)) DM002_init()
|
|||||||
uint16_t DM002_callback()
|
uint16_t DM002_callback()
|
||||||
{
|
{
|
||||||
if(IS_BIND_DONE)
|
if(IS_BIND_DONE)
|
||||||
|
{
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(DM002_PACKET_PERIOD);
|
||||||
|
#endif
|
||||||
DM002_send_packet(0);
|
DM002_send_packet(0);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (bind_counter == 0)
|
if (bind_counter == 0)
|
||||||
|
|||||||
@@ -230,7 +230,7 @@ static void __attribute__((unused)) DSM_update_channels()
|
|||||||
if(sub_protocol==DSM_AUTO)
|
if(sub_protocol==DSM_AUTO)
|
||||||
num_ch=12; // Force 12 channels in mode Auto
|
num_ch=12; // Force 12 channels in mode Auto
|
||||||
else
|
else
|
||||||
num_ch=option;
|
num_ch=option & 0x7F; // Remove the Max Throw flag
|
||||||
if(num_ch<4 || num_ch>12)
|
if(num_ch<4 || num_ch>12)
|
||||||
num_ch=6; // Default to 6 channels if invalid choice...
|
num_ch=6; // Default to 6 channels if invalid choice...
|
||||||
|
|
||||||
@@ -273,8 +273,8 @@ static void __attribute__((unused)) DSM_build_data_packet(uint8_t upper)
|
|||||||
/* Spektrum own remotes transmit normal values during bind and actually use this (e.g. Nano CP X) to
|
/* Spektrum own remotes transmit normal values during bind and actually use this (e.g. Nano CP X) to
|
||||||
select the transmitter mode (e.g. computer vs non-computer radio), so always send normal output */
|
select the transmitter mode (e.g. computer vs non-computer radio), so always send normal output */
|
||||||
#ifdef DSM_THROTTLE_KILL_CH
|
#ifdef DSM_THROTTLE_KILL_CH
|
||||||
if(CH_TAER[idx]==THROTTLE && kill_ch<=604)
|
if(idx==CH1 && kill_ch<=604)
|
||||||
{//Activate throttle kill only if DSM_THROTTLE_KILL_CH below -50%
|
{//Activate throttle kill only if channel is throttle and DSM_THROTTLE_KILL_CH below -50%
|
||||||
if(kill_ch<CHANNEL_MIN_100) // restrict val to 0...400
|
if(kill_ch<CHANNEL_MIN_100) // restrict val to 0...400
|
||||||
kill_ch=0;
|
kill_ch=0;
|
||||||
else
|
else
|
||||||
@@ -286,7 +286,10 @@ static void __attribute__((unused)) DSM_build_data_packet(uint8_t upper)
|
|||||||
#ifdef DSM_MAX_THROW
|
#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
|
#else
|
||||||
value=convert_channel_16b_nolimit(CH_TAER[idx],0x150,0x6B0); // -100%..+100% => 1100..1900us and -125%..+125% => 1000..2000us based on Redcon 6 channel DSM2 RX
|
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
|
||||||
|
else
|
||||||
|
value=convert_channel_16b_nolimit(CH_TAER[idx],0x150,0x6B0); // -100%..+100% => 1100..1900us and -125%..+125% => 1000..2000us based on Redcon 6 channel DSM2 RX
|
||||||
#endif
|
#endif
|
||||||
if(bits==10) value>>=1;
|
if(bits==10) value>>=1;
|
||||||
value |= (upper && i==0 ? 0x8000 : 0) | (idx << bits);
|
value |= (upper && i==0 ? 0x8000 : 0) | (idx << bits);
|
||||||
@@ -363,12 +366,12 @@ static uint8_t __attribute__((unused)) DSM_Check_RX_packet()
|
|||||||
uint16_t sum = 384 - 0x10;
|
uint16_t sum = 384 - 0x10;
|
||||||
for(uint8_t i = 1; i < 9; i++)
|
for(uint8_t i = 1; i < 9; i++)
|
||||||
{
|
{
|
||||||
sum += pkt[i];
|
sum += packet_in[i];
|
||||||
if(i<5)
|
if(i<5)
|
||||||
if(pkt[i] != (0xff ^ cyrfmfg_id[i-1]))
|
if(packet_in[i] != (0xff ^ cyrfmfg_id[i-1]))
|
||||||
result=0; // bad packet
|
result=0; // bad packet
|
||||||
}
|
}
|
||||||
if( pkt[9] != (sum>>8) && pkt[10] != (uint8_t)sum )
|
if( packet_in[9] != (sum>>8) && packet_in[10] != (uint8_t)sum )
|
||||||
result=0;
|
result=0;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -377,7 +380,7 @@ uint16_t ReadDsm()
|
|||||||
{
|
{
|
||||||
#define DSM_CH1_CH2_DELAY 4010 // Time between write of channel 1 and channel 2
|
#define DSM_CH1_CH2_DELAY 4010 // Time between write of channel 1 and channel 2
|
||||||
#ifdef STM32_BOARD
|
#ifdef STM32_BOARD
|
||||||
#define DSM_WRITE_DELAY 1500 // Time after write to verify write complete
|
#define DSM_WRITE_DELAY 1600 // Time after write to verify write complete
|
||||||
#else
|
#else
|
||||||
#define DSM_WRITE_DELAY 1950 // Time after write to verify write complete
|
#define DSM_WRITE_DELAY 1950 // Time after write to verify write complete
|
||||||
#endif
|
#endif
|
||||||
@@ -417,12 +420,12 @@ uint16_t ReadDsm()
|
|||||||
{ // data received with no errors
|
{ // data received with no errors
|
||||||
CYRF_WriteRegister(CYRF_07_RX_IRQ_STATUS, 0x80); // need to set RXOW before data read
|
CYRF_WriteRegister(CYRF_07_RX_IRQ_STATUS, 0x80); // need to set RXOW before data read
|
||||||
len=CYRF_ReadRegister(CYRF_09_RX_COUNT);
|
len=CYRF_ReadRegister(CYRF_09_RX_COUNT);
|
||||||
if(len>MAX_PKT-2)
|
if(len>TELEMETRY_BUFFER_SIZE-2)
|
||||||
len=MAX_PKT-2;
|
len=TELEMETRY_BUFFER_SIZE-2;
|
||||||
CYRF_ReadDataPacketLen(pkt+1, len);
|
CYRF_ReadDataPacketLen(packet_in+1, len);
|
||||||
if(len==10 && DSM_Check_RX_packet())
|
if(len==10 && DSM_Check_RX_packet())
|
||||||
{
|
{
|
||||||
pkt[0]=0x80;
|
packet_in[0]=0x80;
|
||||||
telemetry_link=1; // send received data on serial
|
telemetry_link=1; // send received data on serial
|
||||||
phase++;
|
phase++;
|
||||||
return 2000;
|
return 2000;
|
||||||
@@ -452,6 +455,9 @@ uint16_t ReadDsm()
|
|||||||
DSM_set_sop_data_crc();
|
DSM_set_sop_data_crc();
|
||||||
return 10000;
|
return 10000;
|
||||||
case DSM_CH1_WRITE_A:
|
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
|
||||||
|
#endif
|
||||||
case DSM_CH1_WRITE_B:
|
case DSM_CH1_WRITE_B:
|
||||||
case DSM_CH2_WRITE_A:
|
case DSM_CH2_WRITE_A:
|
||||||
case DSM_CH2_WRITE_B:
|
case DSM_CH2_WRITE_B:
|
||||||
@@ -502,10 +508,10 @@ uint16_t ReadDsm()
|
|||||||
{ // good data (complete with no errors)
|
{ // good data (complete with no errors)
|
||||||
CYRF_WriteRegister(CYRF_07_RX_IRQ_STATUS, 0x80); // need to set RXOW before data read
|
CYRF_WriteRegister(CYRF_07_RX_IRQ_STATUS, 0x80); // need to set RXOW before data read
|
||||||
len=CYRF_ReadRegister(CYRF_09_RX_COUNT);
|
len=CYRF_ReadRegister(CYRF_09_RX_COUNT);
|
||||||
if(len>MAX_PKT-2)
|
if(len>TELEMETRY_BUFFER_SIZE-2)
|
||||||
len=MAX_PKT-2;
|
len=TELEMETRY_BUFFER_SIZE-2;
|
||||||
CYRF_ReadDataPacketLen(pkt+1, len);
|
CYRF_ReadDataPacketLen(packet_in+1, len);
|
||||||
pkt[0]=CYRF_ReadRegister(CYRF_13_RSSI)&0x1F;// store RSSI of the received telemetry signal
|
packet_in[0]=CYRF_ReadRegister(CYRF_13_RSSI)&0x1F;// store RSSI of the received telemetry signal
|
||||||
telemetry_link=1;
|
telemetry_link=1;
|
||||||
}
|
}
|
||||||
CYRF_WriteRegister(CYRF_29_RX_ABORT, 0x20); // Abort RX operation
|
CYRF_WriteRegister(CYRF_29_RX_ABORT, 0x20); // Abort RX operation
|
||||||
|
|||||||
@@ -272,6 +272,9 @@ uint16_t devo_callback()
|
|||||||
static uint8_t txState=0;
|
static uint8_t txState=0;
|
||||||
if (txState == 0)
|
if (txState == 0)
|
||||||
{
|
{
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(2400);
|
||||||
|
#endif
|
||||||
txState = 1;
|
txState = 1;
|
||||||
DEVO_BuildPacket();
|
DEVO_BuildPacket();
|
||||||
CYRF_WriteDataPacket(packet);
|
CYRF_WriteDataPacket(packet);
|
||||||
|
|||||||
@@ -287,7 +287,12 @@ uint16_t E01X_callback()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(packet_period);
|
||||||
|
#endif
|
||||||
E01X_send_packet(0);
|
E01X_send_packet(0);
|
||||||
|
}
|
||||||
return packet_period;
|
return packet_period;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -92,8 +92,8 @@ static void __attribute__((unused)) ESKY150_send_packet()
|
|||||||
uint8_t flight_mode=0;
|
uint8_t flight_mode=0;
|
||||||
uint16_t aux_ch6=0;
|
uint16_t aux_ch6=0;
|
||||||
uint8_t aux_ch7=0;
|
uint8_t aux_ch7=0;
|
||||||
if(option==1)
|
if(sub_protocol)
|
||||||
{
|
{ // 7 channels
|
||||||
flight_mode=ESKY150_convert_2bit_channel(CH5);
|
flight_mode=ESKY150_convert_2bit_channel(CH5);
|
||||||
aux_ch6=convert_channel_16b_limit(CH6,1000,2000);
|
aux_ch6=convert_channel_16b_limit(CH6,1000,2000);
|
||||||
aux_ch7=ESKY150_convert_2bit_channel(CH7);
|
aux_ch7=ESKY150_convert_2bit_channel(CH7);
|
||||||
@@ -151,7 +151,12 @@ uint8_t ESKY150_convert_2bit_channel(uint8_t num)
|
|||||||
uint16_t ESKY150_callback()
|
uint16_t ESKY150_callback()
|
||||||
{
|
{
|
||||||
if(IS_BIND_DONE)
|
if(IS_BIND_DONE)
|
||||||
|
{
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(ESKY150_SENDING_PACKET_PERIOD);
|
||||||
|
#endif
|
||||||
ESKY150_send_packet();
|
ESKY150_send_packet();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NRF24L01_WritePayload(packet, ESKY150_PAYLOADSIZE);
|
NRF24L01_WritePayload(packet, ESKY150_PAYLOADSIZE);
|
||||||
|
|||||||
@@ -18,8 +18,13 @@
|
|||||||
|
|
||||||
#include "iface_nrf24l01.h"
|
#include "iface_nrf24l01.h"
|
||||||
|
|
||||||
|
//#define ESKY_ET4_FORCE_ID
|
||||||
|
|
||||||
#define ESKY_BIND_COUNT 1000
|
#define ESKY_BIND_COUNT 1000
|
||||||
#define ESKY_PACKET_PERIOD 3333
|
#define ESKY_STD_PACKET_PERIOD 3333
|
||||||
|
#define ESKY_ET4_PACKET_PERIOD 1190
|
||||||
|
#define ESKY_ET4_TOTAL_PACKET_PERIOD 20300
|
||||||
|
#define ESKY_ET4_BIND_PACKET_PERIOD 5000
|
||||||
#define ESKY_PAYLOAD_SIZE 13
|
#define ESKY_PAYLOAD_SIZE 13
|
||||||
#define ESKY_PACKET_CHKTIME 100 // Time to wait for packet to be sent (no ACK, so very short)
|
#define ESKY_PACKET_CHKTIME 100 // Time to wait for packet to be sent (no ACK, so very short)
|
||||||
|
|
||||||
@@ -63,27 +68,36 @@ static void __attribute__((unused)) ESKY_init()
|
|||||||
static void __attribute__((unused)) ESKY_init2()
|
static void __attribute__((unused)) ESKY_init2()
|
||||||
{
|
{
|
||||||
NRF24L01_FlushTx();
|
NRF24L01_FlushTx();
|
||||||
hopping_frequency_no = 0;
|
if(sub_protocol==ESKY_STD)
|
||||||
uint16_t channel_ord = rx_tx_addr[0] % 74;
|
{
|
||||||
hopping_frequency[12] = 10 + (uint8_t)channel_ord; //channel_code
|
uint16_t channel_ord = rx_tx_addr[0] % 74;
|
||||||
uint8_t channel1, channel2;
|
hopping_frequency[12] = 10 + (uint8_t)channel_ord; //channel_code
|
||||||
channel1 = 10 + (uint8_t)((37 + channel_ord*5) % 74);
|
uint8_t channel1, channel2;
|
||||||
channel2 = 10 + (uint8_t)(( channel_ord*5) % 74) ;
|
channel1 = 10 + (uint8_t)((37 + channel_ord*5) % 74);
|
||||||
|
channel2 = 10 + (uint8_t)(( channel_ord*5) % 74) ;
|
||||||
|
|
||||||
hopping_frequency[0] = channel1;
|
hopping_frequency[0] = channel1;
|
||||||
hopping_frequency[1] = channel1;
|
hopping_frequency[1] = channel1;
|
||||||
hopping_frequency[2] = channel1;
|
hopping_frequency[2] = channel1;
|
||||||
hopping_frequency[3] = channel2;
|
hopping_frequency[3] = channel2;
|
||||||
hopping_frequency[4] = channel2;
|
hopping_frequency[4] = channel2;
|
||||||
hopping_frequency[5] = channel2;
|
hopping_frequency[5] = channel2;
|
||||||
|
|
||||||
//end_bytes
|
//end_bytes
|
||||||
hopping_frequency[6] = 6;
|
hopping_frequency[6] = 6;
|
||||||
hopping_frequency[7] = channel1*2;
|
hopping_frequency[7] = channel1*2;
|
||||||
hopping_frequency[8] = channel2*2;
|
hopping_frequency[8] = channel2*2;
|
||||||
hopping_frequency[9] = 6;
|
hopping_frequency[9] = 6;
|
||||||
hopping_frequency[10] = channel1*2;
|
hopping_frequency[10] = channel1*2;
|
||||||
hopping_frequency[11] = channel2*2;
|
hopping_frequency[11] = channel2*2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // ESKY_ET4
|
||||||
|
hopping_frequency[0] = 0x29; //41
|
||||||
|
hopping_frequency[1] = 0x12; //18
|
||||||
|
hopping_frequency[6] = 0x87; //135 payload end byte
|
||||||
|
hopping_frequency[12] = 0x84; //132 indicates which channels to use
|
||||||
|
}
|
||||||
|
|
||||||
// Turn radio power on
|
// Turn radio power on
|
||||||
NRF24L01_SetTxRxMode(TX_EN);
|
NRF24L01_SetTxRxMode(TX_EN);
|
||||||
@@ -111,20 +125,32 @@ static void __attribute__((unused)) ESKY_send_packet(uint8_t bind)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Regular packet
|
if (packet_count == 0)
|
||||||
// Each data packet is repeated 3 times on one channel, and 3 times on another channel
|
|
||||||
// For arithmetic simplicity, channels are repeated in rf_channels array
|
|
||||||
if (hopping_frequency_no == 0)
|
|
||||||
for (uint8_t i = 0; i < 6; i++)
|
for (uint8_t i = 0; i < 6; i++)
|
||||||
{
|
{
|
||||||
uint16_t val=convert_channel_ppm(CH_AETR[i]);
|
uint16_t val=convert_channel_ppm(CH_AETR[i]);
|
||||||
packet[i*2] = val>>8; //high byte of servo timing(1000-2000us)
|
packet[i*2] = val>>8; //high byte of servo timing(1000-2000us)
|
||||||
packet[i*2+1] = val&0xFF; //low byte of servo timing(1000-2000us)
|
packet[i*2+1] = val&0xFF; //low byte of servo timing(1000-2000us)
|
||||||
}
|
}
|
||||||
rf_ch = hopping_frequency[hopping_frequency_no];
|
if(sub_protocol==ESKY_STD)
|
||||||
packet[12] = hopping_frequency[hopping_frequency_no+6]; // end_bytes
|
{
|
||||||
hopping_frequency_no++;
|
// Regular packet
|
||||||
if (hopping_frequency_no > 6) hopping_frequency_no = 0;
|
// Each data packet is repeated 3 times on one channel, and 3 times on another channel
|
||||||
|
// For arithmetic simplicity, channels are repeated in rf_channels array
|
||||||
|
rf_ch = hopping_frequency[packet_count];
|
||||||
|
packet[12] = hopping_frequency[packet_count+6]; // end_bytes
|
||||||
|
packet_count++;
|
||||||
|
if (packet_count > 6) packet_count = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // ESKY_ET4
|
||||||
|
// Regular packet
|
||||||
|
// Each data packet is repeated 14 times alternating between 2 channels
|
||||||
|
rf_ch = hopping_frequency[packet_count&1];
|
||||||
|
packet_count++;
|
||||||
|
if(packet_count>14) packet_count=0;
|
||||||
|
packet[12] = hopping_frequency[6]; // end_byte
|
||||||
|
}
|
||||||
}
|
}
|
||||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, rf_ch);
|
NRF24L01_WriteReg(NRF24L01_05_RF_CH, rf_ch);
|
||||||
NRF24L01_FlushTx();
|
NRF24L01_FlushTx();
|
||||||
@@ -135,7 +161,20 @@ static void __attribute__((unused)) ESKY_send_packet(uint8_t bind)
|
|||||||
uint16_t ESKY_callback()
|
uint16_t ESKY_callback()
|
||||||
{
|
{
|
||||||
if(IS_BIND_DONE)
|
if(IS_BIND_DONE)
|
||||||
|
{
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
if(packet_count==0)
|
||||||
|
telemetry_set_input_sync(sub_protocol==ESKY_STD?ESKY_STD_PACKET_PERIOD*6:ESKY_ET4_TOTAL_PACKET_PERIOD);
|
||||||
|
#endif
|
||||||
ESKY_send_packet(0);
|
ESKY_send_packet(0);
|
||||||
|
if(sub_protocol==ESKY_ET4)
|
||||||
|
{
|
||||||
|
if(packet_count==0)
|
||||||
|
return ESKY_ET4_TOTAL_PACKET_PERIOD-ESKY_ET4_PACKET_PERIOD*13;
|
||||||
|
else
|
||||||
|
return ESKY_ET4_PACKET_PERIOD;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ESKY_send_packet(1);
|
ESKY_send_packet(1);
|
||||||
@@ -145,16 +184,25 @@ uint16_t ESKY_callback()
|
|||||||
BIND_DONE;
|
BIND_DONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ESKY_PACKET_PERIOD;
|
return ESKY_STD_PACKET_PERIOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t initESKY(void)
|
uint16_t initESKY(void)
|
||||||
{
|
{
|
||||||
bind_counter = ESKY_BIND_COUNT;
|
bind_counter = ESKY_BIND_COUNT;
|
||||||
rx_tx_addr[2] = rx_tx_addr[3]; // Model match
|
rx_tx_addr[2] = rx_tx_addr[3]; // Model match
|
||||||
|
#ifdef ESKY_ET4_FORCE_ID
|
||||||
|
if(sub_protocol==ESKY_ET4)
|
||||||
|
{
|
||||||
|
rx_tx_addr[0]=0x72;
|
||||||
|
rx_tx_addr[1]=0xBB;
|
||||||
|
rx_tx_addr[2]=0xCC;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
rx_tx_addr[3] = 0xBB;
|
rx_tx_addr[3] = 0xBB;
|
||||||
ESKY_init();
|
ESKY_init();
|
||||||
ESKY_init2();
|
ESKY_init2();
|
||||||
|
packet_count=0;
|
||||||
return 50000;
|
return 50000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -188,7 +188,12 @@ uint16_t FQ777_callback()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(FQ777_PACKET_PERIOD);
|
||||||
|
#endif
|
||||||
FQ777_send_packet(0);
|
FQ777_send_packet(0);
|
||||||
|
}
|
||||||
return FQ777_PACKET_PERIOD;
|
return FQ777_PACKET_PERIOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
113
Multiprotocol/FX816_nrf24l01.ino
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
/*
|
||||||
|
This project is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Multiprotocol is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
// Compatible with FEI XIONG P38 plane.
|
||||||
|
|
||||||
|
#if defined(FX816_NRF24L01_INO)
|
||||||
|
|
||||||
|
#include "iface_nrf24l01.h"
|
||||||
|
|
||||||
|
#define FX816_INITIAL_WAIT 500
|
||||||
|
#define FX816_PACKET_PERIOD 10000
|
||||||
|
#define FX816_RF_BIND_CHANNEL 0x28 //40
|
||||||
|
#define FX816_RF_NUM_CHANNELS 4
|
||||||
|
#define FX816_PAYLOAD_SIZE 6
|
||||||
|
#define FX816_BIND_COUNT 300 //3sec
|
||||||
|
|
||||||
|
static void __attribute__((unused)) FX816_send_packet()
|
||||||
|
{
|
||||||
|
packet[0] = IS_BIND_IN_PROGRESS?0x55:0xAA;
|
||||||
|
packet[1] = rx_tx_addr[0];
|
||||||
|
packet[2] = rx_tx_addr[1];
|
||||||
|
uint8_t val=convert_channel_8b(AILERON);
|
||||||
|
#define FX816_SWITCH 20
|
||||||
|
if(val>127+FX816_SWITCH)
|
||||||
|
packet[3] = 1;
|
||||||
|
else if(val<127-FX816_SWITCH)
|
||||||
|
packet[3] = 2;
|
||||||
|
else
|
||||||
|
packet[3] = 0;
|
||||||
|
packet[4] = convert_channel_16b_limit(THROTTLE,0,100);
|
||||||
|
val=0;
|
||||||
|
for(uint8_t i=0;i<FX816_PAYLOAD_SIZE-1;i++)
|
||||||
|
val+=packet[i];
|
||||||
|
packet[5]=val;
|
||||||
|
|
||||||
|
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();
|
||||||
|
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()
|
||||||
|
{
|
||||||
|
NRF24L01_Initialize();
|
||||||
|
NRF24L01_SetTxRxMode(TX_EN);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __attribute__((unused)) FX816_initialize_txid()
|
||||||
|
{
|
||||||
|
//Only 8 IDs: the RX led does not indicate frame loss.
|
||||||
|
//I didn't open the plane to find out if I could connect there so this is the best I came up with with few trial and errors...
|
||||||
|
rx_tx_addr[0]=0x35+(rx_tx_addr[3]&0x07); //Original dump=0x35
|
||||||
|
rx_tx_addr[1]=0x09; //Original dump=0x09
|
||||||
|
memcpy(hopping_frequency,"\x09\x1B\x30\x42",FX816_RF_NUM_CHANNELS); //Original dump=9=0x09,27=0x1B,48=0x30,66=0x42
|
||||||
|
for(uint8_t i=0;i<FX816_RF_NUM_CHANNELS;i++)
|
||||||
|
hopping_frequency[i]+=rx_tx_addr[3]&0x07;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t FX816_callback()
|
||||||
|
{
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(FX816_PACKET_PERIOD);
|
||||||
|
#endif
|
||||||
|
if(IS_BIND_IN_PROGRESS)
|
||||||
|
if(--bind_counter==0)
|
||||||
|
BIND_DONE;
|
||||||
|
FX816_send_packet();
|
||||||
|
return FX816_PACKET_PERIOD;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t initFX816()
|
||||||
|
{
|
||||||
|
BIND_IN_PROGRESS; // autobind protocol
|
||||||
|
FX816_initialize_txid();
|
||||||
|
FX816_init();
|
||||||
|
hopping_frequency_no = 0;
|
||||||
|
bind_counter=FX816_BIND_COUNT;
|
||||||
|
return FX816_INITIAL_WAIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -188,6 +188,9 @@ uint16_t FY326_callback()
|
|||||||
return FY326_PACKET_CHKTIME;
|
return FY326_PACKET_CHKTIME;
|
||||||
break;
|
break;
|
||||||
case FY326_DATA:
|
case FY326_DATA:
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(FY326_PACKET_PERIOD);
|
||||||
|
#endif
|
||||||
FY326_send_packet(0);
|
FY326_send_packet(0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ static void __attribute__((unused)) flysky_build_packet(uint8_t init)
|
|||||||
for(i = 0; i < 8; i++)
|
for(i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
uint16_t temp=convert_channel_ppm(CH_AETR[i]);
|
uint16_t temp=convert_channel_ppm(CH_AETR[i]);
|
||||||
if(sub_protocol == CX20 && CH_AETR[i]==ELEVATOR)
|
if(sub_protocol == CX20 && i==CH2) //ELEVATOR
|
||||||
temp=3000-temp;
|
temp=3000-temp;
|
||||||
packet[5 + i*2]=temp&0xFF; //low byte of servo timing(1000-2000us)
|
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)
|
packet[6 + i*2]=(temp>>8)&0xFF; //high byte of servo timing(1000-2000us)
|
||||||
@@ -168,16 +168,15 @@ uint16_t ReadFlySky()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(packet_period);
|
||||||
|
#endif
|
||||||
flysky_build_packet(0);
|
flysky_build_packet(0);
|
||||||
A7105_WriteData(21, hopping_frequency[hopping_frequency_no & 0x0F]);
|
A7105_WriteData(21, hopping_frequency[hopping_frequency_no & 0x0F]);
|
||||||
A7105_SetPower();
|
A7105_SetPower();
|
||||||
}
|
}
|
||||||
hopping_frequency_no++;
|
hopping_frequency_no++;
|
||||||
|
return packet_period;
|
||||||
if(sub_protocol==CX20)
|
|
||||||
return 3984;
|
|
||||||
else
|
|
||||||
return 1510; //1460 on deviation but not working with the latest V911 bricks... Turnigy 9X v2 is 1533, Flysky TX for 9XR/9XR Pro is 1510, V911 TX is 1490.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t PROGMEM tx_channels[8][4] = {
|
const uint8_t PROGMEM tx_channels[8][4] = {
|
||||||
@@ -235,6 +234,10 @@ uint16_t initFlySky()
|
|||||||
}
|
}
|
||||||
hopping_frequency_no=0;
|
hopping_frequency_no=0;
|
||||||
packet_count=0;
|
packet_count=0;
|
||||||
|
if(sub_protocol==CX20)
|
||||||
|
packet_period=3984;
|
||||||
|
else
|
||||||
|
packet_period=1510; //1460 on deviation but not working with the latest V911 bricks... Turnigy 9X v2 is 1533, Flysky TX for 9XR/9XR Pro is 1510, V911 TX is 1490.
|
||||||
if(IS_BIND_IN_PROGRESS)
|
if(IS_BIND_IN_PROGRESS)
|
||||||
bind_counter = FLYSKY_BIND_COUNT;
|
bind_counter = FLYSKY_BIND_COUNT;
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ static void __attribute__((unused)) flyzone_build_packet()
|
|||||||
packet[4] = convert_channel_8b(ELEVATOR); //00..80..FF
|
packet[4] = convert_channel_8b(ELEVATOR); //00..80..FF
|
||||||
packet[5] = convert_channel_8b(THROTTLE); //00..FF
|
packet[5] = convert_channel_8b(THROTTLE); //00..FF
|
||||||
packet[6] = convert_channel_8b(RUDDER); //00..80..FF
|
packet[6] = convert_channel_8b(RUDDER); //00..80..FF
|
||||||
packet[7] = 0xFF;
|
packet[7] = convert_channel_8b(CH5); //00..80..FF
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t ReadFlyzone()
|
uint16_t ReadFlyzone()
|
||||||
@@ -55,6 +55,9 @@ uint16_t ReadFlyzone()
|
|||||||
if(phase>19)
|
if(phase>19)
|
||||||
{
|
{
|
||||||
phase=0;
|
phase=0;
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(20*1500);
|
||||||
|
#endif
|
||||||
flyzone_build_packet();
|
flyzone_build_packet();
|
||||||
A7105_WriteData(8, hopping_frequency[0]);
|
A7105_WriteData(8, hopping_frequency[0]);
|
||||||
A7105_SetPower();
|
A7105_SetPower();
|
||||||
|
|||||||
@@ -13,156 +13,32 @@
|
|||||||
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
|
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef FAILSAFE_ENABLE
|
|
||||||
//Convert from percentage to failsafe value
|
|
||||||
#define FAILSAFE_THROTTLE_LOW_VAL (((FAILSAFE_THROTTLE_LOW+125)*1024)/125)
|
|
||||||
#if FAILSAFE_THROTTLE_LOW_VAL <= 0
|
|
||||||
#undef FAILSAFE_THROTTLE_LOW_VAL
|
|
||||||
#define FAILSAFE_THROTTLE_LOW_VAL 1
|
|
||||||
#elif (FAILSAFE_THROTTLE_LOW_VAL) >= 2046
|
|
||||||
#undef FAILSAFE_THROTTLE_LOW_VAL
|
|
||||||
#define FAILSAFE_THROTTLE_LOW_VAL 2046
|
|
||||||
#endif
|
|
||||||
void InitFailsafe()
|
|
||||||
{
|
|
||||||
for(uint8_t i=0;i<NUM_CHN;i++)
|
|
||||||
Failsafe_data[i]=1024;
|
|
||||||
Failsafe_data[THROTTLE]=(uint16_t)FAILSAFE_THROTTLE_LOW_VAL; //1=-125%, 204=-100%
|
|
||||||
FAILSAFE_VALUES_on;
|
|
||||||
#ifdef FAILSAFE_SERIAL_ONLY
|
|
||||||
if(mode_select == MODE_SERIAL)
|
|
||||||
FAILSAFE_VALUES_off;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef ENABLE_PPM
|
|
||||||
void InitPPM()
|
|
||||||
{
|
|
||||||
for(uint8_t i=0;i<NUM_CHN;i++)
|
|
||||||
PPM_data[i]=PPM_MAX_100+PPM_MIN_100;
|
|
||||||
PPM_data[THROTTLE]=PPM_MIN_100*2;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
void InitChannel()
|
|
||||||
{
|
|
||||||
for(uint8_t i=0;i<NUM_CHN;i++)
|
|
||||||
Channel_data[i]=1024;
|
|
||||||
#ifdef FAILSAFE_THROTTLE_LOW_VAL
|
|
||||||
Channel_data[THROTTLE]=(uint16_t)FAILSAFE_THROTTLE_LOW_VAL; //0=-125%, 204=-100%
|
|
||||||
#else
|
|
||||||
Channel_data[THROTTLE]=204;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
/************************/
|
|
||||||
/** Convert routines **/
|
|
||||||
/************************/
|
|
||||||
// Convert channel 8b with limit and deadband
|
|
||||||
uint8_t convert_channel_8b_limit_deadband(uint8_t num,uint8_t min,uint8_t mid, uint8_t max, uint8_t deadband)
|
|
||||||
{
|
|
||||||
uint16_t val=limit_channel_100(num); // 204<->1844
|
|
||||||
uint16_t db_low=CHANNEL_MID-deadband, db_high=CHANNEL_MID+deadband; // 1024+-deadband
|
|
||||||
if(val>=db_low && val<=db_high)
|
|
||||||
return mid;
|
|
||||||
else if(val<db_low)
|
|
||||||
val=min+(val-CHANNEL_MIN_100)*(mid-min)/(db_low-CHANNEL_MIN_100);
|
|
||||||
else
|
|
||||||
val=mid+(val-db_high)*(max-mid)/(CHANNEL_MAX_100-1-db_high);
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reverse a channel and store it
|
|
||||||
void reverse_channel(uint8_t num)
|
|
||||||
{
|
|
||||||
uint16_t val=2048-Channel_data[num];
|
|
||||||
if(val>=2048) val=2047;
|
|
||||||
Channel_data[num]=val;
|
|
||||||
}
|
|
||||||
// Channel value is converted to ppm 860<->2140 -125%<->+125% and 988<->2012 -100%<->+100%
|
|
||||||
uint16_t convert_channel_ppm(uint8_t num)
|
|
||||||
{
|
|
||||||
uint16_t val=Channel_data[num];
|
|
||||||
return (((val<<2)+val)>>3)+860; //value range 860<->2140 -125%<->+125%
|
|
||||||
}
|
|
||||||
// Channel value 100% is converted to 10bit values 0<->1023
|
|
||||||
uint16_t convert_channel_10b(uint8_t num)
|
|
||||||
{
|
|
||||||
uint16_t val=Channel_data[num];
|
|
||||||
val=((val<<2)+val)>>3;
|
|
||||||
if(val<=128) return 0;
|
|
||||||
if(val>=1152) return 1023;
|
|
||||||
return val-128;
|
|
||||||
}
|
|
||||||
// Channel value 100% is converted to 8bit values 0<->255
|
|
||||||
uint8_t convert_channel_8b(uint8_t num)
|
|
||||||
{
|
|
||||||
uint16_t val=Channel_data[num];
|
|
||||||
val=((val<<2)+val)>>5;
|
|
||||||
if(val<=32) return 0;
|
|
||||||
if(val>=288) return 255;
|
|
||||||
return val-32;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Channel value 100% is converted to value scaled
|
|
||||||
int16_t convert_channel_16b_limit(uint8_t num,int16_t min,int16_t max)
|
|
||||||
{
|
|
||||||
int32_t val=limit_channel_100(num); // 204<->1844
|
|
||||||
val=(val-CHANNEL_MIN_100)*(max-min)/(CHANNEL_MAX_100-CHANNEL_MIN_100)+min;
|
|
||||||
return (uint16_t)val;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Channel value -125%<->125% is scaled to 16bit value with no limit
|
|
||||||
int16_t convert_channel_16b_nolimit(uint8_t num, int16_t min, int16_t max)
|
|
||||||
{
|
|
||||||
int32_t val=Channel_data[num]; // 0<->2047
|
|
||||||
val=(val-CHANNEL_MIN_100)*(max-min)/(CHANNEL_MAX_100-CHANNEL_MIN_100)+min;
|
|
||||||
return (uint16_t)val;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Channel value is converted sign + magnitude 8bit values
|
|
||||||
uint8_t convert_channel_s8b(uint8_t num)
|
|
||||||
{
|
|
||||||
uint8_t ch;
|
|
||||||
ch = convert_channel_8b(num);
|
|
||||||
return (ch < 128 ? 127-ch : ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Channel value is limited to 100%
|
|
||||||
uint16_t limit_channel_100(uint8_t num)
|
|
||||||
{
|
|
||||||
if(Channel_data[num]>=CHANNEL_MAX_100)
|
|
||||||
return CHANNEL_MAX_100;
|
|
||||||
if (Channel_data[num]<=CHANNEL_MIN_100)
|
|
||||||
return CHANNEL_MIN_100;
|
|
||||||
return Channel_data[num];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Channel value is converted for HK310
|
|
||||||
void convert_channel_HK310(uint8_t num, uint8_t *low, uint8_t *high)
|
|
||||||
{
|
|
||||||
uint16_t temp=0xFFFF-(3440+((Channel_data[num]*5)>>1))/3;
|
|
||||||
*low=(uint8_t)(temp&0xFF);
|
|
||||||
*high=(uint8_t)(temp>>8);
|
|
||||||
}
|
|
||||||
#ifdef FAILSAFE_ENABLE
|
|
||||||
// Failsafe value is converted for HK310
|
|
||||||
void convert_failsafe_HK310(uint8_t num, uint8_t *low, uint8_t *high)
|
|
||||||
{
|
|
||||||
uint16_t temp=0xFFFF-(3440+((Failsafe_data[num]*5)>>1))/3;
|
|
||||||
*low=(uint8_t)(temp&0xFF);
|
|
||||||
*high=(uint8_t)(temp>>8);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Channel value for FrSky (PPM is multiplied by 1.5)
|
|
||||||
uint16_t convert_channel_frsky(uint8_t num)
|
|
||||||
{
|
|
||||||
uint16_t val=Channel_data[num];
|
|
||||||
return ((val*15)>>4)+1290;
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************/
|
/******************************/
|
||||||
/** FrSky D and X routines **/
|
/** FrSky D and X routines **/
|
||||||
/******************************/
|
/******************************/
|
||||||
|
|
||||||
|
#if defined(FRSKYX_CC2500_INO) || defined(FRSKY_RX_CC2500_INO) || defined(FRSKYR9_SX1276_INO)
|
||||||
|
//**CRC**
|
||||||
|
const uint16_t PROGMEM FrSkyX_CRC_Short[]={
|
||||||
|
0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF,
|
||||||
|
0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7 };
|
||||||
|
static uint16_t __attribute__((unused)) FrSkyX_CRCTable(uint8_t val)
|
||||||
|
{
|
||||||
|
uint16_t word ;
|
||||||
|
word = pgm_read_word(&FrSkyX_CRC_Short[val&0x0F]) ;
|
||||||
|
val /= 16 ;
|
||||||
|
return word ^ (0x1081 * val) ;
|
||||||
|
}
|
||||||
|
uint16_t FrSkyX_crc(uint8_t *data, uint8_t len)
|
||||||
|
{
|
||||||
|
uint16_t crc = 0;
|
||||||
|
for(uint8_t i=0; i < len; i++)
|
||||||
|
crc = (crc<<8) ^ FrSkyX_CRCTable((uint8_t)(crc>>8) ^ *data++);
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if defined(FRSKYD_CC2500_INO) || defined(FRSKYX_CC2500_INO)
|
#if defined(FRSKYD_CC2500_INO) || defined(FRSKYX_CC2500_INO)
|
||||||
enum {
|
enum {
|
||||||
FRSKY_BIND = 0,
|
FRSKY_BIND = 0,
|
||||||
@@ -171,7 +47,7 @@ enum {
|
|||||||
FRSKY_DATA2,
|
FRSKY_DATA2,
|
||||||
FRSKY_DATA3,
|
FRSKY_DATA3,
|
||||||
FRSKY_DATA4,
|
FRSKY_DATA4,
|
||||||
FRSKY_DATA5
|
FRSKY_DATA5,
|
||||||
};
|
};
|
||||||
|
|
||||||
void Frsky_init_hop(void)
|
void Frsky_init_hop(void)
|
||||||
@@ -266,7 +142,7 @@ void Frsky_init_hop(void)
|
|||||||
/*15_DEVIATN*/ 0x42 };
|
/*15_DEVIATN*/ 0x42 };
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(FRSKYX_CC2500_INO)
|
#if defined(FRSKYX_CC2500_INO) || defined(FRSKYX2_CC2500_INO)
|
||||||
const PROGMEM uint8_t FRSKYX_cc2500_conf[]= {
|
const PROGMEM uint8_t FRSKYX_cc2500_conf[]= {
|
||||||
//FRSKYX
|
//FRSKYX
|
||||||
/*02_IOCFG0*/ 0x06 ,
|
/*02_IOCFG0*/ 0x06 ,
|
||||||
@@ -346,8 +222,58 @@ void Frsky_init_hop(void)
|
|||||||
uint8_t val=pgm_read_byte_near(&FRSKY_common_end_cc2500_conf[i][1]);
|
uint8_t val=pgm_read_byte_near(&FRSKY_common_end_cc2500_conf[i][1]);
|
||||||
CC2500_WriteReg(reg,val);
|
CC2500_WriteReg(reg,val);
|
||||||
}
|
}
|
||||||
|
if(protocol==PROTO_FRSKYX2)
|
||||||
|
CC2500_WriteReg(CC2500_08_PKTCTRL0, 0x05); // enable CRC
|
||||||
CC2500_SetTxRxMode(TX_EN);
|
CC2500_SetTxRxMode(TX_EN);
|
||||||
CC2500_SetPower();
|
CC2500_SetPower();
|
||||||
CC2500_Strobe(CC2500_SIDLE); // Go to idle...
|
CC2500_Strobe(CC2500_SIDLE); // Go to idle...
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(FRSKYX_CC2500_INO) || defined(FRSKYX2_CC2500_INO)
|
||||||
|
uint8_t FrSkyX_chanskip;
|
||||||
|
uint8_t FrSkyX_TX_Seq, FrSkyX_TX_IN_Seq;
|
||||||
|
uint8_t FrSkyX_RX_Seq ;
|
||||||
|
|
||||||
|
#ifdef SPORT_SEND
|
||||||
|
struct t_FrSkyX_TX_Frame
|
||||||
|
{
|
||||||
|
uint8_t count;
|
||||||
|
uint8_t payload[8];
|
||||||
|
} ;
|
||||||
|
// Store FrskyX telemetry
|
||||||
|
struct t_FrSkyX_TX_Frame FrSkyX_TX_Frames[4] ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define FRSKYX_FAILSAFE_TIMEOUT 1032
|
||||||
|
|
||||||
|
static void __attribute__((unused)) FrSkyX_set_start(uint8_t ch )
|
||||||
|
{
|
||||||
|
CC2500_Strobe(CC2500_SIDLE);
|
||||||
|
CC2500_WriteReg(CC2500_25_FSCAL1, calData[ch]);
|
||||||
|
CC2500_WriteReg(CC2500_0A_CHANNR, hopping_frequency[ch]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __attribute__((unused)) FrSkyX_init()
|
||||||
|
{
|
||||||
|
FRSKY_init_cc2500((sub_protocol&2)?FRSKYXEU_cc2500_conf:FRSKYX_cc2500_conf); // LBT or FCC
|
||||||
|
//
|
||||||
|
for(uint8_t c=0;c < 48;c++)
|
||||||
|
{//calibrate hop channels
|
||||||
|
CC2500_Strobe(CC2500_SIDLE);
|
||||||
|
CC2500_WriteReg(CC2500_0A_CHANNR,hopping_frequency[c]);
|
||||||
|
CC2500_Strobe(CC2500_SCAL);
|
||||||
|
delayMicroseconds(900);//
|
||||||
|
calData[c] = CC2500_ReadReg(CC2500_25_FSCAL1);
|
||||||
|
}
|
||||||
|
//#######END INIT########
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __attribute__((unused)) FrSkyX_initialize_data(uint8_t adr)
|
||||||
|
{
|
||||||
|
CC2500_WriteReg(CC2500_18_MCSM0, 0x8);
|
||||||
|
CC2500_WriteReg(CC2500_09_ADDR, adr ? 0x03 : rx_tx_addr[3]);
|
||||||
|
CC2500_WriteReg(CC2500_07_PKTCTRL1,0x05); // check address
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -21,6 +21,7 @@ static void __attribute__((unused)) frsky2way_init(uint8_t bind)
|
|||||||
{
|
{
|
||||||
FRSKY_init_cc2500(FRSKYD_cc2500_conf);
|
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_09_ADDR, bind ? 0x03 : rx_tx_addr[3]);
|
||||||
CC2500_WriteReg(CC2500_07_PKTCTRL1, 0x05);
|
CC2500_WriteReg(CC2500_07_PKTCTRL1, 0x05);
|
||||||
CC2500_Strobe(CC2500_SIDLE); // Go to idle...
|
CC2500_Strobe(CC2500_SIDLE); // Go to idle...
|
||||||
@@ -95,11 +96,18 @@ static void __attribute__((unused)) frsky2way_data_frame()
|
|||||||
|
|
||||||
uint16_t initFrSky_2way()
|
uint16_t initFrSky_2way()
|
||||||
{
|
{
|
||||||
Frsky_init_hop();
|
//FrskyD init hop
|
||||||
|
for(uint8_t i=0;i<50;i++)
|
||||||
|
{
|
||||||
|
uint8_t freq = (i * 0x1e) % 0xeb;
|
||||||
|
if(i == 3 || i == 23 || i == 47)
|
||||||
|
freq++;
|
||||||
|
if(i > 47)
|
||||||
|
freq=0;
|
||||||
|
hopping_frequency[i]=freq;
|
||||||
|
}
|
||||||
|
|
||||||
packet_count=0;
|
packet_count=0;
|
||||||
#if defined TELEMETRY
|
|
||||||
init_frskyd_link_telemetry();
|
|
||||||
#endif
|
|
||||||
if(IS_BIND_IN_PROGRESS)
|
if(IS_BIND_IN_PROGRESS)
|
||||||
{
|
{
|
||||||
frsky2way_init(1);
|
frsky2way_init(1);
|
||||||
@@ -156,15 +164,18 @@ uint16_t ReadFrSky_2way()
|
|||||||
{
|
{
|
||||||
if (state == FRSKY_DATA1)
|
if (state == FRSKY_DATA1)
|
||||||
{
|
{
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(9000);
|
||||||
|
#endif
|
||||||
len = CC2500_ReadReg(CC2500_3B_RXBYTES | CC2500_READ_BURST) & 0x7F;
|
len = CC2500_ReadReg(CC2500_3B_RXBYTES | CC2500_READ_BURST) & 0x7F;
|
||||||
if (len && len<=(0x11+3))// 20bytes
|
if (len && len<=(0x11+3))// 20bytes
|
||||||
{
|
{
|
||||||
CC2500_ReadData(pkt, len); //received telemetry packets
|
CC2500_ReadData(packet_in, len); //received telemetry packets
|
||||||
#if defined(TELEMETRY)
|
#if defined(TELEMETRY)
|
||||||
if(pkt[len-1] & 0x80)
|
if(packet_in[len-1] & 0x80)
|
||||||
{//with valid crc
|
{//with valid crc
|
||||||
packet_count=0;
|
packet_count=0;
|
||||||
frsky_check_telemetry(pkt,len); //check if valid telemetry packets and buffer them.
|
frsky_check_telemetry(packet_in,len); //check if valid telemetry packets and buffer them.
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -177,7 +188,7 @@ uint16_t ReadFrSky_2way()
|
|||||||
packet_count=0;
|
packet_count=0;
|
||||||
#if defined TELEMETRY
|
#if defined TELEMETRY
|
||||||
telemetry_link=0;//no link frames
|
telemetry_link=0;//no link frames
|
||||||
pkt[6]=0;//no user frames.
|
packet_in[6]=0;//no user frames.
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
208
Multiprotocol/FrSkyR9_sx1276.ino
Normal file
@@ -0,0 +1,208 @@
|
|||||||
|
#if defined(FRSKYR9_SX1276_INO)
|
||||||
|
#include "iface_sx1276.h"
|
||||||
|
|
||||||
|
#define FREQ_MAP_SIZE 29
|
||||||
|
|
||||||
|
// TODO the channel spacing is equal, consider calculating the new channel instead of using lookup tables (first_chan + index * step)
|
||||||
|
|
||||||
|
static uint32_t FrSkyR9_freq_map_915[FREQ_MAP_SIZE] =
|
||||||
|
{
|
||||||
|
914472960,
|
||||||
|
914972672,
|
||||||
|
915472384,
|
||||||
|
915972096,
|
||||||
|
916471808,
|
||||||
|
916971520,
|
||||||
|
917471232,
|
||||||
|
917970944,
|
||||||
|
918470656,
|
||||||
|
918970368,
|
||||||
|
919470080,
|
||||||
|
919969792,
|
||||||
|
920469504,
|
||||||
|
920969216,
|
||||||
|
921468928,
|
||||||
|
921968640,
|
||||||
|
922468352,
|
||||||
|
922968064,
|
||||||
|
923467776,
|
||||||
|
923967488,
|
||||||
|
924467200,
|
||||||
|
924966912,
|
||||||
|
925466624,
|
||||||
|
925966336,
|
||||||
|
926466048,
|
||||||
|
926965760,
|
||||||
|
927465472,
|
||||||
|
|
||||||
|
// last two determined by FrSkyR9_step
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint32_t FrSkyR9_freq_map_868[FREQ_MAP_SIZE] =
|
||||||
|
{
|
||||||
|
859504640,
|
||||||
|
860004352,
|
||||||
|
860504064,
|
||||||
|
861003776,
|
||||||
|
861503488,
|
||||||
|
862003200,
|
||||||
|
862502912,
|
||||||
|
863002624,
|
||||||
|
863502336,
|
||||||
|
864002048,
|
||||||
|
864501760,
|
||||||
|
865001472,
|
||||||
|
865501184,
|
||||||
|
866000896,
|
||||||
|
866500608,
|
||||||
|
867000320,
|
||||||
|
867500032,
|
||||||
|
867999744,
|
||||||
|
868499456,
|
||||||
|
868999168,
|
||||||
|
869498880,
|
||||||
|
869998592,
|
||||||
|
870498304,
|
||||||
|
870998016,
|
||||||
|
871497728,
|
||||||
|
871997440,
|
||||||
|
872497152,
|
||||||
|
|
||||||
|
// last two determined by FrSkyR9_step
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint8_t FrSkyR9_step = 1;
|
||||||
|
static uint32_t* FrSkyR9_freq_map = FrSkyR9_freq_map_915;
|
||||||
|
|
||||||
|
uint16_t initFrSkyR9()
|
||||||
|
{
|
||||||
|
set_rx_tx_addr(MProtocol_id_master);
|
||||||
|
|
||||||
|
if(sub_protocol & 0x01)
|
||||||
|
FrSkyR9_freq_map = FrSkyR9_freq_map_868;
|
||||||
|
else
|
||||||
|
FrSkyR9_freq_map = FrSkyR9_freq_map_915;
|
||||||
|
|
||||||
|
FrSkyR9_step = 1 + (random(0xfefefefe) % 24);
|
||||||
|
FrSkyR9_freq_map[27] = FrSkyR9_freq_map[FrSkyR9_step];
|
||||||
|
FrSkyR9_freq_map[28] = FrSkyR9_freq_map[FrSkyR9_step+1];
|
||||||
|
|
||||||
|
SX1276_SetMode(true, false, SX1276_OPMODE_SLEEP);
|
||||||
|
SX1276_SetMode(true, false, SX1276_OPMODE_STDBY);
|
||||||
|
|
||||||
|
// uint8_t buffer[2];
|
||||||
|
// buffer[0] = 0x00;
|
||||||
|
// buffer[1] = 0x00;
|
||||||
|
// SX1276_WriteRegisterMulti(SX1276_40_DIOMAPPING1, buffer, 2);
|
||||||
|
|
||||||
|
SX1276_SetDetectOptimize(true, SX1276_DETECT_OPTIMIZE_SF6);
|
||||||
|
SX1276_ConfigModem1(SX1276_MODEM_CONFIG1_BW_500KHZ, SX1276_MODEM_CONFIG1_CODING_RATE_4_5, true);
|
||||||
|
SX1276_ConfigModem2(6, false, false);
|
||||||
|
SX1276_ConfigModem3(false, false);
|
||||||
|
SX1276_SetPreambleLength(9);
|
||||||
|
SX1276_SetDetectionThreshold(SX1276_MODEM_DETECTION_THRESHOLD_SF6);
|
||||||
|
SX1276_SetLna(1, true);
|
||||||
|
SX1276_SetHopPeriod(0); // 0 = disabled, we hope frequencies manually
|
||||||
|
SX1276_SetPaDac(true);
|
||||||
|
|
||||||
|
hopping_frequency_no = 0;
|
||||||
|
|
||||||
|
// TODO this can probably be shorter
|
||||||
|
return 20000; // start calling FrSkyR9_callback in 20 milliseconds
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t FrSkyR9_callback()
|
||||||
|
{
|
||||||
|
SX1276_SetMode(true, false, SX1276_OPMODE_STDBY);
|
||||||
|
|
||||||
|
//SX1276_WriteReg(SX1276_11_IRQFLAGSMASK, 0xbf); // use only RxDone interrupt
|
||||||
|
|
||||||
|
// uint8_t buffer[2];
|
||||||
|
// buffer[0] = 0x00;
|
||||||
|
// buffer[1] = 0x00;
|
||||||
|
// SX1276_WriteRegisterMulti(SX1276_40_DIOMAPPING1, buffer, 2); // RxDone interrupt mapped to DIO0 (the rest are not used because of the REG_IRQ_FLAGS_MASK)
|
||||||
|
|
||||||
|
// SX1276_WriteReg(REG_PAYLOAD_LENGTH, 13);
|
||||||
|
|
||||||
|
// SX1276_WriteReg(REG_FIFO_ADDR_PTR, 0x00);
|
||||||
|
|
||||||
|
// SX1276_WriteReg(SX1276_01_OPMODE, 0x85); // RXCONTINUOUS
|
||||||
|
// delay(10); // 10 ms
|
||||||
|
|
||||||
|
// SX1276_WriteReg(SX1276_01_OPMODE, 0x81); // STDBY
|
||||||
|
|
||||||
|
//SX1276_WriteReg(SX1276_09_PACONFIG, 0xF0);
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
SX1276_SetFrequency(FrSkyR9_freq_map[hopping_frequency_no]); // set current center frequency
|
||||||
|
|
||||||
|
delayMicroseconds(500);
|
||||||
|
|
||||||
|
packet[0] = 0x3C; // ????
|
||||||
|
packet[1] = rx_tx_addr[3]; // unique radio id
|
||||||
|
packet[2] = rx_tx_addr[2]; // unique radio id
|
||||||
|
packet[3] = hopping_frequency_no; // current channel index
|
||||||
|
packet[4] = FrSkyR9_step; // step size and last 2 channels start index
|
||||||
|
packet[5] = RX_num; // receiver number from OpenTX
|
||||||
|
|
||||||
|
// binding mode: 0x00 regular / 0x41 bind?
|
||||||
|
if(IS_BIND_IN_PROGRESS)
|
||||||
|
packet[6] = 0x41;
|
||||||
|
else
|
||||||
|
packet[6] = 0x00;
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
packet[7] = 0x00; // fail safe related (looks like the same sequence of numbers as FrskyX protocol)
|
||||||
|
|
||||||
|
// two channel are spread over 3 bytes.
|
||||||
|
// each channel is 11 bit + 1 bit (msb) that states whether
|
||||||
|
// it's part of the upper channels (9-16) or lower (1-8) (0 - lower 1 - upper)
|
||||||
|
|
||||||
|
#define CH_POS 8
|
||||||
|
static uint8_t chan_start=0;
|
||||||
|
uint8_t chan_index = chan_start;
|
||||||
|
|
||||||
|
for(int i = 0; i < 12; i += 3)
|
||||||
|
{
|
||||||
|
// map channel values (0-2047) to (64-1984)
|
||||||
|
uint16_t ch1 = FrSkyX_scaleForPXX(chan_index);
|
||||||
|
uint16_t ch2 = FrSkyX_scaleForPXX(chan_index + 1);
|
||||||
|
|
||||||
|
packet[CH_POS + i] = ch1;
|
||||||
|
packet[CH_POS + i + 1] = (ch1 >> 8) | (ch2 << 4);
|
||||||
|
packet[CH_POS + i + 2] = (ch2 >> 4);
|
||||||
|
|
||||||
|
chan_index += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((sub_protocol & 0x02) == 0)
|
||||||
|
chan_start ^= 0x08; // Alternate between lower and upper when 16 channels is used
|
||||||
|
|
||||||
|
packet[20] = 0x08; // ????
|
||||||
|
packet[21] = 0x00; // ????
|
||||||
|
packet[22] = 0x00; // ????
|
||||||
|
packet[23] = 0x00; // ????
|
||||||
|
|
||||||
|
uint16_t crc = FrSkyX_crc(packet, 24);
|
||||||
|
|
||||||
|
packet[24] = crc; // low byte
|
||||||
|
packet[25] = crc >> 8; // high byte
|
||||||
|
|
||||||
|
SX1276_WritePayloadToFifo(packet, 26);
|
||||||
|
|
||||||
|
hopping_frequency_no = (hopping_frequency_no + FrSkyR9_step) % FREQ_MAP_SIZE;
|
||||||
|
|
||||||
|
SX1276_SetMode(true, false, SX1276_OPMODE_TX);
|
||||||
|
|
||||||
|
// need to clear RegIrqFlags?
|
||||||
|
|
||||||
|
return 19400;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -117,6 +117,9 @@ uint16_t ReadFRSKYV()
|
|||||||
{
|
{
|
||||||
if(IS_BIND_DONE)
|
if(IS_BIND_DONE)
|
||||||
{ // Normal operation
|
{ // Normal operation
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(9006);
|
||||||
|
#endif
|
||||||
uint8_t chan = FRSKYV_calc_channel();
|
uint8_t chan = FRSKYV_calc_channel();
|
||||||
CC2500_Strobe(CC2500_SIDLE);
|
CC2500_Strobe(CC2500_SIDLE);
|
||||||
if (option != prev_option)
|
if (option != prev_option)
|
||||||
|
|||||||
@@ -19,62 +19,7 @@
|
|||||||
|
|
||||||
#include "iface_cc2500.h"
|
#include "iface_cc2500.h"
|
||||||
|
|
||||||
uint8_t FrX_chanskip;
|
static void __attribute__((unused)) FrSkyX_build_bind_packet()
|
||||||
uint8_t FrX_send_seq ;
|
|
||||||
uint8_t FrX_receive_seq ;
|
|
||||||
|
|
||||||
#define FRX_FAILSAFE_TIMEOUT 1032
|
|
||||||
|
|
||||||
static void __attribute__((unused)) frskyX_set_start(uint8_t ch )
|
|
||||||
{
|
|
||||||
CC2500_Strobe(CC2500_SIDLE);
|
|
||||||
CC2500_WriteReg(CC2500_25_FSCAL1, calData[ch]);
|
|
||||||
CC2500_WriteReg(CC2500_0A_CHANNR, hopping_frequency[ch]);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __attribute__((unused)) frskyX_init()
|
|
||||||
{
|
|
||||||
FRSKY_init_cc2500((sub_protocol&2)?FRSKYXEU_cc2500_conf:FRSKYX_cc2500_conf); // LBT or FCC
|
|
||||||
//
|
|
||||||
for(uint8_t c=0;c < 48;c++)
|
|
||||||
{//calibrate hop channels
|
|
||||||
CC2500_Strobe(CC2500_SIDLE);
|
|
||||||
CC2500_WriteReg(CC2500_0A_CHANNR,hopping_frequency[c]);
|
|
||||||
CC2500_Strobe(CC2500_SCAL);
|
|
||||||
delayMicroseconds(900);//
|
|
||||||
calData[c] = CC2500_ReadReg(CC2500_25_FSCAL1);
|
|
||||||
}
|
|
||||||
//#######END INIT########
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __attribute__((unused)) frskyX_initialize_data(uint8_t adr)
|
|
||||||
{
|
|
||||||
CC2500_WriteReg(CC2500_0C_FSCTRL0,option); // Frequency offset hack
|
|
||||||
CC2500_WriteReg(CC2500_18_MCSM0, 0x8);
|
|
||||||
CC2500_WriteReg(CC2500_09_ADDR, adr ? 0x03 : rx_tx_addr[3]);
|
|
||||||
CC2500_WriteReg(CC2500_07_PKTCTRL1,0x05);
|
|
||||||
}
|
|
||||||
|
|
||||||
//**CRC**
|
|
||||||
const uint16_t PROGMEM frskyX_CRC_Short[]={
|
|
||||||
0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF,
|
|
||||||
0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7 };
|
|
||||||
static uint16_t __attribute__((unused)) frskyX_CRCTable(uint8_t val)
|
|
||||||
{
|
|
||||||
uint16_t word ;
|
|
||||||
word = pgm_read_word(&frskyX_CRC_Short[val&0x0F]) ;
|
|
||||||
val /= 16 ;
|
|
||||||
return word ^ (0x1081 * val) ;
|
|
||||||
}
|
|
||||||
static uint16_t __attribute__((unused)) frskyX_crc_x(uint8_t *data, uint8_t len)
|
|
||||||
{
|
|
||||||
uint16_t crc = 0;
|
|
||||||
for(uint8_t i=0; i < len; i++)
|
|
||||||
crc = (crc<<8) ^ frskyX_CRCTable((uint8_t)(crc>>8) ^ *data++);
|
|
||||||
return crc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __attribute__((unused)) frskyX_build_bind_packet()
|
|
||||||
{
|
{
|
||||||
packet[0] = (sub_protocol & 2 ) ? 0x20 : 0x1D ; // LBT or FCC
|
packet[0] = (sub_protocol & 2 ) ? 0x20 : 0x1D ; // LBT or FCC
|
||||||
packet[1] = 0x03;
|
packet[1] = 0x03;
|
||||||
@@ -94,36 +39,20 @@ static void __attribute__((unused)) frskyX_build_bind_packet()
|
|||||||
//
|
//
|
||||||
uint8_t limit = (sub_protocol & 2 ) ? 31 : 28 ;
|
uint8_t limit = (sub_protocol & 2 ) ? 31 : 28 ;
|
||||||
memset(&packet[13], 0, limit - 13);
|
memset(&packet[13], 0, limit - 13);
|
||||||
uint16_t lcrc = frskyX_crc_x(&packet[3], limit-3);
|
if(binding_idx&0x01)
|
||||||
|
memcpy(&packet[13],(void *)"\x55\xAA\x5A\xA5",4); // Telem off
|
||||||
|
if(binding_idx&0x02)
|
||||||
|
memcpy(&packet[17],(void *)"\x55\xAA\x5A\xA5",4); // CH9-16
|
||||||
|
//
|
||||||
|
uint16_t lcrc = FrSkyX_crc(&packet[3], limit-3);
|
||||||
//
|
//
|
||||||
packet[limit++] = lcrc >> 8;
|
packet[limit++] = lcrc >> 8;
|
||||||
packet[limit] = lcrc;
|
packet[limit] = lcrc;
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0-2047, 0 = 817, 1024 = 1500, 2047 = 2182
|
#define FrSkyX_FAILSAFE_TIME 1032
|
||||||
//64=860,1024=1500,1984=2140//Taranis 125%
|
static void __attribute__((unused)) FrSkyX_build_packet()
|
||||||
static uint16_t __attribute__((unused)) frskyX_scaleForPXX( uint8_t i )
|
|
||||||
{ //mapped 860,2140(125%) range to 64,1984(PXX values);
|
|
||||||
uint16_t chan_val=convert_channel_frsky(i)-1226;
|
|
||||||
if(i>7) chan_val|=2048; // upper channels offset
|
|
||||||
return chan_val;
|
|
||||||
}
|
|
||||||
#ifdef FAILSAFE_ENABLE
|
|
||||||
static uint16_t __attribute__((unused)) frskyX_scaleForPXX_FS( uint8_t i )
|
|
||||||
{ //mapped 1,2046(125%) range to 64,1984(PXX values);
|
|
||||||
uint16_t chan_val=((Failsafe_data[i]*15)>>4)+64;
|
|
||||||
if(Failsafe_data[i]==FAILSAFE_CHANNEL_NOPULSES)
|
|
||||||
chan_val=FAILSAFE_CHANNEL_NOPULSES;
|
|
||||||
else if(Failsafe_data[i]==FAILSAFE_CHANNEL_HOLD)
|
|
||||||
chan_val=FAILSAFE_CHANNEL_HOLD;
|
|
||||||
if(i>7) chan_val|=2048; // upper channels offset
|
|
||||||
return chan_val;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define FRX_FAILSAFE_TIME 1032
|
|
||||||
static void __attribute__((unused)) frskyX_data_frame()
|
|
||||||
{
|
{
|
||||||
//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
|
//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
|
||||||
//
|
//
|
||||||
@@ -135,29 +64,30 @@ static void __attribute__((unused)) frskyX_data_frame()
|
|||||||
#ifdef FAILSAFE_ENABLE
|
#ifdef FAILSAFE_ENABLE
|
||||||
static uint16_t failsafe_count=0;
|
static uint16_t failsafe_count=0;
|
||||||
static uint8_t FS_flag=0,failsafe_chan=0;
|
static uint8_t FS_flag=0,failsafe_chan=0;
|
||||||
if (FS_flag == 0 && failsafe_count > FRX_FAILSAFE_TIME && chan_offset == 0 && IS_FAILSAFE_VALUES_on)
|
if (FS_flag == 0 && failsafe_count > FrSkyX_FAILSAFE_TIME && chan_offset == 0 && IS_FAILSAFE_VALUES_on)
|
||||||
{
|
{
|
||||||
FS_flag = 0x10;
|
FS_flag = 0x10;
|
||||||
failsafe_chan = 0;
|
failsafe_chan = 0;
|
||||||
} else if (FS_flag & 0x10 && failsafe_chan < (sub_protocol & 0x01 ? 8-1:16-1))
|
} else if (FS_flag & 0x10 && failsafe_chan < (sub_protocol & 0x01 ? 8-1:16-1))
|
||||||
{
|
{
|
||||||
FS_flag = 0x10 | ((FS_flag + 2) & 0x0F); //10, 12, 14, 16, 18, 1A, 1C, 1E - failsafe packet
|
FS_flag = 0x10 | ((FS_flag + 2) & 0x0F); //10, 12, 14, 16, 18, 1A, 1C, 1E - failsafe packet
|
||||||
failsafe_chan ++;
|
failsafe_chan ++;
|
||||||
} else if (FS_flag & 0x10)
|
} else if (FS_flag & 0x10)
|
||||||
{
|
{
|
||||||
FS_flag = 0;
|
FS_flag = 0;
|
||||||
failsafe_count = 0;
|
failsafe_count = 0;
|
||||||
|
FAILSAFE_VALUES_off;
|
||||||
}
|
}
|
||||||
failsafe_count++;
|
failsafe_count++;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
packet[0] = (sub_protocol & 0x02 ) ? 0x20 : 0x1D ; // LBT or FCC
|
packet[0] = (sub_protocol & 0x02 ) ? 0x20 : 0x1D ; // LBT or FCC
|
||||||
packet[1] = rx_tx_addr[3];
|
packet[1] = rx_tx_addr[3];
|
||||||
packet[2] = rx_tx_addr[2];
|
packet[2] = rx_tx_addr[2];
|
||||||
packet[3] = 0x02;
|
packet[3] = 0x02;
|
||||||
//
|
//
|
||||||
packet[4] = (FrX_chanskip<<6)|hopping_frequency_no;
|
packet[4] = (FrSkyX_chanskip<<6)|hopping_frequency_no;
|
||||||
packet[5] = FrX_chanskip>>2;
|
packet[5] = FrSkyX_chanskip>>2;
|
||||||
packet[6] = RX_num;
|
packet[6] = RX_num;
|
||||||
//packet[7] = FLAGS 00 - standard packet
|
//packet[7] = FLAGS 00 - standard packet
|
||||||
//10, 12, 14, 16, 18, 1A, 1C, 1E - failsafe packet
|
//10, 12, 14, 16, 18, 1A, 1C, 1E - failsafe packet
|
||||||
@@ -169,78 +99,135 @@ static void __attribute__((unused)) frskyX_data_frame()
|
|||||||
#endif
|
#endif
|
||||||
packet[8] = 0;
|
packet[8] = 0;
|
||||||
//
|
//
|
||||||
uint8_t startChan = chan_offset; for(uint8_t i = 0; i <12 ; i+=3)
|
uint8_t startChan = chan_offset;
|
||||||
|
for(uint8_t i = 0; i <12 ; i+=3)
|
||||||
{//12 bytes of channel data
|
{//12 bytes of channel data
|
||||||
#ifdef FAILSAFE_ENABLE
|
#ifdef FAILSAFE_ENABLE
|
||||||
if( (FS_flag & 0x10) && ((failsafe_chan & 0x07) == (startChan & 0x07)) )
|
if( (FS_flag & 0x10) && ((failsafe_chan & 0x07) == (startChan & 0x07)) )
|
||||||
chan_0 = frskyX_scaleForPXX_FS(failsafe_chan);
|
chan_0 = FrSkyX_scaleForPXX_FS(failsafe_chan);
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
chan_0 = frskyX_scaleForPXX(startChan);
|
chan_0 = FrSkyX_scaleForPXX(startChan);
|
||||||
startChan++;
|
startChan++;
|
||||||
//
|
//
|
||||||
#ifdef FAILSAFE_ENABLE
|
#ifdef FAILSAFE_ENABLE
|
||||||
if( (FS_flag & 0x10) && ((failsafe_chan & 0x07) == (startChan & 0x07)) )
|
if( (FS_flag & 0x10) && ((failsafe_chan & 0x07) == (startChan & 0x07)) )
|
||||||
chan_1 = frskyX_scaleForPXX_FS(failsafe_chan);
|
chan_1 = FrSkyX_scaleForPXX_FS(failsafe_chan);
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
chan_1 = frskyX_scaleForPXX(startChan);
|
chan_1 = FrSkyX_scaleForPXX(startChan);
|
||||||
startChan++;
|
startChan++;
|
||||||
//
|
//
|
||||||
packet[9+i] = lowByte(chan_0); //3 bytes*4
|
packet[9+i] = lowByte(chan_0); //3 bytes*4
|
||||||
packet[9+i+1]=(((chan_0>>8) & 0x0F)|(chan_1 << 4));
|
packet[9+i+1]=(((chan_0>>8) & 0x0F)|(chan_1 << 4));
|
||||||
packet[9+i+2]=chan_1>>4;
|
packet[9+i+2]=chan_1>>4;
|
||||||
}
|
}
|
||||||
packet[21] = (FrX_receive_seq << 4) | FrX_send_seq ;//8 at start
|
if(sub_protocol & 0x01 ) //In X8 mode send only 8ch every 9ms
|
||||||
|
|
||||||
if(sub_protocol & 0x01 ) // in X8 mode send only 8ch every 9ms
|
|
||||||
chan_offset = 0 ;
|
chan_offset = 0 ;
|
||||||
else
|
else
|
||||||
chan_offset^=0x08;
|
chan_offset^=0x08;
|
||||||
|
|
||||||
|
//sequence and send SPort
|
||||||
uint8_t limit = (sub_protocol & 2 ) ? 31 : 28 ;
|
uint8_t limit = (sub_protocol & 2 ) ? 31 : 28 ;
|
||||||
for (uint8_t i=22;i<limit;i++)
|
for (uint8_t i=22;i<limit;i++)
|
||||||
packet[i]=0;
|
packet[i]=0;
|
||||||
#if defined SPORT_POLLING
|
packet[21] = FrSkyX_RX_Seq << 4; //TX=8 at startup
|
||||||
uint8_t idxs=0;
|
#ifdef SPORT_SEND
|
||||||
if(ok_to_send)
|
if (FrSkyX_TX_IN_Seq!=0xFF)
|
||||||
for (uint8_t i=23;i<limit;i++)
|
{//RX has replied at least once
|
||||||
{//
|
if (FrSkyX_TX_IN_Seq & 0x08)
|
||||||
if(sport_index==sport_idx)
|
{//Request init
|
||||||
{//no new data
|
//debugln("Init");
|
||||||
ok_to_send=false;
|
FrSkyX_TX_Seq = 0 ;
|
||||||
break;
|
for(uint8_t i=0;i<4;i++)
|
||||||
}
|
FrSkyX_TX_Frames[i].count=0; //Discard frames in current output buffer
|
||||||
packet[i]=SportData[sport_index];
|
|
||||||
sport_index= (sport_index+1)& (MAX_SPORT_BUFFER-1);
|
|
||||||
idxs++;
|
|
||||||
}
|
}
|
||||||
packet[22]= idxs;
|
else if (FrSkyX_TX_IN_Seq & 0x04)
|
||||||
#ifdef DEBUG_SERIAL
|
{//Retransmit the requested packet
|
||||||
for(uint8_t i=0;i<idxs;i++)
|
debugln("Retry:%d",FrSkyX_TX_IN_Seq&0x03);
|
||||||
|
packet[21] |= FrSkyX_TX_IN_Seq&0x03;
|
||||||
|
packet[22] = FrSkyX_TX_Frames[FrSkyX_TX_IN_Seq&0x03].count;
|
||||||
|
for (uint8_t i=23;i<23+FrSkyX_TX_Frames[FrSkyX_TX_IN_Seq&0x03].count;i++)
|
||||||
|
packet[i] = FrSkyX_TX_Frames[FrSkyX_TX_IN_Seq&0x03].payload[i];
|
||||||
|
}
|
||||||
|
else if ( FrSkyX_TX_Seq != 0x08 )
|
||||||
{
|
{
|
||||||
Serial.print(packet[23+i],HEX);
|
if(FrSkyX_TX_Seq==FrSkyX_TX_IN_Seq)
|
||||||
Serial.print(" ");
|
{//Send packet from the incoming radio buffer
|
||||||
|
//debugln("Send:%d",FrSkyX_TX_Seq);
|
||||||
|
packet[21] |= FrSkyX_TX_Seq;
|
||||||
|
uint8_t nbr_bytes=0;
|
||||||
|
for (uint8_t i=23;i<limit;i++)
|
||||||
|
{
|
||||||
|
if(SportHead==SportTail)
|
||||||
|
break; //buffer empty
|
||||||
|
packet[i]=SportData[SportHead];
|
||||||
|
FrSkyX_TX_Frames[FrSkyX_TX_Seq].payload[i-23]=SportData[SportHead];
|
||||||
|
SportHead=(SportHead+1) & (MAX_SPORT_BUFFER-1);
|
||||||
|
nbr_bytes++;
|
||||||
|
}
|
||||||
|
packet[22]=nbr_bytes;
|
||||||
|
FrSkyX_TX_Frames[FrSkyX_TX_Seq].count=nbr_bytes;
|
||||||
|
if(nbr_bytes)
|
||||||
|
{//Check the buffer status
|
||||||
|
uint8_t used = SportTail;
|
||||||
|
if ( SportHead > SportTail )
|
||||||
|
used += MAX_SPORT_BUFFER - SportHead ;
|
||||||
|
else
|
||||||
|
used -= SportHead ;
|
||||||
|
if ( used < (MAX_SPORT_BUFFER>>1) )
|
||||||
|
{
|
||||||
|
DATA_BUFFER_LOW_off;
|
||||||
|
debugln("Ok buf:%d",used);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FrSkyX_TX_Seq = ( FrSkyX_TX_Seq + 1 ) & 0x03 ; //Next iteration send next packet
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{//Not in sequence somehow, transmit what the receiver wants but why not asking for retransmit...
|
||||||
|
//debugln("RX_Seq:%d,TX:%d",FrSkyX_TX_IN_Seq,FrSkyX_TX_Seq);
|
||||||
|
packet[21] |= FrSkyX_TX_IN_Seq;
|
||||||
|
packet[22] = FrSkyX_TX_Frames[FrSkyX_TX_IN_Seq].count;
|
||||||
|
for (uint8_t i=23;i<23+FrSkyX_TX_Frames[FrSkyX_TX_IN_Seq].count;i++)
|
||||||
|
packet[i] = FrSkyX_TX_Frames[FrSkyX_TX_IN_Seq].payload[i-23];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Serial.println(" ");
|
else
|
||||||
#endif
|
packet[21] |= 0x08 ; //FrSkyX_TX_Seq=8 at startup
|
||||||
#endif // SPORT_POLLING
|
}
|
||||||
|
if(packet[22])
|
||||||
|
{//Debug
|
||||||
|
debug("SP: ");
|
||||||
|
for(uint8_t i=0;i<packet[22];i++)
|
||||||
|
debug("%02X ",packet[23+i]);
|
||||||
|
debugln("");
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
packet[21] |= FrSkyX_TX_Seq ;//TX=8 at startup
|
||||||
|
if ( !(FrSkyX_TX_IN_Seq & 0xF8) )
|
||||||
|
FrSkyX_TX_Seq = ( FrSkyX_TX_Seq + 1 ) & 0x03 ; // Next iteration send next packet
|
||||||
|
#endif // SPORT_SEND
|
||||||
|
|
||||||
uint16_t lcrc = frskyX_crc_x(&packet[3], limit-3);
|
uint16_t lcrc = FrSkyX_crc(&packet[3], limit-3);
|
||||||
packet[limit++]=lcrc>>8;//high byte
|
packet[limit++]=lcrc>>8;//high byte
|
||||||
packet[limit]=lcrc;//low byte
|
packet[limit]=lcrc;//low byte
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t ReadFrSkyX()
|
uint16_t ReadFrSkyX()
|
||||||
{
|
{
|
||||||
|
static bool transmit=true;
|
||||||
|
#ifdef DEBUG_SERIAL
|
||||||
|
static uint16_t fr_time=0;
|
||||||
|
#endif
|
||||||
|
|
||||||
switch(state)
|
switch(state)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
frskyX_set_start(47);
|
FrSkyX_set_start(47);
|
||||||
CC2500_SetPower();
|
CC2500_SetPower();
|
||||||
CC2500_Strobe(CC2500_SFRX);
|
CC2500_Strobe(CC2500_SFRX);
|
||||||
//
|
//
|
||||||
frskyX_build_bind_packet();
|
FrSkyX_build_bind_packet();
|
||||||
CC2500_Strobe(CC2500_SIDLE);
|
CC2500_Strobe(CC2500_SIDLE);
|
||||||
CC2500_WriteData(packet, packet[0]+1);
|
CC2500_WriteData(packet, packet[0]+1);
|
||||||
if(IS_BIND_DONE)
|
if(IS_BIND_DONE)
|
||||||
@@ -249,73 +236,103 @@ uint16_t ReadFrSkyX()
|
|||||||
state++;
|
state++;
|
||||||
return 9000;
|
return 9000;
|
||||||
case FRSKY_BIND_DONE:
|
case FRSKY_BIND_DONE:
|
||||||
frskyX_initialize_data(0);
|
FrSkyX_initialize_data(0);
|
||||||
hopping_frequency_no=0;
|
hopping_frequency_no=0;
|
||||||
BIND_DONE;
|
BIND_DONE;
|
||||||
state++;
|
state++; //FRSKY_DATA1
|
||||||
break;
|
break;
|
||||||
case FRSKY_DATA1:
|
case FRSKY_DATA5:
|
||||||
if ( prev_option != option )
|
#ifdef MULTI_SYNC
|
||||||
{
|
telemetry_set_input_sync(9000);
|
||||||
CC2500_WriteReg(CC2500_0C_FSCTRL0,option); // Frequency offset hack
|
#endif
|
||||||
prev_option = option ;
|
#if defined TELEMETRY
|
||||||
}
|
telemetry_link=1; //Send telemetry out anyway
|
||||||
CC2500_SetTxRxMode(TX_EN);
|
#endif
|
||||||
frskyX_set_start(hopping_frequency_no);
|
|
||||||
CC2500_SetPower();
|
|
||||||
CC2500_Strobe(CC2500_SFRX);
|
|
||||||
hopping_frequency_no = (hopping_frequency_no+FrX_chanskip)%47;
|
|
||||||
CC2500_Strobe(CC2500_SIDLE);
|
|
||||||
CC2500_WriteData(packet, packet[0]+1);
|
|
||||||
//
|
|
||||||
// frskyX_data_frame();
|
|
||||||
state++;
|
|
||||||
return 5200;
|
|
||||||
case FRSKY_DATA2:
|
|
||||||
CC2500_SetTxRxMode(RX_EN);
|
|
||||||
CC2500_Strobe(CC2500_SIDLE);
|
|
||||||
state++;
|
|
||||||
return 200;
|
|
||||||
case FRSKY_DATA3:
|
|
||||||
CC2500_Strobe(CC2500_SRX);
|
|
||||||
state++;
|
|
||||||
return 3100;
|
|
||||||
case FRSKY_DATA4:
|
|
||||||
len = CC2500_ReadReg(CC2500_3B_RXBYTES | CC2500_READ_BURST) & 0x7F;
|
len = CC2500_ReadReg(CC2500_3B_RXBYTES | CC2500_READ_BURST) & 0x7F;
|
||||||
if (len && (len<=(0x0E + 3))) //Telemetry frame is 17
|
if (len && (len<=(0x0E + 3))) //Telemetry frame is 17
|
||||||
{
|
{
|
||||||
packet_count=0;
|
packet_count=0;
|
||||||
CC2500_ReadData(pkt, len);
|
CC2500_ReadData(packet_in, len);
|
||||||
#if defined TELEMETRY
|
#if defined TELEMETRY
|
||||||
frsky_check_telemetry(pkt,len); //check if valid telemetry packets
|
frsky_check_telemetry(packet_in,len); //Check and parse telemetry packets
|
||||||
//parse telemetry packets here
|
|
||||||
//The same telemetry function used by FrSky(D8).
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
packet_count++;
|
packet_count++;
|
||||||
|
//debugln("M %d",packet_count);
|
||||||
// restart sequence on missed packet - might need count or timeout instead of one missed
|
// restart sequence on missed packet - might need count or timeout instead of one missed
|
||||||
if(packet_count>100)
|
if(packet_count>100)
|
||||||
{//~1sec
|
{//~1sec
|
||||||
// seq_last_sent = 0;
|
FrSkyX_TX_Seq = 0x08 ; //Request init
|
||||||
// seq_last_rcvd = 8;
|
FrSkyX_TX_IN_Seq = 0xFF ; //No sequence received yet
|
||||||
FrX_send_seq = 0x08 ;
|
#ifdef SPORT_SEND
|
||||||
// FrX_receive_seq = 0 ;
|
for(uint8_t i=0;i<4;i++)
|
||||||
|
FrSkyX_TX_Frames[i].count=0; //Discard frames in current output buffer
|
||||||
|
#endif
|
||||||
packet_count=0;
|
packet_count=0;
|
||||||
#if defined TELEMETRY
|
#if defined TELEMETRY
|
||||||
telemetry_lost=1;
|
telemetry_lost=1;
|
||||||
|
telemetry_link=0; //Stop sending telemetry
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
CC2500_Strobe(CC2500_SFRX); //flush the RXFIFO
|
CC2500_Strobe(CC2500_SFRX); //Flush the RXFIFO
|
||||||
}
|
|
||||||
frskyX_data_frame();
|
|
||||||
if ( FrX_send_seq != 0x08 )
|
|
||||||
{
|
|
||||||
FrX_send_seq = ( FrX_send_seq + 1 ) & 0x03 ;
|
|
||||||
}
|
}
|
||||||
|
FrSkyX_build_packet();
|
||||||
state = FRSKY_DATA1;
|
state = FRSKY_DATA1;
|
||||||
|
#if not defined(FRSKYX_LBT)
|
||||||
return 500;
|
return 500;
|
||||||
|
#endif // for LBT just continue to DATA1 right away
|
||||||
|
case FRSKY_DATA1:
|
||||||
|
if ( prev_option != option )
|
||||||
|
{
|
||||||
|
CC2500_WriteReg(CC2500_0C_FSCTRL0,option); //Frequency offset hack
|
||||||
|
prev_option = option ;
|
||||||
|
}
|
||||||
|
FrSkyX_set_start(hopping_frequency_no);
|
||||||
|
transmit=true;
|
||||||
|
#ifdef FRSKYX_LBT
|
||||||
|
CC2500_Strobe(CC2500_SIDLE);
|
||||||
|
delayMicroseconds(90); //Wait for the freq to stabilize
|
||||||
|
CC2500_Strobe(CC2500_SRX); //Acquire RSSI
|
||||||
|
state++;
|
||||||
|
return 500;
|
||||||
|
case FRSKY_DATA2:
|
||||||
|
uint8_t rssi;
|
||||||
|
rssi = CC2500_ReadReg(CC2500_34_RSSI | CC2500_READ_BURST); // 0.5 db/count, RSSI value read from the RSSI status register is a 2's complement number
|
||||||
|
if ((sub_protocol & 2) && rssi > 72 && rssi < 128) //LBT and RSSI between -36 and -8.5 dBm
|
||||||
|
{
|
||||||
|
transmit=false;
|
||||||
|
debugln("Busy %d %d",hopping_frequency_no,rssi);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
CC2500_Strobe(CC2500_SIDLE);
|
||||||
|
CC2500_Strobe(CC2500_SFRX);
|
||||||
|
CC2500_SetTxRxMode(TX_EN);
|
||||||
|
CC2500_SetPower();
|
||||||
|
hopping_frequency_no = (hopping_frequency_no+FrSkyX_chanskip)%47;
|
||||||
|
if(transmit)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_SERIAL
|
||||||
|
uint16_t fr_cur=millis();
|
||||||
|
fr_time=fr_cur-fr_time;
|
||||||
|
if(fr_time!=9)
|
||||||
|
debugln("Bad timing: %d",fr_time);
|
||||||
|
fr_time=fr_cur;
|
||||||
|
#endif
|
||||||
|
CC2500_WriteData(packet, packet[0]+1);
|
||||||
|
}
|
||||||
|
state=FRSKY_DATA3;
|
||||||
|
return 5200;
|
||||||
|
case FRSKY_DATA3:
|
||||||
|
CC2500_SetTxRxMode(RX_EN);
|
||||||
|
CC2500_Strobe(CC2500_SIDLE);
|
||||||
|
state++;
|
||||||
|
return 200;
|
||||||
|
case FRSKY_DATA4:
|
||||||
|
CC2500_Strobe(CC2500_SRX);
|
||||||
|
state++;
|
||||||
|
return 3100;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -325,34 +342,34 @@ uint16_t initFrSkyX()
|
|||||||
set_rx_tx_addr(MProtocol_id_master);
|
set_rx_tx_addr(MProtocol_id_master);
|
||||||
Frsky_init_hop();
|
Frsky_init_hop();
|
||||||
packet_count=0;
|
packet_count=0;
|
||||||
while(!FrX_chanskip)
|
while(!FrSkyX_chanskip)
|
||||||
FrX_chanskip=random(0xfefefefe)%47;
|
FrSkyX_chanskip=random(0xfefefefe)%47;
|
||||||
|
|
||||||
//for test***************
|
//for test***************
|
||||||
//rx_tx_addr[3]=0xB3;
|
//rx_tx_addr[3]=0xB3;
|
||||||
//rx_tx_addr[2]=0xFD;
|
//rx_tx_addr[2]=0xFD;
|
||||||
//************************
|
//************************
|
||||||
frskyX_init();
|
FrSkyX_init();
|
||||||
#if defined SPORT_POLLING
|
|
||||||
#ifdef INVERT_SERIAL
|
|
||||||
start_timer4() ;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
//
|
|
||||||
if(IS_BIND_IN_PROGRESS)
|
if(IS_BIND_IN_PROGRESS)
|
||||||
{
|
{
|
||||||
state = FRSKY_BIND;
|
state = FRSKY_BIND;
|
||||||
frskyX_initialize_data(1);
|
FrSkyX_initialize_data(1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
state = FRSKY_DATA1;
|
state = FRSKY_DATA1;
|
||||||
frskyX_initialize_data(0);
|
FrSkyX_initialize_data(0);
|
||||||
}
|
}
|
||||||
// seq_last_sent = 0;
|
FrSkyX_TX_Seq = 0x08 ; // Request init
|
||||||
// seq_last_rcvd = 8;
|
FrSkyX_TX_IN_Seq = 0xFF ; // No sequence received yet
|
||||||
FrX_send_seq = 0x08 ;
|
#ifdef SPORT_SEND
|
||||||
FrX_receive_seq = 0 ;
|
for(uint8_t i=0;i<4;i++)
|
||||||
|
FrSkyX_TX_Frames[i].count=0; // discard frames in current output buffer
|
||||||
|
SportHead=SportTail=0; // empty data buffer
|
||||||
|
#endif
|
||||||
|
FrSkyX_RX_Seq = 0 ; // Seq 0 to start with
|
||||||
|
binding_idx=0; // CH1-8 and Telem on
|
||||||
return 10000;
|
return 10000;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
454
Multiprotocol/FrSky_Rx_cc2500.ino
Normal file
@@ -0,0 +1,454 @@
|
|||||||
|
/*
|
||||||
|
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(FRSKY_RX_CC2500_INO)
|
||||||
|
|
||||||
|
#include "iface_cc2500.h"
|
||||||
|
|
||||||
|
#define FRSKY_RX_D16FCC_LENGTH 32
|
||||||
|
#define FRSKY_RX_D16LBT_LENGTH 35
|
||||||
|
#define FRSKY_RX_D8_LENGTH 20
|
||||||
|
#define FRSKY_RX_FORMATS 3
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
FRSKY_RX_D16FCC = 0,
|
||||||
|
FRSKY_RX_D16LBT,
|
||||||
|
FRSKY_RX_D8
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
FRSKY_RX_TUNE_START,
|
||||||
|
FRSKY_RX_TUNE_LOW,
|
||||||
|
FRSKY_RX_TUNE_HIGH,
|
||||||
|
FRSKY_RX_BIND,
|
||||||
|
FRSKY_RX_DATA,
|
||||||
|
};
|
||||||
|
|
||||||
|
const PROGMEM uint8_t frsky_rx_common_reg[][2] = {
|
||||||
|
{CC2500_02_IOCFG0, 0x01},
|
||||||
|
{CC2500_18_MCSM0, 0x18},
|
||||||
|
{CC2500_07_PKTCTRL1, 0x04},
|
||||||
|
{CC2500_3E_PATABLE, 0xFF},
|
||||||
|
{CC2500_0C_FSCTRL0, 0},
|
||||||
|
{CC2500_0D_FREQ2, 0x5C},
|
||||||
|
{CC2500_13_MDMCFG1, 0x23},
|
||||||
|
{CC2500_14_MDMCFG0, 0x7A},
|
||||||
|
{CC2500_19_FOCCFG, 0x16},
|
||||||
|
{CC2500_1A_BSCFG, 0x6C},
|
||||||
|
{CC2500_1B_AGCCTRL2, 0x03},
|
||||||
|
{CC2500_1C_AGCCTRL1, 0x40},
|
||||||
|
{CC2500_1D_AGCCTRL0, 0x91},
|
||||||
|
{CC2500_21_FREND1, 0x56},
|
||||||
|
{CC2500_22_FREND0, 0x10},
|
||||||
|
{CC2500_23_FSCAL3, 0xA9},
|
||||||
|
{CC2500_24_FSCAL2, 0x0A},
|
||||||
|
{CC2500_25_FSCAL1, 0x00},
|
||||||
|
{CC2500_26_FSCAL0, 0x11},
|
||||||
|
{CC2500_29_FSTEST, 0x59},
|
||||||
|
{CC2500_2C_TEST2, 0x88},
|
||||||
|
{CC2500_2D_TEST1, 0x31},
|
||||||
|
{CC2500_2E_TEST0, 0x0B},
|
||||||
|
{CC2500_03_FIFOTHR, 0x07},
|
||||||
|
{CC2500_09_ADDR, 0x00},
|
||||||
|
};
|
||||||
|
|
||||||
|
const PROGMEM uint8_t frsky_rx_d16fcc_reg[][2] = {
|
||||||
|
{CC2500_17_MCSM1, 0x0C},
|
||||||
|
{CC2500_0E_FREQ1, 0x76},
|
||||||
|
{CC2500_0F_FREQ0, 0x27},
|
||||||
|
{CC2500_06_PKTLEN, 0x1E},
|
||||||
|
{CC2500_08_PKTCTRL0, 0x01},
|
||||||
|
{CC2500_0B_FSCTRL1, 0x0A},
|
||||||
|
{CC2500_10_MDMCFG4, 0x7B},
|
||||||
|
{CC2500_11_MDMCFG3, 0x61},
|
||||||
|
{CC2500_12_MDMCFG2, 0x13},
|
||||||
|
{CC2500_15_DEVIATN, 0x51},
|
||||||
|
};
|
||||||
|
|
||||||
|
const PROGMEM uint8_t frsky_rx_d16lbt_reg[][2] = {
|
||||||
|
{CC2500_17_MCSM1, 0x0E},
|
||||||
|
{CC2500_0E_FREQ1, 0x80},
|
||||||
|
{CC2500_0F_FREQ0, 0x00},
|
||||||
|
{CC2500_06_PKTLEN, 0x23},
|
||||||
|
{CC2500_08_PKTCTRL0, 0x01},
|
||||||
|
{CC2500_0B_FSCTRL1, 0x08},
|
||||||
|
{CC2500_10_MDMCFG4, 0x7B},
|
||||||
|
{CC2500_11_MDMCFG3, 0xF8},
|
||||||
|
{CC2500_12_MDMCFG2, 0x03},
|
||||||
|
{CC2500_15_DEVIATN, 0x53},
|
||||||
|
};
|
||||||
|
|
||||||
|
const PROGMEM uint8_t frsky_rx_d8_reg[][2] = {
|
||||||
|
{CC2500_17_MCSM1, 0x0C},
|
||||||
|
{CC2500_0E_FREQ1, 0x76},
|
||||||
|
{CC2500_0F_FREQ0, 0x27},
|
||||||
|
{CC2500_06_PKTLEN, 0x19},
|
||||||
|
{CC2500_08_PKTCTRL0, 0x05},
|
||||||
|
{CC2500_0B_FSCTRL1, 0x08},
|
||||||
|
{CC2500_10_MDMCFG4, 0xAA},
|
||||||
|
{CC2500_11_MDMCFG3, 0x39},
|
||||||
|
{CC2500_12_MDMCFG2, 0x11},
|
||||||
|
{CC2500_15_DEVIATN, 0x42},
|
||||||
|
};
|
||||||
|
|
||||||
|
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()
|
||||||
|
{
|
||||||
|
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_D16FCC_LENGTH, FRSKY_RX_D16LBT_LENGTH, FRSKY_RX_D8_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]));
|
||||||
|
|
||||||
|
switch (frsky_rx_format) {
|
||||||
|
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]));
|
||||||
|
break;
|
||||||
|
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]));
|
||||||
|
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]));
|
||||||
|
CC2500_WriteReg(CC2500_07_PKTCTRL1, 0x05); // always check address
|
||||||
|
CC2500_WriteReg(CC2500_09_ADDR, 0x03); // bind address
|
||||||
|
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();
|
||||||
|
delayMicroseconds(1000); // wait for RX to activate
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
CC2500_WriteReg(CC2500_23_FSCAL3, 0x89);
|
||||||
|
CC2500_WriteReg(CC2500_25_FSCAL1, calData[channel]);
|
||||||
|
frsky_rx_strobe_rx();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __attribute__((unused)) frsky_rx_calibrate()
|
||||||
|
{
|
||||||
|
frsky_rx_strobe_rx();
|
||||||
|
for (unsigned c = 0; c < 47; c++)
|
||||||
|
{
|
||||||
|
CC2500_Strobe(CC2500_SIDLE);
|
||||||
|
CC2500_WriteReg(CC2500_0A_CHANNR, hopping_frequency[c]);
|
||||||
|
CC2500_Strobe(CC2500_SCAL);
|
||||||
|
delayMicroseconds(900);
|
||||||
|
calData[c] = CC2500_ReadReg(CC2500_25_FSCAL1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t __attribute__((unused)) frskyx_rx_check_crc()
|
||||||
|
{
|
||||||
|
// check D8 checksum
|
||||||
|
if (frsky_rx_format == FRSKY_RX_D8)
|
||||||
|
return (packet[packet_length-1] & 0x80) == 0x80; // check CRC_OK flag in status byte 2
|
||||||
|
// check D16 checksum
|
||||||
|
uint8_t limit = packet_length - 4;
|
||||||
|
uint16_t lcrc = FrSkyX_crc(&packet[3], limit - 3); // computed crc
|
||||||
|
uint16_t rcrc = (packet[limit] << 8) | (packet[limit + 1] & 0xff); // received crc
|
||||||
|
return lcrc == rcrc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __attribute__((unused)) frsky_rx_build_telemetry_packet()
|
||||||
|
{
|
||||||
|
uint16_t raw_channel[8];
|
||||||
|
uint32_t bits = 0;
|
||||||
|
uint8_t bitsavailable = 0;
|
||||||
|
uint8_t idx = 0;
|
||||||
|
uint8_t i;
|
||||||
|
|
||||||
|
if (frsky_rx_format == FRSKY_RX_D16FCC || frsky_rx_format == FRSKY_RX_D16LBT) {
|
||||||
|
// decode D16 channels
|
||||||
|
raw_channel[0] = ((packet[10] << 8) & 0xF00) | packet[9];
|
||||||
|
raw_channel[1] = ((packet[11] << 4) & 0xFF0) | (packet[10] >> 4);
|
||||||
|
raw_channel[2] = ((packet[13] << 8) & 0xF00) | packet[12];
|
||||||
|
raw_channel[3] = ((packet[14] << 4) & 0xFF0) | (packet[13] >> 4);
|
||||||
|
raw_channel[4] = ((packet[16] << 8) & 0xF00) | packet[15];
|
||||||
|
raw_channel[5] = ((packet[17] << 4) & 0xFF0) | (packet[16] >> 4);
|
||||||
|
raw_channel[6] = ((packet[19] << 8) & 0xF00) | packet[18];
|
||||||
|
raw_channel[7] = ((packet[20] << 4) & 0xFF0) | (packet[19] >> 4);
|
||||||
|
for (i = 0; i < 8; i++) {
|
||||||
|
// ignore failsafe channels
|
||||||
|
if(packet[7] != 0x10+(i<<1)) {
|
||||||
|
uint8_t shifted = (raw_channel[i] & 0x800)>0;
|
||||||
|
uint16_t channel_value = raw_channel[i] & 0x7FF;
|
||||||
|
if (channel_value < 64)
|
||||||
|
rx_rc_chan[shifted ? i + 8 : i] = 0;
|
||||||
|
else
|
||||||
|
rx_rc_chan[shifted ? i + 8 : i] = min(((channel_value - 64) << 4) / 15, 2047);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// decode D8 channels
|
||||||
|
raw_channel[0] = ((packet[10] & 0x0F) << 8 | packet[6]);
|
||||||
|
raw_channel[1] = ((packet[10] & 0xF0) << 4 | packet[7]);
|
||||||
|
raw_channel[2] = ((packet[11] & 0x0F) << 8 | packet[8]);
|
||||||
|
raw_channel[3] = ((packet[11] & 0xF0) << 4 | packet[9]);
|
||||||
|
raw_channel[4] = ((packet[16] & 0x0F) << 8 | packet[12]);
|
||||||
|
raw_channel[5] = ((packet[16] & 0xF0) << 4 | packet[13]);
|
||||||
|
raw_channel[6] = ((packet[17] & 0x0F) << 8 | packet[14]);
|
||||||
|
raw_channel[7] = ((packet[17] & 0xF0) << 4 | packet[15]);
|
||||||
|
for (i = 0; i < 8; i++) {
|
||||||
|
if (raw_channel[i] < 1290)
|
||||||
|
raw_channel[i] = 1290;
|
||||||
|
rx_rc_chan[i] = min(((raw_channel[i] - 1290) << 4) / 15, 2047);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// buid 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
|
||||||
|
|
||||||
|
// pack channels
|
||||||
|
for (i = 0; i < packet_in[3]; i++) {
|
||||||
|
bits |= ((uint32_t)rx_rc_chan[i]) << bitsavailable;
|
||||||
|
bitsavailable += 11;
|
||||||
|
while (bitsavailable >= 8) {
|
||||||
|
packet_in[idx++] = bits & 0xff;
|
||||||
|
bits >>= 8;
|
||||||
|
bitsavailable -= 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t initFrSky_Rx()
|
||||||
|
{
|
||||||
|
state = 0;
|
||||||
|
frsky_rx_chanskip = 1;
|
||||||
|
hopping_frequency_no = 0;
|
||||||
|
rx_data_started = false;
|
||||||
|
frsky_rx_finetune = 0;
|
||||||
|
telemetry_link = 0;
|
||||||
|
if (IS_BIND_IN_PROGRESS) {
|
||||||
|
frsky_rx_format = FRSKY_RX_D8;
|
||||||
|
frsky_rx_initialise_cc2500();
|
||||||
|
phase = FRSKY_RX_TUNE_START;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
uint16_t temp = FRSKY_RX_EEPROM_OFFSET;
|
||||||
|
frsky_rx_format = eeprom_read_byte((EE_ADDR)temp++) % FRSKY_RX_FORMATS;
|
||||||
|
rx_tx_addr[0] = eeprom_read_byte((EE_ADDR)temp++);
|
||||||
|
rx_tx_addr[1] = eeprom_read_byte((EE_ADDR)temp++);
|
||||||
|
rx_tx_addr[2] = eeprom_read_byte((EE_ADDR)temp++);
|
||||||
|
frsky_rx_finetune = eeprom_read_byte((EE_ADDR)temp++);
|
||||||
|
for (uint8_t ch = 0; ch < 47; ch++)
|
||||||
|
hopping_frequency[ch] = eeprom_read_byte((EE_ADDR)temp++);
|
||||||
|
frsky_rx_initialise_cc2500();
|
||||||
|
frsky_rx_calibrate();
|
||||||
|
CC2500_WriteReg(CC2500_18_MCSM0, 0x08); // FS_AUTOCAL = manual
|
||||||
|
CC2500_WriteReg(CC2500_09_ADDR, rx_tx_addr[0]); // set address
|
||||||
|
CC2500_WriteReg(CC2500_07_PKTCTRL1, 0x05); // check address
|
||||||
|
if (option == 0)
|
||||||
|
CC2500_WriteReg(CC2500_0C_FSCTRL0, frsky_rx_finetune);
|
||||||
|
else
|
||||||
|
CC2500_WriteReg(CC2500_0C_FSCTRL0, option);
|
||||||
|
frsky_rx_set_channel(hopping_frequency_no);
|
||||||
|
phase = FRSKY_RX_DATA;
|
||||||
|
}
|
||||||
|
return 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t FrSky_Rx_callback()
|
||||||
|
{
|
||||||
|
static uint32_t pps_timer=0;
|
||||||
|
static uint8_t pps_counter=0;
|
||||||
|
static int8_t read_retry = 0;
|
||||||
|
static int8_t tune_low, tune_high;
|
||||||
|
uint8_t len, ch;
|
||||||
|
|
||||||
|
if ((prev_option != option) && (phase >= FRSKY_RX_DATA)) {
|
||||||
|
if (option == 0)
|
||||||
|
CC2500_WriteReg(CC2500_0C_FSCTRL0, frsky_rx_finetune);
|
||||||
|
else
|
||||||
|
CC2500_WriteReg(CC2500_0C_FSCTRL0, option);
|
||||||
|
prev_option = option;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rx_disable_lna != IS_POWER_FLAG_on) {
|
||||||
|
rx_disable_lna = IS_POWER_FLAG_on;
|
||||||
|
CC2500_SetTxRxMode(rx_disable_lna ? TXRX_OFF : RX_EN);
|
||||||
|
}
|
||||||
|
|
||||||
|
len = CC2500_ReadReg(CC2500_3B_RXBYTES | CC2500_READ_BURST) & 0x7F;
|
||||||
|
|
||||||
|
switch(phase) {
|
||||||
|
case FRSKY_RX_TUNE_START:
|
||||||
|
if (len >= packet_length) {
|
||||||
|
CC2500_ReadData(packet, packet_length);
|
||||||
|
if(packet[1] == 0x03 && packet[2] == 0x01 && frskyx_rx_check_crc()) {
|
||||||
|
rx_tx_addr[0] = packet[3]; // TXID
|
||||||
|
rx_tx_addr[1] = packet[4]; // TXID
|
||||||
|
frsky_rx_finetune = -127;
|
||||||
|
CC2500_WriteReg(CC2500_0C_FSCTRL0, frsky_rx_finetune);
|
||||||
|
phase = FRSKY_RX_TUNE_LOW;
|
||||||
|
frsky_rx_strobe_rx();
|
||||||
|
return 1000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
frsky_rx_format = (frsky_rx_format + 1) % FRSKY_RX_FORMATS; // switch to next format (D16FCC, D16LBT, D8)
|
||||||
|
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:
|
||||||
|
if (len >= packet_length) {
|
||||||
|
CC2500_ReadData(packet, packet_length);
|
||||||
|
if(packet[1] == 0x03 && packet[2] == 0x01 && frskyx_rx_check_crc() && packet[3] == rx_tx_addr[0] && packet[4] == rx_tx_addr[1]) {
|
||||||
|
tune_low = frsky_rx_finetune;
|
||||||
|
frsky_rx_finetune = 127;
|
||||||
|
CC2500_WriteReg(CC2500_0C_FSCTRL0, frsky_rx_finetune);
|
||||||
|
phase = FRSKY_RX_TUNE_HIGH;
|
||||||
|
frsky_rx_strobe_rx();
|
||||||
|
return 1000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
frsky_rx_finetune += 1;
|
||||||
|
CC2500_WriteReg(CC2500_0C_FSCTRL0, frsky_rx_finetune);
|
||||||
|
frsky_rx_strobe_rx();
|
||||||
|
return 18000;
|
||||||
|
|
||||||
|
case FRSKY_RX_TUNE_HIGH:
|
||||||
|
if (len >= packet_length) {
|
||||||
|
CC2500_ReadData(packet, packet_length);
|
||||||
|
if(packet[1] == 0x03 && packet[2] == 0x01 && frskyx_rx_check_crc() && packet[3] == rx_tx_addr[0] && packet[4] == rx_tx_addr[1]) {
|
||||||
|
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;
|
||||||
|
else
|
||||||
|
phase = FRSKY_RX_TUNE_START;
|
||||||
|
frsky_rx_strobe_rx();
|
||||||
|
return 1000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
frsky_rx_finetune -= 1;
|
||||||
|
CC2500_WriteReg(CC2500_0C_FSCTRL0, frsky_rx_finetune);
|
||||||
|
frsky_rx_strobe_rx();
|
||||||
|
return 18000;
|
||||||
|
|
||||||
|
case FRSKY_RX_BIND:
|
||||||
|
if(len >= packet_length) {
|
||||||
|
CC2500_ReadData(packet, packet_length);
|
||||||
|
if(packet[1] == 0x03 && packet[2] == 0x01 && frskyx_rx_check_crc() && packet[3] == rx_tx_addr[0] && packet[4] == rx_tx_addr[1] && packet[5] <= 0x2D) {
|
||||||
|
for (ch = 0; ch < 5; ch++)
|
||||||
|
hopping_frequency[packet[5]+ch] = packet[6+ch];
|
||||||
|
state |= 1 << (packet[5] / 5);
|
||||||
|
if (state == 0x3ff) {
|
||||||
|
debug("Bind complete: ");
|
||||||
|
frsky_rx_calibrate();
|
||||||
|
rx_tx_addr[2] = packet[12]; // RX # (D16)
|
||||||
|
CC2500_WriteReg(CC2500_18_MCSM0, 0x08); // FS_AUTOCAL = manual
|
||||||
|
CC2500_WriteReg(CC2500_09_ADDR, rx_tx_addr[0]); // set address
|
||||||
|
CC2500_WriteReg(CC2500_07_PKTCTRL1, 0x05); // check address
|
||||||
|
phase = FRSKY_RX_DATA;
|
||||||
|
frsky_rx_set_channel(hopping_frequency_no);
|
||||||
|
// store format, finetune setting, txid, channel list
|
||||||
|
uint16_t temp = FRSKY_RX_EEPROM_OFFSET;
|
||||||
|
eeprom_write_byte((EE_ADDR)temp++, frsky_rx_format);
|
||||||
|
debug("format=%d, ", frsky_rx_format);
|
||||||
|
eeprom_write_byte((EE_ADDR)temp++, rx_tx_addr[0]);
|
||||||
|
debug("addr[0]=%02X, ", rx_tx_addr[0]);
|
||||||
|
eeprom_write_byte((EE_ADDR)temp++, rx_tx_addr[1]);
|
||||||
|
debug("addr[1]=%02X, ", rx_tx_addr[1]);
|
||||||
|
eeprom_write_byte((EE_ADDR)temp++, rx_tx_addr[2]);
|
||||||
|
debug("rx_num=%02X, ", rx_tx_addr[2]);
|
||||||
|
eeprom_write_byte((EE_ADDR)temp++, frsky_rx_finetune);
|
||||||
|
debugln("tune=%d", (int8_t)frsky_rx_finetune);
|
||||||
|
for (ch = 0; ch < 47; ch++)
|
||||||
|
{
|
||||||
|
eeprom_write_byte((EE_ADDR)temp++, hopping_frequency[ch]);
|
||||||
|
debug("%02X ", hopping_frequency[ch]);
|
||||||
|
}
|
||||||
|
debugln("");
|
||||||
|
BIND_DONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
frsky_rx_strobe_rx();
|
||||||
|
}
|
||||||
|
return 1000;
|
||||||
|
|
||||||
|
case FRSKY_RX_DATA:
|
||||||
|
if (len >= packet_length) {
|
||||||
|
CC2500_ReadData(packet, packet_length);
|
||||||
|
if (packet[1] == rx_tx_addr[0] && packet[2] == rx_tx_addr[1] && frskyx_rx_check_crc() && (frsky_rx_format == FRSKY_RX_D8 || packet[6] == rx_tx_addr[2])) {
|
||||||
|
RX_RSSI = packet[packet_length-2];
|
||||||
|
if(RX_RSSI >= 128)
|
||||||
|
RX_RSSI -= 128;
|
||||||
|
else
|
||||||
|
RX_RSSI += 128;
|
||||||
|
// hop to next channel
|
||||||
|
if (frsky_rx_format == FRSKY_RX_D16FCC || frsky_rx_format == FRSKY_RX_D16LBT)
|
||||||
|
frsky_rx_chanskip = ((packet[4] & 0xC0) >> 6) | ((packet[5] & 0x3F) << 2);
|
||||||
|
hopping_frequency_no = (hopping_frequency_no + frsky_rx_chanskip) % 47;
|
||||||
|
frsky_rx_set_channel(hopping_frequency_no);
|
||||||
|
if (telemetry_link == 0) { // send channels to TX
|
||||||
|
frsky_rx_build_telemetry_packet();
|
||||||
|
telemetry_link = 1;
|
||||||
|
}
|
||||||
|
rx_data_started = true;
|
||||||
|
read_retry = 0;
|
||||||
|
pps_counter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// packets per second
|
||||||
|
if (millis() - pps_timer >= 1000) {
|
||||||
|
pps_timer = millis();
|
||||||
|
debugln("%d pps", pps_counter);
|
||||||
|
RX_LQI = pps_counter;
|
||||||
|
pps_counter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
if(rx_data_started)
|
||||||
|
read_retry = 0;
|
||||||
|
else
|
||||||
|
read_retry = -50; // retry longer until first packet is catched
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -16,7 +16,7 @@ Multiprotocol is distributed in the hope that it will be useful,
|
|||||||
|
|
||||||
#if defined(GD00X_NRF24L01_INO)
|
#if defined(GD00X_NRF24L01_INO)
|
||||||
|
|
||||||
#include "iface_xn297l.h"
|
#include "iface_nrf250k.h"
|
||||||
|
|
||||||
//#define FORCE_GD00X_ORIGINAL_ID
|
//#define FORCE_GD00X_ORIGINAL_ID
|
||||||
|
|
||||||
@@ -208,6 +208,9 @@ uint16_t GD00X_callback()
|
|||||||
if(--bind_counter==0)
|
if(--bind_counter==0)
|
||||||
BIND_DONE;
|
BIND_DONE;
|
||||||
GD00X_send_packet();
|
GD00X_send_packet();
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(packet_period);
|
||||||
|
#endif
|
||||||
return packet_period;
|
return packet_period;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -139,6 +139,9 @@ uint16_t GW008_callback()
|
|||||||
return 5000;
|
return 5000;
|
||||||
break;
|
break;
|
||||||
case GW008_DATA:
|
case GW008_DATA:
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(GW008_PACKET_PERIOD);
|
||||||
|
#endif
|
||||||
GW008_send_packet(0);
|
GW008_send_packet(0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -177,7 +177,12 @@ static void __attribute__((unused)) H8_3D_init()
|
|||||||
uint16_t H8_3D_callback()
|
uint16_t H8_3D_callback()
|
||||||
{
|
{
|
||||||
if(IS_BIND_DONE)
|
if(IS_BIND_DONE)
|
||||||
|
{
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(packet_period);
|
||||||
|
#endif
|
||||||
H8_3D_send_packet(0);
|
H8_3D_send_packet(0);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (bind_counter == 0)
|
if (bind_counter == 0)
|
||||||
|
|||||||
387
Multiprotocol/HOTT_cc2500.ino
Normal file
@@ -0,0 +1,387 @@
|
|||||||
|
/*
|
||||||
|
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(HOTT_CC2500_INO)
|
||||||
|
|
||||||
|
#include "iface_cc2500.h"
|
||||||
|
|
||||||
|
//#define HOTT_FORCE_ID // Force ID of original dump
|
||||||
|
|
||||||
|
#define HOTT_TX_PACKET_LEN 50
|
||||||
|
#define HOTT_RX_PACKET_LEN 22
|
||||||
|
#define HOTT_PACKET_PERIOD 10000
|
||||||
|
#define HOTT_NUM_RF_CHANNELS 75
|
||||||
|
#define HOTT_COARSE 0
|
||||||
|
|
||||||
|
enum {
|
||||||
|
HOTT_START = 0x00,
|
||||||
|
HOTT_CAL = 0x01,
|
||||||
|
HOTT_DATA1 = 0x02,
|
||||||
|
HOTT_RX1 = 0x03,
|
||||||
|
HOTT_RX2 = 0x04,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define HOTT_FREQ0_VAL 0x6E
|
||||||
|
|
||||||
|
// Some important initialization parameters, all others are either default,
|
||||||
|
// or not important in the context of transmitter
|
||||||
|
// FIFOTHR 00
|
||||||
|
// SYNC1 D3
|
||||||
|
// SYNC0 91
|
||||||
|
// PKTLEN 32 - Packet length, 50 bytes
|
||||||
|
// PKTCTRL1 04 - APPEND_STATUS on=RSSI+LQI, all other are receive parameters - irrelevant
|
||||||
|
// PKTCTRL0 44 - whitening, use FIFO, use CRC, fixed packet length
|
||||||
|
// ADDR 00
|
||||||
|
// CHANNR 10
|
||||||
|
// FSCTRL1 09 - IF
|
||||||
|
// FSCTRL0 00 - zero freq offset
|
||||||
|
// FREQ2 5C - synthesizer frequencyfor 26MHz crystal
|
||||||
|
// FREQ1 6C
|
||||||
|
// FREQ0 B9
|
||||||
|
// MDMCFG4 2D -
|
||||||
|
// MDMCFG3 3B -
|
||||||
|
// MDMCFG2 73 - disable DC blocking, MSK, no Manchester code, 32 bits sync word
|
||||||
|
// MDMCFG1 A3 - FEC enable, 4 preamble bytes, CHANSPC_E - 03
|
||||||
|
// MDMCFG0 AA - CHANSPC_M - AA
|
||||||
|
// DEVIATN 47 -
|
||||||
|
// MCSM2 07 -
|
||||||
|
// MCSM1 00 - always use CCA, go to IDLE when done
|
||||||
|
// MCSM0 08 - disable autocalibration, PO_TIMEOUT - 64, no pin radio control, no forcing XTAL to stay in SLEEP
|
||||||
|
// FOCCFG 1D
|
||||||
|
const PROGMEM uint8_t HOTT_init_values[] = {
|
||||||
|
/* 00 */ 0x2F, 0x2E, 0x2F, 0x00, 0xD3, 0x91, 0x32, 0x04,
|
||||||
|
/* 08 */ 0x44, 0x00, 0x00, 0x09, 0x00, 0x5C, 0x6C, HOTT_FREQ0_VAL + HOTT_COARSE,
|
||||||
|
/* 10 */ 0x2D, 0x3B, 0x73, 0xA3, 0xAA, 0x47, 0x07, 0x00,
|
||||||
|
/* 18 */ 0x08, 0x1D, 0x1C, 0xC7, 0x09, 0xF0, 0x87, 0x6B,
|
||||||
|
/* 20 */ 0xF0, 0xB6, 0x10, 0xEA, 0x0A, 0x00, 0x11
|
||||||
|
};
|
||||||
|
|
||||||
|
static void __attribute__((unused)) HOTT_rf_init()
|
||||||
|
{
|
||||||
|
CC2500_Strobe(CC2500_SIDLE);
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < 39; ++i)
|
||||||
|
CC2500_WriteReg(i, pgm_read_byte_near(&HOTT_init_values[i]));
|
||||||
|
|
||||||
|
prev_option = option;
|
||||||
|
CC2500_WriteReg(CC2500_0C_FSCTRL0, option);
|
||||||
|
|
||||||
|
CC2500_SetTxRxMode(TX_EN);
|
||||||
|
CC2500_SetPower();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __attribute__((unused)) HOTT_tune_chan()
|
||||||
|
{
|
||||||
|
CC2500_Strobe(CC2500_SIDLE);
|
||||||
|
CC2500_WriteReg(CC2500_0A_CHANNR, (rf_ch_num+1)*3);
|
||||||
|
CC2500_Strobe(CC2500_SCAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __attribute__((unused)) HOTT_tune_chan_fast()
|
||||||
|
{
|
||||||
|
CC2500_Strobe(CC2500_SIDLE);
|
||||||
|
CC2500_WriteReg(CC2500_0A_CHANNR, (rf_ch_num+1)*3);
|
||||||
|
CC2500_WriteReg(CC2500_25_FSCAL1, calData[rf_ch_num]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __attribute__((unused)) HOTT_tune_freq()
|
||||||
|
{
|
||||||
|
if ( prev_option != option )
|
||||||
|
{
|
||||||
|
CC2500_WriteReg(CC2500_0C_FSCTRL0, option);
|
||||||
|
CC2500_WriteReg(CC2500_0F_FREQ0, HOTT_FREQ0_VAL + HOTT_COARSE);
|
||||||
|
prev_option = option ;
|
||||||
|
phase = HOTT_START; // Restart the tune process if option is changed to get good tuned values
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint8_t PROGMEM HOTT_hop[][HOTT_NUM_RF_CHANNELS]=
|
||||||
|
{ { 48, 37, 16, 62, 9, 50, 42, 22, 68, 0, 55, 35, 21, 74, 1, 56, 31, 20, 70, 11, 45, 32, 24, 71, 8, 54, 38, 26, 61, 13, 53, 30, 15, 65, 7, 52, 34, 28, 60, 3, 47, 39, 18, 69, 2, 49, 44, 23, 72, 5, 51, 43, 19, 64, 12, 46, 33, 17, 67, 6, 58, 36, 29, 73, 14, 57, 41, 25, 63, 4, 59, 40, 27, 66, 10 },
|
||||||
|
{ 50, 23, 5, 34, 67, 53, 22, 12, 39, 62, 51, 21, 10, 33, 63, 59, 16, 1, 43, 66, 49, 19, 8, 30, 71, 47, 24, 2, 35, 68, 45, 25, 14, 41, 74, 55, 18, 4, 32, 61, 54, 17, 11, 31, 72, 52, 28, 6, 38, 65, 46, 15, 9, 40, 60, 48, 26, 3, 37, 70, 58, 29, 0, 36, 64, 56, 20, 7, 42, 69, 57, 27, 13, 44, 73 },
|
||||||
|
{ 73, 51, 39, 18, 9, 64, 56, 34, 16, 12, 66, 58, 36, 25, 11, 61, 47, 40, 15, 8, 71, 50, 43, 20, 6, 62, 54, 42, 19, 3, 63, 46, 44, 29, 14, 72, 49, 33, 22, 5, 69, 57, 30, 21, 10, 70, 45, 35, 26, 7, 65, 59, 31, 28, 1, 67, 48, 32, 24, 0, 60, 55, 41, 17, 2, 74, 52, 38, 27, 4, 68, 53, 37, 23, 13 },
|
||||||
|
{ 52, 60, 40, 21, 14, 50, 72, 41, 23, 13, 59, 61, 39, 16, 6, 58, 66, 33, 17, 5, 55, 64, 43, 20, 12, 54, 74, 35, 29, 3, 46, 63, 37, 22, 10, 48, 65, 31, 27, 9, 49, 73, 38, 24, 11, 56, 70, 32, 15, 1, 51, 71, 44, 18, 8, 45, 67, 36, 25, 7, 57, 62, 34, 28, 2, 53, 69, 42, 19, 4, 47, 68, 30, 26, 0 },
|
||||||
|
{ 50, 16, 34, 6, 71, 51, 24, 40, 7, 68, 57, 27, 33, 14, 70, 55, 26, 30, 5, 74, 47, 28, 44, 11, 67, 49, 15, 32, 9, 61, 52, 22, 37, 13, 66, 59, 18, 42, 3, 62, 46, 29, 31, 12, 60, 48, 19, 38, 1, 72, 58, 17, 36, 4, 64, 53, 21, 39, 0, 63, 56, 20, 41, 2, 65, 45, 25, 35, 10, 69, 54, 23, 43, 8, 73 },
|
||||||
|
{ 55, 38, 12, 62, 23, 52, 44, 3, 66, 18, 54, 36, 10, 74, 16, 56, 42, 9, 70, 17, 58, 33, 5, 69, 20, 50, 40, 1, 63, 24, 53, 37, 13, 65, 15, 48, 34, 4, 61, 22, 57, 31, 6, 64, 26, 46, 35, 11, 72, 21, 47, 30, 7, 68, 29, 45, 32, 8, 60, 19, 49, 43, 2, 67, 27, 51, 39, 0, 71, 28, 59, 41, 14, 73, 25 },
|
||||||
|
{ 70, 32, 18, 10, 58, 69, 38, 22, 2, 54, 67, 36, 19, 12, 57, 62, 34, 20, 14, 52, 63, 41, 15, 3, 51, 73, 42, 28, 6, 48, 60, 43, 29, 5, 45, 64, 31, 17, 4, 56, 65, 35, 26, 13, 53, 61, 37, 23, 1, 49, 68, 40, 16, 9, 47, 71, 39, 25, 7, 50, 66, 33, 24, 8, 59, 72, 44, 27, 11, 46, 74, 30, 21, 0, 55 },
|
||||||
|
{ 6, 45, 71, 27, 44, 10, 46, 74, 22, 32, 0, 55, 69, 21, 33, 4, 50, 66, 18, 38, 7, 57, 62, 19, 36, 1, 48, 70, 20, 40, 8, 47, 68, 15, 43, 2, 58, 61, 26, 42, 3, 56, 72, 23, 34, 14, 54, 67, 16, 37, 5, 59, 64, 24, 30, 12, 52, 65, 25, 39, 13, 49, 73, 17, 31, 9, 53, 60, 28, 35, 11, 51, 63, 29, 41 },
|
||||||
|
{ 31, 65, 50, 20, 13, 37, 66, 45, 23, 5, 32, 69, 54, 19, 7, 39, 74, 52, 27, 1, 42, 64, 53, 22, 4, 43, 70, 58, 16, 3, 40, 71, 57, 17, 0, 35, 63, 56, 18, 9, 44, 72, 51, 21, 6, 33, 67, 46, 25, 11, 30, 73, 55, 15, 8, 36, 62, 48, 24, 10, 41, 60, 49, 29, 14, 34, 61, 47, 26, 2, 38, 68, 59, 28, 12 },
|
||||||
|
{ 67, 22, 49, 36, 13, 64, 28, 57, 37, 6, 65, 29, 46, 39, 3, 70, 26, 45, 35, 1, 62, 24, 58, 34, 10, 68, 19, 53, 33, 4, 66, 21, 52, 31, 7, 74, 18, 47, 32, 5, 61, 16, 51, 38, 8, 72, 23, 55, 30, 12, 73, 17, 59, 44, 0, 60, 15, 50, 43, 14, 63, 27, 48, 42, 11, 71, 20, 54, 41, 9, 69, 25, 56, 40, 2 },
|
||||||
|
{ 19, 38, 14, 66, 57, 18, 44, 7, 74, 48, 23, 30, 6, 71, 58, 26, 32, 5, 61, 46, 20, 34, 0, 68, 45, 24, 36, 1, 70, 50, 27, 33, 10, 63, 52, 16, 42, 9, 65, 51, 15, 41, 11, 64, 53, 22, 37, 3, 60, 56, 28, 35, 4, 67, 49, 17, 39, 13, 69, 54, 25, 43, 2, 73, 55, 21, 31, 8, 62, 47, 29, 40, 12, 72, 59 },
|
||||||
|
{ 4, 52, 64, 28, 44, 14, 46, 74, 16, 32, 11, 50, 68, 27, 36, 0, 47, 70, 26, 34, 13, 57, 61, 18, 38, 6, 56, 62, 19, 40, 5, 58, 67, 17, 31, 12, 54, 63, 22, 33, 3, 53, 72, 21, 41, 10, 48, 66, 15, 35, 7, 45, 60, 20, 37, 9, 51, 69, 25, 42, 2, 59, 71, 24, 39, 1, 55, 65, 23, 30, 8, 49, 73, 29, 43 },
|
||||||
|
{ 44, 66, 19, 1, 56, 35, 62, 20, 4, 54, 39, 70, 24, 5, 55, 31, 74, 26, 12, 58, 32, 60, 17, 10, 45, 37, 63, 22, 3, 50, 33, 64, 16, 7, 51, 34, 61, 21, 8, 48, 38, 68, 29, 0, 46, 36, 72, 28, 14, 49, 42, 69, 25, 6, 57, 43, 65, 18, 2, 52, 30, 71, 23, 13, 47, 41, 67, 15, 9, 53, 40, 73, 27, 11, 59 },
|
||||||
|
{ 12, 16, 36, 46, 69, 6, 20, 44, 58, 62, 11, 19, 34, 48, 71, 1, 18, 42, 50, 74, 3, 25, 31, 47, 65, 0, 24, 33, 45, 72, 2, 23, 35, 56, 64, 10, 22, 38, 49, 63, 7, 26, 37, 51, 70, 14, 21, 30, 53, 67, 5, 15, 40, 52, 66, 9, 17, 39, 55, 60, 13, 27, 41, 54, 73, 4, 28, 32, 57, 61, 8, 29, 43, 59, 68 },
|
||||||
|
{ 63, 42, 18, 2, 57, 71, 34, 22, 10, 48, 67, 36, 25, 4, 46, 60, 31, 28, 6, 47, 74, 37, 15, 0, 55, 65, 32, 24, 12, 56, 66, 40, 27, 14, 52, 62, 38, 19, 3, 50, 73, 33, 29, 11, 53, 61, 35, 16, 7, 58, 72, 41, 26, 5, 59, 69, 30, 20, 9, 51, 68, 44, 23, 1, 49, 70, 39, 17, 8, 54, 64, 43, 21, 13, 45 },
|
||||||
|
{ 52, 1, 71, 17, 36, 47, 7, 64, 26, 32, 53, 5, 60, 20, 42, 57, 2, 66, 18, 34, 56, 4, 63, 24, 35, 46, 13, 72, 22, 30, 48, 0, 67, 21, 39, 50, 3, 74, 16, 31, 59, 14, 61, 23, 37, 45, 6, 65, 19, 44, 51, 11, 62, 27, 41, 55, 9, 68, 15, 38, 58, 8, 70, 29, 40, 54, 10, 69, 28, 33, 49, 12, 73, 25, 43 }
|
||||||
|
};
|
||||||
|
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()
|
||||||
|
{
|
||||||
|
packet[0] = pgm_read_word_near( &HOTT_hop_val[num_ch] );
|
||||||
|
packet[1] = pgm_read_word_near( &HOTT_hop_val[num_ch] )>>8;
|
||||||
|
|
||||||
|
for(uint8_t i=0; i<HOTT_NUM_RF_CHANNELS; i++)
|
||||||
|
hopping_frequency[i]=pgm_read_byte_near( &HOTT_hop[num_ch][i] );
|
||||||
|
|
||||||
|
#ifdef HOTT_FORCE_ID
|
||||||
|
memcpy(rx_tx_addr,"\x7C\x94\x00\x0D\x50",5);
|
||||||
|
#endif
|
||||||
|
memset(&packet[30],0xFF,9);
|
||||||
|
packet[39]=0x07; // unknown and constant
|
||||||
|
if(IS_BIND_IN_PROGRESS)
|
||||||
|
{
|
||||||
|
packet[28] = 0x80; // unknown 0x80 when bind starts then when RX replies start normal, 0x89/8A/8B/8C/8D/8E during normal packets
|
||||||
|
packet[29] = 0x02; // unknown 0x02 when bind starts then when RX replies cycle in sequence 0x1A/22/2A/0A/12, 0x02 during normal packets
|
||||||
|
memset(&packet[40],0xFA,5);
|
||||||
|
memcpy(&packet[45],rx_tx_addr,5);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
packet[28] = 0x8C; // unknown 0x80 when bind starts then when RX replies start normal, 0x89/8A/8B/8C/8D/8E during normal packets, 0x0F->config menu
|
||||||
|
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->config menu, 0x0A->no more RX telemetry
|
||||||
|
memcpy(&packet[40],rx_tx_addr,5);
|
||||||
|
|
||||||
|
uint8_t addr=HOTT_EEPROM_OFFSET+RX_num*5;
|
||||||
|
for(uint8_t i=0;i<5;i++)
|
||||||
|
packet[45+i]=eeprom_read_byte((EE_ADDR)(addr+i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __attribute__((unused)) HOTT_data_packet()
|
||||||
|
{
|
||||||
|
packet[2] = hopping_frequency_no;
|
||||||
|
|
||||||
|
packet[3] = 0x00; // used for failsafe but may also be used for additional channels
|
||||||
|
#ifdef FAILSAFE_ENABLE
|
||||||
|
static uint8_t failsafe_count=0;
|
||||||
|
if(IS_FAILSAFE_VALUES_on && IS_BIND_DONE)
|
||||||
|
{
|
||||||
|
failsafe_count++;
|
||||||
|
if(failsafe_count>=3)
|
||||||
|
{
|
||||||
|
FAILSAFE_VALUES_off;
|
||||||
|
failsafe_count=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
failsafe_count=0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Channels value are PPM*2, -100%=1100µs, +100%=1900µs, order TAER
|
||||||
|
uint16_t val;
|
||||||
|
for(uint8_t i=4;i<28;i+=2)
|
||||||
|
{
|
||||||
|
val=Channel_data[(i-4)>>1];
|
||||||
|
val=(((val<<2)+val)>>2)+860*2; // value range 860<->2140 *2 <-> -125%<->+125%
|
||||||
|
#ifdef FAILSAFE_ENABLE
|
||||||
|
if(failsafe_count==1)
|
||||||
|
{ // first failsafe packet
|
||||||
|
packet[3]=0x40;
|
||||||
|
uint16_t fs=Failsafe_data[(i-4)>>1];
|
||||||
|
if( fs == FAILSAFE_CHANNEL_HOLD || fs == FAILSAFE_CHANNEL_NOPULSES)
|
||||||
|
val|=0x8000; // channel hold flag
|
||||||
|
else
|
||||||
|
{
|
||||||
|
val=(((fs<<2)+fs)>>2)+860*2; // value range 860<->2140 *2 <-> -125%<->+125%
|
||||||
|
val|=0x4000; // channel specific position flag
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(failsafe_count==2)
|
||||||
|
{ // second failsafe packet=timing?
|
||||||
|
packet[3]=0x50;
|
||||||
|
if(i==4)
|
||||||
|
val=2;
|
||||||
|
else
|
||||||
|
val=0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
packet[i] = val;
|
||||||
|
packet[i+1] = val>>8;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HOTT_FW_TELEMETRY
|
||||||
|
static uint8_t prev_SerialRX_val=0;
|
||||||
|
if(HoTT_SerialRX && HoTT_SerialRX_val >= 0xD7 && HoTT_SerialRX_val <= 0xDF)
|
||||||
|
{
|
||||||
|
if(prev_SerialRX_val!=HoTT_SerialRX_val)
|
||||||
|
{
|
||||||
|
prev_SerialRX_val=HoTT_SerialRX_val;
|
||||||
|
packet[28] = HoTT_SerialRX_val; // send the touch being pressed only once
|
||||||
|
}
|
||||||
|
else
|
||||||
|
packet[28] = 0xDF; // no touch pressed
|
||||||
|
packet[29] = 0x01; // 0x01->config menu
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
packet[28] = 0x8C; // unknown 0x80 when bind starts then when RX replies start normal, 0x89/8A/8B/8C/8D/8E during normal packets, 0x0F->config menu
|
||||||
|
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->config menu, 0x0A->no more RX telemetry
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
CC2500_SetTxRxMode(TX_EN);
|
||||||
|
CC2500_SetPower();
|
||||||
|
CC2500_WriteReg(CC2500_06_PKTLEN, 0x32);
|
||||||
|
CC2500_WriteData(packet, HOTT_TX_PACKET_LEN);
|
||||||
|
#if 0
|
||||||
|
debug("RF:%02X P:",rf_ch_num);
|
||||||
|
for(uint8_t i=0;i<HOTT_TX_PACKET_LEN;i++)
|
||||||
|
debug(" %02X",packet[i]);
|
||||||
|
debugln("");
|
||||||
|
#endif
|
||||||
|
hopping_frequency_no++;
|
||||||
|
hopping_frequency_no %= HOTT_NUM_RF_CHANNELS;
|
||||||
|
rf_ch_num=hopping_frequency[hopping_frequency_no];
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t ReadHOTT()
|
||||||
|
{
|
||||||
|
#ifdef HOTT_FW_TELEMETRY
|
||||||
|
static uint8_t pps_counter=0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
switch(phase)
|
||||||
|
{
|
||||||
|
case HOTT_START:
|
||||||
|
rf_ch_num = 0;
|
||||||
|
HOTT_tune_chan();
|
||||||
|
phase = HOTT_CAL;
|
||||||
|
return 2000;
|
||||||
|
case HOTT_CAL:
|
||||||
|
calData[rf_ch_num]=CC2500_ReadReg(CC2500_25_FSCAL1);
|
||||||
|
if (++rf_ch_num < HOTT_NUM_RF_CHANNELS)
|
||||||
|
HOTT_tune_chan();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hopping_frequency_no = 0;
|
||||||
|
rf_ch_num=hopping_frequency[hopping_frequency_no];
|
||||||
|
counter = 0;
|
||||||
|
phase = HOTT_DATA1;
|
||||||
|
}
|
||||||
|
return 2000;
|
||||||
|
|
||||||
|
/* Work cycle: 10ms */
|
||||||
|
case HOTT_DATA1:
|
||||||
|
//TX
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(HOTT_PACKET_PERIOD);
|
||||||
|
#endif
|
||||||
|
HOTT_tune_freq();
|
||||||
|
HOTT_tune_chan_fast();
|
||||||
|
HOTT_data_packet();
|
||||||
|
phase = HOTT_RX1;
|
||||||
|
return 4500;
|
||||||
|
case HOTT_RX1:
|
||||||
|
//RX
|
||||||
|
CC2500_SetTxRxMode(RX_EN);
|
||||||
|
CC2500_WriteReg(CC2500_06_PKTLEN, HOTT_RX_PACKET_LEN);
|
||||||
|
CC2500_Strobe(CC2500_SRX);
|
||||||
|
phase = HOTT_RX2;
|
||||||
|
return 4500;
|
||||||
|
case HOTT_RX2:
|
||||||
|
//Telemetry
|
||||||
|
len = CC2500_ReadReg(CC2500_3B_RXBYTES | CC2500_READ_BURST) & 0x7F;
|
||||||
|
if (len==HOTT_RX_PACKET_LEN+2)
|
||||||
|
{
|
||||||
|
CC2500_ReadData(packet_in, len);
|
||||||
|
if(memcmp(rx_tx_addr,packet_in,5)==0)
|
||||||
|
{ // TX ID matches
|
||||||
|
if(IS_BIND_IN_PROGRESS)
|
||||||
|
{
|
||||||
|
debug("B:");
|
||||||
|
for(uint8_t i=0;i<HOTT_RX_PACKET_LEN;i++)
|
||||||
|
debug(" %02X", packet_in[i]);
|
||||||
|
debugln("");
|
||||||
|
uint8_t addr=HOTT_EEPROM_OFFSET+RX_num*5;
|
||||||
|
for(uint8_t i=0; i<5; i++)
|
||||||
|
eeprom_write_byte((EE_ADDR)(addr+i),packet_in[5+i]);
|
||||||
|
BIND_DONE;
|
||||||
|
HOTT_init();
|
||||||
|
}
|
||||||
|
#ifdef HOTT_FW_TELEMETRY
|
||||||
|
else
|
||||||
|
{ //Telemetry
|
||||||
|
// [0..4] = TXID
|
||||||
|
// [5..9] = RXID
|
||||||
|
// [10] = 0x40 bind, 0x00 normal, 0x80 config menu
|
||||||
|
// [11] = telmetry pages. For sensors 0x00 to 0x04, for config mennu 0x00 to 0x12.
|
||||||
|
// Normal telem page 0 = 0x00, 0x33, 0x34, 0x46, 0x64, 0x33, 0x0A, 0x00, 0x00, 0x00
|
||||||
|
// = 0x55, 0x32, 0x38, 0x55, 0x64, 0x32, 0xD0, 0x07, 0x00, 0x55
|
||||||
|
// Page 0 [12] = [21] = ??
|
||||||
|
// Page 0 [13] = RX_Voltage*10 in V
|
||||||
|
// Page 0 [14] = Temperature-20 in °C
|
||||||
|
// Page 0 [15] = RX_RSSI
|
||||||
|
// Page 0 [16] = RX_LQI ??
|
||||||
|
// Page 0 [17] = RX_STR ??
|
||||||
|
// Page 0 [18,19] = [19]*256+[18]=max lost packet time in ms, max value seems 2s=0x7D0
|
||||||
|
// Page 0 [20] = 0x00 ??
|
||||||
|
// Config menu consists of the different telem pages put all together
|
||||||
|
// Page X [12] = seems like all the telem pages with the same value are going together to make the full config menu text. Seen so far 'a', 'b', 'c', 'd'
|
||||||
|
// Page X [13..21] = 9 ascii chars to be displayed, char is highlighted when ascii|0x80
|
||||||
|
// Screen display is 21 characters large which means that once the first 21 chars are filled go to the begining of the next line
|
||||||
|
// Menu commands are sent through TX packets:
|
||||||
|
// packet[28]= 0xXF=>no key press, 0xXD=>down, 0xXB=>up, 0xX9=>enter, 0xXE=>right, 0xX7=>left with X=0 or D
|
||||||
|
// packet[29]= 0xX1/0xX9 with X=0 or X counting 0,1,1,2,2,..,9,9
|
||||||
|
TX_RSSI = packet_in[22];
|
||||||
|
if(TX_RSSI >=128)
|
||||||
|
TX_RSSI -= 128;
|
||||||
|
else
|
||||||
|
TX_RSSI += 128;
|
||||||
|
// Reduce telemetry to 14 bytes
|
||||||
|
packet_in[0]= TX_RSSI;
|
||||||
|
packet_in[1]= TX_LQI;
|
||||||
|
debug("T=");
|
||||||
|
for(uint8_t i=10;i < HOTT_RX_PACKET_LEN; i++)
|
||||||
|
{
|
||||||
|
packet_in[i-8]=packet_in[i];
|
||||||
|
debug(" %02X",packet_in[i]);
|
||||||
|
}
|
||||||
|
debugln("");
|
||||||
|
telemetry_link=2;
|
||||||
|
}
|
||||||
|
pps_counter++;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifdef HOTT_FW_TELEMETRY
|
||||||
|
packet_count++;
|
||||||
|
if(packet_count>=100)
|
||||||
|
{
|
||||||
|
TX_LQI=pps_counter;
|
||||||
|
pps_counter=packet_count=0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
CC2500_Strobe(CC2500_SFRX); //Flush the RXFIFO
|
||||||
|
phase=HOTT_DATA1;
|
||||||
|
return 1000;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t initHOTT()
|
||||||
|
{
|
||||||
|
num_ch=random(0xfefefefe)%16;
|
||||||
|
HOTT_init();
|
||||||
|
HOTT_rf_init();
|
||||||
|
packet_count=0;
|
||||||
|
#ifdef HOTT_FW_TELEMETRY
|
||||||
|
HoTT_SerialRX_val=0;
|
||||||
|
HoTT_SerialRX=false;
|
||||||
|
#endif
|
||||||
|
phase = HOTT_START;
|
||||||
|
return 10000;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -123,8 +123,8 @@ static void __attribute__((unused)) build_ch_data()
|
|||||||
for (i = 0; i< 8; i++) {
|
for (i = 0; i< 8; i++) {
|
||||||
j=CH_AETR[i];
|
j=CH_AETR[i];
|
||||||
temp=convert_channel_16b_limit(j,0,1000);
|
temp=convert_channel_16b_limit(j,0,1000);
|
||||||
if (j == THROTTLE) // It is clear that hisky's throttle stick is made reversely, so I adjust it here on purpose
|
if (j == CH3) // It is clear that hisky's throttle stick is made reversely, so I adjust it here on purpose
|
||||||
temp = 1000 -temp;
|
temp = 1000 - temp;
|
||||||
if (j == CH7)
|
if (j == CH7)
|
||||||
temp = temp < 400 ? 0 : 3; // Gyro mode, 0 - 6 axis, 3 - 3 axis
|
temp = temp < 400 ? 0 : 3; // Gyro mode, 0 - 6 axis, 3 - 3 axis
|
||||||
packet[i] = (uint8_t)(temp&0xFF);
|
packet[i] = (uint8_t)(temp&0xFF);
|
||||||
@@ -151,6 +151,9 @@ uint16_t hisky_cb()
|
|||||||
phase=6;
|
phase=6;
|
||||||
break;
|
break;
|
||||||
case 7: // build packet
|
case 7: // build packet
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(5000);
|
||||||
|
#endif
|
||||||
#ifdef FAILSAFE_ENABLE
|
#ifdef FAILSAFE_ENABLE
|
||||||
if(IS_FAILSAFE_VALUES_on && hopping_frequency_no==0)
|
if(IS_FAILSAFE_VALUES_on && hopping_frequency_no==0)
|
||||||
{ // send failsafe every 100ms
|
{ // send failsafe every 100ms
|
||||||
@@ -159,6 +162,7 @@ uint16_t hisky_cb()
|
|||||||
convert_failsafe_HK310(CH5, &packet[4],&packet[5]);
|
convert_failsafe_HK310(CH5, &packet[4],&packet[5]);
|
||||||
packet[7]=0xAA;
|
packet[7]=0xAA;
|
||||||
packet[8]=0x5A;
|
packet[8]=0x5A;
|
||||||
|
FAILSAFE_VALUES_off;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
@@ -216,6 +220,9 @@ uint16_t hisky_cb()
|
|||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
//Build normal packet
|
//Build normal packet
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(9000);
|
||||||
|
#endif
|
||||||
build_ch_data();
|
build_ch_data();
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
|
|||||||
@@ -146,6 +146,11 @@ static void __attribute__((unused)) HITEC_build_packet()
|
|||||||
break;
|
break;
|
||||||
case 0x7B:
|
case 0x7B:
|
||||||
packet[5]=hopping_frequency[13]>>1; // if not there the Optima link is jerky...
|
packet[5]=hopping_frequency[13]>>1; // if not there the Optima link is jerky...
|
||||||
|
packet[14]=0x2A;
|
||||||
|
packet[15]=0x46; // unknown but if 0x45 then 17=0x46, if 0x46 then 17=0x46 or 0x47, if 0x47 then 0x45 or 0x46
|
||||||
|
packet[16]=0x2A;
|
||||||
|
packet[17]=0x47;
|
||||||
|
packet[18]=0x2A;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(sub_protocol==MINIMA)
|
if(sub_protocol==MINIMA)
|
||||||
@@ -259,6 +264,9 @@ uint16_t ReadHITEC()
|
|||||||
case HITEC_PREP:
|
case HITEC_PREP:
|
||||||
if ( prev_option == option )
|
if ( prev_option == option )
|
||||||
{ // No user frequency change
|
{ // No user frequency change
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(HITEC_PACKET_PERIOD);
|
||||||
|
#endif
|
||||||
HITEC_change_chan_fast();
|
HITEC_change_chan_fast();
|
||||||
hopping_frequency_no++;
|
hopping_frequency_no++;
|
||||||
if(hopping_frequency_no>=rf_ch_num)
|
if(hopping_frequency_no>=rf_ch_num)
|
||||||
@@ -285,32 +293,32 @@ uint16_t ReadHITEC()
|
|||||||
return HITEC_RX1_TIMING;
|
return HITEC_RX1_TIMING;
|
||||||
case HITEC_RX2:
|
case HITEC_RX2:
|
||||||
uint8_t len=CC2500_ReadReg(CC2500_3B_RXBYTES | CC2500_READ_BURST) & 0x7F;
|
uint8_t len=CC2500_ReadReg(CC2500_3B_RXBYTES | CC2500_READ_BURST) & 0x7F;
|
||||||
if(len && len<MAX_PKT)
|
if(len && len<TELEMETRY_BUFFER_SIZE)
|
||||||
{ // Something has been received
|
{ // Something has been received
|
||||||
CC2500_ReadData(pkt, len);
|
CC2500_ReadData(packet_in, len);
|
||||||
if( (pkt[len-1] & 0x80) && pkt[0]==len-3 && pkt[1]==rx_tx_addr[1] && pkt[2]==rx_tx_addr[2] && pkt[3]==rx_tx_addr[3])
|
if( (packet_in[len-1] & 0x80) && packet_in[0]==len-3 && packet_in[1]==rx_tx_addr[1] && packet_in[2]==rx_tx_addr[2] && packet_in[3]==rx_tx_addr[3])
|
||||||
{ //valid crc && length ok && tx_id ok
|
{ //valid crc && length ok && tx_id ok
|
||||||
debug("RX:l=%d",len);
|
debug("RX:l=%d",len);
|
||||||
for(uint8_t i=0;i<len;i++)
|
for(uint8_t i=0;i<len;i++)
|
||||||
debug(",%02X",pkt[i]);
|
debug(",%02X",packet_in[i]);
|
||||||
if(IS_BIND_IN_PROGRESS)
|
if(IS_BIND_IN_PROGRESS)
|
||||||
{
|
{
|
||||||
if(len==13) // Bind packets have a length of 13
|
if(len==13) // Bind packets have a length of 13
|
||||||
{ // bind packet: 0A,00,E5,F2,7X,05,06,07,08,09,00
|
{ // bind packet: 0A,00,E5,F2,7X,05,06,07,08,09,00
|
||||||
debug(",bind");
|
debug(",bind");
|
||||||
boolean check=true;
|
boolean check=true;
|
||||||
for(uint8_t i=5;i<=10;i++)
|
for(uint8_t i=5;i<10;i++)
|
||||||
if(pkt[i]!=i%10) check=false;
|
if(packet_in[i]!=i) check=false;
|
||||||
if((pkt[4]&0xF0)==0x70 && check)
|
if((packet_in[4]&0xF0)==0x70 && check)
|
||||||
{
|
{
|
||||||
bind_phase=pkt[4]+1;
|
bind_phase=packet_in[4]+1;
|
||||||
if(bind_phase==0x7B)
|
if(bind_phase==0x7B)
|
||||||
bind_counter=164; // in dumps the RX stops to reply at 0x7B so wait a little and exit
|
bind_counter=164; // in dumps the RX stops to reply at 0x7B so wait a little and exit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if( len==15 && pkt[4]==0 && pkt[12]==0 )
|
if( len==15 && packet_in[4]==0 && packet_in[12]==0 )
|
||||||
{ // Valid telemetry packets
|
{ // Valid telemetry packets
|
||||||
// no station:
|
// no station:
|
||||||
// 0C,1C,A1,2B,00,00,00,00,00,00,00,8D,00,64,8E -> 00 8D=>RX battery voltage 0x008D/28=5.03V
|
// 0C,1C,A1,2B,00,00,00,00,00,00,00,8D,00,64,8E -> 00 8D=>RX battery voltage 0x008D/28=5.03V
|
||||||
@@ -323,40 +331,42 @@ uint16_t ReadHITEC()
|
|||||||
// 0C,1C,A1,2B,00,16,00,00,00,00,00,16,00,2C,8E
|
// 0C,1C,A1,2B,00,16,00,00,00,00,00,16,00,2C,8E
|
||||||
// 0C,1C,A1,2B,00,17,00,00,00,42,44,17,00,48,8D -> 42=>temperature3 0x42-0x28=26°C,44=>temperature4 0x44-0x28=28°C
|
// 0C,1C,A1,2B,00,17,00,00,00,42,44,17,00,48,8D -> 42=>temperature3 0x42-0x28=26°C,44=>temperature4 0x44-0x28=28°C
|
||||||
// 0C,1C,A1,2B,00,18,00,00,00,00,00,18,00,50,92
|
// 0C,1C,A1,2B,00,18,00,00,00,00,00,18,00,50,92
|
||||||
debug(",telem,%02x",pkt[14]&0x7F);
|
debug(",telem,%02x",packet_in[14]&0x7F);
|
||||||
|
#if defined(HITEC_FW_TELEMETRY) || defined(HITEC_HUB_TELEMETRY)
|
||||||
|
TX_RSSI = packet_in[13];
|
||||||
|
if(TX_RSSI >=128)
|
||||||
|
TX_RSSI -= 128;
|
||||||
|
else
|
||||||
|
TX_RSSI += 128;
|
||||||
|
TX_LQI = packet_in[14]&0x7F;
|
||||||
|
#endif
|
||||||
#if defined(HITEC_FW_TELEMETRY)
|
#if defined(HITEC_FW_TELEMETRY)
|
||||||
if(sub_protocol==OPT_FW)
|
if(sub_protocol==OPT_FW)
|
||||||
{
|
{
|
||||||
// 8 bytes telemetry packets => see at the end of this file how to fully decode it
|
// 8 bytes telemetry packets => see at the end of this file how to fully decode it
|
||||||
pkt[0]=pkt[13]; // TX RSSI
|
packet_in[0]=TX_RSSI; // TX RSSI
|
||||||
pkt[1]=pkt[14]&0x7F; // TX LQI
|
packet_in[1]=TX_LQI; // TX LQI
|
||||||
uint8_t offset=pkt[5]==0?1:0;
|
uint8_t offset=packet_in[5]==0?1:0;
|
||||||
for(uint8_t i=5;i < 11; i++)
|
for(uint8_t i=5;i < 11; i++)
|
||||||
pkt[i-3]=pkt[i+offset]; // frame number followed by 5 bytes of data
|
packet_in[i-3]=packet_in[i+offset]; // frame number followed by 5 bytes of data
|
||||||
telemetry_link=2; // telemetry forward available
|
telemetry_link=2; // telemetry forward available
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if defined(HITEC_HUB_TELEMETRY)
|
#if defined(HITEC_HUB_TELEMETRY)
|
||||||
if(sub_protocol==OPT_HUB)
|
if(sub_protocol==OPT_HUB)
|
||||||
{
|
{
|
||||||
switch(pkt[5]) // telemetry frame number
|
switch(packet_in[5]) // telemetry frame number
|
||||||
{
|
{
|
||||||
case 0x00:
|
case 0x00:
|
||||||
v_lipo1 = (pkt[10])<<5 | (pkt[11])>>3; // calculation in float is volt=(pkt[10]<<8+pkt[11])/28
|
v_lipo1 = (packet_in[10])<<5 | (packet_in[11])>>3; // calculation in float is volt=(packet_in[10]<<8+packet_in[11])/28
|
||||||
break;
|
break;
|
||||||
case 0x11:
|
case 0x11:
|
||||||
v_lipo1 = (pkt[9])<<5 | (pkt[10])>>3; // calculation in float is volt=(pkt[9]<<8+pkt[10])/28
|
v_lipo1 = (packet_in[9])<<5 | (packet_in[10])>>3; // calculation in float is volt=(packet_in[9]<<8+packet_in[10])/28
|
||||||
break;
|
break;
|
||||||
case 0x18:
|
case 0x18:
|
||||||
v_lipo2 = (pkt[6])<<5 | (pkt[7])>>3; // calculation in float is volt=(pkt[6]<<8+pkt[7])/10
|
v_lipo2 = (packet_in[6])<<5 | (packet_in[7])>>3; // calculation in float is volt=(packet_in[6]<<8+packet_in[7])/10
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
TX_RSSI = pkt[13];
|
|
||||||
if(TX_RSSI >=128)
|
|
||||||
TX_RSSI -= 128;
|
|
||||||
else
|
|
||||||
TX_RSSI += 128;
|
|
||||||
TX_LQI = pkt[14]&0x7F;
|
|
||||||
telemetry_link=1; // telemetry hub available
|
telemetry_link=1; // telemetry hub available
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -389,10 +399,6 @@ uint16_t initHITEC()
|
|||||||
rx_tx_addr[3]=0x6A;
|
rx_tx_addr[3]=0x6A;
|
||||||
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);
|
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
|
#endif
|
||||||
#if defined(HITEC_HUB_TELEMETRY)
|
|
||||||
if(sub_protocol==OPT_HUB)
|
|
||||||
init_frskyd_link_telemetry();
|
|
||||||
#endif
|
|
||||||
phase = HITEC_START;
|
phase = HITEC_START;
|
||||||
return 10000;
|
return 10000;
|
||||||
}
|
}
|
||||||
@@ -403,7 +409,7 @@ packet[1] = TX LQI value
|
|||||||
packet[2] = frame number
|
packet[2] = frame number
|
||||||
packet[3-7] telemetry data
|
packet[3-7] telemetry data
|
||||||
|
|
||||||
The frame number takes the following values: 0x00, 0x11, 0x12, ..., 0x18. The frames can be present or not, they also do not have to follow each others.
|
The frame number takes the following values: 0x00, 0x11, 0x12, ..., 0x1C. The frames can be present or not, they also do not have to follow each others.
|
||||||
Here is a description of the telemetry data for each frame number:
|
Here is a description of the telemetry data for each frame number:
|
||||||
- frame 0x00
|
- frame 0x00
|
||||||
data byte 0 -> 0x00 unknown
|
data byte 0 -> 0x00 unknown
|
||||||
@@ -414,9 +420,9 @@ data byte 4 -> RX Batt Volt_L => RX Batt=(Volt_H*256+Volt_L)/28
|
|||||||
- frame 0x11
|
- frame 0x11
|
||||||
data byte 0 -> 0xAF start of frame
|
data byte 0 -> 0xAF start of frame
|
||||||
data byte 1 -> 0x00 unknown
|
data byte 1 -> 0x00 unknown
|
||||||
data byte 2 -> 0x2D frame type but constant here
|
data byte 2 -> 0x2D station type 0x2D=standard station nitro or electric, 0xAC=advanced station
|
||||||
data byte 3 -> Volt1_H
|
data byte 3 -> RX Batt Volt_H
|
||||||
data byte 4 -> Volt1_L RX Batt=(Volt1_H*256+Volt1_L)/28 V
|
data byte 4 -> RX Batt Volt_L => RX Batt=(Volt_H*256+Volt_L)/28
|
||||||
- frame 0x12
|
- frame 0x12
|
||||||
data byte 0 -> Lat_sec_H GPS : latitude second
|
data byte 0 -> Lat_sec_H GPS : latitude second
|
||||||
data byte 1 -> Lat_sec_L signed int : 1/100 of second
|
data byte 1 -> Lat_sec_L signed int : 1/100 of second
|
||||||
@@ -431,9 +437,9 @@ data byte 3 -> signed int : +=Est, - = west
|
|||||||
data byte 4 -> Temp2 Temperature2=Temp2-40°C
|
data byte 4 -> Temp2 Temperature2=Temp2-40°C
|
||||||
- frame 0x14
|
- frame 0x14
|
||||||
data byte 0 -> Speed_H
|
data byte 0 -> Speed_H
|
||||||
data byte 1 -> Speed_L Speed=Speed_H*256+Speed_L km/h
|
data byte 1 -> Speed_L GPS Speed=Speed_H*256+Speed_L km/h
|
||||||
data byte 2 -> Alti_sea_H
|
data byte 2 -> Alti_sea_H
|
||||||
data byte 3 -> Alti_sea_L Altitude sea=Alti_sea_H*256+Alti_sea_L m
|
data byte 3 -> Alti_sea_L GPS Altitude=Alti_sea_H*256+Alti_sea_L m
|
||||||
data byte 4 -> Temp1 Temperature1=Temp1-40°C
|
data byte 4 -> Temp1 Temperature1=Temp1-40°C
|
||||||
- frame 0x15
|
- frame 0x15
|
||||||
data byte 0 -> FUEL
|
data byte 0 -> FUEL
|
||||||
@@ -448,15 +454,30 @@ data byte 2 -> Date_day
|
|||||||
data byte 3 -> Time_hour GPS Time
|
data byte 3 -> Time_hour GPS Time
|
||||||
data byte 4 -> Time_min
|
data byte 4 -> Time_min
|
||||||
- frame 0x17
|
- frame 0x17
|
||||||
data byte 0 -> 0x00 COURSEH
|
data byte 0 -> COURSEH
|
||||||
data byte 1 -> 0x00 COURSEL GPS Course = COURSEH*256+COURSEL
|
data byte 1 -> COURSEL GPS heading = COURSEH*256+COURSEL in degrees
|
||||||
data byte 2 -> 0x00 GPS count
|
data byte 2 -> Count GPS satellites
|
||||||
data byte 3 -> Temp3 Temperature3=Temp2-40°C
|
data byte 3 -> Temp3 Temperature3=Temp2-40°C
|
||||||
data byte 4 -> Temp4 Temperature4=Temp3-40°C
|
data byte 4 -> Temp4 Temperature4=Temp3-40°C
|
||||||
- frame 0x18
|
- frame 0x18
|
||||||
data byte 1 -> Volt2_H
|
data byte 0 -> Volt_L Volt=(Volt_H*256+Volt_L)/10 V
|
||||||
data byte 2 -> Volt2_L Volt2=(Volt2_H*256+Volt2_L)/10 V
|
data byte 1 -> Volt_H
|
||||||
data byte 3 -> AMP1_L
|
data byte 2 -> AMP_L
|
||||||
data byte 4 -> AMP1_H Amp=(AMP1_H*256+AMP1_L -180)/14 in signed A
|
data byte 3 -> AMP_H Amp=(AMP1_*256+AMP_L -180)/14 in signed A
|
||||||
|
- frame 0x19 Servo sensor
|
||||||
|
data byte 0 -> AMP_Servo1 Amp=AMP_Servo1/10 in A
|
||||||
|
data byte 1 -> AMP_Servo2 Amp=AMP_Servo2/10 in A
|
||||||
|
data byte 2 -> AMP_Servo3 Amp=AMP_Servo3/10 in A
|
||||||
|
data byte 3 -> AMP_Servo4 Amp=AMP_Servo4/10 in A
|
||||||
|
- frame 0x1A
|
||||||
|
data byte 2 -> ASpeed_H Air speed=ASpeed_H*256+ASpeed_L km/h
|
||||||
|
data byte 3 -> ASpeed_L
|
||||||
|
- frame 0x1B Variometer sensor
|
||||||
|
data byte 0 -> Alti1H
|
||||||
|
data byte 1 -> Alti1L Altitude unfiltered
|
||||||
|
data byte 2 -> Alti2H
|
||||||
|
data byte 3 -> Alti2L Altitude filtered
|
||||||
|
- frame 0x1C Unknown
|
||||||
|
- frame 0x22 Unknown
|
||||||
*/
|
*/
|
||||||
#endif
|
#endif
|
||||||
@@ -242,9 +242,14 @@ uint16_t HONTAI_callback()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(packet_period);
|
||||||
|
#endif
|
||||||
HONTAI_send_packet(0);
|
HONTAI_send_packet(0);
|
||||||
|
}
|
||||||
|
|
||||||
return sub_protocol == FQ777_951 ? FQ777_951_PACKET_PERIOD : HONTAI_PACKET_PERIOD;
|
return packet_period;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t initHONTAI()
|
uint16_t initHONTAI()
|
||||||
@@ -253,6 +258,7 @@ uint16_t initHONTAI()
|
|||||||
bind_counter = HONTAI_BIND_COUNT;
|
bind_counter = HONTAI_BIND_COUNT;
|
||||||
HONTAI_initialize_txid();
|
HONTAI_initialize_txid();
|
||||||
HONTAI_init();
|
HONTAI_init();
|
||||||
|
packet_period = sub_protocol == FQ777_951 ? FQ777_951_PACKET_PERIOD : HONTAI_PACKET_PERIOD;
|
||||||
return HONTAI_INITIAL_WAIT;
|
return HONTAI_INITIAL_WAIT;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -376,6 +376,9 @@ uint16_t ReadHubsan()
|
|||||||
case DATA_4:
|
case DATA_4:
|
||||||
case DATA_5:
|
case DATA_5:
|
||||||
if( txState == 0) { // send packet
|
if( txState == 0) { // send packet
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(10000);
|
||||||
|
#endif
|
||||||
#ifdef HUBSAN_HUB_TELEMETRY
|
#ifdef HUBSAN_HUB_TELEMETRY
|
||||||
rfMode = A7105_TX;
|
rfMode = A7105_TX;
|
||||||
#endif
|
#endif
|
||||||
@@ -464,9 +467,6 @@ uint16_t initHubsan()
|
|||||||
}
|
}
|
||||||
packet_count=0;
|
packet_count=0;
|
||||||
bind_phase=0;
|
bind_phase=0;
|
||||||
#ifdef HUBSAN_HUB_TELEMETRY
|
|
||||||
init_frskyd_link_telemetry();
|
|
||||||
#endif
|
|
||||||
return 10000;
|
return 10000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -201,7 +201,10 @@ uint16_t ReadJ6Pro()
|
|||||||
cyrf_datainit();
|
cyrf_datainit();
|
||||||
phase = J6PRO_CHAN_1;
|
phase = J6PRO_CHAN_1;
|
||||||
case J6PRO_CHAN_1:
|
case J6PRO_CHAN_1:
|
||||||
//Keep transmit power updated
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(24550);
|
||||||
|
#endif
|
||||||
|
//Keep transmit power updated
|
||||||
CYRF_SetPower(0x28);
|
CYRF_SetPower(0x28);
|
||||||
j6pro_build_data_packet();
|
j6pro_build_data_packet();
|
||||||
//return 3400;
|
//return 3400;
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ Multiprotocol is distributed in the hope that it will be useful,
|
|||||||
|
|
||||||
#if defined(KF606_NRF24L01_INO)
|
#if defined(KF606_NRF24L01_INO)
|
||||||
|
|
||||||
#include "iface_xn297l.h"
|
#include "iface_nrf250k.h"
|
||||||
|
|
||||||
//#define FORCE_KF606_ORIGINAL_ID
|
//#define FORCE_KF606_ORIGINAL_ID
|
||||||
|
|
||||||
@@ -86,6 +86,9 @@ static void __attribute__((unused)) KF606_init()
|
|||||||
|
|
||||||
uint16_t KF606_callback()
|
uint16_t KF606_callback()
|
||||||
{
|
{
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(KF606_PACKET_PERIOD);
|
||||||
|
#endif
|
||||||
if(IS_BIND_IN_PROGRESS)
|
if(IS_BIND_IN_PROGRESS)
|
||||||
if(--bind_counter==0)
|
if(--bind_counter==0)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -279,12 +279,14 @@ uint16_t initKN()
|
|||||||
packet_period = KN_WL_SENDING_PACKET_PERIOD;
|
packet_period = KN_WL_SENDING_PACKET_PERIOD;
|
||||||
bind_counter = KN_WL_BIND_COUNT;
|
bind_counter = KN_WL_BIND_COUNT;
|
||||||
packet_count = KN_WL_PACKET_SEND_COUNT;
|
packet_count = KN_WL_PACKET_SEND_COUNT;
|
||||||
|
seed = KN_WL_PACKET_SEND_COUNT * KN_WL_SENDING_PACKET_PERIOD;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
packet_period = KN_FX_SENDING_PACKET_PERIOD;
|
packet_period = KN_FX_SENDING_PACKET_PERIOD;
|
||||||
bind_counter = KN_FX_BIND_COUNT;
|
bind_counter = KN_FX_BIND_COUNT;
|
||||||
packet_count = KN_FX_PACKET_SEND_COUNT;
|
packet_count = KN_FX_PACKET_SEND_COUNT;
|
||||||
|
seed = KN_FX_PACKET_SEND_COUNT * KN_FX_SENDING_PACKET_PERIOD;
|
||||||
}
|
}
|
||||||
kn_init();
|
kn_init();
|
||||||
phase = IS_BIND_IN_PROGRESS ? KN_PHASE_PRE_BIND : KN_PHASE_PRE_SEND;
|
phase = IS_BIND_IN_PROGRESS ? KN_PHASE_PRE_BIND : KN_PHASE_PRE_SEND;
|
||||||
@@ -318,6 +320,9 @@ uint16_t kn_callback()
|
|||||||
case KN_PHASE_SENDING:
|
case KN_PHASE_SENDING:
|
||||||
if(packet_sent >= packet_count)
|
if(packet_sent >= packet_count)
|
||||||
{
|
{
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(seed);
|
||||||
|
#endif
|
||||||
packet_sent = 0;
|
packet_sent = 0;
|
||||||
hopping_frequency_no++;
|
hopping_frequency_no++;
|
||||||
if(hopping_frequency_no >= KN_RF_CH_COUNT) hopping_frequency_no = 0;
|
if(hopping_frequency_no >= KN_RF_CH_COUNT) hopping_frequency_no = 0;
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
#if defined(MJXQ_NRF24L01_INO)
|
#if defined(MJXQ_NRF24L01_INO)
|
||||||
|
|
||||||
#include "iface_nrf24l01.h"
|
#include "iface_nrf24l01.h"
|
||||||
#include "iface_xn297l.h"
|
#include "iface_nrf250k.h"
|
||||||
|
|
||||||
#define MJXQ_BIND_COUNT 150
|
#define MJXQ_BIND_COUNT 150
|
||||||
#define MJXQ_PACKET_PERIOD 4000 // Timeout for callback in uSec
|
#define MJXQ_PACKET_PERIOD 4000 // Timeout for callback in uSec
|
||||||
@@ -327,7 +327,12 @@ static void __attribute__((unused)) MJXQ_initialize_txid()
|
|||||||
uint16_t MJXQ_callback()
|
uint16_t MJXQ_callback()
|
||||||
{
|
{
|
||||||
if(IS_BIND_DONE)
|
if(IS_BIND_DONE)
|
||||||
|
{
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(MJXQ_PACKET_PERIOD);
|
||||||
|
#endif
|
||||||
MJXQ_send_packet(0);
|
MJXQ_send_packet(0);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (bind_counter == 0)
|
if (bind_counter == 0)
|
||||||
|
|||||||
@@ -222,7 +222,12 @@ static void __attribute__((unused)) MT99XX_initialize_txid()
|
|||||||
uint16_t MT99XX_callback()
|
uint16_t MT99XX_callback()
|
||||||
{
|
{
|
||||||
if(IS_BIND_DONE)
|
if(IS_BIND_DONE)
|
||||||
|
{
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(packet_period);
|
||||||
|
#endif
|
||||||
MT99XX_send_packet();
|
MT99XX_send_packet();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (bind_counter == 0)
|
if (bind_counter == 0)
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
13,CG023,CG023,YD829
|
13,CG023,CG023,YD829
|
||||||
14,Bayang,Bayang,H8S3D,X16_AH,IRDRONE,DHD_D4
|
14,Bayang,Bayang,H8S3D,X16_AH,IRDRONE,DHD_D4
|
||||||
15,FrskyX,CH_16,CH_8,EU_16,EU_8
|
15,FrskyX,CH_16,CH_8,EU_16,EU_8
|
||||||
16,ESky
|
16,ESky,Std,ET4
|
||||||
17,MT99xx,MT,H7,YZ,LS,FY805
|
17,MT99xx,MT,H7,YZ,LS,FY805
|
||||||
18,MJXq,WLH08,X600,X800,H26D,E010,H26WH,PHOENIX
|
18,MJXq,WLH08,X600,X800,H26D,E010,H26WH,PHOENIX
|
||||||
19,Shenqi
|
19,Shenqi
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
32,GW008
|
32,GW008
|
||||||
33,DM002
|
33,DM002
|
||||||
34,CABELL,CAB_V3,C_TELEM,-,-,-,-,F_SAFE,UNBIND
|
34,CABELL,CAB_V3,C_TELEM,-,-,-,-,F_SAFE,UNBIND
|
||||||
35,ESKY150
|
35,ESKY150,4CH,7CH
|
||||||
36,H8_3D,H8_3D,H20H,H20Mini,H30Mini
|
36,H8_3D,H8_3D,H20H,H20Mini,H30Mini
|
||||||
37,CORONA,COR_V1,COR_V2,FD_V3
|
37,CORONA,COR_V1,COR_V2,FD_V3
|
||||||
38,CFlie
|
38,CFlie
|
||||||
@@ -43,7 +43,7 @@
|
|||||||
43,Traxxas,RX6519
|
43,Traxxas,RX6519
|
||||||
44,NCC1701
|
44,NCC1701
|
||||||
45,E01X,E012,E015,E016H
|
45,E01X,E012,E015,E016H
|
||||||
46,V911S
|
46,V911S,V911S,E119
|
||||||
47,GD00X,GD_V1,GD_V2
|
47,GD00X,GD_V1,GD_V2
|
||||||
48,V761
|
48,V761
|
||||||
49,KF606
|
49,KF606
|
||||||
@@ -52,4 +52,14 @@
|
|||||||
52,ZSX,280
|
52,ZSX,280
|
||||||
53,Flyzone,FZ-410
|
53,Flyzone,FZ-410
|
||||||
54,Scanner
|
54,Scanner
|
||||||
63,XN_DUMP,250K,1M,2M
|
55,Frsky_RX
|
||||||
|
56,AFHDS2A_RX
|
||||||
|
57,HoTT
|
||||||
|
58,FX816,P38
|
||||||
|
59,Bayang_RX
|
||||||
|
60,Pelikan
|
||||||
|
61,Tiger
|
||||||
|
62,XK,X450,X420
|
||||||
|
63,XN_DUMP,250K,1M,2M,AUTO
|
||||||
|
64,FrskyX2,CH_16,CH_8,EU_16,EU_8
|
||||||
|
65,FrSkyR9,915MHz,868MHz,915_8ch,868_8ch
|
||||||
|
|||||||
337
Multiprotocol/Multi_Names.ino
Normal file
@@ -0,0 +1,337 @@
|
|||||||
|
/*
|
||||||
|
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_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_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_SFHSS[] ="SFHSS";
|
||||||
|
const char STR_J6PRO[] ="J6 Pro";
|
||||||
|
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[] ="FSky 2A";
|
||||||
|
const char STR_Q2X2[] ="Q2x2";
|
||||||
|
const char STR_WK2x01[] ="Walkera";
|
||||||
|
const char STR_Q303[] ="Q303";
|
||||||
|
const char STR_GW008[] ="GW008";
|
||||||
|
const char STR_DM002[] ="DM002";
|
||||||
|
const char STR_CABELL[] ="Cabell";
|
||||||
|
const char STR_ESKY150[] ="Esky150";
|
||||||
|
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_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_FLYZONE[] ="FlyZone";
|
||||||
|
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_SUBTYPE_FLYSKY[] = "\x04""Std\0""V9x9""V6x6""V912""CX20";
|
||||||
|
const char STR_SUBTYPE_HUBSAN[] = "\x04""H107""H301""H501";
|
||||||
|
const char STR_SUBTYPE_FRSKYX[] = "\x07""D16\0 ""D16 8ch""LBT(EU)""LBT 8ch";
|
||||||
|
const char STR_SUBTYPE_HISKY[] = "\x05""Std\0 ""HK310";
|
||||||
|
const char STR_SUBTYPE_V2X2[] = "\x06""Std\0 ""JXD506";
|
||||||
|
const char STR_SUBTYPE_DSM[] = "\x06""2 22ms""2 11ms""X 22ms""X 11ms";
|
||||||
|
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";
|
||||||
|
const char STR_SUBTYPE_MT99[] = "\x06""MT99\0 ""H7\0 ""YZ\0 ""LS\0 ""FY805";
|
||||||
|
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";
|
||||||
|
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_FLYZONE[] = "\x05""FZ410";
|
||||||
|
const char STR_SUBTYPE_FX816[] = "\x03""P38";
|
||||||
|
const char STR_SUBTYPE_XN297DUMP[] = "\x07""250Kbps""1Mbps\0 ""2Mbps\0 ""Auto\0 ";
|
||||||
|
const char STR_SUBTYPE_ESKY150[] = "\x03""4CH""7CH";
|
||||||
|
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";
|
||||||
|
const char STR_SUBTYPE_ESKY[] = "\x03""Std""ET4";
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
OPTION_NONE,
|
||||||
|
OPTION_OPTION,
|
||||||
|
OPTION_RFTUNE,
|
||||||
|
OPTION_VIDFREQ,
|
||||||
|
OPTION_FIXEDID,
|
||||||
|
OPTION_TELEM,
|
||||||
|
OPTION_SRVFREQ,
|
||||||
|
OPTION_MAXTHR,
|
||||||
|
OPTION_RFCHAN
|
||||||
|
};
|
||||||
|
|
||||||
|
#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(FLYSKY_A7105_INO)
|
||||||
|
{PROTO_FLYSKY, STR_FLYSKY, 5, STR_SUBTYPE_FLYSKY, OPTION_NONE },
|
||||||
|
#endif
|
||||||
|
#if defined(HUBSAN_A7105_INO)
|
||||||
|
{PROTO_HUBSAN, STR_HUBSAN, 3, STR_SUBTYPE_HUBSAN, OPTION_VIDFREQ },
|
||||||
|
#endif
|
||||||
|
#if defined(FRSKYD_CC2500_INO)
|
||||||
|
{PROTO_FRSKYD, STR_FRSKYD, 0, NO_SUBTYPE, OPTION_RFTUNE },
|
||||||
|
#endif
|
||||||
|
#if defined(HISKY_NRF24L01_INO)
|
||||||
|
{PROTO_HISKY, STR_HISKY, 2, STR_SUBTYPE_HISKY, OPTION_NONE },
|
||||||
|
#endif
|
||||||
|
#if defined(V2X2_NRF24L01_INO)
|
||||||
|
{PROTO_V2X2, STR_V2X2, 2, STR_SUBTYPE_V2X2, OPTION_NONE },
|
||||||
|
#endif
|
||||||
|
#if defined(DSM_CYRF6936_INO)
|
||||||
|
{PROTO_DSM, STR_DSM, 4, STR_SUBTYPE_DSM, OPTION_MAXTHR },
|
||||||
|
#endif
|
||||||
|
#if defined(DEVO_CYRF6936_INO)
|
||||||
|
{PROTO_DEVO, STR_DEVO, 5, STR_SUBTYPE_DEVO, OPTION_FIXEDID },
|
||||||
|
#endif
|
||||||
|
#if defined(YD717_NRF24L01_INO)
|
||||||
|
{PROTO_YD717, STR_YD717, 5, STR_SUBTYPE_YD717, OPTION_NONE },
|
||||||
|
#endif
|
||||||
|
#if defined(KN_NRF24L01_INO)
|
||||||
|
{PROTO_KN, STR_KN, 2, STR_SUBTYPE_KN, OPTION_NONE },
|
||||||
|
#endif
|
||||||
|
#if defined(SYMAX_NRF24L01_INO)
|
||||||
|
{PROTO_SYMAX, STR_SYMAX, 2, STR_SUBTYPE_SYMAX, OPTION_NONE },
|
||||||
|
#endif
|
||||||
|
#if defined(SLT_NRF24L01_INO)
|
||||||
|
{PROTO_SLT, STR_SLT, 5, STR_SUBTYPE_SLT, OPTION_RFTUNE },
|
||||||
|
#endif
|
||||||
|
#if defined(CX10_NRF24L01_INO)
|
||||||
|
{PROTO_CX10, STR_CX10, 7, STR_SUBTYPE_CX10, OPTION_NONE },
|
||||||
|
#endif
|
||||||
|
#if defined(CG023_NRF24L01_INO)
|
||||||
|
{PROTO_CG023, STR_CG023, 2, STR_SUBTYPE_CG023, OPTION_NONE },
|
||||||
|
#endif
|
||||||
|
#if defined(BAYANG_NRF24L01_INO)
|
||||||
|
{PROTO_BAYANG, STR_BAYANG, 5, STR_SUBTYPE_BAYANG, OPTION_TELEM },
|
||||||
|
#endif
|
||||||
|
#if defined(FRSKYX_CC2500_INO)
|
||||||
|
{PROTO_FRSKYX, STR_FRSKYX, 4, STR_SUBTYPE_FRSKYX, OPTION_RFTUNE },
|
||||||
|
#endif
|
||||||
|
#if defined(FRSKYX2_CC2500_INO)
|
||||||
|
{PROTO_FRSKYX2, STR_FRSKYX2, 4, STR_SUBTYPE_FRSKYX, OPTION_RFTUNE },
|
||||||
|
#endif
|
||||||
|
#if defined(ESKY_NRF24L01_INO)
|
||||||
|
{PROTO_ESKY, STR_ESKY, 2, STR_SUBTYPE_ESKY, OPTION_NONE },
|
||||||
|
#endif
|
||||||
|
#if defined(MT99XX_NRF24L01_INO)
|
||||||
|
{PROTO_MT99XX, STR_MT99XX, 5, STR_SUBTYPE_MT99, OPTION_NONE },
|
||||||
|
#endif
|
||||||
|
#if defined(MJXQ_NRF24L01_INO)
|
||||||
|
{PROTO_MJXQ, STR_MJXQ, 7, STR_SUBTYPE_MJXQ, OPTION_RFTUNE },
|
||||||
|
#endif
|
||||||
|
#if defined(SHENQI_NRF24L01_INO)
|
||||||
|
{PROTO_SHENQI, STR_SHENQI, 0, NO_SUBTYPE, OPTION_NONE },
|
||||||
|
#endif
|
||||||
|
#if defined(FY326_NRF24L01_INO)
|
||||||
|
{PROTO_FY326, STR_FY326, 2, STR_SUBTYPE_FY326, OPTION_NONE },
|
||||||
|
#endif
|
||||||
|
#if defined(SFHSS_CC2500_INO)
|
||||||
|
{PROTO_SFHSS, STR_SFHSS, 0, NO_SUBTYPE, OPTION_RFTUNE },
|
||||||
|
#endif
|
||||||
|
#if defined(J6PRO_CYRF6936_INO)
|
||||||
|
{PROTO_J6PRO, STR_J6PRO, 0, NO_SUBTYPE, OPTION_NONE },
|
||||||
|
#endif
|
||||||
|
#if defined(FQ777_NRF24L01_INO)
|
||||||
|
{PROTO_FQ777, STR_FQ777, 0, NO_SUBTYPE, OPTION_NONE },
|
||||||
|
#endif
|
||||||
|
#if defined(ASSAN_NRF24L01_INO)
|
||||||
|
{PROTO_ASSAN, STR_ASSAN, 0, NO_SUBTYPE, OPTION_NONE },
|
||||||
|
#endif
|
||||||
|
#if defined(FRSKYV_CC2500_INO)
|
||||||
|
{PROTO_FRSKYV, STR_FRSKYV, 0, NO_SUBTYPE, OPTION_RFTUNE },
|
||||||
|
#endif
|
||||||
|
#if defined(HONTAI_NRF24L01_INO)
|
||||||
|
{PROTO_HONTAI, STR_HONTAI, 4, STR_SUBTYPE_HONTAI, OPTION_NONE },
|
||||||
|
#endif
|
||||||
|
#if defined(AFHDS2A_A7105_INO)
|
||||||
|
{PROTO_AFHDS2A, STR_AFHDS2A, 4, STR_SUBTYPE_AFHDS2A, OPTION_SRVFREQ },
|
||||||
|
#endif
|
||||||
|
#if defined(CX10_NRF24L01_INO)
|
||||||
|
{PROTO_Q2X2, STR_Q2X2, 3, STR_SUBTYPE_Q2X2, OPTION_NONE },
|
||||||
|
#endif
|
||||||
|
#if defined(WK2x01_CYRF6936_INO)
|
||||||
|
{PROTO_WK2x01, STR_WK2x01, 6, STR_SUBTYPE_WK2x01, OPTION_NONE },
|
||||||
|
#endif
|
||||||
|
#if defined(Q303_NRF24L01_INO)
|
||||||
|
{PROTO_Q303, STR_Q303, 4, STR_SUBTYPE_Q303, OPTION_NONE },
|
||||||
|
#endif
|
||||||
|
#if defined(GW008_NRF24L01_INO)
|
||||||
|
{PROTO_GW008, STR_GW008, 0, NO_SUBTYPE, OPTION_NONE },
|
||||||
|
#endif
|
||||||
|
#if defined(DM002_NRF24L01_INO)
|
||||||
|
{PROTO_DM002, STR_DM002, 0, NO_SUBTYPE, OPTION_NONE },
|
||||||
|
#endif
|
||||||
|
#if defined(CABELL_NRF24L01_INO)
|
||||||
|
{PROTO_CABELL, STR_CABELL, 8, STR_SUBTYPE_CABELL, OPTION_OPTION },
|
||||||
|
#endif
|
||||||
|
#if defined(ESKY150_NRF24L01_INO)
|
||||||
|
{PROTO_ESKY150, STR_ESKY150, 2, STR_SUBTYPE_ESKY150, OPTION_NONE },
|
||||||
|
#endif
|
||||||
|
#if defined(H8_3D_NRF24L01_INO)
|
||||||
|
{PROTO_H8_3D, STR_H8_3D, 4, STR_SUBTYPE_H83D, OPTION_NONE },
|
||||||
|
#endif
|
||||||
|
#if defined(CORONA_CC2500_INO)
|
||||||
|
{PROTO_CORONA, STR_CORONA, 3, STR_SUBTYPE_CORONA, OPTION_RFTUNE },
|
||||||
|
#endif
|
||||||
|
#if defined(CFLIE_NRF24L01_INO)
|
||||||
|
{PROTO_CFLIE, STR_CFLIE, 0, NO_SUBTYPE, OPTION_NONE },
|
||||||
|
#endif
|
||||||
|
#if defined(HITEC_CC2500_INO)
|
||||||
|
{PROTO_HITEC, STR_HITEC, 3, STR_SUBTYPE_HITEC, OPTION_RFTUNE },
|
||||||
|
#endif
|
||||||
|
#if defined(WFLY_CYRF6936_INO)
|
||||||
|
{PROTO_WFLY, STR_WFLY, 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(TRAXXAS_CYRF6936_INO)
|
||||||
|
{PROTO_TRAXXAS, STR_TRAXXAS, 1, STR_SUBTYPE_TRAXXAS, OPTION_NONE },
|
||||||
|
#endif
|
||||||
|
#if defined(NCC1701_NRF24L01_INO)
|
||||||
|
{PROTO_NCC1701, STR_NCC1701, 0, NO_SUBTYPE, OPTION_NONE },
|
||||||
|
#endif
|
||||||
|
#if defined(E01X_NRF24L01_INO)
|
||||||
|
{PROTO_E01X, STR_E01X, 3, STR_SUBTYPE_E01X, OPTION_OPTION },
|
||||||
|
#endif
|
||||||
|
#if defined(V911S_NRF24L01_INO)
|
||||||
|
{PROTO_V911S, STR_V911S, 2, STR_SUBTYPE_V911S, OPTION_RFTUNE },
|
||||||
|
#endif
|
||||||
|
#if defined(GD00X_NRF24L01_INO)
|
||||||
|
{PROTO_GD00X, STR_GD00X, 2, STR_SUBTYPE_GD00X, OPTION_RFTUNE },
|
||||||
|
#endif
|
||||||
|
#if defined(V761_NRF24L01_INO)
|
||||||
|
{PROTO_V761, STR_V761, 0, NO_SUBTYPE, OPTION_NONE },
|
||||||
|
#endif
|
||||||
|
#if defined(KF606_NRF24L01_INO)
|
||||||
|
{PROTO_KF606, STR_KF606, 0, NO_SUBTYPE, OPTION_RFTUNE },
|
||||||
|
#endif
|
||||||
|
#if defined(REDPINE_CC2500_INO)
|
||||||
|
{PROTO_REDPINE, STR_REDPINE, 2, STR_SUBTYPE_REDPINE, OPTION_RFTUNE },
|
||||||
|
#endif
|
||||||
|
#if defined(POTENSIC_NRF24L01_INO)
|
||||||
|
{PROTO_POTENSIC, STR_POTENSIC, 1, STR_SUBTYPE_POTENSIC, OPTION_NONE },
|
||||||
|
#endif
|
||||||
|
#if defined(ZSX_NRF24L01_INO)
|
||||||
|
{PROTO_ZSX, STR_ZSX, 1, STR_SUBTYPE_ZSX, OPTION_NONE },
|
||||||
|
#endif
|
||||||
|
#if defined(FLYZONE_A7105_INO)
|
||||||
|
{PROTO_FLYZONE, STR_FLYZONE, 1, STR_SUBTYPE_FLYZONE, OPTION_NONE },
|
||||||
|
#endif
|
||||||
|
#if defined(SCANNER_CC2500_INO)
|
||||||
|
{PROTO_SCANNER, STR_SCANNER, 0, NO_SUBTYPE, OPTION_NONE },
|
||||||
|
#endif
|
||||||
|
#if defined(FRSKY_RX_CC2500_INO)
|
||||||
|
{PROTO_FRSKY_RX, STR_FRSKY_RX, 0, NO_SUBTYPE, OPTION_RFTUNE },
|
||||||
|
#endif
|
||||||
|
#if defined(AFHDS2A_RX_A7105_INO)
|
||||||
|
{PROTO_AFHDS2A_RX, STR_AFHDS2A_RX,0, NO_SUBTYPE, OPTION_NONE },
|
||||||
|
#endif
|
||||||
|
#if defined(HOTT_CC2500_INO)
|
||||||
|
{PROTO_HOTT, STR_HOTT, 0, NO_SUBTYPE, OPTION_RFTUNE },
|
||||||
|
#endif
|
||||||
|
#if defined(FX816_NRF24L01_INO)
|
||||||
|
{PROTO_FX816, STR_FX816, 1, STR_SUBTYPE_FX816, OPTION_NONE },
|
||||||
|
#endif
|
||||||
|
#if defined(BAYANG_RX_NRF24L01_INO)
|
||||||
|
{PROTO_BAYANG_RX, STR_BAYANG_RX, 0, NO_SUBTYPE, OPTION_NONE },
|
||||||
|
#endif
|
||||||
|
#if defined(PELIKAN_A7105_INO)
|
||||||
|
{PROTO_PELIKAN, STR_PELIKAN , 0, NO_SUBTYPE, OPTION_NONE },
|
||||||
|
#endif
|
||||||
|
#if defined(TIGER_NRF24L01_INO)
|
||||||
|
{PROTO_TIGER, STR_TIGER , 0, NO_SUBTYPE, OPTION_NONE },
|
||||||
|
#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, 4, STR_SUBTYPE_XN297DUMP, OPTION_RFCHAN },
|
||||||
|
#endif
|
||||||
|
#if defined(FRSKYR9_SX1276_INO)
|
||||||
|
{PROTO_FRSKY_R9, STR_FRSKYR9, 4, STR_SUBTYPE_FRSKYR9, OPTION_NONE },
|
||||||
|
#endif
|
||||||
|
{0x00, nullptr, 0, nullptr, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -17,8 +17,8 @@
|
|||||||
// Version
|
// Version
|
||||||
//******************
|
//******************
|
||||||
#define VERSION_MAJOR 1
|
#define VERSION_MAJOR 1
|
||||||
#define VERSION_MINOR 2
|
#define VERSION_MINOR 3
|
||||||
#define VERSION_REVISION 1
|
#define VERSION_REVISION 0
|
||||||
#define VERSION_PATCH_LEVEL 76
|
#define VERSION_PATCH_LEVEL 76
|
||||||
|
|
||||||
//******************
|
//******************
|
||||||
@@ -81,7 +81,17 @@ enum PROTOCOLS
|
|||||||
PROTO_ZSX = 52, // =>NRF24L01
|
PROTO_ZSX = 52, // =>NRF24L01
|
||||||
PROTO_FLYZONE = 53, // =>A7105
|
PROTO_FLYZONE = 53, // =>A7105
|
||||||
PROTO_SCANNER = 54, // =>CC2500
|
PROTO_SCANNER = 54, // =>CC2500
|
||||||
|
PROTO_FRSKY_RX = 55, // =>CC2500
|
||||||
|
PROTO_AFHDS2A_RX= 56, // =>A7105
|
||||||
|
PROTO_HOTT = 57, // =>CC2500
|
||||||
|
PROTO_FX816 = 58, // =>NRF24L01
|
||||||
|
PROTO_BAYANG_RX = 59, // =>NRF24L01
|
||||||
|
PROTO_PELIKAN = 60, // =>A7105
|
||||||
|
PROTO_TIGER = 61, // =>NRF24L01
|
||||||
|
PROTO_XK = 62, // =>NRF24L01
|
||||||
PROTO_XN297DUMP = 63, // =>NRF24L01
|
PROTO_XN297DUMP = 63, // =>NRF24L01
|
||||||
|
PROTO_FRSKYX2 = 64, // =>CC2500
|
||||||
|
PROTO_FRSKY_R9 = 65, // =>SX1276
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Flysky
|
enum Flysky
|
||||||
@@ -204,6 +214,13 @@ enum FRSKYX
|
|||||||
EU_16 = 2,
|
EU_16 = 2,
|
||||||
EU_8 = 3,
|
EU_8 = 3,
|
||||||
};
|
};
|
||||||
|
enum FRSKYX2
|
||||||
|
{
|
||||||
|
FRSKYX2_CH_16 = 0,
|
||||||
|
FRSKYX2_CH_8 = 1,
|
||||||
|
FRSKYX2_EU_16 = 2,
|
||||||
|
FRSKYX2_EU_8 = 3,
|
||||||
|
};
|
||||||
enum HONTAI
|
enum HONTAI
|
||||||
{
|
{
|
||||||
HONTAI = 0,
|
HONTAI = 0,
|
||||||
@@ -288,6 +305,40 @@ enum TRAXXAS
|
|||||||
{
|
{
|
||||||
RX6519 = 0,
|
RX6519 = 0,
|
||||||
};
|
};
|
||||||
|
enum ESKY150
|
||||||
|
{
|
||||||
|
ESKY150_4CH = 0,
|
||||||
|
ESKY150_7CH = 1,
|
||||||
|
};
|
||||||
|
enum V911S
|
||||||
|
{
|
||||||
|
V911S_STD = 0,
|
||||||
|
V911S_E119 = 1,
|
||||||
|
};
|
||||||
|
enum XK
|
||||||
|
{
|
||||||
|
X450 = 0,
|
||||||
|
X420 = 1,
|
||||||
|
};
|
||||||
|
enum XN297DUMP
|
||||||
|
{
|
||||||
|
XN297DUMP_250K = 0,
|
||||||
|
XN297DUMP_1M = 1,
|
||||||
|
XN297DUMP_2M = 2,
|
||||||
|
XN297DUMP_AUTO = 3,
|
||||||
|
};
|
||||||
|
enum FRSKY_R9
|
||||||
|
{
|
||||||
|
R9_915 = 0,
|
||||||
|
R9_868 = 1,
|
||||||
|
R9_915_8CH = 2,
|
||||||
|
R9_868_8CH = 3,
|
||||||
|
};
|
||||||
|
enum ESKY
|
||||||
|
{
|
||||||
|
ESKY_STD = 0,
|
||||||
|
ESKY_ET4 = 1,
|
||||||
|
};
|
||||||
|
|
||||||
#define NONE 0
|
#define NONE 0
|
||||||
#define P_HIGH 1
|
#define P_HIGH 1
|
||||||
@@ -297,16 +348,16 @@ enum TRAXXAS
|
|||||||
|
|
||||||
struct PPM_Parameters
|
struct PPM_Parameters
|
||||||
{
|
{
|
||||||
uint8_t protocol : 6;
|
uint8_t protocol;
|
||||||
uint8_t sub_proto : 3;
|
uint8_t sub_proto : 3;
|
||||||
uint8_t rx_num : 4;
|
uint8_t rx_num : 6;
|
||||||
uint8_t power : 1;
|
uint8_t power : 1;
|
||||||
uint8_t autobind : 1;
|
uint8_t autobind : 1;
|
||||||
uint8_t option;
|
int8_t option;
|
||||||
|
uint32_t chan_order;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Telemetry
|
// Telemetry
|
||||||
|
|
||||||
enum MultiPacketTypes
|
enum MultiPacketTypes
|
||||||
{
|
{
|
||||||
MULTI_TELEMETRY_STATUS = 1,
|
MULTI_TELEMETRY_STATUS = 1,
|
||||||
@@ -315,16 +366,25 @@ enum MultiPacketTypes
|
|||||||
MULTI_TELEMETRY_DSM = 4,
|
MULTI_TELEMETRY_DSM = 4,
|
||||||
MULTI_TELEMETRY_DSMBIND = 5,
|
MULTI_TELEMETRY_DSMBIND = 5,
|
||||||
MULTI_TELEMETRY_AFHDS2A = 6,
|
MULTI_TELEMETRY_AFHDS2A = 6,
|
||||||
MULTI_TELEMETRY_CONFIG = 7,
|
MULTI_TELEMETRY_REUSE_1 = 7,
|
||||||
MULTI_TELEMETRY_SYNC = 8,
|
MULTI_TELEMETRY_SYNC = 8,
|
||||||
MULTI_TELEMETRY_SPORT_POLLING = 9,
|
MULTI_TELEMETRY_REUSE_2 = 9,
|
||||||
MULTI_TELEMETRY_HITEC = 10,
|
MULTI_TELEMETRY_HITEC = 10,
|
||||||
MULTI_TELEMETRY_SCANNER = 11,
|
MULTI_TELEMETRY_SCANNER = 11,
|
||||||
|
MULTI_TELEMETRY_AFHDS2A_AC = 12,
|
||||||
|
MULTI_TELEMETRY_RX_CHANNELS = 13,
|
||||||
|
MULTI_TELEMETRY_HOTT = 14,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Macros
|
// Macros
|
||||||
#define NOP() __asm__ __volatile__("nop")
|
#define NOP() __asm__ __volatile__("nop")
|
||||||
|
|
||||||
|
//***************
|
||||||
|
//*** Tests ***
|
||||||
|
//***************
|
||||||
|
#define IS_FAILSAFE_PROTOCOL ( (protocol==PROTO_HISKY && sub_protocol==HK310) || protocol==PROTO_AFHDS2A || protocol==PROTO_DEVO || protocol==PROTO_SFHSS || protocol==PROTO_WK2x01 || protocol== PROTO_HOTT || protocol==PROTO_FRSKYX )
|
||||||
|
#define IS_CHMAP_PROTOCOL ( (protocol==PROTO_HISKY && sub_protocol==HK310) || protocol==PROTO_AFHDS2A || protocol==PROTO_DEVO || protocol==PROTO_SFHSS || protocol==PROTO_WK2x01 || protocol== PROTO_DSM || protocol==PROTO_SLT || protocol==PROTO_FLYSKY || protocol==PROTO_ESKY || protocol==PROTO_J6PRO || protocol==PROTO_PELIKAN )
|
||||||
|
|
||||||
//***************
|
//***************
|
||||||
//*** Flags ***
|
//*** Flags ***
|
||||||
//***************
|
//***************
|
||||||
@@ -380,6 +440,7 @@ enum MultiPacketTypes
|
|||||||
#define TX_RX_PAUSE_on protocol_flags2 |= _BV(4)
|
#define TX_RX_PAUSE_on protocol_flags2 |= _BV(4)
|
||||||
#define IS_TX_RX_PAUSE_on ( ( protocol_flags2 & _BV(4) ) !=0 )
|
#define IS_TX_RX_PAUSE_on ( ( protocol_flags2 & _BV(4) ) !=0 )
|
||||||
#define IS_TX_PAUSE_on ( ( protocol_flags2 & (_BV(4)|_BV(3)) ) !=0 )
|
#define IS_TX_PAUSE_on ( ( protocol_flags2 & (_BV(4)|_BV(3)) ) !=0 )
|
||||||
|
#define IS_TX_PAUSE_off ( ( protocol_flags2 & (_BV(4)|_BV(3)) ) ==0 )
|
||||||
//Signal OK
|
//Signal OK
|
||||||
#define INPUT_SIGNAL_off protocol_flags2 &= ~_BV(5)
|
#define INPUT_SIGNAL_off protocol_flags2 &= ~_BV(5)
|
||||||
#define INPUT_SIGNAL_on protocol_flags2 |= _BV(5)
|
#define INPUT_SIGNAL_on protocol_flags2 |= _BV(5)
|
||||||
@@ -395,6 +456,24 @@ enum MultiPacketTypes
|
|||||||
#define WAIT_BIND_on protocol_flags2 |= _BV(7)
|
#define WAIT_BIND_on protocol_flags2 |= _BV(7)
|
||||||
#define IS_WAIT_BIND_on ( ( protocol_flags2 & _BV(7) ) !=0 )
|
#define IS_WAIT_BIND_on ( ( protocol_flags2 & _BV(7) ) !=0 )
|
||||||
#define IS_WAIT_BIND_off ( ( protocol_flags2 & _BV(7) ) ==0 )
|
#define IS_WAIT_BIND_off ( ( protocol_flags2 & _BV(7) ) ==0 )
|
||||||
|
//Incoming telemetry data buffer
|
||||||
|
#define DATA_BUFFER_LOW_off protocol_flags3 &= ~_BV(0)
|
||||||
|
#define DATA_BUFFER_LOW_on protocol_flags3 |= _BV(0)
|
||||||
|
#define IS_DATA_BUFFER_LOW_on ( ( protocol_flags3 & _BV(0) ) !=0 )
|
||||||
|
#define IS_DATA_BUFFER_LOW_off ( ( protocol_flags3 & _BV(0) ) ==0 )
|
||||||
|
#define SEND_MULTI_STATUS_off protocol_flags3 &= ~_BV(1)
|
||||||
|
#define SEND_MULTI_STATUS_on protocol_flags3 |= _BV(1)
|
||||||
|
#define IS_SEND_MULTI_STATUS_on ( ( protocol_flags3 & _BV(1) ) !=0 )
|
||||||
|
#define IS_SEND_MULTI_STATUS_off ( ( protocol_flags3 & _BV(1) ) ==0 )
|
||||||
|
#define DISABLE_CH_MAP_off protocol_flags3 &= ~_BV(2)
|
||||||
|
#define DISABLE_CH_MAP_on protocol_flags3 |= _BV(2)
|
||||||
|
#define IS_DISABLE_CH_MAP_on ( ( protocol_flags3 & _BV(2) ) !=0 )
|
||||||
|
#define IS_DISABLE_CH_MAP_off ( ( protocol_flags3 & _BV(2) ) ==0 )
|
||||||
|
#define DISABLE_TELEM_off protocol_flags3 &= ~_BV(3)
|
||||||
|
#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 )
|
||||||
|
|
||||||
|
|
||||||
// Failsafe
|
// Failsafe
|
||||||
#define FAILSAFE_CHANNEL_HOLD 2047
|
#define FAILSAFE_CHANNEL_HOLD 2047
|
||||||
@@ -566,79 +645,95 @@ enum {
|
|||||||
#define AFHDS2A_EEPROM_OFFSET 50 // RX ID, 4 bytes per model id, end is 50+64=114
|
#define AFHDS2A_EEPROM_OFFSET 50 // RX ID, 4 bytes per model id, end is 50+64=114
|
||||||
#define BUGS_EEPROM_OFFSET 114 // RX ID, 2 bytes per model id, end is 114+32=146
|
#define BUGS_EEPROM_OFFSET 114 // RX ID, 2 bytes per model id, end is 114+32=146
|
||||||
#define BUGSMINI_EEPROM_OFFSET 146 // RX ID, 2 bytes per model id, end is 146+32=178
|
#define BUGSMINI_EEPROM_OFFSET 146 // RX ID, 2 bytes per model id, end is 146+32=178
|
||||||
//#define CONFIG_EEPROM_OFFSET 210 // Current configuration of the multimodule
|
#define FRSKY_RX_EEPROM_OFFSET 178 // (1) format + (3) TX ID + (1) freq_tune + (47) channels, 52 bytes, end is 178+52=230
|
||||||
|
#define AFHDS2A_RX_EEPROM_OFFSET 230 // (4) TX ID + (16) channels, 20 bytes, end is 230+20=250
|
||||||
|
#define AFHDS2A_EEPROM_OFFSET2 250 // RX ID, 4 bytes per model id, end is 250+192=442
|
||||||
|
#define HOTT_EEPROM_OFFSET 442 // RX ID, 5 bytes per model id, end is 320+442=762
|
||||||
|
#define BAYANG_RX_EEPROM_OFFSET 762 // (5) TX ID + (4) channels, 9 bytes, end is 771
|
||||||
|
//#define CONFIG_EEPROM_OFFSET 771 // Current configuration of the multimodule
|
||||||
|
|
||||||
//****************************************
|
//****************************************
|
||||||
//*** MULTI protocol serial definition ***
|
//*** MULTI protocol serial definition ***
|
||||||
//****************************************
|
//****************************************
|
||||||
/*
|
/*
|
||||||
**************************
|
***************************
|
||||||
16 channels serial protocol
|
16 channels serial protocol
|
||||||
**************************
|
***************************
|
||||||
Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
||||||
Total of 26 bytes
|
Total of 26 bytes for protocol V1, variable length 27..36 for protocol V2
|
||||||
Stream[0] = 0x55 sub_protocol values are 0..31 Stream contains channels
|
Stream[0] = header
|
||||||
Stream[0] = 0x54 sub_protocol values are 32..63 Stream contains channels
|
0x55 sub_protocol values are 0..31 Stream contains channels
|
||||||
Stream[0] = 0x57 sub_protocol values are 0..31 Stream contains failsafe
|
0x54 sub_protocol values are 32..63 Stream contains channels
|
||||||
Stream[0] = 0x56 sub_protocol values are 32..63 Stream contains failsafe
|
0x57 sub_protocol values are 0..31 Stream contains failsafe
|
||||||
header
|
0x56 sub_protocol values are 32..63 Stream contains failsafe
|
||||||
Stream[1] = sub_protocol|BindBit|RangeCheckBit|AutoBindBit;
|
Stream[1] = sub_protocol|BindBit|RangeCheckBit|AutoBindBit;
|
||||||
sub_protocol is 0..31 (bits 0..4), value should be added with 32 if Stream[0] = 0x54
|
sub_protocol is 0..31 (bits 0..4), value should be added with 32 if Stream[0] = 0x54 | 0x56
|
||||||
=> Reserved 0
|
Reserved 0
|
||||||
Flysky 1
|
Flysky 1
|
||||||
Hubsan 2
|
Hubsan 2
|
||||||
FrskyD 3
|
FrskyD 3
|
||||||
Hisky 4
|
Hisky 4
|
||||||
V2x2 5
|
V2x2 5
|
||||||
DSM 6
|
DSM 6
|
||||||
Devo 7
|
Devo 7
|
||||||
YD717 8
|
YD717 8
|
||||||
KN 9
|
KN 9
|
||||||
SymaX 10
|
SymaX 10
|
||||||
SLT 11
|
SLT 11
|
||||||
CX10 12
|
CX10 12
|
||||||
CG023 13
|
CG023 13
|
||||||
Bayang 14
|
Bayang 14
|
||||||
FrskyX 15
|
FrskyX 15
|
||||||
ESky 16
|
ESky 16
|
||||||
MT99XX 17
|
MT99XX 17
|
||||||
MJXQ 18
|
MJXQ 18
|
||||||
SHENQI 19
|
SHENQI 19
|
||||||
FY326 20
|
FY326 20
|
||||||
SFHSS 21
|
SFHSS 21
|
||||||
J6PRO 22
|
J6PRO 22
|
||||||
FQ777 23
|
FQ777 23
|
||||||
ASSAN 24
|
ASSAN 24
|
||||||
FrskyV 25
|
FrskyV 25
|
||||||
HONTAI 26
|
HONTAI 26
|
||||||
OpenLRS 27
|
OpenLRS 27
|
||||||
AFHDS2A 28
|
AFHDS2A 28
|
||||||
Q2X2 29
|
Q2X2 29
|
||||||
WK2x01 30
|
WK2x01 30
|
||||||
Q303 31
|
Q303 31
|
||||||
GW008 32
|
GW008 32
|
||||||
DM002 33
|
DM002 33
|
||||||
CABELL 34
|
CABELL 34
|
||||||
ESKY150 35
|
ESKY150 35
|
||||||
H8_3D 36
|
H8_3D 36
|
||||||
CORONA 37
|
CORONA 37
|
||||||
CFlie 38
|
CFlie 38
|
||||||
Hitec 39
|
Hitec 39
|
||||||
WFLY 40
|
WFLY 40
|
||||||
BUGS 41
|
BUGS 41
|
||||||
BUGSMINI 42
|
BUGSMINI 42
|
||||||
TRAXXAS 43
|
TRAXXAS 43
|
||||||
NCC1701 44
|
NCC1701 44
|
||||||
E01X 45
|
E01X 45
|
||||||
V911S 46
|
V911S 46
|
||||||
GD00X 47
|
GD00X 47
|
||||||
V761 48
|
V761 48
|
||||||
KF606 49
|
KF606 49
|
||||||
REDPINE 50
|
REDPINE 50
|
||||||
POTENSIC 51
|
POTENSIC 51
|
||||||
ZSX 52
|
ZSX 52
|
||||||
FLYZONE 53
|
FLYZONE 53
|
||||||
SCANNER 54
|
SCANNER 54
|
||||||
|
FRSKY_RX 55
|
||||||
|
AFHDS2A_RX 56
|
||||||
|
HOTT 57
|
||||||
|
FX816 58
|
||||||
|
BAYANG_RX 59
|
||||||
|
PELIKAN 60
|
||||||
|
TIGER 61
|
||||||
|
XK 62
|
||||||
|
XN297DUMP 63
|
||||||
|
FRSKYX2 64
|
||||||
|
FRSKY_R9 65
|
||||||
BindBit=> 0x80 1=Bind/0=No
|
BindBit=> 0x80 1=Bind/0=No
|
||||||
AutoBindBit=> 0x40 1=Yes /0=No
|
AutoBindBit=> 0x40 1=Yes /0=No
|
||||||
RangeCheck=> 0x20 1=Yes /0=No
|
RangeCheck=> 0x20 1=Yes /0=No
|
||||||
@@ -780,6 +875,23 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
|||||||
RED_SLOW 1
|
RED_SLOW 1
|
||||||
sub_protocol==TRAXXAS
|
sub_protocol==TRAXXAS
|
||||||
RX6519 0
|
RX6519 0
|
||||||
|
sub_protocol==ESKY150
|
||||||
|
ESKY150_4CH 0
|
||||||
|
ESKY150_7CH 1
|
||||||
|
sub_protocol==V911S
|
||||||
|
V911S_STD 0
|
||||||
|
V911S_E119 1
|
||||||
|
sub_protocol==XK
|
||||||
|
X450 0
|
||||||
|
X420 1
|
||||||
|
sub_protocol==FRSKY_R9
|
||||||
|
R9_915 0
|
||||||
|
R9_868 1
|
||||||
|
R9_915_8CH 2
|
||||||
|
R9_868_8CH 3
|
||||||
|
sub_protocol==ESKY
|
||||||
|
ESKY_STD 0
|
||||||
|
ESKY_ET4 1
|
||||||
|
|
||||||
Power value => 0x80 0=High/1=Low
|
Power value => 0x80 0=High/1=Low
|
||||||
Stream[3] = option_protocol;
|
Stream[3] = option_protocol;
|
||||||
@@ -793,7 +905,15 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
|||||||
2047 +125%
|
2047 +125%
|
||||||
Values are concatenated to fit in 22 bytes like in SBUS protocol.
|
Values are concatenated to fit in 22 bytes like in SBUS protocol.
|
||||||
Failsafe values have exactly the same range/values than normal channels except the extremes where
|
Failsafe values have exactly the same range/values than normal channels except the extremes where
|
||||||
0=hold, 2047=no pulse. If failsafe is not set or RX then failsafe packets should not be sent.
|
0=no pulse, 2047=hold. If failsafe is not set or RX then failsafe packets should not be sent.
|
||||||
|
Stream[26] = sub_protocol bits 6 & 7|RxNum bits 4 & 5|Telemetry_Invert 3|Future_Use 2|Disable_Telemetry 1|Disable_CH_Mapping 0
|
||||||
|
sub_protocol is 0..255 (bits 0..5 + bits 6..7)
|
||||||
|
RxNum value is 0..63 (bits 0..3 + bits 4..5)
|
||||||
|
Telemetry_Invert => 0x08 0=normal, 1=invert
|
||||||
|
Future_Use => 0x04 0= , 1=
|
||||||
|
Disable_Telemetry => 0x02 0=enable, 1=disable
|
||||||
|
Disable_CH_Mapping => 0x01 0=enable, 1=disable
|
||||||
|
Stream[27.. 35] = between 0 and 9 bytes for additional protocol data
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
Multimodule Status
|
Multimodule Status
|
||||||
@@ -813,7 +933,9 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
|||||||
0x04 = Protocol is valid
|
0x04 = Protocol is valid
|
||||||
0x08 = Module is in binding mode
|
0x08 = Module is in binding mode
|
||||||
0x10 = Module waits a bind event to load the protocol
|
0x10 = Module waits a bind event to load the protocol
|
||||||
0x20 = Failsafe supported by currently running protocol
|
0x20 = Current protocol supports failsafe
|
||||||
|
0x40 = Current protocol supports disable channel mapping
|
||||||
|
0x80 = Data buffer is almost full
|
||||||
[3] major
|
[3] major
|
||||||
[4] minor
|
[4] minor
|
||||||
[5] revision
|
[5] revision
|
||||||
@@ -847,24 +969,41 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
|||||||
[4] Flags
|
[4] Flags
|
||||||
0x01 = Input signal detected
|
0x01 = Input signal detected
|
||||||
0x02 = Serial mode enabled
|
0x02 = Serial mode enabled
|
||||||
0x04 = protocol is valid
|
0x04 = Protocol is valid
|
||||||
0x08 = module is in binding mode
|
0x08 = Module is in binding mode
|
||||||
0x10 = module waits a bind event to load the protocol
|
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
|
||||||
[5] major
|
[5] major
|
||||||
[6] minor
|
[6] minor
|
||||||
[7] revision
|
[7] revision
|
||||||
[8] patchlevel,
|
[8] patchlevel
|
||||||
version of multi code, should be displayed as major.minor.revision.patchlevel
|
version of multi code, should be displayed as major.minor.revision.patchlevel
|
||||||
|
[9] channel order: CH4|CH3|CH2|CH1 with CHx value A=0,E=1,T=2,R=3
|
||||||
|
[10] Next valid protocol number, can be used to skip invalid protocols
|
||||||
|
[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
|
||||||
|
[19&0x0F] Number of sub protocols
|
||||||
|
[20..27] Sub protocol name [8], not null terminated if sub prototcol len == 8
|
||||||
|
|
||||||
more information can be added by specifing a longer length of the type, the TX will just ignore these bytes
|
more information can be added by specifing a longer length of the type, the TX will just ignore these bytes
|
||||||
|
|
||||||
|
|
||||||
Type 0x02 Frksy S.port telemetry
|
Type 0x02 Frksy S.port telemetry
|
||||||
Type 0x03 Frsky Hub telemetry
|
Type 0x03 Frsky Hub telemetry
|
||||||
|
|
||||||
*No* usual frsky byte stuffing and without start/stop byte (0x7e)
|
*No* usual frsky byte stuffing and without start/stop byte (0x7e)
|
||||||
|
|
||||||
|
|
||||||
Type 0x04 Spektrum telemetry data
|
Type 0x04 Spektrum telemetry data
|
||||||
data[0] TX RSSI
|
data[0] TX RSSI
|
||||||
data[1-15] telemetry data
|
data[1-15] telemetry data
|
||||||
@@ -875,11 +1014,24 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
|||||||
technically DSM bind data is only 10 bytes but multi sends 16
|
technically DSM bind data is only 10 bytes but multi sends 16
|
||||||
like with telemtery, check length field)
|
like with telemtery, check length field)
|
||||||
|
|
||||||
Type 0x06 Flysky AFHDS2 telemetry data
|
Type 0x06 Flysky AFHDS2 telemetry data type 0xAA
|
||||||
length: 29
|
length: 29
|
||||||
data[0] = RSSI value
|
data[0] = RSSI value
|
||||||
data[1-28] telemetry data
|
data[1-28] telemetry data
|
||||||
|
|
||||||
|
Type 0x08 Input synchronisation
|
||||||
|
Informs the TX about desired rate and current delay
|
||||||
|
length: 4
|
||||||
|
data[0-1] Desired refresh rate in ??s
|
||||||
|
data[2-3] Time (??s) between last serial servo input received and servo input needed (lateness), TX should adjust its
|
||||||
|
sending time to minimise this value.
|
||||||
|
data[4] Interval of this message in ms
|
||||||
|
data[5] Input delay target in 10??s
|
||||||
|
Note that there are protocols (AFHDS2A) that have a refresh rate that is smaller than the maximum achievable
|
||||||
|
refresh rate via the serial protocol, in this case, the TX should double the rate and also subract this
|
||||||
|
refresh rate from the input lag if the input lag is more than the desired refresh rate.
|
||||||
|
The remote should try to get to zero of (inputdelay+target*10).
|
||||||
|
|
||||||
Type 0x0A Hitec telemetry data
|
Type 0x0A Hitec telemetry data
|
||||||
length: 8
|
length: 8
|
||||||
data[0] = TX RSSI value
|
data[0] = TX RSSI value
|
||||||
@@ -888,8 +1040,30 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
|||||||
data[3-7] telemetry data
|
data[3-7] telemetry data
|
||||||
Full description at the bottom of Hitec_cc2500.ino
|
Full description at the bottom of Hitec_cc2500.ino
|
||||||
|
|
||||||
Type 0x0B Spectrum Scanner telemetry data
|
Type 0x0B Spectrum Scanner telemetry data
|
||||||
length: 6
|
length: 6
|
||||||
data[0] = start channel (2400 + x*0.333 Mhz)
|
data[0] = start channel (2400 + x*0.333 Mhz)
|
||||||
data[1-5] power levels
|
data[1-5] power levels
|
||||||
|
|
||||||
|
Type 0x0C Flysky AFHDS2 telemetry data type 0xAC
|
||||||
|
length: 29
|
||||||
|
data[0] = RSSI value
|
||||||
|
data[1-28] telemetry data
|
||||||
|
|
||||||
|
Type 0x0D RX channels forwarding
|
||||||
|
length: variable
|
||||||
|
data[0] = received packets per second
|
||||||
|
data[1] = rssi
|
||||||
|
data[2] = start channel
|
||||||
|
data[3] = number of channels to follow
|
||||||
|
data[4-]= packed channels data, 11 bit per channel
|
||||||
|
|
||||||
|
Type 0x0E HoTT telemetry
|
||||||
|
length: 14
|
||||||
|
data[0] = TX_RSSI
|
||||||
|
data[1] = TX_LQI
|
||||||
|
data[2] = type
|
||||||
|
data[3] = page
|
||||||
|
data[4-13] = data
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -197,6 +197,9 @@ uint16_t NCC_callback()
|
|||||||
phase = NCC_BIND_TX2;
|
phase = NCC_BIND_TX2;
|
||||||
return NCC_PACKET_INTERVAL - NCC_WRITE_WAIT;
|
return NCC_PACKET_INTERVAL - NCC_WRITE_WAIT;
|
||||||
case NCC_TX3:
|
case NCC_TX3:
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(NCC_PACKET_INTERVAL);
|
||||||
|
#endif
|
||||||
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR))
|
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR))
|
||||||
{ // RX fifo data ready
|
{ // RX fifo data ready
|
||||||
NRF24L01_ReadPayload(packet, NCC_RX_PACKET_LEN);
|
NRF24L01_ReadPayload(packet, NCC_RX_PACKET_LEN);
|
||||||
@@ -268,9 +271,6 @@ uint16_t initNCC(void)
|
|||||||
hopping_frequency_no=4; // start with bind
|
hopping_frequency_no=4; // start with bind
|
||||||
NCC_init();
|
NCC_init();
|
||||||
phase=NCC_BIND_TX1;
|
phase=NCC_BIND_TX1;
|
||||||
#ifdef NCC1701_HUB_TELEMETRY
|
|
||||||
init_frskyd_link_telemetry();
|
|
||||||
#endif
|
|
||||||
return 10000;
|
return 10000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -505,7 +505,7 @@ boolean XN297_ReadPayload(uint8_t* msg, uint8_t len)
|
|||||||
//process address
|
//process address
|
||||||
for (uint8_t i = 0; i < xn297_addr_len; ++i)
|
for (uint8_t i = 0; i < xn297_addr_len; ++i)
|
||||||
{
|
{
|
||||||
uint8_t b_in=xn297_tx_addr[xn297_addr_len-i-1];
|
uint8_t b_in=xn297_rx_addr[xn297_addr_len-i-1];
|
||||||
if(xn297_scramble_enabled)
|
if(xn297_scramble_enabled)
|
||||||
b_in ^= xn297_scramble[i];
|
b_in ^= xn297_scramble[i];
|
||||||
crc = crc16_update(crc, b_in, 8);
|
crc = crc16_update(crc, b_in, 8);
|
||||||
@@ -525,10 +525,13 @@ boolean XN297_ReadPayload(uint8_t* msg, uint8_t len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint8_t XN297_ReadEnhancedPayload(uint8_t* msg, uint8_t len)
|
uint8_t XN297_ReadEnhancedPayload(uint8_t* msg, uint8_t len)
|
||||||
{
|
{ //!!! Don't forget do a +2 and if using CRC add +2 on any of the used NRF24L01_11_RX_PW_Px !!!
|
||||||
uint8_t buffer[32];
|
uint8_t buffer[32];
|
||||||
uint8_t pcf_size; // pcf payload size
|
uint8_t pcf_size; // pcf payload size
|
||||||
NRF24L01_ReadPayload(buffer, len+2); // pcf + payload
|
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];
|
pcf_size = buffer[0];
|
||||||
if(xn297_scramble_enabled)
|
if(xn297_scramble_enabled)
|
||||||
pcf_size ^= xn297_scramble[xn297_addr_len];
|
pcf_size ^= xn297_scramble[xn297_addr_len];
|
||||||
@@ -540,7 +543,35 @@ uint8_t XN297_ReadEnhancedPayload(uint8_t* msg, uint8_t len)
|
|||||||
msg[i] ^= bit_reverse((xn297_scramble[xn297_addr_len+i+1] << 2) |
|
msg[i] ^= bit_reverse((xn297_scramble[xn297_addr_len+i+1] << 2) |
|
||||||
(xn297_scramble[xn297_addr_len+i+2] >> 6));
|
(xn297_scramble[xn297_addr_len+i+2] >> 6));
|
||||||
}
|
}
|
||||||
return pcf_size;
|
|
||||||
|
if (!xn297_crc)
|
||||||
|
return pcf_size; // No CRC so OK by default...
|
||||||
|
|
||||||
|
// Calculate CRC
|
||||||
|
uint16_t 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];
|
||||||
|
crc = crc16_update(crc, b_in, 8);
|
||||||
|
}
|
||||||
|
//process payload
|
||||||
|
for (uint8_t i = 0; i < len+1; ++i)
|
||||||
|
crc = crc16_update(crc, buffer[i], 8);
|
||||||
|
crc = crc16_update(crc, 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
|
// End of XN297 emulation
|
||||||
|
|||||||
438
Multiprotocol/NRF250K_EMU.ino
Normal file
@@ -0,0 +1,438 @@
|
|||||||
|
/*
|
||||||
|
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/>.
|
||||||
|
*/
|
||||||
|
#ifdef NRF24L01_INSTALLED
|
||||||
|
#include "iface_nrf250k.h"
|
||||||
|
|
||||||
|
static void __attribute__((unused)) XN297L_Init()
|
||||||
|
{
|
||||||
|
#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");
|
||||||
|
PE1_off; // antenna RF2
|
||||||
|
PE2_on;
|
||||||
|
CC2500_Reset();
|
||||||
|
CC2500_Strobe(CC2500_SIDLE);
|
||||||
|
|
||||||
|
// Address Config = No address check
|
||||||
|
// Base Frequency = 2400
|
||||||
|
// CRC Autoflush = false
|
||||||
|
// CRC Enable = false
|
||||||
|
// Channel Spacing = 333.251953
|
||||||
|
// Data Format = Normal mode
|
||||||
|
// Data Rate = 249.939
|
||||||
|
// Deviation = 126.953125
|
||||||
|
// Device Address = 0
|
||||||
|
// Manchester Enable = false
|
||||||
|
// Modulated = true
|
||||||
|
// Modulation Format = GFSK
|
||||||
|
// Packet Length Mode = Variable packet length mode. Packet length configured by the first byte after sync word
|
||||||
|
// RX Filter BW = 203.125000
|
||||||
|
// Sync Word Qualifier Mode = No preamble/sync
|
||||||
|
// TX Power = 0
|
||||||
|
// Whitening = false
|
||||||
|
// Fast Frequency Hopping - no PLL auto calibration
|
||||||
|
|
||||||
|
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
|
||||||
|
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, 0xC3); // Frequency Control Word, Low Byte
|
||||||
|
CC2500_WriteReg(CC2500_10_MDMCFG4, 0x8D); // Modem Configuration
|
||||||
|
CC2500_WriteReg(CC2500_11_MDMCFG3, 0x3B); // Modem Configuration
|
||||||
|
CC2500_WriteReg(CC2500_12_MDMCFG2, 0x10); // Modem Configuration
|
||||||
|
CC2500_WriteReg(CC2500_13_MDMCFG1, 0x23); // Modem Configuration
|
||||||
|
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
|
||||||
|
|
||||||
|
CC2500_SetTxRxMode(TX_EN);
|
||||||
|
CC2500_SetPower();
|
||||||
|
xn297_scramble_enabled=XN297_SCRAMBLED; //enabled by default
|
||||||
|
#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;
|
||||||
|
static const uint16_t initial = 0xb5d2;
|
||||||
|
|
||||||
|
// 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
|
||||||
|
uint16_t crc = initial;
|
||||||
|
for (uint8_t i = 0; i < last; ++i)
|
||||||
|
crc = crc16_update(crc, 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
|
||||||
|
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[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)
|
||||||
|
{
|
||||||
|
uint8_t offset = xn297_addr_len < 4 ? 1 : 0;
|
||||||
|
uint16_t crc = 0xb5d2;
|
||||||
|
for (uint8_t i = offset; i < last; ++i)
|
||||||
|
crc = crc16_update(crc, buf[i], 8);
|
||||||
|
crc = crc16_update(crc, 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
|
||||||
|
for (uint8_t i = 0; i < num_freq; i++)
|
||||||
|
{
|
||||||
|
CC2500_Strobe(CC2500_SIDLE);
|
||||||
|
CC2500_WriteReg(CC2500_0A_CHANNR, hopping_frequency[i]*3);
|
||||||
|
CC2500_Strobe(CC2500_SCAL);
|
||||||
|
delayMicroseconds(900);
|
||||||
|
calData[i]=CC2500_ReadReg(CC2500_25_FSCAL1);
|
||||||
|
}
|
||||||
|
#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
|
||||||
|
// spacing is 333.25 kHz, must multiply xn297 channel by 3
|
||||||
|
CC2500_WriteReg(CC2500_0A_CHANNR, hopping_frequency[index] * 3);
|
||||||
|
// set PLL calibration
|
||||||
|
CC2500_WriteReg(CC2500_25_FSCAL1, calData[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_Strobe(CC2500_SIDLE);
|
||||||
|
CC2500_WriteReg(CC2500_0A_CHANNR, number*3);
|
||||||
|
CC2500_Strobe(CC2500_SCAL);
|
||||||
|
delayMicroseconds(900);
|
||||||
|
#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;
|
||||||
|
prev_option = option;
|
||||||
|
CC2500_WriteReg(CC2500_0C_FSCTRL0, option);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, len-2);
|
||||||
|
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, addr, len);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//CC2500
|
||||||
|
#ifdef CC2500_INSTALLED
|
||||||
|
xn297_addr_len = len;
|
||||||
|
memcpy(xn297_tx_addr, 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
|
||||||
|
uint8_t buf[35];
|
||||||
|
uint8_t last = 0;
|
||||||
|
uint8_t i;
|
||||||
|
|
||||||
|
//nrf preamble
|
||||||
|
if(xn297_tx_addr[xn297_addr_len - 1] & 0x80)
|
||||||
|
buf[0]=0xAA;
|
||||||
|
else
|
||||||
|
buf[0]=0x55;
|
||||||
|
last++;
|
||||||
|
// address
|
||||||
|
for (i = 0; i < xn297_addr_len; ++i)
|
||||||
|
buf[last++] = xn297_tx_addr[xn297_addr_len - i - 1];
|
||||||
|
// payload
|
||||||
|
for (i = 0; i < len; ++i)
|
||||||
|
buf[last++] = msg[i];
|
||||||
|
|
||||||
|
// crc
|
||||||
|
uint16_t crc = 0xffff;
|
||||||
|
for (uint8_t i = 1; i < last; ++i)
|
||||||
|
crc = crc16_update(crc, 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);
|
||||||
|
// nrf packet
|
||||||
|
CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, buf, last);
|
||||||
|
// transmit
|
||||||
|
CC2500_Strobe(CC2500_STX);
|
||||||
|
#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
|
||||||
@@ -109,6 +109,9 @@ uint16_t POTENSIC_callback()
|
|||||||
BIND_DONE;
|
BIND_DONE;
|
||||||
XN297_SetTXAddr(rx_tx_addr,5);
|
XN297_SetTXAddr(rx_tx_addr,5);
|
||||||
}
|
}
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(POTENSIC_PACKET_PERIOD);
|
||||||
|
#endif
|
||||||
POTENSIC_send_packet();
|
POTENSIC_send_packet();
|
||||||
return POTENSIC_PACKET_PERIOD;
|
return POTENSIC_PACKET_PERIOD;
|
||||||
}
|
}
|
||||||
|
|||||||
239
Multiprotocol/Pelikan_a7105.ino
Normal file
@@ -0,0 +1,239 @@
|
|||||||
|
/*
|
||||||
|
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 CADET PRO V4 TX
|
||||||
|
|
||||||
|
#if defined(PELIKAN_A7105_INO)
|
||||||
|
|
||||||
|
#include "iface_a7105.h"
|
||||||
|
|
||||||
|
//#define PELIKAN_FORCE_ID
|
||||||
|
|
||||||
|
#define PELIKAN_BIND_COUNT 400
|
||||||
|
#define PELIKAN_BIND_RF 0x3C
|
||||||
|
#define PELIKAN_NUM_RF_CHAN 0x1D
|
||||||
|
#define PELIKAN_PAQUET_PERIOD 7980
|
||||||
|
|
||||||
|
static void __attribute__((unused)) pelikan_build_packet()
|
||||||
|
{
|
||||||
|
static boolean upper=false;
|
||||||
|
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];
|
||||||
|
packet[6] = 0x05; //??
|
||||||
|
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);
|
||||||
|
uint8_t top=(channel>>2) & 0xC0;
|
||||||
|
packet[2] = channel;
|
||||||
|
channel=convert_channel_16b_nolimit(CH_AETR[offset++], 153, 871);
|
||||||
|
top|=(channel>>4) & 0x30;
|
||||||
|
packet[3] = channel;
|
||||||
|
channel=convert_channel_16b_nolimit(CH_AETR[offset++], 153, 871);
|
||||||
|
top|=(channel>>6) & 0x0C;
|
||||||
|
packet[4] = channel;
|
||||||
|
channel=convert_channel_16b_nolimit(CH_AETR[offset], 153, 871);
|
||||||
|
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(++packet_count>4)
|
||||||
|
{
|
||||||
|
packet_count=0;
|
||||||
|
if(++hopping_frequency_no>=PELIKAN_NUM_RF_CHAN)
|
||||||
|
hopping_frequency_no=0;
|
||||||
|
}
|
||||||
|
packet[10]=hopping_frequency_no;
|
||||||
|
packet[11]=packet_count;
|
||||||
|
|
||||||
|
packet_length = 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Check
|
||||||
|
crc8=0x15;
|
||||||
|
for(uint8_t i=1; i<packet_length-1 ;i++)
|
||||||
|
crc8+=packet[i];
|
||||||
|
packet[packet_length-1]=crc8;
|
||||||
|
|
||||||
|
//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("");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
A7105_WriteData(packet_length, IS_BIND_IN_PROGRESS?PELIKAN_BIND_RF:hopping_frequency[hopping_frequency_no]);
|
||||||
|
A7105_SetPower();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t ReadPelikan()
|
||||||
|
{
|
||||||
|
#ifndef FORCE_PELIKAN_TUNING
|
||||||
|
A7105_AdjustLOBaseFreq(1);
|
||||||
|
#endif
|
||||||
|
if(IS_BIND_IN_PROGRESS)
|
||||||
|
{
|
||||||
|
bind_counter--;
|
||||||
|
if (bind_counter==0)
|
||||||
|
{
|
||||||
|
BIND_DONE;
|
||||||
|
A7105_Strobe(A7105_STANDBY);
|
||||||
|
A7105_WriteReg(A7105_03_FIFOI,0x28);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(PELIKAN_PAQUET_PERIOD);
|
||||||
|
#endif
|
||||||
|
pelikan_build_packet();
|
||||||
|
return PELIKAN_PAQUET_PERIOD;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t pelikan_firstCh(uint8_t u, uint8_t l)
|
||||||
|
{
|
||||||
|
int16_t i;
|
||||||
|
i = u * 10 + l - 23;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (i > 24)
|
||||||
|
i -= 24;
|
||||||
|
if (i <= 0)
|
||||||
|
return 10;
|
||||||
|
else if ((i > 0) && (i < 13))
|
||||||
|
return 10 + 12 + (i * 4);
|
||||||
|
else if ((i > 12) && (i < 24))
|
||||||
|
return 10 - 2 + ((i - 12) * 4);
|
||||||
|
}
|
||||||
|
while (i > 24);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t pelikan_adjust_value(uint8_t value, uint8_t addition, uint8_t limit)
|
||||||
|
{
|
||||||
|
uint8_t i;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
i = 0;
|
||||||
|
if (value > limit) {
|
||||||
|
value -= 62;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (value == 24) {
|
||||||
|
value += addition;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (value == 48) {
|
||||||
|
value += addition;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (i > 0);
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t pelikan_add(uint8_t pfrq,uint8_t a, uint8_t limit)
|
||||||
|
{
|
||||||
|
uint8_t nfrq;
|
||||||
|
nfrq = pfrq + a;
|
||||||
|
|
||||||
|
nfrq = pelikan_adjust_value(nfrq, a, limit);
|
||||||
|
|
||||||
|
return nfrq;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __attribute__((unused)) pelikan_init_hop()
|
||||||
|
{
|
||||||
|
#define PELIKAN_HOP_LIMIT 70
|
||||||
|
rx_tx_addr[0] = 0;
|
||||||
|
rx_tx_addr[1]+= RX_num;
|
||||||
|
uint8_t high = (rx_tx_addr[1]>>4) % 3; // 0..2
|
||||||
|
uint8_t low = rx_tx_addr[1] & 0x0F;
|
||||||
|
if(high==2)
|
||||||
|
low %= 0x04; // 0..3
|
||||||
|
else if(high)
|
||||||
|
low %= 0x0E; // 0..D
|
||||||
|
else
|
||||||
|
low %= 0x0F; // 0..E
|
||||||
|
rx_tx_addr[1] = (high<<4) + low;
|
||||||
|
uint8_t addition = (20 * high)+ (2 * low) + 8;
|
||||||
|
|
||||||
|
uint8_t first_channel = pelikan_firstCh(high, low);
|
||||||
|
first_channel = pelikan_adjust_value(first_channel, addition, PELIKAN_HOP_LIMIT);
|
||||||
|
hopping_frequency[0] = first_channel;
|
||||||
|
debug("%02X", first_channel);
|
||||||
|
for (uint8_t i = 1; i < PELIKAN_NUM_RF_CHAN; i++)
|
||||||
|
{
|
||||||
|
hopping_frequency[i] = pelikan_add(hopping_frequency[i-1], addition, PELIKAN_HOP_LIMIT);
|
||||||
|
debug(" %02X", hopping_frequency[i]);
|
||||||
|
}
|
||||||
|
debugln("");
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef PELIKAN_FORCE_ID
|
||||||
|
const uint8_t PROGMEM pelikan_hopp[][PELIKAN_NUM_RF_CHAN] = {
|
||||||
|
{ 0x5A,0x46,0x32,0x6E,0x6C,0x58,0x44,0x42,0x40,0x6A,0x56,0x54,0x52,0x3E,0x68,0x66,0x64,0x50,0x3C,0x3A,0x38,0x62,0x4E,0x4C,0x5E,0x4A,0x36,0x5C,0x34 }
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint16_t initPelikan()
|
||||||
|
{
|
||||||
|
A7105_Init();
|
||||||
|
if(IS_BIND_IN_PROGRESS)
|
||||||
|
A7105_WriteReg(A7105_03_FIFOI,0x10);
|
||||||
|
|
||||||
|
//ID from dump
|
||||||
|
#ifdef PELIKAN_FORCE_ID
|
||||||
|
rx_tx_addr[0]=0x0D; // hopping freq
|
||||||
|
rx_tx_addr[1]=0xF4; // hopping freq
|
||||||
|
rx_tx_addr[2]=0x50; // ID
|
||||||
|
rx_tx_addr[3]=0x18; // ID
|
||||||
|
// 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]);
|
||||||
|
#else
|
||||||
|
pelikan_init_hop();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
hopping_frequency_no=PELIKAN_NUM_RF_CHAN;
|
||||||
|
packet_count=5;
|
||||||
|
return 2400;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -354,7 +354,12 @@ static void __attribute__((unused)) Q303_initialize_txid()
|
|||||||
uint16_t Q303_callback()
|
uint16_t Q303_callback()
|
||||||
{
|
{
|
||||||
if(IS_BIND_DONE)
|
if(IS_BIND_DONE)
|
||||||
|
{
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(packet_period);
|
||||||
|
#endif
|
||||||
Q303_send_packet(0);
|
Q303_send_packet(0);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (bind_counter == 0)
|
if (bind_counter == 0)
|
||||||
|
|||||||
@@ -125,6 +125,9 @@ static uint16_t ReadREDPINE()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(packet_period);
|
||||||
|
#endif
|
||||||
CC2500_SetTxRxMode(TX_EN);
|
CC2500_SetTxRxMode(TX_EN);
|
||||||
REDPINE_set_channel(hopping_frequency_no);
|
REDPINE_set_channel(hopping_frequency_no);
|
||||||
CC2500_SetPower();
|
CC2500_SetPower();
|
||||||
@@ -133,10 +136,7 @@ static uint16_t ReadREDPINE()
|
|||||||
CC2500_Strobe(CC2500_SIDLE);
|
CC2500_Strobe(CC2500_SIDLE);
|
||||||
hopping_frequency_no = (hopping_frequency_no + 1) % 49;
|
hopping_frequency_no = (hopping_frequency_no + 1) % 49;
|
||||||
CC2500_WriteData(packet, REDPINE_PACKET_SIZE);
|
CC2500_WriteData(packet, REDPINE_PACKET_SIZE);
|
||||||
if (sub_protocol==0)
|
return packet_period;
|
||||||
return REDPINE_LOOPTIME_FAST*100;
|
|
||||||
else
|
|
||||||
return REDPINE_LOOPTIME_SLOW*1000;
|
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -235,6 +235,11 @@ static uint16_t initREDPINE()
|
|||||||
}
|
}
|
||||||
hopping_frequency[49] = 0; // Last channel is the bind channel at hop 0
|
hopping_frequency[49] = 0; // Last channel is the bind channel at hop 0
|
||||||
|
|
||||||
|
if (sub_protocol==0)
|
||||||
|
packet_period = REDPINE_LOOPTIME_FAST*100;
|
||||||
|
else
|
||||||
|
packet_period = REDPINE_LOOPTIME_SLOW*1000;
|
||||||
|
|
||||||
bind_counter=REDPINE_BIND;
|
bind_counter=REDPINE_BIND;
|
||||||
REDPINE_init(sub_protocol);
|
REDPINE_init(sub_protocol);
|
||||||
CC2500_SetTxRxMode(TX_EN); // enable PA
|
CC2500_SetTxRxMode(TX_EN); // enable PA
|
||||||
|
|||||||
@@ -173,8 +173,8 @@ static void __attribute__((unused)) SFHSS_build_data_packet()
|
|||||||
else
|
else
|
||||||
{ //Use channel value
|
{ //Use channel value
|
||||||
ch[i]=(ch[i]>>1)+2560;
|
ch[i]=(ch[i]>>1)+2560;
|
||||||
if(CH_AETR[ch_offset+i]==THROTTLE && ch[i]<3072) // Throttle
|
//if(IS_DISABLE_CH_MAP_off && ch_offset+i==CH3 && ch[i]<3072) // Throttle
|
||||||
ch[i]+=1024;
|
// ch[i]+=1024;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -235,6 +235,9 @@ uint16_t ReadSFHSS()
|
|||||||
#define SFHSS_PACKET_PERIOD 6800
|
#define SFHSS_PACKET_PERIOD 6800
|
||||||
#define SFHSS_DATA2_TIMING 1625 // Adjust this value between 1600 and 1650 if your RX(s) are not operating properly
|
#define SFHSS_DATA2_TIMING 1625 // Adjust this value between 1600 and 1650 if your RX(s) are not operating properly
|
||||||
case SFHSS_DATA1:
|
case SFHSS_DATA1:
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(6800);
|
||||||
|
#endif
|
||||||
SFHSS_build_data_packet();
|
SFHSS_build_data_packet();
|
||||||
SFHSS_send_packet();
|
SFHSS_send_packet();
|
||||||
phase = SFHSS_DATA2;
|
phase = SFHSS_DATA2;
|
||||||
|
|||||||
@@ -63,6 +63,10 @@ void SHENQI_send_packet()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
if(packet_count==1)
|
||||||
|
telemetry_set_input_sync(3000+2508+6*1750);
|
||||||
|
#endif
|
||||||
LT8900_SetAddress(rx_tx_addr,4);
|
LT8900_SetAddress(rx_tx_addr,4);
|
||||||
packet[1]=255-convert_channel_8b(RUDDER);
|
packet[1]=255-convert_channel_8b(RUDDER);
|
||||||
packet[2]=255-convert_channel_16b_limit(THROTTLE,0x60,0xA0);
|
packet[2]=255-convert_channel_16b_limit(THROTTLE,0x60,0xA0);
|
||||||
@@ -91,7 +95,9 @@ void SHENQI_send_packet()
|
|||||||
uint16_t SHENQI_callback()
|
uint16_t SHENQI_callback()
|
||||||
{
|
{
|
||||||
if(IS_BIND_DONE)
|
if(IS_BIND_DONE)
|
||||||
|
{
|
||||||
SHENQI_send_packet();
|
SHENQI_send_packet();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR))
|
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR))
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
#if defined(SLT_NRF24L01_INO)
|
#if defined(SLT_NRF24L01_INO)
|
||||||
|
|
||||||
#include "iface_nrf24l01.h"
|
#include "iface_nrf250k.h"
|
||||||
|
|
||||||
//#define SLT_Q200_FORCE_ID
|
//#define SLT_Q200_FORCE_ID
|
||||||
|
|
||||||
@@ -25,6 +25,7 @@
|
|||||||
#define SLT_PAYLOADSIZE_V2 11
|
#define SLT_PAYLOADSIZE_V2 11
|
||||||
#define SLT_NFREQCHANNELS 15
|
#define SLT_NFREQCHANNELS 15
|
||||||
#define SLT_TXID_SIZE 4
|
#define SLT_TXID_SIZE 4
|
||||||
|
#define SLT_BIND_CHANNEL 0x50
|
||||||
|
|
||||||
enum{
|
enum{
|
||||||
// flags going to packet[6] (Q200)
|
// flags going to packet[6] (Q200)
|
||||||
@@ -48,30 +49,13 @@ enum {
|
|||||||
SLT_DATA2,
|
SLT_DATA2,
|
||||||
SLT_DATA3,
|
SLT_DATA3,
|
||||||
SLT_BIND1,
|
SLT_BIND1,
|
||||||
SLT_BIND2
|
SLT_BIND2,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void __attribute__((unused)) SLT_init()
|
static void __attribute__((unused)) SLT_init()
|
||||||
{
|
{
|
||||||
NRF24L01_Initialize();
|
NRF250K_Init();
|
||||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO)); // 2-bytes CRC, radio off
|
NRF250K_SetTXAddr(rx_tx_addr, SLT_TXID_SIZE);
|
||||||
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, 0x00); // Disable auto retransmit
|
|
||||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
|
|
||||||
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, 4); // bytes of data payload for pipe 1
|
|
||||||
NRF24L01_SetBitrate(NRF24L01_BR_250K); // 256kbps
|
|
||||||
NRF24L01_SetPower();
|
|
||||||
if(sub_protocol==SLT_V1)
|
|
||||||
NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, (uint8_t*)"\xC3\xC3\xAA\x55", SLT_TXID_SIZE);
|
|
||||||
else // V2
|
|
||||||
NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, (uint8_t*)"\x7E\xB8\x63\xA9", SLT_TXID_SIZE);
|
|
||||||
NRF24L01_FlushRx();
|
|
||||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, rx_tx_addr, SLT_TXID_SIZE);
|
|
||||||
NRF24L01_FlushTx();
|
|
||||||
// Turn radio power on
|
|
||||||
NRF24L01_SetTxRxMode(TX_EN);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __attribute__((unused)) SLT_set_freq(void)
|
static void __attribute__((unused)) SLT_set_freq(void)
|
||||||
@@ -109,21 +93,25 @@ static void __attribute__((unused)) SLT_set_freq(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Bind channel
|
||||||
|
hopping_frequency[SLT_NFREQCHANNELS]=SLT_BIND_CHANNEL;
|
||||||
|
|
||||||
|
//Calib all channels
|
||||||
|
NRF250K_HoppingCalib(SLT_NFREQCHANNELS+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __attribute__((unused)) SLT_wait_radio()
|
static void __attribute__((unused)) SLT_wait_radio()
|
||||||
{
|
{
|
||||||
if (packet_sent)
|
if (packet_sent)
|
||||||
while (!(NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_TX_DS)));
|
while (!NRF250K_IsPacketSent());
|
||||||
packet_sent = 0;
|
packet_sent = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __attribute__((unused)) SLT_send_packet(uint8_t len)
|
static void __attribute__((unused)) SLT_send_packet(uint8_t len)
|
||||||
{
|
{
|
||||||
SLT_wait_radio();
|
SLT_wait_radio();
|
||||||
NRF24L01_FlushTx();
|
NRF250K_WritePayload(packet, len);
|
||||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, _BV(NRF24L01_07_TX_DS) | _BV(NRF24L01_07_RX_DR) | _BV(NRF24L01_07_MAX_RT));
|
|
||||||
NRF24L01_WritePayload(packet, len);
|
|
||||||
packet_sent = 1;
|
packet_sent = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,7 +120,8 @@ static void __attribute__((unused)) SLT_build_packet()
|
|||||||
static uint8_t calib_counter=0;
|
static uint8_t calib_counter=0;
|
||||||
|
|
||||||
// Set radio channel - once per packet batch
|
// Set radio channel - once per packet batch
|
||||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no]);
|
NRF250K_SetFreqOffset(); // Set frequency offset
|
||||||
|
NRF250K_Hopping(hopping_frequency_no);
|
||||||
if (++hopping_frequency_no >= SLT_NFREQCHANNELS)
|
if (++hopping_frequency_no >= SLT_NFREQCHANNELS)
|
||||||
hopping_frequency_no = 0;
|
hopping_frequency_no = 0;
|
||||||
|
|
||||||
@@ -141,7 +130,7 @@ static void __attribute__((unused)) SLT_build_packet()
|
|||||||
for (uint8_t i = 0; i < 4; ++i)
|
for (uint8_t i = 0; i < 4; ++i)
|
||||||
{
|
{
|
||||||
uint16_t v = convert_channel_10b(CH_AETR[i]);
|
uint16_t v = convert_channel_10b(CH_AETR[i]);
|
||||||
if(sub_protocol>SLT_V2 && (CH_AETR[i]==THROTTLE || CH_AETR[i]==ELEVATOR) )
|
if(sub_protocol>SLT_V2 && (i==CH2 || i==CH3) )
|
||||||
v=1023-v; // reverse throttle and elevator channels for Q100/Q200/MR100 protocols
|
v=1023-v; // reverse throttle and elevator channels for Q100/Q200/MR100 protocols
|
||||||
packet[i] = v;
|
packet[i] = v;
|
||||||
e = (e >> 2) | (uint8_t) ((v >> 2) & 0xC0);
|
e = (e >> 2) | (uint8_t) ((v >> 2) & 0xC0);
|
||||||
@@ -183,23 +172,16 @@ static void __attribute__((unused)) SLT_build_packet()
|
|||||||
static void __attribute__((unused)) SLT_send_bind_packet()
|
static void __attribute__((unused)) SLT_send_bind_packet()
|
||||||
{
|
{
|
||||||
SLT_wait_radio();
|
SLT_wait_radio();
|
||||||
BIND_IN_PROGRESS; //Limit TX power to bind level
|
NRF250K_Hopping(SLT_NFREQCHANNELS); //Bind channel
|
||||||
NRF24L01_SetPower();
|
BIND_IN_PROGRESS; //Limit TX power to bind level
|
||||||
|
NRF250K_SetPower();
|
||||||
BIND_DONE;
|
BIND_DONE;
|
||||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, (uint8_t *)"\x7E\xB8\x63\xA9", SLT_TXID_SIZE);
|
NRF250K_SetTXAddr((uint8_t *)"\x7E\xB8\x63\xA9", SLT_TXID_SIZE);
|
||||||
|
|
||||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, 0x50);
|
|
||||||
memcpy((void*)packet,(void*)rx_tx_addr,SLT_TXID_SIZE);
|
memcpy((void*)packet,(void*)rx_tx_addr,SLT_TXID_SIZE);
|
||||||
if(phase==SLT_BIND2)
|
if(phase==SLT_BIND2)
|
||||||
SLT_send_packet(SLT_TXID_SIZE);
|
SLT_send_packet(SLT_TXID_SIZE);
|
||||||
else // SLT_BIND1
|
else // SLT_BIND1
|
||||||
SLT_send_packet(SLT_PAYLOADSIZE_V2);
|
SLT_send_packet(SLT_PAYLOADSIZE_V2);
|
||||||
|
|
||||||
SLT_wait_radio(); //Wait until the packet's sent before changing TX address!
|
|
||||||
|
|
||||||
NRF24L01_SetPower(); //Change power back to normal level
|
|
||||||
if(phase==SLT_BIND2) // after V1 bind and V2 second bind packet
|
|
||||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, rx_tx_addr, SLT_TXID_SIZE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SLT_TIMING_BUILD 1000
|
#define SLT_TIMING_BUILD 1000
|
||||||
@@ -213,7 +195,12 @@ uint16_t SLT_callback()
|
|||||||
switch (phase)
|
switch (phase)
|
||||||
{
|
{
|
||||||
case SLT_BUILD:
|
case SLT_BUILD:
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(sub_protocol==SLT_V1?20000:13730);
|
||||||
|
#endif
|
||||||
SLT_build_packet();
|
SLT_build_packet();
|
||||||
|
NRF250K_SetPower(); //Change power level
|
||||||
|
NRF250K_SetTXAddr(rx_tx_addr, SLT_TXID_SIZE);
|
||||||
phase++;
|
phase++;
|
||||||
return SLT_TIMING_BUILD;
|
return SLT_TIMING_BUILD;
|
||||||
case SLT_DATA1:
|
case SLT_DATA1:
|
||||||
@@ -250,7 +237,6 @@ uint16_t SLT_callback()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{// Continue to send normal packets
|
{// Continue to send normal packets
|
||||||
NRF24L01_SetPower(); // Set tx_power
|
|
||||||
phase = SLT_BUILD;
|
phase = SLT_BUILD;
|
||||||
if(sub_protocol==SLT_V1)
|
if(sub_protocol==SLT_V1)
|
||||||
return 20000-SLT_TIMING_BUILD;
|
return 20000-SLT_TIMING_BUILD;
|
||||||
@@ -286,8 +272,8 @@ uint16_t initSLT()
|
|||||||
/* rx_tx_addr[0]=0x01;rx_tx_addr[1]=0x02;rx_tx_addr[2]=0x0B;rx_tx_addr[3]=0x57;*/
|
/* rx_tx_addr[0]=0x01;rx_tx_addr[1]=0x02;rx_tx_addr[2]=0x0B;rx_tx_addr[3]=0x57;*/
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
SLT_set_freq();
|
|
||||||
SLT_init();
|
SLT_init();
|
||||||
|
SLT_set_freq();
|
||||||
phase = SLT_BUILD;
|
phase = SLT_BUILD;
|
||||||
return 50000;
|
return 50000;
|
||||||
}
|
}
|
||||||
|
|||||||
177
Multiprotocol/SX1276_SPI.ino
Normal file
@@ -0,0 +1,177 @@
|
|||||||
|
#ifdef SX1276_INSTALLED
|
||||||
|
#include "iface_sx1276.h"
|
||||||
|
|
||||||
|
void SX1276_WriteReg(uint8_t address, uint8_t data)
|
||||||
|
{
|
||||||
|
SPI_CSN_off;
|
||||||
|
SPI_Write(address | 0x80); // MSB 1 = write
|
||||||
|
NOP();
|
||||||
|
SPI_Write(data);
|
||||||
|
SPI_CSN_on;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t SX1276_ReadReg(uint8_t address)
|
||||||
|
{
|
||||||
|
SPI_CSN_off;
|
||||||
|
SPI_Write(address & 0x7F);
|
||||||
|
uint8_t result = SPI_Read();
|
||||||
|
SPI_CSN_on;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SX1276_WriteRegisterMulti(uint8_t address, const uint8_t* data, uint8_t length)
|
||||||
|
{
|
||||||
|
SPI_CSN_off;
|
||||||
|
SPI_Write(address | 0x80); // MSB 1 = write
|
||||||
|
|
||||||
|
for(uint8_t i = 0; i < length; i++)
|
||||||
|
SPI_Write(data[i]);
|
||||||
|
|
||||||
|
SPI_CSN_on;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t SX1276_Reset()
|
||||||
|
{
|
||||||
|
//TODO
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SX1276_SetFrequency(uint32_t frequency)
|
||||||
|
{
|
||||||
|
uint32_t f = frequency / 61;
|
||||||
|
uint8_t data[3];
|
||||||
|
data[0] = (f & (0xFF << 16)) >> 16;
|
||||||
|
data[1] = (f & (0xFF << 8)) >> 8;
|
||||||
|
data[2] = f & 0xFF;
|
||||||
|
|
||||||
|
SX1276_WriteRegisterMulti(SX1276_06_FRFMSB, data, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SX1276_SetMode(bool lora, bool low_freq_mode, uint8_t mode)
|
||||||
|
{
|
||||||
|
uint8_t data = 0x00;
|
||||||
|
|
||||||
|
if(lora)
|
||||||
|
{
|
||||||
|
data = data | (1 << 7);
|
||||||
|
data = data & ~(1 << 6);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data = data & ~(1 << 7);
|
||||||
|
data = data | (1 << 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(low_freq_mode)
|
||||||
|
data = data | (1 << 3);
|
||||||
|
|
||||||
|
data = data | mode;
|
||||||
|
|
||||||
|
SX1276_WriteReg(SX1276_01_OPMODE, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SX1276_SetDetectOptimize(bool auto_if, uint8_t detect_optimize)
|
||||||
|
{
|
||||||
|
uint8_t data = SX1276_ReadReg(SX1276_31_DETECTOPTIMIZE);
|
||||||
|
data = (data & 0b01111000) | detect_optimize;
|
||||||
|
data = data | (auto_if << 7);
|
||||||
|
|
||||||
|
SX1276_WriteReg(SX1276_31_DETECTOPTIMIZE, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SX1276_ConfigModem1(uint8_t bandwidth, uint8_t coding_rate, bool implicit_header_mode)
|
||||||
|
{
|
||||||
|
uint8_t data = 0x00;
|
||||||
|
data = data | (bandwidth << 4);
|
||||||
|
data = data | (coding_rate << 1);
|
||||||
|
data = data | implicit_header_mode;
|
||||||
|
|
||||||
|
SX1276_WriteReg(SX1276_1D_MODEMCONFIG1, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SX1276_ConfigModem2(uint8_t spreading_factor, bool tx_continuous_mode, bool rx_payload_crc_on)
|
||||||
|
{
|
||||||
|
uint8_t data = SX1276_ReadReg(SX1276_1E_MODEMCONFIG2);
|
||||||
|
data = data & 0b11; // preserve the last 2 bits
|
||||||
|
data = data | (spreading_factor << 4);
|
||||||
|
data = data | (tx_continuous_mode << 3);
|
||||||
|
data = data | (rx_payload_crc_on << 2);
|
||||||
|
|
||||||
|
SX1276_WriteReg(SX1276_1E_MODEMCONFIG2, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SX1276_ConfigModem3(bool low_data_rate_optimize, bool agc_auto_on)
|
||||||
|
{
|
||||||
|
uint8_t data = SX1276_ReadReg(SX1276_26_MODEMCONFIG3);
|
||||||
|
data = data & 0b11; // preserve the last 2 bits
|
||||||
|
data = data | (low_data_rate_optimize << 3);
|
||||||
|
data = data | (agc_auto_on << 2);
|
||||||
|
|
||||||
|
SX1276_WriteReg(SX1276_26_MODEMCONFIG3, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SX1276_SetPreambleLength(uint16_t length)
|
||||||
|
{
|
||||||
|
uint8_t data[2];
|
||||||
|
data[0] = (length >> 8) & 0xFF; // high byte
|
||||||
|
data[1] = length & 0xFF; // low byte
|
||||||
|
|
||||||
|
SX1276_WriteRegisterMulti(SX1276_20_PREAMBLEMSB, data, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SX1276_SetDetectionThreshold(uint8_t threshold)
|
||||||
|
{
|
||||||
|
SX1276_WriteReg(SX1276_37_DETECTIONTHRESHOLD, threshold);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SX1276_SetLna(uint8_t gain, bool high_freq_lna_boost)
|
||||||
|
{
|
||||||
|
uint8_t data = SX1276_ReadReg(SX1276_0C_LNA);
|
||||||
|
data = data & 0b100; // preserve the third bit
|
||||||
|
data = data | (gain << 5);
|
||||||
|
|
||||||
|
if(high_freq_lna_boost)
|
||||||
|
data = data | 0b11;
|
||||||
|
|
||||||
|
SX1276_WriteReg(SX1276_0C_LNA, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SX1276_SetHopPeriod(uint8_t freq_hop_period)
|
||||||
|
{
|
||||||
|
SX1276_WriteReg(SX1276_24_HOPPERIOD, freq_hop_period);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SX1276_SetPaDac(bool on)
|
||||||
|
{
|
||||||
|
uint8_t data = SX1276_ReadReg(SX1276_4D_PADAC);
|
||||||
|
data = data & 0b11111000; // preserve the upper 5 bits
|
||||||
|
|
||||||
|
if(on)
|
||||||
|
data = data | 0x07;
|
||||||
|
else
|
||||||
|
data = data | 0x04;
|
||||||
|
|
||||||
|
SX1276_WriteReg(SX1276_4D_PADAC, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SX1276_SetPaConfig(bool pa_boost_pin, uint8_t max_power, uint8_t output_power)
|
||||||
|
{
|
||||||
|
uint8_t data = 0x00;
|
||||||
|
data = data | (pa_boost_pin << 7);
|
||||||
|
data = data | (max_power << 4);
|
||||||
|
data = data | output_power;
|
||||||
|
|
||||||
|
SX1276_WriteReg(SX1276_09_PACONFIG, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SX1276_WritePayloadToFifo(uint8_t* payload, uint8_t length)
|
||||||
|
{
|
||||||
|
SX1276_WriteReg(SX1276_22_PAYLOAD_LENGTH, length);
|
||||||
|
SX1276_WriteReg(SX1276_0E_FIFOTXBASEADDR, 0x00);
|
||||||
|
SX1276_WriteReg(SX1276_0D_FIFOADDRPTR, 0x00);
|
||||||
|
SX1276_WriteRegisterMulti(SX1276_00_FIFO, payload, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -18,12 +18,11 @@
|
|||||||
#include "iface_cc2500.h"
|
#include "iface_cc2500.h"
|
||||||
|
|
||||||
#define SCAN_MAX_RADIOCHANNEL 249 // 2483 MHz
|
#define SCAN_MAX_RADIOCHANNEL 249 // 2483 MHz
|
||||||
#define SCAN_CHANNEL_LOCK_TIME 300 // with precalibration, channel requires only 90 usec for synthesizer to settle
|
#define SCAN_CHANNEL_LOCK_TIME 90 // with precalibration, channel requires only 90 usec for synthesizer to settle
|
||||||
#define SCAN_AVERAGE_INTVL 30
|
#define SCAN_AVERAGE_INTVL 20
|
||||||
|
#define SCAN_MAX_COUNT 10
|
||||||
#define SCAN_CHANS_PER_PACKET 5
|
#define SCAN_CHANS_PER_PACKET 5
|
||||||
|
|
||||||
static uint8_t scan_tlm_index;
|
|
||||||
|
|
||||||
enum ScanStates {
|
enum ScanStates {
|
||||||
SCAN_CHANNEL_CHANGE = 0,
|
SCAN_CHANNEL_CHANGE = 0,
|
||||||
SCAN_GET_RSSI = 1,
|
SCAN_GET_RSSI = 1,
|
||||||
@@ -89,42 +88,53 @@ static int __attribute__((unused)) Scanner_scan_rssi()
|
|||||||
rssi_rel = rssi - 128; // relative power levels 0-127 (equals -137 to -72 dBm)
|
rssi_rel = rssi - 128; // relative power levels 0-127 (equals -137 to -72 dBm)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rssi_rel = rssi + 128; // relativ power levels 128-255 (equals -73 to -10 dBm)
|
rssi_rel = rssi + 128; // relative power levels 128-255 (equals -73 to -10 dBm)
|
||||||
}
|
}
|
||||||
return rssi_rel;
|
return rssi_rel;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t Scanner_callback()
|
uint16_t Scanner_callback()
|
||||||
{
|
{
|
||||||
switch (phase)
|
uint8_t rssi,max_rssi;
|
||||||
{
|
|
||||||
case SCAN_CHANNEL_CHANGE:
|
//!!!Blocking mode protocol!!!
|
||||||
|
TX_MAIN_PAUSE_off;
|
||||||
|
tx_resume();
|
||||||
|
while(1)
|
||||||
|
{ //Start
|
||||||
|
packet_in[0] = rf_ch_num; // start channel for telemetry packet
|
||||||
|
for(uint8_t i=0;i<SCAN_CHANS_PER_PACKET;i++)
|
||||||
|
{
|
||||||
|
Scanner_scan_next(); // set channel
|
||||||
|
delayMicroseconds(SCAN_CHANNEL_LOCK_TIME); // wait for freq to adjust
|
||||||
|
max_rssi = 0;
|
||||||
|
for(uint8_t j=0;j<SCAN_MAX_COUNT;j++)
|
||||||
|
{
|
||||||
|
rssi = Scanner_scan_rssi();
|
||||||
|
if(rssi >= max_rssi) max_rssi = rssi;
|
||||||
|
delayMicroseconds(SCAN_AVERAGE_INTVL); // wait before next read
|
||||||
|
}
|
||||||
|
packet_in[i+1] = max_rssi;
|
||||||
|
//next channel
|
||||||
rf_ch_num++;
|
rf_ch_num++;
|
||||||
if (rf_ch_num >= (SCAN_MAX_RADIOCHANNEL + 1))
|
if (rf_ch_num >= (SCAN_MAX_RADIOCHANNEL + 1))
|
||||||
rf_ch_num = 0;
|
rf_ch_num = 0;
|
||||||
if (scan_tlm_index++ == 0)
|
}
|
||||||
pkt[0] = rf_ch_num; // start channel for telemetry packet
|
telemetry_link = 1;
|
||||||
Scanner_scan_next();
|
do
|
||||||
phase = SCAN_GET_RSSI;
|
{
|
||||||
return SCAN_CHANNEL_LOCK_TIME;
|
if(Update_All())
|
||||||
case SCAN_GET_RSSI:
|
return 1000; // protocol has changed, give back the control to main
|
||||||
phase = SCAN_CHANNEL_CHANGE;
|
}
|
||||||
pkt[scan_tlm_index] = Scanner_scan_rssi();
|
while(telemetry_link == 1);
|
||||||
if (scan_tlm_index == SCAN_CHANS_PER_PACKET)
|
|
||||||
{
|
|
||||||
// send data to TX
|
|
||||||
telemetry_link = 1;
|
|
||||||
scan_tlm_index = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return SCAN_AVERAGE_INTVL;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t initScanner(void)
|
uint16_t initScanner(void)
|
||||||
{
|
{
|
||||||
rf_ch_num = SCAN_MAX_RADIOCHANNEL;
|
rf_ch_num = 0;
|
||||||
scan_tlm_index = 0;
|
telemetry_link = 0;
|
||||||
phase = SCAN_CHANNEL_CHANGE;
|
|
||||||
Scanner_cc2500_init();
|
Scanner_cc2500_init();
|
||||||
CC2500_Strobe(CC2500_SRX);
|
CC2500_Strobe(CC2500_SRX);
|
||||||
Scanner_calibrate();
|
Scanner_calibrate();
|
||||||
|
|||||||
@@ -359,6 +359,9 @@ uint16_t symax_callback()
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SYMAX_DATA:
|
case SYMAX_DATA:
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(SYMAX_PACKET_PERIOD);
|
||||||
|
#endif
|
||||||
SYMAX_send_packet(0);
|
SYMAX_send_packet(0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -162,6 +162,9 @@ uint16_t ReadTRAXXAS()
|
|||||||
TRAXXAS_cyrf_data_config();
|
TRAXXAS_cyrf_data_config();
|
||||||
phase++;
|
phase++;
|
||||||
case TRAXXAS_DATA:
|
case TRAXXAS_DATA:
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(13940);
|
||||||
|
#endif
|
||||||
TRAXXAS_send_data_packet();
|
TRAXXAS_send_data_packet();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
182
Multiprotocol/Tiger_nrf24l01.ino
Normal file
@@ -0,0 +1,182 @@
|
|||||||
|
/*
|
||||||
|
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 Tiger Drone 1400782.
|
||||||
|
|
||||||
|
#if defined(TIGER_NRF24L01_INO)
|
||||||
|
|
||||||
|
#include "iface_nrf24l01.h"
|
||||||
|
|
||||||
|
#define TIGER_FORCE_ID
|
||||||
|
|
||||||
|
#define TIGER_INITIAL_WAIT 500
|
||||||
|
#define TIGER_PACKET_PERIOD 3940
|
||||||
|
#define TIGER_RF_NUM_CHANNELS 4
|
||||||
|
#define TIGER_BIND_RF_NUM_CHANNELS 8
|
||||||
|
#define TIGER_PAYLOAD_SIZE 16
|
||||||
|
#define TIGER_BIND_COUNT 761 //3sec
|
||||||
|
|
||||||
|
|
||||||
|
static uint8_t __attribute__((unused)) TIGER_convert_channel(uint8_t num)
|
||||||
|
{
|
||||||
|
uint8_t val=convert_channel_8b(num);
|
||||||
|
// 7F..01=left, 00=center, 80..FF=right
|
||||||
|
if(val==0x80)
|
||||||
|
val=0; // 0
|
||||||
|
else
|
||||||
|
if(val>0x80)
|
||||||
|
val--; // 80..FE
|
||||||
|
else
|
||||||
|
{
|
||||||
|
val=0x80-val; // 80..01
|
||||||
|
if(val==0x80)
|
||||||
|
val--; // 7F..01
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __attribute__((unused)) TIGER_send_packet()
|
||||||
|
{
|
||||||
|
if(IS_BIND_DONE)
|
||||||
|
{
|
||||||
|
//Channels
|
||||||
|
packet[0]=convert_channel_8b(THROTTLE); // 00..FF
|
||||||
|
packet[1]=TIGER_convert_channel(RUDDER); // 7F..01=left, 00=center, 80..FF=right
|
||||||
|
packet[2]=TIGER_convert_channel(ELEVATOR); // 7F..01=down, 00=center, 80..FF=up
|
||||||
|
packet[3]=TIGER_convert_channel(AILERON); // 7F..01=left, 00=center, 80..FF=right
|
||||||
|
//Flags
|
||||||
|
packet[14]= GET_FLAG(CH5_SW, 0x04) //FLIP
|
||||||
|
| GET_FLAG(CH6_SW, 0x10); //LIGHT
|
||||||
|
}
|
||||||
|
//Check
|
||||||
|
crc8=0;
|
||||||
|
for(uint8_t i=0;i<TIGER_PAYLOAD_SIZE-1;i++)
|
||||||
|
crc8+=packet[i];
|
||||||
|
packet[TIGER_PAYLOAD_SIZE-1]=crc8;
|
||||||
|
|
||||||
|
//Hopping frequency
|
||||||
|
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no>>1]);
|
||||||
|
hopping_frequency_no++;
|
||||||
|
if(IS_BIND_IN_PROGRESS)
|
||||||
|
{
|
||||||
|
if(hopping_frequency_no>=2*TIGER_BIND_RF_NUM_CHANNELS)
|
||||||
|
hopping_frequency_no=0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(hopping_frequency_no>=2*(TIGER_BIND_RF_NUM_CHANNELS+TIGER_RF_NUM_CHANNELS))
|
||||||
|
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
|
||||||
|
XN297_WritePayload(packet, TIGER_PAYLOAD_SIZE);
|
||||||
|
//Set tx_power
|
||||||
|
NRF24L01_SetPower();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __attribute__((unused)) TIGER_init()
|
||||||
|
{
|
||||||
|
NRF24L01_Initialize();
|
||||||
|
NRF24L01_SetTxRxMode(TX_EN);
|
||||||
|
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()
|
||||||
|
{
|
||||||
|
#ifdef TIGER_FORCE_ID
|
||||||
|
rx_tx_addr[0]=0x64;
|
||||||
|
rx_tx_addr[1]=0x39;
|
||||||
|
rx_tx_addr[2]=0x12;
|
||||||
|
rx_tx_addr[3]=0x00;
|
||||||
|
rx_tx_addr[4]=0x00;
|
||||||
|
memcpy(hopping_frequency,"\x0E\x39\x1C\x07\x24\x3E\x2B\x47",TIGER_BIND_RF_NUM_CHANNELS);
|
||||||
|
memcpy(&hopping_frequency[TIGER_BIND_RF_NUM_CHANNELS],"\x36\x41\x37\x4E",TIGER_RF_NUM_CHANNELS);
|
||||||
|
#endif
|
||||||
|
//prepare bind packet
|
||||||
|
memset(&packet[0], 0x00, 4);
|
||||||
|
memset(&packet[4], 0x40, 10);
|
||||||
|
memcpy(&packet[7], rx_tx_addr, 5);
|
||||||
|
packet[14]=0xC0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t TIGER_callback()
|
||||||
|
{
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(TIGER_PACKET_PERIOD);
|
||||||
|
#endif
|
||||||
|
if(IS_BIND_IN_PROGRESS)
|
||||||
|
if(--bind_counter==0)
|
||||||
|
{
|
||||||
|
BIND_DONE;
|
||||||
|
XN297_SetTXAddr((uint8_t *)"\x49\xA6\x83\xEB\x4B", 5);
|
||||||
|
}
|
||||||
|
TIGER_send_packet();
|
||||||
|
return TIGER_PACKET_PERIOD;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t initTIGER()
|
||||||
|
{
|
||||||
|
BIND_IN_PROGRESS; // autobind protocol
|
||||||
|
TIGER_initialize_txid();
|
||||||
|
TIGER_init();
|
||||||
|
hopping_frequency_no = 0;
|
||||||
|
bind_counter=TIGER_BIND_COUNT;
|
||||||
|
return TIGER_INITIAL_WAIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
/*Bind
|
||||||
|
- RF setup: 1Mbps, scrambled, CRC
|
||||||
|
- TX addr: 0x68 0x94 0xA6 0xD5 0xC3
|
||||||
|
- 8 RF channels: 0x0E 0x39 0x1C 0x07 0x24 0x3E 0x2B 0x47
|
||||||
|
- 2 packets per RF channel, 3940µs between packets
|
||||||
|
- payload 16 bytes: 0x00 0x00 0x00 0x00 0x40 0x40 0x40 0x64 0x39 0x12 0x00 0x00 0x40 0x40 0xC0 0xAF
|
||||||
|
- payload[15]=sum of payload[0..14]
|
||||||
|
- the only difference with normal packets is the payload[14]=0xC0
|
||||||
|
- ??? payload[7..11] TX ID ???
|
||||||
|
|
||||||
|
Normal
|
||||||
|
- RF setup: 1Mbps
|
||||||
|
- TX addr: 0x49 0xA6 0x83 0xEB 0x4B
|
||||||
|
- 4 RF channels: 0x36 0x41 0x37 0x4E
|
||||||
|
- 2 packets per RF channel, 3940µs between packets
|
||||||
|
- payload 16 bytes: 0x00 0x00 0x00 0x00 0x40 0x40 0x40 0x64 0x39 0x12 0x00 0x00 0x40 0x40 0x00 0xEF
|
||||||
|
- payload[15]=sum of payload[0..14]
|
||||||
|
- throttle is on payload[0] 00..FF
|
||||||
|
- rudder is on payload[1] 00=center, 80..FF=right, 01..7F=left
|
||||||
|
- elevator is on payload[2] 00=center, 80..FF=up, 01..7F=down
|
||||||
|
- aileron is on payload[3] 00=center, 80..FF=right, 01..7F=left
|
||||||
|
- trims payload[4..6]
|
||||||
|
- ??? payload[7..11] TX ID ???
|
||||||
|
- ??? payload[12..13] ???
|
||||||
|
- flip is on payload[14] and flag 0x04
|
||||||
|
- light is on payload[14] and flag 0x10
|
||||||
|
*/
|
||||||
@@ -264,6 +264,9 @@ uint16_t ReadV2x2()
|
|||||||
case V202_DATA:
|
case V202_DATA:
|
||||||
if (packet_sent && NRF24L01_packet_ack() != PKT_ACKED)
|
if (packet_sent && NRF24L01_packet_ack() != PKT_ACKED)
|
||||||
return V2X2_PACKET_CHKTIME;
|
return V2X2_PACKET_CHKTIME;
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(V2X2_PACKET_PERIOD);
|
||||||
|
#endif
|
||||||
V2X2_send_packet(0);
|
V2X2_send_packet(0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -174,6 +174,9 @@ uint16_t V761_callback()
|
|||||||
}
|
}
|
||||||
return 15730;
|
return 15730;
|
||||||
case V761_DATA:
|
case V761_DATA:
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(V761_PACKET_PERIOD);
|
||||||
|
#endif
|
||||||
V761_send_packet();
|
V761_send_packet();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
#if defined(V911S_NRF24L01_INO)
|
#if defined(V911S_NRF24L01_INO)
|
||||||
|
|
||||||
#include "iface_xn297l.h"
|
#include "iface_nrf250k.h"
|
||||||
|
|
||||||
//#define V911S_ORIGINAL_ID
|
//#define V911S_ORIGINAL_ID
|
||||||
|
|
||||||
@@ -30,6 +30,8 @@
|
|||||||
|
|
||||||
// flags going to packet[1]
|
// flags going to packet[1]
|
||||||
#define V911S_FLAG_EXPERT 0x04
|
#define V911S_FLAG_EXPERT 0x04
|
||||||
|
#define E119_FLAG_EXPERT 0x08
|
||||||
|
#define E119_FLAG_CALIB 0x40
|
||||||
// flags going to packet[2]
|
// flags going to packet[2]
|
||||||
#define V911S_FLAG_CALIB 0x01
|
#define V911S_FLAG_CALIB 0x01
|
||||||
|
|
||||||
@@ -56,10 +58,21 @@ static void __attribute__((unused)) V911S_send_packet(uint8_t bind)
|
|||||||
}
|
}
|
||||||
if(rf_ch_num&2)
|
if(rf_ch_num&2)
|
||||||
channel=7-channel;
|
channel=7-channel;
|
||||||
|
XN297L_Hopping(channel);
|
||||||
|
hopping_frequency_no++;
|
||||||
|
hopping_frequency_no&=7; // 8 RF channels
|
||||||
|
|
||||||
packet[ 0]=(rf_ch_num<<3)|channel;
|
packet[ 0]=(rf_ch_num<<3)|channel;
|
||||||
packet[ 1]=V911S_FLAG_EXPERT; // short press on left button
|
memset(packet+1, 0x00, V911S_PACKET_SIZE - 1);
|
||||||
packet[ 2]=GET_FLAG(CH5_SW,V911S_FLAG_CALIB); // long press on right button
|
if(sub_protocol==V911S_STD)
|
||||||
memset(packet+3, 0x00, V911S_PACKET_SIZE - 3);
|
{
|
||||||
|
packet[ 1]=V911S_FLAG_EXPERT; // short press on left button
|
||||||
|
packet[ 2]=GET_FLAG(CH5_SW,V911S_FLAG_CALIB); // long press on right button
|
||||||
|
}
|
||||||
|
else
|
||||||
|
packet[ 1]=E119_FLAG_EXPERT // short press on left button
|
||||||
|
|GET_FLAG(CH5_SW,E119_FLAG_CALIB); // short press on right button
|
||||||
|
|
||||||
//packet[3..6]=trims TAER signed
|
//packet[3..6]=trims TAER signed
|
||||||
uint16_t ch=convert_channel_16b_limit(THROTTLE ,0,0x7FF);
|
uint16_t ch=convert_channel_16b_limit(THROTTLE ,0,0x7FF);
|
||||||
packet[ 7] = ch;
|
packet[ 7] = ch;
|
||||||
@@ -68,21 +81,30 @@ static void __attribute__((unused)) V911S_send_packet(uint8_t bind)
|
|||||||
packet[ 8]|= ch<<3;
|
packet[ 8]|= ch<<3;
|
||||||
packet[ 9] = ch>>5;
|
packet[ 9] = ch>>5;
|
||||||
ch=convert_channel_16b_limit(ELEVATOR,0,0x7FF);
|
ch=convert_channel_16b_limit(ELEVATOR,0,0x7FF);
|
||||||
packet[10] = ch;
|
if(sub_protocol==V911S_STD)
|
||||||
packet[11] = ch>>8;
|
{
|
||||||
ch=convert_channel_16b_limit(RUDDER ,0x7FF,0);
|
packet[10] = ch;
|
||||||
packet[11]|= ch<<3;
|
packet[11] = ch>>8;
|
||||||
packet[12] = ch>>5;
|
ch=convert_channel_16b_limit(RUDDER ,0x7FF,0);
|
||||||
|
packet[11]|= ch<<3;
|
||||||
|
packet[12] = ch>>5;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ch=0x7FF-ch;
|
||||||
|
packet[ 9]|= ch<<6;
|
||||||
|
packet[10] = ch>>2;
|
||||||
|
packet[11] = ch>>10;
|
||||||
|
ch=convert_channel_16b_limit(RUDDER ,0x7FF,0);
|
||||||
|
packet[11]|= ch<<1;
|
||||||
|
packet[12] = ch>>7;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bind)
|
if(sub_protocol==V911S_STD)
|
||||||
{
|
XN297L_WritePayload(packet, V911S_PACKET_SIZE);
|
||||||
XN297L_Hopping(channel);
|
else
|
||||||
hopping_frequency_no++;
|
XN297L_WriteEnhancedPayload(packet, V911S_PACKET_SIZE, bind?0:1);
|
||||||
hopping_frequency_no&=7; // 8 RF channels
|
|
||||||
}
|
|
||||||
|
|
||||||
XN297L_WritePayload(packet, V911S_PACKET_SIZE);
|
|
||||||
|
|
||||||
XN297L_SetPower(); // Set tx_power
|
XN297L_SetPower(); // Set tx_power
|
||||||
XN297L_SetFreqOffset(); // Set frequency offset
|
XN297L_SetFreqOffset(); // Set frequency offset
|
||||||
@@ -91,7 +113,10 @@ static void __attribute__((unused)) V911S_send_packet(uint8_t bind)
|
|||||||
static void __attribute__((unused)) V911S_init()
|
static void __attribute__((unused)) V911S_init()
|
||||||
{
|
{
|
||||||
XN297L_Init();
|
XN297L_Init();
|
||||||
XN297L_SetTXAddr((uint8_t *)"KNBND",5); // Bind address
|
if(sub_protocol==V911S_STD)
|
||||||
|
XN297L_SetTXAddr((uint8_t *)"KNBND",5); // V911S Bind address
|
||||||
|
else
|
||||||
|
XN297L_SetTXAddr((uint8_t *)"XPBND",5); // E119 Bind address
|
||||||
XN297L_HoppingCalib(V911S_NUM_RF_CHANNELS); // Calibrate all channels
|
XN297L_HoppingCalib(V911S_NUM_RF_CHANNELS); // Calibrate all channels
|
||||||
XN297L_RFChannel(V911S_RF_BIND_CHANNEL); // Set bind channel
|
XN297L_RFChannel(V911S_RF_BIND_CHANNEL); // Set bind channel
|
||||||
}
|
}
|
||||||
@@ -111,7 +136,12 @@ static void __attribute__((unused)) V911S_initialize_txid()
|
|||||||
uint16_t V911S_callback()
|
uint16_t V911S_callback()
|
||||||
{
|
{
|
||||||
if(IS_BIND_DONE)
|
if(IS_BIND_DONE)
|
||||||
|
{
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(V911S_PACKET_PERIOD);
|
||||||
|
#endif
|
||||||
V911S_send_packet(0);
|
V911S_send_packet(0);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (bind_counter == 0)
|
if (bind_counter == 0)
|
||||||
@@ -135,15 +165,30 @@ uint16_t initV911S(void)
|
|||||||
{
|
{
|
||||||
V911S_initialize_txid();
|
V911S_initialize_txid();
|
||||||
#ifdef V911S_ORIGINAL_ID
|
#ifdef V911S_ORIGINAL_ID
|
||||||
rx_tx_addr[0]=0xA5;
|
if(sub_protocol==V911S_STD)
|
||||||
rx_tx_addr[1]=0xFF;
|
{//V911S
|
||||||
rx_tx_addr[2]=0x70;
|
rx_tx_addr[0]=0xA5;
|
||||||
rx_tx_addr[3]=0x8D;
|
rx_tx_addr[1]=0xFF;
|
||||||
rx_tx_addr[4]=0x76;
|
rx_tx_addr[2]=0x70;
|
||||||
for(uint8_t i=0;i<V911S_NUM_RF_CHANNELS;i++)
|
rx_tx_addr[3]=0x8D;
|
||||||
hopping_frequency[i]=0x10+i*5;
|
rx_tx_addr[4]=0x76;
|
||||||
hopping_frequency[0]++;
|
for(uint8_t i=0;i<V911S_NUM_RF_CHANNELS;i++)
|
||||||
rf_ch_num=0;
|
hopping_frequency[i]=0x10+i*5;
|
||||||
|
hopping_frequency[0]++;
|
||||||
|
rf_ch_num=0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//E119
|
||||||
|
rx_tx_addr[0]=0x30;
|
||||||
|
rx_tx_addr[1]=0xFF;
|
||||||
|
rx_tx_addr[2]=0xD1;
|
||||||
|
rx_tx_addr[3]=0x2C;
|
||||||
|
rx_tx_addr[4]=0x2A;
|
||||||
|
for(uint8_t i=0;i<V911S_NUM_RF_CHANNELS;i++)
|
||||||
|
hopping_frequency[i]=0x0E + i*5;
|
||||||
|
rf_ch_num=0;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
V911S_init();
|
V911S_init();
|
||||||
@@ -19,9 +19,9 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Check for minimum board file definition version for DIY multi-module boards
|
// Check for minimum board file definition version for DIY multi-module boards
|
||||||
#define MIN_AVR_BOARD 108
|
#define MIN_AVR_BOARD 110
|
||||||
#define MIN_ORX_BOARD 108
|
#define MIN_ORX_BOARD 110
|
||||||
#define MIN_STM32_BOARD 115
|
#define MIN_STM32_BOARD 117
|
||||||
//AVR
|
//AVR
|
||||||
#if (defined(ARDUINO_MULTI_NO_BOOT) && ARDUINO_MULTI_NO_BOOT < MIN_AVR_BOARD) || (defined(ARDUINO_MULTI_FLASH_FROM_TX) && ARDUINO_MULTI_FLASH_FROM_TX < MIN_AVR_BOARD)
|
#if (defined(ARDUINO_MULTI_NO_BOOT) && ARDUINO_MULTI_NO_BOOT < MIN_AVR_BOARD) || (defined(ARDUINO_MULTI_FLASH_FROM_TX) && ARDUINO_MULTI_FLASH_FROM_TX < MIN_AVR_BOARD)
|
||||||
#error You need to update your Multi 4-in-1 board definition. Open Boards Manager and update to the latest version of the Multi 4-in-1 AVR Boards.
|
#error You need to update your Multi 4-in-1 board definition. Open Boards Manager and update to the latest version of the Multi 4-in-1 AVR Boards.
|
||||||
@@ -89,6 +89,11 @@
|
|||||||
#error "The FrSkyX forced frequency tuning value is outside of the range -127..127."
|
#error "The FrSkyX forced frequency tuning value is outside of the range -127..127."
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef FORCE_FRSKYX2_TUNING
|
||||||
|
#if ( FORCE_FRSKYX2_TUNING < -127 ) || ( FORCE_FRSKYX2_TUNING > 127 )
|
||||||
|
#error "The FrSkyX2 forced frequency tuning value is outside of the range -127..127."
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
#ifdef FORCE_HITEC_TUNING
|
#ifdef FORCE_HITEC_TUNING
|
||||||
#if ( FORCE_HITEC_TUNING < -127 ) || ( FORCE_HITEC_TUNING > 127 )
|
#if ( FORCE_HITEC_TUNING < -127 ) || ( FORCE_HITEC_TUNING > 127 )
|
||||||
#error "The HITEC forced frequency tuning value is outside of the range -127..127."
|
#error "The HITEC forced frequency tuning value is outside of the range -127..127."
|
||||||
@@ -104,6 +109,11 @@
|
|||||||
#error "The SFHSS forced frequency tuning value is outside of the range -127..127."
|
#error "The SFHSS forced frequency tuning value is outside of the range -127..127."
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef FORCE_HOTT_TUNING
|
||||||
|
#if ( FORCE_HOTT_TUNING < -127 ) || ( FORCE_HOTT_TUNING > 127 )
|
||||||
|
#error "The HOTT forced frequency tuning value is outside of the range -127..127."
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
//A7105
|
//A7105
|
||||||
#ifdef FORCE_AFHDS2A_TUNING
|
#ifdef FORCE_AFHDS2A_TUNING
|
||||||
#if ( FORCE_AFHDS2A_TUNING < -300 ) || ( FORCE_AFHDS2A_TUNING > 300 )
|
#if ( FORCE_AFHDS2A_TUNING < -300 ) || ( FORCE_AFHDS2A_TUNING > 300 )
|
||||||
@@ -125,6 +135,11 @@
|
|||||||
#error "The Flyzone forced frequency tuning value is outside of the range -300..300."
|
#error "The Flyzone forced frequency tuning value is outside of the range -300..300."
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef FORCE_PELIKAN_TUNING
|
||||||
|
#if ( FORCE_PELIKAN_TUNING < -300 ) || ( FORCE_PELIKAN_TUNING > 300 )
|
||||||
|
#error "The Pelikan forced frequency tuning value is outside of the range -300..300."
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
#ifdef FORCE_HUBSAN_TUNING
|
#ifdef FORCE_HUBSAN_TUNING
|
||||||
#if ( FORCE_HUBSAN_TUNING < -300 ) || ( FORCE_HUBSAN_TUNING > 300 )
|
#if ( FORCE_HUBSAN_TUNING < -300 ) || ( FORCE_HUBSAN_TUNING > 300 )
|
||||||
#error "The Hubsan forced frequency tuning value is outside of the range -300..300."
|
#error "The Hubsan forced frequency tuning value is outside of the range -300..300."
|
||||||
@@ -141,6 +156,9 @@
|
|||||||
#ifndef FORCE_FLYZONE_TUNING
|
#ifndef FORCE_FLYZONE_TUNING
|
||||||
#define FORCE_FLYZONE_TUNING 0
|
#define FORCE_FLYZONE_TUNING 0
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef FORCE_PELIKAN_TUNING
|
||||||
|
#define FORCE_PELIKAN_TUNING 0
|
||||||
|
#endif
|
||||||
#ifndef FORCE_HUBSAN_TUNING
|
#ifndef FORCE_HUBSAN_TUNING
|
||||||
#define FORCE_HUBSAN_TUNING 0
|
#define FORCE_HUBSAN_TUNING 0
|
||||||
#endif
|
#endif
|
||||||
@@ -162,6 +180,7 @@
|
|||||||
#undef CC25_CSN_pin
|
#undef CC25_CSN_pin
|
||||||
#undef NRF24L01_INSTALLED // Disable NRF for OrangeTX module
|
#undef NRF24L01_INSTALLED // Disable NRF for OrangeTX module
|
||||||
#undef NRF_CSN_pin
|
#undef NRF_CSN_pin
|
||||||
|
#undef SX1276_INSTALLED // Disable NRF for OrangeTX module
|
||||||
#define TELEMETRY // Enable telemetry
|
#define TELEMETRY // Enable telemetry
|
||||||
#define INVERT_TELEMETRY // Enable invert telemetry
|
#define INVERT_TELEMETRY // Enable invert telemetry
|
||||||
#define DSM_TELEMETRY // Enable DSM telemetry
|
#define DSM_TELEMETRY // Enable DSM telemetry
|
||||||
@@ -174,10 +193,13 @@
|
|||||||
#undef AFHDS2A_A7105_INO
|
#undef AFHDS2A_A7105_INO
|
||||||
#undef BUGS_A7105_INO
|
#undef BUGS_A7105_INO
|
||||||
#undef FLYZONE_A7105_INO
|
#undef FLYZONE_A7105_INO
|
||||||
|
#undef AFHDS2A_RX_A7105_INO
|
||||||
|
#undef PELIKAN_A7105_INO
|
||||||
#endif
|
#endif
|
||||||
#ifndef CYRF6936_INSTALLED
|
#ifndef CYRF6936_INSTALLED
|
||||||
#undef DEVO_CYRF6936_INO
|
#undef DEVO_CYRF6936_INO
|
||||||
#undef DSM_CYRF6936_INO
|
#undef DSM_CYRF6936_INO
|
||||||
|
#undef HOTT_CC2500_INO
|
||||||
#undef J6PRO_CYRF6936_INO
|
#undef J6PRO_CYRF6936_INO
|
||||||
#undef WFLY_CYRF6936_INO
|
#undef WFLY_CYRF6936_INO
|
||||||
#undef WK2x01_CYRF6936_INO
|
#undef WK2x01_CYRF6936_INO
|
||||||
@@ -187,12 +209,14 @@
|
|||||||
#undef FRSKYD_CC2500_INO
|
#undef FRSKYD_CC2500_INO
|
||||||
#undef FRSKYV_CC2500_INO
|
#undef FRSKYV_CC2500_INO
|
||||||
#undef FRSKYX_CC2500_INO
|
#undef FRSKYX_CC2500_INO
|
||||||
|
#undef FRSKYX2_CC2500_INO
|
||||||
#undef SFHSS_CC2500_INO
|
#undef SFHSS_CC2500_INO
|
||||||
#undef CORONA_CC2500_INO
|
#undef CORONA_CC2500_INO
|
||||||
#undef REDPINE_CC2500_INO
|
#undef REDPINE_CC2500_INO
|
||||||
#undef HITEC_CC2500_INO
|
#undef HITEC_CC2500_INO
|
||||||
#undef XN297L_CC2500_EMU
|
|
||||||
#undef SCANNER_CC2500_INO
|
#undef SCANNER_CC2500_INO
|
||||||
|
#undef FRSKY_RX_CC2500_INO
|
||||||
|
#undef HOTT_CC2500_INO
|
||||||
#endif
|
#endif
|
||||||
#ifndef NRF24L01_INSTALLED
|
#ifndef NRF24L01_INSTALLED
|
||||||
#undef BAYANG_NRF24L01_INO
|
#undef BAYANG_NRF24L01_INO
|
||||||
@@ -209,6 +233,7 @@
|
|||||||
#undef MT99XX_NRF24L01_INO
|
#undef MT99XX_NRF24L01_INO
|
||||||
#undef MJXQ_NRF24L01_INO
|
#undef MJXQ_NRF24L01_INO
|
||||||
#undef SHENQI_NRF24L01_INO
|
#undef SHENQI_NRF24L01_INO
|
||||||
|
#undef FX816_NRF24L01_INO
|
||||||
#undef FY326_NRF24L01_INO
|
#undef FY326_NRF24L01_INO
|
||||||
#undef FQ777_NRF24L01_INO
|
#undef FQ777_NRF24L01_INO
|
||||||
#undef ASSAN_NRF24L01_INO
|
#undef ASSAN_NRF24L01_INO
|
||||||
@@ -226,9 +251,17 @@
|
|||||||
#undef E01X_NRF24L01_INO
|
#undef E01X_NRF24L01_INO
|
||||||
#undef V761_NRF24L01_INO
|
#undef V761_NRF24L01_INO
|
||||||
#undef V911S_NRF24L01_INO
|
#undef V911S_NRF24L01_INO
|
||||||
#undef XN297L_CC2500_EMU
|
|
||||||
#undef POTENSIC_NRF24L01_INO
|
#undef POTENSIC_NRF24L01_INO
|
||||||
#undef ZSX_NRF24L01_INO
|
#undef ZSX_NRF24L01_INO
|
||||||
|
#undef BAYANG_RX_NRF24L01_INO
|
||||||
|
#undef TIGER_NRF24L01_INO
|
||||||
|
#undef XK_NRF24L01_INO
|
||||||
|
#endif
|
||||||
|
#if not defined(STM32_BOARD)
|
||||||
|
#undef SX1276_INSTALLED
|
||||||
|
#endif
|
||||||
|
#ifndef SX1276_INSTALLED
|
||||||
|
#undef FRSKYR9_SX1276_INO
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//Make sure telemetry is selected correctly
|
//Make sure telemetry is selected correctly
|
||||||
@@ -245,17 +278,38 @@
|
|||||||
#undef NCC1701_HUB_TELEMETRY
|
#undef NCC1701_HUB_TELEMETRY
|
||||||
#undef HUB_TELEMETRY
|
#undef HUB_TELEMETRY
|
||||||
#undef SPORT_TELEMETRY
|
#undef SPORT_TELEMETRY
|
||||||
#undef SPORT_POLLING
|
#undef SPORT_SEND
|
||||||
#undef DSM_TELEMETRY
|
#undef DSM_TELEMETRY
|
||||||
#undef MULTI_STATUS
|
#undef MULTI_STATUS
|
||||||
#undef MULTI_TELEMETRY
|
#undef MULTI_TELEMETRY
|
||||||
#undef SCANNER_TELEMETRY
|
#undef SCANNER_TELEMETRY
|
||||||
|
#undef SCANNER_CC2500_INO
|
||||||
|
#undef FRSKY_RX_TELEMETRY
|
||||||
|
#undef FRSKY_RX_CC2500_INO
|
||||||
|
#undef AFHDS2A_RX_TELEMETRY
|
||||||
|
#undef AFHDS2A_RX_A7105_INO
|
||||||
|
#undef HOTT_FW_TELEMETRY
|
||||||
|
#undef BAYANG_RX_TELEMETRY
|
||||||
|
#undef BAYANG_RX_NRF24L01_INO
|
||||||
#else
|
#else
|
||||||
#if defined MULTI_TELEMETRY && not defined INVERT_TELEMETRY
|
#if defined(MULTI_TELEMETRY) && defined(MULTI_STATUS)
|
||||||
#warning MULTI_TELEMETRY has been defined but not INVERT_TELEMETRY. They should be both enabled for OpenTX telemetry and status to work.
|
#error You should choose either MULTI_TELEMETRY or MULTI_STATUS but not both.
|
||||||
#endif
|
#endif
|
||||||
#if not defined(SCANNER_CC2500_INO)
|
#if not defined(SCANNER_CC2500_INO) || not defined(SCANNER_TELEMETRY)
|
||||||
#undef SCANNER_TELEMETRY
|
#undef SCANNER_TELEMETRY
|
||||||
|
#undef SCANNER_CC2500_INO
|
||||||
|
#endif
|
||||||
|
#if not defined(FRSKY_RX_CC2500_INO) || not defined(FRSKY_RX_TELEMETRY)
|
||||||
|
#undef FRSKY_RX_TELEMETRY
|
||||||
|
#undef FRSKY_RX_CC2500_INO
|
||||||
|
#endif
|
||||||
|
#if not defined(AFHDS2A_RX_A7105_INO) || not defined(AFHDS2A_RX_TELEMETRY)
|
||||||
|
#undef AFHDS2A_RX_TELEMETRY
|
||||||
|
#undef AFHDS2A_RX_A7105_INO
|
||||||
|
#endif
|
||||||
|
#if not defined(BAYANG_RX_NRF24L01_INO) || not defined(BAYANG_RX_TELEMETRY)
|
||||||
|
#undef BAYANG_RX_TELEMETRY
|
||||||
|
#undef BAYANG_RX_NRF24L01_INO
|
||||||
#endif
|
#endif
|
||||||
#if not defined(BAYANG_NRF24L01_INO)
|
#if not defined(BAYANG_NRF24L01_INO)
|
||||||
#undef BAYANG_HUB_TELEMETRY
|
#undef BAYANG_HUB_TELEMETRY
|
||||||
@@ -263,7 +317,7 @@
|
|||||||
#if not defined(NCC1701_NRF24L01_INO)
|
#if not defined(NCC1701_NRF24L01_INO)
|
||||||
#undef NCC1701_HUB_TELEMETRY
|
#undef NCC1701_HUB_TELEMETRY
|
||||||
#endif
|
#endif
|
||||||
#if not ( defined(BUGS_A7105_INO) || defined(BUGSMINI_NRF24L01_INO) )
|
#if not defined(BUGS_A7105_INO) && not defined(BUGSMINI_NRF24L01_INO)
|
||||||
#undef BUGS_HUB_TELEMETRY
|
#undef BUGS_HUB_TELEMETRY
|
||||||
#endif
|
#endif
|
||||||
#if not defined(CABELL_NRF24L01_INO)
|
#if not defined(CABELL_NRF24L01_INO)
|
||||||
@@ -283,26 +337,42 @@
|
|||||||
#if not defined(FRSKYD_CC2500_INO)
|
#if not defined(FRSKYD_CC2500_INO)
|
||||||
#undef HUB_TELEMETRY
|
#undef HUB_TELEMETRY
|
||||||
#endif
|
#endif
|
||||||
#if not defined(FRSKYX_CC2500_INO)
|
#if not defined(FRSKYX_CC2500_INO) and not defined(FRSKYX2_CC2500_INO)
|
||||||
#undef SPORT_TELEMETRY
|
#undef SPORT_TELEMETRY
|
||||||
#undef SPORT_POLLING
|
#undef SPORT_SEND
|
||||||
#endif
|
#endif
|
||||||
#if not defined (SPORT_TELEMETRY) || not defined (STM32_BOARD)
|
#if not defined (SPORT_TELEMETRY)
|
||||||
#undef SPORT_POLLING
|
#undef SPORT_SEND
|
||||||
#endif
|
|
||||||
#if defined SPORT_POLLING && not defined INVERT_TELEMETRY
|
|
||||||
#error SPORT_POLLING has been defined but not INVERT_TELEMETRY. They should be both enabled to work.
|
|
||||||
#endif
|
#endif
|
||||||
#if not defined(DSM_CYRF6936_INO)
|
#if not defined(DSM_CYRF6936_INO)
|
||||||
#undef DSM_TELEMETRY
|
#undef DSM_TELEMETRY
|
||||||
#endif
|
#endif
|
||||||
#if not defined(DSM_TELEMETRY) && not defined(SPORT_TELEMETRY) && not defined(HUB_TELEMETRY) && not defined(HUBSAN_HUB_TELEMETRY) && not defined(BUGS_HUB_TELEMETRY) && not defined(NCC1701_HUB_TELEMETRY) && not defined(BAYANG_HUB_TELEMETRY) && not defined(CABELL_HUB_TELEMETRY) && not defined(AFHDS2A_HUB_TELEMETRY) && not defined(AFHDS2A_FW_TELEMETRY) && not defined(MULTI_TELEMETRY) && not defined(MULTI_STATUS) && not defined(HITEC_HUB_TELEMETRY) && not defined(HITEC_FW_TELEMETRY) && not defined(SCANNER_TELEMETRY)
|
#if not defined(HOTT_CC2500_INO)
|
||||||
|
#undef HOTT_FW_TELEMETRY
|
||||||
|
#endif
|
||||||
|
#if not defined(HOTT_FW_TELEMETRY) && not defined(DSM_TELEMETRY) && not defined(SPORT_TELEMETRY) && not defined(HUB_TELEMETRY) && not defined(HUBSAN_HUB_TELEMETRY) && not defined(BUGS_HUB_TELEMETRY) && not defined(NCC1701_HUB_TELEMETRY) && not defined(BAYANG_HUB_TELEMETRY) && not defined(CABELL_HUB_TELEMETRY) && not defined(AFHDS2A_HUB_TELEMETRY) && not defined(AFHDS2A_FW_TELEMETRY) && not defined(MULTI_TELEMETRY) && not defined(MULTI_STATUS) && not defined(HITEC_HUB_TELEMETRY) && not defined(HITEC_FW_TELEMETRY) && not defined(SCANNER_TELEMETRY) && not defined(FRSKY_RX_TELEMETRY) && not defined(AFHDS2A_RX_TELEMETRY) && not defined(BAYANG_RX_TELEMETRY)
|
||||||
#undef TELEMETRY
|
#undef TELEMETRY
|
||||||
#undef INVERT_TELEMETRY
|
#undef INVERT_TELEMETRY
|
||||||
#undef SPORT_POLLING
|
#undef MULTI_TELEMETRY
|
||||||
|
#undef MULTI_STATUS
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef SPORT_TELEMETRY
|
||||||
|
#define SPORT_SEND
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if not defined(STM32_BOARD)
|
||||||
|
#undef MULTI_SYNC
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if not defined(MULTI_TELEMETRY)
|
||||||
|
#undef MULTI_SYNC
|
||||||
|
#undef MULTI_NAMES
|
||||||
|
#else
|
||||||
|
#define MULTI_NAMES
|
||||||
|
#endif
|
||||||
|
|
||||||
//Make sure TX is defined correctly
|
//Make sure TX is defined correctly
|
||||||
#ifndef AILERON
|
#ifndef AILERON
|
||||||
#error You must select a correct channel order.
|
#error You must select a correct channel order.
|
||||||
@@ -354,3 +424,18 @@
|
|||||||
#if defined (STM32_BOARD) && defined (DEBUG_SERIAL) && defined (NRF24L01_INSTALLED)
|
#if defined (STM32_BOARD) && defined (DEBUG_SERIAL) && defined (NRF24L01_INSTALLED)
|
||||||
#define XN297DUMP_NRF24L01_INO
|
#define XN297DUMP_NRF24L01_INO
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//Check if Direct inputs defined correctly
|
||||||
|
#if defined (ENABLE_DIRECT_INPUTS)
|
||||||
|
#if not defined (STM32_BOARD) || not defined (ENABLE_PPM) || defined (ENABLE_SERIAL)
|
||||||
|
#error You can enable dirct inputs only in PPM mode and only for STM32 board.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if not defined (DI1_PIN) && not defined (DI2_PIN) && not defined (DI3_PIN) && not defined (DI4_PIN)
|
||||||
|
#error You must define at least 1 direct input pin or undefine ENABLE_DIRECT_INPUTS in config.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if not defined (DI_CH1_read) && not defined (DI_CH2_read) && not defined (DI_CH3_read) && not defined (DI_CH4_read)
|
||||||
|
#error You must define at least 1 direct input chanell read macros or undefine ENABLE_DIRECT_INPUTS in config.
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -194,25 +194,25 @@ uint16_t ReadWFLY()
|
|||||||
debugln("L=%02X",len)
|
debugln("L=%02X",len)
|
||||||
if(len==0x10)
|
if(len==0x10)
|
||||||
{
|
{
|
||||||
CYRF_ReadDataPacketLen(pkt, len);
|
CYRF_ReadDataPacketLen(packet_in, len);
|
||||||
debug("RX=");
|
debug("RX=");
|
||||||
for(uint8_t i=0;i<0x0F;i++)
|
for(uint8_t i=0;i<0x0F;i++)
|
||||||
{
|
{
|
||||||
debug(" %02X",pkt[i]);
|
debug(" %02X",packet_in[i]);
|
||||||
if(pkt[i]==packet[i])
|
if(packet_in[i]==packet[i])
|
||||||
check++; // Verify quickly the content
|
check++; // Verify quickly the content
|
||||||
sum+=pkt[i];
|
sum+=packet_in[i];
|
||||||
}
|
}
|
||||||
debugln(" %02X",pkt[15]);
|
debugln(" %02X",packet_in[15]);
|
||||||
if(sum==pkt[15] && check>=10)
|
if(sum==packet_in[15] && check>=10)
|
||||||
{ // Good packet received
|
{ // Good packet received
|
||||||
if(pkt[2]==0x64)
|
if(packet_in[2]==0x64)
|
||||||
{ // Switch to normal mode
|
{ // Switch to normal mode
|
||||||
BIND_DONE;
|
BIND_DONE;
|
||||||
phase=WFLY_PREP_DATA;
|
phase=WFLY_PREP_DATA;
|
||||||
return 10000;
|
return 10000;
|
||||||
}
|
}
|
||||||
memcpy((void *)packet,(void *)pkt,0x10); // Send back to the RX what we've just received with no modifications
|
memcpy((void *)packet,(void *)packet_in,0x10); // Send back to the RX what we've just received with no modifications
|
||||||
}
|
}
|
||||||
phase=WFLY_BIND_TX;
|
phase=WFLY_BIND_TX;
|
||||||
return 200;
|
return 200;
|
||||||
@@ -232,6 +232,9 @@ uint16_t ReadWFLY()
|
|||||||
packet_count=0;
|
packet_count=0;
|
||||||
phase++;
|
phase++;
|
||||||
case WFLY_DATA:
|
case WFLY_DATA:
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(5371);
|
||||||
|
#endif
|
||||||
start=micros();
|
start=micros();
|
||||||
while ((uint8_t)((uint8_t)micros()-(uint8_t)start) < 200)
|
while ((uint8_t)((uint8_t)micros()-(uint8_t)start) < 200)
|
||||||
if((CYRF_ReadRegister(CYRF_02_TX_CTRL) & 0x80) == 0x00)
|
if((CYRF_ReadRegister(CYRF_02_TX_CTRL) & 0x80) == 0x00)
|
||||||
|
|||||||
@@ -435,6 +435,9 @@ uint16_t WK_cb()
|
|||||||
{
|
{
|
||||||
if (packet_sent == 0)
|
if (packet_sent == 0)
|
||||||
{
|
{
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(2800);
|
||||||
|
#endif
|
||||||
packet_sent = 1;
|
packet_sent = 1;
|
||||||
if(sub_protocol == WK2801)
|
if(sub_protocol == WK2801)
|
||||||
WK_BuildPacket_2801();
|
WK_BuildPacket_2801();
|
||||||
|
|||||||
217
Multiprotocol/XK_nrf24l01.ino
Normal file
@@ -0,0 +1,217 @@
|
|||||||
|
/*
|
||||||
|
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 X450 and X420/X520 plane.
|
||||||
|
|
||||||
|
#if defined(XK_NRF24L01_INO)
|
||||||
|
|
||||||
|
#include "iface_nrf250k.h"
|
||||||
|
|
||||||
|
//#define FORCE_XK_ORIGINAL_ID
|
||||||
|
|
||||||
|
#define XK_INITIAL_WAIT 500
|
||||||
|
#define XK_PACKET_PERIOD 4000
|
||||||
|
#define XK_RF_BIND_NUM_CHANNELS 8
|
||||||
|
#define XK_RF_NUM_CHANNELS 4
|
||||||
|
#define XK_PAYLOAD_SIZE 16
|
||||||
|
#define XK_BIND_COUNT 750 //3sec
|
||||||
|
|
||||||
|
static uint16_t __attribute__((unused)) XK_convert_channel(uint8_t num)
|
||||||
|
{
|
||||||
|
uint16_t val=convert_channel_10b(num);
|
||||||
|
// 1FF..01=left, 00=center, 200..3FF=right
|
||||||
|
if(val==0x200)
|
||||||
|
val=0; // 0
|
||||||
|
else
|
||||||
|
if(val>0x200)
|
||||||
|
val--; // 200..3FE
|
||||||
|
else
|
||||||
|
{
|
||||||
|
val=0x200-val; // 200..01
|
||||||
|
if(val==0x200)
|
||||||
|
val--; // 1FF..01
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __attribute__((unused)) XK_send_packet()
|
||||||
|
{
|
||||||
|
memset(packet,0x00,7);
|
||||||
|
memset(&packet[10],0x00,5);
|
||||||
|
|
||||||
|
packet[12]=0x40;
|
||||||
|
packet[13]=0x40;
|
||||||
|
if(IS_BIND_IN_PROGRESS)
|
||||||
|
packet[14] = 0xC0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint16_t val=convert_channel_10b(THROTTLE);
|
||||||
|
packet[0] = val>>2; // 0..255
|
||||||
|
//packet[12] |= val & 2;
|
||||||
|
val=XK_convert_channel(RUDDER);
|
||||||
|
packet[1] = val>>2;
|
||||||
|
//packet[12] |= (val & 2)<<2;
|
||||||
|
val=XK_convert_channel(ELEVATOR);
|
||||||
|
packet[2] = val>>2;
|
||||||
|
//packet[13] |= val & 2;
|
||||||
|
val=XK_convert_channel(AILERON);
|
||||||
|
packet[3] = val>>2;
|
||||||
|
//packet[13] |= (val & 2)<<2;
|
||||||
|
|
||||||
|
memset(&packet[4],0x40,3); // Trims
|
||||||
|
|
||||||
|
if(Channel_data[CH5] > CHANNEL_MAX_COMMAND)
|
||||||
|
packet[10] = 0x10; // V-Mode
|
||||||
|
else
|
||||||
|
if(Channel_data[CH5] > CHANNEL_MIN_COMMAND)
|
||||||
|
packet[10] = 0x04; // 6G-Mode
|
||||||
|
//0x00 default M-Mode
|
||||||
|
|
||||||
|
packet[10] |= GET_FLAG(CH7_SW,0x80); // Emergency stop momentary switch
|
||||||
|
|
||||||
|
packet[11] = GET_FLAG(CH8_SW,0x03) // 3D/6G momentary switch
|
||||||
|
|GET_FLAG(CH6_SW,0x40); // Take off momentary switch
|
||||||
|
packet[14] = GET_FLAG(CH9_SW,0x01) // Photo momentary switch
|
||||||
|
|GET_FLAG(CH10_SW,0x2); // Video momentary switch
|
||||||
|
}
|
||||||
|
|
||||||
|
crc=packet[0];
|
||||||
|
for(uint8_t i=1; i<XK_PAYLOAD_SIZE-1;i++)
|
||||||
|
crc+=packet[i];
|
||||||
|
packet[15]=crc;
|
||||||
|
|
||||||
|
// debug("C: %02X, P:",hopping_frequency[(IS_BIND_IN_PROGRESS?0:XK_RF_BIND_NUM_CHANNELS)+(hopping_frequency_no>>1)]);
|
||||||
|
XN297L_Hopping((IS_BIND_IN_PROGRESS?0:XK_RF_BIND_NUM_CHANNELS)+(hopping_frequency_no>>1));
|
||||||
|
hopping_frequency_no++;
|
||||||
|
if(hopping_frequency_no >= (IS_BIND_IN_PROGRESS?XK_RF_BIND_NUM_CHANNELS*2:XK_RF_NUM_CHANNELS*2))
|
||||||
|
hopping_frequency_no=0;
|
||||||
|
|
||||||
|
XN297L_WritePayload(packet, XK_PAYLOAD_SIZE);
|
||||||
|
// for(uint8_t i=0; i<XK_PAYLOAD_SIZE; i++)
|
||||||
|
// debug(" %02X",packet[i]);
|
||||||
|
// debugln("");
|
||||||
|
|
||||||
|
XN297L_SetPower(); // Set tx_power
|
||||||
|
XN297L_SetFreqOffset(); // Set frequency offset
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint8_t PROGMEM XK_bind_hop[XK_RF_BIND_NUM_CHANNELS]= { 0x07, 0x24, 0x3E, 0x2B, 0x47, 0x0E, 0x39, 0x1C }; // Bind
|
||||||
|
|
||||||
|
const uint8_t PROGMEM XK_tx_addr[]= { 0xB3, 0x67, 0xE9, 0x98, 0x3A, 0xEC, 0xA6, 0x59, 0xB2, 0x94, 0x2B, 0xA5, 0x37, 0xC5, 0x4A, 0xD3,
|
||||||
|
0x49, 0xA6, 0x83, 0xEB, 0x4B, 0xC9, 0x59, 0xD2, 0x65, 0x34, 0x6A, 0xD3, 0x2C, 0x96, 0x2A, 0xA9,
|
||||||
|
0x32, 0xB2, 0xB4, 0x49, 0xD3, 0x37, 0xE9 };
|
||||||
|
|
||||||
|
const uint8_t PROGMEM XK_hop[]= { 0x47, 0x3A, 0x4C, 0x39, 0x4D, 0x34, 0x4A, 0x3F, 0x45, 0x3E, 0x4B, 0x3D, 0x3B, 0x48, 0x40, 0x49,
|
||||||
|
0x46, 0x3C, 0x43, 0x38, 0x35, 0x42, 0x33, 0x44, 0x4E, 0x37, 0x44, 0x35, 0x37, 0x4E, 0x36, 0x41 };
|
||||||
|
|
||||||
|
static void __attribute__((unused)) XK_initialize_txid()
|
||||||
|
{
|
||||||
|
//bind hop
|
||||||
|
for(uint8_t i=0; i<XK_RF_BIND_NUM_CHANNELS; i++)
|
||||||
|
hopping_frequency[i]=pgm_read_byte_near( &XK_bind_hop[i] );
|
||||||
|
|
||||||
|
//GID
|
||||||
|
packet[7]=rx_tx_addr[1];
|
||||||
|
packet[8]=rx_tx_addr[2];
|
||||||
|
packet[9]=rx_tx_addr[3];
|
||||||
|
uint8_t sum=packet[7]+packet[8]+packet[9];
|
||||||
|
// debugln("GID=%02X %02X %02X, sum=%d", packet[7],packet[8],packet[9],sum);
|
||||||
|
|
||||||
|
//Normal hop
|
||||||
|
uint8_t start=(sum&0x07)<<2;
|
||||||
|
// debug("start=%d, hop=",start);
|
||||||
|
for(uint8_t i=0; i<XK_RF_NUM_CHANNELS; i++)
|
||||||
|
{
|
||||||
|
hopping_frequency[ i + XK_RF_BIND_NUM_CHANNELS ]=pgm_read_byte_near( &XK_hop[ start + i ] );
|
||||||
|
// debug("%02X ", hopping_frequency[ i + XK_RF_BIND_NUM_CHANNELS ]);
|
||||||
|
}
|
||||||
|
// debugln("");
|
||||||
|
//Normal packet address
|
||||||
|
start=(sum&0x1F)+((sum>>5)&0x03);
|
||||||
|
// debug("start=%d, addr=",start);
|
||||||
|
for(uint8_t i=0; i<5; i++)
|
||||||
|
{
|
||||||
|
rx_tx_addr[i]=pgm_read_byte_near( &XK_tx_addr[ start + i ] );
|
||||||
|
// debug("%02X ", rx_tx_addr[ i ]);
|
||||||
|
}
|
||||||
|
// debugln("");
|
||||||
|
|
||||||
|
#ifdef FORCE_XK_ORIGINAL_ID
|
||||||
|
switch(RX_num%2)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
//TX1 X8 X450
|
||||||
|
//GID
|
||||||
|
packet[7]=0x04;
|
||||||
|
packet[8]=0x15;
|
||||||
|
packet[9]=0x22;
|
||||||
|
//Normal hop
|
||||||
|
memcpy(&hopping_frequency[XK_RF_BIND_NUM_CHANNELS],(uint8_t*)"\x3B\x48\x40\x49", XK_RF_NUM_CHANNELS); // freq and order verified
|
||||||
|
//Normal packet address
|
||||||
|
memcpy(rx_tx_addr,(uint8_t*)"\x2C\x96\x2A\xA9\x32",5);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
//TX2 X4 X420
|
||||||
|
//GID
|
||||||
|
packet[7]=0x13;
|
||||||
|
packet[8]=0x24;
|
||||||
|
packet[9]=0x18;
|
||||||
|
//Normal hop
|
||||||
|
memcpy(&hopping_frequency[XK_RF_BIND_NUM_CHANNELS],(uint8_t*)"\x36\x41\x37\x4E", XK_RF_NUM_CHANNELS); // freq ok and order from xn297dump auto
|
||||||
|
//Normal packet address
|
||||||
|
memcpy(rx_tx_addr,(uint8_t*)"\xA6\x83\xEB\x4B\xC9",5);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __attribute__((unused)) XK_init()
|
||||||
|
{
|
||||||
|
XN297L_Init();
|
||||||
|
XN297L_SetTXAddr((uint8_t*)"\x68\x94\xA6\xD5\xC3", 5); // Bind address
|
||||||
|
XN297L_HoppingCalib(XK_RF_BIND_NUM_CHANNELS+XK_RF_NUM_CHANNELS); // Calibrate all channels
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t XK_callback()
|
||||||
|
{
|
||||||
|
if(sub_protocol==X420)
|
||||||
|
option=0; // Forcing the use of NRF24L01@1Mbps
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(XK_PACKET_PERIOD);
|
||||||
|
#endif
|
||||||
|
if(IS_BIND_IN_PROGRESS)
|
||||||
|
if(--bind_counter==0)
|
||||||
|
{
|
||||||
|
BIND_DONE;
|
||||||
|
XN297L_SetTXAddr(rx_tx_addr, 5); // Normal packets address
|
||||||
|
}
|
||||||
|
XK_send_packet();
|
||||||
|
return XK_PACKET_PERIOD;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t initXK()
|
||||||
|
{
|
||||||
|
if(sub_protocol==X420)
|
||||||
|
option=prev_option=0; // Forcing the use of NRF24L01@1Mbps
|
||||||
|
BIND_IN_PROGRESS; // Autobind protocol
|
||||||
|
XK_initialize_txid();
|
||||||
|
XK_init();
|
||||||
|
if(sub_protocol==X420)
|
||||||
|
NRF24L01_SetBitrate(NRF24L01_BR_1M); // X420/X520 runs @1Mbps
|
||||||
|
hopping_frequency_no = 0;
|
||||||
|
bind_counter=XK_BIND_COUNT;
|
||||||
|
return XK_INITIAL_WAIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -33,6 +33,10 @@
|
|||||||
uint8_t address_length;
|
uint8_t address_length;
|
||||||
uint16_t timeH=0;
|
uint16_t timeH=0;
|
||||||
boolean scramble;
|
boolean scramble;
|
||||||
|
boolean enhanced;
|
||||||
|
boolean ack;
|
||||||
|
uint8_t pid;
|
||||||
|
uint8_t bitrate;
|
||||||
|
|
||||||
static void __attribute__((unused)) XN297Dump_init()
|
static void __attribute__((unused)) XN297Dump_init()
|
||||||
{
|
{
|
||||||
@@ -48,14 +52,14 @@ static void __attribute__((unused)) XN297Dump_init()
|
|||||||
NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, (uint8_t*)"\x55\x0F\x71", 3); // set up RX address to xn297 preamble
|
NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, (uint8_t*)"\x55\x0F\x71", 3); // set up RX address to xn297 preamble
|
||||||
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, XN297DUMP_MAX_PACKET_LEN); // Enable rx pipe 0
|
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, XN297DUMP_MAX_PACKET_LEN); // Enable rx pipe 0
|
||||||
|
|
||||||
debug("XN297 dump, address length=%d, speed=",address_length);
|
debug("XN297 dump, address length=%d, bitrate=",address_length);
|
||||||
switch(sub_protocol)
|
switch(bitrate)
|
||||||
{
|
{
|
||||||
case 0:
|
case XN297DUMP_250K:
|
||||||
NRF24L01_SetBitrate(NRF24L01_BR_250K);
|
NRF24L01_SetBitrate(NRF24L01_BR_250K);
|
||||||
debugln("250K");
|
debugln("250K");
|
||||||
break;
|
break;
|
||||||
case 2:
|
case XN297DUMP_2M:
|
||||||
NRF24L01_SetBitrate(NRF24L01_BR_2M);
|
NRF24L01_SetBitrate(NRF24L01_BR_2M);
|
||||||
debugln("2M");
|
debugln("2M");
|
||||||
break;
|
break;
|
||||||
@@ -76,9 +80,14 @@ static boolean __attribute__((unused)) XN297Dump_process_packet(void)
|
|||||||
{
|
{
|
||||||
uint16_t crcxored;
|
uint16_t crcxored;
|
||||||
uint8_t packet_sc[XN297DUMP_MAX_PACKET_LEN], packet_un[XN297DUMP_MAX_PACKET_LEN];
|
uint8_t packet_sc[XN297DUMP_MAX_PACKET_LEN], packet_un[XN297DUMP_MAX_PACKET_LEN];
|
||||||
|
enhanced=false;
|
||||||
// init crc
|
// init crc
|
||||||
crc = 0xb5d2;
|
crc = 0xb5d2;
|
||||||
|
|
||||||
|
/*debug("P: 71 0F 55 ");
|
||||||
|
for(uint8_t i=0; i<XN297DUMP_MAX_PACKET_LEN; i++)
|
||||||
|
debug("%02X ",packet[i]);
|
||||||
|
debugln("");*/
|
||||||
//Try normal payload
|
//Try normal payload
|
||||||
// address
|
// address
|
||||||
for (uint8_t i = 0; i < address_length; i++)
|
for (uint8_t i = 0; i < address_length; i++)
|
||||||
@@ -142,17 +151,17 @@ static boolean __attribute__((unused)) XN297Dump_process_packet(void)
|
|||||||
}
|
}
|
||||||
if(packet_length!=0)
|
if(packet_length!=0)
|
||||||
{ // Found a valid CRC for the enhanced payload mode
|
{ // Found a valid CRC for the enhanced payload mode
|
||||||
debug("Enhanced ");
|
enhanced=true;
|
||||||
//check selected address length
|
//check selected address length
|
||||||
if((packet_un[address_length]>>1)!=packet_length-address_length)
|
if((packet_un[address_length]>>1)!=packet_length-address_length)
|
||||||
{
|
{
|
||||||
for(uint8_t i=3;i<=5;i++)
|
for(uint8_t i=3;i<=5;i++)
|
||||||
if((packet_un[i]>>1)==packet_length-i)
|
if((packet_un[i]>>1)==packet_length-i)
|
||||||
address_length=i;
|
address_length=i;
|
||||||
debug("Wrong address length selected using %d ", address_length )
|
debugln("Detected wrong address length, using %d intead", address_length );
|
||||||
}
|
}
|
||||||
debug("pid=%d ",((packet_un[address_length]&0x01)<<1)|(packet_un[address_length+1]>>7));
|
pid=((packet_un[address_length]&0x01)<<1)|(packet_un[address_length+1]>>7);
|
||||||
debug("ack=%d ",(packet_un[address_length+1]>>6)&0x01);
|
ack=(packet_un[address_length+1]>>6)&0x01;
|
||||||
// address
|
// address
|
||||||
for (uint8_t i = 0; i < address_length; i++)
|
for (uint8_t i = 0; i < address_length; i++)
|
||||||
packet[address_length-1-i]=packet_un[i];
|
packet[address_length-1-i]=packet_un[i];
|
||||||
@@ -175,92 +184,449 @@ static void __attribute__((unused)) XN297Dump_overflow()
|
|||||||
}
|
}
|
||||||
static uint16_t XN297Dump_callback()
|
static uint16_t XN297Dump_callback()
|
||||||
{
|
{
|
||||||
static uint32_t time=0;
|
static uint32_t time=0,*time_rf;
|
||||||
|
|
||||||
|
//!!!Blocking mode protocol!!!
|
||||||
|
TX_MAIN_PAUSE_off;
|
||||||
|
tx_resume();
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
if(option==0xFF && bind_counter>XN297DUMP_PERIOD_SCAN)
|
if(sub_protocol<XN297DUMP_AUTO)
|
||||||
{ // Scan frequencies
|
{
|
||||||
hopping_frequency_no++;
|
if(option==0xFF && bind_counter>XN297DUMP_PERIOD_SCAN)
|
||||||
bind_counter=0;
|
{ // Scan frequencies
|
||||||
}
|
hopping_frequency_no++;
|
||||||
if(hopping_frequency_no!=rf_ch_num)
|
bind_counter=0;
|
||||||
{ // Channel has changed
|
|
||||||
if(hopping_frequency_no>XN297DUMP_MAX_RF_CHANNEL)
|
|
||||||
hopping_frequency_no=0; // Invalid channel 0 by default
|
|
||||||
rf_ch_num=hopping_frequency_no;
|
|
||||||
debugln("Channel=%d,0x%02X",hopping_frequency_no,hopping_frequency_no)
|
|
||||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH,hopping_frequency_no);
|
|
||||||
// switch to RX mode
|
|
||||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
|
|
||||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
|
||||||
NRF24L01_SetTxRxMode(RX_EN);
|
|
||||||
NRF24L01_FlushRx();
|
|
||||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, (0 << NRF24L01_00_EN_CRC) // switch to RX mode and disable CRC
|
|
||||||
| (1 << NRF24L01_00_CRCO)
|
|
||||||
| (1 << NRF24L01_00_PWR_UP)
|
|
||||||
| (1 << NRF24L01_00_PRIM_RX));
|
|
||||||
phase=0; // init timer
|
|
||||||
}
|
|
||||||
XN297Dump_overflow();
|
|
||||||
|
|
||||||
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR))
|
|
||||||
{ // RX fifo data ready
|
|
||||||
if(NRF24L01_ReadReg(NRF24L01_09_CD) || option != 0xFF)
|
|
||||||
{
|
|
||||||
NRF24L01_ReadPayload(packet,XN297DUMP_MAX_PACKET_LEN);
|
|
||||||
XN297Dump_overflow();
|
|
||||||
uint16_t timeL=TCNT1;
|
|
||||||
if(TIMER2_BASE->SR & TIMER_SR_UIF)
|
|
||||||
{//timer just rolled over...
|
|
||||||
XN297Dump_overflow();
|
|
||||||
timeL=0;
|
|
||||||
}
|
|
||||||
if(phase==0)
|
|
||||||
{
|
|
||||||
phase=1;
|
|
||||||
time=0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
time=(timeH<<16)+timeL-time;
|
|
||||||
debug("RX: %5luus C=%d ", time>>1 , hopping_frequency_no);
|
|
||||||
time=(timeH<<16)+timeL;
|
|
||||||
if(XN297Dump_process_packet())
|
|
||||||
{ // valid crc found
|
|
||||||
debug("S=%c A=",scramble?'Y':'N');
|
|
||||||
for(uint8_t i=0; i<address_length; i++)
|
|
||||||
{
|
|
||||||
debug(" %02X",packet[i]);
|
|
||||||
}
|
|
||||||
debug(" P(%d)=",packet_length-address_length);
|
|
||||||
for(uint8_t i=address_length; i<packet_length; i++)
|
|
||||||
{
|
|
||||||
debug(" %02X",packet[i]);
|
|
||||||
}
|
|
||||||
debugln("");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
debugln("Bad CRC");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if(hopping_frequency_no!=rf_ch_num)
|
||||||
|
{ // Channel has changed
|
||||||
|
if(hopping_frequency_no>XN297DUMP_MAX_RF_CHANNEL)
|
||||||
|
hopping_frequency_no=0; // Invalid channel 0 by default
|
||||||
|
rf_ch_num=hopping_frequency_no;
|
||||||
|
debugln("Channel=%d,0x%02X",hopping_frequency_no,hopping_frequency_no);
|
||||||
|
NRF24L01_WriteReg(NRF24L01_05_RF_CH,hopping_frequency_no);
|
||||||
|
// switch to RX mode
|
||||||
|
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
|
||||||
|
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||||
|
NRF24L01_SetTxRxMode(RX_EN);
|
||||||
|
NRF24L01_FlushRx();
|
||||||
|
NRF24L01_WriteReg(NRF24L01_00_CONFIG, (0 << NRF24L01_00_EN_CRC) // switch to RX mode and disable CRC
|
||||||
|
| (1 << NRF24L01_00_CRCO)
|
||||||
|
| (1 << NRF24L01_00_PWR_UP)
|
||||||
|
| (1 << NRF24L01_00_PRIM_RX));
|
||||||
|
phase=0; // init timer
|
||||||
|
}
|
||||||
|
XN297Dump_overflow();
|
||||||
|
|
||||||
XN297Dump_overflow();
|
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR))
|
||||||
// restart RX mode
|
{ // RX fifo data ready
|
||||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
|
if(NRF24L01_ReadReg(NRF24L01_09_CD) || option != 0xFF)
|
||||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
{
|
||||||
NRF24L01_SetTxRxMode(RX_EN);
|
NRF24L01_ReadPayload(packet,XN297DUMP_MAX_PACKET_LEN);
|
||||||
NRF24L01_FlushRx();
|
XN297Dump_overflow();
|
||||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, (0 << NRF24L01_00_EN_CRC) // switch to RX mode and disable CRC
|
uint16_t timeL=TCNT1;
|
||||||
| (1 << NRF24L01_00_CRCO)
|
if(TIMER2_BASE->SR & TIMER_SR_UIF)
|
||||||
| (1 << NRF24L01_00_PWR_UP)
|
{//timer just rolled over...
|
||||||
| (1 << NRF24L01_00_PRIM_RX));
|
XN297Dump_overflow();
|
||||||
XN297Dump_overflow();
|
timeL=0;
|
||||||
|
}
|
||||||
|
if((phase&0x01)==0)
|
||||||
|
{
|
||||||
|
phase=1;
|
||||||
|
time=0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
time=(timeH<<16)+timeL-time;
|
||||||
|
if(XN297Dump_process_packet())
|
||||||
|
{ // valid crc found
|
||||||
|
debug("RX: %5luus C=%d ", time>>1 , hopping_frequency_no);
|
||||||
|
time=(timeH<<16)+timeL;
|
||||||
|
if(enhanced)
|
||||||
|
{
|
||||||
|
debug("Enhanced ");
|
||||||
|
debug("pid=%d ",pid);
|
||||||
|
if(ack) debug("ack ");
|
||||||
|
}
|
||||||
|
debug("S=%c A=",scramble?'Y':'N');
|
||||||
|
for(uint8_t i=0; i<address_length; i++)
|
||||||
|
{
|
||||||
|
debug(" %02X",packet[i]);
|
||||||
|
}
|
||||||
|
debug(" P(%d)=",packet_length-address_length);
|
||||||
|
for(uint8_t i=address_length; i<packet_length; i++)
|
||||||
|
{
|
||||||
|
debug(" %02X",packet[i]);
|
||||||
|
}
|
||||||
|
debugln("");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
debugln("RX: %5luus C=%d Bad CRC", time>>1 , hopping_frequency_no);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
XN297Dump_overflow();
|
||||||
|
// restart RX mode
|
||||||
|
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
|
||||||
|
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||||
|
NRF24L01_SetTxRxMode(RX_EN);
|
||||||
|
NRF24L01_FlushRx();
|
||||||
|
NRF24L01_WriteReg(NRF24L01_00_CONFIG, (0 << NRF24L01_00_EN_CRC) // switch to RX mode and disable CRC
|
||||||
|
| (1 << NRF24L01_00_CRCO)
|
||||||
|
| (1 << NRF24L01_00_PWR_UP)
|
||||||
|
| (1 << NRF24L01_00_PRIM_RX));
|
||||||
|
XN297Dump_overflow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch(phase)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
debugln("------------------------");
|
||||||
|
debugln("Detecting XN297 packets.");
|
||||||
|
XN297Dump_init();
|
||||||
|
debug("Trying RF channel: 0");
|
||||||
|
hopping_frequency_no=0;
|
||||||
|
bitrate=0;
|
||||||
|
phase++;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if(bind_counter>XN297DUMP_PERIOD_SCAN)
|
||||||
|
{ // Scan frequencies
|
||||||
|
hopping_frequency_no++;
|
||||||
|
bind_counter=0;
|
||||||
|
if(hopping_frequency_no>XN297DUMP_MAX_RF_CHANNEL)
|
||||||
|
{
|
||||||
|
hopping_frequency_no=0;
|
||||||
|
bitrate++;
|
||||||
|
bitrate%=3;
|
||||||
|
debugln("");
|
||||||
|
XN297Dump_init();
|
||||||
|
debug("Trying RF channel: 0");
|
||||||
|
}
|
||||||
|
if(hopping_frequency_no)
|
||||||
|
debug(",%d",hopping_frequency_no);
|
||||||
|
NRF24L01_WriteReg(NRF24L01_05_RF_CH,hopping_frequency_no);
|
||||||
|
// switch to RX mode
|
||||||
|
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
|
||||||
|
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||||
|
NRF24L01_SetTxRxMode(RX_EN);
|
||||||
|
NRF24L01_FlushRx();
|
||||||
|
NRF24L01_WriteReg(NRF24L01_00_CONFIG, (0 << NRF24L01_00_EN_CRC) // switch to RX mode and disable CRC
|
||||||
|
| (1 << NRF24L01_00_CRCO)
|
||||||
|
| (1 << NRF24L01_00_PWR_UP)
|
||||||
|
| (1 << NRF24L01_00_PRIM_RX));
|
||||||
|
}
|
||||||
|
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR))
|
||||||
|
{ // RX fifo data ready
|
||||||
|
if(NRF24L01_ReadReg(NRF24L01_09_CD))
|
||||||
|
{
|
||||||
|
NRF24L01_ReadPayload(packet,XN297DUMP_MAX_PACKET_LEN);
|
||||||
|
if(XN297Dump_process_packet())
|
||||||
|
{ // valid crc found
|
||||||
|
debug("\r\n\r\nPacket detected: bitrate=");
|
||||||
|
switch(bitrate)
|
||||||
|
{
|
||||||
|
case XN297DUMP_250K:
|
||||||
|
NRF24L01_SetBitrate(NRF24L01_BR_250K);
|
||||||
|
debug("250K");
|
||||||
|
break;
|
||||||
|
case XN297DUMP_2M:
|
||||||
|
NRF24L01_SetBitrate(NRF24L01_BR_2M);
|
||||||
|
debug("2M");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
NRF24L01_SetBitrate(NRF24L01_BR_1M);
|
||||||
|
debug("1M");
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
debug(" C=%d ", hopping_frequency_no);
|
||||||
|
if(enhanced)
|
||||||
|
{
|
||||||
|
debug("Enhanced ");
|
||||||
|
debug("pid=%d ",pid);
|
||||||
|
if(ack) debug("ack ");
|
||||||
|
}
|
||||||
|
debug("S=%c A=",scramble?'Y':'N');
|
||||||
|
for(uint8_t i=0; i<address_length; i++)
|
||||||
|
{
|
||||||
|
debug(" %02X",packet[i]);
|
||||||
|
rx_tx_addr[i]=packet[i];
|
||||||
|
}
|
||||||
|
debug(" P(%d)=",packet_length-address_length);
|
||||||
|
for(uint8_t i=address_length; i<packet_length; i++)
|
||||||
|
{
|
||||||
|
debug(" %02X",packet[i]);
|
||||||
|
}
|
||||||
|
packet_length=packet_length-address_length;
|
||||||
|
debugln("\r\n--------------------------------");
|
||||||
|
phase=2;
|
||||||
|
debugln("Identifying all RF channels in use.");
|
||||||
|
bind_counter=0;
|
||||||
|
hopping_frequency_no=0;
|
||||||
|
rf_ch_num=0;
|
||||||
|
packet_count=0;
|
||||||
|
debug("Trying RF channel: 0");
|
||||||
|
NRF24L01_Initialize();
|
||||||
|
XN297_SetScrambledMode(scramble?XN297_SCRAMBLED:XN297_UNSCRAMBLED);
|
||||||
|
XN297_SetTXAddr(rx_tx_addr,address_length);
|
||||||
|
XN297_SetRXAddr(rx_tx_addr,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, packet_length + 2 + (enhanced?2:0) ); // 2 extra bytes for xn297 crc
|
||||||
|
NRF24L01_WriteReg(NRF24L01_05_RF_CH,0);
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if(bind_counter>XN297DUMP_PERIOD_SCAN)
|
||||||
|
{ // Scan frequencies
|
||||||
|
hopping_frequency_no++;
|
||||||
|
bind_counter=0;
|
||||||
|
if(hopping_frequency_no>XN297DUMP_MAX_RF_CHANNEL)
|
||||||
|
{
|
||||||
|
debug("\r\n\r\n%d RF channels identified:",rf_ch_num);
|
||||||
|
for(uint8_t i=0;i<rf_ch_num;i++)
|
||||||
|
debug(" %d",hopping_frequency[i]);
|
||||||
|
time_rf=(uint32_t*)malloc(rf_ch_num*sizeof(time));
|
||||||
|
if(time_rf==NULL)
|
||||||
|
{
|
||||||
|
debugln("\r\nCan't allocate memory for next phase!!!");
|
||||||
|
phase=0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
debugln("\r\n--------------------------------");
|
||||||
|
debugln("Identifying RF channels order.");
|
||||||
|
hopping_frequency_no=1;
|
||||||
|
phase=3;
|
||||||
|
packet_count=0;
|
||||||
|
bind_counter=0;
|
||||||
|
debugln("Time between CH:%d and CH:%d",hopping_frequency[0],hopping_frequency[hopping_frequency_no]);
|
||||||
|
time_rf[hopping_frequency_no]=-1;
|
||||||
|
NRF24L01_WriteReg(NRF24L01_05_RF_CH,hopping_frequency[0]);
|
||||||
|
uint16_t timeL=TCNT1;
|
||||||
|
if(TIMER2_BASE->SR & TIMER_SR_UIF)
|
||||||
|
{//timer just rolled over...
|
||||||
|
XN297Dump_overflow();
|
||||||
|
timeL=0;
|
||||||
|
}
|
||||||
|
time=(timeH<<16)+timeL;
|
||||||
|
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
|
||||||
|
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||||
|
NRF24L01_SetTxRxMode(RX_EN);
|
||||||
|
NRF24L01_FlushRx();
|
||||||
|
NRF24L01_WriteReg(NRF24L01_00_CONFIG, (0 << NRF24L01_00_EN_CRC) // switch to RX mode and disable CRC
|
||||||
|
| (1 << NRF24L01_00_CRCO)
|
||||||
|
| (1 << NRF24L01_00_PWR_UP)
|
||||||
|
| (1 << NRF24L01_00_PRIM_RX));
|
||||||
|
XN297Dump_overflow();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
debug(",%d",hopping_frequency_no);
|
||||||
|
NRF24L01_WriteReg(NRF24L01_05_RF_CH,hopping_frequency_no);
|
||||||
|
// switch to RX mode
|
||||||
|
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR))
|
||||||
|
{ // RX fifo data ready
|
||||||
|
if(NRF24L01_ReadReg(NRF24L01_09_CD))
|
||||||
|
{
|
||||||
|
boolean res;
|
||||||
|
if(enhanced)
|
||||||
|
res=XN297_ReadEnhancedPayload(packet, packet_length);
|
||||||
|
else
|
||||||
|
res=XN297_ReadPayload(packet, packet_length);
|
||||||
|
if(res)
|
||||||
|
{ // valid crc found
|
||||||
|
XN297Dump_overflow();
|
||||||
|
uint16_t timeL=TCNT1;
|
||||||
|
if(TIMER2_BASE->SR & TIMER_SR_UIF)
|
||||||
|
{//timer just rolled over...
|
||||||
|
XN297Dump_overflow();
|
||||||
|
timeL=0;
|
||||||
|
}
|
||||||
|
if(packet_count==0)
|
||||||
|
{//save channel
|
||||||
|
hopping_frequency[rf_ch_num]=hopping_frequency_no;
|
||||||
|
rf_ch_num++;
|
||||||
|
time=0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
time=(timeH<<16)+timeL-time;
|
||||||
|
debug("\r\nRX on channel: %d, Time: %5luus P:",hopping_frequency_no, time>>1);
|
||||||
|
time=(timeH<<16)+timeL;
|
||||||
|
for(uint8_t i=0;i<packet_length;i++)
|
||||||
|
debug(" %02X",packet[i]);
|
||||||
|
packet_count++;
|
||||||
|
if(packet_count>5)
|
||||||
|
{
|
||||||
|
bind_counter=XN297DUMP_PERIOD_SCAN+1;
|
||||||
|
debug("\r\nTrying RF channel: ");
|
||||||
|
packet_count=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// restart RX mode
|
||||||
|
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
XN297Dump_overflow();
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
if(bind_counter>XN297DUMP_PERIOD_SCAN)
|
||||||
|
{ // Scan frequencies
|
||||||
|
hopping_frequency_no++;
|
||||||
|
bind_counter=0;
|
||||||
|
if(hopping_frequency_no>=rf_ch_num)
|
||||||
|
{
|
||||||
|
uint8_t next=0;
|
||||||
|
debugln("\r\n\r\nChannel order:");
|
||||||
|
debugln("%d: 0us",hopping_frequency[0]);
|
||||||
|
uint8_t i=1;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
time=time_rf[i];
|
||||||
|
if(time!=-1)
|
||||||
|
{
|
||||||
|
next=i;
|
||||||
|
for(uint8_t j=2;j<rf_ch_num;j++)
|
||||||
|
if(time>time_rf[j])
|
||||||
|
{
|
||||||
|
next=j;
|
||||||
|
time=time_rf[j];
|
||||||
|
}
|
||||||
|
time_rf[next]=-1;
|
||||||
|
debugln("%d: %5luus",hopping_frequency[next],time);
|
||||||
|
i=0;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
while(i<rf_ch_num);
|
||||||
|
free(time_rf);
|
||||||
|
debugln("\r\n--------------------------------");
|
||||||
|
debugln("Identifying Sticks and features.");
|
||||||
|
phase=4;
|
||||||
|
hopping_frequency_no=0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
debugln("Time between CH:%d and CH:%d",hopping_frequency[0],hopping_frequency[hopping_frequency_no]);
|
||||||
|
time_rf[hopping_frequency_no]=-1;
|
||||||
|
NRF24L01_WriteReg(NRF24L01_05_RF_CH,hopping_frequency[0]);
|
||||||
|
uint16_t timeL=TCNT1;
|
||||||
|
if(TIMER2_BASE->SR & TIMER_SR_UIF)
|
||||||
|
{//timer just rolled over...
|
||||||
|
XN297Dump_overflow();
|
||||||
|
timeL=0;
|
||||||
|
}
|
||||||
|
time=(timeH<<16)+timeL;
|
||||||
|
// switch to RX mode
|
||||||
|
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR))
|
||||||
|
{ // RX fifo data ready
|
||||||
|
if(NRF24L01_ReadReg(NRF24L01_09_CD))
|
||||||
|
{
|
||||||
|
boolean res;
|
||||||
|
if(enhanced)
|
||||||
|
res=XN297_ReadEnhancedPayload(packet, packet_length);
|
||||||
|
else
|
||||||
|
res=XN297_ReadPayload(packet, packet_length);
|
||||||
|
if(res)
|
||||||
|
{ // valid crc found
|
||||||
|
XN297Dump_overflow();
|
||||||
|
uint16_t timeL=TCNT1;
|
||||||
|
if(TIMER2_BASE->SR & TIMER_SR_UIF)
|
||||||
|
{//timer just rolled over...
|
||||||
|
XN297Dump_overflow();
|
||||||
|
timeL=0;
|
||||||
|
}
|
||||||
|
if(packet_count&1)
|
||||||
|
{
|
||||||
|
time=(timeH<<16)+timeL-time;
|
||||||
|
if(time_rf[hopping_frequency_no] > (time>>1))
|
||||||
|
time_rf[hopping_frequency_no]=time>>1;
|
||||||
|
debugln("Time: %5luus", time>>1);
|
||||||
|
NRF24L01_WriteReg(NRF24L01_05_RF_CH,hopping_frequency[0]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
time=(timeH<<16)+timeL;
|
||||||
|
NRF24L01_WriteReg(NRF24L01_05_RF_CH,hopping_frequency[hopping_frequency_no]);
|
||||||
|
}
|
||||||
|
packet_count++;
|
||||||
|
if(packet_count>6)
|
||||||
|
{
|
||||||
|
bind_counter=XN297DUMP_PERIOD_SCAN+1;
|
||||||
|
packet_count=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// restart RX mode
|
||||||
|
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
XN297Dump_overflow();
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR))
|
||||||
|
{ // RX fifo data ready
|
||||||
|
if(NRF24L01_ReadReg(NRF24L01_09_CD))
|
||||||
|
{
|
||||||
|
boolean res;
|
||||||
|
if(enhanced)
|
||||||
|
res=XN297_ReadEnhancedPayload(packet, packet_length);
|
||||||
|
else
|
||||||
|
res=XN297_ReadPayload(packet, packet_length);
|
||||||
|
if(res)
|
||||||
|
{ // valid crc found
|
||||||
|
if(memcmp(packet_in,packet,packet_length))
|
||||||
|
{
|
||||||
|
debug("P:");
|
||||||
|
for(uint8_t i=0;i<packet_length;i++)
|
||||||
|
debug(" %02X",packet[i]);
|
||||||
|
debugln("");
|
||||||
|
memcpy(packet_in,packet,packet_length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// restart RX mode
|
||||||
|
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
bind_counter++;
|
bind_counter++;
|
||||||
if(IS_RX_FLAG_on) // Let the radio update the protocol
|
if(IS_RX_FLAG_on) // Let the radio update the protocol
|
||||||
{
|
{
|
||||||
if(Update_All()) return 10000; // New protocol selected
|
if(Update_All()) return 10000; // New protocol selected
|
||||||
if(prev_option!=option)
|
if(prev_option!=option && sub_protocol<XN297DUMP_AUTO)
|
||||||
{ // option has changed
|
{ // option has changed
|
||||||
hopping_frequency_no=option;
|
hopping_frequency_no=option;
|
||||||
prev_option=option;
|
prev_option=option;
|
||||||
@@ -274,6 +640,10 @@ static uint16_t XN297Dump_callback()
|
|||||||
uint16_t initXN297Dump(void)
|
uint16_t initXN297Dump(void)
|
||||||
{
|
{
|
||||||
BIND_DONE;
|
BIND_DONE;
|
||||||
|
if(sub_protocol<XN297DUMP_AUTO)
|
||||||
|
bitrate=sub_protocol;
|
||||||
|
else
|
||||||
|
bitrate=0;
|
||||||
address_length=RX_num;
|
address_length=RX_num;
|
||||||
if(address_length<3||address_length>5)
|
if(address_length<3||address_length>5)
|
||||||
address_length=5; //default
|
address_length=5; //default
|
||||||
@@ -281,7 +651,7 @@ uint16_t initXN297Dump(void)
|
|||||||
bind_counter=0;
|
bind_counter=0;
|
||||||
rf_ch_num=0xFF;
|
rf_ch_num=0xFF;
|
||||||
prev_option=option^0x55;
|
prev_option=option^0x55;
|
||||||
phase=0; // init timer
|
phase=0; // init
|
||||||
return XN297DUMP_INITIAL_WAIT;
|
return XN297DUMP_INITIAL_WAIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,223 +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/>.
|
|
||||||
*/
|
|
||||||
#include "iface_xn297l.h"
|
|
||||||
|
|
||||||
#if defined (XN297L_CC2500_EMU)
|
|
||||||
static void __attribute__((unused)) XN297L_Init()
|
|
||||||
{
|
|
||||||
PE1_off; // antenna RF2
|
|
||||||
PE2_on;
|
|
||||||
CC2500_Reset();
|
|
||||||
CC2500_Strobe(CC2500_SIDLE);
|
|
||||||
|
|
||||||
// Address Config = No address check
|
|
||||||
// Base Frequency = 2400
|
|
||||||
// CRC Autoflush = false
|
|
||||||
// CRC Enable = false
|
|
||||||
// Channel Spacing = 333.251953
|
|
||||||
// Data Format = Normal mode
|
|
||||||
// Data Rate = 249.939
|
|
||||||
// Deviation = 126.953125
|
|
||||||
// Device Address = 0
|
|
||||||
// Manchester Enable = false
|
|
||||||
// Modulated = true
|
|
||||||
// Modulation Format = GFSK
|
|
||||||
// Packet Length Mode = Variable packet length mode. Packet length configured by the first byte after sync word
|
|
||||||
// RX Filter BW = 203.125000
|
|
||||||
// Sync Word Qualifier Mode = No preamble/sync
|
|
||||||
// TX Power = 0
|
|
||||||
// Whitening = false
|
|
||||||
// Fast Frequency Hopping - no PLL auto calibration
|
|
||||||
|
|
||||||
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
|
|
||||||
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, 0xC3); // Frequency Control Word, Low Byte
|
|
||||||
CC2500_WriteReg(CC2500_10_MDMCFG4, 0x8D); // Modem Configuration
|
|
||||||
CC2500_WriteReg(CC2500_11_MDMCFG3, 0x3B); // Modem Configuration
|
|
||||||
CC2500_WriteReg(CC2500_12_MDMCFG2, 0x10); // Modem Configuration
|
|
||||||
CC2500_WriteReg(CC2500_13_MDMCFG1, 0x23); // Modem Configuration
|
|
||||||
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
|
|
||||||
|
|
||||||
CC2500_SetTxRxMode(TX_EN);
|
|
||||||
CC2500_SetPower();
|
|
||||||
xn297_scramble_enabled=XN297_SCRAMBLED; //enabled by default
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __attribute__((unused)) XN297L_SetTXAddr(const uint8_t* addr, uint8_t len)
|
|
||||||
{
|
|
||||||
if (len > 5) len = 5;
|
|
||||||
if (len < 3) len = 3;
|
|
||||||
xn297_addr_len = len;
|
|
||||||
memcpy(xn297_tx_addr, addr, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __attribute__((unused)) XN297L_WritePayload(uint8_t* msg, uint8_t len)
|
|
||||||
{
|
|
||||||
uint8_t buf[32];
|
|
||||||
uint8_t last = 0;
|
|
||||||
uint8_t i;
|
|
||||||
static const uint16_t initial = 0xb5d2;
|
|
||||||
|
|
||||||
// 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
|
|
||||||
uint16_t crc = initial;
|
|
||||||
for (uint8_t i = 0; i < last; ++i)
|
|
||||||
crc = crc16_update(crc, 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __attribute__((unused)) XN297L_HoppingCalib(uint8_t num_freq)
|
|
||||||
{ //calibrate hopping frequencies
|
|
||||||
for (uint8_t i = 0; i < num_freq; i++)
|
|
||||||
{
|
|
||||||
CC2500_Strobe(CC2500_SIDLE);
|
|
||||||
CC2500_WriteReg(CC2500_0A_CHANNR, hopping_frequency[i]*3);
|
|
||||||
CC2500_Strobe(CC2500_SCAL);
|
|
||||||
delayMicroseconds(900);
|
|
||||||
calData[i]=CC2500_ReadReg(CC2500_25_FSCAL1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __attribute__((unused)) XN297L_Hopping(uint8_t index)
|
|
||||||
{
|
|
||||||
// spacing is 333.25 kHz, must multiply xn297 channel by 3
|
|
||||||
CC2500_WriteReg(CC2500_0A_CHANNR, hopping_frequency[index] * 3);
|
|
||||||
// set PLL calibration
|
|
||||||
CC2500_WriteReg(CC2500_25_FSCAL1, calData[index]);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __attribute__((unused)) XN297L_RFChannel(uint8_t number)
|
|
||||||
{ //change channel
|
|
||||||
CC2500_Strobe(CC2500_SIDLE);
|
|
||||||
CC2500_WriteReg(CC2500_0A_CHANNR, number*3);
|
|
||||||
CC2500_Strobe(CC2500_SCAL);
|
|
||||||
delayMicroseconds(900);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __attribute__((unused)) XN297L_SetPower()
|
|
||||||
{
|
|
||||||
CC2500_SetPower();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __attribute__((unused)) XN297L_SetFreqOffset()
|
|
||||||
{ // Frequency offset
|
|
||||||
if (prev_option != option)
|
|
||||||
{
|
|
||||||
prev_option = option;
|
|
||||||
CC2500_WriteReg(CC2500_0C_FSCTRL0, option);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#elif defined (NRF24L01_INSTALLED)
|
|
||||||
|
|
||||||
static void __attribute__((unused)) XN297L_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_250K); // 250Kbps
|
|
||||||
NRF24L01_SetPower();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __attribute__((unused)) XN297L_SetTXAddr(const uint8_t* addr, uint8_t len)
|
|
||||||
{
|
|
||||||
XN297_SetTXAddr(addr,len);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __attribute__((unused)) XN297L_WritePayload(uint8_t* msg, uint8_t len)
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __attribute__((unused)) XN297L_HoppingCalib(__attribute__((unused)) uint8_t num_freq)
|
|
||||||
{ //calibrate hopping frequencies
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __attribute__((unused)) XN297L_Hopping(uint8_t index)
|
|
||||||
{
|
|
||||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[index]);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __attribute__((unused)) XN297L_RFChannel(uint8_t number)
|
|
||||||
{ //change channel
|
|
||||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, number);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __attribute__((unused)) XN297L_SetPower()
|
|
||||||
{
|
|
||||||
NRF24L01_SetPower();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __attribute__((unused)) XN297L_SetFreqOffset()
|
|
||||||
{ // Frequency offset
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -155,7 +155,12 @@ static void __attribute__((unused)) yd717_init()
|
|||||||
uint16_t yd717_callback()
|
uint16_t yd717_callback()
|
||||||
{
|
{
|
||||||
if(IS_BIND_DONE)
|
if(IS_BIND_DONE)
|
||||||
|
{
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(YD717_PACKET_PERIOD);
|
||||||
|
#endif
|
||||||
yd717_send_packet(0);
|
yd717_send_packet(0);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (bind_counter == 0)
|
if (bind_counter == 0)
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ Multiprotocol is distributed in the hope that it will be useful,
|
|||||||
|
|
||||||
#if defined(ZSX_NRF24L01_INO)
|
#if defined(ZSX_NRF24L01_INO)
|
||||||
|
|
||||||
#include "iface_xn297l.h"
|
#include "iface_nrf250k.h"
|
||||||
|
|
||||||
//#define FORCE_ZSX_ORIGINAL_ID
|
//#define FORCE_ZSX_ORIGINAL_ID
|
||||||
|
|
||||||
@@ -80,6 +80,9 @@ static void __attribute__((unused)) ZSX_init()
|
|||||||
|
|
||||||
uint16_t ZSX_callback()
|
uint16_t ZSX_callback()
|
||||||
{
|
{
|
||||||
|
#ifdef MULTI_SYNC
|
||||||
|
telemetry_set_input_sync(ZSX_PACKET_PERIOD);
|
||||||
|
#endif
|
||||||
if(IS_BIND_IN_PROGRESS)
|
if(IS_BIND_IN_PROGRESS)
|
||||||
if(--bind_counter==0)
|
if(--bind_counter==0)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -54,7 +54,7 @@
|
|||||||
/*** AUTO BIND ***/ // Also referred as "Bind on powerup"
|
/*** AUTO BIND ***/ // Also referred as "Bind on powerup"
|
||||||
/*****************/
|
/*****************/
|
||||||
//Bind from channel enables you to bind when a specified channel is going from low to high. This feature is only active
|
//Bind from channel enables you to bind when a specified channel is going from low to high. This feature is only active
|
||||||
// if you specify AUTOBIND in PPM mode or set AutoBind to YES for serial mode. It also requires that the throttle channel is low.
|
// if you specify AUTOBIND in PPM mode or set AutoBind to YES for serial mode.
|
||||||
//Comment to globaly disable the bind feature from a channel.
|
//Comment to globaly disable the bind feature from a channel.
|
||||||
#define ENABLE_BIND_CH
|
#define ENABLE_BIND_CH
|
||||||
//Set the channel number used for bind. Default is 16.
|
//Set the channel number used for bind. Default is 16.
|
||||||
@@ -77,9 +77,7 @@
|
|||||||
#define CYRF6936_INSTALLED
|
#define CYRF6936_INSTALLED
|
||||||
#define CC2500_INSTALLED
|
#define CC2500_INSTALLED
|
||||||
#define NRF24L01_INSTALLED
|
#define NRF24L01_INSTALLED
|
||||||
|
//#define SX1276_INSTALLED // only supported on STM32 modules
|
||||||
//If available use the CC2500 to emulate the XN297L @250Kbps instead of the NRF24L01. Comment to disable.
|
|
||||||
#define XN297L_CC2500_EMU
|
|
||||||
|
|
||||||
/** OrangeRX TX **/
|
/** OrangeRX TX **/
|
||||||
//If you compile for the OrangeRX TX module you need to select the correct board type.
|
//If you compile for the OrangeRX TX module you need to select the correct board type.
|
||||||
@@ -87,17 +85,18 @@
|
|||||||
//#define ORANGE_TX_BLUE
|
//#define ORANGE_TX_BLUE
|
||||||
|
|
||||||
/** CC2500 Fine Frequency Tuning **/
|
/** CC2500 Fine Frequency Tuning **/
|
||||||
//For optimal performance the CC2500 RF module used by the FrSkyD, FrSkyV, FrSkyX, SFHSS, CORONA, Redpine and Hitec protocols needs to be tuned for each protocol.
|
//For optimal performance the CC2500 RF module used by the CORONA, FrSkyD, FrSkyV, FrSkyX, Hitec, HoTT, SFHSS and Redpine protocols needs to be tuned for each protocol.
|
||||||
//Initial tuning should be done via the radio menu with a genuine FrSky/Futaba/CORONA/Hitec/Redpine receiver.
|
//Initial tuning should be done via the radio menu with a genuine CORONA/FrSky/Hitec/HoTT/Futaba/Redpine receiver.
|
||||||
//Once a good tuning value is found it can be set here and will override the radio's 'option' setting for all existing and new models which use that protocol.
|
//Once a good tuning value is found it can be set here and will override the radio's 'option' setting for all existing and new models which use that protocol.
|
||||||
//For more information: https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/tree/master/docs/Frequency_Tuning.md
|
//For more information: https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/tree/master/docs/Frequency_Tuning.md
|
||||||
//Uncomment the lines below (remove the "//") and set an appropriate value (replace the "0") to enable. Valid range is -127 to +127.
|
//Uncomment the lines below (remove the "//") and set an appropriate value (replace the "0") to enable. Valid range is -127 to +127.
|
||||||
|
//#define FORCE_CORONA_TUNING 0
|
||||||
//#define FORCE_FRSKYD_TUNING 0
|
//#define FORCE_FRSKYD_TUNING 0
|
||||||
//#define FORCE_FRSKYV_TUNING 0
|
//#define FORCE_FRSKYV_TUNING 0
|
||||||
//#define FORCE_FRSKYX_TUNING 0
|
//#define FORCE_FRSKYX_TUNING 0
|
||||||
//#define FORCE_SFHSS_TUNING 0
|
//#define FORCE_SFHSS_TUNING 0
|
||||||
//#define FORCE_CORONA_TUNING 0
|
|
||||||
//#define FORCE_HITEC_TUNING 0
|
//#define FORCE_HITEC_TUNING 0
|
||||||
|
//#define FORCE_HOTT_TUNING 0
|
||||||
//#define FORCE_REDPINE_TUNING 0
|
//#define FORCE_REDPINE_TUNING 0
|
||||||
|
|
||||||
/** A7105 Fine Frequency Tuning **/
|
/** A7105 Fine Frequency Tuning **/
|
||||||
@@ -112,6 +111,7 @@
|
|||||||
//#define FORCE_BUGS_TUNING 0
|
//#define FORCE_BUGS_TUNING 0
|
||||||
//#define FORCE_FLYSKY_TUNING 0
|
//#define FORCE_FLYSKY_TUNING 0
|
||||||
//#define FORCE_FLYZONE_TUNING 0
|
//#define FORCE_FLYZONE_TUNING 0
|
||||||
|
//#define FORCE_PELIKAN_TUNING 0
|
||||||
//#define FORCE_HUBSAN_TUNING 0
|
//#define FORCE_HUBSAN_TUNING 0
|
||||||
|
|
||||||
/** CYRF6936 Fine Frequency Tuning **/
|
/** CYRF6936 Fine Frequency Tuning **/
|
||||||
@@ -123,11 +123,12 @@
|
|||||||
/** Low Power **/
|
/** Low Power **/
|
||||||
//Low power is reducing the transmit power of the multi module. This setting is configurable per model in PPM (table below) or Serial mode (radio GUI).
|
//Low power is reducing the transmit power of the multi module. This setting is configurable per model in PPM (table below) or Serial mode (radio GUI).
|
||||||
//It can be activated when flying indoor or small models since the distance is short or if a model is causing issues when flying closed to the TX.
|
//It can be activated when flying indoor or small models since the distance is short or if a model is causing issues when flying closed to the TX.
|
||||||
//By default low power is completly disabled on all rf chips to prevent mistakes, but you can enable it by uncommenting the lines below:
|
//By default low power selection is enabled on all rf chips, but you can disable it by commenting (add //) the lines below if you don't want to risk
|
||||||
//#define A7105_ENABLE_LOW_POWER
|
//flying a model with low power.
|
||||||
//#define CYRF6936_ENABLE_LOW_POWER
|
#define A7105_ENABLE_LOW_POWER
|
||||||
//#define CC2500_ENABLE_LOW_POWER
|
#define CYRF6936_ENABLE_LOW_POWER
|
||||||
//#define NRF24L01_ENABLE_LOW_POWER
|
#define CC2500_ENABLE_LOW_POWER
|
||||||
|
#define NRF24L01_ENABLE_LOW_POWER
|
||||||
|
|
||||||
|
|
||||||
/*****************/
|
/*****************/
|
||||||
@@ -138,6 +139,7 @@
|
|||||||
//If you have 2 Multi modules which you want to share the same ID so you can use either to control the same RC model
|
//If you have 2 Multi modules which you want to share the same ID so you can use either to control the same RC model
|
||||||
// then you can force the ID to a certain known value using the lines below.
|
// then you can force the ID to a certain known value using the lines below.
|
||||||
//Default is commented, you should uncoment only for test purpose or if you know exactly what you are doing!!!
|
//Default is commented, you should uncoment only for test purpose or if you know exactly what you are doing!!!
|
||||||
|
//The 8 numbers below can be anything between 0...9 and A..F
|
||||||
//#define FORCE_GLOBAL_ID 0x12345678
|
//#define FORCE_GLOBAL_ID 0x12345678
|
||||||
|
|
||||||
//Protocols using the CYRF6936 (DSM, Devo, Walkera...) are using the CYRF ID instead which should prevent duplicated IDs.
|
//Protocols using the CYRF6936 (DSM, Devo, Walkera...) are using the CYRF ID instead which should prevent duplicated IDs.
|
||||||
@@ -156,10 +158,12 @@
|
|||||||
|
|
||||||
//The protocols below need an A7105 to be installed
|
//The protocols below need an A7105 to be installed
|
||||||
#define AFHDS2A_A7105_INO
|
#define AFHDS2A_A7105_INO
|
||||||
|
#define AFHDS2A_RX_A7105_INO
|
||||||
#define BUGS_A7105_INO
|
#define BUGS_A7105_INO
|
||||||
#define FLYSKY_A7105_INO
|
#define FLYSKY_A7105_INO
|
||||||
#define FLYZONE_A7105_INO
|
#define FLYZONE_A7105_INO
|
||||||
#define HUBSAN_A7105_INO
|
#define HUBSAN_A7105_INO
|
||||||
|
#define PELIKAN_A7105_INO
|
||||||
|
|
||||||
//The protocols below need a CYRF6936 to be installed
|
//The protocols below need a CYRF6936 to be installed
|
||||||
#define DEVO_CYRF6936_INO
|
#define DEVO_CYRF6936_INO
|
||||||
@@ -174,7 +178,9 @@
|
|||||||
#define FRSKYD_CC2500_INO
|
#define FRSKYD_CC2500_INO
|
||||||
#define FRSKYV_CC2500_INO
|
#define FRSKYV_CC2500_INO
|
||||||
#define FRSKYX_CC2500_INO
|
#define FRSKYX_CC2500_INO
|
||||||
|
#define FRSKY_RX_CC2500_INO
|
||||||
#define HITEC_CC2500_INO
|
#define HITEC_CC2500_INO
|
||||||
|
#define HOTT_CC2500_INO
|
||||||
#define SCANNER_CC2500_INO
|
#define SCANNER_CC2500_INO
|
||||||
#define SFHSS_CC2500_INO
|
#define SFHSS_CC2500_INO
|
||||||
#define REDPINE_CC2500_INO
|
#define REDPINE_CC2500_INO
|
||||||
@@ -182,6 +188,7 @@
|
|||||||
//The protocols below need a NRF24L01 to be installed
|
//The protocols below need a NRF24L01 to be installed
|
||||||
#define ASSAN_NRF24L01_INO
|
#define ASSAN_NRF24L01_INO
|
||||||
#define BAYANG_NRF24L01_INO
|
#define BAYANG_NRF24L01_INO
|
||||||
|
#define BAYANG_RX_NRF24L01_INO
|
||||||
#define BUGSMINI_NRF24L01_INO
|
#define BUGSMINI_NRF24L01_INO
|
||||||
#define CABELL_NRF24L01_INO
|
#define CABELL_NRF24L01_INO
|
||||||
#define CFLIE_NRF24L01_INO
|
#define CFLIE_NRF24L01_INO
|
||||||
@@ -192,6 +199,7 @@
|
|||||||
#define ESKY_NRF24L01_INO
|
#define ESKY_NRF24L01_INO
|
||||||
#define ESKY150_NRF24L01_INO
|
#define ESKY150_NRF24L01_INO
|
||||||
#define FQ777_NRF24L01_INO
|
#define FQ777_NRF24L01_INO
|
||||||
|
#define FX816_NRF24L01_INO
|
||||||
#define FY326_NRF24L01_INO
|
#define FY326_NRF24L01_INO
|
||||||
#define GD00X_NRF24L01_INO
|
#define GD00X_NRF24L01_INO
|
||||||
#define GW008_NRF24L01_INO
|
#define GW008_NRF24L01_INO
|
||||||
@@ -208,17 +216,27 @@
|
|||||||
#define SHENQI_NRF24L01_INO
|
#define SHENQI_NRF24L01_INO
|
||||||
#define SLT_NRF24L01_INO
|
#define SLT_NRF24L01_INO
|
||||||
#define SYMAX_NRF24L01_INO
|
#define SYMAX_NRF24L01_INO
|
||||||
|
#define TIGER_NRF24L01_INO
|
||||||
#define V2X2_NRF24L01_INO
|
#define V2X2_NRF24L01_INO
|
||||||
#define V761_NRF24L01_INO
|
#define V761_NRF24L01_INO
|
||||||
#define V911S_NRF24L01_INO
|
#define V911S_NRF24L01_INO
|
||||||
|
#define XK_NRF24L01_INO
|
||||||
#define YD717_NRF24L01_INO
|
#define YD717_NRF24L01_INO
|
||||||
#define ZSX_NRF24L01_INO
|
#define ZSX_NRF24L01_INO
|
||||||
|
|
||||||
|
//The protocols below need a SX1276 to be installed
|
||||||
|
//#define FRSKYR9_SX1276_INO
|
||||||
|
|
||||||
/***************************/
|
/***************************/
|
||||||
/*** PROTOCOLS SETTINGS ***/
|
/*** PROTOCOLS SETTINGS ***/
|
||||||
/***************************/
|
/***************************/
|
||||||
|
|
||||||
|
//FrSkyX specific setting
|
||||||
|
//-----------------------
|
||||||
|
//EU LBT setting: if commented the TX will not check if a channel is busy before transmitting.
|
||||||
|
//!!! Work in progress !!! it's currently known to cause telemerty issues. Enable only if you know what you are doing.
|
||||||
|
//#define FRSKYX_LBT
|
||||||
|
|
||||||
//DSM specific settings
|
//DSM specific settings
|
||||||
//---------------------
|
//---------------------
|
||||||
//The DSM protocol is using by default the Spektrum throw of 1100..1900us @100% and 1000..2000us @125%.
|
//The DSM protocol is using by default the Spektrum throw of 1100..1900us @100% and 1000..2000us @125%.
|
||||||
@@ -227,7 +245,7 @@
|
|||||||
//Some models (X-Vert, Blade 230S...) require a special value to instant stop the motor(s).
|
//Some models (X-Vert, Blade 230S...) require a special value to instant stop the motor(s).
|
||||||
// You can disable this feature by adding "//" on the line below. You have to specify which channel (14 by default) will be used to kill the throttle channel.
|
// You can disable this feature by adding "//" on the line below. You have to specify which channel (14 by default) will be used to kill the throttle channel.
|
||||||
// If the channel 14 is above -50% the throttle is untouched but if it is between -50% and -100%, the throttle output will be forced between -100% and -150%.
|
// If the channel 14 is above -50% the throttle is untouched but if it is between -50% and -100%, the throttle output will be forced between -100% and -150%.
|
||||||
// For example, a value of -80% applied on channel 15 will instantly kill the motors on the X-Vert.
|
// For example, a value of -80% applied on channel 14 will instantly kill the motors on the X-Vert.
|
||||||
#define DSM_THROTTLE_KILL_CH 14
|
#define DSM_THROTTLE_KILL_CH 14
|
||||||
|
|
||||||
//AFHDS2A specific settings
|
//AFHDS2A specific settings
|
||||||
@@ -239,25 +257,12 @@
|
|||||||
/**************************/
|
/**************************/
|
||||||
/*** FAILSAFE SETTINGS ***/
|
/*** FAILSAFE SETTINGS ***/
|
||||||
/**************************/
|
/**************************/
|
||||||
//The module is using the same default failsafe values for all protocols which currently supports it:
|
//The following protocols are supporting failsafe: FrSkyX, Devo, WK2x01, SFHSS, HISKY/HK310 and AFHDS2A
|
||||||
// Devo, WK2x01, SFHSS, HISKY/HK310 and AFHDS2A
|
//In Serial mode failsafe is configured on the radio itself.
|
||||||
//All channels are centered except throttle which is forced low.
|
//In PPM mode and only after the module is up and fully operational, press the bind button for at least 5sec to send the current stick positions as failsafe to the RX.
|
||||||
//If you want to diasble failsafe globally comment the line below using "//".
|
//If you want to disable failsafe globally comment the line below using "//".
|
||||||
#define FAILSAFE_ENABLE
|
#define FAILSAFE_ENABLE
|
||||||
|
|
||||||
//Failsafe throttle low value in percentage.
|
|
||||||
//Value between -125% and +125%. Default -100.
|
|
||||||
#define FAILSAFE_THROTTLE_LOW -100
|
|
||||||
|
|
||||||
//The radio using serial protocol can set failsafe data.
|
|
||||||
// Two options are available:
|
|
||||||
// a. replace the default failsafe data with serial failsafe data when they are received.
|
|
||||||
// b. wait for the radio to provide failsafe before sending it. Enable advanced settings like "FAILSAFE NOT SET" or "FAILSAFE RX".
|
|
||||||
// Option a. is the default since you have a protection even if no failsafe has been set on the radio.
|
|
||||||
// You can force option b. by uncommenting the line below (remove the "//").
|
|
||||||
//#define FAILSAFE_SERIAL_ONLY
|
|
||||||
|
|
||||||
|
|
||||||
/**************************/
|
/**************************/
|
||||||
/*** TELEMETRY SETTINGS ***/
|
/*** TELEMETRY SETTINGS ***/
|
||||||
/**************************/
|
/**************************/
|
||||||
@@ -268,24 +273,28 @@
|
|||||||
|
|
||||||
//Comment to invert the polarity of the output telemetry serial signal.
|
//Comment to invert the polarity of the output telemetry serial signal.
|
||||||
//This function takes quite some flash space and processor power on an atmega.
|
//This function takes quite some flash space and processor power on an atmega.
|
||||||
//For OpenTX it must be uncommented.
|
//For a Taranis/T16 with an external module it must be uncommented. For a T16 internal module it must be commented.
|
||||||
//On a 9XR_PRO running ersky9x both commented and uncommented will work depending on the radio setting Invert COM1 under the Telemetry menu.
|
//A 9XR_PRO running erskyTX will work with both commented and uncommented depending on the radio setting Invert COM1 under the Telemetry menu.
|
||||||
//On other addon/replacement boards like the 9xtreme board or the Ar9x board running ersky9x, you need to uncomment the line below.
|
//On other addon/replacement boards like the 9xtreme board or the Ar9x board running erskyTX, you need to uncomment the line below.
|
||||||
//For er9x it depends if you have an inveter mod or not on the telemetry pin. If you don't have an inverter comment this line.
|
//For er9x it depends if you have an inveter mod or not on the telemetry pin. If you don't have an inverter comment this line.
|
||||||
#define INVERT_TELEMETRY
|
#define INVERT_TELEMETRY
|
||||||
|
//For STM32 and OrangeRX modules, comment to prevent the TX from forcing the serial telemetry polarity normal/invert.
|
||||||
|
#define INVERT_TELEMETRY_TX
|
||||||
|
|
||||||
//Comment if you don't want to send Multi status telemetry frames (Protocol available, Bind in progress, version...)
|
//Uncomment if you want to send Multi status telemetry frames (Protocol available, Bind in progress, version...)
|
||||||
//Use with er9x/erksy9x, for OpenTX MULTI_TELEMETRY below is preferred instead
|
//Use with er9x/erskyTX, for OpenTX you must select MULTI_TELEMETRY below
|
||||||
//#define MULTI_STATUS
|
//#define MULTI_STATUS
|
||||||
|
|
||||||
//Uncomment to send Multi status and allow OpenTX to autodetect the telemetry format
|
//Sends Multi status and allow OpenTX to autodetect the telemetry format. Comment to disable.
|
||||||
//Supported by OpenTX version 2.2 RC9 and newer. NOT supported by er9x/ersky9x use MULTI_STATUS instead.
|
//Supported by OpenTX version 2.2 RC9 and newer. NOT supported by er9x/erskyTX use MULTI_STATUS instead.
|
||||||
#define MULTI_TELEMETRY
|
#define MULTI_TELEMETRY
|
||||||
|
//Work in progress: Sync OpenTX frames with the current protocol timing. This feature is only available on the STM32 module. Uncomment to enable.
|
||||||
|
//#define MULTI_SYNC
|
||||||
|
|
||||||
//Comment a line to disable a specific protocol telemetry
|
//Comment a line to disable a specific protocol telemetry
|
||||||
#define DSM_TELEMETRY // Forward received telemetry packet directly to TX to be decoded by er9x, ersky9x and OpenTX
|
#define DSM_TELEMETRY // Forward received telemetry packet directly to TX to be decoded by er9x, erskyTX and OpenTX
|
||||||
#define SPORT_TELEMETRY // Use FrSkyX SPORT format to send telemetry to TX
|
#define SPORT_TELEMETRY // Use FrSkyX format to send/receive telemetry
|
||||||
#define AFHDS2A_FW_TELEMETRY // Forward received telemetry packet directly to TX to be decoded by ersky9x and OpenTX
|
#define AFHDS2A_FW_TELEMETRY // Forward received telemetry packet directly to TX to be decoded by erskyTX and OpenTX
|
||||||
#define AFHDS2A_HUB_TELEMETRY // Use FrSkyD Hub format to send basic telemetry to TX like er9x
|
#define AFHDS2A_HUB_TELEMETRY // Use FrSkyD Hub format to send basic telemetry to TX like er9x
|
||||||
#define HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
|
#define HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
|
||||||
#define BAYANG_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
|
#define BAYANG_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
|
||||||
@@ -293,16 +302,13 @@
|
|||||||
#define HUBSAN_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
|
#define HUBSAN_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
|
||||||
#define NCC1701_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
|
#define NCC1701_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
|
||||||
#define CABELL_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
|
#define CABELL_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
|
||||||
#define HITEC_HUB_TELEMETRY // Use FrSkyD Hub format to send basic telemetry to the radios which can decode it like er9x, ersky9x and OpenTX
|
#define HITEC_HUB_TELEMETRY // Use FrSkyD Hub format to send basic telemetry to the radios which can decode it like er9x, erskyTX and OpenTX
|
||||||
#define HITEC_FW_TELEMETRY // Under development: Forward received telemetry packets to be decoded by ersky9x and OpenTX
|
#define HITEC_FW_TELEMETRY // Forward received telemetry packets to be decoded by erskyTX and OpenTX
|
||||||
#define SCANNER_TELEMETRY // Forward spectrum scanner data to TX
|
#define SCANNER_TELEMETRY // Forward spectrum scanner data to TX
|
||||||
|
#define FRSKY_RX_TELEMETRY // Forward channels data to TX
|
||||||
//SPORT_POLLING is an implementation of the same polling routine as XJT module for sport telemetry bidirectional communication.
|
#define AFHDS2A_RX_TELEMETRY // Forward channels data to TX
|
||||||
//This is useful for passing sport control frames from TX to RX(ex: changing Betaflight PID or VTX channels on the fly using LUA scripts with OpentX).
|
#define HOTT_FW_TELEMETRY // Forward received telemetry packets to be decoded by erskyTX and OpenTX
|
||||||
//Using this feature requires to uncomment INVERT_TELEMETRY as this TX output on telemetry pin only inverted signal.
|
#define BAYANG_RX_TELEMETRY // Forward channels data to TX
|
||||||
//!!!! This is a work in progress!!! Do not enable unless you want to test and report
|
|
||||||
//#define SPORT_POLLING
|
|
||||||
|
|
||||||
|
|
||||||
/****************************/
|
/****************************/
|
||||||
/*** SERIAL MODE SETTINGS ***/
|
/*** SERIAL MODE SETTINGS ***/
|
||||||
@@ -353,6 +359,10 @@
|
|||||||
// The default value is 16 to receive all possible channels but you might want to filter some "bad" channels from the PPM frame like the ones above 6 on the Walkera PL0811.
|
// The default value is 16 to receive all possible channels but you might want to filter some "bad" channels from the PPM frame like the ones above 6 on the Walkera PL0811.
|
||||||
#define MAX_PPM_CHANNELS 16
|
#define MAX_PPM_CHANNELS 16
|
||||||
|
|
||||||
|
/** Telemetry **/
|
||||||
|
//Send simple FrSkyX telemetry using the FrSkyD telemetry format
|
||||||
|
#define TELEMETRY_FRSKYX_TO_FRSKYD
|
||||||
|
|
||||||
/** Rotary Switch Protocol Selector Settings **/
|
/** Rotary Switch Protocol Selector Settings **/
|
||||||
//The table below indicates which protocol to run when a specific position on the rotary switch has been selected.
|
//The table below indicates which protocol to run when a specific position on the rotary switch has been selected.
|
||||||
//All fields and values are explained below. Everything is configurable from here like in the Serial mode.
|
//All fields and values are explained below. Everything is configurable from here like in the Serial mode.
|
||||||
@@ -362,99 +372,99 @@
|
|||||||
// short press the bind button multiple times until you reach the desired one. The bank number currently selected is indicated by the number of LED flash.
|
// short press the bind button multiple times until you reach the desired one. The bank number currently selected is indicated by the number of LED flash.
|
||||||
// Full procedure is located here: https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/blob/master/Protocols_Details.md#protocol-selection-in-ppm-mode
|
// Full procedure is located here: https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/blob/master/Protocols_Details.md#protocol-selection-in-ppm-mode
|
||||||
|
|
||||||
//The parameter below indicates the number of desired banks between 1 and 5. Default is 5.
|
//The parameter below indicates the number of desired banks between 1 and 5. Default is 1.
|
||||||
#define NBR_BANKS 5
|
#define NBR_BANKS 1
|
||||||
|
|
||||||
const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
|
const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
|
||||||
#if NBR_BANKS > 0
|
#if NBR_BANKS > 0
|
||||||
//****************************** BANK 1 ******************************
|
//****************************** BANK 1 ******************************
|
||||||
// Switch Protocol Sub protocol RX_Num Power Auto Bind Option
|
// Switch Protocol Sub protocol RX_Num Power Auto Bind Option Chan Order
|
||||||
/* 1 */ {PROTO_FLYSKY, Flysky , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 1 */ {PROTO_FLYSKY, Flysky , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
/* 2 */ {PROTO_AFHDS2A, PWM_IBUS , 0 , P_HIGH , NO_AUTOBIND , 0 }, // RX number 0
|
/* 2 */ {PROTO_AFHDS2A, PWM_IBUS , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 }, // RX number 0
|
||||||
/* 3 */ {PROTO_AFHDS2A, PWM_IBUS , 1 , P_HIGH , NO_AUTOBIND , 0 }, // RX number 1
|
/* 3 */ {PROTO_AFHDS2A, PWM_IBUS , 1 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 }, // RX number 1
|
||||||
/* 4 */ {PROTO_AFHDS2A, PWM_IBUS , 2 , P_HIGH , NO_AUTOBIND , 0 }, // RX number 2
|
/* 4 */ {PROTO_AFHDS2A, PWM_IBUS , 2 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 }, // RX number 2
|
||||||
/* 5 */ {PROTO_AFHDS2A, PWM_IBUS , 3 , P_HIGH , NO_AUTOBIND , 0 }, // RX number 3
|
/* 5 */ {PROTO_AFHDS2A, PWM_IBUS , 3 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 }, // RX number 3
|
||||||
/* 6 */ {PROTO_AFHDS2A, PWM_IBUS , 2 , P_HIGH , NO_AUTOBIND , 0 }, // RX number 4
|
/* 6 */ {PROTO_AFHDS2A, PWM_IBUS , 2 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 }, // RX number 4
|
||||||
/* 7 */ {PROTO_AFHDS2A, PWM_IBUS , 3 , P_HIGH , NO_AUTOBIND , 0 }, // RX number 5
|
/* 7 */ {PROTO_AFHDS2A, PWM_IBUS , 3 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 }, // RX number 5
|
||||||
/* 8 */ {PROTO_SFHSS, H107 , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 8 */ {PROTO_SFHSS, H107 , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
/* 9 */ {PROTO_FRSKYV, NONE , 0 , P_HIGH , NO_AUTOBIND , 40 }, // option=fine freq tuning
|
/* 9 */ {PROTO_FRSKYV, NONE , 0 , P_HIGH , NO_AUTOBIND , 40 , 0x00000000 }, // option=fine freq tuning
|
||||||
/* 10 */ {PROTO_FRSKYD, NONE , 0 , P_HIGH , NO_AUTOBIND , 40 }, // option=fine freq tuning
|
/* 10 */ {PROTO_FRSKYD, NONE , 0 , P_HIGH , NO_AUTOBIND , 40 , 0x00000000 }, // option=fine freq tuning
|
||||||
/* 11 */ {PROTO_FRSKYX, CH_16 , 0 , P_HIGH , NO_AUTOBIND , 40 }, // option=fine freq tuning
|
/* 11 */ {PROTO_FRSKYX, CH_16 , 0 , P_HIGH , NO_AUTOBIND , 40 , 0x00000000 }, // option=fine freq tuning
|
||||||
/* 12 */ {PROTO_FRSKYX, EU_16 , 0 , P_HIGH , NO_AUTOBIND , 40 }, // option=fine freq tuning
|
/* 12 */ {PROTO_FRSKYX, EU_16 , 0 , P_HIGH , NO_AUTOBIND , 40 , 0x00000000 }, // option=fine freq tuning
|
||||||
/* 13 */ {PROTO_DEVO , NONE , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 13 */ {PROTO_DEVO , NONE , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
/* 14 */ {PROTO_WK2x01, WK2801 , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 14 */ {PROTO_WK2x01, WK2801 , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
#endif
|
#endif
|
||||||
#if NBR_BANKS > 1
|
#if NBR_BANKS > 1
|
||||||
//****************************** BANK 2 ******************************
|
//****************************** BANK 2 ******************************
|
||||||
// Switch Protocol Sub protocol RX_Num Power Auto Bind Option
|
// Switch Protocol Sub protocol RX_Num Power Auto Bind Option Chan Order
|
||||||
/* 1 */ {PROTO_DSM , DSM2_11 , 0 , P_HIGH , NO_AUTOBIND , 6 }, // option=number of channels
|
/* 1 */ {PROTO_DSM , DSM2_11 , 0 , P_HIGH , NO_AUTOBIND , 6 , 0x00000000 }, // option=number of channels
|
||||||
/* 2 */ {PROTO_DSM , DSM2_22 , 0 , P_HIGH , NO_AUTOBIND , 6 }, // option=number of channels
|
/* 2 */ {PROTO_DSM , DSM2_22 , 0 , P_HIGH , NO_AUTOBIND , 6 , 0x00000000 }, // option=number of channels
|
||||||
/* 3 */ {PROTO_DSM , DSMX_11 , 0 , P_HIGH , NO_AUTOBIND , 6 }, // option=number of channels
|
/* 3 */ {PROTO_DSM , DSMX_11 , 0 , P_HIGH , NO_AUTOBIND , 6 , 0x00000000 }, // option=number of channels
|
||||||
/* 4 */ {PROTO_DSM , DSMX_22 , 0 , P_HIGH , NO_AUTOBIND , 6 }, // option=number of channels
|
/* 4 */ {PROTO_DSM , DSMX_22 , 0 , P_HIGH , NO_AUTOBIND , 6 , 0x00000000 }, // option=number of channels
|
||||||
/* 5 */ {PROTO_DSM , DSM2_11 , 0 , P_HIGH , NO_AUTOBIND , 8 }, // option=number of channels
|
/* 5 */ {PROTO_DSM , DSM2_11 , 0 , P_HIGH , NO_AUTOBIND , 8 , 0x00000000 }, // option=number of channels
|
||||||
/* 6 */ {PROTO_DSM , DSM2_22 , 0 , P_HIGH , NO_AUTOBIND , 8 }, // option=number of channels
|
/* 6 */ {PROTO_DSM , DSM2_22 , 0 , P_HIGH , NO_AUTOBIND , 8 , 0x00000000 }, // option=number of channels
|
||||||
/* 7 */ {PROTO_DSM , DSMX_11 , 0 , P_HIGH , NO_AUTOBIND , 8 }, // option=number of channels
|
/* 7 */ {PROTO_DSM , DSMX_11 , 0 , P_HIGH , NO_AUTOBIND , 8 , 0x00000000 }, // option=number of channels
|
||||||
/* 8 */ {PROTO_DSM , DSMX_22 , 0 , P_HIGH , NO_AUTOBIND , 8 }, // option=number of channels
|
/* 8 */ {PROTO_DSM , DSMX_22 , 0 , P_HIGH , NO_AUTOBIND , 8 , 0x00000000 }, // option=number of channels
|
||||||
/* 9 */ {PROTO_SLT , SLT_V1 , 0 , P_HIGH , NO_AUTOBIND , 6 },
|
/* 9 */ {PROTO_SLT , SLT_V1 , 0 , P_HIGH , NO_AUTOBIND , 6 , 0x00000000 },
|
||||||
/* 10 */ {PROTO_HUBSAN, H107 , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 10 */ {PROTO_HUBSAN, H107 , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
/* 11 */ {PROTO_HUBSAN, H301 , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 11 */ {PROTO_HUBSAN, H301 , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
/* 12 */ {PROTO_HUBSAN, H501 , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 12 */ {PROTO_HUBSAN, H501 , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
/* 13 */ {PROTO_HISKY, Hisky , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 13 */ {PROTO_HISKY, Hisky , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
/* 14 */ {PROTO_V2X2 , NONE , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 14 */ {PROTO_V2X2 , NONE , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
#endif
|
#endif
|
||||||
#if NBR_BANKS > 2
|
#if NBR_BANKS > 2
|
||||||
//****************************** BANK 3 ******************************
|
//****************************** BANK 3 ******************************
|
||||||
// Switch Protocol Sub protocol RX_Num Power Auto Bind Option
|
// Switch Protocol Sub protocol RX_Num Power Auto Bind Option Chan Order
|
||||||
/* 1 */ {PROTO_ESKY , NONE , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 1 */ {PROTO_ESKY , NONE , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
/* 2 */ {PROTO_ESKY150, NONE , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 2 */ {PROTO_ESKY150, NONE , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
/* 3 */ {PROTO_ASSAN, NONE , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 3 */ {PROTO_ASSAN, NONE , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
/* 4 */ {PROTO_CORONA, COR_V2 , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 4 */ {PROTO_CORONA, COR_V2 , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
/* 5 */ {PROTO_SYMAX, SYMAX , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 5 */ {PROTO_SYMAX, SYMAX , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
/* 6 */ {PROTO_KN , WLTOYS , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 6 */ {PROTO_KN , WLTOYS , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
/* 7 */ {PROTO_BAYANG, BAYANG , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 7 */ {PROTO_BAYANG, BAYANG , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
/* 8 */ {PROTO_BAYANG, H8S3D , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 8 */ {PROTO_BAYANG, H8S3D , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
/* 9 */ {PROTO_BAYANG, X16_AH , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 9 */ {PROTO_BAYANG, X16_AH , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
/* 10 */ {PROTO_BAYANG, IRDRONE , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 10 */ {PROTO_BAYANG, IRDRONE , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
/* 11 */ {PROTO_H8_3D, H8_3D , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 11 */ {PROTO_H8_3D, H8_3D , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
/* 12 */ {PROTO_H8_3D, H20H , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 12 */ {PROTO_H8_3D, H20H , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
/* 13 */ {PROTO_H8_3D, H20MINI , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 13 */ {PROTO_H8_3D, H20MINI , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
/* 14 */ {PROTO_H8_3D, H30MINI , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 14 */ {PROTO_H8_3D, H30MINI , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
#endif
|
#endif
|
||||||
#if NBR_BANKS > 3
|
#if NBR_BANKS > 3
|
||||||
//****************************** BANK 4 ******************************
|
//****************************** BANK 4 ******************************
|
||||||
// Switch Protocol Sub protocol RX_Num Power Auto Bind Option
|
// Switch Protocol Sub protocol RX_Num Power Auto Bind Option Chan Order
|
||||||
/* 1 */ {PROTO_MJXQ , WLH08 , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 1 */ {PROTO_MJXQ , WLH08 , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
/* 2 */ {PROTO_MJXQ , X600 , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 2 */ {PROTO_MJXQ , X600 , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
/* 3 */ {PROTO_MJXQ , X800 , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 3 */ {PROTO_MJXQ , X800 , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
/* 4 */ {PROTO_MJXQ , H26D , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 4 */ {PROTO_MJXQ , H26D , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
/* 5 */ {PROTO_MJXQ , E010 , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 5 */ {PROTO_MJXQ , E010 , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
/* 6 */ {PROTO_MJXQ , H26WH , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 6 */ {PROTO_MJXQ , H26WH , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
/* 7 */ {PROTO_HONTAI, HONTAI , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 7 */ {PROTO_HONTAI, HONTAI , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
/* 8 */ {PROTO_HONTAI, JJRCX1 , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 8 */ {PROTO_HONTAI, JJRCX1 , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
/* 9 */ {PROTO_HONTAI, X5C1 , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 9 */ {PROTO_HONTAI, X5C1 , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
/* 10 */ {PROTO_HONTAI, FQ777_951 , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 10 */ {PROTO_HONTAI, FQ777_951 , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
/* 11 */ {PROTO_Q303 , Q303 , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 11 */ {PROTO_Q303 , Q303 , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
/* 12 */ {PROTO_Q303 , CX35 , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 12 */ {PROTO_Q303 , CX35 , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
/* 13 */ {PROTO_Q303 , CX10D , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 13 */ {PROTO_Q303 , CX10D , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
/* 14 */ {PROTO_Q303 , CX10WD , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 14 */ {PROTO_Q303 , CX10WD , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
#endif
|
#endif
|
||||||
#if NBR_BANKS > 4
|
#if NBR_BANKS > 4
|
||||||
//****************************** BANK 5 ******************************
|
//****************************** BANK 5 ******************************
|
||||||
// Switch Protocol Sub protocol RX_Num Power Auto Bind Option
|
// Switch Protocol Sub protocol RX_Num Power Auto Bind Option Chan Order
|
||||||
/* 1 */ {PROTO_CX10 , CX10_GREEN , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 1 */ {PROTO_CX10 , CX10_GREEN , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
/* 2 */ {PROTO_CX10 , CX10_BLUE , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 2 */ {PROTO_CX10 , CX10_BLUE , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
/* 3 */ {PROTO_CX10 , DM007 , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 3 */ {PROTO_CX10 , DM007 , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
/* 4 */ {PROTO_CX10 , JC3015_1 , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 4 */ {PROTO_CX10 , JC3015_1 , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
/* 5 */ {PROTO_CX10 , JC3015_2 , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 5 */ {PROTO_CX10 , JC3015_2 , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
/* 6 */ {PROTO_CX10 , MK33041 , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 6 */ {PROTO_CX10 , MK33041 , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
/* 7 */ {PROTO_Q2X2 , Q222 , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 7 */ {PROTO_Q2X2 , Q222 , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
/* 8 */ {PROTO_Q2X2 , Q242 , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 8 */ {PROTO_Q2X2 , Q242 , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
/* 9 */ {PROTO_Q2X2 , Q282 , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 9 */ {PROTO_Q2X2 , Q282 , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
/* 10 */ {PROTO_CG023, CG023 , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 10 */ {PROTO_CG023, CG023 , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
/* 11 */ {PROTO_CG023, YD829 , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 11 */ {PROTO_CG023, YD829 , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
/* 12 */ {PROTO_FQ777, NONE , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 12 */ {PROTO_FQ777, NONE , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
/* 13 */ {PROTO_YD717, YD717 , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 13 */ {PROTO_YD717, YD717 , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
/* 14 */ {PROTO_MT99XX, MT99 , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 14 */ {PROTO_MT99XX, MT99 , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
// RX_Num is used for TX & RX match. Using different RX_Num values for each receiver will prevent starting a model with the false config loaded...
|
// RX_Num is used for TX & RX match. Using different RX_Num values for each receiver will prevent starting a model with the false config loaded...
|
||||||
@@ -471,12 +481,23 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
|
|||||||
// Option: the value is between -128 and +127.
|
// Option: the value is between -128 and +127.
|
||||||
// The option value is only valid for some protocols, read this page for more information: https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/blob/master/Protocols_Details.md
|
// The option value is only valid for some protocols, read this page for more information: https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/blob/master/Protocols_Details.md
|
||||||
|
|
||||||
|
// Chan order: if the value is different from 0, this setting will remap the first 8 channels in any given order before giving them to the protocol.
|
||||||
|
// It does not disable the automatic channel remapping of the protocol itself but changes the input of it.
|
||||||
|
// Even if your TX is sending less than 8 channels you have to respect the format like if it was.
|
||||||
|
// Examples:
|
||||||
|
// - 0x12345678 will give to the protocol the channels in the order 1,2,3,4,5,6,7,8 which is equivalent to 0x00000000.
|
||||||
|
// - 0x42315678 will give to the protocol the channels in the order 4,2,3,1,5,6,7,8 swapping channel 1 and 4.
|
||||||
|
// - 0x40010000 will give to the protocol the channels in the order 4,2,3,1,5,6,7,8 swapping channel 1 and 4. Note: 0 means leave the channel where it is.
|
||||||
|
// - 0x0000ABCD will give to the protocol the channels in the order 1,2,3,4,10,11,12,13 which potentially enables acces to channels not available on your TX. Note A=10,B=11,C=12,D=13,E=14,F=15.
|
||||||
|
|
||||||
/* Available protocols and associated sub protocols to pick and choose from (Listed in alphabetical order)
|
/* Available protocols and associated sub protocols to pick and choose from (Listed in alphabetical order)
|
||||||
PROTO_AFHDS2A
|
PROTO_AFHDS2A
|
||||||
PWM_IBUS
|
PWM_IBUS
|
||||||
PPM_IBUS
|
PPM_IBUS
|
||||||
PWM_SBUS
|
PWM_SBUS
|
||||||
PPM_SBUS
|
PPM_SBUS
|
||||||
|
PROTO_AFHDS2A_RX
|
||||||
|
NONE
|
||||||
PROTO_ASSAN
|
PROTO_ASSAN
|
||||||
NONE
|
NONE
|
||||||
PROTO_BAYANG
|
PROTO_BAYANG
|
||||||
@@ -485,6 +506,8 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
|
|||||||
X16_AH
|
X16_AH
|
||||||
IRDRONE
|
IRDRONE
|
||||||
DHD_D4
|
DHD_D4
|
||||||
|
PROTO_BAYANG_RX
|
||||||
|
NONE
|
||||||
PROTO_BUGS
|
PROTO_BUGS
|
||||||
NONE
|
NONE
|
||||||
PROTO_BUGSMINI
|
PROTO_BUGSMINI
|
||||||
@@ -525,9 +548,11 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
|
|||||||
E015
|
E015
|
||||||
E016H
|
E016H
|
||||||
PROTO_ESKY
|
PROTO_ESKY
|
||||||
NONE
|
ESKY_STD
|
||||||
|
ESKY_ET4
|
||||||
PROTO_ESKY150
|
PROTO_ESKY150
|
||||||
NONE
|
ESKY150_4CH
|
||||||
|
ESKY150_7CH
|
||||||
PROTO_FLYSKY
|
PROTO_FLYSKY
|
||||||
Flysky
|
Flysky
|
||||||
V9X9
|
V9X9
|
||||||
@@ -540,6 +565,11 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
|
|||||||
NONE
|
NONE
|
||||||
PROTO_FRSKYD
|
PROTO_FRSKYD
|
||||||
NONE
|
NONE
|
||||||
|
PROTO_FRSKYR9
|
||||||
|
R9_915
|
||||||
|
R9_868
|
||||||
|
R9_915_8CH
|
||||||
|
R9_868_8CH
|
||||||
PROTO_FRSKYV
|
PROTO_FRSKYV
|
||||||
NONE
|
NONE
|
||||||
PROTO_FRSKYX
|
PROTO_FRSKYX
|
||||||
@@ -547,6 +577,15 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
|
|||||||
CH_8
|
CH_8
|
||||||
EU_16
|
EU_16
|
||||||
EU_8
|
EU_8
|
||||||
|
PROTO_FRSKYX2
|
||||||
|
FRSKYX2_CH_16
|
||||||
|
FRSKYX2_CH_8
|
||||||
|
FRSKYX2_EU_16
|
||||||
|
FRSKYX2_EU_8
|
||||||
|
PROTO_FRSKY_RX
|
||||||
|
NONE
|
||||||
|
PROTO_FX816
|
||||||
|
NONE
|
||||||
PROTO_FY326
|
PROTO_FY326
|
||||||
FY326
|
FY326
|
||||||
FY319
|
FY319
|
||||||
@@ -572,6 +611,8 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
|
|||||||
JJRCX1
|
JJRCX1
|
||||||
X5C1
|
X5C1
|
||||||
FQ777_951
|
FQ777_951
|
||||||
|
PROTO_HOTT
|
||||||
|
NONE
|
||||||
PROTO_HUBSAN
|
PROTO_HUBSAN
|
||||||
H107
|
H107
|
||||||
H301
|
H301
|
||||||
@@ -599,6 +640,8 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
|
|||||||
FY805
|
FY805
|
||||||
PROTO_NCC1701
|
PROTO_NCC1701
|
||||||
NONE
|
NONE
|
||||||
|
PROTO_PELIKAN
|
||||||
|
NONE
|
||||||
PROTO_POTENSIC
|
PROTO_POTENSIC
|
||||||
NONE
|
NONE
|
||||||
PROTO_Q2X2
|
PROTO_Q2X2
|
||||||
@@ -628,6 +671,8 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
|
|||||||
PROTO_SYMAX
|
PROTO_SYMAX
|
||||||
SYMAX
|
SYMAX
|
||||||
SYMAX5C
|
SYMAX5C
|
||||||
|
PROTO_TIGER
|
||||||
|
NONE
|
||||||
PROTO_TRAXXAS
|
PROTO_TRAXXAS
|
||||||
RX6519
|
RX6519
|
||||||
PROTO_V2X2
|
PROTO_V2X2
|
||||||
@@ -636,7 +681,8 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
|
|||||||
PROTO_V761
|
PROTO_V761
|
||||||
NONE
|
NONE
|
||||||
PROTO_V911S
|
PROTO_V911S
|
||||||
NONE
|
V911S_STD
|
||||||
|
V911S_E119
|
||||||
PROTO_WFLY
|
PROTO_WFLY
|
||||||
NONE
|
NONE
|
||||||
PROTO_WK2x01
|
PROTO_WK2x01
|
||||||
@@ -646,6 +692,9 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
|
|||||||
W6_6_1
|
W6_6_1
|
||||||
W6_HEL
|
W6_HEL
|
||||||
W6_HEL_I
|
W6_HEL_I
|
||||||
|
PROTO_XK
|
||||||
|
X450
|
||||||
|
X420
|
||||||
PROTO_YD717
|
PROTO_YD717
|
||||||
YD717
|
YD717
|
||||||
SKYWLKR
|
SKYWLKR
|
||||||
@@ -655,3 +704,29 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
|
|||||||
PROTO_ZSX
|
PROTO_ZSX
|
||||||
NONE
|
NONE
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**********************************/
|
||||||
|
/*** DIRECT INPUTS SETTINGS ***/
|
||||||
|
/**********************************/
|
||||||
|
//In this section you can configure the direct inputs.
|
||||||
|
//It enables switches wired directly to the board
|
||||||
|
//Direct inputs works only in ppm mode and only for stm_32 boards
|
||||||
|
//Uncomment following lines to enable derect inputs or define your own configuration in _MyConfig.h
|
||||||
|
/*
|
||||||
|
#define ENABLE_DIRECT_INPUTS
|
||||||
|
|
||||||
|
#define DI1_PIN PC13
|
||||||
|
#define IS_DI1_on (digitalRead(DI1_PIN)==LOW)
|
||||||
|
|
||||||
|
#define DI2_PIN PC14
|
||||||
|
#define IS_DI2_on (digitalRead(DI2_PIN)==LOW)
|
||||||
|
|
||||||
|
#define DI3_PIN PC15
|
||||||
|
#define IS_DI3_on (digitalRead(DI3_PIN)==LOW)
|
||||||
|
|
||||||
|
//Define up to 4 direct input channels
|
||||||
|
//CHANNEL1 - 2pos switch
|
||||||
|
#define DI_CH1_read IS_DI1_on ? PPM_MAX_100*2 : PPM_MIN_100*2
|
||||||
|
//CHANNEL2 - 3pos switch
|
||||||
|
#define DI_CH2_read IS_DI2_on ? PPM_MAX_100*2 : (IS_DI2_on ? PPM_MAX_100 + PPM_MIN_100 : PPM_MIN_100*2)
|
||||||
|
*/
|
||||||
|
|||||||
@@ -60,20 +60,20 @@
|
|||||||
#define MY_PPM_PROT // Use the bellow protocol list
|
#define MY_PPM_PROT // Use the bellow protocol list
|
||||||
const PPM_Parameters My_PPM_prot[14*NBR_BANKS]={
|
const PPM_Parameters My_PPM_prot[14*NBR_BANKS]={
|
||||||
//****************************** BANK 1 ******************************
|
//****************************** BANK 1 ******************************
|
||||||
// Switch Protocol Sub protocol RX_Num Power Auto Bind Option
|
// Switch Protocol Sub protocol RX_Num Power Auto Bind Option Chan Order
|
||||||
/* 1 */ {PROTO_KN , WLTOYS , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 1 */ {PROTO_KN , WLTOYS , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
/* 2 */ {PROTO_FLYSKY, Flysky , 0 , P_HIGH , AUTOBIND , 0 },
|
/* 2 */ {PROTO_FLYSKY, Flysky , 0 , P_HIGH , AUTOBIND , 0 , 0x00000000 },
|
||||||
/* 3 */ {PROTO_AFHDS2A, PWM_IBUS , 1 , P_HIGH , NO_AUTOBIND , 0 }, // RX number 1
|
/* 3 */ {PROTO_AFHDS2A, PWM_IBUS , 1 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 }, // RX number 1
|
||||||
/* 4 */ {PROTO_AFHDS2A, PWM_IBUS , 2 , P_HIGH , NO_AUTOBIND , 0 }, // RX number 2
|
/* 4 */ {PROTO_AFHDS2A, PWM_IBUS , 2 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 }, // RX number 2
|
||||||
/* 5 */ {PROTO_AFHDS2A, PWM_IBUS , 3 , P_HIGH , NO_AUTOBIND , 0 }, // RX number 3
|
/* 5 */ {PROTO_AFHDS2A, PWM_IBUS , 3 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 }, // RX number 3
|
||||||
/* 6 */ {PROTO_AFHDS2A, PWM_IBUS , 2 , P_HIGH , NO_AUTOBIND , 0 }, // RX number 4
|
/* 6 */ {PROTO_AFHDS2A, PWM_IBUS , 2 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 }, // RX number 4
|
||||||
/* 7 */ {PROTO_AFHDS2A, PWM_IBUS , 3 , P_HIGH , NO_AUTOBIND , 0 }, // RX number 5
|
/* 7 */ {PROTO_AFHDS2A, PWM_IBUS , 3 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 }, // RX number 5
|
||||||
/* 8 */ {PROTO_SFHSS, H107 , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 8 */ {PROTO_SFHSS, H107 , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
/* 9 */ {PROTO_FRSKYV, NONE , 0 , P_HIGH , NO_AUTOBIND , 40 }, // option=fine freq tuning
|
/* 9 */ {PROTO_FRSKYV, NONE , 0 , P_HIGH , NO_AUTOBIND , 40 , 0x00000000 }, // option=fine freq tuning
|
||||||
/* 10 */ {PROTO_FRSKYD, NONE , 0 , P_HIGH , NO_AUTOBIND , 40 }, // option=fine freq tuning
|
/* 10 */ {PROTO_FRSKYD, NONE , 0 , P_HIGH , NO_AUTOBIND , 40 , 0x00000000 }, // option=fine freq tuning
|
||||||
/* 11 */ {PROTO_FRSKYX, CH_16 , 0 , P_HIGH , NO_AUTOBIND , 40 }, // option=fine freq tuning
|
/* 11 */ {PROTO_FRSKYX, CH_16 , 0 , P_HIGH , NO_AUTOBIND , 40 , 0x00000000 }, // option=fine freq tuning
|
||||||
/* 12 */ {PROTO_FRSKYX, EU_16 , 0 , P_HIGH , NO_AUTOBIND , 40 }, // option=fine freq tuning
|
/* 12 */ {PROTO_FRSKYX, EU_16 , 0 , P_HIGH , NO_AUTOBIND , 40 , 0x00000000 }, // option=fine freq tuning
|
||||||
/* 13 */ {PROTO_DEVO , NONE , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 13 */ {PROTO_DEVO , NONE , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
/* 14 */ {PROTO_WK2x01, WK2801 , 0 , P_HIGH , NO_AUTOBIND , 0 },
|
/* 14 */ {PROTO_WK2x01, WK2801 , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
34
Multiprotocol/iface_nrf250k.h
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
#ifndef _IFACE_NRF250K_H_
|
||||||
|
|
||||||
|
#define _IFACE_NRF250K_H_
|
||||||
|
|
||||||
|
#if defined (CC2500_INSTALLED)
|
||||||
|
#include "iface_cc2500.h"
|
||||||
|
#endif
|
||||||
|
#if defined (NRF24L01_INSTALLED)
|
||||||
|
#include "iface_nrf24l01.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//XN297L
|
||||||
|
static void __attribute__((unused)) XN297L_Init();
|
||||||
|
static void __attribute__((unused)) XN297L_SetTXAddr(const uint8_t*, uint8_t);
|
||||||
|
static void __attribute__((unused)) XN297L_WritePayload(uint8_t*, uint8_t);
|
||||||
|
static void __attribute__((unused)) XN297L_WriteEnhancedPayload(uint8_t*, uint8_t, uint8_t);
|
||||||
|
static void __attribute__((unused)) XN297L_HoppingCalib(__attribute__((unused)) uint8_t);
|
||||||
|
static void __attribute__((unused)) XN297L_Hopping(uint8_t);
|
||||||
|
static void __attribute__((unused)) XN297L_RFChannel(uint8_t);
|
||||||
|
static void __attribute__((unused)) XN297L_SetPower();
|
||||||
|
static void __attribute__((unused)) XN297L_SetFreqOffset();
|
||||||
|
|
||||||
|
//NRF250K
|
||||||
|
#define NRF250K_Init() XN297L_Init()
|
||||||
|
#define NRF250K_HoppingCalib(X) XN297L_HoppingCalib(X)
|
||||||
|
#define NRF250K_Hopping(X) XN297L_Hopping(X)
|
||||||
|
#define NRF250K_RFChannel(X) XN297L_RFChannel(X)
|
||||||
|
#define NRF250K_SetPower() XN297L_SetPower()
|
||||||
|
#define NRF250K_SetFreqOffset() XN297L_SetFreqOffset()
|
||||||
|
static void __attribute__((unused)) NRF250K_SetTXAddr(uint8_t*, uint8_t);
|
||||||
|
static void __attribute__((unused)) NRF250K_WritePayload(uint8_t*, uint8_t);
|
||||||
|
static boolean __attribute__((unused)) NRF250K_IsPacketSent();
|
||||||
|
|
||||||
|
#endif
|
||||||
90
Multiprotocol/iface_sx1276.h
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _IFACE_SX1276_H_
|
||||||
|
#define _IFACE_SX1276_H_
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
SX1276_00_FIFO = 0x00,
|
||||||
|
SX1276_01_OPMODE = 0x01,
|
||||||
|
SX1276_06_FRFMSB = 0x06,
|
||||||
|
SX1276_09_PACONFIG = 0x09,
|
||||||
|
SX1276_0B_OCP = 0x0B,
|
||||||
|
SX1276_0C_LNA = 0x0C,
|
||||||
|
SX1276_0D_FIFOADDRPTR = 0x0D,
|
||||||
|
SX1276_0E_FIFOTXBASEADDR = 0x0E,
|
||||||
|
SX1276_11_IRQFLAGSMASK = 0x11,
|
||||||
|
SX1276_1D_MODEMCONFIG1 = 0x1D,
|
||||||
|
SX1276_1E_MODEMCONFIG2 = 0x1E,
|
||||||
|
SX1276_20_PREAMBLEMSB = 0x20,
|
||||||
|
SX1276_22_PAYLOAD_LENGTH = 0x22,
|
||||||
|
SX1276_24_HOPPERIOD = 0x24,
|
||||||
|
SX1276_26_MODEMCONFIG3 = 0x26,
|
||||||
|
SX1276_31_DETECTOPTIMIZE = 0x31,
|
||||||
|
SX1276_37_DETECTIONTHRESHOLD = 0x37,
|
||||||
|
SX1276_40_DIOMAPPING1 = 0x40,
|
||||||
|
SX1276_42_VERSION = 0x42,
|
||||||
|
SX1276_4D_PADAC = 0x4D
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
SX1276_OPMODE_SLEEP = 0,
|
||||||
|
SX1276_OPMODE_STDBY,
|
||||||
|
SX1276_OPMODE_FSTX,
|
||||||
|
SX1276_OPMODE_TX,
|
||||||
|
SX1276_OPMODE_FSRX,
|
||||||
|
SX1276_OPMODE_RXCONTINUOUS,
|
||||||
|
SX1276_OPMODE_RXSINGLE,
|
||||||
|
SX1276_OPMODE_CAD
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
SX1276_DETECT_OPTIMIZE_SF7_TO_SF12 = 0x03,
|
||||||
|
SX1276_DETECT_OPTIMIZE_SF6 = 0x05
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
SX1276_MODEM_CONFIG1_BW_7_8KHZ = 0,
|
||||||
|
SX1276_MODEM_CONFIG1_BW_10_4KHZ,
|
||||||
|
SX1276_MODEM_CONFIG1_BW_15_6KHZ,
|
||||||
|
SX1276_MODEM_CONFIG1_BW_20_8KHZ,
|
||||||
|
SX1276_MODEM_CONFIG1_BW_31_25KHZ,
|
||||||
|
SX1276_MODEM_CONFIG1_BW_41_7KHZ,
|
||||||
|
SX1276_MODEM_CONFIG1_BW_62_5KHZ,
|
||||||
|
SX1276_MODEM_CONFIG1_BW_125KHZ,
|
||||||
|
SX1276_MODEM_CONFIG1_BW_250KHZ,
|
||||||
|
SX1276_MODEM_CONFIG1_BW_500KHZ
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
SX1276_MODEM_CONFIG1_CODING_RATE_4_5 = 1,
|
||||||
|
SX1276_MODEM_CONFIG1_CODING_RATE_4_6,
|
||||||
|
SX1276_MODEM_CONFIG1_CODING_RATE_4_7,
|
||||||
|
SX1276_MODEM_CONFIG1_CODING_RATE_4_8
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
SX1276_MODEM_DETECTION_THRESHOLD_SF7_TO_SF12 = 0x0A,
|
||||||
|
SX1276_MODEM_DETECTION_THRESHOLD_SF6 = 0x0C,
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
#ifndef _IFACE_XN297L_H_
|
|
||||||
|
|
||||||
#define _IFACE_XN297L_H_
|
|
||||||
|
|
||||||
#if defined (XN297L_CC2500_EMU)
|
|
||||||
#include "iface_cc2500.h"
|
|
||||||
#elif defined (NRF24L01_INSTALLED)
|
|
||||||
#include "iface_nrf24l01.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void __attribute__((unused)) XN297L_Init();
|
|
||||||
static void __attribute__((unused)) XN297L_SetTXAddr(const uint8_t*, uint8_t);
|
|
||||||
static void __attribute__((unused)) XN297L_WritePayload(uint8_t*, uint8_t);
|
|
||||||
static void __attribute__((unused)) XN297L_HoppingCalib(__attribute__((unused)) uint8_t);
|
|
||||||
static void __attribute__((unused)) XN297L_Hopping(uint8_t);
|
|
||||||
static void __attribute__((unused)) XN297L_RFChannel(uint8_t);
|
|
||||||
static void __attribute__((unused)) XN297L_SetPower();
|
|
||||||
static void __attribute__((unused)) XN297L_SetFreqOffset();
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -22,14 +22,13 @@ Here are detailed descriptions of every supported protocols (sorted by RF module
|
|||||||
- Bind channel is going from -100% to +100%
|
- Bind channel is going from -100% to +100%
|
||||||
|
|
||||||
* Additional notes:
|
* Additional notes:
|
||||||
- It's recommended to combine Throttle cut with another button to drive the bind channel. This will prevent to launch a bind while flying...
|
- **It's recommended to combine the bind switch with Throttle cut or throttle at -100% to drive the bind channel. This will prevent to launch a bind while flying** and enable you to use the bind switch for something else.
|
||||||
- Bind channel does not have to be assigned to a free channel. Since it only acts when Throttle is Low (and throttle cut active), it could be used on the same channel as Flip for example since you are not going to flip your model when Throttle is low... Same goes for RTH and such other features.
|
|
||||||
- Using channel 16 for the bind channel seems the most relevant as only one protocol so far is using 16 channels which is FrSkyX. But even on FrSkyX this feature won't have any impact since there is NO valid reason to have Autobind set to Y for such a protocol.
|
- Using channel 16 for the bind channel seems the most relevant as only one protocol so far is using 16 channels which is FrSkyX. But even on FrSkyX this feature won't have any impact since there is NO valid reason to have Autobind set to Y for such a protocol.
|
||||||
|
|
||||||
## Protocol selection in PPM mode
|
## Protocol selection in PPM mode
|
||||||
The protocol selection is based on 2 parameters:
|
The protocol selection is based on 2 parameters:
|
||||||
* selection switch: this is the rotary switch on the module numbered from 0 to 15
|
* selection switch: this is the rotary switch on the module numbered from 0 to 15
|
||||||
- switch position 0 is to select the Serial mode for er9x/ersky9x/OpenTX radio
|
- switch position 0 is to select the Serial mode for er9x/erskyTX/OpenTX radio
|
||||||
- switch position 15 is to select the bank
|
- switch position 15 is to select the bank
|
||||||
- switch position 1..14 will select the protocol 1..14 in the bank *X*
|
- switch position 1..14 will select the protocol 1..14 in the bank *X*
|
||||||
* banks are used to increase the amount of accessible protocols by the switch. There are up to 5 banks giving acces to up to 70 protocol entries (5 * 14). To modify or verify which bank is currenlty active do the following:
|
* banks are used to increase the amount of accessible protocols by the switch. There are up to 5 banks giving acces to up to 70 protocol entries (5 * 14). To modify or verify which bank is currenlty active do the following:
|
||||||
@@ -56,7 +55,7 @@ Notes:
|
|||||||
Serial mode is selected by placing the rotary switch to position 0 before power on of the radio.
|
Serial mode is selected by placing the rotary switch to position 0 before power on of the radio.
|
||||||
|
|
||||||
You've upgraded the module but the radio does not display the name of the protocol you are loking for:
|
You've upgraded the module but the radio does not display the name of the protocol you are loking for:
|
||||||
* ersky9x:
|
* erskyTX:
|
||||||
- Place the file [Multi.txt](https://raw.githubusercontent.com/pascallanger/DIY-Multiprotocol-TX-Module/master/Multiprotocol/Multi.txt) (which is part of the MPM source files) on the root of your SD card.
|
- Place the file [Multi.txt](https://raw.githubusercontent.com/pascallanger/DIY-Multiprotocol-TX-Module/master/Multiprotocol/Multi.txt) (which is part of the MPM source files) on the root of your SD card.
|
||||||
- If the entry still does not appear or is broken, [upgrade](https://openrcforums.com/forum/viewtopic.php?f=7&t=4676) to version R222d2 or newer.
|
- If the entry still does not appear or is broken, [upgrade](https://openrcforums.com/forum/viewtopic.php?f=7&t=4676) to version R222d2 or newer.
|
||||||
* OpenTX:
|
* OpenTX:
|
||||||
@@ -69,6 +68,7 @@ Protocol Name|Protocol Number|Sub_Proto 0|Sub_Proto 1|Sub_Proto 2|Sub_Proto 3|Su
|
|||||||
---|---|---|---|---|---|---|---|---|---|---|---
|
---|---|---|---|---|---|---|---|---|---|---|---
|
||||||
[Assan](Protocols_Details.md#ASSAN---24)|24|ASSAN||||||||NRF24L01|
|
[Assan](Protocols_Details.md#ASSAN---24)|24|ASSAN||||||||NRF24L01|
|
||||||
[Bayang](Protocols_Details.md#BAYANG---14)|14|Bayang|H8S3D|X16_AH|IRDRONE|DHD_D4||||NRF24L01|XN297
|
[Bayang](Protocols_Details.md#BAYANG---14)|14|Bayang|H8S3D|X16_AH|IRDRONE|DHD_D4||||NRF24L01|XN297
|
||||||
|
[Bayang RX](Protocols_Details.md#BAYANG-RX---59)|59|||||||||NRF24L01|XN297
|
||||||
[Bugs](Protocols_Details.md#BUGS---41)|41|BUGS||||||||A7105|
|
[Bugs](Protocols_Details.md#BUGS---41)|41|BUGS||||||||A7105|
|
||||||
[BugsMini](Protocols_Details.md#BUGSMINI---42)|42|BUGSMINI|BUGS3H|||||||NRF24L01|XN297
|
[BugsMini](Protocols_Details.md#BUGSMINI---42)|42|BUGSMINI|BUGS3H|||||||NRF24L01|XN297
|
||||||
[Cabell](Protocols_Details.md#Cabell---34)|34|Cabell_V3|C_TELEM|-|-|-|-|F_SAFE|UNBIND|NRF24L01|
|
[Cabell](Protocols_Details.md#Cabell---34)|34|Cabell_V3|C_TELEM|-|-|-|-|F_SAFE|UNBIND|NRF24L01|
|
||||||
@@ -80,15 +80,19 @@ CFlie|38|CFlie||||||||NRF24L01|
|
|||||||
[DM002](Protocols_Details.md#DM002---33)|33|DM002||||||||NRF24L01|XN297
|
[DM002](Protocols_Details.md#DM002---33)|33|DM002||||||||NRF24L01|XN297
|
||||||
[DSM](Protocols_Details.md#DSM---6)|6|DSM2-22|DSM2-11|DSMX-22|DSMX-11|AUTO||||CYRF6936|
|
[DSM](Protocols_Details.md#DSM---6)|6|DSM2-22|DSM2-11|DSMX-22|DSMX-11|AUTO||||CYRF6936|
|
||||||
[E01X](Protocols_Details.md#E01X---45)|45|E012|E015|E016H||||||NRF24L01|XN297/HS6200
|
[E01X](Protocols_Details.md#E01X---45)|45|E012|E015|E016H||||||NRF24L01|XN297/HS6200
|
||||||
[ESky](Protocols_Details.md#ESKY---16)|16|ESky||||||||NRF24L01|
|
[ESky](Protocols_Details.md#ESKY---16)|16|ESky|Std|ET4||||||NRF24L01|
|
||||||
[ESky150](Protocols_Details.md#ESKY150---35)|35|ESKY150||||||||NRF24L01|
|
[ESky150](Protocols_Details.md#ESKY150---35)|35|ESKY150||||||||NRF24L01|
|
||||||
[Flysky](Protocols_Details.md#FLYSKY---1)|1|Flysky|V9x9|V6x6|V912|CX20||||A7105|
|
[Flysky](Protocols_Details.md#FLYSKY---1)|1|Flysky|V9x9|V6x6|V912|CX20||||A7105|
|
||||||
[Flysky AFHDS2A](Protocols_Details.md#FLYSKY-AFHDS2A---28)|28|PWM_IBUS|PPM_IBUS|PWM_SBUS|PPM_SBUS|||||A7105|
|
[Flysky AFHDS2A](Protocols_Details.md#FLYSKY-AFHDS2A---28)|28|PWM_IBUS|PPM_IBUS|PWM_SBUS|PPM_SBUS|||||A7105|
|
||||||
[Flyzone](Protocols_Details.md#FLYZONE---53)|53|Flyzone|FZ410|||||||A7105|
|
[Flysky AFHDS2A RX](Protocols_Details.md#FLYSKY-AFHDS2A-RX---56)|56|||||||||A7105|
|
||||||
|
[Flyzone](Protocols_Details.md#FLYZONE---53)|53|FZ410||||||||A7105|
|
||||||
[FQ777](Protocols_Details.md#FQ777---23)|23|FQ777||||||||NRF24L01|SSV7241
|
[FQ777](Protocols_Details.md#FQ777---23)|23|FQ777||||||||NRF24L01|SSV7241
|
||||||
[FrskyD](Protocols_Details.md#FRSKYD---3)|3|FrskyD||||||||CC2500|
|
[FrskyD](Protocols_Details.md#FRSKYD---3)|3|FrskyD||||||||CC2500|
|
||||||
|
[FrskyR9](Protocols_Details.md#FRSKYR9---65)|65|FrskyR9|R9_915|R9_868||||||SX1276|
|
||||||
[FrskyV](Protocols_Details.md#FRSKYV---25)|25|FrskyV||||||||CC2500|
|
[FrskyV](Protocols_Details.md#FRSKYV---25)|25|FrskyV||||||||CC2500|
|
||||||
[FrskyX](Protocols_Details.md#FRSKYX---15)|15|CH_16|CH_8|EU_16|EU_8|||||CC2500|
|
[FrskyX](Protocols_Details.md#FRSKYX---15)|15|CH_16|CH_8|EU_16|EU_8|||||CC2500|
|
||||||
|
[FrskyX_RX](Protocols_Details.md#FRSKYX_RX---55)|55|FCC|EU_LBT|||||CC2500|
|
||||||
|
[FX816](Protocols_Details.md#FX816---58)|28|FX816|P38|||||||NRF24L01|
|
||||||
[FY326](Protocols_Details.md#FY326---20)|20|FY326|FY319|||||||NRF24L01|
|
[FY326](Protocols_Details.md#FY326---20)|20|FY326|FY319|||||||NRF24L01|
|
||||||
[GD00X](Protocols_Details.md#GD00X---47)|47|GD_V1*|GD_V2*|||||||NRF24L01|
|
[GD00X](Protocols_Details.md#GD00X---47)|47|GD_V1*|GD_V2*|||||||NRF24L01|
|
||||||
[GW008](Protocols_Details.md#GW008---32)|32|GW008||||||||NRF24L01|XN297
|
[GW008](Protocols_Details.md#GW008---32)|32|GW008||||||||NRF24L01|XN297
|
||||||
@@ -96,6 +100,7 @@ CFlie|38|CFlie||||||||NRF24L01|
|
|||||||
[Hisky](Protocols_Details.md#HISKY---4)|4|Hisky|HK310|||||||NRF24L01|
|
[Hisky](Protocols_Details.md#HISKY---4)|4|Hisky|HK310|||||||NRF24L01|
|
||||||
[Hitec](Protocols_Details.md#HITEC---39)|39|OPT_FW|OPT_HUB|MINIMA||||||CC2500|
|
[Hitec](Protocols_Details.md#HITEC---39)|39|OPT_FW|OPT_HUB|MINIMA||||||CC2500|
|
||||||
[Hontai](Protocols_Details.md#HONTAI---26)|26|HONTAI|JJRCX1|X5C1|FQ777_951|||||NRF24L01|XN297
|
[Hontai](Protocols_Details.md#HONTAI---26)|26|HONTAI|JJRCX1|X5C1|FQ777_951|||||NRF24L01|XN297
|
||||||
|
[HoTT](Protocols_Details.md#HoTT---57)|57|||||||||CC2500|
|
||||||
[Hubsan](Protocols_Details.md#HUBSAN---2)|2|H107|H301|H501||||||A7105|
|
[Hubsan](Protocols_Details.md#HUBSAN---2)|2|H107|H301|H501||||||A7105|
|
||||||
[J6Pro](Protocols_Details.md#J6Pro---22)|22|J6PRO||||||||CYRF6936|
|
[J6Pro](Protocols_Details.md#J6Pro---22)|22|J6PRO||||||||CYRF6936|
|
||||||
[KF606](Protocols_Details.md#KF606---49)|49|KF606*||||||||NRF24L01|XN297
|
[KF606](Protocols_Details.md#KF606---49)|49|KF606*||||||||NRF24L01|XN297
|
||||||
@@ -104,6 +109,7 @@ CFlie|38|CFlie||||||||NRF24L01|
|
|||||||
[MT99xx](Protocols_Details.md#MT99XX---17)|17|MT|H7|YZ|LS|FY805||||NRF24L01|XN297
|
[MT99xx](Protocols_Details.md#MT99XX---17)|17|MT|H7|YZ|LS|FY805||||NRF24L01|XN297
|
||||||
[NCC1701](Protocols_Details.md#NCC1701---44)|44|NCC1701||||||||NRF24L01|
|
[NCC1701](Protocols_Details.md#NCC1701---44)|44|NCC1701||||||||NRF24L01|
|
||||||
[OpenLRS](Protocols_Details.md#OpenLRS---27)|27|||||||||None|
|
[OpenLRS](Protocols_Details.md#OpenLRS---27)|27|||||||||None|
|
||||||
|
[Pelikan](Protocols_Details.md#Pelikan---60)|60|||||||||A7105|
|
||||||
[Potensic](Protocols_Details.md#Potensic---51)|51|A20||||||||NRF24L01|XN297
|
[Potensic](Protocols_Details.md#Potensic---51)|51|A20||||||||NRF24L01|XN297
|
||||||
[Q2X2](Protocols_Details.md#Q2X2---29)|29|Q222|Q242|Q282||||||NRF24L01|
|
[Q2X2](Protocols_Details.md#Q2X2---29)|29|Q222|Q242|Q282||||||NRF24L01|
|
||||||
[Q303](Protocols_Details.md#Q303---31)|31|Q303|CX35|CX10D|CX10WD|||||NRF24L01|XN297
|
[Q303](Protocols_Details.md#Q303---31)|31|Q303|CX35|CX10D|CX10WD|||||NRF24L01|XN297
|
||||||
@@ -113,15 +119,16 @@ CFlie|38|CFlie||||||||NRF24L01|
|
|||||||
[Shenqi](Protocols_Details.md#Shenqi---19)|19|Shenqi||||||||NRF24L01|LT8900
|
[Shenqi](Protocols_Details.md#Shenqi---19)|19|Shenqi||||||||NRF24L01|LT8900
|
||||||
[SLT](Protocols_Details.md#SLT---11)|11|SLT_V1|SLT_V2|Q100|Q200|MR100||||NRF24L01|
|
[SLT](Protocols_Details.md#SLT---11)|11|SLT_V1|SLT_V2|Q100|Q200|MR100||||NRF24L01|
|
||||||
[SymaX](Protocols_Details.md#Symax---10)|10|SYMAX|SYMAX5C|||||||NRF24L01|
|
[SymaX](Protocols_Details.md#Symax---10)|10|SYMAX|SYMAX5C|||||||NRF24L01|
|
||||||
[Traxxas](Protocols_Details.md#Traxxas---43)|43|Traxxas|RX6519|||||||CYRF6936|
|
[Tiger](Protocols_Details.md#Tiger---61)|61|Tiger||||||||NRF24L01|XN297
|
||||||
|
[Traxxas](Protocols_Details.md#Traxxas---43)|43|RX6519||||||||CYRF6936|
|
||||||
[V2x2](Protocols_Details.md#V2X2---5)|5|V2x2|JXD506|||||||NRF24L01|
|
[V2x2](Protocols_Details.md#V2X2---5)|5|V2x2|JXD506|||||||NRF24L01|
|
||||||
[V761](Protocols_Details.md#V761---48)|48|V761||||||||NRF24L01|XN297
|
[V761](Protocols_Details.md#V761---48)|48|V761||||||||NRF24L01|XN297
|
||||||
[V911S](Protocols_Details.md#V911S---46)|46|V911S*||||||||NRF24L01|XN297
|
[V911S](Protocols_Details.md#V911S---46)|46|V911S*|E119*|||||||NRF24L01|XN297
|
||||||
[WFly](Protocols_Details.md#WFLY---40)|40|WFLY||||||||CYRF6936|
|
[WFly](Protocols_Details.md#WFLY---40)|40|WFLY||||||||CYRF6936|
|
||||||
[WK2x01](Protocols_Details.md#WK2X01---30)|30|WK2801|WK2401|W6_5_1|W6_6_1|W6_HEL|W6_HEL_I|||CYRF6936|
|
[WK2x01](Protocols_Details.md#WK2X01---30)|30|WK2801|WK2401|W6_5_1|W6_6_1|W6_HEL|W6_HEL_I|||CYRF6936|
|
||||||
[YD717](Protocols_Details.md#YD717---8)|8|YD717|SKYWLKR|SYMAX4|XINXUN|NIHUI||||NRF24L01|
|
[YD717](Protocols_Details.md#YD717---8)|8|YD717|SKYWLKR|SYMAX4|XINXUN|NIHUI||||NRF24L01|
|
||||||
[ZSX](Protocols_Details.md#ZSX---52)|52|280||||||||NRF24L01|XN297
|
[ZSX](Protocols_Details.md#ZSX---52)|52|280||||||||NRF24L01|XN297
|
||||||
* "*" Sub Protocols designated by * suffix will use the NRF24L01 module by default to emulate the XN297L RF chip. If a CC2500 module is installed it will be used instead as it is proving to be a better option for the XN297L@250kbps. Each specific sub protocol has a more detailed explanation.
|
* "*" Sub Protocols designated by * suffix are using a XN297L@250kbps which will be emulated by default with the NRF24L01. If option (freq tune) is diffrent from 0, the CC2500 module (if installed) will be used instead. Each specific sub protocol has a more detailed explanation.
|
||||||
|
|
||||||
# A7105 RF Module
|
# A7105 RF Module
|
||||||
|
|
||||||
@@ -164,11 +171,11 @@ Extended limits and failsafe supported
|
|||||||
|
|
||||||
Telemetry enabled protocol:
|
Telemetry enabled protocol:
|
||||||
- by defaut using FrSky Hub protocol (for example er9x): RX(A1), battery voltage FS-CVT01(A2) and RX&TX RSSI
|
- by defaut using FrSky Hub protocol (for example er9x): RX(A1), battery voltage FS-CVT01(A2) and RX&TX RSSI
|
||||||
- if using ersky9x and OpenTX: full telemetry information available
|
- if using erskyTX and OpenTX: full telemetry information available
|
||||||
|
|
||||||
Option is used to change the servo refresh rate. A value of 0 gives 50Hz (min), 70 gives 400Hz (max). Specific refresh rate value can be calculated like this option=(refresh_rate-50)/5.
|
Option is used to change the servo refresh rate. A value of 0 gives 50Hz (min), 70 gives 400Hz (max). Specific refresh rate value can be calculated like this option=(refresh_rate-50)/5.
|
||||||
|
|
||||||
**RX_Num is used to give a number a given RX. You must use a different RX_Num per RX. A maximum of 16 AFHDS2A RXs are supported.**
|
**RX_Num is used to give a number a given RX. You must use a different RX_Num per RX. A maximum of 64 AFHDS2A RXs are supported.**
|
||||||
|
|
||||||
OpenTX suggested RSSI alarm threshold settings (Telemetry tab): Low=15, Critical=12.
|
OpenTX suggested RSSI alarm threshold settings (Telemetry tab): Low=15, Critical=12.
|
||||||
|
|
||||||
@@ -187,10 +194,19 @@ Note that the RX ouput will be AETR whatever the input channel order is.
|
|||||||
### Sub_protocol PWM_SBUS - *2*
|
### Sub_protocol PWM_SBUS - *2*
|
||||||
### Sub_protocol PPM_SBUS - *3*
|
### Sub_protocol PPM_SBUS - *3*
|
||||||
|
|
||||||
|
## FLYSKY AFHDS2A RX - *56*
|
||||||
|
The Flysky AFHDS2A receiver protocol enables master/slave trainning, separate access from 2 different radios to the same model,...
|
||||||
|
|
||||||
|
Available in OpenTX 2.3.3, Trainer Mode Master/Multi
|
||||||
|
|
||||||
|
Extended limits supported
|
||||||
|
|
||||||
|
Low power: enable/disable the LNA stage on the RF component to use depending on the distance with the TX.
|
||||||
|
|
||||||
## FLYZONE - *53*
|
## FLYZONE - *53*
|
||||||
Models using the Flyzone FZ-410 TX: Fokker D.VII Micro EP RTF
|
Models using the Flyzone FZ-410 TX: Fokker D.VII Micro EP RTF
|
||||||
|
|
||||||
Models using the old ARES TX (prior to Hitec RED): Tiger Moth
|
Models using the old ARES TX (prior to Hitec RED): Tiger Moth, eRC Micro Stik
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4
|
CH1|CH2|CH3|CH4
|
||||||
---|---|---|---
|
---|---|---|---
|
||||||
@@ -242,6 +258,19 @@ A|E|T|R|ARM|ANGLE|FLIP|PICTURE|VIDEO|LED
|
|||||||
|
|
||||||
ANGLE: angle is +100%, acro is -100%
|
ANGLE: angle is +100%, acro is -100%
|
||||||
|
|
||||||
|
## Pelikan - *60*
|
||||||
|
Models: TX: CADET PRO V4, RX: RX-602 V4
|
||||||
|
|
||||||
|
Extended limits supported
|
||||||
|
|
||||||
|
**Only 1 set of frequencies for now**
|
||||||
|
|
||||||
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
||||||
|
---|---|---|---|---|---|---|---
|
||||||
|
A|E|T|R|CH5|CH6|CH7|CH8
|
||||||
|
|
||||||
|
Note that the RX ouput will be AETR.
|
||||||
|
|
||||||
***
|
***
|
||||||
# CC2500 RF Module
|
# CC2500 RF Module
|
||||||
|
|
||||||
@@ -294,7 +323,7 @@ Models: FrSky receivers D4R and D8R. DIY RX-F801 and RX-F802 receivers. Also kno
|
|||||||
|
|
||||||
Extended limits supported
|
Extended limits supported
|
||||||
|
|
||||||
Telemetry enabled for A0, A1, RSSI, TSSI and Hub
|
Telemetry enabled for A0, A1, RSSI, TX_RSSI, TX_LQI and Hub. Lowest the TX_LQI value is best the quality link is, it's a good indicator of how well the module is tuned.
|
||||||
|
|
||||||
Option for this protocol corresponds to fine frequency tuning. This value is different for each Module and **must** be accurate otherwise the link will not be stable.
|
Option for this protocol corresponds to fine frequency tuning. This value is different for each Module and **must** be accurate otherwise the link will not be stable.
|
||||||
Check the [Frequency Tuning page](/docs/Frequency_Tuning.md) to determine it.
|
Check the [Frequency Tuning page](/docs/Frequency_Tuning.md) to determine it.
|
||||||
@@ -308,7 +337,7 @@ Models: FrSky receivers X4R, X6R and X8R. Also known as D16.
|
|||||||
|
|
||||||
Extended limits and failsafe supported
|
Extended limits and failsafe supported
|
||||||
|
|
||||||
Telemetry enabled for A1 (RxBatt), A2, RSSI, TSSI and Hub
|
Telemetry enabled for A1 (RxBatt), A2, RSSI, TX_RSSI, TX_LQI and Hub. Lowest the TX_LQI value is best the quality link is, it's a good indicator of how well the module is tuned.
|
||||||
|
|
||||||
Option for this protocol corresponds to fine frequency tuning. This value is different for each Module and **must** be accurate otherwise the link will not be stable.
|
Option for this protocol corresponds to fine frequency tuning. This value is different for each Module and **must** be accurate otherwise the link will not be stable.
|
||||||
Check the [Frequency Tuning page](/docs/Frequency_Tuning.md) to determine it.
|
Check the [Frequency Tuning page](/docs/Frequency_Tuning.md) to determine it.
|
||||||
@@ -341,6 +370,34 @@ CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
|||||||
---|---|---|---|---|---|---|---
|
---|---|---|---|---|---|---|---
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
||||||
|
|
||||||
|
## FRSKYX_RX - *55*
|
||||||
|
The FrSkyX receiver protocol enables master/slave trainning, separate access from 2 different radios to the same model,...
|
||||||
|
|
||||||
|
Available in OpenTX 2.3.3, Trainer Mode Master/Multi
|
||||||
|
|
||||||
|
Extended limits supported
|
||||||
|
|
||||||
|
Option for this protocol corresponds to fine frequency tuning.
|
||||||
|
If the value is equal to 0, the RX will auto tune otherwise it will use the indicated value.
|
||||||
|
This value is different for each Module and **must** be accurate otherwise the link will not be stable.
|
||||||
|
Check the [Frequency Tuning page](/docs/Frequency_Tuning.md) to determine it.
|
||||||
|
|
||||||
|
Low power: enable/disable the LNA stage on the RF component to use depending on the distance with the TX.
|
||||||
|
|
||||||
|
### Sub_protocol FCC - *0*
|
||||||
|
FCC protocol 8 or 16 channels.
|
||||||
|
|
||||||
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13|CH14|CH15|CH16
|
||||||
|
---|---|---|---|---|---|---|---|---|----|----|----|----|----|----|----
|
||||||
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13|CH14|CH15|CH16
|
||||||
|
|
||||||
|
### Sub_protocol EU_LBT - *1*
|
||||||
|
EU_LBT protocol 8 or 16 channels.
|
||||||
|
|
||||||
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13|CH14|CH15|CH16
|
||||||
|
---|---|---|---|---|---|---|---|---|----|----|----|----|----|----|----
|
||||||
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13|CH14|CH15|CH16
|
||||||
|
|
||||||
## HITEC - *39*
|
## HITEC - *39*
|
||||||
Models: OPTIMA, MINIMA and MICRO receivers.
|
Models: OPTIMA, MINIMA and MICRO receivers.
|
||||||
|
|
||||||
@@ -356,20 +413,40 @@ CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
|
|||||||
### Sub_protocol OPT_FW - *0*
|
### Sub_protocol OPT_FW - *0*
|
||||||
OPTIMA RXs
|
OPTIMA RXs
|
||||||
|
|
||||||
Full telemetry available on ersky9x and OpenTX. This is still a WIP.
|
Full telemetry available on OpenTX 2.3.3+, still in progress for erskyTx. Lowest the TX_LQI value is best the quality link is, it's a good indicator of how well the module is tuned.
|
||||||
|
|
||||||
**The TX must be close to the RX for the bind negotiation to complete successfully**
|
**The TX must be close to the RX for the bind negotiation to complete successfully**
|
||||||
|
|
||||||
### Sub_protocol OPT_HUB - *1*
|
### Sub_protocol OPT_HUB - *1*
|
||||||
OPTIMA RXs
|
OPTIMA RXs
|
||||||
|
|
||||||
Basic telemetry using FrSky Hub on er9x, ersky9x, OpenTX and any radio with FrSky telemetry support with RX voltage, VOLT2 voltage, TX RSSI and TX LQI.
|
Basic telemetry using FrSky Hub on er9x, erskyTX, OpenTX and any radio with FrSky telemetry support with RX voltage, VOLT2 voltage, TX_RSSI and TX_LQI. Lowest the TX_LQI value is best the quality link is, it's a good indicator of how well the module is tuned.
|
||||||
|
|
||||||
**The TX must be close to the RX for the bind negotiation to complete successfully**
|
**The TX must be close to the RX for the bind negotiation to complete successfully**
|
||||||
|
|
||||||
### Sub_protocol MINIMA - *2*
|
### Sub_protocol MINIMA - *2*
|
||||||
MINIMA, MICRO and RED receivers
|
MINIMA, MICRO and RED receivers
|
||||||
|
|
||||||
|
## HoTT - *57*
|
||||||
|
Models: Graupner HoTT receivers (tested on GR-12L and GR-16L).
|
||||||
|
|
||||||
|
Extended limits and failsafe supported
|
||||||
|
|
||||||
|
**RX_Num is used to give a number a given RX. You must use a different RX_Num per RX. A maximum of 64 HoTT RXs are supported.**
|
||||||
|
|
||||||
|
**Failsafe MUST be configured once with the desired channel values (hold or position) while the RX is up (wait 10+sec for the RX to learn the config) and then failsafe MUST be set to RX/Receiver otherwise the servos will jitter!!!**
|
||||||
|
|
||||||
|
The RX features configuration are done using the OpenTX script "Graupner HoTT.lua" .
|
||||||
|
|
||||||
|
Option for this protocol corresponds to fine frequency tuning. This value is different for each Module and **must** be accurate otherwise the link will not be stable.
|
||||||
|
Check the [Frequency Tuning page](/docs/Frequency_Tuning.md) to determine it.
|
||||||
|
|
||||||
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12
|
||||||
|
---|---|---|---|---|---|---|---|---|----|----|----
|
||||||
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12
|
||||||
|
|
||||||
|
Basic telemetry is available on OpenTX 2.3.3+ with RX voltage, Rx temperature, RX RSSI, RX LQI, TX RSSI and TX LQI. Lowest the TX_LQI value is best the quality link is, it's a good indicator of how well the module is tuned.
|
||||||
|
|
||||||
## SFHSS - *21*
|
## SFHSS - *21*
|
||||||
Models: Futaba RXs and XK models.
|
Models: Futaba RXs and XK models.
|
||||||
|
|
||||||
@@ -507,10 +584,10 @@ A|E|T|R|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|----|TH_KILL
|
|||||||
|
|
||||||
Notes:
|
Notes:
|
||||||
- model/type/number of channels indicated on the RX can be different from what the RX is in fact wanting to see. So don't hesitate to test different combinations until you have something working. Using Auto is the best way to find these settings.
|
- model/type/number of channels indicated on the RX can be different from what the RX is in fact wanting to see. So don't hesitate to test different combinations until you have something working. Using Auto is the best way to find these settings.
|
||||||
- RX output will match the Spektrum standard TAER independently of the input configuration AETR, RETA...
|
- RX output will match the Spektrum standard TAER independently of the input configuration AETR, RETA... unless on OpenTX 2.3.3+ you use the "Disable channel mapping" feature on the GUI.
|
||||||
- RX output will match the Spektrum standard throw (1500µs +/- 400µs -> 1100..1900µs) for a 100% input. This is true for both Serial and PPM input. For PPM, make sure the end points PPM_MIN_100 and PPM_MAX_100 in _config.h are matching your TX ouput. The maximum ouput is 1000..2000µs based on an input of 125%.
|
- RX output will match the Spektrum standard throw (1500µs +/- 400µs -> 1100..1900µs) for a 100% input. This is true for both Serial and PPM input. For PPM, make sure the end points PPM_MIN_100 and PPM_MAX_100 in _config.h are matching your TX ouput. The maximum ouput is 1000..2000µs based on an input of 125%.
|
||||||
- If you want to override the above and get maximum throw (old way) uncomment in _config.h the line #define DSM_MAX_THROW . In this mode to achieve standard throw use a channel weight of 84%.
|
- If you want to override the above and get maximum throw either uncomment in _config.h the line #define DSM_MAX_THROW or on OpenTX 2.3.3+ use the "Enable max throw" feature on the GUI (0=No,1=Yes). In this mode to achieve standard throw use a channel weight of 84%.
|
||||||
- TH_KILL is a feature which is enabled on channel 14 by default (can be disabled/changed) in the _config.h file. Some models (X-Vert, Blade 230S...) require a special position to instant stop the motor(s). If the channel 15 is above -50% the throttle is untouched but if it is between -50% and -100%, the throttle output will be forced between -100% and -150%. For example, a value of -80% applied on channel 14 will instantly kill the motors on the X-Vert.
|
- TH_KILL is a feature which is enabled on channel 14 by default (can be disabled/changed) in the _config.h file. Some models (X-Vert, Blade 230S...) require a special position to instant stop the motor(s). If the channel 14 is above -50% the throttle is untouched but if it is between -50% and -100%, the throttle output will be forced between -100% and -150%. For example, a value of -80% applied on channel 14 will instantly kill the motors on the X-Vert.
|
||||||
|
|
||||||
### Sub_protocol DSM2_22 - *0*
|
### Sub_protocol DSM2_22 - *0*
|
||||||
DSM2, Resolution 1024, refresh rate 22ms
|
DSM2, Resolution 1024, refresh rate 22ms
|
||||||
@@ -523,9 +600,9 @@ DSMX, Resolution 2048, refresh rate 11ms
|
|||||||
### Sub_protocol AUTO - *4*
|
### Sub_protocol AUTO - *4*
|
||||||
The "AUTO" feature enables the TX to automatically choose what are the best settings for your DSM RX and update your model protocol settings accordingly.
|
The "AUTO" feature enables the TX to automatically choose what are the best settings for your DSM RX and update your model protocol settings accordingly.
|
||||||
|
|
||||||
The current radio firmware which are able to use the "AUTO" feature are ersky9x (9XR Pro, 9Xtreme, Taranis, ...), er9x for M128(9XR)&M2561 and OpenTX (mostly Taranis).
|
The current radio firmware which are able to use the "AUTO" feature are erskyTX (9XR Pro, 9Xtreme, Taranis, ...), er9x for M128(9XR)&M2561 and OpenTX (mostly Taranis).
|
||||||
For these firmwares, you must have a telemetry enabled TX and you have to make sure you set the Telemetry "Usr proto" to "DSMx".
|
For these firmwares, you must have a telemetry enabled TX and you have to make sure you set the Telemetry "Usr proto" to "DSMx".
|
||||||
Also on er9x you will need to be sure to match the polarity of the telemetry serial (normal or inverted by bitbashing), while on ersky9x you can set "Invert COM1" accordinlgy.
|
Also on er9x you will need to be sure to match the polarity of the telemetry serial (normal or inverted by bitbashing), while on erskyTX you can set "Invert COM1" accordinlgy.
|
||||||
|
|
||||||
## J6Pro - *22*
|
## J6Pro - *22*
|
||||||
|
|
||||||
@@ -613,6 +690,17 @@ CH12|CH13
|
|||||||
----|----
|
----|----
|
||||||
TAKE_OFF|EMG_STOP
|
TAKE_OFF|EMG_STOP
|
||||||
|
|
||||||
|
## BAYANG RX - *59*
|
||||||
|
The Bayang receiver protocol enables master/slave trainning, separate access from 2 different radios to the same model,...
|
||||||
|
|
||||||
|
See the [BAYANG protocol](Protocols_Details.md#BAYANG---14) on how to activate ANAUX1 and ANAUX2 (Option/Telemetry=2).
|
||||||
|
|
||||||
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10
|
||||||
|
---|---|---|---|---|---|---|---|---|---
|
||||||
|
A|E|T|R|ANAUX1|ANAUX2|FLIP|RTH|PICTURE|VIDEO
|
||||||
|
|
||||||
|
Available in OpenTX 2.3.3, Trainer Mode Master/Multi
|
||||||
|
|
||||||
## BUGSMINI - *42*
|
## BUGSMINI - *42*
|
||||||
Models: MJX Bugs 3 Mini and 3H
|
Models: MJX Bugs 3 Mini and 3H
|
||||||
|
|
||||||
@@ -763,10 +851,22 @@ CH1|CH2|CH3|CH4|CH5|CH6
|
|||||||
---|---|---|---|---|---
|
---|---|---|---|---|---
|
||||||
A|E|T|R|GYRO|PITCH
|
A|E|T|R|GYRO|PITCH
|
||||||
|
|
||||||
|
### Sub_protocol Std - *0*
|
||||||
|
|
||||||
|
### Sub_protocol ET4 - *1*
|
||||||
|
Models compatible with the ET4 transmitter like ESky Big Lama
|
||||||
|
**Multiple IDs but only one frequency...**
|
||||||
|
|
||||||
## ESKY150 - *35*
|
## ESKY150 - *35*
|
||||||
ESky protocol for small models since 2014 (150, 300, 150X, ...)
|
ESky protocol for small models since 2014 (150, 300, 150X, ...)
|
||||||
|
|
||||||
Number of channels are set with option. option=0 4 channels and option=1 7 channels. An invalid option value will end up with 4 channels.
|
### Sub_protocol 4CH - *0*
|
||||||
|
|
||||||
|
CH1|CH2|CH3|CH4
|
||||||
|
---|---|---|---
|
||||||
|
A|E|T|R
|
||||||
|
|
||||||
|
### Sub_protocol 7CH - *1*
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7
|
||||||
---|---|---|---|---|---|---
|
---|---|---|---|---|---|---
|
||||||
@@ -774,12 +874,27 @@ A|E|T|R|FMODE|AUX6|AUX7
|
|||||||
|
|
||||||
FMODE and AUX7 have 4 positions: -100%..-50%=>0, -50%..5%=>1, 5%..50%=>2, 50%..100%=>3
|
FMODE and AUX7 have 4 positions: -100%..-50%=>0, -50%..5%=>1, 5%..50%=>2, 50%..100%=>3
|
||||||
|
|
||||||
|
## FX816 - *58*
|
||||||
|
Model: FEI XIONG FX816 P38
|
||||||
|
|
||||||
|
Only 8 TX IDs available
|
||||||
|
|
||||||
|
CH1|CH2|CH3|CH4
|
||||||
|
---|---|---|---
|
||||||
|
A|-|T|-
|
||||||
|
|
||||||
## FY326 - *20*
|
## FY326 - *20*
|
||||||
|
|
||||||
|
### Sub_protocol FY326 - *0*
|
||||||
|
Model: FY326 Q7 Quadcopter
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
|
||||||
---|---|---|---|---|---|---|---|---
|
---|---|---|---|---|---|---|---|---
|
||||||
A|E|T|R|FLIP|RTH|HEADLESS|EXPERT|CALIBRATE
|
A|E|T|R|FLIP|RTH|HEADLESS|EXPERT|CALIBRATE
|
||||||
|
|
||||||
|
### Sub_protocol FY319 - *1*
|
||||||
|
Model: X6 FY319 Quadcopter (Needs Testing)
|
||||||
|
|
||||||
## FQ777 - *23*
|
## FQ777 - *23*
|
||||||
Model: FQ777-124 (with SV7241A)
|
Model: FQ777-124 (with SV7241A)
|
||||||
|
|
||||||
@@ -790,9 +905,9 @@ A|E|T|R|FLIP|RTH|HEADLESS|EXPERT
|
|||||||
## GD00X - *47*
|
## GD00X - *47*
|
||||||
Model: GD005 C-17 Transport, GD006 DA62 and ZC-Z50
|
Model: GD005 C-17 Transport, GD006 DA62 and ZC-Z50
|
||||||
|
|
||||||
If the model does not respond well to inputs or hard to bind, you can try to set Power to Low. But this protocol is known to be problematic because it's using the xn297L emulation with a transmission speed of 250kbps therefore it doesn't work very well with every modules, this is an hardware issue with the accuracy of the components used and nothing we can do about it in the firmware.
|
This protocol is known to be problematic because it's using the xn297L emulation with a transmission speed of 250kbps therefore it doesn't work very well with every modules, this is an hardware issue with the accuracy of the components.
|
||||||
|
|
||||||
If a CC2500 rf component is available it will be used in place of the NRF24L01 which might fix the issue mentioned above. Option is used for fine frequency tuning like any CC2500 protocols. Check the [Frequency Tuning page](/docs/Frequency_Tuning.md) to determine it if necessary.
|
If the model does not respond well to inputs or hard to bind, you can try to switch the emulation from the default NRF24L01 RF component to the CC2500 by using an option value (freq tuning) different from 0. Option in this case is used for fine frequency tuning like any CC2500 protocols so check the [Frequency Tuning page](/docs/Frequency_Tuning.md).
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7
|
||||||
---|---|---|---|---|---|---
|
---|---|---|---|---|---|---
|
||||||
@@ -893,9 +1008,9 @@ ARM|
|
|||||||
## KF606 - *49*
|
## KF606 - *49*
|
||||||
Model: KF606
|
Model: KF606
|
||||||
|
|
||||||
If the model does not respond well to inputs or hard to bind, you can try to set Power to Low. But this protocol is known to be problematic because it's using the xn297L emulation with a transmission speed of 250kbps therefore it doesn't work very well with every modules, this is an hardware issue with the accuracy of the components used and nothing we can do about it in the firmware.
|
This protocol is known to be problematic because it's using the xn297L emulation with a transmission speed of 250kbps therefore it doesn't work very well with every modules, this is an hardware issue with the accuracy of the components.
|
||||||
|
|
||||||
If a CC2500 rf component is available it will be used in place of the NRF24L01 which might fix the issue mentioned above. Option is used for fine frequency tuning like any CC2500 protocols. Check the [Frequency Tuning page](/docs/Frequency_Tuning.md) to determine it if necessary.
|
If the model does not respond well to inputs or hard to bind, you can try to switch the emulation from the default NRF24L01 RF component to the CC2500 by using an option value (freq tuning) different from 0. Option in this case is used for fine frequency tuning like any CC2500 protocols so check the [Frequency Tuning page](/docs/Frequency_Tuning.md).
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4|CH5
|
CH1|CH2|CH3|CH4|CH5
|
||||||
---|---|---|---|---
|
---|---|---|---|---
|
||||||
@@ -920,9 +1035,9 @@ Only 3 TX IDs available, change RX_Num value 0..2 to cycle through them
|
|||||||
### Sub_protocol E010 - *4*
|
### Sub_protocol E010 - *4*
|
||||||
15 TX IDs available, change RX_Num value 0..14 to cycle through them
|
15 TX IDs available, change RX_Num value 0..14 to cycle through them
|
||||||
|
|
||||||
If the model does not respond well to inputs or hard to bind, you can try to set Power to Low. But this protocol is known to be problematic because it's using the xn297L emulation with a transmission speed of 250kbps therefore it doesn't work very well with every modules, this is an hardware issue with the accuracy of the components used and nothing we can do about it in the firmware.
|
This protocol is known to be problematic because it's using the xn297L emulation with a transmission speed of 250kbps therefore it doesn't work very well with every modules, this is an hardware issue with the accuracy of the components.
|
||||||
|
|
||||||
If a CC2500 rf component is available it will be used in place of the NRF24L01 which might fix the issue mentioned above. Option is used for fine frequency tuning like any CC2500 protocols. Check the [Frequency Tuning page](/docs/Frequency_Tuning.md) to determine it if necessary.
|
If the model does not respond well to inputs or hard to bind, you can try to switch the emulation from the default NRF24L01 RF component to the CC2500 by using an option value (freq tuning) different from 0. Option in this case is used for fine frequency tuning like any CC2500 protocols so check the [Frequency Tuning page](/docs/Frequency_Tuning.md).
|
||||||
|
|
||||||
### Sub_protocol H26WH - *5*
|
### Sub_protocol H26WH - *5*
|
||||||
CH6|
|
CH6|
|
||||||
@@ -952,7 +1067,9 @@ Model: Yi Zhan i6S
|
|||||||
|
|
||||||
Only one model can be flown at the same time since the ID is hardcoded.
|
Only one model can be flown at the same time since the ID is hardcoded.
|
||||||
|
|
||||||
If the model does not respond well to inputs or hard to bind, you can try to set Power to Low. But this protocol is known to be problematic because it's using the xn297L emulation with a transmission speed of 250kbps therefore it doesn't work very well with every modules, this is an hardware issue with the accuracy of the components used and nothing we can do about it in the firmware.
|
This protocol is known to be problematic because it's using the xn297L emulation with a transmission speed of 250kbps therefore it doesn't work very well with every modules, this is an hardware issue with the accuracy of the components.
|
||||||
|
|
||||||
|
If the model does not respond well to inputs or hard to bind, you can try to switch the emulation from the default NRF24L01 RF component to the CC2500 by using an option value (freq tuning) different from 0. Option in this case is used for fine frequency tuning like any CC2500 protocols so check the [Frequency Tuning page](/docs/Frequency_Tuning.md).
|
||||||
|
|
||||||
### Sub_protocol LS - *3*
|
### Sub_protocol LS - *3*
|
||||||
Models: LS114, 124, 215
|
Models: LS114, 124, 215
|
||||||
@@ -1022,7 +1139,10 @@ CH1|CH2|CH3|CH4
|
|||||||
A|E|T|R
|
A|E|T|R
|
||||||
|
|
||||||
### Sub_protocol Q303 - *0*
|
### Sub_protocol Q303 - *0*
|
||||||
If the model does not respond well to inputs or hard to bind, you can try to set Power to Low. But this protocol is known to be problematic because it's using the xn297L emulation with a transmission speed of 250kbps therefore it doesn't work very well with every modules, this is an hardware issue with the accuracy of the components used and nothing we can do about it in the firmware.
|
|
||||||
|
This protocol is known to be problematic because it's using the xn297L emulation with a transmission speed of 250kbps therefore it doesn't work very well with every modules, this is an hardware issue with the accuracy of the components.
|
||||||
|
|
||||||
|
If the model does not respond well to inputs or hard to bind, you can try to switch the emulation from the default NRF24L01 RF component to the CC2500 by using an option value (freq tuning) different from 0. Option in this case is used for fine frequency tuning like any CC2500 protocols so check the [Frequency Tuning page](/docs/Frequency_Tuning.md).
|
||||||
|
|
||||||
CH5|CH6|CH7|CH8|CH9|CH10|CH11
|
CH5|CH6|CH7|CH8|CH9|CH10|CH11
|
||||||
---|---|---|---|---|---|---
|
---|---|---|---|---|---|---
|
||||||
@@ -1171,6 +1291,15 @@ CH10|CH11|CH12
|
|||||||
---|---|---
|
---|---|---
|
||||||
Start/Stop|EMERGENCY|CAMERA_UP/DN
|
Start/Stop|EMERGENCY|CAMERA_UP/DN
|
||||||
|
|
||||||
|
## Tiger - *61*
|
||||||
|
Autobind protocol
|
||||||
|
|
||||||
|
**Only 1 ID**
|
||||||
|
|
||||||
|
CH1|CH2|CH3|CH4|CH5|CH6
|
||||||
|
---|---|---|---|---|---
|
||||||
|
A|E|T|R|FLIP|LIGHT
|
||||||
|
|
||||||
## V761 - *48*
|
## V761 - *48*
|
||||||
Model: Volantex V761 and may be other
|
Model: Volantex V761 and may be other
|
||||||
|
|
||||||
@@ -1183,16 +1312,20 @@ CH1|CH2|CH3|CH4|CH5
|
|||||||
Gyro: -100%=Beginer mode (Gyro on, yaw and pitch rate limited), 0%=Mid Mode ( Gyro on no rate limits), +100%=Mode Expert Gyro off
|
Gyro: -100%=Beginer mode (Gyro on, yaw and pitch rate limited), 0%=Mid Mode ( Gyro on no rate limits), +100%=Mode Expert Gyro off
|
||||||
|
|
||||||
## V911S - *46*
|
## V911S - *46*
|
||||||
Models: WLtoys V911S, XK A110
|
This protocol is known to be problematic because it's using the xn297L emulation with a transmission speed of 250kbps therefore it doesn't work very well with every modules, this is an hardware issue with the accuracy of the components.
|
||||||
|
|
||||||
If the model does not respond well to inputs or hard to bind, you can try to set Power to Low. But this protocol is known to be problematic because it's using the xn297L emulation with a transmission speed of 250kbps therefore it doesn't work very well with every modules, this is an hardware issue with the accuracy of the components used and nothing we can do about it in the firmware.
|
If the model does not respond well to inputs or hard to bind, you can try to switch the emulation from the default NRF24L01 RF component to the CC2500 by using an option value (freq tuning) different from 0. Option in this case is used for fine frequency tuning like any CC2500 protocols so check the [Frequency Tuning page](/docs/Frequency_Tuning.md).
|
||||||
|
|
||||||
If a CC2500 rf component is available it will be used in place of the NRF24L01 which might fix the issue mentioned above. Option is used for fine frequency tuning like any CC2500 protocols. Check the [Frequency Tuning page](/docs/Frequency_Tuning.md) to determine it if necessary.
|
|
||||||
|
|
||||||
CH1|CH2|CH3|CH4|CH5
|
CH1|CH2|CH3|CH4|CH5
|
||||||
---|---|---|---|---
|
---|---|---|---|---
|
||||||
A|E|T|R|CALIB
|
A|E|T|R|CALIB
|
||||||
|
|
||||||
|
### Sub_protocol V911S - *0*
|
||||||
|
Models: WLtoys V911S, XK A110
|
||||||
|
|
||||||
|
### Sub_protocol E119 - *1*
|
||||||
|
Models: Eachine E119
|
||||||
|
|
||||||
## YD717 - *8*
|
## YD717 - *8*
|
||||||
Autobind protocol
|
Autobind protocol
|
||||||
|
|
||||||
@@ -1216,7 +1349,41 @@ CH1|CH2|CH3|CH4|CH5
|
|||||||
---|---|---|---|---
|
---|---|---|---|---
|
||||||
||T|R|LIGHT
|
||T|R|LIGHT
|
||||||
|
|
||||||
|
# SX1276 RF Module
|
||||||
|
|
||||||
|
## FRSKYR9 - *65*
|
||||||
|
Extended limits supported
|
||||||
|
|
||||||
|
### Sub_protocol R9_915 - *0*
|
||||||
|
915MHz, 16 channels
|
||||||
|
|
||||||
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13|CH14|CH15|CH16
|
||||||
|
---|---|---|---|---|---|---|---|---|----|----|----|----|----|----|----
|
||||||
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13|CH14|CH15|CH16
|
||||||
|
|
||||||
|
### Sub_protocol R9_868 - *1*
|
||||||
|
868MHz, 16 channels
|
||||||
|
|
||||||
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13|CH14|CH15|CH16
|
||||||
|
---|---|---|---|---|---|---|---|---|----|----|----|----|----|----|----
|
||||||
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13|CH14|CH15|CH16
|
||||||
|
|
||||||
|
### Sub_protocol R9_915_8CH - *2*
|
||||||
|
915MHz, 8 channels
|
||||||
|
|
||||||
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
||||||
|
---|---|---|---|---|---|---|---
|
||||||
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
||||||
|
|
||||||
|
### Sub_protocol R9_868_8CH - *3*
|
||||||
|
868MHz, 8 channels
|
||||||
|
|
||||||
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
||||||
|
---|---|---|---|---|---|---|---
|
||||||
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
||||||
|
|
||||||
# OpenLRS module
|
# OpenLRS module
|
||||||
|
|
||||||
## OpenLRS - *27*
|
## OpenLRS - *27*
|
||||||
This is a reservation for OpenLRSng which is using Multi's serial protocol for their modules: https://openlrsng.org/. On the Multi side there is no protocol affected on 27 so it's just ignored.
|
This is a reservation for OpenLRSng which is using Multi's serial protocol for their modules: https://openlrsng.org/. On the Multi side there is no protocol affected on 27 so it's just ignored.
|
||||||
|
|
||||||
|
|||||||
@@ -19,9 +19,9 @@ If you like this project and want to support further development please consider
|
|||||||
|
|
||||||
## Development status
|
## Development status
|
||||||
|
|
||||||
Current Multiprotocol code check status: [](https://travis-ci.org/pascallanger/DIY-Multiprotocol-TX-Module)
|
Current Multiprotocol code check status: [](https://travis-ci.org/pascallanger/DIY-Multiprotocol-TX-Module)
|
||||||
|
|
||||||
Current Multiprotocol boards check status: [](https://travis-ci.org/pascallanger/DIY-Multiprotocol-TX-Module-Boards)
|
Current Multiprotocol boards check status: [](https://travis-ci.org/pascallanger/DIY-Multiprotocol-TX-Module-Boards)
|
||||||
|
|
||||||
|
|
||||||
## Quicklinks
|
## Quicklinks
|
||||||
@@ -40,6 +40,7 @@ Current Multiprotocol boards check status: [
|
* [STM32 Multiprotocol Module](docs/Compiling_STM32.md)
|
||||||
* [OrangeRX Module](docs/Compiling_OrangeTx.md)
|
* [OrangeRX Module](docs/Compiling_OrangeTx.md)
|
||||||
1. [Transmitter Setup](docs/Transmitters.md)
|
1. [Transmitter Setup](docs/Transmitters.md)
|
||||||
|
* [Channel Order](docs/Channel_Order.md)
|
||||||
1. [How to for popular models](docs/Models.md)
|
1. [How to for popular models](docs/Models.md)
|
||||||
1. [Troubleshooting](docs/Troubleshooting.md)
|
1. [Troubleshooting](docs/Troubleshooting.md)
|
||||||
2. [Advanced Topics (not for the fainthearted!)](docs/Advanced_Topics.md)
|
2. [Advanced Topics (not for the fainthearted!)](docs/Advanced_Topics.md)
|
||||||
|
|||||||
5
buildroot/bin/opt_replace
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
SED=$(which gsed || which sed)
|
||||||
|
|
||||||
|
eval "${SED} -i 's/#define \b${1}\b$/#define ${2}/g' Multiprotocol/_Config.h"
|
||||||
@@ -2,20 +2,18 @@
|
|||||||
|
|
||||||
To enable serial debug on your module you must know how to buid the firmware from the source code available on this GitHub. To do so follow this page: [Compiling and programming the STM32 module](Compiling_STM32.md).
|
To enable serial debug on your module you must know how to buid the firmware from the source code available on this GitHub. To do so follow this page: [Compiling and programming the STM32 module](Compiling_STM32.md).
|
||||||
|
|
||||||
Procedure to use serial debug:
|
Procedure:
|
||||||
1. Edit the file [Multiprotocol.ino](../Multiprotocol/Multiprotocol.ino#L26)
|
1. Upload the debug firmware to the module:
|
||||||
1. Modify at the begining of the file the line: `//#define DEBUG_SERIAL` by removing the // leaving only: `#define DEBUG_SERIAL`
|
<img src="images/Debug1.png" />
|
||||||
1. Save the file
|
|
||||||
1. Upload the firmware to the module:
|
|
||||||
|
|
||||||
iRangeX+, Banggood and old Jumper 4in1 modules|Recent Jumper 4in1 modules with built-in CP2102|FTDI
|
iRangeX+, Banggood and old Jumper 4in1 modules|Recent Jumper 4in1 modules with built-in CP2102|FTDI
|
||||||
----------------------------------------------|-----------------------------------------------|----
|
----------------------------------------------|-----------------------------------------------|----
|
||||||
Use the Upload method:"Upload via USB"|Use the Upload method: "Upload via Serial (FTDI)|Use the Upload method: "Upload via Serial (FTDI)
|
Use the Debug Option: "Native USB Debugging"|Use the Debug Option: "Serial/FTDI Debugging"|Use the Debug Option: "Serial/FTDI Debugging"
|
||||||
Do not disconnect the USB cable. In case you have to do it, you have to connect the module, close and reopen the Serial Monitor to get the module working otherwise it will be stuck with the status LED off.|Do not disconnect the USB cable. In case you have to do it, you have to power first the TX and then connect the USB cable to the module and relaunch the Serial monitor.|No restrictions apart from relaunching the Serial monitor if you disconnect the FTDI from the PC
|
Do not disconnect the USB cable. In case you have to do it, you have to connect the module, close and reopen the Serial Monitor to get the module working otherwise the status LED will do a [Fast double blink](Troubleshooting.md).|Do not disconnect the USB cable. In case you have to do it, you have to power the TX first, then connect the USB cable to the module and relaunch the Serial monitor.|No restrictions apart from relaunching the Serial monitor if you disconnect the FTDI from the PC.
|
||||||
|
|
||||||
5. Power on the TX
|
2. Power on the TX
|
||||||
1. Open in the Arduino IDE the Serial Monitor: Tools->Serial Monitor or Ctrl+Shift+M<br> <img src="images/Serial_Monitor_1.png" />
|
1. Open in the Arduino IDE the Serial Monitor: Tools->Serial Monitor or Ctrl+Shift+M<br> <img src="images/Serial_Monitor_1.png" />
|
||||||
1. Make sure the settings at the bottom of the Serial Monitor window are the same as the picture above especially the baud rate set to 115200 baud
|
1. Make sure the settings at the bottom of the Serial Monitor window are the same as the picture above especially the baud rate set to 115200 baud
|
||||||
1. The Serial Monitor window should show the module booting, selection of a different protocol and more depending on the protocol currently loaded<br> <img src="images/Serial_Monitor_2.png" />
|
1. The Serial Monitor window should show the module booting, selection of a different protocol and more depending on the protocol currently loaded<br> <img src="images/Serial_Monitor_2.png" />
|
||||||
1. At this stage you can test whatever is needed or have been instructed to do. You can easily select text in the window to copy and paste it on the forum or in a text file.
|
1. At this stage you can test whatever is needed or have been instructed to do. You can easily select text in the window to copy and paste it on the forum or in a text file.
|
||||||
1. **Important: to use your module normally and before flying you must reupload the firmware as you usually do with the debug line commented: `//#define DEBUG_SERIAL` **
|
1. **Important: to use your module normally and before flying you must reupload the firmware as you usually do with the Debug Option set to "None"**
|
||||||
|
|||||||
@@ -22,14 +22,14 @@ Qty|Part|Description|Value|Package|Digikey Part Number
|
|||||||
1|U4 U6|Pin header|1x10||[S1011EC-40-ND](https://www.digikey.com/product-detail/en/sullins-connector-solutions/PRPC040SAAN-RC/S1011EC-40-ND/2775214)
|
1|U4 U6|Pin header|1x10||[S1011EC-40-ND](https://www.digikey.com/product-detail/en/sullins-connector-solutions/PRPC040SAAN-RC/S1011EC-40-ND/2775214)
|
||||||
1|P1|ISP|2x3||[3M9459-ND](http://www.digikey.com/product-search/en?keywords=3M%20961206-6404-AR)
|
1|P1|ISP|2x3||[3M9459-ND](http://www.digikey.com/product-search/en?keywords=3M%20961206-6404-AR)
|
||||||
1|P2|Receptacle|5-pin||[WM14512-ND](http://www.digikey.com/product-search/en?keywords=Molex%2C%20LLC%200022142054)
|
1|P2|Receptacle|5-pin||[WM14512-ND](http://www.digikey.com/product-search/en?keywords=Molex%2C%20LLC%200022142054)
|
||||||
2|R4 R6|Resistor|1K|0603|[P1.0KGCT-ND](http://www.digikey.com/product-search/en?keywords=P1.0KGCT-ND)
|
1|R1|Resistor|10k|0603|[P10KGCT-ND](http://www.digikey.com/product-search/en?keywords=P10KGCT-ND)
|
||||||
1|R2|Resistor|2.2K|0603|[P2.2KGCT-ND](http://www.digikey.com/product-search/en?keywords=P2.2KGCT-ND)
|
2|R2 R5 R7|Resistor|2.2K|0603|[P2.2KGCT-ND](http://www.digikey.com/product-search/en?keywords=P2.2KGCT-ND)
|
||||||
2|R1 R3|Resistor|10k|0603|[P10KGCT-ND](http://www.digikey.com/product-search/en?keywords=P10KGCT-ND)
|
2|R3 R4 R6|Resistor|1K|0603|[P1.0KGCT-ND](http://www.digikey.com/product-search/en?keywords=P1.0KGCT-ND)
|
||||||
1|R5|Resistor|20K|0603|[P20KGCT-ND](http://www.digikey.com/product-search/en?keywords=P20KGCT-ND)
|
1|R8|Resistor|470|0603|[P470GCT-ND](https://www.digikey.com/products/en?keywords=P470GCT-ND)
|
||||||
1|SW1|Hex Switch||4-DIP|[FR01KR16P-W-S-ND](https://www.digikey.com/product-detail/en/nkk-switches/FR01KR16P-W-S/FR01KR16P-W-S-ND/2104098)
|
1|SW1|Hex Switch||4-DIP|[FR01KR16P-W-S-ND](https://www.digikey.com/product-detail/en/nkk-switches/FR01KR16P-W-S/FR01KR16P-W-S-ND/2104098)
|
||||||
1|Sw2|Momentary Switch||6mm|[ 450-1643-ND](https://www.digikey.com/product-detail/en/te-connectivity-alcoswitch-switches/2-1825910-7/450-1642-ND/1632528)
|
1|Sw2|Momentary Switch||6mm|[ 450-1643-ND](https://www.digikey.com/product-detail/en/te-connectivity-alcoswitch-switches/2-1825910-7/450-1642-ND/1632528)
|
||||||
1|SW3|Momentary Switch||6mm|[CKN9104CT-ND](http://www.digikey.com/product-search/en?keywords=CKN9104CT-ND)
|
1|SW3|Momentary Switch||6mm|[CKN9104CT-ND](http://www.digikey.com/product-search/en?keywords=CKN9104CT-ND)
|
||||||
1|U1|Voltage reg 5V|AMS1117-50|SOT223|[LM1117MP-5.0/NOPBCT-ND](https://www.digikey.com/product-detail/en/texas-instruments/LM1117MP-5.0-NOPB/LM1117MP-5.0-NOPBCT-ND/363589)
|
1|U1|Voltage reg 5V|AMS1117-50|SOT223|[LM1117MP-5.0/NOPBCT-ND](https://www.digikey.com/product-detail/en/texas-instruments/LM1117MP-5.0-NOPB/LM1117MP-5.0-NOPBCT-ND/363589)
|
||||||
1|U2|Voltage reg 3.3V|AMS1117-33|SOT223|[LM1117MPX-3.3/NOPBCT-ND](https://www.digikey.com/product-detail/en/texas-instruments/LM1117MPX-3.3-NOPB/LM1117MPX-3.3-NOPBCT-ND/1010516)
|
1|U2|Voltage reg 3.3V|AMS1117-33|SOT223|[LM1117MPX-3.3/NOPBCT-ND](https://www.digikey.com/product-detail/en/texas-instruments/LM1117MPX-3.3-NOPB/LM1117MPX-3.3-NOPBCT-ND/1010516)
|
||||||
1|X1|8 MHz Crystal|8MHz||[535-10267-1-ND](http://www.digikey.com/product-search/en?keywords=535-10267-1-ND)
|
1|X1|16 MHz Crystal|16MHz||[535-10267-1-ND](http://www.digikey.com/product-search/en?keywords=535-10267-1-ND)
|
||||||
1||2.4GHz Antenna|||[553-1309-ND](http://www.digikey.com/product-search/en?keywords=553-1309-ND)
|
1||2.4GHz Antenna|||[553-1309-ND](http://www.digikey.com/product-search/en?keywords=553-1309-ND)
|
||||||
|
|||||||
91
docs/Channel_Order.md
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
# Channel Order
|
||||||
|
|
||||||
|
Channel ordering is extremely important to the Multiprotocol Module. It is vital that the module receives channel data from the radio in the order which it expects so that it can reorder the data sent over the air into the order which the receiver requires/expects.
|
||||||
|
|
||||||
|
## Background
|
||||||
|
The Multiprotocol Module supports dozens of different protocols, many of which require channel data to be sent in a specific order (especially ones for models with integrated receiver/flight controllers).
|
||||||
|
|
||||||
|
The Multiprotocol Module was designed to:
|
||||||
|
* Enable users to control many different models or receivers using a single transmitter system
|
||||||
|
* Work with radios where the input channels could not be reassigned
|
||||||
|
* Make it simple to configure models without having to think about the channel order they require
|
||||||
|
|
||||||
|
To address these considerations the Multiprotocol Module will internally reorder the radio's output channels to the order required by the selected protocol before transmitting the data to the receiver.
|
||||||
|
|
||||||
|
The Multiprotocol Module also has functionality which depends on knowing which input channel is the throttle:
|
||||||
|
* 'Bind on Channel' requires the throttle to be at -100% before the bind can be initiated (so that bind cannot be initiated while flying)
|
||||||
|
* 'Throttle Kill' needs to know which channel to apply the throttle reduction to
|
||||||
|
|
||||||
|
**So, the Multiprotocol Module must know what order the channel data from the radio is in. However, because the radio does not tell the module which input is assigned to each channel, the order is fixed in the Multiprotocol Module's firmware. This is the _expected channel order_.**
|
||||||
|
|
||||||
|
## Expected Channel Order
|
||||||
|
The expected channel order is the order in which the Multiprotocol Module expects to receive channel data from the radio. It associates the four primary radio inputs (aileron, elevator,throttle, and rudder) to the four output channels CH1, CH2, CH3, and CH4. In AETR, **A**ileron is on CH1, **E**levator is on CH2, **T**hrottle is on CH3, and **R**udder is on CH4.
|
||||||
|
|
||||||
|
**The default expected channel order is AETR.**
|
||||||
|
|
||||||
|
The Multiprotocol Module uses the expected channel order to reorder channels into the order required by the selected protocol, and to apply channel-specific features such as 'Throttle Kill'.
|
||||||
|
|
||||||
|
If you are using firmware which has an expected channel order of AETR (the default), and you are using a protocol which has a fixed channel order†, you must create your radio models with a channel order of AETR, regardless of the channel order the receiver requires. **The Multiprotocol Module will do the conversion from AETR to the required order for you.**
|
||||||
|
|
||||||
|
For example, Spektrum / DSM receivers expect **TAER**. When you configure the model in the radio you set it up in **AETR** order, the Multiprotocol Module reorders the channels before transmission, the receiver receives **TAER**, everything works as expected:
|
||||||
|
|
||||||
|
Radio CH | Radio Input/Output | Module Reordering | Receiver Receives |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| 1 | Ail | 3 -> 1 | Thr |
|
||||||
|
| 2 | Ele | 1 -> 2 | Ail |
|
||||||
|
| 3 | Thr | 2 -> 3 | Ele |
|
||||||
|
| 4 | Rud | 4 -> 4 | Rud |
|
||||||
|
|
||||||
|
If the radio channel order is not in the expected order (AETR) the channel reordering will be broken.
|
||||||
|
|
||||||
|
For example, if the radio is configured with TAER, but the Multiprotocol module expects AETR, this will happen:
|
||||||
|
|
||||||
|
Radio CH | Radio Input/Output | Module Reordering | Receiver Receives |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| 1 | Thr | 3 -> 1 | Ele |
|
||||||
|
| 2 | Ail | 1 -> 2 | Thr |
|
||||||
|
| 3 | Ele | 2 -> 3 | Ail |
|
||||||
|
| 4 | Rud | 4 -> 4 | Rud |
|
||||||
|
|
||||||
|
With potentially dangerous or disasterous consequences.
|
||||||
|
|
||||||
|
At best, you won't be able to arm your model because the throttle value is too high (because the receiver sees the elevator output, which is at 50%, where it expects throttle to be). At worst the throttle will go to 50% as soon as the model binds with the radio.
|
||||||
|
|
||||||
|
**†** Not all protocols have a fixed channel order, see [Protocols Without a Fixed Channel Order](#protocols-without-a-fixed-channel-order).
|
||||||
|
|
||||||
|
## Setting the Expected Channel Order
|
||||||
|
You can change the expected channel order by compiling or downloading firmware with a different channel order and flashing it to your Multiprotocol Module.
|
||||||
|
|
||||||
|
1. If you compile your own firmware, modify the channel order line in the `_Config.h` file to match your preference
|
||||||
|
2. If you flash the pre-compiled firmware from the Releases page, download the order-specific firmware image which matches your preference
|
||||||
|
|
||||||
|
**After updating the Multiprotocol Module you must still ensure your radio setup matches the module's expected order.**
|
||||||
|
|
||||||
|
## Changing the Channel Order on the radio
|
||||||
|
**Your radio is not aware of the channel order expected by the Multiprotocol Module, and the module is not aware of the default channel order on your radio.**
|
||||||
|
|
||||||
|
Once you have settled on a preferred channel order, and flashed your Multiprotocol Module with firmware which expects that order, you should:
|
||||||
|
|
||||||
|
1. Change the Default Channel Order setting on your radio to match the Multiprotocol Module
|
||||||
|
1. Ensure that any models which you control with the Multiprotocol Module are configured with the channel order which the Module expects
|
||||||
|
|
||||||
|
**Changing the Default Channel Order only affects new models - you must manually edit existing models.**
|
||||||
|
|
||||||
|
## Protocols Without a Fixed Channel Order
|
||||||
|
The Multiprotocol Module also supports protocols which _do not_ have a specific channel order. For these protocols the channel order _is not_ changed and will be transmitted as received from the radio.
|
||||||
|
|
||||||
|
Examples of protocols which are not reordered: Corona, FrSkyD, FrSkyX, FrSkyV, Hitec, and WFly.
|
||||||
|
|
||||||
|
The full list of supported protocols, including the output channel order for each of them, is available [here](../Protocols_Details.md).
|
||||||
|
|
||||||
|
Where the channel table looks like this, with an input assigned to each channel, the output **is** being reordered:
|
||||||
|
|
||||||
|
CH1|CH2|CH3|CH4
|
||||||
|
---|---|---|---
|
||||||
|
A|E|T|R
|
||||||
|
|
||||||
|
Where the channel table looks like this, the output **is not** being reordered:
|
||||||
|
|
||||||
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
||||||
|
---|---|---|---|---|---|---|---
|
||||||
|
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
||||||
@@ -1,25 +1,25 @@
|
|||||||
# Compiling and Flashing (STM32)
|
# Compiling and Flashing (STM32)
|
||||||
|
|
||||||
Multiprotocol modules can be flashed with a precompiled firmware file (Option 1) or you can compile and upload your customized firmware using the Arduino IDE (Option 2).
|
Multiprotocol modules can be flashed with a precompiled firmware file (Option 1 and 2) or you can compile and upload your customized firmware using the Arduino IDE (Option 3).
|
||||||
|
|
||||||
**These instructions are for the STM32 version of the Multiprotocol module.** If you are Compling for the Arduino ATmega328p version of the Multiprotocol Module please go to the dedicated [ATmega328](Compiling.md) page.
|
**These instructions are for the STM32 version of the Multiprotocol module.** If you are Compling for the Arduino ATmega328p version of the Multiprotocol Module please go to the dedicated [ATmega328](Compiling.md) page.
|
||||||
|
|
||||||
## Index
|
## Index
|
||||||
1. [Tools Required](#tools-required)
|
1. [Tools Required](#tools-required)
|
||||||
1. [Option 1 - Update firmware using precompiled binaries](#option-1-update-firmware-using-precompiled-binaries)
|
1. [Option 1 - Update firmware using precompiled binaries](#option-1---update-firmware-using-precompiled-binaries)
|
||||||
1. [Option 2 - Compiling and updating firmware](#option-2-compiling-and-updating-firmware)
|
1. [Option 2 - Flash from TX](#option-2---flash-from-tx)
|
||||||
|
1. [Option 3 - Compiling and updating firmware](#option-3---compiling-and-updating-firmware)
|
||||||
1. [Preparation](#preparation)
|
1. [Preparation](#preparation)
|
||||||
1. [Install the Arduino IDE](#install-the-arduino-ide)
|
1. [Install the Arduino IDE](#install-the-arduino-ide)
|
||||||
1. [Download the Multiprotocol source and open the project](#download-the-multiprotocol-source-and-open-the-project)
|
1. [Download the Multiprotocol source and open the project](#download-the-multiprotocol-source-and-open-the-project)
|
||||||
1. [Install the Multi 4-in-1 board](#install-the-multi-4-in-1-board)
|
1. [Install the Multi 4-in-1 board](#install-the-multi-4-in-1-board)
|
||||||
1. [Configure the Arduino IDE](#configure-the-arduino-ide)
|
1. [Configure the Arduino IDE](#configure-the-arduino-ide)
|
||||||
1. [Configure the firmware](#configure-the-firmware)
|
1. [Configure the firmware](#configure-the-firmware)
|
||||||
1. [Verify the firmware](#verify-the-firmware)
|
1. [Verify the firmware](#verify-the-firmware)
|
||||||
1. [Connect the module](#connect-the-module)
|
1. [Connect the module](#connect-the-module)
|
||||||
1. [USB Port](#usb-port)
|
1. [USB Port](#usb-port)
|
||||||
1. [USB-to-Serial adapter](#usb-to-serial-adapter)
|
1. [USB-to-Serial adapter](#usb-to-serial-adapter)
|
||||||
1. [Upload the firmware](#upload-the-firmware)
|
1. [Upload the firmware](#upload-the-firmware)
|
||||||
1. [Exporting compiled firmware](exporting-compiled-firmware)
|
|
||||||
1. [Troubleshooting](#troubleshooting)
|
1. [Troubleshooting](#troubleshooting)
|
||||||
|
|
||||||
## Tools required
|
## Tools required
|
||||||
@@ -37,20 +37,25 @@ You are still unsure if your module can be flashed without tools or opening it?
|
|||||||
|
|
||||||
Your multi module is not USB upgradable ready, here is what you need:
|
Your multi module is not USB upgradable ready, here is what you need:
|
||||||
|
|
||||||
| **3.3V USB-TTL Adapter** | **4-pin Serial Programming Header** |
|
| **3.3V USB-TTL Adapter** | **4-pin 2.54mm Serial Programming Header** | **4-pin 1mm Serial Programming header + cable** | **5-pin 1.25mm cable** |
|
||||||
|:---:|:--:|
|
|:---:|:---:|:---:|:---:|
|
||||||
| <img src="images/ch340g.jpg" width="200"/> | <img src="images/4-pin-header.jpg" width="150" height="150"/>
|
| All modules | DIY, Banggood 4-in-1, iRangeX IRX4/IRX4+/IRX4Lite, Jumper 4in1 1st gen | Vantac lite, URUAV lite | Jumper T16 internal module |
|
||||||
| [(example ebay link)](https://www.ebay.co.uk/itm/FTDI-USB-to-TTL-Serial-Converter-Adapter-FT232RL-Module-5V-and-3-3V-Arduino-ARM/231918152528) | [(example ebay link)](https://www.ebay.co.uk/itm/4x-826629-4-Pin-header-pin-strips-AMPMODU-MOD-II-male-PIN4-straight/192334571714) |
|
| <img src="images/ch340g.jpg" width="200"/> | <img src="images/4-pin-header.jpg" width="150" height="150"/> | <img src="images/4-pin-1mm.jpg" width="150" height="150"/> | <img src="images/5-pin-125mm.jpg" width="150" height="150"/> |
|
||||||
|
| [(example ebay link)](https://www.ebay.co.uk/itm/FTDI-USB-to-TTL-Serial-Converter-Adapter-FT232RL-Module-5V-and-3-3V-Arduino-ARM/231918152528) | [(example ebay link)](https://www.ebay.co.uk/itm/4x-826629-4-Pin-header-pin-strips-AMPMODU-MOD-II-male-PIN4-straight/192334571714) | [(example ebay link)](https://www.ebay.com/itm/5-PCS-Mini-Micro-ZH-1mm-2-6-Pin-JST-Connector-with-Wire-HI/183963001322) | [(example ebay link)](https://www.ebay.co.uk/itm/5-PAIRS-5-PIN-Micro-JST-GH-1-25-Connector-Plug-Socket-1-25mm-150mm-Cable/273110735668)
|
||||||
|
|
||||||
The USB-TTL adapter can be either FTDI or CH340G, as long as it works. It should have a switch or jumper to select 3.3V or 5V, which **must** be set to **3.3V**.
|
The USB-TTL adapter can be either FTDI or CH340G, as long as it works. It should have a switch or jumper to select 3.3V or 5V, which **must** be set to **3.3V**.
|
||||||
|
|
||||||
The 4-pin header needs to be soldered onto the board as indicated by the red rectangle:
|
The header needs to be soldered onto the board as indicated by the red rectangle:
|
||||||
|
|
||||||
| **DIY Multiprotocol** | **Banggood 4-in-1** | **iRangeX IRX4 Plus** | **Jumper** | **MPM Lite** |
|
| **DIY Multiprotocol** | **Banggood 4-in-1** | **iRangeX IRX4 / IR4+** | **Jumper 4in1 1st gen** |
|
||||||
|:---:|:---:|:---:|:---:|:---:|
|
|:---:|:---:|:---:|:---:|
|
||||||
| <img src="images/Board_PCB_STM32_with_serial.jpg" width="142" height="200"/> | <img src="images/bg-multi-stm32-serial.jpg" width="195" height="200"/> | <img src="images/irx4plus-serial.jpg" width="164" height="200"/> | <img src="images/Jumper-serial.jpg" width="164" height="200"/> | <img src="images/mpmlite-serial.jpg" width="200" height="189" />
|
| <img src="images/Board_PCB_STM32_with_serial.jpg" width="142" height="200"/> | <img src="images/bg-multi-stm32-serial.jpg" width="195" height="200"/> | <img src="images/irx4plus-serial.jpg" width="164" height="200"/> | <img src="images/Jumper-serial.jpg" width="164" height="200"/>
|
||||||
|
|
||||||
**Note:** The Banggood STM32 module most likely already has the header pin in place.
|
| **Vantac/URUAV Lite** | **iRangeX IRX4 Lite** | **Jumper T16 internal module** |
|
||||||
|
|:---:|:---:|:---:|
|
||||||
|
| <img src="images/mpmlite-serial.jpg" width="200" height="189" /> | <img src="images/irx4-lite.jpg" width="160" height="200" /> | <img src="images/T16-internal-connector.png" width="160" height="200" /> |
|
||||||
|
|
||||||
|
**Note:** The Banggood STM32 and T16 internal modules most likely already has the header pin in place.
|
||||||
|
|
||||||
## Option 1 - Update Firmware using Precompiled Binaries
|
## Option 1 - Update Firmware using Precompiled Binaries
|
||||||
If you don't need/want to customize the multi module firmware then you can use pre-compiled binaries available [here](https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/releases).
|
If you don't need/want to customize the multi module firmware then you can use pre-compiled binaries available [here](https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/releases).
|
||||||
@@ -67,10 +72,17 @@ If you don't need/want to customize the multi module firmware then you can use p
|
|||||||
<img src="https://github.com/benlye/flash-multi/raw/master/img/flash-multi.jpg">
|
<img src="https://github.com/benlye/flash-multi/raw/master/img/flash-multi.jpg">
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
After a succesful flash your Module is now updated to the newer version firmware using the most common options. To change specific configured options you would need to use Option-2, Compile and flash update using Arduino IDE.
|
After a succesful flash your Module is now updated to the newer version firmware using the most common options. To change specific configured options you would need to use [Option-3](#option-3---compiling-and-updating-firmware), Compile using Arduino IDE and your desired upload method.
|
||||||
|
|
||||||
# Option2 - Compiling and Updating Firmware
|
## Option 2 - Flash from TX
|
||||||
## Preparation
|
1. If you don't need/want to customize the multi module firmware then you can use pre-compiled binaries available [here](https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/releases).
|
||||||
|
2. If you are compiling the firmware yourself in the Arduino environment with [Option-3](#option-3---compiling-and-updating-firmware), do the following to export the binary:
|
||||||
|
- Click **Sketch -> Export compiled Binary**, or press **Ctrl+Alt+S**
|
||||||
|
- Locate the file named **multi-stm-x.x.x.x.bin** in the **Multiprotocol source folder** folder (x.x.x.x is the multi version)
|
||||||
|
3. Follow the instructions [here](/docs/Flash_from_Tx.md) to upload the firmware using your radio
|
||||||
|
|
||||||
|
## Option 3 - Compiling and Updating Firmware
|
||||||
|
### Preparation
|
||||||
Multiprotocol firmware can be compiled and flashed with your customized firmware using the Arduino IDE. The guide below will walk you through all the steps in many details, don't be afraid by the length it is in fact simple!
|
Multiprotocol firmware can be compiled and flashed with your customized firmware using the Arduino IDE. The guide below will walk you through all the steps in many details, don't be afraid by the length it is in fact simple!
|
||||||
|
|
||||||
### Install the Arduino IDE
|
### Install the Arduino IDE
|
||||||
@@ -90,14 +102,14 @@ Multiprotocol firmware can be compiled and flashed with your customized firmware
|
|||||||
1. Under **Tools -> Board** select **Multi 4-in-1 (STM32FC103)**
|
1. Under **Tools -> Board** select **Multi 4-in-1 (STM32FC103)**
|
||||||
1. Under **Tools -> Debug Option** select **None**
|
1. Under **Tools -> Debug Option** select **None**
|
||||||
|
|
||||||
## Configure the firmware
|
### Configure the firmware
|
||||||
Make any changes you require to the firmware.
|
Make any changes you require to the firmware.
|
||||||
|
|
||||||
The STM32 module has more than enough flash space for all the available protocols so, unlike the Atmega328p-based module, it is not necessary to disable unused protocols.
|
The STM32 module has more than enough flash space for all the available protocols so, unlike the Atmega328p-based module, it is not necessary to disable unused protocols.
|
||||||
|
|
||||||
You can still disable protocols if you wish, and you may also enable or disable other optional Multiprotocol features.
|
You can still disable protocols if you wish, and you may also enable or disable other optional Multiprotocol features.
|
||||||
|
|
||||||
## Verify the firmware
|
### Verify the firmware
|
||||||
To check that the program will compile correctly and fit in the STM32 click **Sketch -> Verify/Compile**, or press **Ctrl+R**.
|
To check that the program will compile correctly and fit in the STM32 click **Sketch -> Verify/Compile**, or press **Ctrl+R**.
|
||||||
|
|
||||||
If there are errors, carefully read it, go to the line number indicated and correct your typo.
|
If there are errors, carefully read it, go to the line number indicated and correct your typo.
|
||||||
@@ -109,15 +121,15 @@ Global variables use 4064 bytes (19%) of dynamic memory, leaving 16416 bytes for
|
|||||||
```
|
```
|
||||||
You can proceed to the next step.
|
You can proceed to the next step.
|
||||||
|
|
||||||
## Connect the module
|
### Connect the module
|
||||||
### USB port
|
#### USB port
|
||||||
Ensure that you [installed the necessary drivers](https://github.com/benlye/DIY-Multiprotocol-TX-Module/blob/doc-updates/docs/Arduino_IDE_Boards.md#install-device-drivers).
|
Ensure that you [installed the necessary drivers](https://github.com/benlye/DIY-Multiprotocol-TX-Module/blob/doc-updates/docs/Arduino_IDE_Boards.md#install-device-drivers).
|
||||||
|
|
||||||
If your Multiprotocol module has a USB port, connect it to the computer. With the drivers installed your computer should detect the module as a COM port. If the device appears correctly (check in **Device Manager**) you can proceed to the next step and [upload the firmware](#upload-the-firmware). If not, you will need to flash your module one time using a USB-to-serial adapter (also known as an FTDI adapter).
|
If your Multiprotocol module has a USB port, connect it to the computer. With the drivers installed your computer should detect the module as a COM port. If the device appears correctly (check in **Device Manager**) you can proceed to the next step and [upload the firmware](#upload-the-firmware). If not, you will need to flash your module one time using a USB-to-serial adapter (also known as an FTDI adapter).
|
||||||
|
|
||||||
**Note:** Some modules require external power in order for the USB port to work. If your module does not power on with USB power alone, install it in the transmitter and switch the transmitter on. It is generally safe for the module to recieve power from both USB and the transmitter.
|
**Note:** Some modules require external power in order for the USB port to work. If your module does not power on with USB power alone, install it in the transmitter and switch the transmitter on. It is generally safe for the module to recieve power from both USB and the transmitter.
|
||||||
|
|
||||||
### USB-to-Serial adapter
|
#### USB-to-Serial adapter
|
||||||
It is **strongly** recommended that you power your module from the transmitter when flashing it using a USB-to-serial adapater. This ensures that the module cannot be inadvertently supplied with 5V, which will damage the RF modules. This guide assumes that you will follow that advice, and instructs you to leave the V+ pin on the USB-to-TTL adapter disconnected. You may choose to ignore that advice at your own risk!
|
It is **strongly** recommended that you power your module from the transmitter when flashing it using a USB-to-serial adapater. This ensures that the module cannot be inadvertently supplied with 5V, which will damage the RF modules. This guide assumes that you will follow that advice, and instructs you to leave the V+ pin on the USB-to-TTL adapter disconnected. You may choose to ignore that advice at your own risk!
|
||||||
|
|
||||||
The wiring for the USB-to-TTL adapter is:
|
The wiring for the USB-to-TTL adapter is:
|
||||||
@@ -128,35 +140,39 @@ The wiring for the USB-to-TTL adapter is:
|
|||||||
|
|
||||||
**It is critical to ensure that the USB-to-TTL adapter is set to 3.3V**.
|
**It is critical to ensure that the USB-to-TTL adapter is set to 3.3V**.
|
||||||
|
|
||||||
| **DIY Multiprotocol** | **Banggood 4-in-1** | **iRangeX IRX4** | **Jumper 4-in-1** |
|
| **DIY Multiprotocol** | **Banggood 4-in-1** | **iRangeX IRX4** |
|
||||||
|:---:|:---:|:---:|:---:|
|
|:---:|:---:|:---:|
|
||||||
| <img src="images/diy-ch340g.jpg" height="200"/> | <img src="images/bg-stm32-ch340g.jpg" height="200"/> | <img src="images/irx4-ch340g.jpg" height="200"/> | <img src="images/Jumper-ch340g.jpg" height="200"/> |
|
| <img src="images/diy-ch340g.jpg" height="200"/> | <img src="images/bg-stm32-ch340g.jpg" height="200"/> | <img src="images/irx4-ch340g.jpg" height="200"/> |
|
||||||
|
|
||||||
|
| **Jumper 4-in-1 1st gen** | **Jumper T16 internal module** |
|
||||||
|
|:---:|:---:|
|
||||||
|
| <img src="images/Jumper-ch340g.jpg" height="200"/> | <img src="images/T16-internal-connection.png" height="200"/> |
|
||||||
|
|
||||||
1. Put the module in the transmitter
|
1. Put the module in the transmitter
|
||||||
1. Connect the USB-to-TTL adapter to the module as described above
|
1. Connect the USB-to-TTL adapter to the module as described above
|
||||||
1. Plug the USB-to-TTL adapter into the PC
|
1. Plug the USB-to-TTL adapter into the PC
|
||||||
1. In the Arduino IDE click **Tools -> Port** and choose the COM port which matches the USB-to-TTL adapter
|
1. In the Arduino IDE click **Tools -> Port** and choose the COM port which matches the USB-to-TTL adapter
|
||||||
|
|
||||||
In order to flash the bootloader the **BOOT0** jumper must be installed connecting **BOOT0** to 3.3V. The location of **BOOT0** varies by hardware module. The latest Jumper modules with an intergrated FTDI do not need the BOOT0 jumper.
|
In order to flash the bootloader the **BOOT0** jumper must be installed connecting **BOOT0** to 3.3V. The location of **BOOT0** varies by hardware module.
|
||||||
|
|
||||||
| **DIY Multiprotocol** | **Banggood 4-in-1** | **iRangeX IRX4** | **iRangeX IRX4 Plus** | **Jumper 4-in-1** | **Vantac MPM Lite** |
|
| **DIY Multiprotocol** | **Banggood 4-in-1** | **iRangeX IRX4** | **iRangeX IRX4 Plus** | **Jumper 4-in-1 1st gen** |
|
||||||
|:---:|:---:|:---:|:---:|:---:|:---:|
|
|:---:|:---:|:---:|:---:|:---:|
|
||||||
| Bridge pins 1 and 2 as shown by the yellow jumper wire. | Bridge the left-most pins of the 6-pin header as shown by the yellow jumper. | Bridge pins 1 and 2 as shown by the blue jumper. | Bridge the BOOT0 pin to the adjacent 3.3V pin as shown by the yellow jumper. If it doesn't work move the jumper to bridge the two left hand pins (BOOT0 and directly above). | Bridge pins 1 and 2 as shown by the red jumper wire. | Brdige the two pins next to the usb port labelled with Boot0 |
|
| Bridge pins 1 and 2 as shown by the yellow jumper wire. | Bridge the left-most pins of the 6-pin header as shown by the yellow jumper. | Bridge pins 1 and 2 as shown by the blue jumper. | Bridge the BOOT0 pin to the adjacent 3.3V pin as shown by the yellow jumper. If it doesn't work move the jumper to bridge the two left hand pins (BOOT0 and directly above). | Bridge pins 1 and 2 as shown by the red jumper wire. |
|
||||||
| <img src="images/diy-ch340g.jpg" height="200"/> | <img src="images/bg-stm32-boot0.jpg" height="200"/> | <img src="images/irx4-boot0.jpg" height="200"/> | <img src="images/irx4plus-boot0.jpg" height="200"/> | <img src="images/Jumper-ch340g.jpg" height="200"/> | <img src="images/mpmlite-boot0.jpg" width="200" /> |
|
| <img src="images/diy-ch340g.jpg" height="200"/> | <img src="images/bg-stm32-boot0.jpg" height="200"/> | <img src="images/irx4-boot0.jpg" height="200"/> | <img src="images/irx4plus-boot0.jpg" height="200"/> | <img src="images/Jumper-ch340g.jpg" height="200"/> |
|
||||||
|
|
||||||
|
| **Vantac/URUAV Lite** | **iRangeX IRX4 Lite** | **Jumper T16 internal module** |
|
||||||
|
|:---:|:---:|:---:|
|
||||||
|
| Brdige the two pins next to the usb port labelled with Boot0 | Brdige the two indicated pins| Bridge BOOT0 and +3.3V in RED on the cabling |
|
||||||
|
| <img src="images/mpmlite-boot0.jpg" width="200" /> | <img src="images/irx4-lite-boot0.jpg" height="200"/> | <img src="images/T16-internal-connection.png" height="200"/> |
|
||||||
|
|
||||||
1. If on Linux, ensure you have permissions to access serial interfaces as described [here](https://github.com/benlye/DIY-Multiprotocol-TX-Module/blob/doc-updates/docs/Arduino_IDE_Boards.md#linux)
|
1. If on Linux, ensure you have permissions to access serial interfaces as described [here](https://github.com/benlye/DIY-Multiprotocol-TX-Module/blob/doc-updates/docs/Arduino_IDE_Boards.md#linux)
|
||||||
1. Install the **BOOT0** jumper as described above.
|
1. Install the **BOOT0** jumper as described above.
|
||||||
1. Switch on the transmitter
|
1. Switch on the transmitter
|
||||||
|
|
||||||
## Upload the firmware
|
### Upload the firmware
|
||||||
1. In the Arduino IDE click **Sketch -> Upload**, or press **Ctrl+U**
|
1. In the Arduino IDE click **Sketch -> Upload**, or press **Ctrl+U**
|
||||||
|
|
||||||
## Exporting compiled firmware
|
# Troubleshooting
|
||||||
1. Click **Sketch -> Export compiled Binary**, or press **Ctrl+Alt+S**
|
|
||||||
1. Locate the file named **multi-stm-x.x.x.x.bin** in the **Multiprotocol source folder** folder (x.x.x.x is the multi version)
|
|
||||||
1. Follow the instructions [here](/docs/Flash_from_Tx.md) to upload the firmware using your radio
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
You can report your problem using the [GitHub issue](https://github.com/midelic/DIY-Multiprotocol-TX-Module/issues) system or go to the [Main thread on RCGROUPS](http://www.rcgroups.com/forums/showthread.php?t=2165676) to ask your question.
|
You can report your problem using the [GitHub issue](https://github.com/midelic/DIY-Multiprotocol-TX-Module/issues) system or go to the [Main thread on RCGROUPS](http://www.rcgroups.com/forums/showthread.php?t=2165676) to ask your question.
|
||||||
Please provide the following information:
|
Please provide the following information:
|
||||||
|
|
||||||
|
|||||||
@@ -8,16 +8,17 @@ The protocols which require frequency tuning are:
|
|||||||
* **S-FHSS** (e.g. Futaba S-FHSS receivers)
|
* **S-FHSS** (e.g. Futaba S-FHSS receivers)
|
||||||
* **Corona** (e.g. Corona V1 FSS, Corona V2 DSSS CR8D/CR6D/CR4D and FlyDream IS-4R/IS-4R0 receivers)
|
* **Corona** (e.g. Corona V1 FSS, Corona V2 DSSS CR8D/CR6D/CR4D and FlyDream IS-4R/IS-4R0 receivers)
|
||||||
* **Hitec** (e.g. Optima, Minima, Micro and RED receivers)
|
* **Hitec** (e.g. Optima, Minima, Micro and RED receivers)
|
||||||
|
* **HoTT** (e.g. Graupner receivers)
|
||||||
|
|
||||||
There is a [video](#video) at the end of this page which gives an example of the tuning process.
|
There is a [video](#video) at the end of this page which gives an example of the tuning process.
|
||||||
|
|
||||||
## More information
|
## More information
|
||||||
Original FrSky, Futaba, Corona and Hitec receivers have been frequency-tuned by the manufacturer at the factory. Because of variations in the oscillator crystals used in multiprotocol modules it is necessary to fine-tune the module to match the manufacturer frequencies.
|
Original FrSky, Futaba, Corona Hitec and HoTT receivers have been frequency-tuned by the manufacturer at the factory. Because of variations in the oscillator crystals used in multiprotocol modules it is necessary to fine-tune the module to match the manufacturer frequencies.
|
||||||
|
|
||||||
'Compatible' receivers suffer the same variation in crystal oscillators as multiprotocol modules, but have to be compatible with genuine (manufacturer-tuned) transmitters so they will typically have auto-tuning built in, and will self-tune to the radio's frequency when they are bound.
|
'Compatible' receivers suffer the same variation in crystal oscillators as multiprotocol modules, but have to be compatible with genuine (manufacturer-tuned) transmitters so they will typically have auto-tuning built in, and will self-tune to the radio's frequency when they are bound.
|
||||||
|
|
||||||
## Fine-tuning procedure
|
## Fine-tuning procedure
|
||||||
**Note:** For best results, the fine-tuning procedure should be carried out with a genuine FrSky/Futaba/Corona/Hitec receiver.
|
**Note:** For best results, the fine-tuning procedure should be carried out with a genuine FrSky/Futaba/Corona/Hitec/HoTT receiver.
|
||||||
|
|
||||||
The procedure can be performed in serial or PPM mode, but is easier with in serial mode where the effect of the change can be seen in real-time.
|
The procedure can be performed in serial or PPM mode, but is easier with in serial mode where the effect of the change can be seen in real-time.
|
||||||
|
|
||||||
@@ -49,7 +50,7 @@ Connection is lost at -73 and +35; the median is -19:
|
|||||||
### Finally
|
### Finally
|
||||||
Once the **Freq** value is known it should be applied to all other models which use this protocol and, if they were previously bound, the receivers must be re-bound.
|
Once the **Freq** value is known it should be applied to all other models which use this protocol and, if they were previously bound, the receivers must be re-bound.
|
||||||
|
|
||||||
For convenience this can be done in the `_Config.h` (or `_MyConfig.h`) configuration file.
|
For convenience this can be applied once for all per protocol using the FORCE commands described below in `_Config.h` (or `_MyConfig.h`) configuration file.
|
||||||
|
|
||||||
#### Forced tuning values
|
#### Forced tuning values
|
||||||
Once known-good tuning values have been determined, they can be stored in the configuration file to be automatically applied to all models which use the given protocol.
|
Once known-good tuning values have been determined, they can be stored in the configuration file to be automatically applied to all models which use the given protocol.
|
||||||
@@ -73,6 +74,7 @@ These settings can also be used to force different tuning values for different m
|
|||||||
//#define FORCE_SFHSS_TUNING 0
|
//#define FORCE_SFHSS_TUNING 0
|
||||||
//#define FORCE_CORONA_TUNING 0
|
//#define FORCE_CORONA_TUNING 0
|
||||||
//#define FORCE_HITEC_TUNING 0
|
//#define FORCE_HITEC_TUNING 0
|
||||||
|
//#define FORCE_HOTT_TUNING 0
|
||||||
```
|
```
|
||||||
|
|
||||||
## Video
|
## Video
|
||||||
|
|||||||
BIN
docs/images/4-pin-1mm.jpg
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
docs/images/5-pin-125mm.jpg
Normal file
|
After Width: | Height: | Size: 29 KiB |
BIN
docs/images/Debug1.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
docs/images/T16-internal-connection.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
docs/images/T16-internal-connector.png
Normal file
|
After Width: | Height: | Size: 323 KiB |
BIN
docs/images/irx4-lite-boot0.jpg
Normal file
|
After Width: | Height: | Size: 537 KiB |
BIN
docs/images/irx4-lite-cabling.jpg
Normal file
|
After Width: | Height: | Size: 545 KiB |
BIN
docs/images/irx4-lite.jpg
Normal file
|
After Width: | Height: | Size: 538 KiB |