/*
 * @file exo_io_al_qspi_common.c
 *
 * @brief This file contains abstracted function definition for QSPI 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.
 */

#ifndef _EXO_IO_AL_QSPI_COMMON_H_
#define _EXO_IO_AL_QSPI_COMMON_H_

#include "exo_io_al_common.h"
#include "exo_hal_common.h"



#define QSPI_INTF_ENB


/**
 * @brief IO-HAl QSPI interface control block handle structure definition
 */
typedef struct _ioal_qspi_hdle
{
  ioal_intf_gen_info intf_gen_info;						/*!< Hold general information of interface  						*/
  void (* qspi_error_cb)         (struct _ioal_qspi_hdle *hqspi);
  void (* qspi_abort_cplt_cb)    (struct _ioal_qspi_hdle *hqspi);
  void (* qspi_fifo_threshold_cb)(struct _ioal_qspi_hdle *hqspi);
  void (* qspi_cmd_cplt_cb)      (struct _ioal_qspi_hdle *hqspi);
  void (* qspi_rx_cplt_cb)       (struct _ioal_qspi_hdle *hqspi);
  void (* qspi_tx_cplt_cb)       (struct _ioal_qspi_hdle *hqspi);
  void (* qspi_status_match_cb)  (struct _ioal_qspi_hdle *hqspi);
}ioal_qspi_hdle;






/**
  * @brief  ioal_qspi Command structure definition
  */
typedef struct
{
  uint32 Instruction;        /* Specifies the Instruction to be sent
                                  This parameter can be a value (8-bit) between 0x00 and 0xFF */
  uint32 Address;            /* Specifies the Address to be sent (Size from 1 to 4 bytes according AddressSize)
                                  This parameter can be a value (32-bits) between 0x0 and 0xFFFFFFFF */
  uint32 AlternateBytes;     /* Specifies the Alternate Bytes to be sent (Size from 1 to 4 bytes according AlternateBytesSize)
                                  This parameter can be a value (32-bits) between 0x0 and 0xFFFFFFFF */
  uint32 AddressSize;        /* Specifies the Address Size
                                  This parameter can be a value of @ref QSPI_AddressSize */
  uint32 AlternateBytesSize; /* Specifies the Alternate Bytes Size
                                  This parameter can be a value of @ref QSPI_AlternateBytesSize */
  uint32 DummyCycles;        /* Specifies the Number of Dummy Cycles.
                                  This parameter can be a number between 0 and 31 */
  uint32 InstructionMode;    /* Specifies the Instruction Mode
                                  This parameter can be a value of @ref QSPI_InstructionMode */
  uint32 AddressMode;        /* Specifies the Address Mode
                                  This parameter can be a value of @ref QSPI_AddressMode */
  uint32 AlternateByteMode;  /* Specifies the Alternate Bytes Mode
                                  This parameter can be a value of @ref QSPI_AlternateBytesMode */
  uint32 DataMode;           /* Specifies the Data Mode (used for dummy cycles and data phases)
                                  This parameter can be a value of @ref QSPI_DataMode */
  uint32 NbData;             /* Specifies the number of data to transfer. (This is the number of bytes)
                                  This parameter can be any value between 0 and 0xFFFFFFFF (0 means undefined length
                                  until end of memory)*/
  uint32 DdrMode;            /* Specifies the double data rate mode for address, alternate byte and data phase
                                  This parameter can be a value of @ref QSPI_DdrMode */
  uint32 DdrHoldHalfCycle;   /* Specifies if the DDR hold is enabled. When enabled it delays the data
                                  output by one half of system clock in DDR mode.
                                  This parameter can be a value of @ref QSPI_DdrHoldHalfCycle */
  uint32 SIOOMode;           /* Specifies the send instruction only once mode
                                  This parameter can be a value of @ref QSPI_SIOOMode */
}ioal_qspi_CommandTypeDef;

/**
  * @brief  ioal_qspi Auto Polling mode configuration structure definition
  */
