mirror of
https://github.com/pascallanger/DIY-Multiprotocol-TX-Module.git
synced 2025-11-25 21:39:39 +00:00
Compare commits
168 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6ba1c8b118 | ||
|
|
b949ac0fed | ||
|
|
510f892d2f | ||
|
|
17750e774a | ||
|
|
be1591c489 | ||
|
|
3b22705166 | ||
|
|
c05c0a5693 | ||
|
|
d6fc6a3517 | ||
|
|
7bfaee8b4f | ||
|
|
89c00e8f17 | ||
|
|
447a58966f | ||
|
|
74162aa972 | ||
|
|
78a1e61f7a | ||
|
|
a917227ddc | ||
|
|
c866d07743 | ||
|
|
43d969f962 | ||
|
|
3973b42f81 | ||
|
|
6046ad81db | ||
|
|
63a9874aea | ||
|
|
89420fe2d4 | ||
|
|
9769354989 | ||
|
|
580b996215 | ||
|
|
8f5fb5083f | ||
|
|
821076ce95 | ||
|
|
0bfe1f8e63 | ||
|
|
9c35f6f73c | ||
|
|
983debe6ce | ||
|
|
66704b5a13 | ||
|
|
f11da0c1de | ||
|
|
7676398aab | ||
|
|
9c6c55fa00 | ||
|
|
5b9ca3ba06 | ||
|
|
23141b6087 | ||
|
|
6d4b4bd2c0 | ||
|
|
5cec22a757 | ||
|
|
153ba2e090 | ||
|
|
21e8bed52b | ||
|
|
ecfc5b0313 | ||
|
|
2bcebbda45 | ||
|
|
52e8d87ab1 | ||
|
|
b613345da4 | ||
|
|
f2665ca786 | ||
|
|
e3189d3aed | ||
|
|
c829e1c86f | ||
|
|
8499a508f5 | ||
|
|
50dec0e55d | ||
|
|
6f419adb7f | ||
|
|
502e8beafb | ||
|
|
5aae065dc0 | ||
|
|
152dbed3fa | ||
|
|
b516bb8d20 | ||
|
|
30e3e84066 | ||
|
|
8338104266 | ||
|
|
00c6aa52b9 | ||
|
|
e5689d2f1b | ||
|
|
b51dedcea1 | ||
|
|
49f004e53f | ||
|
|
062fc05eac | ||
|
|
6d080d5d5f | ||
|
|
0955340a93 | ||
|
|
9b2318cc7e | ||
|
|
2098cdc5e0 | ||
|
|
d19b5187c5 | ||
|
|
2a78b1d6b7 | ||
|
|
84ae6366eb | ||
|
|
e5b235ac83 | ||
|
|
0195384592 | ||
|
|
0937f832fc | ||
|
|
c77b4af2a0 | ||
|
|
b943bae8dd | ||
|
|
4955978eb6 | ||
|
|
df409fddf5 | ||
|
|
0330c596e4 | ||
|
|
8c6c58f12f | ||
|
|
4bc08d22b8 | ||
|
|
96fb3b20b7 | ||
|
|
47f713c6c8 | ||
|
|
443c7a6b99 | ||
|
|
e79ca9b7d7 | ||
|
|
b94f774f80 | ||
|
|
5614e8bef6 | ||
|
|
4ce3a5d298 | ||
|
|
f6de3de78c | ||
|
|
8099018132 | ||
|
|
360dde2e1b | ||
|
|
cc7b7638d3 | ||
|
|
321e4aee34 | ||
|
|
f18847df57 | ||
|
|
a2559a65d3 | ||
|
|
5ac41fdd15 | ||
|
|
6d38dd2d7a | ||
|
|
667058269c | ||
|
|
ad6f934892 | ||
|
|
714220c349 | ||
|
|
4887fca873 | ||
|
|
cfe80edcb6 | ||
|
|
484588ff6b | ||
|
|
1bb059c2a2 | ||
|
|
ef5d9cb6b3 | ||
|
|
37a06c050d | ||
|
|
5f0ed395ba | ||
|
|
ae27c8b671 | ||
|
|
088bfb9c2f | ||
|
|
b01462e36b | ||
|
|
abd36dc6a4 | ||
|
|
ebb8a33c1a | ||
|
|
2b0f663482 | ||
|
|
956e632392 | ||
|
|
90b6bb8f7d | ||
|
|
6153e84abf | ||
|
|
16357f29e9 | ||
|
|
0b8a5a7539 | ||
|
|
6874e3a6a7 | ||
|
|
96263ed8a6 | ||
|
|
7bb1cb9ae3 | ||
|
|
20e32c4cb0 | ||
|
|
b4421306c0 | ||
|
|
e53f723fdb | ||
|
|
832a331437 | ||
|
|
12e66bd84f | ||
|
|
d290cc519f | ||
|
|
f4b19fe33e | ||
|
|
767d2c079a | ||
|
|
7750310be5 | ||
|
|
6de4e1e1dd | ||
|
|
627d47f139 | ||
|
|
36675cf729 | ||
|
|
33d8234eb3 | ||
|
|
347eb11328 | ||
|
|
5ed61f30e1 | ||
|
|
a633f46f4f | ||
|
|
baf9a0f978 | ||
|
|
c98b8fc8bf | ||
|
|
2fae0a35b8 | ||
|
|
b04f38ed3d | ||
|
|
60d5dd4101 | ||
|
|
75b7dd1dd7 | ||
|
|
aa2717d6ab | ||
|
|
4058f04b39 | ||
|
|
25ebd55c85 | ||
|
|
d00b58c8ed | ||
|
|
e7eb07a5a4 | ||
|
|
a4cac50261 | ||
|
|
4f8da64822 | ||
|
|
4f89721cd0 | ||
|
|
43c2843490 | ||
|
|
c152265284 | ||
|
|
b591b92b4e | ||
|
|
090388aa1b | ||
|
|
c6ab696949 | ||
|
|
df45a3ff83 | ||
|
|
fedd04b724 | ||
|
|
d8630da09d | ||
|
|
6192f7287e | ||
|
|
5b8a08ab22 | ||
|
|
313b03fb84 | ||
|
|
5639def6fb | ||
|
|
15a254879c | ||
|
|
5baa9bd256 | ||
|
|
d5346c0eaf | ||
|
|
a2213fd6dc | ||
|
|
9b07f12f90 | ||
|
|
c9b49483e0 | ||
|
|
e2972a5823 | ||
|
|
d5b3ed832d | ||
|
|
9fcc030c15 | ||
|
|
fc81b7ee5a | ||
|
|
f168abc2bb |
194
.github/workflows/main.yml
vendored
Normal file
194
.github/workflows/main.yml
vendored
Normal file
@@ -0,0 +1,194 @@
|
||||
# Workflow for testing MULTI-Module firmware builds
|
||||
|
||||
name: CI
|
||||
|
||||
on:
|
||||
# Trigger the workflow on pushes, except those that are tagged (avoids double-testing releases)
|
||||
push:
|
||||
branches:
|
||||
- '**'
|
||||
tags-ignore:
|
||||
- '**'
|
||||
paths:
|
||||
- '.github/workflows/**'
|
||||
- 'buildroot/bin/**'
|
||||
- 'Multiprotocol/**'
|
||||
|
||||
# Trigger the workflow on pull requests to the master branch
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
- '.github/workflows/**'
|
||||
- 'buildroot/bin/**'
|
||||
- 'Multiprotocol/**'
|
||||
|
||||
# Triggers the workflow on release creation
|
||||
release:
|
||||
types:
|
||||
- created
|
||||
|
||||
# Allows the workflow to be triggered manually from the Actions tab
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
# Configure the board matrix
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
board: [
|
||||
"multi4in1:avr:multiatmega328p:bootloader=none",
|
||||
"multi4in1:avr:multiatmega328p:bootloader=optiboot",
|
||||
"multi4in1:avr:multixmega32d4",
|
||||
"multi4in1:STM32F1:multi5in1t18int",
|
||||
"multi4in1:STM32F1:multistm32f103cb:debug_option=none",
|
||||
"multi4in1:STM32F1:multistm32f103cb:debug_option=native",
|
||||
"multi4in1:STM32F1:multistm32f103cb:debug_option=ftdi",
|
||||
"multi4in1:STM32F1:multistm32f103c8:debug_option=none"
|
||||
]
|
||||
|
||||
# Set the environment variables
|
||||
env:
|
||||
BOARD: ${{ matrix.board }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Install Arduino CLI
|
||||
uses: arduino/setup-arduino-cli@v1.1.1
|
||||
|
||||
- name: Prepare build environment
|
||||
run: |
|
||||
echo "Github Ref: $GITHUB_REF"
|
||||
echo "Event name: ${{ github.event_name }}"
|
||||
echo "Event action: ${{ github.event.action }}"
|
||||
echo "Tag name: ${{ github.event.release.tag_name }}"
|
||||
|
||||
arduino-cli config init --additional-urls https://raw.githubusercontent.com/pascallanger/DIY-Multiprotocol-TX-Module-Boards/master/package_multi_4in1_board_index.json
|
||||
arduino-cli core update-index
|
||||
|
||||
if [[ "$BOARD" =~ "multi4in1:avr:" ]]; then
|
||||
arduino-cli core install arduino:avr;
|
||||
arduino-cli core install multi4in1:avr
|
||||
fi
|
||||
|
||||
if [[ "$BOARD" =~ "multi4in1:STM32F1:" ]]; then
|
||||
arduino-cli core install multi4in1:STM32F1
|
||||
fi
|
||||
|
||||
chmod +x ${GITHUB_WORKSPACE}/buildroot/bin/*
|
||||
echo "${GITHUB_WORKSPACE}/buildroot/bin" >> $GITHUB_PATH
|
||||
|
||||
mkdir ./build
|
||||
mkdir ./binaries
|
||||
|
||||
- name: Configure MULTI-Module firmware options
|
||||
run: |
|
||||
# Load the build functions
|
||||
source ./buildroot/bin/buildFunctions;
|
||||
|
||||
# Get the version
|
||||
getMultiVersion
|
||||
echo "MULTI_VERSION=$(echo $MULTI_VERSION)" >> $GITHUB_ENV
|
||||
|
||||
# Get all the protocols for this board
|
||||
getAllProtocols
|
||||
echo "A7105_PROTOCOLS=$(echo $A7105_PROTOCOLS)" >> $GITHUB_ENV
|
||||
echo "CC2500_PROTOCOLS=$(echo $CC2500_PROTOCOLS)" >> $GITHUB_ENV
|
||||
echo "CYRF6936_PROTOCOLS=$(echo $CYRF6936_PROTOCOLS)" >> $GITHUB_ENV
|
||||
echo "NRF24L01_PROTOCOLS=$(echo $NRF24L01_PROTOCOLS)" >> $GITHUB_ENV
|
||||
echo "SX1276_PROTOCOLS=$(echo $SX1276_PROTOCOLS)" >> $GITHUB_ENV
|
||||
echo "ALL_PROTOCOLS=$(echo $ALL_PROTOCOLS)" >> $GITHUB_ENV
|
||||
|
||||
# Get all the RF modules for this board
|
||||
getAllRFModules
|
||||
echo "ALL_RFMODULES=$(echo $ALL_RFMODULES)" >> $GITHUB_ENV
|
||||
|
||||
# Disable CHECK_FOR_BOOTLOADER when not needed
|
||||
if [[ "$BOARD" == "multi4in1:avr:multiatmega328p:bootloader=none" ]]; then
|
||||
opt_disable CHECK_FOR_BOOTLOADER;
|
||||
fi
|
||||
|
||||
# Trim the build down for the Atmega328p board
|
||||
if [[ "$BOARD" =~ "multi4in1:avr:multiatmega328p:" ]]; then
|
||||
opt_disable $ALL_PROTOCOLS
|
||||
opt_enable FRSKYX_CC2500_INO AFHDS2A_A7105_INO MJXQ_NRF24L01_INO DSM_CYRF6936_INO;
|
||||
fi
|
||||
|
||||
# Trim the enabled protocols down for the STM32F103CB board with debugging or the STM32F103C8 board in general
|
||||
if [[ "$BOARD" == "multi4in1:STM32F1:multistm32f103cb:debug_option=ftdi" ]] || [[ "$BOARD" == "multi4in1:STM32F1:multistm32f103cb:debug_option=native" ]] || [[ "$BOARD" =~ "multi4in1:STM32F1:multistm32f103c8" ]]; then
|
||||
opt_disable $ALL_PROTOCOLS;
|
||||
opt_enable FRSKYX_CC2500_INO AFHDS2A_A7105_INO MJXQ_NRF24L01_INO DSM_CYRF6936_INO;
|
||||
fi
|
||||
|
||||
- name: Save default firmware configuration
|
||||
run: |
|
||||
cat Multiprotocol/_Config.h
|
||||
cp Multiprotocol/_Config.h ./_Config.h.bak
|
||||
|
||||
- name: Build default configuration
|
||||
run: |
|
||||
# Skip the default build for boards where it's too large now
|
||||
if [[ "$BOARD" == "multi4in1:STM32F1:multistm32f103cb:debug_option=none" ]] || [[ "$BOARD" == "multi4in1:STM32F1:multi5in1t18int" ]]; then
|
||||
printf "Not testing default build for $BOARD.";
|
||||
else
|
||||
source ./buildroot/bin/buildFunctions;
|
||||
buildMulti
|
||||
fi
|
||||
|
||||
- name: Build serial only
|
||||
run: |
|
||||
source ./buildroot/bin/buildFunctions;
|
||||
cp ./_Config.h.bak Multiprotocol/_Config.h
|
||||
opt_disable ENABLE_PPM;
|
||||
buildMulti;
|
||||
|
||||
- name: Build PPM only
|
||||
run: |
|
||||
source ./buildroot/bin/buildFunctions;
|
||||
cp ./_Config.h.bak Multiprotocol/_Config.h
|
||||
opt_disable ENABLE_SERIAL;
|
||||
buildMulti;
|
||||
|
||||
- name: Build each RF module individually
|
||||
run: |
|
||||
source ./buildroot/bin/buildFunctions;
|
||||
cp ./_Config.h.bak Multiprotocol/_Config.h;
|
||||
buildEachRFModule;
|
||||
|
||||
- name: Build each protocol individually
|
||||
run: |
|
||||
source ./buildroot/bin/buildFunctions;
|
||||
cp ./_Config.h.bak Multiprotocol/_Config.h;
|
||||
buildEachProtocol;
|
||||
|
||||
- name: Build release files
|
||||
run: |
|
||||
source ./buildroot/bin/buildFunctions;
|
||||
cp ./_Config.h.bak Multiprotocol/_Config.h;
|
||||
buildReleaseFiles;
|
||||
ls -al ./binaries;
|
||||
|
||||
NUM_FILES=$(ls -l ./binaries | grep ^- | wc -l);
|
||||
if [ $NUM_FILES -gt 0 ]; then
|
||||
echo "HAVE_FILES=true" >> $GITHUB_ENV
|
||||
else
|
||||
echo "HAVE_FILES=false" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: Deploy files to release
|
||||
if: github.event_name == 'release' && github.event.action == 'created' && env.HAVE_FILES == 'true'
|
||||
uses: AButler/upload-release-assets@v2.0
|
||||
with:
|
||||
files: './binaries/*'
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: 'Upload Artifacts'
|
||||
if: env.HAVE_FILES == 'true'
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: multi-test-build
|
||||
path: ./binaries/
|
||||
392
.travis.yml
392
.travis.yml
@@ -1,392 +0,0 @@
|
||||
os: linux
|
||||
dist: bionic
|
||||
language: c
|
||||
|
||||
env:
|
||||
jobs:
|
||||
- BOARD="multi4in1:avr:multiatmega328p:bootloader=none"
|
||||
- BOARD="multi4in1:avr:multiatmega328p:bootloader=optiboot"
|
||||
- BOARD="multi4in1:avr:multixmega32d4"
|
||||
- BOARD="multi4in1:STM32F1:multi5in1t18int"
|
||||
- BOARD="multi4in1:STM32F1:multistm32f103c:debug_option=none"
|
||||
- BOARD="multi4in1:STM32F1:multistm32f103c:debug_option=native"
|
||||
- BOARD="multi4in1:STM32F1:multistm32f103c:debug_option=ftdi"
|
||||
|
||||
notifications:
|
||||
email: false
|
||||
|
||||
before_install:
|
||||
# Fetch the tag information for the current branch
|
||||
- git fetch origin --tags
|
||||
|
||||
# Publish the buildroot script folder
|
||||
- chmod +x ${TRAVIS_BUILD_DIR}/buildroot/bin/*
|
||||
- export PATH=${TRAVIS_BUILD_DIR}/buildroot/bin/:${PATH}
|
||||
|
||||
# Helper functions for the builds
|
||||
- buildMulti() { start_fold config_diff; travis_time_start; git diff Multiprotocol/_Config.h; end_fold config_diff; exitcode=0; BUILDCMD="arduino-cli compile -b $BOARD Multiprotocol/Multiprotocol.ino --build-path ${TRAVIS_BUILD_DIR}/build/"; echo $BUILDCMD; $BUILDCMD; if [ $? -ne 0 ]; then exitcode=1; fi; echo; return $exitcode; }
|
||||
- buildProtocol() { exitcode=0; opt_disable $ALL_PROTOCOLS; opt_enable $1; buildMulti; if [ $? -ne 0 ]; then exitcode=1; fi; return $exitcode; }
|
||||
- buildEachProtocol() { exitcodesum=0; for PROTOCOL in $ALL_PROTOCOLS ; do printf "\e[33;1mBuilding $PROTOCOL\e[0m"; buildProtocol $PROTOCOL; if [ $? -ne 0 ]; then exitcodesum=$((exitcodesum + 1)); fi; done; return $exitcodesum; }
|
||||
- buildRFModule() { exitcode=0; opt_disable $ALL_RFMODULES; opt_enable $1; buildMulti; if [ $? -ne 0 ]; then exitcode=1; fi; return $exitcode; }
|
||||
- buildEachRFModule() { exitcodesum=0; for RFMODULE in $ALL_RFMODULES; do printf "\e[33;1mBuilding $RFMODULE\e[0m"; buildRFModule $RFMODULE; if [ $? -ne 0 ]; then exitcodesum=$((exitcodesum + 1)); fi; done; return $exitcodesum; }
|
||||
- buildDefault() { exitcode=0; printf "\n\e[33;1mBuilding default configuration\e[0m\n"; buildMulti; if [ $? -ne 0 ]; then exitcode=1; fi; return $exitcode; }
|
||||
- buildSerialOnly() { exitcode=0; printf "\n\e[33;1mBuilding serial mode only\e[0m\n"; opt_disable ENABLE_PPM; opt_enable ENABLE_SERIAL; buildMulti; if [ $? -ne 0 ]; then exitcode=1; fi; return $exitcode; }
|
||||
- buildPPMOnly() { exitcode=0; printf "\n\e[33;1mBuilding PPM mode only\e[0m\n"; opt_enable ENABLE_PPM; opt_disable ENABLE_SERIAL; buildMulti; if [ $? -ne 0 ]; then exitcode=1; fi; return $exitcode; }
|
||||
|
||||
# Function to build the release files - dependent on board type
|
||||
- if [[ "$BOARD" == "multi4in1:avr:multixmega32d4" ]]; then
|
||||
buildReleaseFiles(){
|
||||
exitcode=0;
|
||||
printf "\n\e[33;1mBuilding multi-orangerx-aetr-green-inv-v$MULTI_VERSION.bin\e[0m";
|
||||
opt_enable $ALL_PROTOCOLS;
|
||||
opt_disable ORANGE_TX_BLUE;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-orangerx-aetr-green-inv-v$MULTI_VERSION.bin;
|
||||
printf "\n\e[33;1mBuilding multi-orangerx-aetr-blue-inv-v$MULTI_VERSION.bin\e[0m";
|
||||
opt_enable ORANGE_TX_BLUE;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-orangerx-aetr-blue-inv-v$MULTI_VERSION.bin;
|
||||
cp Multiprotocol/Multi.txt ./binaries/Multi.txt;
|
||||
mkdir -p SCRIPTS/TOOLS;
|
||||
cp Lua_scripts/*.lua SCRIPTS/TOOLS/;
|
||||
cp Lua_scripts/*.txt SCRIPTS/TOOLS/;
|
||||
zip ./binaries/MultiLuaScripts.zip SCRIPTS/TOOLS/*;
|
||||
return $exitcode; };
|
||||
elif [[ "$BOARD" == "multi4in1:avr:multiatmega328p:bootloader=none" ]]; then
|
||||
buildReleaseFiles(){
|
||||
printf "\n\e[33;1mBuilding multi-avr-usbasp-aetr-A7105-inv-v$MULTI_VERSION.bin\e[0m";
|
||||
exitcode=0;
|
||||
opt_disable CHECK_FOR_BOOTLOADER;
|
||||
opt_disable $ALL_PROTOCOLS;
|
||||
opt_enable $A7105_PROTOCOLS;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-avr-usbasp-aetr-A7105-inv-v$MULTI_VERSION.bin;
|
||||
printf "\n\e[33;1mBuilding multi-avr-usbasp-aetr-CC2500-inv-v$MULTI_VERSION.bin\e[0m";
|
||||
opt_disable $ALL_PROTOCOLS;
|
||||
opt_enable $CC2500_PROTOCOLS;
|
||||
opt_disable HITEC_CC2500_INO REDPINE_CC2500_INO SKYARTEC_CC2500_INO SCANNER_CC2500_INO;
|
||||
buildMulti;
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-avr-usbasp-aetr-CC2500-inv-v$MULTI_VERSION.bin;
|
||||
printf "\n\e[33;1mBuilding multi-avr-usbasp-aetr-CYRF6936-inv-v$MULTI_VERSION.bin\e[0m";
|
||||
opt_disable $ALL_PROTOCOLS;
|
||||
opt_enable $CYRF6936_PROTOCOLS;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-avr-usbasp-aetr-CYRF6936-inv-v$MULTI_VERSION.bin;
|
||||
return $exitcode; };
|
||||
elif [[ "$BOARD" == "multi4in1:avr:multiatmega328p:bootloader=optiboot" ]]; then
|
||||
buildReleaseFiles(){
|
||||
printf "\n\e[33;1mBuilding multi-avr-txflash-aetr-A7105-inv-v$MULTI_VERSION.bin\e[0m";
|
||||
exitcode=0;
|
||||
opt_enable CHECK_FOR_BOOTLOADER;
|
||||
opt_disable $ALL_PROTOCOLS;
|
||||
opt_enable $A7105_PROTOCOLS;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-avr-txflash-aetr-A7105-inv-v$MULTI_VERSION.bin;
|
||||
printf "\n\e[33;1mBuilding multi-avr-txflash-aetr-CC2500-inv-v$MULTI_VERSION.bin\e[0m";
|
||||
opt_disable $ALL_PROTOCOLS;
|
||||
opt_enable $CC2500_PROTOCOLS;
|
||||
opt_disable HITEC_CC2500_INO REDPINE_CC2500_INO SKYARTEC_CC2500_INO SCANNER_CC2500_INO;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-avr-txflash-aetr-CC2500-inv-v$MULTI_VERSION.bin;
|
||||
printf "\n\e[33;1mBuilding multi-avr-txflash-aetr-CYRF6936-inv-v$MULTI_VERSION.bin\e[0m";
|
||||
opt_disable $ALL_PROTOCOLS;
|
||||
opt_enable $CYRF6936_PROTOCOLS;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-avr-txflash-aetr-CYRF6936-inv-v$MULTI_VERSION.bin;
|
||||
return $exitcode; };
|
||||
elif [[ "$BOARD" == "multi4in1:STM32F1:multistm32f103c:debug_option=none" ]]; then
|
||||
buildReleaseFiles(){
|
||||
printf "\n\e[33;1mBuilding multi-stm-erskytx-aetr-inv-v$MULTI_VERSION.bin\e[0m";
|
||||
exitcode=0;
|
||||
opt_enable CHECK_FOR_BOOTLOADER;
|
||||
opt_enable $ALL_PROTOCOLS;
|
||||
opt_enable MULTI_STATUS;
|
||||
opt_disable MULTI_TELEMETRY;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-erskytx-aetr-inv-v$MULTI_VERSION.bin;
|
||||
printf "\n\e[33;1mBuilding multi-stm-erskytx-taer-inv-v$MULTI_VERSION.bin\e[0m";
|
||||
opt_replace AETR TAER;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-erskytx-taer-inv-v$MULTI_VERSION.bin;
|
||||
printf "\n\e[33;1mBuilding multi-stm-erskytx-reta-inv-v$MULTI_VERSION.bin\e[0m";
|
||||
opt_replace TAER RETA;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-erskytx-reta-inv-v$MULTI_VERSION.bin;
|
||||
printf "\n\e[33;1mBuilding multi-stm-erskytx-aetr-noinv-v$MULTI_VERSION.bin\e[0m";
|
||||
opt_replace RETA AETR;
|
||||
opt_disable INVERT_TELEMETRY;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-erskytx-aetr-noinv-v$MULTI_VERSION.bin;
|
||||
printf "\n\e[33;1mBuilding multi-stm-erskytx-taer-noinv-v$MULTI_VERSION.bin\e[0m";
|
||||
opt_replace AETR TAER;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-erskytx-taer-noinv-v$MULTI_VERSION.bin;
|
||||
printf "\n\e[33;1mBuilding multi-stm-erskytx-reta-noinv-v$MULTI_VERSION.bin\e[0m";
|
||||
opt_replace TAER RETA;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-erskytx-reta-noinv-v$MULTI_VERSION.bin;
|
||||
printf "\n\e[33;1mBuilding multi-stm-opentx-aetr-inv-v$MULTI_VERSION.bin\e[0m";
|
||||
opt_replace RETA AETR;
|
||||
opt_disable MULTI_STATUS;
|
||||
opt_enable MULTI_TELEMETRY;
|
||||
opt_enable INVERT_TELEMETRY;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-opentx-aetr-inv-v$MULTI_VERSION.bin;
|
||||
printf "\n\e[33;1mBuilding multi-stm-opentx-taer-inv-v$MULTI_VERSION.bin\e[0m";
|
||||
opt_replace AETR TAER;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-opentx-taer-inv-v$MULTI_VERSION.bin;
|
||||
printf "\n\e[33;1mBuilding multi-stm-opentx-reta-inv-v$MULTI_VERSION.bin\e[0m";
|
||||
opt_replace TAER RETA;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-opentx-reta-inv-v$MULTI_VERSION.bin;
|
||||
printf "\n\e[33;1mBuilding multi-stm-opentx-aetr-noinv-v$MULTI_VERSION.bin\e[0m";
|
||||
opt_replace RETA AETR;
|
||||
opt_disable INVERT_TELEMETRY;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-opentx-aetr-noinv-v$MULTI_VERSION.bin;
|
||||
printf "\n\e[33;1mBuilding multi-stm-opentx-taer-noinv-v$MULTI_VERSION.bin\e[0m";
|
||||
opt_replace AETR TAER;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-opentx-taer-noinv-v$MULTI_VERSION.bin;
|
||||
printf "\n\e[33;1mBuilding multi-stm-opentx-reta-noinv-v$MULTI_VERSION.bin\e[0m";
|
||||
opt_replace TAER RETA;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-opentx-reta-noinv-v$MULTI_VERSION.bin;
|
||||
printf "\n\e[33;1mBuilding multi-stm-ppm-aetr-noinv-v$MULTI_VERSION.bin\e[0m";
|
||||
opt_replace RETA AETR;
|
||||
opt_disable MULTI_STATUS;
|
||||
opt_disable MULTI_TELEMETRY;
|
||||
opt_set NBR_BANKS 5;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-ppm-aetr-noinv-v$MULTI_VERSION.bin;
|
||||
printf "\n\e[33;1mBuilding multi-stm-ppm-taer-noinv-v$MULTI_VERSION.bin\e[0m";
|
||||
opt_replace AETR TAER;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-ppm-taer-noinv-v$MULTI_VERSION.bin;
|
||||
printf "\n\e[33;1mBuilding multi-stm-ppm-reta-noinv-v$MULTI_VERSION.bin\e[0m";
|
||||
opt_replace TAER RETA;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-ppm-reta-noinv-v$MULTI_VERSION.bin;
|
||||
return $exitcode; };
|
||||
elif [[ "$BOARD" == "multi4in1:STM32F1:multistm32f103c:debug_option=native" ]]; then
|
||||
buildReleaseFiles(){
|
||||
printf "\n\e[33;1mBuilding multi-stm-erskytx-xn297dump-inv-usbdebug-v$MULTI_VERSION.bin\e[0m";
|
||||
exitcode=0;
|
||||
opt_enable CHECK_FOR_BOOTLOADER;
|
||||
opt_disable $ALL_PROTOCOLS;
|
||||
opt_add XN297DUMP_NRF24L01_INO;
|
||||
opt_enable MULTI_STATUS;
|
||||
opt_disable MULTI_TELEMETRY;
|
||||
opt_enable INVERT_TELEMETRY;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-erskytx-xn297dump-inv-usbdebug-v$MULTI_VERSION.bin;
|
||||
printf "\n\e[33;1mBuilding multi-stm-opentx-xn297dump-inv-usbdebug-v$MULTI_VERSION.bin\e[0m";
|
||||
opt_disable $ALL_PROTOCOLS;
|
||||
opt_disable MULTI_STATUS;
|
||||
opt_enable MULTI_TELEMETRY;
|
||||
opt_enable INVERT_TELEMETRY;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-opentx-xn297dump-inv-usbdebug-v$MULTI_VERSION.bin;
|
||||
return $exitcode; };
|
||||
elif [[ "$BOARD" == "multi4in1:STM32F1:multistm32f103c:debug_option=ftdi" ]]; then
|
||||
buildReleaseFiles(){
|
||||
printf "\n\e[33;1mBuilding multi-stm-erskytx-xn297dump-inv-ftdidebug-v$MULTI_VERSION.bin\e[0m";
|
||||
exitcode=0;
|
||||
opt_enable CHECK_FOR_BOOTLOADER;
|
||||
opt_disable $ALL_PROTOCOLS;
|
||||
opt_add XN297DUMP_NRF24L01_INO;
|
||||
opt_enable MULTI_STATUS;
|
||||
opt_disable MULTI_TELEMETRY;
|
||||
opt_enable INVERT_TELEMETRY;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-erskytx-xn297dump-inv-ftdidebug-v$MULTI_VERSION.bin;
|
||||
printf "\n\e[33;1mBuilding multi-stm-opentx-xn297dump-inv-ftdidebug-v$MULTI_VERSION.bin\e[0m";
|
||||
opt_disable $ALL_PROTOCOLS;
|
||||
opt_disable MULTI_STATUS;
|
||||
opt_enable MULTI_TELEMETRY;
|
||||
opt_enable INVERT_TELEMETRY;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-opentx-xn297dump-inv-ftdidebug-v$MULTI_VERSION.bin;
|
||||
return $exitcode; };
|
||||
elif [[ "$BOARD" == "multi4in1:STM32F1:multi5in1t18int" ]]; then
|
||||
buildReleaseFiles(){
|
||||
printf "\n\e[33;1mBuilding multi-t18int-opentx-aetr-noinv-v$MULTI_VERSION.bin\e[0m";
|
||||
opt_disable INVERT_TELEMETRY;
|
||||
exitcode=0;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-t18int-opentx-aetr-noinv-v$MULTI_VERSION.bin;
|
||||
printf "\n\e[33;1mBuilding multi-t18int-opentx-taer-noinv-v$MULTI_VERSION.bin\e[0m";
|
||||
opt_replace AETR TAER;
|
||||
exitcode=0;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-t18int-opentx-taer-noinv-v$MULTI_VERSION.bin;
|
||||
printf "\n\e[33;1mBuilding multi-t18int-opentx-reta-noinv-v$MULTI_VERSION.bin\e[0m";
|
||||
opt_replace TAER RETA;
|
||||
exitcode=0;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-t18int-opentx-reta-noinv-v$MULTI_VERSION.bin;
|
||||
return $exitcode; };
|
||||
else
|
||||
buildReleaseFiles() { echo "No release files for this board."; };
|
||||
fi
|
||||
|
||||
install:
|
||||
# Install Arduino CLI
|
||||
- mkdir ~/arduino-cli
|
||||
- curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | BINDIR=~/arduino-cli sh;
|
||||
- export PATH=$PATH:$HOME/arduino-cli
|
||||
|
||||
# Update the board url and package index
|
||||
- arduino-cli core update-index --additional-urls https://raw.githubusercontent.com/pascallanger/DIY-Multiprotocol-TX-Module-Boards/master/package_multi_4in1_board_index.json
|
||||
|
||||
# Install the STM32 board if needed
|
||||
- if [[ "$BOARD" =~ "multi4in1:STM32F1:" ]]; then
|
||||
arduino-cli core install multi4in1:STM32F1 --additional-urls https://raw.githubusercontent.com/pascallanger/DIY-Multiprotocol-TX-Module-Boards/master/package_multi_4in1_board_index.json;
|
||||
fi
|
||||
|
||||
# Install the AVR board if needed
|
||||
- if [[ "$BOARD" =~ "multi4in1:avr:" ]]; then
|
||||
arduino-cli core install arduino:avr;
|
||||
arduino-cli core install multi4in1:avr --additional-urls https://raw.githubusercontent.com/pascallanger/DIY-Multiprotocol-TX-Module-Boards/master/package_multi_4in1_board_index.json;
|
||||
fi
|
||||
|
||||
before_script:
|
||||
# Change current working directory to the build dir
|
||||
- cd ${TRAVIS_BUILD_DIR}
|
||||
|
||||
# Create somwhere to put the exported binaries
|
||||
- mkdir ./binaries
|
||||
|
||||
# Log the initial Multi config
|
||||
- cat Multiprotocol/_Config.h
|
||||
|
||||
# Back up the configuration
|
||||
- cp Multiprotocol/_Config.h ./_Config.h.bak
|
||||
|
||||
# Get the firmware version number from the source
|
||||
- MAJOR_VERSION=$(grep "VERSION_MAJOR" "Multiprotocol/Multiprotocol.h" | awk -v N=3 '{gsub(/\r/,""); print $N}')
|
||||
- MINOR_VERSION=$(grep "VERSION_MINOR" "Multiprotocol/Multiprotocol.h" | awk -v N=3 '{gsub(/\r/,""); print $N}')
|
||||
- REVISION_VERSION=$(grep "VERSION_REVISION" "Multiprotocol//Multiprotocol.h" | awk -v N=3 '{gsub(/\r/,""); print $N}')
|
||||
- PATCH_VERSION=$(grep "VERSION_PATCH" "Multiprotocol//Multiprotocol.h" | awk -v N=3 '{gsub(/\r/,""); print $N}')
|
||||
- MULTI_VERSION=$MAJOR_VERSION.$MINOR_VERSION.$REVISION_VERSION.$PATCH_VERSION
|
||||
|
||||
# Derive the Multi protocols from the Multi source
|
||||
- A7105_PROTOCOLS=$(sed -n 's/[\/\/]*[[:blank:]]*#define[[:blank:]]*\([[:alnum:]_]*_A7105_INO\)\(.*\)/\1/p' Multiprotocol/_Config.h)
|
||||
- CC2500_PROTOCOLS=$(sed -n 's/[\/\/]*[[:blank:]]*#define[[:blank:]]*\([[:alnum:]_]*_CC2500_INO\)\(.*\)/\1/p' Multiprotocol/_Config.h)
|
||||
- CYRF6936_PROTOCOLS=$(sed -n 's/[\/\/]*[[:blank:]]*#define[[:blank:]]*\([[:alnum:]_]*_CYRF6936_INO\)\(.*\)/\1/p' Multiprotocol/_Config.h)
|
||||
- NRF24L01_PROTOCOLS=$(sed -n 's/[\/\/]*[[:blank:]]*#define[[:blank:]]*\([[:alnum:]_]*_NRF24L01_INO\)\(.*\)/\1/p' Multiprotocol/_Config.h)
|
||||
- SX1276_PROTOCOLS=$(sed -n 's/[\/\/]*[[:blank:]]*#define[[:blank:]]*\([[:alnum:]_]*_SX1276_INO\)\(.*\)/\1/p' Multiprotocol/_Config.h)
|
||||
|
||||
# Get the full set of protocols for each board
|
||||
- if [[ "$BOARD" =~ "multi4in1:avr:multixmega32d4" ]]; then
|
||||
ALL_PROTOCOLS=$(echo $CYRF6936_PROTOCOLS);
|
||||
elif [[ "$BOARD" =~ "multi4in1:avr:multiatmega328p:" ]]; then
|
||||
ALL_PROTOCOLS=$(echo $A7105_PROTOCOLS $CC2500_PROTOCOLS $CYRF6936_PROTOCOLS $NRF24L01_PROTOCOLS);
|
||||
elif [[ "$BOARD" =~ "multi4in1:STM32F1:" ]]; then
|
||||
ALL_PROTOCOLS=$(echo $A7105_PROTOCOLS $CC2500_PROTOCOLS $CYRF6936_PROTOCOLS $NRF24L01_PROTOCOLS $SX1276_PROTOCOLS);
|
||||
fi
|
||||
- echo $ALL_PROTOCOLS
|
||||
|
||||
# Declare all the installed modules
|
||||
- if [[ "$BOARD" =~ "multi4in1:STM32F1:" ]]; then
|
||||
ALL_RFMODULES=$(echo A7105_INSTALLED CYRF6936_INSTALLED CC2500_INSTALLED NRF24L01_INSTALLED SX1276_INSTALLED);
|
||||
else
|
||||
ALL_RFMODULES=$(echo A7105_INSTALLED CYRF6936_INSTALLED CC2500_INSTALLED NRF24L01_INSTALLED);
|
||||
fi
|
||||
|
||||
# Disable CHECK_FOR_BOOTLOADER when not needed
|
||||
- if [[ "$BOARD" == "multi4in1:avr:multiatmega328p:bootloader=none" ]]; then
|
||||
opt_disable CHECK_FOR_BOOTLOADER;
|
||||
fi
|
||||
|
||||
# Trim the enabled protocols down for the STM32 board with debugging
|
||||
- if [[ "$BOARD" == "multi4in1:STM32F1:multistm32f103c:debug_option=ftdi" ]] || [[ "$BOARD" == "multi4in1:STM32F1:multistm32f103c:debug_option=native" ]]; then
|
||||
opt_disable $ALL_PROTOCOLS;
|
||||
opt_enable FRSKYX_CC2500_INO AFHDS2A_A7105_INO MJXQ_NRF24L01_INO DSM_CYRF6936_INO;
|
||||
fi
|
||||
|
||||
# Trim the enabled protocols down for the Atmega328p board
|
||||
- if [[ "$BOARD" =~ "multi4in1:avr:multiatmega328p:" ]]; then
|
||||
opt_disable $ALL_PROTOCOLS;
|
||||
opt_enable FRSKYX_CC2500_INO AFHDS2A_A7105_INO MJXQ_NRF24L01_INO DSM_CYRF6936_INO;
|
||||
fi
|
||||
|
||||
# Useful Travis functions
|
||||
- export -f travis_fold
|
||||
- export -f travis_nanoseconds
|
||||
- export -f travis_time_start
|
||||
- export -f travis_time_finish
|
||||
- start_fold() { echo -e "travis_fold:start:$1"; }
|
||||
- end_fold() { echo -e "\ntravis_fold:end:$1\r"; }
|
||||
|
||||
script:
|
||||
# Build with default configuration - all protocols are enabled for STM32; a subset of protocols for Atmega or STM32 debugging
|
||||
- buildDefault
|
||||
|
||||
# Serial only
|
||||
- buildSerialOnly
|
||||
|
||||
# PPM only
|
||||
- buildPPMOnly
|
||||
|
||||
# Re-enable PPM and serial
|
||||
- opt_enable ENABLE_SERIAL
|
||||
- opt_enable ENABLE_PPM
|
||||
|
||||
# Build for each RF module individually
|
||||
- buildEachRFModule
|
||||
|
||||
# Restore the default configuration
|
||||
- cp ./_Config.h.bak Multiprotocol/_Config.h
|
||||
|
||||
# Build each protocol individually
|
||||
- buildEachProtocol
|
||||
|
||||
# Restore the default configuration
|
||||
- cp ./_Config.h.bak Multiprotocol/_Config.h
|
||||
|
||||
# Restore the default configuration
|
||||
- cp ./_Config.h.bak Multiprotocol/_Config.h
|
||||
|
||||
# Builds the files for a release - always built, but only copied to Github if the test is tagged as a release
|
||||
- buildReleaseFiles
|
||||
|
||||
deploy:
|
||||
provider: releases
|
||||
token:
|
||||
secure: KGXaoqvd8rbZ3AZtL9Rrn1JYiocGsPaihRUyR8gM8vTfvH9WYAE1+h6SzROQOuJSwr89MvTo3SBOTlM/0PDBnEGLec9Irt7cwO0xf9xM2vPuUG8DYcUzmJJzME9dkn/7qHof1JGgRpp1duUAN1triE9NxhKxL1hbs+tUUbDPAejxwoFNfnta/T4PfD6xmkZNJbneIfYFuFgyLpwwFhuUy9JP7s1AFOiT+fCHxPaZrPn5GsXqAi95Cb7Q3w1iVSt3BmrGxL2j3CeNpWzFY1RrMdc8ay+ppOhSPEIl2vyM7VeLRRBL3EVeFWkiS4ywevqw70wOivTczluv3OeuIJAe5o2UU+w5+59c7+i44Nih23PDAZBhAG5JkLUYUN0XUJpXJ5ZlZsb8IS8sI1txlZa5tNVoXO9+soGEY4rKSpZaPptuENm792CzzAjcaUI9pOFJ/0CBoSCbu5MpM/plkJCMd8fY27EE8cNYvolMuRATNlXs7h9mURGR69pmcR1jFShH+A7Kyp1S1sH19sGCEU16rt2aAtf2FadFg/gKACC2y9rB3wBb4Qnapu2AwNRlTYNuU1+G+kb2FXRwMl04q+38S+cIBHH9NHfdftp9MRPf8Ekatojs92be/Ux21S+hcA7sx/DV22Dl45V6l4mXzR7U4x1nQcdn1SGuy5I4lL6IYCk=
|
||||
skip_cleanup: true
|
||||
file_glob: true
|
||||
file: binaries/*
|
||||
on:
|
||||
tags: true
|
||||
@@ -170,6 +170,24 @@
|
||||
],
|
||||
"toolsDependencies": []
|
||||
},
|
||||
{
|
||||
"name": "MULTI-Module AVR Boards",
|
||||
"architecture": "avr",
|
||||
"version": "1.1.1",
|
||||
"category": "Contributed",
|
||||
"help": {
|
||||
"online": "https://github.com/pascallanger/DIY-Multiprotocol-TX-Module"
|
||||
},
|
||||
"url": "https://github.com/pascallanger/DIY-Multiprotocol-TX-Module-Boards/raw/master/archives/package_multi_4in1_avr_board_v1.1.1.tar.gz",
|
||||
"archiveFileName": "package_multi_4in1_avr_board_v1.1.1.tar.gz",
|
||||
"checksum": "SHA-256:02158258b4dbaca61bedbb6933336200d13b02ad0db981e2dda253682c482e99",
|
||||
"size": "324512",
|
||||
"boards": [
|
||||
{"name": "Multi 4-in-1 (Atmega328p, 3.3V, 16MHz)"},
|
||||
{"name": "Multi 4-in-1 (OrangeRX)"}
|
||||
],
|
||||
"toolsDependencies": []
|
||||
},
|
||||
{
|
||||
"name": "Multi 4-in-1 STM32 Board",
|
||||
"architecture": "STM32F1",
|
||||
@@ -549,6 +567,73 @@
|
||||
"version": "4.8.3-2014q1"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"name": "Multi X-in-1 STM32 Boards",
|
||||
"architecture": "STM32F1",
|
||||
"version": "1.2.0",
|
||||
"category": "Contributed",
|
||||
"help": {
|
||||
"online": "https://github.com/pascallanger/DIY-Multiprotocol-TX-Module"
|
||||
},
|
||||
"url": "https://github.com/pascallanger/DIY-Multiprotocol-TX-Module-Boards/raw/master/archives/package_multi_4in1_stm32_board_v1.2.0.tar.gz",
|
||||
"archiveFileName": "package_multi_4in1_stm32_board_v1.2.0.tar.gz",
|
||||
"checksum": "SHA-256:754f08ca2a553701cc9112b645c079b6041107f1bf863648305e560c136a6ac5",
|
||||
"size": "7496214",
|
||||
"boards": [
|
||||
{"name": "Multi 4-in-1 (STM32F103C)"},
|
||||
{"name": "Multi 5-in-1 (Jumper T18 Internal)"}
|
||||
],
|
||||
"toolsDependencies": [{
|
||||
"packager": "arduino",
|
||||
"name": "arm-none-eabi-gcc",
|
||||
"version": "4.8.3-2014q1"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"name": "Multi X-in-1 STM32 Boards",
|
||||
"architecture": "STM32F1",
|
||||
"version": "1.2.1",
|
||||
"category": "Contributed",
|
||||
"help": {
|
||||
"online": "https://github.com/pascallanger/DIY-Multiprotocol-TX-Module"
|
||||
},
|
||||
"url": "https://github.com/pascallanger/DIY-Multiprotocol-TX-Module-Boards/raw/master/archives/package_multi_4in1_stm32_board_v1.2.1.tar.gz",
|
||||
"archiveFileName": "package_multi_4in1_stm32_board_v1.2.1.tar.gz",
|
||||
"checksum": "SHA-256:c66d34afadc5b21e9e28c4d477fa03a6d55db0b74b59ff2dcb07b4d6ef06da1a",
|
||||
"size": "7496448",
|
||||
"boards": [
|
||||
{"name": "Multi 4-in-1 (STM32F103C)"},
|
||||
{"name": "Multi 5-in-1 (Jumper T18 Internal)"}
|
||||
],
|
||||
"toolsDependencies": [{
|
||||
"packager": "arduino",
|
||||
"name": "arm-none-eabi-gcc",
|
||||
"version": "4.8.3-2014q1"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"name": "MULTI-Module STM32 Boards",
|
||||
"architecture": "STM32F1",
|
||||
"version": "1.2.2",
|
||||
"category": "Contributed",
|
||||
"help": {
|
||||
"online": "https://github.com/pascallanger/DIY-Multiprotocol-TX-Module"
|
||||
},
|
||||
"url": "https://github.com/pascallanger/DIY-Multiprotocol-TX-Module-Boards/raw/master/archives/package_multi_4in1_stm32_board_v1.2.2.tar.gz",
|
||||
"archiveFileName": "package_multi_4in1_stm32_board_v1.2.2.tar.gz",
|
||||
"checksum": "SHA-256:0fe4a8899438bbc31dc37714acca13968e43d75a47e59143343d83b634d2e47d",
|
||||
"size": "7485662",
|
||||
"boards": [
|
||||
{"name": "Multi X-in-1 STM32F103CB (128KB)"},
|
||||
{"name": "Multi X-in-1 STM32F103C8 (64KB)"},
|
||||
{"name": "Multi 5-in-1 (Jumper T18 Internal)"}
|
||||
],
|
||||
"toolsDependencies": [{
|
||||
"packager": "arduino",
|
||||
"name": "arm-none-eabi-gcc",
|
||||
"version": "4.8.3-2014q1"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"name": "Multi 4-in-1 OrangeRX Board - DEPRECATED, USE MULTI 4-IN-1 AVR BOARDS PACKAGE INSTEAD",
|
||||
"architecture": "orangerx",
|
||||
|
||||
601
Lua_scripts/DSM FwdPrg.lua
Normal file
601
Lua_scripts/DSM FwdPrg.lua
Normal file
@@ -0,0 +1,601 @@
|
||||
local toolName = "TNS|DSM Forward Programming|TNE"
|
||||
|
||||
---- #########################################################################
|
||||
---- # #
|
||||
---- # Copyright (C) OpenTX #
|
||||
-----# #
|
||||
---- # License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html #
|
||||
---- # #
|
||||
---- # This program is free software; you can redistribute it and/or modify #
|
||||
---- # it under the terms of the GNU General Public License version 2 as #
|
||||
---- # published by the Free Software Foundation. #
|
||||
---- # #
|
||||
---- # This program is distributed in the hope that it will be useful #
|
||||
---- # but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
---- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
---- # GNU General Public License for more details. #
|
||||
---- # #
|
||||
---- #########################################################################
|
||||
|
||||
|
||||
--###############################################################################
|
||||
-- Multi buffer for DSM description
|
||||
-- Multi_Buffer[0..2]=="DSM" -> Lua script is running
|
||||
-- Multi_Buffer[3]==0x70+len -> TX to RX data ready to be sent
|
||||
-- Multi_Buffer[4..9]=6 bytes of TX to RX data
|
||||
-- Multi_Buffer[10..25]=16 bytes of RX to TX data
|
||||
--
|
||||
-- To start operation:
|
||||
-- Write 0x00 at address 3
|
||||
-- Write 0x00 at address 10
|
||||
-- Write "DSM" at address 0..2
|
||||
--###############################################################################
|
||||
|
||||
local RX_VERSION, WAIT_CMD, MENU_TITLE, MENU_LINES, MENU_VALUES, VALUE_CHANGING, VALUE_CHANGING_WAIT, VALUE_CHANGED = 0, 1, 2, 3, 4, 5, 6, 7
|
||||
local MENU, LIST_MENU_NOCHANGING, LIST_MENU2, PERCENTAGE_VALUE = 0x1C, 0x6C, 0x4C, 0xC0
|
||||
local Phase = RX_VERSION
|
||||
local Waiting_RX = 0
|
||||
local Text = {}
|
||||
local Retry=100
|
||||
local Blink = 0
|
||||
local Value_Changed=0
|
||||
|
||||
local Menu = { Cur=nil, Id=nil, Title="", Prev=nil, PrevId=nil, Next=nil, NextId=nil, Back=nil, BackId=nil, CurLine=nil, SelLine=nil, EditLine=nil }
|
||||
local Line = {}
|
||||
local RX = { Name="", Version="" }
|
||||
|
||||
local function conv_int16(number)
|
||||
if number >= 0x8000 then
|
||||
return number - 0x10000
|
||||
end
|
||||
return number
|
||||
end
|
||||
|
||||
local function Get_Text(index)
|
||||
out = Text[index]
|
||||
if out == nil then -- unknown...
|
||||
out = "Unknown_"..string.format("%X",index)
|
||||
end
|
||||
return out
|
||||
end
|
||||
|
||||
local function DSM_Release()
|
||||
multiBuffer( 0, 0 )
|
||||
end
|
||||
|
||||
local function DSM_Send(...)
|
||||
local arg = {...}
|
||||
for i = 1 , #arg do
|
||||
multiBuffer( 3+i, arg[i])
|
||||
end
|
||||
multiBuffer( 3, 0x70+#arg)
|
||||
end
|
||||
|
||||
local function Value_Add(dir)
|
||||
local line=Line[Menu.SelLine]
|
||||
Speed = getRotEncSpeed()
|
||||
if Speed == ROTENC_MIDSPEED then
|
||||
line.Val = line.Val + (5 * dir)
|
||||
elseif Speed == ROTENC_HIGHSPEED then
|
||||
line.Val = line.Val + (15 * dir)
|
||||
else
|
||||
line.Val = line.Val + dir
|
||||
end
|
||||
if line.Val > line.Max then
|
||||
line.Val = line.Max
|
||||
elseif line.Val < line.Min then
|
||||
line.Val = line.Min
|
||||
end
|
||||
if Line[Menu.SelLine].Type ~= LIST_MENU_NOCHANGING then
|
||||
Phase = VALUE_CHANGING
|
||||
Waiting_RX = 0
|
||||
end
|
||||
end
|
||||
|
||||
local function DSM_Menu(event)
|
||||
local Speed = 0
|
||||
if event == EVT_VIRTUAL_NEXT then
|
||||
if Menu.EditLine == nil then
|
||||
-- not changing a value
|
||||
if Menu.SelLine ~= nil then
|
||||
if Menu.SelLine < 7 then
|
||||
local num = Menu.SelLine
|
||||
for i = Menu.SelLine + 1, 6, 1 do
|
||||
if Line[i].Type ~= nil and Line[i].Next ~= nil then
|
||||
Menu.SelLine=i
|
||||
break
|
||||
end
|
||||
end
|
||||
if num == Menu.SelLine then
|
||||
if Menu.Next ~= 0 then -- Next
|
||||
Menu.SelLine = 7
|
||||
elseif Menu.Prev ~= 0 then -- Prev
|
||||
Menu.SelLine = 8
|
||||
end
|
||||
end
|
||||
elseif Menu.Prev ~= 0 then -- Prev
|
||||
Menu.SelLine = 8
|
||||
end
|
||||
end
|
||||
else -- need to inc the value
|
||||
Value_Add(1)
|
||||
end
|
||||
elseif event == EVT_VIRTUAL_PREV then
|
||||
if Menu.EditLine == nil then
|
||||
if Menu.SelLine ~= nil then
|
||||
if Menu.SelLine == 8 and Menu.Next ~= 0 then
|
||||
Menu.SelLine = 7
|
||||
elseif Menu.SelLine > 0 then
|
||||
if Menu.SelLine > 6 then
|
||||
Menu.SelLine = 7
|
||||
end
|
||||
local num = Menu.SelLine
|
||||
for i = Menu.SelLine-1, 0, -1 do
|
||||
if Line[i].Type ~= nil and Line[i].Next ~= nil then
|
||||
Menu.SelLine=i
|
||||
break
|
||||
end
|
||||
end
|
||||
if num == Menu.SelLine then -- Back
|
||||
Menu.SelLine = -1
|
||||
end
|
||||
else
|
||||
Menu.SelLine = -1 -- Back
|
||||
end
|
||||
end
|
||||
else -- need to dec the value
|
||||
Value_Add(-1)
|
||||
end
|
||||
elseif event == EVT_VIRTUAL_ENTER then
|
||||
if Menu.SelLine == -1 then -- Back
|
||||
Menu.Cur = Menu.Back
|
||||
Menu.Id = Menu.BackId
|
||||
Menu.SelLine = 0
|
||||
Phase = MENU_TITLE
|
||||
Waiting_RX = 0
|
||||
elseif Menu.SelLine == 7 then -- Next
|
||||
Menu.Cur = Menu.Next
|
||||
Menu.Id = Menu.NextId
|
||||
Menu.SelLine = 0
|
||||
Phase = MENU_TITLE
|
||||
Waiting_RX = 0
|
||||
elseif Menu.SelLine == 8 then -- Prev
|
||||
Menu.Cur = Menu.Prev
|
||||
Menu.Id = Menu.PrevId
|
||||
Menu.SelLine = 0
|
||||
Phase = MENU_TITLE
|
||||
Waiting_RX = 0
|
||||
elseif Menu.SelLine ~= nil and Line[Menu.SelLine].Next ~= nil then
|
||||
if Line[Menu.SelLine].Type == MENU then -- Next menu exist
|
||||
Menu.Cur = Line[Menu.SelLine].Next
|
||||
Menu.Id = Line[Menu.SelLine].NextId
|
||||
Phase = MENU_TITLE
|
||||
Waiting_RX = 0
|
||||
else
|
||||
-- value entry
|
||||
if Menu.EditLine == Menu.SelLine then
|
||||
Menu.EditLine = nil
|
||||
Value_Changed = 0
|
||||
Phase = VALUE_CHANGED
|
||||
Waiting_RX = 0
|
||||
else
|
||||
Menu.EditLine = Menu.SelLine
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function DSM_Send_Receive()
|
||||
if Waiting_RX == 0 then
|
||||
Waiting_RX = 1
|
||||
-- Need to send a request
|
||||
if Phase == RX_VERSION then -- request RX version
|
||||
DSM_Send(0x11,0x06,0x00,0x14,0x00,0x00)
|
||||
elseif Phase == WAIT_CMD then -- keep connection open
|
||||
DSM_Send(0x00,0x04,0x00,0x00)
|
||||
elseif Phase == MENU_TITLE then -- request menu title
|
||||
if Menu.Cur == nil then
|
||||
DSM_Send(0x12,0x06,0x00,0x14,0x00,0x00) -- first menu only
|
||||
Menu.Cur = 0
|
||||
else
|
||||
DSM_Send(0x16,0x06,Menu.Id,Menu.Cur,0x00,Menu.SelLine)
|
||||
end
|
||||
elseif Phase == MENU_LINES then -- request menu lines
|
||||
if Menu.CurLine == nil then
|
||||
DSM_Send(0x13,0x04,Menu.Id,Menu.Cur) -- line 0
|
||||
elseif Menu.CurLine >= 0x80 then
|
||||
local last_byte={0x40,0x01,0x02,0x04,0x00,0x00} -- unknown...
|
||||
DSM_Send(0x20,0x06,Menu.CurLine-0x80,Menu.CurLine-0x80,0x00,last_byte[Menu.CurLine-0x80+1]) -- line X
|
||||
else
|
||||
DSM_Send(0x14,0x06,Menu.Id,Menu.Cur,0x00,Menu.CurLine) -- line X
|
||||
end
|
||||
elseif Phase == MENU_VALUES then -- request menu values
|
||||
DSM_Send(0x15,0x06,Menu.Id,Menu.Cur,Line[Menu.CurLine].ValId,Menu.CurLine) -- line X
|
||||
elseif Phase == VALUE_CHANGING then -- send value
|
||||
local value=Line[Menu.SelLine].Val
|
||||
if value < 0 then
|
||||
value = 0x10000 + value
|
||||
end
|
||||
DSM_Send(0x18,0x06,Line[Menu.SelLine].ValId,Menu.SelLine,bit32.rshift(value,8),bit32.band(value,0xFF)) -- send current value
|
||||
Phase = VALUE_CHANGING_WAIT
|
||||
elseif Phase == VALUE_CHANGED then -- send value
|
||||
if Value_Changed == 0 then
|
||||
local value=Line[Menu.SelLine].Val
|
||||
if value < 0 then
|
||||
value = 0x10000 + value
|
||||
end
|
||||
DSM_Send(0x18,0x06,Line[Menu.SelLine].ValId,Menu.SelLine,bit32.rshift(value,8),bit32.band(value,0xFF)) -- send current value
|
||||
Value_Changed = Value_Changed + 1
|
||||
Waiting_RX = 0
|
||||
elseif Value_Changed == 1 then
|
||||
DSM_Send(0x19,0x06,Line[Menu.SelLine].ValId,Menu.SelLine) -- validate
|
||||
-- Value_Changed = Value_Changed + 1
|
||||
-- Waiting_RX = 0
|
||||
--elseif Value_Changed == 2 then
|
||||
-- DSM_Send(0x1B,0x06,0x10,Menu.SelLine) -- validate again?
|
||||
-- Value_Changed = Value_Changed + 1
|
||||
end
|
||||
elseif Phase == VALUE_CHANGING_WAIT then
|
||||
DSM_Send(0x1A,0x06,Line[Menu.SelLine].ValId,Menu.SelLine)
|
||||
end
|
||||
multiBuffer(10,0x00);
|
||||
Retry = 50
|
||||
elseif multiBuffer(10) == 0x09 then
|
||||
-- Answer received
|
||||
--if multiBuffer(11) == 0x00 then -- waiting for commands?
|
||||
if multiBuffer(11) == 0x01 then -- read version
|
||||
--ex: 0x09 0x01 0x00 0x15 0x02 0x22 0x01 0x00 0x14 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
RX.Name = Get_Text(multiBuffer(13))
|
||||
RX.Version = multiBuffer(14).."."..multiBuffer(15).."."..multiBuffer(16)
|
||||
Phase = MENU_TITLE
|
||||
elseif multiBuffer(11) == 0x02 then -- read menu title
|
||||
--ex: 0x09 0x02 0x4F 0x10 0xA5 0x00 0x00 0x00 0x50 0x10 0x10 0x10 0x00 0x00 0x00 0x00
|
||||
Menu.Cur = multiBuffer(12)
|
||||
Menu.Id = multiBuffer(13)
|
||||
Menu.Title = Get_Text(multiBuffer(14)+multiBuffer(15)*256)
|
||||
Menu.Prev = multiBuffer(16)
|
||||
Menu.PrevId = multiBuffer(17)
|
||||
Menu.Next = multiBuffer(18)
|
||||
Menu.NextId = multiBuffer(19)
|
||||
Menu.Back = multiBuffer(20)
|
||||
Menu.BackId = multiBuffer(21)
|
||||
for i = 0, 6 do -- clear menu
|
||||
Line[i] = { Menu = nil, Id = nil, Type = nil, Text="", Next = nil, NextId = nil, ValLine = nil, ValId = nil, Min, Max, Def, Val, Unit, Step }
|
||||
end
|
||||
Menu.CurLine = nil
|
||||
if Menu.Next ~= 0 then
|
||||
Menu.SelLine = 7 -- highlight Next
|
||||
else
|
||||
Menu.SelLine = -1 -- highlight Back
|
||||
end
|
||||
Blink = 0
|
||||
Phase = MENU_LINES
|
||||
elseif multiBuffer(11) == 0x03 then -- read menu lines
|
||||
--ex: 0x09 0x03 0x00 0x10 0x00 0x1C 0xF9 0x00 0x10 0x10 0x00 0x00 0x00 0x00 0x03 0x00
|
||||
-- Menu Id line Type Text_idx Next V_Id Val_Min Val_Max Val_Def
|
||||
--ex: 0x09 0x03 0x61 0x10 0x00 0x6C 0x50 0x00 0x00 0x10 0x36 0x00 0x49 0x00 0x36 0x00
|
||||
Menu.CurLine = multiBuffer(14)
|
||||
local line = Line[Menu.CurLine]
|
||||
line.Menu = multiBuffer(12)
|
||||
line.Id = multiBuffer(13) -- not quite sure yet
|
||||
line.Type = multiBuffer(15) -- not quite sure yet: 1C is text menu only, 4C/6C is text followed by text list, C0 is text followed by percentage value
|
||||
line.Text = Get_Text(multiBuffer(16)+multiBuffer(17)*256)
|
||||
if multiBuffer(18) == Menu.Cur then
|
||||
line.Next = nil
|
||||
else
|
||||
line.Next = multiBuffer(18) -- not quite sure yet: 1C=text menu=>next menu, others=>line number of the value
|
||||
end
|
||||
if Menu.SelLine == -1 and line.Next ~= nil then -- Auto select first line of the menu
|
||||
Menu.SelLine = Menu.CurLine
|
||||
end
|
||||
line.NextId = multiBuffer(19) -- not quite sure yet
|
||||
line.ValLine = multiBuffer(18) -- not quite sure yet
|
||||
line.ValId = multiBuffer(19) -- not quite sure yet
|
||||
line.Min = conv_int16(multiBuffer(20)+multiBuffer(21)*256)
|
||||
line.Max = conv_int16(multiBuffer(22)+multiBuffer(23)*256)
|
||||
line.Def = conv_int16(multiBuffer(24)+multiBuffer(25)*256)
|
||||
if line.Type == MENU then
|
||||
-- nothing to do on menu entries
|
||||
elseif line.Type == LIST_MENU_NOCHANGING or line.Type == LIST_MENU2 then
|
||||
line.Val = nil --line.Def - line.Min -- use default value not sure if needed
|
||||
line.Def = line.Min -- pointer to the start of the list in Text
|
||||
line.Max = line.Max - line.Min -- max index
|
||||
line.Min = 0 -- min index
|
||||
else -- default to numerical value
|
||||
line.Val = nil --line.Def -- use default value not sure if needed
|
||||
end
|
||||
if line.Type ~= 0x1C then -- value to follow
|
||||
line.Text = line.Text..":"
|
||||
end
|
||||
Phase = MENU_LINES
|
||||
elseif multiBuffer(11) == 0x04 then -- read menu values
|
||||
--ex: 0x09 0x04 0x53 0x10 0x00 0x10 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
-- Menu MeId line VaId Value
|
||||
--ex: 0x09 0x04 0x61 0x10 0x02 0x10 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
Menu.CurLine = multiBuffer(14)
|
||||
Line[Menu.CurLine].Val = conv_int16(multiBuffer(16)+multiBuffer(17)*256)
|
||||
Phase = MENU_VALUES
|
||||
elseif multiBuffer(11) == 0x05 then -- unknown... need to get through the lines...
|
||||
Menu.CurLine = 0x80 + multiBuffer(12)
|
||||
Phase = MENU_LINES
|
||||
elseif multiBuffer(11) == 0x00 and Phase == VALUE_CHANGING then
|
||||
Phase = VALUE_CHANGING_WAIT
|
||||
end
|
||||
-- Data processed
|
||||
Waiting_RX = 0
|
||||
multiBuffer(10,0x00)
|
||||
Retry = 50
|
||||
else
|
||||
Retry = Retry - 1
|
||||
if Retry <= 0 then
|
||||
-- Retry the RX request
|
||||
Retry = 50
|
||||
Waiting_RX = 0
|
||||
if Phase ~= RX_VERSION and Phase ~= VALUE_CHANGING_WAIT then
|
||||
Phase = WAIT_CMD
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function DSM_Display()
|
||||
lcd.clear()
|
||||
if LCD_W == 480 then
|
||||
--Draw title
|
||||
lcd.drawFilledRectangle(0, 0, LCD_W, 30, TITLE_BGCOLOR)
|
||||
lcd.drawText(1, 5, "DSM Forward Programming", MENU_TITLE_COLOR)
|
||||
--Draw RX Menu
|
||||
if Phase == RX_VERSION then
|
||||
lcd.drawText(10,50,"No compatible DSM RX...", BLINK)
|
||||
else
|
||||
if Menu.Title ~= nil then
|
||||
local attrib=0;
|
||||
lcd.drawText(80,32,Menu.Title,MIDSIZE)
|
||||
for i = 0, 6 do
|
||||
if i == Menu.SelLine then
|
||||
attrib = INVERS
|
||||
else
|
||||
attrib = 0
|
||||
end
|
||||
if Line[i] ~= nil and Line[i].Type ~= nil then
|
||||
if Line[i].Type ~= MENU then -- list/value
|
||||
if Line[i].Val ~= nil then
|
||||
local text=""
|
||||
if Line[i].Type == LIST_MENU_NOCHANGING or Line[i].Type == LIST_MENU2 then
|
||||
text = Get_Text(Line[i].Val+Line[i].Def)
|
||||
elseif Line[i].Type == PERCENTAGE_VALUE then
|
||||
text = Line[i].Val.." %"
|
||||
else
|
||||
text = Line[i].Val
|
||||
end
|
||||
if Menu.EditLine == Menu.SelLine then -- blink edited entry
|
||||
Blink = Blink + 1
|
||||
if Blink > 25 then
|
||||
attrib = 0
|
||||
if Blink > 50 then
|
||||
Blink = 0
|
||||
end
|
||||
end
|
||||
end
|
||||
lcd.drawText(240,32+20*(i+2), text, attrib) -- display value
|
||||
end
|
||||
attrib = 0
|
||||
end
|
||||
lcd.drawText(10,32+20*(i+2), Line[i].Text, attrib) -- display text
|
||||
end
|
||||
end
|
||||
if Menu.SelLine == -1 then
|
||||
lcd.drawText(437,32, "Back", INVERS)
|
||||
else
|
||||
lcd.drawText(437,32, "Back", 0)
|
||||
end
|
||||
lcd.drawRectangle(437-5, 32-2, 47, 25)
|
||||
if Menu.Next ~= 0 then
|
||||
if Menu.SelLine == 7 then
|
||||
lcd.drawText(437,220, "Next",INVERS)
|
||||
else
|
||||
lcd.drawText(437,220, "Next")
|
||||
end
|
||||
lcd.drawRectangle(437-5, 220-2, 47, 25)
|
||||
end
|
||||
if Menu.Prev ~= 0 then
|
||||
if Menu.SelLine == 8 then
|
||||
lcd.drawText(5,220, "Prev",INVERS)
|
||||
else
|
||||
lcd.drawText(5,220, "Prev")
|
||||
end
|
||||
lcd.drawRectangle(5-5, 220-2, 47, 25)
|
||||
end
|
||||
end
|
||||
lcd.drawText(170,252, "RX "..RX.Name.." v"..RX.Version) -- display RX info
|
||||
end
|
||||
else
|
||||
-- --Draw RX Menu on LCD_W=128
|
||||
-- if multiBuffer( 4 ) == 0xFF then
|
||||
-- lcd.drawText(2,17,"No compatible DSM RX...",SMLSIZE)
|
||||
-- else
|
||||
-- if Retry_128 ~= 0 then
|
||||
-- --Intro page
|
||||
-- Retry_128 = Retry_128 - 1
|
||||
-- lcd.drawScreenTitle("DSM Forward Programming",0,0)
|
||||
-- lcd.drawText(2,17,"Press Prev Page for previous Menu" ,SMLSIZE)
|
||||
-- else
|
||||
-- --Menu page
|
||||
-- for line = 0, 7, 1 do
|
||||
-- for i = 0, 21-1, 1 do
|
||||
-- value=multiBuffer( line*21+6+i )
|
||||
-- if value > 0x80 then
|
||||
-- value = value - 0x80
|
||||
-- lcd.drawText(2+i*6,1+8*line,string.char(value).." ",SMLSIZE+INVERS)
|
||||
-- else
|
||||
-- lcd.drawText(2+i*6,1+8*line,string.char(value),SMLSIZE)
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
end
|
||||
end
|
||||
|
||||
-- Init
|
||||
local function DSM_Init()
|
||||
--Set protocol to talk to
|
||||
multiBuffer( 0, string.byte('D') )
|
||||
--test if value has been written
|
||||
if multiBuffer( 0 ) ~= string.byte('D') then
|
||||
error("Not enough memory!")
|
||||
return 2
|
||||
end
|
||||
--Init TX buffer
|
||||
multiBuffer( 3, 0x00 )
|
||||
--Init RX buffer
|
||||
multiBuffer( 10, 0x00 )
|
||||
--Init telemetry
|
||||
multiBuffer( 0, string.byte('D') )
|
||||
multiBuffer( 1, string.byte('S') )
|
||||
multiBuffer( 2, string.byte('M') )
|
||||
|
||||
--Text to be displayed -> need to use a file instead?
|
||||
--RX names--
|
||||
Text[0x0014]="SPM4651T"
|
||||
Text[0x0015]="AR637T"
|
||||
--Lists--
|
||||
Text[0x0036]="Throttle"
|
||||
Text[0x0037]="Aileron"
|
||||
Text[0x0038]="Elevator"
|
||||
Text[0x0039]="Rudder"
|
||||
Text[0x003A]="Gear"
|
||||
|
||||
--******
|
||||
--This part is strange since the AR637T needs
|
||||
for i=1,7 do -- 3B..41
|
||||
Text[0x003A+i]="Aux"..i
|
||||
end
|
||||
for i=1,8 do -- 41..49
|
||||
Text[0x0041+i]="XPlus-"..i
|
||||
end
|
||||
--But FOTO-PETE reports that it should be:
|
||||
Text[0x0040]="Roll"
|
||||
Text[0x0041]="Pitch"
|
||||
Text[0x0042]="Yaw"
|
||||
Text[0x0046]="Priority"
|
||||
--******
|
||||
|
||||
Text[0x004A]="Failsafe"
|
||||
Text[0x004B]="Main Menu"
|
||||
Text[0x004E]="Position"
|
||||
Text[0x0050]="Outputs"
|
||||
Text[0x0051]="Output Channel 1"
|
||||
Text[0x0052]="Output Channel 2"
|
||||
Text[0x0053]="Output Channel 3"
|
||||
Text[0x0054]="Output Channel 4"
|
||||
Text[0x0055]="Output Channel 5"
|
||||
Text[0x0056]="Output Channel 6"
|
||||
--Text[0x005E]="Inhibit"
|
||||
Text[0x005F]="Hold Last"
|
||||
Text[0x0060]="Preset"
|
||||
--Text[0x0061]="Custom"
|
||||
--Messages--
|
||||
Text[0x0078]="FM Channel"
|
||||
Text[0x0080]="Orientation"
|
||||
Text[0x0085]="Frame Rate"
|
||||
Text[0x0086]="System Setup"
|
||||
Text[0x0087]="F-Mode Setup"
|
||||
Text[0x0088]="Enabled F-Modes"
|
||||
Text[0x008A]="Gain Sensitivity"
|
||||
Text[0x0090]="Apply"
|
||||
Text[0x0093]="Complete"
|
||||
Text[0x0094]="Done"
|
||||
Text[0x0097]="Factory Reset"
|
||||
Text[0x009A]="Capture Failsafe Positions"
|
||||
Text[0x009C]="Custom Failsafe"
|
||||
Text[0x00A5]="First Time Setup"
|
||||
Text[0x00AD]="Gain Channel Select"
|
||||
Text[0x00B6]="FM1"
|
||||
Text[0x00B7]="FM2"
|
||||
Text[0x00B8]="FM3"
|
||||
Text[0x00B9]="FM4"
|
||||
Text[0x00BA]="FM5"
|
||||
Text[0x00BB]="FM6"
|
||||
Text[0x00BC]="FM7"
|
||||
Text[0x00BD]="FM8"
|
||||
Text[0x00BE]="FM9"
|
||||
Text[0x00BF]="FM10"
|
||||
Text[0x00F9]="Gyro settings"
|
||||
Text[0x00FE]="Stick Priority"
|
||||
Text[0x0100]="Make sure the model has been"
|
||||
Text[0x0101]="configured, including wing type,"
|
||||
Text[0x0102]="reversing, travel, trimmed, etc."
|
||||
Text[0x0103]="before continuing setup."
|
||||
Text[0x0104]="0104"
|
||||
Text[0x0105]="0105"
|
||||
Text[0x0106]="Any wing type, channel assignment,"
|
||||
Text[0x0107]="subtrim, or servo reversing changes"
|
||||
Text[0x0108]="require running through initial"
|
||||
Text[0x0109]="setup again."
|
||||
Text[0x010A]="010A"
|
||||
Text[0x010B]="010B"
|
||||
Text[0x0190]="Relearn Servo Settings"
|
||||
Text[0x019C]="Enter Receiver Bind Mode"
|
||||
Text[0x01DC]="AS3X"
|
||||
Text[0x01DD]="AS3X Settings"
|
||||
Text[0x01DE]="AS3X Gains"
|
||||
Text[0x01E0]="Rate Gains"
|
||||
Text[0x020A]="Restore from Backup"
|
||||
Text[0x0209]="Save to Backup"
|
||||
Text[0x020D]="First Time SAFE Setup"
|
||||
Text[0x021A]="Set the model level,"
|
||||
Text[0x021B]="and press Continue."
|
||||
Text[0x021C]="021C"
|
||||
Text[0x021D]="021D"
|
||||
|
||||
Text[0x021F]="Set the model on its nose,"
|
||||
Text[0x0220]="and press Continue. If the"
|
||||
Text[0x0221]="orientation on the next"
|
||||
Text[0x0222]="screen is wrong go back"
|
||||
Text[0x0223]="and try again."
|
||||
Text[0x0224]="Continue"
|
||||
Text[0x0229]="Set Orientation Manually"
|
||||
|
||||
Text[0x0227]="Other settings"
|
||||
Text[0x022B]="WARNING!"
|
||||
Text[0x022C]="This will reset the"
|
||||
Text[0x022D]="configuration to factory"
|
||||
Text[0x022E]="defaults. This does not"
|
||||
Text[0x022F]="affect the backup config."
|
||||
Text[0x0230]="0230"
|
||||
Text[0x0231]="This will overwrite the"
|
||||
Text[0x0232]="backup memory with your"
|
||||
Text[0x0233]="current configuartion."
|
||||
Text[0x0234]="0234"
|
||||
Text[0x0235]="0235"
|
||||
Text[0x0236]="This will overwrite the"
|
||||
Text[0x0237]="current config with"
|
||||
Text[0x0238]="that which is in"
|
||||
Text[0x0239]="the backup memory."
|
||||
Text[0x023A]="023A"
|
||||
Text[0x023D]="Copy Flight Mode Settings"
|
||||
Text[0x0240]="Utilities"
|
||||
Text[0x8001]="Flight Mode 1"
|
||||
Text[0x8002]="Flight Mode 2"
|
||||
Text[0x8003]="Flight Mode 3"
|
||||
end
|
||||
|
||||
-- Main
|
||||
local function DSM_Run(event)
|
||||
if event == nil then
|
||||
error("Cannot be run as a model script!")
|
||||
return 2
|
||||
elseif event == EVT_VIRTUAL_EXIT then
|
||||
DSM_Release()
|
||||
return 2
|
||||
else
|
||||
DSM_Menu(event)
|
||||
DSM_Send_Receive()
|
||||
DSM_Display()
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
||||
return { init=DSM_Init, run=DSM_Run }
|
||||
@@ -79,6 +79,7 @@
|
||||
65,3,FrSkyR9,R9_968_8CH,0,CH5,CH6,CH7,CH8
|
||||
55,0,FrSkyRX,RX,0,CH5,CH6,CH7,CH8,CH9,CH10,CH11,CH12,CH13,CH14,CH15,CH16
|
||||
55,1,FrSkyRX,CloneTX,0
|
||||
55,2,FrSkyRX,EraseTX,0
|
||||
58,0,FX816,P38,1
|
||||
20,0,FY326,FY326,1,Flip,RTH,HLess,Expert,Calib
|
||||
20,1,FY326,FY319,1,Flip,RTH,HLess,Expert,Calib
|
||||
@@ -99,13 +100,14 @@
|
||||
26,1,Hontai,JJRCX1,1,Flip,Arm,Pict,Video,HLess,RTH,Calib
|
||||
26,2,Hontai,X5C1,1,Flip,Arm,Pict,Video,HLess,RTH,Calib
|
||||
26,3,Hontai,FQ777_951,1,Flip,Arm,Pict,Video,HLess,RTH,Calib
|
||||
57,0,HoTT,Sync,0,CH5,CH6,CH7,CH8,CH9,CH10,CH11,CH12
|
||||
57,1,HoTT,No_Sync,0,CH5,CH6,CH7,CH8,CH9,CH10,CH11,CH12
|
||||
57,0,HoTT,Sync,0,CH5,CH6,CH7,CH8,CH9,CH10,CH11,CH12,CH13,CH14,CH15,CH16
|
||||
57,1,HoTT,No_Sync,0,CH5,CH6,CH7,CH8,CH9,CH10,CH11,CH12,CH13,CH14,CH15,CH16
|
||||
2,0,Hubsan,H107,1,Flip,Light,Pict,Video,HLess
|
||||
2,1,Hubsan,H301,0,RTH,Light,Stab,Video
|
||||
2,2,Hubsan,H501,0,RTH,Light,Pict,Video,HLess,GPS_H,ALT_H,Flip,FModes
|
||||
22,0,J6Pro,Std,0,CH5,CH6,CH7,CH8,CH9,CH10,CH11,CH12
|
||||
71,0,JJRC345,Std,1,Flip,HLess,RTH
|
||||
71,0,JJRC345,JJRC345,1,Flip,HLess,RTH,LED,UNK1,UNK2,UNK3
|
||||
71,1,JJRC345,SkyTmblr,1,Flip,HLess,RTH,LED,UNK1,UNK2,UNK3
|
||||
49,0,KF606,Std,1,Trim
|
||||
9,0,KN,WLToys,0,DRate,THold,IdleUp,Gyro,Ttrim,Atrim,Etrim
|
||||
9,1,KN,Feilun,0,DRate,THold,IdleUp,Gyro,Ttrim,Atrim,Etrim
|
||||
@@ -122,6 +124,7 @@
|
||||
17,2,MT99XX,YZ,1,Flip,LED,Pict,Video,HLess
|
||||
17,3,MT99XX,LS,1,Flip,Invert,Pict,Video,HLess
|
||||
17,4,MT99XX,FY805,1,Flip,n-a,n-a,n-a,HLess
|
||||
17,5,MT99XX,A180,1,3D_6G
|
||||
44,0,NCC1701,Std,1,Warp
|
||||
77,0,OMP,M2,0,THold,IdleUp,6G_3D
|
||||
60,0,Pelikan,PRO_V4,0,CH5,CH6,CH7,CH8
|
||||
@@ -138,10 +141,11 @@
|
||||
72,0,Q90C,Std,0,FMode,VTX+
|
||||
74,0,RadioLink,Surface,0,CH5,CH6,CH7,CH8,FS_CH1,FS_CH2,FS_CH3,FS_CH4,FS_CH5,FS_CH6,FS_CH7,FS_CH8
|
||||
74,1,RadioLink,Air,0,CH5,CH6,CH7,CH8,FS_CH1,FS_CH2,FS_CH3,FS_CH4,FS_CH5,FS_CH6,FS_CH7,FS_CH8
|
||||
74,2,RadioLink,DumboRC,0,CH5,CH6,CH7,CH8,FS_CH1,FS_CH2,FS_CH3,FS_CH4,FS_CH5,FS_CH6,FS_CH7,FS_CH8
|
||||
76,0,Realacc,R11,1,Flip,Light,Calib,HLess,RTH,UNK
|
||||
50,0,Redpine,Fast,0,sCH5,sCH6,sCH7,sCH8,sCH9,sCH10,sCH11,sCH12,sCH13,sCH14,sCH15,sCH16
|
||||
50,1,Redpine,Slow,0,sCH5,sCH6,sCH7,sCH8,sCH9,sCH10,sCH11,sCH12,sCH13,sCH14,sCH15,sCH16
|
||||
21,0,SFHSS,Std,0,CH5,CH6,CH7,CH8
|
||||
21,0,Futaba,SFHSS,0,CH5,CH6,CH7,CH8
|
||||
19,0,Shenqi,Cycle,1
|
||||
68,0,Skyartec,Std,0,CH5,CH6,CH7
|
||||
11,0,SLT,V1,0,Gear,Pitch
|
||||
@@ -174,3 +178,9 @@
|
||||
8,3,YD717,XinXun,1,Flip,Light,Pict,Video,HLess
|
||||
8,4,YD717,NiHui,1,Flip,Light,Pict,Video,HLess
|
||||
52,0,ZSX,280,1,Light
|
||||
78,0,M-Link,Std,0,CH5,CH6,CH7,CH8,CH9,CH10,CH11,CH12,CH13,CH14,CH15,CH16
|
||||
79,0,WFLY2,RF20x,0,CH5,CH6,CH7,CH8,CH9,CH10
|
||||
80,0,E016Hv2,E016Hv2,1,TakLan,EmStop,Flip,Calib,HLess,RTH
|
||||
81,0,E010r5,E010r5,1,Flip,LED,CALIB,HLess,RTH,GLIDE
|
||||
82,0,LOLI,LOLI,0,CH5,CH6,CH7,CH8,1SwSePpPw,2SwSePw,3SwSe,4SwSe,5SwSeSb,6SwSe,7SwSePw,8SwSe
|
||||
83,0,E129,E129,1,TakLan,EmStop,TrimA,TrimE,TrimR
|
||||
|
||||
221
Lua_scripts/MultiLOLI.lua
Normal file
221
Lua_scripts/MultiLOLI.lua
Normal file
@@ -0,0 +1,221 @@
|
||||
|
||||
local toolName = "TNS|Multi LOLI RX config|TNE"
|
||||
|
||||
---- #########################################################################
|
||||
---- # #
|
||||
---- # Copyright (C) OpenTX #
|
||||
-----# #
|
||||
---- # License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html #
|
||||
---- # #
|
||||
---- # This program is free software; you can redistribute it and/or modify #
|
||||
---- # it under the terms of the GNU General Public License version 2 as #
|
||||
---- # published by the Free Software Foundation. #
|
||||
---- # #
|
||||
---- # This program is distributed in the hope that it will be useful #
|
||||
---- # but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
---- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
---- # GNU General Public License for more details. #
|
||||
---- # #
|
||||
---- #########################################################################
|
||||
|
||||
local loli_nok = false
|
||||
local channels={ { 768, "PWM", 100, 102, "PPM", 50, -768, "Servo", 0, -2048, "Switch", -100 }, -- CH1
|
||||
{ 768, "PWM", 100, -768, "Servo", 0, -2048, "Switch", -100 }, -- CH2
|
||||
{ -768, "Servo", 0, -2048, "Switch", -100 }, -- CH3
|
||||
{ -768, "Servo", 0, -2048, "Switch", -100 }, -- CH4
|
||||
{ 102, "SBUS", 50, -768, "Servo", 0, -2048, "Switch", -100 }, -- CH5
|
||||
{ -768, "Servo", 0, -2048, "Switch", -100 }, -- CH6
|
||||
{ 768, "PWM", 100, -768, "Servo", 0, -2048, "Switch", -100 }, -- CH7
|
||||
{ -768, "Servo", 0, -2048, "Switch", -100 } } -- CH8
|
||||
|
||||
local sel = 1
|
||||
local edit = false
|
||||
|
||||
local blink = 0
|
||||
local BLINK_SPEED = 15
|
||||
|
||||
local function drawScreenTitle(title)
|
||||
if LCD_W == 480 then
|
||||
lcd.drawFilledRectangle(0, 0, LCD_W, 30, TITLE_BGCOLOR)
|
||||
lcd.drawText(1, 5, title, MENU_TITLE_COLOR)
|
||||
else
|
||||
lcd.drawScreenTitle(title, 0, 0)
|
||||
end
|
||||
end
|
||||
|
||||
local function LOLI_Draw_LCD(event)
|
||||
local line = 0
|
||||
|
||||
lcd.clear()
|
||||
|
||||
--Display settings
|
||||
local lcd_opt = 0
|
||||
if LCD_W == 480 then
|
||||
drawScreenTitle("Multi - LOLI RX configuration tool")
|
||||
x_pos = 152
|
||||
x_inc = 90
|
||||
y_pos = 40
|
||||
y_inc = 20
|
||||
else
|
||||
x_pos = 5
|
||||
x_inc = 30
|
||||
y_pos = 1
|
||||
y_inc = 8
|
||||
lcd_opt = SMLSIZE
|
||||
end
|
||||
|
||||
--Multi Module detection
|
||||
if loli_nok then
|
||||
if LCD_W == 480 then
|
||||
lcd.drawText(10,50,"The LOLI protocol is not selected...", lcd_opt)
|
||||
else
|
||||
--Draw on LCD_W=128
|
||||
lcd.drawText(2,17,"LOLI protocol not selected...",SMLSIZE)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
--Display current config
|
||||
if LCD_W == 480 then
|
||||
line = line + 1
|
||||
lcd.drawText(x_pos, y_pos+y_inc*line -2, "Channel", lcd_opt)
|
||||
lcd.drawText(x_pos+x_inc, y_pos+y_inc*line -2, "Function", lcd_opt)
|
||||
lcd.drawRectangle(x_pos-4, y_pos+y_inc*line -4 , 2*x_inc +2, 188)
|
||||
lcd.drawLine(x_pos-4, y_pos+y_inc*line +18, x_pos-4 +2*x_inc +1, y_pos+y_inc*line +18, SOLID, 0)
|
||||
lcd.drawLine(x_pos+x_inc -5, y_pos+y_inc*line -4, x_pos+x_inc -5, y_pos+y_inc*line -5 +188, SOLID, 0)
|
||||
line = line + 1
|
||||
end
|
||||
|
||||
local out
|
||||
for i = 1, 8 do
|
||||
out = getValue("ch"..(i+8))
|
||||
lcd.drawText(x_pos, y_pos+y_inc*line, "CH"..i, lcd_opt)
|
||||
for j = 1, #channels[i], 3 do
|
||||
if out > channels[i][j] then
|
||||
if sel == i then
|
||||
invert = INVERS
|
||||
if edit == true then
|
||||
blink = blink + 1
|
||||
if blink > BLINK_SPEED then
|
||||
invert = 0
|
||||
if blink > BLINK_SPEED * 2 then
|
||||
blink = 0
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
invert = 0
|
||||
end
|
||||
lcd.drawText(x_pos+x_inc, y_pos+y_inc*line, channels[i][j+1], lcd_opt + invert)
|
||||
break
|
||||
end
|
||||
end
|
||||
line = line + 1
|
||||
end
|
||||
end
|
||||
|
||||
local function LOLI_Change_Value(dir)
|
||||
local pos = 0
|
||||
local out
|
||||
--look for the current position
|
||||
out = getValue("ch"..(sel+8))
|
||||
for j = 1, #channels[sel], 3 do
|
||||
if out > channels[sel][j] then
|
||||
pos = j
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
--decrement or increment
|
||||
if dir < 0 and pos > 1 then
|
||||
pos = pos - 3
|
||||
elseif dir > 0 and pos + 3 < #channels[sel] then
|
||||
pos = pos + 3
|
||||
else
|
||||
return
|
||||
end
|
||||
|
||||
--delete all mixers for the selected channel
|
||||
local num_mix = model.getMixesCount(sel-1 +8)
|
||||
for i = 1, num_mix do
|
||||
model.deleteMix(sel-1 +8, 0);
|
||||
end
|
||||
|
||||
--create new mixer
|
||||
local source_max = getFieldInfo("cyc1")
|
||||
|
||||
local val = { name = channels[sel][pos+1],
|
||||
source = source_max.id - 1, -- MAX=100 on TX16S
|
||||
weight = channels[sel][pos+2],
|
||||
offset = 0,
|
||||
switch = 0,
|
||||
multiplex = 0,
|
||||
curveType = 0,
|
||||
curveValue = 0,
|
||||
flightModes = 0,
|
||||
carryTrim = false,
|
||||
mixWarn = 0,
|
||||
delayUp = 0,
|
||||
delayDown = 0,
|
||||
speedUp = 0,
|
||||
speedDown = 0 }
|
||||
model.insertMix(sel-1 +8, 0, val)
|
||||
end
|
||||
|
||||
local function LOLI_Menu(event)
|
||||
if event == EVT_VIRTUAL_NEXT then
|
||||
if edit == false then
|
||||
-- not changing a value
|
||||
if sel < 8 then
|
||||
sel = sel + 1
|
||||
end
|
||||
else
|
||||
-- need to inc the value
|
||||
LOLI_Change_Value(1)
|
||||
end
|
||||
elseif event == EVT_VIRTUAL_PREV then
|
||||
if edit == false then
|
||||
-- not changing a value
|
||||
if sel > 1 then
|
||||
sel = sel - 1
|
||||
end
|
||||
else
|
||||
-- need to dec the value
|
||||
LOLI_Change_Value(-1)
|
||||
end
|
||||
elseif event == EVT_VIRTUAL_ENTER then
|
||||
if edit == false then
|
||||
edit = true
|
||||
blink = BLINK_SPEED
|
||||
else
|
||||
edit = false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Init
|
||||
local function LOLI_Init()
|
||||
local module_conf = model.getModule(0)
|
||||
if module_conf["Type"] ~= 6 or module_conf["protocol"] ~= 82 then
|
||||
module_conf = model.getModule(1)
|
||||
if module_conf["Type"] ~= 6 or module_conf["protocol"] ~= 82 then
|
||||
loli_nok = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Main
|
||||
local function LOLI_Run(event)
|
||||
if event == nil then
|
||||
error("Cannot be run as a model script!")
|
||||
return 2
|
||||
elseif event == EVT_VIRTUAL_EXIT then
|
||||
return 2
|
||||
else
|
||||
LOLI_Menu(event)
|
||||
LOLI_Draw_LCD(event)
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
||||
return { init=LOLI_Init, run=LOLI_Run }
|
||||
@@ -13,7 +13,7 @@ If you like this project and want to support further development please consider
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
## MultiChannelsUpdater.lua
|
||||
## MultiChannelsUpdater
|
||||
|
||||
Automatically name the channels based on the loaded Multi protocol and sub protocol including the module channel order convention.
|
||||
|
||||
@@ -21,7 +21,13 @@ Need OpenTX 2.3.9 or above. Located on the radio SD card under \SCRIPTS\TOOLS. T
|
||||
|
||||
[](https://www.youtube.com/watch?v=L58ayXuewyA)
|
||||
|
||||
## Graupner HoTT.ua
|
||||
## MultiLOLI
|
||||
|
||||
Script to set the channels function (switch, servo, pwm, ppm, sbus) on a [LOLI RX](https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/blob/master/Protocols_Details.md#loli---82)
|
||||
|
||||
[](https://www.youtube.com/watch?v=e698pQxfv-A)
|
||||
|
||||
## Graupner HoTT
|
||||
|
||||
Enable text configuration of the HoTT RX and sensors: Vario, GPS, ESC, GAM and EAM.
|
||||
|
||||
@@ -32,3 +38,19 @@ Notes:
|
||||
- It's normal to lose the telemetry feed while using the text mode configuration. Telemetry will resume properly if the script is exited by doing a short press on the exit button.
|
||||
|
||||
[](https://www.youtube.com/watch?v=81wd8NlF3Qw)
|
||||
|
||||
## DSM Forward Programming
|
||||
|
||||
This is a work in progress. It's only available for color screens (Horus, TX16S, T16, T18...).
|
||||
|
||||
If some text appears as Unknown_xxx, please report xxx and what the exact text display should be.
|
||||
|
||||
Need OpenTX 2.3.10 nightly or above. Located on the radio SD card under \SCRIPTS\TOOLS.
|
||||
|
||||
[](https://www.youtube.com/watch?v=sjIaDw5j9nE)
|
||||
|
||||
## DSM PID Flight log gain parameters for Blade micros
|
||||
|
||||
Lua telemetry script from [feathering on RCGroups](https://www.rcgroups.com/forums/showpost.php?p=46033341&postcount=20728) to facilitate setting the Gain Parameters on the Blade 150S FBL. It doesn't use Forward Programming but instead it just reads telemetry data from the Multi-module and displays it on a telemetry display.
|
||||
|
||||
It is very similar to the Telemetry Based Text Generator functionality on Spektrum transmitters where one doesn't need to rely on the angle of the swashplate to determine selection/value.
|
||||
|
||||
127
Lua_scripts/pidDsm.lua
Normal file
127
Lua_scripts/pidDsm.lua
Normal file
@@ -0,0 +1,127 @@
|
||||
--
|
||||
-- This telemetry script displays the Flight Log Gain
|
||||
-- Parameters streamed from the Blade 150S Spektrum AR6335A
|
||||
-- Flybarless Controller.
|
||||
|
||||
-- The script facilitates the setting of the FBL's
|
||||
-- Gain Parameters including PID for both
|
||||
-- cyclic and tail. It is similar to the Telemetry Based
|
||||
-- Text Generator available on Spektrum transmitters.
|
||||
|
||||
-- Supporting similar Blade micros such as the Fusion 180
|
||||
-- would possibly require minor modifications to this script.
|
||||
|
||||
-- This script reads telemetry data from the Spektrum
|
||||
-- receiver and thus functionality relies on data being
|
||||
-- captured by the OpenTX transmitter. A DSM
|
||||
-- telemetry-ready module is required. Please see the
|
||||
-- MULTI-Module project at https://www.multi-module.org/.
|
||||
|
||||
-- The only supported display is the Taranis'. It may work
|
||||
-- with higher res screens.
|
||||
--
|
||||
|
||||
|
||||
-- Sensor names
|
||||
local PSensor = "FdeA"
|
||||
local ISensor = "FdeB"
|
||||
local DSensor = "FdeL"
|
||||
local RSensor = "FdeR"
|
||||
local ActiveParamSensor = "Hold"
|
||||
|
||||
local tags = {"P", "I", "D"}
|
||||
|
||||
|
||||
local function getPage(iParam)
|
||||
-- get page from 0-based index
|
||||
-- {0,1,2,3}: cyclic (1), {4,5,6,7}: tail (2)
|
||||
local res = (math.floor(iParam/4)==0) and 1 or 2
|
||||
return res
|
||||
end
|
||||
|
||||
function round(v)
|
||||
-- round float
|
||||
local factor = 100
|
||||
return math.floor(v * factor + 0.5) / factor
|
||||
end
|
||||
|
||||
|
||||
local function readValue(sensor)
|
||||
-- read from sensor, round and return
|
||||
local v = getValue(sensor)
|
||||
v = round(v)
|
||||
return v
|
||||
end
|
||||
|
||||
local function readActiveParamValue(sensor)
|
||||
-- read and return a validated active parameter value
|
||||
local v = getValue(sensor)
|
||||
if (v<1 or v>8) then
|
||||
return nil
|
||||
end
|
||||
return v
|
||||
end
|
||||
|
||||
local function readParameters()
|
||||
-- read and return parameters
|
||||
local p = readValue(PSensor)
|
||||
local i = readValue(ISensor)
|
||||
local d = readValue(DSensor)
|
||||
local r = readValue(RSensor)
|
||||
local a = readActiveParamValue(ActiveParamSensor)
|
||||
return {p,i,d,r,a}
|
||||
end
|
||||
|
||||
local function drawParameters()
|
||||
-- draw labels and params on screen
|
||||
local params = readParameters()
|
||||
local activeParam = params[5]
|
||||
|
||||
-- if active gain does not validate then assume
|
||||
-- Gain Adjustment Mode is disabled
|
||||
if not activeParam then
|
||||
lcd.clear()
|
||||
lcd.drawText(20,30,"Please enter Gain Adjustment Mode")
|
||||
return
|
||||
end
|
||||
|
||||
local activePage = getPage(activeParam-1)
|
||||
for iParam=0,7 do
|
||||
-- highlight selected parameter
|
||||
local attr = (activeParam==iParam+1) and 2 or 0
|
||||
-- circular index (per page)
|
||||
local perPageIndx = iParam % 4 + 1
|
||||
-- check if displaying cyclic params.
|
||||
local isCyclicPage = (getPage(iParam)==1)
|
||||
-- set y draw coord
|
||||
local y = perPageIndx*10+2
|
||||
|
||||
-- labels
|
||||
local x = isCyclicPage and 6 or 120
|
||||
-- labels are P,I,D for both pages except for last param
|
||||
local val = iParam==3 and "Response" or
|
||||
(iParam==7 and "Filtering" or tags[perPageIndx])
|
||||
lcd.drawText (x, y, val, attr)
|
||||
|
||||
-- gains
|
||||
-- set all params for non-active page to '--' rather than 'last value'
|
||||
val = (getPage(iParam)==activePage) and params[perPageIndx] or '--'
|
||||
x = isCyclicPage and 70 or 180
|
||||
lcd.drawText (x, y, val, attr)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function run_func(event)
|
||||
-- TODO: calling clear() on every function call redrawing all labels is not ideal
|
||||
lcd.clear()
|
||||
lcd.drawText (8, 2, "Cyclic (0...200)")
|
||||
lcd.drawText (114, 2, "Tail (0...200)")
|
||||
drawParameters()
|
||||
end
|
||||
|
||||
local function init_func() end
|
||||
local function bg_func() end
|
||||
|
||||
|
||||
return { run=run_func, background=bg_func, init=init_func }
|
||||
@@ -27,13 +27,16 @@ void A7105_WriteData(uint8_t len, uint8_t channel)
|
||||
for (i = 0; i < len; i++)
|
||||
SPI_Write(packet[i]);
|
||||
A7105_CSN_on;
|
||||
if(protocol!=PROTO_FLYSKY)
|
||||
if(protocol!=PROTO_WFLY2)
|
||||
{
|
||||
A7105_Strobe(A7105_STANDBY); //Force standby mode, ie cancel any TX or RX...
|
||||
A7105_SetTxRxMode(TX_EN); //Switch to PA
|
||||
if(!(protocol==PROTO_FLYSKY || protocol==PROTO_KYOSHO))
|
||||
{
|
||||
A7105_Strobe(A7105_STANDBY); //Force standby mode, ie cancel any TX or RX...
|
||||
A7105_SetTxRxMode(TX_EN); //Switch to PA
|
||||
}
|
||||
A7105_WriteReg(A7105_0F_PLL_I, channel);
|
||||
A7105_Strobe(A7105_TX);
|
||||
}
|
||||
A7105_WriteReg(A7105_0F_PLL_I, channel);
|
||||
A7105_Strobe(A7105_TX);
|
||||
}
|
||||
|
||||
void A7105_ReadData(uint8_t len)
|
||||
@@ -107,7 +110,7 @@ void A7105_WriteID(uint32_t ida)
|
||||
{
|
||||
A7105_CSN_off;
|
||||
SPI_Write(A7105_06_ID_DATA); //ex id=0x5475c52a ;txid3txid2txid1txid0
|
||||
SPI_Write((ida>>24)&0xff); //53
|
||||
SPI_Write((ida>>24)&0xff); //54
|
||||
SPI_Write((ida>>16)&0xff); //75
|
||||
SPI_Write((ida>>8)&0xff); //c5
|
||||
SPI_Write((ida>>0)&0xff); //2a
|
||||
@@ -207,6 +210,11 @@ void A7105_AdjustLOBaseFreq(uint8_t cmd)
|
||||
offset=(int16_t)FORCE_KYOSHO_TUNING;
|
||||
#endif
|
||||
break;
|
||||
case PROTO_WFLY2:
|
||||
#ifdef FORCE_WFLY2_TUNING
|
||||
offset=(int16_t)FORCE_WFLY2_TUNING;
|
||||
#endif
|
||||
break;
|
||||
case PROTO_AFHDS2A:
|
||||
case PROTO_AFHDS2A_RX:
|
||||
#ifdef FORCE_AFHDS2A_TUNING
|
||||
@@ -216,7 +224,7 @@ void A7105_AdjustLOBaseFreq(uint8_t cmd)
|
||||
}
|
||||
}
|
||||
if(offset==1024) // Use channel 15 as an input
|
||||
offset=convert_channel_16b_nolimit(CH15,-300,300);
|
||||
offset=convert_channel_16b_nolimit(CH15,-300,300,false);
|
||||
|
||||
if(old_offset==offset) // offset is the same as before...
|
||||
return;
|
||||
@@ -318,6 +326,20 @@ const uint8_t PROGMEM KYOSHO_A7105_regs[] = {
|
||||
0x1e, 0x00, 0x00, 0xff, 0x00, 0x00, 0x23, 0x70, 0x1F, 0x47, 0x80, 0x57, 0x01, 0x45, 0x19, 0x00, // 20 - 2f
|
||||
0x01, 0x0f // 30 - 31
|
||||
};
|
||||
const uint8_t PROGMEM KYOSHO_HYPE_A7105_regs[] = {
|
||||
0xff, 0x42, 0x00, 0x10, 0xC0, 0xff, 0xff ,0x00, 0x00, 0x00, 0x00, 0x01, 0x09, 0x05, 0x01, 0x04, // 00 - 0f
|
||||
0x9e, 0x4b, 0x00, 0x02, 0x16, 0x2b, 0x12, 0x00, 0x62, 0x80, 0x80, 0x00, 0x0a, 0x96, 0xc2, 0x1f, // 10 - 1f
|
||||
0x12, 0x00, 0x00, 0xff, 0x00, 0x00, 0x3a, 0x00, 0x17, 0x47, 0x80, 0x03, 0x01, 0x45, 0x18, 0x00, // 20 - 2f
|
||||
0x01, 0x0f // 30 - 31
|
||||
};
|
||||
#endif
|
||||
#ifdef WFLY2_A7105_INO //A7106 values
|
||||
const uint8_t PROGMEM WFLY2_A7105_regs[] = {
|
||||
0xff, 0x62, 0xff, 0x1F, 0x40, 0xff, 0xff ,0x00, 0x00, 0x00, 0x00, 0x33, 0x33, 0x05, 0x00, 0x64, // 00 - 0f Changes: 0B:19->33, 0C:01,33
|
||||
0x9e, 0x4b, 0x00, 0x02, 0x16, 0x2b, 0x12, 0x40, 0x62, 0x80, 0x80, 0x00, 0x0a, 0x32, 0x03, 0x0f, // 10 - 1f 1C:4A->0A
|
||||
0x12, 0x00, 0x00, 0xff, 0x00, 0x00, 0x23, 0x70, 0x15, 0x47, 0x80, 0x03, 0x01, 0x45, 0x18, 0x00, // 20 - 2f 2B:77->03, 2E:19->18
|
||||
0x01, 0x0f // 30 - 31
|
||||
};
|
||||
#endif
|
||||
|
||||
#define ID_NORMAL 0x55201041
|
||||
@@ -327,6 +349,13 @@ void A7105_Init(void)
|
||||
uint8_t *A7105_Regs=0;
|
||||
uint8_t vco_calibration0, vco_calibration1;
|
||||
|
||||
#ifdef WFLY2_A7105_INO
|
||||
if(protocol==PROTO_WFLY2)
|
||||
{
|
||||
A7105_Regs=(uint8_t*)WFLY2_A7105_regs;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifdef HEIGHT_A7105_INO
|
||||
if(protocol==PROTO_HEIGHT)
|
||||
{
|
||||
@@ -363,12 +392,17 @@ void A7105_Init(void)
|
||||
A7105_Regs=(uint8_t*)FLYSKY_A7105_regs;
|
||||
#endif
|
||||
#if defined(AFHDS2A_A7105_INO) || defined(AFHDS2A_RX_A7105_INO)
|
||||
if(protocol==PROTO_AFHDS2A)
|
||||
if(protocol==PROTO_AFHDS2A || protocol==PROTO_AFHDS2A_RX)
|
||||
A7105_Regs=(uint8_t*)AFHDS2A_A7105_regs;
|
||||
#endif
|
||||
#ifdef KYOSHO_A7105_INO
|
||||
if(protocol==PROTO_KYOSHO)
|
||||
A7105_Regs=(uint8_t*)KYOSHO_A7105_regs;
|
||||
{
|
||||
if(sub_protocol==KYOSHO_FHSS)
|
||||
A7105_Regs=(uint8_t*)KYOSHO_A7105_regs;
|
||||
else
|
||||
A7105_Regs=(uint8_t*)KYOSHO_HYPE_A7105_regs;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -387,12 +421,12 @@ void A7105_Init(void)
|
||||
if(protocol==PROTO_HEIGHT && sub_protocol==HEIGHT_8CH)
|
||||
if(i==0x03) val=0x0A;
|
||||
#endif
|
||||
if( val != 0xFF)
|
||||
if( val != 0xff)
|
||||
A7105_WriteReg(i, val);
|
||||
}
|
||||
A7105_Strobe(A7105_STANDBY);
|
||||
|
||||
if(protocol==PROTO_KYOSHO)
|
||||
if(protocol==PROTO_KYOSHO && sub_protocol==KYOSHO_FHSS)
|
||||
{//strange calibration...
|
||||
//IF Filter Bank Calibration
|
||||
A7105_WriteReg(A7105_02_CALC,0x0F);
|
||||
@@ -431,7 +465,7 @@ void A7105_Init(void)
|
||||
while(A7105_ReadReg(A7105_02_CALC)); // Wait for calibration to end
|
||||
vco_calibration1 = A7105_ReadReg(A7105_25_VCO_SBCAL_I);
|
||||
|
||||
if(protocol==PROTO_BUGS)
|
||||
if(protocol==PROTO_BUGS || protocol==PROTO_WFLY2)
|
||||
A7105_SetVCOBand(vco_calibration0 & 0x07, vco_calibration1 & 0x07); // Set calibration band value to best match
|
||||
else
|
||||
if(protocol!=PROTO_HUBSAN)
|
||||
@@ -445,6 +479,7 @@ void A7105_Init(void)
|
||||
vco_calibration1=0x02;
|
||||
break;
|
||||
case PROTO_PELIKAN:
|
||||
case PROTO_KYOSHO: //sub_protocol Hype
|
||||
vco_calibration1=0x0C;
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
enum {
|
||||
AFHDS2A_RX_BIND1,
|
||||
AFHDS2A_RX_BIND2,
|
||||
AFHDS2A_RX_BIND3,
|
||||
AFHDS2A_RX_DATA
|
||||
};
|
||||
|
||||
@@ -39,7 +40,7 @@ static void __attribute__((unused)) AFHDS2A_Rx_build_telemetry_packet()
|
||||
packet_in[idx++] = 14; // number of channels in packet
|
||||
// pack channels
|
||||
for (uint8_t i = 0; i < 14; i++) {
|
||||
uint32_t val = packet[9+i*2] | ((packet[10+i*2] << 8)&0x0F);
|
||||
uint32_t val = packet[9+i*2] | (((packet[10+i*2])&0x0F) << 8);
|
||||
if (val < 860)
|
||||
val = 860;
|
||||
// convert ppm (860-2140) to Multi (0-2047)
|
||||
@@ -105,16 +106,17 @@ uint16_t AFHDS2A_Rx_callback()
|
||||
switch(phase) {
|
||||
case AFHDS2A_RX_BIND1:
|
||||
if(IS_BIND_DONE) return initAFHDS2A_Rx(); // Abort bind
|
||||
debugln("bind p=%d", phase+1);
|
||||
if (AFHDS2A_Rx_data_ready()) {
|
||||
A7105_ReadData(AFHDS2A_RX_TXPACKET_SIZE);
|
||||
if ((packet[0] == 0xbb && packet[9] == 0x01) || (packet[0] == 0xbc && packet[9] <= 0x02)) {
|
||||
memcpy(rx_id, &packet[1], 4); // TX id actually
|
||||
memcpy(hopping_frequency, &packet[11], AFHDS2A_RX_NUMFREQ);
|
||||
phase = AFHDS2A_RX_BIND2;
|
||||
debugln("phase bind2");
|
||||
}
|
||||
}
|
||||
A7105_WriteReg(A7105_0F_PLL_I, (packet_count++ & 1) ? 0x0D : 0x8C); // bind channels
|
||||
A7105_SetTxRxMode(RX_EN);
|
||||
A7105_Strobe(A7105_RX);
|
||||
return 10000;
|
||||
|
||||
@@ -132,32 +134,41 @@ uint16_t AFHDS2A_Rx_callback()
|
||||
eeprom_write_byte((EE_ADDR)temp++, rx_id[i]);
|
||||
for (i = 0; i < AFHDS2A_RX_NUMFREQ; i++)
|
||||
eeprom_write_byte((EE_ADDR)temp++, hopping_frequency[i]);
|
||||
BIND_DONE;
|
||||
phase = AFHDS2A_RX_DATA;
|
||||
return 3850;
|
||||
phase = AFHDS2A_RX_BIND3;
|
||||
debugln("phase bind3");
|
||||
packet_count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
case AFHDS2A_RX_BIND3:
|
||||
debugln("bind p=%d", phase+1);
|
||||
// transmit response packet
|
||||
packet[0] = 0xBC;
|
||||
memcpy(&packet[1], rx_id, 4);
|
||||
memcpy(&packet[5], rx_tx_addr, 4);
|
||||
packet[9] = 0x01;
|
||||
//packet[9] = 0x01;
|
||||
packet[10] = 0x00;
|
||||
memset(&packet[11], 0xFF, 26);
|
||||
A7105_SetTxRxMode(TX_EN);
|
||||
rx_disable_lna = !IS_POWER_FLAG_on;
|
||||
A7105_WriteData(AFHDS2A_RX_RXPACKET_SIZE, packet_count++ & 1 ? 0x0D : 0x8C);
|
||||
if(phase == AFHDS2A_RX_BIND3 && packet_count > 20)
|
||||
{
|
||||
debugln("done");
|
||||
BIND_DONE;
|
||||
return initAFHDS2A_Rx(); // Restart protocol
|
||||
}
|
||||
phase |= AFHDS2A_RX_WAIT_WRITE;
|
||||
return 1700;
|
||||
|
||||
case AFHDS2A_RX_BIND2 | AFHDS2A_RX_WAIT_WRITE:
|
||||
//Wait for TX completion
|
||||
pps_timer = micros();
|
||||
while (micros() - pps_timer < 700) // Wait max 700µs, using serial+telemetry exit in about 120µs
|
||||
while ((uint32_t)(micros() - pps_timer) < 700) // Wait max 700µs, using serial+telemetry exit in about 120µs
|
||||
if (!(A7105_ReadReg(A7105_00_MODE) & 0x01))
|
||||
break;
|
||||
A7105_SetTxRxMode(RX_EN);
|
||||
A7105_Strobe(A7105_RX);
|
||||
case AFHDS2A_RX_BIND3 | AFHDS2A_RX_WAIT_WRITE:
|
||||
phase &= ~AFHDS2A_RX_WAIT_WRITE;
|
||||
return 10000;
|
||||
|
||||
|
||||
@@ -270,11 +270,18 @@ static void AFHDS2A_build_packet(uint8_t type)
|
||||
}
|
||||
|
||||
#define AFHDS2A_WAIT_WRITE 0x80
|
||||
|
||||
#ifdef STM32_BOARD
|
||||
#define AFHDS2A_WRITE_TIME 1550
|
||||
#else
|
||||
#define AFHDS2A_WRITE_TIME 1700
|
||||
#endif
|
||||
|
||||
uint16_t ReadAFHDS2A()
|
||||
{
|
||||
static uint8_t packet_type;
|
||||
static uint16_t packet_counter;
|
||||
uint8_t data_rx;
|
||||
uint8_t data_rx=0;
|
||||
uint16_t start;
|
||||
#ifndef FORCE_AFHDS2A_TUNING
|
||||
A7105_AdjustLOBaseFreq(1);
|
||||
@@ -291,7 +298,7 @@ uint16_t ReadAFHDS2A()
|
||||
A7105_ReadData(AFHDS2A_RXPACKET_SIZE);
|
||||
if(packet[0] == 0xbc && packet[9] == 0x01)
|
||||
{
|
||||
uint8_t addr;
|
||||
uint16_t addr;
|
||||
if(RX_num<16)
|
||||
addr=AFHDS2A_EEPROM_OFFSET+RX_num*4;
|
||||
else
|
||||
@@ -313,13 +320,13 @@ uint16_t ReadAFHDS2A()
|
||||
return 3850;
|
||||
}
|
||||
phase |= AFHDS2A_WAIT_WRITE;
|
||||
return 1700;
|
||||
return AFHDS2A_WRITE_TIME;
|
||||
case AFHDS2A_BIND1|AFHDS2A_WAIT_WRITE:
|
||||
case AFHDS2A_BIND2|AFHDS2A_WAIT_WRITE:
|
||||
case AFHDS2A_BIND3|AFHDS2A_WAIT_WRITE:
|
||||
//Wait for TX completion
|
||||
start=micros();
|
||||
while ((uint16_t)micros()-start < 700) // Wait max 700µs, using serial+telemetry exit in about 120µs
|
||||
while ((uint16_t)((uint16_t)micros()-start) < 700) // Wait max 700µs, using serial+telemetry exit in about 120µs
|
||||
if(!(A7105_ReadReg(A7105_00_MODE) & 0x01))
|
||||
break;
|
||||
A7105_SetPower();
|
||||
@@ -329,7 +336,7 @@ uint16_t ReadAFHDS2A()
|
||||
phase++;
|
||||
if(phase > AFHDS2A_BIND3)
|
||||
phase = AFHDS2A_BIND1;
|
||||
return 2150;
|
||||
return 3850-AFHDS2A_WRITE_TIME;
|
||||
case AFHDS2A_BIND4:
|
||||
AFHDS2A_build_bind_packet();
|
||||
A7105_WriteData(AFHDS2A_TXPACKET_SIZE, packet_count%2 ? 0x0d : 0x8c);
|
||||
@@ -351,10 +358,8 @@ uint16_t ReadAFHDS2A()
|
||||
telemetry_set_input_sync(3850);
|
||||
#endif
|
||||
AFHDS2A_build_packet(packet_type);
|
||||
if((A7105_ReadReg(A7105_00_MODE) & 0x01)) // Check if something has been received...
|
||||
data_rx=0;
|
||||
else
|
||||
data_rx=1; // Yes
|
||||
if((A7105_ReadReg(A7105_00_MODE) & 0x01)==0) // Check if something has been received...
|
||||
data_rx=1; // Yes
|
||||
A7105_WriteData(AFHDS2A_TXPACKET_SIZE, hopping_frequency[hopping_frequency_no++]);
|
||||
if(hopping_frequency_no >= AFHDS2A_NUMFREQ)
|
||||
hopping_frequency_no = 0;
|
||||
@@ -370,13 +375,13 @@ uint16_t ReadAFHDS2A()
|
||||
}
|
||||
else
|
||||
#endif
|
||||
packet_type = AFHDS2A_PACKET_STICKS; // todo : check for settings changes
|
||||
packet_type = AFHDS2A_PACKET_STICKS; // todo : check for settings changes
|
||||
}
|
||||
if(!(A7105_ReadReg(A7105_00_MODE) & (1<<5 | 1<<6)) && data_rx==1)
|
||||
{ // RX+FECF+CRCF Ok
|
||||
A7105_ReadData(AFHDS2A_RXPACKET_SIZE);
|
||||
if(packet[0] == 0xAA && packet[9] == 0xFC)
|
||||
packet_type=AFHDS2A_PACKET_SETTINGS; // RX is asking for settings
|
||||
packet_type=AFHDS2A_PACKET_SETTINGS; // RX is asking for settings
|
||||
else
|
||||
if((packet[0] == 0xAA && packet[9]!=0xFD) || packet[0] == 0xAC)
|
||||
{// Normal telemetry packet, ignore packets which contain the RX configuration: AA FD FF 32 00 01 00 FF FF FF 05 DC 05 DE FA FF FF FF FF FF FF FF FF FF FF FF FF FF FF
|
||||
@@ -399,18 +404,18 @@ uint16_t ReadAFHDS2A()
|
||||
}
|
||||
packet_counter++;
|
||||
phase |= AFHDS2A_WAIT_WRITE;
|
||||
return 1700;
|
||||
return AFHDS2A_WRITE_TIME;
|
||||
case AFHDS2A_DATA|AFHDS2A_WAIT_WRITE:
|
||||
//Wait for TX completion
|
||||
start=micros();
|
||||
while ((uint16_t)micros()-start < 700) // Wait max 700µs, using serial+telemetry exit in about 120µs
|
||||
while ((uint16_t)((uint16_t)micros()-start) < 700) // Wait max 700µs, using serial+telemetry exit in about 120µs
|
||||
if(!(A7105_ReadReg(A7105_00_MODE) & 0x01))
|
||||
break;
|
||||
A7105_SetPower();
|
||||
A7105_SetTxRxMode(RX_EN);
|
||||
A7105_Strobe(A7105_RX);
|
||||
phase &= ~AFHDS2A_WAIT_WRITE;
|
||||
return 2150;
|
||||
return 3850-AFHDS2A_WRITE_TIME;
|
||||
}
|
||||
return 3850; // never reached, please the compiler
|
||||
}
|
||||
@@ -428,7 +433,7 @@ uint16_t initAFHDS2A()
|
||||
{
|
||||
phase = AFHDS2A_DATA_INIT;
|
||||
//Read RX ID from EEPROM based on RX_num, RX_num must be uniq for each RX
|
||||
uint8_t addr;
|
||||
uint16_t addr;
|
||||
if(RX_num<16)
|
||||
addr=AFHDS2A_EEPROM_OFFSET+RX_num*4;
|
||||
else
|
||||
|
||||
@@ -115,7 +115,7 @@ void delayMilliseconds(unsigned long ms)
|
||||
uint16_t lms = ms ;
|
||||
|
||||
while (lms > 0) {
|
||||
if (((uint16_t)micros() - start) >= 1000) {
|
||||
if ((uint16_t)((uint16_t)micros() - start) >= 1000) {
|
||||
lms--;
|
||||
start += 1000;
|
||||
}
|
||||
|
||||
@@ -143,19 +143,19 @@ static void __attribute__((unused)) BAYANG_send_packet()
|
||||
if(CH13_SW)
|
||||
packet[3] |= BAYANG_FLAG_EMG_STOP;
|
||||
//Aileron
|
||||
val = convert_channel_10b(AILERON);
|
||||
val = convert_channel_10b(AILERON, false);
|
||||
packet[4] = (val>>8) + (dyntrim ? ((val>>2) & 0xFC) : 0x7C);
|
||||
packet[5] = val & 0xFF;
|
||||
//Elevator
|
||||
val = convert_channel_10b(ELEVATOR);
|
||||
val = convert_channel_10b(ELEVATOR, false);
|
||||
packet[6] = (val>>8) + (dyntrim ? ((val>>2) & 0xFC) : 0x7C);
|
||||
packet[7] = val & 0xFF;
|
||||
//Throttle
|
||||
val = convert_channel_10b(THROTTLE);
|
||||
val = convert_channel_10b(THROTTLE, false);
|
||||
packet[8] = (val>>8) + 0x7C;
|
||||
packet[9] = val & 0xFF;
|
||||
//Rudder
|
||||
val = convert_channel_10b(RUDDER);
|
||||
val = convert_channel_10b(RUDDER, false);
|
||||
packet[10] = (val>>8) + (dyntrim ? ((val>>2) & 0xFC) : 0x7C);
|
||||
packet[11] = val & 0xFF;
|
||||
}
|
||||
@@ -218,7 +218,7 @@ static void __attribute__((unused)) BAYANG_check_rx(void)
|
||||
for (uint8_t i=1; i < BAYANG_PACKET_SIZE-1; i++)
|
||||
check += packet[i];
|
||||
// decode data , check sum is ok as well, since there is no crc
|
||||
if (packet[0] == 0x85 && packet[14] == check)
|
||||
if (packet[0] == 0x85 && packet[14] == check && telemetry_link == 0)
|
||||
{
|
||||
// uncompensated battery volts*100/2
|
||||
v_lipo1 = (packet[3]<<7) + (packet[4]>>1);
|
||||
@@ -230,9 +230,16 @@ static void __attribute__((unused)) BAYANG_check_rx(void)
|
||||
//Flags
|
||||
//uint8_t flags = packet[3] >> 3;
|
||||
// battery low: flags & 1
|
||||
telemetry_link=1;
|
||||
#if defined HUB_TELEMETRY
|
||||
// Multiplexed P, I, D values in packet[8] and packet[9].
|
||||
// The two most significant bits specify which term is sent.
|
||||
// Remaining 14 bits represent the value: 0 .. 16383
|
||||
frsky_send_user_frame(0x24+(packet[8]>>6), packet[9], packet[8] & 0x3F ); //0x24 = ACCEL_X_ID, so ACCEL_X_ID=P, ACCEL_Y_ID=I, ACCEL_Z_ID=D
|
||||
#endif
|
||||
telemetry_counter++;
|
||||
if(telemetry_lost==0)
|
||||
telemetry_link=1;
|
||||
if(telemetry_lost)
|
||||
telemetry_link=0; // Don't send anything yet
|
||||
}
|
||||
}
|
||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||
@@ -367,4 +374,4 @@ uint16_t initBAYANG(void)
|
||||
return BAYANG_INITIAL_WAIT+BAYANG_PACKET_PERIOD;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -48,6 +48,7 @@ Bit(s) Bitmask Option Comment
|
||||
11 0x400 MULTI_STATUS Indicates if MULTI_STATUS is defined
|
||||
12 0x800 MULTI_TELEMETRY Indicates if MULTI_TELEMETRY is defined
|
||||
13 0x1000 DEBUG_SERIAL Indicates if DEBUG_SERIAL is defined
|
||||
14-16 0xE000 Module sub-type Reads as a three-bit value indicating a number from 0-7 which maps to a module sub-type (right-shift 13 bits to read)
|
||||
|
||||
The 8-byte version number is the version number zero-padded to a fixed width of two-bytes per segment and no separator.
|
||||
E.g. 1.2.3.45 becomes 01020345.
|
||||
@@ -60,9 +61,15 @@ OpenTX 2 10
|
||||
|
||||
Module types are mapped to the following decimal / binary values:
|
||||
Module Type Decimal Value Binary Valsue
|
||||
AVR 0 00
|
||||
STM32 1 01
|
||||
OrangeRX 2 10
|
||||
AVR (Atmega328p) 0 00
|
||||
STM32 (F103) 1 01
|
||||
OrangeRX (Xmega) 2 10
|
||||
|
||||
Module sub-type is currently used for STM32F103 only and is mapped as follows:
|
||||
Module Type Sub Type Decimal Value Binary Value
|
||||
STM32 (F103) STM32F103CB 0 000
|
||||
STM32 (F103) STM32F103C8 1 001
|
||||
STM32 (F103) T18 5in1 2 010
|
||||
|
||||
Channel orders are mapped to the following decimal / binary values:
|
||||
Channel Order Decimal Value Binary Value
|
||||
@@ -109,6 +116,17 @@ RTEA 23 10111
|
||||
bool firmwareFlag_DEBUG_SERIAL = true;
|
||||
#endif
|
||||
|
||||
// STM32 Module sub-type flags
|
||||
#if defined (MCU_STM32F103CB)
|
||||
bool firmwareFlag_MCU_STM32F103CB = true;
|
||||
#endif
|
||||
#if defined (MCU_STM32F103C8)
|
||||
bool firmwareFlag_MCU_STM32F103C8 = true;
|
||||
#endif
|
||||
#if defined (MULTI_5IN1_INTERNAL)
|
||||
bool firmwareFlag_MULTI_5IN1_INTERNAL = true;
|
||||
#endif
|
||||
|
||||
// Channel order flags
|
||||
#if defined (AETR)
|
||||
bool firmwareFlag_ChannelOrder_AETR = true;
|
||||
|
||||
@@ -340,7 +340,7 @@ uint16_t ReadBUGS(void)
|
||||
case BUGS_BIND_2:
|
||||
//Wait for TX completion
|
||||
start=micros();
|
||||
while ((uint16_t)micros()-start < 500) // Wait max 500µs, using serial+telemetry exit in about 60µs
|
||||
while ((uint16_t)((uint16_t)micros()-start) < 500) // Wait max 500µs, using serial+telemetry exit in about 60µs
|
||||
if(!(A7105_ReadReg(A7105_00_MODE) & 0x01))
|
||||
break;
|
||||
A7105_SetTxRxMode(RX_EN);
|
||||
@@ -399,7 +399,7 @@ uint16_t ReadBUGS(void)
|
||||
case BUGS_DATA_2:
|
||||
//Wait for TX completion
|
||||
start=micros();
|
||||
while ((uint16_t)micros()-start < 500) // Wait max 500µs, using serial+telemetry exit in about 60µs
|
||||
while ((uint16_t)((uint16_t)micros()-start) < 500) // Wait max 500µs, using serial+telemetry exit in about 60µs
|
||||
if(!(A7105_ReadReg(A7105_00_MODE) & 0x01))
|
||||
break;
|
||||
A7105_SetTxRxMode(RX_EN);
|
||||
|
||||
@@ -163,4 +163,174 @@ void CC2500_SetPower()
|
||||
prev_power=power;
|
||||
}
|
||||
}
|
||||
|
||||
void __attribute__((unused)) CC2500_SetFreqOffset()
|
||||
{
|
||||
if(prev_option != option)
|
||||
{
|
||||
prev_option = option;
|
||||
CC2500_WriteReg(CC2500_0C_FSCTRL0, option);
|
||||
}
|
||||
}
|
||||
|
||||
void __attribute__((unused)) CC2500_250K_Init()
|
||||
{
|
||||
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();
|
||||
}
|
||||
void __attribute__((unused)) CC2500_250K_HoppingCalib(uint8_t num_freq)
|
||||
{
|
||||
for (uint8_t i = 0; i < num_freq; i++)
|
||||
{
|
||||
CC2500_Strobe(CC2500_SIDLE);
|
||||
// spacing is 333.25 kHz, must multiply channel by 3
|
||||
CC2500_WriteReg(CC2500_0A_CHANNR, hopping_frequency[i]*3);
|
||||
// calibrate
|
||||
CC2500_Strobe(CC2500_SCAL);
|
||||
delayMicroseconds(900);
|
||||
calData[i]=CC2500_ReadReg(CC2500_25_FSCAL1);
|
||||
}
|
||||
}
|
||||
void __attribute__((unused)) CC2500_250K_Hopping(uint8_t index)
|
||||
{
|
||||
// spacing is 333.25 kHz, must multiply channel by 3
|
||||
CC2500_WriteReg(CC2500_0A_CHANNR, hopping_frequency[index] * 3);
|
||||
// set PLL calibration
|
||||
CC2500_WriteReg(CC2500_25_FSCAL1, calData[index]);
|
||||
}
|
||||
void __attribute__((unused)) CC2500_250K_RFChannel(uint8_t number)
|
||||
{
|
||||
CC2500_Strobe(CC2500_SIDLE);
|
||||
// spacing is 333.25 kHz, must multiply channel by 3
|
||||
CC2500_WriteReg(CC2500_0A_CHANNR, number*3);
|
||||
// calibrate
|
||||
CC2500_Strobe(CC2500_SCAL);
|
||||
delayMicroseconds(900);
|
||||
}
|
||||
|
||||
//NRF emulation layer with CRC16 enabled
|
||||
uint8_t cc2500_nrf_tx_addr[5], cc2500_nrf_addr_len;
|
||||
void __attribute__((unused)) CC2500_250K_NRF_SetTXAddr(uint8_t* addr, uint8_t len)
|
||||
{
|
||||
cc2500_nrf_addr_len = len;
|
||||
memcpy(cc2500_nrf_tx_addr, addr, len);
|
||||
}
|
||||
void __attribute__((unused)) CC2500_250K_NRF_WritePayload(uint8_t* msg, uint8_t len)
|
||||
{
|
||||
#if defined(ESKY150V2_CC2500_INO)
|
||||
uint8_t buf[158];
|
||||
#else
|
||||
uint8_t buf[35];
|
||||
#endif
|
||||
uint8_t last = 0;
|
||||
uint8_t i;
|
||||
|
||||
//nrf preamble
|
||||
if(cc2500_nrf_tx_addr[cc2500_nrf_addr_len - 1] & 0x80)
|
||||
buf[0]=0xAA;
|
||||
else
|
||||
buf[0]=0x55;
|
||||
last++;
|
||||
// address
|
||||
for (i = 0; i < cc2500_nrf_addr_len; ++i)
|
||||
buf[last++] = cc2500_nrf_tx_addr[cc2500_nrf_addr_len - i - 1];
|
||||
// payload
|
||||
for (i = 0; i < len; ++i)
|
||||
buf[last++] = msg[i];
|
||||
|
||||
// crc
|
||||
crc = 0xffff;
|
||||
for (uint8_t i = 1; i < last; ++i)
|
||||
crc16_update( buf[i], 8);
|
||||
buf[last++] = crc >> 8;
|
||||
buf[last++] = crc & 0xff;
|
||||
buf[last++] = 0;
|
||||
|
||||
//for(uint8_t i=0;i<last;i++)
|
||||
// debug("%02X ",buf[i]);
|
||||
//debugln("");
|
||||
// stop TX/RX
|
||||
CC2500_Strobe(CC2500_SIDLE);
|
||||
// flush tx FIFO
|
||||
CC2500_Strobe(CC2500_SFTX);
|
||||
// packet length
|
||||
CC2500_WriteReg(CC2500_3F_TXFIFO, last);
|
||||
// transmit nrf packet
|
||||
uint8_t *buff=buf;
|
||||
uint8_t status;
|
||||
if(last>63)
|
||||
{
|
||||
CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, buff, 63);
|
||||
CC2500_Strobe(CC2500_STX);
|
||||
last-=63;
|
||||
buff+=63;
|
||||
while(last)
|
||||
{//Loop until all the data is sent
|
||||
do
|
||||
{// Wait for the FIFO to become available
|
||||
status=CC2500_ReadReg(CC2500_3A_TXBYTES | CC2500_READ_BURST);
|
||||
}
|
||||
while((status&0x7F)>31 && (status&0x80)==0);
|
||||
if(last>31)
|
||||
{//Send 31 bytes
|
||||
CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, buff, 31);
|
||||
last-=31;
|
||||
buff+=31;
|
||||
}
|
||||
else
|
||||
{//Send last bytes
|
||||
CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, buff, last);
|
||||
last=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{//Send packet
|
||||
CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, buff, last);
|
||||
CC2500_Strobe(CC2500_STX);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -19,17 +19,17 @@
|
||||
|
||||
#include "iface_nrf24l01.h"
|
||||
|
||||
#define CX10_BIND_COUNT 4360 // 6 seconds
|
||||
#define CX10_BIND_COUNT 4360 // 6 seconds
|
||||
#define CX10_PACKET_SIZE 15
|
||||
#define CX10A_PACKET_SIZE 19 // CX10 blue board packets have 19-byte payload
|
||||
#define CX10A_PACKET_SIZE 19 // CX10 blue board packets have 19-byte payload
|
||||
#define Q2X2_PACKET_SIZE 21
|
||||
#define CX10_PACKET_PERIOD 1316 // Timeout for callback in uSec
|
||||
#define CX10_PACKET_PERIOD 1316 // Timeout for callback in uSec
|
||||
#define CX10A_PACKET_PERIOD 6000
|
||||
|
||||
#define CX10_INITIAL_WAIT 500
|
||||
|
||||
// flags
|
||||
#define CX10_FLAG_FLIP 0x10 // goes to rudder channel
|
||||
#define CX10_FLAG_FLIP 0x10 // goes to rudder channel
|
||||
#define CX10_FLAG_MODE_MASK 0x03
|
||||
#define CX10_FLAG_HEADLESS 0x04
|
||||
// flags2
|
||||
@@ -181,7 +181,7 @@ static void __attribute__((unused)) CX10_init()
|
||||
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowledgment on all data pipes
|
||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 only
|
||||
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, packet_length); // rx pipe 0 (used only for blue board)
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, CX10_RF_BIND_CHANNEL);
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, CX10_RF_BIND_CHANNEL);
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps
|
||||
NRF24L01_SetPower();
|
||||
}
|
||||
@@ -220,7 +220,8 @@ uint16_t CX10_callback()
|
||||
NRF24L01_FlushTx();
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
CX10_Write_Packet(1);
|
||||
delayMicroseconds(400);
|
||||
// wait for packet to be sent
|
||||
while( (NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_TX_DS)) == 0); //delayMicroseconds(400);
|
||||
// switch to RX mode
|
||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||
NRF24L01_FlushRx();
|
||||
|
||||
@@ -98,14 +98,14 @@ void CYRF_SetTxRxMode(uint8_t mode)
|
||||
{
|
||||
if(mode==TXRX_OFF)
|
||||
{
|
||||
if(protocol!=PROTO_WFLY)
|
||||
if( protocol!=PROTO_WFLY && protocol!=PROTO_MLINK )
|
||||
CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x24); // 4=IDLE, 8=TX, C=RX
|
||||
CYRF_WriteRegister(CYRF_0E_GPIO_CTRL,0x00); // XOUT=0 PACTL=0
|
||||
}
|
||||
else
|
||||
{
|
||||
//Set the post tx/rx state
|
||||
if(protocol!=PROTO_WFLY)
|
||||
if( protocol!=PROTO_WFLY && protocol!=PROTO_MLINK )
|
||||
CYRF_WriteRegister(CYRF_0F_XACT_CFG, mode == TX_EN ? 0x28 : 0x2C); // 4=IDLE, 8=TX, C=RX
|
||||
if(mode == TX_EN)
|
||||
#ifdef ORANGE_TX_BLUE
|
||||
@@ -168,10 +168,10 @@ void CYRF_SetPower(uint8_t val)
|
||||
/*
|
||||
*
|
||||
*/
|
||||
void CYRF_ConfigCRCSeed(uint16_t crc)
|
||||
void CYRF_ConfigCRCSeed(uint16_t crc_seed)
|
||||
{
|
||||
CYRF_WriteRegister(CYRF_15_CRC_SEED_LSB,crc & 0xff);
|
||||
CYRF_WriteRegister(CYRF_16_CRC_SEED_MSB,crc >> 8);
|
||||
CYRF_WriteRegister(CYRF_15_CRC_SEED_LSB,crc_seed & 0xff);
|
||||
CYRF_WriteRegister(CYRF_16_CRC_SEED_MSB,crc_seed >> 8);
|
||||
}
|
||||
/*
|
||||
* these are the recommended sop codes from Cyrpress
|
||||
@@ -321,4 +321,69 @@ static void __attribute__((unused)) CYRF_PROGMEM_ConfigSOPCode(const uint8_t *da
|
||||
code[i]=pgm_read_byte_near(&data[i]);
|
||||
CYRF_ConfigSOPCode(code);
|
||||
}
|
||||
|
||||
//CYRF GFSK 1Mb functions
|
||||
const uint8_t PROGMEM CYRF_GFSK1M_init_vals[][2] = {
|
||||
{CYRF_02_TX_CTRL, 0x00}, // transmit err & complete interrupts disabled
|
||||
{CYRF_05_RX_CTRL, 0x00}, // receive err & complete interrupts disabled
|
||||
{CYRF_28_CLK_EN, 0x02}, // Force Receive Clock Enable, MUST be set
|
||||
{CYRF_32_AUTO_CAL_TIME, 0x3c}, // must be set to 3C
|
||||
{CYRF_35_AUTOCAL_OFFSET, 0x14}, // must be set to 14
|
||||
{CYRF_06_RX_CFG, 0x48}, // LNA manual control, Rx Fast Turn Mode Enable
|
||||
{CYRF_1B_TX_OFFSET_LSB, 0x00}, // Tx frequency offset LSB
|
||||
{CYRF_1C_TX_OFFSET_MSB, 0x00}, // Tx frequency offset MSB
|
||||
{CYRF_0F_XACT_CFG, 0x24}, // Force End State, transaction end state = idle
|
||||
{CYRF_03_TX_CFG, 0x00}, // GFSK mode
|
||||
{CYRF_12_DATA64_THOLD, 0x0a}, // 64 Chip Data PN Code Correlator Threshold = 10
|
||||
{CYRF_0F_XACT_CFG, 0x04}, // Transaction End State = idle
|
||||
{CYRF_39_ANALOG_CTRL, 0x01}, // synth setting time for all channels is the same as for slow channels
|
||||
{CYRF_0F_XACT_CFG, 0x24}, //Force IDLE
|
||||
{CYRF_29_RX_ABORT, 0x00}, //Clear RX abort
|
||||
{CYRF_12_DATA64_THOLD, 0x0a}, //set pn correlation threshold
|
||||
{CYRF_10_FRAMING_CFG, 0x4a}, //set sop len and threshold
|
||||
{CYRF_29_RX_ABORT, 0x0f}, //Clear RX abort?
|
||||
{CYRF_03_TX_CFG, 0x00}, // GFSK mode
|
||||
{CYRF_10_FRAMING_CFG, 0x4a}, // 0b11000000 //set sop len and threshold
|
||||
{CYRF_1F_TX_OVERRIDE, 0x04}, //disable tx CRC
|
||||
{CYRF_1E_RX_OVERRIDE, 0x14}, //disable rx crc
|
||||
{CYRF_14_EOP_CTRL, 0x00}, //set EOP sync == 0
|
||||
};
|
||||
static void __attribute__((unused)) CYRF_GFSK1M_Init(uint8_t payload_length, uint8_t preamble_len)
|
||||
{
|
||||
for(uint8_t i = 0; i < sizeof(CYRF_GFSK1M_init_vals) / 2; i++)
|
||||
CYRF_WriteRegister(pgm_read_byte_near(&CYRF_GFSK1M_init_vals[i][0]), pgm_read_byte_near(&CYRF_GFSK1M_init_vals[i][1]));
|
||||
|
||||
|
||||
CYRF_WriteRegister(CYRF_01_TX_LENGTH, payload_length);
|
||||
|
||||
CYRF_WritePreamble(0xAAAA00 | preamble_len);
|
||||
|
||||
CYRF_SetPower(0x00);
|
||||
|
||||
CYRF_SetTxRxMode(TX_EN);
|
||||
}
|
||||
static void __attribute__((unused)) CYRF_GFSK1M_SendPayload(uint8_t *buffer, uint8_t len)
|
||||
{
|
||||
uint8_t send=len>16 ? 16 : len;
|
||||
CYRF_WriteRegister(CYRF_02_TX_CTRL, 0x40);
|
||||
CYRF_WriteRegisterMulti(CYRF_20_TX_BUFFER, buffer, send); // Fill the buffer with 16 bytes max
|
||||
CYRF_WriteRegister(CYRF_02_TX_CTRL, 0x80); // Start send
|
||||
buffer += send;
|
||||
len -= send;
|
||||
|
||||
while(len>8)
|
||||
{
|
||||
while((CYRF_ReadRegister(CYRF_04_TX_IRQ_STATUS)&0x10) == 0); // Wait that half of the buffer is empty
|
||||
CYRF_WriteRegisterMulti(CYRF_20_TX_BUFFER, buffer, 8); // Add 8 bytes to the buffer
|
||||
buffer+=8;
|
||||
len-=8;
|
||||
}
|
||||
|
||||
if(len)
|
||||
{
|
||||
while((CYRF_ReadRegister(CYRF_04_TX_IRQ_STATUS)&0x10) == 0); // Wait that half of the buffer is empty
|
||||
CYRF_WriteRegisterMulti(CYRF_20_TX_BUFFER, buffer, len); // Add the remaining bytes to the buffer
|
||||
}
|
||||
}
|
||||
#define CYRF_GFSK1M_SetPower() CYRF_SetPower(0x00)
|
||||
#endif
|
||||
@@ -32,9 +32,15 @@ uint16_t convert_channel_ppm(uint8_t num)
|
||||
}
|
||||
|
||||
// Channel value 100% is converted to 10bit values 0<->1023
|
||||
uint16_t convert_channel_10b(uint8_t num)
|
||||
uint16_t convert_channel_10b(uint8_t num, bool failsafe)
|
||||
{
|
||||
uint16_t val=Channel_data[num];
|
||||
uint16_t val;
|
||||
#ifdef FAILSAFE_ENABLE
|
||||
if(failsafe)
|
||||
val=Failsafe_data[num]; // 0<->2047
|
||||
else
|
||||
#endif
|
||||
val=Channel_data[num];
|
||||
val=((val<<2)+val)>>3;
|
||||
if(val<=128) return 0;
|
||||
if(val>=1152) return 1023;
|
||||
@@ -91,9 +97,15 @@ int16_t convert_channel_16b_limit(uint8_t num,int16_t min,int16_t max)
|
||||
}
|
||||
|
||||
// Channel value -125%<->125% is scaled to 16bit value with no limit
|
||||
int16_t convert_channel_16b_nolimit(uint8_t num, int16_t min, int16_t max)
|
||||
int16_t convert_channel_16b_nolimit(uint8_t num, int16_t min, int16_t max, bool failsafe)
|
||||
{
|
||||
int32_t val=Channel_data[num]; // 0<->2047
|
||||
int32_t val;
|
||||
#ifdef FAILSAFE_ENABLE
|
||||
if(failsafe)
|
||||
val=Failsafe_data[num]; // 0<->2047
|
||||
else
|
||||
#endif
|
||||
val=Channel_data[num]; // 0<->2047
|
||||
val=(val-CHANNEL_MIN_100)*(max-min)/(CHANNEL_MAX_100-CHANNEL_MIN_100)+min;
|
||||
return (uint16_t)val;
|
||||
}
|
||||
@@ -151,14 +163,14 @@ static uint16_t __attribute__((unused)) FrSkyX_scaleForPXX( uint8_t i, uint8_t
|
||||
}
|
||||
|
||||
#ifdef FAILSAFE_ENABLE
|
||||
static uint16_t __attribute__((unused)) FrSkyX_scaleForPXX_FS( uint8_t i )
|
||||
static uint16_t __attribute__((unused)) FrSkyX_scaleForPXX_FS( uint8_t i, uint8_t num_chan=8)
|
||||
{ //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
|
||||
if(i>=num_chan) chan_val|=2048; // upper channels offset
|
||||
return chan_val;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -61,7 +61,6 @@ static void __attribute__((unused)) CORONA_rf_init()
|
||||
CC2500_WriteReg(CC2500_15_DEVIATN, 0x50);
|
||||
}
|
||||
|
||||
prev_option = option;
|
||||
CC2500_WriteReg(CC2500_0C_FSCTRL0, option);
|
||||
|
||||
//not sure what they are doing to the PATABLE since basically only the first byte is used and it's only 8 bytes long. So I think they end up filling the PATABLE fully with 0xFF
|
||||
@@ -262,11 +261,7 @@ uint16_t ReadCORONA()
|
||||
telemetry_set_input_sync(22000);
|
||||
#endif
|
||||
// Tune frequency if it has been changed
|
||||
if ( prev_option != option )
|
||||
{
|
||||
CC2500_WriteReg(CC2500_0C_FSCTRL0, option);
|
||||
prev_option = option ;
|
||||
}
|
||||
CC2500_SetFreqOffset();
|
||||
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
|
||||
#include "iface_cyrf6936.h"
|
||||
|
||||
//#define DSM_DEBUG_FWD_PGM
|
||||
|
||||
//#define DSM_GR300
|
||||
|
||||
#define DSM_BIND_CHANNEL 0x0d //13 This can be any odd channel
|
||||
@@ -151,6 +153,7 @@ static void __attribute__((unused)) DSM_build_data_packet(uint8_t upper)
|
||||
if(sub_protocol==DSM2_22)
|
||||
bits=10; // Only DSM2_22 is using a resolution of 1024
|
||||
}
|
||||
|
||||
#ifdef DSM_THROTTLE_KILL_CH
|
||||
uint16_t kill_ch=Channel_data[DSM_THROTTLE_KILL_CH-1];
|
||||
#endif
|
||||
@@ -181,7 +184,7 @@ static void __attribute__((unused)) DSM_build_data_packet(uint8_t upper)
|
||||
if(option & 0x80)
|
||||
value=Channel_data[CH_TAER[idx]]; // -100%..+100% => 1024..1976us and -125%..+125% => 904..2096us based on Redcon 6 channel DSM2 RX
|
||||
else
|
||||
value=convert_channel_16b_nolimit(CH_TAER[idx],0x156,0x6AA); // -100%..+100% => 1100..1900us and -125%..+125% => 1000..2000us based on a DX8 G2 dump
|
||||
value=convert_channel_16b_nolimit(CH_TAER[idx],0x156,0x6AA,false); // -100%..+100% => 1100..1900us and -125%..+125% => 1000..2000us based on a DX8 G2 dump
|
||||
#endif
|
||||
if(bits==10) value>>=1;
|
||||
value |= (upper && i==0 ? 0x8000 : 0) | (idx << bits);
|
||||
@@ -189,6 +192,23 @@ static void __attribute__((unused)) DSM_build_data_packet(uint8_t upper)
|
||||
packet[i*2+2] = (value >> 8) & 0xff;
|
||||
packet[i*2+3] = (value >> 0) & 0xff;
|
||||
}
|
||||
#ifdef DSM_FWD_PGM
|
||||
if(upper==0 && DSM_SerialRX && (DSM_SerialRX_val[0]&0xF8)==0x70 )
|
||||
{ // Send forward programming data if available
|
||||
for(uint8_t i=0; i<(DSM_SerialRX_val[0]&0x07);i++)
|
||||
{
|
||||
packet[i*2+4]=0x70+i;
|
||||
packet[i*2+5]=DSM_SerialRX_val[i+1];
|
||||
}
|
||||
DSM_SerialRX=false;
|
||||
#ifdef DSM_DEBUG_FWD_PGM
|
||||
debug("FWD=");
|
||||
for(uint8_t i=4; i<16;i++)
|
||||
debug(" %02X",packet[i]);
|
||||
debugln("");
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static uint8_t __attribute__((unused)) DSM_Check_RX_packet()
|
||||
@@ -306,10 +326,11 @@ uint16_t ReadDsm()
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(11000); // Always request 11ms spacing even if we don't use half of it in 22ms mode
|
||||
#endif
|
||||
CYRF_SetPower(0x28); //Keep transmit power in sync
|
||||
case DSM_CH1_WRITE_B:
|
||||
DSM_build_data_packet(phase == DSM_CH1_WRITE_B); // build lower or upper channels
|
||||
case DSM_CH2_WRITE_A:
|
||||
case DSM_CH2_WRITE_B:
|
||||
DSM_build_data_packet(phase == DSM_CH1_WRITE_B||phase == DSM_CH2_WRITE_B); // build lower or upper channels
|
||||
CYRF_ReadRegister(CYRF_04_TX_IRQ_STATUS); // clear IRQ flags
|
||||
CYRF_WriteDataPacket(packet);
|
||||
#if 0
|
||||
@@ -344,8 +365,6 @@ uint16_t ReadDsm()
|
||||
phase++; // change from CH1_CHECK to CH2_WRITE
|
||||
return DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY;
|
||||
}
|
||||
if (phase == DSM_CH2_CHECK_A)
|
||||
CYRF_SetPower(0x28); //Keep transmit power in sync
|
||||
#if defined DSM_TELEMETRY
|
||||
phase++; // change from CH2_CHECK to CH2_READ
|
||||
CYRF_SetTxRxMode(RX_EN); //Receive mode
|
||||
@@ -368,6 +387,15 @@ uint16_t ReadDsm()
|
||||
if(len>TELEMETRY_BUFFER_SIZE-2)
|
||||
len=TELEMETRY_BUFFER_SIZE-2;
|
||||
CYRF_ReadDataPacketLen(packet_in+1, len);
|
||||
#ifdef DSM_DEBUG_FWD_PGM
|
||||
//debug(" %02X", packet_in[1]);
|
||||
if(packet_in[1]==9)
|
||||
{
|
||||
for(uint8_t i=0;i<len;i++)
|
||||
debug(" %02X", packet_in[i+1]);
|
||||
debugln("");
|
||||
}
|
||||
#endif
|
||||
packet_in[0]=CYRF_ReadRegister(CYRF_13_RSSI)&0x1F;// store RSSI of the received telemetry signal
|
||||
telemetry_link=1;
|
||||
}
|
||||
|
||||
@@ -146,7 +146,7 @@ static void __attribute__((unused)) DEVO_build_data_pkt()
|
||||
uint8_t sign = 0x0b;
|
||||
for (uint8_t i = 0; i < 4; i++)
|
||||
{
|
||||
int16_t value=convert_channel_16b_nolimit(CH_EATR[ch_idx * 4 + i],-1600,1600);//range -1600..+1600
|
||||
int16_t value=convert_channel_16b_nolimit(CH_EATR[ch_idx * 4 + i],-1600,1600,false);//range -1600..+1600
|
||||
if(value < 0)
|
||||
{
|
||||
value = -value;
|
||||
|
||||
141
Multiprotocol/E010R5_cyrf6936.ino
Normal file
141
Multiprotocol/E010R5_cyrf6936.ino
Normal file
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
This project is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Multiprotocol is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if defined(E010R5_CYRF6936_INO)
|
||||
|
||||
#include "iface_rf2500.h"
|
||||
|
||||
#define E010R5_FORCE_ID
|
||||
|
||||
#define E010R5_BIND_CH 0x2D //45
|
||||
#define E010R5_PAYLOAD_SIZE 14
|
||||
|
||||
|
||||
static void __attribute__((unused)) E010R5_build_data_packet()
|
||||
{
|
||||
packet[ 0] = 0x0D; // Packet length
|
||||
packet[ 1] = convert_channel_8b(THROTTLE);
|
||||
packet[ 2] = convert_channel_s8b(RUDDER);
|
||||
packet[ 3] = convert_channel_s8b(ELEVATOR);
|
||||
packet[ 4] = convert_channel_s8b(AILERON);
|
||||
packet[ 5] = 0x20; // Trim Rudder
|
||||
packet[ 6] = 0x20; // Trim Elevator
|
||||
packet[ 7] = 0x20; // Trim Aileron
|
||||
packet[ 8] = 0x01 // Flags: high=0x01, low=0x00
|
||||
| GET_FLAG(CH5_SW, 0x04) // flip=0x04
|
||||
| GET_FLAG(CH6_SW, 0x08) // led=0x08
|
||||
| GET_FLAG(CH8_SW, 0x10) // headless=0x10
|
||||
| GET_FLAG(CH9_SW, 0x20); // one key return=0x20
|
||||
packet[ 9] = IS_BIND_IN_PROGRESS ? 0x80 : 0x00 // Flags: bind=0x80
|
||||
| GET_FLAG(CH7_SW, 0x20) // calib=0x20
|
||||
| GET_FLAG(CH10_SW, 0x01); // strange effect=0x01=long press on right button
|
||||
packet[10] = rx_tx_addr[0];
|
||||
packet[11] = rx_tx_addr[1];
|
||||
packet[12] = rx_tx_addr[2];
|
||||
packet[13] = 0x9D; // Check
|
||||
for(uint8_t i=0;i<13;i++)
|
||||
packet[13] += packet[i];
|
||||
|
||||
RF2500_BuildPayload(packet);
|
||||
}
|
||||
|
||||
uint16_t ReadE010R5()
|
||||
{
|
||||
//Bind
|
||||
if(bind_counter)
|
||||
{
|
||||
bind_counter--;
|
||||
if(bind_counter==0)
|
||||
BIND_DONE;
|
||||
}
|
||||
|
||||
//Send packet
|
||||
RF2500_SendPayload();
|
||||
|
||||
//Timing and hopping
|
||||
packet_count++;
|
||||
switch(packet_count)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
case 4:
|
||||
case 5:
|
||||
return 1183;
|
||||
default:
|
||||
hopping_frequency_no++;
|
||||
hopping_frequency_no &= 3;
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
rf_ch_num = 0x30 + (hopping_frequency_no<<3);
|
||||
else
|
||||
rf_ch_num = hopping_frequency[hopping_frequency_no];
|
||||
RF2500_RFChannel(rf_ch_num);
|
||||
RF2500_SetPower();
|
||||
packet_count = 0;
|
||||
case 3:
|
||||
E010R5_build_data_packet();
|
||||
return 3400;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t initE010R5()
|
||||
{
|
||||
BIND_IN_PROGRESS; // Autobind protocol
|
||||
bind_counter = 2600;
|
||||
|
||||
//RF2500 emu init
|
||||
RF2500_Init(E010R5_PAYLOAD_SIZE, false); // 14 bytes, not scrambled
|
||||
RF2500_SetTXAddr((uint8_t*)"\x0E\x54\x96\xEE"); // Same address for bind and normal packets
|
||||
|
||||
#ifdef E010R5_FORCE_ID
|
||||
switch(rx_tx_addr[3]%3)
|
||||
{
|
||||
case 0:
|
||||
//TX1
|
||||
hopping_frequency[0]=0x35; //53
|
||||
hopping_frequency[1]=0x30; //48
|
||||
rx_tx_addr[1]=0x45;
|
||||
rx_tx_addr[2]=0x46;
|
||||
break;
|
||||
case 1:
|
||||
//TX2
|
||||
hopping_frequency[0]=0x35; //53
|
||||
hopping_frequency[1]=0x3C; //60
|
||||
rx_tx_addr[1]=0x1B;
|
||||
rx_tx_addr[2]=0x9E;
|
||||
break;
|
||||
default:
|
||||
//TX3
|
||||
hopping_frequency[0]=0x30; //48
|
||||
hopping_frequency[1]=0x38; //56
|
||||
rx_tx_addr[1]=0x17;
|
||||
rx_tx_addr[2]=0x0D;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
rx_tx_addr[0]=0x00;
|
||||
// This is the same as the E010 v1...
|
||||
hopping_frequency[2]=hopping_frequency[0]+0x10;
|
||||
hopping_frequency[3]=hopping_frequency[1]+0x10;
|
||||
|
||||
E010R5_build_data_packet();
|
||||
RF2500_RFChannel(hopping_frequency[0]);
|
||||
hopping_frequency_no=0;
|
||||
packet_count=0;
|
||||
|
||||
return 3400;
|
||||
}
|
||||
|
||||
#endif
|
||||
158
Multiprotocol/E016HV2_cc2500.ino
Normal file
158
Multiprotocol/E016HV2_cc2500.ino
Normal file
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
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(E016HV2_CC2500_INO)
|
||||
|
||||
#include "iface_cc2500.h"
|
||||
|
||||
//#define FORCE_E016HV2_ORIGINAL_ID
|
||||
|
||||
#define E016HV2_INITIAL_WAIT 500
|
||||
#define E016HV2_PACKET_PERIOD 10000
|
||||
#define E016HV2_RF_BIND_CHANNEL 5
|
||||
#define E016HV2_PAYLOAD_SIZE 11
|
||||
#define E016HV2_BIND_COUNT 300 //3sec
|
||||
|
||||
static void __attribute__((unused)) E016HV2_send_packet()
|
||||
{
|
||||
//payload length (after this byte)
|
||||
packet[0 ] = 0x0A;
|
||||
|
||||
//bind indicator
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
packet[1 ] = 0x02;
|
||||
if(bind_counter)
|
||||
bind_counter--;
|
||||
else
|
||||
{
|
||||
BIND_DONE;
|
||||
CC2500_250K_RFChannel(rf_ch_num); // Set main channel
|
||||
}
|
||||
}
|
||||
else
|
||||
packet[1 ] = 0x20;
|
||||
|
||||
//ID
|
||||
packet[2 ] = rx_tx_addr[2];
|
||||
packet[3 ] = rx_tx_addr[3];
|
||||
|
||||
//channels TREA
|
||||
uint8_t channel;
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
channel=0x64; // Throttle must be centered during bind
|
||||
else
|
||||
channel=convert_channel_8b_limit_deadband(THROTTLE,0x00,0x64,0xC8, 20);
|
||||
packet[4 ] = channel;
|
||||
channel=convert_channel_16b_limit(RUDDER,0x00,0xC8);
|
||||
packet[5 ] = channel;
|
||||
channel=convert_channel_16b_limit(ELEVATOR,0x00,0xC8);
|
||||
packet[6 ] = channel;
|
||||
channel=convert_channel_16b_limit(AILERON,0x00,0xC8);
|
||||
packet[7 ] = channel;
|
||||
|
||||
//flags
|
||||
if(CH8_SW && !phase) //toggle calib flag
|
||||
flags ^= 0x40;
|
||||
phase=CH8_SW;
|
||||
|
||||
packet[8 ] = GET_FLAG(CH7_SW, 0x01) // 0x01=Flip
|
||||
| GET_FLAG(CH9_SW, 0x02) // 0x02=Headless
|
||||
| GET_FLAG(CH10_SW, 0x04) // 0x04=One Key Return
|
||||
| flags; // 0x40=Calib
|
||||
|
||||
packet[9 ] = 0x02; // Speed control 0x00:low, 0x01:medium, 0x02:high
|
||||
|
||||
packet[10] = GET_FLAG(CH5_SW, 0x01) // 0x01=TakeOff/Land (momentary switch)
|
||||
| GET_FLAG(CH6_SW, 0x04); // 0x04=Emergeny Stop (momentary switch)
|
||||
|
||||
CC2500_SetPower(); // Set tx_power
|
||||
CC2500_SetFreqOffset(); // Set frequency offset
|
||||
|
||||
//Build real packet and send it
|
||||
static uint8_t pid=0;
|
||||
crc=0;
|
||||
|
||||
// stop TX/RX
|
||||
CC2500_Strobe(CC2500_SIDLE);
|
||||
// flush tx FIFO
|
||||
CC2500_Strobe(CC2500_SFTX);
|
||||
// packet length
|
||||
CC2500_WriteReg(CC2500_3F_TXFIFO, 6 + 4 + 1 + 11 + 2); // preamble + address + packet_control + payload + crc
|
||||
|
||||
// preamble+address
|
||||
CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, (uint8_t*)"\xAA\xAA\xAA\xAA\xAA\xAA\xE7\xE7\xE7\xE7", 10);
|
||||
|
||||
// packet control
|
||||
CC2500_WriteReg(CC2500_3F_TXFIFO, 0x50+(pid<<2));
|
||||
pid++;
|
||||
|
||||
// payload
|
||||
//debug("P:")
|
||||
for (uint8_t i = 0; i < E016HV2_PAYLOAD_SIZE; ++i)
|
||||
{
|
||||
uint8_t byte = (bit_reverse(packet[i])<<1) | (packet[i+1]&0x01);
|
||||
//debug(" %02X",byte)
|
||||
CC2500_WriteReg(CC2500_3F_TXFIFO,byte);
|
||||
crc16_update(byte, 8);
|
||||
}
|
||||
|
||||
// crc
|
||||
CC2500_WriteReg(CC2500_3F_TXFIFO,crc >> 8);
|
||||
CC2500_WriteReg(CC2500_3F_TXFIFO,crc);
|
||||
//debugln(" %04X",crc)
|
||||
|
||||
// transmit
|
||||
CC2500_Strobe(CC2500_STX);
|
||||
}
|
||||
|
||||
uint16_t E016HV2_callback()
|
||||
{
|
||||
E016HV2_send_packet();
|
||||
return E016HV2_PACKET_PERIOD;
|
||||
}
|
||||
|
||||
uint16_t initE016HV2()
|
||||
{
|
||||
//Config CC2500
|
||||
CC2500_250K_Init();
|
||||
CC2500_250K_RFChannel(E016HV2_RF_BIND_CHANNEL); // Set bind channel
|
||||
|
||||
#ifdef FORCE_E016HV2_ORIGINAL_ID
|
||||
rx_tx_addr[2]=0x27;
|
||||
rx_tx_addr[3]=0x1B;
|
||||
//rf_ch_num = 44;
|
||||
#endif
|
||||
//General ID
|
||||
//3F1B -> 68,2C1B -> 49,2B1B -> 48,2A1B -> 47,291B -> 46,281B -> 45,271B -> 44,261B -> 43,251B -> 42
|
||||
//241B -> no bind,231B -> no bind,221B -> 71,211B -> 70,201B -> 69,1F1B -> 68,1E1B -> 67,1D1B -> 66,1C1B -> 65,1B1B -> 64,1A1B -> 63,191B -> 62,181B -> 61,171B -> 60,161B -> 59
|
||||
//0C1B -> 49,051B -> 42,041B -> no bind,031B -> no bind,021B -> 71,011B -> 70,001B -> no bind
|
||||
if(rx_tx_addr[2]<3) rx_tx_addr[2]+=3; // rx_tx_addr[2]=0 is invalid
|
||||
if(rx_tx_addr[3]==0) rx_tx_addr[3]+=64; // rx_tx_addr[3]=0 is invalid
|
||||
rf_ch_num = (rx_tx_addr[2] + rx_tx_addr[3]) % 32 + 42;
|
||||
if(rf_ch_num>71) // channels 72 and 73 are invalid
|
||||
{
|
||||
rx_tx_addr[2]-=2;
|
||||
rf_ch_num-=2;
|
||||
}
|
||||
|
||||
phase=CH8_SW;
|
||||
flags=0;
|
||||
bind_counter = E016HV2_BIND_COUNT;
|
||||
BIND_IN_PROGRESS; // Autobind protocol
|
||||
return E016HV2_INITIAL_WAIT;
|
||||
}
|
||||
|
||||
#endif
|
||||
152
Multiprotocol/E129_cyrf6936.ino
Normal file
152
Multiprotocol/E129_cyrf6936.ino
Normal file
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
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(E129_CYRF6936_INO)
|
||||
|
||||
#include "iface_rf2500.h"
|
||||
|
||||
//#define E129_FORCE_ID
|
||||
|
||||
#define E129_BIND_CH 0x2D //45
|
||||
#define E129_PAYLOAD_SIZE 16
|
||||
|
||||
static void __attribute__((unused)) E129_build_data_packet()
|
||||
{
|
||||
//Build the packet
|
||||
memset(packet,0,E129_PAYLOAD_SIZE);
|
||||
packet[ 0] = 0x0F; // Packet length
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
packet[ 1] = 0xA4;
|
||||
packet[ 2] = bit_reverse(rx_tx_addr[2]);
|
||||
packet[ 3] = bit_reverse(rx_tx_addr[3]);
|
||||
packet[ 4] = bit_reverse(rx_tx_addr[0]);
|
||||
packet[ 5] = bit_reverse(rx_tx_addr[1]);
|
||||
for(uint8_t i=0; i<4; i++)
|
||||
packet[6+i]=hopping_frequency[i]-2;
|
||||
}
|
||||
else
|
||||
{
|
||||
packet[ 1] = 0xA6;
|
||||
packet[ 2] = 0xF7; // High rate 0xF7, low rate 0xF4
|
||||
//packet[ 3] = 0x00; // Mode: short press=0x20->0x00->0x20->..., long press=0x10->0x30->0x10->...
|
||||
packet[ 4] = GET_FLAG(CH5_SW, 0x20) // Take off/Land 0x20
|
||||
| GET_FLAG(CH6_SW, 0x04); // Emergency stop 0x04
|
||||
|
||||
uint16_t val = convert_channel_10b(AILERON,false);
|
||||
uint8_t trim = convert_channel_8b(CH7) & 0xFC;
|
||||
packet[ 5] = trim | (val >>8); // Trim (0x00..0x1F..0x3E) << 2 | channel >> 8
|
||||
packet[ 6] = val; // channel (0x000...0x200...0x3FF)
|
||||
val = convert_channel_10b(ELEVATOR,false);
|
||||
trim = convert_channel_8b(CH8) & 0xFC;
|
||||
packet[ 7] = trim | (val >>8); // Trim (0x00..0x1F..0x3E) << 2 | channel >> 8
|
||||
packet[ 8] = val; // channel (0x000...0x200...0x3FF)
|
||||
if(packet_count>200)
|
||||
val = convert_channel_10b(THROTTLE,false);
|
||||
else
|
||||
{//Allow bind to complete with throttle not centered
|
||||
packet_count++;
|
||||
val=0x200;
|
||||
}
|
||||
packet[ 9] = (0x1F<<2) | (val >>8); // Trim (0x00..0x1F..0x3E) << 2 | channel >> 8
|
||||
packet[10] = val; // channel (0x000...0x200...0x3FF)
|
||||
val = convert_channel_10b(RUDDER,false);
|
||||
trim = convert_channel_8b(CH9) & 0xFC;
|
||||
packet[11] = trim | (val >>8); // Trim (0x00..0x1F..0x3E) << 2 | channel >> 8
|
||||
packet[12] = val; // channel (0x000...0x200...0x3FF)
|
||||
}
|
||||
packet[14] = 0x00; // Check
|
||||
for(uint8_t i=0;i<14;i++)
|
||||
packet[14] += packet[i];
|
||||
|
||||
RF2500_BuildPayload(packet);
|
||||
}
|
||||
|
||||
uint16_t ReadE129()
|
||||
{
|
||||
//Set RF channel
|
||||
if(phase==0)
|
||||
RF2500_RFChannel(IS_BIND_IN_PROGRESS ? E129_BIND_CH : hopping_frequency[hopping_frequency_no]);
|
||||
|
||||
//Send packet
|
||||
RF2500_SendPayload();
|
||||
|
||||
//Send twice on same channel
|
||||
if(phase==0)
|
||||
{
|
||||
phase++;
|
||||
return 1260;
|
||||
}
|
||||
|
||||
//Bind
|
||||
if(bind_counter)
|
||||
{
|
||||
bind_counter--;
|
||||
if(bind_counter==0)
|
||||
{
|
||||
BIND_DONE;
|
||||
RF2500_SetTXAddr(rx_tx_addr); // 4 bytes of address
|
||||
}
|
||||
}
|
||||
|
||||
//Build packet
|
||||
E129_build_data_packet();
|
||||
|
||||
//Set power
|
||||
RF2500_SetPower();
|
||||
|
||||
//Hopp
|
||||
hopping_frequency_no++;
|
||||
hopping_frequency_no &= 3;
|
||||
|
||||
phase=0;
|
||||
return 5200-1260;
|
||||
}
|
||||
|
||||
uint16_t initE129()
|
||||
{
|
||||
BIND_IN_PROGRESS; // Autobind protocol
|
||||
bind_counter = 384; // ~2sec
|
||||
|
||||
//RF2500 emu init
|
||||
RF2500_Init(E129_PAYLOAD_SIZE, true); // 16 bytes, Scrambled
|
||||
|
||||
//Freq hopping
|
||||
calc_fh_channels(4);
|
||||
for(uint8_t i=0; i<4; i++)
|
||||
if(hopping_frequency[i]==E129_BIND_CH)
|
||||
hopping_frequency[i]++;
|
||||
|
||||
#ifdef E129_FORCE_ID
|
||||
rx_tx_addr[0]=0xC1;
|
||||
rx_tx_addr[1]=0x22;
|
||||
rx_tx_addr[2]=0x05;
|
||||
rx_tx_addr[3]=0xA3;
|
||||
hopping_frequency[0]=0x3C; //60
|
||||
hopping_frequency[1]=0x49; //73
|
||||
hopping_frequency[2]=0x4B; //75
|
||||
hopping_frequency[3]=0x41; //65
|
||||
#endif
|
||||
|
||||
RF2500_SetTXAddr((uint8_t*)"\xE2\x32\xE0\xC8"); // 4 bytes of bind address
|
||||
|
||||
E129_build_data_packet();
|
||||
hopping_frequency_no=0;
|
||||
packet_count=0;
|
||||
phase=0;
|
||||
return 1260;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
#if defined(ESKY150V2_CC2500_INO)
|
||||
|
||||
#include "iface_nrf250k.h"
|
||||
#include "iface_cc2500.h"
|
||||
|
||||
//#define ESKY150V2_FORCE_ID
|
||||
|
||||
@@ -52,17 +52,17 @@ static void __attribute__((unused)) ESKY150V2_set_freq(void)
|
||||
hopping_frequency[ESKY150V2_NFREQCHANNELS]=ESKY150V2_BIND_CHANNEL;
|
||||
|
||||
//Calib all channels
|
||||
NRF250K_SetFreqOffset(); // Set frequency offset
|
||||
NRF250K_HoppingCalib(ESKY150V2_NFREQCHANNELS+1);
|
||||
CC2500_SetFreqOffset(); // Set frequency offset
|
||||
CC2500_250K_HoppingCalib(ESKY150V2_NFREQCHANNELS+1);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) ESKY150V2_send_packet()
|
||||
{
|
||||
NRF250K_SetFreqOffset(); // Set frequency offset
|
||||
NRF250K_Hopping(hopping_frequency_no);
|
||||
CC2500_SetFreqOffset(); // Set frequency offset
|
||||
CC2500_250K_Hopping(hopping_frequency_no);
|
||||
if (++hopping_frequency_no >= ESKY150V2_NFREQCHANNELS)
|
||||
hopping_frequency_no = 0;
|
||||
NRF250K_SetPower(); //Set power level
|
||||
CC2500_SetPower(); //Set power level
|
||||
|
||||
packet[0] = 0xFA; // Unknown
|
||||
packet[1] = 0x41; // Unknown
|
||||
@@ -74,12 +74,11 @@ static void __attribute__((unused)) ESKY150V2_send_packet()
|
||||
packet[4+2*i] = channel;
|
||||
packet[5+2*i] = channel>>8;
|
||||
}
|
||||
NRF250K_WritePayload(packet, ESKY150V2_PAYLOADSIZE);
|
||||
CC2500_250K_NRF_WritePayload(packet, ESKY150V2_PAYLOADSIZE);
|
||||
}
|
||||
|
||||
uint16_t ESKY150V2_callback()
|
||||
{
|
||||
if(option==0) option=1; //Trick the RF component auto select system
|
||||
if(IS_BIND_DONE)
|
||||
{
|
||||
#ifdef MULTI_SYNC
|
||||
@@ -90,14 +89,14 @@ uint16_t ESKY150V2_callback()
|
||||
else
|
||||
{
|
||||
BIND_DONE; //Need full power for bind to work...
|
||||
NRF250K_SetPower(); //Set power level
|
||||
CC2500_SetPower(); //Set power level
|
||||
BIND_IN_PROGRESS;
|
||||
NRF250K_WritePayload(packet, ESKY150V2_BINDPAYLOADSIZE);
|
||||
CC2500_250K_NRF_WritePayload(packet, ESKY150V2_BINDPAYLOADSIZE);
|
||||
if (--bind_counter == 0)
|
||||
{
|
||||
BIND_DONE;
|
||||
// Change TX address from bind to normal mode
|
||||
NRF250K_SetTXAddr(rx_tx_addr, ESKY150V2_TXID_SIZE);
|
||||
CC2500_250K_NRF_SetTXAddr(rx_tx_addr, ESKY150V2_TXID_SIZE);
|
||||
memset(packet,0x00,ESKY150V2_PAYLOADSIZE);
|
||||
}
|
||||
return 30000; //ESKY150V2_BINDING_PACKET_PERIOD;
|
||||
@@ -107,8 +106,7 @@ uint16_t ESKY150V2_callback()
|
||||
|
||||
uint16_t initESKY150V2()
|
||||
{
|
||||
if(option==0) option=1; // Trick the RF component auto select system
|
||||
NRF250K_Init();
|
||||
CC2500_250K_Init();
|
||||
ESKY150V2_set_freq();
|
||||
hopping_frequency_no = 0;
|
||||
|
||||
@@ -120,8 +118,8 @@ uint16_t initESKY150V2()
|
||||
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
NRF250K_SetTXAddr((uint8_t *)"\x73\x73\x74\x63", ESKY150V2_TXID_SIZE); //Bind address
|
||||
NRF250K_Hopping(ESKY150V2_NFREQCHANNELS); //Bind channel
|
||||
CC2500_250K_NRF_SetTXAddr((uint8_t *)"\x73\x73\x74\x63", ESKY150V2_TXID_SIZE); //Bind address
|
||||
CC2500_250K_Hopping(ESKY150V2_NFREQCHANNELS); //Bind channel
|
||||
memcpy(packet,"\x73\x73\x74\x63", ESKY150V2_TXID_SIZE);
|
||||
memcpy(&packet[ESKY150V2_TXID_SIZE],rx_tx_addr, ESKY150V2_TXID_SIZE);
|
||||
packet[8]=0x41; //Unknown
|
||||
@@ -134,7 +132,7 @@ uint16_t initESKY150V2()
|
||||
bind_counter=100;
|
||||
}
|
||||
else
|
||||
NRF250K_SetTXAddr(rx_tx_addr, ESKY150V2_TXID_SIZE);
|
||||
CC2500_250K_NRF_SetTXAddr(rx_tx_addr, ESKY150V2_TXID_SIZE);
|
||||
return 50000;
|
||||
}
|
||||
|
||||
|
||||
@@ -52,24 +52,18 @@ static void __attribute__((unused)) ssv_pack_dpl(uint8_t addr[], uint8_t pid, ui
|
||||
header[0] = (addr[4] >> 7);
|
||||
|
||||
// calculate the crc
|
||||
union
|
||||
{
|
||||
uint8_t bytes[2];
|
||||
uint16_t val;
|
||||
} crc;
|
||||
|
||||
crc.val=0x3c18;
|
||||
crc=0x3c18;
|
||||
for (i = 0; i < 7; ++i)
|
||||
crc.val=crc16_update(crc.val,header[i],8);
|
||||
crc16_update(header[i],8);
|
||||
for (i = 0; i < *len; ++i)
|
||||
crc.val=crc16_update(crc.val,payload[i],8);
|
||||
crc16_update(payload[i],8);
|
||||
|
||||
// encode payload and crc
|
||||
// xor with this:
|
||||
for (i = 0; i < *len; ++i)
|
||||
payload[i] ^= ssv_xor[i];
|
||||
crc.bytes[1] ^= ssv_xor[i++];
|
||||
crc.bytes[0] ^= ssv_xor[i++];
|
||||
crc ^= ssv_xor[i++]<<8;
|
||||
crc ^= ssv_xor[i++];
|
||||
|
||||
// pack the pcf, payload, and crc into packed_payload
|
||||
packed_payload[0] = pcf >> 1;
|
||||
@@ -78,11 +72,11 @@ static void __attribute__((unused)) ssv_pack_dpl(uint8_t addr[], uint8_t pid, ui
|
||||
for (i = 0; i < *len - 1; ++i)
|
||||
packed_payload[i+2] = (payload[i] << 7) | (payload[i+1] >> 1);
|
||||
|
||||
packed_payload[i+2] = (payload[i] << 7) | (crc.val >> 9);
|
||||
packed_payload[i+2] = (payload[i] << 7) | (crc >> 9);
|
||||
++i;
|
||||
packed_payload[i+2] = (crc.val >> 1 & 0x80 ) | (crc.val >> 1 & 0x7F);
|
||||
packed_payload[i+2] = (crc >> 1 & 0x80 ) | (crc >> 1 & 0x7F);
|
||||
++i;
|
||||
packed_payload[i+2] = (crc.val << 7);
|
||||
packed_payload[i+2] = (crc << 7);
|
||||
|
||||
*len += 4;
|
||||
}
|
||||
|
||||
@@ -375,7 +375,6 @@ void Frsky_init_clone(void)
|
||||
val=option;
|
||||
CC2500_WriteReg(reg,val);
|
||||
}
|
||||
prev_option = option ; // Save option to monitor FSCTRL0 change
|
||||
for(uint8_t i=0;i<17;i++)
|
||||
{
|
||||
uint8_t reg=pgm_read_byte_near(&FRSKY_common_end_cc2500_conf[i][0]);
|
||||
@@ -406,7 +405,7 @@ void Frsky_init_clone(void)
|
||||
{
|
||||
for (uint8_t i=start+1;i<=end;i++)
|
||||
packet[i]=0;
|
||||
packet[start] = FrSkyX_RX_Seq << 4; //TX=8 at startup
|
||||
packet[start] = FrSkyX_RX_Seq << 4;
|
||||
#ifdef SPORT_SEND
|
||||
if (FrSkyX_TX_IN_Seq!=0xFF)
|
||||
{//RX has replied at least once
|
||||
|
||||
@@ -203,11 +203,7 @@ uint16_t ReadFrSky_2way()
|
||||
}
|
||||
CC2500_Strobe(CC2500_SIDLE);
|
||||
CC2500_WriteReg(CC2500_0A_CHANNR, hopping_frequency[counter % 47]);
|
||||
if ( prev_option != option )
|
||||
{
|
||||
CC2500_WriteReg(CC2500_0C_FSCTRL0,option); // Frequency offset hack
|
||||
prev_option = option ;
|
||||
}
|
||||
CC2500_SetFreqOffset();
|
||||
CC2500_WriteReg(CC2500_23_FSCAL3, 0x89);
|
||||
CC2500_Strobe(CC2500_SFRX);
|
||||
frsky2way_data_frame();
|
||||
|
||||
@@ -200,11 +200,7 @@ uint16_t ReadFrSkyL()
|
||||
break;
|
||||
|
||||
case FRSKY_DATA1:
|
||||
if ( prev_option != option )
|
||||
{
|
||||
CC2500_WriteReg(CC2500_0C_FSCTRL0,option); //Frequency offset hack
|
||||
prev_option = option ;
|
||||
}
|
||||
CC2500_SetFreqOffset();
|
||||
FrSkyX_set_start(hopping_frequency_no);
|
||||
FrSkyL_build_packet();
|
||||
FrSkyL_encode_packet(true);
|
||||
|
||||
@@ -122,11 +122,7 @@ uint16_t ReadFRSKYV()
|
||||
#endif
|
||||
uint8_t chan = FRSKYV_calc_channel();
|
||||
CC2500_Strobe(CC2500_SIDLE);
|
||||
if (option != prev_option)
|
||||
{
|
||||
CC2500_WriteReg(CC2500_0C_FSCTRL0, option);
|
||||
prev_option=option;
|
||||
}
|
||||
CC2500_SetFreqOffset();
|
||||
CC2500_WriteReg(CC2500_0A_CHANNR, chan * 5 + 6);
|
||||
FRSKYV_build_data_packet();
|
||||
|
||||
|
||||
@@ -142,11 +142,7 @@ uint16_t ReadFrSkyX()
|
||||
|
||||
case FRSKY_DATA1:
|
||||
CC2500_Strobe(CC2500_SIDLE);
|
||||
if ( prev_option != option )
|
||||
{
|
||||
CC2500_WriteReg(CC2500_0C_FSCTRL0,option); //Frequency offset hack
|
||||
prev_option = option ;
|
||||
}
|
||||
CC2500_SetFreqOffset();
|
||||
FrSkyX_set_start(hopping_frequency_no);
|
||||
FrSkyX_build_packet();
|
||||
if(FrSkyFormat & 2)
|
||||
|
||||
@@ -358,21 +358,35 @@ static void __attribute__((unused)) frsky_rx_data()
|
||||
|
||||
uint16_t initFrSky_Rx()
|
||||
{
|
||||
frsky_rx_chanskip = 1;
|
||||
hopping_frequency_no = 0;
|
||||
rx_data_started = false;
|
||||
frsky_rx_finetune = 0;
|
||||
telemetry_link = 0;
|
||||
packet_count = 0;
|
||||
if (IS_BIND_IN_PROGRESS)
|
||||
if(sub_protocol == FRSKY_ERASE)
|
||||
{
|
||||
frsky_rx_format = FRSKY_RX_D8;
|
||||
frsky_rx_initialise_cc2500();
|
||||
phase = FRSKY_RX_TUNE_START;
|
||||
debugln("FRSKY_RX_TUNE_START");
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
{// Clear all cloned addresses
|
||||
uint16_t addr[]={ FRSKYD_CLONE_EEPROM_OFFSET+1, FRSKYX_CLONE_EEPROM_OFFSET+1, FRSKYX2_CLONE_EEPROM_OFFSET+1 };
|
||||
for(uint8_t i=0; i<3;i++)
|
||||
for(uint8_t j=0; j<3;j++)
|
||||
eeprom_write_byte((EE_ADDR)(addr[i]+j), 0xFF);
|
||||
packet_count = 100;
|
||||
}
|
||||
}
|
||||
else
|
||||
frsky_rx_data();
|
||||
{
|
||||
frsky_rx_chanskip = 1;
|
||||
hopping_frequency_no = 0;
|
||||
rx_data_started = false;
|
||||
frsky_rx_finetune = 0;
|
||||
telemetry_link = 0;
|
||||
packet_count = 0;
|
||||
if (IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
frsky_rx_format = FRSKY_RX_D8;
|
||||
frsky_rx_initialise_cc2500();
|
||||
phase = FRSKY_RX_TUNE_START;
|
||||
debugln("FRSKY_RX_TUNE_START");
|
||||
}
|
||||
else
|
||||
frsky_rx_data();
|
||||
}
|
||||
return 1000;
|
||||
}
|
||||
|
||||
@@ -382,6 +396,15 @@ uint16_t FrSky_Rx_callback()
|
||||
static int8_t tune_low, tune_high;
|
||||
uint8_t len, ch;
|
||||
|
||||
if(sub_protocol == FRSKY_ERASE)
|
||||
{
|
||||
if(packet_count)
|
||||
packet_count--;
|
||||
else
|
||||
BIND_DONE;
|
||||
return 10000; // Nothing to do...
|
||||
}
|
||||
|
||||
if(IS_BIND_DONE && phase != FRSKY_RX_DATA) return initFrSky_Rx(); // Abort bind
|
||||
|
||||
if ((prev_option != option) && (phase >= FRSKY_RX_DATA))
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
*/
|
||||
// Last sync with main deviation/sfhss_cc2500.c dated 2016-03-23
|
||||
|
||||
#if defined(SFHSS_CC2500_INO)
|
||||
#if defined(FUTABA_CC2500_INO)
|
||||
|
||||
#include "iface_cc2500.h"
|
||||
|
||||
@@ -79,7 +79,6 @@ static void __attribute__((unused)) SFHSS_rf_init()
|
||||
for (uint8_t i = 0; i < 39; ++i)
|
||||
CC2500_WriteReg(i, pgm_read_byte_near(&SFHSS_init_values[i]));
|
||||
|
||||
prev_option = option;
|
||||
CC2500_WriteReg(CC2500_0C_FSCTRL0, option);
|
||||
|
||||
CC2500_SetTxRxMode(TX_EN);
|
||||
@@ -165,16 +164,14 @@ static void __attribute__((unused)) SFHSS_build_data_packet()
|
||||
// 3584-4095 -> looks to be used for the throttle channel with values ranging from 880µs to 1520µs
|
||||
for(uint8_t i=0;i<4;i++)
|
||||
{
|
||||
ch[i]=Failsafe_data[CH_AETR[ch_offset+i]];
|
||||
if(ch[i]==FAILSAFE_CHANNEL_HOLD)
|
||||
uint16_t val=Failsafe_data[CH_AETR[ch_offset+i]];
|
||||
if(val==FAILSAFE_CHANNEL_HOLD)
|
||||
ch[i]=1024;
|
||||
else if(ch[i]==FAILSAFE_CHANNEL_NOPULSES)
|
||||
else if(val==FAILSAFE_CHANNEL_NOPULSES)
|
||||
ch[i]=0;
|
||||
else
|
||||
{ //Use channel value
|
||||
ch[i]=(ch[i]>>1)+2560;
|
||||
//if(IS_DISABLE_CH_MAP_off && ch_offset+i==CH3 && ch[i]<3072) // Throttle
|
||||
// ch[i]+=1024;
|
||||
ch[i] = convert_channel_16b_nolimit(CH_AETR[ch_offset+i],3571,2571,true); //3472,2672: not enough throw
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -182,7 +179,7 @@ static void __attribute__((unused)) SFHSS_build_data_packet()
|
||||
#endif
|
||||
{ //Normal data
|
||||
for(uint8_t i=0;i<4;i++)
|
||||
ch[i] = convert_channel_16b_nolimit(CH_AETR[ch_offset+i],2020,1020);
|
||||
ch[i] = convert_channel_16b_nolimit(CH_AETR[ch_offset+i],2020,1020,false);
|
||||
}
|
||||
|
||||
|
||||
@@ -86,7 +86,6 @@ static void __attribute__((unused)) HOTT_rf_init()
|
||||
for (uint8_t i = 0; i < 39; ++i)
|
||||
CC2500_WriteReg(i, pgm_read_byte_near(&HOTT_init_values[i]));
|
||||
|
||||
prev_option = option;
|
||||
CC2500_WriteReg(CC2500_0C_FSCTRL0, option);
|
||||
|
||||
CC2500_SetTxRxMode(TX_EN);
|
||||
@@ -159,7 +158,7 @@ static void __attribute__((unused)) HOTT_init()
|
||||
else
|
||||
{
|
||||
memcpy(&packet[40],rx_tx_addr,5);
|
||||
uint8_t addr=HOTT_EEPROM_OFFSET+RX_num*5;
|
||||
uint16_t addr=HOTT_EEPROM_OFFSET+RX_num*5;
|
||||
debug("RXID: ");
|
||||
for(uint8_t i=0;i<5;i++)
|
||||
{
|
||||
@@ -172,10 +171,11 @@ static void __attribute__((unused)) HOTT_init()
|
||||
|
||||
static void __attribute__((unused)) HOTT_prep_data_packet()
|
||||
{
|
||||
static uint8_t upper=0;
|
||||
|
||||
packet[2] = hopping_frequency_no;
|
||||
|
||||
packet[3] = 0x00; // used for failsafe but may also be used for additional channels
|
||||
packet[3] = upper; // used for failsafe and upper channels (only supporting 16 channels)
|
||||
#ifdef FAILSAFE_ENABLE
|
||||
static uint8_t failsafe_count=0;
|
||||
if(IS_FAILSAFE_VALUES_on && IS_BIND_DONE)
|
||||
@@ -195,13 +195,16 @@ static void __attribute__((unused)) HOTT_prep_data_packet()
|
||||
uint16_t val;
|
||||
for(uint8_t i=4;i<28;i+=2)
|
||||
{
|
||||
val=Channel_data[(i-4)>>1];
|
||||
uint8_t ch=(i-4)>>1;
|
||||
if(upper && ch >= 8)
|
||||
ch+=4; // when upper swap CH9..CH12 by CH13..16
|
||||
val=Channel_data[ch];
|
||||
val=(((val<<2)+val)>>2)+860*2; // value range 860<->2140 *2 <-> -125%<->+125%
|
||||
#ifdef FAILSAFE_ENABLE
|
||||
if(failsafe_count==1)
|
||||
{ // first failsafe packet
|
||||
packet[3]=0x40;
|
||||
uint16_t fs=Failsafe_data[(i-4)>>1];
|
||||
packet[3] |= 0x40;
|
||||
uint16_t fs=Failsafe_data[ch];
|
||||
if( fs == FAILSAFE_CHANNEL_HOLD || fs == FAILSAFE_CHANNEL_NOPULSES)
|
||||
val|=0x8000; // channel hold flag
|
||||
else
|
||||
@@ -212,7 +215,7 @@ static void __attribute__((unused)) HOTT_prep_data_packet()
|
||||
}
|
||||
else if(failsafe_count==2)
|
||||
{ // second failsafe packet=timing?
|
||||
packet[3]=0x50;
|
||||
packet[3] |= 0x50;
|
||||
if(i==4)
|
||||
val=2;
|
||||
else
|
||||
@@ -222,6 +225,8 @@ static void __attribute__((unused)) HOTT_prep_data_packet()
|
||||
packet[i] = val;
|
||||
packet[i+1] = val>>8;
|
||||
}
|
||||
upper ^= 0x01; // toggle between CH9..CH12 and CH13..16
|
||||
|
||||
#ifdef HOTT_FW_TELEMETRY
|
||||
if(IS_BIND_DONE)
|
||||
{
|
||||
@@ -374,7 +379,7 @@ uint16_t ReadHOTT()
|
||||
for(uint8_t i=0;i<HOTT_RX_PACKET_LEN;i++)
|
||||
debug(" %02X", packet_in[i]);
|
||||
debugln("");
|
||||
uint8_t addr=HOTT_EEPROM_OFFSET+RX_num*5;
|
||||
uint16_t addr=HOTT_EEPROM_OFFSET+RX_num*5;
|
||||
for(uint8_t i=0; i<5; i++)
|
||||
eeprom_write_byte((EE_ADDR)(addr+i),packet_in[5+i]);
|
||||
BIND_DONE;
|
||||
|
||||
@@ -54,7 +54,6 @@ static void __attribute__((unused)) HITEC_CC2500_init()
|
||||
for (uint8_t i = 0; i < 39; ++i)
|
||||
CC2500_WriteReg(i, pgm_read_byte_near(&HITEC_init_values[i]));
|
||||
|
||||
prev_option = option;
|
||||
CC2500_WriteReg(CC2500_0C_FSCTRL0, option);
|
||||
|
||||
CC2500_SetTxRxMode(TX_EN);
|
||||
@@ -165,7 +164,7 @@ static void __attribute__((unused)) HITEC_build_packet()
|
||||
packet[0] = 0x1A; // 26 bytes to follow
|
||||
for(uint8_t i=0;i<9;i++)
|
||||
{
|
||||
uint16_t ch = convert_channel_16b_nolimit(i,0x1B87,0x3905);
|
||||
uint16_t ch = convert_channel_16b_nolimit(i,0x1B87,0x3905,false);
|
||||
packet[4+2*i] = ch >> 8;
|
||||
packet[5+2*i] = ch & 0xFF;
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ enum{
|
||||
#define HONTAI_POLY 0x8408
|
||||
static void __attribute__((unused)) crc16(uint8_t *data_p, uint8_t length)
|
||||
{
|
||||
uint16_t crc = 0xffff;
|
||||
crc = 0xffff;
|
||||
|
||||
length -= 2;
|
||||
do
|
||||
|
||||
@@ -59,7 +59,7 @@ static void __attribute__((unused)) j6pro_build_data_packet()
|
||||
packet[0] = 0xaa; //FIXME what is this?
|
||||
for (i = 0; i < 12; i++)
|
||||
{
|
||||
value = convert_channel_10b(CH_AETR[i]);
|
||||
value = convert_channel_10b(CH_AETR[i], false);
|
||||
packet[i+1] = value & 0xff;
|
||||
upperbits |= (value >> 8) << (i * 2);
|
||||
}
|
||||
@@ -111,8 +111,8 @@ static void __attribute__((unused)) cyrf_datainit()
|
||||
{
|
||||
/* Use when already bound */
|
||||
uint8_t sop_idx = (0xff & (cyrfmfg_id[0] + cyrfmfg_id[1] + cyrfmfg_id[2] + cyrfmfg_id[3] - cyrfmfg_id[5])) % 19;
|
||||
uint16_t crc = (0xff & (cyrfmfg_id[1] - cyrfmfg_id[4] + cyrfmfg_id[5])) |
|
||||
((0xff & (cyrfmfg_id[2] + cyrfmfg_id[3] - cyrfmfg_id[4] + cyrfmfg_id[5])) << 8);
|
||||
crc = (0xff & (cyrfmfg_id[1] - cyrfmfg_id[4] + cyrfmfg_id[5])) |
|
||||
((0xff & (cyrfmfg_id[2] + cyrfmfg_id[3] - cyrfmfg_id[4] + cyrfmfg_id[5])) << 8);
|
||||
//CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x24);
|
||||
CYRF_PROGMEM_ConfigSOPCode(DEVO_j6pro_sopcodes[sop_idx]);
|
||||
CYRF_ConfigCRCSeed(crc);
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#define JJRC345_INITIAL_WAIT 500
|
||||
#define JJRC345_PACKET_SIZE 16
|
||||
#define JJRC345_RF_BIND_CHANNEL 5
|
||||
#define SKYTMBLR_RF_BIND_CHANNEL 40
|
||||
#define JJRC345_BIND_COUNT 500
|
||||
#define JJRC345_NUM_CHANNELS 4
|
||||
|
||||
@@ -32,6 +33,12 @@ enum JJRC345_FLAGS {
|
||||
// flags going to packet[8]
|
||||
JJRC345_FLAG_HEADLESS = 0x40,
|
||||
JJRC345_FLAG_RTH = 0x80,
|
||||
// flags going to packet[9]
|
||||
SKYTMBLR_FLAG_UNK1 = 0x40,
|
||||
SKYTMBLR_FLAG_UNK2 = 0x80,
|
||||
// flags going to packet[10]
|
||||
SKYTMBLR_FLAG_LED = 0x40,
|
||||
SKYTMBLR_FLAG_UNK3 = 0x80,
|
||||
};
|
||||
|
||||
static uint8_t __attribute__((unused)) JJRC345_convert_channel(uint8_t num)
|
||||
@@ -55,7 +62,7 @@ static void __attribute__((unused)) JJRC345_send_packet()
|
||||
packet[2] = 0x00;
|
||||
if (IS_BIND_IN_PROGRESS)
|
||||
{ //00 05 00 0A 46 4A 41 47 00 00 40 46 A5 4A F1 18
|
||||
packet[1] = JJRC345_RF_BIND_CHANNEL;
|
||||
packet[1] = (sub_protocol == JJRC345 ? JJRC345_RF_BIND_CHANNEL:SKYTMBLR_RF_BIND_CHANNEL);
|
||||
packet[4] = hopping_frequency[0];
|
||||
packet[5] = hopping_frequency[1];
|
||||
packet[6] = hopping_frequency[2];
|
||||
@@ -92,10 +99,14 @@ static void __attribute__((unused)) JJRC345_send_packet()
|
||||
packet[3] = 0x00; // Checksum upper bits
|
||||
|
||||
packet[8] = 0x00 // Rudder trim, 00 when not used, 01..1F when trimmed left, 20..3F
|
||||
| GET_FLAG(CH6_SW,JJRC345_FLAG_HEADLESS) // Headless mode: 00 normal, 40 headless
|
||||
| GET_FLAG(CH7_SW,JJRC345_FLAG_RTH); // RTH: 80 active
|
||||
packet[9] = 0; // Elevator trim, 00 when not used, 20..25 when trimmed up, 0..1F when trimmed down
|
||||
packet[10] = 0x40; // Aileron trim, 40 when not used, 40..5F when trimmed left, 61..7F when trimmed right
|
||||
| GET_FLAG(CH6_SW ,JJRC345_FLAG_HEADLESS) // 0x40 HeadLess
|
||||
| GET_FLAG(CH7_SW ,JJRC345_FLAG_RTH); // 0x80 RTH
|
||||
packet[9] = 0x00 // Elevator trim, 00 when not used, 20..25 when trimmed up, 0..1F when trimmed down
|
||||
| GET_FLAG(CH9_SW ,SKYTMBLR_FLAG_UNK1) // 0x40 Unknown
|
||||
| GET_FLAG(CH10_SW,SKYTMBLR_FLAG_UNK2); // 0x80 Unknown
|
||||
packet[10] = 0x00 // Aileron trim, 00 when not used, 00..1F when trimmed left, 21..3F when trimmed right
|
||||
| GET_FLAG(!CH8_SW,SKYTMBLR_FLAG_LED) // 0x40 LED
|
||||
| GET_FLAG(CH11_SW,SKYTMBLR_FLAG_UNK3); // 0x80 Unknown
|
||||
|
||||
packet[11] = hopping_frequency[0]; // First hopping frequency
|
||||
|
||||
@@ -124,7 +135,7 @@ static void __attribute__((unused)) JJRC345_init()
|
||||
NRF24L01_Initialize();
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
XN297_SetTXAddr((uint8_t*)"\xcc\xcc\xcc\xcc\xcc", 5);
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, JJRC345_RF_BIND_CHANNEL); // Bind channel
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, sub_protocol == JJRC345 ? JJRC345_RF_BIND_CHANNEL:SKYTMBLR_RF_BIND_CHANNEL); // Bind channel
|
||||
NRF24L01_FlushTx();
|
||||
NRF24L01_FlushRx();
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
|
||||
|
||||
@@ -125,16 +125,16 @@ static void __attribute__((unused)) kn_bind_init()
|
||||
static void __attribute__((unused)) kn_update_packet_control_data()
|
||||
{
|
||||
uint16_t value;
|
||||
value = convert_channel_10b(THROTTLE);
|
||||
value = convert_channel_10b(THROTTLE, false);
|
||||
packet[0] = (value >> 8) & 0xFF;
|
||||
packet[1] = value & 0xFF;
|
||||
value = convert_channel_10b(AILERON);
|
||||
value = convert_channel_10b(AILERON, false);
|
||||
packet[2] = (value >> 8) & 0xFF;
|
||||
packet[3] = value & 0xFF;
|
||||
value = convert_channel_10b(ELEVATOR);
|
||||
value = convert_channel_10b(ELEVATOR, false);
|
||||
packet[4] = (value >> 8) & 0xFF;
|
||||
packet[5] = value & 0xFF;
|
||||
value = convert_channel_10b(RUDDER);
|
||||
value = convert_channel_10b(RUDDER, false);
|
||||
packet[6] = (value >> 8) & 0xFF;
|
||||
packet[7] = value & 0xFF;
|
||||
// Trims, middle is 0x64 (100) range 0-200
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
|
||||
#include "iface_a7105.h"
|
||||
|
||||
//#define KYOSHO_FORCE_ID
|
||||
//#define KYOSHO_FORCE_ID_FHSS
|
||||
//#define KYOSHO_FORCE_ID_HYPE
|
||||
|
||||
//Kyosho constants & variables
|
||||
#define KYOSHO_BIND_COUNT 2500
|
||||
@@ -67,13 +68,62 @@ static void __attribute__((unused)) kyosho_send_packet()
|
||||
packet[36] |= (hopping_frequency_no&0xF0); // last byte is ending with F on the dumps so let's see
|
||||
hopping_frequency_no &= 0x1F;
|
||||
}
|
||||
// debug("ch=%02X P=",rf_ch_num);
|
||||
// for(uint8_t i=0; i<37; i++)
|
||||
// debug("%02X ", packet[i]);
|
||||
// debugln("");
|
||||
#if 0
|
||||
debug("ch=%02X P=",rf_ch_num);
|
||||
for(uint8_t i=0; i<37; i++)
|
||||
debug("%02X ", packet[i]);
|
||||
debugln("");
|
||||
#endif
|
||||
A7105_WriteData(37, rf_ch_num);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) kyosho_hype_send_packet()
|
||||
{
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
if(packet_sent==0)
|
||||
{//build the packet and send it
|
||||
packet[0] = rx_tx_addr[1];
|
||||
packet[1] = rx_tx_addr[3];
|
||||
//RF table
|
||||
for(uint8_t i=0; i<15;i++)
|
||||
packet[i+2]=hopping_frequency[i];
|
||||
A7105_WriteData(17, 0x01);
|
||||
packet_sent++;
|
||||
packet_period=1421;
|
||||
#if 0
|
||||
debug("ch=01 P=");
|
||||
for(uint8_t i=0; i<17; i++)
|
||||
debug("%02X ", packet[i]);
|
||||
debugln("");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
A7105_Strobe(A7105_TX); //only send
|
||||
}
|
||||
else
|
||||
{
|
||||
//original TX is only refreshing the packet every 20ms and keep repeating the same packet in between (STROBE_TX)
|
||||
//build packet=6 channels with order AETR
|
||||
for(uint8_t i=0;i<6;i++)
|
||||
packet[i] = convert_channel_8b(CH_AETR[i]);
|
||||
//set RF channel
|
||||
rf_ch_num=hopping_frequency[hopping_frequency_no];
|
||||
hopping_frequency_no++;
|
||||
if(hopping_frequency_no>14)
|
||||
hopping_frequency_no = 0;
|
||||
//send it
|
||||
A7105_WriteData(6, rf_ch_num);
|
||||
packet_period=931; //packet period fluctuates a lot on the original TX from one packet to the other but stable if looking over a period of 40ms
|
||||
#if 0
|
||||
debug("ch=%02X P=",rf_ch_num);
|
||||
for(uint8_t i=0; i<6; i++)
|
||||
debug("%02X ", packet[i]);
|
||||
debugln("");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t ReadKyosho()
|
||||
{
|
||||
#ifndef FORCE_KYOSHO_TUNING
|
||||
@@ -83,34 +133,70 @@ uint16_t ReadKyosho()
|
||||
{
|
||||
bind_counter--;
|
||||
if (bind_counter==0)
|
||||
{
|
||||
BIND_DONE;
|
||||
if(sub_protocol==KYOSHO_HYPE)
|
||||
{
|
||||
A7105_WriteID(MProtocol_id);
|
||||
A7105_WriteReg(A7105_03_FIFOI,0x05);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
A7105_SetPower();
|
||||
if(hopping_frequency_no==0)
|
||||
A7105_SetPower();
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(3852);
|
||||
telemetry_set_input_sync(packet_period);
|
||||
#endif
|
||||
}
|
||||
kyosho_send_packet();
|
||||
return 3852;
|
||||
if(sub_protocol==KYOSHO_FHSS)
|
||||
kyosho_send_packet();
|
||||
else//HYPE
|
||||
kyosho_hype_send_packet();
|
||||
return packet_period;
|
||||
}
|
||||
|
||||
uint16_t initKyosho()
|
||||
{
|
||||
A7105_Init();
|
||||
|
||||
// compute 32 channels from ID
|
||||
calc_fh_channels(32);
|
||||
|
||||
// compute channels from ID
|
||||
calc_fh_channels(sub_protocol==KYOSHO_FHSS?32:15);
|
||||
hopping_frequency_no=0;
|
||||
|
||||
#ifdef KYOSHO_FORCE_ID
|
||||
memcpy(rx_tx_addr,"\x3A\x39\x37\x00",4);
|
||||
memcpy(hopping_frequency,"\x29\x4C\x67\x92\x31\x1C\x77\x18\x23\x6E\x81\x5C\x8F\x5A\x51\x94\x7A\x12\x45\x6C\x7F\x1E\x0D\x88\x63\x8C\x4F\x37\x26\x61\x2C\x8A",32);
|
||||
#ifdef KYOSHO_FORCE_ID_FHSS
|
||||
if(sub_protocol==KYOSHO_FHSS)
|
||||
{
|
||||
memcpy(rx_tx_addr,"\x3A\x39\x37\x00",4);
|
||||
memcpy(hopping_frequency,"\x29\x4C\x67\x92\x31\x1C\x77\x18\x23\x6E\x81\x5C\x8F\x5A\x51\x94\x7A\x12\x45\x6C\x7F\x1E\x0D\x88\x63\x8C\x4F\x37\x26\x61\x2C\x8A",32);
|
||||
}
|
||||
#endif
|
||||
if(sub_protocol==KYOSHO_HYPE)
|
||||
{
|
||||
MProtocol_id &= 0x00FF00FF;
|
||||
rx_tx_addr[0] = 0xAF - (rx_tx_addr[1]&0x0F);
|
||||
rx_tx_addr[2] = 0xFF - rx_tx_addr[3];
|
||||
MProtocol_id |= (rx_tx_addr[0]<<24) + (rx_tx_addr[2]<<8);
|
||||
#ifdef KYOSHO_FORCE_ID_HYPE
|
||||
MProtocol_id=0xAF90738C;
|
||||
set_rx_tx_addr(MProtocol_id);
|
||||
memcpy(hopping_frequency,"\x27\x1B\x63\x75\x03\x39\x57\x69\x87\x0F\x7B\x3F\x33\x51\x6F",15);
|
||||
#endif
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
A7105_WriteID(0xAF00FF00);
|
||||
else
|
||||
{
|
||||
A7105_WriteID(MProtocol_id);
|
||||
A7105_WriteReg(A7105_03_FIFOI,0x05);
|
||||
}
|
||||
}
|
||||
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
bind_counter = KYOSHO_BIND_COUNT;
|
||||
|
||||
packet_sent=0;
|
||||
packet_period=3852; //FHSS
|
||||
return 2000;
|
||||
}
|
||||
#endif
|
||||
|
||||
314
Multiprotocol/LOLI_nrf24l01.ino
Normal file
314
Multiprotocol/LOLI_nrf24l01.ino
Normal file
@@ -0,0 +1,314 @@
|
||||
/*
|
||||
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(LOLI_NRF24L01_INO)
|
||||
|
||||
#include "iface_nrf24l01.h"
|
||||
|
||||
#define LOLI_BIND_CHANNEL 33
|
||||
#define LOLI_PACKET_SIZE 11
|
||||
#define LOLI_NUM_CHANNELS 5
|
||||
|
||||
static void __attribute__((unused)) LOLI_init()
|
||||
{
|
||||
NRF24L01_Initialize();
|
||||
NRF24L01_FlushTx();
|
||||
NRF24L01_FlushRx();
|
||||
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowldgement on all data pipes
|
||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 only
|
||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5-bytes RX/TX address
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, (uint8_t*)"LOVE!", 5);
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, (uint8_t*)"LOVE!", 5);
|
||||
NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x00); // No retransmits
|
||||
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, LOLI_PACKET_SIZE); // RX FIFO size
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_250K); // 250Kbps
|
||||
|
||||
NRF24L01_SetPower();
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
}
|
||||
|
||||
// flags going to packet[1] for packet type 0xa2 (Rx config)
|
||||
#define LOLI_FLAG_PWM7 0x02
|
||||
#define LOLI_FLAG_PWM2 0x04
|
||||
#define LOLI_FLAG_PWM1 0x08
|
||||
#define LOLI_FLAG_SBUS 0x40
|
||||
#define LOLI_FLAG_PPM 0x80
|
||||
|
||||
// flags going to packet[2] for packet type 0xa2 (Rx config)
|
||||
#define LOLI_FLAG_SW8 0x01
|
||||
#define LOLI_FLAG_SW7 0x02
|
||||
#define LOLI_FLAG_SW6 0x04
|
||||
#define LOLI_FLAG_SW5 0x08
|
||||
#define LOLI_FLAG_SW4 0x10
|
||||
#define LOLI_FLAG_SW3 0x20
|
||||
#define LOLI_FLAG_SW2 0x40
|
||||
#define LOLI_FLAG_SW1 0x80
|
||||
|
||||
#ifdef LOLI_NRF24L01_INO
|
||||
uint8_t LOLI_P1, LOLI_P2;
|
||||
#endif
|
||||
|
||||
static void __attribute__((unused)) LOLI_send_packet()
|
||||
{
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
packet[0] = 0xa0;
|
||||
memcpy(&packet[1], hopping_frequency, LOLI_NUM_CHANNELS);
|
||||
memcpy(&packet[6], rx_tx_addr, 5);
|
||||
rf_ch_num = LOLI_BIND_CHANNEL;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Check RX config
|
||||
uint8_t P1=0;
|
||||
uint8_t P2=0;
|
||||
//ch1: PWM/PPM
|
||||
if(Channel_data[CH1+8] > CHANNEL_MAX_COMMAND)
|
||||
P1|=LOLI_FLAG_PWM1;
|
||||
else if(Channel_data[CH1+8] > CHANNEL_SWITCH)
|
||||
P1|=LOLI_FLAG_PPM;
|
||||
//ch2: PWM
|
||||
if(Channel_data[CH2+8] > CHANNEL_MAX_COMMAND)
|
||||
P1|=LOLI_FLAG_PWM2;
|
||||
//ch5: SBUS
|
||||
if(Channel_data[CH5+8] > CHANNEL_SWITCH)
|
||||
P1|=LOLI_FLAG_SBUS;
|
||||
//ch7: PWM
|
||||
if(Channel_data[CH7+8] > CHANNEL_MAX_COMMAND)
|
||||
P1|=LOLI_FLAG_PWM7;
|
||||
|
||||
//switches
|
||||
for(uint8_t i=0;i<8;i++)
|
||||
if(Channel_data[i+8]<CHANNEL_MIN_COMMAND)
|
||||
P2 |= 1 << (7-i);
|
||||
|
||||
if(LOLI_P1!=P1 || LOLI_P2!=P2)
|
||||
flags=10;
|
||||
if(flags)
|
||||
{// Send RX config since P1 or P2 have changed
|
||||
LOLI_P1=P1;LOLI_P2=P2;
|
||||
packet[0] = 0xa2;
|
||||
packet[1] = LOLI_P1; // CH1:LOLI_FLAG_PPM || LOLI_FLAG_PWM1, CH2:LOLI_FLAG_PWM2, CH5:LOLI_FLAG_SBUS, CH7:LOLI_FLAG_PWM7
|
||||
packet[2] = LOLI_P2; // CHx switch bit(8-x)=1
|
||||
flags--;
|
||||
}
|
||||
else
|
||||
{// Normal packet
|
||||
#ifdef FAILSAFE_ENABLE
|
||||
packet[0] = IS_FAILSAFE_VALUES_on ? 0xa0 : 0xa1;
|
||||
#else
|
||||
packet[0] = 0xa1;
|
||||
#endif
|
||||
|
||||
//Build channels
|
||||
uint8_t ch=0, offset=1;
|
||||
uint16_t val;
|
||||
for(uint8_t i=0;i<2;i++)
|
||||
{
|
||||
val = convert_channel_10b(ch++, IS_FAILSAFE_VALUES_on);
|
||||
packet[offset++] = val >> 2;
|
||||
packet[offset ] = val << 6;
|
||||
val = convert_channel_10b(ch++, IS_FAILSAFE_VALUES_on);
|
||||
packet[offset++]|= val >> 4;
|
||||
packet[offset ] = val << 4;
|
||||
val = convert_channel_10b(ch++, IS_FAILSAFE_VALUES_on);
|
||||
packet[offset++]|= val >> 6;
|
||||
packet[offset ] = val << 2;
|
||||
val = convert_channel_10b(ch++, IS_FAILSAFE_VALUES_on);
|
||||
packet[offset++]|= val >> 8;
|
||||
packet[offset++] = val & 0xff;
|
||||
}
|
||||
FAILSAFE_VALUES_off; // Failsafe values are sent if they were available
|
||||
}
|
||||
|
||||
if (++hopping_frequency_no > LOLI_NUM_CHANNELS-1)
|
||||
hopping_frequency_no = 0;
|
||||
rf_ch_num = hopping_frequency[hopping_frequency_no];
|
||||
}
|
||||
|
||||
#if 0
|
||||
debug("P(%02X):",rf_ch_num);
|
||||
for(uint8_t i=0; i<LOLI_PACKET_SIZE; i++)
|
||||
debug(" %02X",packet[i]);
|
||||
debugln("");
|
||||
#endif
|
||||
|
||||
//Send packet
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, rf_ch_num);
|
||||
NRF24L01_SetPower();
|
||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, 0x0a); // 8bit CRC, TX
|
||||
NRF24L01_FlushTx();
|
||||
NRF24L01_WritePayload(packet, LOLI_PACKET_SIZE);
|
||||
}
|
||||
|
||||
enum{
|
||||
LOLI_BIND1,
|
||||
LOLI_BIND2,
|
||||
LOLI_BIND3,
|
||||
LOLI_PREP_DATA,
|
||||
LOLI_DATA1,
|
||||
LOLI_DATA2,
|
||||
LOLI_SET_RX_CONFIG,
|
||||
LOLI_SET_FAILSAFE
|
||||
};
|
||||
|
||||
#define LOLI_WRITE_TIME 1000
|
||||
|
||||
uint16_t LOLI_callback()
|
||||
{
|
||||
switch (phase)
|
||||
{
|
||||
case LOLI_BIND1:
|
||||
if(bind_counter)
|
||||
{
|
||||
bind_counter--;
|
||||
if(bind_counter==0)
|
||||
{
|
||||
phase=LOLI_PREP_DATA;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// send bind packet
|
||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, 0x0a); // 8bit CRC, TX
|
||||
LOLI_send_packet();
|
||||
phase++;
|
||||
return 2000;
|
||||
case LOLI_BIND2:
|
||||
// switch to RX mode
|
||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||
NRF24L01_FlushRx();
|
||||
NRF24L01_SetTxRxMode(RX_EN);
|
||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, 0x3b); // 8bit CRC, RX
|
||||
phase++;
|
||||
packet_count = 0;
|
||||
return 2000;
|
||||
case LOLI_BIND3:
|
||||
// got bind response ?
|
||||
if (NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR))
|
||||
{
|
||||
NRF24L01_ReadPayload(packet, LOLI_PACKET_SIZE);
|
||||
if (packet[0] == 'O' && packet[1] == 'K')
|
||||
{
|
||||
debugln("Bind OK");
|
||||
phase++; // LOLI_PREP_DATA
|
||||
break;
|
||||
}
|
||||
}
|
||||
packet_count++;
|
||||
if (packet_count > 50)
|
||||
phase = LOLI_BIND1;
|
||||
return 1000;
|
||||
|
||||
case LOLI_PREP_DATA:
|
||||
BIND_DONE;
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, rx_tx_addr, 5);
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, rx_tx_addr, 5);
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||
NRF24L01_FlushRx();
|
||||
packet_count = 0;
|
||||
//defaut RX config with servo outputs
|
||||
LOLI_P1=0;LOLI_P2=0;flags=10;
|
||||
phase++;
|
||||
|
||||
case LOLI_DATA1:
|
||||
#ifdef LOLI_HUB_TELEMETRY
|
||||
// Check telemetry
|
||||
if (NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR))
|
||||
{ // RX fifo data ready
|
||||
NRF24L01_ReadPayload(packet, LOLI_PACKET_SIZE);
|
||||
#if 0
|
||||
debug("T:");
|
||||
for(uint8_t i=0; i<LOLI_PACKET_SIZE; i++)
|
||||
debug(" %02X",packet[i]);
|
||||
debugln("");
|
||||
#endif
|
||||
RX_RSSI = packet[0]<<1;
|
||||
uint16_t val=((packet[1] << 8) | packet[2])/10;
|
||||
if(val > 255) val=255;
|
||||
v_lipo1 = val;
|
||||
val=((packet[3] << 8) | packet[4])/10;
|
||||
if(val > 255) val=255;
|
||||
v_lipo2 = val;
|
||||
telemetry_link = 1;
|
||||
telemetry_counter++; // TX LQI counter
|
||||
if(telemetry_lost)
|
||||
{
|
||||
telemetry_lost = 0;
|
||||
packet_count = 100;
|
||||
telemetry_counter = 100;
|
||||
}
|
||||
}
|
||||
//LQI
|
||||
packet_count++;
|
||||
if(packet_count>=100)
|
||||
{
|
||||
packet_count=0;
|
||||
TX_LQI=telemetry_counter;
|
||||
if(telemetry_counter==0)
|
||||
telemetry_lost = 1;
|
||||
telemetry_counter = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Send data packet
|
||||
LOLI_send_packet();
|
||||
|
||||
#ifdef LOLI_HUB_TELEMETRY
|
||||
phase ++;
|
||||
return LOLI_WRITE_TIME;
|
||||
case LOLI_DATA2:
|
||||
// Wait for packet to be sent
|
||||
while( (NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_TX_DS)) == 0);
|
||||
// Switch to RX mode
|
||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||
NRF24L01_FlushRx();
|
||||
NRF24L01_SetTxRxMode(RX_EN);
|
||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, 0x3b); // 8bit CRC, RX
|
||||
phase = LOLI_DATA1;
|
||||
return 20000 - LOLI_WRITE_TIME;
|
||||
#else
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
return 20000;
|
||||
}
|
||||
|
||||
uint16_t initLOLI()
|
||||
{
|
||||
rx_tx_addr[1] %= 0x30;
|
||||
calc_fh_channels(LOLI_NUM_CHANNELS);
|
||||
for (uint8_t i=0; i < LOLI_NUM_CHANNELS; i++)
|
||||
if (hopping_frequency[i] == LOLI_BIND_CHANNEL)
|
||||
hopping_frequency[i]++;
|
||||
|
||||
if (IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
bind_counter=250;
|
||||
phase = LOLI_BIND1;
|
||||
}
|
||||
else
|
||||
phase = LOLI_PREP_DATA;
|
||||
|
||||
LOLI_init();
|
||||
|
||||
return 500;
|
||||
}
|
||||
|
||||
#endif
|
||||
556
Multiprotocol/MLINK_cyrf6936.ino
Normal file
556
Multiprotocol/MLINK_cyrf6936.ino
Normal file
@@ -0,0 +1,556 @@
|
||||
/*
|
||||
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(MLINK_CYRF6936_INO)
|
||||
|
||||
#include "iface_cyrf6936.h"
|
||||
|
||||
//#define MLINK_FORCE_ID
|
||||
#define MLINK_BIND_COUNT 696 // around 20s
|
||||
#define MLINK_NUM_FREQ 78
|
||||
#define MLINK_BIND_CHANNEL 0x01
|
||||
#define MLINK_PACKET_SIZE 8
|
||||
|
||||
enum {
|
||||
MLINK_BIND_TX=0,
|
||||
MLINK_BIND_PREP_RX,
|
||||
MLINK_BIND_RX,
|
||||
MLINK_PREP_DATA,
|
||||
MLINK_SEND1,
|
||||
MLINK_SEND2,
|
||||
MLINK_SEND3,
|
||||
MLINK_CHECK3,
|
||||
MLINK_RX,
|
||||
MLINK_BUILD4,
|
||||
};
|
||||
|
||||
uint8_t MLINK_Data_Code[16], MLINK_CRC_Init, MLINK_Unk_6_2;
|
||||
|
||||
const uint8_t PROGMEM MLINK_init_vals[][2] = {
|
||||
//Init from dump
|
||||
{ CYRF_01_TX_LENGTH, 0x08 }, // Length of packet
|
||||
{ CYRF_02_TX_CTRL, 0x40 }, // Clear TX Buffer
|
||||
{ CYRF_03_TX_CFG, 0x3C }, //0x3E in normal mode, 0x3C in bind mode: SDR 64 chip codes (=8 bytes data code used)
|
||||
{ CYRF_05_RX_CTRL, 0x00 },
|
||||
{ CYRF_06_RX_CFG, 0x93 }, // AGC enabled, overwrite enable, valid flag enable
|
||||
{ CYRF_0B_PWR_CTRL, 0x00 },
|
||||
//{ CYRF_0C_XTAL_CTRL, 0x00 }, // Set to GPIO on reset
|
||||
//{ CYRF_0D_IO_CFG, 0x00 }, // Set to GPIO on reset
|
||||
//{ CYRF_0E_GPIO_CTRL, 0x00 }, // Set by the CYRF_SetTxRxMode function
|
||||
{ CYRF_0F_XACT_CFG, 0x04 }, // end state idle
|
||||
{ CYRF_10_FRAMING_CFG, 0x00 }, // SOP disabled
|
||||
{ CYRF_11_DATA32_THOLD, 0x05 }, // not used???
|
||||
{ CYRF_12_DATA64_THOLD, 0x0F }, // 64 Chip Data PN Code Correlator Threshold
|
||||
{ CYRF_14_EOP_CTRL, 0x05 }, // 5 consecutive noncorrelations symbol for EOP
|
||||
{ CYRF_15_CRC_SEED_LSB, 0x00 }, // not used???
|
||||
{ CYRF_16_CRC_SEED_MSB, 0x00 }, // not used???
|
||||
{ CYRF_1B_TX_OFFSET_LSB,0x00 },
|
||||
{ CYRF_1C_TX_OFFSET_MSB,0x00 },
|
||||
{ CYRF_1D_MODE_OVERRIDE,0x00 },
|
||||
{ CYRF_1E_RX_OVERRIDE, 0x14 }, // RX CRC16 is disabled and Force Receive Data Rate
|
||||
{ CYRF_1F_TX_OVERRIDE, 0x04 }, // TX CRC16 is disabled
|
||||
{ CYRF_26_XTAL_CFG, 0x08 },
|
||||
{ CYRF_29_RX_ABORT, 0x00 },
|
||||
{ CYRF_32_AUTO_CAL_TIME,0x3C },
|
||||
{ CYRF_35_AUTOCAL_OFFSET,0x14 },
|
||||
{ CYRF_39_ANALOG_CTRL, 0x03 }, // Receive invert and all slow
|
||||
};
|
||||
|
||||
static void __attribute__((unused)) MLINK_cyrf_config()
|
||||
{
|
||||
for(uint8_t i = 0; i < sizeof(MLINK_init_vals) / 2; i++)
|
||||
CYRF_WriteRegister(pgm_read_byte_near(&MLINK_init_vals[i][0]), pgm_read_byte_near(&MLINK_init_vals[i][1]));
|
||||
CYRF_WritePreamble(0x333304);
|
||||
CYRF_SetTxRxMode(TX_EN);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) MLINK_send_bind_packet()
|
||||
{
|
||||
uint8_t p_c=packet_count>>1;
|
||||
|
||||
memset(packet, p_c<0x16?0x00:0xFF, MLINK_PACKET_SIZE-1);
|
||||
packet[0]=0x0F; // bind
|
||||
packet[1]=p_c;
|
||||
switch(p_c)
|
||||
{
|
||||
case 0x00:
|
||||
packet[2]=0x40; //unknown but seems constant
|
||||
packet[4]=0x01; //unknown but seems constant
|
||||
packet[5]=0x03; //unknown but seems constant
|
||||
packet[6]=0xE3; //unknown but seems constant
|
||||
break;
|
||||
case 0x05:
|
||||
packet[6]=MLINK_CRC_Init; //CRC init value
|
||||
break;
|
||||
case 0x06:
|
||||
packet[2]=MLINK_Unk_6_2; //unknown and different
|
||||
//Start of hopping frequencies
|
||||
for(uint8_t i=0;i<4;i++)
|
||||
packet[i+3]=hopping_frequency[i];
|
||||
break;
|
||||
case 0x15:
|
||||
packet[6]=0x51; //unknown but seems constant
|
||||
break;
|
||||
case 0x16:
|
||||
packet[2]=0x51; //unknown but seems constant
|
||||
packet[3]=0xEC; //unknown but seems constant
|
||||
packet[4]=0x05; //unknown but seems constant
|
||||
break;
|
||||
case 0x1A:
|
||||
packet[1]=0xFF;
|
||||
memset(&packet[2],0x00,5);
|
||||
break;
|
||||
}
|
||||
if(p_c>=0x01 && p_c<=0x04)
|
||||
{//DATA_CODE
|
||||
uint8_t p_c_5=(p_c-1)*5;
|
||||
for(uint8_t i=0;i<5;i++)
|
||||
if(i+p_c_5<16)
|
||||
packet[i+2]=MLINK_Data_Code[i+p_c_5];
|
||||
}
|
||||
else
|
||||
if(p_c>=0x07 && p_c<=0x15)
|
||||
{//Hopping frequencies
|
||||
uint8_t p_c_5=5*(p_c-6)-1;
|
||||
for(uint8_t i=0;i<5;i++)
|
||||
if(i+p_c_5<MLINK_NUM_FREQ)
|
||||
packet[i+2]=hopping_frequency[i+p_c_5];
|
||||
}
|
||||
else
|
||||
if(p_c>0x19)
|
||||
{
|
||||
packet[1]=0xFF;
|
||||
memset(&packet[2], 0x00, MLINK_PACKET_SIZE-3);
|
||||
}
|
||||
|
||||
//Calculate CRC
|
||||
crc8=0xFF; // Init = 0xFF
|
||||
for(uint8_t i=0;i<MLINK_PACKET_SIZE-1;i++)
|
||||
crc8_update(bit_reverse(packet[i]));
|
||||
packet[7] = bit_reverse(crc8); // CRC reflected out
|
||||
|
||||
//Debug
|
||||
#if 0
|
||||
debug("P(%02d):",p_c);
|
||||
for(uint8_t i=0;i<8;i++)
|
||||
debug(" %02X",packet[i]);
|
||||
debugln("");
|
||||
#endif
|
||||
|
||||
//Send packet
|
||||
CYRF_WriteDataPacketLen(packet, MLINK_PACKET_SIZE);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) MLINK_send_data_packet()
|
||||
{
|
||||
static uint8_t tog=0;
|
||||
uint8_t start;
|
||||
|
||||
#ifdef FAILSAFE_ENABLE
|
||||
static uint8_t fs=0;
|
||||
if(IS_FAILSAFE_VALUES_on && phase==MLINK_SEND1)
|
||||
{
|
||||
fs=10; // Original radio is sending 70 packets
|
||||
FAILSAFE_VALUES_off;
|
||||
}
|
||||
if(fs)
|
||||
{// Failsafe packets
|
||||
switch(phase)
|
||||
{
|
||||
case MLINK_SEND2:
|
||||
packet[0]=0x06;
|
||||
start=17;
|
||||
break;
|
||||
case MLINK_SEND3:
|
||||
packet[0]=0x84;
|
||||
start=5;
|
||||
fs--;
|
||||
break;
|
||||
default: //MLINK_SEND1:
|
||||
packet[0]=0x05;
|
||||
start=11;
|
||||
break;
|
||||
}
|
||||
//Pack 6 channels per packet
|
||||
for(uint8_t i=0;i<6;i++)
|
||||
{
|
||||
uint8_t val=start<16 ? convert_channel_16b_nolimit(start,426 >> 4,3448 >> 4,true) : 0x00;
|
||||
start--; // switch to next channel
|
||||
packet[i+1]=val;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{// Normal packets
|
||||
if(hopping_frequency_no==0)
|
||||
tog=1;
|
||||
//Channels to be sent
|
||||
if(phase==MLINK_SEND1 || ((hopping_frequency_no%5==0) && (phase==MLINK_SEND2)))
|
||||
{
|
||||
if((hopping_frequency_no&1)==0)
|
||||
packet[0] = 0x09; //10,8,6
|
||||
else
|
||||
packet[0] = 0x01; //11,9,7
|
||||
}
|
||||
else
|
||||
if(phase==MLINK_SEND2)
|
||||
{
|
||||
if(tog)
|
||||
packet[0] = 0x02; //x,15,13
|
||||
else
|
||||
packet[0] = 0x0A; //x,14,12
|
||||
tog^=1;
|
||||
}
|
||||
else
|
||||
{//phase==MLINK_SEND3
|
||||
if((hopping_frequency_no&1)==0)
|
||||
packet[0] = 0x88; //4,2,0
|
||||
else
|
||||
packet[0] = 0x80; //5,3,1
|
||||
}
|
||||
|
||||
//Start channel
|
||||
start=4+6*(packet[0]&3);
|
||||
if((packet[0]&0x08)==0)
|
||||
start++;
|
||||
|
||||
//Channels 426..1937..3448
|
||||
for(uint8_t i=0;i<3;i++)
|
||||
{
|
||||
uint16_t val=start<16 ? convert_channel_16b_nolimit(start,426,3448,false) : 0x0000;
|
||||
start-=2; // switch to next channel
|
||||
packet[i*2+1]=val>>8;
|
||||
packet[i*2+2]=val;
|
||||
}
|
||||
}
|
||||
|
||||
//Calculate CRC
|
||||
crc8=bit_reverse(hopping_frequency_no + MLINK_CRC_Init); // Init = relected freq index + offset
|
||||
for(uint8_t i=0;i<MLINK_PACKET_SIZE-1;i++)
|
||||
crc8_update(bit_reverse(packet[i]));
|
||||
packet[7] = bit_reverse(crc8); // CRC reflected out
|
||||
|
||||
//Send
|
||||
CYRF_WriteDataPacketLen(packet, MLINK_PACKET_SIZE);
|
||||
|
||||
//Debug
|
||||
#if 0
|
||||
debug("P(%02d):",hopping_frequency_no);
|
||||
for(uint8_t i=0;i<8;i++)
|
||||
debug(" %02X",packet[i]);
|
||||
debugln("");
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef MLINK_HUB_TELEMETRY
|
||||
static void __attribute__((unused)) MLINK_Send_Telemetry()
|
||||
{ // not sure how MLINK telemetry works, the 2 RXs I have are sending something completly different...
|
||||
RX_RSSI = TX_LQI;
|
||||
|
||||
if(packet_in[0]==0x13)
|
||||
{ // RX-9-DR : 13 1A C8 00 01 64 00
|
||||
v_lipo1 = packet_in[5*2]; // Rx_Batt*20
|
||||
}
|
||||
|
||||
if(packet_in[0]==0x03)
|
||||
{ // RX-5 : 03 15 23 00 00 01 02
|
||||
//Incoming packet values
|
||||
RX_RSSI = packet_in[2*2]<<1; // Looks to be the RX RSSI value
|
||||
RX_LQI = packet_in[5*2]; // Looks to be connection lost
|
||||
}
|
||||
|
||||
// Read TX RSSI
|
||||
TX_RSSI = CYRF_ReadRegister(CYRF_13_RSSI)&0x1F;
|
||||
|
||||
telemetry_counter++; // TX LQI counter
|
||||
telemetry_link = 1;
|
||||
|
||||
if(telemetry_lost)
|
||||
{
|
||||
telemetry_lost = 0;
|
||||
packet_count = 100;
|
||||
telemetry_counter = 100;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
uint16_t ReadMLINK()
|
||||
{
|
||||
uint8_t status;//,len,sum=0,check=0;
|
||||
uint16_t start;
|
||||
|
||||
switch(phase)
|
||||
{
|
||||
case MLINK_BIND_RX:
|
||||
//debugln("RX");
|
||||
status=CYRF_ReadRegister(CYRF_05_RX_CTRL);
|
||||
if( (status&0x80) == 0 )
|
||||
{//Packet received
|
||||
len=CYRF_ReadRegister(CYRF_09_RX_COUNT);
|
||||
debugln("L=%02X",len)
|
||||
if( len==8 )
|
||||
{
|
||||
CYRF_ReadDataPacketLen(packet, len*2);
|
||||
debug("RX=");
|
||||
for(uint8_t i=0;i<8;i++)
|
||||
debug(" %02X",packet[i*2]);
|
||||
debugln("");
|
||||
//Check CRC
|
||||
crc8=0xFF; // Init = 0xFF
|
||||
for(uint8_t i=0;i<MLINK_PACKET_SIZE-1;i++)
|
||||
crc8_update(bit_reverse(packet[i<<1]));
|
||||
if(packet[14] == bit_reverse(crc8))
|
||||
{// CRC is ok
|
||||
debugln("CRC ok");
|
||||
if(packet[0]==0x7F)
|
||||
packet_count=3; // Start sending bind payload
|
||||
else if(packet_count > 0x19*2)
|
||||
{
|
||||
if(packet[0] == 0x8F)
|
||||
packet_count++;
|
||||
else if(packet[0] == 0x9F)
|
||||
packet_count=0x80; // End bind
|
||||
else
|
||||
packet_count=0; // Restart bind...
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
packet_count=0;
|
||||
CYRF_WriteRegister(CYRF_29_RX_ABORT, 0x20); // Enable RX abort
|
||||
CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x24); // Force end state
|
||||
CYRF_WriteRegister(CYRF_29_RX_ABORT, 0x00); // Disable RX abort
|
||||
phase=MLINK_BIND_TX; // Retry sending bind packet
|
||||
CYRF_SetTxRxMode(TX_EN); // Transmit mode
|
||||
if(packet_count)
|
||||
return 18136;
|
||||
case MLINK_BIND_TX:
|
||||
if(--bind_counter==0 || packet_count>=0x1B*2)
|
||||
{ // Switch to normal mode
|
||||
BIND_DONE;
|
||||
phase=MLINK_PREP_DATA;
|
||||
return 22720;
|
||||
}
|
||||
MLINK_send_bind_packet();
|
||||
if(packet_count == 0 || packet_count > 0x19*2)
|
||||
{
|
||||
phase++; // MLINK_BIND_PREP_RX
|
||||
return 4700; // Original is 4900
|
||||
}
|
||||
packet_count++;
|
||||
if(packet_count&1)
|
||||
return 6000;
|
||||
return 22720;
|
||||
case MLINK_BIND_PREP_RX:
|
||||
start=micros();
|
||||
while ((uint16_t)((uint16_t)micros()-(uint16_t)start) < 200) // Wait max 200µs for TX to finish
|
||||
if((CYRF_ReadRegister(CYRF_02_TX_CTRL) & 0x80) == 0x00)
|
||||
break; // Packet transmission complete
|
||||
CYRF_SetTxRxMode(RX_EN); // Receive mode
|
||||
CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x82); // Prepare to receive
|
||||
phase++; //MLINK_BIND_RX
|
||||
if(packet_count > 0x19*2)
|
||||
return 28712; // Give more time to the RX to confirm that the bind is ok...
|
||||
return 28712-4700;
|
||||
|
||||
|
||||
case MLINK_PREP_DATA:
|
||||
CYRF_ConfigDataCode(MLINK_Data_Code,16);
|
||||
MLINK_CRC_Init += 0xED;
|
||||
hopping_frequency_no = 0x00;
|
||||
CYRF_ConfigRFChannel(hopping_frequency[hopping_frequency_no]);
|
||||
CYRF_SetPower(0x38);
|
||||
#ifdef MLINK_HUB_TELEMETRY
|
||||
packet_count = 0;
|
||||
telemetry_lost = 1;
|
||||
#endif
|
||||
phase++;
|
||||
|
||||
|
||||
case MLINK_SEND1:
|
||||
MLINK_send_data_packet();
|
||||
phase++;
|
||||
return 4880+1111;
|
||||
case MLINK_SEND2:
|
||||
MLINK_send_data_packet();
|
||||
phase++;
|
||||
if(hopping_frequency_no%5==0)
|
||||
return 4617+1017;
|
||||
return 4617+1422;
|
||||
case MLINK_SEND3:
|
||||
MLINK_send_data_packet();
|
||||
phase++;
|
||||
return 4611;
|
||||
case MLINK_CHECK3:
|
||||
//Switch to next channel
|
||||
hopping_frequency_no++;
|
||||
if(hopping_frequency_no>=MLINK_NUM_FREQ)
|
||||
hopping_frequency_no=0;
|
||||
CYRF_ConfigRFChannel(hopping_frequency[hopping_frequency_no]);
|
||||
|
||||
//Receive telemetry
|
||||
if(hopping_frequency_no%5==0)
|
||||
{//Receive telemetry
|
||||
CYRF_SetTxRxMode(RX_EN); // Receive mode
|
||||
CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x82); // Prepare to receive
|
||||
phase++; //MLINK_RX
|
||||
return 8038+2434+410-1000;
|
||||
}
|
||||
else
|
||||
CYRF_SetPower(0x38);
|
||||
phase=MLINK_SEND1;
|
||||
return 4470;
|
||||
case MLINK_RX:
|
||||
#ifdef MLINK_HUB_TELEMETRY
|
||||
//TX LQI calculation
|
||||
packet_count++;
|
||||
if(packet_count>=100)
|
||||
{
|
||||
packet_count=0;
|
||||
TX_LQI=telemetry_counter;
|
||||
if(telemetry_counter==0)
|
||||
telemetry_lost = 1;
|
||||
telemetry_counter = 0;
|
||||
}
|
||||
#endif
|
||||
status=CYRF_ReadRegister(CYRF_05_RX_CTRL);
|
||||
debug("T(%02X):",status);
|
||||
if( (status&0x80) == 0 )
|
||||
{//Packet received
|
||||
len=CYRF_ReadRegister(CYRF_09_RX_COUNT);
|
||||
debug("(%X)",len)
|
||||
if( len && len <= MLINK_PACKET_SIZE )
|
||||
{
|
||||
CYRF_ReadDataPacketLen(packet_in, len*2);
|
||||
#ifdef MLINK_HUB_TELEMETRY
|
||||
if(len==MLINK_PACKET_SIZE)
|
||||
{
|
||||
for(uint8_t i=0;i<8;i++)
|
||||
//Check CRC
|
||||
crc8=bit_reverse(MLINK_CRC_Init);
|
||||
for(uint8_t i=0;i<MLINK_PACKET_SIZE-1;i++)
|
||||
{
|
||||
crc8_update(bit_reverse(packet_in[i<<1]));
|
||||
debug(" %02X",packet_in[i<<1]);
|
||||
}
|
||||
if(packet_in[14] == bit_reverse(crc8)) // Packet CRC is ok
|
||||
MLINK_Send_Telemetry();
|
||||
else
|
||||
debug(" NOK");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
debugln("");
|
||||
CYRF_WriteRegister(CYRF_29_RX_ABORT, 0x20); // Enable RX abort
|
||||
CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x24); // Force end state
|
||||
CYRF_WriteRegister(CYRF_29_RX_ABORT, 0x00); // Disable RX abort
|
||||
CYRF_SetTxRxMode(TX_EN); // Transmit mode
|
||||
phase=MLINK_SEND2;
|
||||
return 1000;
|
||||
}
|
||||
return 1000;
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) MLINK_shuffle_freqs(uint32_t seed, uint8_t *hop)
|
||||
{
|
||||
randomSeed(seed);
|
||||
|
||||
for(uint8_t i=0; i < MLINK_NUM_FREQ/2; i++)
|
||||
{
|
||||
uint8_t r = random(0xfefefefe) % (MLINK_NUM_FREQ/2);
|
||||
uint8_t tmp = hop[r];
|
||||
hop[r] = hop[i];
|
||||
hop[i] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t initMLINK()
|
||||
{
|
||||
MLINK_cyrf_config();
|
||||
|
||||
//Init ID and RF freqs
|
||||
for(uint8_t i=0; i < MLINK_NUM_FREQ/2; i++)
|
||||
{
|
||||
hopping_frequency[i ] = (i<<1) + 3;
|
||||
hopping_frequency[i+MLINK_NUM_FREQ/2] = (i<<1) + 3;
|
||||
}
|
||||
// part1
|
||||
memcpy(MLINK_Data_Code ,rx_tx_addr,4);
|
||||
MLINK_shuffle_freqs(MProtocol_id, hopping_frequency);
|
||||
|
||||
// part2
|
||||
MProtocol_id ^= 0x6FBE3201;
|
||||
set_rx_tx_addr(MProtocol_id);
|
||||
memcpy(MLINK_Data_Code+4,rx_tx_addr,4);
|
||||
MLINK_shuffle_freqs(MProtocol_id, &hopping_frequency[MLINK_NUM_FREQ/2]);
|
||||
|
||||
// part3
|
||||
MLINK_CRC_Init = rx_tx_addr[3]; //value sent during bind then used to init the CRC
|
||||
MLINK_Unk_6_2 = 0x3A; //unknown value sent during bind but doesn't seem to matter
|
||||
|
||||
#ifdef MLINK_FORCE_ID
|
||||
if(RX_num)
|
||||
{
|
||||
//Cockpit SX
|
||||
memcpy(MLINK_Data_Code,"\x4C\x97\x9D\xBF\xB8\x3D\xB5\xBE",8);
|
||||
memcpy(hopping_frequency,"\x0D\x41\x09\x43\x17\x2D\x05\x31\x13\x3B\x1B\x3D\x0B\x41\x11\x45\x09\x2B\x17\x4D\x19\x3F\x03\x3F\x0F\x37\x1F\x47\x1B\x49\x07\x35\x27\x2F\x15\x33\x23\x39\x1F\x33\x19\x45\x0D\x2D\x11\x35\x0B\x47\x25\x3D\x21\x37\x1D\x3B\x05\x2F\x21\x39\x23\x4B\x03\x31\x25\x29\x07\x4F\x1D\x4B\x15\x4D\x13\x4F\x0F\x49\x29\x2B\x27\x43",MLINK_NUM_FREQ);
|
||||
MLINK_Unk_6_2 = 0x3A; //unknown value sent during bind but doesn't seem to matter
|
||||
MLINK_CRC_Init = 0x07; //value sent during bind then used to init the CRC
|
||||
}
|
||||
else
|
||||
{
|
||||
//HFM3
|
||||
memcpy(MLINK_Data_Code,"\xC0\x90\x8F\xBB\x7C\x8E\x2B\x8E",8);
|
||||
memcpy(hopping_frequency,"\x05\x41\x27\x4B\x17\x33\x11\x39\x0F\x3F\x05\x2F\x13\x2D\x25\x31\x1F\x2D\x25\x35\x03\x41\x1B\x43\x09\x3D\x1F\x29\x1D\x35\x0D\x3B\x19\x49\x23\x3B\x17\x47\x1D\x2B\x13\x37\x0B\x31\x23\x33\x29\x3F\x07\x37\x07\x43\x11\x2B\x1B\x39\x0B\x4B\x03\x4F\x21\x47\x0F\x4D\x15\x45\x21\x4F\x09\x3D\x19\x2F\x15\x45\x0D\x49\x27\x4D",MLINK_NUM_FREQ);
|
||||
MLINK_Unk_6_2 = 0x02; //unknown value but doesn't seem to matter
|
||||
MLINK_CRC_Init = 0x3E; //value sent during bind then used to init the CRC
|
||||
}
|
||||
//Other TX
|
||||
//MLINK_Unk_6_2 = 0x7e; //unknown value but doesn't seem to matter
|
||||
//MLINK_CRC_Init = 0xA2; //value sent during bind then used to init the CRC
|
||||
#endif
|
||||
|
||||
for(uint8_t i=0;i<8;i++)
|
||||
MLINK_Data_Code[i+8]=MLINK_Data_Code[7-i];
|
||||
|
||||
debug("ID:")
|
||||
for(uint8_t i=0;i<16;i++)
|
||||
debug(" %02X", MLINK_Data_Code[i]);
|
||||
debugln("");
|
||||
|
||||
debugln("CRC init: %02X", MLINK_CRC_Init)
|
||||
|
||||
debug("RF:")
|
||||
for(uint8_t i=0;i<MLINK_NUM_FREQ;i++)
|
||||
debug(" %02X", hopping_frequency[i]);
|
||||
debugln("");
|
||||
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
packet_count = 0;
|
||||
bind_counter = MLINK_BIND_COUNT;
|
||||
CYRF_ConfigDataCode((uint8_t*)"\x6F\xBE\x32\x01\xDB\xF1\x2B\x01\xE3\x5C\xFA\x02\x97\x93\xF9\x02",16); //Bind data code
|
||||
CYRF_ConfigRFChannel(MLINK_BIND_CHANNEL);
|
||||
phase = MLINK_BIND_TX;
|
||||
}
|
||||
else
|
||||
phase = MLINK_PREP_DATA;
|
||||
|
||||
return 10000;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -19,19 +19,19 @@
|
||||
|
||||
#include "iface_nrf24l01.h"
|
||||
|
||||
#define MT99XX_BIND_COUNT 928
|
||||
#define MT99XX_PACKET_PERIOD_FY805 2460
|
||||
#define MT99XX_PACKET_PERIOD_MT 2625
|
||||
#define MT99XX_PACKET_PERIOD_YZ 3125
|
||||
#define MT99XX_INITIAL_WAIT 500
|
||||
#define MT99XX_PACKET_SIZE 9
|
||||
#define MT99XX_BIND_COUNT 928
|
||||
#define MT99XX_PACKET_PERIOD_FY805 2460
|
||||
#define MT99XX_PACKET_PERIOD_MT 2625
|
||||
#define MT99XX_PACKET_PERIOD_YZ 3125
|
||||
#define MT99XX_PACKET_PERIOD_A180 3400 // timing changes between the packets 2 x 27220 then 1x 26080, it seems that it is only on the first RF channel which jitters by 1.14ms but hard to pinpoint with XN297dump
|
||||
#define MT99XX_INITIAL_WAIT 500
|
||||
#define MT99XX_PACKET_SIZE 9
|
||||
|
||||
#define checksum_offset rf_ch_num
|
||||
#define channel_offset phase
|
||||
//#define FORCE_A180_ID
|
||||
|
||||
enum{
|
||||
// flags going to packet[6] (MT99xx, H7)
|
||||
FLAG_MT_RATE1 = 0x01, // (H7 high rate)
|
||||
FLAG_MT_RATE1 = 0x01, // (H7 & A180 high rate)
|
||||
FLAG_MT_RATE2 = 0x02, // (MT9916 only)
|
||||
FLAG_MT_VIDEO = 0x10,
|
||||
FLAG_MT_SNAPSHOT= 0x20,
|
||||
@@ -53,6 +53,12 @@ enum{
|
||||
FLAG_FY805_HEADLESS= 0x10,
|
||||
};
|
||||
|
||||
enum{
|
||||
// flags going to packet[6] (A180)
|
||||
FLAG_A180_3D6G = 0x01,
|
||||
FLAG_A180_RATE = 0x02,
|
||||
};
|
||||
|
||||
enum {
|
||||
MT99XX_INIT = 0,
|
||||
MT99XX_BIND,
|
||||
@@ -64,89 +70,134 @@ const uint8_t h7_mys_byte[] = {
|
||||
0x05, 0x15, 0x06, 0x16, 0x07, 0x17, 0x00, 0x10
|
||||
};
|
||||
|
||||
static const uint8_t ls_mys_byte[] = {
|
||||
const uint8_t ls_mys_byte[] = {
|
||||
0x05, 0x15, 0x25, 0x06, 0x16, 0x26,
|
||||
0x07, 0x17, 0x27, 0x00, 0x10, 0x20,
|
||||
0x01, 0x11, 0x21, 0x02, 0x12, 0x22,
|
||||
0x03, 0x13, 0x23, 0x04, 0x14, 0x24
|
||||
};
|
||||
|
||||
const uint8_t yz_p4_seq[] = {0xa0, 0x20, 0x60};
|
||||
|
||||
static void __attribute__((unused)) MT99XX_send_packet()
|
||||
{
|
||||
const uint8_t yz_p4_seq[] = {0xa0, 0x20, 0x60};
|
||||
static uint8_t yz_seq_num=0;
|
||||
static uint8_t ls_counter=0;
|
||||
static uint8_t seq_num=0;
|
||||
|
||||
if(sub_protocol != YZ)
|
||||
{ // MT99XX & H7 & LS
|
||||
packet[0] = convert_channel_16b_limit(THROTTLE,0xE1,0x00); // throttle
|
||||
packet[1] = convert_channel_16b_limit(RUDDER ,0x00,0xE1); // rudder
|
||||
packet[2] = convert_channel_16b_limit(AILERON ,0xE1,0x00); // aileron
|
||||
packet[3] = convert_channel_16b_limit(ELEVATOR,0x00,0xE1); // elevator
|
||||
packet[4] = 0x20; // pitch trim (0x3f-0x20-0x00)
|
||||
packet[5] = 0x20; // roll trim (0x00-0x20-0x3f)
|
||||
packet[6] = GET_FLAG( CH5_SW, FLAG_MT_FLIP );
|
||||
packet[7] = h7_mys_byte[hopping_frequency_no]; // next rf channel index ?
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
//Bind packet
|
||||
packet[0] = 0x20;
|
||||
switch(sub_protocol)
|
||||
{
|
||||
case YZ:
|
||||
packet_period = MT99XX_PACKET_PERIOD_YZ;
|
||||
packet[1] = 0x15;
|
||||
packet[2] = 0x05;
|
||||
packet[3] = 0x06;
|
||||
break;
|
||||
case LS:
|
||||
packet[1] = 0x14;
|
||||
packet[2] = 0x05;
|
||||
packet[3] = 0x11;
|
||||
break;
|
||||
case FY805:
|
||||
packet_period = MT99XX_PACKET_PERIOD_FY805;
|
||||
packet[1] = 0x15;
|
||||
packet[2] = 0x12;
|
||||
packet[3] = 0x17;
|
||||
break;
|
||||
case A180:
|
||||
packet_period = MT99XX_PACKET_PERIOD_A180;
|
||||
default: // MT99 & H7 & A180
|
||||
packet[1] = 0x14;
|
||||
packet[2] = 0x03;
|
||||
packet[3] = 0x25;
|
||||
break;
|
||||
}
|
||||
packet[4] = rx_tx_addr[0];
|
||||
packet[5] = rx_tx_addr[1];
|
||||
packet[6] = rx_tx_addr[2];
|
||||
packet[7] = crc8; // checksum offset
|
||||
packet[8] = 0xAA; // fixed
|
||||
}
|
||||
else
|
||||
{
|
||||
if(sub_protocol != YZ)
|
||||
{ // MT99XX & H7 & LS & FY805 & A180
|
||||
packet[0] = convert_channel_16b_limit(THROTTLE,0xE1,0x00); // throttle
|
||||
packet[1] = convert_channel_16b_limit(RUDDER ,0x00,0xE1); // rudder
|
||||
packet[2] = convert_channel_16b_limit(AILERON ,0xE1,0x00); // aileron
|
||||
packet[3] = convert_channel_16b_limit(ELEVATOR,0x00,0xE1); // elevator
|
||||
packet[4] = 0x20; // pitch trim (0x3f-0x20-0x00)
|
||||
packet[5] = 0x20; // roll trim (0x00-0x20-0x3f)
|
||||
packet[6] = GET_FLAG( CH5_SW, FLAG_MT_FLIP );
|
||||
packet[7] = h7_mys_byte[hopping_frequency_no]; // next rf channel index ?
|
||||
|
||||
if(sub_protocol==H7)
|
||||
packet[6]|=FLAG_MT_RATE1; // max rate on H7
|
||||
else
|
||||
if(sub_protocol==MT99)
|
||||
packet[6] |= 0x40 | FLAG_MT_RATE2
|
||||
| GET_FLAG( CH7_SW, FLAG_MT_SNAPSHOT )
|
||||
| GET_FLAG( CH8_SW, FLAG_MT_VIDEO ); // max rate on MT99xx
|
||||
else
|
||||
if(sub_protocol==FY805)
|
||||
{
|
||||
switch(sub_protocol)
|
||||
{
|
||||
case MT99:
|
||||
packet[6] |= 0x40 | FLAG_MT_RATE2 // max rate on MT99xx
|
||||
| GET_FLAG( CH7_SW, FLAG_MT_SNAPSHOT )
|
||||
| GET_FLAG( CH8_SW, FLAG_MT_VIDEO );
|
||||
break;
|
||||
case H7:
|
||||
packet[6] |= FLAG_MT_RATE1; // max rate on H7
|
||||
break;
|
||||
case LS:
|
||||
packet[6] |= FLAG_LS_RATE // max rate
|
||||
| GET_FLAG( CH6_SW, FLAG_LS_INVERT ) // invert
|
||||
| GET_FLAG( CH7_SW, FLAG_LS_SNAPSHOT ) // snapshot
|
||||
| GET_FLAG( CH8_SW, FLAG_LS_VIDEO ) // video
|
||||
| GET_FLAG( CH9_SW, FLAG_LS_HEADLESS ); // Headless
|
||||
packet[7] = ls_mys_byte[seq_num++];
|
||||
if(seq_num >= sizeof(ls_mys_byte))
|
||||
seq_num=0;
|
||||
break;
|
||||
case FY805:
|
||||
packet[6]=0x20;
|
||||
//Rate 0x01?
|
||||
//Flip ?
|
||||
packet[7]=0x01
|
||||
|GET_FLAG( CH5_SW, FLAG_MT_FLIP )
|
||||
|GET_FLAG( CH9_SW, FLAG_FY805_HEADLESS ); //HEADLESS
|
||||
checksum_offset=0;
|
||||
}
|
||||
else //LS
|
||||
{
|
||||
packet[6] |= FLAG_LS_RATE // max rate
|
||||
| GET_FLAG( CH6_SW, FLAG_LS_INVERT ) //INVERT
|
||||
| GET_FLAG( CH7_SW, FLAG_LS_SNAPSHOT ) //SNAPSHOT
|
||||
| GET_FLAG( CH8_SW, FLAG_LS_VIDEO ) //VIDEO
|
||||
| GET_FLAG( CH9_SW, FLAG_LS_HEADLESS ); //HEADLESS
|
||||
packet[7] = ls_mys_byte[ls_counter++];
|
||||
if(ls_counter >= sizeof(ls_mys_byte))
|
||||
ls_counter=0;
|
||||
}
|
||||
|
||||
uint8_t result=checksum_offset;
|
||||
for(uint8_t i=0; i<8; i++)
|
||||
result += packet[i];
|
||||
packet[8] = result;
|
||||
}
|
||||
else
|
||||
{ // YZ
|
||||
packet[0] = convert_channel_16b_limit(THROTTLE,0x00,0x64); // throttle
|
||||
packet[1] = convert_channel_16b_limit(RUDDER ,0x64,0x00); // rudder
|
||||
packet[2] = convert_channel_16b_limit(ELEVATOR,0x00,0x64); // elevator
|
||||
packet[3] = convert_channel_16b_limit(AILERON ,0x64,0x00); // aileron
|
||||
if(packet_count++ >= 23)
|
||||
{
|
||||
yz_seq_num ++;
|
||||
if(yz_seq_num > 2)
|
||||
yz_seq_num = 0;
|
||||
packet_count=0;
|
||||
|GET_FLAG( CH9_SW, FLAG_FY805_HEADLESS ); //HEADLESS
|
||||
crc8=0;
|
||||
break;
|
||||
case A180:
|
||||
packet[6] = FLAG_A180_RATE
|
||||
| GET_FLAG( CH5_SW, FLAG_A180_3D6G );
|
||||
packet[7] = 0x00;
|
||||
break;
|
||||
}
|
||||
uint8_t result=crc8;
|
||||
for(uint8_t i=0; i<8; i++)
|
||||
result += packet[i];
|
||||
packet[8] = result;
|
||||
}
|
||||
else
|
||||
{ // YZ
|
||||
packet[0] = convert_channel_16b_limit(THROTTLE,0x00,0x64); // throttle
|
||||
packet[1] = convert_channel_16b_limit(RUDDER ,0x64,0x00); // rudder
|
||||
packet[2] = convert_channel_16b_limit(ELEVATOR,0x00,0x64); // elevator
|
||||
packet[3] = convert_channel_16b_limit(AILERON ,0x64,0x00); // aileron
|
||||
if(packet_count++ >= 23)
|
||||
{
|
||||
seq_num ++;
|
||||
if(seq_num > 2)
|
||||
seq_num = 0;
|
||||
packet_count=0;
|
||||
}
|
||||
packet[4] = yz_p4_seq[seq_num];
|
||||
packet[5] = 0x02 // expert ? (0=unarmed, 1=normal)
|
||||
| GET_FLAG(CH8_SW, 0x10) //VIDEO
|
||||
| GET_FLAG(CH5_SW, 0x80) //FLIP
|
||||
| GET_FLAG(CH9_SW, 0x04) //HEADLESS
|
||||
| GET_FLAG(CH7_SW, 0x20); //SNAPSHOT
|
||||
packet[6] = GET_FLAG(CH6_SW, 0x80); //LED
|
||||
packet[7] = packet[0];
|
||||
for(uint8_t idx = 1; idx < MT99XX_PACKET_SIZE-2; idx++)
|
||||
packet[7] += packet[idx];
|
||||
packet[8] = 0xff;
|
||||
}
|
||||
packet[4] = yz_p4_seq[yz_seq_num];
|
||||
packet[5] = 0x02 // expert ? (0=unarmed, 1=normal)
|
||||
| GET_FLAG(CH8_SW, 0x10) //VIDEO
|
||||
| GET_FLAG(CH5_SW, 0x80) //FLIP
|
||||
| GET_FLAG(CH9_SW, 0x04) //HEADLESS
|
||||
| GET_FLAG(CH7_SW, 0x20); //SNAPSHOT
|
||||
packet[6] = GET_FLAG(CH6_SW, 0x80); //LED
|
||||
packet[7] = packet[0];
|
||||
for(uint8_t idx = 1; idx < MT99XX_PACKET_SIZE-2; idx++)
|
||||
packet[7] += packet[idx];
|
||||
packet[8] = 0xff;
|
||||
}
|
||||
|
||||
if(sub_protocol == LS)
|
||||
@@ -154,14 +205,15 @@ static void __attribute__((unused)) MT99XX_send_packet()
|
||||
else
|
||||
if(sub_protocol==FY805)
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, 0x4B); // FY805 always transmits on the same channel
|
||||
else
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no] + channel_offset);
|
||||
else // MT99 & H7 & YZ & A180
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no]);
|
||||
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||
NRF24L01_FlushTx();
|
||||
XN297_WritePayload(packet, MT99XX_PACKET_SIZE);
|
||||
|
||||
hopping_frequency_no++;
|
||||
if(sub_protocol == YZ)
|
||||
if(sub_protocol == YZ || sub_protocol == A180)
|
||||
hopping_frequency_no++; // skip every other channel
|
||||
|
||||
if(hopping_frequency_no > 15)
|
||||
@@ -186,124 +238,94 @@ static void __attribute__((unused)) MT99XX_init()
|
||||
if(sub_protocol == YZ)
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_250K); // 250Kbps (nRF24L01+ only)
|
||||
else
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps
|
||||
NRF24L01_SetPower();
|
||||
|
||||
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP) );
|
||||
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) MT99XX_initialize_txid()
|
||||
{
|
||||
rx_tx_addr[3] = 0xCC;
|
||||
rx_tx_addr[4] = 0xCC;
|
||||
if(sub_protocol == YZ)
|
||||
rx_tx_addr[1] = rx_tx_addr[3]; // RX_Num
|
||||
|
||||
switch(protocol)
|
||||
{
|
||||
rx_tx_addr[0] = 0x53; // test (SB id)
|
||||
rx_tx_addr[1] = 0x00;
|
||||
rx_tx_addr[2] = 0x00;
|
||||
}
|
||||
else
|
||||
if(sub_protocol == FY805)
|
||||
{
|
||||
rx_tx_addr[0] = 0x81; // test (SB id)
|
||||
case YZ:
|
||||
rx_tx_addr[0] = 0x53; // test (SB id)
|
||||
rx_tx_addr[1] = 0x00;
|
||||
rx_tx_addr[2] = 0x00;
|
||||
break;
|
||||
case FY805:
|
||||
rx_tx_addr[0] = 0x81; // test (SB id)
|
||||
rx_tx_addr[1] = 0x0F;
|
||||
rx_tx_addr[2] = 0x00;
|
||||
}
|
||||
else
|
||||
if(sub_protocol == LS)
|
||||
rx_tx_addr[0] = 0xCC;
|
||||
else //MT99 & H7
|
||||
rx_tx_addr[2] = 0x00;
|
||||
checksum_offset = rx_tx_addr[0] + rx_tx_addr[1] + rx_tx_addr[2];
|
||||
channel_offset = (((checksum_offset & 0xf0)>>4) + (checksum_offset & 0x0f)) % 8;
|
||||
break;
|
||||
case LS:
|
||||
rx_tx_addr[0] = 0xCC;
|
||||
break;
|
||||
#ifdef FORCE_A180_ID
|
||||
case A180:
|
||||
rx_tx_addr[0] = 0x84; // MikeHRC ID
|
||||
rx_tx_addr[1] = 0x62;
|
||||
rx_tx_addr[2] = 0x4A;
|
||||
//crc8 = 0x30
|
||||
//channel_offset = 0x03;
|
||||
break;
|
||||
#endif
|
||||
default: //MT99 & H7 & A180
|
||||
rx_tx_addr[2] = 0x00;
|
||||
break;
|
||||
}
|
||||
|
||||
rx_tx_addr[3] = 0xCC;
|
||||
rx_tx_addr[4] = 0xCC;
|
||||
|
||||
crc8 = rx_tx_addr[0] + rx_tx_addr[1] + rx_tx_addr[2];
|
||||
|
||||
//memcpy(hopping_frequency,"\x02\x48\x0C\x3e\x16\x34\x20\x2A\x2A\x20\x34\x16\x3e\x0c\x48\x02",16);
|
||||
for(uint8_t i=0; i<8; i++)
|
||||
{
|
||||
hopping_frequency[(i<<1) ]=0x02 + (10*i);
|
||||
hopping_frequency[(i<<1)+1]=0x48 - (10*i);
|
||||
}
|
||||
hopping_frequency_no=0;
|
||||
}
|
||||
|
||||
uint16_t MT99XX_callback()
|
||||
{
|
||||
if(IS_BIND_DONE)
|
||||
{
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(packet_period);
|
||||
#endif
|
||||
MT99XX_send_packet();
|
||||
}
|
||||
else
|
||||
if(bind_counter)
|
||||
{
|
||||
bind_counter--;
|
||||
if (bind_counter == 0)
|
||||
{
|
||||
// set tx address for data packets
|
||||
XN297_SetTXAddr(rx_tx_addr, 5);
|
||||
// set tx address for data packets
|
||||
XN297_SetTXAddr(rx_tx_addr, 5);
|
||||
uint8_t channel_offset = (((crc8 & 0xf0)>>4) + (crc8 & 0x0f)) % 8;
|
||||
for(uint8_t i=0;i<16;i++)
|
||||
hopping_frequency[i] += channel_offset;
|
||||
BIND_DONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(sub_protocol == LS)
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, 0x2D); // LS always transmits on the same channel
|
||||
else
|
||||
if(sub_protocol==FY805)
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, 0x4B); // FY805 always transmits on the same channel
|
||||
else
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no]);
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||
NRF24L01_FlushTx();
|
||||
XN297_WritePayload(packet, MT99XX_PACKET_SIZE); // bind packet
|
||||
hopping_frequency_no++;
|
||||
if(sub_protocol == YZ)
|
||||
hopping_frequency_no++; // skip every other channel
|
||||
if(hopping_frequency_no > 15)
|
||||
hopping_frequency_no = 0;
|
||||
bind_counter--;
|
||||
}
|
||||
}
|
||||
#ifdef MULTI_SYNC
|
||||
else
|
||||
telemetry_set_input_sync(packet_period);
|
||||
#endif
|
||||
|
||||
MT99XX_send_packet();
|
||||
return packet_period;
|
||||
}
|
||||
|
||||
uint16_t initMT99XX(void)
|
||||
{
|
||||
BIND_IN_PROGRESS; // autobind protocol
|
||||
if(sub_protocol != A180)
|
||||
BIND_IN_PROGRESS; // autobind protocol
|
||||
bind_counter = MT99XX_BIND_COUNT;
|
||||
|
||||
memcpy(hopping_frequency,"\x02\x48\x0C\x3e\x16\x34\x20\x2A\x2A\x20\x34\x16\x3e\x0c\x48\x02",16);
|
||||
hopping_frequency_no=0;
|
||||
|
||||
MT99XX_initialize_txid();
|
||||
MT99XX_init();
|
||||
|
||||
packet[0] = 0x20;
|
||||
packet_period = MT99XX_PACKET_PERIOD_MT;
|
||||
switch(sub_protocol)
|
||||
{ // MT99 & H7
|
||||
case MT99:
|
||||
case H7:
|
||||
packet[1] = 0x14;
|
||||
packet[2] = 0x03;
|
||||
packet[3] = 0x25;
|
||||
break;
|
||||
case YZ:
|
||||
packet_period = MT99XX_PACKET_PERIOD_YZ;
|
||||
packet[1] = 0x15;
|
||||
packet[2] = 0x05;
|
||||
packet[3] = 0x06;
|
||||
break;
|
||||
case LS:
|
||||
packet[1] = 0x14;
|
||||
packet[2] = 0x05;
|
||||
packet[3] = 0x11;
|
||||
break;
|
||||
case FY805:
|
||||
packet_period = MT99XX_PACKET_PERIOD_FY805;
|
||||
packet[1] = 0x15;
|
||||
packet[2] = 0x12;
|
||||
packet[3] = 0x17;
|
||||
break;
|
||||
}
|
||||
packet[4] = rx_tx_addr[0];
|
||||
packet[5] = rx_tx_addr[1];
|
||||
packet[6] = rx_tx_addr[2];
|
||||
packet[7] = checksum_offset; // checksum offset
|
||||
packet[8] = 0xAA; // fixed
|
||||
|
||||
packet_count=0;
|
||||
return MT99XX_INITIAL_WAIT+MT99XX_PACKET_PERIOD_MT;
|
||||
}
|
||||
|
||||
@@ -14,11 +14,11 @@
|
||||
14,Bayang,Bayang,H8S3D,X16_AH,IRDRONE,DHD_D4,QX100
|
||||
15,FrskyX,CH_16,CH_8,EU_16,EU_8,Cloned,Clon_8
|
||||
16,ESky,Std,ET4
|
||||
17,MT99xx,MT,H7,YZ,LS,FY805
|
||||
17,MT99xx,MT,H7,YZ,LS,FY805,A180
|
||||
18,MJXq,WLH08,X600,X800,H26D,E010,H26WH,PHOENIX
|
||||
19,Shenqi
|
||||
20,FY326,FY326,FY319
|
||||
21,SFHSS
|
||||
21,Futaba,SFHSS
|
||||
22,J6PRO
|
||||
23,FQ777
|
||||
24,ASSAN
|
||||
@@ -37,7 +37,7 @@
|
||||
37,CORONA,COR_V1,COR_V2,FD_V3
|
||||
38,CFlie
|
||||
39,Hitec,OPT_FW,OPT_HUB,MINIMA
|
||||
40,WFLY
|
||||
40,WFLY,WFR0x
|
||||
41,BUGS
|
||||
42,BUGSMINI,BUGSMINI,BUGS3H
|
||||
43,Traxxas,RX6519
|
||||
@@ -52,7 +52,7 @@
|
||||
52,ZSX,280
|
||||
53,Height,5ch,8ch
|
||||
54,Scanner
|
||||
55,Frsky_RX,RX,CloneTX
|
||||
55,Frsky_RX,RX,CloneTX,EraseTX
|
||||
56,AFHDS2A_RX
|
||||
57,HoTT,Sync,No_Sync
|
||||
58,FX816,P38
|
||||
@@ -68,9 +68,16 @@
|
||||
68,Skyartec
|
||||
69,ESKYv2,150V2
|
||||
70,DSM_RX
|
||||
71,JJRC345
|
||||
71,JJRC345,JJRC345,SkyTmblr
|
||||
72,Q90C
|
||||
73,Kyosho
|
||||
74,RadioLink,Surface
|
||||
73,Kyosho,FHSS,Hype
|
||||
74,RadioLink,Surface,Air,DumboRC
|
||||
75,---
|
||||
76,Realacc,R11
|
||||
77,OMP
|
||||
77,OMP
|
||||
78,M-Link
|
||||
79,WFLY,RF20x
|
||||
80,E016H,E016Hv2
|
||||
81,E010r5
|
||||
82,LOLI
|
||||
83,E129
|
||||
@@ -38,7 +38,7 @@ const char STR_MT99XX[] ="MT99XX";
|
||||
const char STR_MJXQ[] ="MJXq";
|
||||
const char STR_SHENQI[] ="Shenqi";
|
||||
const char STR_FY326[] ="FY326";
|
||||
const char STR_SFHSS[] ="SFHSS";
|
||||
const char STR_FUTABA[] ="Futaba";
|
||||
const char STR_J6PRO[] ="J6 Pro";
|
||||
const char STR_JJRC345[] ="JJRC345";
|
||||
const char STR_FQ777[] ="FQ777";
|
||||
@@ -59,7 +59,8 @@ const char STR_H8_3D[] ="H8 3D";
|
||||
const char STR_CORONA[] ="Corona";
|
||||
const char STR_CFLIE[] ="CFlie";
|
||||
const char STR_HITEC[] ="Hitec";
|
||||
const char STR_WFLY[] ="WFly";
|
||||
const char STR_WFLY[] ="WFLY";
|
||||
const char STR_WFLY2[] ="WFLY2";
|
||||
const char STR_BUGS[] ="Bugs";
|
||||
const char STR_BUGSMINI[] ="BugMini";
|
||||
const char STR_TRAXXAS[] ="Traxxas";
|
||||
@@ -90,8 +91,13 @@ const char STR_KYOSHO[] ="Kyosho";
|
||||
const char STR_RLINK[] ="RadLink";
|
||||
const char STR_REALACC[] ="Realacc";
|
||||
const char STR_OMP[] ="OMP";
|
||||
const char STR_MLINK[] ="M-Link";
|
||||
const char STR_TEST[] ="Test";
|
||||
const char STR_FAKE[] ="Fake";
|
||||
const char STR_NANORF[] ="NanoRF";
|
||||
const char STR_E016HV2[] ="E016Hv2";
|
||||
const char STR_E010R5[] ="E010r5";
|
||||
const char STR_LOLI[] ="LOLI";
|
||||
const char STR_E129[] ="E129";
|
||||
|
||||
const char STR_SUBTYPE_FLYSKY[] = "\x04""Std\0""V9x9""V6x6""V912""CX20";
|
||||
const char STR_SUBTYPE_HUBSAN[] = "\x04""H107""H301""H501";
|
||||
@@ -108,11 +114,11 @@ const char STR_SUBTYPE_SLT[] = "\x06""V1_6ch""V2_8ch""Q100\0 ""Q200\0 ""M
|
||||
const char STR_SUBTYPE_CX10[] = "\x07""Green\0 ""Blue\0 ""DM007\0 ""-\0 ""JC3015a""JC3015b""MK33041";
|
||||
const char STR_SUBTYPE_CG023[] = "\x05""Std\0 ""YD829";
|
||||
const char STR_SUBTYPE_BAYANG[] = "\x07""Std\0 ""H8S3D\0 ""X16 AH\0""IRDrone""DHD D4\0""QX100\0 ";
|
||||
const char STR_SUBTYPE_MT99[] = "\x06""MT99\0 ""H7\0 ""YZ\0 ""LS\0 ""FY805";
|
||||
const char STR_SUBTYPE_MT99[] = "\x05""MT99\0""H7\0 ""YZ\0 ""LS\0 ""FY805""A180\0";
|
||||
const char STR_SUBTYPE_MJXQ[] = "\x07""WLH08\0 ""X600\0 ""X800\0 ""H26D\0 ""E010\0 ""H26WH\0 ""Phoenix";
|
||||
const char STR_SUBTYPE_FY326[] = "\x05""Std\0 ""FY319";
|
||||
const char STR_SUBTYPE_HONTAI[] = "\x07""Std\0 ""JJRC X1""X5C1\0 ""FQ_951";
|
||||
const char STR_SUBTYPE_AFHDS2A[] = "\x08""PWM,IBUS""PPM,IBUS""PWM,SBUS""PPM,SBUS""PWM,IB16""PPM,IB16";
|
||||
const char STR_SUBTYPE_AFHDS2A[] = "\x08""PWM,IBUS""PPM,IBUS""PWM,SBUS""PPM,SBUS""PWM,IB16""PPM,IB16""PWM,SB16""PPM,SB16";
|
||||
const char STR_SUBTYPE_Q2X2[] = "\x04""Q222""Q242""Q282";
|
||||
const char STR_SUBTYPE_WK2x01[] = "\x06""WK2801""WK2401""W6_5_1""W6_6_1""W6_HeL""W6_HeI";
|
||||
const char STR_SUBTYPE_Q303[] = "\x06""Std\0 ""CX35\0 ""CX10D\0""CX10WD";
|
||||
@@ -137,14 +143,18 @@ const char STR_SUBTYPE_XK[] = "\x04""X450""X420";
|
||||
const char STR_SUBTYPE_FRSKYR9[] = "\x07""915MHz\0""868MHz\0""915 8ch""868 8ch""FCC\0 ""--\0 ""FCC 8ch""-- 8ch\0";
|
||||
const char STR_SUBTYPE_ESKY[] = "\x03""Std""ET4";
|
||||
const char STR_SUBTYPE_PROPEL[] = "\x04""74-Z";
|
||||
const char STR_SUBTYPE_FRSKY_RX[] = "\x07""RX\0 ""CloneTX";
|
||||
const char STR_SUBTYPE_FRSKY_RX[] = "\x07""RX\0 ""CloneTX""EraseTX";
|
||||
const char STR_SUBTYPE_FRSKYL[] = "\x08""LR12\0 ""LR12 6ch";
|
||||
const char STR_SUBTYPE_WFLY[] = "\x06""WFR0xS";
|
||||
const char STR_SUBTYPE_WFLY[] = "\x05""WFR0x";
|
||||
const char STR_SUBTYPE_WFLY2[] = "\x05""RF20x";
|
||||
const char STR_SUBTYPE_HOTT[] = "\x07""Sync\0 ""No_Sync";
|
||||
const char STR_SUBTYPE_PELIKAN[] = "\x04""Pro\0""Lite";
|
||||
const char STR_SUBTYPE_V761[] = "\x03""3ch""4ch";
|
||||
const char STR_SUBTYPE_RLINK[] = "\x07""Surface""Air\0 ";
|
||||
const char STR_SUBTYPE_REALACC[] = "\x03""R11";
|
||||
const char STR_SUBTYPE_RLINK[] = "\x07""Surface""Air\0 ""DumboRC";
|
||||
const char STR_SUBTYPE_REALACC[] = "\x03""R11";
|
||||
const char STR_SUBTYPE_KYOSHO[] = "\x04""FHSS""Hype";
|
||||
const char STR_SUBTYPE_FUTABA[] = "\x05""SFHSS";
|
||||
const char STR_SUBTYPE_JJRC345[] = "\x08""JJRC345\0""SkyTmblr";
|
||||
|
||||
enum
|
||||
{
|
||||
@@ -206,9 +216,18 @@ const mm_protocol_definition multi_protocols[] = {
|
||||
#if defined(DSM_RX_CYRF6936_INO)
|
||||
{PROTO_DSM_RX, STR_DSM_RX, 0, NO_SUBTYPE, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(E010R5_CYRF6936_INO)
|
||||
{PROTO_E010R5, STR_E010R5, 0, NO_SUBTYPE, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(E016HV2_CC2500_INO)
|
||||
{PROTO_E016HV2, STR_E016HV2, 0, NO_SUBTYPE, OPTION_RFTUNE },
|
||||
#endif
|
||||
#if defined(E01X_NRF24L01_INO)
|
||||
{PROTO_E01X, STR_E01X, 3, STR_SUBTYPE_E01X, OPTION_OPTION },
|
||||
#endif
|
||||
#if defined(E129_CYRF6936_INO)
|
||||
{PROTO_E129, STR_E129, 0, NO_SUBTYPE, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(ESKY_NRF24L01_INO)
|
||||
{PROTO_ESKY, STR_ESKY, 2, STR_SUBTYPE_ESKY, OPTION_NONE },
|
||||
#endif
|
||||
@@ -222,20 +241,17 @@ const mm_protocol_definition multi_protocols[] = {
|
||||
{PROTO_FLYSKY, STR_FLYSKY, 5, STR_SUBTYPE_FLYSKY, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(AFHDS2A_A7105_INO)
|
||||
{PROTO_AFHDS2A, STR_AFHDS2A, 6, STR_SUBTYPE_AFHDS2A, OPTION_SRVFREQ },
|
||||
{PROTO_AFHDS2A, STR_AFHDS2A, 8, STR_SUBTYPE_AFHDS2A, OPTION_SRVFREQ },
|
||||
#endif
|
||||
#if defined(AFHDS2A_RX_A7105_INO)
|
||||
{PROTO_AFHDS2A_RX, STR_AFHDS2A_RX,0, NO_SUBTYPE, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(HEIGHT_A7105_INO)
|
||||
{PROTO_HEIGHT, STR_HEIGHT, 2, STR_SUBTYPE_HEIGHT, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(FQ777_NRF24L01_INO)
|
||||
{PROTO_FQ777, STR_FQ777, 0, NO_SUBTYPE, OPTION_NONE },
|
||||
#endif
|
||||
//OpenTX 2.3.x issue: DO NOT CHANGE ORDER below
|
||||
#if defined(FRSKY_RX_CC2500_INO)
|
||||
{PROTO_FRSKY_RX, STR_FRSKY_RX, 2, STR_SUBTYPE_FRSKY_RX, OPTION_RFTUNE },
|
||||
{PROTO_FRSKY_RX, STR_FRSKY_RX, 3, STR_SUBTYPE_FRSKY_RX, OPTION_RFTUNE },
|
||||
#endif
|
||||
#if defined(FRSKYD_CC2500_INO)
|
||||
{PROTO_FRSKYD, STR_FRSKYD, 2, STR_SUBTYPE_FRSKYD, OPTION_RFTUNE },
|
||||
@@ -254,6 +270,9 @@ const mm_protocol_definition multi_protocols[] = {
|
||||
#if defined(FRSKYR9_SX1276_INO)
|
||||
{PROTO_FRSKY_R9, STR_FRSKYR9, 8, STR_SUBTYPE_FRSKYR9, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(FUTABA_CC2500_INO)
|
||||
{PROTO_FUTABA, STR_FUTABA, 1, STR_SUBTYPE_FUTABA, OPTION_RFTUNE },
|
||||
#endif
|
||||
#if defined(FX816_NRF24L01_INO)
|
||||
{PROTO_FX816, STR_FX816, 1, STR_SUBTYPE_FX816, OPTION_NONE },
|
||||
#endif
|
||||
@@ -269,6 +288,9 @@ const mm_protocol_definition multi_protocols[] = {
|
||||
#if defined(H8_3D_NRF24L01_INO)
|
||||
{PROTO_H8_3D, STR_H8_3D, 4, STR_SUBTYPE_H83D, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(HEIGHT_A7105_INO)
|
||||
{PROTO_HEIGHT, STR_HEIGHT, 2, STR_SUBTYPE_HEIGHT, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(HISKY_NRF24L01_INO)
|
||||
{PROTO_HISKY, STR_HISKY, 2, STR_SUBTYPE_HISKY, OPTION_NONE },
|
||||
#endif
|
||||
@@ -288,7 +310,7 @@ const mm_protocol_definition multi_protocols[] = {
|
||||
{PROTO_J6PRO, STR_J6PRO, 0, NO_SUBTYPE, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(JJRC345_NRF24L01_INO)
|
||||
{PROTO_JJRC345, STR_JJRC345, 0, NO_SUBTYPE, OPTION_NONE },
|
||||
{PROTO_JJRC345, STR_JJRC345, 2, STR_SUBTYPE_JJRC345, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(KF606_NRF24L01_INO)
|
||||
{PROTO_KF606, STR_KF606, 0, NO_SUBTYPE, OPTION_RFTUNE },
|
||||
@@ -297,18 +319,24 @@ const mm_protocol_definition multi_protocols[] = {
|
||||
{PROTO_KN, STR_KN, 2, STR_SUBTYPE_KN, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(KYOSHO_A7105_INO)
|
||||
{PROTO_KYOSHO, STR_KYOSHO, 0, NO_SUBTYPE, OPTION_NONE },
|
||||
{PROTO_KYOSHO, STR_KYOSHO, 2, STR_SUBTYPE_KYOSHO, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(LOLI_NRF24L01_INO)
|
||||
{PROTO_LOLI, STR_LOLI, 0, NO_SUBTYPE, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(MJXQ_NRF24L01_INO)
|
||||
{PROTO_MJXQ, STR_MJXQ, 7, STR_SUBTYPE_MJXQ, OPTION_RFTUNE },
|
||||
#endif
|
||||
#if defined(MLINK_CYRF6936_INO)
|
||||
{PROTO_MLINK, STR_MLINK, 0, NO_SUBTYPE, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(MT99XX_NRF24L01_INO)
|
||||
{PROTO_MT99XX, STR_MT99XX, 5, STR_SUBTYPE_MT99, OPTION_NONE },
|
||||
{PROTO_MT99XX, STR_MT99XX, 6, STR_SUBTYPE_MT99, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(NCC1701_NRF24L01_INO)
|
||||
{PROTO_NCC1701, STR_NCC1701, 0, NO_SUBTYPE, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(OMP_NRF24L01_INO)
|
||||
#if defined(OMP_CC2500_INO)
|
||||
{PROTO_OMP, STR_OMP, 0, NO_SUBTYPE, OPTION_RFTUNE },
|
||||
#endif
|
||||
#if defined(PELIKAN_A7105_INO)
|
||||
@@ -330,7 +358,7 @@ const mm_protocol_definition multi_protocols[] = {
|
||||
{PROTO_Q90C, STR_Q90C, 0, NO_SUBTYPE, OPTION_RFTUNE },
|
||||
#endif
|
||||
#if defined(RLINK_CC2500_INO)
|
||||
{PROTO_RLINK, STR_RLINK, 2, STR_SUBTYPE_RLINK, OPTION_RFTUNE },
|
||||
{PROTO_RLINK, STR_RLINK, 3, STR_SUBTYPE_RLINK, OPTION_RFTUNE },
|
||||
#endif
|
||||
#if defined(REALACC_NRF24L01_INO)
|
||||
{PROTO_REALACC, STR_REALACC, 1, STR_SUBTYPE_REALACC, OPTION_NONE },
|
||||
@@ -341,9 +369,6 @@ const mm_protocol_definition multi_protocols[] = {
|
||||
#if defined(SCANNER_CC2500_INO)
|
||||
// {PROTO_SCANNER, STR_SCANNER, 0, NO_SUBTYPE, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(SFHSS_CC2500_INO)
|
||||
{PROTO_SFHSS, STR_SFHSS, 0, NO_SUBTYPE, OPTION_RFTUNE },
|
||||
#endif
|
||||
#if defined(SHENQI_NRF24L01_INO)
|
||||
{PROTO_SHENQI, STR_SHENQI, 0, NO_SUBTYPE, OPTION_NONE },
|
||||
#endif
|
||||
@@ -377,6 +402,9 @@ const mm_protocol_definition multi_protocols[] = {
|
||||
#if defined(WFLY_CYRF6936_INO)
|
||||
{PROTO_WFLY, STR_WFLY, 1, STR_SUBTYPE_WFLY, OPTION_NONE },
|
||||
#endif
|
||||
#if defined(WFLY2_A7105_INO)
|
||||
{PROTO_WFLY2, STR_WFLY2, 1, STR_SUBTYPE_WFLY2, OPTION_OPTION },
|
||||
#endif
|
||||
#if defined(XK_NRF24L01_INO)
|
||||
{PROTO_XK, STR_XK , 2, STR_SUBTYPE_XK, OPTION_RFTUNE },
|
||||
#endif
|
||||
@@ -392,8 +420,8 @@ const mm_protocol_definition multi_protocols[] = {
|
||||
#if defined(TEST_CC2500_INO)
|
||||
{PROTO_TEST, STR_TEST, 0, NO_SUBTYPE, OPTION_RFTUNE },
|
||||
#endif
|
||||
#if defined(FAKE_NRF24L01_INO)
|
||||
{PROTO_FAKE, STR_FAKE, 0, NO_SUBTYPE, OPTION_NONE },
|
||||
#if defined(NANORF_NRF24L01_INO)
|
||||
{PROTO_NANORF, STR_NANORF, 0, NO_SUBTYPE, OPTION_NONE },
|
||||
#endif
|
||||
{0x00, nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
//******************
|
||||
#define VERSION_MAJOR 1
|
||||
#define VERSION_MINOR 3
|
||||
#define VERSION_REVISION 1
|
||||
#define VERSION_PATCH_LEVEL 59
|
||||
#define VERSION_REVISION 2
|
||||
#define VERSION_PATCH_LEVEL 30
|
||||
|
||||
//******************
|
||||
// Protocols
|
||||
@@ -47,7 +47,7 @@ enum PROTOCOLS
|
||||
PROTO_MJXQ = 18, // =>NRF24L01
|
||||
PROTO_SHENQI = 19, // =>NRF24L01
|
||||
PROTO_FY326 = 20, // =>NRF24L01
|
||||
PROTO_SFHSS = 21, // =>CC2500
|
||||
PROTO_FUTABA = 21, // =>CC2500
|
||||
PROTO_J6PRO = 22, // =>CYRF6936
|
||||
PROTO_FQ777 = 23, // =>NRF24L01
|
||||
PROTO_ASSAN = 24, // =>NRF24L01
|
||||
@@ -102,9 +102,15 @@ enum PROTOCOLS
|
||||
PROTO_KYOSHO = 73, // =>A7105
|
||||
PROTO_RLINK = 74, // =>CC2500
|
||||
PROTO_REALACC = 76, // =>NRF24L01
|
||||
PROTO_OMP = 77, // =>NRF24L01
|
||||
PROTO_OMP = 77, // =>CC2500 & NRF24L01
|
||||
PROTO_MLINK = 78, // =>CYRF6936
|
||||
PROTO_WFLY2 = 79, // =>A7105
|
||||
PROTO_E016HV2 = 80, // =>CC2500 & NRF24L01
|
||||
PROTO_E010R5 = 81, // =>CYRF6936
|
||||
PROTO_LOLI = 82, // =>NRF24L01
|
||||
PROTO_E129 = 83, // =>CYRF6936
|
||||
|
||||
PROTO_FAKE = 126, // =>CC2500+NRF24L01
|
||||
PROTO_NANORF = 126, // =>NRF24L01
|
||||
PROTO_TEST = 127, // =>CC2500
|
||||
};
|
||||
|
||||
@@ -213,6 +219,7 @@ enum MT99XX
|
||||
YZ = 2,
|
||||
LS = 3,
|
||||
FY805 = 4,
|
||||
A180 = 5,
|
||||
};
|
||||
enum MJXQ
|
||||
{
|
||||
@@ -366,6 +373,7 @@ enum FRSKY_RX
|
||||
{
|
||||
FRSKY_RX = 0,
|
||||
FRSKY_CLONE = 1,
|
||||
FRSKY_ERASE = 2,
|
||||
};
|
||||
|
||||
enum FRSKYL
|
||||
@@ -398,6 +406,25 @@ enum HEIGHT
|
||||
HEIGHT_8CH = 1,
|
||||
};
|
||||
|
||||
enum KYOSHO
|
||||
{
|
||||
KYOSHO_FHSS = 0,
|
||||
KYOSHO_HYPE = 1,
|
||||
};
|
||||
|
||||
enum JJRC345
|
||||
{
|
||||
JJRC345 = 0,
|
||||
SKYTMBLR = 1,
|
||||
};
|
||||
|
||||
enum RLINK
|
||||
{
|
||||
RLINK_SURFACE = 0,
|
||||
RLINK_AIR = 1,
|
||||
RLINK_DUMBORC = 2,
|
||||
};
|
||||
|
||||
#define NONE 0
|
||||
#define P_HIGH 1
|
||||
#define P_LOW 0
|
||||
@@ -440,8 +467,8 @@ enum MultiPacketTypes
|
||||
//***************
|
||||
//*** 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 || protocol==PROTO_FRSKYX2 || protocol==PROTO_FRSKY_R9)
|
||||
#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 || protocol==PROTO_SKYARTEC || protocol==PROTO_ESKY150V2 || protocol==PROTO_DSM_RX)
|
||||
#define IS_FAILSAFE_PROTOCOL ( (protocol==PROTO_HISKY && sub_protocol==HK310) || protocol==PROTO_AFHDS2A || protocol==PROTO_DEVO || protocol==PROTO_FUTABA || protocol==PROTO_WK2x01 || protocol== PROTO_HOTT || protocol==PROTO_FRSKYX || protocol==PROTO_FRSKYX2 || protocol==PROTO_FRSKY_R9 || protocol==PROTO_WFLY2 || protocol==PROTO_LOLI || protocol==PROTO_MLINK)
|
||||
#define IS_CHMAP_PROTOCOL ( (protocol==PROTO_HISKY && sub_protocol==HK310) || protocol==PROTO_AFHDS2A || protocol==PROTO_DEVO || protocol==PROTO_FUTABA || protocol==PROTO_WK2x01 || protocol== PROTO_DSM || protocol==PROTO_SLT || protocol==PROTO_FLYSKY || (protocol==PROTO_KYOSHO && sub_protocol==KYOSHO_HYPE) || protocol==PROTO_ESKY || protocol==PROTO_J6PRO || protocol==PROTO_PELIKAN || protocol==PROTO_SKYARTEC || protocol==PROTO_ESKY150V2 || protocol==PROTO_DSM_RX)
|
||||
|
||||
//***************
|
||||
//*** Flags ***
|
||||
@@ -547,8 +574,9 @@ enum MultiPacketTypes
|
||||
//********************
|
||||
#if defined(STM32_BOARD) && (defined (DEBUG_SERIAL) || defined (ARDUINO_MULTI_DEBUG))
|
||||
uint16_t debug_time=0;
|
||||
#define debug(msg, ...) {char debug_buf[64]; sprintf(debug_buf, msg, ##__VA_ARGS__); Serial.write(debug_buf);}
|
||||
#define debugln(msg, ...) {char debug_buf[64]; sprintf(debug_buf, msg "\r\n", ##__VA_ARGS__); Serial.write(debug_buf);}
|
||||
char debug_buf[64];
|
||||
#define debug(msg, ...) { sprintf(debug_buf, msg, ##__VA_ARGS__); Serial.write(debug_buf);}
|
||||
#define debugln(msg, ...) { sprintf(debug_buf, msg "\r\n", ##__VA_ARGS__); Serial.write(debug_buf);}
|
||||
#define debug_time(msg) { uint16_t debug_time_TCNT1=TCNT1; debug_time=debug_time_TCNT1-debug_time; debug(msg "%u", debug_time>>1); debug_time=debug_time_TCNT1; }
|
||||
#define debugln_time(msg) { uint16_t debug_time_TCNT1=TCNT1; debug_time=debug_time_TCNT1-debug_time; debug(msg "%u\r\n", debug_time>>1); debug_time=debug_time_TCNT1; }
|
||||
#else
|
||||
@@ -720,6 +748,15 @@ enum {
|
||||
#define DSM_RX_EEPROM_OFFSET 877 // (4) TX ID + format, 5 bytes, end is 882
|
||||
//#define CONFIG_EEPROM_OFFSET 882 // Current configuration of the multimodule
|
||||
|
||||
/* STM32 Flash Size */
|
||||
#ifndef DISABLE_FLASH_SIZE_CHECK
|
||||
#ifdef MCU_STM32F103C8
|
||||
#define MCU_EXPECTED_FLASH_SIZE 64 // STM32F103C8 has 64KB of flash space
|
||||
#else
|
||||
#define MCU_EXPECTED_FLASH_SIZE 128 // STM32F103CB has 128KB of flash space
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//****************************************
|
||||
//*** MULTI protocol serial definition ***
|
||||
//****************************************
|
||||
@@ -734,8 +771,9 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
||||
0x54 sub_protocol values are 32..63 Stream contains channels
|
||||
0x57 sub_protocol values are 0..31 Stream contains failsafe
|
||||
0x56 sub_protocol values are 32..63 Stream contains failsafe
|
||||
Note: V2 adds the 2 top bits to extend the number of protocols to 256 in Stream[26]
|
||||
Stream[1] = sub_protocol|BindBit|RangeCheckBit|AutoBindBit;
|
||||
sub_protocol is 0..31 (bits 0..4), value should be added with 32 if Stream[0] = 0x54 | 0x56
|
||||
sub_protocol is 0..31 (bits 0..4)
|
||||
Reserved 0
|
||||
Flysky 1
|
||||
Hubsan 2
|
||||
@@ -757,7 +795,7 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
||||
MJXQ 18
|
||||
SHENQI 19
|
||||
FY326 20
|
||||
SFHSS 21
|
||||
Futaba 21
|
||||
J6PRO 22
|
||||
FQ777 23
|
||||
ASSAN 24
|
||||
@@ -813,6 +851,12 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
||||
RLINK 74
|
||||
REALACC 76
|
||||
OMP 77
|
||||
MLINK 78
|
||||
WFLY2 79
|
||||
E016HV2 80
|
||||
E010R5 81
|
||||
LOLI 82
|
||||
E129 83
|
||||
BindBit=> 0x80 1=Bind/0=No
|
||||
AutoBindBit=> 0x40 1=Yes /0=No
|
||||
RangeCheck=> 0x20 1=Yes /0=No
|
||||
@@ -1006,6 +1050,13 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
||||
sub_protocol==HEIGHT
|
||||
HEIGHT_5CH 0
|
||||
HEIGHT_8CH 1
|
||||
sub_protocol==JJRC345
|
||||
JJRC345 0
|
||||
SKYTMBLR 1
|
||||
sub_protocol==RLINK
|
||||
RLINK_SURFACE 0
|
||||
RLINK_AIR 1
|
||||
RLINK_DUMBORC 2
|
||||
|
||||
Power value => 0x80 0=High/1=Low
|
||||
Stream[3] = option_protocol;
|
||||
@@ -1032,6 +1083,7 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
||||
FrSkyX and FrSkyX2: Stream[27] during bind Telem on=0x00,off=0x01 | CH1-8=0x00,CH9-16=0x02
|
||||
FrSkyX and FrSkyX2: Stream[27..34] during normal operation unstuffed SPort data to be sent
|
||||
HoTT: Stream[27] 1 byte for telemetry type
|
||||
DSM: Stream[27..33] Forward Programming
|
||||
*/
|
||||
/*
|
||||
Multimodule Status
|
||||
|
||||
@@ -75,7 +75,7 @@ uint32_t blink=0,last_signal=0;
|
||||
//
|
||||
uint16_t counter;
|
||||
uint8_t channel;
|
||||
#ifdef ESKY150V2_CC2500_INO
|
||||
#if defined(ESKY150V2_CC2500_INO)
|
||||
uint8_t packet[150];
|
||||
#else
|
||||
uint8_t packet[50];
|
||||
@@ -101,8 +101,8 @@ uint16_t packet_period;
|
||||
uint8_t packet_count;
|
||||
uint8_t packet_sent;
|
||||
uint8_t packet_length;
|
||||
#if defined(HOTT_CC2500_INO) || defined(ESKY150V2_CC2500_INO)
|
||||
uint8_t hopping_frequency[75];
|
||||
#if defined(HOTT_CC2500_INO) || defined(ESKY150V2_CC2500_INO) || defined(MLINK_CYRF6936_INO)
|
||||
uint8_t hopping_frequency[78];
|
||||
#else
|
||||
uint8_t hopping_frequency[50];
|
||||
#endif
|
||||
@@ -112,7 +112,9 @@ uint8_t rf_ch_num;
|
||||
uint8_t throttle, rudder, elevator, aileron;
|
||||
uint8_t flags;
|
||||
uint16_t crc;
|
||||
uint16_t crc16_polynomial;
|
||||
uint8_t crc8;
|
||||
uint8_t crc8_polynomial;
|
||||
uint16_t seed;
|
||||
uint16_t failsafe_count;
|
||||
uint16_t state;
|
||||
@@ -232,6 +234,11 @@ uint8_t packet_in[TELEMETRY_BUFFER_SIZE];//telemetry receiving packets
|
||||
uint8_t SportHead=0, SportTail=0;
|
||||
#endif
|
||||
|
||||
// Functions definition when required
|
||||
#ifdef HUB_TELEMETRY
|
||||
static void __attribute__((unused)) frsky_send_user_frame(uint8_t, uint8_t, uint8_t);
|
||||
#endif
|
||||
|
||||
//RX protocols
|
||||
#if defined(AFHDS2A_RX_A7105_INO) || defined(FRSKY_RX_CC2500_INO) || defined(BAYANG_RX_NRF24L01_INO) || defined(DSM_RX_CYRF6936_INO)
|
||||
bool rx_data_started;
|
||||
@@ -256,6 +263,10 @@ uint8_t packet_in[TELEMETRY_BUFFER_SIZE];//telemetry receiving packets
|
||||
uint8_t HoTT_SerialRX_val=0;
|
||||
bool HoTT_SerialRX=false;
|
||||
#endif
|
||||
#ifdef DSM_FWD_PGM
|
||||
uint8_t DSM_SerialRX_val[7];
|
||||
bool DSM_SerialRX=false;
|
||||
#endif
|
||||
#endif // TELEMETRY
|
||||
|
||||
// Callback
|
||||
@@ -286,7 +297,7 @@ void setup()
|
||||
currMillis = millis();
|
||||
}
|
||||
|
||||
delay(50); // Brief delay for FTDI debugging
|
||||
delay(250); // Brief delay for FTDI debugging
|
||||
debugln("Multiprotocol version: %d.%d.%d.%d", VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION, VERSION_PATCH_LEVEL);
|
||||
#endif
|
||||
|
||||
@@ -311,6 +322,7 @@ void setup()
|
||||
#elif defined STM32_BOARD
|
||||
//STM32
|
||||
afio_cfg_debug_ports(AFIO_DEBUG_NONE);
|
||||
pinMode(LED_pin,OUTPUT);
|
||||
pinMode(LED2_pin,OUTPUT);
|
||||
pinMode(A7105_CSN_pin,OUTPUT);
|
||||
pinMode(CC25_CSN_pin,OUTPUT);
|
||||
@@ -364,6 +376,49 @@ void setup()
|
||||
|
||||
//Timers
|
||||
init_HWTimer(); //0.5us
|
||||
|
||||
//Read module flash size
|
||||
#ifndef DISABLE_FLASH_SIZE_CHECK
|
||||
unsigned short *flashSize = (unsigned short *) (0x1FFFF7E0);// Address register
|
||||
debugln("Module Flash size: %dKB",(int)(*flashSize & 0xffff));
|
||||
if((int)(*flashSize & 0xffff) < MCU_EXPECTED_FLASH_SIZE) // Not supported by this project
|
||||
while (true) { //SOS
|
||||
for(uint8_t i=0; i<3;i++)
|
||||
{
|
||||
LED_on;
|
||||
delay(100);
|
||||
LED_off;
|
||||
delay(100);
|
||||
}
|
||||
for(uint8_t i=0; i<3;i++)
|
||||
{
|
||||
LED_on;
|
||||
delay(500);
|
||||
LED_off;
|
||||
delay(100);
|
||||
}
|
||||
for(uint8_t i=0; i<3;i++)
|
||||
{
|
||||
LED_on;
|
||||
delay(100);
|
||||
LED_off;
|
||||
delay(100);
|
||||
}
|
||||
LED_off;
|
||||
delay(1000);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Initialize the EEPROM
|
||||
uint16_t eepromStatus = EEPROM.init();
|
||||
debugln("EEPROM initialized: %d",eepromStatus);
|
||||
|
||||
// If there was no valid EEPROM page the EEPROM is corrupt or uninitialized and should be formatted
|
||||
if( eepromStatus == EEPROM_NO_VALID_PAGE )
|
||||
{
|
||||
EEPROM.format();
|
||||
debugln("No valid EEPROM page, EEPROM formatted");
|
||||
}
|
||||
#else
|
||||
//ATMEGA328p
|
||||
// all inputs
|
||||
@@ -502,7 +557,7 @@ void setup()
|
||||
MProtocol_id_master=random_id(EEPROM_ID_OFFSET,false);
|
||||
|
||||
debugln("Module Id: %lx", MProtocol_id_master);
|
||||
|
||||
|
||||
#ifdef ENABLE_PPM
|
||||
//Protocol and interrupts initialization
|
||||
if(mode_select != MODE_SERIAL)
|
||||
@@ -540,9 +595,9 @@ void setup()
|
||||
option = FORCE_FRSKYX_TUNING; // Use config-defined tuning value for FrSkyX
|
||||
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
|
||||
#if defined(FORCE_FUTABA_TUNING) && defined(FUTABA_CC2500_INO)
|
||||
if (protocol==PROTO_FUTABA)
|
||||
option = FORCE_FUTABA_TUNING; // Use config-defined tuning value for SFHSS
|
||||
else
|
||||
#endif
|
||||
#if defined(FORCE_CORONA_TUNING) && defined(CORONA_CC2500_INO)
|
||||
@@ -698,6 +753,18 @@ void loop()
|
||||
}
|
||||
}
|
||||
|
||||
void End_Bind()
|
||||
{
|
||||
//Request protocol to terminate bind
|
||||
if(protocol==PROTO_FRSKYD || protocol==PROTO_FRSKYL || protocol==PROTO_FRSKYX || protocol==PROTO_FRSKYX2 || protocol==PROTO_FRSKYV || protocol==PROTO_FRSKY_R9
|
||||
|| protocol==PROTO_DSM_RX || protocol==PROTO_AFHDS2A_RX || protocol==PROTO_FRSKY_RX || protocol==PROTO_BAYANG_RX
|
||||
|| protocol==PROTO_AFHDS2A || protocol==PROTO_BUGS || protocol==PROTO_BUGSMINI || protocol==PROTO_HOTT || protocol==PROTO_ASSAN)
|
||||
BIND_DONE;
|
||||
else
|
||||
if(bind_counter>2)
|
||||
bind_counter=2;
|
||||
}
|
||||
|
||||
bool Update_All()
|
||||
{
|
||||
#ifdef ENABLE_SERIAL
|
||||
@@ -773,7 +840,7 @@ bool Update_All()
|
||||
update_led_status();
|
||||
#if defined(TELEMETRY)
|
||||
#if ( !( defined(MULTI_TELEMETRY) || defined(MULTI_STATUS) ) )
|
||||
if((protocol == PROTO_BAYANG_RX) || (protocol == PROTO_AFHDS2A_RX) || (protocol == PROTO_FRSKY_RX) || (protocol == PROTO_SCANNER) || (protocol==PROTO_FRSKYD) || (protocol==PROTO_BAYANG) || (protocol==PROTO_NCC1701) || (protocol==PROTO_BUGS) || (protocol==PROTO_BUGSMINI) || (protocol==PROTO_HUBSAN) || (protocol==PROTO_AFHDS2A) || (protocol==PROTO_FRSKYX) || (protocol==PROTO_FRSKYX2) || (protocol==PROTO_DSM) || (protocol==PROTO_CABELL) || (protocol==PROTO_HITEC) || (protocol==PROTO_HOTT) || (protocol==PROTO_PROPEL) || (protocol==PROTO_DEVO) || (protocol==PROTO_DSM_RX) || (protocol==PROTO_FRSKY_R9) || (protocol==PROTO_RLINK))
|
||||
if((protocol == PROTO_BAYANG_RX) || (protocol == PROTO_AFHDS2A_RX) || (protocol == PROTO_FRSKY_RX) || (protocol == PROTO_SCANNER) || (protocol==PROTO_FRSKYD) || (protocol==PROTO_BAYANG) || (protocol==PROTO_NCC1701) || (protocol==PROTO_BUGS) || (protocol==PROTO_BUGSMINI) || (protocol==PROTO_HUBSAN) || (protocol==PROTO_AFHDS2A) || (protocol==PROTO_FRSKYX) || (protocol==PROTO_FRSKYX2) || (protocol==PROTO_DSM) || (protocol==PROTO_CABELL) || (protocol==PROTO_HITEC) || (protocol==PROTO_HOTT) || (protocol==PROTO_PROPEL) || (protocol==PROTO_OMP) || (protocol==PROTO_DEVO) || (protocol==PROTO_DSM_RX) || (protocol==PROTO_FRSKY_R9) || (protocol==PROTO_RLINK) || (protocol==PROTO_WFLY2) || (protocol==PROTO_LOLI))
|
||||
#endif
|
||||
if(IS_DISABLE_TELEM_off)
|
||||
TelemetryUpdate();
|
||||
@@ -788,14 +855,7 @@ bool Update_All()
|
||||
if(IS_AUTOBIND_FLAG_on && IS_BIND_CH_PREV_on && Channel_data[BIND_CH-1]<CHANNEL_MIN_COMMAND)
|
||||
{ // Autobind is on and BIND_CH went down
|
||||
BIND_CH_PREV_off;
|
||||
//Request protocol to terminate bind
|
||||
#if defined(FRSKYD_CC2500_INO) || defined(FRSKYL_CC2500_INO) || defined(FRSKYX_CC2500_INO) || defined(FRSKYV_CC2500_INO) || defined(AFHDS2A_A7105_INO) || defined(FRSKYR9_SX1276_INO)
|
||||
if(protocol==PROTO_FRSKYD || protocol==PROTO_FRSKYL || protocol==PROTO_FRSKYX || protocol==PROTO_FRSKYX2 || protocol==PROTO_FRSKYV || protocol==PROTO_AFHDS2A || protocol==PROTO_FRSKY_R9)
|
||||
BIND_DONE;
|
||||
else
|
||||
#endif
|
||||
if(bind_counter>2)
|
||||
bind_counter=2;
|
||||
End_Bind();
|
||||
}
|
||||
#endif //ENABLE_BIND_CH
|
||||
if(IS_CHANGE_PROTOCOL_FLAG_on)
|
||||
@@ -1037,6 +1097,9 @@ static void protocol_init()
|
||||
next_callback=0; // Default is immediate call back
|
||||
LED_off; // Led off during protocol init
|
||||
modules_reset(); // Reset all modules
|
||||
crc16_polynomial = 0x1021; // Default CRC crc16_polynomial
|
||||
crc8_polynomial = 0x31; // Default CRC crc8_polynomial
|
||||
prev_option = option;
|
||||
|
||||
// reset telemetry
|
||||
#ifdef TELEMETRY
|
||||
@@ -1148,6 +1211,13 @@ static void protocol_init()
|
||||
remote_callback = ReadKyosho;
|
||||
break;
|
||||
#endif
|
||||
#if defined(WFLY2_A7105_INO)
|
||||
case PROTO_WFLY2:
|
||||
PE1_off; //antenna RF1
|
||||
next_callback = initWFLY2();
|
||||
remote_callback = ReadWFLY2;
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
#ifdef CC2500_INSTALLED
|
||||
#if defined(FRSKYD_CC2500_INO)
|
||||
@@ -1187,8 +1257,8 @@ static void protocol_init()
|
||||
remote_callback = ReadFrSkyX;
|
||||
break;
|
||||
#endif
|
||||
#if defined(SFHSS_CC2500_INO)
|
||||
case PROTO_SFHSS:
|
||||
#if defined(FUTABA_CC2500_INO)
|
||||
case PROTO_FUTABA:
|
||||
PE1_off; //antenna RF2
|
||||
PE2_on;
|
||||
next_callback = initSFHSS();
|
||||
@@ -1267,6 +1337,14 @@ static void protocol_init()
|
||||
remote_callback = RLINK_callback;
|
||||
break;
|
||||
#endif
|
||||
#if defined(E016HV2_CC2500_INO)
|
||||
case PROTO_E016HV2:
|
||||
PE1_off;
|
||||
PE2_on; //antenna RF2
|
||||
next_callback = initE016HV2();
|
||||
remote_callback = E016HV2_callback;
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
#ifdef CYRF6936_INSTALLED
|
||||
#if defined(DSM_CYRF6936_INO)
|
||||
@@ -1290,6 +1368,27 @@ static void protocol_init()
|
||||
remote_callback = ReadWFLY;
|
||||
break;
|
||||
#endif
|
||||
#if defined(MLINK_CYRF6936_INO)
|
||||
case PROTO_MLINK:
|
||||
PE2_on; //antenna RF4
|
||||
next_callback = initMLINK();
|
||||
remote_callback = ReadMLINK;
|
||||
break;
|
||||
#endif
|
||||
#if defined(E010R5_CYRF6936_INO)
|
||||
case PROTO_E010R5:
|
||||
PE2_on; //antenna RF4
|
||||
next_callback = initE010R5();
|
||||
remote_callback = ReadE010R5;
|
||||
break;
|
||||
#endif
|
||||
#if defined(E129_CYRF6936_INO)
|
||||
case PROTO_E129:
|
||||
PE2_on; //antenna RF4
|
||||
next_callback = initE129();
|
||||
remote_callback = ReadE129;
|
||||
break;
|
||||
#endif
|
||||
#if defined(DEVO_CYRF6936_INO)
|
||||
case PROTO_DEVO:
|
||||
#ifdef ENABLE_PPM
|
||||
@@ -1418,6 +1517,12 @@ static void protocol_init()
|
||||
remote_callback = MT99XX_callback;
|
||||
break;
|
||||
#endif
|
||||
#if defined(LOLI_NRF24L01_INO)
|
||||
case PROTO_LOLI:
|
||||
next_callback=initLOLI();
|
||||
remote_callback = LOLI_callback;
|
||||
break;
|
||||
#endif
|
||||
#if defined(MJXQ_NRF24L01_INO)
|
||||
case PROTO_MJXQ:
|
||||
next_callback=initMJXQ();
|
||||
@@ -1604,7 +1709,7 @@ static void protocol_init()
|
||||
remote_callback = REALACC_callback;
|
||||
break;
|
||||
#endif
|
||||
#if defined(OMP_NRF24L01_INO)
|
||||
#if defined(OMP_CC2500_INO)
|
||||
case PROTO_OMP:
|
||||
next_callback=initOMP();
|
||||
remote_callback = OMP_callback;
|
||||
@@ -1616,10 +1721,10 @@ static void protocol_init()
|
||||
remote_callback = TEST_callback;
|
||||
break;
|
||||
#endif
|
||||
#if defined(FAKE_NRF24L01_INO)
|
||||
case PROTO_FAKE:
|
||||
next_callback=initFAKE();
|
||||
remote_callback = FAKE_callback;
|
||||
#if defined(NANORF_NRF24L01_INO)
|
||||
case PROTO_NANORF:
|
||||
next_callback=initNANORF();
|
||||
remote_callback = NANORF_callback;
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
@@ -1748,9 +1853,9 @@ void update_serial_data()
|
||||
option=FORCE_FRSKYX_TUNING; // Use config-defined tuning value for FrSkyX
|
||||
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
|
||||
#if defined(FORCE_FUTABA_TUNING) && defined(FUTABA_CC2500_INO)
|
||||
if (protocol==PROTO_FUTABA)
|
||||
option=FORCE_FUTABA_TUNING; // Use config-defined tuning value for SFHSS
|
||||
else
|
||||
#endif
|
||||
#if defined(FORCE_CORONA_TUNING) && defined(CORONA_CC2500_INO)
|
||||
@@ -1860,13 +1965,7 @@ 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(FRSKYL_CC2500_INO) || defined(FRSKYX_CC2500_INO) || defined(FRSKYV_CC2500_INO) || defined(AFHDS2A_A7105_INO) || defined(FRSKYR9_SX1276_INO) || defined(DSM_RX_CYRF6936_INO)
|
||||
if(protocol==PROTO_FRSKYD || protocol==PROTO_FRSKYL || protocol==PROTO_FRSKYX || protocol==PROTO_FRSKYX2 || protocol==PROTO_FRSKYV || protocol==PROTO_AFHDS2A || protocol==PROTO_FRSKY_R9 || protocol==PROTO_DSM_RX)
|
||||
BIND_DONE;
|
||||
else
|
||||
#endif
|
||||
if(bind_counter>2)
|
||||
bind_counter=2;
|
||||
End_Bind();
|
||||
}
|
||||
|
||||
//store current protocol values
|
||||
@@ -1927,7 +2026,7 @@ void update_serial_data()
|
||||
}
|
||||
#endif
|
||||
#ifdef SPORT_SEND
|
||||
if((protocol==PROTO_FRSKYX || protocol==PROTO_FRSKYX2 || protocol==PROTO_FRSKY_R9) && rx_len==35)
|
||||
if((protocol==PROTO_FRSKYX || protocol==PROTO_FRSKYX2 || protocol==PROTO_FRSKY_R9) && rx_len==27+8)
|
||||
{//Protocol waiting for 8 bytes
|
||||
#define BYTE_STUFF 0x7D
|
||||
#define STUFF_MASK 0x20
|
||||
@@ -1971,12 +2070,19 @@ void update_serial_data()
|
||||
}
|
||||
#endif //SPORT_SEND
|
||||
#ifdef HOTT_FW_TELEMETRY
|
||||
if(protocol==PROTO_HOTT && rx_len==28)
|
||||
if(protocol==PROTO_HOTT && rx_len==27+1)
|
||||
{//Protocol waiting for 1 byte
|
||||
HoTT_SerialRX_val=rx_ok_buff[27];
|
||||
HoTT_SerialRX=true;
|
||||
}
|
||||
#endif
|
||||
#ifdef DSM_FWD_PGM
|
||||
if(protocol==PROTO_DSM && rx_len==27+7)
|
||||
{//Protocol waiting for 7 bytes
|
||||
memcpy(DSM_SerialRX_val, (const void *)&rx_ok_buff[27],7);
|
||||
DSM_SerialRX=true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
RX_DONOTUPDATE_off;
|
||||
@@ -2221,7 +2327,7 @@ void pollBoot()
|
||||
#if defined(TELEMETRY)
|
||||
void PPM_Telemetry_serial_init()
|
||||
{
|
||||
if( (protocol==PROTO_FRSKYD) || (protocol==PROTO_HUBSAN) || (protocol==PROTO_AFHDS2A) || (protocol==PROTO_BAYANG)|| (protocol==PROTO_NCC1701) || (protocol==PROTO_CABELL) || (protocol==PROTO_HITEC) || (protocol==PROTO_BUGS) || (protocol==PROTO_BUGSMINI) || (protocol==PROTO_PROPEL) || (protocol==PROTO_RLINK)
|
||||
if( (protocol==PROTO_FRSKYD) || (protocol==PROTO_HUBSAN) || (protocol==PROTO_AFHDS2A) || (protocol==PROTO_BAYANG)|| (protocol==PROTO_NCC1701) || (protocol==PROTO_CABELL) || (protocol==PROTO_HITEC) || (protocol==PROTO_BUGS) || (protocol==PROTO_BUGSMINI) || (protocol==PROTO_PROPEL) || (protocol==PROTO_OMP) || (protocol==PROTO_RLINK) || (protocol==PROTO_WFLY2) || (protocol==PROTO_LOLI)
|
||||
#ifdef TELEMETRY_FRSKYX_TO_FRSKYD
|
||||
|| (protocol==PROTO_FRSKYX) || (protocol==PROTO_FRSKYX2)
|
||||
#endif
|
||||
@@ -2332,6 +2438,37 @@ static void __attribute__((unused)) calc_fh_channels(uint8_t num_ch)
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t __attribute__((unused)) bit_reverse(uint8_t b_in)
|
||||
{
|
||||
uint8_t b_out = 0;
|
||||
for (uint8_t i = 0; i < 8; ++i)
|
||||
{
|
||||
b_out = (b_out << 1) | (b_in & 1);
|
||||
b_in >>= 1;
|
||||
}
|
||||
return b_out;
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) crc16_update(uint8_t a, uint8_t bits)
|
||||
{
|
||||
crc ^= a << 8;
|
||||
while(bits--)
|
||||
if (crc & 0x8000)
|
||||
crc = (crc << 1) ^ crc16_polynomial;
|
||||
else
|
||||
crc = crc << 1;
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) crc8_update(uint8_t byte)
|
||||
{
|
||||
crc8 = crc8 ^ byte;
|
||||
for ( uint8_t j = 0; j < 8; j++ )
|
||||
if ( crc8 & 0x80 )
|
||||
crc8 = (crc8<<1) ^ crc8_polynomial;
|
||||
else
|
||||
crc8 <<= 1;
|
||||
}
|
||||
|
||||
/**************************/
|
||||
/**************************/
|
||||
/** Interrupt routines **/
|
||||
@@ -2484,7 +2621,7 @@ static void __attribute__((unused)) calc_fh_channels(uint8_t num_ch)
|
||||
ISR(TIMER1_COMPB_vect)
|
||||
#endif
|
||||
{ // Timer1 compare B interrupt
|
||||
if(rx_idx>=26 && rx_idx<RXBUFFER_SIZE)
|
||||
if(rx_idx>=26 && rx_idx<=RXBUFFER_SIZE)
|
||||
{
|
||||
// A full frame has been received
|
||||
if(!IS_RX_DONOTUPDATE_on)
|
||||
@@ -2503,7 +2640,7 @@ static void __attribute__((unused)) calc_fh_channels(uint8_t num_ch)
|
||||
}
|
||||
#ifdef DEBUG_SERIAL
|
||||
else
|
||||
debugln("RX frame too short");
|
||||
debugln("RX frame size incorrect");
|
||||
#endif
|
||||
discard_frame=true;
|
||||
#ifdef STM32_BOARD
|
||||
|
||||
@@ -58,11 +58,11 @@ static void __attribute__((unused)) NCC_init()
|
||||
const uint8_t NCC_xor[]={0x80, 0x44, 0x64, 0x75, 0x6C, 0x71, 0x2A, 0x36, 0x7C, 0xF1, 0x6E, 0x52, 0x09, 0x9D};
|
||||
static void __attribute__((unused)) NCC_Crypt_Packet()
|
||||
{
|
||||
uint16_t crc=0;
|
||||
crc=0;
|
||||
for(uint8_t i=0; i< NCC_TX_PACKET_LEN-2; i++)
|
||||
{
|
||||
packet[i]^=NCC_xor[i];
|
||||
crc=crc16_update(crc, packet[i], 8);
|
||||
crc16_update(packet[i], 8);
|
||||
}
|
||||
crc^=0x60DE;
|
||||
packet[NCC_TX_PACKET_LEN-2]=crc>>8;
|
||||
@@ -70,11 +70,11 @@ static void __attribute__((unused)) NCC_Crypt_Packet()
|
||||
}
|
||||
static boolean __attribute__((unused)) NCC_Decrypt_Packet()
|
||||
{
|
||||
uint16_t crc=0;
|
||||
crc=0;
|
||||
debug("RX: ");
|
||||
for(uint8_t i=0; i< NCC_RX_PACKET_LEN-2; i++)
|
||||
{
|
||||
crc=crc16_update(crc, packet[i], 8);
|
||||
crc16_update( packet[i], 8);
|
||||
packet[i]^=NCC_xor[i];
|
||||
debug("%02X ",packet[i]);
|
||||
}
|
||||
|
||||
@@ -300,29 +300,6 @@ const uint16_t xn297_crc_xorout_enhanced[] = {
|
||||
0xABFC, 0xE68E, 0x0DE7, 0x28A2, 0x1965 };
|
||||
#endif
|
||||
|
||||
static uint8_t bit_reverse(uint8_t b_in)
|
||||
{
|
||||
uint8_t b_out = 0;
|
||||
for (uint8_t i = 0; i < 8; ++i)
|
||||
{
|
||||
b_out = (b_out << 1) | (b_in & 1);
|
||||
b_in >>= 1;
|
||||
}
|
||||
return b_out;
|
||||
}
|
||||
|
||||
static const uint16_t polynomial = 0x1021;
|
||||
static uint16_t crc16_update(uint16_t crc, uint8_t a, uint8_t bits)
|
||||
{
|
||||
crc ^= a << 8;
|
||||
while(bits--)
|
||||
if (crc & 0x8000)
|
||||
crc = (crc << 1) ^ polynomial;
|
||||
else
|
||||
crc = crc << 1;
|
||||
return crc;
|
||||
}
|
||||
|
||||
void XN297_SetTXAddr(const uint8_t* addr, uint8_t len)
|
||||
{
|
||||
if (len > 5) len = 5;
|
||||
@@ -401,9 +378,9 @@ void XN297_WritePayload(uint8_t* msg, uint8_t len)
|
||||
if (xn297_crc)
|
||||
{
|
||||
uint8_t offset = xn297_addr_len < 4 ? 1 : 0;
|
||||
uint16_t crc = 0xb5d2;
|
||||
crc = 0xb5d2;
|
||||
for (uint8_t i = offset; i < last; ++i)
|
||||
crc = crc16_update(crc, buf[i], 8);
|
||||
crc16_update( buf[i], 8);
|
||||
if(xn297_scramble_enabled)
|
||||
crc ^= pgm_read_word(&xn297_crc_xorout_scrambled[xn297_addr_len - 3 + len]);
|
||||
else
|
||||
@@ -466,10 +443,10 @@ void XN297_WriteEnhancedPayload(uint8_t* msg, uint8_t len, uint8_t noack)
|
||||
if (xn297_crc)
|
||||
{
|
||||
uint8_t offset = xn297_addr_len < 4 ? 1 : 0;
|
||||
uint16_t crc = 0xb5d2;
|
||||
crc = 0xb5d2;
|
||||
for (uint8_t i = offset; i < last; ++i)
|
||||
crc = crc16_update(crc, packet[i], 8);
|
||||
crc = crc16_update(crc, packet[last] & 0xc0, 2);
|
||||
crc16_update( packet[i], 8);
|
||||
crc16_update( packet[last] & 0xc0, 2);
|
||||
if (xn297_scramble_enabled)
|
||||
crc ^= pgm_read_word(&xn297_crc_xorout_scrambled_enhanced[xn297_addr_len-3+len]);
|
||||
//else
|
||||
@@ -505,18 +482,18 @@ boolean XN297_ReadPayload(uint8_t* msg, uint8_t len)
|
||||
return true; // No CRC so OK by default...
|
||||
|
||||
// Calculate CRC
|
||||
uint16_t crc = 0xb5d2;
|
||||
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);
|
||||
crc16_update( b_in, 8);
|
||||
}
|
||||
//process payload
|
||||
for (uint8_t i = 0; i < len; ++i)
|
||||
crc = crc16_update(crc, buf[i], 8);
|
||||
crc16_update( buf[i], 8);
|
||||
//xorout
|
||||
if(xn297_scramble_enabled)
|
||||
crc ^= pgm_read_word(&xn297_crc_xorout_scrambled[xn297_addr_len - 3 + len]);
|
||||
@@ -529,7 +506,7 @@ 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 !!!
|
||||
{ //!!! Don't forget do a +2 and if using CRC add +4 on any of the used NRF24L01_11_RX_PW_Px !!!
|
||||
uint8_t buffer[32];
|
||||
uint8_t pcf_size; // pcf payload size
|
||||
if (xn297_crc)
|
||||
@@ -552,19 +529,19 @@ uint8_t XN297_ReadEnhancedPayload(uint8_t* msg, uint8_t len)
|
||||
return pcf_size; // No CRC so OK by default...
|
||||
|
||||
// Calculate CRC
|
||||
uint16_t crc = 0xb5d2;
|
||||
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);
|
||||
crc16_update( 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);
|
||||
crc16_update( buffer[i], 8);
|
||||
crc16_update( buffer[len+1] & 0xc0, 2);
|
||||
//xorout
|
||||
if (xn297_scramble_enabled)
|
||||
crc ^= pgm_read_word(&xn297_crc_xorout_scrambled_enhanced[xn297_addr_len-3+len]);
|
||||
@@ -606,9 +583,10 @@ void HS6200_SetTXAddr(const uint8_t* addr, uint8_t len)
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, (uint8_t*)"\xaa\xaa\xaa\xaa\xaa", 5);
|
||||
|
||||
// precompute address crc
|
||||
hs6200_crc_init = 0xffff;
|
||||
crc = 0xffff;
|
||||
for(int i=0; i<len; i++)
|
||||
hs6200_crc_init = crc16_update(hs6200_crc_init, addr[len-1-i], 8);
|
||||
crc16_update(addr[len-1-i], 8);
|
||||
hs6200_crc_init=crc;
|
||||
memcpy(hs6200_tx_addr, addr, len);
|
||||
hs6200_address_length = len;
|
||||
}
|
||||
@@ -616,14 +594,14 @@ void HS6200_SetTXAddr(const uint8_t* addr, uint8_t len)
|
||||
static uint16_t hs6200_calc_crc(uint8_t* msg, uint8_t len)
|
||||
{
|
||||
uint8_t pos;
|
||||
uint16_t crc = hs6200_crc_init;
|
||||
|
||||
crc = hs6200_crc_init;
|
||||
// pcf + payload
|
||||
for(pos=0; pos < len-1; pos++)
|
||||
crc = crc16_update(crc, msg[pos], 8);
|
||||
crc16_update(msg[pos], 8);
|
||||
// last byte (1 bit only)
|
||||
if(len > 0)
|
||||
crc = crc16_update(crc, msg[pos+1], 1);
|
||||
crc16_update(msg[pos+1], 1);
|
||||
return crc;
|
||||
}
|
||||
|
||||
@@ -797,7 +775,8 @@ void LT8900_SetAddress(uint8_t *address,uint8_t addr_size)
|
||||
uint8_t LT8900_ReadPayload(uint8_t* msg, uint8_t len)
|
||||
{
|
||||
uint8_t i,pos=0,shift,end,buffer[32];
|
||||
unsigned int crc=LT8900_CRC_Initial_Data,a;
|
||||
unsigned int a;
|
||||
crc=LT8900_CRC_Initial_Data;
|
||||
pos=LT8900_buffer_overhead_bits/8-LT8900_buffer_start;
|
||||
end=pos+len+(LT8900_Flags&_BV(LT8900_PACKET_LENGTH_EN)?1:0)+(LT8900_Flags&_BV(LT8900_CRC_ON)?2:0);
|
||||
//Read payload
|
||||
@@ -817,14 +796,14 @@ uint8_t LT8900_ReadPayload(uint8_t* msg, uint8_t len)
|
||||
//Check len
|
||||
if(LT8900_Flags&_BV(LT8900_PACKET_LENGTH_EN))
|
||||
{
|
||||
crc=crc16_update(crc,buffer[pos],8);
|
||||
crc16_update(buffer[pos],8);
|
||||
if(bit_reverse(len)!=buffer[pos++])
|
||||
return 0; // wrong len...
|
||||
}
|
||||
//Decode message
|
||||
for(i=0;i<len;i++)
|
||||
{
|
||||
crc=crc16_update(crc,buffer[pos],8);
|
||||
crc16_update(buffer[pos],8);
|
||||
msg[i]=bit_reverse(buffer[pos++]);
|
||||
}
|
||||
//Check CRC
|
||||
@@ -839,21 +818,22 @@ uint8_t LT8900_ReadPayload(uint8_t* msg, uint8_t len)
|
||||
|
||||
void LT8900_WritePayload(uint8_t* msg, uint8_t len)
|
||||
{
|
||||
unsigned int crc=LT8900_CRC_Initial_Data,a,mask;
|
||||
unsigned int a,mask;
|
||||
uint8_t i, pos=0,tmp, buffer[64], pos_final,shift;
|
||||
crc=LT8900_CRC_Initial_Data;
|
||||
//Add packet len
|
||||
if(LT8900_Flags&_BV(LT8900_PACKET_LENGTH_EN))
|
||||
{
|
||||
tmp=bit_reverse(len);
|
||||
buffer[pos++]=tmp;
|
||||
crc=crc16_update(crc,tmp,8);
|
||||
crc16_update(tmp,8);
|
||||
}
|
||||
//Add payload
|
||||
for(i=0;i<len;i++)
|
||||
{
|
||||
tmp=bit_reverse(msg[i]);
|
||||
buffer[pos++]=tmp;
|
||||
crc=crc16_update(crc,tmp,8);
|
||||
crc16_update(tmp,8);
|
||||
}
|
||||
//Add CRC
|
||||
if(LT8900_Flags&_BV(LT8900_CRC_ON))
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
static void __attribute__((unused)) XN297L_Init()
|
||||
{
|
||||
prev_option = option;
|
||||
#ifdef CC2500_INSTALLED
|
||||
if(option==0)
|
||||
#endif
|
||||
@@ -38,56 +39,10 @@ static void __attribute__((unused)) XN297L_Init()
|
||||
//CC2500
|
||||
#ifdef CC2500_INSTALLED
|
||||
debugln("Using CC2500");
|
||||
xn297_scramble_enabled=XN297_SCRAMBLED; //enabled by default
|
||||
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
|
||||
CC2500_250K_Init();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -126,7 +81,6 @@ static void __attribute__((unused)) XN297L_WritePayload(uint8_t* msg, uint8_t le
|
||||
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)
|
||||
@@ -147,9 +101,9 @@ static void __attribute__((unused)) XN297L_WritePayload(uint8_t* msg, uint8_t le
|
||||
}
|
||||
|
||||
// crc
|
||||
uint16_t crc = initial;
|
||||
crc = 0xb5d2;
|
||||
for (uint8_t i = 0; i < last; ++i)
|
||||
crc = crc16_update(crc, buf[i], 8);
|
||||
crc16_update( buf[i], 8);
|
||||
if(xn297_scramble_enabled)
|
||||
crc ^= pgm_read_word(&xn297_crc_xorout_scrambled[xn297_addr_len - 3 + len]);
|
||||
else
|
||||
@@ -228,10 +182,10 @@ static void __attribute__((unused)) XN297L_WriteEnhancedPayload(uint8_t* msg, ui
|
||||
// crc
|
||||
//if (xn297_crc)
|
||||
{
|
||||
uint16_t crc = 0xb5d2;
|
||||
crc = 0xb5d2;
|
||||
for (uint8_t i = 0; i < last; ++i)
|
||||
crc = crc16_update(crc, buf[i], 8);
|
||||
crc = crc16_update(crc, buf[last] & 0xc0, 2);
|
||||
crc16_update( buf[i], 8);
|
||||
crc16_update( buf[last] & 0xc0, 2);
|
||||
if (xn297_scramble_enabled)
|
||||
crc ^= pgm_read_word(&xn297_crc_xorout_scrambled_enhanced[xn297_addr_len-3+len]);
|
||||
//else
|
||||
@@ -267,14 +221,7 @@ static void __attribute__((unused)) XN297L_HoppingCalib(uint8_t num_freq)
|
||||
#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);
|
||||
}
|
||||
CC2500_250K_HoppingCalib(num_freq);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -288,10 +235,7 @@ static void __attribute__((unused)) XN297L_Hopping(uint8_t 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]);
|
||||
CC2500_250K_Hopping(index);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -305,10 +249,7 @@ static void __attribute__((unused)) XN297L_RFChannel(uint8_t number)
|
||||
return;
|
||||
}
|
||||
#ifdef CC2500_INSTALLED
|
||||
CC2500_Strobe(CC2500_SIDLE);
|
||||
CC2500_WriteReg(CC2500_0A_CHANNR, number*3);
|
||||
CC2500_Strobe(CC2500_SCAL);
|
||||
delayMicroseconds(900);
|
||||
CC2500_250K_RFChannel(number);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -336,9 +277,8 @@ static void __attribute__((unused)) XN297L_SetFreqOffset()
|
||||
if (prev_option != option)
|
||||
{
|
||||
if(prev_option==0 || option==0)
|
||||
CHANGE_PROTOCOL_FLAG_on;
|
||||
prev_option = option;
|
||||
CC2500_WriteReg(CC2500_0C_FSCTRL0, option);
|
||||
CHANGE_PROTOCOL_FLAG_on; // switch from NRF <-> CC2500
|
||||
CC2500_SetFreqOffset();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -357,8 +297,7 @@ static void __attribute__((unused)) NRF250K_SetTXAddr(uint8_t* addr, uint8_t len
|
||||
}
|
||||
//CC2500
|
||||
#ifdef CC2500_INSTALLED
|
||||
xn297_addr_len = len;
|
||||
memcpy(xn297_tx_addr, addr, len);
|
||||
CC2500_250K_NRF_SetTXAddr(addr, len);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -375,78 +314,7 @@ static void __attribute__((unused)) NRF250K_WritePayload(uint8_t* msg, uint8_t l
|
||||
}
|
||||
//CC2500
|
||||
#ifdef CC2500_INSTALLED
|
||||
#if defined(ESKY150V2_CC2500_INO)
|
||||
uint8_t buf[158];
|
||||
#else
|
||||
uint8_t buf[35];
|
||||
#endif
|
||||
uint8_t last = 0;
|
||||
uint8_t i;
|
||||
|
||||
//nrf preamble
|
||||
if(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);
|
||||
// transmit nrf packet
|
||||
uint8_t *buff=buf;
|
||||
uint8_t status;
|
||||
if(last>63)
|
||||
{
|
||||
CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, buff, 63);
|
||||
CC2500_Strobe(CC2500_STX);
|
||||
last-=63;
|
||||
buff+=63;
|
||||
while(last)
|
||||
{//Loop until all the data is sent
|
||||
do
|
||||
{// Wait for the FIFO to become available
|
||||
status=CC2500_ReadReg(CC2500_3A_TXBYTES | CC2500_READ_BURST);
|
||||
}
|
||||
while((status&0x7F)>31 && (status&0x80)==0);
|
||||
if(last>31)
|
||||
{//Send 31 bytes
|
||||
CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, buff, 31);
|
||||
last-=31;
|
||||
buff+=31;
|
||||
}
|
||||
else
|
||||
{//Send last bytes
|
||||
CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, buff, last);
|
||||
last=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{//Send packet
|
||||
CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, buff, last);
|
||||
CC2500_Strobe(CC2500_STX);
|
||||
}
|
||||
CC2500_250K_NRF_WritePayload(msg, len);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
73
Multiprotocol/NanoRF_nrf24l01.ino
Normal file
73
Multiprotocol/NanoRF_nrf24l01.ino
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
This project is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Multiprotocol is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if defined(NANORF_NRF24L01_INO)
|
||||
|
||||
#include "iface_nrf24l01.h"
|
||||
|
||||
#define NANORF_PACKET_PERIOD 40000
|
||||
#define NANORF_INITIAL_WAIT 500
|
||||
#define NANORF_RF_CHANNEL 40
|
||||
#define NANORF_PAYLOADSIZE 7
|
||||
|
||||
static void __attribute__((unused)) NANORF_send_packet()
|
||||
{
|
||||
packet[0] = convert_channel_8b(AILERON);
|
||||
packet[1] = convert_channel_8b(ELEVATOR);
|
||||
packet[2] = convert_channel_8b(THROTTLE);
|
||||
packet[3] = convert_channel_8b(RUDDER);
|
||||
packet[4] = convert_channel_8b(CH5);
|
||||
packet[5] = convert_channel_8b(CH6);
|
||||
packet[6] = 0;
|
||||
for (uint8_t i=0; i < NANORF_PAYLOADSIZE-1; i++)
|
||||
packet[6] += packet[i];
|
||||
packet[6] += 0x55;
|
||||
|
||||
// clear packet status bits and TX FIFO
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||
NRF24L01_FlushTx();
|
||||
NRF24L01_WritePayload(packet, NANORF_PAYLOADSIZE);
|
||||
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) NANORF_init()
|
||||
{
|
||||
NRF24L01_Initialize();
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR , (uint8_t *)"Nano1",5);
|
||||
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknoledgement
|
||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable all data pipes (even though not used?)
|
||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5-byte RX/TX address
|
||||
NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x00); // 4mS retransmit t/o, 15 tries (retries w/o AA?)
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, NANORF_RF_CHANNEL);
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_1M);
|
||||
NRF24L01_SetPower(); // Set tx_power
|
||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP)); //
|
||||
}
|
||||
|
||||
uint16_t NANORF_callback()
|
||||
{
|
||||
NANORF_send_packet();
|
||||
return NANORF_PACKET_PERIOD;
|
||||
}
|
||||
|
||||
uint16_t initNANORF()
|
||||
{
|
||||
BIND_DONE;
|
||||
NANORF_init();
|
||||
return NANORF_INITIAL_WAIT;
|
||||
}
|
||||
|
||||
#endif
|
||||
301
Multiprotocol/OMP_cc2500.ino
Normal file
301
Multiprotocol/OMP_cc2500.ino
Normal file
@@ -0,0 +1,301 @@
|
||||
/*
|
||||
This project is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Multiprotocol is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if defined(OMP_CC2500_INO)
|
||||
|
||||
#include "iface_nrf250k.h"
|
||||
|
||||
//#define FORCE_OMP_ORIGINAL_ID
|
||||
//#define OMP_TELEM_DEBUG
|
||||
|
||||
#define OMP_INITIAL_WAIT 500
|
||||
#define OMP_PACKET_PERIOD 5000
|
||||
#define OMP_RF_BIND_CHANNEL 35
|
||||
#define OMP_RF_NUM_CHANNELS 8
|
||||
#define OMP_PAYLOAD_SIZE 16
|
||||
#define OMP_BIND_COUNT 600 //3sec
|
||||
|
||||
static void __attribute__((unused)) OMP_send_packet()
|
||||
{
|
||||
#ifdef OMP_HUB_TELEMETRY
|
||||
if(option==0)
|
||||
prev_option=option=1; // Select the CC2500 by default
|
||||
PE1_off; PE2_on; // CC2500 antenna RF2
|
||||
#endif
|
||||
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
memcpy(packet,"BND",3);
|
||||
memcpy(&packet[3],rx_tx_addr,5);
|
||||
memcpy(&packet[8],hopping_frequency,8);
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(packet,0x00,OMP_PAYLOAD_SIZE);
|
||||
|
||||
#ifdef OMP_HUB_TELEMETRY
|
||||
//RX telem request every 7*5=35ms
|
||||
packet_sent++;
|
||||
packet_sent %= OMP_RF_NUM_CHANNELS-1; // Change telem RX channels every time
|
||||
if(packet_sent==0)
|
||||
{
|
||||
packet[0] |= 0x40; // |0x40 to request RX telemetry
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no]);
|
||||
}
|
||||
#endif
|
||||
|
||||
//hopping frequency
|
||||
packet[0 ] |= hopping_frequency_no;
|
||||
XN297L_Hopping(hopping_frequency_no);
|
||||
hopping_frequency_no++;
|
||||
hopping_frequency_no &= OMP_RF_NUM_CHANNELS-1; // 8 RF channels
|
||||
|
||||
//flags
|
||||
packet[1 ] = 0x08 //unknown
|
||||
| GET_FLAG(CH5_SW, 0x20); // HOLD
|
||||
|
||||
packet[2 ] = 0x40; //unknown
|
||||
|
||||
if(Channel_data[CH6] > CHANNEL_MAX_COMMAND)
|
||||
packet[2 ] |= 0x20; // IDLE2
|
||||
else if(Channel_data[CH6] > CHANNEL_MIN_COMMAND)
|
||||
packet[1 ] |= 0x40; // IDLE1
|
||||
|
||||
if(Channel_data[CH7] > CHANNEL_MAX_COMMAND)
|
||||
packet[2 ] |= 0x08; // 3D
|
||||
else if(Channel_data[CH7] > CHANNEL_MIN_COMMAND)
|
||||
packet[2 ] |= 0x04; // ATTITUDE
|
||||
|
||||
//trims??
|
||||
//packet[3..6]
|
||||
|
||||
//channels TAER packed 11bits
|
||||
uint16_t channel=convert_channel_16b_limit(THROTTLE,0,2047);
|
||||
packet[7 ] = channel;
|
||||
packet[8 ] = channel>>8;
|
||||
channel=convert_channel_16b_limit(AILERON,2047,0);
|
||||
packet[8 ] |= channel<<3;
|
||||
packet[9 ] = channel>>5;
|
||||
channel=convert_channel_16b_limit(ELEVATOR,0,2047);
|
||||
packet[9] |= channel<<6;
|
||||
packet[10] = channel>>2;
|
||||
packet[11] = channel>>10;
|
||||
channel=convert_channel_16b_limit(RUDDER,2047,0);
|
||||
packet[11] |= channel<<1;
|
||||
packet[12] = channel>>7;
|
||||
|
||||
//unknown
|
||||
//packet[13..15]
|
||||
packet[15] = 0x04;
|
||||
}
|
||||
|
||||
XN297L_SetPower(); // Set tx_power
|
||||
XN297L_SetFreqOffset(); // Set frequency offset
|
||||
XN297L_WriteEnhancedPayload(packet, OMP_PAYLOAD_SIZE, packet_sent!=0);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) OMP_init()
|
||||
{
|
||||
//Config CC2500
|
||||
#ifdef OMP_HUB_TELEMETRY
|
||||
if(option==0)
|
||||
prev_option=option=1; // Select the CC2500
|
||||
#endif
|
||||
XN297L_Init();
|
||||
XN297L_SetTXAddr((uint8_t*)"FLPBD", 5);
|
||||
XN297L_HoppingCalib(OMP_RF_NUM_CHANNELS); // Calibrate all channels
|
||||
XN297L_RFChannel(OMP_RF_BIND_CHANNEL); // Set bind channel
|
||||
|
||||
#ifdef OMP_HUB_TELEMETRY
|
||||
//Config NRF
|
||||
prev_option=option=0; // Select the NRF
|
||||
XN297L_Init();
|
||||
XN297_Configure(_BV(NRF24L01_00_EN_CRC));
|
||||
XN297_SetRXAddr(rx_tx_addr, 5); // Set the RX address
|
||||
NRF24L01_SetTxRxMode(TXRX_OFF); // Turn it off for now
|
||||
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, OMP_PAYLOAD_SIZE + 4); // packet length +4 bytes of PCF+CRC
|
||||
#endif
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) OMP_initialize_txid()
|
||||
{
|
||||
calc_fh_channels(OMP_RF_NUM_CHANNELS);
|
||||
#ifdef FORCE_OMP_ORIGINAL_ID
|
||||
rx_tx_addr[0]=0x4E;
|
||||
rx_tx_addr[1]=0x72;
|
||||
rx_tx_addr[2]=0x8E;
|
||||
rx_tx_addr[3]=0x70;
|
||||
rx_tx_addr[4]=0x62;
|
||||
for(uint8_t i=0; i<OMP_RF_NUM_CHANNELS;i++)
|
||||
hopping_frequency[i]=(i+3)*5;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef OMP_HUB_TELEMETRY
|
||||
static void __attribute__((unused)) OMP_Send_Telemetry(uint8_t v)
|
||||
{
|
||||
v_lipo1=v;
|
||||
telemetry_counter++; //LQI
|
||||
telemetry_link=1;
|
||||
if(telemetry_lost)
|
||||
{
|
||||
telemetry_lost = 0;
|
||||
packet_count = 100;
|
||||
telemetry_counter = 100;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
enum {
|
||||
OMP_BIND = 0x00,
|
||||
OMP_PREPDATA = 0x01,
|
||||
OMP_DATA = 0x02,
|
||||
OMP_RX = 0x03,
|
||||
};
|
||||
|
||||
#define OMP_WRITE_TIME 850
|
||||
|
||||
uint16_t OMP_callback()
|
||||
{
|
||||
switch(phase)
|
||||
{
|
||||
case OMP_BIND:
|
||||
if(--bind_counter==0)
|
||||
phase++; // OMP_PREPDATA
|
||||
OMP_send_packet();
|
||||
return OMP_PACKET_PERIOD;
|
||||
case OMP_PREPDATA:
|
||||
BIND_DONE;
|
||||
XN297L_SetTXAddr(rx_tx_addr, 5);
|
||||
phase++; // OMP_DATA
|
||||
case OMP_DATA:
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(OMP_PACKET_PERIOD);
|
||||
#endif
|
||||
OMP_send_packet();
|
||||
#ifdef OMP_HUB_TELEMETRY
|
||||
if(packet_sent == 0)
|
||||
{
|
||||
phase++; // OMP_RX
|
||||
return OMP_WRITE_TIME;
|
||||
}
|
||||
else if(packet_sent == 1)
|
||||
{
|
||||
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR))
|
||||
{ // a packet has been received
|
||||
if(XN297_ReadEnhancedPayload(packet_in, OMP_PAYLOAD_SIZE) == OMP_PAYLOAD_SIZE)
|
||||
{ // packet with good CRC and length
|
||||
#ifdef OMP_TELEM_DEBUG
|
||||
debug("OK :");
|
||||
for(uint8_t i=0;i<OMP_PAYLOAD_SIZE;i++)
|
||||
debug(" %02X",packet_in[i]);
|
||||
#endif
|
||||
// packet_in = 01 00 98 2C 03 19 19 F0 49 02 00 00 00 00 00 00
|
||||
// all bytes are fixed and unknown except 2 and 3 which represent the battery voltage: packet_in[3]*256+packet_in[2]=lipo voltage*100 in V
|
||||
uint16_t v=((packet_in[3]<<8)+packet_in[2]-400)/50;
|
||||
if(v>255) v=255;
|
||||
v_lipo2=v;
|
||||
OMP_Send_Telemetry(v);
|
||||
}
|
||||
else
|
||||
{ // As soon as the motor spins the telem packets are becoming really bad and the CRC throws most of them in error as it should but...
|
||||
#ifdef OMP_TELEM_DEBUG
|
||||
debug("NOK:");
|
||||
for(uint8_t i=0;i<OMP_PAYLOAD_SIZE;i++)
|
||||
debug(" %02X",packet_in[i]);
|
||||
#endif
|
||||
if(packet_in[0]==0x01 && packet_in[1]==0x00)
|
||||
{// the start of the packet looks ok...
|
||||
uint16_t v=((packet_in[3]<<8)+packet_in[2]-400)/50;
|
||||
if(v<260 && v>180)
|
||||
{ //voltage is less than 13V and more than 9V (3V/element)
|
||||
if(v>255) v=255;
|
||||
uint16_t v1=v-v_lipo2;
|
||||
if(v1&0x8000) v1=-v1;
|
||||
if(v1<20) // the batt voltage is within 1V from a good reading...
|
||||
{
|
||||
OMP_Send_Telemetry(v); // ok to send
|
||||
#ifdef OMP_TELEM_DEBUG
|
||||
debug(" OK");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
telemetry_counter++; //LQI
|
||||
}
|
||||
#ifdef OMP_TELEM_DEBUG
|
||||
debugln("");
|
||||
#endif
|
||||
}
|
||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||
packet_count++;
|
||||
if(packet_count>=100)
|
||||
{//LQI calculation
|
||||
packet_count=0;
|
||||
TX_LQI=telemetry_counter;
|
||||
RX_RSSI=telemetry_counter;
|
||||
if(telemetry_counter==0)
|
||||
telemetry_lost = 1;
|
||||
telemetry_counter = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return OMP_PACKET_PERIOD;
|
||||
#ifdef OMP_HUB_TELEMETRY
|
||||
case OMP_RX:
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, (1 << NRF24L01_07_RX_DR) //reset the flag(s)
|
||||
| (1 << NRF24L01_07_TX_DS)
|
||||
| (1 << NRF24L01_07_MAX_RT));
|
||||
NRF24L01_FlushRx();
|
||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, (1 << NRF24L01_00_PWR_UP) | (1 << NRF24L01_00_PRIM_RX) ); // Start RX
|
||||
{
|
||||
uint16_t start=(uint16_t)micros();
|
||||
while ((uint16_t)((uint16_t)micros()-(uint16_t)start) < 500)
|
||||
{
|
||||
if(CC2500_ReadReg(CC2500_35_MARCSTATE | CC2500_READ_BURST) != 0x13)
|
||||
break;
|
||||
}
|
||||
}
|
||||
NRF_CE_on;
|
||||
PE1_on;PE2_off; // NRF24L01 antenna RF3
|
||||
phase = OMP_DATA;
|
||||
return OMP_PACKET_PERIOD-OMP_WRITE_TIME;
|
||||
#endif
|
||||
}
|
||||
return OMP_PACKET_PERIOD;
|
||||
}
|
||||
|
||||
uint16_t initOMP()
|
||||
{
|
||||
OMP_initialize_txid();
|
||||
OMP_init();
|
||||
hopping_frequency_no = 0;
|
||||
packet_sent = 0;
|
||||
#ifdef OMP_HUB_TELEMETRY
|
||||
packet_count = 0;
|
||||
telemetry_lost = 1;
|
||||
#endif
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
bind_counter = OMP_BIND_COUNT;
|
||||
phase = OMP_BIND;
|
||||
}
|
||||
else
|
||||
phase = OMP_PREPDATA;
|
||||
return OMP_INITIAL_WAIT;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,140 +0,0 @@
|
||||
/*
|
||||
This project is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Multiprotocol is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if defined(OMP_NRF24L01_INO)
|
||||
|
||||
#include "iface_nrf250k.h"
|
||||
|
||||
//#define FORCE_OMP_ORIGINAL_ID
|
||||
|
||||
#define OMP_INITIAL_WAIT 500
|
||||
#define OMP_PACKET_PERIOD 5000
|
||||
#define OMP_RF_BIND_CHANNEL 35
|
||||
#define OMP_RF_NUM_CHANNELS 8
|
||||
#define OMP_PAYLOAD_SIZE 16
|
||||
#define OMP_BIND_COUNT 600 //3sec
|
||||
|
||||
static void __attribute__((unused)) OMP_send_packet()
|
||||
{
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
memcpy(packet,"BND",3);
|
||||
memcpy(&packet[3],rx_tx_addr,5);
|
||||
memcpy(&packet[8],hopping_frequency,8);
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(packet,0x00,OMP_PAYLOAD_SIZE);
|
||||
|
||||
//hopping frequency
|
||||
packet[0 ] = hopping_frequency_no; // |0x40 to request RX telemetry
|
||||
XN297L_Hopping(hopping_frequency_no);
|
||||
hopping_frequency_no++;
|
||||
hopping_frequency_no &= OMP_RF_NUM_CHANNELS-1; // 8 RF channels
|
||||
|
||||
//flags
|
||||
packet[1 ] = 0x08 //unknown
|
||||
| GET_FLAG(CH5_SW, 0x20); // HOLD
|
||||
|
||||
packet[2 ] = 0x40; //unknown
|
||||
|
||||
if(Channel_data[CH6] > CHANNEL_MAX_COMMAND)
|
||||
packet[2 ] |= 0x20; // IDLE2
|
||||
else if(Channel_data[CH6] > CHANNEL_MIN_COMMAND)
|
||||
packet[1 ] |= 0x40; // IDLE1
|
||||
|
||||
if(Channel_data[CH7] > CHANNEL_MAX_COMMAND)
|
||||
packet[2 ] |= 0x08; // 3D
|
||||
else if(Channel_data[CH7] > CHANNEL_MIN_COMMAND)
|
||||
packet[2 ] |= 0x04; // ATTITUDE
|
||||
|
||||
//trims??
|
||||
//packet[3..6]
|
||||
|
||||
//channels TAER packed 11bits
|
||||
uint16_t channel=convert_channel_16b_limit(THROTTLE,0,2047);
|
||||
packet[7 ] = channel;
|
||||
packet[8 ] = channel>>8;
|
||||
channel=convert_channel_16b_limit(AILERON,2047,0);
|
||||
packet[8 ] |= channel<<3;
|
||||
packet[9 ] = channel>>5;
|
||||
channel=convert_channel_16b_limit(ELEVATOR,0,2047);
|
||||
packet[9] |= channel<<6;
|
||||
packet[10] = channel>>2;
|
||||
packet[11] = channel>>10;
|
||||
channel=convert_channel_16b_limit(RUDDER,2047,0);
|
||||
packet[11] |= channel<<1;
|
||||
packet[12] = channel>>7;
|
||||
|
||||
//unknown
|
||||
//packet[13..15]
|
||||
packet[15] = 0x04;
|
||||
}
|
||||
|
||||
XN297L_SetPower(); // Set tx_power
|
||||
XN297L_SetFreqOffset(); // Set frequency offset
|
||||
XN297L_WriteEnhancedPayload(packet, OMP_PAYLOAD_SIZE, IS_BIND_IN_PROGRESS);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) OMP_init()
|
||||
{
|
||||
XN297L_Init();
|
||||
XN297L_SetTXAddr((uint8_t*)"FLPBD", 5);
|
||||
XN297L_HoppingCalib(OMP_RF_NUM_CHANNELS); // Calibrate all channels
|
||||
XN297L_RFChannel(OMP_RF_BIND_CHANNEL); // Set bind channel
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) OMP_initialize_txid()
|
||||
{
|
||||
calc_fh_channels(OMP_RF_NUM_CHANNELS);
|
||||
#ifdef FORCE_OMP_ORIGINAL_ID
|
||||
rx_tx_addr[0]=0x4E;
|
||||
rx_tx_addr[1]=0x72;
|
||||
rx_tx_addr[2]=0x8E;
|
||||
rx_tx_addr[3]=0x70;
|
||||
rx_tx_addr[4]=0x62;
|
||||
for(uint8_t i=0; i<OMP_RF_NUM_CHANNELS;i++)
|
||||
hopping_frequency[i]=(i+3)*5;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint16_t OMP_callback()
|
||||
{
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
if(--bind_counter==0)
|
||||
{
|
||||
BIND_DONE;
|
||||
XN297L_SetTXAddr(rx_tx_addr, 5);
|
||||
}
|
||||
OMP_send_packet();
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(OMP_PACKET_PERIOD);
|
||||
#endif
|
||||
return OMP_PACKET_PERIOD;
|
||||
}
|
||||
|
||||
uint16_t initOMP()
|
||||
{
|
||||
OMP_initialize_txid();
|
||||
OMP_init();
|
||||
hopping_frequency_no = 0;
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
bind_counter=OMP_BIND_COUNT;
|
||||
else
|
||||
XN297L_SetTXAddr(rx_tx_addr, 5);
|
||||
return OMP_INITIAL_WAIT;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -56,16 +56,16 @@ static void __attribute__((unused)) pelikan_build_packet()
|
||||
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);
|
||||
uint16_t channel=convert_channel_16b_nolimit(CH_AETR[offset++], 153, 871,false);
|
||||
uint8_t top=(channel>>2) & 0xC0;
|
||||
packet[2] = channel;
|
||||
channel=convert_channel_16b_nolimit(CH_AETR[offset++], 153, 871);
|
||||
channel=convert_channel_16b_nolimit(CH_AETR[offset++], 153, 871,false);
|
||||
top|=(channel>>4) & 0x30;
|
||||
packet[3] = channel;
|
||||
channel=convert_channel_16b_nolimit(CH_AETR[offset++], 153, 871);
|
||||
channel=convert_channel_16b_nolimit(CH_AETR[offset++], 153, 871,false);
|
||||
top|=(channel>>6) & 0x0C;
|
||||
packet[4] = channel;
|
||||
channel=convert_channel_16b_nolimit(CH_AETR[offset], 153, 871);
|
||||
channel=convert_channel_16b_nolimit(CH_AETR[offset], 153, 871,false);
|
||||
top|=(channel>>8) & 0x03;
|
||||
packet[5] = channel;
|
||||
packet[6] = top;
|
||||
|
||||
104
Multiprotocol/RF2500_EMU.ino
Normal file
104
Multiprotocol/RF2500_EMU.ino
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
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 CYRF6936_INSTALLED
|
||||
#include "iface_rf2500.h"
|
||||
|
||||
#define RF2500_ADDR_LENGTH 4
|
||||
|
||||
uint8_t RF2500_payload_length, RF2500_tx_addr[RF2500_ADDR_LENGTH], RF2500_buf[80];
|
||||
bool RF2500_scramble_enabled;
|
||||
|
||||
static void __attribute__((unused)) RF2500_Init(uint8_t payload_length, bool scramble)
|
||||
{
|
||||
CYRF_GFSK1M_Init( RF2500_ADDR_LENGTH + 2 + (payload_length+2)*4, 2 ); // full payload length with CRC + address + 5 + FEC
|
||||
|
||||
RF2500_payload_length=payload_length;
|
||||
RF2500_scramble_enabled=scramble;
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) RF2500_SetTXAddr(const uint8_t* addr)
|
||||
{
|
||||
memcpy(RF2500_tx_addr, addr, RF2500_ADDR_LENGTH);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) RF2500_BuildPayload(uint8_t* buffer)
|
||||
{
|
||||
const uint8_t RF2500_scramble[] = { 0xD0, 0x9E, 0x53, 0x33, 0xD8, 0xBA, 0x98, 0x08, 0x24, 0xCB, 0x3B, 0xFC, 0x71, 0xA3, 0xF4, 0x55 };
|
||||
const uint16_t RF2500_crc_xorout_scramble = 0xAEE4;
|
||||
|
||||
//Scramble the incoming buffer
|
||||
if(RF2500_scramble_enabled)
|
||||
for(uint8_t i=0; i<RF2500_payload_length; i++)
|
||||
buffer[i] ^= RF2500_scramble[i];
|
||||
|
||||
//Add CRC to the buffer
|
||||
crc=0x0000;
|
||||
for(uint8_t i=0;i<RF2500_payload_length;i++)
|
||||
crc16_update(bit_reverse(buffer[i]),8);
|
||||
buffer[RF2500_payload_length ] = bit_reverse(crc>>8);
|
||||
buffer[RF2500_payload_length+1] = bit_reverse(crc);
|
||||
|
||||
if(RF2500_scramble_enabled)
|
||||
{
|
||||
buffer[RF2500_payload_length ] ^= RF2500_crc_xorout_scramble>>8;
|
||||
buffer[RF2500_payload_length+1] ^= RF2500_crc_xorout_scramble;
|
||||
}
|
||||
|
||||
#if 0
|
||||
debug("B:");
|
||||
for(uint8_t i=0; i<RF2500_payload_length+2; i++)
|
||||
debug(" %02X",buffer[i]);
|
||||
debugln("");
|
||||
#endif
|
||||
|
||||
memcpy(RF2500_buf,RF2500_tx_addr,RF2500_ADDR_LENGTH); // Address
|
||||
|
||||
uint8_t pos = RF2500_ADDR_LENGTH;
|
||||
|
||||
RF2500_buf[pos++]=0xC3;RF2500_buf[pos++]=0xC3; // 5 FEC encoded
|
||||
memset(&RF2500_buf[pos],0x00,(RF2500_payload_length+2)*4); // + CRC) * 4 FEC bytes per byte
|
||||
|
||||
//FEC encode
|
||||
for(uint8_t i=0; i<RF2500_payload_length+2; i++) // Include CRC
|
||||
{
|
||||
for(uint8_t j=0;j<8;j++)
|
||||
{
|
||||
uint8_t offset=pos + (i<<2) + (j>>1);
|
||||
RF2500_buf[offset] <<= 4;
|
||||
if( (buffer[i]>>j) & 0x01 )
|
||||
RF2500_buf[offset] |= 0x0C;
|
||||
else
|
||||
RF2500_buf[offset] |= 0x03;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
debug("E:");
|
||||
for(uint8_t i=0; i<RF2500_ADDR_LENGTH+2+(RF2500_payload_length+2)*4; i++)
|
||||
debug(" %02X",RF2500_buf[i]);
|
||||
debugln("");
|
||||
#endif
|
||||
|
||||
//CYRF wants LSB first
|
||||
for(uint8_t i=0; i<RF2500_ADDR_LENGTH+2+(RF2500_payload_length+2)*4; i++)
|
||||
RF2500_buf[i]=bit_reverse(RF2500_buf[i]);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) RF2500_SendPayload()
|
||||
{
|
||||
CYRF_GFSK1M_SendPayload(RF2500_buf, RF2500_ADDR_LENGTH + 2 + (RF2500_payload_length+2)*4 );
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -31,87 +31,63 @@ enum {
|
||||
RLINK_RX2 = 0x02,
|
||||
};
|
||||
|
||||
const PROGMEM uint8_t RLINK_hopping[][8] = {
|
||||
/* 4C494E4B */ { 0xBC, 0x5A, 0x70, 0x4E, 0xDF, 0x32, 0x16, 0x89 },
|
||||
/* 4D494E4B */ { 0x4C, 0xF3, 0xEA, 0x5B, 0x62, 0x9D, 0x01, 0x87 },
|
||||
/* 4E494E4B */ { 0x86, 0xEA, 0xD0, 0xC9, 0x2B, 0x53, 0x7F, 0x41 },
|
||||
/* 4F494E4B */ { 0xAC, 0x91, 0x7D, 0x48, 0xE0, 0xB5, 0x32, 0xF6 },
|
||||
/* 50494E4B */ { 0xD6, 0x7C, 0xA4, 0x93, 0x5F, 0xE1, 0x02, 0xB8 },
|
||||
/* 51494E4B */ { 0xED, 0x04, 0x73, 0xC8, 0x56, 0xB9, 0x1F, 0xA2 },
|
||||
/* 52494E4B */ { 0xA7, 0xF0, 0x36, 0xB2, 0x95, 0x4E, 0x1C, 0xD8 },
|
||||
/* 53494E4B */ { 0x76, 0x8B, 0xA0, 0x3E, 0x51, 0x4C, 0x9D, 0x2F },
|
||||
/* 54494E4B */ { 0x07, 0x23, 0x16, 0xFD, 0xC9, 0x5B, 0x84, 0xAE },
|
||||
/* 55494E4B */ { 0xD3, 0xA0, 0x69, 0xBF, 0x12, 0x8C, 0x4E, 0x57 },
|
||||
/* 56494E4B */ { 0xA6, 0xBE, 0x91, 0xD3, 0x7C, 0x4F, 0x82, 0x50 },
|
||||
/* 57494E4B */ { 0x91, 0xDA, 0xBC, 0x75, 0x82, 0x36, 0x4E, 0xF0 },
|
||||
/* 58494E4B */ { 0x9A, 0x27, 0x5C, 0xF4, 0xD8, 0xB0, 0x36, 0xE1 },
|
||||
/* 59494E4B */ { 0x92, 0xF1, 0x34, 0xA7, 0x5B, 0x0C, 0xED, 0x86 },
|
||||
/* 5A494E4B */ { 0x8C, 0x2B, 0x51, 0xF9, 0x3E, 0x4A, 0x67, 0xD0 },
|
||||
/* 5B494E4B */ { 0x5E, 0x3D, 0x67, 0x9B, 0xA2, 0x84, 0xFC, 0x01 },
|
||||
/* 5C494E4B */ { 0xF9, 0x35, 0xBD, 0x78, 0x26, 0x1C, 0x0E, 0xA4 },
|
||||
/* 5D494E4B */ { 0xD9, 0x7B, 0x48, 0x0E, 0x2A, 0xCF, 0x13, 0x65 },
|
||||
/* 5E494E4B */ { 0x07, 0xE4, 0xF9, 0x8A, 0x3C, 0x21, 0xB5, 0xD6 },
|
||||
/* 5F494E4B */ { 0xEB, 0xFA, 0x29, 0xD1, 0x54, 0x3C, 0x07, 0x86 },
|
||||
/* 60494E4B */ { 0xDF, 0xCE, 0x0A, 0x32, 0x71, 0x5B, 0x96, 0x48 },
|
||||
/* 61494E4B */ { 0x19, 0x86, 0xF5, 0x3A, 0x27, 0xDC, 0x0E, 0xB4 },
|
||||
/* 62494E4B */ { 0xF8, 0x47, 0x9C, 0xE0, 0x2D, 0xBA, 0x15, 0x36 },
|
||||
/* 63494E4B */ { 0xED, 0x78, 0x01, 0xA3, 0x2B, 0x6C, 0x45, 0xF9 },
|
||||
/* 64494E4B */ { 0xE0, 0xA2, 0xD4, 0x6B, 0xF5, 0x18, 0x3C, 0x79 },
|
||||
/* 65494E4B */ { 0x26, 0x90, 0x8B, 0x5D, 0x31, 0xCF, 0xE7, 0x4A },
|
||||
/* 66494E4B */ { 0x7B, 0x12, 0xA8, 0x4F, 0xC0, 0x65, 0xD9, 0x3E },
|
||||
/* 67494E4B */ { 0x35, 0xA2, 0x14, 0xBE, 0x06, 0x7D, 0x98, 0xFC },
|
||||
/* 68494E4B */ { 0xD2, 0xA9, 0x7E, 0x40, 0x6F, 0x83, 0x5C, 0xB1 },
|
||||
/* 69494E4B */ { 0xE5, 0xB9, 0xC1, 0x04, 0x83, 0x27, 0xA6, 0xFD },
|
||||
/* 6A494E4B */ { 0x8E, 0x0C, 0x4A, 0x51, 0xFB, 0x63, 0x92, 0x7D },
|
||||
/* 6B494E4B */ { 0xC7, 0x1D, 0x02, 0x93, 0x45, 0xF8, 0xA6, 0xBE },
|
||||
/* 6C494E4B */ { 0xC1, 0x64, 0x59, 0x0A, 0x7D, 0x3F, 0x28, 0xEB },
|
||||
/* 6D494E4B */ { 0xEF, 0x75, 0xAB, 0x94, 0xD2, 0x83, 0x1C, 0x60 },
|
||||
/* 6E494E4B */ { 0xA1, 0x20, 0x54, 0x68, 0x9E, 0x7B, 0x3D, 0xFC },
|
||||
/* 6F494E4B */ { 0x3E, 0x60, 0x28, 0xFC, 0xDA, 0x45, 0x9B, 0x71 },
|
||||
/* 70494E4B */ { 0xB7, 0x0E, 0xA8, 0x23, 0xFC, 0x65, 0x4D, 0x91 },
|
||||
/* 71494E4B */ { 0x29, 0x34, 0x51, 0x7C, 0xB8, 0xFD, 0x0E, 0x6A },
|
||||
/* 72494E4B */ { 0x1B, 0x06, 0x3C, 0x89, 0xF5, 0x2A, 0x7E, 0xD4 },
|
||||
/* 73494E4B */ { 0xF2, 0xC9, 0x63, 0x57, 0x0A, 0xB1, 0x48, 0xDE },
|
||||
/* 74494E4B */ { 0x24, 0xAE, 0x0C, 0x19, 0x53, 0x7B, 0xF6, 0x8D },
|
||||
/* 75494E4B */ { 0xEC, 0xD8, 0xF2, 0x4B, 0xA3, 0x51, 0x09, 0x76 },
|
||||
/* 76494E4B */ { 0x98, 0x71, 0x5E, 0xAD, 0xFC, 0x04, 0x3B, 0x62 },
|
||||
/* 77494E4B */ { 0xAE, 0xF6, 0xB7, 0x01, 0x52, 0x34, 0x9D, 0x8C },
|
||||
/* 78494E4B */ { 0x69, 0x48, 0xF1, 0x3C, 0xDB, 0x0E, 0x25, 0xA7 },
|
||||
/* 79494E4B */ { 0xCF, 0x60, 0x94, 0xAD, 0xB1, 0x82, 0x73, 0xE5 },
|
||||
/* 7A494E4B */ { 0xFA, 0xC1, 0xD7, 0xB0, 0x53, 0x92, 0x6E, 0x48 },
|
||||
/* 7B494E4B */ { 0xAC, 0x7D, 0xE5, 0x8B, 0x41, 0x96, 0x2F, 0x30 },
|
||||
/* 7C494E4B */ { 0xFD, 0xC1, 0xB9, 0x02, 0xE4, 0x87, 0x56, 0x3A },
|
||||
/* 7D494E4B */ { 0x30, 0xDA, 0x4F, 0x8E, 0x5C, 0xB9, 0x26, 0x71 },
|
||||
/* 7E494E4B */ { 0xDC, 0xF9, 0x57, 0x30, 0x82, 0x1E, 0x6A, 0x4B },
|
||||
/* 7F494E4B */ { 0x84, 0x1D, 0x7E, 0x29, 0x3C, 0x65, 0xA0, 0xBF },
|
||||
/* 80494E4B */ { 0x01, 0xA3, 0xF6, 0xE2, 0x4C, 0x8B, 0x5D, 0x79 },
|
||||
/* 81494E4B */ { 0xA1, 0x32, 0xE7, 0x08, 0x4D, 0x5B, 0x9F, 0x6C },
|
||||
/* 82494E4B */ { 0x31, 0x40, 0x67, 0x8F, 0xBA, 0x95, 0x2C, 0xED },
|
||||
/* 83494E4B */ { 0x91, 0x76, 0xFA, 0x83, 0x20, 0x4B, 0xEC, 0x5D },
|
||||
/* 84494E4B */ { 0xDB, 0x54, 0xC2, 0x61, 0xF0, 0xA9, 0x87, 0x3E },
|
||||
/* 85494E4B */ { 0xC0, 0xB4, 0x61, 0xD3, 0x7A, 0x5F, 0x82, 0x9E },
|
||||
/* 86494E4B */ { 0xD6, 0xCF, 0x9B, 0x75, 0xE1, 0x42, 0x3A, 0x80 },
|
||||
/* 87494E4B */ { 0xFE, 0xA2, 0xB4, 0x9C, 0x10, 0x7D, 0x56, 0x83 },
|
||||
/* 88494E4B */ { 0xD2, 0x79, 0x54, 0xEF, 0xC8, 0x0B, 0x36, 0xA1 },
|
||||
/* 89494E4B */ { 0x8D, 0xCF, 0x23, 0x64, 0xE5, 0x0B, 0x1A, 0x97 },
|
||||
/* 8A494E4B */ { 0x07, 0xC4, 0xEF, 0x9A, 0x61, 0xD8, 0xB3, 0x52 },
|
||||
/* 8B494E4B */ { 0x45, 0x6E, 0xBF, 0x8C, 0x9A, 0x2D, 0x31, 0x70 },
|
||||
#ifdef RLINK_FORCE_ID
|
||||
/* 3A99223A */ { 0x1F, 0x89, 0x25, 0x06, 0x4E, 0xBD, 0x3A, 0xC7 },
|
||||
/* FC110D20 */ { 0xBC, 0xFE, 0x59, 0x84, 0x37, 0xA1, 0xD0, 0x62 }
|
||||
#endif
|
||||
};
|
||||
uint32_t RLINK_rand1;
|
||||
uint32_t RLINK_rand2;
|
||||
|
||||
static void __attribute__((unused)) RLINK_load_hopp(uint8_t num)
|
||||
static uint32_t __attribute__((unused)) RLINK_prng_next(uint32_t r)
|
||||
{
|
||||
return 0xA5E2A705 * r + 0x754DB79B;
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) RLINK_init_random(uint32_t id)
|
||||
{
|
||||
uint32_t result = id;
|
||||
|
||||
RLINK_rand2 = result;
|
||||
for (uint8_t i=0; i<31; i++)
|
||||
result = RLINK_prng_next(result);
|
||||
RLINK_rand1 = result;
|
||||
}
|
||||
|
||||
static uint8_t __attribute__((unused)) RLINK_next_random_swap()
|
||||
{
|
||||
uint8_t result = (RLINK_rand2 >> 16) + RLINK_rand2 + (RLINK_rand1 >> 16) + RLINK_rand1;
|
||||
|
||||
RLINK_rand2 = RLINK_prng_next(RLINK_rand2);
|
||||
RLINK_rand1 = RLINK_prng_next(RLINK_rand1);
|
||||
|
||||
return result & 0x0F;
|
||||
}
|
||||
|
||||
static uint32_t __attribute__((unused)) RLINK_compute_start_id(uint32_t id)
|
||||
{
|
||||
return id * 0xF65EF9F9u + 0x2EDDF6CAu;
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) RLINK_shuffle_freqs(uint32_t seed)
|
||||
{
|
||||
RLINK_init_random(seed);
|
||||
|
||||
for(uint8_t i=0; i<RLINK_HOP; i++)
|
||||
{
|
||||
uint8_t r = RLINK_next_random_swap();
|
||||
uint8_t tmp = hopping_frequency[r];
|
||||
hopping_frequency[r] = hopping_frequency[i];
|
||||
hopping_frequency[i] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) RLINK_hop()
|
||||
{
|
||||
uint8_t inc=3*(rx_tx_addr[0]&3);
|
||||
|
||||
for (uint8_t i = 0; i < RLINK_HOP>>1; i++)
|
||||
{
|
||||
uint8_t val=pgm_read_byte_near(&RLINK_hopping[num][i]);
|
||||
hopping_frequency[ i<<1 ]=12*(val>>4 )+inc;
|
||||
hopping_frequency[(i<<1)+1]=12*(val&0x0F)+inc;
|
||||
}
|
||||
// init hop table
|
||||
for(uint8_t i=0; i<RLINK_HOP; i++)
|
||||
hopping_frequency[i] = (12*i) + inc;
|
||||
|
||||
// shuffle
|
||||
RLINK_shuffle_freqs(RLINK_compute_start_id(rx_tx_addr[0] + (rx_tx_addr[1] << 8)));
|
||||
RLINK_shuffle_freqs(RLINK_compute_start_id(rx_tx_addr[2] + (rx_tx_addr[3] << 8)));
|
||||
|
||||
// replace one of the channel randomely
|
||||
rf_ch_num=random(0xfefefefe)%0x11; // 0x00..0x10
|
||||
@@ -121,30 +97,25 @@ static void __attribute__((unused)) RLINK_load_hopp(uint8_t num)
|
||||
|
||||
static void __attribute__((unused)) RLINK_init()
|
||||
{
|
||||
// channels order depend on ID and currently unknown so using a table of 64 entries...
|
||||
uint8_t id=rx_tx_addr[3]&0x3F;
|
||||
memcpy(rx_tx_addr,"\x4C\x49\x4E\x4B",RLINK_TX_ID_LEN);
|
||||
rx_tx_addr[0] += id;
|
||||
RLINK_load_hopp(id);
|
||||
|
||||
#ifdef RLINK_FORCE_ID
|
||||
//surface RC6GS
|
||||
memcpy(rx_tx_addr,"\x3A\x99\x22\x3A",RLINK_TX_ID_LEN);
|
||||
RLINK_load_hopp(64);
|
||||
//air T8FB
|
||||
//memcpy(rx_tx_addr,"\xFC\x11\x0D\x20",RLINK_TX_ID_LEN);
|
||||
//RLINK_load_hopp(65);
|
||||
#endif
|
||||
// channels order depend on ID
|
||||
RLINK_hop();
|
||||
|
||||
/* debug("ID:");
|
||||
for(uint8_t i=0;i<RLINK_TX_ID_LEN;i++)
|
||||
debug(" 0x%02X",rx_tx_addr[i]);
|
||||
debugln("");
|
||||
debug("Hop(%d):", rf_ch_num);
|
||||
for(uint8_t i=0;i<RLINK_HOP;i++)
|
||||
debug(" 0x%02X",hopping_frequency[i]);
|
||||
debugln("");
|
||||
*/
|
||||
#if 0
|
||||
debug("ID:");
|
||||
for(uint8_t i=0;i<RLINK_TX_ID_LEN;i++)
|
||||
debug(" 0x%02X",rx_tx_addr[i]);
|
||||
debugln("");
|
||||
debug("Hop(%d):", rf_ch_num);
|
||||
for(uint8_t i=0;i<RLINK_HOP;i++)
|
||||
debug(" 0x%02X",hopping_frequency[i]);
|
||||
debugln("");
|
||||
#endif
|
||||
}
|
||||
|
||||
const PROGMEM uint8_t RLINK_init_values[] = {
|
||||
@@ -162,21 +133,17 @@ static void __attribute__((unused)) RLINK_rf_init()
|
||||
for (uint8_t i = 0; i < 39; ++i)
|
||||
CC2500_WriteReg(i, pgm_read_byte_near(&RLINK_init_values[i]));
|
||||
|
||||
prev_option = option;
|
||||
if(sub_protocol==RLINK_DUMBORC)
|
||||
{
|
||||
CC2500_WriteReg(4, 0xBA);
|
||||
CC2500_WriteReg(5, 0xDC);
|
||||
}
|
||||
|
||||
CC2500_WriteReg(CC2500_0C_FSCTRL0, option);
|
||||
|
||||
CC2500_SetTxRxMode(TX_EN);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) RLINK_tune_freq()
|
||||
{
|
||||
if ( prev_option != option )
|
||||
{
|
||||
CC2500_WriteReg(CC2500_0C_FSCTRL0, option);
|
||||
prev_option = option ;
|
||||
}
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) RLINK_send_packet()
|
||||
{
|
||||
static uint32_t pseudo=0;
|
||||
@@ -189,16 +156,22 @@ static void __attribute__((unused)) RLINK_send_packet()
|
||||
// packet length
|
||||
packet[0] = RLINK_TX_PACKET_LEN;
|
||||
// header
|
||||
if(sub_protocol)
|
||||
packet[1] = 0x21; //air 0x21 on dump but it looks to support telemetry at least RSSI
|
||||
else
|
||||
{//surface
|
||||
packet[1] = 0x01;
|
||||
//radiolink additionnal ID which is working only on a small set of RXs
|
||||
//if(RX_num) packet[1] |= ((RX_num+2)<<4)+4; // RX number limited to 10 values, 0 is a wildcard
|
||||
}
|
||||
if(packet_count>3)
|
||||
packet[1] |= 0x02; // 0x02 telemetry request flag
|
||||
packet[1] = 0x02; // 0x02 telemetry request flag
|
||||
switch(sub_protocol)
|
||||
{
|
||||
case RLINK_SURFACE:
|
||||
packet[1] |= 0x01;
|
||||
//radiolink additionnal ID which is working only on a small set of RXs
|
||||
//if(RX_num) packet[1] |= ((RX_num+2)<<4)+4; // RX number limited to 10 values, 0 is a wildcard
|
||||
break;
|
||||
case RLINK_AIR:
|
||||
packet[1] |= 0x21; //air 0x21 on dump but it looks to support telemetry at least RSSI
|
||||
break;
|
||||
case RLINK_DUMBORC:
|
||||
packet[1] = 0x00; //always 0x00 on dump
|
||||
break;
|
||||
}
|
||||
|
||||
// ID
|
||||
memcpy(&packet[2],rx_tx_addr,RLINK_TX_ID_LEN);
|
||||
@@ -206,7 +179,7 @@ static void __attribute__((unused)) RLINK_send_packet()
|
||||
// pack 16 channels on 11 bits values between 170 and 1876, 1023 middle. The last 8 channels are failsafe values associated to the first 8 values.
|
||||
for (uint8_t i = 0; i < 16; i++)
|
||||
{
|
||||
uint32_t val = convert_channel_16b_nolimit(i,170,1876); // allow extended limits
|
||||
uint32_t val = convert_channel_16b_nolimit(i,170,1876,false); // allow extended limits
|
||||
if (val & 0x8000)
|
||||
val = 0;
|
||||
else if (val > 2047)
|
||||
@@ -262,7 +235,7 @@ uint16_t RLINK_callback()
|
||||
telemetry_set_input_sync(RLINK_TIMING_PROTO);
|
||||
#endif
|
||||
CC2500_SetPower();
|
||||
RLINK_tune_freq();
|
||||
CC2500_SetFreqOffset();
|
||||
RLINK_send_packet();
|
||||
#if not defined RLINK_HUB_TELEMETRY
|
||||
return RLINK_TIMING_PROTO;
|
||||
|
||||
@@ -98,11 +98,7 @@ static void REDPINE_data_frame() {
|
||||
|
||||
static uint16_t ReadREDPINE()
|
||||
{
|
||||
if ( prev_option != option )
|
||||
{ // Frequency adjust
|
||||
CC2500_WriteReg(CC2500_0C_FSCTRL0, option);
|
||||
prev_option = option ;
|
||||
}
|
||||
CC2500_SetFreqOffset();
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
if (state == REDPINE_BIND) {
|
||||
@@ -122,22 +118,18 @@ static uint16_t ReadREDPINE()
|
||||
}
|
||||
return 4000;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(packet_period);
|
||||
#endif
|
||||
CC2500_SetTxRxMode(TX_EN);
|
||||
REDPINE_set_channel(hopping_frequency_no);
|
||||
CC2500_SetPower();
|
||||
CC2500_Strobe(CC2500_SFRX);
|
||||
REDPINE_data_frame();
|
||||
CC2500_Strobe(CC2500_SIDLE);
|
||||
hopping_frequency_no = (hopping_frequency_no + 1) % 49;
|
||||
CC2500_WriteData(packet, REDPINE_PACKET_SIZE);
|
||||
return packet_period;
|
||||
}
|
||||
return 1;
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(packet_period);
|
||||
#endif
|
||||
CC2500_SetTxRxMode(TX_EN);
|
||||
REDPINE_set_channel(hopping_frequency_no);
|
||||
CC2500_SetPower();
|
||||
CC2500_Strobe(CC2500_SFRX);
|
||||
REDPINE_data_frame();
|
||||
CC2500_Strobe(CC2500_SIDLE);
|
||||
hopping_frequency_no = (hopping_frequency_no + 1) % 49;
|
||||
CC2500_WriteData(packet, REDPINE_PACKET_SIZE);
|
||||
return packet_period;
|
||||
}
|
||||
|
||||
// register, fast 250k, slow
|
||||
@@ -189,7 +181,6 @@ static void REDPINE_init(uint8_t format)
|
||||
CC2500_WriteReg(REDPINE_init_data[i][0], REDPINE_init_data[i][format+1]);
|
||||
}
|
||||
|
||||
prev_option = option;
|
||||
CC2500_WriteReg(CC2500_0C_FSCTRL0, option);
|
||||
CC2500_Strobe(CC2500_SIDLE);
|
||||
|
||||
|
||||
@@ -129,7 +129,7 @@ static void __attribute__((unused)) SLT_build_packet()
|
||||
uint8_t e = 0; // byte where extension 2 bits for every 10-bit channel are packed
|
||||
for (uint8_t i = 0; i < 4; ++i)
|
||||
{
|
||||
uint16_t v = convert_channel_10b(CH_AETR[i]);
|
||||
uint16_t v = convert_channel_10b(CH_AETR[i], false);
|
||||
if(sub_protocol>SLT_V2 && (i==CH2 || i==CH3) )
|
||||
v=1023-v; // reverse throttle and elevator channels for Q100/Q200/MR100 protocols
|
||||
packet[i] = v;
|
||||
@@ -260,6 +260,7 @@ uint16_t SLT_callback()
|
||||
|
||||
uint16_t initSLT()
|
||||
{
|
||||
BIND_DONE; // Not a TX bind protocol
|
||||
packet_count = 0;
|
||||
packet_sent = 0;
|
||||
hopping_frequency_no = 0;
|
||||
|
||||
@@ -54,7 +54,6 @@ static void __attribute__((unused)) SKYARTEC_rf_init()
|
||||
for (uint8_t i = 4; i <= 0x2E; ++i)
|
||||
CC2500_WriteReg(i, pgm_read_byte_near(&SKYARTEC_init_values[i-4]));
|
||||
|
||||
prev_option = option;
|
||||
CC2500_WriteReg(CC2500_0C_FSCTRL0, option);
|
||||
|
||||
CC2500_SetTxRxMode(TX_EN);
|
||||
@@ -130,11 +129,7 @@ uint16_t ReadSKYARTEC()
|
||||
{
|
||||
CC2500_SetPower();
|
||||
// Tune frequency if it has been changed
|
||||
if ( prev_option != option )
|
||||
{
|
||||
CC2500_WriteReg(CC2500_0C_FSCTRL0, option);
|
||||
prev_option = option ;
|
||||
}
|
||||
CC2500_SetFreqOffset();
|
||||
phase = SKYARTEC_PKT1;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -77,19 +77,19 @@ static void __attribute__((unused)) TRAXXAS_send_data_packet()
|
||||
packet[0] = 0x01;
|
||||
memset(&packet[1],0x00,TRAXXAS_PACKET_SIZE-1);
|
||||
//Steering
|
||||
uint16_t ch = convert_channel_16b_nolimit(RUDDER,500,1000);
|
||||
uint16_t ch = convert_channel_16b_nolimit(RUDDER,500,1000,false);
|
||||
packet[2]=ch>>8;
|
||||
packet[3]=ch;
|
||||
//Throttle
|
||||
ch = convert_channel_16b_nolimit(THROTTLE,500,1000);
|
||||
ch = convert_channel_16b_nolimit(THROTTLE,500,1000,false);
|
||||
packet[4]=ch>>8;
|
||||
packet[5]=ch;
|
||||
//AUX3
|
||||
ch = convert_channel_16b_nolimit(AILERON,500,1000);
|
||||
ch = convert_channel_16b_nolimit(AILERON,500,1000,false);
|
||||
packet[6]=ch>>8;
|
||||
packet[7]=ch;
|
||||
//AUX4???
|
||||
ch = convert_channel_16b_nolimit(ELEVATOR,500,1000);
|
||||
ch = convert_channel_16b_nolimit(ELEVATOR,500,1000,false);
|
||||
packet[12]=ch>>8;
|
||||
packet[13]=ch;
|
||||
|
||||
|
||||
@@ -35,16 +35,16 @@
|
||||
#endif
|
||||
|
||||
//Channel MIN MAX values
|
||||
#define CHANNEL_MAX_100 1844 // 100%
|
||||
#define CHANNEL_MIN_100 204 // 100%
|
||||
#define CHANNEL_MAX_125 2047 // 125%
|
||||
#define CHANNEL_MIN_125 0 // 125%
|
||||
#define CHANNEL_MAX_100 1844 // +100%
|
||||
#define CHANNEL_MIN_100 204 // -100%
|
||||
#define CHANNEL_MAX_125 2047 // +125%
|
||||
#define CHANNEL_MIN_125 0 // -125%
|
||||
|
||||
#define CHANNEL_MID 1024
|
||||
|
||||
#define CHANNEL_MIN_COMMAND 784 // 1350us
|
||||
#define CHANNEL_SWITCH 1104 // 1550us
|
||||
#define CHANNEL_MAX_COMMAND 1424 // 1750us
|
||||
#define CHANNEL_MIN_COMMAND 409 // -75%
|
||||
#define CHANNEL_SWITCH 1106 // +10%
|
||||
#define CHANNEL_MAX_COMMAND 1639 // +75%
|
||||
|
||||
//Channel definitions
|
||||
#define CH1 0
|
||||
|
||||
@@ -531,11 +531,11 @@ void frsky_link_frame()
|
||||
telemetry_link |= 2 ; // Send hub if available
|
||||
}
|
||||
else
|
||||
{//PROTO_HUBSAN, PROTO_AFHDS2A, PROTO_BAYANG, PROTO_NCC1701, PROTO_CABELL, PROTO_HITEC, PROTO_BUGS, PROTO_BUGSMINI, PROTO_FRSKYX, PROTO_FRSKYX2, PROTO_PROPEL, PROTO_DEVO, PROTO_RLINK
|
||||
{//PROTO_HUBSAN, PROTO_AFHDS2A, PROTO_BAYANG, PROTO_NCC1701, PROTO_CABELL, PROTO_HITEC, PROTO_BUGS, PROTO_BUGSMINI, PROTO_FRSKYX, PROTO_FRSKYX2, PROTO_PROPEL, PROTO_DEVO, PROTO_RLINK, PROTO_OMP, PROTO_WFLY2, PROTO_LOLI
|
||||
frame[1] = v_lipo1;
|
||||
frame[2] = v_lipo2;
|
||||
frame[3] = RX_RSSI;
|
||||
telemetry_link=0;
|
||||
telemetry_link &= ~1 ; // Sent
|
||||
}
|
||||
frame[4] = TX_RSSI;
|
||||
frame[5] = RX_LQI;
|
||||
@@ -563,7 +563,7 @@ void frsky_user_frame()
|
||||
else
|
||||
{
|
||||
frame[1]=telemetry_in_buffer[6]; // packet size
|
||||
telemetry_link=0; // only 1 packet or processing second packet
|
||||
telemetry_link &= ~2; // only 1 packet or processing second packet
|
||||
}
|
||||
frame[2] = telemetry_in_buffer[7];
|
||||
for(uint8_t i=0;i<USER_MAX_BYTES;i++)
|
||||
@@ -578,7 +578,7 @@ void frsky_user_frame()
|
||||
#endif
|
||||
}
|
||||
else
|
||||
telemetry_link=0;
|
||||
telemetry_link &= ~2;
|
||||
}
|
||||
/*
|
||||
HuB RX packets.
|
||||
@@ -594,6 +594,29 @@ packet_in[6]|(counter++)|00 01 02 03 04 05 06 07 08 09
|
||||
0A 0F 5E 3A 06 00 5E 5E 3B 09 00 5E
|
||||
05 10 5E 06 16 72 5E 5E 3A 06 00 5E
|
||||
*/
|
||||
static void __attribute__((unused)) frsky_send_user_frame(uint8_t ID, uint8_t low, uint8_t high)
|
||||
{
|
||||
telemetry_in_buffer[6] = 0x04; // number of bytes in the payload
|
||||
telemetry_in_buffer[7] = 0x00; // unknown?
|
||||
telemetry_in_buffer[8] = 0x5E; // start of payload
|
||||
telemetry_in_buffer[9] = ID; // ID must be less than 0x40
|
||||
uint8_t pos=10;
|
||||
uint8_t value = low;
|
||||
for(uint8_t i=0;i<2;i++)
|
||||
{// Byte stuffing
|
||||
if(value == 0x5D || value == 0x5E)
|
||||
{// Byte stuffing
|
||||
telemetry_in_buffer[pos+1] = value ^ 0x60;
|
||||
telemetry_in_buffer[pos] = 0x5D;
|
||||
telemetry_in_buffer[6]++; // 1 more byte in the payload
|
||||
pos += 2;
|
||||
}
|
||||
else
|
||||
telemetry_in_buffer[pos++] = value;
|
||||
value = high;
|
||||
}
|
||||
telemetry_link |= 2; // request to send frame
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -952,13 +975,13 @@ void TelemetryUpdate()
|
||||
#endif
|
||||
|
||||
if( telemetry_link & 1 )
|
||||
{ // FrSkyD + Hubsan + AFHDS2A + Bayang + Cabell + Hitec + Bugs + BugsMini + NCC1701 + PROPEL + RLINK
|
||||
{ // FrSkyD + Hubsan + AFHDS2A + Bayang + Cabell + Hitec + Bugs + BugsMini + NCC1701 + PROPEL + RLINK + OMP
|
||||
// FrSkyX telemetry if in PPM
|
||||
frsky_link_frame();
|
||||
return;
|
||||
}
|
||||
#if defined HUB_TELEMETRY
|
||||
if((telemetry_link & 2) && protocol == PROTO_FRSKYD)
|
||||
if((telemetry_link & 2) && ( protocol == PROTO_FRSKYD || protocol == PROTO_BAYANG ) )
|
||||
{ // FrSkyD
|
||||
frsky_user_frame();
|
||||
return;
|
||||
|
||||
@@ -114,9 +114,9 @@
|
||||
#error "The RADIOLINK forced frequency tuning value is outside of the range -127..127."
|
||||
#endif
|
||||
#endif
|
||||
#ifdef FORCE_SFHSS_TUNING
|
||||
#if ( FORCE_SFHSS_TUNING < -127 ) || ( FORCE_SFHSS_TUNING > 127 )
|
||||
#error "The SFHSS forced frequency tuning value is outside of the range -127..127."
|
||||
#ifdef FORCE_FUTABA_TUNING
|
||||
#if ( FORCE_FUTABA_TUNING < -127 ) || ( FORCE_FUTABA_TUNING > 127 )
|
||||
#error "The Futaba forced frequency tuning value is outside of the range -127..127."
|
||||
#endif
|
||||
#endif
|
||||
#ifdef FORCE_SKYARTEC_TUNING
|
||||
@@ -160,6 +160,11 @@
|
||||
#error "The Kyosho forced frequency tuning value is outside of the range -300..300."
|
||||
#endif
|
||||
#endif
|
||||
#ifdef FORCE_WFLY2_TUNING
|
||||
#if ( FORCE_WFLY2_TUNING < -300 ) || ( FORCE_WFLY2_TUNING > 300 )
|
||||
#error "The WFLY2 forced frequency tuning value is outside of the range -300..300."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef USE_A7105_CH15_TUNING
|
||||
#ifndef FORCE_BUGS_TUNING
|
||||
@@ -177,6 +182,9 @@
|
||||
#ifndef FORCE_KYOSHO_TUNING
|
||||
#define FORCE_KYOSHO_TUNING 0
|
||||
#endif
|
||||
#ifndef FORCE_WFLY2_TUNING
|
||||
#define FORCE_WFLY2_TUNING 0
|
||||
#endif
|
||||
#ifndef FORCE_HUBSAN_TUNING
|
||||
#define FORCE_HUBSAN_TUNING 0
|
||||
#endif
|
||||
@@ -215,6 +223,10 @@
|
||||
#define NRF24L01_INSTALLED
|
||||
#define SX1276_INSTALLED
|
||||
#undef ENABLE_PPM
|
||||
#ifdef MLINK_CYRF6936_INO
|
||||
#undef MLINK_CYRF6936_INO
|
||||
#warning "Disabling the MLink protocol to fit in the Flash."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//Make sure protocols are selected correctly
|
||||
@@ -227,18 +239,23 @@
|
||||
#undef HUBSAN_A7105_INO
|
||||
#undef KYOSHO_A7105_INO
|
||||
#undef PELIKAN_A7105_INO
|
||||
#undef WFLY2_A7105_INO
|
||||
#endif
|
||||
#ifndef CYRF6936_INSTALLED
|
||||
#undef DEVO_CYRF6936_INO
|
||||
#undef DSM_CYRF6936_INO
|
||||
#undef DSM_RX_CYRF6936_INO
|
||||
#undef E010R5_CYRF6936_INO
|
||||
#undef E129_CYRF6936_INO
|
||||
#undef J6PRO_CYRF6936_INO
|
||||
#undef MLINK_CYRF6936_INO
|
||||
#undef TRAXXAS_CYRF6936_INO
|
||||
#undef WFLY_CYRF6936_INO
|
||||
#undef WK2x01_CYRF6936_INO
|
||||
#endif
|
||||
#ifndef CC2500_INSTALLED
|
||||
#undef CORONA_CC2500_INO
|
||||
#undef E016HV2_CC2500_INO
|
||||
#undef ESKY150V2_CC2500_INO
|
||||
#undef FRSKYD_CC2500_INO
|
||||
#undef FRSKYL_CC2500_INO
|
||||
@@ -247,10 +264,11 @@
|
||||
#undef FRSKY_RX_CC2500_INO
|
||||
#undef HITEC_CC2500_INO
|
||||
#undef HOTT_CC2500_INO
|
||||
#undef OMP_CC2500_INO // Use both CC2500 and NRF code
|
||||
#undef REDPINE_CC2500_INO
|
||||
#undef RLINK_CC2500_INO
|
||||
#undef SCANNER_CC2500_INO
|
||||
#undef SFHSS_CC2500_INO
|
||||
#undef FUTABA_CC2500_INO
|
||||
#undef SKYARTEC_CC2500_INO
|
||||
#endif
|
||||
#ifndef NRF24L01_INSTALLED
|
||||
@@ -266,7 +284,6 @@
|
||||
#undef E01X_NRF24L01_INO
|
||||
#undef ESKY_NRF24L01_INO
|
||||
#undef ESKY150_NRF24L01_INO
|
||||
#undef ESKY150V2_CC2500_INO // Use both CC2500 and NRF code
|
||||
#undef FQ777_NRF24L01_INO
|
||||
#undef FX816_NRF24L01_INO
|
||||
#undef FY326_NRF24L01_INO
|
||||
@@ -278,10 +295,11 @@
|
||||
#undef JJRC345_NRF24L01_INO
|
||||
#undef KF606_NRF24L01_INO
|
||||
#undef KN_NRF24L01_INO
|
||||
#undef LOLI_NRF24L01_INO
|
||||
#undef MJXQ_NRF24L01_INO
|
||||
#undef MT99XX_NRF24L01_INO
|
||||
#undef NCC1701_NRF24L01_INO
|
||||
#undef OMP_NRF24L01_INO
|
||||
#undef OMP_CC2500_INO // Use both CC2500 and NRF code
|
||||
#undef POTENSIC_NRF24L01_INO
|
||||
#undef PROPEL_NRF24L01_INO
|
||||
#undef Q303_NRF24L01_INO
|
||||
@@ -340,8 +358,12 @@
|
||||
#undef BAYANG_RX_NRF24L01_INO
|
||||
#undef DEVO_HUB_TELEMETRY
|
||||
#undef PROPEL_HUB_TELEMETRY
|
||||
#undef OMP_HUB_TELEMETRY
|
||||
#undef RLINK_HUB_TELEMETRY
|
||||
#undef DSM_RX_CYRF6936_INO
|
||||
#undef DSM_FWD_PGM
|
||||
#undef WFLY2_HUB_TELEMETRY
|
||||
#undef LOLI_HUB_TELEMETRY
|
||||
#else
|
||||
#if defined(MULTI_TELEMETRY) && defined(MULTI_STATUS)
|
||||
#error You should choose either MULTI_TELEMETRY or MULTI_STATUS but not both.
|
||||
@@ -368,6 +390,9 @@
|
||||
#if not defined(DEVO_CYRF6936_INO)
|
||||
#undef DEVO_HUB_TELEMETRY
|
||||
#endif
|
||||
#if not defined(OMP_CC2500_INO)
|
||||
#undef OMP_HUB_TELEMETRY
|
||||
#endif
|
||||
#if not defined(PROPEL_NRF24L01_INO)
|
||||
#undef PROPEL_HUB_TELEMETRY
|
||||
#endif
|
||||
@@ -407,10 +432,19 @@
|
||||
#if not defined(DSM_CYRF6936_INO)
|
||||
#undef DSM_TELEMETRY
|
||||
#endif
|
||||
#if not defined(MLINK_CYRF6936_INO)
|
||||
#undef MLINK_HUB_TELEMETRY
|
||||
#endif
|
||||
#if not defined(HOTT_CC2500_INO)
|
||||
#undef HOTT_FW_TELEMETRY
|
||||
#endif
|
||||
#if not defined(HOTT_FW_TELEMETRY) && not defined(DSM_TELEMETRY) && not defined(SPORT_TELEMETRY) && not defined(HUB_TELEMETRY) && not defined(HUBSAN_HUB_TELEMETRY) && not defined(BUGS_HUB_TELEMETRY) && not defined(NCC1701_HUB_TELEMETRY) && not defined(BAYANG_HUB_TELEMETRY) && not defined(CABELL_HUB_TELEMETRY) && not defined(RLINK_HUB_TELEMETRY) && not defined(AFHDS2A_HUB_TELEMETRY) && not defined(AFHDS2A_FW_TELEMETRY) && not defined(MULTI_TELEMETRY) && not defined(MULTI_STATUS) && not defined(HITEC_HUB_TELEMETRY) && not defined(HITEC_FW_TELEMETRY) && not defined(SCANNER_TELEMETRY) && not defined(FRSKY_RX_TELEMETRY) && not defined(AFHDS2A_RX_TELEMETRY) && not defined(BAYANG_RX_TELEMETRY) && not defined(DEVO_HUB_TELEMETRY) && not defined(PROPEL_HUB_TELEMETRY)
|
||||
#if not defined(WFLY2_A7105_INO)
|
||||
#undef WFLY2_HUB_TELEMETRY
|
||||
#endif
|
||||
#if not defined(LOLI_NRF24L01_INO)
|
||||
#undef LOLI_HUB_TELEMETRY
|
||||
#endif
|
||||
#if not defined(HOTT_FW_TELEMETRY) && not defined(DSM_TELEMETRY) && not defined(SPORT_TELEMETRY) && not defined(HUB_TELEMETRY) && not defined(HUBSAN_HUB_TELEMETRY) && not defined(BUGS_HUB_TELEMETRY) && not defined(NCC1701_HUB_TELEMETRY) && not defined(BAYANG_HUB_TELEMETRY) && not defined(CABELL_HUB_TELEMETRY) && not defined(RLINK_HUB_TELEMETRY) && not defined(AFHDS2A_HUB_TELEMETRY) && not defined(AFHDS2A_FW_TELEMETRY) && not defined(MULTI_TELEMETRY) && not defined(MULTI_STATUS) && not defined(HITEC_HUB_TELEMETRY) && not defined(HITEC_FW_TELEMETRY) && not defined(SCANNER_TELEMETRY) && not defined(FRSKY_RX_TELEMETRY) && not defined(AFHDS2A_RX_TELEMETRY) && not defined(BAYANG_RX_TELEMETRY) && not defined(DEVO_HUB_TELEMETRY) && not defined(PROPEL_HUB_TELEMETRY) && not defined(OMP_HUB_TELEMETRY) && not defined(WFLY2_HUB_TELEMETRY) && not defined(LOLI_HUB_TELEMETRY) && not defined(MLINK_HUB_TELEMETRY)
|
||||
#undef TELEMETRY
|
||||
#undef INVERT_TELEMETRY
|
||||
#undef MULTI_TELEMETRY
|
||||
|
||||
341
Multiprotocol/WFLY2_a7105.ino
Normal file
341
Multiprotocol/WFLY2_a7105.ino
Normal file
@@ -0,0 +1,341 @@
|
||||
/*
|
||||
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(WFLY2_A7105_INO)
|
||||
|
||||
#include "iface_a7105.h"
|
||||
|
||||
//#define WFLY2_FORCE_ID
|
||||
|
||||
//WFLY2 constants & variables
|
||||
#define WFLY2_BIND_COUNT 2777 // abort bind after 10sec
|
||||
#define WFLY2_PACKET_SIZE 32
|
||||
|
||||
enum{
|
||||
WFLY2_DATA,
|
||||
WFLY2_PLL_TX,
|
||||
WFLY2_RX,
|
||||
};
|
||||
|
||||
static void __attribute__((unused)) WFLY2_build_packet()
|
||||
{
|
||||
static uint16_t pseudo=0;
|
||||
|
||||
//End bind
|
||||
if(IS_BIND_IN_PROGRESS && bind_counter)
|
||||
{
|
||||
bind_counter--;
|
||||
if (bind_counter==0)
|
||||
{
|
||||
BIND_DONE;
|
||||
A7105_WriteID(MProtocol_id);
|
||||
rf_ch_num = 0;
|
||||
}
|
||||
}
|
||||
|
||||
memset(packet,0x00,WFLY2_PACKET_SIZE);
|
||||
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
//Header
|
||||
packet[0] = 0x0F; // Bind packet
|
||||
|
||||
//ID
|
||||
packet[1] = rx_tx_addr[3];
|
||||
packet[2] = rx_tx_addr[2];
|
||||
packet[3] = rx_tx_addr[1];
|
||||
//packet[4] = 0x00; // Should be rx_tx_addr[0]&0x0F but bind is already using 0x00 so ....
|
||||
|
||||
//Unknown
|
||||
packet[5] = 0x01;
|
||||
|
||||
//Freq
|
||||
rf_ch_num = (hopping_frequency_no<<1)+0x08;
|
||||
packet[6] = rf_ch_num;
|
||||
hopping_frequency_no++;
|
||||
if(hopping_frequency_no > 0x17) hopping_frequency_no=0x00;
|
||||
|
||||
//Unknown bytes 7..31
|
||||
}
|
||||
else
|
||||
{
|
||||
//Pseudo
|
||||
uint16_t high_bit=(pseudo & 0x8000) ^ 0x8000; // toggle 0x8000 every other line
|
||||
pseudo <<= 1; // *2
|
||||
if( (pseudo & 0x8000) || pseudo == 0 ) pseudo ^= 0x8A87; // Randomisation, pseudo==0 is a guess but would give the start value seen on the dump when P[2]P[1]=0 at init and will prevent a lock up
|
||||
pseudo |= high_bit; // include toggle
|
||||
packet[1] = pseudo;
|
||||
packet[2] = pseudo>>8;
|
||||
|
||||
//RF channel
|
||||
int8_t prev = rf_ch_num & 0x1F;
|
||||
rf_ch_num = (pseudo ^ (pseudo >> 7));
|
||||
rf_ch_num = ((rf_ch_num>>1)&0x08) | (rf_ch_num & 0x47);
|
||||
rf_ch_num = ((rf_ch_num>>2)&0x10) | (rf_ch_num & 0x1F);
|
||||
rf_ch_num ^= rx_tx_addr[3] & 0x1F;
|
||||
if(abs((int8_t)rf_ch_num-prev) <= 9)
|
||||
{
|
||||
if(high_bit)
|
||||
rf_ch_num |= 0x20;
|
||||
}
|
||||
else
|
||||
if(!high_bit)
|
||||
rf_ch_num |= 0x20;
|
||||
|
||||
//Partial ID
|
||||
packet[3] = rx_tx_addr[3];
|
||||
packet[4] = rx_tx_addr[2] & 0x03;
|
||||
|
||||
//Header
|
||||
if(prev_option!=option)
|
||||
{//Set the RX PPM/WBUS on change
|
||||
packet[0] = 0x05; //PPM/WBUS packet
|
||||
packet[5] = 0x01;
|
||||
if(option)
|
||||
packet[6] = 0x01; // PPM
|
||||
else
|
||||
packet[6] = 0x00; // WBUS
|
||||
prev_option = option;
|
||||
}
|
||||
else
|
||||
{//Normal or Failsafe packets
|
||||
uint8_t offset=0;
|
||||
|
||||
//packet[0] = 0x00; // Normal packet
|
||||
|
||||
#ifdef FAILSAFE_ENABLE
|
||||
#define WFLY2_NUM_FS_PKTS 2 //the original TX sends 4 but that's not needed...
|
||||
if(IS_FAILSAFE_VALUES_on && packet_sent >= WFLY2_NUM_FS_PKTS) //Failsafe packet arrived from radio
|
||||
packet_sent = 0; // send FS config packets
|
||||
|
||||
if(packet_sent < WFLY2_NUM_FS_PKTS)
|
||||
{// Send failsafe packets
|
||||
packet[0] = 0x01; //Failsafe packet
|
||||
packet[5] = 0x08 | packet_sent;
|
||||
/*if(packet_sent > 1) // needed when more than 2 FS packets are sent
|
||||
{
|
||||
packet[5] |= 0x50; // all channels in failsafe
|
||||
packet[6] = 0x55; // all channels in failsafe
|
||||
}
|
||||
else*/
|
||||
{
|
||||
uint8_t val=0;
|
||||
for(uint8_t i = 0; i < 6; i++)
|
||||
{
|
||||
val >>= 2;
|
||||
if(Failsafe_data[i+packet_sent*6] == FAILSAFE_CHANNEL_NOPULSES) //no pulse value = 2
|
||||
val |= 0x80;
|
||||
else if(Failsafe_data[i+packet_sent*6] != FAILSAFE_CHANNEL_HOLD) //hold value = 0
|
||||
val |= 0x40; //fs value = 1
|
||||
//debug("ch%d=%04X, val=%02X | ",i+1+packet_sent*6, Failsafe_data[i+packet_sent*6],val);
|
||||
if(i==1)
|
||||
packet[5] |= val;
|
||||
}
|
||||
packet[6] = val;
|
||||
}
|
||||
offset=2;
|
||||
packet_sent++;
|
||||
//debugln("5=%02X, 6=%02X", packet[5], packet[6]);
|
||||
}
|
||||
#endif
|
||||
|
||||
//10 channels -100%=0x2C1...0%=0x800...+100%=0xD3F
|
||||
for(uint8_t i = 0; i < 5; i++)
|
||||
{
|
||||
uint16_t temp=convert_channel_16b_nolimit(i*2 , 0x2C1, 0xD3F, IS_FAILSAFE_VALUES_on);
|
||||
packet[5 + offset + i*3] = temp&0xFF; // low byte
|
||||
packet[7 + offset + i*3] = (temp>>8)&0x0F; // high byte
|
||||
temp=convert_channel_16b_nolimit(i*2+1, 0x2C1, 0xD3F, IS_FAILSAFE_VALUES_on);
|
||||
packet[6 + offset + i*3] = temp&0xFF; // low byte
|
||||
packet[7 + offset + i*3] |= (temp>>4)&0xF0; // high byte
|
||||
}
|
||||
|
||||
#ifdef FAILSAFE_ENABLE
|
||||
if(packet_sent >= WFLY2_NUM_FS_PKTS)
|
||||
FAILSAFE_VALUES_off;
|
||||
#endif
|
||||
|
||||
//Unknown bytes 20+offset..31
|
||||
}
|
||||
}
|
||||
|
||||
//Debug
|
||||
#if 0
|
||||
debug("ch=%02X,%02X P=",rf_ch_num,(rf_ch_num<<1)+0x10);
|
||||
for(uint8_t i=0; i<WFLY2_PACKET_SIZE; i++)
|
||||
debug("%02X ", packet[i]);
|
||||
debugln("");
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef WFLY2_HUB_TELEMETRY
|
||||
static void __attribute__((unused)) WFLY2_Send_Telemetry()
|
||||
{
|
||||
//Incoming packet values
|
||||
v_lipo1=packet[3]<<1; // RX_batt *10 in V
|
||||
v_lipo2=packet[5]<<1; // Ext_batt*10 in V
|
||||
RX_RSSI=(255-packet[7])>>1; // Looks to be the RX RSSI value direct from A7105
|
||||
|
||||
// Read TX RSSI
|
||||
TX_RSSI=255-A7105_ReadReg(A7105_1D_RSSI_THOLD);
|
||||
|
||||
telemetry_counter++; // LQI counter
|
||||
telemetry_link=1;
|
||||
if(telemetry_lost)
|
||||
{
|
||||
telemetry_lost = 0;
|
||||
packet_count = 100;
|
||||
telemetry_counter = 100;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#define WFLY2_PACKET_PERIOD 3600 //3600
|
||||
#define WFLY2_BUFFER_TIME 1500 //1500
|
||||
#define WFLY2_WRITE_TIME 800 //942
|
||||
|
||||
uint16_t ReadWFLY2()
|
||||
{
|
||||
uint16_t start;
|
||||
uint8_t status;
|
||||
|
||||
#ifndef FORCE_WFLY2_TUNING
|
||||
A7105_AdjustLOBaseFreq(1);
|
||||
#endif
|
||||
switch(phase)
|
||||
{
|
||||
case WFLY2_DATA:
|
||||
#ifdef MULTI_SYNC
|
||||
telemetry_set_input_sync(WFLY2_PACKET_PERIOD);
|
||||
#endif
|
||||
//Build data packet
|
||||
WFLY2_build_packet();
|
||||
|
||||
//Fill the TX buffer without sending
|
||||
A7105_WriteData(WFLY2_PACKET_SIZE,0);
|
||||
|
||||
#ifdef WFLY2_HUB_TELEMETRY
|
||||
//LQI calculation
|
||||
packet_count++;
|
||||
if(packet_count>=100)
|
||||
{
|
||||
packet_count=0;
|
||||
TX_LQI=telemetry_counter;
|
||||
if(telemetry_counter==0)
|
||||
telemetry_lost = 1;
|
||||
telemetry_counter = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
phase++; // WFLY2_PLL_TX
|
||||
return WFLY2_BUFFER_TIME;
|
||||
|
||||
case WFLY2_PLL_TX:
|
||||
//Check RX status
|
||||
status=A7105_ReadReg(A7105_00_MODE);
|
||||
//debugln("S:%02X", status);
|
||||
|
||||
//PLL
|
||||
A7105_Strobe(A7105_PLL);
|
||||
|
||||
//Read incoming packet even if bad/not present to not change too much the TX timing, might want to reorg the code...
|
||||
A7105_ReadData(WFLY2_PACKET_SIZE);
|
||||
|
||||
//Read telemetry
|
||||
if((status & 0x21)==0)
|
||||
{ // Packet received and CRC OK
|
||||
//Debug
|
||||
#if 0
|
||||
debug("T:");
|
||||
for(uint8_t i=0; i<WFLY2_PACKET_SIZE-20; i++) // Can't send the full telemetry at full speed
|
||||
debug(" %02X", packet[i]);
|
||||
debugln("");
|
||||
#endif
|
||||
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
if(packet[0]==0x0F && packet[1]==rx_tx_addr[3] && packet[2]==rx_tx_addr[2] && packet[3]==rx_tx_addr[1] && packet[4]==0x00)
|
||||
{
|
||||
bind_counter=1; // End bind
|
||||
debugln("Bind done");
|
||||
//packet[5..7] contains the RXID
|
||||
}
|
||||
}
|
||||
#ifdef WFLY2_HUB_TELEMETRY
|
||||
else
|
||||
if(packet[0]==0 && packet[1]==rx_tx_addr[3] && packet[2]==(rx_tx_addr[2] & 0x03))
|
||||
{//Packet match the ID
|
||||
WFLY2_Send_Telemetry(); // Packet looks good do send telem to the radio
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//Change RF channel
|
||||
A7105_WriteReg(A7105_0F_PLL_I, (rf_ch_num<<1)+0x10);
|
||||
|
||||
//Switch to TX
|
||||
A7105_SetPower();
|
||||
A7105_SetTxRxMode(TX_EN);
|
||||
A7105_Strobe(A7105_TX);
|
||||
|
||||
phase++; // WFLY2_RX
|
||||
return WFLY2_WRITE_TIME;
|
||||
|
||||
case WFLY2_RX:
|
||||
//Wait for TX completion
|
||||
start=micros();
|
||||
while ((uint16_t)((uint16_t)micros()-start) < 700) // Wait max 700µs
|
||||
if(!(A7105_ReadReg(A7105_00_MODE) & 0x01))
|
||||
break;
|
||||
|
||||
//Switch to RX
|
||||
A7105_SetTxRxMode(RX_EN);
|
||||
A7105_Strobe(A7105_RX);
|
||||
|
||||
phase = WFLY2_DATA;
|
||||
return WFLY2_PACKET_PERIOD-WFLY2_WRITE_TIME-WFLY2_BUFFER_TIME;
|
||||
}
|
||||
return WFLY2_PACKET_PERIOD; // never reached, please the compiler
|
||||
}
|
||||
|
||||
uint16_t initWFLY2()
|
||||
{
|
||||
A7105_Init();
|
||||
|
||||
#ifdef WFLY2_FORCE_ID
|
||||
MProtocol_id = 0x50002313; //Richard
|
||||
//MProtocol_id = 0x50000223; //Pascal
|
||||
#endif
|
||||
MProtocol_id &= 0x00FFFFFF; // Since the bind ID starts with 50, let's keep only the last 3 bytes of the ID
|
||||
MProtocol_id |= 0x50000000; // As recommended on the A7105 datasheet
|
||||
set_rx_tx_addr(MProtocol_id); // Update the ID
|
||||
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
A7105_WriteID(0x50FFFFFE); // Bind ID
|
||||
else
|
||||
A7105_WriteID(MProtocol_id);
|
||||
|
||||
hopping_frequency_no=0;
|
||||
rf_ch_num = 0;
|
||||
bind_counter = WFLY2_BIND_COUNT;
|
||||
packet_sent = 255;
|
||||
phase = WFLY2_DATA;
|
||||
#ifdef WFLY2_HUB_TELEMETRY
|
||||
packet_count = 0;
|
||||
telemetry_lost = 1;
|
||||
#endif
|
||||
return 2000;
|
||||
}
|
||||
#endif
|
||||
@@ -105,23 +105,23 @@ static uint16_t __attribute__((unused)) WFLY_send_data_packet()
|
||||
len=4;
|
||||
for(uint8_t i=0;i<3;i++)
|
||||
{ // Channels
|
||||
uint16_t ch = convert_channel_16b_nolimit(i*4+0,151,847);
|
||||
uint16_t ch = convert_channel_16b_nolimit(i*4+0,151,847,false);
|
||||
uint8_t offset=i*5;
|
||||
packet[3+offset]|=ch<<6;
|
||||
packet[4+offset]=ch>>2;
|
||||
len++;
|
||||
if(--nbr_ch==0) break;
|
||||
ch = convert_channel_16b_nolimit(i*4+1,151,847);
|
||||
ch = convert_channel_16b_nolimit(i*4+1,151,847,false);
|
||||
packet[5+offset]=ch;
|
||||
packet[6+offset]=ch>>8;
|
||||
len+=2;
|
||||
if(--nbr_ch==0) break;
|
||||
ch = convert_channel_16b_nolimit(i*4+2,151,847);
|
||||
ch = convert_channel_16b_nolimit(i*4+2,151,847,false);
|
||||
packet[6+offset]|=ch<<2;
|
||||
packet[7+offset]=ch>>6;
|
||||
len++;
|
||||
if(--nbr_ch==0) break;
|
||||
ch = convert_channel_16b_nolimit(i*4+3,151,847);
|
||||
ch = convert_channel_16b_nolimit(i*4+3,151,847,false);
|
||||
packet[7+offset]|=ch<<4;
|
||||
packet[8+offset]=ch>>4;
|
||||
len++;
|
||||
|
||||
@@ -79,7 +79,7 @@ static void __attribute__((unused)) WK_build_bind_pkt(const uint8_t *init)
|
||||
|
||||
static int16_t __attribute__((unused)) WK_get_channel(uint8_t ch, int32_t scale, int16_t center, int16_t range)
|
||||
{
|
||||
int16_t value = convert_channel_16b_nolimit(CH_AETR[ch],-scale,scale)+center;
|
||||
int16_t value = convert_channel_16b_nolimit(CH_AETR[ch],-scale,scale,false)+center;
|
||||
if (value < center - range) value = center - range;
|
||||
if (value > center + range) value = center + range;
|
||||
return value;
|
||||
@@ -451,7 +451,7 @@ uint16_t WK_cb()
|
||||
}
|
||||
packet_sent = 0;
|
||||
uint8_t start=micros();
|
||||
while ((uint8_t)micros()-start < 100) // Wait max 100µs
|
||||
while ((uint8_t)((uint8_t)micros()-start) < 100) // Wait max 100µs
|
||||
if(CYRF_ReadRegister(CYRF_04_TX_IRQ_STATUS) & 0x02)
|
||||
break;
|
||||
if((packet_count & 0x03) == 0)
|
||||
@@ -477,7 +477,6 @@ uint16_t WK_setup()
|
||||
packet_count = 0;
|
||||
packet_sent = 0;
|
||||
WK_last_beacon = 0;
|
||||
prev_option=option;
|
||||
if(sub_protocol!=WK2801 || option==0)
|
||||
{
|
||||
CYRF_GetMfgData(cyrfmfg_id);
|
||||
|
||||
@@ -29,7 +29,16 @@ Multiprotocol is distributed in the hope that it will be useful,
|
||||
|
||||
static uint16_t __attribute__((unused)) XK_convert_channel(uint8_t num)
|
||||
{
|
||||
uint16_t val=convert_channel_10b(num);
|
||||
uint16_t val;
|
||||
if(num==RUDDER)
|
||||
{// introduce deadband on rudder to prevent twitching
|
||||
//debug("RUD:%d",val);
|
||||
val=convert_channel_8b_limit_deadband(RUDDER,0x00,0x80, 0xFF, 40)<<2;
|
||||
//debugln(",%d",val);
|
||||
}
|
||||
else
|
||||
val=convert_channel_10b(num, false);
|
||||
|
||||
// 1FF..01=left, 00=center, 200..3FF=right
|
||||
if(val==0x200)
|
||||
val=0; // 0
|
||||
@@ -56,18 +65,18 @@ static void __attribute__((unused)) XK_send_packet()
|
||||
packet[14] = 0xC0;
|
||||
else
|
||||
{
|
||||
uint16_t val=convert_channel_10b(THROTTLE);
|
||||
uint16_t val=convert_channel_10b(THROTTLE, false);
|
||||
packet[0] = val>>2; // 0..255
|
||||
//packet[12] |= val & 2;
|
||||
packet[12] |= val & 2;
|
||||
val=XK_convert_channel(RUDDER);
|
||||
packet[1] = val>>2;
|
||||
//packet[12] |= (val & 2)<<2;
|
||||
packet[12] |= (val & 2)<<2;
|
||||
val=XK_convert_channel(ELEVATOR);
|
||||
packet[2] = val>>2;
|
||||
//packet[13] |= val & 2;
|
||||
packet[13] |= val & 2;
|
||||
val=XK_convert_channel(AILERON);
|
||||
packet[3] = val>>2;
|
||||
//packet[13] |= (val & 2)<<2;
|
||||
packet[13] |= (val & 2)<<2;
|
||||
|
||||
memset(&packet[4],0x40,3); // Trims
|
||||
|
||||
@@ -84,6 +93,7 @@ static void __attribute__((unused)) XK_send_packet()
|
||||
|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
|
||||
//debugln("P1:%02X,P12:%02X",packet[1],packet[12]);
|
||||
}
|
||||
|
||||
crc=packet[0];
|
||||
|
||||
@@ -92,7 +92,7 @@ static boolean __attribute__((unused)) XN297Dump_process_packet(void)
|
||||
// address
|
||||
for (uint8_t i = 0; i < address_length; i++)
|
||||
{
|
||||
crc = crc16_update(crc, packet[i], 8);
|
||||
crc16_update( packet[i], 8);
|
||||
packet_un[address_length-1-i]=packet[i];
|
||||
packet_sc[address_length-1-i]=packet[i] ^ xn297_scramble[i];
|
||||
}
|
||||
@@ -100,7 +100,7 @@ static boolean __attribute__((unused)) XN297Dump_process_packet(void)
|
||||
// payload
|
||||
for (uint8_t i = address_length; i < XN297DUMP_MAX_PACKET_LEN-XN297DUMP_CRC_LENGTH; i++)
|
||||
{
|
||||
crc = crc16_update(crc, packet[i], 8);
|
||||
crc16_update( packet[i], 8);
|
||||
packet_sc[i] = bit_reverse(packet[i]^xn297_scramble[i]);
|
||||
packet_un[i] = bit_reverse(packet[i]);
|
||||
// check crc
|
||||
@@ -125,14 +125,13 @@ static boolean __attribute__((unused)) XN297Dump_process_packet(void)
|
||||
//Try enhanced payload
|
||||
crc = 0xb5d2;
|
||||
packet_length=0;
|
||||
uint16_t crc_enh;
|
||||
for (uint8_t i = 0; i < XN297DUMP_MAX_PACKET_LEN-XN297DUMP_CRC_LENGTH; i++)
|
||||
{
|
||||
packet_sc[i]=packet[i]^xn297_scramble[i];
|
||||
crc = crc16_update(crc, packet[i], 8);
|
||||
crc_enh = crc16_update(crc, packet[i+1] & 0xC0, 2);
|
||||
crc16_update( packet[i], 8);
|
||||
crc16_update( packet[i+1] & 0xC0, 2);
|
||||
crcxored=(packet[i+1]<<10)|(packet[i+2]<<2)|(packet[i+3]>>6) ;
|
||||
if((crc_enh ^ pgm_read_word(&xn297_crc_xorout_scrambled_enhanced[i - 3])) == crcxored)
|
||||
if((crc ^ pgm_read_word(&xn297_crc_xorout_scrambled_enhanced[i - 3])) == crcxored)
|
||||
{ // Found a valid CRC for the enhanced payload mode
|
||||
packet_length=i;
|
||||
scramble=true;
|
||||
@@ -141,7 +140,7 @@ static boolean __attribute__((unused)) XN297Dump_process_packet(void)
|
||||
memcpy(packet_un,packet_sc,packet_length+2); // unscramble packet
|
||||
break;
|
||||
}
|
||||
if((crc_enh ^ pgm_read_word(&xn297_crc_xorout_enhanced[i - 3])) == crcxored)
|
||||
if((crc ^ pgm_read_word(&xn297_crc_xorout_enhanced[i - 3])) == crcxored)
|
||||
{ // Found a valid CRC for the enhanced payload mode
|
||||
packet_length=i;
|
||||
scramble=false;
|
||||
@@ -628,11 +627,11 @@ static uint16_t XN297Dump_callback()
|
||||
{
|
||||
if(phase==0)
|
||||
{
|
||||
address_length=5;
|
||||
memcpy(rx_tx_addr, (uint8_t *)"\xC9\x59\xD2\x65\x34", 5);
|
||||
bitrate=XN297DUMP_250K;
|
||||
packet_length=16;
|
||||
hopping_frequency_no=0x03;
|
||||
address_length=4;
|
||||
memcpy(rx_tx_addr, (uint8_t *)"\x5A\x20\x12\xAC", address_length); //"\xA3\x05\x22\xC1"
|
||||
bitrate=XN297DUMP_1M;
|
||||
packet_length=32;
|
||||
hopping_frequency_no=60; //bind ?, normal 60
|
||||
|
||||
NRF24L01_Initialize();
|
||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||
@@ -669,7 +668,7 @@ static uint16_t XN297Dump_callback()
|
||||
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x01);
|
||||
NRF24L01_Activate(0x73);
|
||||
NRF24L01_SetPower();
|
||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP) | _BV(NRF24L01_00_PRIM_RX));
|
||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_PWR_UP) | _BV(NRF24L01_00_PRIM_RX)); //_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) |
|
||||
phase++;
|
||||
}
|
||||
else
|
||||
@@ -679,21 +678,66 @@ static uint16_t XN297Dump_callback()
|
||||
if(NRF24L01_ReadReg(NRF24L01_09_CD))
|
||||
{
|
||||
NRF24L01_ReadPayload(packet, packet_length);
|
||||
if(memcmp(packet_in,packet,packet_length))
|
||||
bool ok=true;
|
||||
uint8_t buffer[40];
|
||||
memcpy(buffer,packet,packet_length);
|
||||
if(memcmp(&packet_in[0],&packet[0],packet_length))
|
||||
{
|
||||
debug("P:");
|
||||
for(uint8_t i=0;i<packet_length;i++)
|
||||
debug(" %02X",packet[i]);
|
||||
debugln("");
|
||||
memcpy(packet_in,packet,packet_length);
|
||||
//realign bits
|
||||
for(uint8_t i=0; i<packet_length; i++)
|
||||
buffer[i]=buffer[i+2];
|
||||
//for(uint8_t i=0; i<packet_length; i++)
|
||||
// buffer[i]=(buffer[i]<<4)+(buffer[i+1]>>4);
|
||||
|
||||
//check for validity and decode
|
||||
memset(packet_in,0,packet_length);
|
||||
for(uint8_t i=0; i<packet_length-2; i++)
|
||||
{
|
||||
for(uint8_t j=0;j<2;j++)
|
||||
{
|
||||
packet_in[i>>2] >>= 1;
|
||||
if( (buffer[i]&0xC0) == 0xC0 && (buffer[i]&0x30) == 0x00 )
|
||||
packet_in[i>>2] |= 0x80;
|
||||
else if( (buffer[i]&0xC0) == 0x00 && (buffer[i]&0x30) == 0x30 )
|
||||
packet_in[i>>2] |= 0x00;
|
||||
else
|
||||
ok=false; // error
|
||||
buffer[i] <<= 4;
|
||||
}
|
||||
}
|
||||
if(ok)
|
||||
{
|
||||
debug("P:(%02X,%02X):",packet[0],packet[1]);
|
||||
for(uint8_t i=0;i<packet_length/4;i++)
|
||||
debug(" %02X",packet_in[i]);
|
||||
debugln("");
|
||||
memcpy(packet_in,packet,packet_length);
|
||||
}
|
||||
}
|
||||
/*crc=0;
|
||||
for (uint8_t i = 1; i < 12; ++i)
|
||||
crc16_update( packet[i], 8);
|
||||
if(packet[12]==((crc>>8)&0xFF) && packet[13]==(crc&0xFF))
|
||||
if(memcmp(&packet_in[1],&packet[1],packet_length-1))
|
||||
{
|
||||
debug("P:");
|
||||
for(uint8_t i=0;i<packet_length;i++)
|
||||
debug(" %02X",packet[i]);
|
||||
debug(" CRC: %04X",crc);
|
||||
debugln("");
|
||||
debug("P(%02X):",packet[0]);
|
||||
for(uint8_t i=1;i<packet_length-2;i++)
|
||||
debug(" %02X",((bit_reverse(packet[i])<<1)|(bit_reverse(packet[i-1])>>7))&0xFF);
|
||||
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();
|
||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP) | _BV(NRF24L01_00_PRIM_RX));
|
||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_PWR_UP) | _BV(NRF24L01_00_PRIM_RX)); // _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) |
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
//#define ORANGE_TX_BLUE
|
||||
|
||||
/** CC2500 Fine Frequency Tuning **/
|
||||
//For optimal performance the CC2500 RF module used by the CORONA, FrSkyD, FrSkyV, FrSkyX, Hitec, HoTT, SFHSS and Redpine protocols needs to be tuned for each protocol.
|
||||
//For optimal performance the CC2500 RF module used by the CORONA, FrSkyD, FrSkyV, FrSkyX, Hitec, HoTT, Futaba/SFHSS and Redpine protocols needs to be tuned for each protocol.
|
||||
//Initial tuning should be done via the radio menu with a genuine CORONA/FrSky/Hitec/HoTT/Futaba/Redpine receiver.
|
||||
//Once a good tuning value is found it can be set here and will override the radio's 'option' setting for all existing and new models which use that protocol.
|
||||
//For more information: https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/tree/master/docs/Frequency_Tuning.md
|
||||
@@ -104,7 +104,7 @@
|
||||
//#define FORCE_HOTT_TUNING 0
|
||||
//#define FORCE_RADIOLINK_TUNING 0
|
||||
//#define FORCE_REDPINE_TUNING 0
|
||||
//#define FORCE_SFHSS_TUNING 0
|
||||
//#define FORCE_FUTABA_TUNING 0
|
||||
//#define FORCE_SKYARTEC_TUNING 0
|
||||
|
||||
/** A7105 Fine Frequency Tuning **/
|
||||
@@ -122,6 +122,7 @@
|
||||
//#define FORCE_HUBSAN_TUNING 0
|
||||
//#define FORCE_KYOSHO_TUNING 0
|
||||
//#define FORCE_PELIKAN_TUNING 0
|
||||
//#define FORCE_WFLY2_TUNING 0
|
||||
|
||||
/** CYRF6936 Fine Frequency Tuning **/
|
||||
//This is required in rare cases where some CYRF6936 modules and/or RXs have an inaccurate crystal oscillator.
|
||||
@@ -172,21 +173,26 @@
|
||||
#define FLYSKY_A7105_INO
|
||||
#define HEIGHT_A7105_INO
|
||||
#define HUBSAN_A7105_INO
|
||||
#define KYOSHO_A7105_INO
|
||||
#define KYOSHO_A7105_INO
|
||||
#define PELIKAN_A7105_INO
|
||||
#define WFLY2_A7105_INO
|
||||
|
||||
//The protocols below need a CYRF6936 to be installed
|
||||
#define DEVO_CYRF6936_INO
|
||||
#define DSM_CYRF6936_INO
|
||||
#define DSM_RX_CYRF6936_INO
|
||||
#define E010R5_CYRF6936_INO
|
||||
#define E129_CYRF6936_INO
|
||||
#define J6PRO_CYRF6936_INO
|
||||
#define MLINK_CYRF6936_INO
|
||||
#define TRAXXAS_CYRF6936_INO
|
||||
#define WFLY_CYRF6936_INO
|
||||
#define WK2x01_CYRF6936_INO
|
||||
|
||||
//The protocols below need a CC2500 to be installed
|
||||
#define CORONA_CC2500_INO
|
||||
#define ESKY150V2_CC2500_INO //Need both CC2500 and NRF
|
||||
#define E016HV2_CC2500_INO
|
||||
#define ESKY150V2_CC2500_INO
|
||||
#define FRSKYL_CC2500_INO
|
||||
#define FRSKYD_CC2500_INO
|
||||
#define FRSKYV_CC2500_INO
|
||||
@@ -195,7 +201,7 @@
|
||||
#define HITEC_CC2500_INO
|
||||
#define HOTT_CC2500_INO
|
||||
#define SCANNER_CC2500_INO
|
||||
#define SFHSS_CC2500_INO
|
||||
#define FUTABA_CC2500_INO
|
||||
#define SKYARTEC_CC2500_INO
|
||||
#define REDPINE_CC2500_INO
|
||||
#define RLINK_CC2500_INO
|
||||
@@ -224,10 +230,11 @@
|
||||
#define JJRC345_NRF24L01_INO
|
||||
#define KF606_NRF24L01_INO
|
||||
#define KN_NRF24L01_INO
|
||||
#define LOLI_NRF24L01_INO
|
||||
#define MJXQ_NRF24L01_INO
|
||||
#define MT99XX_NRF24L01_INO
|
||||
#define NCC1701_NRF24L01_INO
|
||||
#define OMP_NRF24L01_INO
|
||||
#define OMP_CC2500_INO //Need both CC2500 and NRF
|
||||
#define POTENSIC_NRF24L01_INO
|
||||
#define PROPEL_NRF24L01_INO
|
||||
#define Q303_NRF24L01_INO
|
||||
@@ -262,6 +269,9 @@
|
||||
// For example, a value of -80% applied on channel 14 will instantly kill the motors on the X-Vert.
|
||||
#define DSM_THROTTLE_KILL_CH 14
|
||||
|
||||
//Enable DSM Forward Programming
|
||||
#define DSM_FWD_PGM
|
||||
|
||||
//AFHDS2A specific settings
|
||||
//-------------------------
|
||||
//When enabled (remove the "//"), the below setting makes LQI (Link Quality Indicator) available on one of the RX ouput channel (5-14).
|
||||
@@ -270,7 +280,7 @@
|
||||
/**************************/
|
||||
/*** FAILSAFE SETTINGS ***/
|
||||
/**************************/
|
||||
//The following protocols are supporting failsafe: FrSkyX, Devo, WK2x01, SFHSS, HISKY/HK310 and AFHDS2A
|
||||
//The following protocols are supporting failsafe: FrSkyX, Devo, WK2x01, Futaba/SFHSS, HISKY/HK310 and AFHDS2A
|
||||
//In Serial mode failsafe is configured on the radio itself.
|
||||
//In PPM mode and only after the module is up and fully operational, press the bind button for at least 5sec to send the current stick positions as failsafe to the RX.
|
||||
//If you want to disable failsafe globally comment the line below using "//".
|
||||
@@ -315,9 +325,13 @@
|
||||
#define DEVO_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
|
||||
#define HUBSAN_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
|
||||
#define NCC1701_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
|
||||
#define OMP_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
|
||||
#define PROPEL_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
|
||||
#define CABELL_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
|
||||
#define RLINK_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
|
||||
#define WFLY2_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
|
||||
#define LOLI_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
|
||||
#define MLINK_HUB_TELEMETRY // Use FrSkyD Hub format to send telemetry to TX
|
||||
#define HITEC_HUB_TELEMETRY // Use FrSkyD Hub format to send basic telemetry to the radios which can decode it like er9x, erskyTX and OpenTX
|
||||
#define HITEC_FW_TELEMETRY // Forward received telemetry packets to be decoded by erskyTX and OpenTX
|
||||
#define SCANNER_TELEMETRY // Forward spectrum scanner data to TX
|
||||
@@ -402,7 +416,7 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
|
||||
/* 5 */ {PROTO_AFHDS2A, PWM_IBUS , 3 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 }, // RX number 3
|
||||
/* 6 */ {PROTO_AFHDS2A, PWM_IBUS , 2 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 }, // RX number 4
|
||||
/* 7 */ {PROTO_AFHDS2A, PWM_IBUS , 3 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 }, // RX number 5
|
||||
/* 8 */ {PROTO_SFHSS, H107 , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||
/* 8 */ {PROTO_FUTABA, NONE , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 }, // option=fine freq tuning
|
||||
/* 9 */ {PROTO_FRSKYV, NONE , 0 , P_HIGH , NO_AUTOBIND , 40 , 0x00000000 }, // option=fine freq tuning
|
||||
/* 10 */ {PROTO_FRSKYD, NONE , 0 , P_HIGH , NO_AUTOBIND , 40 , 0x00000000 }, // option=fine freq tuning
|
||||
/* 11 */ {PROTO_FRSKYX, CH_16 , 0 , P_HIGH , NO_AUTOBIND , 40 , 0x00000000 }, // option=fine freq tuning
|
||||
@@ -564,10 +578,16 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
|
||||
DSMX_11
|
||||
PROTO_DSM_RX
|
||||
NONE
|
||||
PROTO_E010R5
|
||||
NONE
|
||||
PROTO_E016HV2
|
||||
NONE
|
||||
PROTO_E01X
|
||||
E012
|
||||
E015
|
||||
E016H
|
||||
PROTO_E129
|
||||
NONE
|
||||
PROTO_ESKY
|
||||
ESKY_STD
|
||||
ESKY_ET4
|
||||
@@ -660,13 +680,17 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
|
||||
PROTO_J6PRO
|
||||
NONE
|
||||
PROTO_JJRC345
|
||||
NONE
|
||||
JJRC345
|
||||
SKYTMBLR
|
||||
PROTO_KF606
|
||||
NONE
|
||||
PROTO_KN
|
||||
WLTOYS
|
||||
FEILUN
|
||||
PROTO_KYOSHO
|
||||
KYOSHO_FHSS
|
||||
KYOSHO_HYPE
|
||||
PROTO_LOLI
|
||||
NONE
|
||||
PROTO_MJXQ
|
||||
WLH08
|
||||
@@ -676,6 +700,8 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
|
||||
E010
|
||||
H26WH
|
||||
PHOENIX
|
||||
PROTO_MLINK
|
||||
NONE
|
||||
PROTO_MT99XX
|
||||
MT99
|
||||
H7
|
||||
@@ -710,10 +736,12 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
|
||||
RED_FAST
|
||||
RED_SLOW
|
||||
PROTO_RLINK
|
||||
NONE
|
||||
RLINK_SURFACE
|
||||
RLINK_AIR
|
||||
RLINK_DUMBORC
|
||||
PROTO_SCANNER
|
||||
NONE
|
||||
PROTO_SFHSS
|
||||
PROTO_FUTABA
|
||||
NONE
|
||||
PROTO_SHENQI
|
||||
NONE
|
||||
@@ -744,6 +772,8 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
|
||||
V911S_E119
|
||||
PROTO_WFLY
|
||||
NONE
|
||||
PROTO_WFLY2
|
||||
NONE
|
||||
PROTO_WK2x01
|
||||
WK2801
|
||||
WK2401
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
/* 5 */ {PROTO_AFHDS2A, PWM_IBUS , 3 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 }, // RX number 3
|
||||
/* 6 */ {PROTO_AFHDS2A, PWM_IBUS , 2 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 }, // RX number 4
|
||||
/* 7 */ {PROTO_AFHDS2A, PWM_IBUS , 3 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 }, // RX number 5
|
||||
/* 8 */ {PROTO_SFHSS, H107 , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||
/* 8 */ {PROTO_HUBSAN, H107 , 0 , P_HIGH , NO_AUTOBIND , 0 , 0x00000000 },
|
||||
/* 9 */ {PROTO_FRSKYV, NONE , 0 , P_HIGH , NO_AUTOBIND , 40 , 0x00000000 }, // option=fine freq tuning
|
||||
/* 10 */ {PROTO_FRSKYD, NONE , 0 , P_HIGH , NO_AUTOBIND , 40 , 0x00000000 }, // option=fine freq tuning
|
||||
/* 11 */ {PROTO_FRSKYX, CH_16 , 0 , P_HIGH , NO_AUTOBIND , 40 , 0x00000000 }, // option=fine freq tuning
|
||||
|
||||
14
Multiprotocol/iface_rf2500.h
Normal file
14
Multiprotocol/iface_rf2500.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef _IFACE_RF2500_H_
|
||||
#define _IFACE_RF2500_H_
|
||||
|
||||
#include "iface_cyrf6936.h"
|
||||
|
||||
//RF2500
|
||||
static void __attribute__((unused)) RF2500_Init(uint8_t, bool);
|
||||
static void __attribute__((unused)) RF2500_SetTXAddr(const uint8_t*);
|
||||
static void __attribute__((unused)) RF2500_BuildPayload(uint8_t*);
|
||||
static void __attribute__((unused)) RF2500_SendPayload();
|
||||
#define RF2500_SetPower() CYRF_GFSK1M_SetPower()
|
||||
#define RF2500_RFChannel(X) CYRF_ConfigRFChannel(X)
|
||||
|
||||
#endif
|
||||
@@ -76,10 +76,13 @@ CFlie|38|CFlie||||||||NRF24L01|
|
||||
[DM002](Protocols_Details.md#DM002---33)|33|DM002||||||||NRF24L01|XN297
|
||||
[DSM](Protocols_Details.md#DSM---6)|6|DSM2_1F|DSM2_2F|DSMX_1F|DSMX_2F|AUTO||||CYRF6936|
|
||||
[DSM_RX](Protocols_Details.md#DSM_RX---70)|70|RX||||||||CYRF6936|
|
||||
[E010R5](Protocols_Details.md#E010R5---81)|81|||||||||CYRF6936/NRF24L01|RF2500
|
||||
[E016HV2](Protocols_Details.md#E016HV2---80)|80|||||||||CC2500/NRF24L01|unknown
|
||||
[E01X](Protocols_Details.md#E01X---45)|45|E012|E015|E016H||||||NRF24L01|XN297/HS6200
|
||||
[E129](Protocols_Details.md#E129---83)|83|||||||||CYRF6936/NRF24L01|RF2500
|
||||
[ESky](Protocols_Details.md#ESKY---16)|16|ESky|ET4|||||||NRF24L01|
|
||||
[ESky150](Protocols_Details.md#ESKY150---35)|35|ESKY150||||||||NRF24L01|
|
||||
[ESky150V2](Protocols_Details.md#ESKY150V2---69)|69|ESky150V2||||||||CC2500|NRF24L01
|
||||
[ESky150V2](Protocols_Details.md#ESKY150V2---69)|69|ESky150V2||||||||CC2500|NRF51822
|
||||
[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|PWM_IBUS16|PPM_IBUS16|||A7105|
|
||||
[Flysky AFHDS2A RX](Protocols_Details.md#FLYSKY-AFHDS2A-RX---56)|56|RX||||||||A7105|
|
||||
@@ -91,6 +94,7 @@ CFlie|38|CFlie||||||||NRF24L01|
|
||||
[FrskyX](Protocols_Details.md#FRSKYX---15)|15|CH_16|CH_8|EU_16|EU_8|Cloned|Cloned_8|||CC2500|
|
||||
[FrskyX2](Protocols_Details.md#FRSKYX2---64)|64|CH_16|CH_8|EU_16|EU_8|Cloned|Cloned_8|||CC2500|
|
||||
[Frsky_RX](Protocols_Details.md#FRSKY_RX---55)|55|RX|CloneTX|||||||CC2500|
|
||||
[Futaba/SFHSS](Protocols_Details.md#Futaba---21)|21|SFHSS||||||||CC2500|
|
||||
[FX816](Protocols_Details.md#FX816---58)|28|FX816|P38|||||||NRF24L01|
|
||||
[FY326](Protocols_Details.md#FY326---20)|20|FY326|FY319|||||||NRF24L01|
|
||||
[GD00X](Protocols_Details.md#GD00X---47)|47|GD_V1*|GD_V2*|||||||NRF24L01|XN297L
|
||||
@@ -103,14 +107,16 @@ CFlie|38|CFlie||||||||NRF24L01|
|
||||
[HoTT](Protocols_Details.md#HoTT---57)|57|Sync|No_Sync|||||||CC2500|
|
||||
[Hubsan](Protocols_Details.md#HUBSAN---2)|2|H107|H301|H501||||||A7105|
|
||||
[J6Pro](Protocols_Details.md#J6Pro---22)|22|J6Pro||||||||CYRF6936|
|
||||
[JJRC345](Protocols_Details.md#JJRC345---71)|71|JJRC345||||||||NRF24L01|XN297
|
||||
[JJRC345](Protocols_Details.md#JJRC345---71)|71|JJRC345|SkyTmblr|||||||NRF24L01|XN297
|
||||
[KF606](Protocols_Details.md#KF606---49)|49|KF606*||||||||NRF24L01|XN297
|
||||
[KN](Protocols_Details.md#KN---9)|9|WLTOYS|FEILUN|||||||NRF24L01|
|
||||
[Kyosho](Protocols_Details.md#Kyosho---73)|73|||||||||A7105|
|
||||
[Kyosho](Protocols_Details.md#Kyosho---73)|73|FHSS|Hype|||||||A7105|
|
||||
[LOLI](Protocols_Details.md#LOLI---82)|82|||||||||NRF24L01|
|
||||
[MJXq](Protocols_Details.md#MJXQ---18)|18|WLH08|X600|X800|H26D|E010*|H26WH|PHOENIX*||NRF24L01|XN297
|
||||
[MLINK](Protocols_Details.md#MLINK---78)|78|||||||||CYRF6936|
|
||||
[MT99xx](Protocols_Details.md#MT99XX---17)|17|MT|H7|YZ|LS|FY805||||NRF24L01|XN297
|
||||
[NCC1701](Protocols_Details.md#NCC1701---44)|44|NCC1701||||||||NRF24L01|
|
||||
[OMP](Protocols_Details.md#OMP---77)|77|||||||||NRF24L01|XN297L
|
||||
[OMP](Protocols_Details.md#OMP---77)|77|||||||||CC2500&NRF24L01|XN297L
|
||||
[OpenLRS](Protocols_Details.md#OpenLRS---27)|27|||||||||None|
|
||||
[Pelikan](Protocols_Details.md#Pelikan---60)|60|Pro|Lite|||||||A7105|
|
||||
[Potensic](Protocols_Details.md#Potensic---51)|51|A20||||||||NRF24L01|XN297
|
||||
@@ -118,11 +124,10 @@ CFlie|38|CFlie||||||||NRF24L01|
|
||||
[Q2X2](Protocols_Details.md#Q2X2---29)|29|Q222|Q242|Q282||||||NRF24L01|
|
||||
[Q303](Protocols_Details.md#Q303---31)|31|Q303|CX35|CX10D|CX10WD|||||NRF24L01|XN297
|
||||
[Q90C](Protocols_Details.md#Q90C---72)|72|Q90C*||||||||NRF24L01|XN297
|
||||
[RadioLink](Protocols_Details.md#RadioLink---74)|74|Surface|Air|||||||CC2500|
|
||||
[RadioLink](Protocols_Details.md#RadioLink---74)|74|Surface|Air|DumboRC||||||CC2500|
|
||||
[Realacc](Protocols_Details.md#Realacc---76)|76|R11||||||||NRF24L01|
|
||||
[Redpine](Protocols_Details.md#Redpine---50)|50|FAST|SLOW|||||||NRF24L01|XN297
|
||||
[Scanner](Protocols_Details.md#Scanner---54)|54|||||||||CC2500|
|
||||
[SFHSS](Protocols_Details.md#SFHSS---21)|21|SFHSS||||||||CC2500|
|
||||
[Shenqi](Protocols_Details.md#Shenqi---19)|19|Shenqi||||||||NRF24L01|LT8900
|
||||
[Skyartec](Protocols_Details.md#Skyartec---68)|68|Skyartec||||||||CC2500|CC2500
|
||||
[SLT](Protocols_Details.md#SLT---11)|11|SLT_V1|SLT_V2|Q100|Q200|MR100||||NRF24L01|CC2500
|
||||
@@ -132,7 +137,8 @@ CFlie|38|CFlie||||||||NRF24L01|
|
||||
[V2x2](Protocols_Details.md#V2X2---5)|5|V2x2|JXD506|MR101||||||NRF24L01|
|
||||
[V761](Protocols_Details.md#V761---48)|48|V761||||||||NRF24L01|XN297
|
||||
[V911S](Protocols_Details.md#V911S---46)|46|V911S*|E119*|||||||NRF24L01|XN297
|
||||
[WFly](Protocols_Details.md#WFLY---40)|40|WFLY||||||||CYRF6936|
|
||||
[WFLY](Protocols_Details.md#WFLY---40)|40|WFR0x||||||||CYRF6936|
|
||||
[WFLY2](Protocols_Details.md#WFLY2---79)|79|RF20x||||||||A7105|
|
||||
[WK2x01](Protocols_Details.md#WK2X01---30)|30|WK2801|WK2401|W6_5_1|W6_6_1|W6_HEL|W6_HEL_I|||CYRF6936|
|
||||
[XK](Protocols_Details.md#XK---62)|62|X450|X420|||||||NRF24L01|XN297
|
||||
[YD717](Protocols_Details.md#YD717---8)|8|YD717|SKYWLKR|SYMAX4|XINXUN|NIHUI||||NRF24L01|
|
||||
@@ -163,9 +169,15 @@ CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
||||
---|---|---|---|---|---|---|---
|
||||
A|E|T|R|CH5|CH6|CH7|CH8
|
||||
|
||||
Note that the RX ouput will be AETR.
|
||||
RX output will match the Flysky standard AETR independently of the input configuration AETR, RETA... unless on OpenTX 2.3.3+ you use the "Disable channel mapping" feature on the GUI.
|
||||
|
||||
### Sub_protocol Flysky - *0*
|
||||
Supports a variety of Flysky receivers and integrated boards.
|
||||
|
||||
Kyosho FHS MINI-Z also uses this protocol with this channel assignement:
|
||||
CH1|CH2|CH3|CH4|CH5
|
||||
---|---|---|---|---
|
||||
Steering|Throttle|Lights|Steering travel|Others:not sure
|
||||
|
||||
### Sub_protocol V9X9 - *1*
|
||||
CH5|CH6|CH7|CH8
|
||||
@@ -192,7 +204,7 @@ CH5|CH6|CH7
|
||||
Extended limits and failsafe supported
|
||||
|
||||
Telemetry enabled protocol:
|
||||
- by defaut using FrSky Hub protocol (for example er9x): RX(A1), battery voltage FS-CVT01(A2) and RX&TX RSSI
|
||||
- by defaut using FrSky Hub protocol (for example er9x): A1=RX voltage (set the ratio to 12.7 and adjust with offset), A2=battery voltage FS-CVT01 (set the ratio to 12.7 and adjust with offset) and RX&TX RSSI
|
||||
- if using erskyTX and OpenTX: full telemetry information available
|
||||
- if telemetry is incomplete (missing RX RSSI for example), it means that you have to upgrade your RX firmware to version 1.6 or later. You can do it from an original Flysky TX or using a STLink like explained in [this tutorial](https://www.rcgroups.com/forums/showthread.php?2677694-How-to-upgrade-Flysky-Turnigy-iA6B-RX-to-firmware-1-6-with-a-ST-Link).
|
||||
|
||||
@@ -206,7 +218,7 @@ CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13|CH14
|
||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---
|
||||
A|E|T|R|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13|CH14
|
||||
|
||||
Note that the RX ouput will be AETR whatever the input channel order is.
|
||||
RX output will match the Flysky standard AETR independently of the input configuration AETR, RETA... unless on OpenTX 2.3.3+ you use the "Disable channel mapping" feature on the GUI.
|
||||
|
||||
### Sub_protocol PWM_IBUS - *0*
|
||||
### Sub_protocol PPM_IBUS - *1*
|
||||
@@ -259,7 +271,7 @@ A|E|T|R|Gear|Gyro|Flap|Light
|
||||
|
||||
## HUBSAN - *2*
|
||||
|
||||
Telemetry enabled for battery voltage and TX RSSI
|
||||
Telemetry enabled for A1=battery voltage (set the ratio to 12.7 and adjust with offset) and TX RSSI
|
||||
|
||||
Option=vTX frequency (H107D) 5645 - 5900 MHz
|
||||
|
||||
@@ -291,12 +303,23 @@ H122D: FLIP
|
||||
H123D: FMODES -> -100%=Sport mode 1,0%=Sport mode 2,+100%=Acro
|
||||
|
||||
## Kyosho - *73*
|
||||
Surface protocol called FHSS introduced in 2017. Transmitters: KT-531P, KT-431PT, Flysky Noble NB4 (fw>2.0.67)...
|
||||
|
||||
### Sub_protocol FHSS - *0*
|
||||
Surface protocol called FHSS introduced in 2017. Transmitters: KT-531P, KT-431PT...
|
||||
|
||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13|CH14
|
||||
---|---|---|---|---|---|---|---|---|----|----|----|----|----
|
||||
STEERING|THROTTLE|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13|CH14
|
||||
|
||||
### Sub_protocol Hype - *1*
|
||||
Transmitters: ST6DF, HK6S, Flightsport. Receivers: ST6DF, HK6DF.
|
||||
|
||||
CH1|CH2|CH3|CH4|CH5|CH6
|
||||
---|---|---|---|---|---
|
||||
A|E|T|R|CH5|CH6
|
||||
|
||||
RX output will match the Hype standard AETR independently of the input configuration AETR, RETA... unless on OpenTX 2.3.3+ you use the "Disable channel mapping" feature on the GUI.
|
||||
|
||||
## Pelikan - *60*
|
||||
Extended limits supported
|
||||
|
||||
@@ -314,6 +337,21 @@ Models: TX: CADET 4 LITE
|
||||
|
||||
**Only 1 frequency hopping table**
|
||||
|
||||
## WFLY2 - *79*
|
||||
Receivers: RF201S,RF206S,RF207S,RF209S
|
||||
|
||||
Extended limits supported
|
||||
|
||||
Failsafe fully supported (value, hold and no pulse).
|
||||
|
||||
Telemetry enabled for A1=RX_Batt (Ratio 12.7), A2=Ext_Batt (Ratio 12.7), RX RSSI, TX RSSI, TX LQI (100=all telem packets received...0=no telem packets).
|
||||
|
||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10
|
||||
---|---|---|---|---|---|---|---|---|----
|
||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10
|
||||
|
||||
Option is used to select between WBUS=0 and PPM=1
|
||||
|
||||
***
|
||||
# CC2500 RF Module
|
||||
|
||||
@@ -348,6 +386,33 @@ To bind V2 RXs you must follow the below procedure (original):
|
||||
### Sub_protocol FD_V3 - *2*
|
||||
FlyDream RXs like IS-4R and IS-4R0
|
||||
|
||||
## E016HV2 - *80*
|
||||
Models: E016H v2
|
||||
|
||||
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 or bind won't even work.
|
||||
Check the [Frequency Tuning page](/docs/Frequency_Tuning.md) to determine it.
|
||||
|
||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10
|
||||
---|---|---|---|---|---|---|---|---|----
|
||||
A|E|T|R|TAKE_OFF/LANDING|EMERGENCY|FLIP|CALIB|HEADLESS|RTH
|
||||
|
||||
TAKE_OFF/LANDING: this is a momentary switch to arm the motors or land the quad. This switch is not really needed as you can start the quad with throttle low then increase throttle until the motor arms, move throttle to mid-stick and then increase it quickly to lift off; To land just bring throttle all the way down, the quad will just stops when touching the ground.
|
||||
|
||||
EMERGENCY: Can be used along with the throttle cut switch: Throttle cut=set throttle at -100% and set EMERGENCY to 100%
|
||||
|
||||
## ESKY150V2 - *69*
|
||||
ESky protocol for small models: 150 V2, F150 V2, Blade 70s
|
||||
|
||||
Notes:
|
||||
- RX output will match the eSky 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.
|
||||
- To run this protocol you need both CC2500 and NRF24L01 to be enabled for code reasons, only the CC2500 is really used.
|
||||
|
||||
CH1|CH2|CH3|CH4|CH5 |CH6 |CH7 |CH8 |CH9 |CH10|CH11|CH12|CH13|CH14|CH15|CH16
|
||||
---|---|---|---|----|----|----|----|----|----|----|----|----|----|----|----
|
||||
A|E|T|R|CH5 |CH6 |CH7 |CH8 |CH9 |CH10|CH11|CH12|CH13|CH14|CH15|CH16
|
||||
|
||||
RATE for the F150 V2 is assigned to channel 5: -100%=low, 100%=high
|
||||
|
||||
## FRSKYV - *25*
|
||||
Models: FrSky receivers V8R4, V8R7 and V8FR.
|
||||
- FrSkyV = FrSky 1 way
|
||||
@@ -496,6 +561,11 @@ Notes:
|
||||
- For FrSkyD, only the RX number used during bind is cloned -> you can't use RX num anymore
|
||||
- For FrSkyX and FrSkyX2, RX number has to be adjusted on each model to match the original TX model
|
||||
|
||||
### Sub_protocol EraseTX - *2*
|
||||
This subprotocol erases ALL the clone IDs which have been recorded.
|
||||
|
||||
To erase ALL the clone information, select the sub_protocol EraseTX and execute a bind.
|
||||
|
||||
## HITEC - *39*
|
||||
Models: OPTIMA, MINIMA and MICRO receivers.
|
||||
|
||||
@@ -526,7 +596,7 @@ Basic telemetry using FrSky Hub on er9x, erskyTX, OpenTX and any radio with FrSk
|
||||
MINIMA, MICRO and RED receivers. Also used by ARES planes.
|
||||
|
||||
## HoTT - *57*
|
||||
Models: Graupner HoTT receivers (tested on GR-12, GR-12L, GR-16 and Vector).
|
||||
Models: Graupner HoTT receivers (tested on GR-12, GR-12L, GR-16, GR-32 and Vector).
|
||||
|
||||
Extended limits, failsafe and LBT supported.
|
||||
|
||||
@@ -541,9 +611,9 @@ The RX and sensors/FC features configuration are done through the OpenTX script
|
||||
Option for this protocol corresponds to fine frequency tuning. This value is different for each Module and **must** be accurate otherwise the link will not be stable.
|
||||
Check the [Frequency Tuning page](/docs/Frequency_Tuning.md) to determine it.
|
||||
|
||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12
|
||||
---|---|---|---|---|---|---|---|---|----|----|----
|
||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12
|
||||
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 Sync - *0*
|
||||
Recommended for best telemetry performance.
|
||||
@@ -559,8 +629,6 @@ You should definitively upgrade your receivers/sensors to the latest firmware ve
|
||||
|
||||
Extended limits
|
||||
|
||||
**64 IDs available, use RX num to scroll through them**
|
||||
|
||||
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.
|
||||
|
||||
@@ -571,23 +639,29 @@ CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|FS_CH1|FS_CH2|FS_CH3|FS_CH4|FS_CH5|FS_CH6|FS_CH7
|
||||
FS=FailSafe
|
||||
|
||||
### Sub_protocol Surface - *0*
|
||||
Surface protocol. TXs: RC4GS,RC6GS. Compatible RXs:R7FG(Std),R6FG,R6F,R8EF,R8FM,R8F,R4FGM,R4F and more
|
||||
Surface protocol. TXs: RC4GS,RC6GS. Compatible RXs: R7FG(Std),R6FG,R6F,R8EF,R8FM,R8F,R4FGM,R4F
|
||||
|
||||
CH1=Steering, CH2=Throttle, CH8=Gyro gain
|
||||
|
||||
Telemetry: RX_RSSI (for the original value add -256), TX_RSSI, TX_QLY (0..100%), A1=RX_Batt, A2=Batt/2 (adjust the ratio)
|
||||
Telemetry: RX_RSSI (for the original value add -256), TX_RSSI, TX_QLY (0..100%), A1=RX_Batt (set the ratio to 12.7 and adjust with offset), A2=Batt (set the ratio to 25.5 and adjust with offset)
|
||||
|
||||
### Sub_protocol Air - *1*
|
||||
Air protocol. TXs: T8FB,T8S. Compatible RXs:R8EF,R8FM,R8SM,R4FG,R4F and more
|
||||
Air protocol. TXs: T8FB,T8S. Compatible RXs: R8EF,R8FM,R8SM,R4FG,R4F
|
||||
|
||||
Telemetry: RX_RSSI (for the original value add -256), TX_RSSI, TX_QLY (0..100%)
|
||||
|
||||
## SFHSS - *21*
|
||||
Models: Futaba RXs and XK models.
|
||||
### Sub_protocol DumboRC - *2*
|
||||
Compatible RXs: X6/X6F/X6FG
|
||||
|
||||
## Futaba - *21*
|
||||
Also called SFHSS depending on radio version.
|
||||
|
||||
### Sub_protocol SFHSS - *0*
|
||||
Models: Futaba SFHSS RXs and XK models.
|
||||
|
||||
Extended limits and failsafe supported
|
||||
|
||||
RX output will match the Futaba standard AETR 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 Futaba standard servo throw, mid point and the channel order AETR independently of the input configuration AETR, RETA... unless if on OpenTX 2.3.3+ you use the "Disable channel mapping" feature on the GUI.
|
||||
|
||||
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.
|
||||
@@ -619,7 +693,7 @@ A|E|T|R|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12
|
||||
|
||||
RX output will match the Devo standard EATR independently of the input configuration AETR, RETA... unless on OpenTX 2.3.3+ you use the "Disable channel mapping" feature on the GUI.
|
||||
|
||||
Basic telemetry is available if RX supports it: TX_RSSI, A1 and A2
|
||||
Basic telemetry is available if RX supports it: TX_RSSI, A1 (set the ratio to 12.7) and A2 (set the ratio to 12.7)
|
||||
|
||||
Bind procedure using serial:
|
||||
- With the TX off, put the binding plug in and power on the RX (RX LED slow blink), then power it down and remove the binding plug. Receiver should now be in autobind mode.
|
||||
@@ -752,6 +826,7 @@ The DSM receiver protocol enables master/slave trainning, separate access from 2
|
||||
|
||||
Notes:
|
||||
- Automatically detect DSM 2/X 11/22ms 1024/2048res
|
||||
- Bind should be done with all other modules off in the radio
|
||||
- Available in OpenTX 2.3.3+, Trainer Mode Master/Multi
|
||||
- Channels 1..4 are remapped to the module default channel order unless on OpenTX 2.3.3+ you use the "Disable channel mapping" feature on the GUI.
|
||||
- Extended limits supported
|
||||
@@ -760,12 +835,49 @@ CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12
|
||||
---|---|---|---|---|---|---|---|---|----|----|----
|
||||
A|E|T|R|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12
|
||||
|
||||
## E010R5 - *81*
|
||||
Models: E010 R5 red boards, JJRC H36, H36F and H36S
|
||||
|
||||
**Only 3 IDs are available**. More IDs can be added if you send me your "unused" original TX.
|
||||
|
||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10
|
||||
---|---|---|---|---|---|---|---|---|---
|
||||
A|E|T|R|FLIP|LED|CALIB|HEADLESS|RTH|GLIDE
|
||||
|
||||
## E129 - *83*
|
||||
Models: Eachine E129/E130 and Twister Ninja 250
|
||||
|
||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
|
||||
---|---|---|---|---|---|---|---|---
|
||||
A|E|T|R|Take off/Land|Emergency|Trim A|Trim E|Trim R
|
||||
|
||||
Trims can be done to some extent on the AETR channels directly but if you push them too far you won't be able to arm like explained below. In this case use the associated trim TrimA/E/R instead.
|
||||
|
||||
Take off with a none spring throttle is easier by putting both sticks down outwards (like on the original radio) in Mode 1/2, not sure about other modes.
|
||||
|
||||
Calib is the same as the original radio with both sticks down and to the left in Mode 1/2, not sure about other modes.
|
||||
|
||||
## J6Pro - *22*
|
||||
|
||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12
|
||||
---|---|---|---|---|---|---|---|---|----|----|----
|
||||
A|E|T|R|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12
|
||||
|
||||
## MLINK - *78*
|
||||
Extended limits supported
|
||||
|
||||
Bind: the RX must be really close to the TX
|
||||
|
||||
**Failsafe MUST be configured once with the desired channel values (hold or no pulses are not supported) while the RX is up (wait 10+sec for the RX to learn the config) and then failsafe MUST be set to RX/Receiver otherwise the servos will jitter!!!**
|
||||
|
||||
Telemetry: the 2 RXs I have are sending different information in different format
|
||||
- RX-5: RX_RSSI=RSSI=sort of RSSI or link quality, RX_LQI=number of connection lost, TX_RSSI=RSSI from the TX perspective, TX_LQI=percentage of received telemetry packets
|
||||
- RX-9-DR: A1=RX Batt (Ratio=12.7), **RX_RSSI=TX_LQI**=percentage of received telemetry packets **from the TX** perspective **not RX**, TX_RSSI=RSSI from the TX perspective, TX_LQI=percentage of received telemetry packets
|
||||
|
||||
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
|
||||
|
||||
## Traxxas - *43*
|
||||
Receiver 6519
|
||||
|
||||
@@ -814,7 +926,7 @@ Models: Eachine H8(C) mini, BayangToys X6/X7/X9, JJRC JJ850, Floureon H101 ...
|
||||
|
||||
Option=0 -> normal Bayang protocol
|
||||
|
||||
Option=1 -> enable telemetry with [Silverxxx firmware](https://github.com/silver13/H101-acro/tree/master). Value returned to the TX using FrSkyD Hub are RX RSSI, TX RSSI, A1=uncompensated battery voltage, A2=compensated battery voltage
|
||||
Option=1 -> enable telemetry with [Silverxxx firmware](https://github.com/silver13/H101-acro/tree/master). Value returned to the TX using FrSkyD Hub are RX RSSI, TX RSSI, A1=uncompensated battery voltage (set the ratio to 5.0 and adjust with offset), A2=compensated battery voltage (set the ratio to 5.0 and adjust with offset) and if supported AccX=P, AccY=I, ACCZ=D (which you can rename after the sensors discovery)
|
||||
|
||||
Option=2 -> enable analog aux channels with [NFE Silverware firmware](https://github.com/NotFastEnuf/NFE_Silverware). Two otherwise static bytes in the protocol overridden to add two 'analog' (non-binary) auxiliary channels.
|
||||
|
||||
@@ -1033,19 +1145,6 @@ A|E|T|R|FMODE|AUX6|AUX7
|
||||
|
||||
FMODE and AUX7 have 4 positions: -100%..-50%=>0, -50%..5%=>1, 5%..50%=>2, 50%..100%=>3
|
||||
|
||||
## ESKY150V2 - *69*
|
||||
ESky protocol for small models: 150 V2, F150 V2, Blade 70s
|
||||
|
||||
Notes:
|
||||
- RX output will match the eSky 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.
|
||||
- To run this protocol you need both CC2500 and NRF24L01 to be enabled for code reasons, only the CC2500 is really used.
|
||||
|
||||
CH1|CH2|CH3|CH4|CH5 |CH6 |CH7 |CH8 |CH9 |CH10|CH11|CH12|CH13|CH14|CH15|CH16
|
||||
---|---|---|---|----|----|----|----|----|----|----|----|----|----|----|----
|
||||
A|E|T|R|CH5 |CH6 |CH7 |CH8 |CH9 |CH10|CH11|CH12|CH13|CH14|CH15|CH16
|
||||
|
||||
RATE for the F150 V2 is assigned to channel 5: -100%=low, 100%=high
|
||||
|
||||
## FX816 - *58*
|
||||
Model: FEI XIONG FX816 P38
|
||||
|
||||
@@ -1178,11 +1277,18 @@ ARM|
|
||||
### Sub_protocol FQ777_951 - *3*
|
||||
|
||||
## JJRC345 - *71*
|
||||
|
||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11
|
||||
---|---|---|---|---|---|---|---|---|----|----
|
||||
A|E|T|R|FLIP|HEADLESS|RTH|LED|UNK1|UNK2|UNK3
|
||||
|
||||
### Sub_protocol JJRC345 - *0*
|
||||
Model: JJRC345
|
||||
|
||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7
|
||||
---|---|---|---|---|---|---
|
||||
A|E|T|R|FLIP|HEADLESS|RTH
|
||||
### Sub_protocol SkyTmblr - *1*
|
||||
Model: DF-Models SkyTumbler
|
||||
|
||||
RTH not supported
|
||||
|
||||
## KF606 - *49*
|
||||
Model: KF606
|
||||
@@ -1195,6 +1301,31 @@ CH1|CH2|CH3|CH4|CH5
|
||||
---|---|---|---|---
|
||||
A||T||TRIM
|
||||
|
||||
## LOLI - *82*
|
||||
LOLI3 receivers: https://github.com/wooddoor/Loli3
|
||||
|
||||
Failsafe supported. Once failsafe values for the 8 channels have been configured in Custom mode, wait for the RX to learn them, then set Failsafe to Receiver.
|
||||
|
||||
Telemetry supported: RX RSSI, TX LQI (percentage of received telemetry packets), A1 and A2 with a Ratio=25.5 and Offset=0.
|
||||
|
||||
Extended limits supported.
|
||||
|
||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
||||
---|---|---|---|---|---|---|---
|
||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
||||
|
||||
Features:
|
||||
Config on | For channel | Switch | Servo | PPM | SBUS | PWM
|
||||
----|-----|-------|----|------|---|------
|
||||
CH9 | CH1 | -100% | 0% | +50% | - | +100%
|
||||
CH10| CH2 | -100% | 0% | - | - | +100%
|
||||
CH11| CH3 | -100% | 0% | - | - | -
|
||||
CH12| CH4 | -100% | 0% | - | - | -
|
||||
CH13| CH5 | -100% | 0% | - | +50% | -
|
||||
CH14| CH6 | -100% | 0% | | - | -
|
||||
CH15| CH7 | -100% | 0% | - | - | +100%
|
||||
CH16| CH8 | -100% | 0% | - | - | -
|
||||
|
||||
## MJXQ - *18*
|
||||
Autobind protocol
|
||||
|
||||
@@ -1260,12 +1391,19 @@ A|E|T|R|FLIP|INVERT|PICTURE|VIDEO|HEADLESS
|
||||
### Sub_protocol FY805 - *4*
|
||||
Model: FY805
|
||||
|
||||
Only 1 ID available
|
||||
**Only 1 ID available**
|
||||
|
||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
|
||||
---|---|---|---|---|---|---|---|---
|
||||
A|E|T|R|FLIP||||HEADLESS
|
||||
|
||||
### Sub_protocol A180 - *5*
|
||||
Model: XK A180
|
||||
|
||||
CH1|CH2|CH3|CH4|CH5
|
||||
---|---|---|---|---
|
||||
A|E|T|R|3D6G
|
||||
|
||||
## NCC1701 - *44*
|
||||
Model: Air Hogs Star Trek USS Enterprise NCC-1701-A
|
||||
|
||||
@@ -1280,11 +1418,19 @@ CH1|CH2|CH3|CH4|CH5
|
||||
A|E|T|R|Warp
|
||||
|
||||
## OMP - *77*
|
||||
Model: OMPHOBBY M2
|
||||
Model: OMPHOBBY M1 & M2 Helis, T720 RC Glider
|
||||
|
||||
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.
|
||||
This protocol requires both a NRF24L01 and CC2500 RF components to operate.
|
||||
|
||||
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).
|
||||
Telemetry supported:
|
||||
- A1 = battery voltage including "recovered" battery voltage from corrupted telemetry packets
|
||||
- A2 = battery voltage from only good telemetry packets
|
||||
- How to calculate accurately the OpenTX Ratio and Offset:
|
||||
Set the Ratio to 12.7 and Offset to 0, plug 2 batteries with extreme voltage values, write down the values Batt1=12.5V & Telem1=12.2V, Batt2=7V & Telem2=6.6V then calculate/set Ratio=12.7*[(12.5-7)/(12.2-6.6)]=12.47 => 12.5 and Offset=12.5-12.2*[(12.5-7)/(12.2-6.6)]=0.517 => 0.5
|
||||
- RX_RSSI = TQly = percentage of received telemetry packets (good and corrupted) from the model which has nothing to do with how well the RX is receiving the TX
|
||||
|
||||
Option for this protocol corresponds to the CC2500 fine frequency tuning. This value is different for each Module and **must** be accurate otherwise the link will not be stable.
|
||||
Check the [Frequency Tuning page](/docs/Frequency_Tuning.md) to determine it.
|
||||
|
||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7
|
||||
---|---|---|---|---|---|---
|
||||
@@ -1292,7 +1438,8 @@ A|E|T_PITCH|R|T_HOLD|IDLE|MODE
|
||||
|
||||
IDLE= 3 pos switch: -100% Normal, 0% Idle1, +100% Idle2
|
||||
|
||||
MODE= 3 pos switch -100% Attitude(?), 0% Attitude, +100% 3D
|
||||
From the TX manual: MODE= 3 pos switch -100% Attitude, 0% Attitude(?), +100% 3D
|
||||
For M2: MODE= 3 pos switch -100% 6G, 0% 3D, +100% 3D
|
||||
|
||||
## Potensic - *51*
|
||||
Model: Potensic A20
|
||||
@@ -1366,7 +1513,16 @@ Each toggle of VTX will increment the channel.
|
||||
|
||||
Gimbal is full range.
|
||||
|
||||
### Sub_protocol CX10D - *2* and Sub_protocol CX10WD - *3*
|
||||
### Sub_protocol CX10D - *2*
|
||||
Models CX10D and CX33W
|
||||
|
||||
CH5|CH6
|
||||
---|---
|
||||
ARM|FLIP
|
||||
|
||||
ARM is 3 positions: -100%=land / 0%=manual / +100%=take off
|
||||
|
||||
### Sub_protocol CX10WD - *3*
|
||||
CH5|CH6
|
||||
---|---
|
||||
ARM|FLIP
|
||||
|
||||
@@ -19,10 +19,11 @@ If you like this project and want to support further development please consider
|
||||
|
||||
## Development status
|
||||
|
||||
Current Multiprotocol code check status: [](https://travis-ci.org/pascallanger/DIY-Multiprotocol-TX-Module)
|
||||
Multiprotocol downloads: <img src=https://img.shields.io/github/downloads/pascallanger/DIY-Multiprotocol-TX-Module/total.svg>
|
||||
|
||||
Current Multiprotocol boards check status: [](https://travis-ci.org/pascallanger/DIY-Multiprotocol-TX-Module-Boards)
|
||||
Current Multiprotocol code check status: [<img src=https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/workflows/CI/badge.svg>](https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/actions). Download the latest **test** build [here](https://downloads.multi-module.org/latest-test/).
|
||||
|
||||
Current Multiprotocol boards check status: [](https://travis-ci.com/pascallanger/DIY-Multiprotocol-TX-Module-Boards)
|
||||
|
||||
## Quicklinks
|
||||
* [Download latest releases of the firmware](https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/releases) and [instructions to upload .hex files](docs/Advanced_Manually_Setting_ATmega328_Fuses.md)
|
||||
|
||||
210
_travis.yml
Normal file
210
_travis.yml
Normal file
@@ -0,0 +1,210 @@
|
||||
os: linux
|
||||
dist: bionic
|
||||
language: c
|
||||
|
||||
env:
|
||||
jobs:
|
||||
- BOARD="multi4in1:avr:multiatmega328p:bootloader=none"
|
||||
- BOARD="multi4in1:avr:multiatmega328p:bootloader=optiboot"
|
||||
- BOARD="multi4in1:avr:multixmega32d4"
|
||||
- BOARD="multi4in1:STM32F1:multi5in1t18int"
|
||||
- BOARD="multi4in1:STM32F1:multistm32f103cb:debug_option=none"
|
||||
- BOARD="multi4in1:STM32F1:multistm32f103cb:debug_option=native"
|
||||
- BOARD="multi4in1:STM32F1:multistm32f103cb:debug_option=ftdi"
|
||||
- BOARD="multi4in1:STM32F1:multistm32f103c8:debug_option=none"
|
||||
|
||||
notifications:
|
||||
email: false
|
||||
|
||||
before_install:
|
||||
# Fetch the tag information for the current branch
|
||||
- git fetch origin --tags
|
||||
|
||||
# Publish the buildroot script folder
|
||||
- chmod +x ${TRAVIS_BUILD_DIR}/buildroot/bin/*
|
||||
- export PATH=${TRAVIS_BUILD_DIR}/buildroot/bin/:${PATH}
|
||||
|
||||
# Helper functions for the builds
|
||||
- buildMulti() { start_fold config_diff; travis_time_start; git diff Multiprotocol/_Config.h; end_fold config_diff; exitcode=0; BUILDCMD="arduino-cli compile -b $BOARD Multiprotocol/Multiprotocol.ino --build-path ${TRAVIS_BUILD_DIR}/build/"; echo $BUILDCMD; $BUILDCMD; if [ $? -ne 0 ]; then exitcode=1; fi; echo; return $exitcode; }
|
||||
- buildProtocol() { exitcode=0; opt_disable $ALL_PROTOCOLS; opt_enable $1; buildMulti; if [ $? -ne 0 ]; then exitcode=1; fi; return $exitcode; }
|
||||
- buildEachProtocol() { exitcodesum=0; for PROTOCOL in $ALL_PROTOCOLS ; do printf "\e[33;1mBuilding $PROTOCOL\e[0m"; buildProtocol $PROTOCOL; if [ $? -ne 0 ]; then exitcodesum=$((exitcodesum + 1)); fi; done; return $exitcodesum; }
|
||||
- buildRFModule() { exitcode=0; opt_disable $ALL_RFMODULES; opt_enable $1; buildMulti; if [ $? -ne 0 ]; then exitcode=1; fi; return $exitcode; }
|
||||
- buildEachRFModule() { exitcodesum=0; for RFMODULE in $ALL_RFMODULES; do printf "\e[33;1mBuilding $RFMODULE\e[0m"; buildRFModule $RFMODULE; if [ $? -ne 0 ]; then exitcodesum=$((exitcodesum + 1)); fi; done; return $exitcodesum; }
|
||||
- buildDefault() { exitcode=0; printf "\n\e[33;1mBuilding default configuration\e[0m\n"; buildMulti; if [ $? -ne 0 ]; then exitcode=1; fi; return $exitcode; }
|
||||
- buildSerialOnly() { exitcode=0; printf "\n\e[33;1mBuilding serial mode only\e[0m\n"; opt_disable ENABLE_PPM; opt_enable ENABLE_SERIAL; buildMulti; if [ $? -ne 0 ]; then exitcode=1; fi; return $exitcode; }
|
||||
- buildPPMOnly() { exitcode=0; printf "\n\e[33;1mBuilding PPM mode only\e[0m\n"; opt_enable ENABLE_PPM; opt_disable ENABLE_SERIAL; buildMulti; if [ $? -ne 0 ]; then exitcode=1; fi; return $exitcode; }
|
||||
- export -f buildMulti
|
||||
|
||||
# Function to build the release files - dependent on board type.
|
||||
# Release build scripts are located in buildroot/bin.
|
||||
- if [[ "$BOARD" == "multi4in1:avr:multixmega32d4" ]]; then
|
||||
buildReleaseFiles(){
|
||||
build_release_orx;
|
||||
};
|
||||
elif [[ "$BOARD" == "multi4in1:avr:multiatmega328p:bootloader=none" ]]; then
|
||||
buildReleaseFiles(){
|
||||
build_release_avr_noboot;
|
||||
};
|
||||
elif [[ "$BOARD" == "multi4in1:avr:multiatmega328p:bootloader=optiboot" ]]; then
|
||||
buildReleaseFiles(){
|
||||
build_release_avr_optiboot;
|
||||
};
|
||||
elif [[ "$BOARD" == "multi4in1:STM32F1:multistm32f103cb:debug_option=none" ]]; then
|
||||
buildReleaseFiles(){
|
||||
build_release_stm32f1_no_debug;
|
||||
};
|
||||
elif [[ "$BOARD" == "multi4in1:STM32F1:multistm32f103cb:debug_option=native" ]]; then
|
||||
buildReleaseFiles(){
|
||||
build_release_stm32f1_native_debug;
|
||||
};
|
||||
elif [[ "$BOARD" == "multi4in1:STM32F1:multistm32f103cb:debug_option=ftdi" ]]; then
|
||||
buildReleaseFiles(){
|
||||
build_release_stm32f1_serial_debug;
|
||||
};
|
||||
elif [[ "$BOARD" == "multi4in1:STM32F1:multi5in1t18int" ]]; then
|
||||
buildReleaseFiles(){
|
||||
build_release_stm32f1_t18int;
|
||||
};
|
||||
else
|
||||
buildReleaseFiles() { printf "No release files for this board."; };
|
||||
fi
|
||||
|
||||
install:
|
||||
# Install Arduino CLI
|
||||
- mkdir ~/arduino-cli
|
||||
- curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | BINDIR=~/arduino-cli sh -s 0.13.0;
|
||||
- export PATH=$PATH:$HOME/arduino-cli
|
||||
|
||||
# Update the board url and package index
|
||||
- arduino-cli core update-index --additional-urls https://raw.githubusercontent.com/pascallanger/DIY-Multiprotocol-TX-Module-Boards/master/package_multi_4in1_board_index.json
|
||||
|
||||
# Install the STM32 board if needed
|
||||
- if [[ "$BOARD" =~ "multi4in1:STM32F1:" ]]; then
|
||||
arduino-cli core install multi4in1:STM32F1 --additional-urls https://raw.githubusercontent.com/pascallanger/DIY-Multiprotocol-TX-Module-Boards/master/package_multi_4in1_board_index.json;
|
||||
fi
|
||||
|
||||
# Install the AVR board if needed
|
||||
- if [[ "$BOARD" =~ "multi4in1:avr:" ]]; then
|
||||
arduino-cli core install arduino:avr;
|
||||
arduino-cli core install multi4in1:avr --additional-urls https://raw.githubusercontent.com/pascallanger/DIY-Multiprotocol-TX-Module-Boards/master/package_multi_4in1_board_index.json;
|
||||
fi
|
||||
|
||||
before_script:
|
||||
# Export all the variables
|
||||
- set -a
|
||||
|
||||
# Change current working directory to the build dir
|
||||
- cd ${TRAVIS_BUILD_DIR}
|
||||
|
||||
# Create somwhere to put the exported binaries
|
||||
- mkdir ./binaries
|
||||
|
||||
# Log the initial Multi config
|
||||
- cat Multiprotocol/_Config.h
|
||||
|
||||
# Back up the configuration
|
||||
- cp Multiprotocol/_Config.h ./_Config.h.bak
|
||||
|
||||
# Get the firmware version number from the source
|
||||
- MAJOR_VERSION=$(grep "VERSION_MAJOR" "Multiprotocol/Multiprotocol.h" | awk -v N=3 '{gsub(/\r/,""); print $N}')
|
||||
- MINOR_VERSION=$(grep "VERSION_MINOR" "Multiprotocol/Multiprotocol.h" | awk -v N=3 '{gsub(/\r/,""); print $N}')
|
||||
- REVISION_VERSION=$(grep "VERSION_REVISION" "Multiprotocol//Multiprotocol.h" | awk -v N=3 '{gsub(/\r/,""); print $N}')
|
||||
- PATCH_VERSION=$(grep "VERSION_PATCH" "Multiprotocol//Multiprotocol.h" | awk -v N=3 '{gsub(/\r/,""); print $N}')
|
||||
- MULTI_VERSION=$MAJOR_VERSION.$MINOR_VERSION.$REVISION_VERSION.$PATCH_VERSION
|
||||
|
||||
# Derive the Multi protocols from the Multi source
|
||||
- A7105_PROTOCOLS=$(sed -n 's/[\/\/]*[[:blank:]]*#define[[:blank:]]*\([[:alnum:]_]*_A7105_INO\)\(.*\)/\1/p' Multiprotocol/_Config.h)
|
||||
- CC2500_PROTOCOLS=$(sed -n 's/[\/\/]*[[:blank:]]*#define[[:blank:]]*\([[:alnum:]_]*_CC2500_INO\)\(.*\)/\1/p' Multiprotocol/_Config.h)
|
||||
- CYRF6936_PROTOCOLS=$(sed -n 's/[\/\/]*[[:blank:]]*#define[[:blank:]]*\([[:alnum:]_]*_CYRF6936_INO\)\(.*\)/\1/p' Multiprotocol/_Config.h)
|
||||
- NRF24L01_PROTOCOLS=$(sed -n 's/[\/\/]*[[:blank:]]*#define[[:blank:]]*\([[:alnum:]_]*_NRF24L01_INO\)\(.*\)/\1/p' Multiprotocol/_Config.h)
|
||||
- SX1276_PROTOCOLS=$(sed -n 's/[\/\/]*[[:blank:]]*#define[[:blank:]]*\([[:alnum:]_]*_SX1276_INO\)\(.*\)/\1/p' Multiprotocol/_Config.h)
|
||||
|
||||
# Get the full set of protocols for each board
|
||||
- if [[ "$BOARD" =~ "multi4in1:avr:multixmega32d4" ]]; then
|
||||
ALL_PROTOCOLS=$(echo $CYRF6936_PROTOCOLS);
|
||||
elif [[ "$BOARD" =~ "multi4in1:avr:multiatmega328p:" ]]; then
|
||||
ALL_PROTOCOLS=$(echo $A7105_PROTOCOLS $CC2500_PROTOCOLS $CYRF6936_PROTOCOLS $NRF24L01_PROTOCOLS);
|
||||
elif [[ "$BOARD" =~ "multi4in1:STM32F1:" ]]; then
|
||||
ALL_PROTOCOLS=$(echo $A7105_PROTOCOLS $CC2500_PROTOCOLS $CYRF6936_PROTOCOLS $NRF24L01_PROTOCOLS $SX1276_PROTOCOLS);
|
||||
fi
|
||||
- echo $ALL_PROTOCOLS
|
||||
|
||||
# Declare all the installed modules
|
||||
- if [[ "$BOARD" =~ "multi4in1:avr:multixmega32d4" ]]; then
|
||||
ALL_RFMODULES=$(echo CYRF6936_INSTALLED);
|
||||
elif [[ "$BOARD" =~ "multi4in1:avr:multiatmega328p:" ]]; then
|
||||
ALL_RFMODULES=$(echo A7105_INSTALLED CYRF6936_INSTALLED CC2500_INSTALLED NRF24L01_INSTALLED);
|
||||
elif [[ "$BOARD" =~ "multi4in1:STM32F1:" ]]; then
|
||||
ALL_RFMODULES=$(echo A7105_INSTALLED CYRF6936_INSTALLED CC2500_INSTALLED NRF24L01_INSTALLED SX1276_INSTALLED);
|
||||
fi
|
||||
- echo $ALL_RFMODULES
|
||||
|
||||
# Disable CHECK_FOR_BOOTLOADER when not needed
|
||||
- if [[ "$BOARD" == "multi4in1:avr:multiatmega328p:bootloader=none" ]]; then
|
||||
opt_disable CHECK_FOR_BOOTLOADER;
|
||||
fi
|
||||
|
||||
# Trim the enabled protocols down for the STM32F103CB board with debugging
|
||||
- if [[ "$BOARD" == "multi4in1:STM32F1:multistm32f103cb:debug_option=ftdi" ]] || [[ "$BOARD" == "multi4in1:STM32F1:multistm32f103cb: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 STM32F103C8 board
|
||||
- if [[ "$BOARD" == "multi4in1:STM32F1:multistm32f103c8:debug_option=none" ]]; then
|
||||
opt_disable $ALL_PROTOCOLS;
|
||||
opt_enable FRSKYX_CC2500_INO AFHDS2A_A7105_INO MJXQ_NRF24L01_INO DSM_CYRF6936_INO;
|
||||
fi
|
||||
|
||||
# Trim the enabled protocols down for the Atmega328p board
|
||||
- if [[ "$BOARD" =~ "multi4in1:avr:multiatmega328p:" ]]; then
|
||||
opt_disable $ALL_PROTOCOLS;
|
||||
opt_enable FRSKYX_CC2500_INO AFHDS2A_A7105_INO MJXQ_NRF24L01_INO DSM_CYRF6936_INO;
|
||||
fi
|
||||
|
||||
# Useful Travis functions
|
||||
- export -f travis_fold
|
||||
- export -f travis_nanoseconds
|
||||
- export -f travis_time_start
|
||||
- export -f travis_time_finish
|
||||
- start_fold() { echo -e "travis_fold:start:$1"; }
|
||||
- end_fold() { echo -e "\ntravis_fold:end:$1\r"; }
|
||||
|
||||
script:
|
||||
# Build with default configuration - all protocols are enabled for STM32; a subset of protocols for Atmega or STM32 debugging
|
||||
- buildDefault
|
||||
|
||||
# Serial only
|
||||
- buildSerialOnly
|
||||
|
||||
# PPM only
|
||||
- buildPPMOnly
|
||||
|
||||
# Re-enable PPM and serial
|
||||
- opt_enable ENABLE_SERIAL
|
||||
- opt_enable ENABLE_PPM
|
||||
|
||||
# Build for each RF module individually
|
||||
- buildEachRFModule
|
||||
|
||||
# Restore the default configuration
|
||||
- cp ./_Config.h.bak Multiprotocol/_Config.h
|
||||
|
||||
# Build each protocol individually
|
||||
- buildEachProtocol
|
||||
|
||||
# Restore the default configuration
|
||||
- cp ./_Config.h.bak Multiprotocol/_Config.h
|
||||
|
||||
# Builds the files for a release - always built, but only copied to Github if the test is tagged as a release
|
||||
- buildReleaseFiles
|
||||
|
||||
deploy:
|
||||
provider: releases
|
||||
token:
|
||||
secure: KGXaoqvd8rbZ3AZtL9Rrn1JYiocGsPaihRUyR8gM8vTfvH9WYAE1+h6SzROQOuJSwr89MvTo3SBOTlM/0PDBnEGLec9Irt7cwO0xf9xM2vPuUG8DYcUzmJJzME9dkn/7qHof1JGgRpp1duUAN1triE9NxhKxL1hbs+tUUbDPAejxwoFNfnta/T4PfD6xmkZNJbneIfYFuFgyLpwwFhuUy9JP7s1AFOiT+fCHxPaZrPn5GsXqAi95Cb7Q3w1iVSt3BmrGxL2j3CeNpWzFY1RrMdc8ay+ppOhSPEIl2vyM7VeLRRBL3EVeFWkiS4ywevqw70wOivTczluv3OeuIJAe5o2UU+w5+59c7+i44Nih23PDAZBhAG5JkLUYUN0XUJpXJ5ZlZsb8IS8sI1txlZa5tNVoXO9+soGEY4rKSpZaPptuENm792CzzAjcaUI9pOFJ/0CBoSCbu5MpM/plkJCMd8fY27EE8cNYvolMuRATNlXs7h9mURGR69pmcR1jFShH+A7Kyp1S1sH19sGCEU16rt2aAtf2FadFg/gKACC2y9rB3wBb4Qnapu2AwNRlTYNuU1+G+kb2FXRwMl04q+38S+cIBHH9NHfdftp9MRPf8Ekatojs92be/Ux21S+hcA7sx/DV22Dl45V6l4mXzR7U4x1nQcdn1SGuy5I4lL6IYCk=
|
||||
skip_cleanup: true
|
||||
file_glob: true
|
||||
file: binaries/*
|
||||
on:
|
||||
tags: true
|
||||
103
buildroot/bin/buildFunctions
Normal file
103
buildroot/bin/buildFunctions
Normal file
@@ -0,0 +1,103 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
getMultiVersion() {
|
||||
MAJOR_VERSION=$(grep "VERSION_MAJOR" "Multiprotocol/Multiprotocol.h" | awk -v N=3 '{gsub(/\r/,""); print $N}')
|
||||
MINOR_VERSION=$(grep "VERSION_MINOR" "Multiprotocol/Multiprotocol.h" | awk -v N=3 '{gsub(/\r/,""); print $N}')
|
||||
REVISION_VERSION=$(grep "VERSION_REVISION" "Multiprotocol//Multiprotocol.h" | awk -v N=3 '{gsub(/\r/,""); print $N}')
|
||||
PATCH_VERSION=$(grep "VERSION_PATCH" "Multiprotocol//Multiprotocol.h" | awk -v N=3 '{gsub(/\r/,""); print $N}')
|
||||
MULTI_VERSION=$MAJOR_VERSION.$MINOR_VERSION.$REVISION_VERSION.$PATCH_VERSION
|
||||
}
|
||||
|
||||
getAllRFModules() {
|
||||
if [[ "$BOARD" =~ "multi4in1:avr:multixmega32d4" ]]; then
|
||||
ALL_RFMODULES=$(echo CYRF6936_INSTALLED);
|
||||
elif [[ "$BOARD" =~ "multi4in1:avr:multiatmega328p:" ]]; then
|
||||
ALL_RFMODULES=$(echo A7105_INSTALLED CYRF6936_INSTALLED CC2500_INSTALLED NRF24L01_INSTALLED);
|
||||
elif [[ "$BOARD" =~ "multi4in1:STM32F1:" ]]; then
|
||||
ALL_RFMODULES=$(echo A7105_INSTALLED CYRF6936_INSTALLED CC2500_INSTALLED NRF24L01_INSTALLED SX1276_INSTALLED);
|
||||
fi
|
||||
}
|
||||
|
||||
getAllProtocols() {
|
||||
A7105_PROTOCOLS=$(sed -n 's/[\/\/]*[[:blank:]]*#define[[:blank:]]*\([[:alnum:]_]*_A7105_INO\)\(.*\)/\1/p' Multiprotocol/_Config.h)
|
||||
CC2500_PROTOCOLS=$(sed -n 's/[\/\/]*[[:blank:]]*#define[[:blank:]]*\([[:alnum:]_]*_CC2500_INO\)\(.*\)/\1/p' Multiprotocol/_Config.h)
|
||||
CYRF6936_PROTOCOLS=$(sed -n 's/[\/\/]*[[:blank:]]*#define[[:blank:]]*\([[:alnum:]_]*_CYRF6936_INO\)\(.*\)/\1/p' Multiprotocol/_Config.h)
|
||||
NRF24L01_PROTOCOLS=$(sed -n 's/[\/\/]*[[:blank:]]*#define[[:blank:]]*\([[:alnum:]_]*_NRF24L01_INO\)\(.*\)/\1/p' Multiprotocol/_Config.h)
|
||||
SX1276_PROTOCOLS=$(sed -n 's/[\/\/]*[[:blank:]]*#define[[:blank:]]*\([[:alnum:]_]*_SX1276_INO\)\(.*\)/\1/p' Multiprotocol/_Config.h)
|
||||
|
||||
if [[ "$BOARD" =~ "multi4in1:avr:multixmega32d4" ]]; then
|
||||
ALL_PROTOCOLS=$(echo $CYRF6936_PROTOCOLS);
|
||||
elif [[ "$BOARD" =~ "multi4in1:avr:multiatmega328p:" ]]; then
|
||||
ALL_PROTOCOLS=$(echo $A7105_PROTOCOLS $CC2500_PROTOCOLS $CYRF6936_PROTOCOLS $NRF24L01_PROTOCOLS);
|
||||
elif [[ "$BOARD" =~ "multi4in1:STM32F1:" ]]; then
|
||||
ALL_PROTOCOLS=$(echo $A7105_PROTOCOLS $CC2500_PROTOCOLS $CYRF6936_PROTOCOLS $NRF24L01_PROTOCOLS $SX1276_PROTOCOLS);
|
||||
fi
|
||||
}
|
||||
|
||||
buildMulti() {
|
||||
echo ::group::_Config.h
|
||||
git diff Multiprotocol/_Config.h
|
||||
echo ::endgroup::
|
||||
BUILDCMD="arduino-cli compile -b $BOARD ${GITHUB_WORKSPACE}/Multiprotocol/Multiprotocol.ino --build-path ${GITHUB_WORKSPACE}/build/";
|
||||
echo $BUILDCMD;
|
||||
$BUILDCMD
|
||||
return $?
|
||||
}
|
||||
|
||||
buildProtocol() {
|
||||
exitcode=0;
|
||||
opt_disable $ALL_PROTOCOLS;
|
||||
opt_enable $1;
|
||||
buildMulti;
|
||||
if [ $? -ne 0 ]; then exitcode=1; fi;
|
||||
return $exitcode;
|
||||
}
|
||||
|
||||
buildEachProtocol() {
|
||||
exitcodesum=0;
|
||||
for PROTOCOL in $ALL_PROTOCOLS ; do
|
||||
printf "\e[33;1mBuilding $PROTOCOL\e[0m\n";
|
||||
buildProtocol $PROTOCOL;
|
||||
if [ $? -ne 0 ]; then exitcodesum=$((exitcodesum + 1)); fi;
|
||||
done;
|
||||
return $exitcodesum;
|
||||
}
|
||||
|
||||
buildRFModule() {
|
||||
exitcode=0;
|
||||
opt_disable $ALL_RFMODULES;
|
||||
opt_enable $1;
|
||||
buildMulti;
|
||||
if [ $? -ne 0 ]; then exitcode=1; fi;
|
||||
return $exitcode;
|
||||
}
|
||||
|
||||
buildEachRFModule() {
|
||||
exitcodesum=0;
|
||||
for RFMODULE in $ALL_RFMODULES; do
|
||||
printf "\e[33;1mBuilding $RFMODULE\e[0m\n";
|
||||
buildRFModule $RFMODULE;
|
||||
if [ $? -ne 0 ]; then exitcodesum=$((exitcodesum + 1)); fi;
|
||||
done;
|
||||
return $exitcodesum;
|
||||
}
|
||||
|
||||
buildReleaseFiles(){
|
||||
if [[ "$BOARD" == "multi4in1:avr:multixmega32d4" ]]; then
|
||||
build_release_orx;
|
||||
elif [[ "$BOARD" == "multi4in1:avr:multiatmega328p:bootloader=none" ]]; then
|
||||
build_release_avr_noboot;
|
||||
elif [[ "$BOARD" == "multi4in1:avr:multiatmega328p:bootloader=optiboot" ]]; then
|
||||
build_release_avr_optiboot;
|
||||
elif [[ "$BOARD" == "multi4in1:STM32F1:multistm32f103cb:debug_option=none" ]]; then
|
||||
build_release_stm32f1_no_debug;
|
||||
elif [[ "$BOARD" == "multi4in1:STM32F1:multistm32f103cb:debug_option=native" ]]; then
|
||||
build_release_stm32f1_native_debug;
|
||||
elif [[ "$BOARD" == "multi4in1:STM32F1:multistm32f103cb:debug_option=ftdi" ]]; then
|
||||
build_release_stm32f1_serial_debug;
|
||||
elif [[ "$BOARD" == "multi4in1:STM32F1:multi5in1t18int" ]]; then
|
||||
build_release_stm32f1_t18int;
|
||||
else
|
||||
printf "No release files for this board.";
|
||||
fi
|
||||
}
|
||||
29
buildroot/bin/build_release_avr_noboot
Normal file
29
buildroot/bin/build_release_avr_noboot
Normal file
@@ -0,0 +1,29 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
source ./buildroot/bin/buildFunctions;
|
||||
exitcode=0;
|
||||
|
||||
printf "\e[33;1mBuilding multi-avr-usbasp-aetr-A7105-inv-v$MULTI_VERSION.bin\e[0m\n";
|
||||
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 "\e[33;1mBuilding multi-avr-usbasp-aetr-CC2500-inv-v$MULTI_VERSION.bin\e[0m\n";
|
||||
opt_disable $ALL_PROTOCOLS;
|
||||
opt_enable $CC2500_PROTOCOLS;
|
||||
opt_disable HITEC_CC2500_INO REDPINE_CC2500_INO OMP_CC2500_INO SKYARTEC_CC2500_INO SCANNER_CC2500_INO;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-avr-usbasp-aetr-CC2500-inv-v$MULTI_VERSION.bin;
|
||||
|
||||
printf "\e[33;1mBuilding multi-avr-usbasp-aetr-CYRF6936-inv-v$MULTI_VERSION.bin\e[0m\n";
|
||||
opt_disable $ALL_PROTOCOLS;
|
||||
opt_enable $CYRF6936_PROTOCOLS;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-avr-usbasp-aetr-CYRF6936-inv-v$MULTI_VERSION.bin;
|
||||
|
||||
exit $exitcode;
|
||||
29
buildroot/bin/build_release_avr_optiboot
Normal file
29
buildroot/bin/build_release_avr_optiboot
Normal file
@@ -0,0 +1,29 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
source ./buildroot/bin/buildFunctions;
|
||||
exitcode=0;
|
||||
|
||||
printf "\e[33;1mBuilding multi-avr-txflash-aetr-A7105-inv-v$MULTI_VERSION.bin\e[0m\n";
|
||||
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 "\e[33;1mBuilding multi-avr-txflash-aetr-CC2500-inv-v$MULTI_VERSION.bin\e[0m\n";
|
||||
opt_disable $ALL_PROTOCOLS;
|
||||
opt_enable $CC2500_PROTOCOLS;
|
||||
opt_disable HITEC_CC2500_INO REDPINE_CC2500_INO OMP_CC2500_INO SKYARTEC_CC2500_INO SCANNER_CC2500_INO;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-avr-txflash-aetr-CC2500-inv-v$MULTI_VERSION.bin;
|
||||
|
||||
printf "\e[33;1mBuilding multi-avr-txflash-aetr-CYRF6936-inv-v$MULTI_VERSION.bin\e[0m\n";
|
||||
opt_disable $ALL_PROTOCOLS;
|
||||
opt_enable $CYRF6936_PROTOCOLS;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-avr-txflash-aetr-CYRF6936-inv-v$MULTI_VERSION.bin;
|
||||
|
||||
exit $exitcode;
|
||||
26
buildroot/bin/build_release_orx
Normal file
26
buildroot/bin/build_release_orx
Normal file
@@ -0,0 +1,26 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
source ./buildroot/bin/buildFunctions;
|
||||
exitcode=0;
|
||||
|
||||
printf "\e[33;1mBuilding multi-orangerx-aetr-green-inv-v$MULTI_VERSION.bin\e[0m\n";
|
||||
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 "\e[33;1mBuilding multi-orangerx-aetr-blue-inv-v$MULTI_VERSION.bin\e[0m\n";
|
||||
opt_enable ORANGE_TX_BLUE;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-orangerx-aetr-blue-inv-v$MULTI_VERSION.bin;
|
||||
|
||||
printf "\e[33;1mPackaging ancilliary files for v$MULTI_VERSION\e[0m\n";
|
||||
cp Multiprotocol/Multi.txt ./binaries/Multi.txt;
|
||||
mkdir -p SCRIPTS/TOOLS;
|
||||
cp Lua_scripts/*.lua SCRIPTS/TOOLS/;
|
||||
cp Lua_scripts/*.txt SCRIPTS/TOOLS/;
|
||||
zip -q ./binaries/MultiLuaScripts.zip SCRIPTS/TOOLS/*;
|
||||
|
||||
exit $exitcode;
|
||||
13
buildroot/bin/build_release_stm32f1_native_debug
Normal file
13
buildroot/bin/build_release_stm32f1_native_debug
Normal file
@@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
source ./buildroot/bin/buildFunctions;
|
||||
exitcode=0;
|
||||
|
||||
printf "\e[33;1mBuilding multi-stm-xn297dump-usbdebug-v$MULTI_VERSION.bin\e[0m\n";
|
||||
opt_disable $ALL_PROTOCOLS;
|
||||
opt_add XN297DUMP_NRF24L01_INO;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-xn297dump-usbdebug-v$MULTI_VERSION.bin;
|
||||
|
||||
exit $exitcode;
|
||||
72
buildroot/bin/build_release_stm32f1_no_debug
Normal file
72
buildroot/bin/build_release_stm32f1_no_debug
Normal file
@@ -0,0 +1,72 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
source ./buildroot/bin/buildFunctions;
|
||||
exitcode=0;
|
||||
|
||||
printf "\e[33;1mBuilding multi-stm-serial-aetr-v$MULTI_VERSION.bin\e[0m\n";
|
||||
opt_disable ENABLE_PPM;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-serial-aetr-v$MULTI_VERSION.bin;
|
||||
|
||||
printf "\e[33;1mBuilding multi-stm-serial-taer-v$MULTI_VERSION.bin\e[0m\n";
|
||||
opt_replace AETR TAER;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-serial-taer-v$MULTI_VERSION.bin;
|
||||
|
||||
printf "\e[33;1mBuilding multi-stm-serial-reta-v$MULTI_VERSION.bin\e[0m\n";
|
||||
opt_replace TAER RETA;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-serial-reta-v$MULTI_VERSION.bin;
|
||||
|
||||
printf "\e[33;1mBuilding multi-stm-cc2500-aetr-v$MULTI_VERSION.bin\e[0m\n";
|
||||
opt_replace RETA AETR;
|
||||
opt_disable A7105_INSTALLED;
|
||||
opt_disable CYRF6936_INSTALLED;
|
||||
opt_disable NRF24L01_INSTALLED;
|
||||
opt_disable INVERT_TELEMETRY;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-cc2500-aetr-v$MULTI_VERSION.bin;
|
||||
|
||||
printf "\e[33;1mBuilding multi-stm-cc2500-taer-v$MULTI_VERSION.bin\e[0m\n";
|
||||
opt_replace AETR TAER;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-cc2500-taer-v$MULTI_VERSION.bin;
|
||||
|
||||
printf "\e[33;1mBuilding multi-stm-cc2500-reta-v$MULTI_VERSION.bin\e[0m\n";
|
||||
opt_replace TAER RETA;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-cc2500-reta-v$MULTI_VERSION.bin;
|
||||
|
||||
printf "\e[33;1mBuilding multi-stm-ppm-aetr-v$MULTI_VERSION.bin\e[0m\n";
|
||||
opt_enable A7105_INSTALLED;
|
||||
opt_enable CYRF6936_INSTALLED;
|
||||
opt_enable NRF24L01_INSTALLED;
|
||||
opt_enable ENABLE_PPM;
|
||||
opt_disable ENABLE_SERIAL;
|
||||
opt_replace RETA AETR;
|
||||
opt_disable MULTI_STATUS;
|
||||
opt_disable MULTI_TELEMETRY;
|
||||
opt_set NBR_BANKS 5;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-ppm-aetr-v$MULTI_VERSION.bin;
|
||||
|
||||
printf "\e[33;1mBuilding multi-stm-ppm-taer-v$MULTI_VERSION.bin\e[0m\n";
|
||||
opt_replace AETR TAER;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-ppm-taer-v$MULTI_VERSION.bin;
|
||||
|
||||
printf "\e[33;1mBuilding multi-stm-ppm-reta-v$MULTI_VERSION.bin\e[0m\n";
|
||||
opt_replace TAER RETA;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-ppm-reta-v$MULTI_VERSION.bin;
|
||||
|
||||
exit $exitcode;
|
||||
13
buildroot/bin/build_release_stm32f1_serial_debug
Normal file
13
buildroot/bin/build_release_stm32f1_serial_debug
Normal file
@@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
source ./buildroot/bin/buildFunctions;
|
||||
exitcode=0;
|
||||
|
||||
printf "\e[33;1mBuilding multi-stm-xn297dump-ftdidebug-v$MULTI_VERSION.bin\e[0m\n";
|
||||
opt_disable $ALL_PROTOCOLS;
|
||||
opt_add XN297DUMP_NRF24L01_INO;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-stm-xn297dump-ftdidebug-v$MULTI_VERSION.bin;
|
||||
|
||||
exit $exitcode;
|
||||
25
buildroot/bin/build_release_stm32f1_t18int
Normal file
25
buildroot/bin/build_release_stm32f1_t18int
Normal file
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
source ./buildroot/bin/buildFunctions;
|
||||
exitcode=0;
|
||||
|
||||
printf "\e[33;1mBuilding multi-t18int-aetr-v$MULTI_VERSION.bin\e[0m\n";
|
||||
opt_disable ENABLE_PPM;
|
||||
opt_disable INVERT_TELEMETRY;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-t18int-aetr-v$MULTI_VERSION.bin;
|
||||
|
||||
printf "\e[33;1mBuilding multi-t18int-taer-v$MULTI_VERSION.bin\e[0m\n";
|
||||
opt_replace AETR TAER;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-t18int-taer-v$MULTI_VERSION.bin;
|
||||
|
||||
printf "\e[33;1mBuilding multi-t18int-reta-v$MULTI_VERSION.bin\e[0m\n";
|
||||
opt_replace TAER RETA;
|
||||
buildMulti;
|
||||
exitcode=$((exitcode+$?));
|
||||
mv build/Multiprotocol.ino.bin ./binaries/multi-t18int-reta-v$MULTI_VERSION.bin;
|
||||
|
||||
exit $exitcode;
|
||||
@@ -103,16 +103,16 @@ Multiprotocol firmware can be compiled and flashed with your customized firmware
|
||||
1. Under **Tools -> Debug Option** select **None**
|
||||
|
||||
### Configure the firmware
|
||||
Make any changes you require to the firmware.
|
||||
Make any changes you require to the firmware by editing the [_config.h](https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/blob/master/Multiprotocol/_Config.h) file which is part of the source package you downloaded. All the firmware configuration is done in this one file which enables full customization and a must for any PPM application.
|
||||
|
||||
The STM32 module has more than enough flash space for all the available protocols so, unlike the Atmega328p-based module, it is not necessary to disable unused protocols.
|
||||
The STM32F103CB module has more than enough flash space for all the available protocols so, unlike the Atmega328p-based or STM32F103C8 module, it is not necessary to disable unused protocols.
|
||||
|
||||
You can still disable protocols if you wish, and you may also enable or disable other optional Multiprotocol features.
|
||||
|
||||
### Verify the firmware
|
||||
To check that the program will compile correctly and fit in the STM32 click **Sketch -> Verify/Compile**, or press **Ctrl+R**.
|
||||
|
||||
If there are errors, carefully read it, go to the line number indicated and correct your typo.
|
||||
If there are errors, carefully read it, go to the line number indicated and correct your typo. Arduino has different ways to indicate that the firmware is too big so check this by removing a large number of protocols and reenable them as you need.
|
||||
|
||||
If there are no errors and you see output like this:
|
||||
```
|
||||
|
||||
@@ -23,7 +23,8 @@ Original FrSky, Futaba, Corona Hitec and HoTT receivers have been frequency-tune
|
||||
The procedure can be performed in serial or PPM mode, but is easier with in serial mode where the effect of the change can be seen in real-time.
|
||||
|
||||
### Preparation
|
||||
The radio needs to be bound with the receiver.
|
||||
The radio needs to be bound with the receiver in order to fine tune. If the receiver does not bind, use *coarse* tuning (varying the **Freq** value in steps of +/- 40) until the receiver binds.
|
||||
|
||||
1. Configure the radio with the appropriate protocol
|
||||
1. Set the **Freq** value to 0
|
||||
1. Put the receiver into **Binding** mode
|
||||
|
||||
@@ -64,8 +64,7 @@ The telemetry mod for these transmitters has evolved. The original and popular
|
||||
|
||||
A good tutorial to follow is Oscar Liang's [here](http://blog.oscarliang.net/turnigy-9x-advance-mod/) but when you get to wiring up the Tx Module bay pins, you only need to perform the steps relevant for Pin 5.
|
||||
|
||||
You can see Midelic's original instructions [here](http://www.rcgroups.com/forums/showpost.php?p=28359305&postcount=2)
|
||||
|
||||
If the telemetry output was wired incorrectly, the Multiprotocol module will not continue past the bootloader (some rapid flashes from the red LED, and then no light).
|
||||
|
||||
## Other Notes:
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
- **_Slower blink(on=1s,off=1s)_**: PPM has been selected but no valid signal is being seen on the PPM pin.
|
||||
- **_Fast double blink(on=0.1s,off=0.1s,on=0.1s,off=0.5s)_**: serial debugging is enabled and is waiting for a serial connection
|
||||
- **_On_**: Module is in normal operation mode (transmitting control signals).
|
||||
- **_SOS_**: Module's CPU does not match the minimum requirement of a full 128KB available/good flash. The module won't boot further. This has been introduced after finding out that some module's manufacturers are using wrong components which are causing unexpected behaviors with bad consequences...
|
||||
|
||||
## Protocol selection
|
||||
|
||||
|
||||
Reference in New Issue
Block a user