/****************************************************************************
 *
 * NAME: vProcessKeys
 *
 * 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).
 //偵測最新一次的按鈕後的改變,假使改變了便會在屏幕上顯示最近一次的操作。
 *
 * PARAMETERS:      Name            RW  Usage
 *                  pu8Keys         RW  Persistent value of buttons pressed
 *                                         //壓下按鈕後的固定值
 ****************************************************************************/
PRIVATE void vProcessKeys(uint8 *pu8Keys)
{
    uint8 u8KeysDown; //設置按鍵按下
    uint8 u8NewKeysDown;//新按鍵按下
    u8KeysDown = *pu8Keys; //按鍵按下會等於壓下按鈕的固定值
    /* Process key press */ // 按下按鍵的程序
    u8NewKeysDown = u8ButtonReadFfd(); //讀取按鈕在板子上的狀態
    if (u8NewKeysDown != u8KeysDown)//假使新的鍵相等於設置的鍵
    {
        u8KeysDown = u8NewKeysDown;  //則相等
        /* Key presses depend on mode */  //按鍵決定模式
        switch (sDemoData.sSystem.eState)  //狀態設置
        {
        case E_STATE_SPLASH:  //回應按鍵的值設置資料或者轉至介紹屏幕;JN-3033.p23
            vProcessSplashKeyPress(u8KeysDown);
            break;
        case E_STATE_NETWORK: //回應按鍵的值設置資料或者轉至加入網路屏幕;JN-3033.p23
            vProcessNetworkKeyPress(u8KeysDown);
            break;
        case E_STATE_NODE: // 回應按鍵的值設置資料或者轉至最新接收值的屏幕;JN-3033.p23
            vProcessNodeKeyPress(u8KeysDown);
            break;
        default:
            break;
        }
    }
    /* Store value for use next time */  //儲存下次使用的值
    *pu8Keys = u8KeysDown;
}
/****************************************************************************
 *
 * 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) //設定一個時間參數
{
    u8TimeBlock++; //時間遞增時
    if (u8TimeBlock >= MAX_BLOCKS)  //假如大於等於最大值時
    {
        u8TimeBlock = 0;  //此時的時間區為0
    }
    return u8TimeBlock;  //回傳原本的值
}
/****************************************************************************
 *
 * NAME: vSendData
 *
 * DESCRIPTION:
 * Generates and sends a frame consisting of 1 KVP transaction, for the
 * setting of the LED at the receiving device. The address is provided in the
 * call but the endpoint is fixed. //產生並且傳送一個1個KVP(關鍵值對),以控制一個LED的傳感節點
 *
 * PARAMETERS: Name      RW  Usage
 *             u16Addr   R   Address to send data to //資料傳輸的位置
 *             u8Switch  R   Switch value (0 or 1) //轉換0或1的值
 *
 ****************************************************************************/
PRIVATE void vSendData(uint16 u16Addr, uint8 u8Switch) //設定參數
{
    uint8               u8SrcEP = 0x30;  //源設備的端口號,Source endpoint number
    APS_Addrmode_e      eAddrMode; //接收函數中判斷參數
    AF_Transaction_s    Transaction; //設定一個轉換的結構變量
    uint16              u16DestAddr;
    uint8               u8DestEndpoint;
    uint8               transCount = 1;
    eAddrMode = APS_ADDRMODE_SHORT;
    u16DestAddr = u16Addr;
    u8DestEndpoint = 0x40;
    Transaction.u8SequenceNum = u8AfGetTransactionSequence(TRUE);
    Transaction.uFrame.sKvp.eCommandTypeID = KVP_SET;
    Transaction.uFrame.sKvp.eAttributeDataType = KVP_UNSIGNED_8BIT_INTEGER;
    Transaction.uFrame.sKvp.eErrorCode = KVP_SUCCESS;
    Transaction.uFrame.sKvp.u16AttributeID = 0x0000;
    Transaction.uFrame.sKvp.uAttributeData.UnsignedInt8 = u8Switch;
    afdeDataRequest(eAddrMode,
                    u16DestAddr,
                    u8DestEndpoint,
                    u8SrcEP,
                    DAP_PROFILE_ID,
                    DAP_CID_SWITCH,
                    AF_KVP,
                    transCount,
                    &Transaction,
                    APS_TXOPTION_NONE,
                    ENABLE_ROUTE_DISCOVERY,
                    0);
}
/****************************************************************************
 *
 * 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)// 數據的所繪出的圖規模為0-13
               Temp range is 0-52 //測出溫度的範圍為0-52
               Humidity range is 0-104 //濕度的感測範圍為0-104
               Light range is 0-6 //光的感測範圍為0-6
            */
            for (u8Sensor = 0; u8Sensor < DEMO_SENSOR_LIST_LEN; u8Sensor++)
            {
                psNodeElementData = &psNodeData->asNodeElementData[u8Sensor];
                u8Value = psNodeElementData->u8NowValue; //感測的範圍從0開始到最大值,範圍內取得現在的所測到的值
                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;  //假使得到的值大於13則等於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: vProcessSplashKeyPress
 *
 * DESCRIPTION:
 * Handles button presses on the splash screen. The buttons show the stack
 * version. //按住按鈕後可跳至介紹畫面,可以知道為第幾版本
 *
 * PARAMETERS:      Name        RW  Usage
 *                  u8KeyMap    R   Current buttons pressed bitmap
 *
 * RETURNS:
 * void
 *
 ****************************************************************************/
PRIVATE void vProcessSplashKeyPress(uint8 u8KeyMap)
{
    char acString[9];
    switch (u8KeyMap)
    {
    case E_KEY_0:  //按鍵0時會在LCD板上顯示的字樣
        vUTIL_NumToString(sDemoData.sSystem.u32ZigbeeStackVersion, acString);
        vLcdWriteText("Stack release", 6, 0);
        vLcdWriteText(acString, 6, 80);
        vLcdRefreshAll();
        break;
    case E_KEY_1:  //按鍵1時會在螢幕出現通道的增加
        /* Plus button: increment value */
        sDemoData.sSystem.u8Channel++;
        if (sDemoData.sSystem.u8Channel > CHANNEL_MAX)
        {
            sDemoData.sSystem.u8Channel = CHANNEL_MIN;
        }
        vUpdateSplashScreen();
        break;
    case E_KEY_2: //按鍵2時會在屏幕出現通道的遞減
        /* Minus button: decrement value */
        sDemoData.sSystem.u8Channel--;
        if (sDemoData.sSystem.u8Channel < CHANNEL_MIN)
        {
            sDemoData.sSystem.u8Channel = CHANNEL_MAX;
        }
        vUpdateSplashScreen();
        break;
    case E_KEY_3:    // 選定通道後按按鍵3會跳至加入網路的畫面
        /* Done button: start network and go to network screen */
        sDemoData.sSystem.eState = E_STATE_NETWORK;
        JZS_sConfig.u32Channel = sDemoData.sSystem.u8Channel;
        JZS_vStartStack();
        vBuildNetworkScreen();
        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
 *
 ****************************************************************************/
uint8 u8PermitJoining = 0xff;
PRIVATE void vProcessNetworkKeyPress(uint8 u8KeyMap)
{
    switch (u8KeyMap)
    {
    case E_KEY_0:
        /* Node button: go to node screen (if there are any nodes) */ //如果節點數大於0按鍵0可以跳至節點的屏幕
        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 */ //在節點的銀幕上換至感測溫度的畫面
        sDemoData.sGui.eCurrentSensor = E_SENSOR_TEMP;  //選擇溫度
        u8PermitJoining = 0xff - u8PermitJoining;
        nlmePermitJoiningRequest(u8PermitJoining);
        vBuildNetworkScreen();  //產生畫面
        break;
    case E_KEY_2:
        /* Humidity button: change if not already there */   // 在螢幕上換至感測濕度的畫面
        sDemoData.sGui.eCurrentSensor = E_SENSOR_HTS;  //濕度
        vBuildNetworkScreen();
        break;
    case E_KEY_3:
        /* Temp button: change if not already there */  //同上是亮度
        sDemoData.sGui.eCurrentSensor = E_SENSOR_ALS;
        vBuildNetworkScreen();
        break;
    }
}
/****************************************************************************
 *
 * 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 */  //多個節點加入可按按鍵0換下個節點的畫面
        sDemoData.sGui.u8CurrentNode++; 
        if (sDemoData.sGui.u8CurrentNode == sDemoData.sNode.u8AssociatedNodes) //假使切換至最後一個節點後再按按鍵0
        {
            sDemoData.sSystem.eState = E_STATE_NETWORK; //會跳至節點加入網路的模式
            sDemoData.sGui.eCurrentSensor = E_SENSOR_ALS; //測的數據為光
            vBuildNetworkScreen();
        }
        else
        {
            vBuildNodeScreen(sDemoData.sGui.u8CurrentNode);
        }
        break;
    case E_KEY_2:
        /* Off button */   //可傳送資料控制其他板子為關掉的按鈕
    case E_KEY_3:
        /* On button */    //為開啟的按鈕
        vSendData(sDemoData.sNode.asNodeData[sDemoData.sGui.u8CurrentNode].u16ShortAdr, (u8KeyMap == E_KEY_2) ? 0 : 1);
        break;
    }
}
/****************************************************************************
 *
 * NAME: vUpdateSplashScreen
 *
 * DESCRIPTION:
 * Updates the Splash screen, when it first appears or when the user
 * changes the channel number. //更新啟動畫面,使用者可以切換使用的通道
 *
 * RETURNS:
 * void
 *
 ****************************************************************************/
PRIVATE void vUpdateSplashScreen(void)
{
    char acString[5];
    vValToDec(acString, sDemoData.sSystem.u8Channel, "  "); 
    vLcdWriteText(acString, 7, 16);     //LCD顯示jennicLogo.c的字樣 7,16為LCD上的位置
    vLcdRefreshAll(); 
}
/****************************************************************************
 *
 * NAME: vBuildNetworkScreen
 *
 * DESCRIPTION:
 * Creates the Network screen. Depending on how the GUI has been configured
 * it may want to display up to 3 or up to 4 nodes simultaneuously. Also, it
 * only shows nodes that have successfully associated. To achieve this, it
 * makes use of an array of the four display positions on the screen, and
 * loops through this to position each node in the correct position.
 * //創造加入網路的螢幕,最多可加入3-4個節點,當被接受的節點可顯示在螢幕上,根據先後順序分別有四個位置
 * This function only draws the text required, then uses the related update
 * function to display the actual data and to refresh the LCD.
 * //根據相關的函數來顯示實際數據更新在LCD上
 * PARAMETERS:      Name            RW  Usage
 *                  eSensor         R   Sensor to display
 *
 * RETURNS:
 * void
 *
 ****************************************************************************/
PRIVATE void vBuildNetworkScreen(void)
{
    static const char *apcSensorLabel[DEMO_SENSOR_LIST_LEN] = {
       "Temp", "Humidity", "Light"};  //感測的項目分別有溫度,濕度,亮度
    static const uint8 au8LabelPos[DEMO_SENSOR_LIST_LEN] = {29, 58, 102};
    uint8 u8Node;
    int iIndex;
    teSensor eSensor = sDemoData.sGui.eCurrentSensor;
    vLcdClear();
    if (u8PermitJoining == 0)
    {
        vLcdWriteText("Joining off", 6, 0);  
    }
    else
    {
        vLcdWriteText("Joining on", 6, 0);
    }
    /* Show labels */  //沒有節點的連結時會出現No sensors detected
    if (sDemoData.sNode.u8AssociatedNodes == 0)
    {
        vLcdWriteText("No sensors detected", 3, 0);
    }
    else
    {
        u8Node = 0;
        while ((u8Node < sDemoData.sNode.u8AssociatedNodes) && (u8Node < 4))//當有節點連接時LCD的行列顯示節點的名稱
        {
            vLcdWriteText((char *)apcNodeNameList[u8Node], au8NodeLcdRow[u8Node], au8NodeLcdCol[u8Node]);
            u8Node++;
        }
    }
    /* Hot buttons at bottom of screen */  //螢幕上的熱鍵
    vLcdWriteText("Node", 7, 0);
    for (iIndex = 0; iIndex < DEMO_SENSOR_LIST_LEN; iIndex++)
    {
        vLcdWriteText((char *)apcSensorLabel[iIndex], 7, au8LabelPos[iIndex]);
    }
    vLcdWriteInvertedText((char *)apcSensorLabel[eSensor], 7, au8LabelPos[eSensor]);
    vUpdateNetworkScreen(eSensor);
}
/****************************************************************************
 *
 * NAME: vUpdateNetworkScreen
 *
 * DESCRIPTION:
 * Draws the graphs and values for the Network screen. See the description
 * for vBuildNetworkScreen for an explanation of the positioning of elements
 * on the display.
 * //將所得到的值畫出在顯示器上,更新現有的或之前保留的數據在屏幕上
 * PARAMETERS:      Name            RW  Usage
 *                  eSensor         R   Sensor to display
 *
 * RETURNS:
 * void
 *
 ****************************************************************************/
PRIVATE void vUpdateNetworkScreen(teSensor eSensor)
{
    uint8 u8Node;
    uint8 u8Row;  // 在LCD上分行
    uint8 u8Col;  // 在LCD上分列
   
    u8Node = 0;
    while ((u8Node < sDemoData.sNode.u8AssociatedNodes) && (u8Node < 4)) // node的最大值為4
    {
        u8Row = au8NodeLcdRow[u8Node] + 1; //增加行數
        u8Col = au8NodeLcdCol[u8Node];
        vLcdUpdateElement(&sDemoData.sNode.asNodeData[u8Node], //LCD上節點的基本參數
                          eSensor, u8Row, u8Col, TRUE);
        u8Node++;
    }
    vLcdRefreshAll();
}
/****************************************************************************
 *
 * NAME: vLcdUpdateElement
 *
 * DESCRIPTION:
 * Draws the graph and text for a single sensor for a single node. The text
 * includes alarm indications if the sensor value exceeds user specified
 * limits.
 * //顯示出單一感測器的文字及圖形,當子文字也包含感測的值超出用戶設定的限制提出警告
 * PARAMETERS:  Name                RW  Usage
 *              psNodeElementData   R   Pointer to data for node
 *              u8Row               R   Character row to display on
 *              u8Col               R   Pixel column to display on
 *              boShowInfo          R   TRUE to show missed frames indication
 *
 * RETURNS:
 * void
 *
 ****************************************************************************/
PRIVATE void vLcdUpdateElement(tsNodeData *psNodeData, teSensor eSensor,
                               uint8 u8Row, uint8 u8Col, bool_t boShowInfo)
{
    char acString[10];
    uint8 u8NowValue;
    tsNodeElementData *psNodeElementData = &psNodeData->asNodeElementData[eSensor];
    u8NowValue = psNodeElementData->u8NowValue;
    switch (eSensor)
    {
    case E_SENSOR_TEMP:  //測到的數字加上度C
        vValToDec(acString, u8NowValue, "[C ");
        break;
    case E_SENSOR_HTS:  //測到的數字加上%
        vValToDec(acString, u8NowValue, "% ");
        break;
    case E_SENSOR_ALS:
        /* This is a light sensor so display symbol */   //測到的值以一圖案表示
        acString[0] = '&' + u8NowValue;
        acString[1] = '\0';
        break;
    default:
        break;
    }
    vLcdWriteText(acString, u8Row, u8Col);
    /* Print alarm */
    vLcdWriteText("       ", (uint8)(u8Row + 1), u8Col);
    if (boShowInfo)
    {
        vUTIL_NumToString(psNodeData->u16ShortAdr, acString);
        vLcdWriteText(&acString[4], (uint8)(u8Row + 1), u8Col);
        vValToDec(acString, psNodeData->u8FramesMissed - 1, "");
        vLcdWriteText(acString, (uint8)(u8Row), u8Col + 20);
    }
    /* Draw graph */ //畫圖
    vDrawGraph(psNodeElementData->au8GraphData, (uint8)(u8Col + 27), u8Row);
}
/****************************************************************************
 *
 * NAME: vBuildNodeScreen
 *
 * DESCRIPTION:
 * Builds the text to appear on a Node screen, then uses the update function
 * to populate it with data. //建立了顯示屏幕的節點上的文字,然後使用更新功能來填充它的數據
 *
 * PARAMETERS:      Name            RW  Usage
 *                  u8Node          R   Node to display
 *
 * RETURNS:
 * void
 *
 ****************************************************************************/
PRIVATE void vBuildNodeScreen(uint8 u8Node)
{
    vLcdClear();
    vLcdWriteText((char *)apcNodeNameList[u8Node], 0, 0); //設置名稱
    vLcdWriteText("Humidity", 0, 64);   //後面的數字為在LCD上的位置
    vLcdWriteText("Temp", 3, 0);
    vLcdWriteText("Light", 3, 64);
    vLcdWriteText("Node", 7, 0);
    vLcdWriteText("Off", 7, 75);
    vLcdWriteText("On", 7, 115);
    vUpdateNodeScreen(u8Node);
}
/****************************************************************************
 *
 * NAME: vUpdateNodeScreen
 *
 * DESCRIPTION:
 * Draws the three sensor graphs for a node.
 * //畫出一個節點上的三個感測值
 * PARAMETERS:      Name            RW  Usage
 *                  u8Node          R   Node to display
 *
 * RETURNS:
 * void
 *
 ****************************************************************************/
PRIVATE void vUpdateNodeScreen(uint8 u8Node)
{
    tsNodeData *psNodeData;
    char acString[8];
    psNodeData = &sDemoData.sNode.asNodeData[u8Node];
    /* Status */  //顯示是哪個節點及名稱
    vValToDec(acString, psNodeData->u8FramesMissed - 1, "    ");
    vLcdWriteText(acString, 1, 20);
    /* Update graphs, alarms and values */  //按照位置畫出此節點的溫度,濕度,亮度的圖,
    vLcdUpdateElement(psNodeData, E_SENSOR_TEMP, 4, 0, FALSE);
    vLcdUpdateElement(psNodeData, E_SENSOR_HTS, 1, 64, FALSE);
    vLcdUpdateElement(psNodeData, E_SENSOR_ALS, 4, 64, FALSE);
    vLcdRefreshAll();
}
/****************************************************************************
 *
 * NAME: vDrawGraph
 *
 * DESCRIPTION:
 * Creates a bitmap from an array of values. Each value is represented by a
 * column on the graph, and a lookup table is used to translate each value
 * (assumed to be in the range 0 to 13) to the data required for the bitmap.
 * Finally, the bitmap is displayed via a board API.
 * //產生一個範圍為1-13的點陣圖,值為圖上的所增加的列數
 * PARAMETERS:      Name            RW  Usage
 *                  pu8GraphData    R   Array of 32 elements of graph data
 *                  u8StartCol      R   First column of bitmap
 *                  u8StartRow      R   Top character row of bitmap
 *
 * RETURNS:
 * void
 *
 ****************************************************************************/
PRIVATE void vDrawGraph(uint8 *pu8GraphData, uint8 u8StartCol,
                        uint8 u8StartRow)
{
    static const uint16 au16LineData[14] = {0x4000, 0x6000, 0x7000, 0x7800,
                                            0x7c00, 0x7e00, 0x7f00, 0x7f80,
                                            0x7fc0, 0x7fe0, 0x7ff0, 0x7ff8,
                                            0x7ffc, 0x7ffe}; //範圍為0-13 所以存在14個值
    uint8 au8GraphBitmap[66];
    const tsBitmap sGraphBitmap = {au8GraphBitmap, 33, 2};
    int    i;
    uint16 u16LineData;
    uint8  u8DataPos = sDemoData.sGui.u8GraphPos;
    /* Draw y axis */  //編輯y軸
    au8GraphBitmap[0] = 0xfe;
    au8GraphBitmap[33] = 0x7f;
    /* Fill in data */ //填入資料
    for (i = 0; i < DEMO_HISTORY_LEN; i += 1) //
    {
        u16LineData = au16LineData[pu8GraphData[u8DataPos]];
        au8GraphBitmap[i * 2 + 1] = (uint8)(u16LineData & 0xff);
        au8GraphBitmap[i * 2 + 2] = (uint8)(u16LineData & 0xff);
        au8GraphBitmap[i * 2 + 34] = (uint8)(u16LineData >> 8);
        au8GraphBitmap[i * 2 + 35] = (uint8)(u16LineData >> 8);
                                                   // 繪製圖形隨著變數i的增加顯示在圖形上增加數
        /* Increment data point */ //增量數據點
        u8DataPos = (u8DataPos + 1) & (DEMO_HISTORY_LEN - 1);
    }
    /* Write bitmap to shadow memory */  //內存點陣
    vLcdWriteBitmap((tsBitmap *)&sGraphBitmap, u8StartCol, u8StartRow);
}
/****************************************************************************
 *
 * NAME: vStringCopy
 *
 * DESCRIPTION:
 * Simple string copy as standard libraries not available.
 *
 * PARAMETERS:      Name    RW  Usage
 *                  pcFrom  R   Pointer to string to copy
 *                  pcTo    W   Pointer to store for new string
 *
 * RETURNS:
 * void
 *
 ****************************************************************************/
PRIVATE void vStringCopy(char *pcFrom, char *pcTo)
{
    while (*pcFrom != '\0')
    {
        *pcTo = *pcFrom;
        pcTo++;
        pcFrom++;
    }
    *pcTo = '\0';
}
/****************************************************************************
 *
 * NAME: vValToDec
 *
 * DESCRIPTION:
 * Converts an 8-bit value to a string of the textual decimal representation.
 * Adds a text string after the text.
 *
 * PARAMETERS:      Name            RW  Usage
 *                  pcOutString     R   Location for new string
 *                  u8Value         R   Value to convert
 *                  pcLabel         R   Label to append to string
 *
 * RETURNS:
 * void
 *
 ****************************************************************************/
PRIVATE void vValToDec(char *pcOutString, uint8 u8Value, char *pcLabel)
{
    static const uint8 au8Digits[3] = {100, 10, 1};
    uint8 u8Digit;
    uint8 u8DigitIndex;
    uint8 u8Count;
    bool_t boPreviousDigitPrinted = FALSE;
    for (u8DigitIndex = 0; u8DigitIndex < 3; u8DigitIndex++)
    {
        u8Count = 0;
        u8Digit = au8Digits[u8DigitIndex];
        while (u8Value >= u8Digit)
        {
            u8Value -= u8Digit;
            u8Count++;
        }
        if ((u8Count != 0)  (boPreviousDigitPrinted == TRUE)
             (u8DigitIndex == 2))
        {
            *pcOutString = '0' + u8Count;
            boPreviousDigitPrinted = TRUE;
            pcOutString++;
        }
    }
    vStringCopy(pcLabel, pcOutString);
}
#ifdef TEST_BOS_TIMER
PRIVATE void vTimerFired0(void *pvMessage, uint8 u8Len)
{
    uint8 u8Dummy;
    u8LedFlash0 = 1 - u8LedFlash0;
    vLedControl(0, u8LedFlash0);
    bBosCreateTimer(vTimerFired0, NULL, 0, 10, &u8Dummy);
}
#endif
/****************************************************************************
 *
 * NAME: vAddDesc
 *
 * DESCRIPTION:
 * Draws the three sensor graphs for a node.
 *
 * PARAMETERS:      Name            RW  Usage
 *                  u8Node          R   Node to display
 *
 * RETURNS:
 * void
 *
 ****************************************************************************/
PRIVATE void vAddDesc(void)
{     //控制板為一組輸入一組輸出
    uint8  u8DeviceVer = 0x00;
    uint8  u8Flags = 0x00;
    uint8  u8EndPoint = 0x40;
    uint16 u16DeviceId = 0x0000;
     //        使用相同的組編號為輸入和輸出集群。這意味著從一個節點的輸出組會符合其他節點的輸入組
    uint8 u8InputClusterCnt = 1;
    uint8 au8InputClusterList[] = {DAP_CID_SENSOR_READINGS};
    uint8 u8OutputClusterCnt = 0;
    uint8 au8OutputClusterList[] = {};
    (void)afmeSimpleDescAdd(u8EndPoint, DAP_PROFILE_ID, u16DeviceId,
                            u8DeviceVer, u8Flags, u8InputClusterCnt,
                            au8InputClusterList, u8OutputClusterCnt,
                            au8OutputClusterList);
}
/****************************************************************************/
/***        END OF FILE                                                   ***/
/****************************************************************************/
有些大段的程式碼真的是看不懂還有待研究!!
906~938 1009~1033 1238~1282 1520~1588
這些是看不懂查不到的行數 我會再找看看的!!
連續看了幾天的程式碼發現其實用的語法沒有很多
只是一些設的參數名稱的縮寫要查
大致上的功能看程式碼能看得懂
而這也是Zigbee的API層 也是我們要努力的層
所以要加油
 
沒有留言:
張貼留言