Skip navigation
Home > All Places > Software Forums > WICED Smart Bluetooth > WICED Smart Bluetooth Forums > Blog
1 2 3 Previous Next

WICED Smart Bluetooth Forums

44 posts

The maximum LL PDU (Packet Data Unit) for BLE 4.1 is 27 Bytes. In these 27 Bytes, the actual data that is transferred as a GATT Write or Notification can be upto 20 bytes, excluding the L2CAP header, Data PDU Header and Attribute Operation Code. If the link is encrypted, the LL PDU will additionally have a 4 Byte MIC (Message Integrity Check), there by making the LL PDU as 31 Bytes.


The LL Packet comprises of LL PDU (31 Bytes) + PDU Header (2 Bytes) Header (1 Bytes) + Access Address (4 Bytes) + Cyclic Redundancy Check (3 Bytes)

= 41 Bytes

= 41 * 8 Bits

= 328 Bits


The propagation time of each bit is 1uS. So for 328 Bits it is 328 uS. After each packet is sent, an additional 80 uS is spent for acknowledgement. Also, there is T_IFS, (Interframe time between a packet and acknowledgement and also between acknowledgement and next packet)


So time taken for 1 packet to be sent is:


328uS (actual data) + 150 uS (T_IFS) + 80 uS + 150 uS (T_IFS) = 708 uS


The number of packets per connection interval = Connection interval / 708 uS.

If the connection  interval is 7.5 mS, approximately, 10 packets can be sent.


The relation between the throughput and the connection interval is not so straight forward. As discussed in the previous interaction the time taken for sending 20 bytes is 708 uS.


Now let us discuss this with 3 cases of connection interval:


1) Assume that connection interval is 7.5 mS.

Number of packets sent is 7.5 mS / 708 uS = 10 packets.

Actually 708 uS * 10 = 7080 uS = 7.08 mS. So remaining 0.42 mS is idle (wasted)


2) Assume that connection interval is 8.75 mS.

Number of packets sent is 7.5 mS / 708 uS = 12 packets.

Actually 708 uS * 10 = 7080 uS = 8.496 mS. So remaining is only 0.254 mS is idle (wasted) (8.75 - 8.496 = 0.254 mS)


3) Assume that connection interval is 11.25 mS.

Number of packets sent is 11.25 mS / 708 uS = 15 packets

Actually 708 uS * 15 = 7080 uS = 10.620 mS. So remaining is 0.63mS is idle (wasted).


If you compare 1 and 2, increase in connection interval will result in less idle time. So increased throughput.

If you compare 2 and 3, increase in connection interval will result in more idle time. So less throughput.


So throughput and connection interval will not have a linear relation. However, if you increase the connection interval, power consumption will decrease. And vice versa. Because, less the connection interval, more often it has to be switched from sleep to awake and vice versa.

Back to main page: Leveraging TAG4 to better understand the WICED Smart Programming Environment



Formal Tag4 Documentation:

Hardware User Guide (SDK 2.x and TAG4 Board)

WICED Smart Quick Start Guide (SDK 2.x and TAG4 Board)




Tag 4 Quick Hardware Setup:


       1. Default switch settings for USB power, Booting SFLASH:

                 A. SW6 – 2,4 ON, rest OFF

                 B. SW9 – all ON

                 C. SW8 – 2, 3, 6, 7, 8 ON, rest OFF

                 D. SW4 - VUSBs

                 E. SW5 – VREG

       2. On it's very first download, the board requires a recovery:

                 A. Press-hold BOOT, press-release RESET, release BOOT

                 B. Edit any make target: replace “download” with “recover UART=COMxx”

                 C. Use make target. Replace ‘xx’ with your COM port (found in Device Manager)

                 D. Double click make target to execute build.

       NOTE: After your initial recovery, regular “download” can be used.


Tag 4 Traces:


       1. Start traces:

                 A. Download your app

                 B. Switch SW6 1,2,3 OFF, 4 ON

                 C. Enable traces on the SDK (WICED Smart IDE > Trace > Start Debug Traces)

                 D. Press reset button

       2. Stop traces:

                 A. Disable traces on the SDK (WICED Smart IDE > Trace > Stop Debug Traces)

                 B. Switch SW6 1, 3 OFF, 2, 4 ON

                 C. Power cycle the Tag 4 board

       NOTE: if the board is not power cycled after stopping traces it will not download

       NOTE: the SDK traces must be stopped before they will start again.


Tag 4 Power Measurements:


       1. Basic Power measurement

                 A. Remove R29

                 B. Attach power analyzer to J12

                 C. Run an app, and start analysis

                 NOTE: Leads of J12 must be shorted by power analyzer in order to download app

       2. Power Optimization:

                 A. 20737 Chip Specific Optimization:

                      - Move RD5 and RD6 to A-C position (switches to external DC-DC converter)

                 B. To reduce peak current of RF TX:

                     - Remove FB3, disabling FTDI chip (download your app first)

                 C. To reduce idle current of board:

                      - Remove R39: disables I2C Expander (no sensors will function)


Tag 4 Boot Sources:

       1. Boot EEPROM

                  A. SW8 – 1,3,5 ON, rest OFF

                  B. Power cycle

       2. Boot SFLASH

                  A. SW8 – 2,3,6,7,8 ON, rest OFF

                  B. Power cycle

       3. Boot ROM only

                  A. Press and hold the 'ROM' button on the board

                  B. Power cycle

                  C. Release 'ROM' button

NOTE: when switching between boot sources it is often necessary to perform a recovery


Tag 4 I2C:


       1. Without any additional action, I2C APIs will only interact with EEPROM.

       2. In order to interact with the on-board MEMS sensors and bring out I2C onto J10:

                  A. The on-board I2C expander must be output enabled by calling:


 gpio_configurePin((GPIO_PIN_P8) / 16, (GPIO_PIN_P8) % 16, GPIO_OUTPUT_ENABLE, 1);


                  B. The I2C voltage rail must be powered by calling:


 gpio_configurePin((GPIO_PIN_P2) / 16, (GPIO_PIN_P2) % 16, GPIO_OUTPUT_ENABLE, 0);



Jacob W Torres


Back to main page: Leveraging TAG4 to better understand the WICED Smart Programming Environment

Back to main page: Leveraging TAG4 to better understand the WICED Smart Programming Environment



The Tag4 platform driver can be downloaded below.


Tag 4 Quick Demo Setup:


       1. Download driver below

       2. Copy driver into your application folder

       3. In your apps make file add:

                 include $(DIR)/tag_IV_driver/
       4. In your application include:

                 #include './tag_IV_driver/tag_IV_demo.h'

       5. Call tag_IV_demo() in a loop from within you application.

       6. Ensure that SW9 is on in all positions.

       7. Run traces on the app.


       Your application folder should look like this:



Tag 4 Driver Use:


       1. In your apps make file add:

                 include $(DIR)/tag_IV_driver/

       2. In your application include:

                 #include './tag_IV_driver/tag_IV_driver.h'

       3. To use sensors, ensure that SW9 is on in all positions.

       4. Call tag_IV_ functions from main application


       NOTE: see tag_IV_demo.h for a demonstration of API use.



Jacob W Torres



Back to main page: Leveraging TAG4 to better understand the WICED Smart Programming Environment

What are connection parameters?


There are three parameters that define a connection.


Connection Interval: the connection interval is the time between connection events. When in connection a central pings the peripheral as often as is defined by this connection interval. It is the peripheral's duty to respond to this ping in order for the central to consider the connection alive. At these intervals the client can perform it's reads/writes or the peripheral can perform notifications/indications. The interval can be anywhere from 7.5ms to 4s. When the peripheral requests an updated connection interval from the central, the peripheral sends an acceptable range. This increases the likelihood that the allowable window will overlap with what the central is able to provide.


Timeout: connection supervision timeout is the maximum time since the most recent received packet that the connection will be terminated by the central. The valid timeout range is 100ms to 3200ms.


Latency: slave latency is the number of connection events the peripheral is allowed to miss. If set to zero, the peripheral must respond to every connection event. The slave latency must be less than 500 and in the range from 0 to ( supervision_timeout / interval_max ) - 1 ) so that utilizing latency doesn't violate the timeout and cause a terminated connection. If there is no data to be sent, the peripheral will skip as many connection events as is allowed by the connection latency. Once there is data to be sent, every connection event is utilized to send that data until the tx buffer is clear, at which point the peripheral will resume skipping events. This scheme helps to save battery while maintaining throughput in the generally power-constrained peripheral device.




How do we control connection parameters?


Upon initial connection, there is no negotiation of parameters. The peripheral takes whatever the central gives. Upon successful connection, the peripheral may then request different parameters that are more suitable to it's functionality i.e. a higher throughput device will want a lower connection interval, while a power constrained device with low-throughput will want the longest possible connection interval with the most lenient latency.


No matter what, the central device always has final say over the connection parameters. It's important to note that the central can do absolutely nothing if it chooses. If the central has no intention of ever updating the connection parameters, it can simply reject any update requests that are sent its way. It is up to the peripheral to kill a connection if a central won't grant the parameters it needs to maintain its functionality and/or battery life.


There are two standard methods for the peripheral to request updated parameters:



Method 1: L2CAP Connection Parameter Update Request:


Step 1. The peripheral sends an l2cap packet to the central requesting updated parameters:


           void bleprofile_SendConnParamUpdateReq(UINT16 minInterval,

                UINT16 maxInterval, UINT16 slaveLatency, UINT16 timeout);


Example use:


           bleprofile_SendConnParamUpdateReq(32, 64, 0, 10);


These parameters are in special units:


     Min Interval = minInterval* 1.25 ms

     Max Interval = maxInterval* 1.25 ms

     Supervision Timeout = timeout * 10ms


This means that, as the peripheral, I am requesting a new connection interval between 40 and 80ms, a slave latency of 0, and a supervision timeout of 100ms.

Generally, this function is used in the connection up callback and it is recommended by the spec that it be done after GATT discovery and pairing/encryption.


Step 2. The central receives the request at the l2cap level. Different centrals will do different things at this point. By default, our 20736/7 stack will automatically grant whatever the client requested as long as it is feasible for the link layer to carry it out. On the other hand, resource constrained central devices will be far less likely grant the requested parameters. An iPhone, for instance, will not grant any connection interval below 30ms except for special use-cases.


