Compare commits

...

96 Commits

Author SHA1 Message Date
pascallanger
dd82cbec63 Update Protocols_Details.md 2024-05-17 17:08:01 +02:00
pascallanger
be4595fe67 Update FX_nrf24l01.ino 2024-05-17 14:45:30 +02:00
pascallanger
54ae77ed7f FX/Q560 new sub protocol 2024-05-17 11:01:54 +02:00
pascallanger
2bdbd7088c Traxxas TQ 1st gen: try 5 2024-05-04 11:36:14 +02:00
pascallanger
1d3ed78622 J6Pro update 2024-05-04 11:34:59 +02:00
pascallanger
79b1c54007 Traxxas TQ 1st gen: try 4 2024-05-03 00:15:03 +02:00
pascallanger
81eb5dc6bc Traxxas TQ 1st gen: try 2 2024-04-29 19:43:24 +02:00
pascallanger
85a0e4bde8 Traxxas TQ 1st gen: try 2 2024-04-27 11:23:19 +02:00
pascallanger
63dfa316e8 Traxxas TQ 1st gen: try 1 2024-04-26 19:25:23 +02:00
pascallanger
9d383432a5 Update SGF22_nrf24l01.ino 2024-04-24 07:00:44 +02:00
pascallanger
6b181db629 SLT try 1e 2024-04-18 10:40:37 +02:00
pascallanger
873279dbe9 SLT new sub_protocol V1_4CH 2024-04-15 14:13:37 +02:00
pascallanger
f35be2984a SLT try 1d 2024-04-14 13:29:28 +02:00
pascallanger
7ddeb31e95 SLT try 1c 2024-04-14 13:23:50 +02:00
pascallanger
7444c44b48 SLT try 1b 2024-04-13 10:22:39 +02:00
pascallanger
08d1dcbed2 SLT try 1a 2024-04-12 18:24:50 +02:00
pascallanger
3e4f4e36c1 SLT try 1 2024-04-12 18:20:01 +02:00
pascallanger
902419dd3d Update Protocols_Details.md 2024-04-08 18:36:42 +02:00
pascallanger
038b3b9225 Update Protocols_Details.md 2024-04-04 17:13:35 +02:00
pascallanger
45f0154f4b Update Protocols_Details.md 2024-04-04 16:15:27 +02:00
pascallanger
e03864e35f Traxxas TQ 6 channels 2024-04-04 16:13:35 +02:00
pascallanger
de35ee09f5 Realacc doc update 2024-04-02 16:42:19 +02:00
pascallanger
c88952c35e REALACC: IDs
Any ID
2024-04-02 12:34:04 +02:00
pascallanger
ffae7dda1d Update SGF22_nrf24l01.ino 2024-03-29 16:24:25 +01:00
pascallanger
4f17f76b39 SGF22: new flag 2024-03-29 16:19:20 +01:00
pascallanger
31ef090508 ASF try 4 2024-03-29 15:55:54 +01:00
pascallanger
04d4e39b87 Update _Config.h 2024-03-27 19:34:28 +01:00
pascallanger
b3537ea75a DSM2_SFC try 3 2024-03-26 16:18:34 +01:00
pascallanger
bccc050165 DSM2_SFC try 2 2024-03-26 14:41:19 +01:00
pascallanger
0f0df176de DSM2_SFC try 1
Servo refresh rate -> frame rate 16.5/11ms
2024-03-26 14:37:26 +01:00
pascallanger
5542e7005d ASF try 3 2024-03-26 11:43:42 +01:00
pascallanger
eb35fefd3e ASF try 2 2024-03-25 15:17:51 +01:00
pascallanger
5acc3a8d01 CYRF6936: Findbestchannels flag addition 2024-03-25 15:11:31 +01:00
pascallanger
9e9c3958c6 ASF: try 1 2024-03-23 11:23:42 +01:00
pascallanger
7f3a93ca4c Kyosho3: increase bind time to 2.5s 2024-03-22 18:24:31 +01:00
pascallanger
debc9de11a New protocol Kyosho3/ASF
Only 1 ID and 1 frequency for now
2024-03-22 18:17:21 +01:00
pascallanger
f117105124 SGF22: Fix none working IDs 2024-03-21 16:33:16 +01:00
pascallanger
2e3520acad DSM2SFC timing update 2024-03-19 20:52:50 +01:00
pascallanger
91af921d98 Update Protocols_Details.md 2024-03-19 15:47:56 +01:00
pascallanger
ab45ec6d1c Update Validate.h 2024-03-19 15:44:29 +01:00
pascallanger
26b0b6bd20 Update DSM_cyrf6936.ino 2024-03-19 15:44:21 +01:00
pascallanger
1b9ce32e89 Update DSM_cyrf6936.ino 2024-03-19 14:11:40 +01:00
pascallanger
332e55831c Update Protocols_Details.md 2024-03-18 17:11:23 +01:00
pascallanger
7051438e5d Update Protocols_Details.md 2024-03-18 17:00:40 +01:00
pascallanger
28467fac57 DSM/DSM2SFC new subprotocol 2024-03-18 16:57:54 +01:00
pascallanger
c7513abad8 Update Multiprotocol.h 2024-03-18 09:02:55 +01:00
pascallanger
e6e13c0fdd Docs update 2024-03-17 15:52:42 +01:00
pascallanger
9579a667fc Update REALACC_nrf24l01.ino 2024-03-17 15:28:33 +01:00
pascallanger
cbedda2471 Merge branch 'master' of https://github.com/pascallanger/DIY-Multiprotocol-TX-Module 2024-03-14 20:23:04 +01:00
pascallanger
f8695befe2 REALACC multi IDs 2024-03-14 20:23:02 +01:00
pascallanger
e951e3146b Update Protocols_Details.md (#955) 2024-03-14 20:22:00 +01:00
pascallanger
4c0b46549f EazyRC multi IDs/RFs 2024-02-28 10:46:10 +01:00
pascallanger
188f8ff9ce Radiolink/RC4G: IDs and RFs 2024-02-26 17:20:08 +01:00
pascallanger
bee6e59582 Update EazyRC_nrf24l01.ino 2024-02-24 09:38:42 +01:00
pascallanger
af47462ba7 EazyRC.2 2024-02-23 19:06:20 +01:00
pascallanger
d6ccd4af54 EazyRC.1 2024-02-23 17:51:38 +01:00
pascallanger
0feedc6fa9 New protocol EazyRC 2024-02-23 17:36:02 +01:00
pascallanger
b5bc7c04fb Rename Traxxas/6519 to Traxxas/TQ 2024-02-23 17:19:09 +01:00
pascallanger
a15371d989 Merge branch 'master' of https://github.com/pascallanger/DIY-Multiprotocol-TX-Module 2024-02-23 11:29:35 +01:00
pascallanger
3c82f37e2b Bumping revision 2024-02-23 11:29:19 +01:00
Ben Lye
4f914a18ae Automated build process updates (#950)
* 4-in-1 air and surface builds

* Disable serial and PPM-only builds for STM32 x-in-1

* More air and surface builds

* Fix 5-in-1 tests

* T18 air, surface, and LBT builds

* Remove CFlie from DIY 5-in-1 AIR

* Bump action versions

* v4 artifact merging

* Improve artifact merge

* Fix merge

* DIY 5-in-1 LBT

* Tweak CI job name

* Add T-Lite 5-in-1 LBT

* CI job restructure
2024-02-23 11:26:30 +01:00
pascallanger
1cbce29970 Remove Radiolink/RC4G when MULTI_AIR 2024-02-23 11:06:48 +01:00
pascallanger
e0c44ed5a8 Remove DSMR when MULTI_AIR 2024-02-23 11:05:02 +01:00
pascallanger
390e5dd654 Remove Kyosho/FHSS&SYNC when MULTI_AIR 2024-02-22 17:40:56 +01:00
pascallanger
968293e599 Remove Hisky/HK310 when MULTI_AIR 2024-02-22 17:29:00 +01:00
pascallanger
09ee173e3b Remove Pelikan/SCX24 when MULTI_AIR
Save flash space
2024-02-22 17:14:20 +01:00
pascallanger
babfee0f9e Update RadioLink_cc2500.ino 2024-02-21 13:43:44 +01:00
pascallanger
72da3c5bc5 Create MULTI_AIR / MULTI_SURFACE 2024-02-21 12:31:23 +01:00
Ben Lye
4df1e65a7f Pelikan SCX24 / HPI TF-41 reversed (#917)
* Pelikan SCX24 / HPI TF-41 reversed

* Save some flash and memory

* Save more flash
2024-02-21 12:17:02 +01:00
pascallanger
1459d690d8 Update SGF22_nrf24l01.ino 2024-02-21 11:41:23 +01:00
pascallanger
8d96066215 Merge XK and Tiger protocols 2024-02-21 11:38:31 +01:00
pascallanger
93a5834dd0 Update TRAXXAS_cyrf6936.ino 2024-02-19 21:53:54 +01:00
pascallanger
5f9ac82ed1 SGF22.5 Multiple IDs, 1 set of frequencies 2024-02-19 18:34:27 +01:00
pascallanger
2108912263 Update TRAXXAS_cyrf6936.ino 2024-02-17 11:03:37 +01:00
pascallanger
72f87cade9 XK: new subprotocol Cars
Removed:
 - deadband which was needed on the planes
- force bind since the cars remember the bind info
-
2024-02-17 11:02:52 +01:00
pascallanger
50bd4850fa Radiolink/RC4G
1 ID / 1 set of frequency
2024-02-16 18:03:32 +01:00
pascallanger
dc1490b9b0 SGF22.4 2024-02-16 10:26:48 +01:00
pascallanger
b18adb0efe SGF22.3 2024-02-16 10:24:44 +01:00
pascallanger
53d5684dfd KN: additional trim and flag 2024-02-15 20:52:01 +01:00
pascallanger
724abbc935 SGF22.2 2024-02-15 18:24:58 +01:00
pascallanger
de610b53fc SGF22.1 2024-02-15 16:28:52 +01:00
pascallanger
dd7ee7bdce SGF22 2024-02-15 16:20:37 +01:00
pascallanger
31a9f6860d New protocol SGF22
Only 1 ID!
2024-02-15 15:51:20 +01:00
pascallanger
4a66ae64c6 Update Protocols_Details.md (#940) 2024-02-06 12:06:34 +01:00
pascallanger
11ae26a431 Update Protocols_Details.md 2024-01-31 19:27:54 +01:00
pascallanger
cdabde5d67 Kyosho FHSS and Syncro
Automatically binding a FHSS or a Syncro RX using FHSS
2024-01-31 19:22:36 +01:00
pascallanger
ce75dd3355 Kyosho FHSS/SYNCRO cleanup 2024-01-30 14:53:28 +01:00
pascallanger
69484b5278 Second try 2024-01-30 14:42:24 +01:00
pascallanger
a90e1f2d3a Update Bluefly_ccnrf.ino
Exclude this protocol since it's not working
2024-01-30 14:36:38 +01:00
pascallanger
5af246bba0 Update _Config.h 2024-01-30 12:33:21 +01:00
pascallanger
75a46858da Update Kyosho_a7105.ino 2024-01-30 12:25:25 +01:00
pascallanger
8ac53657ec Kyosho updqte
fixed crash
2024-01-30 12:06:37 +01:00
pascallanger
2888d3e937 TRAXXAS TQ WIP
It still won't work unless you have some luck. I still need to work on the RF frequency.
2024-01-29 18:59:24 +01:00
pascallanger
3d989a47db Typo... 2024-01-29 18:45:32 +01:00
pascallanger
a7d6d12679 Kyosho Syncro
Sub protocol Syncro for KT-331 and KR-331
2024-01-29 17:00:54 +01:00
pascallanger
457703b881 Update Protocols_Details.md 2024-01-18 12:16:59 +01:00
43 changed files with 2399 additions and 849 deletions

View File

@@ -1,6 +1,6 @@
# Workflow for testing MULTI-Module firmware builds
name: CI
name: MULTI Test, Build, Deploy, Release
on:
# Trigger the workflow on pushes, except those that are tagged (avoids double-testing releases)
@@ -32,7 +32,7 @@ on:
workflow_dispatch:
jobs:
build:
test:
runs-on: ubuntu-latest
# Configure the board matrix
@@ -51,21 +51,21 @@ jobs:
- board: "multi4in1:STM32F1:multistm32f103cb:debug_option=none"
name: "STM32F103 (128KB)"
- board: "multi4in1:STM32F1:multistm32f103cb:debug_option=native"
name: "STM32F103 (128KB, USB Debugging)"
name: "STM32F103 (128KB, USB Debug)"
- board: "multi4in1:STM32F1:multistm32f103cb:debug_option=ftdi"
name: "STM32F103 (128KB, Serial Debugging)"
name: "STM32F103 (128KB, Serial Debug)"
- board: "multi4in1:STM32F1:multi5in1t18int"
name: "T18 5-in-1 (128KB)"
# Set the build name using the friendly board name
name: ${{ matrix.name }}
name: "[Test] ${{ matrix.name }}"
# Set the environment variables
env:
BOARD: ${{ matrix.board }}
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Install Arduino CLI
uses: arduino/setup-arduino-cli@v1.1.2
@@ -161,23 +161,38 @@ jobs:
- name: Build serial only
run: |
source ./buildroot/bin/buildFunctions;
cp ./_Config.h.bak Multiprotocol/_Config.h
opt_disable ENABLE_PPM;
buildMulti;
# Skip the serial-only build for boards where it's too large now
if [[ "$BOARD" =~ ":STM32F1:multistm32f103cb:debug_option=none" ]] || [[ "$BOARD" =~ ":STM32F1:multi5in1t18int" ]]; then
printf "Not testing serial-only build for $BOARD.";
else
source ./buildroot/bin/buildFunctions;
cp ./_Config.h.bak Multiprotocol/_Config.h
opt_disable ENABLE_PPM;
buildMulti;
fi
- name: Build PPM only
run: |
source ./buildroot/bin/buildFunctions;
cp ./_Config.h.bak Multiprotocol/_Config.h
opt_disable ENABLE_SERIAL;
buildMulti;
# Skip the PPM-only build for boards where it's too large now
if [[ "$BOARD" =~ ":STM32F1:multistm32f103cb:debug_option=none" ]] || [[ "$BOARD" =~ ":STM32F1:multi5in1t18int" ]]; then
printf "Not testing PPM-only build for $BOARD.";
else
source ./buildroot/bin/buildFunctions;
cp ./_Config.h.bak Multiprotocol/_Config.h
opt_disable ENABLE_SERIAL;
buildMulti;
fi
- name: Build each RF module individually
run: |
source ./buildroot/bin/buildFunctions;
cp ./_Config.h.bak Multiprotocol/_Config.h;
buildEachRFModule;
# Skip the per-RF module builds for boards which have fixed modules
if [[ "$BOARD" =~ ":STM32F1:multi5in1t18int" ]]; then
printf "Not testing individual RF module builds for $BOARD.";
else
source ./buildroot/bin/buildFunctions;
cp ./_Config.h.bak Multiprotocol/_Config.h;
buildEachRFModule;
fi
- name: Build each protocol individually
run: |
@@ -185,6 +200,128 @@ jobs:
cp ./_Config.h.bak Multiprotocol/_Config.h;
buildEachProtocol;
build:
runs-on: ubuntu-latest
# Configure the board matrix
strategy:
fail-fast: false
matrix:
include:
- board: "multi4in1:avr:multiatmega328p:bootloader=none"
name: "ATmega328p"
release: "atmega328p"
- board: "multi4in1:avr:multiatmega328p:bootloader=optiboot"
name: "ATmega328p (Optiboot)"
release: "atmega328p-optiboot"
- board: "multi4in1:avr:multixmega32d4"
name: "OrangeRX"
release: "orangerx"
- board: "multi4in1:STM32F1:multistm32f103c8:debug_option=none"
name: "STM32F103 CC2500 (64KB)"
release: "stm32f103-cc2500-64k"
- board: "multi4in1:STM32F1:multistm32f103cb:debug_option=none"
name: "STM32F103 CC2500 (128KB)"
release: "stm32f103-cc2500-128k"
- board: "multi4in1:STM32F1:multistm32f103cb:debug_option=none"
name: "STM32F103 (128KB)"
release: "stm32f103-128k-4in1"
- board: "multi4in1:STM32F1:multistm32f103cb:debug_option=native"
name: "STM32F103 (128KB, USB Debug)"
release: "stm32f103-128k-usb-debug"
- board: "multi4in1:STM32F1:multistm32f103cb:debug_option=ftdi"
name: "STM32F103 (128KB, Serial Debug)"
release: "stm32f103-128k-serial-debug"
- board: "multi4in1:STM32F1:multistm32f103cb:debug_option=none"
name: "STM32F103 5-in-1 (128KB)"
release: "stm32f103-128k-5in1"
- board: "multi4in1:STM32F1:multistm32f103cb:debug_option=none"
name: "T-Lite 5-in-1 (128KB)"
release: "tlite-5in1"
- board: "multi4in1:STM32F1:multi5in1t18int"
name: "T18 5-in-1 (128KB)"
release: "t18-5in1"
- board: "none"
name: "Scripts"
release: "scripts"
# Set the build name using the friendly board name
name: "[Build] ${{ matrix.name }}"
# Set the environment variables
env:
BOARD: ${{ matrix.board }}
RELEASE: ${{ matrix.release }}
steps:
- uses: actions/checkout@v4
- name: Install Arduino CLI
uses: arduino/setup-arduino-cli@v1.1.2
with:
version: "0.32.2"
- 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,https://raw.githubusercontent.com/pascallanger/DIY-Multiprotocol-TX-Module-Boards/devel/source/package_multi_4in1_board_devel_index.json
arduino-cli core update-index
if [[ "$BOARD" =~ ":avr:" ]]; then
arduino-cli core install arduino:avr;
fi
if [[ "$BOARD" =~ "multi4in1-devel:avr" ]]; then
arduino-cli core install multi4in1-devel:avr
elif [[ "$BOARD" =~ "multi4in1:avr" ]]; then
arduino-cli core install multi4in1:avr
fi
if [[ "$BOARD" =~ "multi4in1-devel:STM32F1:" ]]; then
arduino-cli core install multi4in1-devel:STM32F1
elif [[ "$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 "CCNRF_INO_PROTOCOLS=$(echo $CCNRF_INO_PROTOCOLS)" >> $GITHUB_ENV
echo "ALL_PROTOCOLS=$(echo $ALL_PROTOCOLS)" >> $GITHUB_ENV
# Disable CHECK_FOR_BOOTLOADER when not needed
if [[ "$BOARD" =~ ":avr:multiatmega328p:bootloader=none" ]]; then
opt_disable CHECK_FOR_BOOTLOADER;
fi
- name: Save default firmware configuration
run: |
cat Multiprotocol/_Config.h
cp Multiprotocol/_Config.h ./_Config.h.bak
- name: Build release files
run: |
source ./buildroot/bin/buildFunctions;
@@ -199,16 +336,43 @@ jobs:
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@v3
uses: actions/upload-artifact/@v4
with:
name: multi-${{ matrix.release }}
path: ./binaries/
deploy:
name: "[Deploy] Attach Build Artifacts"
runs-on: ubuntu-latest
needs: [test, build]
steps:
- name: Combine and upload build artifacts
uses: actions/upload-artifact/merge@v4
with:
name: multi-test-build
path: ./binaries/
pattern: multi-*
delete-merged: true
retention-days: 90
release:
name: "[Release] Publish Files to Release"
if: github.event_name == 'release' && github.event.action == 'created'
runs-on: ubuntu-latest
needs: deploy
steps:
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: multi-test-build
path: ./artifacts/
- name: Display downloaded artifacts
run: ls -R ./artifacts/
- name: Deploy artifacts to release
uses: AButler/upload-release-assets@v3.0
with:
files: './artifacts/*'
repo-token: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -35,6 +35,7 @@
6,3,DSM,X_2F,0,CH5,CH6,CH7,CH8,CH9,CH10,CH11,CH12,n-a,ThKill
6,4,DSM,AUTO,0,CH5,CH6,CH7,CH8,CH9,CH10,CH11,CH12,n-a,ThKill
6,5,DSM,R_1F,0,AUX3,AUX4,AUX5
6,6,DSM,2SFC,0
70,0,DSM_RX,RX,0,CH5,CH6,CH7,CH8,CH9,CH10,CH11,CH12
70,1,DSM_RX,CPPM,0,CH5,CH6,CH7,CH8,CH9,CH10,CH11,CH12
45,0,E01X,E012,1,n-a,Flip,n-a,HLess,RTH
@@ -89,6 +90,7 @@
58,0,FX,816,1
58,1,FX,620,1
58,2,FX,9630,1,Rate,Gyro,TrimR,TrimA,TrimE
58,3,FX,Q560,1,FLIP,Gyro,LEDs
20,0,FY326,FY326,1,Flip,RTH,HLess,Expert,Calib
20,1,FY326,FY319,1,Flip,RTH,HLess,Expert,Calib
23,0,FY326,FY326,1,Flip,RTH,HLess,Expert
@@ -119,9 +121,10 @@
49,0,KF606,KF606,1,Trim
49,1,KF606,MIG320,1,Trim,LED
49,2,KF606,ZCZ50,1,Trim,UNK
9,0,KN,WLToys,0,DRate,THold,IdleUp,Gyro,Ttrim,Atrim,Etrim
9,1,KN,Feilun,0,DRate,THold,IdleUp,Gyro,Ttrim,Atrim,Etrim
73,0,Kyosho,Std,0,CH5,CH6,CH7,CH8,CH9,CH10,CH11,CH12,CH13,CH14
9,0,KN,WLToys,0,DRate,THold,IdleUp,Gyro,Ttrim,Atrim,Etrim,Rtrim,Hover
9,1,KN,Feilun,0,DRate,THold,IdleUp,Gyro,Ttrim,Atrim,Etrim,Rtrim,Hover
73,0,Kyosho,FHSS,0,CH5,CH6,CH7,CH8,CH9,CH10,CH11,CH12,CH13,CH14
73,1,Kyosho,Hype,0,CH5,CH6
18,0,MJXQ,WHL08,1,Flip,LED,Pict,Video,HLess,RTH,AuFlip,Pan,Tilt,Rate
18,1,MJXQ,X600,1,Flip,LED,Pict,Video,HLess,RTH,AuFlip,Pan,Tilt,Rate
18,2,MJXQ,X800,1,Flip,LED,Pict,Video,HLess,RTH,AuFlip,Pan,Tilt,Rate
@@ -155,7 +158,8 @@
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
74,3,RadioLink,RC4G,0,CH5,FS_CH1,FS_CH2,FS_CH3,FS_CH4
76,0,Realacc,Std,1,Flip,Light,Calib,HLess,RTH,ThCut,Rotat
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,Futaba,SFHSS,0,CH5,CH6,CH7,CH8
@@ -166,10 +170,10 @@
11,2,SLT,Q100,0,Rates,n-a,CH7,CH8,Mode,Flip,n-a,n-a,Calib
11,3,SLT,Q200,0,Rates,n-a,CH7,CH8,Mode,VidOn,VidOff,Calib
11,4,SLT,MR100,0,Rates,n-a,CH7,CH8,Mode,Flip,Video,Pict
11,5,SLT,V1_4CH,0
10,0,Symax,Std,1,Flip,Rates,Pict,Video,HLess
10,1,Symax,X5C,1,Flip,Rates,Pict,Video,HLess
61,0,Tiger,Std,1,Flip,Light
43,0,Traxxas,6519,0
43,0,Traxxas,TQ,0
5,0,V2x2,Std,1,Flip,Light,Pict,Video,HLess,CalX,CalY
5,1,V2x2,JXD506,1,Flip,Light,Pict,Video,HLess,StaSto,Emerg,Cam_UD
48,0,V761,3CH,0,Gyro,Calib,Flip,RtnAct,Rtn
@@ -185,7 +189,8 @@
30,4,WK2x01,W6HEL,0,Gear,Col,Gyro
30,5,WK2x01,W6HEL_I,0,Gear,Col,Gyro
62,0,XK,X450,1,FMode,TakeOf,Emerg,3D_6G,Pict,Video
62,1,XK,X420,1,FMode,TakeOf,Emerg,3D_6G,Pict,Video
62,1,XK,X420,1,FMode,TakeOf,Emerg,3D_6G,Pict,Video,Flip,Light
62,2,XK,Cars,0,FMode,TakeOf,Emerg,3D_6G,Pict,Video,Flip,Light
8,0,YD717,Std,1,Flip,Light,Pict,Video,HLess
8,1,YD717,SkyWlkr,1,Flip,Light,Pict,Video,HLess
8,2,YD717,Simax4,1,Flip,Light,Pict,Video,HLess
@@ -211,3 +216,6 @@
94,0,Scorpio
95,0,Bluefly,HP100,0,CH5,CH6,CH7,CH8
96,0,BumbleB
97,0,SGF22,Std,1,Mode,Flip,LED,Pict,Video,TrRes
61,1,EazyRC
98,0,Kyosho3,ASF,0

View File

@@ -418,10 +418,10 @@ void A7105_Init(void)
#ifdef KYOSHO_A7105_INO
if(protocol==PROTO_KYOSHO)
{
if(sub_protocol==KYOSHO_FHSS)
A7105_Regs=(uint8_t*)KYOSHO_A7105_regs;
else
if(sub_protocol==KYOSHO_HYPE)
A7105_Regs=(uint8_t*)KYOSHO_HYPE_A7105_regs;
else //FHSS && SYNCRO
A7105_Regs=(uint8_t*)KYOSHO_A7105_regs;
}
#endif
}
@@ -446,7 +446,7 @@ void A7105_Init(void)
}
A7105_Strobe(A7105_STANDBY);
if(protocol==PROTO_KYOSHO && sub_protocol==KYOSHO_FHSS)
if(protocol==PROTO_KYOSHO && sub_protocol!=KYOSHO_HYPE)
{//strange calibration...
//IF Filter Bank Calibration
A7105_WriteReg(A7105_02_CALC,0x0F);

View File

@@ -249,7 +249,7 @@ void CYRF_WriteDataPacket(const uint8_t dpbuffer[])
}
*/
//NOTE: This routine will reset the CRC Seed
void CYRF_FindBestChannels(uint8_t *channels, uint8_t len, uint8_t minspace, uint8_t min, uint8_t max)
void CYRF_FindBestChannels(uint8_t *channels, uint8_t len, uint8_t minspace, uint8_t min, uint8_t max, uint8_t forced)
{
#define NUM_FREQ 80
#define FREQ_OFFSET 4
@@ -269,7 +269,12 @@ void CYRF_FindBestChannels(uint8_t *channels, uint8_t len, uint8_t minspace, uin
delayMilliseconds(1);
for(i = 0; i < NUM_FREQ; i++)
{
CYRF_ConfigRFChannel(protocol==PROTO_LOSI?i|1:i);
if(((i&1) && forced == FIND_CHANNEL_EVEN) || (!(i&1) && forced == FIND_CHANNEL_ODD))
{
rssi[i] = 0xFF;
continue;
}
CYRF_ConfigRFChannel(i); //protocol==PROTO_LOSI?i|1:i);
delayMicroseconds(270); //slow channel require 270usec for synthesizer to settle
if( !(CYRF_ReadRegister(CYRF_05_RX_CTRL) & 0x80)) {
CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x80); //Prepare to receive
@@ -298,7 +303,7 @@ void CYRF_FindBestChannels(uint8_t *channels, uint8_t len, uint8_t minspace, uin
CYRF_WriteRegister(CYRF_29_RX_ABORT, 0x00); // Clear abort RX
}
#if defined(DEVO_CYRF6936_INO) || defined(J6PRO_CYRF6936_INO)
#if defined(DEVO_CYRF6936_INO) || defined(J6PRO_CYRF6936_INO) || defined(TRAXXAS_CYRF6936_INO)
const uint8_t PROGMEM DEVO_j6pro_sopcodes[][8] = {
/* Note these are in order transmitted (LSB 1st) */
{0x3C, 0x37, 0xCC, 0x91, 0xE2, 0xF8, 0xCC, 0x91},
@@ -311,7 +316,7 @@ const uint8_t PROGMEM DEVO_j6pro_sopcodes[][8] = {
{0xB9, 0x8E, 0x19, 0x74, 0x6F, 0x65, 0x18, 0x74},
{0xDF, 0xB1, 0xC0, 0x49, 0x62, 0xDF, 0xC1, 0x49},
{0x97, 0xE5, 0x14, 0x72, 0x7F, 0x1A, 0x14, 0x72},
#if defined(J6PRO_CYRF6936_INO)
#if defined(J6PRO_CYRF6936_INO) || defined(TRAXXAS_CYRF6936_INO)
{0x82, 0xC7, 0x90, 0x36, 0x21, 0x03, 0xFF, 0x17},
{0xE2, 0xF8, 0xCC, 0x91, 0x3C, 0x37, 0xCC, 0x91}, //Note: the '03' was '9E' in the Cypress recommended table
{0xAD, 0x39, 0xA2, 0x0F, 0x9B, 0xC5, 0xA1, 0x0F}, //The following are the same as the 1st 8 above,
@@ -321,6 +326,7 @@ const uint8_t PROGMEM DEVO_j6pro_sopcodes[][8] = {
{0xB6, 0x31, 0xAE, 0x46, 0x5A, 0xCC, 0xAE, 0x46},
{0x9E, 0x82, 0xDC, 0x3C, 0xA1, 0x78, 0xDC, 0x3C},
{0x6F, 0x65, 0x18, 0x74, 0xB9, 0x8E, 0x19, 0x74},
{0x62, 0xDF, 0xC1, 0x49, 0xDF, 0xB1, 0xC0, 0x49}, //j6pro bind
#endif
};
#endif
@@ -328,8 +334,13 @@ const uint8_t PROGMEM DEVO_j6pro_sopcodes[][8] = {
static void __attribute__((unused)) CYRF_PROGMEM_ConfigSOPCode(const uint8_t *data)
{
uint8_t code[8];
//debug("SOP:");
for(uint8_t i=0;i<8;i++)
{
code[i]=pgm_read_byte_near(&data[i]);
//debug(" %02X",code[i]);
}
//debugln("");
CYRF_ConfigSOPCode(code);
}

View File

@@ -267,6 +267,7 @@ uint16_t DSM_RX_callback()
0x01 => 22ms 1024 DSM2 1 packet => number of channels is <8
0x02 => 22ms 1024 DSM2 2 packets => either a number of channel >7
0x12 => 11ms 2048 DSM2 2 packets => can be any number of channels
0x23 => DX3R DSM2 2 surface packets
0xA2 => 22ms 2048 DSMX 1 packet => number of channels is <8
0xB2 => 11ms 2048 DSMX => can be any number of channels
(0x01 or 0xA2) and num_ch < 7 => 22ms else 11ms

View File

@@ -19,11 +19,10 @@
//#define DSM_DEBUG_FWD_PGM
//#define DEBUG_BIND 1
//#define DSM_GR300
#define CLONE_BIT_MASK 0x20
#define DSM_BIND_CHANNEL 0x0d //13 This can be any odd channel
#define CLONE_BIT_MASK 0x20
#define DSM_BIND_CHANNEL 0x0D //13 This can be any odd channel
#define DSM2_SFC_PERIOD 16500
//During binding we will send BIND_COUNT packets
//One packet each 10msec
@@ -32,8 +31,8 @@
// Lemon-RX G2s seems to have a timeout waiting for the channel to get quiet after the
// first good BIND packet.. If using 3s (300), Lemon-RX will not transmit the BIND-Response packet.
#define DSM_BIND_COUNT 180 // About 1.8s
#define DSM_BIND_COUNT_READ 600 // About 4.2s of waiting for Response
#define DSM_BIND_COUNT 180 // About 1.8s
#define DSM_BIND_COUNT_READ 600 // About 4.2s of waiting for Response
enum {
DSM_BIND_WRITE=0,
@@ -95,9 +94,12 @@ static void __attribute__((unused)) DSM_build_bind_packet()
packet[11] = 12;
else
packet[11] = num_ch; // DX5 DSMR sends 0x48...
//packet[11] = 3; // DX3R
if (sub_protocol==DSMR)
packet[12] = 0xa2;
else if (sub_protocol==DSM2_SFC)
packet[12] = 0x23; // DX3R
else if (sub_protocol==DSM2_1F)
packet[12] = num_ch<8?0x01:0x02; // DSM2/1024 1 or 2 packets depending on the number of channels
else if(sub_protocol==DSM2_2F)
@@ -110,7 +112,6 @@ static void __attribute__((unused)) DSM_build_bind_packet()
#endif
else // DSMX_2F && DSM_AUTO
packet[12] = 0xb2; // DSMX/2048 2 packets
packet[13] = 0x00; //???
for(i = 8; i < 14; i++)
@@ -137,8 +138,13 @@ static void __attribute__((unused)) DSM_update_channels()
if(num_ch<3 || num_ch>12)
num_ch=6; // Default to 6 channels if invalid choice...
if(sub_protocol==DSMR && num_ch>7)
num_ch=7; // Max 7 channels in DSMR
#ifndef MULTI_AIR
if(sub_protocol==DSMR && num_ch>7)
num_ch=7; // Max 7 channels in DSMR
if(sub_protocol==DSM2_SFC && num_ch>5)
num_ch=5; // Max 5 channels in DSM2_SFC
#endif
// Create channel map based on number of channels and refresh rate
uint8_t idx=num_ch-3;
@@ -174,19 +180,25 @@ static void __attribute__((unused)) DSM_build_data_packet(uint8_t upper)
bits=10; // Only DSM2_1F is using a resolution of 1024
}
if(sub_protocol == DSMR)
{
for (uint8_t i = 0; i < 7; i++)
{
uint16_t value = 0x0000;
if(i < num_ch)
value=Channel_data[i]<<1;
packet[i*2+2] = (value >> 8) & 0xff;
packet[i*2+3] = (value >> 0) & 0xff;
#ifndef MULTI_AIR
if(sub_protocol == DSMR || sub_protocol == DSM2_SFC)
{ // 12 bits, full range, no reassignment
for (uint8_t i = 0; i < 7; i++)
{
uint16_t value = 0x0000;
if(i < num_ch)
{
value=Channel_data[i]<<1;
if(sub_protocol == DSM2_SFC)
value |= i<<12;
}
packet[i*2+2] = (value >> 8) & 0xff;
packet[i*2+3] = (value >> 0) & 0xff;
}
return;
}
return;
}
#endif
#ifdef DSM_THROTTLE_KILL_CH
uint16_t kill_ch=Channel_data[DSM_THROTTLE_KILL_CH-1];
#endif
@@ -264,8 +276,18 @@ static uint8_t __attribute__((unused)) DSM_Check_RX_packet()
uint16_t DSM_callback()
{
#if defined MULTI_EU
if(sub_protocol == DSM2_1F || sub_protocol == DSM2_2F)
if(sub_protocol == DSM2_1F || sub_protocol == DSM2_2F || sub_protocol == DSM2_SFC)
{
SUB_PROTO_INVALID;
return 11000;
}
#endif
#if defined MULTI_AIR
if(sub_protocol == DSMR || sub_protocol == DSM2_SFC)
{
SUB_PROTO_INVALID;
return 11000;
}
#endif
#define DSM_CH1_CH2_DELAY 4010 // Time between write of channel 1 and channel 2
#ifdef STM32_BOARD
@@ -279,12 +301,7 @@ uint16_t DSM_callback()
uint8_t len;
#endif
uint8_t start;
#ifdef DSM_GR300
uint16_t timing=5000+(convert_channel_8b(CH13)*100);
debugln("T=%u",timing);
#endif
//debugln("P=%d",phase);
switch(phase)
{
case DSM_BIND_WRITE:
@@ -298,11 +315,11 @@ uint16_t DSM_callback()
return 10000;
#if defined DSM_TELEMETRY
case DSM_BIND_CHECK:
#if DEBUG_BIND
debugln("Bind Check");
#endif
//64 SDR Mode is configured so only the 8 first values are needed
CYRF_ConfigDataCode((const uint8_t *)"\x98\x88\x1B\xE4\x30\x79\x03\x84");
#if DEBUG_BIND
debugln("Bind Check");
#endif
//64 SDR Mode is configured so only the 8 first values are needed
CYRF_ConfigDataCode((const uint8_t *)"\x98\x88\x1B\xE4\x30\x79\x03\x84");
CYRF_SetTxRxMode(RX_EN); //Receive mode
CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x87); //Prepare to receive
bind_counter=DSM_BIND_COUNT_READ; //Timeout of 4.2s if no packet received
@@ -365,25 +382,38 @@ uint16_t DSM_callback()
CYRF_SetTxRxMode(TX_EN);
hopping_frequency_no = 0;
phase = DSM_CH1_WRITE_A; // in fact phase++
#ifndef MULTI_AIR
if(sub_protocol == DSMR)
DSM_set_sop_data_crc(false, true);
else
#endif
DSM_set_sop_data_crc(true, sub_protocol==DSMX_2F||sub_protocol==DSMX_1F); //prep CH1
return 10000;
case DSM_CH1_WRITE_A:
#ifdef MULTI_SYNC
telemetry_set_input_sync(11000); // Always request 11ms spacing even if we don't use half of it in 22ms mode
if(sub_protocol!=DSM2_SFC || option&0x40) // option&40 in this case is 16.5ms/11ms frame rate for DSM2_SFC
telemetry_set_input_sync(11000); // Always request 11ms spacing even if we don't use half of it in 22ms mode
else
telemetry_set_input_sync(DSM2_SFC_PERIOD);
#endif
#ifndef MULTI_AIR
if(sub_protocol == DSMR)
CYRF_SetPower(0x08); //Keep transmit power in sync
else
#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:
CYRF_ReadRegister(CYRF_04_TX_IRQ_STATUS); // clear IRQ flags
CYRF_WriteDataPacket(packet);
//debugln_time("");
#ifndef MULTI_AIR
if(sub_protocol==DSM2_SFC)
CYRF_WriteDataPacketLen(packet,2*(num_ch+1));
else
#endif
CYRF_WriteDataPacket(packet);
#if 0
for(uint8_t i=0;i<16;i++)
debug(" %02X", packet[i]);
@@ -420,14 +450,19 @@ uint16_t DSM_callback()
phase++; // change from CH2_CHECK to CH2_READ
CYRF_SetTxRxMode(RX_EN); //Receive mode
CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x87); //0x80??? //Prepare to receive
if(sub_protocol==DSMR)
{
phase = DSM_CH2_READ_B;
return 11000 - DSM_WRITE_DELAY - DSM_READ_DELAY;
}
#ifdef DSM_GR300
if(num_ch==3)
return timing - DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY - DSM_READ_DELAY;
#ifndef MULTI_AIR
if(sub_protocol==DSMR || sub_protocol == DSM2_SFC)
{
phase = DSM_CH2_READ_B;
if(sub_protocol == DSM2_SFC)
{
if(option&0x40) // option&40 in this case is 16.5ms/11ms frame rate for DSM2_SFC
return 11000 - DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY - DSM_READ_DELAY;
else
return DSM2_SFC_PERIOD - DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY - DSM_READ_DELAY;
}
return 11000 - DSM_WRITE_DELAY - DSM_READ_DELAY;
}
#endif
return 11000 - DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY - DSM_READ_DELAY;
case DSM_CH2_READ_A:
@@ -462,10 +497,6 @@ uint16_t DSM_callback()
CYRF_WriteRegister(CYRF_29_RX_ABORT, 0x00); // Clear abort RX operation
CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x87); //0x80??? //Prepare to receive
phase = DSM_CH2_READ_B;
#ifdef DSM_GR300
if(num_ch==3)
return timing;
#endif
return 11000;
}
if (phase == DSM_CH2_READ_A)
@@ -486,19 +517,20 @@ uint16_t DSM_callback()
else
{ //Normal mode 22ms
phase = DSM_CH1_WRITE_A; // change from CH2_CHECK_A to CH1_WRITE_A (ie no upper)
#ifdef DSM_GR300
if(num_ch==3)
return timing - DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY ;
#ifndef MULTI_AIR
if(sub_protocol==DSM2_SFC)
{
if(option&0x40) // option&40 in this case is 16.5ms/11ms frame rate for DSM2_SFC
return 11000 - DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY ;
else
return DSM2_SFC_PERIOD - DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY ;
}
#endif
return 22000 - DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY ;
}
}
else
phase = DSM_CH1_WRITE_A; // change from CH2_CHECK_B to CH1_WRITE_A (upper already transmitted so transmit lower)
#ifdef DSM_GR300
if(num_ch==3)
return timing - DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY ;
#endif
return 11000 - DSM_CH1_CH2_DELAY - DSM_WRITE_DELAY;
#endif
}
@@ -506,6 +538,7 @@ uint16_t DSM_callback()
}
#ifndef MULTI_AIR
const uint8_t PROGMEM DSMR_ID_FREQ[][4 + 23] = {
{ 0x71, 0x74, 0x1c, 0xe4, 0x11, 0x2f, 0x17, 0x3d, 0x23, 0x3b, 0x0f, 0x21, 0x25, 0x49, 0x1d, 0x13, 0x4d, 0x1f, 0x41, 0x4b, 0x47, 0x05, 0x27, 0x15, 0x19, 0x3f, 0x07 },
{ 0xfe, 0xfe, 0xfe, 0xfe, 0x45, 0x31, 0x33, 0x4b, 0x11, 0x29, 0x49, 0x3f, 0x09, 0x13, 0x47, 0x21, 0x1d, 0x43, 0x1f, 0x05, 0x41, 0x19, 0x1b, 0x2d, 0x15, 0x4d, 0x0f },
@@ -529,22 +562,25 @@ const uint8_t PROGMEM DSMR_ID_FREQ[][4 + 23] = {
{ 0xff, 0xff, 0x00, 0x00, 0x2b, 0x35, 0x1b, 0x1d, 0x0f, 0x47, 0x09, 0x0d, 0x45, 0x41, 0x21, 0x11, 0x2f, 0x43, 0x27, 0x33, 0x4b, 0x37, 0x13, 0x19, 0x4d, 0x23, 0x17 },
{ 0x00, 0xff, 0x00, 0x00, 0x1b, 0x1d, 0x33, 0x13, 0x2b, 0x27, 0x09, 0x41, 0x25, 0x17, 0x19, 0x2d, 0x4b, 0x37, 0x45, 0x11, 0x21, 0x0d, 0x3d, 0x4d, 0x07, 0x39, 0x43 },
{ 0xff, 0x00, 0x00, 0x00, 0x37, 0x27, 0x43, 0x4b, 0x39, 0x13, 0x07, 0x0d, 0x25, 0x17, 0x29, 0x1b, 0x1d, 0x45, 0x19, 0x2d, 0x0b, 0x3d, 0x15, 0x47, 0x1f, 0x21, 0x4d } };
#endif
void DSM_init()
{
if(sub_protocol == DSMR)
{
if(option&CLONE_BIT_MASK)
SUB_PROTO_INVALID;
else
{
SUB_PROTO_VALID;
uint8_t row = rx_tx_addr[3]%22;
for(uint8_t i=0; i< 4; i++)
cyrfmfg_id[i] = pgm_read_byte_near(&DSMR_ID_FREQ[row][i]);
for(uint8_t i=0; i< 23; i++)
hopping_frequency[i] = pgm_read_byte_near(&DSMR_ID_FREQ[row][i+4]);
}
#ifndef MULTI_AIR
if(option&CLONE_BIT_MASK)
SUB_PROTO_INVALID;
else
{
//SUB_PROTO_VALID;
uint8_t row = rx_tx_addr[3]%22;
for(uint8_t i=0; i< 4; i++)
cyrfmfg_id[i] = pgm_read_byte_near(&DSMR_ID_FREQ[row][i]);
for(uint8_t i=0; i< 23; i++)
hopping_frequency[i] = pgm_read_byte_near(&DSMR_ID_FREQ[row][i+4]);
}
#endif
}
else
{
@@ -556,25 +592,25 @@ void DSM_init()
uint16_t temp = DSM_CLONE_EEPROM_OFFSET;
for(uint8_t i=0;i<4;i++)
cyrfmfg_id[i] = eeprom_read_byte((EE_ADDR)temp++);
#if DEBUG_BIND
debugln("Using cloned ID");
debug("Clone ID=")
for(uint8_t i=0;i<4;i++)
debug("%02x ", cyrfmfg_id[i]);
debugln("");
#endif
#if DEBUG_BIND
debugln("Using cloned ID");
debug("Clone ID=")
for(uint8_t i=0;i<4;i++)
debug("%02x ", cyrfmfg_id[i]);
debugln("");
#endif
}
else
{
SUB_PROTO_INVALID;
#if DEBUG_BIND
#if DEBUG_BIND
debugln("No valid cloned ID");
#endif
#endif
}
}
else
{
SUB_PROTO_VALID;
//SUB_PROTO_VALID;
CYRF_GetMfgData(cyrfmfg_id);
}
}
@@ -590,8 +626,8 @@ void DSM_init()
//Fix for OrangeRX using wrong DSM_pncodes by preventing access to "Col 8"
if(sop_col==0 && sub_protocol != DSMR)
{
cyrfmfg_id[rx_tx_addr[0]%3]^=0x01; //Change a bit so sop_col will be different from 0
sop_col = (cyrfmfg_id[0] + cyrfmfg_id[1] + cyrfmfg_id[2] + 2) & 0x07;
cyrfmfg_id[rx_tx_addr[0]%3]^=0x01; //Change a bit so sop_col will be different from 0
sop_col = (cyrfmfg_id[0] + cyrfmfg_id[1] + cyrfmfg_id[2] + 2) & 0x07;
}
}
@@ -604,7 +640,7 @@ void DSM_init()
else if(sub_protocol != DSMR)
{
uint8_t tmpch[10];
CYRF_FindBestChannels(tmpch, 10, 5, 3, 75);
CYRF_FindBestChannels(tmpch, 10, 5, 3, 75, FIND_CHANNEL_ANY);
//
uint8_t idx = random(0xfefefefe) % 10;
hopping_frequency[0] = tmpch[idx];
@@ -627,10 +663,10 @@ void DSM_init()
{
DSM_initialize_bind_phase();
phase = DSM_BIND_WRITE;
bind_counter=DSM_BIND_COUNT;
#if DEBUG_BIND
debugln("Bind Started: write count=%d",bind_counter);
#endif
bind_counter=DSM_BIND_COUNT;
#if DEBUG_BIND
debugln("Bind Started: write count=%d",bind_counter);
#endif
}
else
phase = DSM_CHANSEL;

View File

@@ -365,7 +365,7 @@ static void __attribute__((unused)) DEVO_cyrf_init()
static void __attribute__((unused)) DEVO_set_radio_channels()
{
CYRF_FindBestChannels(hopping_frequency, 3, 4, 4, 80);
CYRF_FindBestChannels(hopping_frequency, 3, 4, 4, 80, FIND_CHANNEL_ANY);
hopping_frequency[3] = hopping_frequency[0];
hopping_frequency[4] = hopping_frequency[1];
}

View File

@@ -0,0 +1,166 @@
/*
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(EAZYRC_NRF24L01_INO)
#include "iface_xn297.h"
//#define FORCE_EAZYRC_ORIGINAL_ID
#define EAZYRC_PAYLOAD_SIZE 10
#define EAZYRC_RF_NUM_CHANNELS 4
#define EAZYRC_BIND_CHANNEL 18
#define EAZYRC_PACKET_PERIOD 5000
enum {
EAZYRC_BINDTX=0,
EAZYRC_BINDRX,
EAZYRC_DATA,
};
static void __attribute__((unused)) EAZYRC_send_packet()
{
//Bind:
// TX: C=18 S=Y A= AA BB CC DD EE P(10)= 1A A0 01 00 00 00 1E 00 78 51
// packet[0..2]=tx_addr, packet[6]=first rf channel, packet[8]=unk, packet[9]=sum(packet[0..8])
// RX: C=18 S=Y A= AA BB CC DD EE P(10)= 41 AD 01 1A A0 01 1E 00 87 4F
// packet[0..2]=rx_addr, packet[3..5]=tx_addr, packet[6]=first rf channel, packet[8]=unk but swapped, packet[9]=sum(packet[0..8])
//Normal: C=30 S=Y A= 1A A0 41 AD 02 P(10)= 7F 7F 1F 19 00 00 1E 00 AB FF
// packet[0]=THR, packet[1]=ST, packet[2]=unk, packet[3]=unk, packet[6]=first rf channel, packet[8]=unk, packet[9]=sum(packet[0..8])
//Bound : C=18 S=Y A= AA BB CC DD EE P(10)= 1A A0 01 41 AD 01 1E 00 79 41
// packet[0..2]=tx_addr, packet[3..5]=rx_addr, packet[6]=first rf channel, packet[8]=unk, packet[9]=sum(packet[0..8])
// sent every 12 packets in normal mode, but is it really needed if the car loose power then you need to rebind...
//Packet period around 5ms with a large jitter
memset(&packet[3], 0x00, 7);
if(IS_BIND_IN_PROGRESS)
{
memcpy(&packet,rx_tx_addr,3);
packet[6] = hopping_frequency[0];
packet[8] = 0x78; //??? packet type?
}
else
{
XN297_Hopping(hopping_frequency_no);
hopping_frequency_no++;
hopping_frequency_no &= 3;
packet[0] = convert_channel_8b(THROTTLE);
packet[1] = convert_channel_8b(AILERON);
packet[2] = 0x1F; //??? additional channel?
packet[3] = 0x19; //??? additional channel?
packet[6] = hopping_frequency[0];
packet[8] = 0xAB; //??? packet type?
}
for(uint8_t i=0;i<EAZYRC_PAYLOAD_SIZE-1;i++)
packet[9] += packet[i];
// Send
XN297_SetPower();
XN297_SetTxRxMode(TX_EN);
XN297_WritePayload(packet, EAZYRC_PAYLOAD_SIZE);
#ifdef DEBUG_SERIAL
for(uint8_t i=0; i < len; i++)
debug("%02X ", packet[i]);
debugln();
#endif
}
static void __attribute__((unused)) EAZYRC_initialize_txid()
{
rx_tx_addr[1] = rx_tx_addr[3];
hopping_frequency[0] = (rx_tx_addr[3]%20) + 0x1E; // Wild guess... First channel between 30 and 49so a full range of 30 to 79
#ifdef FORCE_EAZYRC_ORIGINAL_ID
rx_tx_addr[0] = 0x1A;
rx_tx_addr[1] = 0xA0;
rx_tx_addr[2] = 0x01;
hopping_frequency[0] = 0x1E;
#endif
rx_tx_addr[2] = 0x01; // Not sure if this is needed...
for(uint8_t i=1; i<EAZYRC_RF_NUM_CHANNELS; i++)
hopping_frequency[i] = hopping_frequency[0] + 10*i;
}
static void __attribute__((unused)) EAZYRC_RF_init()
{
XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M);
XN297_SetTXAddr((uint8_t*)"\xAA\xBB\xCC\xDD\xEE", 5);
XN297_SetRXAddr((uint8_t*)"\xAA\xBB\xCC\xDD\xEE", EAZYRC_PAYLOAD_SIZE);
XN297_RFChannel(EAZYRC_BIND_CHANNEL);
}
uint16_t EAZYRC_callback()
{
uint8_t rf,n;
uint16_t addr;
switch(phase)
{
case EAZYRC_BINDTX:
if(XN297_IsRX())
{
//Example: TX: C=18 S=Y A= AA BB CC DD EE P(10)= 1A A0 01 00 00 00 1E 00 78 51
// packet[0..2]=tx_addr, packet[6]=first rf channel, packet[8]=unk, packet[9]=sum(packet[0..8])
// RX: C=18 S=Y A= AA BB CC DD EE P(10)= 41 AD 01 1A A0 01 1E 00 87 4F
// packet[0..2]=rx_addr, packet[3..5]=tx_addr, packet[6]=first rf channel, packet[8]=unk but swapped, packet[9]=sum(packet[0..8])
XN297_ReadPayload(packet_in, EAZYRC_PAYLOAD_SIZE);
#ifdef DEBUG_SERIAL
for(uint8_t i=0; i < EAZYRC_PAYLOAD_SIZE; i++)
debug("%02X ", packet_in[i]);
debugln();
#endif
//could check the validity of the packet by looking at the sum...
if(memcmp(&packet_in[3],&rx_tx_addr,3)==0)
{//TX ID match, TX addr to use: 1A A0 41 AD 02
rx_tx_addr[4] = rx_tx_addr[2] + packet_in[2]; //wild guess
rx_tx_addr[2] = packet_in[0];
rx_tx_addr[3] = packet_in[1];
BIND_DONE;
XN297_SetTxRxMode(TXRX_OFF);
XN297_SetTXAddr(rx_tx_addr, 5);
phase = EAZYRC_DATA;
return 5000;
}
}
XN297_SetTxRxMode(TXRX_OFF);
EAZYRC_send_packet();
phase++;
return 1000;
case EAZYRC_BINDRX:
//Wait for the packet transmission to finish
while(XN297_IsPacketSent()==false);
//Switch to RX
XN297_SetTxRxMode(TXRX_OFF);
XN297_SetTxRxMode(RX_EN);
phase = EAZYRC_BINDTX;
return 10000;
case EAZYRC_DATA:
#ifdef MULTI_SYNC
telemetry_set_input_sync(EAZYRC_PACKET_PERIOD);
#endif
EAZYRC_send_packet();
break;
}
return EAZYRC_PACKET_PERIOD;
}
void EAZYRC_init()
{
BIND_IN_PROGRESS;
EAZYRC_initialize_txid();
EAZYRC_RF_init();
phase = EAZYRC_BINDTX;
packet_count = 0;
hopping_frequency_no = 0;
}
#endif

View File

@@ -33,7 +33,7 @@ Multiprotocol is distributed in the hope that it will be useful,
#define FX620_PAYLOAD_SIZE 7
#define FX620_CH_OFFSET 1
#define FX9630_PACKET_PERIOD 8124
#define FX9630_PACKET_PERIOD 8124 //8156 on QIDI-560
#define FX9630_BIND_PACKET_PERIOD 8124
#define FX9630_BIND_CHANNEL 51
#define FX9630_PAYLOAD_SIZE 8
@@ -51,14 +51,19 @@ static void __attribute__((unused)) FX_send_packet()
if(IS_BIND_DONE)
{
XN297_Hopping(hopping_frequency_no++);
if(sub_protocol == FX9630)
{
if(sub_protocol >= FX9630)
{ // FX9630 & FX_Q560
XN297_SetTXAddr(rx_tx_addr, 4);
if (hopping_frequency_no >= FX9630_NUM_CHANNELS)
{
hopping_frequency_no = 0;
trim_ch++;
if(trim_ch > 3) trim_ch = 0;
if(sub_protocol == FX9630)
{
trim_ch++;
if(trim_ch > 3) trim_ch = 0;
}
else // FX_Q560
trim_ch = 0;
}
}
else // FX816 and FX620
@@ -71,8 +76,8 @@ static void __attribute__((unused)) FX_send_packet()
//Channels
uint8_t val;
if (sub_protocol == FX9630)
{
if (sub_protocol >= FX9630)
{ // FX9630 & FX_Q560
packet[0] = convert_channel_8b(THROTTLE);
packet[1] = convert_channel_8b(AILERON);
packet[2] = 0xFF - convert_channel_8b(ELEVATOR);
@@ -83,7 +88,9 @@ static void __attribute__((unused)) FX_send_packet()
| GET_FLAG(CH5_SW, 0x01) // DR toggle swich: 0 small throw, 1 large throw
// FX9630 =>0:6G small throw, 1:6G large throw, 2:3D
// QIDI-550=>0:3D, 1:6G, 2:Torque
| ((Channel_data[CH6] < CHANNEL_MIN_COMMAND ? 0x00 : (Channel_data[CH6] > CHANNEL_MAX_COMMAND ? 0x02 : 0x01)) << 1);
| (Channel_data[CH6] < CHANNEL_MIN_COMMAND ? 0x00 : (Channel_data[CH6] > CHANNEL_MAX_COMMAND ? 0x04 : 0x02));
if(sub_protocol == FX_Q560)
packet[5] |= GET_FLAG(CH7_SW, 0x10);
}
else // FX816 and FX620
{
@@ -123,7 +130,7 @@ static void __attribute__((unused)) FX_send_packet()
packet[5] = 0xAB; // Is it based on ID??
}
}
else // FX9630
else // FX9630 & FX_Q560
{
if(IS_BIND_IN_PROGRESS)
{
@@ -136,12 +143,12 @@ static void __attribute__((unused)) FX_send_packet()
//Check
uint8_t last_packet_idx = packet_length-1;
if (sub_protocol == FX9630 && IS_BIND_IN_PROGRESS)
if (sub_protocol >= FX9630 && IS_BIND_IN_PROGRESS)
last_packet_idx--;
val=0;
for(uint8_t i=0;i<last_packet_idx;i++)
val+=packet[i];
if (sub_protocol == FX9630)
if (sub_protocol >= FX9630)
val = val ^ 0xFF;
packet[last_packet_idx]=val;
@@ -175,7 +182,7 @@ static void __attribute__((unused)) FX_RF_init()
packet_period = FX620_BIND_PACKET_PERIOD;
packet_length = FX620_PAYLOAD_SIZE;
}
else // FX9630
else // FX9630 & FX_Q560
{
XN297_SetTXAddr((uint8_t *)"\x56\x78\x90\x12", 4);
XN297_RFChannel(FX9630_BIND_CHANNEL);
@@ -207,7 +214,7 @@ static void __attribute__((unused)) FX_initialize_txid()
for(uint8_t i=1;i<FX_NUM_CHANNELS;i++)
hopping_frequency[i] = i*10 + hopping_frequency[0];
}
else // FX9630
else // FX9630 & FX_Q560
{
#ifdef FORCE_FX9630_ID
memcpy(rx_tx_addr,(uint8_t*)"\xCE\x31\x9B\x73", 4);
@@ -220,6 +227,10 @@ static void __attribute__((unused)) FX_initialize_txid()
#ifdef FORCE_QIDI_ID
memcpy(rx_tx_addr,(uint8_t*)"\x23\xDC\x76\xA2", 4);
memcpy(hopping_frequency,"\x08\x25\x33", FX9630_NUM_CHANNELS); //Original dump=>08=0x08,37=0x25,51=0x33
//QIDI-560 #1
//memcpy(rx_tx_addr,(uint8_t*)"\x38\xC7\x6D\x8D", 4);
//memcpy(hopping_frequency,"\x0D\x20\x3A", FX9630_NUM_CHANNELS);
#endif
//??? Need to find out how the first RF channel is calculated ???
}

View File

@@ -66,8 +66,10 @@ static void __attribute__((unused)) HISKY_RF_init()
NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, rx_tx_addr, 5);
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, rx_tx_addr, 5);
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, 10); // payload size = 10
#ifndef MULTI_AIR
if(sub_protocol==HK310)
NRF24L01_SetBitrate(NRF24L01_BR_250K); // 250Kbps
#endif
}
// HiSky channel sequence: AILE ELEV THRO RUDD GEAR PITCH, channel data value is from 0 to 1000
@@ -92,6 +94,13 @@ static void __attribute__((unused)) HISKY_build_ch_data()
uint16_t HISKY_callback()
{
phase++;
#ifdef MULTI_AIR
if(sub_protocol==HK310)
{
SUB_PROTO_INVALID;
return 10000;
}
#else
if(sub_protocol==HK310)
switch(phase)
{
@@ -132,6 +141,7 @@ uint16_t HISKY_callback()
phase=8;
break;
}
#endif
switch(phase)
{
case 1:
@@ -195,6 +205,7 @@ uint16_t HISKY_callback()
static void __attribute__((unused)) HISKY_initialize_tx_id()
{
//Generate frequency hopping table
#ifndef MULTI_AIR
if(sub_protocol==HK310)
{
// for HiSky surface protocol, the transmitter always generates hop channels in sequential order.
@@ -204,10 +215,11 @@ static void __attribute__((unused)) HISKY_initialize_tx_id()
hopping_frequency[i]=hopping_frequency_no++; // Sequential order hop channels...
}
else
calc_fh_channels(HISKY_FREQUENCE_NUM);
#endif
// HiSky air protocol uses TX id as an address for nRF24L01, and uses frequency hopping sequence
// which does not depend on this id and is passed explicitly in binding sequence. So we are free
// to generate this sequence as we wish. It should be in the range [02..77]
calc_fh_channels(HISKY_FREQUENCE_NUM);
}
void HISKY_init()

View File

@@ -35,7 +35,6 @@ enum PktState {
J6PRO_CHAN_4,
};
const uint8_t PROGMEM j6pro_bind_sop_code[] = {0x62, 0xdf, 0xc1, 0x49, 0xdf, 0xb1, 0xc0, 0x49};
const uint8_t j6pro_data_code[] = {0x02, 0xf9, 0x93, 0x97, 0x02, 0xfa, 0x5c, 0xe3, 0x01, 0x2b, 0xf1, 0xdb, 0x01, 0x32, 0xbe, 0x6f}; // unneeded since this is the default table after a reset
static void __attribute__((unused)) j6pro_build_bind_packet()
@@ -99,7 +98,7 @@ static void __attribute__((unused)) cyrf_bindinit()
/* Use when binding */
CYRF_SetPower(0x28); //Deviation using max power, replaced by bind power...
//CYRF_ConfigRFChannel(0x52);
CYRF_PROGMEM_ConfigSOPCode(j6pro_bind_sop_code);
CYRF_PROGMEM_ConfigSOPCode(DEVO_j6pro_sopcodes[19]);
CYRF_ConfigCRCSeed(0x0000);
//CYRF_WriteRegister(CYRF_06_RX_CFG, 0x4a);
//CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x80);
@@ -124,7 +123,7 @@ static void __attribute__((unused)) j6pro_set_radio_channels()
{
//FIXME: Query free channels
//lowest channel is 0x08, upper channel is 0x4d?
CYRF_FindBestChannels(hopping_frequency, 3, 5, 8, 77);
CYRF_FindBestChannels(hopping_frequency, 3, 5, 8, 77, FIND_CHANNEL_ANY);
hopping_frequency[3] = hopping_frequency[0];
}

View File

@@ -63,7 +63,7 @@ enum {
KN_FLAG_DR = 0x01, // Dual Rate: 1 - full range
KN_FLAG_TH = 0x02, // Throttle Hold: 1 - hold
KN_FLAG_IDLEUP = 0x04, // Idle up: 1 - 3D
KN_FLAG_RES1 = 0x08,
KN_FLAG_RES1 = 0x08, // HoverDebugging
KN_FLAG_RES2 = 0x10,
KN_FLAG_RES3 = 0x20,
KN_FLAG_GYRO3 = 0x40, // 0 - 6G mode, 1 - 3G mode
@@ -141,19 +141,13 @@ static void __attribute__((unused)) kn_update_packet_control_data()
packet[8] = convert_channel_16b_limit(CH9,0,200); // 0x64; // T
packet[9] = convert_channel_16b_limit(CH10,0,200); // 0x64; // A
packet[10] = convert_channel_16b_limit(CH11,0,200); // 0x64; // E
packet[11] = 0x64; // R
packet[11] = convert_channel_16b_limit(CH12,0,200); // 0x64; // R
flags=0;
if (CH5_SW)
flags = KN_FLAG_DR;
if (CH6_SW)
flags |= KN_FLAG_TH;
if (CH7_SW)
flags |= KN_FLAG_IDLEUP;
if (CH8_SW)
flags |= KN_FLAG_GYRO3;
packet[12] = flags;
packet[12] = GET_FLAG(CH5_SW, KN_FLAG_DR)
|GET_FLAG(CH6_SW, KN_FLAG_TH)
|GET_FLAG(CH7_SW, KN_FLAG_IDLEUP)
|GET_FLAG(CH8_SW, KN_FLAG_GYRO3)
|GET_FLAG(CH13_SW, KN_FLAG_RES1); //Hover debugging
packet[13] = 0x00;
if(sub_protocol==WLTOYS)

View File

@@ -0,0 +1,121 @@
/*
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(KYOSHO3_CYRF6936_INO)
#include "iface_cyrf6936.h"
//#define KYOSHO3_FORCE_ID
//#define KYOSHO3_DEBUG
#define KYOSHO3_BIND_PACKET_SIZE 4
#define KYOSHO3_PACKET_SIZE 9
const uint8_t PROGMEM KYOSHO3_init_vals[][2] = {
//Init from dump
{CYRF_0B_PWR_CTRL, 0x00}, // PMU
{CYRF_32_AUTO_CAL_TIME, 0x3C}, // Default init value
{CYRF_35_AUTOCAL_OFFSET, 0x14}, // Default init value
{CYRF_03_TX_CFG, 0x28 | CYRF_BIND_POWER}, // 8DR Mode, 64 chip codes
{CYRF_10_FRAMING_CFG, 0xA4}, // SOP and LEN enable
{CYRF_1F_TX_OVERRIDE, 0x05}, // Disable CRC, Data invert
{CYRF_1E_RX_OVERRIDE, 0x04}, // CRC check disabled
//{CYRF_11_DATA32_THOLD, 0x04}, // ???Using 64 chip...
{CYRF_12_DATA64_THOLD, 0x0E}, // Default
{CYRF_06_RX_CFG, 0x52}, // AGC disabled, LNA enabled, override enabled
};
static uint16_t __attribute__((unused)) KYOSHO3_send_packet()
{
CYRF_SetPower(0x28);
if(IS_BIND_IN_PROGRESS)
{
if(--bind_counter==0)
BIND_DONE;
packet[0] = 0xAA;
//ID
memcpy(&packet[1],&rx_tx_addr[1],3);
CYRF_WriteDataPacketLen(packet, KYOSHO3_BIND_PACKET_SIZE);
#ifdef KYOSHO3_DEBUG
debug("P:");
for(uint8_t i=0;i<KYOSHO3_BIND_PACKET_SIZE;i++)
debug(" %02X",packet[i]);
debugln("");
#endif
return 2434;
}
else
{
//ID
memcpy(packet,&rx_tx_addr[1],3);
//Channels
for(uint8_t i=0;i<4;i++)
{
packet[3] >>= 2;
packet[3] |= Channel_data[i]<<6;
packet[4+i] = Channel_data[i]>>3;
}
//Checksum
packet[8] = packet[3];
for(uint8_t i=4;i<8;i++)
packet[8] += packet[i];
//Timing
phase ^= 0x01;
CYRF_WriteDataPacketLen(packet, KYOSHO3_PACKET_SIZE);
#ifdef KYOSHO3_DEBUG
debug("P:");
for(uint8_t i=0;i<KYOSHO3_PACKET_SIZE;i++)
debug(" %02X",packet[i]);
debugln("");
#endif
if(phase)
return 9047;
}
return 6957;
}
uint16_t KYOSHO3_callback()
{
return KYOSHO3_send_packet();
}
void KYOSHO3_init()
{
//Config CYRF registers
for(uint8_t i = 0; i < sizeof(KYOSHO3_init_vals) / 2; i++)
CYRF_WriteRegister(pgm_read_byte_near(&KYOSHO3_init_vals[i][0]), pgm_read_byte_near(&KYOSHO3_init_vals[i][1]));
CYRF_WritePreamble(0x333304);
//Find a free even channel
CYRF_FindBestChannels(hopping_frequency,1,1,0x04,0x50, FIND_CHANNEL_EVEN);
#ifdef KYOSHO3_FORCE_ID // data taken from TX dump
rx_tx_addr[1] = 0x01;
rx_tx_addr[2] = 0xAB;
rx_tx_addr[3] = 0x31;
hopping_frequency[0] = 0x04;
#endif
#ifdef KYOSHO3_DEBUG
debugln("ID: %02X %02X %02X",rx_tx_addr[1],rx_tx_addr[2],rx_tx_addr[3]);
debugln("RF CH: %02X",hopping_frequency[0]);
#endif
CYRF_ConfigRFChannel(hopping_frequency[0]);
bind_counter = 8217;
phase = 0;
}
#endif

View File

@@ -19,10 +19,12 @@
//#define KYOSHO_FORCE_ID_FHSS
//#define KYOSHO_FORCE_ID_HYPE
//#define KYOSHO_FORCE_ID_SYNCRO
//Kyosho constants & variables
#define KYOSHO_BIND_COUNT 2500
#ifndef MULTI_AIR
static void __attribute__((unused)) KYOSHO_send_packet()
{
//ID
@@ -32,7 +34,7 @@ static void __attribute__((unused)) KYOSHO_send_packet()
packet[4] = rx_tx_addr[3];
//unknown may be RX ID on some other remotes
memset(packet+5,0xFF,4);
if(IS_BIND_IN_PROGRESS)
{
packet[ 0] = 0xBC; // bind indicator
@@ -42,8 +44,9 @@ static void __attribute__((unused)) KYOSHO_send_packet()
//RF table
for(uint8_t i=0; i<16;i++)
packet[i+11]=hopping_frequency[i+(packet[9]<<4)];
//unknwon
packet[27] = 0x05;
//TX type
packet[27] = (bind_counter & 0x40) ? 0x05:0x07; // FHSS is 5 and Syncro is 7
//Unknown
packet[28] = 0x00;
memset(packet+29,0xFF,8);
//frequency hop during bind
@@ -55,13 +58,23 @@ static void __attribute__((unused)) KYOSHO_send_packet()
else
{
packet[ 0] = 0x58; // normal packet
//14 channels: steering, throttle, ...
for(uint8_t i = 0; i < 14; i++)
//FHSS 14 channels: steering, throttle, ...
//Syncro 6 channels: steering, throttle, ...
for(uint8_t i = 0; i < 14; i++) //needed? i < (sub_protocol==KYOSHO_FHSS?14:6); i++)
{
uint16_t temp=convert_channel_ppm(i);
packet[9 + i*2]=temp&0xFF; // low byte of servo timing(1000-2000us)
packet[10 + i*2]=(temp>>8)&0xFF; // high byte of servo timing(1000-2000us)
uint16_t temp = convert_channel_ppm(i);
packet[ 9 + i*2] = temp&0xFF; // low byte of servo timing(1000-2000us)
packet[10 + i*2] = (temp>>8)&0xFF; // high byte of servo timing(1000-2000us)
}
// if(sub_protocol==KYOSHO_SYNCRO) // needed?
// {
// memcpy(&packet[21],&hopping_frequency[11],6);
// packet[27] = 0x07;
// packet[28] = 0x00;
// memset(packet+29,0xFF,8);
// packet[34] = 0x0F;
// packet[36] = 0x0F;
// }
rf_ch_num=hopping_frequency[hopping_frequency_no];
hopping_frequency_no++;
packet[34] |= (hopping_frequency_no&0x0F)<<4;
@@ -76,6 +89,7 @@ static void __attribute__((unused)) KYOSHO_send_packet()
#endif
A7105_WriteData(37, rf_ch_num);
}
#endif //MULTI_AIR
static void __attribute__((unused)) KYOSHO_hype_send_packet()
{
@@ -150,10 +164,14 @@ uint16_t KYOSHO_callback()
telemetry_set_input_sync(packet_period);
#endif
}
if(sub_protocol==KYOSHO_FHSS)
KYOSHO_send_packet();
else//HYPE
if(sub_protocol==KYOSHO_HYPE)
KYOSHO_hype_send_packet();
else //FHSS && SYNCRO
#ifndef MULTI_AIR
KYOSHO_send_packet();
#else
SUB_PROTO_INVALID;
#endif
return packet_period;
}
@@ -162,7 +180,7 @@ void KYOSHO_init()
A7105_Init();
// compute channels from ID
calc_fh_channels(sub_protocol==KYOSHO_FHSS?32:15);
calc_fh_channels(sub_protocol==KYOSHO_HYPE?15:32);
hopping_frequency_no=0;
#ifdef KYOSHO_FORCE_ID_FHSS
@@ -172,6 +190,13 @@ void KYOSHO_init()
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
#ifdef KYOSHO_FORCE_ID_SYNCRO
if(sub_protocol==KYOSHO_FHSS)
{
memcpy(rx_tx_addr,"\x00\xC2\x24\x00",4);
memcpy(hopping_frequency,"\x73\x12\x7D\x88\x63\x4A\x8D\x60\x57\x16\x5D\x8B\x25\x53\x6E\x3C\x41\x70\x20\x83\x2A\x19\x94\x2F\x91\x4C\x47\x36\x78\x10\x5A\x31",32);
}
#endif
if(sub_protocol==KYOSHO_HYPE)
{
MProtocol_id &= 0x00FF00FF;

View File

@@ -169,8 +169,7 @@ void LOSI_init()
{
LOSI_cyrf_init();
CYRF_FindBestChannels(hopping_frequency, 1, 0, 0x07, 0x4F); // 0x07 and 0x4F are unknown limits, this routine resets the CRC Seed to 0
hopping_frequency[0] |= 1; // Only odd channels are used, integrated in CYRF code...
CYRF_FindBestChannels(hopping_frequency, 1, 0, 0x07, 0x4F, FIND_CHANNEL_ODD); // 0x07 and 0x4F are unknown limits, this routine resets the CRC Seed to 0
crc8 = 0;
crc8 = (uint16_t)LOSI_check(((rx_tx_addr[2]&0x0F) << 8) + rx_tx_addr[3]) >> 12;

View File

@@ -3,12 +3,12 @@
3,FrskyD,D8,Cloned
4,Hisky,Hisky,HK310
5,V2x2,V2x2,JXD506,MR101
6,DSM,DSM2_1F,DSM2_2F,DSMX_1F,DSMX_2F,AUTO,DSMR_1F
6,DSM,DSM2_1F,DSM2_2F,DSMX_1F,DSMX_2F,AUTO,DSMR_1F,DSMR,DSM2_SFC
7,Devo,8CH,10CH,12CH,6CH,7CH
8,YD717,YD717,SKYWLKR,SYMAX4,XINXUN,NIHUI
9,KN,WLTOYS,FEILUN
10,SymaX,SYMAX,SYMAX5C
11,SLT,SLT_V1,SLT_V2,Q100,Q200,MR100
11,SLT,SLT_V1,SLT_V2,Q100,Q200,MR100,V1_4CH
12,CX10,GREEN,BLUE,DM007,---,J3015_1,J3015_2,MK33041
13,CG023,CG023,YD829
14,Bayang,Bayang,H8S3D,X16_AH,IRDRONE,DHD_D4,QX100
@@ -40,7 +40,7 @@
40,WFLY,WFR0x
41,BUGS
42,BUGSMINI,BUGSMINI,BUGS3H
43,Traxxas,RX6519
43,Traxxas,TQ
44,NCC1701
45,E01X,E012,E015
46,V911S,V911S,E119
@@ -55,11 +55,11 @@
55,Frsky_RX,Multi,CloneTX,EraseTX,CPPM
56,AFHDS2A_RX,Multi,CPPM
57,HoTT,Sync,No_Sync
58,FX,816,620,9630
58,FX,816,620,9630,Q560
59,Bayang_RX,Multi,CPPM
60,Pelikan,Pro,Lite,SCX24
61,Tiger
62,XK,X450,X420
61,EazyRC
62,XK,X450,X420,Cars
63,XN_DUMP,250K,1M,2M,AUTO
64,FrskyX2,CH_16,CH_8,EU_16,EU_8,Cloned
65,FrSkyR9,915MHz,868MHz,915_8ch,868_8ch,FCC,--,FCC_8ch,--_8ch
@@ -71,9 +71,9 @@
71,JJRC345,JJRC345,SkyTmblr
72,Q90C
73,Kyosho,FHSS,Hype
74,RadioLink,Surface,Air,DumboRC
74,RadioLink,Surface,Air,DumboRC,RC4G
75,---
76,Realacc,R11
76,Realacc
77,OMP
78,M-Link
79,WFLY,RF20x
@@ -93,3 +93,5 @@
94,Scorpio
95,BlueFly
96,BumbleB
97,SGF22
98,Kyosho3

View File

@@ -78,10 +78,9 @@ const char STR_SCANNER[] ="Scanner";
const char STR_FRSKY_RX[] ="FrSkyRX";
const char STR_AFHDS2A_RX[] ="FS2A_RX";
const char STR_HOTT[] ="HoTT";
const char STR_FX[] ="FX";
const char STR_FX[] ="FX";
const char STR_BAYANG_RX[] ="BayanRX";
const char STR_PELIKAN[] ="Pelikan";
const char STR_TIGER[] ="Tiger";
const char STR_XK[] ="XK";
const char STR_XN297DUMP[] ="XN297DP";
const char STR_FRSKYR9[] ="FrSkyR9";
@@ -108,6 +107,9 @@ const char STR_XERALL[] ="Xerall";
const char STR_SCORPIO[] ="Scorpio";
const char STR_BLUEFLY[] ="BlueFly";
const char STR_BUMBLEB[] ="BumbleB";
const char STR_SGF22[] ="SGF22";
const char STR_EAZYRC[] ="EazyRC";
const char STR_KYOSHO3[] ="Kyosho3";
const char STR_SUBTYPE_FLYSKY[] = "\x04""Std\0""V9x9""V6x6""V912""CX20";
const char STR_SUBTYPE_HUBSAN[] = "\x04""H107""H301""H501";
@@ -120,15 +122,15 @@ const char STR_SUBTYPE_FRSKYD[] = "\x06""D8\0 ""Cloned";
const char STR_SUBTYPE_HISKY[] = "\x05""Std\0 ""HK310";
const char STR_SUBTYPE_V2X2[] = "\x06""Std\0 ""JXD506""MR101\0";
#ifndef MULTI_EU
const char STR_SUBTYPE_DSM[] = "\x04""2 1F""2 2F""X 1F""X 2F""Auto""R 1F";
const char STR_SUBTYPE_DSM[] = "\x04""2 1F""2 2F""X 1F""X 2F""Auto""R 1F""2SFC";
#else
const char STR_SUBTYPE_DSM[] = "\x04""--->""--->""X 1F""X 2F""Auto""R 1F";
const char STR_SUBTYPE_DSM[] = "\x04""--->""--->""X 1F""X 2F""Auto""R 1F""----";
#endif
const char STR_SUBTYPE_DEVO[] = "\x04""8ch\0""10ch""12ch""6ch\0""7ch\0";
const char STR_SUBTYPE_YD717[] = "\x07""Std\0 ""SkyWlkr""Syma X4""XINXUN\0""NIHUI\0 ";
const char STR_SUBTYPE_KN[] = "\x06""WLtoys""FeiLun";
const char STR_SUBTYPE_SYMAX[] = "\x03""Std""X5C";
const char STR_SUBTYPE_SLT[] = "\x06""V1_6ch""V2_8ch""Q100\0 ""Q200\0 ""MR100\0";
const char STR_SUBTYPE_SLT[] = "\x06""V1_6ch""V2_8ch""Q100\0 ""Q200\0 ""MR100\0""V1_4ch";
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 ";
@@ -146,7 +148,7 @@ const char STR_SUBTYPE_H83D[] = "\x07""Std\0 ""H20H\0 ""H20Mini""H30Min
const char STR_SUBTYPE_CORONA[] = "\x05""V1\0 ""V2\0 ""FD V3";
const char STR_SUBTYPE_HITEC[] = "\x07""Optima\0""Opt Hub""Minima\0";
const char STR_SUBTYPE_BUGS_MINI[] = "\x06""Std\0 ""Bugs3H";
const char STR_SUBTYPE_TRAXXAS[] = "\x04""6519";
const char STR_SUBTYPE_TRAXXAS[] = "\x03""TQ2""TQ1";
const char STR_SUBTYPE_E01X[] = "\x05""E012\0""E015\0";
const char STR_SUBTYPE_GD00X[] = "\x05""GD_V1""GD_V2";
const char STR_SUBTYPE_REDPINE[] = "\x04""Fast""Slow";
@@ -157,7 +159,7 @@ const char STR_SUBTYPE_XN297DUMP[] = "\x07""250Kbps""1Mbps\0 ""2Mbps\0 ""Auto\0
const char STR_SUBTYPE_ESKY150[] = "\x03""4ch""7ch";
const char STR_SUBTYPE_ESKY150V2[] = "\x05""150V2";
const char STR_SUBTYPE_V911S[] = "\x05""V911S""E119\0";
const char STR_SUBTYPE_XK[] = "\x04""X450""X420";
const char STR_SUBTYPE_XK[] = "\x04""X450""X420""Cars";
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";
@@ -167,16 +169,16 @@ const char STR_SUBTYPE_WFLY2[] = "\x05""RF20x";
const char STR_SUBTYPE_HOTT[] = "\x07""Sync\0 ""No_Sync";
const char STR_SUBTYPE_PELIKAN[] = "\x05""Pro\0 ""Lite\0""SCX24";
const char STR_SUBTYPE_V761[] = "\x05""3ch\0 ""4ch\0 ""TOPRC";
const char STR_SUBTYPE_RLINK[] = "\x07""Surface""Air\0 ""DumboRC";
const char STR_SUBTYPE_REALACC[] = "\x03""R11";
const char STR_SUBTYPE_RLINK[] = "\x07""Surface""Air\0 ""DumboRC""RC4G\0 ";
const char STR_SUBTYPE_KYOSHO[] = "\x04""FHSS""Hype";
const char STR_SUBTYPE_KYOSHO2[] = "\x05""KT-17";
const char STR_SUBTYPE_KYOSHO3[] = "\x03""ASF";
const char STR_SUBTYPE_FUTABA[] = "\x05""SFHSS";
const char STR_SUBTYPE_JJRC345[] = "\x08""JJRC345\0""SkyTmblr";
const char STR_SUBTYPE_MOULKG[] = "\x06""Analog""Digit\0";
const char STR_SUBTYPE_MOULDKG[] = "\x06""Analog""Digit\0";
const char STR_SUBTYPE_KF606[] = "\x06""KF606\0""MIG320""ZCZ50\0";
const char STR_SUBTYPE_E129[] = "\x04""E129""C186";
const char STR_SUBTYPE_FX[] = "\x04""816\0""620\0""9630";
const char STR_SUBTYPE_FX[] = "\x04""816\0""620\0""9630""Q560";
#define NO_SUBTYPE nullptr
#ifdef SEND_CPPM
@@ -258,7 +260,7 @@ const mm_protocol_definition multi_protocols[] = {
{PROTO_DM002, STR_DM002, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_NRF, DM002_init, DM002_callback },
#endif
#if defined(DSM_CYRF6936_INO)
{PROTO_DSM, STR_DSM, STR_SUBTYPE_DSM, 6, OPTION_MAXTHR, 0, 1, SW_CYRF, DSM_init, DSM_callback },
{PROTO_DSM, STR_DSM, STR_SUBTYPE_DSM, 7, OPTION_MAXTHR, 0, 1, SW_CYRF, DSM_init, DSM_callback },
#endif
#if defined(DSM_RX_CYRF6936_INO)
{PROTO_DSM_RX, STR_DSM_RX, STR_SUB_DSM_RX, DSMCPPM, OPTION_NONE, 0, 1, SW_CYRF, DSM_RX_init, DSM_RX_callback },
@@ -278,6 +280,9 @@ const mm_protocol_definition multi_protocols[] = {
#if defined(E129_CYRF6936_INO)
{PROTO_E129, STR_E129, STR_SUBTYPE_E129, 2, OPTION_NONE, 0, 0, SW_CYRF, E129_init, E129_callback },
#endif
#if defined(EAZYRC_NRF24L01_INO)
{PROTO_EAZYRC, STR_EAZYRC, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_NRF, EAZYRC_init, EAZYRC_callback },
#endif
#if defined(ESKY_NRF24L01_INO)
{PROTO_ESKY, STR_ESKY, STR_SUBTYPE_ESKY, 2, OPTION_NONE, 0, 1, SW_NRF, ESKY_init, ESKY_callback },
#endif
@@ -328,7 +333,7 @@ const mm_protocol_definition multi_protocols[] = {
{PROTO_FUTABA, STR_FUTABA, STR_SUBTYPE_FUTABA, 1, OPTION_RFTUNE, 1, 1, SW_CC2500, SFHSS_init, SFHSS_callback },
#endif
#if defined(FX_NRF24L01_INO)
{PROTO_FX, STR_FX, STR_SUBTYPE_FX, 3, OPTION_NONE, 0, 0, SW_NRF, FX_init, FX_callback },
{PROTO_FX, STR_FX, STR_SUBTYPE_FX, 4, OPTION_NONE, 0, 0, SW_NRF, FX_init, FX_callback },
#endif
#if defined(FY326_NRF24L01_INO)
{PROTO_FY326, STR_FY326, STR_SUBTYPE_FY326, 2, OPTION_NONE, 0, 0, SW_NRF, FY326_init, FY326_callback },
@@ -384,6 +389,9 @@ const mm_protocol_definition multi_protocols[] = {
#if defined(KYOSHO2_NRF24L01_INO)
{PROTO_KYOSHO2, STR_KYOSHO2, STR_SUBTYPE_KYOSHO2, 1, OPTION_NONE, 0, 0, SW_NRF, KYOSHO2_init, KYOSHO2_callback },
#endif
#if defined(KYOSHO3_CYRF6936_INO)
{PROTO_KYOSHO3, STR_KYOSHO3, STR_SUBTYPE_KYOSHO3, 1, OPTION_NONE, 0, 0, SW_CYRF, KYOSHO3_init, KYOSHO3_callback },
#endif
#if defined(LOLI_NRF24L01_INO)
{PROTO_LOLI, STR_LOLI, NO_SUBTYPE, 0, OPTION_NONE, 1, 0, SW_NRF, LOLI_init, LOLI_callback },
#endif
@@ -397,7 +405,7 @@ const mm_protocol_definition multi_protocols[] = {
{PROTO_MLINK, STR_MLINK, NO_SUBTYPE, 0, OPTION_NONE, 1, 0, SW_CYRF, MLINK_init, MLINK_callback },
#endif
#if defined(MOULDKG_NRF24L01_INO)
{PROTO_MOULDKG, STR_MOULDKG, STR_SUBTYPE_MOULKG, 2, OPTION_OPTION, 0, 0, SW_NRF, MOULDKG_init, MOULDKG_callback },
{PROTO_MOULDKG, STR_MOULDKG, STR_SUBTYPE_MOULDKG, 2, OPTION_OPTION, 0, 0, SW_NRF, MOULDKG_init, MOULDKG_callback },
#endif
#if defined(MT99XX_CCNRF_INO)
{PROTO_MT99XX, STR_MT99XX, STR_SUBTYPE_MT99, 8, OPTION_NONE, 0, 0, SW_NRF, MT99XX_init, MT99XX_callback },
@@ -430,10 +438,10 @@ const mm_protocol_definition multi_protocols[] = {
{PROTO_Q90C, STR_Q90C, NO_SUBTYPE, 0, OPTION_RFTUNE, 0, 0, SW_NRF, Q90C_init, Q90C_callback },
#endif
#if defined(RLINK_CC2500_INO)
{PROTO_RLINK, STR_RLINK, STR_SUBTYPE_RLINK, 3, OPTION_RFTUNE, 0, 0, SW_CC2500, RLINK_init, RLINK_callback },
{PROTO_RLINK, STR_RLINK, STR_SUBTYPE_RLINK, 4, OPTION_RFTUNE, 0, 0, SW_CC2500, RLINK_init, RLINK_callback },
#endif
#if defined(REALACC_NRF24L01_INO)
{PROTO_REALACC, STR_REALACC, STR_SUBTYPE_REALACC, 1, OPTION_NONE, 0, 0, SW_NRF, REALACC_init, REALACC_callback },
{PROTO_REALACC, STR_REALACC, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_NRF, REALACC_init, REALACC_callback },
#endif
#if defined(REDPINE_CC2500_INO)
{PROTO_REDPINE, STR_REDPINE, STR_SUBTYPE_REDPINE, 2, OPTION_RFTUNE, 0, 0, SW_CC2500, REDPINE_init, REDPINE_callback },
@@ -444,6 +452,9 @@ const mm_protocol_definition multi_protocols[] = {
#if defined(SCORPIO_CYRF6936_INO)
{PROTO_SCORPIO, STR_SCORPIO, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_CYRF, SCORPIO_init, SCORPIO_callback },
#endif
#if defined(SGF22_NRF24L01_INO)
{PROTO_SGF22, STR_SGF22, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_NRF, SGF22_init, SGF22_callback },
#endif
#if defined(SHENQI_NRF24L01_INO)
{PROTO_SHENQI, STR_SHENQI, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_NRF, SHENQI_init, SHENQI_callback },
#endif
@@ -451,16 +462,13 @@ const mm_protocol_definition multi_protocols[] = {
{PROTO_SKYARTEC, STR_SKYARTEC, NO_SUBTYPE, 0, OPTION_RFTUNE, 0, 1, SW_CC2500, SKYARTEC_init, SKYARTEC_callback },
#endif
#if defined(SLT_CCNRF_INO)
{PROTO_SLT, STR_SLT, STR_SUBTYPE_SLT, 5, OPTION_RFTUNE, 0, 1, SW_NRF, SLT_init, SLT_callback },
{PROTO_SLT, STR_SLT, STR_SUBTYPE_SLT, 6, OPTION_RFTUNE, 0, 1, SW_NRF, SLT_init, SLT_callback },
#endif
#if defined(SYMAX_NRF24L01_INO)
{PROTO_SYMAX, STR_SYMAX, STR_SUBTYPE_SYMAX, 2, OPTION_NONE, 0, 0, SW_NRF, SYMAX_init, SYMAX_callback },
#endif
#if defined(TIGER_NRF24L01_INO)
{PROTO_TIGER, STR_TIGER, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_NRF, TIGER_init, TIGER_callback },
#endif
#if defined(TRAXXAS_CYRF6936_INO)
{PROTO_TRAXXAS, STR_TRAXXAS, STR_SUBTYPE_TRAXXAS, 1, OPTION_NONE, 0, 0, SW_CYRF, TRAXXAS_init, TRAXXAS_callback },
{PROTO_TRAXXAS, STR_TRAXXAS, STR_SUBTYPE_TRAXXAS, 2, OPTION_NONE, 0, 0, SW_CYRF, TRAXXAS_init, TRAXXAS_callback },
#endif
#if defined(V2X2_NRF24L01_INO)
{PROTO_V2X2, STR_V2X2, STR_SUBTYPE_V2X2, 3, OPTION_NONE, 0, 0, SW_NRF, V2X2_init, V2X2_callback },
@@ -485,7 +493,7 @@ const mm_protocol_definition multi_protocols[] = {
{PROTO_XERALL, STR_XERALL, NO_SUBTYPE, 0, OPTION_NONE, 0, 0, SW_NRF, XERALL_init, XERALL_callback },
#endif
#if defined(XK_CCNRF_INO)
{PROTO_XK, STR_XK, STR_SUBTYPE_XK, 2, OPTION_RFTUNE, 0, 0, SW_NRF, XK_init, XK_callback },
{PROTO_XK, STR_XK, STR_SUBTYPE_XK, 3, OPTION_RFTUNE, 0, 0, SW_NRF, XK_init, XK_callback },
#endif
#if defined(XN297DUMP_NRF24L01_INO)
{PROTO_XN297DUMP, STR_XN297DUMP, STR_SUBTYPE_XN297DUMP, 6, OPTION_RFCHAN, 0, 0, SW_NRF, XN297Dump_init, XN297Dump_callback },

View File

@@ -18,8 +18,8 @@
//******************
#define VERSION_MAJOR 1
#define VERSION_MINOR 3
#define VERSION_REVISION 3
#define VERSION_PATCH_LEVEL 43
#define VERSION_REVISION 4
#define VERSION_PATCH_LEVEL 9
#define MODE_SERIAL 0
@@ -89,7 +89,7 @@ enum PROTOCOLS
PROTO_FX = 58, // =>NRF24L01
PROTO_BAYANG_RX = 59, // =>NRF24L01
PROTO_PELIKAN = 60, // =>A7105
PROTO_TIGER = 61, // =>NRF24L01
PROTO_EAZYRC = 61, // =>NRF24L01
PROTO_XK = 62, // =>NRF24L01
PROTO_XN297DUMP = 63, // =>NRF24L01
PROTO_FRSKYX2 = 64, // =>CC2500
@@ -124,6 +124,8 @@ enum PROTOCOLS
PROTO_SCORPIO = 94, // =>CYRF6936
PROTO_BLUEFLY = 95, // =>CC2500 & NRF24L01
PROTO_BUMBLEB = 96, // =>CC2500 & NRF24L01
PROTO_SGF22 = 97, // =>NRF24L01
PROTO_KYOSHO3 = 98, // =>CYRF6936
PROTO_NANORF = 126, // =>NRF24L01
@@ -172,6 +174,7 @@ enum DSM
DSMX_2F = 3,
DSM_AUTO = 4,
DSMR = 5,
DSM2_SFC = 6,
};
enum DSM_RX
{
@@ -199,11 +202,12 @@ enum SYMAX
};
enum SLT
{
SLT_V1 = 0,
SLT_V2 = 1,
Q100 = 2,
Q200 = 3,
MR100 = 4,
SLT_V1 = 0,
SLT_V2 = 1,
Q100 = 2,
Q200 = 3,
MR100 = 4,
SLT_V1_4 = 5,
};
enum CX10
{
@@ -359,7 +363,8 @@ enum REDPINE
};
enum TRAXXAS
{
RX6519 = 0,
TRAXXAS_TQ2 = 0,
TRAXXAS_TQ1 = 1,
};
enum ESKY150
{
@@ -375,6 +380,7 @@ enum XK
{
X450 = 0,
X420 = 1,
XK_CARS = 2,
};
enum XN297DUMP
{
@@ -450,6 +456,7 @@ enum RLINK
RLINK_SURFACE = 0,
RLINK_AIR = 1,
RLINK_DUMBORC = 2,
RLINK_RC4G = 3,
};
enum MOULDKG
{
@@ -472,6 +479,7 @@ enum FX
FX816 = 0,
FX620 = 1,
FX9630 = 2,
FX_Q560 = 3,
};
#define NONE 0
@@ -833,8 +841,8 @@ enum {
#define DSM_RX_EEPROM_OFFSET 877 // (4) TX ID + format, 5 bytes, end is 882
#define MOULDKG_EEPROM_OFFSET 882 // RX ID, 3 bytes per model, end is 882+64*3=1074
#define DSM_CLONE_EEPROM_OFFSET 1074 // (4) TX ID, (1) Initialized, end is 1079
#define TRAXXAS_EEPROM_OFFSET 1079 // RX ID, 2 bytes per model id, end is 1079+128=1207
//#define CONFIG_EEPROM_OFFSET 1207 // Current configuration of the multimodule
#define TRAXXAS_EEPROM_OFFSET 1079 // RX ID and SOP index, 3 bytes per model id, end is 1079+192=1271
//#define CONFIG_EEPROM_OFFSET 1271 // Current configuration of the multimodule
/* STM32 Flash Size */
#ifndef DISABLE_FLASH_SIZE_CHECK
@@ -923,7 +931,6 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
FX 58
BAYANG_RX 59
PELIKAN 60
TIGER 61
XK 62
XN297DUMP 63
FRSKYX2 64
@@ -1104,7 +1111,7 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
RED_FAST 0
RED_SLOW 1
sub_protocol==TRAXXAS
RX6519 0
TQ 0
sub_protocol==ESKY150
ESKY150_4CH 0
ESKY150_7CH 1

View File

@@ -22,7 +22,7 @@
//#define PELIKAN_LITE_FORCE_ID
#define PELIKAN_LITE_FORCE_HOP // hop sequence creation is unknown
//#define PELIKAN_SCX24_FORCE_ID
#define PELIKAN_SCX24_FORCE_HOP // hop sequence creation is unknown
//#define PELIKAN_SCX24_FORCE_HOP // hop sequence creation is unknown
#define PELIKAN_BIND_COUNT 400 // 3sec
#define PELIKAN_BIND_RF 0x3C
@@ -30,6 +30,7 @@
#define PELIKAN_PACKET_PERIOD 7980
#define PELIKAN_LITE_PACKET_PERIOD 18000
#define PELIKAN_SCX24_PACKET_PERIOD 15069
#define PELIKAN_SCX_HOP_LIMIT 90
static void __attribute__((unused)) pelikan_build_packet()
{
@@ -37,9 +38,11 @@ static void __attribute__((unused)) pelikan_build_packet()
uint8_t sum;
uint16_t channel;
#ifndef MULTI_AIR
if(sub_protocol == PELIKAN_SCX24)
packet[0] = 0x11;
else //PELIKAN_PRO & PELIKAN_LITE
#endif
packet[0] = 0x15;
if(IS_BIND_IN_PROGRESS)
{
@@ -48,6 +51,7 @@ static void __attribute__((unused)) pelikan_build_packet()
packet[4] = rx_tx_addr[2];
packet[5] = rx_tx_addr[3];
#ifndef MULTI_AIR
if(sub_protocol == PELIKAN_SCX24)
{
packet[1] = 0x65; //??
@@ -55,6 +59,7 @@ static void __attribute__((unused)) pelikan_build_packet()
packet[7] = 0xAA; //??
}
else
#endif
{//PELIKAN_PRO & PELIKAN_LITE
packet[1] = 0x04; //version??
if(sub_protocol==PELIKAN_PRO)
@@ -70,6 +75,7 @@ static void __attribute__((unused)) pelikan_build_packet()
{
//ID
packet[1] = rx_tx_addr[0];
#ifndef MULTI_AIR
if(sub_protocol == PELIKAN_SCX24)
{
//ID
@@ -95,6 +101,7 @@ static void __attribute__((unused)) pelikan_build_packet()
packet_length = 14;
}
else
#endif
{//PELIKAN_PRO & PELIKAN_LITE
//ID
packet[7] = rx_tx_addr[1];
@@ -158,6 +165,13 @@ static void __attribute__((unused)) pelikan_build_packet()
uint16_t PELIKAN_callback()
{
#ifdef MULTI_AIR
if(sub_protocol == PELIKAN_SCX24)
{
SUB_PROTO_INVALID;
return 10000;
}
#endif
if(phase==0)
{
#ifndef FORCE_PELIKAN_TUNING
@@ -172,10 +186,12 @@ uint16_t PELIKAN_callback()
A7105_Strobe(A7105_STANDBY);
if(sub_protocol==PELIKAN_PRO)
A7105_WriteReg(A7105_03_FIFOI,0x28); //????
else if(sub_protocol==PELIKAN_SCX24)
A7105_WriteReg(A7105_03_FIFOI,0x0D);
else//PELIKAN_LITE
else if(sub_protocol==PELIKAN_LITE)
A7105_WriteID(MProtocol_id);
#ifndef MULTI_AIR
else // PELIKAN_SCX24
A7105_WriteReg(A7105_03_FIFOI,0x0D);
#endif
}
}
#ifdef MULTI_SYNC
@@ -216,6 +232,82 @@ static uint8_t pelikan_firstCh(uint8_t u, uint8_t l)
return 0;
}
static uint8_t pelikan_firstCh_scx(uint8_t i, uint8_t j)
{
uint8_t ch;
switch (j) {
case 0:
ch = 30;
break;
case 1:
case 2:
ch = (i * 4) + 42;
break;
case 3:
ch = (i * 2) + 36;
break;
case 4:
ch = (i * 8) + 54;
break;
case 5:
ch = 30;
break;
}
if (ch > PELIKAN_SCX_HOP_LIMIT)
{
do
{
ch -= 62;
} while (ch > PELIKAN_SCX_HOP_LIMIT);
}
switch (ch) {
case 48:
if (j == 3)
ch += 18;
else if (j == 4)
ch += 20;
else
ch += 40;
break;
case 40:
if (j == 4)
ch += 18;
break;
case 52:
if (j < 3)
ch -= 20;
else if (j == 4)
ch -= 10;
break;
case 66:
if (j < 3)
ch += 18;
else if (j == 4)
ch -= 22;
break;
case 72:
if (j < 3)
ch -= 10;
else if (j ==3)
ch -= 20;
else if (j == 4)
ch -= 36;
break;
case 74:
if (j == 4)
ch -= 20;
break;
case 86:
if (j == 4)
ch -= 48;
break;
}
return ch;
}
static uint8_t pelikan_adjust_value(uint8_t value, uint8_t addition, uint8_t limit)
{
uint8_t i;
@@ -234,6 +326,10 @@ static uint8_t pelikan_adjust_value(uint8_t value, uint8_t addition, uint8_t lim
value += addition;
i++;
}
if (value == 72) {
value += addition;
i++;
}
}
while (i > 0);
@@ -278,6 +374,121 @@ static void __attribute__((unused)) pelikan_init_hop()
debugln("");
}
#ifndef MULTI_AIR
const uint8_t PROGMEM scx_ch_map[4][PELIKAN_NUM_RF_CHAN] =
{
{0,1,2,26,27,28,23,24,25,20,21,22,17,18,19,14,15,16,11,12,13,8,9,10,5,6,7,4,3},
{0,1,2,28,25,26,27,24,21,22,23,20,17,18,19,16,13,14,15,12,9,10,11,8,5,6,7,3,4},
{0,1,27,28,25,26,23,24,21,22,19,20,17,18,15,16,13,14,11,12,9,10,7,8,5,6,3,4,2},
{0,1,28,1,4,2,23,26,22,24,27,25,17,20,16,18,21,19,11,14,10,12,15,13,27,8,6,7,9}
};
static void pelikan_shuffle(uint8_t j)
{
uint8_t temp[PELIKAN_NUM_RF_CHAN];
for (uint8_t i = 0; i < PELIKAN_NUM_RF_CHAN; i++)
temp[i] = hopping_frequency[pgm_read_byte_near(&scx_ch_map[j-1][i])];
for (uint8_t i = 0; i < PELIKAN_NUM_RF_CHAN; i++)
hopping_frequency[i] = temp[i];
}
static void __attribute__((unused)) pelikan_init_hop_scx()
{
rx_tx_addr[0] = 0x10;
rx_tx_addr[1] = (rx_tx_addr[1] + RX_num) % 192;
debugln("TX[0]: %02X TX[1]: %02X", rx_tx_addr[0], rx_tx_addr[1]);
uint8_t high = (rx_tx_addr[1]>>4);
uint8_t low = rx_tx_addr[1] & 0x0F;
int16_t i = (high * 10) + low - 23;
uint8_t j = 0;
if (i > 0)
j = 1;
if (i > 24)
{
do
{
i -= 24;
j++;
} while (i > 24);
}
debugln("H: %02X L: %02X I: %02X J: %02X", high, low, i, j);
uint8_t first_channel;
uint8_t last_channel;
uint8_t addition;
first_channel = pelikan_firstCh_scx(i, j);
if (j == 0)
last_channel = 42 - (high * 10) - low;
else
last_channel = 42 - i + 1;
if (last_channel == 24)
last_channel += 9;
if (last_channel == 36)
last_channel -= 10;
if (j == 0)
addition = (2 * i) + 54;
else if (j == 5)
addition = (2 * i) + 6;
else
addition = 56 - (2 * i);
hopping_frequency[0] = first_channel;
for (uint8_t i = 1; i < PELIKAN_NUM_RF_CHAN; i++)
{
hopping_frequency[i] = pelikan_add(hopping_frequency[i-1], addition, PELIKAN_SCX_HOP_LIMIT);
}
if (j > 0 && j < 5)
pelikan_shuffle(j);
if (j == 2)
{
hopping_frequency[PELIKAN_NUM_RF_CHAN - 2] = last_channel;
} else if (j == 4)
{
uint8_t t = (2 * i) + 36;
if (t == 48)
t += 18;
if (t == 72)
t -= 20;
hopping_frequency[1] = t;
hopping_frequency[PELIKAN_NUM_RF_CHAN - 5] = last_channel;
}
else
{
hopping_frequency[PELIKAN_NUM_RF_CHAN - 1] = last_channel;
}
#ifdef DEBUG_SERIAL
for (uint8_t i = 0; i < PELIKAN_NUM_RF_CHAN; i++)
debug("%02X ", hopping_frequency[i]);
debugln("");
#endif
}
#ifdef PELIKAN_SCX24_FORCE_HOP
const uint8_t PROGMEM pelikan_scx24_hopp[][PELIKAN_NUM_RF_CHAN] = {
/*TX1*/ { 0x1E,0x32,0x46,0x5A,0x44,0x58,0x2E,0x42,0x56,0x2C,0x40,0x54,0x2A,0x3E,0x52,0x28,0x3C,0x50,0x26,0x3A,0x4E,0x24,0x38,0x4C,0x22,0x36,0x4A,0x20,0x1A },
/*TX2*/ { 0x2C,0x44,0x1E,0x52,0x56,0x22,0x3A,0x3E,0x34,0x4C,0x26,0x5A,0x50,0x2A,0x42,0x38,0x2E,0x46,0x20,0x54,0x4A,0x24,0x3C,0x32,0x28,0x40,0x58,0x1B,0x4E },
/*TX3*/ { 0x3C,0x4C,0x1E,0x4A,0x5A,0x2C,0x58,0x2A,0x3A,0x56,0x28,0x38,0x26,0x36,0x46,0x34,0x44,0x54,0x42,0x52,0x24,0x50,0x22,0x32,0x4E,0x20,0x40,0x3E,0x17 },
/*TX4*/ { 0x46,0x32,0x1E,0x58,0x44,0x5A,0x56,0x42,0x2E,0x54,0x40,0x2C,0x52,0x3E,0x2A,0x50,0x3C,0x28,0x4E,0x3A,0x26,0x4C,0x38,0x24,0x4A,0x36,0x22,0x20,0x1A }
};
#endif //PELIKAN_SCX24_FORCE_HOP
#endif //MULTI_AIR
#ifdef PELIKAN_FORCE_ID
const uint8_t PROGMEM pelikan_hopp[][PELIKAN_NUM_RF_CHAN] = {
{ 0x5A,0x46,0x32,0x6E,0x6C,0x58,0x44,0x42,0x40,0x6A,0x56,0x54,0x52,0x3E,0x68,0x66,0x64,0x50,0x3C,0x3A,0x38,0x62,0x4E,0x4C,0x5E,0x4A,0x36,0x5C,0x34 }
@@ -289,14 +500,6 @@ const uint8_t PROGMEM pelikan_lite_hopp[][PELIKAN_NUM_RF_CHAN] = {
{ 0x46,0x2A,0x3E,0x5A,0x5C,0x24,0x4E,0x32,0x54,0x26,0x2C,0x34,0x56,0x1E,0x3A,0x3C,0x50,0x4A,0x2E,0x42,0x20,0x52,0x28,0x22,0x44,0x58,0x36,0x38,0x4C }
};
#endif
#ifdef PELIKAN_SCX24_FORCE_HOP
const uint8_t PROGMEM pelikan_scx24_hopp[][PELIKAN_NUM_RF_CHAN] = {
/*TX1*/ { 0x1E,0x32,0x46,0x5A,0x44,0x58,0x2E,0x42,0x56,0x2C,0x40,0x54,0x2A,0x3E,0x52,0x28,0x3C,0x50,0x26,0x3A,0x4E,0x24,0x38,0x4C,0x22,0x36,0x4A,0x20,0x1A },
/*TX2*/ { 0x2C,0x44,0x1E,0x52,0x56,0x22,0x3A,0x3E,0x34,0x4C,0x26,0x5A,0x50,0x2A,0x42,0x38,0x2E,0x46,0x20,0x54,0x4A,0x24,0x3C,0x32,0x28,0x40,0x58,0x1B,0x4E },
/*TX3*/ { 0x3C,0x4C,0x1E,0x4A,0x5A,0x2C,0x58,0x2A,0x3A,0x56,0x28,0x38,0x26,0x36,0x46,0x34,0x44,0x54,0x42,0x52,0x24,0x50,0x22,0x32,0x4E,0x20,0x40,0x3E,0x17 },
/*TX4*/ { 0x46,0x32,0x1E,0x58,0x44,0x5A,0x56,0x42,0x2E,0x54,0x40,0x2C,0x52,0x3E,0x2A,0x50,0x3C,0x28,0x4E,0x3A,0x26,0x4C,0x38,0x24,0x4A,0x36,0x22,0x20,0x1A }
};
#endif
void PELIKAN_init()
{
@@ -343,8 +546,10 @@ void PELIKAN_init()
A7105_WriteID(MProtocol_id);
packet_period = PELIKAN_LITE_PACKET_PERIOD;
}
#ifndef MULTI_AIR
else// if(sub_protocol==PELIKAN_SCX24)
{
pelikan_init_hop_scx();
#if defined(PELIKAN_SCX24_FORCE_HOP)
// Hop frequency table
uint8_t num=rx_tx_addr[3] & 0x03;
@@ -386,6 +591,7 @@ void PELIKAN_init()
A7105_WriteReg(A7105_03_FIFOI,0x0D);
packet_period = PELIKAN_SCX24_PACKET_PERIOD;
}
#endif //MULTI_AIR
}
hopping_frequency_no = PELIKAN_NUM_RF_CHAN;

View File

@@ -18,7 +18,7 @@ Multiprotocol is distributed in the hope that it will be useful,
#include "iface_xn297.h"
#define FORCE_REALACC_ORIGINAL_ID
//#define FORCE_REALACC_ORIGINAL_ID
#define REALACC_INITIAL_WAIT 500
#define REALACC_PACKET_PERIOD 2268
@@ -30,7 +30,7 @@ Multiprotocol is distributed in the hope that it will be useful,
static void __attribute__((unused)) REALACC_send_packet()
{
packet[ 0]= 0xDC;
packet[ 0]= 0xDC; // DC/D6/DE
packet[ 1]= convert_channel_8b(AILERON); // 00..80..FF
packet[ 2]= convert_channel_8b(ELEVATOR); // 00..80..FF
packet[ 3]= convert_channel_8b(THROTTLE); // 00..FF
@@ -39,16 +39,17 @@ static void __attribute__((unused)) REALACC_send_packet()
packet[ 6]= 0x20; // Trim
packet[ 7]= 0x20; // Trim
packet[ 8]= 0x20; // Trim
packet[ 9]= num_ch; // Change at each power up
packet[10]= 0x04 // Flag1
packet[ 9]= 0x88; // Change at each power up: C5 A2 77 F0 84 58, fixed for the E017 = 88
packet[10]= 0x04 // Flag1: R11=04, E017=0C
| 0x02 // Rate1=0, Rate2=1, Rate3=2
| GET_FLAG(CH8_SW, 0x20); // Headless
packet[11]= 0x00 // Flag2
| GET_FLAG(CH7_SW, 0x01) // Calib
| GET_FLAG(CH9_SW, 0x20) // Return
| GET_FLAG(CH10_SW,0x80); // Unknown
| GET_FLAG(CH10_SW,0x80); // Throttle cut
packet[12]= 0x00 // Flag3
| GET_FLAG(CH5_SW, 0x01) // Flip
| GET_FLAG(CH11_SW,0x02) // Rotating
| GET_FLAG(CH6_SW, 0x80); // Light
XN297_Hopping(hopping_frequency_no);
@@ -59,31 +60,50 @@ static void __attribute__((unused)) REALACC_send_packet()
static void __attribute__((unused)) REALACC_send_bind_packet()
{
packet[0] = 0xB1;
memcpy(&packet[1],rx_tx_addr,4);
memcpy(&packet[5],hopping_frequency,5);
packet[0] = 0xB1; // B0/B1
memcpy(&packet[1],rx_tx_addr,4); // Address
memcpy(&packet[5],hopping_frequency,5); // RF frequencies
XN297_WriteEnhancedPayload(packet, REALACC_BIND_PAYLOAD_SIZE,1);
}
static void __attribute__((unused)) REALACC_initialize_txid()
{
rx_tx_addr[3] &= 0x3F;
calc_fh_channels(REALACC_RF_NUM_CHANNELS);
num_ch=random(0xfefefefe); // 00..FF
#ifdef FORCE_REALACC_ORIGINAL_ID
//Dump
rx_tx_addr[0]=0x99;
rx_tx_addr[1]=0x06;
rx_tx_addr[2]=0x00;
rx_tx_addr[3]=0x00;
hopping_frequency[0]=0x55;
hopping_frequency[1]=0x59;
hopping_frequency[2]=0x5A;
hopping_frequency[3]=0x5A;
hopping_frequency[4]=0x62;
num_ch=0xC5; // Value in dumps: C5 A2 77 F0 84 58
if(RX_num==0)
{//TX1
rx_tx_addr[0]=0x99;
rx_tx_addr[1]=0x06;
rx_tx_addr[2]=0x00;
rx_tx_addr[3]=0x00; // 00..3F:OK, 40..:NOK
hopping_frequency[0]=0x55;
hopping_frequency[1]=0x59;
hopping_frequency[2]=0x5A;
hopping_frequency[3]=0x5A;
hopping_frequency[4]=0x62;
}
else
{//TX2
rx_tx_addr[0]=0x4F;
rx_tx_addr[1]=0xB9;
rx_tx_addr[2]=0xA1;
rx_tx_addr[3]=0x17;
hopping_frequency[0]=0x45;
hopping_frequency[1]=0x38;
hopping_frequency[2]=0x3C;
hopping_frequency[3]=0x41;
hopping_frequency[4]=0x3F;
}
#endif
#if 0
debug("ID: %02X %02X %02X %02X, C: ",rx_tx_addr[0],rx_tx_addr[1],rx_tx_addr[2],rx_tx_addr[3]);
for(uint8_t i=0; i<REALACC_RF_NUM_CHANNELS; i++)
debug(" %02X",hopping_frequency[i]);
debugln("");
#endif
}
static void __attribute__((unused)) REALACC_RF_init()
@@ -129,18 +149,39 @@ void REALACC_init()
// Bind
// Address = 4D 41 49 4E = 'MAIN'
// Channel = 80 (most likely from dump)
// P(10) = B1 99 06 00 00 55 59 5A 5A 62
// B1 indicates bind packet
// TX1
// ---
// P(10) = B1 99 06 00 00 55 59 5A 5A 62
// Bx indicates bind packet, why x=1?
// 99 06 00 00 = ID = address of normal packets
// 55 59 5A 5A 62 = 85, 89, 90, 90, 98 = RF channels to be used (kind of match previous dumps)// Normal
// 55 59 5A 5A 62 = 85, 89, 90, 90, 98 = RF channels to be used (kind of match previous dumps)
// TX2
// ---
// P(10) = B0 4F B9 A1 17 45 38 3C 41 3F
// Bx indicates bind packet, why x=0?
// 4F B9 A1 17 = ID = address of normal packets
// 45 38 3C 41 3F = 69, 56, 60, 65, 63 = RF channels to be used
// Normal
// Address = 99 06 00 00
// Channels = 84, 89, 90, 90, 98 (guess from bind)
// P(13)= DC 80 80 32 80 20 20 20 20 58 04 00 00
// DC = normal packet
// 80 80 32 80 : AETR 00..80..FF
// 20 20 20 20 : Trims
// 58 : changing every time the TX restart
// 04 : |0x20=headless, |0x01=rate2, |0x02=rate3
// 00 : |0x01=calib, |0x20=return, |0x80=unknown
// 00 : |0x80=light, |0x01=flip
// TX1
// ---
// Address = 99 06 00 00
// Channels = 84, 89, 90, 90, 98 (guess from bind)
// P(13)= DC 80 80 32 80 20 20 20 20 58 04 00 00
// Dx = normal packet, why C ?
// 80 80 32 80 : AETR 00..80..FF
// 20 20 20 20 : Trims
// 58 : changing every time the TX restart
// 04 : |0x20=headless, |0x01=rate2, |0x02=rate3
// 00 : |0x01=calib, |0x20=return, |0x80=unknown
// 00 : |0x80=light, |0x01=flip
// TX2
// ---
// Address = 4F B9 A1 17
// P(13)= D6/DE 80 80 80 80 20 20 20 20 88 0C 00 00
// Dx = normal packet, why 6/E ?
// 80 80 32 80 : AETR 00..80..FF
// 20 20 20 20 : Trims
// 88 : not changing unknown
// 0C : |0x20=headless, |0x01=rate2, |0x02=rate3
// 00 : |0x01=calib, |0x20=return, |0x80=unknown
// 00 : |0x80=light, |0x01=flip, |0x02=Rotating

View File

@@ -18,7 +18,11 @@
#include "iface_cc2500.h"
//#define RLINK_DEBUG
//#define RLINK_DEBUG_TELEM
//#define RLINK_FORCE_ID
//#define RLINK_RC4G_FORCE_ID
#define RLINK_TX_PACKET_LEN 33
#define RLINK_RX_PACKET_LEN 15
@@ -97,16 +101,70 @@ static void __attribute__((unused)) RLINK_hop()
static void __attribute__((unused)) RLINK_TXID_init()
{
#ifdef RLINK_RC4G_FORCE_ID
//TODO: test any ID
if(sub_protocol==RLINK_RC4G)
{
rx_tx_addr[1]=0x77;
rx_tx_addr[2]=0x00;
rx_tx_addr[3]=0x00;
}
#endif
#ifdef RLINK_FORCE_ID
//surface RC6GS
memcpy(rx_tx_addr,"\x3A\x99\x22\x3A",RLINK_TX_ID_LEN);
//air T8FB
//memcpy(rx_tx_addr,"\xFC\x11\x0D\x20",RLINK_TX_ID_LEN);
if(sub_protocol==RLINK_SURFACE)
memcpy(rx_tx_addr,"\x3A\x99\x22\x3A",RLINK_TX_ID_LEN); //surface RC6GS
else
memcpy(rx_tx_addr,"\xFC\x11\x0D\x20",RLINK_TX_ID_LEN); //air T8FB
#endif
// channels order depend on ID
RLINK_hop();
if(sub_protocol!=RLINK_RC4G)
RLINK_hop();
else
{//RLINK_RC4G
// Find 2 unused channels
// first channel is a multiple of 3 between 00 and 5D
// second channel is a multiple of 3 between 63 and BD
CC2500_Strobe(CC2500_SIDLE);
CC2500_WriteReg(CC2500_17_MCSM1,0x3C);
CC2500_Strobe(CC2500_SFRX);
CC2500_SetTxRxMode(RX_EN);
CC2500_Strobe(CC2500_SRX);
delayMilliseconds(1); //wait for RX mode
uint16_t val;
uint8_t val_low = 0xFF;
hopping_frequency[0] = 0x00;
hopping_frequency[1] = 0x63;
for(uint8_t ch=0; ch<=0xBD; ch+=3)
{
if(ch==0x63)
val_low = 0xFF; //init for second block
if(ch==0x60)
continue; //skip channel
CC2500_WriteReg(CC2500_0A_CHANNR, ch); //switch channel
delayMicroseconds(370); //wait to read
val = 0;
for(uint8_t i=0;i<16;i++)
val += CC2500_ReadReg(CC2500_34_RSSI | CC2500_READ_BURST);
val >>= 4;
debug("C:%02X RSSI:%02X",ch,val);
if(val_low > val)
{
debug(" OK");
val_low = val;
hopping_frequency[ch<0x63?0:1]=ch; //save best channel
}
debugln("");
}
CC2500_WriteReg(CC2500_17_MCSM1,0x30);
CC2500_Strobe(CC2500_SIDLE);
CC2500_SetTxRxMode(TX_EN);
#ifdef RLINK_RC4G_FORCE_ID
hopping_frequency[0] = 0x03;
hopping_frequency[1] = 0x6F;
#endif
}
#if 0
#ifdef RLINK_DEBUG
debug("ID:");
for(uint8_t i=0;i<RLINK_TX_ID_LEN;i++)
debug(" 0x%02X",rx_tx_addr[i]);
@@ -138,7 +196,9 @@ static void __attribute__((unused)) RLINK_rf_init()
CC2500_WriteReg(4, 0xBA);
CC2500_WriteReg(5, 0xDC);
}
else if(sub_protocol==RLINK_RC4G)
CC2500_WriteReg(5, 0xA5);
CC2500_WriteReg(CC2500_0C_FSCTRL0, option);
CC2500_SetTxRxMode(TX_EN);
@@ -219,18 +279,79 @@ static void __attribute__((unused)) RLINK_send_packet()
packet_count++;
if(packet_count>5) packet_count=0;
//debugln("C= 0x%02X",hopping_frequency[pseudo & 0x0F]);
//debug("P=");
//for(uint8_t i=1;i<RLINK_TX_PACKET_LEN+1;i++)
// debug(" 0x%02X",packet[i]);
//debugln("");
#ifdef RLINK_DEBUG
debugln("C= 0x%02X",hopping_frequency[pseudo & 0x0F]);
debug("P=");
for(uint8_t i=1;i<RLINK_TX_PACKET_LEN+1;i++)
debug(" 0x%02X",packet[i]);
debugln("");
#endif
}
#ifndef MULTI_AIR
static void __attribute__((unused)) RLINK_RC4G_send_packet()
{
uint32_t val;
//hop
CC2500_WriteReg(CC2500_0A_CHANNR, hopping_frequency[packet_count>>1]);
#ifdef RLINK_DEBUG
debug("C= 0x%02X ",hopping_frequency[packet_count>>1]);
#endif
// packet length
packet[0] = 0x0F;
//address
memcpy(&packet[1], &rx_tx_addr[1], 3);
//channels
for(uint8_t i=0;i<2;i++)
{
val = Channel_data[2*i ] +400 -24;
packet[4+i*2] = val;
packet[8+i ] = val>>8;
val = Channel_data[2*i+1] +400 -24;
packet[5+i*2] = val;
packet[8+i ] |= (val>>4) & 0xF0;
}
//special channel which is linked to gyro on the orginal TX but allocating it on CH5 here
packet[10] = convert_channel_16b_limit(CH5,0,100);
//failsafe
for(uint8_t i=0;i<4;i++)
packet[11+i] = convert_channel_16b_limit(CH6+i,0,200);
//next hop
packet_count++;
packet_count &= 0x03;
packet[15] = hopping_frequency[packet_count>>1];
// send packet
CC2500_WriteData(packet, 16);
#ifdef RLINK_DEBUG
debug("P=");
for(uint8_t i=1;i<16;i++)
debug(" 0x%02X",packet[i]);
debugln("");
#endif
}
#endif
#define RLINK_TIMING_PROTO 20000-100 // -100 for compatibility with R8EF
#define RLINK_TIMING_RFSEND 10500
#define RLINK_TIMING_CHECK 2000
#define RLINK_RC4G_TIMING_PROTO 14460
uint16_t RLINK_callback()
{
if(sub_protocol == RLINK_RC4G)
{
#ifndef MULTI_AIR
#ifdef MULTI_SYNC
telemetry_set_input_sync(RLINK_RC4G_TIMING_PROTO);
#endif
CC2500_SetPower();
CC2500_SetFreqOffset();
RLINK_RC4G_send_packet();
#else
SUB_PROTO_INVALID;
#endif
return RLINK_RC4G_TIMING_PROTO;
}
switch(phase)
{
case RLINK_DATA:
@@ -259,13 +380,16 @@ uint16_t RLINK_callback()
len = CC2500_ReadReg(CC2500_3B_RXBYTES | CC2500_READ_BURST) & 0x7F;
if (len == RLINK_RX_PACKET_LEN + 1 + 2) //Telemetry frame is 15 bytes + 1 byte for length + 2 bytes for RSSI&LQI&CRC
{
//debug("Telem:");
#ifdef RLINK_DEBUG_TELEM
debug("Telem:");
#endif
CC2500_ReadData(packet_in, len);
if(packet_in[0]==RLINK_RX_PACKET_LEN && (packet_in[len-1] & 0x80) && memcmp(&packet[2],rx_tx_addr,RLINK_TX_ID_LEN)==0 && packet_in[6]==packet[1])
{//Correct telemetry received: length, CRC, ID and type
//Debug
//for(uint8_t i=0;i<len;i++)
// debug(" %02X",packet_in[i]);
#ifdef RLINK_DEBUG_TELEM
for(uint8_t i=0;i<len;i++)
debug(" %02X",packet_in[i]);
#endif
TX_RSSI = packet_in[len-2];
if(TX_RSSI >=128)
TX_RSSI -= 128;
@@ -278,7 +402,9 @@ uint16_t RLINK_callback()
pps_counter++;
packet_count=0;
}
//debugln("");
#ifdef RLINK_DEBUG_TELEM
debugln("");
#endif
}
if (millis() - pps_timer >= 2000)
{//1 telemetry packet every 100ms

View File

@@ -0,0 +1,175 @@
/*
This project is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Multiprotocol is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
*/
// Compatible with SGF22 R11
#if defined(SGF22_NRF24L01_INO)
#include "iface_xn297.h"
//#define FORCE_SGF22_ORIGINAL_ID
#define SGF22_PACKET_PERIOD 11950 //10240
#define SGF22_BIND_RF_CHANNEL 78
#define SGF22_PAYLOAD_SIZE 12
#define SGF22_BIND_COUNT 50
#define SGF22_RF_NUM_CHANNELS 4
//packet[8]
#define SGF22_FLAG_3D 0x00
#define SGF22_FLAG_ROLL 0x08
#define SGF22_FLAG_LIGHT 0x04
#define SGF22_FLAG_VIDEO 0x10
#define SGF22_FLAG_6G 0x40
#define SGF22_FLAG_VERTICAL 0xC0
//packet[9]
#define SGF22_FLAG_PHOTO 0x40
#define SGF22_FLAG_TRIMRESET 0x04
static void __attribute__((unused)) SGF22_send_packet()
{
if(IS_BIND_IN_PROGRESS)
{
packet[ 0] = 0x5B;
packet[ 8] = 0x00; // ??? do they have to be 0 for bind to succeed ?
packet[ 9] = 0x00; // ??? do they have to be 0 for bind to succeed ?
packet[10] = 0xAA;
packet[11] = 0x55;
}
else
{
//hop
XN297_Hopping(packet_sent & 0x03); // ??? from the dumps I can't really say how hop and seq are sync, there could be an offset (0,1,2,3)...
//sequence from 02 to 7A by increments of 4, sometimes with a flag 0x80 from 82 to FA, I can't tell from the dumps when the switch happens
if( (packet_sent & 0x03) == 0x02)
packet_count = packet_sent;
packet_sent++;
if(packet_sent > 0x7B)
packet_sent = 0;
//packet
packet[0] = 0x1B;
packet[8] = SGF22_FLAG_3D // default
| GET_FLAG(CH6_SW, SGF22_FLAG_ROLL) // roll
| GET_FLAG(CH7_SW, SGF22_FLAG_LIGHT) // push up throttle trim for light
| GET_FLAG(CH9_SW, SGF22_FLAG_VIDEO); // push down throttle trim for video
if(Channel_data[CH5] > CHANNEL_MIN_COMMAND)
packet[8] |= SGF22_FLAG_6G; // mode 1 - 6g
if(Channel_data[CH5] > CHANNEL_MAX_COMMAND)
packet[8] |= SGF22_FLAG_VERTICAL; // mode 0 - vertical
packet[9] = GET_FLAG(CH8_SW, SGF22_FLAG_PHOTO) // press in throttle trim for photo
| GET_FLAG(CH10_SW, SGF22_FLAG_TRIMRESET); // Both sticks down inwards
packet[10] = 0x42; // no fine tune
packet[11] = 0x10; // no fine tune
}
packet[1] = packet_count; // sequence
packet[2] = rx_tx_addr[2];
packet[3] = rx_tx_addr[3];
packet[4] = convert_channel_8b(THROTTLE);
packet[5] = convert_channel_8b(RUDDER);
packet[6] = convert_channel_8b(ELEVATOR);
packet[7] = convert_channel_8b(AILERON);
XN297_SetPower();
XN297_SetTxRxMode(TX_EN);
XN297_WriteEnhancedPayload(packet, SGF22_PAYLOAD_SIZE,0);
#if 0
debug_time("");
for(uint8_t i=0; i<SGF22_PAYLOAD_SIZE; i++)
debug(" %02X",packet[i]);
debugln("");
#endif
}
static void __attribute__((unused)) SGF22_initialize_txid()
{
uint16_t val = ( rx_tx_addr[2] << 8 ) | rx_tx_addr[3];
if ( rx_tx_addr[2] > ( 0xFF - rx_tx_addr[3]) )
val--;
val %= 5;
const uint8_t hop[5][4] =
{ { 0x0C, 0x2A, 0x1B, 0x39 },
{ 0x0F, 0x2D, 0x1E, 0x3D },
{ 0x12, 0x31, 0x21, 0x41 },
{ 0x15, 0x34, 0x24, 0x44 },
{ 0x18, 0x37, 0x27, 0x47 } };
memcpy(hopping_frequency, &hop[val], SGF22_RF_NUM_CHANNELS);
/*//Same code sze...
hopping_frequency[0] = 0x0C + 3 * val;
hopping_frequency[1] = hopping_frequency[0] + 0x1E;
if(val > 1) hopping_frequency[1]++;
hopping_frequency[2] = hopping_frequency[0] + 0x0F;
hopping_frequency[3] = hopping_frequency[1] + 0x0F;
if(val ) hopping_frequency[3]++;*/
#ifdef FORCE_SGF22_ORIGINAL_ID
rx_tx_addr[2] = 0x1F; // TX2:27 TX3:2B
rx_tx_addr[3] = 0x61; // TX2:51 TX3:0C
memcpy(hopping_frequency,"\x15\x34\x24\x44", SGF22_RF_NUM_CHANNELS); //Original dump=>21=0x15,52=0x34,36=0x24,68=0x44
#endif
#if 0
debug("ID: %02X %02X, C: ",rx_tx_addr[2],rx_tx_addr[3]);
for(uint8_t i=0; i<SGF22_RF_NUM_CHANNELS; i++)
debug(" %02X",hopping_frequency[i]);
debugln("");
#endif
}
static void __attribute__((unused)) SGF22_RF_init()
{
XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M);
XN297_SetTXAddr((uint8_t*)"\xC7\x95\x3C\xBB\xA5", 5);
XN297_RFChannel(SGF22_BIND_RF_CHANNEL); // Set bind channel
}
uint16_t SGF22_callback()
{
if(phase == 0)
{
phase++;
#ifdef MULTI_SYNC
telemetry_set_input_sync(SGF22_PACKET_PERIOD);
#endif
SGF22_send_packet();
if(IS_BIND_IN_PROGRESS)
{
if(--bind_counter==0)
BIND_DONE;
}
}
else
{//send 3 times in total the same packet
NRF24L01_Strobe(REUSE_TX_PL);
phase++;
if(phase > 2)
{
phase = 0;
return SGF22_PACKET_PERIOD - 2*1550;
}
}
return 1550;
}
void SGF22_init()
{
BIND_IN_PROGRESS; // autobind protocol
SGF22_initialize_txid();
SGF22_RF_init();
bind_counter=SGF22_BIND_COUNT;
packet_sent = packet_count = 0x26; // TX2:26 TX3:26
phase = 0;
}
#endif

View File

@@ -21,11 +21,12 @@
//#define SLT_Q200_FORCE_ID
// For code readability
#define SLT_PAYLOADSIZE_V1 7
#define SLT_PAYLOADSIZE_V2 11
#define SLT_NFREQCHANNELS 15
#define SLT_TXID_SIZE 4
#define SLT_BIND_CHANNEL 0x50
#define SLT_PAYLOADSIZE_V1 7
#define SLT_PAYLOADSIZE_V1_4 5
#define SLT_PAYLOADSIZE_V2 11
#define SLT_NFREQCHANNELS 15
#define SLT_TXID_SIZE 4
#define SLT_BIND_CHANNEL 0x50
enum{
// flags going to packet[6] (Q200)
@@ -93,6 +94,12 @@ static void __attribute__((unused)) SLT_set_freq(void)
}
}
}
#if 0
debug("CH:");
for (uint8_t i = 0; i < SLT_NFREQCHANNELS; ++i)
debug(" %02X", hopping_frequency[i]);
debugln();
#endif
//Bind channel
hopping_frequency[SLT_NFREQCHANNELS]=SLT_BIND_CHANNEL;
@@ -129,44 +136,47 @@ 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], false);
if(sub_protocol>SLT_V2 && (i==CH2 || i==CH3) )
uint16_t v = convert_channel_10b(sub_protocol != SLT_V1_4 ? CH_AETR[i] : i, false);
if(sub_protocol>SLT_V2 && (i==CH2 || i==CH3) && sub_protocol != SLT_V1_4)
v=1023-v; // reverse throttle and elevator channels for Q100/Q200/MR100 protocols
packet[i] = v;
e = (e >> 2) | (uint8_t) ((v >> 2) & 0xC0);
}
// Extra bits for AETR
packet[4] = e;
//->V1_4CH stops here
// 8-bit channels
packet[5] = convert_channel_8b(CH5);
packet[6] = convert_channel_8b(CH6);
if(sub_protocol!=SLT_V1)
{
if(sub_protocol==Q200)
packet[6] = GET_FLAG(CH9_SW , FLAG_Q200_FMODE)
|GET_FLAG(CH10_SW, FLAG_Q200_FLIP)
|GET_FLAG(CH11_SW, FLAG_Q200_VIDON)
|GET_FLAG(CH12_SW, FLAG_Q200_VIDOFF);
else if(sub_protocol==MR100 || sub_protocol==Q100)
packet[6] = GET_FLAG(CH9_SW , FLAG_MR100_FMODE)
|GET_FLAG(CH10_SW, FLAG_MR100_FLIP)
|GET_FLAG(CH11_SW, FLAG_MR100_VIDEO) // Does not exist on the Q100 but...
|GET_FLAG(CH12_SW, FLAG_MR100_PICTURE); // Does not exist on the Q100 but...
packet[7]=convert_channel_8b(CH7);
packet[8]=convert_channel_8b(CH8);
packet[9]=0xAA; //normal mode for Q100/Q200, unknown for V2/MR100
packet[10]=0x00; //normal mode for Q100/Q200, unknown for V2/MR100
if((sub_protocol==Q100 || sub_protocol==Q200) && CH13_SW)
{//Calibrate
packet[9]=0x77; //enter calibration
if(calib_counter>=20 && calib_counter<=25) // 7 packets for Q100 / 3 packets for Q200
packet[10]=0x20; //launch calibration
calib_counter++;
if(calib_counter>250) calib_counter=250;
}
else
calib_counter=0;
//->V1 stops here
if(sub_protocol==Q200)
packet[6] = GET_FLAG(CH9_SW , FLAG_Q200_FMODE)
|GET_FLAG(CH10_SW, FLAG_Q200_FLIP)
|GET_FLAG(CH11_SW, FLAG_Q200_VIDON)
|GET_FLAG(CH12_SW, FLAG_Q200_VIDOFF);
else if(sub_protocol==MR100 || sub_protocol==Q100)
packet[6] = GET_FLAG(CH9_SW , FLAG_MR100_FMODE)
|GET_FLAG(CH10_SW, FLAG_MR100_FLIP)
|GET_FLAG(CH11_SW, FLAG_MR100_VIDEO) // Does not exist on the Q100 but...
|GET_FLAG(CH12_SW, FLAG_MR100_PICTURE); // Does not exist on the Q100 but...
packet[7]=convert_channel_8b(CH7);
packet[8]=convert_channel_8b(CH8);
packet[9]=0xAA; //normal mode for Q100/Q200, unknown for V2/MR100
packet[10]=0x00; //normal mode for Q100/Q200, unknown for V2/MR100
if((sub_protocol==Q100 || sub_protocol==Q200) && CH13_SW)
{//Calibrate
packet[9]=0x77; //enter calibration
if(calib_counter>=20 && calib_counter<=25) // 7 packets for Q100 / 3 packets for Q200
packet[10]=0x20; //launch calibration
calib_counter++;
if(calib_counter>250) calib_counter=250;
}
else
calib_counter=0;
}
static void __attribute__((unused)) SLT_send_bind_packet()
@@ -186,6 +196,7 @@ static void __attribute__((unused)) SLT_send_bind_packet()
#define SLT_TIMING_BUILD 1000
#define SLT_V1_TIMING_PACKET 1000
#define SLT_V1_4_TIMING_PACKET 1643
#define SLT_V2_TIMING_PACKET 2042
#define SLT_V1_TIMING_BIND2 1000
#define SLT_V2_TIMING_BIND1 6507
@@ -195,8 +206,9 @@ uint16_t SLT_callback()
switch (phase)
{
case SLT_BUILD:
//debugln_time("b ");
#ifdef MULTI_SYNC
telemetry_set_input_sync(sub_protocol==SLT_V1?20000:13730);
telemetry_set_input_sync(packet_period);
#endif
SLT_build_packet();
NRF250K_SetPower(); //Change power level
@@ -206,42 +218,39 @@ uint16_t SLT_callback()
case SLT_DATA1:
case SLT_DATA2:
phase++;
SLT_send_packet(packet_length);
if(sub_protocol==SLT_V1)
{
SLT_send_packet(SLT_PAYLOADSIZE_V1);
return SLT_V1_TIMING_PACKET;
}
else //V2
if(sub_protocol==SLT_V1_4)
{
SLT_send_packet(SLT_PAYLOADSIZE_V2);
return SLT_V2_TIMING_PACKET;
phase++; //Packets are sent two times only
return SLT_V1_4_TIMING_PACKET;
}
//V2
return SLT_V2_TIMING_PACKET;
case SLT_DATA3:
if(sub_protocol==SLT_V1)
SLT_send_packet(SLT_PAYLOADSIZE_V1);
else //V2
SLT_send_packet(SLT_PAYLOADSIZE_V2);
SLT_send_packet(packet_length);
if (++packet_count >= 100)
{// Send bind packet
packet_count = 0;
if(sub_protocol==SLT_V1)
if(sub_protocol==SLT_V1||sub_protocol==SLT_V1_4)
{
phase=SLT_BIND2;
return SLT_V1_TIMING_BIND2;
}
else //V2
{
phase=SLT_BIND1;
return SLT_V2_TIMING_BIND1;
}
//V2
phase=SLT_BIND1;
return SLT_V2_TIMING_BIND1;
}
else
{// Continue to send normal packets
phase = SLT_BUILD;
if(sub_protocol==SLT_V1)
return 20000-SLT_TIMING_BUILD;
else //V2
return 13730-SLT_TIMING_BUILD;
if(sub_protocol==SLT_V1_4)
return 18000-SLT_TIMING_BUILD-SLT_V1_4_TIMING_PACKET;
//V2
return 13730-SLT_TIMING_BUILD;
}
case SLT_BIND1:
SLT_send_bind_packet();
@@ -252,8 +261,10 @@ uint16_t SLT_callback()
phase = SLT_BUILD;
if(sub_protocol==SLT_V1)
return 20000-SLT_TIMING_BUILD-SLT_V1_TIMING_BIND2;
else //V2
return 13730-SLT_TIMING_BUILD-SLT_V2_TIMING_BIND1-SLT_V2_TIMING_BIND2;
if(sub_protocol==SLT_V1_4)
return 18000-SLT_TIMING_BUILD-SLT_V1_TIMING_BIND2-SLT_V1_4_TIMING_PACKET;
//V2
return 13730-SLT_TIMING_BUILD-SLT_V2_TIMING_BIND1-SLT_V2_TIMING_BIND2;
}
return 19000;
}
@@ -276,6 +287,33 @@ void SLT_init()
SLT_RF_init();
SLT_set_freq();
phase = SLT_BUILD;
if(sub_protocol==SLT_V1)
{
packet_length = SLT_PAYLOADSIZE_V1;
#ifdef MULTI_SYNC
packet_period = 20000+2*SLT_V1_TIMING_PACKET; //22ms
#endif
}
else if(sub_protocol==SLT_V1_4)
{
packet_length = SLT_PAYLOADSIZE_V1_4;
#ifdef MULTI_SYNC
packet_period = 18000; //18ms
#endif
//Test IDs
MProtocol_id = MProtocol_id_master ^ (1<<RX_num);
set_rx_tx_addr(MProtocol_id);
debugln("Try ID: %lx", MProtocol_id);
}
else //V2
{
packet_length = SLT_PAYLOADSIZE_V2;
#ifdef MULTI_SYNC
packet_period = 13730+2*SLT_V2_TIMING_PACKET; //~18ms
#endif
}
}
#endif
//SLT v1_4ch timing
//268363 + 1643 / 15 = 18000

View File

@@ -19,58 +19,72 @@
#include "iface_cyrf6936.h"
//#define TRAXXAS_FORCE_ID
//#define TRAXXAS_DEBUG
#define TRAXXAS_TQ1_FORCE_ID
//#define TRAXXAS_TQ2_FORCE_ID
#define TRAXXAS_DEBUG
#define TRAXXAS_CHANNEL 0x05
#define TRAXXAS_BIND_CHANNEL 0x2B
#define TRAXXAS_PACKET_SIZE 16
#define TRAXXAS_BIND_CHANNEL 0x2B
#define TRAXXAS_CHECK_CHANNEL 0x22
#define TRAXXAS_PACKET_SIZE 16
#define TRAXXAS_TQ1_BIND_CHANNEL 0x04
#define TRAXXAS_TQ1_CHECK_CHANNEL 0x34
enum {
TRAXXAS_BIND_PREP_RX=0,
TRAXXAS_BIND_RX,
TRAXXAS_BIND_TX1,
TRAXXAS_PREP_RX,
TRAXXAS_RX,
TRAXXAS_PREP_DATA,
TRAXXAS_DATA,
TRAXXAS_TQ1_BIND,
TRAXXAS_TQ1_DATA1,
TRAXXAS_TQ1_DATA2,
};
const uint8_t PROGMEM TRAXXAS_sop_bind[] ={ 0x3C, 0x37, 0xCC, 0x91, 0xE2, 0xF8, 0xCC, 0x91 };
const uint8_t PROGMEM TRAXXAS_sop_data[] ={ 0xA1, 0x78, 0xDC, 0x3C, 0x9E, 0x82, 0xDC, 0x3C };
//const uint8_t PROGMEM TRAXXAS_sop_check[]={ 0x97, 0xE5, 0x14, 0x72, 0x7F, 0x1A, 0x14, 0x72 };
const uint8_t PROGMEM TRAXXAS_init_vals[][2] = {
//Init from dump
{CYRF_0B_PWR_CTRL, 0x00}, // PMU
{CYRF_32_AUTO_CAL_TIME, 0x3C}, // Default init value
{CYRF_35_AUTOCAL_OFFSET, 0x14}, // Default init value
{CYRF_1B_TX_OFFSET_LSB, 0x55}, // Default init value
{CYRF_1C_TX_OFFSET_MSB, 0x05}, // Default init value
{CYRF_28_CLK_EN, 0x02}, // Force Receive Clock Enable
{CYRF_03_TX_CFG, 0x08 | CYRF_BIND_POWER}, // 8DR Mode, 32 chip codes
{CYRF_0B_PWR_CTRL, 0x00}, // PMU
{CYRF_06_RX_CFG, 0x88 | 0x02}, // AGC enabled, Fast Turn Mode enabled, adding overwrite enable to not lockup RX
{CYRF_1E_RX_OVERRIDE, 0x08}, // Reject packets with 0 seed
{CYRF_03_TX_CFG, 0x08 | CYRF_BIND_POWER}, // 8DR Mode, 32 chip codes
};
static void __attribute__((unused)) TRAXXAS_cyrf_bind_config()
{
CYRF_PROGMEM_ConfigSOPCode(TRAXXAS_sop_bind);
CYRF_PROGMEM_ConfigSOPCode(DEVO_j6pro_sopcodes[0]);
CYRF_WriteRegister(CYRF_15_CRC_SEED_LSB, 0x5A);
CYRF_WriteRegister(CYRF_16_CRC_SEED_MSB, 0x5A);
CYRF_ConfigRFChannel(TRAXXAS_BIND_CHANNEL);
}
static void __attribute__((unused)) TRAXXAS_cyrf_check_config()
{
CYRF_ConfigRFChannel(TRAXXAS_CHECK_CHANNEL);
CYRF_PROGMEM_ConfigSOPCode(DEVO_j6pro_sopcodes[9]);
CYRF_WriteRegister(CYRF_15_CRC_SEED_LSB, 0xA5);
CYRF_WriteRegister(CYRF_16_CRC_SEED_MSB, 0xA5);
}
static void __attribute__((unused)) TRAXXAS_cyrf_data_config()
{
CYRF_PROGMEM_ConfigSOPCode(TRAXXAS_sop_data);
CYRF_ConfigRFChannel(hopping_frequency[0]);
#ifdef TRAXXAS_FORCE_ID // data taken from TX dump
CYRF_WriteRegister(CYRF_15_CRC_SEED_LSB, 0x1B);
CYRF_WriteRegister(CYRF_16_CRC_SEED_MSB, 0x3F);
CYRF_PROGMEM_ConfigSOPCode(DEVO_j6pro_sopcodes[6]);
#else
uint16_t addr=TRAXXAS_EEPROM_OFFSET+RX_num*2;
uint16_t addr=TRAXXAS_EEPROM_OFFSET+RX_num*3;
CYRF_WriteRegister(CYRF_15_CRC_SEED_LSB, cyrfmfg_id[0] - eeprom_read_byte((EE_ADDR)(addr + 0)));
CYRF_WriteRegister(CYRF_16_CRC_SEED_MSB, cyrfmfg_id[1] - eeprom_read_byte((EE_ADDR)(addr + 1)));
CYRF_PROGMEM_ConfigSOPCode(DEVO_j6pro_sopcodes[eeprom_read_byte((EE_ADDR)(addr + 2)) % 20]);
#endif
CYRF_ConfigRFChannel(TRAXXAS_CHANNEL);
CYRF_SetTxRxMode(TX_EN);
}
@@ -79,26 +93,59 @@ static void __attribute__((unused)) TRAXXAS_send_data_packet()
packet[0] = 0x01;
memset(&packet[1],0x00,TRAXXAS_PACKET_SIZE-1);
//Next RF channel ? 0x00 -> keep current, 0x0E change to F=15
//packet[1]
//Steering
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,false);
packet[4]=ch>>8;
packet[5]=ch;
//AUX3
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,false);
packet[12]=ch>>8;
packet[13]=ch;
//packet[1] = hopping_frequency[0] - 1;
//6 channels
uint16_t ch;
for(uint8_t i=0; i<6; i++)
{
ch = convert_channel_16b_nolimit(i,500,1000,false);
packet[2+i*2]=ch>>8;
packet[3+i*2]=ch;
}
CYRF_SetPower(0x08);
CYRF_WriteDataPacketLen(packet, TRAXXAS_PACKET_SIZE);
CYRF_WriteDataPacket(packet);
}
static void __attribute__((unused)) TRAXXAS_TQ1_send_data_packet()
{
memcpy(&packet[1], cyrfmfg_id, 4);
if(IS_BIND_IN_PROGRESS)
{
packet_length = 8;
packet[0] = 0x2A; // Bind packet
packet[5] = 0xA0; // Bind phase 0
packet[6] = TRAXXAS_TQ1_BIND_CHANNEL-1; // Not sure...
}
else
{
packet_length = 16;
packet[0] = 0x02; // Normal packet
packet[5] = 0xA2; // Bind phase 2 = completed?
//4 channels
uint16_t ch;
for(uint8_t i=0; i<4; i++)
{
ch = convert_channel_ppm(i);
packet[6+i*2]=ch;
packet[7+i*2]=ch>>8;
}
packet[14] = hopping_frequency[0]-1; // Not sure...
}
uint8_t xor_value=0;
for(uint8_t i=0; i<packet_length-1; i++)
xor_value ^= packet[i];
packet[packet_length-1] = xor_value;
CYRF_SetPower(0x08);
CYRF_WriteDataPacketLen(packet, packet_length);
#ifdef TRAXXAS_DEBUG
debug("P:");
for(uint8_t i=0; i<packet_length; i++)
debug(" %02X",packet[i]);
debugln("");
#endif
}
uint16_t TRAXXAS_callback()
@@ -107,20 +154,28 @@ uint16_t TRAXXAS_callback()
switch(phase)
{
//TQ2
case TRAXXAS_BIND_PREP_RX:
TRAXXAS_cyrf_bind_config();
case TRAXXAS_PREP_RX:
//debugln("PREP_RX");
if(phase == TRAXXAS_BIND_PREP_RX)
TRAXXAS_cyrf_bind_config();
else
TRAXXAS_cyrf_check_config();
CYRF_SetTxRxMode(RX_EN); //Receive mode
CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x83); //Prepare to receive
packet_count=100; //Timeout for RX
phase=TRAXXAS_BIND_RX;
return 700;
phase++; // TRAXXAS_BIND_RX or TRAXXAS_RX
return 7000;
case TRAXXAS_BIND_RX:
case TRAXXAS_RX:
//debugln("RX");
//Read data from RX
status = CYRF_ReadRegister(CYRF_07_RX_IRQ_STATUS);
if((status & 0x03) == 0x02) // RXC=1, RXE=0 then 2nd check is required (debouncing)
status |= CYRF_ReadRegister(CYRF_07_RX_IRQ_STATUS);
#ifdef TRAXXAS_DEBUG
debugln("s=%02X",status);
//debugln("s=%02X",status);
#endif
CYRF_WriteRegister(CYRF_07_RX_IRQ_STATUS, 0x80); // need to set RXOW before data read
if((status & 0x07) == 0x02)
@@ -138,34 +193,58 @@ uint16_t TRAXXAS_callback()
debug(" %02X",packet[i]);
debugln("");
#endif
// Store RX ID
uint16_t addr=TRAXXAS_EEPROM_OFFSET+RX_num*2;
for(uint8_t i=0;i<2;i++)
eeprom_write_byte((EE_ADDR)(addr+i),packet[i+1]);
uint16_t addr=TRAXXAS_EEPROM_OFFSET+RX_num*3;
if(phase == TRAXXAS_BIND_RX)
{
// Store RX ID
for(uint8_t i=0;i<2;i++)
eeprom_write_byte((EE_ADDR)(addr+i),packet[i+1]);
//Store SOP index
eeprom_write_byte((EE_ADDR)(addr+2),packet[7]);
}
else
{
//check RX ID and SOP
if(eeprom_read_byte((EE_ADDR)(addr + 0)) != packet[1] || eeprom_read_byte((EE_ADDR)(addr + 1)) != packet[2] || eeprom_read_byte((EE_ADDR)(addr + 2)) != packet[7])
{ // Not our RX
phase++; // TRAXXAS_PREP_DATA
return 10000-7000-500;
}
}
// Replace RX ID by TX ID
for(uint8_t i=0;i<6;i++)
packet[i+1]=cyrfmfg_id[i];
packet[7 ] = 0xEE; // Not needed ??
//packet[7 ] = 0xEE; // Not needed ??
packet[8 ] = hopping_frequency[0] - 1;
packet[10] = 0x01; // Must change otherwise bind doesn't complete
packet[13] = 0x05; // Not needed ??
//packet[13] = 0x05; // Not needed ??
packet_count=12;
CYRF_SetTxRxMode(TX_EN);
phase=TRAXXAS_BIND_TX1;
return 200;
return 10000;
}
}
if( --packet_count == 0 )
{ // Retry RX
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
if(--bind_counter != 0)
phase=TRAXXAS_BIND_PREP_RX; // Retry receiving bind packet
else
phase=TRAXXAS_PREP_DATA; // Abort binding
if(phase == TRAXXAS_BIND_RX)
{
if( --packet_count == 0 )
{ // Retry RX
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
if(--bind_counter != 0)
phase=TRAXXAS_BIND_PREP_RX; // Retry receiving bind packet
else
phase=TRAXXAS_PREP_DATA; // Abort binding
}
return 700;
}
return 700;
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++; // TRAXXAS_PREP_DATA
return 10000-7000-500;
case TRAXXAS_BIND_TX1:
//debugln("BIND_TX1");
CYRF_WriteDataPacketLen(packet, TRAXXAS_PACKET_SIZE);
#ifdef TRAXXAS_DEBUG
debug("P=");
@@ -177,89 +256,176 @@ uint16_t TRAXXAS_callback()
phase=TRAXXAS_PREP_DATA;
break;
case TRAXXAS_PREP_DATA:
//debugln("PREP_DATA");
BIND_DONE;
TRAXXAS_cyrf_data_config();
phase++;
return 500;
case TRAXXAS_DATA:
//debugln_time("DATA");
#ifdef MULTI_SYNC
telemetry_set_input_sync(13940);
telemetry_set_input_sync(10000);
#endif
TRAXXAS_send_data_packet();
break;
phase = TRAXXAS_PREP_RX;
return 1000;
//TQ1
case TRAXXAS_TQ1_BIND:
if(bind_counter)
{
CYRF_ConfigRFChannel(TRAXXAS_TQ1_BIND_CHANNEL);
TRAXXAS_TQ1_send_data_packet();
bind_counter--;
if(bind_counter == 0)
{
BIND_DONE;
phase++;
}
}
return 10000;
case TRAXXAS_TQ1_DATA1:
#ifdef MULTI_SYNC
telemetry_set_input_sync(19900);
#endif
CYRF_ConfigRFChannel(TRAXXAS_TQ1_CHECK_CHANNEL);
TRAXXAS_TQ1_send_data_packet();
phase++;
return 7100;
case TRAXXAS_TQ1_DATA2:
CYRF_ConfigRFChannel(hopping_frequency[0]);
TRAXXAS_TQ1_send_data_packet();
phase = TRAXXAS_TQ1_DATA1;
return 12800;
}
return 13940;
return 10000;
}
void TRAXXAS_init()
{
//Config CYRF registers
for(uint8_t i = 0; i < sizeof(TRAXXAS_init_vals) / 2; i++)
CYRF_WriteRegister(pgm_read_byte_near(&TRAXXAS_init_vals[i][0]), pgm_read_byte_near(&TRAXXAS_init_vals[i][1]));
uint8_t init;
if(sub_protocol == TRAXXAS_TQ1)
{
//CYRF_WriteRegister(CYRF_06_RX_CFG, 0x48 | 0x02);
//CYRF_WriteRegister(CYRF_26_XTAL_CFG, 0x08);
init = 5;
}
else //TQ2
{
init = sizeof(TRAXXAS_init_vals) / 2;
for(uint8_t i = 0; i < init; i++)
CYRF_WriteRegister(pgm_read_byte_near(&TRAXXAS_init_vals[i][0]), pgm_read_byte_near(&TRAXXAS_init_vals[i][1]));
}
//Read CYRF ID
CYRF_GetMfgData(cyrfmfg_id);
//cyrfmfg_id[0]+=RX_num; // Not needed since the TX and RX have to match
#ifdef TRAXXAS_FORCE_ID // data taken from TX dump
cyrfmfg_id[0]=0x65; // CYRF MFG ID
cyrfmfg_id[1]=0xE2;
cyrfmfg_id[2]=0x5E;
cyrfmfg_id[3]=0x55;
cyrfmfg_id[4]=0x4D;
cyrfmfg_id[5]=0xFE;
#endif
if(IS_BIND_IN_PROGRESS)
//Find a free channel
if(sub_protocol == TRAXXAS_TQ1)
{
bind_counter=100;
phase = TRAXXAS_BIND_PREP_RX;
cyrfmfg_id[3]+=RX_num; // Not needed for TQ2 since the TX and RX have to match
//CYRF_FindBestChannels(hopping_frequency,1,1,0x0B,0x30, FIND_CHANNEL_ANY); // Complete guess
}
else //TRAXXAS_TQ2
CYRF_FindBestChannels(hopping_frequency,1,1,0x02,0x21, FIND_CHANNEL_ANY);
#ifdef TRAXXAS_TQ1_FORCE_ID // data taken from TX dump
if(sub_protocol == TRAXXAS_TQ1)
{
cyrfmfg_id[0]=0xD8; // CYRF MFG ID
cyrfmfg_id[1]=0xAA;
cyrfmfg_id[2]=0x59;
cyrfmfg_id[3]=0xE6;
//cyrfmfg_id[4]=0x44; // Unused
//cyrfmfg_id[5]=0xFB; // Unused
hopping_frequency[0] = 0x0B;
}
#endif
#ifdef TRAXXAS_TQ2_FORCE_ID // data taken from TX dump
if(sub_protocol == TRAXXAS_TQ2)
{
cyrfmfg_id[0]=0x65; // CYRF MFG ID
cyrfmfg_id[1]=0xE2;
cyrfmfg_id[2]=0x5E;
cyrfmfg_id[3]=0x55;
cyrfmfg_id[4]=0x4D;
cyrfmfg_id[5]=0xFE;
hopping_frequency[0] = 0x05; // seen 05 and 0F
}
#endif
#ifdef TRAXXAS_DEBUG
debugln("ID: %02X %02X %02X %02X %02X %02X",cyrfmfg_id[0],cyrfmfg_id[1],cyrfmfg_id[2],cyrfmfg_id[3],cyrfmfg_id[4],cyrfmfg_id[5]);
debugln("RF CH: %02X",hopping_frequency[0]);
#endif
bind_counter=100;
if(sub_protocol == TRAXXAS_TQ1)
{
CYRF_WriteRegister(CYRF_28_CLK_EN, 0x02);
CYRF_WriteRegister(CYRF_32_AUTO_CAL_TIME, 0x3C);
CYRF_WriteRegister(CYRF_35_AUTOCAL_OFFSET, 0x14);
CYRF_WriteRegister(CYRF_26_XTAL_CFG, 0x08);
CYRF_WriteRegister(CYRF_06_RX_CFG, 0x48);
CYRF_WriteRegister(CYRF_1B_TX_OFFSET_LSB, 0x55);
CYRF_WriteRegister(CYRF_1C_TX_OFFSET_MSB, 0x05);
CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x21);
CYRF_WriteRegister(CYRF_03_TX_CFG, 0x0C);
CYRF_PROGMEM_ConfigSOPCode(DEVO_j6pro_sopcodes[0]);
CYRF_SetTxRxMode(TX_EN);
CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x21);
if(IS_BIND_IN_PROGRESS)
phase = TRAXXAS_TQ1_BIND;
else
phase = TRAXXAS_TQ1_DATA1;
}
else
phase = TRAXXAS_PREP_DATA;
{//TRAXXAS_TQ2
if(IS_BIND_IN_PROGRESS)
phase = TRAXXAS_BIND_PREP_RX;
else
phase = TRAXXAS_PREP_DATA;
}
//
// phase = TRAXXAS_BIND_TX1;
// TRAXXAS_cyrf_bind_config();
// CYRF_SetTxRxMode(TX_EN);
// memcpy(packet,(uint8_t *)"\x02\x4A\xA3\x2D\x1A\x49\xFE\x06\x00\x00\x02\x01\x06\x06\x00\x00",TRAXXAS_PACKET_SIZE);
// memcpy(packet,(uint8_t *)"\x02\xFF\xFF\xFF\xFF\xFF\xFF\x01\x01\x01\x02\x01\x06\x00\x00\x00",TRAXXAS_PACKET_SIZE);
// memcpy(packet,(uint8_t *)"\x02\x49\xAC\x4F\x55\x4D\xFE\x05\x00\x00\x02\x01\x06\x06\x00\x00",TRAXXAS_PACKET_SIZE);
}
/*
Bind phase 1
Traxxas TQ 2nd generation
-------------------------
Packets 0x02: Bind learn TX/RX addresses
CHANNEL: 0x2B
SOP_CODE: 0x3C 0x37 0xCC 0x91 0xE2 0xF8 0xCC 0x91
CRC_SEED_LSB: 0x5A
CRC_SEED_MSB: 0x5A
RX1: 0x02 0x4A 0xA3 0x2D 0x1A 0x49 0xFE 0x06 0x00 0x00 0x02 0x01 0x06 0x06 0x00 0x00
TX1: 0x02 0x65 0xE2 0x5E 0x55 0x4D 0xFE 0xEE 0x00 0x00 0x01 0x01 0x06 0x05 0x00 0x00
RX: 0x02 0x4A 0xA3 0x2D 0x1A 0x49 0xFE 0x06 0x00 0x00 0x02 0x01 0x06 0x06 0x00 0x00
TX: 0x02 0x65 0xE2 0x5E 0x55 0x4D 0xFE 0xEE 0x00 0x00 0x01 0x01 0x06 0x05 0x00 0x00
Notes:
- RX cyrfmfg_id is 0x4A,0xA3,0x2D,0x1A,0x49,0xFE and TX cyrfmfg_id is 0x65,0xE2,0x5E,0x55,0x4D,0xFE
- P[7] changes from 0x06 to 0xEE but not needed to complete the bind -> doesn't care??
- P[8..9]=0x00 unchanged??
- P[8] RF channel - 1 (on packets type 0x03)
- P[9] 0x00 unchanged??
- P[10] needs to be set to 0x01 to complete the bind -> normal packet P[0]??
- P[11] unchanged ?? -> no bind if set to 0x00 or 0x81
- P[12] unchanged ?? -> no bind if set to 0x05 or 0x86
- P[13] changes from 0x06 to 0x05 but not needed to complete the bind -> doesn't care??
- P[14..15]=0x00 unchanged??
Bind phase 2 (looks like normal mode?)
CHANNEL: 0x05
SOP_CODE: 0xA1 0x78 0xDC 0x3C 0x9E 0x82 0xDC 0x3C
CRC_SEED_LSB: 0x1B
CRC_SEED_MSB: 0x3F
RX2: 0x03 0x4A 0xA3 0x2D 0x1A 0x49 0xFE 0x06 0x00 0x00 0x02 0x01 0x06 0x06 0x00 0x00
TX2: 0x01 0x65 0x01 0xF4 0x03 0xE7 0x02 0x08 0x00 0x00 0x01 0x01 0x02 0xEE 0x00 0x00
Note: TX2 is nearly a normal packet at the exception of the 2nd byte equal to cyrfmfg_id[0]
Bind phase 3 (check?)
Packets 0x03: Which RF channel
CHANNEL: 0x22
SOP_CODE: 0x97 0xE5 0x14 0x72 0x7F 0x1A 0x14 0x72
CRC_SEED_LSB: 0xA5
CRC_SEED_MSB: 0xA5
RX3: 0x04 0x4A 0xA3 0x2D 0x1A 0x49 0xFE 0x06 0x00 0x00 0x02 0x01 0x06 0x06 0x00 0x00
RX: 0x03 0x4A 0xA3 0x2D 0x1A 0x49 0xFE 0x06 0x00 0x00 0x02 0x01 0x06 0x06 0x00 0x00
TX: 0x03 0x65 0xE2 0x5E 0x55 0x4D 0xFE 0xEE 0x0E 0x00 0x01 0x01 0x06 0x05 0x00 0x00
- P[8] RF channel - 1
Switch to normal mode
Packets 0x04: unknown
RX: 0x04 0x4A 0xA3 0x2D 0x1A 0x49 0xFE 0x06 0x00 0x00 0x02 0x01 0x06 0x06 0x00 0x00
Packets 0x01: Normal mode
CHANNEL: 0x05
SOP_CODE: 0xA1 0x78 0xDC 0x3C 0x9E 0x82 0xDC 0x3C
CRC_SEED_LSB: 0x1B
@@ -273,5 +439,39 @@ RX ID: \x4B\xA3\x2D\x1A\x49\xFE CRC 0x1A 0x3F => CRC: 65-4B=1A E2-A3=3F
RX ID: \x00\x00\x2D\x1A\x49\xFE CRC 0x65 0xE2 => CRC: 65-00=65 E2-00=E2
RX ID: \x00\xFF\x2D\x1A\x49\xFE CRC 0x65 0xE3 => CRC: 65-00=65 E2-FF=E3
RX ID: \xFF\x00\x2D\x1A\x49\xFE CRC 0x66 0xE2 => CRC: 65-FF=66 E2-00=E2
SOP Codes:
RX1: 02 4A A3 2D 1A 49 FE 06 00 00 02 01 06 06 00 00
SOP: A1 78 DC 3C 9E 82 DC 3C
RX2: 02 49 AC 4F 55 4D FE 05 00 00 02 01 06 06 00 00
SOP: 5A CC AE 46 B6 31 AE 46
RX3: 02 CA F3 62 55 4D FE 03 00 00 02 01 06 06 00 00
SOP: 66 CD 7C 50 DD 26 7C 50
Dump of SOP Codes:
00: 3C 37 CC 91 E2 F8 CC 91 => bind
01: 9B C5 A1 0F AD 39 A2 0F
02: EF 64 B0 2A D2 8F B1 2A
03: 66 CD 7C 50 DD 26 7C 50
04: 5C E1 F6 44 AD 16 F6 44
05: 5A CC AE 46 B6 31 AE 46
06: A1 78 DC 3C 9E 82 DC 3C
07: B9 8E 19 74 6F 65 18 74
08: DF B1 C0 49 62 DF C1 49
09: 97 E5 14 72 7F 1A 14 72 => check
10: 82 C7 90 36 21 03 FF 17
11: E2 F8 CC 91 3C 37 CC 91 => bind 4 bytes group swapped
12: AD 39 A2 0F 9B C5 A1 0F => 01 4 bytes group swapped
13: D2 8F B1 2A EF 64 B0 2A => 02 4 bytes group swapped
14: DD 26 7C 50 66 CD 7C 50 => 03 4 bytes group swapped
...
19: 62 DF C1 49 DF B1 C0 49 => 08 4 bytes group swapped
20: 00 00 00 33 DE AD BA BE ??over??
*/
/*
Traxxas TQ 1st generation
-------------------------
https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/issues/967#issuecomment-2079038576
*/
#endif

