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.

CC2540 discoverable time period

Other Parts Discussed in Thread: CC2540, CC2541

Hello...

I have a basic query. 

Is the default value of cc2540 discoverable period 30.72 seconds or can I change this value??

Can there be any software modifications made to change this value??

  • Hi Gautham,

    The most easiest way of controlling the advertisement on/off is to have a timed OSAL event that performs it. You can basically have the same code as the keyfobdemo:

    uint8 current_adv_enabled_status;
    uint8 new_adv_enabled_status;

    //Find the current GAP advertisement status
    GAPRole_GetParameter( GAPROLE_ADVERT_ENABLED, &current_adv_enabled_status );

    if( current_adv_enabled_status == FALSE )
    {
    new_adv_enabled_status = TRUE;
    }
    else
    {
    new_adv_enabled_status = FALSE;
    }

    //change the GAP advertisement status to opposite of current status
    GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &new_adv_enabled_status );

  • Thanks Nick...

    But what i need is the on/off period. How can I manually set the period??

    I have already seen the code which you have posted. I am able to understand it. 

    Can you please help me for setting the on/off period??

    Thanks...

  • Hi,

    In KeyfobDemo for example, you can add a new event in KeyFobApp_ProcessEvent:

    if ( events & START_ADV_EVT )
    {
    //Start advertising

    GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &adv_enable);

    osal_start_timerEx( keyfobapp_TaskID, STOP_ADV_EVT, STOP_ADV_EVT_PERIOD);

    return ( events ^ START_ADV_EVT);
    }

    if ( events & STOP_ADV_EVT )
    {
    //Stop advertising

    GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &adv_disable);

    osal_start_timerEx( keyfobapp_TaskID, START_ADV_EVT, START_ADV_EVT_PERIOD);

    return ( events ^ STOP_ADV_EVT);
    }

    With that you can define periods with START/STOP_ADV_EVT_PERIOD, ex:
    #define START_ADV_EVT_PERIOD 5000 //Idle for 5 seconds
    #define STOP_ADV_EVT_PERIOD 1000 //Advertise for 1 second

    Note that the ##_EVT are bit masked and should for example be defined as;
    #define KFD_START_DEVICE_EVT 0x0001
    #define KFD_BATTERY_CHECK_EVT 0x0002
    #define KFD_ACCEL_READ_EVT 0x0004
    #define KFD_TOGGLE_BUZZER_EVT 0x0008
    #define KFD_ADV_IN_CONNECTION_EVT 0x0010
    #define KFD_POWERON_LED_TIMEOUT_EVT 0x0020
    #define START_ADV_EVT 0x0040
    #define STOP_ADV_EVT 0x0080

    I hope this helps. Note that you need to trigger advertisement somewhere with osal_start_timerEx( keyfobapp_TaskID, START_ADV_EVT, START_ADV_EVT_PERIOD);

    Best Regards

  • Thanks a lot Nick...

    I shall check with this and let you know if it works...:)

    Regards

  • Hello Nick...

    I tried with what you said yesterday. But I am not able to get the o/p. The keyfob continuously advertises for 180 seconds i.e its default value. 

    I have made modifications as you said. I have attached the file. You please have a look at it and please let me know the modifications.

    Also, please tell me where should I need to  trigger an advertisement with osal_start_timerEx( keyfobapp_TaskID, START_ADV_EVT, START_ADV_EVT_PERIOD); ??

    I mean in the same  KeyFobApp_ProcessEvent: or in which file of the application?? 

    I have triggered it in the  KeyFobApp_ProcessEvent   itself. 

    Please have a look at the following lines in the attached code...

    Line : 163,164 ------ Start and stop periods

    Line : 450- 455 -------- Trigger advertising

    Line :490-516------------ Toggle advertising

    /**************************************************************************************************
      Filename:       keyfobdemo.c
      Revised:        $Date: 2012-10-11 12:11:30 -0700 (Thu, 11 Oct 2012) $
      Revision:       $Revision: 31784 $
    
      Description:    Key Fob Demo Application.
    
      Copyright 2009 - 2012 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 "bcomdef.h"
    #include "OSAL.h"
    #include "OSAL_PwrMgr.h"
    
    #include "OnBoard.h"
    #include "hal_adc.h"
    #include "hal_led.h"
    #include "hal_key.h"
    
    #include "buzzer.h"
    
    #if defined ( ACC_BMA250 )
    #  include "bma250.h"
    #elif defined ( ACC_CMA3000 )
    #  include "cma3000d.h"
    #endif
    
    #include "gatt.h"
    
    #include "hci.h"
    
    #include "gapgattserver.h"
    #include "gattservapp.h"
    
    #if defined ( PLUS_BROADCASTER )
      #include "peripheralBroadcaster.h"
    #else
      #include "peripheral.h"
    #endif
    
    #include "gapbondmgr.h"
    
    #include "devinfoservice.h"
    #include "proxreporter.h"
    #include "battservice.h"
    #include "accelerometer.h"
    #include "simplekeys.h"
    
    #include "keyfobdemo.h"
    
    /*********************************************************************
     * MACROS
     */
    
    /*********************************************************************
     * CONSTANTS
     */
    
    // Delay between power-up and starting advertising (in ms)
    #define STARTDELAY                    500
    
    // Number of beeps before buzzer stops by itself
    #define BUZZER_MAX_BEEPS              10
    
    // Buzzer beep tone frequency for "High Alert" (in Hz)
    #define BUZZER_ALERT_HIGH_FREQ        4096
    
    // Buzzer beep tone frequency for "Low Alert" (in Hz)
    #define BUZZER_ALERT_LOW_FREQ        250
    
    // How often to check battery voltage (in ms)
    #define BATTERY_CHECK_PERIOD          10000
    
    // How often (in ms) to read the accelerometer
    #define ACCEL_READ_PERIOD             50
    
    // Minimum change in accelerometer before sending a notification
    #define ACCEL_CHANGE_THRESHOLD        5
    
    //GAP Peripheral Role desired connection parameters
    
    // Whether to enable automatic parameter update request when a connection is formed
    #define DEFAULT_ENABLE_UPDATE_REQUEST         FALSE
    
    // Use limited discoverable mode to advertise for 30.72s, and then stop, or
    // use general discoverable mode to advertise indefinitely
    #define DEFAULT_DISCOVERABLE_MODE             GAP_ADTYPE_FLAGS_LIMITED
    //#define DEFAULT_DISCOVERABLE_MODE             GAP_ADTYPE_FLAGS_GENERAL
    
    // Minimum connection interval (units of 1.25ms, 80=100ms) if automatic parameter update request is enabled
    #define DEFAULT_DESIRED_MIN_CONN_INTERVAL     80
    
    // Maximum connection interval (units of 1.25ms, 800=1000ms) if automatic parameter update request is enabled
    #define DEFAULT_DESIRED_MAX_CONN_INTERVAL     800
    
    // Slave latency to use if automatic parameter update request is enabled
    #define DEFAULT_DESIRED_SLAVE_LATENCY         0
    
    // Supervision timeout value (units of 10ms, 1000=10s) if automatic parameter update request is enabled
    #define DEFAULT_DESIRED_CONN_TIMEOUT          1000
    
    // keyfobProximityState values
    #define KEYFOB_PROXSTATE_INITIALIZED            0   // Advertising after initialization or due to terminated link
    #define KEYFOB_PROXSTATE_CONNECTED_IN_RANGE     1   // Connected and "within range" of the master, as defined by
                                                        // proximity profile
    #define KEYFOB_PROXSTATE_PATH_LOSS        2   // Connected and "out of range" of the master, as defined by
                                                        // proximity profile
    #define KEYFOB_PROXSTATE_LINK_LOSS        3   // Disconnected as a result of a supervision timeout
    
    // buzzer_state values
    #define BUZZER_OFF              0
    #define BUZZER_ON               1
    
    // keyfobAlertState values
    #define ALERT_STATE_OFF         0
    #define ALERT_STATE_LOW         1
    #define ALERT_STATE_HIGH        2
    
    // Company Identifier: Texas Instruments Inc. (13)
    #define TI_COMPANY_ID                              0x000D
    
    #define INVALID_CONNHANDLE            0xFFFF
    
    #if defined ( PLUS_BROADCASTER )
      #define ADV_IN_CONN_WAIT            500 // delay 500 ms
    #endif
    
    
    
    // start & stop advertising periods
    
    #define START_ADV_EVT_PERIOD 30000 //Idle for 30 seconds
    #define STOP_ADV_EVT_PERIOD 5000 //Advertise for 5 second
    
    
    
    /*********************************************************************
     * TYPEDEFS
     */
    
    /*********************************************************************
     * GLOBAL VARIABLES
     */
    
    /*********************************************************************
     * EXTERNAL VARIABLES
     */
    
    /*********************************************************************
     * EXTERNAL FUNCTIONS
     */
    
    /*********************************************************************
     * LOCAL VARIABLES
     */
    static uint8 keyfobapp_TaskID;   // Task ID for internal task/event processing
    
    static gaprole_States_t gapProfileState = GAPROLE_INIT;
    
    // Proximity State Variables
    static uint8 keyfobProxLLAlertLevel = PP_ALERT_LEVEL_NO;     // Link Loss Alert
    static uint8 keyfobProxIMAlertLevel = PP_ALERT_LEVEL_NO;     // Link Loss Alert
    static int8  keyfobProxTxPwrLevel = 0;  // Tx Power Level (0dBm default)
    
    // keyfobProximityState is the current state of the device
    static uint8 keyfobProximityState;
    
    static uint8 keyfobAlertState;
    
    // GAP - SCAN RSP data (max size = 31 bytes)
    static uint8 deviceName[] =
    {
      // complete name
      0x0b,   // length of first data structure (11 bytes excluding length byte)
      0x09,   // AD Type = Complete local name
      0x4b,   // 'K'
      0x65,   // 'e'
      0x79,   // 'y'
      0x66,   // 'f'
      0x6f,   // 'o'
      0x62,   // 'b'
      0x64,   // 'd'
      0x65,   // 'e'
      0x6d,   // 'm'
      0x6f,   // 'o'
    };
    
    // GAP - Advertisement data (max size = 31 bytes, though this is
    // best kept short to conserve power while advertisting)
    static uint8 advertData[] =
    {
      0x02,   // length of first data structure (2 bytes excluding length byte)
      GAP_ADTYPE_FLAGS,   // AD Type = Flags
      DEFAULT_DISCOVERABLE_MODE | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
    
      // service UUID, to notify central devices what services are included
      // in this peripheral
      0x07,   // length of second data structure (7 bytes excluding length byte)
      GAP_ADTYPE_16BIT_MORE,   // list of 16-bit UUID's available, but not complete list
      LO_UINT16( LINK_LOSS_SERVICE_UUID ),        // Link Loss Service (Proximity Profile)
      HI_UINT16( LINK_LOSS_SERVICE_UUID ),
      LO_UINT16( IMMEDIATE_ALERT_SERVICE_UUID ),  // Immediate Alert Service (Proximity / Find Me Profile)
      HI_UINT16( IMMEDIATE_ALERT_SERVICE_UUID ),
      LO_UINT16( TX_PWR_LEVEL_SERVICE_UUID ),     // Tx Power Level Service (Proximity Profile)
      HI_UINT16( TX_PWR_LEVEL_SERVICE_UUID )
    };
    
    // GAP GATT Attributes
    static uint8 attDeviceName[GAP_DEVICE_NAME_LEN] = "TI BLE Keyfob";
      
    // Buzzer state
    static uint8 buzzer_state = BUZZER_OFF;
    static uint8 buzzer_beep_count = 0;
    
    // Accelerometer Profile Parameters
    static uint8 accelEnabler = FALSE;
    
    /*********************************************************************
     * LOCAL FUNCTIONS
     */
    static void keyfobapp_ProcessOSALMsg( osal_event_hdr_t *pMsg );
    static void keyfobapp_PerformAlert( void );
    static void keyfobapp_StopAlert( void );
    static void keyfobapp_HandleKeys( uint8 shift, uint8 keys );
    static void peripheralStateNotificationCB( gaprole_States_t newState );
    static void proximityAttrCB( uint8 attrParamID );
    static void accelEnablerChangeCB( void );
    static void accelRead( void );
    
    /*********************************************************************
     * PROFILE CALLBACKS
     */
    
    // GAP Role Callbacks
    static gapRolesCBs_t keyFob_PeripheralCBs =
    {
      peripheralStateNotificationCB,  // Profile State Change Callbacks
      NULL                // When a valid RSSI is read from controller
    };
    
    
    // GAP Bond Manager Callbacks
    static gapBondCBs_t keyFob_BondMgrCBs =
    {
      NULL,                     // Passcode callback (not used by application)
      NULL                      // Pairing / Bonding state Callback (not used by application)
    };
    
    // Proximity Peripheral Profile Callbacks
    static proxReporterCBs_t keyFob_ProximityCBs =
    {
      proximityAttrCB,              // Whenever the Link Loss Alert attribute changes
    };
    
    // Accelerometer Profile Callbacks
    static accelCBs_t keyFob_AccelCBs =
    {
      accelEnablerChangeCB,          // Called when Enabler attribute changes
    };
    
    /*********************************************************************
     * PUBLIC FUNCTIONS
     */
    
    /*********************************************************************
     * @fn      KeyFobApp_Init
     *
     * @brief   Initialization function for the Key Fob App Task.
     *          This is called during initialization and should contain
     *          any application specific initialization (ie. hardware
     *          initialization/setup, table initialization, power up
     *          notificaiton ... ).
     *
     * @param   task_id - the ID assigned by OSAL.  This ID should be
     *                    used to send messages and set timers.
     *
     * @return  none
     */
    void KeyFobApp_Init( uint8 task_id )
    {
    
      // For the CC2540DK-MINI keyfob, device doesn't start advertising until button is pressed
      uint8 initial_advertising_enable = FALSE;
      // By setting this to zero, the device will go into the waiting state after
      // being discoverable for 30.72 second, and will not being advertising again
      // until the enabler is set back to TRUE
      uint16 gapRole_AdvertOffTime = 0;
    
      uint8 enable_update_request = DEFAULT_ENABLE_UPDATE_REQUEST;
      uint16 desired_min_interval = DEFAULT_DESIRED_MIN_CONN_INTERVAL;
      uint16 desired_max_interval = DEFAULT_DESIRED_MAX_CONN_INTERVAL;
      uint16 desired_slave_latency = DEFAULT_DESIRED_SLAVE_LATENCY;
      uint16 desired_conn_timeout = DEFAULT_DESIRED_CONN_TIMEOUT;
    
      keyfobapp_TaskID = task_id;
    
      // Set the GAP Role Parameters
      GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &initial_advertising_enable );
      GAPRole_SetParameter( GAPROLE_ADVERT_OFF_TIME, sizeof( uint16 ), &gapRole_AdvertOffTime );
    
      GAPRole_SetParameter( GAPROLE_SCAN_RSP_DATA, sizeof ( deviceName ), deviceName );
      GAPRole_SetParameter( GAPROLE_ADVERT_DATA, sizeof( advertData ), advertData );
    
      GAPRole_SetParameter( GAPROLE_PARAM_UPDATE_ENABLE, sizeof( uint8 ), &enable_update_request );
      GAPRole_SetParameter( GAPROLE_MIN_CONN_INTERVAL, sizeof( uint16 ), &desired_min_interval );
      GAPRole_SetParameter( GAPROLE_MAX_CONN_INTERVAL, sizeof( uint16 ), &desired_max_interval );
      GAPRole_SetParameter( GAPROLE_SLAVE_LATENCY, sizeof( uint16 ), &desired_slave_latency );
      GAPRole_SetParameter( GAPROLE_TIMEOUT_MULTIPLIER, sizeof( uint16 ), &desired_conn_timeout );
    
      // Set the GAP Attributes
      GGS_SetParameter( GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, attDeviceName );
    
      // Setup the GAP Bond Manager
      {
        uint8 pairMode = GAPBOND_PAIRING_MODE_WAIT_FOR_REQ;
        uint8 mitm = TRUE;
        uint8 ioCap = GAPBOND_IO_CAP_DISPLAY_ONLY;
        uint8 bonding = TRUE;
        GAPBondMgr_SetParameter( GAPBOND_PAIRING_MODE, sizeof ( uint8 ), &pairMode );
        GAPBondMgr_SetParameter( GAPBOND_MITM_PROTECTION, sizeof ( uint8 ), &mitm );
        GAPBondMgr_SetParameter( GAPBOND_IO_CAPABILITIES, sizeof ( uint8 ), &ioCap );
        GAPBondMgr_SetParameter( GAPBOND_BONDING_ENABLED, sizeof ( uint8 ), &bonding );
      }
    
      // Initialize GATT attributes
      GGS_AddService( GATT_ALL_SERVICES );         // GAP
      GATTServApp_AddService( GATT_ALL_SERVICES ); // GATT attributes
      DevInfo_AddService();   // Device Information Service
      ProxReporter_AddService( GATT_ALL_SERVICES );  // Proximity Reporter Profile
      Batt_AddService( );     // Battery Service
      Accel_AddService( GATT_ALL_SERVICES );      // Accelerometer Profile
      SK_AddService( GATT_ALL_SERVICES );         // Simple Keys Profile
    
      keyfobProximityState = KEYFOB_PROXSTATE_INITIALIZED;
    
      // Initialize Tx Power Level characteristic in Proximity Reporter
      {
        int8 initialTxPowerLevel = 0;
        ProxReporter_SetParameter( PP_TX_POWER_LEVEL, sizeof ( int8 ), &initialTxPowerLevel );
      }
    
      keyfobAlertState = ALERT_STATE_OFF;
    
      // make sure buzzer is off
      buzzerStop();
    
      // makes sure LEDs are off
      HalLedSet( (HAL_LED_1 | HAL_LED_2), HAL_LED_MODE_OFF );
    
      // For keyfob board set GPIO pins into a power-optimized state
      // Note that there is still some leakage current from the buzzer,
      // accelerometer, LEDs, and buttons on the PCB.
    
      P0SEL = 0; // Configure Port 0 as GPIO
      P1SEL = 0x40; // Configure Port 1 as GPIO, except P1.6 for peripheral function for buzzer
      P2SEL = 0; // Configure Port 2 as GPIO
    
      P0DIR = 0xFC; // Port 0 pins P0.0 and P0.1 as input (buttons),
                    // all others (P0.2-P0.7) as output
      P1DIR = 0xFF; // All port 1 pins (P1.0-P1.7) as output
      P2DIR = 0x1F; // All port 1 pins (P2.0-P2.4) as output
    
      P0 = 0x03; // All pins on port 0 to low except for P0.0 and P0.1 (buttons)
      P1 = 0;   // All pins on port 1 to low
      P2 = 0;   // All pins on port 2 to low
    
    
      // initialize the ADC for battery reads
      HalAdcInit();
    
      // Register for all key events - This app will handle all key events
      RegisterForKeys( keyfobapp_TaskID );
    
    
    #if defined ( DC_DC_P0_7 )
    
      // Enable stack to toggle bypass control on TPS62730 (DC/DC converter)
      HCI_EXT_MapPmIoPortCmd( HCI_EXT_PM_IO_PORT_P0, HCI_EXT_PM_IO_PORT_PIN7 );
    
    #endif // defined ( DC_DC_P0_7 )
      
    // Setup a delayed profile startup
      osal_start_timerEx( keyfobapp_TaskID, KFD_START_DEVICE_EVT, STARTDELAY );
    }
    
    /*********************************************************************
     * @fn      KeyFobApp_ProcessEvent
     *
     * @brief   Key Fob Application Task event processor.  This function
     *          is called to process all events for the task.  Events
     *          include timers, messages and any other user defined events.
     *
     * @param   task_id  - The OSAL assigned task ID.
     * @param   events - events to process.  This is a bit map and can
     *                   contain more than one event.
     *
     * @return  none
     */
    uint16 KeyFobApp_ProcessEvent( uint8 task_id, uint16 events )
    {
      if ( events & SYS_EVENT_MSG )
      {
        uint8 *pMsg;
    
        if ( (pMsg = osal_msg_receive( keyfobapp_TaskID )) != NULL )
        {
          keyfobapp_ProcessOSALMsg( (osal_event_hdr_t *)pMsg );
    
          // Release the OSAL message
          VOID osal_msg_deallocate( pMsg );
        }
    
        // return unprocessed events
        return (events ^ SYS_EVENT_MSG);
      }
      
      
       // Trigger advertisement for start and stop advertising
      if(events & START_ADV_EVT)
      {
        osal_start_timerEx( keyfobapp_TaskID, START_ADV_EVT, START_ADV_EVT_PERIOD);
        
      }
      
      
    
      if ( events & KFD_START_DEVICE_EVT )
      {
        // Start the Device
        VOID GAPRole_StartDevice( &keyFob_PeripheralCBs );
    
        // Start Bond Manager
        VOID GAPBondMgr_Register( &keyFob_BondMgrCBs );
    
        // Start the Proximity Profile
        VOID ProxReporter_RegisterAppCBs( &keyFob_ProximityCBs );
    
        // Set timer for first battery read event
        osal_start_timerEx( keyfobapp_TaskID, KFD_BATTERY_CHECK_EVT, BATTERY_CHECK_PERIOD );
    
        // Start the Accelerometer Profile
        VOID Accel_RegisterAppCBs( &keyFob_AccelCBs );
    
        //Set the proximity attribute values to default
        ProxReporter_SetParameter( PP_LINK_LOSS_ALERT_LEVEL,  sizeof ( uint8 ), &keyfobProxLLAlertLevel );
        ProxReporter_SetParameter( PP_IM_ALERT_LEVEL,  sizeof ( uint8 ), &keyfobProxIMAlertLevel );
        ProxReporter_SetParameter( PP_TX_POWER_LEVEL,  sizeof ( int8 ), &keyfobProxTxPwrLevel );
    
        // Set LED1 on to give feedback that the power is on, and a timer to turn off
        HalLedSet( HAL_LED_1, HAL_LED_MODE_ON );
        osal_pwrmgr_device( PWRMGR_ALWAYS_ON ); // To keep the LED on continuously.
        osal_start_timerEx( keyfobapp_TaskID, KFD_POWERON_LED_TIMEOUT_EVT, 1000 );
        
        return ( events ^ KFD_START_DEVICE_EVT );
      }
      
      
        // Toggle advertising
      
      if ( events & START_ADV_EVT )
    {
      uint8 adv_enable = TRUE;
      
      //Start advertising
    
    GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &adv_enable);
    
    osal_start_timerEx( keyfobapp_TaskID, STOP_ADV_EVT, STOP_ADV_EVT_PERIOD);
    
    return ( events ^ START_ADV_EVT);
    }
    
    if ( events & STOP_ADV_EVT )
    {
      uint8 adv_disable = FALSE;
      
      //Stop advertising
    
    GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &adv_disable);
    
    osal_start_timerEx( keyfobapp_TaskID, START_ADV_EVT, START_ADV_EVT_PERIOD);
    
    return ( events ^ START_ADV_EVT);
    }
    
      
      
    
      if ( events & KFD_POWERON_LED_TIMEOUT_EVT )
      {
        osal_pwrmgr_device( PWRMGR_BATTERY ); // Revert to battery mode after LED off
        HalLedSet( HAL_LED_1, HAL_LED_MODE_OFF ); 
        return ( events ^ KFD_POWERON_LED_TIMEOUT_EVT );
      }
      
      if ( events & KFD_ACCEL_READ_EVT )
      {
        bStatus_t status = Accel_GetParameter( ACCEL_ENABLER, &accelEnabler );
    
        if (status == SUCCESS)
        {
          if ( accelEnabler )
          {
            // Restart timer
            if ( ACCEL_READ_PERIOD )
            {
              osal_start_timerEx( keyfobapp_TaskID, KFD_ACCEL_READ_EVT, ACCEL_READ_PERIOD );
            }
    
            // Read accelerometer data
            accelRead();
          }
          else
          {
            // Stop the acceleromter
            osal_stop_timerEx( keyfobapp_TaskID, KFD_ACCEL_READ_EVT);
          }
        }
        else
        {
            //??
        }
        return (events ^ KFD_ACCEL_READ_EVT);
      }
    
      if ( events & KFD_BATTERY_CHECK_EVT )
      {
        // Restart timer
        if ( BATTERY_CHECK_PERIOD )
        {
          osal_start_timerEx( keyfobapp_TaskID, KFD_BATTERY_CHECK_EVT, BATTERY_CHECK_PERIOD );
        }
    
        // perform battery level check
        Batt_MeasLevel( );
    
        return (events ^ KFD_BATTERY_CHECK_EVT);
      }
    
      if ( events & KFD_TOGGLE_BUZZER_EVT )
      {
        // if this event was triggered while buzzer is on, turn it off, increment beep_count,
        // check whether max has been reached, and if not set the OSAL timer for next event to
        // turn buzzer back on.
        if ( buzzer_state == BUZZER_ON )
        {
          buzzerStop();
          buzzer_state = BUZZER_OFF;
          buzzer_beep_count++;
          #if defined ( POWER_SAVING )
            osal_pwrmgr_device( PWRMGR_BATTERY );
          #endif
    
          // check to see if buzzer has beeped maximum number of times
          // if it has, then don't turn it back on
          if ( ( buzzer_beep_count < BUZZER_MAX_BEEPS ) &&
               ( ( keyfobProximityState == KEYFOB_PROXSTATE_LINK_LOSS ) ||
                 ( keyfobProximityState == KEYFOB_PROXSTATE_PATH_LOSS )    ) )
          {
            osal_start_timerEx( keyfobapp_TaskID, KFD_TOGGLE_BUZZER_EVT, 800 );
          }
        }
        else if ( keyfobAlertState != ALERT_STATE_OFF )
        {
          // if this event was triggered while the buzzer is off then turn it on if appropriate
          keyfobapp_PerformAlert();
        }
    
        return (events ^ KFD_TOGGLE_BUZZER_EVT);
      }
    
    
    #if defined ( PLUS_BROADCASTER )
      if ( events & KFD_ADV_IN_CONNECTION_EVT )
      {
        uint8 turnOnAdv = TRUE;
        // Turn on advertising while in a connection
        GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &turnOnAdv );
      }
    #endif
    
      // Discard unknown events
      return 0;
    }
    
    /*********************************************************************
     * @fn      keyfobapp_ProcessOSALMsg
     *
     * @brief   Process an incoming task message.
     *
     * @param   pMsg - message to process
     *
     * @return  none
     */
    static void keyfobapp_ProcessOSALMsg( osal_event_hdr_t *pMsg )
    {
      switch ( pMsg->event )
      {
        case KEY_CHANGE:
          keyfobapp_HandleKeys( ((keyChange_t *)pMsg)->state, ((keyChange_t *)pMsg)->keys );
          break;
      }
    }
    
    /*********************************************************************
     * @fn      keyfobapp_HandleKeys
     *
     * @brief   Handles all key events for this device.
     *
     * @param   shift - true if in shift/alt.
     * @param   keys - bit field for key events. Valid entries:
     *                 HAL_KEY_SW_2
     *                 HAL_KEY_SW_1
     *
     * @return  none
     */
    static void keyfobapp_HandleKeys( uint8 shift, uint8 keys )
    {
      uint8 SK_Keys = 0;
    
      (void)shift;  // Intentionally unreferenced parameter
    
      if ( keys & HAL_KEY_SW_1 )
      {
        SK_Keys |= SK_KEY_LEFT;
    
        // if is active, pressing the left key should toggle
        // stop the alert
        if( keyfobAlertState != ALERT_STATE_OFF )
        {
          keyfobapp_StopAlert();
        }
    
        // if device is in a connection, toggle the Tx power level between 0 and
        // -6 dBm
        if( gapProfileState == GAPROLE_CONNECTED )
        {
          int8 currentTxPowerLevel;
          int8 newTxPowerLevel;
    
          ProxReporter_GetParameter( PP_TX_POWER_LEVEL, &currentTxPowerLevel );
    
          switch ( currentTxPowerLevel )
          {
          case 0:
            newTxPowerLevel = -6;
            // change power to -6 dBm
            HCI_EXT_SetTxPowerCmd( HCI_EXT_TX_POWER_MINUS_6_DBM );
            // Update Tx powerl level in Proximity Reporter (and send notification)
            // if enabled)
            ProxReporter_SetParameter( PP_TX_POWER_LEVEL, sizeof ( int8 ), &newTxPowerLevel );
            break;
    
          case (-6):
            newTxPowerLevel = 0;
            // change power to 0 dBm
            HCI_EXT_SetTxPowerCmd( HCI_EXT_TX_POWER_0_DBM );
            // Update Tx powerl level in Proximity Reporter (and send notification)
            // if enabled)
            ProxReporter_SetParameter( PP_TX_POWER_LEVEL, sizeof ( int8 ), &newTxPowerLevel );
            break;
    
          default:
            // do nothing
            break;
          }
        }
    
      }
    
      if ( keys & HAL_KEY_SW_2 )
      {
    
        SK_Keys |= SK_KEY_RIGHT;
    
        // if device is not in a connection, pressing the right key should toggle
        // advertising on and off
        if( gapProfileState != GAPROLE_CONNECTED )
        {
          uint8 current_adv_enabled_status;
          uint8 new_adv_enabled_status;
    
          //Find the current GAP advertisement status
          GAPRole_GetParameter( GAPROLE_ADVERT_ENABLED, &current_adv_enabled_status );
    
          if( current_adv_enabled_status == FALSE )
          {
            new_adv_enabled_status = TRUE;
          }
          else
          {
            new_adv_enabled_status = FALSE;
          }
    
          //change the GAP advertisement status to opposite of current status
          GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &new_adv_enabled_status );
        }
    
      }
    
      SK_SetParameter( SK_KEY_ATTR, sizeof ( uint8 ), &SK_Keys );
    }
    
    /*********************************************************************
     * @fn      keyfobapp_PerformAlert
     *
     * @brief   Performs an alert
     *
     * @param   none
     *
     * @return  none
     */
    static void keyfobapp_PerformAlert( void )
    {
    
      if ( keyfobProximityState == KEYFOB_PROXSTATE_LINK_LOSS )
      {
        switch( keyfobProxLLAlertLevel )
        {
        case PP_ALERT_LEVEL_LOW:
    
          #if defined ( POWER_SAVING )
            osal_pwrmgr_device( PWRMGR_ALWAYS_ON );
          #endif
    
          keyfobAlertState = ALERT_STATE_LOW;
    
          buzzerStart( BUZZER_ALERT_LOW_FREQ );
          buzzer_state = BUZZER_ON;
          // only run buzzer for 200ms
          osal_start_timerEx( keyfobapp_TaskID, KFD_TOGGLE_BUZZER_EVT, 200 );
    
          HalLedSet( (HAL_LED_1 | HAL_LED_2), HAL_LED_MODE_OFF );
          break;
    
        case PP_ALERT_LEVEL_HIGH:
    
          #if defined ( POWER_SAVING )
            osal_pwrmgr_device( PWRMGR_ALWAYS_ON );
          #endif
    
          keyfobAlertState = ALERT_STATE_HIGH;
    
          buzzerStart( BUZZER_ALERT_HIGH_FREQ );
          buzzer_state = BUZZER_ON;
          // only run buzzer for 200ms
          osal_start_timerEx( keyfobapp_TaskID, KFD_TOGGLE_BUZZER_EVT, 200 );
    
          HalLedSet( HAL_LED_1, HAL_LED_MODE_ON );
          HalLedSet( HAL_LED_2, HAL_LED_MODE_FLASH );
          break;
    
        case PP_ALERT_LEVEL_NO:
            // Fall through
        default:
          keyfobapp_StopAlert();
          break;
        }
      }
      else if ( keyfobProximityState == KEYFOB_PROXSTATE_PATH_LOSS )
      {
        switch( keyfobProxIMAlertLevel )
        {
        case PP_ALERT_LEVEL_LOW:
    
          #if defined ( POWER_SAVING )
            osal_pwrmgr_device( PWRMGR_ALWAYS_ON );
          #endif
    
          keyfobAlertState = ALERT_STATE_LOW;
    
          buzzerStart( BUZZER_ALERT_LOW_FREQ );
          buzzer_state = BUZZER_ON;
          // only run buzzer for 200ms
          osal_start_timerEx( keyfobapp_TaskID, KFD_TOGGLE_BUZZER_EVT, 200 );
    
          HalLedSet( (HAL_LED_1 | HAL_LED_2), HAL_LED_MODE_OFF );
          break;
    
    
        case PP_ALERT_LEVEL_HIGH:
    
          #if defined ( POWER_SAVING )
            osal_pwrmgr_device( PWRMGR_ALWAYS_ON );
          #endif
    
          keyfobAlertState = ALERT_STATE_HIGH;
    
          buzzerStart( BUZZER_ALERT_HIGH_FREQ );
          buzzer_state = BUZZER_ON;
          // only run buzzer for 200ms
          osal_start_timerEx( keyfobapp_TaskID, KFD_TOGGLE_BUZZER_EVT, 200 );
    
          HalLedSet( HAL_LED_1, HAL_LED_MODE_ON );
          HalLedSet( HAL_LED_2, HAL_LED_MODE_FLASH );
          break;
    
          case PP_ALERT_LEVEL_NO:
            // Fall through
          default:
            keyfobapp_StopAlert();
            break;
          }
      }
    
    }
    
    /*********************************************************************
     * @fn      keyfobapp_StopAlert
     *
     * @brief   Stops an alert
     *
     * @param   none
     *
     * @return  none
     */
    void keyfobapp_StopAlert( void )
    {
    
      keyfobAlertState = ALERT_STATE_OFF;
    
      buzzerStop();
      buzzer_state = BUZZER_OFF;
      HalLedSet( (HAL_LED_1 | HAL_LED_2), HAL_LED_MODE_OFF );
    
    
      #if defined ( POWER_SAVING )
        osal_pwrmgr_device( PWRMGR_BATTERY );
      #endif
    }
    
    /*********************************************************************
     * @fn      peripheralStateNotificationCB
     *
     * @brief   Notification from the profile of a state change.
     *
     * @param   newState - new state
     *
     * @return  none
     */
    static void peripheralStateNotificationCB( gaprole_States_t newState )
    {
      uint16 connHandle = INVALID_CONNHANDLE;
      uint8 valFalse = FALSE;
    
      if ( gapProfileState != newState )
      {
        switch( newState )
        {
        case GAPROLE_STARTED:
          {
            // Set the system ID from the bd addr
            uint8 systemId[DEVINFO_SYSTEM_ID_LEN];
            GAPRole_GetParameter(GAPROLE_BD_ADDR, systemId);
    
            // shift three bytes up
            systemId[7] = systemId[5];
            systemId[6] = systemId[4];
            systemId[5] = systemId[3];
    
            // set middle bytes to zero
            systemId[4] = 0;
            systemId[3] = 0;
    
            DevInfo_SetParameter(DEVINFO_SYSTEM_ID, DEVINFO_SYSTEM_ID_LEN, systemId);
          }
          break;
    
        //if the state changed to connected, initially assume that keyfob is in range
        case GAPROLE_ADVERTISING:
          {
            // Visual feedback that we are advertising.
            HalLedSet( HAL_LED_2, HAL_LED_MODE_ON );
          }
          break;
          
        //if the state changed to connected, initially assume that keyfob is in range      
        case GAPROLE_CONNECTED:
          {
            // set the proximity state to either path loss alert or in range depending
            // on the value of keyfobProxIMAlertLevel (which was set by proximity monitor)
            if( keyfobProxIMAlertLevel != PP_ALERT_LEVEL_NO )
            {
              keyfobProximityState = KEYFOB_PROXSTATE_PATH_LOSS;
              // perform alert
              keyfobapp_PerformAlert();
              buzzer_beep_count = 0;
            }
            else // if keyfobProxIMAlertLevel == PP_ALERT_LEVEL_NO
            {
              keyfobProximityState = KEYFOB_PROXSTATE_CONNECTED_IN_RANGE;
              keyfobapp_StopAlert();
            }
    
            GAPRole_GetParameter( GAPROLE_CONNHANDLE, &connHandle );
    
            #if defined ( PLUS_BROADCASTER )
              osal_start_timerEx( keyfobapp_TaskID, KFD_ADV_IN_CONNECTION_EVT, ADV_IN_CONN_WAIT );
            #endif
              
            // Turn off LED that shows we're advertising
            HalLedSet( HAL_LED_2, HAL_LED_MODE_OFF );
          }
          break;
    
        case GAPROLE_WAITING:
          {
            // then the link was terminated intentionally by the slave or master,
            // or advertising timed out
            keyfobProximityState = KEYFOB_PROXSTATE_INITIALIZED;
    
            // Turn off immediate alert
            ProxReporter_SetParameter(PP_IM_ALERT_LEVEL, sizeof(valFalse), &valFalse);
            keyfobProxIMAlertLevel = PP_ALERT_LEVEL_NO;
            
            // Change attribute value of Accelerometer Enable to FALSE
            Accel_SetParameter(ACCEL_ENABLER, sizeof(valFalse), &valFalse);
            // Stop the acceleromter timer
            osal_stop_timerEx( keyfobapp_TaskID, KFD_ACCEL_READ_EVT);
            
            // Turn off LED that shows we're advertising
            HalLedSet( HAL_LED_2, HAL_LED_MODE_OFF );
            
            // Stop alert if it was active
            if( keyfobAlertState != ALERT_STATE_OFF )
            {
              keyfobapp_StopAlert();
            }
          }
          break;
    
        case GAPROLE_WAITING_AFTER_TIMEOUT:
          {
            // the link was dropped due to supervision timeout
            keyfobProximityState = KEYFOB_PROXSTATE_LINK_LOSS;
    
            // Turn off immediate alert
            ProxReporter_SetParameter(PP_IM_ALERT_LEVEL, sizeof(valFalse), &valFalse);
            keyfobProxIMAlertLevel = PP_ALERT_LEVEL_NO;
            
            // Change attribute value of Accelerometer Enable to FALSE
            Accel_SetParameter(ACCEL_ENABLER, sizeof(valFalse), &valFalse);
            // Stop the acceleromter timer
            osal_stop_timerEx( keyfobapp_TaskID, KFD_ACCEL_READ_EVT);
            
            // Perform link loss alert if enabled
            if( keyfobProxLLAlertLevel != PP_ALERT_LEVEL_NO )
            {
              keyfobapp_PerformAlert();
              buzzer_beep_count = 0;
            }
          }
          break;
    
        default:
          // do nothing
          break;
        }
      }
    
      gapProfileState = newState;
    }
    
    /*********************************************************************
     * @fn      proximityAttrCB
     *
     * @brief   Notification from the profile of an atrribute change by
     *          a connected device.
     *
     * @param   attrParamID - Profile's Attribute Parameter ID
     *            PP_LINK_LOSS_ALERT_LEVEL  - The link loss alert level value
     *            PP_IM_ALERT_LEVEL  - The immediate alert level value
     *
     * @return  none
     */
    static void proximityAttrCB( uint8 attrParamID )
    {
      switch( attrParamID )
      {
    
      case PP_LINK_LOSS_ALERT_LEVEL:
        ProxReporter_GetParameter( PP_LINK_LOSS_ALERT_LEVEL, &keyfobProxLLAlertLevel );
        break;
    
      case PP_IM_ALERT_LEVEL:
        {
          ProxReporter_GetParameter( PP_IM_ALERT_LEVEL, &keyfobProxIMAlertLevel );
    
          // if proximity monitor set the immediate alert level to low or high, then
          // the monitor calculated that the path loss to the keyfob (proximity observer)
          // has exceeded the threshold
          if( keyfobProxIMAlertLevel != PP_ALERT_LEVEL_NO )
          {
            keyfobProximityState = KEYFOB_PROXSTATE_PATH_LOSS;
            keyfobapp_PerformAlert();
            buzzer_beep_count = 0;
          }
          else // proximity monitor turned off alert because the path loss is below threshold
          {
            keyfobProximityState = KEYFOB_PROXSTATE_CONNECTED_IN_RANGE;
            keyfobapp_StopAlert();
          }
        }
        break;
    
      default:
        // should not reach here!
        break;
      }
    
    }
    
    /*********************************************************************
     * @fn      accelEnablerChangeCB
     *
     * @brief   Called by the Accelerometer Profile when the Enabler Attribute
     *          is changed.
     *
     * @param   none
     *
     * @return  none
     */
    static void accelEnablerChangeCB( void )
    {
      bStatus_t status = Accel_GetParameter( ACCEL_ENABLER, &accelEnabler );
    
      if (status == SUCCESS){
        if (accelEnabler)
        {
          // Initialize accelerometer
          accInit();
          // Setup timer for accelerometer task
          osal_start_timerEx( keyfobapp_TaskID, KFD_ACCEL_READ_EVT, ACCEL_READ_PERIOD );
        } else
        {
          // Stop the acceleromter
          osal_stop_timerEx( keyfobapp_TaskID, KFD_ACCEL_READ_EVT);
        }
      } else
      {
        //??
      }
    }
    
    /*********************************************************************
     * @fn      accelRead
     *
     * @brief   Called by the application to read accelerometer data
     *          and put data in accelerometer profile
     *
     * @param   none
     *
     * @return  none
     */
    static void accelRead( void )
    {
    
      static int8 x, y, z;
      int8 new_x, new_y, new_z;
    
      // Read data for each axis of the accelerometer
      accReadAcc(&new_x, &new_y, &new_z);
    
      // Check if x-axis value has changed by more than the threshold value and
      // set profile parameter if it has (this will send a notification if enabled)
      if( (x < (new_x-ACCEL_CHANGE_THRESHOLD)) || (x > (new_x+ACCEL_CHANGE_THRESHOLD)) )
      {
        x = new_x;
        Accel_SetParameter(ACCEL_X_ATTR, sizeof ( int8 ), &x);
      }
    
      // Check if y-axis value has changed by more than the threshold value and
      // set profile parameter if it has (this will send a notification if enabled)
      if( (y < (new_y-ACCEL_CHANGE_THRESHOLD)) || (y > (new_y+ACCEL_CHANGE_THRESHOLD)) )
      {
        y = new_y;
        Accel_SetParameter(ACCEL_Y_ATTR, sizeof ( int8 ), &y);
      }
    
      // Check if z-axis value has changed by more than the threshold value and
      // set profile parameter if it has (this will send a notification if enabled)
      if( (z < (new_z-ACCEL_CHANGE_THRESHOLD)) || (z > (new_z+ACCEL_CHANGE_THRESHOLD)) )
      {
        z = new_z;
        Accel_SetParameter(ACCEL_Z_ATTR, sizeof ( int8 ), &z);
      }
    
    }
    
    /*********************************************************************
    *********************************************************************/
    

  • Nick..

    Can you please check my post and reply asap.. I got struck up here. please help me out...

  • Hi,

    Change DEFAULT_DISCOVERABLE_MODE to GAP_ADTYPE_FLAGS_GENERAL to allow longer advertisements than 180. The call to start advertisement could be where ever you want, button push or on start-up. If start-up, put osal_start_timerEx( keyfobapp_TaskID, START_ADV_EVT, START_ADV_EVT_PERIOD); last in the KFD_START_DEVICE_EVT event. 

    Note that you have two events called START_ADV_EVT, please remove the first one in KeyFobApp_ProcessEvent.

    Best Regards

  • Thanks....

    I have made the modifications as you said. But now it is advertising for more than 180 secs which is the default value..

    I dont know what could be the reason. And Nick, I want to advertrise only for less than 10 seconds and make the device idle more than 30 seconds and repeat this process.... 

    So please give me a suggestion.

  • Hi Gautham.

    Yes of course it's advertising more than 180 seconds since you now use General Advertising instead of Limited Advertising, it will advertise indefinite. You have to manually stop the advertisements based on the OSAL event earlier discussed. The whole point was that you wanted to toggle advertisements on and off, right? So when you have started the advertisements you have to set a an OSAL timer that will for example trigger a new event 30 seconds later, which will stop advertisements. You still need to implement this manually.

    Best Regards 

  • Hi Nick...

    Ya I used only  the limited discovery mode and tried. But it kept on advertising indefinitely..

    And yes I am trying to toggle it with limited on time(5secs) and more off time(30 secs).

    And I am trying with Broadcaster code. In that code, I have triggered an osal event at the end of SBP_START_DEVICE_EVT only and tried.

    But if I do this, I am not getting the mac being displayed. I think the compiler stops here and it goes to return unprocessed events i.e i guess it returns 0.

  • Hi Gautham,

    Attached simpleBLEBroadcaster code does exactly what you are looking for. Play around with the defines START_ADV_EVT_PERIOD and STOP_ADV_EVT_PERIOD to define the duty cycle.

    I run it on the CC2541 Keyfob and it works flawless.

    /**************************************************************************************************
      Filename:       simpleBLEBroadcaster.c
      Revised:        $Date: 2010-08-06 08:56:11 -0700 (Fri, 06 Aug 2010) $
      Revision:       $Revision: 23333 $
    
      Description:    This file contains the Simple BLE Broadcaster sample application 
                      for use with the CC2540 Bluetooth Low Energy Protocol Stack.
    
      Copyright 2011 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 "bcomdef.h"
    #include "OSAL.h"
    #include "OSAL_PwrMgr.h"
    
    #include "OnBoard.h"
    #include "hal_adc.h"
    #include "hal_led.h"
    #include "hal_key.h"
    #include "hal_lcd.h"
    
    #include "hci.h"
    #include "gap.h"
    
    #include "devinfoservice.h"
    #include "broadcaster.h"
    
    #include "simpleBLEBroadcaster.h"
    
    /*********************************************************************
     * MACROS
     */
    
    /*********************************************************************
     * CONSTANTS
     */
    
    // What is the advertising interval when device is discoverable (units of 625us, 160=100ms)
    #define DEFAULT_ADVERTISING_INTERVAL          160
    
    // Company Identifier: Texas Instruments Inc. (13)
    #define TI_COMPANY_ID                         0x000D
    
    // Length of bd addr as a string
    #define B_ADDR_STR_LEN                        15
    
    /*********************************************************************
     * TYPEDEFS
     */
    
    /*********************************************************************
     * GLOBAL VARIABLES
     */
    
    /*********************************************************************
     * EXTERNAL VARIABLES
     */
    
    /*********************************************************************
     * EXTERNAL FUNCTIONS
     */
    
    /*********************************************************************
     * LOCAL VARIABLES
     */
    static uint8 simpleBLEBroadcaster_TaskID;   // Task ID for internal task/event processing
    
    // GAP - SCAN RSP data (max size = 31 bytes)
    static uint8 scanRspData[] =
    {
      // complete name
      0x15,   // length of this data
      GAP_ADTYPE_LOCAL_NAME_COMPLETE,
      0x53,   // 'S'
      0x69,   // 'i'
      0x6d,   // 'm'
      0x70,   // 'p'
      0x6c,   // 'l'
      0x65,   // 'e'
      0x42,   // 'B'
      0x4c,   // 'L'
      0x45,   // 'E'
      0x42,   // 'B'
      0x72,   // 'r'
      0x6f,   // 'o'
      0x61,   // 'a'
      0x64,   // 'd'
      0x63,   // 'c'
      0x61,   // 'a'
      0x73,   // 's'
      0x74,   // 't'
      0x65,   // 'e'
      0x72,   // 'r'
    
      // Tx power level
      0x02,   // length of this data
      GAP_ADTYPE_POWER_LEVEL,
      0       // 0dBm  
    };
    
    // GAP - Advertisement data (max size = 31 bytes, though this is
    // best kept short to conserve power while advertisting)
    static uint8 advertData[] = 
    { 
      // Flags; this sets the device to use limited discoverable
      // mode (advertises for 30 seconds at a time) instead of general
      // discoverable mode (advertises indefinitely)
      0x02,   // length of this data
      GAP_ADTYPE_FLAGS,
      GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
    
      // three-byte broadcast of the data "1 2 3"
      0x04,   // length of this data including the data type byte
      GAP_ADTYPE_MANUFACTURER_SPECIFIC,      // manufacturer specific advertisement data type
      1,
      2,
      3
    };
    
    /*********************************************************************
     * LOCAL FUNCTIONS
     */
    static void simpleBLEBroadcaster_ProcessOSALMsg( osal_event_hdr_t *pMsg );
    static void peripheralStateNotificationCB( gaprole_States_t newState );
    
    #if defined( CC2540_MINIDK )
    static void simpleBLEBroadcaster_HandleKeys( uint8 shift, uint8 keys );
    #endif
    
    #if (defined HAL_LCD) && (HAL_LCD == TRUE) 
    static char *bdAddr2Str ( uint8 *pAddr );
    #endif // (defined HAL_LCD) && (HAL_LCD == TRUE) 
    
    /*********************************************************************
     * PROFILE CALLBACKS
     */
    
    // GAP Role Callbacks
    static gapRolesCBs_t simpleBLEBroadcaster_BroadcasterCBs =
    {
      peripheralStateNotificationCB,  // Profile State Change Callbacks
      NULL                            // When a valid RSSI is read from controller (not used by application)
    };
    
    /*********************************************************************
     * PUBLIC FUNCTIONS
     */
    
    /*********************************************************************
     * @fn      SimpleBLEBroadcaster_Init
     *
     * @brief   Initialization function for the Simple BLE Broadcaster App
     *          Task. This is called during initialization and should contain
     *          any application specific initialization (ie. hardware
     *          initialization/setup, table initialization, power up
     *          notificaiton ... ).
     *
     * @param   task_id - the ID assigned by OSAL.  This ID should be
     *                    used to send messages and set timers.
     *
     * @return  none
     */
    void SimpleBLEBroadcaster_Init( uint8 task_id )
    {
      simpleBLEBroadcaster_TaskID = task_id;
    
      // Setup the GAP Broadcaster Role Profile
      {
        #if defined( CC2540_MINIDK )   
          // For the CC2540DK-MINI keyfob, device doesn't start advertising until button is pressed
          uint8 initial_advertising_enable = FALSE;
        #else
          // For other hardware platforms, device starts advertising upon initialization
          uint8 initial_advertising_enable = TRUE;
        #endif
    
        // By setting this to zero, the device will go into the waiting state after
        // being discoverable for 30.72 second, and will not being advertising again
        // until the enabler is set back to TRUE
        uint16 gapRole_AdvertOffTime = 0;
          
        //uint8 advType = GAP_ADTYPE_ADV_NONCONN_IND;   // use non-connectable advertisements
        uint8 advType = GAP_ADTYPE_ADV_DISCOVER_IND; // use scannable unidirected advertisements
    
        // Set the GAP Role Parameters
        GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &initial_advertising_enable );
        GAPRole_SetParameter( GAPROLE_ADVERT_OFF_TIME, sizeof( uint16 ), &gapRole_AdvertOffTime );
        
        GAPRole_SetParameter( GAPROLE_SCAN_RSP_DATA, sizeof ( scanRspData ), scanRspData );
        GAPRole_SetParameter( GAPROLE_ADVERT_DATA, sizeof( advertData ), advertData );
    
        GAPRole_SetParameter( GAPROLE_ADV_EVENT_TYPE, sizeof( uint8 ), &advType );
      }
    
      // Set advertising interval
      {
        uint16 advInt = DEFAULT_ADVERTISING_INTERVAL;
    
        GAP_SetParamValue( TGAP_LIM_DISC_ADV_INT_MIN, advInt );
        GAP_SetParamValue( TGAP_LIM_DISC_ADV_INT_MAX, advInt );
        GAP_SetParamValue( TGAP_GEN_DISC_ADV_INT_MIN, advInt );
        GAP_SetParamValue( TGAP_GEN_DISC_ADV_INT_MAX, advInt );
      }
      
    #if defined( CC2540_MINIDK )
     
      // Register for all key events - This app will handle all key events
      RegisterForKeys( simpleBLEBroadcaster_TaskID );
      
      // makes sure LEDs are off
      HalLedSet( (HAL_LED_1 | HAL_LED_2), HAL_LED_MODE_OFF );
      
      // For keyfob board set GPIO pins into a power-optimized state
      // Note that there is still some leakage current from the buzzer,
      // accelerometer, LEDs, and buttons on the PCB.
      
      P0SEL = 0; // Configure Port 0 as GPIO
      P1SEL = 0; // Configure Port 1 as GPIO
      P2SEL = 0; // Configure Port 2 as GPIO
    
      P0DIR = 0xFC; // Port 0 pins P0.0 and P0.1 as input (buttons),
                    // all others (P0.2-P0.7) as output
      P1DIR = 0xFF; // All port 1 pins (P1.0-P1.7) as output
      P2DIR = 0x1F; // All port 1 pins (P2.0-P2.4) as output
      
      P0 = 0x03; // All pins on port 0 to low except for P0.0 and P0.1 (buttons)
      P1 = 0;   // All pins on port 1 to low
      P2 = 0;   // All pins on port 2 to low  
      
    #endif // #if defined( CC2540_MINIDK )
    
    #if (defined HAL_LCD) && (HAL_LCD == TRUE)  
    
      HalLcdWriteString( "BLE Broadcaster", HAL_LCD_LINE_1 );
      
    #endif // (defined HAL_LCD) && (HAL_LCD == TRUE)  
      
      // Setup a delayed profile startup
      osal_set_event( simpleBLEBroadcaster_TaskID, SBP_START_DEVICE_EVT );
    }
    
    /*********************************************************************
     * @fn      SimpleBLEBroadcaster_ProcessEvent
     *
     * @brief   Simple BLE Broadcaster Application Task event processor. This
     *          function is called to process all events for the task. Events
     *          include timers, messages and any other user defined events.
     *
     * @param   task_id  - The OSAL assigned task ID.
     * @param   events - events to process.  This is a bit map and can
     *                   contain more than one event.
     *
     * @return  events not processed
     */
    uint16 SimpleBLEBroadcaster_ProcessEvent( uint8 task_id, uint16 events )
    {
      
      VOID task_id; // OSAL required parameter that isn't used in this function
      
      if ( events & SYS_EVENT_MSG )
      {
        uint8 *pMsg;
    
        if ( (pMsg = osal_msg_receive( simpleBLEBroadcaster_TaskID )) != NULL )
        {
          simpleBLEBroadcaster_ProcessOSALMsg( (osal_event_hdr_t *)pMsg );
    
          // Release the OSAL message
          VOID osal_msg_deallocate( pMsg );
        }
    
        // return unprocessed events
        return (events ^ SYS_EVENT_MSG);
      }
    
      if ( events & SBP_START_DEVICE_EVT )
      {
        // Start the Device
        VOID GAPRole_StartDevice( &simpleBLEBroadcaster_BroadcasterCBs );
        
        return ( events ^ SBP_START_DEVICE_EVT );
      }
      
      // Discard unknown events
      return 0;
    }
    
    /*********************************************************************
     * @fn      simpleBLEBroadcaster_ProcessOSALMsg
     *
     * @brief   Process an incoming task message.
     *
     * @param   pMsg - message to process
     *
     * @return  none
     */
    static void simpleBLEBroadcaster_ProcessOSALMsg( osal_event_hdr_t *pMsg )
    {
      switch ( pMsg->event )
      {
      #if defined( CC2540_MINIDK )
        case KEY_CHANGE:
          simpleBLEBroadcaster_HandleKeys( ((keyChange_t *)pMsg)->state, ((keyChange_t *)pMsg)->keys );
          break;
      #endif // CC2540_MINIDK
          
      default:
        // do nothing
        break;
      }
    }
    
    #if defined( CC2540_MINIDK )
    /*********************************************************************
     * @fn      simpleBLEBroadcaster_HandleKeys
     *
     * @brief   Handles all key events for this device.
     *
     * @param   shift - true if in shift/alt.
     * @param   keys - bit field for key events. Valid entries:
     *                 HAL_KEY_SW_2
     *                 HAL_KEY_SW_1
     *
     * @return  none
     */
    static void simpleBLEBroadcaster_HandleKeys( uint8 shift, uint8 keys )
    {
      VOID shift;  // Intentionally unreferenced parameter
    
      if ( keys & HAL_KEY_SW_2 )
      {
        // ressing the right key should toggle advertising on and off
        uint8 current_adv_enabled_status;
        uint8 new_adv_enabled_status;
        
        //Find the current GAP advertisement status
        GAPRole_GetParameter( GAPROLE_ADVERT_ENABLED, &current_adv_enabled_status );
        
        if( current_adv_enabled_status == FALSE )
        {
          new_adv_enabled_status = TRUE;
        }
        else
        {
          new_adv_enabled_status = FALSE;
        }
        
        //change the GAP advertisement status to opposite of current status
        GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &new_adv_enabled_status );
      }
    }
    #endif // CC2540_MINIDK
    
    /*********************************************************************
     * @fn      peripheralStateNotificationCB
     *
     * @brief   Notification from the profile of a state change.
     *
     * @param   newState - new state
     *
     * @return  none
     */
    static void peripheralStateNotificationCB( gaprole_States_t newState )
    {
      switch ( newState )
      {
        case GAPROLE_STARTED:
          {    
            uint8 ownAddress[B_ADDR_LEN];
            
            GAPRole_GetParameter(GAPROLE_BD_ADDR, ownAddress);
        
            #if (defined HAL_LCD) && (HAL_LCD == TRUE)
              // Display device address 
              HalLcdWriteString( bdAddr2Str( ownAddress ),  HAL_LCD_LINE_2 );
              HalLcdWriteString( "Initialized",  HAL_LCD_LINE_3 );
            #endif // (defined HAL_LCD) && (HAL_LCD == TRUE)    
          }
          break;
          
        case GAPROLE_ADVERTISING:
          {
            #if (defined HAL_LCD) && (HAL_LCD == TRUE)
              HalLcdWriteString( "Advertising",  HAL_LCD_LINE_3 );
            #endif // (defined HAL_LCD) && (HAL_LCD == TRUE)            
          }
          break;
    
        case GAPROLE_WAITING:
          {
            #if (defined HAL_LCD) && (HAL_LCD == TRUE)
              HalLcdWriteString( "Waiting",  HAL_LCD_LINE_3 );
            #endif // (defined HAL_LCD) && (HAL_LCD == TRUE)            
          }
          break;          
    
        case GAPROLE_ERROR:
          {
            #if (defined HAL_LCD) && (HAL_LCD == TRUE)
              HalLcdWriteString( "Error",  HAL_LCD_LINE_3 );
            #endif // (defined HAL_LCD) && (HAL_LCD == TRUE)            
          }
          break;      
          
        default:
          {
            #if (defined HAL_LCD) && (HAL_LCD == TRUE)
              HalLcdWriteString( "",  HAL_LCD_LINE_3 );
            #endif // (defined HAL_LCD) && (HAL_LCD == TRUE)     
          }        
          break; 
      }
    }
    
    #if (defined HAL_LCD) && (HAL_LCD == TRUE)
    /*********************************************************************
     * @fn      bdAddr2Str
     *
     * @brief   Convert Bluetooth address to string. Only needed when
     *          LCD display is used.
     *
     * @return  none
     */
    char *bdAddr2Str( uint8 *pAddr )
    {
      uint8       i;
      char        hex[] = "0123456789ABCDEF";
      static char str[B_ADDR_STR_LEN];
      char        *pStr = str;
      
      *pStr++ = '0';
      *pStr++ = 'x';
      
      // Start from end of addr
      pAddr += B_ADDR_LEN;
      
      for ( i = B_ADDR_LEN; i > 0; i-- )
      {
        *pStr++ = hex[*--pAddr >> 4];
        *pStr++ = hex[*pAddr & 0x0F];
      }
      
      *pStr = 0;
      
      return str;
    }
    #endif // (defined HAL_LCD) && (HAL_LCD == TRUE) 
    
    /*********************************************************************
    *********************************************************************/
    

    2502.simpleBLEBroadcaster.h

    Best Regards

  • Hi Nick,

    Let me explain you completely what i did.

    First after i bought the kit, i loaded the usb dongle with the usb dongle hex file and then haven't changed it yet.

    I initially tested the keyfob with the keyfob hex file and tested. it worked fine.

    Then I tested with the SimpleBLEBroadcaster original code from TI's BLE stack and it worked i.e the device starts advertising only after the right button is pressed.

    Later, I modified the same code in IAR for advertising without button being pressed. That too worked. 

    Now if I again copy your whole code which you have tagged in the previous post and rewrite it  on IAR, its NOT working.

    I mean I have flashed the newly generated hex file into the keyfob and tried. But without the button being pressed, it is displaying the mac address spontaneously . I dont know the reason behind this. 

    Is it that if we overwrite or do editing in the existing application programs from TI in the IAR workbench , this problem will occur?

    Please telme a possible solution..

    Thanks..

  • hey how to change the advertising time