diff --git a/CMakeLists.txt b/CMakeLists.txt index 2983e2c..6b2e8d4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,3 +21,11 @@ target_include_directories(rp2040_hid PRIVATE src) # create map/bin/hex/uf2 file in addition to ELF. pico_add_extra_outputs(rp2040_hid) + +add_executable(ledtest + src/ledtest.c +) + +pico_generate_pio_header(ledtest ${CMAKE_CURRENT_LIST_DIR}/src/ledtest.pio) +target_link_libraries(ledtest pico_stdlib hardware_pio) +pico_add_extra_outputs(ledtest) diff --git a/src/ledtest.c b/src/ledtest.c new file mode 100644 index 0000000..feb1ca1 --- /dev/null +++ b/src/ledtest.c @@ -0,0 +1,101 @@ +#include +#include +#include +#include "ledtest.pio.h" + +#define SDO_PIN 21 +#define OE_PIN 20 +#define FCLK_PIN 19 +#define SCLK_PIN 18 + +#define LED1_GPIO 22 + +static void output_byte_manual(uint8_t val) +{ + gpio_put(FCLK_PIN, false); + gpio_put(SCLK_PIN, false); + for (int i = 0; i < 8; ++i) { + sleep_us(1); + gpio_put(SCLK_PIN, false); + gpio_put(SDO_PIN, val & 0x1); + sleep_us(1); + gpio_put(SCLK_PIN, true); + val >>= 1; + } + sleep_us(1); + gpio_put(SCLK_PIN, false); + gpio_put(FCLK_PIN, true); + sleep_us(1); + gpio_put(FCLK_PIN, false); +} + +static PIO pio = pio0; +static uint sm; + +static void output_pio(uint32_t val) +{ + *(volatile uint32_t*)&pio->txf[sm] = val; +} + +void isr_pio0_0(void) +{ + gpio_put(OE_PIN, false); + // only need to enable outputs after first output + pio_set_irq0_source_enabled(pio, PIO_INTR_SM0_LSB, false); +} + +static const uint16_t pattern[] = { + 0x8001, + 0x4002, + 0x2004, + 0x1008, + 0x0810, + 0x0420, + 0x0240, + 0x0180, +}; + +int main() +{ + gpio_init(LED1_GPIO); + gpio_set_dir(LED1_GPIO, GPIO_OUT); + gpio_put(LED1_GPIO, false); + + gpio_init(SDO_PIN); + gpio_set_dir(SDO_PIN, GPIO_OUT); + gpio_put(SDO_PIN, false); + gpio_init(OE_PIN); + gpio_set_dir(OE_PIN, GPIO_OUT); + gpio_put(OE_PIN, true); + gpio_init(FCLK_PIN); + gpio_set_dir(FCLK_PIN, GPIO_OUT); + gpio_put(FCLK_PIN, false); + gpio_init(SCLK_PIN); + gpio_set_dir(SCLK_PIN, GPIO_OUT); + gpio_put(SCLK_PIN, false); + + uint offset = pio_add_program(pio, &ledtest_program); + sm = pio_claim_unused_sm(pio, true); + pio_sm_config c = ledtest_program_get_default_config(offset); + sm_config_set_out_pins(&c, SDO_PIN, 1); + sm_config_set_sideset_pins(&c, SCLK_PIN); + sm_config_set_out_shift(&c, false, false, 16); + sm_config_set_clkdiv(&c, 13); // 130 / 13 / 2 = 5 MHz + pio_sm_set_pindirs_with_mask(pio, sm, (1u << SDO_PIN) | (1u << SCLK_PIN) | (1u << FCLK_PIN), + (1u << SDO_PIN) | (1u << SCLK_PIN) | (1u << FCLK_PIN)); + pio_gpio_init(pio, SDO_PIN); + pio_gpio_init(pio, SCLK_PIN); + pio_gpio_init(pio, FCLK_PIN); + pio_set_irq0_source_enabled(pio, PIO_INTR_SM0_LSB, true); + irq_set_enabled(PIO0_IRQ_0, true); + pio_sm_init(pio, sm, offset, &c); + pio_sm_set_enabled(pio, sm, true); + + int pos = 0; + while (true) { + output_pio(pattern[pos++]<<16); + if (pos >= (sizeof(pattern) / sizeof(pattern[0]))) + pos = 0; + sleep_ms(100); + } +} diff --git a/src/ledtest.pio b/src/ledtest.pio new file mode 100644 index 0000000..c5d96b7 --- /dev/null +++ b/src/ledtest.pio @@ -0,0 +1,10 @@ +.program ledtest +.side_set 2 + +.wrap_target +pull side 0 +loop: +out pins, 1 side 0 +jmp !OSRE loop side 1 +irq 0 side 2 +.wrap