|
@@ -0,0 +1,213 @@
|
|
|
+/**
|
|
|
+ * @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;
|
|
|
+}
|