1
0
Fork 0
mirror of https://github.com/iNavFlight/inav.git synced 2025-07-26 17:55:28 +03:00

Refactor F7 SPI, migrate to HAL_LL; Remove DMA support from SD-card; Fix SD-card init

This commit is contained in:
Konstantin Sharlaimov (DigitalEntity) 2018-11-03 16:38:48 +01:00
parent e047c17712
commit 49a28ac02b
12 changed files with 159 additions and 373 deletions

View file

@ -80,6 +80,7 @@ static const uint16_t spiDivisorMapFast[] = {
SPI_BaudRatePrescaler_4, // SPI_CLOCK_FAST 18.0 MBits/s
SPI_BaudRatePrescaler_4 // SPI_CLOCK_ULTRAFAST 18.0 MBits/s
};
static const uint16_t spiDivisorMapSlow[] = {
SPI_BaudRatePrescaler_256, // SPI_CLOCK_INITIALIZATON 140.625 KBits/s
SPI_BaudRatePrescaler_64, // SPI_CLOCK_SLOW 562.5 KBits/s
@ -87,6 +88,12 @@ static const uint16_t spiDivisorMapSlow[] = {
SPI_BaudRatePrescaler_2, // SPI_CLOCK_FAST 18.0 MBits/s
SPI_BaudRatePrescaler_2 // SPI_CLOCK_ULTRAFAST 18.0 MBits/s
};
static spiDevice_t spiHardwareMap[] = {
{ .dev = SPI1, .nss = IO_TAG(SPI1_NSS_PIN), .sck = IO_TAG(SPI1_SCK_PIN), .miso = IO_TAG(SPI1_MISO_PIN), .mosi = IO_TAG(SPI1_MOSI_PIN), .rcc = RCC_APB2(SPI1), .af = GPIO_AF_SPI1, .leadingEdge = false, .divisorMap = spiDivisorMapFast },
{ .dev = SPI2, .nss = IO_TAG(SPI2_NSS_PIN), .sck = IO_TAG(SPI2_SCK_PIN), .miso = IO_TAG(SPI2_MISO_PIN), .mosi = IO_TAG(SPI2_MOSI_PIN), .rcc = RCC_APB1(SPI2), .af = GPIO_AF_SPI2, .leadingEdge = false, .divisorMap = spiDivisorMapSlow },
{ .dev = SPI3, .nss = IO_TAG(SPI3_NSS_PIN), .sck = IO_TAG(SPI3_SCK_PIN), .miso = IO_TAG(SPI3_MISO_PIN), .mosi = IO_TAG(SPI3_MOSI_PIN), .rcc = RCC_APB1(SPI3), .af = GPIO_AF_SPI3, .leadingEdge = false, .divisorMap = spiDivisorMapSlow }
};
#elif defined(STM32F4)
static const uint16_t spiDivisorMapFast[] = {
SPI_BaudRatePrescaler_256, // SPI_CLOCK_INITIALIZATON 328.125 KBits/s
@ -95,6 +102,7 @@ static const uint16_t spiDivisorMapFast[] = {
SPI_BaudRatePrescaler_4, // SPI_CLOCK_FAST 21.0 MBits/s
SPI_BaudRatePrescaler_2 // SPI_CLOCK_ULTRAFAST 42.0 MBits/s
};
static const uint16_t spiDivisorMapSlow[] = {
SPI_BaudRatePrescaler_256, // SPI_CLOCK_INITIALIZATON 164.062 KBits/s
SPI_BaudRatePrescaler_64, // SPI_CLOCK_SLOW 656.25 KBits/s
@ -102,18 +110,16 @@ static const uint16_t spiDivisorMapSlow[] = {
SPI_BaudRatePrescaler_2, // SPI_CLOCK_FAST 21.0 MBits/s
SPI_BaudRatePrescaler_2 // SPI_CLOCK_ULTRAFAST 21.0 MBits/s
};
static spiDevice_t spiHardwareMap[] = {
{ .dev = SPI1, .nss = IO_TAG(SPI1_NSS_PIN), .sck = IO_TAG(SPI1_SCK_PIN), .miso = IO_TAG(SPI1_MISO_PIN), .mosi = IO_TAG(SPI1_MOSI_PIN), .rcc = RCC_APB2(SPI1), .af = GPIO_AF_SPI1, .leadingEdge = false, .divisorMap = spiDivisorMapFast },
{ .dev = SPI2, .nss = IO_TAG(SPI2_NSS_PIN), .sck = IO_TAG(SPI2_SCK_PIN), .miso = IO_TAG(SPI2_MISO_PIN), .mosi = IO_TAG(SPI2_MOSI_PIN), .rcc = RCC_APB1(SPI2), .af = GPIO_AF_SPI2, .leadingEdge = false, .divisorMap = spiDivisorMapSlow },
{ .dev = SPI3, .nss = IO_TAG(SPI3_NSS_PIN), .sck = IO_TAG(SPI3_SCK_PIN), .miso = IO_TAG(SPI3_MISO_PIN), .mosi = IO_TAG(SPI3_MOSI_PIN), .rcc = RCC_APB1(SPI3), .af = GPIO_AF_SPI3, .leadingEdge = false, .divisorMap = spiDivisorMapSlow }
};
#else
#error "Invalid CPU"
#endif
static spiDevice_t spiHardwareMap[] = {
{ .dev = SPI1, .nss = IO_TAG(SPI1_NSS_PIN), .sck = IO_TAG(SPI1_SCK_PIN), .miso = IO_TAG(SPI1_MISO_PIN), .mosi = IO_TAG(SPI1_MOSI_PIN), .rcc = RCC_APB2(SPI1), .af = GPIO_AF_SPI1, false, .divisorMap = spiDivisorMapFast },
{ .dev = SPI2, .nss = IO_TAG(SPI2_NSS_PIN), .sck = IO_TAG(SPI2_SCK_PIN), .miso = IO_TAG(SPI2_MISO_PIN), .mosi = IO_TAG(SPI2_MOSI_PIN), .rcc = RCC_APB1(SPI2), .af = GPIO_AF_SPI2, false, .divisorMap = spiDivisorMapSlow },
#if defined(STM32F3) || defined(STM32F4)
{ .dev = SPI3, .nss = IO_TAG(SPI3_NSS_PIN), .sck = IO_TAG(SPI3_SCK_PIN), .miso = IO_TAG(SPI3_MISO_PIN), .mosi = IO_TAG(SPI3_MOSI_PIN), .rcc = RCC_APB1(SPI3), .af = GPIO_AF_SPI3, false, .divisorMap = spiDivisorMapSlow }
#endif
};
SPIDevice spiDeviceByInstance(SPI_TypeDef *instance)
{
if (instance == SPI1)

View file

@ -70,22 +70,16 @@ typedef struct SPIDevice_s {
ioTag_t miso;
rccPeriphTag_t rcc;
uint8_t af;
volatile uint16_t errorCount;
bool leadingEdge;
#if defined(STM32F7)
SPI_HandleTypeDef hspi;
DMA_HandleTypeDef hdma;
dmaTag_t dmaTag;
#endif
const uint16_t * divisorMap;
volatile uint16_t errorCount;
} spiDevice_t;
bool spiInit(SPIDevice device);
bool spiIsBusBusy(SPI_TypeDef *instance);
void spiSetSpeed(SPI_TypeDef *instance, SPIClockSpeed_e speed);
uint8_t spiTransferByte(SPI_TypeDef *instance, uint8_t in);
bool spiIsBusBusy(SPI_TypeDef *instance);
bool spiTransfer(SPI_TypeDef *instance, uint8_t *out, const uint8_t *in, int len);
bool spiTransfer(SPI_TypeDef *instance, uint8_t *rxData, const uint8_t *txData, int len);
uint16_t spiGetErrorCounter(SPI_TypeDef *instance);
void spiResetErrorCounter(SPI_TypeDef *instance);

View file

@ -68,26 +68,47 @@
#define SPI4_NSS_PIN NONE
#endif
#if defined(SPI1_USE_DMA)
#define SPI1_USETXDMA true
#else
#define SPI1_USETXDMA false
#endif
#if defined(SPI2_USE_DMA)
#define SPI2_USETXDMA true
#else
#define SPI2_USETXDMA false
#endif
#if defined(SPI3_USE_DMA)
#define SPI3_USETXDMA true
#else
#define SPI3_USETXDMA false
#endif
#if defined(SPI4_USE_DMA)
#define SPI4_USETXDMA true
#else
#define SPI4_USETXDMA false
#endif
static const uint16_t spiDivisorMapFast[] = {
SPI_BAUDRATEPRESCALER_256, // SPI_CLOCK_INITIALIZATON 421.875 KBits/s
SPI_BAUDRATEPRESCALER_128, // SPI_CLOCK_SLOW 843.75 KBits/s
SPI_BAUDRATEPRESCALER_16, // SPI_CLOCK_STANDARD 6.75 MBits/s
SPI_BAUDRATEPRESCALER_8, // SPI_CLOCK_FAST 13.5 MBits/s
SPI_BAUDRATEPRESCALER_4 // SPI_CLOCK_ULTRAFAST 27.0 MBits/s
LL_SPI_BAUDRATEPRESCALER_DIV256, // SPI_CLOCK_INITIALIZATON 421.875 KBits/s
LL_SPI_BAUDRATEPRESCALER_DIV32, // SPI_CLOCK_SLOW 843.75 KBits/s
LL_SPI_BAUDRATEPRESCALER_DIV16, // SPI_CLOCK_STANDARD 6.75 MBits/s
LL_SPI_BAUDRATEPRESCALER_DIV8, // SPI_CLOCK_FAST 13.5 MBits/s
LL_SPI_BAUDRATEPRESCALER_DIV4 // SPI_CLOCK_ULTRAFAST 27.0 MBits/s
};
static const uint16_t spiDivisorMapSlow[] = {
SPI_BAUDRATEPRESCALER_256, // SPI_CLOCK_INITIALIZATON 210.937 KBits/s
SPI_BAUDRATEPRESCALER_64, // SPI_CLOCK_SLOW 843.75 KBits/s
SPI_BAUDRATEPRESCALER_8, // SPI_CLOCK_STANDARD 6.75 MBits/s
SPI_BAUDRATEPRESCALER_4, // SPI_CLOCK_FAST 13.5 MBits/s
SPI_BAUDRATEPRESCALER_2 // SPI_CLOCK_ULTRAFAST 27.0 MBits/s
LL_SPI_BAUDRATEPRESCALER_DIV256, // SPI_CLOCK_INITIALIZATON 210.937 KBits/s
LL_SPI_BAUDRATEPRESCALER_DIV64, // SPI_CLOCK_SLOW 843.75 KBits/s
LL_SPI_BAUDRATEPRESCALER_DIV8, // SPI_CLOCK_STANDARD 6.75 MBits/s
LL_SPI_BAUDRATEPRESCALER_DIV4, // SPI_CLOCK_FAST 13.5 MBits/s
LL_SPI_BAUDRATEPRESCALER_DIV2 // SPI_CLOCK_ULTRAFAST 27.0 MBits/s
};
static spiDevice_t spiHardwareMap[] = {
{ .dev = SPI1, .nss = IO_TAG(SPI1_NSS_PIN), .sck = IO_TAG(SPI1_SCK_PIN), .miso = IO_TAG(SPI1_MISO_PIN), .mosi = IO_TAG(SPI1_MOSI_PIN), .rcc = RCC_APB2(SPI1), .af = GPIO_AF5_SPI1, .leadingEdge = false, .dmaTag = DMA_TAG(2,3,0), .divisorMap = spiDivisorMapFast },
{ .dev = SPI2, .nss = IO_TAG(SPI2_NSS_PIN), .sck = IO_TAG(SPI2_SCK_PIN), .miso = IO_TAG(SPI2_MISO_PIN), .mosi = IO_TAG(SPI2_MOSI_PIN), .rcc = RCC_APB1(SPI2), .af = GPIO_AF5_SPI2, .leadingEdge = false, .dmaTag = DMA_TAG(1,4,0), .divisorMap = spiDivisorMapSlow },
{ .dev = SPI3, .nss = IO_TAG(SPI3_NSS_PIN), .sck = IO_TAG(SPI3_SCK_PIN), .miso = IO_TAG(SPI3_MISO_PIN), .mosi = IO_TAG(SPI3_MOSI_PIN), .rcc = RCC_APB1(SPI3), .af = GPIO_AF6_SPI3, .leadingEdge = false, .dmaTag = DMA_TAG(1,7,0), .divisorMap = spiDivisorMapSlow },
{ .dev = SPI4, .nss = IO_TAG(SPI4_NSS_PIN), .sck = IO_TAG(SPI4_SCK_PIN), .miso = IO_TAG(SPI4_MISO_PIN), .mosi = IO_TAG(SPI4_MOSI_PIN), .rcc = RCC_APB2(SPI4), .af = GPIO_AF5_SPI4, .leadingEdge = false, .dmaTag = DMA_TAG(2,1,0), .divisorMap = spiDivisorMapSlow }
{ .dev = SPI1, .nss = IO_TAG(SPI1_NSS_PIN), .sck = IO_TAG(SPI1_SCK_PIN), .miso = IO_TAG(SPI1_MISO_PIN), .mosi = IO_TAG(SPI1_MOSI_PIN), .rcc = RCC_APB2(SPI1), .af = GPIO_AF5_SPI1, .leadingEdge = false, .divisorMap = spiDivisorMapFast },
{ .dev = SPI2, .nss = IO_TAG(SPI2_NSS_PIN), .sck = IO_TAG(SPI2_SCK_PIN), .miso = IO_TAG(SPI2_MISO_PIN), .mosi = IO_TAG(SPI2_MOSI_PIN), .rcc = RCC_APB1(SPI2), .af = GPIO_AF5_SPI2, .leadingEdge = false, .divisorMap = spiDivisorMapSlow },
{ .dev = SPI3, .nss = IO_TAG(SPI3_NSS_PIN), .sck = IO_TAG(SPI3_SCK_PIN), .miso = IO_TAG(SPI3_MISO_PIN), .mosi = IO_TAG(SPI3_MOSI_PIN), .rcc = RCC_APB1(SPI3), .af = GPIO_AF6_SPI3, .leadingEdge = false, .divisorMap = spiDivisorMapSlow },
{ .dev = SPI4, .nss = IO_TAG(SPI4_NSS_PIN), .sck = IO_TAG(SPI4_SCK_PIN), .miso = IO_TAG(SPI4_MISO_PIN), .mosi = IO_TAG(SPI4_MOSI_PIN), .rcc = RCC_APB2(SPI4), .af = GPIO_AF5_SPI4, .leadingEdge = false, .divisorMap = spiDivisorMapSlow }
};
SPIDevice spiDeviceByInstance(SPI_TypeDef *instance)
@ -107,46 +128,34 @@ SPIDevice spiDeviceByInstance(SPI_TypeDef *instance)
return SPIINVALID;
}
SPI_HandleTypeDef* spiHandleByInstance(SPI_TypeDef *instance)
void spiTimeoutUserCallback(SPI_TypeDef *instance)
{
return &spiHardwareMap[spiDeviceByInstance(instance)].hspi;
SPIDevice device = spiDeviceByInstance(instance);
if (device == SPIINVALID) {
return;
}
DMA_HandleTypeDef* dmaHandleByInstance(SPI_TypeDef *instance)
{
return &spiHardwareMap[spiDeviceByInstance(instance)].hdma;
spiHardwareMap[device].errorCount++;
}
void SPI1_IRQHandler(void)
{
HAL_SPI_IRQHandler(&spiHardwareMap[SPIDEV_1].hspi);
}
void SPI2_IRQHandler(void)
{
HAL_SPI_IRQHandler(&spiHardwareMap[SPIDEV_2].hspi);
}
void SPI3_IRQHandler(void)
{
HAL_SPI_IRQHandler(&spiHardwareMap[SPIDEV_3].hspi);
}
void SPI4_IRQHandler(void)
{
HAL_SPI_IRQHandler(&spiHardwareMap[SPIDEV_4].hspi);
}
void spiInitDevice(SPIDevice device)
{
spiDevice_t *spi = &(spiHardwareMap[device]);
if (!spi->dev) {
return;
}
#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);
@ -156,7 +165,6 @@ void spiInitDevice(SPIDevice device)
IOInit(IOGetByTag(spi->miso), OWNER_SPI, RESOURCE_SPI_MISO, device + 1);
IOInit(IOGetByTag(spi->mosi), OWNER_SPI, RESOURCE_SPI_MOSI, device + 1);
#if defined(STM32F3) || defined(STM32F4) || defined(STM32F7)
if (spi->leadingEdge == true) {
IOConfigGPIOAF(IOGetByTag(spi->sck), SPI_IO_AF_SCK_CFG_LOW, spi->af);
} else {
@ -169,36 +177,32 @@ void spiInitDevice(SPIDevice device)
IOInit(IOGetByTag(spi->nss), OWNER_SPI, RESOURCE_SPI_CS, device + 1);
IOConfigGPIO(IOGetByTag(spi->nss), SPI_IO_CS_CFG);
}
#endif
spiHardwareMap[device].hspi.Instance = spi->dev;
// Init SPI hardware
HAL_SPI_DeInit(&spiHardwareMap[device].hspi);
LL_SPI_Disable(spi->dev);
LL_SPI_DeInit(spi->dev);
spiHardwareMap[device].hspi.Init.Mode = SPI_MODE_MASTER;
spiHardwareMap[device].hspi.Init.Direction = SPI_DIRECTION_2LINES;
spiHardwareMap[device].hspi.Init.DataSize = SPI_DATASIZE_8BIT;
spiHardwareMap[device].hspi.Init.NSS = SPI_NSS_SOFT;
spiHardwareMap[device].hspi.Init.FirstBit = SPI_FIRSTBIT_MSB;
spiHardwareMap[device].hspi.Init.CRCPolynomial = 7;
spiHardwareMap[device].hspi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;
spiHardwareMap[device].hspi.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
spiHardwareMap[device].hspi.Init.TIMode = SPI_TIMODE_DISABLED;
LL_SPI_InitTypeDef init =
{
.TransferDirection = SPI_DIRECTION_2LINES,
.Mode = SPI_MODE_MASTER,
.DataWidth = SPI_DATASIZE_8BIT,
.ClockPolarity = spi->leadingEdge ? SPI_POLARITY_LOW : SPI_POLARITY_HIGH,
.ClockPhase = spi->leadingEdge ? SPI_PHASE_1EDGE : SPI_PHASE_2EDGE,
.NSS = SPI_NSS_SOFT,
.BaudRate = SPI_BAUDRATEPRESCALER_8,
.BitOrder = SPI_FIRSTBIT_MSB,
.CRCPoly = 7,
.CRCCalculation = SPI_CRCCALCULATION_DISABLE,
};
LL_SPI_SetRxFIFOThreshold(spi->dev, SPI_RXFIFO_THRESHOLD_QF);
if (spi->leadingEdge) {
spiHardwareMap[device].hspi.Init.CLKPolarity = SPI_POLARITY_LOW;
spiHardwareMap[device].hspi.Init.CLKPhase = SPI_PHASE_1EDGE;
} else {
spiHardwareMap[device].hspi.Init.CLKPolarity = SPI_POLARITY_HIGH;
spiHardwareMap[device].hspi.Init.CLKPhase = SPI_PHASE_2EDGE;
}
LL_SPI_Init(spi->dev, &init);
LL_SPI_Enable(spi->dev);
if (HAL_SPI_Init(&spiHardwareMap[device].hspi) == HAL_OK) {
if (spi->nss) {
IOHi(IOGetByTag(spi->nss));
}
}
}
bool spiInit(SPIDevice device)
{
@ -238,20 +242,28 @@ bool spiInit(SPIDevice device)
return false;
}
uint32_t spiTimeoutUserCallback(SPI_TypeDef *instance)
uint8_t spiTransferByte(SPI_TypeDef *instance, uint8_t txByte)
{
SPIDevice device = spiDeviceByInstance(instance);
if (device == SPIINVALID)
return -1;
spiHardwareMap[device].errorCount++;
return spiHardwareMap[device].errorCount;
uint16_t spiTimeout = 1000;
while (!LL_SPI_IsActiveFlag_TXE(instance)) {
if ((spiTimeout--) == 0) {
spiTimeoutUserCallback(instance);
return 0xFF;
}
}
// return uint8_t value or -1 when failure
uint8_t spiTransferByte(SPI_TypeDef *instance, uint8_t in)
{
spiTransfer(instance, &in, &in, 1);
return in;
LL_SPI_TransmitData8(instance, txByte);
spiTimeout = 1000;
while (!LL_SPI_IsActiveFlag_RXNE(instance)) {
if ((spiTimeout--) == 0) {
spiTimeoutUserCallback(instance);
return 0xFF;
}
}
return (uint8_t)LL_SPI_ReceiveData8(instance);
}
/**
@ -259,108 +271,46 @@ uint8_t spiTransferByte(SPI_TypeDef *instance, uint8_t in)
*/
bool spiIsBusBusy(SPI_TypeDef *instance)
{
SPIDevice device = spiDeviceByInstance(instance);
if (spiHardwareMap[device].hspi.State == HAL_SPI_STATE_BUSY)
return true;
else
return (LL_SPI_GetTxFIFOLevel(instance) != LL_SPI_TX_FIFO_EMPTY) || LL_SPI_IsActiveFlag_BSY(instance);
}
bool spiTransfer(SPI_TypeDef *instance, uint8_t *rxData, const uint8_t *txData, int len)
{
SET_BIT(instance->CR2, SPI_RXFIFO_THRESHOLD);
while (len) {
int spiTimeout = 1000;
while (!LL_SPI_IsActiveFlag_TXE(instance)) {
if ((spiTimeout--) == 0) {
spiTimeoutUserCallback(instance);
return false;
}
bool spiTransfer(SPI_TypeDef *instance, uint8_t *out, const uint8_t *in, int len)
{
SPIDevice device = spiDeviceByInstance(instance);
HAL_StatusTypeDef status;
#define SPI_DEFAULT_TIMEOUT 10
if (!out) // Tx only
{
status = HAL_SPI_Transmit(&spiHardwareMap[device].hspi, (uint8_t *)in, len, SPI_DEFAULT_TIMEOUT);
}
else if (!in) // Rx only
{
status = HAL_SPI_Receive(&spiHardwareMap[device].hspi, out, len, SPI_DEFAULT_TIMEOUT);
}
else // Tx and Rx
{
status = HAL_SPI_TransmitReceive(&spiHardwareMap[device].hspi, (uint8_t *)in, out, len, SPI_DEFAULT_TIMEOUT);
}
uint8_t b = txData ? *(txData++) : 0xFF;
LL_SPI_TransmitData8(instance, b);
if ( status != HAL_OK)
spiTimeout = 1000;
while (!LL_SPI_IsActiveFlag_RXNE(instance)) {
if ((spiTimeout--) == 0) {
spiTimeoutUserCallback(instance);
return false;
}
}
b = LL_SPI_ReceiveData8(instance);
if (rxData) {
*(rxData++) = b;
}
--len;
}
return true;
}
void spiSetSpeed(SPI_TypeDef *instance, SPIClockSpeed_e speed)
{
SPIDevice device = spiDeviceByInstance(instance);
HAL_SPI_DeInit(&spiHardwareMap[device].hspi);
spiHardwareMap[device].hspi.Init.BaudRatePrescaler = spiHardwareMap[device].divisorMap[speed];
HAL_SPI_Init(&spiHardwareMap[device].hspi);
}
uint16_t spiGetErrorCounter(SPI_TypeDef *instance)
{
SPIDevice device = spiDeviceByInstance(instance);
if (device == SPIINVALID)
return 0;
return spiHardwareMap[device].errorCount;
}
void spiResetErrorCounter(SPI_TypeDef *instance)
{
SPIDevice device = spiDeviceByInstance(instance);
if (device != SPIINVALID)
spiHardwareMap[device].errorCount = 0;
}
void dmaSPIIRQHandler(dmaChannelDescriptor_t* descriptor)
{
SPIDevice device = descriptor->userParam;
if (device != SPIINVALID)
HAL_DMA_IRQHandler(&spiHardwareMap[device].hdma);
}
DMA_HandleTypeDef* spiSetDMATransmit(DMA_Stream_TypeDef *Stream, uint32_t Channel, SPI_TypeDef *Instance, uint8_t *pData, uint16_t Size)
{
SPIDevice device = spiDeviceByInstance(Instance);
spiHardwareMap[device].hdma.Instance = Stream;
spiHardwareMap[device].hdma.Init.Channel = Channel;
spiHardwareMap[device].hdma.Init.Direction = DMA_MEMORY_TO_PERIPH;
spiHardwareMap[device].hdma.Init.PeriphInc = DMA_PINC_DISABLE;
spiHardwareMap[device].hdma.Init.MemInc = DMA_MINC_ENABLE;
spiHardwareMap[device].hdma.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
spiHardwareMap[device].hdma.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
spiHardwareMap[device].hdma.Init.Mode = DMA_NORMAL;
spiHardwareMap[device].hdma.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
spiHardwareMap[device].hdma.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_1QUARTERFULL;
spiHardwareMap[device].hdma.Init.PeriphBurst = DMA_PBURST_SINGLE;
spiHardwareMap[device].hdma.Init.MemBurst = DMA_MBURST_SINGLE;
spiHardwareMap[device].hdma.Init.Priority = DMA_PRIORITY_LOW;
HAL_DMA_DeInit(&spiHardwareMap[device].hdma);
HAL_DMA_Init(&spiHardwareMap[device].hdma);
__HAL_DMA_ENABLE(&spiHardwareMap[device].hdma);
__HAL_SPI_ENABLE(&spiHardwareMap[device].hspi);
/* Associate the initialized DMA handle to the spi handle */
__HAL_LINKDMA(&spiHardwareMap[device].hspi, hdmatx, spiHardwareMap[device].hdma);
// DMA TX Interrupt
dmaSetHandler(dmaGetByTag(spiHardwareMap[device].dmaTag), dmaSPIIRQHandler, NVIC_BUILD_PRIORITY(3, 0), (uint32_t)device);
//HAL_CLEANCACHE(pData,Size);
// And Transmit
HAL_SPI_Transmit_DMA(&spiHardwareMap[device].hspi, pData, Size);
return &spiHardwareMap[device].hdma;
LL_SPI_Disable(instance);
LL_SPI_SetBaudRatePrescaler(instance, spiHardwareMap[device].divisorMap[speed]);
LL_SPI_Enable(instance);
}
SPI_TypeDef * spiInstanceByDevice(SPIDevice device)

View file

@ -148,6 +148,7 @@ DMA_t dmaFindHandlerIdentifier(DMA_Channel_TypeDef* channel);
DMA_t dmaGetByTag(dmaTag_t tag);
uint32_t dmaGetChannelByTag(dmaTag_t tag);
resourceOwner_e dmaGetOwner(DMA_t dma);
void dmaInit(DMA_t dma, resourceOwner_e owner, uint8_t resourceIndex);
void dmaEnableClock(DMA_t dma);
void dmaSetHandler(DMA_t dma, dmaCallbackHandlerFuncPtr callback, uint32_t priority, uint32_t userParam);

View file

@ -78,6 +78,11 @@ void dmaEnableClock(DMA_t dma)
RCC_AHBPeriphClockCmd(dma->rcc, ENABLE);
}
resourceOwner_e dmaGetOwner(DMA_t dma)
{
return dma->owner;
}
void dmaInit(DMA_t dma, resourceOwner_e owner, uint8_t resourceIndex)
{
dmaEnableClock(dma);

View file

@ -86,6 +86,11 @@ void dmaEnableClock(DMA_t dma)
RCC_AHB1PeriphClockCmd(dma->rcc, ENABLE);
}
resourceOwner_e dmaGetOwner(DMA_t dma)
{
return dma->owner;
}
void dmaInit(DMA_t dma, resourceOwner_e owner, uint8_t resourceIndex)
{
dmaEnableClock(dma);

View file

@ -91,6 +91,11 @@ void dmaEnableClock(DMA_t dma)
} while (0);
}
resourceOwner_e dmaGetOwner(DMA_t dma)
{
return dma->owner;
}
void dmaInit(DMA_t dma, resourceOwner_e owner, uint8_t resourceIndex)
{
dmaEnableClock(dma);

View file

@ -51,10 +51,8 @@
#define SDCARD_TIMEOUT_INIT_MILLIS 200
#define SDCARD_MAX_CONSECUTIVE_FAILURES 8
/* Break up 512-byte SD card sectors into chunks of this size when writing without DMA to reduce the peak overhead
* per call to sdcard_poll().
*/
#define SDCARD_NON_DMA_CHUNK_SIZE 256
/* Break up 512-byte SD card sectors into chunks of this size to reduce the peak overhead per call to sdcard_poll(). */
#define SDCARD_BLOCK_CHUNK_SIZE 128
#ifndef SDCARD_SPI_CLOCK
#define SDCARD_SPI_CLOCK SPI_CLOCK_STANDARD
@ -84,10 +82,6 @@ typedef struct sdcard_t {
sdcard_operationCompleteCallback_c callback;
uint32_t callbackData;
#ifdef SDCARD_PROFILING
timeUs_t profileStartTime;
#endif
} pendingOperation;
uint32_t operationStartTime;
@ -104,10 +98,6 @@ typedef struct sdcard_t {
sdcardMetadata_t metadata;
sdcardCSD_t csd;
#ifdef SDCARD_PROFILING
sdcard_profilerCallback_c profiler;
#endif
} sdcard_t;
static sdcard_t sdcard;
@ -407,7 +397,6 @@ static void sdcard_sendDataBlockBegin(uint8_t *buffer, bool multiBlockWrite)
{
// Card wants 8 dummy clock cycles between the write command's response and a data block beginning:
spiTransferByte(SDCARD_SPI_INSTANCE, 0xFF);
spiTransferByte(SDCARD_SPI_INSTANCE, multiBlockWrite ? SDCARD_MULTIPLE_BLOCK_WRITE_START_TOKEN : SDCARD_SINGLE_BLOCK_WRITE_START_TOKEN);
// Send the first chunk now
@ -500,7 +489,7 @@ static bool sdcard_checkInitDone(void)
/**
* Begin the initialization process for the SD card. This must be called first before any other sdcard_ routine.
*/
void sdcard_init(bool useDMA)
void sdcard_init(void)
{
#ifdef SDCARD_SPI_CS_PIN
sdCardCsPin = IOGetByTag(IO_TAG(SDCARD_SPI_CS_PIN));
@ -537,9 +526,7 @@ void sdcard_init(bool useDMA)
static bool sdcard_setBlockLength(uint32_t blockLen)
{
sdcard_select();
uint8_t status = sdcard_sendCommand(SDCARD_COMMAND_SET_BLOCKLEN, blockLen);
sdcard_deselect();
return status == 0;
@ -594,10 +581,6 @@ bool sdcard_poll(void)
uint8_t initStatus;
bool sendComplete;
#ifdef SDCARD_PROFILING
bool profilingComplete;
#endif
doMore:
switch (sdcard.state) {
case SDCARD_STATE_RESET:
@ -682,9 +665,9 @@ bool sdcard_poll(void)
sendComplete = false;
// Send another chunk
spiTransfer(SDCARD_SPI_INSTANCE, NULL, sdcard.pendingOperation.buffer + SDCARD_NON_DMA_CHUNK_SIZE * sdcard.pendingOperation.chunkIndex, SDCARD_NON_DMA_CHUNK_SIZE);
spiTransfer(SDCARD_SPI_INSTANCE, NULL, sdcard.pendingOperation.buffer + SDCARD_BLOCK_CHUNK_SIZE * sdcard.pendingOperation.chunkIndex, SDCARD_BLOCK_CHUNK_SIZE);
sdcard.pendingOperation.chunkIndex++;
sendComplete = sdcard.pendingOperation.chunkIndex == SDCARD_BLOCK_SIZE / SDCARD_NON_DMA_CHUNK_SIZE;
sendComplete = sdcard.pendingOperation.chunkIndex == SDCARD_BLOCK_SIZE / SDCARD_BLOCK_CHUNK_SIZE;
if (sendComplete) {
// Finish up by sending the CRC and checking the SD-card's acceptance/rejectance
@ -714,10 +697,6 @@ bool sdcard_poll(void)
break;
case SDCARD_STATE_WAITING_FOR_WRITE:
if (sdcard_waitForIdle(SDCARD_MAXIMUM_BYTE_DELAY_FOR_CMD_REPLY)) {
#ifdef SDCARD_PROFILING
profilingComplete = true;
#endif
sdcard.failureCount = 0; // Assume the card is good if it can complete a write
// Still more blocks left to write in a multi-block chain?
@ -729,22 +708,11 @@ bool sdcard_poll(void)
// This function changes the sd card state for us whether immediately succesful or delayed:
if (sdcard_endWriteBlocks() == SDCARD_OPERATION_SUCCESS) {
sdcard_deselect();
} else {
#ifdef SDCARD_PROFILING
// Wait for the multi-block write to be terminated before finishing timing
profilingComplete = false;
#endif
}
} else {
sdcard.state = SDCARD_STATE_READY;
sdcard_deselect();
}
#ifdef SDCARD_PROFILING
if (profilingComplete && sdcard.profiler) {
sdcard.profiler(SDCARD_BLOCK_OPERATION_WRITE, sdcard.pendingOperation.blockIndex, micros() - sdcard.pendingOperation.profileStartTime);
}
#endif
} else if (millis() > sdcard.operationStartTime + SDCARD_TIMEOUT_WRITE_MSEC) {
/*
* The caller has already been told that their write has completed, so they will have discarded
@ -763,12 +731,6 @@ bool sdcard_poll(void)
sdcard.state = SDCARD_STATE_READY;
sdcard.failureCount = 0; // Assume the card is good if it can complete a read
#ifdef SDCARD_PROFILING
if (sdcard.profiler) {
sdcard.profiler(SDCARD_BLOCK_OPERATION_READ, sdcard.pendingOperation.blockIndex, micros() - sdcard.pendingOperation.profileStartTime);
}
#endif
if (sdcard.pendingOperation.callback) {
sdcard.pendingOperation.callback(
SDCARD_BLOCK_OPERATION_READ,
@ -808,12 +770,6 @@ bool sdcard_poll(void)
sdcard_deselect();
sdcard.state = SDCARD_STATE_READY;
#ifdef SDCARD_PROFILING
if (sdcard.profiler) {
sdcard.profiler(SDCARD_BLOCK_OPERATION_WRITE, sdcard.pendingOperation.blockIndex, micros() - sdcard.pendingOperation.profileStartTime);
}
#endif
} else if (millis() > sdcard.operationStartTime + SDCARD_TIMEOUT_WRITE_MSEC) {
sdcard_reset();
goto doMore;
@ -851,10 +807,6 @@ sdcardOperationStatus_e sdcard_writeBlock(uint32_t blockIndex, uint8_t *buffer,
{
uint8_t status;
#ifdef SDCARD_PROFILING
sdcard.pendingOperation.profileStartTime = micros();
#endif
doMore:
switch (sdcard.state) {
case SDCARD_STATE_WRITING_MULTIPLE_BLOCKS:
@ -895,7 +847,7 @@ sdcardOperationStatus_e sdcard_writeBlock(uint32_t blockIndex, uint8_t *buffer,
sdcard.pendingOperation.blockIndex = blockIndex;
sdcard.pendingOperation.callback = callback;
sdcard.pendingOperation.callbackData = callbackData;
sdcard.pendingOperation.chunkIndex = 1; // (for non-DMA transfers) we've sent chunk #0 already
sdcard.pendingOperation.chunkIndex = 1;
sdcard.state = SDCARD_STATE_SENDING_WRITE;
return SDCARD_OPERATION_IN_PROGRESS;
@ -974,10 +926,6 @@ bool sdcard_readBlock(uint32_t blockIndex, uint8_t *buffer, sdcard_operationComp
}
}
#ifdef SDCARD_PROFILING
sdcard.pendingOperation.profileStartTime = micros();
#endif
sdcard_select();
// Standard size cards use byte addressing, high capacity cards use block addressing
@ -1016,13 +964,4 @@ const sdcardMetadata_t* sdcard_getMetadata(void)
return &sdcard.metadata;
}
#ifdef SDCARD_PROFILING
void sdcard_setProfilerCallback(sdcard_profilerCallback_c callback)
{
sdcard.profiler = callback;
}
#endif
#endif

View file

@ -53,7 +53,7 @@ typedef void(*sdcard_operationCompleteCallback_c)(sdcardBlockOperation_e operati
typedef void(*sdcard_profilerCallback_c)(sdcardBlockOperation_e operation, uint32_t blockIndex, uint32_t duration);
void sdcard_init(bool useDMA);
void sdcard_init(void);
bool sdcard_readBlock(uint32_t blockIndex, uint8_t *buffer, sdcard_operationCompleteCallback_c callback, uint32_t callbackData);

View file

@ -610,27 +610,8 @@ void init(void)
#endif
#ifdef USE_SDCARD
bool sdcardUseDMA = false;
sdcardInsertionDetectInit();
#ifdef SDCARD_DMA_CHANNEL_TX
#if defined(USE_LED_STRIP) && defined(WS2811_DMA_CHANNEL)
// Ensure the SPI Tx DMA doesn't overlap with the led strip
#if defined(STM32F4) || defined(STM32F7)
sdcardUseDMA = !feature(FEATURE_LED_STRIP) || SDCARD_DMA_CHANNEL_TX != WS2811_DMA_STREAM;
#else
sdcardUseDMA = !feature(FEATURE_LED_STRIP) || SDCARD_DMA_CHANNEL_TX != WS2811_DMA_CHANNEL;
#endif
#else
sdcardUseDMA = true;
#endif
#endif
sdcard_init(sdcardUseDMA);
sdcard_init();
afatfs_init();
#endif

View file

@ -418,11 +418,6 @@ typedef enum {
AFATFS_INITIALIZATION_FREEFILE_LAST = AFATFS_INITIALIZATION_FREEFILE_SAVE_DIR_ENTRY,
#endif
#ifdef AFATFS_USE_INTROSPECTIVE_LOGGING
AFATFS_INITIALIZATION_INTROSPEC_LOG_CREATE,
AFATFS_INITIALIZATION_INTROSPEC_LOG_CREATING,
#endif
AFATFS_INITIALIZATION_DONE
} afatfsInitializationPhase_e;
@ -453,10 +448,6 @@ typedef struct afatfs_t {
afatfsFile_t freeFile;
#endif
#ifdef AFATFS_USE_INTROSPECTIVE_LOGGING
afatfsFile_t introSpecLog;
#endif
afatfsError_e lastError;
bool filesystemFull;
@ -3225,10 +3216,6 @@ static void afatfs_fileOperationsPoll(void)
{
afatfs_fileOperationContinue(&afatfs.currentDirectory);
#ifdef AFATFS_USE_INTROSPECTIVE_LOGGING
afatfs_fileOperationContinue(&afatfs.introSpecLog);
#endif
for (int i = 0; i < AFATFS_MAX_OPEN_FILES; i++) {
afatfs_fileOperationContinue(&afatfs.openFiles[i]);
}
@ -3357,20 +3344,6 @@ static void afatfs_freeFileCreated(afatfsFile_t *file)
#endif
#ifdef AFATFS_USE_INTROSPECTIVE_LOGGING
static void afatfs_introspecLogCreated(afatfsFile_t *file)
{
if (file) {
afatfs.initPhase++;
} else {
afatfs.lastError = AFATFS_ERROR_GENERIC;
afatfs.filesystemState = AFATFS_FILESYSTEM_STATE_FATAL;
}
}
#endif
static void afatfs_initContinue(void)
{
#ifdef AFATFS_USE_FREEFILE
@ -3479,18 +3452,6 @@ static void afatfs_initContinue(void)
break;
#endif
#ifdef AFATFS_USE_INTROSPECTIVE_LOGGING
case AFATFS_INITIALIZATION_INTROSPEC_LOG_CREATE:
afatfs.initPhase = AFATFS_INITIALIZATION_INTROSPEC_LOG_CREATING;
afatfs_createFile(&afatfs.introSpecLog, AFATFS_INTROSPEC_LOG_FILENAME, FAT_FILE_ATTRIBUTE_ARCHIVE,
AFATFS_FILE_MODE_CREATE | AFATFS_FILE_MODE_APPEND, afatfs_introspecLogCreated);
break;
case AFATFS_INITIALIZATION_INTROSPEC_LOG_CREATING:
afatfs_fileOperationContinue(&afatfs.introSpecLog);
break;
#endif
case AFATFS_INITIALIZATION_DONE:
afatfs.filesystemState = AFATFS_FILESYSTEM_STATE_READY;
break;
@ -3520,50 +3481,6 @@ void afatfs_poll(void)
}
}
#ifdef AFATFS_USE_INTROSPECTIVE_LOGGING
void afatfs_sdcardProfilerCallback(sdcardBlockOperation_e operation, uint32_t blockIndex, uint32_t duration)
{
// Make sure the log file has actually been opened before we try to log to it:
if (afatfs.introSpecLog.type == AFATFS_FILE_TYPE_NONE) {
return;
}
enum {
LOG_ENTRY_SIZE = 16 // Log entry size should be a power of two to avoid partial fwrites()
};
uint8_t buffer[LOG_ENTRY_SIZE];
buffer[0] = operation;
// Padding/reserved:
buffer[1] = 0;
buffer[2] = 0;
buffer[3] = 0;
buffer[4] = blockIndex & 0xFF;
buffer[5] = (blockIndex >> 8) & 0xFF;
buffer[6] = (blockIndex >> 16) & 0xFF;
buffer[7] = (blockIndex >> 24) & 0xFF;
buffer[8] = duration & 0xFF;
buffer[9] = (duration >> 8) & 0xFF;
buffer[10] = (duration >> 16) & 0xFF;
buffer[11] = (duration >> 24) & 0xFF;
// Padding/reserved:
buffer[12] = 0;
buffer[13] = 0;
buffer[14] = 0;
buffer[15] = 0;
// Ignore write failures
afatfs_fwrite(&afatfs.introSpecLog, buffer, LOG_ENTRY_SIZE);
}
#endif
afatfsFilesystemState_e afatfs_getFilesystemState(void)
{
return afatfs.filesystemState;
@ -3579,10 +3496,6 @@ void afatfs_init(void)
afatfs.filesystemState = AFATFS_FILESYSTEM_STATE_INITIALIZATION;
afatfs.initPhase = AFATFS_INITIALIZATION_READ_MBR;
afatfs.lastClusterAllocated = FAT_SMALLEST_LEGAL_CLUSTER_NUMBER;
#ifdef AFATFS_USE_INTROSPECTIVE_LOGGING
sdcard_setProfilerCallback(afatfs_sdcardProfilerCallback);
#endif
}
/**
@ -3604,13 +3517,6 @@ bool afatfs_destroy(bool dirty)
}
}
#ifdef AFATFS_USE_INTROSPECTIVE_LOGGING
if (afatfs.introSpecLog.type != AFATFS_FILE_TYPE_NONE) {
afatfs_fclose(&afatfs.introSpecLog, NULL);
openFileCount++;
}
#endif
#ifdef AFATFS_USE_FREEFILE
if (afatfs.freeFile.type != AFATFS_FILE_TYPE_NONE) {
afatfs_fclose(&afatfs.freeFile, NULL);

View file

@ -115,12 +115,6 @@
#define SDCARD_SPI_INSTANCE SPI3
#define SDCARD_SPI_CS_PIN PD2
#define SDCARD_DMA_CHANNEL_TX DMA1_Stream5
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA_FLAG_TCIF5 //DMA_FLAG_TCIF3_7
#define SDCARD_DMA_CLK RCC_AHB1Periph_DMA1
#define SDCARD_DMA_CHANNEL DMA_CHANNEL_0
// *************** UART *****************************
#define USE_VCP
#define USB_DETECT_PIN PC14