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

📄 hcswitchc.c

📁 能在TI公司的CC2420-ZIGBEE-RF芯片上运行的ZIGBEE应用程序
💻 C
📖 第 1 页 / 共 3 页
字号:
    MESSAGE_INDICATION = 0;

    // This is to check some errant/programming mistakes.
    if ( TO == 0 )
    {
        // Clear watchdog to set TO bit.
        CLRWDT();

        // Clear flags so that we can detect it next time.
        STKPTR &= 0x3F;
        RCON |= 0x1F;

        // Disable all interrupts
        INTCON = 0;

        // Prepare for alternating flashing LED sequence.
        BIND_INDICATION = 0;
        MESSAGE_INDICATION = 1;

        // On this error, blink LEDs.
        while(1)
        {
            CLRWDT();

            // This is to make sure that we don't waste battery.
            // At least one LED is always ON so saving would not be
            // that much - actual application may do something different.
            SLEEP();
            NOP();

            BIND_INDICATION ^= 1;
            MESSAGE_INDICATION ^= 1;
        }
    }

    // Initialize the MAC address
    p = (BYTE *)&macInfo.longAddr;
    *p++ = MAC_LONG_ADDR_BYTE0;
    *p++ = MAC_LONG_ADDR_BYTE1;
    *p++ = MAC_LONG_ADDR_BYTE2;
    *p++ = MAC_LONG_ADDR_BYTE3;
    *p++ = MAC_LONG_ADDR_BYTE4;
    *p++ = MAC_LONG_ADDR_BYTE5;
    *p++ = MAC_LONG_ADDR_BYTE6;
    *p   = MAC_LONG_ADDR_BYTE7;

    // Now that we have complete board id, save the info into nonvolatile memory.
    PutMACAddress(&macInfo.longAddr);

    // Now ask the Stack to set our address in the transceiver.
    APLUpdateAddressInfo();
}

//------------------------------------------------------------------------------
// InitializeBoard
//------------------------------------------------------------------------------

static void InitializeBoard(void)
{
    #ifdef ENABLE_DEBUG
        // This is a RS232 console - you may replace it with any console you like.
        ConsoleInit();
    #endif

    // Switches S2 and S3 are on RB5 and RB4 respectively. We want interrupt-on-change
    INTCON = 0x00;

    // There is no external pull-up resistors on S2 and S3. We will use internal pull-ups.
    // The CC2420 provides SFD (Start of Frame Detect) signal on RB2. We are using
    // the falling edge of that signal to generate INT2
    // Enable PORTB internal pullups, INT2 on falling edge
    INTCON2 = 0x00;

    // Enable INT2 interrupt - SFD from CC2420 or IRQ from ZMD44101
    INTCON3 = 0xD0;

    // CC2420 I/O assignments with respect to PIC:
    // RB0 <- FIFO      (Input)
    // RB1 <- CCA       (Input - Not used in this version of stack)
    // RB2 <- SFD       (Input - Generates interrupt on falling edge)
    // RB3 <- FIFOP     (Input - Used to detect overflow)
    // RC0 -> CSn       (Output - to select CC2420 SPI slave)
    // RC1 -> VREG_EN   (Output - to enable CC2420 voltage regulator)
    // RC2 -> RESETn    (Output - to reset CC2420)
    // RC3 - > SCK      (Output - SPI Clock to CC2420)
    // RC4 <- SO        (Input - SPI data from CC2420)
    // RC5 -> SI        (Output - SPI data to CC2420)

    // Make PORTB as input - this is the RESET default
    TRISB = 0xff;

    // Set PORTC control signal direction and initial states
    // Start with CC2420 disabled and not selected
    LATC = 0xfd;

    // Set the SPI module for use by Stack
    TRISC = 0xD0;

    // Set the SPI module
    SSPSTAT = 0xC0;
    SSPCON1 = 0x20;

    // D1 and D2 are on RA0 and RA1 respectively, and CS of TC77 is on RA2.
    // Make PORTA as digital I/O.
    // The TC77 temp sensor CS is on RA2.
    ADCON1 = 0x0F;

    // Deselect TC77 (RA2)
    LATA = 0x04;

    // Make RA0, RA1, RA2 and RA4 as outputs.
    TRISA = 0xE0;

    // Set up the interrupt to read in a data packet.
    // set to capture on rising edge
    CCP2CON = 0b00000101;
    // set high priority for RX packet detection
    CCP2IP = 1;
    CCP2IF = 0;
    CCP2IE = 1;
}


//******************************************************************************
// Binding Task
//******************************************************************************

static BOOL BindingTask( void )
{
    static SM_BIND  smBind = SM_BIND_INIT;

    APLSetEP( ZDOEndpointHandle );

    switch (smBind)
    {
        case SM_BIND_INIT:
            if (SendEndDeviceBindReq())
            {
                smBind = SM_BIND_CHECK_RESPONSE;
            }
            else
            {
                DEBUG_OUT( "Could not  bind request\r\n" );
                return TRUE;
            }
            break;

        case SM_BIND_CHECK_RESPONSE:
            if (endDeviceBindInfo.flags.bits.bResponseReceived)
            {
                if (endDeviceBindInfo.flags.bits.bBindSuccessful)
                {
                    appFlags.Val ^= TOGGLE_BOUND_FLAG;
                    BIND_INDICATION = appFlags.bits.bIsNotBound;
                    DEBUG_OUT( "End Device Bind/Unbind successful!\r\n" );
                    smBind = SM_BIND_INIT;
                    return TRUE;
                }
                else
                {
                    DEBUG_OUT( "End Device Bind/Unbind unsuccessful.\r\n" );
                    smBind = SM_BIND_INIT;
                    return TRUE;
                }
            }
            else if (TickGetDiff(TickGet(), endDeviceBindInfo.requestStart) >= BIND_WAIT_DURATION)
            {
                DEBUG_OUT( "No one is answering our bind request\r\n" );
                smBind = SM_BIND_INIT;
                return TRUE;
            }
            break;
    }
    return FALSE;
}

//******************************************************************************
// Light Switch Functions
//******************************************************************************

#define MAX_SW_RETRY_COUNT      3
#define RESPONSE_WAIT_DURATION  (5*TICK_SECOND)

// ZigBee provides the following high-level acknowledges. They can be enabled
// independently of each other.

// NOTE - these acknowledges will not work when using indirect messages and
// bindings, as in this demo.  The ZigBee Alliance is aware of the issue with
// the specification.  To use APS and Application Framework acknowledges, you
// must restructure the HCSwitchC and HCLight code to use direct messaging.
// See the HCRouter project for how to discover a device's short address.

// Uncomment the following if you want to get an APS acknowledge that the light
// received the light message.
//#define GET_APS_ACK

// Uncomment the following if you want the light to generate an Application
// Framework-level response when it receives the light message.
// NOTE - the HCLight demo does not currently support this response, due to
// the limitation described above.
//#define GET_AF_RESPONSE

//------------------------------------------------------------------------------
// LightSwitchInit
//------------------------------------------------------------------------------

static void LightSwitchInit(void)
{
    hLightSwitch = APLOpenEP( EP_SWITCH );
}

//------------------------------------------------------------------------------
// LightSwitchTask
//------------------------------------------------------------------------------

