Open the GenericApp project, and in the Workspace we can see these options
Coordinator: Coordinator, RouterEB: Router, EndDevice: Terminal node. Choose different options, and after compilation, different firmware will be generated. Now let’s write a coordinator first.
1. Using the Coordinator Serial Functionality
Add our serial initialization function in the GenericApp.c file within the GenericApp_Init function
halUARTCfg_t uartconfig;
uartconfig.configured = TRUE;
// Set serial port baud rate to 38400
uartconfig.baudRate = HAL_UART_BR_38400;
uartconfig.flowControl = FALSE;
// Set serial port callback function SerialCallBackFunc
uartconfig.callBackFunc = SerialCallBackFunc;
// Open the serial port
HalUARTOpen(0,&uartconfig);
Once powered up, the protocol stack will call the GenericApp_Init function to initialize the serial port, which essentially initializes the registers. If you really don’t understand, you can also directly operate on the registers. However, if you only add the code above, you will find that the serial port is unresponsive. The CC2530 has two serial ports: P02&P03 and P04&P05. Here we generally use P02&P03. Don’t ask me why; I don’t know why I’m accustomed to using this serial port. At this point, we also need to add ZTOOL_P1 in the pre-compile options to enable this serial port. If you are still reading this post, it means you are just starting to learn about ZigBee. For where to find the pre-compile options, please refer to my post on setting up the ZigBee development environment and configuring IAR. Then we write a serial callback function:
static void SerialCallBackFunc(uint8 port, uint8 event)
{
unsigned char serialdata[256];
unsigned char seriallength;
// Read serial data
seriallength = HalUARTRead(0,serialdata,256);
GenericApp_SendTheMessage(serialdata,seriallength,0xFFFF);//0xFFFF broadcast
URX0IF = 0;
}
The return value of HalUARTRead is the current length of the received buffer, which has already been encapsulated by the protocol stack, so you don’t have to concatenate it yourself. Isn’t that great! Now let’s compile it; it will definitely report an error. First, the serial callback function has not been declared, and second, I modified the GenericApp_SendTheMessage function.
Void GenericApp_SendTheMessage(
unsigned char *theMessageData,
unsigned char theMessageDataLength,
unsigned int theMessageAddr )
{
// Use network address transmission
GenericApp_DstAddr.addrMode = (afAddrMode_t)Addr16Bit; // Point-to-point transmission
GenericApp_DstAddr.endPoint = GENERICAPP_ENDPOINT; // Destination address
GenericApp_DstAddr.addr.shortAddr = theMessageAddr; // Call send function
AF_DataRequest( &GenericApp_DstAddr, &GenericApp_epDesc,GENERICAPP_CLUSTERID, theMessageDataLength, theMessageData,&GenericApp_TransID, AF_DISCV_ROUTE, AF_DEFAULT_RADIUS ); }
After modifying the GenericApp_SendTheMessage function, remember to modify its declaration as well. After compiling again, it should be OK. Now all data received on the serial port will be sent to all nodes in this network.
2. Receiving and Sending Wireless Data with the Coordinator
After completing the reception of serial data, let’s see where the coordinator is and how to handle wireless data.
Similarly, in this GenericApp.c file, we find the GenericApp_ProcessEvent function, which is the event handling function for the GenericApp task. In this function, the place for wireless data processing is in the AF_INCOMING_MSG_CMD case. Obviously, after the protocol stack receives wireless data, it calls the GenericApp_MessageMSGCB(MSGpkt); function, passing it the afIncomingMSGPacket_t pointer, which contains data that can be viewed in goto. We won’t elaborate further here. In the GenericApp_MessageMSGCB function, we can process our wireless data.
/* Find the matching cluster ID, what exactly is a cluster ID? Baidu has a lot of information. Here’s a link for everyone to check out:
http://www.360doc.com/content/13/1211/21/14855936_336431501.shtml
*/
switch ( pkt->clusterId )
{
case GENERICAPP_CLUSTERID:
// Add processing for wireless data, directly print to serial port, pkt is the above mentioned afIncomingMSGPacket_t pointer
HalUARTWrite(0,pkt->cmd.Data,pkt->cmd.DataLength); break;
}
Other unnecessary code can actually be deleted, as it’s of no use (unless it’s useful, then leave it be). At this point, the programming for the coordinator is done. Now you can send data to the coordinator through the serial port, and the coordinator will broadcast it to all nodes. If the coordinator receives wireless data, it will also print it out through the serial port.
There’s a pitfall I’ve never understood; sometimes when I print through the serial port, the second byte will be lost inexplicably. Later, I rewrote the HalUARTWrite function, and it worked! If anyone knows why, please enlighten me.
3. Handling Wireless Data and Serial Data in Nodes
Actually, the programming for nodes is quite similar to that for the coordinator. In the Workspace, change the selection to EndDeviceEB
Compilation can also pass, but please note: first, ZTOOL_P1 also needs to be added in the pre-compile; second, in the node’s serial callback function, the data is still sent in broadcast form, meaning all nodes can receive it. Here we only need to send it to the coordinator, so we make the following changes in the serial callback function:
static void SerialCallBackFunc(uint8 port, uint8 event)
{
unsigned char serialdata[256];
unsigned char seriallength;
// Read serial data
seriallength = HalUARTRead(0,serialdata,256);
#if defined (ZDO_COORDINATOR)
// If compiled as a coordinator, broadcast
GenericApp_SendTheMessage(serialdata,seriallength,0xFFFF);//0xFFFF broadcast
#else
// Otherwise, if it’s a router or terminal node, send the data to the coordinator
GenericApp_SendTheMessage(serialdata,seriallength,0x0000);//0x0000 is the coordinator's network address
#endif
URX0IF = 0;
}
Compile and download to the terminal node.
4. Summary
The broadcast speed cannot be too fast; otherwise, you will find that nodes lose packets severely. One reason is that the coordinator needs to buffer the serial data, and another reason is that terminal nodes rely on polling to obtain data from their parent nodes. Excessive use of broadcasting can also cause other issues, such as broadcast storms.
This article is reproduced from Internet of Things.

Long press the left QR code to follow