Skip to main content
Pilous Droip
Senior
February 16, 2018
Question

AutoPolling QSPI and memory erase

  • February 16, 2018
  • 2 replies
  • 1757 views
Posted on February 16, 2018 at 19:52

Hello friends.

I have a problem. I erase external memory. But this procedure last long time. So I set autopolling mode with interrupt. But It doesn't work.

When I send erase command I need wait on WIP bit in status register. And when QIP bit is set, I need generate interrupt.

And program work:

  1. Send 0x06 - enable write to memory
  2. Send erase memory 0xC7
  3. Set autopolling mode

And when I set autopolling mode, immediately is generating interrupt. And it is wrong.

Any idea, what is wrong?

0690X00000609i6QAA.png

So. Here is my autopolling initializion.

void QSPI_AutoPollingMemReady(void)

{

uint32_t tmpreg = 0;

while (QUADSPI->SR & QUADSPI_SR_BUSY) {};

QUADSPI->PSMAR = 0x0000;

QUADSPI->PSMKR = 0x0101;

QUADSPI->CR &= ~ QUADSPI_CR_PMM; /* AND Match Mode */

QUADSPI->CR |= QUADSPI_CR_APMS; //enable autopolling

QUADSPI->DLR = 0x00; //data lenght 0-1bytes; 1-2bytes; 2-3bytes.....

tmpreg = QUADSPI->CCR;

tmpreg &= 0x90800000;

tmpreg |=

(0x00 << QUADSPI_CCR_DDRM_Pos) | // Disable DDR mode

(0x00 << QUADSPI_CCR_DHHC_Pos) | // Delay the data output using analog delay

(0x00 << QUADSPI_CCR_SIOO_Pos) | // Send instruction on every transaction

(0x02 << QUADSPI_CCR_FMODE_Pos) | // function QSPI (0-indirect write); (1-indirect read); (2-autopolling)

(0x01 << QUADSPI_CCR_DMODE_Pos) | // Data mode (0-nodata); (1-data on single line); .....

(0x00 << QUADSPI_CCR_DCYC_Pos) | // Dummy cycle

(0x00 << QUADSPI_CCR_ABSIZE_Pos) | // size of alternate bytes (0-8bit); (1-16bit); (2-24bit); (3-32bit)

(0x00 << QUADSPI_CCR_ABMODE_Pos) | // Alternate mode (0-no alternate); (1-alternate on single line)

(0x02 << QUADSPI_CCR_ADSIZE_Pos) | // size of address bytes (0-8bit); (1-16bit); (2-24bit); (3-32bit)

(0x00 << QUADSPI_CCR_ADMODE_Pos) | // Address mode (0-no address); (1-address on a single line)

(0x01 << QUADSPI_CCR_IMODE_Pos ) | // Instruction mode (0-no instruction); (1-instruction on signel line)

(READ_STATUS_REG_CMD << QUADSPI_CCR_INSTRUCTION_Pos); // Instruction send on SPI 0x05

QUADSPI->CCR = tmpreg;

asm(''NOP'');

QUADSPI->FCR = 0x00; //clear flag

asm(''NOP'');

/*Enable Interrupts*/

tmpreg = QUADSPI->CR ;

tmpreg |= (uint32_t)((QUADSPI_CR_SMIE | QUADSPI_SR_SMF | QUADSPI_CR_FTIE | QUADSPI_SR_FTF | QUADSPI_CR_TEIE | QUADSPI_SR_TEF) & 0x001F0000);

QUADSPI->CR = tmpreg ;

}

And here is my interrupt:

void QUADSPI_IRQHandler(void)

