STM32 SPI FLASH PROBLEMİ

Başlatan zugzwang, 20 Mart 2017, 18:59:31

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

Kodları gönderme sıranız dogru. "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);"
Daha önce spi flash ile çok uğraşan biri olarak nacizane sunları önerebilirim.

Spi biriminin dogru çalıştığından emin olunuz.CS pinini low yapabildiğinize emin olunuz.Ayrıca Spi moduna dikkat ediniz ,datasheette CLK pininin her düşen kenarında datanın hatta gönderileceği yazılmış(SPI Mode 0 olması lazım),daha sonra 64 bit unique id yi okuyor olmanız lazım.
Bu işler zordur,özveri ister...

1n4001

Kullandığın flash'ın datasheetini incelemedim ama genel olarak flash'ların kullanımı konusunda birkaç şey söyleyeyim.
1. Kimi Flash'lar bitleri 0'a çekerek yazma yaptığından yazmadan önce ilgili alanı silmelisin (0xFF yapmalısın)
2. Silme işlemi page, sector, block şeklinde olabilir. Sileceğin alanın boyutuna göre seçimini yapıp silme komutu gönderebilirsin.
3. Flash'larda silme komutu gönderdikten sonra (örn. 50 ms) ve yazma komutu gönderdikten sonra (örn. 5 ms) bekleme ihtiyacı vardır. O sırada verdiğin komuta göre işlem yapar, meşgul olur. İşleminin bittiğini status register'deki busy bitini sorgulayarak anlayabilirsin.
4. Sil - bekle, yaz - bekle işleminden sonra okuma yaparsan sorunsuz okuyabileceğini düşünüyorum.
5. Birde şu var: Page yazma yaparken (örn 256 byte) flash'ın kendi sayacı 255'ten sonra 0'a döner. O yüzden tek seferde bir page boyutundan daha fazla byte veri yazamazsın.

erpay

Öncellikle arkadaşların dediği gibi SPI konusunda  emin olman lazım basit bir SPI Dac sürerek emin olabilirsin mesela.

Sonrasında ilk denediğin gibi ürün ID'sini okumaya çalış, datasheet'de ID için başlayan kod dizininde 4B ile başlayan birşey göremedim bu arada.

ID'yi okuyablidikten sonra WriteEnable ve FlashReady tarzında fonksiyonlar hazırlayabilirsin, bunları birçok okuma ve yazma da kullanman gereken rutin fonksiyonlar olacak.

zugzwang

Yardımcı olmaya çalışan herkese çok teşekkür ediyorum

Üstte Flashın data in pini, alttaki ise CLK pini.

0x9F(1001 1111) göndermeye çalışıyorum.



Bir sıkıntı yok gibi gözüküyor bence, değil mi? Data out(yani dönen) pinine baktığımda ise Keilda debug yaparken watch windowsta da gördüğüm gibi önce birkaç kez 0xFF, sonrasında ise hiçbir şey göremiyorum.

0x9F ile ne yapmaya çalıştığımı ise şöyle göstereyim:



0xEF görmeye çalışıyorum yani kısaca. Ancak ne yaptıysam bir türlü olmadı.

Sizce nerede hata yapıyorum?

zugzwang

Evet nihayet çözüldü sorun çok şükür.

Düşündüğümüz gibi SPI kısmında bir sorun yokmuş.

CS pinini low yapamıyormuşum ve sıkıntı oradan çıkıyormuş. Bunun nedeni ise CS olarak kullandığım pinin PA15 olması.
Moder registerını set etmeden önce clear etmek gerekiyormuş. Ben direk moder |= 0x01; yaptığım için(reset değeri 0x02 olduğundan dolayı) 0x02 | 0x01=0x03 yapıyormuş değeri. O yüzden önce sıfırlayıp ardından moder|= 0x01; yaptığımda tüm sorunlarım çözülmüş oldu.

Debug yaparken falan da Keilda SPI üzerine yoğunlaşıp sadece SPI registerlarını izleyip kontrol ettiğim için günlerim gitti.

Siz siz olun ilişkili GPIO birimlerine de göz atmayı unutmayın.

Yardım etmeye çalışan herkese tekrar teşekkür ederim