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

Issue with 2 Instance x 2 Channel PWMs and TWI RX

Hi everyone,

I'm seeing a weird issue with one of my two instances of 2ch PWMs where if I receive data from TWI, my PWM1 stops functioning and TWI stops functioning as well. However, transmitting data using TWI does not show the same issue and issues are only seen after receiving data from TWI. If I only use PWM2 instead of using both PWM1 and PWM2, TWI issue is no longer seen and I can use TWI to transmit and receive data without issues.

Here is how I initialize my TWI and PWM:

twi_master_init();

... // initialize S210 and other stuff...
 
PWM1.p_cb->channels_cb[0].gpio_pin = 25;
PWM1.p_cb->channels_cb[0].pulsewidth = 0x00000000;
PWM1.p_cb->channels_cb[0].ppi_channels[0] = NRF_PPI_CHANNEL1;
PWM1.p_cb->channels_cb[0].ppi_channels[1] = NRF_PPI_CHANNEL2;
PWM1.p_cb->channels_cb[0].polarity = APP_PWM_POLARITY_ACTIVE_HIGH ;
PWM1.p_cb->channels_cb[0].initialized = 0;

PWM1.p_cb->channels_cb[1].gpio_pin = 26;
PWM1.p_cb->channels_cb[1].pulsewidth = 0x00000000;
PWM1.p_cb->channels_cb[1].ppi_channels[0] = NRF_PPI_CHANNEL3;
PWM1.p_cb->channels_cb[1].ppi_channels[1] = NRF_PPI_CHANNEL4;
PWM1.p_cb->channels_cb[1].polarity = APP_PWM_POLARITY_ACTIVE_HIGH;
PWM1.p_cb->channels_cb[1].initialized = 0;

PWM1.p_cb->period = 0xFFFFFFFF;
PWM1.p_cb->p_ready_callback = pwm_ready_callback;
PWM1.p_cb->ppi_channels[0] = NRF_PPI_CHANNEL5;
PWM1.p_cb->ppi_channels[1] = NRF_PPI_CHANNEL6;
PWM1.p_cb->ppi_group = NRF_PPI_CHANNEL_GROUP0;
PWM1.p_cb->state = NRF_DRV_STATE_UNINITIALIZED;	

PWM2.p_cb->channels_cb[0].gpio_pin = 28;
PWM2.p_cb->channels_cb[0].pulsewidth = 0x00000000;
PWM2.p_cb->channels_cb[0].ppi_channels[0] = NRF_PPI_CHANNEL7;
PWM2.p_cb->channels_cb[0].ppi_channels[1] = NRF_PPI_CHANNEL8;
PWM2.p_cb->channels_cb[0].polarity = APP_PWM_POLARITY_ACTIVE_HIGH ;
PWM2.p_cb->channels_cb[0].initialized = 0;

PWM2.p_cb->channels_cb[1].gpio_pin = 29;
PWM2.p_cb->channels_cb[1].pulsewidth = 0x00000000;
PWM2.p_cb->channels_cb[1].ppi_channels[0] = NRF_PPI_CHANNEL9;
PWM2.p_cb->channels_cb[1].ppi_channels[1] = NRF_PPI_CHANNEL10;
PWM2.p_cb->channels_cb[1].polarity = APP_PWM_POLARITY_ACTIVE_HIGH;
PWM2.p_cb->channels_cb[1].initialized = 0;

PWM2.p_cb->period = 0xFFFFFFFF;
PWM2.p_cb->p_ready_callback = pwm_ready_callback;
PWM2.p_cb->ppi_channels[0] = NRF_PPI_CHANNEL11;
PWM2.p_cb->ppi_channels[1] = NRF_PPI_CHANNEL12;
PWM2.p_cb->ppi_group = NRF_PPI_CHANNEL_GROUP1;
PWM2.p_cb->state = NRF_DRV_STATE_UNINITIALIZED;
 
// begin initialization of PWM channels
app_pwm_config_t pwm1_cfg = APP_PWM_DEFAULT_CONFIG_2CH(4096L, 25, 26);
app_pwm_config_t pwm2_cfg = APP_PWM_DEFAULT_CONFIG_2CH(4096L, 28, 29);
// initialize and enable PWM
pwm1_cfg.pin_polarity[0] = APP_PWM_POLARITY_ACTIVE_HIGH;
pwm1_cfg.pin_polarity[1] = APP_PWM_POLARITY_ACTIVE_HIGH;
err_code = app_pwm_init(&PWM1, &pwm1_cfg, pwm_ready_callback);
APP_ERROR_CHECK(err_code);
pwm2_cfg.pin_polarity[0] = APP_PWM_POLARITY_ACTIVE_HIGH;
pwm2_cfg.pin_polarity[1] = APP_PWM_POLARITY_ACTIVE_HIGH;
err_code = app_pwm_init(&PWM2, &pwm2_cfg, pwm_ready_callback);
APP_ERROR_CHECK(err_code);
// enable PWMs
app_pwm_enable(&PWM1);
app_pwm_enable(&PWM2);
// set all PWMs to 0%
while (app_pwm_channel_duty_set(&PWM1, 1, 0) == NRF_ERROR_BUSY);	// left backward
while (app_pwm_channel_duty_set(&PWM1, 0, 0) == NRF_ERROR_BUSY);	// left forward
while (app_pwm_channel_duty_set(&PWM2, 1, 0) == NRF_ERROR_BUSY);	// right forward
while (app_pwm_channel_duty_set(&PWM2, 0, 0) == NRF_ERROR_BUSY);	// right backward

I tried changing the above PPI channels for PWM around from 1-12 to 20 to 21 and PPI channel group from 0 and 1 to 2 to 3 but still the same issue is seen. Does TWI receiver use one of the PPI essential to the PWM functionality or vise versa?

Thank you for your help.

Parents
  • Hi,

    I had a quick look at your code snippet and I'm curious why you have included the first 6 "paragraphs" of code. The PWM control block, PWMx.p_cb, will be overwritten by app_pwm_init() in the end anyway so this seems redundant. app_pwm_init() is for example allocating PPI channels from a pool of available channels to make sure that there are no conflicts with other modules using the PPIs. Have you had a look at the pwm_library example in the SDK? I suggest that you have a look at that first and then the TWI examples. Then finally try to merge them.

    Using the software TWI drivers should only be a last resort. At least if you plan to expand your project with e.g. BLE in the future. You will not be able to run the software drivers concurrently with the BLE stack.

Reply
  • Hi,

    I had a quick look at your code snippet and I'm curious why you have included the first 6 "paragraphs" of code. The PWM control block, PWMx.p_cb, will be overwritten by app_pwm_init() in the end anyway so this seems redundant. app_pwm_init() is for example allocating PPI channels from a pool of available channels to make sure that there are no conflicts with other modules using the PPIs. Have you had a look at the pwm_library example in the SDK? I suggest that you have a look at that first and then the TWI examples. Then finally try to merge them.

    Using the software TWI drivers should only be a last resort. At least if you plan to expand your project with e.g. BLE in the future. You will not be able to run the software drivers concurrently with the BLE stack.

Children
Related