Constant Tone Extension#
Concept#
To determine the angle of the incoming signal it is essential to transmit a signal with continuous phase, constant amplitude, and constant frequency over a time period long enough to be sampled by all receiver antennas. Transmitting a CW (continuous wave) signal for a long time is not recommended outside of test environments, because it has a very sharp spectrum and can cause serious interference with other devices working in the 2.4 GHz frequency range. Therefore, a short CW must be used, and the transmitter and the receiver must be synchronized so that both know when the CW signal is sent.
Many solutions can be found to overcome this simple problem, and indeed there are many indoor positioning solutions on the market already using direction-finding algorithms. None of them is based on a well-known standard, however. The Bluetooth standard, in contrast, is widespread, and it solves the synchronization problem by its nature: Bluetooth packets are sent with very strict timing, and the peer devices resynchronize their clocks on each reception.
Bluetooth 5.1 introduced a new method to request and send short CW signals as an extension of a normal package. This extension is called Constant Tone Extension (CTE), and it is sent after the CRC of the package when requested.


CTEs can be sent both through a connection (in LL_CTE_RSP packets after an LL_CTE_REQ packet was received), and in periodic advertisements (in AUX_SYNC_IND packets). Additionally, the Silicon Labs Bluetooth stack provides a non-standard solution where CTEs can be sent in extended advertisements (AUX_ADV_IND packets), which makes Direction Finding much more scalable regarding the number of assets to be located. For more info on CTEs see the Bluetooth Core Specification, v5.1 or later.
Sending and Receiving CTEs#
To enable CTE responses on a connection use the API sl_bt_cte_transmitter_enable_connection_cte()on the CTE transmitter side. To send a CTE request from the receiver to the transmitter, use the API sl_bt_cte_receiver_enable_connection_cte() on the receiver side. If CTE responses are enabled on the transmitter side, the Bluetooth stack automatically responds to each CTE request with a CTE response.
To transmit CTEs in periodic advertisements, first start a periodic advertiser on the transmitter side and then use the API sl_bt_cte_transmitter_enable_connectionless_cte(). To start listening to CTEs attached to periodic advertisements, first establish a periodic synchronization on the receiver side and then use the API sl_bt_cte_receiver_enable_connectionless_cte().
To transmit CTEs in Silicon Labs proprietary extended advertisements, first start a (regular) extended advertisement on the transmitter side, and then use the API sl_bt_cte_transmitter_enable_silabs_cte(). To start listening to CTEs attached to Silicon Labs proprietary extended advertisements, first start scanning on the receiver side and then use the API sl_bt_cte_receiver_enable_silabs_cte().
Any time a CTE is received by the Bluetooth stack (either via connection or in advertisements), the Bluetooth stack raises an iq_report event. Depending on the mode of transmission, this means either an sl_bt_evt_cte_receiver_connection_iq_report event, an sl_bt_evt_cte_receiver_connectionless_iq_report event, or an sl_bt_evt_cte_receiver_silabs_iq_report event. Each event includes an array of IQ samples. The following sections detail what these samples mean and how to interpret them.
Note: To get the APIs listed above working, CTE Transmitter and CTE Receiver Software components need to be installed in your project. For more information on the API see the Bluetooth API Reference on http://docs.silabs.com.