我试图弄清楚如何通过QuadSPI创建内存映射的FLASH。我正在将STM32L4S9ZI MCU与Winbond W25Q32JVSSIQ QuadSPI存储器配合使用。
MCU特别支持OctoSPI而不是QuadSPI。但是在参考手册中写到,该特定MCU的OctoSPI可以在QuadSPI模式下使用。
我已经尝试将相同的MCU与OctoSPI Flash存储器一起使用,并且一切正常。但是,使用QuadSPI根本无法正常工作。问题是每次我发送命令时,都不会收到任何响应。我已经尝试过使用示波器,但是信号看起来很奇怪(IO1,IO2,CLK和CS上的周期脉冲一直很低)。现在,我只是想读取闪存芯片的制造商ID,仅此而已。我在OctoSPI flash中使用了相同的代码,并且可以正常工作。
void HAL_OSPI_MspInit(OSPI_HandleTypeDef *hospi)
{
if (hospi->Instance == OCTOSPI1)
{
GPIO_InitTypeDef GPIO_InitStruct;
OSPIM_CfgTypeDef OSPIM_Cfg_Struct;
/*##-1- Enable peripherals and GPIO Clocks #################################*/
/* Enable the OctoSPI memory interface clocks */
__HAL_RCC_OSPI1_CLK_ENABLE();
__HAL_RCC_OSPIM_CLK_ENABLE();
/* Reset the OctoSPI memory interface */
__HAL_RCC_OSPI1_FORCE_RESET();
__HAL_RCC_OSPI1_RELEASE_RESET();
/* Enable GPIO clocks */
/* IOSV bit MUST be set to access GPIO port G[2:15] */
__HAL_RCC_PWR_CLK_ENABLE();
SET_BIT(PWR->CR2, PWR_CR2_IOSV);
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/*##-2- Configure peripheral GPIO ##########################################*/
/* OSPI CS GPIO pin configuration */
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF10_OCTOSPIM_P1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* OSPI CLK GPIO pin configuration */
GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* OSPI D0 GPIO pin configuration */
GPIO_InitStruct.Pin = GPIO_PIN_1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* OSPI D1 GPIO pin configuration */
GPIO_InitStruct.Pin = GPIO_PIN_0;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* OSPI D2 GPIO pin configuration */
GPIO_InitStruct.Pin = GPIO_PIN_7;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* OSPI D3 GPIO pin configuration */
GPIO_InitStruct.Pin = GPIO_PIN_6;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*##-3- Configure the NVIC for OSPI #########################################*/
/* NVIC configuration for OSPI interrupt */
HAL_NVIC_SetPriority(OCTOSPI1_IRQn, 0x0F, 0);
HAL_NVIC_EnableIRQ(OCTOSPI1_IRQn);
/*##-4- Configure the OctoSPI IO Manager ####################################*/
OSPIM_Cfg_Struct.ClkPort = 1;
OSPIM_Cfg_Struct.IOHighPort = HAL_OSPIM_IOPORT_1_HIGH;
OSPIM_Cfg_Struct.IOLowPort = HAL_OSPIM_IOPORT_1_LOW;
OSPIM_Cfg_Struct.NCSPort = 1;
if (HAL_OSPIM_Config(hospi, &OSPIM_Cfg_Struct, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
/* User may add here some code to deal with this error */
while(1)
{
}
}
}
}
// /* Initialize OctoSPI ----------------------------------------------------- */
OSPIHandle.Instance = OCTOSPI1;
HAL_OSPI_DeInit(&OSPIHandle);
OSPIHandle.Init.FifoThreshold = 1;
OSPIHandle.Init.DualQuad = HAL_OSPI_DUALQUAD_DISABLE;
OSPIHandle.Init.MemoryType = HAL_OSPI_MEMTYPE_MICRON;
OSPIHandle.Init.DeviceSize = OSPI_FLASH_SIZE;
OSPIHandle.Init.ChipSelectHighTime = 2;
OSPIHandle.Init.FreeRunningClock = HAL_OSPI_FREERUNCLK_DISABLE;
OSPIHandle.Init.ClockMode = HAL_OSPI_CLOCK_MODE_0;
OSPIHandle.Init.WrapSize = HAL_OSPI_WRAP_NOT_SUPPORTED;
OSPIHandle.Init.ClockPrescaler = 2; /* OctoSPI clock = 120MHz / ClockPrescaler = 60MHz */
OSPIHandle.Init.SampleShifting = HAL_OSPI_SAMPLE_SHIFTING_NONE;
OSPIHandle.Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_ENABLE;
OSPIHandle.Init.ChipSelectBoundary = 0;
if (HAL_OSPI_Init(&OSPIHandle) != HAL_OK)
{
printf("%s %d\r\n", __FILE__, __LINE__);
error_handler();
}
//
// printf("%s %d\r\n", __FILE__, __LINE__);
//
// /* Device ID ---- */
sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG;
sCommand.Instruction = 0x94;
sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE;
sCommand.FlashId = HAL_OSPI_FLASH_ID_1;
sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS;
sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE;
sCommand.Address = 0x000000;
sCommand.AddressMode = HAL_OSPI_ADDRESS_4_LINES;
sCommand.AddressSize = HAL_OSPI_ADDRESS_24_BITS;
sCommand.AddressDtrMode = HAL_OSPI_ADDRESS_DTR_DISABLE;
sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_4_LINES;
sCommand.AlternateBytes = 0xF;
sCommand.AlternateBytesSize = 1;
sCommand.DataMode = HAL_OSPI_DATA_4_LINES;
sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_DISABLE;
sCommand.DummyCycles = 4;
sCommand.NbData = 2;
sCommand.DQSMode = HAL_OSPI_DQS_DISABLE;
uint8_t reg[2];
printf("%s %d\r\n", __FILE__, __LINE__);
if (HAL_OSPI_Command(&OSPIHandle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
printf("%s %d\r\n", __FILE__, __LINE__);
error_handler();
}
printf("%s %d\r\n", __FILE__, __LINE__);
if (HAL_OSPI_Receive(&OSPIHandle, reg, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
printf("%s %d error: %d 0x%08x 0x%08x\r\n", __FILE__, __LINE__, OSPIHandle.ErrorCode, reg[0], reg[1]);
error_handler();
}
printf("%s %d\r\n", __FILE__, __LINE__);
我真的希望我能弄清楚OctoSPI设备上QuadSPI存储器的初始化。
您能为QuadSPI外设的OctoSPI初始化提供帮助吗?我有什么想念的吗?谢谢