Unduh konfigurasi ke FPGA melalui USB atau bongkar FTDI MPSSE
Kami menulis pemuat FPGA di LabVIEW. Bagian 1

Pada artikel pertama, kami menguji algoritma pemuatan pada C lama yang baik, di artikel kedua, kami menemukan cara mengatur program di LabVIEW dan mengimplementasikan antarmuka pengguna yang sederhana. Kali ini kami akan berkenalan dengan metode kerja baru di LabVIEW, menganalisis fitur-fitur penanganan kesalahan dan menyelesaikan proyek: kami menerapkan protokol untuk memuat file konfigurasi ke dalam FPGA.
Menangani kesalahan
Buka kode sumber, analisis fungsi MPSSE_open. Terlepas dari kesederhanaan algoritmik (fungsinya disebut satu demi satu), beberapa elemen D2XX API harus diimpor: FT_OpenEx
, FT_ResetDevice
, FT_Purge
, FT_SetUSBParameters
, FT_SetChars
, FT_SetTimeouts
, FT_SetLatencyTimer
, FT_SetFlowControl
, FT_SetBitMode
Seperti yang ditunjukkan pada artikel sebelumnya , impor fungsi dilakukan menggunakan simpul Call library Function
. Node ini memiliki terminal khusus untuk kontrol kesalahan. LabVIEW memiliki satu aturan sederhana: semua VI harus melacak kesalahan dan melaporkan kesalahan yang dikembalikan oleh terminal kesalahan. Sebagian besar built-in VIs sangat mengikutinya. Saya harap semua orang mengerti betapa pentingnya mengendalikan dan menangani kesalahan, terutama pada tahap debugging, tetapi ada alasan lain mengapa ini sangat penting sehingga tidak jelas bagi programmer "klasik". LabVIEW tidak memiliki urutan perangkat yang ketat dalam diagram blok: perangkat dieksekusi ketika data siap pada inputnya. Jika data dari output satu VI ditransfer ke input VI lain, maka jelas bahwa pada awalnya VI pertama akan berfungsi, hanya setelah itu yang kedua. Tetapi bagaimana jika tidak ada transfer data, dan VI melakukan tindakan independen? Tentu saja, Anda dapat menggunakan "Struktur Urutan Datar" yang rumit, tetapi jauh lebih nyaman untuk menghubungkan perangkat satu sama lain dengan sejumlah kesalahan.
Saat mengimpor fungsi D2XX, kami menemukan dua jenis kesalahan. Yang pertama - ini adalah kesalahan impor langsung - mengembalikan blok Call library Function
itu sendiri. Yang kedua adalah kesalahan dari perpustakaan itu sendiri, itu dikembalikan oleh hampir setiap fungsi melalui FT_STATUS
. Semua nilai yang mungkin dijelaskan sebagai enum di file header ftd2xx.h. Meskipun cukup untuk mengetahui bahwa nilai FT_OK
adalah tidak adanya kesalahan, dan semua nilai lainnya adalah kode kesalahan, saya ingin melacak tidak hanya fakta kesalahan itu sendiri, tetapi juga kesalahan apa yang terjadi dan di mana tepatnya itu terjadi.
Di LabVIEW, data kesalahan disebarkan melalui cluster error
. Ini adalah tipe data khusus yang didedikasikan; LabVIEW memiliki banyak VI dan fungsi untuk bekerja dengannya. Cluster kesalahan terdiri dari tiga elemen: variabel logis - menampilkan status, angka bertanda integer - kode kesalahan, string - sumber kesalahan. Status menunjukkan apakah kesalahan telah terjadi, kode kesalahan menentukan jenisnya dan digunakan oleh VI khusus untuk menghasilkan laporan. Baris ini memberikan gagasan yang lebih terperinci tentang di mana tepatnya kesalahan terjadi. LabVIEW menerima bahwa jika statusnya TRUE
, maka ini adalah kesalahan, jika statusnya FALSE
, tetapi kodenya bukan nol dan baris uraian tidak kosong, maka ini peringatan , jika statusnya FALSE
, kodenya nol dan garisnya kosong - tidak ada kesalahan.

