Serial Memory
Serial Memory

General Description

In addition to the APIs for reading and writing to memory at runtime, this library also provides support for informing programming tools about the external memory so it can be be written at the same time as internal memory.

QSPI configurator slave slot correlation with pins

In QSPI configurator Memory Parts are tied to a specific slave slot that is linked to the actual slave select pin mappings of that specific device. So selecting a memory configuration for slot 0 means that physically that external memory will be the connected to slave select 0 pin. This is important for kits that have hardwired connections to external memories where the memory configuration needs to be in the correct slot depending on what slave select pin is hardwired to it.

Serial Memory handling for Octal DDR

For external memories that are configured in Octal DDR mode, read/write operations at odd addresses and with length equal to 1 are not natively supported due to limitations in the protocol that requires an even address and/or even lengths. For this reason a special handling of these cases is present in mtb_serial_memory_read and mtb_serial_memory_write to allow the use of odd addresses in a transparent way for the user.

For mtb_serial_memory_read when selecting a read one byte at an odd address, the function will instead perform a read at the even address preceding the specified address and then discard the extra byte returning to the user only the data they requested.

For mtb_serial_memory_write the function needs to take into consideration all four possible combination of even/odd addresses and lengths:

This special handling needs to be enabled by setting define in _MTB_SERIAL_MEMORY_EMULATE_BYTE_ADDRESSABLE the application Makefile.

This support can be enabled by defining MTB_SERIAL_MEMORY_ENABLE_XIP_PROGRAM while building the application. With this define in place, code will be generated in the .cy_sflash_user_data & .cy_toc_part2 sections. These sections must be provided by the linker script for the application. One the application has been built, these locations can be read by programming tools (eg: Cypress Programmer, OpenOCD, pyOCD) to know that there is a memory device attached and how to program it.

Note
This support is not compatible with the PSoCâ„¢ 64 series of devices.

Data Structures

struct  mtb_serial_memory_t
 Serial memory object. More...
 

Macros

#define MTB_SERIAL_MEMORY_THREAD_SAFE
 Enables thread-safety for use with multi-threaded RTOS environment.
 
#define CY_IP_MXSMIF
 The MXSMIF IP is available.
 
#define MTB_SERIAL_MEMORY_VERSION_MAJOR   (3U)
 The major version of the serial memory asset.
 
#define MTB_RSLT_SERIAL_MEMORY_ERR_UNSUPPORTED    (CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_BOARD_LIB_SERIAL_MEMORY, 1))
 The function or operation is not supported on the target or the memory.
 
#define MTB_RSLT_SERIAL_MEMORY_ERR_BAD_PARAM    (CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_BOARD_LIB_SERIAL_MEMORY, 2))
 Parameters passed to a function are invalid.
 
#define MTB_RSLT_SERIAL_MEMORY_ERR_READ_BUSY    (CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_BOARD_LIB_SERIAL_MEMORY, 3))
 A previously initiated read operation is not yet complete.
 
#define MTB_RSLT_SERIAL_MEMORY_ERR_OCTAL_ENABLE    (CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_BOARD_LIB_SERIAL_MEMORY, 4))
 Setting octal enabled failed.
 
#define MTB_RSLT_SERIAL_MEMORY_ERR_RX_CAPTURE    (CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_BOARD_LIB_SERIAL_MEMORY, 5))
 Setting rx capture mode failed.
 

Enumerations

enum  mtb_serial_memory_chip_select_t {
  MTB_SERIAL_MEMORY_CHIP_SELECT_0 = 1u ,
  MTB_SERIAL_MEMORY_CHIP_SELECT_1 = 1u << 1 ,
  MTB_SERIAL_MEMORY_CHIP_SELECT_2 = 1u << 2 ,
  MTB_SERIAL_MEMORY_CHIP_SELECT_3 = 1u << 3
}
 Serial Memory Chip Select Each chip select is represented by an enumeration that has the bit corresponding to the chip select number set. More...
 

Functions

cy_rslt_t mtb_serial_memory_setup (mtb_serial_memory_t *obj, mtb_serial_memory_chip_select_t smif_active_chip, SMIF_Type *base, const mtb_hal_clock_t *clock, cy_stc_smif_mem_context_t *mem_context, cy_stc_smif_mem_info_t *mem_info, const cy_stc_smif_block_config_t *block_config)
 Sets up the serial memory. More...
 
