/*
 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#ifndef _HARDWARE_PWM_H
#define _HARDWARE_PWM_H

#include "pico.h"
#include "hardware/structs/pwm.h"
#include "hardware/regs/dreq.h"

#ifdef __cplusplus
extern "C" {
#endif

// PICO_CONFIG: PARAM_ASSERTIONS_ENABLED_PWM, Enable/disable assertions in the PWM module, type=bool, default=0, group=hardware_pwm
#ifndef PARAM_ASSERTIONS_ENABLED_PWM
#define PARAM_ASSERTIONS_ENABLED_PWM 0
#endif

/** \file hardware/pwm.h
 *  \defgroup hardware_pwm hardware_pwm
 *
 * Hardware Pulse Width Modulation (PWM) API
 *
 * The RP2040 PWM block has 8 identical slices. Each slice can drive two PWM output signals, or
 * measure the frequency or duty cycle of an input signal. This gives a total of up to 16 controllable
 * PWM outputs. All 30 GPIOs can be driven by the PWM block.
 *
 * The PWM hardware functions by continuously comparing the input value to a free-running counter. This produces a
 * toggling output where the amount of time spent at the high output level is proportional to the input value. The fraction of
 * time spent at the high signal level is known as the duty cycle of the signal.
 *
 * The default behaviour of a PWM slice is to count upward until the wrap value (\ref pwm_config_set_wrap) is reached, and then
 * immediately wrap to 0. PWM slices also offer a phase-correct mode, where the counter starts to count downward after
 * reaching TOP, until it reaches 0 again.
 *
 * \subsection pwm_example Example
 * \addtogroup hardware_pwm
 * \include hello_pwm.c
 */

/** \brief PWM Divider mode settings
 *   \ingroup hardware_pwm
 *
 */
enum pwm_clkdiv_mode
{
    PWM_DIV_FREE_RUNNING = 0, ///< Free-running counting at rate dictated by fractional divider
    PWM_DIV_B_HIGH = 1,       ///< Fractional divider is gated by the PWM B pin
    PWM_DIV_B_RISING = 2,     ///< Fractional divider advances with each rising edge of the PWM B pin
    PWM_DIV_B_FALLING = 3    ///< Fractional divider advances with each falling edge of the PWM B pin
};

enum pwm_chan
{
    PWM_CHAN_A = 0,
    PWM_CHAN_B = 1
};

typedef struct {
    uint32_t csr;
    uint32_t div;
    uint32_t top;
} pwm_config;

static inline void check_slice_num_param(__unused uint slice_num) {
    valid_params_if(PWM, slice_num < NUM_PWM_SLICES);
}

/** \brief Determine the PWM slice that is attached to the specified GPIO
 *  \ingroup hardware_pwm
 *
 * \return The PWM slice number that controls the specified GPIO.
 */
static inline uint pwm_gpio_to_slice_num(uint gpio) {
    valid_params_if(PWM, gpio < NUM_BANK0_GPIOS);
    return (gpio >> 1u) & 7u;
}

/** \brief Determine the PWM channel that is attached to the specified GPIO.
 *  \ingroup hardware_pwm
 *
 * Each slice 0 to 7 has two channels, A and B.
 *
 * \return The PWM channel that controls the specified GPIO.
 */
static inline uint pwm_gpio_to_channel(uint gpio) {
    valid_params_if(PWM, gpio < NUM_BANK0_GPIOS);
    return gpio & 1u;
}

/** \brief Set phase correction in a PWM configuration
 *  \ingroup hardware_pwm
 *
 * \param c PWM configuration struct to modify
 * \param phase_correct true to set phase correct modulation, false to set trailing edge
 *
 * Setting phase control to true means that instead of wrapping back to zero when the wrap point is reached,
 * the PWM starts counting back down. The output frequency is halved when phase-correct mode is enabled.
 */
static inline void pwm_config_set_phase_correct(pwm_config *c, bool phase_correct) {
    c->csr = (c->csr & ~PWM_CH0_CSR_PH_CORRECT_BITS)
        | (bool_to_bit(phase_correct) << PWM_CH0_CSR_PH_CORRECT_LSB);
}

/** \brief Set clock divider in a PWM configuration
 *  \ingroup hardware_pwm
 *
 * \param c PWM configuration struct to modify
 * \param div Value to divide counting rate by. Must be greater than or equal to 1.
 *
 * If the divide mode is free-running, the PWM counter runs at clk_sys / div.
 * Otherwise, the divider reduces the rate of events seen on the B pin input (level or edge)
 * before passing them on to the PWM counter.
 */
