/*!
* @file     Spi.h
*
* @version  1.0.0
*
* @brief    Header file of AUTOSAR Spi driver.This file contains the definitions of spi driver used.
*
* @attention
*
* Project Name      : AUTOSAR MCAL
*
* Platform          : Arm
*
* Autosar Standard  : Classic Platform 4.4.0
*
* Compiled Version  : G32A10xx_MCAL_1_0_0_01-Otc-25
*
* Copyright (C) 2026 Geehy Semiconductor
*
* You may not use this file except in compliance with the
* GEEHY COPYRIGHT NOTICE (Geehy Semiconductor Software License Agreement).
*
* The program is only for reference, which is distributed in the hope
* that it will be usefull and instructional for customers to develop
* their software. Unless required by applicable law or agreed to in
* writing, the program is distributed on an "AS IS" BASIS, WITHOUT
* ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
* See the Geehy Semiconductor Software License Agreement for the governing permissions
* and limitations under the License.
*/

#ifndef SPI_H
#define SPI_H

#ifdef __cplusplus
extern "C"
{
#endif

#include "Std_Types.h"
#include "Mcal.h"
#include "Spi_Cfg.h"
/** @addtogroup G32A10xx_StdPeriphDriver
  @{
*/

/** @defgroup SPI_Driver
  * @brief SPI driver modules
  @{
*/

/** @defgroup SPI_Macros
  @{
*/
/**************************************************************************
                  VENDOR ID & AUTOSAR VERSION INFO
**************************************************************************/
/** Vendor ID (vendorId) of the dedicated implementation of this module according to the AUTOSAR vendor list. */
#define SPI_H_VENDOR_ID                       0x00C1U
/** Module ID of this module, as defined in the BSW Module List. */
#define SPI_H_MODULE_ID                       0x0053U
/** Major version number of AUTOSAR release on which the appropriate implementation is based on. */
#define SPI_H_AR_RELEASE_MAJOR_VERSION        0x04U
/** Minor version number of AUTOSAR release on which the appropriate implementation is based on. */
#define SPI_H_AR_RELEASE_MINOR_VERSION        0x04U
/** Revision version number of AUTOSAR release on which the appropriate implementation is based on. */
#define SPI_H_AR_RELEASE_REVISION_VERSION     0x00U
/** Major version number of the vendor specific implementation of the module. The numbering is vendor specific. */
#define SPI_H_SW_MAJOR_VERSION                0x01U
/** Minor version number of the vendor specific implementation of the module. The numbering is vendor specific. */
#define SPI_H_SW_MINOR_VERSION                0x00U
/** Patch level version number of the vendor specific implementation of the module. The numbering is vendor specific. */
#define SPI_H_SW_PATCH_VERSION                0x00U

/**************************************************************************
                    VERSION INFOMATION VERIFICATION
**************************************************************************/
#ifdef ENABLE_INTERMODULE_MCAL_CHECK

    /* Make sure the AUTOSAR major version number is the same between Spi.h and Mcal.h */
    #if (SPI_H_AR_RELEASE_MAJOR_VERSION != MCAL_H_AR_RELEASE_MAJOR_VERSION) 
        #error "AUTOSAR Major Version Number mismatch between Spi.h and Mcal.h"
    #endif
    /* Make sure the AUTOSAR minor version number is the same between Spi.h and Mcal.h */
    #if (SPI_H_AR_RELEASE_MINOR_VERSION != MCAL_H_AR_RELEASE_MINOR_VERSION)
        #error "AUTOSAR Minor Version Number mismatch between Spi.h and Mcal.h"
    #endif

    /* Make sure the AUTOSAR major version number is the same between Spi.h and Std_Types.h */
    #if (SPI_H_AR_RELEASE_MAJOR_VERSION != STD_TYPES_H_AR_RELEASE_MAJOR_VERSION) 
        #error "AUTOSAR Major Version Number mismatch between Spi.h and Std_Types.h"
    #endif
    /* Make sure the AUTOSAR minor version number is the same between Spi.h and Std_Types.h */
    #if (SPI_H_AR_RELEASE_MINOR_VERSION != STD_TYPES_H_AR_RELEASE_MINOR_VERSION)
        #error "AUTOSAR Minor Version Number mismatch between Spi.h and Std_Types.h"
    #endif

#endif

/* Make sure the vendor id is the same between Spi.h and Spi_Cfg.h */
#if (SPI_H_VENDOR_ID != SPI_CFG_H_VENDOR_ID)
    #error "Vendor id mismatch between Spi.h and Spi_Cfg.h" 
#endif
/* Make sure the AUTOSAR major version number is the same between Spi.h and Spi_Cfg.h */
#if (SPI_H_AR_RELEASE_MAJOR_VERSION != SPI_CFG_H_AR_RELEASE_MAJOR_VERSION) 
    #error "AUTOSAR Major Version Number mismatch between Spi.h and Spi_Cfg.h"
#endif
/* Make sure the AUTOSAR minor version number is the same between Spi.h and Spi_Cfg.h */
#if (SPI_H_AR_RELEASE_MINOR_VERSION != SPI_CFG_H_AR_RELEASE_MINOR_VERSION)
    #error "AUTOSAR Minor Version Number mismatch between Spi.h and Spi_Cfg.h"
#endif
/* Make sure the AUTOSAR revision version number is the same between Spi.h and Spi_Cfg.h */
#if (SPI_H_AR_RELEASE_REVISION_VERSION != SPI_CFG_H_AR_RELEASE_REVISION_VERSION)
    #error "AUTOSAR Revision Version Number mismatch between Spi.h and Spi_Cfg.h"
#endif
/* Make sure the software major version number is the same between Spi.h and Spi_Cfg.h */
#if (SPI_H_SW_MAJOR_VERSION != SPI_CFG_H_SW_MAJOR_VERSION) 
    #error "Software Major Version Number mismatch between Spi.h and Spi_Cfg.h "
#endif
/* Make sure the software minor version number is the same between Spi.h and Spi_Cfg.h */
#if (SPI_H_SW_MINOR_VERSION != SPI_CFG_H_SW_MINOR_VERSION) 
    #error "Software Minor Version Number mismatch between Spi.h and Spi_Cfg.h "
#endif
/* Make sure the software patch version number is the same between Spi.h and Spi_Cfg.h */
#if(SPI_H_SW_PATCH_VERSION != SPI_CFG_H_SW_PATCH_VERSION)
    #error "Software Patch Version Number mismatch between Spi.h and Spi_Cfg.h "
#endif

/**************************************************************************
                    MACRO DEFINITION
**************************************************************************/
/** HW unit can configure as Sync or Async mode */
#define SPI_PHYUNIT_SYNC_U32        ((uint32)1u)
#define SPI_PHYUNIT_ASYNC_U32       ((uint32)0u)

/** AUOTSAR Development Errors */

/** API service called with wrong parameter */
#define SPI_E_PARAM_CHANNEL       ((uint8)0x0Au)
#define SPI_E_PARAM_JOB           ((uint8)0x0Bu)
#define SPI_E_PARAM_SEQ           ((uint8)0x0Cu)
#define SPI_E_PARAM_LENGTH        ((uint8)0x0Du)
#define SPI_E_PARAM_UNIT          ((uint8)0x0Eu)
/** APIs called with a Null Pointer */
#define SPI_E_PARAM_POINTER       ((uint8)0x10u)
/** API service used without module initiali-zation */
#define SPI_E_UNINIT              ((uint8)0x1Au)
/** API SPI_Init service called while the SPI driver has already been initialized */
#define SPI_E_ALREADY_INITIALIZED ((uint8)0x4Au)

/** AUOTSAR Runtime Errors */

/** Services called in a wrong sequence */
#define SPI_E_SEQ_PENDING         ((uint8)0x2Au)
/** Synchronous transmission service called at wrong time*/
#define SPI_E_SEQ_IN_PROCESS      ((uint8)0x3Au)

/** Vendor Errors define */

/** The number of sequences, jobs or channels exceeds the precompile time
*    related sizes: SPI_SEQCFG_NUM, SPI_JOBCFG_NUM or SPI_CHANNELCFG_NUM.
*/
#define SPI_E_CONFIG_OUT_RANGE         ((uint8)0x5Au)

/** External buffers uninitialized in sequence */
#define SPI_E_PARAM_EXT_BUF_UNIT       ((uint8)0x5Bu)

/** sequence do not include any jobs */
#define SPI_E_SEQUENCE_EMPTY           ((uint8)0x5Cu)

/** job do not include any channels */
#define SPI_E_JOB_EMPTY                ((uint8)0x5Du)

/** Transmit the default transmit value configured if SrcDataBufferPtr being a Null pointer. */
#define SPI_CHANNEL_TX_DEFAULT_VALUE_FLAG ((uint8) 0x01u)
/** Ignore the received data after a Transmit method is requested if DesDataBufferPtr being a Null pointer. */
#define SPI_CHANNEL_RX_IGNORE_FLAG ((uint8) 0x02u)

/** API Service ID define according to AUTOSAR SPI Driver software spec,used when raising an error or exception */
/** Spi_Init: Service ID */
#define SPI_INIT_SERVICE_ID                   ((uint8) 0x00u)
/** Spi_DeInit: Service ID */
#define SPI_DEINIT_SERVICE_ID                 ((uint8) 0x01u)
/** Spi_WriteIB: Service ID */
#define SPI_WRITEIB_SERVICE_ID                ((uint8) 0x02u)
/** Spi_AsyncTransmit: Service ID */
#define SPI_ASYNCTRANSMIT_SERVICE_ID          ((uint8) 0x03u)
/** Spi_ReadIB: Service ID */
#define SPI_READIB_SERVICE_ID                 ((uint8) 0x04u)
/** Spi_SetupEB: Service ID */
#define SPI_SETUPEB_SERVICE_ID                ((uint8) 0x05u)
/** Spi_GetStatus: Service ID */
#define SPI_GETSTATUS_SERVICE_ID              ((uint8) 0x06u)
/** Spi_GetJobResult: Service ID */
#define SPI_GETJOBRESULT_SERVICE_ID           ((uint8) 0x07u)
/** Spi_GetSequenceResult: Service ID */
#define SPI_GETSEQUENCERESULT_SERVICE_ID      ((uint8) 0x08u)
/** Spi_GetVersionInfo: Service ID */
#define SPI_GETVERSIONINFO_SERVICE_ID         ((uint8) 0x09u)
/** Spi_SyncTransmit: Service ID */
#define SPI_SYNCTRANSMIT_SERVICE_ID           ((uint8) 0x0Au)
/** Spi_GetHWUnitStatus: Service ID */
#define SPI_GETHWUNITSTATUS_SERVICE_ID        ((uint8) 0x0Bu)
/** Spi_Cancel: Service ID */
#define SPI_CANCEL_SERVICE_ID                 ((uint8) 0x0Cu)
/** Spi_SetAsyncMode: Service ID */
#define SPI_SETASYNCMODE_SERVICE_ID           ((uint8) 0x0Du)
/** Spi_MainFunction_Handling: Service ID */
#define SPI_MAINFUNCTION_HANDLING_SERVICE_ID  ((uint8)0x10u)
/** Spi_SetHWUnitAsyncMode: Service ID */
#define SPI_SETHWUNITASYNCMODE_SERVICE_ID     ((uint8)0x80u)

#if (LEVEL0 != SPI_LEVEL_DELIVERED)

/** SpiJobPriority: Service ID:0, lowest, 3, highest priority */
#define SPI_JOBPRIORITY_LEVELS_MAX    (4)

#endif /* {(LEVEL0 != SPI_LEVEL_DELIVERED)} */
/**@} end of group SPI_Macros */
/**************************************************************************
                    ENUMERATION DEFINITION
**************************************************************************/
/** @defgroup SPI_Enumerations
  @{
*/
/**
 * @brief    The type Spi_StatusType defines a range of specific status for SPI Handler/Driver.
 */
typedef enum
{
    SPI_UNINIT = 0x00, //!<  Not initialized or not usable.
    SPI_IDLE = 0x01, //!<  Not currently transmitting any job.
    SPI_BUSY = 0x02 //!<  Is performing a SPI Job(transmit).
} Spi_StatusType;

/**
 * @brief    The type Spi_JobResultType defines a range of specific Jobs status for SPI Handler/Driver.
 */
typedef enum
{
    SPI_JOB_OK = 0, //!< The last transmission of the Job has been finished successfully. 
    SPI_JOB_PENDING = 1, //!< Is performing a SPI Job,meaning of this status is equal to SPI_BUSY. 
    SPI_JOB_FAILED = 2, //!< The last transmission of the Job has failed. 
    SPI_JOB_QUEUED = 3 //!< An asynchronous transmit Job has been accepted while Job has not started yet.
} Spi_JobResultType;

/**
 * @brief    Define a range of specific Sequences status for SPI Handler/Driver.
 */
typedef enum
{
    SPI_SEQ_OK = 0, //!< The last transmission of the Sequence has been finished successfully. */
    SPI_SEQ_PENDING = 1, //!< Is performing a SPI Sequence,meaning of this status is equal to SPI_BUSY. */
    SPI_SEQ_FAILED = 2, //!< The last transmission of the Sequence has failed. */
    SPI_SEQ_CANCELLED = 3 //!< The last transmission of the Sequence has been cancelled by user. */
} Spi_SeqResultType;

/**
 * @brief    The type define buffer types (internal or external).
 */
typedef enum
{
    IB = 0, //!< Internal Buffer.
    EB //!< External Buffer.
} Spi_BufferType;

/**
 * @brief    Specifies the asynchronous mechanism mode for SPI buses handled asynchronously in Level 2
 * @implements Spi_AsyncModeType_enumeration
*/
typedef enum
{
    SPI_POLLING_MODE = 0, //!< The asynchronous mechanism is ensured by polling,interrupts related disable
    SPI_INTERRUPT_MODE = 1 //!< The asynchronous mechanism is ensured by interrupt,interrupts related enable
} Spi_AsyncModeType;

/**
 * @brief    The type define spi operation mode (Master or Slave).
 */
typedef enum
{
    SPI_MASTER = 0, //!< SPI use mode as MASTER. */
    SPI_SLAVE = 1 //!< SPI use mode as SLAVE. */
}Spi_ModeType;

/**
 * @brief    The type define SPI HWunits status flag.
 */
typedef enum
{
    SPI_HW_IDLE = 0, //!< SPI HWunits status flag as idle. */
    SPI_HW_BUSY = 1 //!< SPI HWunits status flag as busy. */
}Spi_HwunitStatusType;
/**@} end of group SPI_Enumerations */
/**************************************************************************
                    STRUCT & OTHER TYPE DEFINITION
**************************************************************************/
/** @defgroup SPI_typedef
  @{
*/
/** Type Definitions in AUTOSAR SPI Driver software spec */
/** Type of application data buffer elements. */
typedef uint8 Spi_DataBufferType;
 
/** Type for defining the number of data elements of the type Spi_DataType to send or receive by Channel.*/
typedef uint16 Spi_NumberOfDataType;

#if (SPI_EXTSIZE_COLLECTION_ENABLE == STD_ON)

/** Specifies the identification (ID) for a Channel. */
typedef uint32 Spi_ChannelType;

/** Specifies the identification (ID) for a Job. */
typedef uint32 Spi_JobType;

/** Specifies the identification (ID) for a sequence of jobs. */
typedef uint32 Spi_SequenceType;

#else

/** Specifies the identification (ID) for a Channel. */
typedef uint8 Spi_ChannelType;

/** Specifies the identification (ID) for a Job. */
typedef uint16 Spi_JobType;

/** Specifies the identification (ID) for a sequence of jobs. */
typedef uint8 Spi_SequenceType;

#endif

/** Specifies the ID for a SPI Hardware microcontroller peripheral unit. */
typedef uint8 Spi_HWUnitType;

/** Contains the identification (ID) of the external device. */
typedef uint8 Spi_ExternalDeviceType;

/** Specifies the notification api type. */
typedef void (Spi_NotificationType) (void);

/** Specifies Job notification handler in High Speed Slave mode. */
#ifdef SPI_SLAVE_HIGH_SPEED_SUPPORT
    #if(SPI_SLAVE_HIGH_SPEED_SUPPORT == STD_ON)
        #if ((STD_ON == SPI_DMA_SUPPORT) && (LEVEL0 != SPI_LEVEL_DELIVERED))
            typedef void (Spi_HPNotifyType) (Spi_NumberOfDataType frameCount);
        #endif 
    #endif 
#endif 
/**@} end of group SPI_typedef */

/** @defgroup SPI_Structure
  @{
*/
/**
 * @brief     structure: manage the SPI unit attributes configuration.
 */
typedef struct
{
    VAR(uint32, SPI_VAR) cfgCTRL1; //!< Device attributes configuration for CTRL1.
    VAR(uint32, SPI_VAR) cfgCTRL2; //!< Device attributes configuration for CTRL2.
    VAR(uint32, SPI_VAR) cfgCRCPOLY; //!< CRCPOLY Register. 
} Spi_DeviceAttrCfgType;

/**
 * @brief    structure: manage the SPI channel attributes configuration.
 */
typedef struct
{
    VAR(uint32, SPI_VAR) attrSC1R; //!< Attributes for First Transfer Select in SPI_CTRL1 Register(SC1R) 
    VAR(uint32, SPI_VAR) attrSC2R; //!< Attributes for DSCFG and FRTCFG control in SPI_CTRL2 register(SC2R) 
    VAR(uint8, SPI_VAR)  dataAccessWidth; //!< Attributes for data accesss width. 
} Spi_ChannelAttrCfgType;

/**
 * @brief    structure: manage LLD attributes configuration.
 */
typedef struct
{
    /** SPI External units attributes */
    P2CONST(Spi_DeviceAttrCfgType, SPI_VAR, SPI_APPL_CONST) *spiExtDeviceAttrCfgPtr; 
} Spi_ExtDeviceAttrCfgType;

/**
 * @brief    structure: manage LLD channel & units attributes configuration.
 */
typedef struct
{
    P2CONST(Spi_ChannelAttrCfgType, SPI_VAR, SPI_APPL_CONST) spiChannelAttrCfgPtr; //!< SPI channel attributes
    P2CONST(Spi_DeviceAttrCfgType, SPI_VAR, SPI_APPL_CONST) *spiDevAttrCfgPtr; //!< SPI units attributes
} Spi_AttrCfgType;

/**
 * @brief    The structure contains the Hardware Unit information of status and async transmitting sequences.
 */
typedef struct
{
#if (LEVEL0 != SPI_LEVEL_DELIVERED)
    VAR(Spi_JobType, SPI_VAR) schedulingJobHead[SPI_JOBPRIORITY_LEVELS_MAX]; //!< Head job ID in each priority levels
    VAR(Spi_JobType, SPI_VAR) schedulingJobTail[SPI_JOBPRIORITY_LEVELS_MAX]; //!< Tail job ID in each priority levels
    VAR(sint8, SPI_VAR) schedulingMaxJobPriority; //!< the max number of scheduling job priority
#endif
    VAR(Spi_StatusType, SPI_VAR) Status; //!< the SPI Hardware Unit status
} Spi_HwSequenceInfoType;

/**
 * @brief    This structure contains all data to be needed while configuring any SPI Sequence.
 */
typedef struct
{
    VAR(Spi_JobType, SPI_VAR) numOfJobs; //!< Number of jobs in the sequence
    P2CONST(Spi_JobType, SPI_VAR, SPI_APPL_CONST) pcJobIndexListPtr; //!< Job index list
    P2FUNC(Spi_NotificationType, SPI_VAR, pfEndNotificationPtr); //!< Job notification handler
#ifdef SPI_SLAVE_HIGH_SPEED_SUPPORT
    #if(SPI_SLAVE_HIGH_SPEED_SUPPORT == STD_ON)
        #if ((STD_ON == SPI_DMA_SUPPORT) && (LEVEL0 != SPI_LEVEL_DELIVERED))
            P2FUNC(Spi_HPNotifyType, SPI_VAR, pfHPEndNotificationPtr); //!< Job notification in High Speed Slave mode
        #endif 
    #endif
#endif
    VAR(uint8, SPI_VAR) useInterruptible; //!< the Sequence use as interruptible or not
} Spi_SeqCfgType;

/**
 * @brief    This structure used to manage the sequence state.
 */
typedef struct
{
    VAR(Spi_SeqResultType, SPI_VAR) seqResult; //!< Seq Result
#if (LEVEL0 != SPI_LEVEL_DELIVERED)
    P2CONST(Spi_SeqCfgType, SPI_VAR, SPI_APPL_CONST) seqCfgPtr; //!< Pointer to Sequence Configuration
    P2CONST(Spi_JobType, SPI_VAR, SPI_APPL_CONST) pcCurrentJobIndexPtr; //!< Pointer to JobIndexList in async sequence
    VAR(Spi_JobType, SPI_VAR) currentRemainingJobs; //!< the number of jobs not transmitted in a pending async sequence
#endif
} Spi_SeqStateType;

/**
 * @brief    This structure used to manage the job state.
 *
 */
typedef struct
{
    VAR(Spi_JobResultType, SPI_VAR) jobResult; //!< Job Result. */
#if (LEVEL0 != SPI_LEVEL_DELIVERED)
    P2VAR(Spi_SeqStateType, SPI_VAR, SPI_APPL_DATA) asyncSequenceStatePtr; //!< Pointer to state of async sequence
    VAR(Spi_JobType, SPI_VAR) nextAsyncJob; //!< Pointer to the next async job to be transmitting
#endif
} Spi_JobStateType;

/**
 * @brief    This structure contains the parameters that job configuration need.
 */
typedef struct
{
    VAR(Spi_ChannelType, SPI_VAR) numOfChannels; //!< Channel numbers in the job
    P2CONST(Spi_ChannelType, SPI_VAR, SPI_APPL_CONST) pcChannelIndexListPtr; //!< Pointer to Channel index list
    P2FUNC(Spi_NotificationType, SPI_VAR, pfEndNotificationPtr); //!< Pointer to Job end notification
    P2FUNC(Spi_NotificationType, SPI_VAR, pfStartNotificationPtr); //!< Pointer to Job start notification
    VAR(sint8, SPI_VAR) s8JobPriority; //!< Priority 0~3
    P2VAR(Spi_JobStateType, SPI_VAR, SPI_APPL_DATA) pJobStatePtr; //!< Channel internal state
    VAR(Spi_HWUnitType, SPI_VAR) jobHWUnit; //!< HardWare Unit type
    VAR(uint32, SPI_VAR) offsetOfHWUnit; //!< HardWare Unit offset
    VAR(Spi_ExternalDeviceType, SPI_VAR) extDevType; //!< External Device Type
    P2CONST(Spi_ExtDeviceAttrCfgType, SPI_VAR, SPI_APPL_CONST) extDevAttrsPtr; //!< LLD attributes
} Spi_JobConfigType;

/**
 * @brief    This structure contains the pointers to the given buffer (IB or EB channels Tx/Rx memory locations)
 */
typedef struct
{
    P2VAR(Spi_DataBufferType, SPI_VAR, SPI_APPL_DATA) pBufferTXPtr; //!< Pointer to Transmit buffer
    P2VAR(Spi_DataBufferType, SPI_VAR, SPI_APPL_DATA) pBufferRXPtr; //!< Pointer to Receive buffer
 } Spi_BufferDescriptorType;

/**
 * @brief    This structure for manage the transmission channel state.
 */
typedef struct
{
    VAR(uint8, SPI_VAR) transmitFlags; //!< Default Transmit:Enabled
    VAR(Spi_NumberOfDataType, SPI_VAR) dataLength; //!< Actual to Transfer Data length
} Spi_ChannelStateType;

/**
 * @brief    This structure contains the parameters of channel configuration.
 */
typedef struct
{
    VAR(Spi_BufferType, SPI_VAR) bufType; //!< Buffer Type:IB(Internal Buffer)/EB(External Buffer)
    VAR(uint32, SPI_VAR) defaultTransmitValueSet; //!< Default Transmit Value
    VAR(Spi_NumberOfDataType, SPI_VAR) dataLength; //!< Actual to Transfer Data length
    P2VAR(Spi_BufferDescriptorType, SPI_VAR, SPI_APPL_DATA) pcBufferDescriptPtr; //!< Pointer to Buffer Descriptor
    P2VAR(Spi_ChannelStateType, SPI_VAR, SPI_APPL_DATA) channelStatePtr; //!< Pointer to Channel internal state
#ifdef SPI_SLAVE_HIGH_SPEED_SUPPORT
    #if(SPI_SLAVE_HIGH_SPEED_SUPPORT == STD_ON)
        #if ((STD_ON == SPI_DMA_SUPPORT) && LEVEL0 != SPI_LEVEL_DELIVERED))
            VAR(Spi_NumberOfDataType, SPI_VAR) frameCount; //!< EB buffer have the numbers of total frame 
        #endif 
    #endif 
#endif
} Spi_ChannelConfigType;

/**
 * @brief    This structure contains the parameters that HWUnit configuration need.
 */
typedef struct
{
    VAR(uint8, SPI_VAR) hwOffset; //!< SPI HardWare unit physical address offset on chip
    VAR(uint8, SPI_VAR) numOfCTAR; //!< Ihe number of CTAR registers available in SPI module
    VAR(Spi_ModeType, SPI_VAR) hwUnitMode; //!< HardWare unit use Mode - Master or Slave
    VAR(uint32, SPI_VAR) syncMode; //!< The HardWare unit can configure as Sync or Async
#if (LEVEL0 != SPI_LEVEL_DELIVERED)
    #if (STD_ON == SPI_DMA_SUPPORT)
        VAR(uint16, SPI_VAR) useDma; //!< SPI unit: use DMA or not
        VAR(uint8, SPI_VAR) txDmaChannel; //!< Master TX channel use DMA(SPI TX source to enable)
        VAR(uint8, SPI_VAR) rxDmaChannel; //!< RX DMA channel - enabled by the DSPI RX source
    #endif
#endif
#ifdef SPI_MTFE_MODE_SUPPORTED
    #if (STD_ON == SPI_MTFE_MODE_SUPPORTED)
        VAR(uint8, SPI_VAR) modifyTransFormatEnable; //!< Enable modified transfer format mode.
    #endif
#endif
} Spi_HWUnitConfigType;

/**
 * @brief    This structure contains the parameters that SPI Handler Driver configuration as top level structure.
 */
typedef struct
{
    VAR(uint16, SPI_VAR) maxExternalDevice; //!< The max number of external devices configured
    VAR(Spi_ChannelType, SPI_VAR) maxChannel; //!< The max number of channels configured
    VAR(Spi_JobType, SPI_VAR) maxJob; //!< The max number of jobs configured
    VAR(Spi_SequenceType, SPI_VAR) maxSequence; //!< The max number of sequences configured
    P2CONST(Spi_ChannelConfigType, SPI_VAR, SPI_APPL_CONST) pcChannelCfgPtr; //!< Pointer to channel Array configured
    P2CONST(Spi_JobConfigType, SPI_VAR, SPI_APPL_CONST) pcJobCfgPtr; //!< Pointer to job Array configured
    P2CONST(Spi_SeqCfgType, SPI_VAR, SPI_APPL_CONST) seqCfgPtr;//!< Pointer to sequence Array configured
    P2CONST(Spi_AttrCfgType, SPI_VAR, SPI_APPL_CONST) pcAttrCfgPtr;//!< Chanel and SPI HardWare unit attributes configured
    P2CONST(Spi_HWUnitConfigType, SPI_VAR, SPI_APPL_CONST) pcHWUnitCfgPtr;//!< Pointer to Array of HWUnit configuration
#if (STD_OFF == SPI_DEM_EVENT_ERROR_REPORT_DISABLED)
    CONST(Mcal_DemErrorType, SPI_CONST) eHardwareErrorCfg; //!< SPI Driver DEM Error: SPI_E_HARDWARE_ERROR
    CONST(Mcal_DemErrorType, SPI_CONST) eTimeoutErrorCfg; //!< SPI Driver DEM Error: SPI_E_TIMEOUT_ERROR
#endif

} Spi_ConfigType;
/**@} end of group SPI_Structure */
/**************************************************************************
                    GLOBAL VARIABLE
**************************************************************************/
/** @defgroup SPI_Variable
  @{
*/
#define SPI_START_SEC_VAR_INIT_UNSPECIFIED
#include "Spi_MemMap.h"

extern P2CONST(Spi_ConfigType, SPI_VAR, SPI_APPL_CONST) g_spiCfgPtr;

#define SPI_STOP_SEC_VAR_INIT_UNSPECIFIED
#include "Spi_MemMap.h"

#define SPI_START_SEC_VAR_NO_INIT_UNSPECIFIED
#include "Spi_MemMap.h"

/** Spi job/channel/sequence State */
extern VAR(Spi_JobStateType, SPI_VAR) g_spiJobState[SPI_JOBCFG_NUM];
extern VAR(Spi_ChannelStateType, SPI_VAR) g_spiChannelState[SPI_CHANNELCFG_NUM];
extern VAR(Spi_SeqStateType, SPI_VAR) g_spiSequenceState[SPI_SEQCFG_NUM];

#define SPI_STOP_SEC_VAR_NO_INIT_UNSPECIFIED
#include "Spi_MemMap.h"
 
#define SPI_START_SEC_CONFIG_DATA_UNSPECIFIED
#include "Spi_MemMap.h"
 
extern CONST(Spi_ConfigType, SPI_CONST) g_spiConfig;

#define SPI_STOP_SEC_CONFIG_DATA_UNSPECIFIED
#include "Spi_MemMap.h"
/**@} end of group SPI_Variable */
/**************************************************************************
                    FUNCTION DECLARATION
**************************************************************************/
/** @defgroup SPI_Fuctions
  @{
*/
#define SPI_START_SEC_CODE
#include "Spi_MemMap.h"
 
#if (LEVEL0 != SPI_LEVEL_DELIVERED)
    /** Job transmission finish notification api */
    FUNC(void, SPI_CODE) Spi_JobTransEnd(P2CONST(Spi_JobConfigType,AUTOMATIC,SPI_APPL_CONST) pcJobCfgPtr);
#endif

#if (SPI_VERSION_INFO_API == STD_ON)
    /** Get version information api */
    FUNC (void, SPI_CODE) Spi_GetVersionInfo(P2VAR(Std_VersionInfoType, AUTOMATIC, SPI_APPL_DATA) verInfoPtr);
#endif
/** Initializes the SPI driver api*/
FUNC (void, SPI_CODE) Spi_Init(P2CONST(Spi_ConfigType, AUTOMATIC, SPI_APPL_CONST) cfgPtr);
/** de-initializes the SPI driver api */
FUNC (Std_ReturnType, SPI_CODE) Spi_DeInit(void);

#if ((USAGE0 == SPI_CHANNEL_BUFFERS_ALLOWED) || (USAGE2 == SPI_CHANNEL_BUFFERS_ALLOWED ))
    /** This function writes the given data into the buffer of a specific channel */
    FUNC (Std_ReturnType, SPI_CODE) Spi_WriteIB
    (VAR(Spi_ChannelType, AUTOMATIC) Channel,P2CONST(Spi_DataBufferType, AUTOMATIC, SPI_APPL_CONST) DataBufferPtr);
    /** This function reads the data from the buffer of a channel and puts at the memory location */
    FUNC (Std_ReturnType, SPI_CODE) Spi_ReadIB
    (VAR(Spi_ChannelType, AUTOMATIC) Channel,P2VAR(Spi_DataBufferType, AUTOMATIC, SPI_APPL_DATA) DataBufferPointer);
#endif

#if (LEVEL0 != SPI_LEVEL_DELIVERED)
    /** This function triggers the asynchronous transmission for the given sequence. */
    FUNC (Std_ReturnType, SPI_CODE) Spi_AsyncTransmit(VAR(Spi_SequenceType, AUTOMATIC) Sequence);
#endif

#if ( ( USAGE1 == SPI_CHANNEL_BUFFERS_ALLOWED) || ( USAGE2 == SPI_CHANNEL_BUFFERS_ALLOWED)  )
    /** This function setup an external buffer to be used by a specific channel. */
    FUNC (Std_ReturnType, SPI_CODE) Spi_SetupEB
    (VAR(Spi_ChannelType, AUTOMATIC) Channel,P2CONST(Spi_DataBufferType, AUTOMATIC, SPI_APPL_CONST) SrcDataBufferPtr,
     P2VAR(Spi_DataBufferType, AUTOMATIC, SPI_APPL_DATA) DesDataBufferPtr,VAR(Spi_NumberOfDataType, AUTOMATIC) Length);
#endif
/** This function returns the status of the SPI driver. */
FUNC (Spi_StatusType, SPI_CODE) Spi_GetStatus(void);
/** This function is used to request the status of a specific job. */
FUNC (Spi_JobResultType, SPI_CODE) Spi_GetJobResult(VAR(Spi_JobType, AUTOMATIC) Job);
/** This function is used to request the status of a specific sequence. */
FUNC (Spi_SeqResultType, SPI_CODE) Spi_GetSequenceResult(VAR(Spi_SequenceType, AUTOMATIC) Sequence);

#if ((LEVEL2 == SPI_LEVEL_DELIVERED) || (LEVEL0 == SPI_LEVEL_DELIVERED))
    /** This function is used for synchronous transmission of a given sequence. */
    FUNC (Std_ReturnType, SPI_CODE) Spi_SyncTransmit(VAR(Spi_SequenceType, AUTOMATIC) Sequence);
#endif

#if (SPI_HW_STATUS_API == STD_ON)
    /** This function is used to request the status of a specific SPI peripheral unit */
    FUNC (Spi_StatusType, SPI_CODE) Spi_GetHWUnitStatus(VAR(Spi_HWUnitType, AUTOMATIC) HWUnit);
#endif

#if (STD_ON == SPI_CANCEL_API)
    /** This function is used to request the cancelation of the given sequence. */
    FUNC (void, SPI_CODE) Spi_Cancel(VAR(Spi_SequenceType, AUTOMATIC) Sequence);
#endif

#if (SPI_LEVEL_DELIVERED == LEVEL2)
    /** This function specifies the asynchronous mode for the SPI busses handled asynchronously. */
    FUNC (Std_ReturnType, SPI_CODE) Spi_SetAsyncMode(VAR(Spi_AsyncModeType, AUTOMATIC) Mode);
#endif

#if ((SPI_LEVEL_DELIVERED == LEVEL2) && (SPI_ASYNC_MODE_ENABLE == STD_ON))
    /** This function specifies the asynchronous mode for a given HWUnit. */
    FUNC (Std_ReturnType, SPI_CODE) Spi_SetHWUnitAsyncMode
    (VAR(Spi_HWUnitType, AUTOMATIC) HWUnit,VAR(Spi_AsyncModeType, AUTOMATIC) AsyncMode);
#endif /* {(SPI_LEVEL_DELIVERED == LEVEL2) && (SPI_ASYNC_MODE_ENABLE == STD_ON)} */

#if (LEVEL0 != SPI_LEVEL_DELIVERED)
    /** This function shall asynchronously poll SPI interrupts and call ISR if appropriate. */
    FUNC (void, SPI_CODE) Spi_MainFunction_Handling(void);
#endif

#define SPI_STOP_SEC_CODE
#include "Spi_MemMap.h"

/**@} end of group SPI_Fuctions */
#ifdef __cplusplus
}
#endif

#endif /* SPI_H */

/**@} end of group SPI_Driver */
/**@} end of group G32A10xx_StdPeriphDriver */

