不含stm32 底层的代码
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.
 
 
MyStm32Code/bsp/Src/bsp_spi_soft.c

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;
}