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.

simpliciti中star型 AP_as_Data_Hub 中关于协调器给节点通信的问题

Other Parts Discussed in Thread: SIMPLICITI

我是在cc1110的平台上用的,这个官方给出的例程是star组网,节点ed将信息传输到AP。我现在为了让AP传输信息给ED,然后在AP中写了发送函数,在ED中写了接收函数,都是调用的,但是组网可以成功,但是通信调不通啊,就是AP不能发信息给ED,ED却可以发送信息给AP,还请各位大神指点啊。

这是我在官方例程的基础上修改的,主逻辑是:当有串口信息或者按键被触发的时候,AP就发送信息给ED:

/*----------------------------------------------------------------------------
* Demo Application for SimpliciTI
*
* L. Friedman
* Texas Instruments, Inc.
*----------------------------------------------------------------------------
*/

/**********************************************************************************************
Copyright 2007-2009 Texas Instruments Incorporated. All rights reserved.

IMPORTANT: Your use of this Software is limited to those specific rights granted under
the terms of a software license agreement between the user who downloaded the software,
his/her employer (which must be your employer) and Texas Instruments Incorporated (the
"License"). You may not use this Software unless you agree to abide by the terms of the
License. The License limits your use, and you acknowledge, that the Software may not be
modified, copied or distributed unless embedded on a Texas Instruments microcontroller
or used solely and exclusively in conjunction with a Texas Instruments radio frequency
transceiver, which is integrated into your product. Other than for the foregoing purpose,
you may not use, reproduce, copy, prepare derivative works of, modify, distribute,
perform, display or sell this Software and/or its documentation for any purpose.

YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED 揂S IS?
WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY
WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE.
IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE
THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY
INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST
DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY
THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.

Should you have any questions regarding your right to use this Software,
contact Texas Instruments Incorporated at www.TI.com.
**************************************************************************************************/
#include <string.h>
#include "bsp.h"
#include "mrfi.h"
#include "bsp_leds.h"
#include "bsp_buttons.h"
#include "bsp_buttons.h"
#include "nwk_types.h"
#include "nwk_api.h"
#include "nwk_frame.h"
#include "nwk.h"
#include "nwk_pll.h"

#include "uart_myself.h"
#include "ppp_process.h"
#include "uart_intfc.h"
#include "stdio.h"

#ifndef APP_AUTO_ACK
#error ERROR: Must define the macro APP_AUTO_ACK for this application.
#endif

//#define uart_printf 1 //定义的串口打印


void toggleLED(uint8_t);

/**************************** COMMENTS ON ASYNC LISTEN APPLICATION ***********************
Summary:
This AP build includes implementation of an unknown number of end device peers in
addition to AP functionality. In this scenario all End Devices establish a link to
the AP and only to the AP. The AP acts as a data hub. All End Device peers are on
the AP and not on other distinct ED platforms.

There is still a limit to the number of peers supported on the AP that is defined
by the macro NUM_CONNECTIONS. The AP will support NUM_CONNECTIONS or fewer peers
but the exact number does not need to be known at build time.

In this special but common scenario SimpliciTI restricts each End Device object to a
single connection to the AP. If multiple logical connections are required these must
be accommodated by supporting contexts in the application payload itself.

Solution overview:
When a new peer connection is required the AP main loop must be notified. In essence
the main loop polls a semaphore to know whether to begin listening for a peer Link
request from a new End Device. There are two solutions: automatic notification and
external notification. The only difference between the automatic notification
solution and the external notification solution is how the listen semaphore is
set. In the external notification solution the sempahore is set by the user when the
AP is stimulated for example by a button press or a commend over a serial link. In the
automatic scheme the notification is accomplished as a side effect of a new End Device
joining.

The Rx callback must be implemented. When the callback is invoked with a non-zero
Link ID the handler could set a semaphore that alerts the main work loop that a
SMPL_Receive() can be executed successfully on that Link ID.

If the callback conveys an argument (LinkID) of 0 then a new device has joined the
network. A SMPL_LinkListen() should be executed.

Whether the joining device supports ED objects is indirectly inferred on the joining
device from the setting of the NUM_CONNECTIONS macro. The value of this macro should
be non-zero only if ED objects exist on the device. This macro is always non-zero
for ED-only devices. But Range Extenders may or may not support ED objects. The macro
should be be set to 0 for REs that do not also support ED objects. This prevents the
Access Point from reserving resources for a joinng device that does not support any
End Device Objects and it prevents the AP from executing a SMPL_LinkListen(). The
Access Point will not ever see a Link frame if the joining device does not support
any connections.

Each joining device must execute a SMPL_Link() after receiving the join reply from the
Access Point. The Access Point will be listening.

*************************** END COMMENTS ON ASYNC LISTEN APPLICATION ********************/

/************ THIS SOURCE FILE REPRESENTS THE AUTOMATIC NOTIFICATION SOLUTION ************/

/* reserve space for the maximum possible peer Link IDs */
static linkID_t sLID[NUM_CONNECTIONS] = {0};
static uint8_t sNumCurrentPeers = 0;

