/* Copyright Statement:
 *
 * This software/firmware and related documentation ("AutoChips Software") are
 * protected under relevant copyright laws. The information contained herein is
 * confidential and proprietary to AutoChips Inc. and/or its licensors. Without
 * the prior written permission of AutoChips inc. and/or its licensors, any
 * reproduction, modification, use or disclosure of AutoChips Software, and
 * information contained herein, in whole or in part, shall be strictly
 * prohibited.
 *
 * AutoChips Inc. (C) 2022. All rights reserved.
 *
 * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
 * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("AUTOCHIPS SOFTWARE")
 * RECEIVED FROM AUTOCHIPS AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
 * ON AN "AS-IS" BASIS ONLY. AUTOCHIPS EXPRESSLY DISCLAIMS ANY AND ALL
 * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
 * NONINFRINGEMENT. NEITHER DOES AUTOCHIPS PROVIDE ANY WARRANTY WHATSOEVER WITH
 * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
 * INCORPORATED IN, OR SUPPLIED WITH THE AUTOCHIPS SOFTWARE, AND RECEIVER AGREES
 * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
 * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
 * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN AUTOCHIPS
 * SOFTWARE. AUTOCHIPS SHALL ALSO NOT BE RESPONSIBLE FOR ANY AUTOCHIPS SOFTWARE
 * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
 * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND AUTOCHIPS'S
 * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE AUTOCHIPS SOFTWARE
 * RELEASED HEREUNDER WILL BE, AT AUTOCHIPS'S OPTION, TO REVISE OR REPLACE THE
 * AUTOCHIPS SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
 * CHARGE PAID BY RECEIVER TO AUTOCHIPS FOR SUCH AUTOCHIPS SOFTWARE AT ISSUE.
 */

#ifndef _AC780X_SPI_REG_H
#define _AC780X_SPI_REG_H
/*!
 * @file ac780x_spi_reg.h
 *
 * @brief SPI access register inline function definition.
 *
 */
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */


/* ===========================================  Includes  =========================================== */
#include "ac780x_spi.h"

/* ============================================  Define  ============================================ */

/* ===========================================  Typedef  ============================================ */

/* ==========================================  Variables  =========================================== */

/* ====================================  Functions declaration  ===================================== */

/* ======================================  Functions define  ======================================== */
/*!
* @brief Set SPI CS baudrate, 1/(low_time + high_time)
*
* @param[in] SPIx: SPI module
*                  - SPI0
* @param[in] sckLow: SPI SCK Low count, low_time = (SCK_LOW + 1) * Bus_Period
* @param[in] sckHigh: SPI SCK High count, high_time = (SCK_LOW + 1) * SCK_High
* @return none
*/
__STATIC_INLINE void SPI_SetBaudrate(SPI_Type *SPIx, uint8_t sckLow, uint8_t sckHigh)
{
    MODIFY_REG32(SPIx->CFG0, SPI_CFG0_SCK_HIGH_Msk, SPI_CFG0_SCK_HIGH_Pos, sckHigh);
    MODIFY_REG32(SPIx->CFG0, SPI_CFG0_SCK_LOW_Msk, SPI_CFG0_SCK_LOW_Pos, sckLow);
}

/*!
* @brief Set SPI frame size
*
* @param[in] SPIx: SPI module
*                  - SPI0
* @param[in] frameSize: SPI frame size, support 4~16bits, value can be 0 to 15
* @return none
*/
__STATIC_INLINE void SPI_SetFRMSize(SPI_Type *SPIx, SPI_FrameSizeType frameSize)
{
    MODIFY_REG32(SPIx->CFG1, SPI_CFG1_FRMSIZE_Msk, SPI_CFG1_FRMSIZE_Pos, frameSize);
}

/*!
* @brief Set SPI master mode fault cs check time
*
* @param[in] SPIx: SPI module
*                  - SPI0
* @param[in] time: CS check time：0~255
* @return none
*/
__STATIC_INLINE void SPI_SetMasterFaultCheckTime(SPI_Type *SPIx, uint8_t time)
{
    MODIFY_REG32(SPIx->CFG2, SPI_CFG2_CS_CHECK_Msk, SPI_CFG2_CS_CHECK_Pos, time);
}

/*!
* @brief Get SPI frame size
*
* @param[in] SPIx: SPI module
*                  - SPI0
* @return frameSize: SPI frame size, support 4~16bits, value can be 0 to 15
*/
#define SPI_GetFRMSize(SPIx)    (((SPIx)->CFG1 & SPI_CFG1_FRMSIZE_Msk) >> SPI_CFG1_FRMSIZE_Pos)

/*!
* @brief Set SPI CPHA
*
* @param[in] SPIx: SPI module
*                  - SPI0
* @param[in] cpha: SPI CPHA
*                  -SPI_CPHA_1EDGE
*                  -SPI_CPHA_2EDGE
* @return none
*/
__STATIC_INLINE void SPI_SetCPHA(SPI_Type *SPIx, SPI_CphaType cpha)
{
    MODIFY_REG32(SPIx->CFG1, SPI_CFG1_CPHA_Msk, SPI_CFG1_CPHA_Pos, cpha);
}

/*!
* @brief Set SPI CPOL
*
* @param[in] SPIx: SPI module
*                  - SPI0
* @param[in] cpol: SPI cpol select
*                  - SPI_CPOL_LOW
*                  - SPI_CPOL_HIGH
* @return none
*/
__STATIC_INLINE void SPI_SetCPOL(SPI_Type *SPIx, SPI_CpolType cpol)
{
    MODIFY_REG32(SPIx->CFG1, SPI_CFG1_CPOL_Msk, SPI_CFG1_CPOL_Pos, cpol);
}

/*!
* @brief Set SPI Rx MSB first
*
* @param[in] SPIx: SPI module
*                  - SPI0
* @param[in] state: Enable/Disable SPI Rx MSB first
*                  - ENABLE: the first bit of shifter shift in is the MSB of the input data
*                  - DISABLE:the first bit of shifter shift in is the LSB of  the input data
* @return none
*/
__STATIC_INLINE void SPI_SetRMSBF(SPI_Type *SPIx, ACTION_Type state)
{
    MODIFY_REG32(SPIx->CFG1, SPI_CFG1_RMSBF_Msk, SPI_CFG1_RMSBF_Pos, state);
}

/*!
* @brief Set SPI Tx MSB first
*
* @param[in] SPIx: SPI module
*                  - SPI0
* @param[in] txMsbFirstEn: Enable/Disable SPI Tx MSB first
*                  - ENABLE: MSB first shift out
*                  - DISABLE:LSB first shift out
* @return none
*/
__STATIC_INLINE void SPI_SetTMSBF(SPI_Type *SPIx, ACTION_Type txMsbFirstEn)
{
    MODIFY_REG32(SPIx->CFG1, SPI_CFG1_MSBF_Msk, SPI_CFG1_MSBF_Pos, txMsbFirstEn);
}

/*!
* @brief Set SPI CS
*
* @param[in] SPIx: SPI module
*                  - SPI0
* @param[in] state: Enable/Diaable SPI CS output continuous
*                  - ENABLE: CS output continuous
*                  - DISABLE:CS output non-continuous
* @return none
*/
__STATIC_INLINE void SPI_SetContinuousCS(SPI_Type *SPIx, ACTION_Type state)
{
    MODIFY_REG32(SPIx->CFG1, SPI_CFG1_CONT_CS_Msk, SPI_CFG1_CONT_CS_Pos, state);
}

/*!
* @brief Set SPI CS output enable
*
* @param[in] SPIx: SPI module
*                  - SPI0
* @param[in] state: Enable/Diaable SPI CS hardware output
*                  - ENABLE: enable the CS hardware output
*                  - DISABLE:disable the CS hardware output
* @return none
*/
__STATIC_INLINE void SPI_SetCSOE(SPI_Type *SPIx, ACTION_Type state)
{
    MODIFY_REG32(SPIx->CFG1, SPI_CFG1_CSOE_Msk, SPI_CFG1_CSOE_Pos, state);
}

/*!
* @brief Enable/Disable SPI CS mode fault detect function
*
* @param[in] SPIx: SPI module
*                  - SPI0
* @param[in] state: Enable/Disable SPI CS mode fault detect function
*                  - ENABLE: enable the multi-master detect function
*                  - DISABLE: disable the multi-master detect function
* @return none
*/
__STATIC_INLINE void SPI_SetModeFault(SPI_Type *SPIx, ACTION_Type state)
{
    MODIFY_REG32(SPIx->CFG1, SPI_CFG1_MODFEN_Msk, SPI_CFG1_MODFEN_Pos, state);
}

/*!
* @brief Enable/Disable SPI wake up function
*
* @param[in] SPIx: SPI module
*                  - SPI0
* @param[in] wakuEn: SPI WAKUEN
*                  - ENABLE: enable slave wake up function
*                  - DISABLE: disable slave wake up function
* @return none
*/
__STATIC_INLINE void SPI_SetWakeup(SPI_Type *SPIx, ACTION_Type state)
{
    MODIFY_REG32(SPIx->CFG1, SPI_CFG1_WKUEN_Msk, SPI_CFG1_WKUEN_Pos, state);
}

/*!
* @brief Set SPI CS Idle count time
*
* @param[in] SPIx: SPI module
*                  - SPI0
* @param[in] csIdleCnt: SPI CS Idle count
*                  - CS IDLE time = (csIdleCount+1)*CLK_PERIOD
* @return none
*/
__STATIC_INLINE void SPI_SetCSIdle(SPI_Type *SPIx, uint8_t csIdleCnt)
{
    MODIFY_REG32(SPIx->CFG1, SPI_CFG1_CS_IDLE_Msk, SPI_CFG1_CS_IDLE_Pos, csIdleCnt);
}
/*!
* @brief Set SPI CS Setup count
*
* @param[in] SPIx: SPI module
*                  - SPI0
* @param[in] csSetupCnt: SPI CS Setup count
*                   - setup time = (csSetupCnt+1)*CLK_PERIOD
* @return none
*/
__STATIC_INLINE void SPI_CSSetup(SPI_Type *SPIx, uint8_t csSetupCnt)
{
    MODIFY_REG32(SPIx->CFG0, SPI_CFG0_CS_SETUP_Msk, SPI_CFG0_CS_SETUP_Pos, csSetupCnt);
}

/*!
* @brief Set SPI CS Hold count
*
* @param[in] SPIx: SPI module
*                  - SPI0
* @param[in] csHoldCnt: SPI CS Hold count
*                  - hold time = (csHoldCnt+1)*CLK_PERIOD.
* @return none
*/
__STATIC_INLINE void SPI_CSHold(SPI_Type *SPIx, uint8_t csHoldCnt)
{
    MODIFY_REG32(SPIx->CFG0, SPI_CFG0_CS_HOLD_Msk, SPI_CFG0_CS_HOLD_Pos, csHoldCnt);
}

/*!
* @brief Enable/Disable SPI module
*
* @param[in] SPIx: SPI module
*                  - SPI0
* @param[in] state: enable/disable SPI module
*                  - ENABLE
*                  - DISABLE
* @return none
*/
__STATIC_INLINE void SPI_SetEnable(SPI_Type *SPIx, ACTION_Type state)
{
    MODIFY_REG32(SPIx->CMD, SPI_CMD_SPIEN_Msk, SPI_CMD_SPIEN_Pos, state);
}

/*!
* @brief Reset SPI Module
*
* @param[in] SPIx: SPI module
*                  - SPI0
* @return none
*/
__STATIC_INLINE void SPI_SoftwareReset(SPI_Type *SPIx)
{
    SPIx->CMD |= SPI_CMD_SWRST_Msk;
}

/*!
* @brief Release SPI CS, it will go high
*
* @param[in] SPIx: SPI module
*                  - SPI0
* @return none
*/
__STATIC_INLINE void SPI_CSRelease(SPI_Type *SPIx)
{
    SPIx->CMD |= SPI_CMD_CSRLS_Msk;
}

/*!
* @brief Start Master Receive With Rx Only Mode
*
* @param[in] SPIx: SPI module
*                  - SPI0
* @return none
*/
__STATIC_INLINE void SPI_RxOnlyModeTrig(SPI_Type *SPIx)
{
    SPIx->CMD |= SPI_CMD_ROTRIG_Msk;
}

/*!
* @brief Set SPI mode: Master/Slave
*
* @param[in] SPIx: SPI module
*                  - SPI0
* @param[in] mode: set SPI master mode
*                  - SPI_MASTER: spi master mode
*                  - SPI_SLAVE:  spi slave mode
* @return none
*/
__STATIC_INLINE void SPI_SetMode(SPI_Type *SPIx, SPI_ModeType mode)
{
    MODIFY_REG32(SPIx->CFG1, SPI_CFG1_MSTR_Msk, SPI_CFG1_MSTR_Pos, mode);
}

/*!
* @brief Enable/Disable SPI tx empty Interrupt
*
* @param[in] SPIx: SPI module
*                  - SPI0
* @param[in] state: enable/disable SPI tx empty interrupt
*                  - ENABLE
*                  - DISABLE
* @return none
*/
__STATIC_INLINE void SPI_SetTxEInterrupt(SPI_Type *SPIx, ACTION_Type state)
{
    MODIFY_REG32(SPIx->CFG1, SPI_CFG1_TXEIE_Msk, SPI_CFG1_TXEIE_Pos, state);
}

/*!
* @brief Enable SPI rx full Interrupt
*
* @param[in] SPIx: SPI module
*                  - SPI0
* @param[in] state: enable/disable SPI rx full interrupt
*                  - ENABLE
*                  - DISABLE
* @return none
*/
__STATIC_INLINE void SPI_SetRxFInterrupt(SPI_Type *SPIx, ACTION_Type state)
{
    MODIFY_REG32(SPIx->CFG1, SPI_CFG1_RXFIE_Msk, SPI_CFG1_RXFIE_Pos, state);
}

/*!
* @brief Enable SPI tx underflow Interrupt
*
* @param[in] SPIx: SPI module
*                  - SPI0
* @param[in] state: enable/disable SPI tx underflow interrupt
*                  - ENABLE
*                  - DISABLE
* @return none
*/
__STATIC_INLINE void SPI_SetTxUInterrupt(SPI_Type *SPIx, ACTION_Type state)
{
    MODIFY_REG32(SPIx->CFG1, SPI_CFG1_TXUIE_Msk, SPI_CFG1_TXUIE_Pos, state);
}

/*!
* @brief Enable SPI rx overflow Interrupt
*
* @param[in] SPIx: SPI module
*                  - SPI0
* @param[in] state: enable/disable SPI rx overflow interrupt
*                  - ENABLE
*                  - DISABLE
* @return none
*/
__STATIC_INLINE void SPI_SetRxOInterrupt(SPI_Type *SPIx, ACTION_Type state)
{
    MODIFY_REG32(SPIx->CFG1, SPI_CFG1_RXOIE_Msk, SPI_CFG1_RXOIE_Pos, state);
}

/*!
* @brief Enable/Disable SPI Mode Fault Interrupt
*
* @param[in] SPIx: SPI module
*                  - SPI0
* @param[in] state: enable/disable SPI mode fault interrupt
*                  - ENABLE
*                  - DISABLE
* @return none
*/
__STATIC_INLINE void SPI_SetModeFaultInterrupt(SPI_Type *SPIx, ACTION_Type state)
{
    MODIFY_REG32(SPIx->CFG1, SPI_CFG1_MODFIE_Msk, SPI_CFG1_MODFIE_Pos, state);
}

/*!
* @brief Check current SPI Master flag
*
* @param[in] SPIx: SPI module
*                  - SPI0
* @return 0:slave, 1:master
*/
#define SPI_IsMaster(SPIx)    (((SPIx)->CFG1 & SPI_CFG1_MSTR_Msk) >> SPI_CFG1_MSTR_Pos)

/*!
* @brief Check current SPI Tx empty flag
*
* @param[in] SPIx: SPI module
*                  - SPI0
* @return 0:not empty, 1:empty
*/
#define SPI_IsTxEF(SPIx)    (((SPIx)->STATUS & SPI_STATUS_TXEF_Msk) >> SPI_STATUS_TXEF_Pos)

/*!
* @brief Check current SPI Rx full flag
*
* @param[in] SPIx: SPI module
*                  - SPI0
* @return 0:not full, 1:full
*/
#define SPI_IsRxFF(SPIx)    (((SPIx)->STATUS & SPI_STATUS_RXFF_Msk) >> SPI_STATUS_RXFF_Pos)

/*!
* @brief Check current SPI Tx underflow flag
*
* @param[in] SPIx: SPI module
*                  - SPI0
* @return 0:no underflow, 1:underflow
*/
#define SPI_IsTxUF(SPIx)    (((SPIx)->STATUS & SPI_STATUS_TXUF_Msk) >> SPI_STATUS_TXUF_Pos)

/*!
* @brief Check current SPI Rx overflow flag
*
* @param[in] SPIx: SPI module
*                  - SPI0
* @return 0:no overflow, 1:overflow
*/
#define SPI_IsRxOF(SPIx)   (((SPIx)->STATUS & SPI_STATUS_RXOF_Msk) >> SPI_STATUS_RXOF_Pos)

/*!
* @brief Check current SPI Busy flag
*
* @param[in] SPIx: SPI module
*                  - SPI0
* @return 0:not busy, 1:busy
*/
#define SPI_IsBusy(SPIx)  (((SPIx)->STATUS & SPI_STATUS_MEBY_Msk) >> SPI_STATUS_MEBY_Pos)

/*!
* @brief Check current SPI Mode error flag
*
* @param[in] SPIx: SPI module
*                  - SPI0
* @return 0:no multi-master error detected , 1:master mode error detected
*/
#define SPI_IsModeFault(SPIx)   (((SPIx)->STATUS & SPI_STATUS_MODEF_Msk) >> SPI_STATUS_MODEF_Pos)

/*!
* @brief Clear current SPI Tx underflow flag
*
* @param[in] SPIx: SPI module
*                  - SPI0
* @return none
*/
#define SPI_ClearTxUF(SPIx)    ((SPIx)->STATUS = SPI_STATUS_TXUF_Msk)

/*!
* @brief Clear current SPI Rx overflow flag
*
* @param[in] SPIx: SPI module
*                  - SPI0
* @return none
*/
#define SPI_ClearRxOF(SPIx)   ((SPIx)->STATUS = SPI_STATUS_RXOF_Msk)

/*!
* @brief Check current SPI Tx empty interrupt is enabled or not
*
* @param[in] SPIx: SPI module
*                  - SPI0
* @return 0: interrupt is not enabled , 1: interrupt is enabled
*/
#define SPI_IsTxEFInterruptEn(SPIx)    (((SPIx)->CFG1 & SPI_CFG1_TXEIE_Msk) >> SPI_CFG1_TXEIE_Pos)

