38#if defined(STM32F072xB) || defined(STM32F091xC)
39#include "stm32f0xx_ll_rcc.h"
40#elif defined(STM32F103xB)
41#include "stm32f1xx_ll_rcc.h"
42#elif defined(STM32F303xC) || defined(STM32F303xE)
43#include "stm32f3xx_ll_rcc.h"
44#elif defined(STM32L432xx) || defined(STM32L431xx)
45#include "stm32l4xx_ll_rcc.h"
46#elif defined(STM32F767xx)
47#include "stm32f7xx_ll_rcc.h"
48#elif defined(STM32G0B1xx)
49#include "stm32g0xx_ll_rcc.h"
51#error Dont know what STM32 chip you have.
54#define SPI_DEFAULT_TIMEOUT 100u
57static void spi_reset(SPI_TypeDef *port)
59 switch ((
unsigned)port)
62 DIE(
"Unknown SPI port requested.");
65 __HAL_RCC_SPI1_CLK_ENABLE();
66 __HAL_RCC_SPI1_FORCE_RESET();
67 __HAL_RCC_SPI1_RELEASE_RESET();
72 __HAL_RCC_SPI2_CLK_ENABLE();
73 __HAL_RCC_SPI2_FORCE_RESET();
74 __HAL_RCC_SPI2_RELEASE_RESET();
79 __HAL_RCC_SPI3_CLK_ENABLE();
80 __HAL_RCC_SPI3_FORCE_RESET();
81 __HAL_RCC_SPI3_RELEASE_RESET();
86 __HAL_RCC_SPI4_CLK_ENABLE();
87 __HAL_RCC_SPI4_FORCE_RESET();
88 __HAL_RCC_SPI4_RELEASE_RESET();
93 __HAL_RCC_SPI5_CLK_ENABLE();
94 __HAL_RCC_SPI5_FORCE_RESET();
95 __HAL_RCC_SPI5_RELEASE_RESET();
100 __HAL_RCC_SPI6_CLK_ENABLE();
101 __HAL_RCC_SPI6_FORCE_RESET();
102 __HAL_RCC_SPI6_RELEASE_RESET();
107 __HAL_RCC_SPI7_CLK_ENABLE();
108 __HAL_RCC_SPI7_FORCE_RESET();
109 __HAL_RCC_SPI7_RELEASE_RESET();
114 __HAL_RCC_SPI8_CLK_ENABLE();
115 __HAL_RCC_SPI8_FORCE_RESET();
116 __HAL_RCC_SPI8_RELEASE_RESET();
123 ChipSelectMethod cs_assert, ChipSelectMethod cs_deassert,
125 :
SPI(name, cs_assert, cs_deassert, bus_lock)
135static const uint32_t baud_rate_table[] =
137 2, SPI_BAUDRATEPRESCALER_2,
138 4, SPI_BAUDRATEPRESCALER_4,
139 8, SPI_BAUDRATEPRESCALER_8,
140 16, SPI_BAUDRATEPRESCALER_16,
141 32, SPI_BAUDRATEPRESCALER_32,
142 64, SPI_BAUDRATEPRESCALER_64,
143 128, SPI_BAUDRATEPRESCALER_128,
144 256, SPI_BAUDRATEPRESCALER_256,
159 pclock = __LL_RCC_CALC_PCLK1_FREQ(configCPU_CLOCK_HZ, LL_RCC_GetAPB1Prescaler());
161 while (baud_rate_table[ofs] && ((pclock / baud_rate_table[ofs]) >
speedHz))
165 if (baud_rate_table[ofs] == 0)
170 spiHandle_.Init.BaudRatePrescaler = baud_rate_table[ofs + 1];
172 spiHandle_.Init.Direction = SPI_DIRECTION_2LINES;
177 spiHandle_.Init.CLKPolarity = SPI_POLARITY_HIGH;
182 spiHandle_.Init.CLKPolarity = SPI_POLARITY_LOW;
214 spiHandle_.Init.DataSize = SPI_DATASIZE_16BIT;
228 spiHandle_.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
229 spiHandle_.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
231 spiHandle_.Init.CRCLength = SPI_CRC_LENGTH_8BIT;
253 HAL_StatusTypeDef ret = HAL_OK;
254 unsigned bytes = msg->len;
260 ret = HAL_SPI_Receive(
261 &
spiHandle_, (uint8_t *)msg->rx_buf, 1, SPI_DEFAULT_TIMEOUT);
265 if (ret == HAL_OK && msg->len)
267 ret = HAL_SPI_Receive(&
spiHandle_, (uint8_t *)msg->rx_buf, msg->len,
268 SPI_DEFAULT_TIMEOUT);
271 else if (!msg->rx_buf)
276 ret = HAL_SPI_Transmit(
277 &
spiHandle_, (uint8_t *)msg->tx_buf, 1, SPI_DEFAULT_TIMEOUT);
281 if (ret == HAL_OK && msg->len)
283 ret = HAL_SPI_Transmit(&
spiHandle_, (uint8_t *)msg->tx_buf,
284 msg->len, SPI_DEFAULT_TIMEOUT);
287 while (__HAL_SPI_GET_FLAG(&
spiHandle_, SPI_FLAG_BSY))
292 while (__HAL_SPI_GET_FLAG(&
spiHandle_, SPI_FLAG_RXNE))
301 if ((msg->rx_buf & 1) && (msg->tx_buf & 1))
303 ret = HAL_SPI_TransmitReceive(&
spiHandle_, (uint8_t *)msg->tx_buf,
304 (uint8_t *)msg->rx_buf, 1, SPI_DEFAULT_TIMEOUT);
309 if ((msg->rx_buf & 1) || (msg->tx_buf & 1))
314 if (ret == HAL_OK && msg->len)
316 ret = HAL_SPI_TransmitReceive(&
spiHandle_, (uint8_t *)msg->tx_buf,
317 (uint8_t *)msg->rx_buf, msg->len, SPI_DEFAULT_TIMEOUT);
This class provides a mutex API.
Private data for an SPI device.
uint8_t mode
one of four SPI modes
uint32_t speedHz
Max default speed in Hz.
bool lsbFirst
transmit LSB first if true
uint8_t bitsPerWord
number of bits per word transaction
int update_configuration() override
Update the configuration of the bus.
SPI_HandleTypeDef spiHandle_
Stm32 HAL device structure.
int transfer(struct spi_ioc_transfer *msg) override
Method to transmit/receive the data.
Stm32SPI()
Default constructor.
#define HASSERT(x)
Checks that the value of expression x is true, else terminates the current process.
#define DIE(MSG)
Unconditionally terminates the current process with a message.