static inline void pwm_config_set_clkdiv(pwm_config *c, float div) {
    c->div = (uint32_t)(div * (float)(1u << PWM_CH0_DIV_INT_LSB));
}

/** \brief Set PWM clock divider in a PWM configuration
 *  \ingroup hardware_pwm
 *
 * \param c PWM configuration struct to modify
 * \param div Integer value to reduce counting rate by. Must be greater than or equal to 1.
 *
 * If the divide mode is free-running, the PWM counter runs at clk_sys / div.
 * Otherwise, the divider reduces the rate of events seen on the B pin input (level or edge)
 * before passing them on to the PWM counter.
 */
static inline void pwm_config_set_clkdiv_int(pwm_config *c, uint div) {
    c->div = div << PWM_CH0_DIV_INT_LSB;
}

/** \brief Set PWM counting mode in a PWM configuration
 *  \ingroup hardware_pwm
 *
 * \param c PWM configuration struct to modify
 * \param mode PWM divide/count mode
 *
 * Configure which event gates the operation of the fractional divider.
 * The default is always-on (free-running PWM). Can also be configured to count on
 * high level, rising edge or falling edge of the B pin input.
 */
static inline void pwm_config_set_clkdiv_mode(pwm_config *c, enum pwm_clkdiv_mode mode) {
    valid_params_if(PWM, mode == PWM_DIV_FREE_RUNNING ||
            mode == PWM_DIV_B_RISING ||
            mode == PWM_DIV_B_HIGH ||
            mode == PWM_DIV_B_FALLING);
    c->csr = (c->csr & ~PWM_CH0_CSR_DIVMODE_BITS)
        | (((uint)mode) << PWM_CH0_CSR_DIVMODE_LSB);
}

/** \brief Set output polarity in a PWM configuration
 *  \ingroup hardware_pwm
 *
 * \param c PWM configuration struct to modify
 * \param a true to invert output A
 * \param b true to invert output B
 */
static inline void pwm_config_set_output_polarity(pwm_config *c, bool a, bool b) {
    c->csr = (c->csr & ~(PWM_CH0_CSR_A_INV_BITS | PWM_CH0_CSR_B_INV_BITS))
        | ((bool_to_bit(a) << PWM_CH0_CSR_A_INV_LSB) | (bool_to_bit(b) << PWM_CH0_CSR_B_INV_LSB));
}

/** \brief Set PWM counter wrap value in a PWM configuration
 *  \ingroup hardware_pwm
 *
 * Set the highest value the counter will reach before returning to 0. Also known as TOP.
 *
 * \param c PWM configuration struct to modify
 * \param wrap Value to set wrap to
 */
static inline void pwm_config_set_wrap(pwm_config *c, uint16_t wrap) {
    c->top = wrap;
}

/** \brief Initialise a PWM with settings from a configuration object
 *  \ingroup hardware_pwm
 *
 * Use the \ref pwm_get_default_config() function to initialise a config structure, make changes as
 * needed using the pwm_config_* functions, then call this function to set up the PWM.
 *
 * \param slice_num PWM slice number
 * \param c The configuration to use
 * \param start If true the PWM will be started running once configured. If false you will need to start
 *  manually using \ref pwm_set_enabled() or \ref pwm_set_mask_enabled()
 */
static inline void pwm_init(uint slice_num, pwm_config *c, bool start) {
    check_slice_num_param(slice_num);
    pwm_hw->slice[slice_num].csr = 0;

    pwm_hw->slice[slice_num].ctr = PWM_CH0_CTR_RESET;
    pwm_hw->slice[slice_num].cc = PWM_CH0_CC_RESET;
    pwm_hw->slice[slice_num].top = c->top;
    pwm_hw->slice[slice_num].div = c->div;
    pwm_hw->slice[slice_num].csr = c->csr | (bool_to_bit(start) << PWM_CH0_CSR_EN_LSB);
}

/** \brief Get a set of default values for PWM configuration
 *  \ingroup hardware_pwm
 *
 * PWM config is free-running at system clock speed, no phase correction, wrapping at 0xffff,
 * with standard polarities for channels A and B.
 *
 * \return Set of default values.
 */
static inline pwm_config pwm_get_default_config(void) {
    pwm_config c = {0, 0, 0};
    pwm_config_set_phase_correct(&c, false);
    pwm_config_set_clkdiv_int(&c, 1);
    pwm_config_set_clkdiv_mode(&c, PWM_DIV_FREE_RUNNING);
    pwm_config_set_output_polarity(&c, false, false);
    pwm_config_set_wrap(&c, 0xffffu);
    return c;
}

/** \brief Set the current PWM counter wrap value
 *  \ingroup hardware_pwm
 *
 * Set the highest value the counter will reach before returning to 0. Also
 * known as TOP.
 *
 * The counter wrap value is double-buffered in hardware. This means that,
 * when the PWM is running, a write to the counter wrap value does not take
 * effect until after the next time the PWM slice wraps (or, in phase-correct
 * mode, the next time the slice reaches 0). If the PWM is not running, the
 * write is latched in immediately.
 *
 * \param slice_num PWM slice number
 * \param wrap Value to set wrap to
 */
static inline void pwm_set_wrap(uint slice_num, uint16_t wrap) {
    check_slice_num_param(slice_num);
    pwm_hw->slice[slice_num].top = wrap;
}

/** \brief Set the current PWM counter compare value for one channel
 *  \ingroup hardware_pwm
 *
 * Set the value of the PWM counter compare value, for either channel A or channel B.
 *
 * The counter compare register is double-buffered in hardware. This means
 * that, when the PWM is running, a write to the counter compare values does
 * not take effect until the next time the PWM slice wraps (or, in
 * phase-correct mode, the next time the slice reaches 0). If the PWM is not
 * running, the write is latched in immediately.
 *
 * \param slice_num PWM slice number
 * \param chan Which channel to update. 0 for A, 1 for B.
 * \param level new level for the selected output
 */
static inline void pwm_set_chan_level(uint slice_num, uint chan, uint16_t level) {
    check_slice_num_param(slice_num);
    hw_write_masked(
        &pwm_hw->slice[slice_num].cc,
        ((uint)level) << (chan ? PWM_CH0_CC_B_LSB : PWM_CH0_CC_A_LSB),
        chan ? PWM_CH0_CC_B_BITS : PWM_CH0_CC_A_BITS
    );
}

/** \brief Set PWM counter compare values
 *  \ingroup hardware_pwm
 *
 * Set the value of the PWM counter compare values, A and B.
 *
 * The counter compare register is double-buffered in hardware. This means
 * that, when the PWM is running, a write to the counter compare values does
 * not take effect until the next time the PWM slice wraps (or, in
 * phase-correct mode, the next time the slice reaches 0). If the PWM is not
 * running, the write is latched in immediately.
 *
 * \param slice_num PWM slice number
 * \param level_a Value to set compare A to. When the counter reaches this value the A output is deasserted
 * \param level_b Value to set compare B to. When the counter reaches this value the B output is deasserted
 */
static inline void pwm_set_both_levels(uint slice_num, uint16_t level_a, uint16_t level_b) {
    check_slice_num_param(slice_num);
    pwm_hw->slice[slice_num].cc = (((uint)level_b) << PWM_CH0_CC_B_LSB) | (((uint)level_a) << PWM_CH0_CC_A_LSB);
}

/** \brief Helper function to set the PWM level for the slice and channel associated with a GPIO.
 *  \ingroup hardware_pwm
 *
 * Look up the correct slice (0 to 7) and channel (A or B) for a given GPIO, and update the corresponding
 * counter compare field.
 *
 * This PWM slice should already have been configured and set running. Also be careful of multiple GPIOs
 * mapping to the same slice and channel (if GPIOs have a difference of 16).
 *
 * The counter compare register is double-buffered in hardware. This means
 * that, when the PWM is running, a write to the counter compare values does
 * not take effect until the next time the PWM slice wraps (or, in
 * phase-correct mode, the next time the slice reaches 0). If the PWM is not
 * running, the write is latched in immediately.
 *
 * \param gpio GPIO to set level of
 * \param level PWM level for this GPIO
 */
static inline void pwm_set_gpio_level(uint gpio, uint16_t level) {
    valid_params_if(PWM, gpio < NUM_BANK0_GPIOS);
    pwm_set_chan_level(pwm_gpio_to_slice_num(gpio), pwm_gpio_to_channel(gpio), level);
}

/** \brief Get PWM counter
 *  \ingroup hardware_pwm
 *
 * Get current value of PWM counter
 *
 * \param slice_num PWM slice number
 * \return Current value of the PWM counter
 */
static inline uint16_t pwm_get_counter(uint slice_num) {
    check_slice_num_param(slice_num);
    return (uint16_t)(pwm_hw->slice[slice_num].ctr);
}

