STM32F4 FatFS Bitmap Resim Basmada hız sorunu

Başlatan Mucit23, 22 Şubat 2018, 23:49:55

Zoroaster


SD kartta sektorler 512 Byte. (Yenilerde daha uzun)

Eger herhangi bir sektore gelip baslangic adresini relatif 0 yapip 512 Byte oku dersen sorunsuz okursun.

Fakat sektor icinde ilerleyip ornegin relatif start adresi 0x001 deyip 512 byte oku dersen 512 byte okuyamazsin. Cunku 511 byte var ve 1 byte'i bir sonraki sektorden okuman gerekir.

Yuksek seviyel rutinler bu konuya dikkat eder. Ama Dusuk seviyeli kodlarda bu sorun olusturur.

Seytan deliginden kacti.

RaMu

#16
SDSC (2GB ye kadar kartlar) ve SDHC(2~32GB arası) ve
SDXC(32GB üstü) denen kart tipleri var,
şuan piyasadaki birçok kart SDHC,
SDHC ve SDXC(ayarlanabilir) kartlarda 1 Sektör 512 byte,
ve ancak ve ancak sektör adresi ile okuma yapmak mümkün yani
byte okuma yapılamaz,
byte 58 okunacaksa
sektor başlangıcına gidilip 58 boş byte okunuyor,
bunuda zaten f_lseek fonksiyonu hallediyor anlaşılan.

Aslında iki tane okuma komutu var SD kart için,
sıralı okuma(CMD18) ve normal(CMD17) okuma,
normal okuma komutu ve okunacak adres SD karta gönderildikten sonra
SD karta 514 Clock uygulanıp (SPI mod için konuşursak)
512 byte data ve 2 byte CRC alınıyor,
sonrasında yine okuma komutu ve okunacak adres gönderilmesi gerekiyor,
Sıralı okuma komutu ve okuma başlangıç adresi gönderilirse,
ben megabytelarca veri okuyorum,
512 byte data ve 2 byte crc şeklinde sadece Clock vererek sıralı okuma yapılıyor.

Yani f_read fonksiyonunu bir şekilde
CMD18 sıralı okuma komutunu kullanmasını sağlamak lazım.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

Mucit23

Peki nasıl bir yöntem izlemek gerekir? Sıralı okuma yaparken CRC ve sektör hesaplarını benmi yapacağım?
Ikinci olarak incelediğim örneklerde bu tür kontroller yapılmıyordu. Ilk basta f_lseek ile bmp başlangıcına gidilip her seferinde 3 byte olmak üzere sıra sıra okuma yapılıyordu. Bunu bende denedim çalışıyordu.  O zaman sektör vs gibi kontroller yapılmıyordu.

OptimusPrime

Simdi bayt bayt da okuyamiyorum diyorsun eskiden okuyordun.!

Seri okuma işini cozemezssen kendin bir ust seviye fonksiyon yazip ne kadar veri okuduguna bakarak rgb dizisini sen kendin doldurursun. Mesela 400 tane okuyabildin 500 tane kaldı. Kalan kisim icin gerekli duzenlemeyi yap yine çağır vs vs tabi seri okumadan daha yavas kalacak bu kısım. Son çare olarak düşünülebilir.
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 ||

Mucit23

Byte byte okuyorum ama nedense ekrana gönderirken problem oluyor. Henüz tam çözemedim. Onu bir şekilde hallederim. Fakat bu f_read işi bana cok mantıksız geliyor. Fatfs de benim dosya okurken bu tür işlerle uğraşmamam lazım. 
Burada Elm Chan Amcanın bir örneği var.
http://elm-chan.org/fsw/ff/doc/open.html

Tek seferde 4k veri okumuş. Dosya kopyalama işlemi yapmış.

Acaba Fatfs sürümü ile ilgili olabilirmi? Yada Kütüphaneden kaynaklı bir problem?


baran123

Bu iş banada çok saçma geldi FatFs gibi üst seviye bir kütüphane neden bunu yapmıyor anlamadım.
Şimdi dikkatimi çekti

