STM32F429 SDRAM konusunda anlayamadıklarım

Başlatan Mucit23, 04 Şubat 2016, 01:14:42

F493

#15
Selam,

Bu tip kontrolleri fonksiyonların içine koymak lazım ki baş ağrıtmasın.

Şuan olayı bayagı anladın sanırım.  Bundan sonra donanım konusunda bayagı fikrin olmuştur. Bende kendi projemde şuan ana yazılım senaryo ile uğraşıyorum önümüzdeki günlerde Stemwin ile bir menu hazırlamam gerekecek, beni de o kısım düşündürüyor.

Esen kalın.

Mucit23

Elbette bilgim dahilinde ise neden olmasın.

Mucit23

Konuyu kapatmadan şu aklımdaki BUFFER_OFSET meselesinede cevap bulmak istiyorum. LCD ekranın SDRAM üzerinde nasıl bir hafıza düzeni var onu kafamda oturtmaya çalışıyorum.

BUFFER OFSET değeri 0x50000 olarak tanımlı . Yani desimal olarak  327680 sayısına denk geliyor.

Kütüphanenin orjinal LCD_Clear fonksiyonu aşağıdaki gibi .

  for (index = 0x00; index < BUFFER_OFFSET; index++)
  {
    *(__IO uint16_t*)(CurrentFrameBuffer + (2*index)) = Color;
  }


Buda benim yazdığım LCD_Clear Fonksiyonu
for(ram_counter=0;ram_counter<76800*2;ram_counter++)
{
    *(__IO uint16_t*) (CurrentFrameBuffer + ram_counter) = Color;
}


Orjinal kodda adres hesaplanırken index değeri neden 2 ile çarpılıyor bunu anlayamıyorum.
Yukarıdaki kodları yavaşlatıp çalıştırdığımda ekranın dolduruluş şeklinin aynı olduğunu görebiliyorum. Her bir pixel ramde ne kadar yer kaplıyor çözemedim. Varmı çözebilecek olan?

F493

Alıntı yapılan: Mucit23 - 06 Şubat 2016, 00:20:17
Varmı çözebilecek olan?

Çok cool  :) iddaalı.

CurrentFrameBuffer = 0xC000 0000 farz ediyorum
BUFFER OFFSET = 0X50000

CurrentFrameBuffer ile BUFFER OFFSET arası  Layer1 için ayrılmış olsun 
(CurrentFrameBuffer + BUFFER OFFSET)  ile 0xCFFF FFFF arası layer2 . 

Daha öncede bahsettiğim gibi 320*240 ekran için 153.6 KB alan gerekli.
for(ram_counter=0;ram_counter<76800*2;ram_counter++) // 76800*2 = 153.6 KB demektir.
{
    *(__IO uint16_t*) (CurrentFrameBuffer + ram_counter) = Color;
}


Üst satırdaki kod ile şimdi yazdığım aynı işi yapar,
for(ram_counter=0;ram_counter<76800;ram_counter++) 
{
    *(__IO uint16_t*) (CurrentFrameBuffer + (ram_counter *2) ) = Color;
}


Aslında doğru olan bu kod. ram_counter * 2 demek hep çift adres adımlarıyla arttırmak demek. Nedeni? Çünkü Color değişkeni 16bit. Döngü sonunda CurrentFrameBuffer + 153598 ileri gitmiş olacagız. Byte açısından böyle.

for (index = 0x00; index < BUFFER_OFFSET; index++)
  {
    *(__IO uint16_t*)(CurrentFrameBuffer + (2*index)) = Color;
  }

Bu kodda ise CurrentFrameBuffer ile (CurrentFrameBuffer + BUFFER_OFFSET) alanını çift adres adımlarıyla Layer2 yi temizliyor. İki işlemde aynı

76800*2 olan for döngüsünde  sadece 153.6 KB temizleniyor.
BUFFER_OFFSET degeri de byte cinsinden aslında 655Kb'lık alanı temizliyor. ( 2*index demek döngünün sonunda (BUFFER_OFFSET-1)*2 noktasına erişmek demek.)
Siz bu bilgiler ışığında kendi alanlarınızı yaratabilirsiniz. Örneğin,

