LibDriver WS2812B
Loading...
Searching...
No Matches
driver_ws2812b.c
Go to the documentation of this file.
1
36
37#include "driver_ws2812b.h"
38
42#define CHIP_NAME "Worldsemi WS2812B"
43#define MANUFACTURER_NAME "Worldsemi "
44#define SUPPLY_VOLTAGE_MIN 3.7f
45#define SUPPLY_VOLTAGE_MAX 5.3f
46#define MAX_CURRENT 16.0f
47#define TEMPERATURE_MIN -25.0f
48#define TEMPERATURE_MAX 85.0f
49#define DRIVER_VERSION 1000
50
62{
63 if (handle == NULL) /* check handle */
64 {
65 return 2; /* return error */
66 }
67 if (handle->debug_print == NULL) /* check debug_print */
68 {
69 return 3; /* return error */
70 }
71 if (handle->spi_10mhz_init == NULL) /* check spi_10mhz_init */
72 {
73 handle->debug_print("ws2812b: spi_10mhz_init is null.\n"); /* spi_10mhz_init is null */
74
75 return 3; /* return error */
76 }
77 if (handle->spi_deinit == NULL) /* check spi_deinit */
78 {
79 handle->debug_print("ws2812b: spi_deinit is null.\n"); /* spi_deinit is null */
80
81 return 3; /* return error */
82 }
83 if (handle->spi_write_cmd == NULL) /* check spi_write_cmd */
84 {
85 handle->debug_print("ws2812b: spi_write_cmd is null.\n"); /* spi_write_cmd is null */
86
87 return 3; /* return error */
88 }
89 if (handle->delay_ms == NULL) /* check delay_ms */
90 {
91 handle->debug_print("ws2812b: delay_ms is null.\n"); /* delay_ms is null */
92
93 return 3; /* return error */
94 }
95
96 if (handle->spi_10mhz_init() != 0) /* spi init */
97 {
98 handle->debug_print("ws2812b: spi init failed.\n"); /* spi init failed */
99
100 return 1; /* return error */
101 }
102 handle->inited = 1; /* flag finish initialization */
103
104 return 0; /* success return 0 */
105}
106
113static void a_ws2812b_write_one_frame(uint32_t rgb, uint8_t temp[48])
114{
115 uint8_t r, g, b;
116 uint8_t i, j;
117 uint32_t c, point;
118 const uint16_t one_code = 0xFFF8U;
119 const uint16_t zero_code = 0xE000U;
120
121 r = (uint8_t)((rgb >> 16) & 0xFF); /* set red */
122 g = (uint8_t)((rgb >> 8) & 0xFF); /* set green */
123 b = (uint8_t)((rgb >> 0) & 0xFF); /* set blue */
124 c = ((uint32_t)(g) << 16) | ((uint32_t)(r) << 8) | b; /* set color */
125
126 memset(temp, 0, sizeof(uint8_t) * 48); /* clear the temp buffer */
127
128 point = 0; /* clear point */
129 for (i = 0; i < 24; i++) /* set 24 bit */
130 {
131 if (((c >> (23 - i)) & 0x01) != 0) /* if bit 1 */
132 {
133 for (j = 0; j < 16; j ++) /* 16 bit */
134 {
135 if (((one_code >> (15 - j)) & 0x01) != 0) /* if one code */
136 {
137 temp[point / 8] |= 1 << (7 - (point % 8)); /* set bit 1 */
138 }
139 else
140 {
141 temp[point / 8] |= 0 << (7 - (point % 8)); /* set bit 0 */
142 }
143 point = point + 1; /* point++ */
144 }
145 }
146 else /* if bit 0 */
147 {
148 for (j = 0; j < 16; j ++) /* 16 bit */
149 {
150 if (((zero_code >> (15 - j)) & 0x01) != 0) /* if zero code */
151 {
152 temp[point / 8] |= 1 << (7 - (point % 8)); /* set bit 1 */
153 }
154 else
155 {
156 temp[point / 8] |= 0 << (7 - (point % 8)); /* set bit 0 */
157 }
158 point = point + 1; /* point++ */
159 }
160 }
161 }
162}
163
181uint8_t ws2812b_write(ws2812b_handle_t *handle, uint32_t *rgb, uint32_t len, uint8_t *temp, uint32_t temp_len)
182{
183 uint32_t i;
184 uint32_t bit_size;
185
186 if (handle == NULL) /* check handle */
187 {
188 return 2; /* return error */
189 }
190 if (handle->inited != 1) /* check handle initialization */
191 {
192 return 3; /* return error */
193 }
194 if (rgb == NULL) /* check rgb */
195 {
196 handle->debug_print("ws2812b: rgb is null.\n"); /* rgb is null */
197
198 return 4; /* return error */
199 }
200 if (temp == NULL) /* check temp */
201 {
202 handle->debug_print("ws2812b: temp is null.\n"); /* temp is null */
203
204 return 5; /* return error */
205 }
206
207 bit_size = WS2812B_EACH_RESET_BIT_FRAME_LEN * len; /* set the bit size */
208 bit_size = bit_size / 8; /* set the bit size */
209 if (bit_size > temp_len) /* check temp length */
210 {
211 handle->debug_print("ws2812b: temp buffer is too small and "
212 "size will be %d.\n", bit_size); /* temp buffer is too small*/
213
214 return 5; /* return error */
215 }
216 for (i = 0; i < bit_size; i++) /* set the reset frame */
217 {
218 temp[i] = 0x00; /* set 0x00 */
219 }
220 if (handle->spi_write_cmd(temp, (uint16_t)bit_size) != 0) /* write command */
221 {
222 handle->debug_print("ws2812b: write command failed.\n"); /* write command failed */
223
224 return 1; /* return error */
225 }
226
227 bit_size = 24 * 16 * len; /* set the bit size */
228 bit_size = bit_size / 8; /* set the bit size */
229 if (bit_size > temp_len) /* check temp length */
230 {
231 handle->debug_print("ws2812b: temp buffer is too small and "
232 "size will be %d.\n", bit_size); /* temp buffer is too small*/
233
234 return 6; /* return error */
235 }
236
237 for (i = 0; i < len; i++) /* set the color frame */
238 {
239 a_ws2812b_write_one_frame(rgb[i], &temp[i * 48]); /* set color */
240 }
241
242 if (handle->spi_write_cmd(temp, (uint16_t)bit_size) != 0) /* write command */
243 {
244 handle->debug_print("ws2812b: write command failed.\n"); /* write command failed */
245
246 return 1; /* return error */
247 }
248
249 return 0; /* success return 0 */
250}
251
267uint8_t ws2812b_write_only_reset(ws2812b_handle_t *handle, uint32_t len, uint8_t *temp, uint32_t temp_len)
268{
269 uint32_t i;
270 uint32_t bit_size;
271
272 if (handle == NULL) /* check handle */
273 {
274 return 2; /* return error */
275 }
276 if (handle->inited != 1) /* check handle initialization */
277 {
278 return 3; /* return error */
279 }
280 if (temp == NULL) /* check temp */
281 {
282 handle->debug_print("ws2812b: temp is null.\n"); /* temp is null */
283
284 return 4; /* return error */
285 }
286
287 bit_size = WS2812B_EACH_RESET_BIT_FRAME_LEN * len; /* set the bit size */
288 bit_size = bit_size / 8; /* set the bit size */
289 if (bit_size > temp_len) /* check temp length */
290 {
291 handle->debug_print("ws2812b: temp buffer is too small and "
292 "size will be %d.\n", bit_size); /* temp buffer is too small*/
293
294 return 5; /* return error */
295 }
296
297 for (i = 0; i < bit_size; i++) /* set the reset frame */
298 {
299 temp[i] = 0x00; /* set 0x00 */
300 }
301
302 if (handle->spi_write_cmd(temp, (uint16_t)bit_size) != 0) /* write command */
303 {
304 handle->debug_print("ws2812b: write command failed.\n"); /* write command failed */
305
306 return 1; /* return error */
307 }
308
309 return 0; /* success return 0 */
310}
311
329uint8_t ws2812b_write_only_color(ws2812b_handle_t *handle, uint32_t *rgb, uint32_t len, uint8_t *temp, uint32_t temp_len)
330{
331 uint32_t i;
332 uint32_t bit_size;
333
334 if (handle == NULL) /* check handle */
335 {
336 return 2; /* return error */
337 }
338 if (handle->inited != 1) /* check handle initialization */
339 {
340 return 3; /* return error */
341 }
342 if (rgb == NULL) /* check rgb */
343 {
344 handle->debug_print("ws2812b: rgb is null.\n"); /* rgb is null */
345
346 return 4; /* return error */
347 }
348 if (temp == NULL) /* check temp */
349 {
350 handle->debug_print("ws2812b: temp is null.\n"); /* temp is null */
351
352 return 5; /* return error */
353 }
354
355 bit_size = 24 * 16 * len; /* set the bit size */
356 bit_size = bit_size / 8; /* set the bit size */
357 if (bit_size > temp_len) /* check temp length */
358 {
359 handle->debug_print("ws2812b: temp buffer is too small and "
360 "size will be %d.\n", bit_size); /* temp buffer is too small*/
361
362 return 6; /* return error */
363 }
364
365 for (i = 0; i < len; i++) /* set the color frame */
366 {
367 a_ws2812b_write_one_frame(rgb[i], &temp[i * 48]); /* set color */
368 }
369
370 if (handle->spi_write_cmd(temp, (uint16_t)bit_size) != 0) /* write command */
371 {
372 handle->debug_print("ws2812b: write command failed.\n"); /* write command failed */
373
374 return 1; /* return error */
375 }
376
377 return 0; /* success return 0 */
378}
379
391{
392 uint8_t res;
393
394 if (handle == NULL) /* check handle */
395 {
396 return 2; /* return error */
397 }
398 if (handle->inited != 1) /* check handle initialization */
399 {
400 return 3; /* return error */
401 }
402
403 res = handle->spi_deinit(); /* spi deinit */
404 if (res != 0) /* check error */
405 {
406 handle->debug_print("ws2812b: spi deinit failed.\n"); /* spi deinit failed */
407
408 return 1; /* return error */
409 }
410 handle->inited = 0; /* flag closed */
411
412 return 0; /* success return 0 */
413}
414
427uint8_t ws2812b_set_reg(ws2812b_handle_t *handle, uint8_t *buf, uint16_t len)
428{
429 if (handle == NULL) /* check handle */
430 {
431 return 2; /* return error */
432 }
433 if (handle->inited != 1) /* check handle initialization */
434 {
435 return 3; /* return error */
436 }
437
438 return handle->spi_write_cmd(buf, len); /* write to reg */
439}
440
450{
451 if (info == NULL) /* check handle */
452 {
453 return 2; /* return error */
454 }
455
456 memset(info, 0, sizeof(ws2812b_info_t)); /* initialize ws2812b info structure */
457 strncpy(info->chip_name, CHIP_NAME, 32); /* copy chip name */
458 strncpy(info->manufacturer_name, MANUFACTURER_NAME, 32); /* copy manufacturer name */
459 strncpy(info->interface, "SPI", 8); /* copy interface name */
460 info->supply_voltage_min_v = SUPPLY_VOLTAGE_MIN; /* set minimal supply voltage */
461 info->supply_voltage_max_v = SUPPLY_VOLTAGE_MAX; /* set maximum supply voltage */
462 info->max_current_ma = MAX_CURRENT; /* set maximum current */
463 info->temperature_max = TEMPERATURE_MAX; /* set minimal temperature */
464 info->temperature_min = TEMPERATURE_MIN; /* set maximum temperature */
465 info->driver_version = DRIVER_VERSION; /* set driver version */
466
467 return 0; /* success return 0 */
468}
#define MAX_CURRENT
#define SUPPLY_VOLTAGE_MAX
#define TEMPERATURE_MAX
#define MANUFACTURER_NAME
#define TEMPERATURE_MIN
#define SUPPLY_VOLTAGE_MIN
#define CHIP_NAME
chip register definition
#define DRIVER_VERSION
driver ws2812b header file
uint8_t ws2812b_info(ws2812b_info_t *info)
get chip's information
struct ws2812b_info_s ws2812b_info_t
ws2812b information structure definition
uint8_t ws2812b_write(ws2812b_handle_t *handle, uint32_t *rgb, uint32_t len, uint8_t *temp, uint32_t temp_len)
write reset and color frame
uint8_t ws2812b_deinit(ws2812b_handle_t *handle)
close the chip
struct ws2812b_handle_s ws2812b_handle_t
ws2812b handle structure definition
uint8_t ws2812b_write_only_reset(ws2812b_handle_t *handle, uint32_t len, uint8_t *temp, uint32_t temp_len)
write the reset frame
uint8_t ws2812b_write_only_color(ws2812b_handle_t *handle, uint32_t *rgb, uint32_t len, uint8_t *temp, uint32_t temp_len)
write the color frame
#define WS2812B_EACH_RESET_BIT_FRAME_LEN
ws2812b each reset bit frame length definition
uint8_t ws2812b_init(ws2812b_handle_t *handle)
initialize the chip
uint8_t ws2812b_set_reg(ws2812b_handle_t *handle, uint8_t *buf, uint16_t len)
set the chip register
void(* delay_ms)(uint32_t ms)
void(* debug_print)(const char *const fmt,...)
uint8_t(* spi_deinit)(void)
uint8_t(* spi_10mhz_init)(void)
uint8_t(* spi_write_cmd)(uint8_t *buf, uint16_t len)
float supply_voltage_max_v
uint32_t driver_version
char manufacturer_name[32]
float supply_voltage_min_v