k_uptime_get() returning wrong values

Hi,

I'm trying to measure message travel time using Gazel and k_uptime_get() so I can understand the packet intervals.

I'm using gzll_ack_payload_device and gzll_ack_payload_host from v2.6.1 sample apps modified to send k_uptime_get() as the payload and measure the delta received in the ACK's payload (see git diffs below).

I'm seeing time deltas of 115 msec when I try to use k_uptime_get() stamping.

Then I used LED flashing on both DK boards to be able to measure the timing and I see 1 msec from device to host and 3 msec from host ACK back to device which makes more sense (Analyzer images below)

What is the reason for k_uptime_get() to return wrong reading? I checked the build/zephyr/.config file and I see CONFIG_SYS_CLOCK_TICKS_PER_SEC=32768.

Thanks,

Guy.

diff --git a/samples/gazell/gzll_ack_payload_device/src/main.c b/samples/gazell/gzll_ack_payload_device/src/main.c
index 58bb7fc93..1e8b863ea 100644
--- a/samples/gazell/gzll_ack_payload_device/src/main.c
+++ b/samples/gazell/gzll_ack_payload_device/src/main.c
@@ -17,7 +17,7 @@ LOG_MODULE_REGISTER(app);
 #define PIPE_NUMBER 0

 /* 1-byte payload length is used when transmitting. */
-#define TX_PAYLOAD_LENGTH 1
+#define TX_PAYLOAD_LENGTH 8

 /* Maximum number of transmission attempts */
 #define MAX_TX_ATTEMPTS 100
@@ -51,6 +51,7 @@ K_MSGQ_DEFINE(gzll_msgq,
 static K_SEM_DEFINE(main_sem, 0, 1);

 static struct k_work gzll_work;
+static uint64_t start_time, end_time;

 static void gzll_tx_result_handler(struct gzll_tx_result *tx_result);
 static void gzll_work_handler(struct k_work *work);
@@ -99,8 +100,10 @@ int main(void)
        }
 #endif

-       data_payload[0] = ~dk_get_buttons();
+       // data_payload[0] = ~dk_get_buttons();

