cancel
Showing results for 
Search instead for 
Did you mean: 

Memory mapped mode write sizes for PSRAM APS6408L on B-U858I-IOT02A Discovery Kit

rikeshshakya
Associate III

@Alex - APMemory I am trying interface APS6408L on the B-U858I-IOT02A Discovery Kit in OSPI DTR memory mapped mode for both read and writes. The datasheet for APS6408L mentions that the page size for it is 1Kb. 

 

In the memory mapped mode, is it possible to write in a chunk greater than 1Kb for the RAM? I am read this for the memory in the datasheet, 

"Burst Type & Length
Read and write operations are default Hybrid Wrap 32 mode. Other burst lengths of 16, 32, 64 or 1K bytes in
standard or Hybrid wrap modes are register configurable(see Table 20). The device also includes command for
Linear Bursting. Bursts can start on any even address. Write burst length has a minimum of 2 bytes. Read has no
minimum length. Both write and read have no restriction on maximum burst length as long as tCEM is met."

 

I am using memcpy for writing the data in the memory mapped mode. My question is, is it possible to write in blocks greater than 1Kb for this memory?

 

-Rikesh

 

 

 

20 REPLIES 20

Sorry, you're not wanting to perform 1kB+ bursts, i.e. as a single synchronous access. You're only wanting to be able to read/write pages of flash using as many bursts as that would require.

@alister , I am using the driver for the APS6408L PSRAM from the ST https://github.com/STMicroelectronics/stm32-aps6408.

I am also using the BSP driver for the OCTOSPI from ST https://github.com/STMicroelectronics/b-u585i-iot02a-bsp

I did not make any updates to the driver and I am using them as it is in the ST github repository links that I have provided above. Therefore, I believe the memory mapped that I am using is as RM0456 rev 5 section 28.

When I mentioned enabling/disabling the DCache, I was just trying to mention that I did not see any difference in the results of the comparison of the data.

 

When looking at the configuration for the memory mapping in the APS6408 from ST below, my understanding is that the memory mapping is using the synchronous read and write. 

 