LabVIEW berisi basis data internal di mana setiap kode kesalahan dikaitkan dengan deskripsinya. Untuk setiap jenis kesalahan, rentang nilai kode khusus dialokasikan. Misalnya, untuk kesalahan yang terkait dengan pengoperasian jaringan, beberapa rentang dialokasikan: dari β2147467263 hingga β1967390460, dari 61 hingga 65, dari 116 menjadi 118 dan 122, 1101, 1114, 1115, 1132 hingga 1134, dari 1139 hingga 1143 dan dari 1178 hingga 1185 Untuk kesalahan yang ditentukan pengguna, dua rentang dicadangkan dari β8999 hingga β8000 dan dari 5000 hingga 9999. Dari rentang ini, kita dapat memilih nilai untuk kode kesalahan pustaka D2XX.
Mari kita membuat VI yang menerima status fungsi D2XX sebagai input dan mengubah status ini menjadi cluster kesalahan LabVIEW. Sebagian besar fungsi dan VI di LabVIEW, setelah menerima status TRUE
pada input Error In
, tidak menjalankan kode mereka, tetapi mengirimkan informasi kesalahan ke terminal Error Out
. Ini memungkinkan Anda untuk secara efektif mentransfer informasi tentang sumber melalui seluruh rantai ke penangan kesalahan, menghilangkan eksekusi kode dalam mode darurat. Sangat diharapkan bahwa VI kita berperilaku sama.
Mari kita mengatur daftar status D2XX dalam bentuk enum
dan menempatkannya dalam tipe yang terpisah (dalam artikel sebelumnya kita melakukan ini dengan tipe FTDI).
Kami menyimpan VI baru dengan nama FT_error.vi. Kami menambahkan dua klaster Error In
dan Error Out
panel depan, Anda dapat menemukannya di panel "Array, Matrix & Cluster". Kami menghubungkan mereka ke terminal pada panel koneksi di sudut kiri bawah dan kanan bawah, masing-masing, sebagaimana telah disebutkan dalam artikel sebelumnya, ini adalah lokasi terminal aliran kesalahan yang diadopsi oleh LabVIEW. Kami menambahkan struktur Case
ke diagram blok, mengirimkan cluster Error In
ke input Case selector
, setelah itu struktur Case
berubah warna dan membagi dua sub-diagram: "No Error" - warna hijau, dan "Error" - warna merah. Di dalam kasus Error, kami mentransfer cluster kesalahan dari terminal pemilih langsung ke terowongan output di perbatasan kanan. Dan dalam kasus hijau, kami menambahkan Case
lain, tergantung pada statusnya, ia akan menentukan apakah akan membuat kesalahan (status tidak sama dengan FT_OK), atau membiarkannya apa adanya: lewati cluster kesalahan input untuk keluar tanpa mengubah.
Untuk mengubah secara teknis kode kesalahan menjadi sebuah cluster, Anda dapat menggunakan VI Error Cluster From Error Code VI
. SubVI ini menambahkan rantai panggilan ke deskripsi kesalahan, sehingga kami dapat menentukan tidak hanya apa yang terjadi, tetapi juga di mana itu terjadi.
Untuk memilih teks yang sesuai dengan status input (FT_Status), gunakan blok properti: pilih "RingText.Text". Teks kesalahan dikirim ke input error message
dari Error Cluster From Error Code VI
.
Jangan lupa menggambar ikon "berbicara".
FT_error.vi
Panel sub-instrumen depan (depan)

Diagram blok. Kesalahan input

Diagram blok. Tidak ada kesalahan pada input dan statusnya adalah FT_OK

Diagram blok. Tidak ada kesalahan pada input, tetapi statusnya berbeda dari FT_OK
Untuk menguji FT_error, Anda dapat membuat VI kosong, tambahkan VI yang dibuat di sana, dan lihat bagaimana nilainya akan berubah saat startup jika berbagai status diterapkan.
Tes FT_error.vi
Panel depan (depan) perangkat

