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

F7 first try on DMA SDCARD

This commit is contained in:
Sami Korhonen 2016-08-27 14:58:33 +03:00
parent 6e51f2f9b2
commit a399c14bf9
5 changed files with 123 additions and 10 deletions

View file

@ -92,3 +92,7 @@ uint16_t spiGetErrorCounter(SPI_TypeDef *instance);
void spiResetErrorCounter(SPI_TypeDef *instance);
SPIDevice spiDeviceByInstance(SPI_TypeDef *instance);
#if defined(USE_HAL_DRIVER)
SPI_HandleTypeDef* spiHandleByInstance(SPI_TypeDef *instance);
DMA_HandleTypeDef* spiSetDMATransmit(DMA_Stream_TypeDef *Stream, uint32_t Channel, SPI_TypeDef *Instance, uint8_t *pData, uint16_t Size);
#endif

View file

@ -23,8 +23,10 @@
#include "build_config.h"
#include "bus_spi.h"
#include "dma.h"
#include "io.h"
#include "io_impl.h"
#include "nvic.h"
#include "rcc.h"
#ifndef SPI1_SCK_PIN
@ -81,6 +83,10 @@ typedef struct{
}spiHandle_t;
static spiHandle_t spiHandle[SPIDEV_MAX+1];
typedef struct{
DMA_HandleTypeDef Handle;
}dmaHandle_t;
static dmaHandle_t dmaHandle[SPIDEV_MAX+1];
SPIDevice spiDeviceByInstance(SPI_TypeDef *instance)
{
@ -99,6 +105,16 @@ SPIDevice spiDeviceByInstance(SPI_TypeDef *instance)
return SPIINVALID;
}
SPI_HandleTypeDef* spiHandleByInstance(SPI_TypeDef *instance)
{
return &spiHandle[spiDeviceByInstance(instance)].Handle;
}
DMA_HandleTypeDef* dmaHandleByInstance(SPI_TypeDef *instance)
{
return &dmaHandle[spiDeviceByInstance(instance)].Handle;
}
void SPI1_IRQHandler(void)
{
HAL_SPI_IRQHandler(&spiHandle[SPIDEV_1].Handle);
@ -342,3 +358,71 @@ void spiResetErrorCounter(SPI_TypeDef *instance)
if (device != SPIINVALID)
spiHardwareMap[device].errorCount = 0;
}
void dmaSPIIRQHandler(dmaChannelDescriptor_t* descriptor)
{
DMA_HandleTypeDef * hdma = &dmaHandle[(descriptor->userParam)].Handle;
HAL_DMA_IRQHandler(hdma);
//SCB_InvalidateDCache_by_Addr();
/*if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_TCIF))
{
DMA_CLEAR_FLAG(descriptor, DMA_IT_TCIF);
DMA_CLEAR_FLAG(descriptor, DMA_IT_HTIF);
if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_FEIF))
{
DMA_CLEAR_FLAG(descriptor, DMA_IT_FEIF);
}
}
if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_TEIF))
{
DMA_CLEAR_FLAG(descriptor, DMA_IT_TEIF);
}
if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_DMEIF))
{
DMA_CLEAR_FLAG(descriptor, DMA_IT_DMEIF);
}*/
}
DMA_HandleTypeDef* spiSetDMATransmit(DMA_Stream_TypeDef *Stream, uint32_t Channel, SPI_TypeDef *Instance, uint8_t *pData, uint16_t Size)
{
SPI_HandleTypeDef* hspi = &spiHandle[spiDeviceByInstance(Instance)].Handle;
DMA_HandleTypeDef* hdma = &dmaHandle[spiDeviceByInstance(Instance)].Handle;
hdma->Instance = Stream;
hdma->Init.Channel = Channel;
hdma->Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma->Init.PeriphInc = DMA_PINC_DISABLE;
hdma->Init.MemInc = DMA_MINC_ENABLE;
hdma->Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma->Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma->Init.Mode = DMA_NORMAL;
hdma->Init.FIFOMode = DMA_FIFOMODE_DISABLE;
hdma->Init.FIFOThreshold = DMA_FIFO_THRESHOLD_1QUARTERFULL;
hdma->Init.PeriphBurst = DMA_PBURST_SINGLE;
hdma->Init.MemBurst = DMA_MBURST_SINGLE;
hdma->Init.Priority = DMA_PRIORITY_LOW;
HAL_DMA_DeInit(hdma);
HAL_DMA_Init(hdma);
__HAL_DMA_ENABLE(hdma);
__HAL_SPI_ENABLE(hspi);
/* Associate the initialized DMA handle to the spi handle */
__HAL_LINKDMA(hspi, hdmatx, (*hdma));
// DMA TX Interrupt
dmaSetHandler(DMA2_ST1_HANDLER, dmaSPIIRQHandler, NVIC_BUILD_PRIORITY(3, 0), (uint32_t)spiDeviceByInstance(Instance));
// SCB_CleanDCache_by_Addr((uint32_t) pData, Size);
HAL_SPI_Transmit_DMA(hspi, pData, Size);
//HAL_DMA_Start(&hdma, (uint32_t) pData, (uint32_t) &(Instance->DR), Size);
return hdma;
}

View file

