mirror of
https://github.com/pascallanger/DIY-Multiprotocol-TX-Module.git
synced 2025-11-26 05:59:41 +00:00
Compare commits
81 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6f33abb25e | ||
|
|
2c9693389e | ||
|
|
d3c82c4da4 | ||
|
|
541a96e7b4 | ||
|
|
5b234a9cbc | ||
|
|
24c3a62f3a | ||
|
|
23756a387a | ||
|
|
efbd350dfd | ||
|
|
072e95c84e | ||
|
|
4be26e7202 | ||
|
|
a616cbb95c | ||
|
|
8aea9aa3dd | ||
|
|
e4992bc917 | ||
|
|
000b3e97c7 | ||
|
|
cb91e19413 | ||
|
|
c72e690085 | ||
|
|
f1a4e659e7 | ||
|
|
0d56d17d52 | ||
|
|
96c89c8c97 | ||
|
|
7df5a1f211 | ||
|
|
8ae8e028c7 | ||
|
|
581ad5f8f4 | ||
|
|
977bae3750 | ||
|
|
8a0161607e | ||
|
|
cd6a7bfc3a | ||
|
|
4671700b7d | ||
|
|
840ca74407 | ||
|
|
0d8a7e46de | ||
|
|
8b9940b0f0 | ||
|
|
521b819b8a | ||
|
|
208e9ef64b | ||
|
|
a7ea8e012e | ||
|
|
d940a7e49a | ||
|
|
9d50171034 | ||
|
|
701a5b9e28 | ||
|
|
d11785ef2d | ||
|
|
f4a4d91ef8 | ||
|
|
9514e47ed3 | ||
|
|
9461f2d632 | ||
|
|
f6064d03e1 | ||
|
|
0d917e0dc5 | ||
|
|
9408af8d08 | ||
|
|
862ab48bbc | ||
|
|
f498347c53 | ||
|
|
3f77f59c8a | ||
|
|
e96186015d | ||
|
|
1fa6e4526b | ||
|
|
3853d585a0 | ||
|
|
e8c6225ef0 | ||
|
|
17c67cc780 | ||
|
|
dcc4236833 | ||
|
|
6a7c735924 | ||
|
|
3c40cd853e | ||
|
|
5357660b68 | ||
|
|
a15a911f8e | ||
|
|
ded0487ce6 | ||
|
|
e7b079ece7 | ||
|
|
0cbe4de920 | ||
|
|
5c3bf30fe7 | ||
|
|
56b8694fd5 | ||
|
|
c9fecafada | ||
|
|
f3ca7ad644 | ||
|
|
c3b48c78af | ||
|
|
18dcc29a0d | ||
|
|
c3a5c263d3 | ||
|
|
ccdf60d525 | ||
|
|
443e1cec75 | ||
|
|
aa540514b8 | ||
|
|
fda7e2e5b6 | ||
|
|
fb4d5cf437 | ||
|
|
9fc2898a56 | ||
|
|
2e24323adf | ||
|
|
77abc1ed7c | ||
|
|
259d550d04 | ||
|
|
1a8f9c5a12 | ||
|
|
1916eb3095 | ||
|
|
fc3eec7ae1 | ||
|
|
8d10c9b004 | ||
|
|
511f77f5e7 | ||
|
|
a58d7a4d79 | ||
|
|
6748f6ce78 |
@@ -149,22 +149,22 @@ before_deploy:
|
||||
opt_disable CHECK_FOR_BOOTLOADER;
|
||||
opt_enable $ALL_PROTOCOLS;
|
||||
buildMulti;
|
||||
mv build/Multiprotocol.ino.bin ./binaries/Multi-STM_FTDI_INV-$TRAVIS_TAG.hex;
|
||||
mv build/Multiprotocol.ino.bin ./binaries/Multi-STM_FTDI_INV-$TRAVIS_TAG.bin;
|
||||
opt_disable MULTI_STATUS;
|
||||
opt_enable MULTI_TELEMETRY;
|
||||
buildMulti;
|
||||
mv build/Multiprotocol.ino.bin ./binaries/Multi-STM_FTDI_INV_OPENTX-$TRAVIS_TAG.hex;
|
||||
mv build/Multiprotocol.ino.bin ./binaries/Multi-STM_FTDI_INV_OPENTX-$TRAVIS_TAG.bin;
|
||||
fi
|
||||
# Build the release files for STM32 with bootloader
|
||||
- if [[ "$BOARD" =~ "multi4in1:STM32F1:multistm32f103c:upload_method=TxFlashMethod" ]]; then
|
||||
opt_enable CHECK_FOR_BOOTLOADER;
|
||||
opt_enable $ALL_PROTOCOLS;
|
||||
buildMulti;
|
||||
mv build/Multiprotocol.ino.bin ./binaries/Multi-STM_TXFLASH_INV-$TRAVIS_TAG.hex;
|
||||
mv build/Multiprotocol.ino.bin ./binaries/Multi-STM_TXFLASH_INV-$TRAVIS_TAG.bin;
|
||||
opt_disable MULTI_STATUS;
|
||||
opt_enable MULTI_TELEMETRY;
|
||||
buildMulti;
|
||||
mv build/Multiprotocol.ino.bin ./binaries/Multi-STM_TXFLASH_INV_OPENTX-$TRAVIS_TAG.hex;
|
||||
mv build/Multiprotocol.ino.bin ./binaries/Multi-STM_TXFLASH_INV_OPENTX-$TRAVIS_TAG.bin;
|
||||
fi
|
||||
deploy:
|
||||
provider: releases
|
||||
|
||||
@@ -7,40 +7,7 @@
|
||||
"help": {
|
||||
"online": "https://github.com/pascallanger/DIY-Multiprotocol-TX-Module"
|
||||
},
|
||||
"platforms": [{
|
||||
"name": "Multi 4-in-1 AVR Boards",
|
||||
"architecture": "avr",
|
||||
"version": "1.0.0",
|
||||
"category": "Contributed",
|
||||
"help": {
|
||||
"online": "https://github.com/pascallanger/DIY-Multiprotocol-TX-Module"
|
||||
},
|
||||
"url": "https://github.com/pascallanger/DIY-Multiprotocol-TX-Module-Boards/raw/master/archives/package_multi_4in1_board_v1.0.0.zip",
|
||||
"archiveFileName": "package_multi_4in1_board_v1.0.0.zip",
|
||||
"checksum": "SHA-256:3DE301E9FC3C8A81CB2CEDE3458A68C626A9A5C37A73FA9C85BE9D841935684D",
|
||||
"size": "3205",
|
||||
"boards": [{
|
||||
"name": "Multi 4-in-1 (Atmega328p, 3.3V, 16MHz)"
|
||||
}],
|
||||
"toolsDependencies": []
|
||||
},
|
||||
{
|
||||
"name": "Multi 4-in-1 AVR Boards",
|
||||
"architecture": "avr",
|
||||
"version": "1.0.1",
|
||||
"category": "Contributed",
|
||||
"help": {
|
||||
"online": "https://github.com/pascallanger/DIY-Multiprotocol-TX-Module"
|
||||
},
|
||||
"url": "https://github.com/pascallanger/DIY-Multiprotocol-TX-Module-Boards/raw/master/archives/package_multi_4in1_avr_board_v1.0.1.tar.gz",
|
||||
"archiveFileName": "package_multi_4in1_avr_board_v1.0.1.tar.gz",
|
||||
"checksum": "SHA-256:9bb29828476c141f5ef877e66b80ca969021d648acaf1ac5248676beb9ee3003",
|
||||
"size": "3201",
|
||||
"boards": [{
|
||||
"name": "Multi 4-in-1 (Atmega328p, 3.3V, 16MHz)"
|
||||
}],
|
||||
"toolsDependencies": []
|
||||
},
|
||||
"platforms": [
|
||||
{
|
||||
"name": "Multi 4-in-1 AVR Boards",
|
||||
"architecture": "avr",
|
||||
@@ -96,25 +63,58 @@
|
||||
"toolsDependencies": []
|
||||
},
|
||||
{
|
||||
"name": "Multi 4-in-1 STM32 Board",
|
||||
"architecture": "STM32F1",
|
||||
"version": "1.0.0",
|
||||
"name": "Multi 4-in-1 AVR Boards",
|
||||
"architecture": "avr",
|
||||
"version": "1.0.5",
|
||||
"category": "Contributed",
|
||||
"help": {
|
||||
"online": "https://github.com/pascallanger/DIY-Multiprotocol-TX-Module"
|
||||
},
|
||||
"url": "https://github.com/pascallanger/DIY-Multiprotocol-TX-Module-Boards/raw/master/archives/package_multi_4in1_stm32_board_v1.0.0.zip",
|
||||
"archiveFileName": "package_multi_4in1_stm32_board_v1.0.0.zip",
|
||||
"checksum": "SHA-256:7B661C6455F5AD7329E61EC297D4ADED9EF19F618E04E09A35A3C840977A56F5",
|
||||
"size": "10896168",
|
||||
"boards": [{
|
||||
"name": "Multi 4-in-1 (STM32F103C)"
|
||||
}],
|
||||
"toolsDependencies": [{
|
||||
"packager": "arduino",
|
||||
"name": "arm-none-eabi-gcc",
|
||||
"version": "4.8.3-2014q1"
|
||||
}]
|
||||
"url": "https://github.com/pascallanger/DIY-Multiprotocol-TX-Module-Boards/raw/master/archives/package_multi_4in1_avr_board_v1.0.5.tar.gz",
|
||||
"archiveFileName": "package_multi_4in1_avr_board_v1.0.5.tar.gz",
|
||||
"checksum": "SHA-256:0a4754d47cdbb49ca194b15835686331530ed9d36c0db093a29ae5f865e75421",
|
||||
"size": "169830",
|
||||
"boards": [
|
||||
{"name": "Multi 4-in-1 (Atmega328p, 3.3V, 16MHz)"},
|
||||
{"name": "Multi 4-in-1 (OrangeRX)"}
|
||||
],
|
||||
"toolsDependencies": []
|
||||
},
|
||||
{
|
||||
"name": "Multi 4-in-1 AVR Boards",
|
||||
"architecture": "avr",
|
||||
"version": "1.0.6",
|
||||
"category": "Contributed",
|
||||
"help": {
|
||||
"online": "https://github.com/pascallanger/DIY-Multiprotocol-TX-Module"
|
||||
},
|
||||
"url": "https://github.com/pascallanger/DIY-Multiprotocol-TX-Module-Boards/raw/master/archives/package_multi_4in1_avr_board_v1.0.6.tar.gz",
|
||||
"archiveFileName": "package_multi_4in1_avr_board_v1.0.6.tar.gz",
|
||||
"checksum": "SHA-256:4f4cf8820e30bf6c88f280514c67ee67b9dc6649f439597cfb8d0be3a5b13bf5",
|
||||
"size": "169819",
|
||||
"boards": [
|
||||
{"name": "Multi 4-in-1 (Atmega328p, 3.3V, 16MHz)"},
|
||||
{"name": "Multi 4-in-1 (OrangeRX)"}
|
||||
],
|
||||
"toolsDependencies": []
|
||||
},
|
||||
{
|
||||
"name": "Multi 4-in-1 AVR Boards",
|
||||
"architecture": "avr",
|
||||
"version": "1.0.7",
|
||||
"category": "Contributed",
|
||||
"help": {
|
||||
"online": "https://github.com/pascallanger/DIY-Multiprotocol-TX-Module"
|
||||
},
|
||||
"url": "https://github.com/pascallanger/DIY-Multiprotocol-TX-Module-Boards/raw/master/archives/package_multi_4in1_avr_board_v1.0.7.tar.gz",
|
||||
"archiveFileName": "package_multi_4in1_avr_board_v1.0.7.tar.gz",
|
||||
"checksum": "SHA-256:453c9999e433ed1bdda2ba2b12cb7cbba7b547591db969dc6b7efb941b61cf76",
|
||||
"size": "169825",
|
||||
"boards": [
|
||||
{"name": "Multi 4-in-1 (Atmega328p, 3.3V, 16MHz)"},
|
||||
{"name": "Multi 4-in-1 (OrangeRX)"}
|
||||
],
|
||||
"toolsDependencies": []
|
||||
},
|
||||
{
|
||||
"name": "Multi 4-in-1 STM32 Board",
|
||||
@@ -127,7 +127,7 @@
|
||||
"url": "https://github.com/pascallanger/DIY-Multiprotocol-TX-Module-Boards/raw/master/archives/package_multi_4in1_stm32_board_v1.0.1.tar.gz",
|
||||
"archiveFileName": "package_multi_4in1_stm32_board_v1.0.1.tar.gz",
|
||||
"checksum": "SHA-256:b522b5d3474308768c197a6897cad037fb54d6fac26c75678415a0908793bae3",
|
||||
"size": "10332106",
|
||||
"size": "10332875",
|
||||
"boards": [{
|
||||
"name": "Multi 4-in-1 (STM32F103C)"
|
||||
}],
|
||||
@@ -147,7 +147,7 @@
|
||||
},
|
||||
"url": "https://github.com/pascallanger/DIY-Multiprotocol-TX-Module-Boards/raw/master/archives/package_multi_4in1_stm32_board_v1.0.2.tar.gz",
|
||||
"archiveFileName": "package_multi_4in1_stm32_board_v1.0.2.tar.gz",
|
||||
"checksum": "SHA-256:26D21DBD2FE80680AC523B8BCA24B3ECF2C2016BAC626826D20B651E11278287",
|
||||
"checksum": "SHA-256:26d21dbd2fe80680ac523b8bca24b3ecf2c2016bac626826d20b651e11278287",
|
||||
"size": "10318646",
|
||||
"boards": [{
|
||||
"name": "Multi 4-in-1 (STM32F103C)"
|
||||
@@ -347,7 +347,70 @@
|
||||
"version": "4.8.3-2014q1"
|
||||
}]
|
||||
},
|
||||
{
|
||||
{
|
||||
"name": "Multi 4-in-1 STM32 Board",
|
||||
"architecture": "STM32F1",
|
||||
"version": "1.1.2",
|
||||
"category": "Contributed",
|
||||
"help": {
|
||||
"online": "https://github.com/pascallanger/DIY-Multiprotocol-TX-Module"
|
||||
},
|
||||
"url": "https://github.com/pascallanger/DIY-Multiprotocol-TX-Module-Boards/raw/master/archives/package_multi_4in1_stm32_board_v1.1.2.tar.gz",
|
||||
"archiveFileName": "package_multi_4in1_stm32_board_v1.1.2.tar.gz",
|
||||
"checksum": "SHA-256:debfdc14df3023045a2297bc99daf7104be75f21572fc5a4f57192ffae4028f0",
|
||||
"size": "10322776",
|
||||
"boards": [{
|
||||
"name": "Multi 4-in-1 (STM32F103C)"
|
||||
}],
|
||||
"toolsDependencies": [{
|
||||
"packager": "arduino",
|
||||
"name": "arm-none-eabi-gcc",
|
||||
"version": "4.8.3-2014q1"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"name": "Multi 4-in-1 STM32 Board",
|
||||
"architecture": "STM32F1",
|
||||
"version": "1.1.3",
|
||||
"category": "Contributed",
|
||||
"help": {
|
||||
"online": "https://github.com/pascallanger/DIY-Multiprotocol-TX-Module"
|
||||
},
|
||||
"url": "https://github.com/pascallanger/DIY-Multiprotocol-TX-Module-Boards/raw/master/archives/package_multi_4in1_stm32_board_v1.1.3.tar.gz",
|
||||
"archiveFileName": "package_multi_4in1_stm32_board_v1.1.3.tar.gz",
|
||||
"checksum": "SHA-256:6b9dceb033ccc31f37cebc4f025ddb862cd24a733e7c356ca2fa5719d595af89",
|
||||
"size": "10322145",
|
||||
"boards": [{
|
||||
"name": "Multi 4-in-1 (STM32F103C)"
|
||||
}],
|
||||
"toolsDependencies": [{
|
||||
"packager": "arduino",
|
||||
"name": "arm-none-eabi-gcc",
|
||||
"version": "4.8.3-2014q1"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"name": "Multi 4-in-1 STM32 Board",
|
||||
"architecture": "STM32F1",
|
||||
"version": "1.1.4",
|
||||
"category": "Contributed",
|
||||
"help": {
|
||||
"online": "https://github.com/pascallanger/DIY-Multiprotocol-TX-Module"
|
||||
},
|
||||
"url": "https://github.com/pascallanger/DIY-Multiprotocol-TX-Module-Boards/raw/master/archives/package_multi_4in1_stm32_board_v1.1.4.tar.gz",
|
||||
"archiveFileName": "package_multi_4in1_stm32_board_v1.1.4.tar.gz",
|
||||
"checksum": "SHA-256:16a83a3b4409cb55aead6593396979483996080634d214ae07c8a956db2480fb",
|
||||
"size": "10322152",
|
||||
"boards": [{
|
||||
"name": "Multi 4-in-1 (STM32F103C)"
|
||||
}],
|
||||
"toolsDependencies": [{
|
||||
"packager": "arduino",
|
||||
"name": "arm-none-eabi-gcc",
|
||||
"version": "4.8.3-2014q1"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"name": "Multi 4-in-1 OrangeRX Board - DEPRECATED, USE MULTI 4-IN-1 AVR BOARDS PACKAGE INSTEAD",
|
||||
"architecture": "orangerx",
|
||||
"version": "1.0.1",
|
||||
|
||||
@@ -87,8 +87,7 @@ static void AFHDS2A_update_telemetry()
|
||||
// max 7 sensors per packet
|
||||
#ifdef AFHDS2A_FW_TELEMETRY
|
||||
if (option & 0x80)
|
||||
{
|
||||
// forward telemetry to TX, skip rx and tx id to save space
|
||||
{// forward 0xAA and 0xAC telemetry to TX, skip rx and tx id to save space
|
||||
pkt[0]= TX_RSSI;
|
||||
debug("T=");
|
||||
for(int i=9;i < AFHDS2A_RXPACKET_SIZE; i++)
|
||||
@@ -96,38 +95,41 @@ static void AFHDS2A_update_telemetry()
|
||||
pkt[i-8]=packet[i];
|
||||
debug(" %02X",packet[i]);
|
||||
}
|
||||
debugln("");
|
||||
telemetry_link=2;
|
||||
debugln("");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#ifdef AFHDS2A_HUB_TELEMETRY
|
||||
for(uint8_t sensor=0; sensor<7; sensor++)
|
||||
{
|
||||
// Send FrSkyD telemetry to TX
|
||||
uint8_t index = 9+(4*sensor);
|
||||
switch(packet[index])
|
||||
if(packet[0]==0xAA)
|
||||
{ // 0xAA Normal telemetry, 0xAC Extended telemetry not decoded here
|
||||
for(uint8_t sensor=0; sensor<7; sensor++)
|
||||
{
|
||||
case AFHDS2A_SENSOR_RX_VOLTAGE:
|
||||
//v_lipo1 = packet[index+3]<<8 | packet[index+2];
|
||||
v_lipo1 = packet[index+2];
|
||||
telemetry_link=1;
|
||||
break;
|
||||
case AFHDS2A_SENSOR_A3_VOLTAGE:
|
||||
v_lipo2 = (packet[index+3]<<5) | (packet[index+2]>>3); // allows to read voltage up to 4S
|
||||
telemetry_link=1;
|
||||
break;
|
||||
case AFHDS2A_SENSOR_RX_ERR_RATE:
|
||||
RX_LQI=packet[index+2];
|
||||
break;
|
||||
case AFHDS2A_SENSOR_RX_RSSI:
|
||||
RX_RSSI = -packet[index+2];
|
||||
break;
|
||||
case 0xff:
|
||||
return;
|
||||
/*default:
|
||||
// unknown sensor ID
|
||||
break;*/
|
||||
// Send FrSkyD telemetry to TX
|
||||
uint8_t index = 9+(4*sensor);
|
||||
switch(packet[index])
|
||||
{
|
||||
case AFHDS2A_SENSOR_RX_VOLTAGE:
|
||||
//v_lipo1 = packet[index+3]<<8 | packet[index+2];
|
||||
v_lipo1 = packet[index+2];
|
||||
telemetry_link=1;
|
||||
break;
|
||||
case AFHDS2A_SENSOR_A3_VOLTAGE:
|
||||
v_lipo2 = (packet[index+3]<<5) | (packet[index+2]>>3); // allows to read voltage up to 4S
|
||||
telemetry_link=1;
|
||||
break;
|
||||
case AFHDS2A_SENSOR_RX_ERR_RATE:
|
||||
RX_LQI=packet[index+2];
|
||||
break;
|
||||
case AFHDS2A_SENSOR_RX_RSSI:
|
||||
RX_RSSI = -packet[index+2];
|
||||
break;
|
||||
case 0xff: // end of data
|
||||
return;
|
||||
/*default:
|
||||
// unknown sensor ID
|
||||
break;*/
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -271,6 +273,11 @@ uint16_t ReadAFHDS2A()
|
||||
}
|
||||
}
|
||||
packet_count++;
|
||||
if(IS_BIND_DONE)
|
||||
{ // exit bind if asked to do so from the GUI
|
||||
phase = AFHDS2A_BIND4;
|
||||
return 3850;
|
||||
}
|
||||
phase |= AFHDS2A_WAIT_WRITE;
|
||||
return 1700;
|
||||
case AFHDS2A_BIND1|AFHDS2A_WAIT_WRITE:
|
||||
@@ -328,25 +335,26 @@ uint16_t ReadAFHDS2A()
|
||||
if(!(A7105_ReadReg(A7105_00_MODE) & (1<<5 | 1<<6)) && data_rx==1)
|
||||
{ // RX+FECF+CRCF Ok
|
||||
A7105_ReadData(AFHDS2A_RXPACKET_SIZE);
|
||||
if(packet[0] == 0xaa)
|
||||
{
|
||||
if(packet[9] == 0xfc)
|
||||
packet_type=AFHDS2A_PACKET_SETTINGS; // RX is asking for settings
|
||||
else
|
||||
if(packet[0] == 0xAA && packet[9] == 0xFC)
|
||||
packet_type=AFHDS2A_PACKET_SETTINGS; // RX is asking for settings
|
||||
else
|
||||
if(packet[0] == 0xAA || packet[0] == 0xAC)
|
||||
{
|
||||
#ifdef AFHDS2A_LQI_CH
|
||||
for(uint8_t sensor=0; sensor<7; sensor++)
|
||||
{//read LQI value for RX output
|
||||
uint8_t index = 9+(4*sensor);
|
||||
if(packet[index]==AFHDS2A_SENSOR_RX_ERR_RATE)
|
||||
RX_LQI=packet[index+2];
|
||||
}
|
||||
#endif
|
||||
#if defined(AFHDS2A_FW_TELEMETRY) || defined(AFHDS2A_HUB_TELEMETRY)
|
||||
AFHDS2A_update_telemetry();
|
||||
#endif
|
||||
if(!memcmp(&packet[1], rx_tx_addr, 4))
|
||||
{ // Validate TX address
|
||||
#ifdef AFHDS2A_LQI_CH
|
||||
for(uint8_t sensor=0; sensor<7; sensor++)
|
||||
{//read LQI value for RX output
|
||||
uint8_t index = 9+(4*sensor);
|
||||
if(packet[index]==AFHDS2A_SENSOR_RX_ERR_RATE)
|
||||
RX_LQI=packet[index+2];
|
||||
}
|
||||
#endif
|
||||
#if defined(AFHDS2A_FW_TELEMETRY) || defined(AFHDS2A_HUB_TELEMETRY)
|
||||
AFHDS2A_update_telemetry();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
packet_counter++;
|
||||
phase |= AFHDS2A_WAIT_WRITE;
|
||||
|
||||
@@ -42,6 +42,7 @@ enum {
|
||||
#define BUGSMINI_CH_SW_PICTURE CH8_SW
|
||||
#define BUGSMINI_CH_SW_VIDEO CH9_SW
|
||||
#define BUGSMINI_CH_SW_LED CH10_SW
|
||||
#define BUGSMINI_CH_SW_ALTHOLD CH11_SW
|
||||
|
||||
// flags packet[12]
|
||||
#define BUGSMINI_FLAG_FLIP 0x08 // automatic flip
|
||||
@@ -54,6 +55,7 @@ enum {
|
||||
#define BUGSMINI_FLAG_ARM 0x40 // arm (toggle to turn on motors)
|
||||
#define BUGSMINI_FLAG_DISARM 0x20 // disarm (toggle to turn off motors)
|
||||
#define BUGSMINI_FLAG_ANGLE 0x02 // angle/acro mode (set is angle mode)
|
||||
#define BUGSMINI_FLAG_ALTHOLD 0x04 // angle/altitude hold mode (set is altitude mode)
|
||||
|
||||
static void __attribute__((unused)) BUGSMINI_init()
|
||||
{
|
||||
@@ -133,7 +135,7 @@ static void __attribute__((unused)) BUGSMINI_send_packet(uint8_t bind)
|
||||
packet[10]= (((rudder / 5) >> 1) + 7) // dynamic trim 0x07 - 0x39
|
||||
| (rudder << 7);
|
||||
packet[11]= 0x40 | (throttle << 7);
|
||||
packet[12]= 0x80 | ((packet[12] ^ 0x40) & 0x40) // bugs 3 H doesn't have 0x80 ?
|
||||
packet[12]= 0x80 | ((packet[12] ^ 0x40) & 0x40)
|
||||
| BUGSMINI_FLAG_MODE
|
||||
| GET_FLAG(BUGSMINI_CH_SW_PICTURE, BUGSMINI_FLAG_PICTURE)
|
||||
| GET_FLAG(BUGSMINI_CH_SW_VIDEO, BUGSMINI_FLAG_VIDEO);
|
||||
@@ -141,10 +143,11 @@ static void __attribute__((unused)) BUGSMINI_send_packet(uint8_t bind)
|
||||
packet[12] |= GET_FLAG(BUGSMINI_CH_SW_FLIP, BUGSMINI_FLAG_FLIP);
|
||||
packet[13] = arm_flags
|
||||
| GET_FLAG(BUGSMINI_CH_SW_LED, BUGSMINI_FLAG_LED)
|
||||
| GET_FLAG(BUGSMINI_CH_SW_ALTHOLD, BUGSMINI_FLAG_ALTHOLD)
|
||||
| GET_FLAG(BUGSMINI_CH_SW_ANGLE, BUGSMINI_FLAG_ANGLE);
|
||||
|
||||
// BUGS3H althold -> BUGSMINI_FLAG_ALTHOLD|BUGSMINI_FLAG_ANGLE , angle -> 0
|
||||
packet[14] = 0;
|
||||
packet[15] = 0; // 0x53 on bugs 3 H ?
|
||||
packet[15] = 0; // a lot of 0x53 and some 0x52 on bugs 3H
|
||||
}
|
||||
uint8_t checksum = 0x6d;
|
||||
for(uint8_t i=1; i < BUGSMINI_TX_PAYLOAD_SIZE; i++)
|
||||
@@ -309,8 +312,8 @@ uint16_t BUGSMINI_callback()
|
||||
case BUGSMINI_DATA2:
|
||||
// switch to RX mode
|
||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||
NRF24L01_SetTxRxMode(RX_EN);
|
||||
NRF24L01_FlushRx();
|
||||
NRF24L01_SetTxRxMode(RX_EN);
|
||||
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO)
|
||||
| _BV(NRF24L01_00_PWR_UP) | _BV(NRF24L01_00_PRIM_RX));
|
||||
phase = BUGSMINI_DATA1;
|
||||
|
||||
@@ -62,7 +62,7 @@ static void __attribute__((unused)) BAYANG_send_packet(uint8_t bind)
|
||||
else
|
||||
#else
|
||||
if(option & BAYANG_OPTION_FLAG_ANALOGAUX)
|
||||
packet[0]= 0xA2; // analog aux is enabled
|
||||
packet[0]= 0xA2; // analog aux is enabled
|
||||
else
|
||||
#endif
|
||||
packet[0]= 0xA4;
|
||||
@@ -80,6 +80,10 @@ static void __attribute__((unused)) BAYANG_send_packet(uint8_t bind)
|
||||
packet[10] = 0x30;
|
||||
packet[11] = 0x01;
|
||||
break;
|
||||
case DHD_D4:
|
||||
packet[10] = 0xC8;
|
||||
packet[11] = 0x99;
|
||||
break;
|
||||
default:
|
||||
packet[10] = rx_tx_addr[0]; // txid[0]
|
||||
packet[11] = rx_tx_addr[1]; // txid[1]
|
||||
@@ -106,7 +110,7 @@ static void __attribute__((unused)) BAYANG_send_packet(uint8_t bind)
|
||||
packet[1] = convert_channel_8b(CH14);
|
||||
}
|
||||
else
|
||||
packet[1] = 0xFA; // normal mode is 0xf7, expert 0xfa
|
||||
packet[1] = 0xFA; // normal mode is 0xF7, expert 0xFa , D4 normal is 0xF4
|
||||
|
||||
//Flags packet[2]
|
||||
packet[2] = 0x00;
|
||||
@@ -164,11 +168,14 @@ static void __attribute__((unused)) BAYANG_send_packet(uint8_t bind)
|
||||
packet[12] = 0xE0;
|
||||
packet[13] = 0x2E;
|
||||
break;
|
||||
case DHD_D4:
|
||||
packet[12] = 0x37; //0x17 during bind
|
||||
packet[13] = 0xED;
|
||||
break;
|
||||
default:
|
||||
packet[12] = rx_tx_addr[2]; // txid[2]
|
||||
if (option & BAYANG_OPTION_FLAG_ANALOGAUX)
|
||||
{
|
||||
// Analog aux channel 2 (channel 15)
|
||||
{ // Analog aux channel 2 (channel 15)
|
||||
packet[13] = convert_channel_8b(CH15);
|
||||
}
|
||||
else
|
||||
@@ -325,7 +332,10 @@ uint16_t BAYANG_callback()
|
||||
static void __attribute__((unused)) BAYANG_initialize_txid()
|
||||
{
|
||||
//Could be using txid[0..2] but using rx_tx_addr everywhere instead...
|
||||
hopping_frequency[0]=0;
|
||||
if(sub_protocol==DHD_D4)
|
||||
hopping_frequency[0]=(rx_tx_addr[2]&0x07)|0x01;
|
||||
else
|
||||
hopping_frequency[0]=0;
|
||||
hopping_frequency[1]=(rx_tx_addr[3]&0x1F)+0x10;
|
||||
hopping_frequency[2]=hopping_frequency[1]+0x20;
|
||||
hopping_frequency[3]=hopping_frequency[2]+0x20;
|
||||
|
||||
@@ -284,10 +284,11 @@ static void __attribute__((unused))BUGS_set_radio_data()
|
||||
{
|
||||
offset=BUGS_NUM_RFCHAN;
|
||||
// Read radio_id from EEPROM
|
||||
radio_id=0;
|
||||
uint8_t base_adr=BUGS_EEPROM_OFFSET+RX_num*4;
|
||||
for(uint8_t i=0; i<4; i++)
|
||||
radio_id|=eeprom_read_byte((EE_ADDR)(base_adr+i))<<(i*8);
|
||||
uint8_t base_adr=BUGS_EEPROM_OFFSET+RX_num*2;
|
||||
uint16_t rxid=0;
|
||||
for(uint8_t i=0; i<2; i++)
|
||||
rxid|=eeprom_read_byte((EE_ADDR)(base_adr+i))<<(i*8);
|
||||
radio_id = BUGS_rxid_to_radioid(rxid);
|
||||
}
|
||||
A7105_WriteID(radio_id);
|
||||
|
||||
@@ -318,7 +319,6 @@ uint16_t ReadBUGS(void)
|
||||
{
|
||||
uint8_t mode, base_adr;
|
||||
uint16_t rxid;
|
||||
uint32_t radio_id;
|
||||
uint16_t start;
|
||||
|
||||
// keep frequency tuning updated
|
||||
@@ -374,10 +374,9 @@ uint16_t ReadBUGS(void)
|
||||
BIND_DONE;
|
||||
// set radio_id
|
||||
rxid = (packet[1] << 8) + packet[2];
|
||||
radio_id = BUGS_rxid_to_radioid(rxid);
|
||||
base_adr=BUGS_EEPROM_OFFSET+RX_num*4;
|
||||
for(uint8_t i=0; i<4; i++)
|
||||
eeprom_write_byte((EE_ADDR)(base_adr+i),radio_id>>(i*8)); // Save radio_id in EEPROM
|
||||
base_adr=BUGS_EEPROM_OFFSET+RX_num*2;
|
||||
for(uint8_t i=0; i<2; i++)
|
||||
eeprom_write_byte((EE_ADDR)(base_adr+i),rxid>>(i*8)); // Save rxid in EEPROM
|
||||
BUGS_set_radio_data();
|
||||
phase = BUGS_DATA_1;
|
||||
packet_count = 0;
|
||||
@@ -437,11 +436,11 @@ uint16_t ReadBUGS(void)
|
||||
|
||||
uint16_t initBUGS(void)
|
||||
{
|
||||
uint32_t radio_id=0;
|
||||
uint8_t base_adr=BUGS_EEPROM_OFFSET+RX_num*4;
|
||||
for(uint8_t i=0; i<4; i++)
|
||||
radio_id|=eeprom_read_byte((EE_ADDR)(base_adr+i))<<(i*8);
|
||||
if(radio_id==0xffffffff)
|
||||
uint16_t rxid=0;
|
||||
uint8_t base_adr=BUGS_EEPROM_OFFSET+RX_num*2;
|
||||
for(uint8_t i=0; i<2; i++)
|
||||
rxid|=eeprom_read_byte((EE_ADDR)(base_adr+i))<<(i*8);
|
||||
if(rxid==0xffff)
|
||||
BIND_IN_PROGRESS;
|
||||
|
||||
BUGS_set_radio_data();
|
||||
|
||||
@@ -109,8 +109,6 @@ static uint8_t tx_payload_len = 0; // Length of the packet stored in packet
|
||||
static uint8_t rx_payload_len = 0; // Length of the packet stored in rx_packet
|
||||
static uint8_t rx_packet[MAX_PACKET_SIZE]; // For reading in ACK payloads
|
||||
|
||||
static uint16_t cflie_counter;
|
||||
static uint32_t packet_counter;
|
||||
static uint8_t data_rate;
|
||||
|
||||
enum {
|
||||
@@ -194,8 +192,6 @@ static void send_packet()
|
||||
// Transmit the payload
|
||||
NRF24L01_WritePayload(packet, tx_payload_len);
|
||||
|
||||
++packet_counter;
|
||||
|
||||
// // Check and adjust transmission power.
|
||||
NRF24L01_SetPower();
|
||||
}
|
||||
@@ -256,7 +252,6 @@ static void send_search_packet()
|
||||
|
||||
NRF24L01_WritePayload(buf, sizeof(buf));
|
||||
|
||||
++packet_counter;
|
||||
}
|
||||
|
||||
// Frac 16.16
|
||||
@@ -782,7 +777,6 @@ static uint16_t cflie_callback()
|
||||
break;
|
||||
case PKT_TIMEOUT:
|
||||
send_search_packet();
|
||||
cflie_counter = CFLIE_BIND_COUNT;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -152,6 +152,17 @@ void CYRF_SetPower(uint8_t val)
|
||||
CYRF_WriteRegister(CYRF_03_TX_CFG,power);
|
||||
prev_power=power;
|
||||
}
|
||||
|
||||
#ifdef USE_CYRF6936_CH15_TUNING
|
||||
static uint16_t Channel15=1024;
|
||||
if(Channel15!=Channel_data[CH15])
|
||||
{ // adjust frequency
|
||||
Channel15=Channel_data[CH15]+0x155; // default value is 0x555 = 0x400 + 0x155
|
||||
CYRF_WriteRegister(CYRF_1B_TX_OFFSET_LSB, Channel15&0xFF);
|
||||
CYRF_WriteRegister(CYRF_1C_TX_OFFSET_MSB, Channel15>>8);
|
||||
Channel15-=0x155;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -56,7 +56,21 @@ void InitChannel()
|
||||
/************************/
|
||||
/** Convert routines **/
|
||||
/************************/
|
||||
// Revert a channel and store it
|
||||
// Convert channel 8b with limit and deadband
|
||||
uint8_t convert_channel_8b_limit_deadband(uint8_t num,uint8_t min,uint8_t mid, uint8_t max, uint8_t deadband)
|
||||
{
|
||||
uint16_t val=limit_channel_100(num); // 204<->1844
|
||||
uint16_t db_low=CHANNEL_MID-deadband, db_high=CHANNEL_MID+deadband; // 1024+-deadband
|
||||
if(val>=db_low && val<=db_high)
|
||||
return mid;
|
||||
else if(val<db_low)
|
||||
val=min+(val-CHANNEL_MIN_100)*(mid-min)/(db_low-CHANNEL_MIN_100);
|
||||
else
|
||||
val=mid+(val-db_high)*(max-mid)/(CHANNEL_MAX_100-1-db_high);
|
||||
return val;
|
||||
}
|
||||
|
||||
// Reverse a channel and store it
|
||||
void reverse_channel(uint8_t num)
|
||||
{
|
||||
uint16_t val=2048-Channel_data[num];
|
||||
@@ -67,7 +81,7 @@ void reverse_channel(uint8_t num)
|
||||
uint16_t convert_channel_ppm(uint8_t num)
|
||||
{
|
||||
uint16_t val=Channel_data[num];
|
||||
return (((val<<2)+val)>>3)+860; //value range 860<->2140 -125%<->+125%
|
||||
return (((val<<2)+val)>>3)+860; //value range 860<->2140 -125%<->+125%
|
||||
}
|
||||
// Channel value 100% is converted to 10bit values 0<->1023
|
||||
uint16_t convert_channel_10b(uint8_t num)
|
||||
|
||||
@@ -42,7 +42,6 @@ enum {
|
||||
|
||||
//
|
||||
uint8_t sop_col;
|
||||
uint8_t DSM_num_ch=0;
|
||||
uint8_t ch_map[14];
|
||||
const uint8_t PROGMEM DSM_ch_map_progmem[][14] = {
|
||||
//22+11ms for 4..7 channels
|
||||
@@ -189,17 +188,17 @@ static void __attribute__((unused)) DSM_build_bind_packet()
|
||||
packet[8] = sum >> 8;
|
||||
packet[9] = sum & 0xff;
|
||||
packet[10] = 0x01; //???
|
||||
packet[11] = DSM_num_ch;
|
||||
packet[11] = num_ch;
|
||||
|
||||
if (sub_protocol==DSM2_22)
|
||||
packet[12]=DSM_num_ch<8?0x01:0x02; // DSM2/1024 1 or 2 packets depending on the number of channels
|
||||
packet[12]=num_ch<8?0x01:0x02; // DSM2/1024 1 or 2 packets depending on the number of channels
|
||||
if(sub_protocol==DSM2_11)
|
||||
packet[12]=0x12; // DSM2/2048 2 packets
|
||||
if(sub_protocol==DSMX_22)
|
||||
#if defined DSM_TELEMETRY
|
||||
packet[12] = 0xb2; // DSMX/2048 2 packets
|
||||
#else
|
||||
packet[12] = DSM_num_ch<8? 0xa2 : 0xb2; // DSMX/2048 1 or 2 packets depending on the number of channels
|
||||
packet[12] = num_ch<8? 0xa2 : 0xb2; // DSMX/2048 1 or 2 packets depending on the number of channels
|
||||
#endif
|
||||
if(sub_protocol==DSMX_11 || sub_protocol==DSM_AUTO) // Force DSMX/1024 in mode Auto
|
||||
packet[12]=0xb2; // DSMX/1024 2 packets
|
||||
@@ -229,15 +228,15 @@ static void __attribute__((unused)) DSM_update_channels()
|
||||
{
|
||||
prev_option=option;
|
||||
if(sub_protocol==DSM_AUTO)
|
||||
DSM_num_ch=12; // Force 12 channels in mode Auto
|
||||
num_ch=12; // Force 12 channels in mode Auto
|
||||
else
|
||||
DSM_num_ch=option;
|
||||
if(DSM_num_ch<4 || DSM_num_ch>12)
|
||||
DSM_num_ch=6; // Default to 6 channels if invalid choice...
|
||||
num_ch=option;
|
||||
if(num_ch<4 || num_ch>12)
|
||||
num_ch=6; // Default to 6 channels if invalid choice...
|
||||
|
||||
// Create channel map based on number of channels and refresh rate
|
||||
uint8_t idx=DSM_num_ch-4;
|
||||
if(DSM_num_ch>7 && DSM_num_ch<11 && (sub_protocol==DSM2_11 || sub_protocol==DSMX_11))
|
||||
uint8_t idx=num_ch-4;
|
||||
if(num_ch>7 && num_ch<11 && (sub_protocol==DSM2_11 || sub_protocol==DSMX_11))
|
||||
idx+=5; // In 11ms mode change index only for channels 8..10
|
||||
for(uint8_t i=0;i<14;i++)
|
||||
ch_map[i]=pgm_read_byte_near(&DSM_ch_map_progmem[idx][i]);
|
||||
@@ -376,9 +375,13 @@ static uint8_t __attribute__((unused)) DSM_Check_RX_packet()
|
||||
|
||||
uint16_t ReadDsm()
|
||||
{
|
||||
#define DSM_CH1_CH2_DELAY 4010 // Time between write of channel 1 and channel 2
|
||||
#define DSM_WRITE_DELAY 1950 // Time after write to verify write complete
|
||||
#define DSM_READ_DELAY 600 // Time before write to check read phase, and switch channels. Was 400 but 600 seems what the 328p needs to read a packet
|
||||
#define DSM_CH1_CH2_DELAY 4010 // Time between write of channel 1 and channel 2
|
||||
#ifdef STM32_BOARD
|
||||
#define DSM_WRITE_DELAY 1500 // Time after write to verify write complete
|
||||
#else
|
||||
#define DSM_WRITE_DELAY 1950 // Time after write to verify write complete
|
||||
#endif
|
||||
#define DSM_READ_DELAY 600 // Time before write to check read phase, and switch channels. Was 400 but 600 seems what the 328p needs to read a packet
|
||||
#if defined DSM_TELEMETRY
|
||||
uint8_t rx_phase;
|
||||
uint8_t len;
|
||||
@@ -465,6 +468,7 @@ uint16_t ReadDsm()
|
||||
while ((uint8_t)((uint8_t)micros()-(uint8_t)start) < 100) // Wait max 100µs, max I've seen is 50µs
|
||||
if((CYRF_ReadRegister(CYRF_02_TX_CTRL) & 0x80) == 0x00)
|
||||
break;
|
||||
|
||||
if(phase==DSM_CH1_CHECK_A || phase==DSM_CH1_CHECK_B)
|
||||
{
|
||||
#if defined DSM_TELEMETRY
|
||||
@@ -505,7 +509,7 @@ uint16_t ReadDsm()
|
||||
telemetry_link=1;
|
||||
}
|
||||
CYRF_WriteRegister(CYRF_29_RX_ABORT, 0x20); // Abort RX operation
|
||||
if (phase == DSM_CH2_READ_A && (sub_protocol==DSM2_22 || sub_protocol==DSMX_22) && DSM_num_ch < 8) // 22ms mode
|
||||
if (phase == DSM_CH2_READ_A && (sub_protocol==DSM2_22 || sub_protocol==DSMX_22) && num_ch < 8) // 22ms mode
|
||||
{
|
||||
CYRF_SetTxRxMode(RX_EN); // Force end state read
|
||||
CYRF_WriteRegister(CYRF_29_RX_ABORT, 0x00); // Clear abort RX operation
|
||||
@@ -526,7 +530,7 @@ uint16_t ReadDsm()
|
||||
DSM_set_sop_data_crc();
|
||||
if (phase == DSM_CH2_CHECK_A)
|
||||
{
|
||||
if(DSM_num_ch > 7 || sub_protocol==DSM2_11 || sub_protocol==DSMX_11)
|
||||
if(num_ch > 7 || sub_protocol==DSM2_11 || sub_protocol==DSMX_11)
|
||||
phase = DSM_CH1_WRITE_B; //11ms mode or upper to transmit change from CH2_CHECK_A to CH1_WRITE_A
|
||||
else
|
||||
{ //Normal mode 22ms
|
||||
|
||||
@@ -17,8 +17,6 @@
|
||||
|
||||
#include "iface_cyrf6936.h"
|
||||
|
||||
#define DEVO_NUM_CHANNELS 8
|
||||
|
||||
//For Debug
|
||||
//#define NO_SCRAMBLE
|
||||
|
||||
@@ -93,7 +91,7 @@ static void __attribute__((unused)) DEVO_add_pkt_suffix()
|
||||
|
||||
static void __attribute__((unused)) DEVO_build_beacon_pkt(uint8_t upper)
|
||||
{
|
||||
packet[0] = (DEVO_NUM_CHANNELS << 4) | 0x07;
|
||||
packet[0] = (num_ch << 4) | 0x07;
|
||||
uint8_t max = 8, offset = 0, enable = 0;
|
||||
if (upper)
|
||||
{
|
||||
@@ -105,7 +103,7 @@ static void __attribute__((unused)) DEVO_build_beacon_pkt(uint8_t upper)
|
||||
{
|
||||
#ifdef FAILSAFE_ENABLE
|
||||
uint16_t failsafe=Failsafe_data[CH_EATR[i+offset]];
|
||||
if(i + offset < DEVO_NUM_CHANNELS && failsafe!=FAILSAFE_CHANNEL_HOLD && IS_FAILSAFE_VALUES_on)
|
||||
if(i + offset < num_ch && failsafe!=FAILSAFE_CHANNEL_HOLD && IS_FAILSAFE_VALUES_on)
|
||||
{
|
||||
enable |= 0x80 >> i;
|
||||
packet[i+1] = ((failsafe*25)>>8)-100;
|
||||
@@ -122,7 +120,7 @@ static void __attribute__((unused)) DEVO_build_beacon_pkt(uint8_t upper)
|
||||
|
||||
static void __attribute__((unused)) DEVO_build_bind_pkt()
|
||||
{
|
||||
packet[0] = (DEVO_NUM_CHANNELS << 4) | 0x0a;
|
||||
packet[0] = (num_ch << 4) | 0x0a;
|
||||
packet[1] = bind_counter & 0xff;
|
||||
packet[2] = (bind_counter >> 8);
|
||||
packet[3] = *hopping_frequency_ptr;
|
||||
@@ -144,7 +142,7 @@ static void __attribute__((unused)) DEVO_build_data_pkt()
|
||||
{
|
||||
static uint8_t ch_idx=0;
|
||||
|
||||
packet[0] = (DEVO_NUM_CHANNELS << 4) | (0x0b + ch_idx);
|
||||
packet[0] = (num_ch << 4) | (0x0b + ch_idx);
|
||||
uint8_t sign = 0x0b;
|
||||
for (uint8_t i = 0; i < 4; i++)
|
||||
{
|
||||
@@ -159,7 +157,7 @@ static void __attribute__((unused)) DEVO_build_data_pkt()
|
||||
}
|
||||
packet[9] = sign;
|
||||
ch_idx++;
|
||||
if (ch_idx * 4 >= DEVO_NUM_CHANNELS)
|
||||
if (ch_idx * 4 >= num_ch)
|
||||
ch_idx = 0;
|
||||
DEVO_add_pkt_suffix();
|
||||
}
|
||||
@@ -258,7 +256,7 @@ static void __attribute__((unused)) DEVO_BuildPacket()
|
||||
}
|
||||
break;
|
||||
case DEVO_BOUND_10:
|
||||
DEVO_build_beacon_pkt(DEVO_NUM_CHANNELS > 8 ? failsafe_pkt : 0);
|
||||
DEVO_build_beacon_pkt(num_ch > 8 ? failsafe_pkt : 0);
|
||||
failsafe_pkt = failsafe_pkt ? 0 : 1;
|
||||
DEVO_scramble_pkt();
|
||||
phase = DEVO_BOUND_1;
|
||||
@@ -301,6 +299,24 @@ uint16_t devo_callback()
|
||||
|
||||
uint16_t DevoInit()
|
||||
{
|
||||
switch(sub_protocol)
|
||||
{
|
||||
case 1:
|
||||
num_ch=10;
|
||||
break;
|
||||
case 2:
|
||||
num_ch=12;
|
||||
break;
|
||||
case 3:
|
||||
num_ch=6;
|
||||
break;
|
||||
case 4:
|
||||
num_ch=7;
|
||||
break;
|
||||
default:
|
||||
num_ch=8;
|
||||
break;
|
||||
}
|
||||
DEVO_cyrf_init();
|
||||
CYRF_GetMfgData(cyrfmfg_id);
|
||||
CYRF_SetTxRxMode(TX_EN);
|
||||
|
||||
@@ -16,18 +16,20 @@ Multiprotocol is distributed in the hope that it will be useful,
|
||||
|
||||
#if defined(GD00X_NRF24L01_INO)
|
||||
|
||||
#include "iface_nrf24l01.h"
|
||||
#include "iface_xn297l.h"
|
||||
|
||||
//#define FORCE_GD00X_ORIGINAL_ID
|
||||
|
||||
#define GD00X_INITIAL_WAIT 500
|
||||
#define GD00X_PACKET_PERIOD 3500
|
||||
#define GD00X_RF_BIND_CHANNEL 2
|
||||
#define GD00X_RF_NUM_CHANNELS 4
|
||||
#define GD00X_PAYLOAD_SIZE 15
|
||||
#define GD00X_BIND_COUNT 857 //3sec
|
||||
|
||||
#define GD00X_V2_BIND_PACKET_PERIOD 5110
|
||||
#define GD00X_V2_RF_BIND_CHANNEL 0x43
|
||||
#define GD00X_V2_RF_NUM_CHANNELS 2
|
||||
#define GD00X_V2_PAYLOAD_SIZE 6
|
||||
|
||||
// flags going to packet[11]
|
||||
@@ -55,7 +57,7 @@ static void __attribute__((unused)) GD00X_send_packet()
|
||||
channel=convert_channel_ppm(CH5); // TRIM
|
||||
packet[9 ] = channel;
|
||||
packet[10] = channel>>8;
|
||||
packet[11] = GD00X_FLAG_DR // Force high rate
|
||||
packet[11] = GET_FLAG(!CH7_SW, GD00X_FLAG_DR)
|
||||
| GET_FLAG(CH6_SW, GD00X_FLAG_LIGHT);
|
||||
packet[12] = 0x00;
|
||||
packet[13] = 0x00;
|
||||
@@ -70,23 +72,14 @@ static void __attribute__((unused)) GD00X_send_packet()
|
||||
{
|
||||
packet[0]=convert_channel_16b_limit(THROTTLE,0,100); // 0..100
|
||||
|
||||
// Deadband is needed on aileron
|
||||
uint16_t aileron=limit_channel_100(AILERON); // 204<->1844
|
||||
#define GD00X_V2_DB_MIN 1024-40
|
||||
#define GD00X_V2_DB_MAX 1024+40
|
||||
if(aileron>GD00X_V2_DB_MIN && aileron<GD00X_V2_DB_MAX)
|
||||
packet[1]=0x20; // Send the channel centered
|
||||
else // Ail: 0x3F..0x20..0x00
|
||||
if(aileron>GD00X_V2_DB_MAX)
|
||||
packet[1]=0x1F-((aileron-GD00X_V2_DB_MAX)*(0x20)/(CHANNEL_MAX_100+1-GD00X_V2_DB_MAX)); // 1F..00
|
||||
else
|
||||
packet[1]=0x3F-((aileron-CHANNEL_MIN_100)*(0x1F)/(GD00X_V2_DB_MIN-CHANNEL_MIN_100)); // 3F..21
|
||||
|
||||
// Deadband is needed on aileron, 40 gives +-6%
|
||||
packet[1]=convert_channel_8b_limit_deadband(AILERON,0x3F,0x20,0x00,40); // Aileron: 3F..20..00
|
||||
// Trims must be in a seperate channel for this model
|
||||
packet[2]=0x3F-(convert_channel_8b(CH5)>>2); // Trim: 0x3F..0x20..0x00
|
||||
|
||||
uint8_t seq=((packet_count*3)/7)%5;
|
||||
packet[4]=seq | GD00X_V2_FLAG_DR;
|
||||
packet[4]=seq
|
||||
| GET_FLAG(!CH7_SW, GD00X_V2_FLAG_DR);
|
||||
|
||||
if(CH6_SW!=prev_CH6)
|
||||
{ // LED switch is temporary
|
||||
@@ -118,42 +111,31 @@ static void __attribute__((unused)) GD00X_send_packet()
|
||||
packet[5]='D';
|
||||
}
|
||||
|
||||
// Power on, TX mode, CRC enabled
|
||||
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
||||
if(IS_BIND_DONE)
|
||||
{
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no]);
|
||||
XN297L_Hopping(hopping_frequency_no);
|
||||
if(sub_protocol==GD_V1)
|
||||
{
|
||||
hopping_frequency_no++;
|
||||
hopping_frequency_no &= 3; // 4 RF channels
|
||||
hopping_frequency_no &= GD00X_RF_NUM_CHANNELS-1; // 4 RF channels
|
||||
}
|
||||
}
|
||||
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||
NRF24L01_FlushTx();
|
||||
XN297_WritePayload(packet, packet_length);
|
||||
XN297L_WritePayload(packet, packet_length);
|
||||
|
||||
NRF24L01_SetPower(); // Set tx_power
|
||||
XN297L_SetPower(); // Set tx_power
|
||||
XN297L_SetFreqOffset(); // Set frequency offset
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) GD00X_init()
|
||||
{
|
||||
NRF24L01_Initialize();
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
XN297L_Init();
|
||||
if(sub_protocol==GD_V1)
|
||||
XN297_SetTXAddr((uint8_t*)"\xcc\xcc\xcc\xcc\xcc", 5);
|
||||
XN297L_SetTXAddr((uint8_t*)"\xcc\xcc\xcc\xcc\xcc", 5);
|
||||
else
|
||||
XN297_SetTXAddr((uint8_t*)"GDKNx", 5);
|
||||
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, sub_protocol==GD_V1?GD00X_RF_BIND_CHANNEL:GD00X_V2_RF_BIND_CHANNEL); // Bind channel
|
||||
NRF24L01_FlushTx();
|
||||
NRF24L01_FlushRx();
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
|
||||
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowldgement on all data pipes
|
||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 only
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_250K); // 250Kbps
|
||||
NRF24L01_SetPower();
|
||||
XN297L_SetTXAddr((uint8_t*)"GDKNx", 5);
|
||||
XN297L_HoppingCalib(sub_protocol==GD_V1?GD00X_RF_NUM_CHANNELS:GD00X_V2_RF_NUM_CHANNELS); // Calibrate all channels
|
||||
XN297L_RFChannel(sub_protocol==GD_V1?GD00X_RF_BIND_CHANNEL:GD00X_V2_RF_BIND_CHANNEL); // Set bind channel
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) GD00X_initialize_txid()
|
||||
@@ -161,14 +143,14 @@ static void __attribute__((unused)) GD00X_initialize_txid()
|
||||
if(sub_protocol==GD_V1)
|
||||
{
|
||||
uint8_t start=76+(rx_tx_addr[0]&0x03);
|
||||
for(uint8_t i=0; i<4;i++)
|
||||
for(uint8_t i=0; i<GD00X_RF_NUM_CHANNELS;i++)
|
||||
hopping_frequency[i]=start-(i<<1);
|
||||
#ifdef FORCE_GD00X_ORIGINAL_ID
|
||||
rx_tx_addr[0]=0x1F; // or 0xA5 or 0x26
|
||||
rx_tx_addr[1]=0x39; // or 0x37 or 0x35
|
||||
rx_tx_addr[2]=0x12; // Constant on 3 TXs
|
||||
rx_tx_addr[3]=0x13; // Constant on 3 TXs
|
||||
for(uint8_t i=0; i<4;i++)
|
||||
for(uint8_t i=0; i<GD00X_RF_NUM_CHANNELS;i++)
|
||||
hopping_frequency[i]=79-(i<<1); // or 77 or 78
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ static void __attribute__((unused)) GW008_send_packet(uint8_t bind)
|
||||
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||
NRF24L01_FlushTx();
|
||||
XN297_WriteEnhancedPayload(packet, GW008_PAYLOAD_SIZE, 0, 0x3c7d);
|
||||
XN297_WriteEnhancedPayload(packet, GW008_PAYLOAD_SIZE, 0);
|
||||
|
||||
NRF24L01_SetPower(); // Set tx_power
|
||||
}
|
||||
|
||||
109
Multiprotocol/KF606_nrf24l01.ino
Normal file
109
Multiprotocol/KF606_nrf24l01.ino
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
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 KF606 plane.
|
||||
|
||||
#if defined(KF606_NRF24L01_INO)
|
||||
|
||||
#include "iface_xn297l.h"
|
||||
|
||||
//#define FORCE_KF606_ORIGINAL_ID
|
||||
|
||||
#define KF606_INITIAL_WAIT 500
|
||||
#define KF606_PACKET_PERIOD 3000
|
||||
#define KF606_RF_BIND_CHANNEL 7
|
||||
#define KF606_PAYLOAD_SIZE 4
|
||||
#define KF606_BIND_COUNT 857 //3sec
|
||||
#define KF606_RF_NUM_CHANNELS 2
|
||||
|
||||
static void __attribute__((unused)) KF606_send_packet()
|
||||
{
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
packet[0] = 0xAA;
|
||||
memcpy(&packet[1],rx_tx_addr,3);
|
||||
}
|
||||
else
|
||||
{
|
||||
packet[0]= 0x55;
|
||||
packet[1]= convert_channel_8b(THROTTLE); // 0..255
|
||||
// Deadband is needed on aileron, 40 gives +-6%
|
||||
packet[2]=convert_channel_8b_limit_deadband(AILERON,0x20,0x80,0xE0,40); // Aileron: Max values:20..80..E0, Low rates:50..80..AF, High rates:3E..80..C1
|
||||
// Aileron trim must be on a separated channel C1..D0..DF
|
||||
packet[3]= convert_channel_16b_limit(CH5,0xC1,0xDF);
|
||||
}
|
||||
if(IS_BIND_DONE)
|
||||
{
|
||||
XN297L_Hopping(hopping_frequency_no);
|
||||
hopping_frequency_no ^= 1; // 2 RF channels
|
||||
}
|
||||
|
||||
XN297L_WritePayload(packet, KF606_PAYLOAD_SIZE);
|
||||
|
||||
XN297L_SetPower(); // Set tx_power
|
||||
XN297L_SetFreqOffset(); // Set frequency offset
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) KF606_initialize_txid()
|
||||
{
|
||||
rx_tx_addr[0]=rx_tx_addr[3]; // Use RX_num;
|
||||
hopping_frequency[0]=(rx_tx_addr[0]&0x3F)+9;
|
||||
hopping_frequency[1]=hopping_frequency[0]+3;
|
||||
#ifdef FORCE_KF606_ORIGINAL_ID
|
||||
//TX1
|
||||
rx_tx_addr[0]=0x57;
|
||||
rx_tx_addr[1]=0x02;
|
||||
rx_tx_addr[2]=0x00;
|
||||
hopping_frequency[0]=0x20;
|
||||
hopping_frequency[0]=0x23;
|
||||
//TX2
|
||||
rx_tx_addr[0]=0x25;
|
||||
rx_tx_addr[1]=0x04;
|
||||
rx_tx_addr[2]=0x00;
|
||||
hopping_frequency[0]=0x2E;
|
||||
hopping_frequency[0]=0x31;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) KF606_init()
|
||||
{
|
||||
XN297L_Init();
|
||||
XN297L_SetTXAddr((uint8_t*)"\xe7\xe7\xe7\xe7\xe7", 5);
|
||||
XN297L_HoppingCalib(KF606_RF_NUM_CHANNELS); // Calibrate all channels
|
||||
XN297L_RFChannel(KF606_RF_BIND_CHANNEL); // Set bind channel
|
||||
}
|
||||
|
||||
uint16_t KF606_callback()
|
||||
{
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
if(--bind_counter==0)
|
||||
{
|
||||
BIND_DONE;
|
||||
XN297_SetTXAddr(rx_tx_addr, 3);
|
||||
}
|
||||
KF606_send_packet();
|
||||
return KF606_PACKET_PERIOD;
|
||||
}
|
||||
|
||||
uint16_t initKF606()
|
||||
{
|
||||
BIND_IN_PROGRESS; // autobind protocol
|
||||
KF606_initialize_txid();
|
||||
KF606_init();
|
||||
hopping_frequency_no = 0;
|
||||
bind_counter=KF606_BIND_COUNT;
|
||||
return KF606_INITIAL_WAIT;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -18,6 +18,7 @@
|
||||
#if defined(MJXQ_NRF24L01_INO)
|
||||
|
||||
#include "iface_nrf24l01.h"
|
||||
#include "iface_xn297l.h"
|
||||
|
||||
#define MJXQ_BIND_COUNT 150
|
||||
#define MJXQ_PACKET_PERIOD 4000 // Timeout for callback in uSec
|
||||
@@ -78,6 +79,7 @@ const uint8_t PROGMEM E010_map_rfchan[][2] = {
|
||||
#define MJXQ_PAN_UP 0x04
|
||||
#define MJXQ_TILT_DOWN 0x20
|
||||
#define MJXQ_TILT_UP 0x10
|
||||
|
||||
static uint8_t __attribute__((unused)) MJXQ_pan_tilt_value()
|
||||
{
|
||||
// CH12_SW PAN // H26D
|
||||
@@ -190,25 +192,35 @@ static void __attribute__((unused)) MJXQ_send_packet(uint8_t bind)
|
||||
uint8_t sum = packet[0];
|
||||
for (uint8_t i=1; i < MJXQ_PACKET_SIZE-1; i++) sum += packet[i];
|
||||
packet[15] = sum;
|
||||
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no++ / 2]);
|
||||
hopping_frequency_no %= 2 * MJXQ_RF_NUM_CHANNELS; // channels repeated
|
||||
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||
NRF24L01_FlushTx();
|
||||
|
||||
// Power on, TX mode, 2byte CRC and send packet
|
||||
if (sub_protocol == H26D || sub_protocol == H26WH)
|
||||
hopping_frequency_no++;
|
||||
if (sub_protocol == E010 || sub_protocol == PHOENIX)
|
||||
{
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
NRF24L01_WritePayload(packet, MJXQ_PACKET_SIZE);
|
||||
XN297L_Hopping(hopping_frequency_no / 2);
|
||||
XN297L_SetFreqOffset();
|
||||
XN297L_SetPower();
|
||||
XN297L_WritePayload(packet, MJXQ_PACKET_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
||||
XN297_WritePayload(packet, MJXQ_PACKET_SIZE);
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no / 2]);
|
||||
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||
NRF24L01_FlushTx();
|
||||
|
||||
// Power on, TX mode, 2byte CRC and send packet
|
||||
if (sub_protocol == H26D || sub_protocol == H26WH)
|
||||
{
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
NRF24L01_WritePayload(packet, MJXQ_PACKET_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
||||
XN297_WritePayload(packet, MJXQ_PACKET_SIZE);
|
||||
}
|
||||
NRF24L01_SetPower();
|
||||
}
|
||||
NRF24L01_SetPower();
|
||||
hopping_frequency_no %= 2 * MJXQ_RF_NUM_CHANNELS; // channels repeated
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) MJXQ_init()
|
||||
@@ -225,30 +237,35 @@ static void __attribute__((unused)) MJXQ_init()
|
||||
memcpy(hopping_frequency, "\x0a\x35\x42\x3d", MJXQ_RF_NUM_CHANNELS);
|
||||
memcpy(addr, "\x6d\x6a\x73\x73\x73", MJXQ_ADDRESS_LENGTH);
|
||||
}
|
||||
|
||||
NRF24L01_Initialize();
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
|
||||
if (sub_protocol == H26D || sub_protocol == H26WH)
|
||||
if (sub_protocol == E010 || sub_protocol == PHOENIX)
|
||||
{
|
||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5-byte RX/TX address
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, addr, MJXQ_ADDRESS_LENGTH);
|
||||
XN297L_Init();
|
||||
XN297L_SetTXAddr(addr, sizeof(addr));
|
||||
XN297L_HoppingCalib(MJXQ_RF_NUM_CHANNELS);
|
||||
}
|
||||
else
|
||||
XN297_SetTXAddr(addr, MJXQ_ADDRESS_LENGTH);
|
||||
{
|
||||
NRF24L01_Initialize();
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
|
||||
NRF24L01_FlushTx();
|
||||
NRF24L01_FlushRx();
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
|
||||
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowledgment on all data pipes
|
||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 only
|
||||
NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x00); // no retransmits
|
||||
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, MJXQ_PACKET_SIZE);
|
||||
if (sub_protocol == E010 || sub_protocol == PHOENIX)
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_250K); // 250K
|
||||
else
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps
|
||||
NRF24L01_SetPower();
|
||||
if (sub_protocol == H26D || sub_protocol == H26WH)
|
||||
{
|
||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // 5-byte RX/TX address
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, addr, MJXQ_ADDRESS_LENGTH);
|
||||
}
|
||||
else
|
||||
XN297_SetTXAddr(addr, MJXQ_ADDRESS_LENGTH);
|
||||
|
||||
NRF24L01_FlushTx();
|
||||
NRF24L01_FlushRx();
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
|
||||
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowledgment on all data pipes
|
||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 only
|
||||
NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x00); // no retransmits
|
||||
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, MJXQ_PACKET_SIZE);
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps
|
||||
NRF24L01_SetPower();
|
||||
}
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) MJXQ_init2()
|
||||
@@ -268,6 +285,7 @@ static void __attribute__((unused)) MJXQ_init2()
|
||||
hopping_frequency[i]=pgm_read_byte_near( &E010_map_rfchan[rx_tx_addr[3]&0x0F][i] );
|
||||
hopping_frequency[i+2]=hopping_frequency[i]+0x10;
|
||||
}
|
||||
XN297L_HoppingCalib(MJXQ_RF_NUM_CHANNELS);
|
||||
break;
|
||||
case WLH08:
|
||||
// do nothing
|
||||
|
||||
@@ -4,14 +4,14 @@
|
||||
4,Hisky,Hisky,HK310
|
||||
5,V2x2,V2x2,JXD506
|
||||
6,DSM,DSM2-22,DSM2-11,DSMX-22,DSMX-11,AUTO
|
||||
7,Devo
|
||||
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
|
||||
12,CX10,GREEN,BLUE,DM007,---,J3015_1,J3015_2,MK33041
|
||||
13,CG023,CG023,YD829
|
||||
14,Bayang,Bayang,H8S3D,X16_AH,IRDRONE
|
||||
14,Bayang,Bayang,H8S3D,X16_AH,IRDRONE,DHD_D4
|
||||
15,FrskyX,CH_16,CH_8,EU_16,EU_8
|
||||
16,ESky
|
||||
17,MT99xx,MT,H7,YZ,LS,FY805
|
||||
@@ -44,5 +44,9 @@
|
||||
44,NCC1701
|
||||
45,E01X,E012,E015,E016H
|
||||
46,V911S
|
||||
47,GD00X,V1,V2
|
||||
63,Test
|
||||
47,GD00X,GD_V1,GD_V2
|
||||
48,V761
|
||||
49,KF606
|
||||
50,REDPINE,FAST,SLOW
|
||||
51,POTENSIC,A20
|
||||
63,XN_DUMP,250K,1M,2M
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#define VERSION_MAJOR 1
|
||||
#define VERSION_MINOR 2
|
||||
#define VERSION_REVISION 1
|
||||
#define VERSION_PATCH_LEVEL 39
|
||||
#define VERSION_PATCH_LEVEL 69
|
||||
|
||||
//******************
|
||||
// Protocols
|
||||
@@ -74,7 +74,11 @@ enum PROTOCOLS
|
||||
PROTO_E01X = 45, // =>NRF24L01
|
||||
PROTO_V911S = 46, // =>NRF24L01
|
||||
PROTO_GD00X = 47, // =>NRF24L01
|
||||
PROTO_TEST = 63, // =>NRF24L01
|
||||
PROTO_V761 = 48, // =>NRF24L01
|
||||
PROTO_KF606 = 49, // =>NRF24L01
|
||||
PROTO_REDPINE = 50, // =>CC2500
|
||||
PROTO_POTENSIC = 51, // =>NRF24L01
|
||||
PROTO_XN297DUMP = 63, // =>NRF24L01
|
||||
};
|
||||
|
||||
enum Flysky
|
||||
@@ -166,6 +170,7 @@ enum BAYANG
|
||||
H8S3D = 1,
|
||||
X16_AH = 2,
|
||||
IRDRONE = 3,
|
||||
DHD_D4 = 4,
|
||||
};
|
||||
enum MT99XX
|
||||
{
|
||||
@@ -267,6 +272,16 @@ enum BUGSMINI
|
||||
BUGSMINI= 0,
|
||||
BUGS3H = 1,
|
||||
};
|
||||
enum REDPINE
|
||||
{
|
||||
RED_FAST= 0,
|
||||
RED_SLOW= 1,
|
||||
};
|
||||
enum TRAXXAS
|
||||
{
|
||||
RX6519 = 0,
|
||||
};
|
||||
|
||||
#define NONE 0
|
||||
#define P_HIGH 1
|
||||
#define P_LOW 0
|
||||
@@ -385,10 +400,11 @@ enum MultiPacketTypes
|
||||
#define debug(msg, ...) {char debug_buf[64]; sprintf(debug_buf, msg, ##__VA_ARGS__); Serial.write(debug_buf);}
|
||||
#define debugln(msg, ...) {char debug_buf[64]; sprintf(debug_buf, msg "\r\n", ##__VA_ARGS__); Serial.write(debug_buf);}
|
||||
#define debug_time(msg) { uint16_t debug_time_TCNT1=TCNT1; debug_time=debug_time_TCNT1-debug_time; debug(msg "%u", debug_time>>1); debug_time=debug_time_TCNT1; }
|
||||
#define debugln_time(msg) { uint16_t debug_time_TCNT1=TCNT1; debug_time=debug_time_TCNT1-debug_time; debug(msg "%u\r\n", debug_time>>1); debug_time=debug_time_TCNT1; }
|
||||
#else
|
||||
#define debug(...) { }
|
||||
#define debugln(...) { }
|
||||
#define debug_time(...) { }
|
||||
#define debugln_time(...) { }
|
||||
#undef DEBUG_SERIAL
|
||||
#endif
|
||||
|
||||
@@ -540,8 +556,8 @@ enum {
|
||||
#define EEPROM_ID_VALID_OFFSET 20 // 1 byte flag that ID is valid
|
||||
#define MODELMODE_EEPROM_OFFSET 30 // Autobind mode, 1 byte per model, end is 30+16=46
|
||||
#define AFHDS2A_EEPROM_OFFSET 50 // RX ID, 4 bytes per model id, end is 50+64=114
|
||||
#define BUGS_EEPROM_OFFSET 114 // TX ID, 4 bytes per model id, end is 114+64=178
|
||||
#define BUGSMINI_EEPROM_OFFSET 178 // RX ID, 2 bytes per model id, end is 178+32=210
|
||||
#define BUGS_EEPROM_OFFSET 114 // RX ID, 2 bytes per model id, end is 114+32=146
|
||||
#define BUGSMINI_EEPROM_OFFSET 146 // RX ID, 2 bytes per model id, end is 146+32=178
|
||||
//#define CONFIG_EEPROM_OFFSET 210 // Current configuration of the multimodule
|
||||
|
||||
//****************************************
|
||||
@@ -608,6 +624,10 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
||||
E01X 45
|
||||
V911S 46
|
||||
GD00X 47
|
||||
V761 48
|
||||
KF606 49
|
||||
REDPINE 50
|
||||
POTENSIC 51
|
||||
BindBit=> 0x80 1=Bind/0=No
|
||||
AutoBindBit=> 0x40 1=Yes /0=No
|
||||
RangeCheck=> 0x20 1=Yes /0=No
|
||||
@@ -665,6 +685,7 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
||||
H8S3D 1
|
||||
X16_AH 2
|
||||
IRDRONE 3
|
||||
DHD_D4 4
|
||||
sub_protocol==MT99XX
|
||||
MT99 0
|
||||
H7 1
|
||||
@@ -743,6 +764,11 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p --
|
||||
sub_protocol==GD00X
|
||||
GD_V1 0
|
||||
GD_V2 1
|
||||
sub_protocol==REDPINE
|
||||
RED_FAST 0
|
||||
RED_SLOW 1
|
||||
sub_protocol==TRAXXAS
|
||||
RX6519 0
|
||||
|
||||
Power value => 0x80 0=High/1=Low
|
||||
Stream[3] = option_protocol;
|
||||
|
||||
@@ -111,9 +111,10 @@ uint16_t failsafe_count;
|
||||
uint16_t state;
|
||||
uint8_t len;
|
||||
uint8_t armed, arm_flags, arm_channel_previous;
|
||||
uint8_t num_ch;
|
||||
|
||||
#if defined(FRSKYX_CC2500_INO) || defined(SFHSS_CC2500_INO) || defined(HITEC_CC2500_INO)
|
||||
uint8_t calData[48];
|
||||
#ifdef CC2500_INSTALLED
|
||||
uint8_t calData[50];
|
||||
#endif
|
||||
|
||||
#ifdef CHECK_FOR_BOOTLOADER
|
||||
@@ -397,7 +398,7 @@ void setup()
|
||||
#endif
|
||||
|
||||
// Read or create protocol id
|
||||
MProtocol_id_master=random_id(10,false);
|
||||
MProtocol_id_master=random_id(EEPROM_ID_OFFSET,false);
|
||||
|
||||
debugln("Module Id: %lx", MProtocol_id_master);
|
||||
|
||||
@@ -442,6 +443,11 @@ void setup()
|
||||
option = FORCE_CORONA_TUNING; // Use config-defined tuning value for CORONA
|
||||
else
|
||||
#endif
|
||||
#if defined(FORCE_REDPINE_TUNING) && defined(REDPINE_CC2500_INO)
|
||||
if (protocol==PROTO_REDPINE)
|
||||
option = FORCE_REDPINE_TUNING; // Use config-defined tuning value for REDPINE
|
||||
else
|
||||
#endif
|
||||
#if defined(FORCE_HITEC_TUNING) && defined(HITEC_CC2500_INO)
|
||||
if (protocol==PROTO_HITEC)
|
||||
option = FORCE_HITEC_TUNING; // Use config-defined tuning value for HITEC
|
||||
@@ -634,8 +640,8 @@ uint8_t Update_All()
|
||||
{ // Autobind is on and BIND_CH went down
|
||||
BIND_CH_PREV_off;
|
||||
//Request protocol to terminate bind
|
||||
#if defined(FRSKYD_CC2500_INO) || defined(FRSKYX_CC2500_INO) || defined(FRSKYV_CC2500_INO)
|
||||
if(protocol==PROTO_FRSKYD || protocol==PROTO_FRSKYX || protocol==PROTO_FRSKYV)
|
||||
#if defined(FRSKYD_CC2500_INO) || defined(FRSKYX_CC2500_INO) || defined(FRSKYV_CC2500_INO) || defined(AFHDS2A_A7105_INO)
|
||||
if(protocol==PROTO_FRSKYD || protocol==PROTO_FRSKYX || protocol==PROTO_FRSKYV || protocol==PROTO_AFHDS2A )
|
||||
BIND_DONE;
|
||||
else
|
||||
#endif
|
||||
@@ -969,6 +975,14 @@ static void protocol_init()
|
||||
remote_callback = ReadCORONA;
|
||||
break;
|
||||
#endif
|
||||
#if defined(REDPINE_CC2500_INO)
|
||||
case PROTO_REDPINE:
|
||||
PE1_off; //antenna RF2
|
||||
PE2_on;
|
||||
next_callback = initREDPINE();
|
||||
remote_callback = ReadREDPINE;
|
||||
break;
|
||||
#endif
|
||||
#if defined(HITEC_CC2500_INO)
|
||||
case PROTO_HITEC:
|
||||
PE1_off; //antenna RF2
|
||||
@@ -1044,6 +1058,13 @@ static void protocol_init()
|
||||
remote_callback = ReadJ6Pro;
|
||||
break;
|
||||
#endif
|
||||
#if defined(TRAXXAS_CYRF6936_INO)
|
||||
case PROTO_TRAXXAS:
|
||||
PE2_on; //antenna RF4
|
||||
next_callback = initTRAXXAS();
|
||||
remote_callback = ReadTRAXXAS;
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
#ifdef NRF24L01_INSTALLED
|
||||
#if defined(HISKY_NRF24L01_INO)
|
||||
@@ -1222,10 +1243,28 @@ static void protocol_init()
|
||||
remote_callback = GD00X_callback;
|
||||
break;
|
||||
#endif
|
||||
#if defined(TEST_NRF24L01_INO)
|
||||
case PROTO_TEST:
|
||||
next_callback=initTest();
|
||||
remote_callback = Test_callback;
|
||||
#if defined(V761_NRF24L01_INO)
|
||||
case PROTO_V761:
|
||||
next_callback=initV761();
|
||||
remote_callback = V761_callback;
|
||||
break;
|
||||
#endif
|
||||
#if defined(KF606_NRF24L01_INO)
|
||||
case PROTO_KF606:
|
||||
next_callback=initKF606();
|
||||
remote_callback = KF606_callback;
|
||||
break;
|
||||
#endif
|
||||
#if defined(POTENSIC_NRF24L01_INO)
|
||||
case PROTO_POTENSIC:
|
||||
next_callback=initPOTENSIC();
|
||||
remote_callback = POTENSIC_callback;
|
||||
break;
|
||||
#endif
|
||||
#if defined(XN297DUMP_NRF24L01_INO)
|
||||
case PROTO_XN297DUMP:
|
||||
next_callback=initXN297Dump();
|
||||
remote_callback = XN297Dump_callback;
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
@@ -1309,13 +1348,18 @@ void update_serial_data()
|
||||
option=FORCE_CORONA_TUNING; // Use config-defined tuning value for CORONA
|
||||
else
|
||||
#endif
|
||||
#if defined(FORCE_REDPINE_TUNING) && defined(REDPINE_CC2500_INO)
|
||||
if (protocol==PROTO_REDPINE)
|
||||
option=FORCE_REDPINE_TUNING; // Use config-defined tuning value for REDPINE
|
||||
else
|
||||
#endif
|
||||
#if defined(FORCE_HITEC_TUNING) && defined(HITEC_CC2500_INO)
|
||||
if (protocol==PROTO_HITEC)
|
||||
option=FORCE_HITEC_TUNING; // Use config-defined tuning value for HITEC
|
||||
else
|
||||
#endif
|
||||
option=rx_ok_buff[3]; // Use radio-defined option value
|
||||
|
||||
|
||||
#ifdef FAILSAFE_ENABLE
|
||||
bool failsafe=false;
|
||||
if(rx_ok_buff[0]&0x02)
|
||||
@@ -1350,8 +1394,8 @@ void update_serial_data()
|
||||
else
|
||||
if( ((rx_ok_buff[1]&0x80)==0) && ((cur_protocol[1]&0x80)!=0) ) // Bind flag has been reset
|
||||
{ // Request protocol to end bind
|
||||
#if defined(FRSKYD_CC2500_INO) || defined(FRSKYX_CC2500_INO) || defined(FRSKYV_CC2500_INO)
|
||||
if(protocol==PROTO_FRSKYD || protocol==PROTO_FRSKYX || protocol==PROTO_FRSKYV)
|
||||
#if defined(FRSKYD_CC2500_INO) || defined(FRSKYX_CC2500_INO) || defined(FRSKYV_CC2500_INO) || defined(AFHDS2A_A7105_INO)
|
||||
if(protocol==PROTO_FRSKYD || protocol==PROTO_FRSKYX || protocol==PROTO_FRSKYV || protocol==PROTO_AFHDS2A )
|
||||
BIND_DONE;
|
||||
else
|
||||
#endif
|
||||
|
||||
@@ -194,8 +194,6 @@ void NRF24L01_SetTxRxMode(enum TXRX_State mode)
|
||||
if (mode == RX_EN)
|
||||
{
|
||||
NRF_CE_off;
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // reset the flag(s)
|
||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, 0x0F); // switch to RX mode
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, (1 << NRF24L01_07_RX_DR) //reset the flag(s)
|
||||
| (1 << NRF24L01_07_TX_DS)
|
||||
| (1 << NRF24L01_07_MAX_RT));
|
||||
@@ -251,26 +249,52 @@ uint8_t xn297_tx_addr[5];
|
||||
uint8_t xn297_rx_addr[5];
|
||||
uint8_t xn297_crc = 0;
|
||||
|
||||
static const uint8_t xn297_scramble[] = {
|
||||
0xe3, 0xb1, 0x4b, 0xea, 0x85, 0xbc, 0xe5, 0x66,
|
||||
0x0d, 0xae, 0x8c, 0x88, 0x12, 0x69, 0xee, 0x1f,
|
||||
0xc7, 0x62, 0x97, 0xd5, 0x0b, 0x79, 0xca, 0xcc,
|
||||
0x1b, 0x5d, 0x19, 0x10, 0x24, 0xd3, 0xdc, 0x3f,
|
||||
0x8e, 0xc5, 0x2f};
|
||||
// xn297 address / pcf / payload scramble table
|
||||
const uint8_t xn297_scramble[] = {
|
||||
0xE3, 0xB1, 0x4B, 0xEA, 0x85, 0xBC, 0xE5, 0x66,
|
||||
0x0D, 0xAE, 0x8C, 0x88, 0x12, 0x69, 0xEE, 0x1F,
|
||||
0xC7, 0x62, 0x97, 0xD5, 0x0B, 0x79, 0xCA, 0xCC,
|
||||
0x1B, 0x5D, 0x19, 0x10, 0x24, 0xD3, 0xDC, 0x3F,
|
||||
0x8E, 0xC5, 0x2F, 0xAA, 0x16, 0xF3, 0x95 };
|
||||
|
||||
// scrambled, standard mode crc xorout table
|
||||
const uint16_t PROGMEM xn297_crc_xorout_scrambled[] = {
|
||||
0x0000, 0x3448, 0x9BA7, 0x8BBB, 0x85E1, 0x3E8C,
|
||||
0x451E, 0x18E6, 0x6B24, 0xE7AB, 0x3828, 0x814B,
|
||||
0xD461, 0xF494, 0x2503, 0x691D, 0xFE8B, 0x9BA7,
|
||||
0x8B17, 0x2920, 0x8B5F, 0x61B1, 0xD391, 0x7401,
|
||||
0x2138, 0x129F, 0xB3A0, 0x2988};
|
||||
0x0000, 0x3448, 0x9BA7, 0x8BBB, 0x85E1, 0x3E8C,
|
||||
0x451E, 0x18E6, 0x6B24, 0xE7AB, 0x3828, 0x814B,
|
||||
0xD461, 0xF494, 0x2503, 0x691D, 0xFE8B, 0x9BA7,
|
||||
0x8B17, 0x2920, 0x8B5F, 0x61B1, 0xD391, 0x7401,
|
||||
0x2138, 0x129F, 0xB3A0, 0x2988, 0x23CA, 0xC0CB,
|
||||
0x0C6C, 0xB329, 0xA0A1, 0x0A16, 0xA9D0 };
|
||||
|
||||
// unscrambled, standard mode crc xorout table
|
||||
const uint16_t PROGMEM xn297_crc_xorout[] = {
|
||||
0x0000, 0x3d5f, 0xa6f1, 0x3a23, 0xaa16, 0x1caf,
|
||||
0x62b2, 0xe0eb, 0x0821, 0xbe07, 0x5f1a, 0xaf15,
|
||||
0x4f0a, 0xad24, 0x5e48, 0xed34, 0x068c, 0xf2c9,
|
||||
0x1852, 0xdf36, 0x129d, 0xb17c, 0xd5f5, 0x70d7,
|
||||
0xb798, 0x5133, 0x67db, 0xd94e};
|
||||
0x0000, 0x3D5F, 0xA6F1, 0x3A23, 0xAA16, 0x1CAF,
|
||||
0x62B2, 0xE0EB, 0x0821, 0xBE07, 0x5F1A, 0xAF15,
|
||||
0x4F0A, 0xAD24, 0x5E48, 0xED34, 0x068C, 0xF2C9,
|
||||
0x1852, 0xDF36, 0x129D, 0xB17C, 0xD5F5, 0x70D7,
|
||||
0xB798, 0x5133, 0x67DB, 0xD94E, 0x0A5B, 0xE445,
|
||||
0xE6A5, 0x26E7, 0xBDAB, 0xC379, 0x8E20 };
|
||||
|
||||
// scrambled enhanced mode crc xorout table
|
||||
const uint16_t PROGMEM xn297_crc_xorout_scrambled_enhanced[] = {
|
||||
0x0000, 0x7EBF, 0x3ECE, 0x07A4, 0xCA52, 0x343B,
|
||||
0x53F8, 0x8CD0, 0x9EAC, 0xD0C0, 0x150D, 0x5186,
|
||||
0xD251, 0xA46F, 0x8435, 0xFA2E, 0x7EBD, 0x3C7D,
|
||||
0x94E0, 0x3D5F, 0xA685, 0x4E47, 0xF045, 0xB483,
|
||||
0x7A1F, 0xDEA2, 0x9642, 0xBF4B, 0x032F, 0x01D2,
|
||||
0xDC86, 0x92A5, 0x183A, 0xB760, 0xA953 };
|
||||
|
||||
// unscrambled enhanced mode crc xorout table
|
||||
// unused so far
|
||||
/*
|
||||
const uint16_t xn297_crc_xorout_enhanced[] = {
|
||||
0x0000, 0x8BE6, 0xD8EC, 0xB87A, 0x42DC, 0xAA89,
|
||||
0x83AF, 0x10E4, 0xE83E, 0x5C29, 0xAC76, 0x1C69,
|
||||
0xA4B2, 0x5961, 0xB4D3, 0x2A50, 0xCB27, 0x5128,
|
||||
0x7CDB, 0x7A14, 0xD5D2, 0x57D7, 0xE31D, 0xCE42,
|
||||
0x648D, 0xBF2D, 0x653B, 0x190C, 0x9117, 0x9A97,
|
||||
0xABFC, 0xE68E, 0x0DE7, 0x28A2, 0x1965 };
|
||||
*/
|
||||
|
||||
static uint8_t bit_reverse(uint8_t b_in)
|
||||
{
|
||||
@@ -365,8 +389,7 @@ void XN297_WritePayload(uint8_t* msg, uint8_t len)
|
||||
for (uint8_t i = 0; i < len; ++i)
|
||||
{
|
||||
// bit-reverse bytes in packet
|
||||
uint8_t b_out = bit_reverse(msg[i]);
|
||||
buf[last] = b_out;
|
||||
buf[last] = bit_reverse(msg[i]);
|
||||
if(xn297_scramble_enabled)
|
||||
buf[last] ^= xn297_scramble[xn297_addr_len+i];
|
||||
last++;
|
||||
@@ -387,8 +410,7 @@ void XN297_WritePayload(uint8_t* msg, uint8_t len)
|
||||
NRF24L01_WritePayload(buf, last);
|
||||
}
|
||||
|
||||
|
||||
void XN297_WriteEnhancedPayload(uint8_t* msg, uint8_t len, uint8_t noack, uint16_t crc_xorout)
|
||||
void XN297_WriteEnhancedPayload(uint8_t* msg, uint8_t len, uint8_t noack)
|
||||
{
|
||||
uint8_t packet[32];
|
||||
uint8_t scramble_index=0;
|
||||
@@ -444,7 +466,10 @@ void XN297_WriteEnhancedPayload(uint8_t* msg, uint8_t len, uint8_t noack, uint16
|
||||
for (uint8_t i = offset; i < last; ++i)
|
||||
crc = crc16_update(crc, packet[i], 8);
|
||||
crc = crc16_update(crc, packet[last] & 0xc0, 2);
|
||||
crc ^= crc_xorout;
|
||||
if (xn297_scramble_enabled)
|
||||
crc ^= pgm_read_word(&xn297_crc_xorout_scrambled_enhanced[xn297_addr_len-3+len]);
|
||||
//else
|
||||
// crc ^= pgm_read_word(&xn297_crc_xorout_enhanced[xn297_addr_len - 3 + len]);
|
||||
|
||||
packet[last++] |= (crc >> 8) >> 2;
|
||||
packet[last++] = ((crc >> 8) << 6) | ((crc & 0xff) >> 2);
|
||||
|
||||
125
Multiprotocol/POTENSIC_nrf24l01.ino
Normal file
125
Multiprotocol/POTENSIC_nrf24l01.ino
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
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(POTENSIC_NRF24L01_INO)
|
||||
|
||||
#include "iface_nrf24l01.h"
|
||||
|
||||
//#define FORCE_POTENSIC_ORIGINAL_ID
|
||||
|
||||
#define POTENSIC_PACKET_PERIOD 4100 // Timeout for callback in uSec
|
||||
#define POTENSIC_INITIAL_WAIT 500
|
||||
#define POTENSIC_PACKET_SIZE 10
|
||||
#define POTENSIC_BIND_COUNT 400
|
||||
#define POTENSIC_RF_NUM_CHANNELS 4
|
||||
|
||||
static void __attribute__((unused)) POTENSIC_set_checksum()
|
||||
{
|
||||
uint8_t checksum = packet[1];
|
||||
for(uint8_t i=2; i<POTENSIC_PACKET_SIZE-2; i++)
|
||||
checksum += packet[i];
|
||||
packet[8] |= checksum & 0x0f;
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) POTENSIC_send_packet()
|
||||
{
|
||||
packet[8]=0;
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
packet[0] = 0x61;
|
||||
memcpy(&packet[1],rx_tx_addr,5);
|
||||
packet[6] = 0x20;
|
||||
packet[7] = 0xC0;
|
||||
}
|
||||
else
|
||||
{
|
||||
packet[0] = 0x64;
|
||||
// Deadband is needed on throttle to emulate the spring to neutral otherwise the quad behaves weirdly, 160 gives +-20%
|
||||
packet[1] = convert_channel_8b_limit_deadband(THROTTLE,0x00,0x19,0x32,160)<<1; // Throttle 00..19..32 *2
|
||||
uint8_t elevator=convert_channel_8b(ELEVATOR)>>3;
|
||||
packet[2] = ((255-convert_channel_8b(RUDDER))&0xF8)|(elevator>>2);
|
||||
packet[3] = (elevator<<6)|(((255-convert_channel_8b(AILERON))>>2)&0xFE);
|
||||
packet[4] = 0x20; // Trim
|
||||
packet[5] = 0x20 // Trim
|
||||
| GET_FLAG(CH7_SW, 0x80); // High: +100%
|
||||
packet[6] = 0x20; // Trim
|
||||
packet[7] = 0x40 // Low: -100%
|
||||
| GET_FLAG((Channel_data[CH7] > CHANNEL_MIN_COMMAND && !CH7_SW), 0x80) // Medium: 0%
|
||||
| GET_FLAG((CH5_SW||CH6_SW), 0x02) // Momentary Take off/Landing + Emergency
|
||||
| GET_FLAG(CH8_SW, 0x04); // Headless: -100%=off,+100%=on
|
||||
packet[8] = GET_FLAG(CH6_SW, 0x80); // Emergency
|
||||
}
|
||||
POTENSIC_set_checksum();
|
||||
packet[9] = hopping_frequency_no;
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no&0x03]);
|
||||
hopping_frequency_no++;
|
||||
// Power on, TX mode, 2byte CRC
|
||||
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||
NRF24L01_FlushTx();
|
||||
XN297_WritePayload(packet, POTENSIC_PACKET_SIZE);
|
||||
NRF24L01_SetPower();
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) POTENSIC_init()
|
||||
{
|
||||
NRF24L01_Initialize();
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
NRF24L01_FlushTx();
|
||||
NRF24L01_FlushRx();
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
XN297_SetTXAddr((uint8_t*)"\x01\x01\x01\x01\x06", 5); // Bind address
|
||||
else
|
||||
XN297_SetTXAddr(rx_tx_addr,5); // Normal address
|
||||
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowldgement on all data pipes
|
||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 only
|
||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); // set address length (5 bytes)
|
||||
NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x00); // no retransmits
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps
|
||||
NRF24L01_SetPower();
|
||||
NRF24L01_Activate(0x73); // Activate feature register
|
||||
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x00); // Disable dynamic payload length on all pipes
|
||||
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x01);
|
||||
NRF24L01_Activate(0x73);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) POTENSIC_initialize_txid()
|
||||
{
|
||||
#ifdef FORCE_POTENSIC_ORIGINAL_ID
|
||||
memcpy(rx_tx_addr,(uint8_t *)"\xF6\xE0\x20\x00\x0E",5);
|
||||
#endif
|
||||
memcpy(hopping_frequency,(uint8_t *)"\x32\x3E\x3A\x36",POTENSIC_RF_NUM_CHANNELS); //50, 62, 58, 54
|
||||
}
|
||||
|
||||
uint16_t POTENSIC_callback()
|
||||
{
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
if(--bind_counter==0)
|
||||
{
|
||||
BIND_DONE;
|
||||
XN297_SetTXAddr(rx_tx_addr,5);
|
||||
}
|
||||
POTENSIC_send_packet();
|
||||
return POTENSIC_PACKET_PERIOD;
|
||||
}
|
||||
|
||||
uint16_t initPOTENSIC(void)
|
||||
{
|
||||
bind_counter = POTENSIC_BIND_COUNT;
|
||||
POTENSIC_initialize_txid();
|
||||
POTENSIC_init();
|
||||
hopping_frequency_no = 0;
|
||||
return POTENSIC_INITIAL_WAIT;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -292,7 +292,6 @@ static void __attribute__((unused)) Q303_init()
|
||||
case CX35:
|
||||
case CX10D:
|
||||
case CX10WD:
|
||||
XN297_SetScrambledMode(XN297_SCRAMBLED);
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_1M);
|
||||
break;
|
||||
case Q303:
|
||||
|
||||
243
Multiprotocol/Redpine_cc2500.ino
Normal file
243
Multiprotocol/Redpine_cc2500.ino
Normal file
@@ -0,0 +1,243 @@
|
||||
/*
|
||||
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(REDPINE_CC2500_INO)
|
||||
|
||||
#include "iface_cc2500.h"
|
||||
|
||||
#define REDPINE_LOOPTIME_FAST 25 //2.5ms
|
||||
#define REDPINE_LOOPTIME_SLOW 6 //6ms
|
||||
|
||||
#define REDPINE_BIND 1000
|
||||
#define REDPINE_PACKET_SIZE 11
|
||||
#define REDPINE_FEC false // from cc2500 datasheet: The convolutional coder is a rate 1/2 code with a constraint length of m=4
|
||||
#define REDPINE_NUM_HOPS 50
|
||||
|
||||
static void REDPINE_set_channel(uint8_t ch)
|
||||
{
|
||||
CC2500_Strobe(CC2500_SIDLE);
|
||||
CC2500_WriteReg(CC2500_25_FSCAL1, calData[ch]);
|
||||
CC2500_WriteReg(CC2500_0A_CHANNR, hopping_frequency[ch]);
|
||||
}
|
||||
|
||||
static void REDPINE_build_bind_packet()
|
||||
{
|
||||
memset(&packet[0], 0, REDPINE_PACKET_SIZE);
|
||||
|
||||
packet[0] = REDPINE_PACKET_SIZE - 1;
|
||||
packet[1] = 0x03;
|
||||
packet[2] = 0x01;
|
||||
packet[3] = rx_tx_addr[2];
|
||||
packet[4] = rx_tx_addr[3]; // Use RX_Num
|
||||
uint16_t idx = ((REDPINE_BIND - bind_counter) % 10) * 5;
|
||||
packet[5] = idx;
|
||||
packet[6] = hopping_frequency[idx++];
|
||||
packet[7] = hopping_frequency[idx++];
|
||||
packet[8] = hopping_frequency[idx++];
|
||||
packet[9] = hopping_frequency[idx++];
|
||||
packet[10] = hopping_frequency[idx++];
|
||||
// packet[11] = 0x02;
|
||||
// packet[12] = RXNUM;
|
||||
}
|
||||
|
||||
static uint16_t Redpine_Scale(uint8_t chan)
|
||||
{
|
||||
uint16_t chan_val=Channel_data[chan]; // -125%..+125% <=> 0..2047
|
||||
if (chan_val > 2046) chan_val = 2046;
|
||||
else if (chan_val < 10) chan_val = 10;
|
||||
return chan_val;
|
||||
}
|
||||
|
||||
|
||||
static void REDPINE_data_frame() {
|
||||
uint16_t chan[4];
|
||||
|
||||
memset(&packet[0], 0, REDPINE_PACKET_SIZE);
|
||||
|
||||
packet[0] = REDPINE_PACKET_SIZE - 1;
|
||||
packet[1] = rx_tx_addr[2];
|
||||
packet[2] = rx_tx_addr[3]; // Use RX_Num
|
||||
|
||||
chan[0] = Redpine_Scale(0);
|
||||
chan[1] = Redpine_Scale(1);
|
||||
chan[2] = Redpine_Scale(2);
|
||||
chan[3] = Redpine_Scale(3);
|
||||
|
||||
packet[3] = chan[0];
|
||||
packet[4] = (((chan[0] >> 8) & 0x07) | (chan[1] << 4)) | GET_FLAG(CH5_SW, 0x08);
|
||||
packet[5] = ((chan[1] >> 4) & 0x7F) | GET_FLAG(CH6_SW, 0x80);
|
||||
packet[6] = chan[2];
|
||||
packet[7] = (((chan[2] >> 8) & 0x07) | (chan[3] << 4)) | GET_FLAG(CH7_SW, 0x08);
|
||||
packet[8] = ((chan[3] >> 4) & 0x7F) | GET_FLAG(CH8_SW, 0x80);
|
||||
packet[9] = GET_FLAG(CH9_SW, 0x01)
|
||||
| GET_FLAG(CH10_SW, 0x02)
|
||||
| GET_FLAG(CH11_SW, 0x04)
|
||||
| GET_FLAG(CH12_SW, 0x08)
|
||||
| GET_FLAG(CH13_SW, 0x10)
|
||||
| GET_FLAG(CH14_SW, 0x20)
|
||||
| GET_FLAG(CH15_SW, 0x40)
|
||||
| GET_FLAG(CH16_SW, 0x80);
|
||||
|
||||
if (sub_protocol==0)
|
||||
packet[10] = REDPINE_LOOPTIME_FAST;
|
||||
else
|
||||
packet[10] = REDPINE_LOOPTIME_SLOW;
|
||||
}
|
||||
|
||||
static uint16_t ReadREDPINE()
|
||||
{
|
||||
if ( prev_option != option )
|
||||
{ // Frequency adjust
|
||||
CC2500_WriteReg(CC2500_0C_FSCTRL0, option);
|
||||
prev_option = option ;
|
||||
}
|
||||
if(IS_BIND_IN_PROGRESS)
|
||||
{
|
||||
if(bind_counter == REDPINE_BIND)
|
||||
REDPINE_init(0);
|
||||
if(bind_counter == REDPINE_BIND/2)
|
||||
REDPINE_init(1);
|
||||
REDPINE_set_channel(49);
|
||||
CC2500_SetTxRxMode(TX_EN);
|
||||
CC2500_SetPower();
|
||||
CC2500_Strobe(CC2500_SFRX);
|
||||
REDPINE_build_bind_packet();
|
||||
CC2500_Strobe(CC2500_SIDLE);
|
||||
CC2500_WriteData(packet, REDPINE_PACKET_SIZE);
|
||||
if(--bind_counter==0)
|
||||
{
|
||||
BIND_DONE;
|
||||
REDPINE_init(sub_protocol);
|
||||
}
|
||||
return 9000;
|
||||
}
|
||||
else
|
||||
{
|
||||
CC2500_SetTxRxMode(TX_EN);
|
||||
REDPINE_set_channel(hopping_frequency_no);
|
||||
CC2500_SetPower();
|
||||
CC2500_Strobe(CC2500_SFRX);
|
||||
REDPINE_data_frame();
|
||||
CC2500_Strobe(CC2500_SIDLE);
|
||||
hopping_frequency_no = (hopping_frequency_no + 1) % 49;
|
||||
CC2500_WriteData(packet, REDPINE_PACKET_SIZE);
|
||||
if (sub_protocol==0)
|
||||
return REDPINE_LOOPTIME_FAST*100;
|
||||
else
|
||||
return REDPINE_LOOPTIME_SLOW*1000;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
// register, fast 250k, slow
|
||||
static const uint8_t REDPINE_init_data[][3] = {
|
||||
{CC2500_00_IOCFG2, 0x06, 0x06},
|
||||
{CC2500_02_IOCFG0, 0x06, 0x06},
|
||||
{CC2500_03_FIFOTHR, 0x07, 0x07},
|
||||
{CC2500_07_PKTCTRL1, 0x04, 0x04},
|
||||
{CC2500_08_PKTCTRL0, 0x05, 0x05},
|
||||
{CC2500_09_ADDR, 0x00, 0x00},
|
||||
{CC2500_0B_FSCTRL1, 0x0A, 0x0A},
|
||||
{CC2500_0C_FSCTRL0, 0x00, 0x00},
|
||||
{CC2500_0D_FREQ2, 0x5D, 0x5c},
|
||||
{CC2500_0E_FREQ1, 0x93, 0x76},
|
||||
{CC2500_0F_FREQ0, 0xB1, 0x27},
|
||||
{CC2500_10_MDMCFG4, 0x2D, 0x7B},
|
||||
{CC2500_11_MDMCFG3, 0x3B, 0x61},
|
||||
{CC2500_12_MDMCFG2, 0x73, 0x13},
|
||||
#ifdef REDPINE_FEC
|
||||
{CC2500_13_MDMCFG1, 0xA3, 0xA3},
|
||||
#else
|
||||
{CC2500_13_MDMCFG1, 0x23, 0x23},
|
||||
#endif
|
||||
{CC2500_14_MDMCFG0, 0x56, 0x7a}, // Chan space
|
||||
{CC2500_15_DEVIATN, 0x00, 0x51},
|
||||
{CC2500_17_MCSM1, 0x0c, 0x0c},
|
||||
{CC2500_18_MCSM0, 0x08, 0x08}, //??? 0x18, 0x18},
|
||||
{CC2500_19_FOCCFG, 0x1D, 0x16},
|
||||
{CC2500_1A_BSCFG, 0x1C, 0x6c},
|
||||
{CC2500_1B_AGCCTRL2, 0xC7, 0x43},
|
||||
{CC2500_1C_AGCCTRL1, 0x00, 0x40},
|
||||
{CC2500_1D_AGCCTRL0, 0xB0, 0x91},
|
||||
{CC2500_21_FREND1, 0xB6, 0x56},
|
||||
{CC2500_22_FREND0, 0x10, 0x10},
|
||||
{CC2500_23_FSCAL3, 0xEA, 0xA9},
|
||||
{CC2500_24_FSCAL2, 0x0A, 0x0A},
|
||||
{CC2500_25_FSCAL1, 0x00, 0x00},
|
||||
{CC2500_26_FSCAL0, 0x11, 0x11},
|
||||
{CC2500_29_FSTEST, 0x59, 0x59},
|
||||
{CC2500_2C_TEST2, 0x88, 0x88},
|
||||
{CC2500_2D_TEST1, 0x31, 0x31},
|
||||
{CC2500_2E_TEST0, 0x0B, 0x0B},
|
||||
{CC2500_3E_PATABLE, 0xff, 0xff}
|
||||
};
|
||||
|
||||
static void REDPINE_init(uint8_t format)
|
||||
{
|
||||
CC2500_Reset();
|
||||
|
||||
CC2500_WriteReg(CC2500_06_PKTLEN, REDPINE_PACKET_SIZE);
|
||||
|
||||
for (uint8_t i=0; i < ((sizeof REDPINE_init_data) / (sizeof REDPINE_init_data[0])); i++)
|
||||
CC2500_WriteReg(REDPINE_init_data[i][0], REDPINE_init_data[i][format+1]);
|
||||
|
||||
prev_option = option;
|
||||
CC2500_WriteReg(CC2500_0C_FSCTRL0, option);
|
||||
CC2500_Strobe(CC2500_SIDLE);
|
||||
|
||||
// calibrate hop channels
|
||||
for (uint8_t c = 0; c < REDPINE_NUM_HOPS; c++)
|
||||
{
|
||||
CC2500_Strobe(CC2500_SIDLE);
|
||||
CC2500_WriteReg(CC2500_0A_CHANNR, hopping_frequency[c]);
|
||||
CC2500_Strobe(CC2500_SCAL);
|
||||
delayMicroseconds(900);
|
||||
calData[c] = CC2500_ReadReg(CC2500_25_FSCAL1);
|
||||
}
|
||||
}
|
||||
|
||||
static uint16_t initREDPINE()
|
||||
{
|
||||
hopping_frequency_no = 0;
|
||||
// Used from kn_nrf24l01.c : kn_calculate_freqency_hopping_channels
|
||||
uint32_t idx = 0;
|
||||
uint32_t rnd = MProtocol_id;
|
||||
#define REDPINE_MAX_RF_CHANNEL 255
|
||||
hopping_frequency[idx++] = 1;
|
||||
while (idx < REDPINE_NUM_HOPS-1)
|
||||
{
|
||||
uint32_t i;
|
||||
rnd = rnd * 0x0019660D + 0x3C6EF35F; // Randomization
|
||||
// Drop least-significant byte for better randomization. Start from 1
|
||||
uint8_t next_ch = (rnd >> 8) % REDPINE_MAX_RF_CHANNEL + 1;
|
||||
// Check that it's not duplicate nor adjacent nor channel 0 or 1
|
||||
for (i = 0; i < idx; i++)
|
||||
{
|
||||
uint8_t ch = hopping_frequency[i];
|
||||
if ((ch <= next_ch + 1) && (ch >= next_ch - 1) && (ch > 1))
|
||||
break;
|
||||
}
|
||||
if (i != idx)
|
||||
continue;
|
||||
hopping_frequency[idx++] = next_ch;
|
||||
}
|
||||
hopping_frequency[49] = 0; // Last channel is the bind channel at hop 0
|
||||
|
||||
bind_counter=REDPINE_BIND;
|
||||
REDPINE_init(sub_protocol);
|
||||
CC2500_SetTxRxMode(TX_EN); // enable PA
|
||||
return 10000;
|
||||
}
|
||||
#endif
|
||||
235
Multiprotocol/TRAXXAS_cyrf6936.ino
Normal file
235
Multiprotocol/TRAXXAS_cyrf6936.ino
Normal file
@@ -0,0 +1,235 @@
|
||||
/*
|
||||
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/>.
|
||||
|
||||
Works with Traxxas 6519 receivers https://traxxas.com/sites/default/files/24CompGuide-2016.jpg .
|
||||
*/
|
||||
|
||||
#if defined(TRAXXAS_CYRF6936_INO)
|
||||
|
||||
#include "iface_cyrf6936.h"
|
||||
|
||||
//#define TRAXXAS_FORCE_ID
|
||||
|
||||
#define TRAXXAS_CHANNEL 0x05
|
||||
#define TRAXXAS_BIND_CHANNEL 0x2B
|
||||
#define TRAXXAS_PACKET_SIZE 16
|
||||
|
||||
enum {
|
||||
TRAXXAS_BIND_PREP_RX=0,
|
||||
TRAXXAS_BIND_RX,
|
||||
TRAXXAS_BIND_TX1,
|
||||
TRAXXAS_PREP_DATA,
|
||||
TRAXXAS_DATA,
|
||||
};
|
||||
|
||||
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_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_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_data_config()
|
||||
{
|
||||
CYRF_PROGMEM_ConfigSOPCode(TRAXXAS_sop_data);
|
||||
#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);
|
||||
#else
|
||||
CYRF_WriteRegister(CYRF_15_CRC_SEED_LSB, cyrfmfg_id[0]+0xB6);
|
||||
CYRF_WriteRegister(CYRF_16_CRC_SEED_MSB, cyrfmfg_id[1]+0x5D);
|
||||
#endif
|
||||
CYRF_ConfigRFChannel(TRAXXAS_CHANNEL);
|
||||
CYRF_SetTxRxMode(TX_EN);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) TRAXXAS_send_data_packet()
|
||||
{
|
||||
packet[0] = 0x01;
|
||||
memset(&packet[1],0x00,TRAXXAS_PACKET_SIZE-1);
|
||||
//Steering
|
||||
uint16_t ch = convert_channel_16b_nolimit(RUDDER,500,1000);
|
||||
packet[2]=ch>>8;
|
||||
packet[3]=ch;
|
||||
//Throttle
|
||||
ch = convert_channel_16b_nolimit(THROTTLE,500,1000);
|
||||
packet[4]=ch>>8;
|
||||
packet[5]=ch;
|
||||
//AUX3
|
||||
ch = convert_channel_16b_nolimit(AILERON,500,1000);
|
||||
packet[6]=ch>>8;
|
||||
packet[7]=ch;
|
||||
//AUX4???
|
||||
ch = convert_channel_16b_nolimit(ELEVATOR,500,1000);
|
||||
packet[12]=ch>>8;
|
||||
packet[13]=ch;
|
||||
|
||||
CYRF_SetPower(0x08);
|
||||
CYRF_WriteDataPacketLen(packet, TRAXXAS_PACKET_SIZE);
|
||||
}
|
||||
|
||||
uint16_t ReadTRAXXAS()
|
||||
{
|
||||
uint8_t status;
|
||||
|
||||
switch(phase)
|
||||
{
|
||||
case TRAXXAS_BIND_PREP_RX:
|
||||
TRAXXAS_cyrf_bind_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;
|
||||
case TRAXXAS_BIND_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);
|
||||
debugln("s=%02X",status);
|
||||
CYRF_WriteRegister(CYRF_07_RX_IRQ_STATUS, 0x80); // need to set RXOW before data read
|
||||
if((status & 0x07) == 0x02)
|
||||
{ // Data received with no errors
|
||||
len=CYRF_ReadRegister(CYRF_09_RX_COUNT);
|
||||
debugln("L=%02X",len)
|
||||
if(len==TRAXXAS_PACKET_SIZE)
|
||||
{
|
||||
CYRF_ReadDataPacketLen(packet, TRAXXAS_PACKET_SIZE);
|
||||
debug("RX=");
|
||||
for(uint8_t i=0;i<TRAXXAS_PACKET_SIZE;i++)
|
||||
debug(" %02X",packet[i]);
|
||||
debugln("");
|
||||
for(uint8_t i=0;i<6;i++)
|
||||
packet[i+1]=cyrfmfg_id[i];
|
||||
packet[10]=0x01;
|
||||
packet_count=12;
|
||||
CYRF_SetTxRxMode(TX_EN);
|
||||
phase=TRAXXAS_BIND_TX1;
|
||||
return 200;
|
||||
}
|
||||
}
|
||||
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;
|
||||
case TRAXXAS_BIND_TX1:
|
||||
CYRF_WriteDataPacketLen(packet, TRAXXAS_PACKET_SIZE);
|
||||
debug("P=");
|
||||
for(uint8_t i=0;i<TRAXXAS_PACKET_SIZE;i++)
|
||||
debug(" %02X",packet[i]);
|
||||
debugln("");
|
||||
if(--packet_count==0) // Switch to normal mode
|
||||
phase=TRAXXAS_PREP_DATA;
|
||||
break;
|
||||
case TRAXXAS_PREP_DATA:
|
||||
BIND_DONE;
|
||||
TRAXXAS_cyrf_data_config();
|
||||
phase++;
|
||||
case TRAXXAS_DATA:
|
||||
TRAXXAS_send_data_packet();
|
||||
break;
|
||||
}
|
||||
return 13940;
|
||||
}
|
||||
|
||||
uint16_t initTRAXXAS()
|
||||
{
|
||||
CYRF_Reset();
|
||||
|
||||
//Config CYRF registers
|
||||
for(uint8_t i = 0; i < sizeof(TRAXXAS_init_vals) / 2; i++)
|
||||
CYRF_WriteRegister(pgm_read_byte_near(&TRAXXAS_init_vals[i][0]), pgm_read_byte_near(&TRAXXAS_init_vals[i][1]));
|
||||
|
||||
//Read CYRF ID
|
||||
CYRF_GetMfgData(cyrfmfg_id);
|
||||
cyrfmfg_id[0]+=RX_num;
|
||||
|
||||
#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)
|
||||
{
|
||||
bind_counter=100;
|
||||
phase = TRAXXAS_BIND_PREP_RX;
|
||||
}
|
||||
else
|
||||
phase = TRAXXAS_PREP_DATA;
|
||||
return 1000;
|
||||
}
|
||||
|
||||
/*
|
||||
Bind phase 1
|
||||
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
|
||||
Note: RX cyrfmfg_id is 0x4A,0xA3,0x2D,0x1A,0x49,0xFE and TX cyrfmfg_id is 0x65,0xE2,0x5E,0x55,0x4D,0xFE
|
||||
|
||||
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?)
|
||||
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
|
||||
|
||||
Switch to normal mode
|
||||
CHANNEL: 0x05
|
||||
SOP_CODE: 0xA1 0x78 0xDC 0x3C 0x9E 0x82 0xDC 0x3C
|
||||
CRC_SEED_LSB: 0x1B
|
||||
CRC_SEED_MSB: 0x3F
|
||||
TX3: 0x01 0x00 0x02 0xA8 0x03 0xE7 0x02 0x08 0x00 0x00 0x01 0x01 0x02 0xEE 0x00 0x00
|
||||
*/
|
||||
#endif
|
||||
@@ -40,11 +40,31 @@
|
||||
#define CHANNEL_MAX_125 2047 // 125%
|
||||
#define CHANNEL_MIN_125 0 // 125%
|
||||
|
||||
#define CHANNEL_MID 1024
|
||||
|
||||
#define CHANNEL_MIN_COMMAND 784 // 1350us
|
||||
#define CHANNEL_SWITCH 1104 // 1550us
|
||||
#define CHANNEL_MAX_COMMAND 1424 // 1750us
|
||||
|
||||
//Channel definitions
|
||||
#define CH1 0
|
||||
#define CH2 1
|
||||
#define CH3 2
|
||||
#define CH4 3
|
||||
#define CH5 4
|
||||
#define CH6 5
|
||||
#define CH7 6
|
||||
#define CH8 7
|
||||
#define CH9 8
|
||||
#define CH10 9
|
||||
#define CH11 10
|
||||
#define CH12 11
|
||||
#define CH13 12
|
||||
#define CH14 13
|
||||
#define CH15 14
|
||||
#define CH16 15
|
||||
|
||||
//Channel order
|
||||
#ifdef AETR
|
||||
#define AILERON 0
|
||||
#define ELEVATOR 1
|
||||
@@ -192,20 +212,3 @@
|
||||
#define THROTTLE 1
|
||||
#define RUDDER 0
|
||||
#endif
|
||||
|
||||
#define CH1 0
|
||||
#define CH2 1
|
||||
#define CH3 2
|
||||
#define CH4 3
|
||||
#define CH5 4
|
||||
#define CH6 5
|
||||
#define CH7 6
|
||||
#define CH8 7
|
||||
#define CH9 8
|
||||
#define CH10 9
|
||||
#define CH11 10
|
||||
#define CH12 11
|
||||
#define CH13 12
|
||||
#define CH14 13
|
||||
#define CH15 14
|
||||
#define CH16 15
|
||||
|
||||
195
Multiprotocol/V761_nrf24l01.ino
Normal file
195
Multiprotocol/V761_nrf24l01.ino
Normal file
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
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/>.
|
||||
|
||||
Thanks to Goebish ,Ported from his deviation firmware
|
||||
*/
|
||||
|
||||
#if defined(V761_NRF24L01_INO)
|
||||
|
||||
#include "iface_nrf24l01.h"
|
||||
|
||||
#define V761_PACKET_PERIOD 7060 // Timeout for callback in uSec
|
||||
#define V761_INITIAL_WAIT 500
|
||||
#define V761_PACKET_SIZE 8
|
||||
#define V761_BIND_COUNT 200
|
||||
|
||||
//Fx chan management
|
||||
#define V761_BIND_FREQ 0x28
|
||||
#define V761_RF_NUM_CHANNELS 3
|
||||
|
||||
enum
|
||||
{
|
||||
V761_BIND1 = 0,
|
||||
V761_BIND2,
|
||||
V761_DATA
|
||||
};
|
||||
|
||||
static void __attribute__((unused)) V761_set_checksum()
|
||||
{
|
||||
uint8_t checksum = packet[0];
|
||||
for(uint8_t i=1; i<V761_PACKET_SIZE-2; i++)
|
||||
checksum += packet[i];
|
||||
if(phase == V761_BIND1)
|
||||
{
|
||||
packet[6] = checksum ^ 0xff;
|
||||
packet[7] = packet[6];
|
||||
}
|
||||
else
|
||||
{
|
||||
checksum += packet[6];
|
||||
packet[7] = checksum ^ 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void __attribute__((unused)) V761_send_packet()
|
||||
{
|
||||
if(phase != V761_DATA)
|
||||
{
|
||||
packet[0] = rx_tx_addr[0];
|
||||
packet[1] = rx_tx_addr[1];
|
||||
packet[2] = rx_tx_addr[2];
|
||||
packet[3] = rx_tx_addr[3];
|
||||
packet[4] = hopping_frequency[1];
|
||||
packet[5] = hopping_frequency[2];
|
||||
if(phase == V761_BIND2)
|
||||
packet[6] = 0xf0; // ?
|
||||
}
|
||||
else
|
||||
{
|
||||
packet[0] = convert_channel_8b(THROTTLE); // throttle
|
||||
packet[1] = convert_channel_8b(RUDDER)>>1; // rudder
|
||||
packet[2] = convert_channel_8b(ELEVATOR)>>1; // elevator
|
||||
packet[3] = convert_channel_8b(AILERON)>>1; // aileron
|
||||
packet[5] = (packet_count++ / 3)<<6;
|
||||
packet[4] = (packet[5] == 0x40) ? 0x1a : 0x20;
|
||||
|
||||
// Channel 5 - Gyro mode is packet 5
|
||||
if(CH5_SW) // Mode Expert Gyro off
|
||||
flags = 0x0c;
|
||||
else
|
||||
if(Channel_data[CH5] < CHANNEL_MIN_COMMAND)
|
||||
flags = 0x08; // Beginer mode (Gyro on, yaw and pitch rate limited)
|
||||
else
|
||||
flags = 0x0a; // Mid Mode ( Gyro on no rate limits)
|
||||
packet[5] |= flags;
|
||||
packet[6] = 0x80; // unknown
|
||||
|
||||
//packet counter
|
||||
if(packet_count >= 12)
|
||||
packet_count = 0;
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no++]);
|
||||
if(hopping_frequency_no >= V761_RF_NUM_CHANNELS)
|
||||
hopping_frequency_no = 0;
|
||||
}
|
||||
V761_set_checksum();
|
||||
// Power on, TX mode, 2byte CRC
|
||||
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||
NRF24L01_FlushTx();
|
||||
XN297_WritePayload(packet, V761_PACKET_SIZE);
|
||||
NRF24L01_SetPower();
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) V761_init()
|
||||
{
|
||||
NRF24L01_Initialize();
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
NRF24L01_FlushTx();
|
||||
NRF24L01_FlushRx();
|
||||
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowldgement on all data pipes
|
||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 only
|
||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x02); // set address length (4 bytes)
|
||||
NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x00); // no retransmits
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps
|
||||
NRF24L01_SetPower();
|
||||
NRF24L01_Activate(0x73); // Activate feature register
|
||||
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x00); // Disable dynamic payload length on all pipes
|
||||
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x01);
|
||||
NRF24L01_Activate(0x73);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) V761_initialize_txid()
|
||||
{
|
||||
// TODO: try arbitrary rx_tx_addr & frequencies (except hopping_frequency[0])
|
||||
switch(RX_num%3)
|
||||
{
|
||||
case 1: //Dump from air on Protonus TX
|
||||
memcpy(rx_tx_addr,(uint8_t *)"\xE8\xE4\x45\x09",4);
|
||||
memcpy(hopping_frequency,(uint8_t *)"\x0D\x21\x44",3);
|
||||
break;
|
||||
case 2: //Dump from air on mshagg2 TX
|
||||
memcpy(rx_tx_addr,(uint8_t *)"\xAE\xD1\x45\x09",4);
|
||||
memcpy(hopping_frequency,(uint8_t *)"\x13\x1D\x4A",3);
|
||||
break;
|
||||
default: //Dump from SPI
|
||||
memcpy(rx_tx_addr,(uint8_t *)"\x6f\x2c\xb1\x93",4);
|
||||
memcpy(hopping_frequency,(uint8_t *)"\x14\x1e\x4b",3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t V761_callback()
|
||||
{
|
||||
switch(phase)
|
||||
{
|
||||
case V761_BIND1:
|
||||
if(bind_counter)
|
||||
bind_counter--;
|
||||
packet_count ++;
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, V761_BIND_FREQ);
|
||||
XN297_SetTXAddr((uint8_t*)"\x34\x43\x10\x10", 4);
|
||||
V761_send_packet();
|
||||
if(packet_count >= 20)
|
||||
{
|
||||
packet_count = 0;
|
||||
phase = V761_BIND2;
|
||||
}
|
||||
return 15730;
|
||||
case V761_BIND2:
|
||||
if(bind_counter)
|
||||
bind_counter--;
|
||||
packet_count ++;
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[0]);
|
||||
XN297_SetTXAddr(rx_tx_addr, 4);
|
||||
V761_send_packet();
|
||||
if(bind_counter == 0)
|
||||
{
|
||||
phase = V761_DATA;
|
||||
BIND_DONE;
|
||||
}
|
||||
else if(packet_count >= 20)
|
||||
{
|
||||
packet_count = 0;
|
||||
phase = V761_BIND1;
|
||||
}
|
||||
return 15730;
|
||||
case V761_DATA:
|
||||
V761_send_packet();
|
||||
break;
|
||||
}
|
||||
return V761_PACKET_PERIOD;
|
||||
}
|
||||
|
||||
uint16_t initV761(void)
|
||||
{
|
||||
BIND_IN_PROGRESS;
|
||||
bind_counter = V761_BIND_COUNT;
|
||||
V761_initialize_txid();
|
||||
phase = V761_BIND1;
|
||||
V761_init();
|
||||
hopping_frequency_no = 0;
|
||||
packet_count = 0;
|
||||
return V761_INITIAL_WAIT;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
#if defined(V911S_NRF24L01_INO)
|
||||
|
||||
#include "iface_nrf24l01.h"
|
||||
#include "iface_xn297l.h"
|
||||
|
||||
//#define V911S_ORIGINAL_ID
|
||||
|
||||
@@ -75,35 +75,25 @@ static void __attribute__((unused)) V911S_send_packet(uint8_t bind)
|
||||
packet[12] = ch>>5;
|
||||
}
|
||||
|
||||
// Power on, TX mode, 2byte CRC
|
||||
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
||||
if (!bind)
|
||||
{
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[channel]);
|
||||
XN297L_Hopping(channel);
|
||||
hopping_frequency_no++;
|
||||
hopping_frequency_no&=7; // 8 RF channels
|
||||
}
|
||||
// clear packet status bits and TX FIFO
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||
NRF24L01_FlushTx();
|
||||
XN297_WritePayload(packet, V911S_PACKET_SIZE);
|
||||
|
||||
NRF24L01_SetPower(); // Set tx_power
|
||||
XN297L_WritePayload(packet, V911S_PACKET_SIZE);
|
||||
|
||||
XN297L_SetPower(); // Set tx_power
|
||||
XN297L_SetFreqOffset(); // Set frequency offset
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) V911S_init()
|
||||
{
|
||||
NRF24L01_Initialize();
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
XN297_SetTXAddr((uint8_t *)"\x4B\x4E\x42\x4E\x44", 5); // Bind address
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, V911S_RF_BIND_CHANNEL); // Bind channel
|
||||
NRF24L01_FlushTx();
|
||||
NRF24L01_FlushRx();
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
|
||||
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowldgement on all data pipes
|
||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 only
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_250K); // 250Kbps
|
||||
NRF24L01_SetPower();
|
||||
XN297L_Init();
|
||||
XN297L_SetTXAddr((uint8_t *)"KNBND",5); // Bind address
|
||||
XN297L_HoppingCalib(V911S_NUM_RF_CHANNELS); // Calibrate all channels
|
||||
XN297L_RFChannel(V911S_RF_BIND_CHANNEL); // Set bind channel
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) V911S_initialize_txid()
|
||||
|
||||
@@ -18,10 +18,10 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Check for minimum version of multi-module boards
|
||||
#define MIN_AVR_BOARD 103
|
||||
#define MIN_ORX_BOARD 103
|
||||
#define MIN_STM32_BOARD 104
|
||||
// Check for minimum board file definition version for DIY multi-module boards
|
||||
#define MIN_AVR_BOARD 107
|
||||
#define MIN_ORX_BOARD 107
|
||||
#define MIN_STM32_BOARD 114
|
||||
//AVR
|
||||
#if (defined(ARDUINO_MULTI_NO_BOOT) && ARDUINO_MULTI_NO_BOOT < MIN_AVR_BOARD) || (defined(ARDUINO_MULTI_FLASH_FROM_TX) && ARDUINO_MULTI_FLASH_FROM_TX < MIN_AVR_BOARD)
|
||||
#error You need to update your Multi 4-in-1 board definition. Open Boards Manager and update to the latest version of the Multi 4-in-1 AVR Boards.
|
||||
@@ -87,6 +87,11 @@
|
||||
#error "The CORONA forced frequency tuning value is outside of the range -127..127."
|
||||
#endif
|
||||
#endif
|
||||
#ifdef FORCE_REDPINE_TUNING
|
||||
#if ( FORCE_REDPINE_TUNING < -127 ) || ( FORCE_REDPINE_TUNING > 127 )
|
||||
#error "The REDPINE forced frequency tuning value is outside of the range -127..127."
|
||||
#endif
|
||||
#endif
|
||||
#ifdef FORCE_HITEC_TUNING
|
||||
#if ( FORCE_HITEC_TUNING < -127 ) || ( FORCE_HITEC_TUNING > 127 )
|
||||
#error "The HITEC forced frequency tuning value is outside of the range -127..127."
|
||||
@@ -119,6 +124,10 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined (USE_CYRF6936_CH15_TUNING) && (DSM_THROTTLE_KILL_CH == 15)
|
||||
#error "Error Channel 15 conflict between the CYRF6936 freq tuning and the DSM throttle kill feature."
|
||||
#endif
|
||||
|
||||
//Change/Force configuration if OrangeTX
|
||||
#ifdef ORANGE_TX
|
||||
#undef ENABLE_PPM // Disable PPM for OrangeTX module
|
||||
@@ -146,7 +155,7 @@
|
||||
#undef J6PRO_CYRF6936_INO
|
||||
#undef WFLY_CYRF6936_INO
|
||||
#undef WK2x01_CYRF6936_INO
|
||||
#undef TRAXXAS_CYRF6936_INO
|
||||
#undef TRAXXAS_CYRF6936_INO
|
||||
#endif
|
||||
#ifndef CC2500_INSTALLED
|
||||
#undef FRSKYD_CC2500_INO
|
||||
@@ -154,7 +163,9 @@
|
||||
#undef FRSKYX_CC2500_INO
|
||||
#undef SFHSS_CC2500_INO
|
||||
#undef CORONA_CC2500_INO
|
||||
#undef REDPINE_CC2500_INO
|
||||
#undef HITEC_CC2500_INO
|
||||
#undef XN297L_CC2500_EMU
|
||||
#endif
|
||||
#ifndef NRF24L01_INSTALLED
|
||||
#undef BAYANG_NRF24L01_INO
|
||||
@@ -162,6 +173,7 @@
|
||||
#undef CX10_NRF24L01_INO
|
||||
#undef ESKY_NRF24L01_INO
|
||||
#undef HISKY_NRF24L01_INO
|
||||
#undef KF606_NRF24L01_INO
|
||||
#undef KN_NRF24L01_INO
|
||||
#undef SLT_NRF24L01_INO
|
||||
#undef SYMAX_NRF24L01_INO
|
||||
@@ -185,7 +197,10 @@
|
||||
#undef BUGSMINI_NRF24L01_INO
|
||||
#undef NCC1701_NRF24L01_INO
|
||||
#undef E01X_NRF24L01_INO
|
||||
#undef V761_NRF24L01_INO
|
||||
#undef V911S_NRF24L01_INO
|
||||
#undef XN297L_CC2500_EMU
|
||||
#undef POTENSIC_NRF24L01_INO
|
||||
#endif
|
||||
|
||||
//Make sure telemetry is selected correctly
|
||||
@@ -303,3 +318,7 @@
|
||||
#if MAX_PPM_CHANNELS>16
|
||||
#error MAX_PPM_CHANNELS must be below or equal to 16. The default for this value is 16.
|
||||
#endif
|
||||
|
||||
#if defined (STM32_BOARD) && defined (DEBUG_SERIAL) && defined (NRF24L01_INSTALLED)
|
||||
#define XN297DUMP_NRF24L01_INO
|
||||
#endif
|
||||
|
||||
@@ -253,7 +253,7 @@ uint16_t initWFLY()
|
||||
rx_tx_addr[2]=0xBF; // ID
|
||||
rx_tx_addr[3]=0x13; // ID
|
||||
ch=0x16; // value seen between 0x0A and 0x17
|
||||
rc_ch_num=0x15 // RF channel to send the current hopping table
|
||||
rf_ch_num=0x15 // RF channel to send the current hopping table
|
||||
#endif
|
||||
|
||||
debug("ID:")
|
||||
|
||||
238
Multiprotocol/XN297Dump_nrf24l01.ino
Normal file
238
Multiprotocol/XN297Dump_nrf24l01.ino
Normal file
@@ -0,0 +1,238 @@
|
||||
/*
|
||||
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/>.
|
||||
*/
|
||||
|
||||
// sub_protocol: 0=250Kbps, 1=1Mbps, 2=2Mbps. Other values default to 1Mbps.
|
||||
// RX_num = address length 3 or 4 or 5. Other values default to 5.
|
||||
// option = RF channel number 0..84 and -1 = scan all channels. Other values default to RF channel 0.
|
||||
|
||||
#ifdef XN297DUMP_NRF24L01_INO
|
||||
|
||||
#include "iface_nrf24l01.h"
|
||||
|
||||
// Parameters which can be modified
|
||||
#define XN297DUMP_PERIOD_SCAN 50000 // 25000
|
||||
#define XN297DUMP_MAX_RF_CHANNEL 84 // Default 84
|
||||
|
||||
// Do not touch from there
|
||||
#define XN297DUMP_INITIAL_WAIT 500
|
||||
#define XN297DUMP_MAX_PACKET_LEN 32
|
||||
#define XN297DUMP_CRC_LENGTH 2
|
||||
|
||||
uint8_t address_length;
|
||||
uint16_t timeH=0;
|
||||
boolean scramble;
|
||||
|
||||
static void __attribute__((unused)) XN297Dump_init()
|
||||
{
|
||||
NRF24L01_Initialize();
|
||||
NRF24L01_SetTxRxMode(RX_EN);
|
||||
|
||||
NRF24L01_FlushTx();
|
||||
NRF24L01_FlushRx();
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
|
||||
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowledgment on all data pipes
|
||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 only
|
||||
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x01); // 3 bytes RX/TX address
|
||||
NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, (uint8_t*)"\x55\x0F\x71", 3); // set up RX address to xn297 preamble
|
||||
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, XN297DUMP_MAX_PACKET_LEN); // Enable rx pipe 0
|
||||
|
||||
debug("XN297 dump, address length=%d, speed=",address_length);
|
||||
switch(sub_protocol)
|
||||
{
|
||||
case 0:
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_250K);
|
||||
debugln("250K");
|
||||
break;
|
||||
case 2:
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_2M);
|
||||
debugln("2M");
|
||||
break;
|
||||
default:
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_1M);
|
||||
debugln("1M");
|
||||
break;
|
||||
|
||||
}
|
||||
NRF24L01_Activate(0x73); // Activate feature register
|
||||
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x00); // Disable dynamic payload length on all pipes
|
||||
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x01);
|
||||
NRF24L01_Activate(0x73);
|
||||
NRF24L01_SetPower();
|
||||
}
|
||||
|
||||
static boolean __attribute__((unused)) XN297Dump_process_packet(void)
|
||||
{
|
||||
uint16_t crcxored;
|
||||
uint8_t packet_sc[XN297DUMP_MAX_PACKET_LEN], packet_un[XN297DUMP_MAX_PACKET_LEN];
|
||||
|
||||
// init crc
|
||||
crc = 0xb5d2;
|
||||
|
||||
// address
|
||||
for (uint8_t i = 0; i < address_length; i++)
|
||||
{
|
||||
crc = crc16_update(crc, packet[i], 8);
|
||||
packet_un[address_length-1-i]=packet[i];
|
||||
packet_sc[address_length-1-i]=packet[i] ^ xn297_scramble[i];
|
||||
}
|
||||
|
||||
// payload
|
||||
for (uint8_t i = address_length; i < XN297DUMP_MAX_PACKET_LEN-XN297DUMP_CRC_LENGTH; i++)
|
||||
{
|
||||
crc = crc16_update(crc, packet[i], 8);
|
||||
packet_sc[i] = bit_reverse(packet[i]^xn297_scramble[i]);
|
||||
packet_un[i] = bit_reverse(packet[i]);
|
||||
// check crc
|
||||
crcxored = crc ^ pgm_read_word(&xn297_crc_xorout[i+1 - 3]);
|
||||
if( (crcxored >> 8) == packet[i + 1] && (crcxored & 0xff) == packet[i + 2])
|
||||
{
|
||||
packet_length=i+1;
|
||||
memcpy(packet,packet_un,packet_length);
|
||||
scramble=false;
|
||||
return true;
|
||||
}
|
||||
crcxored = crc ^ pgm_read_word(&xn297_crc_xorout_scrambled[i+1 - 3]);
|
||||
if( (crcxored >> 8) == packet[i + 1] && (crcxored & 0xff) == packet[i + 2])
|
||||
{
|
||||
packet_length=i+1;
|
||||
memcpy(packet,packet_sc,packet_length);
|
||||
scramble=true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) XN297Dump_overflow()
|
||||
{
|
||||
if(TIMER2_BASE->SR & TIMER_SR_UIF)
|
||||
{ // timer overflow
|
||||
timeH++;
|
||||
TIMER2_BASE->SR = 0x1E5F & ~TIMER_SR_UIF; // Clear Timer2 overflow flag
|
||||
}
|
||||
}
|
||||
static uint16_t XN297Dump_callback()
|
||||
{
|
||||
static uint32_t time=0;
|
||||
while(1)
|
||||
{
|
||||
if(option==0xFF && bind_counter>XN297DUMP_PERIOD_SCAN)
|
||||
{ // Scan frequencies
|
||||
hopping_frequency_no++;
|
||||
bind_counter=0;
|
||||
}
|
||||
if(hopping_frequency_no!=rf_ch_num)
|
||||
{ // Channel has changed
|
||||
if(hopping_frequency_no>XN297DUMP_MAX_RF_CHANNEL)
|
||||
hopping_frequency_no=0; // Invalid channel 0 by default
|
||||
rf_ch_num=hopping_frequency_no;
|
||||
debugln("Channel=%d,0x%02X",hopping_frequency_no,hopping_frequency_no)
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH,hopping_frequency_no);
|
||||
// switch to RX mode
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
|
||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||
NRF24L01_SetTxRxMode(RX_EN);
|
||||
NRF24L01_FlushRx();
|
||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, (0 << NRF24L01_00_EN_CRC) // switch to RX mode and disable CRC
|
||||
| (1 << NRF24L01_00_CRCO)
|
||||
| (1 << NRF24L01_00_PWR_UP)
|
||||
| (1 << NRF24L01_00_PRIM_RX));
|
||||
phase=0; // init timer
|
||||
}
|
||||
XN297Dump_overflow();
|
||||
|
||||
if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR))
|
||||
{ // RX fifo data ready
|
||||
if(NRF24L01_ReadReg(NRF24L01_09_CD) || option != 0xFF)
|
||||
{
|
||||
NRF24L01_ReadPayload(packet,XN297DUMP_MAX_PACKET_LEN);
|
||||
XN297Dump_overflow();
|
||||
uint16_t timeL=TCNT1;
|
||||
if(TIMER2_BASE->SR & TIMER_SR_UIF)
|
||||
{//timer just rolled over...
|
||||
XN297Dump_overflow();
|
||||
timeL=0;
|
||||
}
|
||||
if(phase==0)
|
||||
{
|
||||
phase=1;
|
||||
time=0;
|
||||
}
|
||||
else
|
||||
time=(timeH<<16)+timeL-time;
|
||||
debug("RX: %5luus C=%d ", time>>1 , hopping_frequency_no);
|
||||
time=(timeH<<16)+timeL;
|
||||
if(XN297Dump_process_packet())
|
||||
{ // valid crc found
|
||||
debug("S=%c A=",scramble?'Y':'N');
|
||||
for(uint8_t i=0; i<address_length; i++)
|
||||
{
|
||||
debug(" %02X",packet[i]);
|
||||
}
|
||||
debug(" P(%d)=",packet_length-address_length);
|
||||
for(uint8_t i=address_length; i<packet_length; i++)
|
||||
{
|
||||
debug(" %02X",packet[i]);
|
||||
}
|
||||
debugln("");
|
||||
}
|
||||
else
|
||||
{
|
||||
debugln("Bad CRC");
|
||||
}
|
||||
}
|
||||
|
||||
XN297Dump_overflow();
|
||||
// restart RX mode
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
|
||||
NRF24L01_SetTxRxMode(TXRX_OFF);
|
||||
NRF24L01_SetTxRxMode(RX_EN);
|
||||
NRF24L01_FlushRx();
|
||||
NRF24L01_WriteReg(NRF24L01_00_CONFIG, (0 << NRF24L01_00_EN_CRC) // switch to RX mode and disable CRC
|
||||
| (1 << NRF24L01_00_CRCO)
|
||||
| (1 << NRF24L01_00_PWR_UP)
|
||||
| (1 << NRF24L01_00_PRIM_RX));
|
||||
XN297Dump_overflow();
|
||||
}
|
||||
bind_counter++;
|
||||
if(IS_RX_FLAG_on) // Let the radio update the protocol
|
||||
{
|
||||
if(Update_All()) return 10000; // New protocol selected
|
||||
if(prev_option!=option)
|
||||
{ // option has changed
|
||||
hopping_frequency_no=option;
|
||||
prev_option=option;
|
||||
}
|
||||
}
|
||||
XN297Dump_overflow();
|
||||
}
|
||||
return 100;
|
||||
}
|
||||
|
||||
uint16_t initXN297Dump(void)
|
||||
{
|
||||
BIND_DONE;
|
||||
address_length=RX_num;
|
||||
if(address_length<3||address_length>5)
|
||||
address_length=5; //default
|
||||
XN297Dump_init();
|
||||
bind_counter=0;
|
||||
rf_ch_num=0xFF;
|
||||
prev_option=option^0x55;
|
||||
phase=0; // init timer
|
||||
return XN297DUMP_INITIAL_WAIT;
|
||||
}
|
||||
|
||||
#endif
|
||||
223
Multiprotocol/XN297L_EMU.ino
Normal file
223
Multiprotocol/XN297L_EMU.ino
Normal file
@@ -0,0 +1,223 @@
|
||||
/*
|
||||
This project is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Multiprotocol is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Multiprotocol. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "iface_xn297l.h"
|
||||
|
||||
#if defined (XN297L_CC2500_EMU)
|
||||
static void __attribute__((unused)) XN297L_Init()
|
||||
{
|
||||
PE1_off; // antenna RF2
|
||||
PE2_on;
|
||||
CC2500_Reset();
|
||||
CC2500_Strobe(CC2500_SIDLE);
|
||||
|
||||
// Address Config = No address check
|
||||
// Base Frequency = 2400
|
||||
// CRC Autoflush = false
|
||||
// CRC Enable = false
|
||||
// Channel Spacing = 333.251953
|
||||
// Data Format = Normal mode
|
||||
// Data Rate = 249.939
|
||||
// Deviation = 126.953125
|
||||
// Device Address = 0
|
||||
// Manchester Enable = false
|
||||
// Modulated = true
|
||||
// Modulation Format = GFSK
|
||||
// Packet Length Mode = Variable packet length mode. Packet length configured by the first byte after sync word
|
||||
// RX Filter BW = 203.125000
|
||||
// Sync Word Qualifier Mode = No preamble/sync
|
||||
// TX Power = 0
|
||||
// Whitening = false
|
||||
// Fast Frequency Hopping - no PLL auto calibration
|
||||
|
||||
CC2500_WriteReg(CC2500_08_PKTCTRL0, 0x01); // Packet Automation Control
|
||||
CC2500_WriteReg(CC2500_0B_FSCTRL1, 0x0A); // Frequency Synthesizer Control
|
||||
CC2500_WriteReg(CC2500_0C_FSCTRL0, option); // Frequency offset hack
|
||||
CC2500_WriteReg(CC2500_0D_FREQ2, 0x5C); // Frequency Control Word, High Byte
|
||||
CC2500_WriteReg(CC2500_0E_FREQ1, 0x4E); // Frequency Control Word, Middle Byte
|
||||
CC2500_WriteReg(CC2500_0F_FREQ0, 0xC3); // Frequency Control Word, Low Byte
|
||||
CC2500_WriteReg(CC2500_10_MDMCFG4, 0x8D); // Modem Configuration
|
||||
CC2500_WriteReg(CC2500_11_MDMCFG3, 0x3B); // Modem Configuration
|
||||
CC2500_WriteReg(CC2500_12_MDMCFG2, 0x10); // Modem Configuration
|
||||
CC2500_WriteReg(CC2500_13_MDMCFG1, 0x23); // Modem Configuration
|
||||
CC2500_WriteReg(CC2500_14_MDMCFG0, 0xA4); // Modem Configuration
|
||||
CC2500_WriteReg(CC2500_15_DEVIATN, 0x62); // Modem Deviation Setting
|
||||
CC2500_WriteReg(CC2500_18_MCSM0, 0x08); // Main Radio Control State Machine Configuration
|
||||
CC2500_WriteReg(CC2500_19_FOCCFG, 0x1D); // Frequency Offset Compensation Configuration
|
||||
CC2500_WriteReg(CC2500_1A_BSCFG, 0x1C); // Bit Synchronization Configuration
|
||||
CC2500_WriteReg(CC2500_1B_AGCCTRL2, 0xC7); // AGC Control
|
||||
CC2500_WriteReg(CC2500_1C_AGCCTRL1, 0x00); // AGC Control
|
||||
CC2500_WriteReg(CC2500_1D_AGCCTRL0, 0xB0); // AGC Control
|
||||
CC2500_WriteReg(CC2500_21_FREND1, 0xB6); // Front End RX Configuration
|
||||
CC2500_WriteReg(CC2500_23_FSCAL3, 0xEA); // Frequency Synthesizer Calibration
|
||||
CC2500_WriteReg(CC2500_25_FSCAL1, 0x00); // Frequency Synthesizer Calibration
|
||||
CC2500_WriteReg(CC2500_26_FSCAL0, 0x11); // Frequency Synthesizer Calibration
|
||||
|
||||
CC2500_SetTxRxMode(TX_EN);
|
||||
CC2500_SetPower();
|
||||
xn297_scramble_enabled=XN297_SCRAMBLED; //enabled by default
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) XN297L_SetTXAddr(const uint8_t* addr, uint8_t len)
|
||||
{
|
||||
if (len > 5) len = 5;
|
||||
if (len < 3) len = 3;
|
||||
xn297_addr_len = len;
|
||||
memcpy(xn297_tx_addr, addr, len);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) XN297L_WritePayload(uint8_t* msg, uint8_t len)
|
||||
{
|
||||
uint8_t buf[32];
|
||||
uint8_t last = 0;
|
||||
uint8_t i;
|
||||
static const uint16_t initial = 0xb5d2;
|
||||
|
||||
// address
|
||||
for (i = 0; i < xn297_addr_len; ++i)
|
||||
{
|
||||
buf[last] = xn297_tx_addr[xn297_addr_len - i - 1];
|
||||
if(xn297_scramble_enabled)
|
||||
buf[last] ^= xn297_scramble[i];
|
||||
last++;
|
||||
}
|
||||
|
||||
// payload
|
||||
for (i = 0; i < len; ++i) {
|
||||
// bit-reverse bytes in packet
|
||||
buf[last] = bit_reverse(msg[i]);
|
||||
if(xn297_scramble_enabled)
|
||||
buf[last] ^= xn297_scramble[xn297_addr_len+i];
|
||||
last++;
|
||||
}
|
||||
|
||||
// crc
|
||||
uint16_t crc = initial;
|
||||
for (uint8_t i = 0; i < last; ++i)
|
||||
crc = crc16_update(crc, buf[i], 8);
|
||||
if(xn297_scramble_enabled)
|
||||
crc ^= pgm_read_word(&xn297_crc_xorout_scrambled[xn297_addr_len - 3 + len]);
|
||||
else
|
||||
crc ^= pgm_read_word(&xn297_crc_xorout[xn297_addr_len - 3 + len]);
|
||||
buf[last++] = crc >> 8;
|
||||
buf[last++] = crc & 0xff;
|
||||
|
||||
// stop TX/RX
|
||||
CC2500_Strobe(CC2500_SIDLE);
|
||||
// flush tx FIFO
|
||||
CC2500_Strobe(CC2500_SFTX);
|
||||
// packet length
|
||||
CC2500_WriteReg(CC2500_3F_TXFIFO, last + 3);
|
||||
// xn297L preamble
|
||||
CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, (uint8_t*)"\x71\x0f\x55", 3);
|
||||
// xn297 packet
|
||||
CC2500_WriteRegisterMulti(CC2500_3F_TXFIFO, buf, last);
|
||||
// transmit
|
||||
CC2500_Strobe(CC2500_STX);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) XN297L_HoppingCalib(uint8_t num_freq)
|
||||
{ //calibrate hopping frequencies
|
||||
for (uint8_t i = 0; i < num_freq; i++)
|
||||
{
|
||||
CC2500_Strobe(CC2500_SIDLE);
|
||||
CC2500_WriteReg(CC2500_0A_CHANNR, hopping_frequency[i]*3);
|
||||
CC2500_Strobe(CC2500_SCAL);
|
||||
delayMicroseconds(900);
|
||||
calData[i]=CC2500_ReadReg(CC2500_25_FSCAL1);
|
||||
}
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) XN297L_Hopping(uint8_t index)
|
||||
{
|
||||
// spacing is 333.25 kHz, must multiply xn297 channel by 3
|
||||
CC2500_WriteReg(CC2500_0A_CHANNR, hopping_frequency[index] * 3);
|
||||
// set PLL calibration
|
||||
CC2500_WriteReg(CC2500_25_FSCAL1, calData[index]);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) XN297L_RFChannel(uint8_t number)
|
||||
{ //change channel
|
||||
CC2500_Strobe(CC2500_SIDLE);
|
||||
CC2500_WriteReg(CC2500_0A_CHANNR, number*3);
|
||||
CC2500_Strobe(CC2500_SCAL);
|
||||
delayMicroseconds(900);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) XN297L_SetPower()
|
||||
{
|
||||
CC2500_SetPower();
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) XN297L_SetFreqOffset()
|
||||
{ // Frequency offset
|
||||
if (prev_option != option)
|
||||
{
|
||||
prev_option = option;
|
||||
CC2500_WriteReg(CC2500_0C_FSCTRL0, option);
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined (NRF24L01_INSTALLED)
|
||||
|
||||
static void __attribute__((unused)) XN297L_Init()
|
||||
{
|
||||
NRF24L01_Initialize();
|
||||
NRF24L01_SetTxRxMode(TX_EN);
|
||||
NRF24L01_FlushTx();
|
||||
NRF24L01_FlushRx();
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
|
||||
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowldgement on all data pipes
|
||||
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0 only
|
||||
NRF24L01_SetBitrate(NRF24L01_BR_250K); // 250Kbps
|
||||
NRF24L01_SetPower();
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) XN297L_SetTXAddr(const uint8_t* addr, uint8_t len)
|
||||
{
|
||||
XN297_SetTXAddr(addr,len);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) XN297L_WritePayload(uint8_t* msg, uint8_t len)
|
||||
{
|
||||
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
||||
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
||||
NRF24L01_FlushTx();
|
||||
XN297_WritePayload(msg, len);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) XN297L_HoppingCalib(__attribute__((unused)) uint8_t num_freq)
|
||||
{ //calibrate hopping frequencies
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) XN297L_Hopping(uint8_t index)
|
||||
{
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[index]);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) XN297L_RFChannel(uint8_t number)
|
||||
{ //change channel
|
||||
NRF24L01_WriteReg(NRF24L01_05_RF_CH, number);
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) XN297L_SetPower()
|
||||
{
|
||||
NRF24L01_SetPower();
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) XN297L_SetFreqOffset()
|
||||
{ // Frequency offset
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -29,8 +29,8 @@
|
||||
/*************************/
|
||||
/*** BOOTLOADER USE ***/
|
||||
/*************************/
|
||||
//Allow flashing multimodule directly with TX(erky9x or opentx modified firmwares)
|
||||
//Instructions: https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/tree/master/BootLoaders#compiling--uploading-firmware-with-the-flash-from-tx-bootloader
|
||||
//Allow flashing multimodule directly with TX(erky9x or opentx maintenance mode)
|
||||
//Instructions:https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/blob/master/docs/Flash_from_Tx.md
|
||||
//To enable this feature remove the "//" on the next line. Requires a compatible bootloader or upload method to be selected when you use the Multi 4-in-1 Boards Manager definitions.
|
||||
//#define CHECK_FOR_BOOTLOADER
|
||||
|
||||
@@ -78,14 +78,17 @@
|
||||
#define CC2500_INSTALLED
|
||||
#define NRF24L01_INSTALLED
|
||||
|
||||
//If available use the CC2500 to emulate the XN297L @250Kbps instead of the NRF24L01. Comment to disable.
|
||||
#define XN297L_CC2500_EMU
|
||||
|
||||
/** OrangeRX TX **/
|
||||
//If you compile for the OrangeRX TX module you need to select the correct board type.
|
||||
//By default the compilation is done for the GREEN board, to switch to a BLUE board uncomment the line below by removing the "//"
|
||||
//#define ORANGE_TX_BLUE
|
||||
|
||||
/** CC2500 Fine Frequency Tuning **/
|
||||
//For optimal performance the CC2500 RF module used by the FrSkyD, FrSkyV, FrSkyX, SFHSS, CORONA and Hitec protocols needs to be tuned for each protocol.
|
||||
//Initial tuning should be done via the radio menu with a genuine FrSky/Futaba/CORONA/Hitec receiver.
|
||||
//For optimal performance the CC2500 RF module used by the FrSkyD, FrSkyV, FrSkyX, SFHSS, CORONA, Redpine and Hitec protocols needs to be tuned for each protocol.
|
||||
//Initial tuning should be done via the radio menu with a genuine FrSky/Futaba/CORONA/Hitec/Redpine receiver.
|
||||
//Once a good tuning value is found it can be set here and will override the radio's 'option' setting for all existing and new models which use that protocol.
|
||||
//For more information: https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/tree/master/docs/Frequency_Tuning.md
|
||||
//Uncomment the lines below (remove the "//") and set an appropriate value (replace the "0") to enable. Valid range is -127 to +127.
|
||||
@@ -95,6 +98,7 @@
|
||||
//#define FORCE_SFHSS_TUNING 0
|
||||
//#define FORCE_CORONA_TUNING 0
|
||||
//#define FORCE_HITEC_TUNING 0
|
||||
//#define FORCE_REDPINE_TUNING 0
|
||||
|
||||
/** A7105 Fine Frequency Tuning **/
|
||||
//This is required in rare cases where some A7105 modules and/or RXs have an inaccurate crystal oscillator.
|
||||
@@ -109,6 +113,12 @@
|
||||
//#define FORCE_AFHDS2A_TUNING 0
|
||||
//#define FORCE_BUGS_TUNING 0
|
||||
|
||||
/** CYRF6936 Fine Frequency Tuning **/
|
||||
//This is required in rare cases where some CYRF6936 modules and/or RXs have an inaccurate crystal oscillator.
|
||||
//If using Serial mode only (for now), you can use CH15 to find the right tuning value. -100%=-300, 0%=default 0, +100%=+300.
|
||||
//Uncomment the line below (remove the "//") to enable this feature.
|
||||
//#define USE_CYRF6936_CH15_TUNING
|
||||
|
||||
/** Low Power **/
|
||||
//Low power is reducing the transmit power of the multi module. This setting is configurable per model in PPM (table below) or Serial mode (radio GUI).
|
||||
//It can be activated when flying indoor or small models since the distance is short or if a model is causing issues when flying closed to the TX.
|
||||
@@ -155,7 +165,7 @@
|
||||
#define J6PRO_CYRF6936_INO
|
||||
#define WFLY_CYRF6936_INO
|
||||
#define WK2x01_CYRF6936_INO
|
||||
//#define TRAXXAS_CYRF6936_INO
|
||||
#define TRAXXAS_CYRF6936_INO
|
||||
|
||||
//The protocols below need a CC2500 to be installed
|
||||
#define CORONA_CC2500_INO
|
||||
@@ -164,6 +174,7 @@
|
||||
#define FRSKYX_CC2500_INO
|
||||
#define HITEC_CC2500_INO
|
||||
#define SFHSS_CC2500_INO
|
||||
#define REDPINE_CC2500_INO
|
||||
|
||||
//The protocols below need a NRF24L01 to be installed
|
||||
#define ASSAN_NRF24L01_INO
|
||||
@@ -184,15 +195,18 @@
|
||||
#define HISKY_NRF24L01_INO
|
||||
#define HONTAI_NRF24L01_INO
|
||||
#define H8_3D_NRF24L01_INO
|
||||
#define KF606_NRF24L01_INO
|
||||
#define KN_NRF24L01_INO
|
||||
#define MJXQ_NRF24L01_INO
|
||||
#define MT99XX_NRF24L01_INO
|
||||
#define NCC1701_NRF24L01_INO
|
||||
#define NCC1701_NRF24L01_INO
|
||||
#define POTENSIC_NRF24L01_INO
|
||||
#define Q303_NRF24L01_INO
|
||||
#define SHENQI_NRF24L01_INO
|
||||
#define SLT_NRF24L01_INO
|
||||
#define SYMAX_NRF24L01_INO
|
||||
#define V2X2_NRF24L01_INO
|
||||
#define V761_NRF24L01_INO
|
||||
#define V911S_NRF24L01_INO
|
||||
#define YD717_NRF24L01_INO
|
||||
|
||||
@@ -207,10 +221,10 @@
|
||||
// For more throw, 1024..1976us @100% and 904..2096us @125%, remove the "//" on the line below. Be aware that too much throw can damage some UMX servos. To achieve standard throw in this mode use a channel weight of 84%.
|
||||
//#define DSM_MAX_THROW
|
||||
//Some models (X-Vert, Blade 230S...) require a special value to instant stop the motor(s).
|
||||
// You can disable this feature by adding "//" on the line below. You have to specify which channel (15 by default) will be used to kill the throttle channel.
|
||||
// If the channel 15 is above -50% the throttle is untouched but if it is between -50% and -100%, the throttle output will be forced between -100% and -150%.
|
||||
// You can disable this feature by adding "//" on the line below. You have to specify which channel (14 by default) will be used to kill the throttle channel.
|
||||
// If the channel 14 is above -50% the throttle is untouched but if it is between -50% and -100%, the throttle output will be forced between -100% and -150%.
|
||||
// For example, a value of -80% applied on channel 15 will instantly kill the motors on the X-Vert.
|
||||
#define DSM_THROTTLE_KILL_CH 15
|
||||
#define DSM_THROTTLE_KILL_CH 14
|
||||
|
||||
//AFHDS2A specific settings
|
||||
//-------------------------
|
||||
@@ -465,6 +479,7 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
|
||||
H8S3D
|
||||
X16_AH
|
||||
IRDRONE
|
||||
DHD_D4
|
||||
PROTO_BUGS
|
||||
NONE
|
||||
PROTO_BUGSMINI
|
||||
@@ -556,6 +571,8 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
|
||||
H501
|
||||
PROTO_J6PRO
|
||||
NONE
|
||||
PROTO_KF606
|
||||
NONE
|
||||
PROTO_KN
|
||||
WLTOYS
|
||||
FEILUN
|
||||
@@ -575,6 +592,8 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
|
||||
FY805
|
||||
PROTO_NCC1701
|
||||
NONE
|
||||
PROTO_POTENSIC
|
||||
NONE
|
||||
PROTO_Q2X2
|
||||
Q222
|
||||
Q242
|
||||
@@ -584,6 +603,9 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
|
||||
CX35
|
||||
CX10D
|
||||
CX10WD
|
||||
PROTO_REDPINE
|
||||
RED_FAST
|
||||
RED_SLOW
|
||||
PROTO_SFHSS
|
||||
NONE
|
||||
PROTO_SHENQI
|
||||
@@ -598,10 +620,12 @@ const PPM_Parameters PPM_prot[14*NBR_BANKS]= {
|
||||
SYMAX
|
||||
SYMAX5C
|
||||
PROTO_TRAXXAS
|
||||
NONE
|
||||
RX6519
|
||||
PROTO_V2X2
|
||||
V2X2
|
||||
JXD506
|
||||
PROTO_V761
|
||||
NONE
|
||||
PROTO_V911S
|
||||
NONE
|
||||
PROTO_WFLY
|
||||
|
||||
20
Multiprotocol/iface_xn297l.h
Normal file
20
Multiprotocol/iface_xn297l.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#ifndef _IFACE_XN297L_H_
|
||||
|
||||
#define _IFACE_XN297L_H_
|
||||
|
||||
#if defined (XN297L_CC2500_EMU)
|
||||
#include "iface_cc2500.h"
|
||||
#elif defined (NRF24L01_INSTALLED)
|
||||
#include "iface_nrf24l01.h"
|
||||
#endif
|
||||
|
||||
static void __attribute__((unused)) XN297L_Init();
|
||||
static void __attribute__((unused)) XN297L_SetTXAddr(const uint8_t*, uint8_t);
|
||||
static void __attribute__((unused)) XN297L_WritePayload(uint8_t*, uint8_t);
|
||||
static void __attribute__((unused)) XN297L_HoppingCalib(__attribute__((unused)) uint8_t);
|
||||
static void __attribute__((unused)) XN297L_Hopping(uint8_t);
|
||||
static void __attribute__((unused)) XN297L_RFChannel(uint8_t);
|
||||
static void __attribute__((unused)) XN297L_SetPower();
|
||||
static void __attribute__((unused)) XN297L_SetFreqOffset();
|
||||
|
||||
#endif
|
||||
@@ -68,15 +68,15 @@ You've upgraded the module but the radio does not display the name of the protoc
|
||||
Protocol Name|Protocol Number|Sub_Proto 0|Sub_Proto 1|Sub_Proto 2|Sub_Proto 3|Sub_Proto 4|Sub_Proto 5|Sub_Proto 6|Sub_Proto 7|RF Module
|
||||
---|---|---|---|---|---|---|---|---|---|---
|
||||
[Assan](Protocols_Details.md#ASSAN---24)|24|ASSAN||||||||NRF24L01
|
||||
[Bayang](Protocols_Details.md#BAYANG---14)|14|Bayang|H8S3D|X16_AH|IRDRONE|||||NRF24L01
|
||||
[Bayang](Protocols_Details.md#BAYANG---14)|14|Bayang|H8S3D|X16_AH|IRDRONE|DHD_D4||||NRF24L01
|
||||
[Bugs](Protocols_Details.md#BUGS---41)|41|BUGS||||||||A7105
|
||||
[BugsMini](Protocols_Details.md#BUGSMINI---42)|42|BUGSMINI|BUGSMINI|BUGS3H||||||NRF24L01
|
||||
[BugsMini](Protocols_Details.md#BUGSMINI---42)|42|BUGSMINI|BUGS3H|||||||NRF24L01
|
||||
[Cabell](Protocols_Details.md#Cabell---34)|34|Cabell_V3|C_TELEM|-|-|-|-|F_SAFE|UNBIND|NRF24L01
|
||||
CFlie|38|CFlie||||||||NRF24L01
|
||||
[CG023](Protocols_Details.md#CG023---13)|13|CG023|YD829|||||||NRF24L01
|
||||
[Corona](Protocols_Details.md#CORONA---37)|37|COR_V1|COR_V2|FD_V3||||||CC2500
|
||||
[CX10](Protocols_Details.md#CX10---12)|12|GREEN|BLUE|DM007|-|J3015_1|J3015_2|MK33041||NRF24L01
|
||||
[Devo](Protocols_Details.md#DEVO---7)|7|Devo||||||||CYRF6936
|
||||
[Devo](Protocols_Details.md#DEVO---7)|7|Devo|8CH|10CH|12CH|6CH|7CH|||CYRF6936
|
||||
[DM002](Protocols_Details.md#DM002---33)|33|DM002||||||||NRF24L01
|
||||
[DSM](Protocols_Details.md#DSM---6)|6|DSM2-22|DSM2-11|DSMX-22|DSMX-11|AUTO||||CYRF6936
|
||||
[E01X](Protocols_Details.md#E01X---45)|45|E012|E015|E016H||||||NRF24L01
|
||||
@@ -89,7 +89,7 @@ CFlie|38|CFlie||||||||NRF24L01
|
||||
[FrskyV](Protocols_Details.md#FRSKYV---25)|25|FrskyV||||||||CC2500
|
||||
[FrskyX](Protocols_Details.md#FRSKYX---15)|15|CH_16|CH_8|EU_16|EU_8|||||CC2500
|
||||
[FY326](Protocols_Details.md#FY326---20)|20|FY326|FY319|||||||NRF24L01
|
||||
[GD00X](Protocols_Details.md#GD00X---47)|47|V1|V2|||||||NRF24L01
|
||||
[GD00X](Protocols_Details.md#GD00X---47)|47|GD_V1*|GD_V2*|||||||NRF24L01
|
||||
[GW008](Protocols_Details.md#GW008---32)|32|GW008||||||||NRF24L01
|
||||
[H8_3D](Protocols_Details.md#H8_3D---36)|36|H8_3D|H20H|H20Mini|H30Mini|||||NRF24L01
|
||||
[Hisky](Protocols_Details.md#HISKY---4)|4|Hisky|HK310|||||||NRF24L01
|
||||
@@ -97,26 +97,34 @@ CFlie|38|CFlie||||||||NRF24L01
|
||||
[Hontai](Protocols_Details.md#HONTAI---26)|26|HONTAI|JJRCX1|X5C1|FQ777_951|||||NRF24L01
|
||||
[Hubsan](Protocols_Details.md#HUBSAN---2)|2|H107|H301|H501||||||A7105
|
||||
[J6Pro](Protocols_Details.md#J6Pro---22)|22|J6PRO||||||||CYRF6936
|
||||
[KF606](Protocols_Details.md#KF606---49)|49|KF606*||||||||NRF24L01
|
||||
[KN](Protocols_Details.md#KN---9)|9|WLTOYS|FEILUN|||||||NRF24L01
|
||||
[MJXq](Protocols_Details.md#MJXQ---18)|18|WLH08|X600|X800|H26D|E010|H26WH|PHOENIX||NRF24L01
|
||||
[MJXq](Protocols_Details.md#MJXQ---18)|18|WLH08|X600|X800|H26D|E010*|H26WH|PHOENIX*||NRF24L01
|
||||
[MT99xx](Protocols_Details.md#MT99XX---17)|17|MT|H7|YZ|LS|FY805||||NRF24L01
|
||||
[NCC1701](Protocols_Details.md#NCC1701---44)|44|NCC1701||||||||NRF24L01
|
||||
[OpenLRS](Protocols_Details.md#OpenLRS---27)|27|||||||||None
|
||||
[Potensic](Protocols_Details.md#Potensic---51)|51|A20||||||||NRF24L01
|
||||
[Q2X2](Protocols_Details.md#Q2X2---29)|29|Q222|Q242|Q282||||||NRF24L01
|
||||
[Q303](Protocols_Details.md#Q303---31)|31|Q303|CX35|CX10D|CX10WD|||||NRF24L01
|
||||
[Redpine](Protocols_Details.md#Redpine---50)|50|FAST|SLOW|||||||NRF24L01
|
||||
[SFHSS](Protocols_Details.md#SFHSS---21)|21|SFHSS||||||||CC2500
|
||||
[Shenqi](Protocols_Details.md#Shenqi---19)|19|Shenqi||||||||NRF24L01
|
||||
[SLT](Protocols_Details.md#SLT---11)|11|SLT_V1|SLT_V2|Q100|Q200|MR100||||NRF24L01
|
||||
[SymaX](Protocols_Details.md#Symax---10)|10|SYMAX|SYMAX5C|||||||NRF24L01
|
||||
Traxxas|43|Traxxas||||||||NRF24L01
|
||||
[Traxxas](Protocols_Details.md#Traxxas---43)|43|Traxxas|RX6519|||||||CYRF6936
|
||||
[V2x2](Protocols_Details.md#V2X2---5)|5|V2x2|JXD506|||||||NRF24L01
|
||||
[V911S](Protocols_Details.md#V911S---46)|46|V911S||||||||NRF24L01
|
||||
[V761](Protocols_Details.md#V761---48)|48|V761||||||||NRF24L01
|
||||
[V911S](Protocols_Details.md#V911S---46)|46|V911S*||||||||NRF24L01
|
||||
[WFly](Protocols_Details.md#WFLY---40)|40|WFLY||||||||CYRF6936
|
||||
[WK2x01](Protocols_Details.md#WK2X01---30)|30|WK2801|WK2401|W6_5_1|W6_6_1|W6_HEL|W6_HEL_I|||CYRF6936
|
||||
[YD717](Protocols_Details.md#YD717---8)|8|YD717|SKYWLKR|SYMAX4|XINXUN|NIHUI||||NRF24L01
|
||||
* "*" Sub Protocols designated by * suffix will use the NRF24L01 module by default to emulate the XN297L RF chip.
|
||||
* If a CC2500 module is installed it will be used instead as it is proving to be a better option for the XN297L@250kbps. Each specific sub protocol has a more detailed explanation.
|
||||
|
||||
# A7105 RF Module
|
||||
|
||||
If USE_A7105_CH15_TUNING is enabled, the value of channel 15 is used by all A7105 protocols for tuning the frequency. This is required in rare cases where some A7105 modules and/or RXs have an inaccurate crystal oscillator.
|
||||
|
||||
## FLYSKY - *1*
|
||||
Extended limits supported
|
||||
|
||||
@@ -153,13 +161,15 @@ CH5|CH6|CH7
|
||||
Extended limits and failsafe supported
|
||||
|
||||
Telemetry enabled protocol:
|
||||
- by defaut using FrSky Hub protocol (for example er9x): RX&battery voltages and RX&TX RSSI
|
||||
- by defaut using FrSky Hub protocol (for example er9x): RX(A1), battery voltage FS-CVT01(A2) and RX&TX RSSI
|
||||
- if using ersky9x and OpenTX: full telemetry information available
|
||||
|
||||
Option is used to change the servo refresh rate. A value of 0 gives 50Hz (min), 70 gives 400Hz (max). Specific refresh rate value can be calculated like this option=(refresh_rate-50)/5.
|
||||
|
||||
**RX_Num is used to give a number a given RX. You must use a different RX_Num per RX. A maximum of 16 AFHDS2A RXs are supported.**
|
||||
|
||||
OpenTX suggested RSSI alarm threshold settings (Telemetry tab): Low=15, Critical=12.
|
||||
|
||||
If telemetry is incomplete (missing RX RSSI for example), it means that you have to upgrade your RX firmware to version 1.6 or later. You can do it from an original Flysky TX or using a STLink like explained in [this tutorial](https://www.rcgroups.com/forums/showthread.php?2677694-How-to-upgrade-Flysky-Turnigy-iA6B-RX-to-firmware-1-6-with-a-ST-Link).
|
||||
|
||||
AFHDS2A_LQI_CH is a feature which is disabled by defaut in the _config.h file. When enabled, it makes LQI (Link Quality Indicator) available on one of the RX ouput channel (5-14).
|
||||
@@ -364,12 +374,14 @@ A|E|T|R|CH5|CH6|CH7|CH8
|
||||
***
|
||||
# CYRF6936 RF Module
|
||||
|
||||
If USE_CYRF6936_CH15_TUNING is enabled, the value of channel 15 is used by all CYRF6936 protocols for tuning the frequency. This is required in rare cases where some CYRF6936 modules and/or RXs have an inaccurate crystal oscillator.
|
||||
|
||||
## DEVO - *7*
|
||||
Extended limits and failsafe supported
|
||||
|
||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
||||
---|---|---|---|---|---|---|---
|
||||
A|E|T|R|CH5|CH6|CH7|CH8
|
||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12
|
||||
---|---|---|---|---|---|---|---|---|---|---|---
|
||||
A|E|T|R|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12
|
||||
|
||||
Note that the RX ouput will be EATR.
|
||||
|
||||
@@ -394,6 +406,12 @@ Bind procedure using PPM:
|
||||
- To verify that the TX is in fixed mode: power cycle the TX, the module LED should be solid ON (no blink).
|
||||
- Note: Autobind/fixed ID mode is linked to the RX_Num number. Which means that you can have multiple dial numbers set to the same protocol DEVO with different RX_Num and have different bind modes at the same time. It enables PPM users to get model match under DEVO.
|
||||
|
||||
### Sub_protocol 8CH - *0*
|
||||
### Sub_protocol 10CH - *1*
|
||||
### Sub_protocol 12CH - *2*
|
||||
### Sub_protocol 6CH - *3*
|
||||
### Sub_protocol 7CH - *4*
|
||||
|
||||
## WK2X01 - *30*
|
||||
Extended limits supported
|
||||
Autobind protocol
|
||||
@@ -469,16 +487,16 @@ Telemetry enabled for TSSI and plugins
|
||||
|
||||
option=number of channels from 4 to 12. An invalid option value will end up with 6 channels.
|
||||
|
||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|----|----|CH15
|
||||
---|---|---|---|---|---|---|---|---|----|----|----|----|----|----
|
||||
A|E|T|R|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|----|----|TH_KILL
|
||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|----|CH14
|
||||
---|---|---|---|---|---|---|---|---|----|----|----|----|----
|
||||
A|E|T|R|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12|----|TH_KILL
|
||||
|
||||
Notes:
|
||||
- model/type/number of channels indicated on the RX can be different from what the RX is in fact wanting to see. So don't hesitate to test different combinations until you have something working. Using Auto is the best way to find these settings.
|
||||
- RX output will match the Spektrum standard TAER independently of the input configuration AETR, RETA...
|
||||
- RX output will match the Spektrum standard throw (1500µs +/- 400µs -> 1100..1900µs) for a 100% input. This is true for both Serial and PPM input. For PPM, make sure the end points PPM_MIN_100 and PPM_MAX_100 in _config.h are matching your TX ouput. The maximum ouput is 1000..2000µs based on an input of 125%.
|
||||
- If you want to override the above and get maximum throw (old way) uncomment in _config.h the line #define DSM_MAX_THROW . In this mode to achieve standard throw use a channel weight of 84%.
|
||||
- TH_KILL is a feature which is enabled on channel 15 by default (can be disabled/changed) in the _config.h file. Some models (X-Vert, Blade 230S...) require a special position to instant stop the motor(s). If the channel 15 is above -50% the throttle is untouched but if it is between -50% and -100%, the throttle output will be forced between -100% and -150%. For example, a value of -80% applied on channel 15 will instantly kill the motors on the X-Vert.
|
||||
- TH_KILL is a feature which is enabled on channel 14 by default (can be disabled/changed) in the _config.h file. Some models (X-Vert, Blade 230S...) require a special position to instant stop the motor(s). If the channel 15 is above -50% the throttle is untouched but if it is between -50% and -100%, the throttle output will be forced between -100% and -150%. For example, a value of -80% applied on channel 14 will instantly kill the motors on the X-Vert.
|
||||
|
||||
### Sub_protocol DSM2_22 - *0*
|
||||
DSM2, Resolution 1024, refresh rate 22ms
|
||||
@@ -501,6 +519,15 @@ CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12
|
||||
---|---|---|---|---|---|---|---|---|----|----|----
|
||||
A|E|T|R|CH5|CH6|CH7|CH8|CH9|CH10|CH11|CH12
|
||||
|
||||
## Traxxas - *43*
|
||||
Receiver 6519
|
||||
|
||||
Extended limits supported
|
||||
|
||||
CH1|CH2|CH3|CH4
|
||||
---|---|---|---
|
||||
AUX3|AUX4|THROTTLE|STEERING
|
||||
|
||||
## WFLY - *40*
|
||||
Receivers: WFR04S, WFR07S, WFR09S
|
||||
|
||||
@@ -565,6 +592,13 @@ CH12|CH13
|
||||
----|----
|
||||
TAKE_OFF|EMG_STOP
|
||||
|
||||
### Sub_protocol DHD_D4 - *4*
|
||||
Model: DHD D4
|
||||
|
||||
CH12|CH13
|
||||
----|----
|
||||
TAKE_OFF|EMG_STOP
|
||||
|
||||
## BUGSMINI - *42*
|
||||
Models: MJX Bugs 3 Mini and 3H
|
||||
|
||||
@@ -581,7 +615,9 @@ ANGLE: angle is +100%, acro is -100%
|
||||
### Sub_protocol BUGSMINI - *0*
|
||||
|
||||
### Sub_protocol BUGS3H - *1*
|
||||
|
||||
CH11|
|
||||
---|
|
||||
ALTHOLD|
|
||||
|
||||
## Cabell - *34*
|
||||
Homegrown protocol with variable number of channels (4-16) and telemetry (RSSI, V1, V2).
|
||||
@@ -738,19 +774,25 @@ CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
||||
A|E|T|R|FLIP|RTH|HEADLESS|EXPERT
|
||||
|
||||
## GD00X - *47*
|
||||
Model: GD005 C-17 Transport and GD006 DA62
|
||||
Model: GD005 C-17 Transport, GD006 DA62 and ZC-Z50
|
||||
|
||||
If the model does not respond well to inputs or hard to bind, you can try to set Power to Low. But this protocol is known to be problematic because it's using the xn297L emulation with a transmission speed of 250kbps therefore it doesn't work very well with every modules, this is an hardware issue with the accuracy of the components used and nothing we can do about it in the firmware.
|
||||
|
||||
CH1|CH2|CH3|CH4|CH5|CH6
|
||||
---|---|---|---|---|---
|
||||
A||T||TRIM|LED
|
||||
If a CC2500 rf component is available it will be used in place of the NRF24L01 which might fix the issue mentioned above. Option is used for fine frequency tuning like any CC2500 protocols. Check the [Frequency Tuning page](/docs/Frequency_Tuning.md) to determine it if necessary.
|
||||
|
||||
### Sub_protocol V1 - *0*
|
||||
First model
|
||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7
|
||||
---|---|---|---|---|---|---
|
||||
A||T||TRIM|LED|RATE
|
||||
|
||||
### Sub_protocol V2 - *1*
|
||||
New model
|
||||
TRIM: either use this channel for trim only or add a mixer with aileron to increase the roll rate.
|
||||
|
||||
RATE: -100% high rate, +100% low rate
|
||||
|
||||
### Sub_protocol GD_V1 - *0*
|
||||
First generation of GD models, ZC-Z50
|
||||
|
||||
### Sub_protocol GD_V2 - *1*
|
||||
New generation of GD models
|
||||
|
||||
## GW008 - *32*
|
||||
Model: Global Drone GW008 from Banggood
|
||||
@@ -834,6 +876,17 @@ ARM|
|
||||
|
||||
### Sub_protocol FQ777_951 - *3*
|
||||
|
||||
## KF606 - *49*
|
||||
Model: KF606
|
||||
|
||||
If the model does not respond well to inputs or hard to bind, you can try to set Power to Low. But this protocol is known to be problematic because it's using the xn297L emulation with a transmission speed of 250kbps therefore it doesn't work very well with every modules, this is an hardware issue with the accuracy of the components used and nothing we can do about it in the firmware.
|
||||
|
||||
If a CC2500 rf component is available it will be used in place of the NRF24L01 which might fix the issue mentioned above. Option is used for fine frequency tuning like any CC2500 protocols. Check the [Frequency Tuning page](/docs/Frequency_Tuning.md) to determine it if necessary.
|
||||
|
||||
CH1|CH2|CH3|CH4|CH5
|
||||
---|---|---|---|---
|
||||
A||T||TRIM
|
||||
|
||||
## MJXQ - *18*
|
||||
Autobind protocol
|
||||
|
||||
@@ -855,6 +908,8 @@ Only 3 TX IDs available, change RX_Num value 0..2 to cycle through them
|
||||
|
||||
If the model does not respond well to inputs or hard to bind, you can try to set Power to Low. But this protocol is known to be problematic because it's using the xn297L emulation with a transmission speed of 250kbps therefore it doesn't work very well with every modules, this is an hardware issue with the accuracy of the components used and nothing we can do about it in the firmware.
|
||||
|
||||
If a CC2500 rf component is available it will be used in place of the NRF24L01 which might fix the issue mentioned above. Option is used for fine frequency tuning like any CC2500 protocols. Check the [Frequency Tuning page](/docs/Frequency_Tuning.md) to determine it if necessary.
|
||||
|
||||
### Sub_protocol H26WH - *5*
|
||||
CH6|
|
||||
---|
|
||||
@@ -862,7 +917,7 @@ ARM|
|
||||
|
||||
Only 1 TX ID available
|
||||
|
||||
### Sub_protocol H26WH - *6*
|
||||
### Sub_protocol PHOENIX - *6*
|
||||
CH6|
|
||||
---|
|
||||
ARM|
|
||||
@@ -880,6 +935,7 @@ Models: MT99xx
|
||||
Models: Eachine H7, Cheerson CX023
|
||||
### Sub_protocol YZ - *2*
|
||||
Model: Yi Zhan i6S
|
||||
|
||||
Only one model can be flown at the same time since the ID is hardcoded.
|
||||
|
||||
If the model does not respond well to inputs or hard to bind, you can try to set Power to Low. But this protocol is known to be problematic because it's using the xn297L emulation with a transmission speed of 250kbps therefore it doesn't work very well with every modules, this is an hardware issue with the accuracy of the components used and nothing we can do about it in the firmware.
|
||||
@@ -913,6 +969,21 @@ CH1|CH2|CH3|CH4|CH5
|
||||
---|---|---|---|---
|
||||
A|E|T|R|Warp
|
||||
|
||||
## Potensic - *51*
|
||||
Models: Potensic A20
|
||||
|
||||
CH1|CH2|CH3|CH4|CH5|CH6|CH7|CH8
|
||||
---|---|---|---|---|---|---|---
|
||||
A|E|T|R|TAKE_OFF/LANDING|EMERGENCY|MODE|HEADLESS
|
||||
|
||||
TAKE_OFF/LANDING: momentary switch -100% -> +100%
|
||||
|
||||
EMERGENCY: Stop +100%
|
||||
|
||||
MODE: Beginner -100%, Medium 0%, Advanced +100%
|
||||
|
||||
HEADLESS: Off -100%, On +100%
|
||||
|
||||
## Q2X2 - *29*
|
||||
### Sub_protocol Q222 - *0*
|
||||
Models: Q222 v1 and V686 v2
|
||||
@@ -963,6 +1034,12 @@ ARM|FLIP
|
||||
|
||||
ARM is 3 positions: -100%=land / 0%=manual / +100%=take off
|
||||
|
||||
## Redpine - *50*
|
||||
[Link to the forum](https://www.rcgroups.com/forums/showthread.php?3236043-Redpine-Lowest-latency-RC-protocol)
|
||||
|
||||
### Sub_protocol FAST - *0*
|
||||
### Sub_protocol SLOW - *1*
|
||||
|
||||
## Shenqi - *19*
|
||||
Autobind protocol
|
||||
|
||||
@@ -1080,11 +1157,24 @@ CH10|CH11|CH12
|
||||
---|---|---
|
||||
Start/Stop|EMERGENCY|CAMERA_UP/DN
|
||||
|
||||
## V761 - *48*
|
||||
Model: Volantex V761 and may be other
|
||||
|
||||
Warning: Only 3 IDs, you can cycle through them using RX_Num.
|
||||
|
||||
CH1|CH2|CH3|CH4|CH5
|
||||
---|---|---|---|---
|
||||
-|E|T|R|GYRO
|
||||
|
||||
Gyro: -100%=Beginer mode (Gyro on, yaw and pitch rate limited), 0%=Mid Mode ( Gyro on no rate limits), +100%=Mode Expert Gyro off
|
||||
|
||||
## V911S - *46*
|
||||
Models: WLtoys V911S, XK A110
|
||||
|
||||
If the model does not respond well to inputs or hard to bind, you can try to set Power to Low. But this protocol is known to be problematic because it's using the xn297L emulation with a transmission speed of 250kbps therefore it doesn't work very well with every modules, this is an hardware issue with the accuracy of the components used and nothing we can do about it in the firmware.
|
||||
|
||||
If a CC2500 rf component is available it will be used in place of the NRF24L01 which might fix the issue mentioned above. Option is used for fine frequency tuning like any CC2500 protocols. Check the [Frequency Tuning page](/docs/Frequency_Tuning.md) to determine it if necessary.
|
||||
|
||||
CH1|CH2|CH3|CH4|CH5
|
||||
---|---|---|---|---
|
||||
A|E|T|R|CALIB
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
# Compiling and Programming (STM32)
|
||||
# Flashing, Compiling and Programming (STM32)
|
||||
|
||||
Multiprotocol firmware is compiled using the Arduino IDE. The guide below will walk you through all the steps to compile and upload your customized firmware.
|
||||
Multiprotocol firmware can be either flashed with a precompiled binary (Option-1) or compile/upload your customized firmware using the Arduino IDE (Option-2).
|
||||
|
||||
**These instructions are for the STM32 version of the Multiprotocol module.** If you are Compling for the Arduino ATmega328p version of the Multiprotocol Module please go to the dedicated [ATmega328](Compiling.md) page.
|
||||
|
||||
## Index
|
||||
1. [Tools Required](#tools-required)
|
||||
1. [Preparation](#preparation)
|
||||
1. [Option-1 Update firmware using precompiled binaries](#option-1-update-firmware-using-precompiled-binaries)
|
||||
1. [Option-2 Compiling and updating firmware](#option-2-compiling-and-updating-firmware)
|
||||
1. [Preparation](#preparation)
|
||||
1. [Install the Arduino IDE](#install-the-arduino-ide)
|
||||
1. [Download the Multiprotocol source and open the project](#download-the-multiprotocol-source-and-open-the-project)
|
||||
1. [Install the Multi 4-in-1 board](#install-the-multi-4-in-1-board)
|
||||
@@ -20,14 +22,22 @@ Multiprotocol firmware is compiled using the Arduino IDE. The guide below will w
|
||||
1. [Upload via USB](#upload-via-usb)
|
||||
1. [Install the Maple USB Drivers](#install-the-maple-usb-drivers)
|
||||
1. [Upload the firmware](#upload-the-firmware)
|
||||
1. [Precompiled Binaries](#flashing-pre-compiled-binaries)
|
||||
1. [Troubleshooting](#troubleshooting)
|
||||
|
||||
## Tools required
|
||||
|
||||
**Notes**:
|
||||
* The Vantac MPM Lite module most likely already has the USB Bootloader flashed on it. You can directly use the [upload via USB](#upload-via-usb) method. Early modules' bootloader was however not booting everytime, if this is the case you need to upgarde it.
|
||||
Tools are only required if a multi module does not have a USB port, a working bootloader or an integrated FTDI adapter:
|
||||
* The latest iRangeX IRX4+ modules most likely already have the USB Bootloader flashed on it. You therefore don't need the FTDI adapter below and don't need to open your module to flash it.
|
||||
* The latest jumper modules have an integrated FTDI appearing as a CP2102 device on the computer. You therefore don't need the FTDI adapter below and don't need to open your module to flash it.
|
||||
* The Vantac MPM Lite module already has the USB Bootloader flashed on it. You therefore don't need the FTDI adapter below and don't need to open your module to flash it. **Modules' bootloader however might not be booting everytime depending on the radio, if this is the case you need to upgrade it.**
|
||||
|
||||
You are still unsure if your module can be flashed without tools or opening it? Here is how to quickly check:
|
||||
* Power off the TX
|
||||
* Connect a USB cable to the module, if the module does not have a USB port then you must open the module to flash it using an external FTDI
|
||||
* Connect the cable to the PC and power on the the TX
|
||||
* If the PC does not complain about a none working device being plugged then you are good to upgrade via USB directly without the need of any tools or opening the module.
|
||||
|
||||
Your multi module is not USB upgradable ready, here is what you need:
|
||||
|
||||
| **3.3V USB-TTL Adapter** | **4-pin Serial Programming Header** |
|
||||
|:---:|:--:|
|
||||
@@ -44,7 +54,29 @@ The 4-pin header needs to be soldered onto the board as indicated by the red rec
|
||||
|
||||
**Note:** The Banggood STM32 module most likely already has the header pin in place.
|
||||
|
||||
## Option-1 Update Firmware using Precompiled Binaries
|
||||
If you don't need/want to customize the multi module firmware then you can use pre-compiled binaries available [here](https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/releases).
|
||||
|
||||
**STM32 Builds (file names beginning with 'Multi-STM_')
|
||||
- All radio modules and protocols are included in all builds
|
||||
- Files with TXFLASH in the name are built with a bootloader for flashing from a transmitter OR via the module's USB port (eg. Multi-STM_TXFLASH_INV-vX.X.X.XX.bin)
|
||||
- Files with FTDI in the name are built without a bootloader for flashing using an FTDI adapter (eg. Multi-STM_FTDI_INV-vX.X.X.XX.bin)
|
||||
- OpenTx/JumperTX version (files with OPENTX in the name) have the MULTI_TELEMETRY parameter enabled (eg. Multi-STM_TXFLASH_INV_OPENTX-vX.X.X.XX.bin or Multi-STM_FTDI_INV_OPENTX-vvX.X.X.XX.bin)
|
||||
|
||||
[Flash-Multi](https://github.com/benlye/flash-multi) is the recommended Windows utility for flashing pre-compiled firmware to any STM32-based Multiprotocol TX module. Firmware upload can be performed using the built-in USB connection or via an external FTDI adapter.
|
||||
|
||||
<p align="center">
|
||||
<img src="https://github.com/benlye/flash-multi/raw/master/img/flash-multi.jpg">
|
||||
</p>
|
||||
|
||||
After a succesful flash your Module is now updated to the newer version firmware using the most common options. To change specific configured options you would need to use Option-2, Compile and flash update using Arduino IDE.
|
||||
|
||||
# Option-2 Compiling and Updating Firmware
|
||||
|
||||
## Preparation
|
||||
|
||||
Multiprotocol firmware can be compiled and uploaded with your customized firmware using the Arduino IDE. The guide below will walk you through all the steps in many details, don't be afraid by the length it is in fact simple!
|
||||
|
||||
### Install the Arduino IDE
|
||||
1. Download and install the Arduino IDE. The currently supported Arduino version is 1.8.5, available for [Windows]( https://www.arduino.cc/download_handler.php?f=/arduino-1.8.5-windows.exe), [Mac OSX](https://www.arduino.cc/download_handler.php?f=/arduino-1.8.5-macosx.zip) and [Linux (64-bit)](https://www.arduino.cc/download_handler.php?f=/arduino-1.8.5-linux64.tar.xz)
|
||||
1. It is recommended to upgrade Java to the [latest version](https://www.java.com/en/download/)
|
||||
@@ -273,17 +305,6 @@ error resetting after download: usb_reset: could not reset device, win error: Th
|
||||
|
||||
**Note:** The line `Reset via USB Serial Failed! Did you select the right serial port?` or a warning line stating that the device could not be reset is **not a problem**.
|
||||
|
||||
## Flashing pre-compiled binaries
|
||||
Pre-compiled binaries are available [here](https://github.com/pascallanger/DIY-Multiprotocol-TX-Module/releases).
|
||||
- **Multiprotocol_V1.X.X_STM32.bin** files are for transmitters with support for hardware telemetry inversion, such as Turnigy 9X, 9XR, 9X+.
|
||||
- **Multiprotocol_V1.X.X_STM32_INV.bin** files are for tranismitters which require telemetry inverted in the module firmware, such as Taranis.
|
||||
|
||||
If you want to flash a pre-compiled binary file (like the Release .bin files) you will use the same USB-to-TTL adapter as [above](#connect-the-programmer).
|
||||
|
||||
You will also need to download the **ST Flash Loader Demonstrator** from [here](http://www.st.com/content/st_com/en/products/development-tools/software-development-tools/stm32-software-development-tools/stm32-programmers/flasher-stm32.html)
|
||||
|
||||
Run the **ST Flash Loader Demonstrator** program. There are many tutorials on the web on how to use this program, for example [here](http://www.scienceprog.com/flashing-programs-to-stm32-embedded-bootloader).
|
||||
|
||||
## Troubleshooting
|
||||
You can report your problem using the [GitHub issue](https://github.com/midelic/DIY-Multiprotocol-TX-Module/issues) system or go to the [Main thread on RCGROUPS](http://www.rcgroups.com/forums/showthread.php?t=2165676) to ask your question.
|
||||
Please provide the following information:
|
||||
|
||||
@@ -98,7 +98,7 @@ The next screen shows the mixer menu with the mode change on momentary switch SH
|
||||
<img src="images/Inductrix_Mixer.png" Width="600" Height="200" />
|
||||
|
||||
# Cheerson CX-20 / Quanum Nova
|
||||
<img src="http://uaequadcopters.com/images/products/Large/932-cheersoncx20dronquad.jpg" Width="200" Height="155" />
|
||||
<img src="images/cx20.jpg" Width="200" Height="155" />
|
||||
|
||||
## Channel Map
|
||||
|
||||
|
||||
BIN
docs/images/cx20.jpg
Normal file
BIN
docs/images/cx20.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 63 KiB |
BIN
docs/images/flash-multi.jpg
Normal file
BIN
docs/images/flash-multi.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 38 KiB |
Reference in New Issue
Block a user