/* 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) 2023. 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.
 */
/******************************************************************************
 * @version: V1.0.0 demo
 ******************************************************************************/

/*!
* @file spi.c
*
* @brief This file contains the user spi function..
*
*/

/* ===========================================  Includes  =========================================== */
#include "gpio.h"
#include "spi.h"
#include "ac780x_spi.h"
#include "ac780x_spi_reg.h"

/* ============================================  Define  ============================================ */
#define SPI1_TX_DMA_CHN     (DMA0_CHANNEL0)     /* DMA channel sent by SPI */
#define SPI1_RX_DMA_CHN     (DMA0_CHANNEL1)     /* DMA channel for SPI reception */
#define SPI_DATA_LEN    8u /* In the full-duplex mode of SPI, the data length of TX and RX must be the same */

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

/* ==========================================  Variables  =========================================== */
uint8_t rxBuff[SPI_DATA_LEN] = {0};    /* SPI1 receive array */
uint8_t txBuff[SPI_DATA_LEN] = {0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55};  /* SPI1 send array */
uint32_t g_DMA_startReceive = 0;        /* receive complete flag */
uint32_t g_DMA_startTransmit = 0;       

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

/* ======================================  Functions define  ======================================== */
/*!
* @brief  DMA Callback
*
* @param[in] none
* @return none
*/
void DMA_SPI_RX_Callback(void *device, uint32_t wpara, uint32_t lpara)
{
    if (wpara & DMA_CHANNEL_STATUS_FINISH_Msk)
    {
        g_DMA_startReceive = 0;
        /* Release SPI CS, it will go high */
        SPI_CSRelease(SPI1);
    }
}

/*!
* @brief  spi dma tx and rx test
*
* @param[in] none
* @return none
*/
void Spi1_Test(void)
{
    ERROR_Type ret = ERROR;

    if(g_DMA_startReceive == 0)
    {
        txBuff[0]++;
        g_DMA_startReceive = 1;
        
        /* SPI_TransmitReceiveDMA() The callback function of DMA is triggered after RX is completed*/
        ret = SPI_TransmitReceiveDMA(SPI1, SPI1_TX_DMA_CHN, SPI1_RX_DMA_CHN, rxBuff, txBuff, SPI_DATA_LEN, DMA_SPI_RX_Callback); 
        if(ret == ERROR)
        {
            printf("ERROR\r\n");
        }
        else
        {
            printf("SUCCESS\r\n");
        }
    }   
    else
    {
        
    }
    mdelay(200);
}

/*!
* @brief  Init spi1 pin
*
* @param[in] none
* @return none
*/
void Spi1_Gpio_Init(void)
{
    GPIO_SetFunc(GPIOB, GPIO_PIN12, GPIO_FUN3);     /* SCK */
    GPIO_SetFunc(GPIOB, GPIO_PIN11, GPIO_FUN3);     /* MOSI */
    GPIO_SetFunc(GPIOC, GPIO_PIN1, GPIO_FUN3);      /* CS */
    GPIO_SetFunc(GPIOC, GPIO_PIN0, GPIO_FUN3);      /* MISO */  
}

/*!
* @brief  Init spi
*
* @param[in] none
* @return none
*/
void Spi1_Init(void)
{
    SPI_ConfigType spi_config_t;
    
    memset(&spi_config_t, 0x00, sizeof(spi_config_t));
    
    /* The baud rate of SPI is 1Mhz */
    spi_config_t.csSetup = 20;   /* Chip Select Setup Time  = (CS_SETUP + 1) * CLK_PERIOD. */
    spi_config_t.csHold  = 20;   /* Chip Select Hold Time = (CS_HOLD + 1) * CLK_PERIOD. */
    spi_config_t.sckHigh = 15;   /* SCK clock high time= (SCK_HIGH + 1) * CLK_PERIOD. */
    spi_config_t.sckLow  = 15;   /* SCK clock low time = (SCK_LOW + 1) * CLK_PERIOD. */
    spi_config_t.csIdle  = 20;   /* CS free time = (CS_IDLE + 1) * CLK_PERIOD. */
    spi_config_t.mode      = SPI_MASTER;        /* set master */
    spi_config_t.cpha      = SPI_CPHA_1EDGE;    /* second edge sampling */
    spi_config_t.cpol      = SPI_CPOL_LOW;     /* SCK active high */
    spi_config_t.frmSize   = SPI_FRAME_SIZE_8BITS;  /* transfer byte width 8bits */
    spi_config_t.rxMsbFirstEn      = ENABLE;    /* RX MSB */
    spi_config_t.txMsbFirstEn      = ENABLE;    /* TX MSB */
    spi_config_t.csOutputEn        = ENABLE;    /* CS is hardware control */
    spi_config_t.continuousCSEn    = ENABLE;    /* CS is continuous mode */
    spi_config_t.dmaRxEn       = ENABLE;   /* RX DMA disable */
    spi_config_t.dmaTxEn       = ENABLE;   /* TX DMA disable */
    spi_config_t.modeFaultEn   = DISABLE;   /* Fault detection mode disable*/
    spi_config_t.wakeUpEn      = DISABLE;   /* wake up disable */
    spi_config_t.spiEn         = ENABLE;    /* Spi enable */
    spi_config_t.callBack      = NULL;      /* call back fun */
    spi_config_t.interruptEn   = DISABLE;   /* interrupt enable */
    spi_config_t.txUFInterruptEn       = DISABLE;   /* TX buffer underflow interrupt enable */
    spi_config_t.rxOFInterruptEn       = DISABLE;   /* RX buffer overflow interrupt enable */
    spi_config_t.modeFaultInterruptEn = DISABLE;    /* Mode Fault Interrupt disable */
    
    SPI_Init(SPI1, &spi_config_t);  /* spi initialization */
    Spi1_Gpio_Init();               /* spi Pin initialization */
}





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