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

📄 prodtestcoord.c

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

                        /* Send test details */
                        if (sDemoData.sTestData.bTestMode == TRUE)
                        {
                            acEndpointAssociated[3] = '0' - 1 + sDemoData.sNode.u8AssociatedNodes;
                            vSendOnUart(acEndpointAssociated);

                            if (sDemoData.sNode.u8AssociatedNodes == TEST_ENDPOINTS)
                            {
                                /* All nodes are associated so start timer for sync loss
                                   and decide which need to be programmed with new
                                   extended addresses */
                                int i;

                                for (i = 0; i < TEST_ENDPOINTS; i++)
                                {
                                    sDemoData.sTestData.au8SyncLoss[i] = 0;
                                    sDemoData.sNode.asNodeData[i].u8FramesMissed = 0;
                                }
                                sDemoData.sTestData.u8Count = TEST_SYNC_COUNT;
                            }
                        }
                    }
                    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;
    }

    /* Check for anything arriving on UART: this is only used in test mode
       on channel set screen to set channel and start running */
    if ((psHardwareInd->u32DeviceId == E_AHI_DEVICE_UART0)
        && (sDemoData.sSystem.eState == E_STATE_SET_CHANNEL))
    {
        switch (psHardwareInd->u32ItemBitmap & 0xff)
        {
        case E_AHI_UART_INT_RXDATA:
        case E_AHI_UART_INT_TIMEOUT:
            if (sDemoData.sTestData.u8CommandDigit < 3)
            {
                sDemoData.sTestData.acCommand[sDemoData.sTestData.u8CommandDigit]
                    = (char)(psHardwareInd->u32ItemBitmap >> 8);
                sDemoData.sTestData.u8CommandDigit++;

                if (sDemoData.sTestData.u8CommandDigit == 3)
                {
                    if ((sDemoData.sTestData.acCommand[0] == acStartConfigure[0])
                        && (sDemoData.sTestData.acCommand[1] == acStartConfigure[1]))
                    {
                        uint8 u8Channel;

                        u8Channel = sDemoData.sTestData.acCommand[2] - 'A' + 1;
                        if ((u8Channel >= 11) && (u8Channel <= 26))
                        {
                            sDemoData.sTestData.bSensorsTested = FALSE;
                            sDemoData.sTestData.bTestMode = TRUE;
                            sDemoData.sSystem.u8Channel = u8Channel;
                            sDemoData.sNode.bLocalNode = FALSE;
                            vProcessSetupKeyPress(E_KEY_3);
                        }
                    }
                }
            }


            break;
        }
    }

    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++;
        }
        else
        {
            if (u8Node < TEST_ENDPOINTS)
            {
                sDemoData.sTestData.au8SyncLoss[u8Node]++;
            }
        }
    }

    /* 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;
    }
}

/****************************************************************************

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -