This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

How can I use CC2531 as ZigBee coordinator

Other Parts Discussed in Thread: CC2531, CC2530, Z-STACK, CC2538, CC2650

Hi,

I want to use the CC2531 as ZigBee Coordinator. I load the ZNP example on the dongle and work with Ztool and now I want to use it as a real coordinator that do all the binding work with the ZED for me.

How can I do something like this? Best way would be to load the Thermostat example on it but I don't know how and if such a Thing is possible.

Best regards

  • Yes, it is possible to do so. You can revise GPIO settings to run example on CC2531 USB dongle.
  • How do I do this becaause at the moment I use IAR and I don't know how to flash from IAR I need a .hex for FlashProgrammer or is it possible to flash directly from IAR ?
  • You can either generate hex file from IAR and download it using Flash Programmer, or download binary from IAR directly.
  • Can you explain how to do this and which example would be best for the CC2531 the CC2530DB or the CC2530 ? And is there any Information about the porting of the CC2531 ?
    Best regards
  • You can download and install Z-Stack Home 1.2.2a. There is Z-Stack Home Sample Application User's Guide.pdf which show you how to do it.
  • I have installed this and read the Guide but I can't find something about CC2531. Or is it like CC2530?
  • Programming/Debugging CC2531 is like CC2530.
  • And the porting ? is it also the same? And which example do I use CC2530DK or CC2538?

  • Basically, the examples which can run on CC2530DK is able to run on CC2531. You have to revise hal_key.c to map GPI of buttons on CC2530Dk to GPI used by CC2531 USB dongle.
  • Hi I have a Problem with the example CC2530DB I can't open it in IAR there is always an error: "Can not open Coordinator EB with toolchain 8051" I deleted the 8051 workbench but the error occur again.
    The CC2538 example I can open without any Problems can I use this for the CC2531 ?

    Best regards
  • For CC2531 and CC2530, you have to use IAR EW8051 not EWARM.
  • OK I've done all the things you said and load the Project on CC2531 now it communicates with my LaunchPad but what do I have to do to send data from the CC2531 because the LaunchPad sends Data Request and the CC2531 only sends Ack no Data

    Best Regards
  • What example do you run on CC2531 and CC2650 LaunchPad?
  • On LaunchPad the TempertaureSensor example and on CC2531 the Thermostat example
  • You have to do binding between TempertaureSensor and Thermostat example to make TempertaureSensor report temperature data to Thermostat.
  • Maybe you can tell me how to do this ? or where I can find the Information about this ?
  • In original SampleThermostat and SampleTemperatureSensor, they use EZ-mode to do it. Do you use EZ-mode in your revised examples?
  • I don't Change anything so I think I use it I only change the Button Ports and LED Ports.

  • EZ-Mode would be triggered by HAL_KEY_SW_2 in original example. Since you have change button port/pin, you can use your HAL_KEY_SW_2 to trigger EZ-mode.
  • Ok The CC2650 sends a Beacon Request and the CC2531 sends a Beacon and Link State but the CC2650 don't accept the beacon I think because it sends again a beacon request. I' d disable security on both devices. Is there an other Thing I'd to do ?
  • Do you trigger EZ-mode to make CC2650 sends a Beacon Request and the CC2531 sends a Beacon? Can you attach sniffer log?
  • Hi, I turn off the EZMode for testing but nothing changes.

    3175.sniffer.zip

  • If you don't use EZ-mode, you have to enable permit join on coordinator and device will join.
  • Ok how do I do this I think I have to define it in Options but what do I have to define ?
  • You can use API ZDP_MgmtPermitJoinReq to enable/disable permit join on coordinator.
  • Where do I use the API?
  • You can use it when a button is pressed.
  • Ok if I press a btn it don't reach this section:

    /**************************************************************************************************
     * @fn      HalKeyRead
     *
     * @brief   Read the current value of a key
     *
     * @param   None
     *
     * @return  keys - current keys status
     **************************************************************************************************/
    uint8 HalKeyRead ( void )
    {
      uint8 keys = 0;
    
      if (HAL_PUSH_BUTTON1())
      {
        keys |= HAL_KEY_SW_6;
      }
    
      if ((HAL_KEY_JOY_MOVE_PORT & HAL_KEY_JOY_MOVE_BIT))  /* Key is active low */
      {
        keys |= halGetJoyKeyInput();
      }
    
      return keys;
    }

    So I think something of my configuration of the btn is wrong:

    /* ------------------------------------------------------------------------------------------------
     *                                    Push Button Configuration
     * ------------------------------------------------------------------------------------------------
     */
    
    #define ACTIVE_LOW        !
    #define ACTIVE_HIGH       !!    /* double negation forces result to be '1' */
    
    /* S1 */
    #define PUSH1_BV          BV(1)
    #define PUSH1_SBIT        P1_2
    
    #if defined (HAL_BOARD_CC2530EB_REV17)
      #define PUSH1_POLARITY    ACTIVE_HIGH
    #elif defined (HAL_BOARD_CC2530EB_REV13)
      #define PUSH1_POLARITY    ACTIVE_LOW
    #else
      #error Unknown Board Indentifier
    #endif
    
    /* Joystick Center Press */
    #define PUSH2_BV          BV(0)
    #define PUSH2_SBIT        P1_3
    #define PUSH2_POLARITY    ACTIVE_HIGH
    

    But when I turn on EZMode and press btn then the CC2531 starts to send Beacons I'm really confused. But the CC2650 don't accept this beacons now the question is why ???

    Best regards 

  • You should revise hal_key.c to make button works. CC2650 doesn't accept the beacons because your CC2531 coordinator doesn't enable permit join.
  • #define HAL_KEY_RISING_EDGE   0
    #define HAL_KEY_FALLING_EDGE  1

    #define HAL_KEY_DEBOUNCE_VALUE  25

    /* CPU port interrupt */
    #define HAL_KEY_CPU_PORT_0_IF P1IF
    #define HAL_KEY_CPU_PORT_2_IF P1IF

    /* SW_6 is at P1_2 */
    #define HAL_KEY_SW_6_PORT   P1
    #define HAL_KEY_SW_6_BIT    BV(1)
    #define HAL_KEY_SW_6_SEL    P1SEL
    #define HAL_KEY_SW_6_DIR    P1DIR

    /* edge interrupt */
    #define HAL_KEY_SW_6_EDGEBIT  BV(0)
    #define HAL_KEY_SW_6_EDGE     HAL_KEY_FALLING_EDGE


    /* SW_6 interrupts */
    #define HAL_KEY_SW_6_IEN      IEN1  /* CPU interrupt mask register */
    #define HAL_KEY_SW_6_IENBIT   BV(5) /* Mask bit for all of Port_0 */
    #define HAL_KEY_SW_6_ICTL     P1IEN /* Port Interrupt Control register */
    #define HAL_KEY_SW_6_ICTLBIT  BV(1) /* P0IEN - P0.1 enable/disable bit */
    #define HAL_KEY_SW_6_PXIFG    P1IFG /* Interrupt flag at source */

    /* SW_7 is at at P1_3 */
    #define HAL_KEY_SW_7_PORT   P1
    #define HAL_KEY_SW_7_BIT    BV(0)
    #define HAL_KEY_SW_7_SEL    P1SEL
    #define HAL_KEY_SW_7_DIR    P1DIR

    /* edge interrupt */
    #define HAL_KEY_SW_7_EDGEBIT  BV(3)
    #define HAL_KEY_SW_7_EDGE     HAL_KEY_FALLING_EDGE

    /* Joy move interrupts */
    #define HAL_KEY_SW_7_IEN      IEN2  /* CPU interrupt mask register */
    #define HAL_KEY_SW_7_IENBIT   BV(1) /* Mask bit for all of Port_2 */
    #define HAL_KEY_SW_7_ICTL     P1IEN /* Port Interrupt Control register */
    #define HAL_KEY_SW_7_ICTLBIT  BV(0) /* P2IENL - P2.0<->P2.3 enable/disable bit */
    #define HAL_KEY_SW_7_PXIFG    P1IFG /* Interrupt flag at source */

    Ok is this right or did I misunderstood something?

    Best regards

  • If SW_6 is on P1.2, you should use "#define HAL_KEY_SW_6_BIT    BV(2)" instead of "#define HAL_KEY_SW_6_BIT    BV(1)".

    If SW_7 is on P1.3, you should use "#define HAL_KEY_SW_7_BIT    BV(3)" instead of "#define HAL_KEY_SW_7_BIT    BV(1)".

    There are some settings incorrect. I would suggest you to check CC2530 user guild to fix them.

  • Hi,
    Ok thank you but it don't work maybe you can tell me where I can find the right Settings for the CC2531 ? You give me the data sheet of the CC2530.

    Best regards
  • The attached hal_key.c is for CC2531.

    /**************************************************************************************************
      Filename:       hal_key.c
      Revised:        $Date:$
      Revision:       $Revision:$
    
      Description: This file contains the interface to the H/W Key driver.
    
    
      Copyright 2006-2010 Texas Instruments Incorporated. All rights reserved.
    
      IMPORTANT: Your use of this Software is limited to those specific rights
      granted under the terms of a software license agreement between the user
      who downloaded the software, his/her employer (which must be your employer)
      and Texas Instruments Incorporated (the "License").  You may not use this
      Software unless you agree to abide by the terms of the License. The License
      limits your use, and you acknowledge, that the Software may not be modified,
      copied or distributed unless embedded on a Texas Instruments microcontroller
      or used solely and exclusively in conjunction with a Texas Instruments radio
      frequency transceiver, which is integrated into your product.  Other than for
      the foregoing purpose, you may not use, reproduce, copy, prepare derivative
      works of, modify, distribute, perform, display or sell this Software and/or
      its documentation for any purpose.
    
      YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
      PROVIDED �AS IS� WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
      INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
      NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
      TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
      NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
      LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
      INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
      OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
      OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
      (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
    
      Should you have any questions regarding your right to use this Software,
      contact Texas Instruments Incorporated at www.TI.com.
    **************************************************************************************************/
    
    /* ------------------------------------------------------------------------------------------------
     *                                          Includes
     * ------------------------------------------------------------------------------------------------
     */
    
    #include "hal_board.h"
    #include "hal_drivers.h"
    #include "hal_key.h"
    #include "hal_types.h"
    #include "osal.h"
    #include "usb_interrupt.h"
    
    /* ------------------------------------------------------------------------------------------------
     *                                           Macros  
     * ------------------------------------------------------------------------------------------------
     */
    
    #define HAL_KEY_CLR_INT() \
    st ( \
      /* PxIFG has to be cleared before PxIF. */\
      P1IFG = 0; \
      P1IF = 0; \
    )
    
    /* ------------------------------------------------------------------------------------------------
     *                                          Constants
     * ------------------------------------------------------------------------------------------------
     */
    
    /* ------------------------------------------------------------------------------------------------
     *                                          Typedefs
     * ------------------------------------------------------------------------------------------------
     */
    
    /* ------------------------------------------------------------------------------------------------
     *                                       Global Variables
     * ------------------------------------------------------------------------------------------------
     */
    
    uint8 Hal_KeyIntEnable;
    
    /* ------------------------------------------------------------------------------------------------
     *                                       Global Functions
     * ------------------------------------------------------------------------------------------------
     */
    
    /* ------------------------------------------------------------------------------------------------
     *                                       Local Variables
     * ------------------------------------------------------------------------------------------------
     */
    
    static halKeyCBack_t pHalKeyProcessFunction;
    static volatile uint8 isrKeys;
    static uint8 halKeys;
    
    /* ------------------------------------------------------------------------------------------------
     *                                       Local Functions
     * ------------------------------------------------------------------------------------------------
     */
    
    /**************************************************************************************************
     * @fn          HalKeyInit
     *
     * @brief       This function is called by HalDriverInit to initialize the H/W keys.
     *
     * input parameters
     *
     * None.
     *
     * output parameters
     *
     * None.
     *
     * @return      None.
     **************************************************************************************************
     */
    void HalKeyInit(void)
    {
    }
    
    /**************************************************************************************************
     * @fn          HalKeyConfig
     *
     * @brief       This function is called by HalDriverInit to initialize the H/W keys.
     *
     * input parameters
     *
     * @param       interruptEnable - TRUE/FALSE to enable the key interrupt.
     * @param       cback - The callback function for the key change event.
     *
     * output parameters
     *
     * None.
     *
     * @return      None.
     **************************************************************************************************
     */
    void HalKeyConfig(bool interruptEnable, halKeyCBack_t cback)
    {
      if ((Hal_KeyIntEnable = interruptEnable))
      {
        HAL_KEY_CLR_INT();             // Clear spurious ints.
        PICTL |= 0x01;                 // P1ICONL: Falling edge ints on pins 0-3.
        P1IEN |= PUSH1_BV | PUSH2_BV;  // Enable specific P1 bits for ints by bit mask.
        IEN2  |= 0x10;                 // Enable general P1 interrupts.
      }
      else
      {
        (void)osal_set_event(Hal_TaskID, HAL_KEY_EVENT);
      }
    
      pHalKeyProcessFunction = cback;
    }
    
    /**************************************************************************************************
     * @fn          HalKeyPoll
     *
     * @brief       This function is called by Hal_ProcessEvent() on a HAL_KEY_EVENT.
     *
     * input parameters
     *
     * None.
     *
     * output parameters
     *
     * None.
     *
     * @return      None.
     **************************************************************************************************
     */
    void HalKeyPoll(void)
    {
      uint8 newKeys;
    
      if (Hal_KeyIntEnable)
      {
        halIntState_t intState;
        HAL_ENTER_CRITICAL_SECTION(intState);
        newKeys = isrKeys;
        isrKeys = 0;
        HAL_EXIT_CRITICAL_SECTION(intState);
      }
      else
      {
        uint8 keys = HalKeyRead();
        newKeys = (halKeys ^ keys) & keys;
        halKeys = keys;
      }
    
      if (newKeys && pHalKeyProcessFunction)
      {
        (pHalKeyProcessFunction)(newKeys, HAL_KEY_STATE_NORMAL);
      }
    }
    
    /**************************************************************************************************
     * @fn          HalKeyRead
     *
     * @brief       This function is called anywhere.
     *
     * input parameters
     *
     * None.
     *
     * output parameters
     *
     * None.
     *
     * @return      The bit mask of all keys pressed.
     **************************************************************************************************
     */
    uint8 HalKeyRead(void)
    {
      uint8 keys = 0;
    
      if (HAL_PUSH_BUTTON1())
      {
        keys |= HAL_KEY_SW_1;
      }
    
      if (HAL_PUSH_BUTTON2())
      {
        keys |= HAL_KEY_SW_2;
      }
    
      return keys;
    }
    
    /**************************************************************************************************
     * @fn      HalKeyEnterSleep
     *
     * @brief  - Get called to enter sleep mode
     *
     * @param
     *
     * @return
     **************************************************************************************************/
    void HalKeyEnterSleep ( void )
    {
    }
    
    /**************************************************************************************************
     * @fn      HalKeyExitSleep
     *
     * @brief   - Get called when sleep is over
     *
     * @param
     *
     * @return  - return saved keys
     **************************************************************************************************/
    uint8 HalKeyExitSleep ( void )
    {
      /* Wake up and read keys */
      return ( HalKeyRead () );
    }
    
    /**************************************************************************************************
     * @fn          usbKeyISR
     *
     * @brief       This function is the ISR for the Port2 USB/Key interrupt.
     *
     * input parameters
     *
     * None.
     *
     * output parameters
     *
     * None.
     *
     * @return      None.
     **************************************************************************************************
     */
    HAL_ISR_FUNCTION( usbKeyISR, P1INT_VECTOR )
    {
      HAL_ENTER_ISR();
    
      if (P1IFG & PUSH1_BV)
      {
        isrKeys |= HAL_KEY_SW_1;
      }
    
      if (P1IFG & PUSH2_BV)
      {
        isrKeys |= HAL_KEY_SW_2;
      }
    
      HAL_KEY_CLR_INT();
      (void)osal_set_event(Hal_TaskID, HAL_KEY_EVENT);
    
      HAL_EXIT_ISR();
    }
    
    /**************************************************************************************************
    */
    

  • Big thank you :) but now it does the same as before Permit association is true but they don't allign

    Best regards
  • Can you attach sniffer log?
  • I'd started again and than this occur and the green LED is blinking is it possible that on my CC2650 is something wrong ? :

    sniffer3.zip

  • Yes, the coordinator enables permit join in sniffer log but device doesn't send association request. Can you erase the flash on your device and download application to test again?
  • I've to port the example and the only Point I think I maybe do something wrong is here:

    /******************************************************************************
     * @fn      TempSensor_handleKeys
     *
     * @brief   Callback service for keys
     *
     * @param   keys  - keys that were pressed
     *
     * @return  void
     */
    static void TempSensor_handleKeys(uint8_t keys)
    {
        if(keys == KEY_LEFT) // LP BTN-1
        {
            // increase temperature
            giTsScreenMode = TEMPSENSOR_MAINMODE;
    
            TempSensor_changeTemp(true);
    
        }
    
        if(keys == KEY_RIGHT) // LP BTN-2
        {
            // Start EZMode Commissioning
            if( (giTsScreenMode == TEMPSENSOR_MAINMODE) ||
                (giTsScreenMode == TEMPSENSOR_HELPMODE) )
            {
                giTsScreenMode = TEMPSENSOR_MAINMODE;
    
                TempSensor_startEzMode();
            }
        }

    Maybe you know what is wrong if I press btn they work the right way.

  • Do you try to erase the flash and test again?
  • Yes now the LED's arent lighting up and the board don't send anything. The LED's for flashing work.

  • So, does the device join coordinator now?
  • No It don't join the coordinator I take out the if clause because the LaunchPad has no Display it make no sense :) but it don't join coordinator anyway.

    Maybe something with the configuration is wrong : that are the predefined symbols of the ZStackCore:

    MODULE_CC26XX_7X7
    xZDO_API_ADVANCED
    ZDO_API_BASIC
    CC26XX
    FLASH_ROM_BUILD
    USE_ICALL
    TC_LINKKEY_JOIN
    HAL_ASSERT_SPIN
    xHALNODEBUG
    xDEBUG
    xDEBUG_SW_TRACE
    xDBG_ENABLE
    OAD_KEEP_NV_PAGES
    NV_RESTORE
    NV_INIT
    FEATURE_MAC_SECURITY
    FEATURE_GREEN_POWER
    FEATURE_ENHANCED_BEACON
    HOLD_AUTO_START
    ewarm
    NEAR_FUNC=
    DATA=
    NV_RESTORE

    And that are the symbols of the Temperature Sensor Application:

    ZCL_READ
    ZCL_WRITE
    ZCL_BASIC
    ZCL_REPORT
    ZCL_IDENTIFY
    ZCL_TEMPERATURE_MEASUREMENT
    ZCL_EZMODE
    xZCL_GROUPS
    ZCL_STANDALONE
    ZG_SECURE_ENABLED=0
    ewarm
    USE_ICALL
    HEAPMGR_SIZE=4096
    ICALL_HOOK_ABORT_FUNC=halAssertHandler
    xdc_runtime_Log_DISABLE_ALL
    xdc_runtime_Assert_DISABLE_ALL
    MODULE_CC26XX_7X7
    xTI_DRIVERS_LCD_INCLUDED

  • Hi, after Debugging I found that the State Change mentioned in the comments of the code never occur I can't even find the Loop. So first it is in EZMODE_STATE_JOINER and never reach EZMODE_STATE_IDENTIFYING.

    // joiners will try to join the network, and if success will go to identifying state
        case EZMODE_STATE_JOINER:
          zclEZModeOpener = 0;
          zcl_EZModeStartDevice(*zclEZModeRegisterData.pTaskID, 0);   // see ZDO_STATE_CHANGE in zclSampleSw_event_loop()
        break;
    
        // go into identify state
        case EZMODE_STATE_IDENTIFYING:
    
          // tell app to go into identify mode
          if ( zclEZModeRegisterData.pfnNotifyCB )
          {
            (*zclEZModeRegisterData.pfnNotifyCB)( zclEZModeState, NULL );
          }
    
          // initiators start looking for other nodes in identify mode
          if ( zclEZModeInvokeData.initiator )
          {
            zcl_SetEZModeState ( EZMODE_STATE_WAITING_IDENTIFYQUERYRSP );
          }
        break;

  • Do you enable NV_RESTORE when you test this?
  • Yes I think so. Why is it wrong? i tried without nothing changes.

  • I don't know what is wrong in your test. That's why I am helping you to find it. Can you disable NV_RESTORE and test again?
  • Yes I' ve done that but nothing changes. I ported the example like said in the wiki. I don't know what is wrong do I have to define this ZSTACK_MANUAL_START?

    The state which is returned here is in my case 0x04

    /**
     * Generic function to send a request message to the ZStack Thread
     * and wait for a "default" response message.
     *
     * @param appEntity - Application iCall Entity ID
     * @param cmdID - Command ID of the message
     * @param pReq - Pointer to the request's structure
     * @param msgSize - length of the message being sent
     * @param pFnMatch - Function pointer to the response matching function
     *
     * @return zstack_ZStatusValues
     */
    static zstack_ZStatusValues sendReqDefaultRsp(ICall_EntityID appEntity,
                                                  zstack_CmdIDs cmdID, void *pReq,
                                                  int              msgSize,
                                                  ICall_MsgMatchFn pFnMatch)
    {
        zstack_ZStatusValues status = zstack_ZStatusValues_ZMemError;
    
        // Allocate message buffer space
        ICall_Errno errno;
        zstackmsg_genericReq_t *pMsg =
            (zstackmsg_genericReq_t *)ICall_allocMsg(msgSize);
    
        // Make sure the allocation was successful
        if(pMsg != NULL)
        {
            // Fill in the message header
            pMsg->hdr.event = cmdID;
            pMsg->hdr.status = 0;
    
            // Update the messges's request field
            pMsg->pReq = pReq;
    
            // Send the message
            errno = ICall_sendServiceMsg(appEntity, ICALL_SERVICE_CLASS_ZSTACK,
                                         ICALL_MSG_FORMAT_KEEP, pMsg);
    
            // Was the message sent successfully
            if(errno == ICALL_ERRNO_SUCCESS)
            {
                // Return status
                zstackmsg_genericReq_t *pCmdStatus = NULL;
    
                // Wait for the response message
                errno = ICall_waitMatch(ICALL_TIMEOUT_FOREVER, pFnMatch, NULL,
                                        NULL, (void **)&pCmdStatus);
    
                // Was the response successful
                if(errno == ICALL_ERRNO_SUCCESS)
                {
                    // setup return of
                    status = (zstack_ZStatusValues)pMsg->hdr.status;
                }
                else
                {
                    // Translate ICall Error status to ZStack API status
                    if(errno == ICALL_ERRNO_NOMSG)
                    {
                        status = zstack_ZStatusValues_ZIcallNoMsg;
                    }
                    else if(errno == ICALL_ERRNO_TIMEOUT)
                    {
                        status = zstack_ZStatusValues_ZIcallTimeout;
                    }
                    else
                    {
                        status = zstack_ZStatusValues_ZFailure;
                    }
                }
            }
    
            // pCmdStatus is the same as pMsg
            ICall_freeMsg(pMsg);
        }
    
        // function status
        return(status);
    }

  • Do you disable NV_RESTORE in CC2650Stack?
  • Yes but it don't has any effect nothing has changed in the behaviour of the device