static BOOL LightSwitchTask( void )
{
#ifdef GET_AF_RESPONSE
    WORD_VAL            attribID;
    BYTE                dataTypeAndCommand;
    BYTE                errorCode;
    static TICK         messageTimeSent;
#else
#ifdef GET_APS_ACK
    static TICK         messageTimeSent;
#endif
#endif
    static BYTE         messageTryCount;
    static SM_SWITCH    smSwitch = SM_SWITCH_INIT;
    static BYTE         switchRetryCount;
    BYTE                switchValue;
    TRANS_ID            transID;

    APLSetEP( hLightSwitch );

    switch( smSwitch )
    {
        case SM_SWITCH_INIT:
            // The switch has been pressed .
            messageTryCount = 5;
            switchRetryCount = MAX_SW_RETRY_COUNT;
            smSwitch = SM_SWITCH_UPDATE;
            break;

        case SM_SWITCH_UPDATE:
            if ( APLIsPutReady() )
            {
                DEBUG_OUT( "Sending switch value...\r\n" );
                // We could do this a couple of ways. Since we have momentary switches,
                // we'll make the lamp toggle rather than set it to a particular value.
                // Note that the Switching Load Controller has to be able to handle any of
                // the three valid values we can send it, so we can do whatever is easiest
                // for us.
                switchValue = LIGHT_TOGGLE;
                #ifdef GET_AF_RESPONSE
                    #ifdef GET_APS_ACK
                        APLSendKVPIndirectWithACK( transID, MY_PROFILE_ID, OnOffSRC_CLUSTER,
                                EP_SWITCH, 1, &switchValue, GENERATE_TRANS_ID, TRANS_SET_ACK,
                                OnOffSRC_OnOff_DATATYPE, OnOffSRC_OnOff, DEFAULT_RADIUS, ROUTE_DISCOVERY_SUPPRESS );
                    #else
                        APLSendKVPIndirect( transID, MY_PROFILE_ID, OnOffSRC_CLUSTER,
                                EP_SWITCH, 1, &switchValue, GENERATE_TRANS_ID, TRANS_SET_ACK,
                                OnOffSRC_OnOff_DATATYPE, OnOffSRC_OnOff, DEFAULT_RADIUS, ROUTE_DISCOVERY_SUPPRESS );
                    #endif
                #else
                    #ifdef GET_APS_ACK
                        APLSendKVPIndirectWithACK( transID, MY_PROFILE_ID, OnOffSRC_CLUSTER,
                                EP_SWITCH, 1, &switchValue, GENERATE_TRANS_ID, TRANS_SET,
                                OnOffSRC_OnOff_DATATYPE, OnOffSRC_OnOff, DEFAULT_RADIUS, ROUTE_DISCOVERY_SUPPRESS );
                    #else
                        APLSendKVPIndirect( transID, MY_PROFILE_ID, OnOffSRC_CLUSTER,
                                EP_SWITCH, 1, &switchValue, GENERATE_TRANS_ID, TRANS_SET,
                                OnOffSRC_OnOff_DATATYPE, OnOffSRC_OnOff, DEFAULT_RADIUS, ROUTE_DISCOVERY_SUPPRESS );
                    #endif
                #endif
                if (transID == TRANS_ID_INVALID)
                {
                    messageTryCount --;
                    DEBUG_OUT( "Error sending switch message\r\n" );
                    if ( APSDE_DATA_confirm() == NO_BOUND_DEVICE)
                    {
                        DEBUG_OUT( "No bound device\r\n" );
                        smSwitch = SM_SWITCH_INIT;
                        return TRUE;
                    }
                    else if (messageTryCount == 0)
                    {
                        smSwitch = SM_SWITCH_INIT;
                        return TRUE;
                    }
                }
                else
                {
                    #if defined (GET_APS_ACK) || defined (GET_AF_RESPONSE)
                        messageTimeSent = TickGet();
                    #endif
                    switchRetryCount--;
                    smSwitch = SM_SWITCH_MAC_WAIT;
                }
            }
            else
            {
                DEBUG_OUT( "We cannot send switch message\r\n" );
            }
            break;

        case SM_SWITCH_MAC_WAIT:
            if ( APLIsConfirmed() )
            {
                // We have MAC acknowledge for our message, so we know the
                // lamp device's MAC has received the message.  Remove the frame
                // from the list of frames waiting for acknowledge.
                DEBUG_OUT( "Switch MAC acknowledge received.\r\n" );
                APLRemoveFrame();

                // If we're waiting for another acknowlegde, set the state
                // machine to wait for that level.  Otherwise, we're done.  Note
                // that we have to check for the APS level first, then we can
                // check for the application framework level.
                #ifdef GET_APS_ACK
                    smSwitch = SM_SWITCH_APS_WAIT;
                #else
                #ifdef GET_AF_RESPONSE
                    smSwitch = SM_SWITCH_AF_WAIT;
                #else
                    smSwitch = SM_SWITCH_INIT;
                    return TRUE;
                #endif
                #endif
            }
            else if ( APLIsTimedOut() )
            {
                // We timed out before receiving an acknowledge of our message.
                // Remove the frame from the list of frames waiting for
                // acknowledge, and see if we should try again.
                APLRemoveFrame();

                if ( switchRetryCount == 0 )

⌨️ 快捷键说明

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