STM32F750 QSPI Erişimi

Başlatan yldzelektronik, 18 Ağustos 2019, 12:28:01

yldzelektronik

Selamlar,

STM32F750N8 kullanarak W25Q128JVSIMTR QSPI flasha bağlanmaya, veri yazıp okumaya çalışıyorum. Ancak başarılı olamıyorum.

Referans aldığım kodlar STM32F7508-DISCO QSPI ReadWrite IT örneğinde mevcut.

Init işlemi aşağıdaki gibi. Ancak burada dikkatimi çeken bir şey var. ClockPrescaler ve ChipSelectHighTime ile ilgili farklı kaynaklarda farklı şeyler görüyorum. Örneğin yine aynı kitin bsp_library dosyasında mcu 216 mhz ayarlanmış ve ClockPrescaler 1 olarak belirlenmiş. Bunun yanında ChipSelectHighTime 6 cycle olarak belirlenmiş.

Gerçi orada düşülen nota göre bu değerin en az 50 nSec olması gerekiyor. Dolayısıyla aşağıdaki ayarlarda da herhangi bir gariplik yok. Yanılıyor muyum?
  /* Initialize QuadSPI ------------------------------------------------------ */
  QSPIHandle.Instance = QUADSPI;
  HAL_QSPI_DeInit(&QSPIHandle);
        
  /* ClockPrescaler set to 2, so QSPI clock = 216MHz / (2+1) = 72MHz */
  QSPIHandle.Init.ClockPrescaler     = 2;
  QSPIHandle.Init.FifoThreshold      = 4;
  QSPIHandle.Init.SampleShifting     = QSPI_SAMPLE_SHIFTING_HALFCYCLE;
  QSPIHandle.Init.FlashSize          = POSITION_VAL(0x1000000) - 1;
  QSPIHandle.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_2_CYCLE;
  QSPIHandle.Init.ClockMode          = QSPI_CLOCK_MODE_0;
  QSPIHandle.Init.FlashID            = QSPI_FLASH_ID_1;
  QSPIHandle.Init.DualFlash          = QSPI_DUALFLASH_DISABLE;
  
  if (HAL_QSPI_Init(&QSPIHandle) != HAL_OK)
  {
    Error_Handler();
  }

Burada da okuma ve yazma ilgili ayarlar mevcut.
  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 Reception buffer --------------------------------------- */
        for (index = 0; index < BUFFERSIZE; index++)
        {
          aRxBuffer[index] = 0;
        }

        /* 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 = QUAD_IN_FAST_PROG_CMD;
          sCommand.AddressMode = QSPI_ADDRESS_1_LINE;
          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_IT(&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_OUT_FAST_READ_CMD;
          sCommand.DummyCycles = DUMMY_CLOCK_CYCLES_READ_QUAD;

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

          if (HAL_QSPI_Receive_IT(&QSPIHandle, aRxBuffer) != HAL_OK)
          {
            Error_Handler();
          }
          step++;
        }
        break;
        
      case 5:
        if (RxCplt != 0)
        {
          RxCplt = 0;

          /* Result comparison ----------------------------------------------- */
          for (index = 0; index < BUFFERSIZE; index++)
          {
            if (aRxBuffer[index] != aTxBuffer[index])
            {
              Error_Handler();
            }
          }
          BSP_LED_On(LED1);

          address += QSPI_PAGE_SIZE;
          if(address >= QSPI_END_ADDR)
          {
            address = 0;
          }
          step = 0;
        }
        break;
        
      default :
        Error_Handler();
    }
  }

Aynı kodları denediğimde (Hem dahili hem harici kristal ile denedim. Ayrıca MCO1 pininden /4 olarak systemclock değerini görebiliyorum. 54 MHz.) okuma yapamıyorum. Init işlemlerinde falan herhangi bir sorun yaşanmıyor. Ancak flasha yazdıktan sonra okuma yaptığımda 0x99, 0x88 (bütün buffer) değerlerini alıyorum. ChipSelectHighTime = 2 iken 0x99, 6 iken 0x88 alıyorum.

Nerede hata yaptığımı bulamadım. Daha sonra BSP fonksiyonlarıyla denedim.
        memset(aRxBuffer, 0, BUFFERSIZE);

        BSP_QSPI_Erase_Block(address);

        BSP_QSPI_Write(aTxBuffer, address, sizeof(aTxBuffer));

        BSP_QSPI_Read(aRxBuffer, address, sizeof(aTxBuffer));

        address += QSPI_PAGE_SIZE;
        if(address >= QSPI_END_ADDR)
        {
            address = 0;
        }

        HAL_Delay(5000);

Değişen herhangi bir şey yok.

Disco ile benim kart arasındaki farklardan biri farklı flash entegreleri kullanıyoruz.

Kit üzerinde N25Q128A13EF840F-ND var, benim kart üzerinde W25Q128JVSIMTR var. Biraz baktım komut setleri birbirine oldukça benzer. Aynı diyebilirim.

Nasıl çözebilirim?
Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.

yldzelektronik

Sorunu çözdüm. İlk sorun, Disco üzerindeki ic ile benim kullandığım arasındaki bazı komutların farklı olması, diğeri komutların gönderilişleri farklı olması idi.
Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.

Mucit23

Çözmene sevindim  ::ok