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