/*!
* @file     Spi_Hw.h
*
* @version  1.0.0
*
* @brief    Header file of AUTOSAR Spi driver(SPI LLD).This file contains the definitions of SPI peripheral LLD 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_HW_H
#define SPI_HW_H

#include "Mcal.h"
#include "Spi.h"

#ifdef __cplusplus
extern "C"{
#endif

/** @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_HW_H_VENDOR_ID                        0x00C1U
/** Major version number of AUTOSAR release on which the appropriate implementation is based on. */
#define SPI_HW_H_AR_RELEASE_MAJOR_VERSION         0x04U
/** Minor version number of AUTOSAR release on which the appropriate implementation is based on. */
#define SPI_HW_H_AR_RELEASE_MINOR_VERSION         0x04U
/** Revision version number of AUTOSAR release on which the appropriate implementation is based on. */
#define SPI_HW_H_AR_RELEASE_REVISION_VERSION      0x00U
/** Major version number of the vendor specific implementation of the module. The numbering is vendor specific. */
#define SPI_HW_H_SW_MAJOR_VERSION                 0x01U
/** Minor version number of the vendor specific implementation of the module. The numbering is vendor specific. */
#define SPI_HW_H_SW_MINOR_VERSION                 0x00U
/** Patch level version number of the vendor specific implementation of the module. The numbering is vendor specific. */
#define SPI_HW_H_SW_PATCH_VERSION                 0x00U

/**************************************************************************
                    MACRO DEFINITION
**************************************************************************/

#if (LEVEL0 != SPI_LEVEL_DELIVERED)
    /** HardWare unit map to SPI structure */
    #define SPI_HWUNIT_TO_SPI(HWUnit)    (&g_SpiHwUnitState[(HWUnit)])
#endif 
/**@} end of group SPI_Macros */
/**************************************************************************
                    STRUCT & OTHER TYPE DEFINITION
**************************************************************************/
/** @defgroup SPI_Structure
  @{
*/
#if (STD_ON == SPI_ONEJOBSEQ_OPTIMIZE)
/**
* @brief    Spi_SyncTransmit():Cache channel attributes used by the optimized implementation.
*/
typedef struct
{
    VAR(uint32, SPI_VAR) spiTxCmd;
    P2CONST(Spi_BufferDescriptorType, SPI_VAR, SPI_APPL_CONST) spiBufDescriptorPtr; //!< Pointer to buffer descriptor
    P2VAR(Spi_ChannelStateType, SPI_VAR, SPI_APPL_DATA) spiStatePtr; //!< Pointer to channel states
    VAR(uint32, SPI_VAR) spiDefaultTransmitValue; //!< Store the default transfer data value
    VAR(uint8, SPI_VAR) spiDataAccessedWidth; //!< Attributes for channel data accesss width. 
} Spi_CachedChannelAttrType;

