我正在尝试在我的项目中初始化我的 W25Q128jv 外部闪存,但我无法在上面写入,我认为这可能是因为内存映射模式,但我真的不知道。对于这个项目,当我添加 TouchGFX 以保存一些项目时,我将需要我的 QUADSPI,但现在我只是尝试执行一个 for 循环来验证它是否有效及其性能。如果我禁用 MemoryMappingMode 写入,它将进入 HardFault。
- uint32_t *flashbuffer = (uint32_t*)0x90000000;
- const uint32_t size = 1000;
- int begin = HAL_Gettick();
- for(i = 0; i < size; i++)
- {
- flashbuffer=i;
- }
- int end = HAL_GetTick();
这是 MX_QUADSPI_Init
- static void MX_QUADSPI_Init(void)
- {
- /* USER CODE BEGIN QUADSPI_Init 0 */
- /* USER CODE END QUADSPI_Init 0 */
- /* USER CODE BEGIN QUADSPI_Init 1 */
- /* USER CODE END QUADSPI_Init 1 */
- /* QUADSPI parameter configuration*/
- hqspi.Instance = QUADSPI;
- hqspi.Init.ClockPrescaler = 1;
- hqspi.Init.FifoThreshold = 4;
- hqspi.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_HALFCYCLE;
- hqspi.Init.FlashSize = 23;
- hqspi.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_6_CYCLE;
- hqspi.Init.ClockMode = QSPI_CLOCK_MODE_0;
- hqspi.Init.FlashID = QSPI_FLASH_ID_1;
- hqspi.Init.DualFlash = QSPI_DUALFLASH_DISABLE;
- if (HAL_QSPI_Init(&hqspi) != HAL_OK)
- {
- Error_Handler();
- }
- /* USER CODE BEGIN QUADSPI_Init 2 */
- BSP_QSPI_Init();
- /* USER CODE END QUADSPI_Init 2 */
- }
这是我的初始化
- uint8_t BSP_QSPI_Init(void)
- {
- QSPI_CommandTypeDef s_command;
- uint8_t value = W25Q128JV_FSR_QE;
- /* QSPI memory reset */
- if (QSPI_ResetMemory() != QSPI_OK)
- {
- return QSPI_NOT_SUPPORTED;
- }
- /* Enable write operations */
- if (QSPI_WriteEnable() != QSPI_OK)
- {
- return QSPI_ERROR;
- }
- /* Set status register for Quad Enable,the Quad IO2 and IO3 pins are enable */
- s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
- s_command.Instruction = WRITE_STATUS_REG2_CMD;
- s_command.AddressMode = QSPI_ADDRESS_NONE;
- s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
- s_command.DataMode = QSPI_DATA_1_LINE;
- s_command.DummyCycles = 0;
- s_command.NbData = 1;
- s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
- s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
- s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
- /* Configure the command */
- if (HAL_QSPI_Command(&hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
- {
- return QSPI_ERROR;
- }
- /* Transmit the data */
- if (HAL_QSPI_Transmit(&hqspi, &value, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
- {
- return QSPI_ERROR;
- }
- /* automatic polling mode to wait for memory ready */
- if (QSPI_AutoPollingMemReady(W25Q128JV_WRITE_STATUS_REG_TIME_MS) != QSPI_OK)
- {
- return QSPI_ERROR;
- }
- BSP_QSPI_MemoryMappedMode();
- return QSPI_OK;
- }
- /*BSP_QSPI_Init*/
这是我的司机
- static uint8_t QSPI_WriteEnable(void) {
- QSPI_CommandTypeDef sCommand;
- QSPI_AutoPollingTypeDef sConfig;
- /* Enable write operations ------------------------------------------ */
- sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE;
- sCommand.Instruction = WRITE_ENABLE_CMD;
- sCommand.AddressMode = QSPI_ADDRESS_NONE;
- sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
- sCommand.DataMode = QSPI_DATA_NONE;
- sCommand.DummyCycles = 0;
- sCommand.DdrMode = QSPI_DDR_MODE_DISABLE;
- sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
- sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
- if (HAL_QSPI_Command(&hqspi, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
- return (QSPI_ERROR);
- }
- /* Configure automatic polling mode to wait for write enabling ---- */
- sConfig.Match = W25Q128JV_FSR_WREN;
- sConfig.Mask = W25Q128JV_FSR_WREN;
- sConfig.MatchMode = QSPI_MATCH_MODE_AND;
- sConfig.StatusBytesSize = 1;
- sConfig.Interval = 0x10;
- sConfig.AutomaticStop = QSPI_AUTOMATIC_STOP_ENABLE;
- sCommand.Instruction = READ_STATUS_REG1_CMD;
- sCommand.DataMode = QSPI_DATA_1_LINE;
- sCommand.NbData = 1;
- if (HAL_QSPI_AutoPolling(&hqspi, &sCommand, &sConfig, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
- return (QSPI_ERROR);
- }
- return (QSPI_OK);
- } /* QSPI_WriteEnable */
- static uint8_t BSP_QSPI_Write(const uint8_t * pData, uint32_t WriteAddr, uint32_t Size) {
- QSPI_CommandTypeDef s_command;
- uint32_t end_addr, current_size, current_addr;
- /* Calculation of the size between the write address and the end of the page */
- current_addr = 0U;
- while (current_addr <= WriteAddr) {
- current_addr += W25Q128JV_PAGE_SIZE;
- }
- current_size = current_addr - WriteAddr;
- /* Check if the size of the data is less than the remaining place in the page */
- if (current_size > Size) {
- current_size = Size;
- }
- /* Initialize the address variables */
- current_addr = WriteAddr;
- end_addr = WriteAddr + Size;
- /* Initialize the program command */
- s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
- s_command.Instruction = QUAD_INPUT_PAGE_PROG_CMD;
- s_command.AddressMode = QSPI_ADDRESS_1_LINE;
- s_command.AddressSize = QSPI_ADDRESS_24_BITS;
- s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
- s_command.DataMode = QSPI_DATA_4_LINES;
- s_command.DummyCycles = 0;
- s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
- s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
- s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
- /* Perform the write page by page */
- do {
- s_command.Address = current_addr;
- s_command.NbData = current_size;
- /* Enable write operations */
- QSPI_WriteEnable();
- /* Configure the command */
- if (HAL_QSPI_Command(&hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
- return (QSPI_ERROR);
- }
- /* Transmission of the data */
- if (HAL_QSPI_Transmit(&hqspi, (uint8_t *)((uint32_t)pData), HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
- return (QSPI_ERROR);
- }
- /* Configure automatic polling mode to wait for end of program */
- if (QSPI_AutoPollingMemReady(HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK) {
- return (QSPI_ERROR);
- }
- /* Update the address and size variables for next page programming */
- current_addr += current_size;
- pData += current_size;
- current_size = ((current_addr + W25Q128JV_PAGE_SIZE) > end_addr) ? (end_addr - current_addr) : W25Q128JV_PAGE_SIZE;
- } while (current_addr < end_addr);
- return (QSPI_OK);
- } /* BSP_QSPI_Write */
- uint8_t BSP_QSPI_Read(uint8_t* pData, uint32_t ReadAddr, uint32_t Size) {
- QSPI_CommandTypeDef s_command;
- /* Initialize the read command */
- s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
- s_command.Instruction = READ_CMD;
- s_command.AddressMode = QSPI_ADDRESS_1_LINE;
- s_command.AddressSize = QSPI_ADDRESS_24_BITS;
- s_command.Address = ReadAddr;
- s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
- s_command.DataMode = QSPI_DATA_1_LINE;
- s_command.DummyCycles = 0;
- s_command.NbData = Size;
- s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
- s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
- s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
- /* Configure the command */
- if (HAL_QSPI_Command(&hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
- return (QSPI_ERROR);
- }
- /* Reception of the data */
- if (HAL_QSPI_Receive(&hqspi, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
- return (QSPI_ERROR);
- }
- return (QSPI_OK);
- } /* BSP_QSPI_Read */
- static void BSP_QSPI_MemoryMappedMode(void) {
- QSPI_CommandTypeDef s_command;
- QSPI_MemoryMappedTypeDef s_mem_mapped_cfg;
- /* Configure the command for the read instruction */
- s_command.Instruction = QUAD_INOUT_FAST_READ_CMD;
- s_command.Address = 0U;
- s_command.AlternateBytes = 0xF0;
- s_command.AddressSize = QSPI_ADDRESS_24_BITS;
- s_command.AlternateBytesSize = QSPI_ALTERNATE_BYTES_8_BITS;
- s_command.DummyCycles = W25Q128JV_DUMMY_CYCLES_READ_QUAD;
- s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
- s_command.AddressMode = QSPI_ADDRESS_4_LINES;
- s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_4_LINES;
- s_command.DataMode = QSPI_DATA_4_LINES;
- s_command.NbData = 0U;
- s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
- s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
- s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
- /* Configure the memory mapped mode */
- s_mem_mapped_cfg.TimeOutPeriod = 0;
- s_mem_mapped_cfg.TimeOutActivation = QSPI_TIMEOUT_COUNTER_DISABLE;
- if (HAL_QSPI_MemoryMapped(&hqspi, &s_command, &s_mem_mapped_cfg) != HAL_OK) {
- Error_Handler();
- }
- } /* BSP_QSPI_MemoryMappedMode */
0
|
1个回答
|
|
|