8484#define TIMER_CC1_MOD_TX_DUTY NRF_TIMER_CC_CHANNEL1
8585#define TIMER_CC2_FEM_0 NRF_TIMER_CC_CHANNEL2
8686#define TIMER_CC3_FEM_1 NRF_TIMER_CC_CHANNEL3
87+ #define TIMER_CC4_SWEEP_DUTY NRF_TIMER_CC_CHANNEL4
8788#if NRF54H_ERRATA_216_PRESENT
8889#define TIMER_CC7_ERRATA216 NRF_TIMER_CC_CHANNEL7
8990#endif /* NRF54H_ERRATA_216_PRESENT */
9091
9192/* RX timeout counted from the last packet received. */
9293#define RX_PACKET_TIMEOUT_MS 100
9394
95+ /* Ram-up time for radio when using fast ramp. */
96+ #define RADIO_RAMP_UP_FAST_US 40
97+
9498/* Buffer for the radio TX packet */
9599static uint8_t tx_packet [RADIO_MAX_PAYLOAD_LEN ];
96100/* Buffer for the radio RX packet. */
@@ -103,6 +107,12 @@ static uint32_t rx_packet_cnt;
103107/* Radio current channel (frequency). */
104108static uint8_t current_channel ;
105109
110+ /* Radio Sweep with duty-cycle channel array */
111+ const static uint8_t channel_array [72 ] = {4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 ,
112+ 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 , 28 , 29 , 30 , 31 , 32 , 33 , 34 , 35 , 36 , 37 , 38 , 39 , 40 , 41 ,
113+ 42 , 43 , 44 , 45 , 46 , 47 , 48 , 49 , 50 , 51 , 52 , 53 , 54 , 55 , 56 , 57 , 58 , 59 , 60 , 61 , 62 , 63 ,
114+ 64 , 65 , 66 , 67 , 68 , 69 , 70 , 71 , 72 , 73 , 74 , 75 , 76 , 77 , 78 };
115+
106116/* Timer used for channel sweeps and tx with duty cycle. */
107117static nrfx_timer_t timer =
108118 NRFX_TIMER_INSTANCE (NRF_TIMER_INST_GET (RADIO_TEST_TIMER_INSTANCE ));
@@ -850,24 +860,31 @@ static void radio_mode_set(NRF_RADIO_Type *reg, nrf_radio_mode_t mode)
850860 mltpan_6 (mode );
851861}
852862
853- static void radio_unmodulated_tx_carrier (uint8_t mode , int8_t txpower , uint8_t channel )
863+ static void radio_unmodulated_tx_carrier_radio_setup (uint8_t mode , int8_t txpower , uint8_t channel ,
864+ bool start_ready_short_enable )
854865{
855866 radio_disable ();
856867
857868 radio_mode_set (NRF_RADIO , mode );
858- nrf_radio_shorts_enable (NRF_RADIO , NRF_RADIO_SHORT_READY_START_MASK );
859869 radio_power_set (mode , channel , txpower );
860-
861870 radio_channel_set (mode , channel );
862871
872+ if (start_ready_short_enable ) {
873+ nrf_radio_shorts_enable (NRF_RADIO , NRF_RADIO_SHORT_READY_START_MASK );
874+ }
875+
863876#if CONFIG_FEM
864877 (void )fem_configure (false, mode , & fem );
865878#else
866879 if (sweep_processing ) {
867880 radio_ppi_config (false);
868881 }
869882#endif /* CONFIG_FEM */
883+ }
870884
885+ static void radio_unmodulated_tx_carrier (uint8_t mode , int8_t txpower , uint8_t channel )
886+ {
887+ radio_unmodulated_tx_carrier_radio_setup (mode , txpower , channel , true);
871888 radio_start (false, sweep_processing );
872889}
873890
@@ -1052,6 +1069,31 @@ static void radio_modulated_tx_carrier_duty_cycle(uint8_t mode, int8_t txpower,
10521069 irq_unlock (key );
10531070}
10541071
1072+ static void radio_tx_sweep_with_sleep (int8_t txpower , uint16_t t_tx_us , uint16_t t_sleep_us )
1073+ {
1074+ radio_disable ();
1075+ const uint32_t total_time_per_channel_us = t_tx_us + t_sleep_us ;
1076+
1077+ current_channel = 0 ;
1078+
1079+ nrfx_timer_disable (& timer );
1080+ nrf_timer_shorts_disable (timer .p_reg , ~0 );
1081+ nrf_timer_int_disable (timer .p_reg , ~0 );
1082+
1083+ nrfx_timer_compare (& timer ,
1084+ TIMER_CC0_SWEEP_DWELL ,
1085+ nrfx_timer_us_to_ticks (& timer , t_tx_us + RADIO_RAMP_UP_FAST_US ),
1086+ true);
1087+
1088+ nrfx_timer_extended_compare (& timer ,
1089+ TIMER_CC4_SWEEP_DUTY ,
1090+ nrfx_timer_us_to_ticks (& timer , total_time_per_channel_us ),
1091+ NRF_TIMER_SHORT_COMPARE4_CLEAR_MASK ,
1092+ true);
1093+
1094+ nrfx_timer_enable (& timer );
1095+ }
1096+
10551097void radio_test_start (const struct radio_test_config * config )
10561098{
10571099#if CONFIG_FEM
@@ -1099,6 +1141,11 @@ void radio_test_start(const struct radio_test_config *config)
10991141 config -> params .modulated_tx_duty_cycle .pattern ,
11001142 config -> params .modulated_tx_duty_cycle .duty_cycle );
11011143 break ;
1144+ case TX_SWEEP_WITH_DUTY_CYCLE :
1145+ radio_tx_sweep_with_sleep (config -> params .tx_sweep_duty_cycle .txpower ,
1146+ config -> params .tx_sweep_duty_cycle .t_tx_us ,
1147+ config -> params .tx_sweep_duty_cycle .t_sleep_us );
1148+ break ;
11021149 }
11031150
11041151 test_is_running = true;
@@ -1221,6 +1268,19 @@ static void timer_handler(nrf_timer_event_t event_type, void *context)
12211268
12221269 channel_start = config -> params .rx_sweep .channel_start ;
12231270 channel_end = config -> params .rx_sweep .channel_end ;
1271+ } else if (config -> type == TX_SWEEP_WITH_DUTY_CYCLE ) {
1272+
1273+ sweep_processing = true;
1274+
1275+ /* disable radio after tone */
1276+ radio_unmodulated_tx_carrier_radio_setup (NRF_RADIO_MODE_BLE_1MBIT ,
1277+ config -> params .tx_sweep_duty_cycle .txpower ,
1278+ channel_array [current_channel ],
1279+ false);
1280+
1281+ /* set up next channel */
1282+ channel_start = config -> params .tx_sweep_duty_cycle .channel_index_start ;
1283+ channel_end = config -> params .tx_sweep_duty_cycle .channel_index_end ;
12241284 } else {
12251285 printk ("Unexpected test type: %d\n" , config -> type );
12261286 return ;
@@ -1236,6 +1296,8 @@ static void timer_handler(nrf_timer_event_t event_type, void *context)
12361296 } else if (event_type == NRF_TIMER_EVENT_COMPARE7 ) { /* HMPAN-216 errata */
12371297 errata_216_release ();
12381298#endif /* NRF54H_ERRATA_216_PRESENT */
1299+ } else if (event_type == NRF_TIMER_EVENT_COMPARE4 ) {
1300+ radio_start (false, true);
12391301 } else {
12401302 /* Do nothing */
12411303 }
0 commit comments