/* callback handler */
static uint8_t sCB(linkID_t);

//自定義函数声明:
static uint8_t air_processMessage(linkID_t lid, uint8_t *msg, uint8_t *len);
static uint8_t uart_processMessage(uint8_t *msg, uint8_t *len);

/* received message handler */
static void processMessage(linkID_t, uint8_t *, uint8_t);

/* Frequency Agility helper functions */
static void checkChangeChannel(void);
static void changeChannel(void);

/* work loop semaphores */
static volatile uint8_t sPeerFrameSem = 0;
static volatile uint8_t sJoinSem = 0;

#ifdef FREQUENCY_AGILITY
/* ************** BEGIN interference detection support */

#define INTERFERNCE_THRESHOLD_DBM (-70)
#define SSIZE 25
#define IN_A_ROW 3
static int8_t sSample[SSIZE];
static uint8_t sChannel = 0;
#endif /* FREQUENCY_AGILITY */

/* blink LEDs when channel changes... */
static volatile uint8_t sBlinky = 0;

uint8_t recv_uart_len, recv_uart_msg[MAX_APP_PAYLOAD] ;//串口数据存放地
uint8_t air_msg_len,uart_msg_len;//检测完7E头和7E尾后数据长度

/* ************** END interference detection support */

#define SPIN_ABOUT_A_QUARTER_SECOND NWK_DELAY(250)

uint8_t test_buff[26] = {0x7e,0x11,0x22,0x33,0x44,0x11,0x22,0x00,0x00,0x71,0x56,0x34,0x12,
0x10,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x19,0x14,0x00,0x7e};//测试用的缓存

void main (void)
{
bspIState_t intState;
uint8_t button_flag , uart_flag ; //按键标志位 串口下发数据标志位
uint8_t j,k;
static smplStatus_t rc;
#ifdef FREQUENCY_AGILITY
memset(sSample, 0x0, sizeof(sSample));
#endif

BSP_Init();

/* If an on-the-fly device address is generated it must be done before the
* call to SMPL_Init(). If the address is set here the ROM value will not
* be used. If SMPL_Init() runs before this IOCTL is used the IOCTL call
* will not take effect. One shot only. The IOCTL call below is conformal.
*/
#ifdef I_WANT_TO_CHANGE_DEFAULT_ROM_DEVICE_ADDRESS_PSEUDO_CODE
{
addr_t lAddr;
createRandomAddress(&lAddr);
SMPL_Ioctl(IOCTL_OBJ_ADDR, IOCTL_ACT_SET, &lAddr);
}
#endif /* I_WANT_TO_CHANGE_DEFAULT_ROM_DEVICE_ADDRESS_PSEUDO_CODE */

SMPL_Init(sCB);

/* green and red LEDs on solid to indicate waiting for a Join. */
if (!BSP_LED2_IS_ON())
{
toggleLED(2);
}
if (!BSP_LED1_IS_ON())
{
toggleLED(1);
}

uart_intfc_init(); //串口0初始化
#ifdef uart_printf
printf("AP start to work...\r\n");
#endif

/* main work loop */

while (1)
{
button_flag = 0; //标志位清零
uart_flag=0; //串口标志位清零

/* manage FHSS schedule if FHSS is active */
FHSS_ACTIVE( nwk_pllBackgrounder( false ) );

/* Wait for the Join semaphore to be set by the receipt of a Join frame from a
* device that supports an End Device.
*
* An external method could be used as well. A button press could be connected
* to an ISR and the ISR could set a semaphore that is checked by a function
* call here, or a command shell running in support of a serial connection
* could set a semaphore that is checked by a function call.
*/
if (sJoinSem && (sNumCurrentPeers < NUM_CONNECTIONS)) //入网程序,允许连接8个*****************************
{
/* listen for a new connection */
while (1)
{
if (SMPL_SUCCESS == SMPL_LinkListen(&sLID[sNumCurrentPeers]))
{
break;
}
/* Implement fail-to-link policy here. otherwise, listen again. */
}
sNumCurrentPeers++;
BSP_ENTER_CRITICAL_SECTION(intState);
sJoinSem--;
BSP_EXIT_CRITICAL_SECTION(intState);
}

/* Have we received a frame on one of the ED connections
* No critical section -- it doesn't really matter much if we miss a poll
*/
if (sPeerFrameSem) //对接收到的空中数据进行处理*************
{
uint8_t recv_air_msg[MAX_APP_PAYLOAD], recv_air_len, i;
/* process all frames waiting */
for (i=0; i<sNumCurrentPeers; ++i)
{
if (SMPL_SUCCESS == SMPL_Receive(sLID[i], recv_air_msg, &recv_air_len))
{

#ifdef uart_printf
printf("recv the raw_air_data:");
for(j=0;j<64;j++)
{
printf(" %x",recv_air_msg[j]);
}
printf("\r\n");
#endif


if(0==air_processMessage(sLID[i], recv_air_msg, &air_msg_len)){ //对其进行了头尾检验
toggleLED(2); //闪一下LED3灯,表示接受到空中数据
tx_send_wait( recv_air_msg, air_msg_len ); //将接收到的无线数据串口发送到网关
}
BSP_ENTER_CRITICAL_SECTION(intState);
sPeerFrameSem--;
BSP_EXIT_CRITICAL_SECTION(intState);
}
}
}

if (BSP_BUTTON1()) //检测是否有按键按下 ,用于测试
{
/* calls nwk_pllBackgrounder for us */
SPIN_ABOUT_A_QUARTER_SECOND; /* debounce... */
memcpy(recv_uart_msg,test_buff,sizeof(test_buff));
button_flag = 1; //标志位置1
}

FHSS_ACTIVE( if( nwk_pllBackgrounder( false ) != false ) ); //检测是否有串口数据进来********************
{
recv_uart_len = rx_receive( recv_uart_msg, 50 );
if( recv_uart_len != 0 )
{
uart_flag = 1; //标志位置1
}
}

if (button_flag || uart_flag ) // 有按键按下或者有来自串口的数据
{
// toggleLED(1); // LED1变化表示串口收到数据
if(0==uart_processMessage(recv_uart_msg,&uart_msg_len))
{

for(k=0;k<sNumCurrentPeers;k++)
{
for(j=0;j<4;j++)
{
if( SMPL_SUCCESS == (rc=SMPL_SendOpt( sLID[k], recv_uart_msg, uart_msg_len , SMPL_TXOPTION_ACKREQ)) ) // 立即无线发送出去
{
toggleLED(1); //发送数据成功,灯闪烁
break;
}

}

}
}
// tx_send_wait( recv_uart_msg, uart_msg_len ); //测试用的
}

if (BSP_BUTTON1())
{
SPIN_ABOUT_A_QUARTER_SECOND; /* debounce */
changeChannel();
}
else
{
checkChangeChannel();
}
BSP_ENTER_CRITICAL_SECTION(intState);
if (sBlinky)
{
if (++sBlinky >= 0xF)
{
sBlinky = 1;
toggleLED(1);
toggleLED(2);
}
}
BSP_EXIT_CRITICAL_SECTION(intState);
}
}

