STM32 SPI FLASH

Başlatan zugzwang, 20 Mart 2017, 19:02:28

zugzwang

Merhaba

STM32F302VB'de external flash ile konuşmaya çalışıyorum. SPI konusunda tamam gibiyim, salae logic analyzer ile incelediğimde de gönderdiğim değeri izleyebiliyorum. Ancak ilk defa flash ile çalışıyorum yaklaşık 100sf.lık datasheetini baştan sona okumama rağmen bir sonuç elde edemedim. Daha önceki konuları vs. okuduğumda ise önce temizlemek gerektiği falan yazılmış ancak datasheetinde göremedim ve açıkcası tam olarak da anlayamadım.

Kısacası elimde Winbond W25Q32FV spiflash var ve buna veri loglamam lazım. SPI(özellikle yazma) konusunda bi sıkıntım yok anladığım kadarıyla ancak Flash konusunda bu ilk uygulamam olacak yani vereceğiniz her türlü tavsiye/kaynak/yönlendirmeye açığım.


İlk olarak "write enable" gibi olaylara takılmamak için, "Read Unique ID Number" adı verilen bi instructionı yapmaya çalışayım dedim
(böylece elimdeki donanımı da test etmiş olurum umuduyla)




8bitlik spi_write() fonksiyonumda sırasıyla spi_write(0x4B); ve ardından da spi_write(0xAA); spi_write(0xBB); spi_write(0xCC); spi_write(0xDD);

yazıyorum ve hemen ardından da aynı adrese gidip okumaya çalışıyorum. Burada da enteresan bir şekilde 0xFF, 0xFF00, 0x00 gibi değerler görüyorum ve bir düzeni yok.

SPI_write fonksiyonum şöyle:

void spi3_write(uint8_t data)
{
	uint32_t spixbase = 0x00;
	spixbase = (uint32_t)SPI3;
	spixbase += 0x0C;
	
	*(__IO uint8_t *)spixbase = data;
	while(!(SPI3->SR & SPI_SR_TXE));
}


SPI_read fonksiyonum ise:

uint8_t spi3_read()
{
      uint32_t spixbase = 0x00;
      //while((SPI3->SR & SPI_SR_RXNE));
      spixbase = (uint32_t)SPI3; 
      spixbase += 0x0C;
  
      return *(__IO uint8_t *) spixbase;
}




Daha fazla uzatmak istemiyorum umarım derdimi anlatabilmişimdir.
Her türlü yardım için şimdiden çok teşekkür ederim

EMP_Otto

Merhabalar,

Write Enable (06h) 
Page Program (02h)  (Adres+Data)
Write Disable (04h)

şeklinde ilerlerseniz istediğiniz datayı başarılı bir şekilde yazarsınız.

Flash birimini kullanmadan önce bilmeniz gereken bazı noktalar vardır.

*Flash biriminin default değeri 1 dir.Bir veri yazmak istediğinizde 1 olan yerler 1 kalır 0 olması gereken yerler 0'a çekilir.
*Flashlar PAGE denen yapılardan oluşur.(Sizdeki flashta 4K lık pagelere sahip)
*Flashın belkide en zor kısmı Pagelerden oluşmasıdır.Çünkü daha önceden yazdığınız bir veriyi değiştirmek istediğinizde öncelikle eski veriyi silmeniz gerekmektedir.EEPROMda olduğu gibi herhangi bir alanı silemezsiniz.Page yapısı komple silmeniz gerekmektedir.
Örnek vermek gerekirse 4K lık alanın 3.5K lık kısmını doldurdunuz ve son yazdığınız datayı değiştirmek isterseniz 4K lık alanın tamamını silmek zorundasınız.Verileriniz  gereksiz ise 4K lık alanı silebilirsiniz fakat veriler gerekli ise öncelikle verileri başka bir page taşıyıp 4K lık page silip gerekli değişiklikleri yapıp tekrardan yazmanız gerekmektedir.Verileri ya 4K lık buffer ile tek seferde yada parça parça taşımanız gerekir.
*Sizde öncelikle page temizleyin sonrasında temizlediğiniz page içerisine istediğiniz veriyi bir seferlik yazarbilirsiniz.Değişiklik yapmak isterseniz page'i tekrar temizlemeniz gerekir.
*İşlemleri yaparken herhangi bir koruma varsa öncelikle onu kaldırmanız gerekir(Yazma koruması gibi).Yanlış işlem yapılmasını engellemek için işinizi tamamlayınca korumayı tekrardan aktif etmeyi unutmayın.


