cancel
Showing results for 
Search instead for 
Did you mean: 

any idea why it is freezing executing *mem_addr = aTxBuffer[index];

MNapi
Senior III

 

I have this code it transfers to 0x90000000 (OSPI) data

__IO uint8_t *mem_addr;

 

/* USER CODE BEGIN 2 */

HAL_OSPI_MemoryMapped(&hospi1, &sMemMappedCfg)

 

mem_addr = (uint8_t *)(OCTOSPI1_BASE + address);

for (index = 0; index < BUFFERSIZE; index++)

{

*mem_addr = aTxBuffer[index];

mem_addr++;

}

 

it compiles and runs fine but freezes on *mem_addr = aTxBuffer[index];

 

has anybody seen something like this ?

 

 

 

20 REPLIES 20

You can't WRITE to NOR FLASH via the Memory Mapped interface.

You can memcpy() out of the memory, ie READ

memcpy(localarray, (void *)(0x90000000 + addr), sizeof(localarray));

You can't memcpy() into the memory, ie WRITE

memcpy((void *)(0x90000000 + addr), localarray, sizeof(localarray));

The write process on QSPI and OSPI on NOR FLASH is more involved, see MX25LM documentation

Freezes or Hard Faults?

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

Quirk info KEIL work CIDE no. Is used same optimization level ?  But normal for any flash is mapped mode only for high speed read . Writing is more flexi and clean by nonmapped access.

 

Finally I got it working, I followed the codes, instruction from STM and other sources for OSPI

STM example worked fine on STM32L4P5 discovery with the same OSPI flash (512 Mbits) but never on my custom board in CubeIDE. Worked fine in Keil

Here was the problem, I had those 2 first MPU regions enabled as in examples.

I removed (disabled) it and the memory mapped mode suddenly works. It can write and read.

I am still not out of the woods, it does not write first 14 character of the string. Maybe I need some delay

 

1.png

With the MMU, perhaps going off to die in MemManage_Handler() ?

 

/**
  * @brief  This function handles Memory Manage exception.
  *   None
  * @retval None
  */
void MemManage_Handler(void)
{
  /* Go to infinite loop when Memory Manage exception occurs */
  while (1)
  {
  }
}

 

 >>I am still not out of the woods, it does not write first 14 character of the string. Maybe I need some delay

You have to send a Write Enable, wait for that to come ready, then you can send a Write Page command, and write up to 256-bytes aligned on a 256-byte boundary (misalignment subtracts from the size), and then wait for it to come ready again.

Loss of initial data can be attributed to incorrect phases, and clock cycles, related to address, alternate and dummy cycles, etc.

Shifts in the reads can be seen for similar reasons, ie a mismatch between the phases the STM32 is generating, and those that the memory is anticipating in its currently configured mode.

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

For sure there is a problem

I had to add one line, nothing else so far solves the problem

it looks like reading from the flash and writing back for some reason solves the problem, now I have whole string in the memory without errors

 

mem_addr = (__IO uint8_t *)(OCTOSPI1_BASE + address);

for (uint16_t i = 0; i < BUFFERSIZE; i++)

{

dummy_operation[i] = *mem_addr; //without it programming does not work

 

*mem_addr = aTxBuffer[i];

 

mem_addr++;

}

 

putting like HAL_Delay(1); or a++; does not work

and I do not see that changing something in CubeMX solves the problem like Delay Hold Quarter Cycle

 

I do have dummy cycles , write enable, OSPI_AutoPollingMemReady, it is not having any affect. 

Man you're persistent..

I'm pretty sure you can't program OCTOSPI NOR FLASH through the memory mapped interface.

Are you sure you not just pushing data into the local CACHE?

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

I do not know you mean by local cache

the only one I see are here.  disabling or enabling makes no difference.

I do have STM examples I am looking what I might be doing wrong, I cannot find anything missing. there must be something somewhere

1.png

>>I do have STM examples I am looking what I might be doing wrong, I cannot find anything missing. there must be something somewhere

We keep going in circles.

What STM Example do you have where they WRITE to the OSPI/QSPI NOR Devices through the Memory Mapped window at 0x90000000 ?

BECAUSE THAT'S NOT HOW THIS WORKS..

WRITES NEED TO BE DONE IN COMMAND MODE, REQUIRING SEVERAL COMMANDS AND WAITING FOR COMPLETION.

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

I am using this one,

https://www.st.com/en/embedded-software/stm32cubeh7.html

STM32Cube_FW_H7_V1.11.0\Projects\STM32H735G-DK\Examples\OSPI

thought I do not have the board to test it

here is a part of main.c

 

/* Initialization of the OSPI ------------------------------------------ */

OSPIHandle.Instance = OCTOSPI1;

HAL_OSPI_DeInit(&OSPIHandle);

 

OSPIHandle.Init.FifoThreshold = 4;

OSPIHandle.Init.DualQuad = HAL_OSPI_DUALQUAD_DISABLE;

OSPIHandle.Init.MemoryType = HAL_OSPI_MEMTYPE_MACRONIX;

OSPIHandle.Init.DeviceSize = OSPI_FLASH_SIZE; /* 256 MBits */

OSPIHandle.Init.ChipSelectHighTime = 2;

OSPIHandle.Init.FreeRunningClock = HAL_OSPI_FREERUNCLK_DISABLE;

OSPIHandle.Init.ClockMode = HAL_OSPI_CLOCK_MODE_0;

OSPIHandle.Init.WrapSize = HAL_OSPI_WRAP_NOT_SUPPORTED;

OSPIHandle.Init.ClockPrescaler = 6;

OSPIHandle.Init.SampleShifting = HAL_OSPI_SAMPLE_SHIFTING_NONE;

OSPIHandle.Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_ENABLE;

