/**
 ******************************************************************************
 * @file    IAP_Option_EW.c
 * @author  SOC AE Team
 * @version V1.0.0
 * @date    2026-04-22
 * @brief   Source file of IAP module.
 *          -This document is for the SinOne 92 and 95 series microcontrollers:
 *           SC95: SC95F8x1xB, SC95F7x1xB, SC95F8x6x, SC95F7x6x, SC95R50x, SC95F873x, SC95F8x7x,
 *           	   SC95F7x7x, SC95R702, SC95R61x, SC95R602, SC95R605, SC95R751.
 *           SC92: SC92F6x1x, SC92R43x, SC92Fx41xB, SC92R445, SC92L840x, SC92R422A, SC92R429B,
 *           	   SC92R448M, SC92R449, SC92R450, YX2501, SC92F652x, SC92R343, SC92R519, SC92F531x, SC92R515,
 *           	   SC92R348, SC92F5x5x, SC92F637x, SC92R51x_R52x, SC92F552x, SC92R349, SC92F663x, SC92R350,
 *           	   SC92R523, SC92R351, SC92F563x, SC92R352, SC92R524, SC92R454.
 ******************************************************************************
 * @attention
 *
 *1.This software is supplied by Shenzhen SaiYuan Microelectronics Co.,Ltd. and is only
 *intended for use with SaiYuan products. No other uses are authorized. This
 *software is owned by Shenzhen SaiYuan Microelectronics Co.,Ltd. and is protected under
 *all applicable laws, including copyright laws.
 *2.The software which is for guidance only aims at providing customers with
 *coding information regarding their products in order for them to save time.
 *As a result, SaiYuan shall not be held liable for any direct, indirect or
 *consequential damages with respect to any claims arising from the content of
 *such software and/or the use made by customers of the coding information
 *contained herein in connection with their products.
 *
 *  COPYRIGHT 2026 Shenzhen SaiYuan Microelectronics
 */

/* Includes ------------------------------------------------------------------*/
#include "IAP_Option_EW.h"
#include "intrins.h"

/* Global variables ---------------------------------------------------------*/
/* IAP operation enable flag, set 0x69 to enable IAP, clear after operation */
unsigned char IapWriteFlag = IAP_DISABLE;
#if defined(SC92F531x)||defined(SC92F5x5x)||defined(SC92F637x)||defined(SC92R349)||defined(SC92R350)||defined(SC92R351)||defined(SC92R352)
/* EEPROM read/write operation wait counter */
unsigned int cnt = 0;
#endif

#if defined(YX2501)||defined(SC92F652x)||defined(SC92R519)||defined(SC92R515)||defined(SC92R51x_R52x)||defined(SC92F552x)\
    ||defined(SC92R523)||defined(SC92F6x1x)||defined(SC92R436)||defined(SC92R438)||defined(SC92R439)||defined(SC92R422A)\
	||defined(SC92R524)
extern void IAP_SetHoldTimeForErase(void);
#endif
extern void IAP_DelayASM(void);


/**
 * @brief  Write one byte of data through IAP
 * @param  Add[in]: Target address for IAP operation
 * @param  Data[in]: Byte data to be written
 * @retval None
 */
