/*
 * @file exo_io_al_fmc_nor_flash_common.c
 *
 * @brief This file contains abstracted function definition for FMC-NOR-FLASH interface
 *
 * @copyright Copyright 2023 Antaris, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "exo_io_al_fmc_nor_flash_common.h"
#include "exo_io_al_stm32f7xx_fmc_nor.h"
#include "exo_osal.h"
#include "exo_common.h"

#ifndef LINUX_TEMP_PORT

extern void *intf_inst_hdle_ptr[MAX_IO_INST_ID];
/**
 * @brief  This API initializes the control block memory
 * and do the basic configurations for FMC-NOR-FLASH
 */
hal_ret_sts io_hal_fmc_nor_flash_init(ioal_fmc_nor_hdle *ioal_nor_flash, io_inst_id inst_id)
{
	hal_ret_sts ret_sts = HAL_MAX_ERR;


	switch(inst_id)
	{
		case IOAL_INST_FMC_NOR1:
			if(HAL_SCS == io_hal_common_fmc_nor_init(ioal_nor_flash))
			{
				intf_inst_hdle_ptr[IOAL_INST_FMC_NOR1] = ioal_nor_flash;
				ret_sts = HAL_SCS;
			}
			else
			{
				ret_sts = HAL_IO_VDP_ERR;
			}
			ioal_nor_flash->intf_gen_info.state = IO_FREE_STATE;
			break;


		default:
			ret_sts = HAL_IO_INIT_INVALID_INSTANCE;
			break;

	}

	return ret_sts;
}

/**
 * @brief  This API write data in FMC-NOR-FLASH
 */
hal_ret_sts io_hal_fmc_nor_flash_program(ioal_fmc_nor_hdle *ioal_nor, uint32 address, uint16* data)
{
	hal_ret_sts ret_sts = HAL_MAX_ERR;
	ioal_nor->intf_gen_info.state = IO_BUSY_STATE;
	if(HAL_SCS == io_hal_common_fmc_nor_program(ioal_nor,address,data))
	{
		ret_sts = HAL_SCS;
	}
	else
	{
		ret_sts = HAL_IO_VDP_ERR;
	}
	ioal_nor->intf_gen_info.state = IO_FREE_STATE;
	return ret_sts;
}

/**
 * @brief  This API erase and write data in FMC-NOR-FLASH
 */
hal_ret_sts io_hal_fmc_nor_flash_program_buffer(ioal_fmc_nor_hdle *ioal_nor, uint32 address, uint8 *data, uint32 buff_size)
{
	hal_ret_sts ret_sts = HAL_MAX_ERR;
	ioal_nor->intf_gen_info.state = IO_BUSY_STATE;
	if(HAL_SCS == io_hal_common_fmc_nor_program_buffer(ioal_nor,address,data,buff_size))
	{
		ret_sts = HAL_SCS;
	}
	else
	{
		ret_sts = HAL_IO_VDP_ERR;
	}
	ioal_nor->intf_gen_info.state = IO_FREE_STATE;
	return ret_sts;
}

/**
 * @brief  This API read data from FMC-NOR-FLASH
 */
hal_ret_sts io_hal_fmc_nor_flash_read(ioal_fmc_nor_hdle *ioal_nor, uint32 address, uint16* data)
{
	hal_ret_sts ret_sts = HAL_MAX_ERR;
	ioal_nor->intf_gen_info.state = IO_BUSY_STATE;
	if(HAL_SCS == io_hal_common_fmc_nor_read(ioal_nor,(uint32*)address,data))
	{
		ret_sts = HAL_SCS;
	}
	else
	{
		ret_sts = HAL_IO_VDP_ERR;
	}
	ioal_nor->intf_gen_info.state = IO_FREE_STATE;
	return ret_sts;
}

/**
 * @brief  This API read data from FMC-NOR-FLASH
 */
