/*
*************************************************************
 Copyright (C), 2016-2020 smartlinkMicro. Co., Ltd.  All rights reserved.
 Filename:
 Complier:      ARM-MDK 5.xx
 Target OS:
 Target HW:
 Author:        htyi
 Version :      V1.0.0
 Date:          2016.4.16
 Description:
 History:
     <author>     <time>     <version >   <desc>

*************************************************************
*/
#include "utilities.h"
#include "spi.h"

//#include "slm_type.h"
#include "sl2x23.h"

static volatile  u8 Irq1_Delay_Cnt = 0;
static volatile  u8  Irq2_Delay_Cnt = 0;

static volatile  u8  DEV_Wkup_Pwm_Level_Hl;
static volatile  u8  DEV_Wkup_Pwm_Level_Hh;
static volatile  u16 DEV_Wkup_Pwm_cnt ;

#undef  HW_V0    // for the original 1101\1101B  demo hardware
#define HW_V1       // for the original production test hardware
void DEV_SPI_Init(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;
    SPI_InitTypeDef   SPI_InitStructure;

    /*!< SPI_CS_GPIO, SPI_MOSI_GPIO, SPI_MISO_GPIO,
         and SPI_SCK_GPIO Periph clock enable */
    RCC_AHBPeriphClockCmd(SPI_MOSI_GPIO_CLK | SPI_MISO_GPIO_CLK |
                          SPI_SCK_GPIO_CLK, ENABLE);

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);


    /*!< SPI Periph clock enable */
    RCC_APB1PeriphClockCmd(SPI_CLK, ENABLE);

    /*!< Configure SPI pins: SCK */
    GPIO_InitStructure.GPIO_Pin = SPI_SCK_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
    GPIO_Init(SPI_SCK_GPIO_PORT, &GPIO_InitStructure);

    /*!< Configure SPI pins: MISO */
    GPIO_InitStructure.GPIO_Pin = SPI_MISO_PIN;
    GPIO_Init(SPI_MISO_GPIO_PORT, &GPIO_InitStructure);

    /*!< Configure SPI pins: MOSI */
    GPIO_InitStructure.GPIO_Pin = SPI_MOSI_PIN;
    GPIO_Init(SPI_MOSI_GPIO_PORT, &GPIO_InitStructure);

    /*!< Configure SPI_CS_PIN pin:  CS pin */
    GPIO_InitStructure.GPIO_Pin = SPI_CS_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(SPI_CS_GPIO_PORT, &GPIO_InitStructure);

    /* Connect PXx to SD_SPI_SCK */
    GPIO_PinAFConfig(SPI_SCK_GPIO_PORT, SPI_SCK_SOURCE, SPI_SCK_AF);
    /* Connect PXx to SD_SPI_MISO */
    GPIO_PinAFConfig(SPI_MISO_GPIO_PORT, SPI_MISO_SOURCE, SPI_MISO_AF);
    /* Connect PXx to SD_SPI_MOSI */
    GPIO_PinAFConfig(SPI_MOSI_GPIO_PORT, SPI_MOSI_SOURCE, SPI_MOSI_AF);

    /*!< SD_SPI Config */
    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;

    SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;

    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;   // 48/4 = 12Mhz

    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
    SPI_InitStructure.SPI_CRCPolynomial = 7;
    SPI_Init(DEV_SPI, &SPI_InitStructure);

    SPI_RxFIFOThresholdConfig(DEV_SPI, SPI_RxFIFOThreshold_QF);

    SPI_Cmd(DEV_SPI, ENABLE);

    SPI_CS_HIGH;    //片选拉高
}

void _RELEASE_SPI_CLK_LOW(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;

    /*!< SPI_CS_GPIO, SPI_MOSI_GPIO, SPI_MISO_GPIO,
         and SPI_SCK_GPIO Periph clock enable */
    RCC_AHBPeriphClockCmd(SPI_MOSI_GPIO_CLK | SPI_MISO_GPIO_CLK |
                          SPI_SCK_GPIO_CLK, ENABLE);

    /*!< Configure SPI pins: SCK */
    GPIO_InitStructure.GPIO_Pin = SPI_SCK_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
    GPIO_Init(SPI_SCK_GPIO_PORT, &GPIO_InitStructure);

}

void _ASSERT_SPI_CLK_LOW(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;

    /*!< SPI_CS_GPIO, SPI_MOSI_GPIO, SPI_MISO_GPIO,
         and SPI_SCK_GPIO Periph clock enable */
    RCC_AHBPeriphClockCmd(SPI_MOSI_GPIO_CLK | SPI_MISO_GPIO_CLK |
                          SPI_SCK_GPIO_CLK, ENABLE);

    /*!< Configure SPI pins: SCK */
    GPIO_InitStructure.GPIO_Pin = SPI_SCK_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
    GPIO_Init(SPI_SCK_GPIO_PORT, &GPIO_InitStructure);

    GPIO_ResetBits(SPI_SCK_GPIO_PORT,SPI_SCK_PIN);

}


/**
  * @brief  DEV CE
  * @param  None
  * @retval None
  */