#if !(defined(SC92L840x)||defined(SC92F531x)||defined(SC92R348)||defined(SC92F5x5x)||defined(SC92F637x)||defined(SC92R349)||defined(SC92R350)||defined(SC92R351)||defined(SC92R352))
void IAP_CodeProgramByteOption(unsigned long Add, unsigned char Data)
{
	/* Save the current IAP operation area */
    unsigned char  tempADER = IAPADE;
    unsigned char  tempEA = EA;
	/* For the following chips, when HXT is enabled, PWM must be activated to enable HRC */
#if defined(SC95F8x7x)||defined(SC95F7x7x)||defined(SC95R503)||defined(SC95R61x)\
	||defined(SC92F6x1x)||defined(SC92R436)||defined(SC92R438)||defined(SC92R439)||defined(SC92R422A)||defined(YX2501)\
	||defined(SC92F652x)||defined(SC92R519)||defined(SC92R515)||defined(SC92R51x_R52x)||defined(SC92F552x)||defined(SC92R523)\
	||defined(SC92Fx41xB)||defined(SC92R445)||defined(SC92R429B)||defined(SC92R448M)||defined(SC92R449)||defined(SC92R450)\
	||defined(SC92R524)||defined(SC92R454)
    /* Temporary storage for PWM configuration registers */
    unsigned char  tempOPINX = OPINX;
    unsigned char  tempPWM = 0;
    unsigned char  tempPWMINV = 0;
    unsigned char  tempPWMFlag = 0;
#endif
    /* Save original ROM bank register value */
#if defined(SC95F8x6x)||defined(SC95F7x6x)||defined(SC95F8x3x)||defined(SC95R702)
    unsigned int   xdata tempROMBNK = ROMBNK;
#endif
    unsigned char  WriteFlag1=0xA5;

	/* If the global interrupt is enabled, it needs to be disabled to prevent IAP operation errors */
    EA = 0;
	
	/* For the following chips, when HXT is enabled, PWM must be activated to enable HRC */
#if defined(SC95F8x7x)||defined(SC95F7x7x)||defined(SC95R503)||defined(SC95R61x)\
	||defined(SC92F6x1x)||defined(SC92R436)||defined(SC92R438)||defined(SC92R439)||defined(SC92R422A)||defined(YX2501)\
	||defined(SC92F652x)||defined(SC92R519)||defined(SC92R515)||defined(SC92R51x_R52x)||defined(SC92F552x)||defined(SC92R523)\
	||defined(SC92R524)
	OPINX = 0xC1;
	if (OPREG & 0x40)
	{
		if ((PWMCON0 & 0x80) == 0)
		{
			tempPWM = PWMCON1;
			tempPWMINV = PWMCFG;
			PWMCFG = 0xFF;
			PWMCON1 = 0;
			tempPWMFlag = 1;
			PWMCON0 |= 0x80;
		}
	}
#elif defined(SC92Fx41xB)||defined(SC92R445)||defined(SC92R429B)||defined(SC92R448M)||defined(SC92R449)||defined(SC92R450)\
	||defined(SC92R454)
	OPINX = 0xC1;
	if (OPREG & 0x40)
	{
		if ((PWMCON & 0x80) == 0)
		{
			tempPWM = PWMCON;
			tempPWMINV = PWMCFG;
			PWMCFG = 0xFF;
			PWMCON = 0;
			tempPWMFlag = 1;
			PWMCON |= 0x80;
		}
	}
#endif

	/* If the address exceeds 64K, it is necessary to operate the Bank register to point to the target address */
#if defined(SC95F8x6x)||defined(SC95F7x6x)||defined(SC95F8x3x)||defined(SC95R702)
    if(Add >= 0x10000)
    {
        if(Add < 0x18000)
        {
            ROMBNK = (ROMBNK & 0xCC) | 0x22;
            Add = (Add - 0x8000);
        }
        else if(Add < 0x20000)
        {
            ROMBNK = (ROMBNK & 0xCC) | 0x33;
            Add = (Add - 0x10000);
        }
    }
    else
    {
        ROMBNK = (ROMBNK & 0xCC) | 0x11;
    }
#endif

    IAPADE = 0X00;
    IAPDAT = Data;
    IAPADH = (unsigned char)(Add >> 8);
    IAPADL = (unsigned char)(Add);

	/* Unlock if IAP operation is allowed */
    if ((IapWriteFlag==0x69)&&(WriteFlag1==0xA5))
    {
        IAPKEY = 0xF0;
	/* Set write operation */
#if defined(SC92F6x1x)||defined(SC92R436)||defined(SC92R438)||defined(SC92R439)||defined(SC92R422A)||defined(YX2501)\
	||defined(SC92F652x)||defined(SC92R519)||defined(SC92R515)||defined(SC92R51x_R52x)||defined(SC92F552x)||defined(SC92R523)\
	||defined(SC92R524)
        IAPCTL = 0x08;
#endif
#if defined(SC95F8x1xB)||defined(SC95F7x1xB)||defined(SC95F8x6x)||defined(SC95F7x6x)||defined(SC95R503)||defined(SC95F8x3x)\
	||defined(SC95F8x7x)||defined(SC95F7x7x)||defined(SC95R702)||defined(SC95R61x)||defined(SC95R602)||defined(SC95R605)||defined(SC95R751)\
	||defined(SC92F663x)||defined(SC92F563x)
        IAPCTL = 0X10;
#endif
    }

	/* Trigger IAP CMD command */
    if ((IapWriteFlag==0x69)&&(WriteFlag1==0xA5))
    {
        if (IAPADE == 0)
        {
            IAPCTL |= 0x02;
        }
    }

    /* Hardware required delay for IAP operation */
    IAP_DelayASM();

    /* Restore IAP address extension register */
    IAPADE = tempADER;
    /* Restore original ROM bank setting */
#if defined(SC95F8x6x)||defined(SC95F7x6x)||defined(SC95F8x3x)||defined(SC95R702)
    ROMBNK = tempROMBNK;
#endif

    /* Restore PWM configuration */
#if defined(SC95F8x7x)||defined(SC95F7x7x)||defined(SC95R503)||defined(SC95R61x)\
	||defined(SC92F6x1x)||defined(SC92R436)||defined(SC92R438)||defined(SC92R439)||defined(SC92R422A)||defined(YX2501)\
	||defined(SC92F652x)||defined(SC92R519)||defined(SC92R515)||defined(SC92R51x_R52x)||defined(SC92F552x)||defined(SC92R523)\
	||defined(SC92R524)
	OPINX = tempOPINX;
    if(tempPWMFlag==1)
    {
        PWMCFG  = tempPWMINV;
        PWMCON1 = tempPWM;
        PWMCON0 &= ~0x80;
        tempPWMFlag = 0;
    }
#elif defined(SC92Fx41xB)||defined(SC92R445)||defined(SC92R429B)||defined(SC92R448M)||defined(SC92R449)||defined(SC92R450)\
	||defined(SC92R454)
	OPINX = tempOPINX;
    if(tempPWMFlag==1)
    {
        PWMCFG  = tempPWMINV;
        PWMCON = tempPWM;
        PWMCON &= ~0x80;
        tempPWMFlag = 0;
    }
#endif
    /* Restore global interrupt status */
    EA = tempEA;
    WriteFlag1 = 0;
}
#endif