Flash ile çalışırken yapılan hatalar ile genelde adres hatası oluyor.Adresi düzgün parçalayamamak yada komut sırasına uumamak oluyor.Nacizane tavsiyem öncelikle okuma işlemini doğru yaptığınızı doğrulayın.(ChipId'yi falan okuyun öncelikle)
Okuma işlemini yaptıktan sonra yazma işlemine geçebilirsiniz.Yazma işleminide basit olsun diye ilk olarak 0 numaralı adrese yapmanız sizin faydanıza olacaktır.

Kullandığınız Flash 1 byte'tan 256 byta kadar tek seferde yazmayı destekliyor.

Takıldığınız yer olursa konu altında sorarsınız.

İyi Çalışmalar





Bu işler zordur,özveri ister...

merve damar


*Flashın belkide en zor kısmı Pagelerden oluşmasıdır.Çünkü daha önceden yazdığınız bir veriyi değiştirmek istediğinizde öncelikle eski






[/quote]

MErhaba öncelikle, burada verinin üzerine yazma işlemi dedğil de mesela devamına silmeden veri yazabilir miyim? Örneğin 0. adresten başlayıp 5 bytelik veriler yazmak kaydetmek istiyorum. her sayfa 256 bytelik, ben 6. baytına istediğim farklı bir değeri yazmak için ilk başta eklediğim değeri silmeliyi miyim?

quarko

Alıntı yapılan: merve damar - 19 Temmuz 2023, 14:50:33MErhaba öncelikle, burada verinin üzerine yazma işlemi dedğil de mesela devamına silmeden veri yazabilir miyim? Örneğin 0. adresten başlayıp 5 bytelik veriler yazmak kaydetmek istiyorum. her sayfa 256 bytelik, ben 6. baytına istediğim farklı bir değeri yazmak için ilk başta eklediğim değeri silmeliyi miyim?

Hayır silmen gerekmez. Yazılan hücreye yeniden yazma durumu olursa, sektörü komple silmen gerekir. ST nin eeprom emulation ı bu mantıkla çalışıyor. İlgili sektörde hep aynı hücreye değilde, adresi ilerlete ilerlete sanal adres verisi ile birlikte kaydediyor.
"Aslanlar kendi hikayelerini yazmadıkça, avcıların kahramanlık hikayelerini dinlemek zorundayız."

flowchartx

Alıntı yapılan: quarko - 19 Temmuz 2023, 15:47:00Hayır silmen gerekmez. Yazılan hücreye yeniden yazma durumu olursa, sektörü komple silmen gerekir. ST nin eeprom emulation ı bu mantıkla çalışıyor. İlgili sektörde hep aynı hücreye değilde, adresi ilerlete ilerlete sanal adres verisi ile birlikte kaydediyor.

Sanal adres verisi dediğiniz nasıl oluyor hocam ne anlama geliyor yani. Biz bi pointer oluşturduğumuzda fiziksel hafızaya ulaşmış olmuyor muyuz? Bu konu kafama çok takılıyor bilmediğim için soruyorum

quarko

Evet pointer tanımlanıp, bir adres verildiğinde o adrese erişilebilir. Okurken sıkıntı yok ama yazarken, Flash hafıza tipinin yazma tipine uygun davranılması gerekir. Sanal adres verisi de şöyle oluyor. Mesela ST nin EEPROM Emulation'ın da bir veri kaydederken, 16 bit verinin kendisine, 16 bit veriye ait sanal bir adres olarak tanımlanıyor. Veriyi yazarken toplam 32 bit olarak, adresiyle birlikte yazılıyor. Hep aynı hücrelere yazma yapılmıyor. Sırayla hep bir sonraki 4 hücreye yazılıyor. İlgili page bittikten sonra, önceden belirtilen adetteki parametrelerin, son değerleri bir sonraki page'e aktarılır. Ve ilk page silinir. İkinci page bittiğinde de yine aynı işlem yapılarak, ilk page ten devam edilir. Hep aynı hücreye yazma işlemi olmadığı için, yazma adet sınırı minimum düzeyde kalmış olur. Böylelikle flash, optimum olarak kullanılmış olur.
"Aslanlar kendi hikayelerini yazmadıkça, avcıların kahramanlık hikayelerini dinlemek zorundayız."

flowchartx

Teşekkürler hocam

merve damar

Teşekkür ederim ben çok zorlaştırmışım, her yeni veri yazdığımda sektörü veya bloğu silmem gerekiyo sanıyodum, Şimdi bi 5 bytelik bi veriyi silmem gerektiğinde sektörü başka sektöre yazıyorum, silmem gereken hariç. Bu şekilde oluyo şuan karışık oldu bi bi fonksyion haline getiricem sonlara doğru. Flashı komple silmek zaman alıyor sektör veya blok halinde silinirse daha faydalı bence

quarko

Evet flash hafızayı silmek zaman alır. O yüzden kayıt amaçlı olarak belirli sektörleri tanımlayıp, sadece o sektörlerde işlem yapmak en doğrusu. Belirlenen sektörlerde de hep aynı hücreye yazmak ta o hücrenin ömrünü tükettiği için aynı hücreye değil de sıralı olarak yazmak, flash hafızanın ömrünü en üst seviyede kullanmayı sağlayacaktır. 
"Aslanlar kendi hikayelerini yazmadıkça, avcıların kahramanlık hikayelerini dinlemek zorundayız."

merve damar

Merhaba, W25q32 flasında her blok 64 kb oluşuyor. baslangıç ve bitiş adresleri datasheette gösterilmiş, fakat 32kblik veri yazabiliyorum sadece mesela blok bitiş adresi 0xFFFF olarak gösterilmiş fakat mesela ben CFFF adrsine veri yazamıyorum ya da okuyamıyorum, bu konuda yardımcı olabilir misiniz? hata mı yapıyorum

merve damar

64 kblık yere yazıyomuşum, ama 32kblık yer i siliyomuşum o yüzden doğru okumamışım, dikkat edin sizde çözüldü