/**
  ******************************************************************************
  * @file    kpm32xx_ddl_flash.h
  * @author  Kiwi Software Team
  * @brief   Header file of FLASH DDL module.
  * @note
  *          V1.0.0, 2024/12/20.
  *
  * Copyright (c) 2024, Kiwi Instruments Co,. Ltd.
  *
  * 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 __KPM32xx_DDL_FLASH_H
#define __KPM32xx_DDL_FLASH_H

#ifdef __cplusplus
extern "C" {
#endif

#include "kpm32xx_ddl_def.h"



/* FLASH unlock keys */
#define FLASH_KEY                      0x53414645U


/* FLASH Program Type */
#define FLASH_TYPEPROGRAM_WORD         0x00000000U  /* Program a word (32-bit) at a specified address       */
#define FLASH_TYPEPROGRAM_HALFWORD     0x00000001U  /* Program a half-word (16-bit) at a specified address  */
#define FLASH_TYPEPROGRAM_BYTE         0x00000002U  /* Program a byte (8-bit) at a specified address        */



/* ICACHE/DCACHE Init structure definition */
typedef struct
{
	uint32_t       prefetchEnable;          /* Enable CACHE prefetch feature or not. */
	uint32_t       statisticEnable;         /* Enable CACHE statistic feature or not. */
} CacheInit_T;


/* Enable the specified FLASH interrupt */
#define __DDL_FLASH_ENABLE_IT(__INTERRUPT__)  SET_BIT(FLASHCTRL->CTRL, __INTERRUPT__)

/* Disable the specified FLASH interrupt */
#define __DDL_FLASH_DISABLE_IT(__INTERRUPT__)  CLEAR_BIT(FLASHCTRL->CTRL, __INTERRUPT__)

/* Get the specified FLASH flag status */
#define __DDL_FLASH_GET_FLAG(__FLAG__)   GET_BITS(FLASHCTRL->ST, __FLAG__)

/* Clear the specified FLASH flags */
#define __DDL_FLASH_CLEAR_FLAG(__FLAG__)   WRITE_REG(FLASHCTRL->ST, __FLAG__)

/* Set program mode */
#define __DDL_FLASH_SET_PROG_MODE(__MODE__)  SET_BITMASK(FLASHCTRL->CTRL, FLASH_CTRL_PROGMODE_Mask, __MODE__)

/* Set Flash operation(program/page erase/mass erase) */
#define __DDL_FLASH_SET_CMD(__CMD__)  SET_BITMASK(FLASHCTRL->CMD, FLASH_CMD_OP_Mask, __CMD__)

/* Flash start operation(program/page erase/mass erase) */
#define __DDL_FLASH_START(void)  SET_BIT(FLASHCTRL->CMD, FLASH_CMD_START)

/* Check Flash in security mode or not */
#define __DDL_IS_FLASH_IN_SECURITY(void)   (FLASHCTRL->SYS & 0x01UL)

/* Check Flash page protect or not */
#define __DDL_IS_FLASH_PAGE_PROTECT(void)   (FLASHCTRL->PROT)

/* Enable ICACHE */
#define __DDL_ICACHE_ENABLE(void)   SET_BIT(ICACHE->CTRL, ICACHE_CTRL_ENABLE)

/* Enable DCACHE */
#define __DDL_DCACHE_ENABLE(void)   SET_BIT(DCACHE->CTRL, DCACHE_CTRL_ENABLE)

/* Disable ICACHE */
#define __DDL_ICACHE_DISABLE(void)  CLEAR_BIT(ICACHE->CTRL, ICACHE_CTRL_ENABLE)

/* Disable DCACHE */
#define __DDL_DCACHE_DISABLE(void)  CLEAR_BIT(DCACHE->CTRL, DCACHE_CTRL_ENABLE)


/**
  * @brief  Enable ICACHE.
  * @retval None
  */
void DDL_ICACHE_Enable(void);

/**
  * @brief  Disable ICACHE.
  * @retval None
  */
void DDL_ICACHE_Disable(void);

/**
  * @brief  Enable DCACHE.
  * @retval None
  */
void DDL_DCACHE_Enable(void);

/**
  * @brief  Disable DCACHE.
  * @retval None
  */
void DDL_DCACHE_Disable(void);

/**
  * @brief  Initialize ICACHE according to specified parameters.
  * @param  init  Point to CACHE initial parameters.
  * @retval None
  */
void DDL_ICACHE_Init(CacheInit_T *init);

/**
  * @brief  Initialize DCACHE according to specified parameters.
  * @param  init  Point to CACHE initial parameters.
  * @retval None
  */
void DDL_DCACHE_Init(CacheInit_T *init);

/**
  * @brief  Enable Flash interrupt.
  * @retval None.
  */
void DDL_Flash_IntEnable(void);

/**
  * @brief  Disable Flash interrupt.
  * @retval None.
  */
void DDL_Flash_IntDisable(void);

/**
  * @brief  Unlock the FLASH control register access
  * @retval None
  */
void DDL_FLASH_Unlock(void);

/**
  * @brief  Locks the FLASH control register access
  * @retval None
  */
void DDL_FLASH_Lock(void);

/**
  * @brief  Set the FLASH Latency
  * @retval None
  */
void DDL_FLASH_SetLatency(uint32_t latency);

/**
  * @brief  Get the FLASH Latency
  * @retval latency.
  */
uint32_t DDL_FLASH_GetLatency(void);

/**
  * @brief  Get the specific FLASH error flag.
  * @retval FLASH_ErrorCode.
  */
uint32_t DDL_FLASH_GetErrorCode(void);

/**
  * @brief  Program word (32-bit) at a specified address.
  * @param  address  specifies the address to be programmed.
  * @param  data     specifies the data to be programmed.
  * @retval DDL Status
  */
DDL_Status_T DDL_FLASH_ProgramWord(uint32_t address, uint32_t data);

/**
  * @brief  Program a half-word (16-bit) at a specified address.
  * @param  address  specifies the address to be programmed.
  * @param  data     specifies the data to be programmed.
  * @retval DDL Status
  */
DDL_Status_T DDL_FLASH_ProgramHalfWord(uint32_t address, uint16_t data);

/**
  * @brief  Program byte (8-bit) at a specified address.
  * @param  address  specifies the address to be programmed.
  * @param  data     specifies the data to be programmed.
  * @retval DDL Status
  */
DDL_Status_T DDL_FLASH_ProgramByte(uint32_t address, uint8_t data);

/**
  * @brief  Erase the specified FLASH memory sector
  * @param  sector  FLASH sector to erase
  * @retval DDL Status
  */
DDL_Status_T DDL_FLASH_EraseSector(uint32_t sector);

/**
  * @brief  Read FLASH data
  * @param  address  specifies the address to read data.
  * @param  data     specifies the buffer to store data.
  * @param  cnt      specifies the size to read back.
  * @retval DDL Status
  */
DDL_Status_T DDL_FLASH_Read(uint32_t address, uint8_t *data, uint32_t cnt);


#ifdef __cplusplus
}
#endif

#endif /* __KPM32xx_DDL_FLASH_H */