/**
 * @brief  Erase a sector through IAP
 * @param  Add[in]: Target sector address for IAP erase operation
 * @retval None
 */
#if defined(SC95F8x1xB)||defined(SC95F7x1xB)||defined(SC95F8x6x)||defined(SC95F7x6x)||defined(SC95R503)||defined(SC95F8x3x)\
	||defined(SC95F8x7x)||defined(SC95F7x7x)||defined(SC95R702)||defined(SC95R61x)||defined(SC95R602)||defined(SC95R605)||defined(SC95R751)\
	||defined(SC92F6x1x)||defined(SC92R436)||defined(SC92R438)||defined(SC92R439)||defined(SC92R422A)||defined(YX2501)\
	||defined(SC92F652x)||defined(SC92R519)||defined(SC92R515)||defined(SC92R51x_R52x)||defined(SC92F552x)||defined(SC92F663x)\
    ||defined(SC92R523)||defined(SC92F563x)||defined(SC92R524)
void IAP_CodeSectorEraseOption(unsigned long Add)
{
	/* Save the current IAP operation area */
    unsigned char  tempADER = IAPADE;
    unsigned char  tempEA = EA;
	/* For the following chips, when HXT is enabled, PWM must be activated to enable HRC */
#if defined(SC95F8x7x)||defined(SC95F7x7x)||defined(SC95R503)||defined(SC95R61x)\
	||defined(SC92F6x1x)||defined(SC92R436)||defined(SC92R438)||defined(SC92R439)||defined(SC92R422A)||defined(YX2501)\
	||defined(SC92F652x)||defined(SC92R519)||defined(SC92R515)||defined(SC92R51x_R52x)||defined(SC92F552x)||defined(SC92R523)\
	||defined(SC92R524)
    /* Temporary storage for PWM configuration registers */
    unsigned char  tempOPINX = OPINX;
    unsigned char  tempPWM = 0;
    unsigned char  tempPWMINV = 0;
    unsigned char  tempPWMFlag = 0;
#endif
    /* Save original ROM bank register value */
#if defined(SC95F8x6x)||defined(SC95F7x6x)||defined(SC95F8x3x)||defined(SC95R702)
    unsigned int xdata tempROMBNK = ROMBNK;
#endif
    unsigned char  WriteFlag2=0xA5;

	/* If the global interrupt is enabled, it needs to be disabled to prevent IAP operation errors */
    EA = 0;
	/* For the following chips, when HXT is enabled, PWM must be activated to enable HRC */
#if defined(SC95F8x7x)||defined(SC95F7x7x)||defined(SC95R503)||defined(SC95R61x)\
	||defined(SC92F6x1x)||defined(SC92R436)||defined(SC92R438)||defined(SC92R439)||defined(SC92R422A)||defined(YX2501)\
	||defined(SC92F652x)||defined(SC92R519)||defined(SC92R515)||defined(SC92R51x_R52x)||defined(SC92F552x)||defined(SC92R523)\
	||defined(SC92R524)
	OPINX = 0xC1;
	if (OPREG & 0x40)
	{
		if ((PWMCON0 & 0x80) == 0)
		{
			tempPWM = PWMCON1;
			tempPWMINV = PWMCFG;
			PWMCFG = 0xFF;
			PWMCON1 = 0;
			tempPWMFlag = 1;
			PWMCON0 |= 0x80;
		}
	}
#endif

	/* If the address exceeds 64K, it is necessary to operate the Bank register to point to the target address */
#if defined(SC95F8x6x)||defined(SC95F7x6x)||defined(SC95F8x3x)||defined(SC95R702)
    if(Add >= 0x10000)
    {
        if(Add < 0x18000)
        {
            ROMBNK = (ROMBNK & 0xCC) | 0x22;
            Add = (Add - 0x8000);
        }
        else if(Add < 0x20000)
        {
            ROMBNK = (ROMBNK & 0xCC) | 0x33;
            Add = (Add - 0x10000);
        }
    }
    else
    {
        ROMBNK = (ROMBNK & 0xCC) | 0x11;
    }
#endif

    IAPADE = 0X00;
    /* Configure CPU holdtime */
#if defined(SC92F6x1x)||defined(SC92R436)||defined(SC92R438)||defined(SC92R439)||defined(SC92R422A)||defined(YX2501)\
    ||defined(SC92F652x)||defined(SC92R519)||defined(SC92R515)||defined(SC92R51x_R52x)||defined(SC92F552x)||defined(SC92R523)\
	||defined(SC92R524)
    IAP_SetHoldTimeForErase();
#endif
    IAPADH = (unsigned char)(Add >> 8);
    IAPADL = (unsigned char)Add;

	/* Unlock if IAP operation is allowed */
    if((IapWriteFlag==0x69)&&(WriteFlag2==0xA5))
    {
        IAPKEY = 0XF0;
	/* Set serase operation */
#if defined(SC95F8x1xB)||defined(SC95F7x1xB)||defined(SC95F8x6x)||defined(SC95F7x6x)||defined(SC95R503)||defined(SC95F8x3x)\
	||defined(SC95F8x7x)||defined(SC95F7x7x)||defined(SC95R702)||defined(SC95R61x)||defined(SC95R602)||defined(SC95R605)||defined(SC95R751)\
	||defined(SC92F663x)||defined(SC92F563x)
        IAPCTL = 0X20;
#else
        IAPCTL = 0X10;
#endif
    }

	/* Trigger IAP CMD command */
    if((IapWriteFlag==0x69)&&(WriteFlag2==0xA5))
    {
        if(IAPADE == 0)
        {
            IAPCTL |= 0x02;
        }
    }

    /* Hardware required delay for IAP operation */
    IAP_DelayASM();
	
    /* Restore IAP extension register */
    IAPADE = tempADER;
    /* Restore original ROM bank setting */
#if defined(SC95F8x6x)||defined(SC95F7x6x)||defined(SC95F8x3x)||defined(SC95R702)
    ROMBNK = tempROMBNK;
#endif
    /* Restore PWM configuration */
#if defined(SC95F8x7x)||defined(SC95F7x7x)||defined(SC95R503)||defined(SC95R61x)\
	||defined(SC92F6x1x)||defined(SC92R436)||defined(SC92R438)||defined(SC92R439)||defined(SC92R422A)||defined(YX2501)\
	||defined(SC92F652x)||defined(SC92R519)||defined(SC92R515)||defined(SC92R51x_R52x)||defined(SC92F552x)||defined(SC92R523)\
	||defined(SC92R524)
	OPINX = tempOPINX;
    if(tempPWMFlag==1)
    {
        PWMCFG  = tempPWMINV;
        PWMCON1 = tempPWM;
        PWMCON0 &= ~0x80;
        tempPWMFlag = 0;
    }
#endif
    /* Restore global interrupt status */
    EA = tempEA;
    WriteFlag2 = 0;
}
#endif





