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

notification and power_manage function

notification_problem.rarHi everyone

I would like to send a large number of bytes from nrf51822 to my central device. To be everything reliable and efficient I decided to use characteristic with notification. The test method is implemented in the following way:

uint32_t ble_mgs_history_send(uint16_t index)
{
	uint32_t err_code;
	
	if (m_mass.conn_handle != BLE_CONN_HANDLE_INVALID)
  {       
		uint16_t               hvx_len;
		ble_gatts_hvx_params_t hvx_params;				
		
		if(m_mass.mass_counter == 0)
		{			
			for(uint16_t i = 0; i < 250; i= i + 1)
			{
					m_mass.histroy_last[i] = i;
				  m_mass.histroy_last[i + 250] = 250 - i;         				
			}
		}
			
		m_mass.history_counter = 500;		
		
	  for(uint16_t j = 0; j < m_mass.history_counter; j = j + 20)
		{				
				memset(&hvx_params, 0, sizeof(hvx_params));
			  hvx_params.handle = m_mass.history_char_handles.value_handle;
				hvx_params.type   = BLE_GATT_HVX_NOTIFICATION;
				hvx_params.offset = 0;
			  hvx_len     = 20;
				
				hvx_params.p_len  = &hvx_len;				
				hvx_params.p_data = &m_mass.histroy_last[j];
				err_code = sd_ble_gatts_hvx(m_mass.conn_handle, &hvx_params);			
				
                            **m_mass.notification_flag = 2;**	
				while(m_mass.notification_flag != 1)
				{
					 power_manage();							
				}
			  m_mass.notification_flag = 0;				

				if (err_code != NRF_SUCCESS)
        {
           SEGGER_RTT_WriteString(0, "Error\n");	
        }      	 
		}
        
  }
	else
	{
			err_code = NRF_ERROR_INVALID_STATE;
	}

  return err_code;	
}

The entire code works fine, the function sd_ble_gatts_hvx sends 20bytes and after that, I get event handler BLE_EVT_TX_COMPLETE where variable m_mass.notification_flag is set to 1. On the other hand, if I remove the power_manage() function then the program sticks in a while function. If I am honest I do not know why this happens, because the function ble_mgs_history_send is executed in the main function via the scheduler. I will be grateful for any kind of suggestions

Samo

  • Strange. Have you tried putting a breakpoint at BLE_EVT_TX_COMPLETE? See if you get it at all? If not, are you getting any events at all? You can also consider uploading your complete project so I can test it here. Which SDK and SoftDevice version are you using?

  • Yes, I get the BLE_EVT_TX_COMPLETE event. It looks like that the program remains in while loop after first calling of sd_ble_gatts_hvx function although the flag changes the value to 1. I simplified the code and attached it to the first post. I use the SDK 10 and corresponding softdevice S110. I will be very pleased if you can check the code.

  • It seems to be a problem with optimization, but I'm not sure exactly what. Can you confirm that it works if you turn off optimizations?

  • Sorry I was abroad. I tested your idea and if I disable optimization (Level 0) I can remove power_manage() function and everything works fine. Can I use power_manage() function with optimization because I have a problem with space?

  • In addition, I observe that if the nrf chip is disconnected from BLE connection during waiting for BLE_EVT_TX_COMPLETE then nrf remains in the following while loop

    while(m_mass.notification_flag != 1)
            power_manage();                            
    

    because the event BLE_EVT_TX_COMPLETE is not executed. Due to this fact I define m_mass.notification_flag variable with three state 0, 1, 2. the value of 0 means that the program does not wait BLE_EVT_TX_COMPLETE event, 2 waits for BLE_EVT_TX_COMPLETE event and 1 events BLE_EVT_TX_COMPLETE arrives. In event BLE_GAP_EVT_DISCONNECTED: I added

    if(m_mass.notification_flag == 2)
       m_mass.notification_flag = 1;
    

    I tested the program and it looks like that everything works fine. Can you tell me if this approach is sufficiently good or I have to apply any other solution?

Related