mirror of
https://github.com/pascallanger/DIY-Multiprotocol-TX-Module.git
synced 2025-02-04 20:58:10 +00:00
984aa3f413
- Change how PPM is handled with a resolution of 2048 and scaled to match serial input range. PPM is now fully scaled for all protocols which was not the case before. If you are using PPM, you might have to adjust the end points depending on the protocols. - Change all range conversions to use 2048 where possible - Updated all protocols with new range functions - Protocols which are taking advantage of 2048 are Assan, FrSky V/D/X, DSM, Devo, WK2x01 - Renamed AUX xto CHx for code readbility
159 lines
4.9 KiB
C++
159 lines
4.9 KiB
C++
/*
|
|
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 Global Drone GW008 protocol.
|
|
// There are 3 versions of this small quad, this protocol is for the one with a XNS104 IC in the stock Tx and PAN159CY IC in the quad (SOCs with built-in xn297 compatible RF).
|
|
// The xn297 version is compatible with the CX10 protocol (green pcb).
|
|
// The LT8910 version is not supported yet.
|
|
|
|
#if defined(GW008_NRF24L01_INO)
|
|
|
|
#include "iface_nrf24l01.h"
|
|
|
|
#define GW008_INITIAL_WAIT 500
|
|
#define GW008_PACKET_PERIOD 2400
|
|
#define GW008_RF_BIND_CHANNEL 2
|
|
#define GW008_PAYLOAD_SIZE 15
|
|
|
|
enum {
|
|
GW008_BIND1,
|
|
GW008_BIND2,
|
|
GW008_DATA
|
|
};
|
|
|
|
static void __attribute__((unused)) send_packet(uint8_t bind)
|
|
{
|
|
packet[0] = rx_tx_addr[0];
|
|
if(bind)
|
|
{
|
|
packet[1] = 0x55;
|
|
packet[2] = hopping_frequency[0];
|
|
packet[3] = hopping_frequency[1];
|
|
packet[4] = hopping_frequency[2];
|
|
packet[5] = hopping_frequency[3];
|
|
memset(&packet[6], 0, 7);
|
|
packet[13] = 0xaa;
|
|
}
|
|
else
|
|
{
|
|
packet[1] = 0x01 | GET_FLAG(CH5, 0x40); // flip
|
|
packet[2] = convert_channel_16b_limit(AILERON , 200, 0); // aileron
|
|
packet[3] = convert_channel_16b_limit(ELEVATOR, 0, 200); // elevator
|
|
packet[4] = convert_channel_16b_limit(RUDDER , 200, 0); // rudder
|
|
packet[5] = convert_channel_16b_limit(THROTTLE, 0, 200); // throttle
|
|
packet[6] = 0xaa;
|
|
packet[7] = 0x02; // max rate
|
|
packet[8] = 0x00;
|
|
packet[9] = 0x00;
|
|
packet[10]= 0x00;
|
|
packet[11]= 0x00;
|
|
packet[12]= 0x00;
|
|
packet[13]= rx_tx_addr[2];
|
|
}
|
|
packet[14] = rx_tx_addr[1];
|
|
|
|
// Power on, TX mode, CRC enabled
|
|
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO) | _BV(NRF24L01_00_PWR_UP));
|
|
NRF24L01_WriteReg(NRF24L01_05_RF_CH, bind ? GW008_RF_BIND_CHANNEL : hopping_frequency[(hopping_frequency_no++)/2]);
|
|
hopping_frequency_no %= 8;
|
|
|
|
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
|
NRF24L01_FlushTx();
|
|
XN297_WriteEnhancedPayload(packet, GW008_PAYLOAD_SIZE, 0, 0x3c7d);
|
|
|
|
NRF24L01_SetPower(); // Set tx_power
|
|
}
|
|
|
|
static void __attribute__((unused)) GW008_init()
|
|
{
|
|
NRF24L01_Initialize();
|
|
NRF24L01_SetTxRxMode(TX_EN);
|
|
XN297_SetTXAddr((uint8_t*)"\xcc\xcc\xcc\xcc\xcc", 5);
|
|
XN297_SetRXAddr((uint8_t*)"\xcc\xcc\xcc\xcc\xcc", 5);
|
|
NRF24L01_FlushTx();
|
|
NRF24L01_FlushRx();
|
|
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
|
|
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknowldgement on all data pipes
|
|
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01);
|
|
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, GW008_PAYLOAD_SIZE+2); // payload + 2 bytes for pcf
|
|
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03);
|
|
NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0x00); // no retransmits
|
|
NRF24L01_SetBitrate(NRF24L01_BR_1M);
|
|
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); // Set feature bits on
|
|
NRF24L01_Activate(0x73);
|
|
}
|
|
|
|
static void __attribute__((unused)) GW008_initialize_txid()
|
|
{
|
|
uint32_t lfsr = random(0xfefefefe) + ((uint32_t)random(0xfefefefe) << 16);
|
|
for(uint8_t i=0; i<4; i++)
|
|
hopping_frequency[i] = 0x10 + ((lfsr >> (i*8)) % 0x37);
|
|
}
|
|
|
|
uint16_t GW008_callback()
|
|
{
|
|
switch(phase)
|
|
{
|
|
case GW008_BIND1:
|
|
if((NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR)) && // RX fifo data ready
|
|
XN297_ReadEnhancedPayload(packet, GW008_PAYLOAD_SIZE) == GW008_PAYLOAD_SIZE && // check payload size
|
|
packet[0] == rx_tx_addr[0] && packet[14] == rx_tx_addr[1]) // check tx id
|
|
{
|
|
NRF24L01_SetTxRxMode(TXRX_OFF);
|
|
NRF24L01_SetTxRxMode(TX_EN);
|
|
rx_tx_addr[2] = packet[13];
|
|
BIND_DONE;
|
|
phase = GW008_DATA;
|
|
}
|
|
else
|
|
{
|
|
NRF24L01_SetTxRxMode(TXRX_OFF);
|
|
NRF24L01_SetTxRxMode(TX_EN);
|
|
send_packet(1);
|
|
phase = GW008_BIND2;
|
|
return 300;
|
|
}
|
|
break;
|
|
case GW008_BIND2:
|
|
// switch to RX mode
|
|
NRF24L01_SetTxRxMode(TXRX_OFF);
|
|
NRF24L01_FlushRx();
|
|
NRF24L01_SetTxRxMode(RX_EN);
|
|
XN297_Configure(_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO)
|
|
| _BV(NRF24L01_00_PWR_UP) | _BV(NRF24L01_00_PRIM_RX));
|
|
phase = GW008_BIND1;
|
|
return 5000;
|
|
break;
|
|
case GW008_DATA:
|
|
send_packet(0);
|
|
break;
|
|
}
|
|
return GW008_PACKET_PERIOD;
|
|
}
|
|
|
|
uint16_t initGW008()
|
|
{
|
|
BIND_IN_PROGRESS; // autobind protocol
|
|
GW008_initialize_txid();
|
|
phase = GW008_BIND1;
|
|
GW008_init();
|
|
hopping_frequency_no = 0;
|
|
return GW008_INITIAL_WAIT;
|
|
}
|
|
|
|
#endif
|