Haberler:

Forum kuralları güncellendi LÜTFEN  okuyunuz:  https://bit.ly/2IjR3ME

Ana Menü

STM32F750 SDRAM Erişimi

Başlatan yldzelektronik, 20 Temmuz 2019, 17:36:41

yldzelektronik

Merhaba,

Stm32f750n8 ile MT48LC8M16A2TG-6A:LTR kullanarak yapılmış bir kartım var.

SDRAM ile ilgili ilk çalışmam. Bu yüzden temel şeyleri kaçırmadan ilerlemek istiyorum.

Kodda timing ile ilgili dikkat etmem gereken hususlar nelerdir? RAMden baştan sona veri yazıp okuma yapmak istiyorum. Böylece test etmiş olacağımı düşünüyorum. Yanılıyor muyum?

SDRAM datasheet te dikkat etmem gereken değerler nelerdir?

Cubemx'te yapmam gereken ayarlar nelerdir?

SDRAM1 bank 1 e bağlı.



Resimdeki alanları datasheet üzerinde bulmam gerekiyor.

SDRAMtiming in memory clock cycles olarak belirtilen alanı 16 seçtim. Ancak bu konuda datasheet te bir karışıklık var gibi geldi.Bu değeri datasheet içinde ne diye aramam gerekiyor?
Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.

yldzelektronik

#1

SDRAM ayarlarını STM32F750N Discovery kiti örnek uygulamadan referans alarak testlere başladım.

main fonksiyon örnekte şöyle (amaç sdram test etmek)
/**
  * @brief  Main program
  * @param  None
  * @retval None
  */
int main(void)
{
  /* Enable the CPU Cache */
  CPU_CACHE_Enable();
  
  /* STM32F7xx HAL library initialization:
      - Configure the Flash prefetch
      - 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
    */
  HAL_Init();

  /* Configure the system clock to 200 MHz */
  SystemClock_Config();
  
  /* Configure LED1 */
  BSP_LED_Init(LED1);

  /*##-1- Configure the SDRAM device #########################################*/
  /* SDRAM device configuration */
  hsdram.Instance = FMC_SDRAM_DEVICE;

  SDRAM_Timing.LoadToActiveDelay    = 2;
  SDRAM_Timing.ExitSelfRefreshDelay = 6;
  SDRAM_Timing.SelfRefreshTime      = 4;
  SDRAM_Timing.RowCycleDelay        = 6;
  SDRAM_Timing.WriteRecoveryTime    = 2;
  SDRAM_Timing.RPDelay              = 2;
  SDRAM_Timing.RCDDelay            = 2;

  hsdram.Init.SDBank            = FMC_SDRAM_BANK1;
  hsdram.Init.ColumnBitsNumber  = FMC_SDRAM_COLUMN_BITS_NUM_8;
  hsdram.Init.RowBitsNumber      = FMC_SDRAM_ROW_BITS_NUM_12;
  hsdram.Init.MemoryDataWidth    = SDRAM_MEMORY_WIDTH;
  hsdram.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;
  hsdram.Init.CASLatency        = FMC_SDRAM_CAS_LATENCY_2;
  hsdram.Init.WriteProtection    = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
  hsdram.Init.SDClockPeriod      = SDCLOCK_PERIOD;
  hsdram.Init.ReadBurst          = FMC_SDRAM_RBURST_ENABLE;
  hsdram.Init.ReadPipeDelay      = FMC_SDRAM_RPIPE_DELAY_0;

  /* Initialize the SDRAM controller */
  if(HAL_SDRAM_Init(&hsdram, &SDRAM_Timing) != HAL_OK)
  {
    /* Initialization Error */
    Error_Handler();
  }

  /* Program the SDRAM external device */
  BSP_SDRAM_Initialization_Sequence(&hsdram, &command);

  /*##-2- SDRAM memory read/write access #####################################*/

  /* Fill the buffer to write */
  Fill_Buffer(aTxBuffer, BUFFER_SIZE, 0xA244250F);

  /* Write data to the SDRAM memory */
  for (uwIndex = 0; uwIndex < BUFFER_SIZE; uwIndex++)
  {
    *(__IO uint32_t*) (SDRAM_BANK_ADDR + WRITE_READ_ADDR + 4*uwIndex) = aTxBuffer[uwIndex];
  }

  /* Read back data from the SDRAM memory */
  for (uwIndex = 0; uwIndex < BUFFER_SIZE; uwIndex++)
  {
    aRxBuffer[uwIndex] = *(__IO uint32_t*) (SDRAM_BANK_ADDR + WRITE_READ_ADDR + 4*uwIndex);
  }

  /*##-3- Checking data integrity ############################################*/

  for (uwIndex = 0; (uwIndex < BUFFER_SIZE) && (uwWriteReadStatus == 0); uwIndex++)
  {
    if (aRxBuffer[uwIndex] != aTxBuffer[uwIndex])
    {
      uwWriteReadStatus++;
    }
  }

  if (uwWriteReadStatus != PASSED)
  {
    while(1)
    {
      /* KO, Toggle LED1 with a period of 200 ms */
      BSP_LED_Toggle(LED1);
      HAL_Delay(200);
    }
  }
  else
  {
    /* OK, turn on LED1 */
    BSP_LED_On(LED1);
  }

  /* Infinite loop */
  while (1)
  {
  }
}

Benim main fonksiyon ise;

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */
  

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
//  MX_ADC1_Init();
//  MX_CRC_Init();
//  MX_I2C1_Init();
//  MX_I2C2_Init();
//  MX_QUADSPI_Init();
//  MX_RTC_Init();
//  MX_SDMMC1_SD_Init();
//  MX_SPI2_Init();
//  MX_TIM10_Init();
//  MX_USART1_UART_Init();
//  MX_DMA2D_Init();
  MX_FMC_Init();
//  MX_LTDC_Init();
//  MX_TIM6_Init();
  /* USER CODE BEGIN 2 */
  /* Program the SDRAM external device */
  BSP_SDRAM_Initialization_Sequence(&hsdram1, &command);

  /*##-2- SDRAM memory read/write access #####################################*/

  /* Fill the buffer to write */
  Fill_Buffer(aTxBuffer, BUFFER_SIZE, 0xaa55aa55/*0xA244250F*/);

  /* Write data to the SDRAM memory */
  uint32_t p;
  for (uwIndex = 0; uwIndex < BUFFER_SIZE; uwIndex++)
  {
    *(__IO uint32_t*) (SDRAM_BANK_ADDR + WRITE_READ_ADDR + 4 * uwIndex) = aTxBuffer[uwIndex];
  }

  /* Read back data from the SDRAM memory */
  for (uwIndex = 0; uwIndex < BUFFER_SIZE; uwIndex++)
  {
    aRxBuffer[uwIndex] = *(__IO uint32_t*) (SDRAM_BANK_ADDR + WRITE_READ_ADDR + 4 * uwIndex);
  }

  /*##-3- Checking data integrity ############################################*/

  for (uwIndex = 0; (uwIndex < BUFFER_SIZE) /*&& (uwWriteReadStatus == 0)*/; uwIndex++)
  {
    if (aRxBuffer[uwIndex] != aTxBuffer[uwIndex])
    {
      uwWriteReadStatus++;
 __BKPT(0);
    }
  }

  if (uwWriteReadStatus != PASSED)
  {
    while(1)
    {
      /* KO, Toggle LED1 with a period of 200 ms */
//      BSP_LED_Toggle(LED1);
      HAL_Delay(200);
    }
  }
  else
  {
    /* OK, turn on LED1 */
//    BSP_LED_On(LED1);
  }

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}
Ayrıca FMC_Init fonksiyonu;
/* FMC initialization function */
static void MX_FMC_Init(void)
{

  /* USER CODE BEGIN FMC_Init 0 */

  /* USER CODE END FMC_Init 0 */

  FMC_SDRAM_TimingTypeDef SdramTiming = {0};

  /* USER CODE BEGIN FMC_Init 1 */

  /* USER CODE END FMC_Init 1 */

  /** Perform the SDRAM1 memory initialization sequence
  */
  hsdram1.Instance = FMC_SDRAM_DEVICE;
  /* hsdram1.Init */
  hsdram1.Init.SDBank = FMC_SDRAM_BANK1;
  hsdram1.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_8;
  hsdram1.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_12;
  hsdram1.Init.MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_16;
  hsdram1.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;
  hsdram1.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_2;
  hsdram1.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
  hsdram1.Init.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_2;
  hsdram1.Init.ReadBurst = FMC_SDRAM_RBURST_ENABLE;
  hsdram1.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0;
  /* SdramTiming */
  SdramTiming.LoadToActiveDelay = 2;
  SdramTiming.ExitSelfRefreshDelay = 6;
  SdramTiming.SelfRefreshTime = 4;
  SdramTiming.RowCycleDelay = 6;
  SdramTiming.WriteRecoveryTime = 2;
  SdramTiming.RPDelay = 2;
  SdramTiming.RCDDelay = 2;

  if (HAL_SDRAM_Init(&hsdram1, &SdramTiming) != HAL_OK)
  {
    Error_Handler( );
  }

  /* USER CODE BEGIN FMC_Init 2 */

  /* USER CODE END FMC_Init 2 */
}
Yardımcı fonksiyonlar ise şöyle;
/**
  * @brief  Perform the SDRAM external memory initialization sequence
  * @param  hsdram: SDRAM handle
  * @param  Command: Pointer to SDRAM command structure
  * @retval None
  */
static void BSP_SDRAM_Initialization_Sequence(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_CommandTypeDef *Command)
{
  __IO uint32_t tmpmrd =0;
  /* Step 3:  Configure a clock configuration enable command */
  Command->CommandMode = FMC_SDRAM_CMD_CLK_ENABLE;
  Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
  Command->AutoRefreshNumber = 1;
  Command->ModeRegisterDefinition = 0;

  /* Send the command */
  HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);

  /* Step 4: Insert 100 us minimum delay */
  /* Inserted delay is equal to 1 ms due to systick time base unit (ms) */
  HAL_Delay(1);

  /* Step 5: Configure a PALL (precharge all) command */
  Command->CommandMode = FMC_SDRAM_CMD_PALL;
  Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
  Command->AutoRefreshNumber = 1;
  Command->ModeRegisterDefinition = 0;

  /* Send the command */
  HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);

  /* Step 6 : Configure a Auto-Refresh command */
  Command->CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
  Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
  Command->AutoRefreshNumber = 8;
  Command->ModeRegisterDefinition = 0;

  /* Send the command */
  HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);

  /* Step 7: Program the external memory mode register */
  tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1          |
                    SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL  |
                    SDRAM_MODEREG_CAS_LATENCY_2          |
                    SDRAM_MODEREG_OPERATING_MODE_STANDARD |
                    SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;

  Command->CommandMode = FMC_SDRAM_CMD_LOAD_MODE;
  Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
  Command->AutoRefreshNumber = 1;
  Command->ModeRegisterDefinition = tmpmrd;

  /* Send the command */
  HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);

  /* Step 8: Set the refresh rate counter */
  /* (15.62 us x Freq) - 20 */
  /* Set the device refresh counter */
  hsdram->Instance->SDRTR |= ((uint32_t)((1292)<< 1));

}