typedef struct
{
  uint32 Match;              /* Specifies the value to be compared with the masked status register to get a match.
                                  This parameter can be any value between 0 and 0xFFFFFFFF */
  uint32 Mask;               /* Specifies the mask to be applied to the status bytes received.
                                  This parameter can be any value between 0 and 0xFFFFFFFF */
  uint32 Interval;           /* Specifies the number of clock cycles between two read during automatic polling phases.
                                  This parameter can be any value between 0 and 0xFFFF */
  uint32 StatusBytesSize;    /* Specifies the size of the status bytes received.
                                  This parameter can be any value between 1 and 4 */
  uint32 MatchMode;          /* Specifies the method used for determining a match.
                                  This parameter can be a value of @ref QSPI_MatchMode */
  uint32 AutomaticStop;      /* Specifies if automatic polling is stopped after a match.
                                  This parameter can be a value of @ref QSPI_AutomaticStop */
}ioal_qspi_AutoPollingTypeDef;

/**
  * @brief  ioal_qspi Memory Mapped mode configuration structure definition
  */
typedef struct
{
  uint32 TimeOutPeriod;      /* Specifies the number of clock to wait when the FIFO is full before to release the chip select.
                                  This parameter can be any value between 0 and 0xFFFF */
  uint32 TimeOutActivation;  /* Specifies if the timeout counter is enabled to release the chip select.
                                  This parameter can be a value of @ref QSPI_TimeOutActivation */
}ioal_qspi_MemoryMappedTypeDef;





/**
  * @brief  This function initializes the qspi interface
  *
  * @retval HAL status
  */
hal_ret_sts io_hal_qspi_init(ioal_qspi_hdle *ioal_hqspi, io_inst_id inst_id);


/**
  * @brief  This function deinitializes the qspi interface
  *
  * @retval HAL status
  */
hal_ret_sts     io_hal_qspi_deInit   (io_inst_id inst_id);


/**
  * @brief  This function de initialize and initializes the qspi interface
  *
  * @retval HAL status
  */
hal_ret_sts 	io_hal_qspi_deinit_init(void);


/* QSPI IRQ handler method */
void            io_hal_qspi_IRQHandler(ioal_qspi_hdle *hqspi);


/**
  * @brief  This function send the command configuration
  *
  * @retval HAL status
  */
hal_ret_sts     io_hal_qspi_command      (ioal_qspi_hdle *hqspi, ioal_qspi_CommandTypeDef *cmd, uint32 timeout);

/**
  * @brief  This function transmit the data bytes
  *
  * @retval HAL status
  */
hal_ret_sts     io_hal_qspi_transmit     (ioal_qspi_hdle *hqspi, uint8 *pData, uint32 timeout);

/**
  * @brief  This function used to receive data bytes
  *
  * @retval HAL status
  */
hal_ret_sts     io_hal_qspi_receive      (ioal_qspi_hdle *hqspi, uint8 *pData, uint32 timeout);


/**
  * @brief  This function enables QSPI status flag polling mode
  *
  * @retval HAL status
  */
hal_ret_sts     io_hal_qspi_auto_polling   (ioal_qspi_hdle *hqspi, ioal_qspi_CommandTypeDef *cmd, ioal_qspi_AutoPollingTypeDef *cfg, uint32 timeout);


/**
  * @brief  This function enables QSPI memory-mapped mode
  *
  * @retval HAL status
  */
hal_ret_sts     io_hal_qspi_memory_mapped(ioal_qspi_hdle *hqspi, ioal_qspi_CommandTypeDef *cmd, ioal_qspi_MemoryMappedTypeDef *cfg);


/**
  * @brief  This function Re initialize the qspi interface
  *
  * @retval HAL status
  */
hal_ret_sts     io_hal_qspi_reinit(io_inst_id inst_id);



#endif /* _EXO_IO_AL_QSPI_COMMON_H_ */
