Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Using TWI with PPI does not call the TWI handler.

Hey!

  I will post the whole code if necessary but for instance as I thought it would be a little glitch in my code, I tried to explain the basics of my problem for now:

- nrf52840 DK v1.1.0

- nrf5 SDK v17.02

- the template project in the peripheral folder is my starting point.

- Almost none of the peripherals has been disabled in the sdk_config.h

I have successfully configured and used SAADC, Timer, and TWI separately so I assume that my hardware is fine.

Also I have mixed the SAADC and a Timer with PPI , so on each compare event the conversion task is triggered.

Now I want to add a second task - in fork way- to the same PPI channel. but it looks like that the TWI handler is not called .

to do so , I have tried a few different configuration, because some of the docs was a bit vague to me somehow. so here is the current configuration:

- the function that is supposed to called everytime  after the TWI handler is called, so the TWI instance would be ready for the next PPI trigger:

static void read_sensor_data_ppi()
{
    m_xfer_done = false;
    nrf_gpio_pin_toggle (LED4);
    /* Read 1 byte from the specified address - skip 3 bits dedicated for fractional part of temperature. */
		
	nrf_drv_twi_xfer_desc_t 	twi_desc_type ;
	twi_desc_type.address = LM75B_ADDR;
	twi_desc_type.primary_length = sizeof(m_sample);
	twi_desc_type.p_primary_buf = &m_sample;
	
	 ret_code_t err_code = nrf_drv_twi_xfer(&m_twi, &twi_desc_type,	NRF_DRV_TWI_FLAG_HOLD_XFER); 	
     
}

- This is the TWI handler code, I have add some extra lines for debugging, apparently you can ignore them, also the data_handler function is just a single log commend :

-

void twi_handler(nrf_drv_twi_evt_t const * p_event, void * p_context)
{
	nrf_gpio_pin_toggle(LED2);
    switch (p_event->type)
    {
        case NRF_DRV_TWI_EVT_DONE:
						TWI_flag = 1;
            if (p_event->xfer_desc.type == NRF_DRV_TWI_XFER_RX)
            {
                data_handler(m_sample);
							  nrf_gpio_pin_toggle (LED3);
							  read_sensor_data_ppi();
            }
						
            m_xfer_done = true;
            break;
						
			  case NRF_DRV_TWI_EVT_ADDRESS_NACK:
					TWI_flag = 0;
            m_xfer_done = true;
						//NRF_LOG_INFO("note");
							
            break;
				case NRF_DRV_TWI_EVT_DATA_NACK:
						 TWI_flag = 0;
            m_xfer_done = true;
				
						NRF_LOG_INFO("11note");
            break;		
        default:
            break;
    }
}

-Here is the TWI initialization function which is almost just the same as it when I use it in blocking mode:

void twi_init(void)
{
  ret_code_t err_code; // a variable to hold error code

// Create a struct with configurations and pass the values to these configurations.
  const nrf_drv_twi_config_t twi_config = {
    .scl                = ARDUINO_SCL_PIN, // scl connected to pin 27, you can change it to any other pin
    .sda                = ARDUINO_SDA_PIN, // sda connected to pin 26, you can change it to any other pin
    .frequency          = NRF_DRV_TWI_FREQ_100K, // set the communication speed to 100K, we can select 250k or 400k as well
    .interrupt_priority = APP_IRQ_PRIORITY_HIGH, // Interrupt priority is set to high, keep in mind to change it if you are using a soft-device
    .clear_bus_init     = false // automatic bus clearing 

  };

  err_code = nrf_drv_twi_init(&m_twi, &twi_config, twi_handler, NULL); // initialize the twi
  APP_ERROR_CHECK(err_code); // check if any error occured during initialization

  nrf_drv_twi_enable(&m_twi); // enable the twi comm so that its ready to communicate with the sensor
	//first time ready for read
	read_sensor_data_ppi();

}

- the PPI configuration is here, I have just included the lines which are related to the TWI instance, as the PPI channel is working just fine with the SAADC task:

		uint32_t twi_start_task_addr = nrf_drv_twi_start_task_get ( &m_twi,
																	NRF_DRV_TWI_XFER_RX );
        err_code = nrf_drv_ppi_channel_assign(m_ppi_channel,
                                          timer_compare_event_addr,
                                          saadc_sample_task_addr);
																					
	    err_code = nrf_drv_ppi_channel_fork_assign (m_ppi_channel,
                                            twi_start_task_addr);																	
	

As you may notice , I have added a GPIO toggle command in the TWI handler, It just does not blink the way I have written the program, but why?

Related