/** * @file softspi.c * @author Myth * @version 0.2 * @date 2021.10.12 * @brief STM32 SoftSPI Library */ #include "dev_soft_spi.h" #define SCLK_Set HAL_GPIO_WritePin(SoftSPIx->SCLK_GPIO, SoftSPIx->SCLK_Pin, GPIO_PIN_SET) #define SCLK_Clr HAL_GPIO_WritePin(SoftSPIx->SCLK_GPIO, SoftSPIx->SCLK_Pin, GPIO_PIN_RESET) #define MOSI_Set HAL_GPIO_WritePin(SoftSPIx->MOSI_GPIO, SoftSPIx->MOSI_Pin, GPIO_PIN_SET) #define MOSI_Clr HAL_GPIO_WritePin(SoftSPIx->MOSI_GPIO, SoftSPIx->MOSI_Pin, GPIO_PIN_RESET) #define MISO_Read HAL_GPIO_ReadPin(SoftSPIx->MISO_GPIO, SoftSPIx->MISO_Pin) #define SS_Set HAL_GPIO_WritePin(SoftSPIx->SS_GPIO, SoftSPIx->SS_Pin, GPIO_PIN_SET) #define SS_Clr HAL_GPIO_WritePin(SoftSPIx->SS_GPIO, SoftSPIx->SS_Pin, GPIO_PIN_RESET) #define Delay SoftSPI_Delay_us(SoftSPIx->Delay_Time) uint8_t SoftSPI_GPIOx_Pin_Init(GPIO_TypeDef *GPIOx, uint32_t Pin, uint32_t Mode, uint32_t Pull); HAL_StatusTypeDef SoftSPI_Init(SoftSPI_TypeDef *SoftSPIx) { SoftSPIx->SCLK_GPIO = SoftSPIx->SCLK_GPIO; SoftSPIx->SCLK_Pin = SoftSPIx->SCLK_Pin; if (!SoftSPI_GPIOx_Pin_Init(SoftSPIx->SCLK_GPIO, SoftSPIx->SCLK_Pin, GPIO_MODE_OUTPUT_PP, GPIO_NOPULL)) return HAL_ERROR; SoftSPIx->MOSI_GPIO = SoftSPIx->MOSI_GPIO; SoftSPIx->MOSI_Pin = SoftSPIx->MOSI_Pin; if (!SoftSPI_GPIOx_Pin_Init(SoftSPIx->MOSI_GPIO, SoftSPIx->MOSI_Pin, GPIO_MODE_OUTPUT_PP, GPIO_NOPULL)) return HAL_ERROR; SoftSPIx->MISO_GPIO = SoftSPIx->MISO_GPIO; SoftSPIx->MISO_Pin = SoftSPIx->MISO_Pin; if (!SoftSPI_GPIOx_Pin_Init(SoftSPIx->MISO_GPIO, SoftSPIx->MISO_Pin, GPIO_MODE_INPUT, GPIO_NOPULL)) return HAL_ERROR; SoftSPIx->SS_GPIO = SoftSPIx->SS_GPIO; SoftSPIx->SS_Pin = SoftSPIx->SS_Pin; if (!SoftSPI_GPIOx_Pin_Init(SoftSPIx->SS_GPIO, SoftSPIx->SS_Pin, GPIO_MODE_OUTPUT_PP, GPIO_NOPULL)) return HAL_ERROR; if(SoftSPIx->WP_GPIO != NULL) { SoftSPIx->WP_GPIO = SoftSPIx->WP_GPIO; SoftSPIx->WP_Pin = SoftSPIx->WP_Pin; //if (!SoftSPI_GPIOx_Pin_Init(SoftSPIx->WP_GPIO, SoftSPIx->WP_Pin, GPIO_MODE_INPUT, GPIO_NOPULL)) if (!SoftSPI_GPIOx_Pin_Init(SoftSPIx->WP_GPIO, SoftSPIx->WP_Pin, GPIO_MODE_OUTPUT_PP, GPIO_PULLUP)) return HAL_ERROR; HAL_GPIO_WritePin(SoftSPIx->WP_GPIO, SoftSPIx->WP_Pin, GPIO_PIN_SET); } SoftSPIx->Delay_Time = SoftSPIx->Delay_Time; return HAL_OK; } void SoftSPI_SetSS(SoftSPI_TypeDef *SoftSPIx) { SS_Set; } void SoftSPI_ClrSS(SoftSPI_TypeDef *SoftSPIx) { SS_Clr; } uint8_t SoftSPI_WriteRead(SoftSPI_TypeDef *SoftSPIx, uint8_t byte) { uint8_t data = 0; uint8_t i; for (i = 0; i < 8; i++) { SCLK_Clr; Delay; if (byte & 0x80) MOSI_Set; else MOSI_Clr; Delay; byte <<= 1; SCLK_Set; Delay; data <<= 1; if (MISO_Read == GPIO_PIN_SET) data |= 0x01; Delay; } return data; } void SoftSPI_WriteReadBuff(SoftSPI_TypeDef *SoftSPIx, uint8_t *pWrite, uint8_t *pRead, uint32_t len) { uint8_t data; uint8_t byte; uint8_t i, j; for (j = 0; j < len; j++) { data = 0; byte = pWrite[j]; for (i = 0; i < 8; i++) { SCLK_Clr; Delay; if (byte & 0x80) MOSI_Set; else MOSI_Clr; Delay; byte <<= 1; SCLK_Set; Delay; data <<= 1; if (MISO_Read == GPIO_PIN_SET) data |= 0x01; Delay; } pRead[j] = data; } } uint8_t SoftSPI_GPIOx_Pin_Init(GPIO_TypeDef *GPIOx, uint32_t Pin, uint32_t Mode, uint32_t Pull) { switch ((uint32_t)(GPIOx)) { case (uint32_t)GPIOA: { GPIO_InitTypeDef GPIO_Initure; __HAL_RCC_GPIOA_CLK_ENABLE(); GPIO_Initure.Pin = Pin; GPIO_Initure.Mode = Mode; GPIO_Initure.Pull = Pull; GPIO_Initure.Speed = GPIO_SPEED_HIGH; HAL_GPIO_Init(GPIOA, &GPIO_Initure); } break; case (uint32_t)GPIOB: { GPIO_InitTypeDef GPIO_Initure; __HAL_RCC_GPIOB_CLK_ENABLE(); GPIO_Initure.Pin = Pin; GPIO_Initure.Mode = Mode; GPIO_Initure.Pull = Pull; GPIO_Initure.Speed = GPIO_SPEED_HIGH; HAL_GPIO_Init(GPIOB, &GPIO_Initure); } break; case (uint32_t)GPIOC: { GPIO_InitTypeDef GPIO_Initure; __HAL_RCC_GPIOC_CLK_ENABLE(); GPIO_Initure.Pin = Pin; GPIO_Initure.Mode = Mode; GPIO_Initure.Pull = Pull; GPIO_Initure.Speed = GPIO_SPEED_HIGH; HAL_GPIO_Init(GPIOC, &GPIO_Initure); } break; case (uint32_t)GPIOD: { GPIO_InitTypeDef GPIO_Initure; __HAL_RCC_GPIOD_CLK_ENABLE(); GPIO_Initure.Pin = Pin; GPIO_Initure.Mode = Mode; GPIO_Initure.Pull = Pull; GPIO_Initure.Speed = GPIO_SPEED_HIGH; HAL_GPIO_Init(GPIOD, &GPIO_Initure); } break; default: return 0; } return 1; }