DSM Telemetry support

More
20 Apr 2015 09:33 - 20 Apr 2015 09:36 #31407 by vlad_vy
Replied by vlad_vy on topic DSM Telemetry support
I don't think it's right

Data type = 0x16 GPS Sensor (always second GPS packet)

0[00] 22(0x16)
1[01] 00
2[02] Altitude LSB (Decimal) //In 0.1m
3[03] Altitude MSB (Decimal) //Altitude = Altitude(0x17) * 10000 + Value (in 0.1m)
4[04] 1/10000 degree minutes latitude (Decimal) (DD MM.MMMM)
5[05] 1/100 degree minutes latitude (Decimal)
6[06] degree minutes latitude (Decimal)
7[07] degrees latitude (Decimal)
8[08] 1/10000 degree minutes longitude (Decimal) (DD MM.MMMM)
9[09] 1/100 degree minutes longitude (Decimal)
10[0A] degree minutes longitude (Decimal)
11[0B] degrees longitude (Decimal)
12[0C] Heading LSB (Decimal)
13[0D] Heading MSB (Decimal) Divide by 10 for Degrees
14[0E] Unknown (Decimal)
15[0F] First bit for latitude: 1=N(+), 0=S(-);
Second bit for longitude: 1=E(+), 0=W(-);
Third bit for longitude over 99 degrees: 1=+-100 degrees
Last edit: 20 Apr 2015 09:36 by vlad_vy.

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

More
20 Apr 2015 13:31 #31415 by PhracturedBlue
Replied by PhracturedBlue on topic DSM Telemetry support
The latest code has debug-to-screen. You can just print out the raw data and figure out what needs to be done. Thoughwe already went through much of this when telemetry was originally added (see the beginning of this thread)

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

More
20 Apr 2015 13:47 - 20 Apr 2015 17:07 #31418 by vlad_vy
Replied by vlad_vy on topic DSM Telemetry support
Indigo, with latest build nothing changed. Latitude and Longitude have zero values.

It looks like wrong pointer in pkt32_to_coord(u16 *ptr). Is it possible?
Last edit: 20 Apr 2015 17:07 by vlad_vy.

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

More
21 Apr 2015 11:07 - 22 Apr 2015 19:35 #31454 by Indigo
Replied by Indigo on topic DSM Telemetry support
I believe problem is
3600000 (should have another zero)
36000000 = 60 x 60 x 1000 (edit: wrong)
edit: Ok, I made a mistake adding another zero. Anyway, lets see what number do you get now?

I have uploaded a new test build c3692a0

I have also added some checks to cyrf3936.c
Replacing:
void CYRF_SetTxRxMode(enum TXRX_State mode)
{
    //Set the post tx/rx state
    CYRF_WriteRegister(CYRF_0F_XACT_CFG, mode == TX_EN ? 0x2C : 0x28);
With:
void CYRF_SetTxRxMode(enum TXRX_State mode)
{
    // Wait for TXGO to self clear indicating transmit has completed.
    while (CYRF_ReadRegister(CYRF_02_TX_CTRL) & 0x80) { }

    if ((mode != RX_EN) != (!(CYRF_ReadRegister(CYRF_05_RX_CTRL) & 0x80))) {
        // if not RX_EN and still in receive mode
        // OR providing TXGO and RXGO are not set, set end state.
        CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x28); // force into Synth(TX) state.
    }
I find the if condition above results in less Holds occurring.

The preceding while loop is not really required, that situation seems to only occur briefly after powering on tx. However, it does ensure that both TXGO and RXGO are not set, before forcing a mode change.
After forcing mode change, waiting for force to complete is not required.
Below is my original testing code:
void CYRF_SetTxRxMode(enum TXRX_State mode)
{
    unsigned i = 0;

    // Wait for TXGO to self clear indicating transmit has completed.
    while (CYRF_ReadRegister(CYRF_02_TX_CTRL) & 0x80) { ++i; }
    if (i) {
        // this occurs briefly at startup (after POWER ON)
        MUSIC_Play(MUSIC_DONE_BINDING);
        i = 0;
    }

    if ((mode != RX_EN) != (!(CYRF_ReadRegister(CYRF_05_RX_CTRL) & 0x80))) {
        // if not RX_EN and still in receive mode
        // OR providing TXGO and RXGO are not set, set end state.
        CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x28); // force into Synth(TX) state.

        // Wait for the FRC_END_STATE bit in XACT_CFG register to clear indicating force has completed.
        while ((CYRF_ReadRegister(CYRF_0F_XACT_CFG) & 0x20) && ++i < NUM_WAIT_LOOPS) { }
        if (i >= NUM_WAIT_LOOPS)        // If force does not complete within 100us,
            MUSIC_Play(MUSIC_ALARM1);   // we should probably reset, but for now just sound an alarm.
        else if (i)
            MUSIC_Play(MUSIC_TIMER_WARNING);    // This won't sound if force completes immediately.
    }

#if HAS_MULTIMOD_SUPPORT
    ...
void CYRF_StartReceive()
{
    u8 reg = CYRF_ReadRegister(CYRF_05_RX_CTRL);
    if (!(reg & 0x80)) {
        // The RXGO bit must not be set until after it self clears.
        CYRF_WriteRegister(CYRF_05_RX_CTRL, reg | 0x80);    // Prepare to receive
        CYRF_ReadRegister(CYRF_13_RSSI);    // Clear RSSI
    }
    else  // This happens before binding completes
        MUSIC_Play(MUSIC_KEY_PRESSING);
}
Last edit: 22 Apr 2015 19:35 by Indigo.

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

More
21 Apr 2015 11:40 - 21 Apr 2015 12:04 #31455 by vlad_vy
Replied by vlad_vy on topic DSM Telemetry support
I think any while() loop without break early or late will cause Tx reboot. Probably will be better:
void CYRF_SetTxRxMode(enum TXRX_State mode)
{
    if ( !(CYRF_ReadRegister(CYRF_02_TX_CTRL) & 0x80) && !(CYRF_ReadRegister(CYRF_05_RX_CTRL) & 0x80)) {
        // TXGO and RXGO are not set, set end state.
        CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x28); //force into Synth(TX) end state
        CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x08); //set Synth(TX) as end state
    }
Last edit: 21 Apr 2015 12:04 by vlad_vy.

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

More
21 Apr 2015 13:19 - 22 Apr 2015 19:36 #31460 by Indigo
Replied by Indigo on topic DSM Telemetry support
I initially tried that and found it wouldn't bind.

What happens is it stays in receive mode waiting for receive to complete.
When required mode is not RX_EN, (eg. TX_EN) then we must force receive mode to end.

The while loop only executes breifly at startup. At other times it is always false (never loops).
Last edit: 22 Apr 2015 19:36 by Indigo.

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

More
21 Apr 2015 13:48 - 21 Apr 2015 13:50 #31461 by vlad_vy
Replied by vlad_vy on topic DSM Telemetry support
You need to see Walkera telemetry topic. If "connection lost" issue happened, we can get stuck in that while() loop and implemented CYRF reset can newer be started.
Last edit: 21 Apr 2015 13:50 by vlad_vy.

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

More
21 Apr 2015 14:09 #31462 by PhracturedBlue
Replied by PhracturedBlue on topic DSM Telemetry support
SetTxRxMode should NOT have a loop in it. It needs to have a predictable runtime. I don't think it should need the force-end-state either. If it is being called at the wrong time, I would put the check in the calling routine, but I can probably be convinced otherwise. i really think something else needs to be done. The timing in the mai loop should ensure Tx mode and RxMode don't overlap. If it is overlapping we should fix it there.

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

More
21 Apr 2015 14:44 - 21 Apr 2015 14:47 #31465 by vlad_vy
Replied by vlad_vy on topic DSM Telemetry support
Next code is tested and working
void CYRF_SetTxRxMode(enum TXRX_State mode)
{
    //Set the post tx/rx state
    if((mode == TX_EN) && !(CYRF_ReadRegister(CYRF_02_TX_CTRL) & 0x80)) 
        CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x28);
    if((mode == RX_EN) && !(CYRF_ReadRegister(CYRF_05_RX_CTRL) & 0x80) && !(CYRF_ReadRegister(CYRF_02_TX_CTRL) & 0x80)) 
        CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x28); 