ffconf.h dosyasının içeriğinde şöyle bir bölüm var.
#define	_MIN_SS		512
#define	_MAX_SS		512
/* These options configure the range of sector size to be supported. (512, 1024,
/  2048 or 4096) Always set both 512 for most systems, all type of memory cards and
/  harddisk. But a larger value may be required for on-board flash memory and some
/  type of optical media. When _MAX_SS is larger than _MIN_SS, FatFs is configured
/  to variable sector size and GET_SECTOR_SIZE command must be implemented to the
/  disk_ioctl() function. */

Zoroaster

Yapiyordur yapmiyorsa da sen kucuk bir rutin yaziver.

Seytan deliginden kacti.

RaMu

#22
mmc_*****.c kütüphanesinde
disk_read fonksiyonunda sıralı okuma komutunu kullanmış
send_cmd(CMD18, sector) 	/* READ_MULTIPLE_BLOCK */

Dosyanın başlangıç sektörü "sector" adresi bilgisini elde edebilirsen,
ve dosya boyutu bilgisinide elde edebilirsen,
sende bu fonksiyonu kullanıp,
dosya sonuna kadar ardışık okuma yapabilirsin;
kısaca
send_cmd(CMD18, sector);  //ardışık okumayı başlatmak için 1 defa bu komutu gönderiyoruz

for(i=0;i<dosya_boyutu_byte;i++)
{
siradaki_byte = spi_readFOKSİYONU;
geleni nereye göndermek istiyorsan....
if(++c>=512) {2 byte spi boş oku CRC için,c=0;}
}




Veya mmc_*****.c içindeki, disk_read fonksiyonunun şu kısmını
if (send_cmd(CMD18, sector) == 0) {	/* READ_MULTIPLE_BLOCK */
			do {
				if (!rcvr_datablock(buff, 512)) break;
				buff += 512;
			} while (--count);
			send_cmd(CMD12, 0);				/* STOP_TRANSMISSION */
		}


şu şekilde değiştirirsen
if (send_cmd(CMD18, sector) == 0) {	/* READ_MULTIPLE_BLOCK */
			do {
				if (!rcvr_datablock(buff, 512)) break;
				buff += 512;
			} while (--count);
if(ardışık_okuma!=1)  //ardışık kuma yapılacaksa okuma sonlandırma komutunu işleme
			send_cmd(CMD12, 0);				/* STOP_TRANSMISSION */
		}


Sonra yukarıdakinin benzeri şekilde
dosyayı buldun, açtın, header kısmını okumak için son hamleni yapmadan hemen önce
ardışık_okuma=1;
f_read fonksiyonuyla header oku,
sonrasını şu şekilde hallet,
for(i=0;i<dosya_boyutu_byte;i++)
{
siradaki_byte = spi_readFOKSİYONU;
geleni nereye göndermek istiyorsan....
if(++c>=512) {2 byte spi boş oku CRC için,c=0;}
}

işin bitince normale dönmek için
ardışık_okuma = 0; yaparsın.

Biraz tehlikeli olabilir ama genel olarak bir sorun yok gibi göründü bana.7

Yinede kütüphane orjinalinde 512 den büyük okuyabilirmiş gibi gözüküyor.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

Mucit23

#23
@RaMu FatFS'ye bu şekilde girişmeden önce sorunu net olarak anlayabilmem lazım. f_read fonksiyonunun bitmap basılırken ne zaman FR_DISK_ERROR ile döndüğünü anlayabilmek için aşağıdaki test fonksiyonunu kullanıyorum.

    if (f_mount(0, &FatFs) == FR_OK) {

        if(f_open(&fil, "test.bmp", FA_READ) == FR_OK) {
            
					  f_read(&fil, hdr, sizeof(hdr), &bytesread);
					  BMP.Offset = *((uint32_t *)&hdr[0x0A]);
					
					  BMP.FileSize = *((uint32_t *)&hdr[0x02]); 

		     	  BMP.Width = *((uint32_t *)&hdr[0x12]);

			      BMP.Height = *((uint32_t *)&hdr[0x16]); 
					
			        f_lseek(&fil, BMP.Offset);
							 LCD_SetCursor(0,0);
               for (i = 0; i < 240; i++)
               {
                  for (j = 0; j < 320; j++)
                  {
									  f_result=f_read(&fil, &rgb, 3, &bytesread);
										if(f_result!=FR_OK)FR_print_error(f_result,i*j);
										*(__IO uint16_t *) (Bank1_LCD_D) = ASSEMBLE_RGB(rgb[0],rgb[1],rgb[2]);
										for(d=0;d<5;d++);
                  }
               }     			
            f_close(&fil);
        }
				else
				{
				  LCD_DisplayStringLine(0,0,"Dosya Acma Hatasi!!");  
				}
        
    }	
		else
		{
		        LCD_DisplayStringLine(0,0,"SD Mount Error!!");
		}


