Part Number: PROCESSOR-SDK-AM437X
I am running the QSPI_BasicExample_idkAM437x_armExampleProject on a Sitara AM437x IDK. I am using SDK version 126.96.36.199.
I have one issue I would like to mention and I would like to ask one question.
Issue: Potential mismatch between “hwAttrs->rxLines” and “object->rxLines”
This issue is an equivalent to the following post:
Inside the function “spi_read_write” you will find the following code (see red rectangle):
So the QSPI flash is being set to Quad SPI mode in case that “hwAttrs->rxLines” is set to “QSPI_RX_LINES_QUAD”. But later on the function “SF25FL_bufferRead” is called and this function looks at “object->rxLines”.
So at this place there is exactly the same issue that Dillon also pointed out in the other E2E post:
"And for the second part of your response, thank you for pointing out this detail. You're right that there's an edge case where the values of "hwAttrs->operMode" and "object->qspiMode" could differ during run-time. I'll go ahead and share this with the development team to see about fixing this.
Additional question – Where do we leave the QSPI mode?
Now I have an additional question. Inside the 1st picture in this post you see that the Flash device is switched into Quad SPI mode after calling “S25FLFlash_BlockErase /SF25FL_bufferWrite” but before calling “SF25FL_bufferRead”. This is OK since the “SF25FL_bufferRead” supports a Quad SPI mode.
But I do not find any place in the example code, where the Flash device is being instructed to leave the Quad SPI mode at the end of the “spi_read_write” function. Note that the function “spi_read_write” is being called 2-times in this example. When you look at the function “S25FLFlash_BlockErase” called at the beginning of “spi_read_write”, you will identify that the SPI driver runs in standard SPI mode (CS, CLK, MOSI, MISO) during the erase function (I assume this is the meaning of the code inside the red rectangle of the below picture):
Is it possible that in the 2nd repetition a flash erase fails because the Flash itself is in Quad SPI mode (from the 1st “spi_read_write” call) but the “S25FLFlash_BlockErase” function adjusts the driver in a way to run in regular SPI mode? Or am I mistaken?
Thank you for pointing out this detail as well. Like you mentioned, this is a similar case to the operMode detail that you pointed out in this thread, and so I will also send this to the development team.
And for your question about switching modes, the mode is set back to standard SPI mode in order to complete the rest of the operations. This behavior also occurs when quad SPI mode is enabled, for the same reason as to complete the rest of the operations.
bool S25FLFlash_QuadModeEnable(S25FL_Handle flashHandle)
SPI_Handle handle = flashHandle->spiHandle; /* SPI handle */
unsigned char writeVal = 0U; /* data to be written */
uint32_t norStatus; /* flash status value */
bool retVal = false; /* return value */
unsigned int operMode; /* temp variable to hold mode */
unsigned int rxLines; /* temp variable to hold rx lines */
unsigned int frmLength;
unsigned int transferType;
unsigned int rxLinesArg;
/* Get the pointer to the object and hwAttrs */
object = handle->object;
/* These operations require the qspi to be configured in the following mode
only: tx/rx single line and config mode. */
/* Save the current mode and rxLine configurations */
operMode = object->qspiMode;
rxLines = object->rxLines;
/* Update the mode and rxLines with the required values */
SPI_control(handle, SPI_V1_CMD_SETCONFIGMODE, NULL);
rxLinesArg = QSPI_RX_LINES_SINGLE;
SPI_control(handle, SPI_V1_CMD_SETRXLINES, (void *)&rxLinesArg);
We are glad that we were able to resolve this issue, and will now proceed to close this thread.
If you have further questions related to this thread, you may click "Ask a related question" below. The newly created question will be automatically linked to this question.
In reply to Dillon Frank:
I may have not explained my 2nd question well enough. I think I will explain the example program flow step by step. When I read the code, I believe that the situation is as follows:
1) When power up the IDK board the Macronix SPI flash is most likely operating in standard SPI mode but the QSPI driver is set in QSPI mode since object->rxLines has the value 2 after open the QSPI handle, which represents the enumeration QSPI_RX_LINES_QUAD (after calling "SF25FL_open").
2) The first function inside the example project called "FlashPrintId" switches the QSPI driver at the beginning to standard SPI mode but restores at the end the QSPI default for the driver. That is the reason why I believe that the Macronix Flash wakes up in standard SPI mode.
3) Then we call for the 1st time the function "spi_read_write".
3a) "S25FLFlash_BlockErase" is called and switches the driver also to standard SPI mode but at the end restores the default QSPI mode for the driver.
3b) "SF25FL_bufferWrite" is called.
3b_a) "S25FLFlash_WriteEnable" is called also switches the driver to standard SPI mode but at the end restores the default QSPI mode for the driver.
3b_b) Now depending on the driver QSPI access mode (memory mapped of config mode) the data is written to the Macronix Flash either via code inside "SF25FL_bufferWrite" (memory mapped QSPI mode) or via the function "SF25FL_ConfigMode_Write". But here comes the point: This code that programs the data does not switch the driver to standard SPI mode and at this point we may have a mismatch. The Macronix Flash is still operating in standard SPI mode but the example code that programs the flash runs in QSPI mode (the default).
3c) Now a function called "S25FLFlash_QuadModeEnable" is being called. This function switches the Macronix flash device from standard SPI into QSPI mode. But as I wrote before, this may come too late.
3d) Now "SF25FL_bufferRead" is being called, the driver as well as the Macronix are set at this point to QSPI mode. But note that there is no function, which instructs the Macronix flash to leave the QSPI mode, whcih we have entered due to point 3c.
4) Now we call spi_read_write" in the code for the 2nd time and we jump back to point 3 above. At this point the Macronix flash is still in QSPI mode but the function "S25FLFlash_BlockErase" (see point 3a) tells the driver to work in standard SPI mode. Also here I see a mismatch between the selected mode of the QSPI driver and the operating mode of the Flash device.
Do you see what I mean? What am I missing?
In reply to inno:
Thank you for clearing that up. To make sure I'm understanding you correctly, you're saying that because quad mode is not disabled at the end of the first spi_read_write, that there is a mismatch between the flash device and the driver when spi_read_write (and eventually bufferWrite) is called the second time, causing the second spi_read_write to fail. Is that a correct understanding?
Yes, this is exactly my point. But let me be a bit more precise and correct your statement (I marked the correction in red color):
"Thank you for clearing that up. To make sure I'm understanding you correctly, you're saying that because quad mode is not disabled at the end of the first spi_read_write, that there is a mismatch between the flash device and the driver when spi_read_write (and eventually S25FLFlash_BlockErase, which runs in standard SPI mode) is called the second time, causing the second spi_read_write to fail. Is that a correct understanding?"
Actually when I read the code of the example project, another mismatch happens already earlier in point 3b_b during the 1st "spi_read_write" call, but this is just a side note.
Look, we have 2 devices communicating with each other, CPU and Flash.- If the CPU decides to communicate in standard SPI mode, then the Flash device needs to be set to a state where it communicates also in standard SPI mode.- If the CPU decides to communicate in QSPI mode, then the Flash device needs to be set to a state where it communicates also in QSPI mode.
But when I read the code of the example project, then I don't see that happening. But for some reason the test passes, I still don't understand why.
So now we are on the same page. Do you have any clue why the test passes?
Thank you for the confirmation. I'm still looking into this, but have you tried connecting your board to CCS and monitoring each of the values within the test at each part of the code? While it's not a fix, it may shed some light as to why this test is passing with the suspected mode mismatches that you mentioned.
Yes, of course I did. The received data seem to be correct and the function "VerifyData", which is being called after the "SF25FL_bufferRead", confirms this. That's why I am so confused, the question that I raised simply came up during code review and learning the example project.
I would also like to connect a logic analyzer to the QSPI bus on the IDK to see what is going on on the bus, but unfortunately the signals are not routed to any pin header and I don't want to solder any test wires myself (I am afraid destroying the board ;-) ).
However, please look here, where the correct data is being received during the test in the 2nd repetition of the "spi_read_write" call:
All content and materials on this site are provided "as is". TI and its respective suppliers and providers of content make no representations about the suitability of these materials for any purpose and disclaim all warranties and conditions with regard to these materials, including but not limited to all implied warranties and conditions of merchantability, fitness for a particular purpose, title and non-infringement of any third party intellectual property right. No license, either express or implied, by estoppel or otherwise, is granted by TI. Use of the information on this site may require a license from a third party, or a license from TI.
TI is a global semiconductor design and manufacturing company. Innovate with 100,000+ analog ICs andembedded processors, along with software, tools and the industry’s largest sales/support staff.