Cara Mendekode Sinyal Seri Non-Standar dengan Efisien

11

Saya adalah anggota sarjana dari tim peneliti yang mengerjakan proyek yang melibatkan ASIC pemancar RF, dan penerima nirkabelnya yang pada akhirnya harus mengirim data ke PC.

Receiver mengeluarkan sinyal serial non-standar yang cepat , kontinu, asinkron, dan tidak standar (mis. Bukan SPI, I2C, UART, dll.) Sehingga tugas saya adalah menulis perangkat lunak mikrokontroler untuk menghubungkan penerima ke komputer. Saat ini pendekatan saya adalah menggunakan interupsi terpicu tepi untuk menempatkan data dalam buffer melingkar dan melakukan seluruh proses decoding bit-by-bit dalam loop utama. Mikrokontroler harus secara bersamaan menampilkan data ini menggunakan USB (virtual com port) ke komputer.

Ini adalah masalah yang saya alami, dan satu yang saya antisipasi:

  1. Saya tidak dapat memproses data yang disangga cukup cepat bahkan dengan prosesor ARM Cortex M3 72 MHz saya yang cukup kuat. Bitrate adalah 400 Kbps (2,5 us / bit). Untuk referensi yang hanya menyisakan 180 siklus per bit (termasuk decoding DAN ISR, yang memiliki ~ 30 siklus overhead aduh!). MCU juga harus menangani banyak tugas lain yang akan dipilihnya dalam loop utama.

  2. Driver port virtual USB virtual juga berbasis interupsi. Ini membuat saya hampir yakin bahwa driver pada akhirnya akan memiliki prosesor terganggu begitu lama sehingga melewatkan jendela 2,5 mikrodetik (180 siklus) di mana sedikit dapat ditransmisikan. Saya tidak yakin bagaimana interupsi konflik / ras seperti ini biasanya diselesaikan.

Jadi pertanyaannya adalah sederhana, apa yang mungkin dilakukan seseorang untuk menyelesaikan masalah ini atau apakah ini bukan pendekatan yang benar? Saya bersedia mempertimbangkan lebih sedikit pendekatan yang berfokus pada perangkat lunak. Misalnya, menggunakan chip USB khusus dengan semacam mesin keadaan perangkat keras untuk decoding, tetapi ini adalah wilayah yang tidak dikenal.

Keegan Jay
sumber
Saya harus mengatakan, jarang saya melihat bahwa banyak saran yang saya suka menjawab dengan cepat, berbicara dengan baik untuk pertanyaan Anda. Saya akan tertarik untuk mengetahui lebih banyak tentang data burts. Apakah mereka meledak, tiba-tiba kecepatan penuh dan kemudian periode data rendah atau masuk akal Anda akan pergi periode yang diperpanjang dengan data kontinu?
Kortuk
Selama ASIC memiliki kekuatan, ASIC mengirimkan aliran data yang berkelanjutan. Sama sekali tidak meledak. Ini adalah aplikasi penginderaan medis real-time dengan pembacaan komputer. Pernah melihat EKG?
Keegan Jay
Begitu banyak jawaban bagus di sini. Saya melihat kesenjangan yang jelas antara solusi yang melibatkan perubahan pada interupsi, dan solusi yang melibatkan perangkat keras / logika digital khusus. Hal-hal seperti FPGA dan Verilog yang saya kenal, tetapi belum berpengalaman sehingga ini berarti mereka harus diselamatkan untuk jangka panjang. Dalam jangka pendek @rocketmagnets, metode interrupt-heavy yang lebih sedikit baik-baik saja. Saya suka keanggunan dari tugas-tugas kasar untuk logika digital dan menyimpan ARM untuk perhitungan yang benar. Di masa depan kekuatan ARM akan digunakan untuk analisis dan penyaringan data serial nirkabel.
Keegan Jay
Apakah sinyalnya sinkron atau tidak sinkron?
markrages
Tidak sinkron. 4 bit awal, 10 bit data, 2 bit stop. Karena sifat ASIC yang mentransmisikan, waktu HI dan LO sangat bervariasi dari chip ke chip. Saya sudah menulis algoritma untuk menyimpulkan baud rate.
Keegan Jay

Jawaban:

5

Jawaban lain: Berhenti menggunakan interupsi.

Orang-orang melompat untuk menggunakan interupsi terlalu mudah. Secara pribadi, saya jarang menggunakannya karena mereka sebenarnya menghabiskan banyak waktu, seperti yang Anda temukan.

