This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

sd_ble_gap_scan_start() induces LFO jitter/instability in PWM output

This is a simplified version of the bug, hoping someone has already seen it and can point me in the right direction.

I will have time over the next 24 hours to build and open-source a full project to show how this bug is reproduced, with a video of this on the scope. In the meantime the main points are below.

TLDR: scanning for advertisements causes PWM output on a GPIO to start a low-frequency drift back and forth (jitter).

High-level walkthrough:

a.) we set up as a BLE peripheral:

	/* init board */
	bsp_board_leds_init();
	APP_ERROR_CHECK(
		app_timer_init()
		);
	/* init logging */
	APP_ERROR_CHECK(
		NRF_LOG_INIT(NULL)
		);
	NRF_LOG_DEFAULT_BACKENDS_INIT();

	/* ble init */
	ble_stack_init();
	gap_params_init();
	APP_ERROR_CHECK(
		nrf_ble_gatt_init(&m_gatt, NULL)
		);
	services_init();
	advertising_init();
	conn_params_init();

	/* ble run */
	advertising_start();

b.) we init a PWM:

	/* FET output is high-drive */
	nrf_gpio_cfg(OUT_PWMa,			/* pin_number */
		NRF_GPIO_PIN_DIR_OUTPUT,	/* dir */
		NRF_GPIO_PIN_INPUT_DISCONNECT,	/* input */
		NRF_GPIO_PIN_PULLDOWN,		/* pull */
		NRF_GPIO_PIN_H0H1,		/* drive */
		NRF_GPIO_PIN_NOSENSE		/* sense */
		);
	nrf_gpio_cfg_output(OUT_PWMb);
	nrf_gpio_cfg_output(OUT_PWMc);

	/* start pwm */
	APP_ERROR_CHECK(
		nrf_drv_pwm_init(&pwm0_inst, &pwm0_conf, NULL)
		);
	nrf_drv_pwm_simple_playback(&pwm0_inst, &pwm0_seq, 1, NRF_DRV_PWM_FLAG_LOOP);

c.) We set up a timer:

	APP_TIMER_DEF(a_timer);
	APP_ERROR_CHECK(
		app_timer_create(&a_timer, APP_TIMER_MODE_REPEATED, a_func)
		);
	APP_ERROR_CHECK(
		app_timer_start(fader_timer,
			APP_TIMER_TICKS(1000 / (pwm0_conf.top_value * 0.5)),
			NULL
		)
	);

d.) We scan for bluetooth advertisements:

	/* scan for other devices */
	static ble_gap_scan_params_t scan_params = {
		.active = 0,
		.use_whitelist = 0,
		.adv_dir_report = 0,
		.interval = APP_ADV_INTERVAL,	/* same interval as advertisement */
		.window = APP_ADV_INTERVAL,	/* no idea what this does */
		.timeout = 0			/* never time out */
	};
	APP_ERROR_CHECK(
		sd_ble_gap_scan_start(&scan_params)
		);

When commenting out the scanning in d.) the PWM is rock-solid; with d.) I get fluctuation.

It doesn't matter what I do (or don't do) in the callback handler for bluetooth (even if it's a nop I get the same result).

Removing the timer code makes no difference.

nRF52830 (nRF52-DK)

nRF5_SDK_14.2.0_17b948a

s132_nrf52_5.0.0_softdevice.hex

gcc-arm-none-eabi-7-2017-q4-major

Related