/**
  * @brief  Fills buffer with user predefined data.
  * @param  pBuffer: pointer on the buffer to fill
  * @param  uwBufferLenght: size of the buffer to fill
  * @param  uwOffset: first value to fill on the buffer
  * @retval None
  */
static void Fill_Buffer(uint32_t *pBuffer, uint32_t uwBufferLenght, uint32_t uwOffset)
{
  uint32_t tmpIndex = 0;

  /* Put in global buffer different values */
  for (tmpIndex = 0; tmpIndex < uwBufferLenght; tmpIndex++ )
  {
    pBuffer[tmpIndex] = tmpIndex + uwOffset;
  }
}

Değişkenler ve macrolar ise şöyle;
typedef enum {PASSED = 0, FAILED = !PASSED} TestStatus_t;

/* USER CODE END ET */

/* Exported constants --------------------------------------------------------*/
/* USER CODE BEGIN EC */
#define SDRAM_BANK_ADDR                ((uint32_t)0xC0000000)

/* #define SDRAM_MEMORY_WIDTH            FMC_SDRAM_MEM_BUS_WIDTH_8  */
#define SDRAM_MEMORY_WIDTH              FMC_SDRAM_MEM_BUS_WIDTH_16

#define SDCLOCK_PERIOD                  FMC_SDRAM_CLOCK_PERIOD_2
/* #define SDCLOCK_PERIOD                FMC_SDRAM_CLOCK_PERIOD_3 */

#define SDRAM_TIMEOUT    ((uint32_t)0xFFFF)

#define SDRAM_MODEREG_BURST_LENGTH_1            ((uint16_t)0x0000)
#define SDRAM_MODEREG_BURST_LENGTH_2            ((uint16_t)0x0001)
#define SDRAM_MODEREG_BURST_LENGTH_4            ((uint16_t)0x0002)
#define SDRAM_MODEREG_BURST_LENGTH_8            ((uint16_t)0x0004)
#define SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL      ((uint16_t)0x0000)
#define SDRAM_MODEREG_BURST_TYPE_INTERLEAVED    ((uint16_t)0x0008)
#define SDRAM_MODEREG_CAS_LATENCY_2              ((uint16_t)0x0020)
#define SDRAM_MODEREG_CAS_LATENCY_3              ((uint16_t)0x0030)
#define SDRAM_MODEREG_OPERATING_MODE_STANDARD    ((uint16_t)0x0000)
#define SDRAM_MODEREG_WRITEBURST_MODE_PROGRAMMED ((uint16_t)0x0000)
#define SDRAM_MODEREG_WRITEBURST_MODE_SINGLE    ((uint16_t)0x0200)


#define BUFFER_SIZE        ((uint32_t)0x1000)
#define WRITE_READ_ADDR    ((uint32_t)0x0000)
//#define WRITE_READ_ADDR    ((uint32_t)0x0800)

/* Read/Write Buffers */
uint32_t aTxBuffer[BUFFER_SIZE];
uint32_t aRxBuffer[BUFFER_SIZE];

/* Status variables */
__IO uint32_t uwWriteReadStatus = 0;

/* Counter index */
uint32_t uwIndex = 0;

FMC_SDRAM_CommandTypeDef command;

Sorun ise şu;

Yazdığım değerlerin aynısını okuyamıyorum. örnekteki kodda 0xA244250F değerini yazıyor. Başlangıç adresi de 0x0800. Bu şartlarda 0. adresten itibaren 0xA244250F yerine 0xA244210F olarak okuyor. Yazdığım değeri 0 olarak değiştirdim. Bu kez 1024. adresten itibaren 0 a dönüp arttığını görüyorum. Bu tarz bir sorunun sebebi ne olabilir?

Derdim bütün pinlerin sağlıklı şekilde bağlandığından emin olmak. MCU bga kılıf.

SDRAM başka nasıl test edilir? Nelerden emin olmam gerekiyor?
Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.

OptimusPrime

Datasheeti iyi oku derim.  ;) Soyle yuzeysel baktigimda ayarlarin yanlis gibi duruyor. Ben iki hata buldum mesela. CAS 2 write recovery 1 olmali   8-)
https://donanimveyazilim.wordpress.com || Cihân-ârâ cihân içredir ârâyı bilmezler, O mâhîler ki deryâ içredir deryâyı bilmezler ||

yldzelektronik

#3
Tekrar merhaba,

Uzun zamandır yazamadım yoğunluktan.

SDRAM ile ilgili ayarları tamamladım. Yararlandığım kaynak burada.

    hsdram1.Init.SDBank = FMC_SDRAM_BANK1;
    hsdram1.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_9;
    hsdram1.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_12;
    hsdram1.Init.MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_16;
    hsdram1.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;
    hsdram1.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_2;
    hsdram1.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
    hsdram1.Init.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_2;
    hsdram1.Init.ReadBurst = FMC_SDRAM_RBURST_ENABLE;
    hsdram1.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0;
    /* SdramTiming */
    SdramTiming.LoadToActiveDelay = 2;
    SdramTiming.ExitSelfRefreshDelay = 7;
    SdramTiming.SelfRefreshTime = 4;
    SdramTiming.RowCycleDelay = 6;
    SdramTiming.WriteRecoveryTime = 2;
    SdramTiming.RPDelay = 2;
    SdramTiming.RCDDelay = 2;

Test ettim ve herhangi bir sorun ile karşılaşmadım. Test yöntemi ise oldukça basit. RAM kapasitesi kadar alana bildiğim bir değeri yazıp o değeri okuyorum. Değer doğru ise sorun yoktur diyorum.

//#define BUFFER_SIZE        ((uint32_t)0x8000)
#define BUFFER_SIZE        ((uint32_t)0x400000)
#define WRITE_READ_ADDR    ((uint32_t)0x0000)
#define WRITE_VALUE ((uint32_t)0xA244250F)

//#define SDRAM_TEST
/* Status variables */
__IO uint32_t uwWriteReadStatus = 0;

/* Counter index */
uint32_t uwIndex = 0;

FMC_SDRAM_CommandTypeDef command;

#if defined(SDRAM_TEST)
/**
  * @brief  Perform the SDRAM external memory initialization sequence
  * @param  hsdram: SDRAM handle
  * @param  Command: Pointer to SDRAM command structure
  * @retval None
  */
static void BSP_SDRAM_Initialization_Sequence(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_CommandTypeDef *Command)
{
    __IO uint32_t tmpmrd = 0;
    /* Step 3:  Configure a clock configuration enable command */
    Command->CommandMode = FMC_SDRAM_CMD_CLK_ENABLE;
    Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
    Command->AutoRefreshNumber = 1;
    Command->ModeRegisterDefinition = 0;

    /* Send the command */
    HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);

    /* Step 4: Insert 100 us minimum delay */
    /* Inserted delay is equal to 1 ms due to systick time base unit (ms) */
    HAL_Delay(1);

    /* Step 5: Configure a PALL (precharge all) command */
    Command->CommandMode = FMC_SDRAM_CMD_PALL;
    Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
    Command->AutoRefreshNumber = 1;
    Command->ModeRegisterDefinition = 0;

    /* Send the command */
    HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);

    /* Step 6 : Configure a Auto-Refresh command */
    Command->CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
    Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
    Command->AutoRefreshNumber = 8;
    Command->ModeRegisterDefinition = 0;

    /* Send the command */
    HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);

    /* Step 7: Program the external memory mode register */
    tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1          |
            SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL  |
            SDRAM_MODEREG_CAS_LATENCY_2          |
            SDRAM_MODEREG_OPERATING_MODE_STANDARD |
            SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;

    Command->CommandMode = FMC_SDRAM_CMD_LOAD_MODE;
    Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
    Command->AutoRefreshNumber = 1;
    Command->ModeRegisterDefinition = tmpmrd;

    /* Send the command */
    HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);

    /* Step 8: Set the refresh rate counter */
    /* (15.62 us x Freq) - 20 */
    /* Set the device refresh counter */
    hsdram->Instance->SDRTR |= ((uint32_t)((1292) << 1));

}
//
#endif
#if defined(SDRAM_TEST)
    /* Program the SDRAM external device */
    BSP_SDRAM_Initialization_Sequence(&hsdram1, &command);

    /*##-2- SDRAM memory read/write access #####################################*/
    /* Write data to the SDRAM memory */
    for(uwIndex = 0; uwIndex < BUFFER_SIZE; uwIndex++)
    {
        *(__IO uint32_t *)(SDRAM_BANK_ADDR + WRITE_READ_ADDR + 4 * uwIndex) = WRITE_VALUE;
    }

    /*##-3- Checking data integrity ############################################*/
    for(uwIndex = 0; (uwIndex < BUFFER_SIZE) /*&& (uwWriteReadStatus == 0)*/; uwIndex++)
    {
        uint32_t value = *(__IO uint32_t *)(SDRAM_BANK_ADDR + WRITE_READ_ADDR + 4 * uwIndex);
        if(value != WRITE_VALUE)
        {
            uwWriteReadStatus++;
            __BKPT(0);
        }
    }

    if(uwWriteReadStatus != PASSED)
    {
        while(1)
        {
            HAL_Delay(200);
        }
    }
#endif

Debug ile kontrol ettiğimde yazdığım bütün alanı aynı değer ile okuyabiliyorum. Yazma ve okuma işlerini 32 bit olarak yapıyorum. Bir de byte olarak yapmam gerekir mi?

Şimdilerde LTDC donanımı ile biraz sıkıntı yaşıyorum. Kullandığım LCD kontrolcüsü şu.