Diagram blok
Sekarang, setelah panggilan fungsi apa pun dari API D2XX, kami akan menggunakan SubVI FT_error.vi. Sekelompok kesalahan akan melewati semua VI di seluruh hierarki panggilan.
Di VI tingkat atas, kita harus memutuskan apa yang harus dilakukan dengan kesalahan yang terdeteksi: Anda dapat menampilkan pesan di kotak dialog, menulisnya ke file laporan, mengabaikannya, atau cukup "diam-diam" mengakhiri aplikasi. Kotak dialog adalah cara termudah dan terpopuler untuk melaporkan kesalahan. Ini juga nyaman untuk programmer pemula, karena tidak ada yang bisa dilakukan. Di setiap VI, mode penanganan kesalahan otomatis diaktifkan secara default ( Mengaktifkan penanganan kesalahan otomatis , terletak di kategori Eksekusi di menu VI Properties). Ia bekerja seperti ini: jika di beberapa node terminal keluaran Error Out
tidak terhubung di mana saja, dan kesalahan terjadi di node ini, maka LabVIEW menjeda aplikasi dan menampilkan kotak dialog. Jika terminal Error Out
node terhubung, maka aliran kesalahan merambat seperti yang diprogram, dan tidak ada tindakan tambahan terjadi. Namun, jendela pesan dapat dipanggil secara terprogram, untuk ini Anda perlu menggunakan General Error Handler
dan Simple Error Handler
VIs (terletak di panel Dialog & Antarmuka Pengguna). Dalam hal ini, kita dapat menggunakan informasi kesalahan untuk menyelesaikan program. Dalam diagram blok, terlihat seperti ini:

Gambar yang dapat diklik
Ketika kesalahan terjadi, program akan ditangguhkan, jendela laporan akan muncul, setelah menutup jendela, program akan keluar dengan benar.
Buka dan tutup FTDI
Jadi, kembali ke fungsi MPSSE_open
. Buat VI baru. Pertama-tama, tambahkan terminal untuk aliran kesalahan. Tambahkan struktur pilihan dan pilih input Error In
pada pemilih. Dalam kasus hijau, kita mengimpor fungsi dalam urutan dan dengan parameter seperti pada prototipe Sishny. Semua node dari Call Library Function Node
terhubung dalam rantai oleh aliran kesalahan. Dalam kasus merah melalui terowongan kita menghubungkan Error In
dengan terminal output dari kesalahan.

Gambar yang dapat diklik

VI MPSSE_open.vi
Baris dengan deskripsi FTDI ( Description
) dikirim ke input SubVI, pada output - Handle
dan chip FTDI yang diinisialisasi dalam mode MPSSE.
Mari kita membuat VP yang selesai bekerja dengan FTDI dan Anda sudah dapat memeriksa kinerja pada perangkat keras.
FT_Close.vi
Diagram blok

Panel depan
Pada artikel sebelumnya, untuk debugging antarmuka, kami membuat rintisan VI SP_FT_MPSSE_FPGA.vi, sekarang saatnya untuk mengisinya. Tambahkan MPSSE_open.vi dan FT_Close.vi ke diagram bloknya. Pada tahap ini, agak sulit untuk menilai apakah inisialisasi itu benar, namun, nilai Handle
bukan nol pada output MPSSE_open.vi dan tidak adanya kesalahan akan memberi tahu kami banyak.

Diagram Alir SP_FT_MPSSE_FPGA.vi
Untuk melihat nilai Handle
Anda dapat menggunakan "Jendela Probe Watch". Ini adalah alat debugging yang nyaman yang memungkinkan Anda untuk menampilkan nilai data pada setiap (hampir semua) kawat selama eksekusi perangkat. Untuk mengatur sampel pada baris, Anda harus memilih "Probe" di menu konteks dari baris ini. Jendela "Probe Watch Window" akan terbuka, dan nomor dengan nomor sampel akan muncul di telepon. Pada gambar di atas adalah "3".
Jendela tontonan pemeriksaan
Pada garis Handle, nilainya 698389336
Hebat! Kami mulai VI tingkat atas, hubungkan papan debug ke komputer. Deskripsi chip FTDI yang terhubung muncul di daftar "Select a device", klik tombol "Program" dan ... tidak ada yang terjadi. Hanya di jendela "Probe Watch" nilai Handle
muncul. Dan itu bagus.
Kami mematikan papan, daftar perangkat dihapus. Klik "Program." Di sinilah jendela laporan kesalahan muncul.
Setelah mengklik tombol "Lanjutkan", VI menyelesaikan tugasnya.
Dilarang menekan tombol jika tidak ada perangkat yang ditemukan. Kami memodifikasi penangan acara case "Timeout". Biarkan saya mengingatkan Anda bahwa chip FTDI yang terhubung ke PC dipindai dua kali per detik, jika terdeteksi dan dapat digunakan untuk memprogram FPGA, maka deskriptornya akan ditambahkan ke Devices list
melalui properti Strings[]
. Kami membuat properti Disabled
untuk "Pemrograman", dan jika tidak ada perangkat yang cocok ditemukan, maka matikan dan gelap tombol.
Batas waktu kasus
Gambar yang dapat diklik
Menguasai GPIO
Setelah MPSSE diaktifkan, bekerja dengannya dilakukan melalui apa yang disebut "op-code", dan hanya FT_Write
, FT_Read
, dan FT_Queue
yang digunakan dari fungsi FT_Write
API (untuk mengetahui status buffer penerima). Kami membuat VI yang sesuai di sepanjang jalur yang kami buat: FT_Write.vi, FT_Read.vi, FT_Queue.vi.
Sedikit rutin
FT_Write.vi

