
Ini adalah artikel (pengantar) pertama dalam seri tentang bagaimana saya akan memperbaiki sistem media mobil. Proyek itu sendiri sedang dalam proses, tidak ada waktu, seperti orang lain, oleh karena itu, pembaca yang budiman, harap bersabar, karena saya sering tidak berjanji untuk memusatkan artikel.
Semuanya dimulai dengan fakta bahwa saya memiliki Prius.
Dan hal pertama yang menarik perhatian saya adalah masalah dengan memperbarui navigasi. Berikut ini sangat sedikit, tetapi di beberapa tempat diperlukan fitur perangkat yang disebut "Tampilan Multifungsi" (pada orang umum - kepala). Dan ini bertentangan dengan latar belakang sejumlah besar radio China dengan Android, dan banyak fasilitas lainnya. Tetapi pemasangan mereka di tempat biasa menyiratkan tidak adanya "roti" seperti diagram distribusi energi dan kontrol iklim.
Gagasan itu lahir untuk menghubungkan radio Android dengan mobil lebih erat dari yang disarankan saudara-saudara Tiongkok. Tentang ini dan artikelnya.
Situasi awal
Jadi Di papan ada sekitar layar 7 inci dengan layar sentuh resistif, terhubung ke elektronik lainnya dengan saluran TX + dan TX-. Dan sudah ada 3 pasang dari kepala. Di sirkuit, keajaiban ini bernama AVC-LAN, dan terlihat seperti ini:

Bagian 1: Melihat sekeliling
Seperti yang Anda lihat, head berada di celah jaringan, antara router dan rantai radio, amplifier (saya memilikinya secara terpisah), dan saluran terpisah harus dihubungkan ke unit navigasi. Di tempat lain, unit parkir mobil menggantung, tidak disebutkan dalam skema saya. Baiklah, ya ... Saya memutuskan untuk menunda kedekatan dengannya sampai waktu yang lebih baik. Selain itu, parkir lebih merupakan fungsi permainan daripada kebutuhan nyata.
Setelah menghapus semua yang tidak perlu, kami mendapatkan kira-kira diagram blok perangkat berikut:

Refleksi
Ada ide untuk hanya mengganti unit navigasi dengan sesuatu yang android, tetapi mati ketika saya mengerti lebih dalam bagaimana mereka berkomunikasi dengan kepala. Selain AVC-LAN, modul-modul ini juga dihubungkan oleh jalur GVIF (Gigabit Video InterFace), dan wajah yang sama dari produsen konverter ini dapat secara tidak sengaja retak jika saya juga membeli konverter sinyal video di GVIF dengan harga lebih dari $ 100. mungkin sulit, tapi .. "- terdengar di kepalaku pada motif lagu yang terkenal, dan aku tidak suka keputusannya.
Ada solusi di jaringan dengan pemasangan radio Cina, bukan penerima radio. Ini tidak cocok untuk saya karena kedua tampilan tersebut adalah redundansi yang tidak masuk akal. IMHO.
Solusi
Solusi berikut telah lahir: ganti seluruh kepala, dan selesaikan radio android, berteman dengan Prius, di mana:
- Desain USB <-> Konverter perangkat keras AVC-LAN
- Kembangkan firmware untuknya sehingga terhubung seperti USB-HID.
- Buatlah komposit sehingga salah satu fungsi terdeteksi seperti keyboard perangkat keras normal (untuk menggunakannya sebagai kontrol asli dari tombol-tombol pada panel)
- Kembangkan aplikasi Android dengan fungsi yang mirip dengan (atau lebih unggul) asli, Priusovsky
- Sejajarkan kamera belakang
- Memecahkan masalah di bagian mekanik (pemasangan di tempat biasa)
Dalam prosesnya, perlu untuk mengembangkan aplikasi lain untuk android - sniffer biasa, sehingga lebih mudah untuk membalikkan paket pada AVC-LAN. Pada saat dan latihan yang sama.
Seharusnya terlihat seperti ini:

Sebagai dasar perangkat keras, diputuskan untuk menggunakan papan pelatihan di SM32F103:

