/**
 * \addtogroup BSP
 * \{
 * \addtogroup DEVICES
 * \{
 * \addtogroup OTPC
 * \{
 */

/**
 ****************************************************************************************
 *
 * @file hw_otpc.c
 *
 * @brief Implementation of the OTP Controller Low Level Driver.
 *
 * Copyright (c) 2016, Dialog Semiconductor
 * 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.
 *
 *
 ****************************************************************************************
 */

#if dg_configUSE_HW_OTPC



#include <stdint.h>
#include "hw_otpc.h"


/*
 * Local variables
 */

/*
 * 1MHz: 1 cycle = 1us ==>
 *    25ns : 1us,   200ns : 1us,   500ns : 1us,   1us : 2us,     5us : 5us, 2us : 3us,     blanc : 1us
 *
 * 2MHz: 1 cycle = 500ns ==>
 *    25ns : 500ns, 200ns : 500ns, 500ns : 1us,   1us : 1.5us,   5us : 5us, 2us : 2.5us,   blanc : 500ns
 *
 * 3MHz: 1 cycle = 333ns ==>
 *    25ns : 333ns, 200ns : 333ns, 500ns : 666ns, 1us : 1.33us,  5us : 5us, 2us : 2.33us,  blanc : 333ns
 *
 * 4MHz: 1 cycle = 250ns ==>
 *    25ns : 250ns, 200ns : 250ns, 500ns : 750ns, 1us : 1.25ns,  5us : 5us, 2us : 2.25ns,  blanc : 250ns
 *
 * 6MHz: 1 cycle = 167ns ==>
 *    25ns : 167ns, 200ns : 333ns, 500ns : 667ns, 1us : 1.167ns, 5us : 5us, 2us : 2.167ns, blanc : 167ns
 *
 * 8MHz: 1 cycle = 125ns ==>
 *    25ns : 125ns, 200ns : 250ns, 500ns : 625ns, 1us : 1.125ns, 5us : 5us, 2us : 2.125ns, blanc : 125ns
 *
 * 12MHz: 1 cycle = 83.33ns ==>
 *    25ns : 83ns, 200ns : 250ns,  500ns : 583ns, 1us : 1.083ns, 5us : 5us, 2us : 2.083ns, blanc : 167ns
 *
 * 16MHz: 1 cycle = 62.5ns ==>
 *    25ns : 62ns, 200ns : 250ns,  500ns : 562ns, 1us : 1.062ns, 5us : 5us, 2us : 2.062ns, blanc : 125ns
 *
 * 24MHz: 1 cycle = 41.67ns ==>
 *    25ns : 41ns, 200ns : 208ns,  500ns : 541ns, 1us : 1.041ns, 5us : 5us, 2us : 2.041ns, blanc : 125ns
 *
 * 32MHz: 1 cycle = 31.25ns ==>
 *    25ns : 31ns, 200ns : 219ns,  500ns : 531ns, 1us : 1.031ns, 5us : 5us, 2us : 2.031ns, blanc : 125ns
 *
 * 48MHz: 1 cycle = 41.67ns ==>
 *    25ns : 41ns, 200ns : 208ns,  500ns : 521ns, 1us : 1.021ns, 5us : 5us, 2us : 2.021ns, blanc : 125ns
 *
 */
