Bagaimana cara saya menulis ke memori flash SPI?

9

Saya sedang mengerjakan aplikasi audio di mana alih-alih menyimpan data audio pada kartu SD ( Waveshield pada Arduino) saya menyimpannya pada IC memori flash SPI dan menggulir papan saya sendiri dengan MCU, DAC, dan amp.

Saya menggunakan Winbond W25Q80BVSSIG .

Saya cukup akrab dengan pemrograman AVR menggunakan AVRISP mkII atau USBTiny , apakah menulis data ke flash dilakukan dengan programmer yang sama? Saya belum dapat menemukan apa pun saat mencari programmer memori flash SPI secara khusus.

Pertanyaan ini merupakan tindak lanjut dari pertanyaan ini .

JYelton
sumber
Saya tidak tahu apakah ada seorang programmer yang secara khusus dapat melakukan ini dengan mudah untuk Anda, dari PC atau sesuatu, tetapi jika ada CPLD yang terlibat dalam sirkuit Anda, Anda dapat mengonfigurasinya untuk menulis data ke memori flash.
deed02392
Saya pikir modul spi flash dirancang sekarang menjadi hari untuk menyimpan firmware / bios yang digunakan CPU pada kebanyakan pc. Bukan untuk perangkat penyimpanan yang kuat.
kerajinan Marshal

Jawaban:

12

Jika Anda hanya mencari cara untuk memprogram flash Winbond SPI dengan data "pre-loaded" yang akan dibaca mikrokontroler untuk digunakan ketika sedang berjalan maka yang ingin Anda lihat adalah seorang programmer yang dapat melakukan pemrograman dalam-sirkuit dari chip Flash SPI. Ini juga dikenal sebagai pemrograman dalam-sistem (ISP).

Salah satu pilihan adalah programmer dari DediProg. Perangkat terhubung USB ini dapat memprogram dalam sirkuit jika Anda mendesain papan Anda dengan benar. Mereka bahkan menjual klip adaptor yang dapat dilampirkan ke paket SOW-16 tanpa harus mendesain dalam tajuk pemrograman terpisah di papan Anda. DediProg memiliki buletin informasi aplikasi yang tersedia untuk membantu dengan desain yang benar untuk penggunaan sirkuit. Strategi utama untuk desain adalah menemukan cara sederhana untuk mengisolasi driver antarmuka SPI dalam sistem MCU Anda sehingga mereka tidak mengganggu driver di pod pemrograman SPI. Cara paling sederhana untuk melakukan ini adalah dengan meletakkan resistor seri di garis yang digerakkan MCU antara MCU dan SPI Flash. Programmer akan terhubung pada sisi flash SPI dari resistor seri. Metode alternatif dapat mencakup menambahkan MUX atau switch analog di garis antarmuka yang digerakkan. Skema yang lebih pintar adalah menambahkan "

masukkan deskripsi gambar di sini

Pilihan kedua yang juga dipertimbangkan adalah programer USB dari ASIX . Presto mampu melakukan berbagai jenis perangkat SPI dan I 2 C termasuk perangkat Flash SPI. Saya memiliki salah satu perangkat ini khusus untuk pemrograman Atmel MCU dan berbagai jenis perangkat Flash SPI. Ini adalah solusi yang lebih efektif daripada unit di atas tetapi tidak cukup fleksibel. Perangkat mereka yang lebih mahal bernama Forte mampu melakukan lebih banyak hal karena memiliki lebih banyak pin antarmuka target.

masukkan deskripsi gambar di sini

Kadang-kadang bisa bermanfaat untuk dapat menghubungkan pemrogram ke papan target tanpa harus menambahkan header pemrograman. Salah satu solusi bagus untuk ini adalah menempatkan satu set bantalan kecil di tapak khusus yang ditentukan oleh sebuah perusahaan bernama TagConnect . Mereka memproduksi dan menjual serangkaian kabel pemrograman koneksi cepat yang memiliki pin pogo yang menggunakan jejak khusus di papan tulis. Ada versi kabel 6-pin, 10-pin, dan 14-pin yang tersedia untuk disesuaikan dengan beragam aplikasi. Biaya kabel sangat masuk akal.