View File

@@ -1,163 +0,0 @@
/*
This project is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Multiprotocol is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
*/
// Compatible with Tiger Drone 1400782.
#if defined(TIGER_NRF24L01_INO)
#include "iface_xn297.h"
#define TIGER_FORCE_ID
#define TIGER_INITIAL_WAIT 500
#define TIGER_PACKET_PERIOD 3940
#define TIGER_RF_NUM_CHANNELS 4
#define TIGER_BIND_RF_NUM_CHANNELS 8
#define TIGER_PAYLOAD_SIZE 16
#define TIGER_BIND_COUNT 761 //3sec
static uint8_t __attribute__((unused)) TIGER_convert_channel(uint8_t num)
{
uint8_t val=convert_channel_8b(num);
// 7F..01=left, 00=center, 80..FF=right
if(val==0x80)
val=0; // 0
else
if(val>0x80)
val--; // 80..FE
else
{
val=0x80-val; // 80..01
if(val==0x80)
val--; // 7F..01
}
return val;
}
static void __attribute__((unused)) TIGER_send_packet()
{
if(IS_BIND_DONE)
{
//Channels
packet[0]=convert_channel_8b(THROTTLE); // 00..FF
packet[1]=TIGER_convert_channel(RUDDER); // 7F..01=left, 00=center, 80..FF=right
packet[2]=TIGER_convert_channel(ELEVATOR); // 7F..01=down, 00=center, 80..FF=up
packet[3]=TIGER_convert_channel(AILERON); // 7F..01=left, 00=center, 80..FF=right
//Flags
packet[14]= GET_FLAG(CH5_SW, 0x04) //FLIP
| GET_FLAG(CH6_SW, 0x10); //LIGHT
}
//Check
crc8=0;
for(uint8_t i=0;i<TIGER_PAYLOAD_SIZE-1;i++)
crc8+=packet[i];
packet[TIGER_PAYLOAD_SIZE-1]=crc8;
//Hopping frequency
XN297_Hopping(hopping_frequency_no>>1);
hopping_frequency_no++;
if(IS_BIND_IN_PROGRESS)
{
if(hopping_frequency_no>=2*TIGER_BIND_RF_NUM_CHANNELS)
hopping_frequency_no=0;
}
else
{
if(hopping_frequency_no>=2*(TIGER_BIND_RF_NUM_CHANNELS+TIGER_RF_NUM_CHANNELS))
hopping_frequency_no=2*TIGER_BIND_RF_NUM_CHANNELS;
}
//Send
XN297_SetPower();
XN297_SetTxRxMode(TX_EN);
XN297_WritePayload(packet, TIGER_PAYLOAD_SIZE);
}
static void __attribute__((unused)) TIGER_RF_init()
{
XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, XN297_1M);
XN297_SetTXAddr((uint8_t *)"\x68\x94\xA6\xD5\xC3", 5);
}
static void __attribute__((unused)) TIGER_initialize_txid()
{
#ifdef TIGER_FORCE_ID
rx_tx_addr[0]=0x64;
rx_tx_addr[1]=0x39;
rx_tx_addr[2]=0x12;
rx_tx_addr[3]=0x00;
rx_tx_addr[4]=0x00;
memcpy(hopping_frequency,"\x0E\x39\x1C\x07\x24\x3E\x2B\x47",TIGER_BIND_RF_NUM_CHANNELS);
memcpy(&hopping_frequency[TIGER_BIND_RF_NUM_CHANNELS],"\x36\x41\x37\x4E",TIGER_RF_NUM_CHANNELS);
#endif
//prepare bind packet
memset(&packet[0], 0x00, 4);
memset(&packet[4], 0x40, 10);
memcpy(&packet[7], rx_tx_addr, 5);
packet[14]=0xC0;
}
uint16_t TIGER_callback()
{
#ifdef MULTI_SYNC
telemetry_set_input_sync(TIGER_PACKET_PERIOD);
#endif
if(bind_counter)
if(--bind_counter==0)
{
BIND_DONE;
XN297_SetTXAddr((uint8_t *)"\x49\xA6\x83\xEB\x4B", 5);
}
TIGER_send_packet();
return TIGER_PACKET_PERIOD;
}
void TIGER_init()
{
BIND_IN_PROGRESS; // autobind protocol
TIGER_initialize_txid();
TIGER_RF_init();
hopping_frequency_no = 0;
bind_counter=TIGER_BIND_COUNT;
}
#endif
/*Bind
- RF setup: 1Mbps, scrambled, CRC
- TX addr: 0x68 0x94 0xA6 0xD5 0xC3
- 8 RF channels: 0x0E 0x39 0x1C 0x07 0x24 0x3E 0x2B 0x47
- 2 packets per RF channel, 3940µs between packets
- payload 16 bytes: 0x00 0x00 0x00 0x00 0x40 0x40 0x40 0x64 0x39 0x12 0x00 0x00 0x40 0x40 0xC0 0xAF
- payload[15]=sum of payload[0..14]
- the only difference with normal packets is the payload[14]=0xC0
- ??? payload[7..11] TX ID ???
Normal
- RF setup: 1Mbps
- TX addr: 0x49 0xA6 0x83 0xEB 0x4B
- 4 RF channels: 0x36 0x41 0x37 0x4E
- 2 packets per RF channel, 3940µs between packets
- payload 16 bytes: 0x00 0x00 0x00 0x00 0x40 0x40 0x40 0x64 0x39 0x12 0x00 0x00 0x40 0x40 0x00 0xEF
- payload[15]=sum of payload[0..14]
- throttle is on payload[0] 00..FF
- rudder is on payload[1] 00=center, 80..FF=right, 01..7F=left
- elevator is on payload[2] 00=center, 80..FF=up, 01..7F=down
- aileron is on payload[3] 00=center, 80..FF=right, 01..7F=left
- trims payload[4..6]
- ??? payload[7..11] TX ID ???
- ??? payload[12..13] ???
- flip is on payload[14] and flag 0x04
- light is on payload[14] and flag 0x10
*/

