LinkedIn YouTube Facebook
Szukaj

Newsletter

Proszę czekać.

Dziękujemy za zgłoszenie!

Wstecz
SoM / SBC

Emulator konsoli NES w systemie Linux na komputerze SoMLabs VisonSOM

Kontroler zbudowany z wykorzystaniem układu MCP23S08

Jeżeli nie dysponujemy żadnym kontrolerem, wówczas idealnym rozwiązaniem (choćby ze względu na walor edukacyjny) jest konstrukcja własnego prostego urządzenia. Oryginalny kontroler konsoli NES posiada 8 przycisków: cztery do kontroli kierunku, dwa przyciski akcji (oznaczone jako A i B) oraz przyciski START i SELECT. Aby uniknąć problemów z wyborem i konfiguracją multipleksacji wyprowadzeń GPIO (co nawet przy dużej liczbie wyprowadzeń I/O dostępnych na złączach komputerów jednopłytkowych nie zawsze jest proste), do sprzętowej budowy kontrolera wykorzystamy moduł KAmodEXP1, będący adresowalnym ekspanderem GPIO z układem MCP23S08. Układ ten może pracować zarówno na magistrali SPI jak i I2C oraz posiada dokładnie osiem konfigurowalnych linii GPIO, a więc idealnie wpisuje się w realizowany projekt. Prosty schemat połączeń przedstawiono na rysunku 4 (układ MCP23S08 podłączony w konfiguracji SPI).

Rys. 4. Schemat połączeń dla modułu KAmodEXP1 i płyty bazowej VisionCB-STD

Aby uniknąć programowej  implementacji obsługi układu MCP23S08 w przestrzeni użytkownika, wykorzystamy gotowy sterownik dostępny w jądrze systemu. Konfigurację jądra rozpoczynamy od włączenia sprzętowego kontrolera magistrali SPI dla układów i.MX:

Device Drivers  --->
	[*] SPI support  --->
		<*> Freescale i.MX SPI controllers

Następnie włączamy docelowy sterownik układu MCP23S08:

Device Drivers  --->
	-*- GPIO Support  --->
		SPI GPIO expanders  --->
			<*> Microchip MCP23xxx I/O expander

Włączenie sterownika układu MCP23S08 oraz przygotowanie dla niego opisu Device Tree (co przedstawiono poniżej), spowoduje pojawienie się w systemie nowego kontrolera GPIO dostępnego w przestrzeni użytkownika poprzez interfejs /sys/class/gpio. Aby maksymalnie uprościć obsługę projektowanego urządzenia, linie kontrolera GPIO wykorzystamy w sterowniku klawiatury Polled GPIO buttons [więcej informacji – patrz ramka]:

Device Drivers  --->
	Input device support  --->
		<*> Event interface
		[*] Keyboards  --->
			< > GPIO Buttons
			<*> Polled GPIO buttons

Konfigurację jądra należy uzupełnić opisem Device Tree wymaganym przez włączone powyżej sterowniki. Edycję pliku somlabs-visionsom-6ull.dts rozpoczynamy od dodania opisów dla kontrolera SPI oraz układu MCP23S08listing 1.

&ecspi3 {
	fsl,spi-num-chipselects = <1>;
	cs-gpios = <&gpio1 20 0>;
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_ecspi3>;
	status = "okay";

	gpiom1: gpio@0 {
		compatible = "microchip,mcp23s08";
		gpio-controller;
		#gpio-cells = <2>;
		microchip,spi-present-mask = <0x01>;
		reg = <0>;
		spi-max-frequency = <10000000>;
	};
};

List. 1. Opis Device Tree dla kontrolera SPI3 oraz układu MCP23S08