void DEV_CE_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_AHBPeriphClockCmd(DEV_CE_CLK, ENABLE);

    GPIO_InitStructure.GPIO_Pin = DEV_CE_PIN ;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_Init(DEV_CE_GPIO_PORT, &GPIO_InitStructure);
#ifdef HW_V1
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);

    GPIO_InitStructure.GPIO_Pin = DEV_TRX_PIN ;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_Init(GPIOC, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = DEV_WKUP_PIN ;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_Init(GPIOC, &GPIO_InitStructure);

#endif

}


/**
  * @brief  INT1_EXTI_Config Configure  as external interrupt
  * @param  None
  * @retval None
  */
void INT1_EXTI_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    EXTI_InitTypeDef EXTI_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
    /* Enable GPIOB clock */
    RCC_AHBPeriphClockCmd(DEV_IRQ1_CLK, ENABLE);

    GPIO_InitStructure.GPIO_Pin = DEV_IRQ1_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;

    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(DEV_IRQ1_GPIO_PORT, &GPIO_InitStructure);

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

    SYSCFG_EXTILineConfig(DEV_EXTI_PortSource_1, DEV_EXTI_PinSource_1);

    EXTI_InitStructure.EXTI_Line = DEV_EXTI_Line_1 ;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);

    NVIC_InitStructure.NVIC_IRQChannel = DEV_IRQn_1;
    NVIC_InitStructure.NVIC_IRQChannelPriority = 0x00;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}


/**
  * @brief  INT2_EXTI_Config Configure  as external interrupt
  * @param  None
  * @retval None
  */
void INT2_EXTI_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    EXTI_InitTypeDef EXTI_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    /* Enable GPIOB clock */
    RCC_AHBPeriphClockCmd(DEV_IRQ2_CLK, ENABLE);

    GPIO_InitStructure.GPIO_Pin = DEV_IRQ2_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;

    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(DEV_IRQ2_GPIO_PORT, &GPIO_InitStructure);

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

    SYSCFG_EXTILineConfig(DEV_EXTI_PortSource_2, DEV_EXTI_PinSource_2);

    EXTI_InitStructure.EXTI_Line = DEV_EXTI_Line_2 ;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    if(IRQ_MODE){
        EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;   //上升沿触发
    } else {
        EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;   //下降沿触发
    }
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);

    NVIC_InitStructure.NVIC_IRQChannel = DEV_IRQn_2;
    NVIC_InitStructure.NVIC_IRQChannelPriority = 0x00;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}


void PIN_MUX_Config(u8 IOMUX)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);

    switch(IOMUX)
    {
        case 0:
            GPIO_InitStructure.GPIO_Pin = DEV_DIO_CLK_PIN;      // dataclk
            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
            GPIO_Init(DEV_DIO_CLK_GPIO_PORT, &GPIO_InitStructure);

            GPIO_InitStructure.GPIO_Pin = DEV_MFOUT_PIN;    // rxdata
            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
            GPIO_Init(DEV_MFOUT_GPIO_PORT, &GPIO_InitStructure);

            RCC_AHBPeriphClockCmd(DEV_MFIN_CLK, ENABLE);
            GPIO_InitStructure.GPIO_Pin = DEV_MFIN_PIN;
            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
            GPIO_Init(DEV_MFIN_GPIO_PORT, &GPIO_InitStructure);
            break;

        case 1:
            GPIO_InitStructure.GPIO_Pin = DEV_DIO_CLK_PIN;
            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
            GPIO_Init(DEV_DIO_CLK_GPIO_PORT, &GPIO_InitStructure);

            GPIO_InitStructure.GPIO_Pin = DEV_MFOUT_PIN;
            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
            GPIO_Init(DEV_MFOUT_GPIO_PORT, &GPIO_InitStructure);

            RCC_AHBPeriphClockCmd(DEV_MFIN_CLK, ENABLE);
            GPIO_InitStructure.GPIO_Pin = DEV_MFIN_PIN;
            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
            GPIO_Init(DEV_MFIN_GPIO_PORT, &GPIO_InitStructure);
            break;

        case 2:
            GPIO_InitStructure.GPIO_Pin = DEV_DIO_CLK_PIN;
            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
            GPIO_Init(DEV_DIO_CLK_GPIO_PORT, &GPIO_InitStructure);

            GPIO_InitStructure.GPIO_Pin = DEV_MFOUT_PIN;
            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
            GPIO_Init(DEV_MFOUT_GPIO_PORT, &GPIO_InitStructure);

            RCC_AHBPeriphClockCmd(DEV_MFIN_CLK, ENABLE);
            GPIO_InitStructure.GPIO_Pin = DEV_MFIN_PIN;
            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
            GPIO_Init(DEV_MFIN_GPIO_PORT, &GPIO_InitStructure);
            break;

        default:
            break;
    }
}




// 将系统时钟24分频，计数频率为48MHz/24 = 2MHz,则一个计数时间为0.5us.记满1000个数的时间为0.5ms,这就是TIM3的定时周期