/** \brief Set PWM counter
 *  \ingroup hardware_pwm
 *
 * Set the value of the PWM counter
 *
 * \param slice_num PWM slice number
 * \param c Value to set the PWM counter to
 *
 */
static inline void pwm_set_counter(uint slice_num, uint16_t c) {
    check_slice_num_param(slice_num);
    pwm_hw->slice[slice_num].ctr = c;
}

/** \brief Advance PWM count
 *  \ingroup hardware_pwm
 *
 * Advance the phase of a running the counter by 1 count.
 *
 * This function will return once the increment is complete.
 *
 * \param slice_num PWM slice number
 */
static inline void pwm_advance_count(uint slice_num) {
    check_slice_num_param(slice_num);
    hw_set_bits(&pwm_hw->slice[slice_num].csr, PWM_CH0_CSR_PH_ADV_BITS);
    while (pwm_hw->slice[slice_num].csr & PWM_CH0_CSR_PH_ADV_BITS) {
        tight_loop_contents();
    }
}

/** \brief Retard PWM count
 *  \ingroup hardware_pwm
 *
 * Retard the phase of a running counter by 1 count
 *
 * This function will return once the retardation is complete.
 *
 * \param slice_num PWM slice number
 */
static inline void pwm_retard_count(uint slice_num) {
    check_slice_num_param(slice_num);
    hw_set_bits(&pwm_hw->slice[slice_num].csr, PWM_CH0_CSR_PH_RET_BITS);
    while (pwm_hw->slice[slice_num].csr & PWM_CH0_CSR_PH_RET_BITS) {
        tight_loop_contents();
    }
}

/** \brief Set PWM clock divider using an 8:4 fractional value
 *  \ingroup hardware_pwm
 *
 * Set the clock divider. Counter increment will be on sysclock divided by this value, taking into account the gating.
 *
 * \param slice_num PWM slice number
 * \param integer  8 bit integer part of the clock divider
 * \param fract 4 bit fractional part of the clock divider
 */
static inline void pwm_set_clkdiv_int_frac(uint slice_num, uint8_t integer, uint8_t fract) {
    check_slice_num_param(slice_num);
    valid_params_if(PWM, fract < 16);
    pwm_hw->slice[slice_num].div = (((uint)integer) << PWM_CH0_DIV_INT_LSB) | (((uint)fract) << PWM_CH0_DIV_FRAC_LSB);
}

/** \brief Set PWM clock divider
 *  \ingroup hardware_pwm
 *
 * Set the clock divider. Counter increment will be on sysclock divided by this value, taking into account the gating.
 *
 * \param slice_num PWM slice number
 * \param divider Floating point clock divider,  1.f <= value < 256.f
 */
static inline void pwm_set_clkdiv(uint slice_num, float divider) {
    check_slice_num_param(slice_num);
    valid_params_if(PWM, divider >= 1.f && divider < 256.f);
    uint8_t i = (uint8_t)divider;
    uint8_t f = (uint8_t)((divider - i) * (0x01 << 4));
    pwm_set_clkdiv_int_frac(slice_num, i, f);
}

/** \brief Set PWM output polarity
 *  \ingroup hardware_pwm
 *
 * \param slice_num PWM slice number
 * \param a true to invert output A
 * \param b true to invert output B
 */
static inline void pwm_set_output_polarity(uint slice_num, bool a, bool b) {
    check_slice_num_param(slice_num);
    hw_write_masked(&pwm_hw->slice[slice_num].csr, bool_to_bit(a) << PWM_CH0_CSR_A_INV_LSB | bool_to_bit(b) << PWM_CH0_CSR_B_INV_LSB,
                     PWM_CH0_CSR_A_INV_BITS | PWM_CH0_CSR_B_INV_BITS);
}


/** \brief Set PWM divider mode
 *  \ingroup hardware_pwm
 *
 * \param slice_num PWM slice number
 * \param mode Required divider mode
 */
static inline void pwm_set_clkdiv_mode(uint slice_num, enum pwm_clkdiv_mode mode) {
    check_slice_num_param(slice_num);
    valid_params_if(PWM, mode == PWM_DIV_FREE_RUNNING ||
                         mode == PWM_DIV_B_RISING ||
                         mode == PWM_DIV_B_HIGH ||
                         mode == PWM_DIV_B_FALLING);
    hw_write_masked(&pwm_hw->slice[slice_num].csr, ((uint)mode) << PWM_CH0_CSR_DIVMODE_LSB, PWM_CH0_CSR_DIVMODE_BITS);
}