const uint32_t tim1[11] =
{
    /* 1 MHz */
    (0 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_25NS_Pos) |
    (0 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_200NS_Pos) |
    (0 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_500NS_Pos) |
    (1 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_1US_Pos) |
    (4 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_PW_Pos) |
    (2 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_CADX_Pos),
    /* 2MHz */
    (0 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_25NS_Pos) |
    (0 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_200NS_Pos) |
    (1 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_500NS_Pos) |
    (2 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_1US_Pos) |
    (9 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_PW_Pos) |
    (4 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_CADX_Pos),
    /* 3MHz */
    (0 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_25NS_Pos) |
    (0 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_200NS_Pos) |
    (1 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_500NS_Pos) |
    (3 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_1US_Pos) |
    (14 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_PW_Pos) |
    (6 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_CADX_Pos),
    /* 4MHz */
    (0 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_25NS_Pos) |
    (0 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_200NS_Pos) |
    (2 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_500NS_Pos) |
    (4 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_1US_Pos) |
    (19 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_PW_Pos) |
    (8 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_CADX_Pos),
    /* 6MHz */
    (0 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_25NS_Pos) |
    (1 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_200NS_Pos) |
    (3 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_500NS_Pos) |
    (6 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_1US_Pos) |
    (29 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_PW_Pos) |
    (12 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_CADX_Pos),
    /* 8MHz */
    (0 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_25NS_Pos) |
    (1 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_200NS_Pos) |
    (4 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_500NS_Pos) |
    (8 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_1US_Pos) |
    (39 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_PW_Pos) |
    (16 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_CADX_Pos),
    /* 12MHz */
    (0 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_25NS_Pos) |
    (2 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_200NS_Pos) |
    (6 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_500NS_Pos) |
    (12 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_1US_Pos) |
    (59 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_PW_Pos) |
    (24 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_CADX_Pos),
    /* 16MHz */
    (0 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_25NS_Pos) |
    (3 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_200NS_Pos) |
    (8 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_500NS_Pos) |
    (16 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_1US_Pos) |
    (79 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_PW_Pos) |
    (32 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_CADX_Pos),
    /* 24MHz */
    (0 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_25NS_Pos) |
    (4 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_200NS_Pos) |
    (12 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_500NS_Pos) |
    (24 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_1US_Pos) |
    (119 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_PW_Pos) |
    (48 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_CADX_Pos),
    /* 32MHz */
    (0 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_25NS_Pos) |
    (6 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_200NS_Pos) |
    (16 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_500NS_Pos) |
    (32 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_1US_Pos) |
    (159 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_PW_Pos) |
    (64 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_CADX_Pos),
    /* 48MHz */
    (1 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_25NS_Pos) |
    (9 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_200NS_Pos) |
    (24 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_500NS_Pos) |
    (48 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_1US_Pos) |
    (239 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_PW_Pos) |
    (96 << OTPC_OTPC_TIM1_REG_OTPC_TIM1_CC_T_CADX_Pos)
};

static const uint8_t tim2[HW_OTPC_SYS_CLK_FREQ_48 + 1] =
{ 0, 0, 0, 0, 0, 0,  1,  1,  2,  3,  5 };


/*
 * Forward declarations
 */



/*
 * Inline helpers
 */

/**
 * Wait for programming to finish.
 */
__STATIC_INLINE void wait_for_prog_done(void)
{
    while (!(OTPC->OTPC_STAT_REG & HW_OTPC_REG_FIELD_MASK(STAT, PRDY)))
        ;
}

/**
 * Wait for AREAD or APROG to finish.
 */
__STATIC_INLINE void wait_for_auto_done(void)
{
    while (!(OTPC->OTPC_STAT_REG & HW_OTPC_REG_FIELD_MASK(STAT, ARDY)))
        ;
}

/**
 * Check for correctable or uncorrectable programming error.
 */
__STATIC_INLINE bool have_prog_error(void)
{
    return OTPC->OTPC_STAT_REG &
           (HW_OTPC_FIELD_VAL(STAT, PERR_UNC, 1) | HW_OTPC_FIELD_VAL(STAT, PERR_COR, 1));
}

/*
 * Assertion macros
 */

/*
 * Make sure that the OTP clock is enabled
 */
#define ASSERT_WARNING_OTP_CLK_ENABLED \
        ASSERT_WARNING(CRG_TOP->CLK_AMBA_REG & REG_MSK(CRG_TOP, CLK_AMBA_REG, OTP_ENABLE))

/*
 * Make sure that the OTPC is in given state
 */
#define ASSERT_WARNING_OTPC_MODE(s) \
        ASSERT_WARNING((OTPC->OTPC_MODE_REG & HW_OTPC_REG_FIELD_MASK(MODE, MODE)) \
                                == HW_OTPC_FIELD_VAL(MODE, MODE, s))

/*
 * Make sure that the cell address is valid
 */
#define ASSERT_CELL_OFFSET_VALID(off) \
        ASSERT_WARNING(off < 0x2000)

/*
 * Make sure val is non-zero and less than maximum
 */
#define ASSERT_WARNING_NONZERO_RANGE(val, maximum) \
        do { \
                ASSERT_WARNING(val); \
                ASSERT_WARNING((val) < (maximum)); \
        } while (0)


/*
 * Function definitions
 */

