

#include "Simulated_SPI_Master.h"

SimSPIConfigStruct SimSPIConfig;

/******************************************************************************
函数名：SPI_Master_Start
功  能：初始化并启动SPI主机模式
参  数：Mode：SPI工作模式：         SIM_SPI_MODE_0
                                    SIM_SPI_MODE_1
                                    SIM_SPI_MODE_2
                                    SIM_SPI_MODE_3
                                    
        FirstBit：首先发送的数据位：SIM_SPI_MSB_FIRST
                                    SIM_SPI_LSB_FIRST
返回值：无
******************************************************************************/
void Sim_SPI_Master_Start(uint8_t Mode, uint8_t FirstBit)
{
    switch ( Mode )
    {
        case SIM_SPI_MODE_0:
            SimSPIConfig.CPOL = 0;
            SimSPIConfig.CPHA = 0;
            break;

        case SIM_SPI_MODE_1:
            SimSPIConfig.CPOL = 0;
            SimSPIConfig.CPHA = 1;
            break;

        case SIM_SPI_MODE_2:
            SimSPIConfig.CPOL = 1;
            SimSPIConfig.CPHA = 0;
            break;

        case SIM_SPI_MODE_3:
            SimSPIConfig.CPOL = 1;
            SimSPIConfig.CPHA = 1;
            break;

        default:
            SimSPIConfig.CPOL = 0;
            SimSPIConfig.CPHA = 0;
            break;
    }
    SimSPIConfig.FirstBit = FirstBit;

    SPI_SCLK = SimSPIConfig.CPOL;
    SPI_MOSI = 0;
}

/******************************************************************************
函数名：Sim_SPI_Master_Byte_Write
功  能：向SPI总线上写一字节
参  数：Data:要写入的数据
返回值：无
******************************************************************************/
void Sim_SPI_Master_Byte_Write(uint8_t Data)
{
    uint8_t BitPos;

    if ( SimSPIConfig.FirstBit == SIM_SPI_MSB_FIRST )
    {
        for ( BitPos = 0x80; BitPos >= 0x01; BitPos >>= 1 )
        {
            if ( SimSPIConfig.CPHA == 0 )
            {
                if ( Data & BitPos )
                    SPI_MOSI = 1;
                else
                    SPI_MOSI = 0;
            }

            SPI_SCLK ^= 0x01;

            if ( SimSPIConfig.CPHA )
            {
                if ( Data & BitPos )
                    SPI_MOSI = 1;
                else
                    SPI_MOSI = 0;
            }

            SPI_SCLK ^= 0x01;
        }
    }
    else
    {
        for ( BitPos = 0x01; BitPos <= 0x80; BitPos <<= 1 )
        {
            if ( SimSPIConfig.CPHA == 0 )
            {
                if ( Data & BitPos )
                    SPI_MOSI = 1;
                else
                    SPI_MOSI = 0;
            }

            SPI_SCLK ^= 0x01;

            if ( SimSPIConfig.CPHA )
            {
                if ( Data & BitPos )
                    SPI_MOSI = 1;
                else
                    SPI_MOSI = 0;
            }

            SPI_SCLK ^= 0x01;
        }
    }
}

/******************************************************************************
函数名：Sim_SPI_Master_Byte_Read
功  能：在SPI总线上读取一字节数据
参  数：TxData：在读取的同时写入的数据
返回值：读出的数据
******************************************************************************/
uint8_t Sim_SPI_Master_Byte_Read(uint8_t TxData)
{
    uint8_t RxData;
    uint8_t BitPos;

    RxData = 0x00;

    if ( SimSPIConfig.FirstBit == SIM_SPI_MSB_FIRST )
    {
        for ( BitPos = 0x80; BitPos >= 0x01; BitPos >>= 1 )
        {
            if ( SimSPIConfig.CPHA == 0 )
            {
                if ( TxData & BitPos )
                    SPI_MOSI = 1;
                else
                    SPI_MOSI = 0;
            }

            SPI_SCLK ^= 0x01;

            if ( SimSPIConfig.CPHA )
            {
                if ( TxData & BitPos )
                    SPI_MOSI = 1;
                else
                    SPI_MOSI = 0;
            }
            else
            {
                if ( SPI_MISO )
                    RxData |= BitPos;
            }

            SPI_SCLK ^= 0x01;

            if ( SimSPIConfig.CPHA )
            {
                if ( SPI_MISO )
                    RxData |= BitPos;
            }
        }
    }
    else
    {
        for ( BitPos = 0x01; BitPos <= 0x80; BitPos <<= 1 )
        {
            if ( SimSPIConfig.CPHA == 0 )
            {
                if ( TxData & BitPos )
                    SPI_MOSI = 1;
                else
                    SPI_MOSI = 0;
            }

            SPI_SCLK ^= 0x01;

            if ( SimSPIConfig.CPHA )
            {
                if ( TxData & BitPos )
                    SPI_MOSI = 1;
                else
                    SPI_MOSI = 0;
            }
            else
            {
                if ( SPI_MISO )
                    RxData |= BitPos;
            }

            SPI_SCLK ^= 0x01;

            if ( SimSPIConfig.CPHA )
            {
                if ( SPI_MISO )
                    RxData |= BitPos;
            }
        }
    }

    return RxData;
}

