/*
 * Copyright (c) 2018 - 2019, Nordic Semiconductor ASA
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * 3. Neither the name of the copyright holder nor the names of its
 *    contributors may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef NRFX_COREDEP_H__
#define NRFX_COREDEP_H__

/**
 * @defgroup nrfx_coredep Core-dependent functionality
 * @{
 * @ingroup nrfx
 * @brief Module containing functions with core-dependent implementation, like delay.
 */

#if defined(__NRFX_DOXYGEN__)

/** @brief Core frequency (in MHz). */
#define NRFX_DELAY_CPU_FREQ_MHZ
/** @brief Availability of Data Watchpoint and Trace (DWT) unit in the given SoC. */
#define NRFX_DELAY_DWT_PRESENT
/**
 * @brief Number of cycles consumed by one iteration of the internal loop
 *        in the function @ref nrfx_coredep_delay_us.
 *
 * This value can be specified externally (for example, when the SoC is emulated).
 */
#define NRFX_COREDEP_DELAY_US_LOOP_CYCLES

#elif defined(NRF51)
    #define NRFX_DELAY_CPU_FREQ_MHZ 16
    #define NRFX_DELAY_DWT_PRESENT  0
#elif defined(NRF52810_XXAA) || defined(NRF52811_XXAA)
    #define NRFX_DELAY_CPU_FREQ_MHZ 64
    #define NRFX_DELAY_DWT_PRESENT  0
#elif defined(NRF52832_XXAA) || defined (NRF52832_XXAB)
    #define NRFX_DELAY_CPU_FREQ_MHZ 64
    #define NRFX_DELAY_DWT_PRESENT  1
#elif defined(NRF52840_XXAA)
    #define NRFX_DELAY_CPU_FREQ_MHZ 64
    #define NRFX_DELAY_DWT_PRESENT  1
#elif defined(NRF9160_XXAA)
    #define NRFX_DELAY_CPU_FREQ_MHZ 64
    #define NRFX_DELAY_DWT_PRESENT  1
#else
    #error "Unknown device."
#endif

/**
 * @brief Function for delaying execution for a number of microseconds.
 *
 * The value of @p time_us is multiplied by the frequency in MHz. Therefore, the delay is limited to
 * maximum uint32_t capacity divided by frequency. For example:
 * - For SoCs working at 64MHz: 0xFFFFFFFF/64 = 0x03FFFFFF (67108863 microseconds)
 * - For SoCs working at 16MHz: 0xFFFFFFFF/16 = 0x0FFFFFFF (268435455 microseconds)
 *
 * @sa NRFX_COREDEP_DELAY_US_LOOP_CYCLES
 *
 * @param time_us Number of microseconds to wait.
 */
__STATIC_INLINE void nrfx_coredep_delay_us(uint32_t time_us);

/** @} */

#ifndef SUPPRESS_INLINE_IMPLEMENTATION

#if NRFX_CHECK(NRFX_DELAY_DWT_BASED)

#if !NRFX_DELAY_DWT_PRESENT
#error "DWT unit not present in the SoC that is used."
#endif

__STATIC_INLINE void nrfx_coredep_delay_us(uint32_t time_us)
{
    if (time_us == 0)
    {
        return;
    }
    uint32_t time_cycles = time_us * NRFX_DELAY_CPU_FREQ_MHZ;

    // Save the current state of the DEMCR register to be able to restore it before exiting
    // this function. Enable the trace and debug blocks (including DWT).
    uint32_t core_debug = CoreDebug->DEMCR;
    CoreDebug->DEMCR = core_debug | CoreDebug_DEMCR_TRCENA_Msk;

    // Save the current state of the CTRL register in the DWT block. Make sure
    // that the cycle counter is enabled.
    uint32_t dwt_ctrl = DWT->CTRL;
    DWT->CTRL = dwt_ctrl | DWT_CTRL_CYCCNTENA_Msk;

    // Store start value of the cycle counter.
    uint32_t cyccnt_initial = DWT->CYCCNT;

    // Delay required time.
    while ((DWT->CYCCNT - cyccnt_initial) < time_cycles)
    {}

    // Restore preserved registers.
    DWT->CTRL = dwt_ctrl;
    CoreDebug->DEMCR = core_debug;
}
#else // NRFX_CHECK(NRFX_DELAY_DWT_BASED)


__STATIC_INLINE void nrfx_coredep_delay_us(uint32_t time_us)
{
    if (time_us == 0)
    {
        return;
    }

    // Allow overriding the number of cycles per loop iteration, in case it is
    // needed to adjust this number externally (for example, when the SoC is
    // emulated).
    #ifndef NRFX_COREDEP_DELAY_US_LOOP_CYCLES
        #if defined(NRF51)
            // The loop takes 4 cycles: 1 for SUBS, 3 for BHI.
            #define NRFX_COREDEP_DELAY_US_LOOP_CYCLES  4
        #elif defined(NRF52810_XXAA) || defined(NRF52811_XXAA)
            // The loop takes 7 cycles: 1 for SUBS, 2 for BHI, 2 wait states
            // for each instruction.
            #define NRFX_COREDEP_DELAY_US_LOOP_CYCLES  7
        #else
            // The loop takes 3 cycles: 1 for SUBS, 2 for BHI.
            #define NRFX_COREDEP_DELAY_US_LOOP_CYCLES  3
        #endif
    #endif // NRFX_COREDEP_DELAY_US_LOOP_CYCLES
    // Align the machine code, so that it can be cached properly and no extra
    // wait states appear.
    __ALIGN(16)
    static const uint16_t delay_machine_code[] = {
        0x3800 + NRFX_COREDEP_DELAY_US_LOOP_CYCLES, // SUBS r0, #loop_cycles
        0xd8fd, // BHI .-2
        0x4770  // BX LR
    };

    typedef void (* delay_func_t)(uint32_t);
    const delay_func_t delay_cycles =
        // Set LSB to 1 to execute the code in the Thumb mode.
        (delay_func_t)((((uint32_t)delay_machine_code) | 1));
    uint32_t cycles = time_us * NRFX_DELAY_CPU_FREQ_MHZ;
    delay_cycles(cycles);
}

#endif // !NRFX_CHECK(NRFX_DELAY_DWT_BASED_DELAY)

#endif // SUPPRESS_INLINE_IMPLEMENTATION

#endif // NRFX_COREDEP_H__
