急驰的蚂蚁的笔记 https://bbs.21ic.com/?587964 [收藏] [复制] [RSS]

日志

6410 2D 硬件画点画线及放大缩小

已有 1389 次阅读2010-6-1 05:52 |个人分类:linux驱动|系统分类:ARM

驱动的ioctl


static int s3c_g2d_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
 s3c_g2d_params *params;
 s3c_g2d_line_params line_params;
 s3c_g2d_transmit tarns_params;
 //u32 val ;
 ROT_DEG rot_degree;
 //int i_te;
 params = (s3c_g2d_params*)file->private_data;
 
 
 //s3c_g2d_check_fifo(30);
 mutex_lock(h_rot_mutex);


 switch(cmd) {


 case S3C_G2D_PARAMS_INIT:
  if (copy_from_user(params, (s3c_g2d_params*)arg, sizeof(s3c_g2d_params)))
  {
   mutex_unlock(h_rot_mutex);
   return -EFAULT;
  }
  s3c_g2d_init_regs(params);
  break;
 case S3C_G2D_ROTATOR_0:
  if (copy_from_user(params, (s3c_g2d_params*)arg, sizeof(s3c_g2d_params)))
  {
   mutex_unlock(h_rot_mutex);
   return -EFAULT;
  }
  rot_degree = ROT_0;
  s3c_g2d_rotator_start(params, rot_degree);
  if(!(file->f_flags & O_NONBLOCK))
  {
   if (interruptible_sleep_on_timeout(&waitq_g2d, G2D_TIMEOUT) == 0)
   {
    printk(KERN_ERR "\n%s: Waiting for interrupt is timeout\n", ____);
   }
  }
  break;


 case S3C_G2D_ROTATOR_90:
  if (copy_from_user(params, (s3c_g2d_params*)arg, sizeof(s3c_g2d_params)))
  {
   mutex_unlock(h_rot_mutex);
   return -EFAULT;
  }
  rot_degree = ROT_90;
  s3c_g2d_rotator_start(params, rot_degree);
  if(!(file->f_flags & O_NONBLOCK))
  {
   if (interruptible_sleep_on_timeout(&waitq_g2d, G2D_TIMEOUT) == 0)
   {
    printk(KERN_ERR "\n%s: Waiting for interrupt is timeout\n", ____);
   }
  }
  break;


 case S3C_G2D_ROTATOR_180:
  if (copy_from_user(params, (s3c_g2d_params*)arg, sizeof(s3c_g2d_params)))
  {
   mutex_unlock(h_rot_mutex);
   return -EFAULT;
  }
  rot_degree = ROT_180;
  s3c_g2d_rotator_start(params, rot_degree);
  if(!(file->f_flags & O_NONBLOCK))
  {
   if (interruptible_sleep_on_timeout(&waitq_g2d, G2D_TIMEOUT) == 0)
   {
    printk(KERN_ERR "\n%s: Waiting for interrupt is timeout\n", ____);
   }
  }
  break;


 case S3C_G2D_ROTATOR_270:
  if (copy_from_user(params, (s3c_g2d_params*)arg, sizeof(s3c_g2d_params)))
  {
   mutex_unlock(h_rot_mutex);
   return -EFAULT;
  }
  rot_degree = ROT_270;
  s3c_g2d_rotator_start(params, rot_degree);
  if(!(file->f_flags & O_NONBLOCK))
  {
   if (interruptible_sleep_on_timeout(&waitq_g2d, G2D_TIMEOUT) == 0)
   {
    printk(KERN_ERR "\n%s: Waiting for interrupt is timeout\n", ____);
   }
  }
  break;


 case S3C_G2D_ROTATOR_X_FLIP:
  if (copy_from_user(params, (s3c_g2d_params*)arg, sizeof(s3c_g2d_params)))
  {
   mutex_unlock(h_rot_mutex);
   return -EFAULT;
  }
  rot_degree = ROT_X_FLIP;
  s3c_g2d_rotator_start(params, rot_degree);
  if(!(file->f_flags & O_NONBLOCK))
  {
   if (interruptible_sleep_on_timeout(&waitq_g2d, G2D_TIMEOUT) == 0)
   {
    printk(KERN_ERR "\n%s: Waiting for interrupt is timeout\n", ____);
   }
  }
  break;


 case S3C_G2D_ROTATOR_Y_FLIP:
  if (copy_from_user(params, (s3c_g2d_params*)arg, sizeof(s3c_g2d_params)))
  {
   mutex_unlock(h_rot_mutex);
   return -EFAULT;
  }
  rot_degree = ROT_Y_FLIP;
  s3c_g2d_rotator_start(params, rot_degree);
  if(!(file->f_flags & O_NONBLOCK))
  {
   if (interruptible_sleep_on_timeout(&waitq_g2d, G2D_TIMEOUT) == 0)
   {
    printk(KERN_ERR "\n%s: Waiting for interrupt is timeout\n", ____);
   }
  }
  break;


 case DRAWING_LINE:
  if(copy_from_user(&line_params,  (s3c_g2d_line_params*)arg,  sizeof(s3c_g2d_line_params)))
  {
   mutex_unlock(h_rot_mutex);
   return -EFAULT;
  }
  line_drawing_flag =0;
  s3c_g2d_drawing_line_start(&line_params);
  wait_event_interruptible(waitq_g2d,line_drawing_flag !=0 );
  line_drawing_flag =0;
  
  break;


 case S3C_G2D_TRANS_DATA:
  if(copy_from_user(&tarns_params, (s3c_g2d_transmit *)arg, sizeof(s3c_g2d_transmit)))
  {
   mutex_unlock(h_rot_mutex);
  }
  s3c_g2d_trans(&tarns_params);
  if(!(file->f_flags & O_NONBLOCK))
  {
   if (interruptible_sleep_on_timeout(&waitq_g2d, G2D_TIMEOUT) == 0)
   {
    printk(KERN_ERR "\n%s: Waiting for interrupt is timeout\n", ____);
   }
  }
  break;


 default:
  mutex_unlock(h_rot_mutex);
  return -EINVAL;
 }