__RETAINED_CODE HW_OTPC_SYS_CLK_FREQ hw_otpc_convert_sys_clk_mhz(uint32_t clk_freq)
{
    HW_OTPC_SYS_CLK_FREQ f;

    /* Value to convert must be at most 48 MHz */
    ASSERT_WARNING(clk_freq <= 48);

    if (--clk_freq < 4)
    {
        /*
         * cover 1, 2, 3, 4
         */
        f = (HW_OTPC_SYS_CLK_FREQ)clk_freq;
    }
    else
    {
        clk_freq -= 5;
        /*
         * remaining valid values:
         *  -  0 (initially 6)
         *  -  2 (initially 8)
         *  -  6 (initially 12)
         *  - 10 (initially 16)
         *  - 18 (initially 24)
         *  - 26 (initially 32)
         *  - 42 (initially 48)
         */

        /* no odd valid values any more */
        ASSERT_WARNING(!(clk_freq & 1));

        clk_freq >>= 1;

        /*
         * remaining valid values:
         *  -  0 (initially 6)
         *  -  1 (initially 8)
         *  -  3 (initially 12)
         *  -  5 (initially 16)
         *  -  9 (initially 24)
         *  - 13 (initially 32)
         *  - 21 (initially 48)
         */
        if (clk_freq > 8)
        {
            /*
             * remaining valid values:
             *  -  9 (initially 24)
             *  - 13 (initially 32)
             *  - 21 (initially 48)
             */
            if (clk_freq > 16)
            {
                ASSERT_WARNING(clk_freq == 21);

                f = HW_OTPC_SYS_CLK_FREQ_48;
            }
            else
            {
                clk_freq -= 8;
                /*
                 * remaining valid values:
                 *  -  1 (initially 24)
                 *  -  5 (initially 32)
                 */
                ASSERT_WARNING((clk_freq == 1) || (clk_freq == 5));

                if (clk_freq < 4)
                {
                    f = (HW_OTPC_SYS_CLK_FREQ)HW_OTPC_SYS_CLK_FREQ_24;
                }
                else
                {
                    f = (HW_OTPC_SYS_CLK_FREQ)HW_OTPC_SYS_CLK_FREQ_32;
                }
            }
        }
        else
        {
            /*
             * remaining valid values:
             *  -  0 (initially 6)
             *  -  1 (initially 8)
             *  -  3 (initially 12)
             *  -  5 (initially 16)
             */
            if (clk_freq > 2)
            {
                ASSERT_WARNING((clk_freq == 3) || (clk_freq == 5));

                if (clk_freq > 4)
                {
                    f = (HW_OTPC_SYS_CLK_FREQ)HW_OTPC_SYS_CLK_FREQ_16;
                }
                else
                {
                    f = (HW_OTPC_SYS_CLK_FREQ)HW_OTPC_SYS_CLK_FREQ_12;
                }
            }
            else
            {
                f = (HW_OTPC_SYS_CLK_FREQ)(HW_OTPC_SYS_CLK_FREQ_6 + clk_freq);
            }
        }
    }

    return f;
}


void hw_otpc_disable(void)
{
    /*
     * Enable OTPC clock
     */
    hw_otpc_init();

    /*
     * set OTPC to stand-by mode
     */
    HW_OTPC_REG_SETF(MODE, MODE, HW_OTPC_MODE_STBY);

    /*
     * Disable OTPC clock
     */
    hw_otpc_close();
}


__RETAINED_CODE void hw_otpc_set_speed(HW_OTPC_SYS_CLK_FREQ clk_speed)
{
    ASSERT_WARNING_OTP_CLK_ENABLED;

    /*
     * Set access speed
     */
    ASSERT_WARNING(clk_speed <= HW_OTPC_SYS_CLK_FREQ_48);

    OTPC->OTPC_TIM1_REG = tim1[clk_speed];
    HW_OTPC_REG_SETF(TIM2, CC_T_BCHK, tim2[clk_speed]);
}


void hw_otpc_power_save(uint32_t inactivity_period)
{
    /* Only go to power save for an inactivity_period < 1024 */
    ASSERT_WARNING(inactivity_period < 1024);

    HW_OTPC_REG_SETF(TIM2, CC_STBY_THR, inactivity_period);
}