/*!
* @brief Check current SPI Rx full interrupt is enabled or not
*
* @param[in] SPIx: SPI module
*                  - SPI0
* @return 0: interrupt is not enabled , 1: interrupt is enabled
*/
#define SPI_IsRxFFInterruptEn(SPIx)    (((SPIx)->CFG1 & SPI_CFG1_RXFIE_Msk) >> SPI_CFG1_RXFIE_Pos)

/*!
* @brief Check current SPI Tx underflow interrupt is enabled or not
*
* @param[in] SPIx: SPI module
*                  - SPI0
* @return 0: interrupt is not enabled , 1: interrupt is enabled
*/
#define SPI_IsTxUFInterruptEn(SPIx)    (((SPIx)->CFG1 & SPI_CFG1_TXUIE_Msk) >> SPI_CFG1_TXUIE_Pos)

/*!
* @brief Check current SPI Rx overflow interrupt is enabled or not
*
* @param[in] SPIx: SPI module
*                  - SPI0
* @return 0: interrupt is not enabled , 1: interrupt is enabled
*/
#define SPI_IsRxOFInterruptEn(SPIx)   (((SPIx)->CFG1 & SPI_CFG1_RXOIE_Msk) >> SPI_CFG1_RXOIE_Pos)

/*!
* @brief Check current SPI Mode fault interrupt is enabled or not
*
* @param[in] SPIx: SPI module
*                  - SPI0
* @return 0: interrupt is not enabled , 1: interrupt is enabled
*/
#define SPI_IsModeFaultInterruptEn(SPIx)   (((SPIx)->CFG1 & SPI_CFG1_MODFIE_Msk) >> SPI_CFG1_MODFIE_Pos)

/*!
* @brief Write data into DATA register
*
* @param[in] SPIx: SPI module
*                  - SPI0
* @param[in] dataBuff: SPI send data
* @return none
*/
#define SPI_WriteDataReg(SPIx, dataBuff)    ((SPIx)->DATA = (dataBuff))

/*!
* @brief Read data from DATA register
*
* @param[in] SPIx: SPI module
*                  - SPI0
* @return: SPI receive data
*/
#define SPI_ReadDataReg(SPIx)    ((uint16_t)((SPIx)->DATA & 0xFFFF))

/*!
* @brief  Config Master no overflow mode
*
* @param[in] SPIx: SPI module
*                  - SPI0
* @param[in] state: enable/disable SPI no over flow mode
*                  - ENABLE
*                  - DISABLE
*
* @return none
*/
__STATIC_INLINE void SPI_SetMasterNoOverflowMode(SPI_Type *SPIx, ACTION_Type state)
{
    MODIFY_REG32(SPIx->CFG2, SPI_CFG2_MNOV_Msk, SPI_CFG2_MNOV_Pos, state);
}

/*!
* @brief Enable/Disable Master Tx Only mode
*
* @param[in] SPIx: SPI module
*                  - SPI0
* @param[in] state: enable/disable SPI tx only mode
*                  - ENABLE
*                  - DISABLE
* @return none
*/
__STATIC_INLINE void SPI_SetTxOnly(SPI_Type *SPIx, ACTION_Type state)
{
    MODIFY_REG32(SPIx->CFG2, SPI_CFG2_TOEN_Msk, SPI_CFG2_TOEN_Pos, state);
}

/*!
* @brief Enable/Disable Master Rx Only mode
*
* @param[in] SPIx: SPI module
*                  - SPI0
* @param[in] state: enable/disable SPI rx only mode
*                  - ENABLE
*                  - DISABLE
* @return none
*/
__STATIC_INLINE void SPI_SetRxOnly(SPI_Type *SPIx, ACTION_Type state)
{
    MODIFY_REG32(SPIx->CFG2, SPI_CFG2_ROEN_Msk, SPI_CFG2_ROEN_Pos, state);
}

#ifdef __cplusplus
}
#endif

#endif /* _AC780X_SPI_REG_H */

/* =============================================  EOF  ============================================== */