View File

@@ -266,6 +266,7 @@
#undef E01X_CYRF6936_INO
#undef E129_CYRF6936_INO
#undef J6PRO_CYRF6936_INO
#undef KYOSHO3_CYRF6936_INO
#undef LOSI_CYRF6936_INO
#undef MLINK_CYRF6936_INO
#undef TRAXXAS_CYRF6936_INO
@@ -312,6 +313,7 @@
#undef CX10_NRF24L01_INO
#undef DM002_NRF24L01_INO
#undef E016H_NRF24L01_INO
#undef EAZYRC_NRF24L01_INO
#undef ESKY_NRF24L01_INO
#undef ESKY150_NRF24L01_INO
#undef FQ777_NRF24L01_INO
@@ -330,9 +332,9 @@
#undef POTENSIC_NRF24L01_INO
#undef PROPEL_NRF24L01_INO
#undef REALACC_NRF24L01_INO
#undef SGF22_NRF24L01_INO
#undef SHENQI_NRF24L01_INO
#undef SYMAX_NRF24L01_INO
#undef TIGER_NRF24L01_INO
#undef V2X2_NRF24L01_INO
#undef V761_NRF24L01_INO
#undef XERALL_NRF24L01_INO
@@ -368,6 +370,73 @@
#undef FRSKYR9_SX1276_INO
#endif
#ifdef MULTI_AIR
#undef JOYSWAY_A7105_INO
//#undef KYOSHO_A7105_INO
//#undef PELIKAN_A7105_INO
#undef LOSI_CYRF6936_INO //Need DSM to be enabled
#undef TRAXXAS_CYRF6936_INO
#undef EAZYRC_NRF24L01_INO
#undef KYOSHO2_NRF24L01_INO
#undef KYOSHO3_CYRF6936_INO
#undef MOULDKG_NRF24L01_INO
#undef SHENQI_NRF24L01_INO
#endif
#ifdef MULTI_SURFACE
#undef BUGS_A7105_INO
#undef HEIGHT_A7105_INO
#undef HUBSAN_A7105_INO
#undef E010R5_CYRF6936_INO
#undef E01X_CYRF6936_INO
#undef E129_CYRF6936_INO
#undef J6PRO_CYRF6936_INO
#undef SCORPIO_CYRF6936_INO
#undef E016HV2_CC2500_INO
#undef ESKY150V2_CC2500_INO
#undef IKEAANSLUTA_CC2500_INO // This is mostly a "for-fun" kind of a thing, not needed for most users
#undef SKYARTEC_CC2500_INO
#undef REDPINE_CC2500_INO
#undef BAYANG_NRF24L01_INO
#undef BAYANG_RX_NRF24L01_INO
#undef BUGSMINI_NRF24L01_INO
#undef CABELL_NRF24L01_INO
#undef CFLIE_NRF24L01_INO
#undef CG023_NRF24L01_INO
#undef CX10_NRF24L01_INO
#undef DM002_NRF24L01_INO
#undef E016H_NRF24L01_INO
#undef ESKY_NRF24L01_INO
#undef ESKY150_NRF24L01_INO
#undef FQ777_NRF24L01_INO
#undef FX_NRF24L01_INO
#undef FY326_NRF24L01_INO
#undef GW008_NRF24L01_INO
#undef HONTAI_NRF24L01_INO
#undef H8_3D_NRF24L01_INO
#undef JJRC345_NRF24L01_INO
#undef KN_NRF24L01_INO
#undef LOLI_NRF24L01_INO
#undef NCC1701_NRF24L01_INO
#undef POTENSIC_NRF24L01_INO
#undef PROPEL_NRF24L01_INO
#undef REALACC_NRF24L01_INO
#undef SGF22_NRF24L01_INO
#undef SYMAX_NRF24L01_INO
#undef V761_NRF24L01_INO
#undef XERALL_NRF24L01_INO
#undef YD717_NRF24L01_INO
#undef ZSX_NRF24L01_INO
#undef GD00X_CCNRF_INO
#undef KF606_CCNRF_INO
#undef MJXQ_CCNRF_INO
#undef MT99XX_CCNRF_INO
#undef OMP_CCNRF_INO
#undef Q303_CCNRF_INO
#undef Q90C_CCNRF_INO
#undef V911S_CCNRF_INO
#endif
//OpenTX 2.3.x issue
#if defined (FRSKYD_CC2500_INO) || defined(FRSKYV_CC2500_INO) || defined(FRSKYX_CC2500_INO)
#define FRSKYX_CC2500_INO

