AnsweredAssumed Answered

Data corruption with imx6ull qspi peripheral

Question asked by Kevin Cronn on Mar 1, 2019
Latest reply on Mar 5, 2019 by igorpadykov

I am seeing data corruption when using the imx6ull qspi peripheral. I have put prints in after filling the TX FIFO and the prints show the data going into the FIFO is correct but it comes out of the chip onto the qspi bus wrong. Here is an example, the bold data is incorrect (this is a baremetal project):

 

FC 4F 02 00 FD 4F 02 00 FE 4F 02 00 FF 4F 02 00

00 50 02 00 01 50 02 00 02 50 02 00 03 50 02 00

04 50 02 00 05 50 02 00 06 50 02 00 07 50 02 00

08 50 02 00 09 50 02 00 0A 50 02 00 0B 50 02 00

0C 50 02 00 0D 50 02 00 0E 50 02 00 0F 50 02 00

10 50 02 00 11 50 02 00 12 50 02 00 13 50 02 00

14 50 02 00 15 50 02 00 16 50 02 00 17 50 02 00

18 50 02 00 19 50 02 00 1A 50 02 00 1B 50 02 00

1C 50 02 00 1D 50 02 00 1E 50 02 00 1F 50 02 00

20 50 02 00 21 50 02 00 22 50 02 00 23 50 02 00

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF

FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 

FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 

FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 

FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 

FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF

40 50 02 00 41 50 02 00 42 50 02 00 43 50 02 00

44 50 02 00 45 50 02 00 46 50 02 00 47 50 02 00

48 50 02 00 49 50 02 00 4A 50 02 00 4B 50 02 00

4C 50 02 00 4D 50 02 00 4E 50 02 00 4F 50 02 00

50 50 02 00 51 50 02 00 52 50 02 00 53 50 02 00

54 50 02 00 55 50 02 00 56 50 02 00 57 50 02 00

58 50 02 00 59 50 02 00 5A 50 02 00 5B 50 02 00

5C 50 02 00 5D 50 02 00 5E 50 02 00 5F 50 02 00

 

It should have been this:

24 50 02 00 25 50 02 00 26 50 02 00 27 50 02 00

28 50 02 00 29 50 02 00 2A 50 02 00 2B 50 02 00

2C 50 02 00 2D 50 02 00 2E 50 02 00 2F 50 02 00

30 50 02 00 31 50 02 00 32 50 02 00 33 50 02 00

34 50 02 00 35 50 02 00 36 50 02 00 37 50 02 00

38 50 02 00 39 50 02 00 3A 50 02 00 3B 50 02 00

3C 50 02 00 3D 50 02 00 3E 50 02 00 3F 50 02 00

 

Here is my code to write to the qspi peripheral:

 

void QSPI_Write(QuadSPI_Type *base, uint32_t *buffer, size_t size)
{
    uint32_t i = 0;
    for (i = 0; i < size / 4U; i++)
    {
    /* Check if the buffer is full */
    while (QuadSPI->SR & QuadSPI_SR_TXFULL_MASK)
    {
    }

    base->TBDR = *buffer;
    buffer++;
    }
}

 

 

 

void programQspiFlash(uint32_t addr, uint32_t *src_addr)
{

    while (QuadSPI->SR & QuadSPI_SR_BUSY_MASK)
    {
    }
    // clear FIFO
    QuadSPI->MCR |= QuadSPI_MCR_CLR_TXF_MASK;


    // Set IP Command Address
    QuadSPI->SFAR = addr;


    // cmd write enable
   while (QuadSPI->SR & QuadSPI_SR_BUSY_MASK & QuadSPI_SR_BUSY_MASK)
   {
   }
   while (QuadSPI->SR & QuadSPI_SR_BUSY_MASK & (QuadSPI_SR_BUSY_MASK |       QuadSPI_SR_IP_ACC_MASK))
    {
    }
    QuadSPI->SPTRCLR = QuadSPI_SPTRCLR_IPPTRC_MASK;


   // Write the seqid bit
   QuadSPI->IPCR = ((QuadSPI->IPCR & (~QuadSPI_IPCR_SEQID_MASK)) | QuadSPI_IPCR_SEQID(1));
   // end cmd write enable 

    while (QuadSPI->SR & QuadSPI_SR_BUSY_MASK)
    {
    }

    QuadSPI->SPTRCLR = QuadSPI_SPTRCLR_IPPTRC_MASK;

    // First write some data into TXFIFO to prevent from under run
   QSPI_Write(QuadSPI, src_addr, 128);
    src_addr += 32;

    // Start the program
   QuadSPI->IPCR = ((QuadSPI->IPCR & (~QuadSPI_IPCR_IDATSZ_MASK)) |     QuadSPI_IPCR_IDATSZ(FLASH_PAGE_SIZE));

   while (QuadSPI->SR & (QuadSPI_SR_BUSY_MASK | QuadSPI_SR_IP_ACC_MASK))
    {
    }
    QuadSPI->SPTRCLR = QuadSPI_SPTRCLR_IPPTRC_MASK;

    // Write the seqid bit
    QuadSPI->IPCR = ((QuadSPI->IPCR & (~QuadSPI_IPCR_SEQID_MASK)) | QuadSPI_IPCR_SEQID(4U));
QSPI_Write(QuadSPI, src_addr, 128);
src_addr += 32;

// Wait until flash finished program
uint32_t val = 0;
do
{
while (QuadSPI->SR & QuadSPI_SR_BUSY_MASK)
{
}

// Clear FIFO
QuadSPI->MCR |= QuadSPI_MCR_CLR_RXF_MASK;
// Clear command sequence.
QuadSPI->SPTRCLR = QuadSPI_SPTRCLR_IPPTRC_MASK;
// Write the seqid bit
QuadSPI->IPCR = ((QuadSPI->IPCR & (~QuadSPI_IPCR_SEQID_MASK)) | QuadSPI_IPCR_SEQID(3U));
while (QuadSPI->SR & QuadSPI_SR_BUSY_MASK)
{
}
val = *(volatile uint32_t *)(FSL_FEATURE_QSPI_ARDB_BASE);
// Clear ARDB area
QuadSPI->FR = QuadSPI_FR_RBDF_MASK;
} while (val & 0x1);


while (QuadSPI->SR & (QuadSPI_SR_BUSY_MASK | QuadSPI_SR_IP_ACC_MASK))
{
}

// Do a software reset of the qspi peripheral
// Reset AHB domain and buffer domian
QuadSPI->MCR |= (QuadSPI_MCR_SWRSTHD_MASK | QuadSPI_MCR_SWRSTSD_MASK);

// Wait for the reset to finish
int i = 0;
for (i = 0; i < 100; i++)
{
__ASM("nop");
}

// Disable QSPI module
QuadSPI->MCR |= QuadSPI_MCR_MDIS_MASK;

// Clear the reset flags
QuadSPI->MCR &= ~(QuadSPI_MCR_SWRSTHD_MASK | QuadSPI_MCR_SWRSTSD_MASK);

// Enable QSPI module
QuadSPI->MCR &= ~QuadSPI_MCR_MDIS_MASK;

}

 

I am at a loss to explain the data corruption, has anyone seen this before or have any ideas to the issue?

Outcomes