|
6 | 6 |
|
7 | 7 | #include <zephyr/kernel.h> |
8 | 8 | #include <zephyr/logging/log.h> |
| 9 | +#include <zephyr/device.h> |
| 10 | +#include <zephyr/devicetree.h> |
| 11 | +#include <zephyr/pm/device.h> |
9 | 12 | #include <zephyr/zbus/zbus.h> |
10 | 13 | #include <zephyr/drivers/sensor/npm1300_charger.h> |
11 | 14 | #include <zephyr/drivers/mfd/npm1300.h> |
@@ -57,6 +60,9 @@ BUILD_ASSERT(CONFIG_APP_POWER_WATCHDOG_TIMEOUT_SECONDS > |
57 | 60 | static const struct device *charger = DEVICE_DT_GET(DT_NODELABEL(npm1300_charger)); |
58 | 61 | static const struct device *pmic = DEVICE_DT_GET(DT_NODELABEL(pmic_main)); |
59 | 62 |
|
| 63 | +static const struct device *const uart0_dev = DEVICE_DT_GET(DT_NODELABEL(uart0)); |
| 64 | +static const struct device *const uart1_dev = DEVICE_DT_GET(DT_NODELABEL(uart1)); |
| 65 | + |
60 | 66 | /* Forward declarations */ |
61 | 67 | static int subscribe_to_vsbus_events(const struct device *pmic, struct gpio_callback *event_cb); |
62 | 68 | static int charger_read_sensors(float *voltage, float *current, float *temp, int32_t *chg_status); |
@@ -118,11 +124,13 @@ static void state_running_entry(void *o) |
118 | 124 | return; |
119 | 125 | } |
120 | 126 |
|
121 | | - err = subscribe_to_vsbus_events(pmic, &event_cb); |
122 | | - if (err) { |
123 | | - LOG_ERR("subscribe_to_vsbus_events, error: %d", err); |
124 | | - SEND_FATAL_ERROR(); |
125 | | - return; |
| 127 | + if (IS_ENABLED(CONFIG_APP_POWER_DISABLE_UART_ON_VBUS_REMOVED)) { |
| 128 | + err = subscribe_to_vsbus_events(pmic, &event_cb); |
| 129 | + if (err) { |
| 130 | + LOG_ERR("subscribe_to_vsbus_events, error: %d", err); |
| 131 | + SEND_FATAL_ERROR(); |
| 132 | + return; |
| 133 | + } |
126 | 134 | } |
127 | 135 |
|
128 | 136 | err = charger_read_sensors(¶meters.v0, ¶meters.i0, ¶meters.t0, &chg_status); |
@@ -165,17 +173,97 @@ static void state_running_run(void *o) |
165 | 173 |
|
166 | 174 | /* End of state handling */ |
167 | 175 |
|
| 176 | +static int uart_disable(void) |
| 177 | +{ |
| 178 | + int err; |
| 179 | + |
| 180 | + if (!device_is_ready(uart0_dev) || !device_is_ready(uart1_dev)) { |
| 181 | + LOG_ERR("UART devices are not ready"); |
| 182 | + return -ENODEV; |
| 183 | + } |
| 184 | + |
| 185 | +#ifdef CONFIG_NRF_MODEM_LIB_TRACE_BACKEND_UART |
| 186 | + err = nrf_modem_lib_trace_level_set(NRF_MODEM_LIB_TRACE_LEVEL_OFF); |
| 187 | + if (err) { |
| 188 | + LOG_ERR("nrf_modem_lib_trace_level_set, error: %d", err); |
| 189 | + return err; |
| 190 | + } |
| 191 | +#endif |
| 192 | + |
| 193 | + /* Wait for UART buffers to be emptied before suspending. |
| 194 | + * If a transfer is ongoing, the driver will cause an assertion to fail. |
| 195 | + * 100 ms is an arbitrary value that should be enough for the buffers to empty. |
| 196 | + */ |
| 197 | + k_busy_wait(100 * USEC_PER_MSEC); |
| 198 | + |
| 199 | + err = pm_device_action_run(uart1_dev, PM_DEVICE_ACTION_SUSPEND); |
| 200 | + if (err) { |
| 201 | + LOG_ERR("pm_device_action_run, error: %d", err); |
| 202 | + return err; |
| 203 | + } |
| 204 | + |
| 205 | + err = pm_device_action_run(uart0_dev, PM_DEVICE_ACTION_SUSPEND); |
| 206 | + if (err) { |
| 207 | + LOG_ERR("pm_device_actiöon_run, error: %d", err); |
| 208 | + return err; |
| 209 | + } |
| 210 | + |
| 211 | + LOG_DBG("UART devices disabled"); |
| 212 | + return 0; |
| 213 | +} |
| 214 | + |
| 215 | +static int uart_enable(void) |
| 216 | +{ |
| 217 | + int err; |
| 218 | + |
| 219 | + if (!device_is_ready(uart0_dev) || !device_is_ready(uart1_dev)) { |
| 220 | + LOG_ERR("UART devices are not ready"); |
| 221 | + return -ENODEV; |
| 222 | + } |
| 223 | + |
| 224 | + err = pm_device_action_run(uart0_dev, PM_DEVICE_ACTION_RESUME); |
| 225 | + if (err) { |
| 226 | + LOG_ERR("pm_device_action_run, error: %d", err); |
| 227 | + return err; |
| 228 | + } |
| 229 | + |
| 230 | + err = pm_device_action_run(uart1_dev, PM_DEVICE_ACTION_RESUME); |
| 231 | + if (err) { |
| 232 | + LOG_ERR("pm_device_action_run, error: %d", err); |
| 233 | + return err; |
| 234 | + } |
| 235 | + |
| 236 | + LOG_DBG("UART devices enabled"); |
| 237 | + return 0; |
| 238 | +} |
| 239 | + |
168 | 240 | static void event_callback(const struct device *dev, struct gpio_callback *cb, uint32_t pins) |
169 | 241 | { |
170 | 242 | ARG_UNUSED(dev); |
171 | 243 | ARG_UNUSED(cb); |
172 | 244 |
|
| 245 | + int err; |
| 246 | + |
173 | 247 | if (pins & BIT(NPM1300_EVENT_VBUS_DETECTED)) { |
174 | | - LOG_WRN("Vbus detected"); |
| 248 | + LOG_DBG("VBUS detected"); |
| 249 | + |
| 250 | + err = uart_enable(); |
| 251 | + if (err) { |
| 252 | + LOG_ERR("uart_enable, error: %d", err); |
| 253 | + SEND_FATAL_ERROR(); |
| 254 | + return; |
| 255 | + } |
175 | 256 | } |
176 | 257 |
|
177 | 258 | if (pins & BIT(NPM1300_EVENT_VBUS_REMOVED)) { |
178 | | - LOG_WRN("Vbus removed"); |
| 259 | + LOG_DBG("VBUS removed"); |
| 260 | + |
| 261 | + err = uart_disable(); |
| 262 | + if (err) { |
| 263 | + LOG_ERR("uart_disable, error: %d", err); |
| 264 | + SEND_FATAL_ERROR(); |
| 265 | + return; |
| 266 | + } |
179 | 267 | } |
180 | 268 | } |
181 | 269 |
|
|
0 commit comments