StateMachine: add swap flag

Always use DMA if swap flag is enabled.

Improve docs a bit
This commit is contained in:
Jeff Epler 2022-05-06 15:18:59 -05:00
parent 23c0fc8354
commit b482a732c6
No known key found for this signature in database
GPG Key ID: D5BF15AB975AB4DE
10 changed files with 74 additions and 36 deletions

View File

@ -1540,6 +1540,10 @@ msgstr ""
msgid "Mismatched data size"
msgstr ""
#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
msgid "Mismatched swap flag"
msgstr ""
#: ports/mimxrt10xx/common-hal/busio/SPI.c ports/stm/common-hal/busio/SPI.c
msgid "Missing MISO or MOSI Pin"
msgstr ""
@ -2033,7 +2037,7 @@ msgstr ""
msgid "RNG Init Error"
msgstr ""
#: ports/nrf/common-hal/busio/UART.c ports/raspberrypi/common-hal/busio/UART.c
#: ports/nrf/common-hal/busio/UART.c
msgid "RS485 Not yet supported on this device"
msgstr ""

View File

@ -378,7 +378,7 @@ STATIC mp_obj_t rp2pio_statemachine_stop(mp_obj_t self_obj) {
}
MP_DEFINE_CONST_FUN_OBJ_1(rp2pio_statemachine_stop_obj, rp2pio_statemachine_stop);
//| def write(self, buffer: ReadableBuffer, *, start: int = 0, end: Optional[int] = None) -> None:
//| def write(self, buffer: ReadableBuffer, *, start: int = 0, end: Optional[int] = None, swap bool = False) -> None:
//| """Write the data contained in ``buffer`` to the state machine. If the buffer is empty, nothing happens.
//|
//| Writes to the FIFO will match the input buffer's element size. For example, bytearray elements
@ -391,14 +391,16 @@ MP_DEFINE_CONST_FUN_OBJ_1(rp2pio_statemachine_stop_obj, rp2pio_statemachine_stop
//| :param ~circuitpython_typing.ReadableBuffer buffer: Write out the data in this buffer
//| :param int start: Start of the slice of ``buffer`` to write out: ``buffer[start:end]``
//| :param int end: End of the slice; this index is not included. Defaults to ``len(buffer)``"""
//| :param bool swap: For 2- and 4-byte elements, swap the byte order"""
//| ...
//|
STATIC mp_obj_t rp2pio_statemachine_write(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_buffer, ARG_start, ARG_end };
enum { ARG_buffer, ARG_start, ARG_end, ARG_swap };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_buffer, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
{ MP_QSTR_start, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} },
{ MP_QSTR_swap, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
};
rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
check_for_deinit(self);
@ -420,7 +422,7 @@ STATIC mp_obj_t rp2pio_statemachine_write(size_t n_args, const mp_obj_t *pos_arg
mp_raise_ValueError(translate("Buffer elements must be 4 bytes long or less"));
}
bool ok = common_hal_rp2pio_statemachine_write(self, ((uint8_t *)bufinfo.buf) + start, length, stride_in_bytes);
bool ok = common_hal_rp2pio_statemachine_write(self, ((uint8_t *)bufinfo.buf) + start, length, stride_in_bytes, args[ARG_swap].u_bool);
if (mp_hal_is_interrupted()) {
return mp_const_none;
}
@ -431,7 +433,7 @@ STATIC mp_obj_t rp2pio_statemachine_write(size_t n_args, const mp_obj_t *pos_arg
}
MP_DEFINE_CONST_FUN_OBJ_KW(rp2pio_statemachine_write_obj, 2, rp2pio_statemachine_write);
//| def background_write(self, once: Optional[ReadableBuffer]=None, *, loop: Optional[ReadableBuffer]=None) -> None:
//| def background_write(self, once: Optional[ReadableBuffer]=None, *, loop: Optional[ReadableBuffer]=None, swap: bool=False) -> None:
//| """Write data to the TX fifo in the background, with optional looping.
//|
//| First, if any previous ``once`` or ``loop`` buffer has not been started, this function blocks until they have.
@ -459,8 +461,13 @@ MP_DEFINE_CONST_FUN_OBJ_KW(rp2pio_statemachine_write_obj, 2, rp2pio_statemachine
//| where a change in duty cycle requires a special transitional buffer to be used exactly once. Most
//| use cases will probably only use one of ``once`` or ``loop``.
//|
//| Having neither ``once`` nor ``loop`` terminates an existing
//| background looping write after exactly a whole loop. This is in contrast to
//| `stop_background_write, which interrupts an ongoing DMA operation.
//|
//| :param ~Optional[circuitpython_typing.ReadableBuffer] once: Data to be written once
//| :param ~Optional[circuitpython_typing.ReadableBuffer] loop: Data to be written repeatedly
//| :param bool swap: For 2- and 4-byte elements, swap the byte order"""
//| """
//| ...
//|
@ -483,10 +490,11 @@ STATIC void fill_buf_info(sm_buf_info *info, mp_obj_t obj, size_t *stride_in_byt
}
STATIC mp_obj_t rp2pio_statemachine_background_write(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_once, ARG_loop };
enum { ARG_once, ARG_loop, ARG_swap };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_once, MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_loop, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} },
{ MP_QSTR_swap, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
};
rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
check_for_deinit(self);
@ -502,7 +510,7 @@ STATIC mp_obj_t rp2pio_statemachine_background_write(size_t n_args, const mp_obj
return mp_const_none;
}
bool ok = common_hal_rp2pio_statemachine_background_write(self, &once_info, &loop_info, stride_in_bytes);
bool ok = common_hal_rp2pio_statemachine_background_write(self, &once_info, &loop_info, stride_in_bytes, args[ARG_swap].u_bool);
if (mp_hal_is_interrupted()) {
return mp_const_none;
@ -515,7 +523,9 @@ STATIC mp_obj_t rp2pio_statemachine_background_write(size_t n_args, const mp_obj
MP_DEFINE_CONST_FUN_OBJ_KW(rp2pio_statemachine_background_write_obj, 1, rp2pio_statemachine_background_write);
//| def stop_background_write(self) -> None:
//| """Immediately stop a background write, if one is in progress. Items already in the TX FIFO are not affected."""
//| """Immediately stop a background write, if one is in progress. Any
//| DMA in progress is halted, but items already in the TX FIFO are not
//| affected."""
//|
STATIC mp_obj_t rp2pio_statemachine_obj_stop_background_write(mp_obj_t self_in) {
rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(self_in);
@ -567,7 +577,7 @@ const mp_obj_property_t rp2pio_statemachine_pending_obj = {
MP_ROM_NONE},
};
//| def readinto(self, buffer: WriteableBuffer, *, start: int = 0, end: Optional[int] = None) -> None:
//| def readinto(self, buffer: WriteableBuffer, *, start: int = 0, end: Optional[int] = None, bool swap) -> None:
//| """Read into ``buffer``. If the number of bytes to read is 0, nothing happens. The buffer
//| includes any data added to the fifo even if it was added before this was called.
//|
@ -581,16 +591,18 @@ const mp_obj_property_t rp2pio_statemachine_pending_obj = {
//|
//| :param ~circuitpython_typing.WriteableBuffer buffer: Read data into this buffer
//| :param int start: Start of the slice of ``buffer`` to read into: ``buffer[start:end]``
//| :param int end: End of the slice; this index is not included. Defaults to ``len(buffer)``"""
//| :param int end: End of the slice; this index is not included. Defaults to ``len(buffer)``
//| :param bool swap: For 2- and 4-byte elements, swap the byte order"""
//| ...
//|
STATIC mp_obj_t rp2pio_statemachine_readinto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_buffer, ARG_start, ARG_end };
enum { ARG_buffer, ARG_start, ARG_end, ARG_swap };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_buffer, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
{ MP_QSTR_start, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} },
{ MP_QSTR_swap, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
};
rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
check_for_deinit(self);
@ -613,7 +625,7 @@ STATIC mp_obj_t rp2pio_statemachine_readinto(size_t n_args, const mp_obj_t *pos_
mp_raise_ValueError(translate("Buffer elements must be 4 bytes long or less"));
}
bool ok = common_hal_rp2pio_statemachine_readinto(self, ((uint8_t *)bufinfo.buf) + start, length, stride_in_bytes);
bool ok = common_hal_rp2pio_statemachine_readinto(self, ((uint8_t *)bufinfo.buf) + start, length, stride_in_bytes, args[ARG_swap].u_bool);
if (!ok) {
mp_raise_OSError(MP_EIO);
}
@ -639,11 +651,13 @@ MP_DEFINE_CONST_FUN_OBJ_KW(rp2pio_statemachine_readinto_obj, 2, rp2pio_statemach
//| :param int out_end: End of the slice; this index is not included. Defaults to ``len(buffer_out)``
//| :param int in_start: Start of the slice of ``buffer_in`` to read into: ``buffer_in[in_start:in_end]``
//| :param int in_end: End of the slice; this index is not included. Defaults to ``len(buffer_in)``"""
//| :param bool swap_out: For 2- and 4-byte elements, swap the byte order for the buffer being transmitted (written)"""
//| :param bool swap_in: For 2- and 4-rx elements, swap the byte order for the buffer being received (read)"""
//| ...
//|
STATIC mp_obj_t rp2pio_statemachine_write_readinto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_buffer_out, ARG_buffer_in, ARG_out_start, ARG_out_end, ARG_in_start, ARG_in_end };
enum { ARG_buffer_out, ARG_buffer_in, ARG_out_start, ARG_out_end, ARG_in_start, ARG_in_end, ARG_swap_out, ARG_swap_in };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_buffer_out, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
{ MP_QSTR_buffer_in, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
@ -651,6 +665,8 @@ STATIC mp_obj_t rp2pio_statemachine_write_readinto(size_t n_args, const mp_obj_t
{ MP_QSTR_out_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} },
{ MP_QSTR_in_start, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_in_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} },
{ MP_QSTR_swap_out, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
{ MP_QSTR_swap_in, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
};
rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
check_for_deinit(self);
@ -689,7 +705,7 @@ STATIC mp_obj_t rp2pio_statemachine_write_readinto(size_t n_args, const mp_obj_t
out_stride_in_bytes,
((uint8_t *)buf_in_info.buf) + in_start,
in_length,
in_stride_in_bytes);
in_stride_in_bytes, args[ARG_swap_out].u_bool, args[ARG_swap_in].u_bool);
if (!ok) {
mp_raise_OSError(MP_EIO);
}

View File

@ -65,15 +65,15 @@ void common_hal_rp2pio_statemachine_stop(rp2pio_statemachine_obj_t *self);
void common_hal_rp2pio_statemachine_run(rp2pio_statemachine_obj_t *self, const uint16_t *instructions, size_t len);
// Writes out the given data.
bool common_hal_rp2pio_statemachine_write(rp2pio_statemachine_obj_t *self, const uint8_t *data, size_t len, uint8_t stride_in_bytes);
bool common_hal_rp2pio_statemachine_background_write(rp2pio_statemachine_obj_t *self, const sm_buf_info *once_obj, const sm_buf_info *loop_obj, uint8_t stride_in_bytes);
bool common_hal_rp2pio_statemachine_write(rp2pio_statemachine_obj_t *self, const uint8_t *data, size_t len, uint8_t stride_in_bytes, bool swap);
bool common_hal_rp2pio_statemachine_background_write(rp2pio_statemachine_obj_t *self, const sm_buf_info *once_obj, const sm_buf_info *loop_obj, uint8_t stride_in_bytes, bool swap);
bool common_hal_rp2pio_statemachine_stop_background_write(rp2pio_statemachine_obj_t *self);
mp_int_t common_hal_rp2pio_statemachine_get_pending(rp2pio_statemachine_obj_t *self);
bool common_hal_rp2pio_statemachine_get_writing(rp2pio_statemachine_obj_t *self);
bool common_hal_rp2pio_statemachine_readinto(rp2pio_statemachine_obj_t *self, uint8_t *data, size_t len, uint8_t stride_in_bytes);
bool common_hal_rp2pio_statemachine_readinto(rp2pio_statemachine_obj_t *self, uint8_t *data, size_t len, uint8_t stride_in_bytes, bool swap);
bool common_hal_rp2pio_statemachine_write_readinto(rp2pio_statemachine_obj_t *self,
const uint8_t *data_out, size_t out_len, uint8_t out_stride_in_bytes,
uint8_t *data_in, size_t in_len, uint8_t in_stride_in_bytes);
uint8_t *data_in, size_t in_len, uint8_t in_stride_in_bytes, bool swap_out, bool swap_in);
// Return actual state machine frequency.
uint32_t common_hal_rp2pio_statemachine_get_frequency(rp2pio_statemachine_obj_t *self);

