Support for walkera telemetry.

More
28 Apr 2015 14:32 - 30 Apr 2015 05:33 #31738 by vlad_vy
Replied by vlad_vy on topic Support for walkera telemetry.
With buffer overwrite mode we can do things even more simple: Two versions of devo_telemetry_cb() without excessive poll. Both Devo versions working fine with Ladybird and RX1202+telemetry module. I had several flights with both versions. You can choose any version that you like more.

devo_cyrf6936.c
devo_telemetry_cb() without excessive poll:
static u16 devo_telemetry_cb()
{
    int delay;
    
    if (txState == 0) {
        DEVO_BuildPacket();
        CYRF_WriteDataPacket(packet);
        txState = 1;
        return 900;
    }
    if (txState == 1) {
        int i = 0;
        u8 reg;
        while (! ((reg = CYRF_ReadRegister(0x04)) & 0x02)) {
            if (++i >= NUM_WAIT_LOOPS)
                break;
        }
        if (((reg & 0x22) == 0x20) || (CYRF_ReadRegister(0x02) & 0x80)) {
     	      CYRF_Reset();
            cyrf_init();
            cyrf_set_bound_sop_code();
            CYRF_ConfigRFChannel(*radio_ch_ptr);
            //printf("Rst CYRF\n");
            delay = 1500;
            txState = 3;
        } else {
            if (state == DEVO_BOUND) {
                /* exit binding state */
                state = DEVO_BOUND_3;
                cyrf_set_bound_sop_code();
            }
            if(pkt_num == 0 || bind_counter > 0) {
                delay = 1500;
                txState = 3;
            } else {
                CYRF_SetTxRxMode(RX_EN); //Receive mode
                CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x80); //Prepare to receive (do not enable any IRQ)
                txState = 2;
                return 1100;
            }
        }
    }
    if(txState == 2) {  // this won't be true in emulator so we need to simulate it somehow
        u8 rx_status = CYRF_ReadRegister(0x07);
        if((rx_status & 0x3) == 0x02) { // RXC=1, RXE=0 then 2nd check is required (debouncing)
            rx_status |= CYRF_ReadRegister(0x07);
        }
        if ((rx_status & 0x07) == 0x02) { // good data (complete with no errors)
            CYRF_WriteRegister(CYRF_07_RX_IRQ_STATUS, 0x80); //Prepare to read buffer
            CYRF_ReadDataPacket(packet);
            parse_telemetry_packet(packet);
        }
#ifdef EMULATOR
        u8 telem_bit = rand32() % 7; // random number in [0, 7)
        packet[0] =  TELEMETRY_ENABLE + telem_bit; // allow emulator to simulate telemetry parsing to prevent future bugs in the telemetry monitor
        //printf("telem 1st packet: 0x%x\n", packet[0]);
        for(int i = 1; i < 13; i++)
            packet[i] = rand32() % 256;
        parse_telemetry_packet(packet);
        for(int i = 0; i < TELEM_UPDATE_SIZE; i++)
            Telemetry.updated[i] = 0xff;
#endif
        delay = 400;
        txState = 3;
    }
    if(txState == 3) {
        CYRF_SetTxRxMode(TX_EN); //Write mode
        if(pkt_num == 0) {
            //Keep tx power updated
            CYRF_WriteRegister(CYRF_03_TX_CFG, 0x08 | Model.tx_power);
            radio_ch_ptr = radio_ch_ptr == &radio_ch[2] ? radio_ch : radio_ch_ptr + 1;
            CYRF_ConfigRFChannel(*radio_ch_ptr);
        }
        txState = 0;
    }
    return delay;
}

devo_cyrf6936.c
devo_telemetry_cb() without excessive poll and with while() loop: It is possible that it has a little more time for telemetry parsing. Telemetry packet ended in between 1900us and 2000us from cycle start.
static u16 devo_telemetry_cb()
{
    int delay;
    
    if (txState == 0) {
        DEVO_BuildPacket();
        CYRF_WriteDataPacket(packet);
        txState = 1;
        return 900;
    }
    if (txState == 1) {
        int i = 0;
        u8 reg;
        while (! ((reg = CYRF_ReadRegister(0x04)) & 0x02)) {
            if (++i >= NUM_WAIT_LOOPS)
                break;
        }
        if (((reg & 0x22) == 0x20) || (CYRF_ReadRegister(0x02) & 0x80)) {
     	      CYRF_Reset();
            cyrf_init();
            cyrf_set_bound_sop_code();
            CYRF_ConfigRFChannel(*radio_ch_ptr);
            //printf("Rst CYRF\n");
            delay = 1500;
            txState = 3;
        } else {
            if (state == DEVO_BOUND) {
                /* exit binding state */
                state = DEVO_BOUND_3;
                cyrf_set_bound_sop_code();
            }
            if(pkt_num == 0 || bind_counter > 0) {
                delay = 1500;
                txState = 3;
            } else {
                CYRF_SetTxRxMode(RX_EN); //Receive mode
                CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x80); //Prepare to receive (do not enable any IRQ)
                txState = 2;
                return 1000;
            }
        }
    }
    if(txState == 2) {  // this won't be true in emulator so we need to simulate it somehow
        int i = 0;
        u8 rx_status;
        while ( !((rx_status = CYRF_ReadRegister(0x07)) & 0x02)) {
            if (++i > NUM_WAIT_LOOPS)
                break;
        }
        if((rx_status & 0x3) == 0x02) { // RXC=1, RXE=0 then 2nd check is required (debouncing)
            rx_status |= CYRF_ReadRegister(0x07);
        }
        if ((rx_status & 0x07) == 0x02) { // good data (complete with no errors)
            CYRF_WriteRegister(CYRF_07_RX_IRQ_STATUS, 0x80); //Prepare to read buffer
            CYRF_ReadDataPacket(packet);
            parse_telemetry_packet(packet);
        }
#ifdef EMULATOR
        u8 telem_bit = rand32() % 7; // random number in [0, 7)
        packet[0] =  TELEMETRY_ENABLE + telem_bit; // allow emulator to simulate telemetry parsing to prevent future bugs in the telemetry monitor
        //printf("telem 1st packet: 0x%x\n", packet[0]);
        for(int i = 1; i < 13; i++)
            packet[i] = rand32() % 256;
        parse_telemetry_packet(packet);
        for(int i = 0; i < TELEM_UPDATE_SIZE; i++)
            Telemetry.updated[i] = 0xff;
#endif
        delay = 500;
        txState = 3;
    }
    if(txState == 3) {
        CYRF_SetTxRxMode(TX_EN); //Write mode
        if(pkt_num == 0) {
            //Keep tx power updated
            CYRF_WriteRegister(CYRF_03_TX_CFG, 0x08 | Model.tx_power);
            radio_ch_ptr = radio_ch_ptr == &radio_ch[2] ? radio_ch : radio_ch_ptr + 1;
            CYRF_ConfigRFChannel(*radio_ch_ptr);
        }
        txState = 0;
    }
    return delay;
}

dsm2_cyrf6936.c
{CYRF_06_RX_CFG, 0x4A},
#endif
        {
            state++;
            CYRF_SetTxRxMode(RX_EN); //Receive mode
            CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x87); //Prepare to receive
            return 11000 - CH1_CH2_DELAY - WRITE_DELAY - READ_DELAY;
        }
    } else if(state == DSM2_CH2_READ_A || state == DSM2_CH2_READ_B) {
        //Read telemetry if needed
        int rx_status = CYRF_ReadRegister(0x07);
        if((rx_status & 0x3) == 0x02) { // RXC=1, RXE=0 then 2nd check is required (debouncing)
            rx_status |= CYRF_ReadRegister(0x07);
        }
        if ((rx_status & 0x07) == 0x02) { // good data (complete with no errors)
            CYRF_WriteRegister(CYRF_07_RX_IRQ_STATUS, 0x80); //Prepare to read buffer
            CYRF_ReadDataPacket(packet);
            parse_telemetry_packet(packet);
        }
        if (state == DSM2_CH2_READ_A && num_channels < 8) {

Changed files:
Last edit: 30 Apr 2015 05:33 by vlad_vy.

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

More
28 Apr 2015 17:04 - 28 Apr 2015 17:05 #31742 by linux-user
Replied by linux-user on topic Support for walkera telemetry.
Vlad's Devo/DSM test deviation-devo10-v4.0.1-3626aff is now running for 24h without a single 'RST CYRF' message or LOS event.
- Is this just statistics?
- Did you omit the 'RST CYRF' message in the code?
- Have we found a way to avoid LOS in the first place?
Last edit: 28 Apr 2015 17:05 by linux-user.

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

More
28 Apr 2015 17:23 - 28 Apr 2015 17:26 #31743 by vlad_vy
Replied by vlad_vy on topic Support for walkera telemetry.
I don't know, but think build has not debug message and now code has automatic CYRF reset in case any problem.

Do you have any problems with telemetry? Inverted values or anything else?
Last edit: 28 Apr 2015 17:26 by vlad_vy.

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

More
28 Apr 2015 17:50 #31744 by linux-user
Replied by linux-user on topic Support for walkera telemetry.
No problems yet with 3626aff.

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

More
28 Apr 2015 18:19 #31746 by PhracturedBlue
Replied by PhracturedBlue on topic Support for walkera telemetry.
It is built with debug, but the printf in the reset condition was disabled.
If I'm going to do a new build anyway to enable debug(so we can see if issues are actually occurring) should I take Vald's latest code? I like reducing the polling and busy loops, so that is good.

Is this code otherwise ready to go?

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

More
28 Apr 2015 18:32 #31747 by vlad_vy
Replied by vlad_vy on topic Support for walkera telemetry.
I think my latest code is ready for use. Up to now I don't notice any problems.

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

More
28 Apr 2015 20:06 - 28 Apr 2015 20:14 #31749 by PhracturedBlue
Replied by PhracturedBlue on topic Support for walkera telemetry.
Ok. New build of Vlad's work here:
www.deviationtx.com/downloads-new/catego...vlad-s-devo-dsm-test

I chose the _01 version. Not sure which is better, but telemetry parsing doesn't take much time.

Edit: I did enable the Reset printf so we can see if it is still occurring
Last edit: 28 Apr 2015 20:14 by PhracturedBlue.

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

More
28 Apr 2015 20:23 #31750 by Gyrfalcon
Replied by Gyrfalcon on topic Support for walkera telemetry.
Nice timing!

I just put together an ac powered test system using a Devo12S and a MCP receiver (RX2637H-D) that has telemetry enabled for receiver voltage, battery voltage and temp. I can also easily do fixed or auto binding tests.

Would you mind making a Devo12S release as well, or point me to the source that you are using? (As well as the make command used for consistency).

Also, what recommendations for the test environment do you have? Power level, distance between receiver and transmitter, other considerations?

I'll look forward to providing some feedback on the results

Thanks,

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

More
28 Apr 2015 20:45 #31752 by PhracturedBlue
Replied by PhracturedBlue on topic Support for walkera telemetry.
I've uploaded the devo12 build to the above location.
I have not published the repo, however it is just the trunk + the files from vlad's .zip file.
I then edit devo_cyrf6936.c to enable the printf in the 'Reset detector'
I run:
make TARGET=devo12 TYPE=dev zip

Note that I have never been able to reproduce the LOS that linux-user has on any of my transmitters, but I have been able to trigger the Reset condition. We have high confidence that the reset condition will resolve the LOS issue, so now it is more a question of optimizing the code and trying to prevent the Reset from happening in the 1st place (and fixing the telemetry glitches)

Anyhow, I'd like to see a significant amount of testing to gain confidence this can be pushed into the trunk.

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

More
28 Apr 2015 20:56 #31753 by Gyrfalcon
Replied by Gyrfalcon on topic Support for walkera telemetry.
Perfect and thanks for the additional information!

I'll let you know what I discover with my system.

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

More
28 Apr 2015 21:07 - 28 Apr 2015 21:19 #31754 by linux-user
Replied by linux-user on topic Support for walkera telemetry.
Hm, first result with deviation-devo10-v4.0.1-25d5f26:
I see lots of 'RST CYRF" messages as soon as RX is connected.
TX alone (without connected RX) does not show 'RST CYRF" messages at first glance.

Besides that it seems to work good. Telemetry works perfect. No noticeable delay on control.
Last edit: 28 Apr 2015 21:19 by linux-user.

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

More
28 Apr 2015 21:45 - 28 Apr 2015 21:56 #31757 by Gyrfalcon
Replied by Gyrfalcon on topic Support for walkera telemetry.
So far that is also the same for me.

Also, (this is probably obvious and expected) with Telemetry turned off no RST CYRF or any other messages are displayed.

I am also getting a lot of these messages - only with Telemetry on. (I'll check into this later.)

DEBUG: LCD_DrawWindowedImageFromFile (media/devo12.bmp) Dimensions asked for
size (480 x 272) bounds (464 x 275)

Hard to read at the beginning off line due to characters overlapping.
Last edit: 28 Apr 2015 21:56 by Gyrfalcon. Reason: More information

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

More
28 Apr 2015 22:29 #31761 by PhracturedBlue
Replied by PhracturedBlue on topic Support for walkera telemetry.
there is a bunch of debug stuff written to the screen (you'll see the same in the emulator). I'm only interested in the debug messages from the devo protocol though (the 'RST CYRF' message). It sounds like vald's code isn't really working as intended, since the Reset should be a very rare (or non-existant event)

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

More
28 Apr 2015 22:47 #31762 by Gyrfalcon
Replied by Gyrfalcon on topic Support for walkera telemetry.
Thanks PB, I understand.

As for the Devo Telemetry with an RX2637H-D, it seams to perform the best of any the builds I have tried so far. Unfortunately, there is a consistent flow of Rst CYRF messages on my system.

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

More
29 Apr 2015 06:43 - 29 Apr 2015 07:55 #31790 by vlad_vy
Replied by vlad_vy on topic Support for walkera telemetry.
Sorry, it seems I miss something and Devo telemetry timing is variable, so it's not possible to have devo_telemetry_cb() without poll. I can reduce polling only. The next code version tested with debug build and enabled printf(" Rst CYRF\n"). I have not any Rst CYRF messages at debug screen. I had several flights without any problems.
static u16 devo_telemetry_cb()
{
    if (txState == 0) {
        txState = 1;
        DEVO_BuildPacket();
        CYRF_WriteDataPacket(packet);
        return 900;
    }
    int delay = 100;
    if (txState == 1) {
        int i = 0;
        u8 reg;
        while (! ((reg = CYRF_ReadRegister(0x04)) & 0x02)) {
            if (++i >= NUM_WAIT_LOOPS)
                break;
        }
        if (((reg & 0x22) == 0x20) || (CYRF_ReadRegister(0x02) & 0x80)) {
            CYRF_Reset();
            cyrf_init();
            cyrf_set_bound_sop_code();
            CYRF_ConfigRFChannel(*radio_ch_ptr);
            //printf(" Rst CYRF\n");
            delay = 1500;
            txState = 15;
        } else {
            if (state == DEVO_BOUND) {
                /* exit binding state */
                state = DEVO_BOUND_3;
                cyrf_set_bound_sop_code();
            }
            if(pkt_num == 0 || bind_counter > 0) {
                delay = 1500;
                txState = 15;
            } else {
                CYRF_SetTxRxMode(RX_EN); //Receive mode
                CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x80); //Prepare to receive (do not enable any IRQ)
                delay = 900;
                txState = 9;                
            }
        }
    } else {  // this won't be true in emulator so we need to simulate it somehow
        u8 rx_status = CYRF_ReadRegister(CYRF_07_RX_IRQ_STATUS);
        if ((rx_status & 0x03) == 0x02) {  // RXC=1, RXE=0 then 2nd check is required (debouncing)
            rx_status |= CYRF_ReadRegister(CYRF_07_RX_IRQ_STATUS);
            if ((rx_status & 0x07) == 0x02) {  // good data (complete with no errors)
                CYRF_WriteRegister(CYRF_07_RX_IRQ_STATUS, 0x80);  // need to set RXOW before data read
                CYRF_ReadDataPacket(packet);
                parse_telemetry_packet(packet);
                delay = 100 * (16 - txState);
                txState = 15;
            }
        }
#ifdef EMULATOR
        u8 telem_bit = rand32() % 7; // random number in [0, 7)
        packet[0] =  TELEMETRY_ENABLE + telem_bit; // allow emulator to simulate telemetry parsing to prevent future bugs in the telemetry monitor
        //printf("telem 1st packet: 0x%x\n", packet[0]);
        for(int i = 1; i < 13; i++)
            packet[i] = rand32() % 256;
        parse_telemetry_packet(packet);
        for(int i = 0; i < TELEM_UPDATE_SIZE; i++)
            Telemetry.updated[i] = 0xff;
        delay = 100 * (16 - txState);
        txState = 15;
#endif
    }
    txState++;
    if(txState == 16) { //2.3msec have passed
        CYRF_SetTxRxMode(TX_EN); //Write mode
        if(pkt_num == 0) {
            //Keep tx power updated
            CYRF_WriteRegister(CYRF_03_TX_CFG, 0x08 | Model.tx_power);
            radio_ch_ptr = radio_ch_ptr == &radio_ch[2] ? radio_ch : radio_ch_ptr + 1;
            CYRF_ConfigRFChannel(*radio_ch_ptr);
        }
        txState = 0;
    }
    return delay;
}

Changed files (printf(" Rst CYRF\n") commented out):
Last edit: 29 Apr 2015 07:55 by vlad_vy.

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

More
29 Apr 2015 07:55 - 29 Apr 2015 08:18 #31791 by vlad_vy
Replied by vlad_vy on topic Support for walkera telemetry.
I think the next code will be better, it doesn't continue polling in case buffer error.

static u16 devo_telemetry_cb()
{
    if (txState == 0) {
        txState = 1;
        DEVO_BuildPacket();
        CYRF_WriteDataPacket(packet);
        return 900;
    }
    int delay = 100;
    if (txState == 1) {
        int i = 0;
        u8 reg;
        while (! ((reg = CYRF_ReadRegister(0x04)) & 0x02)) {
            if (++i >= NUM_WAIT_LOOPS)
                break;
        }
        if (((reg & 0x22) == 0x20) || (CYRF_ReadRegister(0x02) & 0x80)) {
            CYRF_Reset();
            cyrf_init();
            cyrf_set_bound_sop_code();
            CYRF_ConfigRFChannel(*radio_ch_ptr);
            //printf(" Rst CYRF\n");
            delay = 1500;
            txState = 15;
        } else {
            if (state == DEVO_BOUND) {
                /* exit binding state */
                state = DEVO_BOUND_3;
                cyrf_set_bound_sop_code();
            }
            if(pkt_num == 0 || bind_counter > 0) {
                delay = 1500;
                txState = 15;
            } else {
                CYRF_SetTxRxMode(RX_EN); //Receive mode
                CYRF_WriteRegister(CYRF_05_RX_CTRL, 0x80); //Prepare to receive (do not enable any IRQ)
                delay = 900;
                txState = 9;                
            }
        }
    } else {  // this won't be true in emulator so we need to simulate it somehow
        u8 rx_status = CYRF_ReadRegister(CYRF_07_RX_IRQ_STATUS);
        if ((rx_status & 0x03) == 0x02) {  // RXC=1, RXE=0 then 2nd check is required (debouncing)
            rx_status |= CYRF_ReadRegister(CYRF_07_RX_IRQ_STATUS);
            if ((rx_status & 0x07) == 0x02) {  // good data (complete with no errors)
                CYRF_WriteRegister(CYRF_07_RX_IRQ_STATUS, 0x80);  // need to set RXOW before data read
                CYRF_ReadDataPacket(packet);
                parse_telemetry_packet(packet);
            }
            delay = 100 * (16 - txState);
            txState = 15;
        }
#ifdef EMULATOR
        u8 telem_bit = rand32() % 7; // random number in [0, 7)
        packet[0] =  TELEMETRY_ENABLE + telem_bit; // allow emulator to simulate telemetry parsing to prevent future bugs in the telemetry monitor
        //printf("telem 1st packet: 0x%x\n", packet[0]);
        for(int i = 1; i < 13; i++)
            packet[i] = rand32() % 256;
        parse_telemetry_packet(packet);
        for(int i = 0; i < TELEM_UPDATE_SIZE; i++)
            Telemetry.updated[i] = 0xff;
        delay = 100 * (16 - txState);
        txState = 15;
#endif
    }
    txState++;
    if(txState == 16) { //2.3msec have passed
        CYRF_SetTxRxMode(TX_EN); //Write mode
        if(pkt_num == 0) {
            //Keep tx power updated
            CYRF_WriteRegister(CYRF_03_TX_CFG, 0x08 | Model.tx_power);
            radio_ch_ptr = radio_ch_ptr == &radio_ch[2] ? radio_ch : radio_ch_ptr + 1;
            CYRF_ConfigRFChannel(*radio_ch_ptr);
        }
        txState = 0;
    }
    return delay;
}

Changed files (printf(" Rst CYRF\n") commented out):
Last edit: 29 Apr 2015 08:18 by vlad_vy.

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

More
29 Apr 2015 08:03 #31792 by Gyrfalcon
Replied by Gyrfalcon on topic Support for walkera telemetry.
OK, since I was still up, I created a new build as highlighted by PhracturedBlue with Vlad's latest updates. I un commented printf("Rst_CYRF\n") and it is running on the bench. So far all looks good. No Rst CYFR messages, telemetry looks solid and the receiver has no LOS. I'll let you know tomorrow if it hold solid over night.

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

More
29 Apr 2015 08:23 - 29 Apr 2015 09:18 #31794 by vlad_vy
Replied by vlad_vy on topic Support for walkera telemetry.
I think that all my latest changes have not useful results, so I returned to first version of code, with minor changes - reduced polling and buffer overwrite enabled.


Changed files (printf(" Rst CYRF\n") commented out):
Last edit: 29 Apr 2015 09:18 by vlad_vy.

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

More
29 Apr 2015 12:52 #31798 by PhracturedBlue
Replied by PhracturedBlue on topic Support for walkera telemetry.
vlad's build (with reset message enabled):
www.deviationtx.com/downloads-new/catego...-devo-dsm-test-31794

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

More
30 Apr 2015 04:09 #31830 by Gyrfalcon
Replied by Gyrfalcon on topic Support for walkera telemetry.
The latest Vlad build ([PhracturedBlue]Vlad's Devo/DSM test #31794, deviation-devo12-v4.0.1-f628e56) has been running on the bench now for over 7 hours and is looking good. No debug messages of any kind. Telemetry is holding solid as well as the receiver connection. One other observation is that the servos now seem to move smoothly. Perhaps all the Rst CYRF activity was causing a disruption to the quality of transmission signal, making the servos appear twitchy when commanded to move.

For this latest test, I am using the auto bind feature with two receivers (RX1202 and RX2637H-D w/Telemetry) and both connect and reconnect just fine. For reconnections I have removed the power and the reconnected it after a short time. Both receivers re-bind, although it would never be fast enough to prevent me from crashing. :)

I have also walked the transmitter (Devo12S @100uW) out of range for telemetry and both receivers, and returned. (I have a HK Discovery Buzzer connected on the gear channel of the RX1202 that I can hear when activated.) Once back within range everything reconnects and looks good. Again no debug messages.

Next I'll try my RX2648-D with the WK-CTL01-D Telemetry for a short test to see if it also looks good.

Later, I can also do some DSMX testing (SPMAR9020 system with a TM1000) if that code looks good to everyone. But we can discuss that on the DSM Telemetry Support thread if desired.

Everything is looking so good I am temped to get a Walkera and/or Spectrum GPS unit.

Feel free to ask any questions. Thanks

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

Time to create page: 0.092 seconds
Powered by Kunena Forum