/**
 * @brief  Write one byte of data to EEPROM through IAP
 * @param  Add[in]: Target EEPROM address for IAP operation
 * @param  Data[in]: Byte data to be written to EEPROM
 * @retval None
 */
#if defined(SC95F8x1xB)||defined(SC95F7x1xB)||defined(SC95F8x6x)||defined(SC95F7x6x)||defined(SC95R503)||defined(SC95F8x3x)\
	||defined(SC95F8x7x)||defined(SC95F7x7x)||defined(SC95R702)||defined(SC95R61x)||defined(SC95R602)||defined(SC95R605)||defined(SC95R751)\
	||defined(SC92Fx41xB)||defined(SC92R445)||defined(SC92L840x)||defined(SC92R429B)||defined(SC92R448M)\
    ||defined(SC92R449)||defined(SC92R450)||defined(YX2501)||defined(SC92F652x)||defined(SC92R343)\
    ||defined(SC92R519)||defined(SC92F531x)||defined(SC92R515)||defined(SC92R348)||defined(SC92F5x5x)\
    ||defined(SC92F637x)||defined(SC92R51x_R52x)||defined(SC92F552x)||defined(SC92R349)||defined(SC92F663x)\
    ||defined(SC92R350)||defined(SC92R523)||defined(SC92R351)||defined(SC92F563x)||defined(SC92R352)\
	||defined(SC92R524)||defined(SC92R454)
void IAP_EEPROMProgramByteOption(unsigned int Add, unsigned char Data)
{
	/* Save the current IAP operation area */
    unsigned char  tempADER = IAPADE;
    unsigned char  tempEA = EA;
	/* For the following chips, when HXT is enabled, PWM must be activated to enable HRC */
#if defined(SC95F8x7x)||defined(SC95F7x7x)||defined(SC95R503)||defined(SC95R61x)\
	||defined(SC92Fx41xB)||defined(SC92R445)||defined(SC92L840x)||defined(SC92R429B)||defined(SC92R448M)\
    ||defined(SC92R449)||defined(SC92R450)||defined(YX2501)||defined(SC92F652x)||defined(SC92R519)\
	||defined(SC92R515)||defined(SC92R348)||defined(SC92R51x_R52x)||defined(SC92F552x)||defined(SC92R523)\
	||defined(SC92R524)||defined(SC92R454)
    /* Temporary storage for PWM configuration registers */
    unsigned char  tempOPINX = OPINX;
    unsigned char  tempPWM = 0;
    unsigned char  tempPWMINV = 0;
    unsigned char  tempPWMFlag = 0;
#endif
	
    unsigned char  WriteFlag3=0xA5;

	/* If the global interrupt is enabled, it needs to be disabled to prevent IAP operation errors */
    EA = 0;
	/* For the following chips, when HXT is enabled, PWM must be activated to enable HRC */
#if defined(SC95F8x7x)||defined(SC95F7x7x)||defined(SC95R503)||defined(SC95R61x)\
	||defined(SC92L840x)||defined(YX2501)||defined(SC92F652x)||defined(SC92R519)||defined(SC92R515)\
	||defined(SC92R51x_R52x)||defined(SC92F552x)||defined(SC92R523)||defined(SC92R524)
	OPINX = 0xC1;
	if (OPREG & 0x40)
	{
		if ((PWMCON0 & 0x80) == 0)
		{
			tempPWM = PWMCON1;
			tempPWMINV = PWMCFG;
			PWMCFG = 0xFF;
			PWMCON1 = 0;
			tempPWMFlag = 1;
			PWMCON0 |= 0x80;
		}
	}
#elif defined(SC92Fx41xB)||defined(SC92R445)||defined(SC92R429B)||defined(SC92R448M)||defined(SC92R449)||defined(SC92R450)||defined(SC92R348)\
	||defined(SC92R454)
	OPINX = 0xC1;
	if (OPREG & 0x40)
	{
		if ((PWMCON & 0x80) == 0)
		{
			tempPWM = PWMCON;
			tempPWMINV = PWMCFG;
			PWMCFG = 0xFF;
			PWMCON = 0;
			tempPWMFlag = 1;
			PWMCON |= 0x80;
		}
	}
#endif
	
    IAPADE = 0X02;
    IAPDAT = Data;
	
#if defined(SC92F531x)||defined(SC92F5x5x)||defined(SC92F637x)||defined(SC92R349)||defined(SC92R350)||defined(SC92R351)||defined(SC92R352)
    IAPAD = (unsigned char)(Add);
#else
    IAPADH = (unsigned char)(Add >> 8);
    IAPADL = (unsigned char)(Add);
#endif
	
    /* Verify EEPROM address is valid */
#if defined(SC95F8x3x)\
	||defined(SC92F663x)||defined(SC92F563x)
    if((((unsigned int)IAPADH << 8) + (unsigned int)IAPADL) < 0X400)
#elif defined(SC95F8x1xB)||defined(SC95F7x1xB)||defined(SC95F8x6x)||defined(SC95F7x6x)||defined(SC95R503)\
	||defined(SC95F8x7x)||defined(SC95F7x7x)||defined(SC95R702)||defined(SC95R61x)||defined(SC95R602)||defined(SC95R605)||defined(SC95R751)
    if((((unsigned int)IAPADH << 8) + (unsigned int)IAPADL) < 0X1800)
#elif defined(YX2501)||defined(SC92F652x)||defined(SC92R519)||defined(SC92R515)||defined(SC92R51x_R52x)||defined(SC92F552x)||defined(SC92R523)\
	||defined(SC92R524)
    if((((unsigned int)IAPADH << 8) + (unsigned int)IAPADL) < 0X200)
#elif defined(SC92F531x)||defined(SC92F5x5x)||defined(SC92F637x)||defined(SC92R349)||defined(SC92R350)||defined(SC92R351)||defined(SC92R352)
    if((unsigned char)IAPAD < 0X100)
#else
    if((((unsigned int)IAPADH << 8) + (unsigned int)IAPADL) < 0X80)
#endif
    {
	/* Unlock if IAP operation is allowed */
        if((IapWriteFlag==0x69)&&(WriteFlag3==0xA5))
        {
            IAPKEY = 0xF0;
	/* Set write operation */
#if defined(YX2501)||defined(SC92F652x)||defined(SC92R519)||defined(SC92R515)||defined(SC92R51x_R52x)||defined(SC92F552x)\
	||defined(SC92R523)||defined(SC92R524)
            IAPCTL = 0x08;
#endif
#if defined(SC95F8x1xB)||defined(SC95F7x1xB)||defined(SC95F8x6x)||defined(SC95F7x6x)||defined(SC95R503)||defined(SC95F8x3x)\
	||defined(SC95F8x7x)||defined(SC95F7x7x)||defined(SC95R702)||defined(SC95R61x)||defined(SC95R602)||defined(SC95R605)||defined(SC95R751)\
	||defined(SC92F663x)||defined(SC92F563x)
            IAPCTL = 0X10;
#endif
        }

	/* Trigger IAP CMD command */
        if((IapWriteFlag==0x69)&&(WriteFlag3==0xA5))
        {
            if(IAPADE == 0X02)
            {
                IAPCTL |= 0x02;
            }
        }
        IAP_DelayASM();
    }
	/* Wait for EBUSY bit to be set */
#if defined(SC92F531x)||defined(SC92F5x5x)||defined(SC92F637x)||defined(SC92R349)||defined(SC92R350)||defined(SC92R351)||defined(SC92R352)
    while((IAPCTL & 0x01) && (cnt <0xFFFF))
    {
        cnt++;
    }
    cnt = 0;
#endif
    /* Restore IAP address extension register */
    IAPADE = tempADER;

    /* Restore PWM configuration */
#if defined(SC95F8x7x)||defined(SC95F7x7x)||defined(SC95R503)||defined(SC95R61x)\
	||defined(SC92L840x)||defined(YX2501)||defined(SC92F652x)||defined(SC92R519)||defined(SC92R515)\
	||defined(SC92R51x_R52x)||defined(SC92F552x)||defined(SC92R523)||defined(SC92R524)
	OPINX = tempOPINX;
    if(tempPWMFlag==1)
    {
        PWMCFG  = tempPWMINV;
        PWMCON1 = tempPWM;
        PWMCON0 &= ~0x80;
        tempPWMFlag = 0;
    }
#elif defined(SC92Fx41xB)||defined(SC92R445)||defined(SC92R429B)||defined(SC92R448M)||defined(SC92R449)||defined(SC92R450)||defined(SC92R348)\
	||defined(SC92R454)
	OPINX = tempOPINX;
    if(tempPWMFlag==1)
    {
        PWMCFG  = tempPWMINV;
        PWMCON = tempPWM;
        PWMCON &= ~0x80;
        tempPWMFlag = 0;
    }
#endif
    /* Restore global interrupt status */
    EA = tempEA;
    WriteFlag3 = 0;
}
#endif







