我正在尝试将开发套件
STM32H7B3I-EVAL 中的 OCTOSPI2(连接器 MB1242)与 Hypebus PSRAM IS66WVH8M8ALL-100 一起使用。
我成功地将内存配置为在内存映射模式下写入和读取,但是这只能在写入紧接着读取时才能完成。例如,如果我在写入地址后添加 1ms 延迟,读取相同的地址将返回错误的内容。
超总线配置
- __weak HAL_StatusTypeDef MX_OSPI_RAM_Init(OSPI_HandleTypeDef *hospi, MX_OSPI_InitTypeDef *Init) {
- OSPI_HyperbusCfgTypeDef sHyperbusCfg;
- HAL_StatusTypeDef status;
- /* OctoSPI initialization */
- hospi->Instance = OCTOSPI2;
- HAL_OSPI_DeInit(hospi);
- /*
- * With Init->ClockPrescaler = 3, the RAM will run at 40 MHz
- * ClockPrescaler = 3
- * Refresh = 160
- */
- hospi->Init.FifoThreshold = 4;
- hospi->Init.DualQuad = HAL_OSPI_DUALQUAD_DISABLE;
- hospi->Init.MemoryType = HAL_OSPI_MEMTYPE_HYPERBUS;
- hospi->Init.DeviceSize = Init->MemorySize;
- hospi->Init.ChipSelectHighTime = 8;
- hospi->Init.FreeRunningClock = HAL_OSPI_FREERUNCLK_DISABLE;
- hospi->Init.ClockMode = HAL_OSPI_CLOCK_MODE_0;
- hospi->Init.ClockPrescaler = Init->ClockPrescaler;
- hospi->Init.SampleShifting = Init->SampleShifting;
- hospi->Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_ENABLE;
- hospi->Init.DelayBlockBypass = HAL_OSPI_DELAY_BLOCK_BYPASSED;
- hospi->Init.Refresh = 160;//373; /*4us @40MHz*/
- hospi->Init.ChipSelectBoundary = 1;
- hospi->Init.ClkChipSelectHighTime = 0;
- hospi->Init.WrapSize = HAL_OSPI_WRAP_NOT_SUPPORTED;
- status = HAL_OSPI_Init(hospi);
- if (status == HAL_OK) {
- sHyperbusCfg.RWRecoveryTime = RW_RECOVERY_TIME;
- sHyperbusCfg.AccessTime = DEFAULT_INITIAL_LATENCY;
- sHyperbusCfg.WriteZeroLatency = HAL_OSPI_LATENCY_ON_WRITE;
- sHyperbusCfg.LatencyMode = HAL_OSPI_FIXED_LATENCY;
- status = HAL_OSPI_HyperbusCfg(&hospi_ram[0], &sHyperbusCfg, HAL_OSPI_TIMEOUT_DEFAULT_VALUE);
- }
- return status;
- }
- int32_t BSP_OSPI_RAM_Init(uint32_t Instance, BSP_OSPI_RAM_Init_t *Init) {
- int32_t ret;
- MX_OSPI_InitTypeDef ospi_init;
- /* Check if the instance is supported */
- if (Instance >= OSPI_RAM_INSTANCES_NUMBER) {
- ret = BSP_ERROR_WRONG_PARAM;
- } else {
- /* Check if the instance is already initialized */
- if (Ospi_Ram_Ctx[Instance].IsInitialized == OSPI_ACCESS_NONE) {
- #if (USE_HAL_OSPI_REGISTER_CALLBACKS == 0)
- /* Msp OSPI initialization */
- OSPI_RAM_MspInit(&hospi_ram[Instance]);
- #else
- /* Register the OSPI MSP Callbacks */
- if(OspiRam_IsMsPCBValid[Instance] == 0UL)
- {
- if(BSP_OSPI_RAM_RegisterDefaultMspCallbacks(Instance) != BSP_ERROR_NONE)
- {
- return BSP_ERROR_PERIPH_FAILURE;
- }
- }
- #endif /* USE_HAL_OSPI_REGISTER_CALLBACKS */
- /* Fill config structure */
- ospi_init.ClockPrescaler = 7; /* OctoSPI clock = 280MHz / ClockPrescaler = 40MHz */
- ospi_init.MemorySize = (uint32_t)POSITION_VAL(ISS66WVH8M8_RAM_SIZE);
- ospi_init.SampleShifting = HAL_OSPI_SAMPLE_SHIFTING_NONE;
- /* STM32 OSPI interface initialization */
- if (MX_OSPI_RAM_Init(&hospi_ram[Instance], &ospi_init) != HAL_OK) {
- ret = BSP_ERROR_PERIPH_FAILURE;
- }
- /* Configure the memory */
- else if (BSP_OSPI_RAM_ConfigHyperRAM(Instance,
- Init->LatencyType,
- Init->BurstType,
- Init->BurstLength) != BSP_ERROR_NONE) {
- ret = BSP_ERROR_COMPONENT_FAILURE;
- }
- else {
- ret = BSP_ERROR_NONE;
- }
- } else {
- ret = BSP_ERROR_NONE;
- }
- }
- /* Return BSP status */
- return ret;
- }
测试代码
- BSP_OSPI_RAM_Init_t sOSPI_RAM_Init;
- /** Init external ram **/
- sOSPI_RAM_Init.LatencyType = BSP_OSPI_RAM_FIXED_LATENCY;
- sOSPI_RAM_Init.BurstType = BSP_OSPI_RAM_LINEAR_BURST;
- sOSPI_RAM_Init.BurstLength = BSP_OSPI_RAM_BURST_32_BYTES;
- if (BSP_OSPI_RAM_Init(0, &sOSPI_RAM_Init) != BSP_ERROR_NONE) {
- Error_Handler();
- }
- /** Put exRam in memory mapped mode **/
- if (BSP_OSPI_RAM_EnableMemoryMappedMode(0) != BSP_ERROR_NONE) {
- Error_Handler();
- }
- while (1) {
- mem_addr = (__IO uint16_t*)(OCTOSPI2_BASE + address);
- for (index = 0; index < BUFFERSIZE; (index += 2)) {
- /* Writing Sequence --------------------------------------------------- */
- *mem_addr = *(uint16_t*)&aTxBuffer[index];
- //HAL_Delay(1); <<<---- Adding this delay cause the read to fail
- /* Reading Sequence --------------------------------------------------- */
- if (*mem_addr != *(uint16_t*)&aTxBuffer[index]) {
- BSP_LED_On(LED_RED);
- }
- mem_addr++;
- }
- BSP_LED_Toggle(LED_GREEN);
- HAL_Delay(100);
- address += OSPI_HYPERRAM_INCR_SIZE;
- if (address >= OSPI_HYPERRAM_END_ADDR) {
- address = 0;
- }
- }
我尝试以多种方式更改计时配置,但都没有成功。目前 MCU 的运行频率为 280MHz,OctoSPI 时钟为 40MHz。
有人有类似的问题吗?