测试代码


/*
*  函数介绍: 硬件画线
*  输入参数: u16 start_x, u16 start_y 起始坐标  u16 end_x, u16 end_y,u32 colour结束坐标  colour线的颜色
*  输出参数:
*  返回值  : 0 成功  -1失败
*/
int G2D_CTL::drawing_line(XY *start_xy, XY *end_xy, u32 colour)
{
 s3c_g2d_line_params line_params;
 line_params.dst_base_addr = g2d_context.dst_addr;
 line_params.start_x = start_xy->x;
 line_params.start_y =start_xy->y;
 line_params.end_x   = end_xy->x;
 line_params.end_y   =end_xy->y;
 line_params.line_colour = colour;
/* printf("line_params.start_x =%d\n",line_params.start_x);
 printf("line_params.start_y =%d\n",line_params.start_y);
 printf("line_params.end_x =%d\n",line_params.end_x);
 printf("line_params.end_y = %d\n",line_params.end_y);
 printf("line_params.line_colour = %x\n",line_params.line_colour);*/


 line_params.line_or_point = 1;
 if(ioctl(g2d_fd, DRAWING_LINE, &line_params) < 0)
 {
  printf("DRAWING_LINE fail\n");
  return -1;
 }
 return 0;
}


 


/*
*  函数介绍: 硬件拷贝
*  输入参数: src_base_addr 源地址  src_r 源图像大小   dst_base_addr 目的地址    dst_r 目的图像大小
*  输出参数:
*  返回值  : 0 成功  -1失败
*/
int G2D_CTL::transmit_bit_blt(u32 src_base_addr, G2D_RECT *src_r, u32 dst_base_addr, G2D_RECT *dst_r)
{
 s3c_g2d_transmit trans_params;
 trans_params.src_base_addr = src_base_addr;
 trans_params.src_start_x   = src_r->begin.x;
 trans_params.src_start_y   = src_r->begin.y;
 trans_params.src_end_x     = src_r->end.x;
 trans_params.src_end_y     = src_r->end.y;


 trans_params.dst_base_addr = dst_base_addr;
 trans_params.dst_start_x   = dst_r->begin.x;
 trans_params.dst_start_y   = dst_r->begin.y;
 trans_params.dst_end_x     = dst_r->end.x;
 trans_params.dst_end_y     = dst_r->end.y;
 if(ioctl(g2d_fd, S3C_G2D_TRANS_DATA, &trans_params) < 0)
 {
  printf("S3C_G2D_TRANS_DATA fail\n");
  return -1;
 }
 return 0;
 
}


 