uint32_t hw_otpc_num_of_rr(void)
{
    unsigned int i;

    volatile uint32_t *ptr = (volatile uint32_t *)MEMORY_OTP_BASE;

    ASSERT_WARNING_OTP_CLK_ENABLED;

    // STBY mode
    HW_OTPC_REG_SETF(MODE, MODE, HW_OTPC_MODE_STBY);

    // The access will be performed in the spare rows
    HW_OTPC_REG_SETF(MODE, USE_SP_ROWS, 1);

    // MREAD mode
    HW_OTPC_REG_SETF(MODE, MODE, HW_OTPC_MODE_MREAD);

    // Read Records
    i = 0;

    while ((i < MAX_RR_AVAIL) && (ptr[0x9e - 4 * i] & 0x1))
    {
        i++;
    }

    // STBY mode
    HW_OTPC_REG_SETF(MODE, MODE, HW_OTPC_MODE_STBY);

    // Select the normal memory array
    HW_OTPC_REG_SETF(MODE, USE_SP_ROWS, 0);

    return i;
}

static bool manual_prog_verify(uint32_t cell_offset, uint32_t pword_l, uint32_t pword_h)
{
    uint32_t val_l, val_h, old_mode = OTPC->OTPC_MODE_REG;
    uint32_t *addr = hw_otpc_cell_to_mem(cell_offset);

    /* we have to go through standby mode first */
    HW_OTPC_REG_SETF(MODE, MODE, HW_OTPC_MODE_STBY);
    __DMB();
    HW_OTPC_REG_SETF(MODE, ERR_RESP_DIS, 1);
    __DMB();
    HW_OTPC_REG_SETF(MODE, MODE, HW_OTPC_MODE_MREAD);

    if (OTPC->OTPC_STAT_REG & HW_OTPC_REG_FIELD_MASK(STAT, RERROR))
    {
        HW_OTPC_REG_SETF(STAT, RERROR,
                         1); //This bit need to be cleared manually (can only happen if a previous read has not checked/cleared it)
    }

    /*
     * Read cell in manual mode, as 2 32-bit values (little-endian)
     */
    val_l = addr[0];
    val_h = addr[1];
    HW_OTPC_REG_SETF(MODE, MODE, HW_OTPC_MODE_STBY);
    __DMB();
    OTPC->OTPC_MODE_REG = old_mode;

    if (OTPC->OTPC_STAT_REG & HW_OTPC_REG_FIELD_MASK(STAT, RERROR))
    {
        HW_OTPC_REG_SETF(STAT, RERROR, 1); //This bit need to be cleared manually
        return false;
    }

    return (pword_h == val_h) && (pword_l == val_l);
}

/*
 * Set to 1 to manually verify the programmed cell value, if the auto-verification fails.
 */
#define MANUAL_PROG_VERIFICATION        1

bool hw_otpc_manual_word_prog(uint32_t cell_offset, uint32_t pword_l, uint32_t pword_h, bool use_rr)
{
    int i;
    bool ret = true;

    ASSERT_WARNING_OTP_CLK_ENABLED;

    ASSERT_WARNING_OTPC_MODE(HW_OTPC_MODE_STBY);

    ASSERT_CELL_OFFSET_VALID(cell_offset);

    /*
     * Program the data regs
     */
    OTPC->OTPC_PWORDL_REG = pword_l;
    OTPC->OTPC_PWORDH_REG = pword_h;

    /*
     * Start programming
     */
    HW_OTPC_REG_SETF(MODE, MODE, HW_OTPC_MODE_MPROG);
    OTPC->OTPC_PCTRL_REG =
        HW_OTPC_FIELD_VAL(PCTRL, WADDR, cell_offset) |
        HW_OTPC_FIELD_VAL(PCTRL, PSTART, 1);
    wait_for_prog_done();

    /*
     * Check and retry up to 10 times
     */
    i = 0;

    while (have_prog_error())
    {
        if (i == 10)
        {
            break;
        }

        i = i + 1;

        OTPC->OTPC_PCTRL_REG =
            HW_OTPC_FIELD_VAL(PCTRL, WADDR, cell_offset) |
            HW_OTPC_FIELD_VAL(PCTRL, PSTART, 1) |
            HW_OTPC_FIELD_VAL(PCTRL, PRETRY, 1);

        wait_for_prog_done();
    }

    if (i == 10)
    {
        ret = false;

        if (MANUAL_PROG_VERIFICATION)
        {
            ret = manual_prog_verify(cell_offset, pword_l, pword_h);
        }

        if (use_rr && !ret)
        {
            do
            {
                // Reset state
                HW_OTPC_REG_SETF(MODE, MODE, HW_OTPC_MODE_STBY);

                // Abort if the writing was done in the spare area
                if (OTPC->OTPC_MODE_REG & HW_OTPC_REG_FIELD_MASK(MODE, USE_SP_ROWS))
                {
                    break;
                }

                // Write the repair record to the spare area
                if (!hw_otpc_write_rr(cell_offset, pword_l, pword_h))
                {
                    break;
                }

                HW_OTPC_REG_SETF(MODE, MODE, HW_OTPC_MODE_STBY);
                // force reloading
                HW_OTPC_REG_SETF(MODE, MODE, HW_OTPC_MODE_MREAD);

                ret = true;
                break;
            }
            while (0);
        }
    }

    HW_OTPC_REG_SETF(MODE, MODE, HW_OTPC_MODE_STBY);

    return ret;
}

