Wake up event of Target Wake Time (TWT) on nRF7002-DK

Hi,

I'm developing an application to send data via UDP. In order to minimize the power consumption of my application, my idea is to send data during the wake time of TWT.

I start by connecting to the AP. To do this, I based myself on the Wi-Fi: Station sample where I get the following output (Image 1) :

  (Image 1 )

After this, I set up the TWT based on the Wi-Fi: TWT sample with the TWT_WAKE_INTERVAL and TWT_INTERVAL set to 20000us and 5000000us, respectively. I'm obtaining the following output (Image 2):

  ( Image 2 )

I was expecting that I would get an event when the wake up time and sleep time started. However, from what we can see in Image 2, it appears that I'm not obtaining any NET_EVENT_WIFI_TWT_SLEEP_STATE event. For this reason, I thought that my TWT application was not working (since there were no active or sleeping events), but after a quick test with the Joulescope JS110, I was able to verify that these events were being generated as we can see in the following image (Image 3) and  the TWT_WAKE_INTERVAL and TWT_INTERVAL are correct (Image 4):

  ( Image 3 )

  ( Image 4 )

At this moment, my wifi_mgmt_event_handler looks like:

static void wifi_mgmt_event_handler(struct net_mgmt_event_callback *cb,
									uint32_t mgmt_event, struct net_if *iface)
{
	switch (mgmt_event)
	{
	case NET_EVENT_WIFI_CONNECT_RESULT:
		LOG_INF(" ========================= NET_EVENT_WIFI_CONNECT_RESULT event ========================= " );
		handle_wifi_connect_result(cb);
		break;
		
	case NET_EVENT_WIFI_DISCONNECT_RESULT:
		LOG_INF(" ========================= NET_EVENT_WIFI_DISCONNECT_RESULT ========================= ");
		handle_wifi_disconnect_result(cb);
		break;

	case NET_EVENT_WIFI_TWT:
		LOG_INF(" ========================= NET_EVENT_WIFI_TWT event ========================= ");
		handle_wifi_twt_event(cb);
		break;

	case NET_EVENT_WIFI_TWT_SLEEP_STATE:
		LOG_INF(" ========================= NET_EVENT_WIFI_TWT_SLEEP_STATE event ========================= ");
		handle_wifi_twt_state_event(cb);
		break;

	default:
		LOG_ERR("(WIFI) Unknown event: %d ", mgmt_event);
		break;
	}
}

My main function looks like:

int main(void)
{
	int i, ret;

	memset(&context, 0, sizeof(context));

	net_mgmt_init_event_callback(&wifi_shell_mgmt_cb,
								 wifi_mgmt_event_handler,
								 WIFI_SHELL_MGMT_EVENTS);

	net_mgmt_add_event_callback(&wifi_shell_mgmt_cb);

	net_mgmt_init_event_callback(&net_shell_mgmt_cb,
								 net_mgmt_event_handler,
								 NET_EVENT_IPV4_DHCP_BOUND);

	net_mgmt_add_event_callback(&net_shell_mgmt_cb);

	LOG_INF("Starting %s with CPU frequency: %d MHz", CONFIG_BOARD, SystemCoreClock / MHZ(1));
	k_sleep(K_SECONDS(1));

	LOG_INF("Static IP address (overridable): %s/%s -> %s",
			CONFIG_NET_CONFIG_MY_IPV4_ADDR,
			CONFIG_NET_CONFIG_MY_IPV4_NETMASK,
			CONFIG_NET_CONFIG_MY_IPV4_GW);

	while (1)
	{

		wifi_connect();

		for (i = 0; i < CONNECTION_TIMEOUT; i++)
		{
			k_sleep(K_MSEC(STATUS_POLLING_MS));
			cmd_wifi_status();
			if (context.connect_result)
			{
				break;
			}
		}

		if (context.connected)
		{
			LOG_INF("============ Connected to wifi ============");
			break;
		}
		else if (!context.connect_result)
		{
			LOG_ERR("Connection Timed Out");
		}

		k_sleep(K_MSEC(300));
	}

	k_sleep(K_SECONDS(2));

	if (!twt_supported)
	{
		LOG_INF("AP is not TWT capable, exiting the sample\n");
		return 1;
	}
	else
	{
		LOG_INF("AP is TWT capable, establishing TWT");
	}

	ret = setup_twt(true);
	if (ret)
	{
		LOG_ERR("Failed to establish TWT flow: %d\n", ret);
		return 1;
	}

	k_sleep(K_FOREVER);

	return 0;
}

