⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lancelot.c

📁 基于FPGA的VGA控制器设计。对外支持普通VGA接口
💻 C
字号:
/***********************************
 ***          Lancelot           ***
 ***********************************
 *** Written by Marco Groeneveld ***
 ***  For more information visit *** 
 ***    http://www.fpga.nl       *** 
 **********************************/
#include <io.h>
#include <stdio.h>
#include <string.h>
#include <system.h>
#include <lancelot.h>
#include <../../lancelot_vga/inc/lancelot_vga_regs.h>
#include <sys/alt_cache.h>

// Display three colour bars
void vga_test(unsigned char *ram)
{
   unsigned int i;
   unsigned int j;
   unsigned int k;
   
   // Fill video memory
   for(k = 0; k < 200; k++)
   {
      for(j = 0; j < 800 / 10; j++)
      {
         for(i = 0; i < 10; i++)
         {
            *(ram+ (k*800) + (j*10) + i             ) = j;   
            *(ram+ (k*800) + (j*10) + i + (200*800) ) = j + 80;   
            *(ram+ (k*800) + (j*10) + i + (400*800) ) = j + 160;   
         }
      }
   }

   // Fill colour table
   for(i = 0; i < 80; i++)
   {
      IOWR_LANCELOT_VGA_COLOUR(VGA_BASE, ( ( (i)     << 24 ) | ( (i*3) << 16 ) ) & 0xFFFF0000);
      IOWR_LANCELOT_VGA_COLOUR(VGA_BASE, ( ( (i+80)  << 24 ) | ( (i*3) << 8  ) ) & 0xFF00FF00);
      IOWR_LANCELOT_VGA_COLOUR(VGA_BASE, ( ( (i+160) << 24 ) | ( (i*3)       ) ) & 0xFF0000FF);
   }
}

// Initialize vga controller
void vga_init(void)
{
   // Reset Lancelot
   IOWR_LANCELOT_VGA_RESET(VGA_BASE, 0x12345678);
   // Wait until reset completed
   while( ( IORD_LANCELOT_VGA_STATUS(VGA_BASE) & 0xFFFF0000 ) != 0x52470000 );

   // Set Lancelot 800 x 600 vga parameters
   IOWR_LANCELOT_VGA_RESOLUTION(VGA_BASE, (horizontal_resolution << 16) + vertical_resolution);
   IOWR_LANCELOT_VGA_HORIZONTAL(VGA_BASE, (hsync_pulse_width << 16) + (hsync_back_porch_width << 8) + hsync_front_porch_width);
   IOWR_LANCELOT_VGA_VERTICAL(VGA_BASE, (vsync_pulse_width << 16) + (vsync_back_porch_width << 8) + vsync_front_porch_width);
   IOWR_LANCELOT_VGA_CONTROL(VGA_BASE, LANCELOT_VGA_CONTROL_START_VIDEO | LANCELOT_VGA_CONTROL_SET_DAC);
}

void copy_image(unsigned char *ram, unsigned char *flash)
{
   unsigned int i;
   unsigned int width;
   unsigned int height;
   unsigned int offset;
   
   width = (*(flash + 19) << 8) | *(flash + 18);
   height = (*(flash  + 23) << 8) | *(flash + 22);
   offset = (*(flash  + 11) << 8) | *(flash + 10); 
   
   // Fill Colour Table
   for(i = 0; i < 256; i++)
      IOWR_LANCELOT_VGA_COLOUR(VGA_BASE,
         ( (i << 24) |
         ( *( flash + 54 + (i * 4)     )       ) |
         ( *( flash + 54 + (i * 4) + 1 ) << 8  ) | 
         ( *( flash + 54 + (i * 4) + 2 ) << 16 )  ) );

   // Copy image to memory
   for(i = 0; i < height; i++)
      memcpy(ram + (i * width), flash + offset + ( (width * (height - 1) ) - (i * width) ), width);  
}

void switch_image(unsigned char *ram, unsigned char *flash)
{
   unsigned int i;

  // Force blanking
  IOWR_LANCELOT_VGA_CONTROL(VGA_BASE, LANCELOT_VGA_CONTROL_FORCE_BLANKING);  
  printf("\nSwitching image");
   
  // Wait for vertical blank
  while(! IORD_LANCELOT_VGA_STATUS(VGA_BASE) & LANCELOT_VGA_STATUS_VS_BLANK );
  
   // Fill Colour Table
   for(i = 0; i < 256; i++)
      IOWR_LANCELOT_VGA_COLOUR(VGA_BASE,
         ( (i << 24) |
         ( *( flash + 54 + (i * 4)     )       ) |
         ( *( flash + 54 + (i * 4) + 1 ) << 8  ) | 
         ( *( flash + 54 + (i * 4) + 2 ) << 16 )  ) );

   // Set new data address
   IOWR_LANCELOT_VGA_DMA(VGA_BASE, (unsigned int) (ram) & 0x7FFFFFFF);

  // Release blanking
  IOWR_LANCELOT_VGA_CONTROL(VGA_BASE, LANCELOT_VGA_CONTROL_START_VIDEO);  
}

int main(void)
{
   unsigned char *ram1, *ram2;
   unsigned char *flash;
   unsigned int i;
      
   printf("\nWelcome to Lancelot!");
   printf("\n====================");
   
   ram1 = (unsigned char *) alt_uncached_malloc(800*600);
   ram2 = (unsigned char *) alt_uncached_malloc(800*600);
   flash = (unsigned char *) FLASH_BASE;
   
   vga_test(ram1);
   vga_init();
   copy_image(ram1, flash + 0x200000);
   copy_image(ram2, flash + 0x300000);
   
   while(1)
   {
      for(i=0; i < 10000000; i++);
      switch_image(ram1, flash + 0x200000);
      for(i=0; i < 10000000; i++);
      switch_image(ram2, flash + 0x300000);
   }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -