Small API additions and minor fixes (#406)

* Add missing DREQ_s

* store actual clock frequency in clock_configure (fixes #368)

* use dma DREQ values defined in dreqs/dma.h

* Fix hw_is_claimed, and add xxx_is_claimed APIs

* Add some PIO irq helper methods

* Add DMA channel IRQ status getter and clear methods

* Implement the correct PIO IRQ status/clear methods (good to have methods here as the h/w interrupt registers are super confusing)

* fix pico_multicore dependencies

* add missing wrapper func __aeabi_f2d

* Further DMA/PIO IRQ API cleanup (and review fixes)

* add PICO_INT64_OPS_IN_RAM flag
This commit is contained in:
Graham Sanderson
2021-06-02 13:12:27 -05:00
committed by GitHub
parent 91e9327ff1
commit 5afa3636d6
21 changed files with 368 additions and 36 deletions

View File

@ -111,6 +111,11 @@ static inline void check_sm_param(__unused uint sm) {
valid_params_if(PIO, sm < NUM_PIO_STATE_MACHINES);
}
static inline void check_sm_mask(__unused uint mask) {
valid_params_if(PIO, mask < (1u << NUM_PIO_STATE_MACHINES));
}
static inline void check_pio_param(__unused PIO pio) {
valid_params_if(PIO, pio == pio0 || pio == pio1);
}
@ -554,6 +559,7 @@ static inline void pio_sm_set_enabled(PIO pio, uint sm, bool enabled) {
*/
static inline void pio_set_sm_mask_enabled(PIO pio, uint32_t mask, bool enabled) {
check_pio_param(pio);
check_sm_mask(mask);
pio->ctrl = (pio->ctrl & ~mask) | (enabled ? mask : 0u);
}
@ -583,6 +589,7 @@ static inline void pio_sm_restart(PIO pio, uint sm) {
*/
static inline void pio_restart_sm_mask(PIO pio, uint32_t mask) {
check_pio_param(pio);
check_sm_mask(mask);
pio->ctrl |= (mask << PIO_CTRL_SM_RESTART_LSB) & PIO_CTRL_SM_RESTART_BITS;
}
@ -644,6 +651,7 @@ static inline void pio_sm_clkdiv_restart(PIO pio, uint sm) {
*/
static inline void pio_clkdiv_restart_sm_mask(PIO pio, uint32_t mask) {
check_pio_param(pio);
check_sm_mask(mask);
pio->ctrl |= (mask << PIO_CTRL_CLKDIV_RESTART_LSB) & PIO_CTRL_CLKDIV_RESTART_BITS;
}
@ -660,10 +668,154 @@ static inline void pio_clkdiv_restart_sm_mask(PIO pio, uint32_t mask) {
*/
static inline void pio_enable_sm_mask_in_sync(PIO pio, uint32_t mask) {
check_pio_param(pio);
check_sm_mask(mask);
pio->ctrl |= ((mask << PIO_CTRL_CLKDIV_RESTART_LSB) & PIO_CTRL_CLKDIV_RESTART_BITS) |
((mask << PIO_CTRL_SM_ENABLE_LSB) & PIO_CTRL_SM_ENABLE_BITS);
}
/*! \brief PIO interrupt source numbers for pio related IRQs
* \ingroup hardware_pio
*/
enum pio_interrupt_source {
pis_interrupt0 = PIO_INTR_SM0_LSB,
pis_interrupt1 = PIO_INTR_SM1_LSB,
pis_interrupt2 = PIO_INTR_SM2_LSB,
pis_interrupt3 = PIO_INTR_SM3_LSB,
pis_sm0_tx_fifo_not_full = PIO_INTR_SM0_TXNFULL_LSB,
pis_sm1_tx_fifo_not_full = PIO_INTR_SM1_TXNFULL_LSB,
pis_sm2_tx_fifo_not_full = PIO_INTR_SM2_TXNFULL_LSB,
pis_sm3_tx_fifo_not_full = PIO_INTR_SM3_TXNFULL_LSB,
pis_sm0_rx_fifo_not_empty = PIO_INTR_SM0_RXNEMPTY_LSB,
pis_sm1_rx_fifo_not_empty = PIO_INTR_SM1_RXNEMPTY_LSB,
pis_sm2_rx_fifo_not_empty = PIO_INTR_SM2_RXNEMPTY_LSB,
pis_sm3_rx_fifo_not_empty = PIO_INTR_SM3_RXNEMPTY_LSB,
};
/*! \brief Enable/Disable a single source on a PIO's IRQ 0
* \ingroup hardware_pio
*
* \param pio The PIO instance; either \ref pio0 or \ref pio1
* \param source the source number (see \ref pio_interrupt_source)
* \param enabled true to enable IRQ 0 for the source, false to disable.
*/
static inline void pio_set_irq0_source_enabled(PIO pio, enum pio_interrupt_source source, bool enabled) {
check_pio_param(pio);
invalid_params_if(PIO, source >= 12);
if (enabled)
hw_set_bits(&pio->inte0, 1u << source);
else
hw_clear_bits(&pio->inte0, 1u << source);
}
/*! \brief Enable/Disable a single source on a PIO's IRQ 1
* \ingroup hardware_pio
*
* \param pio The PIO instance; either \ref pio0 or \ref pio1
* \param source the source number (see \ref pio_interrupt_source)
* \param enabled true to enable IRQ 0 for the source, false to disable.
*/
static inline void pio_set_irq1_source_enabled(PIO pio, enum pio_interrupt_source source, bool enabled) {
check_pio_param(pio);
invalid_params_if(PIO, source >= 12);
if (enabled)
hw_set_bits(&pio->inte1, 1u << source);
else
hw_clear_bits(&pio->inte1, 1u << source);
}
/*! \brief Enable/Disable multiple sources on a PIO's IRQ 0
* \ingroup hardware_pio
*
* \param pio The PIO instance; either \ref pio0 or \ref pio1
* \param source_mask Mask of bits, one for each source number (see \ref pio_interrupt_source) to affect
* \param enabled true to enable all the sources specified in the mask on IRQ 0, false to disable all the sources specified in the mask on IRQ 0
*/
static inline void pio_set_irq0_source_mask_enabled(PIO pio, uint32_t source_mask, bool enabled) {
check_pio_param(pio);
invalid_params_if(PIO, source_mask > PIO_INTR_BITS);
if (enabled) {
hw_set_bits(&pio->inte0, source_mask);
} else {
hw_clear_bits(&pio->inte0, source_mask);
}
}
/*! \brief Enable/Disable multiple sources on a PIO's IRQ 1
* \ingroup hardware_pio
*
* \param pio The PIO instance; either \ref pio0 or \ref pio1
* \param source_mask Mask of bits, one for each source number (see \ref pio_interrupt_source) to affect
* \param enabled true to enable all the sources specified in the mask on IRQ 1, false to disable all the source specified in the mask on IRQ 1
*/
static inline void pio_set_irq1_source_mask_enabled(PIO pio, uint32_t source_mask, bool enabled) {
check_pio_param(pio);
invalid_params_if(PIO, source_mask > PIO_INTR_BITS);
if (enabled) {
hw_set_bits(&pio->inte1, source_mask);
} else {
hw_clear_bits(&pio->inte1, source_mask);
}
}
/*! \brief Enable/Disable a single source on a PIO's specified (0/1) IRQ index
* \ingroup hardware_pio
*
* \param pio The PIO instance; either \ref pio0 or \ref pio1
* \param irq_index the IRQ index; either 0 or 1
* \param source the source number (see \ref pio_interrupt_source)
* \param enabled true to enable the source on the specified IRQ, false to disable.
*/
static inline void pio_set_irqn_source_enabled(PIO pio, uint irq_index, enum pio_interrupt_source source, bool enabled) {
invalid_params_if(PIO, irq_index > 1);
if (irq_index) {
pio_set_irq1_source_enabled(pio, source, enabled);
} else {
pio_set_irq0_source_enabled(pio, source, enabled);
}
}
/*! \brief Enable/Disable multiple sources on a PIO's specified (0/1) IRQ index
* \ingroup hardware_pio
*
* \param pio The PIO instance; either \ref pio0 or \ref pio1
* \param irq_index the IRQ index; either 0 or 1
* \param source_mask Mask of bits, one for each source number (see \ref pio_interrupt_source) to affect
* \param enabled true to enable all the sources specified in the mask on the specified IRQ, false to disable all the sources specified in the mask on the specified IRQ
*/
static inline void pio_set_irqn_source_mask_enabled(PIO pio, uint irq_index, uint32_t source_mask, bool enabled) {
invalid_params_if(PIO, irq_index > 1);
if (irq_index) {
pio_set_irq0_source_mask_enabled(pio, source_mask, enabled);
} else {
pio_set_irq1_source_mask_enabled(pio, source_mask, enabled);
}
}
/*! \brief Determine if a particular PIO interrupt is set
* \ingroup hardware_pio
*
* \param pio The PIO instance; either \ref pio0 or \ref pio1
* \param pio_interrupt_num the PIO interrupt number 0-7
* \return true if corresponding PIO interrupt is currently set
*/
static inline bool pio_interrupt_get(PIO pio, uint pio_interrupt_num) {
check_pio_param(pio);
invalid_params_if(PIO, pio_interrupt_num >= 8);
return pio->irq & (1u << pio_interrupt_num);
}
/*! \brief Clear a particular PIO interrupt
* \ingroup hardware_pio
*
* \param pio The PIO instance; either \ref pio0 or \ref pio1
* \param pio_interrupt_num the PIO interrupt number 0-7
*/
static inline void pio_interrupt_clear(PIO pio, uint pio_interrupt_num) {
check_pio_param(pio);
invalid_params_if(PIO, pio_interrupt_num >= 8);
hw_set_bits(&pio->irq, (1u << pio_interrupt_num));
}
/*! \brief Return the current program counter for a state machine
* \ingroup hardware_pio
*
@ -1136,6 +1288,17 @@ void pio_sm_unclaim(PIO pio, uint sm);
*/
int pio_claim_unused_sm(PIO pio, bool required);
/*! \brief Determine if a PIO state machine is claimed
* \ingroup hardware_pio
*
* \param pio The PIO instance; either \ref pio0 or \ref pio1
* \param sm State machine index (0..3)
* \return true if claimed, false otherwise
* \see pio_sm_claim
* \see pio_claim_sm_mask
*/
bool pio_sm_is_claimed(PIO pio, uint sm);
#ifdef __cplusplus
}
#endif

View File

@ -35,6 +35,7 @@ void pio_claim_sm_mask(PIO pio, uint sm_mask) {
if (sm_mask & 1u) pio_sm_claim(pio, i);
}
}
void pio_sm_unclaim(PIO pio, uint sm) {
check_sm_param(sm);
uint which = pio_get_index(pio);
@ -50,6 +51,12 @@ int pio_claim_unused_sm(PIO pio, bool required) {
return index >= (int)base ? index - (int)base : -1;
}
bool pio_sm_is_claimed(PIO pio, uint sm) {
check_sm_param(sm);
uint which = pio_get_index(pio);
return hw_is_claimed(&claimed, which * NUM_PIO_STATE_MACHINES + sm);
}
static_assert(PIO_INSTRUCTION_COUNT <= 32, "");
static uint32_t _used_instruction_space[2];