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

No more BLE_EVT_TX_COMPLETE in SD7

I use Eclipse, gcc and OS X to compile.

I had FW working just fine with SD 6 and SDK 5.2. I recently tried to upgrade and ran into many problems, but the latest is the worst. I am now using SDK 6.1 and SD 7.0, and I also tried SD 7.1 and saw the same issue.

I have a custom service that I use to send data to an Android app. The data is usually much more than 20 bytes, so I have a loop like this in the code:

for (int i = 0; i < len; i+=20) {
	uint16_t size = (len-i > 20 ? 20 : len-i);
	memcpy(buffer, data+i, size);

	memset(&params, 0, sizeof(params));
	params.type = BLE_GATT_HVX_NOTIFICATION;
	params.handle = p_scs->data_up_handles.value_handle;
	params.p_data = buffer;
	params.p_len = &size;

	int error = sd_ble_gatts_hvx(p_scs->conn_handle, &params);

	//when sending data very fast, we can use up all the buffers. this should protect us as we wait for the TX complete event
	while (error == BLE_ERROR_NO_TX_BUFFERS) {
		simple_uart_putstring("Hit a No Buffer error \n");
		while (waitForTxComplete) {
			nrf_delay_us(500000);
			simple_uart_putstring("Still waiting \n");
		}
		waitForTxComplete = true;
		error = sd_ble_gatts_hvx(p_scs->conn_handle, &params);
		simple_uart_putstring("Still getting an error sending \n");
	}
	simple_uart_putstring("Past it \n");


	if (error != NRF_SUCCESS) {
		simple_uart_putstring("Still caught an error transmitting \n");
		if (error == BLE_ERROR_NO_TX_BUFFERS) {
			simple_uart_putstring("It's a buffer error! \n");
		}
		return error;
	}
}

Then I simply have a function in the class that listens for BLE events and does this on the event type:

   case BLE_EVT_TX_COMPLETE:
    	simple_uart_putstring("Got an event telling us we are all clear \n");
    	waitForTxComplete = false;
		break;

This all worked fine with SD6, the event would come through after the TX was complete and the data would all go through. Now, I never see the BLE_EVT_TX_COMPLETE event, and so I get stuck in a loop waiting for the TX Buffers to clear. I output debug through UART and I can see the event never comes. It transmits 7 twenty packet payloads before it hits a BLE_ERROR_NO_TX_BUFFERS error, and then it just hangs forever in the loop.

I know the events are all working properly because I send data down to the nrf51822 first and that works just fine. So it seems the only issue is the BLE_EVT_TX_COMPLETE event isn't coming through anymore. I checked documentation on the latest SD7.1 version and I cannot find anything about this.

Is there an issue? Or did something change that I am not handling correctly anymore?

  • Hi Eric,

    Please confirm that the 7 packets are received on the android device, if not check if p_scs->conn_handle has been assigned the correct value obtained from connected event.

    Regards, Vich

  • Ok, after leaving this for a while and coming back to it, I figured it out. As with 80% of problems, it turned out to be a user error!

    I had set up my code with SDK5.2 to NOT use app scheduler for BLE events. This meant that my main context would get interrupted by the BLE interrupts when they came through, so I would see the events while I was waiting for them.

    When I switched to SDK7, I had to re-copy over the ble_init_stack function as there were some changes. When I did that, I forgot to change the SOFTDEVICE_HANDLER_INIT to not use app scheduler. Therefore, the events were now getting caught and waiting for app_sched_exec to be called, which never happened since I was in a polling loop.

    It was just a dumb little flip of a boolean value that I didn't catch when I copy/pasted, which lead to behavior which I didn't immediately associate with the problem. I wanted to update this here in case anyone else runs into something similar...

Related