masukkan deskripsi gambar di sini

Michael Karas
sumber
Ini sangat membantu. Saya berencana memprogram memori flash sebelum menyoldernya ke PCB akhir. Sejauh ini saya sudah melakukan ini untuk MCU dan ini bekerja dengan baik. Saya ragu apakah menyediakan pin ISP pada PCB adalah ide yang baik atau tidak, karena mereka tidak seharusnya diprogram ulang setelah selesai.
JYelton
1
@JYelton - Dalam pengalaman saya, ide yang bagus untuk merencanakan ISP karena beberapa alasan. ECO (Engineering Change Orders) adalah fakta kehidupan dalam siklus produk. Seseorang atau sesuatu akan menuntut perubahan konten Flash setelah Anda mulai berproduksi. Chip flash kadang-kadang rentan terhadap gangguan kebisingan yang tak terduga di sirkuit dan akhirnya kontennya terganggu. Alasan lain untuk menyediakan ISP.
Michael Karas
1
Apakah ada header "standar" yang kompatibel dengan sebagian besar programmer ini setidaknya melalui kabel adaptor yang dibundel? Saya telah melihat header pin 2x4 dan 2x5 dengan banyak pinout berbeda. Juga lihat flashrom.org/Supported_hardware
kert
Setiap orang punya ide sendiri yang masuk akal. Kabel Tag-connect adalah $ 35 ~ $ 40.
markrages
1
@markrages - Tetapi untuk lab pengembangan atau stasiun pemrograman pabrik tertentu Anda hanya perlu membeli satu kabel. Anda tidak perlu satu untuk setiap produk. Plus, kabel-kabel ini jauh lebih murah daripada mencoba menggulung pogo-pin fixturing Anda sendiri untuk memungkinkan ISP tanpa konektor.
Michael Karas
8

Saya yakin Anda bisa melakukannya dengan Bajak Laut Bus tanpa melalui MCU Anda ... yang memungkinkan Anda melakukan interaksi serial yang sewenang-wenang langsung ke sebuah chip menggunakan komunikasi SPI, I2C, atau UART. Mungkin perlu sedikit usaha untuk "skrip" itu, tetapi mungkin akan membiarkan Anda melakukan pekerjaan itu.

Saya juga melihat alat khusus untuk memuat EEPROM lebih dari I2C secara langsung, tetapi tidak flash dan tidak SPI secara khusus.

vicatcu
sumber
Saya mulai bertanya-tanya apakah pilihan flash SPI saya bagus, mengingat betapa (jelasnya) metode yang digunakan untuk menulis ke hal-hal yang meledak.
JYelton
1
Itu akan membutuhkan beberapa skrip serius, tetapi ide yang bagus. Sedikit rumit untuk seleraku. Mungkin Anda harus mempertimbangkan kartu SD? Maka Anda hanya perlu peduli tentang bacaan, menulis ke sana dengan komputer
chwi
Prototipe saat ini menggunakan Arduino dan Waveshield (yang memiliki pembaca kartu SD). Saya ingin keluar dari kartu SD karena saya yakin biayanya akan lebih sedikit (tidak ada pembaca dan kartu) dan juga bukti yang lebih merusak.
JYelton
7

Saya belum pernah mendengar ada alat lain yang berbicara SPI langsung ke chip seperti itu, dan saya pikir itu tidak mungkin karena "semua" chip memerlukan panggilan berbeda untuk operasi yang berbeda.

Chip ini membutuhkan panggilan SPI untuk menulis, membaca, mengubah sektor, ukuran data dll. Di bawah bab 7.2 Instruksi dalam lembar data Anda dapat melihat semua perintah SPI yang dapat Anda kirimkan. Oleh karena itu, karena semua memori flash eksternal tidak memiliki set instruksi yang sama, Anda perlu menulis aplikasi khusus untuk yang ini.

