Skip to content

Instantly share code, notes, and snippets.

@palaniraja
Created September 7, 2025 18:25
Show Gist options
  • Save palaniraja/23b85c8edc73bb8a783a545de9e80c27 to your computer and use it in GitHub Desktop.
Save palaniraja/23b85c8edc73bb8a783a545de9e80c27 to your computer and use it in GitHub Desktop.
Waveshare RP2040-Zero C sample code
# Generated Cmake Pico project file
cmake_minimum_required(VERSION 3.13)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
# initalize pico_sdk from installed location
# (note this can come from environment, CMake cache etc)
#set(PICO_SDK_PATH "D:/Raspberry/Pico-Code/pico-sdk")
# Pull in Raspberry Pi Pico SDK (must be before project)
include(pico_sdk_import.cmake)
project(RP2040_Zero_Test C CXX ASM)
# Initialise the Raspberry Pi Pico SDK
pico_sdk_init()
# Add executable. Default name is the project name, version 0.1
add_executable(RP2040_Zero_Test RP2040_Zero_Test.c )
pico_generate_pio_header(RP2040_Zero_Test ${CMAKE_CURRENT_LIST_DIR}/ws2812.pio OUTPUT_DIR ${CMAKE_CURRENT_LIST_DIR}/generated)
pico_set_program_name(RP2040_Zero_Test "RP2040_Zero_Test")
pico_set_program_version(RP2040_Zero_Test "0.1")
pico_enable_stdio_uart(RP2040_Zero_Test 0)
pico_enable_stdio_usb(RP2040_Zero_Test 0)
# Add the standard library to the build
target_link_libraries(RP2040_Zero_Test pico_stdlib)
# Add any user requested libraries
target_link_libraries(RP2040_Zero_Test
hardware_pio
)
pico_add_extra_outputs(RP2040_Zero_Test)
#include <stdio.h>
#include <stdlib.h>
#include "pico/stdlib.h"
#include "hardware/pio.h"
#include "hardware/clocks.h"
#include "ws2812.pio.h"
void put_pixel(uint32_t pixel_grb)
{
pio_sm_put_blocking(pio0, 0, pixel_grb << 8u);
}
void put_rgb(uint8_t red, uint8_t green, uint8_t blue)
{
uint32_t mask = (green << 16) | (red << 8) | (blue << 0);
put_pixel(mask);
}
int main()
{
//set_sys_clock_48();
stdio_init_all();
PIO pio = pio0;
int sm = 0;
uint offset = pio_add_program(pio, &ws2812_program);
uint8_t cnt = 0;
puts("RP2040-Zero WS2812 Test");
ws2812_program_init(pio, sm, offset, 16, 800000, true);
while (1)
{
for (cnt = 0; cnt < 0xff; cnt++)
{
put_rgb(cnt, 0xff - cnt, 0);
sleep_ms(3);
}
for (cnt = 0; cnt < 0xff; cnt++)
{
put_rgb(0xff - cnt, 0, cnt);
sleep_ms(3);
}
for (cnt = 0; cnt < 0xff; cnt++)
{
put_rgb(0, cnt, 0xff - cnt);
sleep_ms(3);
}
}
}
;
; Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
;
; SPDX-License-Identifier: BSD-3-Clause
;
.pio_version 0 // only requires PIO version 0
.program ws2812
.side_set 1
; The following constants are selected for broad compatibility with WS2812,
; WS2812B, and SK6812 LEDs. Other constants may support higher bandwidths for
; specific LEDs, such as (7,10,8) for WS2812B LEDs.
.define public T1 3
.define public T2 3
.define public T3 4
.lang_opt python sideset_init = pico.PIO.OUT_HIGH
.lang_opt python out_init = pico.PIO.OUT_HIGH
.lang_opt python out_shiftdir = 1
.wrap_target
bitloop:
out x, 1 side 0 [T3 - 1] ; Side-set still takes place when instruction stalls
jmp !x do_zero side 1 [T1 - 1] ; Branch on the bit we shifted out. Positive pulse
do_one:
jmp bitloop side 1 [T2 - 1] ; Continue driving high, for a long pulse
do_zero:
nop side 0 [T2 - 1] ; Or drive low, for a short pulse
.wrap
% c-sdk {
#include "hardware/clocks.h"
static inline void ws2812_program_init(PIO pio, uint sm, uint offset, uint pin, float freq, bool rgbw) {
pio_gpio_init(pio, pin);
pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, true);
pio_sm_config c = ws2812_program_get_default_config(offset);
sm_config_set_sideset_pins(&c, pin);
sm_config_set_out_shift(&c, false, true, rgbw ? 32 : 24);
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX);
int cycles_per_bit = ws2812_T1 + ws2812_T2 + ws2812_T3;
float div = clock_get_hz(clk_sys) / (freq * cycles_per_bit);
sm_config_set_clkdiv(&c, div);
pio_sm_init(pio, sm, offset, &c);
pio_sm_set_enabled(pio, sm, true);
}
%}
.program ws2812_parallel
.define public T1 3
.define public T2 3
.define public T3 4
.wrap_target
out x, 32
mov pins, !null [T1-1]
mov pins, x [T2-1]
mov pins, null [T3-2]
.wrap
% c-sdk {
#include "hardware/clocks.h"
static inline void ws2812_parallel_program_init(PIO pio, uint sm, uint offset, uint pin_base, uint pin_count, float freq) {
for(uint i=pin_base; i<pin_base+pin_count; i++) {
pio_gpio_init(pio, i);
}
pio_sm_set_consecutive_pindirs(pio, sm, pin_base, pin_count, true);
pio_sm_config c = ws2812_parallel_program_get_default_config(offset);
sm_config_set_out_shift(&c, true, true, 32);
sm_config_set_out_pins(&c, pin_base, pin_count);
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX);
int cycles_per_bit = ws2812_parallel_T1 + ws2812_parallel_T2 + ws2812_parallel_T3;
float div = clock_get_hz(clk_sys) / (freq * cycles_per_bit);
sm_config_set_clkdiv(&c, div);
pio_sm_init(pio, sm, offset, &c);
pio_sm_set_enabled(pio, sm, true);
}
%}
@palaniraja
Copy link
Author

I do not remember where I got this link from - https://www.waveshare.com/w/upload/5/58/RP2040-Zero.zip it is definitely not from their wiki.

posting the relevant code here in case i need to refer later. My rp2040-blinky is based on this sample code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment