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.

Alternate between Central and Peripheral roles

Other Parts Discussed in Thread: CC2541, CC2540

I'm starting on a SensorTag application which at times needs to be a BLE Central device. The Peripheral and Central roles will alternate; i.e. at any one time the sensorTag will be either a Central or Peripheral device. Api documentation, wiki sample code and threads on this forum raise some questions.

1. Has anyone been successful repeatedly switching between Central and Peripheral roles?

2. The wiki example (http://processors.wiki.ti.com/index.php/MasterSlaveSwitch ) appears to be calling GAPCentralRole_StartDevice and GAPRole_StartDevice multiple times, but the API documentation says these api's should be called once only.

3. My approach would be to switch between roles only when roles are idle: Peripheral not connected nor advertising, Central not connected, not connecting and not discovering.  In such a case, is it still necessary to call the <xxx>_StartDevice api's to effect a switch?

TIA for any insights.

- Richard

  • 4. Which BLE library should one link with?  The v1.2 MasterSlaveSwitch example uses CC2541_ble_single_chip_all.lib, but this library doesn't exist in the v1.3 distribution.

  • Richard,

    I tried the role switch using the MasterSlaveSwitch example from TI but it didn't work for me. When the device started as Peripheral and switched to Central, it did not detect devices during scan (never received the GAP_DEVICE_INFO_EVENT event). When started as Central and switched to Peripheral, advertising never went out (used the sniffer to check that).

    Same results with 1.2 and 1.3.

    If you find a way to make it work I'd love to hear about it.

    --Tom

  • We've given up trying to get this to work, suspect its not supported by TI BLE stack.

    Instead, we've changed our topology to eliminate the need for supporting both roles in one device.  More of a work-around than real solution :-(

  • I'd love it if one of TI's reps can comment on this topic. I've seen multiple posts of people who failed to make the role switch work and not a single post reporting success.

  • TI may unwittingly added to the confusion by conflating master/slave roles with Central/Peripheral roles.  

    At the link level, there are master and slave roles.  TI might support switching those roles via HCI command.  

    At the GATT profile level, there are Central and Peripheral roles.  While the Central is typically the LL master and peripheral typically the LL slave, the GATT and link-level roles are orthogonal to one another.

    This thread is about having a single device alternate between Central and Peripheral roles, without regard to the link-level roles.

  • I agree, TI did confuse the two. Their MasterSlaveSwitch example project is really about switching between GAP Peripheral and Central roles.

  • Hi,

    I can switch between Central and Peripheral roles with their MasterSlave example with SDK 1.2.1

    My product has an external MCU connected to CC2540 via the UART. I can send command to ask it to switch.

    I also think, it is also possible to use an I/O and another pin to control the reset of CC2540, for example, pull low the pin and the reset the CC2540, when CC2540 starts up and the I/O pin is low, then go to Central role, otherwise, go to Peripheral.

    -YC

  • Hi YC,

    That's very interesting.  Can you share which version of TI stack you're using, 1.2 or 1.3?  Which BLE library do you link with?

    Thanks,

    Richard

  • Hi Richard,

    I am using stack 1.2.1, and the library is CC2540_ble_single_chip_all.lib

    -YC

  • I'm new to this, but I think you can create a Central/Peripheral device using the MasterSlaveSwitch example as reference.  You have to use the library CC2540_BLE.lib if you intend to use the 1.3 stack.

  • Update from further testing - Leo is right, the v1.3 CC254x_BLE.lib contains both Central and Peripheral roles; linking with that library I am able to run either role in the same program image.

    However, dynamically switching roles at runtime doesn't really work. It seems that the peripheral role can only be started one time; the second time that GAPRole_StartDevice() is called it returns status code 0x11 "bleAlreadyInRequestedMode" and the device is not discoverable and cannot be made discoverable by disabling and reenabling advertising

    To summarize results of role-switch testing:
    Central -> Peripheral, works
    Central -> Peripheral -> Central, works
    Central -> Peripheral -> Central -> Peripheral, FAILS peripheral is not advertising second time it is started
    Peripheral -> Central works
    Peripheral -> Central -> Peripheral, FAILS peripheral is not advertising second time it is started

    It also works to restart the processor each time a role switch is desired; initialization logic chooses a role and then sticks with that role (until the next reset).

  • My findings are very similar to Richard's, except I didn't find the Central -> Peripheral -> Central case to work. Or maybe it depends on the definition of "work"... The role switch (P -> C) does happen with no errors and I could even started a scan, but no devices were found even though devices were advertising (verified with a sniffer).

    Richard, were you able to discover other devices when you switched from Peripheral to Central?

    --Tom

  • Yes, in my testing the central role worked consistently; was able to connect, read and write characteristics and disconnect repeatedly.  I am calling GAPCentralRole_StartDevice() each time I switch from Peripheral to Central role.  Using stack version v1.3.

  • I think you can make the switching work by sending a reset signal on the reset line/pin of the CC254x and just use a port to determine whether to boot up in the central role or in the peripheral role.  This solution is however application-dependent.

  • Richard,

    When switching back to peripheral role, did you make sure that gapRole_state = GAPROLE_INIT before calling the GAPRole_StartDevice for a second time?

    Leo

  • Hi,

    This is a link to a beta version of the masterSlaveSwitch ported to 1.3.1.

    http://e2e.ti.com/cfs-file.ashx/__key/communityserver-components-userfiles/00-00-11-75-55/masterslaveswitch.zip

    http://e2e.ti.com/cfs-file.ashx/__key/communityserver-components-userfiles/00-00-11-75-55/peripheral_5F00_masterslaveswitch.c

    I can't guarantee that it works completely, and it seems you have figured out everything for yourselves. The main issue is a small change to peripheral.c (new version in the second link) to allow multiple invocations of the start device function.

    It should also work with 1.3.2 when this modification is done to peripheral.c;

    bStatus_t GAPRole_StartDevice( gapRolesCBs_t *pAppCallbacks )
    {
    if ( gapRole_state == GAPROLE_INIT ||
    (!gapRole_AdvEnabled && (gapRole_state == GAPROLE_WAITING || gapRole_state == GAPROLE_WAITING_AFTER_TIMEOUT ) ) )
    {
    // Clear all of the Application callbacks
    if ( pAppCallbacks )

    The important variables in the project are (see associated typedef enums for more info):

    -          deviceRole (ROLE_PERIPHERAL or ROLE_CENTRAL)

    -          gapPeripheralState – state of the peripheral. Must be _STARTED, _INIT, _WAITING or _WAITING_AFTER_TIMEOUT when switching. I.e. all connections and advertisements must have ceased.

    -          gapCentralState – state of the central. Must be _INIT_DONE or _DISCONNECTED when switching

     

    The switching is handled in two stages

    Button DOWN (four way joystick) initiates switching.

    -          If something is going on, attempt to stop this. I.e. disconnect, stop advertising.

    o   And set deviceRole to the opposite value

    -          When callback of the completion of the Stop/Disconnect is received, set the switch event.

    o   For Peripheral, callback is in peripheralStateNotificationCB(), case WAITING

    o   For Central, callback is in simpleBLECentralEventCB(), case LINK_TERMINATED

    -          If nothing is going on, set switching event immediately.

    In other words, the switching is done in

    1.       masterSlaveSwitch_HandleKeys() -> if( keys & HAL_KEY_DOWN )

    2.       GapRole callbacks

    a.       peripheralStateNotificationCB(), case WAITING

    b.      simpleBLECentralEventCB(), case LINK_TERMINATED

    3.       MasterSlaveSwitch_ProcessEvent() -> if ( events & MSS_CHANGE_ROLE_EVT )

     

     The peripheral automatically advertises, the central scans when you press UP, connects when you press LEFT (to choose) and CENTER (to connect).


    Best regards,
    Aslak 

  • hello  

    I download the masterSlaveSwitch you have given

    http://e2e.ti.com/cfs-file.ashx/__key/communityserver-components-userfiles/00-00-11-75-55/masterslaveswitch.zip

    then, I compile it  in the  BLE-1.3.2,but it was error like this:

    Fatal Error[Pe1696]: cannot open source file "C:\Texas Instruments\BLE-CC254x-1.3.2\Projects\ble\Profiles\ExampleService\exampleService.c"

    I can't  find the file "exampleService.c" in BLE-CC254x-1.3.2 folder,can you give the link to us to download the file ? 

    sorry for poor english, thank you very much!

  • On compile, I have several errors related to files that cannot be found in the project source tree. The errors are:

    Fatal Error[Pe1696]: cannot open source file "E:\Projects\BLE-CC254x-1.3.2_masterSlaveSwitch\Projects\ble\Profiles\ExampleService\exampleService.c"

    Fatal Error[Pe1696]: cannot open source file "E:\Projects\BLE-CC254x-1.3.2_masterSlaveSwitch\Components\hal\target\CC2540EB\hal_crc.c"

    Fatal Error[Pe1696]: cannot open source file "exampleService.h"

    Fatal Error[Pe1696]: cannot open source file "E:\Projects\BLE-CC254x-1.3.2_masterSlaveSwitch\Projects\ble\common\npi\npi_np\npi.c"

    Fatal Error[Pe1696]: cannot open source file "hci_tl.h"

  • Can anyone instruct me on where to find the "ExampleService" files exampleService.c and exampleService.h ???

  • Would you please instruct me on where to find the "ExampleService" files exampleService.c and exampleService.h ? Thank you in advance for your kind assistance in this matter.