Seringkali mungkin untuk menulis loop utama yang mensurvei segalanya dengan sangat cepat sehingga latensinya masih dalam spesifikasi, dan sangat sedikit waktu yang terbuang.

loop
{
    if (serial_bit_ready)
    {
        // shift serial bit into a byte
    }

    if (serial_byte_ready)
    {
        // decode serial data
    }

    if (enough_serial_bytes_available)
    {
        // more decoding
    }        

    if (usb_queue_not_empty)
    {
        // handle USB data
    }        
}

Mungkin ada beberapa hal dalam loop yang terjadi jauh lebih sering daripada yang lain. Mungkin bit yang masuk misalnya, dalam hal ini, tambahkan lebih dari tes tersebut, sehingga lebih banyak prosesor didedikasikan untuk tugas itu.

loop
{
    if (serial_bit_ready)
    {
        // shift serial bit into a byte
    }

    if (serial_byte_ready)
    {
        // decode serial data
    }

    if (serial_bit_ready)
    {
        // shift serial bit into a byte
    }

    if (enough_serial_bytes_available)
    {
        // more decoding
    }        

    if (serial_bit_ready)
    {
        // shift serial bit into a byte
    }

    if (usb_queue_not_empty)
    {
        // handle USB data
    }        
}

Mungkin ada beberapa peristiwa di mana latensi pendekatan ini terlalu tinggi. Misalnya, Anda mungkin memerlukan acara dengan waktu yang sangat akurat. Dalam hal ini, buat acara itu di interupsi, dan miliki semua yang lainnya di loop.

Roket
sumber
Saya suka jawaban Anda lebih dari jawaban orang Rocketmagnet lainnya. Alih-alih lebih banyak hadrware, lebih cepat perangkat keras, lebih banyak dari yang lain, Anda Rocketmagnet, menyarankan: lakukan lebih sedikit, lebih baik, lebih sederhana.
Oke, saya telah melihat banyak kasus yang terputus membuat solusi jauh lebih baik. Mereka melakukan hal-hal hebat, memungkinkan kode terstruktur dengan baik, latensi rendah dan banyak keuntungan lainnya, tetapi saya harus setuju dengan Anda di sini. Sepertinya prosesnya sangat intens 1 pengontrol mungkin perlu mendedikasikan setiap bit perhatiannya untuk menangani aliran serial. Digital front end kedengarannya ideal untuk saya, tetapi berkali-kali Anda memiliki beberapa micros dan tidak ada FPGA di sekitar ketika itu adalah proyek sekolah, saya mungkin akan mendedikasikan mikro untuk menanganinya untuk saya terlebih dahulu dan mencoba memasukkan FPGA nanti untuk menggantikannya untuk biaya.
Kortuk
Ini mungkin solusi yang akan saya gunakan dalam jangka pendek. Saya berharap untuk menghindari ini karena itu melibatkan menulis ulang sedikit dari driver serial yang ada, tetapi ini adalah solusi elegan yang ada dalam kemampuan saya selama jangka waktu yang singkat.
Keegan Jay
1
@JayKeegan - Ya, itu mungkin rute tercepat ke solusi. PSoC dan FPGA mungkin menjadi pendekatan untuk proyek selanjutnya.
Rocketmagnet
6

Anda mungkin bisa menggunakan FPGA dan bukannya Mikrokontroler untuk memecahkan kode dan buffer datastream nirkabel. Kemudian gunakan prosesor ARM untuk menyiram buffer FPGA (misalnya menggunakan antarmuka SPI) dan mengirimkan konten keluar dari port USB Comm. Ini bekerja, tetapi FPGA harus dapat menjaga dengan mudah selama Anda bisa sering memperbaikinya untuk memastikan bahwa buffer perangkat kerasnya tidak dibanjiri (atau jika Anda dapat menangani data yang terjatuh di tingkat protokol yang lebih tinggi) ).

vicatcu
sumber
Ini bisa menjadi solusi yang sangat baik dalam jangka panjang. Saya berharap saya menerima banyak solusi logika / perangkat keras digital selain solusi perangkat lunak karena sekarang saya punya alasan untuk mempelajari hal-hal ini! Sayangnya saya belum memiliki pengalaman dengan FPGA.
Keegan Jay
6

Mudah: Gunakan Mikrokontroler PSoC5 .

PSoC

Anda memiliki semua kemudahan penggunaan mikrokontroler, plus itu berisi CPLD, sehingga Anda dapat menulis periferal perangkat keras Anda sendiri di Verilog. Cukup tulis dekoder data serial Anda di Verilog, dan gunakan DMA untuk mengalirkannya ke port USB.

Sementara itu, inti ARM 32-bit yang kuat dapat memutar-mutar instruksinya.

Roket
sumber
Halaman ikhtisar tidak mencantumkan frekuensi jam, yang menimbulkan kecurigaan saya. Datasheet mengatakan 40MHz (Saya juga mencatat 6mA pada 6MHz). Itu setengah dari yang dimiliki OP sekarang. "MCU juga harus menangani banyak tugas lain", jadi itu mungkin tergantung pada apakah itu adalah ide yang bagus atau tidak.
stevenvh
Mereka naik ke 67MHz. Jadi hampir secepat prosesor OP saat ini, kecuali bahwa sebagian besar pekerjaan akan dilakukan dalam perangkat keras, meninggalkan CPU dengan lebih banyak waktu luang.
Rocketmagnet
1
Saya tidak melihat semua lembar data. Yang pertama saya pilih kata 40MHz.
stevenvh
@stevenvh - Mereka memiliki nilai kecepatan yang berbeda. Angka ketiga di PN adalah kelas kecepatan. (4 = 48MHz, 6 = 67MHz).
Rocketmagnet
1
Ini juga merupakan solusi yang fantastis dalam jangka panjang, mirip dengan ide FPGA. Saya belum pernah mendengar jenis chip ini tetapi membawa banyak fungsi di seluruh papan saya menjadi satu chip. Di masa depan, ini bisa berarti seluruh receiver cocok dengan ukuran sebesar thumb drive, yang merupakan visi pemimpin proyek saya. Saya akan belajar semileter Verilog berikutnya.
Keegan Jay
4

Saya pikir Anda memiliki pilihan rekayasa klasik untuk dibuat: cepat, murah, bekerja: pilih dua.

Solusi @ vicatcu tentu saja bagus, tetapi jika Anda tidak dapat atau tidak akan menambahkan lebih banyak perangkat keras ke dalamnya (dan ini termasuk prosesor yang lebih cepat) maka Anda harus membuat pilihan. Jika tautan serial ini adalah yang paling penting daripada Anda harus duduk di ISR ​​sampai semua bit telah dikumpulkan. 180 instruksi per bit sebenarnya tidak buruk sama sekali, tetapi jangan mencoba melakukan semuanya. Saat Anda mendeteksi awal transfer, putar hingga transfer selesai. Masukkan hasilnya ke dalam FIFO dan lanjutkan pemrosesan normal.

Anda tidak mengatakan berapa lama masing-masing transmisi tetapi jika mereka pendek dan meledak ini akan menjadi solusi yang layak. Saya berani bertaruh bahwa implementasi port COM virtual Anda memiliki beberapa buffering perangkat keras juga, jadi layanan interupsi "laggy" untuk itu seharusnya tidak menimbulkan terlalu banyak masalah. Sejauh apa yang perlu dilakukan MCU ... Anda memiliki beberapa keputusan desain untuk dibuat.

akohlsmith
sumber
Solusi ini melengkapi pendekatan peranti lunak rocketman dengan mengurangi jumlah driver berbasis interupsi. Saya dapat menyimpan driver serial utama yang saya sebutkan sebagai berbasis interrupt. Saya juga akan mencoba memutar sampai seluruh frame terbaca seperti yang Anda sebutkan.
Keegan Jay
3

Pertama-tama, saya sudah menyukai beberapa jawaban di sini, dan beberapa sudah mendapatkan suara saya.

Tetapi hanya dengan melemparkan solusi lain yang mungkin: mengingat kendala dari proyek Anda, apakah menambahkan mikrokontroler kedua akan menjadi buruk (akankah itu melibatkan board run lain)? Mungkin mikrokontroler 8-bit sederhana yang terhubung ke Cortex-M3 Anda melalui perangkat cepat seperti SPI. Pengontrol 8-bit pilihan Anda akan mengumpulkan bit dan membentuk byte seperti pada jawaban yang dipilih, tetapi ketika itu memiliki byte, itu bisa membuangnya ke register data SPI untuk mentransfer.

Sisi korteks-M3 hanya akan mengganggu data SPI yang diterima. Yang memotong interupsi dipicu tepi eksternal 400 KHz Anda sebelumnya menjadi 50 KHz.

Dua alasan mengapa saya menyarankan ini adalah karena beberapa metode lain (PSoC atau menambahkan FPGA) agak mahal (walaupun ini mungkin tidak masalah untuk proyek akademik volume rendah) dan karena mungkin memungkinkan Anda untuk melestarikan beberapa struktur kode Anda saat ini.

