FC2カウンター FPGAの部屋 ZYBO用の Linaro Ubuntu のPL部にビットマップ・ディスプレイ・コントローラを搭載する7(ZYBOで動作確認)

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

FPGAの部屋

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

ZYBO用の Linaro Ubuntu のPL部にビットマップ・ディスプレイ・コントローラを搭載する7(ZYBOで動作確認)

ZYBO用の Linaro Ubuntu のPL部にビットマップ・ディスプレイ・コントローラを搭載する6(UIOの設定4)”の続き。

前回まで、UIOのテストを続けてきて、動作の確認ができたので、いよいよ本番のビットマップ・ディスプレイ・コントローラに意味のある文字を表示させて見るテストをする。前々から使ってきたビットマップ・ディスプレイ・コントローラにキャラクタ・ジェネレータROMのキャラクタ・データを表示するテストを行うことにした。このテストはLinux上ではなく、Zynqのスタンドアローン環境で動作するようになっているので、これをLinux に移植した。当然ながら、デバイスへのアクセスアはUIOを使用する。

draw_disp_uio.c を cc -o draw_disp_uio draw_disp_uio.c コマンドでコンパイルして、./draw_disp_uio コマンドで実行するとキャラクタは表示できたのだが、linaro ユーザーで開いていた SSH 接続のTera Termが落ちてしまった。
ZYBO_BMDCwASL_62_141004.jpg

シリアル接続のroot のTera Term には、

[ 166.816932] xemacps e000b000.ps7-ethernet: TX error 0x138

が表示された。ether が落ちてしまったようだ。

そう言えば、起動画面の

[ 0.000000] cma: CMA: reserved 128 MiB at 17800000

を信じてやってきたが、top コマンドの表示の

Mem: 506664k total, 68264k used, 438400k free

は、128MBをCMA領域に割り振られているにしては、Free メモリが多すぎる。
ZYBO_BMDCwASL_61_141004.png

やはり、CMA領域を確保する必要がありそうだ。

draw_disp_uio.c を下に貼っておく。

/* * draw_disp_uio.c * *  Created on: 2014/10/03 *      Author: Masaaki */

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

#define VIDEO_BUFFER_START_ADDRESS  0x17800000

#define HORIZONTAL_PIXEL    800
#define ALL_CHAR_OF_1LINE   (HORIZONTAL_PIXEL/8)
#define VERTICAL_PIXEL      600
#define ALL_CHAR_OF_ROW     (VERTICAL_PIXEL/8)
#define ALL_DISP_ADDRESS    (HORIZONTAL_PIXEL*VERTICAL_PIXEL*4)
#define ALL_DISP_CHARACTOR  HORIZONTAL_PIXEL*VERTICAL_PIXEL

