⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 homesensorcoord.c

📁 Micro controladores jennic wireless networking zigbee
💻 C
📖 第 1 页 / 共 5 页
字号:
            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 + -