Skip to main content
Snm.1
Associate III
August 11, 2023
Question

w25q128jv

  • August 11, 2023
  • 10 replies
  • 9052 views

I want to read and write to w25q128jv with stm32l5 octo spi insted of quad spi.. is there anybody help me. ı could not write correctly.. and ı could not erase. correctly. first problem is when ı was write whiel start addres 0 my code write start to the 2. I added my write code. 

 

/**
 * @brief this method can used program page with quad
 * @PAram dat_buffer     : Data storage area
 * @PAram column_address: The address to start reading (maximum 32bit) WB_Serial_NAND_PageDataRead
 * @PAram buffer_size   : The number of bytes to read (maximum 65535)
 * @retval  none
 * NOTE : If you want to this mode you should set QE into the SR2
 */
bool W25Q128JVS::pageProgramWithQuad(uint8_t *dat_buffer, const uint32_t column_address, const uint16_t buffer_size)
{
if(m_ospi == nullptr)
{
return false;
}
 
if(dat_buffer == nullptr)
{
return false;
}
 
return m_ospi->transmitWith0Dummy1LineInstruction1LineAddress4lineData(dat_buffer, QUAD_INPUT_PAGE_PROGRAM, column_address, buffer_size);
}
/**
 * @brief this method can used program page
 * @PAram dat_buffer     : Data storage area
 * @PAram column_address: The address to start reading (maximum 32bit) WB_Serial_NAND_PageDataRead
 * @PAram buffer_size   : The number of bytes to read (maximum 65535)
 * @retval  none
 * NOTE : If you want to this mode you should set QE into the SR2
 */
bool W25Q128JVS::pageProgram(uint8_t *dat_buffer, const uint32_t column_address, const uint16_t buffer_size)
{
if(m_ospi == nullptr)
{
return false;
}
 
if(dat_buffer == nullptr)
{
return false;
}
return m_ospi->transmitWith0Dummy1LineInstruction1Line3ByteAddress(dat_buffer, PAGE_PROGRAM, column_address, column_address);
}

/***************************************************************************************************************/

bool OSPIL552::transmitWith0Dummy1LineInstruction1LineAddress4lineData(uint8_t *data_buffer, const uint32_t instruction, const uint32_t address, const uint16_t buffer_size)
 {
if(data_buffer == NULL)
{
return false;
}
 
OSPI_RegularCmdTypeDef cmd = {0};
 
cmd.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE;
cmd.Instruction = instruction;
cmd.AddressMode = HAL_OSPI_ADDRESS_1_LINE;
cmd.AddressSize = HAL_OSPI_ADDRESS_24_BITS;
cmd.Address = address;
cmd.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE;
cmd.AlternateBytes = HAL_OSPI_ALTERNATE_BYTES_NONE;
cmd.AlternateBytesSize = HAL_OSPI_ALTERNATE_BYTES_NONE;
cmd.DummyCycles = 4;
cmd.DataMode = HAL_OSPI_DATA_4_LINES;
cmd.DataDtrMode = HAL_OSPI_DATA_DTR_DISABLE;
cmd.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD;
cmd.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG;
cmd.NbData = buffer_size;
 
   if (HAL_OSPI_Command(ospi_handle, &cmd, HAL_OSPI_TIMEOUT_DEFAULT_VALUE))
   {
return false;
   }
 
   if (HAL_OSPI_Transmit(ospi_handle, reinterpret_cast<uint8_t *>(data_buffer), HAL_OSPI_TIMEOUT_DEFAULT_VALUE))
   {
return false;
   }
 
   return true;
 }
 

