Liburan akan segera berakhir, yang berarti sudah waktunya untuk menyesali hati dan menghidupkan kepalanya. Jadi ide lain muncul di benak saya. Setelah saya menghubungkan gamepad dari Dendy (ini adalah joystick, itu controller, itu joystick, itu konsol game, dll.) Geektimes.ru/post/281520 , saya berpikir untuk menghubungkan yang kedua ke Raspberry pi. Saya tidak ingin membeli sampah kedua dengan tombol pengacau, dan omong-omong, mereka membuangnya ke rak-rak Nintendo Classic Mini, yah, saat Anda membuangnya, Anda akan membeli lobak. Tujuannya bukan untuk membeli emulator seharga 4K, tetapi saya memutuskan untuk membeli gamepad. Untungnya, saya berhasil membelinya, itu adalah yang terakhir di toko. Mereka yang tertarik dengan apa yang datang dapat mengklik tombol di bawah ini.Ini adalah tautan langsung ke buktinya , jika yang biasa tidak diaktifkan.
Tidak ada rahasia bahwa gamepad ini dapat dihubungkan ke Wii dan Wii U, yang berarti dapat diinterogasi melalui antarmuka i2c. Yang menggembirakan adalah bahwa gamepad ini ditenagai oleh 3,3 V, yang berarti Anda tidak perlu repot-repot mencocokkan level voltase. Untuk menghubungkan gamepad ke Raspberry pi, saya memutuskan untuk membeli konektor untuk wiimote di aliexpress, yang disolder di papan darinya. Meskipun ada 2 konektor dalam paket, dan mereka berada dalam gelembung yang sama, salah satu konektor rusak. Tidak ada timah yang tidak bisa dilakukan di sini. Setelah semuanya disolder, perlu untuk memeriksa apakah ini berhasil. Untuk ini, saya memutuskan untuk menggunakan utilitas dari paket i2c-tools. Idenya adalah untuk menentukan perangkat di alamat - 52. Setelah meluncurkan i2cdetect, saya melihat yang berharga:i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: 03 04 05 06 07 -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- 52 -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
Hati saya segera menjadi lebih hangat (seolah-olah seorang gadis yang tidak dikenal tersenyum pada Anda di jalan di musim semi), jadi itu berhasil. Selanjutnya, Anda harus google tentang menghubungkan periferal ke Wii. Saya menemukan contoh bagaimana Wii nunchak terhubung ke Raspberry pi. Dari contoh ini, saya menemukan bahwa gamepad harus diinisialisasi dengan menulis nol pada register 0x40, dan kemudian tepat sebelum membaca setiap kali Anda hanya perlu menulis nol dan membaca 6 byte pertama.Dalam hal ini, saya juga menghadapi pilihan perpustakaan untuk i2c. Karena saya tidak berhasil dengan perpustakaan bcm2835, saya memutuskan untuk menggunakan perpustakaan yang digunakan dalam contoh - ini adalah perpustakaan WirinPi. Semuanya berhasil dengannya. Secara empiris, saya menemukan bahwa informasi tombol terkandung dalam 4 dan 5 byte (jika Anda menghitung byte dari nol). Informasi tentang tombol pilih, mulai, bawah, kanan ada di byte keempat, dan informasi tentang tombol A, B, atas, kiri ada di byte kelima. Selain itu, informasi tentang tombol pilih, turun, kanan ada di 4 bit byte yang tinggi, dan informasi tentang tombol mulai ada di bawah. Hal yang sama berlaku untuk byte ke-5, informasi tentang tombol A, B ada di bit 4 byte yang tinggi, dan informasi tentang tombol ke atas, sebelah kiri ada di yang lebih rendah. Berikut adalah kode tombol: A - 0xcf, B - 0xbf, naik - 0xf0, kiri - 0xf1, pilih - 0xcf, mulai - 0xf3, turun - 0xbf, kanan - 0x7f.Hasil penekanan tombol bersama, informasi tentang yang dalam satu byte dan dalam bit yang sama, adalah logis "DAN" dari kode mereka. Jadi misalnya, menekan tombol A dan B bersamaan memberi nilai 0x8f.Berikut ini tautan ke tabel:
Selanjutnya, saya menulis program uji kecil untuk membaca tombol, di bawah ini saya akan mencantumkannya secara lengkap dan menjelaskan apa yang terjadi dengannya:#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <wiringPi.h>
#include <wiringPiI2C.h>
#include <errno.h>
char i, a, b, c, d, state;
char bytes[6];
int main(void) {
wiringPiSetup();
int fd = wiringPiI2CSetup(0x52);
wiringPiI2CWriteReg8(fd, 0x40, 0x00);
delayMicroseconds(20);
while(1)
{
state = 0;
wiringPiI2CWrite(fd, 0x00);
delayMicroseconds(100);
for (i=0; i<6; i++)
{
bytes[i] = wiringPiI2CRead(fd);
}
a = bytes[5] >> 4;
b = bytes[5] << 4;
c = bytes[4] >> 4;
d = bytes[4] << 4;
if (a == 0xc)
state ^= (1 << 0);
if (a == 0xb)
state ^= (1 << 1);
if (c == 0xc)
state ^= (1 << 2);
if (d == 0x30)
state ^= (1 << 3);
if (b == 0x00)
state ^= (1 << 4);
if (c == 0xb)
state ^= (1 << 5);
if (b == 0x10)
state ^= (1 << 6);
if (c == 0x7)
state ^= (1 << 7);
printf("%x \n", state);
}
return 0;
}
Pada awalnya, variabel dideklarasikan, dengan bantuan yang menentukan keadaan tombol tertentu. Adalah penting bahwa variabel-variabelnya adalah dari tipe char, jika tidak dengan pergeseran bitwise ke kiri, hanya 4 nol yang ditambahkan, dan hanya itu. Penafsiran akan salah. Tidak peduli seberapa lucu kedengarannya, Anda harus menggunakan mantra .Selanjutnya, di badan utama program, pustaka WiringPi diinisialisasi - wiringPiSetup () ;, dan kemudian alamat perangkat i2c diatur ke 0x52. Selanjutnya, pengontrol diinisialisasi:
wiringPiI2CWriteReg8(fd, 0x40, 0x00);
delayMicroseconds(20);
Nah, kalau begitu, sudah ada di tubuh loop, 6 byte dibaca, dan sebelum membaca, nol ditulis setiap kali. Dan setelah itu, tombol yang ditekan ditentukan. Secara umum, semua kode ini dimigrasikan ke file emulator.Terakhir kali, inisialisasi perpustakaan terdaftar dalam file fceu.c:
int FCEUI_Initialize(void)
{
if(!FCEU_InitVirtualVideo())
return 0;
memset(&FSettings,0,sizeof(FSettings));
FSettings.UsrFirstSLine[0]=8;
FSettings.UsrFirstSLine[1]=0;
FSettings.UsrLastSLine[0]=231;
FSettings.UsrLastSLine[1]=239;
FSettings.SoundVolume=100;
FCEUPPU_Init();
X6502_Init();
wiringPiSetup();
return 1;
}
Baik dan selanjutnya semua perubahan hanya menyangkut file input.c. Awalnya, dalam fungsi int FCEUI_Initialize (void), mode operasi port gpio untuk bekerja dengan gamepad lama (dari Simba) diatur, dan gamepad diinisialisasi.
pinMode (0, OUTPUT);
pinMode (2, OUTPUT);
pinMode (3, INPUT);
digitalWrite (0, HIGH);
digitalWrite (2, LOW);
fd = wiringPiI2CSetup(0x52);
wiringPiI2CWriteReg8(fd, 0x40, 0x00);
usleep(20);
Pada awalnya, Anda juga perlu mendeklarasikan variabel yang akan menentukan penekanan tombol.Dalam fungsi DECLFW (B4016) statis, strobo disediakan untuk gamepad lama, strobo baru tidak diperlukan:
if (LastStrobe==0)
{
digitalWrite (0, LOW);
}
Saat membuat program pengujian, saya tidak dapat memecahkan masalah mengidentifikasi tombol yang ditekan bersama, informasi tentang yang dalam satu byte dan dalam satu bit. Pada akhirnya, saya menerapkan konstruksi kasus alih-alih jika lain.Nah, fungsi itu sendiri adalah fungsi membaca keadaan tombol:
void FCEU_UpdateInput(void)
{
joy[0] = 0;
joy[1] = 0xff;
wiringPiI2CWrite(fd, 0x00);
usleep(100);
for (i = 0; i <= 7; i++)
{
bytes[i] = wiringPiI2CRead(fd);
joy[1] ^= digitalRead(3) << i;
digitalWrite (2, HIGH);
delayMicroseconds (20);
digitalWrite (2, LOW);
delayMicroseconds (20);
}
a = bytes[5] >> 4;
b = bytes[5] << 4;
c = bytes[4] >> 4;
d = bytes[4] << 4;
switch (a){
case 0xc:
joy[0] ^= (1 << 0);
break;
case 0xb:
joy[0] ^= (1 << 1);
break;
case 0x8:
joy[0] ^= (1 << 0);
joy[0] ^= (1 << 1);
break;
}
switch (b){
case 0x00:
joy[0] ^= (1 << 4);
break;
case 0x10:
joy[0] ^= (1 << 6);
break;
case 0x20:
joy[0] ^= (1 << 4);
joy[0] ^= (1 << 6);
break;
}
switch (c){
case 0xc:
joy[0] ^= (1 << 2);
break;
case 0xb:
joy[0] ^= (1 << 5);
break;
case 0x7:
joy[0] ^= (1 << 7);
break;
case 0x8:
joy[0] ^= (1 << 2);
joy[0] ^= (1 << 5);
break;
case 0x4:
joy[0] ^= (1 << 2);
joy[0] ^= (1 << 7);
break;
case 0x3:
joy[0] ^= (1 << 5);
joy[0] ^= (1 << 7);
break;
}
switch (d){
case 0x30:
joy[0] ^= (1 << 3);
break;
}
digitalWrite (0, HIGH);
}
Dalam satu siklus, saya menggabungkan pembacaan tombol dari kedua gamepad, well, berpikir bahwa 2 byte tambahan dibaca, tidak masalah, tetapi semuanya terjadi pada saat yang sama. Dan tidak ada penundaan.Secara umum, semuanya baik-baik saja.PS: Seingat saya besok kerja sudah terdistorsi.PPS Saya lupa menambahkan bahwa untuk kompilasi yang berhasil, di Makefile (dibentuk setelah menjalankan perintah Configure), yang terletak di direktori src, Anda perlu menambahkan -lwiringPi -lm -lrt ke tempat di mana dependensi perpustakaan ditulis. Baris:LIBS =