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.

IWR1642BOOST: Can't open QSPI flash

Part Number: IWR1642BOOST
Other Parts Discussed in Thread: UNIFLASH, IWR1642, IWR1443

I took the test code and tried to execute it as a cli command.  Here is my code.  It does not return from the QSPIFlash_open.  What is wrong.  Is there a compiler option I need to set?  I followed the instructions from SWRA583.   

#define TEST_DATA_LENGTH 4096U

uint8_t gTestDataArray[TEST_DATA_LENGTH];

/* System DMA handle, created in init Task */
DMA_Handle gDmaHandle = NULL;
QSPI_Handle gQSPIDrv = (QSPI_Handle)NULL;

int32_t test_qspiflash(int32_t argc, char* argv[])
{
DMA_Params dmaParams;
int32_t retVal = 0;
uint32_t flashAddr = 0U;
SPIFLASH_devID devId;
uint32_t index;
uint32_t testDataLen = 0U;
uint8_t* readDataArray;
QSPI_Params QSPIParams;
QSPIFlash_Handle QSPIFlashHandle = NULL;
uint32_t dmaChan = 10;

/**************************************************************************
* Test: MCPI_Initialize
**************************************************************************/
/* Setup the PINMUX to bring out the QSPI */
Pinmux_Set_OverrideCtrl(SOC_XWR16XX_PINR12_PADAP, PINMUX_OUTEN_RETAIN_HW_CTRL, PINMUX_INPEN_RETAIN_HW_CTRL);
Pinmux_Set_FuncSel(SOC_XWR16XX_PINR12_PADAP, SOC_XWR16XX_PINR12_PADAP_QSPI_CLK);

Pinmux_Set_OverrideCtrl(SOC_XWR16XX_PINP11_PADAQ, PINMUX_OUTEN_RETAIN_HW_CTRL, PINMUX_INPEN_RETAIN_HW_CTRL);
Pinmux_Set_FuncSel(SOC_XWR16XX_PINP11_PADAQ, SOC_XWR16XX_PINP11_PADAQ_QSPI_CSN);

Pinmux_Set_OverrideCtrl(SOC_XWR16XX_PINR13_PADAL, PINMUX_OUTEN_RETAIN_HW_CTRL, PINMUX_INPEN_RETAIN_HW_CTRL);
Pinmux_Set_FuncSel(SOC_XWR16XX_PINR13_PADAL, SOC_XWR16XX_PINR13_PADAL_QSPI_D0);

Pinmux_Set_OverrideCtrl(SOC_XWR16XX_PINN12_PADAM, PINMUX_OUTEN_RETAIN_HW_CTRL, PINMUX_INPEN_RETAIN_HW_CTRL);
Pinmux_Set_FuncSel(SOC_XWR16XX_PINN12_PADAM, SOC_XWR16XX_PINN12_PADAM_QSPI_D1);

Pinmux_Set_OverrideCtrl(SOC_XWR16XX_PINR14_PADAN, PINMUX_OUTEN_RETAIN_HW_CTRL, PINMUX_INPEN_RETAIN_HW_CTRL);
Pinmux_Set_FuncSel(SOC_XWR16XX_PINR14_PADAN, SOC_XWR16XX_PINR14_PADAN_QSPI_D2);

Pinmux_Set_OverrideCtrl(SOC_XWR16XX_PINP12_PADAO, PINMUX_OUTEN_RETAIN_HW_CTRL, PINMUX_INPEN_RETAIN_HW_CTRL);
Pinmux_Set_FuncSel(SOC_XWR16XX_PINP12_PADAO, SOC_XWR16XX_PINP12_PADAO_QSPI_D3);

/* Debug Message: */
CLI_write("******************************************\n");
CLI_write("Debug: QSPI Driver Test Application Start \n");
CLI_write("******************************************\n");

/* Initialize the QSPI Driver */
QSPI_init();

/* Initialize the QSPI Flash */
QSPIFlash_init();

/* Open QSPI driver */
QSPI_Params_init(&QSPIParams);

/* Set the QSPI peripheral clock to 200MHz */
QSPIParams.qspiClk = 200 * 1000000U;

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(=5, setup by QSPI driver internally)
*/
QSPIParams.bitRate = 40 * 1000000U;

gQSPIDrv = QSPI_open(&QSPIParams, &retVal);

if(gQSPIDrv == NULL)
{
CLI_write("QSPI_open failed with error=%d\n", retVal);
goto Exit;
}

/* Init SYSDMA params */
DMA_Params_init(&dmaParams);

/* Open DMA driver instance 0 for SPI test */
gDmaHandle = DMA_open(0, &dmaParams, &retVal);

if(gDmaHandle == NULL)
{
CLI_write("Open DMA driver failed returned null\n");
return -1;
}

readDataArray = Memory_alloc (NULL, TEST_DATA_LENGTH, 64, NULL);
if(readDataArray == NULL)
{
CLI_write("Test array allocation failed\n");
}
else
{
CLI_write("Test array allocation -> 0x%x\n\n", readDataArray);
}

/**************************************************************************
* Test: Open API test
**************************************************************************/

/* Open the QSPI Instance */
QSPIFlashHandle = QSPIFlash_open(gQSPIDrv, &retVal);
if (QSPIFlashHandle == NULL )
{
CLI_write ("QSPIFlash Open returned null");
goto Exit;
}
else
{
CLI_write ("QSPIFlash Open API passed ");

/* Graceful shutdown */
QSPIFlash_close(QSPIFlashHandle);
CLI_write("Debug: QSPIFlash Instance has been closed successfully\n");
}

  • Hi,

    1. Have you been able to program the EVM using uniflash and running the OOB demo? need to confirm the board works fine.
    2. Is this a custom board using a flash drive different from the recommendation?

    Regards,
    Charles O
  • Yes, the is a working IWR1642 Boost board from Ti. I have been running the demo code and everything is working fine. I have flash programs many times. It is not a custom board. Does the Boost board have user writeable flash. The instructions do not speak about external flash drivers. I thought QSPI flash was the on board serial flash for storing programs. I am using one sector to store config information.
  • Hi Charles. Any word on this? It has been 5 days with no activity.
  • Hi,

    I ran this and it works just fine. Please try loading the .xer4f file  using code composer and running it.  using code composer and running it.

  • I'm having problems importing the test code. Any guides or hints how to make the test code into a ccs project?
  • You dont need the CCS project to run the file.
    1. Launch the selected configuration for IWR1642 that you have set up
    2. load the .xer4f file under run > load > load program
    3. click run

    Regards,
    Charles O
  • Yes, but the point is to start using the flash code. I am starting with the MMWAVE people count demo, and I'm trying to access QSPI flash. If I can't compile the code, I can't use the flash.
  • Hi,

    You will need to add the parts of the QSPI flash code you need to the people count demo. I think that's an easier way to go about it.
    You can also refer to the level sense demo for SPI reference
    www.ti.com/.../TIDEP-01000

    Regards,
    Charles O
  • We have come full circle. If you read my original post, I was using my existing people count application and adding QSPI access to that application. The QSPIFlash_open function did not return (it hung). I need pointers on how to debug this, or what I have done incorrectly. I see the SDK provides 3 different flash drivers with redundant jump tables. Could that be a problem?
  • The level sense demo has the QSPI flash and can be used as reference. Can you please see if this helps?
  • Can you narrow it down to a lab from the industrial SDK. You are pointing me to the website for the 68xx. I would like to know which demo software you are referring. There are 5 demo applications to choose from. Which one uses QSPI?
  • Also, from the BOM of the 1642 boost board i gathered that the external flash is Macronx. Can you confirm that that is the correct part, and that I use the qspiflash_device_macronix.c file to interface with external flash.

    From the QSPIFlashGetStatus, I am getting
    /* Read status */
    status = QSPIFlashGetStatus(QSPIHandle, ptrFlashParams->readSR1Cmd);
    CLI_write("status1 = %x\n", status);


    status = QSPIFlashGetStatus(QSPIHandle, ptrFlashParams->readSR2Cmd);
    CLI_write("status2 = %x\n", status);

    status = QSPIFlashGetStatus(QSPIHandle, ptrFlashParams->readSR3Cmd);
    CLI_write("status3 = %x\n", status);

    Status1 = 40
    Status2 = 0
    Status3 = 0

    How can I tell I am using the right driver.
  • HI,

    I am referring to the level sensing TI design that uses the IWR1443. The SPI implementation is quite similar
    www.ti.com/.../TIDEP-0091

    Regarding the serial flash, you can check the BOM for the EVM available under design files or read the part number off the part itself.

    Regards,
    Charles O
  • There is no lab called level sense. None of the labs in the industrial toolbox 3.1.1 have any reference to QSPI. So there was no code that I can use as template. The only references is in the driver directory, and the test code for QSPI and QSPI_flash.
  • Nevermind. I found it.
  • Here is the code that worked for people's information.

    DMA_Params dmaParams;
    int32_t retVal = 0;
    uint32_t flashAddr = 0U;
    //SPIFLASH_devID devId;
    int32_t read_rcode = 0;
    uint32_t testDataLen = 256U * 4U; // Flash sector length is 4k
    uint8_t* readDataArray;
    QSPI_Params QSPIParams;
    QSPIFlash_Handle QSPIFlashHandle = NULL;
    DMA_Handle gDmaHandle = NULL;
    QSPI_Handle gQSPIDrv = (QSPI_Handle)NULL;


    CLI_write("read_zan_config: Reading Flash length=%d,%d,%d,%d\n",
    sizeof(MmwDemo_MCB),sizeof(SceneryParams),sizeof(GatingParams),sizeof(StateParams),sizeof(AllocationParams));
    readDataArray = Memory_alloc (NULL, testDataLen, 64, NULL);
    application_cfg *overlay = (application_cfg *)&readDataArray[0];
    if(readDataArray == NULL) {
    CLI_write("read_zan_config: Not enough memory for buffer");
    read_rcode = -3;
    goto READ_CONFIG_EXIT;
    }

    /* Setup the PINMUX to bring out the MibSpiA */
    Pinmux_Set_OverrideCtrl(SOC_XWR16XX_PIND13_PADAD, PINMUX_OUTEN_RETAIN_HW_CTRL, PINMUX_INPEN_RETAIN_HW_CTRL);
    Pinmux_Set_FuncSel(SOC_XWR16XX_PIND13_PADAD, SOC_XWR16XX_PIND13_PADAD_SPIA_MOSI);

    Pinmux_Set_OverrideCtrl(SOC_XWR16XX_PINE14_PADAE, PINMUX_OUTEN_RETAIN_HW_CTRL, PINMUX_INPEN_RETAIN_HW_CTRL);
    Pinmux_Set_FuncSel(SOC_XWR16XX_PINE14_PADAE, SOC_XWR16XX_PINE14_PADAE_SPIA_MISO);

    Pinmux_Set_OverrideCtrl(SOC_XWR16XX_PINE13_PADAF, PINMUX_OUTEN_RETAIN_HW_CTRL, PINMUX_INPEN_RETAIN_HW_CTRL);
    Pinmux_Set_FuncSel(SOC_XWR16XX_PINE13_PADAF, SOC_XWR16XX_PINE13_PADAF_SPIA_CLK);

    Pinmux_Set_OverrideCtrl(SOC_XWR16XX_PINC13_PADAG, PINMUX_OUTEN_RETAIN_HW_CTRL, PINMUX_INPEN_RETAIN_HW_CTRL);
    Pinmux_Set_FuncSel(SOC_XWR16XX_PINC13_PADAG, SOC_XWR16XX_PINC13_PADAG_SPIA_CSN);

    Pinmux_Set_OverrideCtrl(SOC_XWR16XX_PINP13_PADAA, PINMUX_OUTEN_RETAIN_HW_CTRL, PINMUX_INPEN_RETAIN_HW_CTRL);
    Pinmux_Set_FuncSel(SOC_XWR16XX_PINP13_PADAA, SOC_XWR16XX_PINP13_PADAA_SPI_HOST_INTR);

    QSPI_init(); /* Nothing */
    QSPIFlash_init(); /* Nothing */
    QSPI_Params_init(&QSPIParams); /* Copy default QSPI parms to structurer */
    QSPIParams.qspiClk = 200 * 1000000U; /* Set the QSPI peripheral clock to 200MHz */
    QSPIParams.clkMode = QSPI_CLOCK_MODE_0;
    QSPIParams.bitRate = 40 * 1000000U; /* Running at 40MHz QSPI bit rate
    * BitClockRate = qspiClk/divisor(=5, setup by QSPI driver internally) */
    gQSPIDrv = QSPI_open(&QSPIParams, &retVal); // Init parms and structures.
    if(gQSPIDrv == NULL) {
    CLI_write("read_zan_config: QSPI_open failed with error=%d\n", retVal);
    read_rcode = -1;
    goto READ_CONFIG_EXIT;
    }

    DMA_Params_init(&dmaParams); /* Init SYSDMA params */
    gDmaHandle = DMA_open(0, &dmaParams, &retVal); /* Open DMA driver instance 0 for SPI test */
    if(gDmaHandle == NULL) {
    CLI_write("read_zan_config: Open DMA driver failed with error=%d\n", retVal);
    read_rcode = -2;
    goto READ_CONFIG_EXIT;
    }


    /**************************************************************************
    * Open QSPIFlash
    **************************************************************************/
    Pinmux_Set_OverrideCtrl(SOC_XWR16XX_PINP11_PADAQ, PINMUX_OUTEN_RETAIN_HW_CTRL, PINMUX_INPEN_RETAIN_HW_CTRL);
    Pinmux_Set_FuncSel(SOC_XWR16XX_PINP11_PADAQ, SOC_XWR16XX_PINP11_PADAQ_QSPI_CSN);

    Pinmux_Set_OverrideCtrl(SOC_XWR16XX_PINR13_PADAL, PINMUX_OUTEN_RETAIN_HW_CTRL, PINMUX_INPEN_RETAIN_HW_CTRL);
    Pinmux_Set_FuncSel(SOC_XWR16XX_PINR13_PADAL, SOC_XWR16XX_PINR13_PADAL_QSPI_D0);

    Pinmux_Set_OverrideCtrl(SOC_XWR16XX_PINN12_PADAM, PINMUX_OUTEN_RETAIN_HW_CTRL, PINMUX_INPEN_RETAIN_HW_CTRL);
    Pinmux_Set_FuncSel(SOC_XWR16XX_PINN12_PADAM, SOC_XWR16XX_PINN12_PADAM_QSPI_D1);

    Pinmux_Set_OverrideCtrl(SOC_XWR16XX_PINR14_PADAN, PINMUX_OUTEN_RETAIN_HW_CTRL, PINMUX_INPEN_RETAIN_HW_CTRL);
    Pinmux_Set_FuncSel(SOC_XWR16XX_PINR14_PADAN, SOC_XWR16XX_PINR14_PADAN_QSPI_D2);

    Pinmux_Set_OverrideCtrl(SOC_XWR16XX_PINP12_PADAO, PINMUX_OUTEN_RETAIN_HW_CTRL, PINMUX_INPEN_RETAIN_HW_CTRL);
    Pinmux_Set_FuncSel(SOC_XWR16XX_PINP12_PADAO, SOC_XWR16XX_PINP12_PADAO_QSPI_D3);

    QSPIFlashHandle = QSPIFlash_open(gQSPIDrv, &retVal);
    if (QSPIFlashHandle == NULL ) {
    CLI_write ("read_zan_config: QSPIFlash_open:FAIL\n");
    read_rcode = -4;
    goto READ_CONFIG_EXIT;
    }

    /**************************************************************************
    * Test: single write, single read
    **************************************************************************/
    /* Generate data */
    flashAddr = QSPIFlash_getExtFlashAddr(QSPIFlashHandle);

    /* Use offset 15MB as the test area */
    flashAddr = flashAddr + 0x180000U;
    testDataLen = 256U * 4U; // Sector length is 4k

    QSPIFlash_singleRead(QSPIFlashHandle, flashAddr, testDataLen, (uint8_t *)&readDataArray[0]);
    CLI_write("read_zan_config eye_catcher: %x %x %x %x %x %x %x %x\n",readDataArray[0],readDataArray[1],
    readDataArray[2],readDataArray[3],readDataArray[4],readDataArray[5],readDataArray[6],readDataArray[7]);
    retVal = memcmp((void *)&overlay->config_eye_catcher, "scenery ", 8);
    if (retVal != 0) {
    CLI_write("read_zan_config config not saved. saving defaults"); // Defaults initialized above
    testDataLen = 256U * 4U; // Sector length is 4k
    QSPIFlash_sectorErase(QSPIFlashHandle, flashAddr);
    QSPIFlash_singleWrite(QSPIFlashHandle, flashAddr, testDataLen, (uint8_t *)&zan_config);
    } else {
    memcpy((void *)&zan_config, (void *)&readDataArray[0], sizeof(application_cfg)) ;
    CLI_write ("read_zan_config: Config loaded from Flash\n");
    }

    READ_CONFIG_EXIT:
    /* Graceful shutdown */
    QSPIFlash_close(QSPIFlashHandle);
    QSPI_close(gQSPIDrv);
    DMA_close(gDmaHandle);
    return read_rcode;