Lines Matching +full:write +full:- +full:bit +full:- +full:idx
5 * https://electronut.in/nrf52-i2s-ws2812/
7 * Note: the word "word" refers to a 32-bit integer unless otherwise stated.
11 * The I2S peripheral sends two 16-bit channel values for each clock period.
12 * A single LED color (8 data bits) will take up one 32-bit word or one LRCK
15 * SPDX-License-Identifier: Apache-2.0
28 #include <zephyr/dt-bindings/led/led.h>
49 /* Serialize an 8-bit color channel value into two 16-bit I2S values (or 1 32-bit
68 const struct ws2812_i2s_cfg *cfg = dev->config; in ws2812_strip_update_rgb()
69 const uint8_t sym_one = cfg->nibble_one; in ws2812_strip_update_rgb()
70 const uint8_t sym_zero = cfg->nibble_zero; in ws2812_strip_update_rgb()
71 const uint32_t reset_word = cfg->active_low ? ~0 : 0; in ws2812_strip_update_rgb()
78 ret = k_mem_slab_alloc(cfg->mem_slab, &mem_block, K_SECONDS(10)); in ws2812_strip_update_rgb()
81 return -ENOMEM; in ws2812_strip_update_rgb()
85 /* Add a pre-data reset, so the first pixel isn't skipped by the strip. */ in ws2812_strip_update_rgb()
93 * in color mapping on-wire format (e.g. GRB, GRBW, RGB, etc). in ws2812_strip_update_rgb()
96 for (uint16_t j = 0; j < cfg->num_colors; j++) { in ws2812_strip_update_rgb()
99 switch (cfg->color_mapping[j]) { in ws2812_strip_update_rgb()
114 return -EINVAL; in ws2812_strip_update_rgb()
121 for (uint16_t i = 0; i < cfg->reset_words; i++) { in ws2812_strip_update_rgb()
127 ret = i2s_write(cfg->dev, mem_block, cfg->tx_buf_bytes); in ws2812_strip_update_rgb()
129 k_mem_slab_free(cfg->mem_slab, mem_block); in ws2812_strip_update_rgb()
130 LOG_ERR("Failed to write data: %d", ret); in ws2812_strip_update_rgb()
134 ret = i2s_trigger(cfg->dev, I2S_DIR_TX, I2S_TRIGGER_START); in ws2812_strip_update_rgb()
140 ret = i2s_trigger(cfg->dev, I2S_DIR_TX, I2S_TRIGGER_DRAIN); in ws2812_strip_update_rgb()
147 flush_time_us = cfg->lrck_period * cfg->tx_buf_bytes / sizeof(uint32_t); in ws2812_strip_update_rgb()
148 k_usleep(flush_time_us + cfg->extra_wait_time_us); in ws2812_strip_update_rgb()
155 const struct ws2812_i2s_cfg *cfg = dev->config; in ws2812_strip_length()
157 return cfg->length; in ws2812_strip_length()
162 const struct ws2812_i2s_cfg *cfg = dev->config; in ws2812_i2s_init()
167 lrck_hz = USEC_PER_SEC / cfg->lrck_period; in ws2812_i2s_init()
169 lrck_hz, cfg->lrck_period); in ws2812_i2s_init()
171 /* 16-bit stereo, 100kHz LCLK */ in ws2812_i2s_init()
177 config.mem_slab = cfg->mem_slab; in ws2812_i2s_init()
178 config.block_size = cfg->tx_buf_bytes; in ws2812_i2s_init()
181 ret = i2s_configure(cfg->dev, I2S_DIR_TX, &config); in ws2812_i2s_init()
187 for (uint16_t i = 0; i < cfg->num_colors; i++) { in ws2812_i2s_init()
188 switch (cfg->color_mapping[i]) { in ws2812_i2s_init()
196 "Check the color-mapping DT property", in ws2812_i2s_init()
197 dev->name); in ws2812_i2s_init()
198 return -EINVAL; in ws2812_i2s_init()
210 #define WS2812_I2S_LRCK_PERIOD_US(idx) DT_INST_PROP(idx, lrck_period) argument
212 #define WS2812_RESET_DELAY_US(idx) DT_INST_PROP(idx, reset_delay) argument
214 #define WS2812_RESET_DELAY_WORDS(idx) \ argument
215 DIV_ROUND_UP(WS2812_RESET_DELAY_US(idx), WS2812_I2S_LRCK_PERIOD_US(idx))
217 #define WS2812_NUM_COLORS(idx) (DT_INST_PROP_LEN(idx, color_mapping)) argument
219 #define WS2812_I2S_NUM_PIXELS(idx) (DT_INST_PROP(idx, chain_length)) argument
221 #define WS2812_I2S_BUFSIZE(idx) \ argument
222 (((WS2812_NUM_COLORS(idx) * WS2812_I2S_NUM_PIXELS(idx)) + \
223 WS2812_I2S_PRE_DELAY_WORDS + WS2812_RESET_DELAY_WORDS(idx)) * 4)
225 #define WS2812_I2S_DEVICE(idx) \ argument
227 K_MEM_SLAB_DEFINE_STATIC(ws2812_i2s_##idx##_slab, WS2812_I2S_BUFSIZE(idx), 2, 4); \
229 static const uint8_t ws2812_i2s_##idx##_color_mapping[] = \
230 DT_INST_PROP(idx, color_mapping); \
232 static const struct ws2812_i2s_cfg ws2812_i2s_##idx##_cfg = { \
233 .dev = DEVICE_DT_GET(DT_INST_BUS(idx)), \
234 .tx_buf_bytes = WS2812_I2S_BUFSIZE(idx), \
235 .mem_slab = &ws2812_i2s_##idx##_slab, \
236 .num_colors = WS2812_NUM_COLORS(idx), \
237 .length = DT_INST_PROP(idx, chain_length), \
238 .color_mapping = ws2812_i2s_##idx##_color_mapping, \
239 .lrck_period = WS2812_I2S_LRCK_PERIOD_US(idx), \
240 .extra_wait_time_us = DT_INST_PROP(idx, extra_wait_time), \
241 .reset_words = WS2812_RESET_DELAY_WORDS(idx), \
242 .active_low = DT_INST_PROP(idx, out_active_low), \
243 .nibble_one = DT_INST_PROP(idx, nibble_one), \
244 .nibble_zero = DT_INST_PROP(idx, nibble_zero), \
247 DEVICE_DT_INST_DEFINE(idx, ws2812_i2s_init, NULL, NULL, &ws2812_i2s_##idx##_cfg, \