STM32F769IDiscovery  1.00
uDANTE Audio Networking with STM32F7 DISCO board
stm32f769i_discovery_qspi.c
Go to the documentation of this file.
1 
67 /* Includes ------------------------------------------------------------------*/
69 
83 /* Private variables ---------------------------------------------------------*/
84 
89 
96 /* Private functions ---------------------------------------------------------*/
97 
101 static uint8_t QSPI_ResetMemory(QSPI_HandleTypeDef *hqspi);
102 static uint8_t QSPI_EnterFourBytesAddress(QSPI_HandleTypeDef *hqspi);
103 static uint8_t QSPI_DummyCyclesCfg(QSPI_HandleTypeDef *hqspi);
104 static uint8_t QSPI_EnterMemory_QPI(QSPI_HandleTypeDef *hqspi);
105 static uint8_t QSPI_ExitMemory_QPI(QSPI_HandleTypeDef *hqspi);
106 static uint8_t QSPI_OutDrvStrengthCfg(QSPI_HandleTypeDef *hqspi);
107 static uint8_t QSPI_WriteEnable(QSPI_HandleTypeDef *hqspi);
108 static uint8_t QSPI_AutoPollingMemReady (QSPI_HandleTypeDef *hqspi, uint32_t Timeout);
109 
122 uint8_t BSP_QSPI_Init(void)
123 {
124  QSPIHandle.Instance = QUADSPI;
125 
126  /* Call the DeInit function to reset the driver */
127  if (HAL_QSPI_DeInit(&QSPIHandle) != HAL_OK)
128  {
129  return QSPI_ERROR;
130  }
131 
132  /* System level initialization */
133  BSP_QSPI_MspInit(&QSPIHandle, NULL);
134 
135  /* QSPI initialization */
136  /* QSPI freq = SYSCLK /(1 + ClockPrescaler) = 216 MHz/(1+1) = 108 Mhz */
137  QSPIHandle.Init.ClockPrescaler = 1; /* QSPI freq = 216 MHz/(1+1) = 108 Mhz */
138  QSPIHandle.Init.FifoThreshold = 16;
142  QSPIHandle.Init.ClockMode = QSPI_CLOCK_MODE_0;
143  QSPIHandle.Init.FlashID = QSPI_FLASH_ID_1;
145 
146  if (HAL_QSPI_Init(&QSPIHandle) != HAL_OK)
147  {
148  return QSPI_ERROR;
149  }
150 
151  /* QSPI memory reset */
152  if (QSPI_ResetMemory(&QSPIHandle) != QSPI_OK)
153  {
154  return QSPI_NOT_SUPPORTED;
155  }
156 
157  /* Put QSPI memory in QPI mode */
158  if( QSPI_EnterMemory_QPI( &QSPIHandle )!=QSPI_OK )
159  {
160  return QSPI_NOT_SUPPORTED;
161  }
162 
163  /* Set the QSPI memory in 4-bytes address mode */
164  if (QSPI_EnterFourBytesAddress(&QSPIHandle) != QSPI_OK)
165  {
166  return QSPI_NOT_SUPPORTED;
167  }
168 
169  /* Configuration of the dummy cycles on QSPI memory side */
170  if (QSPI_DummyCyclesCfg(&QSPIHandle) != QSPI_OK)
171  {
172  return QSPI_NOT_SUPPORTED;
173  }
174 
175  /* Configuration of the Output driver strength on memory side */
176  if( QSPI_OutDrvStrengthCfg( &QSPIHandle ) != QSPI_OK )
177  {
178  return QSPI_NOT_SUPPORTED;
179  }
180 
181  return QSPI_OK;
182 }
183 
188 uint8_t BSP_QSPI_DeInit(void)
189 {
190  QSPIHandle.Instance = QUADSPI;
191 
192  /* Put QSPI memory in SPI mode */
193  if( QSPI_ExitMemory_QPI(&QSPIHandle )!=QSPI_OK )
194  {
195  return QSPI_NOT_SUPPORTED;
196  }
197 
198  /* Call the DeInit function to reset the driver */
199  if (HAL_QSPI_DeInit(&QSPIHandle) != HAL_OK)
200  {
201  return QSPI_ERROR;
202  }
203 
204  /* System level De-initialization */
205  BSP_QSPI_MspDeInit(&QSPIHandle, NULL);
206 
207  return QSPI_OK;
208 }
209 
217 uint8_t BSP_QSPI_Read(uint8_t* pData, uint32_t ReadAddr, uint32_t Size)
218 {
219  QSPI_CommandTypeDef s_command;
220 
221  /* Initialize the read command */
224  s_command.AddressMode = QSPI_ADDRESS_4_LINES;
225  s_command.AddressSize = QSPI_ADDRESS_32_BITS;
226  s_command.Address = ReadAddr;
228  s_command.DataMode = QSPI_DATA_4_LINES;
230  s_command.NbData = Size;
231  s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
234 
235  /* Configure the command */
236  if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
237  {
238  return QSPI_ERROR;
239  }
240 
241  /* Reception of the data */
242  if (HAL_QSPI_Receive(&QSPIHandle, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
243  {
244  return QSPI_ERROR;
245  }
246 
247  return QSPI_OK;
248 }
249 
257 uint8_t BSP_QSPI_Write(uint8_t* pData, uint32_t WriteAddr, uint32_t Size)
258 {
259  QSPI_CommandTypeDef s_command;
260  uint32_t end_addr, current_size, current_addr;
261 
262  /* Calculation of the size between the write address and the end of the page */
263  current_addr = 0;
264 
265  while (current_addr <= WriteAddr)
266  {
267  current_addr += MX25L512_PAGE_SIZE;
268  }
269  current_size = current_addr - WriteAddr;
270 
271  /* Check if the size of the data is less than the remaining place in the page */
272  if (current_size > Size)
273  {
274  current_size = Size;
275  }
276 
277  /* Initialize the address variables */
278  current_addr = WriteAddr;
279  end_addr = WriteAddr + Size;
280 
281  /* Initialize the program command */
284  s_command.AddressMode = QSPI_ADDRESS_4_LINES;
285  s_command.AddressSize = QSPI_ADDRESS_32_BITS;
287  s_command.DataMode = QSPI_DATA_4_LINES;
288  s_command.DummyCycles = 0;
289  s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
292 
293  /* Perform the write page by page */
294  do
295  {
296  s_command.Address = current_addr;
297  s_command.NbData = current_size;
298 
299  /* Enable write operations */
300  if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK)
301  {
302  return QSPI_ERROR;
303  }
304 
305  /* Configure the command */
306  if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
307  {
308  return QSPI_ERROR;
309  }
310 
311  /* Transmission of the data */
312  if (HAL_QSPI_Transmit(&QSPIHandle, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
313  {
314  return QSPI_ERROR;
315  }
316 
317  /* Configure automatic polling mode to wait for end of program */
318  if (QSPI_AutoPollingMemReady(&QSPIHandle, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK)
319  {
320  return QSPI_ERROR;
321  }
322 
323  /* Update the address and size variables for next page programming */
324  current_addr += current_size;
325  pData += current_size;
326  current_size = ((current_addr + MX25L512_PAGE_SIZE) > end_addr) ? (end_addr - current_addr) : MX25L512_PAGE_SIZE;
327  } while (current_addr < end_addr);
328 
329  return QSPI_OK;
330 }
331 
337 uint8_t BSP_QSPI_Erase_Block(uint32_t BlockAddress)
338 {
339  QSPI_CommandTypeDef s_command;
340 
341  /* Initialize the erase command */
344  s_command.AddressMode = QSPI_ADDRESS_4_LINES;
345  s_command.AddressSize = QSPI_ADDRESS_32_BITS;
346  s_command.Address = BlockAddress;
348  s_command.DataMode = QSPI_DATA_NONE;
349  s_command.DummyCycles = 0;
350  s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
353 
354  /* Enable write operations */
355  if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK)
356  {
357  return QSPI_ERROR;
358  }
359 
360  /* Send the command */
361  if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
362  {
363  return QSPI_ERROR;
364  }
365 
366  /* Configure automatic polling mode to wait for end of erase */
367  if (QSPI_AutoPollingMemReady(&QSPIHandle, MX25L512_SUBSECTOR_ERASE_MAX_TIME) != QSPI_OK)
368  {
369  return QSPI_ERROR;
370  }
371 
372  return QSPI_OK;
373 }
374 
379 uint8_t BSP_QSPI_Erase_Chip(void)
380 {
381  QSPI_CommandTypeDef s_command;
382 
383  /* Initialize the erase command */
385  s_command.Instruction = BULK_ERASE_CMD;
386  s_command.AddressMode = QSPI_ADDRESS_NONE;
388  s_command.DataMode = QSPI_DATA_NONE;
389  s_command.DummyCycles = 0;
390  s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
393 
394  /* Enable write operations */
395  if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK)
396  {
397  return QSPI_ERROR;
398  }
399 
400  /* Send the command */
401  if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
402  {
403  return QSPI_ERROR;
404  }
405 
406  /* Configure automatic polling mode to wait for end of erase */
407  if (QSPI_AutoPollingMemReady(&QSPIHandle, MX25L512_BULK_ERASE_MAX_TIME) != QSPI_OK)
408  {
409  return QSPI_ERROR;
410  }
411 
412  return QSPI_OK;
413 }
414 
419 uint8_t BSP_QSPI_GetStatus(void)
420 {
421  QSPI_CommandTypeDef s_command;
422  uint8_t reg;
423 
424  /* Initialize the read flag status register command */
426  s_command.Instruction = READ_STATUS_REG_CMD;
427  s_command.AddressMode = QSPI_ADDRESS_NONE;
429  s_command.DataMode = QSPI_DATA_4_LINES;
430  s_command.DummyCycles = 0;
431  s_command.NbData = 1;
432  s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
435 
436  /* Configure the command */
437  if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
438  {
439  return QSPI_ERROR;
440  }
441 
442  /* Reception of the data */
443  if (HAL_QSPI_Receive(&QSPIHandle, &reg, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
444  {
445  return QSPI_ERROR;
446  }
447 
448  /* Check the value of the register*/
449  if ((reg & MX25L512_SR_WIP) == 0)
450  {
451  return QSPI_OK;
452  }
453  else
454  {
455  return QSPI_BUSY;
456  }
457 }
458 
465 {
466  /* Configure the structure with the memory configuration */
472 
473  return QSPI_OK;
474 }
475 
481 {
482  QSPI_CommandTypeDef s_command;
483  QSPI_MemoryMappedTypeDef s_mem_mapped_cfg;
484 
485  /* Configure the command for the read instruction */
488  s_command.AddressMode = QSPI_ADDRESS_4_LINES;
489  s_command.AddressSize = QSPI_ADDRESS_32_BITS;
491  s_command.DataMode = QSPI_DATA_4_LINES;
493  s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
496 
497  /* Configure the memory mapped mode */
499  s_mem_mapped_cfg.TimeOutPeriod = 0;
500 
501  if (HAL_QSPI_MemoryMapped(&QSPIHandle, &s_command, &s_mem_mapped_cfg) != HAL_OK)
502  {
503  return QSPI_ERROR;
504  }
505 
506  return QSPI_OK;
507 }
508 
525 __weak void BSP_QSPI_MspInit(QSPI_HandleTypeDef *hqspi, void *Params)
526 {
527  GPIO_InitTypeDef gpio_init_structure;
528 
529  /*##-1- Enable peripherals and GPIO Clocks #################################*/
530  /* Enable the QuadSPI memory interface clock */
531  QSPI_CLK_ENABLE();
532  /* Reset the QuadSPI memory interface */
535  /* Enable GPIO clocks */
542 
543  /*##-2- Configure peripheral GPIO ##########################################*/
544  /* QSPI CS GPIO pin configuration */
545  gpio_init_structure.Pin = QSPI_CS_PIN;
546  gpio_init_structure.Alternate = QSPI_CS_PIN_AF;
547  gpio_init_structure.Mode = GPIO_MODE_AF_PP;
548  gpio_init_structure.Pull = GPIO_PULLUP;
549  gpio_init_structure.Speed = GPIO_SPEED_FREQ_HIGH;
550  HAL_GPIO_Init(QSPI_CS_GPIO_PORT, &gpio_init_structure);
551  /* QSPI CLK GPIO pin configuration */
552  gpio_init_structure.Pin = QSPI_CLK_PIN;
553  gpio_init_structure.Alternate = QSPI_CLK_PIN_AF;
554  gpio_init_structure.Pull = GPIO_NOPULL;
555  HAL_GPIO_Init(QSPI_CLK_GPIO_PORT, &gpio_init_structure);
556  /* QSPI D0 GPIO pin configuration */
557  gpio_init_structure.Pin = QSPI_D0_PIN;
558  gpio_init_structure.Alternate = QSPI_D0_PIN_AF;
559  HAL_GPIO_Init(QSPI_D0_GPIO_PORT, &gpio_init_structure);
560  /* QSPI D1 GPIO pin configuration */
561  gpio_init_structure.Pin = QSPI_D1_PIN;
562  gpio_init_structure.Alternate = QSPI_D1_PIN_AF;
563  HAL_GPIO_Init(QSPI_D1_GPIO_PORT, &gpio_init_structure);
564  /* QSPI D2 GPIO pin configuration */
565  gpio_init_structure.Pin = QSPI_D2_PIN;
566  gpio_init_structure.Alternate = QSPI_D2_PIN_AF;
567  HAL_GPIO_Init(QSPI_D2_GPIO_PORT, &gpio_init_structure);
568  /* QSPI D3 GPIO pin configuration */
569  gpio_init_structure.Pin = QSPI_D3_PIN;
570  gpio_init_structure.Alternate = QSPI_D3_PIN_AF;
571  HAL_GPIO_Init(QSPI_D3_GPIO_PORT, &gpio_init_structure);
572 
573  /*##-3- Configure the NVIC for QSPI #########################################*/
574  /* NVIC configuration for QSPI interrupt */
577 }
578 
586 __weak void BSP_QSPI_MspDeInit(QSPI_HandleTypeDef *hqspi, void *Params)
587 {
588  /*##-1- Disable the NVIC for QSPI ###########################################*/
590 
591  /*##-2- Disable peripherals and GPIO Clocks ################################*/
592  /* De-Configure QSPI pins */
599 
600  /*##-3- Reset peripherals ##################################################*/
601  /* Reset the QuadSPI memory interface */
604 
605  /* Disable the QuadSPI memory interface clock */
607 }
608 
614 static uint8_t QSPI_ResetMemory(QSPI_HandleTypeDef *hqspi)
615 {
616  QSPI_CommandTypeDef s_command;
617  QSPI_AutoPollingTypeDef s_config;
618  uint8_t reg;
619 
620  /* Send command RESET command in QPI mode (QUAD I/Os) */
621  /* Initialize the reset enable command */
623  s_command.Instruction = RESET_ENABLE_CMD;
624  s_command.AddressMode = QSPI_ADDRESS_NONE;
626  s_command.DataMode = QSPI_DATA_NONE;
627  s_command.DummyCycles = 0;
628  s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
631  /* Send the command */
632  if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
633  {
634  return QSPI_ERROR;
635  }
636  /* Send the reset memory command */
637  s_command.Instruction = RESET_MEMORY_CMD;
638  if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
639  {
640  return QSPI_ERROR;
641  }
642 
643  /* Send command RESET command in SPI mode */
644  /* Initialize the reset enable command */
646  s_command.Instruction = RESET_ENABLE_CMD;
647  /* Send the command */
648  if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
649  {
650  return QSPI_ERROR;
651  }
652  /* Send the reset memory command */
653  s_command.Instruction = RESET_MEMORY_CMD;
654  if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
655  {
656  return QSPI_ERROR;
657  }
658 
659  /* After reset CMD, 1000ms requested if QSPI memory SWReset occured during full chip erase operation */
660  HAL_Delay( 1000 );
661 
662  /* Configure automatic polling mode to wait the WIP bit=0 */
663  s_config.Match = 0;
664  s_config.Mask = MX25L512_SR_WIP;
665  s_config.MatchMode = QSPI_MATCH_MODE_AND;
666  s_config.StatusBytesSize = 1;
667  s_config.Interval = 0x10;
669 
671  s_command.Instruction = READ_STATUS_REG_CMD;
672  s_command.DataMode = QSPI_DATA_1_LINE;
673 
674  if (HAL_QSPI_AutoPolling(hqspi, &s_command, &s_config, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
675  {
676  return QSPI_ERROR;
677  }
678 
679  /* Initialize the reading of status register */
681  s_command.Instruction = READ_STATUS_REG_CMD;
682  s_command.AddressMode = QSPI_ADDRESS_NONE;
684  s_command.DataMode = QSPI_DATA_1_LINE;
685  s_command.DummyCycles = 0;
686  s_command.NbData = 1;
687  s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
690 
691  /* Configure the command */
692  if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
693  {
694  return QSPI_ERROR;
695  }
696 
697  /* Reception of the data */
699  {
700  return QSPI_ERROR;
701  }
702 
703  /* Enable write operations, command in 1 bit */
704  /* Enable write operations */
706  s_command.Instruction = WRITE_ENABLE_CMD;
707  s_command.AddressMode = QSPI_ADDRESS_NONE;
709  s_command.DataMode = QSPI_DATA_NONE;
710  s_command.DummyCycles = 0;
711  s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
714 
715  if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
716  {
717  return QSPI_ERROR;
718  }
719 
720  /* Configure automatic polling mode to wait for write enabling */
721  s_config.Match = MX25L512_SR_WREN;
722  s_config.Mask = MX25L512_SR_WREN;
723  s_config.MatchMode = QSPI_MATCH_MODE_AND;
724  s_config.StatusBytesSize = 1;
725  s_config.Interval = 0x10;
727 
728  s_command.Instruction = READ_STATUS_REG_CMD;
729  s_command.DataMode = QSPI_DATA_1_LINE;
730 
731  if (HAL_QSPI_AutoPolling(hqspi, &s_command, &s_config, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
732  {
733  return QSPI_ERROR;
734  }
735 
736  /* Update the configuration register with new dummy cycles */
739  s_command.AddressMode = QSPI_ADDRESS_NONE;
741  s_command.DataMode = QSPI_DATA_1_LINE;
742  s_command.DummyCycles = 0;
743  s_command.NbData = 1;
744  s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
747 
748  /* Enable the Quad IO on the QSPI memory (Non-volatile bit) */
749  reg |= MX25L512_SR_QUADEN;
750 
751  /* Configure the command */
752  if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
753  {
754  return QSPI_ERROR;
755  }
756 
757  /* Transmission of the data */
759  {
760  return QSPI_ERROR;
761  }
762 
763  /* 40ms Write Status/Configuration Register Cycle Time */
764  HAL_Delay( 40 );
765 
766  return QSPI_OK;
767 }
768 
774 static uint8_t QSPI_EnterFourBytesAddress(QSPI_HandleTypeDef *hqspi)
775 {
776  QSPI_CommandTypeDef s_command;
777 
778  /* Initialize the command */
781  s_command.AddressMode = QSPI_ADDRESS_NONE;
783  s_command.DataMode = QSPI_DATA_NONE;
784  s_command.DummyCycles = 0;
785  s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
788 
789  /* Enable write operations */
790  if (QSPI_WriteEnable(hqspi) != QSPI_OK)
791  {
792  return QSPI_ERROR;
793  }
794 
795  /* Send the command */
796  if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
797  {
798  return QSPI_ERROR;
799  }
800 
801  /* Configure automatic polling mode to wait the memory is ready */
802  if (QSPI_AutoPollingMemReady(hqspi, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK)
803  {
804  return QSPI_ERROR;
805  }
806 
807  return QSPI_OK;
808 }
809 
815 static uint8_t QSPI_DummyCyclesCfg(QSPI_HandleTypeDef *hqspi)
816 {
817  QSPI_CommandTypeDef s_command;
818  uint8_t reg[2];
819 
820  /* Initialize the reading of status register */
822  s_command.Instruction = READ_STATUS_REG_CMD;
823  s_command.AddressMode = QSPI_ADDRESS_NONE;
825  s_command.DataMode = QSPI_DATA_4_LINES;
826  s_command.DummyCycles = 0;
827  s_command.NbData = 1;
828  s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
831 
832  /* Configure the command */
833  if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
834  {
835  return QSPI_ERROR;
836  }
837 
838  /* Reception of the data */
839  if (HAL_QSPI_Receive(hqspi, &(reg[0]), HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
840  {
841  return QSPI_ERROR;
842  }
843 
844  /* Initialize the reading of configuration register */
846  s_command.Instruction = READ_CFG_REG_CMD;
847  s_command.AddressMode = QSPI_ADDRESS_NONE;
849  s_command.DataMode = QSPI_DATA_4_LINES;
850  s_command.DummyCycles = 0;
851  s_command.NbData = 1;
852  s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
855 
856  /* Configure the command */
857  if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
858  {
859  return QSPI_ERROR;
860  }
861 
862  /* Reception of the data */
863  if (HAL_QSPI_Receive(hqspi, &(reg[1]), HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
864  {
865  return QSPI_ERROR;
866  }
867 
868  /* Enable write operations */
869  if (QSPI_WriteEnable(hqspi) != QSPI_OK)
870  {
871  return QSPI_ERROR;
872  }
873 
874  /* Update the configuration register with new dummy cycles */
877  s_command.AddressMode = QSPI_ADDRESS_NONE;
879  s_command.DataMode = QSPI_DATA_4_LINES;
880  s_command.DummyCycles = 0;
881  s_command.NbData = 2;
882  s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
885 
886  /* MX25L512_DUMMY_CYCLES_READ_QUAD = 3 for 10 cycles in QPI mode */
888 
889  /* Configure the write volatile configuration register command */
890  if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
891  {
892  return QSPI_ERROR;
893  }
894 
895  /* Transmission of the data */
896  if (HAL_QSPI_Transmit(hqspi, &(reg[0]), HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
897  {
898  return QSPI_ERROR;
899  }
900 
901  /* 40ms Write Status/Configuration Register Cycle Time */
902  HAL_Delay( 40 );
903 
904  return QSPI_OK;
905 }
906 
912 static uint8_t QSPI_EnterMemory_QPI( QSPI_HandleTypeDef *hqspi )
913 {
914  QSPI_CommandTypeDef s_command;
915  QSPI_AutoPollingTypeDef s_config;
916 
917  /* Initialize the QPI enable command */
918  /* QSPI memory is supported to be in SPI mode, so CMD on 1 LINE */
920  s_command.Instruction = ENTER_QUAD_CMD;
921  s_command.AddressMode = QSPI_ADDRESS_NONE;
923  s_command.DataMode = QSPI_DATA_NONE;
924  s_command.DummyCycles = 0;
925  s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
928 
929  /* Send the command */
930  if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
931  {
932  return QSPI_ERROR;
933  }
934 
935  /* Configure automatic polling mode to wait the QUADEN bit=1 and WIP bit=0 */
936  s_config.Match = MX25L512_SR_QUADEN;
938  s_config.MatchMode = QSPI_MATCH_MODE_AND;
939  s_config.StatusBytesSize = 1;
940  s_config.Interval = 0x10;
942 
944  s_command.Instruction = READ_STATUS_REG_CMD;
945  s_command.DataMode = QSPI_DATA_4_LINES;
946 
947  if (HAL_QSPI_AutoPolling(hqspi, &s_command, &s_config, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
948  {
949  return QSPI_ERROR;
950  }
951 
952  return QSPI_OK;
953 }
954 
960 static uint8_t QSPI_ExitMemory_QPI( QSPI_HandleTypeDef *hqspi)
961 {
962  QSPI_CommandTypeDef s_command;
963 
964  /* Initialize the QPI enable command */
965  /* QSPI memory is supported to be in QPI mode, so CMD on 4 LINES */
967  s_command.Instruction = EXIT_QUAD_CMD;
968  s_command.AddressMode = QSPI_ADDRESS_NONE;
970  s_command.DataMode = QSPI_DATA_NONE;
971  s_command.DummyCycles = 0;
972  s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
975 
976  /* Send the command */
977  if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
978  {
979  return QSPI_ERROR;
980  }
981 
982  return QSPI_OK;
983 }
984 
990 static uint8_t QSPI_OutDrvStrengthCfg( QSPI_HandleTypeDef *hqspi )
991 {
992  QSPI_CommandTypeDef s_command;
993  uint8_t reg[2];
994 
995  /* Initialize the reading of status register */
997  s_command.Instruction = READ_STATUS_REG_CMD;
998  s_command.AddressMode = QSPI_ADDRESS_NONE;
1000  s_command.DataMode = QSPI_DATA_4_LINES;
1001  s_command.DummyCycles = 0;
1002  s_command.NbData = 1;
1003  s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
1005  s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
1006 
1007  /* Configure the command */
1008  if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
1009  {
1010  return QSPI_ERROR;
1011  }
1012 
1013  /* Reception of the data */
1014  if (HAL_QSPI_Receive(hqspi, &(reg[0]), HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
1015  {
1016  return QSPI_ERROR;
1017  }
1018 
1019  /* Initialize the reading of configuration register */
1021  s_command.Instruction = READ_CFG_REG_CMD;
1022  s_command.AddressMode = QSPI_ADDRESS_NONE;
1024  s_command.DataMode = QSPI_DATA_4_LINES;
1025  s_command.DummyCycles = 0;
1026  s_command.NbData = 1;
1027  s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
1029  s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
1030 
1031  /* Configure the command */
1032  if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
1033  {
1034  return QSPI_ERROR;
1035  }
1036 
1037  /* Reception of the data */
1038  if (HAL_QSPI_Receive(hqspi, &(reg[1]), HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
1039  {
1040  return QSPI_ERROR;
1041  }
1042 
1043  /* Enable write operations */
1044  if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK)
1045  {
1046  return QSPI_ERROR;
1047  }
1048 
1049  /* Update the configuration register with new output driver strength */
1052  s_command.AddressMode = QSPI_ADDRESS_NONE;
1054  s_command.DataMode = QSPI_DATA_4_LINES;
1055  s_command.DummyCycles = 0;
1056  s_command.NbData = 2;
1057  s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
1059  s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
1060 
1061  /* Set Output Strength of the QSPI memory 15 ohms */
1063 
1064  /* Configure the write volatile configuration register command */
1065  if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
1066  {
1067  return QSPI_ERROR;
1068  }
1069 
1070  /* Transmission of the data */
1071  if (HAL_QSPI_Transmit(hqspi, &(reg[0]), HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
1072  {
1073  return QSPI_ERROR;
1074  }
1075 
1076  return QSPI_OK;
1077 }
1078 
1084 static uint8_t QSPI_WriteEnable(QSPI_HandleTypeDef *hqspi)
1085 {
1086  QSPI_CommandTypeDef s_command;
1087  QSPI_AutoPollingTypeDef s_config;
1088 
1089  /* Enable write operations */
1091  s_command.Instruction = WRITE_ENABLE_CMD;
1092  s_command.AddressMode = QSPI_ADDRESS_NONE;
1094  s_command.DataMode = QSPI_DATA_NONE;
1095  s_command.DummyCycles = 0;
1096  s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
1098  s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
1099 
1100  if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
1101  {
1102  return QSPI_ERROR;
1103  }
1104 
1105  /* Configure automatic polling mode to wait for write enabling */
1106  s_config.Match = MX25L512_SR_WREN;
1107  s_config.Mask = MX25L512_SR_WREN;
1108  s_config.MatchMode = QSPI_MATCH_MODE_AND;
1109  s_config.StatusBytesSize = 1;
1110  s_config.Interval = 0x10;
1112 
1113  s_command.Instruction = READ_STATUS_REG_CMD;
1114  s_command.DataMode = QSPI_DATA_4_LINES;
1115 
1116  if (HAL_QSPI_AutoPolling(hqspi, &s_command, &s_config, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
1117  {
1118  return QSPI_ERROR;
1119  }
1120 
1121  return QSPI_OK;
1122 }
1123 
1130 static uint8_t QSPI_AutoPollingMemReady(QSPI_HandleTypeDef *hqspi, uint32_t Timeout)
1131 {
1132  QSPI_CommandTypeDef s_command;
1133  QSPI_AutoPollingTypeDef s_config;
1134 
1135  /* Configure automatic polling mode to wait for memory ready */
1137  s_command.Instruction = READ_STATUS_REG_CMD;
1138  s_command.AddressMode = QSPI_ADDRESS_NONE;
1140  s_command.DataMode = QSPI_DATA_4_LINES;
1141  s_command.DummyCycles = 0;
1142  s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
1144  s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
1145 
1146  s_config.Match = 0;
1147  s_config.Mask = MX25L512_SR_WIP;
1148  s_config.MatchMode = QSPI_MATCH_MODE_AND;
1149  s_config.StatusBytesSize = 1;
1150  s_config.Interval = 0x10;
1152 
1153  if (HAL_QSPI_AutoPolling(hqspi, &s_command, &s_config, Timeout) != HAL_OK)
1154  {
1155  return QSPI_ERROR;
1156  }
1157 
1158  return QSPI_OK;
1159 }
1176 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
#define QSPI_D0_PIN
QSPI Handle Structure definition.
#define QSPI_NOT_SUPPORTED
#define QSPI_D3_PIN_AF
#define MODIFY_REG(REG, CLEARMASK, SETMASK)
Definition: stm32f7xx.h:190
#define MX25L512_DUMMY_CYCLES_READ_QUAD_IO
Definition: mx25l512.h:82
#define QSPI_ALTERNATE_BYTES_NONE
#define GPIO_NOPULL
#define QSPI_CS_GPIO_CLK_ENABLE()
uint8_t BSP_QSPI_GetStatus(void)
Reads current status of the QSPI memory.
#define QSPI_CLK_PIN_AF
#define RESET_ENABLE_CMD
MX25L512 Commands.
Definition: mx25l512.h:94
#define GPIO_SPEED_FREQ_HIGH
#define QSPI_CLK_DISABLE()
#define QSPI_D1_PIN_AF
#define MX25L512_SUBSECTOR_ERASE_MAX_TIME
Definition: mx25l512.h:88
void HAL_Delay(__IO uint32_t Delay)
This function provides accurate delay (in milliseconds) based on variable incremented.
#define QSPI_D0_GPIO_CLK_ENABLE()
#define QSPI_D2_PIN
#define QSPI_D0_PIN_AF
#define MX25L512_FLASH_SIZE
MX25L512 Configuration.
Definition: mx25l512.h:75
#define QSPI_SIOO_INST_EVERY_CMD
#define QSPI_ADDRESS_NONE
void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin)
QSPI_InitTypeDef Init
#define QSPI_D1_GPIO_PORT
uint8_t BSP_QSPI_EnableMemoryMappedMode(void)
Configure the QSPI in memory-mapped mode.
#define MX25L512_SUBSECTOR_SIZE
Definition: mx25l512.h:77
#define MX25L512_SR_QUADEN
Definition: mx25l512.h:175
QSPI Command structure definition.
#define WRITE_ENABLE_CMD
Definition: mx25l512.h:125
#define QSPI_MATCH_MODE_AND
HAL_StatusTypeDef HAL_QSPI_DeInit(QSPI_HandleTypeDef *hqspi)
#define QSPI_DATA_4_LINES
This file contains the common defines and functions prototypes for the stm32f769i_discovery_qspi.c driver.
#define QSPI_OK
#define BULK_ERASE_CMD
Definition: mx25l512.h:154
#define POSITION_VAL(VAL)
Definition: stm32f7xx.h:192
HAL_StatusTypeDef HAL_QSPI_Transmit(QSPI_HandleTypeDef *hqspi, uint8_t *pData, uint32_t Timeout)
#define GPIO_PULLUP
#define QSPI_RELEASE_RESET()
#define QSPI_BUSY
#define QSPI_D1_GPIO_CLK_ENABLE()
#define QSPI_TIMEOUT_COUNTER_DISABLE
#define MX25L512_SR_WIP
MX25L512 Registers.
Definition: mx25l512.h:171
#define QSPI_D3_PIN
HAL_StatusTypeDef HAL_QSPI_AutoPolling(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_AutoPollingTypeDef *cfg, uint32_t Timeout)
#define NULL
Definition: usbd_def.h:53
QSPI Memory Mapped mode configuration structure definition.
#define QSPI_CLK_GPIO_PORT
#define QPI_PAGE_PROG_4_BYTE_ADDR_CMD
Definition: mx25l512.h:141
#define WRITE_STATUS_CFG_REG_CMD
Definition: mx25l512.h:131
#define QSPI_DDR_MODE_DISABLE
uint8_t BSP_QSPI_GetInfo(QSPI_Info *pInfo)
Return the configuration of the QSPI memory.
#define MX25L512_BULK_ERASE_MAX_TIME
Definition: mx25l512.h:86
QSPI Auto Polling mode configuration structure definition.
void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority)
#define QSPI_AUTOMATIC_STOP_ENABLE
#define ENTER_QUAD_CMD
Definition: mx25l512.h:164
QUADSPI_TypeDef * Instance
#define READ_STATUS_REG_CMD
Definition: mx25l512.h:129
#define QSPI_ERROR
#define QSPI_CS_GPIO_PORT
void HAL_NVIC_EnableIRQ(IRQn_Type IRQn)
#define QSPI_D3_GPIO_PORT
#define EXIT_QUAD_CMD
Definition: mx25l512.h:165
#define QSPI_CLK_GPIO_CLK_ENABLE()
#define QSPI_INSTRUCTION_1_LINE
#define MX25L512_DUMMY_CYCLES_READ_QUAD
Definition: mx25l512.h:80
#define QSPI_D0_GPIO_PORT
GPIO Init structure definition.
#define QSPI_D1_PIN
#define QSPI_DUALFLASH_DISABLE
#define QUADSPI
Definition: stm32f745xx.h:1353
uint8_t BSP_QSPI_Erase_Chip(void)
Erases the entire QSPI memory.
uint8_t BSP_QSPI_Read(uint8_t *pData, uint32_t ReadAddr, uint32_t Size)
Reads an amount of data from the QSPI memory.
#define SUBSECTOR_ERASE_4_BYTE_ADDR_CMD
Definition: mx25l512.h:149
#define READ_CFG_REG_CMD
Definition: mx25l512.h:130
#define QSPI_SAMPLE_SHIFTING_HALFCYCLE
#define MX25L512_CR_ODS_15
Definition: mx25l512.h:181
#define MX25L512_CR_NB_DUMMY
Definition: mx25l512.h:189
#define QSPI_DATA_NONE
QSPI_HandleTypeDef QSPIHandle
void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init)
uint8_t BSP_QSPI_Erase_Block(uint32_t BlockAddress)
Erases the specified block of the QSPI memory.
#define QSPI_FORCE_RESET()
#define QSPI_CS_PIN
#define MX25L512_CR_ODS
Definition: mx25l512.h:179
#define HAL_QPSI_TIMEOUT_DEFAULT_VALUE
HAL_StatusTypeDef HAL_QSPI_MemoryMapped(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, QSPI_MemoryMappedTypeDef *cfg)
uint8_t BSP_QSPI_Init(void)
Initializes the QSPI interface.
uint8_t BSP_QSPI_DeInit(void)
De-Initializes the QSPI interface.
__weak void BSP_QSPI_MspDeInit(QSPI_HandleTypeDef *hqspi, void *Params)
QSPI MSP De-Initialization This function frees the hardware resources used in this example: ...
#define MX25L512_PAGE_SIZE
Definition: mx25l512.h:78
#define QSPI_INSTRUCTION_4_LINES
#define QPI_READ_4_BYTE_ADDR_CMD
Definition: mx25l512.h:122
#define QSPI_DATA_1_LINE
#define QSPI_CS_HIGH_TIME_1_CYCLE
uint8_t BSP_QSPI_Write(uint8_t *pData, uint32_t WriteAddr, uint32_t Size)
Writes an amount of data to the QSPI memory.
__weak void BSP_QSPI_MspInit(QSPI_HandleTypeDef *hqspi, void *Params)
QSPI MSP Initialization This function configures the hardware resources used in this example: ...
#define QSPI_D2_GPIO_PORT
HAL_StatusTypeDef HAL_QSPI_Init(QSPI_HandleTypeDef *hqspi)
#define QSPI_DDR_HHC_ANALOG_DELAY
#define GPIO_MODE_AF_PP
#define QSPI_FLASH_ID_1
#define QSPI_ADDRESS_4_LINES
#define ENTER_4_BYTE_ADDR_MODE_CMD
Definition: mx25l512.h:160
#define QSPI_CLK_PIN
void HAL_NVIC_DisableIRQ(IRQn_Type IRQn)
#define QSPI_D2_GPIO_CLK_ENABLE()
HAL_StatusTypeDef HAL_QSPI_Command(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t Timeout)
#define QSPI_ADDRESS_32_BITS
#define RESET_MEMORY_CMD
Definition: mx25l512.h:95
#define QSPI_CS_PIN_AF
#define QSPI_D3_GPIO_CLK_ENABLE()
#define QSPI_D2_PIN_AF
#define QSPI_CLK_ENABLE()
#define MX25L512_SR_WREN
Definition: mx25l512.h:172
#define QSPI_CLOCK_MODE_0
HAL_StatusTypeDef HAL_QSPI_Receive(QSPI_HandleTypeDef *hqspi, uint8_t *pData, uint32_t Timeout)