@ -156,7 +156,7 @@ void EXTIRelease(IO_t io)
void EXTIEnable(IO_t io, bool enable)
{
#if defined(STM32F1) || defined(STM32F4)
#if defined(STM32F1) || defined(STM32F4) || defined(STM32F7)
uint32_t extiLine = IO_EXTI_Line(io);
if(!extiLine)
return;
@ -164,9 +164,6 @@ void EXTIEnable(IO_t io, bool enable)
EXTI->IMR |= extiLine;
else
EXTI->IMR &= ~extiLine;
#elif defined(STM32F7)
(void)io;
(void)enable;
#elif defined(STM32F303xC)
int extiLine = IO_EXTI_Line(io);
if(extiLine < 0)
@ -183,8 +180,6 @@ void EXTIEnable(IO_t io, bool enable)
void EXTI_IRQHandler(void)
{
//HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_4);
uint32_t exti_active = EXTI->IMR & EXTI->PR;
while(exti_active) {

View file

@ -108,6 +108,9 @@ static sdcard_t sdcard;
#ifdef SDCARD_DMA_CHANNEL_TX
static bool useDMAForTx;
#if defined(USE_HAL_DRIVER)
DMA_HandleTypeDef *sdDMAHandle;
#endif
#else
// DMA channel not available so we can hard-code this to allow the non-DMA paths to be stripped by optimization
static const bool useDMAForTx = false;
@ -413,6 +416,9 @@ static void sdcard_sendDataBlockBegin(uint8_t *buffer, bool multiBlockWrite)
if (useDMAForTx) {
#ifdef SDCARD_DMA_CHANNEL_TX
#if defined(USE_HAL_DRIVER)
sdDMAHandle = spiSetDMATransmit(SDCARD_DMA_CHANNEL_TX, SDCARD_DMA_CHANNEL, SDCARD_SPI_INSTANCE, buffer, SDCARD_BLOCK_SIZE);
#else
// Queue the transmission of the sector payload
#ifdef SDCARD_DMA_CLK
RCC_AHB1PeriphClockCmd(SDCARD_DMA_CLK, ENABLE);
@ -446,6 +452,7 @@ static void sdcard_sendDataBlockBegin(uint8_t *buffer, bool multiBlockWrite)
DMA_Cmd(SDCARD_DMA_CHANNEL_TX, ENABLE);
SPI_I2S_DMACmd(SDCARD_SPI_INSTANCE, SPI_I2S_DMAReq_Tx, ENABLE);
#endif
#endif
}
else {
@ -729,6 +736,28 @@ bool sdcard_poll(void)
sendComplete = false;
#ifdef SDCARD_DMA_CHANNEL_TX
#if defined(USE_HAL_DRIVER)
//if (useDMAForTx && __HAL_DMA_GET_FLAG(sdDMAHandle, SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG) == SET) {
//if (useDMAForTx && HAL_DMA_PollForTransfer(sdDMAHandle, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY) == HAL_OK) {
if (useDMAForTx && (sdDMAHandle->State == HAL_DMA_STATE_READY)) {
//__HAL_DMA_CLEAR_FLAG(sdDMAHandle, SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG);
//__HAL_DMA_DISABLE(sdDMAHandle);
// Drain anything left in the Rx FIFO (we didn't read it during the write)
while (__HAL_SPI_GET_FLAG(spiHandleByInstance(SDCARD_SPI_INSTANCE), SPI_FLAG_RXNE) == SET) {
SDCARD_SPI_INSTANCE->DR;
}
// Wait for the final bit to be transmitted
while (spiIsBusBusy(SDCARD_SPI_INSTANCE)) {
}
HAL_SPI_DMAStop(spiHandleByInstance(SDCARD_SPI_INSTANCE));
sendComplete = true;
}
#else
#ifdef SDCARD_DMA_CHANNEL
if (useDMAForTx && DMA_GetFlagStatus(SDCARD_DMA_CHANNEL_TX, SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG) == SET) {
DMA_ClearFlag(SDCARD_DMA_CHANNEL_TX, SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG);
@ -752,6 +781,7 @@ bool sdcard_poll(void)
sendComplete = true;
}
#endif
#endif
if (!useDMAForTx) {
// Send another chunk

View file

@ -123,10 +123,10 @@
// Divide to under 25MHz for normal operation:
#define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 8 // 27MHz
//#define SDCARD_DMA_CHANNEL_TX DMA2_Stream1
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA_FLAG_TCIF1
#define SDCARD_DMA_CHANNEL_TX DMA2_Stream1
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA_FLAG_TCIF1_5
#define SDCARD_DMA_CLK RCC_AHB1Periph_DMA2
#define SDCARD_DMA_CHANNEL DMA_Channel_4
#define SDCARD_DMA_CHANNEL DMA_CHANNEL_4
#define USE_I2C
#define I2C_DEVICE (I2CDEV_4)
@ -134,7 +134,7 @@
#define SENSORS_SET (SENSOR_ACC|SENSOR_MAG|SENSOR_BARO)
//#define USE_ADC
#define USE_ADC
#define VBAT_ADC_PIN PC0
#define CURRENT_METER_ADC_PIN PC1
#define RSSI_ADC_GPIO_PIN PC2