Initial Release

This commit is contained in:
graham sanderson
2021-01-20 10:49:34 -06:00
commit 46078742c7
245 changed files with 21157 additions and 0 deletions

15
pio/apa102/CMakeLists.txt Normal file
View File

@@ -0,0 +1,15 @@
add_executable(pio_apa102)
pico_generate_pio_header(pio_apa102 ${CMAKE_CURRENT_LIST_DIR}/apa102.pio)
target_sources(pio_apa102 PRIVATE apa102.c)
target_link_libraries(pio_apa102 PRIVATE
pico_stdlib
hardware_pio
)
pico_add_extra_outputs(pio_apa102)
# add url via pico_set_program_url
example_auto_set_url(pio_apa102)

69
pio/apa102/apa102.c Normal file
View File

@@ -0,0 +1,69 @@
/**
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdio.h>
#include <math.h>
#include "pico/stdlib.h"
#include "hardware/pio.h"
#include "apa102.pio.h"
#define PIN_CLK 2
#define PIN_DIN 3
#define N_LEDS 150
#define SERIAL_FREQ (5 * 1000 * 1000)
// Global brightness value 0->31
#define BRIGHTNESS 16
void put_start_frame(PIO pio, uint sm) {
pio_sm_put_blocking(pio, sm, 0u);
}
void put_end_frame(PIO pio, uint sm) {
pio_sm_put_blocking(pio, sm, ~0u);
}
void put_rgb888(PIO pio, uint sm, uint8_t r, uint8_t g, uint8_t b) {
pio_sm_put_blocking(pio, sm,
0x7 << 29 | // magic
(BRIGHTNESS & 0x1f) << 24 | // global brightness parameter
(uint32_t) b << 16 |
(uint32_t) g << 8 |
(uint32_t) r << 0
);
}
#define TABLE_SIZE (1 << 8)
uint8_t wave_table[TABLE_SIZE];
int main() {
stdio_init_all();
PIO pio = pio0;
uint sm = 0;
uint offset = pio_add_program(pio, &apa102_mini_program);
apa102_mini_program_init(pio, sm, offset, SERIAL_FREQ, PIN_CLK, PIN_DIN);
for (int i = 0; i < TABLE_SIZE; ++i)
wave_table[i] = powf(sinf(i * M_PI / TABLE_SIZE), 5.f) * 255;
uint t = 0;
while (true) {
put_start_frame(pio, sm);
for (int i = 0; i < N_LEDS; ++i) {
put_rgb888(pio, sm,
wave_table[(i + t) % TABLE_SIZE],
wave_table[(2 * i + 3 * 2) % TABLE_SIZE],
wave_table[(3 * i + 4 * t) % TABLE_SIZE]
);
}
put_end_frame(pio, sm);
sleep_ms(10);
++t;
}
}

89
pio/apa102/apa102.pio Normal file
View File

@@ -0,0 +1,89 @@
;
; Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
;
; SPDX-License-Identifier: BSD-3-Clause
;
.program apa102_mini
.side_set 1
; This is really just a TX-only SPI. CLK is side-set pin 0, DIN is OUT pin 0.
; Autopull enabled, threshold 32.
;
; Every word (32 bits) written to the FIFO will be shifted out in its entirety, MSB-first.
out pins, 1 side 0 ; Stall here when no data (still asserts clock low)
nop side 1
% c-sdk {
#include "hardware/clocks.h"
static inline void apa102_mini_program_init(PIO pio, uint sm, uint offset,
uint baud, uint pin_clk, uint pin_din) {
pio_sm_set_pins_with_mask(pio, sm, 0, (1u << pin_clk) | (1u << pin_din));
pio_sm_set_pindirs_with_mask(pio, sm, ~0u, (1u << pin_clk) | (1u << pin_din));
pio_gpio_init(pio, pin_clk);
pio_gpio_init(pio, pin_din);
pio_sm_config c = apa102_mini_program_get_default_config(offset);
sm_config_set_out_pins(&c, pin_din, 1);
sm_config_set_sideset_pins(&c, pin_clk);
// Shift to right, autopull with threshold 32
sm_config_set_out_shift(&c, false, true, 32);
// Deeper FIFO as we're not doing any RX
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX);
// We transmit 1 bit every 2 execution cycles
float div = (float)clock_get_hz(clk_sys) / (2 * baud);
sm_config_set_clkdiv(&c, div);
pio_sm_init(pio, sm, offset, &c);
pio_sm_set_enabled(pio, sm, true);
}
%}
.program apa102_rgb555
; Alternative program to unpack two RGB555 pixels from a FIFO word and transmit.
; This makes it easier to DMA large buffers without processor involvement.
; OSR: shift to right
; ISR: shift to right
; To set brightness, set ISR to bit-reverse of 5-bit brightness,
; followed by 111. (00...00_b0b1b2b3b4_111)
; DMA pixel format is 0RRRRRGGGGGBBBBB x2 (15 bpp, 2px per FIFO word)
; APA102 command structure:
; increasing time ---->>
; | byte 3 | byte 2 | byte 1 | byte 0 |
; |7 0|7 0|7 0|7 0|
; -------------------------------------
; Pixel |111bbbbb|BBBBBBBB|GGGGGGGG|RRRRRRRR|
; Start Frame |00000000|00000000|00000000|00000000|
; Stop Frame |11111111|11111111|11111111|11111111|
.wrap_target
public pixel_out:
; pixel_out formats an APA102 colour command in the ISR.
; bit_run shifts 32 bits out of the ISR, with clock.
pull ifempty
set x, 2
colour_loop:
in osr, 5
out null, 5
in null, 3
jmp x-- colour_loop
in y, 8
mov isr, ::isr ; reverse for msb-first wire order
out null, 1
public bit_run:
; in isr, n rotates ISR by n bits (right rotation only)
; Use this to perform out shifts from ISR, via mov pins
set x, 31
bit_out:
set pins, 0
mov pins, isr [6]
set pins, 1
in isr, 1 [6]
jmp x-- bit_out
.wrap