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

Data from callback initialiser to callback?

I have a bluetooth service which I want to have to initialise a TWI transaction (using app_twi). I want to get the data back from the TWI transaction, but I can't figure quite the best way to do that. I have the ble service and TWI working separately, it's just bringing them together neatly that is awkward it seems.

I was previously trying to figure out out to get data back from a callback function, but I thought it might be easier to instead move the TWi transaction instantiation to the service file itself, that way the callback can occur in the same file as the data is required.

Where I am struggling now is in having the callback function send the data to the characteristic update function. The update function as always been located in service.c, but was previously called from main.c by a timeout interrupt where the data also originated. This was fine since the data structure (`ble_os_t m_our_service;) for the service is instantiated in main.c and it could be passed through to update function.

Now however, the updated data is coming from within the service.c.

The rh_read() function is called in the timer timout interrupt as before, but this generates a callback when the TWI transfer is complete. But since it's a callback, it doens't have access to the m_our_service data structure which is required by the update characteristic function, our_humidity_characteristic_update(&m_our_service, &rh_conv);

I can't pass it as p_user_data in the transaction data since it's 'not a compile time constant'.

How can I safely pass the required data structure through when there is this disconnection between transfer initiator and callback function?

static void rh_read_callback(ret_code_t result, void * p_data)
{
	nrf_gpio_pin_toggle(LED);

	
	if(result != NRF_SUCCESS)
	{
		printf("Transfer failure - twi_read_callback - Error: %d\r\n", (int)result); 
	}else{
		
		uint16_t rh_raw = (m_sht21_buffer[0]<<8) | (m_sht21_buffer[1]&0xFC) ; // 8 bit	
		uint16_t rh_conv   = -6 + ((125 * rh_raw)>>16); 	// RH= -6 + 125 * SRH/2^16 // 34us as floats, 2us as ints
		
		printf("\033[2J\033[1;1H");
		printf("RH real: %d%%\n\r\n", rh_conv);
		
		our_humidity_characteristic_update(&m_our_service, &rh_conv);     //////////////// PROBLEM
		
	}
}


void rh_read(void)
{
	
	
	static app_twi_transfer_t transfers[] = 
	{
		SHT21_RH_READ(&m_sht21_buffer[0])
	};
	static app_twi_transaction_t const transaction =
	{
	.callback            = rh_read_callback,
	.p_user_data         = NULL,
	.p_transfers         = transfers,
	.number_of_transfers = sizeof(transfers) / sizeof(transfers[0])
	};
	
	APP_ERROR_CHECK(app_twi_schedule(&m_app_twi, &transaction));
}

Later on I will have a few services accessing the TWI at potentially conflicting intervals. Will use of the app_twi_schedule() like I have here prevent any issues with that?

Related