/******************************************************************************
函数名：Sim_SPI_Master_Word_Write
功  能：向SPI总线上写一个字(16bit)的数据
参  数：Data:要写入的数据
返回值：无
******************************************************************************/
void Sim_SPI_Master_Word_Write(uint16_t Data)
{
    uint16_t BitPos;

    if ( SimSPIConfig.FirstBit == SIM_SPI_MSB_FIRST )
    {
        for ( BitPos = 0x8000; BitPos >= 0x0001; BitPos >>= 1 )
        {
            if ( SimSPIConfig.CPHA == 0 )
            {
                if ( Data & BitPos )
                    SPI_MOSI = 1;
                else
                    SPI_MOSI = 0;
            }

            SPI_SCLK ^= 0x01;

            if ( SimSPIConfig.CPHA )
            {
                if ( Data & BitPos )
                    SPI_MOSI = 1;
                else
                    SPI_MOSI = 0;
            }

            SPI_SCLK ^= 0x01;
        }
    }
    else
    {
        for ( BitPos = 0x0001; BitPos <= 0x8000; BitPos <<= 1 )
        {
            if ( SimSPIConfig.CPHA == 0 )
            {
                if ( Data & BitPos )
                    SPI_MOSI = 1;
                else
                    SPI_MOSI = 0;
            }

            SPI_SCLK ^= 0x01;

            if ( SimSPIConfig.CPHA )
            {
                if ( Data & BitPos )
                    SPI_MOSI = 1;
                else
                    SPI_MOSI = 0;
            }

            SPI_SCLK ^= 0x01;
        }
    }
}

/******************************************************************************
函数名：Sim_SPI_Master_Word_Read
功  能：在SPI总线上读取一个字(16bit)的数据
参  数：TxData：在读取的同时写入的数据
返回值：读出的数据
******************************************************************************/
uint16_t Sim_SPI_Master_Word_Read(uint16_t TxData)
{
    uint16_t RxData;
    uint16_t BitPos;

    RxData = 0x00;

    if ( SimSPIConfig.FirstBit == SIM_SPI_MSB_FIRST )
    {
        for ( BitPos = 0x8000; BitPos >= 0x0001; BitPos >>= 1 )
        {
            if ( SimSPIConfig.CPHA == 0 )
            {
                if ( TxData & BitPos )
                    SPI_MOSI = 1;
                else
                    SPI_MOSI = 0;
            }

            SPI_SCLK ^= 0x01;

            if ( SimSPIConfig.CPHA )
            {
                if ( TxData & BitPos )
                    SPI_MOSI = 1;
                else
                    SPI_MOSI = 0;
            }
            else
            {
                if ( SPI_MISO )
                    RxData |= BitPos;
            }

            SPI_SCLK ^= 0x01;

            if ( SimSPIConfig.CPHA )
            {
                if ( SPI_MISO )
                    RxData |= BitPos;
            }
        }
    }
    else
    {
        for ( BitPos = 0x0001; BitPos <= 0x8000; BitPos <<= 1 )
        {
            if ( SimSPIConfig.CPHA == 0 )
            {
                if ( TxData & BitPos )
                    SPI_MOSI = 1;
                else
                    SPI_MOSI = 0;
            }

            SPI_SCLK ^= 0x01;

            if ( SimSPIConfig.CPHA )
            {
                if ( TxData & BitPos )
                    SPI_MOSI = 1;
                else
                    SPI_MOSI = 0;
            }
            else
            {
                if ( SPI_MISO )
                    RxData |= BitPos;
            }

            SPI_SCLK ^= 0x01;

            if ( SimSPIConfig.CPHA )
            {
                if ( SPI_MISO )
                    RxData |= BitPos;
            }
        }
    }

    return RxData;
}