EDIT: Sebagai tindak lanjut, saya benar-benar akan merekomendasikan salah satu memori flash Atmel sendiri SPI, karena kebanyakan dari mereka sudah menulis kode terbuka yang tersedia untuk mereka. Melihat posting ini dari AVRFreaks akan memberi Anda kode untuk beberapa chip flash serial Atmels AT45xxxx.

chwi
sumber
Jika saya mengerti Anda dengan benar, saya harus menulis sebuah program untuk MCU saya yang kemudian menulis data ke memori flash? Masalahnya adalah MCU memiliki memori kurang dari flash eksternal, jadi saya agak bingung.
JYelton
Iya. Anda dapat mengirim data dari garis serial komputer Anda dengan UART yang Anda tulis ke flash. Anda juga dapat menulis beberapa program untuk MCU, memprogram flash beberapa blok sekaligus. Mungkin sedikit memakan waktu tetapi berfungsi karena flash eksternal tidak akan terhapus selama Anda melacak perubahan sektor dengan benar
chwi
2
Ini jawaban yang benar. Jadi Anda akan memerlukan program di PC Anda untuk mengunduh potongan ke MCU yang kemudian menulisnya ke flash. Ini membantu jika ada pengecekan kesalahan dan Anda tidak perlu menulis program baru di PC; jadi saya sarankan Anda menemukan beberapa kode untuk XMODEM atau serupa.
pjc50
@ pjc50 ... jangan terlalu cepat mendeklarasikan 'jawaban yang benar' :)
vicatcu
Sebenarnya banyak programmer dapat memprogram memori flash; dan salah satu skema pemrograman umum yang digunakan dengan atmel micros cukup dekat dengan SPI untuk memulai.
Chris Stratton
4

Saya membeli programmer " FlashCAT " dari Komputer Tertanam dengan harga sekitar US $ 30. Sangat mudah untuk terhubung ke PC melalui USB dan menulis file ke memori flash Winbond. Metode dan programmer dalam jawaban lain mungkin sama baiknya, beberapa lebih mahal atau DIY, tetapi ini adalah cara yang murah dan sederhana yang sesuai dengan apa yang saya cari.

Ini gambar setup:

Pemrograman dengan FlashCAT

Programmer FlashCAT di sebelah kiri, terhubung ke USB. Ini menjalankan firmware pemrograman SPI (sebagai lawan JTAG) dan memasok daya ke memori flash. Daya yang disediakan dapat dipilih (3.3V atau 5V) dengan jumper.

Saya memiliki SOIC ke soket DIP di papan tempat memotong roti untuk memudahkan memprogram banyak chip. (Anda dapat melihat IC memori flash lain yang duduk di papan tempat memotong roti juga.)

Perangkat Lunak FlashCAT

Saya belum mengonversi file audio saya ke format biner yang tepat, tetapi saya menulis file WAV 211KB ke memori hanya untuk menguji, seperti gambar di atas. Saya kemudian membacanya kembali dan menyimpannya sebagai file baru, menamainya menjadi .wav, dan diputar dengan benar di PC.

Langkah selanjutnya adalah menyandikan file dengan benar, dan menulis perangkat lunak AVR untuk membaca data dan mengirimkannya melalui DAC.

Penafian: Saya tidak berafiliasi dengan Komputer Tertanam, saya hanya pelanggan yang memilih sesuatu yang murah dan saya berbagi informasi tentang pengalaman dengan produk.

JYelton
sumber
4

Agak terlambat untuk diskusi, tetapi bagi siapa saja yang membacanya setelah pencarian ....

Satu hal yang saya tidak lihat disebutkan, yang benar-benar penting ketika memprogram chip Flash SPI adalah kontrol pin Pilih Chip (CS_). Pin Select Chip digunakan untuk memberi tanda baca perintah ke SPI Flash. Secara khusus, transisi dari CS_ tinggi ke CS_ rendah harus segera mendahului penerbitan kode operasi op Write (WREN, BE, SE, PP). Jika ada aktivitas antara transisi CS_ (yaitu setelah CS_ sudah rendah) dan sebelum kode tulis ditransmisikan, kode tulis itu biasanya akan diabaikan.

Juga, apa yang tidak umum dijelaskan dalam lembar data Flash SPI, karena ini merupakan bagian yang tidak terpisahkan dari protokol SPI, yang juga penting, adalah bahwa untuk setiap byte satu mentransmisikan pada bus SPI, ia menerima byte sebagai balasannya. Juga, seseorang tidak dapat menerima byte, kecuali satu mentransmisikan byte.

Biasanya, Master SPI yang dikomandoi pengguna, memiliki Buffer Pengiriman, yang mengirim byte keluar pada baris MOSI bus SPI dan Buffer Terima, yang menerima byte dari jalur MISO bus SPI.

Agar data apa pun muncul di buffer Terima, beberapa data pasti telah dikirim Buffer Pengiriman. Demikian pula, setiap kali seseorang mengirim data dari buffer Transmit, data akan muncul di Buffer Terima.

Jika seseorang tidak berhati-hati menyeimbangkan penulisan Transmit dan Receive reads, orang tidak akan tahu apa yang diharapkan dalam buffer Terima. Jika Menerima buffer overflow, data biasanya tumpah dan hilang.

Jadi, ketika seseorang mengirim perintah baca, yang merupakan kode op satu byte dan tiga byte alamat, pertama akan menerima empat byte "sampah" di buffer Terima Master SPI. Empat byte sampah ini sesuai dengan kode op dan tiga byte alamat. Ketika sedang dikirim, Flash belum tahu apa yang harus dibaca, jadi itu hanya mengembalikan empat kata sampah.

Setelah empat kata sampah dikembalikan, untuk mendapatkan hal lain dalam Buffer Terima, Anda harus Mengirimkan sejumlah data sama dengan jumlah yang ingin Anda Baca. Setelah kode op dan alamat, tidak masalah apa yang Anda kirim, hanya mengisi untuk mendorong Baca DAta dari SPI Flash ke Buffer Terima.

Jika Anda tidak melacak dengan hati-hati empat kata sampah pertama yang dikembalikan, Anda mungkin berpikir bahwa satu atau lebih kata-kata tersebut adalah bagian dari Data Baca Anda yang dikembalikan.

Jadi, untuk mengetahui apa yang sebenarnya Anda dapatkan dari buffer yang diterima, penting untuk mengetahui ukuran buffer Anda, tahu bagaimana cara mengetahui apakah buffer itu kosong atau penuh (biasanya ada yang mendaftar bit status untuk melaporkan hal ini) dan melacak bagaimana banyak hal yang telah Anda kirim dan berapa banyak yang Anda terima.

Sebelum memulai operasi SPI Flash apa pun, sebaiknya "tiriskan" Receive FIFO. Ini berarti memeriksa status buffer menerima dan mengosongkannya (biasanya dilakukan dengan melakukan 'baca' dari Buffer Terima) jika belum kosong. Biasanya, mengosongkan (membaca) Buffer Terima yang sudah kosong tidak ada salahnya.

Informasi berikut ini tersedia dari diagram waktu di lembar data SPI Flash, tetapi kadang-kadang orang mengabaikan bit. Semua perintah dan data dikeluarkan ke flash SPI menggunakan bus SPI. Urutan untuk membaca SPI Flash adalah:

1) Start with CS_ high.
2) Bring CS_ low.
3) Issue "Read" op code to SPI Flash.
4) Issue three address bytes to SPI Flash.
5) "Receive" four garbage words in Receive Buffer.
6) Transmit as many arbitrary bytes (don't cares) as you wish to receive. 
Number of transmitted bytes after address equals size of desired read.
7) Receive read data in the Receive Buffer.
8) When you've read the desired amount of data, set CS_ high to end the Read command.
If you skip this step, any additional transmissions will be interpreted as 
request for more data from (a continuation of) this Read.

