FC2カウンター FPGAの部屋 Vivadoを使用してZYBO_0_163_6フォルダのプロジェクトにRGB2HSV IPを追加6(UbuntuでRGB2HSVを試す)

FPGAやCPLDの話題やFPGA用のツールの話題などです。 マニアックです。 日記も書きます。

FPGAの部屋

FPGAの部屋の有用と思われるコンテンツのまとめサイトを作りました。Xilinx ISEの初心者の方には、FPGAリテラシーおよびチュートリアルのページをお勧めいたします。

Vivadoを使用してZYBO_0_163_6フォルダのプロジェクトにRGB2HSV IPを追加6(UbuntuでRGB2HSVを試す)

Vivadoを使用してZYBO_0_163_6フォルダのプロジェクトにRGB2HSV IPを追加5(Ubuntuでの動作)”の続き。

前回は、BOOT.bin や devicetree.dtb を作成して、SDカードに書き込み、ZYBOに挿入して電源ONした。Ubuntu が起動して、それ上でカメラの動作を確認できた。今回は、RGB2HSV IP を使うアプリケーション・ソフトウェアを作成して、RGB2HSV変換を行った。

まずは、
./udmabuf_insmod
./cam_disp_plat

コマンドでカメラ画像を表示させた。
platoon_16_161118.png

まずは、./rgb2hsv_rev_plat コマンドで、RGB2HSV した画像をRGB に戻した。これは通常のカメラ画像と同じだった。

次に、./rgb2hsv_ho_plat コマンドで、S と V を 255 にしたときのRGB の値を出力するようにした。
platoon_17_161118.png

最初に原画像を示す。
platoon_18_161119.jpg

rgb2hsv_ho_plat を実行したときの画像を示す。
platoon_19_161119.jpg

rgb2hsv_rec_plat.c を貼っておく。rgb2hsv_ho_plat.c はrgb2hsv_rec_plat.c の while(1) ループで強制的に max = 255; min = 0; にしている。

//
// rgb2hsv_rev_plat.c
// Created on: 2016/11/15
//      Author: marsee
//
// Refered to http://japan.xilinx.com/support/documentation/sw_manuals_j/xilinx2014_4/ug902-vivado-high-level-synthesis.pdf
//

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <sys/mman.h>
#include <fcntl.h>

#define CMA_START_ADDRESS 0x17800000
#define VIDEO_BUFFER_START_ADDRESS  0x18000000    // Limit 0x18800000, 800*600*4 = 2MBytes * 2

#define HORIZONTAL_PIXELS    800
#define ALL_CHAR_OF_1LINE   (HORIZONTAL_PIXELS/8)
#define VERTICAL_LINES      600
#define ALL_CHAR_OF_ROW     (VERTICAL_LINES/8)
#define ALL_DISP_ADDRESS    (HORIZONTAL_PIXELS*VERTICAL_LINES*4)
#define ALL_DISP_CHARACTOR  (HORIZONTAL_PIXELS*VERTICAL_LINES)