İlgili ayarları şu şekilde yaptım:



    hltdc.Instance = LTDC;
    hltdc.Init.HSPolarity = LTDC_HSPOLARITY_AL;
    hltdc.Init.VSPolarity = LTDC_VSPOLARITY_AL;
    hltdc.Init.DEPolarity = LTDC_DEPOLARITY_AL;
    hltdc.Init.PCPolarity = LTDC_PCPOLARITY_IPC;
    hltdc.Init.HorizontalSync = 0;
    hltdc.Init.VerticalSync = 2;
    hltdc.Init.AccumulatedHBP = 46;
    hltdc.Init.AccumulatedVBP = 25;
    hltdc.Init.AccumulatedActiveW = 846;
    hltdc.Init.AccumulatedActiveH = 505;
    hltdc.Init.TotalWidth = 1056;
    hltdc.Init.TotalHeigh = 527;
    hltdc.Init.Backcolor.Blue = 0;
    hltdc.Init.Backcolor.Green = 255;
    hltdc.Init.Backcolor.Red = 0;
    if(HAL_LTDC_Init(&hltdc) != HAL_OK)
    {
        Error_Handler();
    }
    pLayerCfg.WindowX0 = 0;
    pLayerCfg.WindowX1 = 800;
    pLayerCfg.WindowY0 = 0;
    pLayerCfg.WindowY1 = 480;
    pLayerCfg.PixelFormat = LTDC_PIXEL_FORMAT_RGB888;
    pLayerCfg.Alpha = 255;
    pLayerCfg.Alpha0 = 0;
    pLayerCfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_PAxCA;
    pLayerCfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_PAxCA;
    pLayerCfg.FBStartAdress = 0;
    pLayerCfg.ImageWidth = 800;
    pLayerCfg.ImageHeight = 480;
    pLayerCfg.Backcolor.Blue = 0;
    pLayerCfg.Backcolor.Green = 255;
    pLayerCfg.Backcolor.Red = 0;
    if(HAL_LTDC_ConfigLayer(&hltdc, &pLayerCfg, 0) != HAL_OK)
    {
        Error_Handler();
    }

Aslında şuan herhangi bir layer ayarı yapmak istemiyorum. Yalnızca ekrana mavi, yeşil, kırmızı herhangi birini bastırsam şuan yeterli. Ekranın çalıştığını görmek istiyorum.

LTDC ayarlarını yaparken referans aldığım doküman ise AN4861

Aşağıda ekranın durumu var.


Referans aldığım dokümana göre;

PCLK (Pixel Clock) [Hz] = Total Heigh x Total Width x Refresh Rate
PCLK = 527 * 1056 * 60 = 33 390 720 Hz = 33,39072 MHz.

Bu değerlere göre PCL değerini hem 33,5 MHz olarak hem de 33,3333 MHz olarak ayarladım. Hatta denemek amacıyla 50 MHz olarak da denedim. Sonuç resimdeki gibi. Hiçbir değişiklik yok.
    RCC_OscInitTypeDef RCC_OscInitStruct = {0};
    RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
    RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};

    /** Configure LSE Drive Capability
    */
    HAL_PWR_EnableBkUpAccess();
    /** Configure the main internal regulator output voltage
    */
    __HAL_RCC_PWR_CLK_ENABLE();
    __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
    /** Initializes the CPU, AHB and APB busses clocks
    */
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_LSI;
    RCC_OscInitStruct.HSIState = RCC_HSI_ON;
    RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
    RCC_OscInitStruct.LSIState = RCC_LSI_ON;
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
    RCC_OscInitStruct.PLL.PLLM = 8;
    RCC_OscInitStruct.PLL.PLLN = 200;
    RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
    RCC_OscInitStruct.PLL.PLLQ = 8;
    if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
    {
        Error_Handler();
    }
    /** Activate the Over-Drive mode
    */
    if(HAL_PWREx_EnableOverDrive() != HAL_OK)
    {
        Error_Handler();
    }
    /** Initializes the CPU, AHB and APB busses clocks
    */
    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
                                  | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;

    if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_6) != HAL_OK)
    {
        Error_Handler();
    }
    PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LTDC | RCC_PERIPHCLK_RTC
            | RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_I2C1
            | RCC_PERIPHCLK_I2C2 | RCC_PERIPHCLK_SDMMC1
            | RCC_PERIPHCLK_CLK48;
    PeriphClkInitStruct.PLLSAI.PLLSAIN = 200;
    PeriphClkInitStruct.PLLSAI.PLLSAIR = 3;
    PeriphClkInitStruct.PLLSAI.PLLSAIQ = 2;
    PeriphClkInitStruct.PLLSAI.PLLSAIP = RCC_PLLSAIP_DIV2;
    PeriphClkInitStruct.PLLSAIDivQ = 1;
    PeriphClkInitStruct.PLLSAIDivR = RCC_PLLSAIDIVR_4;
    PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;
    PeriphClkInitStruct.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;
    PeriphClkInitStruct.I2c1ClockSelection = RCC_I2C1CLKSOURCE_PCLK1;
    PeriphClkInitStruct.I2c2ClockSelection = RCC_I2C2CLKSOURCE_PCLK1;
    PeriphClkInitStruct.Clk48ClockSelection = RCC_CLK48SOURCE_PLL;
    PeriphClkInitStruct.Sdmmc1ClockSelection = RCC_SDMMC1CLKSOURCE_CLK48;
    if(HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
    {
        Error_Handler();
    }

Bu arada Interrupt açmıştım ve durumu debug ile denediğimde 2 kez isr içine girdiğini gördüm. Callback ile baktığımda,
/**
  * @brief  Error LTDC callback.
  * @param  hltdc  pointer to a LTDC_HandleTypeDef structure that contains
  *                the configuration information for the LTDC.
  * @retval None
  */
void HAL_LTDC_ErrorCallback(LTDC_HandleTypeDef *hltdc)
{
 /* Prevent unused argument(s) compilation warning */
 UNUSED(hltdc);
 __BKPT(0);
 /* NOTE : This function should not be modified, when the callback is needed,
 the HAL_LTDC_ErrorCallback could be implemented in the user file
 */
}
//

/**
  * @brief  Line Event callback.
  * @param  hltdc  pointer to a LTDC_HandleTypeDef structure that contains
  *                the configuration information for the LTDC.
  * @retval None
  */
void HAL_LTDC_LineEventCallback(LTDC_HandleTypeDef *hltdc)
{
 /* Prevent unused argument(s) compilation warning */
 UNUSED(hltdc);
 __BKPT(0);
 /* NOTE : This function should not be modified, when the callback is needed,
 the HAL_LTDC_LineEventCallback could be implemented in the user file
 */
}
//

/**
  * @brief  Reload Event callback.
  * @param  hltdc  pointer to a LTDC_HandleTypeDef structure that contains
  *                the configuration information for the LTDC.
  * @retval None
  */
void HAL_LTDC_ReloadEventCallback(LTDC_HandleTypeDef *hltdc)
{
 /* Prevent unused argument(s) compilation warning */
 UNUSED(hltdc);
 __BKPT(0);
 /* NOTE : This function should not be modified, when the callback is needed,
 the HAL_LTDC_ReloadEvenCallback could be implemented in the user file
 */
}
//

HAL_LTDC_ERROR_TE /*!< LTDC Transfer error      */
HAL_LTDC_ERROR_FU /*!< LTDC FIFO Underrun        */

birer kez oluştuğunu gördüm.

HAL_LTDC_ErrorCallback
2 kez çağırıldığını gördüm ve yukarıdakilerden kaynaklandığını gördüm.

Sonuç olarak lcd yi sağlıklı bir şekilde nasıl çalıştırabilirim? Nerede hata yapıyorum acaba?
Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.

OptimusPrime

32 bit uygun fakat RAM testi o kadar basit degil  ;)

