cancel
Showing results for 
Search instead for 
Did you mean: 

Read data from QSPI with DMA

Pilous Droip
Senior
Posted on February 09, 2018 at 12:28

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?

0690X00000609eyQAA.png

#nucleo-f767zi #qspi-flash #stm32f7-dma
1 REPLY 1
gbm
Lead II
Posted on February 09, 2018 at 15:13

Read the errata - there are two significant problems with QSPI, which may affect your piece of code. Don't use dummy bytes.