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

@ -39,6 +39,11 @@ int dma_claim_unused_channel(bool required) {
return hw_claim_unused_from_range((uint8_t*)&_claimed, required, 0, NUM_DMA_CHANNELS-1, "No DMA channels are available");
}
bool dma_channel_is_claimed(uint channel) {
check_dma_channel_param(channel);
return hw_is_claimed((uint8_t *) &_claimed, channel);
}
#ifndef NDEBUG
void print_dma_ctrl(dma_channel_hw_t *channel) {

View File

@ -34,8 +34,12 @@ extern "C" {
* * Memory to memory
*/
// this is not defined in generated dreq.h
#define DREQ_FORCE 63
// these are not defined in generated dreq.h
#define DREQ_DMA_TIMER0 DMA_CH0_CTRL_TRIG_TREQ_SEL_VALUE_TIMER0
#define DREQ_DMA_TIMER1 DMA_CH0_CTRL_TRIG_TREQ_SEL_VALUE_TIMER1
#define DREQ_DMA_TIMER2 DMA_CH0_CTRL_TRIG_TREQ_SEL_VALUE_TIMER2
#define DREQ_DMA_TIMER3 DMA_CH0_CTRL_TRIG_TREQ_SEL_VALUE_TIMER3
#define DREQ_FORCE DMA_CH0_CTRL_TRIG_TREQ_SEL_VALUE_PERMANENT
// PICO_CONFIG: PARAM_ASSERTIONS_ENABLED_DMA, Enable/disable DMA assertions, type=bool, default=0, group=hardware_dma
#ifndef PARAM_ASSERTIONS_ENABLED_DMA
@ -94,6 +98,16 @@ void dma_channel_unclaim(uint channel);
*/
int dma_claim_unused_channel(bool required);
/*! \brief Determine if a dma channel is claimed
* \ingroup hardware_dma
*
* \param channel the dma channel
* \return true if the channel is claimed, false otherwise
* \see dma_channel_claim
* \see dma_channel_claim_mask
*/
bool dma_channel_is_claimed(uint channel);
/** \brief DMA channel configuration
* \defgroup channel_config channel_config
* \ingroup hardware_dma
@ -465,7 +479,7 @@ static inline void dma_channel_abort(uint channel) {
while (dma_hw->abort & (1ul << channel)) tight_loop_contents();
}
/*! \brief Enable single DMA channel interrupt 0
/*! \brief Enable single DMA channel's interrupt via DMA_IRQ_0
* \ingroup hardware_dma
*
* \param channel DMA channel
@ -480,7 +494,7 @@ static inline void dma_channel_set_irq0_enabled(uint channel, bool enabled) {
hw_clear_bits(&dma_hw->inte0, 1u << channel);
}
/*! \brief Enable multiple DMA channels interrupt 0
/*! \brief Enable multiple DMA channels' interrupts via DMA_IRQ_0
* \ingroup hardware_dma
*
* \param channel_mask Bitmask of all the channels to enable/disable. Channel 0 = bit 0, channel 1 = bit 1 etc.
@ -494,7 +508,7 @@ static inline void dma_set_irq0_channel_mask_enabled(uint32_t channel_mask, bool
}
}
/*! \brief Enable single DMA channel interrupt 1
/*! \brief Enable single DMA channel's interrupt via DMA_IRQ_1
* \ingroup hardware_dma
*
* \param channel DMA channel
@ -509,7 +523,7 @@ static inline void dma_channel_set_irq1_enabled(uint channel, bool enabled) {
hw_clear_bits(&dma_hw->inte1, 1u << channel);
}
/*! \brief Enable multiple DMA channels interrupt 0
/*! \brief Enable multiple DMA channels' interrupts via DMA_IRQ_1
* \ingroup hardware_dma
*
* \param channel_mask Bitmask of all the channels to enable/disable. Channel 0 = bit 0, channel 1 = bit 1 etc.
@ -523,6 +537,105 @@ static inline void dma_set_irq1_channel_mask_enabled(uint32_t channel_mask, bool
}
}
/*! \brief Enable single DMA channel interrupt on either DMA_IRQ_0 or DMA_IRQ_1
* \ingroup hardware_dma
*
* \param irq_index the IRQ index; either 0 or 1 for DMA_IRQ_0 or DMA_IRQ_1
* \param channel DMA channel
* \param enabled true to enable interrupt via irq_index for specified channel, false to disable.
*/
static inline void dma_irqn_set_channel_enabled(uint irq_index, uint channel, bool enabled) {
invalid_params_if(DMA, irq_index > 1);
if (irq_index) {
dma_channel_set_irq1_enabled(channel, enabled);
} else {
dma_channel_set_irq0_enabled(channel, enabled);
}
}
/*! \brief Enable multiple DMA channels' interrupt via either DMA_IRQ_0 or DMA_IRQ_1
* \ingroup hardware_dma
*
* \param irq_index the IRQ index; either 0 or 1 for DMA_IRQ_0 or DMA_IRQ_1
* \param channel_mask Bitmask of all the channels to enable/disable. Channel 0 = bit 0, channel 1 = bit 1 etc.
* \param enabled true to enable all the interrupts specified in the mask, false to disable all the interrupts specified in the mask.
*/
static inline void dma_irqn_set_channel_mask_enabled(uint irq_index, uint32_t channel_mask, bool enabled) {
invalid_params_if(DMA, irq_index > 1);
if (irq_index) {
dma_set_irq1_channel_mask_enabled(channel_mask, enabled);
} else {
dma_set_irq0_channel_mask_enabled(channel_mask, enabled);
}
}
/*! \brief Determine if a particular channel is a cause of DMA_IRQ_0
* \ingroup hardware_dma
*
* \param channel DMA channel
* \return true if the channel is a cause of DMA_IRQ_0, false otherwise
*/
static inline bool dma_channel_get_irq0_status(uint channel) {
check_dma_channel_param(channel);
return dma_hw->ints0 & (1u << channel);
}
/*! \brief Determine if a particular channel is a cause of DMA_IRQ_1
* \ingroup hardware_dma
*
* \param channel DMA channel
* \return true if the channel is a cause of DMA_IRQ_1, false otherwise
*/
static inline bool dma_channel_get_irq1_status(uint channel) {
check_dma_channel_param(channel);
return dma_hw->ints1 & (1u << channel);
}
/*! \brief Determine if a particular channel is a cause of DMA_IRQ_N
* \ingroup hardware_dma
*
* \param irq_index the IRQ index; either 0 or 1 for DMA_IRQ_0 or DMA_IRQ_1
* \param channel DMA channel
* \return true if the channel is a cause of the DMA_IRQ_N, false otherwise
*/
static inline bool dma_irqn_get_channel_status(uint irq_index, uint channel) {
invalid_params_if(DMA, irq_index > 1);
check_dma_channel_param(channel);
return (irq_index ? dma_hw->ints1 : dma_hw->ints0) & (1u << channel);
}
/*! \brief Acknowledge a channel IRQ, resetting it as the cause of DMA_IRQ_0
* \ingroup hardware_dma
*
* \param channel DMA channel
*/
static inline void dma_channel_acknowledge_irq0(uint channel) {
check_dma_channel_param(channel);
hw_set_bits(&dma_hw->ints0, (1u << channel));
}
/*! \brief Acknowledge a channel IRQ, resetting it as the cause of DMA_IRQ_1
* \ingroup hardware_dma
*
* \param channel DMA channel
*/
static inline void dma_channel_acknowledge_irq1(uint channel) {
check_dma_channel_param(channel);
hw_set_bits(&dma_hw->ints1, (1u << channel));
}
/*! \brief Acknowledge a channel IRQ, resetting it as the cause of DMA_IRQ_N
* \ingroup hardware_dma
*
* \param irq_index the IRQ index; either 0 or 1 for DMA_IRQ_0 or DMA_IRQ_1
* \param channel DMA channel
*/
static inline void dma_irqn_acknowledge_channel(uint irq_index, uint channel) {
invalid_params_if(DMA, irq_index > 1);
check_dma_channel_param(channel);
hw_set_bits(irq_index ? &dma_hw->ints1 : &dma_hw->ints0, (1u << channel));
}
/*! \brief Check if DMA channel is busy
* \ingroup hardware_dma
*