29 Eylül 2020, 11:03:36

Haberler:

Picproje Facebook Sayfası:  https://bit.ly/2pUitll


STM32F750 QSPI Erişimi

Başlatan yldzelektronik, 18 Ağustos 2019, 15: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 0index BUFFERSIZEindex++)
        {
          
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, &sCommandHAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
          {
            
Error_Handler();
          }

          if (
HAL_QSPI_Transmit_IT(&QSPIHandleaTxBuffer) != 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, &sCommandHAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
          {
            
Error_Handler();
          }

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

          
/* Result comparison ----------------------------------------------- */
          
for (index 0index BUFFERSIZEindex++)
          {
            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(aRxBuffer0BUFFERSIZE);

        
BSP_QSPI_Erase_Block(address);

        
BSP_QSPI_Write(aTxBufferaddresssizeof(aTxBuffer));

        
BSP_QSPI_Read(aRxBufferaddresssizeof(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