📄 homesensorcoord.c
字号:
|| (u16NodeAddr >= (DEMO_ENDPOINT_ADDR_BASE + DEMO_ENDPOINTS)))
{
return;
}
/* Store data for node */
u8Node = (uint8)(u16NodeAddr - DEMO_ENDPOINT_ADDR_BASE);
psNodeData = &sDemoData.sNode.asNodeData[u8Node];
psNodeData->u8FramesMissed = 0;
psNodeData->u8SwitchOn = psFrame->au8Sdu[2];
vLedControl(u8Node, psNodeData->u8SwitchOn);
for (u8Count = 0; u8Count < DEMO_SENSOR_LIST_LEN; u8Count++)
{
psNodeData->asNodeElementData[u8Count].u8NowValue = psFrame->au8Sdu[u8Count + 3];
}
psNodeData->u8Rssi = psFrame->u8LinkQuality;
}
/****************************************************************************
*
* NAME: vProcessIncomingMlme
*
* DESCRIPTION:
* Deals with any incoming MCPS events. If the event is an indication that
* device wants to associate, goes through a process to determine a short
* address for the device, either as 'next on the list' or the same address
* that was proviously given if the device has associated before. Then sends
* an association response via the stack.
*
* For debug purposes, also displays any Communication Status indications.
*
* PARAMETERS: Name RW Usage
* psMlmeInd R Pointer to structure containing MLME event
*
* RETURNS:
* void
*
****************************************************************************/
PRIVATE void vProcessIncomingMlme(MAC_MlmeDcfmInd_s *psMlmeInd)
{
MAC_MlmeReqRsp_s sMlmeReqRsp;
MAC_MlmeSyncCfm_s sMlmeSyncCfm;
uint16 u16ShortAddress;
uint8 u8Node;
uint8 u8AssocStatus;
switch (psMlmeInd->u8Type)
{
case MAC_MLME_IND_ASSOCIATE:
/* Only respond if in network or node modes. We aren't a coordinator
until then */
if ((sDemoData.sSystem.eState == E_STATE_NETWORK)
|| (sDemoData.sSystem.eState == E_STATE_NODE)
|| (sDemoData.sSystem.eState == E_STATE_NODE_CONTROL))
{
/* Default short address */
u16ShortAddress = 0xffff;
/* Check node extended address matches and device wants short address
(for the demo, we only use short address) */
if (psMlmeInd->uParam.sIndAssociate.u8Capability & 0x80)
{
/* Check if already associated (idiot proofing) */
u8Node = 0;
while (u8Node < sDemoData.sNode.u8AssociatedNodes)
{
if ((psMlmeInd->uParam.sIndAssociate.sDeviceAddr.u32L == sDemoData.sNode.asAssocNodes[u8Node].sExtAddr.u32L) &&
(psMlmeInd->uParam.sIndAssociate.sDeviceAddr.u32H == sDemoData.sNode.asAssocNodes[u8Node].sExtAddr.u32H))
{
/* Already in system: give it same short address */
u16ShortAddress = sDemoData.sNode.asAssocNodes[u8Node].u16ShortAddr;
}
u8Node++;
}
/* Assume association succeeded */
u8AssocStatus = 0;
if (u16ShortAddress == 0xffff)
{
if (sDemoData.sNode.u8AssociatedNodes < DEMO_ENDPOINTS)
{
/* Allocate short address as next in list */
u16ShortAddress = DEMO_ENDPOINT_ADDR_BASE + sDemoData.sNode.u8AssociatedNodes;
/* Store details for future use */
sDemoData.sNode.asAssocNodes[sDemoData.sNode.u8AssociatedNodes].sExtAddr = psMlmeInd->uParam.sIndAssociate.sDeviceAddr;
sDemoData.sNode.asAssocNodes[sDemoData.sNode.u8AssociatedNodes].u16ShortAddr = u16ShortAddress;
sDemoData.sNode.u8AssociatedNodes++;
}
else
{
/* PAN access denied */
u8AssocStatus = 2;
}
}
/* Update display if necessary */
if (sDemoData.sSystem.eState == E_STATE_NETWORK)
{
vBuildNetworkScreen(sDemoData.sGui.eCurrentSensor);
}
}
else
{
/* PAN access denied */
u8AssocStatus = 2;
}
/* Create association response */
sMlmeReqRsp.u8Type = MAC_MLME_RSP_ASSOCIATE;
sMlmeReqRsp.u8ParamLength = sizeof(MAC_MlmeRspAssociate_s);
sMlmeReqRsp.uParam.sRspAssociate.sDeviceAddr = psMlmeInd->uParam.sIndAssociate.sDeviceAddr;
sMlmeReqRsp.uParam.sRspAssociate.u16AssocShortAddr = u16ShortAddress;
sMlmeReqRsp.uParam.sRspAssociate.u8Status = u8AssocStatus;
sMlmeReqRsp.uParam.sRspAssociate.u8SecurityEnable = FALSE;
/* Send association response */
vAppApiMlmeRequest(&sMlmeReqRsp, &sMlmeSyncCfm);
/* There is no confirmation for an association response, hence no need to check */
}
break;
}
}
/****************************************************************************
*
* NAME: bProcessForTimeout
*
* DESCRIPTION:
* Processes any incoming hardware events to see if the event is wake-up
* timer 0 firing, as this is the only hardware event responded to.
*
* PARAMETERS: Name RW Usage
* psHardwareInd R Pointer to structure containing hardware event
*
* RETURNS:
* TRUE if event was wake-up timer 0 firing.
*
****************************************************************************/
PRIVATE bool_t bProcessForTimeout(AppQApiHwInd_s *psHardwareInd)
{
/* Check to see if hardware indication was for wake timer 0 */
if ((psHardwareInd->u32DeviceId == E_AHI_DEVICE_SYSCTRL)
&& (psHardwareInd->u32ItemBitmap & (1 << E_AHI_SYSCTRL_WK0)))
{
return TRUE;
}
return FALSE;
}
/****************************************************************************
*
* NAME: vProcessUpdateBlock
*
* DESCRIPTION:
* Called once per second to update the scrolling graphs and, if showing a
* screen with graphs on, updating the LCD.
*
* RETURNS:
* void
*
****************************************************************************/
PRIVATE void vProcessUpdateBlock(void)
{
tsNodeData *psNodeData;
tsNodeElementData *psNodeElementData;
uint8 *pu8GraphData;
uint8 u8PrevPoint;
uint8 u8Node;
uint8 u8Sensor;
uint8 u8Value;
/* Update graphs */
for (u8Node = 0; u8Node < DEMO_ENDPOINTS; u8Node++)
{
psNodeData = &sDemoData.sNode.asNodeData[u8Node];
if (psNodeData->u8FramesMissed)
{
/* Missed data, so copy previous value forward */
u8PrevPoint = (sDemoData.sGui.u8GraphPos - 1) & (DEMO_HISTORY_LEN - 1);
for (u8Sensor = 0; u8Sensor < DEMO_SENSOR_LIST_LEN; u8Sensor++)
{
pu8GraphData = psNodeData->asNodeElementData[u8Sensor].au8GraphData;
pu8GraphData[sDemoData.sGui.u8GraphPos] = pu8GraphData[u8PrevPoint];
}
}
else
{
/* Data must be scaled for graph (0-13)
Temp range is 0-52
Humidity range is 0-104
Light range is 0-6
*/
for (u8Sensor = 0; u8Sensor < DEMO_SENSOR_LIST_LEN; u8Sensor++)
{
psNodeElementData = &psNodeData->asNodeElementData[u8Sensor];
u8Value = psNodeElementData->u8NowValue;
switch (u8Sensor)
{
case E_SENSOR_TEMP:
u8Value = u8Value >> 2;
break;
case E_SENSOR_HTS:
u8Value = u8Value >> 3;
break;
case E_SENSOR_ALS:
u8Value = u8Value * 2;
break;
}
if (u8Value > 13)
{
u8Value = 13;
}
psNodeElementData->au8GraphData[sDemoData.sGui.u8GraphPos] = u8Value;
}
}
/* For next time, assume failed until proven otherwise */
if (psNodeData->u8FramesMissed < FRAMES_MISSED_INDICATION)
{
psNodeData->u8FramesMissed++;
}
}
/* Increment graph position */
sDemoData.sGui.u8GraphPos = (sDemoData.sGui.u8GraphPos + 1) & (DEMO_HISTORY_LEN - 1);
/* Update display */
switch (sDemoData.sSystem.eState)
{
case E_STATE_NETWORK:
vUpdateNetworkScreen(sDemoData.sGui.eCurrentSensor);
break;
case E_STATE_NODE:
vUpdateNodeScreen(sDemoData.sGui.u8CurrentNode);
break;
default:
break;
}
}
/****************************************************************************
*
* NAME: vProcessSetChannelKeyPress
*
* DESCRIPTION:
* Handles button presses on the Set Channel screen. There is one parameter
* that can be adjusted (the channel) and buttons to navigate to two other
* screens.
*
* PARAMETERS: Name RW Usage
* u8KeyMap R Current buttons pressed bitmap
*
* RETURNS:
* void
*
****************************************************************************/
PRIVATE void vProcessSetChannelKeyPress(uint8 u8KeyMap)
{
switch (u8KeyMap)
{
case E_KEY_0:
/* Further setup button: go to setup screen */
sDemoData.sSystem.eState = E_STATE_SETUP_SCREEN;
vBuildSetupScreen();
break;
case E_KEY_1:
/* Plus button: increment value */
case E_KEY_2:
/* Minus button: decrement value */
vAdjustAlarm(&sDemoData.sSystem.u8Channel, CHANNEL_MAX, CHANNEL_MIN, u8KeyMap == E_KEY_1);
vUpdateSetChannelScreen();
break;
case E_KEY_3:
/* Done button: start beaconing and go to network screen */
vStartBeacon();
sDemoData.sSystem.eState = E_STATE_NETWORK;
vBuildNetworkScreen(sDemoData.sGui.eCurrentSensor);
break;
default:
break;
}
}
/****************************************************************************
*
* NAME: vProcessNetworkKeyPress
*
* DESCRIPTION:
* Handles button presses on the Network screen. The buttons can move onto
* the first Node screen (if there are any nodes) or select a particular
* sensor.
*
* PARAMETERS: Name RW Usage
* u8KeyMap R Current buttons pressed bitmap
*
* RETURNS:
* void
*
****************************************************************************/
PRIVATE void vProcessNetworkKeyPress(uint8 u8KeyMap)
{
switch (u8KeyMap)
{
case E_KEY_0:
/* Node button: go to node screen (if there are any nodes) */
if (sDemoData.sNode.u8AssociatedNodes > 0)
{
sDemoData.sSystem.eState = E_STATE_NODE;
sDemoData.sGui.u8CurrentNode = 0;
vBuildNodeScreen(sDemoData.sGui.u8CurrentNode);
}
break;
case E_KEY_1:
/* Temp button: change if not already there */
vUpdateNetworkSensor(E_SENSOR_TEMP);
break;
case E_KEY_2:
/* Humidity button: change if not already there */
vUpdateNetworkSensor(E_SENSOR_HTS);
break;
case E_KEY_3:
/* Temp button: change if not already there */
vUpdateNetworkSensor(E_SENSOR_ALS);
break;
}
}
/****************************************************************************
*
* NAME: vUpdateNetworkSensor
*
* DESCRIPTION:
* Simple function to save a little code. If the user presses a button on the
* Network screen to select a sensor, this checks that the sensor is not the
* same as the current sensor before updating the screen.
*
* PARAMETERS: Name RW Usage
* eSensor R New sensor to display
*
* RETURNS:
* void
*
****************************************************************************/
PRIVATE void vUpdateNetworkSensor(teSensor eSensor)
{
if (sDemoData.sGui.eCurrentSensor != eSensor)
{
sDemoData.sGui.eCurrentSensor = eSensor;
vBuildNetworkScreen(eSensor);
}
}
/****************************************************************************
*
* NAME: vProcessNodeKeyPress
*
* DESCRIPTION:
* Handles button presses on the Node screens. The first button can move to
* the next Node screen (if there are any more nodes) or back to the Network
* screen. Another button selects the Node Control screen and the other two
* toggle the state of the remote switch.
*
* PARAMETERS: Name RW Usage
* u8KeyMap R Current buttons pressed bitmap
*
* RETURNS:
* void
*
****************************************************************************/
PRIVATE void vProcessNodeKeyPress(uint8 u8KeyMap)
{
switch (u8KeyMap)
{
case E_KEY_0:
/* Node button: go to next node or network screen */
sDemoData.sGui.u8CurrentNode++;
if (sDemoData.sGui.u8CurrentNode == sDemoData.sNode.u8AssociatedNodes)
{
sDemoData.sSystem.eState = E_STATE_NETWORK;
sDemoData.sGui.eCurrentSensor = E_SENSOR_TEMP;
vBuildNetworkScreen(E_SENSOR_TEMP);
}
else
{
vBuildNodeScreen(sDemoData.sGui.u8CurrentNode);
}
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -