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:
@ -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
|
||||
|
@ -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];
|
||||
|
||||
|
Reference in New Issue
Block a user