mirror of
				https://github.com/pascallanger/DIY-Multiprotocol-TX-Module.git
				synced 2025-10-29 10:01:04 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			219 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			219 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/>.
 | |
|  */
 | |
| // Last sync with hexfet new_protocols/fy326_nrf24l01.c dated 2015-07-29
 | |
| 
 | |
| #if defined(FY326_NRF24L01_INO)
 | |
| 
 | |
| #include "iface_nrf24l01.h"
 | |
| 
 | |
| #define FY326_INITIAL_WAIT		500
 | |
| #define FY326_PACKET_PERIOD		1500
 | |
| #define FY326_PACKET_CHKTIME	300
 | |
| #define FY326_PACKET_SIZE		15
 | |
| #define FY326_BIND_COUNT		16
 | |
| #define FY326_RF_BIND_CHANNEL	0x17
 | |
| #define FY326_NUM_RF_CHANNELS	5
 | |
| 
 | |
| enum {
 | |
|     FY326_BIND1=0,
 | |
|     FY326_BIND2,
 | |
|     FY326_DATA,
 | |
|     FY319_BIND1,
 | |
|     FY319_BIND2,
 | |
| };
 | |
| 
 | |
| #define rxid channel
 | |
| 
 | |
| #define CHAN_TO_TRIM(chanval) ((chanval/10)-10)
 | |
| static void __attribute__((unused)) FY326_send_packet(uint8_t bind)
 | |
| {
 | |
| 	packet[0] = rx_tx_addr[3];
 | |
| 	if(bind)
 | |
| 		packet[1] = 0x55;
 | |
| 	else
 | |
| 		packet[1] =	  GET_FLAG(CH7_SW,	0x80)	// Headless
 | |
| 					| GET_FLAG(CH6_SW,	0x40)	// RTH
 | |
| 					| GET_FLAG(CH5_SW,	0x02)	// Flip
 | |
| 					| GET_FLAG(CH9_SW,	0x01)	// Calibrate
 | |
| 					| GET_FLAG(CH8_SW,	0x04);	// Expert
 | |
| 	packet[2]  = convert_channel_16b_limit(AILERON, 0, 200);	// aileron
 | |
| 	packet[3]  = convert_channel_16b_limit(ELEVATOR, 0, 200);		// elevator
 | |
| 	packet[4]  = convert_channel_16b_limit(RUDDER, 0, 200);	// rudder
 | |
| 	packet[5]  = convert_channel_16b_limit(THROTTLE, 0, 200);		// throttle
 | |
| 	if(sub_protocol==FY319)
 | |
| 	{
 | |
| 		packet[6] = convert_channel_8b(AILERON);
 | |
| 		packet[7] = convert_channel_8b(ELEVATOR);
 | |
| 		packet[8] = convert_channel_8b(RUDDER);
 | |
| 	}
 | |
| 	else
 | |
| 	{
 | |
| 		packet[6]  = rx_tx_addr[0];
 | |
| 		packet[7]  = rx_tx_addr[1];
 | |
| 		packet[8]  = rx_tx_addr[2];
 | |
| 	}
 | |
| 	packet[9]  = CHAN_TO_TRIM(packet[2]);	// aileron_trim;
 | |
| 	packet[10] = CHAN_TO_TRIM(packet[3]);	// elevator_trim;
 | |
| 	packet[11] = CHAN_TO_TRIM(packet[4]);	// rudder_trim;
 | |
| 	packet[12] = 0;							// throttle_trim;
 | |
| 	packet[13] = rxid;
 | |
| 	packet[14] = rx_tx_addr[4];
 | |
| 
 | |
| 	if (bind)
 | |
| 		NRF24L01_WriteReg(NRF24L01_05_RF_CH, FY326_RF_BIND_CHANNEL);
 | |
| 	else
 | |
| 	{
 | |
| 		NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no++]);
 | |
| 		hopping_frequency_no %= FY326_NUM_RF_CHANNELS;
 | |
| 	}
 | |
| 
 | |
| 	// clear packet status bits and TX FIFO
 | |
| 	NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
 | |
| 	NRF24L01_FlushTx();
 | |
| 
 | |
| 	NRF24L01_WritePayload(packet, FY326_PACKET_SIZE);
 | |
| 
 | |
| 	NRF24L01_SetPower();	// Set tx_power
 | |
| }
 | |
| 
 | |
| static void __attribute__((unused)) FY326_RF_init()
 | |
| {
 | |
| 	NRF24L01_Initialize();
 | |
| 
 | |
| 	if(sub_protocol==FY319)
 | |
| 		NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03);   // Five-byte rx/tx address
 | |
| 	else
 | |
| 		NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x01);   // Three-byte rx/tx address
 | |
| 	NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR,    (uint8_t *)"\x15\x59\x23\xc6\x29", 5);
 | |
| 	NRF24L01_WriteRegisterMulti(NRF24L01_0A_RX_ADDR_P0, (uint8_t *)"\x15\x59\x23\xc6\x29", 5);
 | |
|     NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, FY326_PACKET_SIZE);
 | |
|     NRF24L01_WriteReg(NRF24L01_05_RF_CH, FY326_RF_BIND_CHANNEL);
 | |
|     NRF24L01_SetBitrate(NRF24L01_BR_250K);
 | |
| 
 | |
|     NRF24L01_WriteReg(NRF24L01_1C_DYNPD, 0x3f);
 | |
|     NRF24L01_WriteReg(NRF24L01_1D_FEATURE, 0x07);
 | |
