CC1310 Easylink LRM模式接收不到数据?
各位大神:
请问有跑过rfEasylink例程吗? 我在修改为625bps rate的时候数据接收不到,请问是怎么回事?
当然发送程序也改成了625bps 速率,另外都是868频率发送。
可以把你在rfEasylink例程中修改的部分贴出来吗?
就下面两个地方,一个配置为625,另一个收的timeout改为500ms了,也试过改为1s,还是不行。
另外我把tx的修改的也贴出来吧:
这就是全部;tx没问题看到发送完成对应的灯闪烁了。
下载我们的GUI调试软件,SmartRF Studio 7,接上接收方,看看有没有收到。
刚测试了 没有收到数据;但是在另一个开发板上烧的rfPaketErrorRate的程序中配置成LRM模式能收到rfEasyLinkTx发送的数据。
可能是SmartRF Studio 7没有设置好,不过根据你说rfPaketErrorRate的程序可以接到到,证明空中有数据,rfPaketErrorRate接收方程序,是让CC1310一直出于接收情况,而rfEasyLinkRx程序,是间隔接收,你把rfEasyLinkTx例程改一下,让CC1310一直发送,试下能不能接收
不行啊,rx就是收不到,就算用rfPaketErrorRate发送也收不到;是不是EasyLink的接收程序有问题啊?
把接收的程序用文字发上来,非图片,就把main函数所在的文件的内容贴上来就行,我测试下
/*
* Copyright (c) 2015-2016, Texas Instruments Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* ======== rfEasyLinkTx.c ========
*/
/* XDCtools Header files */
#include <xdc/std.h>
#include <xdc/runtime/System.h>
#include <xdc/runtime/Error.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/Clock.h>
/* TI-RTOS Header files */
#include <ti/drivers/PIN.h>
/* Board Header files */
#include "Board.h"
/* EasyLink API Header files */
#include "easylink/EasyLink.h"
/***** Defines *****/
/* Undefine to remove address filter and async mode */
#define RFEASYLINKRX_ASYNC
#define RFEASYLINKRX_ADDR_FILTER
#define RFEASYLINKEX_TASK_STACK_SIZE 1024
#define RFEASYLINKEX_TASK_PRIORITY 2
/* Pin driver handle */
static PIN_Handle ledPinHandle;
static PIN_State ledPinState;
/*
* Application LED pin configuration table:
* - All LEDs board LEDs are off.
*/
PIN_Config pinTable[] = {
Board_LED1 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
Board_LED2 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
PIN_TERMINATE
};
/***** Variable declarations *****/
static Task_Params rxTaskParams;
Task_Struct rxTask; /* not static so you can see in ROV */
static uint8_t rxTaskStack[RFEASYLINKEX_TASK_STACK_SIZE];
/* The RX Output struct contains statistics about the RX operation of the radio */
PIN_Handle pinHandle;
#ifdef RFEASYLINKRX_ASYNC
static Semaphore_Handle rxDoneSem;
#endif
/***** Function definitions *****/
#ifdef RFEASYLINKRX_ASYNC
void rxDoneCb(EasyLink_RxPacket * rxPacket, EasyLink_Status status)
{
if (status == EasyLink_Status_Success)
{
/* Toggle LED2 to indicate RX */
PIN_setOutputValue(pinHandle, Board_LED2,!PIN_getOutputValue(Board_LED2));
}
else if(status == EasyLink_Status_Aborted)
{
/* Toggle LED1 to indicate command aborted */
//PIN_setOutputValue(pinHandle, Board_LED1,!PIN_getOutputValue(Board_LED1));
}
else
{
/* Toggle LED1 and LED2 to indicate error */
PIN_setOutputValue(pinHandle, Board_LED1,!PIN_getOutputValue(Board_LED1));
PIN_setOutputValue(pinHandle, Board_LED2,!PIN_getOutputValue(Board_LED2));
}
Semaphore_post(rxDoneSem);
}
#endif
static void rfEasyLinkRxFnx(UArg arg0, UArg arg1)
{
#ifndef RFEASYLINKRX_ASYNC
EasyLink_RxPacket rxPacket = {0};
#endif
#ifdef RFEASYLINKRX_ASYNC
/* Create a semaphore for Async*/
Semaphore_Params params;
Error_Block eb;
/* Init params */
Semaphore_Params_init(¶ms);
Error_init(&eb);
/* Create semaphore instance */
rxDoneSem = Semaphore_create(0, ¶ms, &eb);
#endif //RFEASYLINKRX_ASYNC
EasyLink_init(EasyLink_Phy_625bpsLrm);
/* If you wich to use a frequency other than the default use
* the below API
* EasyLink_setFrequency(868000000);
*/
#ifdef RFEASYLINKRX_ADDR_FILTER
uint8_t addrFilter = 0xaa;
EasyLink_enableRxAddrFilter(&addrFilter, 1, 1);
#endif //RFEASYLINKRX_ADDR_FILTER
while(1) {
#ifdef RFEASYLINKRX_ASYNC
EasyLink_receiveAsync(rxDoneCb, 0);
/* Wait 500ms for Rx */
if(Semaphore_pend(rxDoneSem, (500000 / Clock_tickPeriod)) == FALSE)
{
/* RX timed out abort */
if(EasyLink_abort() == EasyLink_Status_Success)
{
/* Wait for the abort */
Semaphore_pend(rxDoneSem, BIOS_WAIT_FOREVER);
}
}
#else
rxPacket.absTime = 0;
EasyLink_Status result = EasyLink_receive(&rxPacket);
if (result == EasyLink_Status_Success)
{
/* Toggle LED2 to indicate RX */
PIN_setOutputValue(pinHandle, Board_LED2,!PIN_getOutputValue(Board_LED2));
}
else
{
/* Toggle LED1 and LED2 to indicate error */
PIN_setOutputValue(pinHandle, Board_LED1,!PIN_getOutputValue(Board_LED1));
PIN_setOutputValue(pinHandle, Board_LED2,!PIN_getOutputValue(Board_LED2));
}
#endif //RX_ASYNC
}
}
void rxTask_init(PIN_Handle ledPinHandle) {
pinHandle = ledPinHandle;
Task_Params_init(&rxTaskParams);
rxTaskParams.stackSize = RFEASYLINKEX_TASK_STACK_SIZE;
rxTaskParams.priority = RFEASYLINKEX_TASK_PRIORITY;
rxTaskParams.stack = &rxTaskStack;
rxTaskParams.arg0 = (UInt)1000000;
Task_construct(&rxTask, rfEasyLinkRxFnx, &rxTaskParams, NULL);
}
/*
* ======== main ========
*/
int main(void)
{
/* Call board init functions. */
Board_initGeneral();
/* Open LED pins */
ledPinHandle = PIN_open(&ledPinState, pinTable);
if(!ledPinHandle) {
System_abort("Error initializing board LED pins\n");
}
/* Clear LED pins */
PIN_setOutputValue(ledPinHandle, Board_LED1, 0);
PIN_setOutputValue(ledPinHandle, Board_LED2, 0);
rxTask_init(ledPinHandle);
/* Start BIOS */
BIOS_start();
return (0);
}
我这边是可以的,下面是1s的接收程序
/* XDCtools Header files */
#include <xdc/std.h>
#include <xdc/runtime/System.h>
#include <xdc/runtime/Error.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/Clock.h>
/* TI-RTOS Header files */
#include <ti/drivers/PIN.h>
/* Board Header files */
#include "Board.h"
/* EasyLink API Header files */
#include "easylink/EasyLink.h"
/***** Defines *****/
/* Undefine to remove address filter and async mode */
#define RFEASYLINKRX_ASYNC
#define RFEASYLINKRX_ADDR_FILTER
#define RFEASYLINKEX_TASK_STACK_SIZE 1024
#define RFEASYLINKEX_TASK_PRIORITY 2
/* Pin driver handle */
static PIN_Handle ledPinHandle;
static PIN_State ledPinState;
/*
* Application LED pin configuration table:
* - All LEDs board LEDs are off.
*/
PIN_Config pinTable[] = {
Board_LED1 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
Board_LED2 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
PIN_TERMINATE
};
/***** Variable declarations *****/
static Task_Params rxTaskParams;
Task_Struct rxTask; /* not static so you can see in ROV */
static uint8_t rxTaskStack[RFEASYLINKEX_TASK_STACK_SIZE];
/* The RX Output struct contains statistics about the RX operation of the radio */
PIN_Handle pinHandle;
#ifdef RFEASYLINKRX_ASYNC
static Semaphore_Handle rxDoneSem;
#endif
/***** Function definitions *****/
#ifdef RFEASYLINKRX_ASYNC
void rxDoneCb(EasyLink_RxPacket * rxPacket, EasyLink_Status status)
{
if (status == EasyLink_Status_Success)
{
/* Toggle LED2 to indicate RX */
PIN_setOutputValue(pinHandle, Board_LED2,!PIN_getOutputValue(Board_LED2));
}
else if(status == EasyLink_Status_Aborted)
{
/* Toggle LED1 to indicate command aborted */
PIN_setOutputValue(pinHandle, Board_LED1,!PIN_getOutputValue(Board_LED1));
}
else
{
/* Toggle LED1 and LED2 to indicate error */
PIN_setOutputValue(pinHandle, Board_LED1,!PIN_getOutputValue(Board_LED1));
PIN_setOutputValue(pinHandle, Board_LED2,!PIN_getOutputValue(Board_LED2));
}
Semaphore_post(rxDoneSem);
}
#endif
static void rfEasyLinkRxFnx(UArg arg0, UArg arg1)
{
#ifndef RFEASYLINKRX_ASYNC
EasyLink_RxPacket rxPacket = {0};
#endif
#ifdef RFEASYLINKRX_ASYNC
/* Create a semaphore for Async*/
Semaphore_Params params;
Error_Block eb;
/* Init params */
Semaphore_Params_init(¶ms);
Error_init(&eb);
/* Create semaphore instance */
rxDoneSem = Semaphore_create(0, ¶ms, &eb);
#endif //RFEASYLINKRX_ASYNC
EasyLink_init(EasyLink_Phy_625bpsLrm);
EasyLink_setFrequency(868000000);
#ifdef RFEASYLINKRX_ADDR_FILTER
uint8_t addrFilter = 0xaa;
EasyLink_enableRxAddrFilter(&addrFilter, 1, 1);
#endif //RFEASYLINKRX_ADDR_FILTER
while(1) {
#ifdef RFEASYLINKRX_ASYNC
EasyLink_receiveAsync(rxDoneCb, 0);
/* Wait 300ms for Rx */
if(Semaphore_pend(rxDoneSem, (1000000 / Clock_tickPeriod)) == FALSE)
{
/* RX timed out abort */
if(EasyLink_abort() == EasyLink_Status_Success)
{
/* Wait for the abort */
Semaphore_pend(rxDoneSem, BIOS_WAIT_FOREVER);
}
}
#else
rxPacket.absTime = 0;
EasyLink_Status result = EasyLink_receive(&rxPacket);
if (result == EasyLink_Status_Success)
{
/* Toggle LED2 to indicate RX */
PIN_setOutputValue(pinHandle, Board_LED2,!PIN_getOutputValue(Board_LED2));
}
else
{
/* Toggle LED1 and LED2 to indicate error */
PIN_setOutputValue(pinHandle, Board_LED1,!PIN_getOutputValue(Board_LED1));
PIN_setOutputValue(pinHandle, Board_LED2,!PIN_getOutputValue(Board_LED2));
}
#endif //RX_ASYNC
}
}
void rxTask_init(PIN_Handle ledPinHandle) {
pinHandle = ledPinHandle;
Task_Params_init(&rxTaskParams);
rxTaskParams.stackSize = RFEASYLINKEX_TASK_STACK_SIZE;
rxTaskParams.priority = RFEASYLINKEX_TASK_PRIORITY;
rxTaskParams.stack = &rxTaskStack;
rxTaskParams.arg0 = (UInt)1000000;
Task_construct(&rxTask, rfEasyLinkRxFnx, &rxTaskParams, NULL);
}
/*
* ======== main ========
*/
int main(void)
{
/* Call board init functions. */
Board_initGeneral();
/* Open LED pins */
ledPinHandle = PIN_open(&ledPinState, pinTable);
if(!ledPinHandle) {
System_abort("Error initializing board LED pins\n");
}
/* Clear LED pins */
PIN_setOutputValue(ledPinHandle, Board_LED1, 0);
PIN_setOutputValue(ledPinHandle, Board_LED2, 0);
rxTask_init(ledPinHandle);
/* Start BIOS */
BIOS_start();
return (0);
}
发送方我用的是smart RF radio 7,如图配置步骤:
以上方式都试过了,但是还是不行,请问会不会可能是烧录M0的固件不同引起的?
这个不太可能,有没有做板子交叉实验,板子发送方变成接收方,板子原来接收方变成发送方
立刻试验了一下,还是不行;出来LRM其他模式都行,这是怎么回事啊!
我把这个接收方的工程整个发给你,发送方你用smartRF软件发送
2677.rfEasyLinkRx_CC1310_LAUNCHXL_TI_CC1310F128.7z
你的例程是
中的,这个例程我烧录不了,一烧录Programmer2就会立刻卡死。
那你之前怎么烧例程的?
我烧的是这个
项目也是kit中的例程改的。
请问这两个例程包有什么不同吗?
对于RF的功能都是一样的,没什么不同
那就奇怪了,代码我逐行看了确实只有就收timeout不一样,但是就是收不到数据。
我得再研究研究,也麻烦您试一下我用的那个例程包中的easylinkrx的程序试一下,
也好确定是我的问题,还是这个例程有问题。
我测试过了,是可以的,看一下我的调试结果:
这是我的debug,永远进入这里的。
时间改大点,1s或者3s试试看,还有你的发送方是用smartRF软件的吗
这样了,还有什么问题啊?
没发现什么问题,我这边也是这样设置,but it works
完了,想不通。香菇!
我能说什么,突然就成功了,我记得前几天刚完成项目的时候试过一次是成功的所以没管他,今天测怎么都不行,现在突然成功了;可是我什么都没改就多试验了几次!怎么解释,总有什么原因引起的吧。
很明显不是软件的问题,很大可能是硬件上的不稳定,电路设计或许焊接等,请问你用的开发板是TI的吗?
都有,有自己设计的有TI的,问题是一样的,刚才有一处改动就是timeout改为了3秒。我得再还回1秒试试。
你的结论有点含糊,多测试几下总结一下原因,欢迎share出来,谢谢
嗯,问题一定要找出来,不然下次遇到了还是不懂。
总结一下今天遇到问题的答案,首先说明硬件设计都没有问题;今天犯了很多小问题,但是这些小问题加在一起就成了不能解决的大问题。
问题一:不管是测试调试,应该保证外接天线一定要连接,经过几次测试发现,即使距离很近板载天线在LRM模式下也会出现丢包,而且办公室的环境复杂,干扰严重,所以外接天线一定要。
问题二:慌乱中胡乱修改发送数据的时间间隔,timeout的时间修改没有问题,但是发送数据的时间间隔若太长接收可能已经timeout,若太短发送可能未完成,当然这一条在LRM中最容易体现,因为发送速率低。
问题三:数据包大小严重影响收发成功,625bps=78B,而我在自己的项目中定义数据包的长度是128,远超过了78,所以我给定的发送间隔500ms更本就不能让数据发送出去,这也是我的项目中发送失败的原因。
今天测试中主要是前两调原因引起的,第三条是我自己项目的问题总结,希望对大家有一点帮助。
谢谢 Eggsy Pang的帮助。
非常感谢你您的分享!
若还遇到什么问题,欢迎发帖,大家互相学习。再次感谢!