Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions piolib/examples/apitest.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "piolib.h"

Expand Down Expand Up @@ -107,6 +108,27 @@ int main(int argc, const char **argv) {
pio_remove_program(pio, &dummy_program, offset);
}

// V2 additions
{
pio_sm_config c1 = pio_get_default_sm_config();
pio_sm_config c2 = pio_get_default_sm_config();
sm_config_set_out_pins(&c1, 1, 2);
sm_config_set_out_pin_base(&c2, 1);
sm_config_set_out_pin_count(&c2, 2);
check("sm_config_set_out_pins", !memcmp(&c1, &c2, sizeof(c1)));
sm_config_set_in_pins(&c1, 3);
sm_config_set_in_pin_base(&c2, 3);
sm_config_set_in_pin_count(&c2, 32);
check("sm_config_set_in_pins", !memcmp(&c1, &c2, sizeof(c1)));
sm_config_set_set_pins(&c1, 4, 5);
sm_config_set_set_pin_base(&c2, 4);
sm_config_set_set_pin_count(&c2, 5);
check("sm_config_set_set_pins", !memcmp(&c1, &c2, sizeof(c1)));
sm_config_set_sideset_pins(&c1, 6);
sm_config_set_sideset_pin_base(&c2, 6);
check("sm_config_set_sideset_pins", !memcmp(&c1, &c2, sizeof(c1)));
}

offset = pio_add_program(pio, &echo_program);
c = pio_get_default_sm_config();
sm_config_set_wrap(&c, offset + echo_wrap_target, offset + echo_wrap);
Expand Down
100 changes: 98 additions & 2 deletions piolib/include/piolib.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,14 @@ enum pio_xfer_dir {
PIO_DIR_COUNT
};

enum pio_dma_flags {
PIO_DMA_PREFER_HEAVY = (0 << 0),
PIO_DMA_PREFER_LIGHT = (1 << 0),
PIO_DMA_FORCE_HEAVY = (2 << 0),
PIO_DMA_FORCE_LIGHT = (3 << 0),
PIO_DMA_CYCLIC = (1 << 2),
};

