4df842a0094fb1fa5698d8f955b4617713ac0b50
[lpc1224] / include / extdrv / ws2812.h
1 /****************************************************************************
2  *   extdrv/ws2812.h
3  *
4  *
5  * Copyright 2013 Nathael Pajani <nathael.pajani@ed3l.fr>
6  *
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20  *
21  *************************************************************************** */
23 /*
24  * Support for the WS2812 Chainable RGB Leds
25  *
26  * WS2812 protocol can be found here : https://www.adafruit.com/datasheets/WS2812.pdf
27  *
28  */
30 /*
31  * Preliminary notice :
32  * This driver will only function with a clock frequency of 48MHz (or close to) due to
33  *   the use of nop() to get the right timmings.
34  *
35  * Internal data buffer :
36  * This driver uses an internal buffer for NB_LEDS leds or "pixels". The buffer
37  *   size is (3 * NB_LEDS) bytes.
38  * The buffer is set pixel per pixel using the ws2812_set_pixel() function.
39  * The buffer is then sent to the led strip using ws2812_send_frame().
40  *
41  * Driving several led strips :
42  * It is possible to drive several led strips using this driver by calling the config
43  *   function ws2812_config() between each ws2812_send_frame() call, and setting the led
44  *   data again using the ws2812_set_pixel() function for each new led.
45  * This solution is not the most adapted for several led strips, and the driver should be
46  *   modified to use an external buffer which address is either passed to each function or
47  *   set using a modified version of the ws2812_config() function.
48  *   In this case, the timmings should be checked and updated as access to the data may
49  *   require more instructions.
50  *
51  * Note : ws2812_send_frame() will call lpc_disable_irq() to disable all interrupts
52  *   when entering the timming critical section.
53  *   Use of timers and interrupts have been tried but timmings are too short even
54  *   whith the micro-controller running at 48MHz and direct access to the timer and
55  *   GPIO registers.
56  *   Instead the function uses a few nop() to get the right timmings.
57  *   
58  */
60 #include "lib/stdint.h"
61 #include "core/pio.h"
64 /* Size of the internal buffer.
65  * Change the value to the number of leds of your led strip.
66  */
67 #define NB_LEDS  60
70 /* Configure the pin for the led data signal. */
71 void ws2812_config(const struct pio* gpio);
73 /* Send led data from internal buffer using the configured GPIO pin. (Set leds to the
74  *   selected color).
75  * If no pin have been configured, GPIO_0_0 will be used.
76  * If nb_leds is 0 then all led data set using ws2812_set_pixel() since the last call
77  *   to ws2812_clear_buffer(), ws2812_clear() or ws2812_stop() will be sent.
78  * Call to this function will disable interrupts due to timming restrictions.
79  * Return -1 on error (nb_leds above NB_LEDS), or 0 on success.
80  */
81 int ws2812_send_frame(uint16_t nb_leds);
83 /* Set a pixel (led) color in the data buffer (frame)
84  * The pixel number 'pixel_num' is the led offset in the led strip.
85  * 'red', 'green' and 'blue' are the color values of the pixel. A value of 0 is off,
86  *   while a value of 0xFF (255) is full brightness.
87  * Return -1 on error (pixel_num above NB_LEDS), or 0 on success.
88  */
89 int ws2812_set_pixel(uint16_t pixel_num, uint8_t red, uint8_t green, uint8_t blue);
91 /* Get a pixel (led) color from the data buffer */
92 int ws2812_get_pixel(uint16_t pixel_num, uint8_t* red, uint8_t* green, uint8_t* blue);
94 /* Clear the internal data buffer. */
95 void ws2812_clear_buffer(void);
97 /* Clear the internal data buffer and send it to the Leds, turning them all off */
98 void ws2812_clear(void);
99 /*      Alias for ws2812_clear */
100 void ws2812_stop(void);