/*==================================================================================================
*   Project              : RTD AUTOSAR 4.9
*   Platform             : CORTEXM
*   Peripheral           : FS26
*   Dependencies         :
*
*   Autosar Version      : 4.9.0
*   Autosar Revision     : ASR_REL_4_9_REV_0000
*   Autosar Conf.Variant :
*   SW Version           : 6.0.0
*   Build Version        : S32K3_RTD_6_0_0_D2511_ASR_REL_4_9_REV_0000_20251114
*
*   Copyright 2020 - 2025 NXP
*
*   NXP Confidential and Proprietary. This software is owned or controlled by NXP and may only be
*   used strictly in accordance with the applicable license terms. By expressly
*   accepting such terms or by downloading, installing, activating and/or otherwise
*   using the software, you are agreeing that you have read, and that you agree to
*   comply with and are bound by, such license terms. If you do not agree to be
*   bound by the applicable license terms, then you may not retain, install,
*   activate or otherwise use the software.
==================================================================================================*/

/**
*   @file Sbc_fs26_spi_external_access.c
*
*   @addtogroup spi_external_access
*   @{
*/

#if defined (__cplusplus)
extern "C" {
#endif

/*==================================================================================================
*                                        INCLUDE FILES
* 1) system and project includes
* 2) needed interfaces from external units
* 3) internal and external interfaces from this unit
==================================================================================================*/
#include "Sbc_fs26_spi_external_access.h"
#ifdef SBC_FS26_SPI_USED
/*==================================================================================================
*                              SOURCE FILE VERSION INFORMATION
==================================================================================================*/
#define SBC_FS26_SPI_EXTERNAL_ACCESS_VENDOR_ID_C                      43
#define SBC_FS26_SPI_EXTERNAL_ACCESS_AR_RELEASE_MAJOR_VERSION_C       4
#define SBC_FS26_SPI_EXTERNAL_ACCESS_AR_RELEASE_MINOR_VERSION_C       9
#define SBC_FS26_SPI_EXTERNAL_ACCESS_AR_RELEASE_REVISION_VERSION_C    0
#define SBC_FS26_SPI_EXTERNAL_ACCESS_SW_MAJOR_VERSION_C               6
#define SBC_FS26_SPI_EXTERNAL_ACCESS_SW_MINOR_VERSION_C               0
#define SBC_FS26_SPI_EXTERNAL_ACCESS_SW_PATCH_VERSION_C               0

/*==================================================================================================
*                                     FILE VERSION CHECKS
==================================================================================================*/
/* Checks against Spi External Access header file */
#if ( SBC_FS26_SPI_EXTERNAL_ACCESS_VENDOR_ID_C != SBC_FS26_SPI_EXTERNAL_ACCESS_VENDOR_ID)
    #error "Spi External Access source file and Spi External Access header file have different vendor ids"
#endif
#if (( SBC_FS26_SPI_EXTERNAL_ACCESS_AR_RELEASE_MAJOR_VERSION_C    != SBC_FS26_SPI_EXTERNAL_ACCESS_AR_RELEASE_MAJOR_VERSION    ) || \
     ( SBC_FS26_SPI_EXTERNAL_ACCESS_AR_RELEASE_MINOR_VERSION_C    != SBC_FS26_SPI_EXTERNAL_ACCESS_AR_RELEASE_MINOR_VERSION    ) || \
     ( SBC_FS26_SPI_EXTERNAL_ACCESS_AR_RELEASE_REVISION_VERSION_C != SBC_FS26_SPI_EXTERNAL_ACCESS_AR_RELEASE_REVISION_VERSION ))
     #error "AUTOSAR Version Numbers of Spi External Access source file and Spi External Access header file are different"
#endif
#if (( SBC_FS26_SPI_EXTERNAL_ACCESS_SW_MAJOR_VERSION_C != SBC_FS26_SPI_EXTERNAL_ACCESS_SW_MAJOR_VERSION) || \
     ( SBC_FS26_SPI_EXTERNAL_ACCESS_SW_MINOR_VERSION_C != SBC_FS26_SPI_EXTERNAL_ACCESS_SW_MINOR_VERSION) || \
     ( SBC_FS26_SPI_EXTERNAL_ACCESS_SW_PATCH_VERSION_C != SBC_FS26_SPI_EXTERNAL_ACCESS_SW_PATCH_VERSION))
    #error "Software Version Numbers of Spi External Access source file and Spi External Access header file are different"
#endif

/*==================================================================================================
*                                        LOCAL VARIABLES
==================================================================================================*/

/*==================================================================================================
*                                    LOCAL FUNCTION PROTOTYPES
==================================================================================================*/