bool hw_otpc_manual_prog(const uint32_t *p_data, uint32_t cell_offset, HW_OTPC_WORD cell_word,
                         uint32_t num_of_words, bool use_rr)
{
    uint32_t w, c, ncells, off, val;
    bool ret = true;
    const uint32_t *addr;

    ASSERT_WARNING_OTP_CLK_ENABLED;

    ASSERT_WARNING_OTPC_MODE(HW_OTPC_MODE_STBY);

    ASSERT_CELL_OFFSET_VALID(cell_offset);

    if (num_of_words == 0)
    {
        return true;    // early exit
    }

    /* index in p_data[] */
    w = 0;
    off = cell_offset;

    if (cell_word == HW_OTPC_WORD_HIGH)
    {
        /*
         * read low 32-bit word so that we program the same value
         */
        addr = hw_otpc_cell_to_mem(cell_offset);

        hw_otpc_manual_read_on(use_rr);
        /* little-endian */
        val = addr[0];
        hw_otpc_manual_read_off();

        if (!hw_otpc_manual_word_prog(off++, val, p_data[w++], use_rr))
        {
            return false;
        }

        ncells = (num_of_words - 1) >> 1;
    }
    else
    {
        ncells = num_of_words >> 1;
    }

    for (c = 0; c < ncells; c++, off++, w += 2)
    {
        if (!hw_otpc_manual_word_prog(off, p_data[w], p_data[w + 1], use_rr))
        {
            return false;
        }
    }

    if (w < num_of_words)
    {
        /*
         * read high 32-bit word so that we program the same value
         */
        addr = hw_otpc_cell_to_mem(off);

        hw_otpc_manual_read_on(use_rr);
        /* little-endian */
        val = addr[1];
        hw_otpc_manual_read_off();

        if (!hw_otpc_manual_word_prog(off, p_data[w++], val, use_rr))
        {
            return false;
        }
    }

    ASSERT_WARNING(w == num_of_words);

    return ret;
}

bool hw_otpc_write_rr(uint32_t cell_addr, uint32_t pword_l, uint32_t pword_h)
{
    uint32_t repair_cnt;
    bool ret = false;

    ASSERT_WARNING_OTP_CLK_ENABLED;

    ASSERT_WARNING_OTPC_MODE(HW_OTPC_MODE_STBY);

    // Get the number of used Repair Records
    repair_cnt = hw_otpc_num_of_rr();

    // Abort if all repair records are being used
    if (repair_cnt < MAX_RR_AVAIL)
    {
        do
        {
            // The access will be performed in the spare rows
            HW_OTPC_REG_SETF(MODE, USE_SP_ROWS, 1);

            // Write the data to the spare area
            if (!hw_otpc_manual_word_prog(0x4F - repair_cnt - 1,
                                          pword_l, pword_h, false))
            {
                break;
            }

            // Write the header of the repair record to the spare area
            if (!hw_otpc_manual_word_prog(0x4F - repair_cnt,
                                          1 | (cell_addr << 1), 0x00000000, false))
            {
                break;
            }

            ret = true;
        }
        while (0);

        // Return to the normal memory array
        HW_OTPC_REG_SETF(MODE, USE_SP_ROWS, 0);

        if (ret)
        {
            /*
             * Request the reloading of the repair records at the next
             * enabling of the OTP cell
             */
            HW_OTPC_REG_SETF(MODE, RLD_RR_REQ, 1);
        }
    }

    return ret;
}