/** \brief Set PWM phase correct on/off
 *  \ingroup hardware_pwm
 *
 * \param slice_num PWM slice number
 * \param phase_correct true to set phase correct modulation, false to set trailing edge
 *
 * Setting phase control to true means that instead of wrapping back to zero when the wrap point is reached,
 * the PWM starts counting back down. The output frequency is halved when phase-correct mode is enabled.
 */
static inline void pwm_set_phase_correct(uint slice_num, bool phase_correct) {
    check_slice_num_param(slice_num);
    hw_write_masked(&pwm_hw->slice[slice_num].csr, bool_to_bit(phase_correct) << PWM_CH0_CSR_PH_CORRECT_LSB, PWM_CH0_CSR_PH_CORRECT_BITS);
}

/** \brief Enable/Disable PWM
 *  \ingroup hardware_pwm
 *
 * When a PWM is disabled, it halts its counter, and the output pins are left
 * high or low depending on exactly when the counter is halted. When
 * re-enabled the PWM resumes immediately from where it left off.
 *
 * If the PWM's output pins need to be low when halted:
 *
 * - The counter compare can be set to zero whilst the PWM is enabled, and
 *   then the PWM disabled once both pins are seen to be low
 *
 * - The GPIO output overrides can be used to force the actual pins low
 *
 * - The PWM can be run for one cycle (i.e. enabled then immediately disabled)
 *   with a TOP of 0, count of 0 and counter compare of 0, to force the pins
 *   low when the PWM has already been halted. The same method can be used
 *   with a counter compare value of 1 to force a pin high.
 *
 * Note that, when disabled, the PWM can still be advanced one count at a time
 * by pulsing the PH_ADV bit in its CSR. The output pins transition as though
 * the PWM were enabled.
 *
 * \param slice_num PWM slice number
 * \param enabled true to enable the specified PWM, false to disable.
 */
static inline void pwm_set_enabled(uint slice_num, bool enabled) {
    check_slice_num_param(slice_num);
    hw_write_masked(&pwm_hw->slice[slice_num].csr, bool_to_bit(enabled) << PWM_CH0_CSR_EN_LSB, PWM_CH0_CSR_EN_BITS);
}

/** \brief Enable/Disable multiple PWM slices simultaneously
 *  \ingroup hardware_pwm
 *
 * \param mask Bitmap of PWMs to enable/disable. Bits 0 to 7 enable slices 0-7 respectively
 */
static inline void pwm_set_mask_enabled(uint32_t mask) {
    pwm_hw->en = mask;
}

/*! \brief  Enable PWM instance interrupt
 *  \ingroup hardware_pwm
 *
 * Used to enable a single PWM instance interrupt.
 *
 * \param slice_num PWM block to enable/disable
 * \param enabled true to enable, false to disable
 */
static inline void pwm_set_irq_enabled(uint slice_num, bool enabled) {
    check_slice_num_param(slice_num);
    if (enabled) {
        hw_set_bits(&pwm_hw->inte, 1u << slice_num);
    } else {
        hw_clear_bits(&pwm_hw->inte, 1u << slice_num);
    }
}

/*! \brief  Enable multiple PWM instance interrupts
 *  \ingroup hardware_pwm
 *
 * Use this to enable multiple PWM interrupts at once.
 *
 * \param slice_mask Bitmask of all the blocks to enable/disable. Channel 0 = bit 0, channel 1 = bit 1 etc.
 * \param enabled true to enable, false to disable
 */
static inline void pwm_set_irq_mask_enabled(uint32_t slice_mask, bool enabled) {
    valid_params_if(PWM, slice_mask < 256);
    if (enabled) {
        hw_set_bits(&pwm_hw->inte, slice_mask);
    } else {
        hw_clear_bits(&pwm_hw->inte, slice_mask);
    }
}

/*! \brief  Clear a single PWM channel interrupt
 *  \ingroup hardware_pwm
 *
 * \param slice_num PWM slice number
 */
static inline void pwm_clear_irq(uint slice_num) {
    pwm_hw->intr = 1u << slice_num;
}

/*! \brief  Get PWM interrupt status, raw
 *  \ingroup hardware_pwm
 *
 * \return Bitmask of all PWM interrupts currently set
 */
static inline uint32_t pwm_get_irq_status_mask(void) {
    return pwm_hw->ints;
}

/*! \brief  Force PWM interrupt
 *  \ingroup hardware_pwm
 *
 * \param slice_num PWM slice number
 */
static inline void pwm_force_irq(uint 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
}
#endif

#endif
