Example #1
0
/**
  * @brief  Main program
  * @param  None
  * @retval None
  */
int main(void)
{
  QSPI_CommandTypeDef      sCommand;
  QSPI_MemoryMappedTypeDef sMemMappedCfg;
  uint32_t address = 0;
  __IO uint8_t *qspi_addr = (__IO uint8_t *)(0x90000000);
  uint16_t index;
  __IO uint8_t step = 0;

  /* STM32F4xx HAL library initialization:
       - Configure the Flash prefetch, instruction and Data caches
       - Systick timer is configured by default as source of time base, but user 
         can eventually implement his proper time base source (a general purpose 
         timer for example or other time source), keeping in mind that Time base 
         duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and 
         handled in milliseconds basis.
       - Set NVIC Group Priority to 4
       - Low Level Initialization: global MSP (MCU Support Package) initialization
     */
  HAL_Init();

  /* Configure the system clock to 180 MHz */
  SystemClock_Config();

  BSP_LED_Init(LED1);
  BSP_LED_Init(LED3);
  
  /* Initialize QuadSPI structures ------------------------------------------- */
  QSPIHandle.Instance = QUADSPI;
        
  QSPIHandle.Init.ClockPrescaler     = 1;
  QSPIHandle.Init.FifoThreshold      = 4;
  QSPIHandle.Init.SampleShifting     = QSPI_SAMPLE_SHIFTING_HALFCYCLE;
  QSPIHandle.Init.FlashSize          = QSPI_FLASH_SIZE;
  QSPIHandle.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_1_CYCLE;
  QSPIHandle.Init.ClockMode          = QSPI_CLOCK_MODE_0;


  sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
  sCommand.AddressSize       = QSPI_ADDRESS_24_BITS;
  sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
  sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;
  sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
  sCommand.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;

  while(1)
  {
    switch(step)
    {
      case 0:
        CmdCplt = 0;

        /* Initialize QuadSPI ------------------------------------------------ */
        HAL_QSPI_DeInit(&QSPIHandle);
        if (HAL_QSPI_Init(&QSPIHandle) != HAL_OK)
        {
          Error_Handler();
        }

        /* Enable write operations ------------------------------------------- */
        QSPI_WriteEnable(&QSPIHandle);

        /* Erasing Sequence -------------------------------------------------- */
        sCommand.Instruction = SECTOR_ERASE_CMD;
        sCommand.AddressMode = QSPI_ADDRESS_1_LINE;
        sCommand.Address     = address;
        sCommand.DataMode    = QSPI_DATA_NONE;
        sCommand.DummyCycles = 0;

        if (HAL_QSPI_Command_IT(&QSPIHandle, &sCommand) != HAL_OK)
        {
          Error_Handler();
        }

        step++;
        break;

      case 1:
        if(CmdCplt != 0)
        {
          CmdCplt = 0;
          StatusMatch = 0;

          /* Configure automatic polling mode to wait for end of erase ------- */  
          QSPI_AutoPollingMemReady(&QSPIHandle);

          step++;
        }
        break;
        
      case 2:
        if(StatusMatch != 0)
        {
          StatusMatch = 0;
          TxCplt = 0;
          
          /* Enable write operations ----------------------------------------- */
          QSPI_WriteEnable(&QSPIHandle);

          /* Writing Sequence ------------------------------------------------ */
          sCommand.Instruction = EXT_QUAD_IN_FAST_PROG_CMD;
          sCommand.AddressMode = QSPI_ADDRESS_4_LINES;
          sCommand.DataMode    = QSPI_DATA_4_LINES;
          sCommand.NbData      = BUFFERSIZE;

          if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
          {
            Error_Handler();
          }

          if (HAL_QSPI_Transmit_DMA(&QSPIHandle, aTxBuffer) != HAL_OK)
          {
            Error_Handler();
          }

          step++;
        }
        break;

      case 3:
        if(TxCplt != 0)
        {
          TxCplt = 0;
          StatusMatch = 0;

          /* Configure automatic polling mode to wait for end of program ----- */  
          QSPI_AutoPollingMemReady(&QSPIHandle);
        
          step++;
        }
        break;
        
      case 4:
        if(StatusMatch != 0)
        {
          StatusMatch = 0;
          RxCplt = 0;

          /* Configure Volatile Configuration register (with new dummy cycles) */
          QSPI_DummyCyclesCfg(&QSPIHandle);
          
          /* Reading Sequence ------------------------------------------------ */
          sCommand.Instruction = QUAD_INOUT_FAST_READ_CMD;
          sCommand.DummyCycles = DUMMY_CLOCK_CYCLES_READ_QUAD;

          sMemMappedCfg.TimeOutActivation = QSPI_TIMEOUT_COUNTER_DISABLE;

          if (HAL_QSPI_MemoryMapped(&QSPIHandle, &sCommand, &sMemMappedCfg) != HAL_OK)
          {
            Error_Handler();
          }

          for (index = 0; index < BUFFERSIZE; index++)
          {
            if (*qspi_addr != aTxBuffer[index])
            {
              BSP_LED_On(LED3);
            }
            qspi_addr++;
          }
          BSP_LED_Toggle(LED1);

          address += QSPI_PAGE_SIZE;
          if(address >= QSPI_END_ADDR)
          {
            address = 0;
          }
          qspi_addr = (__IO uint8_t *)(0x90000000 + address);

          step = 0;
        }
        break;
        
      default :
        Error_Handler();
    }
  }
}
Example #2
0
/**
  * @brief  Main program
  * @param  None
  * @retval None
  */
