1. Overview
The MCX N947 chip is a highly integrated microcontroller with robust processing capabilities, extensive peripheral support, and advanced security features, making it suitable for various complex applications. One of its critical peripherals is FlexSPI. FlexSPI is an expandable serial peripheral interface mainly used to connect solid-state storage devices such as QuadSPI NOR Flash, QuadSPI NAND Flash, and HyperRAM. FlexSPI is a comprehensive, flexible, high-performance solution that can be configured in different modes to support various storage devices. The NXP FRDM-MCXN947 board is a low-cost design and evaluation board based on the MCXN947 device. NXP provides tools and software support for the MCXN947 device, including hardware evaluation boards, integrated development environment (IDE) software, sample applications, and drivers. By default, the FlexSPI interface on this board connects to an MT35XU512 NOR Flash.
In this article, we will explore how to connect HyperRAM to the FlexSPI interface of the MCXN947 board. Hardware environment: Development Board: FRDM-MCXN947 HyperRAM:W956D8MBYA Software environment: IDE:MCUXpresso IDE v11.9.0 SDK:SDK Builder | MCUXpresso SDK Builder (nxp.com)
2. HyperRAM Schematic Below is the official eight-line Flash schematic from the FRDM-MCXN947. Since the HyperRAM W956D8MBYA package is a TFBGA 24-Ball 5 x 5 Array, it can be directly replaced.
Based on the above schematic, the signal connections for the HyperRAM memory are summarized in Table.
HyperRAM Signal Connection Table
HyperRAM Chip Pin
Function
Connected to MCXN947
CS
CS Chip Select Signal
P3_0/FLEXSPI0_A_SS0_b
SCK
SCK Clock Signal
P3_7/FLEXSPI0_A_SCLK
DQS
DQS Signal
P3_6/FLEXSPI0_A_DQS
DQ0
OSPI Data Signal D0
P3_8/FLEXSPI0_A_DATA0
DQ1
OSPI Data Signal D1
P3_9/FLEXSPI0_A_DATA1
DQ2
OSPI Data Signal D2
P3_10/FLEXSPI0_A_DATA2
DQ3
OSPI Data Signal D3
P3_11/FLEXSPI0_A_DATA3
DQ4
OSPI Data Signal D4
P3_12/FLEXSPI0_A_DATA4
DQ5
OSPI Data Signal D5
P3_13/FLEXSPI0_A_DATA5
DQ6
OSPI Data Signal D6
P3_14/FLEXSPI0_A_DATA6
DQ7
OSPI Data Signal D7
P3_15/FLEXSPI0_A_DATA7
3. HyperRAM Configuration Process
3.1 Clock configuration
The clock for FlexSPI needs to be correctly configured.
During the programming phase, it is safer to choose a lower frequency; here, we select 75MHz.
3.2 FlexSPI Initialization Configuration Structure
Next, we configure the FlexSPI-related settings. We can call FLEXSPI_GetDefaultConfig to obtain some default configurations for the FlexSPI feature structure flexspi_config_t, which has a certain degree of universality and is compatible with most FlexSPI devices. For the W956D8MBYA HyperRAM, on the basis of the default configuration, add the following parameters:
config.ahbConfig.enableAHBPrefetch = true;
config.ahbConfig.enableAHBBufferable = true;
config.ahbConfig.enableReadAddressOpt = true;
config.ahbConfig.enableAHBCachable = true;
config.rxSampleClock = kFLEXSPI_ReadSampleClkLoopbackFromDqsPad;
(1) enableAHBPrefetch: Whether to enable AHB prefetching. When enabled, FlexSPI reads more data than the current AHB burst read. (2) enableAHBBufferable: Whether to enable AHB write buffer access. After executing a write command, it returns without waiting for its completion, allowing subsequent instructions to continue executing, enhancing system concurrency. (3) enableReadAddressOpt: Controls whether to remove the AHB read burst start address alignment restriction. If enabled, burst read addresses are not restricted by byte alignment. (4) enableAHBCachable: Enables AHB bus cacheable reads. If a hit occurs, data is read from the cache, but data consistency must be ensured. (5) rxSampleClock: The clock source used for reading data. For HyperRAM, HyperRAM provides a read strobe pulse and inputs it through the DQS pin.
3.3 Detailed Explanation of FlexSPI External Device Configuration Structure When FlexSPI communicates with external devices, it often needs to coordinate communication timing with the device, such as clock frequency and data validity duration. NXP's software library provides the flexspi_device_config_t structure specifically for configuring these parameters.
typedef struct _flexspi_device_config {
uint32_t flexspiRootClk;
bool isSck2Enabled;
uint32_t flashSize;
flexspi_cs_interval_cycle_unit_t CSIntervalUnit;
uint16_t CSInterval;
uint8_t CSHoldTime;
uint8_t CSSetupTime;
uint8_t dataValidTime;
uint8_t columnspace;
bool enableWordAddress;
uint8_t AWRSeqIndex;
uint8_t AWRSeqNumber;
uint8_t ARDSeqIndex;
uint8_t ARDSeqNumber;
flexspi_ahb_write_wait_unit_t AHBWriteWaitUnit;
uint16_t AHBWriteWaitInterval;
bool enableWriteMask;
} flexspi_device_config_t;
(1) flexspiRootClk = 75000000, this parameter matches the previously set FlexSPI clock frequency. (2) flashSize = 0x2000, the size of the Flash in kilobytes. For W956D8MBYA, 64Mb = 8MB = 8 * 1024KB. (3) CSIntervalUnit = kFLEXSPI_CsIntervalUnit1SckCycle, this parameter configures the time unit for the interval between CS signal lines. (4) CSInterval = 2, this parameter configures the minimum time interval for switching between valid and invalid states of the CS signal line, measured in the units defined by the above CSIntervalUnit member. (5) CSHoldTime = 3, this parameter sets the hold time for the CS signal line, measured in FlexSPI root clock cycles. (6) CSSetupTime = 3, this parameter sets the setup time for the CS signal line, measured in FlexSPI root clock cycles.
According to the MCXNx4x datasheet,T_CK = 6ns,the minimum T_CSS = 8.3ns,and the minimumT_CSH = 9.8ns。The clock period for 75MHz is approximately 13.3 nanoseconds. Therefore, both CSHoldTime and CSSetupTime should be greater than or equal to 1, So they can be configured to 3
(1) dataValidTime=2,Registers DLLACR and DLLBCR are used to configure the valid data time in communication, with the unit being nanoseconds.
(2) columnspace = 3,which is the width of the low-order column address. For this HyperRAM, it uses row and column addresses for access, with a column address width of 3 bits.
(3) enableWordAddress = true,this parameter is configured whether the 2-byte addressable function is enabled. Once enabled, HyperRAM will be accessed using a 16-bit data format.
(4) AWRSeqIndex = 1,this parameter is the index of the write timing sequence in the LUT.
(5) AWRSeqNumber =1,this parameter configures the number of sequences for AHB write commands.
(6) ARDSeqIndex = 0,this parameter is the index of the read timing sequence in the LUT.
(7) ARDSeqNumber =1,this parameter configures the number of sequences for AHB write commands.
(8) enableWriteMask = true,this parameter is used to set whether to drive the DQS bit as a mask when writing to external devices via FlexSPI. This feature is used for address alignment when accessing data widths of 16 bits.
3.4 LUT table configuration
Below is a code example of the LUT table configuration for HyperRAM read and write timing.
const uint32_t customLUT[CUSTOM_LUT_LENGTH] = {
/* Read Data */
[4 * PSRAM_CMD_LUT_SEQ_IDX_READDATA] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0xA0, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18),
[4 * PSRAM_CMD_LUT_SEQ_IDX_READDATA + 1] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_DUMMY_RWDS_DDR, kFLEXSPI_8PAD, 0x07),
[4 * PSRAM_CMD_LUT_SEQ_IDX_READDATA + 2] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_READ_DDR, kFLEXSPI_8PAD, 0x04, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x00),
/* Write data */
[4 * PSRAM_CMD_LUT_SEQ_IDX_WRITEDATA] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_DDR, kFLEXSPI_8PAD, 0x20, kFLEXSPI_Command_RADDR_DDR, kFLEXSPI_8PAD, 0x18),
[4 * PSRAM_CMD_LUT_SEQ_IDX_WRITEDATA + 1] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_CADDR_DDR, kFLEXSPI_8PAD, 0x10, kFLEXSPI_Command_DUMMY_RWDS_DDR, kFLEXSPI_8PAD, 0x07),
[4 * PSRAM_CMD_LUT_SEQ_IDX_WRITEDATA + 2] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_WRITE_DDR, kFLEXSPI_8PAD, 0x04, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0x00),
};
(1) We are using an 8-line differential HyperRAM, which is utilized on both edges of the clock, hence the number of data lines used for communication with external memory is kFLEXSPI_8PAD.
(2) HyperRAM and HyperFlash are memory products designed based on the HyperBus™ interface specification by Cypress Semiconductor. This operand is defined in the specification, therefore the read operation operand is fixed at 0xA0, and the write data operand is fixed at 0x20.
(3) CADDR_DDR column address: Since the number of bytes transferred in one transmission must be a multiple of 8, if the row and column addresses you provide exceed the maximum rows and columns of a specific size HyperRAM, FlexSPI will automatically set the higher bits to 0.
The table above shows that the lower 16 bits are the column address, with 3 valid bits, and the upper 13 bits are reserved for compatibility and need to be set to 0. Therefore, the timing parameter for the column address here needs to be filled with 16, i.e., 0x10.
(4) RADDR_DDR row address: As shown in the figure, if the FLSHxxCR1[CAS] bit is not zero, then the FlexSPI peripheral will split the actual mapped Flash Address (i.e., the memory's own offset address) into a row address FA[31:CAS+1] and a column address [CAS:1] for transmission during transfer timing. For word-addressable flash devices, the last bit of the address is not needed because the flash is read and programmed in two-byte units.
FlexSPI considers one word as two bytes; thus, if alignment to two bytes is required, one less bit address is needed. The sum of row and column addresses should be one bit less. W956D8MBYA has 64Mbit, which is 2^26; with 3 bits for the column address, theoretically, 26-1-3=22 bits are needed for the row address to access the entire HyperRAM. Then, align it to 8 bits; otherwise, FlexSPI will pad zeros at the lower bits, which would not be the address we want to access. Therefore, the parameter is 0x18, i.e., 24 bits.
4. Experimental Verification
We can use simple AHB read and write operations to verify whether this HyperRAM is functional.
The code is as follows.
for (i = 0; i < sizeof(s_psram_write_buffer); i++)
{
s_psram_write_buffer[i] = i;
}
memcpy((uint32_t*)(EXAMPLE_FLEXSPI_AMBA_BASE), s_psram_write_buffer, sizeof(s_psram_write_buffer));
memcpy(s_psram_read_buffer,(uint32_t*)(EXAMPLE_FLEXSPI_AMBA_BASE) , sizeof(s_psram_read_buffer));
if (memcmp(s_psram_read_buffer, s_psram_write_buffer, sizeof(s_psram_write_buffer)) == 0)
{
PRINTF("AHB Command Read/Write data successfully !\r\n");
}
When your serial port prints "AHB Command Read/Write data successfully!",
it indicates that your FlexSPI connection to the HyperRAM is functioning properly.
記事全体を表示