Selain itu, saya pikir ide PSoC mengagumkan dengan perangkat kustom Anda sendiri mentransfer melalui DMA ke USB.

Jon L
sumber
Ini sebenarnya rencana yang ada dalam pikiran saya tepat di sekitar posting ini. Jika saya tidak dapat merampingkan perangkat lunak dengan mengurangi ketergantungan pada interupsi (jawaban yang dipilih) daripada pasti ini yang akan saya lakukan. Tapi ya itu akan membutuhkan papan menjalankan lagi, mungkin dua karena saya payah mendapatkan desain saya yang benar pertama kali.
Keegan Jay
@JayKeegan, haha ​​selamat datang di klub!
Jon L
2

Jika format data Anda mirip dengan UART, tetapi pada kecepatan baud yang tidak dapat diprediksi-namun-konsisten, kecenderungan saya adalah menggunakan CPLD untuk mengubah setiap kata dari data yang masuk menjadi format SPI atau standar-async. Saya tidak berpikir ada kebutuhan untuk mendorong sepenuhnya ke ranah CPLD. Sebenarnya, bahkan logika diskrit mungkin hampir bisa diterapkan. Jika Anda bisa menghasilkan jam yang smidgin lebih dari 5x kecepatan data yang Anda inginkan, Anda bisa menggunakan penghitung dibagi lima dan pembagian 16 dengan beberapa gerbang. Atur penghitung divide-by-lima sehingga akan disimpan di reset setiap kali input idle dan penghitung divide-by-16 adalah nol. Kalau tidak, hasilkan pulsa clock SPI dan tumbuk penghitung divide-by-16 kapan saja penghitung divide-by-five mencapai 2.

Mengingat jam 5x, orang dapat menghasilkan jam SPI menggunakan 16V8 (perangkat logika diprogram yang terkecil dan termurah yang tersedia saat ini). 16V8 atau 22V10 kedua dapat digunakan sebagai pembagi tingkat fraksional untuk menghasilkan jam 5x, atau orang dapat menggunakan chip yang sedikit lebih besar (CPLD) dan melakukan semuanya dalam satu.

Edit / Addendum

Atas pertimbangan lebih lanjut, jika seseorang akan menggunakan CPLD, orang dapat dengan mudah menambahkan beberapa perangkat tambahan ke sirkuit. Sebagai contoh, seseorang dapat dengan mudah menambahkan logika untuk memiliki rangkaian stall sampai ia menerima setidaknya 1,5 bit kali stop bit, diikuti oleh 3,5 bit kali bit mulai; jika menerima bit start yang terlalu pendek, ia harus kembali mencari bit stop. Juga, jika seseorang menggunakan SPI, seseorang dapat menggunakan sinyal / CS untuk memastikan bahwa perangkat penerima akan melihat data yang dibingkai dengan benar. Jika perangkat yang menerima data SPI dapat menangani frame 10-bit, orang dapat mengirim frame tersebut secara langsung. Jika tidak, setiap frame sepuluh-bit dapat dikirim sebagai frame 8-bit dengan set LSB (7 bit data), dan sebuah frame dengan semua LSB's clear (3 bit data); jam SPI akan dipercepat selama bit-bit berhenti sehingga semua data akan dikirim.

Beberapa mikrokontroler memiliki modul pembangkitan PWM yang agak serba guna yang mencakup hal-hal seperti kemampuan untuk diatur ulang oleh sinyal eksternal, dan menyinkronkan pengaturan waktunya dengan pelepasan sinyal semacam itu. Jika mikrokontroler Anda dapat melakukannya, tergantung pada fitur tepatnya, yang mungkin sangat menyederhanakan CPLD atau sirkuit penghasil waktu.

Pendekatan lain yang agak disentuh Rocketmagnet, adalah memiliki mikro kecil yang tujuan utamanya adalah untuk memecahkan kode data serial dan mengubahnya menjadi format yang dapat digunakan oleh mikro utama. Kecepatan data 400KHz Anda cukup cepat untuk decoding perangkat lunak, tetapi sesuatu seperti PIC bisa menanganinya jika tidak harus melakukan hal lain pada saat yang sama. Bergantung pada perangkat apa yang Anda kenal, ini bisa lebih mudah atau lebih sulit daripada menggunakan CPLD.

supercat
sumber
Ini semua akan sangat berharga ketika merancang logika digital untuk decoding. Saya memang akan menghasilkan sebagai SPI. Untuk saat ini, saya hanya melakukan decoding menggunakan MCU mandiri (batasan waktu). Terima kasih!
Keegan Jay