cy_rslt_t mtb_serial_memory_setup_nonsecure (mtb_serial_memory_t *obj, mtb_serial_memory_chip_select_t smif_active_chip, SMIF_Type *base, cy_stc_smif_mem_context_t *mem_context, cy_stc_smif_mem_info_t *mem_info)
 Sets up the serial memory on non-secure world if the peripheral is secure. More...
 
size_t mtb_serial_memory_get_size (mtb_serial_memory_t *obj)
 Returns the size of the serial memory in bytes. More...
 
size_t mtb_serial_memory_get_erase_size (mtb_serial_memory_t *obj, uint32_t addr)
 Returns the size of the erase sector to which the given address belongs. More...
 
size_t mtb_serial_memory_get_prog_size (mtb_serial_memory_t *obj, uint32_t addr)
 Returns the page size for programming of the sector to which the given address belongs. More...
 
__STATIC_INLINE uint32_t mtb_serial_memory_get_sector_start_address (mtb_serial_memory_t *obj, uint32_t addr)
 Utility function to calculate the starting address of an erase sector to which the given address belongs. More...
 
cy_rslt_t mtb_serial_memory_read (mtb_serial_memory_t *obj, uint32_t addr, size_t length, uint8_t *buf)
 Reads data from the serial memory. More...
 
cy_rslt_t mtb_serial_memory_write (mtb_serial_memory_t *obj, uint32_t addr, size_t length, const uint8_t *buf)
 Writes the data to the serial memory. More...
 
cy_rslt_t mtb_serial_memory_erase (mtb_serial_memory_t *obj, uint32_t addr, size_t length)
 Erases the serial memory, uses chip erase command when addr = 0 and length = flash_size otherwise uses sector erase command. More...
 
cy_rslt_t mtb_serial_memory_enable_xip (mtb_serial_memory_t *obj, bool enable)
 Enables Execute-in-Place (memory mapped) mode on the MCU. More...
 
cy_rslt_t mtb_serial_memory_set_active_chip (mtb_serial_memory_t *obj, mtb_serial_memory_chip_select_t chip_select)
 Sets the active memory device that the serial-flash functions perform the operations on. More...
 
uint32_t mtb_serial_memory_get_chip_count (mtb_serial_memory_t *obj)
 Returns the number of memory devices successfully initialized. More...
 
uint32_t mtb_serial_memory_get_active_chip (mtb_serial_memory_t *obj)
 Returns the active chip select. More...
 
cy_rslt_t mtb_serial_memory_set_write_enable (mtb_serial_memory_t *obj, bool enable)
 Send the Write Enable or Write Disable command to the external memory. More...
 

Data Structure Documentation

◆ mtb_serial_memory_t

struct mtb_serial_memory_t
Data Fields
uint32_t smif_active_slot
SMIF_Type * base
const mtb_hal_clock_t * clock
uint32_t configured_csel
uint32_t chip_select
uint32_t status_flags
cy_stc_smif_mem_context_t * mem_context
cy_stc_smif_mem_info_t * mem_info
cy_mutex_t mutex

Enumeration Type Documentation

◆ mtb_serial_memory_chip_select_t

Serial Memory Chip Select Each chip select is represented by an enumeration that has the bit corresponding to the chip select number set.

Enumerator
MTB_SERIAL_MEMORY_CHIP_SELECT_0 

The SMIF chip select 0

MTB_SERIAL_MEMORY_CHIP_SELECT_1 

The SMIF chip select 1

MTB_SERIAL_MEMORY_CHIP_SELECT_2 

The SMIF chip select 2

MTB_SERIAL_MEMORY_CHIP_SELECT_3 

The SMIF chip select 3

Function Documentation

◆ mtb_serial_memory_setup()

cy_rslt_t mtb_serial_memory_setup ( mtb_serial_memory_t obj,
mtb_serial_memory_chip_select_t  smif_active_chip,
SMIF_Type *  base,
const mtb_hal_clock_t *  clock,
cy_stc_smif_mem_context_t *  mem_context,
cy_stc_smif_mem_info_t *  mem_info,
const cy_stc_smif_block_config_t *  block_config 
)

