Skip to content

Commit 379f687

Browse files
applications: 93m1_at: General cleanup of the 93m1_at application
General cleanup and refactoring of the 93m1_at application. Signed-off-by: Syver Haraldsen <syver.haraldsen@nordicsemi.no>
1 parent d6dc070 commit 379f687

10 files changed

Lines changed: 391 additions & 235 deletions

File tree

applications/93m1_at/src/main.c

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -58,28 +58,43 @@ struct app_object {
5858
uint8_t msg_buf[MAX_MSG_SIZE];
5959
};
6060

61-
static struct app_object app;
62-
static const struct smf_state states[];
61+
static void sync_timer_fn(struct k_work *work);
62+
static K_WORK_DELAYABLE_DEFINE(sync_timer, sync_timer_fn);
63+
64+
static void request_module_updates(void);
65+
static enum smf_state_result disconnected_run(void *obj);
66+
static void connected_entry(void *obj);
67+
static enum smf_state_result connected_run(void *obj);
68+
static void connected_exit(void *obj);
69+
static void wdt_callback(int channel_id, void *user_data);
70+
71+
static const struct smf_state states[] = {
72+
[STATE_DISCONNECTED] = SMF_CREATE_STATE(NULL, disconnected_run, NULL, NULL, NULL),
73+
[STATE_CONNECTED] = SMF_CREATE_STATE(connected_entry, connected_run, connected_exit,
74+
NULL, NULL),
75+
};
6376

64-
/* Periodic sync trigger: publishes MAIN_SYNC; the state machine drives it. */
6577
static void sync_timer_fn(struct k_work *work)
6678
{
6779
ARG_UNUSED(work);
80+
6881
struct main_msg msg = { .type = MAIN_SYNC };
6982

7083
(void)zbus_chan_pub(&main_chan, &msg, PUB_TIMEOUT);
7184
}
7285

73-
static K_WORK_DELAYABLE_DEFINE(sync_timer, sync_timer_fn);
74-
75-
static void run_sync(void)
86+
static void request_module_updates(void)
7687
{
77-
LOG_INF("Sync");
88+
LOG_DBG("Requesting module updates");
7889
#if defined(CONFIG_APP_LOCATION)
79-
location_update();
90+
struct location_msg loc_msg = { .type = LOCATION_FIX_REQUEST };
91+
92+
(void)zbus_chan_pub(&location_chan, &loc_msg, PUB_TIMEOUT);
8093
#endif
8194
#if defined(CONFIG_APP_BATTERY)
82-
(void)battery_report();
95+
struct battery_msg bat_msg = { .type = BATTERY_SAMPLE };
96+
97+
(void)zbus_chan_pub(&battery_chan, &bat_msg, PUB_TIMEOUT);
8398
#endif
8499
}
85100

@@ -103,7 +118,6 @@ static void connected_entry(void *obj)
103118
ARG_UNUSED(obj);
104119
LOG_INF("Connected");
105120

106-
/* First sync shortly after connecting. */
107121
(void)k_work_reschedule(&sync_timer, K_SECONDS(CONFIG_APP_SYNC_BOOT_DELAY_SECONDS));
108122
}
109123

@@ -121,8 +135,9 @@ static enum smf_state_result connected_run(void *obj)
121135
const struct main_msg *msg = (const struct main_msg *)state->msg_buf;
122136

123137
if (msg->type == MAIN_SYNC) {
124-
run_sync();
125-
(void)k_work_reschedule(&sync_timer, K_SECONDS(CONFIG_APP_SYNC_INTERVAL));
138+
request_module_updates();
139+
(void)k_work_reschedule(&sync_timer,
140+
K_SECONDS(CONFIG_APP_SYNC_INTERVAL));
126141
}
127142
}
128143

@@ -135,12 +150,6 @@ static void connected_exit(void *obj)
135150
(void)k_work_cancel_delayable(&sync_timer);
136151
}
137152

138-
static const struct smf_state states[] = {
139-
[STATE_DISCONNECTED] = SMF_CREATE_STATE(NULL, disconnected_run, NULL, NULL, NULL),
140-
[STATE_CONNECTED] = SMF_CREATE_STATE(connected_entry, connected_run, connected_exit,
141-
NULL, NULL),
142-
};
143-
144153
static void wdt_callback(int channel_id, void *user_data)
145154
{
146155
LOG_ERR("Main watchdog expired, channel: %d, thread: %s",
@@ -158,6 +167,7 @@ int main(void)
158167
const uint32_t execution_time_ms =
159168
(CONFIG_APP_MAIN_MSG_PROCESSING_TIMEOUT_SECONDS * MSEC_PER_SEC);
160169
const k_timeout_t zbus_wait = K_MSEC(wdt_timeout_ms - execution_time_ms);
170+
static struct app_object app;
161171

162172
task_wdt_id = task_wdt_add(wdt_timeout_ms, wdt_callback, (void *)k_current_get());
163173
if (task_wdt_id < 0) {

applications/93m1_at/src/modules/battery/Kconfig.battery

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ menuconfig APP_BATTERY
1515

1616
if APP_BATTERY
1717

18+
config APP_BATTERY_THREAD_STACK_SIZE
19+
int "Battery thread stack size (bytes)"
20+
default 2048
21+
1822
config APP_BATTERY_AT_TIMEOUT_SECONDS
1923
int "AT%NRFCLOUDMESSAGE timeout (seconds)"
2024
default 60

applications/93m1_at/src/modules/battery/battery.c

Lines changed: 95 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,14 @@
77
#include <stdio.h>
88
#include <zephyr/kernel.h>
99
#include <zephyr/logging/log.h>
10+
#include <zephyr/zbus/zbus.h>
1011
#include <zephyr/drivers/sensor.h>
1112
#include <zephyr/drivers/sensor/npm13xx_charger.h>
1213
#include <nrf_fuel_gauge.h>
1314

15+
#include "app_common.h"
1416
#include "modules/modem_at/modem_at.h"
17+
#include "modules/network/network.h"
1518
#include "lp803448_model.h"
1619
#include "battery.h"
1720

@@ -23,14 +26,35 @@ LOG_MODULE_REGISTER(battery, CONFIG_APP_BATTERY_LOG_LEVEL);
2326
#define CHG_STATUS_CC_MASK BIT(3)
2427
#define CHG_STATUS_CV_MASK BIT(4)
2528

26-
static const struct device *const charger = DEVICE_DT_GET(DT_NODELABEL(npm1300_charger));
29+
ZBUS_CHAN_DEFINE(battery_chan,
30+
struct battery_msg,
31+
NULL,
32+
NULL,
33+
ZBUS_OBSERVERS_EMPTY,
34+
ZBUS_MSG_INIT(0));
2735

28-
static bool gauge_ready;
29-
static int64_t ref_time;
30-
static int32_t prev_chg_status = -1;
36+
ZBUS_MSG_SUBSCRIBER_DEFINE(battery);
3137

32-
static int read_sensors(float *voltage, float *current, float *temp, int32_t *chg_status,
33-
bool *vbus)
38+
#define CHANNEL_LIST(X) \
39+
X(network_chan, struct network_msg) \
40+
X(battery_chan, struct battery_msg)
41+
42+
#define MAX_MSG_SIZE MAX_MSG_SIZE_FROM_LIST(CHANNEL_LIST)
43+
44+
#define ADD_OBSERVERS(_chan, _type) ZBUS_CHAN_ADD_OBS(_chan, battery, 0);
45+
46+
CHANNEL_LIST(ADD_OBSERVERS)
47+
48+
static int read_sensors(const struct device *charger, float *voltage, float *current,
49+
float *temp, int32_t *chg_status, bool *vbus);
50+
static void update_charge_state(int32_t chg_status, int32_t *prev);
51+
static int fuel_gauge_setup(const struct device *charger);
52+
static void battery_sample_and_report(const struct device *charger, int64_t *ref_time,
53+
int32_t *prev_chg_status);
54+
static void battery_thread(void);
55+
56+
static int read_sensors(const struct device *charger, float *voltage, float *current,
57+
float *temp, int32_t *chg_status, bool *vbus)
3458
{
3559
int err;
3660
struct sensor_value val = {0};
@@ -59,31 +83,32 @@ static int read_sensors(float *voltage, float *current, float *temp, int32_t *ch
5983
/* Fuel gauge wants charge-positive; the sensor API is discharge-negative. */
6084
*current = -sensor_value_to_float(&val);
6185

62-
err = sensor_channel_get(charger, (enum sensor_channel)SENSOR_CHAN_NPM13XX_CHARGER_STATUS,
63-
&val);
86+
err = sensor_channel_get(charger,
87+
(enum sensor_channel)SENSOR_CHAN_NPM13XX_CHARGER_STATUS, &val);
6488
if (err) {
6589
return err;
6690
}
6791
*chg_status = val.val1;
6892

6993
struct sensor_value vbus_val;
7094

71-
err = sensor_attr_get(charger, (enum sensor_channel)SENSOR_CHAN_NPM13XX_CHARGER_VBUS_STATUS,
95+
err = sensor_attr_get(charger,
96+
(enum sensor_channel)SENSOR_CHAN_NPM13XX_CHARGER_VBUS_STATUS,
7297
(enum sensor_attribute)SENSOR_ATTR_NPM13XX_CHARGER_VBUS_PRESENT,
7398
&vbus_val);
7499
*vbus = (err == 0) && (vbus_val.val1 != 0);
75100

76101
return 0;
77102
}
78103

79-
static void update_charge_state(int32_t chg_status)
104+
static void update_charge_state(int32_t chg_status, int32_t *prev)
80105
{
81106
union nrf_fuel_gauge_ext_state_info_data ext;
82107

83-
if (chg_status == prev_chg_status) {
108+
if (chg_status == *prev) {
84109
return;
85110
}
86-
prev_chg_status = chg_status;
111+
*prev = chg_status;
87112

88113
if (chg_status & CHG_STATUS_COMPLETE_MASK) {
89114
ext.charge_state = NRF_FUEL_GAUGE_CHARGE_STATE_COMPLETE;
@@ -101,15 +126,15 @@ static void update_charge_state(int32_t chg_status)
101126
&ext);
102127
}
103128

104-
static int fuel_gauge_setup(void)
129+
static int fuel_gauge_setup(const struct device *charger)
105130
{
106131
int err;
107132
int32_t chg_status;
108133
bool vbus;
109134
struct nrf_fuel_gauge_init_parameters params = { .model = &battery_model };
110135
float soc;
111136

112-
err = read_sensors(&params.v0, &params.i0, &params.t0, &chg_status, &vbus);
137+
err = read_sensors(charger, &params.v0, &params.i0, &params.t0, &chg_status, &vbus);
113138
if (err) {
114139
return err;
115140
}
@@ -124,67 +149,87 @@ static int fuel_gauge_setup(void)
124149
return 0;
125150
}
126151

127-
/* Sample the gauge and return state of charge in percent, or -1 on error. */
128-
static int sample_soc(void)
152+
static void battery_sample_and_report(const struct device *charger, int64_t *ref_time,
153+
int32_t *prev_chg_status)
129154
{
130155
float voltage;
131156
float current;
132157
float temp;
133158
float soc;
134159
int32_t chg_status;
135160
bool vbus;
161+
char cmd[64];
162+
int err;
136163

137-
if (read_sensors(&voltage, &current, &temp, &chg_status, &vbus)) {
138-
return -1;
164+
err = read_sensors(charger, &voltage, &current, &temp, &chg_status, &vbus);
165+
if (err) {
166+
LOG_WRN("read_sensors, error: %d", err);
167+
return;
139168
}
140169

141170
(void)nrf_fuel_gauge_ext_state_update(
142171
vbus ? NRF_FUEL_GAUGE_EXT_STATE_INFO_VBUS_CONNECTED
143172
: NRF_FUEL_GAUGE_EXT_STATE_INFO_VBUS_DISCONNECTED, NULL);
144-
update_charge_state(chg_status);
173+
update_charge_state(chg_status, prev_chg_status);
145174

146-
float delta = (float)k_uptime_delta(&ref_time) / 1000.0f;
175+
float delta = (float)k_uptime_delta(ref_time) / 1000.0f;
147176

148-
if (nrf_fuel_gauge_process(voltage, current, temp, delta, &soc, NULL)) {
149-
return -1;
177+
err = nrf_fuel_gauge_process(voltage, current, temp, delta, &soc, NULL);
178+
if (err) {
179+
LOG_WRN("nrf_fuel_gauge_process, error: %d", err);
180+
return;
181+
}
182+
183+
(void)snprintf(cmd, sizeof(cmd),
184+
"AT%%NRFCLOUDMESSAGE={\"appId\":\"BATTERY\",\"data\":\"%d\"}", (int)soc);
185+
186+
err = modem_at_run(cmd, NULL, 0, CONFIG_APP_BATTERY_AT_TIMEOUT_SECONDS);
187+
if (err) {
188+
LOG_WRN("Battery cloud message failed: %d", err);
189+
return;
150190
}
151191

152-
return (int)soc;
192+
LOG_INF("Battery %d%% sent to nRF Cloud", (int)soc);
153193
}
154194

155-
int battery_report(void)
195+
static void battery_thread(void)
156196
{
157-
char cmd[64];
158-
int soc;
159197
int err;
160-
161-
if (!gauge_ready) {
162-
if (!device_is_ready(charger)) {
163-
LOG_ERR("Charger device not ready");
164-
return -ENODEV;
165-
}
166-
if (fuel_gauge_setup()) {
167-
LOG_ERR("Fuel gauge init failed");
168-
return -EIO;
169-
}
170-
ref_time = k_uptime_get();
171-
gauge_ready = true;
198+
const struct zbus_channel *chan;
199+
uint8_t msg_buf[MAX_MSG_SIZE];
200+
int64_t ref_time;
201+
int32_t prev_chg_status = -1;
202+
bool connected = false;
203+
const struct device *const charger = DEVICE_DT_GET(DT_NODELABEL(npm1300_charger));
204+
205+
if (!device_is_ready(charger)) {
206+
LOG_ERR("Charger device not ready");
207+
return;
172208
}
173209

174-
soc = sample_soc();
175-
if (soc < 0) {
176-
return -EIO;
210+
err = fuel_gauge_setup(charger);
211+
if (err) {
212+
LOG_ERR("fuel_gauge_setup, error: %d", err);
213+
return;
177214
}
215+
ref_time = k_uptime_get();
178216

179-
(void)snprintf(cmd, sizeof(cmd),
180-
"AT%%NRFCLOUDMESSAGE={\"appId\":\"BATTERY\",\"data\":\"%d\"}", soc);
217+
while (true) {
218+
err = zbus_sub_wait_msg(&battery, &chan, msg_buf, K_FOREVER);
219+
if (err) {
220+
LOG_ERR("zbus_sub_wait_msg, error: %d", err);
221+
return;
222+
}
181223

182-
err = modem_at_run(cmd, NULL, 0, CONFIG_APP_BATTERY_AT_TIMEOUT_SECONDS);
183-
if (err) {
184-
LOG_WRN("Battery cloud message failed: %d", err);
185-
return err;
186-
}
224+
if (chan == &network_chan) {
225+
const struct network_msg *msg = (const struct network_msg *)msg_buf;
187226

188-
LOG_INF("Battery %d%% sent to nRF Cloud", soc);
189-
return 0;
227+
connected = (msg->type == NETWORK_CONNECTED);
228+
} else if (chan == &battery_chan && connected) {
229+
battery_sample_and_report(charger, &ref_time, &prev_chg_status);
230+
}
231+
}
190232
}
233+
234+
K_THREAD_DEFINE(battery_tid, CONFIG_APP_BATTERY_THREAD_STACK_SIZE, battery_thread,
235+
NULL, NULL, NULL, K_LOWEST_APPLICATION_THREAD_PRIO, 0, 0);

applications/93m1_at/src/modules/battery/battery.h

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,21 @@
77
#ifndef BATTERY_H_
88
#define BATTERY_H_
99

10+
#include <zephyr/zbus/zbus.h>
11+
1012
#ifdef __cplusplus
1113
extern "C" {
1214
#endif
1315

14-
/**
15-
* @brief Sample the fuel gauge and report state of charge to nRF Cloud.
16-
*
17-
* Reads the nPM1300 fuel gauge and sends the state of charge as an
18-
* AT%NRFCLOUDMESSAGE (appId "BATTERY"). Called by the sync state machine.
19-
*
20-
* @retval 0 on success, negative errno otherwise.
21-
*/
22-
int battery_report(void);
16+
enum battery_msg_type {
17+
BATTERY_SAMPLE,
18+
};
19+
20+
struct battery_msg {
21+
enum battery_msg_type type;
22+
};
23+
24+
ZBUS_CHAN_DECLARE(battery_chan);
2325

2426
#ifdef __cplusplus
2527
}

applications/93m1_at/src/modules/cloud/cloud.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
LOG_MODULE_REGISTER(cloud, CONFIG_APP_CLOUD_LOG_LEVEL);
1515

16-
static int extract(const char *resp, const char *prefix, char *out, size_t out_size)
16+
static int parse_resp_field(const char *resp, const char *prefix, char *out, size_t out_size)
1717
{
1818
const char *p = strstr(resp, prefix);
1919

@@ -40,7 +40,7 @@ void cloud_provision(void)
4040
char uuid[40];
4141

4242
if (modem_at_run("AT%DEVICEUUID", resp, sizeof(resp), 10) == 0 &&
43-
extract(resp, "%DEVICEUUID: ", uuid, sizeof(uuid)) == 0) {
43+
parse_resp_field(resp, "%DEVICEUUID: ", uuid, sizeof(uuid)) == 0) {
4444
LOG_INF("Device UUID: %s", uuid);
4545
} else {
4646
LOG_ERR("Failed to read device UUID");

0 commit comments

Comments
 (0)