hal_ret_sts io_hal_fmc_nor_flash_read_buffer(ioal_fmc_nor_hdle *ioal_nor, uint32 address, uint8 *data, uint32 buff_size)
{
	hal_ret_sts ret_sts = HAL_MAX_ERR;
	ioal_nor->intf_gen_info.state = IO_BUSY_STATE;
	if(HAL_SCS == io_hal_common_fmc_nor_read_buffer(ioal_nor,address,data,buff_size))
	{
		ret_sts = HAL_SCS;
	}
	else
	{
		ret_sts = HAL_IO_VDP_ERR;
	}
	ioal_nor->intf_gen_info.state = IO_FREE_STATE;
	return ret_sts;
}
/**
 * @brief  This API erase the specified block of the NOR memory
 */
hal_ret_sts io_hal_fmc_nor_flash_erase_block(ioal_fmc_nor_hdle *ioal_nor, uint32 block_addr)
{
	hal_ret_sts ret_sts = HAL_MAX_ERR;
	ioal_nor->intf_gen_info.state = IO_BUSY_STATE;
	if(HAL_SCS == io_hal_stm32f7xx_fmc_nor_erase_block(ioal_nor,block_addr))
	{
		ret_sts = HAL_SCS;
	}
	else
	{
		ret_sts = HAL_IO_VDP_ERR;
	}
	ioal_nor->intf_gen_info.state = IO_FREE_STATE;
	return ret_sts;
}

/**
 * @brief  This API erase the entire NOR chip.
 */
hal_ret_sts io_hal_fmc_nor_flash_erase_chip(ioal_fmc_nor_hdle* ioal_nor)
{
	hal_ret_sts ret_sts = HAL_MAX_ERR;
	ioal_nor->intf_gen_info.state = IO_BUSY_STATE;
	if(HAL_SCS == io_hal_common_fmc_nor_erase_chip(ioal_nor))
	{
		ret_sts = HAL_SCS;
	}
	else
	{
		ret_sts = HAL_IO_VDP_ERR;
	}
	ioal_nor->intf_gen_info.state = IO_FREE_STATE;
	return ret_sts;
}

/**
 * @brief  This API read data from FMC-NOR-FLASH
 */
ioal_nor_state_t io_hal_fmc_nor_flash_get_state(ioal_fmc_nor_hdle* ioal_nor)
{
	ioal_nor_state_t ret_ste;
	ioal_nor->intf_gen_info.state = IO_BUSY_STATE;
	ret_ste = io_hal_common_fmc_nor_get_state(ioal_nor);
	ioal_nor->intf_gen_info.state = IO_FREE_STATE;
	return ret_ste;
}

/**
 * @brief  This API erase the specified block of the NOR memory
 */
ioal_nor_status_t io_hal_fmc_nor_flash_get_status(ioal_fmc_nor_hdle* ioal_nor, uint32 address, uint32 timeout)
{
	ioal_nor_status_t ret_sts;
	ioal_nor->intf_gen_info.state = IO_BUSY_STATE;
	ret_sts = io_hal_common_fmc_nor_get_status(ioal_nor,address,timeout);
	ioal_nor->intf_gen_info.state = IO_FREE_STATE;
	return ret_sts;
}

/**
 * @brief  This API erase the entire NOR chip.
 */
hal_ret_sts io_hal_fmc_nor_flash_write_enable(ioal_fmc_nor_hdle* ioal_nor)
{
	hal_ret_sts ret_sts = HAL_MAX_ERR;
	ioal_nor->intf_gen_info.state = IO_BUSY_STATE;
	if(HAL_SCS == io_hal_common_fmc_nor_write_enable(ioal_nor))
	{
		ret_sts = HAL_SCS;
	}
	else
	{
		ret_sts = HAL_IO_VDP_ERR;
	}
	ioal_nor->intf_gen_info.state = IO_FREE_STATE;
	return ret_sts;
}

/**
 * @brief  This API read data from FMC-NOR-FLASH
 */