Sets up the serial memory.

Note
The function will reset the memory controller when "Auto Detect SFDP" is chosen in the "Memory Part Number" section of the QSPI Configurator. However, if a specific part number is specified in the QSPI Configurator, the responsibility falls to the application to reset the memory controller using the Cy_SMIF_Reset_Memory() PDL function. This approach is adopted because the mtb_serial_memory_setup() function might be executed from the external memory itself, and resetting the memory controller could disrupt the communication with the memory. This function initializes the slots of the memory device in the SMIF configuration. It's security aware and is a wrapper around Cy_SMIF_MemNumInit, and gather all information about the memory size, erase and program size to be used in subsequent serial memory calls. It can either be called in a secure partition or in the non-secure partition if the peripheral itself is not secured.
Parameters
objPointer to the mtb_serial_memory_t object to setup
smif_active_chipThe slave select line to configure as active
basePointer to the SMIf base address
clockPointer to the clock object
mem_contextPointer to the SMIF Device internal context data
mem_infoPointer to the SMIF memory info structure
block_configPointer to the SMIF block configuration structure
Returns
CY_RSLT_SUCCESS if the setup was successful, an error code otherwise.

◆ mtb_serial_memory_setup_nonsecure()

cy_rslt_t mtb_serial_memory_setup_nonsecure ( mtb_serial_memory_t obj,
mtb_serial_memory_chip_select_t  smif_active_chip,
SMIF_Type *  base,
cy_stc_smif_mem_context_t *  mem_context,
cy_stc_smif_mem_info_t *  mem_info 
)

Sets up the serial memory on non-secure world if the peripheral is secure.

Note
This function is to be called from the non secure partition in trustzone devices (after the secure one has successfully called mtb_serial_memory_setup ) to set up the context and gather all information about the memory size, erase and program size to be used in subsequent serial memory calls.
Parameters
objPointer to the mtb_serial_memory_t object to setup
smif_active_chipThe slave select line to configure as active
basePointer to the SMIf base address
mem_contextPointer to the SMIF Device internal context data
mem_infoPointer to the SMIF memory info structure
Returns
CY_RSLT_SUCCESS if the setup was successful, an error code otherwise.

◆ mtb_serial_memory_get_size()

size_t mtb_serial_memory_get_size ( mtb_serial_memory_t obj)

Returns the size of the serial memory in bytes.

Parameters
objPointer to the mtb_serial_memory_t object to obtain information from
Returns
Memory size in bytes.

◆ mtb_serial_memory_get_erase_size()

size_t mtb_serial_memory_get_erase_size ( mtb_serial_memory_t obj,
uint32_t  addr 
)

Returns the size of the erase sector to which the given address belongs.

Address is used only for a memory with hybrid sector size.

Parameters
objPointer to the mtb_serial_memory_t object to obtain information from.
addrAddress that belongs to the sector for which size is returned.
Returns
Erase sector size in bytes.

◆ mtb_serial_memory_get_prog_size()

size_t mtb_serial_memory_get_prog_size ( mtb_serial_memory_t obj,
uint32_t  addr 
)

Returns the page size for programming of the sector to which the given address belongs.

Address is used only for a memory with hybrid sector size.

Parameters
objPointer to the mtb_serial_memory_t object to obtain information from.
addrAddress that belongs to the sector for which size is returned.
Returns
Page size in bytes.

◆ mtb_serial_memory_get_sector_start_address()

__STATIC_INLINE uint32_t mtb_serial_memory_get_sector_start_address ( mtb_serial_memory_t obj,
uint32_t  addr 
)

Utility function to calculate the starting address of an erase sector to which the given address belongs.

Parameters
objPointer to the mtb_serial_memory_t object to obtain information from.
addrAddress in the sector for which the starting address is returned.
Returns
Starting address of the sector

◆ mtb_serial_memory_read()

cy_rslt_t mtb_serial_memory_read ( mtb_serial_memory_t obj,
uint32_t  addr,
size_t  length,
uint8_t *  buf 
)

Reads data from the serial memory.

This is a blocking function. Returns error if (addr + length) exceeds the memory size. If _MTB_SERIAL_MEMORY_EMULATE_BYTE_ADDRESSABLE is set the function can emulate byte addressable memories for Octal DDR memories and handle one byte reads even at odd addresses.