View File

@ -157,9 +157,9 @@ uint32_t common_hal_audiobusio_pdmin_record_to_buffer(audiobusio_pdmin_obj_t *se
size_t output_count = 0;
common_hal_rp2pio_statemachine_clear_rxfifo(&self->state_machine);
// Do one read to get the mic going and throw it away.
common_hal_rp2pio_statemachine_readinto(&self->state_machine, (uint8_t *)samples, 2 * sizeof(uint32_t), sizeof(uint32_t));
common_hal_rp2pio_statemachine_readinto(&self->state_machine, (uint8_t *)samples, 2 * sizeof(uint32_t), sizeof(uint32_t), false);
while (output_count < output_buffer_length && !common_hal_rp2pio_statemachine_get_rxstall(&self->state_machine)) {
common_hal_rp2pio_statemachine_readinto(&self->state_machine, (uint8_t *)samples, 2 * sizeof(uint32_t), sizeof(uint32_t));
common_hal_rp2pio_statemachine_readinto(&self->state_machine, (uint8_t *)samples, 2 * sizeof(uint32_t), sizeof(uint32_t), false);
// Call filter_sample just one place so it can be inlined.
uint16_t value = filter_sample(samples);
if (self->bit_depth == 8) {

View File

@ -153,7 +153,7 @@ void common_hal_imagecapture_parallelimagecapture_singleshot_capture(imagecaptur
pio_sm_exec(pio, sm, pio_encode_jmp(offset));
pio_sm_set_enabled(pio, sm, true);
common_hal_rp2pio_statemachine_readinto(&self->state_machine, bufinfo.buf, bufinfo.len, 4);
common_hal_rp2pio_statemachine_readinto(&self->state_machine, bufinfo.buf, bufinfo.len, 4, false);
pio_sm_set_enabled(pio, sm, false);
}

View File

@ -90,7 +90,7 @@ void common_hal_neopixel_write(const digitalio_digitalinout_obj_t *digitalinout,
while (port_get_raw_ticks(NULL) < next_start_raw_ticks) {
}
common_hal_rp2pio_statemachine_write(&state_machine, pixels, num_bytes, 1 /* stride in bytes */);
common_hal_rp2pio_statemachine_write(&state_machine, pixels, num_bytes, 1 /* stride in bytes */, false);
// Use a private deinit of the state machine that doesn't reset the pin.
rp2pio_statemachine_deinit(&state_machine, true);

View File

@ -161,7 +161,7 @@ void common_hal_paralleldisplay_parallelbus_send(mp_obj_t obj, display_byte_type
paralleldisplay_parallelbus_obj_t *self = MP_OBJ_TO_PTR(obj);
common_hal_digitalio_digitalinout_set_value(&self->command, byte_type == DISPLAY_DATA);
common_hal_rp2pio_statemachine_write(&self->state_machine, data, data_length, 1);
common_hal_rp2pio_statemachine_write(&self->state_machine, data, data_length, 1, false);
}
void common_hal_paralleldisplay_parallelbus_end_transaction(mp_obj_t obj) {

View File

@ -98,7 +98,7 @@ void common_hal_rotaryio_incrementalencoder_construct(rotaryio_incrementalencode
// We're guaranteed by the init code that some output will be available promptly
uint8_t quiescent_state;
common_hal_rp2pio_statemachine_readinto(&self->state_machine, &quiescent_state, 1, 1);
common_hal_rp2pio_statemachine_readinto(&self->state_machine, &quiescent_state, 1, 1, false);
shared_module_softencoder_state_init(self, quiescent_state & 3);
common_hal_rp2pio_statemachine_set_interrupt_handler(&self->state_machine, incrementalencoder_interrupt_handler, self, PIO_IRQ0_INTF_SM0_RXNEMPTY_BITS);

View File

@ -663,7 +663,7 @@ STATIC enum dma_channel_transfer_size _stride_to_dma_size(uint8_t stride) {
static bool _transfer(rp2pio_statemachine_obj_t *self,
const uint8_t *data_out, size_t out_len, uint8_t out_stride_in_bytes,
uint8_t *data_in, size_t in_len, uint8_t in_stride_in_bytes) {
uint8_t *data_in, size_t in_len, uint8_t in_stride_in_bytes, bool swap_out, bool swap_in) {
// This implementation is based on SPI but varies because the tx and rx buffers
// may be different lengths and occur at different times or speeds.
@ -674,13 +674,26 @@ static bool _transfer(rp2pio_statemachine_obj_t *self,
size_t len = MAX(out_len, in_len);
bool tx = data_out != NULL;
bool rx = data_in != NULL;
if (len >= dma_min_size_threshold) {
bool use_dma = len >= dma_min_size_threshold || swap_out || swap_in;
if (use_dma) {
// Use DMA channels to service the two FIFOs
if (tx) {
chan_tx = dma_claim_unused_channel(false);
// DMA allocation failed...
if (chan_tx < 0) {
return false;
}
}
if (rx) {
chan_rx = dma_claim_unused_channel(false);
// DMA allocation failed...
if (chan_rx < 0) {
// may need to free tx channel
if (chan_tx >= 0) {
dma_channel_unclaim(chan_tx);
}
return false;
}
}
}
volatile uint8_t *tx_destination = NULL;
@ -698,7 +711,6 @@ static bool _transfer(rp2pio_statemachine_obj_t *self,
}
}
uint32_t stall_mask = 1 << (PIO_FDEBUG_TXSTALL_LSB + self->state_machine);
bool use_dma = (!rx || chan_rx >= 0) && (!tx || chan_tx >= 0);
if (use_dma) {
dma_channel_config c;
uint32_t channel_mask = 0;
@ -708,6 +720,7 @@ static bool _transfer(rp2pio_statemachine_obj_t *self,
channel_config_set_dreq(&c, self->tx_dreq);
channel_config_set_read_increment(&c, true);
channel_config_set_write_increment(&c, false);
channel_config_set_bswap(&c, swap_out);
dma_channel_configure(chan_tx, &c,
tx_destination,
data_out,
@ -721,6 +734,7 @@ static bool _transfer(rp2pio_statemachine_obj_t *self,
channel_config_set_dreq(&c, self->rx_dreq);
channel_config_set_read_increment(&c, false);
channel_config_set_write_increment(&c, true);
channel_config_set_bswap(&c, swap_in);
dma_channel_configure(chan_rx, &c,
data_in,
rx_source,
@ -811,27 +825,27 @@ static bool _transfer(rp2pio_statemachine_obj_t *self,
// TODO: Provide a way around these checks in case someone wants to use the FIFO
// with manually run code.
bool common_hal_rp2pio_statemachine_write(rp2pio_statemachine_obj_t *self, const uint8_t *data, size_t len, uint8_t stride_in_bytes) {
bool common_hal_rp2pio_statemachine_write(rp2pio_statemachine_obj_t *self, const uint8_t *data, size_t len, uint8_t stride_in_bytes, bool swap) {
if (!self->out) {
mp_raise_RuntimeError(translate("No out in program"));
}
return _transfer(self, data, len, stride_in_bytes, NULL, 0, 0);
return _transfer(self, data, len, stride_in_bytes, NULL, 0, 0, swap, false);
}
bool common_hal_rp2pio_statemachine_readinto(rp2pio_statemachine_obj_t *self, uint8_t *data, size_t len, uint8_t stride_in_bytes) {
bool common_hal_rp2pio_statemachine_readinto(rp2pio_statemachine_obj_t *self, uint8_t *data, size_t len, uint8_t stride_in_bytes, bool swap) {
if (!self->in) {
mp_raise_RuntimeError(translate("No in in program"));
}
return _transfer(self, NULL, 0, 0, data, len, stride_in_bytes);
return _transfer(self, NULL, 0, 0, data, len, stride_in_bytes, false, swap);
}
bool common_hal_rp2pio_statemachine_write_readinto(rp2pio_statemachine_obj_t *self,
const uint8_t *data_out, size_t out_len, uint8_t out_stride_in_bytes,
uint8_t *data_in, size_t in_len, uint8_t in_stride_in_bytes) {
uint8_t *data_in, size_t in_len, uint8_t in_stride_in_bytes, bool swap_out, bool swap_in) {
if (!self->in || !self->out) {
mp_raise_RuntimeError(translate("No in or out in program"));
}
return _transfer(self, data_out, out_len, out_stride_in_bytes, data_in, in_len, in_stride_in_bytes);
return _transfer(self, data_out, out_len, out_stride_in_bytes, data_in, in_len, in_stride_in_bytes, swap_out, swap_in);
}
bool common_hal_rp2pio_statemachine_get_rxstall(rp2pio_statemachine_obj_t *self) {
@ -902,7 +916,7 @@ uint8_t rp2pio_statemachine_program_offset(rp2pio_statemachine_obj_t *self) {
return _current_program_offset[pio_index][sm];
}
bool common_hal_rp2pio_statemachine_background_write(rp2pio_statemachine_obj_t *self, const sm_buf_info *once, const sm_buf_info *loop, uint8_t stride_in_bytes) {
bool common_hal_rp2pio_statemachine_background_write(rp2pio_statemachine_obj_t *self, const sm_buf_info *once, const sm_buf_info *loop, uint8_t stride_in_bytes, bool swap) {
uint8_t pio_index = pio_get_index(self->pio);
uint8_t sm = self->state_machine;
@ -911,11 +925,13 @@ bool common_hal_rp2pio_statemachine_background_write(rp2pio_statemachine_obj_t *
once = loop;
}
if (SM_DMA_ALLOCATED(pio_index, sm)) {
if (stride_in_bytes != self->background_stride_in_bytes) {
mp_raise_ValueError(translate("Mismatched data size"));
}
if (swap != self->byteswap) {
mp_raise_ValueError(translate("Mismatched swap flag"));
}
while (self->pending_buffers) {
RUN_BACKGROUND_TASKS;
@ -958,12 +974,14 @@ bool common_hal_rp2pio_statemachine_background_write(rp2pio_statemachine_obj_t *
self->pending_buffers = pending_buffers;
self->dma_completed = false;
self->background_stride_in_bytes = stride_in_bytes;
self->byteswap = swap;
c = dma_channel_get_default_config(channel);
channel_config_set_transfer_data_size(&c, _stride_to_dma_size(stride_in_bytes));
channel_config_set_dreq(&c, self->tx_dreq);
channel_config_set_read_increment(&c, true);
channel_config_set_write_increment(&c, false);
channel_config_set_bswap(&c, swap);
dma_channel_configure(channel, &c,
tx_destination,
once->info.buf,

View File

@ -64,7 +64,7 @@ typedef struct {
volatile int pending_buffers;
sm_buf_info current, once, loop;
int background_stride_in_bytes;
bool dma_completed;
bool dma_completed, byteswap;
} rp2pio_statemachine_obj_t;
void reset_rp2pio_statemachine(void);