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??
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.
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, ¤t_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, ¤tTxPowerLevel );
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, ¤t_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, ¤t_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)
/*********************************************************************
*********************************************************************/
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..