I set up PPI so that it kicks off TWIM (I2C) transfer on GPIOTE pin transition low to high. Everything works great, except that I also setup a fork task to set another GPIOTE out to high during the transaction. I then wanted to clear that pin after the transaction has completed, but this throws a hard fault in nrfx_gpiote_out_clear on the assert that pin_in_use_by_te is false. So I guess two questions:
- Why the hard fault here? Is it to prevent accidentally triggering PPI by manually setting the pin?
- If I am only using the NRFX_GPIOTE_CONFIG_OUT_TASK_HIGH (or LOW) task to change the output direction, how do I ever set it back low if I can't use nrfx_gpiote_out_clear? Do I have to free the channel and reassign it every time I want to change the pin state manually?
Here is my code:
...
static void ppi_init(void)
{
...
/* Configure LED GPIOTE to switch on when reading */
nrfx_gpiote_out_config_t config1 = NRFX_GPIOTE_CONFIG_OUT_TASK_HIGH;
error = nrfx_gpiote_out_init(LED2, &config1);
APP_ERROR_CHECK(error);
nrfx_gpiote_out_task_enable(LED2);
...
m_task_address_gpio_set = nrfx_gpiote_out_task_addr_get(LED2);
...
/* Allocate a free PPI channel */
error = nrfx_ppi_channel_alloc(&m_ppi_channel_twi_start);
APP_ERROR_CHECK(error);
/* Assign the event and task to the PPI */
error = nrfx_ppi_channel_assign(m_ppi_channel_twi_start,
m_event_address_gpiote_port,
m_task_address_twi_start);
APP_ERROR_CHECK(error);
/* GPIO task to blink LED2 as fork */
error = nrfx_ppi_channel_fork_assign(m_ppi_channel_twi_start,
m_task_address_gpio_set);
APP_ERROR_CHECK(error);
/* Enable PPI channel for this T/E set */
error = nrfx_ppi_channel_enable(m_ppi_channel_twi_start);
APP_ERROR_CHECK(error);
}
int main(void)
{
...
ppi_init();
...
while(1)
{
if (twim_stopped_flag)
{
...
nrfx_gpiote_out_clear(LED2);
}
}
}
(P.S. No joke - I love the PPL system so much, I have a serious dev crush on it. <3 <3 Keep up the great work!)