Morse Micro IoT SDK  2.9.7
wnm_sleep.c
Go to the documentation of this file.
1/*
2 * Copyright 2023 Morse Micro
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
27#include <string.h>
28#include "mmhal.h"
29#include "mmosal.h"
30#include "mmwlan.h"
31#include "mmping.h"
32#include "mmconfig.h"
33
34#include "mmipal.h"
35
36#include "mm_app_common.h"
37
38/* Default Application configurations. These are used if the required parameters cannot be found in
39 * the configstore*/
40#ifndef DEFAULT_PING_COUNT
42#define DEFAULT_PING_COUNT 10
43#endif
44#ifndef DEFAULT_PING_DATA_SIZE
46#define DEFAULT_PING_DATA_SIZE 56
47#endif
48#ifndef DEFAULT_PING_INTERVAL_MS
50#define DEFAULT_PING_INTERVAL_MS 1000
51#endif
52#ifndef DEFAULT_WNM_SLEEP_DURATION_MS
54#define DEFAULT_WNM_SLEEP_DURATION_MS 20000
55#endif
56#ifndef POST_PING_DELAY_MS
58#define POST_PING_DELAY_MS 10000
59#endif
60#ifndef UPDATE_INTERVAL_MS
63#define UPDATE_INTERVAL_MS (5000)
64#endif
65
73{
102};
103
109static void set_debug_state(enum debug_state state)
110{
112}
113
121static void execute_ping_request(int iteration)
122{
123 struct mmping_args args = MMPING_ARGS_DEFAULT;
124
126
127 /* Get the target IP */
129 enum mmipal_status status = mmipal_get_ip_config(&ip_config);
130 if (status == MMIPAL_SUCCESS)
131 {
132 memcpy(args.ping_target, ip_config.gateway_addr, sizeof(ip_config.gateway_addr));
133 }
134 else
135 {
136 printf("Failed to retrieve IP config\n");
137 }
138 /* If ping.target is set, we use it as an override */
139 (void)mmconfig_read_string("ping.target", args.ping_target, sizeof(args.ping_target));
140
141 status = mmipal_get_local_addr(args.ping_src, args.ping_target);
142 if (status != MMIPAL_SUCCESS)
143 {
144 printf("failed to get local address for PING\n");
145 }
146
148 mmconfig_read_uint32("ping.count", &args.ping_count);
149
151 mmconfig_read_uint32("ping.target", &args.ping_size);
152
154 mmconfig_read_uint32("ping.interval", &args.ping_interval_ms);
155
156 mmping_start(&args);
157 printf("\nPing %s %lu(%lu) bytes of data.\n", args.ping_target, args.ping_size,
159
160 struct mmping_stats stats;
161 uint32_t next_update_time_ms = mmosal_get_time_ms() + UPDATE_INTERVAL_MS;
162 unsigned last_ping_recv_count = 0;
163 mmping_stats(&stats);
164 while (stats.ping_is_running)
165 {
167 mmping_stats(&stats);
168 if (stats.ping_recv_count != last_ping_recv_count ||
169 mmosal_time_has_passed(next_update_time_ms))
170 {
171 printf("(%s) packets transmitted/received = %lu/%lu, "
172 "round-trip min/avg/max = %lu/%lu/%lu ms\n",
175 last_ping_recv_count = stats.ping_recv_count;
176 next_update_time_ms = mmosal_get_time_ms() + UPDATE_INTERVAL_MS;
177 }
178 }
179 uint32_t loss = 0;
180 if (stats.ping_total_count == 0)
181 {
182 loss = 0;
183 }
184 else
185 {
186 loss = (1000 * (stats.ping_total_count - stats.ping_recv_count) * 100 /
187 stats.ping_total_count);
188 }
189
191
192 printf("\n--- %s ping statistics ---\n%lu packets transmitted, %lu packets received, ",
194 printf("%lu.%03lu%% packet loss\nround-trip min/avg/max = %lu/%lu/%lu ms\n",
195 loss/1000, loss%1000, stats.ping_min_time_ms, stats.ping_avg_time_ms,
196 stats.ping_max_time_ms);
197}
198
204static void execute_wnm_sleep(uint32_t wnm_sleep_duration_ms)
205{
206 enum mmwlan_status status = MMWLAN_ERROR;
207
208 printf("\nEntering WNM sleep with chip power down disabled\n");
209 printf("Expected sleep time %lums.\n", wnm_sleep_duration_ms);
210 /* Delay to allow printf's to settle so we measure only idle current */
212
214
215 uint32_t timestamp = mmosal_get_time_ms();
216 status = mmwlan_set_wnm_sleep_enabled(true);
217 uint32_t wnm_sleep_enable_duration_ms = mmosal_get_time_ms() - timestamp;
218 if (status != MMWLAN_SUCCESS)
219 {
220 printf("Failed to enable WNM sleep\n");
221 return;
222 }
223
224 mmosal_task_sleep(wnm_sleep_duration_ms);
225
226 timestamp = mmosal_get_time_ms();
227
229 status = mmwlan_set_wnm_sleep_enabled(false);
231
232 if (status == MMWLAN_SUCCESS)
233 {
234 printf("\nEnter WNM sleep took %lu ms.\n", wnm_sleep_enable_duration_ms);
235 printf("\nExit WNM sleep took %lu ms.\n", (mmosal_get_time_ms() - timestamp));
236 }
237 else
238 {
239 printf("Failed to disable WNM sleep\n");
240 }
241}
242
250static void execute_wnm_sleep_ext(uint32_t wnm_sleep_duration_ms)
251{
252 enum mmwlan_status status = MMWLAN_ERROR;
253 struct mmwlan_set_wnm_sleep_enabled_args wnm_sleep_args =
255
256 printf("\nEntering WNM sleep with chip power down enabled.\n");
257 printf("Expected sleep time %lums.\n", wnm_sleep_duration_ms);
258 /* Delay to allow printf's to settle so we measure only idle current */
260
262
263 uint32_t timestamp = mmosal_get_time_ms();
264 wnm_sleep_args.wnm_sleep_enabled = true;
265 wnm_sleep_args.chip_powerdown_enabled = true;
266 status = mmwlan_set_wnm_sleep_enabled_ext(&wnm_sleep_args);
267 uint32_t wnm_sleep_enable_duration_ms = mmosal_get_time_ms() - timestamp;
268 if (status != MMWLAN_SUCCESS)
269 {
270 printf("Failed to enable WNM sleep\n");
271 return;
272 }
273
274 mmosal_task_sleep(wnm_sleep_duration_ms);
275
276 timestamp = mmosal_get_time_ms();
277 wnm_sleep_args.wnm_sleep_enabled = false;
278
280 status = mmwlan_set_wnm_sleep_enabled_ext(&wnm_sleep_args);
282
283 if (status == MMWLAN_SUCCESS)
284 {
285 printf("\nEnter WNM sleep took %lu ms.\n", wnm_sleep_enable_duration_ms);
286 printf("\nExit WNM sleep took %lu ms.\n", (mmosal_get_time_ms() - timestamp));
287 }
288 else
289 {
290 printf("Failed to disable WNM sleep\n");
291 }
292}
293
298void app_init(void)
299{
300 printf("\n\nMorse WNM Sleep Demo (Built " __DATE__ " " __TIME__ ")\n\n");
301
302 /* Initialize and connect to Wi-Fi, blocks till connected */
304
306
308
310
311 /* Delay to allow communications to settle so we measure only idle current */
313
314 uint32_t wnm_sleep_duration_ms = DEFAULT_WNM_SLEEP_DURATION_MS;
315 mmconfig_read_uint32("wlan.wnm_sleep_duration_ms", &wnm_sleep_duration_ms);
316
318
319 /* The following demonstrates basic WNM Sleep functionality. The MM chip remains powered,
320 * but does not wake up to receive beacons. */
321 execute_wnm_sleep(wnm_sleep_duration_ms);
322
324
325 /* The following demonstrates extended WNM Sleep API that allows the chip to be shutdown
326 * while in WNM Sleep. */
327 execute_wnm_sleep_ext(wnm_sleep_duration_ms);
328
329 /* Delay to allow communications to settle so we measure only idle current */
331
333
334 /* Disconnect from Wi-Fi */
336}
int mmconfig_read_string(const char *key, char *buffer, int bufsize)
Returns the persistent store string value identified by the key.
int mmconfig_read_uint32(const char *key, uint32_t *value)
Returns the unsigned integer stored in persistent store identified by the key.
#define MMHAL_ALL_DEBUG_PINS
Bit mask with all debug pins selected.
Definition: mmhal.h:217
void mmhal_set_debug_pins(uint32_t mask, uint32_t values)
Set the value one or more debug pins.
#define MMIPAL_IP_CONFIG_DEFAULT
Initializer for mmipal_ip_config.
Definition: mmipal.h:100
mmipal_status
Enumeration of status codes returned by MMIPAL functions.
Definition: mmipal.h:37
enum mmipal_status mmipal_get_ip_config(struct mmipal_ip_config *config)
Get the IP configurations.
enum mmipal_status mmipal_get_local_addr(mmipal_ip_addr_t local_addr, const mmipal_ip_addr_t dest_addr)
Gets the local address for the MMWLAN interface that is appropriate for a given destination address.
@ MMIPAL_SUCCESS
Completed successfully.
Definition: mmipal.h:39
void mmosal_task_sleep(uint32_t duration_ms)
Sleep for a period of time, yielding during that time.
uint32_t mmosal_get_time_ms(void)
Get the system time in milliseconds.
static bool mmosal_time_has_passed(uint32_t t)
Check if the given time has already passed.
Definition: mmosal.h:725
#define MMPING_ICMP_ECHO_HDR_LEN
Length of the ICMP echo header in octets.
Definition: mmping.h:64
uint16_t mmping_start(const struct mmping_args *args)
Initialize ping parameters and start ping.
#define MMPING_ARGS_DEFAULT
Initializer for mmping_args.
Definition: mmping.h:95
void mmping_stats(struct mmping_stats *stats)
Get Ping Statistics.
static enum mmwlan_status mmwlan_set_wnm_sleep_enabled(bool wnm_sleep_enabled)
Sets whether WNM sleep mode is enabled.
Definition: mmwlan.h:2118
#define MMWLAN_SET_WNM_SLEEP_ENABLED_ARGS_INIT
Initializer for mmwlan_set_wnm_sleep_enabled_args.
Definition: mmwlan.h:2062
enum mmwlan_status mmwlan_set_wnm_sleep_enabled_ext(const struct mmwlan_set_wnm_sleep_enabled_args *args)
Sets extended WNM sleep mode.
mmwlan_status
Enumeration of status return codes.
Definition: mmwlan.h:50
@ MMWLAN_SUCCESS
The operation was successful.
Definition: mmwlan.h:52
@ MMWLAN_ERROR
The operation failed with an unspecified error.
Definition: mmwlan.h:54
Morse Micro application helper routines for initializing/de-initializing the Wireless LAN interface a...
void app_wlan_stop(void)
Disconnects from Wi-Fi and de-initializes the WLAN interface.
void app_wlan_init(void)
Initializes the WLAN interface (and dependencies) using settings specified in the config store.
void app_wlan_start(void)
Starts the WLAN interface and connects to Wi-Fi using settings specified in the config store.
debug_state
Enumeration of debug states that will be reflected on debug pins.
Definition: ping.c:62
IPv4 configuration structure.
Definition: mmipal.h:88
mmipal_ip_addr_t gateway_addr
Gateway address.
Definition: mmipal.h:96
Ping request arguments data structure.
Definition: mmping.h:77
uint32_t ping_size
Specifies the data packet size in bytes excluding 8 bytes ICMP header.
Definition: mmping.h:91
char ping_src[MMPING_IPADDR_MAXLEN]
String representation of the local IP address.
Definition: mmping.h:79
char ping_target[MMPING_IPADDR_MAXLEN]
String representation of the IP address of the ping target.
Definition: mmping.h:81
uint32_t ping_interval_ms
The time interval between ping requests (in milliseconds)
Definition: mmping.h:83
uint32_t ping_count
This specifies the number of ping requests to send before terminating the session.
Definition: mmping.h:89
Data structure to store ping results.
Definition: mmping.h:105
uint32_t ping_avg_time_ms
The average latency in ms between request sent and response received.
Definition: mmping.h:115
bool ping_is_running
Stores the ping running status.
Definition: mmping.h:119
uint32_t ping_min_time_ms
The minimum latency in ms between request sent and response received.
Definition: mmping.h:113
uint32_t ping_max_time_ms
The maximum latency in ms between request sent and response received.
Definition: mmping.h:117
char ping_receiver[MMPING_IPADDR_MAXLEN]
String representation of the IP address of the ping receiver.
Definition: mmping.h:107
uint32_t ping_recv_count
The number of ping responses received.
Definition: mmping.h:111
uint32_t ping_total_count
Total number of requests sent.
Definition: mmping.h:109
Structure for storing WNM sleep extended arguments.
Definition: mmwlan.h:2046
bool wnm_sleep_enabled
Boolean indicating whether WNM sleep is enabled.
Definition: mmwlan.h:2048
bool chip_powerdown_enabled
Boolean indicating whether chip should be powered down during WNM sleep.
Definition: mmwlan.h:2050
static void execute_wnm_sleep(uint32_t wnm_sleep_duration_ms)
Function to execute WNM sleep.
Definition: wnm_sleep.c:204
#define DEFAULT_PING_DATA_SIZE
Size of the ping request data, excluding 8-byte ICMP header.
Definition: wnm_sleep.c:46
static void set_debug_state(enum debug_state state)
Perform necessary operation (i.e., setting GPIO pins) upon entering the given debug state.
Definition: wnm_sleep.c:109
#define DEFAULT_PING_INTERVAL_MS
Interval between successive ping requests.
Definition: wnm_sleep.c:50
#define DEFAULT_WNM_SLEEP_DURATION_MS
Duration to remain in wnm sleep between transmissions.
Definition: wnm_sleep.c:54
static void execute_ping_request(int iteration)
Function to execute ping request.
Definition: wnm_sleep.c:121
#define UPDATE_INTERVAL_MS
Interval (in milliseconds) at which to provide updates when the receive count has not changed.
Definition: wnm_sleep.c:63
void app_init(void)
Main entry point to the application.
Definition: wnm_sleep.c:298
static void execute_wnm_sleep_ext(uint32_t wnm_sleep_duration_ms)
Function to enter WNM Sleep and power off the MM chip while asleep.
Definition: wnm_sleep.c:250
@ DEBUG_STATE_INIT
Initial state at startup.
Definition: wnm_sleep.c:75
@ DEBUG_STATE_WNM_SLEEP_POWER_DOWN
Indicates that WNM sleep is in progress with chip powered down.
Definition: wnm_sleep.c:95
@ DEBUG_STATE_PINGING_0
Indicates that the ping is in progress.
Definition: wnm_sleep.c:81
@ DEBUG_STATE_WNM_SLEEP_DONE
Indicates that WNM sleep has completed.
Definition: wnm_sleep.c:89
@ DEBUG_STATE_PING_0_DONE
Indicates that the ping has completed.
Definition: wnm_sleep.c:83
@ DEBUG_STATE_CONNECTED
Indicates we are connected to the AP.
Definition: wnm_sleep.c:79
@ DEBUG_STATE_PING_1_DONE
Indicates that the ping has completed.
Definition: wnm_sleep.c:93
@ DEBUG_STATE_EXITING_WNM_SLEEP_POWER_DOWN
Indicates that we are exiting WNM sleep with chip powered down.
Definition: wnm_sleep.c:97
@ DEBUG_STATE_WNM_SLEEP
Indicates that WNM sleep is in progress.
Definition: wnm_sleep.c:85
@ DEBUG_STATE_PINGING_1
Indicates that the ping is in progress.
Definition: wnm_sleep.c:91
@ DEBUG_STATE_WNM_SLEEP_POWER_DOWN_DONE
Indicates that WNM sleep with chip powered down has completed.
Definition: wnm_sleep.c:99
@ DEBUG_STATE_EXITING_WNM_SLEEP
Indicates that we are exiting WNM sleep.
Definition: wnm_sleep.c:87
@ DEBUG_STATE_TERMINATING
Indicates that we are disconnecting from the AP.
Definition: wnm_sleep.c:101
@ DEBUG_STATE_CONNECTING
Indicates we are connecting to the AP.
Definition: wnm_sleep.c:77
#define DEFAULT_PING_COUNT
Number of ping requests to send.
Definition: wnm_sleep.c:42