int32_t APS6408_EnableMemoryMappedMode(OSPI_HandleTypeDef* Ctx,
                                       uint32_t ReadLatencyCode,
                                       uint32_t WriteLatencyCode,
                                       uint32_t BurstType)
{
    OSPI_RegularCmdTypeDef sCommand;
    OSPI_MemoryMappedTypeDef sMemMappedCfg;

    /* Initialize the write command */
    sCommand.OperationType      = HAL_OSPI_OPTYPE_WRITE_CFG;
    sCommand.FlashId            = HAL_OSPI_FLASH_ID_1;
    sCommand.InstructionMode    = HAL_OSPI_INSTRUCTION_8_LINES;
    sCommand.InstructionSize    = HAL_OSPI_INSTRUCTION_8_BITS;
    sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE;
    sCommand.Instruction        = (BurstType == 0U) ? APS6408_WRITE_LINEAR_BURST_CMD : APS6408_WRITE_CMD;
    sCommand.AddressMode        = HAL_OSPI_ADDRESS_8_LINES;
    sCommand.AddressSize        = HAL_OSPI_ADDRESS_32_BITS;
    sCommand.AddressDtrMode     = HAL_OSPI_ADDRESS_DTR_ENABLE;
    sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE;
    sCommand.DataMode           = HAL_OSPI_DATA_8_LINES;
    sCommand.DataDtrMode        = HAL_OSPI_DATA_DTR_ENABLE;
    sCommand.DummyCycles        = WriteLatencyCode;
    sCommand.DQSMode            = HAL_OSPI_DQS_ENABLE;
    sCommand.SIOOMode           = HAL_OSPI_SIOO_INST_EVERY_CMD;

    if (HAL_OSPI_Command(Ctx, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
    {
        return APS6408_ERROR;
    }

    /* Initialize the read command */
    sCommand.OperationType = HAL_OSPI_OPTYPE_READ_CFG;
    sCommand.Instruction   = APS6408_READ_CMD;
    sCommand.DummyCycles   = ReadLatencyCode;

    if (HAL_OSPI_Command(Ctx, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
    {
        return APS6408_ERROR;
    }

    /* OctoSPI activation of memory-mapped mode */
    sMemMappedCfg.TimeOutActivation = HAL_OSPI_TIMEOUT_COUNTER_ENABLE;
    sMemMappedCfg.TimeOutPeriod     = 0x34U;

    if (HAL_OSPI_MemoryMapped(Ctx, &sMemMappedCfg) != HAL_OK)
    {
        return APS6408_ERROR;
    }

    return APS6408_OK;
}
 
My main confusion is when I use the configuration as in the ST's BSP for B-U585I-IOT02A and for component APS6408L, is it possible to use memcpy operation for size of memory greater than 1024 bytes using the read and write functions that I provided above?
 
I have also received comment from @Tesla DeLorean in the other thread that I mainly created for my confusion on memory mapped mode https://community.st.com/t5/stm32-mcus-products/stm32u585-memory-mapped-read-write-on-b-u585i-iot02a/m-p/663478#M241403
After going through the comments from @Tesla DeLorean , it does seem that there might be a necessity to handle the Row boundary for writes in a special manner. However, since I am fairly new to interfacing this memory with STMU5, any further information will be appreciated.
 
In regards to your feedback above @alister "Sorry, you're not wanting to perform 1kB+ bursts, i.e. as a single synchronous access. You're only wanting to be able to read/write pages of flash using as many bursts as that would require.", my understanding is that I need to do burst writes in block sizes of 1Kb for any data sizes above 1Kb while making sure that any write operation does not cross the Row boundary crossing. Is my understanding correct?
 
Thanks to you @alister@Tesla DeLorean and @Alex - APMemory  for taking time and answering on my confusions.
 
 
 

 

alister
Lead

I'm sorry I can't study the circumstances in detail. My understanding is:

  • You've memory-mapped the APS6408L PSRAM. That places it at an internal address space of the STM32U5. Your code may access any address of the APS6408L PSRAM via that space. For each transfer on the OSPI bus, the address phase value will be the offset of the data from the base of that space, which will be the its address in the APS6408L PSRAM.
  • If D-cache is disabled, when the CPU accesses that internal address space, the STM32U5's CPU will stall (wait) while the STM32U5 completes its transfer to/from the APS6408L PSRAM.
  • If D-cache is enabled, when the CPU accesses that address space and finds it's not in cache, the STM32U5 will first read a cache-line size of data containing the addressed data from the APS6408L PSRAM into its cache, perform the CPU's access against that, and that will remain in the cache. If the access was a write and it changed the data in cache, the cache-line will remember it's been changed and when the CPU next accesses somewhere in the internal address space that's uncached and it must free that cache line for it, it will stall the CPU for slightly longer while it first flushes the line to the APS6408L PSRAM and then proceeds to read the new cache line as described above. If your code manually flushes the cache, the STM32U5 does this for each of the lines in cache if the addresses being flushed whose data had been changed. There are several other cache circumstances that behave much like these and you can find the details on ARM's web or in ST's applicable programmer's manual. A cache line size is 32-bytes. Each cache line address is 32-byte aligned.
  • For most code circumstances, D-cached enabled will operate faster.
  • Neither the CPU nor any STM32U5 bus can perform an access at an address that isn't divisible by its access size. So memory-mapped mode should never care about row-boundary crossings because they can't occur.

Is your enquiry only technical curiosity? If you've observed an errors with memory-mapped mode, you should probably check whether the OCTOSPI's configured to wait long enough for the erase/program to complete.

Not expert. If I've said anything incorrect, please advise. Thanks.

alister
Lead

The RM says both

  • "memory-mapped mode: the external memory is memory mapped and it is seen by the
    system as if it was an internal memory, supporting both read and write operations." and
  • "It is not recommended to program the flash memory using memory-mapped writes, as the internal flags for erase or programming status have to be polled. The indirect-write mode fulfills this operation, possibly in conjunction with the automatic status-polling mode."

I'm describing stuff I'm unfamiliar. To do writes in memory-mapped mode, I expect before changing any data in a page on the APS6408L PSRAM you might:

  • save any of the page you're not modifying to RAM somewhere
  • invalidate the cache of the page in the internal address space
  • switch the OCTOSPI to status-polling mode, erase the page and either wait a safe time or use status-polling mode
  • switch the OCTOSPI back to memory-mapped mode
  • copy back into the internal address space anything of the page you'd saved plus the data you're changing
  • flush the page in cache as it's all changed

Wear-levelling and managing preventing losing that page (it's state prior the change) if there's an unexpected power loss during the erase/program are outside the scope of this post.

rikeshshakya
Associate III

@alister , I am working on a PSRAM, so I believe no erase is necessary here. My initial assumption was that with memory mapped, I would not need to worrry about the Row boundary crossing. However, I am unsure about it.

alister
Lead

Duh. Of course!

alister
Lead

As I'd said earlier, neither the CPU nor any STM32U5 bus can perform an access at an address that isn't divisible by its access size. So memory-mapped mode should never care about row-boundary crossings because they can't occur.

rikeshshakya
Associate III

@alister , When you say access size of bus, do you mean 4 bytes?

alister
Lead

I mean the access size of the CPU's load/store instruction, e.g. 1, 2, or 4 bytes.

@Tesla DeLorean @Ilex , alister and I had some discussion on this topic. Do you have any thoughts on this?