1 /*
2 * Copyright (c) 2023 Nordic Semiconductor ASA
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6 #include <stdlib.h>
7
8 #include <zephyr/device.h>
9 #include <zephyr/drivers/gpio.h>
10 #include <zephyr/drivers/regulator.h>
11 #include <zephyr/drivers/sensor.h>
12 #include <zephyr/drivers/sensor/npm1300_charger.h>
13 #include <zephyr/drivers/led.h>
14 #include <zephyr/dt-bindings/regulator/npm1300.h>
15 #include <zephyr/drivers/mfd/npm1300.h>
16 #include <zephyr/sys/printk.h>
17 #include <getopt.h>
18
19 #define SLEEP_TIME_MS 100
20 #define UPDATE_TIME_MS 2000
21
22 static const struct gpio_dt_spec button1 = GPIO_DT_SPEC_GET(DT_ALIAS(sw0), gpios);
23
24 static const struct device *regulators = DEVICE_DT_GET(DT_NODELABEL(npm1300_ek_regulators));
25
26 static const struct device *charger = DEVICE_DT_GET(DT_NODELABEL(npm1300_ek_charger));
27
28 static const struct device *leds = DEVICE_DT_GET(DT_NODELABEL(npm1300_ek_leds));
29
30 static const struct device *pmic = DEVICE_DT_GET(DT_NODELABEL(npm1300_ek_pmic));
31
configure_ui(void)32 void configure_ui(void)
33 {
34 int ret;
35
36 if (!gpio_is_ready_dt(&button1)) {
37 printk("Error: button device %s is not ready\n", button1.port->name);
38 return;
39 }
40
41 ret = gpio_pin_configure_dt(&button1, GPIO_INPUT);
42 if (ret != 0) {
43 printk("Error %d: failed to configure %s pin %d\n", ret, button1.port->name,
44 button1.pin);
45 return;
46 }
47
48 printk("Set up button at %s pin %d\n", button1.port->name, button1.pin);
49
50 if (!device_is_ready(leds)) {
51 printk("Error: led device is not ready\n");
52 return;
53 }
54 }
55
event_callback(const struct device * dev,struct gpio_callback * cb,uint32_t pins)56 static void event_callback(const struct device *dev, struct gpio_callback *cb, uint32_t pins)
57 {
58 printk("Event detected\n");
59 }
60
configure_events(void)61 void configure_events(void)
62 {
63 if (!device_is_ready(pmic)) {
64 printk("Pmic device not ready.\n");
65 return;
66 }
67
68 /* Setup callback for shiphold button press */
69 static struct gpio_callback event_cb;
70
71 gpio_init_callback(&event_cb, event_callback, BIT(NPM1300_EVENT_SHIPHOLD_PRESS));
72
73 mfd_npm1300_add_callback(pmic, &event_cb);
74 }
75
read_sensors(void)76 void read_sensors(void)
77 {
78 struct sensor_value volt;
79 struct sensor_value current;
80 struct sensor_value temp;
81 struct sensor_value error;
82 struct sensor_value status;
83 struct sensor_value vbus_present;
84
85 sensor_sample_fetch(charger);
86 sensor_channel_get(charger, SENSOR_CHAN_GAUGE_VOLTAGE, &volt);
87 sensor_channel_get(charger, SENSOR_CHAN_GAUGE_AVG_CURRENT, ¤t);
88 sensor_channel_get(charger, SENSOR_CHAN_GAUGE_TEMP, &temp);
89 sensor_channel_get(charger, (enum sensor_channel)SENSOR_CHAN_NPM1300_CHARGER_STATUS,
90 &status);
91 sensor_channel_get(charger, (enum sensor_channel)SENSOR_CHAN_NPM1300_CHARGER_ERROR, &error);
92 sensor_attr_get(charger, (enum sensor_channel)SENSOR_CHAN_NPM1300_CHARGER_VBUS_STATUS,
93 (enum sensor_attribute)SENSOR_ATTR_NPM1300_CHARGER_VBUS_PRESENT,
94 &vbus_present);
95
96 printk("V: %d.%03d ", volt.val1, volt.val2 / 1000);
97
98 printk("I: %s%d.%04d ", ((current.val1 < 0) || (current.val2 < 0)) ? "-" : "",
99 abs(current.val1), abs(current.val2) / 100);
100
101 printk("T: %s%d.%02d\n", ((temp.val1 < 0) || (temp.val2 < 0)) ? "-" : "", abs(temp.val1),
102 abs(temp.val2) / 10000);
103
104 printk("Charger Status: %d, Error: %d, VBUS: %s\n", status.val1, error.val1,
105 vbus_present.val1 ? "connected" : "disconnected");
106 }
107
main(void)108 int main(void)
109 {
110 configure_ui();
111
112 configure_events();
113
114 if (!device_is_ready(regulators)) {
115 printk("Error: Regulator device is not ready\n");
116 return 0;
117 }
118
119 if (!device_is_ready(charger)) {
120 printk("Charger device not ready.\n");
121 return 0;
122 }
123
124 while (1) {
125 /* Cycle regulator control GPIOs when first button pressed */
126 static bool last_button;
127 static int dvs_state;
128 bool button_state = gpio_pin_get_dt(&button1) == 1;
129
130 if (button_state && !last_button) {
131 dvs_state = (dvs_state + 1) % 4;
132 regulator_parent_dvs_state_set(regulators, dvs_state);
133 }
134
135 /* Update PMIC LED if button state has changed */
136 if (button_state != last_button) {
137 if (button_state) {
138 led_on(leds, 2U);
139 } else {
140 led_off(leds, 2U);
141 }
142 }
143
144 /* Read and display charger status */
145 static int count;
146
147 if (++count > (UPDATE_TIME_MS / SLEEP_TIME_MS)) {
148 read_sensors();
149 count = 0;
150 }
151
152 last_button = button_state;
153 k_msleep(SLEEP_TIME_MS);
154 }
155 }
156