- Posts: 2631
JD 395 cx-10
- goebish
- Offline
- I Void Warranties
Please Log in or Create an account to join the conversation.
- Durete
- Offline
- Posts: 610
Please Log in or Create an account to join the conversation.
- goebish
- Offline
- I Void Warranties
- Posts: 2631
so, packet[1~4] seems to be the TX ID, but only [1~2] has something to do with frequencies:
rf channel 1 = (packet[1] & 0x0F) + 0x03
rf channel 2 = ((u8)packet[1] >> 4) + 0x16
rf channel 3 = (packet[2] & 0x0F) + 0x2D
rf channel 4 = ((u8)packet[2] >> 4) + 0x40
Seems to work with the 6 captures I have.
Victzh could you try to implement that in your code ? (or I can add it to my test firmwares later)
Also I think packet [2] must be clamped to some low values... (0x00~0x2F ?) this has to be checked against an actual RX but in the stock TXs captures the maximum value I've seen is 0x10 (so rf channel 4 = 0x41), and when I was experimenting with the eachine 3d x4 I noticed weird results when rf channel is greater than 0x42, it still binds, but only works a few inches away before losing connection. Looks like this is a xn297 limitation because I've seen captures of a few different models and it seems none is using any rf channel greater than 0x42 ever (2466 MHz ?) despite the datasheet states 频率范围2400~2483MHz.
Please Log in or Create an account to join the conversation.
- closedsink
- Offline
- Posts: 9
Very impressed that you figured this out.
Other than the limitation you mentioned for packet[2], are you assuming the data packet sequence is just randomly generated?
Please Log in or Create an account to join the conversation.
- goebish
- Offline
- I Void Warranties
- Posts: 2631
Not sure if packet[2] should be limited to 0x1F or 0x2F
Please Log in or Create an account to join the conversation.
- goebish
- Offline
- I Void Warranties
- Posts: 2631
gist.github.com/goebish/f8982353c34f2b71ffe8
edit: well, it works but maybe the rx drops 1/4 of the packets... I'll constrain packet[2] to 0x2F just to be safe ...
Please Log in or Create an account to join the conversation.
- closedsink
- Offline
- Posts: 9
I should verify the values are getting generated as expected, and then I'll update the code on my blog on rcgroups.
(edit - DONE!)
Please Log in or Create an account to join the conversation.
- victzh
- Offline
- Posts: 1386
As PB suggested, I moved XN297 emulation code to nRF24L01 module, so it should be available for any other XN297 based protocol.
I'll try to approach reading next week, time permitting.
Please Log in or Create an account to join the conversation.
- goebish
- Offline
- I Void Warranties
- Posts: 2631
Please Log in or Create an account to join the conversation.
- goebish
- Offline
- I Void Warranties
- Posts: 2631
Looks like everything is working well with a 15 bytes payload (cx10 green, cg023 ...), but I can't get it to work with a 19 bytes payload (cx10 blue from which I know the aircraft ID). I know my code works because I can bind to a blue cx10 with it and a xn297 chip, but doesn't work with nrf24 + emulation layer.victzh wrote: BTW, answering your question about scrambling sequence - it's fixed, it covers both address, no matter the size (from 3 to 5 bytes) and then the message. The code in the emulation layer (as you probably figured by now) handles all of this for you. You just need to call some functions instead of calling native nRF24 ones. Also, note that the main body of message is bit-reversed - it gave me extra headache decoding it
From what I understand, a 19 bytes payload should be fine as the size of preamble+sync+address+payload+crc is still less than 32 bytes long.
Please Log in or Create an account to join the conversation.
- victzh
- Offline
- Posts: 1386
I have an idea what to do and to verify it I need to build approximately the same setup as for implementation of reading. I will try next week.
Please Log in or Create an account to join the conversation.
- goebish
- Offline
- I Void Warranties
- Posts: 2631
I guess xorout is good for this payload size only, at least scramble table seems ok for longer packets.
Thanks again for your work, I understand and learn a lot by following your steps, this is not the 1st time ! (Bradwii on Mini54...)
Please Log in or Create an account to join the conversation.
- goebish
- Offline
- I Void Warranties
- Posts: 2631
0x61B1
So worst case is we have to store a table with values for every payload length we need.
Please Log in or Create an account to join the conversation.
- goebish
- Offline
- I Void Warranties
- Posts: 2631
Payload size / xor out crc16:
for 5 bytes address:
00: 0x9BA7
01: 0x8BBB
02: 0x85E1
03: 0x3E8C
04: 0x451E
05: 0x18E6
06: 0x6B24
07: 0xE7AB
08: 0x3828
09: 0x8148
10: 0xD461
11: 0xF494
12: 0x2503
13: 0x691D
14: 0xFE8B
15: 0x9BA7
16: 0x8B17
17: 0x2920
18: 0x8B5F
19: 0x61B1
20: 0xD391
21: 0x7401
22: 0x2138
23: 0x129F
24: 0xB3A0
25: 0x2988 -> maximum payload size for 5 bytes address with CRC enabled.
--
**: 0x3448 -> for 4 bytes address w/ 0 byte payload, or 3 bytes address w/ 1 byte payload
static const u16 xn297_crc_xorout[] = {
0x0000, 0x3448, 0x9BA7, 0x8BBB, 0x85E1, 0x3E8C, 0x451E, 0x18E6,
0x6B24, 0xE7AB, 0x3828, 0x8148, 0xD461, 0xF494, 0x2503, 0x691D,
0xFE8B, 0x9BA7, 0x8B17, 0x2920, 0x8B5F, 0x61B1, 0xD391, 0x7401,
0x2138, 0x129F, 0xB3A0, 0x2988};
[snip]
if (xn297_crc) {
int offset = xn297_addr_len < 4 ? 1 : 0;
u16 crc = initial;
for (int i = offset; i < last; ++i) {
crc = crc16_update(crc, buf[i]);
}
crc ^= xn297_crc_xorout[xn297_addr_len - 3 + len];
buf[last++] = crc >> 8;
buf[last++] = crc & 0xff;
}
I have brute forced all the values (~550 tries per second, so an average of 1 minute for one 16 bit value) because I'm using a nrf24 as TX + a xn297 as RX (+2 arduino). It would have been easier with 2x xn297, by disabling crc on rx side and listening for 2 more bytes
These toys are a lot of fun
Please Log in or Create an account to join the conversation.
- goebish
- Offline
- I Void Warranties
- Posts: 2631
Not sure it's OK for anything else than 5 bytes address length, but who cares ?
(edit: tested with every address length, no problem !)
XN297_SetTXAddr(tx_addr, 5); // must do before SetRXAddr, even for RX only
XN297_SetRXAddr(tx_addr, 5);
NRF24L01_FlushRx();
NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, PAYLOAD_SIZE+2); // 15-byte payload + 2 bytes CRC
NRF24L01_SetTxRxMode(RX_EN); // must be called BEFORE XN297_Configure
// Power on, RX mode,
//NRF24L01_00_EN_CRC tells the emulation layer to emulate crc checking, tbd
XN297_Configure( BV(NRF24L01_00_EN_CRC) | BV(NRF24L01_00_CRCO)
| BV(NRF24L01_00_PWR_UP) | BV(NRF24L01_00_PRIM_RX));
while(!(NRF24L01_ReadReg(0x07) & 0x40)) {} // wait for RX FIFO data ready
XN297_ReadPayload(test_packet, PAYLOAD_SIZE+2);
u8 XN297_ReadPayload(u8 *msg, int len)
{
u8 res = NRF24L01_ReadPayload(msg, len);
for(u8 i=0; i<len; i++)
msg[i] = bit_reverse(msg[i]) ^ bit_reverse(xn297_scramble[i+xn297_addr_len]);
return res;
}
nRF24l01 receiving packets from my stock Eachine 3D X4 transmitter while I move throttle stick:
15 bytes packet + 2 bytes crc.
It still needs to be implemented properly with CRC checking (well, not mandatory for what we need...) and all, but it works.
This paves the road for implementing the CX10-A (blue pcb) protocol !
victzh wrote: Also, note that the main body of message is bit-reversed - it gave me extra headache decoding it
I admit that it cost me 1500mg of aspirin to get the crc + read mode working
Please Log in or Create an account to join the conversation.
- hexfet
- Offline
- Posts: 1891
Please Log in or Create an account to join the conversation.
- victzh
- Offline
- Posts: 1386
Nice work, goebish. I'm traveling now, can only watch, and I expect you'll have blue board working when I'm back by Wednesday.
Please Log in or Create an account to join the conversation.
- goebish
- Offline
- I Void Warranties
- Posts: 2631
Then you know how it is, one thing leads to another, I cracked the CRC thing, while doing so I figured out how the whole process works then I had a quick try at read mode and it worked almost instantly (thanks to all the hard work you did before).
In the end, I still have not tested the blue cx10, but that's the easy part
Please Log in or Create an account to join the conversation.
- Stavross118
- Offline
- Posts: 23
Excuse my ignorance but does this mean soon I will be able to fly my cx10 and 11 both blue PCb,s on my devo 10 (already modded of course) very soon top guys both victzh and goebishgoebish wrote: I hope you do not mind
, I only wanted to fix crc for 19 bytes payload at first, just to try my blue CX10 with hardcoded aircraft id.
Then you know how it is, one thing leads to another, I cracked the CRC thing completely, while doing so I understood how the whole process works then I had a quick try at read mode and it worked almost instantly (thanks to all the hard work you did before).
In the end, I still have not tested the blue cx10, but that's the easy part
Please Log in or Create an account to join the conversation.
- goebish
- Offline
- I Void Warranties
- Posts: 2631
Please Log in or Create an account to join the conversation.
- Home
- Forum
- Development
- Protocol Development
- JD 395 cx-10