Parameters
objPointer to the mtb_serial_memory_t object to obtain information from.
addrStarting address to read from
lengthNumber of data bytes to read
bufPointer to the buffer to store the data read from the memory
Returns
CY_RSLT_SUCCESS if the read was successful, an error code otherwise.

◆ mtb_serial_memory_write()

cy_rslt_t mtb_serial_memory_write ( mtb_serial_memory_t obj,
uint32_t  addr,
size_t  length,
const uint8_t *  buf 
)

Writes the data to the serial memory.

The program area must have been erased prior to calling this API using mtb_serial_memory_erase() This is a blocking function. Returns error if (addr + length) exceeds the memory size. If _MTB_SERIAL_MEMORY_EMULATE_BYTE_ADDRESSABLE is set the function can emulate byte addressable memories for Octal DDR memories and handle one byte writes even at odd addresses. This however actually writes starting from the previous even address and will always write two bytes.

Parameters
objPointer to the mtb_serial_memory_t object to write to.
addrStarting address to write to
lengthNumber of bytes to write
bufPointer to the buffer storing the data to be written
Returns
CY_RSLT_SUCCESS if the write was successful, an error code otherwise.

◆ mtb_serial_memory_erase()

cy_rslt_t mtb_serial_memory_erase ( mtb_serial_memory_t obj,
uint32_t  addr,
size_t  length 
)

Erases the serial memory, uses chip erase command when addr = 0 and length = flash_size otherwise uses sector erase command.

This is a blocking function. Returns error if addr or (addr + length) is not aligned to the sector size or if (addr + length) exceeds the memory size. For memories with hybrid sectors, returns error if the end address (=addr + length) is not aligned to the size of the sector in which the end address is located. Call mtb_serial_memory_get_size() to get the flash size and call mtb_serial_memory_get_erase_size() to get the size of an erase sector.

Parameters
objPointer to the mtb_serial_memory_t object to erase.
addrStarting address to begin erasing
lengthNumber of bytes to erase
Returns
CY_RSLT_SUCCESS if the erase was successful, an error code otherwise.

◆ mtb_serial_memory_enable_xip()

cy_rslt_t mtb_serial_memory_enable_xip ( mtb_serial_memory_t obj,
bool  enable 
)

Enables Execute-in-Place (memory mapped) mode on the MCU.

This function does not send any command to the serial memory.

Parameters
objPointer to the mtb_serial_memory_t object to enable XIP on.
enabletrue: XIP mode is set, false: normal mode is set
Returns
CY_RSLT_SUCCESS if the operation was successful.

◆ mtb_serial_memory_set_active_chip()

cy_rslt_t mtb_serial_memory_set_active_chip ( mtb_serial_memory_t obj,
mtb_serial_memory_chip_select_t  chip_select 
)

Sets the active memory device that the serial-flash functions perform the operations on.

Parameters
objPointer to the mtb_serial_memory_t object to set active chip for.
chip_selectThe chip select of the memory device to be set as active.
Returns
The function will return an error if the device had not been setup with mtb_serial_memory_setup .

◆ mtb_serial_memory_get_chip_count()

uint32_t mtb_serial_memory_get_chip_count ( mtb_serial_memory_t obj)

Returns the number of memory devices successfully initialized.

Parameters
objPointer to the mtb_serial_memory_t object to get chip count for.
Returns
Number of memory devices successfully initialized.

◆ mtb_serial_memory_get_active_chip()

uint32_t mtb_serial_memory_get_active_chip ( mtb_serial_memory_t obj)

Returns the active chip select.

Parameters
objPointer to the mtb_serial_memory_t object to get the active chip for.
Returns
Returns the active memory chip.

◆ mtb_serial_memory_set_write_enable()

cy_rslt_t mtb_serial_memory_set_write_enable ( mtb_serial_memory_t obj,
bool  enable 
)

Send the Write Enable or Write Disable command to the external memory.

Parameters
objPointer to the mtb_serial_memory_t object to send write enable/disable command to.
enableif true the command to be sent is Write Enable, if false the command to be sent is Write Disable.
Returns
CY_RSLT_SUCCESS if the operation was successful, an error code therwise.