This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] LP-CC1352P7:CC1352P7 - TX-RX 链命令在专有模式下未接收数据 (868MHz)

Guru**** 2546670 points
Other Parts Discussed in Thread: CC1352P7

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/1561482/lp-cc1352p7-cc1352p7---tx-rx-chain-command-not-receiving-data-in-proprietary-mode-868-mhz

器件型号:LP-CC1352P7
主题中讨论的其他器件:CC1352P7

工具/软件:

存在许多风险

  • 频率 : CC1352P7
  • SDK 中找到 :SimpleLink SDK 8.30
  • 射频模式 :专有低于 1GHz (868MHz)
  • 配置 :1 Mbps、350 kHz 偏差、2-GFSK、2.2MHz RX 带宽

我们遇到 TX-RX 命令链问题。 仅 TX 和仅 RX 操作运行良好、但当链接 TX->RX 命令时、即使我们知道远程器件正在传输数据、RX 部分也永远不会接收数据。  我们的协议要求 TX 完成后不久(延迟很小)就会打开 RX 窗口。

测试场景

  1. 器件 A :发送  请求数据包,然后立即侦听 使用 TX-RX 链的响应数据包
  2. 器件 B : 正确接收数据包、立即发送 响应数据包
  3. 问题 :设备 A 完成链 (EVT_CHAIN_DONE)、但从不接收连接请求数据包


static int radio_start_tx_rx_chain(void) {
    /* Reset command status */
    RF_cmdPropTx.status = 0;
    RF_cmdPropRx.status = 0;

    /* Configure TX */
    RF_cmdPropTx.pPkt = g_radio.current_op.tx_data;
    RF_cmdPropTx.pktLen = g_radio.current_op.tx_length;
    RF_cmdPropTx.startTrigger.triggerType = TRIG_NOW;
    RF_cmdPropTx.startTrigger.pastTrig = 1;
    RF_cmdPropTx.pNextOp = (RF_Op*)&RF_cmdPropRx;
    RF_cmdPropTx.condition.rule = COND_ALWAYS;

    /* Configure RX */
    RF_cmdPropRx.maxPktLen = RADIO_MAX_PACKET_LEN;
    RF_cmdPropRx.pQueue = &g_radio.rx_data_queue;
    RF_cmdPropRx.startTrigger.triggerType = TRIG_NOW;
    RF_cmdPropRx.startTrigger.pastTrig = 1;
    RF_cmdPropRx.endTrigger.triggerType = TRIG_REL_START;
    RF_cmdPropRx.endTime = 8000;  // 2ms window
    RF_cmdPropRx.pNextOp = NULL;
    RF_cmdPropRx.condition.rule = COND_NEVER;

    /* Reset RX queue */
    g_radio.rx_data_entry.status = DATA_ENTRY_PENDING;

    /* Post chain */
    g_radio.cmd_handle = RF_postCmd(g_radio.rf_handle,
                                    (RF_Op*)&RF_cmdPropTx,
                                    RF_PriorityNormal,
                                    radio_rf_callback,
                                    RF_EventLastCmdDone);

    return (g_radio.cmd_handle >= 0) ? 0 : -1;
}



static int radio_start_rx(void) {
    /* Reset RX data entry */
    g_radio.rx_data_entry.status = DATA_ENTRY_PENDING;

    /* Use global RF_cmdPropRx, not cmd_rx_adv */
    RF_cmdPropRx.status = 0;
    RF_cmdPropRx.maxPktLen = RADIO_MAX_PACKET_LEN;
    RF_cmdPropRx.pQueue = &g_radio.rx_data_queue;

    /* Configure what gets appended */
    RF_cmdPropRx.rxConf.bAutoFlushIgnored = 1;
    RF_cmdPropRx.rxConf.bAutoFlushCrcErr = 1;
    RF_cmdPropRx.rxConf.bIncludeHdr = 1;      /* Include length byte */
    RF_cmdPropRx.rxConf.bIncludeCrc = 0;      /* Don't include CRC */
    RF_cmdPropRx.rxConf.bAppendRssi = 1;      /* Append RSSI */
    RF_cmdPropRx.rxConf.bAppendTimestamp = 1; /* Append timestamp */
    RF_cmdPropRx.rxConf.bAppendStatus = 1;    /* Append status */

    /* Keep RX on for multiple packets */
    RF_cmdPropRx.pktConf.bRepeatOk = 1;
    RF_cmdPropRx.pktConf.bRepeatNok = 1;

    if (g_radio.current_op.rx_timeout_rat > 0) {
        RF_cmdPropRx.endTrigger.triggerType = TRIG_REL_START;
        RF_cmdPropRx.endTime = g_radio.current_op.rx_timeout_rat;
    } else {
        RF_cmdPropRx.endTrigger.triggerType = TRIG_NEVER;
    }

    /* Post RX command directly (no chaining) */
    g_radio.cmd_handle = RF_postCmd(g_radio.rf_handle,
                                    (RF_Op*)&RF_cmdPropRx,
                                    RF_PriorityNormal,
                                    radio_rf_callback,
                                    RF_EventRxEntryDone | RF_EventLastCmdDone);

    if (g_radio.cmd_handle < 0) {
        g_radio.state = RADIO_STATE_IDLE;
        return -1;
    }

    return 0;
}



static int radio_start_tx(void) {
    /* Prepare TX packet with length byte */
    g_radio.tx_packet[0] = g_radio.current_op.tx_length;
    memcpy(&g_radio.tx_packet[1], g_radio.current_op.tx_data,
           g_radio.current_op.tx_length);

    /* Reset global commands */
    RF_cmdPropTx.status = 0;
    RF_cmdPropRx.status = 0;

    RF_cmdPropTx.pPkt = g_radio.current_op.tx_data;
    RF_cmdPropTx.pktLen = g_radio.current_op.tx_length;
    RF_cmdPropTx.startTrigger.triggerType = TRIG_NOW;
    RF_cmdPropTx.startTrigger.pastTrig = 1;
    RF_cmdPropTx.pNextOp = NULL;
    RF_cmdPropTx.condition.rule = COND_ALWAYS;

    /* Post chain */
    g_radio.cmd_handle = RF_postCmd(g_radio.rf_handle,
                                    (RF_Op*)&RF_cmdPropTx,
                                    RF_PriorityNormal,
                                    radio_rf_callback,
                                    RF_EventLastCmdDone);

    return (g_radio.cmd_handle >= 0) ? 0 : -1;
}



问题

  1. 在与示例不同的专有模式下、TX-RX 链是否需要特定配置?
  2. 我们是否应该注意 TX END 和 RX START 之间的时序限制?
  3. 我们是否应该使用 CMD_PROP_TX_ADV/CMD_PROP_RX_ADV 而不是基本命令?
  4. 链中的 TX 和 RX 之间是否需要最小或最大间隙?
  5. 最重要的是:是否有任何专有模式下 TX->RX 命令链的参考示例? 我们搜索了 SDK、但只找到了仅 TX 链和仅 RX 操作。

非常感谢有关专有模式的正确 TX-RX 链配置的任何指导。 我们特别需要 RX 在 TX 完成后立即启动、以正确实现我们的协议。



  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Sharan、

    当从 Tx 切换到 Rx 时、无线电会有一定的延迟、我相信几百微秒。 您在这里有什么要求?  

    谢谢、

    Marie

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您应该在某些引脚上输出 LNA 和 Pa 信号以进行调试(在发送器和接收器上)、以确保在传输时接收器处于 RX 中:

    将射频内核信号路由到物理引脚—SimpleLinkTm CC13XX/CC26XX SDK 专有射频用户指南 7.30.00 文档

    一个好的方法是在调试时避免链式 RX 上出现超时、以确保您在 RX 中的时间不会太短。

    下面是使用 TX/RX 命令链的 rfPacketRX 示例的修改版本。

    该示例是针对 SmartRF Studio 进行的测试、因此我没有在 RX 中进行超时测试、因为 在测试时、我必须将 Studio 中的窗口从 RX 更改为 TX。

    /***** Includes *****/
    /* Standard C Libraries */
    #include <stdlib.h>
    
    /* TI Drivers */
    #include <ti/drivers/rf/RF.h>
    #include <ti/drivers/GPIO.h>
    
    /* Driverlib Header files */
    #include DeviceFamily_constructPath(driverlib/rf_prop_mailbox.h)
    
    /* Board Header files */
    #include "ti_drivers_config.h"
    
    /* Application Header files */
    #include "RFQueue.h"
    #include <ti_radio_config.h>
    
    /***** Defines *****/
    
    /* Packet RX Configuration */
    #define DATA_ENTRY_HEADER_SIZE  8  /* Constant header size of a Generic Data Entry */
    #define MAX_LENGTH              255 /* Max length byte the radio will accept */
    #define NUM_DATA_ENTRIES        2  /* NOTE: Only two data entries supported at the moment */
    #define NUM_APPENDED_BYTES      2  /* The Data Entries data field will contain:
                                        * 1 Header byte (RF_cmdPropRx.rxConf.bIncludeHdr = 0x1)
                                        * Max 30 payload bytes
                                        * 1 status byte (RF_cmdPropRx.rxConf.bAppendStatus = 0x1) */
    #define PAYLOAD_LENGTH          5
    
    
    /***** Prototypes *****/
    static void callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e);
    
    /***** Variable declarations *****/
    static RF_Object rfObject;
    static RF_Handle rfHandle;
    
    /* Buffer which contains all Data Entries for receiving data.
     * Pragmas are needed to make sure this buffer is 4 byte aligned (requirement from the RF Core) */
    #if defined(__TI_COMPILER_VERSION__)
    #pragma DATA_ALIGN (rxDataEntryBuffer, 4);
    static uint8_t
    rxDataEntryBuffer[RF_QUEUE_DATA_ENTRY_BUFFER_SIZE(NUM_DATA_ENTRIES,
                                                      MAX_LENGTH,
                                                      NUM_APPENDED_BYTES)];
    #elif defined(__IAR_SYSTEMS_ICC__)
    #pragma data_alignment = 4
    static uint8_t
    rxDataEntryBuffer[RF_QUEUE_DATA_ENTRY_BUFFER_SIZE(NUM_DATA_ENTRIES,
                                                      MAX_LENGTH,
                                                      NUM_APPENDED_BYTES)];
    #elif defined(__GNUC__)
    static uint8_t
    rxDataEntryBuffer[RF_QUEUE_DATA_ENTRY_BUFFER_SIZE(NUM_DATA_ENTRIES,
                                                      MAX_LENGTH,
                                                      NUM_APPENDED_BYTES)]
                                                      __attribute__((aligned(4)));
    #else
    #error This compiler is not supported.
    #endif
    
    /* Receive dataQueue for RF Core to fill in data */
    static dataQueue_t dataQueue;
    static rfc_dataEntryGeneral_t* currentDataEntry;
    static uint8_t packetLength;
    static uint8_t* packetDataPointer;
    static uint16_t seqNumber;
    
    
    static uint8_t rxPacket[MAX_LENGTH + NUM_APPENDED_BYTES - 1]; /* The length byte is stored in a separate variable */
    static uint8_t txPacket[PAYLOAD_LENGTH];
    
    /***** Function definitions *****/
    
    void *mainThread(void *arg0)
    {
        RF_Params rfParams;
        RF_Params_init(&rfParams);
    
        GPIO_setConfigAndMux(CONFIG_GPIO_RLED, GPIO_CFG_OUT_STD, IOC_PORT_RFC_GPO0);
        GPIO_setConfigAndMux(CONFIG_GPIO_GLED, GPIO_CFG_OUT_STD, IOC_PORT_RFC_GPO1);
    
        if( RFQueue_defineQueue(&dataQueue,
                                rxDataEntryBuffer,
                                sizeof(rxDataEntryBuffer),
                                NUM_DATA_ENTRIES,
                                MAX_LENGTH + NUM_APPENDED_BYTES))
        {
            /* Failed to allocate space for all data entries */
            while(1);
        }
    
        /* Modify CMD_PROP_RX command for application needs */
        /* Set the Data Entity queue for received data */
        RF_cmdPropRx.pQueue = &dataQueue;
        /* Discard ignored packets from Rx queue */
        RF_cmdPropRx.rxConf.bAutoFlushIgnored = 1;
        /* Discard packets with CRC error from Rx queue */
        RF_cmdPropRx.rxConf.bAutoFlushCrcErr = 1;
        /* Implement packet length filtering to avoid PROP_ERROR_RXBUF */
        RF_cmdPropRx.maxPktLen = MAX_LENGTH;
    
        //RF_cmdPropRx.endTrigger.triggerType = TRIG_REL_START;
        //RF_cmdPropRx.endTime = 8000;  // 2ms window
    
        RF_cmdPropTx.pktLen = PAYLOAD_LENGTH;
        RF_cmdPropTx.pPkt = txPacket;
        RF_cmdPropTx.startTrigger.triggerType = TRIG_NOW;
    
        RF_cmdPropTx.pNextOp = (rfc_radioOp_t*)&RF_cmdPropRx;
        RF_cmdPropTx.condition.rule = COND_ALWAYS;
    
        /* Request access to the radio */
        rfHandle = RF_open(&rfObject, &RF_prop, (RF_RadioSetup*)&RF_cmdPropRadioDivSetup, &rfParams);
    
        /* Set the frequency */
        RF_postCmd(rfHandle, (RF_Op*)&RF_cmdFs, RF_PriorityNormal, NULL, 0);
    
        while(1)
        {
            txPacket[0] = (uint8_t)(seqNumber >> 8);
            txPacket[1] = (uint8_t)(seqNumber++);
            uint8_t i;
            for (i = 2; i < PAYLOAD_LENGTH; i++)
            {
                txPacket[i] = rand();
            }
            RF_runCmd(rfHandle, (RF_Op*)&RF_cmdPropTx, RF_PriorityNormal, &callback, RF_EventRxEntryDone);
        }
    }
    
    void callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e)
    {
        if (e & RF_EventRxEntryDone)
        {
            //GPIO_toggle(CONFIG_GPIO_RLED);
    
            /* Get current unhandled data entry */
            currentDataEntry = RFQueue_getDataEntry();
    
            /* Handle the packet data, located at &currentDataEntry->data:
             * - Length is the first byte with the current configuration
             * - Data starts from the second byte */
            packetLength      = *(uint8_t*)(&currentDataEntry->data);
            packetDataPointer = (uint8_t*)(&currentDataEntry->data + 1);
    
            /* Copy the payload + the status byte to the packet variable */
            memcpy(rxPacket, packetDataPointer, (packetLength + 1));
    
            RFQueue_nextEntry();
        }
    }

    Siri

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Marie:

    我目前测试的延迟为~2ms、但我们可以根据无线电配置进行灵活调整。 我的主要目标是使 TX-RX 链命令正常工作。

    您能否查看并确认该功能是否radio_start_tx_rx_chain()正确?

    作为参考、当我将 TX 和 RX 拆分为单独的命令时、它会按预期工作。  如果您可以为我提供链命令的任何实现示例、也会非常有帮助。


     */
    static int radio_start_tx_rx_chain(void) {
        /* Run FS first */
        RF_cmdFs.frequency = radio_channel_to_frequency(g_radio.current_op.channel);
        RF_cmdFs.fractFreq = 0;
    
        RF_EventMask fsResult = RF_runCmd(g_radio.rf_handle,
                                         (RF_Op*)&RF_cmdFs,
                                         RF_PriorityNormal,
                                         NULL, 0);
    
        if (!(fsResult & RF_EventLastCmdDone)) {
            return -1;
        }
    
        /* Step 1: Execute TX synchronously with runCmd */
        RF_cmdPropTx.status = 0;
        RF_cmdPropTx.pPkt = g_radio.current_op.tx_data;
        RF_cmdPropTx.pktLen = g_radio.current_op.tx_length;
        RF_cmdPropTx.pktConf.bFsOff = 0;  /* Keep FS on for RX */
        RF_cmdPropTx.startTrigger.triggerType = TRIG_NOW;
        RF_cmdPropTx.startTrigger.pastTrig = 1;
        RF_cmdPropTx.pNextOp = NULL;  /* No chaining */
        RF_cmdPropTx.condition.rule = COND_NEVER;
    
        /* Synchronous TX - blocks until complete */
        RF_EventMask txResult = RF_runCmd(g_radio.rf_handle,
                                          (RF_Op*)&RF_cmdPropTx,
                                          RF_PriorityNormal,
                                          NULL, 0);
    
        log_printf("TX complete: status=0x%04X, events=0x%08X",
                   RF_cmdPropTx.status, txResult);
    
        /* Check TX success */
        if (!(txResult & RF_EventLastCmdDone) ||
            RF_cmdPropTx.status != PROP_DONE_OK) {
            log_printf("TX failed in chain");
            g_radio.state = RADIO_STATE_IDLE;
            return -1;
        }
    
        /* Call TX callback */
        if (g_radio.current_op.on_tx_done) {
            g_radio.current_op.on_tx_done(RADIO_RESULT_OK);
        }
        g_radio.stats.tx_count++;
    
        /* Step 2: Start RX asynchronously with postCmd */
        RF_cmdPropRx.status = 0;
        RF_cmdPropRx.pktConf.bFsOff = 1;  /* Can turn off FS after RX */
        RF_cmdPropRx.pktConf.bRepeatOk = 0;
        RF_cmdPropRx.pktConf.bRepeatNok = 0;
        RF_cmdPropRx.pktConf.bUseCrc = 1;
        RF_cmdPropRx.pktConf.bVarLen = 1;
    
        RF_cmdPropRx.rxConf.bAutoFlushIgnored = 1;
        RF_cmdPropRx.rxConf.bAutoFlushCrcErr = 1;
        RF_cmdPropRx.rxConf.bIncludeHdr = 1;
        RF_cmdPropRx.rxConf.bIncludeCrc = 0;
        RF_cmdPropRx.rxConf.bAppendRssi = 1;
        RF_cmdPropRx.rxConf.bAppendTimestamp = 0;
        RF_cmdPropRx.rxConf.bAppendStatus = 1;
    
        RF_cmdPropRx.maxPktLen = RADIO_MAX_PACKET_LEN;
        RF_cmdPropRx.pQueue = &g_radio.rx_data_queue;
    
        /* RX starts immediately */
        RF_cmdPropRx.startTrigger.triggerType = TRIG_NOW;
        RF_cmdPropRx.startTrigger.pastTrig = 1;
        RF_cmdPropRx.startTime = 0;
    
        /* RX window */
        RF_cmdPropRx.endTrigger.triggerType = TRIG_REL_START;
        RF_cmdPropRx.endTime = g_radio.current_op.rx_timeout_rat ?: 8000;
    
        RF_cmdPropRx.pNextOp = NULL;
        RF_cmdPropRx.condition.rule = COND_NEVER;
    
        /* Reset RX queue */
        g_radio.rx_data_entry.status = DATA_ENTRY_PENDING;
    
        log_printf("Starting RX after TX, timeout=%d RAT", RF_cmdPropRx.endTime);
    
        /* Post RX command asynchronously */
        g_radio.cmd_handle = RF_postCmd(g_radio.rf_handle,
                                        (RF_Op*)&RF_cmdPropRx,
                                        RF_PriorityNormal,
                                        radio_rf_callback,
                                        RF_EventRxEntryDone | RF_EventLastCmdDone);
    
        if (g_radio.cmd_handle < 0) {
            log_printf("RX post failed");
            g_radio.state = RADIO_STATE_IDLE;
            return -1;
        }
    
        /* State is now waiting for RX */
        g_radio.state = RADIO_STATE_RX;  /* Treat as RX-only for callback */
    
        return 0;
    }

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    请查看我刚刚发布的代码示例、并将您的代码与之进行比较。

    它已经过测试、并可与 SmartRF Studio 中的 1Mbps PHY 一起使用。

    Siri

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Siri、谢谢。 我来检查一下。

    此致、
    Sharan

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Siri:

     再次感谢此示例、它确实有所帮助。 通过对时序/延迟进行一些调整、我能够使 TX-RX 链命令正常工作。 我在下面粘贴了工作功能。

    现在、我要尝试让反向角色 (RX-TX) 发挥作用。 我遵循了 TX-RX 语法并将其适用于 RX-TX、但它似乎不起作用。 我已经包含了下面的函数供您参考。  

    您能否查看命令配置? 我将根据测试设置的需要调整时序。

    现在、我想让逆向角色发挥作用。 我遵循 TX-RX 的语法并反向修改、但不起作用。 粘贴以下函数以供您参考、请检查命令配置、我将根据我们的测试设置调整时间。

    感谢您的帮助 !

    static int radio_start_rx_tx_chain(void) {
        /* Reset commands */
        RF_cmdPropRx.status = 0;
        RF_cmdPropTx.status = 0;
    
        /* Setup RX first (slave receives first) */
        RF_cmdPropRx.commandNo = CMD_PROP_RX;
        RF_cmdPropRx.pQueue = &g_radio.rx_data_queue;
        RF_cmdPropRx.maxPktLen = RADIO_MAX_PACKET_LEN;
        RF_cmdPropRx.startTrigger.triggerType = TRIG_NOW;
        RF_cmdPropRx.startTrigger.pastTrig = 1;
    
        RF_cmdPropRx.endTrigger.triggerType = TRIG_REL_START;
        RF_cmdPropRx.endTime = 40000;
    
        /* RX configuration */
        RF_cmdPropRx.rxConf.bAutoFlushIgnored = 1;
        RF_cmdPropRx.rxConf.bAutoFlushCrcErr = 1;
        RF_cmdPropRx.rxConf.bIncludeHdr = 1;
        RF_cmdPropRx.rxConf.bAppendRssi = 1;
        RF_cmdPropRx.rxConf.bAppendStatus = 1;
    
        /* Chain to TX after RX completes */
        RF_cmdPropRx.pNextOp = (rfc_radioOp_t*)&RF_cmdPropTx;
        RF_cmdPropRx.condition.rule = COND_ALWAYS;  /* Always go to TX even if RX times out */
    
        /* Setup TX to follow RX */
        RF_cmdPropTx.pPkt = g_radio.current_op.tx_data;
        RF_cmdPropTx.pktLen = g_radio.current_op.tx_length;
        RF_cmdPropTx.startTrigger.triggerType = TRIG_REL_PREVEND;
        RF_cmdPropTx.startTrigger.pastTrig = 1;
        RF_cmdPropTx.startTime = 7000;
    
        /* TX is end of chain */
        RF_cmdPropTx.pNextOp = NULL;
        RF_cmdPropTx.condition.rule = COND_NEVER;
    
        /* Reset RX queue */
        g_radio.rx_data_entry.status = DATA_ENTRY_PENDING;
    
        /* Post the chain starting with RX */
        g_radio.cmd_handle = RF_postCmd(g_radio.rf_handle,
                                        (RF_Op*)&RF_cmdPropRx,  /* Start with RX! */
                                        RF_PriorityNormal,
                                        radio_rf_callback,
                                        RF_EventRxEntryDone | RF_EventLastCmdDone);
    
        return (g_radio.cmd_handle >= 0) ? 0 : -1;
    }



    static int radio_start_rx_tx_chain(void) {
        /* Reset commands */
        RF_cmdPropRx.status = 0;
        RF_cmdPropTx.status = 0;
    
        /* Setup RX first */
        RF_cmdPropRx.commandNo = CMD_PROP_RX;
        RF_cmdPropRx.pQueue = &g_radio.rx_data_queue;
        RF_cmdPropRx.maxPktLen = RADIO_MAX_PACKET_LEN;
        RF_cmdPropRx.startTrigger.triggerType = TRIG_NOW;
        RF_cmdPropRx.startTrigger.pastTrig = 1;
        
        /* RX window from request */
        if (g_radio.current_op.rx_timeout_rat > 0) {
            RF_cmdPropRx.endTrigger.triggerType = TRIG_REL_START;
            RF_cmdPropRx.endTime = g_radio.current_op.rx_timeout_rat;
        } else {
            RF_cmdPropRx.endTrigger.triggerType = TRIG_REL_START;
            RF_cmdPropRx.endTime = 40000;
        }
        
        /* RX configuration */
        RF_cmdPropRx.rxConf.bAutoFlushIgnored = 1;
        RF_cmdPropRx.rxConf.bAutoFlushCrcErr = 1;
        RF_cmdPropRx.rxConf.bIncludeHdr = 1;
        RF_cmdPropRx.rxConf.bAppendRssi = 1;
        RF_cmdPropRx.rxConf.bAppendStatus = 1;
        
        RF_cmdPropRx.pNextOp = (rfc_radioOp_t*)&RF_cmdPropTx;
        RF_cmdPropRx.condition.rule = COND_STOP_ON_TRUE;  /* Stop after receiving packet */
    
        /* Setup TX to follow */
        RF_cmdPropTx.commandNo = CMD_PROP_TX;
        RF_cmdPropTx.pPkt = g_radio.current_op.tx_data;
        RF_cmdPropTx.pktLen = g_radio.current_op.tx_length;
        RF_cmdPropTx.startTrigger.triggerType = TRIG_REL_PREVEND;
        RF_cmdPropTx.startTrigger.pastTrig = 1;
        RF_cmdPropTx.startTime = 7000;
        RF_cmdPropTx.pNextOp = NULL;  /* End of chain */
        RF_cmdPropTx.condition.rule = COND_NEVER;  /* Always execute if reached */
    
        /* Reset RX queue */
        g_radio.rx_data_entry.status = DATA_ENTRY_PENDING;
    
        log_printf("radio_start_rx_tx_chain");
    
        /* Post the chain starting with RX */
        g_radio.cmd_handle = RF_postCmd(g_radio.rf_handle,
                                        (RF_Op*)&RF_cmdPropRx,  /* Start with RX! */
                                        RF_PriorityNormal,
                                        radio_rf_callback,
                                        RF_EventRxEntryDone | RF_EventLastCmdDone);
    
        return (g_radio.cmd_handle >= 0) ? 0 : -1;
    }

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我以我与您分享的示例交换了 RX 和 TX 命令。

    然后我在 RX 命令上添加了一个 10ms 超时、并在 RX 之后 TX 启动 1.75ms。

    代码如下并按预期运行:

    /***** Includes *****/
    /* Standard C Libraries */
    #include <stdlib.h>
    
    /* TI Drivers */
    #include <ti/drivers/rf/RF.h>
    #include <ti/drivers/GPIO.h>
    
    /* Driverlib Header files */
    #include DeviceFamily_constructPath(driverlib/rf_prop_mailbox.h)
    
    /* Board Header files */
    #include "ti_drivers_config.h"
    
    /* Application Header files */
    #include "RFQueue.h"
    #include <ti_radio_config.h>
    
    /***** Defines *****/
    
    /* Packet RX Configuration */
    #define DATA_ENTRY_HEADER_SIZE  8  /* Constant header size of a Generic Data Entry */
    #define MAX_LENGTH              255 /* Max length byte the radio will accept */
    #define NUM_DATA_ENTRIES        2  /* NOTE: Only two data entries supported at the moment */
    #define NUM_APPENDED_BYTES      2  /* The Data Entries data field will contain:
                                        * 1 Header byte (RF_cmdPropRx.rxConf.bIncludeHdr = 0x1)
                                        * Max 30 payload bytes
                                        * 1 status byte (RF_cmdPropRx.rxConf.bAppendStatus = 0x1) */
    #define PAYLOAD_LENGTH          5
    
    
    /***** Prototypes *****/
    static void callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e);
    
    /***** Variable declarations *****/
    static RF_Object rfObject;
    static RF_Handle rfHandle;
    
    /* Buffer which contains all Data Entries for receiving data.
     * Pragmas are needed to make sure this buffer is 4 byte aligned (requirement from the RF Core) */
    #if defined(__TI_COMPILER_VERSION__)
    #pragma DATA_ALIGN (rxDataEntryBuffer, 4);
    static uint8_t
    rxDataEntryBuffer[RF_QUEUE_DATA_ENTRY_BUFFER_SIZE(NUM_DATA_ENTRIES,
                                                      MAX_LENGTH,
                                                      NUM_APPENDED_BYTES)];
    #elif defined(__IAR_SYSTEMS_ICC__)
    #pragma data_alignment = 4
    static uint8_t
    rxDataEntryBuffer[RF_QUEUE_DATA_ENTRY_BUFFER_SIZE(NUM_DATA_ENTRIES,
                                                      MAX_LENGTH,
                                                      NUM_APPENDED_BYTES)];
    #elif defined(__GNUC__)
    static uint8_t
    rxDataEntryBuffer[RF_QUEUE_DATA_ENTRY_BUFFER_SIZE(NUM_DATA_ENTRIES,
                                                      MAX_LENGTH,
                                                      NUM_APPENDED_BYTES)]
                                                      __attribute__((aligned(4)));
    #else
    #error This compiler is not supported.
    #endif
    
    /* Receive dataQueue for RF Core to fill in data */
    static dataQueue_t dataQueue;
    static rfc_dataEntryGeneral_t* currentDataEntry;
    static uint8_t packetLength;
    static uint8_t* packetDataPointer;
    static uint16_t seqNumber;
    
    
    static uint8_t rxPacket[MAX_LENGTH + NUM_APPENDED_BYTES - 1]; /* The length byte is stored in a separate variable */
    static uint8_t txPacket[PAYLOAD_LENGTH];
    
    /***** Function definitions *****/
    
    void *mainThread(void *arg0)
    {
        RF_Params rfParams;
        RF_Params_init(&rfParams);
    
        GPIO_setConfigAndMux(CONFIG_GPIO_RLED, GPIO_CFG_OUT_STD, IOC_PORT_RFC_GPO0);
        GPIO_setConfigAndMux(CONFIG_GPIO_GLED, GPIO_CFG_OUT_STD, IOC_PORT_RFC_GPO1);
    
        if( RFQueue_defineQueue(&dataQueue,
                                rxDataEntryBuffer,
                                sizeof(rxDataEntryBuffer),
                                NUM_DATA_ENTRIES,
                                MAX_LENGTH + NUM_APPENDED_BYTES))
        {
            /* Failed to allocate space for all data entries */
            while(1);
        }
    
        /* Modify CMD_PROP_RX command for application needs */
        /* Set the Data Entity queue for received data */
        RF_cmdPropRx.pQueue = &dataQueue;
        /* Discard ignored packets from Rx queue */
        RF_cmdPropRx.rxConf.bAutoFlushIgnored = 1;
        /* Discard packets with CRC error from Rx queue */
        RF_cmdPropRx.rxConf.bAutoFlushCrcErr = 1;
        /* Implement packet length filtering to avoid PROP_ERROR_RXBUF */
        RF_cmdPropRx.maxPktLen = MAX_LENGTH;
    
        RF_cmdPropRx.endTrigger.triggerType = TRIG_REL_START; 
        RF_cmdPropRx.endTime = (uint32_t)(4000000*0.01f); // 10 ms
    
        RF_cmdPropTx.pktLen = PAYLOAD_LENGTH;
        RF_cmdPropTx.pPkt = txPacket;
    
        RF_cmdPropTx.startTrigger.triggerType = TRIG_REL_PREVEND;       
        RF_cmdPropTx.startTrigger.pastTrig = 1;
        RF_cmdPropTx.startTime = (uint32_t)(4000000*0.00175f); // 1 .75 
    
        RF_cmdPropRx.pNextOp = (rfc_radioOp_t*)&RF_cmdPropTx;
        RF_cmdPropRx.condition.rule = COND_ALWAYS;
    
        /* Request access to the radio */
        rfHandle = RF_open(&rfObject, &RF_prop, (RF_RadioSetup*)&RF_cmdPropRadioDivSetup, &rfParams);
    
        /* Set the frequency */
        RF_postCmd(rfHandle, (RF_Op*)&RF_cmdFs, RF_PriorityNormal, NULL, 0);
    
        while(1)
        {
            txPacket[0] = (uint8_t)(seqNumber >> 8);
            txPacket[1] = (uint8_t)(seqNumber++);
            uint8_t i;
            for (i = 2; i < PAYLOAD_LENGTH; i++)
            {
                txPacket[i] = rand();
            }
            RF_runCmd(rfHandle, (RF_Op*)&RF_cmdPropRx, RF_PriorityNormal, &callback, RF_EventRxEntryDone);
        }
    }
    
    void callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e)
    {
        if (e & RF_EventRxEntryDone)
        {
            /* Get current unhandled data entry */
            currentDataEntry = RFQueue_getDataEntry();
    
            /* Handle the packet data, located at &currentDataEntry->data:
             * - Length is the first byte with the current configuration
             * - Data starts from the second byte */
            packetLength      = *(uint8_t*)(&currentDataEntry->data);
            packetDataPointer = (uint8_t*)(&currentDataEntry->data + 1);
    
            /* Copy the payload + the status byte to the packet variable */
            memcpy(rxPacket, packetDataPointer, (packetLength + 1));
    
            RFQueue_nextEntry();
        }
    }
    

    运行上面的代码并监测 PA 和 LNA 信号(+另一个发送器的 PA 信号)、看起来像这样:

    RX 在 10ms 后超时、并在这之后发送一个数据包 1.75ms。 在超时和接收数据包的情况下发送数据包。

    将 RX 命令的.condition.rule 更改为:

    RF_cmdPropRx.condition.rule = COND_STOP_ON_TRUE;

    无线电仅 在 RX 超时后才会进入 TX。 在 接收到数据包的情况下、链将停止:

    Siri

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Siri:

    感谢您的支持。 我能够使链命令在两个器件 (TX→RX 和 RX→TX) 之间正常工作。 如您所见、主器件(上部)和从器件(下部)现在与连接间隔和时序完全同步。



    我的下一个要求是在每个连接间隔内运行多个链命令。 我扩展了当前设置、以便在单个链式命令中发送两对 TX→RX 和 RX→TX 事务。 但是、只有第一对有效。 我看不到第二个事务发生、甚至没有尝试。

    static int radio_start_tx_rx_chain(void) {
        /* Reset commands */
        RF_cmdPropTx.status = 0;
        RF_cmdPropRx.status = 0;
        RF_cmdPropTx2.status = 0;
        RF_cmdPropRx2.status = 0;
    
        /* First TX */
        RF_cmdPropTx.commandNo = CMD_PROP_TX;
        RF_cmdPropTx.pPkt = g_radio.current_op.tx_data;
        RF_cmdPropTx.pktLen = g_radio.current_op.tx_length;
        RF_cmdPropTx.startTrigger.triggerType = TRIG_NOW;
        RF_cmdPropTx.pNextOp = (rfc_radioOp_t*)&RF_cmdPropRx;
        RF_cmdPropTx.condition.rule = COND_ALWAYS;
    
        /* First RX - configure to not stop on packet */
        RF_cmdPropRx.commandNo = CMD_PROP_RX;
        RF_cmdPropRx.pQueue = &g_radio.rx_data_queue;
        RF_cmdPropRx.maxPktLen = RADIO_MAX_PACKET_LEN;
        RF_cmdPropRx.startTrigger.triggerType = TRIG_REL_PREVEND;
        RF_cmdPropRx.startTime = RF_convertUsToRatTicks(g_radio.current_op.turnaround_time_us);
        RF_cmdPropRx.endTrigger.triggerType = TRIG_REL_START;
        RF_cmdPropRx.endTime = RF_convertMsToRatTicks(g_radio.current_op.rx_timeout_ms);
        RF_cmdPropRx.pktConf.bRepeatOk = 1;
        RF_cmdPropRx.pktConf.bRepeatNok = 1;
        RF_cmdPropRx.pNextOp = (rfc_radioOp_t*)&RF_cmdPropTx2;
        RF_cmdPropRx.condition.rule = COND_ALWAYS;
    
        /* Second TX - use relative timing */
        RF_cmdPropTx2.commandNo = CMD_PROP_TX;
        RF_cmdPropTx2.pPkt = g_radio.current_op.tx_data;
        RF_cmdPropTx2.pktLen = g_radio.current_op.tx_length;
        RF_cmdPropTx2.startTrigger.triggerType = TRIG_REL_PREVEND;
        RF_cmdPropTx2.startTime = RF_convertUsToRatTicks(g_radio.current_op.turnaround_time_us);
        RF_cmdPropTx2.pNextOp = (rfc_radioOp_t*)&RF_cmdPropRx2;
        RF_cmdPropTx2.condition.rule = COND_ALWAYS;
    
        /* Second RX */
        RF_cmdPropRx2.commandNo = CMD_PROP_RX;
        RF_cmdPropRx2.pQueue = &g_radio.rx_data_queue;
        RF_cmdPropRx2.maxPktLen = RADIO_MAX_PACKET_LEN;
        RF_cmdPropRx2.startTrigger.triggerType = TRIG_REL_PREVEND;
        RF_cmdPropRx2.startTime = RF_convertUsToRatTicks(g_radio.current_op.turnaround_time_us);
        RF_cmdPropRx2.endTrigger.triggerType = TRIG_REL_START;
        RF_cmdPropRx2.endTime = RF_convertMsToRatTicks(g_radio.current_op.rx_timeout_ms);
        RF_cmdPropRx2.pNextOp = NULL;
        RF_cmdPropRx2.condition.rule = COND_NEVER;
    
        /* Post the chain */
        g_radio.cmd_handle = RF_postCmd(g_radio.rf_handle,
                                        (RF_Op*)&RF_cmdPropTx,
                                        RF_PriorityNormal,
                                        radio_rf_callback,
                                        RF_EventRxEntryDone | RF_EventLastCmdDone);
    
        return (g_radio.cmd_handle >= 0) ? 0 : -1;
    }



    static int radio_start_rx_tx_chain(void) {
        /* Reset commands */
        RF_cmdPropTx.status = 0;
        RF_cmdPropRx.status = 0;
        RF_cmdPropTx2.status = 0;
        RF_cmdPropRx2.status = 0;
    
        /* Create second command set */
        memcpy(&RF_cmdPropRx2, &RF_cmdPropRx, sizeof(RF_cmdPropRx));
        memcpy(&RF_cmdPropTx2, &RF_cmdPropTx, sizeof(RF_cmdPropTx));
    
        /* First RX */
        RF_cmdPropRx.commandNo = CMD_PROP_RX;
        RF_cmdPropRx.pQueue = &g_radio.rx_data_queue;
        RF_cmdPropRx.maxPktLen = RADIO_MAX_PACKET_LEN;
        RF_cmdPropRx.startTrigger.triggerType = TRIG_NOW;
        RF_cmdPropRx.startTrigger.pastTrig = 1;
        RF_cmdPropRx.endTrigger.triggerType = TRIG_REL_START;
        RF_cmdPropRx.endTime = RF_convertMsToRatTicks(g_radio.current_op.rx_timeout_ms);
        RF_cmdPropRx.pktConf.bRepeatOk = 1;
        RF_cmdPropRx.pktConf.bRepeatNok = 1;
        RF_cmdPropRx.pNextOp = (rfc_radioOp_t*)&RF_cmdPropTx;
        RF_cmdPropRx.condition.rule = COND_ALWAYS;
    
        /* First TX response */
        memcpy(g_radio.tx_packet, g_radio.current_op.tx_data, g_radio.current_op.tx_length);
        RF_cmdPropTx.commandNo = CMD_PROP_TX;
        RF_cmdPropTx.pPkt = g_radio.tx_packet;
        RF_cmdPropTx.pktLen = g_radio.current_op.tx_length;
        RF_cmdPropTx.startTrigger.triggerType = TRIG_REL_PREVEND;
        RF_cmdPropTx.startTrigger.pastTrig = 1;
        RF_cmdPropTx.startTime = RF_convertUsToRatTicks(g_radio.current_op.turnaround_time_us);
        RF_cmdPropTx.pNextOp = (rfc_radioOp_t*)&RF_cmdPropRx2;
        RF_cmdPropTx.condition.rule = COND_ALWAYS;
    
        /* Second RX */
        RF_cmdPropRx2.commandNo = CMD_PROP_RX;
        RF_cmdPropRx2.pQueue = &g_radio.rx_data_queue;
        RF_cmdPropRx2.maxPktLen = RADIO_MAX_PACKET_LEN;
        RF_cmdPropRx2.startTrigger.triggerType = TRIG_REL_PREVEND;
        RF_cmdPropRx2.startTrigger.pastTrig = 1;
        RF_cmdPropRx2.startTime = RF_convertUsToRatTicks(g_radio.current_op.turnaround_time_us);
        RF_cmdPropRx2.endTrigger.triggerType = TRIG_REL_START;
        RF_cmdPropRx2.endTime = RF_convertMsToRatTicks(g_radio.current_op.rx_timeout_ms);
        RF_cmdPropRx2.pktConf.bRepeatOk = 1;
        RF_cmdPropRx2.pktConf.bRepeatNok = 1;
        RF_cmdPropRx2.pNextOp = (rfc_radioOp_t*)&RF_cmdPropTx2;
        RF_cmdPropRx2.condition.rule = COND_ALWAYS;
    
        /* Second TX response */
        RF_cmdPropTx2.commandNo = CMD_PROP_TX;
        RF_cmdPropTx2.pPkt = g_radio.tx_packet;
        RF_cmdPropTx2.pktLen = g_radio.current_op.tx_length;
        RF_cmdPropTx2.startTrigger.triggerType = TRIG_REL_PREVEND;
        RF_cmdPropTx2.startTrigger.pastTrig = 1;
        RF_cmdPropTx2.startTime = RF_convertUsToRatTicks(g_radio.current_op.turnaround_time_us);
        RF_cmdPropTx2.pNextOp = NULL;
        RF_cmdPropTx2.condition.rule = COND_NEVER;
    
        /* Post chain starting with RX */
        g_radio.cmd_handle = RF_postCmd(g_radio.rf_handle,
                                        (RF_Op*)&RF_cmdPropRx,
                                        RF_PriorityNormal,
                                        radio_rf_callback,
                                        RF_EventRxEntryDone | RF_EventTxDone | RF_EventLastCmdDone);
    
        return (g_radio.cmd_handle >= 0) ? 0 : -1;
    }



    /* Use RFQueue for multiple data entries */
    #define NUM_DATA_ENTRIES    4
    #define MAX_PACKET_LENGTH   255
    #define NUM_APPENDED_BYTES  2


    能否请您核对一下我是否遗漏了信息? 任何参考或实施示例都会大大加快我的练习。

    谢谢、
    Sharan

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    在我尝试实现此功能之前、您应该将代码更改为不使用重复模式。  

    将重复模式设置为 1 表示 您将在接收到数据包后立即重新启动 RX 命令、这样 RX 将永远不会完成(由于接收到数据包)、并且您不会运行下一个 TX。

    如果 RX 超时、它应进入 TX2。

    请修复此问题并重试、然后告诉我结果。

    Siri

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我使用bRepeatOk = 0和进行bRepeatNok = 0了测试、但链中的第二对仍然没有通过。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、

    感谢上一个示例。 将对讲机活动映射到 IOS 是一个很好的主意、它给了我一些关于正在发生的事情的提示。 我在每个连接间隔看到两个脉冲。 这是否确认正在执行两个链接操作? 我仍需要微调时序对齐、我正在尝试更清楚地解释脉冲。 任何指针都将非常有用、因为我仍然不熟悉 TI 的无线电芯片:)


    第一张图片:主设备

    • Channel0:CONFIG_GPIO_RLED

    • 通道 1:CONFIG_GPIO_GLED





    第二张图片:主设备和从设备

    • Channel0(主器件):CONFIG_GPIO_RLED

    • 通道 1(从器件):CONFIG_GPIO_RLED




  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我做了一些进一步的测试、第二个 TX-RX 似乎无法正常工作。 从示波器布线中、第二个 TX-RX 对(设置方式与第一个相同)及时对齐、但 RX 似乎超时。

    我附上了 Saleae 日志以供您参考。

    • D0–主器件 GLED (7)

    • D1–主器件 RLED (6)

    • D2–从器件 GLED (7)

    • D3–从器件 RLED (6)


        GPIO_setConfigAndMux(CONFIG_GPIO_RLED, GPIO_CFG_OUT_STD, IOC_PORT_RFC_GPO0);
        GPIO_setConfigAndMux(CONFIG_GPIO_GLED, GPIO_CFG_OUT_STD, IOC_PORT_RFC_GPO1);






    e2e.ti.com/.../capture.sal.zip



     
    static int radio_start_conn_master_chain(void) {
        /* Reset commands */
        RF_cmdPropTx.status = 0;
        RF_cmdPropRx.status = 0;
        RF_cmdPropTx2.status = 0;
        RF_cmdPropRx2.status = 0;
    
        /* First TX */
        RF_cmdPropTx.commandNo = CMD_PROP_TX;
        RF_cmdPropTx.pPkt = g_radio.current_op.tx_data;
        RF_cmdPropTx.pktLen = g_radio.current_op.tx_length;
        RF_cmdPropTx.startTrigger.triggerType = TRIG_NOW;
        RF_cmdPropTx.pNextOp = (rfc_radioOp_t*)&RF_cmdPropRx;
        RF_cmdPropTx.condition.rule = COND_ALWAYS;
    
        /* First RX - configure to not stop on packet */
        RF_cmdPropRx.commandNo = CMD_PROP_RX;
        RF_cmdPropRx.pQueue = &g_radio.rx_data_queue;
        RF_cmdPropRx.maxPktLen = RADIO_MAX_PACKET_LEN;
        RF_cmdPropRx.startTrigger.triggerType = TRIG_REL_PREVEND;
        RF_cmdPropRx.startTime =  RF_convertUsToRatTicks(g_radio.current_op.turnaround_time_us);
        RF_cmdPropRx.endTrigger.triggerType = TRIG_REL_START;
        RF_cmdPropRx.endTime = RF_convertMsToRatTicks(g_radio.current_op.rx_timeout_ms);
        RF_cmdPropRx.pktConf.bRepeatOk = 0;
        RF_cmdPropRx.pktConf.bRepeatNok = 0;
        RF_cmdPropRx.pNextOp = (rfc_radioOp_t*)&RF_cmdPropTx2;
        RF_cmdPropRx.condition.rule = COND_ALWAYS;
    
        /* Second TX - use relative timing */
        RF_cmdPropTx2.commandNo = CMD_PROP_TX;
        RF_cmdPropTx2.pPkt = g_radio.current_op.tx_data;
        RF_cmdPropTx2.pktLen = g_radio.current_op.tx_length;
        RF_cmdPropTx2.startTrigger.triggerType = TRIG_REL_PREVEND;
        RF_cmdPropTx2.startTime = RF_convertUsToRatTicks(g_radio.current_op.turnaround_time_us);
        RF_cmdPropTx2.pNextOp = (rfc_radioOp_t*)&RF_cmdPropRx2;
        RF_cmdPropTx2.condition.rule = COND_ALWAYS;
    
        /* Second RX */
        RF_cmdPropRx2.commandNo = CMD_PROP_RX;
        RF_cmdPropRx2.pQueue = &g_radio.rx_data_queue;
        RF_cmdPropRx2.maxPktLen = RADIO_MAX_PACKET_LEN;
        RF_cmdPropRx2.startTrigger.triggerType = TRIG_REL_PREVEND;
        RF_cmdPropRx2.startTime = RF_convertUsToRatTicks(g_radio.current_op.turnaround_time_us);
        RF_cmdPropRx2.endTrigger.triggerType = TRIG_REL_START;
        RF_cmdPropRx2.endTime =  RF_convertMsToRatTicks(g_radio.current_op.rx_timeout_ms);
        RF_cmdPropRx2.pNextOp = NULL;
        RF_cmdPropRx2.condition.rule = COND_NEVER;
    
        /* Post the chain */
        g_radio.cmd_handle = RF_postCmd(g_radio.rf_handle,
                                        (RF_Op*)&RF_cmdPropTx,
                                        RF_PriorityNormal,
                                        radio_rf_callback,
                                        RF_EventRxEntryDone | RF_EventLastCmdDone);
    
        return (g_radio.cmd_handle >= 0) ? 0 : -1;
    }
    
    static int radio_start_rx_tx_chain(void) {
        /* Reset commands */
        RF_cmdPropTx.status = 0;
        RF_cmdPropRx.status = 0;
        RF_cmdPropTx2.status = 0;
        RF_cmdPropRx2.status = 0;
    
        /* Create second command set */
        memcpy(&RF_cmdPropRx2, &RF_cmdPropRx, sizeof(RF_cmdPropRx));
        memcpy(&RF_cmdPropTx2, &RF_cmdPropTx, sizeof(RF_cmdPropTx));
    
        /* First RX */
        RF_cmdPropRx.commandNo = CMD_PROP_RX;
        RF_cmdPropRx.pQueue = &g_radio.rx_data_queue;
        RF_cmdPropRx.maxPktLen = RADIO_MAX_PACKET_LEN;
        RF_cmdPropRx.startTrigger.triggerType = TRIG_NOW;
        RF_cmdPropRx.startTrigger.pastTrig = 1;
        RF_cmdPropRx.endTrigger.triggerType = TRIG_REL_START;
        RF_cmdPropRx.endTime = RF_convertMsToRatTicks(g_radio.current_op.rx_timeout_ms);
        RF_cmdPropRx.pktConf.bRepeatOk = 0;
        RF_cmdPropRx.pktConf.bRepeatNok = 0;
        RF_cmdPropRx.pNextOp = (rfc_radioOp_t*)&RF_cmdPropTx;
        RF_cmdPropRx.condition.rule = COND_ALWAYS;
    
        /* First TX response */
        memcpy(g_radio.tx_packet, g_radio.current_op.tx_data, g_radio.current_op.tx_length);
        RF_cmdPropTx.commandNo = CMD_PROP_TX;
        RF_cmdPropTx.pPkt = g_radio.tx_packet;
        RF_cmdPropTx.pktLen = g_radio.current_op.tx_length;
        RF_cmdPropTx.startTrigger.triggerType = TRIG_REL_PREVEND;
        RF_cmdPropTx.startTrigger.pastTrig = 1;
        RF_cmdPropTx.startTime = RF_convertUsToRatTicks(g_radio.current_op.turnaround_time_us);
        RF_cmdPropTx.pNextOp = (rfc_radioOp_t*)&RF_cmdPropRx2;
        RF_cmdPropTx.condition.rule = COND_ALWAYS;
    
        /* Second RX */
        RF_cmdPropRx2.commandNo = CMD_PROP_RX;
        RF_cmdPropRx2.pQueue = &g_radio.rx_data_queue;
        RF_cmdPropRx2.maxPktLen = RADIO_MAX_PACKET_LEN;
        RF_cmdPropRx2.startTrigger.triggerType = TRIG_REL_PREVEND;
        RF_cmdPropRx2.startTrigger.pastTrig = 1;
        RF_cmdPropRx2.startTime = RF_convertUsToRatTicks(g_radio.current_op.turnaround_time_us);
        RF_cmdPropRx2.endTrigger.triggerType = TRIG_REL_START;
        RF_cmdPropRx2.endTime = 4000;//RF_convertMsToRatTicks(g_radio.current_op.rx_timeout_ms);
        RF_cmdPropRx2.pktConf.bRepeatOk = 0;
        RF_cmdPropRx2.pktConf.bRepeatNok = 0;
        RF_cmdPropRx2.pNextOp = (rfc_radioOp_t*)&RF_cmdPropTx2;
        RF_cmdPropRx2.condition.rule = COND_ALWAYS;
    
        /* Second TX response */
        RF_cmdPropTx2.commandNo = CMD_PROP_TX;
        RF_cmdPropTx2.pPkt = g_radio.tx_packet;
        RF_cmdPropTx2.pktLen = g_radio.current_op.tx_length;
        RF_cmdPropTx2.startTrigger.triggerType = TRIG_REL_PREVEND;
        RF_cmdPropTx2.startTrigger.pastTrig = 1;
        RF_cmdPropTx2.startTime = RF_convertUsToRatTicks(g_radio.current_op.turnaround_time_us);
        RF_cmdPropTx2.pNextOp = NULL;
        RF_cmdPropTx2.condition.rule = COND_NEVER;
    
        /* Post chain starting with RX */
        g_radio.cmd_handle = RF_postCmd(g_radio.rf_handle,
                                        (RF_Op*)&RF_cmdPropRx,
                                        RF_PriorityNormal,
                                        radio_rf_callback,
                                        RF_EventRxEntryDone | RF_EventTxDone | RF_EventLastCmdDone);
    
        return (g_radio.cmd_handle >= 0) ? 0 : -1;
    }

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    不确定具体内容。

    我提供的两个测试代码按预期工作。 它们的目的是展示链接是如何完成的、并让链运行所有命令。

    我没有缩进提供一个示例、您可以在一个器件上运行 TX-RX-TX-RX 链、在另一个器件上运行 RX-TX-RX-TX、然后使它们对齐。

    这是你要做的事吗? 如果是、我得让您根据您用于应用的数据速率、数据包长度等来正确配置时序。

    Siri