/*
  ******************************************************************************
  * @file    app.c
  * @version V1.0.0
  * @date    2021
  * @brief   DMA demo source code.
  ******************************************************************************
*/
#include "app.h"
#include "bsp_spi.h"

#define BUFFER_LENGTH    (256)

#define CHAR_START    (0xAA)
#define CHAR_END      (0x55)

uint8_t gu8_TxBuffer[BUFFER_LENGTH];
uint8_t gu8_RxBuffer[BUFFER_LENGTH];

extern SPI_DataTypeDef    spi_data;

/************************************************************************
 * function   : SPI_Slave_Comm_Test
 * Description: SPI Slave Communicate Test.
 ************************************************************************/ 
void SPI_Slave_Comm_Test(void)
{
    uint32_t i;

    Spi_Gpio_Init();
    Spi_Init();
    
    printfS("SPI Slave Test is Ready!!! \r\n");
    
    while (1) 
    {
                                
        SPI_Receive_IT(gu8_RxBuffer, sizeof(gu8_RxBuffer));
        while(SPI_GetRxState() != SPI_RX_STATE_IDLE);

        SPI_Transmit(gu8_RxBuffer, spi_data.Rx_Count, 0);
    
        printf("Rx_Count = %d. Tx_Count = %d.\r\n", spi_data.Rx_Count, spi_data.Tx_Count);
        for (i = 0; i < BUFFER_LENGTH; i++)
        {
            gu8_RxBuffer[i] = 0;
        }
    }
}

/************************************************************************
 * function   : SPI_Slave_Comm_IT
 * Description: SPI Slave Communicate Interrupt Test.
 ************************************************************************/ 
void SPI_Slave_Comm_IT(void)
{
    uint32_t i;

    Spi_Gpio_Init();
    Spi_Init();

    printfS("SPI Slave Test is Ready!!! \r\n");

    while (1) 
    {
        SPI_Receive_IT(gu8_RxBuffer, sizeof(gu8_RxBuffer));
        while(SPI_GetRxState() != SPI_RX_STATE_IDLE);

        SPI_Transmit_IT(gu8_RxBuffer, spi_data.Rx_Count);
        while(SPI_GetTxState() != SPI_TX_STATE_IDLE);
        
        printf("Rx_Count = %d. Tx_Count = %d.\r\n", spi_data.Rx_Count, spi_data.Tx_Count);
        for (i = 0; i < BUFFER_LENGTH; i++)
        {
            gu8_RxBuffer[i] = 0;
        }
    }
}

/************************************************************************
 * function   : SPI_Slave_DMA_Test
 * Description: SPI Slave DMA Test.
 ************************************************************************/ 
void SPI_Slave_DMA_Test(void)
{
    uint32_t i;
    
    uint32_t lu32_DataLength = 50;

    printfS("SPI Slave DMA Test is Ready!!! \r\n");
    
    Spi_Gpio_Init();
    Spi_Init();
    
    /* Enable DMA Clock */
    System_Module_Enable(EN_DMA);

    while (1) 
    {
        SPI_Receive_DMA(gu8_RxBuffer, lu32_DataLength);
        while(SPI_GetRxState() != SPI_RX_STATE_IDLE);

        SPI_Transmit_DMA(gu8_RxBuffer, lu32_DataLength);
        while(SPI_GetTxState() != SPI_TX_STATE_IDLE);
        
        for (i = 0; i < BUFFER_LENGTH;  i++)
        {
            gu8_RxBuffer[i] = 0;
        }
    }
}

/************************************************************************
 * function   : SPI_Slave_FullDuplex_Test
 * Description: SPI Slave Full Duplex Test. 
 ************************************************************************/ 
void SPI_Slave_FullDuplex_Test(void)
{
    uint32_t i;
    
    uint32_t lu32_COM_OK  = 0;
    uint32_t lu32_COM_Err = 0;
    uint32_t lu32_DataLength = 50;

    Spi_Gpio_Init();
    Spi_Init();
    
    printfS("SPI Slave Full Duplex Test is Ready!!! \r\n");
    
    while (1) 
    {
        for (i = 0; i < BUFFER_LENGTH; i++)
        {
            gu8_TxBuffer[i] = i+1;
            gu8_RxBuffer[i] = 0;
        }
                                
        SPI_TransmitReceive(gu8_TxBuffer, gu8_RxBuffer, lu32_DataLength, 0);
        
        for (i = 0; i < lu32_DataLength; i++)
        {
            if (gu8_TxBuffer[i] != (gu8_RxBuffer[i]+1)) 
            {
                printfS("There is one mistake : gu8_TxBuffer[%d]: 0x%02x != gu8_RxBuffer[%d]: 0x%02x \r\n", i,gu8_TxBuffer[i], i, gu8_RxBuffer[i]);
                
                lu32_COM_Err++;
            }
            else 
            {
                lu32_COM_OK++;
            }
        }
        
        printfS("SPI Slave Full Duplex Test OK count %d times \r\n",  lu32_COM_OK);
        printfS("SPI Slave Full Duplex Test Err count %d times \r\n", lu32_COM_Err);
        lu32_COM_Err = 0;
        lu32_COM_OK = 0;
    }
}

/************************************************************************
 * function   : SPI_Slave_Test
 * Description: SPI Slave Test.
 ************************************************************************/ 
void SPI_Slave_Test(enum_TEST_MODE_t fe_Mode)
{
    printfS("---------- SPI Slave Test ----------\r\n");
        
    switch (fe_Mode)
    {
        case TEST_SLAVE_COMM: 
            SPI_Slave_Comm_Test();
            break; 
        
        case TEST_SLAVE_IT: 
            SPI_Slave_Comm_IT();
            break; 
        
        case TEST_SLAVE_DMA: 
            SPI_Slave_DMA_Test();
            break;
       
        case TEST_SLAVE_FULL_DUPLEX: 
            SPI_Slave_FullDuplex_Test();
            break;
       
        default: break;     
    }
}