bool OSPIL552::transmitWith0Dummy1LineInstruction1Line3ByteAddress(uint8_t *data_buffer, const uint32_t instruction, const uint32_t address, const uint16_t buffer_size)
{
if(data_buffer == NULL)
{
return false;
}

OSPI_RegularCmdTypeDef cmd = {0};

cmd.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE;
cmd.Instruction = instruction;
cmd.AddressMode = HAL_OSPI_ADDRESS_1_LINE;
cmd.AddressSize = HAL_OSPI_ADDRESS_24_BITS;
cmd.Address = address;
cmd.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE;
cmd.AlternateBytes = HAL_OSPI_ALTERNATE_BYTES_NONE;
cmd.AlternateBytesSize = HAL_OSPI_ALTERNATE_BYTES_NONE;
cmd.DummyCycles = 0;
cmd.DataMode = HAL_OSPI_DATA_1_LINE;
cmd.DataDtrMode = HAL_OSPI_DATA_DTR_DISABLE;
cmd.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD;
cmd.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG;
cmd.NbData = buffer_size;

if (HAL_OSPI_Command(ospi_handle, &cmd, HAL_OSPI_TIMEOUT_DEFAULT_VALUE))
{
return false;
}

if (HAL_OSPI_Transmit(ospi_handle, reinterpret_cast<uint8_t *>(data_buffer), HAL_OSPI_TIMEOUT_DEFAULT_VALUE))
{
return false;
}

return true;

}

 

hospi1.Instance = OCTOSPI1;
hospi1.Init.FifoThreshold = 1;
hospi1.Init.DualQuad = HAL_OSPI_DUALQUAD_DISABLE;
hospi1.Init.MemoryType = HAL_OSPI_MEMTYPE_MICRON;
hospi1.Init.DeviceSize = 32;
hospi1.Init.ChipSelectHighTime = 1;
hospi1.Init.FreeRunningClock = HAL_OSPI_FREERUNCLK_DISABLE;
hospi1.Init.ClockMode = HAL_OSPI_CLOCK_MODE_0;
hospi1.Init.WrapSize = HAL_OSPI_WRAP_NOT_SUPPORTED;
hospi1.Init.ClockPrescaler = 1;
hospi1.Init.SampleShifting = HAL_OSPI_SAMPLE_SHIFTING_NONE;
hospi1.Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_DISABLE;
hospi1.Init.ChipSelectBoundary = 0;
hospi1.Init.DelayBlockBypass = HAL_OSPI_DELAY_BLOCK_BYPASSED;
hospi1.Init.Refresh = 0;
if (HAL_OSPI_Init(&hospi1) != HAL_OK)
{
Error_Handler();
}

}

This topic has been closed for replies.

10 replies

KDJEM.1
ST Technical Moderator
August 11, 2023

Hi @Snm.1 ,

Could you please check the DeviceSize and the dummy cycles values.

Note that the Device size defines the memory size in number of bytes = 2**(DEVSIZE+1).

Thank you.

Kaouthar

To give better visibility on the answered topics, please click on "Best answer" on the reply which solved your issue or answered your question.
David Littell
Senior II
August 11, 2023

Note further that DeviceSize in the .ioc file and in the structure initialization for HAL_OSPI_Init() is the actual device size, not that "-1" BS.  The HAL adjusts the DeviceSize value before writing the register field.  Thanks for the constant source of confusion, ST!

Tesla DeLorean
Guru
August 11, 2023

+1  off-by-one and changing parameter meanings and enumerations between releases and families has been a persistent source of headaches..  https://community.st.com/t5/stm32-mcus/how-to-set-up-the-ospi-peripheral-to-interface-with-the/ta-p/49474

#UseTheSourceLuke

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
KDJEM.1
ST Technical Moderator
August 14, 2023

Hello @David Littell & @Tesla DeLorean ,

Thank you for bringing these issues to our attention. I will check internally.

Sorry for any inconvenience.

Kaouthar

To give better visibility on the answered topics, please click on "Best answer" on the reply which solved your issue or answered your question.
Tesla DeLorean
Guru
August 11, 2023

With the Winbond devices be particularly cognoscente of the dummy cycles and address widths. Device can be in different modes during initialization, and dummy cycles are not configurable on the device side like they are on Micron devices.

The mode switching and protection bits can be different. And Winbond has multiple part variants with different command sets. A large number of the older/smaller parts don't support Status Register 2 writes, you have to write BOTH Status Register 1 and 2 as a PAIR. Watch this as your buyer might not be able to source the same parts for every build, especially buying on the spot market.

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
Tesla DeLorean
Guru
August 11, 2023

Perhaps related? Not clear what your defines are, please post code using the appropriate formatting tool, and provide enough context to unpack what's actually going on.

https://community.st.com/t5/stm32-mcu-products/stm32h563vi-octo-spi-interface-dummy-cycles/td-p/581689

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..