REMI Lab강의 노트

Wireless Embedded Systems E05

6장 SDR과 ADALM-Pluto

프로그램이 바꾸는 것: IIO 속성

코드 한 줄 sdr.rx_lo = 2440000000은 장치 안에서 무엇을 바꿀까?

드라이버의 속성

Linux의 IIO(Industrial I/O)는 ADC나 DAC처럼 아날로그와 디지털 사이를 변환하는 장치를 다루는 틀이다. Pluto의 Linux에서 AD9363 드라이버는 IIO 장치 ad9361-phy로 나타나고, 설정 하나하나가 이 장치의 속성(attribute)이다. 이름이 AD9361인 것은 같은 드라이버가 AD9361, AD9363, AD9364를 함께 다루기 때문이다. 표본은 수신용 장치 cf-ad9361-lpc와 송신용 장치 cf-ad9361-dds-core-lpc의 버퍼로 오간다.

Pluto 안의 서버 iiod는 USB로 온 요청을 받아 속성을 읽고 쓰고, 버퍼를 읽고 쓴다. 그래서 어떤 프로그램에서 부르든 장치에서 바뀌는 것은 같은 속성이다. 명령행 도구 iio_attr -c ad9361-phy altvoltage0 frequency 2450000000은 수신 LO를 2.45 GHz로 바꾼다(강의 자료 WE5 14쪽). PC의 Python 라이브러리 pyadi-iio와 이 과목의 브라우저 실습 쪽도 같은 속성을 쓴다.

altvoltage0과 altvoltage1은 수신·송신 LO 채널이다. voltage0은 수신 쪽 설정이면 입력 채널, 송신 쪽 설정이면 출력 채널을 가리킨다. 아래 표의 이름은 이 과목 실습 쪽에서 쓰는 이름이다.

하는 일 실습 쪽 이름 ad9361-phy의 채널·속성 장치에서 바뀌는 곳
수신 중심 주파수 rx_lo altvoltage0 · frequency 수신 믹서의 LO
송신 중심 주파수 tx_lo altvoltage1 · frequency 송신 믹서의 LO
표본화율 sample_rate 입력 voltage0 · sampling_frequency ADC, 디지털 필터, 폭 ±fs/2\pm f_s/2
수신 RF 대역폭 rx_rf_bandwidth 입력 voltage0 · rf_bandwidth ADC 앞 아날로그 필터
송신 RF 대역폭 tx_rf_bandwidth 출력 voltage0 · rf_bandwidth DAC 뒤 아날로그 필터
이득 방식 rx_gain_mode 입력 voltage0 · gain_control_mode 수신 이득을 누가 정하는지
수신 이득 rx_hardwaregain 입력 voltage0 · hardwaregain 수신 증폭(dB)
송신 감쇠 tx_hardwaregain 출력 voltage0 · hardwaregain 송신 출력(0 … −89.75 dB)
캡처 길이 rx(n)의 n 속성 없음(cf-ad9361-lpc 버퍼 크기) 한 번에 받는 NN

이득 방식은 manual, slow_attack, fast_attack, hybrid 가운데 하나이고, 수신 이득은 manual일 때만 쓴 값이 적용된다. 실습 쪽은 다른 방식에서 rx_hardwaregain을 쓰면 오류를 내고, pyadi-iio는 오류 없이 무시한다. 송신 감쇠는 0.25 dB 간격으로 정한다.

pyadi-iio도 LO, 표본화율, RF 대역폭은 같은 이름을 쓴다. 이득은 끝에 _chan0을 붙인 gain_control_mode_chan0, rx_hardwaregain_chan0, tx_hardwaregain_chan0이고, 캡처 길이는 rx_buffer_size로 미리 정한다. 강의 자료의 pyadi-iio 코드에 이득과 캡처 길이를 더하면 다음과 같다(강의 자료 WE5 15쪽).

import adi
sdr = adi.Pluto()                       # USB로 이어진 Pluto를 찾는다
sdr.sample_rate = int(4e6)              # fs = 4 MS/s
sdr.rx_lo = int(2.44e9)                 # 중심 주파수 2.44 GHz
sdr.rx_rf_bandwidth = int(4e6)          # 아날로그 필터 ±2 MHz
sdr.gain_control_mode_chan0 = "manual"  # 이득을 고정한다
sdr.rx_hardwaregain_chan0 = 30          # 수신 이득 30 dB
sdr.rx_buffer_size = 2**16              # N = 65,536
x = sdr.rx()                            # N개 한 캡처, 값은 ADC 코드

이 과목의 실습 쪽은 브라우저 안의 Python에서 도우미 sdrlab의 pluto로 장치를 부른다. 같은 설정과 캡처는 다음과 같다.

from sdrlab import pluto
sdr = await pluto.connect()             # 실습 쪽의 Pluto 연결
applied = await sdr.configure(sample_rate=4e6, rx_lo=2.44e9,
                              rx_rf_bandwidth=4e6,
                              rx_gain_mode="manual",
                              rx_hardwaregain=30)
