From f808b5f2dcea837458ab23a78d769c61f4161bf5 Mon Sep 17 00:00:00 2001 From: Graham Sanderson Date: Tue, 12 Oct 2021 16:04:16 -0500 Subject: [PATCH] Add DREQ methods for PWM/SPI/UART/I2C (#603) --- src/rp2_common/hardware_i2c/include/hardware/i2c.h | 14 ++++++++++++++ src/rp2_common/hardware_pio/include/hardware/pio.h | 9 +++++++-- src/rp2_common/hardware_pwm/include/hardware/pwm.h | 13 +++++++++++++ src/rp2_common/hardware_spi/include/hardware/spi.h | 14 ++++++++++++++ .../hardware_uart/include/hardware/uart.h | 14 ++++++++++++++ 5 files changed, 62 insertions(+), 2 deletions(-) diff --git a/src/rp2_common/hardware_i2c/include/hardware/i2c.h b/src/rp2_common/hardware_i2c/include/hardware/i2c.h index 2518f6f..23ff8f1 100644 --- a/src/rp2_common/hardware_i2c/include/hardware/i2c.h +++ b/src/rp2_common/hardware_i2c/include/hardware/i2c.h @@ -10,6 +10,7 @@ #include "pico.h" #include "pico/time.h" #include "hardware/structs/i2c.h" +#include "hardware/regs/dreq.h" // PICO_CONFIG: PARAM_ASSERTIONS_ENABLED_I2C, Enable/disable assertions in the I2C module, type=bool, default=0, group=hardware_i2c #ifndef PARAM_ASSERTIONS_ENABLED_I2C @@ -311,6 +312,19 @@ static inline void i2c_read_raw_blocking(i2c_inst_t *i2c, uint8_t *dst, size_t l } } +/*! \brief Return the DREQ to use for pacing transfers to/from a particular I2C instance + * \ingroup hardware_i2c + * + * \param i2c Either \ref i2c0 or \ref i2c1 + * \param is_tx true for sending data to the I2C instance, false for receiving data from the I2C instance + */ +static inline uint i2c_get_dreq(i2c_inst_t *i2c, bool is_tx) { + static_assert(DREQ_I2C0_RX == DREQ_I2C0_TX + 1, ""); + static_assert(DREQ_I2C1_RX == DREQ_I2C1_TX + 1, ""); + static_assert(DREQ_I2C1_TX == DREQ_I2C0_TX + 2, ""); + return DREQ_I2C0_TX + i2c_hw_index(i2c) * 2 + !is_tx; +} + #ifdef __cplusplus } #endif diff --git a/src/rp2_common/hardware_pio/include/hardware/pio.h b/src/rp2_common/hardware_pio/include/hardware/pio.h index efd8cf1..d2377ac 100644 --- a/src/rp2_common/hardware_pio/include/hardware/pio.h +++ b/src/rp2_common/hardware_pio/include/hardware/pio.h @@ -436,14 +436,19 @@ static inline void pio_gpio_init(PIO pio, uint pin) { gpio_set_function(pin, pio == pio0 ? GPIO_FUNC_PIO0 : GPIO_FUNC_PIO1); } -/*! \brief Return the DREQ to use for pacing transfers to a particular state machine +/*! \brief Return the DREQ to use for pacing transfers to/from a particular state machine FIFO * \ingroup hardware_pio * * \param pio The PIO instance; either \ref pio0 or \ref pio1 * \param sm State machine index (0..3) - * \param is_tx true for sending data to the state machine, false for received data from the state machine + * \param is_tx true for sending data to the state machine, false for receiving data from the state machine */ static inline uint pio_get_dreq(PIO pio, uint sm, bool is_tx) { + static_assert(DREQ_PIO0_TX1 == DREQ_PIO0_TX0 + 1, ""); + static_assert(DREQ_PIO0_TX2 == DREQ_PIO0_TX0 + 2, ""); + static_assert(DREQ_PIO0_TX3 == DREQ_PIO0_TX0 + 3, ""); + static_assert(DREQ_PIO0_RX0 == DREQ_PIO0_TX0 + NUM_PIO_STATE_MACHINES, ""); + static_assert(DREQ_PIO1_RX0 == DREQ_PIO1_TX0 + NUM_PIO_STATE_MACHINES, ""); check_pio_param(pio); check_sm_param(sm); return sm + (is_tx ? 0 : NUM_PIO_STATE_MACHINES) + (pio == pio0 ? DREQ_PIO0_TX0 : DREQ_PIO1_TX0); diff --git a/src/rp2_common/hardware_pwm/include/hardware/pwm.h b/src/rp2_common/hardware_pwm/include/hardware/pwm.h index 8723125..634375e 100644 --- a/src/rp2_common/hardware_pwm/include/hardware/pwm.h +++ b/src/rp2_common/hardware_pwm/include/hardware/pwm.h @@ -9,6 +9,7 @@ #include "pico.h" #include "hardware/structs/pwm.h" +#include "hardware/regs/dreq.h" #ifdef __cplusplus extern "C" { @@ -539,6 +540,18 @@ static inline void pwm_force_irq(uint slice_num) { pwm_hw->intf = 1u << slice_num; } +/*! \brief Return the DREQ to use for pacing transfers to a particular PWM slice + * \ingroup hardware_pwm + * + * \param slice_num PWM slice number + */ +static inline uint pwm_get_dreq(uint slice_num) { + static_assert(DREQ_PWM_WRAP1 == DREQ_PWM_WRAP0 + 1, ""); + static_assert(DREQ_PWM_WRAP7 == DREQ_PWM_WRAP0 + 7, ""); + check_slice_num_param(slice_num); + return DREQ_PWM_WRAP0 + slice_num; +} + #ifdef __cplusplus } #endif diff --git a/src/rp2_common/hardware_spi/include/hardware/spi.h b/src/rp2_common/hardware_spi/include/hardware/spi.h index b766f74..e8dc952 100644 --- a/src/rp2_common/hardware_spi/include/hardware/spi.h +++ b/src/rp2_common/hardware_spi/include/hardware/spi.h @@ -10,6 +10,7 @@ #include "pico.h" #include "pico/time.h" #include "hardware/structs/spi.h" +#include "hardware/regs/dreq.h" // PICO_CONFIG: PARAM_ASSERTIONS_ENABLED_SPI, Enable/disable assertions in the SPI module, type=bool, default=0, group=hardware_spi #ifndef PARAM_ASSERTIONS_ENABLED_SPI @@ -337,6 +338,19 @@ int spi_write16_blocking(spi_inst_t *spi, const uint16_t *src, size_t len); */ int spi_read16_blocking(spi_inst_t *spi, uint16_t repeated_tx_data, uint16_t *dst, size_t len); +/*! \brief Return the DREQ to use for pacing transfers to/from a particular SPI instance + * \ingroup hardware_spi + * + * \param spi SPI instance specifier, either \ref spi0 or \ref spi1 + * \param is_tx true for sending data to the SPI instance, false for receiving data from the SPI instance + */ +static inline uint spi_get_dreq(spi_inst_t *spi, bool is_tx) { + static_assert(DREQ_SPI0_RX == DREQ_SPI0_TX + 1, ""); + static_assert(DREQ_SPI1_RX == DREQ_SPI1_TX + 1, ""); + static_assert(DREQ_SPI1_TX == DREQ_SPI0_TX + 2, ""); + return DREQ_SPI0_TX + spi_get_index(spi) * 2 + !is_tx; +} + #ifdef __cplusplus } #endif diff --git a/src/rp2_common/hardware_uart/include/hardware/uart.h b/src/rp2_common/hardware_uart/include/hardware/uart.h index 980dc4b..bce0d2f 100644 --- a/src/rp2_common/hardware_uart/include/hardware/uart.h +++ b/src/rp2_common/hardware_uart/include/hardware/uart.h @@ -9,6 +9,7 @@ #include "pico.h" #include "hardware/structs/uart.h" +#include "hardware/regs/dreq.h" // PICO_CONFIG: PARAM_ASSERTIONS_ENABLED_UART, Enable/disable assertions in the UART module, type=bool, default=0, group=hardware_uart #ifndef PARAM_ASSERTIONS_ENABLED_UART @@ -432,6 +433,19 @@ static inline void uart_default_tx_wait_blocking(void) { */ bool uart_is_readable_within_us(uart_inst_t *uart, uint32_t us); +/*! \brief Return the DREQ to use for pacing transfers to/from a particular UART instance + * \ingroup hardware_uart + * + * \param uart UART instance. \ref uart0 or \ref uart1 + * \param is_tx true for sending data to the UART instance, false for receiving data from the UART instance + */ +static inline uint uart_get_dreq(uart_inst_t *uart, bool is_tx) { + static_assert(DREQ_UART0_RX == DREQ_UART0_TX + 1, ""); + static_assert(DREQ_UART1_RX == DREQ_UART1_TX + 1, ""); + static_assert(DREQ_UART1_TX == DREQ_UART0_TX + 2, ""); + return DREQ_UART0_TX + uart_get_index(uart) * 2 + !is_tx; +} + #ifdef __cplusplus } #endif