| 
 | |
| 	//Switch to RX
 | |
| 	NRF24L01_SetTxRxMode(TXRX_OFF);
 | |
| 	NRF24L01_SetTxRxMode(RX_EN);
 | |
| }
 | |
| 
 | |
| uint16_t FY326_callback()
 | |
| {
 | |
| 	switch (phase)
 | |
| 	{
 | |
| 		case FY319_BIND1:
 | |
| 			if(NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR))
 | |
| 			{
 | |
| 				NRF24L01_ReadPayload(packet, FY326_PACKET_SIZE);
 | |
| 				rxid = packet[13];
 | |
| 				packet[0] = rx_tx_addr[3];
 | |
| 				packet[1] = 0x80;
 | |
| 				packet[14]= rx_tx_addr[4];
 | |
| 				NRF24L01_SetTxRxMode(TXRX_OFF);
 | |
| 				NRF24L01_SetTxRxMode(TX_EN);
 | |
| 				NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
 | |
| 				NRF24L01_FlushTx();
 | |
| 				bind_counter = 255;
 | |
| 				for(uint8_t i=2; i<6; i++)
 | |
| 					packet[i] = hopping_frequency[0];
 | |
| 				phase = FY319_BIND2;
 | |
| 			}
 | |
| 			return FY326_PACKET_CHKTIME;
 | |
| 			break;
 | |
| 		case FY319_BIND2:
 | |
| 			NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70);
 | |
| 			NRF24L01_FlushTx();
 | |
| 			NRF24L01_WritePayload(packet, FY326_PACKET_SIZE);
 | |
| 			if(bind_counter == 250)
 | |
| 				packet[1] = 0x40;
 | |
| 			if(--bind_counter == 0)
 | |
| 			{
 | |
| 				BIND_DONE;
 | |
| 				phase = FY326_DATA;
 | |
| 			}
 | |
| 			break;
 | |
| 		case FY326_BIND1:
 | |
| 			if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_RX_DR))
 | |
| 			{ // RX fifo data ready
 | |
| 				NRF24L01_ReadPayload(packet, FY326_PACKET_SIZE);
 | |
| 				rxid = packet[13];
 | |
| 				rx_tx_addr[0] = 0xAA;
 | |
| 				NRF24L01_SetTxRxMode(TXRX_OFF);
 | |
| 				NRF24L01_SetTxRxMode(TX_EN);
 | |
| 				BIND_DONE;
 | |
| 				phase = FY326_DATA;
 | |
| 			}
 | |
| 			else
 | |
| 				if (bind_counter-- == 0)
 | |
| 				{
 | |
| 					bind_counter = FY326_BIND_COUNT;
 | |
| 					NRF24L01_SetTxRxMode(TXRX_OFF);
 | |
| 					NRF24L01_SetTxRxMode(TX_EN);
 | |
| 					FY326_send_packet(1);
 | |
| 					phase = FY326_BIND2;
 | |
| 					return FY326_PACKET_CHKTIME;
 | |
| 				}
 | |
| 			break;
 | |
| 		case FY326_BIND2:
 | |
| 			if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & _BV(NRF24L01_07_TX_DS))
 | |
| 			{ // TX data sent -> switch to RX mode
 | |
| 				NRF24L01_SetTxRxMode(TXRX_OFF);
 | |
| 				NRF24L01_FlushRx();
 | |
| 				NRF24L01_SetTxRxMode(RX_EN);
 | |
| 				phase = FY326_BIND1;
 | |
| 			}
 | |
| 			else
 | |
| 				return FY326_PACKET_CHKTIME;
 | |
| 			break;
 | |
| 		case FY326_DATA:
 | |
| 			#ifdef MULTI_SYNC
 | |
| 				telemetry_set_input_sync(FY326_PACKET_PERIOD);
 | |
| 			#endif
 | |
| 			FY326_send_packet(0);
 | |
| 			break;
 | |
| 	}
 | |
| 	return FY326_PACKET_PERIOD;
 | |
| }
 | |
| 
 | |
| static void __attribute__((unused)) FY326_initialize_txid()
 | |
| {
 | |
| 	hopping_frequency[0] = 		  (rx_tx_addr[0]&0x0f);
 | |
| 	hopping_frequency[1] = 0x10 + (rx_tx_addr[0] >> 4);
 | |
| 	hopping_frequency[2] = 0x20 + (rx_tx_addr[1]&0x0f);
 | |
| 	hopping_frequency[3] = 0x30 + (rx_tx_addr[1] >> 4);
 | |
| 	hopping_frequency[4] = 0x40 + (rx_tx_addr[2] >> 4);
 | |
| 	if(sub_protocol==FY319)
 | |
| 		for(uint8_t i=0;i<5;i++)
 | |
| 			hopping_frequency[i]=rx_tx_addr[0] & ~0x80;
 | |
| }
 | |
| 
 | |
| void FY326_init(void)
 | |
| {
 | |
| 	BIND_IN_PROGRESS;	// autobind protocol
 | |
|     rxid = 0xAA;
 | |
| 	bind_counter = FY326_BIND_COUNT;
 | |
| 	FY326_initialize_txid();
 | |
| 	FY326_RF_init();
 | |
| 	if(sub_protocol==FY319)
 | |
| 	{
 | |
| 		phase=FY319_BIND1;
 | |
| 	}
 | |
| 	else
 | |
| 		phase=FY326_BIND1;
 | |
| }
 | |
| 
 | |
| #endif
 |