print(applied)                          # 장치가 실제로 적용한 값
x = await sdr.rx(2**16)                 # N = 65,536개 한 캡처

장치와 주고받는 호출에는 await를 붙인다. 설정은 configure()로 한 번에 쓰고, 이 함수는 장치에서 다시 읽은 값을 돌려준다. 캡처 길이는 미리 정하지 않고 rx(n)에 준다. rx(n)이 돌려주는 복소 표본(complex64)은 ADC 최대값이 1.0이 되도록 나눈 값이라, 크기를 곧바로 dBFS로 읽을 수 있다. pyadi-iio의 rx()는 ADC 코드값을 그대로 돌려주므로, 두 쪽의 값을 비교할 때는 ADC 최대값으로 나눠 맞춘다.

설정할 때 알아 둘 것

이득을 비교하는 실습에서는 manual 모드로 이득을 고정한다. slow_attack 같은 자동 이득 제어(AGC)에서는 칩이 평균 세기를 정해진 범위에 두려고 이득을 스스로 바꾸므로, 캡처마다 크기의 기준이 달라진다.

받은 세기는 dBFS, 곧 ADC가 나타낼 수 있는 최대값을 0 dB로 둔 값으로 읽는다. 수신 이득과 케이블 손실을 따로 교정하지 않으면 dBm으로 바꿀 수 없다.

장치는 요청한 값을 자기가 낼 수 있는 가장 가까운 값으로 맞춘다. 예를 들어 LO는 2.4 Hz 간격으로만 정해진다. 그래서 실습 쪽은 설정을 쓴 뒤 다시 읽은 값을 기록한다. 2.083 MS/s보다 낮은 표본화율은 칩 안 FIR 필터를 함께 설정해야 쓸 수 있다. pyadi-iio는 sample_rate를 쓸 때 FIR 필터를 함께 설정하고, 이 과목의 실습 쪽 첫 판은 fs≥2.1f_s\ge2.1 MS/s만 받는다.

이 과목의 송신 규칙

송신은 다른 사람의 무선 기기와 같은 전파를 쓰므로 규칙을 둔다. 실습 쪽은 이 규칙을 벗어나는 설정을 받지 않는다.

  1. 송신은 2.4 GHz ISM 대역(2400–2483.5 MHz) 안에서만 한다. Pluto의 기준 발진기는 ±25 ppm까지 어긋날 수 있어(대역 끝에서 약 ±62 kHz) 실제 반송파가 설정값과 다를 수 있으므로, 양 끝 100 kHz를 비운 2400.1–2483.4 MHz를 쓴다. 톤 하나가 아니라 신호가 차지하는 대역 전체가 이 안에 있어야 한다. 기저대역에서 fbbf_{\mathrm{bb}}에 폭 BB인 신호를 두면 RF에서 fTX,LO+fbb±B/2f_{\mathrm{TX,LO}}+f_{\mathrm{bb}}\pm B/2를 차지한다.
  2. 송신 감쇠는 10 dB 이상, 곧 tx_hardwaregain을 −10 dB 이하로 둔다. ADI는 기본값 −10 dB에서 출력단이 선형 영역에 있고, 이 값에서는 TX를 SMA 케이블로 RX에 바로 이어도 안전하다고 적는다. 그보다 작은 감쇠로 TX를 RX에 직결하지 말라고도 적는다.
  3. 한 Pluto의 TX를 RX로 돌려 받는 루프백은 SMA 케이블 사이에 30 dB 감쇠기를 넣는다.

아래 그림은 루프백 연결이다. TX 포트에서 나온 신호가 감쇠기를 지나 같은 장치의 RX 포트로 돌아오는 길을 따라가며, 그 길에 걸린 조건을 본다.

케이블 루프백 연결. Pluto의 TX 포트에서 SMA 케이블과 30 dB 감쇠기를 거쳐 같은 Pluto의 RX 포트로 돌아온다. 송신 감쇠는 10 dB 이상, 송신 대역은 2400.1–2483.4 MHz이다.PlutoTXRX30 dB 감쇠기케이블SMA 케이블tx_hardwaregain ≤ −10 dB · 신호 전체가 2400.1–2483.4 MHz 안받는 쪽 세기는 dBFS로 읽는다(dBm이 아니다)
이 과목의 루프백 연결이다. 감쇠 조건은 ADI의 ADALM-PLUTO Transmit 쪽을 따랐고, 30 dB 감쇠기는 과목의 규칙이다.

기저대역에서 ej2πfbbte^{j2\pi f_{\mathrm{bb}}t}를 보내면 4장의 규칙(실수 RF = I cos − Q sin)에 따라 RF에서 fTX,LO+fbbf_{\mathrm{TX,LO}}+f_{\mathrm{bb}}에 선다. 장치에서 이 부호가 맞는지는 실습 1에서 루프백으로 확인한다.