Skip to main content
Visitor II
January 6, 2025
Solved

M95P32 EEPROM using QSPI interface on Nucleo-L496ZGP

  • January 6, 2025
  • 3 replies
  • 1486 views

Board added to title; STM32L4 Label added.


I started Working With M95P32 EEPROM which Supports QSPI . This is my code which is not working I don't understand why there is no error in transmit and receive code. But same EEPROM working with SPI.

 

 

 

void QSPI_WriteEnable(void) {

QSPI_CommandTypeDef sCommand;



sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE;

sCommand.Instruction = WRITE_ENABLE_CMD;

sCommand.AddressMode = QSPI_ADDRESS_NONE;

sCommand.DataMode = QSPI_DATA_NONE;

sCommand.DummyCycles = 0;

sCommand.NbData = 0;

sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;

HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET);

HAL_QSPI_Command(&hqspi, &sCommand, HAL_QSPI_TIMEOUT_DEFAULT_VALUE);

HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET);

}





void QSPI_ChipErase(void) {

QSPI_CommandTypeDef sCommand;





sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE;

sCommand.Instruction = CHIP_ERASE_CMD;

sCommand.AddressMode = QSPI_ADDRESS_NONE;

sCommand.DataMode = QSPI_DATA_NONE;

sCommand.DummyCycles = 0;

sCommand.NbData = 0;

sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;

HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET);

HAL_QSPI_Command(&hqspi, &sCommand, HAL_QSPI_TIMEOUT_DEFAULT_VALUE);

HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET);

}



void QSPI_Write(uint32_t address, uint8_t *data, uint32_t size) {

QSPI_CommandTypeDef sCommand;



QSPI_WriteEnable(); // Enable write



sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE;

sCommand.Instruction = PAGE_PROGRAM_CMD;

sCommand.AddressMode = QSPI_ADDRESS_1_LINE;

sCommand.Address = address;

sCommand.DataMode = QSPI_DATA_4_LINES;

sCommand.NbData = 1;

sCommand.DummyCycles = 0;

sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;

HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET);

HAL_QSPI_Command(&hqspi, &sCommand, HAL_QSPI_TIMEOUT_DEFAULT_VALUE);

for(int i=0; i<size;i++)

{

HAL_QSPI_Transmit(&hqspi, &data[i], HAL_QSPI_TIMEOUT_DEFAULT_VALUE);

printf("sentdata:%0x",data[i]);

}

HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET);

printf("\n");

}



void QSPI_Read(uint32_t address, uint8_t *data, uint32_t size) {

QSPI_CommandTypeDef sCommand;



sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE;

sCommand.Instruction = READ_CMD;

sCommand.AddressMode = QSPI_ADDRESS_1_LINE;

sCommand.Address = address;

sCommand.DataMode = QSPI_DATA_4_LINES;

sCommand.NbData = 1;

sCommand.DummyCycles = 0;

sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;

HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET);

HAL_QSPI_Command(&hqspi, &sCommand, HAL_QSPI_TIMEOUT_DEFAULT_VALUE);

for(int i=0; i<size; i++)

{

HAL_QSPI_Receive(&hqspi, &data[i], HAL_QSPI_TIMEOUT_DEFAULT_VALUE);

printf("%0x",data[i]);

}

HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET);

printf("\n");

}

int main(void)

{

uint8_t dataToWrite[4] = {0x25,0x26,0x27,0x28};





// Write data to EEPROM

QSPI_Write(0x3, dataToWrite, sizeof(dataToWrite));



HAL_Delay(1000);

QSPI_Read(0x3, dataToRead, 4);

}

static void MX_QUADSPI_Init(void)

{



/* USER CODE BEGIN QUADSPI_Init 0 */



/* USER CODE END QUADSPI_Init 0 */



/* USER CODE BEGIN QUADSPI_Init 1 */



/* USER CODE END QUADSPI_Init 1 */

/* QUADSPI parameter configuration*/

hqspi.Instance = QUADSPI;

hqspi.Init.ClockPrescaler = 2;

hqspi.Init.FifoThreshold = 4;

hqspi.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_NONE;

hqspi.Init.FlashSize = 11;

hqspi.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_1_CYCLE;

hqspi.Init.ClockMode = QSPI_CLOCK_MODE_0;

hqspi.Init.FlashID = QSPI_FLASH_ID_1;

hqspi.Init.DualFlash = QSPI_DUALFLASH_DISABLE;

if (HAL_QSPI_Init(&hqspi) != HAL_OK)

{

Error_Handler();

}

/* USER CODE BEGIN QUADSPI_Init 2 */



/* USER CODE END QUADSPI_Init 2 */



}

 

 

 

 

    This topic has been closed for replies.
    Best answer by Tesla DeLorean

    Then you might need to unpack things manually from the traces.

    I would suggest starting with the QSPI in 1-bit interactions, reading the JEDEC ID and SFDP data from it. If you can get that to work you'll need to look at modes and methods to switch to 4-bit operation.

    QSPI_CommandTypeDef sCommand = {0}; // strongly advised for large auto/local structures

    If correctly wired and functional I'd anticipate PA2:AF10 QUADSPI_BK1_NCS, and multi-byte transmit/receiver to be viable

    https://www.st.com/resource/en/datasheet/m95p32-i.pdf

    3 replies

    Super User
    January 6, 2025

    Welcome to the forum.

    Please see How to insert source code.

    Also: How to write your question to maximize your chances to find a solution.

    You haven't said what STM32 you're using, what board(s), or tool versions.

     

    Are you using the X-CUBE-EEPRMA1 Standard I2C and SPI EEPROM software expansion for STM32Cube:

    https://www.st.com/en/embedded-software/x-cube-eeprma1.html

    via: https://www.st.com/en/ecosystems/x-nucleo-pgeez1.html#tools-software

    and: https://www.st.com/en/memories/m95p32-i.html#tools-software 

    Technical Moderator
    January 6, 2025

    Hello @Gowthami412 and welcome to the community,

    First as said by @Andrew Neil you need to use </> to paste your code. I've edited your post.

    Second, which STM32 part number are you using?

    Visitor II
    January 6, 2025

    Ok Thank you. I am using STM Nucleo- L496ZGP board.

    Graduate II
    January 6, 2025

    Where do you call the initialization code?

    Why manual PA2 chip select?

    Why individual byte transfers?

    Clear the sCommand structure as an auto/local variable.

    Use a logic analyzer to confirm signaling on bus.

    It is not designed to report all errors, just those it can detect at the HAL or peripheral level.

    Visitor II
    January 6, 2025

    I am calling initialisation in int main I have initialized all required peripherals in main here I didn't paste. 

    1. I tried using without manual CS it didn't work, so I tried adding manual CS then also didn't work.

    2. I tried sending all bytes at a time it didn't work, so I tried sending byte by byte.

    3. We don't have a logic analyser with support QSPI to decode I tried 

    Graduate II
    January 6, 2025

    Then you might need to unpack things manually from the traces.

    I would suggest starting with the QSPI in 1-bit interactions, reading the JEDEC ID and SFDP data from it. If you can get that to work you'll need to look at modes and methods to switch to 4-bit operation.

    QSPI_CommandTypeDef sCommand = {0}; // strongly advised for large auto/local structures

    If correctly wired and functional I'd anticipate PA2:AF10 QUADSPI_BK1_NCS, and multi-byte transmit/receiver to be viable

    https://www.st.com/resource/en/datasheet/m95p32-i.pdf