Tam anlamyila test etmek istiyorsan assagidaki gibi olmali. Buradan aldigin hatalari yorumlayarak nerede sorun oldugunu bulabilirsin.

- Sabit sayi ile hafizayi doldurmak (bu senin yaptigin)
- Artan ve azalan sayi ile hafizayi doldurmak
- Yuruyen 1 ve 0 lar ile hafizayi doldurmak

Bu testlerden sag salim cikmasi lazim.  ::ok

https://donanimveyazilim.wordpress.com || Cihân-ârâ cihân içredir ârâyı bilmezler, O mâhîler ki deryâ içredir deryâyı bilmezler ||

serdararikan


MC_Skywalker

RAM testi için Memtest86 programını örnek alabilirsiniz.

yldzelektronik

Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.

yldzelektronik

@OptimusPrime @MC_Skywalker aslında ram testindeki gayem bga kılıf doğru dürüst lehimlenmiş mi ondan emin olmak  :)

Memtest86 ya çok kısa baktım. Baya detaylı imiş. Öyle bir test gerekli mi bilmiyorum ama fena olmaz sanki.

@OptimusPrime ın bahsettiği yöntemi ileride uygulayabilirim. Şimdilik kalsın diyorum.

Şuan önceliğim LTDC ve QSPI ile ilgili sıkıntıları çözmek.
Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.

OptimusPrime

O zaman en azindan yuruyen 1 denemelisin.  ::ok
https://donanimveyazilim.wordpress.com || Cihân-ârâ cihân içredir ârâyı bilmezler, O mâhîler ki deryâ içredir deryâyı bilmezler ||

yldzelektronik

Alıntı yapılan: OptimusPrime - 16 Ağustos 2019, 16:32:16O zaman en azindan yuruyen 1 denemelisin.  ::ok

Yürüyen derken hocam? Biraz açar mısınız?
Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.

OptimusPrime

adres = 0x0000_0000, patern = 0x0000_0001
adres = 0x0000_0004, patern = 0x0000_0010
adres = 0x0000_0008, patern = 0x0000_0100
adres = 0x0000_000C, patern = 0x0000_1000
adres = 0x0000_0010, patern = 0x0001_0000
adres = 0x0000_0014, patern = 0x0010_0000
adres = 0x0000_001C, patern = 0x0100_0000
adres = 0x0000_0020, patern = 0x1000_0000

gibi. Herbir baglantiyi ayri ayri test etmis olursun. Bunun aynisini adres bitlerinede uygulayabilirsin.
https://donanimveyazilim.wordpress.com || Cihân-ârâ cihân içredir ârâyı bilmezler, O mâhîler ki deryâ içredir deryâyı bilmezler ||

yldzelektronik

LCD ile ilgili sorunum halen devam etmekte.Şöyle bir gelişme var:

