add dma_timer related methods (#604)
This commit is contained in:
		@ -19,6 +19,7 @@
 | 
			
		||||
 | 
			
		||||
#define NUM_CORES _u(2)
 | 
			
		||||
#define NUM_DMA_CHANNELS _u(12)
 | 
			
		||||
#define NUM_DMA_TIMERS _u(4)
 | 
			
		||||
#define NUM_IRQS _u(32)
 | 
			
		||||
#define NUM_PIOS _u(2)
 | 
			
		||||
#define NUM_PIO_STATE_MACHINES _u(4)
 | 
			
		||||
 | 
			
		||||
@ -18,6 +18,7 @@ static_assert(__builtin_offsetof(dma_hw_t, ch[1].ctrl_trig) == DMA_CH1_CTRL_TRIG
 | 
			
		||||
 | 
			
		||||
static_assert(NUM_DMA_CHANNELS <= 16, "");
 | 
			
		||||
static uint16_t _claimed;
 | 
			
		||||
static uint8_t _timer_claimed;
 | 
			
		||||
 | 
			
		||||
void dma_channel_claim(uint channel) {
 | 
			
		||||
    check_dma_channel_param(channel);
 | 
			
		||||
@ -44,6 +45,25 @@ bool dma_channel_is_claimed(uint channel) {
 | 
			
		||||
    return hw_is_claimed((uint8_t *) &_claimed, channel);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void dma_timer_claim(uint timer) {
 | 
			
		||||
    check_dma_timer_param(timer);
 | 
			
		||||
    hw_claim_or_assert(&_timer_claimed, timer, "DMA timer %d is already claimed");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void dma_timer_unclaim(uint timer) {
 | 
			
		||||
    check_dma_timer_param(timer);
 | 
			
		||||
    hw_claim_clear(&_timer_claimed, timer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int dma_claim_unused_timer(bool required) {
 | 
			
		||||
    return hw_claim_unused_from_range(&_timer_claimed, required, 0, NUM_DMA_TIMERS-1, "No DMA timers are available");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool dma_timer_is_claimed(uint timer) {
 | 
			
		||||
    check_dma_timer_param(timer);
 | 
			
		||||
    return hw_is_claimed(&_timer_claimed, timer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifndef NDEBUG
 | 
			
		||||
 | 
			
		||||
void print_dma_ctrl(dma_channel_hw_t *channel) {
 | 
			
		||||
 | 
			
		||||
@ -54,6 +54,10 @@ static inline void check_dma_channel_param(__unused uint channel) {
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void check_dma_timer_param(__unused uint timer_num) {
 | 
			
		||||
    valid_params_if(DMA, timer_num < NUM_DMA_TIMERS);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline static dma_channel_hw_t *dma_channel_hw_addr(uint channel) {
 | 
			
		||||
    check_dma_channel_param(channel);
 | 
			
		||||
    return &dma_hw->ch[channel];
 | 
			
		||||
@ -715,6 +719,71 @@ inline static void dma_sniffer_disable(void) {
 | 
			
		||||
    dma_hw->sniff_ctrl = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*! \brief Mark a dma timer as used
 | 
			
		||||
 *  \ingroup hardware_dma
 | 
			
		||||
 *
 | 
			
		||||
 * Method for cooperative claiming of hardware. Will cause a panic if the timer
 | 
			
		||||
 * is already claimed. Use of this method by libraries detects accidental
 | 
			
		||||
 * configurations that would fail in unpredictable ways.
 | 
			
		||||
 *
 | 
			
		||||
 * \param timer the dma timer
 | 
			
		||||
 */
 | 
			
		||||
void dma_timer_claim(uint timer);
 | 
			
		||||
 | 
			
		||||
/*! \brief Mark a dma timer as no longer used
 | 
			
		||||
 *  \ingroup hardware_dma
 | 
			
		||||
 *
 | 
			
		||||
 * Method for cooperative claiming of hardware.
 | 
			
		||||
 *
 | 
			
		||||
 * \param timer the dma timer to release
 | 
			
		||||
 */
 | 
			
		||||
void dma_timer_unclaim(uint timer);
 | 
			
		||||
 | 
			
		||||
/*! \brief Claim a free dma timer
 | 
			
		||||
 *  \ingroup hardware_dma
 | 
			
		||||
 *
 | 
			
		||||
 * \param required if true the function will panic if none are available
 | 
			
		||||
 * \return the dma timer number or -1 if required was false, and none were free
 | 
			
		||||
 */
 | 
			
		||||
int dma_claim_unused_timer(bool required);
 | 
			
		||||
 | 
			
		||||
/*! \brief Determine if a dma timer is claimed
 | 
			
		||||
 *  \ingroup hardware_dma
 | 
			
		||||
 *
 | 
			
		||||
 * \param timer the dma timer
 | 
			
		||||
 * \return true if the timer is claimed, false otherwise
 | 
			
		||||
 * \see dma_timer_claim
 | 
			
		||||
 */
 | 
			
		||||
bool dma_timer_is_claimed(uint timer);
 | 
			
		||||
 | 
			
		||||
/*! \brief Set the divider for the given DMA timer
 | 
			
		||||
 *  \ingroup hardware_dma
 | 
			
		||||
 *
 | 
			
		||||
 * The timer will run at the system_clock_freq * numerator / denominator, so this is the speed
 | 
			
		||||
 * that data elements will be transferred at via a DMA channel using this timer as a DREQ
 | 
			
		||||
 *
 | 
			
		||||
 * \param timer the dma timer
 | 
			
		||||
 * \param numerator the fraction's numerator
 | 
			
		||||
 * \param denominator the fraction's denominator
 | 
			
		||||
 */
 | 
			
		||||
static inline void dma_timer_set_fraction(uint timer, uint16_t numerator, uint16_t denominator) {
 | 
			
		||||
    check_dma_timer_param(timer);
 | 
			
		||||
    dma_hw->timer[timer] = (((uint32_t)numerator) << DMA_TIMER0_X_LSB) | (((uint32_t)denominator) << DMA_TIMER0_Y_LSB);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*! \brief Return the DREQ number for a given DMA timer
 | 
			
		||||
 *  \ingroup hardware_dma
 | 
			
		||||
 *
 | 
			
		||||
 * \param timer DMA timer number 0-3
 | 
			
		||||
 */
 | 
			
		||||
static inline uint dma_get_timer_dreq(uint timer_num) {
 | 
			
		||||
    static_assert(DREQ_DMA_TIMER1 == DREQ_DMA_TIMER0 + 1, "");
 | 
			
		||||
    static_assert(DREQ_DMA_TIMER2 == DREQ_DMA_TIMER0 + 2, "");
 | 
			
		||||
    static_assert(DREQ_DMA_TIMER3 == DREQ_DMA_TIMER0 + 3, "");
 | 
			
		||||
    check_dma_timer_param(timer_num);
 | 
			
		||||
    return DREQ_DMA_TIMER0 + timer_num;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifndef NDEBUG
 | 
			
		||||
void print_dma_ctrl(dma_channel_hw_t *channel);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user