"SPI 5개나 있으니까 두개 연결하면되겠지?"
멍청한 생각이었다.
그냥 SPI를 이용한다면 파이썬 라이브러리를 통해 SPI 프로그램을 구현하기만 하면 될것이었다.
하지만 라즈베리파이에서 지원하는 디바이스인 ENC28J60을 사용하려고 하니 문제가 발생했다.
SPI 한 채널 CE0,CE1를 이용한 이더넷과 멀티디바이스 연결
SPI를 사용하는 두개의 모듈 SPI 2.2 TFT 모델과 ENC28J60 을 멀티로 연결 하는 방법은 다음과 같다.
1. 라즈베리파이의 SPI0 - GPIO10(MOSI), GPIO9(MISO), GPIO11(CLK) 연결.
2.2 TFT - Raspberry pi CM4
VCC - 3.3v
GND - Ground
CS - GPIO8
RESET - RUN_PG
DC - GPIO25
MOSI - GPIO10(MOSI)
SCK - GPIO11(CLK)
LED - GPIO6
MISO - GPIO9(MISO)
ENC28J60 - Raspberry pi CM4
VCC - 3.3v
GND - Ground
CS - GPIO7
INT - GPIO23
MOSI - GPIO10(MOSI)
SCK - GPIO11(CLK)
MISO - GPIO9(MISO)
2. /boot/overlays/ENC28J60-overlay.dts 수정 및 컴파일
이미 Raspberry pi os에는 ENC28J60에 대한 SPI 드라이버가 내장되어 있다. 따라서 SPI=on을 해주기만해도 dts에 의해 드라이버를 자동으로 인식한다. 하지만 안타깝게도 CE를 설정해주는 함수는 찾아보기 힘들다.
/boot/overlays/README
...
Name: enc28j60
Info: Overlay for the Microchip ENC28J60 Ethernet Controller on SPI0
Load: dtoverlay=enc28j60,<param>=<val>
Params: int_pin GPIO used for INT (default 25)
speed SPI bus speed (default 12000000)
Name: enc28j60-spi2
Info: Overlay for the Microchip ENC28J60 Ethernet Controller on SPI2
Load: dtoverlay=enc28j60-spi2,<param>=<val>
Params: int_pin GPIO used for INT (default 39)
speed SPI bus speed (default 12000000)
CE1핀으로 사용하려면 *dts 파일을 작성하여, 사용할 CE1핀이 변경된, dtb로 다시 컴파일 해주어야한다.
(*DTS파일은 Device Tree Specification 의 약자 이다. 라즈베리파이 OS가 빌드 될 때에, 디바이스 드라이버들이 탑재되어 이미지가 빌드된다.)
DTS파일 양식은 리눅스에서 약속된 형태로 사용되므로 구조를 따로 공부해두는 것도 좋다.
- dtc 는 dts를 컴파일하여 dts로 만들어주는 컴파일러이다.
- dts = device tree specification (사람이 이해 할 수 있는 수준으로 기술)
- dtb = device tree blob (DT를 binary로 변환 한 것)
- dtc = device tree compiler
ENC28J60에 해당되는 Device Tree를 수정해주는 작업
이곳←클릭 enc28j60-overlay.dts 코드를 가져올 수 있다.
컴파일하기 전, 복사한 코드를 아래와 같이 수정하여 준다.
(1) reg를 1로하여 CE1을 사용함을 알리고,
(2) TFT의 frequency 와 맞춰주기위해 16Mhz로 수정해준다.
(3) 또한 인터럽트 핀을 GPIO23번으로 교체한다.
cd /boot/overlays
sudo vi ENC28J60-overlay.dts
// Overlay for the Microchip ENC28J60 Ethernet Controller
/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2708";
fragment@0 {
target = <&spi0>;
__overlay__ {
/* needed to avoid dtc warning */
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
spidev@0{
status = "disabled";
};
eth1: enc28j60@0{
compatible = "microchip,enc28j60";
reg = <1>; /* CE1 */
pinctrl-names = "default";
pinctrl-0 = <ð1_pins>;
interrupt-parent = <&gpio>;
interrupts = <23 0x2>; /* falling edge */
spi-max-frequency = <16000000>;//12
status = "okay";
};
};
};
fragment@1 {
target = <&gpio>;
__overlay__ {
eth1_pins: eth1_pins {
brcm,pins = <23>;
brcm,function = <0>; /* in */
brcm,pull = <0>; /* none */
};
};
};
__overrides__ {
int_pin = <ð1>, "interrupts:0",
<ð1_pins>, "brcm,pins:0";
speed = <ð1>, "spi-max-frequency:0";
};
};
컴파일 하기전 기존 파일을 따로 백업해두자
sudo mv enc28j60.dtbo enc28j60.dtbo_backup
새로만든 dts 파일을 적용시키자.
sudo dtc -@ -I dts -O dtb -o enc28j60.dtbo enc28j60-overlay.dts
위 코드를 실행시키면 dts파일을 컴파일하여 enc28j60.dtbo 파일로 만들어져서 나온다.
3. /boot/config.txt 수정
config.txt파일은 부팅시에 장치들의 설정을 미리 설정해두는 파일이다.
이때 TFT LCD모듈과 이더넷모듈을 같은 클락(SCK)을 사용해야 정상적으로 동작한다. SCK 클럭 수를 16Mhz로 통일시킨다. dtoverlay=spi0-2cs, 로 바꾸어주어서 cs핀을 두개 이상사용한다고 입력해준다. enc28j60의 int_pin 을 23으로 바꾼다.
아래와 같은 코드를 추가해준다.
sudo vi /boot/config.txt
...
dtparam=spi=on
dtoverlay=spi0-2cs, cs1_pin=7
dtoverlay=enc28j60, int_pin=23
# --- added by adafruit-pitft-helper Mon Apr 12 16:24:03 2021 ---
#hdmi_force_hotplug=1 # required for cases when HDMI is not plugged
dtparam=i2c1=on
dtparam=i2c_arm=on
dtoverlay=pitft22,rotate=90,speed=16000000,fps=24
# --- end adafruit-pitft-helper Mon Apr 12 16:24:03 2021 ---
4. 리부트
sudo reboot
5. 결과확인
TFT 는 SPI0.0 을 사용한다.
ENC28J60 은 SPI0.1 을 사용한다.
네트워크가 IP자동할당 붙어있는 것을 확인 할 수 있다.
dmesg | grep spi
pi@raspberrypi:/boot/overlays$ dmesg | grep spi
[ 5.268578] enc28j60 spi0.1: Ethernet driver 1.02 loaded
[ 5.458739] graphics fb1: fb_ili9340 frame buffer, 320x240, 150 KiB video memory, 4 KiB buffer memory, fps=25, spi0.0 at 16 MHz
[ 7.719114] enc28j60 spi0.1 eth1: link down
[ 7.719133] enc28j60 spi0.1 eth1: multicast mode
[ 7.719306] enc28j60 spi0.1 eth1: multicast mode
[ 7.734465] enc28j60 spi0.1 eth1: multicast mode
[ 7.734707] enc28j60 spi0.1 eth1: multicast mode
[ 7.785027] enc28j60 spi0.1 eth1: multicast mode
[ 7.785251] enc28j60 spi0.1 eth1: multicast mode
[ 8.610802] enc28j60 spi0.1 eth1: link up - Half duplex
...
ifconfig
pi@raspberrypi:/boot/overlays$ ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.1.174 netmask 255.255.255.0 broadcast 192.168.1.255
RX packets 5725 bytes 1423850 (1.3 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 1216 bytes 93691 (91.4 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.1.57 netmask 255.255.255.0 broadcast 192.168.1.255
RX packets 7430 bytes 1172572 (1.1 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 76 bytes 19756 (19.2 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
device interrupt 58
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
인터넷 속도 측정 결과 비교
- 100M 인터넷 환경에서 측정
- 라즈베리파이 ethernet 포트에서 다운로드 83.25 Mbit/s , 업로드 92.92 Mbit.s
- SPI 이더넷포트 다운로드 5.87 Mbit/s , 4.31Mbit/s
- python3 speedtest-cli 사용
pi@raspberrypi:~$ python3 speedtest-cli
Retrieving speedtest.net configuration...
Testing from Korea Telecom (14.51.232.196)...
Retrieving speedtest.net server list...
Selecting best server based on ping...
Hosted by kdatacenter.com (Seoul) [20.65 km]: 23.189 ms
Testing download speed................................................................................
Download: 83.25 Mbit/s
Testing upload speed......................................................................................................
Upload: 92.92 Mbit/s
pi@raspberrypi:~$ python3 speedtest-cli
Retrieving speedtest.net configuration...
Testing from Korea Telecom (14.51.232.196)...
Retrieving speedtest.net server list...
Selecting best server based on ping...
Hosted by kdatacenter.com (Seoul) [20.65 km]: 24.863 ms
Testing download speed................................................................................
Download: 5.87 Mbit/s
Testing upload speed......................................................................................................
Upload: 4.31 Mbit/s
pi@raspberrypi:~$
위에 나온것은 Raspberry pi cm4의 이더넷 포트에 연결한 것이다. 다운로드속도 83.25 Mbit/s가 나오고 있다.
ENC28J60 은 이보다 더 낮은 속도인 5.87 Mbit/s 나온다. 속도저하의 원인은 아직 발견 못했지만, LCD화면도 나오고 인더넷 연결도 원할 한 것을 확인하였다. 웹서핑 정도는 충분한 인터넷속도를 보여준다.
'임베디드 용어설명' 카테고리의 다른 글
라즈베리파이 pi 로그인이 안됨 해결방법.(Bullseye 버전 이후 default ID 삭제) (0) | 2022.09.20 |
---|---|
ESP IDF 설치 (Mac OS) (1) | 2021.07.16 |
STM32F105 CDC라고 쓰고 USB 가상포트 라고 읽는다. (0) | 2021.04.22 |
STM32F103 UART TX를 OD핀으로 쓰기. 3.3v 신호를 5v 신호로 레벨시프트(3.3 v -> 5v level shift) (0) | 2021.04.13 |
openwrt 사용법 (HLK-7688AN) (0) | 2021.02.04 |