View File

@@ -487,7 +487,7 @@ void WK_init()
CYRF_SetTxRxMode(TX_EN);
hopping_frequency_no=0;
CYRF_FindBestChannels(hopping_frequency, 3, 4, 4, 80);
CYRF_FindBestChannels(hopping_frequency, 3, 4, 4, 80, FIND_CHANNEL_ANY);
CYRF_ConfigRFChannel(hopping_frequency[0]);
packet_count = 0;

View File

@@ -29,11 +29,18 @@ Multiprotocol is distributed in the hope that it will be useful,
static uint16_t __attribute__((unused)) XK_convert_channel(uint8_t num)
{
// Introduce deadband on all channels to prevent twitching
//debug("val:%d",val);
uint16_t val=convert_channel_8b_limit_deadband(num,0x00,0x80, 0xFF, 40)<<2;
//debugln(",%d",val);
uint16_t val;
if(sub_protocol != XK_CARS)
{
// Introduce deadband on all channels to prevent twitching
//debug("val:%d",val);
val=convert_channel_8b_limit_deadband(num,0x00,0x80, 0xFF, 40)<<2;
//debugln(",%d",val);
}
else
val=convert_channel_16b_limit(num,0x00,0x3FF);
// 1FF..01=left, 00=center, 200..3FF=right
if(val==0x200)
val=0; // 0
@@ -89,12 +96,14 @@ static void __attribute__((unused)) XK_send_packet()
packet[10] = 0x04; // 6G-Mode
//0x00 default M-Mode
packet[10] |= GET_FLAG(CH7_SW,0x80); // Emergency stop momentary switch
packet[10] |= GET_FLAG(CH7_SW ,0x80); // Emergency stop momentary switch
packet[11] = GET_FLAG(CH8_SW,0x03) // 3D/6G momentary switch
|GET_FLAG(CH6_SW,0x40); // Take off momentary switch
packet[14] = GET_FLAG(CH9_SW,0x01) // Photo momentary switch
|GET_FLAG(CH10_SW,0x2); // Video momentary switch
packet[11] = GET_FLAG(CH8_SW ,0x03) // 3D/6G momentary switch
|GET_FLAG(CH6_SW ,0x40); // Take off momentary switch
packet[14] = GET_FLAG(CH9_SW ,0x01) // Photo momentary switch
|GET_FLAG(CH10_SW,0x02) // Video momentary switch
|GET_FLAG(CH11_SW,0x04) // Flip
|GET_FLAG(CH12_SW,0x10); // Light
//debugln("P1:%02X,P12:%02X",packet[1],packet[12]);
}
@@ -187,7 +196,7 @@ static void __attribute__((unused)) XK_initialize_txid()
static void __attribute__((unused)) XK_RF_init()
{
XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, sub_protocol==X420 ? XN297_1M : XN297_250K);
XN297_Configure(XN297_CRCEN, XN297_SCRAMBLED, sub_protocol==X450 ? XN297_250K : XN297_1M );
XN297_SetTXAddr((uint8_t*)"\x68\x94\xA6\xD5\xC3", 5); // Bind address
XN297_HoppingCalib(XK_RF_BIND_NUM_CHANNELS+XK_RF_NUM_CHANNELS); // Calibrate all channels
}
@@ -209,7 +218,8 @@ uint16_t XK_callback()
void XK_init()
{
BIND_IN_PROGRESS; // Autobind protocol
if(sub_protocol != XK_CARS)
BIND_IN_PROGRESS; // Autobind protocol
XK_initialize_txid();
XK_RF_init();
hopping_frequency_no = 0;

View File

@@ -37,6 +37,7 @@ boolean enhanced;
boolean ack;
uint8_t pid;
uint8_t bitrate;
uint8_t old_option;
static void __attribute__((unused)) XN297Dump_RF_init()
{
@@ -609,12 +610,11 @@ static uint16_t XN297Dump_callback()
{
if(phase==0)
{
address_length=3;
memcpy(rx_tx_addr, (uint8_t *)"\xBD\x54\x78", address_length); //"\x62\xE6\xBD\x54\x78"
bitrate=XN297DUMP_1M;
address_length=4;
memcpy(rx_tx_addr, (uint8_t *)"\xF4\x71\x8D\x01", address_length); // bind \x7E\xB8\x63\xA9
bitrate=XN297DUMP_250K;
packet_length=7;
hopping_frequency_no=40; //bind ?, normal 40
hopping_frequency_no=0x50; //bind 0x50, normal ??
NRF24L01_Initialize();
NRF24L01_SetTxRxMode(TXRX_OFF);
@@ -623,8 +623,9 @@ static uint16_t XN297Dump_callback()
NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, rx_tx_addr, address_length); // set up RX address
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, packet_length); // Enable rx pipe 0
NRF24L01_WriteReg(NRF24L01_05_RF_CH, option); //hopping_frequency_no);
debug("NRF dump, len=%d, rf=%d, address length=%d, bitrate=",packet_length,hopping_frequency_no,address_length);
old_option = option;
debug("NRF dump, len=%d, rf=%d, address length=%d, bitrate=",packet_length,option,address_length); //hopping_frequency_no,address_length);
switch(bitrate)
{
case XN297DUMP_250K:
@@ -643,6 +644,7 @@ static uint16_t XN297Dump_callback()
}
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++;
time=0;
}
else
{
@@ -650,13 +652,23 @@ static uint16_t XN297Dump_callback()
{ // RX fifo data ready
if(NRF24L01_ReadReg(NRF24L01_09_CD))
{
XN297Dump_overflow();
uint16_t timeL=TCNT1;
if(TIMER2_BASE->SR & TIMER_SR_UIF)
{//timer just rolled over...
XN297Dump_overflow();
timeL=0;
}
time=(timeH<<16)+timeL-time;
debug("RX: %5luus ", time>>1);
time=(timeH<<16)+timeL;
NRF24L01_ReadPayload(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:");
debug("C: %02X P:", option);
for(uint8_t i=0;i<packet_length;i++)
debug(" %02X",packet[i]);
debugln("");
@@ -718,7 +730,12 @@ static uint16_t XN297Dump_callback()
NRF24L01_FlushRx();
NRF24L01_WriteReg(NRF24L01_00_CONFIG, _BV(NRF24L01_00_PWR_UP) | _BV(NRF24L01_00_PRIM_RX)); // _BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) |
}
NRF24L01_WriteReg(NRF24L01_05_RF_CH, option); //hopping_frequency_no);
XN297Dump_overflow();
if(old_option != option)
{
NRF24L01_WriteReg(NRF24L01_05_RF_CH, option); //hopping_frequency_no);
old_option = option;
}
}
}
else if(sub_protocol == XN297DUMP_CC2500)

View File

@@ -165,9 +165,14 @@
/*** PROTOCOLS TO INCLUDE ***/
/****************************/
//In this section select the protocols you want to be accessible when using the module.
//All the protocols will not fit in the Atmega328p module so you need to pick and choose.
//All the protocols will not fit in the STM32 or Atmega328p modules so you need to pick and choose.
//Comment the protocols you are not using with "//" to save Flash space.
//Already defined protocols selection
//#define MULTI_AIR //Only Air protocols will be available, all the others are disabled
//#define MULTI_SURFACE //Only Surface protocols will be available, all the others are disabled
//#define MULTI_EU //Only LBT/EU protocols will be available, all the others are disabled
//Protocol for module configuration
#define MULTI_CONFIG_INO
@@ -188,9 +193,10 @@
#define DSM_CYRF6936_INO
#define DSM_RX_CYRF6936_INO
#define E010R5_CYRF6936_INO
//#define E01X_CYRF6936_INO
#define E01X_CYRF6936_INO
#define E129_CYRF6936_INO
#define J6PRO_CYRF6936_INO
#define KYOSHO3_CYRF6936_INO
#define LOSI_CYRF6936_INO //Need DSM to be enabled
#define MLINK_CYRF6936_INO
#define SCORPIO_CYRF6936_INO
@@ -222,11 +228,12 @@
#define BAYANG_RX_NRF24L01_INO
#define BUGSMINI_NRF24L01_INO
#define CABELL_NRF24L01_INO
//#define CFLIE_NRF24L01_INO
#define CFLIE_NRF24L01_INO
#define CG023_NRF24L01_INO
#define CX10_NRF24L01_INO //Include Q2X2 protocol
#define DM002_NRF24L01_INO
#define E016H_NRF24L01_INO
#define EAZYRC_NRF24L01_INO
#define ESKY_NRF24L01_INO
#define ESKY150_NRF24L01_INO
#define FQ777_NRF24L01_INO
@@ -240,14 +247,14 @@
#define KN_NRF24L01_INO
#define KYOSHO2_NRF24L01_INO
#define LOLI_NRF24L01_INO
//#define MOULDKG_NRF24L01_INO
#define MOULDKG_NRF24L01_INO
#define NCC1701_NRF24L01_INO
#define POTENSIC_NRF24L01_INO
#define PROPEL_NRF24L01_INO
#define REALACC_NRF24L01_INO
#define SGF22_NRF24L01_INO
#define SHENQI_NRF24L01_INO
#define SYMAX_NRF24L01_INO
#define TIGER_NRF24L01_INO
#define V2X2_NRF24L01_INO
#define V761_NRF24L01_INO
#define XERALL_NRF24L01_INO
@@ -255,7 +262,6 @@
#define ZSX_NRF24L01_INO
//The protocols below need either a CC2500 or NRF24L01 to be installed
#define BLUEFLY_CCNRF_INO
#define GD00X_CCNRF_INO
#define KF606_CCNRF_INO
#define MJXQ_CCNRF_INO
@@ -606,6 +612,7 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
DSMX_1F
DSMX_2F
DSMR
DSM2_SFC
PROTO_DSM_RX
DSM_RX
DSM_CLONE
@@ -622,6 +629,8 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
PROTO_E129
E129_E129
E129_C186
PROTO_EAZYRC
NONE
PROTO_ESKY
ESKY_STD
ESKY_ET4
@@ -680,6 +689,7 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
FX816
FX620
FX9630
Q560
PROTO_FY326
FY326
FY319
@@ -736,6 +746,8 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
KYOSHO_HYPE
PROTO_KYOSHO2
NONE
PROTO_KYOSHO3
NONE
PROTO_LOLI
NONE
PROTO_LOSI
@@ -796,10 +808,13 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
RLINK_SURFACE
RLINK_AIR
RLINK_DUMBORC
RLINK_RC4G
PROTO_SCANNER
NONE
PROTO_SCORPIO
NONE
PROTO_SGF22
NONE
PROTO_SHENQI
NONE
PROTO_SKYARTEC
@@ -813,10 +828,8 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
PROTO_SYMAX
SYMAX
SYMAX5C
PROTO_TIGER
NONE
PROTO_TRAXXAS
RX6519
NONE
PROTO_V2X2
V2X2
JXD506
@@ -843,6 +856,7 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
PROTO_XK
X450
X420
XK_CARS
PROTO_YD717
YD717
SKYWLKR

View File

@@ -71,7 +71,11 @@ enum CYRF_PWR {
CYRF_PWR_DEFAULT,
};
enum FIND_CHANNEL {
FIND_CHANNEL_ANY = 0,
FIND_CHANNEL_EVEN = 1,
FIND_CHANNEL_ODD = 2,
};
/* SPI CYRF6936 */
/*

View File

@@ -75,13 +75,14 @@ CFlie|38|CFlie||||||||NRF24L01|
[CX10](Protocols_Details.md#CX10---12)|12|GREEN|BLUE|DM007|-|J3015_1|J3015_2|MK33041||NRF24L01|XN297
[Devo](Protocols_Details.md#DEVO---7)|7|Devo|8CH|10CH|12CH|6CH|7CH|||CYRF6936|
[DM002](Protocols_Details.md#DM002---33)|33|||||||||NRF24L01|XN297
[DSM](Protocols_Details.md#DSM---6)|6|DSM2_1F|DSM2_2F|DSMX_1F|DSMX_2F|AUTO|DSMR_1F|||CYRF6936|
[DSM](Protocols_Details.md#DSM---6)|6|DSM2_1F|DSM2_2F|DSMX_1F|DSMX_2F|AUTO|DSMR_1F|DSM2SFC||CYRF6936|
[DSM_RX](Protocols_Details.md#DSM_RX---70)|70|Multi|CPPM|||||||CYRF6936|
[E010R5](Protocols_Details.md#E010R5---81)|81|||||||||CYRF6936|RF2500
[E016H](Protocols_Details.md#E016H---85)|85|||||||||NRF24L01|XN297
[E016HV2](Protocols_Details.md#E016HV2---80)|80|||||||||CC2500/NRF24L01|unknown
[E01X](Protocols_Details.md#E01X---45)|45|E012|E015|||||||CYRF6936|HS6200
[E129](Protocols_Details.md#E129---83)|83|E129|C186|||||||CYRF6936|RF2500
[EazyRC](Protocols_Details.md#EazyRC---61)|61|||||||||NRF24L01|XN297L
[ESky](Protocols_Details.md#ESKY---16)|16|ESky|ET4|||||||NRF24L01|
[ESky150](Protocols_Details.md#ESKY150---35)|35|||||||||NRF24L01|
[ESky150V2](Protocols_Details.md#ESKY150V2---69)|69|||||||||CC2500|NRF51822
@@ -115,6 +116,7 @@ CFlie|38|CFlie||||||||NRF24L01|
[KN](Protocols_Details.md#KN---9)|9|WLTOYS|FEILUN|||||||NRF24L01|
[Kyosho](Protocols_Details.md#Kyosho---73)|73|FHSS|Hype|||||||A7105|
[Kyosho2](Protocols_Details.md#Kyosho2---93)|93|KT-17||||||||NRF24L01|
[Kyosho3](Protocols_Details.md#Kyosho3---98)|98|ASF||||||||CYRF6936|
[LOLI](Protocols_Details.md#LOLI---82)|82|||||||||NRF24L01|
[Losi](Protocols_Details.md#Losi---89)|89|||||||||CYRF6936|
[MJXq](Protocols_Details.md#MJXQ---18)|18|WLH08|X600|X800|H26D|E010*|H26WH|PHOENIX*||NRF24L01|XN297
@@ -131,17 +133,17 @@ 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|DumboRC||||||CC2500|
[RadioLink](Protocols_Details.md#RadioLink---74)|74|Surface|Air|DumboRC|RC4G|||||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|
[Scorpio](Protocols_Details.md#Scorpio---94)|94|||||||||CYRF6936|
[SGF22](Protocols_Details.md#SGF22---97)|97|SGF22||||||||NRF24L01|XN297
[Shenqi](Protocols_Details.md#Shenqi---19)|19|Shenqi||||||||NRF24L01|LT8900
[Skyartec](Protocols_Details.md#Skyartec---68)|68|||||||||CC2500|CC2500
[SLT](Protocols_Details.md#SLT---11)|11|SLT_V1|SLT_V2|Q100|Q200|MR100||||NRF24L01|CC2500
[SLT](Protocols_Details.md#SLT---11)|11|SLT_V1|SLT_V2|Q100|Q200|MR100|V1_4CH|||NRF24L01|CC2500
[SymaX](Protocols_Details.md#Symax---10)|10|SYMAX|SYMAX5C|||||||NRF24L01|
[Tiger](Protocols_Details.md#Tiger---61)|61|||||||||NRF24L01|XN297
[Traxxas](Protocols_Details.md#Traxxas---43)|43|6519 RX||||||||CYRF6936|
[Traxxas](Protocols_Details.md#Traxxas---43)|43|TQ||||||||CYRF6936|
[V2x2](Protocols_Details.md#V2X2---5)|5|V2x2|JXD506|MR101||||||NRF24L01|
[V761](Protocols_Details.md#V761---48)|48|3CH|4CH|TOPRC||||||NRF24L01|XN297
[V911S](Protocols_Details.md#V911S---46)|46|V911S*|E119*|||||||NRF24L01|XN297
@@ -149,7 +151,7 @@ CFlie|38|CFlie||||||||NRF24L01|
[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|
[XERALL](Protocols_Details.md#XERALL---91)|91|Tank||||||||NRF24L01|XN297
[XK](Protocols_Details.md#XK---62)|62|X450|X420|||||||NRF24L01|XN297
[XK](Protocols_Details.md#XK---62)|62|X450|X420|Cars||||||NRF24L01|XN297
[YD717](Protocols_Details.md#YD717---8)|8|YD717|SKYWLKR|SYMAX4|XINXUN|NIHUI||||NRF24L01|
[ZSX](Protocols_Details.md#ZSX---52)|52|280||||||||NRF24L01|XN297
* "*" Sub Protocols designated by * suffix are using a XN297L@250kbps which will be emulated by default with the NRF24L01. If option (freq tune) is diffrent from 0, the CC2500 module (if installed) will be used instead. Each specific sub protocol has a more detailed explanation.
@@ -326,7 +328,9 @@ CH1|CH2|CH3|CH4
## Kyosho - *73*
### Sub_protocol FHSS - *0*
Surface protocol called FHSS introduced in 2017. Transmitter: KT-531P. Models: Mini-Z
Surface protocol called FHSS introduced in 2017. Transmitter: KT-531P. Models: Mini-Z.
Surface protocol called Syncro. TX: KT-331, RX: KR-331
Extended limits supported
@@ -365,8 +369,6 @@ TX: Axial AX-4 2.4GHz transmitter, HPI TF-41 and Panda Hobby 3CH Smart Radio 2.4
Models: Axial SCX24: Deadbolt, Jeep Wranger Rubicon, Chevrolet 1967 C10, B-17 Betty, HPI RF-50 and Panda Hobby: Tetra K1, X1, X2
**Only 4 frequency hopping tables**
Extended limits supported
CH1|CH2|CH3
@@ -539,12 +541,23 @@ Surface DSMR receivers
**Only 22 IDs available**, use RX num to cycle through them.
Telemetry enabled, extended limits available.
Telemetry enabled, extended limits available and no channel mapping. Do not use DSM/AUTO to bind but DSM/R_1F instead.
CH1|CH2|CH3|CH4|CH5|CH6|CH7
---|---|---|---|---|---|---
STR|THR|AUX1|AUX2|AUX3|AUX4|AUX5
### Sub_protocol DSM2SFC - *6*
Surface DSM2 receivers, tested with a SR3100
Extended limits available and no channel mapping. Do not use DSM/AUTO to bind but DSM/2SFC instead.
Servo refresh rate 22/11ms is repurposed to the frame rates 16.5ms(22) and 11ms(11).
CH1|CH2|CH3
---|---|---
STR|THR|AUX1
## DSM_RX - *70*
The DSM receiver protocol enables master/slave trainning, separate access from 2 different radios to the same model,...
@@ -619,7 +632,7 @@ Calib is the same as the original radio with both sticks down and to the left in
Models: Eachine E129/E130 and Twister Ninja 250
### Sub_protocol C186 - *1*
Models: C186/E120, C127/E110, K127, C159, C189, C129v2
Models: RC ERA C186/E120, C127/E110, K127, C159, C189, C129v2
The FC of the heli seems to store the trims Trim A/E/R=CH7..9. If you use these trims, make sure to center them after powering off the heli or they will be added to the previous trims and over correct.
@@ -637,6 +650,17 @@ CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12
---|---|---|---|---|---|---|---|---|----|----|----
A|E|T|R|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12
## Kyosho3 - *98*
### Sub_protocol ASF - *0*
Surface protocol ASF. Models: Mini-Z.
Extended limits supported
CH1|CH2|CH3|CH4
---|---|---|---
STEERING|THROTTLE|CH3|CH4
## Losi - *89*
TX: LSR-3000
@@ -669,13 +693,15 @@ CH1|CH2|CH3|CH4
A|E|T|R
## Traxxas - *43*
Receiver 6519
Transmitter TQ, Receivers: 6519, 2218(X), ECM-2.5
Extended limits supported
CH1|CH2|CH3|CH4
---|---|---|---
AUX3|AUX4|THROTTLE|STEERING
CH1|CH2|CH3|CH4|CH5|CH6
---|---|---|---|---|---
CH1|CH2|CH3|CH4|CH5|CH6
Warning from v1.3.4.7 channels order have changed
## WFLY - *40*
Receivers: WFR04S, WFR07S, WFR09S
@@ -998,6 +1024,17 @@ Telemetry: RX_RSSI (for the original value add -256), TX_RSSI, TX_QLY (0..100%)
### Sub_protocol DumboRC - *2*
Compatible RXs: X6/X6F/X6FG
### Sub_protocol RC4G - *3*
Compatible RXs: R4EH-G(/R4EH-H)
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
---|---|---|---|---|---|---|---|---
CH1|CH2|CH3|CH4|CH5|FS_CH1|FS_CH2|FS_CH3|FS_CH4
FS=FailSafe
CH5 is driven by CH3 on the original TX, gyro sensitivity?
## Futaba - *21*
Also called SFHSS depending on radio version.
@@ -1376,6 +1413,12 @@ FLIP: sets model into flip mode for approx 5 seconds at each throw of switch (re
MODE: -100% level, +100% acro
### Sub_protocol V1_4CH - *5*
CH1|CH2|CH3|CH4
---|---|---|---
CH1|CH2|CH3|CH4
## V911S - *46*
CH1|CH2|CH3|CH4|CH5|CH6
@@ -1390,18 +1433,14 @@ Models: WLtoys V911S, XK A110
### Sub_protocol E119 - *1*
Models: Eachine E119, JJRC W01-J3, XK A220 P-40, XK A800 R2, F959S R2, A160 R2, A280
CH1|CH2|CH3|CH4|CH5|CH6|CH7
---|---|---|---|---|---|---
A|E|T|R|CALIB|RATE|6G_3D
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
---|---|---|---|---|---|---|---|---
A|E|T|R|CALIB|RATE|6G_3D|6GSENIOR|LIGHT
A280 -> 6GSENIOR: -100% - 6G, +100% - Senior mode (turn off gyro), LIGHT: cycle the light through on-flash-off when the CH9 value is changed from -100% to 100%
## XK - *62*
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10
---|---|---|---|---|---|---|---|---|----
A|E|T|R|Flight_modes|Take_off|Emerg stop|3D/6G|Picture|Video
Flight_modes: -100%=M-Mode, 0%=6G-Mode, +100%=V-Mode. CH6-CH10 are mementary switches.
CC2500: only X450 is supported.
### Sub_protocol X450 - *0*
@@ -1411,8 +1450,30 @@ If a CC2500 is installed it will be used for this sub protocol. Option in this c
If only a NRF24L01 is installed then this sub protocol might be problematic because it is using the xn297L emulation with a transmission speed of 250kbps which doesn't work very well with every NRF24L01, this is an hardware issue with the authenticity and accuracy of the components.
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10
---|---|---|---|---|---|---|---|---|----
A|E|T|R|Flight_modes|Take_off|Emerg stop|3D/6G|Picture|Video
Flight_modes: -100%=M-Mode, 0%=6G-Mode, +100%=V-Mode. CH6-CH10 are mementary switches.
### Sub_protocol X420 - *1*
Models: XK X420/X520 (TX=X4), WLtoys 284131/284161/284010
Models: XK X420/X520 (TX=X4)
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10
---|---|---|---|---|---|---|---|---|----
A|E|T|R|Flight_modes|Take_off|Emerg stop|3D/6G|Picture|Video
Flight_modes: -100%=M-Mode, 0%=6G-Mode, +100%=V-Mode. CH6-CH10 are mementary switches.
Model: Tiger Drone 1400782
CH1|CH2|CH3|CH4|CH11|CH12
---|---|---|---|---|---
A|E|T|R|FLIP|LIGHT
### Sub_protocol Cars - *2*
Models: WLtoys cars 284131/284161/284010/124016/124017/144010 and Eachine EAT14
***
# NRF24L01 RF Module
@@ -1440,13 +1501,13 @@ Channels 14 and 15 (ANAAUX1 and ANAAUX2) only available with analog aux channel
### Sub_protocol BAYANG - *0*
Models: Eachine H8(C) mini, BayangToys X6/X7/X9, JJRC JJ850, Floureon H101 ...
Option=0 -> normal Bayang protocol
Option=0 or Telemetry = Off -> 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 (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=1 or Telemetry = On -> 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.
Option=2 or Telemetry = Off+AUX -> 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.
Option=3 -> both Silverware telemetry and analog aux channels enabled.
Option=3 or Telemetry = On+AUX-> both Silverware telemetry and analog aux channels enabled.
### Sub_protocol H8S3D - *1*
Model: H8S 3D
@@ -1622,6 +1683,13 @@ CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
---|---|---|---|---|---|---|---|---
A|E|T|R|STOP|FLIP|-|HEADLESS|RTH
## EazyRC - *61*
Autobind protocol
CH1|CH2|CH3|CH4
---|---|---|---
STEERING||THROTTLE|
## ESKY - *16*
CH1|CH2|CH3|CH4|CH5|CH6
@@ -1667,7 +1735,7 @@ Only 8 TX IDs available
Model: FX620 SU35
### Sub_protocol 9630 - *2*
Model: FX9630, FX9603 and QIDI-550
Model: FX9630, FX9603, QIDI-550
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9
---|---|---|---|---|---|---|---|---
@@ -1677,6 +1745,17 @@ FX9630 and FX9603 Gyro: -100%=6G small throw, 0%=6G large throw, +100%=3D
QIDI-550 Gyro: -100%=3D, 0%=6G, +100%=Torque
### Sub_protocol Q560 - *2*
Model: QIDI-560
CH1|CH2|CH3|CH4|CH5|CH6|CH7
---|---|---|---|---|---|---
A|E|T|R|FLIP|GYRO|LEDs
FLIP and LEDs are toggle channels meaning that -100% to +100% is a command and +100% to -100% is also a command
Gyro: -100%=6G, 0%=3D+Gyro, +100%=3D
## FY326 - *20*
### Sub_protocol FY326 - *0*
@@ -1751,9 +1830,9 @@ CH1|CH2|CH3|CH4|CH5
| | |T|R|AUX
## KN - *9*
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11
---|---|---|---|---|---|---|---|---|----|----
A|E|T|R|DR|THOLD|IDLEUP|GYRO|Ttrim|Atrim|Etrim
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|CH13
---|---|---|---|---|---|---|---|---|----|----|----|----
A|E|T|R|DR|THOLD|IDLEUP|GYRO|Ttrim|Atrim|Etrim|Rtrim|HoverDebugging
Dual Rate: +100%=full range, Throttle Hold: +100%=hold, Idle Up: +100%=3D, GYRO: -100%=6G, +100%=3G
@@ -1912,17 +1991,13 @@ A|E|T|R|FLIP|LED|PICTURE|VIDEO|HEADLESS|RTH|XCAL|YCAL
Model: JXD 509 is using Q282 with CH12=Start/Stop motors
## Realacc - *76*
Model: Realacc R11
Untested protocol, let me know if it works.
Model: Realacc R11, Eachine E017
Autobind protocol
### Sub_protocol R11 - *0*
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10
---|---|---|---|---|---|---|---|---|----
A|E|T|R|FLIP|LIGHT|CALIB|HLESS|RTH|UNK
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11
---|---|---|---|---|---|---|---|---|----|----
A|E|T|R|FLIP|LIGHT|CALIB|HLESS|RTH|THR_CUT|ROTATE
## Redpine - *50*
[Link to the forum](https://www.rcgroups.com/forums/showthread.php?3236043-Redpine-Lowest-latency-RC-protocol)
@@ -1930,6 +2005,15 @@ A|E|T|R|FLIP|LIGHT|CALIB|HLESS|RTH|UNK
### Sub_protocol FAST - *0*
### Sub_protocol SLOW - *1*
## SGF22 - *97*
Autobind protocol
Model: SGF22
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10
---|---|---|---|---|---|---|---|---|---
A|E|T|R|MODE|FLIP|LIGHT|PHOTO|VIDEO|TRIMRESET
## Shenqi - *19*
Autobind protocol
@@ -1992,17 +2076,6 @@ AUTO: Land=-100% Takeoff=+100%
The model can work with a none centered throttle.
## Tiger - *61*
Models: Tiger Drone 1400782, WLToys 124016 / 124017 / 144010 and Eachine EAT14
Autobind protocol
**Only 1 ID**
CH1|CH2|CH3|CH4|CH5|CH6
---|---|---|---|---|---
A|E|T|R|FLIP|LIGHT
## V761 - *48*
Gyro: -100%=Beginner mode (Gyro on, yaw and pitch rate limited), 0%=Mid Mode ( Gyro on no rate limits), +100%=Mode Expert Gyro off

View File

@@ -84,23 +84,30 @@ buildEachRFModule() {
}
buildReleaseFiles(){
if [[ "$BOARD" =~ ":avr:multixmega32d4" ]]; then
if [[ "$RELEASE" == "scripts" ]]; then
build_release_scripts;
elif [[ "$RELEASE" == "orangerx" ]]; then
build_release_orx;
build_release_extras;
elif [[ "$BOARD" =~ ":avr:multiatmega328p:bootloader=none" ]]; then
elif [[ "$RELEASE" == "atmega328p" ]]; then
build_release_avr_noboot;
elif [[ "$BOARD" =~ ":avr:multiatmega328p:bootloader=optiboot" ]]; then
elif [[ "$RELEASE" == "atmega328p-optiboot" ]]; then
build_release_avr_optiboot;
elif [[ "$BOARD" =~ ":STM32F1:multistm32f103cb:debug_option=none" ]]; then
build_release_stm32f1_no_debug;
elif [[ "$BOARD" =~ ":STM32F1:multistm32f103cb:debug_option=native" ]]; then
build_release_stm32f1_native_debug;
elif [[ "$BOARD" =~ ":STM32F1:multistm32f103cb:debug_option=ftdi" ]]; then
build_release_stm32f1_serial_debug;
elif [[ "$BOARD" =~ ":STM32F1:multi5in1t18int" ]]; then
elif [[ "$RELEASE" == "stm32f103-128k-4in1" ]]; then
build_release_stm32f1_4in1_no_debug;
elif [[ "$RELEASE" == "stm32f103-128k-usb-debug" ]]; then
build_release_stm32f1_4in1_native_debug;
elif [[ "$RELEASE" == "stm32f103-128k-serial-debug" ]]; then
build_release_stm32f1_4in1_serial_debug;
elif [[ "$RELEASE" == "stm32f103-cc2500-64k" ]]; then
build_release_stm32f1_cc2500_64k;
elif [[ "$RELEASE" == "stm32f103-cc2500-128k" ]]; then
build_release_stm32f1_cc2500_128k;
elif [[ "$RELEASE" == "stm32f103-128k-5in1" ]]; then
build_release_stm32f1_5in1;
elif [[ "$RELEASE" == "tlite-5in1" ]]; then
build_release_stm32f1_tlite;
elif [[ "$RELEASE" == "t18-5in1" ]]; then
build_release_stm32f1_t18int;
elif [[ "$BOARD" =~ ":STM32F1:multistm32f103c8:debug_option=none" ]]; then
build_release_stm32f1_64k;
else
printf "No release files for this board.";
fi

View File

@@ -0,0 +1,97 @@
#!/usr/bin/env bash
source ./buildroot/bin/buildFunctions;
exitcode=0;
# Generic 4-in-1 AIR builds
printf "\e[33;1mBuilding mm-stm-serial-aetr-air-v$MULTI_VERSION.bin\e[0m\n";
opt_add MULTI_AIR
opt_disable ENABLE_PPM;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-serial-aetr-air-v$MULTI_VERSION.bin;
printf "\e[33;1mBuilding mm-stm-serial-taer-air-v$MULTI_VERSION.bin\e[0m\n";
opt_replace AETR TAER;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-serial-taer-air-v$MULTI_VERSION.bin;
printf "\e[33;1mBuilding mm-stm-serial-reta-air-v$MULTI_VERSION.bin\e[0m\n";
opt_replace TAER RETA;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-serial-reta-air-v$MULTI_VERSION.bin;
# Generic 4-in-1 SURFACE builds
printf "\e[33;1mBuilding mm-stm-serial-aetr-sfc-v$MULTI_VERSION.bin\e[0m\n";
opt_replace RETA AETR;
opt_remove MULTI_AIR;
opt_add MULTI_SURFACE;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-serial-aetr-sfc-v$MULTI_VERSION.bin;
printf "\e[33;1mBuilding mm-stm-serial-taer-sfc-v$MULTI_VERSION.bin\e[0m\n";
opt_replace AETR TAER;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-serial-taer-sfc-v$MULTI_VERSION.bin;
printf "\e[33;1mBuilding mm-stm-serial-reta-sfc-v$MULTI_VERSION.bin\e[0m\n";
opt_replace TAER RETA;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-serial-reta-sfc-v$MULTI_VERSION.bin;
# Generic 4-in-1 LBT/EU builds
printf "\e[33;1mBuilding mm-stm-serial-aetr-lbt-v$MULTI_VERSION.bin\e[0m\n";
opt_replace RETA AETR;
opt_remove MULTI_SURFACE;
opt_add MULTI_EU;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-serial-aetr-lbt-v$MULTI_VERSION.bin;
printf "\e[33;1mBuilding mm-stm-serial-taer-lbt-v$MULTI_VERSION.bin\e[0m\n";
opt_replace AETR TAER;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-serial-taer-lbt-v$MULTI_VERSION.bin;
printf "\e[33;1mBuilding mm-stm-serial-reta-lbt-v$MULTI_VERSION.bin\e[0m\n";
opt_replace TAER RETA;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-serial-reta-lbt-v$MULTI_VERSION.bin;
# 4-in-1 PPM builds
printf "\e[33;1mBuilding mm-stm-ppm-aetr-v$MULTI_VERSION.bin\e[0m\n";
opt_add MULTI_AIR;
opt_enable A7105_INSTALLED;
opt_enable CYRF6936_INSTALLED;
opt_enable NRF24L01_INSTALLED;
opt_remove MULTI_EU;
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/mm-stm-ppm-aetr-v$MULTI_VERSION.bin;
printf "\e[33;1mBuilding mm-stm-ppm-taer-v$MULTI_VERSION.bin\e[0m\n";
opt_replace AETR TAER;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-ppm-taer-v$MULTI_VERSION.bin;
printf "\e[33;1mBuilding mm-stm-ppm-reta-v$MULTI_VERSION.bin\e[0m\n";
opt_replace TAER RETA;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-ppm-reta-v$MULTI_VERSION.bin;
exit $exitcode;

View File

@@ -0,0 +1,71 @@
#!/usr/bin/env bash
source ./buildroot/bin/buildFunctions;
exitcode=0;
# DIY 5-in-1 AIR builds
printf "\e[33;1mBuilding mm-stm-5in1-aetr-air-v$MULTI_VERSION.bin\e[0m\n";
opt_add MULTI_AIR;
opt_disable ENABLE_PPM;
opt_disable CFLIE_NRF24L01_INO
opt_enable SX1276_INSTALLED;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-5in1-aetr-air-v$MULTI_VERSION.bin;
printf "\e[33;1mBuilding mm-stm-5in1-taer-air-v$MULTI_VERSION.bin\e[0m\n";
opt_replace AETR TAER;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-5in1-taer-air-v$MULTI_VERSION.bin;
printf "\e[33;1mBuilding mm-stm-5in1-reta-air-v$MULTI_VERSION.bin\e[0m\n";
opt_replace TAER RETA;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-5in1-reta-air-v$MULTI_VERSION.bin;
# DIY 5-in-1 SURFACE builds
printf "\e[33;1mBuilding mm-stm-5in1-aetr-sfc-v$MULTI_VERSION.bin\e[0m\n";
opt_add MULTI_SURFACE;
opt_remove MULTI_AIR;
opt_enable CFLIE_NRF24L01_INO
opt_replace RETA AETR;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-5in1-aetr-sfc-v$MULTI_VERSION.bin;
printf "\e[33;1mBuilding mm-stm-5in1-taer-sfc-v$MULTI_VERSION.bin\e[0m\n";
opt_replace AETR TAER;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-5in1-taer-sfc-v$MULTI_VERSION.bin;
printf "\e[33;1mBuilding mm-stm-5in1-reta-sfc-v$MULTI_VERSION.bin\e[0m\n";
opt_replace TAER RETA;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-5in1-reta-sfc-v$MULTI_VERSION.bin;
# DIY 5-in-1 LBT builds
printf "\e[33;1mBuilding mm-stm-5in1-aetr-lbt-v$MULTI_VERSION.bin\e[0m\n";
opt_remove MULTI_SURFACE;
opt_add MULTI_EU;
opt_replace RETA AETR;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-5in1-aetr-lbt-v$MULTI_VERSION.bin;
printf "\e[33;1mBuilding mm-stm-5in1-taer-lbt-v$MULTI_VERSION.bin\e[0m\n";
opt_replace AETR TAER;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-5in1-taer-lbt-v$MULTI_VERSION.bin;
printf "\e[33;1mBuilding mm-stm-5in1-reta-lbt-v$MULTI_VERSION.bin\e[0m\n";
opt_replace TAER RETA;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-5in1-reta-lbt-v$MULTI_VERSION.bin;
exit $exitcode;

View File

@@ -0,0 +1,49 @@
#!/usr/bin/env bash
source ./buildroot/bin/buildFunctions;
exitcode=0;
# CC2500-only FCC builds
printf "\e[33;1mBuilding mm-stm-cc2500-aetr-v$MULTI_VERSION.bin\e[0m\n";
opt_disable A7105_INSTALLED;
opt_disable CYRF6936_INSTALLED;
opt_disable NRF24L01_INSTALLED;
opt_disable ENABLE_PPM;
opt_disable INVERT_TELEMETRY;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-cc2500-aetr-v$MULTI_VERSION.bin;
printf "\e[33;1mBuilding mm-stm-cc2500-taer-v$MULTI_VERSION.bin\e[0m\n";
opt_replace AETR TAER;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-cc2500-taer-v$MULTI_VERSION.bin;
printf "\e[33;1mBuilding mm-stm-cc2500-reta-v$MULTI_VERSION.bin\e[0m\n";
opt_replace TAER RETA;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-cc2500-reta-v$MULTI_VERSION.bin;
# CC2500-only LBT/EU builds
printf "\e[33;1mBuilding mm-stm-cc2500-aetr-lbt-v$MULTI_VERSION.bin\e[0m\n";
opt_replace RETA AETR;
opt_add MULTI_EU;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-cc2500-aetr-lbt-v$MULTI_VERSION.bin;
printf "\e[33;1mBuilding mm-stm-cc2500-taer-lbt-v$MULTI_VERSION.bin\e[0m\n";
opt_replace AETR TAER;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-cc2500-taer-lbt-v$MULTI_VERSION.bin;
printf "\e[33;1mBuilding mm-stm-cc2500-reta-lbt-v$MULTI_VERSION.bin\e[0m\n";
opt_replace TAER RETA;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-cc2500-reta-lbt-v$MULTI_VERSION.bin;
exit $exitcode;

View File

@@ -5,8 +5,8 @@ exitcode=0;
# CC2500-only 64Kb FCC builds
printf "\e[33;1mBuilding mm-stm-cc2500-64-aetr-v$MULTI_VERSION.bin\e[0m\n";
opt_enable $ALL_PROTOCOLS;
opt_disable IKEAANSLUTA_CC2500_INO;
#opt_enable $ALL_PROTOCOLS;
#opt_disable IKEAANSLUTA_CC2500_INO;
opt_disable ENABLE_PPM;
opt_disable A7105_INSTALLED;
opt_disable CYRF6936_INSTALLED;

View File

@@ -1,160 +0,0 @@
#!/usr/bin/env bash
source ./buildroot/bin/buildFunctions;
exitcode=0;
# Generic 4-in-1 FCC builds
printf "\e[33;1mBuilding mm-stm-serial-aetr-v$MULTI_VERSION.bin\e[0m\n";
opt_disable ENABLE_PPM;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-serial-aetr-v$MULTI_VERSION.bin;
printf "\e[33;1mBuilding mm-stm-serial-taer-v$MULTI_VERSION.bin\e[0m\n";
opt_replace AETR TAER;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-serial-taer-v$MULTI_VERSION.bin;
printf "\e[33;1mBuilding mm-stm-serial-reta-v$MULTI_VERSION.bin\e[0m\n";
opt_replace TAER RETA;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-serial-reta-v$MULTI_VERSION.bin;
# Generic 4-in-1 LBT/EU builds
printf "\e[33;1mBuilding mm-stm-serial-aetr-lbt-v$MULTI_VERSION.bin\e[0m\n";
opt_replace RETA AETR;
opt_add MULTI_EU;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-serial-aetr-lbt-v$MULTI_VERSION.bin;
printf "\e[33;1mBuilding mm-stm-serial-taer-lbt-v$MULTI_VERSION.bin\e[0m\n";
opt_replace AETR TAER;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-serial-taer-lbt-v$MULTI_VERSION.bin;
printf "\e[33;1mBuilding mm-stm-serial-reta-lbt-v$MULTI_VERSION.bin\e[0m\n";
opt_replace TAER RETA;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-serial-reta-lbt-v$MULTI_VERSION.bin;
# DIY 5-in-1 builds
printf "\e[33;1mBuilding mm-stm-5in1-aetr-v$MULTI_VERSION.bin\e[0m\n";
opt_remove MULTI_EU;
opt_replace RETA AETR;
opt_enable SX1276_INSTALLED;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-5in1-aetr-v$MULTI_VERSION.bin;
printf "\e[33;1mBuilding mm-stm-5in1-taer-v$MULTI_VERSION.bin\e[0m\n";
opt_replace AETR TAER;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-5in1-taer-v$MULTI_VERSION.bin;
printf "\e[33;1mBuilding mm-stm-5in1-reta-v$MULTI_VERSION.bin\e[0m\n";
opt_replace TAER RETA;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-5in1-reta-v$MULTI_VERSION.bin;
# T-Lite 5-in-1 builds
printf "\e[33;1mBuilding mm-tlite5in1-aetr-v$MULTI_VERSION.bin\e[0m\n";
opt_replace RETA AETR;
opt_disable INVERT_TELEMETRY;
opt_disable SX1276_INSTALLED;
opt_enable "MULTI_5IN1_INTERNAL JP_TLite"
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-tlite5in1-aetr-v$MULTI_VERSION.bin;
printf "\e[33;1mBuilding mm-tlite5in1-taer-v$MULTI_VERSION.bin\e[0m\n";
opt_replace AETR TAER;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-tlite5in1-taer-v$MULTI_VERSION.bin;
printf "\e[33;1mBuilding mm-tlite5in1-reta-v$MULTI_VERSION.bin\e[0m\n";
opt_replace TAER RETA;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-tlite5in1-reta-v$MULTI_VERSION.bin;
# CC2500-only FCC builds
printf "\e[33;1mBuilding mm-stm-cc2500-aetr-v$MULTI_VERSION.bin\e[0m\n";
opt_replace RETA AETR;
opt_disable "MULTI_5IN1_INTERNAL JP_TLite"
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/mm-stm-cc2500-aetr-v$MULTI_VERSION.bin;
printf "\e[33;1mBuilding mm-stm-cc2500-taer-v$MULTI_VERSION.bin\e[0m\n";
opt_replace AETR TAER;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-cc2500-taer-v$MULTI_VERSION.bin;
printf "\e[33;1mBuilding mm-stm-cc2500-reta-v$MULTI_VERSION.bin\e[0m\n";
opt_replace TAER RETA;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-cc2500-reta-v$MULTI_VERSION.bin;
# CC2500-only LBT/EU builds
printf "\e[33;1mBuilding mm-stm-cc2500-aetr-lbt-v$MULTI_VERSION.bin\e[0m\n";
opt_replace RETA AETR;
opt_add MULTI_EU;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-cc2500-aetr-lbt-v$MULTI_VERSION.bin;
printf "\e[33;1mBuilding mm-stm-cc2500-taer-lbt-v$MULTI_VERSION.bin\e[0m\n";
opt_replace AETR TAER;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-cc2500-taer-lbt-v$MULTI_VERSION.bin;
printf "\e[33;1mBuilding mm-stm-cc2500-reta-lbt-v$MULTI_VERSION.bin\e[0m\n";
opt_replace TAER RETA;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-cc2500-reta-lbt-v$MULTI_VERSION.bin;
# 4-in-1 PPM builds
printf "\e[33;1mBuilding mm-stm-ppm-aetr-v$MULTI_VERSION.bin\e[0m\n";
opt_enable A7105_INSTALLED;
opt_enable CYRF6936_INSTALLED;
opt_enable NRF24L01_INSTALLED;
opt_remove MULTI_EU;
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/mm-stm-ppm-aetr-v$MULTI_VERSION.bin;
printf "\e[33;1mBuilding mm-stm-ppm-taer-v$MULTI_VERSION.bin\e[0m\n";
opt_replace AETR TAER;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-ppm-taer-v$MULTI_VERSION.bin;
printf "\e[33;1mBuilding mm-stm-ppm-reta-v$MULTI_VERSION.bin\e[0m\n";
opt_replace TAER RETA;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-stm-ppm-reta-v$MULTI_VERSION.bin;
exit $exitcode;

View File

@@ -3,23 +3,65 @@
source ./buildroot/bin/buildFunctions;
exitcode=0;
printf "\e[33;1mBuilding mm-t18int-aetr-v$MULTI_VERSION.bin\e[0m\n";
# T18 5-in-1 AIR builds
printf "\e[33;1mBuilding mm-t18int-aetr-air-v$MULTI_VERSION.bin\e[0m\n";
opt_add MULTI_AIR
opt_disable ENABLE_PPM;
opt_disable INVERT_TELEMETRY;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-t18int-aetr-v$MULTI_VERSION.bin;
mv build/Multiprotocol.ino.bin ./binaries/mm-t18int-aetr-air-v$MULTI_VERSION.bin;
printf "\e[33;1mBuilding mm-t18int-taer-v$MULTI_VERSION.bin\e[0m\n";
printf "\e[33;1mBuilding mm-t18int-taer-air-v$MULTI_VERSION.bin\e[0m\n";
opt_replace AETR TAER;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-t18int-taer-v$MULTI_VERSION.bin;
mv build/Multiprotocol.ino.bin ./binaries/mm-t18int-taer-air-v$MULTI_VERSION.bin;
printf "\e[33;1mBuilding mm-t18int-reta-v$MULTI_VERSION.bin\e[0m\n";
printf "\e[33;1mBuilding mm-t18int-reta-air-v$MULTI_VERSION.bin\e[0m\n";
opt_replace TAER RETA;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-t18int-reta-v$MULTI_VERSION.bin;
mv build/Multiprotocol.ino.bin ./binaries/mm-t18int-reta-air-v$MULTI_VERSION.bin;
# T18 5-in-1 SURFACE builds
printf "\e[33;1mBuilding mm-t18int-aetr-sfc-v$MULTI_VERSION.bin\e[0m\n";
opt_remove MULTI_AIR
opt_add MULTI_SURFACE
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-t18int-aetr-sfc-v$MULTI_VERSION.bin;
printf "\e[33;1mBuilding mm-t18int-taer-sfc-v$MULTI_VERSION.bin\e[0m\n";
opt_replace AETR TAER;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-t18int-taer-sfc-v$MULTI_VERSION.bin;
printf "\e[33;1mBuilding mm-t18int-reta-sfc-v$MULTI_VERSION.bin\e[0m\n";
opt_replace TAER RETA;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-t18int-reta-sfc-v$MULTI_VERSION.bin;
# T18 5-in-1 LBT/EU builds
printf "\e[33;1mBuilding mm-t18int-aetr-lbt-v$MULTI_VERSION.bin\e[0m\n";
opt_remove MULTI_SURFACE
opt_add MULTI_EU
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-t18int-aetr-lbt-v$MULTI_VERSION.bin;
printf "\e[33;1mBuilding mm-t18int-taer-lbt-v$MULTI_VERSION.bin\e[0m\n";
opt_replace AETR TAER;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-t18int-taer-lbt-v$MULTI_VERSION.bin;
printf "\e[33;1mBuilding mm-t18int-reta-lbt-v$MULTI_VERSION.bin\e[0m\n";
opt_replace TAER RETA;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-t18int-reta-lbt-v$MULTI_VERSION.bin;
exit $exitcode;

View File

@@ -0,0 +1,70 @@
#!/usr/bin/env bash
source ./buildroot/bin/buildFunctions;
exitcode=0;
# T-Lite 5-in-1 AIR builds
printf "\e[33;1mBuilding mm-tlite5in1-aetr-air-v$MULTI_VERSION.bin\e[0m\n";
opt_add MULTI_AIR;
opt_disable ENABLE_PPM;
opt_disable INVERT_TELEMETRY;
opt_enable "MULTI_5IN1_INTERNAL JP_TLite"
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-tlite5in1-aetr-air-v$MULTI_VERSION.bin;
printf "\e[33;1mBuilding mm-tlite5in1-taer-air-v$MULTI_VERSION.bin\e[0m\n";
opt_replace AETR TAER;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-tlite5in1-taer-air-v$MULTI_VERSION.bin;
printf "\e[33;1mBuilding mm-tlite5in1-reta-air-v$MULTI_VERSION.bin\e[0m\n";
opt_replace TAER RETA;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-tlite5in1-reta-air-v$MULTI_VERSION.bin;
# T-Lite 5-in-1 SURFACE builds
printf "\e[33;1mBuilding mm-tlite5in1-aetr-sfc-v$MULTI_VERSION.bin\e[0m\n";
opt_add MULTI_SURFACE;
opt_remove MULTI_AIR;
opt_replace RETA AETR;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-tlite5in1-aetr-sfc-v$MULTI_VERSION.bin;
printf "\e[33;1mBuilding mm-tlite5in1-taer-sfc-v$MULTI_VERSION.bin\e[0m\n";
opt_replace AETR TAER;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-tlite5in1-taer-sfc-v$MULTI_VERSION.bin;
printf "\e[33;1mBuilding mm-tlite5in1-reta-sfc-v$MULTI_VERSION.bin\e[0m\n";
opt_replace TAER RETA;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-tlite5in1-reta-sfc-v$MULTI_VERSION.bin;
# T-Lite 5-in-1 SURFACE builds
printf "\e[33;1mBuilding mm-tlite5in1-aetr-lbt-v$MULTI_VERSION.bin\e[0m\n";
opt_remove MULTI_SURFACE;
opt_add MULTI_EU;
opt_replace RETA AETR;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-tlite5in1-aetr-lbt-v$MULTI_VERSION.bin;
printf "\e[33;1mBuilding mm-tlite5in1-taer-lbt-v$MULTI_VERSION.bin\e[0m\n";
opt_replace AETR TAER;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-tlite5in1-taer-lbt-v$MULTI_VERSION.bin;
printf "\e[33;1mBuilding mm-tlite5in1-reta-lbt-v$MULTI_VERSION.bin\e[0m\n";
opt_replace TAER RETA;
buildMulti;
exitcode=$((exitcode+$?));
mv build/Multiprotocol.ino.bin ./binaries/mm-tlite5in1-reta-lbt-v$MULTI_VERSION.bin;
exit $exitcode;