int main(void)
{
  QSPI_CommandTypeDef      sCommand;
  QSPI_MemoryMappedTypeDef sMemMappedCfg;
  __IO uint32_t qspi_addr = 0;
  uint8_t *flash_addr;
  __IO uint8_t step = 0;
  uint32_t max_size, size;

  /* STM32F4xx HAL library initialization:
       - Configure the Flash prefetch, instruction and Data caches
       - Systick timer is configured by default as source of time base, but user
         can eventually implement his proper time base source (a general purpose
         timer for example or other time source), keeping in mind that Time base
         duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and
         handled in milliseconds basis.
       - Set NVIC Group Priority to 4
       - Low Level Initialization: global MSP (MCU Support Package) initialization
     */
  HAL_Init();

  /* Configure the system clock to 180 MHz */
  SystemClock_Config();

  BSP_LED_Init(LED1);
  BSP_LED_Init(LED3);

  /* Initialize QuadSPI ------------------------------------------------------ */
  QSPIHandle.Instance = QUADSPI;
  HAL_QSPI_DeInit(&QSPIHandle);

  QSPIHandle.Init.ClockPrescaler     = 1;
  QSPIHandle.Init.FifoThreshold      = 4;
  QSPIHandle.Init.SampleShifting     = QSPI_SAMPLE_SHIFTING_HALFCYCLE;
  QSPIHandle.Init.FlashSize          = QSPI_FLASH_SIZE;
  QSPIHandle.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_2_CYCLE;
  QSPIHandle.Init.ClockMode          = QSPI_CLOCK_MODE_0;

  if (HAL_QSPI_Init(&QSPIHandle) != HAL_OK)
  {
    Error_Handler();
  }

  sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
  sCommand.AddressSize       = QSPI_ADDRESS_24_BITS;
  sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
  sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;
  sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
  sCommand.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;

  flash_addr = 0;
  size = 0 ;

#if defined(__CC_ARM)
  max_size = (uint32_t)(&Load$$QSPI$$Length);
#elif defined(__ICCARM__)
  max_size = __section_size(".qspi_init");
#elif defined(__GNUC__)
  max_size = (uint32_t)((uint8_t *)(&_qspi_init_length));
#endif

  while(1)
  {
    switch(step)
    {
      case 0:
        CmdCplt = 0;

        /* Enable write operations ------------------------------------------- */
        QSPI_WriteEnable(&QSPIHandle);

        /* Erasing Sequence -------------------------------------------------- */
        sCommand.Instruction = SECTOR_ERASE_CMD;
        sCommand.AddressMode = QSPI_ADDRESS_1_LINE;
        sCommand.Address     = qspi_addr;
        sCommand.DataMode    = QSPI_DATA_NONE;
        sCommand.DummyCycles = 0;

        if (HAL_QSPI_Command_IT(&QSPIHandle, &sCommand) != HAL_OK)
        {
          Error_Handler();
        }

        step++;
        break;

      case 1:
        if(CmdCplt != 0)
        {
          CmdCplt = 0;
          StatusMatch = 0;

          /* Configure automatic polling mode to wait for end of erase ------- */
          QSPI_AutoPollingMemReady(&QSPIHandle);

          /* Initialize the variables for the data writing ------------------- */
          #if defined(__CC_ARM)
          flash_addr = (uint8_t *)(&Load$$QSPI$$Base);
          #elif defined(__ICCARM__)
          flash_addr = (uint8_t *)(__section_begin(".qspi_init"));
          #elif defined(__GNUC__)
          flash_addr =(uint8_t *)(&_qspi_init_base);
          #endif

          /* Copy only one page if the section is bigger */
          if (max_size > QSPI_PAGE_SIZE)
          {
            size = QSPI_PAGE_SIZE;
          }
          else
          {
            size = max_size;
          }

          step++;
        }
        break;

      case 2:
        if(StatusMatch != 0)
        {
          StatusMatch = 0;
          TxCplt = 0;

          /* Enable write operations ----------------------------------------- */
          QSPI_WriteEnable(&QSPIHandle);

          /* Writing Sequence ------------------------------------------------ */
          sCommand.Instruction = EXT_QUAD_IN_FAST_PROG_CMD;
          sCommand.AddressMode = QSPI_ADDRESS_4_LINES;
          sCommand.Address     = qspi_addr;
          sCommand.DataMode    = QSPI_DATA_4_LINES;
          sCommand.NbData      = size;

          if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
          {
            Error_Handler();
          }

          if (HAL_QSPI_Transmit_DMA(&QSPIHandle, flash_addr) != HAL_OK)
          {
            Error_Handler();
          }

          step++;
        }
        break;

      case 3:
        if(TxCplt != 0)
        {
          TxCplt = 0;
          StatusMatch = 0;

          /* Configure automatic polling mode to wait for end of program ----- */
          QSPI_AutoPollingMemReady(&QSPIHandle);

          step++;
        }
        break;

      case 4:
        if(StatusMatch != 0)
        {
          qspi_addr += size;
          flash_addr += size;

          /* Check if a new page writing is needed */
          if (qspi_addr < max_size)
          {
            /* Update the remaining size if it is less than the page size */
            if ((qspi_addr + size) > max_size)
            {
              size = max_size - qspi_addr;
            }
            step = 2;
          }
          else
          {
            StatusMatch = 0;
            RxCplt = 0;

            /* Configure Volatile Configuration register (with new dummy cycles) */
            QSPI_DummyCyclesCfg(&QSPIHandle);

            /* Reading Sequence ------------------------------------------------ */
            sCommand.Instruction = QUAD_INOUT_FAST_READ_CMD;
            sCommand.DummyCycles = DUMMY_CLOCK_CYCLES_READ_QUAD;

            sMemMappedCfg.TimeOutActivation = QSPI_TIMEOUT_COUNTER_DISABLE;

            if (HAL_QSPI_MemoryMapped(&QSPIHandle, &sCommand, &sMemMappedCfg) != HAL_OK)
            {
              Error_Handler();
            }

            step++;
          }
        }
        break;

      case 5:
          /* Execute the code from QSPI memory ------------------------------- */
          GpioToggle();
        break;

      default :
        Error_Handler();
    }
  }
}