From a7079b7124ec21f7a611a68d69c5d5465a543041 Mon Sep 17 00:00:00 2001 From: esea_info Date: Wed, 25 Oct 2023 11:04:12 +0800 Subject: [PATCH] spi_helper --- bsp/Inc/bsp_spi.h | 95 ++++++++++++++ bsp/Inc/bsp_spi_soft.h | 159 +++++++++++++--------- bsp/Src/bsp_spi.c | 151 +++++++++++++++++++++ bsp/Src/bsp_spi_soft.c | 291 +++++++++++++++++++++++++---------------- 4 files changed, 519 insertions(+), 177 deletions(-) create mode 100644 bsp/Inc/bsp_spi.h create mode 100644 bsp/Src/bsp_spi.c diff --git a/bsp/Inc/bsp_spi.h b/bsp/Inc/bsp_spi.h new file mode 100644 index 0000000..cdc120a --- /dev/null +++ b/bsp/Inc/bsp_spi.h @@ -0,0 +1,95 @@ +#ifndef __BSP_SPI_H +#define __BSP_SPI_H + +#include "stm32f4xx_hal.h" +#include "main.h" +// #include "sys.h" + +typedef enum +{ + SPI_Trans_Polling = 0x00U, + SPI_Trans_IT = 0x01U, + SPI_Trans_DMA = 0x02U, +} SPI_Transmode_TypeDef; + +typedef enum +{ + SPI_WORKMODE_RX_TX = 0x00U, + SPI_WORKMODE_TX = 0x01U, + SPI_WORKMODE_RX = 0x02U, +} SPI_WORKMODE_RX_TX_TypeDef; + + +typedef void ( *enable_func_gpio) (void); +typedef int ( *callback_fun) (void *obj, void *buf, uint16_t size); + +typedef struct +{ + SPI_HandleTypeDef *hspi; + + volatile SPI_WORKMODE_RX_TX_TypeDef rx_tx; + + SPI_Transmode_TypeDef trans_mode; /* 0 :polling, 1: IT 2: DMA*/ + SPI_Transmode_TypeDef rcv_mode; /* 0 :polling, 1: IT 2: DMA*/ + + // Record_Trans_Rcv_TypeDef *trans_record; + // Record_Trans_Rcv_TypeDef *rcv_record; + + uint8_t *trans_buf; + uint16_t trans_size; + uint8_t *rcv_buf; + uint16_t rcv_size; + + volatile uint8_t transferring; + uint32_t timebase; + + // enable_func_gpio enable_trans_gpio; + // enable_func_gpio enable_trans_cplt_gpio; + + void * obj; + callback_fun callback; + + +}SPI_HELPER_TypeDef; + +extern SPI_HELPER_TypeDef *spihelper; + +SPI_HELPER_TypeDef * SPI_HELPER_Init( ); +void SPI_HELPER_Set_Huart(SPI_HELPER_TypeDef * spihelper, SPI_HELPER_TypeDef *hspi); + + +int SPI_HELPER_Setup_Trans_mode( SPI_HELPER_TypeDef * spihelper, uint8_t trans_mode ); +int SPI_HELPER_Setup_Rcv_mode( SPI_HELPER_TypeDef * spihelper, uint8_t rcv_mode ); + +int SPI_HELPER_Set_Rcv_Buf( SPI_HELPER_TypeDef * spihelper, uint8_t * buf, uint16_t size); +int SPI_HELPER_Set_Trans_Buf( SPI_HELPER_TypeDef * spihelper, uint8_t * buf, uint16_t size); + +int SPI_HELPER_Setup_WokMode_RX_TX( SPI_HELPER_TypeDef * spihelper, uint8_t rx_tx ); + +int SPI_HELPER_Set_Callback( SPI_HELPER_TypeDef * spihelper, void *obj, callback_fun func); + +int SPI_HELPER_Trans(SPI_HELPER_TypeDef * spihelper, uint8_t *buf, uint16_t size); +int SPI_HELPER_Trans_TxCplt_Callback( SPI_HELPER_TypeDef * spihelper ); + +int SPI_HELPER_Start_Rcv(SPI_HELPER_TypeDef * spihelper, uint8_t *buf, uint16_t size); +int SPI_HELPER_RCV_Cplt_Callback( SPI_HELPER_TypeDef * spihelper ); + +int SPI_HELPER_Start_Trans_Rcv(SPI_HELPER_TypeDef * spihelper, uint8_t *txbuf ,uint8_t *rxbuf, uint16_t size); +int SPI_HELPER_Trans_RCV_Cplt_Callback( SPI_HELPER_TypeDef * spihelper ); + +void SPI_HELPER_Test(void) ; +void SPI_HELPER_TransmitReceive(uint8_t* txData, uint8_t* rxData, uint16_t size) ; + +#endif + +/* +void HAL_SPI_IRQHandler(SPI_HandleTypeDef *hspi); +void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi); +void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi); +void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi); +void HAL_SPI_TxHalfCpltCallback(SPI_HandleTypeDef *hspi); +void HAL_SPI_RxHalfCpltCallback(SPI_HandleTypeDef *hspi); +void HAL_SPI_TxRxHalfCpltCallback(SPI_HandleTypeDef *hspi); +void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi); +void HAL_SPI_AbortCpltCallback(SPI_HandleTypeDef *hspi); +*/ \ No newline at end of file diff --git a/bsp/Inc/bsp_spi_soft.h b/bsp/Inc/bsp_spi_soft.h index efb1a4f..24dfd73 100644 --- a/bsp/Inc/bsp_spi_soft.h +++ b/bsp/Inc/bsp_spi_soft.h @@ -4,10 +4,20 @@ #include "main.h" // #include "sys.h" -// #define SCL_GPIO_PORT GPIOB -// #define SCL_PIN GPIO_PIN_6 -// #define SDA_GPIO_PORT GPIOB -// #define SDA_PIN GPIO_PIN_7 +#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 { @@ -19,17 +29,22 @@ typedef enum { typedef struct { - GPIO_TypeDef *sclk_port; - uint16_t sclk_pin; - GPIO_TypeDef *mosi_port; - uint16_t mosi_pin; - GPIO_TypeDef *miso_port; - uint16_t miso_pin; - GPIO_TypeDef *cs_port; - uint16_t cs_pin; - uint8_t sda_pin_num; //定义延时,以适应不同器件对速率的不同要求,具体值要在调试中确定 - uint8_t addr; //器件地址 - uint32_t delaytick; //定义延时,以适应不同器件对速率的不同要求,具体值要在调试中确定 + 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; @@ -46,70 +61,84 @@ typedef struct #define FAILURE 1 void SPI_Init(const SPI_SOFT_TypeDef *pSoftSPI); -uint8_t WriteReg(uint32_t d); -uint8_t ReadReg(uint32_t d); - +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 /* 时序 -// * @brief: I2C 开始,SCL为高电平的时候SDA产生一个下降沿信号 - -// _____ -// *SDA \_____________ -// * __________ -// *SCL \________ -// - - -// * @brief: I2C 停止,SCL为高电平的时候SDA产生一个上升沿信号 -// _______ -// *SDA __________/ -// * ____________ -// *SCL _____/ - +CPOL CPHA + 0 0 00 第一个 上升沿 + 0 1 01 第一个 下降沿 + 1 0 10 第二个 下降沿 + 1 1 11 第二个 上升沿 -// * @brief: I2C 响应 -// ____ -// *SCL ______/ \______ -// * ____ _____ -// *SDA \_______/ -// +00 常用, 前置SCL拉低, 过程 SDA 输出, SCLK 拉高 延时 拉低 -// * @brief: I2C 不响应 - -// ____ -// *SCL ______/ \______ -// * __________________ -// *SDA -// +00 : +// T____ +// ______/ \______ +01 +// ____T +// ______/ \______ - HAL_I2C_MspDeInit( &hi2c1 ); - uint8_t readout[256] = {0}; - uint8_t writein[1] = {0xFB}; - // SPI_Init( ); +10 : +// * ____T _____ +// \_______/ - // SPI_Write_Test( 0xA0, 0, writein, 1 ); - // HAL_Delay( 200 ); +11 +// * ____ T_____ +// \_______/ - // SPI_Read_Test( 0xA0, 0, readout, 1 ); - // log_i("iic test %02X .... ", *readout); +00 +空闲状态:片选信号SS为高,SCK输出低电平。 +开始信号:片选信号SS变低,SCK输出低电平。 +结束信号:片选信号SS变高,SCK输出低电平。 +读取:SCK由低变高之后,读取MISO引脚信号。 +写入:SCK输出低电平,MOSI引脚输出相应的电平,然后SCK输出高电平。 - SPI_SOFT_TypeDef sIIC = { - GPIOB, GPIO_PIN_6, GPIOB, GPIO_PIN_7, - 7,0xA0,1, - }; - SPI_Init( &sIIC ); - - SPI_Write_Test( &sIIC,0xA0, 0, writein, 1 ); - HAL_Delay( 200 ); +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; - SPI_Read_Test(&sIIC, 0xA0, 0, readout, 1 ); +// 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); - log_i("iic test %02X .... ", *readout); +*/ -*/ \ No newline at end of file diff --git a/bsp/Src/bsp_spi.c b/bsp/Src/bsp_spi.c new file mode 100644 index 0000000..0670484 --- /dev/null +++ b/bsp/Src/bsp_spi.c @@ -0,0 +1,151 @@ +#include "bsp_spi.h" +#include "elog.h" +// #include "delay.h" + +extern SPI_HandleTypeDef hspi5; +SPI_HandleTypeDef *testSPIHandle = &hspi5; + + +SPI_HELPER_TypeDef * SPI_HELPER_Init( ) +{ + SPI_HELPER_TypeDef *Handle = (SPI_HELPER_TypeDef *)malloc(sizeof(SPI_HELPER_TypeDef)); + if (Handle == NULL) + { + return NULL; + } + + Handle->hspi = NULL; + Handle->rx_tx = SPI_WORKMODE_RX_TX; + Handle->trans_mode = SPI_Trans_Polling; + Handle->rcv_mode = SPI_Trans_Polling; + + Handle->transferring = 0; + + + Handle->obj =NULL; + Handle->callback =NULL; + return Handle; +} + + +int SPI_HELPER_Setup_Trans_mode( SPI_HELPER_TypeDef * spihelper, uint8_t trans_mode ) +{ + spihelper->trans_mode =trans_mode; + spihelper->rcv_mode =trans_mode; + return 0; +} +int SPI_HELPER_Setup_Rcv_mode( SPI_HELPER_TypeDef * spihelper, uint8_t rcv_mode ) +{ + spihelper->rcv_mode =rcv_mode; + return 0; +} + +int SPI_HELPER_Setup_WokMode_RX_TX( SPI_HELPER_TypeDef * spihelper, uint8_t rx_tx ) +{ + spihelper->rx_tx =rx_tx; + return 0; +} + +int SPI_HELPER_Set_Rcv_Buf( SPI_HELPER_TypeDef * spihelper, uint8_t * buf, uint16_t size) +{ + spihelper->rcv_buf = buf; + spihelper->rcv_size = size; + return 0; +} +int SPI_HELPER_Set_Trans_Buf( SPI_HELPER_TypeDef * spihelper, uint8_t * buf, uint16_t size) +{ + spihelper->trans_buf = buf; + spihelper->trans_size = size; + return 0; +} + +int SPI_HELPER_Set_Callback( SPI_HELPER_TypeDef * spihelper, void *obj, callback_fun func) +{ + spihelper->obj = obj; + spihelper->callback = func; + return 0; +} + +void SPI_Test(void) +{ + uint8_t txData[4] = {0x9F, 0x00, 0x00, 0x00}; + uint8_t rxData[4] = {0}; // + SPI_TransmitReceive(txData, rxData, 4); + log_i("Manufacturer ID: 0x%02X\n", rxData[1]); // EF + log_i("Memory Type: 0x%02X\n", rxData[2]); // 40 + log_i("Capacity: 0x%02X\n", rxData[3]); // 19 +} + + +void SPI_TransmitReceive(uint8_t* txData, uint8_t* rxData, uint16_t size) +{ + HAL_GPIO_WritePin(SPI5_CS_GPIO_Port, SPI5_CS_Pin, GPIO_PIN_RESET); + HAL_SPI_TransmitReceive(testSPIHandle, txData, rxData, size, HAL_MAX_DELAY); + HAL_GPIO_WritePin(SPI5_CS_GPIO_Port, SPI5_CS_Pin, GPIO_PIN_SET); +} + +// void SPI_Init(const SPI_SOFT_TypeDef *pSoftSPI) +// { +// GPIO_InitTypeDef GPIO_InitStructure; +// __HAL_RCC_GPIOB_CLK_ENABLE(); // 使能GPIOB时钟 + +// // //PB6 SCL PB7初始化设置 +// // GPIO_Initure.Pin = pSoftIIC->scl_pin ; +// // GPIO_Initure.Mode = GPIO_MODE_OUTPUT_PP; // 推挽输出 +// // GPIO_Initure.Pull = GPIO_PULLUP; // 上拉 +// // GPIO_Initure.Speed = GPIO_SPEED_FAST; // 快速 +// // HAL_GPIO_Init( pSoftIIC->scl_port, &GPIO_Initure ); + +// // // SDA PB7 初始化设置 +// // GPIO_Initure.Pin = pSoftIIC->sda_pin; +// // HAL_GPIO_Init( pSoftIIC->sda_port, &GPIO_Initure ); + +// // GPIO_WRITE_PIN(pSoftIIC->sda_port, pSoftIIC->sda_pin, 1); +// // GPIO_WRITE_PIN(pSoftIIC->scl_port, pSoftIIC->scl_pin, 1); + + +// // RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); +// // GPIO_InitTypeDef GPIO_InitStructure; +// // GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //457引脚配置为推挽输出 +// // GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5| GPIO_Pin_7;//457引脚配置为推挽输出 +// // GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; +// // GPIO_Init(GPIOA, &GPIO_InitStructure); + +// // GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//pin6是MISO,对于STM32来说是输入,配置为上拉输入 +// // GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;//pin6是MISO,对于STM32来说是输入,配置为上拉输入 +// // GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; +// // GPIO_Init(GPIOA, &GPIO_InitStructure); + +// // //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); + +// // 初始化 +// HAL_GPIO_WritePin(pSoftSPI->mosi_port, pSoftSPI->mosi_pin, GPIO_PIN_RESET); +// HAL_GPIO_WritePin(pSoftSPI->cs_port, pSoftSPI->cs_pin, GPIO_PIN_SET); +// HAL_GPIO_WritePin(pSoftSPI->mosi_port, pSoftSPI->mosi_pin, GPIO_PIN_SET); +// } + + diff --git a/bsp/Src/bsp_spi_soft.c b/bsp/Src/bsp_spi_soft.c index 8701ae9..b9a44f8 100644 --- a/bsp/Src/bsp_spi_soft.c +++ b/bsp/Src/bsp_spi_soft.c @@ -1,99 +1,94 @@ #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_Initure; - - __HAL_RCC_GPIOB_CLK_ENABLE(); // 使能GPIOB时钟 - - // //PB6 SCL PB7初始化设置 - // GPIO_Initure.Pin = pSoftIIC->scl_pin ; - // GPIO_Initure.Mode = GPIO_MODE_OUTPUT_PP; // 推挽输出 - // GPIO_Initure.Pull = GPIO_PULLUP; // 上拉 - // GPIO_Initure.Speed = GPIO_SPEED_FAST; // 快速 - // HAL_GPIO_Init( pSoftIIC->scl_port, &GPIO_Initure ); - - // // SDA PB7 初始化设置 - // GPIO_Initure.Pin = pSoftIIC->sda_pin; - // HAL_GPIO_Init( pSoftIIC->sda_port, &GPIO_Initure ); - - // GPIO_WRITE_PIN(pSoftIIC->sda_port, pSoftIIC->sda_pin, 1); - // GPIO_WRITE_PIN(pSoftIIC->scl_port, pSoftIIC->scl_pin, 1); - - - // RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); - // GPIO_InitTypeDef GPIO_InitStructure; - // GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //457引脚配置为推挽输出 - // GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5| GPIO_Pin_7;//457引脚配置为推挽输出 - // GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - // GPIO_Init(GPIOA, &GPIO_InitStructure); - - // GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//pin6是MISO,对于STM32来说是输入,配置为上拉输入 - // GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;//pin6是MISO,对于STM32来说是输入,配置为上拉输入 - // GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - // GPIO_Init(GPIOA, &GPIO_InitStructure); - - // //CS引脚初始化 - // GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; - // GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; //推挽输出 - // GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - // GPIO_Init(GPIOC, &GPIO_InitStructure); - - // //SCK和MOSI引脚初始化 - // GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_7; - // GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; //推挽输出 - // GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - // GPIO_Init(GPIOA, &GPIO_InitStructure); - - // //MISO引脚初始化 - // GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; - // GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ; //浮空输入 - // GPIO_Init(GPIOA, &GPIO_InitStructure); + 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(void) +void SDO_IN(const SPI_SOFT_TypeDef *pSoftSPI) { GPIO_InitTypeDef GPIO_InitStruct = {0}; - GPIO_InitStruct.Pin = GPIO_PIN_1; + 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(GPIOC, &GPIO_InitStruct); + HAL_GPIO_Init(pSoftSPI->miso_pin, &GPIO_InitStruct); } /** * @brief Set SDIO as the output mode */ -void SDO_OUT(void) +void SDO_OUT(const SPI_SOFT_TypeDef *pSoftSPI) { GPIO_InitTypeDef GPIO_InitStruct; - GPIO_InitStruct.Pin = GPIO_PIN_1; + 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(GPIOC, &GPIO_InitStruct); + HAL_GPIO_Init(pSoftSPI->miso_pin, &GPIO_InitStruct); } /** * @brief Send one byte by SPI bus - * + * @def 先拉低,然后发送,在拉高有个跳变沿(从机检测到跳变),然后可以进入接收 * @param u8_writedata */ -void SPI_Write_OneByte(uint8_t 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; + // SDI_H; + HAL_GPIO_WritePin(pSoftSPI->mosi_port, pSoftSPI->mosi_pin, GPIO_PIN_SET); else - SDI_L; - SCLK_H; + // 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; + // SCLK_L; + // HAL_GPIO_WritePin(pSoftSPI->sclk_port, pSoftSPI->sclk_pin, GPIO_PIN_RESET); } } /** @@ -101,93 +96,165 @@ void SPI_Write_OneByte(uint8_t u8_writedata) * * @return temp */ -uint8_t SPI_Read_OneByte(void) +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; - if (SDO_R) + // 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; - else - temp &= ~0x01; - SCLK_L; + // 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} + * @param d: {D2, D1, D0} addr uint32_T * @return SUCCESS */ -uint8_t WriteReg(uint32_t d) +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(); - CS_L; - SPI_Write_OneByte(tx[0]); - SPI_Write_OneByte(tx[1]); - SPI_Write_OneByte(tx[2]); - CS_H; - SDI_L; + 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} + * @param d: {D2, D1, D0} addr uint32_t * @return data: The data be read in a register */ -uint8_t ReadReg(uint32_t d) +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(); + SDO_OUT(pSoftSPI); // CS_L; - // SPI_Write_OneByte(tx[0]); - // SPI_Write_OneByte(tx[1]); - // SDO_IN(); - // data = SPI_Read_OneByte(); + 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; - // SDO_OUT(); + HAL_GPIO_WritePin(pSoftSPI->cs_port, pSoftSPI->cs_pin, GPIO_PIN_SET); + SDO_OUT(pSoftSPI); // SDI_L; - return data; -} + HAL_GPIO_WritePin(pSoftSPI->mosi_port, pSoftSPI->mosi_pin, GPIO_PIN_RESET); + log_i(" ReadReg ... %02X ", data); + return data; +} -/* ,同步传输数据,比如在时钟的上升沿是写数据,那么在时钟的下降沿就是读数据 -static uint8_t W25QXX_SPI_ReadWriteByte(uint8_t TxData) +// test ok +uint32_t SPI_FLASH_ReadDeviceID(const SPI_SOFT_TypeDef *pSoftSPI) { - int i = 0; - uint8_t RxData = 0; - W25QXX_SCK_L(); // 时钟拉低 - for(i = 7; i >= 0; i--) - { - W25QXX_SCK_L(); // 时钟拉低 ,发送1bit - if(TxData & (1 << i)) - { - W25QXX_MOSI_H(); - } - else - { - W25QXX_MOSI_L(); - } - delay_us(1); // 延时1微秒 - W25QXX_SCK_H(); // 拉高时钟读 1bit - RxData <<= 1; - RxData |= W25QXX_MISO_GET(); - delay_us(1); - } - W25QXX_SCK_L(); - return RxData; -} - + 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; +} -*/