void hw_otpc_manual_read_on(bool spare_rows)
{
    ASSERT_WARNING_OTP_CLK_ENABLED;

    ASSERT_WARNING_OTPC_MODE(HW_OTPC_MODE_STBY);

    /*
     * Place the OTPC in manual read mode
     */
    if (spare_rows)
    {
        OTPC->OTPC_MODE_REG =
            HW_OTPC_FIELD_VAL(MODE, MODE, HW_OTPC_MODE_MREAD) |
            HW_OTPC_FIELD_VAL(MODE, USE_SP_ROWS, 1);
    }
    else
    {
        OTPC->OTPC_MODE_REG = HW_OTPC_MODE_MREAD;
    }
}


void hw_otpc_manual_read_off(void)
{
    ASSERT_WARNING_OTP_CLK_ENABLED;

    ASSERT_WARNING_OTPC_MODE(HW_OTPC_MODE_MREAD);

    /*
     * Place the OTPC in STBY mode
     */
    OTPC->OTPC_MODE_REG = HW_OTPC_MODE_STBY;
}


bool hw_otpc_dma_prog(const uint32_t *p_data, uint32_t cell_offset, HW_OTPC_WORD cell_word,
                      uint32_t num_of_words, bool spare_rows)
{
    ASSERT_WARNING_OTP_CLK_ENABLED;

    ASSERT_WARNING_OTPC_MODE(HW_OTPC_MODE_STBY);

    ASSERT_CELL_OFFSET_VALID(cell_offset);

    /*
     * Make sure that the size is valid
     */
    ASSERT_WARNING(num_of_words);
    ASSERT_WARNING(num_of_words < 16384);

    /*
     * Set up DMA
     */
    unsigned int remap_type = REG_GETF(CRG_TOP, SYS_CTRL_REG, REMAP_ADR0);

    if (IS_SYSRAM_ADDRESS(p_data) ||
        (IS_REMAPPED_ADDRESS(p_data) && (remap_type == 0x3)))
    {
        OTPC->OTPC_AHBADR_REG = black_orca_phy_addr((uint32_t)p_data);
#if dg_configEXEC_MODE != MODE_IS_CACHED
    }
    else if (IS_CACHERAM_ADDRESS(p_data))
    {
        OTPC->OTPC_AHBADR_REG = black_orca_phy_addr((uint32_t)p_data);
#endif
    }
    else
    {
        /*
         * Destination address can only reside in RAM or Cache RAM, but in case of remapped
         * address, REMAP_ADR0 cannot be 0x6 (Cache Data RAM)
         */
        ASSERT_WARNING(0);
    }

    OTPC->OTPC_CELADR_REG = (cell_offset << 1) | (cell_word == HW_OTPC_WORD_HIGH);
    OTPC->OTPC_NWORDS_REG = num_of_words - 1;

    /*
     * Start DMA programming
     */
    if (spare_rows)
    {
        OTPC->OTPC_MODE_REG =
            HW_OTPC_FIELD_VAL(MODE, MODE, HW_OTPC_MODE_APROG) |
            HW_OTPC_FIELD_VAL(MODE, USE_DMA, 1) |
            HW_OTPC_FIELD_VAL(MODE, USE_SP_ROWS, 1);
    }
    else
    {
        OTPC->OTPC_MODE_REG =
            HW_OTPC_FIELD_VAL(MODE, MODE, HW_OTPC_MODE_APROG) |
            HW_OTPC_FIELD_VAL(MODE, USE_DMA, 1);
    }

    wait_for_auto_done();

    /*
     * Check result
     */
    if (OTPC->OTPC_STAT_REG & HW_OTPC_REG_FIELD_MASK(STAT, PERR_UNC))
    {
        return false;
    }

    return true;
}