OSPIHandle.Init.ChipSelectBoundary = 0;

 

if (HAL_OSPI_Init(&OSPIHandle) != HAL_OK)

{

Error_Handler();

}

 

/* Configure the memory in octal mode ------------------------------------- */

OSPI_OctalDtrModeCfg(&OSPIHandle);

 

sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG;

sCommand.FlashId = HAL_OSPI_FLASH_ID_1;

sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_8_LINES;

sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_16_BITS;

sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_ENABLE;

sCommand.AddressSize = HAL_OSPI_ADDRESS_32_BITS;

sCommand.AddressDtrMode = HAL_OSPI_ADDRESS_DTR_ENABLE;

sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE;

sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_ENABLE;

sCommand.DQSMode = HAL_OSPI_DQS_DISABLE;

sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD;

 

/* Infinite loop */

while (1)

{

switch(step)

{

case 0:

CmdCplt = 0;

 

/* Enable write operations ------------------------------------------- */

OSPI_WriteEnable(&OSPIHandle);

 

/* Erasing Sequence ----------------------------------------------- */

sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG;

sCommand.Instruction = OCTAL_SECTOR_ERASE_CMD;

sCommand.AddressMode = HAL_OSPI_ADDRESS_8_LINES;

sCommand.DataMode = HAL_OSPI_DATA_NONE;

sCommand.Address = address;

sCommand.DummyCycles = 0;

sCommand.DQSMode = HAL_OSPI_DQS_DISABLE;

 

if (HAL_OSPI_Command_IT(&OSPIHandle, &sCommand) != HAL_OK)

{

Error_Handler();

}

 

step++;

 

break;

 

case 1:

 

if(CmdCplt != 0)

{

CmdCplt = 0;

StatusMatch = 0;

 

/* Configure automatic polling mode to wait for end of erase ------- */

OSPI_AutoPollingMemReady(&OSPIHandle);

 

step++;

}

break;

 

case 2:

 

if(StatusMatch != 0)

{

StatusMatch = 0;

TxCplt = 0;

 

/* Enable write operations ------------------------------------------- */

OSPI_WriteEnable(&OSPIHandle);

 

/* Writing Sequence ------------------------------------------------ */

sCommand.Instruction = OCTAL_PAGE_PROG_CMD;

sCommand.DataMode = HAL_OSPI_DATA_8_LINES;

sCommand.NbData = BUFFERSIZE;

sCommand.Address = address;

 

if (HAL_OSPI_Command(&OSPIHandle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)

{

Error_Handler();

}

 

if (HAL_OSPI_Transmit_IT(&OSPIHandle, aTxBuffer) != HAL_OK)

{

Error_Handler();

}

 

 

step++;

}

break;

 

case 3:

 

if(TxCplt != 0)

{

TxCplt = 0;

StatusMatch = 0;

 

/* Configure automatic polling mode to wait for end of program ----- */

OSPI_AutoPollingMemReady(&OSPIHandle);

 

/* Memory-mapped mode configuration ------------------------------- */

sCommand.OperationType = HAL_OSPI_OPTYPE_WRITE_CFG;

sCommand.DataMode = HAL_OSPI_DATA_8_LINES;

sCommand.NbData = 1;

sCommand.DQSMode = HAL_OSPI_DQS_ENABLE;

sCommand.DummyCycles = 0;

 

if (HAL_OSPI_Command(&OSPIHandle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)

{

Error_Handler();

}

 

sCommand.OperationType = HAL_OSPI_OPTYPE_READ_CFG;

sCommand.Instruction = OCTAL_IO_DTR_READ_CMD;

sCommand.DummyCycles = DUMMY_CLOCK_CYCLES_READ_OCTAL ;

sCommand.DQSMode = HAL_OSPI_DQS_ENABLE;

 

if (HAL_OSPI_Command(&OSPIHandle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)

{

Error_Handler();

}

 

sMemMappedCfg.TimeOutActivation = HAL_OSPI_TIMEOUT_COUNTER_DISABLE;

 

 

if (HAL_OSPI_MemoryMapped(&OSPIHandle, &sMemMappedCfg) != HAL_OK)

{

Error_Handler();

}

 

/* Reading Sequence ----------------------------------------------- */

mem_addr = (__IO uint8_t *)(OCTOSPI1_BASE + address);

for (index = 0; index < BUFFERSIZE ; index++)

{

if (*mem_addr != aTxBuffer[index])

{

BSP_LED_On(LED_RED);

}

mem_addr++;

}

 

BSP_LED_Toggle(LED_GREEN);

HAL_Delay(50);

 

address += OSPI_PAGE_SIZE;

if(address >= OSPI_END_ADDR)

{

address = 0;

}

 

/* Re-Initialize OctoSPI*/

HAL_OSPI_DeInit(&OSPIHandle);

HAL_OSPI_Init(&OSPIHandle);

 

step = 0;

}

 

break;

 

default :

Error_Handler();

}

}

}

 

Ok, but that's using COMMAND MODE to write via OCTOSPI->DR not writing in the *(0x90000000) address space like you're repeatedly claim is failing, as it should.

The example above, and the video, showing it READ the content in MEMORY MAPPED MODE.

The memcpy() works only when the DESTINATION is RAM

If the COMMAND MODE WRITE is failing, on your BOARD, perhaps focus more on the HARDWARE, and the pin differences, and workability of that, rather than play GOOGLE to find code to cut-n-paste.

Or find a DISCO / EVAL board that's KNOWN WORKING, to establish a base-line of functionality to pivot from.

if (*mem_addr != aTxBuffer[index]) // READING READING READING

 

*mem_addr = aTxBuffer[i]; // WRITING !!!! NOT GOING TO WORK PROPERLY

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