STM32F7508-DISCO LTDC_PicturesFromSDCard örneğini kendi kartıma uyarladım. SD carddan resim okuyup yazmayı deniyorum. Ancak başarılı olamıyorum. SD card okunuyor. Sorun yok.

Ekranda gördüğüm ise: https://www.youtube.com/watch?v=cxayA_-Zh34

LCD Init kodları:
/**
  * @brief  Initializes the LTDC MSP.
  * @param  hltdc: LTDC handle
  * @param  Params
  * @retval None
  */
__weak void BSP_LCD_MspInit(LTDC_HandleTypeDef *hltdc, void *Params)
{
    GPIO_InitTypeDef GPIO_InitStruct;

    /* Enable the LTDC and DMA2D clocks */
    __HAL_RCC_LTDC_CLK_ENABLE();
    __HAL_RCC_DMA2D_CLK_ENABLE();

    /* Enable GPIOs clock */
	BSP_GPIOCLK_Enable();
    LCD_DISP_GPIO_CLK_ENABLE();
    LCD_BL_CTRL_GPIO_CLK_ENABLE();

    /*** LTDC Pins configuration ***/
	/**LTDC GPIO Configuration    
    PG11     ------> LTDC_B3
    PJ13     ------> LTDC_B1
    PJ12     ------> LTDC_B0
    PK7     ------> LTDC_DE
    PK6     ------> LTDC_B7
    PK5     ------> LTDC_B6
    PG12     ------> LTDC_B4
    PJ14     ------> LTDC_B2
    PI10     ------> LTDC_HSYNC
    PK4     ------> LTDC_B5
    PI9     ------> LTDC_VSYNC
    PK1     ------> LTDC_G6
    PK2     ------> LTDC_G7
    PI15     ------> LTDC_R0
    PJ11     ------> LTDC_G4
    PK0     ------> LTDC_G5
    PI14     ------> LTDC_CLK
    PJ8     ------> LTDC_G1
    PJ10     ------> LTDC_G3
    PJ7     ------> LTDC_G0
    PJ9     ------> LTDC_G2
    PJ6     ------> LTDC_R7
    PJ4     ------> LTDC_R5
    PJ5     ------> LTDC_R6
    PJ3     ------> LTDC_R4
    PJ2     ------> LTDC_R3
    PJ0     ------> LTDC_R1
    PJ1     ------> LTDC_R2 
    */
    GPIO_InitStruct.Pin 		= GPIO_PIN_11;
    GPIO_InitStruct.Pull 		= GPIO_NOPULL;
    GPIO_InitStruct.Alternate 	= GPIO_AF14_LTDC;
    GPIO_InitStruct.Mode 		= GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed 		= GPIO_SPEED_FREQ_VERY_HIGH;
    HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);

	GPIO_InitStruct.Pin 		= GPIO_PIN_13	| GPIO_PIN_12	| GPIO_PIN_14	|GPIO_PIN_11 |
								  GPIO_PIN_8	| GPIO_PIN_10	| GPIO_PIN_7	|GPIO_PIN_9  |
								  GPIO_PIN_6	| GPIO_PIN_4	| GPIO_PIN_5	|GPIO_PIN_3  |
								  GPIO_PIN_2	| GPIO_PIN_0	| GPIO_PIN_1;
    GPIO_InitStruct.Pull 		= GPIO_NOPULL;
    GPIO_InitStruct.Alternate 	= GPIO_AF14_LTDC;
    GPIO_InitStruct.Mode 		= GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed 		= GPIO_SPEED_FREQ_VERY_HIGH;
    HAL_GPIO_Init(GPIOJ, &GPIO_InitStruct);

    GPIO_InitStruct.Pin 		= GPIO_PIN_7	| GPIO_PIN_6 	| GPIO_PIN_5	| GPIO_PIN_4  |
								  GPIO_PIN_1	| GPIO_PIN_2	| GPIO_PIN_0;
    GPIO_InitStruct.Pull 		= GPIO_NOPULL;
    GPIO_InitStruct.Alternate 	= GPIO_AF14_LTDC;
    GPIO_InitStruct.Mode 		= GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed 		= GPIO_SPEED_FREQ_VERY_HIGH;
    HAL_GPIO_Init(GPIOK, &GPIO_InitStruct);

    GPIO_InitStruct.Pin 		= GPIO_PIN_12;
    GPIO_InitStruct.Pull 		= GPIO_NOPULL;
    GPIO_InitStruct.Alternate 	= GPIO_AF9_LTDC;
    GPIO_InitStruct.Mode 		= GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed 		= GPIO_SPEED_FREQ_VERY_HIGH;
    HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);

    GPIO_InitStruct.Pin 		= GPIO_PIN_10 	| GPIO_PIN_9	| GPIO_PIN_15	| GPIO_PIN_14;
    GPIO_InitStruct.Pull 		= GPIO_NOPULL;
    GPIO_InitStruct.Alternate	= GPIO_AF14_LTDC;
    GPIO_InitStruct.Mode 		= GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed 		= GPIO_SPEED_FREQ_VERY_HIGH;
    HAL_GPIO_Init(GPIOI, &GPIO_InitStruct);
	
    /* LCD_DISP GPIO configuration */
    GPIO_InitStruct.Pin       	= LCD_DISP_PIN;     /* LCD_DISP pin has to be manually controlled */
    GPIO_InitStruct.Mode      	= GPIO_MODE_OUTPUT_PP;
    HAL_GPIO_Init(LCD_DISP_GPIO_PORT, &GPIO_InitStruct);

    /** TIM10 GPIO Configuration PF6     ------> TIM10_CH1 */
    GPIO_InitStruct.Pin 		= LCD_BL_CTL_Pin;
    GPIO_InitStruct.Pull 		= GPIO_NOPULL;
    GPIO_InitStruct.Alternate	= GPIO_AF3_TIM10;
    GPIO_InitStruct.Mode 		= GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed 		= GPIO_SPEED_FREQ_VERY_HIGH;
    HAL_GPIO_Init(LCD_BL_CTL_GPIO_Port, &GPIO_InitStruct);
}
//

