Enable DDR mode for S28HL512

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Casper_LScontro
Level 1
Level 1
10 sign-ins 5 replies posted 5 sign-ins

Dear Cypress support,

We have been trying to get the S28HL512 to work with our stm32h735.

When using the single spi settings and command we are able to write and read to flash, but when setting the CFR5V[1] bit  high at the address 0x00800006 after sending a write enable command  to set STRV[1] high, i can read it back using a bit mask and confirm the bit have been set.

After the CFR5V[1]  is set i'm still able to read the bit and poll the STR1V[0] bit to see if the reading have been sucessful using single spi commands and communication which should not be allowed due to the  CFR5V[1]  being high?

When reading the device ready bit using double byte commands in ddr mode and afterwards poll the device ready bit we get a time our error.

Is there another configuration needed to be set in order to use DDR mode?

I suspect i have done something wrong due to still be able to use single spi commands in what i suppose is DDR mode enable?

static void OSPI_OctalModeCfg(OSPI_HandleTypeDef *hospi)
{
OSPI_RegularCmdTypeDef sCommand;
OSPI_AutoPollingTypeDef sConfig;
uint8_t reg;

/* Enable write operations ---------------------------------------- */
sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG;
sCommand.FlashId = HAL_OSPI_FLASH_ID_1;
sCommand.Instruction = WRITE_ENABLE_CMD;
sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE;
sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS;
sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE;
sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE;
sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE;
sCommand.DataMode = HAL_OSPI_DATA_NONE;
sCommand.DummyCycles = 0;
sCommand.DQSMode = HAL_OSPI_DQS_DISABLE;
sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD;

if (HAL_OSPI_Command(hospi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
Error_Handler();
}

/* Configure automatic polling mode to wait for write enabling ---- */
sCommand.Instruction = READ_STATUS_REG_CMD;
sCommand.DataMode = HAL_OSPI_DATA_1_LINE;
sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_DISABLE;
sCommand.NbData = 1;

if (HAL_OSPI_Command(hospi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
Error_Handler();
}

sConfig.Match = WRITE_ENABLE_MATCH_VALUE;
sConfig.Mask = WRITE_ENABLE_MASK_VALUE;
sConfig.MatchMode = HAL_OSPI_MATCH_MODE_AND;
sConfig.Interval = AUTO_POLLING_INTERVAL;
sConfig.AutomaticStop = HAL_OSPI_AUTOMATIC_STOP_ENABLE;

if (HAL_OSPI_AutoPolling(hospi, &sConfig, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
Error_Handler();
}

/* Write Configuration register 2 (with new dummy cycles) --------- */
sCommand.Instruction = 0x71;
sCommand.Address = 0x00800003;
sCommand.AddressMode = HAL_OSPI_ADDRESS_1_LINE;
sCommand.AddressSize = HAL_OSPI_ADDRESS_32_BITS;
sCommand.AddressDtrMode = HAL_OSPI_ADDRESS_DTR_DISABLE;

if (HAL_OSPI_Command(hospi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
Error_Handler();
}

reg = 0x02;

if (HAL_OSPI_Transmit(hospi, &reg, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
Error_Handler();
}

/* Wait that the memory is ready ---------------------------------- */
sCommand.Instruction = 0x65;
//sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE;
sCommand.Address = 0x00800000;


if (HAL_OSPI_Command(hospi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
Error_Handler();
}

sConfig.Match = 0x00;
sConfig.Mask = MEMORY_READY_MASK_VALUE;

if (HAL_OSPI_AutoPolling(hospi, &sConfig, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
Error_Handler();
}

/* Enable write operations ---------------------------------------- */
sCommand.Instruction = WRITE_ENABLE_CMD;
sCommand.DataMode = HAL_OSPI_DATA_NONE;

if (HAL_OSPI_Command(hospi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
Error_Handler();
}

/* Configure automatic polling mode to wait for write enabling ---- */
sCommand.Instruction = READ_STATUS_REG_CMD;
sCommand.DataMode = HAL_OSPI_DATA_1_LINE;

if (HAL_OSPI_Command(hospi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
Error_Handler();
}

sConfig.Match = WRITE_ENABLE_MATCH_VALUE;
sConfig.Mask = WRITE_ENABLE_MASK_VALUE;

if (HAL_OSPI_AutoPolling(hospi, &sConfig, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
Error_Handler();
}

 

and the defines is like this

#define OSPI_FLASH_SIZE 26
#define OSPI_PAGE_SIZE 256
//#define DUMMY_CYCLES_REG_OCTAL_DTR 8U
//#define DUMMY_CYCLES_REG_OCTAL 8U
#define DUMMY_CYCLES_REG_OCTAL_DTR 1U
#define DUMMY_CYCLES_REG_OCTAL 1U
/* Flash commands */
#define OCTAL_IO_DTR_READ_CMD 0xEEEE
#define OCTAL_PAGE_PROG_CMD 0x1212
#define OCTAL_READ_STATUS_REG_CMD 0x0505
#define OCTAL_SECTOR_ERASE_CMD 0x2121
//#define OCTAL_WRITE_ENABLE_CMD 0x06F9
#define OCTAL_WRITE_ENABLE_CMD 0x0606U
//#define MX25LM51245G_OCTA_READ_ID_CMD 0x9F60U /*!< Octa Read IDentification */
#define MX25LM51245G_OCTA_READ_ID_CMD 0x9F9FU
#define READ_STATUS_REG_CMD 0x05
#define WRITE_CFG_REG_2_CMD 0x72
#define WRITE_ENABLE_CMD 0x06
#define MX25LM51245G_READ_ID_CMD 0x9FU /*!< Read IDentification
/* Dummy clocks cycles */
#define DUMMY_CLOCK_CYCLES_READ 6
#define DUMMY_CLOCK_CYCLES_READ_REG 4
//#define DUMMY_CLOCK_CYCLES_READ_OCTAL 20
#define DUMMY_CYCLES_READ_OCTAL 8U
/* Auto-polling values */
#define WRITE_ENABLE_MATCH_VALUE 0x02
#define WRITE_ENABLE_MASK_VALUE 0x02

#define MEMORY_READY_MATCH_VALUE 0x00
#define MEMORY_READY_MASK_VALUE 0x01

/* Write Configuration register 2 (with octal mode) --------------- */
sCommand.Instruction = 0x71;
sCommand.Address = 0x00800006;
sCommand.AddressMode = HAL_OSPI_ADDRESS_1_LINE;

if (HAL_OSPI_Command(hospi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
Error_Handler();
}

reg = 0x42;

if (HAL_OSPI_Transmit(hospi, &reg, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
Error_Handler();
}
/* Wait that the memory is ready ---------------------------------- */
sCommand.Instruction = 0x65;
//sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE;
sCommand.Address = 0x00800000;


if (HAL_OSPI_Command(hospi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
Error_Handler();
}

sConfig.Match = 0x00;
sConfig.Mask = MEMORY_READY_MASK_VALUE;

if (HAL_OSPI_AutoPolling(hospi, &sConfig, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
Error_Handler();
}

/* Wait that the memory is ready ---------------------------------- */
sCommand.Instruction = 0x65;
//sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE;
sCommand.Address = 0x00800006;


if (HAL_OSPI_Command(hospi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
Error_Handler();
}

sConfig.Match = 0x01;
sConfig.Mask = 0x02;

if (HAL_OSPI_AutoPolling(hospi, &sConfig, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
Error_Handler();
}
/* Wait that the configuration is effective and check that memory is ready */
HAL_Delay(MEMORY_REG_WRITE_DELAY);

/* Wait that the memory is ready ---------------------------------- */
OSPI_AutoPollingMemReady(hospi);
}

and the defines is as follow

#define OSPI_FLASH_SIZE 26
#define OSPI_PAGE_SIZE 256
//#define DUMMY_CYCLES_REG_OCTAL_DTR 8U
//#define DUMMY_CYCLES_REG_OCTAL 8U
#define DUMMY_CYCLES_REG_OCTAL_DTR 1U
#define DUMMY_CYCLES_REG_OCTAL 1U
/* Flash commands */
#define OCTAL_IO_DTR_READ_CMD 0xEEEE
#define OCTAL_PAGE_PROG_CMD 0x1212
#define OCTAL_READ_STATUS_REG_CMD 0x0505
#define OCTAL_SECTOR_ERASE_CMD 0x2121
//#define OCTAL_WRITE_ENABLE_CMD 0x06F9
#define OCTAL_WRITE_ENABLE_CMD 0x0606U
//#define MX25LM51245G_OCTA_READ_ID_CMD 0x9F60U /*!< Octa Read IDentification */
#define MX25LM51245G_OCTA_READ_ID_CMD 0x9F9FU
#define READ_STATUS_REG_CMD 0x05
#define WRITE_CFG_REG_2_CMD 0x72
#define WRITE_ENABLE_CMD 0x06
#define MX25LM51245G_READ_ID_CMD 0x9FU /*!< Read IDentification
/* Dummy clocks cycles */
#define DUMMY_CLOCK_CYCLES_READ 6
#define DUMMY_CLOCK_CYCLES_READ_REG 4
//#define DUMMY_CLOCK_CYCLES_READ_OCTAL 20
#define DUMMY_CYCLES_READ_OCTAL 8U
/* Auto-polling values */
#define WRITE_ENABLE_MATCH_VALUE 0x02
#define WRITE_ENABLE_MASK_VALUE 0x02

#define MEMORY_READY_MATCH_VALUE 0x00
#define MEMORY_READY_MASK_VALUE 0x01

0 Likes
1 Solution
Apurva_S
Moderator
Moderator
Moderator
100 likes received 500 replies posted 250 solutions authored

Hi @Casper_LScontro 

In S28HL512T device, SPI mode supports only SDR whereas OPI (octal peripheral interface) mode supports both SDR and DDR. It is mentioned on page 6 of the datasheet.

Regards.

View solution in original post

0 Likes
4 Replies
Apurva_S
Moderator
Moderator
Moderator
100 likes received 500 replies posted 250 solutions authored

Hi @Casper_LScontro 

In S28HL512T device, SPI mode supports only SDR whereas OPI (octal peripheral interface) mode supports both SDR and DDR. It is mentioned on page 6 of the datasheet.

Regards.

0 Likes
Casper_LScontro
Level 1
Level 1
10 sign-ins 5 replies posted 5 sign-ins

Thanks for the quick answer.

first of i can see i got the code copied twice in the above case so sorry for that.

So to make sure i understand it correctly, so due to me sending a single spi command even though the DDR bit is set i am still able to communicate with it so this is expected behavior?

best regards Casper

0 Likes
Apurva_S
Moderator
Moderator
Moderator
100 likes received 500 replies posted 250 solutions authored

Hi @Casper_LScontro 

S28HL512T device only supports (1S-1S-1S), (8S-8S-8S) and (8D-8D-8D) interface. There is no (1D-1D-1D) interface. Since you have only set the CFR5V[1] bit to 1 (DDR enabled) but you have not changed the interface to OPI (Octal Peripheral Interface) (CFR5[0] bit is still 0 indicating SPI interface), the flash may ignore the CFR5V[1] bit and still operate in SPI SDR mode (1S-1S-1S).

Regards.

0 Likes

Thank you for the further clarification your initial answer helped me find the reason as you also describe above. Another reason for the wrong readings were down to the default address size were 3 bytes and not 4 as I faulty thought when i corrected these two things I got it working both in octo and spi mode. 

I can now read,write and operate the flash in memory mapped mode using the stm32 OCTOSPI driver.

Best Regards Casper

0 Likes