#ifndef __BSP_SPI_SOFT_H
#define __BSP_SPI_SOFT_H
#include "stm32f4xx_hal.h"
#include "main.h"
// #include "sys.h"

#define CS_GPIO_PORT GPIOF
#define CS_PIN	 GPIO_PIN_6
#define SCK_GPIO_PORT GPIOF
#define SCK_PIN	 GPIO_PIN_7
#define MISO_GPIO_PORT GPIOF
#define MISO_PIN	 GPIO_PIN_8
#define MOSI_GPIO_PORT GPIOF
#define MOSI_PIN	 GPIO_PIN_9


// FPF6    ------> SPI5_CS
// PF7     ------> SPI5_SCK
// PF8     ------> SPI5_MISO
// PF9     ------> SPI5_MOSI


typedef enum  {
  SPI_OK           = 0x00,    //IIC工作正常
  SPI_WAIT_ACK_ERR = 0x01,    //slave设备返回ACK错误
  SPI_WRITE_ERR    = 0x02,    //向slave设备写入错误
  SPI_READ_ERR     = 0x04     //从slave设备读取错误
} SPI_STATUS;

typedef struct
{
    GPIO_TypeDef	*cs_port;   	
    uint16_t			cs_pin;	
    GPIO_TypeDef	*sclk_port;		 
    uint16_t			sclk_pin;			
    GPIO_TypeDef	*miso_port;   	
    uint16_t			miso_pin;	
    GPIO_TypeDef	*mosi_port;   	
    uint16_t			mosi_pin;			 


    uint8_t			  sda_pin_num;   	//定义延时，以适应不同器件对速率的不同要求,具体值要在调试中确定
    uint8_t				addr;        	//器件地址
    uint32_t			delaytick;   	//定义延时，以适应不同器件对速率的不同要求,具体值要在调试中确定
    uint8_t  CPOL;    //时钟极性，为0：空闲状态时，SCK保持低电平；  1： 表示在空闲状态时，SCK保持高电平。
    uint8_t  CPHA;    // 时钟相位， 0：从第一个时钟边沿开始； 1：第二个时钟边沿开始。
  uint16_t period ;   //确定速度为大于0K小于等于400K的整数，默认为100K,>period=500/speed speed时钟频率
}SPI_SOFT_TypeDef;

 

#define CS_H HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_SET)
#define CS_L HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_RESET)
#define SCLK_H HAL_GPIO_WritePin(GPIOC, GPIO_PIN_4, GPIO_PIN_SET)
#define SCLK_L HAL_GPIO_WritePin(GPIOC, GPIO_PIN_4, GPIO_PIN_RESET)
#define SDI_H HAL_GPIO_WritePin(GPIOC, GPIO_PIN_1, GPIO_PIN_SET)
#define SDI_L HAL_GPIO_WritePin(GPIOC, GPIO_PIN_1, GPIO_PIN_RESET)
#define SDO_R HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_1)

#define SUCCESS 0
#define FAILURE 1

void SPI_Init(const SPI_SOFT_TypeDef *pSoftSPI);  
uint8_t WriteReg(const SPI_SOFT_TypeDef *pSoftSPI, uint32_t d);
uint8_t ReadReg(const SPI_SOFT_TypeDef *pSoftSPI, uint32_t d);  
void SPI_Write_OneByte(const SPI_SOFT_TypeDef *pSoftSPI, uint8_t u8_writedata);
uint8_t SPI_Read_OneByte(const SPI_SOFT_TypeDef *pSoftSPI);
uint8_t SPI_ReadWriteByte(const SPI_SOFT_TypeDef *pSoftSPI, uint8_t TxData);

uint32_t SPI_FLASH_ReadDeviceID( const SPI_SOFT_TypeDef *pSoftSPI);
#endif


/*
时序
CPOL  CPHA
 0      0    00    第一个  上升沿
 0      1    01   第一个  下降沿
 1      0    10   第二个  下降沿
 1      1    11   第二个  上升沿

00 常用， 前置SCL拉低， 过程  SDA 输出， SCLK 拉高 延时  拉低

00 ：
//                 T____
//           ______/    \______

01
//                  ____T
//           ______/    \______


10 ：
//      *    ____T        _____
//               \_______/

11
//      *    ____        T_____
//               \_______/


00
空闲状态：片选信号SS为高，SCK输出低电平。
开始信号：片选信号SS变低，SCK输出低电平。
结束信号：片选信号SS变高，SCK输出低电平。
读取：SCK由低变高之后，读取MISO引脚信号。
写入：SCK输出低电平，MOSI引脚输出相应的电平，然后SCK输出高电平。

MISO：Master input slave output 主机输入，从机输出（数据来自从机）；

MOSI：Master output slave input 主机输出，从机输入（数据来自主机）；

MISO也可以是SIMO，DOUT，DO，SDO或SO（在主机端）;

MOSI也可以是SOMI，DIN，DI，SDI或SI（在主机端）;


SPI_SOFT_TypeDef sSPI ={
    GPIOF, GPIO_PIN_6,GPIOF, GPIO_PIN_7,GPIOF, GPIO_PIN_8,GPIOF, GPIO_PIN_9,
    6,0,1,
} ;       
SPI_Init(&sSPI);

  uint8_t txData[4] = {0x9F, 0x00, 0x00, 0x00}; 
  uint32_t hhhh =2667577344;
  uint8_t rxData[4] = {0};   //  
  uint8_t  rrr;

//   rrr = SPI_ReadWriteByte(&sSPI, txData[0]);
//     log_i("rrrr: 0x%02X\n", rrr);     // 19
//     delay_us(1);
//   rrr = SPI_ReadWriteByte(&sSPI, 0xFF);
//     log_i("rrrr: 0x%02X\n", rrr);     // 19
//     delay_us(1);
//   rrr = SPI_ReadWriteByte(&sSPI, 0xFF);
//     log_i("rrrr: 0x%02X\n", rrr);     // 19
//     delay_us(1);
//   rrr = SPI_ReadWriteByte(&sSPI, 0xFF);
//     log_i("rrrr: 0x%02X\n", rrr);     // 19
//     delay_us(1);
hhhh = SPI_FLASH_ReadDeviceID(&sSPI);

*/