void toggleLED(uint8_t which)
{
if (1 == which)
{
BSP_TOGGLE_LED1();
}
else if (2 == which)
{
BSP_TOGGLE_LED2();
}

return;
}

static uint8_t air_processMessage(linkID_t lid, uint8_t *msg, uint8_t *len) //1 数据处理函数
{
uint8_t i;
if(msg[0] == 0x7e){
for(i=1;i<64;i++)
{
if(0x7e==msg[i]){
break;
}
}
if(i != 64){
*len = i+1;
toggleLED(*msg);
return 0;
}
else
return 1;
}
else
return 1;
}
static uint8_t uart_processMessage(uint8_t *msg, uint8_t *len) //2 数据处理函数
{
uint8_t i;
if(msg[0] == 0x7e){
for(i=1;i<64;i++)
{
if(0x7e==msg[i]){
break;
}
}
if(i != 64){
*len = i+1;
toggleLED(*msg);
return 0;
}
else
return 1;
}
else
return 1;
}
/* Runs in ISR context. Reading the frame should be done in the */
/* application thread not in the ISR thread. */
static uint8_t sCB(linkID_t lid) //空中中断
{
if (lid)
{
sPeerFrameSem++;
sBlinky = 0;
}
else
{
sJoinSem++;
}

/* leave frame to be read by application. */
return 0;
}

static void processMessage(linkID_t lid, uint8_t *msg, uint8_t len)
{
/* do something useful */
if (len)
{
toggleLED(*msg);
}
return;
}

static void changeChannel(void)
{
#ifdef FREQUENCY_AGILITY
freqEntry_t freq;

if (++sChannel >= NWK_FREQ_TBL_SIZE)
{
sChannel = 0;
}
freq.logicalChan = sChannel;
SMPL_Ioctl(IOCTL_OBJ_FREQ, IOCTL_ACT_SET, &freq);
BSP_TURN_OFF_LED1();
BSP_TURN_OFF_LED2();
sBlinky = 1;
#endif
return;
}

/* implement auto-channel-change policy here... */
static void checkChangeChannel(void)
{
#ifdef FREQUENCY_AGILITY
int8_t dbm, inARow = 0;

uint8_t i;

memset(sSample, 0x0, SSIZE);
for (i=0; i<SSIZE; ++i)
{
/* quit if we need to service an app frame */
if (sPeerFrameSem || sJoinSem)
{
return;
}
NWK_DELAY(1);
SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RSSI, (void *)&dbm);
sSample[i] = dbm;

if (dbm > INTERFERNCE_THRESHOLD_DBM)
{
if (++inARow == IN_A_ROW)
{
changeChannel();
break;
}
}
else
{
inARow = 0;
}
}
#endif
return;
}


//串口重映射
__near_func int putchar(int ch)
{
tx_send_wait( &ch , 1);
MRFI_DelayMs(1);
return ch;
}