hal_ret_sts io_hal_fmc_nor_flash_write_disable(ioal_fmc_nor_hdle* ioal_nor)
{
	hal_ret_sts ret_sts = HAL_MAX_ERR;
	ioal_nor->intf_gen_info.state = IO_BUSY_STATE;
	if(HAL_SCS == io_hal_common_fmc_nor_write_disable(ioal_nor))
	{
		ret_sts = HAL_SCS;
	}
	else
	{
		ret_sts = HAL_IO_VDP_ERR;
	}
	ioal_nor->intf_gen_info.state = IO_FREE_STATE;
	return ret_sts;
}

/**
 * @brief  This API erase the specified block of the NOR memory
 */
hal_ret_sts io_hal_fmc_nor_flash_return_to_read_mode(ioal_fmc_nor_hdle* ioal_nor)
{
	hal_ret_sts ret_sts = HAL_MAX_ERR;
	ioal_nor->intf_gen_info.state = IO_BUSY_STATE;
	if(HAL_SCS == io_hal_common_fmc_nor_return_to_read_mode(ioal_nor))
	{
		ret_sts = HAL_SCS;
	}
	else
	{
		ret_sts = HAL_IO_VDP_ERR;
	}
	ioal_nor->intf_gen_info.state = IO_FREE_STATE;
	return ret_sts;
}

/**
 * @brief  This API erase the entire NOR chip.
 */
hal_ret_sts io_hal_fmc_nor_flash_read_id(ioal_fmc_nor_hdle *ioal_nor, ioal_nor_id_t *id)
{
	hal_ret_sts ret_sts = HAL_MAX_ERR;
	ioal_nor->intf_gen_info.state = IO_BUSY_STATE;
	if(HAL_SCS == io_hal_common_fmc_nor_read_id(ioal_nor, id))
	{
		io_hal_fmc_nor_flash_return_to_read_mode(ioal_nor);
		ret_sts = HAL_SCS;
	}
	else
	{
		ret_sts = HAL_IO_VDP_ERR;
	}
	ioal_nor->intf_gen_info.state = IO_FREE_STATE;
	return ret_sts;
}

/**
 * @brief  This API erase the entire NOR chip.
 */
hal_ret_sts io_hal_fmc_nor_flash_read_cfi(ioal_fmc_nor_hdle *ioal_nor, ioal_nor_cfi_t *cfi)
{
	hal_ret_sts ret_sts = HAL_MAX_ERR;
	ioal_nor->intf_gen_info.state = IO_BUSY_STATE;
	if(HAL_SCS == io_hal_common_fmc_nor_read_cfi(ioal_nor, cfi))
	{
		io_hal_fmc_nor_flash_return_to_read_mode(ioal_nor);
		ret_sts = HAL_SCS;
	}
	else
	{
		ret_sts = HAL_IO_VDP_ERR;
	}
	ioal_nor->intf_gen_info.state = IO_FREE_STATE;
	return ret_sts;
}

/**
 * @brief  This API Re-initializes the control block memory
 * and do the basic configurations for FMC-NOR-FLASH
 */
hal_ret_sts io_hal_fmc_nor_flash_reinit(io_inst_id inst_id)
{
	hal_ret_sts ret_sts = HAL_MAX_ERR;
	ioal_fmc_nor_hdle *ioal_nor_flash;

	switch(inst_id)
	{
		case IOAL_INST_FMC_NOR1:
			ioal_nor_flash = intf_inst_hdle_ptr[IOAL_INST_FMC_NOR1];
			if(HAL_SCS == io_hal_common_fmc_nor_init(ioal_nor_flash))
			{
				ret_sts = HAL_SCS;
			}
			else
			{
				ret_sts = HAL_IO_VDP_ERR;
			}
			ioal_nor_flash->intf_gen_info.state = IO_FREE_STATE;
			break;


		default:
			ret_sts = HAL_IO_INIT_INVALID_INSTANCE;
			break;

	}

	return ret_sts;
}

#endif
