Skip to content

Commit

Permalink
Add support for RP2040-zero LED
Browse files Browse the repository at this point in the history
  • Loading branch information
dangiu committed Jul 31, 2022
1 parent 06f69a9 commit 7df1d06
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 37 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ add_executable(PicoMemcard)

pico_set_linker_script(PicoMemcard ${CMAKE_SOURCE_DIR}/memmap.ld)
pico_generate_pio_header(PicoMemcard ${CMAKE_CURRENT_LIST_DIR}/psxSPI.pio)
pico_generate_pio_header(PicoMemcard ${CMAKE_CURRENT_LIST_DIR}/ws2812.pio)


# Example source
Expand Down
8 changes: 4 additions & 4 deletions inc/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,20 @@
#define MEMCARD_FILE_NAME "memcard.mcr" // name of memory card file image

/* Board targeted by build */
#define TARGET_PICO
//#define TARGET_RP2040ZERO
#define PICO
//#define RP2040ZERO


/* PSX Interface Pinout */
#ifdef TARGET_PICO
#ifdef PICO
#define PIN_DAT 5
#define PIN_CMD PIN_DAT + 1 // must be immediately after PIN_DAT
#define PIN_SEL PIN_CMD + 1 // must be immediately after PIN_CMD
#define PIN_CLK PIN_SEL + 1 // must be immediately after PIN_SEL
#define PIN_ACK 9
#endif

#ifdef TARGET_RP2040ZERO
#ifdef RP2040ZERO
#define PIN_DAT 9
#define PIN_CMD PIN_DAT + 1 // must be immediately after PIN_DAT
#define PIN_SEL PIN_CMD + 1 // must be immediately after PIN_CMD
Expand Down
5 changes: 1 addition & 4 deletions inc/led.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@

void led_init();
void led_output_sync_status(bool out_of_sync);
void led_blink(int amount, int on_ms, int off_ms);
void led_blink_fast(int amount);
void led_blink_normal(int amount);
void led_blink_slow(int amount);
void led_blink_error(int amount);

#endif
82 changes: 55 additions & 27 deletions src/led.c
Original file line number Diff line number Diff line change
@@ -1,44 +1,72 @@
#include "led.h"
#include "config.h"
#include "hardware/gpio.h"
#include "hardware/pio.h"
#ifdef RP2040ZERO
#include "ws2812.pio.h"
#endif

#ifdef PICO
#define PICO_LED_PIN 25
#endif

void led_init() {
static uint smWs2813;
static uint offsetWs2813;

#ifdef RP2040ZERO
void ws2812_put_pixel(uint32_t pixel_grb) {
pio_sm_put_blocking(pio1, smWs2813, pixel_grb << 8u);
}
void ws2812_put_rgb(uint8_t red, uint8_t green, uint8_t blue) {
uint32_t mask = (green << 16) | (red << 8) | (blue << 0);
ws2812_put_pixel(mask);
}
#endif

void led_init() {
#ifdef RP2040ZERO
offsetWs2813 = pio_add_program(pio1, &ws2812_program);
smWs2813 = pio_claim_unused_sm(pio1, true);
ws2812_program_init(pio1, smWs2813, offsetWs2813, 16, 800000, true);
#endif
}

void led_output_sync_status(bool out_of_sync) {
#ifdef PICO
gpio_put(PICO_LED_PIN, !out_of_sync);
#endif
#ifdef RP2040ZERO
if(out_of_sync)
ws2812_put_rgb(255, 255, 0);
else
ws2812_put_rgb(0, 255, 0);
#endif
}

void led_blink(int amount, int on_ms, int off_ms) {
bool initial_state = gpio_get(PICO_LED_PIN);
if(initial_state) {
/* turn led off if already on */
gpio_put(PICO_LED_PIN, false);
sleep_ms(off_ms);
--amount; // last blink is performed while restoring led state
}
void led_blink_error(int amount) {
/* ensure led is off */
#ifdef PICO
gpio_put(PICO_LED_PIN, false);
#endif
#ifdef RP2040ZERO
ws2812_put_rgb(0, 0, 0);
#endif
sleep_ms(500);
/* start blinking */
for(int i = 0; i < amount; ++i) {
#ifdef PICO
gpio_put(PICO_LED_PIN, true);
sleep_ms(on_ms);
#endif
#ifdef RP2040ZERO
ws2812_put_rgb(255, 0, 0);
#endif
sleep_ms(500);
#ifdef PICO
gpio_put(PICO_LED_PIN, false);
sleep_ms(off_ms);
#endif
#ifdef RP2040ZERO
ws2812_put_rgb(0, 0, 0);
#endif
sleep_ms(500);
}
if(initial_state) {
/* restore led state */
gpio_put(PICO_LED_PIN, true);
}
}

void led_blink_fast(int amount) {
led_blink(amount, 250, 250);
}

void led_blink_normal(int amount) {
led_blink(amount, 500, 500);
}

void led_blink_slow(int amount) {
led_blink(amount, 1000, 1000);
}
4 changes: 2 additions & 2 deletions src/memcard_simulator.c
Original file line number Diff line number Diff line change
Expand Up @@ -325,14 +325,14 @@ _Noreturn int simulate_memory_card() {
status = memory_card_init(&mc);
if(status != MC_OK) {
while(true) {
led_blink_normal(status);
led_blink_error(status);
sleep_ms(2000);
}
}
status = memory_card_import(&mc, MEMCARD_FILE_NAME);
if(status != MC_OK) {
while(true) {
led_blink_normal(status);
led_blink_error(status);
sleep_ms(2000);
}
}
Expand Down
48 changes: 48 additions & 0 deletions ws2812.pio
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
;
; Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
;
; SPDX-License-Identifier: BSD-3-Clause
;

.program ws2812
.side_set 1

.define public T1 2
.define public T2 5
.define public T3 3

.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);
}
%}

0 comments on commit 7df1d06

Please sign in to comment.