Diagram blok. FT_Write.vi

FT_Read.vi

Diagram blok. FT_Read.vi

FT_Queue.vi

Diagram blok. FT_Queue.vi
Sekarang dari tiga batu bata ini kita mengeluarkan VI untuk membaca port paralel dan menulis untuk itu. Nilai tersebut direpresentasikan sebagai array variabel Boolean.
MPSSE_Set_LByte.vi dan MPSSE_Get_LByte.vi
MPSSE_Set_LByte.vi

Diagram blok. MPSSE_Set_LByte.vi

MPSSE_Get_LByte.vi

Diagram blok. MPSSE_Get_LByte.vi
Saya akui saya malas membuat daftar nama untuk semua kode-op, jadi saya meninggalkannya dalam bentuk Angka Ajaib.
Sebagaimana dinyatakan dalam artikel pertama, protokol boot Pasif Serial FPGA tidak lebih dari SPI dengan manipulasi flag tambahan. Total lima kaki digunakan: garis DCLK , DATA [0] , nCONFIG harus dikonfigurasi sebagai keluaran, garis nSTATUS , CONF_DONE sebagai input.
Tata letak meja pinoutPin FPGA | Nama pin | Pin | MPSSE | Arahan | standar |
---|
DCLK | BDBUS0 | 38 | TCK / SK | Keluar | 0 |
DATA [0] | BDBUS1 | 39 | TDI / DO | Keluar | 1 |
nCONFIG | BDBUS2 | 40 | TDO / DI | Keluar | 1 |
nSTATUS | BDBUS3 | 41 | TMS / CS | Masuk | 1 |
CONF_DONE | BDBUS4 | 43 | GPIOL0 | Masuk | 1 |
Kami membutuhkan VP yang dapat mengubah nilai pada leg yang dipilih tanpa memengaruhi yang lainnya. Pertama-tama, buat Enum
dengan nomor seri dari kaki di port, simpan sebagai "Ketik Jenis Def" ke file SP_LBYTE_BITS.ctl. Kami membuat VI baru, tambahkan terminal aliran kesalahan yang sudah dikenal. Kami membaca nilai saat ini dari port paralel menggunakan MPSSE_Get_LByte.vi, gunakan fungsi Replace Array Subset
untuk memodifikasi bit yang diinginkan dan menulis nilai kembali ke port (MPSSE_Set_LByte.vi).
SP_Set_Flag.vi
SP_Set_Flag.vi

Diagram blok. SP_Set_Flag.vi

Enum SP_LBYTE_BITS.ctl
Untuk memulai konfigurasi, MPSSE harus menghasilkan transisi rendah ke tinggi pada baris nCONFIG . Segera setelah FPGA siap menerima data, FPGA itu akan membentuk level tinggi di jalur nSTATUS . Pada tahap ini, semuanya siap untuk percobaan dengan besi. Pada diagram blok SP_FT_MPSSE_FPGA.v kita menambahkan baris kontrol nCONFIG - setelah inisialisasi MPSSE kita memberikan level rendah, dan kemudian tinggi. Setelah setiap operasi (untuk debugging) kami membaca status kaki porta.
SP_FT_MPSSE_FPGA.vi
Saat startup

Diagram blok
Secara umum, selama peluncuran VI, jelas bahwa FPGA merespons transisi pada garis nCONFIG - nol diatur pada kaki nSTATUS , dan kemudian satu. Tetapi tidak akan berlebihan untuk memonitor ini dengan osiloskop. Hampir semua osiloskop dua saluran dengan pemicu pemicu (siaga) cocok. Saluran A (jalur biru) saya letakkan di titik kontrol sirkuit nCONFIG , saluran B (jalur merah) - rantai nSTATUS . Pemicu diatur ke tepi jatuh saluran A.

Gambar bisa diklik. Dengan detail!
Bekerja dengan file
FPGA siap menerima file konfigurasi. Apakah kami siap mentransfer file ke FPGA?
LabVIEW berisi seperangkat alat yang luas untuk bekerja dengan file. Saya tidak bisa mengatakan bahwa fungsinya cukup untuk semua tugas, tetapi operasi dasar seperti membaca dan menulis dilakukan dengan mudah dan menyenangkan. Perangkat dasar VI untuk bekerja dengan file dapat ditemukan di panel "File I / O". Untuk menyelesaikan masalah, Anda perlu membuka file konfigurasi, mengevaluasi ukurannya (kita perlu tahu berapa byte untuk mengirim FPGA), membacanya dan menutupnya. Semuanya sederhana dan satu demi satu. Kami menggunakan Open/Create/Replace File
, Get File Size
, Read from Binary File
, Close File
refnum
, gabungkan dengan rantai aliran kesalahan dan refnum
- nomor, seperti deskriptor file, dibuat ketika file dibuka dan harus ditransfer ke input dari VI lain yang bekerja dengan file ini.
Sejauh ini, kita tidak punya tempat untuk membuang data yang dibaca, tetapi jika Anda benar-benar ingin memeriksa operabilitas rantai, Anda dapat membuat indikator tipe String
dan mengaturnya sedikit. Dalam menu konteks, aktifkan opsi "Tampilan Hex", nyalakan bilah gulir vertikal (Item Terlihat -> Bilah Gulir Vertikal) dan setelah peluncuran kami mengamati konten file konfigurasi biner.
SP_FT_MPSSE_FPGA.vi
Panel depan Kami melihat isi file

Diagram blok. Karinka dapat diklik
Dua garis paralel independen dari kode yang dibentuk pada diagram blok VI, oleh karena itu, rantai kesalahan terpisah digunakan untuk mereka. Untuk mengurangi aliran paralel menjadi satu terminal Error Out
, fungsi Merge Errors
digunakan. Fungsi ini mencari kesalahan input dari atas ke bawah (ya, mungkin ada lebih dari dua terminal input, itu diregangkan oleh mouse) dan mengembalikan yang pertama ditemukannya. Jika tidak ada kesalahan, itu mengembalikan pesan peringatan pertama. Jika tidak ada peringatan, maka tidak ada kesalahan pada output. Penting untuk dicatat bahwa urutan koneksi input Merge Errors
menentukan prioritas kesalahan, dan jika kesalahan terjadi segera dalam dua rantai, kesalahan yang lebih rendah akan diabaikan. Ini harus diperlakukan dengan hati-hati.
Jika kita mencoba menekan tombol "Program" di VI tingkat atas tanpa memilih file, maka input SP_FT_MPSSE_FPGA.vi akan menerima jalur kosong, yang akan menyebabkan kesalahan "Kesalahan 1430. LabVIEW: (Hex 0x596) Path kosong atau relatif. Anda harus menggunakan jalan absolut. " Seperti yang dikatakan teman masa kecil saya: "Trifles, ini adalah sesuatu yang duniawi!" Dan kesalahan ini sama sekali bukan kesalahan, tapi ketidaktahuan pengguna. Kami tidak akan menghentikan program dan bersumpah dengan jendela dengan palang merah, kami cukup menghapus kesalahan dengan kode ini dari aliran dan di kotak dialog kami menyarankan pengguna untuk memutuskan file. Untuk memfilter kesalahan, gunakan VI "Hapus Kesalahan" dari palet "Dialog & Antarmuka Pengguna". Untuk menampilkan pesan - "Dialog Satu Tombol".

