In SDK 11.0 it seems that in case pin 31 is configured as a button (using port events), nrf_gpiote_task_enable keeps triggering the port event due too a work around for OUTINIT PAN.
In SDK 11.0 it seems that in case pin 31 is configured as a button (using port events), nrf_gpiote_task_enable keeps triggering the port event due too a work around for OUTINIT PAN.
What chip are you using? What board? Our DK or custom? Could you edit your question and include some code?
I'm using a NRF52 chip on a custom board with a button connected to pin 31. The button is handled through app_button (low power port event). The NRF52 generates PWM on some other pins using GPIOTE and PPI. This requires calling nrf_gpiote_task_enable and nrf_gpiote_task_disable when switching between PWM on and off. Every time nrf_gpiote_task_enable is called, a port event is generated because pin 31 is configured as a low power GPIOTE pin and nrf_gpiote_task_enable temporarily changes the pin 31 GPIOTE config.
Code from the SDK:
__STATIC_INLINE void nrf_gpiote_task_enable(uint32_t idx)
{
uint32_t final_config = NRF_GPIOTE->CONFIG[idx] | GPIOTE_CONFIG_MODE_Task;
/* Workaround for the OUTINIT PAN. When nrf_gpiote_task_config() is called a glitch happens
on the GPIO if the GPIO in question is already assigned to GPIOTE and the pin is in the
correct state in GPIOTE but not in the OUT register. */
/* Configure channel to Pin31, not connected to the pin, and configure as a tasks that will set it to proper level */
NRF_GPIOTE->CONFIG[idx] = final_config | ((31 << GPIOTE_CONFIG_PSEL_Pos) & GPIOTE_CONFIG_PSEL_Msk);
__NOP();
__NOP();
__NOP();
NRF_GPIOTE->CONFIG[idx] = final_config;
}
The workaround is not needed for nRF52. The following implementation should be used:
__STATIC_INLINE void nrf_gpiote_task_enable(uint32_t idx)
{
uint32_t final_config = NRF_GPIOTE->CONFIG[idx] | GPIOTE_CONFIG_MODE_Task;
#ifdef NRF51
/* Workaround for the OUTINIT PAN. When nrf_gpiote_task_config() is called a glitch happens
on the GPIO if the GPIO in question is already assigned to GPIOTE and the pin is in the
correct state in GPIOTE but not in the OUT register. */
/* Configure channel to not existing, not connected to the pin, and configure as a tasks that will set it to proper level */
NRF_GPIOTE->CONFIG[idx] = final_config | (((31) << GPIOTE_CONFIG_PSEL_Pos) & GPIOTE_CONFIG_PORT_PIN_Msk);
__NOP();
__NOP();
__NOP();
#endif
NRF_GPIOTE->CONFIG[idx] = final_config;
}
This will be used in the next SDK release.
@Petter - it appears that this issue still exists in SDK12. Can you confirm whether we need it for nRF52 or not and if it is completely safe to comment the code out? Or why was it not fixed for SDK 12? Thanks.
@guraaf It was fixed in SDK 12.2.0.