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: "Connection End" event seemingly not synchronized with BLE TX

Part Number: CC2640
Other Parts Discussed in Thread: CC2650

Hi,

I'm working on a board where there appears to be coupling between BLE transmissions and some measurement circuitry. Due to this, I'm trying to synchronize my measurements to be immediately after the end of a connection event.  I'm using the CC2640 IC, with the BLE Stack 2.2.1. (I've probed the antenna TX port with 1 GHz oscilloscope probe, and am noticing spikes with a period of the connection interval, which are also aligned with the noise I'm seeing in the analog measurement circuitry).

I've tried to use the HCI_EXT_ConnEventNoticeCmd() command to trigger my measurement, but I am not seeing that any synchronization is taking place. Am I misinterpreting the operation of this function? Or is there some large seemingly random latency (of many milliseconds) between the actual transmission and the connection event end notice? Or is there likely a bug in my code?

My code is based on the simple_peripheral example. The main changes I've made are to always enable connection events (I removed the other references to enabling/disabling connection events) and to call custom measurement code when the connection end event happens.

    case GAPROLE_CONNECTED:
      {
        linkDBInfo_t linkInfo;
        uint8_t numActive = 0;

        Util_startClock(&periodicClock);
        numActive = linkDB_NumActive();

        // Use numActive to determine the connection handle of the last
        // connection
        if ( linkDB_GetInfo( numActive - 1, &linkInfo ) == SUCCESS )
        {
        	uint16_t connHandle = 0;
			Display_print1(dispHandle, 2, 0, "Num Conns: %d", (uint16_t)numActive);
			Display_print0(dispHandle, 3, 0, Util_convertBdAddr2Str(linkInfo.addr));
			// Enable connection events, shouldn't use much power, should it?
			if(GAPRole_GetParameter(GAPROLE_CONNHANDLE, &connHandle) == SUCCESS)
				HCI_EXT_ConnEventNoticeCmd(connHandle, selfEntity, SBP_CONN_EVT_END_EVT);
        }

And upon the event, I added a call to my custom function which toggles some I/O pins and starts a sensor controller task:

          // Check for BLE stack events first
          if (pEvt->signature == 0xffff)
          {
            if (pEvt->event_flag & SBP_CONN_EVT_END_EVT)
            {
				// And initiate the SC if needed
				SimpleBLEPeripheral_InitSCConnEvent();
				// Try to retransmit pending ATT Response (if any)
				SimpleBLEPeripheral_sendAttRsp();
            }
          }

Thanks,

Nathan

  • Hi,

    Since the application is at the lowest priority, higher priority process might run and cause some variance in receiving the event. Do you have a logic trace that captures these events.

    Best wishes
  • I agree that Application processing time could be an issue. In order to counter that, I've changed the connection interval to 50 ms (and longer) (during which I'd hope that application processes could complete). I still have TX pulses happening during my measurement cycle.  Tomorrow, I could try changing the connection interval to 250 ms, and see how it responds.

    I'm not familiar with how to do a logic trace. I'm using Code Composer Studio 7.2 with a CC2650 launchpad board as a debugger. I've tried following the SW Trace Instructions (including adding the IOCPortConfigureSet(...) call to my main() function right before ICall is initialized), but I'm getting an error when starting statistical function profiling ("Could not run alalyzer on Cortex_M3_0. Cause: Failed to open COM port"). Custom Core trace is giving the same error message.

      // Enable iCache prefetching
      VIMSConfigure(VIMS_BASE, TRUE, TRUE);
    
      // Enable cache
      VIMSModeSet(VIMS_BASE, VIMS_MODE_ENABLED);
    
      // Hardware Trace Support
      // See: <processors.wiki.ti.com/.../SWO_Trace>
    
      IOCPortConfigureSet(IOID_16, IOC_PORT_MCU_SWV, IOC_STD_OUTPUT);
    
      /* Initialize ICall module */
      ICall_init();

    On the other hand, I'm able to view the "ROV Classic" and "Runtime Object View", so it seems that at least part of debugger is working.

    Or was there some other hardware trace you were thinking about? This is difficult due to the multi-processor nature of this task. I think that it really needs some sort of debugger on the radio processor that can report TX events, and then being able to track how it goes through ICall to the application layer.

    -Nathan

  • Another debug help would be if a pin (of the 7x7 device) could be configured to output a pulse during TX. Is this possible to do? I'd like to try replicating my issue on the Launchpad board, but I'm not sure how to probe its antenna to detect the RF pulses.
  • One option is to map and use the range extender (RF Observable) IOs to monitor when the radio is TX or RX'ing. See the "CC2640 Range Extender Control" article on the TI BLE Wiki. Then you will not need to probe the antenna.

    As Zahid mentions, stack operations will take precedence over the application task. If you do the measurement during BLE idle activity, i.e, when only BLE empty packets are being sent, stack operations will be minimized. You can correlate the measurement with a BLE air sniffer to confirm only empty packets are being sent.

    Best wishes
  • Thanks for your help.

    I solved the issue, and it turned out to be something mostly unrelated.

    Mapping IOC_PORT_RFC_GP1 (PA enable) to an IO pin was helpful.

    I had conditionally delayed my measurement based on if the device was connected. The error was that I was calling linkDB_NumActive() from a SWI (clock timeout handler). It seems that in this case, it always returns 0, so I was not delaying my measurement until the connection end pulse. I modified the code to call this function from the main loop (through an event handler) instead. Now, my measurement is starting approx 350us after the PA turns off.

    // Called from main loop
    // If disconnected, immediately start measurement.
    // If connected, set the pending flag, which allows the next connection event to trigger a measurement, but also with a timeout in case the connection is lost.
    static void SimpleBLEPeripheral_requestInitiateSCReq_CB() {
    	// If not delayed or not connected
    	uint8 numConnections = linkDB_NumActive();
    	if(SimpleBLEPeripheral_delayedAfterTX_msTimeout == 0 || numConnections == 0) {
    		// Request Immediate Servicing, can be immediately called since not in SWI.
    		SimpleBLEPeripheral_handleInitiateSCEvent();
    	} else {
    		// Need to wait for either a timeout or a connection event
    		// Start the timeout clock
    		Clock_setTimeout(Clock_handle(&InitiateSCTimeoutClock), (SimpleBLEPeripheral_delayedAfterTX_msTimeout*1000)/Clock_tickPeriod);
    		Util_startClock(&InitiateSCTimeoutClock);
    		SimpleBLEPeripheral_setEventFlag(EVENTS_INITIATE_SC_PENDING);
    	}
    }

    -Nathan