From 995bb921c142a4de4903c68737e1dcb94db08784 Mon Sep 17 00:00:00 2001 From: pascallanger Date: Wed, 22 Mar 2017 14:55:55 +0100 Subject: [PATCH] DM002 protocol protocol number 33 sub_protocol none=0 ch5=flip ch6=led ch7=headless --- Boards/package_MULTI2_index.json | 99 +++++++++++++++++++++ Multiprotocol/Bayang_nrf24l01.ino | 7 +- Multiprotocol/CYRF6936_SPI.ino | 4 + Multiprotocol/DM002_nrf24l01.ino | 141 ++++++++++++++++++++++++++++++ Multiprotocol/Multiprotocol.h | 4 +- Multiprotocol/Multiprotocol.ino | 69 ++++++++++----- Multiprotocol/Validate.h | 1 + Multiprotocol/_Config.h | 24 ++++- 8 files changed, 318 insertions(+), 31 deletions(-) create mode 100644 Boards/package_MULTI2_index.json create mode 100644 Multiprotocol/DM002_nrf24l01.ino diff --git a/Boards/package_MULTI2_index.json b/Boards/package_MULTI2_index.json new file mode 100644 index 0000000..00c7d96 --- /dev/null +++ b/Boards/package_MULTI2_index.json @@ -0,0 +1,99 @@ +{ + "packages": [ + { + "name": "MULTI", + "maintainer": "Pascal", + "help": { + "online": "https://www.rcgroups.com/forums/showthread.php?2165676-DIY-Multiprotocol-TX-Module/page555" + }, + "websiteURL": "https://github.com/pascallanger/DIY-Multiprotocol-TX-Module", + "platforms": [ + { + "name": "Multi 4in1 Atmega328p", + "architecture": "avr", + "version": "1.0.0", + "category": "Multi", + "help": { + "online": "https://www.rcgroups.com/forums/showthread.php?2165676-DIY-Multiprotocol-TX-Module/page555" + }, + "url": "https://github.com/pascallanger/DIY-Multiprotocol-TX-Module", + "archiveFileName": "multi_avr-1.0.0.zip", + "checksum": "SHA-256:ec3ff8a1dc96d3ba6f432b9b837a35fd4174a34b3d2927de1d51010e8b94f9f1", + "size": "15005", + "boards": [ + {"name": "Multi 4in1 Atmega328p"}, + ], + "toolsDependencies": [ + { + "packager": "arduino", + "name": "avr-gcc", + "version": "4.8.1-arduino5" + }, + { + "packager": "arduino", + "name": "avrdude", + "version": "6.0.1-arduino5" + } + ] + }, + { + "name": "Multi 4in1 STM32", + "architecture": "stm32", + "version": "1.0.0", + "category": "Multi", + "help": { + "online": "https://www.rcgroups.com/forums/showthread.php?2165676-DIY-Multiprotocol-TX-Module/page555" + }, + "url": "https://github.com/pascallanger/DIY-Multiprotocol-TX-Module", + "archiveFileName": "multi_stm32-1.0.0.zip", + "checksum": "SHA-256:ec3ff8a1dc96d3ba6f432b9b837a35fd4174a34b3d2927de1d51010e8b94f9f1", + "size": "15005", + "boards": [ + {"name": "Multi 4in1 STM32"}, + ], + "toolsDependencies": [ + { + "packager": "arduino", + "name": "avr-gcc", + "version": "4.8.1-arduino5" + }, + { + "packager": "arduino", + "name": "avrdude", + "version": "6.0.1-arduino5" + } + ] + }, + { + "name": "Multi 4in1 OrangeTX", + "architecture": "xmega", + "version": "1.0.0", + "category": "Multi", + "help": { + "online": "https://www.rcgroups.com/forums/showthread.php?2165676-DIY-Multiprotocol-TX-Module/page555" + }, + "url": "https://github.com/pascallanger/DIY-Multiprotocol-TX-Module", + "archiveFileName": "multi_xmega-1.0.0.zip", + "checksum": "SHA-256:ec3ff8a1dc96d3ba6f432b9b837a35fd4174a34b3d2927de1d51010e8b94f9f1", + "size": "15005", + "boards": [ + {"name": "Multi 4in1 OrangeTX"}, + ], + "toolsDependencies": [ + { + "packager": "arduino", + "name": "avr-gcc", + "version": "4.8.1-arduino5" + }, + { + "packager": "arduino", + "name": "avrdude", + "version": "6.0.1-arduino5" + } + ] + } + ], + "tools":[] + } + ] +} diff --git a/Multiprotocol/Bayang_nrf24l01.ino b/Multiprotocol/Bayang_nrf24l01.ino index 00acd97..043dd0c 100644 --- a/Multiprotocol/Bayang_nrf24l01.ino +++ b/Multiprotocol/Bayang_nrf24l01.ino @@ -121,8 +121,7 @@ static void __attribute__((unused)) BAYANG_send_packet(uint8_t bind) #ifdef BAYANG_HUB_TELEMETRY if (option) { // switch radio to rx as soon as packet is sent - - while (!(NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_TX_DS))); + while (!(NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_TX_DS))); NRF24L01_WriteReg(NRF24L01_00_CONFIG, 0x03); } #endif @@ -131,7 +130,7 @@ static void __attribute__((unused)) BAYANG_send_packet(uint8_t bind) } #ifdef BAYANG_HUB_TELEMETRY -static void __attribute__((unused)) check_rx(void) +static void __attribute__((unused)) BAYANG_check_rx(void) { if (NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR)) { // data received from model @@ -204,7 +203,7 @@ uint16_t BAYANG_callback() } if (packet_count > 1) - check_rx(); + BAYANG_check_rx(); packet_count %= 5; } diff --git a/Multiprotocol/CYRF6936_SPI.ino b/Multiprotocol/CYRF6936_SPI.ino index ecab9a4..bbfe7ff 100644 --- a/Multiprotocol/CYRF6936_SPI.ino +++ b/Multiprotocol/CYRF6936_SPI.ino @@ -78,6 +78,7 @@ uint8_t CYRF_Reset() */ void CYRF_GetMfgData(uint8_t data[]) { +#ifndef FORCE_CYRF_ID /* Fuses power on */ CYRF_WriteRegister(CYRF_25_MFG_ID, 0xFF); @@ -85,6 +86,9 @@ void CYRF_GetMfgData(uint8_t data[]) /* Fuses power off */ CYRF_WriteRegister(CYRF_25_MFG_ID, 0x00); +#else + memcpy(data,FORCE_CYRF_ID,6); +#endif } /* diff --git a/Multiprotocol/DM002_nrf24l01.ino b/Multiprotocol/DM002_nrf24l01.ino new file mode 100644 index 0000000..057571b --- /dev/null +++ b/Multiprotocol/DM002_nrf24l01.ino @@ -0,0 +1,141 @@ +/* + This project is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Multiprotocol is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Multiprotocol. If not, see . + */ +// compatible with DM002 + +#if defined(DM002_NRF24L01_INO) + +#include "iface_nrf24l01.h" + +#define DM002_PACKET_PERIOD 6100 // Timeout for callback in uSec +#define DM002_INITIAL_WAIT 500 +#define DM002_PACKET_SIZE 12 // packets have 12-byte payload +#define DM002_RF_BIND_CHANNEL 0x27 +#define DM002_BIND_COUNT 655 // 4 seconds + + +enum DM002_FLAGS { + // flags going to packet[9] + DM002_FLAG_FLIP = 0x01, + DM002_FLAG_LED = 0x02, + DM002_FLAG_HEADLESS = 0x10, +}; + +static void __attribute__((unused)) DM002_send_packet(uint8_t bind) +{ + memcpy(packet+5,(uint8_t *)"\x00\x7F\x7F\x7F\x00\x00\x00",7); + if(bind) + { + packet[0] = 0xAA; + packet[1] = rx_tx_addr[0]; + packet[2] = rx_tx_addr[1]; + packet[3] = rx_tx_addr[2]; + packet[4] = rx_tx_addr[3]; + } + else + { + packet[0]=0x55; + // Throttle : 0 .. 200 + packet[1]=convert_channel_8b_scale(THROTTLE,0,200); + // Other channels min 0x57, mid 0x7F, max 0xA7 + packet[2] = convert_channel_8b_scale(RUDDER,0x57,0xA7); + packet[3] = convert_channel_8b_scale(ELEVATOR, 0x57,0xA7); + packet[4] = convert_channel_8b_scale(AILERON, 0x57,0xA7); + // Features + packet[9] = GET_FLAG(Servo_AUX1,DM002_FLAG_FLIP) + | GET_FLAG(Servo_AUX2,DM002_FLAG_LED) + | GET_FLAG(Servo_AUX3,DM002_FLAG_HEADLESS); + // Packet counter + if(packet_count&0x03) + { + packet_count++; + hopping_frequency_no++; + hopping_frequency_no&=4; + } + packet_count&=0x0F; + packet[10] = packet_count; + packet_count++; + } + //CRC + for(uint8_t i=0;iCYRF6936 MODE_Q303 = 31, // =>NRF24L01 MODE_GW008 = 32, // =>NRF24L01 + MODE_DM002 = 33, // =>NRF24L01 }; enum Flysky @@ -480,6 +481,7 @@ Serial: 100000 Baud 8e2 _ xxxx xxxx p -- WK2x01 30 Q303 31 GW008 32 + DM002 33 BindBit=> 0x80 1=Bind/0=No AutoBindBit=> 0x40 1=Yes /0=No RangeCheck=> 0x20 1=Yes /0=No diff --git a/Multiprotocol/Multiprotocol.ino b/Multiprotocol/Multiprotocol.ino index 1bf00c0..c6b795b 100644 --- a/Multiprotocol/Multiprotocol.ino +++ b/Multiprotocol/Multiprotocol.ino @@ -22,13 +22,22 @@ */ #include //#define DEBUG_TX +//#define USE_MY_CONFIG #include "Multiprotocol.h" //Multiprotocol module configuration file #include "_Config.h" +// Let's automatically select the board +// if arm is selected #ifdef __arm__ - #define STM32_BOARD // Let's automatically select this board if arm is selected since this is the only one for now... + #define STM32_BOARD #endif + +//Personal config file +#if defined USE_MY_CONFIG || __has_include("_MyConfig.h") + #include "_MyConfig.h" +#endif + #include "Pins.h" #include "TX_Def.h" #include "Validate.h" @@ -948,6 +957,12 @@ static void protocol_init() remote_callback = GW008_callback; break; #endif + #if defined(DM002_NRF24L01_INO) + case MODE_DM002: + next_callback=initDM002(); + remote_callback = DM002_callback; + break; + #endif #endif } } @@ -1158,35 +1173,41 @@ static uint32_t random_value(void) } #endif -static uint32_t random_id(uint16_t adress, uint8_t create_new) +static uint32_t random_id(uint16_t address, uint8_t create_new) { - uint32_t id=0; + #ifndef FORCE_GLOBAL_ID + uint32_t id=0; - if(eeprom_read_byte((EE_ADDR)(adress+10))==0xf0 && !create_new) - { // TXID exists in EEPROM - for(uint8_t i=4;i>0;i--) + if(eeprom_read_byte((EE_ADDR)(address+10))==0xf0 && !create_new) + { // TXID exists in EEPROM + for(uint8_t i=4;i>0;i--) + { + id<<=8; + id|=eeprom_read_byte((EE_ADDR)address+i-1); + } + if(id!=0x2AD141A7) //ID with seed=0 + return id; + } + // Generate a random ID + #if defined STM32_BOARD + #define STM32_UUID ((uint32_t *)0x1FFFF7E8) + if (!create_new) + id = STM32_UUID[0] ^ STM32_UUID[1] ^ STM32_UUID[2]; + #else + id = random(0xfefefefe) + ((uint32_t)random(0xfefefefe) << 16); + #endif + for(uint8_t i=0;i<4;i++) { - id<<=8; - id|=eeprom_read_byte((EE_ADDR)adress+i-1); + eeprom_write_byte((EE_ADDR)address+i,id); + id>>=8; } - if(id!=0x2AD141A7) //ID with seed=0 - return id; - } - // Generate a random ID - #if defined STM32_BOARD - #define STM32_UUID ((uint32_t *)0x1FFFF7E8) - if (!create_new) - id = STM32_UUID[0] ^ STM32_UUID[1] ^ STM32_UUID[2]; + eeprom_write_byte((EE_ADDR)(address+10),0xf0);//write bind flag in eeprom. + return id; #else - id = random(0xfefefefe) + ((uint32_t)random(0xfefefefe) << 16); + (void)address; + (void)create_new; + return FORCE_GLOBAL_ID; #endif - for(uint8_t i=0;i<4;i++) - { - eeprom_write_byte((EE_ADDR)adress+i,id); - id>>=8; - } - eeprom_write_byte((EE_ADDR)(adress+10),0xf0);//write bind flag in eeprom. - return id; } /**************************/ diff --git a/Multiprotocol/Validate.h b/Multiprotocol/Validate.h index 67c73af..f6077ec 100644 --- a/Multiprotocol/Validate.h +++ b/Multiprotocol/Validate.h @@ -70,6 +70,7 @@ #undef HONTAI_NRF24L01_INO #undef Q303_NRF24L01_INO #undef GW008_NRF24L01_INO + #undef DM002_NRF24L01_INO #endif //Make sure telemetry is selected correctly diff --git a/Multiprotocol/_Config.h b/Multiprotocol/_Config.h index 2a0598c..513ca8b 100644 --- a/Multiprotocol/_Config.h +++ b/Multiprotocol/_Config.h @@ -71,6 +71,23 @@ //#define NRF24L01_ENABLE_LOW_POWER +/*****************/ +/*** GLOBAL ID ***/ +/*****************/ +//A global ID is used by most protocols to bind and retain the bind to models. To prevent duplicate IDs, it is automatically +// generated using a random 32 bits number the first time the eeprom is initialized. +//If you have 2 Multi modules which you want to share the same ID so you can use either to control the same RC model +// then you can force the ID to a certain known value using the lines below. +//Default is commented, you should uncoment only for test purpose or if you know exactly what you are doing!!! +//#define FORCE_GLOBAL_ID 0x12345678 + +//Protocols using the CYRF6936 (DSM, Devo, Walkera...) are using the CYRF ID instead which should prevent duplicated IDs. +//If you have 2 Multi modules which you want to share the same ID so you can use either to control the same RC model +// then you can force the ID to a certain known value using the lines below. +//Default is commented, you should uncoment only for test purpose or if you know exactly what you are doing!!! +//#define FORCE_CYRF_ID "\x12\x34\x56\x78\x9A\xBC" + + /****************************/ /*** PROTOCOLS TO INCLUDE ***/ /****************************/ @@ -115,6 +132,7 @@ #define HONTAI_NRF24L01_INO #define Q303_NRF24L01_INO #define GW008_NRF24L01_INO +#define DM002_NRF24L01_INO /**************************/ /*** TELEMETRY SETTINGS ***/ @@ -210,8 +228,8 @@ const PPM_Parameters PPM_prot[15]= { /* 3 */ {MODE_FRSKYD, 0 , 0 , P_HIGH , NO_AUTOBIND , 40 }, // option=fine freq tuning /* 4 */ {MODE_HISKY , Hisky , 0 , P_HIGH , NO_AUTOBIND , 0 }, /* 5 */ {MODE_V2X2 , 0 , 0 , P_HIGH , NO_AUTOBIND , 0 }, -/* 6 */ {MODE_DSM , DSM2_22 , 0 , P_HIGH , NO_AUTOBIND , 6 }, // option=number of channels -/* 7 */ {MODE_DEVO , 0 , 0 , P_HIGH , NO_AUTOBIND , 0 }, +/* 6 */ {MODE_DSM , DSMX_11 , 0 , P_HIGH , NO_AUTOBIND , 6 }, // option=number of channels +/* 7 */ {MODE_DSM , DSM2_22 , 0 , P_HIGH , NO_AUTOBIND , 6 }, /* 8 */ {MODE_YD717 , YD717 , 0 , P_HIGH , NO_AUTOBIND , 0 }, /* 9 */ {MODE_KN , WLTOYS , 0 , P_HIGH , NO_AUTOBIND , 0 }, /* 10 */ {MODE_SYMAX , SYMAX , 0 , P_HIGH , NO_AUTOBIND , 0 }, @@ -339,6 +357,8 @@ const PPM_Parameters PPM_prot[15]= { CX10WD MODE_GW008 NONE + MODE_DM002 + NONE */ // RX_Num is used for model match. Using RX_Num values different for each receiver will prevent starting a model with the false config loaded...