2
\$\begingroup\$

I am working with the STM32F767ZIT6. At the moment I am exploring the QuadSPI peripheral. After setting up the peripheral with the following configuration I noticed some undesired behavior of the data lines following the dummy cycles.

// PRESCALER    = 160 -> 1 MHz.
// FTHRES       =   3 -> 4 Byte threshold.
// FSEL         =   1 -> Flash 2 selected.

QUADSPI->CR =
        (160UL << QUADSPI_CR_PRESCALER_Pos)
    |   (  3UL << QUADSPI_CR_FTHRES_Pos)
    |   QUADSPI_CR_FSEL;

// FSIZE    = 31    -> 2^32 Bytes.
// CSHT     =  7    -> Chip select 8 Cycles
// CKMODE   =  0    -> SPI Mode 0.

QUADSPI->DCR =
        (31UL << QUADSPI_DCR_FSIZE_Pos)
    |   ( 7UL << QUADSPI_DCR_CSHT_Pos);

// FMODE        = 0 -> Indirect Write Mode.
// IMODE        = 3 -> Four Lines.
// ADMODE       = 3 -> Four Lines.
// ABMODE       = 3 -> Four Lines.
// DMODE        = 3 -> Four Lines.
// ADSIZE       = 2 -> 24 Bit.
// ABSIZE       = 2 -> 24 Bit.
// DCYC         = 8 -> 8 Dummy Cycles.
// INSTRUCTION  = 0x48.

QUADSPI->CCR =
        ( 3UL << QUADSPI_CCR_DMODE_Pos)
    |   ( 3UL << QUADSPI_CCR_ABMODE_Pos)
    |   ( 3UL << QUADSPI_CCR_ADMODE_Pos)
    |   ( 3UL << QUADSPI_CCR_IMODE_Pos)
    |   ( 2UL << QUADSPI_CCR_ADSIZE_Pos)
    |   ( 2UL << QUADSPI_CCR_ABSIZE_Pos)
    |   ( 8UL << QUADSPI_CCR_DCYC_Pos)
    |   (72UL << QUADSPI_CCR_INSTRUCTION_Pos);

QUADSPI->DLR = 64;
QUADSPI->ABR = 0xAABBCCUL;
QUADSPI->AR = 0x123456UL;

QUADSPI->CR =
        QUADSPI->CR
    |   QUADSPI_CR_EN;
  1. Send Instruction (1 Byte 72)
  2. Send Address (3 Bytes 0x123456)
  3. Send Alternate (3 Bytes 0xAABBCCDD)
  4. Send Dummy (8 Cycles)
  5. Send Data (64 Bytes 0x12345678, 0xFFFFFFFF ... 0xFFFFFFFF)

Quad SPI example

So after the first glance everything looks good. But there's one thing that could cause trouble and make me uncomfortable. After the 8 dummy cycles the data lines changing their state, according to the first data byte high nibble, on the rising edge of the clock. But I am using SPI mode 0 so the slave is sampling the data lines on the rising edge of the clock. So there is a chance that the first 4 bits after the dummy cycles gets corrupted.

Did I made some configuration mistake, is it a bug or is this normal behavior and I am wrong?

Reference Manual

  • Quad SPI description p.407
  • Quad SPI registers p.423

EDIT: After looking into the errata I probably found the problem.

2.12 QUADSPI peripheral limitations

2.12.1 First nibble of data is not written after a dummy phase Description

The first nibble of data to be written to the external Flash memory is lost in the following conditions:

  • The QUADSPI is used in the indirect write mode

  • And at least one dummy cycle is used

Workaround

Use alternate-bytes instead of a dummy phase in order to add a latency between the address phase and the data phase. This works only if the number of dummy cycles corresponds to a multiple of 8 bits of data. Example: To generate: – 1 dummy cycle: send 1 alternate-byte, possible only in 4 data line DDR mode or Dual-flash SDR mode – 2 dummy cycles: send 1 alternate-byte in 4 data line SDR mode – 4 dummy cycles: send 2 alternate-bytes in 4 data line SDR mode or send 1 alternate-byte in 2 data line SDR mode – 8 dummy cycles: send 1 alternate-byte in 1 data line SDR mode

But the workaround is not working for me because my slave needs the 8 dummy cycles to switch between input/output mode. If I use the alternate byte instead of the dummy cycles there is a chance that the master and slave driving the data lines concurrent which could cause some hardware damage! So is there a magic trick to getting around this problem?

\$\endgroup\$
  • \$\begingroup\$ Recently I've experienced a case where the CS line would suddenly go high in the middle of an SPI transaction. I wasted many hours until I additionally turned on the analog view of the CS line in Saleae Logic: it showed a perfect signal staying low for the entire transaction. Obviously, it was a bug in the Saleae analyzer or software. There was a problem in my system but in a completely different place. Better check if your problem is real. \$\endgroup\$ – Codo Feb 18 '18 at 12:01
  • \$\begingroup\$ Unfortunately, it is not a measurement error from the logic analyzer. I looked at the signal with an oscilloscope and saw the same problem. \$\endgroup\$ – Michael Feb 18 '18 at 14:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.