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和应用手册"CC13xx 组合式 wM-Bus C 模式和 T-Mode"中提供的示例开发无线 M-Bus 应用、包括
https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/689154/cc1310-require-partial-mode-example-of-cc1310
我们可以接收数据包、但偶尔会丢失一些数据包、并且希望获得一些建议。
示例是使用一个线程在每次接收到包时激活无线电和回调、但我们已扩展代码来处理错误和 CRC 检查、这可能是原因。
是否可以在背对背接收设置中使用"部分读取"?
我们曾尝试 在不走运的情况下使用 bRepeatNok/bRepeatOk、但可以在回调本身中重新激活回调。
此致 Peter
我已经进行了研发检查、应该没有任何理由不使用重复模式和部分读取条目。 但是、我们没有相关的代码示例、也没有对其进行测试。
我假设在跟踪数据队列等方面、这会使代码稍微复杂化。
我不明白为什么这也是必要的。 您不应在回调中进行大量处理、而应将其移动到应用中的其他位置。 然后在接收到数据包后重新启动 RX、然后处理接收到的数据包、同时重新启动射频内核并接收新的数据包。
Siri
尊敬的 Siri:
感谢您的快速回复、我将尝试它。
在回调中停止并重新初始化无线电的最佳方法是什么。 目前我只是设置 rxDone 和 partialReadEntry -> status = data_entry_pending,但有更好的方法吗?
此致 Peter
你好,Peter
我不确定我是否理解您在回调中想要做什么。 你是否没有关注你所连接到的线程内的示例?
您可以在回调中设置长度、如下所示:
RF_runImmediateCmd(rfHandle, (uint32_t*)&RF_cmdPropSetLen);
这将确保对讲机在接收到正确字节数时自动退出 RX、因此您不必手动停止对讲机。
今天、我使用重复模式做了一些测试、发现在使用 SET_LEN 命令时无法使用该模式、因此需要将两种重复模式都设置为0。
Br
Siri
尊敬的 Siri:
是的、我遵循该示例并使用
RF_runImmediateCmd(rfHandle, (uint32_t*)&RF_cmdPropSetLen);
它工作正常、但在某些情况下会发生错误、我希望在接收到整个包之前重新初始化。
此致 Peter
您应该使用 RF_CancelCmd 来退出 RX。
我正在处理一个更完整的代码示例、该示例中也包含一些错误处理、完成后可以将其发布在此处
Siri
尊敬的 Siri:
非常感谢、非常感谢您的帮助、并期待看到您正在学习的示例。
此致 Peter
早上好!
我稍微更改了代码、但仍然有一些数据包丢失。 您对下面的代码有什么建议吗?
/** * @file protocol/sndp/src/SndpWMBus.c * @brief WMBus message parser * @copyright (C) 2023 ReMoni ApS. * * These computer program listings and specifications, are the property of * ReMoni ApS and shall not be reproduced or copied or used in whole or in * part without written permission from ReMoni ApS. * */ /*--------------------------------------------------------------------------- Include files ---------------------------------------------------------------------------*/ /* *INDENT-OFF* */ #include <ti/devices/DeviceFamily.h> #include DeviceFamily_constructPath(driverlib/rf_data_entry.h) #include <ti/drivers/rf/RF.h> #include <remoni/mode.h> #include <remoni/Device.h> #include <remoni/crc16wmbus.h> #include <pthread.h> #include <unistd.h> #include "Board.h" #include "nvm_cog.h" #include "Sndp.h" #include "SndpApAir_cc1310.h" #include "SndpCfg.h" #include "SndpRoutingTable.h" #include "sndpUart.h" #include "smartrf_settings/smartrf_settings_wmbus.h" #include "SndpWMBus.h" /* BIOS Header files */ #include <ti/sysbios/BIOS.h> #include <ti/sysbios/knl/Task.h> #include <ti/sysbios/knl/Semaphore.h> #include <ti/sysbios/knl/Event.h> #include <ti/sysbios/knl/Clock.h> #include <xdc/runtime/System.h> /* *INDENT-ON* */ /*--------------------------------------------------------------------------- Macro definitions ---------------------------------------------------------------------------*/ #define RF_TASK_PRIORITY 3 /* Packet RX Configuration */ #define DATA_ENTRY_HEADER_SIZE 12 /* Constant header size of a Generic Data Entry */ #define MAX_LENGTH 255 #define LENGTH_POSITION 2 #define APPENDED_BYTES 1 #define NUM_DATA_ENTRIES 1 /* NOTE: Only two data entries supported at the moment */ #define FRAME_IX (DATA_ENTRY_HEADER_SIZE + LENGTH_POSITION - 1) #define RF_QUEUE_DATA_ENTRY_HEADER_SIZE 12 // Constant header size of a Generic Data Entry #define RF_QUEUE_QUEUE_ALIGN_PADDING(length) (4 - ((length + RF_QUEUE_DATA_ENTRY_HEADER_SIZE) % 4)) // Padding offset #define RF_QUEUE_DATA_ENTRY_BUFFER_SIZE(numEntries, dataSize, appendedBytes) \ (numEntries * (RF_QUEUE_DATA_ENTRY_HEADER_SIZE + dataSize + appendedBytes + RF_QUEUE_QUEUE_ALIGN_PADDING(dataSize + appendedBytes))) #define RX_EVT Event_Id_00 /*--------------------------------------------------------------------------- Enumerations/Type definitions/Structs ---------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------- Global variables/const ---------------------------------------------------------------------------*/ extern Task_Params radioTaskParams; // Borrow from radio task - not used in this mode extern Task_Struct radioTask; // Borrow from radio task - not used in this mode extern uint8_t radioTaskStack[]; // Borrow from radio task - not used in this mode extern const size_t radioStackSize; // Borrow from radio task - not used in this mode /*--------------------------------------------------------------------------- Local variables/const ---------------------------------------------------------------------------*/ static RF_Object rfObject; static RF_Handle rfHandle; static uint8_t rxDataEntryBuffer[RF_QUEUE_DATA_ENTRY_BUFFER_SIZE(NUM_DATA_ENTRIES, MAX_LENGTH, APPENDED_BYTES)] __attribute__((aligned(4))); static rfc_dataEntryPartial_t* partialReadEntry = (rfc_dataEntryPartial_t*)&rxDataEntryBuffer; /* Receive dataQueue for RF Core to fill in data */ static dataQueue_t dataQueue; static rfc_propRxOutput_t rxStatistics; static uint8_t lengthWritten = false; static uint8_t rxDone = false; static uint8_t packet[sizeof(rxDataEntryBuffer)]; /* The length byte is stored in a separate variable */ static uint8_t has_packet = false; /* Act as boolean and length of packet when true */ static RF_CmdHandle rf_comm_handle; rfc_CMD_READ_RFREG_t RF_cmdReadRfReg = { .commandNo = 0x0601, .address = 0x5178, .value = 0, }; Event_Handle rxEvent; Event_Params rxEventParams; Event_Struct rxStructEvent; /* Memory allocated at build time */ /*--------------------------------------------------------------------------- Local prototypes ---------------------------------------------------------------------------*/ static void rfTaskFunction(UArg arg0, UArg arg1); static void callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e); /**************************************************************************** Local functions ****************************************************************************/ /** * rfThread() - Thread initializing radio with callback and keep it going * @param [in] arg0 Passed argument 0 * @param [in] arg1 Passed argument 1 */ static void rfTaskFunction(UArg arg0, UArg arg1) { UInt events; RF_Stat status; RF_Params rfParams; RF_Params_init(&rfParams); partialReadEntry->length = MAX_LENGTH + LENGTH_POSITION + APPENDED_BYTES + 4; partialReadEntry->config.irqIntv = LENGTH_POSITION; partialReadEntry->config.type = DATA_ENTRY_TYPE_PARTIAL; partialReadEntry->status = DATA_ENTRY_PENDING; partialReadEntry->pNextEntry = (uint8_t*)partialReadEntry; dataQueue.pCurrEntry = (uint8_t*)partialReadEntry; dataQueue.pLastEntry = NULL; /* Modify CMD_PROP_RX command for application needs */ RF_cmdPropRx_wmbus.pQueue = &dataQueue; /* Set the Data Entity queue for received data */ RF_cmdPropRx_wmbus.maxPktLen = 0; /* Unlimited length, needed for RF_runImmediateCmd to work */ RF_cmdPropRx_wmbus.rxConf.bAutoFlushCrcErr = 0x0; /* Auto-flush packets with invalid CRC */ RF_cmdPropRx_wmbus.pktConf.bRepeatNok = 0x0; /* Exit RX after a packet is recived */ RF_cmdPropRx_wmbus.pktConf.bRepeatOk = 0x0; /* Exit RX after a packet is recived */ RF_cmdPropRx_wmbus.pOutput = (uint8_t*)&rxStatistics; /* Request access to the radio */ rfHandle = RF_open(&rfObject, &RF_prop_wmbus, (RF_RadioSetup*)&RF_cmdPropRadioDivSetup_wmbus, &rfParams); /* Set the frequency */ rf_comm_handle = RF_postCmd(rfHandle, (RF_Op*)&RF_cmdFs_wmbus, RF_PriorityNormal, NULL, 0); /* Set event */ Event_Params_init(&rxEventParams); Event_construct(&rxStructEvent, &rxEventParams); /* Memory allocated at build time */ rxEvent = Event_handle(&rxStructEvent); /* Memory allocated at build time */ // rxEvent = Event_create(&rxEventParams, NULL); /* Memory allocated in here */ // if (rxEvent == NULL) { System_abort("Event create failed"); } while (!SndpWMBus_ShouldStop()) { rxDone = false; lengthWritten = false; rf_comm_handle = RF_postCmd(rfHandle, (RF_Op*)&RF_cmdPropRx_wmbus, RF_PriorityNormal, &callback, IRQ_RX_N_DATA_WRITTEN); uint32_t timeout_cnt = 7000; // Restart counter if something goes wrong while (!rxDone && !SndpWMBus_ShouldStop()) { // Using events instead of usleep(5000) to get faster response events = Event_pend(rxEvent, Event_Id_NONE, RX_EVT, 5000 / 10); // tickPeriod 10 uS timeout_cnt--; // Filtering on events could be done like if (events & RX_EVT) if (timeout_cnt == 0) { // Restart if nothing received status = RF_flushCmd(rfHandle, rf_comm_handle, 0); RF_close(rfHandle); rfHandle = RF_open(&rfObject, &RF_prop_wmbus, (RF_RadioSetup*)&RF_cmdPropRadioDivSetup_wmbus, &rfParams); rf_comm_handle = RF_postCmd(rfHandle, (RF_Op*)&RF_cmdFs_wmbus, RF_PriorityNormal, NULL, 0); (void)status; // Just to remove warning - System_printf(status) can be used break; } (void)events; // Remove warning } } RF_flushCmd(rfHandle, RF_CMDHANDLE_FLUSH_ALL, 0); RF_close(rfHandle); } /** callback() - Callback to set length and receive full package */ /** * callback() - Callback to set length and receive full package * @param [in] RF_Handle The radio handle * @param [in] RF_CmdHandle The command handle * @param [in] RF_EventMask The event mask initiating the callback */ void callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e) { if (e & RF_EventNDataWritten) { if (!lengthWritten) { lengthWritten = true; RF_runImmediateCmd(rfHandle, (uint32_t*)&RF_cmdReadRfReg); if (RF_cmdReadRfReg.value == 1) { // C-Mode uint8_t preamble = rxDataEntryBuffer[DATA_ENTRY_HEADER_SIZE]; switch (preamble) { case 0xcd: { uint8_t l_field = rxDataEntryBuffer[DATA_ENTRY_HEADER_SIZE + LENGTH_POSITION - 1]; uint8_t crc_length = (l_field > 9) ? (2 * (l_field - 10) / 16 + 2 + 1) : 0; RF_cmdPropSetLen_wmbus.rxLen = l_field + crc_length + (LENGTH_POSITION - 1) + 2; break; } case 0x3d: // Length is 2 bytes longer than wmbusmeters because it is including CRC at the end RF_cmdPropSetLen_wmbus.rxLen = rxDataEntryBuffer[DATA_ENTRY_HEADER_SIZE + LENGTH_POSITION - 1] + (LENGTH_POSITION - 1) + 1 - 3; break; default: { // Unknown and ungandled package type - future implementation RF_cmdPropSetLen_wmbus.rxLen = 0; break; } } } else { // T-Mode currently unhandled // uint8_t l_field = rxDataEntryBuffer[DATA_ENTRY_HEADER_SIZE]; // RF_cmdPropSetLen_wmbus.rxLen = l_field; // System_printf("%d\n", l_field); RF_cmdPropSetLen_wmbus.rxLen = 0; } if (RF_cmdPropSetLen_wmbus.rxLen == 0) { // Abort RF_Stat status = RF_cancelCmd(h, ch, 1); // Cancel command - callback will be called (void)status; // Remove warning } else { // Set length memset(&rxDataEntryBuffer[30], 0, sizeof(rxDataEntryBuffer) - 30); // Mostly for debug when inspecting data RF_runImmediateCmd(rfHandle, (uint32_t*)&RF_cmdPropSetLen_wmbus); } } } else { uint8_t preamble = rxDataEntryBuffer[DATA_ENTRY_HEADER_SIZE]; uint8_t length = rxDataEntryBuffer[FRAME_IX]; uint8_t is_valid = 0; if (0xcd == preamble) { //uint8_t is_valid = crc16wmbus_check_block(&rxDataEntryBuffer[FRAME_IX], 12); length += (length > 9) ? (2 * (length - 10) / 16 + 2 + 2) : 3; is_valid = crc16wmbus_check_split(&rxDataEntryBuffer[FRAME_IX], length); } else if (0x3d == preamble) { length += 1; //Length is without it self is_valid = crc16wmbus_check_block(&rxDataEntryBuffer[FRAME_IX], length); } // TODO: Look at others if (is_valid) { int8_t rssi = rxStatistics.lastRssi; /* Copy the payload + the status byte to the packet variable */ if (has_packet > 0) { /* packet in use by sndp */ } else if (is_valid) { has_packet = length + 1; memset(packet, 0, sizeof(packet)); memcpy(packet, &rxDataEntryBuffer[DATA_ENTRY_HEADER_SIZE], length + 1); SndpWMBus_NewMessage(packet, &has_packet, rssi); // Non blocking handover // System_printf("Data %d\n", rxStatistics.timeStamp); } } // System_printf("%d %x %x\n", is_valid, preamble, e); partialReadEntry->status = DATA_ENTRY_PENDING; rxDone = true; Event_post(rxEvent, RX_EVT); } } /**************************************************************************** Global functions ****************************************************************************/ /** SndpWMBus_Init() - Initialize WMBus */ void WMBusHW_Init(void) { /* Create the rf task */ Task_Params_init(&radioTaskParams); radioTaskParams.stackSize = radioStackSize; radioTaskParams.priority = RF_TASK_PRIORITY; radioTaskParams.stack = &radioTaskStack; radioTaskParams.instance->name = "WMBus Task"; Task_construct(&radioTask, rfTaskFunction, &radioTaskParams, NULL); }
它仍在进行中、但有点实用。 不过、设置长度实际上效果更好一些、如下所示:
rf_cmdPropSetLen_wmbus.rxLen = data_entry_header_size + length_position;
而不依赖 RF_CancelCmd ()。 我错了吗?
此致 Peter
您好!
它看起来像使用 RF_cancelCmd (h、ch、0);突然退出产生了影响、所以使用上面的代码做了这个微小的改变。
此致 Peter
尚未完成演示、但正在进行中。
只是为了确保我完全理解您的问题。
您是否丢失了数据包、如未找到同步、还是数据包中出现 CRC 错误。
如果您丢失了数据包、是否已确认这是时序问题? 即、在传输新的数据包时、您是否已经验证无线电尚未进入 RX?
如果问题与 CRC 错误有关、您是否已确保遵循勘误表注释中的通报11?
Br
Siri
尊敬的 Siri:
感谢您的更新。
我不清楚为什么软件包会丢失、我真的不知道如何进一步调试它。 使用上面的代码、根本不存在任何 CRC 错误、回调不会报告任何异常情况。
我从水表获得数据 、并过滤掉所有紧凑型封装、因此预计数据永远~2分钟、但有时(每几个小时)存在间隙。 在使用多个有源计量表和紧凑封装的情况下进行调试会有点困难。
我 还没有实施建议11、因为它与 CPU 从空闲状态切换相关、我不知道是什么情况、但我将在下周执行、因为它不会有任何危害。
在您的帮助下、上面的代码效果更好、可能每隔几个小时就会丢失一个包裹。 您能看到任何明显的错误或改进建议吗?
此致 Peter
我将尝试给您提供一些一般的调试提示、以便您可以尝试缩小问题范围。
如果从您正在传输某些内容的意义上来说数据包丢失了、但没有收到任何数据包、则应检查以下事项:
您确定器件处于 RX 状态吗? 检查 RX 命令的状态是否为2 (有效)
将 RF_EventMdmSoft 添加到回调中来查看是否收到 SYNC、也是一个好主意。 通过这种方法、您可以确定数据包是否被过滤掉、或者您是否甚至找不到同步字。
如果您的设备在 RX 中、但在传输数据包时找不到同步字、可能是因为存在干扰数据包的干扰器导致您错过同步字。 让监听器查看监听器是否接收到数据包始终是一个好主意。 如果监听器收到但并非您(并且您的器件位于 RX 中)、则可能是硬件出错、导致灵敏度不良。
编写 SW 来接收所有正常数据包通常不算太难、但当您尝试处理所有错误情况时会更困难。
我制作了一个可用于调试的代码示例。 您应该对设置等进行类似操作、然后确保代码处理所有错误情况。
为了对此进行测试、我建议不仅要尝试从水表接收正常数据包、 但是、如果有发送器、则可以配置为传输太长、太短、具有 CRC 错误、导致溢出的数据包等的数据包。另外、请确保代码正在处理所有这些情况。
我的测试代码如下:
/***** 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 | D0 | D1 | D2 | .. | .. | D(N-2) | D(N-1) | // ---------------------------------------------------------------------------------------------------------- // Optional appended bytes // ------------------------------------------------------- // | CRC1 | CRC0 | RSSI | TS3 | TS2 | TS1 | TS0 | Status | // ------------------------------------------------------- #define DATA_ENTRY_HEADER_SIZE 12 /* Constant header size of a Partial Data Entry */ #define MAX_LENGTH 10 /* Max length byte the application will accept */ #define PACKET_HEADER_SIZE 4 /* Bytes in packet before location of the length byte */ #define LENGTH_POSITION PACKET_HEADER_SIZE + 1 /* Position of length byte (after sync) */ #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 + MAX_LENGTH + LENGTH_POSITION + NUM_APPENDED_BYTES] __attribute__((aligned(4))); static uint8_t rxDataEntryBuf1[DATA_ENTRY_HEADER_SIZE + MAX_LENGTH + LENGTH_POSITION + 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[MAX_LENGTH + 1]; // Must have room to store the length byte as well 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 = MAX_LENGTH + LENGTH_POSITION + 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 = LENGTH_POSITION; partialReadEntry0->config.type = DATA_ENTRY_TYPE_PARTIAL; partialReadEntry0->status = DATA_ENTRY_PENDING; partialReadEntry1->length = MAX_LENGTH + LENGTH_POSITION + 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 = LENGTH_POSITION; 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); Semaphore_pend(rxSemaphoreHandle, BIOS_WAIT_FOREVER); if (cancelRx) { status = RF_cancelCmd(rfHandle, rxHandle, 0); Semaphore_pend(rxSemaphoreHandle, BIOS_WAIT_FOREVER); } } } 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; payloadLength = *(uint8_t*)(¤tReadEntry->rxData + LENGTH_POSITION - 1); if (payloadLength > MAX_LENGTH) { cancelRx = true; Semaphore_post(rxSemaphoreHandle); } else { RF_cmdPropSetLen.rxLen = payloadLength + LENGTH_POSITION - 1; // Must subtract 1 due to rxConf.bIncludeHdr = 1 RF_runImmediateCmd(rfHandle, (uint32_t*)&RF_cmdPropSetLen); } } } if (e & RF_EventMdmSoft) { eventMdmSoft++; } if (e & RF_EventRxOk) { eventRxOk++; memcpy(packetHeader, (uint8_t*)(¤tReadEntry->rxData + 0 ), PACKET_HEADER_SIZE); memcpy(packetPayload, (uint8_t*)(¤tReadEntry->rxData + (LENGTH_POSITION - 1) ), (payloadLength + 1)); memcpy(packetStatusBytes, (uint8_t*)(¤tReadEntry->rxData + LENGTH_POSITION + payloadLength), NUM_APPENDED_BYTES); } if (e & RF_EventLastCmdDone) { eventLastCmdDone++; currentReadEntry->status = DATA_ENTRY_PENDING; currentReadEntry = (rfc_dataEntryPartial_t*)currentReadEntry->pNextEntry; dataQueue.pCurrEntry = (uint8_t*)currentReadEntry; Semaphore_post(rxSemaphoreHandle); } if (e & RF_EventCmdAborted) { eventCmdAborted++; currentReadEntry->status = DATA_ENTRY_PENDING; currentReadEntry = (rfc_dataEntryPartial_t*)currentReadEntry->pNextEntry; dataQueue.pCurrEntry = (uint8_t*)currentReadEntry; Semaphore_post(rxSemaphoreHandle); } if (e & RF_EventRxBufFull) { currentReadEntry->status = DATA_ENTRY_PENDING; currentReadEntry = (rfc_dataEntryPartial_t*)currentReadEntry->pNextEntry; dataQueue.pCurrEntry = (uint8_t*)currentReadEntry; eventRxBufFull++; } }
我已经测试了以下内容:
数据包过短:
A1 A2 A3 A4 1 1
nRxStopped 递增并且 eventLastCmdDone 被设置
数据包过长(应用程序将取消 RX 命令)
A1 A2 A3 A4 14 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
nRxStopped 递增,并设置 eventCmdAborted
有 CRC 错误的数据包:
A1 A2 A3 A4 5 1 2 3 4 5 6
nRxNok 递增并且 eventLastCmdDone 被设置
OK 数据包:
A1 A2 A3 A4 5 1 2 3 4 5 6
nRxOk 递增并且 eventLastCmdDone 和 eventRxOk 被置位
缓冲区溢出:
在 rf_runImmediateCmd 的回调中设置断点以溢出
nBrBuffFull 会递增、而 eventLastCmdDone 和 eventRxBufFull 会被设置
由于您使用的是部分读取条目、因此 CPU 将在射频内核处于活动状态且正在接收数据包时执行代码。 因此、您需要遵循建议11。
如果您正在使用正常的数据条目、并且在 RX 中完成无线电操作并收到数据包之前未获得回调、则这不是必需的、但在您的情况下是必要的。
但是、如果问题是缺少同步而不是 CRC 错误、这不能解决您的问题、但您仍然应该实施它以避免 数据包中出现不必要的错误。
Br
Siri
尊敬的 Siri:
谢谢、我来试一下。
我当前正在调试 T 模式、看起来像
RF_runImmediateCmd (rfHandle、(uint32_t*)&RF_cmdReadRfReg); //获取 Mode 值
仅返回 RF_EventNDataWriten 的正确值、而不返回 RF_EventNDataWriten 的值。 是这样吗?
此致 Peter
我想您问的是 RF_EventNDataWriten 与 RF_EventDataWritten 的对比情况????
RF_EventNDataWriten:写入部分读取 Rx 缓冲区的指定字节数
RF_EventDataWriten: 写入部分读取 Rx 缓冲器的数据
在我的示例中、长度是同步字之后的字节编号5、这意味着在接收到至少5个字节之前我无法读出长度。
因此, partialReadEntry0->config.irqIntv 和 partialReadEntry1->config.irqIntv= 5;
因此、我需要等待第一个 RF_EventNDataWriten 事件、然后才能读取长度信息。
如果我第一次读取 RF_EventDataWriten 时尝试读取长度(字节5)、则表示尚未接收到长度。
Siri
尊敬的 Siri:
感谢您的回答、C 模式现在很稳定。 我引用了我自己的代码、但我认为我已经找到了这个代码并从
void callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e) { if (e & RF_EventNDataWritten) { if (!lengthWritten) { lengthWritten = true; RF_runImmediateCmd(rfHandle, (uint32_t*)&RF_cmdReadRfReg); if (RF_cmdReadRfReg.value == 1) { // C-Mode uint8_t preamble = rxDataEntryBuffer[DATA_ENTRY_HEADER_SIZE]; switch (preamble) { case 0xcd: { uint8_t l_field = rxDataEntryBuffer[DATA_ENTRY_HEADER_SIZE + LENGTH_POSITION - 1]; uint8_t crc_length = (l_field > 9) ? (2 * (l_field - 10) / 16 + 2 + 1) : 0; RF_cmdPropSetLen_wmbus.rxLen = l_field + crc_length + (LENGTH_POSITION - 1) + 2; break; } case 0x3d: // Length is 2 bytes longer than wmbusmeters because it is including CRC at the end RF_cmdPropSetLen_wmbus.rxLen = rxDataEntryBuffer[DATA_ENTRY_HEADER_SIZE + LENGTH_POSITION - 1] + (LENGTH_POSITION - 1) + 1 - 3; break; default: { // Unknown and ungandled package type - future implementation RF_cmdPropSetLen_wmbus.rxLen = 0; break; } } } else { // T-Mode currently unhandled // uint8_t l_field = rxDataEntryBuffer[DATA_ENTRY_HEADER_SIZE]; // RF_cmdPropSetLen_wmbus.rxLen = l_field; // System_printf("%d\n", l_field); RF_cmdPropSetLen_wmbus.rxLen = 0; } if (RF_cmdPropSetLen_wmbus.rxLen == 0) { // Abort RF_Stat status = RF_cancelCmd(h, ch, 1); // Cancel command - callback will be called (void)status; // Remove warning } else { // Set length memset(&rxDataEntryBuffer[30], 0, sizeof(rxDataEntryBuffer) - 30); // Mostly for debug when inspecting data RF_runImmediateCmd(rfHandle, (uint32_t*)&RF_cmdPropSetLen_wmbus); } } } else { uint8_t preamble = rxDataEntryBuffer[DATA_ENTRY_HEADER_SIZE]; uint8_t length = rxDataEntryBuffer[FRAME_IX]; uint8_t is_valid = 0; if (0xcd == preamble) { //uint8_t is_valid = crc16wmbus_check_block(&rxDataEntryBuffer[FRAME_IX], 12); length += (length > 9) ? (2 * (length - 10) / 16 + 2 + 2) : 3; is_valid = crc16wmbus_check_split(&rxDataEntryBuffer[FRAME_IX], length); } else if (0x3d == preamble) { length += 1; //Length is without it self is_valid = crc16wmbus_check_block(&rxDataEntryBuffer[FRAME_IX], length); } // TODO: Look at others if (is_valid) { int8_t rssi = rxStatistics.lastRssi; /* Copy the payload + the status byte to the packet variable */ if (has_packet > 0) { /* packet in use by sndp */ } else if (is_valid) { has_packet = length + 1; memset(packet, 0, sizeof(packet)); memcpy(packet, &rxDataEntryBuffer[DATA_ENTRY_HEADER_SIZE], length + 1); SndpWMBus_NewMessage(packet, &has_packet, rssi); // Non blocking handover // System_printf("Data %d\n", rxStatistics.timeStamp); } } // System_printf("%d %x %x\n", is_valid, preamble, e); partialReadEntry->status = DATA_ENTRY_PENDING; rxDone = true; Event_post(rxEvent, RX_EVT); } }
至
void callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e) { if (e & RF_EventNDataWritten) { if (!lengthWritten) { lengthWritten = true; RF_runImmediateCmd(rfHandle, (uint32_t*)&RF_cmdReadRfReg); // Get the Mode value rxMode = RF_cmdReadRfReg.value; // Store the mode - reg will change later if (rxMode == 1) { // C-Mode uint8_t preamble = rxDataEntryBuffer[DATA_ENTRY_HEADER_SIZE]; switch (preamble) { case 0xcd: { uint8_t l_field = rxDataEntryBuffer[DATA_ENTRY_HEADER_SIZE + LENGTH_POSITION - 1]; uint8_t crc_length = (l_field > 9) ? (2 * (l_field - 10) / 16 + 2 + 1) : 0; RF_cmdPropSetLen_wmbus.rxLen = l_field + crc_length + (LENGTH_POSITION - 1) + 2; break; } case 0x3d: // Length is 2 bytes longer than wmbusmeters because it is including CRC at the end RF_cmdPropSetLen_wmbus.rxLen = rxDataEntryBuffer[DATA_ENTRY_HEADER_SIZE + LENGTH_POSITION - 1] + (LENGTH_POSITION - 1) + 1 - 3; break; default: { // Unknown and unhandled package type - future implementation RF_cmdPropSetLen_wmbus.rxLen = 0; break; } } } else { // T-Mode is like frame a uint8_t l_field = rxDataEntryBuffer[DATA_ENTRY_HEADER_SIZE]; uint8_t crc_length = (l_field > 9) ? (2 * (l_field - 10) / 16 + 2) : 0; RF_cmdPropSetLen_wmbus.rxLen = l_field + crc_length; } if (RF_cmdPropSetLen_wmbus.rxLen == 0) { // Abort RF_Stat status = RF_cancelCmd(h, ch, 0); // Cancel command - callback will be called (void)status; // Remove warning } else { // Set length memset(&rxDataEntryBuffer[30], 0, sizeof(rxDataEntryBuffer) - 30); // Mostly for debug when inspecting data RF_runImmediateCmd(rfHandle, (uint32_t*)&RF_cmdPropSetLen_wmbus); } } } else { uint8_t preamble = rxDataEntryBuffer[DATA_ENTRY_HEADER_SIZE]; uint8_t length = rxDataEntryBuffer[FRAME_IX]; uint8_t is_valid = 0; if (rxMode == 0) { // T-Mode length = rxDataEntryBuffer[DATA_ENTRY_HEADER_SIZE]; // No preamble length += (length > 9) ? (2 * (length - 10) / 16 + 2 + 2) : 3; length += 1; //Length is without it self if (length + DATA_ENTRY_HEADER_SIZE < MAX_LENGTH) { // Don't process if to big memmove(&rxDataEntryBuffer[DATA_ENTRY_HEADER_SIZE + 1], &rxDataEntryBuffer[DATA_ENTRY_HEADER_SIZE], length); rxDataEntryBuffer[DATA_ENTRY_HEADER_SIZE] = 0xcd; // Fake C-Mode is_valid = crc16wmbus_check_split(&rxDataEntryBuffer[FRAME_IX], length); } } else if (0xcd == preamble) { //uint8_t is_valid = crc16wmbus_check_block(&rxDataEntryBuffer[FRAME_IX], 12); length += (length > 9) ? (2 * (length - 10) / 16 + 2 + 2) : 3; is_valid = crc16wmbus_check_split(&rxDataEntryBuffer[FRAME_IX], length); } else if (0x3d == preamble) { length += 1; //Length is without it self is_valid = crc16wmbus_check_block(&rxDataEntryBuffer[FRAME_IX], length); } // TODO: Look at others if (is_valid) { int8_t rssi = rxStatistics.lastRssi; /* Copy the payload + the status byte to the packet variable */ if (has_packet > 0) { /* packet in use by sndp */ } else if (is_valid) { has_packet = length + 1; memset(packet, 0, sizeof(packet)); memcpy(packet, &rxDataEntryBuffer[DATA_ENTRY_HEADER_SIZE], length + 1); SndpWMBus_NewMessage(packet, &has_packet, rssi); // Non blocking handover // System_printf("Data %d\n", rxStatistics.timeStamp); } } // System_printf("%d %d %d %x %x\n", is_valid, rxMode, length, preamble, e); partialReadEntry->status = DATA_ENTRY_PENDING; rxDone = true; Event_post(rxEvent, RX_EVT); } }
但是、这会导致 T 模式封装多于 WMBusMeters 可以看到的具有无效 CRC 的 T 模式封装、并且也会影响 C 模式。 实际上只有1米发送、那么问题出在哪里呢?
此致 Peter
你好,Peter
我不确定我是否理解您所问的问题。 "什么意思?
"这会导致多于 WMBusMeters 可以看到的具有无效 CRC 的 T 模式封装、并影响 C。 模式"
我无法调试您的实现、我不确定我是否理解您遇到的问题。
请记住、即使您仅有1米的传输距离、附近也可能有其他仪表可以接收。 此外、由于 wmbus 仅使用2字节的同步字、因此您还将接收伪数据包。 如果接收到伪数据包时占用代码、则此时发送的任何其他数据包都将丢失。
在验证软件是否按预期工作之前、最好在屏蔽环境中进行一些测试、此时可以完全控制发送到无线电的内容(无干扰源)。
此外、在调试时将代码简化为仅记录找到的 SYNC 数量、c 模式的数量和 t 模式数据包的数量、并将该数量与您发送的数据包数量进行比较、可能有助于了解传输中有多少其他数据、 这可能会干扰您的数据包。
Siri
尊敬的 Siri:
我将尝试进一步解释、不希望您调试我的代码、只需快速查看是否有关闭的东西。
我认为代码在仅配置为 C 模式(帧格式 A 和 B)时基本没问题、但在启用 T 模式后开始失效。
我 希望寻找假的 T-Mode 数据包可能会导致 C 模式数据包丢失、但没有办法尽早识别这些情况、例如在新的同步中重新启动?
我希望能够可靠地处理 C 模式和 T 模式封装。
此致 Peter
你好,Peter
仍然不确定我是否理解您遇到的问题。
当您尝试进行电机控制时、
我无法仅通过查看代码来说明问题所在、我只能建议您继续调试问题以缩小问题范围。
当我们知道问题的原因时、我们也可以查看解决方案。
我们可以做的是设置具有 SmartRF Studio 的 CC1310 LP、并将其用作监听器。
您无法从 Studio 运行 C/T 模式补丁、但您可以设置正确的 PHY 参数、例如6字节的固定数据包长度。
这将给你一个指示,在空气中发生了什么。
从下图中可以看出、我已将 CC1310在我的办公桌上运行了大约3分钟。
它接收到27个数据包、其中3个是我从另一个 LP 传输的数据包、其余为噪声或附近的其他仪表。
从 RSSI 水平可以看出、我实际发送的3个数据包比收集的其余数据包强得多。 一些其他数据包看起来像"真实"C 模式数据包、因为它们具有信令字节(0x54)、其余数据包可能是 T 模式或噪声。
请注意、wmbus 补丁具有可编程的载波侦听阈值。 此设置默认为-107dBm、因此不接受信号强度低于的同步字。
出于调试目的、可以将阈值增加到接收到实际发送的数据包的水平、而其他所有内容都将不被接受。
此处说明了如何更改阈值:
CC13xx 组合的 wM-Bus C 模式和 T 模式应用手册(修订版 E)
我对您的代码有一些可能会导致问题的注释:
在设置了 RF_cmdPropSetLen_wmbus.rxLen 的回调中、您将其设置为 l_field +某个值。
这意味着得到的长度可以大于255。
您是否已确保数据条目足够大、从而不会出现溢出的情况?
从代码来看、似乎您正在设置
partialReadEntry -> length = MAX_LENGTH + length_position + added_bytes + 4;
在这里、您不考虑 rxLen 大于 MAX_LEN
您的代码另一个可能的问题是您没有订阅 RF_EventCmdAborted
if (e & RF_EventNDataWritten) { . . } else { partialReadEntry->status = DATA_ENTRY_PENDING; rxDone = true; Event_post(rxEvent, RX_EVT); }
如果您执行 RF_cancelCmd、则不会获得 eventLastCmdDone、而只能获得 RF_EventCmdAborted、这意味着在取消的情况下您的代码不会设置 partialReadEntry -> status = DATA_ENTRY_PUNDING;
可能还有其他原因、因此、我强烈建议您调试代码、每次仅调试一种数据包类型、以确保所有"错误案例"/"边界案例"都得到正确处理。
长度字节= 0
长度字节= 255
CRC 错误
C 模式的帧格式错误(不是帧 A 或帧 B)
Br
Siri
尊敬的 Siri:
再次感谢您的帮助、非常感谢。
我看到的是您的选项2
或者您是否会收到这些数据包、但还会收到很多虚假 T 模式数据包、这也会导致您丢失 C 模式数据包
我已经实施了您的建议
但是设置 载波侦听阈值实际上并不会对任何东西产生影响。 我正在 Linux 上开发、因此使用 SmartRF Studio 有点困难、但我还要尝试获取 Windows 机器。
这是有道理的,寻找幽灵包将使我松散真正的包.
此致 Peter
不应将 partialReadEntry ->长度限制为 MAX_LENGTH
您可能需要增加它、因为您可以接收比此时间更长的数据包。
在我的示例中、长度字节表示后跟多少个字节(不包括 CRC)
/ ---------------------------------------------------------------------------------------- // | DATA_ENTRY_HEADER (12 bytes) | H0 | H1 | H2 | H3 | Length 5 | D1 | D2 | D3 | D4 | D5 | // ---------------------------------------------------------------------------------------- #define DATA_ENTRY_HEADER_SIZE 12 #define MAX_LENGTH 5 #define PACKET_HEADER_SIZE 4 #define LENGTH_POSITION 5 #define NUM_APPENDED_BYTES 0 static uint8_t rxDataEntryBuf0[DATA_ENTRY_HEADER_SIZE + MAX_LENGTH + LENGTH_POSITION + NUM_APPENDED_BYTES] partialReadEntry0->length = MAX_LENGTH + LENGTH_POSITION + NUM_APPENDED_BYTES + 4; RF_cmdPropSetLen.rxLen = payloadLength + LENGTH_POSITION - 1; // Must subtract 1 due to rxConf.bIncludeHdr = 1 (H0 in the figure above)
有效载荷长度从不大于 MAX_LENGTH (5)、因此最大 rxLen i 将设置为9。
MAX_LENGTH 为255。 我不知道 wmbus 数据包的格式、因此不知道其中包含的内容、但如果您有如下内容:
/ ------------------------------------------------------------------------------------------------------- // | DATA_ENTRY_HEADER (12 bytes) | H0 | Length 255 | D1 | D2 | D3 | D4 | D5 |------| D255 | CRC1 | CRC2 | // ------------------------------------------------------------------------------------------------------- #define DATA_ENTRY_HEADER_SIZE 12 #define MAX_LENGTH 255 #define PACKET_HEADER_SIZE 1 #define LENGTH_POSITION 2 #define NUM_APPENDED_BYTES 0 static uint8_t rxDataEntryBuf0[DATA_ENTRY_HEADER_SIZE + MAX_LENGTH + LENGTH_POSITION + NUM_APPENDED_BYTES] partialReadEntry0->length = MAX_LENGTH + 2 + LENGTH_POSITION + NUM_APPENDED_BYTES + 4; RF_cmdPropSetLen.rxLen = payloadLength + 2 + LENGTH_POSITION - 1; // Must subtract 1 due to rxConf.bIncludeHdr = 1 (H0 in the figure
必须将2添加到 partialReadEntry0->length 和 rf_cmdPropSetLen.rxLen 中。
如果将 CS 阈值增大到高值根本没有帮助(例如、-50dBm、具体取决于您的发送器的强度)、我猜大概是问题与处理噪声/伪数据包无关。
Br
Siri
尊敬的 Siri:
我认为、至少目前将大小限制为 MAX_LENGTH 是可以的。 我还没有看到任何这样长的软件包、我们正在通过另一个具有更严格限制的协议转发这些软件包。
我可能没有以正确的方式或在正确的位置提高 CS 阈值。 I 使用
HW_REG_OVERRIDE (0x6090、0x0ACE);//载波侦听阈值覆盖
并尝试在不同的地方甚至像0x0AFF 一样使用它、但没有任何明显的差别。
此致 Peter
覆盖已是应与该补丁一起使用的设置的一部分、因此您只需修改它(而不是将其添加到其他位置:
#include DEVICE_FAMILY_PATH(driverlib/rf_mailbox.h) #include DEVICE_FAMILY_PATH(driverlib/rf_common_cmd.h) #include DEVICE_FAMILY_PATH(driverlib/rf_prop_cmd.h) #include <ti/drivers/rf/RF.h> #include DEVICE_FAMILY_PATH(rf_patches/rf_patch_cpe_wmbus_ctmode.h) #include DEVICE_FAMILY_PATH(rf_patches/rf_patch_mce_wmbus_ctmode.h) #include DEVICE_FAMILY_PATH(rf_patches/rf_patch_rfe_wmbus_ctmode.h) #include "smartrf_settings.h" uint32_t txShapeTMode[] = {0x00000000, 0x00000000, 0x00000000, 0x4B110200, 0xF2F0E1A6, 0xF2F2F2F2}; uint32_t txShapeCMode[] = {0x00000000, 0x00000000, 0x00000000, 0x440F0200, 0xD9D8CA96, 0xD9D9D9D9}; // TI-RTOS RF Mode Object RF_Mode RF_prop = { .rfMode = RF_MODE_PROPRIETARY_SUB_1, .cpePatchFxn = &rf_patch_cpe_wmbus_ctmode, .mcePatchFxn = &rf_patch_mce_wmbus_ctmode, .rfePatchFxn = &rf_patch_rfe_wmbus_ctmode, }; // Overrides for CMD_PROP_RADIO_DIV_SETUP static uint32_t pOverrides[] = { //Run the MCE and RFE patches MCE_RFE_OVERRIDE(1,0,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_0x2e.xml // Tx: Configure PA ramping setting and set AGC reference level to 0x2E HW_REG_OVERRIDE(0x6088,0x082E), // Tx: Configure PA ramping setting and set AGC settle wait = (0x7+1)*2 = 16 samples HW_REG_OVERRIDE(0x608C,0x0407), // override_phy_rx_rssi_offset_5db.xml // Rx: Set RSSI offset to adjust reported RSSI by +5 dB (uint32_t)0x00FB88A3, // TX power override // Tx: Set PA trim to max (in ADI0, set PACTL0=0xF8) ADI_REG_OVERRIDE(0,12,0xF8), // AGC winsize 2 samples HW_REG_OVERRIDE(0x6064,0x1101), // CS threshold to –107 dBm HW_REG_OVERRIDE(0x6090,0xA095),//////////////////////////////////////////Change the override here // Let the patch control the correlator setting (uint32_t)0x00048103, // Clear state in internal radio register due to frequency change HW_REG_OVERRIDE(0x51F8,0x0000), // Set divider bias to disabled HW32_ARRAY_OVERRIDE(0x405C,1), (uint32_t)0x18000200, // TX shape in T-mode 0xC0040031, (uint32_t)&txShapeTMode[0], // TX shape in C-mode //0xC0040031, //(uint32_t)&txShapeCMode[0], (uint32_t)0xFFFFFFFF, };
如果您这样做、您收到的所有数据包的 RSSI 均为-50 dBm 以上、因此您可能有一些您不知道的强干扰器/仪表、或者您的问题不是虚假数据包。
使用 SmartRF Studio 将同步事件添加到回调和/或测试中将帮助您了解这一点。
Siri
尊敬的 Siri:
谢谢、这是我的错。
现在它的工作和价值-85给出了合理的结果,没有许多"鬼"在我的工作地点,这是非常嘈杂。 我将在明天的实际情景中进行测试、并在团队中进行讨论。
TI 建议在嘈杂环境中使用大约-90的值还是应 保持在-107?
此致 Peter
这取决于具体情况、很难给出任何好的建议。
设置较高的阈值(假设为-90dBm)将减少由于噪声(或附近的其他仪表)而导致的错误数据包的数量、因此您更有可能接收到想要的数据包、因为接收器不会被占用来处理不适合您的数据包。
另一方面、这也会设置您的灵敏度级别、因为您将无法接收信号强度低于-90dBm 的任何数据包(即使这些数据包是为您准备的)。
我假设在数据包的开头有一些信息可以用来确定数据包是否适合您(某种 ID 等?)
如果有、我想您可以检查该信息、并在数据包不适合您时取消 RX、而不必等待接收整个数据包、然后再进行检查。
Siri
尊敬的 Siri:
好的、谢谢、这是讲得通的。 我想我将进一步测试和完善这一点、现在您已向我指出了正确的方向。
谢谢、祝您愉快。 此致 Peter