/*
 * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD
 * All rights reserved.
 *
 * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use
 * exclusively with CVA's microcontroller products. This file can be freely
 * distributed within development tools that are supporting such microcontroller
 * products.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
 * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
 * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL,
 * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
 */

#ifndef _FLS_H_
#define _FLS_H_

/*! \brief Contains public interface to various functions related
 *         to the FLS module
 */

/*******************************************************************************
 * the includes
 ******************************************************************************/
#include <stdbool.h>
#include <stdint.h>
#include "mcu.h"
#include "bootloader_cfg.h"

#ifdef __cplusplus
extern "C" {
#endif

/*******************************************************************************
 * the defines
 ******************************************************************************/
/* One erase section bytes size is 1024 */
#define FLS_ERASE_SECTION_ADDR_ALIGNED_MASK (0x3FFu)
#define FLS_PGM_SECTION_ADDR_ALIGNED_MASK   (0x07u)
#define FLS_PGM_PHRASE_BYTE_SIZE            (0x08u)
#define FLS_ERASE_SECTION_SIZE              (FLS_ERASE_SECTION_ADDR_ALIGNED_MASK + 1u)
#define FLS_PGM_SECTION_SIZE                (FLS_ERASE_SECTION_SIZE)
#define FLS_FASTRAM_ADDR                    (0x14000000UL)

/*******************************************************************************
 * the typedefs
 ******************************************************************************/
typedef enum
{
    FLS_STD_RETURN_OK = 0u,
    FLS_STD_RETURN_ADDR_INVALID,
    FLS_STD_RETURN_DATA_INVALID,
    FLS_STD_RETURN_LEN_INVALID,
    FLS_STD_RETURN_FLASH_DRIVER_INVALID,
    FLS_STD_RETURN_PGM_NG,
    FLS_STD_RETURN_CHECK_PHASE_NG,
    FLS_STD_RETURN_ERASE_NG,
    FLS_STD_RETURN_PENDING,
    FLS_STD_RETURN_BUSY,
    FLS_STD_RETURN_TIMEOUT,
    FLS_STD_RETURN_VIRGIN,

} Fls_StdRtnType;

#if(BOOTLOADER_CFG_FLS_CODE_GENERATE_EN != 0u)

/*******************************************************************************
 * the globals
 ******************************************************************************/

/*******************************************************************************
 * the function prototypes
 ******************************************************************************/

/*! \brief Initializes the Flash driver module
 *
 * This function initializes Flash driver by setting the register
 * instance to it.
 *
 * \param[in] flashDrvPtr : pointer to Flash driver instance
 * \return void
 */
extern
#if(BOOTLOADER_CFG_FLS_COPY_AUTO_EN == 1u)
    __attribute__((section(".code_ram")))
#else
    __attribute__((section(".ram_flash_driver")))
#endif
    void
    Fls_Init(FlashDrvType *obj);

/*! \brief Erased the pflash
 *
 * This function erase the length located in the pflash
 *
 * \param[in] targetAddress : pointer to pFlash address
 * \param[in] sectorNum : how many sector to be erased
 * \return Fls_StdRtnType
 */
extern
#if(BOOTLOADER_CFG_FLS_COPY_AUTO_EN == 1u)
    __attribute__((section(".code_ram")))
#else
    __attribute__((section(".ram_flash_driver")))
#endif
    Fls_StdRtnType
    Fls_Erase(uint32_t targetAddress, uint32_t sectorNum);

/*! \brief Write datas to pflash
 *
 * This function wrtie the length bytes to pflash
 *
 * \param[in] targetAddress : the target address to begin to write in pflash
 * \param[in] sourceAddressPtr : pointer to write data buffer
 * \param[in] bytesNum : how many bytes to be written to pflash
 * \return Fls_StdRtnType
 */
extern
#if(BOOTLOADER_CFG_FLS_COPY_AUTO_EN == 1u)
    __attribute__((section(".code_ram")))
#else
    __attribute__((section(".ram_flash_driver")))
#endif
    Fls_StdRtnType
    Fls_Write(uint32_t targetAddress, const uint8_t* sourceAddressPtr, uint32_t bytesNum);

/*! \brief Read out data from pflash
 *
 * This function read out the length bytes data from pflash
 *
 * \param[in] readAddress : the target address to begin to read in pflash
 * \param[in] readBufferPtr : pointer to store read out datas
 * \param[in] bytesNum : how many bytes to be readout from pflash
 * \return Fls_StdRtnType
 */
extern Fls_StdRtnType Fls_Read(uint32_t readAddress, uint8_t *readBufferPtr, uint32_t bytesNum);

/*! \brief Compare written datas in pflash
 *
 * This function compare the written length datas
 *
 * \param[in] sourceAddressPtr : pointer to  stored in localed buffer
 * \param[in] targetAddressPtr : pointer to stored in pflash
 * \param[in] bytesNum : how many bytes to be compared from pflash
 * \return Fls_StdRtnType
 */
extern Fls_StdRtnType Fls_Compare(const uint8_t *sourceAddressPtr, const uint8_t *targetAddressPtr, uint32_t bytesNum);

/*! \brief Check the flash is write or not been write
 *
 * This function Check the flash is write or not been write
 *
 * \param[in] memAddress : the target address to begin to read in pflash
 * \return Fls_StdRtnType
 */
extern Fls_StdRtnType Fls_CheckWriteState(uint32_t memAddress);

#else

/*! \brief Read out data from pflash
 *
 * This function read out the length bytes data from pflash
 *
 * \param[in] readAddress : the target address to begin to read in pflash
 * \param[in] readBufferPtr : pointer to store read out datas
 * \param[in] bytesNum : how many bytes to be readout from pflash
 * \return Fls_StdRtnType
 */
extern Fls_StdRtnType Fls_Read(uint32_t readAddress, uint8_t* readBufferPtr, uint32_t bytesNum);

/*! \brief Compare written datas in pflash
 *
 * This function compare the written length datas
 *
 * \param[in] sourceAddressPtr : pointer to  stored in localed buffer
 * \param[in] targetAddressPtr : pointer to stored in pflash
 * \param[in] bytesNum : how many bytes to be compared from pflash
 * \return Fls_StdRtnType
 */
extern Fls_StdRtnType Fls_Compare(const uint8_t* sourceAddressPtr, const uint8_t* targetAddressPtr, uint32_t bytesNum);

/*! \brief Check the flash is write or not been write
 *
 * This function Check the flash is write or not been write
 *
 * \param[in] memAddress : the target address to begin to read in pflash
 * \return Fls_StdRtnType
 */
extern Fls_StdRtnType Fls_CheckWriteState(uint32_t memAddress);

#endif

#ifdef __cplusplus
}
#endif /* extern "C" */

#endif
