From 5d856ace58b33ba1fd852cab4d53701501c2cfc0 Mon Sep 17 00:00:00 2001 From: Federico Terraneo <fede.tft@miosix.org> Date: Sun, 30 Apr 2017 14:56:01 +0200 Subject: [PATCH] Fixed DMA bug: the completion interrupt should be on the RX side --- sbs.conf | 8 ++++++++ src/shared/DMA/DMA.cpp | 27 +++++++++++++++------------ 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/sbs.conf b/sbs.conf index d36862388..db4938d4d 100644 --- a/sbs.conf +++ b/sbs.conf @@ -164,3 +164,11 @@ BinName: anakin-test-dma Include: %shared %i2c %math %anakin-data Defines: Main: anakin-test-dma + +[dma-lowlevel-test] +Type: board +BoardId: stm32f429zi_skyward_anakin +BinName: dma-lowlevel-test +Include: %shared %i2c %math %anakin-data +Defines: +Main: dma-lowlevel-test diff --git a/src/shared/DMA/DMA.cpp b/src/shared/DMA/DMA.cpp index 791e2355c..7e53eab19 100644 --- a/src/shared/DMA/DMA.cpp +++ b/src/shared/DMA/DMA.cpp @@ -34,15 +34,15 @@ typedef Gpio<GPIOA_BASE,7> mosi; /** * DMA RX end of transfer */ -void __attribute__((naked)) DMA2_Stream5_IRQHandler() +void __attribute__((naked)) DMA2_Stream0_IRQHandler() { saveContext(); asm volatile("bl _Z20SPI1rxDmaHandlerImplv"); restoreContext(); } -static Thread *waiting = NULL; -static vector<SPIRequest> *requestVector; +static Thread *waiting = nullptr; +static vector<SPIRequest> *requestVector = nullptr; static size_t requestIndex = 0; static bool error = false; @@ -53,10 +53,16 @@ void __attribute__((used)) SPI1rxDmaHandlerImpl() { if(DMA2->LISR & (DMA_LISR_TEIF0 | DMA_LISR_DMEIF0)) error = true; + if(DMA2->HISR & (DMA_HISR_TEIF5 | DMA_HISR_DMEIF5)) + error = true; DMA2->LIFCR = DMA_LIFCR_CTCIF0 | DMA_LIFCR_CTEIF0 | DMA_LIFCR_CDMEIF0; + DMA2->HIFCR = DMA_HIFCR_CTCIF5 + | DMA_HIFCR_CTEIF5 + | DMA_HIFCR_CDMEIF5; + if(requestVector==nullptr) return; (*requestVector)[requestIndex].IRQendTransaction(); if( ++requestIndex >= requestVector->size() ) @@ -114,8 +120,9 @@ bool SPIDriver::transaction(vector<SPIRequest>& requests) } } - bool result=!error; disableDMA(); + requestVector=nullptr; + bool result=!error; pthread_mutex_unlock(&mutex); return result; } @@ -143,8 +150,8 @@ SPIDriver::SPIDriver() // | SPI_CR1_BR_1 //Less than 10MHz | SPI_CR1_BR_2 // fClock / 32 | SPI_CR1_SPE; //SPI enabled - NVIC_SetPriority(DMA2_Stream5_IRQn,10);//Low priority for DMA - NVIC_EnableIRQ(DMA2_Stream5_IRQn); + NVIC_SetPriority(DMA2_Stream0_IRQn,10);//Low priority for DMA + NVIC_EnableIRQ(DMA2_Stream0_IRQn); } } @@ -166,6 +173,7 @@ void SPIRequest::IRQbeginTransaction() DMA2_Stream0->CR = DMA_SxCR_CHSEL_1 | DMA_SxCR_CHSEL_0 // Channel 3 | DMA_SxCR_PL_1 //High priority because fifo disabled | DMA_SxCR_MINC //Increment memory pointer + | DMA_SxCR_TCIE //Interrupt on transfer complete | DMA_SxCR_TEIE //Interrupt on transfer error | DMA_SxCR_DMEIE //Interrupt on direct mode error | DMA_SxCR_EN; //Start DMA @@ -179,7 +187,6 @@ void SPIRequest::IRQbeginTransaction() | DMA_SxCR_PL_1 //High priority because fifo disabled | DMA_SxCR_MINC //Increment memory pointer | DMA_SxCR_DIR_0 //Memory to peripheral - | DMA_SxCR_TCIE //Interrupt on transfer complete | DMA_SxCR_TEIE //Interrupt on transfer error | DMA_SxCR_DMEIE //Interrupt on direct mode error | DMA_SxCR_EN; //Start DMA @@ -188,10 +195,6 @@ void SPIRequest::IRQbeginTransaction() void SPIRequest::IRQendTransaction() { - //FIXME: ensure dead time between CS high and CS low!!! - //And, is it really needed? chipSelect.high(); - - //TX dma channel has no IRQ, so clear flag here - DMA2->HIFCR=DMA_HIFCR_CTCIF5; + delayUs(10); //FIXME: properly size the delay } -- GitLab