And my setup_twt function looks like:

static int setup_twt(bool enable)
{
	struct net_if *iface = net_if_get_default();
	struct wifi_twt_params params = { };
	int ret;

	params.operation = WIFI_TWT_SETUP;
	params.negotiation_type = WIFI_TWT_INDIVIDUAL;
	params.setup_cmd = WIFI_TWT_SETUP_CMD_REQUEST;
	params.dialog_token = 1;
	params.flow_id = 1;
	params.setup.responder = 0;
	params.setup.implicit = 1;
	params.setup.trigger = IS_ENABLED(CONFIG_TWT_TRIGGER_ENABLE);
	params.setup.announce = IS_ENABLED(CONFIG_TWT_ANNOUNCED_MODE);
	params.setup.twt_wake_interval = CONFIG_TWT_WAKE_INTERVAL;
	params.setup.twt_interval = CONFIG_TWT_INTERVAL;

	ret = net_mgmt(NET_REQUEST_WIFI_TWT, iface, &params, sizeof(params));
	if (ret)
	{
		LOG_INF("TWT setup failed: %d", ret);
		return ret;
	}
	else
	{
		LOG_INF("TWT setup requested");
	}

	return 0;
}

What I want to know is:

  • What am I doing wrong in the wake up and sleep events detection (in order to send data via UDP during the wake time)?
  • How can I fix the problem?

P.S.:

Sometimes looks like the TWT is not set (Image 5):

