mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-16 21:05:35 +03:00
commit
0a34f0e774
8 changed files with 200 additions and 306 deletions
|
@ -61,6 +61,7 @@ VCP_SRC = \
|
|||
MCU_COMMON_SRC = \
|
||||
drivers/adc_stm32f10x.c \
|
||||
drivers/bus_i2c_stm32f10x.c \
|
||||
drivers/bus_std_periph.c \
|
||||
drivers/dma.c \
|
||||
drivers/inverter.c \
|
||||
drivers/light_ws2811strip_stdperiph.c \
|
||||
|
|
|
@ -72,6 +72,7 @@ MCU_COMMON_SRC = \
|
|||
target/system_stm32f30x.c \
|
||||
drivers/adc_stm32f30x.c \
|
||||
drivers/bus_i2c_stm32f30x.c \
|
||||
drivers/bus_spi_stdperiph.c \
|
||||
drivers/dma.c \
|
||||
drivers/light_ws2811strip_stdperiph.c \
|
||||
drivers/pwm_output_dshot.c \
|
||||
|
|
|
@ -157,6 +157,7 @@ MCU_COMMON_SRC = \
|
|||
drivers/accgyro/accgyro_mpu.c \
|
||||
drivers/adc_stm32f4xx.c \
|
||||
drivers/bus_i2c_stm32f10x.c \
|
||||
drivers/bus_spi_stdperiph.c \
|
||||
drivers/dma_stm32f4xx.c \
|
||||
drivers/inverter.c \
|
||||
drivers/light_ws2811strip_stdperiph.c \
|
||||
|
|
|
@ -157,7 +157,6 @@ MCU_COMMON_SRC = \
|
|||
drivers/serial_uart_hal.c
|
||||
|
||||
MCU_EXCLUDES = \
|
||||
drivers/bus_spi.c \
|
||||
drivers/bus_i2c.c \
|
||||
drivers/timer.c \
|
||||
drivers/serial_uart.c
|
||||
|
|
|
@ -66,69 +66,6 @@ SPI_TypeDef *spiInstanceByDevice(SPIDevice device)
|
|||
return spiDevice[device].dev;
|
||||
}
|
||||
|
||||
void spiInitDevice(SPIDevice device)
|
||||
{
|
||||
spiDevice_t *spi = &(spiDevice[device]);
|
||||
|
||||
#ifdef SDCARD_SPI_INSTANCE
|
||||
if (spi->dev == SDCARD_SPI_INSTANCE) {
|
||||
spi->leadingEdge = true;
|
||||
}
|
||||
#endif
|
||||
#ifdef RX_SPI_INSTANCE
|
||||
if (spi->dev == RX_SPI_INSTANCE) {
|
||||
spi->leadingEdge = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Enable SPI clock
|
||||
RCC_ClockCmd(spi->rcc, ENABLE);
|
||||
RCC_ResetCmd(spi->rcc, ENABLE);
|
||||
|
||||
IOInit(IOGetByTag(spi->sck), OWNER_SPI_SCK, RESOURCE_INDEX(device));
|
||||
IOInit(IOGetByTag(spi->miso), OWNER_SPI_MISO, RESOURCE_INDEX(device));
|
||||
IOInit(IOGetByTag(spi->mosi), OWNER_SPI_MOSI, RESOURCE_INDEX(device));
|
||||
|
||||
#if defined(STM32F3) || defined(STM32F4)
|
||||
IOConfigGPIOAF(IOGetByTag(spi->sck), SPI_IO_AF_CFG, spi->af);
|
||||
IOConfigGPIOAF(IOGetByTag(spi->miso), SPI_IO_AF_CFG, spi->af);
|
||||
IOConfigGPIOAF(IOGetByTag(spi->mosi), SPI_IO_AF_CFG, spi->af);
|
||||
#endif
|
||||
#if defined(STM32F10X)
|
||||
IOConfigGPIO(IOGetByTag(spi->sck), SPI_IO_AF_SCK_CFG);
|
||||
IOConfigGPIO(IOGetByTag(spi->miso), SPI_IO_AF_MISO_CFG);
|
||||
IOConfigGPIO(IOGetByTag(spi->mosi), SPI_IO_AF_MOSI_CFG);
|
||||
#endif
|
||||
|
||||
// Init SPI hardware
|
||||
SPI_I2S_DeInit(spi->dev);
|
||||
|
||||
SPI_InitTypeDef spiInit;
|
||||
spiInit.SPI_Mode = SPI_Mode_Master;
|
||||
spiInit.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
|
||||
spiInit.SPI_DataSize = SPI_DataSize_8b;
|
||||
spiInit.SPI_NSS = SPI_NSS_Soft;
|
||||
spiInit.SPI_FirstBit = SPI_FirstBit_MSB;
|
||||
spiInit.SPI_CRCPolynomial = 7;
|
||||
spiInit.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
|
||||
|
||||
if (spi->leadingEdge) {
|
||||
spiInit.SPI_CPOL = SPI_CPOL_Low;
|
||||
spiInit.SPI_CPHA = SPI_CPHA_1Edge;
|
||||
} else {
|
||||
spiInit.SPI_CPOL = SPI_CPOL_High;
|
||||
spiInit.SPI_CPHA = SPI_CPHA_2Edge;
|
||||
}
|
||||
|
||||
#ifdef STM32F303xC
|
||||
// Configure for 8-bit reads.
|
||||
SPI_RxFIFOThresholdConfig(spi->dev, SPI_RxFIFOThreshold_QF);
|
||||
#endif
|
||||
|
||||
SPI_Init(spi->dev, &spiInit);
|
||||
SPI_Cmd(spi->dev, ENABLE);
|
||||
}
|
||||
|
||||
bool spiInit(SPIDevice device)
|
||||
{
|
||||
switch (device) {
|
||||
|
@ -149,7 +86,7 @@ bool spiInit(SPIDevice device)
|
|||
break;
|
||||
#endif
|
||||
case SPIDEV_3:
|
||||
#if defined(USE_SPI_DEVICE_3) && (defined(STM32F303xC) || defined(STM32F4))
|
||||
#if defined(USE_SPI_DEVICE_3) && !defined(STM32F1)
|
||||
spiInitDevice(device);
|
||||
return true;
|
||||
#else
|
||||
|
@ -176,81 +113,6 @@ uint32_t spiTimeoutUserCallback(SPI_TypeDef *instance)
|
|||
return spiDevice[device].errorCount;
|
||||
}
|
||||
|
||||
// return uint8_t value or -1 when failure
|
||||
uint8_t spiTransferByte(SPI_TypeDef *instance, uint8_t txByte)
|
||||
{
|
||||
uint16_t spiTimeout = 1000;
|
||||
|
||||
while (SPI_I2S_GetFlagStatus(instance, SPI_I2S_FLAG_TXE) == RESET)
|
||||
if ((spiTimeout--) == 0)
|
||||
return spiTimeoutUserCallback(instance);
|
||||
|
||||
#ifdef STM32F303xC
|
||||
SPI_SendData8(instance, txByte);
|
||||
#else
|
||||
SPI_I2S_SendData(instance, txByte);
|
||||
#endif
|
||||
spiTimeout = 1000;
|
||||
while (SPI_I2S_GetFlagStatus(instance, SPI_I2S_FLAG_RXNE) == RESET)
|
||||
if ((spiTimeout--) == 0)
|
||||
return spiTimeoutUserCallback(instance);
|
||||
|
||||
#ifdef STM32F303xC
|
||||
return ((uint8_t)SPI_ReceiveData8(instance));
|
||||
#else
|
||||
return ((uint8_t)SPI_I2S_ReceiveData(instance));
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the bus is currently in the middle of a transmission.
|
||||
*/
|
||||
bool spiIsBusBusy(SPI_TypeDef *instance)
|
||||
{
|
||||
#ifdef STM32F303xC
|
||||
return SPI_GetTransmissionFIFOStatus(instance) != SPI_TransmissionFIFOStatus_Empty || SPI_I2S_GetFlagStatus(instance, SPI_I2S_FLAG_BSY) == SET;
|
||||
#else
|
||||
return SPI_I2S_GetFlagStatus(instance, SPI_I2S_FLAG_TXE) == RESET || SPI_I2S_GetFlagStatus(instance, SPI_I2S_FLAG_BSY) == SET;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
bool spiTransfer(SPI_TypeDef *instance, const uint8_t *txData, uint8_t *rxData, int len)
|
||||
{
|
||||
uint16_t spiTimeout = 1000;
|
||||
|
||||
uint8_t b;
|
||||
instance->DR;
|
||||
while (len--) {
|
||||
b = txData ? *(txData++) : 0xFF;
|
||||
while (SPI_I2S_GetFlagStatus(instance, SPI_I2S_FLAG_TXE) == RESET) {
|
||||
if ((spiTimeout--) == 0)
|
||||
return spiTimeoutUserCallback(instance);
|
||||
}
|
||||
#ifdef STM32F303xC
|
||||
SPI_SendData8(instance, b);
|
||||
#else
|
||||
SPI_I2S_SendData(instance, b);
|
||||
#endif
|
||||
spiTimeout = 1000;
|
||||
while (SPI_I2S_GetFlagStatus(instance, SPI_I2S_FLAG_RXNE) == RESET) {
|
||||
if ((spiTimeout--) == 0)
|
||||
return spiTimeoutUserCallback(instance);
|
||||
}
|
||||
#ifdef STM32F303xC
|
||||
b = SPI_ReceiveData8(instance);
|
||||
#else
|
||||
b = SPI_I2S_ReceiveData(instance);
|
||||
#endif
|
||||
if (rxData)
|
||||
*(rxData++) = b;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#include "build/debug.h"
|
||||
|
||||
bool spiBusTransfer(const busDevice_t *bus, const uint8_t *txData, uint8_t *rxData, int length)
|
||||
{
|
||||
IOLo(bus->busdev_u.spi.csnPin);
|
||||
|
@ -259,28 +121,6 @@ bool spiBusTransfer(const busDevice_t *bus, const uint8_t *txData, uint8_t *rxDa
|
|||
return true;
|
||||
}
|
||||
|
||||
void spiSetDivisor(SPI_TypeDef *instance, uint16_t divisor)
|
||||
{
|
||||
#define BR_BITS ((BIT(5) | BIT(4) | BIT(3)))
|
||||
|
||||
#if !(defined(STM32F1) || defined(STM32F3))
|
||||
// SPI2 and SPI3 are on APB1/AHB1 which PCLK is half that of APB2/AHB2.
|
||||
|
||||
if (instance == SPI2 || instance == SPI3) {
|
||||
divisor /= 2; // Safe for divisor == 0 or 1
|
||||
}
|
||||
#endif
|
||||
|
||||
SPI_Cmd(instance, DISABLE);
|
||||
|
||||
const uint16_t tempRegister = (instance->CR1 & ~BR_BITS);
|
||||
instance->CR1 = tempRegister | (divisor ? ((ffs(divisor | 0x100) - 2) << 3) : 0);
|
||||
|
||||
SPI_Cmd(instance, ENABLE);
|
||||
|
||||
#undef BR_BITS
|
||||
}
|
||||
|
||||
uint16_t spiGetErrorCounter(SPI_TypeDef *instance)
|
||||
{
|
||||
SPIDevice device = spiDeviceByInstance(instance);
|
||||
|
|
|
@ -70,3 +70,6 @@ typedef struct SPIDevice_s {
|
|||
} spiDevice_t;
|
||||
|
||||
extern spiDevice_t spiDevice[SPIDEV_COUNT];
|
||||
|
||||
void spiInitDevice(SPIDevice device);
|
||||
uint32_t spiTimeoutUserCallback(SPI_TypeDef *instance);
|
||||
|
|
|
@ -71,40 +71,6 @@ spiDevice_t spiDevice[SPIDEV_COUNT];
|
|||
|
||||
#define SPI_DEFAULT_TIMEOUT 10
|
||||
|
||||
SPIDevice spiDeviceByInstance(SPI_TypeDef *instance)
|
||||
{
|
||||
#ifdef USE_SPI_DEVICE_1
|
||||
if (instance == SPI1)
|
||||
return SPIDEV_1;
|
||||
#endif
|
||||
|
||||
#ifdef USE_SPI_DEVICE_2
|
||||
if (instance == SPI2)
|
||||
return SPIDEV_2;
|
||||
#endif
|
||||
|
||||
#ifdef USE_SPI_DEVICE_3
|
||||
if (instance == SPI3)
|
||||
return SPIDEV_3;
|
||||
#endif
|
||||
|
||||
#ifdef USE_SPI_DEVICE_4
|
||||
if (instance == SPI4)
|
||||
return SPIDEV_4;
|
||||
#endif
|
||||
|
||||
return SPIINVALID;
|
||||
}
|
||||
|
||||
SPI_TypeDef *spiInstanceByDevice(SPIDevice device)
|
||||
{
|
||||
if (device >= SPIDEV_COUNT) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return spiDevice[device].dev;
|
||||
}
|
||||
|
||||
void spiInitDevice(SPIDevice device)
|
||||
{
|
||||
spiDevice_t *spi = &(spiDevice[device]);
|
||||
|
@ -157,53 +123,6 @@ void spiInitDevice(SPIDevice device)
|
|||
LL_SPI_Enable(spi->dev);
|
||||
}
|
||||
|
||||
bool spiInit(SPIDevice device)
|
||||
{
|
||||
switch (device) {
|
||||
case SPIINVALID:
|
||||
return false;
|
||||
case SPIDEV_1:
|
||||
#if defined(USE_SPI_DEVICE_1)
|
||||
spiInitDevice(device);
|
||||
return true;
|
||||
#else
|
||||
break;
|
||||
#endif
|
||||
case SPIDEV_2:
|
||||
#if defined(USE_SPI_DEVICE_2)
|
||||
spiInitDevice(device);
|
||||
return true;
|
||||
#else
|
||||
break;
|
||||
#endif
|
||||
case SPIDEV_3:
|
||||
#if defined(USE_SPI_DEVICE_3)
|
||||
spiInitDevice(device);
|
||||
return true;
|
||||
#else
|
||||
break;
|
||||
#endif
|
||||
case SPIDEV_4:
|
||||
#if defined(USE_SPI_DEVICE_4)
|
||||
spiInitDevice(device);
|
||||
return true;
|
||||
#else
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t spiTimeoutUserCallback(SPI_TypeDef *instance)
|
||||
{
|
||||
SPIDevice device = spiDeviceByInstance(instance);
|
||||
if (device == SPIINVALID) {
|
||||
return -1;
|
||||
}
|
||||
spiDevice[device].errorCount++;
|
||||
return spiDevice[device].errorCount;
|
||||
}
|
||||
|
||||
uint8_t spiTransferByte(SPI_TypeDef *instance, uint8_t txByte)
|
||||
{
|
||||
uint16_t spiTimeout = 1000;
|
||||
|
@ -292,14 +211,6 @@ bool spiTransfer(SPI_TypeDef *instance, const uint8_t *txData, uint8_t *rxData,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool spiBusTransfer(const busDevice_t *bus, const uint8_t *txData, uint8_t *rxData, int length)
|
||||
{
|
||||
IOLo(bus->busdev_u.spi.csnPin);
|
||||
spiTransfer(bus->busdev_u.spi.instance, txData, rxData, length);
|
||||
IOHi(bus->busdev_u.spi.csnPin);
|
||||
return true;
|
||||
}
|
||||
|
||||
void spiSetDivisor(SPI_TypeDef *instance, uint16_t divisor)
|
||||
{
|
||||
#if !(defined(STM32F1) || defined(STM32F3))
|
||||
|
@ -314,59 +225,4 @@ void spiSetDivisor(SPI_TypeDef *instance, uint16_t divisor)
|
|||
LL_SPI_SetBaudRatePrescaler(instance, divisor ? (ffs(divisor | 0x100) - 2) << SPI_CR1_BR_Pos : 0);
|
||||
LL_SPI_Enable(instance);
|
||||
}
|
||||
|
||||
uint16_t spiGetErrorCounter(SPI_TypeDef *instance)
|
||||
{
|
||||
SPIDevice device = spiDeviceByInstance(instance);
|
||||
if (device == SPIINVALID) {
|
||||
return 0;
|
||||
}
|
||||
return spiDevice[device].errorCount;
|
||||
}
|
||||
|
||||
void spiResetErrorCounter(SPI_TypeDef *instance)
|
||||
{
|
||||
SPIDevice device = spiDeviceByInstance(instance);
|
||||
if (device != SPIINVALID) {
|
||||
spiDevice[device].errorCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool spiBusWriteRegister(const busDevice_t *bus, uint8_t reg, uint8_t data)
|
||||
{
|
||||
IOLo(bus->busdev_u.spi.csnPin);
|
||||
spiTransferByte(bus->busdev_u.spi.instance, reg);
|
||||
spiTransferByte(bus->busdev_u.spi.instance, data);
|
||||
IOHi(bus->busdev_u.spi.csnPin);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool spiBusReadRegisterBuffer(const busDevice_t *bus, uint8_t reg, uint8_t *data, uint8_t length)
|
||||
{
|
||||
IOLo(bus->busdev_u.spi.csnPin);
|
||||
spiTransferByte(bus->busdev_u.spi.instance, reg | 0x80); // read transaction
|
||||
spiTransfer(bus->busdev_u.spi.instance, NULL, data, length);
|
||||
IOHi(bus->busdev_u.spi.csnPin);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t spiBusReadRegister(const busDevice_t *bus, uint8_t reg)
|
||||
{
|
||||
uint8_t data;
|
||||
IOLo(bus->busdev_u.spi.csnPin);
|
||||
spiTransferByte(bus->busdev_u.spi.instance, reg | 0x80); // read transaction
|
||||
spiTransfer(bus->busdev_u.spi.instance, NULL, &data, 1);
|
||||
IOHi(bus->busdev_u.spi.csnPin);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void spiBusSetInstance(busDevice_t *bus, SPI_TypeDef *instance)
|
||||
{
|
||||
bus->bustype = BUSTYPE_SPI;
|
||||
bus->busdev_u.spi.instance = instance;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
193
src/main/drivers/bus_spi_stdperiph.c
Normal file
193
src/main/drivers/bus_spi_stdperiph.c
Normal file
|
@ -0,0 +1,193 @@
|
|||
/*
|
||||
* This file is part of Cleanflight.
|
||||
*
|
||||
* Cleanflight is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Cleanflight is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <platform.h>
|
||||
|
||||
#ifdef USE_SPI
|
||||
|
||||
#include "drivers/bus.h"
|
||||
#include "drivers/bus_spi.h"
|
||||
#include "drivers/bus_spi_impl.h"
|
||||
#include "drivers/exti.h"
|
||||
#include "drivers/io.h"
|
||||
#include "drivers/rcc.h"
|
||||
|
||||
spiDevice_t spiDevice[SPIDEV_COUNT];
|
||||
|
||||
void spiInitDevice(SPIDevice device)
|
||||
{
|
||||
spiDevice_t *spi = &(spiDevice[device]);
|
||||
|
||||
#ifdef SDCARD_SPI_INSTANCE
|
||||
if (spi->dev == SDCARD_SPI_INSTANCE) {
|
||||
spi->leadingEdge = true;
|
||||
}
|
||||
#endif
|
||||
#ifdef RX_SPI_INSTANCE
|
||||
if (spi->dev == RX_SPI_INSTANCE) {
|
||||
spi->leadingEdge = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Enable SPI clock
|
||||
RCC_ClockCmd(spi->rcc, ENABLE);
|
||||
RCC_ResetCmd(spi->rcc, ENABLE);
|
||||
|
||||
IOInit(IOGetByTag(spi->sck), OWNER_SPI_SCK, RESOURCE_INDEX(device));
|
||||
IOInit(IOGetByTag(spi->miso), OWNER_SPI_MISO, RESOURCE_INDEX(device));
|
||||
IOInit(IOGetByTag(spi->mosi), OWNER_SPI_MOSI, RESOURCE_INDEX(device));
|
||||
|
||||
#if defined(STM32F3) || defined(STM32F4)
|
||||
IOConfigGPIOAF(IOGetByTag(spi->sck), SPI_IO_AF_CFG, spi->af);
|
||||
IOConfigGPIOAF(IOGetByTag(spi->miso), SPI_IO_AF_CFG, spi->af);
|
||||
IOConfigGPIOAF(IOGetByTag(spi->mosi), SPI_IO_AF_CFG, spi->af);
|
||||
#elif defined(STM32F10X)
|
||||
IOConfigGPIO(IOGetByTag(spi->sck), SPI_IO_AF_SCK_CFG);
|
||||
IOConfigGPIO(IOGetByTag(spi->miso), SPI_IO_AF_MISO_CFG);
|
||||
IOConfigGPIO(IOGetByTag(spi->mosi), SPI_IO_AF_MOSI_CFG);
|
||||
#else
|
||||
#error Undefined MCU architecture
|
||||
#endif
|
||||
|
||||
// Init SPI hardware
|
||||
SPI_I2S_DeInit(spi->dev);
|
||||
|
||||
SPI_InitTypeDef spiInit;
|
||||
spiInit.SPI_Mode = SPI_Mode_Master;
|
||||
spiInit.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
|
||||
spiInit.SPI_DataSize = SPI_DataSize_8b;
|
||||
spiInit.SPI_NSS = SPI_NSS_Soft;
|
||||
spiInit.SPI_FirstBit = SPI_FirstBit_MSB;
|
||||
spiInit.SPI_CRCPolynomial = 7;
|
||||
spiInit.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
|
||||
|
||||
if (spi->leadingEdge) {
|
||||
spiInit.SPI_CPOL = SPI_CPOL_Low;
|
||||
spiInit.SPI_CPHA = SPI_CPHA_1Edge;
|
||||
} else {
|
||||
spiInit.SPI_CPOL = SPI_CPOL_High;
|
||||
spiInit.SPI_CPHA = SPI_CPHA_2Edge;
|
||||
}
|
||||
|
||||
#ifdef STM32F303xC
|
||||
// Configure for 8-bit reads.
|
||||
SPI_RxFIFOThresholdConfig(spi->dev, SPI_RxFIFOThreshold_QF);
|
||||
#endif
|
||||
|
||||
SPI_Init(spi->dev, &spiInit);
|
||||
SPI_Cmd(spi->dev, ENABLE);
|
||||
}
|
||||
|
||||
// return uint8_t value or -1 when failure
|
||||
uint8_t spiTransferByte(SPI_TypeDef *instance, uint8_t txByte)
|
||||
{
|
||||
uint16_t spiTimeout = 1000;
|
||||
|
||||
while (SPI_I2S_GetFlagStatus(instance, SPI_I2S_FLAG_TXE) == RESET)
|
||||
if ((spiTimeout--) == 0)
|
||||
return spiTimeoutUserCallback(instance);
|
||||
|
||||
#ifdef STM32F303xC
|
||||
SPI_SendData8(instance, txByte);
|
||||
#else
|
||||
SPI_I2S_SendData(instance, txByte);
|
||||
#endif
|
||||
spiTimeout = 1000;
|
||||
while (SPI_I2S_GetFlagStatus(instance, SPI_I2S_FLAG_RXNE) == RESET)
|
||||
if ((spiTimeout--) == 0)
|
||||
return spiTimeoutUserCallback(instance);
|
||||
|
||||
#ifdef STM32F303xC
|
||||
return ((uint8_t)SPI_ReceiveData8(instance));
|
||||
#else
|
||||
return ((uint8_t)SPI_I2S_ReceiveData(instance));
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the bus is currently in the middle of a transmission.
|
||||
*/
|
||||
bool spiIsBusBusy(SPI_TypeDef *instance)
|
||||
{
|
||||
#ifdef STM32F303xC
|
||||
return SPI_GetTransmissionFIFOStatus(instance) != SPI_TransmissionFIFOStatus_Empty || SPI_I2S_GetFlagStatus(instance, SPI_I2S_FLAG_BSY) == SET;
|
||||
#else
|
||||
return SPI_I2S_GetFlagStatus(instance, SPI_I2S_FLAG_TXE) == RESET || SPI_I2S_GetFlagStatus(instance, SPI_I2S_FLAG_BSY) == SET;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
bool spiTransfer(SPI_TypeDef *instance, const uint8_t *txData, uint8_t *rxData, int len)
|
||||
{
|
||||
uint16_t spiTimeout = 1000;
|
||||
|
||||
uint8_t b;
|
||||
instance->DR;
|
||||
while (len--) {
|
||||
b = txData ? *(txData++) : 0xFF;
|
||||
while (SPI_I2S_GetFlagStatus(instance, SPI_I2S_FLAG_TXE) == RESET) {
|
||||
if ((spiTimeout--) == 0)
|
||||
return spiTimeoutUserCallback(instance);
|
||||
}
|
||||
#ifdef STM32F303xC
|
||||
SPI_SendData8(instance, b);
|
||||
#else
|
||||
SPI_I2S_SendData(instance, b);
|
||||
#endif
|
||||
spiTimeout = 1000;
|
||||
while (SPI_I2S_GetFlagStatus(instance, SPI_I2S_FLAG_RXNE) == RESET) {
|
||||
if ((spiTimeout--) == 0)
|
||||
return spiTimeoutUserCallback(instance);
|
||||
}
|
||||
#ifdef STM32F303xC
|
||||
b = SPI_ReceiveData8(instance);
|
||||
#else
|
||||
b = SPI_I2S_ReceiveData(instance);
|
||||
#endif
|
||||
if (rxData)
|
||||
*(rxData++) = b;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void spiSetDivisor(SPI_TypeDef *instance, uint16_t divisor)
|
||||
{
|
||||
#define BR_BITS ((BIT(5) | BIT(4) | BIT(3)))
|
||||
|
||||
#if !(defined(STM32F1) || defined(STM32F3))
|
||||
// SPI2 and SPI3 are on APB1/AHB1 which PCLK is half that of APB2/AHB2.
|
||||
|
||||
if (instance == SPI2 || instance == SPI3) {
|
||||
divisor /= 2; // Safe for divisor == 0 or 1
|
||||
}
|
||||
#endif
|
||||
|
||||
SPI_Cmd(instance, DISABLE);
|
||||
|
||||
const uint16_t tempRegister = (instance->CR1 & ~BR_BITS);
|
||||
instance->CR1 = tempRegister | (divisor ? ((ffs(divisor | 0x100) - 2) << 3) : 0);
|
||||
|
||||
SPI_Cmd(instance, ENABLE);
|
||||
|
||||
#undef BR_BITS
|
||||
}
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue