📄 homesensorcoord.c
字号:
psNodeElementData = &psNodeData->asNodeElementData[j];
/* Clear alarms and values */
psNodeElementData->u8NowValue = 0;
psNodeElementData->u8HighAlarm = 0;
psNodeElementData->u8LowAlarm = 255;
/* Clear history list */
pu8GraphData = psNodeElementData->au8GraphData;
for (k = 0; k < DEMO_HISTORY_LEN; k++)
{
*pu8GraphData = 0;
pu8GraphData++;
}
}
}
sDemoData.sNode.bLocalNode = TRUE; /* Default to local node in use */
sDemoData.sNode.u8AssociatedNodes = 1; /* As local node is in use, 1 node is 'associated' */
/* Initialise GUI state */
sDemoData.sGui.eCurrentSensor = E_SENSOR_TEMP;
sDemoData.sGui.u8CurrentNode = 0;
sDemoData.sGui.u8GraphPos = 0;
sDemoData.sGui.u8ControlSelection = 0;
sDemoData.sGui.u8SetupSelection = 0;
sDemoData.sGui.bShowFourNodes = TRUE;
sDemoData.sSystem.u8Channel = CHANNEL_MID;
/* Set light sensor values to 'wrong' ends of range, so the first time
a value is read they will get updated */
sDemoData.sLightSensor.u16Hi = 0;
sDemoData.sLightSensor.u16Lo = 65535;
}
/****************************************************************************
*
* NAME: vSetTimer
*
* DESCRIPTION:
* Sets wake-up timer 0 for a 50ms time-out. Assumes that timer was
* previously enabled.
*
* RETURNS:
* void
*
****************************************************************************/
PRIVATE void vSetTimer(void)
{
/* Set timer for next block */
vAHI_WakeTimerStart(E_AHI_WAKE_TIMER_0, sDemoData.sSystem.u32CalibratedTimeout);
}
/****************************************************************************
*
* NAME: vProcessCurrentTimeBlock
*
* DESCRIPTION:
* Operates a simple state machine. Called 20 times per second, this performs
* several tasks over a 1 second period, with the time split into 50ms blocks.
* In one block it updates the display, in another it starts a reading from
* the temperature, in another it reads the temperature, etc.
*
* PARAMETERS: Name RW Usage
* u8TimeBlock R Current time block, 0-19
*
* RETURNS:
* void
*
* NOTES:
* A value greater than 19 may be used for u8TimeBlock, to ensure that the
* simple state machine remains idle.
*
****************************************************************************/
PRIVATE void vProcessCurrentTimeBlock(uint8 u8TimeBlock)
{
uint8 u8LocalSensor;
uint16 u16LightSensor;
uint16 u16Diff;
/* Process current block scheduled activity */
switch (u8TimeBlock)
{
case BLOCK_UPDATE:
/* Time to update the display */
vProcessUpdateBlock();
/* Also update the information passed back to the endpoints in the
beacon payload */
vUpdateBeaconPayload();
break;
case BLOCK_START_TEMP:
/* Time to start read of the temperature sensor. We read sensors
even if we don't use the data, as the coordinator is assumed to
be a device that doesn't have to be particularly economical on
power */
vHTSstartReadTemp();
break;
case BLOCK_READ_TEMP:
/* Time to read the temperature sensor */
u8LocalSensor = (uint8)u16HTSreadTempResult();
if (u8LocalSensor > 52)
{
u8LocalSensor = 52;
}
if (sDemoData.sNode.bLocalNode)
{
sDemoData.sNode.asNodeData[0].asNodeElementData[E_SENSOR_TEMP].u8NowValue = u8LocalSensor;
sDemoData.sNode.asNodeData[0].u8FramesMissed = 0;
}
break;
case BLOCK_START_HUMIDITY:
/* Time to start a read of the humidity sensor */
vHTSstartReadHumidity();
break;
case BLOCK_READ_HUMIDITY:
/* Time to read the humidity sensor */
u8LocalSensor = (uint8)u16HTSreadHumidityResult();
if (u8LocalSensor > 104)
{
u8LocalSensor = 104;
}
if (sDemoData.sNode.bLocalNode)
{
sDemoData.sNode.asNodeData[0].asNodeElementData[E_SENSOR_HTS].u8NowValue = u8LocalSensor;
}
break;
case BLOCK_READ_LIGHT:
/* Time to read the light sensor. This sensor automatically starts
a new conversion afterwards so there is no need for a 'start read' */
u16LightSensor = u16ALSreadChannelResult();
/* Adjust the high and low values if necessary, and obtain the
difference between them */
if (sDemoData.sLightSensor.u16Hi < u16LightSensor)
{
sDemoData.sLightSensor.u16Hi = u16LightSensor;
}
if (sDemoData.sLightSensor.u16Lo > u16LightSensor)
{
sDemoData.sLightSensor.u16Lo = u16LightSensor;
}
u16Diff = sDemoData.sLightSensor.u16Hi - sDemoData.sLightSensor.u16Lo;
/* Work out the current value as a value between 0 and 6 within the
range of values that have been seen previously */
if (u16Diff)
{
u8LocalSensor = (uint8)(((uint32)(u16LightSensor - sDemoData.sLightSensor.u16Lo) * 6) / (uint32)u16Diff);
}
else
{
u8LocalSensor = 0;
}
if (sDemoData.sNode.bLocalNode)
{
sDemoData.sNode.asNodeData[0].asNodeElementData[E_SENSOR_ALS].u8NowValue = u8LocalSensor;
}
break;
}
}
/****************************************************************************
*
* NAME: bProcessKeys
*
* DESCRIPTION:
* Gets the latest button presses and detects any change since the last time
* the buttons were checked. If there is a change it is passed to the
* individual handler for the screen currently being displayed (the buttons
* are all 'soft' keys so their meaning changes from screen to screen). The
* exception to this is a button combination that causes the software to
* shutdown and stop the LCD. There is also a reset combination.
*
* PARAMETERS: Name RW Usage
* pu8Keys RW Persistent value of buttons pressed
*
* RETURNS:
* TRUE if reset combination is pressed
*
****************************************************************************/
PRIVATE bool_t bProcessKeys(uint8 *pu8Keys)
{
uint8 u8KeysDown;
uint8 u8NewKeysDown;
u8KeysDown = *pu8Keys;
/* Process key press */
u8NewKeysDown = u8ButtonReadFfd();
if (u8NewKeysDown != 0)
{
if ((u8NewKeysDown | u8KeysDown) != u8KeysDown)
{
/* Logical OR values to enable multiple keys at once */
u8KeysDown |= u8NewKeysDown;
/* Key presses depend on mode */
switch (sDemoData.sSystem.eState)
{
case E_STATE_NETWORK:
vProcessNetworkKeyPress(u8KeysDown);
break;
case E_STATE_NODE:
vProcessNodeKeyPress(u8KeysDown);
break;
case E_STATE_NODE_CONTROL:
vProcessNodeControlKeyPress(u8KeysDown);
break;
case E_STATE_SET_CHANNEL:
vProcessSetChannelKeyPress(u8KeysDown);
break;
case E_STATE_SETUP_SCREEN:
vProcessSetupKeyPress(u8KeysDown);
break;
default:
break;
}
}
}
else
{
u8KeysDown = 0;
}
/* Store value for use next time */
*pu8Keys = u8KeysDown;
return (u8KeysDown == E_KEYS_0_AND_3);
}
/****************************************************************************
*
* NAME: u8UpdateTimeBlock
*
* DESCRIPTION:
* Moves the state machine time block on by one time period.
*
* PARAMETERS: Name RW Usage
* u8TimeBlock R Previous time block
*
* RETURNS:
* uint8 Next time block
*
****************************************************************************/
PRIVATE uint8 u8UpdateTimeBlock(uint8 u8TimeBlock)
{
/* Update block state for next time, if in a state where regular
updates should be performed */
if ((sDemoData.sSystem.eState != E_STATE_SET_CHANNEL)
&& (sDemoData.sSystem.eState != E_STATE_SETUP_SCREEN)
&& (sDemoData.sSystem.eState != E_STATE_SCANNING))
{
u8TimeBlock++;
if (u8TimeBlock >= MAX_BLOCKS)
{
u8TimeBlock = 0;
}
}
return u8TimeBlock;
}
/****************************************************************************
*
* NAME: vProcessInterrupts
*
* DESCRIPTION:
* Loops around checking for upward events from the Application Queue API.
* To save power, the CPU is set to doze at the start of the loop. If an event
* is generated, the CPU is woken up and processes it, then the code here is
* allowed to continue.
* For each type of event, the queue is checked and, if there is something to
* process, the appropriate handler is called. The buffer is then returned to
* the Application Queue API. This continues until all events have been
* processed. If the hardware event handler detects that a timeout has
* happened, the loop is exited.
*
* RETURNS:
* void when a timeout is detected
*
* NOTES:
* There is a possibility of the system locking up if an interrupt is
* generated and handled by the Application Queue API just before the request
* to doze the CPU. Normally there won't be an issue as the wake-up timer will
* generate an interrupt eventually, but it is theoretically possible that an
* MLME or MCPS event just before the timer fires could create this situation
* (has never been seen in practice). An easy solution is to use the second
* wake-up timer as a watchdog.
*
****************************************************************************/
PRIVATE void vProcessInterrupts(void)
{
MAC_MlmeDcfmInd_s *psMlmeInd;
MAC_McpsDcfmInd_s *psMcpsInd;
AppQApiHwInd_s *psAHI_Ind;
bool_t bDone;
/* Wait for events */
bDone = FALSE;
do
{
/* Doze CPU: it will wake when interrupt occurs, then process
interrupts, then this code will be able to process queue */
vAHI_CpuDoze();
/* Check for anything on the MCPS upward queue */
do
{
psMcpsInd = psAppQApiReadMcpsInd();
if (psMcpsInd != NULL)
{
vProcessIncomingData(psMcpsInd);
vAppQApiReturnMcpsIndBuffer(psMcpsInd);
}
} while (psMcpsInd != NULL);
/* Check for anything on the MLME upward queue */
do
{
psMlmeInd = psAppQApiReadMlmeInd();
if (psMlmeInd != NULL)
{
vProcessIncomingMlme(psMlmeInd);
vAppQApiReturnMlmeIndBuffer(psMlmeInd);
}
} while (psMlmeInd != NULL);
/* Check for anything on the AHI upward queue */
do
{
psAHI_Ind = psAppQApiReadHwInd();
if (psAHI_Ind != NULL)
{
if (bProcessForTimeout(psAHI_Ind) == TRUE)
{
bDone = TRUE;
}
vAppQApiReturnHwIndBuffer(psAHI_Ind);
}
} while (psAHI_Ind != NULL);
} while (bDone == FALSE);
}
/****************************************************************************
*
* NAME: vProcessIncomingData
*
* DESCRIPTION:
* Deals with any incoming MCPS data events. If the event is an indication
* from a device with a short address matching a demo endpoint, the data in
* the payload is stored for display the next time that the LCD is updated.
*
* PARAMETERS: Name RW Usage
* psMcpsInd R Pointer to structure containing MCPS event
*
* RETURNS:
* void
*
****************************************************************************/
PRIVATE void vProcessIncomingData(MAC_McpsDcfmInd_s *psMcpsInd)
{
MAC_RxFrameData_s *psFrame;
MAC_Addr_s *psAddr;
tsNodeData *psNodeData;
uint16 u16NodeAddr;
uint8 u8Node;
uint8 u8Count;
psFrame = &psMcpsInd->uParam.sIndData.sFrame;
/* Check that MCPS frame is a valid sensor one */
if ((psMcpsInd->u8Type != MAC_MCPS_IND_DATA)
|| (psFrame->u8SduLength != 8)
|| (psFrame->au8Sdu[0] != DEMO_ENDPOINT_IDENTIFIER))
{
return;
}
/* Use address to determine node */
psAddr = &psFrame->sSrcAddr;
if (psAddr->u8AddrMode != 2)
{
return;
}
u16NodeAddr = psAddr->uAddr.u16Short;
if ((u16NodeAddr < DEMO_ENDPOINT_ADDR_BASE)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -