Bekerja dengan kartu SD melalui antarmuka SPI. Implementasi VHDL

Hai Habr! Setelah di kantor, saya mendapat tugas menilai kemungkinan menerapkan penyimpanan data pada kartu SD saat menghubungkannya ke FPGA. Penggunaan SPI dianggap sebagai antarmuka interaksi, karena lebih mudah diimplementasikan. Saya ingin berbagi pengalaman yang didapat.



Karena ruang pada papan sirkuit tercetak selalu terbatas, pertimbangan kartu SD akan dilakukan pada contoh kartu dalam faktor bentuk microSD.

Kandungan


1. Membaca spesifikasi
1.1 Informasi umum
1.2 Inisialisasi
1.3 Menghapus informasi
1.4 Membaca informasi
1.4.1 Membaca satu blok data
1.4.2 Membaca banyak blok data
1.5 Menulis informasi
1.5.1 Menulis satu blok data
1.5.2 Menulis banyak blok data
2. Menerapkan algoritma dalam perangkat keras
2.1 Komponen dari lapisan fisik
2.2 Komponen tingkat perintah
2.3 Komponen komunikasi dengan dunia luar
3. Verifikasi dalam perangkat keras
4. Hasil

1. Spesifikasi membaca


1.1 Umum


Pembacaan cepat spesifikasi memberitahu kita opsi kartu SD berikut:

  • transfer data ke kartu SD dilakukan pada satu baris;
  • membaca data dari kartu SD dilakukan pada satu baris;
  • dalam mode SPI, daya hanya +3,3V;
  • frekuensi clock dalam mode inisialisasi dalam kisaran 100-400 kHz;
  • frekuensi clock setelah inisialisasi - 25 MHz.

Ini langsung menyiratkan titik pada bandwidth puncak teoretis: 25 MHz * 1 bit = 25 Mb / s, yang agak kecil. Yang kedua minus penggunaan SD-card, power + 3.3V. Pada papan sirkuit tercetak yang rencananya akan dipasang kartu SD, tidak ada tegangan seperti itu.

Kartu faktor bentuk MicroSD dapat dibagi menjadi 3 kategori berdasarkan kapasitas:

  • SDSC Kapasitas kartu hingga 2 GB inklusif. Alamat di dalam kartu adalah byte.
  • SDHC. Kapasitas kartu lebih dari 2 GB dan inklusif hingga 32 GB. Alamat di dalam kartu menunjukkan blok 512 byte.
  • SDXC. Kapasitas kartu lebih dari 32 GB dan hingga 128 TB inklusif. Alamat di dalam kartu menunjukkan blok 512 byte.

Tampilan umum peta ditunjukkan pada gambar di bawah ini.


Nomor kontakNamaSebuah tipeDeskripsi
1RSV-Tidak digunakan
2CSmemasukkanPemilihan chip
3DImemasukkanJalur data dari perangkat Master (MOSI)
4VddNutrisiTegangan suplai
5SCLKmemasukkanSinyal jam
6VssNutrisiTanah
7MELAKUKANKeluaranJalur Data ke Perangkat Utama (MISO)
8RSV-Tidak digunakan

Koneksi dilakukan sesuai dengan diagram di bawah ini:


Resistor harus diberi peringkat 50 kOhm

Setelah menghidupkan daya, kartu SD dalam mode SDIO. Untuk beralih ke mode SPI, Anda harus melakukan inisialisasi. Protokol untuk bekerja dengan kartu melibatkan penggunaan skema kontrol untuk transfer data dan perintah yang benar dalam bentuk algoritma CRC. Saat beroperasi dalam mode SPI, verifikasi CRC dinonaktifkan secara default. Dengan demikian, perintah pertama yang dikirim ke kartu untuk mengalihkan kartu ke mode SPI harus berisi nilai CRC yang benar.

Perintah yang dikirimkan melalui antarmuka SPI berukuran 48 bit. Format perintah:

  • Bit 47 (paling kiri) selalu berisi nilai 0.
  • Bit 46 selalu berisi nilai 1.
  • Bits 45..40 berisi indeks perintah.
  • Bits 39..8 berisi argumen dari perintah.
  • Bits 7..1 berisi CRC dari bit sebelumnya.
  • Bit 0 selalu mengandung nilai 1.

Bits 47 dan 46 memberikan kartu kemampuan untuk secara jelas melacak awal transaksi, karena bus MOSI saat istirahat sama dengan satu.



Perintah yang digunakan saat bekerja dengan kartu SD akan menerima jawaban seperti R1, R3, R7.


Jawaban dari tipe R1, ukuran 8 bit. Jenis jawaban R3, ukuran 40 bit. Jenis jawaban R7, ukuran 40 bit. Semua perintah dan jawaban mereka dirinci dalam Spesifikasi Fisik Sederhana Lapisan.









1.2 Inisialisasi


Algoritma Inisialisasi:

  1. Setelah menyalakan daya, tunggu setidaknya 1 ms.
  2. Hasilkan minimum 74 jam switching untuk kartu. Baris CS dan MOSI harus dalam keadaan unit logis.
  3. Hasilkan perintah CMD0. Perintah CMD0 me-reset kartu SD.
  4. CMD0. R1. , R1 16 , 3. R1 , 0x01 ( ), 3, 5.
  5. CMD8. .
  6. CMD8. R7. , , , 7, , , 17, 13.
  7. CMD55. CMD55 , .
  8. CMD55. R1. 0x01 ( ), 7, 9.
  9. ACMD41. ACMD41 , SDSC ( 0x00000000) .
  10. ACMD41. R1. , , 11. , 0x00 ( ) 14, 7.
  11. CMD1. CMD1 ACMD41.
  12. CMD1. R1. , , 13, , 0x00 ( ), 14, 11.
  13. . , . .
  14. CMD16. , 512 .
  15. CMD16. R1. , 0x00 ( ) 16, 13.
  16. . . .
  17. CMD55. CMD55 , .
  18. CMD55. R1. 0x01 ( ), 17, 19.
  19. ACMD41. ACMD41. ACMD41 , SDHC ( 0x40000000) .
  20. ACMD41. R1. , , 13. , 0x00 ( ) 21, 17.
  21. CMD58. .
  22. Menunggu respons terhadap perintah CMD58. Jawabannya adalah respons tipe R3. Jika sedikit diatur dalam respons bahwa kartu bekerja dengan alamat blok 512 byte, lanjutkan ke langkah 16, jika tidak ke langkah 14.

Setelah inisialisasi selesai, kartu dapat dioperasikan dalam blok 512 byte dengan frekuensi clock 25 MHz. Ini adalah versi lengkap dari algoritma inisialisasi, yang mencakup semua jenis kartu. Dalam kasus saya, ketika menggunakan kartu 16 GB, algoritma inisialisasi terdiri dari langkah 1-6, 17-22, 16.

Algoritma Grafis

1.3 Menghapus Informasi


Kartu faktor bentuk SD mikro mendukung perintah penghapusan. Setelah perintah hapus, nilai dari alamat penghapusan yang ditentukan akan diisi dengan nilai 0xFF atau 0x00, tergantung pada kartu.

Algoritma Penghapusan Informasi

  1. CMD32. .
  2. CMD32. R1. 0x00 ( - ), 3, 4.
  3. . , .
  4. CMD33. . , CMD32.
  5. CMD33. R1. 0x00 ( - ), 3, 6
  6. Mengirim perintah CMD38. Perintah untuk menghapus informasi dari blok yang dipilih. Setiap 4 byte harus dikirim sebagai argumen, kecuali untuk nilai 0x00000001, 0x00000002.
  7. Menunggu respons terhadap perintah CMD38. Jawabannya adalah respons tipe R1b. Ini adalah versi jawaban yang diperpanjang ketika kartu menghasilkan respons R1, dan kemudian menarik garis MISO ke nol, menunjukkan chip sedang sibuk. Penting untuk menunggu sampai nilai unit muncul pada baris MISO. Jika jawabannya tidak 0x00 (ada beberapa kesalahan saat menjalankan perintah), lanjutkan ke langkah 3, jika tidak ke langkah 8
  8. Penyelesaian algoritma penghapusan.

Algoritma Grafis

1.4 Membaca informasi


Membaca informasi dari kartu SD melalui SPI dimungkinkan dengan dua cara.

1.4.1 Membaca blok data tunggal


Saat membaca satu blok data, perangkat Master menghasilkan perintah untuk kartu SD untuk membaca satu blok data, menunggu respons bahwa perintah telah diproses dan sedang menunggu paket dengan data dari kartu. Setelah menerima paket dengan data dari kartu, transaksi baca berakhir.


Tampilan umum dari transaksi yang membaca satu blok data.

Awalnya, opsi seperti itu diterapkan, tetapi kecepatan yang dihasilkan sangat marah (perbandingan kecepatan akan lebih rendah).

1.4.2 Membaca beberapa blok data


Saat membaca beberapa blok data, perangkat Master menghasilkan perintah untuk kartu SD untuk membaca beberapa blok data, menunggu respons bahwa perintah telah diproses, dan mengharapkan paket data dari kartu. Setelah mengirim paket data, kartu mengirimkan paket data berikutnya. Ini akan berlanjut sampai perintah diterima dari perangkat Master untuk menyelesaikan pembacaan.


Tampilan umum dari transaksi yang membaca banyak blok data.


Struktur Paket Data

Di mana:

  • Token Data Perintah baca menggunakan nilai 0xFE.
  • Blok Data. Berisi data yang dibaca dari kartu.
  • CRC Berisi checksum dari bidang sebelumnya.

Jika kesalahan terjadi saat membaca, kartu bukannya Data Token mengembalikan Token Kesalahan. Ukuran Token Galat adalah 1 byte. Bits 7..5 berisi nilai nol, bit 4..0 mengkodekan jenis kesalahan.

Algoritma untuk membaca beberapa blok data:

  1. Mengirim perintah CMD18. Perintah memberi tahu kartu bahwa banyak blok akan dibaca.
  2. Menunggu respons terhadap perintah CMD18. Jawabannya adalah respons tipe R1. Jika jawabannya tidak 0x00 (ada beberapa kesalahan saat menjalankan perintah), lanjutkan ke langkah 3, jika tidak ke langkah 4.
  3. Status kesalahan. Gagal membaca, keluar dari algoritma membaca.
  4. Menunggu tanda dari kartu. Jika Token Kesalahan diterima dari kartu, lanjutkan ke langkah 3, jika tidak, lanjutkan ke langkah 5.
  5. Terima dari kartu blok data berukuran 512 byte.
  6. Terima dari ukuran kartu CRC bidang 2 byte.
  7. . , 8, 4.
  8. CMD12. . , Data Packet, .
  9. CMD12. R1b. R1, MISO , . MISO , . 0x00 ( - ), 3, 10.
  10. .

Ada sedikit nuansa dalam algoritma membaca. Sinyal pilih chip (CS) harus diatur ke logika nol sebelum membuat perintah CMD18 dan diatur ke logika satu setelah menerima respons terhadap perintah CMD12.

Algoritma Grafis

1.5 Merekam Informasi


Menulis informasi ke kartu SD melalui antarmuka SPI dimungkinkan dalam dua versi.

1.5.1 Menulis satu blok data


Saat merekam satu blok data, perangkat Master menghasilkan perintah untuk kartu SD untuk menulis satu blok data, menunggu respons dari kartu bahwa perintah telah diproses, mentransmisikan paket dengan data untuk merekam ke kartu, mengharapkan respons dari kartu bahwa data ditulis, menyelesaikan transaksi.


Tampilan umum dari transaksi tulis dari satu blok data.

Seperti halnya membaca, catatan satu blok data awalnya diimplementasikan. Hasil kecepatannya tidak memuaskan.

1.5.2 Menulis banyak blok data


Saat merekam beberapa blok data, perangkat Master menghasilkan perintah untuk merekam beberapa blok data, menunggu respons dari kartu bahwa perintah telah diproses, mentransmisikan paket dengan data untuk merekam ke kartu, mengharapkan respons dari kartu bahwa data dicatat. Setelah menerima respons Master, perangkat mentransmisikan paket dengan data berikut untuk direkam ke kartu. Ini akan berlanjut sampai perangkat Master mengirim Token Data Stop.


Tampilan umum dari transaksi tulis untuk beberapa blok data.

Struktur Paket Data mirip dengan struktur Paket Data saat membaca data.

Format:

  • Token Data Untuk perintah tulis, nilai 0xFC digunakan.
  • Blok Data. Berisi data yang ditulis ke kartu.
  • CRC Berisi checksum dari bidang sebelumnya.

Stop Tran Token yang digunakan untuk menyelesaikan perintah tulis berukuran 1 byte dan sama dengan 0xFD.

Setelah bit terakhir dari Paket Data dimasukkan ke dalam kartu, kartu merespons jam berikutnya dengan status catatan data - Respons Data. Respons Data memiliki ukuran 1 byte, bit 7..5 dapat berupa apa saja, bit 4 selalu nol, bit 0 selalu sama dengan satu, bit 3..1 mengkodekan status catatan data. Setelah kartu mengembalikan Paket Data, kartu menarik garis MISO ke nol, menunjukkan kartu sibuk. Setelah level unit logis pada garis MISO, Anda dapat mentransfer paket data berikutnya ke kartu.

Algoritma untuk merekam beberapa blok data:

  • Mengirim perintah CMD25. Perintah memberi tahu kartu bahwa beberapa blok akan ditulis.
  • CMD25. R1. 0x00 ( - ), 3, 4.
  • . , .
  • .
  • 512 .
  • CRC 2 .
  • Data Response . , 3, 8.
  • . , 9, 4.
  • Stop Tran Token. , .
  • Menunggu respons dari kartu. Kartu pada Stop Tran Token menarik garis MISO ke nol, menunjukkan kartu sibuk. Kita perlu menunggu di baris MISO untuk nilai unit, yang akan menunjukkan akhir dari perintah
  • Penyelesaian algoritma perekaman.

Ada juga nuansa kecil dalam algoritma perekaman. Sinyal pilih chip (CS) harus diatur ke logika nol sebelum membuat perintah CMD25 dan diatur ke logika satu setelah menerima respons untuk Stop Tran Token

Algoritma Grafis

2. Implementasi algoritma dalam perangkat keras


Sebagai hasil dari membaca spesifikasi, kami mendapatkan beberapa karakteristik dari algoritma yang perlu diimplementasikan dalam perangkat keras.

Mode operasi yang memungkinkan:

  • Pembentukan frekuensi awal. Baris CS dan MOSI harus dalam keadaan unit logis.
  • Transfer data ke kartu SD.
  • Terima data dari kartu SD.
  • Menunggu selesainya tim. Ini digunakan ketika, setelah menghasilkan respons, kartu SD menarik garis MISO ke nol untuk menunggu munculnya unit.
  • Baca respons saat menulis data.
  • Menunggu tanda saat membaca data.

Mode jam yang memungkinkan:

  • Sinyal jam untuk diinisialisasi.
  • Sinyal jam untuk bekerja.

Dari sudut pandang saya, algoritma diimplementasikan secara optimal menggunakan tiga komponen:

  • Komponen lapisan fisik, yang terhubung langsung ke kartu SD, menghasilkan sinyal SCLK, CS, DI, dibaca dengan DO.
  • Komponen tingkat perintah yang menyiapkan semua data untuk komponen di lapisan fisik.
  • Komponen komunikasi dengan dunia luar yang menyembunyikan seluruh perangkat internal dan menyediakan antarmuka untuk perintah (membaca, menulis, menghapus) dan data.

2.1 Komponen lapisan fisik


entity SDPhy is
	generic	(	gTCQ		: time := 2 ns );
	port	(	-- Control bus
			iPhyTxData	: in	std_logic_vector( 9 downto 0);
			iPhyMode	: in	std_logic_vector( 4 downto 0);
			iPhyTxWrite	: in	std_logic;
			oPhyTxReady	: out	std_logic; 
			-- Out Data
			oPhyRxData	: out	std_logic_vector( 7 downto 0); 
			oPhyRxWrite	: out	std_logic;
			oPhyCmdEnd	: out	std_logic;
			-- Spi
			oSdCS		: out	std_logic;
			oSdClk		: out	std_logic;
			oSdMosi		: out	std_logic;
			oSdMosiT	: out	std_logic;
			iSdMiso		: in	std_logic;
			-- system
			sclk		: in	std_logic;
			pclk		: in	std_logic;
			rst		: in	std_logic ); 
end SDPhy;

Dimana:

  • iPhyTxData , iPhyMode , .
  • iPhyTxWrite , iPhyTxData iPhyMode .
  • oPhyTxReady , . FULL FIFO, .
  • oPhyRxData , SD-.
  • oPhyRxWrite , oPhyRxData .
  • oPhyCmdEnd , .
  • oSdCS (CS) SD-.
  • oSdClk SD-.
  • oSdMosi SD-.
  • oSdMosiT SD-.
  • iSdMiso SD-.
  • sclk SD- (50 ).
  • pclk , .
  • sinyal reset pertama, level aktif satu.

Dalam FPGA, ada unit khusus untuk bekerja dengan sinyal clock (PLL, MMCM), namun, menerima sinyal clock kurang dari 5 MHz dari outputnya bermasalah. Akibatnya, lapisan fisik beroperasi pada frekuensi 50 MHz. Bersama dengan setiap data dalam sinyal iPhyMode, sedikit diterima yang menunjukkan pada frekuensi berapa data ini harus ditransfer ke kartu SD (atau diterima dari itu). Tergantung pada bit kecepatan, Jam mengaktifkan sinyal yang dihasilkan.

Dua automata diimplementasikan dalam komponen lapisan fisik, untuk mentransfer data ke kartu SD dan untuk menerima data dari itu.

Kode mesin untuk transfer data: github .

  • Status SDummy menyediakan pembentukan frekuensi awal, 128 switching.
  • Status STxBits menyediakan transfer data ke kartu SD.

Kode mesin untuk menerima data: github .

  • Status sRxBits menyediakan penerimaan data dari kartu SD.
  • Status sBusy memastikan bahwa kartu SD siap (kartu melepaskan garis MISO ke tingkat unit).
  • Status sResp mengimplementasikan membaca respons saat menulis data.
  • Status sToken menerapkan token wait saat membaca data.

2.2 Komponen tingkat perintah


entity SdCommand is
	generic	(	gTCQ		: time := 2 ns );
	port	(	-- Command from host
			oSdInitComp	: out	std_logic;
			oSdInitFail	: out	std_logic;
			iSdAddress	: in	std_logic_vector(31 downto 0);
			iSdStartErase	: in	std_logic;
			iSdStartRead	: in	std_logic;
			iSdStartWrite	: in	std_logic;
			oSdCmdFinish	: out	std_logic_vector( 1 downto 0);
			oSdhcPresent	: out	std_logic;
			-- Data
			oSdReadData	: out	std_logic;
			iSdDataR	: in	std_logic_vector(31 downto 0);
			oSdWriteData	: out	std_logic;
			oSdDataW	: out	std_logic_vector(32 downto 0);
			-- Spi
			oSdCS		: out	std_logic;
			oSdClk		: out	std_logic;
			oSdMosi		: out	std_logic;
			oSdMosiT	: out	std_logic;
			iSdMiso		: in	std_logic;
			-- system
			pclk		: in	std_logic;
			sclk		: in	std_logic;
			rst		: in	std_logic );

Dimana:

  • oSdInitComp menandatangani penyelesaian inisialisasi kartu SD.
  • Tanda oSdInitFail tentang kegagalan inisialisasi.
  • Alamat iSdAddress di kartu SD untuk menjalankan perintah.
  • iSdStartErase mulai menghapus eksekusi perintah.
  • iSdStartRead mulai membaca eksekusi perintah.
  • iSdStartWrite mulai menulis eksekusi perintah.
  • Status penyelesaian tim oSdCmdFinish. Bit nol sama dengan satu, perintah selesai dengan sukses. Bit pertama adalah satu, perintah selesai dengan kesalahan.
  • oSdhcSajikan bendera deteksi kartu SDHC / SDXC.
  • oSdReadData Membaca data untuk menulis ke kartu SD.
  • data iSdDataR untuk menulis ke kartu SD.
  • bendera oSdWriteData untuk menulis data yang dibaca dari kartu SD.
  • Data oSdDataW membaca dari kartu SD.

Sinyal yang tersisa bertepatan dengan sinyal dari lapisan fisik.

Komponen ini memiliki 5 mesin otomatis.

  • smSdInit ( github ) - inisialisasi kartu SD.
  • smSdErase ( github ) - hapus data dari kartu SD.
  • smSdRead ( github ) - baca data dari kartu SD.
  • smSdWrite ( github ) - menulis data ke kartu SD.
  • smSdCommand ( github ) - berdasarkan fitur yang dihasilkan menyiapkan data untuk lapisan fisik dari semua mesin sebelumnya.

2.3 Komponen komunikasi dengan dunia luar


entity SdHost is
	generic	(	gTCQ		: time := 2 ns );
	port	(	-- Sd Host command
			iSdCommand	: in	std_logic_vector( 2 downto 0);
			iSdAddress	: in	std_logic_vector(31 downto 0);
			iSdStart	: in	std_logic;
			oSdStatus	: out	std_logic_vector( 1 downto 0);
			oSdInitFail	: out	std_logic;
			-- Write data to card
			iSdTxData	: in	std_logic_vector(31 downto 0);
			iSdTxValid	: in	std_logic;
			iSdTxLast	: in	std_logic;
			oSdTxReady	: out	std_logic;
			-- Read data from card
			oSdRxData	: out	std_logic_vector(31 downto 0);
			oSdRxValid	: out	std_logic;
			oSdRxLast	: out	std_logic;
			iSdRxReady	: in	std_logic;
			-- Spi
			oSdCS		: out	std_logic;
			oSdClk		: out	std_logic;
			oSdMosi		: out	std_logic;
			oSdMosiT	: out	std_logic;
			iSdMiso		: in	std_logic;
			-- system
			pclk		: in	std_logic;
			sclk		: in	std_logic;
			rst		: in	std_logic );

Dimana:

  • kode perintah iSdCommand untuk dieksekusi.
  • iSdAddress adalah alamat untuk menjalankan perintah.
  • iSdStart memulai eksekusi perintah.
  • Status penyelesaian tim oSdStatus. Bit nol sama dengan satu - perintah selesai. Bit pertama adalah satu - perintah dilengkapi dengan kesalahan.
  • Tanda oSdInitFail tentang kegagalan inisialisasi.
  • iSdTxData. Antarmuka Axi-Stream untuk menulis data ke kartu SD. Port dengan data.
  • iSdTxValid. Antarmuka Axi-Stream untuk menulis data ke kartu SD. Port dengan sinyal tulis.
  • iSdTxLast. Antarmuka Axi-Stream untuk menulis data ke kartu SD. Port dengan tanda dw terakhir dalam data.
  • oSdTxReady. Antarmuka Axi-Stream untuk menulis data ke kartu SD. Port dengan tanda kesiapan untuk menerima data.
  • oSdRxData. Antarmuka Axi-Stream untuk membaca data dari kartu SD. Port dengan data.
  • oSdRxValid. Antarmuka Axi-Stream untuk membaca data dari kartu SD. Port dengan sinyal tulis.
  • oSdRxLast. Antarmuka Axi-Stream untuk membaca data dari kartu SD. Port dengan tanda dw terakhir dalam data.
  • iSdRxReady. Antarmuka Axi-Stream untuk membaca data dari kartu SD. Port dengan tanda kesiapan untuk menerima data.

Sinyal yang tersisa bertepatan dengan sinyal dari lapisan fisik.

Komponen mengimplementasikan satu mesin smSdControl ( github ).

  • Keadaan lemah. Menunggu inisialisasi dan perintah selesai.
  • Keadaan sWaitCmd. Memeriksa jenis perintah.
  • sReadCmd. FIFO, , SD- .
  • sWriteCmd. , FIFO SD-, .
  • sEraseCmd. .
  • sWaitEnd. .
  • sFinish. , .

3.


Algoritma ditulis, diverifikasi dalam simulator. Perlu untuk memeriksa sekarang di setrika. Dari apa yang tersedia, papan Zybo dari Digilent muncul, memiliki terminal FPGA gratis di bank dengan tegangan + 3.3V, yang Anda dapat dengan mudah menghubungkan perangkat eksternal. Ya, dan jenis FPGA yang digunakan adalah Zynq-7000, yang berarti ada inti prosesor. Anda dapat menulis tes dalam C, yang akan menyederhanakan tugas pengujian. Jadi, kami menghubungkan algoritma yang diimplementasikan ke inti prosesor melalui port GP (operasi 4-byte dimungkinkan, mirip dengan PIO ). Kami tidak akan repot dengan gangguan, kami menerapkan jajak pendapat waktu. Saat bekerja pada modul prosesor, algoritma perekaman data adalah sebagai berikut:









  • Tetapkan alamat dalam kartu SD.
  • Setel kode perintah 2.
  • Tulis data ke buffer yang terletak di logika yang dapat diprogram.
  • Jalankan perintah.
  • Tunggu sampai perintah selesai.
  • Setel ulang status penyelesaian tim.

Tes yang Diimplementasikan:

for (SectorAddress = 0; SectorAddress < 1048576; SectorAddress ++)
{
	if ((SectorAddress % 1024) == 0)
	{
		xil_printf("Data write to %d sector \n\r", SectorAddress);
	}

	/** Set address */
	Xil_Out32(0x43c00008, SectorAddress);

	/** Set command */
	Xil_Out32(0x43c00004, 2);

	/** Write data to PL */
	for (int32_t i = 0; i < 1024; i++)
	{
		Xil_Out32(0x43c00014, cntrData);
		cntrData++;
	}

	/** Start */
	Xil_Out32(0x43c00000, 1);

	/** Wait end of operation */
	for (;;)
	{
		status = Xil_In32(0x43c0000c);
		if (status == 0x01 || status == 0x03)
		{
			if (status == 0x03)
			{
				xil_printf("Error in write \n\r");
			}
			break;
		}
		else
		{
			cntrDuration++;
			usleep(100);
		}
	}

	/** Duration operation */
	durationWrite += cntrDuration;

	if (cntrDuration > MaxWrite )
	{
		MaxWrite = cntrDuration;
	}

	cntrDuration = 0x00;

	/** Clear start */
	Xil_Out32(0x43c00000, 0);

	SectorAddress += 7;
}

Untuk pertanyaan mengapa batas luar 1024 digunakan dalam loop. Algoritma menetapkan jumlah blok sama dengan 8. Ukuran satu blok adalah 512 byte. Ukuran total 8 blok data adalah 8 * 512 byte = 4096 byte. Bus antara modul prosesor dan logika yang dapat diprogram berukuran 4 byte. Ternyata untuk mengirim 4.096 byte dari 4 byte dari modul prosesor ke logika yang dapat diprogram, perlu untuk melakukan 4096/4 = 1024 operasi tulis.

Saat mengerjakan modul prosesor, algoritme pembacaan data adalah sebagai berikut:

  • Tetapkan alamat dalam kartu SD.
  • Tetapkan kode perintah 1.
  • Jalankan perintah.
  • Tunggu sampai perintah selesai.
  • Setel ulang status penyelesaian tim.
  • Baca data dari buffer dalam logika yang dapat diprogram.

Tes yang Diimplementasikan:

for (SectorAddress = 0; SectorAddress < 1048576; SectorAddress++)
{
	if ((SectorAddress % 1024) == 0)
	{
		xil_printf("Data read from %d sector \n\r", SectorAddress);
	}

	/** Set address */
	Xil_Out32(0x43c00008, SectorAddress);

	/** Set command */
	Xil_Out32(0x43c00004, 1);

	/** Start */
	Xil_Out32(0x43c00000, 1);

	/** Wait end of operation */
	for (;;)
	{
		status = Xil_In32(0x43c0000c);
		if (status == 0x01 || status == 0x03)
		{
			 if (status == 0x03)
			{
				xil_printf("Error in read \n\r");
			}
			break;
		}
		else
		{
			cntrDuration++;
			usleep(100);
		}
	}

	 /** Duration operation */
	 durationRead += cntrDuration;

	 if (cntrDuration > MaxRead )
	 {
		 MaxRead = cntrDuration;
	 }

	cntrDuration = 0x00;

	/** Clear start */
	Xil_Out32(0x43c00000, 0);

	/** Read data from PL */
	for (int32_t i = 0; i < 1024; i++)
	{
		DataR = Xil_In32(0x43c0001c);
		if (DataR != cntrData)
		{
			xil_printf("Data corrupt! \n\r");
		}
		DataR = Xil_In32(0x43c00020);
		cntrData++;
	}

	SectorAddress += 7;
}

Saat bekerja pada modul prosesor, algoritma penghapusan data adalah sebagai berikut:

  • Tetapkan alamat dalam kartu SD.
  • Tetapkan kode perintah 4.
  • Jalankan perintah.
  • Tunggu sampai perintah selesai.
  • Setel ulang status penyelesaian tim.

Tes yang Diimplementasikan:

for (SectorAddress = 0; SectorAddress < 1048576; SectorAddress++)
{
	if ((SectorAddress % 1024) == 0)
	{
		xil_printf("Data erase from %d sector \n\r", SectorAddress);
	}

	/** Set address */
	Xil_Out32(0x43c00008, SectorAddress);

	/** Set command */
	Xil_Out32(0x43c00004, 4);

	/** Start */
	Xil_Out32(0x43c00000, 1);

	/** Wait end of operation */
	for (;;)
	{
		status = Xil_In32(0x43c0000c);
		if (status == 0x01 || status == 0x03)
		{
			if (status == 0x03)
			{
				xil_printf("Error in write! \n\r");
			}
			break;
		}
		else
		{
			cntrDuration++;
			usleep(100);
		}
	}

	/** Duration operation */
	durationErase += cntrDuration;

	if (cntrDuration > MaxErase )
	{
		MaxErase = cntrDuration;
	}

	cntrDuration = 0x00;

	/** Clear start */
	Xil_Out32(0x43c00000, 0);

	SectorAddress += 7;
}

Uji sepenuhnya pada github.

4. Hasil


Jumlah dataBacaanMerekamMenghapus
1 blok (512 byte)4,7 Mbps1,36 Mbps0,58 Mbps
8 blok (4096 byte)15,4 Mbps6,38 Mbps4,66 Mbps
16 blok (8192 byte)18,82 Mbps11,26 Mbps9,79 Mbps

Kartu 16 GB digunakan. Selama pengujian, 2 GB data direkam, 2 GB data dibaca, dan 2 GB data dihapus.

Kesimpulannya mengecewakan. Saat menggunakan FPGA, tidak masuk akal untuk menggunakan kartu SD dalam mode SPI, kecuali untuk kasus ketika sangat diperlukan untuk menyimpan sejumlah besar data tanpa menunjukkan persyaratan kecepatan.

All Articles