# multi_bd_wrapper.xdc
# 2015/07/02 by marsee
#
##Switches
##IO_L19N_T3_VREF_35 sw0
set_property PACKAGE_PIN G15 [get_ports {In0_1[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {In0_1[0]}]
##IO_L24P_T3_34 sw1
set_property PACKAGE_PIN P15 [get_ports {In0_1[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {In0_1[1]}]
##IO_L4N_T0_34 sw2
set_property PACKAGE_PIN W13 [get_ports {In0[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {In0[0]}]
##IO_L9P_T1_DQS_34 sw3
set_property PACKAGE_PIN T16 [get_ports {In0[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {In0[1]}]
##LEDs
##IO_L23P_T3_35 Dout[0]
set_property PACKAGE_PIN M14 [get_ports {Dout[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {Dout[0]}]
##IO_L23N_T3_35 Dout[1]
set_property PACKAGE_PIN M15 [get_ports {Dout[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {Dout[1]}]
##IO_0_35 Dout[2]
set_property PACKAGE_PIN G14 [get_ports {Dout[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {Dout[2]}]
##IO_L3N_T0_DQS_AD1N_35 Dout[3]
set_property PACKAGE_PIN D18 [get_ports {Dout[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {Dout[3]}]
// multi_apuint.cpp
#include <ap_int.h>
void multi_apuint(ap_uint<8> multi_in0, ap_uint<8> multi_in1,
ap_uint<16> *multi_out){
#pragma HLS INTERFACE ap_ctrl_none port=return
#pragma HLS INTERFACE ap_none port=multi_out
#pragma HLS INTERFACE ap_none port=multi_in1
#pragma HLS INTERFACE ap_none port=multi_in0
*multi_out = multi_in0 * multi_in1;
}
// ==============================================================
// RTL generated by Vivado(TM) HLS - High-Level Synthesis from C, C++ and SystemC
// Version: 2015.4
// Copyright (C) 2015 Xilinx Inc. All rights reserved.
//
// ===========================================================
`timescale 1 ns / 1 ps
(* CORE_GENERATION_INFO="multi_apuint,hls_ip_2015_4,{HLS_INPUT_TYPE=cxx,HLS_INPUT_FLOAT=0,HLS_INPUT_FIXED=1,HLS_INPUT_PART=xc7z010clg400-1,HLS_INPUT_CLOCK=10.000000,HLS_INPUT_ARCH=others,HLS_SYN_CLOCK=6.380000,HLS_SYN_LAT=0,HLS_SYN_TPT=none,HLS_SYN_MEM=0,HLS_SYN_DSP=1,HLS_SYN_FF=0,HLS_SYN_LUT=0}" *)
module multi_apuint (
multi_in0_V,
multi_in1_V,
multi_out_V
);
parameter ap_true = 1'b1;
parameter ap_const_logic_1 = 1'b1;
parameter ap_const_logic_0 = 1'b0;
input [7:0] multi_in0_V;
input [7:0] multi_in1_V;
output [15:0] multi_out_V;
wire [7:0] r_V_fu_53_p0;
wire [7:0] r_V_fu_53_p1;
wire [15:0] r_V_fu_53_p00;
wire [15:0] r_V_fu_53_p10;
assign multi_out_V = (r_V_fu_53_p0 * r_V_fu_53_p1);
assign r_V_fu_53_p0 = r_V_fu_53_p00;
assign r_V_fu_53_p00 = multi_in1_V;
assign r_V_fu_53_p1 = r_V_fu_53_p10;
assign r_V_fu_53_p10 = multi_in0_V;
endmodule //multi_apuint
参考URL
AR# 62437 2014.3 Vivado 消費電力 - 「set_switching_activity -signal_rate」はグリッチ消費電力解析に影響するか
Vivado Design Suite ユーザー ガイド 消費電力解析および最適化 UG907 (v2015.3) 2015 年 9 月 30 日
set_switching_activity -signal_rate 1 -static_probability .99 [get_ports]
#!/bin/sh
for file in *.bmp
do
convert -geometry 640x480 -depth 8 -type GrayScale $file ${file%bmp}jpg
done
// -l : left bmp file name
// -r : right bmp file name
// -n : Start File Number
// -h : help
//
// RL_capture_bmp.cpp
// 2016/02/24
// 2016/03/22 : -n : Start File Number
//
// This software converts the left and right of the camera image to BMP file.
// -l : left bmp file name
// -r : right bmp file name
// -n : Start File Number
// -h : help
//
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <string.h>
#include "bmpheader.h"
#define PIXEL_NUM_OF_BYTES 4
#define NUMBER_OF_WRITE_FRAMES 3 // Note: If not at least 3 or more, the image is not displayed in succession.
#define XGA_HORIZONTAL_PIXELS 1024
#define XGA_VERTICAL_LINES 768
#define XGA_ALL_DISP_ADDRESS (XGA_HORIZONTAL_PIXELS * XGA_VERTICAL_LINES * PIXEL_NUM_OF_BYTES)
#define XGA_3_PICTURES (XGA_ALL_DISP_ADDRESS * NUMBER_OF_WRITE_FRAMES)
#define SVGA_HORIZONTAL_PIXELS 800
#define SVGA_VERTICAL_LINES 600
#define SVGA_ALL_DISP_ADDRESS (SVGA_HORIZONTAL_PIXELS * SVGA_VERTICAL_LINES * PIXEL_NUM_OF_BYTES)
#define SVGA_3_PICTURES (SVGA_ALL_DISP_ADDRESS * NUMBER_OF_WRITE_FRAMES)
int WriteBMPfile(FILE *fbmp, volatile unsigned int *frame_buffer, BMP24FORMAT **bmp_data);
int main(int argc, char *argv[]){
int opt;
int c, help_flag=0;
char left_bmp_fn[256] = "left";
char right_bmp_fn[256] = "right";
unsigned char attr[1024];
unsigned long phys_addr;
volatile unsigned int *Leye_addr, *Reye_addr;
int i, j;
int file_no = 0;
FILE *fbmp;
BMP24FORMAT **bmp_data; // 24 bits Date of BMP files (SVGA_HORIZONTAL_PIXELS * SVGA_VERTICAL_LINES)
while ((opt=getopt(argc, argv, "l:r:n:h")) != -1){
switch (opt){
case 'l':
strcpy(left_bmp_fn, optarg);
break;
case 'r':
strcpy(right_bmp_fn, optarg);
break;
case 'n':
file_no = atoi(optarg);
break;
case 'h':
help_flag = 1;
break;
}
}
if (help_flag == 1){ // help
printf("Usage : RL_capture_bmp [-l <left bmp file name>] [-r <right bmp file name>] [-n <Start File Number>] [-h]\n");
}
// udmabuf0
int fdf = open("/dev/udmabuf0", O_RDWR | O_SYNC); // frame_buffer, The chache is disabled.
if (fdf == -1){
fprintf(stderr, "/dev/udmabuf0 open error\n");
exit(-1);
}
volatile unsigned *frame_buffer = (volatile unsigned *)mmap(NULL, SVGA_3_PICTURES+XGA_3_PICTURES+SVGA_ALL_DISP_ADDRESS, PROT_READ|PROT_WRITE, MAP_SHARED, fdf, 0);
if (!frame_buffer){
fprintf(stderr, "frame_buffer mmap error\n");
exit(-1);
}
// phys_addr of udmabuf0
int fdp = open("/sys/devices/virtual/udmabuf/udmabuf0/phys_addr", O_RDONLY);
if (fdp == -1){
fprintf(stderr, "/sys/devices/virtual/udmabuf/udmabuf0/phys_addr open error\n");
exit(-1);
}
read(fdp, attr, 1024);
sscanf((const char *)attr, "%lx", &phys_addr);
close(fdp);
printf("phys_addr = %x\n", (unsigned int)phys_addr);
// allocated the memory for bmp file
if ((bmp_data=(BMP24FORMAT **)malloc(sizeof(BMP24FORMAT *)*SVGA_VERTICAL_LINES)) == NULL){
fprintf(stderr, "Can not allocate memory of the first dimension of SVGA_VERTICAL_LINES of bmp_data\n");
exit(1);
}
for (i=0; i<SVGA_VERTICAL_LINES; i++){
if ((bmp_data[i]=(BMP24FORMAT *)malloc(sizeof(BMP24FORMAT) * SVGA_HORIZONTAL_PIXELS)) == NULL){
fprintf(stderr, "Can not allocate %d th memory of the first dimension of bmp_data\n", i);
exit(1);
}
}
// assigned the left and right eys's frame buffer
Leye_addr = frame_buffer; // The Left Camera Image
Reye_addr = (volatile unsigned int *)((unsigned)frame_buffer+SVGA_3_PICTURES+0x8); // The Right Camera Image
char lbmp_file[256];
char rbmp_file[256];
// w - writed the left and right eye's bmp files. q - exit.
c = getc(stdin);
while(c != 'q'){
switch ((char)c) {
case 'w' : // w - writed the left and right eye's bmp files.
// writed the left and right eys's frame buffer
sprintf(lbmp_file, "left%d.bmp", file_no);
if ((fbmp=fopen(lbmp_file, "wb")) == NULL){
fprintf(stderr, "Cannot open %s in binary mode\n", lbmp_file);
exit(1);
}
WriteBMPfile(fbmp, Leye_addr, bmp_data);
fclose(fbmp);
sprintf(rbmp_file, "right%d.bmp", file_no);
if ((fbmp=fopen(rbmp_file, "wb")) == NULL){
fprintf(stderr, "Cannot open %s in binary mode\n", rbmp_file);
exit(1);
}
WriteBMPfile(fbmp, Reye_addr, bmp_data);
fclose(fbmp);
printf("file No. = %d\n", file_no);
file_no++;
break;
}
c = getc(stdin);
}
for(i=0; i<SVGA_VERTICAL_LINES; i++){
free(bmp_data[i]);
}
free(bmp_data);
munmap((void *)frame_buffer, (SVGA_3_PICTURES+XGA_3_PICTURES+SVGA_ALL_DISP_ADDRESS));
close(fdf);
return(0);
}
int WriteBMPfile(FILE *fbmp, volatile unsigned *frame_buffer, BMP24FORMAT **bmp_data){
BITMAPFILEHEADER bmpfh; // file header for a bmp file
BITMAPINFOHEADER bmpih; // INFO header for BMP file
// Copy the camera color data of the bmp_data (data of BMP when its starts from lower left)
for (int i=0; i<SVGA_VERTICAL_LINES; i++){
for (int j=0; j<SVGA_HORIZONTAL_PIXELS; j++){
bmp_data[(SVGA_VERTICAL_LINES-1)-i][j].red = (frame_buffer[i*SVGA_HORIZONTAL_PIXELS+j]>>16)&0xff;
bmp_data[(SVGA_VERTICAL_LINES-1)-i][j].green = (frame_buffer[i*SVGA_HORIZONTAL_PIXELS+j]>>8)&0xff;
bmp_data[(SVGA_VERTICAL_LINES-1)-i][j].blue = (frame_buffer[i*SVGA_HORIZONTAL_PIXELS+j])&0xff;
}
}
// Assign a value to the file header of the BMP file
bmpfh.bfType = 0x4d42;
bmpfh.bfSize = SVGA_HORIZONTAL_PIXELS*SVGA_VERTICAL_LINES*3+54;
bmpfh.bfReserved1 = 0;
bmpfh.bfReserved2 = 0;
bmpfh.bfOffBits = 0x36;
// Assign a value to the INFO header of the BMP file
bmpih.biSize = 0x28;
bmpih.biWidth = SVGA_HORIZONTAL_PIXELS;
bmpih.biHeight = SVGA_VERTICAL_LINES;
bmpih.biPlanes = 0x1;
bmpih.biBitCount = 24;
bmpih.biCompression = 0;
bmpih.biSizeImage = 0;
bmpih.biXPixPerMeter = 3779;
bmpih.biYPixPerMeter = 3779;
bmpih.biClrUsed = 0;
bmpih.biClrImporant = 0;
// Writing of BMP file header
fwrite(&bmpfh.bfType, sizeof(char), 2, fbmp);
fwrite(&bmpfh.bfSize, sizeof(long), 1, fbmp);
fwrite(&bmpfh.bfReserved1, sizeof(short), 1, fbmp);
fwrite(&bmpfh.bfReserved2, sizeof(short), 1, fbmp);
fwrite(&bmpfh.bfOffBits, sizeof(long), 1, fbmp);
// Writing of BMP INFO header
fwrite(&bmpih, sizeof(BITMAPINFOHEADER), 1, fbmp);
// Writing of lbmp_data anr rbmp_data
for (int i=0; i<SVGA_VERTICAL_LINES; i++) {
for (int j=0; j<SVGA_HORIZONTAL_PIXELS; j++) {
fputc((int)bmp_data[i][j].blue, fbmp);
fputc((int)bmp_data[i][j].green, fbmp);
fputc((int)bmp_data[i][j].red, fbmp);
}
}
}
// lap_filter_axis.h
// 2015/05/01
#define HORIZONTAL_PIXEL_WIDTH 800
#define VERTICAL_PIXEL_WIDTH 600
//#define HORIZONTAL_PIXEL_WIDTH 50
//#define VERTICAL_PIXEL_WIDTH 10
#define ALL_PIXEL_VALUE (HORIZONTAL_PIXEL_WIDTH*VERTICAL_PIXEL_WIDTH)
//
// lap_filter_axis.cpp
// 2015/05/01
// 2015/06/25 : 修正、ラプラシアンフィルタの値が青だけ担っていたので、RGBに拡張した
//
#include <stdio.h>
#include <string.h>
#include <ap_int.h>
#include <hls_stream.h>
#include <ap_axi_sdata.h>
#include "lap_filter_axis.h"
int laplacian_fil(int x0y0, int x1y0, int x2y0, int x0y1, int x1y1, int x2y1, int x0y2, int x1y2, int x2y2);
int conv_rgb2y(int rgb);
int lap_filter_axis(hls::stream<ap_axis<32,1,1,1> >& ins, hls::stream<ap_axis<32,1,1,1> >& outs){
#pragma HLS INTERFACE axis port=ins
#pragma HLS INTERFACE axis port=outs
#pragma HLS INTERFACE s_axilite port=return
ap_axis<32,1,1,1> pix;
ap_axis<32,1,1,1> lap;
unsigned int line_buf[2][HORIZONTAL_PIXEL_WIDTH];
#pragma HLS array_partition variable=line_buf block factor=2 dim=1
#pragma HLS resource variable=line_buf core=RAM_2P
int pix_mat[3][3];
#pragma HLS array_partition variable=pix_mat complete
int lap_fil_val;
do { // user が 1になった時にフレームがスタートする
ins >> pix;
} while(pix.user == 0);
for (int y=0; y<VERTICAL_PIXEL_WIDTH; y++){
for (int x=0; x<HORIZONTAL_PIXEL_WIDTH; x++){
#pragma HLS PIPELINE
if (!(x==0 && y==0)) // 最初の入力はすでに入力されている
ins >> pix; // AXI4-Stream からの入力
for (int k=0; k<3; k++){
for (int m=0; m<2; m++){
#pragma HLS UNROLL
pix_mat[k][m] = pix_mat[k][m+1];
}
}
pix_mat[0][2] = line_buf[0][x];
pix_mat[1][2] = line_buf[1][x];
int y_val = conv_rgb2y(pix.data);
pix_mat[2][2] = y_val;
line_buf[0][x] = line_buf[1][x]; // 行の入れ替え
line_buf[1][x] = y_val;
lap_fil_val = laplacian_fil( pix_mat[0][0], pix_mat[0][1], pix_mat[0][2],
pix_mat[1][0], pix_mat[1][1], pix_mat[1][2],
pix_mat[2][0], pix_mat[2][1], pix_mat[2][2]);
lap.data = (lap_fil_val<<16)+(lap_fil_val<<8)+lap_fil_val; // RGB同じ値を入れる
if (x<2 || y<2) // 最初の2行とその他の行の最初の2列は無効データなので0とする
lap.data = 0;
if (x==0 && y==0) // 最初のデータでは、TUSERをアサートする
lap.user = 1;
else
lap.user = 0;
if (x == (HORIZONTAL_PIXEL_WIDTH-1)) // 行の最後で TLAST をアサートする
lap.last = 1;
else
lap.last = 0;
outs << lap; // AXI4-Stream へ出力
}
}
return 1;
}
// RGBからYへの変換
// RGBのフォーマットは、{8'd0, R(8bits), G(8bits), B(8bits)}, 1pixel = 32bits
// 輝度信号Yのみに変換する。変換式は、Y = 0.299R + 0.587G + 0.114B
// "YUVフォーマット及び YUV<->RGB変換"を参考にした。http://vision.kuee.kyoto-u.ac.jp/~hiroaki/firewire/yuv.html
// 2013/09/27 : float を止めて、すべてint にした
int conv_rgb2y(int rgb){
int r, g, b, y_f;
int y;
b = rgb & 0xff;
g = (rgb>>8) & 0xff;
r = (rgb>>16) & 0xff;
y_f = 77*r + 150*g + 29*b; //y_f = 0.299*r + 0.587*g + 0.114*b;の係数に256倍した
y = y_f >> 8; // 256で割る
return(y);
}
// ラプラシアンフィルタ
// x0y0 x1y0 x2y0 -1 -1 -1
// x0y1 x1y1 x2y1 -1 8 -1
// x0y2 x1y2 x2y2 -1 -1 -1
int laplacian_fil(int x0y0, int x1y0, int x2y0, int x0y1, int x1y1, int x2y1, int x0y2, int x1y2, int x2y2)
{
int y;
y = -x0y0 -x1y0 -x2y0 -x0y1 +8*x1y1 -x2y1 -x0y2 -x1y2 -x2y2;
if (y<0)
y = 0;
else if (y>255)
y = 255;
return(y);
}
が表示されたあと、左目カメラ画像と右目カメラ画像が表示された。..........................13 pairs have been successfully detected.
Running stereo calibration ...
done with RMS error=0.482794
average reprojection err = 0.485068
// mt9d111_axi_lite_slave.v
// mt9d111_inf_axi_master のAXI Lite Slave モジュール。Frame Buffer のスタートアドレス・レジスタを持つ。
//
// 2014/11/08 : one_shot_reg を実装。
// オフセット0番地: フレーム・バッファの先頭アドレス(fb_start_address)
// オフセット4番地: 0 ビット目が 0 の時動画、0 ビット目に 1 の時に、ワンショットで取得した1フレームのカメラ画像を表示(one_shot_reg)
// 1 ビット目に 1 を Write した時に、ワンショットで1フレームの画像をフレーム・バッファに保存
//
// StereoCam_Alt_Disp.c
// 2016/02/01 by marsee
//
// 2016/02/17 : 's' commannd : Camera Start and Stop Command, but left camera only.
//
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <sys/mman.h>
#include <fcntl.h>
#define PIXEL_NUM_OF_BYTES 4
#define NUMBER_OF_WRITE_FRAMES 3 // Note: If not at least 3 or more, the image is not displayed in succession.
#define XGA_HORIZONTAL_PIXELS 1024
#define XGA_VERTICAL_LINES 768
#define XGA_ALL_DISP_ADDRESS (XGA_HORIZONTAL_PIXELS*XGA_VERTICAL_LINES*PIXEL_NUM_OF_BYTES)
#define SVGA_HORIZONTAL_PIXELS 800
#define SVGA_VERTICAL_LINES 600
#define SVGA_ALL_DISP_ADDRESS (SVGA_HORIZONTAL_PIXELS*SVGA_VERTICAL_LINES*PIXEL_NUM_OF_BYTES)
void cam_i2c_init(volatile unsigned *caminf_axi_iic) {
caminf_axi_iic[64] = 0x2; // reset tx fifo ,address is 0x100, i2c_control_reg
caminf_axi_iic[64] = 0x1; // enable i2c
}
void cam_i2x_write_sync(void) {
// unsigned c;
// c = *cam_i2c_rx_fifo;
// while ((c & 0x84) != 0x80)
// c = *cam_i2c_rx_fifo; // No Bus Busy and TX_FIFO_Empty = 1
usleep(1000);
}
void cam_i2c_write(volatile unsigned *caminf_axi_iic, unsigned int device_addr, unsigned int write_addr, unsigned int write_data){
caminf_axi_iic[66] = 0x100 | (device_addr & 0xfe); // Slave IIC Write Address, address is 0x108, i2c_tx_fifo
caminf_axi_iic[66] = write_addr;
caminf_axi_iic[66] = (write_data >> 8)|0xff; // first data
caminf_axi_iic[66] = 0x200 | (write_data & 0xff); // second data
cam_i2x_write_sync();
}
int main()
{
int fd0, fd1, fd2, fd3, fd4, fd5, fd6, fd7, fd9, fd10;
volatile unsigned *bmdc_axi_lites0;
volatile unsigned *caminf_axi_vdma_0, *dviin_axi_vdma_0;
volatile unsigned *caminf_axis_switch_0, *caminf_axis_switch_1;
volatile unsigned *caminf_mt9d111_inf_axis_0;
volatile unsigned *caminf_axi_iic;
volatile unsigned *caminf_lap_filter_axis_0;
volatile unsigned *frame_buffer;
unsigned char attr[1024];
unsigned long phys_addr;
char c;
int laps_cntrl;
// Bitmap Display Controller 0 AXI4 Lite Slave (UIO6)
fd6 = open("/dev/uio6", O_RDWR); // bitmap_display_controller 0 axi4 lite
if (fd6 < 1){
fprintf(stderr, "/dev/uio6 (bitmap_disp_cntrler_axi_master_0) open errorn");
exit(-1);
}
bmdc_axi_lites0 = (volatile unsigned *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd6, 0);
if (!bmdc_axi_lites0){
fprintf(stderr, "bmdc_axi_lites0 mmap errorn");
exit(-1);
}
// caminf_axi_vdma_0 (UIO1)
fd1 = open("/dev/uio1", O_RDWR); // caminf_axi_vdma_0 interface AXI4 Lite Slave
if (fd1 < 1){
fprintf(stderr, "/dev/uio1 (caminf_axi_vdma_0) open errorn");
exit(-1);
}
caminf_axi_vdma_0 = (volatile unsigned *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd1, 0);
if (!caminf_axi_vdma_0){
fprintf(stderr, "caminf_axi_vdma_0 mmap errorn");
exit(-1);
}
// dviin_axi_vdma_0 (UIO7)
fd7 = open("/dev/uio7", O_RDWR); // dviin_axi_vdma_0 interface AXI4 Lite Slave
if (fd7 < 1){
fprintf(stderr, "/dev/uio7 (dviin_axi_vdma_0) open errorn");
exit(-1);
}
dviin_axi_vdma_0 = (volatile unsigned *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd7, 0);
if (!dviin_axi_vdma_0){
fprintf(stderr, "dviin_axi_vdma_0 mmap errorn");
exit(-1);
}
// mt9d111 i2c AXI4 Lite Slave (UIO0)
fd0 = open("/dev/uio0", O_RDWR); // mt9d111 i2c AXI4 Lite Slave
if (fd0 < 1){
fprintf(stderr, "/dev/uio0 (caminf_axi_iic) open errorn");
exit(-1);
}
caminf_axi_iic = (volatile unsigned *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd0, 0);
if (!caminf_axi_iic){
fprintf(stderr, "caminf_axi_iic mmap errorn");
exit(-1);
}
// mt9d111 inf axis AXI4 Lite Slave (UIO5)
fd5 = open("/dev/uio5", O_RDWR); // mt9d111 inf axis AXI4 Lite Slave
if (fd5 < 1){
fprintf(stderr, "/dev/uio5 (caminf_mt9d111_inf_axis_0) open errorn");
exit(-1);
}
caminf_mt9d111_inf_axis_0 = (volatile unsigned *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd5, 0);
if (!caminf_mt9d111_inf_axis_0){
fprintf(stderr, "caminf_mt9d111_inf_axis_0 mmap errorn");
exit(-1);
}
// caminf_axis_switch_0 (UIO2)
fd2 = open("/dev/uio2", O_RDWR); // caminf_axis_switch_0 interface AXI4 Lite Slave
if (fd2 < 1){
fprintf(stderr, "/dev/uio2 (caminf_axis_switch_0) open errorn");
exit(-1);
}
caminf_axis_switch_0 = (volatile unsigned *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd2, 0);
if (!caminf_axis_switch_0){
fprintf(stderr, "caminf_axis_switch_0 mmap errorn");
exit(-1);
}
// caminf_axis_switch_1 (UIO3)
fd3 = open("/dev/uio3", O_RDWR); // caminf_axis_switch_1 interface AXI4 Lite Slave
if (fd3 < 1){
fprintf(stderr, "/dev/uio3 (caminf_axis_switch_1) open errorn");
exit(-1);
}
caminf_axis_switch_1 = (volatile unsigned *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd3, 0);
if (!caminf_axis_switch_1){
fprintf(stderr, "caminf_axis_switch_1 mmap errorn");
exit(-1);
}
// caminf_lap_filter_axis_0 (UIO4)
fd4 = open("/dev/uio4", O_RDWR); // caminf_lap_filter_axis_0 interface AXI4 Lite Slave
if (fd4 < 1){
fprintf(stderr, "/dev/uio4 (caminf_lap_filter_axis_0) open errorn");
exit(-1);
}
caminf_lap_filter_axis_0 = (volatile unsigned *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd4, 0);
if (!caminf_lap_filter_axis_0){
fprintf(stderr, "caminf_lap_filter_axis_0 mmap errorn");
exit(-1);
}
// udmabuf0
fd9 = open("/dev/udmabuf0", O_RDWR | O_SYNC); // frame_buffer, The chache is disabled.
if (fd9 == -1){
fprintf(stderr, "/dev/udmabuf0 open errorn");
exit(-1);
}
frame_buffer = (volatile unsigned *)mmap(NULL, (XGA_ALL_DISP_ADDRESS*NUMBER_OF_WRITE_FRAMES)+(SVGA_ALL_DISP_ADDRESS*NUMBER_OF_WRITE_FRAMES), PROT_READ|PROT_WRITE, MAP_SHARED, fd9, 0);
if (!frame_buffer){
fprintf(stderr, "frame_buffer mmap errorn");
exit(-1);
}
// caminf_axis_switch_1, 1to2 ,Select M00_AXIS
// Refer to http://marsee101.blog19.fc2.com/blog-entry-3177.html
caminf_axis_switch_1[16] = 0x0; // 0x40 = 0
caminf_axis_switch_1[17] = 0x80000000; // 0x44 = 0x80000000, disable
caminf_axis_switch_1[0] = 0x2; // Comit registers
// caminf_axis_switch_0, 2to1, Select S00_AXIS
// Refer to http://marsee101.blog19.fc2.com/blog-entry-3177.html
caminf_axis_switch_0[16] = 0x0; // 0x40 = 0;
caminf_axis_switch_0[0] = 0x2; // Comit registers
// phys_addr of udmabuf0
fd10 = open("/sys/devices/virtual/udmabuf/udmabuf0/phys_addr", O_RDONLY);
if (fd10 == -1){
fprintf(stderr, "/sys/devices/virtual/udmabuf/udmabuf0/phys_addr open errorn");
exit(-1);
}
read(fd10, attr, 1024);
sscanf(attr, "%lx", &phys_addr);
close(fd10);
printf("phys_addr = %xn", (unsigned)phys_addr);
// AXI VDMA Initialization sequence (caminf_axi_vdma_0)
caminf_axi_vdma_0[12] = 0x4; // S2MM_VDMACR (S2MM VDMA Control Register Offset 30h) is 0x4
while ((caminf_axi_vdma_0[12] & 0x4) == 0x4) ; // Reset is progress
caminf_axi_vdma_0[12] = 0x4; // S2MM_VDMACR (S2MM VDMA Control Register Offset 30h) is 0x4
while ((caminf_axi_vdma_0[12] & 0x4) == 0x4) ; // Reset is progress
caminf_axi_vdma_0[18] = NUMBER_OF_WRITE_FRAMES; // S2MM_FRMSTORE (0x48) register
caminf_axi_vdma_0[12] = 0x00010002; // S2MM_VDMACR(IRQFrameCount = 0x1, Circular_Park = 1)
caminf_axi_vdma_0[41] = SVGA_HORIZONTAL_PIXELS*PIXEL_NUM_OF_BYTES; // S2MM Horizontal Size Register(S2MM_HSIZE)0xc80 = 3200dec = 800 x 4
caminf_axi_vdma_0[42] = SVGA_HORIZONTAL_PIXELS*PIXEL_NUM_OF_BYTES; // S2MM Frame Delay and Stride Register(S2MM_FRMDLY_STRIDE)0xc80 = 3200dec = 800 x 4
caminf_axi_vdma_0[43] = (unsigned)phys_addr; // S2MM Start Address (1 to 16) Start Address 1
caminf_axi_vdma_0[44] = (unsigned)phys_addr+SVGA_ALL_DISP_ADDRESS; // S2MM Start Address (1 to 16) Start Address 2
caminf_axi_vdma_0[45] = (unsigned)phys_addr+2*SVGA_ALL_DISP_ADDRESS; // S2MM Start Address (1 to 16) Start Address 3
caminf_axi_vdma_0[12] = 0x00010003; // S2MM_VDMACR(IRQFrameCount = 0x1, Circular_Park = 1, Run/stop = 1)
while((caminf_axi_vdma_0[13] & 0x1) == 0x1) ; // Halt? (S2MM_VDMASR 0x34)
caminf_axi_vdma_0[40] = SVGA_VERTICAL_LINES; // S2MM Vertical Size (S2MM_VSIZE Offset 0xA0) 0x258 = 600dec
// AXI VDMA Initialization sequence (dviin_axi_vdma_0)
dviin_axi_vdma_0[12] = 0x4; // S2MM_VDMACR (S2MM VDMA Control Register Offset 30h) is 0x4
while ((dviin_axi_vdma_0[12] & 0x4) == 0x4) ; // Reset is progress
dviin_axi_vdma_0[12] = 0x4; // S2MM_VDMACR (S2MM VDMA Control Register Offset 30h) is 0x4
while ((dviin_axi_vdma_0[12] & 0x4) == 0x4) ; // Reset is progress
dviin_axi_vdma_0[18] = NUMBER_OF_WRITE_FRAMES; // S2MM_FRMSTORE (0x48) register
dviin_axi_vdma_0[12] = 0x00010002; // S2MM_VDMACR(IRQFrameCount = 0x1, Circular_Park = 1)
dviin_axi_vdma_0[41] = XGA_HORIZONTAL_PIXELS*PIXEL_NUM_OF_BYTES; // S2MM Horizontal Size Register(S2MM_HSIZE)0xc80 = 3200dec = 800 x 4
dviin_axi_vdma_0[42] = XGA_HORIZONTAL_PIXELS*PIXEL_NUM_OF_BYTES; // S2MM Frame Delay and Stride Register(S2MM_FRMDLY_STRIDE)0xc80 = 3200dec = 800 x 4
dviin_axi_vdma_0[43] = (unsigned)phys_addr+3*SVGA_ALL_DISP_ADDRESS; // S2MM Start Address (1 to 16) Start Address 1
dviin_axi_vdma_0[44] = (unsigned)phys_addr+3*SVGA_ALL_DISP_ADDRESS+XGA_ALL_DISP_ADDRESS; // S2MM Start Address (1 to 16) Start Address 2
dviin_axi_vdma_0[45] = (unsigned)phys_addr+3*SVGA_ALL_DISP_ADDRESS+2*XGA_ALL_DISP_ADDRESS; // S2MM Start Address (1 to 16) Start Address 3
dviin_axi_vdma_0[12] = 0x00010003; // S2MM_VDMACR(IRQFrameCount = 0x1, Circular_Park = 1, Run/stop = 1)
while((dviin_axi_vdma_0[13] & 0x1) == 0x1) ; // Halt? (S2MM_VDMASR 0x34)
dviin_axi_vdma_0[40] = XGA_VERTICAL_LINES; // S2MM Vertical Size (S2MM_VSIZE Offset 0xA0) 0x258 = 600dec
// CMOS Camera initialize, MT9D111
cam_i2c_init(caminf_axi_iic);
cam_i2c_write(caminf_axi_iic, 0xba, 0xf0, 0x1); // Changed regster map to IFP page 1
cam_i2c_write(caminf_axi_iic, 0xba, 0x97, 0x20); // RGB Mode, RGB565
caminf_mt9d111_inf_axis_0[1] = 0;
// Camera Base Address Setting
caminf_mt9d111_inf_axis_0[0] = (unsigned)phys_addr+3*SVGA_ALL_DISP_ADDRESS;; // Camera Interface start (Address is dummy)
// bitmap display controller settings
bmdc_axi_lites0[0] = (unsigned)phys_addr; // Bitmap Display Controller 0 start, My Camera Image
c = getc(stdin);
while(c != 'q'){
switch ((char)c) {
case '1' :
bmdc_axi_lites0[0] = (unsigned)phys_addr; // Bitmap Display Controller 0 start, My Camera Image
break;
case '2' :
bmdc_axi_lites0[0] = (unsigned)phys_addr+3*SVGA_ALL_DISP_ADDRESS+0x8; // Another one ZYBO Camera Image
break;
case 's' :
if (caminf_mt9d111_inf_axis_0[1] == 0)
caminf_mt9d111_inf_axis_0[1] = 1; // left camera is stopped.
else
caminf_mt9d111_inf_axis_0[1] = 0; // left camere is started.
break;
case 'l' : // laplacian filter
// caminf_axis_switch_1, 1to2 ,Select M01_AXIS
// Refer to http://marsee101.blog19.fc2.com/blog-entry-3177.html
caminf_axis_switch_1[16] = 0x80000000; // 0x40 = 0x80000000; disable
caminf_axis_switch_1[17] = 0; // 0x44 = 0;
caminf_axis_switch_1[0] = 0x2; // 0x0 = 2; Commit registers
// laplacian filter AXIS Start
laps_cntrl = caminf_lap_filter_axis_0[0] & 0x80; // Auto Restart bit
caminf_lap_filter_axis_0[0] = laps_cntrl | 0x01; // Start bit set
caminf_lap_filter_axis_0[0] = 0x80; // Auto Restart bit set
// caminf_axis_switch_0, 2to1, Select S01_AXIS
// Refer to http://marsee101.blog19.fc2.com/blog-entry-3177.html
caminf_axis_switch_0[16] = 0x1; // 0x40 = 0x1;
caminf_axis_switch_0[0] = 0x2; // 0x0 = 2; Commit registers
break;
case 'c' : // camera image
// caminf_axis_switch_1, 1to2 ,Select M01_AXIS
// Refer to http://marsee101.blog19.fc2.com/blog-entry-3177.html
caminf_axis_switch_1[16] = 0; // 0x44 = 0;
caminf_axis_switch_1[17] = 0x80000000; // 0x40 = 0x80000000; disable
caminf_axis_switch_1[0] = 0x2; // 0x0 = 2; Commit registers
// laplacian filter AXIS Start
caminf_lap_filter_axis_0[0] = 0x00; // Auto Restart Disable
// caminf_axis_switch_0, 2to1, Select S01_AXIS
// Refer to http://marsee101.blog19.fc2.com/blog-entry-3177.html
caminf_axis_switch_0[16] = 0x0; // 0x40 = 0x0;
caminf_axis_switch_0[0] = 0x2; // 0x0 = 2; Commit registers
break;
}
c = getc(stdin);
}
munmap((void *)bmdc_axi_lites0, 0x10000);
munmap((void *)caminf_axi_vdma_0, 0x10000);
munmap((void *)dviin_axi_vdma_0, 0x10000);
munmap((void *)caminf_axi_iic, 0x10000);
munmap((void *)caminf_mt9d111_inf_axis_0, 0x10000);
munmap((void *)caminf_axis_switch_0, 0x10000);
munmap((void *)caminf_axis_switch_1, 0x10000);
munmap((void *)caminf_lap_filter_axis_0, 0x10000);
munmap((void *)frame_buffer, (XGA_ALL_DISP_ADDRESS*NUMBER_OF_WRITE_FRAMES)+(SVGA_ALL_DISP_ADDRESS*NUMBER_OF_WRITE_FRAMES));
close(fd0);
close(fd1);
close(fd2);
close(fd3);
close(fd4);
close(fd5);
close(fd6);
close(fd7);
close(fd9);
close(fd10);
return(0);
}
距離 (m) | 左右視差 (pixels) | 上下視差 (Lines) |
---|---|---|
0.5 | 304 | -11 |
0.6 | 249 | -14 |
0.7 | 213 | -14 |
0.8 | 183 | -14 |
0.9 | 161 | -14 |
1.0 | 149 | -14 |
1.2 | 119 | -20 |
1.4 | 99 | -20 |
1.5 | 90 | -20 |
1.6 | 81 | -20 |
1.8 | 69 | -20 |
2.0 | 61 | -20 |
2.2 | 57 | -20 |
となっている。c : 右目カメラ画像の横方向の幅を指定する(初期値: 160 ピクセル)
r : 右目カメラ画像の縦方向の幅を指定する(初期値: 120 行)
d : 右目カメラ画像の横方向の切り取り位置(初期値: 0 ピクセル)
s : 右目カメラ画像の縦方向の切り取り位置(初期値: 0 ピクセル)
j : 左へ 1 ピクセル移動
k : 右へ 1 ピクセル移動
h : 左へ 10 ピクセル移動
l (Lの小文字): 右へ 10 ピクセル移動
g : 左へ 30 ピクセル移動
; : 右へ 30 ピクセル移動
i : 上へ 1 ピクセル移動
u : 上へ 10 ピクセル移動
m : 下へ 1 ピクセル移動
n : 下へ 10 ピクセル移動
//
// RL_alpha_blend.c by marsee
// 2016/02/06
//
// 800 pixels x 600 lines x 4 bytes x 3 pictures + 1024 pixels x 768 lines x 4 bytes x 3 pictures +
// 800 pixels x 600 lines x 4 bytes(alpha blend area for Right camera and Left camera) = 17117184
//
// When you press the j key, right camera image is moved one pixel to the left.
// When you press the k key, right camera image is moved one pixel to the right.
// When you press the h key, right camera image is moved ten pixels to the left.
// When you press the l key, right camera image is moved ten pixels to the right.
// When you press the i key, right camera image is moved one pixel to the up.
// When you press the m key, right camera image is moved one pixel to the down.
//
// Usage : RL_alpha_blend [-c 80] [-r 60] [-h]
// -c and -r indicates the area to be cut out of the left edge of the right-eye camera image.
//
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <sys/mman.h>
#include <fcntl.h>
#define PIXEL_NUM_OF_BYTES 4
#define NUMBER_OF_WRITE_FRAMES 3 // Note: If not at least 3 or more, the image is not displayed in succession.
#define XGA_HORIZONTAL_PIXELS 1024
#define XGA_VERTICAL_LINES 768
#define XGA_ALL_DISP_ADDRESS (XGA_HORIZONTAL_PIXELS * XGA_VERTICAL_LINES * PIXEL_NUM_OF_BYTES)
#define XGA_3_PICTURES (XGA_ALL_DISP_ADDRESS * NUMBER_OF_WRITE_FRAMES)
#define SVGA_HORIZONTAL_PIXELS 800
#define SVGA_VERTICAL_LINES 600
#define SVGA_ALL_DISP_ADDRESS (SVGA_HORIZONTAL_PIXELS * SVGA_VERTICAL_LINES * PIXEL_NUM_OF_BYTES)
#define SVGA_3_PICTURES (SVGA_ALL_DISP_ADDRESS * NUMBER_OF_WRITE_FRAMES)
#define DEFAULT_RECTANGLE_PIXELS 160
#define DEFAULT_RECTANGLE_LINES 120
int half_bright(int pixel);
int alpha_blend(int pixel1, int pixel2);
int main(int argc, char *argv[]){
int column_width = DEFAULT_RECTANGLE_PIXELS;
int row_width = DEFAULT_RECTANGLE_LINES;
int opt, c;
int help_flag = 0;
int fdf, fdp, fd6;
volatile unsigned *frame_buffer;
volatile unsigned *bmdc_axi_lites0;
unsigned char attr[1024];
unsigned long phys_addr;
volatile unsigned *Leye_addr, *alpha_addr;
int i, j;
volatile unsigned *Reye_start_addr, *Reye_stride;
volatile unsigned *abdisp_start_addr, *abdisp_addr;
volatile unsigned *s, *t;
unsigned int buf_size;
int offset_row=0, offset_column=0;
int reye_img_offset_row=0, reye_img_offset_column=0;
while ((opt=getopt(argc, argv, "c:r:d:s:h")) != -1){
switch (opt){
case 'c':
column_width = atoi(optarg);
break;
case 'r':
row_width = atoi(optarg);
break;
case 'd':
reye_img_offset_column = atoi(optarg);
break;
case 's':
reye_img_offset_row = atoi(optarg);
break;
case 'h':
help_flag = 1;
break;
}
}
printf("column_width = %d, row_width = %dn", column_width, row_width);
printf("reye_img_offset_column = %d, reye_img_offset_row = %dn", reye_img_offset_column, reye_img_offset_row);
if (help_flag == 1){ // help
printf("Usage : RL_alpha_blend [-c 160] [-r 120] [-d 0] [-s 0] [-h]n");
printf("-c: column_width, -r: row_widthn");
printf("-d: column of right eys's camere image offset, -s: row of right eys's camere image offsetn");
printf("-c and -r indicates the area to be cut out of the left edge of the right-eye camera image.n");
printf("n");
printf("Key bindn");
printf("j: left 1 pixelnk: right 1 pixelnh: left 10 pixelsnl: right 10 pixelsn");
printf("g: left 30 pixelsn';': right 30 pixelsn");
printf("i: up 1 pixelnu: up 10 pixelsnm: down 1 pixelnn: down 10 pixelsn");
return(0);
}
// Bitmap Display Controller 0 AXI4 Lite Slave (UIO6)
fd6 = open("/dev/uio6", O_RDWR); // bitmap_display_controller 0 axi4 lite
if (fd6 < 1){
fprintf(stderr, "/dev/uio6 (bitmap_disp_cntrler_axi_master_0) open errorn");
exit(-1);
}
bmdc_axi_lites0 = (volatile unsigned *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd6, 0);
if (!bmdc_axi_lites0){
fprintf(stderr, "bmdc_axi_lites0 mmap errorn");
exit(-1);
}
// udmabuf0
fdf = open("/dev/udmabuf0", O_RDWR | O_SYNC); // frame_buffer, The chache is disabled.
if (fdf == -1){
fprintf(stderr, "/dev/udmabuf0 open errorn");
exit(-1);
}
frame_buffer = (volatile unsigned *)mmap(NULL, SVGA_3_PICTURES+XGA_3_PICTURES+SVGA_ALL_DISP_ADDRESS, PROT_READ|PROT_WRITE, MAP_SHARED, fdf, 0);
if (!frame_buffer){
fprintf(stderr, "frame_buffer mmap errorn");
exit(-1);
}
// phys_addr of udmabuf0
fdp = open("/sys/devices/virtual/udmabuf/udmabuf0/phys_addr", O_RDONLY);
if (fdp == -1){
fprintf(stderr, "/sys/devices/virtual/udmabuf/udmabuf0/phys_addr open errorn");
exit(-1);
}
read(fdp, attr, 1024);
sscanf(attr, "%lx", &phys_addr);
close(fdp);
printf("phys_addr = %xn", (int)phys_addr);
// buf_size of udmabuf0
fdp = open("/sys/devices/virtual/udmabuf/udmabuf0/size", O_RDONLY);
if (fdp == -1){
fprintf(stderr, "/sys/devices/virtual/udmabuf/udmabuf0/size open errorn");
exit(-1);
}
read(fdp, attr, 1024);
sscanf(attr, "%d", &buf_size);
close(fdp);
printf("buf_size = %dn", (int)buf_size);
// Display the left-eye camera image
Leye_addr = frame_buffer;
alpha_addr = (volatile unsigned *)((unsigned)frame_buffer+SVGA_3_PICTURES+XGA_3_PICTURES);
s = alpha_addr;
t = Leye_addr;
for (i=0; i<SVGA_VERTICAL_LINES; i++){
for (j=0; j<SVGA_HORIZONTAL_PIXELS; j++){
*s = *t;
s++;
t++;
}
}
bmdc_axi_lites0[0] = (unsigned)phys_addr+SVGA_3_PICTURES+XGA_3_PICTURES;
// Display the right eye camera image, taken in a rectangular
Reye_start_addr = (volatile unsigned *)((unsigned)frame_buffer + SVGA_3_PICTURES + (SVGA_HORIZONTAL_PIXELS * (SVGA_VERTICAL_LINES - row_width)/2 * PIXEL_NUM_OF_BYTES)+0x8+reye_img_offset_column+(SVGA_HORIZONTAL_PIXELS * reye_img_offset_row * PIXEL_NUM_OF_BYTES)); // left edge + offset
Reye_stride = (volatile unsigned *)((SVGA_HORIZONTAL_PIXELS - column_width)*PIXEL_NUM_OF_BYTES);
abdisp_start_addr = (volatile unsigned *)((unsigned)frame_buffer + SVGA_3_PICTURES + XGA_3_PICTURES+ (SVGA_HORIZONTAL_PIXELS * (SVGA_VERTICAL_LINES - row_width)/2 * PIXEL_NUM_OF_BYTES));
abdisp_addr = abdisp_start_addr;
s = abdisp_addr;
t = Reye_start_addr;
for (i=0; i<row_width; i++){
for (j=0; j<column_width; j++){
*s = alpha_blend(*s, *t);
s++;
t++;
}
s = (volatile unsigned *)((unsigned)s+ (unsigned)Reye_stride);
t = (volatile unsigned *)((unsigned)t + (unsigned)Reye_stride);
}
printf("offset_row = %d pixels, offset_column = %d linesn", offset_row, offset_column);
// j, k, h, l, i, m , q key
while(c != 'q'){
c = getc(stdin);
switch ((char)c) {
case 'j' : // left 1 pixel
abdisp_addr--;
offset_row--;
break;
case 'k' : // right 1 pixel
abdisp_addr++;
offset_row++;
break;
case 'h' : // left 10 pixels
abdisp_addr -= 10;
offset_row -= 10;
break;
case 'l' : // right 10 pixels
abdisp_addr += 10;
offset_row += 10;
break;
case 'g' : // left 30 pixels
abdisp_addr -= 30;
offset_row -= 30;
break;
case ';' : // right 30 pixels
abdisp_addr += 30;
offset_row += 30;
break;
case 'i' : // up 1 pixel
abdisp_addr -= SVGA_HORIZONTAL_PIXELS;
offset_column--;
break;
case 'u' : // up 10 pixel
abdisp_addr -= (SVGA_HORIZONTAL_PIXELS*10);
offset_column -= 10;
break;
case 'm' : // down 1 pixel
abdisp_addr += SVGA_HORIZONTAL_PIXELS;
offset_column++;
break;
case 'n' : // down 10 pixel
abdisp_addr += (SVGA_HORIZONTAL_PIXELS*10);
offset_column += 10;
break;
}
// Display the left-eye camera image
s = alpha_addr;
t = Leye_addr;
for (i=0; i<SVGA_VERTICAL_LINES; i++){
for (j=0; j<SVGA_HORIZONTAL_PIXELS; j++){
*s = *t;
s++;
t++;
}
}
// Display the right eye camera image, taken in a rectangular
s = abdisp_addr;
t = Reye_start_addr;
for (i=0; i<row_width; i++){
for (j=0; j<column_width; j++){
*s = alpha_blend(*s, *t);
s++;
t++;
}
s = (volatile unsigned *)((unsigned)s+ (unsigned)Reye_stride);
t = (volatile unsigned *)((unsigned)t + (unsigned)Reye_stride);
}
if (c != 'n')
printf("offset_row = %d pixels, offset_column = %d linesn", offset_row, offset_column);
}
munmap((void *)bmdc_axi_lites0, 0x10000);
munmap((void *)frame_buffer, (SVGA_3_PICTURES+XGA_3_PICTURES+SVGA_ALL_DISP_ADDRESS));
close(fd6);
close(fdf);
return(0);
}
int half_bright(int pixel){
int hpixel = 0;
hpixel = (pixel & 0xff)/2;
hpixel |= (pixel & 0xff00)/2;
hpixel |= (pixel & 0xff0000)/2;
return(hpixel);
}
int alpha_blend(int pixel1, int pixel2){
int r, g, b;
b = (pixel1 & 0xff)/2 + (pixel2 & 0xff)/2;
g = ((pixel1 & 0xff00)/2 + (pixel2 & 0xff00)/2) & 0xff00;
r = ((pixel1 & 0xff0000)/2 + (pixel2 & 0xff0000)/2) & 0xff0000;
return(b+g+r);
}
j キーで 1 ピクセル左へ移動
k キーで 1 ピクセル右へ移動
h キーで 10 ピクセル左へ移動
l (Lの小文字)キーで 10 ピクセル右へ移動
i キーで 1 ピクセル上へ移動
m キーで 1 ピクセル下に移動
sudo insmod udmabuf.ko udmabuf0=15197184
sudo chmod 666 /dev/udmabuf0
という処理を行う。1 とリターンキーを押すと自分のカメラ画像を表示する。
2 とリターンキーを押すと右目用ZYBO からHDMI ポート経由で転送されてきた画像を表示する。
l (Lの小文字)とリターンキーを押すと、自分のカメラ画像にラプラシアンフィルタ処理を施す。
c とリターンキーを押すと、カメラ画像に戻る。
q とリターンキーで、アプリケーションを終了する。
//
// StereoCam_Alt_Disp.c
// 2016/02/01 by marsee
//
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <sys/mman.h>
#include <fcntl.h>
#define PIXEL_NUM_OF_BYTES 4
#define NUMBER_OF_WRITE_FRAMES 3 // Note: If not at least 3 or more, the image is not displayed in succession.
#define XGA_HORIZONTAL_PIXELS 1024
#define XGA_VERTICAL_LINES 768
#define XGA_ALL_DISP_ADDRESS (XGA_HORIZONTAL_PIXELS*XGA_VERTICAL_LINES*PIXEL_NUM_OF_BYTES)
#define SVGA_HORIZONTAL_PIXELS 800
#define SVGA_VERTICAL_LINES 600
#define SVGA_ALL_DISP_ADDRESS (SVGA_HORIZONTAL_PIXELS*SVGA_VERTICAL_LINES*PIXEL_NUM_OF_BYTES)
void cam_i2c_init(volatile unsigned *caminf_axi_iic) {
caminf_axi_iic[64] = 0x2; // reset tx fifo ,address is 0x100, i2c_control_reg
caminf_axi_iic[64] = 0x1; // enable i2c
}
void cam_i2x_write_sync(void) {
// unsigned c;
// c = *cam_i2c_rx_fifo;
// while ((c & 0x84) != 0x80)
// c = *cam_i2c_rx_fifo; // No Bus Busy and TX_FIFO_Empty = 1
usleep(1000);
}
void cam_i2c_write(volatile unsigned *caminf_axi_iic, unsigned int device_addr, unsigned int write_addr, unsigned int write_data){
caminf_axi_iic[66] = 0x100 | (device_addr & 0xfe); // Slave IIC Write Address, address is 0x108, i2c_tx_fifo
caminf_axi_iic[66] = write_addr;
caminf_axi_iic[66] = (write_data >> 8)|0xff; // first data
caminf_axi_iic[66] = 0x200 | (write_data & 0xff); // second data
cam_i2x_write_sync();
}
int main()
{
int fd0, fd1, fd2, fd3, fd4, fd5, fd6, fd7, fd9, fd10;
volatile unsigned *bmdc_axi_lites0;
volatile unsigned *caminf_axi_vdma_0, *dviin_axi_vdma_0;
volatile unsigned *caminf_axis_switch_0, *caminf_axis_switch_1;
volatile unsigned *caminf_mt9d111_inf_axis_0;
volatile unsigned *caminf_axi_iic;
volatile unsigned *caminf_lap_filter_axis_0;
volatile unsigned *frame_buffer;
unsigned char attr[1024];
unsigned long phys_addr;
char c;
int laps_cntrl;
// Bitmap Display Controller 0 AXI4 Lite Slave (UIO6)
fd6 = open("/dev/uio6", O_RDWR); // bitmap_display_controller 0 axi4 lite
if (fd6 < 1){
fprintf(stderr, "/dev/uio6 (bitmap_disp_cntrler_axi_master_0) open error\n");
exit(-1);
}
bmdc_axi_lites0 = (volatile unsigned *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd6, 0);
if (!bmdc_axi_lites0){
fprintf(stderr, "bmdc_axi_lites0 mmap error\n");
exit(-1);
}
// caminf_axi_vdma_0 (UIO1)
fd1 = open("/dev/uio1", O_RDWR); // caminf_axi_vdma_0 interface AXI4 Lite Slave
if (fd1 < 1){
fprintf(stderr, "/dev/uio1 (caminf_axi_vdma_0) open error\n");
exit(-1);
}
caminf_axi_vdma_0 = (volatile unsigned *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd1, 0);
if (!caminf_axi_vdma_0){
fprintf(stderr, "caminf_axi_vdma_0 mmap error\n");
exit(-1);
}
// dviin_axi_vdma_0 (UIO7)
fd7 = open("/dev/uio7", O_RDWR); // dviin_axi_vdma_0 interface AXI4 Lite Slave
if (fd7 < 1){
fprintf(stderr, "/dev/uio7 (dviin_axi_vdma_0) open error\n");
exit(-1);
}
dviin_axi_vdma_0 = (volatile unsigned *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd7, 0);
if (!dviin_axi_vdma_0){
fprintf(stderr, "dviin_axi_vdma_0 mmap error\n");
exit(-1);
}
// mt9d111 i2c AXI4 Lite Slave (UIO0)
fd0 = open("/dev/uio0", O_RDWR); // mt9d111 i2c AXI4 Lite Slave
if (fd0 < 1){
fprintf(stderr, "/dev/uio0 (caminf_axi_iic) open error\n");
exit(-1);
}
caminf_axi_iic = (volatile unsigned *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd0, 0);
if (!caminf_axi_iic){
fprintf(stderr, "caminf_axi_iic mmap error\n");
exit(-1);
}
// mt9d111 inf axis AXI4 Lite Slave (UIO5)
fd5 = open("/dev/uio5", O_RDWR); // mt9d111 inf axis AXI4 Lite Slave
if (fd5 < 1){
fprintf(stderr, "/dev/uio5 (caminf_mt9d111_inf_axis_0) open error\n");
exit(-1);
}
caminf_mt9d111_inf_axis_0 = (volatile unsigned *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd5, 0);
if (!caminf_mt9d111_inf_axis_0){
fprintf(stderr, "caminf_mt9d111_inf_axis_0 mmap error\n");
exit(-1);
}
// caminf_axis_switch_0 (UIO2)
fd2 = open("/dev/uio2", O_RDWR); // caminf_axis_switch_0 interface AXI4 Lite Slave
if (fd2 < 1){
fprintf(stderr, "/dev/uio2 (caminf_axis_switch_0) open error\n");
exit(-1);
}
caminf_axis_switch_0 = (volatile unsigned *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd2, 0);
if (!caminf_axis_switch_0){
fprintf(stderr, "caminf_axis_switch_0 mmap error\n");
exit(-1);
}
// caminf_axis_switch_1 (UIO3)
fd3 = open("/dev/uio3", O_RDWR); // caminf_axis_switch_1 interface AXI4 Lite Slave
if (fd3 < 1){
fprintf(stderr, "/dev/uio3 (caminf_axis_switch_1) open error\n");
exit(-1);
}
caminf_axis_switch_1 = (volatile unsigned *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd3, 0);
if (!caminf_axis_switch_1){
fprintf(stderr, "caminf_axis_switch_1 mmap error\n");
exit(-1);
}
// caminf_lap_filter_axis_0 (UIO4)
fd4 = open("/dev/uio4", O_RDWR); // caminf_lap_filter_axis_0 interface AXI4 Lite Slave
if (fd4 < 1){
fprintf(stderr, "/dev/uio4 (caminf_lap_filter_axis_0) open error\n");
exit(-1);
}
caminf_lap_filter_axis_0 = (volatile unsigned *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd4, 0);
if (!caminf_lap_filter_axis_0){
fprintf(stderr, "caminf_lap_filter_axis_0 mmap error\n");
exit(-1);
}
// udmabuf0
fd9 = open("/dev/udmabuf0", O_RDWR | O_SYNC); // frame_buffer, The chache is disabled.
if (fd9 == -1){
fprintf(stderr, "/dev/udmabuf0 open error\n");
exit(-1);
}
frame_buffer = (volatile unsigned *)mmap(NULL, (XGA_ALL_DISP_ADDRESS*NUMBER_OF_WRITE_FRAMES)+(SVGA_ALL_DISP_ADDRESS*NUMBER_OF_WRITE_FRAMES), PROT_READ|PROT_WRITE, MAP_SHARED, fd9, 0);
if (!frame_buffer){
fprintf(stderr, "frame_buffer mmap error\n");
exit(-1);
}
// caminf_axis_switch_1, 1to2 ,Select M00_AXIS
// Refer to http://marsee101.blog19.fc2.com/blog-entry-3177.html
caminf_axis_switch_1[16] = 0x0; // 0x40 = 0
caminf_axis_switch_1[17] = 0x80000000; // 0x44 = 0x80000000, disable
caminf_axis_switch_1[0] = 0x2; // Comit registers
// caminf_axis_switch_0, 2to1, Select S00_AXIS
// Refer to http://marsee101.blog19.fc2.com/blog-entry-3177.html
caminf_axis_switch_0[16] = 0x0; // 0x40 = 0;
caminf_axis_switch_0[0] = 0x2; // Comit registers
// phys_addr of udmabuf0
fd10 = open("/sys/devices/virtual/udmabuf/udmabuf0/phys_addr", O_RDONLY);
if (fd10 == -1){
fprintf(stderr, "/sys/devices/virtual/udmabuf/udmabuf0/phys_addr open error\n");
exit(-1);
}
read(fd10, attr, 1024);
sscanf(attr, "%lx", &phys_addr);
close(fd10);
printf("phys_addr = %x\n", (unsigned)phys_addr);
// AXI VDMA Initialization sequence (caminf_axi_vdma_0)
caminf_axi_vdma_0[12] = 0x4; // S2MM_VDMACR (S2MM VDMA Control Register Offset 30h) is 0x4
while ((caminf_axi_vdma_0[12] & 0x4) == 0x4) ; // Reset is progress
caminf_axi_vdma_0[12] = 0x4; // S2MM_VDMACR (S2MM VDMA Control Register Offset 30h) is 0x4
while ((caminf_axi_vdma_0[12] & 0x4) == 0x4) ; // Reset is progress
caminf_axi_vdma_0[18] = NUMBER_OF_WRITE_FRAMES; // S2MM_FRMSTORE (0x48) register
caminf_axi_vdma_0[12] = 0x00010002; // S2MM_VDMACR(IRQFrameCount = 0x1, Circular_Park = 1)
caminf_axi_vdma_0[41] = SVGA_HORIZONTAL_PIXELS*PIXEL_NUM_OF_BYTES; // S2MM Horizontal Size Register(S2MM_HSIZE)0xc80 = 3200dec = 800 x 4
caminf_axi_vdma_0[42] = SVGA_HORIZONTAL_PIXELS*PIXEL_NUM_OF_BYTES; // S2MM Frame Delay and Stride Register(S2MM_FRMDLY_STRIDE)0xc80 = 3200dec = 800 x 4
caminf_axi_vdma_0[43] = (unsigned)phys_addr; // S2MM Start Address (1 to 16) Start Address 1
caminf_axi_vdma_0[44] = (unsigned)phys_addr+SVGA_ALL_DISP_ADDRESS; // S2MM Start Address (1 to 16) Start Address 2
caminf_axi_vdma_0[45] = (unsigned)phys_addr+2*SVGA_ALL_DISP_ADDRESS; // S2MM Start Address (1 to 16) Start Address 3
caminf_axi_vdma_0[12] = 0x00010003; // S2MM_VDMACR(IRQFrameCount = 0x1, Circular_Park = 1, Run/stop = 1)
while((caminf_axi_vdma_0[13] & 0x1) == 0x1) ; // Halt? (S2MM_VDMASR 0x34)
caminf_axi_vdma_0[40] = SVGA_VERTICAL_LINES; // S2MM Vertical Size (S2MM_VSIZE Offset 0xA0) 0x258 = 600dec
// AXI VDMA Initialization sequence (dviin_axi_vdma_0)
dviin_axi_vdma_0[12] = 0x4; // S2MM_VDMACR (S2MM VDMA Control Register Offset 30h) is 0x4
while ((dviin_axi_vdma_0[12] & 0x4) == 0x4) ; // Reset is progress
dviin_axi_vdma_0[12] = 0x4; // S2MM_VDMACR (S2MM VDMA Control Register Offset 30h) is 0x4
while ((dviin_axi_vdma_0[12] & 0x4) == 0x4) ; // Reset is progress
dviin_axi_vdma_0[18] = NUMBER_OF_WRITE_FRAMES; // S2MM_FRMSTORE (0x48) register
dviin_axi_vdma_0[12] = 0x00010002; // S2MM_VDMACR(IRQFrameCount = 0x1, Circular_Park = 1)
dviin_axi_vdma_0[41] = XGA_HORIZONTAL_PIXELS*PIXEL_NUM_OF_BYTES; // S2MM Horizontal Size Register(S2MM_HSIZE)0xc80 = 3200dec = 800 x 4
dviin_axi_vdma_0[42] = XGA_HORIZONTAL_PIXELS*PIXEL_NUM_OF_BYTES; // S2MM Frame Delay and Stride Register(S2MM_FRMDLY_STRIDE)0xc80 = 3200dec = 800 x 4
dviin_axi_vdma_0[43] = (unsigned)phys_addr+3*SVGA_ALL_DISP_ADDRESS; // S2MM Start Address (1 to 16) Start Address 1
dviin_axi_vdma_0[44] = (unsigned)phys_addr+3*SVGA_ALL_DISP_ADDRESS+XGA_ALL_DISP_ADDRESS; // S2MM Start Address (1 to 16) Start Address 2
dviin_axi_vdma_0[45] = (unsigned)phys_addr+3*SVGA_ALL_DISP_ADDRESS+2*XGA_ALL_DISP_ADDRESS; // S2MM Start Address (1 to 16) Start Address 3
dviin_axi_vdma_0[12] = 0x00010003; // S2MM_VDMACR(IRQFrameCount = 0x1, Circular_Park = 1, Run/stop = 1)
while((dviin_axi_vdma_0[13] & 0x1) == 0x1) ; // Halt? (S2MM_VDMASR 0x34)
dviin_axi_vdma_0[40] = XGA_VERTICAL_LINES; // S2MM Vertical Size (S2MM_VSIZE Offset 0xA0) 0x258 = 600dec
// CMOS Camera initialize, MT9D111
cam_i2c_init(caminf_axi_iic);
cam_i2c_write(caminf_axi_iic, 0xba, 0xf0, 0x1); // Changed regster map to IFP page 1
cam_i2c_write(caminf_axi_iic, 0xba, 0x97, 0x20); // RGB Mode, RGB565
caminf_mt9d111_inf_axis_0[1] = 0;
// Camera Base Address Setting
caminf_mt9d111_inf_axis_0[0] = (unsigned)phys_addr+3*SVGA_ALL_DISP_ADDRESS;; // Camera Interface start (Address is dummy)
// bitmap display controller settings
bmdc_axi_lites0[0] = (unsigned)phys_addr; // Bitmap Display Controller 0 start, My Camera Image
c = getc(stdin);
while(c != 'q'){
switch ((char)c) {
case '1' :
bmdc_axi_lites0[0] = (unsigned)phys_addr; // Bitmap Display Controller 0 start, My Camera Image
break;
case '2' :
bmdc_axi_lites0[0] = (unsigned)phys_addr+3*SVGA_ALL_DISP_ADDRESS+0xc; // Another one ZYBO Camera Image
break;
case 'l' : // laplacian filter
// caminf_axis_switch_1, 1to2 ,Select M01_AXIS
// Refer to http://marsee101.blog19.fc2.com/blog-entry-3177.html
caminf_axis_switch_1[16] = 0x80000000; // 0x40 = 0x80000000; disable
caminf_axis_switch_1[17] = 0; // 0x44 = 0;
caminf_axis_switch_1[0] = 0x2; // 0x0 = 2; Commit registers
// laplacian filter AXIS Start
laps_cntrl = caminf_lap_filter_axis_0[0] & 0x80; // Auto Restart bit
caminf_lap_filter_axis_0[0] = laps_cntrl | 0x01; // Start bit set
caminf_lap_filter_axis_0[0] = 0x80; // Auto Restart bit set
// caminf_axis_switch_0, 2to1, Select S01_AXIS
// Refer to http://marsee101.blog19.fc2.com/blog-entry-3177.html
caminf_axis_switch_0[16] = 0x1; // 0x40 = 0x1;
caminf_axis_switch_0[0] = 0x2; // 0x0 = 2; Commit registers
break;
case 'c' : // camera image
// caminf_axis_switch_1, 1to2 ,Select M01_AXIS
// Refer to http://marsee101.blog19.fc2.com/blog-entry-3177.html
caminf_axis_switch_1[16] = 0; // 0x44 = 0;
caminf_axis_switch_1[17] = 0x80000000; // 0x40 = 0x80000000; disable
caminf_axis_switch_1[0] = 0x2; // 0x0 = 2; Commit registers
// laplacian filter AXIS Start
caminf_lap_filter_axis_0[0] = 0x00; // Auto Restart Disable
// caminf_axis_switch_0, 2to1, Select S01_AXIS
// Refer to http://marsee101.blog19.fc2.com/blog-entry-3177.html
caminf_axis_switch_0[16] = 0x0; // 0x40 = 0x0;
caminf_axis_switch_0[0] = 0x2; // 0x0 = 2; Commit registers
break;
}
c = getc(stdin);
}
munmap((void *)bmdc_axi_lites0, 0x10000);
munmap((void *)caminf_axi_vdma_0, 0x10000);
munmap((void *)dviin_axi_vdma_0, 0x10000);
munmap((void *)caminf_axi_iic, 0x10000);
munmap((void *)caminf_mt9d111_inf_axis_0, 0x10000);
munmap((void *)caminf_axis_switch_0, 0x10000);
munmap((void *)caminf_axis_switch_1, 0x10000);
munmap((void *)caminf_lap_filter_axis_0, 0x10000);
munmap((void *)frame_buffer, (XGA_ALL_DISP_ADDRESS*NUMBER_OF_WRITE_FRAMES)+(SVGA_ALL_DISP_ADDRESS*NUMBER_OF_WRITE_FRAMES));
close(fd0);
close(fd1);
close(fd2);
close(fd3);
close(fd4);
close(fd5);
close(fd6);
close(fd7);
close(fd9);
close(fd10);
return(0);
}
日 | 月 | 火 | 水 | 木 | 金 | 土 |
---|---|---|---|---|---|---|
- | 1 | 2 | 3 | 4 | 5 | 6 |
7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 | - | - | - | - | - |