Step 3. After the peripheral sends its request, it may want to hear back from the central once the process is complete. Of course, this is an optional step. But if the peripheral chooses, it can register a callback from the stack to be alerted when a connection parameter update is complete. To do so, declare a callback handler function with no parameters, and pass the function as a parameter to bleprofile_regAppEvtHandler_leConnUpdateComplete.


               Step A.      void paramUpdateHandler( void )


                              ble_trace3("ConnParam in Timeout: %d, %d, %d",





               Step B. bleprofile_regAppEvtHandler_leConnUpdateComplete((BLEPROFILE_NO_PARAM_CB) paramUpdateHandler);




Method 2: Peripheral Preferred Connection Parameters (PPCP):


Step 1. the peripheral, instead of sending an l2cap request, puts the same requested parameters into a GATT characteristic of the mandatory GAP service. This characteristic has a value 8 octets in length. This value is further split into 2 octets per connection parameter. The format can be found below, as implemented in a4wp_power_receiver.c:


             // Handle 0x2e: characteristic preferred connection param, handle 0x2f characteristic value.

             // 0x0050 (100ms preferred min connection interval)

             // 0x00A0 (200ms preferred max connection interval)

             // 0x0000 (0 preferred slave latency)

             // 0x03E8 (10,000ms preferred supervision timeout)



                  0x50, 0x00, 0xA0, 0x00, 0x00, 0x00, 0xE8, 0x03,


Step 2. the central will, in this case, need to first find the requested connection parameters. So, it must perform a GATT discovery on the peripheral and identify and have a special case for the existence of a PPCP characteristic. The exception to this is in Attribute Caching. If two devices are already bonded and the central cached the preferred connection parameters, there is no need to perform a GATT discovery. Once the characteristic is discovered by the client, different stacks will do different things. Our 20736/37 stack does not have built in support for this method of updating parameters. It is up to the app designer to discover the peripheral characteristic, read in the requested values, and handle, at the application level, whether or not to grant the requested parameters.


If, at the application level, it is decided to grant the requested parameters, or to grant new ones at least closer to the requested, the central device can call the following API:



           * \brief Connection update request

           * \ingroup blecm


           * \details This function issues HCI LE Connection Update Command.  This

           * command may be used in the client application if it needs to update

           * connection parameters when connection is already established and

           * required parameters are different than ones requested by the peripheral. 

           * When peripheral device requests some parameters using L2CAP message, stack

           * automatically replies and sets controller appropriately and there is no

           * need to use this function call.


           * \param connHandle HCI handle of established connection

           * \param connMinInterval Minimum value for the connection event interval

           * \param connMaxInterval Maximum value for the connection event interval

           * \param connLatency Slave latency for the connection in number of connection events

           * \param supervisionTimeout Supervision timeout for the LE Link

           * \param connMinEventLen Minimum length of connection needed for this LE connection

           * \param connMaxEventLen Maximum length of connection needed for this LE connection



           void blecm_ConnectionUpdate(INT32 connHandle, INT32 connMinInterval, INT32 connMaxInterval,

                            INT32 connLatency, INT32 supervisionTimeout, INT32 connMinEventLen,

                            INT32 connMaxEventLen);


Step 3. See Method 1 for Step 3 as it will be the same process to register for a parameter update callback to be alerted when the central has updated the parameters.


*some BLE centrals are known to not utilize this method. For instance, Apple devices will not look for a PPCP characteristic in their GATT discovery, they will only respond to l2cap requests.

The beginning of every GATT database (GATTDB) within the SDK begins the comment:


      // Service change characteristic is optional and is not present


What is the service change characteristic? Why would I want it? And how would I implement it?



     When a GATT client and server connect for the very first time, the client knows nothing about the server. In order to achieve a useful relationship, the client performs a GATT discovery on the server. There are a few variations in how the client can choose to go about this--search by handle, by type, etc.--we won't delve into the specifics of discovery.

     With low power in mind, these GATT discoveries are costly. Given that the client has the resources, it is far more efficient to jot down the details of the server's GATTDB and store that locally--this is called an Attribute Cache. In order to save power, upon future reconnections, the client will not perform a GATT discovery, but rather reach into its local memory to save power on both the client and server devices.

     However, a problem arises when we change the GATTDB between connections. The client will think the servers GATTDB is of the old form and begin operating on that basis. Now, this will only happen in the field under the premise that your firmware alters the GATTDB between connections.

     How do we fix this? One way is to utilize the Service Changed Characteristic. This characteristic is essentially a way for the server to indicate to the client that a change has been made to its GATTDB. The client should then update its Attribute Cache with the newest values.




This is how you would implement it in your GATTDB:



     const UINT8 gatt_database[]=


          // Handle 0x01: GATT service



          // Indicate that entire GATTDB has been altered

          // (handles: 0x0000 - 0xffff)

          CHARACTERISTIC_UUID16(0x0002, 0x0003,



               LEGATTDB_PERM_NONE, 4),

               0x00, 0x00, 0xff, 0xff,





               0x00, 0x00,




     This characteristic is implemented under the GATT Service that is mandatory to all GATTDB's. The Service Change Characteristic has a spec defined UUID. It needs only the ability to indicate and should have no required permissions. Lastly, it needs a value length of 4 bytes. These 4 bytes are used to designate the range of handles which have been changed. The first 2 bytes are the start handle, the last 2 bytes are the stop handle. As can be seen in the code above, we have specified this range to be all handles 0x0000 - 0xffff--tlling the client to completely rediscover the GATTDB.

     Since we need to use indications, this characteristic now needs a Client Configuration Descriptor--as all server initiated communications need. This descriptor is, essentially, two client-writable bytes that allow the client to give the server permission to transmit asynchronous communications--one byte is for notifications and the other is for indications. The service changed characteristic requires the use of indications (a notification with an application level ACK).



     The actual use of the Service Changed Characteristic requires the implementation of indications, GATT discovery by the client, and a change in the GATTDB by the server. These will not be covered here, but there exist individual resources for each:


     For implementation of indications see:



     For example firmware of a GATT change see:

          Re: How to change the GATT database after init (bleapp_set_cfg) ?

     For implementation of GATT discovery see:



This is a troubleshoot guide that deals with issues on BLE devices 20737(TAG4) and WICED Sense using WICED Smart hello_client.


<1. Problems pairing with mobile device in hello_client>


In order to pair with mobile devices with the hello_client app, you will need to add the following code after blecen_Create();



On your mobile device, enable bluetooth and select hello_client in the device selection.


Note that if the device has already been paired with hello_client before and your TAG board has been re-downloaded, you will have to erase the device in order to pair again.


     - In iOS, go to Settings -> Bluetooth -> My Devices -> select information on Hello Client device, and it will give you the option to "Forget This Device."


     - Similarly in Android, go to Settings -> Bluetooth -> Paired Devices -> Select Settings on Hello Client, and you can choose to "Forget."


You will now be able to pair with your mobile device, and you should see the following screen(using LightBlue on iOS here) on your device and traces on your WICED Smart IDE.


<iOS LightBlue Pairing>

IMG_0043.jpg  IMG_0044.jpg  IMG_0045.jpg


<Trace Result Screen>

13:06:32 - Store Bonded Info 0

13:06:32 - NVRAM write status = 120 , bond info block.

13:06:32 - GetBondedInfoIdx returns 0 meaning no bonded info

13:06:33 - encryption changed: 00




13:06:33 - Store Bonded Info 0

13:06:33 - NVRAM write status = 120 , bond info block.

13:06:33 - lesmpkeys_init.

13:06:33 - VSRead returns 0038 bytes

13:06:33 -

13:06:33 -

13:06:33 - Get Keys

13:06:33 - 070000000100000045b5fd0309b9691e

13:06:33 - 080860f0e44060f2582d41bf48b96a0c

13:06:33 - 50b96d0e5d2567f04dd541911efc4028

13:06:33 - 71f432f559d54196

13:06:33 -

13:06:33 - loadIRK:

13:06:33 -

13:06:33 - Got 5 irks.

13:06:33 - addr Type: 0

13:06:33 - addr :

13:06:33 - 303e14dd815b

13:06:33 - irk :

13:06:33 - d37f6eb437c08d82e7b5b9b59c68ac4b

13:06:33 - addr Type: 0

13:06:33 - addr :

13:06:33 - 303e14dd815b

13:06:33 - irk :

13:06:33 - d37f6eb437c08d82e7b5b9b59c68ac4b

13:06:33 - addr Type: 0

13:06:33 - addr :

13:06:33 - 303e14dd815b

13:06:33 - irk :

13:06:33 - d37f6eb437c08d82e7b5b9b59c68ac4b

13:06:33 - addr Type: 0

13:06:33 - addr :

13:06:33 - 303e14dd815b

13:06:33 - irk :

13:06:33 - d37f6eb437c08d82e7b5b9b59c68ac4b

13:06:33 - addr Type: 0

13:06:33 - addr :

13:06:33 - 303e14dd815b

13:06:33 - irk :

13:06:33 - d37f6eb437c08d82e7b5b9b59c68ac4b



<2. Can connect with some devices but having problems with multiple hosts>

You will need to include the smp_multi_key.a patch for pairing with multiple hosts. Otherwise multiple keys would get messed up in the storage. This patch also allows you to loop over the max number of devices, which is set to 5 by default. Using this patch the 6th device connected would take the key storage space of the first device, the 7th device the 2nd, and so on so forth. On the second loop the 11th device would be stored in the 6th device key storage entry.


To do this, open the in WICED-Smart-SDK/Apps/hello_client/ and add the following line.

APP_PATCHES_AND_LIBS += smp_multi_key_storage.a


One thing to be careful of is once the key storage is taken over for an older device, you will have to "forget" hello_client on your mobile device, otherwise it will not be able to bond. Once you forget hello_client from your device, you can pair with hello_client again and the key will be stored in a new spot, recognized as a new device.


Please download the new patch available (attached) and rename it to smp_multi_key_storage.a and replace the old version in WICED-Smart-SDK\Wiced-Smart\tier2\brcm\libraries\lib\20736\ or \20737. With the older version of the patch that is included in the SDK, it has a bug that memory gets corrupted and there is data loss of bonded devices after two loops of the bonding table (10 entries with the max number of devices as 5)


The new patch also has an added API that lets you change the maximum number of devices in the bonding table.

// To setup the max number of bonded devices .

void lesmpkeys_set_maxNumOfBondedDevice(UINT8 num);




<3. Running into memory issues on multiple devices>


This stems from insufficient memory allocated to the bonding table if you are using part of the NVRAM area for custom storage. You can solve this in the following two ways.


  1. Change the max number of devices to a lower number (see above) and see if the next device successfully loops through the bonding table and gets stored correctly.
  2. If you do not want to change the max number of devices, you need to allocate more space for the bonding table. Change the Platforms/BCM92073*TAG_Q32/2073*_EEPROM.btp file as needed. This is an example for allowing enough space for 5 keys when storing custom parameters in NVRAM area.
    • DLConfigVSLength to 2048
    • ConfigDSLocation to 2432

This should give the key storage section enough space to accommodate 5 keys.



<4. Issues with OTA after changing memory map as in 3. b>


If you decide to take the 3. b route, you will have to change parameters for OTA, otherwise the memory map will not match when you try a firmware upgrade.


The default layout for EEPROM and Serial flash is in WICED-Smart-SDK\Apps\ota_firmware_upgrade\ws_upgrade.c. When you move dynamic section (DS) in the .btp file, you have to update ws_upgrade.c, and change the corresponding values in nv_loc_len[].



The attached sample app implements the HW timer. Run traces on the app to see the HW timer callback fire once every 100ms--10 times for every SW timeout loop.


The necessary components to get the HW timer working are (see attached .c file for full implementation):


     -Disable sleep:   

          1.  #include "devicelpm.h"

          2.  devlpm_registerForLowPowerQueries(hello_hw_timer_device_lpm_queriable, 0);

          3.  UINT32 hello_hw_timer_device_lpm_queriable(LowPowerModePollType type, UINT32 context) { return 0; }


     -Import patch and declaration:

          1.  #include "hw_timer.h"

          2.  In your make target add:

                    APP_PATCHES_AND_LIBS += hw_timer.a

          3.  declare in your .c :

                    extern void hw_timer_int_handler(void);


     -Define callback (must call stop, only call start is you want a loop):

          void hw_timer_int_handler(void)



               //do something





          1.  hw_timer_register_timer_expired_callback(hw_timer_int_handler);

          2.  hw_timer_start(100000);



    See Sleep Deep_Sleep Explanation and Techniques for alternate methods of disabling sleep.



How to debug non-responsive customer based hardware


So, you've got your custom hardware back from the build facility.  It's populated with one of those sexy Broadcom Bluetooth devices.  An exuberant crowd of managers and team leaders is milling about the lab, watching with anticipation as you attach the power source.  The gleeful moment arrives, and you flip the switch to ON -- Viola!  ...  Nothing happens.  Nada.  Zip. Nilch.   Maybe you had expected the board's LED to start pulsing indicating the application firmware (pre-programmed into the non-volatile memory) is running.   You did pre-program the EEPROM/SFLASH right?   Maybe you're just happy there was no smoke, popping sounds, or the acrid smell of "burnt Roast Beef" when the design is bad, or assembled using wrong/misplaced component(s).  With a "pat on the back" and some encouraging words, management slinks-away to perform whatever their job function is; leaving you scratching your head and saying "Huh?".  You reach for the schematics and an oscilloscope probe...    Now what do you do?


Before you post a help request on the Community Forum (WICED Smart Bluetooth Forums), please consider some of the fundamental steps Broadcom recommends you try first.


We remind the reader there are three topologies in which Broadcom devices can operate which may impact how to debug the design:


  1. Chip on Board or System On a Chip (COB and SOC terms can be used interchangeably) - SOC designs use discreet components and are often very similar to Broadcom's TAG3 or TAG4 evaluation boards.  In SOC designs, the (integrated) Broadcom radio and MCU is populated as one-component with additional circuitry added around it, such as the EEPROM, ferrite beads, capacitors/resistors, antenna, and (optional) 32KHz crystal.  Broadcom's Bluetooth SOC device stenciling (part number markings) DO NOT end with the letter S, L, or an E  and come in a 32pin QFN package.  SOC designs are perhaps easiest to debug because you can get a scope probe on virtually everything that can go wrong.  Note: Devices stenciled with an S, L, or an E are covered next under the SIP topology.
  2. System In Package (aka SIP) - a SIP offers the majority of the necessary components all-in-one package, including the antenna.  They come with (Limited Module) FCC/UL/CE pre-certifications resulting in your company only needing to perform Spurious Emissions testing.  Certifications can save hundreds of thousands of dollars, not to mention time to market and testing hassles. Some customer designs consist of only the Broadcom SIP and a battery!   Presently, three flavors of the SIP are available and offer different features depending on the requirements (power, size, RF expertise, etc). These part numbers end with an S, L, or an E and come in a 49pin LGA package.   SIPs are rarely defective, so debugging them is usually a function of getting the on-board 64k-byte EEPROM programmed with the users application.
  3. Modules - Broadcom's Partners offer world-class products and services!  Our partners offer everything from device procurement, design services, Broadcom SDK Abstraction, FCC/UL/CE certified modules, to mass production and plastics up to and including Cloud Services. If you're reading this debug Blog, chances are you are not using one of our partner's devices/services because it would already be working for you.


Debugging hardware is easier when able to perform A<->B comparison tests/measurements against a known-good design.    You can purchase a  Broadcom TAG3/TAG4/WICED-Sense evaluation board, or evaluation boards from Broadcom's partners (IoT Partner Solutions) at this link:  Purchase a WICED Bluetooth Dev Kit


Documentation for the TAG3/TAG4 (COB/SOC) eval boards, and SOC/SIP Technical Reference Manuals are found here: WICED Bluetooth Documents & Downloads


While debugging, you must have access to these pins (at a minimum):   VCC/VDD/VIN, HCI_UART_TX, GND, HCI_UART_RX, RESET_N


During debug/initial programming of the NVRAM, it's strongly advised to use a USB<->RS232 serial cable (one option is model #TTL-232RG-VREG3V3-WE found here: Programming the TAG2/TAG3 Board using command line tools).


Debug steps:

    1. Visual Inspection for Mechanical / Assembly problems - Grab your magnifying glass and meticulously inspect both sides of the printed circuit board (PCB). Does anything look bent, damaged, or out of place?  Are there any solder bridges, or open-connections on the fine-pitch (device) pins?   Does anything look like it has experienced high-heating duress?  Are their any cracks in the PCB?
    2. 'Buzz Out' (use a Volt-Ohm meter to make resistance and continuity measurements of) the Power and Ground Rails going to each device and component that touches them.   Measure resistor values for for each resistor shown on the schematics.  Verify any diodes or resistors in the design are installed in the correct direction.
    3. Verify VCC/VDD is 3.3volts.
    4. Measure the amount of power the board is consuming.  Does it seem excessive, or too small?   Are any of the components hot-to-the-touch?
    5. Confirm the timing of the RESET signal going to the BCM2073XX meets the timing requirements. Confirm the device is not being held in RESET which would happens when RESET_N pin is held low.
    6. There are two UARTs on the device.  HCI_UART is used for programming NVRAM, and PUART is available for the users application. Upon powerup, the BCM2073XX device ROMCODE senses the HCI_UART_RXD pin to ascertain if it should enter programming mode.  If asserted HIGH, the device enters programming mode. If low, it reads a small chunk of NVRAM contents. One good way to test if the on-board ARM is running romcode is to hold HCI_UART_RXD high during the RESET pulse to force it into programming mode.  Then, execute the ~WICED-Smart-SDK/Tools/mbt/MBT.EXE utility(within the SDK) with the "reset COMxx" parameters to verify HCI Commands/Responses are working.    It is very important to get this to succeed as it confirms there are no electrical or mechanical issues causing the problem(s), and that the embedded ARM controller is indeed running firmware.
    7. If MBT.EXE does not successfully run, Inspect the following areas:
      • Either chip on board design, or module/SIP designs:
        1. If your design has a 2nd microcontroller in place, verify the UART interface signals are not reversed.  In fact, you might want to isolate the Broadcom chip (cut the traces to the host MCU) to assist getting MBT.EXE to function, or to aid in programming the NVRAM with the SDK.
      • Chip on Board designs (BCM2073X):
        1. Ensure the voltage levels for LDOIN/LDOOUT/VDDVCO/VDDPLL match those found on the Broadcom Evaluation Board.
        2. Ensure the 24MHz crystal running.
        3. Ensure TMC is asserted low.
        4. Monitor the Serial Flash/EEPROM's SDA and SCL pins after the RESET is de-asserted on the BCM2073X. You should see bus activity for a short period of time as the internal ARM MCU comes out of reset (ROMCODE tries to load the application firmware from NVRAM).  Make sure you have pullup resistors on these pins.
        5. If the NVRAM has a known-good application image in it, ensure the HCI_UART_RXD pin of the 2073XX is asserted Low during powerup.
      • Module/SiP designs (BCM2073XS, BCM2073XL, BCM2073XE):
        1. These designs are difficult to debug because access to the crystal and NVRAM pins are not accessable from outside the package.
        2. Spend your entire effort getting Step #6 (execution of MBT.exe) functioning to ensure the issue is not a mechanical/electrical one.
        3. Consider NVRAM pre-programming services from Avnet to ensure the module has a known-good application programmed prior to board manufacturing.
    8. After getting MBT.EXE working, your next step is to program the NVRAM with your custom application, or a sample application from the SDK.  Refer to Programming the TAG2/TAG3 Board using command line tools



If you find an error within this Blog, or have ideas on how to improve it, please send a Private Message to my In-Box so I can incorporate your recommendations.

Please do not post comments on this blog.


The iOS application is written to scan for WICED Sense Kit around your iOS device , connect to it and start publishing the sensor data to quickstart.()IBM Internet of Things Foundation


iOS application


You can refer to the iOS attached applicaiton, this iOS application generated a random cliend ID which can be fed in quickstart page to see the data.

External packages used : BLE library for iOS, Moscapsule for MQTT library

Note : size classes are not used, resolution for different iOS devices might not be scaled

WICED Smart SDK setup


1. You can use the WICED Sense SDK as is or you can program the WICED Sense using the WICED Smart SDK, you can download the WICED Smart SDK from

2. The WICED sense comes with default firmware loaded to keep advertising the five sensor data ( Gyro, Accelerometer, e-compass,temperature and humidity

3.With in the SDK there is a sample application called wiced-sense , the default applicaiton loaded on all sense tags. You can modify based on your needs and download the application to your hardware using the below make target






WICED Smart ADC Example

Posted by JacobT_81 Sep 1, 2015

The attached app shows sample usage of the ADC hardware built into the 36/37/s chips.


To use the app, load it onto a Tag board that has a push button on P0. Run traces on the board. You'll initially see ~0V, and when you press the button you'll see the applied voltage on the voltage rail (~3300mV).


There are three necessary steps to get the ADC running, as seen in the app:



     #include "adc.h"


     Instantiate in create function:



     And poll the ADC using the function:




*Calibration occurs within the initialization function. However, it may be useful to your application to calibrate the ADC to an external voltage for added assurance, or to do so periodically throughout the run-time of your application. To do so, call the function below: parameter one is the known voltage of the reference source in mV, and parameter two is the location of the reference voltage. The location can be configured to many different buses and all GPIOs (for external sources). Control click the second parameter within the source code to see a complete list of the locations that can be utilized as a reference voltage.

     adc_adcCalibrate(2000, ADC_INPUT_VDDIO);


The output of the polling function is in mV.




More info on the ADC:

     BCM20732S ADC Configuration

     BCM20737S - ADC Noise-free resolution

     Questions related to the ADC implementation on the BCM2073XS...

     BCM20737 ADC DMA or Interrupt Service Routine

Hello Everyone,


See the attached file for an example of use of the PUART.


To use the sample code, load it onto two Tag boards, connect the boards via PUART, rx-to-tx, with a common ground (currently setup for P32, P33). Run HCI traces (default) on one board and click the button (P0) on the other board. An incrementing value, starting at 0, will be displayed on your terminal with every click of the button. This value was sent via PUART from the peripheral board (the value will increment twice on every click because the button registers an interrupt on each rising and falling edge).



Advertiser and Scanner

Posted by userc_19497 Aug 19, 2015

Hello. Here is an example app that is capable of swapping between advertising and scanning.



BLE advertisement packets consists of 31 bytes. Each field (i.e. appearance, name, service UUID or similar) has a header of 2 bytes (length and type), meaning that the maximum user payload is 29 bytes. That means the more fields that are packed into one advertisement packet, there are less bytes freed for user payload.


Here's an example of advertisement data(AD) from Bluetooth SIG documentation. (pdf attached)

You can view all the different data types and formats in the documentation attached.


Advertisement Field

In our SDK, each field is represented by BLE_ADV_FIELD data structure. Here's the definition:

typedef PACKED struct
    UINT8 len; //length of field
    UINT8 val; //value of field
    UINT8 data[ADV_LEN_MAX-2]; // This is the data and the biggest one is 31-2 = 29

Notice the length, value, and the actual data in the struct corresponds to how AD is formatted in the example above.


You can change the advertisement packet by defining the fields in an array and initializing them.

    BLE_ADV_FIELD adv[2];

     // Format advertisement data.  Data consists of 2 fields.  Standard Advertisement flags
     // and Broadcom Vendor specific data.  The vendor specific data consists of
     // 16 byte UUID and a message "Hello"

     // flags
     adv[0].len     = 1 + 1; // 1 (data length) + 1 (value)
     adv[0].val     = ADV_FLAGS;

     adv[1].len     = 23 + 1; // 23 (data length) + (value)
     adv[1].val     = ADV_MANUFACTURER_DATA; // (AD_TYPE == 0xff)
     adv[1].data[0] = 0x0f;  // Broadcom  (Company Identifier 2 bytes)
     adv[1].data[1] = 0x00;

     // Set UUID
     BT_MEMCPY(&adv[1].data[2], mybeacon_uuid, 16);

     // Set "Hello" message
     BT_MEMCPY(&adv[1].data[18], msg, 5);


Here are the field values:

// ADV flag values
enum ble_adv_flag_value
    ADV_FLAGS                           = 0x01,
    ADV_SERVICE_UUID16_MORE             = 0x02,
    ADV_SERVICE_UUID16_COMP             = 0x03,
    ADV_SERVICE_UUID32_MORE             = 0x04,
    ADV_SERVICE_UUID32_COMP             = 0x05,
    ADV_SERVICE_UUID128_MORE            = 0x06,
    ADV_SERVICE_UUID128_COMP            = 0x07,
    ADV_LOCAL_NAME_SHORT                = 0x08,
    ADV_LOCAL_NAME_COMP                 = 0x09,
    ADV_TX_POWER_LEVEL                  = 0x0A,
    ADV_CLASS_OF_DEVICE                 = 0x0D,
    ADV_SIMPLE_PAIRING_HASH_C           = 0x0E,
    ADV_TK_VALUE                        = 0x10,
    ADV_OOB_FLAGS                       = 0x11,
    ADV_SERVICE_DATA                    = 0x16,
    ADV_TARGET_PUBLIC_ADR               = 0x17,
    ADV_TARGET_RANDOM_ADR               = 0x18,
    ADV_APPEARANCE                      = 0x19,
    ADV_ADVERTISING_INTERVAL            = 0x1A,
    ADV_SERVICE_DATA_UUID32             = 0x20,
    ADV_SERVICE_DATA_UUID128            = 0x21,
    ADV_INDOOR_POSITION                 = 0x24,
    ADV_3D_INFORMATION_DATA             = 0x3D,
    ADV_MANUFACTURER_DATA               = 0xFF,


Then, you'll have to call bleprofile_GenerateADVData function to actually generate the AD.

     bleprofile_GenerateADVData(adv, 2);

where the first parameter is the array to BLE_ADV_FIELD and the second is the number of fields.


Starting Advertisement

You can start advertising in few different ways.

If you have the BLE_PROFILE_CFG defined for the app, then you can simply start by calling:

   bleprofile_Discoverable(HIGH_UNDIRECTED_DISCOVERABLE, NULL);


Or you can start advertising by setting up the advertisement parameters yourself.

        HCIULP_ADV_NONCONNECTABLE_EVENT,                // non-connectable undirected advertisement
        160,                                            // adv interval 100 msec
        HCIULP_ADV_CHANNEL_MAP_MASK,                    // all channels
        HCIULP_PUBLIC_ADDRESS,                          // int advAdrType,
        HCIULP_ADV_FILTER_POLICY_WHITE_LIST_NOT_USED,   // int advFilterPolicy,
        HCIULP_PUBLIC_ADDRESS,                          // int initiatorAdrType,


Advertisement packets have different types.

The first argument to this function, blecm_startAdv defines the type of the advertisement.


Value Passed
Advertisement Type

You can refer to the "auto-generated API" for more details on this function.




In order to start scanning, you simply need to call blecen_Scan function.



Or to turn it off: 



Advertisement Handler

You need to register a handler if you want to do anything with the advertisement packet in the app create function.

void advertisement_handler(HCIULP_ADV_PACKET_REPORT_WDATA *evt);
void basic_create(void)

    // register to process peripheral advertisements
    blecm_RegleAdvReportCb((BLECM_FUNC_WITH_PARAM) advertisement_handler);



Swapping between Advertiser and Scanner

I have made an example app that swaps its role between advertising and scanning. The files are attached as adv.h and adv.c

The app first starts scanning, but you can change its role by pushing the button on the board. It has a minimum RSSI value, so you'll need to have advertising device close to the scanner in order for the scanner to pick up the advertisement.


I was able to put the code into two Tag 3 boards and test their functions.

Here's the app in action.

Both apps started:


One of them starts advertising:


Roles switched:


AD in detail:

Notice how the advertisement data corresponds to how we set the BLE_ADV_FIELD array above.



LED with PWM

Posted by userc_19497 Aug 17, 2015

Hello, here is how you can turn on an LED using PWM.

Include Library

#include "pwm.h"
#include "gpiodriver.h"

Define Macros

#define LED_RED    26  /* PWM 0 */
#define LED_BLUE   27  /* PWM 1 */
#define LED_GREEN  28  /* PWM 2 */

#define GPIO_PORT(x)  (x/16)
#define GPIO_PIN(x)   (x%16)


#define LED_RED_CHANNEL      (PWM0)
#define LED_BLUE_CHANNEL     (PWM1)

     Note: depending on which chip you are using, the GPIO Pins might change

Enable LED

     // enable
     gpio_configurePin(GPIO_PORT(LED_RED), GPIO_PIN(LED_RED), ENABLE_LED_RED, 0); 
     pwm_start( LED_GREEN_CHANNEL, LHL_CLK, 0x000 , 0);

     // pwm_start( id, clk, toggleCount, initCount);
     // Output Voltage  | Toggle Count (Found these values by trial & error)
     // --------------------------------------------
     // ~ (4/4) V_MAX  |    0x000
     // ~ (3/4) V_MAX  |    0x100
     // ~ (2/4) V_MAX  |    0x210
     // ~ (1/4) V_MAX  |    0x315


     Note: depending on the hardware configuration, the V_MAX may change

Disable LED

     // disable
     pwm_disableChannel( 1 << LED_RED_CHANNEL );




BCM2073XS GPIO Basics

Hardware User Guide (SDK 2.x and TAG3 Board)

How to turn on LED

Different Frequencies for PWM



Once you have the WICED Smart IDE installed you can import other WICED Smart SDK .7z releases easily without reinstalling the IDE, or even changing the workspace. This method comes in handy when you have several releases you want to test and compare. You may keep several projects(SDKs) open in one workspace, but for simplicity we will start with closing the existing project.



<Importing a New WICED Smart SDK>


1. Right-click on your current project name in the IDE and select "Close Project". This will not modify or delete your files in anyway. It will, however, close the files you had open in the IDE, and you can choose to either save any changes that had been made. (This step is optional, you may have several projects open at once)


2. Extract the new WICED Smart SDK .7z file to your chosen destination.

3. Click on the arrow next to the leftmost folder icon and select "Makefile Project with Existing Code"


4. Click on "Browse" and navigate to and then select the WICED SDK folder you created. The "Project Name" will be automatically filled in from the name in the "Existing Code Location" you choose. You may modify the name for clarity.


5. The new SDK will now be showing in the leftmost "Project Explorer" view.


<Making New Targets>

Initially the new project directory will not show up in the right-most "Make Target" view. You will need to set up the directory first and then you will be able to add on new targets more easily.

1. In the leftmost tab of "Project Explorer", right-click on the new project you just imported. Select "Make Targets" and "Create".


2. Type in "clean" as the target name and press OK. (Any name will do but you will probably need a target "clean" anyway)



3. In this step you will have to close the IDE window and then restart it. When it reopens, you will see that the directory for targets will has been created.



4. From now on you can right-click on the project name in the "Make Target" tab or just click on the target+ icon.



Enjoy working with your new SDK!

WICED Smart User's Guide

Posted by kwang Aug 3, 2015
Table of Contents:
Product SelectionProduct EvaluationWICED SenseProduct DevelopmentManufacturing / Production
Product Selection
Here you will find a series of links/resources that will assist in the selection of a WICED Smart BLE product:
Data sheets:
Product Evaluation
Here you will find a series of links/resources that will assist during the purchase/use of a WICED Smart BLE development system:
To purchase one of our kits, please visit our partners page: Purchase a WICED Bluetooth Dev Kit
Downloading and Installing the SDK
For SDK downloads, please visit WICED Smart Documents & Downloads
If you are using one of Broadcom's TAG boards the Quick Start guide is extremely helpful in getting to know the TAG board and using the SDK.
Quick Start Guides:
SDK 2.x and TAG3 - The specified item was not found.
Hardware Guides:
Common Errors While Installing
If you are having problems with your installer, check that the download size of the installer is roughly 260MB, installer problems are typically caused by incomplete downloads.
The picture below shows a very common error message.  Our SDK utilizes a 32-bit version of an Eclipse based IDE which requires a 32-bit version of JRE to be installed.  If you already have the 64-bit JRE installed, you will also need to install the 32-bit version as well. The JRE is designed to allow both 32 and 64 bit variants to be installed on the system.
The WICED Sense kit uses a Silicon Labs USB to Serial Device.  The TAG3 board uses an FTDI USB to Serial Device. Both should be installed as part of the SDK 2.2.1 installation process. If not, the FTDI drivers for the TAG3 reinstall them using the file /WICED-Smart-SDK/Drivers/dpinst.exe (make sure you access from the command line).  The Silicon Labs USB Drivers can be found WICED Sense Table of Contents
Everything we have for the WICED Sense, such as schematics, drivers, and Android application source code, can be accessed through the WICED Sense Table of Contents. A great post for the WICED Sense is the WICED SENSE Kit BLOG which is like a WICED Sense quick start guide.
Some Android devices appear to have issues pairing to the WICED Sense Tag from inside the app, linked is a work-around that should allow you to connect to your Android device: WICED Sense Android Pairing Work-Around
Product Development
The most basic starting points to begin writing code are hello_client/sensor and mybeacon.  AS does a great overview of hello_sensor in his interview: WICED Smart Video BLOG: Experts Interview - Sleep Deep_Sleep and Advertising
Below are links to commonly visited posts that may help in your development process.
GATT Database:








Command Line Tools:

Filter Blog

By date:
By tag: