AnsweredAssumed Answered

Read data from QSPI with DMA

Question asked by Pilous Droip on Feb 9, 2018
Latest reply on Feb 9, 2018 by gbm

Hello.

 

I have a problem. I have this function:

 

/*instruction = 0x0B - Fast read

 * addr = address (0x00) - address

 * count = number of read data (4bytes)

 * dst = data out */

 

void QSPI_fast_read (uint8_t instruction, uint32_t addr, size_t count, uint8_t *dst)
{
/* Quad Command Fast Read (QCFR), instruction, address, data use 2 lines
* Adresa: 24 bits (3 bajty - viz QUADSPI_CCR_ABSIZ)
* read: byte (count)
*
* Read with DMA, mez FIFO = 1
* DMA2, Stream 7, Channel 3
*/
DMA_Stream_TypeDef *stream = DMA2_Stream7;
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA2);
stream->CR = 0;

stream->CR =
(0x03 << DMA_SxCR_CHSEL_Pos) | // channel id = 3
(0x00 << DMA_SxCR_MBURST_Pos) | // MemBurst 0x0: single transfer, 0x1: burst of 4 beats, 0x2: burst of 8; 0x3: burst of 16 beats
(0x00 << DMA_SxCR_PBURST_Pos) | // PeriphBurst 0x0: single transfer, 0x1: burst of 4 beats, 0x2: burst of 8; 0x3: burst of 16 beats
(0x03 << DMA_SxCR_PL_Pos) | // priority level (0 lowest; 3 highest)
(0x00 << DMA_SxCR_MSIZE_Pos) | // 8 bit source memory
(0x00 << DMA_SxCR_PSIZE_Pos) | // 8-bit target register
(1 * DMA_SxCR_MINC) | // memory increment
(0 * DMA_SxCR_PINC) | // no periph increment
(0x00 << DMA_SxCR_DIR_Pos ) | // direction 0: P->M, 1: M->P
(0 * DMA_SxCR_PFCTRL) | // 0 - DMA is the flow controller, 1 - periph is the flow controller
(0 * DMA_SxCR_EN);

stream->M0AR = (uint32_t)dst; /* mem address */
stream->PAR = (uint32_t)&QUADSPI->DR; /* periph address */
stream->NDTR = count;

QUADSPI->FCR = -1; // clear all flags
QUADSPI->DLR = (count-1); //data lenght
QUADSPI->CCR =
(0 << QUADSPI_CCR_DDRM_Pos) | // disable DDR mode
(0 << QUADSPI_CCR_DHHC_Pos) | // delay the data output using analog delay
(0 << QUADSPI_CCR_SIOO_Pos) | // send instruction for each command (0) or only for 1st command (1)
(0x01 << QUADSPI_CCR_FMODE_Pos) | // Functional mode; 0 : indirect write, 1 : indirect read, 2 : autopolling, 3 : memory-mapped
(0x01 << QUADSPI_CCR_DMODE_Pos) | // Data mode: 0 : no data, 1 : data on single line, 2: data on dual line, 3 : quad line
(0x07 << QUADSPI_CCR_DCYC_Pos) | // number of dummy cycles, 0..31
(0x00 << QUADSPI_CCR_ABSIZE_Pos) | // alternate byte size; 0: 8-bit, 1: 16-bit, 2: 24-bit, 3: 32-bit
(0x00 << QUADSPI_CCR_ABMODE_Pos) | // alternate bytes mode; 0: no alt bytes, 1 : on single line, 2 : dual line, 3 : quad line
(0x02 << QUADSPI_CCR_ADSIZE_Pos) | // address size; 0: 8-bit, 1: 16-bit, 2: 24-bit, 3: 32-bit
(0x01 << QUADSPI_CCR_ADMODE_Pos) | // address mode; 0: no address, 1 : on single line, 2 : dual line, 3 : quad line
(0x01 << QUADSPI_CCR_IMODE_Pos) | // instrustion mode mode; 0: no instruction, 1 : on single line, 2 : dual line, 3 : quad line
(instruction << QUADSPI_CCR_INSTRUCTION_Pos); // instruction

QUADSPI->CR |= QUADSPI_CR_DMAEN; //enable read DMA
stream->CR |= DMA_SxCR_EN;
QUADSPI->AR = addr; //write to address register, when ADMODE != 0 and FMODE = 1.
while (!(DMA2->HISR & DMA_HISR_TCIF7)) {}; //wait to the end of DMA
DMA2->HIFCR |= DMA_HIFCR_CTCIF7;
stream->CR &= ~DMA_SxCR_EN;
SCB_InvalidateDCache_by_Addr ((uint32_t*)dst, count); // reset cache
QUADSPI->CR &= ~QUADSPI_CR_DMAEN; //the end read of DMA
}

 

And i have a problem with this line:

while (!(DMA2->HISR & DMA_HISR_TCIF7)) {}; //wait to the end of DMA
DMA2->HIFCR |= DMA_HIFCR_CTCIF7;

My program is waiting on 'while'. And I can't find a solution of this problem. Any idea, what is wrong?

 

But, I check the communication. And you can see,

  1. Fast command (1byte) 0x0B were send
  2. Address (3bytes) 0x00 were send
  3. dummy cycles (8bits) were send (but, here is anything wrong.....)
  4. Data received (32bits)

 

Do you see anything wrong?

 

Attachments

Outcomes