我使用的是 RT685 平台,通过 FlexSPI 连接 PSRAM。PSRAM (ISSI IS66WVR8M8FALL) 连接到端口 A2,QSPI 闪存连接到端口 A1。
PSRAM 被配置为通过 AHB 访问,FlexSPI 在启动后配置在 MCU 端,几分钟后从 DSP 端写入数据。从 DSP 端写入数据时,PSRAM 中存在一些 0x00 数据,而且数据看起来很规则。为了调试这个问题,我一次写了 192 字节 0x32 然后写了 0x33...
spi_ram.png
从 MCU 端写入和读取数据没有问题。该问题仅在从 DSP 端写入数据时出现。
FlexSPI 的配置、
const flexspi_config_t FLEXSPI_config = {
.rxSampleClock = kFLEXSPI_ReadSampleClkLoopbackInternally,
.enableSckFreeRunning = false,
.enableDoze = true,
.enableHalfSpeedAccess = false,
.enableSckBDiffOpt = false,
.enableSameConfigForAll = false,
.seqTimeoutCycle = 65535,
.ipGrantTimeoutCycle = 255,
.txWatermark = 8U,
.rxWatermark = 8U,
.ahbConfig = {
.ahbGrantTimeoutCycle = 255,
.ahbBusTimeoutCycle = 65535,
.resumeWaitCycle = 32,
.buffer = {
{ .priority = 0, .masterIndex = 0U, .bufferSize = 256U, .enablePrefetch = true },
{ .priority = 1, .masterIndex = 0U, .bufferSize = 256U, .enablePrefetch = true },
{ .priority = 2, .masterIndex = 0U, .bufferSize = 256U, .enablePrefetch = true },
{ .priority = 3, .masterIndex = 0U, .bufferSize = 256U, .enablePrefetch = true },
{ .priority = 4, .masterIndex = 0U, .bufferSize = 256U, .enablePrefetch = true },
{ .priority = 5, .masterIndex = 0U, .bufferSize = 256U, .enablePrefetch = true },
{ .priority = 6, .masterIndex = 0U, .bufferSize = 256U, .enablePrefetch = true },
{ .priority = 7, .masterIndex = 0U, .bufferSize = 256U, .enablePrefetch = true }
},
.enableClearAHBBufferOpt = true,
.enableReadAddressOpt = false,
.enableAHBPrefetch = false,
.enableAHBBufferable = true,
.enableAHBCachable = false
}
};PSRAM 的配置、
flexspi_device_config_t FLEXSPI_config_Device_SPIRAM = {
.flexspiRootClk = SPIRAM_ROOT_CLOCK_HZ,
.isSck2Enabled = false,
.flashSize = SPIRAM_SIZE_KBYTES,
.CSIntervalUnit = kFLEXSPI_CsIntervalUnit1SckCycle,
.CSInterval = 2,
.CSHoldTime = 3,
.CSSetupTime = 3,
.dataValidTime = 0,
.columnspace = 0U,
.enableWordAddress = false,
.AWRSeqIndex = SPIRAM_LUT_SEQ_IDX_WRITE,
.AWRSeqNumber = 1U,
.ARDSeqIndex = SPIRAM_LUT_SEQ_IDX_READ,
.ARDSeqNumber = 1U,
.AHBWriteWaitUnit = kFLEXSPI_AhbWriteWaitUnit2AhbCycle,
.AHBWriteWaitInterval = 1,
.enableWriteMask = false,
};有人知道这个问题吗?
我认为问题很可能是由于多主访问的 FlexSPI AHB 配置不正确造成的。
目前,所有 AHB 缓冲区都分配给主控 0。
.buffer = {
{ .priority = 0, .masterIndex = 0U, .bufferSize = 256U, .enablePrefetch = true },
{ .priority = 1, .masterIndex = 0U, .bufferSize = 256U, .enablePrefetch = true },
{ .priority = 2, .masterIndex = 0U, .bufferSize = 256U, .enablePrefetch = true },
{ .priority = 3, .masterIndex = 0U, .bufferSize = 256U, .enablePrefetch = true },
{ .priority = 4, .masterIndex = 0U, .bufferSize = 256U, .enablePrefetch = true },
{ .priority = 5, .masterIndex = 0U, .bufferSize = 256U, .enablePrefetch = true },
{ .priority = 6, .masterIndex = 0U, .bufferSize = 256U, .enablePrefetch = true },
{ .priority = 7, .masterIndex = 0U, .bufferSize = 256U, .enablePrefetch = true }
},
您可以尝试为 dsp 分配一个缓冲器。
启用 AHB 写缓冲(enableAHBBufferable = true)可能会延迟或合并写入,这不适合 PSRAM,可能会导致数据丢失。
您可以尝试
enableAHBBufferable = false;
BR
哈利
嗨,哈里、
我试着禁用 AHB TX 的缓冲区,但这无助于解决这个问题。
enableAHBBufferable = false;
您知道缓存中是否有任何可能导致这种情况的因素吗?
非常感谢。
根据 RT600/RT685 的相关文件。缓冲区 [] 对应 AHB RX 缓冲区,即读取路径缓冲区,
的范围。优先级从 0 到 7,7 为最高优先级,0 为最低优先级;
。mastIndex 是 AHB 主设备 ID,用于将某个 AHB RX 缓冲区分配给主设备进行读取访问。文档指出,FlexSPI 将根据主站 ID 选择 RX 缓冲区;一个主站不支持分配多个 RX 缓冲区。
的单位。SDK 结构中的 bufferSize 是字节,但底层寄存器 BUFSZ 的单位是 64 位
Harry_Zhang_1-1779348676305.png
Harry_Zhang_0-1779348649679.png
详情请参考 RT600 用户手册。
BR
哈利
我会与我们的内部团队讨论,并尽快给您答复。
BR
哈利
是的,你说得对。
xthal_set_region_attribute((void *)0x08000000,0x800000,XCHAL_CA_BYPASS,0);
BR
哈利
测试之后
如果 FlexSPI PSRAM 的读写操作由不同的主控(即 CM33 和 DSP)处理,有两点需要注意:
1.对于 DSP,访问 FlexSPI 时会绕过 Cache64,而对于 CM33,访问 FlexSPI 的路径上有 Cache64。详见第一张图。
Harry_Zhang_0-1779790039305.png
因此,我建议在 CM33 读取 - DSP 写入和 CM33 写入 - DSP 读取时禁用 cache64。
2.HiFi4 dsp 有指令缓存和数据缓存。对于 PSRAM 的访问,访问是可缓存的。
因此,如果 DSP 写入 PSRAM,那么 CM33 的读数可能会不一致。
Harry_Zhang_1-1779790093412.png
因此,我建议在 CM33 读取 - DSP 写入和 CM33 写入 - DSP 读取时,为 FlexSPI PSRAM 设置非高速缓存访问。
我们测试的数据是一致的。
BR
哈利
您能分享一下您的代码吗?
我想在我这边重现这个问题。
BR
哈利
"由于代码中包含一些商业代码,恐怕我无法与大家分享,对此我深表歉意。"
我们需要编写代码来重现您之前提到的问题。
"根据我对 UM11147 的理解,uSDHC 的 ADMA 无法访问 SPI RAM 的映射地址,对吗?"
是的,你说得对。
BR
哈利
谢谢你,哈里。
实际上,我提出了两个与访问 SPI RAM 有关的问题。
两者都在使用连接到 FlexSPI 端口 A2 的 SPI RAM(8MB),还有一个连接到端口 A1 的 SPI 闪存(8MB)。SPI RAM 地址被映射到 0x08800000。
# 1 从 DSP 内核写入 SPI RAM 的数据。
// copy data into SPI RAM from DSP core
uint8_t * dst = (uint8_t *)0x08800000;
uint8_t src[192] = { 0x30 };
memcpy(dst, src, sizeof(src));# 2 数据从 SPI RAM 写入 MCU 内核上的 SD 卡
我们使用的文件系统是https://doc.segger.com/UM02001_emFile.html#FS_Write
https://doc.segger.com/UM02001_emFile.html#FS_FOpen
uint8_t * src=(uint8_t*)0x08800000;
FS_FILE * pFile = FS_FOpen("\test.dat", "wb+");
if (pFile)
{
FS_Write(pFile, src, 0x8000);
FS_FClose(pFile);
}在 emFile 的底层代码中,它将使用 ADMA 的源点,类似于
USDHC_SetADMA1Descriptor(, , (const uint32_t *)0x08800000, 0x8000, );我想你可以在 EVK 上用 .NET Framework 进行测试、
f_write()谢谢你,哈里。
我很想知道如何配置 `.buffer`,例如
.优先级 "的范围是什么?
如何配置 `.masterIndex`?
根据我的理解,缓冲区的总大小应该是 2048。
我没有找到任何资料说明如何配置,如果有的话,请参阅 `fsl_flexspi.h` 中的文档或注释、我想这一定会很有帮助。
在这种情况下,我打算让 DSP 将数据写入 PSRAM,然后让 MCU 读出。根据我的理解,".buffer "是用于 AHB RX 的,那么在我的情况下,是否应该为 DSP 指定任何缓冲区?
谢谢你,哈里。我还有一个问题,能否将 PSRAM 映射地址用于 MCU 内核中 uSDHS 的 ADMA?例如,如果我将 PSRAM 地址映射到 0x08800000,是否可以使用指针
uint8_t * dataAddr = (uint8_t*)0x08800000;ADMA?
谢谢你,哈里,这真的很有帮助。
我可以这样禁用 DSP 内核的高速缓存吗?
int main(void)
{
void *spiRamStart;
*(uint32_t *)(&spiRamStart) = 0x08800000;
xthal_set_region_attribute(spiRamStart, 0x00800000, XCHAL_CA_BYPASS, 0);
// ...
}