1
0
Fork 0
mirror of https://github.com/betaflight/betaflight.git synced 2025-07-23 16:25:31 +03:00

Fix SPI timeout

This commit is contained in:
Hans Christian Olaussen 2021-04-01 12:46:16 +02:00
parent 025ee87a7a
commit ff95fc6471
4 changed files with 60 additions and 42 deletions

View file

@ -36,6 +36,8 @@
#include "nvic.h"
#include "rcc.h"
#define SPI_TIMEOUT_SYS_TICKS (SPI_TIMEOUT_US / 1000)
void spiInitDevice(SPIDevice device, bool leadingEdge)
{
spiDevice_t *spi = &(spiDevice[device]);
@ -93,8 +95,7 @@ void spiInitDevice(SPIDevice device, bool leadingEdge)
if (spi->leadingEdge) {
spi->hspi.Init.CLKPolarity = SPI_POLARITY_LOW;
spi->hspi.Init.CLKPhase = SPI_PHASE_1EDGE;
}
else {
} else {
spi->hspi.Init.CLKPolarity = SPI_POLARITY_HIGH;
spi->hspi.Init.CLKPhase = SPI_PHASE_2EDGE;
}
@ -118,10 +119,11 @@ uint8_t spiTransferByte(SPI_TypeDef *instance, uint8_t out)
bool spiIsBusBusy(SPI_TypeDef *instance)
{
SPIDevice device = spiDeviceByInstance(instance);
if(spiDevice[device].hspi.State == HAL_SPI_STATE_BUSY)
if (spiDevice[device].hspi.State == HAL_SPI_STATE_BUSY) {
return true;
else
} else {
return false;
}
}
bool spiTransfer(SPI_TypeDef *instance, const uint8_t *out, uint8_t *in, int len)
@ -129,20 +131,18 @@ bool spiTransfer(SPI_TypeDef *instance, const uint8_t *out, uint8_t *in, int len
SPIDevice device = spiDeviceByInstance(instance);
HAL_StatusTypeDef status;
#define SPI_DEFAULT_TIMEOUT 10
if (!in) {
// Tx only
status = HAL_SPI_Transmit(&spiDevice[device].hspi, out, len, SPI_DEFAULT_TIMEOUT);
} else if(!out) {
status = HAL_SPI_Transmit(&spiDevice[device].hspi, out, len, SPI_TIMEOUT_SYS_TICKS);
} else if (!out) {
// Rx only
status = HAL_SPI_Receive(&spiDevice[device].hspi, in, len, SPI_DEFAULT_TIMEOUT);
status = HAL_SPI_Receive(&spiDevice[device].hspi, in, len, SPI_TIMEOUT_SYS_TICKS);
} else {
// Tx and Rx
status = HAL_SPI_TransmitReceive(&spiDevice[device].hspi, out, in, len, SPI_DEFAULT_TIMEOUT);
status = HAL_SPI_TransmitReceive(&spiDevice[device].hspi, out, in, len, SPI_TIMEOUT_SYS_TICKS);
}
if(status != HAL_OK) {
if (status != HAL_OK) {
spiTimeoutUserCallback(instance);
}
@ -210,8 +210,9 @@ void SPI4_IRQHandler(void)
void dmaSPIIRQHandler(dmaChannelDescriptor_t* descriptor)
{
SPIDevice device = descriptor->userParam;
if (device != SPIINVALID)
if (device != SPIINVALID) {
HAL_DMA_IRQHandler(&spiDevice[device].hdma);
}
}
#endif // USE_DMA
#endif

View file

@ -20,6 +20,8 @@
#pragma once
#define SPI_TIMEOUT_US 10000
#if defined(STM32F1) || defined(STM32F3) || defined(STM32F4) || defined(STM32G4)
#define MAX_SPI_PIN_SEL 2
#elif defined(STM32F7)

View file

@ -36,6 +36,7 @@
#include "drivers/io.h"
#include "drivers/nvic.h"
#include "drivers/rcc.h"
#include "drivers/time.h"
#ifndef SPI2_SCK_PIN
#define SPI2_NSS_PIN PB12
@ -71,8 +72,6 @@
#define SPI4_NSS_PIN NONE
#endif
#define SPI_DEFAULT_TIMEOUT 10
static LL_SPI_InitTypeDef defaultInit =
{
.TransferDirection = SPI_DIRECTION_2LINES,
@ -107,10 +106,12 @@ void spiInitDevice(SPIDevice device, bool leadingEdge)
IOInit(IOGetByTag(spi->miso), OWNER_SPI_MISO, RESOURCE_INDEX(device));
IOInit(IOGetByTag(spi->mosi), OWNER_SPI_MOSI, RESOURCE_INDEX(device));
if (spi->leadingEdge == true)
if (spi->leadingEdge == true) {
IOConfigGPIOAF(IOGetByTag(spi->sck), SPI_IO_AF_SCK_CFG_LOW, spi->sckAF);
else
} else {
IOConfigGPIOAF(IOGetByTag(spi->sck), SPI_IO_AF_SCK_CFG_HIGH, spi->sckAF);
}
IOConfigGPIOAF(IOGetByTag(spi->miso), SPI_IO_AF_MISO_CFG, spi->misoAF);
IOConfigGPIOAF(IOGetByTag(spi->mosi), SPI_IO_AF_CFG, spi->mosiAF);
@ -136,18 +137,21 @@ void spiInitDevice(SPIDevice device, bool leadingEdge)
uint8_t spiTransferByte(SPI_TypeDef *instance, uint8_t txByte)
{
uint16_t spiTimeout = 1000;
timeUs_t timeoutStartUs = microsISR();
while (!LL_SPI_IsActiveFlag_TXE(instance))
if ((spiTimeout--) == 0)
while (!LL_SPI_IsActiveFlag_TXE(instance)) {
if (cmpTimeUs(microsISR(), timeoutStartUs) >= SPI_TIMEOUT_US) {
return spiTimeoutUserCallback(instance);
}
}
LL_SPI_TransmitData8(instance, txByte);
spiTimeout = 1000;
while (!LL_SPI_IsActiveFlag_RXNE(instance))
if ((spiTimeout--) == 0)
timeoutStartUs = microsISR();
while (!LL_SPI_IsActiveFlag_RXNE(instance)) {
if (cmpTimeUs(microsISR(), timeoutStartUs) >= SPI_TIMEOUT_US) {
return spiTimeoutUserCallback(instance);
}
}
return (uint8_t)LL_SPI_ReceiveData8(instance);
}
@ -163,12 +167,14 @@ bool spiIsBusBusy(SPI_TypeDef *instance)
bool spiTransfer(SPI_TypeDef *instance, const uint8_t *txData, uint8_t *rxData, int len)
{
timeUs_t timeoutStartUs;
// set 16-bit transfer
CLEAR_BIT(instance->CR2, SPI_RXFIFO_THRESHOLD);
while (len > 1) {
int spiTimeout = 1000;
timeoutStartUs = microsISR();
while (!LL_SPI_IsActiveFlag_TXE(instance)) {
if ((spiTimeout--) == 0) {
if (cmpTimeUs(microsISR(), timeoutStartUs) >= SPI_TIMEOUT_US) {
return spiTimeoutUserCallback(instance);
}
}
@ -181,9 +187,9 @@ bool spiTransfer(SPI_TypeDef *instance, const uint8_t *txData, uint8_t *rxData,
}
LL_SPI_TransmitData16(instance, w);
spiTimeout = 1000;
timeoutStartUs = microsISR();
while (!LL_SPI_IsActiveFlag_RXNE(instance)) {
if ((spiTimeout--) == 0) {
if (cmpTimeUs(microsISR(), timeoutStartUs) >= SPI_TIMEOUT_US) {
return spiTimeoutUserCallback(instance);
}
}
@ -197,18 +203,18 @@ bool spiTransfer(SPI_TypeDef *instance, const uint8_t *txData, uint8_t *rxData,
// set 8-bit transfer
SET_BIT(instance->CR2, SPI_RXFIFO_THRESHOLD);
if (len) {
int spiTimeout = 1000;
timeoutStartUs = microsISR();
while (!LL_SPI_IsActiveFlag_TXE(instance)) {
if ((spiTimeout--) == 0) {
if (cmpTimeUs(microsISR(), timeoutStartUs) >= SPI_TIMEOUT_US) {
return spiTimeoutUserCallback(instance);
}
}
uint8_t b = txData ? *(txData++) : 0xFF;
LL_SPI_TransmitData8(instance, b);
spiTimeout = 1000;
timeoutStartUs = microsISR();
while (!LL_SPI_IsActiveFlag_RXNE(instance)) {
if ((spiTimeout--) == 0) {
if (cmpTimeUs(microsISR(), timeoutStartUs) >= SPI_TIMEOUT_US) {
return spiTimeoutUserCallback(instance);
}
}

View file

@ -33,6 +33,7 @@
#include "drivers/exti.h"
#include "drivers/io.h"
#include "drivers/rcc.h"
#include "drivers/time.h"
static SPI_InitTypeDef defaultInit = {
.SPI_Mode = SPI_Mode_Master,
@ -104,23 +105,27 @@ void spiInitDevice(SPIDevice device, bool leadingEdge)
// return uint8_t value or -1 when failure
uint8_t spiTransferByte(SPI_TypeDef *instance, uint8_t txByte)
{
uint16_t spiTimeout = 1000;
timeUs_t timeoutStartUs = microsISR();
DISCARD(instance->DR);
while (SPI_I2S_GetFlagStatus(instance, SPI_I2S_FLAG_TXE) == RESET)
if ((spiTimeout--) == 0)
while (SPI_I2S_GetFlagStatus(instance, SPI_I2S_FLAG_TXE) == RESET) {
if (cmpTimeUs(microsISR(), timeoutStartUs) >= SPI_TIMEOUT_US) {
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)
timeoutStartUs = microsISR();
while (SPI_I2S_GetFlagStatus(instance, SPI_I2S_FLAG_RXNE) == RESET) {
if (cmpTimeUs(microsISR(), timeoutStartUs) >= SPI_TIMEOUT_US) {
return spiTimeoutUserCallback(instance);
}
}
#ifdef STM32F303xC
return ((uint8_t)SPI_ReceiveData8(instance));
@ -144,15 +149,17 @@ bool spiIsBusBusy(SPI_TypeDef *instance)
bool spiTransfer(SPI_TypeDef *instance, const uint8_t *txData, uint8_t *rxData, int len)
{
uint16_t spiTimeout = 1000;
timeUs_t timeoutStartUs;
uint8_t b;
DISCARD(instance->DR);
while (len--) {
b = txData ? *(txData++) : 0xFF;
timeoutStartUs = microsISR();
while (SPI_I2S_GetFlagStatus(instance, SPI_I2S_FLAG_TXE) == RESET) {
if ((spiTimeout--) == 0)
if (cmpTimeUs(microsISR(), timeoutStartUs) >= SPI_TIMEOUT_US) {
return spiTimeoutUserCallback(instance);
}
}
#ifdef STM32F303xC
SPI_SendData8(instance, b);
@ -160,19 +167,21 @@ bool spiTransfer(SPI_TypeDef *instance, const uint8_t *txData, uint8_t *rxData,
SPI_I2S_SendData(instance, b);
#endif
spiTimeout = 1000;
timeoutStartUs = microsISR();
while (SPI_I2S_GetFlagStatus(instance, SPI_I2S_FLAG_RXNE) == RESET) {
if ((spiTimeout--) == 0)
if (cmpTimeUs(microsISR(), timeoutStartUs) >= SPI_TIMEOUT_US) {
return spiTimeoutUserCallback(instance);
}
}
#ifdef STM32F303xC
b = SPI_ReceiveData8(instance);
#else
b = SPI_I2S_ReceiveData(instance);
#endif
if (rxData)
if (rxData) {
*(rxData++) = b;
}
}
return true;