- Posts: 3333
Support for walkera telemetry.
- vlad_vy
- Offline
Please Log in or Create an account to join the conversation.
- Indigo
- Offline
- Posts: 230
vlad_vy wrote: Indigo, why you write to NULL? I think it's not "black hole", it's something like (void *)0L. Results can be unpredictable.
Thanks for reviewing my code.
I'm not writing to NULL, in an earlier commit I changed ReadRegisterMulti() to enable dummy reads.
ReadRegisterMulti() is now this:
static void ReadRegisterMulti(u8 address, u8 data[], u8 length)
{
CS_LO();
PROTOSPI_xfer(address);
for(u8 i = 0; i < length; i++)
{
u8 byte = PROTOSPI_xfer(0);
if (data != NULL)
data[i] = byte;
}
CS_HI();
}
That's OK, isn't it? If data is NULL, the byte(s) read is not stored.
Please Log in or Create an account to join the conversation.
- vlad_vy
- Offline
- Posts: 3333
Please Log in or Create an account to join the conversation.
- PhracturedBlue
- Offline
- Posts: 4402
I have to admit I'm very skeptical of the process at the moment. When I look at Indigo's code, it has a lot of change compared to the trunk in DSM and Devo protocols. I don't really understand what much of that change is buying me. In Devo, it may result in eliminating the 'Reboot' condition, but at least at the moment, it will come at the cost of major refactoring of the callback loop, and the Reboot condition itself is not causing any issues (any more). In DSM2 the code refactor may reduce Holds? I belive the original intent was to improve reception rate (eliminate invalids and bogus data)? What else does it achieve? All of that change comes with inherent stability risk to the most commonly used protocols. It makes me very nervous, especially with 9 out of 10 builds seeming to have major issues that make it unusable. I really need to see concrete gains, and then I will wonder whether those gains can be had with less change to the protocol code.
Please Log in or Create an account to join the conversation.
- Francisco
- Offline
- Posts: 11
The telemetry works, but sometimes turn to inverted( black/White) and the voltaje dont change anymore, especially when the voltaje is low.
I use the 4.01, tried with build from yesterday but the problem persists.
Please Log in or Create an account to join the conversation.
- vlad_vy
- Offline
- Posts: 3333
Please Log in or Create an account to join the conversation.
- vlad_vy
- Offline
- Posts: 3333
} else {
if(CYRF_ReadRegister(0x07) & 0x20) { // this won't be true in emulator so we need to simulate it somehow
CYRF_ReadDataPacket(packet);
parse_telemetry_packet(packet);
delay = 100 * (16 - txState);
txState = 15;
}
Please Log in or Create an account to join the conversation.
- PhracturedBlue
- Offline
- Posts: 4402
The current code uses a strict rule set: must have received a complete 16byte packet without any errors. It may be necessary to change the check to be more robust (which I think is what Indigo has been working on), but changing that line without anything else will make it more likelythat bad packets get to the telemetry parser which doesn't seem very helpful.
Please Log in or Create an account to join the conversation.
- vlad_vy
- Offline
- Posts: 3333
Please Log in or Create an account to join the conversation.
- Indigo
- Offline
- Posts: 230
If you want to keep it simple use same rule as dsm protocol:
if((CYRF_ReadRegister(0x07) & 0x07) == 0x02) // complete with no errors.
Whenever complete bit (0x02) is set you should read it to clear the buffer ready for next packet.
Please Log in or Create an account to join the conversation.
- Indigo
- Offline
- Posts: 230
int CYRF_ReadDataPacketLen(u8 dpbuffer[], u8 len)
{
unsigned rx_state = CYRF_ReadRegister(CYRF_07_RX_IRQ_STATUS);
if ((rx_state & 0x03) == 0x02) {
// RXC=1, RXE=0 then 2nd check is required (debouncing)
rx_state |= CYRF_ReadRegister(CYRF_07_RX_IRQ_STATUS);
}
if (rx_state) {
CYRF_WriteRegister(CYRF_07_RX_IRQ_STATUS, 0x80); // need to set RXOW before data read.
u8 length;
if (rx_state & 0x07)
// if complete or error, we can get the actual count
length = CYRF_ReadRegister(CYRF_09_RX_COUNT);
else
// otherwise, use length reported by start of packet
length = CYRF_ReadRegister(CYRF_0A_RX_LENGTH);
if (!length)
length = 1;
else if (((rx_state & 0x87) == 0x02) && length == len) {
// complete with no errors
ReadRegisterMulti(CYRF_21_RX_BUFFER, dpbuffer, length);
return 1;
}
// else, empty buffer
ReadRegisterMulti(CYRF_21_RX_BUFFER, NULL, length);
}
return 0;
}
A second check of CYRF_07_RX_IRQ_STATUS is illegal if RXC=1 and RXE=1, and is only needed if RXC=1 and RXE=0 so that check we need.
if status is zero, nothing has happened and buffer will still be empty.
CYRF_09_RX_COUNT can only be used if receive complete or error has occured. Next best length field is
CYRF_0A_RX_LENGTH updated after reception of a new length field (shortly after start of packet detected)
Please Log in or Create an account to join the conversation.
- Indigo
- Offline
- Posts: 230
int CYRF_ReadDataPacketLen(u8 dpbuffer[], u8 len, int exit)
{
unsigned rx_state = CYRF_ReadRegister(CYRF_07_RX_IRQ_STATUS);
unsigned length;
// if receive complete, any error, or exit receiving
if ((rx_state & 0x07) || exit) {
if (rx_state) {
length = CYRF_ReadRegister(CYRF_09_RX_COUNT);
if (length) {
// need to set RXOW before data read.
CYRF_WriteRegister(CYRF_07_RX_IRQ_STATUS, rx_state | 0x80);
// if RXE=0 then 2nd check is required to get true value of RXE
if (!(rx_state & 0x01))
rx_state |= CYRF_ReadRegister(CYRF_07_RX_IRQ_STATUS);
if (((rx_state & 0x07) == 0x02) && length == len) {
// good data (complete with no errors)
ReadRegisterMulti(CYRF_21_RX_BUFFER, dpbuffer, length);
return 1;
}
// else empty buffer (clean-up)
ReadRegisterMulti(CYRF_21_RX_BUFFER, NULL, length);
}
}
}
return 0;
}
The Devo protocol calls this multiple times, the final call is when state == 15
if (CYRF_ReadDataPacketLen(packet, 0x10, txState == 15)) {
Please Log in or Create an account to join the conversation.
- vlad_vy
- Offline
- Posts: 3333
Please Log in or Create an account to join the conversation.
- vlad_vy
- Offline
- Posts: 3333
PB, can you build test version?
cyrf6936.c
int CYRF_ReadDataPacketLen(u8 dpbuffer[])
{
u8 rx_state;
u8 length;
rx_state = CYRF_ReadRegister(CYRF_07_RX_IRQ_STATUS);
if (rx_state & 0x02) { // receive complete
if (!(rx_state & 0x01)) { // RXC=1, RXE=0 then 2nd check is required (debouncing)
rx_state |= CYRF_ReadRegister(CYRF_07_RX_IRQ_STATUS);
}
CYRF_WriteRegister(CYRF_07_RX_IRQ_STATUS, 0x80); // need to set RXOW before data read.
length = CYRF_ReadRegister(CYRF_09_RX_COUNT);
if (rx_state & 0x05) { //if any error
// bad data, empty buffer
while (length) {
CYRF_ReadRegister(CYRF_21_RX_BUFFER);
length--;
}
return 2; //bad data
} else {
// good data (complete with no errors)
ReadRegisterMulti(CYRF_21_RX_BUFFER, dpbuffer, length);
return 1; //good data
}
}
return 0; //receive not complete
}
devo_cyrf6936.c
} else { // this won't be true in emulator so we need to simulate it somehow
u8 rx_state = CYRF_ReadDataPacketLen(packet);
if(rx_state) {
if(rx_state == 1) {
parse_telemetry_packet(packet);
}
delay = 100 * (16 - txState);
txState = 15;
}
#ifdef EMULATOR
dsm2_cyrf6936_b45.c
} else if(state == DSM2_CH2_READ_A || state == DSM2_CH2_READ_B) {
//Read telemetry if needed
u8 rx_state = CYRF_ReadDataPacketLen(packet);
if(rx_state == 1) {
parse_telemetry_packet(packet);
}
if (state == DSM2_CH2_READ_A && num_channels < 8) {
Changed files:
Please Log in or Create an account to join the conversation.
- PhracturedBlue
- Offline
- Posts: 4402
www.deviationtx.com/downloads-new/catego...vlad-s-devo-dsm-test
If you want, I can give you access that you can make your own test builds. It only requires that you have 'curl' installed, and can run 'make zip'
Please Log in or Create an account to join the conversation.
- Indigo
- Offline
- Posts: 230
And it will work even better if we use:
CYRF_WriteRegister(CYRF_06_RX_CFG, 0x4A);
and don't waste time manually emptying the receive buffer.
Please Log in or Create an account to join the conversation.
- vlad_vy
- Offline
- Posts: 3333
PB, i have the local build environment only, all other is dark forest for me.
Please Log in or Create an account to join the conversation.
- PhracturedBlue
- Offline
- Posts: 4402
Learning to use HG to keep up to date, and to create diffs is pretty easy.
Just let me know if you are interested and I'll give you developers permissions which will give you upload access
Assuming you are using windows, all you'd need would be curl from here (get Win32-Generic or Win64-Generic as needed):
curl.haxx.se/download.html
and put it in your /usr/bin directory in MSYS
then just follow the instructions here:
www.deviationtx.com/forum/7-development/...ly-to-the-test#30367
Please Log in or Create an account to join the conversation.
- Indigo
- Offline
- Posts: 230
And it will work even better if we use:
CYRF_WriteRegister(CYRF_06_RX_CFG, 0x4A);
cyrf6936.c:
int CYRF_ReadDataPacket(u8 dpbuffer[])
{
u8 rx_state = CYRF_ReadRegister(CYRF_07_RX_IRQ_STATUS);
if (rx_state & 0x02) { // receive complete
if (!(rx_state & 0x01)) { // RXC=1, RXE=0 then 2nd check is required (debouncing)
rx_state |= CYRF_ReadRegister(CYRF_07_RX_IRQ_STATUS);
}
if (rx_state & 0x05) {
return -1; // bad data
}
// good data (complete with no errors)
CYRF_WriteRegister(CYRF_07_RX_IRQ_STATUS, 0x80); // set RXOW before data read
u8 length = CYRF_ReadRegister(CYRF_09_RX_COUNT);
ReadRegisterMulti(CYRF_21_RX_BUFFER, dpbuffer, length);
return 1;
}
return 0; // no data
}
devo_cyrf6936.c:
} else {
int status = CYRF_ReadDataPacket(packet);
if (status) {
if (status == 1) {
scramble_pkt(); //This will unscramble the packet
if ((packet[0] & 0xF0) == TELEMETRY_ENABLE && (fixed_id & 0x00ffffff) ==
(((u32)packet[15] << 16) | ((u32)packet[14] << 8) | packet[13]))
{
parse_telemetry_packet();
}
}
delay = 100 * (16 - txState);
txState = 15;
}
#ifdef EMULATOR
dsm2_cyrf6936.c:
} else if(state == DSM2_CH2_READ_A || state == DSM2_CH2_READ_B) {
if (CYRF_ReadDataPacket(packet) == 1)
parse_telemetry_packet();
if (state == DSM2_CH2_READ_A && num_channels < 8) {
Updated build 342e9de with this has been uploaded to Test Builds
Source
Please Log in or Create an account to join the conversation.
- vlad_vy
- Offline
- Posts: 3333
int CYRF_ReadDataPacketLen(u8 dpbuffer[])
{
u8 rx_state;
u8 length;
rx_state = CYRF_ReadRegister(CYRF_07_RX_IRQ_STATUS);
if (rx_state & 0x02) { // receive complete
if (!(rx_state & 0x01)) { // RXC=1, RXE=0 then 2nd check is required (debouncing)
rx_state |= CYRF_ReadRegister(CYRF_07_RX_IRQ_STATUS);
}
length = CYRF_ReadRegister(CYRF_09_RX_COUNT);
if (rx_state & 0x05) { //if any error
if( !(CYRF_ReadRegister(CYRF_06_RX_CFG) & 0x02)) { //if buffer overwrite disabled (RXOW bit)
// bad data, empty buffer
CYRF_WriteRegister(CYRF_07_RX_IRQ_STATUS, 0x80); // need to set RXOW before data read
while (length) {
CYRF_ReadRegister(CYRF_21_RX_BUFFER);
length--;
}
}
return 2; //bad data
} else {
// good data (complete with no errors)
CYRF_WriteRegister(CYRF_07_RX_IRQ_STATUS, 0x80); // need to set RXOW before data read
ReadRegisterMulti(CYRF_21_RX_BUFFER, dpbuffer, length);
return 1; //good data
}
}
return 0; //receive not complete
}
Please Log in or Create an account to join the conversation.
- Home
- Forum
- Development
- Protocol Development
- Support for walkera telemetry.