Diagram blok
Gambar yang dapat diklik
Konfigurasi unduhan
Untuk transfer data serial, prosesor MPSSE perlu mengirim kode-kode 0x18, argumen perintah akan menjadi panjang dari urutan yang ditransmisikan (dua byte, dimulai dengan yang terendah), dan urutan data itu sendiri. Panjangnya dikodekan minus satu. Mari kita kirim blok data sebagai VI MPSSE_send.
MPSSE_Send.vi
MPSSE_Send.vi

Diagram blok
Ukuran buffer input ( Array Size
) dikonversi menjadi tipe byte ganda U16
, kami kurangi satu, swap byte rendah dan tinggi ( Swap Bytes
) - Anda perlu mengirim panjang mulai dari yang terendah, dan mengonversi nomor byte ganda ke array byte tunggal ( Type Cast
).
Fungsi Type Cast
perlu mendapat perhatian khusus. Ini adalah konverter tipe universal, kecerdikannya terkadang sangat mengejutkan. Singkatnya, lalu:

Secara visual untuk programmer
Namun, ini bukan hanya menuang data ke tipe yang berbeda, tetapi juga interpretasi heuristik. Fungsi ini memungkinkan Anda untuk melakukan konversi antara tipe data yang tidak kompatibel, sementara fungsi tersebut tidak ragu untuk menyelaraskan data input dan bahkan menghapus bagian "ekstra". Jika tipe data yang diminta membutuhkan lebih banyak memori daripada data input, maka fungsi akan mengalokasikan jumlah yang hilang. Untuk pengembang pemula, LabVIEW Type Cast
dapat menjadi penyelamat, tetapi dengan tumbuh dewasa, lebih baik untuk menolak konverter seperti itu - sangat banyak tersembunyi dari mata dan dapat menjadi sumber kesalahan yang tidak terduga. Lebih baik menggunakan metode konversi yang lebih eksplisit, seperti Coerce To Type
.
Saat menginisialisasi prosesor MPSSE, kami menetapkan ukuran buffer maksimum yang diijinkan untuk transfer data ke 65536 byte, oleh karena itu, kami harus membagi file konfigurasi menjadi fragmen yang ukurannya tidak melebihi ukuran yang ditentukan. Kami akan menggunakan fungsi Array Subset
, fungsi ini memilih subarray dari array yang dimulai dengan elemen index
dan length
. Kami akan memecahnya dalam loop While
, kami akan meningkatkan setiap iterasi indeks dengan 65536, antara iterasi kami akan melewati nilai melalui register geser. Segera setelah tidak mungkin untuk mencubit 65536 byte dari array utama, kami mengambil semua yang tersisa, mengirimnya dan menghentikan siklus.
Menurut protokol pengunduhan, setelah semua data ditransfer, dua pulsa clock lagi harus diterapkan untuk memulai inisialisasi FPGA. Untuk melakukan ini, setelah loop, kami mengirim byte "kosong".
SP_FT_MPSSE_FPGA.vi
Gambar yang dapat diklik
Untuk memahami keberhasilan firmware, kami mempertimbangkan bendera, dan jika CONF_DONE disetel ke satu, kami melaporkan tingkat atas VI bahwa semuanya baik-baik saja.
Program selesai. Tetap memastikan bahwa FPGA berhasil di-flash, dan board berkedip bahagia dengan LED.
Tentang Penamaan VP
, , LabVIEW, , SubVI. . :
- β , FTDI, API D2XX. "FT", FT_Close.vi FT_Read.vi.
- β MPSSE. "MPSSE". : MPSSE_open.vi, MPSSE_Set_LByte.vi, MPSSE_Get_LByte.vi.
- β "Passive Serial" MPSSE. "S". , SP_FT_MPSSE_FPGA.vi ( , ) SP_LBYTE_BITS.ctl.
- . . , .
( ), . subVI .
Kesimpulan
, , .
, LabVIEW, . , , , ( ). .
- . LabVIEW: . Per. . . .β .:
, 2008 β 400 .: . - labview_mpsse . .
- .
- Software Application Development D2XX Programmer's Guide . API D2XX.