/*!
* @file     Crypto_Sha256.c
*
* @version  1.0.0
*
* @brief    This file provides all the sha256 firmware functions
*   
* @attention
*
* Project Name      : AUTOSAR MCAL
*
* Platform          : Arm
*
* Autosar Standard  : Classic Platform 4.4.0
*
* Compiled Version  : G32A10xx_MCAL_1_0_0_15-Nov-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.
*/

#ifdef __cplusplus
extern "C"{
#endif

#include "Crypto_Sha256.h"
#include "Mcu_RcmReg.h"
#include "Crypto_ShaReg.h"
/** @addtogroup G32A10xx_StdPeriphDriver
  @{
*/

/** @defgroup CRYPTO_Driver
  * @brief CRYPTO driver modules
  @{
*/

/** @defgroup CRYPTO_Macros
  @{
*/
/*******************************************************************************
                    VENDOR ID & AUTOSAR VERSION INFO
*******************************************************************************/
/** Vendor ID (vendorId) of the dedicated implementation of this module according to the AUTOSAR vendor list. */
#define CRYPTO_SHA256_VENDOR_ID                         0x00C1U
/** Major version number of AUTOSAR release on which the appropriate implementation is based on. */
#define CRYPTO_SHA256_AR_RELEASE_MAJOR_VERSION          0x04U
/** Minor version number of AUTOSAR release on which the appropriate implementation is based on. */
#define CRYPTO_SHA256_AR_RELEASE_MINOR_VERSION          0x04U
/** Revision version number of AUTOSAR release on which the appropriate implementation is based on. */
#define CRYPTO_SHA256_AR_RELEASE_REVISION_VERSION       0x00U
/** Major version number of the vendor specific implementation of the module. The numbering is vendor specific. */
#define CRYPTO_SHA256_SW_MAJOR_VERSION                  0x01U
/** Minor version number of the vendor specific implementation of the module. The numbering is vendor specific. */
#define CRYPTO_SHA256_SW_MINOR_VERSION                  0x00U
/** Patch level version number of the vendor specific implementation of the module. The numbering is vendor specific. */
#define CRYPTO_SHA256_SW_PATCH_VERSION                  0x00U
/**@} end of group CRYPTO_Macros */
/*******************************************************************************
                            GLOBAL FUNCTIONS
*******************************************************************************/
/** @defgroup CRYPTO_Fuctions
  @{
*/
/*!
* @brief     Reset the SHA256 peripheral register.
*
* @param     None
*
* @retval    None
*/
FUNC(void, CRYPTO_CODE) Crypto_Sha256_Reset(void)
{
    REG_BIT_SET32(RCM_AHBRST_REG_ADDR,RCM_AHBRST_SHARST_MASK);
    REG_BIT_CLEAR32(RCM_AHBRST_REG_ADDR,RCM_AHBRST_SHARST_MASK);
}

/*!
* @brief     Configure the Number of valid bits in last word of the message.
*
* @param     ValidNumber: Number of valid bits in last word of the message.
*
* @retval    None
*/
FUNC(void, CRYPTO_CODE) Crypto_Sha256_CfgLastWordValidBitsNbr(VAR(uint64, AUTOMATIC) validNumber)
{
    REG_WRITE32(SHA256_DILH_REG_ADDR,(uint32_t)((validNumber) >> 32));
    REG_WRITE32(SHA256_DILL_REG_ADDR,(uint32_t)(validNumber));
}

/*!
* @brief     Writes data in the Input Data FIFO.
*
* @param     data: new data of the message to be processed.
*
* @retval    None
*/
FUNC(void, CRYPTO_CODE) Crypto_Sha256_WritesInputData(VAR(uint32, AUTOMATIC) data)
{
    REG_WRITE32(SHA256_DIN_REG_ADDR,data);
}

/*!
* @brief     Read the provides message digest.
*
* @param     messageDigest: pointer to a SHA256_Config_T structure.
*
* @retval    None
*/
FUNC(void, CRYPTO_CODE) Crypto_Sha256_ReadDigest(P2VAR( uint8, AUTOMATIC, CRYPTO_APPL_DATA ) outBuffer)
{
    VAR(uint8, AUTOMATIC) idx = 0;
    VAR(uint32, AUTOMATIC) readData = 0;
    for (idx = 0u; idx < 8u; idx++) 
    {   
        /* Read the data field */  
        readData = (uint32)REG_READ32(SHA256_DOUT_REG_ADDR(idx));
        outBuffer[(idx * 4u) + 0u] = (uint8)(readData >>  0);
        outBuffer[(idx * 4u) + 1u] = (uint8)(readData >>  8);
        outBuffer[(idx * 4u) + 2u] = (uint8)(readData >> 16);
        outBuffer[(idx * 4u) + 3u] = (uint8)(readData >> 24);
    }
}

/*!
* @brief     Start the Digest calculation.
*
* @param     None
*
* @retval    None
*/
FUNC(void, CRYPTO_CODE) Crypto_Sha256_StartDigest(void)
{
    REG_BIT_SET32(SHA256_CTRL_REG_ADDR,SHA256_CTRL_OP_START_MASK);
}

/*!
* @brief     Enables the specified SHA256 interrupts.
*
* @param     interrupt: Select the ADC interrupt sources
*                       This parameter can be any combination of the following values:
*                       SHA256_INT_INDATAINT: Input Data interrupt mask
*                       SHA256_INT_DCALCINT: Digest calculation completion Data interrupt mask
*
* @retval    None
*/
FUNC(void, CRYPTO_CODE) Crypto_Sha256_EnableInterrupt(void)
{
    REG_BIT_SET32(SHA256_CTRL_REG_ADDR,SHA256_CTRL_IE_MASK);
}

/*!
* @brief     Disables the specified SHA256 interrupts.
*
* @param     interrupt: Select the ADC interrupt sources
*                       This parameter can be any combination of the following values:
*                       SHA256_INT_INDATAINT: Input Data interrupt mask
*                       SHA256_INT_DCALCINT: Digest calculation completion Data interrupt mask
*
* @retval    None
*/
FUNC(void, CRYPTO_CODE) Crypto_Sha256_DisableInterrupt(void)
{
    REG_BIT_CLEAR32(SHA256_CTRL_REG_ADDR,SHA256_CTRL_IE_MASK);
}

/*!
* @brief     Reads the pending SHA256 flag
*
* @param     flag: Select the flag to check
*                  This parameter can be one of the following values:
*             SHA256_FLAG_INTR: Data input interrupt status flag
*             SHA256_FLAG_OP_DONE: Digest calculation completion interrupt status flag
*             SHA256_FLAG_BUSY: Busy flag
*
* @retval    SET or RESET
*/
FUNC(uint8, CRYPTO_CODE) Crypto_Sha256_ReadFlagStatus(VAR(Crypto_Sha256_FlagType, AUTOMATIC) flag)
{
    VAR(uint32, AUTOMATIC) reg = 0;   
    reg = REG_READ32(SHA256_STATUS_REG_ADDR);    

    return ((reg & (uint32)flag) != 0u) ? TRUE : FALSE;
}

/*!
* @brief Check if the hardware is busy
*/
FUNC(boolean, CRYPTO_CODE) Crypto_Sha256_IsBusy(void)
{
    VAR(uint8, AUTOMATIC) AesStatus = (uint8)REG_BIT_GET8(SHA256_STATUS_REG_ADDR, SHA256_STATUS_BUSY_MASK);

    VAR(boolean, AUTOMATIC) isBusy = (boolean)TRUE;

    if (SHA256_STATUS_BUSY_MASK != AesStatus) 
    {
        isBusy = (boolean)FALSE;
    }
    else
    {
        /* nothing */
    }
    return isBusy;
}

/*!
* @brief     Clears the pending SHA256 flag
*
* @param     flag: Select the flag to check
*                  This parameter can be one of the following values:
*            SHA256_FLAG_OP_DONE: Write 1 for clear OP_DONE.
*
* @retval    None
*/
FUNC(void, CRYPTO_CODE) Crypto_Sha256_ClearStatusFlag(void)
{
    REG_BIT_SET32(SHA256_STATUS_REG_ADDR,SHA256_STATUS_OP_DONE_MASK);
}

/*!
* @brief     Waits for Compute data
*
* @param     timeOut: Waits for Compute time
*
* @retval    ERROR: time
*            SUCCESS: The SHA256 OP DONE
*
*/
FUNC(uint8, CRYPTO_CODE) Crypto_Sha256_WaitForCompute(VAR(uint32, AUTOMATIC) timeOut)
{
    VAR(uint32, AUTOMATIC) timeNum = timeOut;
    VAR(uint32, AUTOMATIC) status = 0;
    VAR(uint8, AUTOMATIC) reply = FALSE;
    while (timeNum > 0u)
    {
        status = REG_READ32(SHA256_STATUS_REG_ADDR);
        if (((status & SHA256_STATUS_OP_DONE_MASK) == SHA256_STATUS_OP_DONE_MASK) && 
            ((status & SHA256_STATUS_BUSY_MASK) != SHA256_STATUS_BUSY_MASK))
        {
            break;
        }
        else
        {
            timeNum --;
        }
    }
    if (timeNum > 0u)
    {
        reply = TRUE;
    }
    else
    {
        /* do nothing */
    }
    return reply;
}

/**@} end of group CRYPTO_Fuctions */
#ifdef __cplusplus
}
#endif
/**@} end of group CRYPTO_Driver */
/**@} end of group G32A10xx_StdPeriphDriver */

