Edit 2: Files need to reproduce the issue described in this questions:
To reproduce the issue please just replace the main.c and nrf_drv_config.h into a ble_app_uart example in SDK v10.0.0, and put the project files into /s110/arm5_no_packs.
Further inspection shows that sd_ble_gap_ppcp_set()
(at line 127 of attachment's main.c) returns error code 7, which should be NRF_ERROR_INVALID_PARAM
? This is strange because I believe that 2000ms is still well below the 4s limit.
Edit 1:
I am using the PWM library to generate a PWM of period about 27us. After I tried changing the connection interval a little bit, I have noticed that any max_conn_interval
greater than or equal to MSEC_TO_UNITS(1999, UNIT_1_25_MS)
cause the PWM signal to become completely wrong.
For example,
- With
MSEC_TO_UNITS(2000, UNIT_1_25_MS)
I am looking at a PWM signal with 3700ms period with 2600ms high. - Meanwhile, with
MSEC_TO_UNITS(1999, UNIT_1_25_MS)
, I got a PWM signal with 26.80~27.20us period with 13.60us high, very close to my intended 27us period with 50% duty cycle.
Is there any reason for this? I don't think I see anything mentioned in the PWM library documentation.
For reference, I am using SDK v10.0.0, with SoftDevice S110 v8.0.0 on nRF51 DK. I started with ble_app_uart example, strip off all NUS code, add a Device Information Service in with just Serial Number field and now just started working with PWM.
Below is all of my code that I think is relevant.
#define MIN_CONN_INTERVAL MSEC_TO_UNITS(1999, UNIT_1_25_MS) /**< Minimum acceptable connection interval (20 ms), Connection interval uses 1.25 ms units. */
#define MAX_CONN_INTERVAL MSEC_TO_UNITS(1999, UNIT_1_25_MS) /**< Maximum acceptable connection interval (75 ms), Connection interval uses 1.25 ms units. */
...
APP_PWM_INSTANCE(PWM, 2);
...
/**@brief Function for initializing the Connection Parameters module.
*/
static void conn_params_init(void)
{
uint32_t err_code;
ble_conn_params_init_t cp_init;
memset(&cp_init, 0, sizeof(cp_init));
cp_init.p_conn_params = NULL;
cp_init.first_conn_params_update_delay = FIRST_CONN_PARAMS_UPDATE_DELAY;
cp_init.next_conn_params_update_delay = NEXT_CONN_PARAMS_UPDATE_DELAY;
cp_init.max_conn_params_update_count = MAX_CONN_PARAMS_UPDATE_COUNT;
cp_init.start_on_notify_cccd_handle = BLE_GATT_HANDLE_INVALID;
cp_init.disconnect_on_fail = false;
cp_init.evt_handler = on_conn_params_evt;
cp_init.error_handler = conn_params_error_handler;
err_code = ble_conn_params_init(&cp_init);
APP_ERROR_CHECK(err_code);
}
...
/** @brief Initialize PWM signal
*/
static void pwm_init(void)
{
uint32_t err_code;
app_pwm_config_t pwm_config = APP_PWM_DEFAULT_CONFIG_1CH(27, 29);
err_code = app_pwm_init(&PWM, &pwm_config, NULL);
DEBUG_MAIN_PRINTF(("app_pwm_init returns %d\n", err_code));
DEBUG_MAIN_PRINTF(("period = %d\n", app_pwm_cycle_ticks_get(&PWM)));
APP_ERROR_CHECK(err_code);
app_pwm_enable(&PWM);
while (app_pwm_channel_duty_set(&PWM, 0, 100) == NRF_ERROR_BUSY);
}
/**@brief Application main function.
*/
int main(void)
{
uint32_t err_code;
bool erase_bonds;
uint8_t start_string[] = START_STRING;
// Initialization starts -----------------------------------------------------------------------
APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_OP_QUEUE_SIZE, false);
uart_init();
buttons_leds_init(&erase_bonds);
pwm_init();
ble_stack_init();
gap_params_init();
services_init();
advertising_init();
conn_params_init();
// Initialization ends -------------------------------------------------------------------------
printf("%s",start_string);
while (app_pwm_channel_duty_set(&PWM, 0, 50) == NRF_ERROR_BUSY);
err_code = ble_advertising_start(BLE_ADV_MODE_FAST);
APP_ERROR_CHECK(err_code);
// Enter main loop.
for (;;)
{
power_manage();
}
}