// 将系统时钟24分频，计数频率为48MHz/48 = 1MHz,则一个计数时间为1us.记满1000个数的时间为1ms,这就是TIM3的定时周期

volatile uint32_t tim14_cnt_05ms = 0;
extern volatile uint8_t pn9_rx_timeout;
u8 set_bit = 1;
u8 bit_cmp = 1;

// 将系统时钟24分频，计数频率为48MHz/48000 = 1KHz,则一个计数时间为1ms.记满1000个数的时间为1ms,这就是TIM3的定时周期



void EXTIO_IRQEN(u8 irq_en)
{
    if(!irq_en)
    {
        TIM_Cmd(TIM15, DISABLE);
        NVIC->ICER[0] |= (uint32_t)0x01 << (EXTI0_1_IRQn & (uint8_t)0x1F);
        NVIC->ICER[0] |= (uint32_t)0x01 << (TIM15_IRQn & (uint8_t)0x1F);
        NVIC->ICER[0] |= (uint32_t)0x01 << (TIM17_IRQn & (uint8_t)0x1F);
        EXTI->IMR &= ~(DEV_EXTI_Line_2|DEV_EXTI_Line_1);
    }
    else
    {
        TIM_Cmd(TIM15, ENABLE);
        NVIC->ISER[0] |= (uint32_t)0x01 << (EXTI0_1_IRQn & (uint8_t)0x1F);
        NVIC->ISER[0] |= (uint32_t)0x01 << (TIM15_IRQn & (uint8_t)0x1F);
        NVIC->ISER[0] |= (uint32_t)0x01 << (TIM17_IRQn & (uint8_t)0x1F);
        EXTI->IMR |= (DEV_EXTI_Line_2|DEV_EXTI_Line_1);
    }
}


/**
  * @brief  INT_EXTI_Config  Configure as external interrupt
  * @param  None
  * @retval None
  */
void INT_EXTI_Config(void)           //作为IRQ 的中断
{

    INT2_EXTI_Config();

}


void EXTI0_1_IRQHandler(void)
{

    /* wkup interrupt */

    if(EXTI_GetITStatus(DEV_EXTI_Line_1) == SET)
    {
        /* user handle sudo */

        Irq1_Delay_Cnt = 6;  // 4*2 = 8ms

        EXTI_ClearITPendingBit(DEV_EXTI_Line_1);    // clean irq flag
    }
    /* data interrupt */
    if(EXTI_GetITStatus(DEV_EXTI_Line_2) == SET)
    {

        irq_flag_io =1;
        EXTI_ClearITPendingBit(DEV_EXTI_Line_2);      // clean irq flag
    }

}


u8 SPI_ReadWriteByte(u8 byte)
{
    while(SPI_I2S_GetFlagStatus(DEV_SPI, SPI_I2S_FLAG_TXE) == RESET);

    SPI_SendData8(DEV_SPI, byte);

    while(SPI_I2S_GetFlagStatus(DEV_SPI, SPI_I2S_FLAG_RXNE) == RESET);

    return SPI_ReceiveData8(DEV_SPI);
}


u8 DEV_ReadSR(u8 sr)
{
    u8 byte = 0;
    SPI_CS_LOW;                            //使能器件


    SPI_ReadWriteByte(sr);          //发送读取状态寄存器命令
    byte = SPI_ReadWriteByte(0Xff);        //读取一个字节

    SPI_CS_HIGH;                           //取消片选
    return byte;
}


void DEV_WriteSR(u8 sr, u8 value)
{
    SPI_CS_LOW;
    //使能器件

    SPI_ReadWriteByte(sr);                   //发送读取状态寄存器命令
    SPI_ReadWriteByte(value);

    SPI_CS_HIGH;                           //取消片选
}

void DEV_SPI_Write(u8 WriteAddr, u8* pBuffer, u32 NumByteToRead)
{
    u16 i;
    SPI_CS_LOW;


    SPI_ReadWriteByte(WriteAddr);   //最高位：1表示写,0表示读
    for(i = 0; i < NumByteToRead; i++)
    {
        SPI_ReadWriteByte(pBuffer[i]);         //循环写数
    }

    SPI_CS_HIGH;
}


void DEV_SPI_Read(u8 ReadAddr, u8* pBuffer, u32 NumByteToRead)
{
    u16 i;
    SPI_CS_LOW;


    SPI_ReadWriteByte(ReadAddr);
    for(i = 0; i < NumByteToRead; i++)
    {
        pBuffer[i] = SPI_ReadWriteByte(0XFF);   //循环读数
    }

    SPI_CS_HIGH;
}

volatile uint32_t spi_err = 0;
void SPI_Test(u8 sr, u32 cnt)
{
    volatile    int i;
    volatile    int j;

    char test[4] = {0x5a, 0xa5, 0xff, 0x00};
    for(j = 0; j < cnt; j++)
    {
        for(i = 0; i < 4; i++)
        {
            DEV_WriteSR(sr, test[i]);
            if(DEV_ReadSR(sr) != test[i])
            {
                spi_err++;
                printf("temp = %x \r\n", DEV_ReadSR(sr));
            }

        }
    }
}

//endfile