#define _320_240_16BIT_FRAME_BUFFER_SIZE                   0X25800 // 153600 == 153.6KB
#define CAMERA_1_FRAME_BUFFER                             _320_240_16BIT_FRAME_BUFFER_SIZE
#define LCD_TEXT_FRAME_BUFFER                             (_320_240_16BIT_FRAME_BUFFER_SIZE*2)


Kullanımı
for(ram_counter=0;ram_counter < (_320_240_16BIT_FRAME_BUFFER_SIZE  / 2) ;ram_counter++) 
{
    *(__IO uint16_t*) (CurrentFrameBuffer + (ram_counter *2) ) = Color;
}

for(ram_counter=0;ram_counter < (_320_240_16BIT_FRAME_BUFFER_SIZE  / 2) ;ram_counter++) 
{
    *(__IO uint16_t*) (CurrentFrameBuffer + LCD_TEXT_FRAME_BUFFER   + (ram_counter *2) ) = Color;
}

Mucit23

Vakit ayırdığınız için teşekkürler. Şimdi debugda clear fonksiyonlarını inceledim.

Şimdi meseleyi anladım. Aslında dediğiniz gibi durum tamamen ST mühendislerinin böyle uygun görmesinden kaynaklanıyor.
Normalde her bir pixel 16 bit yer kapladığından ram counteri 2 şer 2 şer arttırmak gerekiyor. Debugda bunu gördüm. ram_couunterin her iki artışında bir pixel renk değiştiriyordu.

for (index = 0x00; index < BUFFER_OFFSET; index++)
  {
    *(__IO uint16_t*)(CurrentFrameBuffer + (2*index)) = Color;
  }

Bu kodda ise BUFFER_OFSET 0x50000 seçilmesi bence gereksiz. Öyle görünüyor çünkü normalde her bir frame 153kb yer kaplıyor hafızada yukarıdaki kod boş yere hafızadan 655kb alanı temizliyor. Bunun anlamak için for döngüsünün başlangıç değerini 76800 verdim ekranda hiçbir yer değişmedi. 76790 verdim sadece son 10 pixel renk değiştirdi.

Bu durum ilk başta çok soru işareti oluşturdu ama şimdi anladım. BUFFER_OFSET yerine orjinal kütüphanede 76800 yazdım ben. Daha hızlı çalışır.

Mucit23

Benzer bir soruyu STM32F7 Disco üzerindeki SDRAM için sorayım.

Kart üzerinde Micron MT48LC4M32B2 ram var
https://www.micron.com/~/media/documents/products/data-sheet/dram/128mb_x32_sdram.pdf

PDF'den anladığım kadarıyla toplam kapasite 128Mbyte. Ve Burada bit bazında değil bytle ile işlem yapılıyor.

STM32F7 üzerindeki SDRAM örneğinde boyut aşağıdaki gibi tanımlanmış

#define SDRAM_DEVICE_SIZE  ((uint32_t)0x800000)  /* SDRAM device size in MBytes */

desimal olarak 8388608 byte kullanıma hazır bir alan var.

128Mbyte alan için neden boyutu 0x800000 tanımlamışlar?

F493

Selam Mucit23,

SDRAM Boyutu 128 Mega Bit (byte değil)

Öncelikle   STM32F7 yazılım tarafındaki #define SDRAM_DEVICE_SIZE  ((uint32_t)0x800000)  /* SDRAM device size in MBytes */   ne anlama geliyor bir bakalım.
0x800000 -> 8388608 byte -> 8388608 / 1024 = 8192KB -> 8192KB / 1024 = 8Mbyte


Şimdi gelelim SDRAM'e,  128 Mega Bit  = 128 / 16bit = 8 Mega Byte

Yani her bir gözeneği 16bit olan 128Mega Bit'lik bu SDRAM 8Mega Byte alana sahipmiş.


Esen kalın.

Mucit23

Hocam teşekkürler anladım meseleyi. Ben aslında Mbyte olduğunu düşünmüştüm ilk başta. Mb=Mbit olacak. Kavram karışıklılığı

KingSlayyer

@F493 Sayın Hocam , @Mucit23 Sayın üstad, aradan 4 yıl geçmiş ama bir projem hakkında yardıma ihtiyacım var eğer mesajımı görürseniz yardımcı olabilir misiniz ?