/**
  ************************************* Copyright ****************************** 
  *
  *                 Copyright (C), 2012-2016, Radioway Tech. Co., Ltd.
  *                            All Rights Reserved
  *
  *    
  * FileName   : spi.c
  * Version    : v1.0
  * Author     : Heb
  * Date       : 2024-06-24
  * Description: 
  * Function List: 
  	1. ....
          <version>: 
     <modify staff>: 
             <data>: 
      <description>: 
  	2. ...
  ******************************************************************************
 */

#include "board.h"

void spi_init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;
    SPI_InitTypeDef  SPI_InitStruct;

    // 使能GPIO、SPI时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
    
    // 初始化SPI1
    SPI_StructInit(&SPI_InitStruct);
    SPI_InitStruct.SPI_Mode      = SPI_Mode_Master;
    SPI_InitStruct.SPI_DataSize  = SPI_DataSize_8b;
    SPI_InitStruct.SPI_DataWidth = 8;
    SPI_InitStruct.SPI_CPOL      = SPI_CPOL_Low;
    SPI_InitStruct.SPI_CPHA      = SPI_CPHA_1Edge;
    SPI_InitStruct.SPI_NSS       = SPI_NSS_Soft;
    SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
    SPI_InitStruct.SPI_FirstBit  = SPI_FirstBit_MSB;
    SPI_Init(SPI1, &SPI_InitStruct);

    SPI_BiDirectionalLineConfig(SPI1, SPI_Direction_Rx);
    SPI_BiDirectionalLineConfig(SPI1, SPI_Direction_Tx);

    // 初始化GPIO
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource4,  GPIO_AF_0);
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource5,  GPIO_AF_0);
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource6,  GPIO_AF_6);

    GPIO_StructInit(&GPIO_InitStruct);
    GPIO_InitStruct.GPIO_Pin   =  GPIO_Pin_0;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_High;
    GPIO_InitStruct.GPIO_Mode  = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOB, &GPIO_InitStruct);

    GPIO_StructInit(&GPIO_InitStruct);
    GPIO_InitStruct.GPIO_Pin   =  GPIO_Pin_5 | GPIO_Pin_6;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_High;
    GPIO_InitStruct.GPIO_Mode  = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOB, &GPIO_InitStruct);

    GPIO_StructInit(&GPIO_InitStruct);
    GPIO_InitStruct.GPIO_Pin   = GPIO_Pin_4;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_High;
    GPIO_InitStruct.GPIO_Mode  = GPIO_Mode_IPU;
    GPIO_Init(GPIOB, &GPIO_InitStruct);

    SPI_Cmd(SPI1, ENABLE);
}

uint8_t spi_inout(uint8_t out_data)
{
    uint16_t time_out = 0;
    uint32_t in_data = 0;
    
    while (RESET == SPI_GetFlagStatus(SPI1, SPI_FLAG_TXEPT))
    {
        time_out++;
        if(time_out > 251)
            return 0;
    }
    
    SPI_SendData(SPI1, out_data);

    while (RESET == SPI_GetFlagStatus(SPI1, SPI_FLAG_RXAVL))
    {
        time_out++;
        if(time_out > 251)
            return 0;
    }

    in_data = SPI_ReceiveData(SPI1);
    
    return (uint8_t)in_data;
}
