SPI
Jako první je nutné najít vhodné a volné GPIO piny, pro pokusy jsem použil malou hračku TP-LINK WR703N. Je nutné si dát pozor, které piny procesor používá pro volbu režimů startu (viz. OpenWRT wiki). Já jsem využil piny 0 - CLK, 7 - MOSI a 29 - MISO.dále je nutné nainstalovat příslušné balíčky:
kmod-spi-bitbang
kmod-spi-dev
kmod-spi-gpio
kmod-spi-gpio-custom
po restartu zařízení by měl být načten jen modul spi_gpio
root@OpenWrt:/# lsmod | grep spi
spi_gpio 4112 0
dalšímu modulu (spi-gpio-custom) je nutné předat čísla GPIO pinů, které se mají používat, plus další parametry
insmod spi-gpio-custom bus0=1,0,7,29,0,1000 |
bus0=<id>,<sck>,<mosi>,<miso>,<modeX>,<maxfreqX>,<csX>[<modeX>,<maxfreqX>,<csX>]... [bus1=<id>,<sck>,<mosi>,<miso>,<modeX>,<maxfreqX>,<csX>] ...
V našem případě máme dost pinů pouze na jedno SPI, definujeme tedy parametry jen pro bus0.
<id>
<sck> číslo GPIO pinu, který bude přiřazen jako hodiny SPI (SCK)
<mosi> číslo GPIO pinu, který bude přiřazen jako výstup dat SPI (MOSI)
<miso> číslo GPIO pinu, který bude přiřazen jako vstup dat SPI (MISO)
<modeX>
<maxfreqX> hodnota maximální frekvence, kterou bude SPI se slavem komunikovat (v Hz)
<csX> číslo GPIO pinu, který bude přiřazen jako Chip Select (CS)
Volitelně může několikrát následovat <modeX>,<maxfreqX>,<csX> pro další SPI slave zařízení (na stejné SPI sběrnici).
Kompletní příkaz pro zavedení modulu vypadá takto: insmod spi-gpio-custom bus0=1,0,7,29,0,1000,20,0,2000,21,0,3000,22 |
Díky předchozímu se nám do /dev přidají následující zařízení. Druhou číslicí v názvu zařízení se adresují jednotlivá zařízení na jedné sběrnici (pro každý je logicky nutné zadat CS).
/dev/spidev1.0
/dev/spidev1.1
/dev/spidev1.2
spidev1.0 je ovládán pomocí CS na GPIO pinu 20, maximální frekvence hodin je 1 kHz
spidev1.0 je ovládán pomocí CS na GPIO pinu 21, maximální frekvence hodin je 2 kHz
spidev1.0 je ovládán pomocí CS na GPIO pinu 22, maximální frekvence hodin je 3 kHz
I2C
Obdobný postup je i pro I2C sběrnici, ta ke své funkci potřebuje jen dva datové piny (zařízení nejsou adresována CS ale adresou na sběrnici).Pro podporu I2C je nutné nainstalovat balíčky:
kmod-i2c-gpio-custom kmod-i2c-core
Parametry modulů jsou jen dva, číslo GPIO pinu datového vodiče SDA a SCL. U WR703N jsou potřeba pull-up rezistory na oba datové vodiče.
insmod i2c-gpio-custom bus0=0,0,29
insmod i2c-dev
Výpis syslogu:
root@OpenWrt:/# insmod i2c-gpio-custom bus0=0,0,29
[ 846.320000] Custom GPIO-based I2C driver version 0.1.1
[ 846.330000] i2c-gpio i2c-gpio.0: using pins 0 (SDA) and 29 (SCL)
Pro vlastní zápis a čtení je možné použít balíček i2c-tools.
Nejprve detekujeme, zda máme na sběrnici něco připojeno:
root@OpenWrt:/# i2cdetect -y 0
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: 50 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
Ano máme, konkrétně na adrese 0x50, jdeme tedy zapisovat a následně číst.
root@OpenWrt:/# i2cget -y 0 0x50 0 b
0x00
root@OpenWrt:/# i2cget -y 0 0x50 1 b
0x01
root@OpenWrt:/# i2cget -y 0 0x50 2 b
0x02
root@OpenWrt:/# i2cget -y 0 0x50 3 b
0x03
root@OpenWrt:/# i2cget -y 0 0x50 4 b
0x11
root@OpenWrt:/# i2cset -y 0 0x50 4 0x04 b
root@OpenWrt:/# i2cget -y 0 0x50 4 b
0x04
1-Wire
A nyní k 1-Wirepotřebné balíčky jsou tyto:
kmod-w1-master-gpio kmod-w1-gpio-custom kmod-w1-slave-therm
Po restartu máme zavedeny všechny potřebné moduly až na w1-gpio-custom.
root@OpenWrt:/# lsmod | grep w1
w1_gpio 1344 0
w1_therm 1840 0
wire 14721 2 w1_therm
Obvyklým postupem předáme parametry, druhý definuje číslo GPIO portu, pin také potřebuje 4,4 kOhm pull-up. Třetí, zda je pin open drain (jinak ale vůbec netuším k čemu tato volba slouží).
root@OpenWrt:/# insmod w1-gpio-custom bus0=0,7,0
[ 890.230000] Custom GPIO-based W1 driver version 0.1.1
Po zavedení modulu už máme načtená čidla na sběrnici, v našem případě jedno čidlo DS1822 s adresou 22-0000001abd7d a 1-wire spínač 28-000000eefb97.
root@OpenWrt:/# ls /sys/devices/w1_bus_master1/
22-0000001abd7d 28-000000eefb97 w1_master_attempts w1_master_remove
driver w1_master_max_slave_count w1_master_search
subsystem w1_master_name w1_master_slave_count
uevent w1_master_pointer w1_master_slaves
w1_master_add w1_master_pullup w1_master_timeout
Nyní stačí načíst hodnotu, v tomto případě se vše zdařilo (CRC souhlasí) a teplota je 26,187 ºC.
root@OpenWrt:/# cat /sys/devices/w1_bus_master1/22-0000001abd7d/w1_slave
a3 01 4b 46 7f ff 0d 10 ce : crc=ce YES
a3 01 4b 46 7f ff 0d 10 ce t=26187
GPIO
Další možností je piny používat jako GPIO piny, pomocí příkazu ho nastavíme jako GPIO.
echo "29" > /sys/class/gpio/export
Dále je nutné nastavit směr, out či in.
echo "out" > /sys/class/gpio/gpio29/direction
A nyní již zapisujeme hodnotu (0 nebo 1).
echo "1" > /sys/class/gpio/gpio29/value
Hodnotu value je možné i číst, v režimu vstupu čteme skutečný stav pinu.
Víc dokumentace k modulu GPIO je na https://www.kernel.org/doc/Documentation/gpio/sysfs.txt
Ještě jedno informace na závěr, pro uvolnění USARTU je vhodné deaktivovat výstup hlášek jádra pomocí příkazu: dmesg -n 1
Zdroje:
http://randomcoderdude.wordpress.com/2013/08/15/spi-over-gpio-in-openwrt/
http://wiki.openwrt.org/toh/tp-link/tl-wr703n
https://dev.openwrt.org/browser/trunk/package/kernel/spi-gpio-custom/src/spi-gpio-custom.c
http://cs.wikipedia.org/wiki/Serial_Peripheral_Interface - obrázek
https://dev.openwrt.org/browser/trunk/package/w1-gpio-custom/src/w1-gpio-custom.c?rev=10982
http://mujweb.cz/mrazik/router/index.html
http://cs.wikipedia.org/wiki/I%C2%B2C - obrázek
http://wiki.openwrt.org/doc/hardware/port.gpio
Žádné komentáře:
Okomentovat