Dipesan dengan AliExpress seharga $ 2.05.
Atau cari - spoilerMungkin lot sudah dihapus oleh penjual, jadi saya berikan string ajaib untuk mencari di Ali:
STM32F103C8T6 ARM STM32 Modul Papan Pengembangan Sistem Minimum
Apa yang saya sukai dari dia:
- Modul perangkat keras USB (Perangkat) di papan prosesor
- Tumpukan USB yang memadai dari produsen (tidak seperti Freescale-ovsky, jangan diingat pada malam hari).
- Port GPIO gratis yang dapat digunakan untuk menghubungkan tombol biasa di sisi monitor. Mungkin ini akan menyembunyikan tombol perangkat keras radio di bawah panel. Saya tidak tahu dia akan jadi apa
- Dan di atasnya Anda dapat menggantung konverter AVC-LAN ke level logis
Saya akan menjelaskan lebih lanjut dalam urutan implementasi, yang karena, pertama-tama, untuk pengetahuan pribadi saya. Yaitu Saya mencoba untuk menyadari tempat-tempat di mana mereka tidak pada awalnya, pada akhirnya meninggalkan apa yang seharusnya terjadi.
Bagaimanapun, beberapa artikel direncanakan di hub yang berbeda. Proyek ini ternyata menjadi FullStack - dari koneksi perangkat keras ke aplikasi android.
Bagian 2: USB, HID, deskriptor, dan semua untuk mendapatkan prototipe pilot
Langkah pertama saya ingin mendapatkan banyak perangkat dan telepon, dan agar perangkat dapat mentransfer paket ke telepon, dan itu - untuk menampilkannya di aplikasi.
Seperti yang dikatakan Gagarin: Ayo pergi!
Perangkat USB HID Composite pada STM32
Apa yang saya putuskan untuk lakukan adalah mengadaptasi contoh ST dari tugas-tugas saya dan mendapatkan perangkat USB yang dikenali oleh tuan rumah sebagai bagian dari keyboard dan โsesuatu yang lainโ - Perangkat RAW HID. Yang pertama, seperti yang sudah saya katakan, ditujukan untuk kontrol Android asli, yang kedua - untuk pertukaran langsung paket AVC-LAN dengan program pada perangkat.
Berdasarkan STM's CubeMX, dan setelah membaca banyak artikel tentang cara mengimplementasikan custom HID, saya menemukan satu hal yang tidak menyenangkan di jaringan: masalah membuat perangkat komposit praktis tidak ada atau sangat langka.
Kode sumber nantiSaya belum mengunggah kode sumber, karena fakta bahwa proyek sekarang sedang dilaksanakan dalam mode pelatihan eksperimental. Jika proyek berhasil diselesaikan, pastikan untuk menyeret mereka ke Github dan mengedit artikel dengan tautan ke mereka.
Dalam bentuk di mana mereka berada, tidak masuk akal untuk mengunggah - ada cukup banyak kekacauan di Internet tanpa saya.
USB, Komposit, HID
Hanya beberapa kata tentang hal ini. Diasumsikan bahwa Anda kurang lebih akrab dengan standar USB. Jika tidak, lebih baik membiasakan diri Anda dan bereksperimen dengan contoh-contoh dari CubeMX.
Jadi kita punya:
Contoh penerapan STM USB stack dan mouse. Di sana kami telah mengkonfigurasi beberapa deskriptor dan titik akhir fungsional. Ini merupakan tambahan untuk 0x00 dan 0x80 untuk mengendalikan seluruh perangkat.
Untuk mengimplementasikan proyek saya, saya membutuhkan titik akhir keyboard menjadi dua arah (saya tidak tahu mengapa - ini berguna) dan beberapa titik akhir lainnya yang akan digunakan untuk bertukar data dengan fungsi kedua - RAW. Tambahkan mereka.
Kami membuat titik dua arah dengan menambahkan titik OUT ke deskriptor:
Deskriptor konfigurasi.Saat mengedit deskriptor, perhatikan indeks dan ukuran.
(2c5cf968121f0d8fa43a6755c09e15ef3a317791):
0x07, USB_DESC_TYPE_ENDPOINT, HID_EPOUT_ADDR, 0x03, HID_EPOUT_SIZE, 0x00, HID_FS_BINTERVAL,
Dan tambahkan beberapa poin lagi:
Deskriptor konfigurasi(bc2bd583c98715e106fcb3ab07b266bc9221be36):
0x07, USB_DESC_TYPE_ENDPOINT, HID_EPIN_ADDR2, 0x03, HID_EPIN_SIZE, 0x00, HID_FS_BINTERVAL, 0x07, USB_DESC_TYPE_ENDPOINT, HID_EPOUT_ADDR2, 0x03, HID_EPOUT_SIZE, 0x00, HID_FS_BINTERVAL,
Itu adalah deskriptor konfigurasi. Sekarang tuan rumah akan yakin bahwa kita memiliki semacam perangkat HID komposit, dan Anda dapat mengirim data ke semua titik ini. Tapi ini tidak benar.
Untuk mewujudkannya:
1. Pengontrol kami memiliki bagian memori yang dialokasikan secara khusus yang dilengkapi dengan modul CAN dan USB. Karena modul USB terlibat secara independen dalam proses penerimaan / pengiriman paket data, Anda perlu mengatur buffer dalam memori ini untuk setiap titik akhir individu:
USBD_LL_Init dalam file usbd_conf.c HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x00 , PCD_SNG_BUF, 0x18); HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x80 , PCD_SNG_BUF, 0x58); HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , HID_EPOUT_ADDR , PCD_SNG_BUF, 0x100); HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , HID_EPIN_ADDR , PCD_SNG_BUF, 0x140); HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , HID_EPOUT_ADDR2 , PCD_SNG_BUF, 0x180); HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , HID_EPIN_ADDR2 , PCD_SNG_BUF, 0x1B0);
Alamat penyangga bersifat arbitrer, jika saja mereka tidak akan tumpang tindih.
Untuk beberapa alasan, tumpukan ST ditulis dengan harapan bahwa perangkat tidak akan memiliki lebih dari satu titik akhir dua arah, jadi kami akan sedikit memodifikasi tumpukan:
Transfer
Ubah nama prosedur USBD_HID_SendReport menjadi USBD_HID_SendReportEP, tambahkan satu parameter lagi - angka titik akhir. Kami meninggalkan prosedur dengan nama lama untuk kompatibilitas ke belakang, tetapi dalam tubuh kami memanggil USBD_HID_SendReportEP dengan konstanta dalam bentuk titik akhir. Solusinya masih bukan yang paling estetis, tetapi akan berhasil untuk percobaan, dan bahkan jika tetap, itu tidak akan mengganggu proyek tertentu.
usbd_hid.c uint8_t USBD_HID_SendReportEP (USBD_HandleTypeDef *pdev, uint8_t ep, uint8_t *report, uint16_t len) { ... , USBD_HID_SendReport } uint8_t USBD_HID_SendReport (USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t len) { return USBD_HID_SendReportEP(pdev,HID_EPIN_ADDR,report,len); }
Sekarang semuanya siap untuk mengirim data, tetap saja pada waktu yang tepat untuk memanggil fungsi ini.
Finalisasi
Demi pesanan, kami mencari proyek dan memanggil USBD_LL_CloseEP lagi, tetapi untuk titik akhir yang baru dibuat.
Penerimaan
Agar titik akhir disetel secara moral agar berfungsi, Anda perlu menghubungi USBD_LL_PrepareReceive untuk mereka. Saya sarankan pembaca untuk pergi mencari proyek untuk baris ini, dan menyesuaikan panggilan ini dengan kebutuhan Anda.
Saya mendapatkan cumi-cumi jelek ini dalam kode saya:
usbd_core.c USBD_LL_PrepareReceive(pdev, HID_EPOUT_ADDR+(epnum&0x7F)-1 , hhid->Report_buf, USBD_HID_OUTREPORT_BUF_SIZE);
Yaitu Saya melanjutkan dari fakta bahwa jumlah titik akhir berturut-turut. Ini buruk, IMHO. Jangan lakukan itu. Namun, jangan suka ST juga.
Yang tersisa adalah pergi ke file usbd_hid.c, dan secara khusus ke fungsi USBD_HID_DataOut, dan pastikan bahwa panggilan ke penangan data yang diterima cocok dengan ide pribadi Anda tentang yang indah. Saya tidak berhasil juga, jadi kode dan uraiannya akan panjang dan tidak bisa dipahami. Lebih mudah melakukannya sendiri.
Laporkan
Semuanya, di tempat ini kami mendapat perangkat komposit yang mampu bertukar data melalui dua titik dua arah. Pada langkah terakhir, kami "tutup mulut" keingintahuan pengemudi HID, menggambarkan deskriptor laporan seperti itu:
__ALIGN_BEGIN static uint8_t HID_ReportDesc2[33] __ALIGN_END = { 0x06, 0x00, 0xff,
Laporan ini memberi tahu driver HID: akan ada sekitar 31 byte data. Tidak perlu mencari tahu apa itu - berikan saja pada program yang membuka perangkat ini. Dalam laporan fisik, byte nol akan sama dengan indeks laporan (REPORT_ID (2)). Dengan demikian, total 32 byte akan datang.
Dan masukkan data tentang hal itu di usbd-hid.c, fungsi USBD_HID_Setup.:
usbd-hid.c switch (req->bRequest) { case USB_REQ_GET_DESCRIPTOR: if( req->wValue >> 8 == HID_REPORT_DESC) {
Lebih lanjut dalam program ini:
- Perakitan konverter level logika AVC-LAN, dan koneksi ke board. Analisis lapisan fisik AVC-LAN, bentuk gelombang nyata.
- Memproses antarmuka di tingkat pengontrol dan mengirim paket dengan laporan
- Antarmuka ujung ke ujung dan rekayasa terbalik Prius. Package Sniffer (atau aplikasi Android pertama saya)
PS
- Saya memutuskan untuk menulis artikel karena saya dipaksa (hampir), meyakinkan bahwa ini harus dibagikan. Bahkan jika saya tidak menyelesaikan proyek, beberapa informasi terbaru dapat membantu seseorang bahkan dengan cara "mentah".
- Kritik terhadap proyek ini disambut baik Saya sendiri belum sepenuhnya membayangkan bahwa itu akan berhasil.
- Kritik terhadap artikel, desain, presentasi - terutama, karena Ini adalah artikel pertama untuk sumber tersebut. Dengan kelanjutan karya ini, saya ingin mengekspresikan pikiran saya dalam bentuk yang biasa dan dapat dicerna untuk pembaca