// char_draw: Draw the character to receive a character code and address
// addr : Start address at drawing charactor
// char_code : drawing charactor code
// char_color : color of drawing charactor, represented by 32-bit, oRGB (8bits)
// return value :show a drawing start address of the next character
unsigned int *char_draw(unsigned *addr, unsigned *char_rom_axi_lite, unsigned char char_code, unsigned int char_color){
    int i,j;
    unsigned int char_pattern;
    unsigned int char_code_int;
    unsigned int *cal_char_addr;
    unsigned int *return_addr;

    char_code_int = (unsigned int)(char_code);
    return_addr = addr + 8;
    cal_char_addr = (unsigned int *)((unsigned)char_rom_axi_lite+((char_code_int<<3)<<2)); // Data of the character generator ROM is 32 bits wide, valid only 8 bits of the least significant
    for(i=0; i<8; i++){
        char_pattern = *(volatile unsigned int *)(cal_char_addr); // Reads the pattern of the character
        for(j=0; j<8; j++){
            if(char_pattern & 0x1// Drawing a dot when 7th bit is one
                *(volatile unsigned int *)((unsigned int)addr ^ 4) = char_color;
            else
                *(volatile unsigned int *)((unsigned int)addr ^ 4) = 0// drawing black
            addr++;
            char_pattern >>= 1// 1bit shift right
        }
        addr -= 8// Return to the address of the beginning of the line
        addr += HORIZONTAL_PIXEL; // Down one line
        cal_char_addr++;
    }

    return return_addr;
}

int main() {
    unsigned char char_code;
    unsigned *ddr2_addr;
    unsigned int coler_code;
    unsigned int char_cnt;
    int i, j, k;
    int fd0, fd1, fd3;
    volatile unsigned *bmdc_axis_lite;
    volatile unsigned *char_rom_axi_lite;
    volatile unsigned *bmdc_axim;

    // Bitmap Display Controller AXI4 Lite Slave (UIO0)
    fd0 = open("/dev/uio0", O_RDWR); // bitmap_display_controller axi4 lite
    if (fd0 < 1){
        fprintf(stderr, "/dev/uio0 open error\n");
        exit(-1);
    }
    bmdc_axis_lite = (volatile unsigned *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd0, 0);
    if (!bmdc_axis_lite){
        fprintf(stderr, "mmap error\n");
        exit(-1);
    }
    bmdc_axis_lite[0] = VIDEO_BUFFER_START_ADDRESS; // Bitmap Display Controller start
    munmap((void *)bmdc_axis_lite, 0x10000);

    // Charactor Generate ROM UIO1
    fd1 = open("/dev/uio1", O_RDWR); // char_rom_axi4 lite
    if (fd1 < 1){
        fprintf(stderr, "/dev/uio1 open error\n");
        exit(-1);
    }
    char_rom_axi_lite = (volatile unsigned *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd1, 0);
    if (!char_rom_axi_lite){
        fprintf(stderr, "mmap error\n");
        exit(-1);
    }

    // Bitmap Display Controller AXI4 Master UIO3
    fd3 = open("/dev/uio3", O_RDWR); // bitmap_display_controller FB
    if (fd3 < 1){
        fprintf(stderr, "/dev/uio3 open error\n");
        exit(-1);
    }
    bmdc_axim = (volatile unsigned *)mmap(NULL, 0x1000000, PROT_READ|PROT_WRITE, MAP_SHARED, fd3, 0);
    if (!bmdc_axim){
        fprintf(stderr, "mmap error\n");
        exit(-1);
    }

   // Clean display
    for (k=0; k < ALL_DISP_CHARACTOR; k++){
        bmdc_axim[k] = 0;
    }

    // Charactor output
    ddr2_addr = (unsigned *)bmdc_axim;
    char_cnt = 0;
    for(j=0; j<((ALL_CHAR_OF_1LINE*ALL_CHAR_OF_ROW)/((128-33)*7))+1; j++){
        for(i=1; i<8; i++){
            switch(i){
                case 1 :
                    coler_code = 0xff; // blue
                    break;
                case 2 :
                    coler_code = 0xff00; // Green
                    break;
                case 3 :
                    coler_code = 0xffff; // Cyan
                    break;
                case 4 :
                    coler_code = 0xff0000; // Red
                    break;
                case 5 :
                    coler_code = 0xff00ff; // Magenta
                    break;
                case 6 :
                    coler_code = 0xffff00; // Yellow
                    break;
                case 7 :
                    coler_code = 0xffffff; // Write
                    break;
            }

            for(char_code=0x21; char_code<0x80; char_code++){
                if(char_code >= 0x80// Character code has reached the upper limit, back into the bottom
                    char_code = 0x21;
                if (char_cnt!=0 && char_cnt%ALL_CHAR_OF_1LINE==0)
                    ddr2_addr = (unsigned *)((unsigned int)ddr2_addr + HORIZONTAL_PIXEL*4*7); // Having finished writing a single line, the line below, the address HORIZONTAL_PIXELx1 pixel 4 bytes x7 line
                ddr2_addr = char_draw(ddr2_addr, (unsigned int *)char_rom_axi_lite, char_code, coler_code); // Draw charactor
                char_cnt++;
            }
        }
    }

    munmap((void *)char_rom_axi_lite, 0x10000);
    munmap((void *)bmdc_axim, 0x1000000);

    return 0;
}


ZYBO用LinuxカーネルにCMA領域を確保1”に続く。
  1. 2014年10月04日 11:13 |
  2. ZYBO
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


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

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