/**
* @brief    Internal structure keeping a set of cached sequences attributes.
* @details  Internal structure keeping a set of cached sequences attributes
*           used by the optimized implementation of Spi_SyncTransmit() for
*           the sequences having only one job.
*/
typedef struct
{
    VAR(uint8, SPI_VAR) optimizedHWType; //!< Optimized HardWare type 
    VAR(Spi_HWUnitType, SPI_VAR) spiHwUnit; //!< HardWare unit
    VAR(Spi_ChannelType, SPI_VAR) spiChannelsNum; //!< channels number
    P2VAR(Spi_JobStateType, SPI_VAR, SPI_APPL_DATA) spiJobStatePtr; //!< pointer to the sequence job state
    P2VAR(Spi_StatusType, SPI_VAR, SPI_APPL_DATA) spiHWStatusPtr; //!< pointer to HW Unit status
    P2VAR(Spi_CachedChannelAttrType, SPI_VAR, SPI_APPL_DATA) spiChannelsPtr; //!< pointer to channel cached attributes table
    VAR(uint32, SPI_VAR) spiBaseAddress; //!< SPI HardWare Unit memory mapped registers base address
    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_CachedSeqAttrType;
#endif /* {(STD_ON == SPI_ONEJOBSEQ_OPTIMIZE)} */

/**
* @brief    Store state of transfer process for Spi_Hw_SyncTrans() and Spi_Hw_SyncTransFast().
*/
#if ( LEVEL1 != SPI_LEVEL_DELIVERED )
typedef struct
{
    VAR(uint32, SPI_VAR) spiBaseAddress; //!< SPI HardWare Unit memory mapped registers base address
    P2VAR(Spi_DataBufferType, SPI_VAR, SPI_APPL_DATA) spiTxBufferPtr; //!< Pointer to the Tx channel buffer
    P2VAR(Spi_DataBufferType, SPI_VAR, SPI_APPL_DATA) spiRxBufferPtr; //!< Pointer to the Rx channel buffer
    VAR(uint32, SPI_VAR) spiDefaultTransmitValue; //!< Channels default data value to transmit
    VAR(uint8, SPI_VAR) spiTxDataAccess; //!< Transmit data width value
    VAR(uint8, SPI_VAR) spiRxDataAccess; //!< Receive data width value
    VAR(Spi_ChannelType, SPI_VAR) spiTxChannelsNum; //!< The channels number to transmit in pending job
    VAR(Spi_ChannelType, SPI_VAR) spiRxChannelsNum; //!< The channels number to receive in pending job
    VAR(Spi_NumberOfDataType, SPI_VAR) spiTxLength; //!< The frames number to transmit in pending channel
    VAR(Spi_NumberOfDataType, SPI_VAR) spiRxLength; //!< The frames number to receive in pending channel
    P2CONST(Spi_ChannelType, SPI_VAR, SPI_APPL_CONST) spiTxChannelIndexListPtr; //!< Pointer to Tx ChannelIndexList
    P2CONST(Spi_ChannelType, SPI_VAR, SPI_APPL_CONST) spiRxChannelIndexListPtr; //!< Pointer to Rx ChannelIndexList
#if (STD_ON == SPI_ONEJOBSEQ_OPTIMIZE)
    P2VAR(Spi_CachedChannelAttrType, SPI_VAR, SPI_APPL_DATA) spiRxChannelPtr; //!< Pointer to Rx channel cached attributes table
#endif
    VAR(uint8, SPI_VAR) spiJobEndFlag; //!< SPI CfgIO job end flag
    VAR(uint32, SPI_VAR) frameCmd; //!< SPI data frames transmit command value
    VAR(uint32, SPI_VAR) spiJobCmd; //!< External device TXCMD command value
}Spi_SyncProcessStateType;
#endif

/**
* @brief    Structure:store runtime configuration parameters states of Spi SPI Device.
*/
typedef struct
{
    P2CONST(Spi_HWUnitConfigType, SPI_VAR, SPI_APPL_CONST) spiHwUnitCfgPtr; //!< Pointer to HWUnit configuration
#if (LEVEL0 != SPI_LEVEL_DELIVERED)
  #if (STD_ON == SPI_DMA_SUPPORT)
    P2VAR(uint32, SPI_VAR, SPI_APPL_DATA) spiTxDmaTcdPtr; //!< Pointer to the master TX DMA Transfer Control Descriptor
    P2VAR(uint32, SPI_VAR, SPI_APPL_DATA) spiRxDmaTcdPtr; //!< Pointer to the master RX DMA Transfer Control Descriptor
  #endif    
    VAR(uint32, SPI_VAR) spiExtDeviceCTRL1; //!< External device different attributes in SPI_CTRL1 Register
    VAR(uint32, SPI_VAR) spiExtDeviceCTRL2; //!< External device different attributes in SPI_CTRL2 Register
    P2VAR(Spi_DataBufferType, SPI_VAR, SPI_APPL_DATA) spiCurrentTxBufPtr; //!< Pointer to current channel Tx buffer
    P2VAR(Spi_DataBufferType, SPI_VAR, SPI_APPL_DATA) spiCurrentRxBufPtr; //!< Pointer to current channel Rx buffer
    VAR(uint32, SPI_VAR) spiDefaultTransData; //!< Channels default transmit data of frame
    P2CONST(Spi_ChannelType, SPI_VAR, SPI_APPL_CONST) spiCurTxChanIndexListPtr; //!< Pointer to current channel transmit Channel Index List
    P2CONST(Spi_ChannelType, SPI_VAR, SPI_APPL_CONST) spiCurRxChanIndexListPtr; //!< Pointer to current channel receive ChannelIndexList
    VAR(Spi_ChannelType, SPI_VAR) spiRemainTxChannels; //!< The remaining Tx channels number in pending async job
    VAR(Spi_ChannelType, SPI_VAR) spiRemainRxChannels; //!< The remaining Rx channels number in pending async job
    VAR(Spi_NumberOfDataType,SPI_VAR) spiRemainFrames; //!< The remaining frames number in pending channel
    VAR(Spi_NumberOfDataType,SPI_VAR) spiSentFrames; //!< Sent frames number,the next ISR call have to be read back
    P2CONST(Spi_JobConfigType, SPI_VAR, SPI_APPL_CONST) spiCurrentJobPtr;//!< pointer to the current job
    VAR(boolean, SPI_VAR) spiIsEndJob; //!< The flag to indicate job last transmit data
#endif
    VAR(uint32, SPI_VAR) spiBaseAddress; //!< SPI HardWare Unit memory mapped registers base address
    VAR(uint32, SPI_VAR) spiCtrl1Addr; //!< Address of Ctrl1 register(CTRL1)
    VAR(uint32, SPI_VAR) spiCtrl2Addr; //!< Address of Ctrl2 register(CTRL2)
    VAR(uint32, SPI_VAR) spiStsAddr; //!< Address of Status register(STS)
    VAR(uint32, SPI_VAR) spiDataAddr; //!< Address of transmit or receive Data register(DATA)
    VAR(uint32, SPI_VAR) spiCrcPolyAddr; //!< Address of CRCPOLY register(CRCPOLY)
    VAR(uint32, SPI_VAR) spiRxCrcAddr; //!< Address of RXCRC register(RXCRC)
    VAR(uint32, SPI_VAR) spiTxCrcAddr; //!< Address of TXCRC register(TXCRC)
    VAR(uint32, SPI_VAR) spiCurrentCmd; //!< Current frame command
    VAR(Spi_AsyncModeType, SPI_VAR) spiAsyncMode; //!< CfgIO unit Async transfer mode
    P2VAR(Spi_StatusType, SPI_VAR, SPI_APPL_DATA) spiStatusPtr; //!< Pointer to the hardware unit state
    VAR(Spi_NumberOfDataType, SPI_VAR) spiReceivedData; //!< Received frames data
    VAR(uint8, SPI_VAR) spiIsPollReqEn; //!< Enable poll request
    VAR(uint32, SPI_VAR) spiIsTxPollReq; //!< TX poll request
    VAR(uint32, SPI_VAR) spiIsRxPollReq; //!< RX poll request
    VAR(uint8, SPI_VAR) spiFirstChannelInJob; //!< first channel in job
}Spi_HwStateType;

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

#if (STD_ON == SPI_ONEJOBSEQ_OPTIMIZE)
    /**  Pointer table to the cached sequence attributes information structure */
    extern P2VAR(Spi_CachedSeqAttrType,AUTOMATIC,SPI_VAR) spiSingleJobSeqOptPtr[SPI_SEQCFG_NUM];
#endif

#define SPI_STOP_SEC_VAR_INIT_UNSPECIFIED
#include "Spi_MemMap.h"
 
#if ((STD_ON == SPI_DMA_SUPPORT) && (LEVEL0 != SPI_LEVEL_DELIVERED)) 
    #define SPI_START_SEC_VAR_NO_INIT_UNSPECIFIED_NO_CACHEABLE
#else
    #define SPI_START_SEC_VAR_NO_INIT_UNSPECIFIED
#endif 

#include "Spi_MemMap.h"

/**  Keep the HWUnit fields state */
extern VAR(Spi_HwStateType, SPI_VAR) g_SpiHwUnitState[SPI_HWUNITCFG_NUM];

#if ((STD_ON == SPI_DMA_SUPPORT) && (LEVEL0 != SPI_LEVEL_DELIVERED))    
    #define SPI_STOP_SEC_VAR_NO_INIT_UNSPECIFIED_NO_CACHEABLE
#else
    #define SPI_STOP_SEC_VAR_NO_INIT_UNSPECIFIED
#endif 

#include "Spi_MemMap.h"

#define SPI_START_SEC_CONST_32
#include "Spi_MemMap.h"

extern CONST(uint32, SPI_CONST) SPI_BASEADDRESS[SPI_HWUNITCFG_NUM];

#define SPI_STOP_SEC_CONST_32
#include "Spi_MemMap.h"

/**@} end of group SPI_Variable */
/**************************************************************************
                    FUNCTION DECLARATION
**************************************************************************/
/** @defgroup SPI_Fuctions
  @{
*/
#define SPI_START_SEC_CODE
#include "Spi_MemMap.h"

#if ((STD_ON == SPI_CANCEL_API) && (STD_ON == SPI_SLAVE_SUPPORT))
    /** This function is used to request the cancelation of the given sequence for Slave */
    FUNC(void, SPI_CODE) Spi_Hw_SlaveTransCancel(VAR(Spi_SequenceType, AUTOMATIC) SeqId);
#endif

#if (((SPI_LEVEL_DELIVERED == LEVEL2)||(SPI_LEVEL_DELIVERED == LEVEL0)) && (STD_ON == SPI_ONEJOBSEQ_OPTIMIZE))
    /** Cached sequence / job configuration parameters */
    FUNC(void, SPI_CODE) Spi_Hw_PreCacheInfo(void);
    /**  Starts the synchronous transmission for optimized sequences having only one job */
    FUNC(Std_ReturnType, SPI_CODE) Spi_Hw_SyncTransFast
    (P2CONST(Spi_CachedSeqAttrType, AUTOMATIC, SPI_APPL_CONST) SeqCfgPtr);
#endif

/** Initialize the specific Spi unit with all configuration and structure parameters from the specific SPI unit*/
FUNC(void, SPI_CODE) Spi_Hw_Init
    (VAR(Spi_HWUnitType, AUTOMATIC) HwUnitId,P2VAR(Spi_StatusType, AUTOMATIC, SPI_APPL_DATA) StatusPtr);
/** This function performs the de-initialization of a specific peripheral unit. */
FUNC(void, SPI_CODE) Spi_Hw_DeInit(VAR(Spi_HWUnitType, AUTOMATIC) HWUnitId);

#if (LEVEL0 != SPI_LEVEL_DELIVERED)
    /** This function sets the Job's attributes and send all the data through the SPI bus. */
    FUNC(void, SPI_CODE) Spi_Hw_JobTrans(P2CONST(Spi_JobConfigType, AUTOMATIC, SPI_APPL_CONST) JobCfgPtr);
    /** IRQ configure functions */
    FUNC(void, SPI_CODE) Spi_Hw_IrqCfg
        (VAR(Spi_HWUnitType, AUTOMATIC) HWUnitId,VAR(Spi_AsyncModeType, AUTOMATIC) AsyncMode);
    /** IRQ polling functions */
    FUNC(void, SPI_CODE) Spi_Hw_PollingIrq(VAR(Spi_HWUnitType, AUTOMATIC) HWUnitId);
    /** This function is called by TDF or RDF ISRs for the SPI units working in PIO_FIFO mode */
    FUNC(void, SPI_CODE) Spi_Hw_IrqRxFifo(P2VAR(Spi_HwStateType, AUTOMATIC, SPI_APPL_DATA) HwStatePtr);
    /** ISR service routines */
    ISR(SPI_IRQHandler);

#endif

#if ( LEVEL1 != SPI_LEVEL_DELIVERED )
    /** This function performs the synchronous transmission for a sequence */
    FUNC(Std_ReturnType, SPI_CODE) Spi_Hw_SyncTrans(VAR(Spi_SequenceType, AUTOMATIC) SeqId);
    FUNC(Std_ReturnType, SPI_CODE) Spi_Hw_SeqSyncTrans(VAR(Spi_SequenceType, AUTOMATIC) spiSeqId);
#endif

#if ((STD_ON == SPI_DMA_SUPPORT) && (LEVEL0 != SPI_LEVEL_DELIVERED))
    /** This function is called by DMA ISR for Rx DMA channels. */
    FUNC(void, SPI_CODE) Spi_Hw_IsrTxDma(P2VAR(Spi_HwStateType, AUTOMATIC, SPI_APPL_DATA) HwStatePtr);
    FUNC(void, SPI_CODE) Spi_Hw_IsrRxDma(P2VAR(Spi_HwStateType, AUTOMATIC, SPI_APPL_DATA) HwStatePtr);
    FUNC (void, SPI_CODE) Spi0_IsrRxDma(void);
    FUNC (void, SPI_CODE) Spi0_IsrTxDma(void);
#endif

#define SPI_STOP_SEC_CODE
#include "Spi_MemMap.h"

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

#endif /* SPI_HW_H */
/**@} end of group SPI_Driver */
/**@} end of group G32A10xx_StdPeriphDriver */
 