int main(){
    int fd1, fd2, fd3, fd4, fd6, fd7, fd9, fd10;
    volatile unsigned *axis_switch_0, *axis_switch_1;
    volatile unsigned *rgb2hsv_0;
    volatile unsigned *dmaw4gabor_0;
    volatile unsigned *bmdc_axi_lites0, *bmdc_axi_lites1;
    volatile unsigned *frame_buffer_bmdc;
    unsigned char  attr[1024];
    unsigned long  phys_addr;
    int i, j;
    int max, min;
    int h, s, v;
    int r, g, b;
    volatile int *fb_hsv, *fb_rgb;


    // axis_switch_0 (UIO2)
    fd2 = open("/dev/uio2", O_RDWR); // axis_switch_0 interface AXI4 Lite Slave
    if (fd2 < 1){
        fprintf(stderr, "/dev/uio2 (axis_switch_0) open error\n");
        exit(-1);
    }
    axis_switch_0 = (volatile unsigned *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd2, 0);
    if (!axis_switch_0){
        fprintf(stderr, "axis_switch_0 mmap error\n");
        exit(-1);
    }
    
    // axis_switch_1 (UIO3)
    fd3 = open("/dev/uio3", O_RDWR); // axis_switch_1 interface AXI4 Lite Slave
    if (fd3 < 1){
        fprintf(stderr, "/dev/uio3 (axis_switch_1) open error\n");
        exit(-1);
    }
    axis_switch_1 = (volatile unsigned *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd3, 0);
    if (!axis_switch_1){
        fprintf(stderr, "axis_switch_1 mmap error\n");
        exit(-1);
    }
    
    // rgb2hsv_0 (UIO15)
    fd4 = open("/dev/uio15", O_RDWR); // rgb2hsv_0 interface AXI4 Lite Slave
    if (fd4 < 1){
        fprintf(stderr, "/dev/uio14 (rgb2hsv_0) open error\n");
        exit(-1);
    }
    rgb2hsv_0 = (volatile unsigned *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd4, 0);
    if (!rgb2hsv_0){
        fprintf(stderr, "lap_filter_axis_0 mmap error\n");
        exit(-1);
    }
    
    // dmaw4gabor_0 (UIO1)
    fd1 = open("/dev/uio1", O_RDWR); // dmaw4gabor_0 interface AXI4 Lite Slave
    if (fd1 < 1){
        fprintf(stderr, "/dev/uio1 (dmaw4gabor_0) open error\n");
        exit(-1);
    }
    dmaw4gabor_0 = (volatile unsigned *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd1, 0);
    if (!dmaw4gabor_0){
        fprintf(stderr, "dmaw4gabor_0 mmap error\n");
        exit(-1);
    }
    
    // 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);
    }
    
    // Bitmap Display Controller 1 AXI4 Lite Slave (UIO7)
    fd7 = open("/dev/uio7", O_RDWR); // bitmap_display_controller axi4 lite
    if (fd7 < 1){
        fprintf(stderr, "/dev/uio7 (bitmap_disp_cntrler_axi_master_0) open error\n");
        exit(-1);
    }
    bmdc_axi_lites1 = (volatile unsigned *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd7, 0);
    if (!bmdc_axi_lites1){
        fprintf(stderr, "bmdc_axi_lites1 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_bmdc = (volatile unsigned *)mmap(NULL, 5760000, PROT_READ|PROT_WRITE, MAP_SHARED, fd9, 0);
    if (!frame_buffer_bmdc){
        fprintf(stderr, "frame_buffer_bmdc mmap error\n");
        exit(-1);
    }

    // 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", (int)phys_addr);
    
    // axis_switch_1, 1to2 ,Select M01_AXIS
    // Refer to http://marsee101.blog19.fc2.com/blog-entry-3177.html
    axis_switch_1[16] = 0x80000000// 0x40 = 0x80000000; disable, through
    axis_switch_1[17] = 0x80000000// 0x44 = 0x80000000; disable, laplacian filter
    axis_switch_1[18] = 0x80000000// 0x48 = 0x80000000; disable, gabor filter
    axis_switch_1[19] = 0// 0x48 = 0; RGB2HSV
    axis_switch_1[0] = 0x2// 0x0 = 2; Commit registers
    
    // RGB2HSV AXIS Start
    rgb2hsv_0[0] = 0x01// Start bit set
    rgb2hsv_0[0] = 0x80// Auto Restart bit set
    
    // axis_switch_0, 2to1, Select S01_AXIS
    // Refer to http://marsee101.blog19.fc2.com/blog-entry-3177.html
    axis_switch_0[16] = 0x3// 0x40 = 0x2; RGB2HSV
    axis_switch_0[0] = 0x2// 0x0 = 2; Commit registers
    
    // bitmap display controller settings
    bmdc_axi_lites0[0] = (int)phys_addr+ALL_DISP_ADDRESS; // Bitmap Display Controller 0 start
    bmdc_axi_lites1[0] = (int)phys_addr+ALL_DISP_ADDRESS; // Bitmap Display Controller 1 start

    munmap((void *)axis_switch_0, 0x10000);
    munmap((void *)axis_switch_1, 0x10000);
    munmap((void *)rgb2hsv_0, 0x10000);
    munmap((void *)dmaw4gabor_0, 0x10000);
    munmap((void *)bmdc_axi_lites0, 0x10000);
    munmap((void *)bmdc_axi_lites1, 0x10000);
    
    close(fd1);
    close(fd2);
    close(fd3);
    close(fd4);
    close(fd6);
    close(fd7);
 
    fb_hsv = (volatile int *)frame_buffer_bmdc;
    fb_rgb = (volatile int *)((int)frame_buffer_bmdc+(int)ALL_DISP_ADDRESS); 

    while(1){
        for(j=0; j<VERTICAL_LINES; j++){
            for(i=0; i<HORIZONTAL_PIXELS; i++){
                h = (fb_hsv[HORIZONTAL_PIXELS*j+i]/65536) & 0x1ff;
                s = (fb_hsv[HORIZONTAL_PIXELS*j+i]/256) & 0xff;
                v = fb_hsv[HORIZONTAL_PIXELS*j+i] & 0xff;

                max = v;
                min = max - (int)(((float)s/255.0)*(float)max + 0.5);

                if(h>=0 && h<60){
                    r = max;
                    g = (int)(((float)h/60.0)*(float)(max-min)+0.5) + min;
                    b = min;
                }else if(h>=60 && h<120){
                    r = (int)(((120.0-(float)h)/60.0)*((float)(max-min))+0.5) + min;
                    g = max;
                    b = min;
                }else if(h>=120 && h<180){
                    r = min;
                    g = max;
                    b = (int)((((float)h-120.0)/60.0)*((float)(max-min))+0.5) + min;
                }else if(h>=180 && h<240){
                    r = min;
                    g = (int)(((240.0-(float)h)/60.0)*((float)(max-min))+0.5) + min;
                    b = max;
                }else if(h>=240 && h<300){
                    r = (int)((((float)h-240.0)/60.0)*((float)(max-min))+0.5) + min;
                    g = min;
                    b = max;
                }else{// if(h<=300 && h<=360){
                    r = max;
                    g = min;
                    b = (int)(((360.0-(float)h)/60.0)*((float)(max-min))+0.5) + min;
                }
                fb_rgb[HORIZONTAL_PIXELS*j+i] = (r&0xff)*65536 | (g&0xff)*256 | b&0xff;
            }
        }
        sleep(1);
    }
   
    munmap((void *)frame_buffer_bmdc, 576000);
    close(fd9);
    
    return(0);
}

  1. 2016年11月19日 04:22 |
  2. Zybot
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック URL
http://marsee101.blog19.fc2.com/tb.php/3636-7125d369
この記事にトラックバックする(FC2ブログユーザー)