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

Changing GPIOTE out pin level gives hard fault

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:

  1. Why the hard fault here?  Is it to prevent accidentally triggering PPI by manually setting the pin?
  2. 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!)

Parents Reply Children
Related