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

Sending data to iOS crashes midway

Using NRF51822 + SoftDevice 130, version 2.0.0, I have written a program which reads data from on-chip flash memory and transfers it to smartphone once connection is established. In order to determine if connection is established I wait for event "BLE_GAP_EVT_CONNECTED" in "on_ble_evt" handler. After that data is transferred using "ble_nus_string_send". 

When I connect to the device using NRF Toolbox app (in UART mode) on Android - All data is transferred correctly and can be seen in the application's Log.
When I connect to the device using the same app but this time on iOS - Data strarts to transfer correctly but hangs before all data is received by iPhone.

  • /* Variables */
    extern volatile memCellData_t currentMemCell;
    extern ble_nus_t m_nus;
    uint8_t stringData[4];
    extern volatile bool bleTxComplete;
    
    /* Functions */
    void dataTransfer (void)
    {
    	uint32_t word;
    	uint32_t readAddress = (uint32_t)FIRST_PAGE_START_ADDRESS;
    	uint32_t err_code;
    
    	// While there are words to read from FLASH
    	while(readAddress < currentMemCell.address)
    	{
    		// Read one word. Data LSB is in FLASH lower addresses.
    		word = FLASH_ReadWord((uint32_t *)readAddress);
    
    		// Check if this WORD is TIMESTAMP_MARKER
    		if(word == TIMESTAMP_MARKER)
    		{
    			// This WORD is TIMESTAMP_MARKER. This means next WORD is timeStamp data.
    
    			// Send TIMESTAMP marker to smartphone.
    			// Thus it knows that following WORD is timeStamp data.
    			err_code = ble_nus_string_send(&m_nus, (uint8_t *)integer2String(TIMESTAMP_MARKER), sizeof(stringData));
    			while(!bleTxComplete){};
    			APP_ERROR_CHECK(err_code);
    
    			// Skip to the first byte of next WORD (which is timeStamp data);
    			readAddress += WORD_SIZE;
    
    			// Read timeStamp WORD from FLASH.
    			word = FLASH_ReadWord((uint32_t *)readAddress);
    
    			// Send the timeStamp WORD to smartphone device via BLE.
    			err_code = ble_nus_string_send(&m_nus, (uint8_t *)integer2String(word), sizeof(stringData));
    		    while(!bleTxComplete){};
    			APP_ERROR_CHECK(err_code);
    
    			// Increment address for next read operation
    			readAddress += WORD_SIZE;
    		}
    		else
    		{
    			// Send sensorData WORD via BLE
    			err_code = ble_nus_string_send(&m_nus, (uint8_t *)integer2String(word), sizeof(stringData));
    			while(!bleTxComplete){};
    			APP_ERROR_CHECK(err_code);
    
    			// Increment address for next read operation
    			readAddress += WORD_SIZE;
    		}
    	}
    
    	// All data was extracted from FLASH.
    	// Reset currentMemCell values.
    	currentMemCell.page = (uint8_t)FIRST_PAGE;
    	currentMemCell.pageWasErased = false;
    	currentMemCell.address = (uint32_t)FIRST_PAGE_START_ADDRESS;
    }
    
    static uint8_t * integer2String (uint32_t data)
    {
    	stringData[0] = data >> 24;
    	stringData[1] = data >> 16;
    	stringData[2] = data >> 8;
    	stringData[3] = data;
    
    	return stringData;
    }
    
    uint32_t FLASH_ReadWord (uint32_t * byteAddress)
    {
    	return * byteAddress;
    }
    
    static void FLASH_Save (uint32_t value)
    {
    	// Check if the page, which is about to be written on, was already erased. If it was not - erase it!
    	if(!currentMemCell.pageWasErased)
    	{
    		flashIsBusy = true;
    		sd_flash_page_erase(currentMemCell.page);
    
    		// Wait for erase to complete. This is flag NRF_EVT_FLASH_OPERATION_SUCCESS
    		while(flashIsBusy)
    		{
    			//ToDo: Implement Sleep;
    		}
    		
    		currentMemCell.pageWasErased = true;
    	}
    
    	// After page was erased, write 4 bytes to specified address in the page
    	flashIsBusy = true;
    	sd_flash_write((uint32_t *)currentMemCell.address , &value, (uint32_t)1);
    
    	// Wait for write to complete. This is flag NRF_EVT_FLASH_OPERATION_SUCCESS
    	while(flashIsBusy)
    	{
    		// ToDo: Implement Sleep.
    	}
    
    	// Increment address with 4 bytes (one word) for next write operation
    	currentMemCell.address += 4;
    
    	// Check if updated address is now in the next page. If it is - increment page value, and toggle pageWasErased to false.
    	if((currentMemCell.address - (currentMemCell.page * PAGE_SIZE)) >= PAGE_SIZE)
    	{
    		currentMemCell.page ++;
    		currentMemCell.pageWasErased = false;
    	}
    }

  • I'm never actually resetting bleTxComplete flag. Let's see if that fixes it...

  • I assume that bleTxComplete is set to true in your TX_COMPLETE event?

    Are you sure you have set the breakpoint in your main() is in a place that is hit? Or that you are still debugging if the device resets?

    Can you please try to define DEBUG in your preprocessor defines and monitor your RTT log? Please let me know if you need help with doing this.

     

    When I connect to the device using the same app but this time on iOS - Data strarts to transfer correctly but hangs before all data is received by iPhone.

     This sounds awfully like an APP_ERROR_CHECK(err_code) when err_code != 0.

  • Yes, bleTxComplete is set true in "on_ble_evt()" handler. I am sure that the breakpoint in "main()" is going to be hit in case of reset, because I have used it a couple of times to detect such a behavior. 

    Now I'm going to place a breakpoint earlier - in the "APP_ERROR_CHECK()" and see what will happen. I know how to set DEBUG in preprocessor, but what do you mean by RTT log, is that the Debugger Log.

Related