/**
 * @brief  Erase an EEPROM sector through IAP
 * @param  Add[in]: Target EEPROM sector address for IAP erase operation
 * @retval None
 */
#if defined(SC95F8x1xB)||defined(SC95F7x1xB)||defined(SC95F8x6x)||defined(SC95F7x6x)||defined(SC95R503)||defined(SC95F8x3x)\
	||defined(SC95F8x7x)||defined(SC95F7x7x)||defined(SC95R702)||defined(SC95R61x)||defined(SC95R602)||defined(SC95R605)||defined(SC95R751)\
	||defined(YX2501)||defined(SC92F652x)||defined(SC92R519)||defined(SC92R515)||defined(SC92R51x_R52x)||defined(SC92F552x)\
    ||defined(SC92F663x)||defined(SC92R523)||defined(SC92F563x)||defined(SC92R524)
void IAP_EEPROMSectorEraseOption(unsigned int Add)
{
	/* Save the current IAP operation area */
    unsigned char  tempADER = IAPADE;
    unsigned char  tempEA = EA;
	/* For the following chips, when HXT is enabled, PWM must be activated to enable HRC */
#if defined(SC95F8x7x)||defined(SC95F7x7x)||defined(SC95R503)||defined(SC95R61x)\
	||defined(YX2501)||defined(SC92F652x)||defined(SC92R519)||defined(SC92R515)||defined(SC92R51x_R52x)||defined(SC92F552x)||defined(SC92R523)\
	||defined(SC92R524)
    /* Temporary storage for PWM configuration registers */
    unsigned char  tempOPINX = OPINX;
    unsigned char  tempPWM = 0;
    unsigned char  tempPWMINV = 0;
    unsigned char  tempPWMFlag = 0;
#endif
    unsigned char  WriteFlag4=0xA5;

	/* If the global interrupt is enabled, it needs to be disabled to prevent IAP operation errors */
    EA = 0;
	/* For the following chips, when HXT is enabled, PWM must be activated to enable HRC */
#if defined(SC95F8x7x)||defined(SC95F7x7x)||defined(SC95R503)||defined(SC95R61x)\
	||defined(YX2501)||defined(SC92F652x)||defined(SC92R519)||defined(SC92R515)||defined(SC92R51x_R52x)||defined(SC92F552x)||defined(SC92R523)\
	||defined(SC92R524)
	OPINX = 0xC1;
	if (OPREG & 0x40)
	{
		if ((PWMCON0 & 0x80) == 0)
		{
			tempPWM = PWMCON1;
			tempPWMINV = PWMCFG;
			PWMCFG = 0xFF;
			PWMCON1 = 0;
			tempPWMFlag = 1;
			PWMCON0 |= 0x80;
		}
	}
#endif

    IAPADE = 0X02;
    /* Configure CPU holdtime */
#if defined(YX2501)||defined(SC92F652x)||defined(SC92R519)||defined(SC92R515)||defined(SC92R51x_R52x)||defined(SC92F552x)\
    ||defined(SC92R523)||defined(SC92R524)
    IAP_SetHoldTimeForErase();
#endif
    IAPADH = (unsigned char)(Add >> 8);
    IAPADL = (unsigned char)Add;

    /* Verify EEPROM address is valid */
#if defined(SC95F8x3x)||defined(SC92F663x)||defined(SC92F563x)
    if((((unsigned int)IAPADH << 8) + (unsigned int)IAPADL) < 0X400)
#elif defined(SC95F8x1xB)||defined(SC95F7x1xB)||defined(SC95F8x6x)||defined(SC95F7x6x)||defined(SC95R503)\
	||defined(SC95F8x7x)||defined(SC95F7x7x)||defined(SC95R702)||defined(SC95R61x)||defined(SC95R602)||defined(SC95R605)||defined(SC95R751)
    if((((unsigned int)IAPADH << 8) + (unsigned int)IAPADL) < 0X1800)
#elif defined(YX2501)||defined(SC92F652x)||defined(SC92R519)||defined(SC92R515)||defined(SC92R51x_R52x)||defined(SC92F552x)||defined(SC92R523)\
	||defined(SC92R524)
    if((((unsigned int)IAPADH << 8) + (unsigned int)IAPADL) < 0X200)
#endif
    {
		/* Unlock if IAP operation is allowed */
        if((IapWriteFlag==0x69)&&(WriteFlag4==0xA5))
        {
            IAPKEY = 0XF0;
		/* Set serase operation */
#if defined(SC95F8x1xB)||defined(SC95F7x1xB)||defined(SC95F8x6x)||defined(SC95F7x6x)||defined(SC95R503)||defined(SC95F8x3x)\
	||defined(SC95F8x7x)||defined(SC95F7x7x)||defined(SC95R702)||defined(SC95R61x)||defined(SC95R602)||defined(SC95R605)||defined(SC95R751)\
	||defined(SC92F663x)||defined(SC92F563x)
            IAPCTL = 0X20;
#else
            IAPCTL = 0X10;
#endif
        }

		/* Trigger IAP CMD command */
        if((IapWriteFlag==0x69)&&(WriteFlag4==0xA5))
        {
            if(IAPADE == 0X02)
            {
                IAPCTL |= 0x02;
            }
        }
		
		/* Hardware required delay for IAP operation */
        IAP_DelayASM();
    }

    /* Restore IAP address extension register */
    IAPADE = tempADER;

    /* Restore PWM configuration */
#if defined(SC95F8x7x)||defined(SC95F7x7x)||defined(SC95R503)||defined(SC95R61x)\
	||defined(YX2501)||defined(SC92F652x)||defined(SC92R519)||defined(SC92R515)||defined(SC92R51x_R52x)||defined(SC92F552x)||defined(SC92R523)\
	||defined(SC92R524)
	OPINX = tempOPINX;
    if(tempPWMFlag==1)
    {
        PWMCFG  = tempPWMINV;
        PWMCON1 = tempPWM;
        PWMCON0 &= ~0x80;
        tempPWMFlag = 0;
    }
#endif
    /* Restore global interrupt status */
    EA = tempEA;
    WriteFlag4 = 0;
}
#endif