uint8_t BSP_LCD_Init(void)
{
    /* Select the used LCD */

    /* The HX8264 LCD 800x480 is selected */
    /* Timing Configuration */
    hLtdcHandler.Init.HorizontalSync 		= (HX8264_HSYNC - 1);
    hLtdcHandler.Init.VerticalSync 			= (HX8264_VSYNC - 1);
    hLtdcHandler.Init.AccumulatedHBP 		= (HX8264_HSYNC + HX8264_HBP - 1);
    hLtdcHandler.Init.AccumulatedVBP 		= (HX8264_VSYNC + HX8264_VBP - 1);
    hLtdcHandler.Init.AccumulatedActiveW 	= (HX8264_WIDTH + HX8264_HSYNC + HX8264_HBP - 1);
    hLtdcHandler.Init.AccumulatedActiveH 	= (HX8264_HEIGHT + HX8264_VSYNC + HX8264_VBP - 1);
    hLtdcHandler.Init.TotalHeigh 			= (HX8264_HEIGHT + HX8264_VSYNC + HX8264_VBP + HX8264_VFP - 1);
    hLtdcHandler.Init.TotalWidth 			= (HX8264_WIDTH + HX8264_HSYNC + HX8264_HBP + HX8264_HFP - 1);

    /* LCD clock configuration */
    BSP_LCD_ClockConfig(&hLtdcHandler, NULL);

    /* Initialize the LCD pixel width and pixel height */
    hLtdcHandler.LayerCfg->ImageWidth  = HX8264_WIDTH;
    hLtdcHandler.LayerCfg->ImageHeight = HX8264_HEIGHT;

    /* Background value */
    hLtdcHandler.Init.Backcolor.Blue = 0;
    hLtdcHandler.Init.Backcolor.Green = 0;
    hLtdcHandler.Init.Backcolor.Red = 0;

    /* Polarity */
    hLtdcHandler.Init.HSPolarity = LTDC_HSPOLARITY_AL;
    hLtdcHandler.Init.VSPolarity = LTDC_VSPOLARITY_AL;
    hLtdcHandler.Init.DEPolarity = LTDC_DEPOLARITY_AL;
    hLtdcHandler.Init.PCPolarity = LTDC_PCPOLARITY_IPC;
    hLtdcHandler.Instance = LTDC;

    if(HAL_LTDC_GetState(&hLtdcHandler) == HAL_LTDC_STATE_RESET)
    {
        /* Initialize the LCD Msp: this __weak function can be rewritten by the application */
        BSP_LCD_MspInit(&hLtdcHandler, NULL);
    }
    HAL_LTDC_Init(&hLtdcHandler);

    /* Assert display enable LCD_DISP pin */
    HAL_GPIO_WritePin(LCD_DISP_GPIO_PORT, LCD_DISP_PIN, GPIO_PIN_SET);

    /* Assert backlight LCD_BL_CTRL pin */
	Init_BacklightPWM();
	

#if !defined(DATA_IN_ExtSDRAM)
    /* Initialize the SDRAM */
    BSP_SDRAM_Init();
#endif

    /* Initialize the font */
    BSP_LCD_SetFont(&LCD_DEFAULT_FONT);

    return LCD_OK;
}

Sorunun rgb ayarlarıyla ilgili olduğunu sanıyorum. Mesela ekranın ortasına yazı yazdırmak istediğimde ekranın ortasında bir kargaşa oluştuğunu görüyorum. Ama renkler birbirine girmiş.

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.

Mucit23

Hocam temel olarak ilk önce rgb datası ile test etmek gerekir. Ben olsaydım ilk olarak ram alanını 32bit ARGB Değerleri ile doldurup ekranda RGB testi yapardım. Bu çok önemli eğer bu aşamayı geçemiyorsanız resim basmaya felan uğraşma. Bence sen bunu düzgün yapamıyorsun.

LTDC yi bende çok iyi bilmiyorum. O yüzden net birşey diyemiyorum.

OptimusPrime

Sonuca bakarak birsey demek zor. Sanki yatay pixel i fazla veriyorsun gibide duruyor. Ama olmayadabilir. En güzeli özellikle vsync hsync i scope ile gozleyip bilinen bir data göndermen. Bu sana nerede hata olduğuna dair fikir verecektir.
https://donanimveyazilim.wordpress.com || Cihân-ârâ cihân içredir ârâyı bilmezler, O mâhîler ki deryâ içredir deryâyı bilmezler ||