/*==================================================================================================
*                                        GLOBAL FUNCTIONS PROTOTYPES
==================================================================================================*/
#define SBC_FS26_START_SEC_CODE
#include "Sbc_fs26_MemMap.h"
#if (defined(SPI_START_TRANSFER_CALLBACK) && defined(SPI_END_TRANSFER_CALLBACK))
extern void SPI_START_TRANSFER_CALLBACK (void);
extern void SPI_END_TRANSFER_CALLBACK (void);
#endif

/*==================================================================================================
*                                         LOCAL FUNCTIONS
==================================================================================================*/

/*==================================================================================================
*                                        GLOBAL FUNCTIONS
==================================================================================================*/
/*!
 * @brief SPI prepare buffer.
 *
 * This function Setup transmit/receive buffer of SPI master.
 *
 * @param[in] pSpiSetup      SPI interface setup
 * @param[in] pTxBuffer      SPI Tx buffer
 * @param[out] pRxBuffer     SPI Rx buffer
 *
 * @return Std_ReturnType    Return E_NOT_OK in case buffer preparation failed. Otherwise return E_OK.
 */
Std_ReturnType Sbc_fs26_SpiPrepareBuffer(const Sbc_fs26_SpiSetupType * pSpiSetup, const uint8 * pTxBuffer, uint8 * pRxBuffer)
{
    Std_ReturnType eStatus = E_OK;
#if !(defined(SBC_FS26_USE_IPV_DSPI) || defined(SBC_FS26_USE_IPV_SPI) || defined(SBC_FS26_USE_IPV_LPSPI) || defined(SBC_FS26_USE_IPV_FLEXIO_SPI))
    eStatus = (Std_ReturnType)Spi_SetupEB((Spi_ChannelType)pSpiSetup->Spi, pTxBuffer, pRxBuffer, (Spi_NumberOfDataType)pSpiSetup->NumberOfBytes);
#else
    (void)pSpiSetup;
    (void)pTxBuffer;
    (void)pRxBuffer;
#endif

    return eStatus;
}
/*!
 * @brief SPI transfer.
 *
 * This function transfers data via SPI.
 *
 * @param[in] pSpiSetup      SPI interface setup
 * @param[in] pTxBuffer      SPI Tx buffer
 * @param[out] pRxBuffer     SPI Rx buffer
 *
 * @return Std_ReturnType    Return E_NOT_OK in case spi transfer failed. Otherwise return E_OK.
 */
Std_ReturnType Sbc_fs26_SpiTransferExternal(const Sbc_fs26_SpiSetupType *pSpiSetup, const uint8 * pTxBuffer, uint8 * pRxBuffer)
{
    Std_ReturnType eStatus = E_OK;

#ifdef SBC_FS26_USE_IPV_DSPI
    const Dspi_Ip_ExternalDeviceType *ExternalDevice = pSpiSetup->Extension;
#elif defined(SBC_FS26_USE_IPV_SPI)
    const Spi_Ip_ExternalDeviceType *ExternalDevice = pSpiSetup->Extension;
#elif defined(SBC_FS26_USE_IPV_LPSPI)
    const Lpspi_Ip_ExternalDeviceType *ExternalDevice = pSpiSetup->Extension;
#elif defined(SBC_FS26_USE_IPV_FLEXIO_SPI)
    const Flexio_Spi_Ip_ExternalDeviceType *ExternalDevice = pSpiSetup->Extension;
#else
    const Spi_SequenceType   *SpiSequence = pSpiSetup->Extension;
    (void)pTxBuffer;
    (void)pRxBuffer;
#if (2U != SBC_FS26_SPI_LEVEL_DELIVERED)
    (void)pSpiSetup->SyncTransmit;  /* Unused parameter. */
    (void)pSpiSetup->Timeout;  /* Unused parameter. */
#endif /* (2U != SBC_FS26_SPI_LEVEL_DELIVERED) */
#endif

    /* Start SPI transfer */
#ifdef SBC_FS26_USE_IPV_DSPI
    if (FALSE == pSpiSetup->SyncTransmit)
    {
        eStatus = (Std_ReturnType)Dspi_Ip_AsyncTransmit(ExternalDevice,
                                                     (uint8 *)pTxBuffer,
                                                     (uint8 *)pRxBuffer,
                                                     (uint16)pSpiSetup->NumberOfBytes,
                                                     (Dspi_Ip_CallbackType)pSpiSetup->Callback);
    }
    else
    {
#if (defined(SPI_START_TRANSFER_CALLBACK) && defined(SPI_END_TRANSFER_CALLBACK))
        SPI_START_TRANSFER_CALLBACK();
#endif
        eStatus = (Std_ReturnType)Dspi_Ip_SyncTransmit(ExternalDevice,
                                                    (uint8 *)pTxBuffer,
                                                    (uint8 *)pRxBuffer,
                                                    (uint16)pSpiSetup->NumberOfBytes,
                                                    pSpiSetup->Timeout);
#if (defined(SPI_START_TRANSFER_CALLBACK) && defined(SPI_END_TRANSFER_CALLBACK))
        SPI_END_TRANSFER_CALLBACK();
#endif
    }
#elif defined(SBC_FS26_USE_IPV_SPI)
    if (FALSE == pSpiSetup->SyncTransmit)
    {
        eStatus = (Std_ReturnType)Spi_Ip_AsyncTransmit(ExternalDevice,
                                                       (uint8 *)pTxBuffer,
                                                       (uint8 *)pRxBuffer,
                                                       (uint16)pSpiSetup->NumberOfBytes,
                                                       (Spi_Ip_CallbackType)pSpiSetup->Callback);
    }
    else
    {
#if (defined(SPI_START_TRANSFER_CALLBACK) && defined(SPI_END_TRANSFER_CALLBACK))
        SPI_START_TRANSFER_CALLBACK();
#endif
        eStatus = (Std_ReturnType)Spi_Ip_SyncTransmit(ExternalDevice,
                                                      (uint8 *)pTxBuffer,
                                                      (uint8 *)pRxBuffer,
                                                      (uint16)pSpiSetup->NumberOfBytes,
                                                      pSpiSetup->Timeout);
#if (defined(SPI_START_TRANSFER_CALLBACK) && defined(SPI_END_TRANSFER_CALLBACK))
        SPI_END_TRANSFER_CALLBACK();
#endif
    }
#elif defined(SBC_FS26_USE_IPV_LPSPI)
    if (FALSE == pSpiSetup->SyncTransmit)
    {
        eStatus = (Std_ReturnType)Lpspi_Ip_AsyncTransmit(ExternalDevice,
                                                       (uint8 *)pTxBuffer,
                                                       (uint8 *)pRxBuffer,
                                                       (uint16)pSpiSetup->NumberOfBytes,
                                                       (Lpspi_Ip_CallbackType)pSpiSetup->Callback);
    }
    else
    {
#if (defined(SPI_START_TRANSFER_CALLBACK) && defined(SPI_END_TRANSFER_CALLBACK))
        SPI_START_TRANSFER_CALLBACK();
#endif
        eStatus = (Std_ReturnType)Lpspi_Ip_SyncTransmit(ExternalDevice,
                                                      (uint8 *)pTxBuffer,
                                                      (uint8 *)pRxBuffer,
                                                      (uint16)pSpiSetup->NumberOfBytes,
                                                      pSpiSetup->Timeout);
#if (defined(SPI_START_TRANSFER_CALLBACK) && defined(SPI_END_TRANSFER_CALLBACK))
        SPI_END_TRANSFER_CALLBACK();
#endif
    }
#elif defined(SBC_FS26_USE_IPV_FLEXIO_SPI)
    if (FALSE == pSpiSetup->SyncTransmit)
    {
        eStatus = (Std_ReturnType)Flexio_Spi_Ip_AsyncTransmit(ExternalDevice,
                                                       (uint8 *)pTxBuffer,
                                                       (uint8 *)pRxBuffer,
                                                       (uint16)pSpiSetup->NumberOfBytes,
                                                       (Flexio_Spi_Ip_CallbackType)pSpiSetup->Callback);
    }
    else
    {
#if (defined(SPI_START_TRANSFER_CALLBACK) && defined(SPI_END_TRANSFER_CALLBACK))
        SPI_START_TRANSFER_CALLBACK();
#endif
        eStatus = (Std_ReturnType)Flexio_Spi_Ip_SyncTransmit(ExternalDevice,
                                                      (uint8 *)pTxBuffer,
                                                      (uint8 *)pRxBuffer,
                                                      (uint16)pSpiSetup->NumberOfBytes,
                                                      pSpiSetup->Timeout);
#if (defined(SPI_START_TRANSFER_CALLBACK) && defined(SPI_END_TRANSFER_CALLBACK))
        SPI_END_TRANSFER_CALLBACK();
#endif
    }
#else

#if (2U == SBC_FS26_SPI_LEVEL_DELIVERED)
        if (FALSE == pSpiSetup->SyncTransmit)
        {
#endif /* (2U == SBC_FS26_SPI_LEVEL_DELIVERED) */
#if ((2U == SBC_FS26_SPI_LEVEL_DELIVERED) || (1U == SBC_FS26_SPI_LEVEL_DELIVERED))
            eStatus |= (Std_ReturnType)Spi_AsyncTransmit(*SpiSequence);
#endif /* ((2U == SBC_FS26_SPI_LEVEL_DELIVERED) || (1U == SBC_FS26_SPI_LEVEL_DELIVERED)) */
#if (2U == SBC_FS26_SPI_LEVEL_DELIVERED)
        }
        else
        {
#endif /* (2U == SBC_FS26_SPI_LEVEL_DELIVERED) */
#if ((2U == SBC_FS26_SPI_LEVEL_DELIVERED) || (0U == SBC_FS26_SPI_LEVEL_DELIVERED))
            eStatus |= (Std_ReturnType)Spi_SyncTransmit(*SpiSequence);
#endif /* ((2U == SBC_FS26_SPI_LEVEL_DELIVERED) || (0U == SBC_FS26_SPI_LEVEL_DELIVERED)) */
#if (2U == SBC_FS26_SPI_LEVEL_DELIVERED)
        }
#endif /* (2U == SBC_FS26_SPI_LEVEL_DELIVERED) */
#endif

    return eStatus;
}


#ifndef SBC_FS26_SYNC_TRANSMIT
/*!
 * @brief Get the hardware SPI transmission status
 *
 * This function returns the SPI transmission status.
 * @param[in] pSpiSetup      SPI interface setup
 * @return                   SPI transmission status.
 *
 */
Sbc_fs26_SpiStatusType Sbc_fs26_GetTransmissionStatus(const Sbc_fs26_SpiSetupType *pSpiSetup)
{
    Sbc_fs26_SpiStatusType eSpiStatus;
#ifdef SBC_FS26_USE_IPV_DSPI
    uint8 SpiInstance = (uint8)pSpiSetup->Extension->Instance;
    Dspi_Ip_HwStatusType SpiStatus = Dspi_Ip_GetStatus(SpiInstance);
#elif defined(SBC_FS26_USE_IPV_SPI)
    uint8 SpiInstance = (uint8)pSpiSetup->Extension->Instance;
    Spi_Ip_HwStatusType SpiStatus = Spi_Ip_GetStatus(SpiInstance);
#elif defined(SBC_FS26_USE_IPV_LPSPI)
    uint8 SpiInstance = (uint8)pSpiSetup->Extension->Instance;
    Lpspi_Ip_HwStatusType SpiStatus = Lpspi_Ip_GetStatus(SpiInstance);
#elif defined(SBC_FS26_USE_IPV_FLEXIO_SPI)
    uint8 SpiInstance = (uint8)pSpiSetup->Extension->Instance;
    Flexio_Spi_Ip_HwStatusType SpiStatus = Flexio_Spi_Ip_GetStatus(SpiInstance);
#else
    const Spi_SequenceType   *SpiSequence = pSpiSetup->Extension;
    Spi_SeqResultType SpiStatus = Spi_GetSequenceResult(*SpiSequence);
#endif

    switch (SpiStatus)
    {
#ifdef SBC_FS26_USE_IPV_DSPI
        case DSPI_IP_IDLE:
#elif defined(SBC_FS26_USE_IPV_SPI)
        case SPI_IP_IDLE:
#elif defined(SBC_FS26_USE_IPV_LPSPI)
        case LPSPI_IP_IDLE:
#elif defined(SBC_FS26_USE_IPV_FLEXIO_SPI)
        case FLEXIO_SPI_IP_IDLE:
#else
        case SPI_SEQ_OK:
#endif
        eSpiStatus = SPI_TRANS_OK;
        break;
#ifdef SBC_FS26_USE_IPV_DSPI
        case DSPI_IP_BUSY:
#elif defined(SBC_FS26_USE_IPV_SPI)
        case SPI_IP_BUSY:
#elif defined(SBC_FS26_USE_IPV_LPSPI)
        case LPSPI_IP_BUSY:
#elif defined(SBC_FS26_USE_IPV_FLEXIO_SPI)
        case FLEXIO_SPI_IP_BUSY:
#else
        case SPI_SEQ_PENDING:
#endif
        eSpiStatus = SPI_TRANS_PENDING;
        break;
    default:
        eSpiStatus = SPI_TRANS_FAILED;
        break;
    }

    return eSpiStatus;
}

#endif


#define SBC_FS26_STOP_SEC_CODE
#include "Sbc_fs26_MemMap.h"

#endif /* (STD_ON == SBC_FS26_IP_SPI_USED) */

#if defined(__cplusplus)
}
#endif

/** @}*/
