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);
    }
}

  • 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 

  • The softdevice can buffer about 6-8packets (more or less depending on configuration), if you need larger buffer you need to handle this in the application. For instance use use an app_timer (e.g. every 10ms) that will try to offload the data by calling sd_ble_gatts_hvx() until NRF_ERROR_RESOURCES occurs.

Related