FatFs Dosya Okuma ve Buffer Problemi

Başlatan kimlenbu, 14 Mart 2014, 12:41:37

kimlenbu

Selamlar,

SSD1963 sürücülü 7" ekranda SD karttan okunan bir fotoğrafı göstermeye çalışıyorum. elm-chan'ın FatFS kütüphanesini kullanıyorum.

fotograf verisini karta rgb565 formatinda binary olarak atıyorum. buffer boyutunu 512-2048 aralığında değiştiriyorum. yazdığım program sadece ilk okumada buffer kadarlık bir veriyi ekranda düzgün gösteriyor ondan sonra ise random renkler gösteriliyor.

Hatam nedir ? bildiğim kadarıyla f_read fonksiyonu her çalışmasından sonra dosya konumunu kendisi öteliyor. Dosya konumunu kendim ayarladığımda gene de değişiklik olmadı.

göstermek istediğim resim şu : (100x100)px



2048 byte'lık buffer kullandığımda ekrandaki görüntü şu :



ilgili kod parçası :

void SSD1963_LCD_SDBMP(uint16_t x,uint16_t y,uint16_t w,uint16_t h,const TCHAR *fname)
{       

  volatile uint32_t index;
  volatile uint32_t size = (w * h);
//volatile uint32_t OkumaSayisi = (w * h * 2)/512;
//volatile uint32_t Okuma=0;
  uint16_t *bitmap_ptr =  (uint16_t*)buffer;
//   uint16_t i;
   

	LCD_WriteCommand(0x002A);	
	LCD_WriteData(x>>8);	    
	LCD_WriteData(x&0x00ff);
	LCD_WriteData((x+w-1)>>8);	    
	LCD_WriteData((x+w-1)&0x00ff);
  LCD_WriteCommand(0x002b);	
	LCD_WriteData(y>>8);	    
	LCD_WriteData(y&0x00ff);
	LCD_WriteData((y+h-1)>>8);	    
	LCD_WriteData((y+h-1)&0x00ff);
	LCD_WriteCommand(0x002c);
	
	
	res=f_open(&fsrc, fname, FA_READ);
			do
				{
	// 			res = f_lseek(&fsrc, 2048*Okuma); Bu satir olsa da olmasa da sonuc ayni
				res=f_read(&fsrc,buffer,sizeof(buffer),&br);
				Okuma++;
				
				for(index =0; index < br; index++)
				{
				LCD_WriteData(*bitmap_ptr++);
				}
			}while(br>=sizeof(buffer));
	
	f_close(&fsrc);
}

ErsinErce

f_read(&src,buffer,4096,&totalbyte);
f_sync(&src);


şeklinde loop'a sokmuşum çalışan bir uygulamamda

atomx

Şöyle birsey olabilir belki

char buffer[resimgenisligi*3];

f_lseek ile bitmap header okunur 54 galiba

Daha sonra

Lcdwindowarea x,y,genislik,yukseklik
Lcdposition x,y
Lcd->register = 0x0022;

For(int i =0; i < resimyuksekligi; i++)
{
f_read(&buffer, resimgenisligi*3, &byteread);

For(int j =0; j < resimgenisligi*3; j++)
{
Kirmizi=buffer[j*3+2];
Yesil = buffer[j*3+1];
Mavi=buffer[j*3];

Lcd->ram = rgbto565(kirmizi, yesil, mavi);
}
}

Pek aciklayici olmadi ama is gorebilir.

Hüseyin TECER

kimlenbu

@ErsinErce, ne yazık ki bende hala okumuyor.

@atomx, dediğini anladım, 565 formatında her pixel 2byte ile ifade ediliyor. Amacın her satır bilgisini tek tek okutmak ama dediğin şekilde yapıca da sadece ilk satıra ait pixelleri basıp kalıyor.

atomx

Hüseyin TECER

kimlenbu

#5
f_read fonksiyonunda bir gariplik var, okunan değerleri başka bir dosyaya kaydettirdim. sonuç :

1. Okuma ) Buffer kadar değeri doğru okuyor
2. Okuma ) Buffer kadar 0 okuyor
3. Okuma ) 2. Okumada olması gereken değerlerleri okuyor.
4. Okuma ) Buffer kadar 0 okuyor.
....

özetle çift sayılı okumalarda hep 0 okuyorum.

çift okumaları başka buffer'a yaptım olmadı, çift okumaları yapıp ekrana göndertmedim olmadı, dosyayı her okuyuşta açıp f_lseek ile konumlandırdım ve kapattıp olmadı. Aklıma daha da bir şey gelmiyor.

edit : @atomx, kodlar için teşekkür ederim, inceledim ama işime yarayabilecek bir fikir vermedi. nispeten hızlı olsun diye 24 bit bmp yerine direkt rgb565 olarak kaydedip okuyorum.

atomx

SPI arayüzünü kullanıyorsan proje dosyası atayım fakat LCD SSD1289 için
Hüseyin TECER

kimlenbu


