You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
260 lines
7.4 KiB
260 lines
7.4 KiB
#include "bsp_spi_soft.h"
|
|
#include "elog.h"
|
|
// #include "delay.h"
|
|
|
|
#define DELAY_TIME 1 // 10微秒
|
|
|
|
void SPI_Init(const SPI_SOFT_TypeDef *pSoftSPI)
|
|
{
|
|
GPIO_InitTypeDef GPIO_InitStructure;
|
|
|
|
__HAL_RCC_GPIOF_CLK_ENABLE(); // 使能GPIO F 时钟
|
|
|
|
// //CS引脚初始化
|
|
GPIO_InitStructure.Pin = pSoftSPI->cs_pin;
|
|
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; // 推挽输出
|
|
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW;
|
|
HAL_GPIO_Init(pSoftSPI->cs_port, &GPIO_InitStructure);
|
|
|
|
// SCK和MOSI引脚初始化
|
|
GPIO_InitStructure.Pin = pSoftSPI->sclk_pin;
|
|
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; // 推挽输出
|
|
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
|
|
HAL_GPIO_Init(pSoftSPI->sclk_port, &GPIO_InitStructure);
|
|
|
|
// MISO引脚初始化
|
|
GPIO_InitStructure.Pin = pSoftSPI->miso_pin;
|
|
// GPIO_InitStructure.Mode = GPIO_Mode_IPU ; //浮空输入
|
|
GPIO_InitStructure.Mode = GPIO_MODE_INPUT; // 浮空输入
|
|
GPIO_InitStructure.Pull = GPIO_PULLUP;
|
|
HAL_GPIO_Init(pSoftSPI->miso_pin, &GPIO_InitStructure);
|
|
|
|
// MOSI引脚初始化
|
|
GPIO_InitStructure.Pin = pSoftSPI->mosi_pin;
|
|
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; // 推挽输出
|
|
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
|
|
HAL_GPIO_Init(pSoftSPI->mosi_port, &GPIO_InitStructure);
|
|
|
|
// 初始化 0 0
|
|
HAL_GPIO_WritePin(pSoftSPI->sclk_port, pSoftSPI->sclk_pin, GPIO_PIN_SET); // 极性0 初始化需要拉高
|
|
HAL_GPIO_WritePin(pSoftSPI->cs_port, pSoftSPI->cs_pin, GPIO_PIN_SET);
|
|
// HAL_GPIO_WritePin(pSoftSPI->mosi_port, pSoftSPI->mosi_pin, GPIO_PIN_SET);
|
|
}
|
|
|
|
/**
|
|
* @brief Set SDIO as the input mode
|
|
*/
|
|
void SDO_IN(const SPI_SOFT_TypeDef *pSoftSPI)
|
|
{
|
|
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
|
GPIO_InitStruct.Pin = pSoftSPI->miso_pin;
|
|
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
|
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
|
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
|
HAL_GPIO_Init(pSoftSPI->miso_pin, &GPIO_InitStruct);
|
|
}
|
|
/**
|
|
* @brief Set SDIO as the output mode
|
|
*/
|
|
void SDO_OUT(const SPI_SOFT_TypeDef *pSoftSPI)
|
|
{
|
|
GPIO_InitTypeDef GPIO_InitStruct;
|
|
GPIO_InitStruct.Pin = pSoftSPI->miso_pin;
|
|
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
|
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
|
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
|
HAL_GPIO_Init(pSoftSPI->miso_pin, &GPIO_InitStruct);
|
|
}
|
|
/**
|
|
* @brief Send one byte by SPI bus
|
|
* @def 先拉低,然后发送,在拉高有个跳变沿(从机检测到跳变),然后可以进入接收
|
|
* @param u8_writedata
|
|
*/
|
|
void SPI_Write_OneByte(const SPI_SOFT_TypeDef *pSoftSPI, uint8_t u8_writedata)
|
|
{
|
|
uint8_t i;
|
|
for (i = 0; i < 8; i++)
|
|
{
|
|
HAL_GPIO_WritePin(pSoftSPI->sclk_port, pSoftSPI->sclk_pin, GPIO_PIN_RESET); // SCK Low
|
|
__NOP();
|
|
if (u8_writedata & 0x80)
|
|
// SDI_H;
|
|
HAL_GPIO_WritePin(pSoftSPI->mosi_port, pSoftSPI->mosi_pin, GPIO_PIN_SET);
|
|
else
|
|
// SDI_L;
|
|
HAL_GPIO_WritePin(pSoftSPI->mosi_port, pSoftSPI->mosi_pin, GPIO_PIN_RESET);
|
|
// SCLK_H;
|
|
HAL_GPIO_WritePin(pSoftSPI->sclk_port, pSoftSPI->sclk_pin, GPIO_PIN_SET);
|
|
__NOP();
|
|
u8_writedata <<= 1;
|
|
// SCLK_L;
|
|
// HAL_GPIO_WritePin(pSoftSPI->sclk_port, pSoftSPI->sclk_pin, GPIO_PIN_RESET);
|
|
}
|
|
}
|
|
/**
|
|
* @brief Read one byte by SPI bus
|
|
*
|
|
* @return temp
|
|
*/
|
|
uint8_t SPI_Read_OneByte(const SPI_SOFT_TypeDef *pSoftSPI)
|
|
{
|
|
uint8_t i;
|
|
uint8_t temp = 0;
|
|
for (i = 0; i < 8; i++)
|
|
{
|
|
temp <<= 1;
|
|
// SCLK_H;
|
|
HAL_GPIO_WritePin(pSoftSPI->sclk_port, pSoftSPI->sclk_pin, GPIO_PIN_SET); // SCK High
|
|
__NOP();
|
|
// if (SDO_R)
|
|
if (HAL_GPIO_ReadPin(pSoftSPI->miso_port, pSoftSPI->miso_pin) == GPIO_PIN_SET) // miso read
|
|
temp |= 0x01;
|
|
// SCLK_L;
|
|
__NOP();
|
|
HAL_GPIO_WritePin(pSoftSPI->sclk_port, pSoftSPI->sclk_pin, GPIO_PIN_RESET);
|
|
HAL_GPIO_WritePin(pSoftSPI->sclk_port, pSoftSPI->sclk_pin, GPIO_PIN_SET); // SCK High
|
|
}
|
|
return temp;
|
|
}
|
|
|
|
// 同步传输数据,比如在时钟的上升沿是写数据,那么在时钟的下降沿就是读数据
|
|
uint8_t SPI_ReadWriteByte(const SPI_SOFT_TypeDef *pSoftSPI, uint8_t TxData)
|
|
{
|
|
int i = 0;
|
|
uint8_t RxData = 0;
|
|
|
|
HAL_GPIO_WritePin(pSoftSPI->sclk_port, pSoftSPI->sclk_pin, GPIO_PIN_RESET); // sclk low
|
|
for (i = 7; i >= 0; i--)
|
|
{
|
|
// W25QXX_SCK_L(); // 时钟拉低 ,发送1bit
|
|
HAL_GPIO_WritePin(pSoftSPI->sclk_port, pSoftSPI->sclk_pin, GPIO_PIN_RESET); // SCK Low
|
|
__NOP();
|
|
// 数据发送
|
|
if (TxData & (1 << i))
|
|
{
|
|
HAL_GPIO_WritePin(pSoftSPI->mosi_port, pSoftSPI->mosi_pin, GPIO_PIN_SET); // MOSI H
|
|
}
|
|
else
|
|
{
|
|
HAL_GPIO_WritePin(pSoftSPI->mosi_port, pSoftSPI->mosi_pin, GPIO_PIN_RESET); // MOSI L
|
|
}
|
|
__NOP();
|
|
|
|
// W25QXX_SCK_H(); // 拉高时钟读 1bit
|
|
HAL_GPIO_WritePin(pSoftSPI->sclk_port, pSoftSPI->sclk_pin, GPIO_PIN_SET);
|
|
__NOP();
|
|
|
|
// 数据接收
|
|
RxData <<= 1;
|
|
if (HAL_GPIO_ReadPin(pSoftSPI->miso_port, pSoftSPI->miso_pin) == GPIO_PIN_SET)
|
|
RxData |= 0x01;
|
|
|
|
__NOP();
|
|
}
|
|
|
|
HAL_GPIO_WritePin(pSoftSPI->sclk_port, pSoftSPI->sclk_pin, GPIO_PIN_RESET); // SCK LOw
|
|
return RxData;
|
|
}
|
|
|
|
void SPI_Read_Write_buf(const SPI_SOFT_TypeDef *pSoftSPI, uint8_t* txBuf,uint8_t* rxBuf,uint16_t len)
|
|
{
|
|
int i = 0;
|
|
uint8_t RxData = 0;
|
|
|
|
for ( size_t i = 0; i < len; i++ )
|
|
{
|
|
if (i==0) {
|
|
SPI_Write_OneByte(pSoftSPI, *txBuf);
|
|
txBuf++;
|
|
}
|
|
else{
|
|
*rxBuf = SPI_ReadWriteByte(pSoftSPI, *txBuf);
|
|
txBuf++;
|
|
rxBuf++;
|
|
}
|
|
}
|
|
// TODO TimeOut
|
|
return ;
|
|
}
|
|
|
|
/**
|
|
* @brief Write a register
|
|
*
|
|
* @param d: {D2, D1, D0} addr uint32_T
|
|
* @return SUCCESS
|
|
*/
|
|
uint8_t WriteReg(const SPI_SOFT_TypeDef *pSoftSPI, uint32_t d)
|
|
{
|
|
uint8_t tx[3] = {(d >> 16) & 0xff, (d >> 8) & 0xff, d & 0xff};
|
|
SDO_OUT(pSoftSPI);
|
|
// CS_L;
|
|
HAL_GPIO_WritePin(pSoftSPI->cs_port, pSoftSPI->cs_pin, GPIO_PIN_RESET);
|
|
SPI_Write_OneByte(pSoftSPI, tx[0]);
|
|
SPI_Write_OneByte(pSoftSPI, tx[1]);
|
|
SPI_Write_OneByte(pSoftSPI, tx[2]);
|
|
// CS_H;
|
|
HAL_GPIO_WritePin(pSoftSPI->cs_port, pSoftSPI->cs_pin, GPIO_PIN_SET);
|
|
// SDI_L;
|
|
HAL_GPIO_WritePin(pSoftSPI->mosi_port, pSoftSPI->mosi_pin, GPIO_PIN_RESET);
|
|
return SUCCESS;
|
|
}
|
|
|
|
/**
|
|
* @brief Read a register
|
|
* @param d: {D2, D1, D0} addr uint32_t
|
|
* @return data: The data be read in a register
|
|
*/
|
|
uint8_t ReadReg(const SPI_SOFT_TypeDef *pSoftSPI, uint32_t d)
|
|
{
|
|
uint8_t tx[3] = {(d >> 16) & 0xff, (d >> 8) & 0xff, d & 0xff};
|
|
uint8_t data;
|
|
// tx[0] = tx[0] | RF_DATA_READ_BIT;
|
|
SDO_OUT(pSoftSPI);
|
|
// CS_L;
|
|
HAL_GPIO_WritePin(pSoftSPI->cs_port, pSoftSPI->cs_pin, GPIO_PIN_RESET);
|
|
SPI_Write_OneByte(pSoftSPI, tx[0]);
|
|
SPI_Write_OneByte(pSoftSPI, tx[1]);
|
|
|
|
data = SPI_Read_OneByte(pSoftSPI);
|
|
// CS_H;
|
|
HAL_GPIO_WritePin(pSoftSPI->cs_port, pSoftSPI->cs_pin, GPIO_PIN_SET);
|
|
SDO_OUT(pSoftSPI);
|
|
// SDI_L;
|
|
HAL_GPIO_WritePin(pSoftSPI->mosi_port, pSoftSPI->mosi_pin, GPIO_PIN_RESET);
|
|
|
|
log_i(" ReadReg ... %02X ", data);
|
|
return data;
|
|
}
|
|
|
|
// test ok
|
|
uint32_t SPI_FLASH_ReadDeviceID(const SPI_SOFT_TypeDef *pSoftSPI)
|
|
{
|
|
uint32_t Temp = 0;
|
|
uint8_t readout = 0;
|
|
// CS_L;
|
|
HAL_GPIO_WritePin(pSoftSPI->cs_port, pSoftSPI->cs_pin, GPIO_PIN_RESET);
|
|
|
|
log_i(" SPI_FLASH_ReadDeviceID ... ");
|
|
// 发送4字节指令
|
|
// readout = SPI_ReadWriteByte(pSoftSPI,0x9F);
|
|
SPI_Write_OneByte(pSoftSPI, 0x9F);
|
|
Temp |= (readout << 24);
|
|
|
|
readout = SPI_ReadWriteByte(pSoftSPI, 0xFF);
|
|
|
|
// readout = SPI_ReadWriteByte(pSoftSPI,0xFF);
|
|
Temp |= (readout << 16);
|
|
readout = SPI_ReadWriteByte(pSoftSPI, 0xFF);
|
|
// readout = SPI_ReadWriteByte(pSoftSPI,0xFF);
|
|
Temp |= (readout << 8);
|
|
readout = SPI_ReadWriteByte(pSoftSPI, 0xFF);
|
|
// readout = SPI_ReadWriteByte(pSoftSPI,0xFF);
|
|
Temp |= (readout);
|
|
|
|
log_i("rrrr: 0x%08X\n", Temp); // 0X00EF4019
|
|
// CS_H;
|
|
HAL_GPIO_WritePin(pSoftSPI->cs_port, pSoftSPI->cs_pin, GPIO_PIN_SET);
|
|
|
|
return Temp;
|
|
}
|
|
|
|
|