/* * rgb2hsv_rev.c * * Created on: 2016/10/24 * Author: Masaaki */
// ソフトウェアでHSV2RGB変換を行う
#include <stdio.h>
#include <stdlib.h>
#include "xil_io.h"
#include "xparameters.h"
#include "xgabor_filter_lh.h"
#include "xdmaw4gabor.h"
#define HORIZONTAL_PIXELS 800
#define VERTICAL_LINES 600
#define PIXEL_NUM_OF_BYTES 4
#define FRAME_BUFFER_ADDRESS 0x10000000
#define ALL_DISP_ADDRESS (HORIZONTAL_PIXELS*VERTICAL_LINES*PIXEL_NUM_OF_BYTES)
int main(){
XGabor_filter_lh gabf;
XDmaw4gabor xdma4g;
XRgb2hsv_Initialize(&gabf, 0);
XRgb2hsv_Start(&gabf);
XRgb2hsv_EnableAutoRestart(&gabf);
int i, j;
int max, min;
int h, s, v;
int r, g, b;
volatile int *fb_hsv, *fb_rgb;
// axis_switch_1, 1to2 ,Select M00_AXIS
// Refer to http://marsee101.blog19.fc2.com/blog-entry-3177.html
Xil_Out32((XPAR_CAMERA_INTERFACE_AXIS_SWITCH_1_BASEADDR+0x40), 0x80000000);
Xil_Out32((XPAR_CAMERA_INTERFACE_AXIS_SWITCH_1_BASEADDR+0x44), 0x80000000); // disable
Xil_Out32((XPAR_CAMERA_INTERFACE_AXIS_SWITCH_1_BASEADDR+0x48), 0x80000000); // disable
Xil_Out32((XPAR_CAMERA_INTERFACE_AXIS_SWITCH_1_BASEADDR+0x4C), 0x0); // disable
Xil_Out32((XPAR_CAMERA_INTERFACE_AXIS_SWITCH_1_BASEADDR), 0x2); // Commit registers
// axis_switch_0, 2to1, Select S00_AXIS
// Refer to http://marsee101.blog19.fc2.com/blog-entry-3177.html
Xil_Out32((XPAR_CAMERA_INTERFACE_AXIS_SWITCH_0_BASEADDR+0x40), 0x3);
Xil_Out32((XPAR_CAMERA_INTERFACE_AXIS_SWITCH_0_BASEADDR), 0x2); // Commit registers
// DMAW4Gabor Address set
XDmaw4gabor_Initialize(&xdma4g, 0);
XDmaw4gabor_Set_frame_buffer0(&xdma4g, FRAME_BUFFER_ADDRESS);
XDmaw4gabor_Set_frame_buffer1(&xdma4g, FRAME_BUFFER_ADDRESS);
// Bitmap display Controller Address set
volatile int *bmdc0_axi_lites;
volatile int *bmdc1_axi_lites;
bmdc0_axi_lites = (volatile int *)XPAR_BITMAP_DISP_CNTRLER_AXI_MASTER_0_BASEADDR;
bmdc1_axi_lites = (volatile int *)XPAR_BITMAP_DISP_CNTRLER_AXI_MASTER_1_BASEADDR;
bmdc0_axi_lites[0] = (unsigned int)(FRAME_BUFFER_ADDRESS+ALL_DISP_ADDRESS); // Bitmap Display Controller 0 start
bmdc1_axi_lites[0] = (unsigned int)(FRAME_BUFFER_ADDRESS+ALL_DISP_ADDRESS); // Bitmap Display Controller 1 start
//bmdc0_axi_lites[0] = (unsigned int)(FRAME_BUFFER_ADDRESS); // Bitmap Display Controller 0 start
//bmdc1_axi_lites[0] = (unsigned int)(FRAME_BUFFER_ADDRESS); // Bitmap Display Controller 1 start
fb_hsv = (volatile int *)FRAME_BUFFER_ADDRESS;
fb_rgb = (volatile int *)((unsigned int)FRAME_BUFFER_ADDRESS+(unsigned 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); // 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;
}
}
Xil_DCacheFlush();
sleep(1);
}
return 0;
}
/* * rgb2hsv_ho.c * * Created on: 2016/10/24 * Author: ono */
// ソフトウェアでHSV2RGB変換するのだが、S=V=255として変換する。Hだけを変換。
#include <stdio.h>
#include <stdlib.h>
#include "xil_io.h"
#include "xparameters.h"
#include "xgabor_filter_lh.h"
#include "xdmaw4gabor.h"
#define HORIZONTAL_PIXELS 800
#define VERTICAL_LINES 600
#define PIXEL_NUM_OF_BYTES 4
#define FRAME_BUFFER_ADDRESS 0x10000000
#define ALL_DISP_ADDRESS (HORIZONTAL_PIXELS*VERTICAL_LINES*PIXEL_NUM_OF_BYTES)
int main(){
XGabor_filter_lh gabf;
XDmaw4gabor xdma4g;
XRgb2hsv_Initialize(&gabf, 0);
XRgb2hsv_Start(&gabf);
XRgb2hsv_EnableAutoRestart(&gabf);
int i, j;
int max, min;
int h, s, v;
int r, g, b;
volatile int *fb_hsv, *fb_rgb;
// axis_switch_1, 1to2 ,Select M00_AXIS
// Refer to http://marsee101.blog19.fc2.com/blog-entry-3177.html
Xil_Out32((XPAR_CAMERA_INTERFACE_AXIS_SWITCH_1_BASEADDR+0x40), 0x80000000);
Xil_Out32((XPAR_CAMERA_INTERFACE_AXIS_SWITCH_1_BASEADDR+0x44), 0x80000000); // disable
Xil_Out32((XPAR_CAMERA_INTERFACE_AXIS_SWITCH_1_BASEADDR+0x48), 0x80000000); // disable
Xil_Out32((XPAR_CAMERA_INTERFACE_AXIS_SWITCH_1_BASEADDR+0x4C), 0x0); // disable
Xil_Out32((XPAR_CAMERA_INTERFACE_AXIS_SWITCH_1_BASEADDR), 0x2); // Commit registers
// axis_switch_0, 2to1, Select S00_AXIS
// Refer to http://marsee101.blog19.fc2.com/blog-entry-3177.html
Xil_Out32((XPAR_CAMERA_INTERFACE_AXIS_SWITCH_0_BASEADDR+0x40), 0x3);
Xil_Out32((XPAR_CAMERA_INTERFACE_AXIS_SWITCH_0_BASEADDR), 0x2); // Commit registers
// DMAW4Gabor Address set
XDmaw4gabor_Initialize(&xdma4g, 0);
XDmaw4gabor_Set_frame_buffer0(&xdma4g, FRAME_BUFFER_ADDRESS);
XDmaw4gabor_Set_frame_buffer1(&xdma4g, FRAME_BUFFER_ADDRESS);
// Bitmap display Controller Address set
volatile int *bmdc0_axi_lites;
volatile int *bmdc1_axi_lites;
bmdc0_axi_lites = (volatile int *)XPAR_BITMAP_DISP_CNTRLER_AXI_MASTER_0_BASEADDR;
bmdc1_axi_lites = (volatile int *)XPAR_BITMAP_DISP_CNTRLER_AXI_MASTER_1_BASEADDR;
bmdc0_axi_lites[0] = (unsigned int)(FRAME_BUFFER_ADDRESS+ALL_DISP_ADDRESS); // Bitmap Display Controller 0 start
bmdc1_axi_lites[0] = (unsigned int)(FRAME_BUFFER_ADDRESS+ALL_DISP_ADDRESS); // Bitmap Display Controller 1 start
//bmdc0_axi_lites[0] = (unsigned int)(FRAME_BUFFER_ADDRESS); // Bitmap Display Controller 0 start
//bmdc1_axi_lites[0] = (unsigned int)(FRAME_BUFFER_ADDRESS); // Bitmap Display Controller 1 start
fb_hsv = (volatile int *)FRAME_BUFFER_ADDRESS;
fb_rgb = (volatile int *)((unsigned int)FRAME_BUFFER_ADDRESS+(unsigned 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;
max = 255;
min = 0;
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;
}
}
Xil_DCacheFlush();
sleep(1);
}
return 0;
}
を起動した。source ZYBO_0.tcl
/* * cam_disp_lgh.c * * Created on: 2016/10/22 * Author: Masaaki */
#include <stdio.h>
#include <stdlib.h>
#include "xil_io.h"
#include "xparameters.h"
#include "sleep.h"
#include "xdmaw4gabor.h"
#define NUMBER_OF_WRITE_FRAMES 3 // Note: If not at least 3 or more, the image is not displayed in succession.
#define HORIZONTAL_PIXELS 800
#define VERTICAL_LINES 600
#define PIXEL_NUM_OF_BYTES 4
#define FRAME_BUFFER_ADDRESS 0x10000000
#define ALL_DISP_ADDRESS (HORIZONTAL_PIXELS*VERTICAL_LINES*PIXEL_NUM_OF_BYTES)
void cam_i2c_init(volatile unsigned *mt9d111_i2c_axi_lites) {
mt9d111_i2c_axi_lites[64] = 0x2; // reset tx fifo ,address is 0x100, i2c_control_reg
mt9d111_i2c_axi_lites[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 *mt9d111_i2c_axi_lites, unsigned int device_addr, unsigned int write_addr, unsigned int write_data){
mt9d111_i2c_axi_lites[66] = 0x100 | (device_addr & 0xfe); // Slave IIC Write Address, address is 0x108, i2c_tx_fifo
mt9d111_i2c_axi_lites[66] = write_addr;
mt9d111_i2c_axi_lites[66] = (write_data >> 8)|0xff; // first data
mt9d111_i2c_axi_lites[66] = 0x200 | (write_data & 0xff); // second data
cam_i2x_write_sync();
}
int main(){
XDmaw4gabor xdma4g;
// axis_switch_1, 1to2 ,Select M00_AXIS
// Refer to http://marsee101.blog19.fc2.com/blog-entry-3177.html
Xil_Out32((XPAR_CAMERA_INTERFACE_AXIS_SWITCH_1_BASEADDR+0x40), 0x0);
Xil_Out32((XPAR_CAMERA_INTERFACE_AXIS_SWITCH_1_BASEADDR+0x44), 0x80000000); // disable
Xil_Out32((XPAR_CAMERA_INTERFACE_AXIS_SWITCH_1_BASEADDR+0x48), 0x80000000); // disable
Xil_Out32((XPAR_CAMERA_INTERFACE_AXIS_SWITCH_1_BASEADDR+0x4C), 0x80000000); // disable
Xil_Out32((XPAR_CAMERA_INTERFACE_AXIS_SWITCH_1_BASEADDR), 0x2); // Commit registers
// axis_switch_0, 2to1, Select S00_AXIS
// Refer to http://marsee101.blog19.fc2.com/blog-entry-3177.html
Xil_Out32((XPAR_CAMERA_INTERFACE_AXIS_SWITCH_0_BASEADDR+0x40), 0x0);
Xil_Out32((XPAR_CAMERA_INTERFACE_AXIS_SWITCH_0_BASEADDR), 0x2); // Commit registers
XDmaw4gabor_Initialize(&xdma4g, 0);
XDmaw4gabor_Set_frame_buffer0(&xdma4g, FRAME_BUFFER_ADDRESS);
XDmaw4gabor_Set_frame_buffer1(&xdma4g, FRAME_BUFFER_ADDRESS);
XDmaw4gabor_Start(&xdma4g);
XDmaw4gabor_EnableAutoRestart(&xdma4g);
// mt9d111_inf_axis_0, axi_iic_0, bitmap_disp_cntrler_axi_master_0
volatile unsigned int *bmdc0_axi_lites;
volatile unsigned int *bmdc1_axi_lites;
volatile unsigned int *mt9d111_axi_lites;
volatile unsigned int *mt9d111_i2c_axi_lites;
bmdc0_axi_lites = (volatile unsigned *)XPAR_BITMAP_DISP_CNTRLER_AXI_MASTER_0_BASEADDR;
bmdc1_axi_lites = (volatile unsigned *)XPAR_BITMAP_DISP_CNTRLER_AXI_MASTER_1_BASEADDR;
mt9d111_axi_lites = (volatile unsigned *)XPAR_CAMERA_INTERFACE_MT9D111_INF_AXIS_0_BASEADDR;
mt9d111_i2c_axi_lites = (volatile unsigned *)XPAR_CAMERA_INTERFACE_AXI_IIC_0_BASEADDR;
bmdc0_axi_lites[0] = (volatile unsigned int)FRAME_BUFFER_ADDRESS; // Bitmap Display Controller 0 start
bmdc1_axi_lites[0] = (volatile unsigned int)FRAME_BUFFER_ADDRESS; // Bitmap Display Controller 1 start
mt9d111_axi_lites[0] = (volatile unsigned int)FRAME_BUFFER_ADDRESS; // Camera Interface start (Address is dummy)
// CMOS Camera initialize, MT9D111
cam_i2c_init(mt9d111_i2c_axi_lites);
cam_i2c_write(mt9d111_i2c_axi_lites, 0xba, 0xf0, 0x1); // Changed regster map to IFP page 1
cam_i2c_write(mt9d111_i2c_axi_lites, 0xba, 0x97, 0x20); // RGB Mode, RGB565
mt9d111_axi_lites[1] = 0; // One_shot_mode is disabled
return(0);
}
の指示子を追加した)#pragma HLS INTERFACE s_axilite port=return
// rgb2hsv.h
// 2016/10/06 by marsee
//
#ifndef __RGB2HSV_H__
#define __RGB2HSV_H__
//#define HORIZONTAL_PIXEL_WIDTH 800
//#define VERTICAL_PIXEL_WIDTH 600
#define HORIZONTAL_PIXEL_WIDTH 640
#define VERTICAL_PIXEL_WIDTH 480
//#define HORIZONTAL_PIXEL_WIDTH 64
//#define VERTICAL_PIXEL_WIDTH 48
#define ALL_PIXEL_VALUE (HORIZONTAL_PIXEL_WIDTH*VERTICAL_PIXEL_WIDTH)
#endif
// rgb2hsv.cpp
// 2016/10/06 by marsee
//
#include <ap_int.h>
#include <hls_stream.h>
#include <ap_axi_sdata.h>
#include "rgb2hsv.h"
#define MAG 8 // 小数点以下のビット幅
int rgb2hsv(hls::stream<ap_axis<32,1,1,1> >& ins, hls::stream<ap_axis<32,1,1,1> >& outs){
#pragma HLS INTERFACE axis port=outs
#pragma HLS INTERFACE axis port=ins
ap_axis<32,1,1,1> pix;
int r, g, b;
int h, s, v;
int max, min;
int hsv;
do{
#pragma HLS LOOP_TRIPCOUNT min=1 max=1 avg=1
ins >> pix;
}while(pix.user == 0);
loop_y: for(int y=0; y<VERTICAL_PIXEL_WIDTH; y++){
loop_x: for(int x=0; x<HORIZONTAL_PIXEL_WIDTH; x++){
#pragma HLS UNROLL factor=2
#pragma HLS PIPELINE II=1
if(!(x==0 && y==0)) // 最初の入力はすでに入力されている
ins >> pix; // AXI4-Stream からの入力
b = pix.data & 0xff;
g = (pix.data>>8) & 0xff;
r = (pix.data>>16) & 0xff;
// h と max, min を求める
if(r==g && g==b && r==b){
max = r; // 8倍
min = r;
}else if(r>=g && r>=b){ // r が最大
max = r;
if(g>=b)
min = b;
else
min = g;
}else if(g>=r && g>=b){ // g が最大
max = g;
if(r>=b)
min = b;
else
min = r;
}else{ // b が最大
max = b;
if(r>=g)
min = g;
else
min = r;
}
if(max-min == 0)
h = 0;
else if(max == r)
h = 60 * (((g-b)<<MAG)/(max-min)); // MAGビットシフトして精度を確保
else if(max == g)
h = 60 * (((b-r)<<MAG)/(max-min)) + (120<<MAG); // MAGビットシフトして精度を確保
else // if(max == b)
h = 60 * (((r-g)<<MAG)/(max-min)) + (240<<MAG); // MAGビットシフトして精度を確保
if(h < 0)
h += 360<<MAG;
h += 1<<(MAG-1); // +0.5、四捨五入
h >>= MAG; // 桁を戻す
if(max == 0)
s = 0;
else
s = (((max - min)<<MAG)/max) * 255; // MAGビットシフトして精度を確保
s += 1<<(MAG-1); // +0.5、四捨五入
s >>= MAG; // 桁を戻す
v = max;
hsv = (h&0x1ff)*65536 + (s&0xff)*256 + (v&0xff);
pix.data = hsv;
if (x==0 && y==0) // 最初のデータでは、TUSERをアサートする
pix.user = 1;
else
pix.user = 0;
if (x == (HORIZONTAL_PIXEL_WIDTH-1)) // 行の最後で TLAST をアサートする
pix.last = 1;
else
pix.last = 0;
outs << pix;
}
}
return(0);
}
// rgb2hsv_tb.cpp
// 2016/10/09
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ap_int.h>
#include <hls_stream.h>
#include <iostream>
#include <fstream>
#include <math.h>
#include <ap_axi_sdata.h>
#include <hls_video.h>
#include "rgb2hsv.h"
#include "bmp_header.h"
#define BMP_FILE_NAME "road_1.bmp"
#define SQUARE_ERROR_LIMIT 4 // 2乗誤差のエラー限界、この数以上はエラーとする
#define H 0
#define S 1
#define V 2
int rgb2hsv(hls::stream<ap_axis<32,1,1,1> >& ins, hls::stream<ap_axis<32,1,1,1> >& outs);
int rgb2hsv_soft(hls::stream<ap_axis<32,1,1,1> >& ins, hls::stream<ap_axis<32,1,1,1> >& outs);
void WriteBmpFile(FILE *fbmpw, BITMAPFILEHEADER &bmpfhr, BITMAPINFOHEADER &bmpihr, int *pixel_buf, int select_hsv);
int main(){
using namespace std;
hls::stream<ap_axis<32,1,1,1> > ins;
hls::stream<ap_axis<32,1,1,1> > ins_soft;
hls::stream<ap_axis<32,1,1,1> > outs;
hls::stream<ap_axis<32,1,1,1> > outs_soft;
ap_axis<32,1,1,1> pix;
ap_axis<32,1,1,1> vals;
ap_axis<32,1,1,1> vals_soft;
BITMAPFILEHEADER bmpfhr; // BMPファイルのファイルヘッダ(for Read)
BITMAPINFOHEADER bmpihr; // BMPファイルのINFOヘッダ(for Read)
FILE *fbmpr, *fbmpw, *fbmpwf;
int *rd_bmp, *hw_hsv, *sw_hsv;
int blue, green, red;
if ((fbmpr = fopen(BMP_FILE_NAME, "rb")) == NULL){ // BMP ファイル をオープン
fprintf(stderr, "Can't open test.bmp by binary read mode\n");
exit(1);
}
// bmpヘッダの読み出し
fread(&bmpfhr.bfType, sizeof(char), 2, fbmpr);
fread(&bmpfhr.bfSize, sizeof(long), 1, fbmpr);
fread(&bmpfhr.bfReserved1, sizeof(short), 1, fbmpr);
fread(&bmpfhr.bfReserved2, sizeof(short), 1, fbmpr);
fread(&bmpfhr.bfOffBits, sizeof(long), 1, fbmpr);
fread(&bmpihr, sizeof(BITMAPINFOHEADER), 1, fbmpr);
// ピクセルを入れるメモリをアロケートする
if ((rd_bmp =(int *)malloc(sizeof(int) * (bmpihr.biWidth * bmpihr.biHeight))) == NULL){
fprintf(stderr, "Can't allocate rd_bmp memory\n");
exit(1);
}
if ((hw_hsv =(int *)malloc(sizeof(int) * (bmpihr.biWidth * bmpihr.biHeight))) == NULL){
fprintf(stderr, "Can't allocate hw_hsv memory\n");
exit(1);
}
if ((sw_hsv =(int *)malloc(sizeof(int) * (bmpihr.biWidth * bmpihr.biHeight))) == NULL){
fprintf(stderr, "Can't allocate sw_hsv memory\n");
exit(1);
}
// rd_bmp にBMPのピクセルを代入。その際に、行を逆転する必要がある
for (int y=0; y<bmpihr.biHeight; y++){
for (int x=0; x<bmpihr.biWidth; x++){
blue = fgetc(fbmpr);
green = fgetc(fbmpr);
red = fgetc(fbmpr);
rd_bmp[((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x] = (blue & 0xff) | ((green & 0xff)<<8) | ((red & 0xff)<<16);
}
}
fclose(fbmpr);
// ins に入力データを用意する
for(int i=0; i<5; i++){ // dummy data
pix.user = 0;
pix.data = i;
ins << pix;
ins_soft << pix;
}
for(int j=0; j < bmpihr.biHeight; j++){
for(int i=0; i < bmpihr.biWidth; i++){
pix.data = (ap_int<32>)rd_bmp[(j*bmpihr.biWidth)+i];
if (j==0 && i==0) // 最初のデータの時に TUSER を 1 にする
pix.user = 1;
else
pix.user = 0;
if (i == bmpihr.biWidth-1) // 行の最後でTLASTをアサートする
pix.last = 1;
else
pix.last = 0;
ins << pix;
ins_soft << pix;
}
}
rgb2hsv(ins, outs);
rgb2hsv_soft(ins_soft, outs_soft);
// ハードウェアとソフトウェアのラプラシアン・フィルタの値のチェック
cout << endl;
cout << "outs" << endl;
for(int j=0; j < bmpihr.biHeight; j++){
for(int i=0; i < bmpihr.biWidth; i++){
outs >> vals;
outs_soft >> vals_soft;
ap_int<32> val = vals.data;
ap_int<32> val_soft = vals_soft.data;
hw_hsv[(j*bmpihr.biWidth)+i] = (int)val;
sw_hsv[(j*bmpihr.biWidth)+i] = (int)val_soft;
red = (rd_bmp[(j*bmpihr.biWidth)+i]>>16) & 0xff;
green = (rd_bmp[(j*bmpihr.biWidth)+i]>>8) & 0xff;
blue = rd_bmp[(j*bmpihr.biWidth)+i] & 0xff;
if ((double)pow((double)(val&0xff)-(val_soft&0xff),(double)2) > SQUARE_ERROR_LIMIT || // v の2乗誤差が4よりも大きい
(double)pow((double)((val>>8)&0xff)-((val_soft>>8)&0xff),(double)2) > SQUARE_ERROR_LIMIT || // s の2乗誤差が4よりも大きい
(double)pow((double)((val>>16)&0x1ff)-((val_soft>>16)&0x1ff),(double)2) > SQUARE_ERROR_LIMIT){ // h の2乗誤差が4よりも大きい
printf("ERROR HW and SW results mismatch i = %ld, j = %ld, Red = %d, Green = %d, Blue = %d, "
"HW_h = %d, HW_s = %d, HW_v = %d, SW_h = %d, SW_s = %d, SW_v = %d\n",
i, j, red, green, blue, (int)(val>>16)&0xff, (int)(val>>8)&0xff, (int)val&0xff,
(int)(val_soft>>16)&0xff, (int)(val_soft>>8)&0xff, (int)val_soft&0xff);
//return(1);
}
//if (vals.last)
//cout << "AXI-Stream is end" << endl;
}
}
cout << "Success HW and SW results match" << endl;
cout << endl;
if ((fbmpw=fopen("h_hw.bmp", "wb")) == NULL){
fprintf(stderr, "Can't open h_hw.bmp by binary write mode\n");
exit(1);
}
WriteBmpFile(fbmpw, bmpfhr, bmpihr, hw_hsv, H);
if ((fbmpw=fopen("s_hw.bmp", "wb")) == NULL){
fprintf(stderr, "Can't open s_hw.bmp by binary write mode\n");
exit(1);
}
WriteBmpFile(fbmpw, bmpfhr, bmpihr, hw_hsv, S);
if ((fbmpw=fopen("v_hw.bmp", "wb")) == NULL){
fprintf(stderr, "Can't open v_hw.bmp by binary write mode\n");
exit(1);
}
WriteBmpFile(fbmpw, bmpfhr, bmpihr, hw_hsv, V);
if ((fbmpw=fopen("h_sw.bmp", "wb")) == NULL){
fprintf(stderr, "Can't open h_sw.bmp by binary write mode\n");
exit(1);
}
WriteBmpFile(fbmpw, bmpfhr, bmpihr, sw_hsv, H);
if ((fbmpw=fopen("s_sw.bmp", "wb")) == NULL){
fprintf(stderr, "Can't open s_sw.bmp by binary write mode\n");
exit(1);
}
WriteBmpFile(fbmpw, bmpfhr, bmpihr, sw_hsv, S);
if ((fbmpw=fopen("v_sw.bmp", "wb")) == NULL){
fprintf(stderr, "Can't open v_sw.bmp by binary write mode\n");
exit(1);
}
WriteBmpFile(fbmpw, bmpfhr, bmpihr, sw_hsv, V);
free(rd_bmp);
free(hw_hsv);
free(sw_hsv);
}
int rgb2hsv_soft(hls::stream<ap_axis<32,1,1,1> >& ins, hls::stream<ap_axis<32,1,1,1> >& outs){
ap_axis<32,1,1,1> pix;
int r, g, b;
float h, s;
int v;
int max, min;
int hsv;
do{
ins >> pix;
}while(pix.user == 0);
loop_y: for(int y=0; y<VERTICAL_PIXEL_WIDTH; y++){
loop_x: for(int x=0; x<HORIZONTAL_PIXEL_WIDTH; x++){
if(!(x==0 && y==0)) // 最初の入力はすでに入力されている
ins >> pix; // AXI4-Stream からの入力
b = pix.data & 0xff;
g = (pix.data>>8) & 0xff;
r = (pix.data>>16) & 0xff;
// h と max, min を求める
if(r==g && g==b && r==b){
max = r;
min = r;
}else if(r>=g && r>=b){
max = r;
if(g>=b)
min = b;
else
min = g;
}else if(g>=r && g>=b){
max = g;
if(r>=b)
min = b;
else
min = r;
}else{ // b が最大
max = b;
if(r>=g)
min = g;
else
min = r;
}
if(max-min == 0)
h = 0.0;
else if(max == r)
h = 60.0 * ((float)(g-b)/(float)(max-min));
else if(max == g)
h = 60.0 * ((float)(b-r)/(float)(max-min)) + 120.0;
else // if(max == b)
h = 60.0 * ((float)(r-g)/(float)(max-min)) + 240.0;
if(h < 0)
h += 360.0;
if(max == 0)
s = 0.0;
else
s = (float)(max - min)/(float)max * 255.0;
v = max;
hsv = (((int)(h+0.5))&0x1ff)*65536 + (((int)(s+0.5))&0xff)*256 + (v&0xff); // h と s は四捨五入
pix.data = hsv;
if (x==0 && y==0) // 最初のデータでは、TUSERをアサートする
pix.user = 1;
else
pix.user = 0;
if (x == (HORIZONTAL_PIXEL_WIDTH-1)) // 行の最後で TLAST をアサートする
pix.last = 1;
else
pix.last = 0;
outs << pix;
}
}
return(0);
}
// SV のうちの1つをblue, green, redの値として同じ値をBMPファイルに書く
// H は S,V の値を255とした時の H の値に対する RGB の値を計算する
void WriteBmpFile(FILE *fbmpw, BITMAPFILEHEADER &bmpfhr, BITMAPINFOHEADER &bmpihr, int *pixel_buf, int select_hsv){
int h;
int sv;
int r, g, b;
// BMPファイルヘッダの書き込み
fwrite(&bmpfhr.bfType, sizeof(char), 2, fbmpw);
fwrite(&bmpfhr.bfSize, sizeof(long), 1, fbmpw);
fwrite(&bmpfhr.bfReserved1, sizeof(short), 1, fbmpw);
fwrite(&bmpfhr.bfReserved2, sizeof(short), 1, fbmpw);
fwrite(&bmpfhr.bfOffBits, sizeof(long), 1, fbmpw);
fwrite(&bmpihr, sizeof(BITMAPINFOHEADER), 1, fbmpw);
// RGB データの書き込み、逆順にする
for (int y=0; y<bmpihr.biHeight; y++){
for (int x=0; x<bmpihr.biWidth; x++){
switch(select_hsv){
case H:
h = (pixel_buf[((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x]>>16) & 0x1ff;
if(h>=0 && h<60){
r = 255;
g = (int)(((float)h/60.0)*255.0+0.5);
b = 0;
}else if(h>=60 && h<120){
r = (int)(((120.0-(float)h)/60.0)*255+0.5);
g = 255;
b = 0;
}else if(h>=120 && h<180){
r = 0;
g = 255;
b = (int)((((float)h-120.0)/60.0)*255+0.5);
}else if(h>=180 && h<240){
r = 0;
g = (int)(((240.0-(float)h)/60.0)*255+0.5);
b = 255;
}else if(h>=240 && h<300){
r = (int)((((float)h-240.0)/60.0)*255+0.5);
g = 0;
b = 255;
}else{ // h>=300 && h<=360
r = 255;
g = 0;
b = (int)(((360.0-(float)h)/60.0)*255+0.5);
}
break;
case S:
sv = (pixel_buf[((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x] >> 8) & 0xff;
break;
default: // case V:
sv = pixel_buf[((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x] & 0xff;
break;
}
if(select_hsv==S || select_hsv==V){
fputc(sv, fbmpw);
fputc(sv, fbmpw);
fputc(sv, fbmpw);
}else{
fputc(b, fbmpw);
fputc(g, fbmpw);
fputc(r, fbmpw);
}
}
}
fclose(fbmpw);
}
for (int y=0; y<bmpihr.biHeight; y++){
for (int x=0; x<bmpihr.biWidth; x++){
switch(select_hsv){
case H:
h = (pixel_buf[((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x]>>16) & 0x1ff;
if(h>=0 && h<60){
r = 255;
g = (int)(((float)h/60.0)*255.0+0.5);
b = 0;
}else if(h>=60 && h<120){
r = (int)(((120.0-(float)h)/60.0)*255+0.5);
g = 255;
b = 0;
}else if(h>=120 && h<180){
r = 0;
g = 255;
b = (int)((((float)h-120.0)/60.0)*255+0.5);
}else if(h>=180 && h<240){
r = 0;
g = (int)(((240.0-(float)h)/60.0)*255+0.5);
b = 255;
}else if(h>=240 && h<300){
r = (int)((((float)h-240.0)/60.0)*255+0.5);
g = 0;
b = 255;
}else{ // h>=300 && h<=360
r = 255;
g = 0;
b = (int)(((360.0-(float)h)/60.0)*255+0.5);
}
break;
case S:
sv = (pixel_buf[((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x] >> 8) & 0xff;
break;
default: // case V:
sv = pixel_buf[((bmpihr.biHeight-1)-y)*bmpihr.biWidth+x] & 0xff;
break;
}
だそうだ。つまり、記録しながら実行もできるよというツールなんだろう?Jupyter Notebook (読み方は「ジュパイター・ノートブック」または「ジュピター・ノートブック」) とは、ノートブックと呼ばれる形式で作成したプログラムを実行し、実行結果を記録しながら、データの分析作業を進めるためのツールです。
と表示され、XGA 画像だと認識できている。HDMI is capturing a video source of resolution 1024x768
だそうだ。つまり、XGA解像度が無かった。。。Valid resolutions are:
0 : 640x480, 60Hz
1 : 800x600, 60Hz
2 : 1280x720, 60Hz
3 : 1280x1024, 60Hz
4 : 1920x1080, 60Hz
In: serial@e0000000
Out: serial@e0000000
Err: serial@e0000000
Model: Zynq ARTY-Z Development Board
Board: Xilinx Zynq
Net: ZYNQ GEM: e000b000, phyaddr 1, interface rgmii-id
SF: Detected S25FL128S_64K with page size 256 Bytes, erase size 64 KiB, total 16 MiB
Warning: ethernet@e000b000 using MAC address from ROM
eth0: ethernet@e000b000
Hit any key to stop autoboot: 0
Device: sdhci@e0100000
Manufacturer ID: 74
OEM: 4a60
Name: USD
Tran Speed: 50000000
Rd Block Len: 512
SD version 3.0
High Capacity: Yes
Capacity: 7.5 GiB
Bus Width: 4-bit
Erase Group Size: 512 Bytes
reading uEnv.txt
** Unable to read file uEnv.txt **
Copying Linux from SD to RAM...
reading uImage
4506400 bytes read in 415 ms (10.4 MiB/s)
reading devicetree.dtb
8936 bytes read in 20 ms (435.5 KiB/s)
## Booting kernel from Legacy Image at 03000000 ...
Image Name: Linux-3.17.0-xilinx
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 4506336 Bytes = 4.3 MiB
Load Address: 00008000
Entry Point: 00008000
Verifying Checksum ... OK
## Flattened Device Tree blob at 02a00000
Booting using the fdt blob at 0x2a00000
Loading Kernel Image ... OK
Loading Device Tree to 1eb18000, end 1eb1d2e7 ... OK
Starting kernel ...
Booting Linux on physical CPU 0x0
Linux version 3.17.0-xilinx (hackwad@xcordevl1) (gcc version 4.9.2 (Sourcery CodeBench Lite 2015.05-17) ) #23 SMP PREEMPT Tue Aug 16 10:40:10 MDT 2016
CPU: ARMv7 Processor [413fc090] revision 0 (ARMv7), cr=18c5387d
CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
Machine model: xlnx,zynq-7000
cma: Reserved 128 MiB at 16800000
Memory policy: Data cache writealloc
PERCPU: Embedded 8 pages/cpu @5fb9e000 s8768 r8192 d15808 u32768
Built 1 zonelists in Zone order, mobility grouping on. Total pages: 130048
Kernel command line: console=ttyPS0,115200 root=/dev/mmcblk0p2 rw earlyprintk rootfstype=ext4 rootwait devtmpfs.mount=1
PID hash table entries: 2048 (order: 1, 8192 bytes)
Dentry cache hash table entries: 65536 (order: 6, 262144 bytes)
Inode-cache hash table entries: 32768 (order: 5, 131072 bytes)
Memory: 379048K/524288K available (6184K kernel code, 363K rwdata, 2228K rodata, 208K init, 255K bss, 145240K reserved, 0K highmem)
Virtual kernel memory layout:
vector : 0xffff0000 - 0xffff1000 ( 4 kB)
fixmap : 0xffc00000 - 0xffe00000 (2048 kB)
vmalloc : 0x60800000 - 0xff000000 (2536 MB)
lowmem : 0x40000000 - 0x60000000 ( 512 MB)
pkmap : 0x3fe00000 - 0x40000000 ( 2 MB)
modules : 0x3f000000 - 0x3fe00000 ( 14 MB)
.text : 0x40008000 - 0x4083f31c (8413 kB)
.init : 0x40840000 - 0x40874240 ( 209 kB)
.data : 0x40876000 - 0x408d0ea0 ( 364 kB)
.bss : 0x408d0ea0 - 0x40910c78 ( 256 kB)
Preemptible hierarchical RCU implementation.
Dump stacks of tasks blocking RCU-preempt GP.
RCU restricting CPUs from NR_CPUS=4 to nr_cpu_ids=2.
RCU: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=2
NR_IRQS:16 nr_irqs:16 16
L2C: platform provided aux values match the hardware, so have no effect. Please remove them.
L2C-310 erratum 769419 enabled
L2C-310 enabling early BRESP for Cortex-A9
L2C-310 full line of zeros enabled for Cortex-A9
L2C-310 ID prefetch enabled, offset 1 lines
L2C-310 dynamic clock gating enabled, standby mode enabled
L2C-310 cache controller enabled, 8 ways, 512 kB
L2C-310: CACHE_ID 0x410000c8, AUX_CTRL 0x76360001
slcr mapped to 60804000
zynq_clock_init: clkc starts at 60804100
Zynq clock init
sched_clock: 64 bits at 325MHz, resolution 3ns, wraps every 3383112499200ns
timer #0 at 60806000, irq=43
Console: colour dummy device 80x30
Calibrating delay loop... 1292.69 BogoMIPS (lpj=6463488)
pid_max: default: 32768 minimum: 301
Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
CPU: Testing write buffer coherency: ok
CPU0: thread -1, cpu 0, socket 0, mpidr 80000000
Setting up static identity map for 0x5de6d8 - 0x5de730
CPU1: Booted secondary processor
CPU1: thread -1, cpu 1, socket 0, mpidr 80000001
Brought up 2 CPUs
SMP: Total of 2 processors activated.
CPU: All CPU(s) started in SVC mode.
devtmpfs: initialized
VFP support v0.3: implementor 41 architecture 3 part 30 variant 9 rev 4
regulator-dummy: no parameters
NET: Registered protocol family 16
DMA: preallocated 256 KiB pool for atomic coherent allocations
cpuidle: using governor ladder
cpuidle: using governor menu
hw-breakpoint: found 5 (+1 reserved) breakpoint and 1 watchpoint registers.
hw-breakpoint: maximum watchpoint size is 4 bytes.
zynq-ocm f800c000.ocmc: ZYNQ OCM pool: 256 KiB @ 0x60880000
VCCPINT: 1000 mV
vgaarb: loaded
SCSI subsystem initialized
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
media: Linux media interface: v0.10
Linux video capture interface: v2.00
pps_core: LinuxPPS API ver. 1 registered
pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
PTP clock support registered
EDAC MC: Ver: 3.0.0
Advanced Linux Sound Architecture Driver Initialized.
cfg80211: Calling CRDA to update world regulatory domain
Switched to clocksource arm_global_timer
NET: Registered protocol family 2
TCP established hash table entries: 4096 (order: 2, 16384 bytes)
TCP bind hash table entries: 4096 (order: 3, 32768 bytes)
TCP: Hash tables configured (established 4096 bind 4096)
TCP: reno registered
UDP hash table entries: 256 (order: 1, 8192 bytes)
UDP-Lite hash table entries: 256 (order: 1, 8192 bytes)
NET: Registered protocol family 1
RPC: Registered named UNIX socket transport module.
RPC: Registered udp transport module.
RPC: Registered tcp transport module.
RPC: Registered tcp NFSv4.1 backchannel transport module.
hw perfevents: enabled with armv7_cortex_a9 PMU driver, 7 counters available
futex hash table entries: 512 (order: 3, 32768 bytes)
jffs2: version 2.2. (NAND) (SUMMARY) c 2001-2006 Red Hat, Inc.
msgmni has been set to 996
io scheduler noop registered
io scheduler deadline registered
io scheduler cfq registered (default)
dma-pl330 f8003000.dmac: Loaded driver for PL330 DMAC-2364208
dma-pl330 f8003000.dmac: DBUFF-128x8bytes Num_Chans-8 Num_Peri-4 Num_Events-16
e0000000.serial: ttyPS0 at MMIO 0xe0000000 (irq = 59, base_baud = 6250000) is a xuartps
console [ttyPS0] enabled
xdevcfg f8007000.devcfg: ioremap 0xf8007000 to 6086a000
[drm] Initialized drm 1.1.0 20060810
brd: module loaded
loop: module loaded
CAN device driver interface
libphy: MACB_mii_bus: probed
macb e000b000.ethernet eth0: Cadence GEM at 0xe000b000 irq 54 (00:18:3e:02:48:48)
macb e000b000.ethernet eth0: attached PHY driver [Generic PHY] (mii_bus:phy_addr=e000b000.etherne:00, irq=-1)
e1000e: Intel(R) PRO/1000 Network Driver - 2.3.2-k
e1000e: Copyright(c) 1999 - 2014 Intel Corporation.
ipw2100: Intel(R) PRO/Wireless 2100 Network Driver, git-1.2.2
ipw2100: Copyright(c) 2003-2006 Intel Corporation
libipw: 802.11 data/management/control stack, git-1.1.13
libipw: Copyright (C) 2004-2005 Intel Corporation <jketreno@linux.intel.com>
Atmel at76x USB Wireless LAN Driver 0.17 loading
usbcore: registered new interface driver at76c50x-usb
Broadcom 43xx driver loaded [ Features: PNLS ]
Broadcom 43xx-legacy driver loaded [ Features: PLID ]
usbcore: registered new interface driver rtl8187
usbcore: registered new interface driver rtl8192cu
usbcore: registered new interface driver rndis_wlan
usbcore: registered new interface driver lbtf_usb
Intel(R) Wireless WiFi driver for Linux, in-tree:
Copyright(c) 2003- 2014 Intel Corporation
iwl4965: Intel(R) Wireless WiFi 4965 driver for Linux, in-tree:
iwl4965: Copyright(c) 2003-2011 Intel Corporation
iwl3945: Intel(R) PRO/Wireless 3945ABG/BG Network Connection driver for Linux, in-tree:s
iwl3945: Copyright(c) 2003-2011 Intel Corporation
usbcore: registered new interface driver brcmfmac
usbcore: registered new interface driver asix
usbcore: registered new interface driver ax88179_178a
usbcore: registered new interface driver cdc_ether
usbcore: registered new interface driver net1080
usbcore: registered new interface driver rndis_host
usbcore: registered new interface driver cdc_subset
usbcore: registered new interface driver zaurus
usbcore: registered new interface driver cdc_ncm
ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
ehci-pci: EHCI PCI platform driver
ULPI transceiver vendor/product ID 0x0451/0x1507
Found TI TUSB1210 ULPI transceiver.
ULPI integrity check: passed.
zynq-ehci zynq-ehci.0: Xilinx Zynq USB EHCI Host Controller
zynq-ehci zynq-ehci.0: new USB bus registered, assigned bus number 1
zynq-ehci zynq-ehci.0: irq 53, io mem 0x00000000
zynq-ehci zynq-ehci.0: USB 2.0 started, EHCI 1.00
usb usb1: New USB device found, idVendor=1d6b, idProduct=0002
usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb1: Product: Xilinx Zynq USB EHCI Host Controller
usb usb1: Manufacturer: Linux 3.17.0-xilinx ehci_hcd
usb usb1: SerialNumber: zynq-ehci.0
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 1 port detected
usbcore: registered new interface driver usb-storage
mousedev: PS/2 mouse device common for all mice
i2c /dev entries driver
cdns-i2c e0004000.i2c: 400 kHz mmio e0004000 irq 57
cdns-wdt f8005000.watchdog: Xilinx Watchdog Timer at 60874000 with timeout 10s
Xilinx Zynq CpuIdle Driver started
sdhci: Secure Digital Host Controller Interface driver
sdhci: Copyright(c) Pierre Ossman
sdhci-pltfm: SDHCI platform and OF driver helper
sdhci-arasan e0100000.sdhci: No vmmc regulator found
sdhci-arasan e0100000.sdhci: No vqmmc regulator found
mmc0: SDHCI controller on e0100000.sdhci [e0100000.sdhci] using ADMA
ledtrig-cpu: registered to indicate activity on CPUs
usbcore: registered new interface driver usbhid
usbhid: USB HID core driver
xlnk driver initializing
xlnk major 245
xlnk driver loaded
xlnk_pdev is not null
TCP: cubic registered
NET: Registered protocol family 17
can: controller area network core (rev 20120528 abi 9)
NET: Registered protocol family 29
can: raw protocol (rev 20120528)
can: broadcast manager protocol (rev 20120528 t)
can: netlink gateway (rev 20130117) max_hops=1
lib80211: common routines for IEEE802.11 drivers
zynq_pm_ioremap: no compatible node found for 'xlnx,zynq-ddrc-1.0'
zynq_pm_late_init: Unable to map DDRC IO memory.
Registering SWP/SWPB emulation handler
drivers/rtc/hctosys.c: unable to open rtc device (rtc0)
ALSA device list:
mmc0: new high speed SDHC card at address 59b4
mmcblk0: mmc0:59b4 USD 7.51 GiB
mmcblk0: p1 p2
No soundcards found.
EXT4-fs (mmcblk0p2): mounted filesystem with ordered data mode. Opts: (null)
VFS: Mounted root (ext4 filesystem) on device 179:2.
devtmpfs: mounted
Freeing unused kernel memory: 208K (40840000 - 40874000)
!ョX.]Y[イォLWFailed to insert module 'kdbus': Function not implementedted
?K袁ムオェノケスオコ・ム。・ムヘz*ケムノスチ・
?・ア ア5systemd[1]: systemd 225 running in system mode. (+PAM +AUDIT +SELINUX +IMA +APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTS。ョ^.]Y[イォLWDetected architecture arm.ECCOMP +BLKID -ELFUTILS +KMOD -IDN)
Welcome to Ubuntu 15.10!
systemd-sysv-generator[733]: Overwriting existing symlink /run/systemd/generator。ョ^.]Y[イォLWdisplay-manager.service: Cannot add dependency job, ignoring: Unit di[ OK ] Started Dispatch Password Requests to Console Directory Watch.h.
[ OK ] Reached target Encrypted Volumes.es.
[ OK ] Reached target Remote File Systems (Pre).e).
[ OK ] Created slice Root Slice.e.
[ OK ] Listening on Journal Socket.et.
[ OK ] Created slice User and Session Slice.ce.
[ OK ] Listening on /dev/initctl Compatibility Named Pipe.pe.
[ OK ] Created slice System Slice.ce.
[ OK ] Created slice system-getty.slice.ce.
Starting Remount Root and Kernel File Systems......
Starting Nameserver information manager......
[ OK ] Created slice system-serial\x2dgetty.slice.ce.
[ OK ] Reached target Slices.es.
Starting Increase datagram queue length......
[ OK ] Listening on udev Control Socket.et.
[ OK ] Listening on udev Kernel Socket.et.
systemd[1]: Starting Create list of required static device nodes for the current Starting Create list of required st... nodes for the current kernel...
[ OK ] Listening on Journal Socket (/dev/log).g).
Starting Load Kernel Modules......
[ OK ] Started Forward Password Requests to Wall Directory Watch.ch.
Starting udev Coldplug all Devices......
[ OK ] Started Remount Root and Kernel File Systems.ms.
[ OK ] Started Increase datagram queue length.th.
systemd[1]: Started Create list of required static device nodes for the current [ OK ] Started Create list of required sta...ce nodes for the current kernel.
[ OK ] Started Load Kernel Modules.es.
[ OK ] Started Nameserver information manager.er.
[ OK ] Started udev Coldplug all Devices.es.
Starting Apply Kernel Variables......
Starting Create Static Device Nodes in /dev......
[ OK ] Listening on Syslog Socket.
Starting Journal Service...
Starting Load/Save Random Seed...
Activating swap /var/swap...
[ OK ] Started Apply Kernel Variables.
[ OK ] Started Create Static Device Nodes in /dev.
[ OK ] Started Load/Save Random Seed.
[ OK ] Started Journal Service.
Starting Flush Journal to Persistent Storage...
Starting udev Kernel Device Manager...
[ OK ] Reached target Local File Systems (Pre).
[ OK ] Reached target Local File Systems.
[ OK ] Reached target Remote File Systems.
Starting Wait for all "auto" /etc/n... up for network-online.target...
Starting LSB: Raise network interfaces....
[ OK ] Activated swap /var/swap.
[ OK ] Started udev Kernel Device Manager.
[ OK ] Started Flush Journal to Persistent Storage.
Starting Create Volatile Files and Directories...
[ OK ] Reached target Swap.
[ OK ] Started Create Volatile Files and Directories.
Starting Update UTMP about System Boot/Shutdown...
[ OK ] Reached target System Time Synchronized.
[ OK ] Started Update UTMP about System Boot/Shutdown.
[ OK ] Found device /dev/ttyPS0.
[ OK ] Started Wait for all "auto" /etc/ne...be up for network-online.target.
[ OK ] Stopped LSB: Start NTP daemon.
[ OK ] Started LSB: Raise network interfaces..
[ OK ] Reached target Network.
[ OK ] Reached target Network is Online.
[ OK ] Reached target System Initialization.
[ OK ] Listening on D-Bus System Message Bus Socket.
[ OK ] Reached target Sockets.
[ OK ] Started Trigger resolvconf update for networkd DNS.
[ OK ] Reached target Paths.
[ OK ] Reached target Basic System.
Starting Login Service...
Starting LSB: start Samba NetBIOS nameserver (nmbd)...
Starting Permit User Sessions...
Starting LSB: start Samba daemons for the AD DC...
Starting LSB: Load kernel modules needed to enable cpufreq scaling...
Starting LSB: starts/stops the 2ping listener...
[ OK ] Started Regular background program processing daemon.
Starting /etc/rc.local Compatibility...
[ OK ] Started OpenBSD Secure Shell server.
Starting Enable support for additional executable binary formats...
[ OK ] Started D-Bus System Message Bus.
Starting System Logging Service...
[ OK ] Started Daily Cleanup of Temporary Directories.
[ OK ] Reached target Timers.
[ OK ] Started Permit User Sessions.
[ OK ] Started LSB: starts/stops the 2ping listener.
[ OK ] Started Enable support for additional executable binary formats.
[ OK ] Started System Logging Service.
[ OK ] Started Login Service.
[ OK ] Started LSB: Load kernel modules needed to enable cpufreq scaling.
[ OK ] Created slice user-0.slice.
[ OK ] Started Session c1 of user root.
Starting User Manager for UID 0...
Starting LSB: set CPUFreq kernel parameters...
Starting LSB: Start NTP daemon...
[ OK ] Started LSB: set CPUFreq kernel parameters.
[ OK ] Started User Manager for UID 0.
[ OK ] Started LSB: Start NTP daemon.
rc.local[1503]: /root/2_jupyter_server.sh: Jupyter server started
rc.local[1503]: /root/3_pl_server.sh: Programmable Logic server started
[ OK ] Started /etc/rc.local Compatibility.
[ OK ] Started Getty on tty1.
[ OK ] Started Serial Getty on ttyPS0.
[ OK ] Reached target Login Prompts.
Stopping LSB: Start NTP daemon...
[ OK ] Stopped LSB: Start NTP daemon.
Starting LSB: Start NTP daemon...
[ OK ] Started LSB: Start NTP daemon.
Starting LSB: start Samba SMB/CIFS daemon (smbd)...
Stopping LSB: Start NTP daemon...
[ OK ] Stopped LSB: Start NTP daemon.
Starting LSB: Start NTP daemon...
[ OK ] Started LSB: Start NTP daemon.
[ OK ] Started LSB: start Samba daemons for the AD DC.
Ubuntu 15.10 pynq ttyPS0
pynq login: xilinx (automatic login)
Last login: Thu Jan 1 00:00:13 UTC 1970 on ttyPS0
xilinx@pynq:~$
WARNING: [SCHED 204-21] Estimated clock period (15.5ns) exceeds the target (target clock period: 10ns, clock uncertainty: 1.25ns, effective delay budget: 8.75ns).
WARNING: [SCHED 204-21] The critical path consists of the following:
multiplexor before 'phi' operation ('pix.data.V') with incoming values : ('tmp.data.V', rgb2hsv/rgb2hsv.cpp:23) ('tmp.data.V', rgb2hsv/rgb2hsv.cpp:30) ('hsv', rgb2hsv/rgb2hsv.cpp:79) (1.57 ns)
'phi' operation ('pix.data.V') with incoming values : ('tmp.data.V', rgb2hsv/rgb2hsv.cpp:23) ('tmp.data.V', rgb2hsv/rgb2hsv.cpp:30) ('hsv', rgb2hsv/rgb2hsv.cpp:79) (0 ns)
'partselect' operation ('min', rgb2hsv/rgb2hsv.cpp:34) (0 ns)
'icmp' operation ('tmp_8', rgb2hsv/rgb2hsv.cpp:40) (2 ns)
'or' operation ('or_cond2', rgb2hsv/rgb2hsv.cpp:40) (1.37 ns)
'or' operation ('sel_tmp2_demorgan', rgb2hsv/rgb2hsv.cpp:37) (1.37 ns)
'select' operation ('sel_tmp', rgb2hsv/rgb2hsv.cpp:37) (1.37 ns)
'select' operation ('sel_tmp1', rgb2hsv/rgb2hsv.cpp:48) (1.37 ns)
'select' operation ('min_5', rgb2hsv/rgb2hsv.cpp:37) (1.37 ns)
'sub' operation ('tmp_10', rgb2hsv/rgb2hsv.cpp:68) (1.72 ns)
'sdiv' operation ('tmp_11', rgb2hsv/rgb2hsv.cpp:68) (3.38 ns)
// rgb2hsv.h
// 2016/10/06 by marsee
//
#ifndef __RGB2HSV_H__
#define __RGB2HSV_H__
#define HORIZONTAL_PIXEL_WIDTH 800
#define VERTICAL_PIXEL_WIDTH 600
//#define HORIZONTAL_PIXEL_WIDTH 64
//#define VERTICAL_PIXEL_WIDTH 48
#define ALL_PIXEL_VALUE (HORIZONTAL_PIXEL_WIDTH*VERTICAL_PIXEL_WIDTH)
#endif
// rgb2hsv.cpp
// 2016/10/06 by marsee
//
#include <ap_int.h>
#include <hls_stream.h>
#include <ap_axi_sdata.h>
#include "rgb2hsv.h"
int rgb2hsv(hls::stream<ap_axis<32,1,1,1> >& ins, hls::stream<ap_axis<32,1,1,1> >& outs){
#pragma HLS INTERFACE axis port=outs
#pragma HLS INTERFACE axis port=ins
ap_axis<32,1,1,1> pix;
int r, g, b;
int h, s, v;
int max, min;
int hsv;
int offset;
#pragma HLS LOOP_TRIPCOUNT min=1 max=1 avg=1
{
ins >> pix;
}while(pix.user == 0);
loop_y: for(int y=0; y<VERTICAL_PIXEL_WIDTH; y++){
loop_x: for(int x=0; x<HORIZONTAL_PIXEL_WIDTH; x++){
#pragma HLS UNROLL factor=2
#pragma HLS PIPELINE II=1
if(!(x==0 && y==0)) // 最初の入力はすでに入力されている
ins >> pix; // AXI4-Stream からの入力
b = pix.data & 0xff;
g = (pix.data>>8) & 0xff;
r = (pix.data>>16) & 0xff;
// h と max, min を求める
if(r==g && g==b && r==b){
max = r;
min = r;
}else if(r>=g && r>=b){
max = r;
if(g>=b)
min = b;
else
min = g;
offset = 0;
}else if(g>=r && g>=b){
max = g;
if(r>=b)
min = b;
else
min = r;
offset = 120;
}else{ // b が最大
max = b;
if(r>=g)
min = g;
else
min = b;
offset = 240;
}
if(max-min == 0)
h = 0;
else
h = 60 * ((g-b)/(max-min)) + offset;
if(h < 0)
h += 360;
if(max == 0)
s = 0;
else
s = (max - min)/max * 255;
v = max;
hsv = (h&0xff)<<16 + (s&0xff)<<8 + (v&0xff);
pix.data = hsv;
if (x==0 && y==0) // 最初のデータでは、TUSERをアサートする
pix.user = 1;
else
pix.user = 0;
if (x == (HORIZONTAL_PIXEL_WIDTH-1)) // 行の最後で TLAST をアサートする
pix.last = 1;
else
pix.last = 0;
outs << pix;
}
}
return(0);
}
// wl_tracking_dmaw.cpp
// 2016/09/28 by marsee
//
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <string.h>
#include "xpwm.h"
#include "xmotor_monitor.h"
#define DIR_LEFT_NORMAL 1
#define DIR_LEFT_REVERSE 0
#define DIR_RIGHT_NORMAL 0
#define DIR_RIGHT_REVERSE 1
#define PIXEL_NUM_OF_BYTES 4
#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 GABOR_DETECT_LINE 590
#define GABOR_DETECT_LINE_ADDR (SVGA_HORIZONTAL_PIXELS * GABOR_DETECT_LINE * PIXEL_NUM_OF_BYTES)
#define GABOR_THRESHOLD 5
#define DIST_THRESHOLD 30
#define LEFT_GABOR_EDGE_OVERFLOW 0
#define RIGHT_GABOR_EDGE_OVERFLOW (SVGA_HORIZONTAL_PIXELS/2)
#define DEBUG
//#define MOTOR_OFF
// Gobor filter
//
void gabor_fil_on(){
int fd2, fd3, fd4;
volatile unsigned *axis_switch_0, *axis_switch_1;
volatile unsigned *gabor_filter_lh_0;
int gabor_cntrl;
// 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);
}
// gabor_filter_lh_0 (UIo14)
fd4 = open("/dev/uio14", O_RDWR); // gabor_filter_lh_0 interface AXI4 Lite Slave
if (fd4 < 1){
fprintf(stderr, "/dev/uio14 (gabor_filter_lh_0) open error\n");
exit(-1);
}
gabor_filter_lh_0 = (volatile unsigned *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd4, 0);
if (!gabor_filter_lh_0){
fprintf(stderr, "lap_filter_axis_0 mmap error\n");
exit(-1);
}
// 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
axis_switch_1[17] = 0x80000000; // 0x44 = 0x80000000; disable
axis_switch_1[18] = 0; // 0x48 = 0;
axis_switch_1[0] = 0x2; // 0x0 = 2; Commit registers
// gabor filter AXIS Start
gabor_filter_lh_0[0] = 0x01; // Start bit set
gabor_filter_lh_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] = 0x2; // 0x40 = 0x2;
axis_switch_0[0] = 0x2; // 0x0 = 2; Commit registers
munmap((void *)axis_switch_0, 0x10000);
munmap((void *)axis_switch_1, 0x10000);
munmap((void *)gabor_filter_lh_0, 0x10000);
close(fd2);
close(fd3);
close(fd4);
}
int search_gabor_edge(unsigned int start_addr, unsigned int number, int threshold){
volatile int *imgaddr, *endaddr;
int i;
imgaddr = (volatile int *)start_addr;
for (i=0; i<number; i++){
int c=imgaddr[i] & 0xff;
//printf("%d\n",c);
if (c >= threshold){
break;
}
}
return(i);
}
// Motor
//
void motor_settings(XPwm *motorLp, XPwm *motorRp){
XPwm_DisableAutoRestart(motorLp);
while(!XPwm_IsIdle(motorLp)) ;
XPwm_Start(motorLp);
XPwm_EnableAutoRestart(motorLp);
XPwm_DisableAutoRestart(motorRp);
while(!XPwm_IsIdle(motorRp)) ;
XPwm_Start(motorRp);
XPwm_EnableAutoRestart(motorRp);
}
void Stopped_Zybot(XPwm *motorLp, XPwm *motorRp){
XPwm_Set_sw_late_V(motorLp, 0);
XPwm_Set_sw_late_V(motorRp, 0);
}
void motor_initialize(XPwm &motorL, XPwm &motorR, XMotor_monitor &mmL, XMotor_monitor &mmR){
XPwm *motorLp, *motorRp;
XMotor_monitor *mmLp, *mmRp;
motorLp = &motorL;
motorRp = &motorR;
mmLp = &mmL;
mmRp = &mmR;
// Initialization of motor
if (XPwm_Initialize(motorLp, "pwm_0") != XST_SUCCESS){
fprintf(stderr,"pwm_0 (Left) open error\n");
exit(-1);
}
if (XPwm_Initialize(motorRp, "pwm_1") != XST_SUCCESS){
fprintf(stderr,"pwm_1 (Right) open error\n");
exit(-1);
}
// Initialization of motor monitor
if (XMotor_monitor_Initialize(mmLp, "motor_monitor_0") != XST_SUCCESS){
fprintf(stderr,"motor_monitor_0 (Left) open error\n");
exit(-1);
}
if (XMotor_monitor_Initialize(mmRp, "motor_monitor_1") != XST_SUCCESS){
fprintf(stderr,"motor_monitor_1 (Right) open error\n");
exit(-1);
}
// The Motors is rotated in the forward direction.
XPwm_Set_sw_late_V(motorLp, 0);
XPwm_Set_dir_V(motorLp, 1);
XPwm_Set_sw_late_V(motorRp, 0);
XPwm_Set_dir_V(motorRp, 0);
motor_settings(motorLp, motorRp);
}
// DMAW4Gabor setting
volatile unsigned *dmaw4g_initialize(int &fd1){
volatile unsigned *dmaw4gabor_0;
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);
}
return(dmaw4gabor_0);
}
int main(){
int fd1;
volatile unsigned *dmaw4gabor_0;
XPwm motorL, motorR;
XMotor_monitor mmL, mmR;
unsigned char attr[1024];
unsigned long phys_addr;
int left_wl_edge, right_wl_edge;
// Gabor filter Initialize
gabor_fil_on();
// Motor Initialize
motor_initialize(motorL, motorR, mmL, mmR);
// DMAW4Gabor Initialize
dmaw4gabor_0 = dmaw4g_initialize(fd1);
// udmabuf0
int fdf = open("/dev/udmabuf0", O_RDWR | O_SYNC); // frame_buffer, The cache is disabled.
if (fdf == -1){
fprintf(stderr, "/dev/udmabuf0 open error\n");
exit(-1);
}
volatile unsigned *frame_buffer = (volatile unsigned *)mmap(NULL, 3*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);
// DMA4Gabor frame_buffer1 setting
dmaw4gabor_0[8] = (int)phys_addr + SVGA_ALL_DISP_ADDRESS; // Data signal of frame_buffer1
// main loop
printf("White line Tracking start. \n");
while(1){
// Gabor filter for left white line
left_wl_edge = SVGA_HORIZONTAL_PIXELS/2 - search_gabor_edge(
(unsigned int)frame_buffer+GABOR_DETECT_LINE_ADDR, SVGA_HORIZONTAL_PIXELS/2, GABOR_THRESHOLD);
// Gabor filter for right white line
right_wl_edge = search_gabor_edge(
(unsigned int)frame_buffer+SVGA_ALL_DISP_ADDRESS+GABOR_DETECT_LINE_ADDR+(SVGA_HORIZONTAL_PIXELS/2)*PIXEL_NUM_OF_BYTES,
SVGA_HORIZONTAL_PIXELS/2, GABOR_THRESHOLD);
#ifdef DEBUG
printf("left_wl_edge = %d, right_wl_edge = %d\n", left_wl_edge, right_wl_edge);
#endif
if (left_wl_edge == LEFT_GABOR_EDGE_OVERFLOW){
#ifndef MOTOR_OFF
XPwm_Set_sw_late_V(&motorL, 5);
XPwm_Set_sw_late_V(&motorR, 35);
#endif
#ifdef DEBUG
printf("Left gabor edge is overflow\n");
#endif
} else if (right_wl_edge == RIGHT_GABOR_EDGE_OVERFLOW){
#ifndef MOTOR_OFF
XPwm_Set_sw_late_V(&motorL, 35);
XPwm_Set_sw_late_V(&motorR, 5);
#endif
#ifdef DEBUG
printf("Right gabar edge is overflow\n");
#endif
} else if ((right_wl_edge - left_wl_edge) > DIST_THRESHOLD){
#ifndef MOTOR_OFF
XPwm_Set_sw_late_V(&motorL, 25);
XPwm_Set_sw_late_V(&motorR, 15);
#endif
#ifdef DEBUG
printf("Right turn\n");
#endif
} else if ((right_wl_edge - left_wl_edge) < -DIST_THRESHOLD){
#ifndef MOTOR_OFF
XPwm_Set_sw_late_V(&motorL, 15);
XPwm_Set_sw_late_V(&motorR, 25);
#endif
#ifdef DEBUG
printf("Left turn\n");
#endif
} else if (abs(right_wl_edge - left_wl_edge) <= DIST_THRESHOLD){
#ifndef MOTOR_OFF
XPwm_Set_sw_late_V(&motorL, 20);
XPwm_Set_sw_late_V(&motorR, 20);
#endif
#ifdef DEBUG
printf("Go straight\n");
#endif
}
}
}
日 | 月 | 火 | 水 | 木 | 金 | 土 |
---|---|---|---|---|---|---|
- | - | - | - | - | - | 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 |
30 | 31 | - | - | - | - | - |