Use controller/peripheral and SDO/SDI terminology in the remaining
SPI-using drivers (audio, auxdisplay, bluetooth HCI, dac, eeprom,
ethernet, flash, fpga, gpio, haptics, hdlc_rcp_if, ieee802154,
input, led, led_strip, lora, mfd, misc, mux, rtc, sdhc, stepper,
video, watchdog, wifi) and the ec_host_cmd SPI STM32 backend,
following coding guideline rule A.2: switch to
SPI_OP_MODE_CONTROLLER/PERIPHERAL and SPI_SDO_OVERRUN_DT, rename
Zephyr-owned identifiers (the HCI SPI header buffers, the winc1500
bus wrapper transfer parameters), and update comments, log messages
and Kconfig help prose.
Vendor and out-of-scope identifiers keep their names: STM32
LL_SPI_MODE_SLAVE in the ec_host_cmd backend, the ATWINC1500 SDK I2C
SLAVE_ADDRESS definition, and the I2S codec clock-role variable in
tlv320aic26.
Assisted-by: Claude:fable-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Add a WS2812 LED strip driver on top of the pulse_io subsystem.
Pixel data is encoded as fixed-period cells with per-bit duty and
sent through a pulse_io transmit channel, so the driver runs on
any SoC with a pulse_io backend. Add a led_strip sample overlay
driving the on-board WS2812 of the esp32s3_devkitc through the
RMT backend, selected with the pulse_io file suffix.
Assisted-by: Claude Code:opus-4-8
Signed-off-by: Sylvio Alves <sylvio.alves@espressif.com>
send_buf uses NRF_GPIO as the GPIO controller base address.
NRF_GPIO is defined as NRF_P0 in sdk-hal_nordic/nrfx/mdk,
so with pins not belong to GPIO0,
it causes data to be sent to the wrong pin.
At compile time get the GPIO controller register address
from devicetree, and calculate the OUTSET base address
with struct NRF_GPIO_Type.
Tested on nRF52833 hardware.
Signed-off-by: ZF Yu <ez4y2f@icloud.com>
The driver discarded the load offset returned by pio_add_program() and
started the state machine with pio_sm_init(pio, sm, -1, ...). The -1 is
silently masked to PC 31 by pio_encode_jmp(), which only works by
accident while the ws2812 program is the sole program in the PIO
instance: top-down placement puts it at offsets 28..31, and PC 31 then
happens to hit the program's final jmp back to its start.
As soon as another program is loaded into the same PIO instance first
(lower init priority), the ws2812 program is placed at a lower offset.
The SM then starts inside foreign code, falls through into empty
instruction memory and loops there forever, so the data pin stays
silent without any error being reported.
Store the offset in a data struct of the parent PIO program device and
pass it to pio_sm_init() as the initial PC, with error handling for
exhausted instruction memory. Parent-before-child init order is given
by the devicetree dependency ordinals; a device_is_ready() guard is
added as a safety net.
Signed-off-by: Andreas Petter <andreas@ibpetter.de>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Since commit 37717b229f ("sys: util: rename Z_MIN Z_MAX Z_CLAMP to min
max and clamp"), <zephyr/sys/util.h> unconditionally defines function-
like macros named `min`, `max`, and `clamp` in the global namespace (in
C mode). util.h gets pulled in transitively by very broad headers,
including the POSIX layer's <pthread.h>, so any third-party C code that
uses these names as ordinary identifiers (e.g. XNNPACK's static `clamp`
helper and its public `clamp` struct field) fails to build as soon as
<pthread.h> is included.
Following the approach used by Linux, move the lowercase `min`, `max`,
`min3`, `max3`, and `clamp` macros (and their helpers) into a new
<zephyr/sys/minmax.h> header that has to be included explicitly by
source files that want them. util.h keeps the uppercase MIN/MAX/CLAMP,
so most code is unaffected; only the (much smaller) set of files that
actually use the lowercase variants needs to pick up the new include.
Fixes#107853.
Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
Utilize a code spell-checking tool to scan for and correct spelling errors
in all files within:
- `drivers/interrupt_controller`
- `drivers/led_strip`
- `drivers/lora`
- `drivers/memc`
- `drivers/mfd`
Signed-off-by: Pisit Sawangvonganan <pisit@ndrsolution.com>
Move the non-RGB mapping code into an update function.
This creates simpler functions and makes implementation of LED strip API's
update_channels function simpler.
Signed-off-by: Jeppe Odgaard <jeppe.odgaard@prevas.dk>
I2S bus specification 3.0 [1] updated terms "Master" and "Slave" to
"Controller" and "Target". This rename macros using these terms and
deprecates old names.
[1] https://www.nxp.com/docs/en/user-manual/UM11732.pdf
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
so that time-consuming I/O takes place in the background. This is
especially important when writing to multiple long LED strips.
This commit mostly mirrors what was done in the pl022 driver and the
rpi_pico_pio_spi driver, including the needed DT configuration. DMA will be
used if `CONFIG_DMA` is enabled and proper `tx` channel is defined in the
DT.
The DT overlay I used when testing:
```
&pio0 {
status = "okay";
pio-ws2812 {
compatible = "worldsemi,ws2812-rpi_pico-pio";
status = "okay";
pinctrl-0 = <&ws2812_pio0_default>;
pinctrl-names = "default";
bit-waveform = <3>, <3>, <4>;
/* This device has no tx channel configured so DMA will NOT
* be used. */
ws2812_1: ws2812_1 {
status = "okay";
gpios = <&gpio0 23 GPIO_ACTIVE_HIGH>;
chain-length = <1>;
color-mapping = <LED_COLOR_ID_GREEN
LED_COLOR_ID_RED
LED_COLOR_ID_BLUE>;
reset-delay = <280>;
frequency = <800000>;
};
/* This device has proper tx channel configured so DMA will
* be used. */
ws2812_2: ws2812_2 {
status = "okay";
gpios = <&gpio0 19 GPIO_ACTIVE_HIGH>;
chain-length = <64>;
color-mapping = <LED_COLOR_ID_RED
LED_COLOR_ID_GREEN
LED_COLOR_ID_BLUE>;
reset-delay = <280>;
frequency = <800000>;
dmas = <&dma 1 0 0>;
/* DMA slot will be
* determined by the driver so what's in here
* doesn't matter. */
dma-names = "tx";
};
};
};
&dma {
status = "okay";
};
```
Signed-off-by: Terry Geng <terry@terriex.com>
to guarantee two updates to ws2812 happen not faster than the required
reset time of ws2812. Using `k_usleep` forces a context switching, which
might be unnecessary if two time between update calls are not as frequent
as the reset time (which should be the most of the case anyways).
Signed-off-by: Terry Geng <terry@terriex.com>
Use the "zephyr-keep-sorted-start/stop" comment to have CI check
the alphabetical order of includes, to help reducing the chance
of conflicts while contributing drivers.
Signed-off-by: Josuah Demangeon <me@josuah.net>
Rename the modulino pixels driver to use the official marketing name,
the "smartleds" one was picked incorrectly from the source code of the
on board mcu of the module itself, but that was clearly out of date.
Signed-off-by: Fabio Baltieri <fabiobaltieri@google.com>
This commit introduces a new driver for WS2812 and compatible LED
strips that uses a UART peripheral.
The driver generates the precise, high-speed signal required by the
WS2812 protocol by encoding each data bit into a multi-bit "symbol"
and using a frame-aware packing strategy for transmission:
- Signal Inversion: The UART's TX line must be inverted (tx-invert)
to create the protocol's required idle-low signal. A UART start
bit then generates the initial high pulse of a WS2812 bit.
- Frame-Aware Packing: The driver reuses the UART's hardware-
generated start and stop bits as the first and last bits of the
on-wire symbol. The inner bits of the symbol are packed into the
UART data payload.
This packing scheme imposes a configuration constraint: the total
number of bits in a UART frame (1 start + N data + 1 stop) must be
an integer multiple of the symbol's length (bits-per-symbol).
Signed-off-by: Wai-Hong Tam <waihong@google.com>
In case one defines an RGB led that is bigger than the led_rgb struct,
ws2812_gpio_update_rgb would overflow the buffer it writes to while
iterating. This could lead to crashes, as the code would also support
GRBW (as supposed in one comment).
As a 'proper' fix would require another buffer and therefore more
memory, I added a BUILD_ASSERT to ensure it does not compile.
Signed-off-by: Stefan Kraus <dev@stefankraus.org>
Due to the alias of ptr on pixels, one iterates over the same area
one reads from to set values. Therefore, if the strip is not 'RGB' but
GBR, one would overwrite the pixels 'r' value with the 'g' value in the
first loop, leading to a wrong read afterwards.
By writing to a temporary variable, we have a clean, unmodified copy
of the original values.
Additionally, this removes the dependency on 'LED_STRIP_RGB_SCRATCH',
as the scratch part (that masked most error cases) is not necessary
anymore.
Signed-off-by: Stefan Kraus <dev@stefankraus.org>
The ws2812_spi driver supports both a fast path for 8-bit symbols and
a generic path for other sizes.
This change introduces a devicetree-based, build-time check to
determine if all enabled instances use 8-bit symbols. If so, the
generic path logic is removed from the build.
Signed-off-by: Wai-Hong Tam <waihong@google.com>
This commit introduces a new devicetree property, bits-per-symbol, to
allow the symbol width to be configured from 3 to 8 bits. This change
is particularly beneficial for MCUs that lack DMA for their SPI
peripheral and have a limited hardware FIFO.
This property provides flexibility by allowing developers to select a
slower SPI clock frequency and use the symbol width to scale the
timings to meet strict LED strip requirements, minimizing the risk of
FIFO underruns.
Additionally, using higher-density patterns (e.g., 3-bit or 4-bit
symbols) makes more efficient use of the pixel buffer, which reduces
the RAM footprint required for the LED strip data.
The implementation is optimized with a fast path for the common 8-bit
symbol case, while a generic bit-packing loop handles all other
widths.
Signed-off-by: Wai-Hong Tam <waihong@google.com>
When using DMA for SPI communication, the WS2812 SPI buffer should be
placed in the __nocache section to ensure it resides in uncached memory,
which is typically required for DMA operations.
Signed-off-by: Arthur Gay <arthur.gay@marshmallow.kids>
Add an led_strip driver for the modulino smartleds module. This is a
pluggable I2C board with 8 addressable RGB LEDs
The I2C protocol is implemented on an microcontroller on the modulino
board itself, the firmware for that is open source and can be updated
using an Arduino sketch:
Link: https://github.com/arduino/node_modulino_firmware
Link: https://github.com/arduino-libraries/Modulino
Signed-off-by: Fabio Baltieri <fabiobaltieri@google.com>
Replace occurrences of "RaspberryPi" with "Raspberry Pi" in
documentation, comment blocks etc. Correct the name of "PicoW" to
"Pico W", matching Raspberry Pi's documentation at
https://www.raspberrypi.com/documentation/microcontrollers/pico-series.html .
Signed-off-by: Andrew Featherstone <andrew.featherstone@gmail.com>
end frame is used to supply clock pulses so that data goes to last
LED in the chain. Thus, it depends on the number of LEDs in the chain.
Previously, the number of ones sent into the end frame was
hard-coded and limited the usage of the driver to 64 LEDs in the
strip.
Signed-off-by: Cyril Fougeray <cyril.fougeray@toolsforhumanity.com>
The TLC5971_STRIP config enables if the "ti,tlc5971" node exists.
Also, removing the setting that explicitly enables in the
`tests/drivers/build_all/led_strip` test.
Signed-off-by: TOKITA Hiroshi <tokita.hiroshi@gmail.com>
The current driver contains assembly code which is specific for the nRF51
SOC which makes it incompatible with other SOC's. This patch adds support
for other nRF SOC's as well. The timing is calucated based on the CPU clock
frequency, but can be configured manually as well if needed.
Changes have been verified on a Adafruit Feather nRF52840 Express board,
which contains a single NeoPixel RGB LED. Timings have been verified using
a scope connected to the WS1812 data line.
Signed-off-by: Chaim Zax <chaim.zax@zaxx.pro>
TLC59731 is a 3-Channel, 8-Bit, PWM LED Driver with
TI Single-Wire interface (EasySet) protocol.
Signed-off-by: Javad Rahimipetroudi <javad.rahimipetroudi@mind.be>
Makes the update channels function optional, this is only
implemented in one driver so can be safely omitted from most
drivers
Signed-off-by: Jamie McCrae <spam@helper3000.net>
Checks that the supplied length is valid for the given driver
before passing it to the update function
Signed-off-by: Jamie McCrae <spam@helper3000.net>
Applying the modern way which is adding `default y` and
`depends on DT_HAS_...` to enable configs.
Signed-off-by: TOKITA Hiroshi <tokita.hiroshi@gmail.com>
Removing `choice WS2812_STRIP_DRIVER` to enable the use of multiple
types of WS2812 drivers.
Also, `menuconfig WS2812_STRIP` will be deleted as it does not
correspond to the appropriate settings.
Signed-off-by: TOKITA Hiroshi <tokita.hiroshi@gmail.com>
For sharing pin definition property with `worldsemi,ws2812-gpio`,
rename `output-pin` to `gpios`.
Signed-off-by: TOKITA Hiroshi <tokita.hiroshi@gmail.com>
ws2812-gpio's `in-gpios` property is not used as an input pin.
Renaming it to `gpios` to reflect the actual situation.
Signed-off-by: TOKITA Hiroshi <tokita.hiroshi@gmail.com>
The lower bits of the brightness control registers were erroneously
shifted even though FIELD_PREP already does the shifting. In practice,
the effect is negliglible but of course should be fixed.
Also add missing parenthesis around shifting operations to satisy static
analysis.
Signed-off-by: Mikkel Jakobsen <mikkel.aunsbjerg@escolifesciences.com>
Add driver that based on RPI-PICO's PIO feature for ws2812.
This driver can handle WS2812 or compatible LED strips.
The single PIO node can handle up to 4 strips.
Any pins that can be configured for PIO can be used for strips.
I verified the samples/driver/led_ws2812 sample
working with WS2812(144 pcs) led strip using following patches.
- samples/drivers/led_ws2812/boards/rpi_pico.overlay
```
/ {
aliases {
led-strip = &ws2812;
};
};
&pinctrl {
ws2812_pio0_default: ws2812_pio0_default {
ws2812 {
pinmux = <PIO0_P21>;
};
};
};
&pio0 {
status = "okay";
pio-ws2812 {
compatible = "worldsemi,ws2812-rpi_pico-pio";
status = "okay";
pinctrl-0 = <&ws2812_pio0_default>;
pinctrl-names = "default";
bit-waveform = <3>, <3>, <4>;
ws2812: ws2812 {
status = "okay";
output-pin = <21>;
chain-length = <144>;
color-mapping = <LED_COLOR_ID_GREEN
LED_COLOR_ID_RED
LED_COLOR_ID_BLUE>;
reset-delay = <280>;
frequency = <800000>;
};
};
};
```
- samples/drivers/led_ws2812/boards/rpi_pico.conf
```
CONFIG_WS2812_STRIP_RPI_PICO_PIO=y
```
Signed-off-by: TOKITA Hiroshi <tokita.hiroshi@gmail.com>
The WS2812 LED strip driver does not use a scratch byte, therefore
free up a byte per pixel which was unused except in the GPIO-based
driver whereby it is used
Signed-off-by: Jamie McCrae <spam@helper3000.net>
Modified files (yaml, dts, overlay, and c) which were using spi-cpol
and spi-cpha to be compatible with the new structure.
Signed-off-by: Ali Hozhabri <ali.hozhabri@st.com>
Modify the signature of the k_mem_slab_free() function with a new one,
replacing the old void **mem with void *mem as a parameter.
The following function:
void k_mem_slab_free(struct k_mem_slab *slab, void **mem);
has the wrong signature. mem is only used as a regular pointer, so there
is no need to use a double-pointer. The correct signature should be:
void k_mem_slab_free(struct k_mem_slab *slab, void *mem);
The issue with the current signature, although functional, is that it is
extremely confusing. I myself, a veteran Zephyr developer, was confused
by this parameter when looking at it recently.
All in-tree uses of the function have been adapted.
Fixes#61888.
Signed-off-by: Carles Cufi <carles.cufi@nordicsemi.no>