/**
 * @brief  Configure CPU HoldTime for IAP operations
 * @note   Different hold time options for different MCU series:
 *           -  4ms/2ms/1ms:SC92Fx41xB / SC92R445 / SC92R429B / SC92R448 / SC92R449 / SC92R450 / SC92R343 / SC92R348 / SC92R454
 *           -  6ms/3ms/1.5ms:SC92L840x
 * @param  CPU_HoldTime[in]: CPU HoldTime configuration parameter
 *           CPU_Hold_4ms    : CPU Hold 4ms
 *           CPU_Hold_2ms    : CPU Hold 2ms
 *           CPU_Hold_1ms    : CPU Hold 1ms
 *           CPU_Hold_6ms    : CPU Hold 6ms (ONLY for SC92L840x)
 *           CPU_Hold_3ms    : CPU Hold 3ms (ONLY for SC92L840x)
 *           CPU_Hold_1_5ms  : CPU Hold 1.5ms (ONLY for SC92L840x)
 * @retval None
 */
#if defined(SC92Fx41xB)||defined(SC92R445)||defined(SC92L840x)||defined(SC92R429B)||defined(SC92R448)||defined(SC92R449)||defined(SC92R450)||defined(SC92R343)||defined(SC92R348)\
	||defined(SC92R454)