+       *(uint64_t *)data_payload = k_uptime_get();
+       LOG_INF("Entering data payload %llu", *(uint64_t *)data_payload);
        result_value = nrf_gzll_add_packet_to_tx_fifo(PIPE_NUMBER, data_payload, TX_PAYLOAD_LENGTH);
        if (!result_value) {
                LOG_ERR("Cannot add packet to GZLL TX FIFO");
@@ -170,11 +173,13 @@ static void gzll_device_report_tx(bool success,

 void nrf_gzll_device_tx_success(uint32_t pipe, nrf_gzll_device_tx_info_t tx_info)
 {
+       LOG_INF("Tx success payload %s in ACK", tx_info.payload_received_in_ack?"received":"not received");
        gzll_device_report_tx(true, pipe, &tx_info);
 }

 void nrf_gzll_device_tx_failed(uint32_t pipe, nrf_gzll_device_tx_info_t tx_info)
 {
+       LOG_INF("Tx failed");
        gzll_device_report_tx(false, pipe, &tx_info);
 }

@@ -207,6 +212,7 @@ static void gzll_tx_result_handler(struct gzll_tx_result *tx_result)

        if (tx_result->success) {
                if (tx_result->info.payload_received_in_ack) {
+                       end_time = k_uptime_get();
                        /* Pop packet and write first byte of the payload to the GPIO port. */
                        result_value = nrf_gzll_fetch_packet_from_rx_fifo(tx_result->pipe,
                                                                          ack_payload,
@@ -214,22 +220,32 @@ static void gzll_tx_result_handler(struct gzll_tx_result *tx_result)
                        if (!result_value) {
                                LOG_ERR("RX fifo error");
                        } else if (ack_payload_length > 0) {
-                               err = dk_set_leds(ack_payload[0] & DK_ALL_LEDS_MSK);
+                               err = dk_set_leds_state(0, DK_ALL_LEDS_MSK);
                                if (err) {
                                        LOG_ERR("Cannot output LEDs (err: %d)", err);
                                }
+                               // LOG_INF("ACK payload %llu end time %llu", *(uint64_t *)ack_payload, end_time);
+                               LOG_INF("Time diff %lld", k_uptime_delta((uint64_t *)ack_payload));
                        }
                }
        } else {
                LOG_ERR("Gazell transmission failed");
        }

+       k_msleep(100);
        /* Load data payload into the TX queue. */
-       data_payload[0] = ~dk_get_buttons();
+       start_time=k_uptime_get();
+       // LOG_INF("Uptime %lld", start_time);
+       *(uint64_t *)data_payload = k_uptime_get();
+       // LOG_INF("Entering data payload %llu", *(uint64_t *)data_payload);
        result_value = nrf_gzll_add_packet_to_tx_fifo(tx_result->pipe,
                                                      data_payload,
                                                      TX_PAYLOAD_LENGTH);
        if (!result_value) {
                LOG_ERR("TX fifo error");
        }
+       err = dk_set_leds_state(DK_ALL_LEDS_MSK, 0);
+       if (err) {
+               LOG_ERR("Cannot output LEDs (err: %d)", err);
+       }
 }

diff --git a/samples/gazell/gzll_ack_payload_device/src/main.c b/samples/gazell/gzll_ack_payload_device/src/main.c
index 58bb7fc93..1e8b863ea 100644
--- a/samples/gazell/gzll_ack_payload_device/src/main.c
+++ b/samples/gazell/gzll_ack_payload_device/src/main.c
@@ -17,7 +17,7 @@ LOG_MODULE_REGISTER(app);
 #define PIPE_NUMBER 0

 /* 1-byte payload length is used when transmitting. */
-#define TX_PAYLOAD_LENGTH 1
+#define TX_PAYLOAD_LENGTH 8

 /* Maximum number of transmission attempts */
 #define MAX_TX_ATTEMPTS 100
@@ -51,6 +51,7 @@ K_MSGQ_DEFINE(gzll_msgq,
 static K_SEM_DEFINE(main_sem, 0, 1);

 static struct k_work gzll_work;
+static uint64_t start_time, end_time;

 static void gzll_tx_result_handler(struct gzll_tx_result *tx_result);
 static void gzll_work_handler(struct k_work *work);
@@ -99,8 +100,10 @@ int main(void)
        }
 #endif

-       data_payload[0] = ~dk_get_buttons();
+       // data_payload[0] = ~dk_get_buttons();

+       *(uint64_t *)data_payload = k_uptime_get();
+       LOG_INF("Entering data payload %llu", *(uint64_t *)data_payload);
        result_value = nrf_gzll_add_packet_to_tx_fifo(PIPE_NUMBER, data_payload, TX_PAYLOAD_LENGTH);
        if (!result_value) {
                LOG_ERR("Cannot add packet to GZLL TX FIFO");
@@ -170,11 +173,13 @@ static void gzll_device_report_tx(bool success,

 void nrf_gzll_device_tx_success(uint32_t pipe, nrf_gzll_device_tx_info_t tx_info)
 {
+       LOG_INF("Tx success payload %s in ACK", tx_info.payload_received_in_ack?"received":"not received");
        gzll_device_report_tx(true, pipe, &tx_info);
 }

 void nrf_gzll_device_tx_failed(uint32_t pipe, nrf_gzll_device_tx_info_t tx_info)
 {
+       LOG_INF("Tx failed");
        gzll_device_report_tx(false, pipe, &tx_info);
 }

@@ -207,6 +212,7 @@ static void gzll_tx_result_handler(struct gzll_tx_result *tx_result)

        if (tx_result->success) {
                if (tx_result->info.payload_received_in_ack) {
+                       end_time = k_uptime_get();
                        /* Pop packet and write first byte of the payload to the GPIO port. */
                        result_value = nrf_gzll_fetch_packet_from_rx_fifo(tx_result->pipe,
                                                                          ack_payload,
@@ -214,22 +220,32 @@ static void gzll_tx_result_handler(struct gzll_tx_result *tx_result)
                        if (!result_value) {
                                LOG_ERR("RX fifo error");
                        } else if (ack_payload_length > 0) {
-                               err = dk_set_leds(ack_payload[0] & DK_ALL_LEDS_MSK);
+                               err = dk_set_leds_state(0, DK_ALL_LEDS_MSK);
                                if (err) {
                                        LOG_ERR("Cannot output LEDs (err: %d)", err);
                                }
+                               // LOG_INF("ACK payload %llu end time %llu", *(uint64_t *)ack_payload, end_time);
+                               LOG_INF("Time diff %lld", k_uptime_delta((uint64_t *)ack_payload));
                        }
                }
        } else {
                LOG_ERR("Gazell transmission failed");
        }

+       k_msleep(100);
        /* Load data payload into the TX queue. */
-       data_payload[0] = ~dk_get_buttons();
+       start_time=k_uptime_get();
+       // LOG_INF("Uptime %lld", start_time);
+       *(uint64_t *)data_payload = k_uptime_get();
+       // LOG_INF("Entering data payload %llu", *(uint64_t *)data_payload);
        result_value = nrf_gzll_add_packet_to_tx_fifo(tx_result->pipe,
                                                      data_payload,
                                                      TX_PAYLOAD_LENGTH);
        if (!result_value) {
                LOG_ERR("TX fifo error");
        }
+       err = dk_set_leds_state(DK_ALL_LEDS_MSK, 0);
+       if (err) {
+               LOG_ERR("Cannot output LEDs (err: %d)", err);
+       }
 }

Parents
  • Hello,

    Are you changing both of the projects? I see that you have uploaded the modifications of the same file two times (i.e of the payload device).

    Can you share some console logs from both devices?

    How are you measuring? Are you measuring the time for two-way trip (transmission from device and receiving acknowledgement back at device)? Or between device and host?

    I can see that you are calculating delta on the device side like this:

    LOG_INF("Time diff %lld", k_uptime_delta((uint64_t *)ack_payload));

    but two devices have their own booting time, and hence you should be measuring the DELTA from the time packet was sent to the time acknowledgement is received. But this code is not doing that. This code is taking the DELTA between the current-time-of-Device and the time (of Host) at which ACK was sent.


  • Sorry, didn't notice that I pasted the same diff twice. Here's the host side:

    diff --git a/samples/gazell/gzll_ack_payload_host/src/main.c b/samples/gazell/gzll_ack_payload_host/src/main.c
    index d06180e83..a946c84e4 100644
    --- a/samples/gazell/gzll_ack_payload_host/src/main.c
    +++ b/samples/gazell/gzll_ack_payload_host/src/main.c
    @@ -17,7 +17,7 @@ LOG_MODULE_REGISTER(app);
     #define PIPE_NUMBER 0
    
     /* 1-byte payload length is used when transmitting. */
    -#define TX_PAYLOAD_LENGTH 1
    +#define TX_PAYLOAD_LENGTH 8
    
     /* Gazell Link Layer RX result structure */
     struct gzll_rx_result {
    @@ -158,6 +158,10 @@ void nrf_gzll_host_rx_data_ready(uint32_t pipe, nrf_gzll_host_rx_info_t rx_info)
            int err;
            struct gzll_rx_result rx_result;
    
    +       err = dk_set_leds_state(DK_ALL_LEDS_MSK, 0);
    +       if (err) {
    +               LOG_ERR("Cannot output LEDs (err: %d)", err);
    +       }
            rx_result.pipe = pipe;
            rx_result.info = rx_info;
            err = k_msgq_put(&gzll_msgq, &rx_result, K_NO_WAIT);
    @@ -194,15 +198,21 @@ static void gzll_rx_result_handler(struct gzll_rx_result *rx_result)
            if (!result_value) {
                    LOG_ERR("RX fifo error");
            } else if (data_payload_length > 0) {
    -               err = dk_set_leds(data_payload[0] & DK_ALL_LEDS_MSK);
    -               if (err) {
    -                       LOG_ERR("Cannot output LEDs (err: %d)", err);
    -               }
    +               // err = dk_set_leds(data_payload[0] & DK_ALL_LEDS_MSK);
    +               // if (err) {
    +               //      LOG_ERR("Cannot output LEDs (err: %d)", err);
    +               // }
    +               // LOG_INF("Got payload %llu", *(uint64_t *)data_payload);
            }
    
            /* Read buttons and load ACK payload into TX queue. */
    -       ack_payload[0] = ~dk_get_buttons(); /* Button logic is inverted. */
    +       // ack_payload[0] = ~dk_get_buttons(); /* Button logic is inverted. */
    +       memcpy(ack_payload, data_payload, sizeof(uint64_t));
    
    +       err = dk_set_leds_state(0, DK_ALL_LEDS_MSK);
    +       if (err) {
    +               LOG_ERR("Cannot output LEDs (err: %d)", err);
    +       }
            result_value = nrf_gzll_add_packet_to_tx_fifo(rx_result->pipe,
                                                          ack_payload,
                                                          TX_PAYLOAD_LENGTH);

    Basically, I send the timestamp from the device in the packet payload, and add it to the ACK from the host. 

    So ack_payload is basically the timestamp where the packet has been sent and the diff should represent round trip.

    The printout I have is limited since I didn't want to introduce UART latency but on the device console I see this:

    I: Tx success payload received in ACK
    I: Time diff 114
    I: Tx success payload received in ACK
    I: Time diff 115
    I: Tx success payload received in ACK
    I: Time diff 114
    I: Tx success payload received in ACK
    I: Time diff 115
    I: Tx success payload received in ACK
    I: Time diff 115
    I: Tx success payload received in ACK
    I: Time diff 114
    I: Tx success payload received in ACK
    I: Time diff 115
    I: Tx success payload received in ACK
    I: Time diff 115
    I: Tx success payload received in ACK
    I: Time diff 114
    I: Tx success payload received in ACK
    I: Time diff 115
    I: Tx success payload received in ACK
    I: Time diff 115
    I: Tx success payload received in ACK
    I: Time diff 115
    

    This keeps repeating. You can see that the reported time is 114-115 and the scope graphs are showing much lower latency

    Thanks,

    Guy.

  • I figured out that the reason for the clock deviation is because I'm getting and ACK for the packet previous to last one.

    My flow is basically taking the sample app of sending a timestamp on every ACK and when receiving and ACK measuring the now - timestamp in the payload.

    The host side just pushes the payload back into the ACK.

    My question is why am I getting these buffered ACKs?

    Here's my device code:

    /*
     * Copyright (c) 2021 Nordic Semiconductor ASA
     *
     * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
     */
    
    #include <zephyr/kernel.h>
    #include <date_time.h>
    #include <nrf_gzll.h>
    #include <gzll_glue.h>
    #include <dk_buttons_and_leds.h>
    
    #include <zephyr/logging/log.h>
    
    LOG_MODULE_REGISTER(app);
    
    /* Pipe 0 is used in this example. */
    #define PIPE_NUMBER 0
    
    /* 1-byte payload length is used when transmitting. */
    #define TX_PAYLOAD_LENGTH 8
    
    /* Maximum number of transmission attempts */
    #define MAX_TX_ATTEMPTS 100
    
    /* Gazell Link Layer TX result structure */
    struct gzll_tx_result {
    	bool success;
    	uint32_t pipe;
    	nrf_gzll_device_tx_info_t info;
    };
    
    #ifdef CONFIG_GZLL_TX_STATISTICS
    /* Struct containing transmission statistics. */
    static nrf_gzll_tx_statistics_t statistics;
    static nrf_gzll_tx_statistics_t statistics_2;
    #endif
    
    /* Gazell Link Layer TX result message queue */
    K_MSGQ_DEFINE(gzll_msgq,
    	      sizeof(struct gzll_tx_result),
    	      1,
    	      sizeof(uint32_t));
    
    /* Main loop semaphore */
    static K_SEM_DEFINE(main_sem, 0, 1);
    
    static struct k_work gzll_work;
    static uint64_t end_time;
    static 	nrf_gzll_device_tx_info_t dummy_tx_info;
    
    static void gzll_tx_result_handler(struct gzll_tx_result *tx_result);
    static void gzll_work_handler(struct k_work *work);
    static void gzll_device_report_tx(bool success, uint32_t pipe, nrf_gzll_device_tx_info_t *tx_info);
    
    int main(void)
    {
    	int err;
    	bool result_value;
    	struct tm now;
    	/* Payload to send to Host. */
    	// static uint8_t data_payload[TX_PAYLOAD_LENGTH];
    	
    	now.tm_sec = 0;
    	now.tm_min = 0;
    	now.tm_hour = 12;
    	now.tm_mday = 1;
    	now.tm_mon = 7;
    	now.tm_year = 124;
    	now.tm_wday = 2;
    
    	err = date_time_set(&now);
    
    	k_work_init(&gzll_work, gzll_work_handler);
    
    	// LOG_INF("Time divider %d", CONFIG_DATE_TIME_UPDATE_INTERVAL_SECONDS);
    
    	err = dk_leds_init();
    	if (err) {
    		LOG_ERR("Cannot initialize LEDs (err: %d)", err);
    		return 0;
    	}
    
    	err = dk_buttons_init(NULL);
    	if (err) {
    		LOG_ERR("Cannot initialize buttons (err: %d)", err);
    		return 0;
    	}
    
    	/* Initialize Gazell Link Layer glue */
    	result_value = gzll_glue_init();
    	if (!result_value) {
    		LOG_ERR("Cannot initialize GZLL glue code");
    		return 0;
    	}
    
    	/* Initialize the Gazell Link Layer */
    	result_value = nrf_gzll_init(NRF_GZLL_MODE_DEVICE);
    	if (!result_value) {
    		LOG_ERR("Cannot initialize GZLL");
    		return 0;
    	}
    
    	nrf_gzll_set_max_tx_attempts(MAX_TX_ATTEMPTS);
    
    #ifdef CONFIG_GZLL_TX_STATISTICS
    	/* Turn on transmission statistics gathering. */
    	result_value = nrf_gzll_tx_statistics_enable(&statistics);
    	if (!result_value) {
    		LOG_ERR("Cannot enable GZLL TX statistics");
    		return 0;
    	}
    #endif
    
    	// data_payload[0] = ~dk_get_buttons();
    
    	dummy_tx_info.payload_received_in_ack = false;
    	gzll_device_report_tx(true, PIPE_NUMBER,  &dummy_tx_info);
    	// err = date_time_now((uint64_t *)data_payload);
    	// // *(uint64_t *)data_payload = k_uptime_get();
    	// LOG_INF("Entering data payload %llu", *(uint64_t *)data_payload);
    	// result_value = nrf_gzll_add_packet_to_tx_fifo(PIPE_NUMBER, data_payload, TX_PAYLOAD_LENGTH);
    	// if (!result_value) {
    	// 	LOG_ERR("Cannot add packet to GZLL TX FIFO");
    	// 	return 0;
    	// }
    
    	result_value = nrf_gzll_enable();
    	if (!result_value) {
    		LOG_ERR("Cannot enable GZLL");
    		return 0;
    	}
    
    	LOG_INF("Gzll ack payload device example started.");
    
    	while (true) {
    		if (k_sem_take(&main_sem, K_FOREVER)) {
    			continue;
    		}
    
    #ifdef CONFIG_GZLL_TX_STATISTICS
    		if (statistics.packets_num >= 1000) {
    			uint32_t key = irq_lock();
    
    			statistics_2 = statistics;
    
    			/* Reset statistics buffers. */
    			nrf_gzll_reset_tx_statistics();
    
    			irq_unlock(key);
    
    			/* Print all transmission statistics. */
    			LOG_INF("");
    			LOG_INF("Total transmitted packets:   %4u",  statistics_2.packets_num);
    			LOG_INF("Total transmission time-outs: %03u", statistics_2.timeouts_num);
    			LOG_INF("");
    
    			for (uint8_t i = 0; i < nrf_gzll_get_channel_table_size(); i++) {
    				LOG_INF(
    				"Channel %u: %03u packets transmitted, %03u transmissions failed.",
    				i,
    				statistics_2.channel_packets[i],
    				statistics_2.channel_timeouts[i]);
    			}
    		}
    #endif
    	}
    }
    
    static void gzll_device_report_tx(bool success,
    				  uint32_t pipe,
    				  nrf_gzll_device_tx_info_t *tx_info)
    {
    	int err;
    	struct gzll_tx_result tx_result;
    
    	tx_result.success = success;
    	tx_result.pipe = pipe;
    	tx_result.info = *tx_info;
    	err = k_msgq_put(&gzll_msgq, &tx_result, K_NO_WAIT);
    	if (!err) {
    		/* Get work handler to run */
    		k_work_submit(&gzll_work);
    	} else {
    		LOG_ERR("Cannot put TX result to message queue");
    	}
    }
    
    void nrf_gzll_device_tx_success(uint32_t pipe, nrf_gzll_device_tx_info_t tx_info)
    {
    	// LOG_INF("Tx success payload %s in ACK", tx_info.payload_received_in_ack?"received":"not received");
    	gzll_device_report_tx(true, pipe, &tx_info);
    }
    
    void nrf_gzll_device_tx_failed(uint32_t pipe, nrf_gzll_device_tx_info_t tx_info)
    {
    	LOG_INF("Tx failed");
    	gzll_device_report_tx(false, pipe, &tx_info);
    }
    
    void nrf_gzll_disabled(void)
    {
    }
    
    void nrf_gzll_host_rx_data_ready(uint32_t pipe, nrf_gzll_host_rx_info_t rx_info)
    {
    }
    
    static void gzll_work_handler(struct k_work *work)
    {
    	struct gzll_tx_result tx_result;
    
    	/* Process message queue */
    	while (!k_msgq_get(&gzll_msgq, &tx_result, K_FOREVER)) {
    		gzll_tx_result_handler(&tx_result);
    	}
    
    	/* Get main loop to run */
    	k_sem_give(&main_sem);
    }
    
    void data_send_cb(struct k_timer *tmr)
    {
    	int result_value;
    	/* Payload to send to Host. */
    	static uint8_t data_payload[TX_PAYLOAD_LENGTH];
    
    	/* Load data payload into the TX queue. */
    	result_value = date_time_now((uint64_t *)data_payload);
    	LOG_INF("Entering data payload %llu", *(uint64_t *)data_payload);
    	result_value = nrf_gzll_add_packet_to_tx_fifo(PIPE_NUMBER,
    						      data_payload,
    						      TX_PAYLOAD_LENGTH);
    	if (!result_value) {
    		LOG_ERR("TX fifo error");
    	}
    	result_value = dk_set_leds_state(DK_ALL_LEDS_MSK, 0);
    	if (result_value) {
    		LOG_ERR("Cannot output LEDs (err: %d)", result_value);
    	}
    }
    
    K_TIMER_DEFINE(tmr, data_send_cb, NULL);
    
    static void gzll_tx_result_handler(struct gzll_tx_result *tx_result)
    {
    	int err;
    	bool result_value;
    	/* Placeholder for received ACK payloads from Host. */
    	uint8_t ack_payload[NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH];
    	uint32_t ack_payload_length = NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH;
    
    	err = date_time_now(&end_time);
    	if (tx_result->success) {
    		if (tx_result->info.payload_received_in_ack) {
    			// end_time = k_uptime_get();
    			/* Pop packet and write first byte of the payload to the GPIO port. */
    			result_value = nrf_gzll_fetch_packet_from_rx_fifo(tx_result->pipe,
    									  ack_payload,
    									  &ack_payload_length);
    			if (!result_value) {
    				LOG_ERR("RX fifo error");
    			} else if (ack_payload_length > 0) {
    				err = dk_set_leds_state(0, DK_ALL_LEDS_MSK);
    				if (err) {
    					LOG_ERR("Cannot output LEDs (err: %d)", err);
    				}
    				LOG_INF("ACK payload %llu end time %llu", *(uint64_t *)ack_payload, end_time);
    				LOG_INF("Time diff %lld", (end_time - *(uint64_t *)ack_payload));
    			}
    		}
    	} else {
    		LOG_ERR("Gazell transmission failed");
    	}
    
    	k_timer_start(&tmr, K_MSEC(100), K_NO_WAIT);
    }
    

    And the console is showing this:

    I: Entering data payload 4848
    I: Entering data payload 4953
    I: ACK payload 4848 end time 4961
    I: Time diff 113
    I: Entering data payload 5066
    I: ACK payload 4953 end time 5075
    I: Time diff 122
    

    You can tell that the current ACK is for a 1 message old and I'm supposed to have 1 message in flight at all time. Between the first two data payload messages comes an empty ACK which my host never sent.

    Here's the host code for reference:

    /*
     * Copyright (c) 2021 Nordic Semiconductor ASA
     *
     * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
     */
    
    #include <zephyr/kernel.h>
    #include <nrf_gzll.h>
    #include <gzll_glue.h>
    #include <dk_buttons_and_leds.h>
    
    #include <zephyr/logging/log.h>
    
    LOG_MODULE_REGISTER(app);
    
    /* Pipe 0 is used in this example. */
    #define PIPE_NUMBER 0
    
    /* 1-byte payload length is used when transmitting. */
    #define TX_PAYLOAD_LENGTH 8
    
    /* Gazell Link Layer RX result structure */
    struct gzll_rx_result {
    	uint32_t pipe;
    	nrf_gzll_host_rx_info_t info;
    };
    
    /* Placeholder for data payload received from host. */
    static uint8_t data_payload[NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH];
    
    /* Payload to attach to ACK sent to device. */
    // static uint8_t ack_payload[TX_PAYLOAD_LENGTH];
    
    #ifdef CONFIG_GZLL_TX_STATISTICS
    /* Struct containing transmission statistics. */
    static nrf_gzll_tx_statistics_t statistics;
    static nrf_gzll_tx_statistics_t statistics_2;
    #endif
    
    /* Gazell Link Layer RX result message queue */
    K_MSGQ_DEFINE(gzll_msgq,
    	      sizeof(struct gzll_rx_result),
    	      1,
    	      sizeof(uint32_t));
    
    /* Main loop semaphore */
    static K_SEM_DEFINE(main_sem, 0, 1);
    
    static struct k_work gzll_work;
    
    static void gzll_rx_result_handler(struct gzll_rx_result *rx_result);
    static void gzll_work_handler(struct k_work *work);
    
    int main(void)
    {
    	int err;
    	bool result_value;
    
    	k_work_init(&gzll_work, gzll_work_handler);
    
    	err = dk_leds_init();
    	if (err) {
    		LOG_ERR("Cannot initialize LEDs (err: %d)", err);
    		return 0;
    	}
    
    	err = dk_buttons_init(NULL);
    	if (err) {
    		LOG_ERR("Cannot initialize buttons (err: %d)", err);
    		return 0;
    	}
    
    	/* Initialize Gazell Link Layer glue */
    	result_value = gzll_glue_init();
    	if (!result_value) {
    		LOG_ERR("Cannot initialize GZLL glue code");
    		return 0;
    	}
    
    	/* Initialize the Gazell Link Layer */
    	result_value = nrf_gzll_init(NRF_GZLL_MODE_HOST);
    	if (!result_value) {
    		LOG_ERR("Cannot initialize GZLL");
    		return 0;
    	}
    
    #ifdef CONFIG_GZLL_TX_STATISTICS
    	/* Turn on transmission statistics gathering. */
    	result_value = nrf_gzll_tx_statistics_enable(&statistics);
    	if (!result_value) {
    		LOG_ERR("Cannot enable GZLL TX statistics");
    		return 0;
    	}
    #endif
    
    	// ack_payload[0] = ~dk_get_buttons();
    	// result_value = nrf_gzll_add_packet_to_tx_fifo(PIPE_NUMBER, ack_payload, TX_PAYLOAD_LENGTH);
    	// if (!result_value) {
    	// 	LOG_ERR("Cannot add packet to GZLL TX FIFO");
    	// 	return 0;
    	// }
    
    	result_value = nrf_gzll_enable();
    	if (!result_value) {
    		LOG_ERR("Cannot enable GZLL");
    		return 0;
    	}
    
    	LOG_INF("Gzll ack payload host example started.");
    
    	while (true) {
    		if (k_sem_take(&main_sem, K_FOREVER)) {
    			continue;
    		}
    
    #ifdef CONFIG_GZLL_TX_STATISTICS
    		if (statistics.packets_num >= 1000) {
    			uint32_t key = irq_lock();
    
    			statistics_2 = statistics;
    
    			/* Reset statistics buffers. */
    			nrf_gzll_reset_tx_statistics();
    
    			irq_unlock(key);
    
    			/* Print all transmission statistics. */
    			LOG_INF("");
    			LOG_INF("Total received packets:   %4u", statistics_2.packets_num);
    			LOG_INF("Total CRC failures:       %03u", statistics_2.timeouts_num);
    			LOG_INF("");
    
    			for (uint8_t i = 0; i < nrf_gzll_get_channel_table_size(); i++) {
    				LOG_INF("Channel %u: %03u packets received, %03u CRC failures.",
    					i,
    					statistics_2.channel_packets[i],
    					statistics_2.channel_timeouts[i]);
    			}
    		}
    #endif
    	}
    }
    
    void nrf_gzll_device_tx_success(uint32_t pipe, nrf_gzll_device_tx_info_t tx_info)
    {
    }
    
    void nrf_gzll_device_tx_failed(uint32_t pipe, nrf_gzll_device_tx_info_t tx_info)
    {
    }
    
    void nrf_gzll_disabled(void)
    {
    }
    
    void nrf_gzll_host_rx_data_ready(uint32_t pipe, nrf_gzll_host_rx_info_t rx_info)
    {
    	int err;
    	struct gzll_rx_result rx_result;
    
    	err = dk_set_leds_state(DK_ALL_LEDS_MSK, 0);
    	if (err) {
    		LOG_ERR("Cannot output LEDs (err: %d)", err);
    	}
    	rx_result.pipe = pipe;
    	rx_result.info = rx_info;
    	err = k_msgq_put(&gzll_msgq, &rx_result, K_NO_WAIT);
    	if (!err) {
    		/* Get work handler to run */
    		k_work_submit(&gzll_work);
    	} else {
    		LOG_ERR("Cannot put RX result to message queue");
    	}
    }
    
    static void gzll_work_handler(struct k_work *work)
    {
    	struct gzll_rx_result rx_result;
    
    	/* Process message queue */
    	while (!k_msgq_get(&gzll_msgq, &rx_result, K_NO_WAIT)) {
    		gzll_rx_result_handler(&rx_result);
    	}
    
    	/* Get main loop to run */
    	k_sem_give(&main_sem);
    }
    
    static void gzll_rx_result_handler(struct gzll_rx_result *rx_result)
    {
    	int err;
    	uint32_t data_payload_length = NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH;
    
    	/* Pop packet and write first byte of the payload to the GPIO port. */
    	bool result_value = nrf_gzll_fetch_packet_from_rx_fifo(rx_result->pipe,
    							       data_payload,
    							       &data_payload_length);
    	if (!result_value) {
    		LOG_ERR("RX fifo error");
    	} else if (data_payload_length > 0) {
    		// err = dk_set_leds(data_payload[0] & DK_ALL_LEDS_MSK);
    		// if (err) {
    		// 	LOG_ERR("Cannot output LEDs (err: %d)", err);
    		// }
    		// LOG_INF("Got payload %llu", *(uint64_t *)data_payload);
    	}
    
    	/* Read buttons and load ACK payload into TX queue. */
    	// ack_payload[0] = ~dk_get_buttons(); /* Button logic is inverted. */
    	// memcpy(ack_payload, data_payload, sizeof(uint64_t));
    
    	err = dk_set_leds_state(0, DK_ALL_LEDS_MSK);
    	if (err) {
    		LOG_ERR("Cannot output LEDs (err: %d)", err);
    	}
    	LOG_INF("data_payload %lld", *(uint64_t *)data_payload);
    	result_value = nrf_gzll_add_packet_to_tx_fifo(rx_result->pipe,
    						      data_payload,
    						      TX_PAYLOAD_LENGTH);
    	if (!result_value) {
    		LOG_ERR("TX fifo error");
    	}
    }
    

    Thanks,

    Guy

Reply
  • I figured out that the reason for the clock deviation is because I'm getting and ACK for the packet previous to last one.

    My flow is basically taking the sample app of sending a timestamp on every ACK and when receiving and ACK measuring the now - timestamp in the payload.

    The host side just pushes the payload back into the ACK.

    My question is why am I getting these buffered ACKs?

    Here's my device code:

    /*
     * Copyright (c) 2021 Nordic Semiconductor ASA
     *
     * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
     */
    
    #include <zephyr/kernel.h>
    #include <date_time.h>
    #include <nrf_gzll.h>
    #include <gzll_glue.h>
    #include <dk_buttons_and_leds.h>
    
    #include <zephyr/logging/log.h>
    
    LOG_MODULE_REGISTER(app);
    
    /* Pipe 0 is used in this example. */
    #define PIPE_NUMBER 0
    
    /* 1-byte payload length is used when transmitting. */
    #define TX_PAYLOAD_LENGTH 8
    
    /* Maximum number of transmission attempts */
    #define MAX_TX_ATTEMPTS 100
    
    /* Gazell Link Layer TX result structure */
    struct gzll_tx_result {
    	bool success;
    	uint32_t pipe;
    	nrf_gzll_device_tx_info_t info;
    };
    
    #ifdef CONFIG_GZLL_TX_STATISTICS
    /* Struct containing transmission statistics. */
    static nrf_gzll_tx_statistics_t statistics;
    static nrf_gzll_tx_statistics_t statistics_2;
    #endif
    
    /* Gazell Link Layer TX result message queue */
    K_MSGQ_DEFINE(gzll_msgq,
    	      sizeof(struct gzll_tx_result),
    	      1,
    	      sizeof(uint32_t));
    
    /* Main loop semaphore */
    static K_SEM_DEFINE(main_sem, 0, 1);
    
    static struct k_work gzll_work;
    static uint64_t end_time;
    static 	nrf_gzll_device_tx_info_t dummy_tx_info;
    
    static void gzll_tx_result_handler(struct gzll_tx_result *tx_result);
    static void gzll_work_handler(struct k_work *work);
    static void gzll_device_report_tx(bool success, uint32_t pipe, nrf_gzll_device_tx_info_t *tx_info);
    
    int main(void)
    {
    	int err;
    	bool result_value;
    	struct tm now;
    	/* Payload to send to Host. */
    	// static uint8_t data_payload[TX_PAYLOAD_LENGTH];
    	
    	now.tm_sec = 0;
    	now.tm_min = 0;
    	now.tm_hour = 12;
    	now.tm_mday = 1;
    	now.tm_mon = 7;
    	now.tm_year = 124;
    	now.tm_wday = 2;
    
    	err = date_time_set(&now);
    
    	k_work_init(&gzll_work, gzll_work_handler);
    
    	// LOG_INF("Time divider %d", CONFIG_DATE_TIME_UPDATE_INTERVAL_SECONDS);
    
    	err = dk_leds_init();
    	if (err) {
    		LOG_ERR("Cannot initialize LEDs (err: %d)", err);
    		return 0;
    	}
    
    	err = dk_buttons_init(NULL);
    	if (err) {
    		LOG_ERR("Cannot initialize buttons (err: %d)", err);
    		return 0;
    	}
    
    	/* Initialize Gazell Link Layer glue */
    	result_value = gzll_glue_init();
    	if (!result_value) {
    		LOG_ERR("Cannot initialize GZLL glue code");
    		return 0;
    	}
    
    	/* Initialize the Gazell Link Layer */
    	result_value = nrf_gzll_init(NRF_GZLL_MODE_DEVICE);
    	if (!result_value) {
    		LOG_ERR("Cannot initialize GZLL");
    		return 0;
    	}
    
    	nrf_gzll_set_max_tx_attempts(MAX_TX_ATTEMPTS);
    
    #ifdef CONFIG_GZLL_TX_STATISTICS
    	/* Turn on transmission statistics gathering. */
    	result_value = nrf_gzll_tx_statistics_enable(&statistics);
    	if (!result_value) {
    		LOG_ERR("Cannot enable GZLL TX statistics");
    		return 0;
    	}
    #endif
    
    	// data_payload[0] = ~dk_get_buttons();
    
    	dummy_tx_info.payload_received_in_ack = false;
    	gzll_device_report_tx(true, PIPE_NUMBER,  &dummy_tx_info);
    	// err = date_time_now((uint64_t *)data_payload);
    	// // *(uint64_t *)data_payload = k_uptime_get();
    	// LOG_INF("Entering data payload %llu", *(uint64_t *)data_payload);
    	// result_value = nrf_gzll_add_packet_to_tx_fifo(PIPE_NUMBER, data_payload, TX_PAYLOAD_LENGTH);
    	// if (!result_value) {
    	// 	LOG_ERR("Cannot add packet to GZLL TX FIFO");
    	// 	return 0;
    	// }
    
    	result_value = nrf_gzll_enable();
    	if (!result_value) {
    		LOG_ERR("Cannot enable GZLL");
    		return 0;
    	}
    
    	LOG_INF("Gzll ack payload device example started.");
    
    	while (true) {
    		if (k_sem_take(&main_sem, K_FOREVER)) {
    			continue;
    		}
    
    #ifdef CONFIG_GZLL_TX_STATISTICS
    		if (statistics.packets_num >= 1000) {
    			uint32_t key = irq_lock();
    
    			statistics_2 = statistics;
    
    			/* Reset statistics buffers. */
    			nrf_gzll_reset_tx_statistics();
    
    			irq_unlock(key);
    
    			/* Print all transmission statistics. */
    			LOG_INF("");
    			LOG_INF("Total transmitted packets:   %4u",  statistics_2.packets_num);
    			LOG_INF("Total transmission time-outs: %03u", statistics_2.timeouts_num);
    			LOG_INF("");
    
    			for (uint8_t i = 0; i < nrf_gzll_get_channel_table_size(); i++) {
    				LOG_INF(
    				"Channel %u: %03u packets transmitted, %03u transmissions failed.",
    				i,
    				statistics_2.channel_packets[i],
    				statistics_2.channel_timeouts[i]);
    			}
    		}
    #endif
    	}
    }
    
    static void gzll_device_report_tx(bool success,
    				  uint32_t pipe,
    				  nrf_gzll_device_tx_info_t *tx_info)
    {
    	int err;
    	struct gzll_tx_result tx_result;
    
    	tx_result.success = success;
    	tx_result.pipe = pipe;
    	tx_result.info = *tx_info;
    	err = k_msgq_put(&gzll_msgq, &tx_result, K_NO_WAIT);
    	if (!err) {
    		/* Get work handler to run */
    		k_work_submit(&gzll_work);
    	} else {
    		LOG_ERR("Cannot put TX result to message queue");
    	}
    }
    
    void nrf_gzll_device_tx_success(uint32_t pipe, nrf_gzll_device_tx_info_t tx_info)
    {
    	// LOG_INF("Tx success payload %s in ACK", tx_info.payload_received_in_ack?"received":"not received");
    	gzll_device_report_tx(true, pipe, &tx_info);
    }
    
    void nrf_gzll_device_tx_failed(uint32_t pipe, nrf_gzll_device_tx_info_t tx_info)
    {
    	LOG_INF("Tx failed");
    	gzll_device_report_tx(false, pipe, &tx_info);
    }
    
    void nrf_gzll_disabled(void)
    {
    }
    
    void nrf_gzll_host_rx_data_ready(uint32_t pipe, nrf_gzll_host_rx_info_t rx_info)
    {
    }
    
    static void gzll_work_handler(struct k_work *work)
    {
    	struct gzll_tx_result tx_result;
    
    	/* Process message queue */
    	while (!k_msgq_get(&gzll_msgq, &tx_result, K_FOREVER)) {
    		gzll_tx_result_handler(&tx_result);
    	}
    
    	/* Get main loop to run */
    	k_sem_give(&main_sem);
    }
    
    void data_send_cb(struct k_timer *tmr)
    {
    	int result_value;
    	/* Payload to send to Host. */
    	static uint8_t data_payload[TX_PAYLOAD_LENGTH];
    
    	/* Load data payload into the TX queue. */
    	result_value = date_time_now((uint64_t *)data_payload);
    	LOG_INF("Entering data payload %llu", *(uint64_t *)data_payload);
    	result_value = nrf_gzll_add_packet_to_tx_fifo(PIPE_NUMBER,
    						      data_payload,
    						      TX_PAYLOAD_LENGTH);
    	if (!result_value) {
    		LOG_ERR("TX fifo error");
    	}
    	result_value = dk_set_leds_state(DK_ALL_LEDS_MSK, 0);
    	if (result_value) {
    		LOG_ERR("Cannot output LEDs (err: %d)", result_value);
    	}
    }
    
    K_TIMER_DEFINE(tmr, data_send_cb, NULL);
    
    static void gzll_tx_result_handler(struct gzll_tx_result *tx_result)
    {
    	int err;
    	bool result_value;
    	/* Placeholder for received ACK payloads from Host. */
    	uint8_t ack_payload[NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH];
    	uint32_t ack_payload_length = NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH;
    
    	err = date_time_now(&end_time);
    	if (tx_result->success) {
    		if (tx_result->info.payload_received_in_ack) {
    			// end_time = k_uptime_get();
    			/* Pop packet and write first byte of the payload to the GPIO port. */
    			result_value = nrf_gzll_fetch_packet_from_rx_fifo(tx_result->pipe,
    									  ack_payload,
    									  &ack_payload_length);
    			if (!result_value) {
    				LOG_ERR("RX fifo error");
    			} else if (ack_payload_length > 0) {
    				err = dk_set_leds_state(0, DK_ALL_LEDS_MSK);
    				if (err) {
    					LOG_ERR("Cannot output LEDs (err: %d)", err);
    				}
    				LOG_INF("ACK payload %llu end time %llu", *(uint64_t *)ack_payload, end_time);
    				LOG_INF("Time diff %lld", (end_time - *(uint64_t *)ack_payload));
    			}
    		}
    	} else {
    		LOG_ERR("Gazell transmission failed");
    	}
    
    	k_timer_start(&tmr, K_MSEC(100), K_NO_WAIT);
    }
    

    And the console is showing this:

    I: Entering data payload 4848
    I: Entering data payload 4953
    I: ACK payload 4848 end time 4961
    I: Time diff 113
    I: Entering data payload 5066
    I: ACK payload 4953 end time 5075
    I: Time diff 122
    

    You can tell that the current ACK is for a 1 message old and I'm supposed to have 1 message in flight at all time. Between the first two data payload messages comes an empty ACK which my host never sent.

    Here's the host code for reference:

    /*
     * Copyright (c) 2021 Nordic Semiconductor ASA
     *
     * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
     */
    
    #include <zephyr/kernel.h>
    #include <nrf_gzll.h>
    #include <gzll_glue.h>
    #include <dk_buttons_and_leds.h>
    
    #include <zephyr/logging/log.h>
    
    LOG_MODULE_REGISTER(app);
    
    /* Pipe 0 is used in this example. */
    #define PIPE_NUMBER 0
    
    /* 1-byte payload length is used when transmitting. */
    #define TX_PAYLOAD_LENGTH 8
    
    /* Gazell Link Layer RX result structure */
    struct gzll_rx_result {
    	uint32_t pipe;
    	nrf_gzll_host_rx_info_t info;
    };
    
    /* Placeholder for data payload received from host. */
    static uint8_t data_payload[NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH];
    
    /* Payload to attach to ACK sent to device. */
    // static uint8_t ack_payload[TX_PAYLOAD_LENGTH];
    
    #ifdef CONFIG_GZLL_TX_STATISTICS
    /* Struct containing transmission statistics. */
    static nrf_gzll_tx_statistics_t statistics;
    static nrf_gzll_tx_statistics_t statistics_2;
    #endif
    
    /* Gazell Link Layer RX result message queue */
    K_MSGQ_DEFINE(gzll_msgq,
    	      sizeof(struct gzll_rx_result),
    	      1,
    	      sizeof(uint32_t));
    
    /* Main loop semaphore */
    static K_SEM_DEFINE(main_sem, 0, 1);
    
    static struct k_work gzll_work;
    
    static void gzll_rx_result_handler(struct gzll_rx_result *rx_result);
    static void gzll_work_handler(struct k_work *work);
    
    int main(void)
    {
    	int err;
    	bool result_value;
    
    	k_work_init(&gzll_work, gzll_work_handler);
    
    	err = dk_leds_init();
    	if (err) {
    		LOG_ERR("Cannot initialize LEDs (err: %d)", err);
    		return 0;
    	}
    
    	err = dk_buttons_init(NULL);
    	if (err) {
    		LOG_ERR("Cannot initialize buttons (err: %d)", err);
    		return 0;
    	}
    
    	/* Initialize Gazell Link Layer glue */
    	result_value = gzll_glue_init();
    	if (!result_value) {
    		LOG_ERR("Cannot initialize GZLL glue code");
    		return 0;
    	}
    
    	/* Initialize the Gazell Link Layer */
    	result_value = nrf_gzll_init(NRF_GZLL_MODE_HOST);
    	if (!result_value) {
    		LOG_ERR("Cannot initialize GZLL");
    		return 0;
    	}
    
    #ifdef CONFIG_GZLL_TX_STATISTICS
    	/* Turn on transmission statistics gathering. */
    	result_value = nrf_gzll_tx_statistics_enable(&statistics);
    	if (!result_value) {
    		LOG_ERR("Cannot enable GZLL TX statistics");
    		return 0;
    	}
    #endif
    
    	// ack_payload[0] = ~dk_get_buttons();
    	// result_value = nrf_gzll_add_packet_to_tx_fifo(PIPE_NUMBER, ack_payload, TX_PAYLOAD_LENGTH);
    	// if (!result_value) {
    	// 	LOG_ERR("Cannot add packet to GZLL TX FIFO");
    	// 	return 0;
    	// }
    
    	result_value = nrf_gzll_enable();
    	if (!result_value) {
    		LOG_ERR("Cannot enable GZLL");
    		return 0;
    	}
    
    	LOG_INF("Gzll ack payload host example started.");
    
    	while (true) {
    		if (k_sem_take(&main_sem, K_FOREVER)) {
    			continue;
    		}
    
    #ifdef CONFIG_GZLL_TX_STATISTICS
    		if (statistics.packets_num >= 1000) {
    			uint32_t key = irq_lock();
    
    			statistics_2 = statistics;
    
    			/* Reset statistics buffers. */
    			nrf_gzll_reset_tx_statistics();
    
    			irq_unlock(key);
    
    			/* Print all transmission statistics. */
    			LOG_INF("");
    			LOG_INF("Total received packets:   %4u", statistics_2.packets_num);
    			LOG_INF("Total CRC failures:       %03u", statistics_2.timeouts_num);
    			LOG_INF("");
    
    			for (uint8_t i = 0; i < nrf_gzll_get_channel_table_size(); i++) {
    				LOG_INF("Channel %u: %03u packets received, %03u CRC failures.",
    					i,
    					statistics_2.channel_packets[i],
    					statistics_2.channel_timeouts[i]);
    			}
    		}
    #endif
    	}
    }
    
    void nrf_gzll_device_tx_success(uint32_t pipe, nrf_gzll_device_tx_info_t tx_info)
    {
    }
    
    void nrf_gzll_device_tx_failed(uint32_t pipe, nrf_gzll_device_tx_info_t tx_info)
    {
    }
    
    void nrf_gzll_disabled(void)
    {
    }
    
    void nrf_gzll_host_rx_data_ready(uint32_t pipe, nrf_gzll_host_rx_info_t rx_info)
    {
    	int err;
    	struct gzll_rx_result rx_result;
    
    	err = dk_set_leds_state(DK_ALL_LEDS_MSK, 0);
    	if (err) {
    		LOG_ERR("Cannot output LEDs (err: %d)", err);
    	}
    	rx_result.pipe = pipe;
    	rx_result.info = rx_info;
    	err = k_msgq_put(&gzll_msgq, &rx_result, K_NO_WAIT);
    	if (!err) {
    		/* Get work handler to run */
    		k_work_submit(&gzll_work);
    	} else {
    		LOG_ERR("Cannot put RX result to message queue");
    	}
    }
    
    static void gzll_work_handler(struct k_work *work)
    {
    	struct gzll_rx_result rx_result;
    
    	/* Process message queue */
    	while (!k_msgq_get(&gzll_msgq, &rx_result, K_NO_WAIT)) {
    		gzll_rx_result_handler(&rx_result);
    	}
    
    	/* Get main loop to run */
    	k_sem_give(&main_sem);
    }
    
    static void gzll_rx_result_handler(struct gzll_rx_result *rx_result)
    {
    	int err;
    	uint32_t data_payload_length = NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH;
    
    	/* Pop packet and write first byte of the payload to the GPIO port. */
    	bool result_value = nrf_gzll_fetch_packet_from_rx_fifo(rx_result->pipe,
    							       data_payload,
    							       &data_payload_length);
    	if (!result_value) {
    		LOG_ERR("RX fifo error");
    	} else if (data_payload_length > 0) {
    		// err = dk_set_leds(data_payload[0] & DK_ALL_LEDS_MSK);
    		// if (err) {
    		// 	LOG_ERR("Cannot output LEDs (err: %d)", err);
    		// }
    		// LOG_INF("Got payload %llu", *(uint64_t *)data_payload);
    	}
    
    	/* Read buttons and load ACK payload into TX queue. */
    	// ack_payload[0] = ~dk_get_buttons(); /* Button logic is inverted. */
    	// memcpy(ack_payload, data_payload, sizeof(uint64_t));
    
    	err = dk_set_leds_state(0, DK_ALL_LEDS_MSK);
    	if (err) {
    		LOG_ERR("Cannot output LEDs (err: %d)", err);
    	}
    	LOG_INF("data_payload %lld", *(uint64_t *)data_payload);
    	result_value = nrf_gzll_add_packet_to_tx_fifo(rx_result->pipe,
    						      data_payload,
    						      TX_PAYLOAD_LENGTH);
    	if (!result_value) {
    		LOG_ERR("TX fifo error");
    	}
    }
    

    Thanks,

    Guy

Children
No Data
Related