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

BLE connection lost after Flash write

Hi: 

I use the SDK 13.0 and nRF52 DK to develop software for the project. Based on BLE UART (NUS), the software do SAADC sample and transfer the data out in real time, The ADC sampling rate is 250 Sa/s. The data is received by a nRF52 dongle board, and transferred to the local PC through UART. The system works fine. 

Now, I try to save the ADC sampling data to the BLE chip flash memory first, and then after triggered, data is read from flash and transferred out through bluetooth. The trigger now is "after finishing the flash write".

For flash write and Read, it's in a packet size of 64 samples. The problem is if I write 4 packets, and read/transfer 4 packets ( total data volume is 64*4 =256 samples), the software works fine. If I write and read/transfer more than 4 packets. the BLE software can be restarted/reset frequently. Double check the data pattern using a terminal software find, the restart/reset happens after/in the last packet write. Because of that, the slave and master device can not build stable connection, and no data transmission can be made.

My thought is the BLE connection parameters (connection interval) are not well tuned. But even tried with different settings on that, it still not work. 

The main function that do the flash write/read and data transfer is attached here. Need some insight to this problem. thanks 

#define MIN_CONNECTION_INTERVAL MSEC_TO_UNITS(180, UNIT_1_25_MS)         /**< Determines minimum connection interval in millisecond. */
#define MAX_CONNECTION_INTERVAL MSEC_TO_UNITS(220, UNIT_1_25_MS)         /**< Determines maximum connection interval in millisecond. */
#define SLAVE_LATENCY           0                                       /**< Determines slave latency in counts of connection events. */
#define SUPERVISION_TIMEOUT     MSEC_TO_UNITS(4000, UNIT_10_MS)  

#define SAADC_SAMPLES_IN_BUFFER         64

static uint16_t FS_WR_DATA_L = 32; 
static uint16_t FS_WR_N = 6; 

int main(void)
{
    uint32_t err_code;
    bool     erase_bonds;
	  int32_t volatile temp;

		///////////////////////
		NRF_POWER->DCDCEN = 1;
		///////////////////////
//		nrf_gpio_cfg_output(13);
//		nrf_gpio_pin_set(13);
//		nrf_gpio_cfg_output(12);
//		nrf_gpio_pin_clear(12);
	
    // Initialize.
		nrf_temp_init(); //////////////////////
		NRF_TEMP->TASKS_START = 1;
		///////////////////////////////////////
    err_code = app_timer_init();
    APP_ERROR_CHECK(err_code);

    uart_init();
    log_init();

    ble_stack_init();
    gap_params_init();
    gatt_init();
    services_init();
    advertising_init();
    conn_params_init();
	/////////////////////////
	//nrf_ble_gatt_data_length_set(&m_gatt, BLE_CONN_HANDLE_INVALID, 247+4);
	fstorage_init();
    
    saadc_sampling_event_init();
    saadc_init();
    saadc_sampling_event_enable();
		
		//////////////////////////////////20180925 Added
		pwm_setup();
		///////////////////////////////////
    printf("\r\nUART Start1!\r\n");		
    NRF_LOG_INFO("UART Start2!\r\n");
    err_code = ble_advertising_start(BLE_ADV_MODE_FAST);
    APP_ERROR_CHECK(err_code);

		////////////////////////////
		//nrf_gpio_cfg_output(19);
    // Enter main loop.
    for (;;)
    {
			if(fs_write_en == 1)
			{	
					uint16_t cc_r;
					uint8_t bytes_to_send;
					uint32_t value_from_f;
					uint8_t value_to_send[(SAADC_SAMPLES_IN_BUFFER)*2 +2];
					uint8_t value[SAADC_SAMPLES_IN_BUFFER*2 +5];
		
					cc_r = m_adc_evt_counter % FS_WR_N;
					
					printf("%x\r\n", cc_r);
					fstorage_write(cc_r * FS_WR_DATA_L, value_to_f, FS_WR_DATA_L);
//					fstorage_read(0, FS_WR_DATA_L);
					
					if (cc_r == (FS_WR_N - 1))
					{
						
						for (int j=0; j < FS_WR_N; j++)
						{
//							printf("%x\r\n", m_adc_evt_counter);
							printf("Data read from flash address 0x%X: \r\n", (uint32_t)fs_config.p_start_addr + j*32); 
							for(int i=0; i<(SAADC_SAMPLES_IN_BUFFER)/2; i++)
							{
								value_from_f = fstorage_read2(j*32 + i);
//								printf("%X \r\n", value_from_f);   
								value[i*4] 		 = value_from_f;
								value[(i*4)+1] = value_from_f >>  8;
								value[(i*4)+2] = value_from_f >> 16;
								value[(i*4)+3] = value_from_f >> 24;
							}  
								///////////////////////////////
								// read temperature sensor
								int32_t volatile temp;
								int32_t t;
								sd_temp_get(&t);
								temp = t;
					
								value[SAADC_SAMPLES_IN_BUFFER*2] = temp;
								value[SAADC_SAMPLES_IN_BUFFER*2 + 1] = temp >> 8;
								value[SAADC_SAMPLES_IN_BUFFER*2 + 2] = m_adc_evt_counter;
								value[SAADC_SAMPLES_IN_BUFFER*2 + 3] = 0x7A;
								value[SAADC_SAMPLES_IN_BUFFER*2 + 4] = 0x7A;
								// Send data over BLE via NUS service. Makes sure not to send more than 20 bytes.
								if((SAADC_SAMPLES_IN_BUFFER*2) <= NRF_BLE_GATT_MAX_MTU_SIZE - 3) 
								{
										bytes_to_send = (SAADC_SAMPLES_IN_BUFFER*2 + 5);
								}
								else 
								{
										bytes_to_send = 20;
								}
//								if( m_conn_handle != BLE_CONN_HANDLE_INVALID ) 
//								{
									err_code = ble_nus_string_send(&m_nus, value, bytes_to_send);
									if (err_code != NRF_ERROR_INVALID_STATE) 
									{
											APP_ERROR_CHECK(err_code);
									}	
//								}
							}
						}
					m_adc_evt_counter++; 
						
					if ( cc_r == (FS_WR_N - 1))
					{
						fstorage_erase();
					}
					fs_write_en = 0;
					power_manage();
				}
				else
				{
						power_manage();
				}
					// Put SDN# in HIGH mode
				nrf_gpio_cfg_output(8);
				nrf_gpio_pin_set(8);
    }
}

Parents
  • It sounds to me that you have an assert in your application, which will by default reset the chip to recover. However during development it is useful to catch the assert, this can be done by define DEBUG in your project (preprocessor symbols), then you can find that in app_error_fault_handler() the code should run app_error_save_and_stop() instead of NVIC_SystemReset(). 

    In app_error_save_and_stop() you should be able to identify the file name, line number and error code for the assert.

  • Hi Kenneth:

    Thanks for prompt reply. 

    Can you kindly provide more information on how to catch the assert, and how to add DEBUG?

    Thanks

  • It's only when you receive err_code = NRF_SUCCESS that the packet is queued to be sent as notification. Do you take into account that when you receive the BLE_GATTS_EVT_HVN_TX_COMPLETE event you also need to check the counter value to know how many packets were sent? 

    p_ble_evt->evt.gatts_evt.params.hvn_tx_complete.count


  • No, I did not do that. 

    What's that, and should I do that? See some example codes, do not see they do this. Or do you more information about this?

    Wei

  • I think it is easier to help you if you can describe what you want to do.

    Most just send notification by calling sd_ble_gatts_hvx() until NRF_ERROR_RESOURCES, wait for BLE_GATTS_EVT_HVN_TX_COMPLETE event, and then call sd_ble_gatts_hvx() until NRF_ERROR_RESOURCES again. This can be repeated indefinitely. 

    Just be aware that you will get one BLE_GATTS_EVT_HVN_TX_COMPLETE for many sd_ble_gatts_hvx() calls.

    If you want to know how many notifications that was actually sent you need to check p_ble_evt->evt.gatts_evt.params.hvn_tx_complete.count on BLE_GATTS_EVT_HVN_TX_COMPLETE event.

  • By the way, can I change the tx buffer length ?

    Thx

  • Hi Kenneth:

    Now, I try to save the ADC sampling data (250Sa/s) to the BLE chip flash memory first, and then after triggered, data is read from flash and transferred out through bluetooth. The trigger now is "after finishing the flash write".

    For flash write and Read, it's in a packet size of 64 samples. The problem is if I write 4 packets, and read/transfer 4 packets ( total data volume is 64*4 =256 samples), the software works fine. If I write and read/transfer more than 4 packets. the BLE software can be restarted/reset frequently. Double check the data pattern using a terminal software find, the restart/reset happens after/in the last packet write. this is because of the APP_ERROR_CHECK(err_code). 

    This is my application request. How can I check the BLE_GATTS_EVT_HVN_TX_COMPLETE event? So I can transfer as many packets as possible in one time transfer? So I can read the saved data from flash memory and transfer them out in one time, like may be with the data size of 64packets * 128 bytes, or bigger.

    Thanks

    Wei 

Reply
  • Hi Kenneth:

    Now, I try to save the ADC sampling data (250Sa/s) to the BLE chip flash memory first, and then after triggered, data is read from flash and transferred out through bluetooth. The trigger now is "after finishing the flash write".

    For flash write and Read, it's in a packet size of 64 samples. The problem is if I write 4 packets, and read/transfer 4 packets ( total data volume is 64*4 =256 samples), the software works fine. If I write and read/transfer more than 4 packets. the BLE software can be restarted/reset frequently. Double check the data pattern using a terminal software find, the restart/reset happens after/in the last packet write. this is because of the APP_ERROR_CHECK(err_code). 

    This is my application request. How can I check the BLE_GATTS_EVT_HVN_TX_COMPLETE event? So I can transfer as many packets as possible in one time transfer? So I can read the saved data from flash memory and transfer them out in one time, like may be with the data size of 64packets * 128 bytes, or bigger.

    Thanks

    Wei 

Children
No Data
Related