void hw_otpc_dma_read(uint32_t *p_data, uint32_t cell_offset, HW_OTPC_WORD cell_word,
                      uint32_t num_of_words, bool spare_rows)
{
    ASSERT_WARNING_OTP_CLK_ENABLED;

    ASSERT_WARNING_OTPC_MODE(HW_OTPC_MODE_STBY);

    ASSERT_CELL_OFFSET_VALID(cell_offset);

    /*
     * Make sure that the size is valid
     */
    ASSERT_WARNING(num_of_words);
    ASSERT_WARNING(num_of_words < 16384);

    /*
     * Set up DMA
     */
    unsigned int remap_type = REG_GETF(CRG_TOP, SYS_CTRL_REG, REMAP_ADR0);

    if (IS_SYSRAM_ADDRESS(p_data) ||
        (IS_REMAPPED_ADDRESS(p_data) && (remap_type == 0x3)))
    {
        OTPC->OTPC_AHBADR_REG = black_orca_phy_addr((uint32_t)p_data);
#if dg_configEXEC_MODE != MODE_IS_CACHED
    }
    else if (IS_CACHERAM_ADDRESS(p_data))
    {
        OTPC->OTPC_AHBADR_REG = black_orca_phy_addr((uint32_t)p_data);
#endif
    }
    else
    {
        /*
         * Destination address can only reside in RAM or Cache RAM, but in case of remapped
         * address, REMAP_ADR0 cannot be 0x6 (Cache Data RAM)
         */
        ASSERT_WARNING(0);
    }

    OTPC->OTPC_CELADR_REG = (cell_offset << 1) | (cell_word == HW_OTPC_WORD_HIGH);
    OTPC->OTPC_NWORDS_REG = num_of_words - 1;

    /*
     * Start DMA programming
     */
    if (spare_rows)
    {
        OTPC->OTPC_MODE_REG =
            HW_OTPC_FIELD_VAL(MODE, MODE, HW_OTPC_MODE_AREAD) |
            HW_OTPC_FIELD_VAL(MODE, USE_DMA, 1) |
            HW_OTPC_FIELD_VAL(MODE, USE_SP_ROWS, 1);
    }
    else
    {
        OTPC->OTPC_MODE_REG =
            HW_OTPC_FIELD_VAL(MODE, MODE, HW_OTPC_MODE_AREAD) |
            HW_OTPC_FIELD_VAL(MODE, USE_DMA, 1);
    }

    wait_for_auto_done();
}


bool hw_otpc_fifo_prog(const uint32_t *p_data, uint32_t cell_offset, HW_OTPC_WORD cell_word,
                       uint32_t num_of_words, bool spare_rows)
{
    unsigned int i;

    ASSERT_WARNING_OTP_CLK_ENABLED;

    ASSERT_WARNING_OTPC_MODE(HW_OTPC_MODE_STBY);

    ASSERT_CELL_OFFSET_VALID(cell_offset);

    ASSERT_WARNING_NONZERO_RANGE(num_of_words, 16384);

    /*
     * Set up FIFO
     */
    OTPC->OTPC_CELADR_REG = (cell_offset << 1) | (cell_word == HW_OTPC_WORD_HIGH);
    OTPC->OTPC_NWORDS_REG = num_of_words - 1;

    /*
     * Perform programming via FIFO
     */
    if (spare_rows)
    {
        OTPC->OTPC_MODE_REG =
            HW_OTPC_FIELD_VAL(MODE, MODE, HW_OTPC_MODE_APROG) |
            HW_OTPC_FIELD_VAL(MODE, USE_SP_ROWS, 1);
    }
    else
    {
        OTPC->OTPC_MODE_REG = HW_OTPC_FIELD_VAL(MODE, MODE, HW_OTPC_MODE_APROG);
    }

    for (i = 0; i < num_of_words; i++)
    {
        while (HW_OTPC_REG_GETF(STAT, FWORDS) == 8)
            ;

        OTPC->OTPC_FFPRT_REG = p_data[i]; // Write FIFO data
    }

    /*
     * Wait for completion
     */
    wait_for_auto_done();

    /*
     * Check result
     */
    if (OTPC->OTPC_STAT_REG & HW_OTPC_REG_FIELD_MASK(STAT, PERR_UNC))
    {
        return false;
    }

    return true;
}


