1 /*
2  * Copyright 2023 Daniel DeGrasse <daniel@degrasse.com>
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 #include <zephyr/drivers/led.h>
9 #include <zephyr/drivers/led/is31fl3733.h>
10 #include <string.h>
11 
12 #define HW_ROW_COUNT 12
13 #define HW_COL_COUNT 16
14 
15 /* LED matrix is addressed using a row major format */
16 #define LED_MATRIX_COORD(x, y) ((x) * HW_COL_COUNT) + (y)
17 
18 static uint8_t led_state[HW_COL_COUNT * HW_ROW_COUNT];
19 
led_channel_write(const struct device * led)20 static int led_channel_write(const struct device *led)
21 {
22 	int ret;
23 	uint32_t led_idx;
24 
25 	/* Set all LEDs to full brightness */
26 	printk("Set all LEDs to full brightness\n");
27 	memset(led_state, 0, sizeof(led_state));
28 	for (uint8_t row = 0; row < CONFIG_LED_ROW_COUNT; row++) {
29 		for (uint8_t col = 0; col < CONFIG_LED_COLUMN_COUNT; col++) {
30 			led_idx = LED_MATRIX_COORD(row, col);
31 			led_state[led_idx] = 0xFF;
32 		}
33 	}
34 	ret = led_write_channels(led, 0, sizeof(led_state), led_state);
35 	if (ret) {
36 		printk("Error: could not write LED channels (%d)\n", ret);
37 		return ret;
38 	}
39 	k_msleep(1000);
40 	/* Disable quadrant of LED display */
41 	printk("Disable LED quadrant\n");
42 	for (uint8_t row = 0; row < CONFIG_LED_ROW_COUNT / 2; row++) {
43 		for (uint8_t col = 0; col < CONFIG_LED_COLUMN_COUNT / 2; col++) {
44 			led_idx = LED_MATRIX_COORD(row, col);
45 			led_state[led_idx] = 0x00;
46 		}
47 	}
48 	ret = led_write_channels(led, 0,
49 		((CONFIG_LED_ROW_COUNT / 2) * HW_COL_COUNT), led_state);
50 	if (ret) {
51 		printk("Error: could not write LED channels (%d)\n", ret);
52 		return ret;
53 	}
54 	k_msleep(1000);
55 	return 0;
56 }
57 
led_brightness(const struct device * led)58 static int led_brightness(const struct device *led)
59 {
60 	int ret;
61 	uint8_t row, col;
62 
63 	/* Set LED brightness to low value sequentially */
64 	printk("Set LEDs to half brightness sequentially\n");
65 	for (row = 0; row < CONFIG_LED_ROW_COUNT; row++) {
66 		for (col = 0; col < CONFIG_LED_COLUMN_COUNT; col++) {
67 			ret = led_set_brightness(led, LED_MATRIX_COORD(row, col),
68 						50);
69 			if (ret < 0) {
70 				printk("Error: could not enable led "
71 					"at [%d, %d]: (%d)\n",
72 					row, col, ret);
73 				return ret;
74 			}
75 			k_msleep(100);
76 		}
77 	}
78 	return 0;
79 }
80 
led_on_off(const struct device * led)81 static int led_on_off(const struct device *led)
82 {
83 	int ret;
84 	uint8_t row, col;
85 
86 	printk("Toggle each led\n");
87 	/* Turn on each led for a short duration */
88 	for (row = 0; row < CONFIG_LED_ROW_COUNT; row++) {
89 		for (col = 0; col < CONFIG_LED_COLUMN_COUNT; col++) {
90 			ret = led_off(led, LED_MATRIX_COORD(row, col));
91 			if (ret < 0) {
92 				printk("Error: could not disable led "
93 					"at [%d, %d]: (%d)\n",
94 					row, col, ret);
95 				return ret;
96 			}
97 			k_msleep(100);
98 			ret = led_on(led, LED_MATRIX_COORD(row, col));
99 			if (ret < 0) {
100 				printk("Error: could not enable led "
101 					"at [%d, %d]: (%d)\n",
102 					row, col, ret);
103 				return ret;
104 			}
105 		}
106 	}
107 	k_msleep(500);
108 	return 0;
109 }
110 
111 const struct device *led_dev = DEVICE_DT_GET_ONE(issi_is31fl3733);
112 
main(void)113 int main(void)
114 {
115 	int ret;
116 	int current_limit = 0xFF;
117 
118 	if (!device_is_ready(led_dev)) {
119 		printk("Error- LED device is not ready\n");
120 		return 0;
121 	}
122 
123 	while (1) {
124 		ret = led_channel_write(led_dev);
125 		if (ret < 0) {
126 			return 0;
127 		}
128 		ret = led_brightness(led_dev);
129 		if (ret < 0) {
130 			return 0;
131 		}
132 		ret = led_on_off(led_dev);
133 		if (ret < 0) {
134 			return 0;
135 		}
136 		if (current_limit == 0xFF) {
137 			/* Select lower current limt */
138 			printk("Restarting sample with lower current limit\n");
139 			current_limit = 0x3F;
140 			ret = is31fl3733_current_limit(led_dev, current_limit);
141 			if (ret) {
142 				printk("Could not set LED current limit (%d)\n", ret);
143 				return 0;
144 			}
145 		} else {
146 			/* Select higher current limt */
147 			printk("Restarting sample with higher current limit\n");
148 			current_limit = 0xFF;
149 			ret = is31fl3733_current_limit(led_dev, current_limit);
150 			if (ret) {
151 				printk("Could not set LED current limit (%d)\n", ret);
152 				return 0;
153 			}
154 		}
155 	}
156 }
157