{

if((QUADSPI->SR & QUADSPI_SR_FTF))

{

QUADSPI->FCR = (uint32_t)((QUADSPI_CR_SMIE | QUADSPI_SR_SMF) & 0x001F0000);

/* Disable the QSPI FIFO Threshold, Transfer Error and Status Match Interrupts */

QSPI_disable_IT((QUADSPI_CR_SMIE | QUADSPI_SR_SMF | QUADSPI_CR_FTIE | QUADSPI_SR_FTF | QUADSPI_CR_TEIE | QUADSPI_SR_TEF), DISABLE);

usart_puts(''\r\nErase success\r\n'');

}

LL_GPIO_TogglePin(GPIOB, GREEN);

}

#quadspi #nucleo-f767zi #stm32f767zi
This topic has been closed for replies.

2 replies

AVI-crak
Senior
February 17, 2018
Posted on February 17, 2018 at 03:51

QUADSPI polling status mask register (QUADSPI _PSMKR)

QUADSPI polling status match register (QUADSPI _PSMAR)

Mask and stencil for checking the flag in automatic mode of infinite reading.

PSMKR - the mask resets all the irrelevant bits when reading the flag, PSMAR performs the XOR operation with the result = if there is a complete match, the interrupt will occur. Any other value that does not match the mask and the stencil is ignored.
Pilous Droip
Senior
February 17, 2018
Posted on February 17, 2018 at 12:13

Yes. This is my problem.

I have got PSMAR and PSMKR wrong set. And I don't know, how to set good value.

So, I know this.

  1. Call erase.
  2. Erase set last bit WIP to HIGH.
  3. Set autopolling.

And what I must set to register PSMAR and PSMKR?

Is this value good? What do you mean?

QUADSPI->PSMKR = 0x01;

QUADSPI->PSMAR = 0x00;

0690X00000609irQAA.png0690X00000609jiQAA.png
AVI-crak
Senior
February 17, 2018
Posted on February 17, 2018 at 13:06

Mask and stencil are applied to the full width (it is desirable).

Memory responds in a loop all the time, it's not one byte - but 4. It looks something like this:

mask 0x01010101 - the remaining bits will be reset

stencil 0x00000000 - wait for the answer to match (your case is now 0x01 -> expect 0x00).

If you want to control two bits or more - they all need to get into the mask, even if they are at the start zero.

The mask is a binary operation '&', the stencil is a binary operation '^'.

An additional problem is the direction of reading the bits (high / low). In this problem, you can easily lose the goal. The easiest option is to catch the answer during debugging (it might surprise you). The way it will look - it's easy to build a mask and a stencil.

Pilous Droip
Senior
February 19, 2018
Posted on February 19, 2018 at 10:56

I try to understand it.

0690X00000609jdQAA.png

for check WIP bit I used:

QUADSPI->PSMAR = 0x00000000 ;

QUADSPI->PSMKR = 0x01010101 ;

but for check WEL bit I used:

QUADSPI->PSMAR = 0x02;

QUADSPI->PSMKR = 0x02;

Can anyone describe the use of PSMAR and PSMKR?

AVI-crak
Senior
February 19, 2018
Posted on February 19, 2018 at 13:19

I already said how it's done.

There is no point in understanding, there are a lot of conditions and confusion. It is much easier to read the answer in a simple way, it will look exactly like this - how you need to process it. The status response always has a size of 8 bits, and it repeats in a loop until a clock signal is sent to the memory chip. (First, you need to give the status reading command.) But the answer may differ from the documentation, primarily externally. A WIP can be the first least significant bit, or maybe the most significant bit. I abandoned the idea of guessing, it is easier for me to consider the answer from the debugger.

You got a cast, and WIP is in the low bit. In this case, you need to reset everything except PSMKR 0x01010101. Now you can catch the necessary condition for you WIP = 0 PSMAR = 0x0, WIP = 1 PSMAR = 0x01010101.

Sequence for recording:

1) Enable recording

2) Wait for the WEL flag (1), WIP (not important) - very fast

3) Wait for the WIP flag (1), WEL (not important) - 1 ~ 10mc

4) write to the address

5) remove the CS signal, and read the flags again before the complete coincidence of WEL (0), WIP (0) - 1 ~ 500mc.