Do komunikacji z układem MCP23S08 wykorzystamy kontroler SPI3 (ecspi3) w konfiguracji z jedną linią CS (wartość określona poprzez pole fsl,spi-num-chipselects), sterowaną poprzez wyprowadzenie GPIO1_20 (definicja linii w polu cs-gpios). W opisie kontrolera wskazujemy również odwołanie do multipleksacji wyprowadzeń I/O (pinctrl-0=<&pinctrl_ecspi3>). Następnie umieszczamy opis nowego kontrolera gpiom1, którego funkcję pełni układ MCP23S08. Opis rozpoczynamy od wskazania typu układu (układ ekspandera występuje również w wersji z 16. liniami GPIO), jak i sposobu jego podłączenia (SPI lub I2C):

  • compatible = „microchip,mcp23s08” – dla wersji SPI z 8. liniami GPIO
  • compatible = „microchip,mcp23s17” – dla wersji SPI z 16. liniami GPIO
  • compatible = „microchip,mcp23008” – dla wersji I2C z 8. liniami GPIO
  • compatible = „microchip,mcp23017” – dla wersji I2C z 16. liniami GPIO

Wpisem gpio-controller oznaczamy urządzenie jako pełniące rolę kontrolera GPIO. Pole microchip,spi-present-mask jest istotne wyłącznie gdy jedna linia CS jest dzielona przez większą liczbę adresowalnych układów. Pole reg – dla konfiguracji MCP23S08 jako układu SPI – określa numer porządkowy wyprowadzenia linii CS.

Zaimplementowany w jądrze systemu Linux sterownik układu MCP23S08 nie wspiera aktualnie funkcji przerwań dla konfiguracji SPI (opcja te jest wspierana wyłącznie przez układy pracujące na magistrali I2C). Z tego powodu, na kolejnym etapie konfiguracji jądra wykorzystano sterownik „Polled GPIO buttons” z aktywnym odpytywaniem. Dla układów pracujących na magistrali I2C bardziej optymalnym rozwiązaniem będzie wybór sterownika „GPIO Buttons” oraz konfiguracja kontrolera GPIO jako „interrupt-controller”. Przykładowy opis Device Tree dla układu MCP23S08 pracującego na magistrali I2C może wyglądać następująco:

gpiom1: gpio@20 {
        compatible = "microchip,mcp23017";
        gpio-controller;
        #gpio-cells = <2>;
        reg = <0x20>;
        interrupt-parent = <&gpio1>;
        interrupts = <17 IRQ_TYPE_LEVEL_LOW>;
        interrupt-controller;
        #interrupt-cells=<2>;
        microchip,irq-mirror;
};

W powyżej przedstawionym opisie, pole reg definiuje sprzętowy adres układu MCP23S08 na magistrali I2C.

Wpisem spi-max-frequency określamy maksymalną dopuszczalną częstotliwość pracy układu na magistrali (tutaj 10MHz). Tak przygotowany opis kontrolera SPI oraz układu MCP23S08 należy uzupełnić o opis konfiguracji multipleksacji wyprowadzeń I/O – listing 2.

&iomuxc {
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_hog_1>;
	imx6ul-evk {

 		/* … */

		pinctrl_ecspi3: ecspi3grp {
			fsl,pins = <
				MX6UL_PAD_UART2_RTS_B__ECSPI3_MISO      0x1b0b1
				MX6UL_PAD_UART2_CTS_B__ECSPI3_MOSI      0x1b0b1
				MX6UL_PAD_UART2_RX_DATA__ECSPI3_SCLK    0x1b0b1
				MX6UL_PAD_UART2_TX_DATA__GPIO1_IO20     0x1b0b0
			>;
		};
	};
};

List. 2. Konfiguracja wyprowadzeń I/O dla kontrolera SPI3

Wyprowadzenia, którym na listingu 2 przypisano role linii SCLK oraz CS, w domyślnym opisie Device Tree dostarczanym przez producenta płytki VisionSOM pełnią rolę linii RX oraz TX kontrolera UART2. Aby uniknąć konfliktu, należy wyłączyć kontroler UART2, poprzez wykomentowanie linii statusu, jak przedstawiono to na listingu 3.

