/////////////////////////////////////// /// 640x480 version! /// This code will segfault the original /// DE1 computer /// compile with /// gcc media_brl4_7_video.c -o testV /////////////////////////////////////// #include #include #include #include #include #include #include #include #include "address_map_arm_brl4.h" /* function prototypes */ void VGA_text (int, int, char *); void VGA_box (int, int, int, int, short); void VGA_line(int, int, int, int, short) ; void VGA_disc (int, int, int, short); // virtual to real address pointers //volatile unsigned int * red_LED_ptr = NULL ; //volatile unsigned int * res_reg_ptr = NULL ; //volatile unsigned int * stat_reg_ptr = NULL ; // audio stuff //volatile unsigned int * audio_base_ptr = NULL ; //volatile unsigned int * audio_fifo_data_ptr = NULL ; //4bytes //volatile unsigned int * audio_left_data_ptr = NULL ; //8bytes //volatile unsigned int * audio_right_data_ptr = NULL ; //12bytes // phase accumulator //unsigned int phase_acc ; // the light weight buss base void *h2p_lw_virtual_base; // pixel buffer volatile unsigned int * vga_pixel_ptr = NULL ; void *vga_pixel_virtual_base; // character buffer volatile unsigned int * vga_char_ptr = NULL ; void *vga_char_virtual_base; // /dev/mem file id int fd; // shared memory key_t mem_key=0xf0; int shared_mem_id; int *shared_ptr; int shared_time; float shared_note; char shared_str[64]; int main(void) { int x1, y1, x2, y2; // Declare volatile pointers to I/O registers (volatile // means that IO load and store instructions will be used // to access these pointer locations, // instead of regular memory loads and stores) // === shared memory ======================= // with video process shared_mem_id = shmget(mem_key, 100, IPC_CREAT | 0666); //shared_mem_id = shmget(mem_key, 100, 0666); shared_ptr = shmat(shared_mem_id, NULL, 0); // === need to mmap: ======================= // FPGA_CHAR_BASE // FPGA_ONCHIP_BASE // HW_REGS_BASE // === get FPGA addresses ================== // Open /dev/mem if( ( fd = open( "/dev/mem", ( O_RDWR | O_SYNC ) ) ) == -1 ) { printf( "ERROR: could not open \"/dev/mem\"...\n" ); return( 1 ); } // get virtual addr that maps to physical h2p_lw_virtual_base = mmap( NULL, HW_REGS_SPAN, ( PROT_READ | PROT_WRITE ), MAP_SHARED, fd, HW_REGS_BASE ); if( h2p_lw_virtual_base == MAP_FAILED ) { printf( "ERROR: mmap1() failed...\n" ); close( fd ); return(1); } // Get the address that maps to the FPGA LED control //red_LED_ptr =(unsigned int *)(h2p_lw_virtual_base + LEDR_BASE); // address to resolution register //res_reg_ptr =(unsigned int *)(h2p_lw_virtual_base + // resOffset); //addr to vga status //stat_reg_ptr = (unsigned int *)(h2p_lw_virtual_base + // statusOffset); // audio addresses // base address is control register //audio_base_ptr = (unsigned int *)(h2p_lw_virtual_base + AUDIO_BASE); //audio_fifo_data_ptr = audio_base_ptr + 1 ; // word //audio_left_data_ptr = audio_base_ptr + 2 ; // words //audio_right_data_ptr = audio_base_ptr + 3 ; // words // === get VGA char addr ===================== // get virtual addr that maps to physical vga_char_virtual_base = mmap( NULL, FPGA_CHAR_SPAN, ( PROT_READ | PROT_WRITE ), MAP_SHARED, fd, FPGA_CHAR_BASE ); if( vga_char_virtual_base == MAP_FAILED ) { printf( "ERROR: mmap2() failed...\n" ); close( fd ); return(1); } // Get the address that maps to the FPGA LED control vga_char_ptr =(unsigned int *)(vga_char_virtual_base); // === get VGA pixel addr ==================== // get virtual addr that maps to physical vga_pixel_virtual_base = mmap( NULL, FPGA_ONCHIP_SPAN, ( PROT_READ | PROT_WRITE ), MAP_SHARED, fd, FPGA_ONCHIP_BASE); if( vga_pixel_virtual_base == MAP_FAILED ) { printf( "ERROR: mmap3() failed...\n" ); close( fd ); return(1); } // Get the address that maps to the FPGA pixel buffer vga_pixel_ptr =(unsigned int *)(vga_pixel_virtual_base); // =========================================== /* create a message to be displayed on the VGA and LCD displays */ char text_top_row[40] = "DE1-SoC ARM/FPGA\0"; char text_bottom_row[40] = "Cornell ece5760\0"; VGA_text (34, 1, text_top_row); VGA_text (34, 2, text_bottom_row); // clear the screen VGA_box (0, 0, 639, 479, 0); short color, toggle ; while(1) { // get shared data shared_time = *shared_ptr ; // time in seconds shared_note = *(shared_ptr+1) ; // audio frequency sprintf(shared_str, "t:%d f:%5.1f ", shared_time, shared_note); VGA_text (34, 3, shared_str); // draw some rectangles x1 = (int)((rand() & 0x3ff)); y1 = (int)((rand() & 0x1ff)); x2 = x1 + (int)((rand() & 0x1ff)); y2 = y1 + (int)((rand() & 0x1ff)); //VGA_box (x1,y1,x2,y2, rand() & 0xff); VGA_disc(x1,y1, rand() & 0x3f, rand() & 0xff); // text background VGA_box (240,0,420,48, 0x01 ); } // end while(1) } // end main /**************************************************************************************** * Subroutine to send a string of text to the VGA monitor ****************************************************************************************/ void VGA_text(int x, int y, char * text_ptr) { volatile char * character_buffer = (char *) vga_char_ptr ; // VGA character buffer int offset; /* assume that the text string fits on one line */ offset = (y << 7) + x; while ( *(text_ptr) ) { // write to the character buffer *(character_buffer + offset) = *(text_ptr); ++text_ptr; ++offset; } } /**************************************************************************************** * Draw a filled rectangle on the VGA monitor ****************************************************************************************/ #define SWAP(X,Y) do{int temp=X; X=Y; Y=temp;}while(0) void VGA_box(int x1, int y1, int x2, int y2, short pixel_color) { char *pixel_ptr ; int row, col; /* check and fix box coordinates to be valid */ if (x1>639) x1 = 639; if (y1>479) y1 = 479; if (x2>639) x2 = 639; if (y2>479) y2 = 479; if (x1<0) x1 = 0; if (y1<0) y1 = 0; if (x2<0) x2 = 0; if (y2<0) y2 = 0; if (x1>x2) SWAP(x1,x2); if (y1>y2) SWAP(y1,y2); for (row = y1; row <= y2; row++) for (col = x1; col <= x2; ++col) { //640x480 pixel_ptr = (char *)vga_pixel_ptr + (row<<10) + col ; // set pixel color *(char *)pixel_ptr = pixel_color; } } /**************************************************************************************** * Draw a filled circle on the VGA monitor ****************************************************************************************/ void VGA_disc(int x, int y, int r, short pixel_color) { char *pixel_ptr ; int row, col, rsqr, xc, yc; rsqr = r*r; for (yc = -r; yc <= r; yc++) for (xc = -r; xc <= r; xc++) { col = xc; row = yc; // add the r to make the edge smoother if(col*col+row*row <= rsqr+r){ col += x; // add the center point row += y; // add the center point //check for valid 640x480 if (col>639) col = 639; if (row>479) row = 479; if (col<0) col = 0; if (row<0) row = 0; pixel_ptr = (char *)vga_pixel_ptr + (row<<10) + col ; // set pixel color *(char *)pixel_ptr = pixel_color; } } } // ============================================= // === Draw a line // ============================================= //plot a line //at x1,y1 to x2,y2 with color //Code is from David Rodgers, //"Procedural Elements of Computer Graphics",1985 void VGA_line(int x1, int y1, int x2, int y2, short c) { int e; signed int dx,dy,j, temp; signed int s1,s2, xchange; signed int x,y; char *pixel_ptr ; /* check and fix line coordinates to be valid */ if (x1>639) x1 = 639; if (y1>479) y1 = 479; if (x2>639) x2 = 639; if (y2>479) y2 = 479; if (x1<0) x1 = 0; if (y1<0) y1 = 0; if (x2<0) x2 = 0; if (y2<0) y2 = 0; x = x1; y = y1; //take absolute value if (x2 < x1) { dx = x1 - x2; s1 = -1; } else if (x2 == x1) { dx = 0; s1 = 0; } else { dx = x2 - x1; s1 = 1; } if (y2 < y1) { dy = y1 - y2; s2 = -1; } else if (y2 == y1) { dy = 0; s2 = 0; } else { dy = y2 - y1; s2 = 1; } xchange = 0; if (dy>dx) { temp = dx; dx = dy; dy = temp; xchange = 1; } e = ((int)dy<<1) - dx; for (j=0; j<=dx; j++) { //video_pt(x,y,c); //640x480 pixel_ptr = (char *)vga_pixel_ptr + (y<<10)+ x; // set pixel color *(char *)pixel_ptr = c; if (e>=0) { if (xchange==1) x = x + s1; else y = y + s2; e = e - ((int)dx<<1); } if (xchange==1) y = y + s2; else x = x + s1; e = e + ((int)dy<<1); } }