Thanks a lot! 

  • Hi,

     

    I set the TWT to 5.24 seconds, and wake interval to 65 ms, and this is my observed current during TWT:

    Are you certain that you actually enter TWT? TWT shall have a floor current of less than 20 uA.

     

    Kind regards,

    Håkon

  • Hi,

    Yes, I believe so. At least, I'm obtaining the following output:

    Now I'm also using SDK v2.4.99-dev2 and a Asus RT-AX53U router.

    This is my sample code:

    twtNordicSample.zip

    Thank you

  • Hi,

     

    I am running on the exact same tag, firmware unchanged, except for SSID/PWD used.

    Here's the current profile:

    And the log output:

    [00:00:00.465,728] <inf> net_config: Waiting interface 1 (0x20001460) to be up...
    [00:00:00.465,850] <inf> net_config: IPv4 address: 192.168.1.99
    [00:00:00.465,911] <inf> net_config: Running dhcpv4 client...
    [00:00:00.466,156] <inf> twt: Starting nrf7002dk_nrf5340_cpuapp with CPU frequency: 64 MHz
    [00:00:01.466,308] <inf> twt: Static IP address (overridable): 192.168.1.99/255.255.255.0 -> 192.168.1.1
    [00:00:03.387,786] <inf> twt: Connection requested
    [00:00:03.387,847] <inf> twt: ==================
    [00:00:03.387,847] <inf> twt: State: SCANNING
    [00:00:03.687,988] <inf> twt: ==================
    [00:00:03.688,018] <inf> twt: State: SCANNING
    [00:00:03.988,159] <inf> twt: ==================
    [00:00:03.988,189] <inf> twt: State: SCANNING
    [00:00:04.288,299] <inf> twt: ==================
    [00:00:04.288,330] <inf> twt: State: SCANNING
    [00:00:04.588,439] <inf> twt: ==================
    [00:00:04.588,470] <inf> twt: State: SCANNING
    [00:00:04.888,580] <inf> twt: ==================
    [00:00:04.888,610] <inf> twt: State: SCANNING
    [00:00:05.188,751] <inf> twt: ==================
    [00:00:05.188,781] <inf> twt: State: SCANNING
    [00:00:05.488,922] <inf> twt: ==================
    [00:00:05.488,952] <inf> twt: State: SCANNING
    [00:00:05.789,062] <inf> twt: ==================
    [00:00:05.789,093] <inf> twt: State: SCANNING
    [00:00:06.089,202] <inf> twt: ==================
    [00:00:06.089,233] <inf> twt: State: SCANNING
    [00:00:06.389,373] <inf> twt: ==================
    [00:00:06.389,404] <inf> twt: State: SCANNING
    [00:00:06.689,514] <inf> twt: ==================
    [00:00:06.689,544] <inf> twt: State: SCANNING
    [00:00:06.989,654] <inf> twt: ==================
    [00:00:06.989,685] <inf> twt: State: SCANNING
    [00:00:07.289,825] <inf> twt: ==================
    [00:00:07.289,855] <inf> twt: State: SCANNING
    [00:00:07.589,996] <inf> twt: ==================
    [00:00:07.590,026] <inf> twt: State: SCANNING
    [00:00:07.890,136] <inf> twt: ==================
    [00:00:07.890,167] <inf> twt: State: SCANNING
    [00:00:08.190,277] <inf> twt: ==================
    [00:00:08.190,307] <inf> twt: State: AUTHENTICATING
    [00:00:08.437,957] <inf> twt: Connected
    [00:00:08.495,849] <inf> net_dhcpv4: Received: 192.168.32.128
    [00:00:08.495,971] <inf> net_config: IPv4 address: 192.168.32.128
    [00:00:08.496,002] <inf> net_config: Lease time: 43200 seconds
    [00:00:08.496,032] <inf> net_config: Subnet: 255.255.255.0
    [00:00:08.496,063] <inf> net_config: Router: 192.168.32.1
    [00:00:08.496,154] <inf> twt: DHCP IP address: 192.168.32.128
    [00:00:08.498,382] <inf> twt: ==================
    [00:00:08.498,382] <inf> twt: State: COMPLETED
    [00:00:08.498,413] <inf> twt: Interface Mode: STATION
    [00:00:08.498,443] <inf> twt: Link Mode: WIFI 6 (802.11ax/HE)
    [00:00:08.498,474] <inf> twt: SSID: OpenWrt                         
    [00:00:08.498,504] <inf> twt: BSSID: FC:34:97:0B:F6:DC
    [00:00:08.498,535] <inf> twt: Band: 5GHz
    [00:00:08.498,535] <inf> twt: Channel: 36
    [00:00:08.498,565] <inf> twt: Security: WPA2-PSK
    [00:00:08.498,565] <inf> twt: MFP: Optional
    [00:00:08.498,596] <inf> twt: RSSI: -60
    [00:00:08.498,596] <inf> twt: TWT: Supported
    [00:00:10.498,687] <inf> twt: AP is TWT capable, establishing TWT
    [00:00:10.511,627] <inf> twt: TWT setup requested
    [00:00:10.519,897] <inf> twt: TWT response: TWT accept
    [00:00:10.519,927] <inf> twt: == TWT negotiated parameters ==
    [00:00:10.519,927] <inf> twt: TWT Dialog token: 1
    [00:00:10.519,927] <inf> twt: TWT flow ID: 0
    [00:00:10.519,958] <inf> twt: TWT negotiation type: TWT individual negotiation
    [00:00:10.519,989] <inf> twt: TWT responder: true
    [00:00:10.520,019] <inf> twt: TWT implicit: true
    [00:00:10.520,019] <inf> twt: TWT announce: false
    [00:00:10.520,050] <inf> twt: TWT trigger: false
    [00:00:10.520,080] <inf> twt: TWT wake interval: 65024 us
    [00:00:10.520,080] <inf> twt: TWT interval: 5005000 us
    [00:00:10.520,080] <inf> twt: ========================
    [00:00:10.520,812] <wrn> twt: TWT SLEEP
    [00:00:15.507,629] <wrn> twt: TWT AWAKE
    [00:00:15.573,364] <wrn> twt: TWT SLEEP
    [00:00:20.513,671] <wrn> twt: TWT AWAKE
    [00:00:20.580,688] <wrn> twt: TWT SLEEP
    [00:00:20.594,268] <wrn> twt: TWT AWAKE
    [00:00:20.594,390] <wrn> twt: TWT SLEEP
    ...
     

    I am not sure what the difference is in our setups. I'm supplying the VBAT from the PPK2, with 3.6V and measuring that current.

    Can you share a picture or similar with your measuring setup? 

    Kind regards,

    Håkon

  • Hi,


    I thought that turning off VCOM0 VCOM1 would be enough to measure the current consumed in this way, but I have seen that there are other components consuming current. By connecting the multimeter to the P22 port, I was able to verify a consumption of approximately 27uA during sleep time.

    Thank you

  • Hi,

     

    Thanks for posting the setup. This explains the difference between our results.

    The problem is that the nRF5340 is not power optimized in this sample (logging is on, qspi etc), it is only the nRF7002, which explains why you're seeing a base current of ~2 mA.

     

    Kind regards,

    Håkon

Related