&uart2 {
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_uart2>;
	fsl,uart-has-rtscts;
	//status = "okay";
};

List. 3. Wyłączenie kontrolera UART2 w opisie Device Tree

Ostatnim etapem przygotowania opisu Device Tree jest zdefiniowanie ośmiu przycisków w ramach sterownika gpio-keys-polled. Ponieważ sterownik pracuje w trybie odpytywania, niezbędne jest określenie interwału czasowego poprzez pole poll-interval (wartość wyrażona w milisekundach). Następnie dokonano opisu ośmiu przycisków definiując ich etykiety (pole label), odwołania do kontrolera GPIO (do kolejnych linii I/O kontrolera gpiom1/układu MCP23S08) oraz przypisując im wybrane kod, zdefiniowane przez podsystem wejścia. Fragment opisu Device Tree przedstawiono na listingu 4.

gpio-keys {

	compatible = "gpio-keys-polled";
	poll-interval = <100>;

	btn0 {
		label = "btn0";
		gpios = <&gpiom1 0 GPIO_ACTIVE_HIGH>;
		linux,code = <103>; /* <KEY_UP> */
	};

	btn1 {
		label = "btn1";
		gpios = <&gpiom1 1 GPIO_ACTIVE_HIGH>;
		linux,code = <108>; /* <KEY_DOWN> */
	};

	btn2 {
		label = "btn2";
		gpios = <&gpiom1 2 GPIO_ACTIVE_HIGH>;
		linux,code = <105>; /* <KEY_LEFT> */
	};

	/* … */
};

List. 4. Opis Device Tree dla sterownika gpio-keys-polled

Po skompilowaniu nowego obrazu jądra oraz opisu Device Tree z wykorzystaniem poleceń:

make ARCH=arm zImage
make ARCH=arm somlabs-visionsom-6ull.dtb

pliki wynikowe (tj. zImage oraz somlabs-visionsom-6ull.dtb) należy skopiować do katalog /boot na karcie SD. Po ponownym uruchomieniu systemu, w buforze komunikatów jądra zostaną wyświetlone komunikaty informujące o poprawnej konfiguracji sterownika:

root@somlabs:~# dmesg | grep gpio-keys
input: gpio-keys as /devices/platform/gpio-keys/input/input0

Poprawność działania kontrolera oraz podłączonych przycisków może zostać przetestowana za pomocą narzędzia evtest:

root@somlabs:~# apt-get install evtest
root@somlabs:~# evtest --grab /dev/input/event0
Input driver version is 1.0.1
Input device ID: bus 0x19 vendor 0x1 product 0x1 version 0x100
Input device name: "gpio-keys"
Supported events:
  Event type 0 (EV_SYN)
  Event type 1 (EV_KEY)
    Event code 103 (KEY_UP)
    Event code 105 (KEY_LEFT)
    ….
Properties:
Testing ... (interrupt to exit)
Event: time 1519407395.872567, type 1 (EV_KEY), code 108 (KEY_DOWN), value 0
Event: time 1519407395.872567, -------------- SYN_REPORT ------------

Ostatecznej konfiguracji przycisków należy dokonać z wykorzystaniem opcji Gamepad Config w emulatorze Fceux.

 Fot. 5. Moduł VisionSOM z uruchomionym emulator konsoli Famicon/NES

Łukasz Skalski

contact@lukasz-skalski.com

Łukasz Skalski - absolwent Politechniki Gdańskiej, miłośnik FLOSS, autor książki "Linux. Podstawy i aplikacje dla systemów embedded" oraz szeregu artykułów dotyczących programowania systemów wbudowanych. Zawodowo związany z firmą Samsung. Wszystkie wolne chwile poświęca projektowaniu i programowaniu urządzeń wyposażonych w mikroprocesory 8-/16- i 32-bitowe. Szczególnym zainteresowaniem obejmuje tematykę systemu Linux w aplikacjach na urządzenia embedded.
Tagi: projekt, SOM