Skip to content

Commit

Permalink
Merge pull request #9610 from jepler/piov2
Browse files Browse the repository at this point in the history
rp2pio: Support PIOv1 (rp2350) features
  • Loading branch information
tannewt authored Sep 16, 2024
2 parents 015a5cf + 2b3fe59 commit 345a829
Show file tree
Hide file tree
Showing 12 changed files with 237 additions and 46 deletions.
146 changes: 122 additions & 24 deletions ports/raspberrypi/bindings/rp2pio/StateMachine.c

Large diffs are not rendered by default.

7 changes: 6 additions & 1 deletion ports/raspberrypi/bindings/rp2pio/StateMachine.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ void common_hal_rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self,
bool auto_push, uint8_t push_threshold, bool in_shift_right,
bool user_interruptible,
int wrap_taget, int wrap,
int offset);
int offset,
int fifo_type,
int mov_status_type,
int mov_status_n);

void common_hal_rp2pio_statemachine_deinit(rp2pio_statemachine_obj_t *self);
bool common_hal_rp2pio_statemachine_deinited(rp2pio_statemachine_obj_t *self);
Expand Down Expand Up @@ -70,3 +73,5 @@ int common_hal_rp2pio_statemachine_get_offset(rp2pio_statemachine_obj_t *self);
int common_hal_rp2pio_statemachine_get_pc(rp2pio_statemachine_obj_t *self);

void common_hal_rp2pio_statemachine_set_interrupt_handler(rp2pio_statemachine_obj_t *self, void (*handler)(void *), void *arg, int mask);

mp_obj_t common_hal_rp2pio_statemachine_get_rxfifo(rp2pio_statemachine_obj_t *self);
6 changes: 5 additions & 1 deletion ports/raspberrypi/common-hal/audiobusio/I2SOut.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,11 @@ void common_hal_audiobusio_i2sout_construct(audiobusio_i2sout_obj_t *self,
false, 32, false, // in settings
false, // Not user-interruptible.
0, -1, // wrap settings
PIO_ANY_OFFSET);
PIO_ANY_OFFSET,
PIO_FIFO_TYPE_DEFAULT,
PIO_MOV_STATUS_DEFAULT,
PIO_MOV_N_DEFAULT
);

self->playing = false;
audio_dma_init(&self->dma);
Expand Down
4 changes: 3 additions & 1 deletion ports/raspberrypi/common-hal/audiobusio/PDMIn.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,9 @@ void common_hal_audiobusio_pdmin_construct(audiobusio_pdmin_obj_t *self,
false, 32, true, // in settings
false, // Not user-interruptible.
0, -1, // wrap settings
PIO_ANY_OFFSET);
PIO_ANY_OFFSET,
PIO_FIFO_TYPE_DEFAULT,
PIO_MOV_STATUS_DEFAULT, PIO_MOV_N_DEFAULT);
uint32_t actual_frequency = common_hal_rp2pio_statemachine_get_frequency(&self->state_machine);
if (actual_frequency < MIN_MIC_CLOCK) {
mp_raise_ValueError(MP_ERROR_TEXT("sampling rate out of range"));
Expand Down
4 changes: 3 additions & 1 deletion ports/raspberrypi/common-hal/floppyio/__init__.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,9 @@ int common_hal_floppyio_flux_readinto(void *buf, size_t len, digitalio_digitalin
false, // Not user-interruptible.
false, // No sideset enable
0, -1, // wrap
PIO_ANY_OFFSET // offset
PIO_ANY_OFFSET, // offset
PIO_FIFO_TYPE_DEFAULT,
PIO_MOV_STATUS_DEFAULT, PIO_MOV_N_DEFAULT
);
if (!ok) {
mp_raise_RuntimeError(MP_ERROR_TEXT("All state machines in use"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,9 @@ void common_hal_imagecapture_parallelimagecapture_construct(imagecapture_paralle
true, 32, true, // in settings
false, // Not user-interruptible.
2, 5, // wrap settings
PIO_ANY_OFFSET);
PIO_ANY_OFFSET,
PIO_FIFO_TYPE_DEFAULT,
PIO_MOV_STATUS_DEFAULT, PIO_MOV_N_DEFAULT);
}

void common_hal_imagecapture_parallelimagecapture_deinit(imagecapture_parallelimagecapture_obj_t *self) {
Expand Down
5 changes: 3 additions & 2 deletions ports/raspberrypi/common-hal/neopixel_write/__init__.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,9 @@ void common_hal_neopixel_write(const digitalio_digitalinout_obj_t *digitalinout,
false, // Not user-interruptible.
false, // No sideset enable
0, -1, // wrap
PIO_ANY_OFFSET // offset
);
PIO_ANY_OFFSET, // offset
PIO_FIFO_TYPE_DEFAULT,
PIO_MOV_STATUS_DEFAULT, PIO_MOV_N_DEFAULT);
if (!ok) {
// Do nothing. Maybe bitbang?
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,9 @@ void common_hal_paralleldisplaybus_parallelbus_construct(paralleldisplaybus_para
false, 32, true, // RX setting we don't use
false, // Not user-interruptible.
0, -1, // wrap settings
PIO_ANY_OFFSET);
PIO_ANY_OFFSET,
PIO_FIFO_TYPE_DEFAULT,
PIO_MOV_STATUS_DEFAULT, PIO_MOV_N_DEFAULT);

common_hal_rp2pio_statemachine_never_reset(&self->state_machine);
}
Expand Down
4 changes: 3 additions & 1 deletion ports/raspberrypi/common-hal/pulseio/PulseIn.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t *self,
true, 32, true, // RX auto pull every 32 bits. shift left to output msb first
false, // Not user-interruptible.
0, -1, // wrap settings
PIO_ANY_OFFSET);
PIO_ANY_OFFSET,
PIO_FIFO_TYPE_DEFAULT,
PIO_MOV_STATUS_DEFAULT, PIO_MOV_N_DEFAULT);

common_hal_pulseio_pulsein_pause(self);

Expand Down
5 changes: 3 additions & 2 deletions ports/raspberrypi/common-hal/rotaryio/IncrementalEncoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,9 @@ void common_hal_rotaryio_incrementalencoder_construct(rotaryio_incrementalencode
false, 32, false, // in settings
false, // Not user-interruptible.
0, MP_ARRAY_SIZE(encoder) - 1, // wrap settings
PIO_ANY_OFFSET
);
PIO_ANY_OFFSET,
PIO_FIFO_TYPE_DEFAULT,
PIO_MOV_STATUS_DEFAULT, PIO_MOV_N_DEFAULT);

// We're guaranteed by the init code that some output will be available promptly
uint8_t quiescent_state;
Expand Down
82 changes: 72 additions & 10 deletions ports/raspberrypi/common-hal/rp2pio/StateMachine.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "shared-bindings/digitalio/Pull.h"
#include "shared-bindings/microcontroller/__init__.h"
#include "shared-bindings/microcontroller/Pin.h"
#include "shared-bindings/memorymap/AddressRange.h"

#include "src/rp2040/hardware_regs/include/hardware/platform_defs.h"
#include "src/rp2_common/hardware_clocks/include/hardware/clocks.h"
Expand Down Expand Up @@ -180,6 +181,33 @@ static uint add_program(PIO pio, const pio_program_t *program, int offset) {
}
}

static enum pio_fifo_join compute_fifo_type(int fifo_type_in, bool rx_fifo, bool tx_fifo) {
if (fifo_type_in != PIO_FIFO_JOIN_AUTO) {
return fifo_type_in;
}
if (!rx_fifo) {
return PIO_FIFO_JOIN_TX;
}
if (!tx_fifo) {
return PIO_FIFO_JOIN_RX;
}
return PIO_FIFO_JOIN_NONE;
}

static int compute_fifo_depth(enum pio_fifo_join join) {
if (join == PIO_FIFO_JOIN_TX || join == PIO_FIFO_JOIN_RX) {
return 8;
}

#if PICO_PIO_VERSION > 0
if (join == PIO_FIFO_JOIN_PUTGET) {
return 0;
}
#endif

return 4;
}

bool rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self,
const uint16_t *program, size_t program_len,
size_t frequency,
Expand All @@ -199,7 +227,9 @@ bool rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self,
bool user_interruptible,
bool sideset_enable,
int wrap_target, int wrap,
int offset
int offset,
int fifo_type,
int mov_status_type, int mov_status_n
) {
// Create a program id that isn't the pointer so we can store it without storing the original object.
uint32_t program_id = ~((uint32_t)program);
Expand Down Expand Up @@ -343,15 +373,27 @@ bool rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self,

sm_config_set_wrap(&c, wrap_target, wrap);
sm_config_set_in_shift(&c, in_shift_right, auto_push, push_threshold);
#if PICO_PIO_VERSION > 0
sm_config_set_in_pin_count(&c, in_pin_count);
#endif

sm_config_set_out_shift(&c, out_shift_right, auto_pull, pull_threshold);
sm_config_set_out_pin_count(&c, out_pin_count);

enum pio_fifo_join join = PIO_FIFO_JOIN_NONE;
if (!rx_fifo) {
join = PIO_FIFO_JOIN_TX;
} else if (!tx_fifo) {
join = PIO_FIFO_JOIN_RX;
sm_config_set_set_pin_count(&c, set_pin_count);

enum pio_fifo_join join = compute_fifo_type(fifo_type, rx_fifo, tx_fifo);

self->fifo_depth = compute_fifo_depth(join);

#if PICO_PIO_VERSION > 0
if (fifo_type == PIO_FIFO_JOIN_TXPUT || fifo_type == PIO_FIFO_JOIN_TXGET) {
self->rxfifo_obj.base.type = &memorymap_addressrange_type;
common_hal_memorymap_addressrange_construct(&self->rxfifo_obj, (uint8_t *)self->pio->rxf_putget[self->state_machine], 4 * sizeof(uint32_t));
} else {
self->rxfifo_obj.base.type = NULL;
}
self->fifo_depth = (join == PIO_FIFO_JOIN_NONE) ? 4 : 8;
#endif

if (rx_fifo) {
self->rx_dreq = pio_get_dreq(self->pio, self->state_machine, false);
Expand All @@ -370,6 +412,11 @@ bool rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self,
self->init_len = init_len;

sm_config_set_fifo_join(&c, join);

// TODO: these arguments
// int mov_status_type, int mov_status_n,
// int set_count, int out_count

self->sm_config = c;

// no DMA allocated
Expand Down Expand Up @@ -519,7 +566,10 @@ void common_hal_rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self,
bool auto_push, uint8_t push_threshold, bool in_shift_right,
bool user_interruptible,
int wrap_target, int wrap,
int offset) {
int offset,
int fifo_type,
int mov_status_type,
int mov_status_n) {

// First, check that all pins are free OR already in use by any PIO if exclusive_pin_use is false.
uint32_t pins_we_use = wait_gpio_mask;
Expand Down Expand Up @@ -585,7 +635,7 @@ void common_hal_rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self,
pull_up |= jmp_mask;
}
if (jmp_pull == PULL_DOWN) {
pull_up |= jmp_mask;
pull_down |= jmp_mask;
}
}
if (initial_pin_direction & (pull_up | pull_down)) {
Expand All @@ -610,7 +660,9 @@ void common_hal_rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self,
true /* claim pins */,
user_interruptible,
sideset_enable,
wrap_target, wrap, offset);
wrap_target, wrap, offset,
fifo_type,
mov_status_type, mov_status_n);
if (!ok) {
mp_raise_RuntimeError(MP_ERROR_TEXT("All state machines in use"));
}
Expand Down Expand Up @@ -1102,6 +1154,16 @@ int common_hal_rp2pio_statemachine_get_pc(rp2pio_statemachine_obj_t *self) {
return pio_sm_get_pc(pio, sm);
}

mp_obj_t common_hal_rp2pio_statemachine_get_rxfifo(rp2pio_statemachine_obj_t *self) {
#if PICO_PIO_VERSION > 0
if (self->rxfifo_obj.base.type) {
return MP_OBJ_FROM_PTR(&self->rxfifo_obj);
}
#endif
return mp_const_none;
}


// Use a compile-time constant for MP_REGISTER_POINTER so the preprocessor will
// not split the expansion across multiple lines.
MP_REGISTER_ROOT_POINTER(mp_obj_t background_pio[enum_NUM_DMA_CHANNELS]);
12 changes: 11 additions & 1 deletion ports/raspberrypi/common-hal/rp2pio/StateMachine.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,13 @@
#include "py/obj.h"

#include "common-hal/microcontroller/Pin.h"
#include "common-hal/memorymap/AddressRange.h"
#include "src/rp2_common/hardware_pio/include/hardware/pio.h"

enum { PIO_ANY_OFFSET = -1 };
enum { PIO_FIFO_JOIN_AUTO = -1, PIO_FIFO_TYPE_DEFAULT = PIO_FIFO_JOIN_AUTO };
enum { PIO_MOV_STATUS_DEFAULT = STATUS_TX_LESSTHAN };
enum { PIO_MOV_N_DEFAULT = 0 };

typedef struct sm_buf_info {
mp_obj_t obj;
Expand Down Expand Up @@ -47,6 +51,9 @@ typedef struct {
sm_buf_info current, once, loop;
int background_stride_in_bytes;
bool dma_completed, byteswap;
#if PICO_PIO_VERSION > 0
memorymap_addressrange_obj_t rxfifo_obj;
#endif
} rp2pio_statemachine_obj_t;

void reset_rp2pio_statemachine(void);
Expand All @@ -70,7 +77,10 @@ bool rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self,
bool claim_pins,
bool interruptible,
bool sideset_enable,
int wrap_target, int wrap, int offset);
int wrap_target, int wrap, int offset,
int fifo_type,
int mov_status_type, int mov_status_n
);

uint8_t rp2pio_statemachine_program_offset(rp2pio_statemachine_obj_t *self);

Expand Down

0 comments on commit 345a829

Please sign in to comment.