/*****************************************************************************
 *
 * MODULE:             JN-AN-1158 (Receiver)
 *
 * COMPONENT:          Receiver.c
 *
 * AUTHOR:             JMB
 *
 * DESCRIPTION:        Receiver
 *
 * $HeadURL $
 *
 * $Revision: 11878 $
 *
 * $LastChangedBy: nxp46755 $
 *
 * $LastChangedDate: 2013-11-14 03:57:27 +0000 (Thu, 14 Nov 2013) $
 *
 * $Id: Receiver.c 11878 2013-11-14 03:57:27Z nxp46755 $
 *
 *
 ****************************************************************************
 *
 * This software is owned by NXP B.V. and/or its supplier and is protected
 * under applicable copyright laws. All rights are reserved. We grant You,
 * and any third parties, a license to use this software solely and
 * exclusively on NXP products [NXP Microcontrollers such as JN5148, JN5142,
 * JN5139]. You, and any third parties must reproduce the copyright and
 * warranty notice and any other legend of ownership on each copy or partial
 * copy of the software.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * Copyright NXP B.V. 2012. All rights reserved
 *
 ***************************************************************************/

/****************************************************************************/
/***        Include files                                                 ***/
/****************************************************************************/
#include <stdarg.h>
#include <ctype.h>
#include <jendefs.h>
#include <AppHardwareApi.h>
#include <AppQueueApi.h>
#include <mac_sap.h>
#include <mac_pib.h>
#include <Utilities.h>
#include "Printf.h"
#include <Config.h>
#include "LcdDriver.h"
#include "Button.h"
#include "LcdFont.h"
#include "RF4CE_API.h"
#include "ZRC.h"
#include "ZID.h"
#if (defined STACK_MEASURE)
    #include "StackMeasure.h"
#endif

extern void vRF4CE_ImpConfigChan(uint8 u8Channels,   uint8 u8MinChannel,
                                 uint8 u8MidChannel, uint8 u8MaxChannel);
/****************************************************************************/
/***        Macro Definitions                                             ***/
/****************************************************************************/

#define     E_KEY_0     BUTTON_0_MASK
#define     E_KEY_1     BUTTON_1_MASK
#define     E_KEY_2     BUTTON_2_MASK
#define     E_KEY_3     BUTTON_3_MASK

/****************************************************************************/
/***        Type Definitions                                              ***/
/****************************************************************************/

typedef enum
{
    E_PRE_START,
    E_COLD_START,
    E_START_COMPLETE,
    E_WAIT_FOR_KEY,
    E_WAIT_FOR_DISCOVERY,
    E_PAIRING,
    E_WAIT_FOR_PAIRING,
    E_PAIRED,
    E_EXCEPT_PAIRING,
    E_UNPAIR,
    E_WAIT_FOR_UNPAIRING,
    E_RUNNING,
    E_TRANSMITTING,
    E_PRE_WARMSTART,
    E_WARMSTART
} teState;

typedef enum
{
    E_TX_CMD_ACK                 = 0x01,
    E_TX_CMD_RESET                = 0x02,
    E_TX_CMD_NET_STARTED        = 0x03,
    E_TX_CMD_ASS_REQ            = 0x04,
    E_TX_CMD_DATA_RX            = 0x05,
    E_TX_CMD_TX_DONE            = 0x06,
    E_TX_CMD_READ_RES            = 0x07,
    E_TX_CMD_BLANK                = 0x08,
    E_TX_CMD_UNPAIR                = 0x09
}teTX_COMMANDS;
/****************************************************************************/
/***        Local Function Prototypes                                     ***/
/****************************************************************************/

/****************************************************************************/
/***        Exported Variables                                            ***/
/****************************************************************************/

/****************************************************************************/
/***        Local Variables                                               ***/
/****************************************************************************/
tuRF4CE_NibValue     NibValue;

PRIVATE volatile teState        eState;
PRIVATE uint8              u8RemotePairingRef;
PRIVATE uint8              u8ReceiverBuffer[255];
#if (defined STACK_MEASURE)
    tsStackInfo sStackInfo;
    extern uint32 heap_location;
    uint32 u32HeapPointer;
#endif
/****************************************************************************/
/***        Exported Functions                                            ***/
/****************************************************************************/
extern uint8 gMAC_u8MaxBuffers;
/****************************************************************************/
/***        Local Functions                                               ***/
/****************************************************************************/
PRIVATE void vInitSystem(void);
PRIVATE void  vIdleLoop(void);

PRIVATE void vValToDec(char *pcOutString, uint8 u8Value, char *pcLabel);
PRIVATE void vStringCopy(char *pcFrom, char *pcTo);
PUBLIC void vLongToString(char * str, uint32 u32Num);
PRIVATE void vSendCommand(uint8 u8Count);
PUBLIC void vUART_RxCharISR(void);
PUBLIC void vUtils_ValToHex(char *pcString, uint32 u32Data, int iSize);
PUBLIC void vUartReset(void);

/****************************************************************************
 *
 * NAME: AppColdStart
 *
 * DESCRIPTION:
 * Runs application.
 *
 * PARAMETERS:      Name            RW  Usage
 * None.
 *
 * RETURNS:
 * None.
 *
 * NOTES:
 * Entry point for a power on reset or wake from sleep mode.
 ****************************************************************************/
PUBLIC void AppColdStart(void)
{
    gMAC_u8MaxBuffers = 2;
    uint8 const u8NodeCapability = RF4CE_NODECAP_TYPE_TARGET
                                       | RF4CE_NODECAP_PWRSRC_MAINS
                                       | RF4CE_NODECAP_SECURITY_CAPABLE
                                       | RF4CE_NODECAP_CHANNORM_CAPABLE;
    uint16 const u16VendorId = 0xfff1;

    #ifdef JENNIC_CHIP_FAMILY_JN516x
        /* Turn off debugger */
        *(volatile uint32 *)0x020000a0 = 0;
    #endif

    #if WATCHDOG_ENABLED
    {
        vAHI_WatchdogStop();
    }
    #endif

    /* General initialisation */
    vInitSystem();

    /* Initialise stack (implementation-specific command) */
    if (bRF4CE_ImpInit(u8NodeCapability, u16VendorId, (uint8 *)"JennicT"))
    {
        vRF4CE_ImpConfigChan(3, 15, 20, 25);
        /* Cold start: reset and clear NIB, then start stack */
        eState = E_PRE_START;
        /* Stack start is asynchronous so enter idle loop waiting for stack to
           complete start-up sequence */
    }
    else
    {
        vRF4CE_ImpConfigChan(3, 15, 20, 25);
        eState = E_PRE_WARMSTART;
    }
    /* Go to idle loop */
    vIdleLoop();
}

/****************************************************************************
 *
 * NAME: vRF4CE_StackEvent
 *
 * DESCRIPTION:
 *
 *
 * PARAMETERS:      Name            RW  Usage
 * None.
 *
 * RETURNS:
 * None.
 *
 * NOTES:
 * None.
 ****************************************************************************/
PUBLIC void vRF4CE_StackEvent(teRF4CE_EventType eEvent,
                              tuRF4CE_EventParam *puParam)
{
    char dis_lcd[50]={'\0'};

        switch (eEvent)
        {
        case E_RF4CE_EV_START_CFM:      /* Use with tsRF4CE_NlmeStartCfm */
            if (E_RF4CE_STATUS_SUCCESS == puParam->sNlmeStartCfm.eStatus)
            {
                /* Now running */
                eState = E_START_COMPLETE;
            }
            else
            {
                /* Try scanning again */
                vRF4CE_NlmeStartReq();
            }
            break;

        case E_RF4CE_EV_AUTODISC_CFM:       /* Use with tsRF4CE_NlmeAutoDiscoveryCfm */
            if (E_RF4CE_STATUS_SUCCESS == puParam->sNlmeAutoDiscoveryCfm.eStatus)
            {
                vAHI_UartWriteData(E_AHI_UART_0, 0x0C);
                /* Device has been discovered so enter possible pairing */
                eState = E_PAIRING;
            }
            else
            {
                /* Device not discovered so wait for user to start discovery again */
                eState = E_START_COMPLETE;
            }
            break;

        case E_RF4CE_EV_PAIR_IND:       /* Use with tsRF4CE_NlmePairInd */

                if (E_PAIRING == eState)
                {

                    tsRF4CE_AppCap sAppCap = {1, 1, 0, 1, 0};
                    uint8          au8DevTypeList[1] = {RF4CE_DEVICE_TYPE_MEDIA_CENTER};
                    uint8          au8ProfileIdList[1] = {ZRC_PROFILE_ID};
                    /* Decision to accept or reject pair is outside scope of spec.
                       Just send a success response in all cases
                           Must be within response timeout */
                    vRF4CE_NlmePairResp(E_RF4CE_STATUS_SUCCESS,
                                        puParam->sNlmePairInd.u16SrcPanId,
                                        puParam->sNlmePairInd.psSrcIeeeAddr,
                                        &sAppCap,
                                        au8DevTypeList,
                                        au8ProfileIdList,
                                        puParam->sNlmePairInd.u8ProvPairingRef);

                    u8RemotePairingRef = puParam->sNlmePairInd.u8ProvPairingRef;
                }
                else
                {
                    eState = E_START_COMPLETE;
                }
                break;

        case E_RF4CE_EV_COMMSTATUS_IND: /* Use with tsRF4CE_NlmeCommStatusInd */
                /* If in pairing state */
                if (E_PAIRING == eState)
                {
                    /* Response is correct */
                    if (puParam->sNlmeCommStatusInd.u8PairingRef == u8RemotePairingRef)
                    {
                        vValToDec(dis_lcd, puParam->sNlmeCommStatusInd.eStatus," ");
                        vLcdWriteText(dis_lcd, 7, 0);
                        if (E_RF4CE_STATUS_SUCCESS == puParam->sNlmeCommStatusInd.eStatus)
                        {
                            eState = E_PAIRED;
                        }
                        else
                        {
                            eState = E_WAIT_FOR_KEY;
                        }
                    }
                }
                break;

        case E_RF4CE_EV_NLDE_CFM:       /* Use with tsRF4CE_NldeDataCfm */

            if (E_TRANSMITTING == eState)
            {
                eState = E_RUNNING;
            }
        break;

        case E_RF4CE_EV_NLDE_IND:       /* Use with tsRF4CE_NldeDataInd */

            /* Decode ZRC command */
            switch (puParam->sNldeDataInd.pu8Nsdu[0])
            {
            case E_ZRC_USER_CONTROL_PRESSED:

                if( puParam->sNldeDataInd.pu8Nsdu[1] == SELECT)
                {
                    vAHI_UartWriteData(E_AHI_UART_0, E_TX_CMD_DATA_RX);
                    vAHI_UartWriteData(E_AHI_UART_0, SELECT);
                }
                if( puParam->sNldeDataInd.pu8Nsdu[1] == PLAY)
                {
                    vAHI_UartWriteData(E_AHI_UART_0, PLAY);
                }
                if( puParam->sNldeDataInd.pu8Nsdu[1] == PAUSE)
                {
                    vAHI_UartWriteData(E_AHI_UART_0, PAUSE);
                }
                if( puParam->sNldeDataInd.pu8Nsdu[1] == VOLUME_UP)
                {
                    vAHI_UartWriteData(E_AHI_UART_0, E_TX_CMD_DATA_RX);
                    vAHI_UartWriteData(E_AHI_UART_0, VOLUME_UP);
                }
                if( puParam->sNldeDataInd.pu8Nsdu[1] == VOLUME_DOWN)
                {
                    vAHI_UartWriteData(E_AHI_UART_0, E_TX_CMD_DATA_RX);
                    vAHI_UartWriteData(E_AHI_UART_0, VOLUME_DOWN);
                }
                if( puParam->sNldeDataInd.pu8Nsdu[1] == STOP)
                {
                    vAHI_UartWriteData(E_AHI_UART_0, E_TX_CMD_DATA_RX);
                    vAHI_UartWriteData(E_AHI_UART_0, STOP);
                }
                if( puParam->sNldeDataInd.pu8Nsdu[1] == FAST_FORWARD)
                {
                    vAHI_UartWriteData(E_AHI_UART_0, E_TX_CMD_DATA_RX);
                    vAHI_UartWriteData(E_AHI_UART_0, FAST_FORWARD);
                }
                if( puParam->sNldeDataInd.pu8Nsdu[1] == REWIND)
                {
                    vAHI_UartWriteData(E_AHI_UART_0, E_TX_CMD_DATA_RX);
                    vAHI_UartWriteData(E_AHI_UART_0, REWIND);
                }
                if( puParam->sNldeDataInd.pu8Nsdu[1] == UP)
                {
                    vAHI_UartWriteData(E_AHI_UART_0, E_TX_CMD_DATA_RX);
                    vAHI_UartWriteData(E_AHI_UART_0, UP);
                }
                if( puParam->sNldeDataInd.pu8Nsdu[1] == DOWN)
                {
                    vAHI_UartWriteData(E_AHI_UART_0, E_TX_CMD_DATA_RX);
                    vAHI_UartWriteData(E_AHI_UART_0, DOWN);
                }
                if( puParam->sNldeDataInd.pu8Nsdu[1] == LEFT)
                {
                    vAHI_UartWriteData(E_AHI_UART_0, E_TX_CMD_DATA_RX);
                    vAHI_UartWriteData(E_AHI_UART_0, LEFT);
                }
                if( puParam->sNldeDataInd.pu8Nsdu[1] == RIGHT)
                {
                    vAHI_UartWriteData(E_AHI_UART_0, E_TX_CMD_DATA_RX);
                    vAHI_UartWriteData(E_AHI_UART_0, RIGHT);
                }
                if( puParam->sNldeDataInd.pu8Nsdu[1] == 0x08)
                {
                    //vAHI_UartWriteData(E_AHI_UART_0, E_TX_CMD_DATA_RX);
                    vAHI_UartWriteData(E_AHI_UART_0, 0x08);
                }
                if( puParam->sNldeDataInd.pu8Nsdu[1] == POWER)
                {
                    vAHI_UartWriteData(E_AHI_UART_0, E_TX_CMD_DATA_RX);
                    vAHI_UartWriteData(E_AHI_UART_0, POWER);
                }
                break;
            case E_ZID_CMD_REPORT_DATA:
                if((puParam->sNldeDataInd.pu8Nsdu[2] == E_ZID_ReportType_INPUT)\
                        && (puParam->sNldeDataInd.pu8Nsdu[3] == E_ZID_ReportId_MOUSE))
                {
                    if(puParam->sNldeDataInd.pu8Nsdu[4] == MOUSE_BTN_LEFT){
                        vAHI_UartWriteData(E_AHI_UART_0, 0xD0);
                    }
                    if(puParam->sNldeDataInd.pu8Nsdu[5] != 0x00){
                        switch(puParam->sNldeDataInd.pu8Nsdu[5]){
                        case 0x01:
                            vAHI_UartWriteData(E_AHI_UART_0, 0xC0);
                            break;
                        case 0x02:
                            vAHI_UartWriteData(E_AHI_UART_0, 0xC1);
                            break;
                        case 0x03:
                            vAHI_UartWriteData(E_AHI_UART_0, 0xC2);
                            break;
                        case 0x04:
                            vAHI_UartWriteData(E_AHI_UART_0, 0xC3);
                            break;
                        case 0xFF:
                            vAHI_UartWriteData(E_AHI_UART_0, 0xC4);
                            break;
                        case 0xFE:
                            vAHI_UartWriteData(E_AHI_UART_0, 0xC5);
                            break;
                        case 0xFD:
                            vAHI_UartWriteData(E_AHI_UART_0, 0xC6);
                            break;
                        case 0xFC:
                            vAHI_UartWriteData(E_AHI_UART_0, 0xC7);
                            break;
                        default:
                            break;
                        }
                    }

                    if(puParam->sNldeDataInd.pu8Nsdu[6] != 0x00){
                        switch(puParam->sNldeDataInd.pu8Nsdu[6]){
                        case 0x01:
                            vAHI_UartWriteData(E_AHI_UART_0, 0xC8);
                            break;
                        case 0x02:
                            vAHI_UartWriteData(E_AHI_UART_0, 0xC9);
                            break;
                        case 0x03:
                            vAHI_UartWriteData(E_AHI_UART_0, 0xCA);
                            break;
                        case 0x04:
                            vAHI_UartWriteData(E_AHI_UART_0, 0xCB);
                            break;
                        case 0xFF:
                            vAHI_UartWriteData(E_AHI_UART_0, 0xCC);
                            break;
                        case 0xFE:
                            vAHI_UartWriteData(E_AHI_UART_0, 0xCD);
                            break;
                        case 0xFD:
                            vAHI_UartWriteData(E_AHI_UART_0, 0xCE);
                            break;
                        case 0xFC:
                            vAHI_UartWriteData(E_AHI_UART_0, 0xCF);
                            break;
                        default:
                            break;
                        }
                    }
                }
                break;
            default:
                break;
            }
            break;
        case E_RF4CE_EV_UNPAIR_CFM:
            /* Save Settings */
            vLcdWriteText("E_RF4CE_EV_UNPAIR_CFM ", 3, 0);
            vLcdRefreshAll();
            vRF4CE_ImpSaveSettings(E_SAVE_MODE_FULL);
            vAHI_UartWriteData(E_AHI_UART_0, E_TX_CMD_UNPAIR);
            eState = E_START_COMPLETE;
            break;

        case E_RF4CE_EV_UNPAIR_IND:
            /* Save Settings */
            vRF4CE_NlmeUnpairResp(0);
            vRF4CE_ImpSaveSettings(E_SAVE_MODE_FULL);
            vAHI_UartWriteData(E_AHI_UART_0, E_TX_CMD_UNPAIR);
            eState = E_START_COMPLETE;
            break;

        case E_RF4CE_EV_DISC_CFM:       /* Use with tsRF4CE_NlmeDiscoveryCfm */
        case E_RF4CE_EV_DISC_IND:       /* Use with tsRF4CE_NlmeDiscoveryInd */
        case E_RF4CE_EV_PAIR_CFM:       /* Use with tsRF4CE_NlmePairInd */

        default:
            vLcdWriteText("StackEvent ", 5, 0);
            vLcdRefreshAll();
            break;
        }
}

/****************************************************************************
 *
 * NAME:
 *
 * DESCRIPTION:
 *
 *
 * PARAMETERS:      Name            RW  Usage
 *
 *
 * RETURNS:
 *
 *
 * NOTES:
 *
 ****************************************************************************/
PRIVATE void vIdleLoop(void)
{
    tuRF4CE_NibValue uValue;
    teState          eOldState;
    char acString[8];
    volatile uint16 i2;
    char dis_lcd[50]={'\0'};

    uint8    u8Status, i=0;
    uint16    n=0;


    while (1)
    {
        eOldState = eState;

        switch (eState)
        {
        case E_PRE_START:
            /* Read Uart status line for data */
            u8Status = u8AHI_UartReadLineStatus(E_AHI_UART_0);
            /* data there? */
            if (u8Status & E_AHI_UART_LS_DR)
            {
                /* Read the data */
                while(u8AHI_UartReadLineStatus(E_AHI_UART_0) & E_AHI_UART_LS_DR)
                {
                    u8ReceiverBuffer[n] = u8AHI_UartReadData(E_AHI_UART_0);
                    n++;
                }
                u8ReceiverBuffer[n]='\0';
                /* Start command? */
                if(u8ReceiverBuffer[0] == 0x71)
                {
                    /* Reset Stack and Nib */
                    vRF4CE_NlmeResetReq(TRUE);
                    eState = E_COLD_START;
                    /* Start Network */
                    vRF4CE_NlmeStartReq();

                }
                if(u8ReceiverBuffer[0] == 0x79)
                {
                    vSendCommand(1);
                    for(i2=0;i2<10000;i2++);
                    vRF4CE_ImpSaveSettings(E_SAVE_MODE_MINIMAL);
                    vAHI_SwReset();
                }
                n=0;
            }
            break;

        case E_COLD_START:
            /* Waiting for star to complete */
            vUartReset();
            break;

        case E_PRE_WARMSTART:

            /* Read Uart status line for data */
            u8Status = u8AHI_UartReadLineStatus(E_AHI_UART_0);
            /* data there? */
            if (u8Status & E_AHI_UART_LS_DR)
            {
                /* Read the data */
                while(u8AHI_UartReadLineStatus(E_AHI_UART_0) & E_AHI_UART_LS_DR)
                {
                    u8ReceiverBuffer[n] = u8AHI_UartReadData(E_AHI_UART_0);
                    n++;
                }
                u8ReceiverBuffer[n]='\0';
                /* Start command without memory? */
                if(u8ReceiverBuffer[0] == 0x71)
                {
                    /* Warm start: reset without clearing NIB */
                    vRF4CE_NlmeResetReq(FALSE);
                    (void)eRF4CE_NlmeGetReq(E_RF4CE_NIB_ATTR_PAIRING_TABLE, 0, &NibValue);
                    if(NibValue.sPairingTableEntry.eState  == E_PAIR_ACTIVE )
                    {
                        /* Warm start response */
                        vAHI_UartWriteData(E_AHI_UART_0, 0x0A);
                        eState = E_WARMSTART;
                    }
                    else
                    {
                        eState = E_START_COMPLETE;
                    }
                }
                n=0;
            }
            break;
        case E_WARMSTART:
            /*Send paired device */
            (void)eRF4CE_NlmeGetReq(E_RF4CE_NIB_ATTR_PAIRING_TABLE, 0, &uValue);
            vLongToString(acString, uValue.sPairingTableEntry.sDstIeeeAddr.u32H);
            acString[8]='\0';
            for(i=0;i<8;i++)
            {
                vAHI_UartWriteData(E_AHI_UART_0, acString[i]);
            }
            vLongToString(acString, uValue.sPairingTableEntry.sDstIeeeAddr.u32L);
            acString[8]='\0';
            vLcdWriteText(acString, 2, 15);
            vLcdRefreshAll();
            for(i=0;i<8;i++)
            {
                vAHI_UartWriteData(E_AHI_UART_0, acString[i]);
            }
            eState = E_RUNNING;
            break;

        case E_START_COMPLETE:
            /* Now running */

            /* Set info in NIB */
            memset(uValue.au8UserString, 0, RF4CE_USER_STRING_LEN);
            memcpy(uValue.au8UserString, "Receiver", 8);
            (void)eRF4CE_NlmeSetReq(E_RF4CE_NIB_ATTR_USER_STRING, 0, &uValue);

            uValue.u8DiscoveryLqiThreshold = 0x40;
            (void)eRF4CE_NlmeSetReq(E_RF4CE_NIB_ATTR_DISC_LQI_THRESHOLD, 0, &uValue);

            /* Get info from NIB */
            //(void)eRF4CE_NlmeGetReq(E_RF4CE_NIB_ATTR_BASE_CHANNEL, 0, &uValue);

            vAHI_UartWriteData(E_AHI_UART_0, E_TX_CMD_NET_STARTED);

            eState = E_WAIT_FOR_KEY;
            n=0;

            break;

        case E_WAIT_FOR_KEY:

            /* Read Uart status line for data */
            u8Status = u8AHI_UartReadLineStatus(E_AHI_UART_0);
            /* data there? */
            if (u8Status & E_AHI_UART_LS_DR)
            {
                /* Read the data */
                while(u8AHI_UartReadLineStatus(E_AHI_UART_0) & E_AHI_UART_LS_DR)
                {
                    u8ReceiverBuffer[n] = u8AHI_UartReadData(E_AHI_UART_0);
                    n++;
                }
                vValToDec(dis_lcd, u8ReceiverBuffer[0]," ");
                vLcdWriteText(dis_lcd, 7, 0);
                vLcdRefreshAll();
                /* Start command? */
                if(u8ReceiverBuffer[0] == 0x72)
                {
                    vAHI_UartWriteData(E_AHI_UART_0, E_TX_CMD_ACK);
                    /* Set Device to auto discovery mode */
                    eState = E_WAIT_FOR_DISCOVERY;
                    tsRF4CE_AppCap   sAppCap             = {1, 1, 0, 1, 0};
                    uint8            au8DevTypeList[1]   = {RF4CE_DEVICE_TYPE_MEDIA_CENTER};
                    uint8            au8ProfileIdList[1] = {ZRC_PROFILE_ID};
                    vRF4CE_NlmeAutoDiscoveryReq(&sAppCap, au8DevTypeList,
                                                au8ProfileIdList, 62500 * 60);
                }
                if(u8ReceiverBuffer[0] == 0x79)
                {
                    vSendCommand(1);
                    for(i2=0;i2<10000;i2++);
                    vRF4CE_ImpSaveSettings(E_SAVE_MODE_MINIMAL);
                    vAHI_SwReset();
                }
                n=0;
            }
            break;

        case E_WAIT_FOR_DISCOVERY:
            /* Waiting for discovery to complete */
            vUartReset();
            break;

        case E_PAIRING:
            /* Read Uart status line for data
              else wait for pairing request*/
            u8Status = u8AHI_UartReadLineStatus(E_AHI_UART_0);
            /* data there? */
            if (u8Status & E_AHI_UART_LS_DR)
            {
                /* Read the data */
                while(u8AHI_UartReadLineStatus(E_AHI_UART_0) & E_AHI_UART_LS_DR)
                {
                    u8ReceiverBuffer[n] = u8AHI_UartReadData(E_AHI_UART_0);
                    n++;
                }
                /* Discovery command? */
                if(u8ReceiverBuffer[0] == 0x72)
                {
                    vAHI_UartWriteData(E_AHI_UART_0, E_TX_CMD_ACK);
                    /* Set Device to auto discovery mode */
                    eState = E_WAIT_FOR_DISCOVERY;
                    tsRF4CE_AppCap   sAppCap             = {1, 1, 0, 1, 0};
                    uint8            au8DevTypeList[1]   = {RF4CE_DEVICE_TYPE_MEDIA_CENTER};
                    uint8            au8ProfileIdList[1] = {ZRC_PROFILE_ID};
                    vRF4CE_NlmeAutoDiscoveryReq(&sAppCap, au8DevTypeList,
                                                au8ProfileIdList, 62500 * 60);
                }
                /* Reset Command */
                if(u8ReceiverBuffer[0] == 0x79)
                {
                    vSendCommand(1);
                    for(i2=0;i2<10000;i2++);
                    vRF4CE_ImpSaveSettings(E_SAVE_MODE_MINIMAL);
                    vAHI_SwReset();
                }
                n=0;
            }
            break;

        case E_PAIRED:
            /* Paired, so can save state */
            vAHI_UartWriteData(E_AHI_UART_0, E_TX_CMD_ASS_REQ);

            (void)eRF4CE_NlmeGetReq(E_RF4CE_NIB_ATTR_PAIRING_TABLE, 0, &uValue);
            vLongToString(acString, uValue.sPairingTableEntry.sDstIeeeAddr.u32H);
            acString[8]='\0';
            for(i=0;i<8;i++)
            {
                vAHI_UartWriteData(E_AHI_UART_0, acString[i]);
            }
            vLongToString(acString, uValue.sPairingTableEntry.sDstIeeeAddr.u32L);
            acString[8]='\0';
            for(i=0;i<8;i++)
            {
                vAHI_UartWriteData(E_AHI_UART_0, acString[i]);
            }

            eState =E_EXCEPT_PAIRING;
            break;

        case E_EXCEPT_PAIRING:
            /* Read Uart status line for data */
            u8Status = u8AHI_UartReadLineStatus(E_AHI_UART_0);
            /* data there? */
            if (u8Status & E_AHI_UART_LS_DR)
            {
                /* Read the data */
                while(u8AHI_UartReadLineStatus(E_AHI_UART_0) & E_AHI_UART_LS_DR)
                {
                    u8ReceiverBuffer[n] = u8AHI_UartReadData(E_AHI_UART_0);
                    n++;
                }

                /* Start command? */
                if(u8ReceiverBuffer[0] == 0x73)
                {
                    /* Save Settings */
                    vRF4CE_ImpSaveSettings(E_SAVE_MODE_FULL);
                    /* Set Device to run mode */
                    eState = E_RUNNING;
                    vAHI_UartWriteData(E_AHI_UART_0, E_TX_CMD_ACK);
                }
                if(u8ReceiverBuffer[0] == 0x74)
                {
                    vAHI_UartWriteData(E_AHI_UART_0, E_TX_CMD_ACK);
                    /* Set Device to unpair */
                    eState = E_UNPAIR;
                }
                if(u8ReceiverBuffer[0] == 0x79)
                {
                    vSendCommand(1);
                    for(i2=0;i2<10000;i2++);
                    vRF4CE_ImpSaveSettings(E_SAVE_MODE_MINIMAL);
                    vAHI_SwReset();
                }

                n=0;
            }
            break;

        case E_UNPAIR:
            /* Un-pair the first paired device in the list */
            (void)vRF4CE_NlmeUnpairReq(0);
            eState = E_WAIT_FOR_UNPAIRING;
            break;

        case E_WAIT_FOR_UNPAIRING:
            /* Waiting for un-pair to complete */
            break;

        case E_RUNNING:
            n=0;
            u8Status = u8AHI_UartReadLineStatus(E_AHI_UART_0);
            if (u8Status & E_AHI_UART_LS_DR)
            {
                //delay
                for(i2=0;i2<10000;i2++);
                while(u8AHI_UartReadLineStatus(E_AHI_UART_0) & E_AHI_UART_LS_DR)
                {
                    u8ReceiverBuffer[n] = u8AHI_UartReadData(E_AHI_UART_0);
                    n++;
                }
                u8ReceiverBuffer[n]='\0';
                if(u8ReceiverBuffer[0] == 0x74)
                {
                    vAHI_UartWriteData(E_AHI_UART_0, E_TX_CMD_ACK);
                    /* Set Device to unpair */
                    eState = E_UNPAIR;
                }
                else if(u8ReceiverBuffer[0] == 0x79)
                {
                    vSendCommand(1);
                    for(i2=0;i2<10000;i2++);
                    vRF4CE_ImpSaveSettings(E_SAVE_MODE_MINIMAL);
                    vAHI_SwReset();
                }
                else if(u8ReceiverBuffer[0] == 0x7E)
                {
                    #if (defined STACK_MEASURE)
                            vGetStackMeasure(&sStackInfo);
                            vPrintf("\nStack Usage");
                            vPrintf("\n TotalSize      : %x",sStackInfo.u32TotalSize);
                            vPrintf("\n CurrentMeasure : %x",sStackInfo.u32CurrentMeasure);
                            vPrintf("\n PeakMeasure    : %x",sStackInfo.u32PeakMeasure);
                            vPrintf("\nHeap Usage");
                            vPrintf("\n Start   u32HeapPointer=%x\n",u32HeapPointer);
                            u32HeapPointer = ((uint32 *)&heap_location)[0];
                            vPrintf("\n Now     u32HeapPointer=%x\n",u32HeapPointer);
                   #endif
                }
                else
                {
                    vSendCommand(n);
                }

            }
            break;


        case E_TRANSMITTING:
            vLcdWriteText("transmitting", 1, 0);
                        vLcdRefreshAll();
            /* Waiting for transmit to complete */
            break;

        default:
            break;
        }
    }
}

/****************************************************************************
 *
 * NAME: AppWarmStart
 *
 * DESCRIPTION:
 * Entry point for a wake from sleep mode with the memory contents held. We
 * are not using this mode and so should never get here.
 *
 * PARAMETERS:      Name            RW  Usage
 * None.
 *
 * RETURNS:
 * None.
 *
 * NOTES:
 * None.
 ****************************************************************************/
PUBLIC void AppWarmStart(void)
{
#if 0
    AppApiMacRestoreSettings();
    eState = E_RUNNING;
    /* Go to idle loop */
    vIdleLoop();
#else
    AppColdStart();
#endif
}

/****************************************************************************
 *
 * NAME: vInitSystem
 *
 * DESCRIPTION:
 * Initialises stack and hardware, sets non-default values in the 802.15.4
 * PIB.
 *
 * PARAMETERS:      Name            RW  Usage
 * None.
 *
 * RETURNS:
 * None.
 *
 * NOTES:
 * None.
 ****************************************************************************/
PRIVATE void vInitSystem(void)
{
    /* Initialise stack and hardware interfaces. We aren't using callbacks
       at all, just monitoring the upward queues in a loop */
    u32AHI_Init();
    /* initialisation of the uart for debug */
    vUART_printInit();
    vAHI_UartEnable(E_AHI_UART_0);
    vAHI_UartReset(E_AHI_UART_0, TRUE, TRUE);
    vAHI_UartReset(E_AHI_UART_0, FALSE, FALSE);

    vAHI_UartSetClockDivisor(E_AHI_UART_0, E_AHI_UART_RATE_115200);
    vAHI_UartSetControl(E_AHI_UART_0, FALSE, FALSE, E_AHI_UART_WORD_LEN_8, TRUE, FALSE);
    vAHI_UartSetAutoFlowCtrl(E_AHI_UART_0, 0x01, TRUE, TRUE, TRUE);


    #if (defined STACK_MEASURE)
    	u32HeapPointer = ((uint32 *)&heap_location)[0];
        vInitStackMeasure();
    #endif
    /* Set Channels to Default allowed channels */
    vRF4CE_ImpConfigChan(3, 15, 20, 25);
    vLcdReset(1,13);
}

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

/****************************************************************************
 *
 * 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 16-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
 *                  u16Num         R   Value to convert
 *
 * RETURNS:
 * void
 *
 ****************************************************************************/
PUBLIC void vLongToString(char * str, uint32 u32Num)
{
    uint8 u8Nybble;
    int i;
    for (i = 28; i >= 0; i -= 4)
    {
        u8Nybble = (uint8)((u32Num >> i) & 0x0f);
        u8Nybble += 0x30;
        if (u8Nybble > 0x39)
            u8Nybble += 7;

        *str = u8Nybble;
        str++;
    }
}

/****************************************************************************
 *
 * NAME: vSendCommand
 *
 * DESCRIPTION:
 * Send key pressed data
 *
 * PARAMETERS:        Name       RW  Usage
 * key press
 *
 * RETURNS:
 *
 * NOTES:
 *
 ****************************************************************************/
PRIVATE void vSendCommand(uint8 u8Count)
{
    uint8 u8TxOptions;
    eState = E_TRANSMITTING;

    u8TxOptions = RF4CE_TX_OPT_ACKNOWLEDGE | RF4CE_TX_OPT_SINGLE_CHAN;
    vRF4CE_NldeDataReq(u8RemotePairingRef, ZRC_PROFILE_ID, 0,
            u8Count, u8ReceiverBuffer , u8TxOptions);
}

/****************************************************************************
 *
 * NAME: vUtils_DisplayHex
 *
 * DESCRIPTION:
 *
 * PARAMETERS:      Name            RW  Usage
 *                  u32Data         R   Value to send
 *                  iSize           R   Length of value
 *
 * RETURNS:
 * void
 *
 ****************************************************************************/
PUBLIC void vUtils_ValToHex(char *pcString, uint32 u32Data, int iSize)
{
    uint8 u8Nybble;
    int i, j;

    j = 0;
    for (i = (iSize << 2) - 4; i >= 0; i -= 4)
    {
        u8Nybble = (uint8)((u32Data >> i) & 0x0f);
        u8Nybble += 0x30;
        if (u8Nybble > 0x39)
            u8Nybble += 7;
        *pcString = u8Nybble;
        pcString++;
    }
    *pcString = '\0';
}
/****************************************************************************
 *
 * NAME: vUartReset
 *
 * DESCRIPTION:
 *
 * PARAMETERS:      Name            RW  Usage
 *
 *
 * RETURNS:
 * void
 *
 ****************************************************************************/
PUBLIC void vUartReset(void)
{
uint8     n=0;
volatile uint16 i;
uint8     u8Status;
uint8    u8ReceiverBuffer[10];

    u8Status = u8AHI_UartReadLineStatus(E_AHI_UART_0);
    if (u8Status & E_AHI_UART_LS_DR)
    {
        while(u8AHI_UartReadLineStatus(E_AHI_UART_0) & E_AHI_UART_LS_DR)
        {
            u8ReceiverBuffer[n] = u8AHI_UartReadData(E_AHI_UART_0);
            n++;
        }
        u8ReceiverBuffer[n]='\0';
        if(u8ReceiverBuffer[0] == 0x79)
        {
            vSendCommand(1);
            for(i=0;i<10000;i++);
            vRF4CE_ImpSaveSettings(E_SAVE_MODE_MINIMAL);
            vAHI_SwReset();
        }
    }


}
/****************************************************************************/
/***        END OF FILE                                                   ***/
/****************************************************************************/
