This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC2640: bleTimeout (0x16) with GATT_Notification() using Android 5.0

Part Number: CC2640
Other Parts Discussed in Thread: CC2541,

I'm using the 2.2.1 SDK on the eval board.   My application reads in about 250 bytes per second via the UART and sends it via notification messages to my phone app by calling SerialPortService_SetParameter() as shown below.

The UART driver simply copies the data into a 270 byte circular buffer and a 5 mS event pulls up to 80 bytes, 4 20-byte chunks, at a time and sends it to the phone.  Our previous design used the CC2541 which was stable across all phone platforms including the Android 5.0 phone.  We are currently upgrading to the CC2640 so I am getting the design running on the eval board first. The design is stable on Android 6 and IOS 10.   When using Android 5 I can run for 10 to 15 seconds and then get a bleTimeout, return code 0x16, and the system is dead until I reconnect.    If I modify the design to write only 2 20-byte buffers every 80 mS then it runs for longer but will occasionally stall for 30 seconds and then come back to life.

Questions:

  1. What causes the bleTimeout since I am sending notification messages to the phone?
  2. When I get the bleTimeout is there any way to recover?
  3. Why when I throttle back does the system stall for 30 seconds and then recovers?

Thanks,

John

Code snippet:

static bool PumpDataToPhone(void)
{
	uint16		i;
	uint16		uLen;
	bStatus_t 	retVal;
	bool		bRtn;

	bRtn = false;

	if( s_uPhoneTxBuffHead != s_uPhoneTxBuffTail )
	{
		// We are active...
		bRtn = true;

		// Try to output 4 20 byte buffers...
		for( i = 0; i < 4; i++)
		{

			if( s_uPhoneTxBuffHead > s_uPhoneTxBuffTail)
			{
				uLen = s_uPhoneTxBuffHead - s_uPhoneTxBuffTail;
			}
			else
			{
				uLen = sizeof(s_phoneTxBuff) - s_uPhoneTxBuffTail;
			}

			if(uLen > TX_PACKET_SIZE)
			{
				uLen = TX_PACKET_SIZE;
			}

			retVal = SerialPortService_SetParameter(SERIALPORTSERVICE_CHAR_DATA, uLen, &s_phoneTxBuff[s_uPhoneTxBuffTail]);

			if(retVal == SUCCESS)
			{
				s_uPhoneTxBuffTail += uLen;

				if(s_uPhoneTxBuffTail >= sizeof(s_phoneTxBuff))
				{
					s_uPhoneTxBuffTail = 0;
				}


				if(s_uPhoneTxBuffTail == s_uPhoneTxBuffHead)
				{
					// No more to send...
					break;
				}
			}
			else
			{
				Display_print1(dispHandle, 4, 0, "JDO Noti Err: %d", retVal);
				break;
			}
		}
	}

	return(bRtn);
}

  • Hi John,

    I'll try my best to answer your questions, I've also contacted a serial data pro as well in case I missed anything.

    1. What causes the bleTimeout since I am sending notification messages to the phone?
    Time outs are cased when there's a GATT operation in progress. This includes notifications/reads/writes/etc.

    2. When I get the bleTimeout is there any way to recover?
    Attempt to re transmit , or perhaps decrease the connection interval. Can you attach a sniffer capture?

    3. Why when I throttle back does the system stall for 30 seconds and then recovers?
    It's hard to say. A sniffer capture of both events would be helpful to see what's going on.

    Regards,
    Rebel
  • Thanks for the quick response.  

    1.  How can a notification cause a time out since I thought it was send and forget?  

    2.  I do attempt to re-transmit but nothing comes out.

    3. See capture attached.

    4. Is there any way to determine before hand that the hardware is busy and I should not try to send?

    I have attached a packet capture from the TI packet sniffer.  In this capture I send 2 2-byte packets every 80 mS.  Packet 20602 is the last packet transmitted.  

    My test packets are 246 bytes and start with 0xAE F1 0E 52 00 01 02 up to 0xF0  with a cksum of 0xC0.

    Android5_TechDataError.psd

    Thanks,

    John 

  • Sorry, I thought we were talking about blePending the whole time, a timeout doesn't make sense here.

    1. They are usually send and forget, (after the controller as actually sent them, you can forget them).

    I noticed many retries in your environment. Until the controller has sent the notification, and the other controller has acknowledged the notification; the controller will be busy.

    Notifications themselves aren't acknowledged at any higher level -

    2. You attempt a re transmit, but do you get ble pending? or any other error code?

    3. Still too hard to say. Can you reproduce this using a simple_central and simple_peripheral?

    4. Well other than attempting to call an another ATT function, I'm not sure.

    I'll have to look deeper into this and get back to you

  • You mention many retries, can you point out the specific packet numbers?  For example, the last packet that was sent was 20602 but I don't see that it is retried.

    I get no other error codes, just a 0x16.

    I have not tried to reproduce using a a simple_peripheral/central combination.   I only have one eval board at my disposal.

    Thanks,

    John

  • Hi John,

    Like 3374 or 3554, they appear to be random.

    I'll have to dig into this to see what is causing the error code. I don't think I'll be able to get a response to you today, but certainly next week.

    Can you get an additional eval board? I'll have to be able to reproduce your issue to be able to do much more.

    We have a throughput example that uses notifications as it's data transport means, and it doesn't run into the problem you're seeing.

    In the meantime, perhaps you can attempt to replicate what's done in the throughput example: github.com/.../cc2650lp

    Regards,
    Rebel
  • Rebel,

    Thanks for your help but I have found the problem but I don't understand it yet.  My design started with the SPP example from : https://github.com/ti-simplelink/ble_examples.

    The UART Rx buffer is 128 bytes and the handler appears to disable and re-enable interrupts.  For some reason, and only with an Android 5, the UART Rx stalls which I then get a bleTimeout.  

    As a work-around, I simply increased the Rx buffer size, UART_ISR_BUF_SIZE, to be larger than my largest message, from 128 to 270 bytes, and now everything works.   I need to go back and revisit the UART handler to see if there is another issue that I am covering up.

    Thanks,

    John