enum pio_sm_flags {
PIO_SM_FLAG_TXSTALL = 0x0001,
PIO_SM_FLAG_RXSTALL = 0x0002,
Expand Down Expand Up @@ -134,6 +142,7 @@ struct pio_chip {
void (*close_instance)(PIO pio);

int (*pio_sm_config_xfer)(PIO pio, uint sm, uint dir, uint buf_size, uint buf_count);
int (*pio_sm_config_xfer_flags)(PIO pio, uint sm, uint dir, uint buf_size, uint buf_count, uint flags);
int (*pio_sm_xfer_data)(PIO pio, uint sm, uint dir, uint data_bytes, void *data);

bool (*pio_can_add_program_at_offset)(PIO pio, const pio_program_t *program, uint offset);
Expand Down Expand Up @@ -237,6 +246,16 @@ struct pio_chip {
void (*pio_interrupt_clear)(PIO pio, uint pio_interrupt_num);
int (*pio_irq_claim)(PIO pio);
uint32_t (*pio_irq_wait)(PIO pio, uint timeout_ms);

/* Additions for V2 SDK */
void (*smc_set_out_pin_base)(PIO pio, pio_sm_config *c, uint out_base);
void (*smc_set_out_pin_count)(PIO pio, pio_sm_config *c, uint out_count);
void (*smc_set_set_pin_base)(PIO pio, pio_sm_config *c, uint set_base);
void (*smc_set_set_pin_count)(PIO pio, pio_sm_config *c, uint set_count);
void (*smc_set_in_pin_base)(PIO pio, pio_sm_config *c, uint in_base);
void (*smc_set_in_pin_count)(PIO pio, pio_sm_config *c, uint in_count);
void (*smc_set_sideset_pin_base)(PIO pio, pio_sm_config *c, uint sideset_base);
void (*smc_set_sideset_pin_count)(PIO pio, pio_sm_config *c, uint sideset_count);
};

struct pio_instance {
Expand Down Expand Up @@ -265,46 +284,69 @@ irq_handler_t irq_get_handler(uint num);
void irq_set_enabled(uint num, bool enabled);
bool irq_is_enabled(uint num);

static inline void check_pio_param(__unused PIO pio)
{
valid_params_if(PIO, pio_get_index(pio) >= 0);
}

static inline PIO pio_get_instance(uint instance)
{
return pio_open_helper(instance);
}

static inline uint pio_get_funcsel(PIO pio) {
check_pio_param(pio);
return GPIO_FUNC_PIO0;
}

static inline void pio_error(PIO pio, const char *msg)
{
check_pio_param(pio);
pio->error = true;
if (pio->errors_are_fatal)
pio_panic(msg);
}

static inline bool pio_get_error(PIO pio)
{
check_pio_param(pio);
return pio->error;
}

static inline void pio_clear_error(PIO pio)
{
check_pio_param(pio);
pio->error = false;
}

static inline void pio_enable_fatal_errors(PIO pio, bool enable)
{
check_pio_param(pio);
pio->errors_are_fatal = enable;
}

static inline uint pio_get_sm_count(PIO pio)
{
check_pio_param(pio);
return pio->chip->sm_count;
}

static inline uint pio_get_instruction_count(PIO pio)
{
check_pio_param(pio);
return pio->chip->instr_count;
}

static inline uint pio_get_fifo_depth(PIO pio)
{
check_pio_param(pio);
return pio->chip->fifo_depth;
}

static inline void check_pio_param(__unused PIO pio)
static inline uint pio_get_gpio_base(PIO pio)
{
valid_params_if(PIO, pio_get_index(pio) >= 0);
check_pio_param(pio);
return 0;
}

static inline int pio_sm_config_xfer(PIO pio, uint sm, uint dir, uint buf_size, uint buf_count)
Expand All @@ -313,6 +355,12 @@ static inline int pio_sm_config_xfer(PIO pio, uint sm, uint dir, uint buf_size,
return pio->chip->pio_sm_config_xfer(pio, sm, dir, buf_size, buf_count);
}

static inline int pio_sm_config_xfer_flags(PIO pio, uint sm, uint dir, uint buf_size, uint buf_count, uint flags)
{
check_pio_param(pio);
return pio->chip->pio_sm_config_xfer_flags(pio, sm, dir, buf_size, buf_count, flags);
}

static inline int pio_sm_xfer_data(PIO pio, uint sm, uint dir, uint data_bytes, void *data)
{
check_pio_param(pio);
Expand Down Expand Up @@ -796,6 +844,54 @@ static inline void sm_config_set_sideset(pio_sm_config *c, uint bit_count, bool
pio->chip->smc_set_sideset(pio, c, bit_count, optional, pindirs);
}

static inline void sm_config_set_out_pin_base(pio_sm_config *c, uint out_base)
{
PIO pio = pio_get_current();
pio->chip->smc_set_out_pin_base(pio, c, out_base);
}

static inline void sm_config_set_out_pin_count(pio_sm_config *c, uint out_count)
{
PIO pio = pio_get_current();
pio->chip->smc_set_out_pin_count(pio, c, out_count);
}

static inline void sm_config_set_set_pin_base(pio_sm_config *c, uint set_base)
{
PIO pio = pio_get_current();
pio->chip->smc_set_set_pin_base(pio, c, set_base);
}

static inline void sm_config_set_set_pin_count(pio_sm_config *c, uint set_count)
{
PIO pio = pio_get_current();
pio->chip->smc_set_set_pin_count(pio, c, set_count);
}

static inline void sm_config_set_in_pin_base(pio_sm_config *c, uint in_base)
{
PIO pio = pio_get_current();
pio->chip->smc_set_in_pin_base(pio, c, in_base);
}

static inline void sm_config_set_in_pin_count(pio_sm_config *c, uint in_count)
{
PIO pio = pio_get_current();
pio->chip->smc_set_in_pin_count(pio, c, in_count);
}

static inline void sm_config_set_sideset_pin_base(pio_sm_config *c, uint sideset_base)
{
PIO pio = pio_get_current();
pio->chip->smc_set_sideset_pin_base(pio, c, sideset_base);
}

static inline void sm_config_set_sideset_pin_count(pio_sm_config *c, uint sideset_count)
{
PIO pio = pio_get_current();
pio->chip->smc_set_sideset_pin_count(pio, c, sideset_count);
}

static inline void sm_config_set_clkdiv_int_frac(pio_sm_config *c, uint16_t div_int, uint8_t div_frac)
{
PIO pio = pio_get_current();
Expand Down
15 changes: 15 additions & 0 deletions piolib/include/rp1_pio_if.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@
#define RP1_PIO_DIR_FROM_SM 1
#define RP1_PIO_DIR_COUNT 2

#define RP1_PIO_SM_CONFIG_XFER_FL_DMA_PREFER_HEAVY (0 << 0)
#define RP1_PIO_SM_CONFIG_XFER_FL_DMA_PREFER_LIGHT (1 << 0)
#define RP1_PIO_SM_CONFIG_XFER_FL_DMA_FORCE_HEAVY (2 << 0)
#define RP1_PIO_SM_CONFIG_XFER_FL_DMA_FORCE_LIGHT (3 << 0)
#define RP1_PIO_SM_CONFIG_XFER_FL_DMA_CYCLIC (1 << 2)

typedef struct {
uint32_t clkdiv;
uint32_t execctrl;
Expand Down Expand Up @@ -183,6 +189,14 @@ struct rp1_pio_sm_config_xfer32_args {
uint32_t buf_count;
};

struct rp1_pio_sm_config_xfer_v2_args {
uint16_t sm;
uint16_t dir;
uint32_t flags;
uint32_t buf_size;
uint32_t buf_count;
};

struct rp1_pio_sm_xfer_data_args {
uint16_t sm;
uint16_t dir;
Expand Down Expand Up @@ -242,6 +256,7 @@ struct rp1_pio_interrupt_clear_args {
#define PIO_IOC_SM_XFER_DATA _IOW(PIO_IOC_MAGIC, 1, struct rp1_pio_sm_xfer_data_args)
#define PIO_IOC_SM_XFER_DATA32 _IOW(PIO_IOC_MAGIC, 2, struct rp1_pio_sm_xfer_data32_args)
#define PIO_IOC_SM_CONFIG_XFER32 _IOW(PIO_IOC_MAGIC, 3, struct rp1_pio_sm_config_xfer32_args)
#define PIO_IOC_SM_CONFIG_XFER_V2 _IOW(PIO_IOC_MAGIC, 4, struct rp1_pio_sm_config_xfer_v2_args)

#define PIO_IOC_READ_HW _IOW(PIO_IOC_MAGIC, 8, struct rp1_access_hw_args)
#define PIO_IOC_WRITE_HW _IOW(PIO_IOC_MAGIC, 9, struct rp1_access_hw_args)
Expand Down
80 changes: 80 additions & 0 deletions piolib/pio_rp1.c
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,13 @@ static int rp1_pio_sm_config_xfer(PIO pio, uint sm, uint dir, uint buf_size, uin
return err;
}

static int rp1_pio_sm_config_xfer_flags(PIO pio, uint sm, uint dir, uint buf_size, uint buf_count, uint flags)
{
struct rp1_pio_sm_config_xfer_v2_args args = { .sm = sm, .dir = dir, .buf_size = buf_size, .buf_count = buf_count, .flags = flags };
check_sm_param(sm);
return rp1_ioctl(pio, PIO_IOC_SM_CONFIG_XFER_V2, &args);
}

static int rp1_pio_sm_xfer_data(PIO pio, uint sm, uint dir, uint data_bytes, void *data)
{
struct rp1_pio_sm_xfer_data_args args = { .sm = sm, .dir = dir, .data_bytes = data_bytes, .rsvd = 0, .data = data };
Expand Down Expand Up @@ -669,6 +676,68 @@ static void rp1_smc_set_sideset_pins(PIO, pio_sm_config *config, uint sideset_ba
(sideset_base << PROC_PIO_SM0_PINCTRL_SIDESET_BASE_LSB);
}

static void rp1_smc_set_out_pin_base(PIO, pio_sm_config *config, uint out_base)
{
smc_to_rp1(config, c);
valid_params_if(PIO, out_base < RP1_PIO_GPIO_COUNT);
c->pinctrl = (c->pinctrl & ~PROC_PIO_SM0_PINCTRL_OUT_BASE_BITS) |
(out_base << PROC_PIO_SM0_PINCTRL_OUT_BASE_LSB);
}

static void rp1_smc_set_out_pin_count(PIO, pio_sm_config *config, uint out_count)
{
smc_to_rp1(config, c);
valid_params_if(PIO, out_count <= RP1_PIO_GPIO_COUNT);
c->pinctrl = (c->pinctrl & ~PROC_PIO_SM0_PINCTRL_OUT_COUNT_BITS) |
(out_count << PROC_PIO_SM0_PINCTRL_OUT_COUNT_LSB);
}

static void rp1_smc_set_set_pin_base(PIO, pio_sm_config *config, uint set_base)
{
smc_to_rp1(config, c);
valid_params_if(PIO, set_base < RP1_PIO_GPIO_COUNT);
c->pinctrl = (c->pinctrl & ~PROC_PIO_SM0_PINCTRL_SET_BASE_BITS) |
(set_base << PROC_PIO_SM0_PINCTRL_SET_BASE_LSB);
}

static void rp1_smc_set_set_pin_count(PIO, pio_sm_config *config, uint set_count)
{
smc_to_rp1(config, c);
valid_params_if(PIO, set_count <= 5);
c->pinctrl = (c->pinctrl & ~PROC_PIO_SM0_PINCTRL_SET_COUNT_BITS) |
(set_count << PROC_PIO_SM0_PINCTRL_SET_COUNT_LSB);
}

static void rp1_smc_set_in_pin_base(PIO, pio_sm_config *config, uint in_base)
{
smc_to_rp1(config, c);
valid_params_if(PIO, in_base < RP1_PIO_GPIO_COUNT);
c->pinctrl = (c->pinctrl & ~PROC_PIO_SM0_PINCTRL_IN_BASE_BITS) |
(in_base << PROC_PIO_SM0_PINCTRL_IN_BASE_LSB);
}

static void rp1_smc_set_in_pin_count(PIO, __unused pio_sm_config *config, __unused uint in_count)
{
/* RP1 PIO has no IN_COUNT field - the count is fixed at 32 */
valid_params_if(PIO, in_count == 32);
}

static void rp1_smc_set_sideset_pin_base(PIO, pio_sm_config *config, uint sideset_base)
{
smc_to_rp1(config, c);
valid_params_if(PIO, sideset_base < RP1_PIO_GPIO_COUNT);
c->pinctrl = (c->pinctrl & ~PROC_PIO_SM0_PINCTRL_SIDESET_BASE_BITS) |
(sideset_base << PROC_PIO_SM0_PINCTRL_SIDESET_BASE_LSB);
}

static void rp1_smc_set_sideset_pin_count(PIO, pio_sm_config *config, uint sideset_count)
{
smc_to_rp1(config, c);
valid_params_if(PIO, sideset_count <= 5);
c->pinctrl = (c->pinctrl & ~PROC_PIO_SM0_PINCTRL_SIDESET_COUNT_BITS) |
(sideset_count << PROC_PIO_SM0_PINCTRL_SIDESET_COUNT_LSB);
}

static void rp1_smc_set_sideset(PIO, pio_sm_config *config, uint bit_count, bool optional, bool pindirs)
{
smc_to_rp1(config, c);
Expand Down Expand Up @@ -990,6 +1059,7 @@ DECLARE_PIO_CHIP(rp1) {
.close_instance = rp1_close_instance,

.pio_sm_config_xfer = rp1_pio_sm_config_xfer,
.pio_sm_config_xfer_flags = rp1_pio_sm_config_xfer_flags,
.pio_sm_xfer_data = rp1_pio_sm_xfer_data,

.pio_can_add_program_at_offset = rp1_pio_can_add_program_at_offset,
Expand Down Expand Up @@ -1075,6 +1145,16 @@ DECLARE_PIO_CHIP(rp1) {
.smc_set_out_special = rp1_smc_set_out_special,
.smc_set_mov_status = rp1_smc_set_mov_status,

/* Additions for V2 SDK */
.smc_set_out_pin_base = rp1_smc_set_out_pin_base,
.smc_set_out_pin_count = rp1_smc_set_out_pin_count,
.smc_set_set_pin_base = rp1_smc_set_set_pin_base,
.smc_set_set_pin_count = rp1_smc_set_set_pin_count,
.smc_set_in_pin_base = rp1_smc_set_in_pin_base,
.smc_set_in_pin_count = rp1_smc_set_in_pin_count,
.smc_set_sideset_pin_base = rp1_smc_set_sideset_pin_base,
.smc_set_sideset_pin_count = rp1_smc_set_sideset_pin_count,

.clock_get_hz = rp1_clock_get_hz,

.pio_gpio_init = rp1_pio_gpio_init,
Expand Down
Loading