Last edit: 21 Apr 2015 14:47 by vlad_vy.

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

More
21 Apr 2015 14:55 - 21 Apr 2015 15:00 #31466 by vlad_vy
Replied by vlad_vy on topic DSM Telemetry support
Indigo, with latest build c3692a0 nothing changed. Latitude and Longitude have zero values. Is it possible that something wrong in telemetry page code?
Last edit: 21 Apr 2015 15:00 by vlad_vy.

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

More
21 Apr 2015 16:31 #31468 by Indigo
Replied by Indigo on topic DSM Telemetry support
I have added:
void CYRF_EndReceiveMode()
{
    if (CYRF_ReadRegister(CYRF_05_RX_CTRL) & 0x80)  // If RXGO (receiving)
        CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x28); // force into Synth(TX) state.
}

This seems to work, so no forcing is needed in:
void CYRF_SetTxRxMode(enum TXRX_State mode)
{
    CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x08); // Set end state to Synth(TX).

New version 05041f3 uploaded to Test Builds.
Source

Latitude and Longitude ???? I don't know.

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

More
21 Apr 2015 18:34 - 21 Apr 2015 19:07 #31469 by vlad_vy
Replied by vlad_vy on topic DSM Telemetry support
I'm not sure it's 100% correctly. We can't be sure that we have not new reception already in progress. It will be correct if we force end state immediately after reading RX buffer. But we have considerable time interval for parsing telemetry after reading RX buffer.

Probably will be better combine buffer clean-up and reading into telemetry buffer at CYRF_RxPacketIsGood(length, *ptr) and force end state at the end of CYRF_RxPacketIsGood(length, *ptr).
Last edit: 21 Apr 2015 19:07 by vlad_vy.

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

More
22 Apr 2015 10:18 #31494 by Indigo
Replied by Indigo on topic DSM Telemetry support
With END STATE always set to Synth(TX), when receive completes the mode will change to Synth(TX). So there can not be new reception in progress.

Currently the Devo protocol calls CYRF_RxPacketIsGood() every 200us until receive is complete, so we can't combine with CYRF_EndReceiveMode(), unless we change Devo protocol to check only once, ie. as late as possible but allowing enough time for ParseTelemetryPacket() to complete.

So I'll keep CYRF_EndReceiveMode() and move the buffer clean-up to it; to end receive mode properly:

The recommended method to exit receive mode when an error has occurred is to force END STATE and then dummy read all RX_COUNT_ADR bytes from RX_BUFFER_ADR

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

