1 /*
2 * Copyright (c) 2016 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 /**
8 * @file Sample app to utilize APA102C LED.
9 *
10 * The APA102/C requires 5V data and clock signals, so logic
11 * level shifter (preferred) or pull-up resistors are needed.
12 * Make sure the pins are 5V tolerant if using pull-up
13 * resistors.
14 *
15 * WARNING: the APA102C are very bright even at low settings.
16 * Protect your eyes and do not look directly into those LEDs.
17 */
18
19 #include <zephyr/kernel.h>
20
21 #include <zephyr/sys/printk.h>
22
23 #include <zephyr/device.h>
24 #include <zephyr/drivers/gpio.h>
25 /* in millisecond */
26 #define SLEEPTIME K_MSEC(250)
27
28 #define GPIO_DATA_PIN 16
29 #define GPIO_CLK_PIN 19
30 #define GPIO_NAME "GPIO_"
31
32 #define APA102C_START_FRAME 0x00000000
33 #define APA102C_END_FRAME 0xFFFFFFFF
34
35 /* The LED is very bright. So to protect the eyes,
36 * brightness is set very low, and RGB values are
37 * set low too.
38 */
39 uint32_t rgb[] = {
40 0xE1000010,
41 0xE1001000,
42 0xE1100000,
43 0xE1101010,
44 };
45 #define NUM_RGB 4
46
47 /* Number of LEDS linked together */
48 #define NUM_LEDS 1
49
send_rgb(const struct device * gpio_dev,uint32_t rgb)50 void send_rgb(const struct device *gpio_dev, uint32_t rgb)
51 {
52 int i;
53
54 for (i = 0; i < 32; i++) {
55 /* MSB goes in first */
56 gpio_pin_set_raw(gpio_dev, GPIO_DATA_PIN, (rgb & BIT(31)) != 0);
57
58 /* Latch data into LED */
59 gpio_pin_set_raw(gpio_dev, GPIO_CLK_PIN, 1);
60 gpio_pin_set_raw(gpio_dev, GPIO_CLK_PIN, 0);
61
62 rgb <<= 1;
63 }
64 }
65
main(void)66 int main(void)
67 {
68 const struct device *gpio_dev;
69 int ret;
70 int idx = 0;
71 int leds = 0;
72
73 gpio_dev = DEVICE_DT_GET(DT_ALIAS(gpio_0));
74 if (!device_is_ready(gpio_dev)) {
75 printk("GPIO device %s is not ready!\n", gpio_dev->name);
76 return 0;
77 }
78
79 /* Setup GPIO output */
80 ret = gpio_pin_configure(gpio_dev, GPIO_DATA_PIN, GPIO_OUTPUT);
81 if (ret) {
82 printk("Error configuring " GPIO_NAME "%d!\n", GPIO_DATA_PIN);
83 }
84
85 ret = gpio_pin_configure(gpio_dev, GPIO_CLK_PIN, GPIO_OUTPUT);
86 if (ret) {
87 printk("Error configuring " GPIO_NAME "%d!\n", GPIO_CLK_PIN);
88 }
89
90 while (1) {
91 send_rgb(gpio_dev, APA102C_START_FRAME);
92
93 for (leds = 0; leds < NUM_LEDS; leds++) {
94 send_rgb(gpio_dev, rgb[(idx + leds) % NUM_RGB]);
95 }
96
97 /* If there are more LEDs linked together,
98 * then what NUM_LEDS is, the NUM_LEDS+1
99 * LED is going to be full bright.
100 */
101 send_rgb(gpio_dev, APA102C_END_FRAME);
102
103 idx++;
104 if (idx >= NUM_RGB) {
105 idx = 0;
106 }
107
108 k_sleep(SLEEPTIME);
109 }
110 return 0;
111 }
112