void CPU_HoldTime_Config(CPU_HoldTime_TypeDef CPU_HoldTime)
{
    unsigned char tempOPINX, tempOPREG;
    tempOPINX = OPINX;
    OPINX = 0xC2;
    tempOPREG = OPREG;
    OPREG &= ~0x0C;
    OPREG |= 0x04;

    IAPADH = 0x3F;
    IAPADL = 0xF0;

    IAPKEY = 0xF0;
    IAPCTL &= 0xF3;
    IAPCTL |= CPU_HoldTime;

    OPREG = tempOPREG;
    OPINX = tempOPINX;
}
#endif






/**
 * @brief  Configure EEPROM WriteTime for IAP operations
 * @param  EEPROM_WriteTime[in]: EEPROM WriteTime configuration parameter
 *         		EEPROM_WriteTime_4ms: The write time for EEPROM is 4ms
 *           	EEPROM_WriteTime_2ms: The write time for EEPROM is 2ms
 *           	EEPROM_WriteTime_1ms: The write time for EEPROM is 1ms
 * @retval None
 */
#if defined(SC92F531x)||defined(SC92F5x5x)||defined(SC92F637x)||defined(SC92R349)||defined(SC92R350)||defined(SC92R351)||defined(SC92R352)
void EEPROM_WriteTime_Config(EEPROM_WriteTime_TypeDef EEPROM_WriteTime)
{
    unsigned char  tempADER = IAPADE;
    unsigned char  tempEA = EA;

    EA = 0;

    IAPKEY = 0xF0;
    IAPADE = 0X02;
    IAPCTL &= 0xF3;
    IAPCTL |= EEPROM_WriteTime;
	
    IAPADE = tempADER;
    EA = tempEA;
}
#endif

/******************* (C) COPYRIGHT 2026 Shenzhen SaiYuan Microelectronics *****END OF FILE****/