Perhatikan bahwa langkah 6 dan 7 harus disisipkan dan diulangi tergantung pada ukuran bacaan dan ukuran Bufer Menerima dan Mengirimkan Anda. Jika Anda mengirim sejumlah besar kata sekaligus, daripada yang diterima oleh Buffer Anda, Anda akan menumpahkan beberapa data.

Untuk membentuk Program Halaman atau perintah Tulis lakukan langkah-langkah ini. Ukuran Halaman (biasanya 256 byte) dan Ukuran Sektor (biasanya 64K) dan batas terkait adalah properti dari SPI Flash yang Anda gunakan. Informasi ini harus ada dalam lembar data untuk Flash. Saya akan menghilangkan rincian menyeimbangkan Bufer Kirim dan Terima.

1) Start with CS_ high.
2) Change CS_ to low.
3) Transmit the Write Enable (WREN) op code.
4) Switch CS_ to high for at least one SPI Bus clock cycle.  This may be tens or
hundreds of host clock cycles.  All write operations do not start until CS_ goes high.  
The preceding two notes apply to all the following 'CS_ to high' steps.
5) Switch CS_ to low.
6) Gadfly loop:   Transmit the 'Read from Status Register' (RDSR) op code and 
one more byte.   Receive two bytes.  First byte is garbage.  Second byte is status.
Check status byte.  If 'Write in Progress' (WIP) bit is set, repeat loop. 
(NOTE:  May also check 'Write Enable Latch' bit is set (WEL) after WIP is clear.)
7) Switch CS_ to high.
8) Switch CS_ to low.
9) Transmit Sector Erase (SE) or Bulk Erase (BE) op code.  If sending SE, then follow
it with three byte address.
10) Switch CS_ to high.
11) Switch CS_ to low.
12) Gadfly loop:  Spin on WIP in Status Register as above in step 6.  WEL will
be unset at end.
13) Switch CS_ to high.
14) Switch CS_ to low.
15) Transmit Write Enable op code (again).
16) Switch CS_ to high.
17) Switch CS_ to low.
18) Gadfly loop:  Wait on WIP bit in Status Register to clear. (WEL will be set.)
19) Transmit Page Program (PP = Write) op code followed by three address bytes.
20) Transmit up to Page Size (typically 256 bytes) of data to write.  (You may allow
Receive data to simply spill over during this operation, unless your host hardware
has a problem with that.)
21) Switch CS_ to high.  
22) SWitch CS_ to low.
23) Gadfly loop:  Spin on WIP in the Status Register.
24) Drain Receive FIFO so that it's ready for the next user.
25)  Optional:  Repeat steps 13 to 24 as needed to write additional pages or
page segments.

Akhirnya, jika alamat tulis Anda tidak pada batas halaman (biasanya kelipatan 256 byte) dan Anda menulis data yang cukup untuk melewati batas halaman berikut, data yang harus melewati batas akan ditulis ke awal halaman di mana alamat program Anda jatuh. Jadi, jika Anda mencoba untuk menulis tiga byte ke alamat 0x0FE. Dua byte pertama akan ditulis ke 0x0fe dan 0x0ff. Byte ketiga akan ditulis ke alamat 0x000.

Jika Anda mengirimkan sejumlah byte data yang lebih besar dari ukuran halaman, byte earlies akan dibuang dan hanya byte 256 (atau ukuran halaman) final yang akan digunakan untuk memprogram halaman.

Seperti biasa, tidak bertanggung jawab atas konsekuensi dari kesalahan, kesalahan pengetikan, kekhilafan, atau kekacauan di atas, atau dalam cara Anda menggunakannya.