bool hw_otpc_fifo_read(uint32_t *p_data, uint32_t cell_offset, HW_OTPC_WORD cell_word,
                       uint32_t num_of_words, bool spare_rows)
{
    unsigned int i;

    ASSERT_WARNING_OTP_CLK_ENABLED;

    ASSERT_WARNING_OTPC_MODE(HW_OTPC_MODE_STBY);

    ASSERT_CELL_OFFSET_VALID(cell_offset);

    ASSERT_WARNING_NONZERO_RANGE(num_of_words, 16384);

    if (OTPC->OTPC_STAT_REG & HW_OTPC_REG_FIELD_MASK(STAT, RERROR))
    {
        HW_OTPC_REG_SETF(STAT, RERROR,
                         1); //This bit need to be cleared manually (can only happen if a previous read has not checked/cleared it)
    }

    /*
     * Set up FIFO
     */
    OTPC->OTPC_CELADR_REG = (cell_offset << 1) | (cell_word == HW_OTPC_WORD_HIGH);
    OTPC->OTPC_NWORDS_REG = num_of_words - 1;

    /*
     * Perform reading via FIFO
     */
    if (spare_rows)
    {
        OTPC->OTPC_MODE_REG =
            HW_OTPC_FIELD_VAL(MODE, MODE, HW_OTPC_MODE_AREAD) |
            HW_OTPC_FIELD_VAL(MODE, USE_SP_ROWS, 1);
    }
    else
    {
        OTPC->OTPC_MODE_REG = HW_OTPC_MODE_AREAD;
    }

    for (i = 0; i < num_of_words; i++)
    {
        while (HW_OTPC_REG_GETF(STAT, FWORDS) == 0)
            ;

        p_data[i] = OTPC->OTPC_FFPRT_REG;
    }

    /*
     * Wait for completion
     */
    wait_for_auto_done();

    /*
     * Check result
     */
    if (OTPC->OTPC_STAT_REG & HW_OTPC_REG_FIELD_MASK(STAT, RERROR))
    {
        HW_OTPC_REG_SETF(STAT, RERROR, 1); //This bit need to be cleared manually
        return false;
    }

    return true;
}


void hw_otpc_prepare(uint32_t num_of_bytes)
{
    ASSERT_WARNING_OTP_CLK_ENABLED;

    ASSERT_WARNING_OTPC_MODE(HW_OTPC_MODE_STBY);

    ASSERT_WARNING_NONZERO_RANGE(num_of_bytes, 65536);

    /*
     * Set up image size
     */
    OTPC->OTPC_NWORDS_REG = ((num_of_bytes + 3) >> 2) - 1;

    /*
     * Enable OTP_COPY
     */
    CRG_TOP->SYS_CTRL_REG |= 1 << REG_POS(CRG_TOP, SYS_CTRL_REG, OTP_COPY);
}


void hw_otpc_cancel_prepare(void)
{
    ASSERT_WARNING_OTP_CLK_ENABLED;

    ASSERT_WARNING_OTPC_MODE(HW_OTPC_MODE_STBY);

    /*
     * Disable OTP_COPY
     */
    CRG_TOP->SYS_CTRL_REG &= ~REG_MSK(CRG_TOP, SYS_CTRL_REG, OTP_COPY);
}


////////////////////////////////////////////////////////////////////////////////////////////////////
// TEST FUNCTIONALITY
////////////////////////////////////////////////////////////////////////////////////////////////////


/**
 * \brief Execution of the test.
 *
 * \return The test result.
 *         <ul>
 *             <li> 0, if the test succeeded
 *             <li> 1, if the test 1 failed
 *         </ul>
 *
 */
static int hw_otpc_core_test(int mode)
{
    ASSERT_WARNING_OTPC_MODE(HW_OTPC_MODE_STBY);

    /*
     * Put OTPC in the proper test mode
     */
    HW_OTPC_REG_SETF(MODE, MODE, mode);

    /*
     * Wait end of test
     */
    while (!(OTPC->OTPC_STAT_REG & HW_OTPC_REG_FIELD_MASK(STAT, TRDY)))
        ;


    /*
     * Check result
     */
    if (OTPC->OTPC_STAT_REG & HW_OTPC_REG_FIELD_MASK(STAT, TERROR))
    {
        return 1;
    }

    return 0;
}


int hw_otpc_blank(void)
{
    return hw_otpc_core_test(HW_OTPC_MODE_TBLANK);
}


int hw_otpc_tdec(void)
{
    return hw_otpc_core_test(HW_OTPC_MODE_TDEC);
}


int hw_otpc_twr(void)
{
    return hw_otpc_core_test(HW_OTPC_MODE_TWR);
}


#endif /* dg_configUSE_HW_OTPC */
/**
 * \}
 * \}
 * \}
 */
