mirror of
https://github.com/pascallanger/DIY-Multiprotocol-TX-Module.git
synced 2025-11-25 13:29:40 +00:00
Compare commits
71 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 |
82
.travis.yml
82
.travis.yml
@@ -45,23 +45,29 @@ before_install:
|
||||
# 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; };
|
||||
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;
|
||||
@@ -72,54 +78,68 @@ before_install:
|
||||
opt_disable $ALL_PROTOCOLS;
|
||||
opt_enable $CYRF6936_PROTOCOLS;
|
||||
buildMulti;
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-avr-usbasp-aetr-CYRF6936-inv-v$MULTI_VERSION.bin; };
|
||||
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;
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-avr-txflash-aetr-CYRF6936-inv-v$MULTI_VERSION.bin; };
|
||||
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;
|
||||
@@ -127,27 +147,33 @@ before_install:
|
||||
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;
|
||||
@@ -155,18 +181,23 @@ before_install:
|
||||
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;
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-ppm-reta-noinv-v$MULTI_VERSION.bin; };
|
||||
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-usbdebug-v$MULTI_VERSION.bin\e[0m";
|
||||
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;
|
||||
@@ -174,17 +205,21 @@ before_install:
|
||||
opt_disable MULTI_TELEMETRY;
|
||||
opt_enable INVERT_TELEMETRY;
|
||||
buildMulti;
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-erskytx-xn297dump-usbdebug-v$MULTI_VERSION.bin;
|
||||
printf "\n\e[33;1mBuilding multi-stm-opentx-xn297dump-usbdebug-v$MULTI_VERSION.bin\e[0m";
|
||||
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;
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-opentx-xn297dump-usbdebug-v$MULTI_VERSION.bin; };
|
||||
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-ftdidebug-v$MULTI_VERSION.bin\e[0m";
|
||||
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;
|
||||
@@ -192,25 +227,17 @@ before_install:
|
||||
opt_disable MULTI_TELEMETRY;
|
||||
opt_enable INVERT_TELEMETRY;
|
||||
buildMulti;
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-erskytx-xn297dump-ftdidebug-v$MULTI_VERSION.bin;
|
||||
printf "\n\e[33;1mBuilding multi-stm-opentx-xn297dump-ftdidebug-v$MULTI_VERSION.bin\e[0m";
|
||||
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;
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-opentx-xn297dump-ftdidebug-v$MULTI_VERSION.bin;
|
||||
printf "\n\e[33;1mBuilding multi-stm-erskytx-aetr-inv-ftdidebug-v$MULTI_VERSION.bin\e[0m";
|
||||
opt_enable $ALL_PROTOCOLS;
|
||||
opt_enable MULTI_STATUS;
|
||||
opt_disable MULTI_TELEMETRY;
|
||||
buildMulti;
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-erskytx-aetr-inv-ftdidebug-v$MULTI_VERSION.bin;
|
||||
printf "\n\e[33;1mBuilding multi-stm-opentx-aetr-inv-ftdidebug-v$MULTI_VERSION.bin\e[0m";
|
||||
opt_disable MULTI_STATUS;
|
||||
opt_enable MULTI_TELEMETRY;
|
||||
buildMulti;
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-opentx-aetr-inv-ftdidebug-v$MULTI_VERSION.bin; };
|
||||
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
|
||||
@@ -275,9 +302,10 @@ before_script:
|
||||
opt_disable CHECK_FOR_BOOTLOADER;
|
||||
fi
|
||||
|
||||
# Trim the enabled protocols down for the STM32 board with USB debugging
|
||||
- if [[ "$BOARD" == "multi4in1:STM32F1:multistm32f103c:debug_option=native" ]]; then
|
||||
opt_disable AFHDS2A_RX_A7105_INO FRSKY_RX_CC2500_INO SCANNER_CC2500_INO WK2x01_CYRF6936_INO HUBSAN_A7105_INO;
|
||||
# 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
|
||||
@@ -295,7 +323,7 @@ before_script:
|
||||
- end_fold() { echo -e "\ntravis_fold:end:$1\r"; }
|
||||
|
||||
script:
|
||||
# Build with default configuration - all protocols are 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
|
||||
- buildDefault
|
||||
|
||||
# Serial only
|
||||
|
||||
@@ -197,6 +197,11 @@ void A7105_AdjustLOBaseFreq(uint8_t cmd)
|
||||
offset=(int16_t)FORCE_FLYZONE_TUNING;
|
||||
#endif
|
||||
break;
|
||||
case PROTO_PELIKAN:
|
||||
#ifdef FORCE_PELIKAN_TUNING
|
||||
offset=(int16_t)FORCE_PELIKAN_TUNING;
|
||||
#endif
|
||||
break;
|
||||
case PROTO_AFHDS2A:
|
||||
case PROTO_AFHDS2A_RX:
|
||||
#ifdef FORCE_AFHDS2A_TUNING
|
||||
@@ -293,6 +298,14 @@ const uint8_t PROGMEM HUBSAN_A7105_regs[] = {
|
||||
0xFF, 0xFF // 30 - 31
|
||||
};
|
||||
#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_PLUS 0xAA201041
|
||||
@@ -309,6 +322,14 @@ void A7105_Init(void)
|
||||
}
|
||||
else
|
||||
#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
|
||||
if(protocol==PROTO_BUGS)
|
||||
A7105_Regs=(uint8_t*)BUGS_A7105_regs;
|
||||
@@ -391,17 +412,21 @@ void A7105_Init(void)
|
||||
case PROTO_FLYZONE:
|
||||
vco_calibration1=0x02;
|
||||
break;
|
||||
case PROTO_PELIKAN:
|
||||
vco_calibration1=0x0C;
|
||||
break;
|
||||
default:
|
||||
vco_calibration1=0x0A;
|
||||
break;
|
||||
}
|
||||
A7105_WriteReg(A7105_25_VCO_SBCAL_I,vco_calibration1); //Reset VCO Band calibration
|
||||
}
|
||||
|
||||
A7105_SetTxRxMode(TX_EN);
|
||||
A7105_SetPower();
|
||||
|
||||
A7105_AdjustLOBaseFreq(0);
|
||||
#ifdef USE_A7105_CH15_TUNING
|
||||
A7105_AdjustLOBaseFreq(0);
|
||||
#endif
|
||||
|
||||
A7105_Strobe(A7105_STANDBY);
|
||||
}
|
||||
|
||||
207
Multiprotocol/Bayang_Rx_nrf24l01.ino
Normal file
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"
|
||||
|
||||
#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_PACKET_SIZE 15
|
||||
#define BAYANG_RF_NUM_CHANNELS 4
|
||||
@@ -46,10 +47,10 @@ enum BAYANG_OPTION_FLAGS {
|
||||
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;
|
||||
if (bind)
|
||||
if (IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
#ifdef BAYANG_HUB_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++)
|
||||
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;
|
||||
|
||||
// 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
|
||||
// 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));
|
||||
|
||||
#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
|
||||
XN297_WritePayload(packet, BAYANG_PACKET_SIZE);
|
||||
|
||||
NRF24L01_SetPower(); // Set tx_power
|
||||
}
|
||||
@@ -233,7 +220,8 @@ static void __attribute__((unused)) BAYANG_check_rx(void)
|
||||
// compensated battery volts*100/2
|
||||
v_lipo2 = (packet[5]<<7) + (packet[6]>>2);
|
||||
// reception in packets / sec
|
||||
RX_RSSI = packet[7];
|
||||
RX_LQI = packet[7];
|
||||
RX_RSSI = RX_LQI;
|
||||
//Flags
|
||||
//uint8_t flags = packet[3] >> 3;
|
||||
// battery low: flags & 1
|
||||
@@ -242,6 +230,7 @@ static void __attribute__((unused)) BAYANG_check_rx(void)
|
||||
telemetry_link=1;
|
||||
}
|
||||
}
|
||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -278,58 +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()
|
||||
{
|
||||
if(IS_BIND_DONE)
|
||||
#ifdef BAYANG_HUB_TELEMETRY
|
||||
uint16_t start;
|
||||
#endif
|
||||
switch(phase)
|
||||
{
|
||||
if(packet_count==0)
|
||||
{
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync((option & BAYANG_OPTION_FLAG_TELEMETRY)?5*BAYANG_PACKET_PERIOD:2*BAYANG_PACKET_PERIOD);
|
||||
#endif
|
||||
BAYANG_send_packet(0);
|
||||
}
|
||||
packet_count++;
|
||||
#ifdef BAYANG_HUB_TELEMETRY
|
||||
if (option & BAYANG_OPTION_FLAG_TELEMETRY)
|
||||
{ // telemetry is enabled
|
||||
state++;
|
||||
if (state > 1000)
|
||||
{
|
||||
//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;
|
||||
case BAYANG_BIND:
|
||||
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
|
||||
BIND_DONE;
|
||||
phase++; //WRITE
|
||||
}
|
||||
else
|
||||
#endif
|
||||
packet_count%=2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bind_counter == 0)
|
||||
{
|
||||
XN297_SetTXAddr(rx_tx_addr, BAYANG_ADDRESS_LENGTH);
|
||||
#ifdef BAYANG_HUB_TELEMETRY
|
||||
XN297_SetRXAddr(rx_tx_addr, BAYANG_ADDRESS_LENGTH);
|
||||
BAYANG_send_packet();
|
||||
break;
|
||||
case BAYANG_WRITE:
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync((option & BAYANG_OPTION_FLAG_TELEMETRY)?BAYANG_PACKET_TELEM_PERIOD:BAYANG_PACKET_PERIOD);
|
||||
#endif
|
||||
BIND_DONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(packet_count==0)
|
||||
BAYANG_send_packet(1);
|
||||
packet_count++;
|
||||
packet_count%=4;
|
||||
bind_counter--;
|
||||
}
|
||||
BAYANG_send_packet();
|
||||
#ifdef BAYANG_HUB_TELEMETRY
|
||||
if (option & BAYANG_OPTION_FLAG_TELEMETRY)
|
||||
{ // telemetry is enabled
|
||||
state++;
|
||||
if (state > 200)
|
||||
{
|
||||
state = 0;
|
||||
//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;
|
||||
}
|
||||
@@ -350,6 +354,7 @@ static void __attribute__((unused)) BAYANG_initialize_txid()
|
||||
uint16_t initBAYANG(void)
|
||||
{
|
||||
BIND_IN_PROGRESS; // autobind protocol
|
||||
phase=BAYANG_BIND;
|
||||
bind_counter = BAYANG_BIND_COUNT;
|
||||
BAYANG_initialize_txid();
|
||||
BAYANG_init();
|
||||
|
||||
@@ -140,3 +140,25 @@ 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
|
||||
|
||||
@@ -92,8 +92,8 @@ static void __attribute__((unused)) ESKY150_send_packet()
|
||||
uint8_t flight_mode=0;
|
||||
uint16_t aux_ch6=0;
|
||||
uint8_t aux_ch7=0;
|
||||
if(option==1)
|
||||
{
|
||||
if(sub_protocol)
|
||||
{ // 7 channels
|
||||
flight_mode=ESKY150_convert_2bit_channel(CH5);
|
||||
aux_ch6=convert_channel_16b_limit(CH6,1000,2000);
|
||||
aux_ch7=ESKY150_convert_2bit_channel(CH7);
|
||||
|
||||
@@ -18,8 +18,13 @@
|
||||
|
||||
#include "iface_nrf24l01.h"
|
||||
|
||||
//#define ESKY_ET4_FORCE_ID
|
||||
|
||||
#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_PACKET_CHKTIME 100 // Time to wait for packet to be sent (no ACK, so very short)
|
||||
|
||||
@@ -63,28 +68,37 @@ static void __attribute__((unused)) ESKY_init()
|
||||
static void __attribute__((unused)) ESKY_init2()
|
||||
{
|
||||
NRF24L01_FlushTx();
|
||||
hopping_frequency_no = 0;
|
||||
uint16_t channel_ord = rx_tx_addr[0] % 74;
|
||||
hopping_frequency[12] = 10 + (uint8_t)channel_ord; //channel_code
|
||||
uint8_t channel1, channel2;
|
||||
channel1 = 10 + (uint8_t)((37 + channel_ord*5) % 74);
|
||||
channel2 = 10 + (uint8_t)(( channel_ord*5) % 74) ;
|
||||
if(sub_protocol==ESKY_STD)
|
||||
{
|
||||
uint16_t channel_ord = rx_tx_addr[0] % 74;
|
||||
hopping_frequency[12] = 10 + (uint8_t)channel_ord; //channel_code
|
||||
uint8_t channel1, channel2;
|
||||
channel1 = 10 + (uint8_t)((37 + channel_ord*5) % 74);
|
||||
channel2 = 10 + (uint8_t)(( channel_ord*5) % 74) ;
|
||||
|
||||
hopping_frequency[0] = channel1;
|
||||
hopping_frequency[1] = channel1;
|
||||
hopping_frequency[2] = channel1;
|
||||
hopping_frequency[3] = channel2;
|
||||
hopping_frequency[4] = channel2;
|
||||
hopping_frequency[5] = channel2;
|
||||
|
||||
//end_bytes
|
||||
hopping_frequency[6] = 6;
|
||||
hopping_frequency[7] = channel1*2;
|
||||
hopping_frequency[8] = channel2*2;
|
||||
hopping_frequency[9] = 6;
|
||||
hopping_frequency[10] = channel1*2;
|
||||
hopping_frequency[11] = channel2*2;
|
||||
hopping_frequency[0] = channel1;
|
||||
hopping_frequency[1] = channel1;
|
||||
hopping_frequency[2] = channel1;
|
||||
hopping_frequency[3] = channel2;
|
||||
hopping_frequency[4] = channel2;
|
||||
hopping_frequency[5] = channel2;
|
||||
|
||||
//end_bytes
|
||||
hopping_frequency[6] = 6;
|
||||
hopping_frequency[7] = channel1*2;
|
||||
hopping_frequency[8] = channel2*2;
|
||||
hopping_frequency[9] = 6;
|
||||
hopping_frequency[10] = channel1*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
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
}
|
||||
@@ -111,20 +125,32 @@ static void __attribute__((unused)) ESKY_send_packet(uint8_t bind)
|
||||
}
|
||||
else
|
||||
{
|
||||
// Regular packet
|
||||
// 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)
|
||||
if (packet_count == 0)
|
||||
for (uint8_t i = 0; i < 6; 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+1] = val&0xFF; //low byte of servo timing(1000-2000us)
|
||||
}
|
||||
rf_ch = hopping_frequency[hopping_frequency_no];
|
||||
packet[12] = hopping_frequency[hopping_frequency_no+6]; // end_bytes
|
||||
hopping_frequency_no++;
|
||||
if (hopping_frequency_no > 6) hopping_frequency_no = 0;
|
||||
if(sub_protocol==ESKY_STD)
|
||||
{
|
||||
// Regular packet
|
||||
// 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_FlushTx();
|
||||
@@ -137,9 +163,17 @@ uint16_t ESKY_callback()
|
||||
if(IS_BIND_DONE)
|
||||
{
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(ESKY_PACKET_PERIOD);
|
||||
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);
|
||||
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
|
||||
{
|
||||
@@ -150,16 +184,25 @@ uint16_t ESKY_callback()
|
||||
BIND_DONE;
|
||||
}
|
||||
}
|
||||
return ESKY_PACKET_PERIOD;
|
||||
return ESKY_STD_PACKET_PERIOD;
|
||||
}
|
||||
|
||||
uint16_t initESKY(void)
|
||||
{
|
||||
bind_counter = ESKY_BIND_COUNT;
|
||||
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;
|
||||
ESKY_init();
|
||||
ESKY_init2();
|
||||
packet_count=0;
|
||||
return 50000;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ static void __attribute__((unused)) flyzone_build_packet()
|
||||
packet[4] = convert_channel_8b(ELEVATOR); //00..80..FF
|
||||
packet[5] = convert_channel_8b(THROTTLE); //00..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()
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
/** FrSky D and X routines **/
|
||||
/******************************/
|
||||
|
||||
#if defined(FRSKYX_CC2500_INO) || defined(FRSKY_RX_CC2500_INO)
|
||||
#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,
|
||||
@@ -142,7 +142,7 @@ void Frsky_init_hop(void)
|
||||
/*15_DEVIATN*/ 0x42 };
|
||||
#endif
|
||||
|
||||
#if defined(FRSKYX_CC2500_INO)
|
||||
#if defined(FRSKYX_CC2500_INO) || defined(FRSKYX2_CC2500_INO)
|
||||
const PROGMEM uint8_t FRSKYX_cc2500_conf[]= {
|
||||
//FRSKYX
|
||||
/*02_IOCFG0*/ 0x06 ,
|
||||
@@ -222,8 +222,58 @@ void Frsky_init_hop(void)
|
||||
uint8_t val=pgm_read_byte_near(&FRSKY_common_end_cc2500_conf[i][1]);
|
||||
CC2500_WriteReg(reg,val);
|
||||
}
|
||||
if(protocol==PROTO_FRSKYX2)
|
||||
CC2500_WriteReg(CC2500_08_PKTCTRL0, 0x05); // enable CRC
|
||||
CC2500_SetTxRxMode(TX_EN);
|
||||
CC2500_SetPower();
|
||||
CC2500_Strobe(CC2500_SIDLE); // Go to idle...
|
||||
}
|
||||
#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);
|
||||
|
||||
CC2500_WriteReg(CC2500_1B_AGCCTRL2, bind ? 0x43 : 0x03);
|
||||
CC2500_WriteReg(CC2500_09_ADDR, bind ? 0x03 : rx_tx_addr[3]);
|
||||
CC2500_WriteReg(CC2500_07_PKTCTRL1, 0x05);
|
||||
CC2500_Strobe(CC2500_SIDLE); // Go to idle...
|
||||
@@ -95,7 +96,17 @@ static void __attribute__((unused)) frsky2way_data_frame()
|
||||
|
||||
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;
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
|
||||
208
Multiprotocol/FrSkyR9_sx1276.ino
Normal file
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
|
||||
@@ -19,52 +19,6 @@
|
||||
|
||||
#include "iface_cc2500.h"
|
||||
|
||||
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_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);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) FrSkyX_build_bind_packet()
|
||||
{
|
||||
packet[0] = (sub_protocol & 2 ) ? 0x20 : 0x1D ; // LBT or FCC
|
||||
@@ -85,6 +39,11 @@ static void __attribute__((unused)) FrSkyX_build_bind_packet()
|
||||
//
|
||||
uint8_t limit = (sub_protocol & 2 ) ? 31 : 28 ;
|
||||
memset(&packet[13], 0, limit - 13);
|
||||
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;
|
||||
@@ -92,27 +51,6 @@ static void __attribute__((unused)) FrSkyX_build_bind_packet()
|
||||
//
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
#define FrSkyX_FAILSAFE_TIME 1032
|
||||
static void __attribute__((unused)) FrSkyX_build_packet()
|
||||
{
|
||||
@@ -431,6 +369,7 @@ uint16_t initFrSkyX()
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
@@ -310,14 +310,14 @@ uint16_t FrSky_Rx_callback()
|
||||
case FRSKY_RX_TUNE_START:
|
||||
if (len >= packet_length) {
|
||||
CC2500_ReadData(packet, packet_length);
|
||||
if(packet[1] == 0x03 && packet[2] == 0x01) {
|
||||
if(frskyx_rx_check_crc()) {
|
||||
frsky_rx_finetune = -127;
|
||||
CC2500_WriteReg(CC2500_0C_FSCTRL0, frsky_rx_finetune);
|
||||
phase = FRSKY_RX_TUNE_LOW;
|
||||
frsky_rx_strobe_rx();
|
||||
return 1000;
|
||||
}
|
||||
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)
|
||||
@@ -330,7 +330,7 @@ uint16_t FrSky_Rx_callback()
|
||||
case FRSKY_RX_TUNE_LOW:
|
||||
if (len >= packet_length) {
|
||||
CC2500_ReadData(packet, packet_length);
|
||||
if (frskyx_rx_check_crc()) {
|
||||
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);
|
||||
@@ -347,7 +347,7 @@ uint16_t FrSky_Rx_callback()
|
||||
case FRSKY_RX_TUNE_HIGH:
|
||||
if (len >= packet_length) {
|
||||
CC2500_ReadData(packet, packet_length);
|
||||
if (frskyx_rx_check_crc()) {
|
||||
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);
|
||||
@@ -367,35 +367,40 @@ uint16_t FrSky_Rx_callback()
|
||||
case FRSKY_RX_BIND:
|
||||
if(len >= packet_length) {
|
||||
CC2500_ReadData(packet, packet_length);
|
||||
if (frskyx_rx_check_crc()) {
|
||||
if (packet[5] <= 0x2D) {
|
||||
for (ch = 0; ch < 5; ch++)
|
||||
hopping_frequency[packet[5]+ch] = packet[6+ch];
|
||||
state |= 1 << (packet[5] / 5);
|
||||
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;
|
||||
}
|
||||
}
|
||||
if (state == 0x3ff) {
|
||||
debugln("bind complete");
|
||||
frsky_rx_calibrate();
|
||||
rx_tx_addr[0] = packet[3]; // TXID
|
||||
rx_tx_addr[1] = packet[4]; // TXID
|
||||
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);
|
||||
eeprom_write_byte((EE_ADDR)temp++, rx_tx_addr[0]);
|
||||
eeprom_write_byte((EE_ADDR)temp++, rx_tx_addr[1]);
|
||||
eeprom_write_byte((EE_ADDR)temp++, rx_tx_addr[2]);
|
||||
eeprom_write_byte((EE_ADDR)temp++, frsky_rx_finetune);
|
||||
for (ch = 0; ch < 47; ch++)
|
||||
eeprom_write_byte((EE_ADDR)temp++, hopping_frequency[ch]);
|
||||
BIND_DONE;
|
||||
}
|
||||
frsky_rx_strobe_rx();
|
||||
}
|
||||
return 1000;
|
||||
|
||||
@@ -16,7 +16,7 @@ Multiprotocol is distributed in the hope that it will be useful,
|
||||
|
||||
#if defined(GD00X_NRF24L01_INO)
|
||||
|
||||
#include "iface_xn297l.h"
|
||||
#include "iface_nrf250k.h"
|
||||
|
||||
//#define FORCE_GD00X_ORIGINAL_ID
|
||||
|
||||
|
||||
@@ -146,6 +146,11 @@ static void __attribute__((unused)) HITEC_build_packet()
|
||||
break;
|
||||
case 0x7B:
|
||||
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;
|
||||
}
|
||||
if(sub_protocol==MINIMA)
|
||||
@@ -302,8 +307,8 @@ uint16_t ReadHITEC()
|
||||
{ // bind packet: 0A,00,E5,F2,7X,05,06,07,08,09,00
|
||||
debug(",bind");
|
||||
boolean check=true;
|
||||
for(uint8_t i=5;i<=10;i++)
|
||||
if(packet_in[i]!=i%10) check=false;
|
||||
for(uint8_t i=5;i<10;i++)
|
||||
if(packet_in[i]!=i) check=false;
|
||||
if((packet_in[4]&0xF0)==0x70 && check)
|
||||
{
|
||||
bind_phase=packet_in[4]+1;
|
||||
|
||||
@@ -16,7 +16,7 @@ Multiprotocol is distributed in the hope that it will be useful,
|
||||
|
||||
#if defined(KF606_NRF24L01_INO)
|
||||
|
||||
#include "iface_xn297l.h"
|
||||
#include "iface_nrf250k.h"
|
||||
|
||||
//#define FORCE_KF606_ORIGINAL_ID
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#if defined(MJXQ_NRF24L01_INO)
|
||||
|
||||
#include "iface_nrf24l01.h"
|
||||
#include "iface_xn297l.h"
|
||||
#include "iface_nrf250k.h"
|
||||
|
||||
#define MJXQ_BIND_COUNT 150
|
||||
#define MJXQ_PACKET_PERIOD 4000 // Timeout for callback in uSec
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
13,CG023,CG023,YD829
|
||||
14,Bayang,Bayang,H8S3D,X16_AH,IRDRONE,DHD_D4
|
||||
15,FrskyX,CH_16,CH_8,EU_16,EU_8
|
||||
16,ESky
|
||||
16,ESky,Std,ET4
|
||||
17,MT99xx,MT,H7,YZ,LS,FY805
|
||||
18,MJXq,WLH08,X600,X800,H26D,E010,H26WH,PHOENIX
|
||||
19,Shenqi
|
||||
@@ -32,7 +32,7 @@
|
||||
32,GW008
|
||||
33,DM002
|
||||
34,CABELL,CAB_V3,C_TELEM,-,-,-,-,F_SAFE,UNBIND
|
||||
35,ESKY150
|
||||
35,ESKY150,4CH,7CH
|
||||
36,H8_3D,H8_3D,H20H,H20Mini,H30Mini
|
||||
37,CORONA,COR_V1,COR_V2,FD_V3
|
||||
38,CFlie
|
||||
@@ -43,7 +43,7 @@
|
||||
43,Traxxas,RX6519
|
||||
44,NCC1701
|
||||
45,E01X,E012,E015,E016H
|
||||
46,V911S
|
||||
46,V911S,V911S,E119
|
||||
47,GD00X,GD_V1,GD_V2
|
||||
48,V761
|
||||
49,KF606
|
||||
@@ -56,4 +56,10 @@
|
||||
56,AFHDS2A_RX
|
||||
57,HoTT
|
||||
58,FX816,P38
|
||||
63,XN_DUMP,250K,1M,2M
|
||||
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
|
||||
|
||||
@@ -30,6 +30,7 @@ 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";
|
||||
@@ -72,7 +73,12 @@ 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";
|
||||
@@ -108,8 +114,13 @@ 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 ";
|
||||
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
|
||||
{
|
||||
@@ -159,7 +170,7 @@ const mm_protocol_definition multi_protocols[] = {
|
||||
{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_NONE },
|
||||
{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 },
|
||||
@@ -173,8 +184,11 @@ const mm_protocol_definition multi_protocols[] = {
|
||||
#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, 0, NO_SUBTYPE, OPTION_NONE },
|
||||
{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 },
|
||||
@@ -228,7 +242,7 @@ const mm_protocol_definition multi_protocols[] = {
|
||||
{PROTO_CABELL, STR_CABELL, 8, STR_SUBTYPE_CABELL, OPTION_OPTION },
|
||||
#endif
|
||||
#if defined(ESKY150_NRF24L01_INO)
|
||||
{PROTO_ESKY150, STR_ESKY150, 0, NO_SUBTYPE, OPTION_NONE },
|
||||
{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 },
|
||||
@@ -261,7 +275,7 @@ const mm_protocol_definition multi_protocols[] = {
|
||||
{PROTO_E01X, STR_E01X, 3, STR_SUBTYPE_E01X, OPTION_OPTION },
|
||||
#endif
|
||||
#if defined(V911S_NRF24L01_INO)
|
||||
{PROTO_V911S, STR_V911S, 0, NO_SUBTYPE, OPTION_NONE },
|
||||
{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 },
|
||||
@@ -299,8 +313,23 @@ const mm_protocol_definition multi_protocols[] = {
|
||||
#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, 3, STR_SUBTYPE_XN297DUMP, OPTION_RFCHAN },
|
||||
{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 }
|
||||
};
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#define VERSION_MAJOR 1
|
||||
#define VERSION_MINOR 3
|
||||
#define VERSION_REVISION 0
|
||||
#define VERSION_PATCH_LEVEL 45
|
||||
#define VERSION_PATCH_LEVEL 76
|
||||
|
||||
//******************
|
||||
// Protocols
|
||||
@@ -85,7 +85,13 @@ enum PROTOCOLS
|
||||
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_FRSKYX2 = 64, // =>CC2500
|
||||
PROTO_FRSKY_R9 = 65, // =>SX1276
|
||||
};
|
||||
|
||||
enum Flysky
|
||||
@@ -208,6 +214,13 @@ enum FRSKYX
|
||||
EU_16 = 2,
|
||||
EU_8 = 3,
|
||||
};
|
||||
enum FRSKYX2
|
||||
{
|
||||
FRSKYX2_CH_16 = 0,
|
||||
FRSKYX2_CH_8 = 1,
|
||||
FRSKYX2_EU_16 = 2,
|
||||
FRSKYX2_EU_8 = 3,
|
||||
};
|
||||
enum HONTAI
|
||||
{
|
||||
HONTAI = 0,
|
||||
@@ -292,6 +305,40 @@ enum TRAXXAS
|
||||
{
|
||||
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 P_HIGH 1
|
||||
@@ -332,6 +379,12 @@ enum MultiPacketTypes
|
||||
// Macros
|
||||
#define NOP() __asm__ __volatile__("nop")
|
||||
|
||||
//***************
|
||||
//*** Tests ***
|
||||
//***************
|
||||
#define IS_FAILSAFE_PROTOCOL ( (protocol==PROTO_HISKY && sub_protocol==HK310) || protocol==PROTO_AFHDS2A || protocol==PROTO_DEVO || protocol==PROTO_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 ***
|
||||
//***************
|
||||
@@ -596,7 +649,8 @@ enum {
|
||||
#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 CONFIG_EEPROM_OFFSET 762 // Current configuration of the multimodule
|
||||
#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 ***
|
||||
@@ -673,6 +727,13 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
||||
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
|
||||
AutoBindBit=> 0x40 1=Yes /0=No
|
||||
RangeCheck=> 0x20 1=Yes /0=No
|
||||
@@ -814,6 +875,23 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
||||
RED_SLOW 1
|
||||
sub_protocol==TRAXXAS
|
||||
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
|
||||
Stream[3] = option_protocol;
|
||||
|
||||
@@ -179,7 +179,7 @@ volatile uint8_t rx_idx=0, rx_len=0;
|
||||
|
||||
|
||||
// Telemetry
|
||||
#define TELEMETRY_BUFFER_SIZE 30
|
||||
#define TELEMETRY_BUFFER_SIZE 32
|
||||
uint8_t packet_in[TELEMETRY_BUFFER_SIZE];//telemetry receiving packets
|
||||
#if defined(TELEMETRY)
|
||||
#ifdef MULTI_SYNC
|
||||
@@ -227,8 +227,9 @@ uint8_t packet_in[TELEMETRY_BUFFER_SIZE];//telemetry receiving packets
|
||||
#endif
|
||||
|
||||
//RX protocols
|
||||
#if defined(AFHDS2A_RX_A7105_INO) || defined(FRSKY_RX_CC2500_INO)
|
||||
#if defined(AFHDS2A_RX_A7105_INO) || defined(FRSKY_RX_CC2500_INO) || defined(BAYANG_RX_NRF24L01_INO)
|
||||
bool rx_data_started;
|
||||
bool rx_data_received;
|
||||
bool rx_disable_lna;
|
||||
uint16_t rx_rc_chan[16];
|
||||
#endif
|
||||
@@ -330,6 +331,22 @@ void setup()
|
||||
pinMode(S2_pin,INPUT_PULLUP);
|
||||
pinMode(S3_pin,INPUT_PULLUP);
|
||||
pinMode(S4_pin,INPUT_PULLUP);
|
||||
|
||||
#if defined ENABLE_DIRECT_INPUTS
|
||||
#if defined (DI1_PIN)
|
||||
pinMode(DI1_PIN,INPUT_PULLUP);
|
||||
#endif
|
||||
#if defined (DI2_PIN)
|
||||
pinMode(DI2_PIN,INPUT_PULLUP);
|
||||
#endif
|
||||
#if defined (DI3_PIN)
|
||||
pinMode(DI3_PIN,INPUT_PULLUP);
|
||||
#endif
|
||||
#if defined (DI4_PIN)
|
||||
pinMode(DI4_PIN,INPUT_PULLUP);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//Random pins
|
||||
pinMode(PB0, INPUT_ANALOG); // set up pin for analog input
|
||||
|
||||
@@ -497,6 +514,11 @@ void setup()
|
||||
option = FORCE_FRSKYX_TUNING; // Use config-defined tuning value for FrSkyX
|
||||
else
|
||||
#endif
|
||||
#if defined(FORCE_FRSKYX2_TUNING) && defined(FRSKYX2_CC2500_INO)
|
||||
if(protocol==PROTO_FRSKYX2)
|
||||
option = FORCE_FRSKYX2_TUNING; // Use config-defined tuning value for FrSkyX2
|
||||
else
|
||||
#endif
|
||||
#if defined(FORCE_SFHSS_TUNING) && defined(SFHSS_CC2500_INO)
|
||||
if (protocol==PROTO_SFHSS)
|
||||
option = FORCE_SFHSS_TUNING; // Use config-defined tuning value for SFHSS
|
||||
@@ -665,8 +687,29 @@ bool Update_All()
|
||||
if(mode_select!=MODE_SERIAL && IS_PPM_FLAG_on) // PPM mode and a full frame has been received
|
||||
{
|
||||
uint32_t chan_or=chan_order;
|
||||
uint8_t ch;
|
||||
for(uint8_t i=0;i<PPM_chan_max;i++)
|
||||
uint8_t ch;
|
||||
uint8_t channelsCount = PPM_chan_max;
|
||||
|
||||
#ifdef ENABLE_DIRECT_INPUTS
|
||||
#ifdef DI_CH1_read
|
||||
PPM_data[channelsCount] = DI_CH1_read;
|
||||
channelsCount++;
|
||||
#endif
|
||||
#ifdef DI_CH2_read
|
||||
PPM_data[channelsCount] = DI_CH2_read;
|
||||
channelsCount++;
|
||||
#endif
|
||||
#ifdef DI_CH3_read
|
||||
PPM_data[channelsCount] = DI_CH3_read;
|
||||
channelsCount++;
|
||||
#endif
|
||||
#ifdef DI_CH4_read
|
||||
PPM_data[channelsCount] = DI_CH4_read;
|
||||
channelsCount++;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
for(uint8_t i=0;i<channelsCount;i++)
|
||||
{ // update servo data without interrupts to prevent bad read
|
||||
uint16_t val;
|
||||
cli(); // disable global int
|
||||
@@ -699,7 +742,7 @@ bool Update_All()
|
||||
update_led_status();
|
||||
#if defined(TELEMETRY)
|
||||
#if ( !( defined(MULTI_TELEMETRY) || defined(MULTI_STATUS) ) )
|
||||
if( (protocol == PROTO_FRSKY_RX) || (protocol == PROTO_SCANNER) || (protocol==PROTO_FRSKYD) || (protocol==PROTO_BAYANG) || (protocol==PROTO_NCC1701) || (protocol==PROTO_BUGS) || (protocol==PROTO_BUGSMINI) || (protocol==PROTO_HUBSAN) || (protocol==PROTO_AFHDS2A) || (protocol==PROTO_FRSKYX) || (protocol==PROTO_DSM) || (protocol==PROTO_CABELL) || (protocol==PROTO_HITEC) || (protocol==PROTO_HOTT))
|
||||
if((protocol == PROTO_BAYANG_RX) || (protocol == PROTO_AFHDS2A_RX) || (protocol == PROTO_FRSKY_RX) || (protocol == PROTO_SCANNER) || (protocol==PROTO_FRSKYD) || (protocol==PROTO_BAYANG) || (protocol==PROTO_NCC1701) || (protocol==PROTO_BUGS) || (protocol==PROTO_BUGSMINI) || (protocol==PROTO_HUBSAN) || (protocol==PROTO_AFHDS2A) || (protocol==PROTO_FRSKYX) || (protocol==PROTO_DSM) || (protocol==PROTO_CABELL) || (protocol==PROTO_HITEC) || (protocol==PROTO_HOTT) || (protocol==PROTO_FRSKYX2))
|
||||
#endif
|
||||
if(IS_DISABLE_TELEM_off)
|
||||
TelemetryUpdate();
|
||||
@@ -991,7 +1034,7 @@ static void protocol_init()
|
||||
TX_RX_PAUSE_off;
|
||||
TX_MAIN_PAUSE_off;
|
||||
tx_resume();
|
||||
#if defined(AFHDS2A_RX_A7105_INO) || defined(FRSKY_RX_CC2500_INO)
|
||||
#if defined(AFHDS2A_RX_A7105_INO) || defined(FRSKY_RX_CC2500_INO) || defined(BAYANG_RX_NRF24L01_INO)
|
||||
for(uint8_t ch=0; ch<16; ch++)
|
||||
rx_rc_chan[ch] = 1024;
|
||||
#endif
|
||||
@@ -1057,6 +1100,13 @@ static void protocol_init()
|
||||
remote_callback = AFHDS2A_Rx_callback;
|
||||
break;
|
||||
#endif
|
||||
#if defined(PELIKAN_A7105_INO)
|
||||
case PROTO_PELIKAN:
|
||||
PE1_off; //antenna RF1
|
||||
next_callback = initPelikan();
|
||||
remote_callback = ReadPelikan;
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
#ifdef CC2500_INSTALLED
|
||||
#if defined(FRSKYD_CC2500_INO)
|
||||
@@ -1083,6 +1133,14 @@ static void protocol_init()
|
||||
remote_callback = ReadFrSkyX;
|
||||
break;
|
||||
#endif
|
||||
#if defined(FRSKYX2_CC2500_INO)
|
||||
case PROTO_FRSKYX2:
|
||||
PE1_off; //antenna RF2
|
||||
PE2_on;
|
||||
next_callback = initFrSkyX2();
|
||||
remote_callback = ReadFrSkyX2;
|
||||
break;
|
||||
#endif
|
||||
#if defined(SFHSS_CC2500_INO)
|
||||
case PROTO_SFHSS:
|
||||
PE1_off; //antenna RF2
|
||||
@@ -1421,6 +1479,24 @@ static void protocol_init()
|
||||
remote_callback = FX816_callback;
|
||||
break;
|
||||
#endif
|
||||
#if defined(BAYANG_RX_NRF24L01_INO)
|
||||
case PROTO_BAYANG_RX:
|
||||
next_callback=initBayang_Rx();
|
||||
remote_callback = Bayang_Rx_callback;
|
||||
break;
|
||||
#endif
|
||||
#if defined(TIGER_NRF24L01_INO)
|
||||
case PROTO_TIGER:
|
||||
next_callback=initTIGER();
|
||||
remote_callback = TIGER_callback;
|
||||
break;
|
||||
#endif
|
||||
#if defined(XK_NRF24L01_INO)
|
||||
case PROTO_XK:
|
||||
next_callback=initXK();
|
||||
remote_callback = XK_callback;
|
||||
break;
|
||||
#endif
|
||||
#if defined(XN297DUMP_NRF24L01_INO)
|
||||
case PROTO_XN297DUMP:
|
||||
next_callback=initXN297Dump();
|
||||
@@ -1428,6 +1504,14 @@ static void protocol_init()
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
#ifdef SX1276_INSTALLED
|
||||
#if defined(FRSKYR9_SX1276_INO)
|
||||
case PROTO_FRSKY_R9:
|
||||
next_callback = initFrSkyR9();
|
||||
remote_callback = FrSkyR9_callback;
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
debugln("Protocol selected: %d, sub proto %d, rxnum %d, option %d", protocol, sub_protocol, RX_num, option);
|
||||
#ifdef MULTI_NAMES
|
||||
@@ -1540,6 +1624,11 @@ void update_serial_data()
|
||||
option=FORCE_FRSKYX_TUNING; // Use config-defined tuning value for FrSkyX
|
||||
else
|
||||
#endif
|
||||
#if defined(FORCE_FRSKYX2_TUNING) && defined(FRSKYX2_CC2500_INO)
|
||||
if(protocol==PROTO_FRSKYX2)
|
||||
option=FORCE_FRSKYX2_TUNING; // Use config-defined tuning value for FrSkyX2
|
||||
else
|
||||
#endif
|
||||
#if defined(FORCE_SFHSS_TUNING) && defined(SFHSS_CC2500_INO)
|
||||
if (protocol==PROTO_SFHSS)
|
||||
option=FORCE_SFHSS_TUNING; // Use config-defined tuning value for SFHSS
|
||||
@@ -1615,24 +1704,6 @@ void update_serial_data()
|
||||
#endif
|
||||
}
|
||||
|
||||
if(prev_ch_mapping!=IS_DISABLE_CH_MAP_on)
|
||||
{
|
||||
prev_ch_mapping=IS_DISABLE_CH_MAP_on;
|
||||
if(IS_DISABLE_CH_MAP_on)
|
||||
{
|
||||
for(uint8_t i=0;i<4;i++)
|
||||
CH_AETR[i]=CH_TAER[i]=CH_EATR[i]=i;
|
||||
debugln("DISABLE_CH_MAP_on");
|
||||
}
|
||||
else
|
||||
{
|
||||
CH_AETR[0]=AILERON;CH_AETR[1]=ELEVATOR;CH_AETR[2]=THROTTLE;CH_AETR[3]=RUDDER;
|
||||
CH_TAER[0]=THROTTLE;CH_TAER[1]=AILERON;CH_TAER[2]=ELEVATOR;CH_TAER[3]=RUDDER;
|
||||
CH_EATR[0]=ELEVATOR;CH_EATR[1]=AILERON;CH_EATR[2]=THROTTLE;CH_EATR[3]=RUDDER;
|
||||
debugln("DISABLE_CH_MAP_off");
|
||||
}
|
||||
}
|
||||
|
||||
if( (rx_ok_buff[0] != cur_protocol[0]) || ((rx_ok_buff[1]&0x5F) != (cur_protocol[1]&0x5F)) || ( (rx_ok_buff[2]&0x7F) != (cur_protocol[2]&0x7F) ) )
|
||||
{ // New model has been selected
|
||||
CHANGE_PROTOCOL_FLAG_on; //change protocol
|
||||
@@ -1660,8 +1731,8 @@ void update_serial_data()
|
||||
else
|
||||
if( ((rx_ok_buff[1]&0x80)==0) && ((cur_protocol[1]&0x80)!=0) ) // Bind flag has been reset
|
||||
{ // Request protocol to end bind
|
||||
#if defined(FRSKYD_CC2500_INO) || defined(FRSKYX_CC2500_INO) || defined(FRSKYV_CC2500_INO) || defined(AFHDS2A_A7105_INO)
|
||||
if(protocol==PROTO_FRSKYD || protocol==PROTO_FRSKYX || protocol==PROTO_FRSKYV || protocol==PROTO_AFHDS2A )
|
||||
#if defined(FRSKYD_CC2500_INO) || defined(FRSKYX_CC2500_INO) || defined(FRSKYV_CC2500_INO) || defined(AFHDS2A_A7105_INO) || defined(FRSKYR9_SX1276_INO)
|
||||
if(protocol==PROTO_FRSKYD || protocol==PROTO_FRSKYX || protocol==PROTO_FRSKYV || protocol==PROTO_AFHDS2A || protocol==PROTO_FRSKY_R9 )
|
||||
BIND_DONE;
|
||||
else
|
||||
#endif
|
||||
@@ -1673,6 +1744,27 @@ void update_serial_data()
|
||||
for(uint8_t i=0;i<3;i++)
|
||||
cur_protocol[i] = rx_ok_buff[i];
|
||||
|
||||
//disable channel mapping
|
||||
if(!IS_CHMAP_PROTOCOL) //not a protocol supporting ch map to be disabled
|
||||
DISABLE_CH_MAP_off;
|
||||
if(prev_ch_mapping!=IS_DISABLE_CH_MAP_on)
|
||||
{
|
||||
prev_ch_mapping=IS_DISABLE_CH_MAP_on;
|
||||
if(IS_DISABLE_CH_MAP_on)
|
||||
{
|
||||
for(uint8_t i=0;i<4;i++)
|
||||
CH_AETR[i]=CH_TAER[i]=CH_EATR[i]=i;
|
||||
debugln("DISABLE_CH_MAP_on");
|
||||
}
|
||||
else
|
||||
{
|
||||
CH_AETR[0]=AILERON;CH_AETR[1]=ELEVATOR;CH_AETR[2]=THROTTLE;CH_AETR[3]=RUDDER;
|
||||
CH_TAER[0]=THROTTLE;CH_TAER[1]=AILERON;CH_TAER[2]=ELEVATOR;CH_TAER[3]=RUDDER;
|
||||
CH_EATR[0]=ELEVATOR;CH_EATR[1]=AILERON;CH_EATR[2]=THROTTLE;CH_EATR[3]=RUDDER;
|
||||
debugln("DISABLE_CH_MAP_off");
|
||||
}
|
||||
}
|
||||
|
||||
// decode channel/failsafe values
|
||||
volatile uint8_t *p=rx_ok_buff+3;
|
||||
uint8_t dec=-3;
|
||||
@@ -1699,8 +1791,14 @@ void update_serial_data()
|
||||
#endif
|
||||
if(rx_len>27)
|
||||
{ // Data available for the current protocol
|
||||
#if defined FRSKYX_CC2500_INO || defined FRSKYX2_CC2500_INO
|
||||
if((protocol==PROTO_FRSKYX || protocol==PROTO_FRSKYX2) && rx_len==28)
|
||||
{//Protocol waiting for 1 byte during bind
|
||||
binding_idx=rx_ok_buff[27];
|
||||
}
|
||||
#endif
|
||||
#ifdef SPORT_SEND
|
||||
if(protocol==PROTO_FRSKYX && rx_len==35)
|
||||
if((protocol==PROTO_FRSKYX || protocol==PROTO_FRSKYX2) && rx_len==35)
|
||||
{//Protocol waiting for 8 bytes
|
||||
#define BYTE_STUFF 0x7D
|
||||
#define STUFF_MASK 0x20
|
||||
@@ -1781,6 +1879,9 @@ void modules_reset()
|
||||
#ifdef NRF24L01_INSTALLED
|
||||
NRF24L01_Reset();
|
||||
#endif
|
||||
#ifdef SX1276_INSTALLED
|
||||
SX1276_Reset();
|
||||
#endif
|
||||
|
||||
//Wait for every component to reset
|
||||
delayMilliseconds(100);
|
||||
@@ -1985,12 +2086,12 @@ void PPM_Telemetry_serial_init()
|
||||
{
|
||||
if( (protocol==PROTO_FRSKYD) || (protocol==PROTO_HUBSAN) || (protocol==PROTO_AFHDS2A) || (protocol==PROTO_BAYANG)|| (protocol==PROTO_NCC1701) || (protocol==PROTO_CABELL) || (protocol==PROTO_HITEC) || (protocol==PROTO_BUGS) || (protocol==PROTO_BUGSMINI)
|
||||
#ifdef TELEMETRY_FRSKYX_TO_FRSKYD
|
||||
|| (protocol==PROTO_FRSKYX)
|
||||
|| (protocol==PROTO_FRSKYX) || (protocol==PROTO_FRSKYX2)
|
||||
#endif
|
||||
)
|
||||
initTXSerial( SPEED_9600 ) ;
|
||||
#ifndef TELEMETRY_FRSKYX_TO_FRSKYD
|
||||
if(protocol==PROTO_FRSKYX)
|
||||
if(protocol==PROTO_FRSKYX || protocol==PROTO_FRSKYX2)
|
||||
initTXSerial( SPEED_57600 ) ;
|
||||
#endif
|
||||
if(protocol==PROTO_DSM)
|
||||
|
||||
@@ -505,7 +505,7 @@ boolean XN297_ReadPayload(uint8_t* msg, uint8_t len)
|
||||
//process address
|
||||
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)
|
||||
b_in ^= xn297_scramble[i];
|
||||
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)
|
||||
{
|
||||
{ //!!! 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 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];
|
||||
if(xn297_scramble_enabled)
|
||||
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) |
|
||||
(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
|
||||
|
||||
438
Multiprotocol/NRF250K_EMU.ino
Normal file
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
|
||||
239
Multiprotocol/Pelikan_a7105.ino
Normal file
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
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
#if defined(SLT_NRF24L01_INO)
|
||||
|
||||
#include "iface_nrf24l01.h"
|
||||
#include "iface_nrf250k.h"
|
||||
|
||||
//#define SLT_Q200_FORCE_ID
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#define SLT_PAYLOADSIZE_V2 11
|
||||
#define SLT_NFREQCHANNELS 15
|
||||
#define SLT_TXID_SIZE 4
|
||||
#define SLT_BIND_CHANNEL 0x50
|
||||
|
||||
enum{
|
||||
// flags going to packet[6] (Q200)
|
||||
@@ -48,30 +49,13 @@ enum {
|
||||
SLT_DATA2,
|
||||
SLT_DATA3,
|
||||
SLT_BIND1,
|
||||
SLT_BIND2
|
||||
SLT_BIND2,
|
||||
};
|
||||
|
||||
static void __attribute__((unused)) SLT_init()
|
||||
{
|
||||
NRF24L01_Initialize();
|
||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO)); // 2-bytes CRC, radio off
|
||||
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);
|
||||
NRF250K_Init();
|
||||
NRF250K_SetTXAddr(rx_tx_addr, SLT_TXID_SIZE);
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
if (packet_sent)
|
||||
while (!(NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_TX_DS)));
|
||||
while (!NRF250K_IsPacketSent());
|
||||
packet_sent = 0;
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) SLT_send_packet(uint8_t len)
|
||||
{
|
||||
SLT_wait_radio();
|
||||
NRF24L01_FlushTx();
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, _BV(NRF24L01_07_TX_DS) | _BV(NRF24L01_07_RX_DR) | _BV(NRF24L01_07_MAX_RT));
|
||||
NRF24L01_WritePayload(packet, len);
|
||||
NRF250K_WritePayload(packet, len);
|
||||
packet_sent = 1;
|
||||
}
|
||||
|
||||
@@ -132,7 +120,8 @@ static void __attribute__((unused)) SLT_build_packet()
|
||||
static uint8_t calib_counter=0;
|
||||
|
||||
// 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)
|
||||
hopping_frequency_no = 0;
|
||||
|
||||
@@ -183,23 +172,16 @@ static void __attribute__((unused)) SLT_build_packet()
|
||||
static void __attribute__((unused)) SLT_send_bind_packet()
|
||||
{
|
||||
SLT_wait_radio();
|
||||
BIND_IN_PROGRESS; //Limit TX power to bind level
|
||||
NRF24L01_SetPower();
|
||||
NRF250K_Hopping(SLT_NFREQCHANNELS); //Bind channel
|
||||
BIND_IN_PROGRESS; //Limit TX power to bind level
|
||||
NRF250K_SetPower();
|
||||
BIND_DONE;
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, (uint8_t *)"\x7E\xB8\x63\xA9", SLT_TXID_SIZE);
|
||||
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, 0x50);
|
||||
NRF250K_SetTXAddr((uint8_t *)"\x7E\xB8\x63\xA9", SLT_TXID_SIZE);
|
||||
memcpy((void*)packet,(void*)rx_tx_addr,SLT_TXID_SIZE);
|
||||
if(phase==SLT_BIND2)
|
||||
SLT_send_packet(SLT_TXID_SIZE);
|
||||
else // SLT_BIND1
|
||||
SLT_send_packet(SLT_PAYLOADSIZE_V2);
|
||||
|
||||
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
|
||||
@@ -217,6 +199,8 @@ uint16_t SLT_callback()
|
||||
telemetry_set_input_sync(sub_protocol==SLT_V1?20000:13730);
|
||||
#endif
|
||||
SLT_build_packet();
|
||||
NRF250K_SetPower(); //Change power level
|
||||
NRF250K_SetTXAddr(rx_tx_addr, SLT_TXID_SIZE);
|
||||
phase++;
|
||||
return SLT_TIMING_BUILD;
|
||||
case SLT_DATA1:
|
||||
@@ -253,7 +237,6 @@ uint16_t SLT_callback()
|
||||
}
|
||||
else
|
||||
{// Continue to send normal packets
|
||||
NRF24L01_SetPower(); // Set tx_power
|
||||
phase = SLT_BUILD;
|
||||
if(sub_protocol==SLT_V1)
|
||||
return 20000-SLT_TIMING_BUILD;
|
||||
@@ -289,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;*/
|
||||
#endif
|
||||
}
|
||||
SLT_set_freq();
|
||||
SLT_init();
|
||||
SLT_set_freq();
|
||||
phase = SLT_BUILD;
|
||||
return 50000;
|
||||
}
|
||||
|
||||
177
Multiprotocol/SX1276_SPI.ino
Normal file
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
|
||||
@@ -125,7 +125,11 @@ static void multi_send_status()
|
||||
multi_send_header(MULTI_TELEMETRY_STATUS, 24);
|
||||
else
|
||||
#endif
|
||||
#ifdef MULTI_TELEMETRY
|
||||
multi_send_header(MULTI_TELEMETRY_STATUS, 6);
|
||||
#else
|
||||
multi_send_header(MULTI_TELEMETRY_STATUS, 6);
|
||||
#endif
|
||||
|
||||
// Build flags
|
||||
uint8_t flags=0;
|
||||
@@ -136,50 +140,41 @@ static void multi_send_status()
|
||||
if (remote_callback != 0)
|
||||
{
|
||||
flags |= 0x04;
|
||||
#ifdef MULTI_NAMES
|
||||
if((sub_protocol&0x07) && multi_protocols_index != 0xFF)
|
||||
{
|
||||
uint8_t nbr=multi_protocols[multi_protocols_index].nbrSubProto;
|
||||
if(protocol==PROTO_DSM) nbr++; //Auto sub_protocol
|
||||
if((sub_protocol&0x07)>=nbr)
|
||||
flags &= ~0x04; //Invalid sub protocol
|
||||
}
|
||||
#endif
|
||||
if (IS_WAIT_BIND_on)
|
||||
flags |= 0x10;
|
||||
else
|
||||
if (IS_BIND_IN_PROGRESS)
|
||||
flags |= 0x08;
|
||||
switch (protocol)
|
||||
{
|
||||
case PROTO_HISKY:
|
||||
if(sub_protocol!=HK310)
|
||||
break;
|
||||
case PROTO_AFHDS2A:
|
||||
case PROTO_DEVO:
|
||||
case PROTO_SFHSS:
|
||||
case PROTO_WK2x01:
|
||||
#ifdef FAILSAFE_ENABLE
|
||||
flags |= 0x20; //Failsafe supported
|
||||
#endif
|
||||
case PROTO_DSM:
|
||||
case PROTO_SLT:
|
||||
case PROTO_FLYSKY:
|
||||
case PROTO_ESKY:
|
||||
case PROTO_J6PRO:
|
||||
flags |= 0x40; //Disable_ch_mapping supported
|
||||
break;
|
||||
#ifdef FAILSAFE_ENABLE
|
||||
case PROTO_HOTT:
|
||||
case PROTO_FRSKYX:
|
||||
flags |= 0x20; //Failsafe supported
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
if(IS_CHMAP_PROTOCOL)
|
||||
flags |= 0x40; //Disable_ch_mapping supported
|
||||
#ifdef FAILSAFE_ENABLE
|
||||
if(IS_FAILSAFE_PROTOCOL)
|
||||
flags |= 0x20; //Failsafe supported
|
||||
#endif
|
||||
if(IS_DATA_BUFFER_LOW_on)
|
||||
flags |= 0x80;
|
||||
}
|
||||
Serial_write(flags);
|
||||
|
||||
|
||||
// Version number example: 1.1.6.1
|
||||
Serial_write(VERSION_MAJOR);
|
||||
Serial_write(VERSION_MINOR);
|
||||
Serial_write(VERSION_REVISION);
|
||||
Serial_write(VERSION_PATCH_LEVEL);
|
||||
|
||||
// Channel order
|
||||
Serial_write(RUDDER<<6|THROTTLE<<4|ELEVATOR<<2|AILERON);
|
||||
#ifdef MULTI_TELEMETRY
|
||||
// Channel order
|
||||
Serial_write(RUDDER<<6|THROTTLE<<4|ELEVATOR<<2|AILERON);
|
||||
#endif
|
||||
|
||||
#ifdef MULTI_NAMES
|
||||
if(multi_protocols_index != 0xFF)
|
||||
@@ -197,8 +192,8 @@ static void multi_send_status()
|
||||
for(uint8_t i=0;i<7;i++)
|
||||
Serial_write(multi_protocols[multi_protocols_index].ProtoString[i]); // protocol name
|
||||
// Sub-protocol
|
||||
uint8_t nbr=multi_protocols[multi_protocols_index].nbrSubProto | (multi_protocols[multi_protocols_index].optionType<<4); // add option display type
|
||||
Serial_write(nbr); // number of sub protocols
|
||||
uint8_t nbr=multi_protocols[multi_protocols_index].nbrSubProto;
|
||||
Serial_write(nbr | (multi_protocols[multi_protocols_index].optionType<<4)); // number of sub protocols && option type
|
||||
uint8_t j=0;
|
||||
if(nbr && (sub_protocol&0x07)<nbr)
|
||||
{
|
||||
@@ -258,7 +253,7 @@ static void multi_send_status()
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined (FRSKY_RX_TELEMETRY) || defined (AFHDS2A_RX_TELEMETRY)
|
||||
#if defined (FRSKY_RX_TELEMETRY) || defined (AFHDS2A_RX_TELEMETRY) || defined (BAYANG_RX_TELEMETRY)
|
||||
void receiver_channels_frame()
|
||||
{
|
||||
uint16_t len = packet_in[3] * 11; // 11 bit per channel
|
||||
@@ -930,11 +925,11 @@ void TelemetryUpdate()
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined (FRSKY_RX_TELEMETRY) || defined(AFHDS2A_RX_TELEMETRY)
|
||||
if (telemetry_link && (protocol == PROTO_FRSKY_RX || protocol == PROTO_AFHDS2A_RX))
|
||||
#if defined (FRSKY_RX_TELEMETRY) || defined(AFHDS2A_RX_TELEMETRY) || defined (BAYANG_RX_TELEMETRY)
|
||||
if ((telemetry_link & 1) && (protocol == PROTO_FRSKY_RX || protocol == PROTO_AFHDS2A_RX || protocol == PROTO_BAYANG_RX))
|
||||
{
|
||||
receiver_channels_frame();
|
||||
telemetry_link = 0;
|
||||
telemetry_link &= ~1;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
182
Multiprotocol/Tiger_nrf24l01.ino
Normal file
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
|
||||
*/
|
||||
@@ -1,180 +0,0 @@
|
||||
/*
|
||||
This project is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Multiprotocol is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
// compatible with V911S
|
||||
|
||||
#if defined(V911S_NRF24L01_INO)
|
||||
|
||||
#include "iface_nrf24l01.h"
|
||||
|
||||
//#define V911S_ORIGINAL_ID
|
||||
|
||||
#define V911S_PACKET_PERIOD 5000
|
||||
#define V911S_BIND_PACKET_PERIOD 3300
|
||||
#define V911S_INITIAL_WAIT 500
|
||||
#define V911S_PACKET_SIZE 16
|
||||
#define V911S_RF_BIND_CHANNEL 35
|
||||
#define V911S_NUM_RF_CHANNELS 8
|
||||
#define V911S_BIND_COUNT 200
|
||||
|
||||
// flags going to packet[1]
|
||||
#define V911S_FLAG_EXPERT 0x04
|
||||
// flags going to packet[2]
|
||||
#define V911S_FLAG_CALIB 0x01
|
||||
|
||||
static void __attribute__((unused)) V911S_send_packet(uint8_t bind)
|
||||
{
|
||||
if(bind)
|
||||
{
|
||||
packet[0] = 0x42;
|
||||
packet[1] = 0x4E;
|
||||
packet[2] = 0x44;
|
||||
for(uint8_t i=0;i<5;i++)
|
||||
packet[i+3] = rx_tx_addr[i];
|
||||
for(uint8_t i=0;i<8;i++)
|
||||
packet[i+8] = hopping_frequency[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t channel=hopping_frequency_no;
|
||||
if(rf_ch_num&1)
|
||||
{
|
||||
if((hopping_frequency_no&1)==0)
|
||||
channel+=8;
|
||||
channel>>=1;
|
||||
}
|
||||
if(rf_ch_num&2)
|
||||
channel=7-channel;
|
||||
packet[ 0]=(rf_ch_num<<3)|channel;
|
||||
packet[ 1]=V911S_FLAG_EXPERT; // short press on left button
|
||||
packet[ 2]=GET_FLAG(CH5_SW,V911S_FLAG_CALIB); // long press on right button
|
||||
memset(packet+3, 0x00, V911S_PACKET_SIZE - 3);
|
||||
//packet[3..6]=trims TAER signed
|
||||
uint16_t ch=convert_channel_16b_limit(THROTTLE ,0,0x7FF);
|
||||
packet[ 7] = ch;
|
||||
packet[ 8] = ch>>8;
|
||||
ch=convert_channel_16b_limit(AILERON ,0x7FF,0);
|
||||
packet[ 8]|= ch<<3;
|
||||
packet[ 9] = ch>>5;
|
||||
ch=convert_channel_16b_limit(ELEVATOR,0,0x7FF);
|
||||
packet[10] = ch;
|
||||
packet[11] = ch>>8;
|
||||
ch=convert_channel_16b_limit(RUDDER ,0x7FF,0);
|
||||
packet[11]|= ch<<3;
|
||||
packet[12] = ch>>5;
|
||||
}
|
||||
|
||||
// Power on, TX mode, 2byte CRC
|
||||
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
||||
if (!bind)
|
||||
{
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[channel]);
|
||||
hopping_frequency_no++;
|
||||
hopping_frequency_no&=7; // 8 RF channels
|
||||
}
|
||||
// clear packet status bits and TX FIFO
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||
NRF24L01_FlushTx();
|
||||
XN297_WritePayload(packet, V911S_PACKET_SIZE);
|
||||
|
||||
NRF24L01_SetPower(); // Set tx_power
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) V911S_init()
|
||||
{
|
||||
NRF24L01_Initialize();
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
XN297_SetTXAddr((uint8_t *)"\x4B\x4E\x42\x4E\x44", 5); // Bind address
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, V911S_RF_BIND_CHANNEL); // Bind channel
|
||||
NRF24L01_FlushTx();
|
||||
NRF24L01_FlushRx();
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
|
||||
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowldgement on all data pipes
|
||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 only
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_250K); // 250Kbps
|
||||
NRF24L01_SetPower();
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) V911S_initialize_txid()
|
||||
{
|
||||
//channels
|
||||
uint8_t offset=rx_tx_addr[3]%5; // 0-4
|
||||
for(uint8_t i=0;i<V911S_NUM_RF_CHANNELS;i++)
|
||||
hopping_frequency[i]=0x10+i*5+offset;
|
||||
if(!offset) hopping_frequency[0]++;
|
||||
|
||||
// channels order
|
||||
rf_ch_num=random(0xfefefefe)&0x03; // 0-3
|
||||
}
|
||||
|
||||
uint16_t V911S_callback()
|
||||
{
|
||||
if(IS_BIND_DONE)
|
||||
{
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(V911S_PACKET_PERIOD);
|
||||
#endif
|
||||
V911S_send_packet(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bind_counter == 0)
|
||||
{
|
||||
BIND_DONE;
|
||||
XN297_SetTXAddr(rx_tx_addr, 5);
|
||||
packet_period=V911S_PACKET_PERIOD;
|
||||
}
|
||||
else
|
||||
{
|
||||
V911S_send_packet(1);
|
||||
bind_counter--;
|
||||
if(bind_counter==100) // same as original TX...
|
||||
packet_period=V911S_BIND_PACKET_PERIOD*3;
|
||||
}
|
||||
}
|
||||
return packet_period;
|
||||
}
|
||||
|
||||
uint16_t initV911S(void)
|
||||
{
|
||||
V911S_initialize_txid();
|
||||
#ifdef V911S_ORIGINAL_ID
|
||||
rx_tx_addr[0]=0xA5;
|
||||
rx_tx_addr[1]=0xFF;
|
||||
rx_tx_addr[2]=0x70;
|
||||
rx_tx_addr[3]=0x8D;
|
||||
rx_tx_addr[4]=0x76;
|
||||
for(uint8_t i=0;i<V911S_NUM_RF_CHANNELS;i++)
|
||||
hopping_frequency[i]=0x10+i*5;
|
||||
hopping_frequency[0]++;
|
||||
rf_ch_num=0;
|
||||
#endif
|
||||
|
||||
V911S_init();
|
||||
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
bind_counter = V911S_BIND_COUNT;
|
||||
packet_period= V911S_BIND_PACKET_PERIOD;
|
||||
}
|
||||
else
|
||||
{
|
||||
XN297_SetTXAddr(rx_tx_addr, 5);
|
||||
packet_period= V911S_PACKET_PERIOD;
|
||||
}
|
||||
hopping_frequency_no=0;
|
||||
return V911S_INITIAL_WAIT;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -14,9 +14,9 @@
|
||||
*/
|
||||
// compatible with V911S
|
||||
|
||||
#if defined(V911S_XN297L_INO)
|
||||
#if defined(V911S_NRF24L01_INO)
|
||||
|
||||
#include "iface_xn297l.h"
|
||||
#include "iface_nrf250k.h"
|
||||
|
||||
//#define V911S_ORIGINAL_ID
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
|
||||
// flags going to packet[1]
|
||||
#define V911S_FLAG_EXPERT 0x04
|
||||
#define E119_FLAG_EXPERT 0x08
|
||||
#define E119_FLAG_CALIB 0x40
|
||||
// flags going to packet[2]
|
||||
#define V911S_FLAG_CALIB 0x01
|
||||
|
||||
@@ -56,10 +58,21 @@ static void __attribute__((unused)) V911S_send_packet(uint8_t bind)
|
||||
}
|
||||
if(rf_ch_num&2)
|
||||
channel=7-channel;
|
||||
XN297L_Hopping(channel);
|
||||
hopping_frequency_no++;
|
||||
hopping_frequency_no&=7; // 8 RF channels
|
||||
|
||||
packet[ 0]=(rf_ch_num<<3)|channel;
|
||||
packet[ 1]=V911S_FLAG_EXPERT; // short press on left button
|
||||
packet[ 2]=GET_FLAG(CH5_SW,V911S_FLAG_CALIB); // long press on right button
|
||||
memset(packet+3, 0x00, V911S_PACKET_SIZE - 3);
|
||||
memset(packet+1, 0x00, V911S_PACKET_SIZE - 1);
|
||||
if(sub_protocol==V911S_STD)
|
||||
{
|
||||
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
|
||||
uint16_t ch=convert_channel_16b_limit(THROTTLE ,0,0x7FF);
|
||||
packet[ 7] = ch;
|
||||
@@ -68,22 +81,31 @@ static void __attribute__((unused)) V911S_send_packet(uint8_t bind)
|
||||
packet[ 8]|= ch<<3;
|
||||
packet[ 9] = ch>>5;
|
||||
ch=convert_channel_16b_limit(ELEVATOR,0,0x7FF);
|
||||
packet[10] = ch;
|
||||
packet[11] = ch>>8;
|
||||
ch=convert_channel_16b_limit(RUDDER ,0x7FF,0);
|
||||
packet[11]|= ch<<3;
|
||||
packet[12] = ch>>5;
|
||||
if(sub_protocol==V911S_STD)
|
||||
{
|
||||
packet[10] = ch;
|
||||
packet[11] = ch>>8;
|
||||
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)
|
||||
{
|
||||
XN297L_Hopping(channel);
|
||||
hopping_frequency_no++;
|
||||
hopping_frequency_no&=7; // 8 RF channels
|
||||
}
|
||||
|
||||
XN297L_WritePayload(packet, V911S_PACKET_SIZE);
|
||||
|
||||
if(sub_protocol==V911S_STD)
|
||||
XN297L_WritePayload(packet, V911S_PACKET_SIZE);
|
||||
else
|
||||
XN297L_WriteEnhancedPayload(packet, V911S_PACKET_SIZE, bind?0:1);
|
||||
|
||||
XN297L_SetPower(); // Set tx_power
|
||||
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()
|
||||
{
|
||||
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_RFChannel(V911S_RF_BIND_CHANNEL); // Set bind channel
|
||||
}
|
||||
@@ -140,15 +165,30 @@ uint16_t initV911S(void)
|
||||
{
|
||||
V911S_initialize_txid();
|
||||
#ifdef V911S_ORIGINAL_ID
|
||||
rx_tx_addr[0]=0xA5;
|
||||
rx_tx_addr[1]=0xFF;
|
||||
rx_tx_addr[2]=0x70;
|
||||
rx_tx_addr[3]=0x8D;
|
||||
rx_tx_addr[4]=0x76;
|
||||
for(uint8_t i=0;i<V911S_NUM_RF_CHANNELS;i++)
|
||||
hopping_frequency[i]=0x10+i*5;
|
||||
hopping_frequency[0]++;
|
||||
rf_ch_num=0;
|
||||
if(sub_protocol==V911S_STD)
|
||||
{//V911S
|
||||
rx_tx_addr[0]=0xA5;
|
||||
rx_tx_addr[1]=0xFF;
|
||||
rx_tx_addr[2]=0x70;
|
||||
rx_tx_addr[3]=0x8D;
|
||||
rx_tx_addr[4]=0x76;
|
||||
for(uint8_t i=0;i<V911S_NUM_RF_CHANNELS;i++)
|
||||
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
|
||||
|
||||
V911S_init();
|
||||
|
||||
@@ -89,6 +89,11 @@
|
||||
#error "The FrSkyX forced frequency tuning value is outside of the range -127..127."
|
||||
#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
|
||||
#if ( FORCE_HITEC_TUNING < -127 ) || ( FORCE_HITEC_TUNING > 127 )
|
||||
#error "The HITEC forced frequency tuning value is outside of the range -127..127."
|
||||
@@ -130,6 +135,11 @@
|
||||
#error "The Flyzone forced frequency tuning value is outside of the range -300..300."
|
||||
#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
|
||||
#if ( FORCE_HUBSAN_TUNING < -300 ) || ( FORCE_HUBSAN_TUNING > 300 )
|
||||
#error "The Hubsan forced frequency tuning value is outside of the range -300..300."
|
||||
@@ -146,6 +156,9 @@
|
||||
#ifndef FORCE_FLYZONE_TUNING
|
||||
#define FORCE_FLYZONE_TUNING 0
|
||||
#endif
|
||||
#ifndef FORCE_PELIKAN_TUNING
|
||||
#define FORCE_PELIKAN_TUNING 0
|
||||
#endif
|
||||
#ifndef FORCE_HUBSAN_TUNING
|
||||
#define FORCE_HUBSAN_TUNING 0
|
||||
#endif
|
||||
@@ -167,6 +180,7 @@
|
||||
#undef CC25_CSN_pin
|
||||
#undef NRF24L01_INSTALLED // Disable NRF for OrangeTX module
|
||||
#undef NRF_CSN_pin
|
||||
#undef SX1276_INSTALLED // Disable NRF for OrangeTX module
|
||||
#define TELEMETRY // Enable telemetry
|
||||
#define INVERT_TELEMETRY // Enable invert telemetry
|
||||
#define DSM_TELEMETRY // Enable DSM telemetry
|
||||
@@ -180,6 +194,7 @@
|
||||
#undef BUGS_A7105_INO
|
||||
#undef FLYZONE_A7105_INO
|
||||
#undef AFHDS2A_RX_A7105_INO
|
||||
#undef PELIKAN_A7105_INO
|
||||
#endif
|
||||
#ifndef CYRF6936_INSTALLED
|
||||
#undef DEVO_CYRF6936_INO
|
||||
@@ -194,11 +209,11 @@
|
||||
#undef FRSKYD_CC2500_INO
|
||||
#undef FRSKYV_CC2500_INO
|
||||
#undef FRSKYX_CC2500_INO
|
||||
#undef FRSKYX2_CC2500_INO
|
||||
#undef SFHSS_CC2500_INO
|
||||
#undef CORONA_CC2500_INO
|
||||
#undef REDPINE_CC2500_INO
|
||||
#undef HITEC_CC2500_INO
|
||||
#undef XN297L_CC2500_EMU
|
||||
#undef SCANNER_CC2500_INO
|
||||
#undef FRSKY_RX_CC2500_INO
|
||||
#undef HOTT_CC2500_INO
|
||||
@@ -236,9 +251,17 @@
|
||||
#undef E01X_NRF24L01_INO
|
||||
#undef V761_NRF24L01_INO
|
||||
#undef V911S_NRF24L01_INO
|
||||
#undef XN297L_CC2500_EMU
|
||||
#undef POTENSIC_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
|
||||
|
||||
//Make sure telemetry is selected correctly
|
||||
@@ -266,6 +289,8 @@
|
||||
#undef AFHDS2A_RX_TELEMETRY
|
||||
#undef AFHDS2A_RX_A7105_INO
|
||||
#undef HOTT_FW_TELEMETRY
|
||||
#undef BAYANG_RX_TELEMETRY
|
||||
#undef BAYANG_RX_NRF24L01_INO
|
||||
#else
|
||||
#if defined(MULTI_TELEMETRY) && defined(MULTI_STATUS)
|
||||
#error You should choose either MULTI_TELEMETRY or MULTI_STATUS but not both.
|
||||
@@ -282,6 +307,10 @@
|
||||
#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
|
||||
#if not defined(BAYANG_NRF24L01_INO)
|
||||
#undef BAYANG_HUB_TELEMETRY
|
||||
#endif
|
||||
@@ -308,7 +337,7 @@
|
||||
#if not defined(FRSKYD_CC2500_INO)
|
||||
#undef HUB_TELEMETRY
|
||||
#endif
|
||||
#if not defined(FRSKYX_CC2500_INO)
|
||||
#if not defined(FRSKYX_CC2500_INO) and not defined(FRSKYX2_CC2500_INO)
|
||||
#undef SPORT_TELEMETRY
|
||||
#undef SPORT_SEND
|
||||
#endif
|
||||
@@ -321,7 +350,7 @@
|
||||
#if not defined(HOTT_CC2500_INO)
|
||||
#undef HOTT_FW_TELEMETRY
|
||||
#endif
|
||||
#if not defined(HOTT_FW_TELEMETRY) && not defined(DSM_TELEMETRY) && not defined(SPORT_TELEMETRY) && not defined(HUB_TELEMETRY) && not defined(HUBSAN_HUB_TELEMETRY) && not defined(BUGS_HUB_TELEMETRY) && not defined(NCC1701_HUB_TELEMETRY) && not defined(BAYANG_HUB_TELEMETRY) && not defined(CABELL_HUB_TELEMETRY) && not defined(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)
|
||||
#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 INVERT_TELEMETRY
|
||||
#undef MULTI_TELEMETRY
|
||||
@@ -340,6 +369,8 @@
|
||||
#if not defined(MULTI_TELEMETRY)
|
||||
#undef MULTI_SYNC
|
||||
#undef MULTI_NAMES
|
||||
#else
|
||||
#define MULTI_NAMES
|
||||
#endif
|
||||
|
||||
//Make sure TX is defined correctly
|
||||
@@ -393,3 +424,18 @@
|
||||
#if defined (STM32_BOARD) && defined (DEBUG_SERIAL) && defined (NRF24L01_INSTALLED)
|
||||
#define XN297DUMP_NRF24L01_INO
|
||||
#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
|
||||
|
||||
217
Multiprotocol/XK_nrf24l01.ino
Normal file
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;
|
||||
uint16_t timeH=0;
|
||||
boolean scramble;
|
||||
boolean enhanced;
|
||||
boolean ack;
|
||||
uint8_t pid;
|
||||
uint8_t bitrate;
|
||||
|
||||
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_WriteReg(NRF24L01_11_RX_PW_P0, XN297DUMP_MAX_PACKET_LEN); // Enable rx pipe 0
|
||||
|
||||
debug("XN297 dump, address length=%d, speed=",address_length);
|
||||
switch(sub_protocol)
|
||||
debug("XN297 dump, address length=%d, bitrate=",address_length);
|
||||
switch(bitrate)
|
||||
{
|
||||
case 0:
|
||||
case XN297DUMP_250K:
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_250K);
|
||||
debugln("250K");
|
||||
break;
|
||||
case 2:
|
||||
case XN297DUMP_2M:
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_2M);
|
||||
debugln("2M");
|
||||
break;
|
||||
@@ -76,9 +80,14 @@ static boolean __attribute__((unused)) XN297Dump_process_packet(void)
|
||||
{
|
||||
uint16_t crcxored;
|
||||
uint8_t packet_sc[XN297DUMP_MAX_PACKET_LEN], packet_un[XN297DUMP_MAX_PACKET_LEN];
|
||||
enhanced=false;
|
||||
// init crc
|
||||
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
|
||||
// address
|
||||
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)
|
||||
{ // Found a valid CRC for the enhanced payload mode
|
||||
debug("Enhanced ");
|
||||
enhanced=true;
|
||||
//check selected address length
|
||||
if((packet_un[address_length]>>1)!=packet_length-address_length)
|
||||
{
|
||||
for(uint8_t i=3;i<=5;i++)
|
||||
if((packet_un[i]>>1)==packet_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));
|
||||
debug("ack=%d ",(packet_un[address_length+1]>>6)&0x01);
|
||||
pid=((packet_un[address_length]&0x01)<<1)|(packet_un[address_length+1]>>7);
|
||||
ack=(packet_un[address_length+1]>>6)&0x01;
|
||||
// address
|
||||
for (uint8_t i = 0; i < address_length; i++)
|
||||
packet[address_length-1-i]=packet_un[i];
|
||||
@@ -175,96 +184,449 @@ static void __attribute__((unused)) XN297Dump_overflow()
|
||||
}
|
||||
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)
|
||||
{
|
||||
if(option==0xFF && bind_counter>XN297DUMP_PERIOD_SCAN)
|
||||
{ // Scan frequencies
|
||||
hopping_frequency_no++;
|
||||
bind_counter=0;
|
||||
}
|
||||
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();
|
||||
|
||||
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(sub_protocol<XN297DUMP_AUTO)
|
||||
{
|
||||
if(option==0xFF && bind_counter>XN297DUMP_PERIOD_SCAN)
|
||||
{ // Scan frequencies
|
||||
hopping_frequency_no++;
|
||||
bind_counter=0;
|
||||
}
|
||||
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();
|
||||
// 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();
|
||||
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&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++;
|
||||
if(IS_RX_FLAG_on) // Let the radio update the protocol
|
||||
{
|
||||
if(Update_All()) return 10000; // New protocol selected
|
||||
if(prev_option!=option)
|
||||
if(prev_option!=option && sub_protocol<XN297DUMP_AUTO)
|
||||
{ // option has changed
|
||||
hopping_frequency_no=option;
|
||||
prev_option=option;
|
||||
@@ -278,6 +640,10 @@ static uint16_t XN297Dump_callback()
|
||||
uint16_t initXN297Dump(void)
|
||||
{
|
||||
BIND_DONE;
|
||||
if(sub_protocol<XN297DUMP_AUTO)
|
||||
bitrate=sub_protocol;
|
||||
else
|
||||
bitrate=0;
|
||||
address_length=RX_num;
|
||||
if(address_length<3||address_length>5)
|
||||
address_length=5; //default
|
||||
@@ -285,7 +651,7 @@ uint16_t initXN297Dump(void)
|
||||
bind_counter=0;
|
||||
rf_ch_num=0xFF;
|
||||
prev_option=option^0x55;
|
||||
phase=0; // init timer
|
||||
phase=0; // init
|
||||
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
|
||||
@@ -16,7 +16,7 @@ Multiprotocol is distributed in the hope that it will be useful,
|
||||
|
||||
#if defined(ZSX_NRF24L01_INO)
|
||||
|
||||
#include "iface_xn297l.h"
|
||||
#include "iface_nrf250k.h"
|
||||
|
||||
//#define FORCE_ZSX_ORIGINAL_ID
|
||||
|
||||
|
||||
@@ -77,9 +77,7 @@
|
||||
#define CYRF6936_INSTALLED
|
||||
#define CC2500_INSTALLED
|
||||
#define NRF24L01_INSTALLED
|
||||
|
||||
//If available use the CC2500 to emulate the XN297L @250Kbps instead of the NRF24L01. Comment to disable.
|
||||
#define XN297L_CC2500_EMU
|
||||
//#define SX1276_INSTALLED // only supported on STM32 modules
|
||||
|
||||
/** OrangeRX TX **/
|
||||
//If you compile for the OrangeRX TX module you need to select the correct board type.
|
||||
@@ -113,6 +111,7 @@
|
||||
//#define FORCE_BUGS_TUNING 0
|
||||
//#define FORCE_FLYSKY_TUNING 0
|
||||
//#define FORCE_FLYZONE_TUNING 0
|
||||
//#define FORCE_PELIKAN_TUNING 0
|
||||
//#define FORCE_HUBSAN_TUNING 0
|
||||
|
||||
/** CYRF6936 Fine Frequency Tuning **/
|
||||
@@ -140,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
|
||||
// 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!!!
|
||||
//The 8 numbers below can be anything between 0...9 and A..F
|
||||
//#define FORCE_GLOBAL_ID 0x12345678
|
||||
|
||||
//Protocols using the CYRF6936 (DSM, Devo, Walkera...) are using the CYRF ID instead which should prevent duplicated IDs.
|
||||
@@ -163,6 +163,7 @@
|
||||
#define FLYSKY_A7105_INO
|
||||
#define FLYZONE_A7105_INO
|
||||
#define HUBSAN_A7105_INO
|
||||
#define PELIKAN_A7105_INO
|
||||
|
||||
//The protocols below need a CYRF6936 to be installed
|
||||
#define DEVO_CYRF6936_INO
|
||||
@@ -187,6 +188,7 @@
|
||||
//The protocols below need a NRF24L01 to be installed
|
||||
#define ASSAN_NRF24L01_INO
|
||||
#define BAYANG_NRF24L01_INO
|
||||
#define BAYANG_RX_NRF24L01_INO
|
||||
#define BUGSMINI_NRF24L01_INO
|
||||
#define CABELL_NRF24L01_INO
|
||||
#define CFLIE_NRF24L01_INO
|
||||
@@ -214,12 +216,16 @@
|
||||
#define SHENQI_NRF24L01_INO
|
||||
#define SLT_NRF24L01_INO
|
||||
#define SYMAX_NRF24L01_INO
|
||||
#define TIGER_NRF24L01_INO
|
||||
#define V2X2_NRF24L01_INO
|
||||
#define V761_NRF24L01_INO
|
||||
#define V911S_NRF24L01_INO
|
||||
#define XK_NRF24L01_INO
|
||||
#define YD717_NRF24L01_INO
|
||||
#define ZSX_NRF24L01_INO
|
||||
|
||||
//The protocols below need a SX1276 to be installed
|
||||
//#define FRSKYR9_SX1276_INO
|
||||
|
||||
/***************************/
|
||||
/*** PROTOCOLS SETTINGS ***/
|
||||
@@ -239,7 +245,7 @@
|
||||
//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.
|
||||
// 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
|
||||
|
||||
//AFHDS2A specific settings
|
||||
@@ -282,8 +288,6 @@
|
||||
//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/erskyTX use MULTI_STATUS instead.
|
||||
#define MULTI_TELEMETRY
|
||||
//Send to OpenTX the current protocol and subprotocol names. Comment to disable.
|
||||
#define MULTI_NAMES
|
||||
//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
|
||||
|
||||
@@ -304,6 +308,7 @@
|
||||
#define FRSKY_RX_TELEMETRY // Forward channels data to TX
|
||||
#define AFHDS2A_RX_TELEMETRY // Forward channels data to TX
|
||||
#define HOTT_FW_TELEMETRY // Forward received telemetry packets to be decoded by erskyTX and OpenTX
|
||||
#define BAYANG_RX_TELEMETRY // Forward channels data to TX
|
||||
|
||||
/****************************/
|
||||
/*** SERIAL MODE SETTINGS ***/
|
||||
@@ -501,6 +506,8 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
|
||||
X16_AH
|
||||
IRDRONE
|
||||
DHD_D4
|
||||
PROTO_BAYANG_RX
|
||||
NONE
|
||||
PROTO_BUGS
|
||||
NONE
|
||||
PROTO_BUGSMINI
|
||||
@@ -541,9 +548,11 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
|
||||
E015
|
||||
E016H
|
||||
PROTO_ESKY
|
||||
NONE
|
||||
ESKY_STD
|
||||
ESKY_ET4
|
||||
PROTO_ESKY150
|
||||
NONE
|
||||
ESKY150_4CH
|
||||
ESKY150_7CH
|
||||
PROTO_FLYSKY
|
||||
Flysky
|
||||
V9X9
|
||||
@@ -556,6 +565,11 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
|
||||
NONE
|
||||
PROTO_FRSKYD
|
||||
NONE
|
||||
PROTO_FRSKYR9
|
||||
R9_915
|
||||
R9_868
|
||||
R9_915_8CH
|
||||
R9_868_8CH
|
||||
PROTO_FRSKYV
|
||||
NONE
|
||||
PROTO_FRSKYX
|
||||
@@ -563,6 +577,11 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
|
||||
CH_8
|
||||
EU_16
|
||||
EU_8
|
||||
PROTO_FRSKYX2
|
||||
FRSKYX2_CH_16
|
||||
FRSKYX2_CH_8
|
||||
FRSKYX2_EU_16
|
||||
FRSKYX2_EU_8
|
||||
PROTO_FRSKY_RX
|
||||
NONE
|
||||
PROTO_FX816
|
||||
@@ -621,6 +640,8 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
|
||||
FY805
|
||||
PROTO_NCC1701
|
||||
NONE
|
||||
PROTO_PELIKAN
|
||||
NONE
|
||||
PROTO_POTENSIC
|
||||
NONE
|
||||
PROTO_Q2X2
|
||||
@@ -650,6 +671,8 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
|
||||
PROTO_SYMAX
|
||||
SYMAX
|
||||
SYMAX5C
|
||||
PROTO_TIGER
|
||||
NONE
|
||||
PROTO_TRAXXAS
|
||||
RX6519
|
||||
PROTO_V2X2
|
||||
@@ -658,7 +681,8 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
|
||||
PROTO_V761
|
||||
NONE
|
||||
PROTO_V911S
|
||||
NONE
|
||||
V911S_STD
|
||||
V911S_E119
|
||||
PROTO_WFLY
|
||||
NONE
|
||||
PROTO_WK2x01
|
||||
@@ -668,6 +692,9 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
|
||||
W6_6_1
|
||||
W6_HEL
|
||||
W6_HEL_I
|
||||
PROTO_XK
|
||||
X450
|
||||
X420
|
||||
PROTO_YD717
|
||||
YD717
|
||||
SKYWLKR
|
||||
@@ -677,3 +704,29 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
|
||||
PROTO_ZSX
|
||||
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)
|
||||
*/
|
||||
|
||||
34
Multiprotocol/iface_nrf250k.h
Normal file
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
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,8 +22,7 @@ Here are detailed descriptions of every supported protocols (sorted by RF module
|
||||
- Bind channel is going from -100% to +100%
|
||||
|
||||
* 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...
|
||||
- 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.
|
||||
- **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.
|
||||
- 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
|
||||
@@ -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|
|
||||
[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|
|
||||
[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|
|
||||
@@ -80,7 +80,7 @@ CFlie|38|CFlie||||||||NRF24L01|
|
||||
[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|
|
||||
[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|
|
||||
[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|
|
||||
@@ -88,6 +88,7 @@ CFlie|38|CFlie||||||||NRF24L01|
|
||||
[Flyzone](Protocols_Details.md#FLYZONE---53)|53|FZ410||||||||A7105|
|
||||
[FQ777](Protocols_Details.md#FQ777---23)|23|FQ777||||||||NRF24L01|SSV7241
|
||||
[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|
|
||||
[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|
|
||||
@@ -108,6 +109,7 @@ CFlie|38|CFlie||||||||NRF24L01|
|
||||
[MT99xx](Protocols_Details.md#MT99XX---17)|17|MT|H7|YZ|LS|FY805||||NRF24L01|XN297
|
||||
[NCC1701](Protocols_Details.md#NCC1701---44)|44|NCC1701||||||||NRF24L01|
|
||||
[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
|
||||
[Q2X2](Protocols_Details.md#Q2X2---29)|29|Q222|Q242|Q282||||||NRF24L01|
|
||||
[Q303](Protocols_Details.md#Q303---31)|31|Q303|CX35|CX10D|CX10WD|||||NRF24L01|XN297
|
||||
@@ -117,15 +119,16 @@ CFlie|38|CFlie||||||||NRF24L01|
|
||||
[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|
|
||||
[SymaX](Protocols_Details.md#Symax---10)|10|SYMAX|SYMAX5C|||||||NRF24L01|
|
||||
[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|
|
||||
[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|
|
||||
[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|
|
||||
[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
|
||||
|
||||
@@ -194,7 +197,7 @@ Note that the RX ouput will be AETR whatever the input channel order is.
|
||||
## 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.2, Trainer Mode Master/Multi
|
||||
Available in OpenTX 2.3.3, Trainer Mode Master/Multi
|
||||
|
||||
Extended limits supported
|
||||
|
||||
@@ -255,6 +258,19 @@ A|E|T|R|ARM|ANGLE|FLIP|PICTURE|VIDEO|LED
|
||||
|
||||
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
|
||||
|
||||
@@ -307,7 +323,7 @@ Models: FrSky receivers D4R and D8R. DIY RX-F801 and RX-F802 receivers. Also kno
|
||||
|
||||
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.
|
||||
Check the [Frequency Tuning page](/docs/Frequency_Tuning.md) to determine it.
|
||||
@@ -321,7 +337,7 @@ Models: FrSky receivers X4R, X6R and X8R. Also known as D16.
|
||||
|
||||
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.
|
||||
Check the [Frequency Tuning page](/docs/Frequency_Tuning.md) to determine it.
|
||||
@@ -357,7 +373,7 @@ 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.2, Trainer Mode Master/Multi
|
||||
Available in OpenTX 2.3.3, Trainer Mode Master/Multi
|
||||
|
||||
Extended limits supported
|
||||
|
||||
@@ -397,14 +413,14 @@ CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
|
||||
### Sub_protocol OPT_FW - *0*
|
||||
OPTIMA RXs
|
||||
|
||||
Full telemetry available on OpenTX 2.3.2+, still in progress for erskyTx.
|
||||
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**
|
||||
|
||||
### Sub_protocol OPT_HUB - *1*
|
||||
OPTIMA RXs
|
||||
|
||||
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.
|
||||
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**
|
||||
|
||||
@@ -429,7 +445,7 @@ 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.2+ with RX voltage, Rx temperature, RX RSSI, RX LQI, TX RSSI and TX LQI.
|
||||
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*
|
||||
Models: Futaba RXs and XK models.
|
||||
@@ -568,9 +584,9 @@ A|E|T|R|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|----|TH_KILL
|
||||
|
||||
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.
|
||||
- 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%.
|
||||
- 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 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*
|
||||
@@ -674,6 +690,17 @@ CH12|CH13
|
||||
----|----
|
||||
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*
|
||||
Models: MJX Bugs 3 Mini and 3H
|
||||
|
||||
@@ -824,10 +851,22 @@ CH1|CH2|CH3|CH4|CH5|CH6
|
||||
---|---|---|---|---|---
|
||||
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*
|
||||
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
|
||||
---|---|---|---|---|---|---
|
||||
@@ -866,9 +905,9 @@ A|E|T|R|FLIP|RTH|HEADLESS|EXPERT
|
||||
## GD00X - *47*
|
||||
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
|
||||
---|---|---|---|---|---|---
|
||||
@@ -969,9 +1008,9 @@ ARM|
|
||||
## KF606 - *49*
|
||||
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
|
||||
---|---|---|---|---
|
||||
@@ -996,9 +1035,9 @@ Only 3 TX IDs available, change RX_Num value 0..2 to cycle through them
|
||||
### Sub_protocol E010 - *4*
|
||||
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*
|
||||
CH6|
|
||||
@@ -1028,7 +1067,9 @@ Model: Yi Zhan i6S
|
||||
|
||||
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*
|
||||
Models: LS114, 124, 215
|
||||
@@ -1098,7 +1139,10 @@ CH1|CH2|CH3|CH4
|
||||
A|E|T|R
|
||||
|
||||
### 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
|
||||
---|---|---|---|---|---|---
|
||||
@@ -1247,6 +1291,15 @@ CH10|CH11|CH12
|
||||
---|---|---
|
||||
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*
|
||||
Model: Volantex V761 and may be other
|
||||
|
||||
@@ -1259,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
|
||||
|
||||
## 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 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
|
||||
---|---|---|---|---
|
||||
A|E|T|R|CALIB
|
||||
|
||||
### Sub_protocol V911S - *0*
|
||||
Models: WLtoys V911S, XK A110
|
||||
|
||||
### Sub_protocol E119 - *1*
|
||||
Models: Eachine E119
|
||||
|
||||
## YD717 - *8*
|
||||
Autobind protocol
|
||||
|
||||
@@ -1292,7 +1349,41 @@ CH1|CH2|CH3|CH4|CH5
|
||||
---|---|---|---|---
|
||||
||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 - *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.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user