mirror of
https://github.com/pascallanger/DIY-Multiprotocol-TX-Module.git
synced 2025-02-04 21: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
181 lines
6.0 KiB
C++
181 lines
6.0 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/>.
|
|
*/
|
|
// ESky protocol for small models since 2014 (150, 300, 150X, ...)
|
|
|
|
#if defined(ESKY150_NRF24L01_INO)
|
|
|
|
#include "iface_nrf24l01.h"
|
|
|
|
#define ESKY150_PAYLOADSIZE 15
|
|
#define ESKY150_TX_ADDRESS_SIZE 4
|
|
#define ESKY150_BINDING_PACKET_PERIOD 2000
|
|
#define ESKY150_SENDING_PACKET_PERIOD 4800
|
|
|
|
static void __attribute__((unused)) ESKY150_init()
|
|
{
|
|
//Original TX always sets for channelx 0x22 and 0x4a
|
|
// Use channels 2..79
|
|
hopping_frequency[0] = rx_tx_addr[3]%37+2;
|
|
hopping_frequency[1] = hopping_frequency[0] + 40;
|
|
|
|
NRF24L01_Initialize();
|
|
NRF24L01_WriteReg(NRF24L01_00_CONFIG, (_BV(NRF24L01_00_EN_CRC) | _BV(NRF24L01_00_CRCO)));
|
|
NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x00); // No Auto Acknoledgement
|
|
NRF24L01_WriteReg(NRF24L01_02_EN_RXADDR, 0x01); // Enable data pipe 0
|
|
NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x02); // 4-byte RX/TX address
|
|
NRF24L01_WriteReg(NRF24L01_04_SETUP_RETR, 0); // Disable retransmit
|
|
NRF24L01_SetPower();
|
|
NRF24L01_SetBitrate(NRF24L01_BR_2M);
|
|
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit
|
|
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, ESKY150_PAYLOADSIZE); // bytes of data payload for pipe 0
|
|
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, rx_tx_addr, ESKY150_TX_ADDRESS_SIZE);
|
|
|
|
NRF24L01_Activate(0x73);
|
|
NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 1); // Dynamic payload for data pipe 0
|
|
// Enable: Dynamic Payload Length, Payload with ACK , W_TX_PAYLOAD_NOACK
|
|
NRF24L01_WriteReg(NRF24L01_1D_FEATURE, _BV(NRF2401_1D_EN_DPL) | _BV(NRF2401_1D_EN_ACK_PAY) | _BV(NRF2401_1D_EN_DYN_ACK));
|
|
NRF24L01_Activate(0x73);
|
|
NRF24L01_FlushTx();
|
|
// Turn radio power on
|
|
NRF24L01_SetTxRxMode(TX_EN);
|
|
}
|
|
|
|
static void __attribute__((unused)) ESKY150_bind_init()
|
|
{
|
|
uint8_t ESKY150_addr[ESKY150_TX_ADDRESS_SIZE] = { 0x73, 0x73, 0x74, 0x63 }; //This RX address "sstc" is fixed for ESky2
|
|
|
|
// Build packet
|
|
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] = ESKY150_addr[0];
|
|
packet[5] = ESKY150_addr[1];
|
|
packet[6] = ESKY150_addr[2];
|
|
packet[7] = ESKY150_addr[3];
|
|
packet[8] = rx_tx_addr[0];
|
|
packet[9] = rx_tx_addr[1];
|
|
packet[10] = rx_tx_addr[2];
|
|
packet[11] = rx_tx_addr[3];
|
|
packet[12] = 0;
|
|
packet[13] = 0;
|
|
packet[14] = 0;
|
|
|
|
// Bind address
|
|
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, ESKY150_addr, ESKY150_TX_ADDRESS_SIZE);
|
|
NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, ESKY150_addr, ESKY150_TX_ADDRESS_SIZE);
|
|
|
|
// Bind Channel 1
|
|
NRF24L01_WriteReg(NRF24L01_05_RF_CH, 1);
|
|
}
|
|
|
|
static void __attribute__((unused)) ESKY150_send_packet()
|
|
{
|
|
// Build packet
|
|
uint16_t throttle=convert_channel_16b_limit(THROTTLE,1000,2000);
|
|
uint16_t aileron=convert_channel_16b_limit(AILERON,1000,2000);
|
|
uint16_t elevator=convert_channel_16b_limit(ELEVATOR,1000,2000);
|
|
uint16_t rudder=convert_channel_16b_limit(RUDDER,1000,2000);
|
|
//set unused channels to zero, for compatibility with older 4 channel models
|
|
uint8_t flight_mode=0;
|
|
uint16_t aux_ch6=0;
|
|
uint8_t aux_ch7=0;
|
|
if(option==1)
|
|
{
|
|
flight_mode=ESKY150_convert_2bit_channel(CH5);
|
|
aux_ch6=convert_channel_16b_limit(CH6,1000,2000);
|
|
aux_ch7=ESKY150_convert_2bit_channel(CH7);
|
|
}
|
|
packet[0] = hopping_frequency[0];
|
|
packet[1] = hopping_frequency[1];
|
|
packet[2] = ((flight_mode << 6) & 0xC0) | ((aux_ch7 << 4) & 0x30) | ((throttle >> 8) & 0xFF);
|
|
packet[3] = throttle & 0xFF;
|
|
packet[4] = ((aux_ch6 >> 4) & 0xF0) | ((aileron >> 8) & 0xFF); //and 0xFF works as values are anyways not bigger than 12 bits, but faster code like that
|
|
packet[5] = aileron & 0xFF;
|
|
packet[6] = (aux_ch6 & 0xF0) | ((elevator >> 8) & 0xFF); //and 0xFF works as values are anyways not bigger than 12 bits, but faster code like that
|
|
packet[7] = elevator & 0xFF;
|
|
packet[8] = ((aux_ch6 << 4) & 0xF0) | ((rudder >> 8) & 0xFF); //and 0xFF works as values are anyways not bigger than 12 bits, but faster code like that
|
|
packet[9] = rudder & 0xFF;
|
|
// The next 4 Bytes are sint8 trim values (TAER). As trims are already included within normal outputs, these values are set to zero.
|
|
packet[10] = 0x00;
|
|
packet[11] = 0x00;
|
|
packet[12] = 0x00;
|
|
packet[13] = 0x00;
|
|
// Calculate checksum:
|
|
uint8_t sum = 0;
|
|
for (uint8_t i = 0; i < 14; ++i)
|
|
sum += packet[i];
|
|
packet[14] = sum;
|
|
|
|
// Hop on 2 channels
|
|
hopping_frequency_no++;
|
|
hopping_frequency_no&=0x01;
|
|
NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no]);
|
|
|
|
// Clear packet status bits and TX FIFO
|
|
NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
|
|
NRF24L01_FlushTx();
|
|
|
|
// Send packet
|
|
NRF24L01_WritePayload(packet, ESKY150_PAYLOADSIZE);
|
|
|
|
//Keep transmit power updated
|
|
NRF24L01_SetPower();
|
|
}
|
|
|
|
uint8_t ESKY150_convert_2bit_channel(uint8_t num)
|
|
{
|
|
if(Channel_data[num] > CHANNEL_MAX_COMMAND)
|
|
return 0x03;
|
|
else
|
|
if(Channel_data[num] < CHANNEL_MIN_COMMAND)
|
|
return 0x00;
|
|
else
|
|
if(Channel_data[num] > CHANNEL_SWITCH)
|
|
return 0x02;
|
|
return 0x01;
|
|
}
|
|
|
|
uint16_t ESKY150_callback()
|
|
{
|
|
if(IS_BIND_DONE)
|
|
ESKY150_send_packet();
|
|
else
|
|
{
|
|
NRF24L01_WritePayload(packet, ESKY150_PAYLOADSIZE);
|
|
if (--bind_counter == 0)
|
|
{
|
|
BIND_DONE;
|
|
// Change TX address from bind to normal mode
|
|
NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, rx_tx_addr, ESKY150_TX_ADDRESS_SIZE);
|
|
}
|
|
return ESKY150_BINDING_PACKET_PERIOD;
|
|
}
|
|
return ESKY150_SENDING_PACKET_PERIOD;
|
|
}
|
|
|
|
uint16_t initESKY150(void)
|
|
{
|
|
ESKY150_init();
|
|
if(IS_BIND_IN_PROGRESS)
|
|
{
|
|
bind_counter=3000;
|
|
ESKY150_bind_init();
|
|
}
|
|
hopping_frequency_no=0;
|
|
return 10000;
|
|
}
|
|
|
|
#endif |