ZC702のLinuxを立ち上げた状態で、”
Zynq-7000(ZC702)のLinuxチュートリアル3(リモートデバック)”でやってきたSDKのリモートデバックを使用して、DS23(LED)を制御してみた。
”
Zynq-7000(ZC702)でビットファイル入りのLinuxのブートイメージが入ったSDカードを作る”で作ったチュートリアル2が入ったSDカードでLinuxをブートしたが、そのSDカードを使ってブートしたLinuxを使用する。
LEDのDS23はMIO 10に接続されている。チュートリアル2でのMIO Configuration はMIO 10にgpio[10] が接続されている。”
Zynq-7000(ZC702)のチュートリアル2のXPSでのZynqの設定”参照。
ZynqのMIOの設定については、”
Zynq-7000 Extensible Processing Platform Technical Reference Manual UG585 (v1.0) May 8, 2012"を参照した。そのマニュアルの282ページ、”14.3 GPIO Control of Device Pins”の”Figure 14‐2: GPIO Channel”によると、GPIOの出力はDATA, MASK_DATA_LSW, MASK_DATA_MSW, DIRM, OEN が関係する。下に”Figure 14‐2: GPIO Channel”を引用させていただく。

(なお、ツイッターで@jet_lagさんに大変お世話になりました。ありがとうございました。)
このGPIOの設定レジスタの情報は、同じマニュアルの1191ページ、”B.19 General Purpose I/O (gpio) ”に書いてある。
MASK_DATA_0_LSW は32ビットのレジスタでMIO[15:0]を設定する。下の16ビットが MASK_0_LSW で1がセットされているとマスクされる。上の16ビットは DATA_0_LSW で、DATA_0[15:0] の値を設定する。ReadするとWriteした値が見える。Readは DATA_0_RO をReadすると、ピンの値が見える。
MASK_DATA_0_MSW は同じく32ビットのレジスタでMIO[31:16]を設定する。
DATA_0はMIO[31:0] の出力の値を設定する。
DIRM_0は、そのピットの入出力設定で、0が入力、1が出力だ。
OEN_0は、そのビットのイネーブル設定で、0がディスエーブル、1がイネーブルだ。
これらを踏まえて、SDKのリモートデバックを使用して、DS23(LED)を制御してみる。
・SDカードをZC702に挿入し、電源ON。
・Linuxが立ち上がる。IPアドレスを10.10.70.120 にセットする。(ifconfig eth0 10.10.70.120 netmask 255.255.255.0)
・パソコンで、SDKを立ちあげて、チュートリアル2のワークスペースを指定する。
・SDKのRemote Absolute File Path for C/C++ Application でLinuxのリモートデバックをするファイルを作成する。(”
Zynq-7000(ZC702)のLinuxチュートリアル4(リモートデバック2)”参照)
GPIOを制御する方法は、mmap() を使用することにした。Raspberry PiのLinux用だが、調度良いサンプルが”
RPi Low-level peripherals”にあったので、これを参照してプログラムを書いた。
プログラムを下に貼っておく。なお、void setup_io() は、”
RPi Low-level peripherals”のものをそのまま使用しているので、そちらを参照して欲しい。
#define GPIO_BASE 0xE000A000
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <dirent.h>
#include <fcntl.h>
#include <assert.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#define PAGE_SIZE (4*1024)
#define BLOCK_SIZE (4*1024)
int mem_fd;
char *gpio_mem, *gpio_map;
volatile unsigned *gpio;
void setup_io();
int main()
{
setup_io();
volatile unsigned *mask_data_0_lsw, *mask_data_0_msw;
volatile unsigned *data_0, *data_0_ro;
volatile unsigned *dirm_0, *oen_0;
mask_data_0_lsw = gpio;
mask_data_0_msw = gpio + 1;
data_0 = gpio + 0x10;
data_0_ro = gpio + 0x18;
dirm_0 = gpio + 0x81;
oen_0 = gpio + 0x82;
*(dirm_0) = *(dirm_0)|0x400;
*(oen_0) = *(oen_0)|0x400;
printf("MASK_DATA_0_LSW = %x\n", *(mask_data_0_lsw));
printf("MASK_DATA_0_MSW = %x\n", *(mask_data_0_msw));
printf("DATA_0 = %x\n", *(data_0));
printf("DATA_0_RO = %x\n", *(data_0_ro));
printf("DIRM_0 = %x\n", *(dirm_0));
printf("OEN_0 = %x\n", *(oen_0));
*(data_0) = *(data_0)&(~(0x400));
printf("DATA_0 = %x\n", *(data_0));
printf("Hello World\n");
return 0;
}
DS23 (LED) はLinuxブート時に、最初から点灯しているので、このプログラムで消灯することが出来た。
なお、上のプリント文の出力結果を下に示す。(Hello Worldのプリントは除く)
MASK_DATA_0_LSW = 2eb2
MASK_DATA_0_MSW = 6c1
DATA_0 = 6c12eb2
DATA_0_RO = 6c12e32
DIRM_0 = 480
OEN_0 = 480
DATA_0 = 6c02ab2
次はPL部に実装したAXI GPIO やAXI Timer を使ってみることにする。
- 2012年07月18日 05:53 |
- Zynq
-
| トラックバック:0
-
| コメント:0