主题中讨论的其他器件:CC2520
我们使用 XCC1352P 制作了一个板、并在 IAR 中尝试了非 RTOS Tx 和 Rx 示例程序。
对于 IEEE802.15.4操作、我们已从 SmartRfStudio 导入设置。
TX 和 Rx 示例程序正在运行.. 在 Tx 侧,scheduleCmd ()正在运行,而不是 runCmd ()。
runCmd()不存在。为什么会这样?
然后、我们尝试了 RfEcho 程序。我们有一个包含 CC2520发送周期性(90ms)帧的卡、我们将新板设置为在正确接收后进行回显。
现在,echo 程序不会从 runCmd()中退出。 同时、回显回调函数通过 RfEvntRxEntryDone 执行。 它永远不会进入 RfEvntLastCmdDone 或从 runCmd()退出。 我们能够在内存中看到接收到的数据包。
我们在 Smart RF Studio 中也没有看到任何数据包作为回声发出。
为什么 Rx 之后的 TX cmd 不起作用? 为什么 rndCmd()不退出? 我们如何解决这个问题?
我们用于相同目的的代码如下所示:
#ifndef 回波
#define PAYLOAD_LENGTH 0x1E
静态空回波(RF_Handle h、RF_CmdHandle ch、RF_EventMask e);
/*接收统计数据*/
静态 RFC_ieeeRxOutput_t rxStatistics;
/*将传输(回波)延迟设置为100ms */
#define TX_DELAY (uint32_t)(4000000*0.1f)
void * mainThread (void * arg0)
{
rf_params rfParams;
rf_params_init (&rfParams);
if (RFQueue_defineQueue (&dataQueue、
rxDataEntryBuffer、
sizeof (rxDataEntryBuffer)、
num_data_entries、
PAYLOAD_LENGTH + NUM_apped_bytes))
{
/*未能为所有数据条目分配空间*/
// PIN_setOutputValue (ledPinHandle、Board_PIN_LED1、1);
// PIN_setOutputValue (ledPinHandle、Board_PIN_LED2、1);
while (1);
}
/*根据应用需求修改 CMD_PROP_TX 和 CMD_PROP_RX 命令*/
/*为接收的数据设置数据实体队列*/
rf_cmdIeeeRx.pRxQ =&dataQueue;
rf_cmdIeeeRx.rxConfig.bAutoFlushIgn=1;
/*丢弃来自 Rx 队列的 CRC 错误数据包*/
rf_cmdIeeeRx.rxConfig.bAutoFlushCrc=1;
/*丢弃来自 Rx 队列的已忽略的数据包*/
rf_cmdIeeeRx.rxConfig.bAutoFlushIgn = 1;
/*丢弃来自 Rx 队列的 CRC 错误数据包*/
rf_cmdIeeeRx.rxConfig.bAutoFlushCrc = 1;
/*实施数据包长度过滤以避免 PROP_ERROR_RXBUF */
//rf_cmdIeeeRx.maxPktLen =有效载荷长度;
/*当正确接收到数据包后结束 RX 操作并移到
*链中的下一个命令*/
//RF_cmdIeeeRx。 pktConfig.bRepeatOk = 0;
//rf_cmdIeeeRx.pktConfig.bRepeatNok = 1;
rf_cmdIeeeRx.startTrigger.triggerType = trig_now;
rf_cmdIeeRx.pNextOp =(RFC_radioOP_t *)&rf_cmdIeeeTx;
/*仅在 RX 成功时运行 TX 命令*/
RF_cmdIeeeRx.condition.rule = COND_ALAlways;//COND_STOP_ON_false;
rf_cmdIeeeRx.pOutput =&rxStatistics;
rf_cmdIeeeTx.payloadLen =有效载荷长度;
rf_cmdIeeeTx.pPayload =数据包;
rf_cmdIeeTx.startTrigger.triggerType = trig_now;//trig_REL_PREVEND;
RF_cmdIeeeTx.StartTime = 0;//TX_DELAY;
/*请求对讲机的访问*/
rfHandle = rf_open (&rfObject、&rf_prop、
(RF_RadioSetup*)&RF_cmdRadioSetup、&rfParams);
/*设置频率*/
rf_postCmd (rfHandle、(rf_Op*)&rf_cmdf、rf_PriorityNormal、NULL、0);
while (1)
{
/*等待数据包
*-当两个链接命令(RX)中的第一个完成时
* RF_EventCmdDone 和 RF_EventRxEntryDone 事件在上引发
*成功接收数据包、然后是链中的下一条命令
*(TX)已运行
*-如果接收到数据包后射频内核出现问题
*错误地引发了 RF_EventCmdDone 事件;这是
*错误条件
*-如果射频内核成功地对接收到的数据包进行回波、则射频内核
*应引发 RF_EventLastCmdDone 事件
*
RF_EventMask terminationReason =
rf_runCmd (rfHandle、(rf_Op*)&rf_cmdIeeeRx、rf_PriorityNormal、
回声调、(RF_EventRxEntryDone |
RF_EventLastCmdDone));
/* RF_EventMask terminationReason =
rf_postCmd (rfHandle、(rf_Op*)&rf_cmdIeeeRx、rf_PriorityNormal、
回声调、(RF_EventRxEntryDone |
RF_EventLastCmdDone));
*
/* rf_ScheduleCmd Params_init (&scheduleParam);
scheduleParam.Priority=RF_PriorityNormal;
scheduleParam.allowDelay=0;*/
//RF_CmdHandle cmd=RF_runCmd (rfHandle、(RF_OP*)&RF_cmdIeeeTx、 RF_PriorityNormal、回叫、(RF_EventRxEntryDone |
// RF_EventLastCmdDone);
// RF_CmdHandle cmd=RF_scheduleCmd (rfHandle、(RF_OP*)&RF_cmdIeeeTx、 &scheduleParam、回叫、(RF_EventRxEntryDone |
//RF_EventLastCmdDone);
switch (terminationReason)
{
案例 RF_EventLastCmdDone:
//独立无线电操作命令或最后一个无线电
//链中的操作命令已完成。
中断;
案例 RF_EventCmd 取消:
//命令在启动前被取消;这可能是导致的
//按 RF_cancelCmd ()或 RF_flushCmd ()。
中断;
案例 RF_EventCmdAborted:
//由 RF_cancelCmd ()或导致命令终止突然
// rf_flushCmd ()。
中断;
案例 RF_EventCmdStopped:
// RF_cancelCmd ()或导致正常命令终止
// rf_flushCmd ()。
中断;
默认值:
//未捕捉错误事件
while (1);
}
uint32_t cmdStatus =(volatile rf_Op*)&rf_cmdIeeeRx)-> status;
#ifdef CMD_STATUS
switch (cmdStatus)
{
案例 PROP_DONE_OK:
//接收到的数据包,CRC 正常
中断;
PROP_DONE_RXERR 案例:
//接收到的数据包带有 CRC 错误
中断;
案例 PROP_DONE_RXTIMEOUT:
//同步搜索时观察到的结束触发
中断;
案例 PROP_DONE_break:
//在命令为时接收数据包时观察到结束触发
//配置的 endType 设置为1
中断;
案例 PROP_DONE_ENDended:
//观察完结束触发后收到的数据包;如果
//命令配置为 endType 设置为0,即结束触发器
//不会终止正在进行的接收
中断;
案例 PROP_DONE_STOPPED:
//命令启动后接收到 CMD_STOP,如果发现 SYNC,
//数据包被接收
中断;
案例 PROP_DONE_ABORT:
//命令启动后收到 CMD_ABORT
中断;
PROP_ERROR_RXBUF 案例:
//没有足够大的 RX 缓冲区来存放处可用的接收数据
//数据包开始
中断;
PROP_ERROR_RXFULL 案例:
//在接收部分读取期间超出 RX 缓冲区空间
中断;
案例 PROP_ERROR_PAR:
//观察到非法参数
中断;
PROP_ERROR_NO_SETUP 案例:
//在受支持的中未设置无线电的情况下发送命令
//模式使用 CMD_PROP_RADIO_SETUP 或 CMD_RADIO_SETUP
中断;
案例 PROP_ERROR_NO_FS:
//发送命令而不对合成器进行编程
中断;
案例 PROP_ERROR_RXOVF:
操作期间观察到// RX 溢出
中断;
默认值:
//未捕获的错误事件-这些可能来自
// rf_mailbox.h 中定义的状态池
while (1);
}
#endif
}
}
静态空回波(RF_Handle h、RF_CmdHandle ch、RF_EventMask e)
{
#ifdef log_radio_events
EventLog[evIndex++& 0x1F]= e;
endif// log_radio_events
IF (e 和 RF_EventRxEntryDone)
{
/*成功 RX */
/*切换 LED2、清除 LED1以指示 RX */
// PIN_setOutputValue (ledPinHandle、Board_PIN_LED1、0);
//PIN_setOutputValue (ledPinHandle、Board_PIN_LED2、
// !PIN_getOutputValue (Board_PIN_LED2);
/*获取当前未处理的数据输入*/
currentDataEntry = RFQueue_getDataEntry();
/*处理位于¤tDataEntry->data 的数据包数据:
*-长度是当前配置的第一个字节
*-数据从第二个字节开始*/
packetLength = 19;//0x1E;//*(uint8_t *)(&(currentDataEntry->data));
packetDataPointer =(uint8_t *)(&(currentDataEntry ->数据)+ 1);
/*将有效载荷+状态字节复制到 rxPacket 变量,然后
发送到 txPacket
*
memcpy (packet、packetDataPointer、packetLength);
RFQueue_nextEntry();
}
否则(e 和 RF_EventLastCmdDone)
{
/*成功回波(TX)*/
/*切换 LED2、清除 LED1以指示 RX */
//PIN_setOutputValue (ledPinHandle、Board_PIN_LED1、0);
// PIN_setOutputValue (ledPinHandle、Board_PIN_LED2、
// !PIN_getOutputValue (Board_PIN_LED2);
packetLength = 19;//仅用于调试目的!
}
else //任何未捕获的事件
{
/*错误条件:设置 LED1、清除 LED2 */
// PIN_setOutputValue (ledPinHandle、Board_PIN_LED1、1);
// PIN_setOutputValue (ledPinHandle、Board_PIN_LED2、0);
packetLength = 19;//仅用于调试目的!
}
}
#endif