Jeff Walther
sumber
"Sebelum memulai operasi SPI Flash apa pun, adalah ide yang bagus untuk" menguras "Receive FIFO. Ini berarti memeriksa status buffer terima dan mengosongkannya (biasanya dilakukan dengan melakukan 'membaca' dari Buffer Terima) jika tidak sudah kosong. Biasanya, mengosongkan (membaca) Buffer Terima yang sudah kosong tidak ada salahnya. " langkah apa yang perlu saya ambil untuk membaca status buffer terima dan mengosongkan buffer penerima?
3

Berlawanan dengan beberapa pernyataan di sini, sementara ada beberapa PROM SPI yang unik di luar sana, ada juga beberapa instruksi standar yang digunakan oleh berbagai macam PROM SPI, termasuk yang Anda pilih.

Seperti yang sudah disebutkan vicatcu, ada kabel 'bit-bash' yang tersedia yang dapat langsung memprogram SPI. Dari segi sinyal, SPI sangat mirip dengan JTAG, jadi setiap jenis kabel bit-bash harus dapat digunakan asalkan antarmuka open source. Protokol internal flash cukup sederhana.

Kami menggunakan saudara lelaki dari bagian yang Anda lihat untuk mem-boot board FPGA kami (256M - 2G). Pengalamatan memiliki byte tambahan untuk menangani volume penyimpanan, tetapi sebaliknya perintah pada dasarnya identik.

Jenis PROM yang Anda gunakan harus dihapus berdasarkan sektor, lalu diprogram berdasarkan halaman. Membaca secara signifikan lebih cepat daripada menulis (dalam kasus yang kita gunakan, pemrograman bisa memakan waktu setengah jam, tetapi membaca seluruh PROM membutuhkan waktu di bawah satu detik di 108MHz).

Sekarang untuk perintah: Ada cara lebih banyak perintah yang tersedia di perangkat ini daripada yang sebenarnya diperlukan untuk memprogram mereka. Anda sebenarnya hanya membutuhkan yang berikut ini:

  • RDID (baca ID) - hanya untuk memverifikasi PROM dan pensinyalan sebelum Anda melakukan sesuatu yang lebih kompleks.
  • WREN (memungkinkan penulisan) - diperlukan sebelum setiap penulisan.
  • PP (0x02 - program halaman) - diperlukan untuk memprogram halaman.
  • SE (0x20 - penghapusan sektor) - mengembalikan bit dalam sektor ke '1'.
  • RDSR (0x05 - register status baca) - diperlukan untuk memantau siklus hapus / tulis.
  • FREAD (0x0B - baca cepat) - baca data PROM dan verifikasi tulis.

Jika Anda ingin informasi lebih lanjut, lihat catatan jawaban pada pemrograman SPI untuk Xilinx FPGAs di situs web mereka (http://www.xilinx.com). Mereka menerapkan subset perintah yang dikurangi sehingga FPGA mereka dapat melakukan booting dari perangkat ini.

Saya merancang programmer saya sendiri untuk melakukan ini berdasarkan apa yang saya miliki dan menulis skrip programmer dengan Python, tetapi Anda dapat melakukan hal yang sama menggunakan kabel. Dalam kasus Anda, saya serius akan mempertimbangkan melakukan segala sesuatu secara tidak langsung melalui MCU seperti yang disarankan Michael Karas. Anda tidak perlu memprogram seluruh PROM dari MCU dalam sekali jalan - Anda dapat melakukannya berdasarkan sektor.

JXJ
sumber
2

Anda harus dapat mengarahkan kembali USBtiny ke program memori flash dan bukan MCU target jika Anda merasa nyaman mengubah pemrogramannya. Namun, mungkin tidak ada cukup memori untuk membuatnya cukup fleksibel untuk memprogram MCU dan flash.

Di suatu tempat saya memiliki papan dari sebuah proyek yang memiliki baik ATTINY dan SPI flash, dan digunakan sebagai Arduino sebagai "programmer" yang tersedia. Sedikit modifikasi sketsa ISP digunakan untuk memprogram MCU dengan avrdude, kemudian utilitas khusus mengirimkan urutan yang menempatkan sketsa dalam mode khusus dan menulis blok data ke flash SPI.

Chris Stratton
sumber