1 /*
2  * Copyright (c) 2022 Nordic Semiconductor
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define LOG_MODULE_NAME app_led
8 
9 #include <zephyr/logging/log.h>
10 LOG_MODULE_REGISTER(LOG_MODULE_NAME);
11 
12 #include "modules.h"
13 
14 #include <zephyr/drivers/gpio.h>
15 #include <zephyr/net/lwm2m.h>
16 
17 #define LIGHT_NAME "Test light"
18 
19 /* If led0 gpios doesn't exist the relevant IPSO object will simply not be created. */
20 static const struct gpio_dt_spec led_gpio = GPIO_DT_SPEC_GET_OR(DT_ALIAS(led0), gpios, {});
21 static uint32_t led_state;
22 
23 /* TODO: Move to a pre write hook that can handle ret codes once available */
led_on_off_cb(uint16_t obj_inst_id,uint16_t res_id,uint16_t res_inst_id,uint8_t * data,uint16_t data_len,bool last_block,size_t total_size,size_t offset)24 static int led_on_off_cb(uint16_t obj_inst_id, uint16_t res_id, uint16_t res_inst_id, uint8_t *data,
25 			 uint16_t data_len, bool last_block, size_t total_size, size_t offset)
26 {
27 	int ret = 0;
28 	uint32_t led_val;
29 
30 	led_val = *(uint8_t *)data;
31 	if (led_val != led_state) {
32 		ret = gpio_pin_set_dt(&led_gpio, (int)led_val);
33 		if (ret) {
34 			/*
35 			 * We need an extra hook in LWM2M to better handle
36 			 * failures before writing the data value and not in
37 			 * post_write_cb, as there is not much that can be
38 			 * done here.
39 			 */
40 			LOG_ERR("Fail to write to GPIO %d", led_gpio.pin);
41 			return ret;
42 		}
43 
44 		led_state = led_val;
45 		/* TODO: Move to be set by an internal post write function */
46 		lwm2m_set_s32(&LWM2M_OBJ(3311, 0, 5852), 0);
47 	}
48 
49 	return ret;
50 }
51 
init_led_device(void)52 int init_led_device(void)
53 {
54 	int ret;
55 
56 	if (!gpio_is_ready_dt(&led_gpio)) {
57 		return -ENODEV;
58 	}
59 
60 	ret = gpio_pin_configure_dt(&led_gpio, GPIO_OUTPUT_INACTIVE);
61 	if (ret) {
62 		return ret;
63 	}
64 
65 	lwm2m_create_object_inst(&LWM2M_OBJ(3311, 0));
66 	lwm2m_register_post_write_callback(&LWM2M_OBJ(3311, 0, 5850), led_on_off_cb);
67 	lwm2m_set_res_buf(&LWM2M_OBJ(3311, 0, 5750), LIGHT_NAME, sizeof(LIGHT_NAME),
68 			  sizeof(LIGHT_NAME), LWM2M_RES_DATA_FLAG_RO);
69 
70 	return 0;
71 }
72