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.

[参考译文] CC1310:无法接收长整型(>250字节) WMBUS 数据包和 RF_runImmediateCmd CMD_PROP_SET_LEN 返回 RF_StatCmdDoneError

Guru**** 1101410 points
Other Parts Discussed in Thread: CC1310, WMBUS
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/1333553/cc1310-fail-to-receive-long-250-bytes-wmbus-packets-and-rf_runimmediatecmd-cmd_prop_set_len-return-rf_statcmddoneerror

器件型号:CC1310
主题中讨论的其他器件: WMBUS

大家好!

我已经在 CC1310上实施了"标准本书"(我认为)无线 MBUS 接收器应用、并查看 SWRA522E 文档参考(https://www.ti.com/lit/an/swra522e/swra522e.pdf)。

在接收第一个带数据的回调时、我们提取数据包长度、并针对不同的数据包格式和 MBUS 模式解析 CRC、然后按照伪代码的建议执行操作;

-"使用长度信息通过 CMD_PROP_SET_LEN"设置正确的长度。

不过、我们刚刚意识到我们无法接收更大的数据包(格式 A 中的数据约为250字节、因此大量的 CRC 意味着我需要接收超过280字节、然后才能验证整个数据包的 CRC)。 事实证明、当我请求设置长度时、返回 RF_Stat 表示我们失败了;

RF_runImmediateCmd (rfHandle、(uint32_t*)和 RF_cmdPropSetLen)--> RF_StatCmdDoneError

我们不使用 RX 监听、我意识到对于小型和大型数据包、RF_Stat 都是相同的、但我们从未见过/想过、因为我们无论如何都会得到数据包。 但显然不适用于较大的数据包。  

我怀疑我的配置有问题、但我无法理解原因/位置/什么。

如果需要的话,我很乐意设置代码一次接收 N 个字节,直到我有了完整的软件包,然后中止 RX 和"我已经完成"这个软件包-- 但我对 CC1310射频结构以及如何设置这样的代码基础的知识和诀窍知之甚少。 是否有任何可以作为 CC1310基础的 WMBUS 数据示例/教程?  

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

    尊敬的 Markus:

    我假设当> 255时 CMD_PROP_SET_LEN 将失败、因为参数只有一个字节长:

    此外、以下是技术参考手册中的一些更多详细信息:

    此致、

    亚瑟

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

    啊,有趣! 我刚刚继承了我使用的代码库、CMD_PROP_SET_LEN 结构中的长度参数是 uint16… 这实际上解释了为什么_all_设置长度的请求失败(我猜内部大小会立即使我的请求无效)。  

    尽管如此、我仍然需要能够 RX 长度为250字节的 WMBUS 数据包、格式 A 中包含相当多的 CRC 字、每16字节数据。 因此、我需要能够接收超过255字节的"原始"数据。 我想这意味着我需要寻找设置 RX 代码的替代方法? 我读过有人提到一次可以接收(并处理) N 个字节数据的10字节迭代 RX 过程、直到我知道我已经完成、然后我就结束了 RX 过程并重新开始(以接收其他数据包)? 这听起来像一个可能的方式进行,或者你是否有任何其他提示/Trix/建议如何做我需要做什么?  

    谢谢。

    /马库斯

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

    尊敬的 Markus:

    我想你可能在谈论部分阅读条目,如果我没有错?

    至于一次性接收更大的数据包、CMD_PROP_RX_ADV 是理想之选、但正如您所说的、您没有使用它、有没有理由不使用它?

    此致、


    亚瑟

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

    啊,好吧,这一切都归结到我不确定我能做什么/应该做什么,以及可能在那里的任何限制。 但是的、如果我可以使用 ADV 执行读取、并允许我接收更大的数据块、我很乐意这样做。  

    我想对于 RX_ADV 使用无限 RX 的过程是相同的、但我需要设置计算长度、我需要使用不同的结构/CMD 来进行读取?  

    抱歉混淆了—我没有使用 CC1310和 TI 射频结构的经验、但非常感谢您提供任何指导:)

    此致!

    /马库斯

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

    从本质上讲、文档的这一部分就是我想要做的事情。 只是为了方便背景。  

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

    啊、是的、我现在看到 CMD_PROP_SET_LEN 的来源。

    似乎我的同事在这里解释了这个过程、尽管它适用于 ZWave: https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/1295007/cc1352p7-partial-entry-mode-with-repeats-setting-new-packet-length

    另外、

    https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/1321678/cc1310-wireless-m-bus-back-to-back-rx/5037757#5037757

    如果您有更多问题、请告诉我。

    此致、

    亚瑟

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

    SET_LEN 命令支持16位长度的字节、如上一个帖子中的图所示(字节索引0和1)。

    下面的代码针对16位长度进行了测试。 该测试未使用 wmbus 数据包格式进行测试、但显示了 SET_LEN 命令应正常工作。

    // 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>
    
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Semaphore.h>
    
    // CMD_PROP_SET_LEN
    rfc_CMD_PROP_SET_LEN_t RF_cmdPropSetLen =
    {
       .commandNo = 0x3401,
       .rxLen = 0x0000,
    };
    
    // Defines
    
    // Packet RX Configuration
    //  ------------------------------------------------------------------------------------------------------------------------
    //  | DATA_ENTRY_HEADER (12 bytes) | H0 | H1 | H2 | H3 | Length N (1 or 2 Bytes)| D0 | D1 | D2 | .. | .. | D(N-2) | D(N-1) |
    //  ------------------------------------------------------------------------------------------------------------------------
    
    // Optional appended bytes
    //  -------------------------------------------------------
    //  | CRC1 | CRC0 | RSSI | TS0 | TS1 | TS2 | TS3 | Status |
    //  -------------------------------------------------------
    #define DATA_ENTRY_HEADER_SIZE  12                  // Constant header size of a Partial Data Entry
    #define MAX_LENGTH              300                 // Max length byte the application will accept
    #define PACKET_HEADER_SIZE      4                   // Bytes in packet before location of the length byte
    #define LENGTH_FIELD_INDEX      PACKET_HEADER_SIZE  // Position of length byte (after sync)
    #define LENGTH_FIELD_SIZE       2                   // Can be 1 or 2
    #define NUM_APPENDED_BYTES      0                   // .rxConf.bIncludeCrc = 0x1;       // 2 bytes (if default CRC is used)
                                                        // .rxConf.bAppendRssi = 0x1;       // 1 byte
                                                        // .rxConf.bAppendTimestamp = 0x1;  // 4 bytes
                                                        // .rxConf.bAppendStatus = 0x1;     // 1 byte
    // Prototypes
    static void callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e);
    
    // Variable declarations
    static RF_Object rfObject;
    static RF_Handle rfHandle;
    static RF_CmdHandle rxHandle;
    
    // Receive dataQueue for RF Core to fill in data
    static dataQueue_t dataQueue;
    
    #if defined(__TI_COMPILER_VERSION__)
    #pragma DATA_ALIGN (rxDataEntryBuf0, 4);
    static uint8_t rxDataEntryBuf0[DATA_ENTRY_HEADER_SIZE + MAX_LENGTH + LENGTH_POSITION - + NUM_APPENDED_BYTES];
    #pragma DATA_ALIGN (rxDataEntryBuf1, 4);
    static uint8_t rxDataEntryBuf1[DATA_ENTRY_HEADER_SIZE + MAX_LENGTH + LENGTH_POSITION - + NUM_APPENDED_BYTES];
    
    #elif defined(__IAR_SYSTEMS_ICC__)
    #pragma data_alignment = 4
    static uint8_t rxDataEntryBuf0[DATA_ENTRY_HEADER_SIZE + MAX_LENGTH + LENGTH_POSITION + NUM_APPENDED_BYTES];
    #pragma data_alignment = 4
    static uint8_t rxDataEntryBuf1[DATA_ENTRY_HEADER_SIZE + MAX_LENGTH + LENGTH_POSITION + NUM_APPENDED_BYTES];
    
    #elif defined(__GNUC__)
    static uint8_t rxDataEntryBuf0[DATA_ENTRY_HEADER_SIZE + PACKET_HEADER_SIZE + LENGTH_FIELD_SIZE + MAX_LENGTH + NUM_APPENDED_BYTES] __attribute__((aligned(4)));
    static uint8_t rxDataEntryBuf1[DATA_ENTRY_HEADER_SIZE + PACKET_HEADER_SIZE + LENGTH_FIELD_SIZE + 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 uint16_t payloadLength;
    
    
    rfc_dataEntryPartial_t* partialReadEntry0 = (rfc_dataEntryPartial_t*)&rxDataEntryBuf0;
    rfc_dataEntryPartial_t* partialReadEntry1 = (rfc_dataEntryPartial_t*)&rxDataEntryBuf1;
    rfc_dataEntryPartial_t* currentReadEntry = (rfc_dataEntryPartial_t*)&rxDataEntryBuf0;
    
    rfc_propRxOutput_t rxStatistics;
    static uint8_t lengthWritten = false;
    static uint8_t cancelRx = false;
    RF_Stat status = 0xFF;
    
    // RX Semaphore
    static Semaphore_Struct rxSemaphore;
    static Semaphore_Handle rxSemaphoreHandle;
    
    uint8_t packetHeader[PACKET_HEADER_SIZE];
    uint8_t packetPayload[LENGTH_FIELD_SIZE + MAX_LENGTH];
    uint8_t packetStatusBytes[NUM_APPENDED_BYTES];
    
    // Debug
    uint8_t eventNDataWritten = 0;
    uint8_t eventRxOk = 0;
    uint8_t eventCmdAborted = 0;
    uint8_t eventRxBufFull = 0;
    uint8_t eventRxEntryDone = 0;
    uint8_t eventDataWritten = 0;
    uint8_t eventRxAborted = 0;
    uint8_t eventMdmSoft = 0;
    uint8_t eventLastCmdDone = 0;
    uint8_t dummy = 0;
    
    
    // Function definitions
    
    void *mainThread(void *arg0)
    {
        RF_Params rfParams;
        RF_Params_init(&rfParams);
    
        GPIO_setConfig(CONFIG_GPIO_RLED, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
        GPIO_write(CONFIG_GPIO_RLED, CONFIG_GPIO_LED_OFF);
    
        /* Initialize RX semaphore */
        Semaphore_construct(&rxSemaphore, 0, NULL);
        rxSemaphoreHandle = Semaphore_handle(&rxSemaphore);
    
        partialReadEntry0->length = PACKET_HEADER_SIZE + LENGTH_FIELD_SIZE + MAX_LENGTH + NUM_APPENDED_BYTES + 4;   // Make sure there is enough room for a complete packet in one data entry.
                                                                                                                    // Number of bytes following this length field
                                                                                                                    // + 4 is to make room for the pktStatus (2 bytes) and nextIndex (2 bytes)
        partialReadEntry0->config.irqIntv = PACKET_HEADER_SIZE + LENGTH_FIELD_SIZE;
        partialReadEntry0->config.type = DATA_ENTRY_TYPE_PARTIAL;
        partialReadEntry0->status = DATA_ENTRY_PENDING;
    
        partialReadEntry1->length = PACKET_HEADER_SIZE + LENGTH_FIELD_SIZE + MAX_LENGTH + NUM_APPENDED_BYTES + 4;  // Make sure there is enough room for a complete packet in one data entry.
                                                                                                                   // Number of bytes following this length field
                                                                                                                   // + 4 is to make room for the pktStatus (2 bytes) and nextIndex (2 bytes)
        partialReadEntry1->config.irqIntv = PACKET_HEADER_SIZE + LENGTH_FIELD_SIZE;
        partialReadEntry1->config.type = DATA_ENTRY_TYPE_PARTIAL;
        partialReadEntry1->status = DATA_ENTRY_PENDING;
    
        partialReadEntry0->pNextEntry = (uint8_t*)partialReadEntry1;
        partialReadEntry1->pNextEntry = (uint8_t*)partialReadEntry0;
    
        dataQueue.pCurrEntry = (uint8_t*)partialReadEntry0;
        dataQueue.pLastEntry = NULL;
    
        // Modify CMD_PROP_RX command for application needs
        RF_cmdPropRx.pQueue = &dataQueue;
        RF_cmdPropRx.pOutput = (uint8_t*)&rxStatistics;
        RF_cmdPropRx.rxConf.bIncludeHdr = 1; // Must be 1 to receive the first byte after sync in the data entry
        RF_cmdPropRx.maxPktLen = 0;          // Unlimited length
    
        RF_cmdPropRx.rxConf.bAutoFlushCrcErr = 1;
        RF_cmdPropRx.pktConf.bRepeatOk = 0;
        RF_cmdPropRx.pktConf.bRepeatNok = 0;
    
        // Optional status bytes appended AFTER the payload
        // If these are changed, NUM_APPENDED_BYTES must also be updated
        RF_cmdPropRx.rxConf.bIncludeCrc = 0x0;      // 2 byte (if default CRC is used)
        RF_cmdPropRx.rxConf.bAppendRssi = 0x0;      // 1 byte
        RF_cmdPropRx.rxConf.bAppendStatus = 0x0;    // 1 Byte
        RF_cmdPropRx.rxConf.bAppendTimestamp = 0x0; // 4 bytes
    
        // 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(true)
        {
            lengthWritten = false;
            cancelRx = false;
            status = 0xFF;
    
            eventNDataWritten = 0;
            eventRxOk = 0;
            eventCmdAborted = 0;
            eventRxBufFull = 0;
            eventRxEntryDone = 0;
            eventDataWritten = 0;
            eventRxAborted = 0;
            eventMdmSoft = 0;
            eventLastCmdDone = 0;
    
            rxHandle = RF_postCmd(rfHandle, (RF_Op*)&RF_cmdPropRx, RF_PriorityNormal, &callback, RF_EventNDataWritten |
                                                                                                 RF_EventRxOk         |
                                                                                                 RF_EventRxBufFull    |
                                                                                                 RF_EventCmdAborted   |
                                                                                                 RF_EventMdmSoft    /*|
                                                                                                 RF_EventCmdCancelled*/); //Not necessary, since this only happens if you cancel something that is not started
    
            Semaphore_pend(rxSemaphoreHandle, BIOS_WAIT_FOREVER); // Wait for cancelRx = true or RF_EventLastCmdDone
    
            if (cancelRx)
            {
                status = RF_cancelCmd(rfHandle, rxHandle, 0);
                Semaphore_pend(rxSemaphoreHandle, BIOS_WAIT_FOREVER); // Semaphore set after RF_EventCmdAborted (RF_EventLastCmdDone will not happen for RF_cancel)
            }
        }
    }
    
    void callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e)
    {
        if (e & RF_EventNDataWritten)
        {
            GPIO_toggle(CONFIG_GPIO_RLED);
            eventNDataWritten++;
    
            if (!lengthWritten)
            {
                lengthWritten = true;
    
                if(LENGTH_FIELD_SIZE == 2)
                {
                    payloadLength = (uint16_t)(((*(uint8_t*)(&currentReadEntry->rxData + LENGTH_FIELD_INDEX)) << 8) +
                                                (*(uint8_t*)(&currentReadEntry->rxData + LENGTH_FIELD_INDEX + 1)));
                }
                else
                {
                    payloadLength = *(uint8_t*)(&currentReadEntry->rxData + LENGTH_FIELD_INDEX);
                }
    
                if (payloadLength > MAX_LENGTH)
                {
                    cancelRx = true;
                    Semaphore_post(rxSemaphoreHandle); // This takes us to "if (cancelRx)
                }
                else
                {
                    RF_cmdPropSetLen.rxLen = payloadLength + PACKET_HEADER_SIZE + LENGTH_FIELD_SIZE - 1; // Must subtract 1 due to rxConf.bIncludeHdr = 1
                    status = RF_runImmediateCmd(rfHandle, (uint32_t*)&RF_cmdPropSetLen);
                }
            }
        }
    
        if (e & RF_EventMdmSoft)
        {
            eventMdmSoft++;
        }
    
        if (e & RF_EventRxOk)
        {
            eventRxOk++;
            memcpy(packetHeader,        (uint8_t*)(&currentReadEntry->rxData + 0                                                     ), PACKET_HEADER_SIZE);
            memcpy(packetPayload,       (uint8_t*)(&currentReadEntry->rxData + LENGTH_FIELD_INDEX                                    ), LENGTH_FIELD_SIZE + payloadLength);
            memcpy(packetStatusBytes,   (uint8_t*)(&currentReadEntry->rxData + LENGTH_FIELD_INDEX + LENGTH_FIELD_SIZE + payloadLength), NUM_APPENDED_BYTES);
        }
    
        if (e & RF_EventLastCmdDone) // When RX is done due to CMD_SET_LEN (not happening when doing RF_cancel())
        {
           eventLastCmdDone++;
           currentReadEntry->status = DATA_ENTRY_PENDING;
           currentReadEntry = (rfc_dataEntryPartial_t*)currentReadEntry->pNextEntry;
           dataQueue.pCurrEntry = (uint8_t*)currentReadEntry;
    
           Semaphore_post(rxSemaphoreHandle);
        }
    
        if (e & RF_EventCmdAborted) // happens due to RF_cancel()
        {
            eventCmdAborted++;
            currentReadEntry->status = DATA_ENTRY_PENDING;
            currentReadEntry = (rfc_dataEntryPartial_t*)currentReadEntry->pNextEntry;
            dataQueue.pCurrEntry = (uint8_t*)currentReadEntry;
    
            Semaphore_post(rxSemaphoreHandle);
        }
    
        if (e & RF_EventRxBufFull) // This will happen BEFORE the RF_EventLastCmdDone
        {
            currentReadEntry->status = DATA_ENTRY_PENDING;
            currentReadEntry = (rfc_dataEntryPartial_t*)currentReadEntry->pNextEntry;
            dataQueue.pCurrEntry = (uint8_t*)currentReadEntry;
    
            eventRxBufFull++;
        }
    }
    

    Siri

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

    谢谢! 很好的示例、具有干净、可读的结构。  

    我将在周末玩这个,看看我结束的地方,但就 WMBUS 和我正在使用的补丁;  

    • 您能否简单地确认、您的 nice 示例中的上述方法实际上是兼容的、并可以使用 WMBUS 补丁来完成?
    • 您能否确认您没有使用 CMD_PROP_RX 和_NOT_CMD_PROP_RX_ADV ? 如果是、MAX_LENGTH 大于256会让我感到困惑...? 或者、我是否可以预期使用  CMD_PROP_RX 接收286字节数据包(在我之前讲过的场景中)?
    • 我的理解是、您的示例中使用的"读取条目"本质上用作双 DMA 页、这样我就可以处理一个数据包而不会有下一个数据包覆盖的风险? 或者,您为什么  像在示例中所做的那样"链接"到 partialReadEntry0和 partialReadEntry1?

    不管怎样--谢谢你们;我觉得理解的希望和我需要达到的目标更近一点:)
    /马库斯

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

    现在、我已经重写了我自己的代码、基本上在接收到数据包后就抛出了我处理该数据包的所有内容(例如、各种业务逻辑和 WMBUS 数据处理、我想删除这些数据处理只是为了专注于数据的 RX)。  

    结果不幸的是、在 currentReadEntry 中只有255个字节的好数据后才有垃圾字节;前255个字节很好、与我发送的数据包匹配、但255个字节计数后的所有字节数与我预期的完全不同。  

    此外、 RF_runImmediateCmd (rfHandle、(uint32_t*)和 RF_cmdPropSetLen)继续返回 RF_StatCmdDoneError 。  

    我已经测试过使用 CMD_PROP_RX 和 CMD_PROP_RX_ADV、但结果是相同的。 我已经将 maxPktLen = 0设置为不受限制的长度、但仍然不走运。 其他一切都与您的示例设置 Siri 相当。 我开始怀疑我的 CMD_PROP_RX 设置有其他问题吗?

    // CMD_PROP_RX
    rfc_CMD_PROP_RX_t RF_cmdPropRxCT =
    {
        .commandNo = 0x3802,
        .status = 0x0000,
        .pNextOp = 0, // INSERT APPLICABLE POINTER: (uint8_t*)&xxx
        .startTime = 0x00000000,
        .startTrigger.triggerType = 0x0,
        .startTrigger.bEnaCmd = 0x0,
        .startTrigger.triggerNo = 0x0,
        .startTrigger.pastTrig = 0x0,
        .condition.rule = 0x1,
        .condition.nSkip = 0x0,
        .pktConf.bFsOff = 0x0,
        .pktConf.bRepeatOk = 0x0,
        .pktConf.bRepeatNok = 0x0,
        .pktConf.bUseCrc = 0x0,
        .pktConf.bVarLen = 0x0,
        .pktConf.bChkAddress = 0x0,
        .pktConf.endType = 0x0,
        .pktConf.filterOp = 0x0,
        .rxConf.bAutoFlushIgnored = 0x0,
        .rxConf.bAutoFlushCrcErr = 0x0,
        .rxConf.bIncludeHdr = 0x0,
        .rxConf.bIncludeCrc = 0x0,
        .rxConf.bAppendRssi = 0x0,//0x1,
        .rxConf.bAppendTimestamp = 0x0,
        .rxConf.bAppendStatus = 0x0,
        .syncWord = 0x0000543D,
        .maxPktLen = 0x0, // MAKE SURE DATA ENTRY IS LARGE ENOUGH
        .address0 = 0xAA,
        .address1 = 0xBB,
        .endTrigger.triggerType = 0x1,
        .endTrigger.bEnaCmd = 0x0,
        .endTrigger.triggerNo = 0x0,
        .endTrigger.pastTrig = 0x0,
        .endTime = 0x00000000,
        .pQueue = 0, // INSERT APPLICABLE POINTER: (dataQueue_t*)&xxx
        .pOutput = 0, // INSERT APPLICABLE POINTER: (uint8_t*)&xxx
    };
    

    为了背景;我正在尝试接收长度为250字节的格式 A 编码的 C/T 模式数据包。 但是、由于格式 A、它们最终超过256字节、这是因为注入了16位 CRC 以及很少的位置。。。 我认为我想接收的"无线"总数据包为 285字节(对于一个250字节的格式 A 数据包)(LLA 标头中的 L 字段为250)。

    我曾尝试使用 SWRA522E 文档/示例的 TI 示例中的 smartrf_settings.c、但仍然是相同的结果;我仅获得前255个字节是不够的、因为原始数据包带 CRC 更长(即使解码/归一化 WMBUS 数据包将为250个字节(+1 L 字段)。

    如果这种接收数据的方法不起作用(例如、由于  RF_runImmediateCmd 不起作用并返回2)、 我想是否有人能帮助我了解如何设置接收器循环、在该循环中、我可以 解析并持续跟踪我何时接收到整个数据、然后手动清理并重新启动更多数据包的 RX。 我想我已经从你的 Siri 那里读到了一些关于这一点的信息,但我无法找到一个解决方案,并为我的设置"触发"这种行为。  

    非常感谢您的任何见解。

    谢谢。
    /马库斯

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

    Siri & Arthur、

    现在我唯一的结论是、在使用 SWRA522E 并按照这些示例运行时、  

    • 如果我使用 CMD_PROP_RX 或 RX_ADV...也没关系...
    • ...在同步字后、我总是得到最大255字节的数据

    WMBUS 补丁实际上限制为255字节、因而 CC1310不能用于接收超过255字节的格式 A 编码 WMBUS 数据包"原始编码数据、包括 CRC "。 在本例中、LLA 标头中的 L 字段为0xFA (250字节)。

    有没有其他方法可以尝试设置 RX 进程以提取整个数据包? 如果我只能获得数据包,如果需要的话,我可以缓冲解析标头,然后确定编码,然后知道我的数据包何时被完全接收——我不需要使用"花哨"  SET_LEN-Approach (因为它似乎不起作用?)。

    谢谢。
    /马库斯

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

    很遗憾、我无法为您提供确切的 wmbus 格式、因为这不是开放标准、TI 无法在此处发布任何显示数据包格式的内容。

    我已经在 CC1310上测试了代码、代码和设置如下所示。

    // Parameter summary
    // Address: 0 
    // Address0: 0xAA 
    // Address1: 0xBB 
    // Frequency: 868.00000 MHz
    // Data Format: Serial mode disable 
    // Deviation: 25.000 kHz
    // pktLen: 30 
    // 802.15.4g Mode: 0 
    // Select bit order to transmit PSDU octets:: 1 
    // Packet Length Config: Variable 
    // Max Packet Length: 255 
    // Packet Length: 30 
    // Packet Data: 255 
    // RX Filter BW: 98 kHz
    // Symbol Rate: 50.00000 kBaud
    // Sync Word Length: 32 Bits 
    // TX Power: 14 dBm (requires define CCFG_FORCE_VDDR_HH = 1 in ccfg.c, see CC13xx/CC26xx Technical Reference Manual)
    // Whitening: No whitening 
    
    
    #include <ti/devices/DeviceFamily.h>
    #include DeviceFamily_constructPath(driverlib/rf_mailbox.h)
    #include DeviceFamily_constructPath(driverlib/rf_common_cmd.h)
    #include DeviceFamily_constructPath(driverlib/rf_prop_cmd.h)
    #include <ti/drivers/rf/RF.h>
    #include DeviceFamily_constructPath(rf_patches/rf_patch_cpe_genfsk.h)
    #include DeviceFamily_constructPath(rf_patches/rf_patch_rfe_genfsk.h)
    #include "smartrf_settings.h"
    
    
    // TI-RTOS RF Mode Object
    RF_Mode RF_prop =
    {
        .rfMode = RF_MODE_PROPRIETARY_SUB_1,
        .cpePatchFxn = &rf_patch_cpe_genfsk,
        .mcePatchFxn = 0,
        .rfePatchFxn = &rf_patch_rfe_genfsk,
    };
    
    // Overrides for CMD_PROP_RADIO_DIV_SETUP
    uint32_t pOverrides[] =
    {
        // override_use_patch_prop_genfsk.xml
        // PHY: Use MCE ROM bank 4, RFE RAM patch
        MCE_RFE_OVERRIDE(0,4,0,1,0,0),
        // override_synth_prop_863_930_div5.xml
        // Synth: Set recommended RTRIM to 7
        HW_REG_OVERRIDE(0x4038,0x0037),
        // Synth: Set Fref to 4 MHz
        (uint32_t)0x000684A3,
        // Synth: Configure fine calibration setting
        HW_REG_OVERRIDE(0x4020,0x7F00),
        // Synth: Configure fine calibration setting
        HW_REG_OVERRIDE(0x4064,0x0040),
        // Synth: Configure fine calibration setting
        (uint32_t)0xB1070503,
        // Synth: Configure fine calibration setting
        (uint32_t)0x05330523,
        // Synth: Set loop bandwidth after lock to 20 kHz
        (uint32_t)0x0A480583,
        // Synth: Set loop bandwidth after lock to 20 kHz
        (uint32_t)0x7AB80603,
        // Synth: Configure VCO LDO (in ADI1, set VCOLDOCFG=0x9F to use voltage input reference)
        ADI_REG_OVERRIDE(1,4,0x9F),
        // Synth: Configure synth LDO (in ADI1, set SLDOCTL0.COMP_CAP=1)
        ADI_HALFREG_OVERRIDE(1,7,0x4,0x4),
        // Synth: Use 24 MHz XOSC as synth clock, enable extra PLL filtering
        (uint32_t)0x02010403,
        // Synth: Configure extra PLL filtering
        (uint32_t)0x00108463,
        // Synth: Increase synth programming timeout (0x04B0 RAT ticks = 300 us)
        (uint32_t)0x04B00243,
        // override_phy_rx_aaf_bw_0xd.xml
        // Rx: Set anti-aliasing filter bandwidth to 0xD (in ADI0, set IFAMPCTL3[7:4]=0xD)
        ADI_HALFREG_OVERRIDE(0,61,0xF,0xD),
        // override_phy_gfsk_rx.xml
        // Rx: Set LNA bias current trim offset to 3
        (uint32_t)0x00038883,
        // Rx: Freeze RSSI on sync found event
        HW_REG_OVERRIDE(0x6084,0x35F1),
        // override_phy_gfsk_pa_ramp_agc_reflevel_0x1a.xml
        // Tx: Configure PA ramping setting (0x41). Rx: Set AGC reference level to 0x1A.
        HW_REG_OVERRIDE(0x6088,0x411A),
        // Tx: Configure PA ramping setting
        HW_REG_OVERRIDE(0x608C,0x8213),
        // override_phy_rx_rssi_offset_5db.xml
        // Rx: Set RSSI offset to adjust reported RSSI by +5 dB (default: 0), trimmed for external bias and differential configuration
        (uint32_t)0x00FB88A3,
    #if (CCFG_FORCE_VDDR_HH)
        // TX power override
        // Tx: Set PA trim to max (in ADI0, set PACTL0=0xF8)
        ADI_REG_OVERRIDE(0,12,0xF8),
    #endif
        (uint32_t)0xFFFFFFFF,
    };
    
    
    // CMD_PROP_RADIO_DIV_SETUP
    rfc_CMD_PROP_RADIO_DIV_SETUP_t RF_cmdPropRadioDivSetup =
    {
        .commandNo = 0x3807,
        .status = 0x0000,
        .pNextOp = 0, // INSERT APPLICABLE POINTER: (uint8_t*)&xxx
        .startTime = 0x00000000,
        .startTrigger.triggerType = 0x0,
        .startTrigger.bEnaCmd = 0x0,
        .startTrigger.triggerNo = 0x0,
        .startTrigger.pastTrig = 0x0,
        .condition.rule = 0x1,
        .condition.nSkip = 0x0,
        .modulation.modType = 0x1,
        .modulation.deviation = 0x64,
        .symbolRate.preScale = 0xF,
        .symbolRate.rateWord = 0x8000,
        .symbolRate.decimMode = 0x0,
        .rxBw = 0x24,
        .preamConf.nPreamBytes = 0x4,
        .preamConf.preamMode = 0x0,
        .formatConf.nSwBits = 0x20,
        .formatConf.bBitReversal = 0x0,
        .formatConf.bMsbFirst = 0x1,
        .formatConf.fecMode = 0x0,
        .formatConf.whitenMode = 0x0,
        .config.frontEndMode = 0x0,
        .config.biasMode = 0x1,
        .config.analogCfgMode = 0x0,
        .config.bNoFsPowerUp = 0x0,
        .txPower = 0xA73F,
        .pRegOverride = pOverrides,
        .centerFreq = 0x0364,
        .intFreq = 0x8000,
        .loDivider = 0x05,
    };
    
    // CMD_FS
    rfc_CMD_FS_t RF_cmdFs =
    {
        .commandNo = 0x0803,
        .status = 0x0000,
        .pNextOp = 0, // INSERT APPLICABLE POINTER: (uint8_t*)&xxx
        .startTime = 0x00000000,
        .startTrigger.triggerType = 0x0,
        .startTrigger.bEnaCmd = 0x0,
        .startTrigger.triggerNo = 0x0,
        .startTrigger.pastTrig = 0x0,
        .condition.rule = 0x1,
        .condition.nSkip = 0x0,
        .frequency = 0x0364,
        .fractFreq = 0x0000,
        .synthConf.bTxMode = 0x0,
        .synthConf.refFreq = 0x0,
        .__dummy0 = 0x00,
        .__dummy1 = 0x00,
        .__dummy2 = 0x00,
        .__dummy3 = 0x0000,
    };
    
    // CMD_PROP_RX
    rfc_CMD_PROP_RX_t RF_cmdPropRx =
    {
        .commandNo = 0x3802,
        .status = 0x0000,
        .pNextOp = 0, // INSERT APPLICABLE POINTER: (uint8_t*)&xxx
        .startTime = 0x00000000,
        .startTrigger.triggerType = 0x0,
        .startTrigger.bEnaCmd = 0x0,
        .startTrigger.triggerNo = 0x0,
        .startTrigger.pastTrig = 0x0,
        .condition.rule = 0x1,
        .condition.nSkip = 0x0,
        .pktConf.bFsOff = 0x0,
        .pktConf.bRepeatOk = 0x0,
        .pktConf.bRepeatNok = 0x0,
        .pktConf.bUseCrc = 0x1,
        .pktConf.bVarLen = 0x1,
        .pktConf.bChkAddress = 0x0,
        .pktConf.endType = 0x0,
        .pktConf.filterOp = 0x0,
        .rxConf.bAutoFlushIgnored = 0x0,
        .rxConf.bAutoFlushCrcErr = 0x0,
        .rxConf.bIncludeHdr = 0x1,
        .rxConf.bIncludeCrc = 0x0,
        .rxConf.bAppendRssi = 0x0,
        .rxConf.bAppendTimestamp = 0x0,
        .rxConf.bAppendStatus = 0x1,
        .syncWord = 0x930B51DE,
        .maxPktLen = 0xFF, // MAKE SURE DATA ENTRY IS LARGE ENOUGH
        .address0 = 0xAA,
        .address1 = 0xBB,
        .endTrigger.triggerType = 0x1,
        .endTrigger.bEnaCmd = 0x0,
        .endTrigger.triggerNo = 0x0,
        .endTrigger.pastTrig = 0x0,
        .endTime = 0x00000000,
        .pQueue = 0, // INSERT APPLICABLE POINTER: (dataQueue_t*)&xxx
        .pOutput = 0, // INSERT APPLICABLE POINTER: (uint8_t*)&xxx
    };
    
    .
    .
    .
    .
    .
    #include <stdlib.h>
    
    /* TI Drivers */
    #include <ti/drivers/rf/RF.h>
    #include <ti/drivers/PIN.h>
    
    /* Driverlib Header files */
    #include DeviceFamily_constructPath(driverlib/rf_prop_mailbox.h)
    
    /* Board Header files */
    #include "Board.h"
    
    /* Application Header files */
    #include "RFQueue.h"
    #include "smartrf_settings/smartrf_settings.h"
    
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Semaphore.h>
    
    // CMD_PROP_SET_LEN
    rfc_CMD_PROP_SET_LEN_t RF_cmdPropSetLen =
    {
       .commandNo = 0x3401,
       .rxLen = 0x0000,
    };
    
    // Defines
    
    // Packet RX Configuration
    //  ------------------------------------------------------------------------------------------------------------------------
    //  | DATA_ENTRY_HEADER (12 bytes) | H0 | H1 | H2 | H3 | Length N (1 or 2 Bytes)| D0 | D1 | D2 | .. | .. | D(N-2) | D(N-1) |
    //  ------------------------------------------------------------------------------------------------------------------------
    
    // Optional appended bytes
    //  -------------------------------------------------------
    //  | CRC1 | CRC0 | RSSI | TS0 | TS1 | TS2 | TS3 | Status |
    //  -------------------------------------------------------
    #define DATA_ENTRY_HEADER_SIZE  12                  // Constant header size of a Partial Data Entry
    #define MAX_LENGTH              300                 // Max length byte the application will accept
    #define PACKET_HEADER_SIZE      4                   // Bytes in packet before location of the length byte
    #define LENGTH_FIELD_INDEX      PACKET_HEADER_SIZE  // Position of length byte (after sync)
    #define LENGTH_FIELD_SIZE       2                   // Can be 1 or 2
    #define NUM_APPENDED_BYTES      0                   // .rxConf.bIncludeCrc = 0x1;       // 2 bytes (if default CRC is used)
                                                        // .rxConf.bAppendRssi = 0x1;       // 1 byte
                                                        // .rxConf.bAppendTimestamp = 0x1;  // 4 bytes
                                                        // .rxConf.bAppendStatus = 0x1;     // 1 byte
    
    
    
    /***** Prototypes *****/
    static void callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e);
    
    /***** Variable declarations *****/
    static RF_Object rfObject;
    static RF_Handle rfHandle;
    static RF_CmdHandle rxHandle;
    
    /* Pin driver handle */
    static PIN_Handle ledPinHandle;
    static PIN_State ledPinState;
    
    // Receive dataQueue for RF Core to fill in data
    static dataQueue_t dataQueue;
    
    #if defined(__TI_COMPILER_VERSION__)
    #pragma DATA_ALIGN (rxDataEntryBuf0, 4);
    static uint8_t rxDataEntryBuf0[DATA_ENTRY_HEADER_SIZE + PACKET_HEADER_SIZE + LENGTH_FIELD_SIZE + MAX_LENGTH + NUM_APPENDED_BYTES];
    #pragma DATA_ALIGN (rxDataEntryBuf1, 4);
    static uint8_t rxDataEntryBuf1[DATA_ENTRY_HEADER_SIZE + PACKET_HEADER_SIZE + LENGTH_FIELD_SIZE + MAX_LENGTH + NUM_APPENDED_BYTES];
    
    #elif defined(__IAR_SYSTEMS_ICC__)
    #pragma data_alignment = 4
    static uint8_t rxDataEntryBuf0[DATA_ENTRY_HEADER_SIZE + MAX_LENGTH + LENGTH_POSITION + NUM_APPENDED_BYTES];
    #pragma data_alignment = 4
    static uint8_t rxDataEntryBuf1[DATA_ENTRY_HEADER_SIZE + MAX_LENGTH + LENGTH_POSITION + NUM_APPENDED_BYTES];
    
    #elif defined(__GNUC__)
    static uint8_t rxDataEntryBuf0[DATA_ENTRY_HEADER_SIZE + PACKET_HEADER_SIZE + LENGTH_FIELD_SIZE + MAX_LENGTH + NUM_APPENDED_BYTES] __attribute__((aligned(4)));
    static uint8_t rxDataEntryBuf1[DATA_ENTRY_HEADER_SIZE + PACKET_HEADER_SIZE + LENGTH_FIELD_SIZE + 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 uint16_t payloadLength;
    
    
    rfc_dataEntryPartial_t* partialReadEntry0 = (rfc_dataEntryPartial_t*)&rxDataEntryBuf0;
    rfc_dataEntryPartial_t* partialReadEntry1 = (rfc_dataEntryPartial_t*)&rxDataEntryBuf1;
    rfc_dataEntryPartial_t* currentReadEntry = (rfc_dataEntryPartial_t*)&rxDataEntryBuf0;
    
    rfc_propRxOutput_t rxStatistics;
    static uint8_t lengthWritten = false;
    static uint8_t cancelRx = false;
    RF_Stat status = 0xFF;
    
    // RX Semaphore
    static Semaphore_Struct rxSemaphore;
    static Semaphore_Handle rxSemaphoreHandle;
    
    uint8_t packetHeader[PACKET_HEADER_SIZE];
    uint8_t packetPayload[LENGTH_FIELD_SIZE + MAX_LENGTH];
    uint8_t packetStatusBytes[NUM_APPENDED_BYTES];
    
    // Debug
    uint8_t eventNDataWritten = 0;
    uint8_t eventRxOk = 0;
    uint8_t eventCmdAborted = 0;
    uint8_t eventRxBufFull = 0;
    uint8_t eventRxEntryDone = 0;
    uint8_t eventDataWritten = 0;
    uint8_t eventRxAborted = 0;
    uint8_t eventMdmSoft = 0;
    uint8_t eventLastCmdDone = 0;
    uint8_t dummy = 0;
    /*
     * Application LED pin configuration table:
     *   - All LEDs board LEDs are off.
     */
    PIN_Config pinTable[] =
    {
        Board_PIN_LED2 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
    	PIN_TERMINATE
    };
    
    /***** Function definitions *****/
    
    void *mainThread(void *arg0)
    {
        RF_Params rfParams;
        RF_Params_init(&rfParams);
    
        /* Open LED pins */
        ledPinHandle = PIN_open(&ledPinState, pinTable);
        if (ledPinHandle == NULL)
        {
            while(1);
        }
    
        Semaphore_construct(&rxSemaphore, 0, NULL);
        rxSemaphoreHandle = Semaphore_handle(&rxSemaphore);
    
        partialReadEntry0->length = PACKET_HEADER_SIZE + LENGTH_FIELD_SIZE + MAX_LENGTH + NUM_APPENDED_BYTES + 4;   // Make sure there is enough room for a complete packet in one data entry.
                                                                                                                        // Number of bytes following this length field
                                                                                                                        // + 4 is to make room for the pktStatus (2 bytes) and nextIndex (2 bytes)
        partialReadEntry0->config.irqIntv = PACKET_HEADER_SIZE + LENGTH_FIELD_SIZE;
        partialReadEntry0->config.type = DATA_ENTRY_TYPE_PARTIAL;
        partialReadEntry0->status = DATA_ENTRY_PENDING;
    
        partialReadEntry1->length = PACKET_HEADER_SIZE + LENGTH_FIELD_SIZE + MAX_LENGTH + NUM_APPENDED_BYTES + 4;  // Make sure there is enough room for a complete packet in one data entry.
                                                                                                                       // Number of bytes following this length field
                                                                                                                      // + 4 is to make room for the pktStatus (2 bytes) and nextIndex (2 bytes)
        partialReadEntry1->config.irqIntv = PACKET_HEADER_SIZE + LENGTH_FIELD_SIZE;
        partialReadEntry1->config.type = DATA_ENTRY_TYPE_PARTIAL;
        partialReadEntry1->status = DATA_ENTRY_PENDING;
    
        partialReadEntry0->pNextEntry = (uint8_t*)partialReadEntry1;
        partialReadEntry1->pNextEntry = (uint8_t*)partialReadEntry0;
    
        dataQueue.pCurrEntry = (uint8_t*)partialReadEntry0;
        dataQueue.pLastEntry = NULL;
    
        // Modify CMD_PROP_RX command for application needs
        RF_cmdPropRx.pQueue = &dataQueue;
        RF_cmdPropRx.pOutput = (uint8_t*)&rxStatistics;
        RF_cmdPropRx.rxConf.bIncludeHdr = 1; // Must be 1 to receive the first byte after sync in the data entry
        RF_cmdPropRx.maxPktLen = 0;          // Unlimited length
    
        RF_cmdPropRx.rxConf.bAutoFlushCrcErr = 1;
        RF_cmdPropRx.pktConf.bRepeatOk = 0;
        RF_cmdPropRx.pktConf.bRepeatNok = 0;
    
        // Optional status bytes appended AFTER the payload
        // If these are changed, NUM_APPENDED_BYTES must also be updated
        RF_cmdPropRx.rxConf.bIncludeCrc = 0x0;      // 2 byte (if default CRC is used)
        RF_cmdPropRx.rxConf.bAppendRssi = 0x0;      // 1 byte
        RF_cmdPropRx.rxConf.bAppendStatus = 0x0;    // 1 Byte
        RF_cmdPropRx.rxConf.bAppendTimestamp = 0x0; // 4 bytes
    
        // 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(true)
        {
            lengthWritten = false;
            cancelRx = false;
            status = 0xFF;
            eventNDataWritten = 0;
            eventRxOk = 0;
            eventCmdAborted = 0;
            eventRxBufFull = 0;
            eventRxEntryDone = 0;
            eventDataWritten = 0;
            eventRxAborted = 0;
            eventMdmSoft = 0;
            eventLastCmdDone = 0;
    
            rxHandle = RF_postCmd(rfHandle, (RF_Op*)&RF_cmdPropRx, RF_PriorityNormal, &callback, RF_EventNDataWritten |
                                                                                                 RF_EventRxOk         |
                                                                                                 RF_EventRxBufFull    |
                                                                                                 RF_EventCmdAborted   |
                                                                                                 RF_EventMdmSoft    /*|
                                                                                                 RF_EventCmdCancelled*/); //Not necessary, since this only happens if you cancel something that is not started
    
            Semaphore_pend(rxSemaphoreHandle, BIOS_WAIT_FOREVER); // Wait for cancelRx = true or RF_EventLastCmdDone
    
            if (cancelRx)
            {
                status = RF_cancelCmd(rfHandle, rxHandle, 0);
                Semaphore_pend(rxSemaphoreHandle, BIOS_WAIT_FOREVER); // Semaphore set after RF_EventCmdAborted (RF_EventLastCmdDone will not happen for RF_cancel)
            }
        }
    }
    
    void callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e)
    {
        if (e & RF_EventNDataWritten)
        {
            eventNDataWritten++;
    
            if (!lengthWritten)
            {
                lengthWritten = true;
    
                if(LENGTH_FIELD_SIZE == 2)
                {
                    payloadLength = (uint16_t)(((*(uint8_t*)(&currentReadEntry->rxData + LENGTH_FIELD_INDEX)) << 8) +
                                                (*(uint8_t*)(&currentReadEntry->rxData + LENGTH_FIELD_INDEX + 1)));
                }
                else
                {
                    payloadLength = *(uint8_t*)(&currentReadEntry->rxData + LENGTH_FIELD_INDEX);
                }
    
                if (payloadLength > MAX_LENGTH)
                {
                    cancelRx = true;
                    Semaphore_post(rxSemaphoreHandle); // This takes us to "if (cancelRx)
                }
                else
                {
                    RF_cmdPropSetLen.rxLen = payloadLength + PACKET_HEADER_SIZE + LENGTH_FIELD_SIZE - 1; // Must subtract 1 due to rxConf.bIncludeHdr = 1
                    status = RF_runImmediateCmd(rfHandle, (uint32_t*)&RF_cmdPropSetLen);
                }
            }
        }
    
        if (e & RF_EventMdmSoft)
        {
            eventMdmSoft++;
        }
    
        if (e & RF_EventRxOk)
        {
            eventRxOk++;
            memcpy(packetHeader,        (uint8_t*)(&currentReadEntry->rxData + 0                                                     ), PACKET_HEADER_SIZE);
            memcpy(packetPayload,       (uint8_t*)(&currentReadEntry->rxData + LENGTH_FIELD_INDEX                                    ), LENGTH_FIELD_SIZE + payloadLength);
            memcpy(packetStatusBytes,   (uint8_t*)(&currentReadEntry->rxData + LENGTH_FIELD_INDEX + LENGTH_FIELD_SIZE + payloadLength), NUM_APPENDED_BYTES);
        }
    
        if (e & RF_EventLastCmdDone) // When RX is done due to CMD_SET_LEN (not happening when doing RF_cancel())
        {
           eventLastCmdDone++;
           currentReadEntry->status = DATA_ENTRY_PENDING;
           currentReadEntry = (rfc_dataEntryPartial_t*)currentReadEntry->pNextEntry;
           dataQueue.pCurrEntry = (uint8_t*)currentReadEntry;
    
           Semaphore_post(rxSemaphoreHandle);
        }
    
        if (e & RF_EventCmdAborted) // happens due to RF_cancel()
        {
            eventCmdAborted++;
            currentReadEntry->status = DATA_ENTRY_PENDING;
            currentReadEntry = (rfc_dataEntryPartial_t*)currentReadEntry->pNextEntry;
            dataQueue.pCurrEntry = (uint8_t*)currentReadEntry;
    
            Semaphore_post(rxSemaphoreHandle);
        }
    
        if (e & RF_EventRxBufFull) // This will happen BEFORE the RF_EventLastCmdDone
        {
            currentReadEntry->status = DATA_ENTRY_PENDING;
            currentReadEntry = (rfc_dataEntryPartial_t*)currentReadEntry->pNextEntry;
            dataQueue.pCurrEntry = (uint8_t*)currentReadEntry;
    
            eventRxBufFull++;
        }
    }
    

    我使用发送器测试了代码、该发送器传输以下数据包:

    4字节前导码

    4字节同步

    4个 虚拟标头字节

    2长度字节(0x0118 = 280)

    280个有效载荷字节(0x01、0x02、0x03、0x04、0x05、 0x06、0x07、0x08、0x09、0x0A 重复27次、然后是 0x11、0x12、0x13、0x14、0x15、 末尾有0x16、0x17、0x18、0x19、0x1A

    在接收器上、我得到缓冲区中正确的298个字节:

    12个数据输入标头字节

    4个数据包标头字节

    2长度字节

    280个有效载荷字节

    在尝试实现 wmbus 接收之前,请先确保您能够做一些类似的事情,并且实际上能够使设置长度超过255的长度保持长度。

    Siri

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

    尊敬的 Siri:

    谢谢——我们当然不需要讨论 WMBUS 的规格。  但如果我错了、请更正我;本示例基于补丁;

    // TI-RTOS RF Mode Object
    RF_Mode RF_propCT =
    {
     .rfMode = RF_MODE_PROPRIETARY_SUB_1,
     .cpePatchFxn = &rf_patch_cpe_genfsk,
     .mcePatchFxn = NULL,
     .rfePatchFxn = &rf_patch_rfe_genfsk,
    };

    ...然而,我正在使用 WMBUS 补丁如下所示;

    // TI-RTOS RF Mode Object
    RF_Mode RF_propCT =
    {
     .rfMode = RF_MODE_PROPRIETARY_SUB_1,
     .cpePatchFxn = &rf_patch_cpe_wmbus_ctmode,
     .mcePatchFxn = &rf_patch_mce_wmbus_ctmode,
     .rfePatchFxn = &rf_patch_rfe_wmbus_ctmode,
    };
    

    所以,在不研究 WMBUS 规格和讨论如何提取数据的情况下,你是否有办法可以确认 swra522e.pdf 中描述的 wmbus-patch 实际上可以对长度超过255字节的原始 WMBUS 数据包进行 RX 呢?  

    SET_LEN 不起作用的情况很奇怪、TI 的文档告诉我们应该采用哪种方式来实现它? 超级奇怪…… 我将从头开始、尝试以一种 hello-world 的方法设置一个空白项目、以便查看我在哪里、工作在哪里、不工作在哪里。  

    谢谢。
    /马库斯

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

    我刚刚使用下面的 wmbus 设置对上面的代码进行了测试:

    CC13xx 组合的 wM-Bus C 模式和 T 模式应用手册(修订版 E)

    我仍然能够使它按预期运行。

    Siri

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

    非常有趣。 那么,当您说设置时,您的意思是从文档引用的.zip 文件和 smartf_settings.c,还是我在评论中引用的补丁?

    无论如何、我会将我拥有的东西报废并从头开始构建、以您的代码为样板、(我知道我应该能够通过这些代码接收 WMBUS 数据?)

    谢谢- Markus  

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

    应用手册中的 zip 文件是与 ctmode 补丁一起使用的设置、是的、我同时使用两者(补丁和随附的设置)。

    我的示例代码没有被写入以接收 wmbus 数据包。 它使用 wmbus PHY (物理层、编码/解码等)、但我接收的数据包格式是代码本身中解释的数据包格式(长度字节是在同步字后接收的字节5或5 + 6)。 我认为这不是 wmbus 数据包的长度。

    我的要点是确认 SET_LEN 命令可与 wmbus PHY (CT 模式补丁等)正常工作、并且可以将长度设置为超过255。

    您需要重写代码以接收 wmbus 数据包格式的数据包。

    Siri

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

    谢谢——我不会担心一旦我得到完整的数据包就会分析 WMBUS 数据。

    无论如何、从零开始、我在 simplelink_cc13xx_cc26xx_sdk_7_10_02_23中找不到 CC1310收集器示例? 您是否会建议一个与众不同的起点来让我快速入门?

    谢谢。
    /马库斯

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

    马库斯·赫

    simplelink_cc13xx_cc26xx_sdk_7_10_02_23根本不支持 CC1310。 您需要使用 simplelink_cc13x0_sdk_4_20_02_07 SDK。

    收集器示例适用于 TI15.4堆栈。 该堆栈不支持 wmbus。

    如果您想制作可以接收 wmbus 数据包的产品、则需要自己从头开始制作一些产品(如果您不想使用我们的 wmbus 堆栈)、并且从 rfPacketTX 和 rfPacketRX 开始介绍的最佳示例是。

    Siri

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

    感谢 Siri、

    现在请说明一点、我很乐意使用您的 WMBUS 堆栈并付诸行动、走得越快越好。 也许我遗漏了某些内容、但我打算使用您 TI 的 WMBUS 补丁以及创建我们的应用所需的一切内容(我认为已经完成了、但无法接收较长的 WMBUS 数据包、这也是我在此试图理解为什么...)。  

    简而言之、我想创建一个组合的 S/C/T WMBUS 模式收集器、我可以从主机一次性置入一个 WMBUS 模式、并让 CC1310进入;

    • 监听/捕获 WMBUS 数据
    • 解码格式 A/B
    • 将 UART 上的解码 WMBUS 数据包刷写到主机
    • 重复...  

    我正在处理系统的其他部分(例如主机)、但我们怀疑我们使用的 CC1310代码库中的问题不正确、因为从未收到用格式 A 编码的长 WMBUS 数据包。 事实证明、这是因为大于255字节的数据是随机数据、而不是我们发送/想要捕获的实际数据、因此 CRC 测试失败、我们丢弃了数据包。  

    现在我所要做的就是在 CC1310的基础上建立一个新的基础、尝试以 A/B 格式接收完整的 WMBUS 数据包、然后我可以继续将该正常工作的 RX 过程重新集成到我们的应用中、得到我们需要的东西; 将使用"收集的"WMBUS 数据包为主机馈送的 CC1310实施。

    非常感谢任何提示和三重奏、但我只需要接收整个数据包(您已经展示过、使用 SET_LEN 方法可以完成并且应该有效)。  

    谢谢。
    /马库斯

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

    你好,Siri --不幸的是,我卡住了,真的需要更多的指导。

    我现在已经放弃了我拥有的一切,并从零开始;

    1. 下载适用于 CC1310的 SDK (4.20.02.07)

    2. 确保 CCS 已更新(10.4.0.00006)
      --->一切都是编译/使用 CCS。 而不是 GCC。  

    3. 然后、我 从 rfPacketRx 的"C:\ti\simplelink_cc13x0_sdk_4_20_02_07\examples\rtos\CC1310_LAUNCHXL"中导入了一个新的 CCS 工程

    4. 我没有实际的 CC1310_LAUNCHXL 套件、因为我在设计中已经设计了 CC1310、因此我必须将示例代码移植到"my"设置中、以使其正常工作。 从本质上讲,这涉及到:

      1. 在 CC1310_LAUNCHXL.h 中将一组 IO 更改为 PIN_未 分配
      2. 删除对 CC1310_LAUNCHXL_shutDownExtFlash ()的调用;在  CC1310_LAUNCHXL_Fxns.c 中
      3. 将 WMBUS 补丁和设置添加到  smarter_settings.c
      4. 将 rfPacketRx.c 替换为 之前注释中基本上涉及的示例代码。
      5. 删除 RFQueue.c/.h、因为您的代码未使用该文件
      6. 添加我的代码来计算 WMBUS 头文件到我应该会以格式 A 接收多少原始编码字节
      7. 完成

    5. 但是... 当我 SET_LEN 时、我仍收到不需要的 RF_StatCmdDoneError (2)。
      与基于4.10.01.01 SDK 的旧(已报废)代码库的行为相同...  

    ...我完全被卡住了。 我根据您可以运行的代码重新编写了一个新项目、并确认了最终的工作、但最终我仍然无法在第一次 RF_EventNDataWritten 回调时动态更改 SET_LEN ...

    最后一件事给了我;HW。 如前所述、我不在 CC1310 LaunchPad 上运行该工具、而是在客户特定的设计上运行它。 这是否会以某种方式对 SET_LEN 不工作产生任何影响? 对我来说很奇怪... 我是说、它是一个软件事务、或者至少是一个射频/堆栈设置事务。  

    有任何线索吗?

    我很乐意将我修改过的项目发送给 TI 的您、让您进行深入了解、看看您是否能够理解其不起作用的原因。 或者、如果您可以检查哪些条件会导致  RF_runImmediateCmd 中的 SET_LEN  失败并报告  RF_StatCmdDoneError?

    有点绝望,但非常感谢您的支持,
    /马库斯

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

    Siri、

    昨天晚上/晚上/今天是开放的心态和尴尬...  

    我意识到、我使用 printf (...)语句调试东西、以在调试模式下捕获"运行时"的内容、并且在我调用 SET_LEN 之前、我有了 printf、以便查看我从解析标头中提取出的"原始编码 WMBUS 数据包长度"。 但是、当它在您的示例中适用于您时、什么可能会导致我的 SET_LEN 请求返回失败? 我知道 printf 需要时间、而只是因为我的 printf 而对 SET_LEN 进行的调用"太晚"了吗?

    事实证明确实如此;只需删除 printf 调试代码、我就可以突然设置_LEN 并按预期接收整个数据包。  

    感谢您的耐心和持续反馈。 下一个障碍似乎是、我无法在 UART 上写入我收到的整个数据包、因为超过256个字节的数据包没有从 CC1310正确发送(它们在256个字节处被截断、因此我在主机上仅接收到256个字节)。 但这是另一个主题、我将首先看到我可以阅读的内容、并尝试让内容生效、然后再联系到这里

    此致、
    /马库斯