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 );
0 commit comments