/*
*  函数介绍: 2d参数初始化
*  输入参数: s3c_g2d_params *params 2d参数结构体
     src_base_addr  LCD源地址
     dst_base_addr  LCD目的地址
     src_r  LCD源参数
     dst_r  LCD目的参数


*  输出参数:
*  返回值  : 0 成功  -1失败
*/
int G2D_CTL::init_params(s3c_g2d_params *params,u32 src_base_addr,u32 dst_base_addr, G2D_RECT *src_r, G2D_RECT *dst_r)
{


 params->bpp        = DF_BPP;
 params->alpha_mode     = 0;
 params->alpha_val      = 0;
 params->color_key_mode = 0;
 params->color_key_val = 0;
 


 params->src_base_addr   = src_base_addr;
 params->src_full_width = src_r->end.x;
 params->src_full_height = src_r->end.y;
 params->src_start_x     = src_r->begin.x;
 params->src_start_y     = src_r->begin.y;
 params->src_work_width = src_r->end.x-1;
 params->src_work_height = src_r->end.y-1; 
 


 params->dst_base_addr   = dst_base_addr;
 params->dst_full_width  = dst_r->end.x;
 params->dst_full_height = dst_r->end.y;
 params->dst_start_x     = dst_r->begin.x;
 params->dst_start_y     = dst_r->begin.y;
 params->dst_work_width  = dst_r->end.x-1;
 params->dst_work_height = dst_r->end.y-1;



 params->cw_x1 = dst_r->begin.x;
 params->cw_y1 = dst_r->begin.y;
 params->cw_x2 = dst_r->end.x-1;
 params->cw_y2 = dst_r->end.y-1;



 params->color_val[G2D_BLACK]   = 0x0;
 params->color_val[G2D_RED]     = 0xF800;
 params->color_val[G2D_GREEN]   = 0x07E0;
 params->color_val[G2D_BLUE]    = 0x001F;
 params->color_val[G2D_WHITE]   = 0xFFFF;
 params->color_val[G2D_YELLOW]  = 0xFFE0;
 params->color_val[G2D_CYAN]    = 0x07FF;
 params->color_val[G2D_MAGENTA] = 0xF81F;


 if(ioctl(g2d_fd, S3C_G2D_PARAMS_INIT, params) < 0)
 {
  printf("S3C_G2D_ROTATOR fail\n");
  return -1;
 }
 return 0;
}


/*
*  函数介绍:放大或缩小矩形,并指定放大缩小率,高度、长度的放大倍数可以不一样
*  输入参数:src_r源图像位置大小,ratio_w长度放大缩小率,ratio_h高度放大缩小率
*  输出参数:
*  返    回:0 成功  -1失败  
*/
int G2D_CTL::stretch_rect(G2D_RECT *src_r, float ratio_w, float ratio_h)
{
 G2D_RECT dst_r;
 int begin_x;
 int begin_y;
 int end_x;
 int end_y;
 begin_x = (int)((float)src_r->begin.x - (ratio_w-1)*((float)(src_r->end.x - src_r->begin.x))/2);
 begin_y = (int)((float)src_r->begin.y - (ratio_h-1)*((float)(src_r->end.y - src_r->begin.y))/2);
 dst_r.begin.x = begin_x;//(begin_x >0 ? begin_x : 0);
 dst_r.begin.y = begin_y;//(begin_y >0 ? begin_y : 0);
 
 end_x = (int)((float)src_r->end.x + (ratio_w-1)*((float)(src_r->end.x - src_r->begin.x))/2);
 end_y = (int)((float)src_r->end.y + (ratio_h-1)*((float)(src_r->end.y - src_r->begin.y))/2);
 dst_r.end.x = end_x;//(end_x >478 ? 479 : end_x);
 dst_r.end.y = end_y;//(end_y >638 ? 639 : end_y);
 return transmit_bit_blt(g2d_context.src_addr,src_r, g2d_context.dst_addr, &dst_r);
 
}


路过

鸡蛋

鲜花

握手

雷人

评论 (0 个评论)