Add DREQ methods for PWM/SPI/UART/I2C (#603)

This commit is contained in:
Graham Sanderson 2021-10-12 16:04:16 -05:00 committed by GitHub
parent 2f2e62968d
commit f808b5f2dc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 62 additions and 2 deletions

View File

@ -10,6 +10,7 @@
#include "pico.h" #include "pico.h"
#include "pico/time.h" #include "pico/time.h"
#include "hardware/structs/i2c.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 // 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 #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 #ifdef __cplusplus
} }
#endif #endif

View File

@ -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); 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 * \ingroup hardware_pio
* *
* \param pio The PIO instance; either \ref pio0 or \ref pio1 * \param pio The PIO instance; either \ref pio0 or \ref pio1
* \param sm State machine index (0..3) * \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 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_pio_param(pio);
check_sm_param(sm); check_sm_param(sm);
return sm + (is_tx ? 0 : NUM_PIO_STATE_MACHINES) + (pio == pio0 ? DREQ_PIO0_TX0 : DREQ_PIO1_TX0); return sm + (is_tx ? 0 : NUM_PIO_STATE_MACHINES) + (pio == pio0 ? DREQ_PIO0_TX0 : DREQ_PIO1_TX0);

View File

@ -9,6 +9,7 @@
#include "pico.h" #include "pico.h"
#include "hardware/structs/pwm.h" #include "hardware/structs/pwm.h"
#include "hardware/regs/dreq.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -539,6 +540,18 @@ static inline void pwm_force_irq(uint slice_num) {
pwm_hw->intf = 1u << 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 #ifdef __cplusplus
} }
#endif #endif

View File

@ -10,6 +10,7 @@
#include "pico.h" #include "pico.h"
#include "pico/time.h" #include "pico/time.h"
#include "hardware/structs/spi.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 // 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 #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); 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 #ifdef __cplusplus
} }
#endif #endif

View File

@ -9,6 +9,7 @@
#include "pico.h" #include "pico.h"
#include "hardware/structs/uart.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 // 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 #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); 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 #ifdef __cplusplus
} }
#endif #endif