Şuanda  ard arda 3 byte okurken bile problem yaşanıyor rgb dizisi 3 byte dan oluşan uint8_t türünde bir dizi Her pixelde bunu okuyup RGB565'e çevirip LCD'ye gönderiyorum. Eğer f_read fonksiyonu bu FR_OK ile dönmezse döngüden çıkıp döngünün o anki değerini ekrana yazdırıyorum. Öyleki Bazen 1000 seferde, bazen 1800 de bazende 800'de hata düşüyor. Her seferinde FatFS farklı zamanda hataya düşüyor. Çıkamadım işin içinden.

Sorun Fat32, Fat16'da değil. Çünkü İkisinde de Normal olarak okuma yapabiliyorum.

LCD ile ilgilide problem yok. Resim Datalarını Program hafızasına yükleyip basabiliyorum. Problem olmuyor.

OptimusPrime

Donanimsal bir problem de var gibi. Scope ile sd kartin pinlerine baktin mi ve beslemesinede
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 ||

RaMu

Yüksek hızda daha öncede söylediğim gibi
benide avlayan besleme olmuştu.
SD kart beslemesini STkit üzerinden alma,
güç kaynağı yoksa bile başka bir usb porttan
3.3V alacak bir şeyler yap.

Birde wdt felan yok demi.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

Mucit23

Beslemeyi skop ile görüntülemedim. Fakat En son Harici LDO bağladıktan sonra mutimetre ile LDO çıkış gerilimini ölçtüm. 3,31V civarıydı. Bunun dışında problem olması muhtemel konular nelerdir.

Ben bağlantıları Delikli pertinax üzerine kablo lehimleyerek yaptım. PCB vs tasarlamadım. SD-STM32 arasındaki kablo uzunlukları 10cm civarı. Bunun dışında dikkat etmem gereken birşey varmı donanımda?

SD kart ile ilgilide olabilir emin değilim. 2GB sd ile deniyorum. 4GB ve 8GB SD kart deneyip okuma yapacağım.

Birde şunu sorayım. FatFS nin yeni sürümlerini kullanmak faydalı olabilirmi. En son R0.13a çıkmış, Bendeki ise R0.11 versiyonu.

RaMu

Program hataya düşerken besleme ne oluyor diye
skopla bakmak doğru sonuç verir,
mültimetre ile ölçmenin bir manası yok.


10cm biraz uzun olabilir, pull up ları 4k7
veya 1k ya kadar düşürmen gerekebilir.


Ben kullanmadım ama sürüm değiştikçe hataları düzeltiyorlar,
faydası olur muhakkak.


Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

Mucit23

Evet Donanımda da kesinlikle problem var. Bu tür Yüksek frekans ile haberleşen sistemlerde dikkatli davranmak gerekiyor. Sorunum hala tam olarak çözülmedi ama anlamsız FR_DISK_ERROR lardan kurtuldum gibi.

Pull-up dirençlerini 4.7k yaptım. Besleme yine STM32F4 Discovery üzerinden yapılıyor ama STM32F4 ile SD kart arasındaki GND bağlantı noktalarını arttırdım. Aynı Zamanda SDIO Clock frekansını biraz düşürdüm. Önceden 12Mhz civarıydı. Şuanda 4.8Mhz civarı. Bu şekilde biraz iyileşme oldu. Tam olarak çözülmedi ama FR_Disk_Error artık almıyorum. 3'er byte pixel datası okuyarak BMP resmi problemsiz basıyorum.

Yüksek boyutlu okuma işi hala aklımda o konuda uğraşım devam ediyor. Aslında bugün aklıma geldi Bu STM32F4'de usb otg desteği vardı. USB OTG ile USB Bellek üzerinden FatFS ile BMP dataları okumak istiyorum. O zaman f_read ile sektör sınırı yaşamam herhalde.

Böyle bir örneğe rastlayan oldumu? Çok mu zor bir iş?