sdio: use centralised DMA functions, instead of DMA spreading out everywhere

This commit is contained in:
Daniel Fekete 2017-06-13 06:14:29 +02:00
parent 4462e13e41
commit 557279aae2
3 changed files with 15 additions and 74 deletions

View File

@ -19,6 +19,8 @@
#include "stm32_gpio_af.h"
#include "SDIO.h"
#include "stm32_dma.h"
#include "Arduino.h"
@ -120,16 +122,9 @@ uint8_t SDIOClass::begin() {
return false;
}
/*
* TODO: We can move this section to useDMA, that way none of this code is included if not using DMA
* We would need another section clearing the settings if not using DMA.
*/
_sdio_this = (void*) this;
__HAL_RCC_DMA2_CLK_ENABLE();
stm32DmaAcquire(&hdma_sdio, SDIO_RXTX, SDIO, true);
hdma_sdio.Instance = SDIO_DMA(SDIO_Stream);
hdma_sdio.Parent = &hsd;
_SDIOSetDMAChannel(hdma_sdio, SDIO_Channel);
hdma_sdio.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_sdio.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_sdio.Init.MemInc = DMA_MINC_ENABLE;
@ -139,10 +134,8 @@ uint8_t SDIOClass::begin() {
hdma_sdio.Init.Priority = DMA_PRIORITY_LOW;
_SDIOSetDMAFIFO(hdma_sdio);
hsd.hdmatx = &hdma_sdio;
hsd.hdmarx = &hdma_sdio;
_SDIOSetDmaIRQ(SDIO_Stream);
__HAL_LINKDMA(&hsd, hdmatx, hdma_sdio);
__HAL_LINKDMA(&hsd, hdmarx, hdma_sdio);
if (HAL_DMA_Init(&hdma_sdio) != HAL_OK) {
return false;
@ -346,16 +339,4 @@ void SDIOClass::useDMA(bool useDMA){
_useDMA = useDMA;
}
/*
* DMA Handler declared here to replace the weak one in the core.
* The name is derived from the Stream name.
*/
extern "C" {
void SDIO_DMA_IRQHandler(SDIO_Stream)(void) {
reinterpret_cast<class SDIOClass*>(_sdio_this)->_sdioDMACallback();
}
void SDIO_IRQHandler(void){
reinterpret_cast<class SDIOClass*>(_sdio_this)->_sdioCallback();
}
}

View File

@ -10,60 +10,17 @@
#define sd_timeout 250 // timeout in ms in the new HAL API
#define SDCARD_STATUS_READY_BIT (1UL << 8)
/*
* Auxiliary macros to derive several names from the same values
* They derive the name of the DMA Controller+Stream/Channel and the name of the IRQ line
* corresponding to that name.
* Also derive the name of ISRs.
*/
#define _SDIO_DMA(a) DMA##a
#define SDIO_DMA(a) _SDIO_DMA(a)
#define _SDIO_DMA_IRQn(a) DMA##a##_IRQn
#define SDIO_DMA_IRQn(a) _SDIO_DMA_IRQn(a)
#define _SDIO_DMA_IRQHandler(a) DMA##a##_IRQHandler
#define SDIO_DMA_IRQHandler(a) _SDIO_DMA_IRQHandler(a)
#define _SDIOSetDmaIRQ(a) HAL_NVIC_SetPriority(SDIO_DMA_IRQn(a), 0xF, 0); \
HAL_NVIC_SetPriority(SDIO_IRQn, 0xE, 0); \
HAL_NVIC_EnableIRQ(SDIO_DMA_IRQn(a)); \
HAL_NVIC_EnableIRQ(SDIO_IRQn);
/*
* MCU specific values, used by the macros above.
*/
#ifdef STM32F0
#endif
#ifdef STM32F1
#define SDIO_Stream 1_Channel3
#define SDIO_Channel 0
#define _DMA_Instance_Type DMA_Channel_TypeDef
/*
* These settings are not possible for F1, L1, F3 series
* So we define them to nothing. We should move these to a single block
* for all the series that are compatible.
*/
#define _SDIOSetDMAChannel(hdma_handler,chan)
#define _SDIOSetDMAFIFO(hdma_handler)
#endif
#ifdef STM32F4
#define SDIO_Stream 2_Stream6
#define SDIO_Channel DMA_CHANNEL_4
#define _DMA_Instance_Type DMA_Stream_TypeDef
#define _SDIOSetDMAChannel(hdma_handler,chan) hdma_handler.Init.Channel = chan
#if defined(STM32F4) || defined(STM32F7)
#define _SDIOSetDMAFIFO(hdma_handler) do { hdma_handler.Init.FIFOMode = DMA_FIFOMODE_ENABLE; \
hdma_handler.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; \
hdma_handler.Init.MemBurst = DMA_MBURST_INC4; \
hdma_handler.Init.PeriphBurst = DMA_PBURST_INC4; } while (0)
#else
#define _SDIOSetDMAFIFO(hdma_handler)
#endif
/*
* Aux function. Doesn't exist in HAL. Allows to pre-erase blocks when the count of blocks to write is known.
* ACMD23
@ -126,8 +83,6 @@ class SDIOClass {
/** \return error line for last error. Tmp function for debug. */
uint32_t errorLine();
void useDMA(bool useDMA);
void _sdioDMACallback() { HAL_DMA_IRQHandler(&hdma_sdio); }
void _sdioCallback() {HAL_SD_IRQHandler(&hsd);}
private:
uint32_t cardStatus();

View File

@ -21,8 +21,13 @@ const dma_request_to_instance_t dmaRequestToStream[] = {
#endif
#ifdef SDIO
{SDIO, SDIO_RXTX, DMA2_Stream3, DMA_CHANNEL_4, 3 + 8, DMA2_Stream3_IRQn},
{SDIO, SDIO_RXTX, DMA2_Stream6, DMA_CHANNEL_4, 6 + 8, DMA2_Stream6_IRQn},
{SDIO, SDIO_RXTX, DMA2_Stream3, DMA_CHANNEL_4, 3 + 8, DMA2_Stream3_IRQn},
#endif
#ifdef SDMMC1
{SDMMC1, SDIO_RXTX, DMA2_Stream6, DMA_CHANNEL_4, 6 + 8, DMA2_Stream6_IRQn},
{SDMMC1, SDIO_RXTX, DMA2_Stream3, DMA_CHANNEL_4, 3 + 8, DMA2_Stream3_IRQn},
#endif
};