8000 rp2pio: Support PIOv1 (rp2350) features by jepler · Pull Request #9610 · adafruit/circuitpython · GitHub
[go: up one dir, main page]

Skip to content

rp2pio: Support PIOv1 (rp2350) features #9610

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Sep 16, 2024
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
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
);
F438 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
10000
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