Hi,
I believe there is a significant inconsistency between the documentation and implementation of AoA antenna switching in the nRF Connect SDK. My testing of this was done in SDK v2.4.1, but the line of code in question is present all the way up to v2.7.0, the latest SDK I have installed.
The documentation used for the AoA receiver is found here. Of note is the following section.
The section above is also in agreement with the Nordic Direction Finding whitepaper section on antenna switching, available here.
The highlighted statement is not exactly truthful and has the potential to skew any generated AoA data to be useless unless the user is aware of how the underlying system is working.
My antenna switching configuration:
//ant_patterns[0] -> 8us guard period + 4us reference period //ant_patterns[1:n] -> 4us switching pattern static uint8_t ant_patterns[] = { 0x7, 0x1, 0x2, 0x3, 0x4};. The comments found above my switching configuration are based on the nRF52833 Radio documentation available here. The following excerpt from the radio documentation is what I believe is improperly implemented in nRF Connect SDK.
During operation, when the end of the SWITCHPATTERN buffer is reached, RADIO cycles back to SWITCHPATTERN[2]. At the end of the AoA/AoD procedure, SWITCHPATTERN[0] is applied to DFECTRL1.TSWITCHSPACING after the previous antenna switch. The SWITCHPATTERN buffer can be erased/cleared using CLEARPATTERN.
- In addition to this, the antenna used during reception of the PDU is
dfe-pdu-antenna = <0x0>;
Based on all the documentation and my switch pattern configuration, I would expect the following GPIO settings when working with AoA Rx
- Scanning PDU: 0x0
- Reference and guard period: 0x7
- Sample slot 0: 0x1
- Sample slot 1: 0x2
- Sample slot 2: 0x3
- Sample slot 3: 0x4
As I have 4 switch patterns configured after my Reference/Guard pattern, my sample slots can be generalized to
- Sample slot 4n+0 : 0x1
- Sample slot 4n+1 : 0x2
- Sample slot 4n+2 : 0x3
- Sample slot 4n+3 : 0x4
However this is not what is found when I scope the lines. There is an additional slot of 0x7 that is added between every complete sweep of the antenna switching patterns.
The offending code block is found in SDK_ROOT\zephyr\subsys\bluetooth\controller\ll_sw\nordic\hal\nrf5\radio\radio_df.c
void radio_df_ant_switch_pattern_set(const uint8_t *patterns, uint8_t len) { /* SWITCHPATTERN is like a moving pointer to an underlying buffer. * Each write stores a value and moves the pointer to new free position. * When read it returns number of stored elements since last write to * CLEARPATTERN. There is no need to use a subscript operator. * * Some storage entries in the buffer has special purpose for DFE * extension in radio: * - SWITCHPATTERN[0] for idle period (PDU Tx/Rx), * - SWITCHPATTERN[1] for guard and reference period, * - SWITCHPATTERN[2] and following for switch-sampling slots. * Due to that in SWITCHPATTER[0] there is stored a pattern provided by * DTS property dfe_pdu_antenna. This limits number of supported antenna * switch patterns by one. */ NRF_RADIO->SWITCHPATTERN = PDU_ANTENNA; for (uint8_t idx = 0; idx < len; ++idx) { NRF_RADIO->SWITCHPATTERN = patterns[idx]; } /* Store antenna id used for GUARD and REFERENCE period at the end of SWITCHPATTERN buffer. * It is required to apply reference antenna id when user provided switchpattern is * exhausted. * Maximum length of the switch pattern provided to this function is at maximum lower by one * than capacity of SWITCHPATTERN buffer. Hence there is always space for reference antenna * id after end of switch pattern. */ NRF_RADIO->SWITCHPATTERN = patterns[GUARD_REF_ANTENNA_PATTERN_IDX]; }
The final write to SWITCHPATTERN is the cause of the sample slots being filled with 0x7. Removing this line fixes the issue and brings the observed switch pattern in line with the pattern that all the documentation suggests we should expect.
NRF_RADIO->SWITCHPATTERN = patterns[GUARD_REF_ANTENNA_PATTERN_IDX];
I would recommend either updating the documentation to indicate that the first entry into a users switch pattern array is used for both the Reference/Guard period, as well as at the start of a sweep through the antennas, or to simply remove the final write to SWITCHPATTERN as I believe it violates the Radio configuration spec as laid out in the radio documentation.
Thank you,
zrivard