More
22 Apr 2015 13:38 - 22 Apr 2015 17:05 #31497 by vlad_vy
Replied by vlad_vy on topic DSM Telemetry support
Next code is tested and working. I don't know if it will be better or worse.
void CYRF_SetTxRxMode(enum TXRX_State mode)
{
    //Set the post tx/rx state
    if((mode == TX_EN) && !(CYRF_ReadRegister(CYRF_02_TX_CTRL) & 0x80)) 
        CYRF_WriteRegister(CYRF_0F_XACT_CFG, 0x28);

#if HAS_MULTIMOD_SUPPORT

devo_cyrf6936
    txState++;
    if(txState == 16) { //2.3msec have passed
        if (CYRF_ReadRegister(CYRF_05_RX_CTRL) & 0x80) { //We're still in receive mode
            //Disrupt any pending receive by enabling abort
            //Force End State should not be used to abort a receive if a SOP has already happened
            CYRF_WriteRegister(CYRF_29_RX_ABORT, 0x20);
            //Buffer clean-up
            CYRF_RxPacketIsGood(0x00);
            //Abort by writing the FRC_END_STATE bit in the XACT_CFG register
            CYRF_SetTxRxMode(TX_EN); //Write mode
            //Disable abort
            CYRF_WriteRegister(CYRF_29_RX_ABORT, 0x00);    
        } 
        else CYRF_SetTxRxMode(TX_EN); //Write mode

dsm2_cyrf6936
    } else if(state == DSM2_CH2_READ_A || state == DSM2_CH2_READ_B) {
        //Read telemetry if needed and parse if good
        if (CYRF_RxPacketIsGood(0x10)) {
           CYRF_ReadDataPacket(packet);
           parse_telemetry_packet();
        }
        if (state == DSM2_CH2_READ_A && num_channels < 8) {
            state = DSM2_CH2_READ_B;
            CYRF_StartReceive(); //Prepare to receive
            return 11000;
        }
        if (state == DSM2_CH2_READ_A)
            state = DSM2_CH1_WRITE_B;
        else
            state = DSM2_CH1_WRITE_A;
        if (CYRF_ReadRegister(CYRF_05_RX_CTRL) & 0x80) { //We're still in receive mode
            //Disrupt any pending receive by enabling abort
            //Force End State should not be used to abort a receive if a SOP has already happened
            CYRF_WriteRegister(CYRF_29_RX_ABORT, 0x20);
            //Buffer clean-up
            CYRF_RxPacketIsGood(0x00);
            //Abort by writing the FRC_END_STATE bit in the XACT_CFG register
            CYRF_SetTxRxMode(TX_EN); //Write mode
            //Disable abort
            CYRF_WriteRegister(CYRF_29_RX_ABORT, 0x00);    
        } 
        else CYRF_SetTxRxMode(TX_EN); //Write mode
        set_sop_data_crc();
        return READ_DELAY;
    } 
    return 0;
}
Last edit: 22 Apr 2015 17:05 by vlad_vy.

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

More
23 Apr 2015 02:23 - 23 Apr 2015 04:49 #31504 by Indigo
Replied by Indigo on topic DSM Telemetry support
Forcing end state is only required after receiving, so it goes in CYRF_EndReceive(), where it is only used if still receiving.
If you find RX_ABORT is needed then your abort procedure should be added to CYRF_EndReceive().

IMHO. I think RX_ABORT is used for interrupting receive while a continuous data stream is being received.
In our case receive is just waiting for the rest of the expected data, so there is nothing really to interrupt.

I'm trying to keep code small, so I'll only include if really required. I've currently got DSM module size down to 3,908 bytes.

I've uploaded a new version bb10550 to Test Builds. This time Latitude and Longitude should work because I have pretty much restored original code (which I assume was working). Source code
Last edit: 23 Apr 2015 04:49 by Indigo.

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

More
23 Apr 2015 06:00 - 23 Apr 2015 07:14 #31508 by vlad_vy
Replied by vlad_vy on topic DSM Telemetry support
Your version doesn't guarantee that RX_GO bit will cleared. I inserted "while(CYRF_ReadRegister(CYRF_05_RX_CTRL) & 0x80) {}" at the end of the Devo cb() and at a very short time (after Ladybird connected) Tx reboots. With my version of code it working without problems.
        }
        txState = 0;
        while(CYRF_ReadRegister(CYRF_05_RX_CTRL) & 0x80) {}
    }
    return delay;
}
Last edit: 23 Apr 2015 07:14 by vlad_vy.

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

More
23 Apr 2015 10:03 #31510 by Indigo
Replied by Indigo on topic DSM Telemetry support
Thanks for testing this. :)

Please try new version 55d20bd.

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

More
23 Apr 2015 11:51 #31512 by vlad_vy
Replied by vlad_vy on topic DSM Telemetry support
Indigo, what you looking for? What is the problem you trying to solve?

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

More
23 Apr 2015 12:00 #31513 by Indigo
Replied by Indigo on topic DSM Telemetry support
Is Latitude and Longitude now working?

Is Devo telemetry working?

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

More
23 Apr 2015 14:24 #31527 by vlad_vy
Replied by vlad_vy on topic DSM Telemetry support
Indigo, with latest build nothing changed. Latitude and Longitude have zero values. With nightly build all OK.

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

Time to create page: 0.090 seconds
Powered by Kunena Forum