Question XN297L as transmitter and NRF24L01 as RX

More
27 Jul 2022 03:58 - 27 Jul 2022 03:59 #78029 by Bangdc
Hi All,
I have a toy drone's TX, which using XN297Lbw RF chip as transmitter. By using logic analyzer with Sigrok , I found this TX config as follows:
- EN_AA (Auto ACK) register as "1"
- TX address: 0x6D, 0x6A, 0x77, 0x77, 0x77
- Bind CH: 0x36
- Payload size: 16
With above information and using arduino + module XN297Lbw, I can communicate with this TX (Bind and receive joystick data)
But when I use NRF24L01 RF chip as RX and xn297_scramble to set for tx,rx address, I can not communicate with TX.
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
};

static void nrf24_set_xn297_address( uint8_t * addr )
{
	uint8_t rxaddr[ 6 ] = { 0x2a };
	crc_addr = 0xb5d2;
	for ( int i = 5; i > 0; --i ) {
		rxaddr[ i ] = addr[ i - 1 ] ^ xn297_scramble[ 5 - i ];
		if ( crc_en ) {
			crc_addr = CRC16_UPDATE( crc_addr, rxaddr[ i ] );
		}
	}

	// write rx address
	rx_writeregs( rxaddr, sizeof( rxaddr ) );
	// write tx address
	rxaddr[ 0 ] = 0x30;
	rx_writeregs( rxaddr, sizeof( rxaddr ) );
}

void rx_init()
{
	debugln("rx_init");
	drv_rx_init();
#define XN_TO_TX B00000010
#define XN_TO_RX B00000011
#define XN_POWER B00000001 | ( ( TX_POWER & 7 ) << 3 )
	rx_writereg( SETUP_AW, 3 );   // address size (5 bytes)
	static int rxaddr[ 5 ] = { /*0x2a,*/ 0x6D, 0x6A, 0x77, 0x77, 0x77 };
	// static int rxaddr[ 5 ] = { /*0x2a,*/ 0x55, 0x0f, 0x71, 0x77, 0x77 };
	//rx_writeregs( rxaddr, sizeof( rxaddr ) );
	// rx_writetxaddress(rxaddr);
	// rx_writerxaddress(rxaddr);
	nrf24_set_xn297_address( (uint8_t*)rxaddr );

	rx_writereg( EN_AA, 1 );      // aa enable
	rx_writereg( EN_RXADDR, 1 );  // pipe 0 only
	rx_writereg( RF_SETUP, XN_POWER );    // power / data rate / lna
	rx_writereg( RX_PW_P0, PAYLOAD_SIZE );  // payload size
	rx_writereg( SETUP_RETR, 0 ); // no retransmissions (redundant?)
	rx_writereg( SETUP_AW, 3 );   // address size (5 bytes)
	rx_command( FLUSH_RX );
	rx_writereg( RF_CH, BIND_CH );      // bind on channel 0
	debugln("Read RF_CH: 0x%x", rx_readreg(RF_CH));

	rx_writereg( 0x1d, B00111000 );   // 64 bit payload, software ce
	// static uint8_t cehigh_regs[ 2 ] = { 0xFD, 0 }; // internal CE high command, 0 also required
	// rx_writeregs( cehigh_regs, sizeof( cehigh_regs ) );

	rx_writereg( 0, XN_TO_RX );   // power up, crc enabled, rx mode

	int rxcheck = rx_readreg( 0x0f ); // rx address pipe 5
	// should be 0xc6
	extern void failloop( int );
	if ( rxcheck != 0xc6 ) {
		failloop( 3 );
	}
}

If I config EN_AA reg as "0" and use address to xn297 preamble " 0x55, 0x0f, 0x71" I can receive bind package, but as I understand , TX use Auto Ack to detect that RX (drone) already received bind package and go to data mode. If EN_AA set to 0, TX will not able to know ack from RX.

I hope someone can help me to found a solution for this.
Thank you for your attention.
Last edit: 27 Jul 2022 03:59 by Bangdc.

Please Log in or Create an account to join the conversation.

More
02 Aug 2022 04:00 #78035 by Bangdc
I found problem.
1. Wrong casting
	static int rxaddr[ 5 ] = { /*0x2a,*/ 0x6D, 0x6A, 0x77, 0x77, 0x77 };
	nrf24_set_xn297_address( (uint8_t*)rxaddr );
==> should be uint8_t rxaddr[ 5 ] = { /*0x2a,*/ 0x6D, 0x6A, 0x77, 0x77, 0x77 };
Cast from int* to (uint8_t*) cause wrong address is set.

2. Auto Ack on NRF24L01 might be different with Auto Ack on XN297, so can not set EC_AA to 1, only 0 is work

Please Log in or Create an account to join the conversation.

Time to create page: 0.025 seconds
Powered by Kunena Forum