This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CCS/AWR1642: Bugs in the QSPI Driver

Part Number: AWR1642

Tool/software: Code Composer Studio

Hi

I am using QSPI Driver to implement the read/write fuction in SFLASH.

I have found that there is a problem with the "QSPIFlash_singleRead()" function.

There is a problem that the data of the input address + 1 can be read because the data must be able to be read from the input address value.

So I checked.

Inside QSPIFlash_singleRead () function

/ * Send dummy byte * /
QSPIFlashWriteByte (QSPIHandle, 0U, dataLen + 1U);

Is a problem.

I want you to check the bugs.

Thanks.

-Changyu Kim

  • Hi,

    Thank you for reporting this issue.

    Were you able to check the release notes if this is a known issue?

    Thank you
    Cesar
  • >There is a problem that the data of the input address + 1 can be read because the data must be able to be read from the input address value

    I read this sentence several times and it is not clear what problem you are seeing.

    First, what SDK are you using?

    Second, can you give an example of what you are seeing? I assume you're doing a write, then reading it back and not seeing the correct data...?

    Have you looked at the white paper for adding flash to an application:
    www.ti.com/.../swra583.pdf
  • Hi

    I used was "mmwave_sdk_02_00_00_04"

    Attach the test code.

    /**************************************************************************
     *              Include
     **************************************************************************/
    /* Standard Include Files. */
    #include <stdint.h>
    #include <string.h>
    #include <stdlib.h>
    #include <stdio.h>
    
    /* BIOS/XDC Include Files. */
    #include <xdc/std.h>
    #include <xdc/cfg/global.h>
    #include <xdc/runtime/Error.h>
    #include <xdc/runtime/System.h>
    #include <xdc/runtime/Timestamp.h>
    #include <xdc/runtime/Types.h>
    
    /* mmWave SK Include Files: */
    #include <ti/common/sys_common.h>
    #include <ti/drivers/qspiflash/qspiflash.h>
    #include <ti/drivers/dma/dma.h>
    
    
    /**************************************************************************
     *              Local Definitions
     **************************************************************************/
    /** \brief  */
    #define FLASH_SECTOR_UNIT               (4096U)
    
    #define FLASH_SECTOR_NUM                (1024U)     // 32Mbit(4MByte) = 4K * 1024(Sector) 
    #define FLASH_BLOCK_32_NUM              (128U)      // 32Mbit = 32K * 128(Block)
    #define FLASH_BLOCK_64_NUM              (64U)       // 32Mbit = 64K * 64(Block)
    
    #define FLASH_APP_1_MAX_SIZE            (1*1024*1024)   // 1MByte
    #define FLASH_APP_1_SECTOR              (256U)      // Application1 Start Sector
    #define FLASH_APP_1_SECTOR_NUM          (256U)      // 1MByte = 4K * 256
    #define FLASH_APP_1_ADDR_BEGIN          (FLASH_APP_1_SECTOR * FLASH_SECTOR_UNIT)
    #define FLASH_APP_1_ADDR_END            (FLASH_APP_1_ADDR_BEGIN + FLASH_APP_1_MAX_SIZE)
    
    #define FLASH_APP_2_MAX_SIZE            (1*1024*1024)   // 1MByte
    #define FLASH_APP_2_SECTOR              (512U)      // Application2 Start Sector
    #define FLASH_APP_2_SECTOR_NUM          (256U)      // 1MByte = 4K * 256
    #define FLASH_APP_2_ADDR_BEGIN          (FLASH_APP_2_SECTOR * FLASH_SECTOR_UNIT)
    #define FLASH_APP_2_ADDR_END            (FLASH_APP_2_ADDR_BEGIN + FLASH_APP_2_MAX_SIZE)
    
    #define VCLK_SRC_SEL        			(*((uint32_t*)0xFFFFFF44) & 0xF)
    #define SPARE_0_LOW_16_BITS 			(*((uint32_t*)0xFFFFE1EC) & 0xFFFF);
    #define SPARE_2_LOW_16_BITS 			(*((uint32_t*)0xFFFFE1F4) & 0xFFFF);
    
    #define TEST_BUFFER_SIZE    			(16U)
    
    /**************************************************************************
     *             Local Typedef 
     **************************************************************************/
    /** \brief  */
    
    /**************************************************************************
     *              Variable Declarations
     **************************************************************************/
    /** \brief  */
    QSPI_Handle gFlashQSPIDrv;
    QSPIFlash_Handle gFlashQSPIHandle;
    SPIFLASH_devID gFlashDevId;
    DMA_Handle gFlashDmaHandle;
    
    uint8_t fblEcuHandle;
    uint32_t fblFlashBaseAddr;
    
    uint32_t clkFreq;
    
    uint8_t fblTestwDataBuff[TEST_BUFFER_SIZE];
    uint8_t fblTestrDataBuff[TEST_BUFFER_SIZE];
    
    /**************************************************************************
     *              External Functions
     **************************************************************************/
    /** \brief  */
    
    /**************************************************************************
     *              Local Function Prototypes
     **************************************************************************/
    /** \brief  */
    
    /**************************************************************************
     *              Function Definitions
     **************************************************************************/
     
    /**
     *  @b Description
     *  @n
     *      
     *
     *  @param[in] 
     *   
     *   
     *
     *  @retval
     *      Not Applicable.
     */
    int32_t flash_init(void)
    {
        int32_t retVal;
    	QSPI_Params QSPIParams;
    
        gFlashQSPIDrv = (QSPI_Handle) NULL;
        gFlashQSPIHandle = NULL;
        gFlashDmaHandle = NULL;
        fblFlashBaseAddr = 0xFFFFFFFF;
        
    	/* Initialize the QSPI Driver */
        QSPI_init();
    
        /* Initialize the QSPI Flash */
        QSPIFlash_init();
    
        /* Open QSPI driver */
        QSPI_Params_init(&QSPIParams);
    
    	/* check the VCLK source */
        if(VCLK_SRC_SEL == 0)
        {
            /* look at spare 0 to decide the clock frequency */
            clkFreq = SPARE_0_LOW_16_BITS;
            clkFreq = (clkFreq*100000)/3;
    
        }
        else if(VCLK_SRC_SEL == 2)
        {
            /* look at spare 2 to decide the clock frequency */
            clkFreq = SPARE_2_LOW_16_BITS;
            clkFreq = (clkFreq*100000)/3;
        }
        else
        {
            while(1);
        }
    	
        /* Set the QSPI peripheral clock  */
        QSPIParams.qspiClk = clkFreq;
    
        QSPIParams.clkMode = QSPI_CLOCK_MODE_0;
    
        /* Running at 40MHz QSPI bit rate
         * QSPI bit clock rate derives from QSPI peripheral clock(qspiClk)
         and divide clock internally down to bit clock rate
         BitClockRate = qspiClk/divisor(setup by QSPI driver internally)
         */
        QSPIParams.bitRate = 40 * 1000000U;
    
        gFlashQSPIDrv = QSPI_open(&QSPIParams, &retVal);
    
        if (gFlashQSPIDrv == NULL)
        {
            /* QSPI_open failed with error */
            /* wait here to debug */
            return retVal;
        }
        
        /* Open the QSPI Instance */
        gFlashQSPIHandle = QSPIFlash_open(gFlashQSPIDrv, &retVal);
        if (gFlashQSPIHandle == NULL)
        {
            /* QSPIFlash Open API failed */
            /* wait here to debug */
            return -2;
        }
        
        /* Get SPI Flash id */
        QSPIFlash_getDeviceID(gFlashQSPIHandle, &gFlashDevId);
        
        /* get the flash address */
        fblFlashBaseAddr = QSPIFlash_getExtFlashAddr(gFlashQSPIHandle);
        
    #ifdef DEBUG_PRINT
        System_printf("device info : Manufature %x, device type = %x, capacity = %x\n",
                gFlashDevId.Manufacture, gFlashDevId.device, gFlashDevId.capacity);
    #endif /* DEBUG_PRINT */
    
    	flash_test();
    	
    	flash_close();
    	
        return retVal;
    }
    
    int32_t flash_state(void)
    {
        int32_t retVal = -1;
    
        if(gFlashQSPIHandle != NULL)
        {
            if(fblFlashBaseAddr != 0xFFFFFFFF)
            {
                retVal = 0;
            }
        }
    
        return retVal;
    }
    
    int32_t flash_erase_all(void)
    {
    	int32_t retVal = 0;
        
    	/* Erase FLASH memory*/
    	retVal = QSPIFlash_chipErase(gFlashQSPIHandle);
        if(retVal != 0)
        {
            return retVal;
        }
        
        return retVal;
    }
    
    int32_t flash_erase_app1(void)
    {
    	int32_t retVal = 0;
    	uint32_t numSectErase = 0;
    	uint32_t iCount = 0;
    	uint32_t startAddr;
    	
    	numSectErase = FLASH_APP_1_SECTOR_NUM;
    	startAddr = fblFlashBaseAddr + (FLASH_APP_1_SECTOR * SBL_SECTOR_UNIT);
    	
        /* Erase FLASH memory*/
        for (iCount = 0; iCount < numSectErase; iCount++)
        {
            retVal = QSPIFlash_sectorErase(gFlashQSPIHandle, startAddr + (iCount * SBL_SECTOR_UNIT));
            if(retVal != 0)
            {
                return retVal;
            }
        }
        
        return retVal;
    }
    
    int32_t flash_erase_app2(void)
    {
    	int32_t retVal = 0;
    	uint32_t numSectErase = 0;
    	uint32_t iCount = 0;
    	uint32_t startAddr;
    	
    	numSectErase = FLASH_APP_2_SECTOR_NUM;
    	startAddr = fblFlashBaseAddr + (FLASH_APP_2_SECTOR * SBL_SECTOR_UNIT);
    	
        /* Erase FLASH memory*/
        for (iCount = 0; iCount < numSectErase; iCount++)
        {
            retVal = QSPIFlash_sectorErase(gFlashQSPIHandle, startAddr + (iCount * SBL_SECTOR_UNIT));
            if(retVal != 0)
            {
                return retVal;
            }
        }
        
        return retVal;
    }
    
    
    uint32_t flash_get_base_addr(void)
    {
        uint32_t retBaseAddr = 0xFFFFFFFF;
        
        if(gFlashQSPIHandle != NULL)
        {
            if(fblFlashBaseAddr != 0xFFFFFFFF)
            {
                retBaseAddr = fblFlashBaseAddr;
            }
        }
    
        return retBaseAddr;
    }
    
    uint32_t flash_get_app_1_base_addr(void)
    {
        uint32_t retBaseAddr = 0xFFFFFFFF;
        
        if(gFlashQSPIHandle != NULL)
        {
            if(fblFlashBaseAddr != 0xFFFFFFFF)
            {
                retBaseAddr = fblFlashBaseAddr + FLASH_APP_1_ADDR_BEGIN;
            }
        }
    
        return retBaseAddr;
    }
    
    uint32_t flash_get_app_1_end_addr(void)
    {
        uint32_t retBaseAddr = 0xFFFFFFFF;
        
        if(gFlashQSPIHandle != NULL)
        {
            if(fblFlashBaseAddr != 0xFFFFFFFF)
            {
                retBaseAddr = fblFlashBaseAddr + FLASH_APP_1_ADDR_END;
            }
        }
    
        return retBaseAddr;
    }
    
    
    uint32_t flash_get_app_2_base_addr(void)
    {
        uint32_t retBaseAddr = 0xFFFFFFFF;
    
        if(gFlashQSPIHandle != NULL)
        {
            if(fblFlashBaseAddr != 0xFFFFFFFF)
            {
                retBaseAddr = fblFlashBaseAddr + FLASH_APP_2_ADDR_BEGIN;
            }
        }
    
        return retBaseAddr;
    }
    
    uint32_t flash_get_app_2_end_addr(void)
    {
        uint32_t retBaseAddr = 0xFFFFFFFF;
        
        if(gFlashQSPIHandle != NULL)
        {
            if(fblFlashBaseAddr != 0xFFFFFFFF)
            {
                retBaseAddr = fblFlashBaseAddr + FLASH_APP_2_ADDR_END;
            }
        }
    
        return retBaseAddr;
    }
    
    
    int32_t flash_write(uint32_t memAddr, uint32_t dataLen, uint8_t* dataBuffAddr)
    {
        int32_t retVal = 0;
    
        if(gFlashQSPIHandle != NULL)
        {
    	    QSPIFlash_singleWrite(gFlashQSPIHandle, memAddr, dataLen, dataBuffAddr);
        }
        
    	return retVal;
    }
    
    int32_t flash_read(uint32_t memAddr, uint32_t dataLen, uint8_t* dataBuffAddr)
    {
        int32_t retVal = 0;
    
        if(gFlashQSPIHandle != NULL)
        {
            QSPIFlash_singleRead(gFlashQSPIHandle, memAddr, dataLen, dataBuffAddr);
        }
        
        return retVal;
    }
    
    void flash_close(void)
    {
        if(gFlashQSPIHandle != NULL)
        {
            QSPIFlash_close(gFlashQSPIHandle);
            if(gFlashQSPIDrv != NULL)
            {
                QSPI_close(gFlashQSPIDrv);
            }
        }
    
        if(gFlashDmaHandle != NULL)
        {
            DMA_close(gFlashDmaHandle);
        }
    }
    
    int32_t flash_enable_MmapRead(void)
    {
        DMA_Params      dmaParams;
        int32_t         retVal = -1;
    
        /* Initialize DMA parameters */
        DMA_Params_init(&dmaParams);
    
        /* Open DMA driver instance 0 for SPI test */
        gFlashDmaHandle = DMA_open(0, &dmaParams, &retVal);
    
        if(gFlashDmaHandle == NULL)
        {
            /* Open DMA driver failed with error */
            return retVal;
        }
    
        if(gFlashQSPIHandle != NULL)
        {
            /* Memory map read back from FLASH in Quad mode */
            QSPIFlash_configMmapRead(gFlashQSPIHandle, FLASH_QUAD_MODE);
            retVal = 0;
        }
    
        return retVal;
    }
    
    int32_t flash_dma_read(uint32_t srcAddr, uint32_t dstAddr, uint32_t dataLen)
    {
        int32_t         retVal = -1;
    
        if(gFlashQSPIHandle != NULL && gFlashDmaHandle != NULL)
        {
            retVal = QSPIFlash_sysDmaRead(gFlashQSPIHandle, gFlashDmaHandle, FLASH_USED_DAM_CH, srcAddr, dstAddr, dataLen);
        }
    
        return retVal;
    }
    
    int32_t flash_mmap_read(const uint32_t *memAddr, uint32_t dataLen, uint32_t* userDataBuf)
    {
        int32_t         retVal = -1;
    
        if(gFlashQSPIHandle != NULL)
        {
            retVal = QSPIFlash_mmapRead(gFlashQSPIHandle, memAddr, dataLen, userDataBuf);
        }
    
        return retVal;
    }
    
    void flash_test(void)
    {
    	int32_t cmpVal = 0;
    	int32_t retVal = 0;
    	uint32_t idx;
    	uint32_t idxEnd;
    	uint8_t wVal;
    	uint32_t fblAddr;
    
    
    	flash_erase_app1();
    
    	wVal = 0xFF;
    	fblAddr = flash_get_app_1_base_addr();
    	idxEnd = 512 / TEST_BUFFER_SIZE;
    
    	for(idx = 0; idx < idxEnd; idx++)
    	{
    		fblAddr = fblAddr + (idx * TEST_BUFFER_SIZE);
    		wVal = wVal + idx;
    		memset(fblTestwDataBuff, wVal, sizeof(fblTestwDataBuff));
    		retVal = flash_write(fblAddr, TEST_BUFFER_SIZE, fblTestwDataBuff);
    		if(retVal != 0)
    		{
    			/* Error */
    			break;
    		}
    
    		retVal = flash_read(fblAddr, TEST_BUFFER_SIZE, fblTestrDataBuff);
    		if(retVal != 0)
    		{
    			/* Error */
    			break;
    		}
    
    		/* Check Data */
    		retVal = memcmp(fblTestrDataBuff, fblTestwDataBuff, TEST_BUFFER_SIZE);
    		if(retVal != 0)
    		{
    			/* Error */
    			cmpVal = -1;
    			break;
    		}
    	}
    
    	if(cmpVal != 0)
    	{
    		flash_close();
    		
    		while(1);
    	}
    }
    
    
    
    

  • And I confirmed the QSPI content in TRM(SWRU520A–May 2017–Revised June 2017).

    page 2463 "23.2.1.2 SFI Translator"
    >> 4. 0 to 3 dummy bytes are issued, if “fast read” is supported.
    What does this mean?
  • Please give an example of the issue that you are seeing. If you are using SDK 2.0, then you must be using an ES2 AWR1642.

    -dave
  • Hi

    I am using an ES2 AWR1642.

    also use QS samples.

    Thanks

  • Hello Mr. Kim,

    Can you confirm which flash part are you using.

    Spansion, Macronix?

    Exact part number would be more helpful

    Regards,
    Kaushal
  • Hi Kaushal

    MACRONIX MX25L3233F is used.

    I have changed the QSPIFLASH_DVR_SOURCES setting in the qspiflashlib.mak file.

    QSPIFLASH_DRV_SOURCES += qspiflash_device_spansion.c -> QSPIFLASH_DRV_SOURCES += qspiflash_device_macronix.c

    and I am using qspiflash rebuild by gmak it.

     

    Thanks.

    -Changyu Kim

  • If you are using an unmodified AWR1642, the QSPI driver should work. Please provide an example of what you are seeing.
  • It turns out that the flash was changed on the ES2 AWR1642 EVMs.  The SDK team is aware of this issue and it will be fixed in the next release.

      -dave

  • Ok.

    So how should I use it?

    QSPIFlash_singleRead(QSPHandle, readAddr+1, dataLen, dataBuffAddr);
    I am using it this way.
    I think there is no problem, how about your?

    When is the next release scheduled?

    -Chan-gyu Kim
  • The SDK team recommends adding -1 to the read address. If your fix allows you to read back the same buffer that you wrote, then it is correct.

    I don't see a date for the 2.1 SDK release, but I think it is scheduled for August.