atomx

SDIO versiyonumda varmış :)

biraz gereksiz kod yığını var temizlersiniz artık. Keil proje dosyası önceden söyleyeyim.

http://www.dosya.tc/server25/31rq1E/jussianRux2.rar.html
Hüseyin TECER

ErsinErce

https://www.mediafire.com/?439yjsire25cmjh

SysTick_Handler içine
ff_support_timerproc();


main.h içine
#include "diskio.h"
#include "ff.h"
#include "ff_rtc_if.h"
#include "rtc_support.h"
#include "ff_support.h"


main.c içinde
UINT totalbyte;
FATFS drive;
FIL src;

disk_initialize(0);
f_mount(0,&drive);
f_open (&src,"x.txt",FA_OPEN_EXISTING | FA_READ);
f_read(&src,Buffer,4096,&totalbyte);
f_sync(&src);
f_close(&src);

kimlenbu

#10
Yardımlarınız için teşekkür ederim. Sorun çözüldü.

Buffer tanımlamasında direkt olarak uint16_t kullandım. Buffer sayısını ikiye çıkardım, arka arkaya iki buffer'a okuma yaptırıp sırayla gösterdim ve tekrar okuma yaptırdım. En önemlisi buffer pointer'ını arttırıyormuşum ama her okumadan sonra başa almıyormuşum. Bufferlar pointerlarını da okumadan önce ilk hallerine resetleyince oldu.

main içinde :

uint16_t buffer3[2000]; // file copy buffer
	uint16_t buffer4[2000]; // file copy buffer


void SSD1963_LCD_SDBMP(uint16_t x,uint16_t y,uint16_t w,uint16_t h,const TCHAR *fname)
{  

  volatile uint32_t index;
  volatile uint32_t size = (w * h);
  uint16_t *bitmap_ptr =  buffer3;
	uint16_t *tmpbitmap_ptr = buffer3;
	uint16_t *bitmap_ptr2 =  buffer4;
	uint16_t *tmpbitmap_ptr2 = buffer4;
	

	LCD_WriteCommand(0x002A);	
	LCD_WriteData(x>>8);	    
	LCD_WriteData(x&0x00ff);
	LCD_WriteData((x+w-1)>>8);	    
	LCD_WriteData((x+w-1)&0x00ff);
  LCD_WriteCommand(0x002b);	
	LCD_WriteData(y>>8);	    
	LCD_WriteData(y&0x00ff);
	LCD_WriteData((y+h-1)>>8);	    
	LCD_WriteData((y+h-1)&0x00ff);
	LCD_WriteCommand(0x002c);
	
	res=f_open(&fsrc, fname, FA_READ | FA_OPEN_EXISTING);
	
			do
				{
					bitmap_ptr=tmpbitmap_ptr;
					bitmap_ptr2=tmpbitmap_ptr2;
					
					res=f_read(&fsrc,buffer3,sizeof(buffer3),&br);
					if(br>=sizeof(buffer3)){res=f_read(&fsrc,buffer4,sizeof(buffer4),&br2);}
					
					for(index =0; index < br; index++)
					{
						LCD_WriteData(*bitmap_ptr++);
					}
					
					if(br>sizeof(buffer3))
						{
							for(index =0; index < br; index++)
							{
								LCD_WriteData(*bitmap_ptr2++);
							}
						}
				
			}while(br>=sizeof(buffer3));
			
			f_close(&fsrc);
	}

ErsinErce


XX_CİHAN_XX

Arkadaşlar iki sene olmuş ama konu ile ilgili bir sorum olacak.
Hafıza kartındaki herhangi bir dosyayı yada kartın tamamını silmek için nasıl bir yol izlemeliyim?
http://elm-chan.org/fsw/ff/00index_e.html
Buradaki modüllerden istediğim işe en yakın modül f_unlink modülü gibi gözüküyor ancak olmadı bir türlü.
Yirmi yaşındaki bir insan, dünyayı değiştirmek ister . Yetmiş yaşına gelince , yine dünyayı değiştirmek ister, ama yapamayacağını bilir.

kantirici

Evet o fonksiyon gibi duruyor. Fonksiyon sadece dosya path ini alıyor. Siz nasıl veriyorsunuz path  i ?

XX_CİHAN_XX

Alıntı yapılan: kantirici - 26 Aralık 2016, 08:47:56
Evet o fonksiyon gibi duruyor. Fonksiyon sadece dosya path ini alıyor. Siz nasıl veriyorsunuz path  i ?
Hocam path'i aşağidaki gibi giriyorum.
path[0] = '/';
path[1] = 0;

Sd card içinde herhangi bir klasor yok. iki tane txt file var sadece. İkisini de silmek istediğim için bu şekilde girdim.
acaba şöyle mi girmeliyim "/<file name>"    ???
Yirmi yaşındaki bir insan, dünyayı değiştirmek ister . Yetmiş yaşına gelince , yine dünyayı değiştirmek ister, ama yapamayacağını bilir.