2006-10-27 11:26:54     video frame display with ADV7179

Document created by Aaronwu Employee on Aug 6, 2013
Version 1Show Document
  • View in full screen mode

2006-10-27 11:26:54     video frame display with ADV7179

ZC L (SINGAPORE)

Message: 15647    Hi All,

 

Now the "video frame capture with ADV7183" is done and it's time to continue on the output portion, especially for BF561_EZKIT without card extender, so that we can check the input frame. So, anybody using the driver for ppi1 for video out?

 

zhichien

QuoteReplyEditDelete

 

 

2006-10-28 21:34:38     RE: video frame display with ADV7179

Alex Pereira (BRAZIL)

Message: 15677    Me and a co-worker, sergio trofino, have worked in a device driver for adv7179 on ez-kit bf561. It's been posted in http://blackfin.uclinux.org/forum/message.php?msg_id=13193

 

Is it what you're looking for?

 

Alex

QuoteReplyEditDelete

 

 

2006-10-30 01:04:21     RE: video frame display with ADV7179

ZC L (SINGAPORE)

Message: 15688    Hi Alex,

 

Yes. It is the codes that I'm looking for but looks very different from the adv7183 driver that Laimonas has created(http://blackfin.uclinux.org/forum/message.php?msg_id=15308). Can you please guide me on how to combine the two source codes?

 

Thanks a lot.

 

zhichien

QuoteReplyEditDelete

 

 

2006-10-30 09:23:25     RE: video frame display with ADV7179

sima sima (UNITED STATES)

Message: 15717    hi

 

I used adv7181 and is successful to capture images from PPI0 to fb0,and 7171 can display them from fb0 to LCD,but I just used one buffer.I thought it was the same as two buffers ,I did it ,as a result just I thought

QuoteReplyEditDelete

 

 

2006-10-30 09:49:59     RE: video frame display with ADV7179

ZC L (SINGAPORE)

Message: 15719    Hi,

 

You working on BF533_EZKIT?

QuoteReplyEditDelete

 

 

2006-11-08 10:33:59     RE: video frame display with ADV7179

sui april (CHINA)

Message: 16175    Hi Alex,

After you finished the ADV7179 driver, have you done the test program for the ADV7179 application? i try to write the app program, but cannot call the function in the driver.

i hope your help. thank you very much

QuoteReplyEditDelete

 

 

2006-11-23 13:00:08     RE: video frame display with ADV7179

Alex Pereira (BRAZIL)

Message: 16787    zhichien,

sorry to answer too late. I just saw you message. I could help you implement this driver, as I already have it here.

The IC ADV7179 is quite the same as 7179 when we think about how to use it. But EZ-KIT 533 and 561 are a little different from each other. So, in EZ-KIT 561 you have to generate a reset pulse as follows in Reset_ADV7179 funciont. Say thank you to Sergio Trofino, the guy who found it.

 

First reset ADV7179 with PF using this funcition:

 

#define RESET_ADV7179 0x4000

static void Reset_ADV7179(void)

{

bfin_write_FIO0_DIR(bfin_read_FIO0_DIR() | RESET_ADV7179);

 

udelay(DELAY_RESET);

 

// generate reset pulse

 

bfin_write_FIO0_FLAG_C(RESET_ADV7179); // clear bit to reset ADV7179

 

udelay(DELAY_RESET);

 

bfin_write_FIO0_FLAG_S(RESET_ADV7179); // set bit to re-enable ADV7179

 

udelay(DELAY_RESET);

}

 

Then fix some mismacth functions name that appear when using 533 code in 561.

 

 

Alex

QuoteReplyEditDelete

 

 

2006-11-24 01:11:23     RE: video frame display with ADV7179

ZC L (SINGAPORE)

Message: 16806    Hi Alex,

 

Thanks for replying. Can you send me a copy of the codes? I found there is some undefined value. (Such as RGB_HEIGHT, YCBCR_WIDTH).

 

And may I know what should be displayed on the monitor?

 

Thank you.

QuoteReplyEditDelete

 

 

2006-11-26 13:03:05     RE: video frame display with ADV7179

Alex Pereira (BRAZIL)

Message: 16885    Here a copy of bfin_ad7179fb.h file:

 

/*

* linux/drivers/video/bfin_ad7179.h -- Analog Devices Blackfin + AD7179 video out chip

*

* Based on vga16fb.c: Copyright 1999 Ben Pfaff <pfaffben@debian.org> and Petr Vandrovec <VANDROVE@vc.cvut.cz>

* Copyright 2004 Ashutosh Kumar Singh (ashutosh.singh@rrap-software.com)

*

* This file is subject to the terms and conditions of the GNU General

* Public License. See the file COPYING in the main directory of this

* archive for more details.

*/

#define CONFIG_NTSC

 

#define BLACK (0x01800180) /* black pixel pattern */

#define BLUE (0x296E29F0) /* blue pixel pattern */

#define RED (0x51F0515A) /* red pixel pattern */

#define MAGENTA (0x6ADE6ACA) /* magenta pixel pattern*/

#define GREEN (0x91229136) /* green pixel pattern */

#define CYAN (0xAA10AAA6) /* cyan pixel pattern */

#define YELLOW (0xD292D210) /* yellow pixel pattern */

#define WHITE (0xFE80FE80) /* white pixel pattern */

 

#define true 1

#define false 0

 

 

struct system_code_type

{

unsigned int sav; /* Start of Active Video */

unsigned int eav; /* End of Active Video */

};

 

#ifdef CONFIG_NTSC

const struct system_code_type system_code_map[4] =

{

{ 0xFF0000EC, 0xFF0000F1 },

{ 0xFF0000AB, 0xFF0000B6 },

{ 0xFF000080, 0xFF00009D },

{ 0xFF0000C7, 0xFF0000DA }

};

#define FIELD1_VB_START 0

#define FIELD1_VB_END 18

#define FIELD1_AV_START 19

#define FIELD1_AV_END 262

#define FIELD2_VB_START 263

#define FIELD2_VB_END 281

#define FIELD2_AV_START 282

#define FIELD2_AV_END 524

#define HB_LENGTH 268

 

#define RGB_WIDTH 720

#define RGB_HEIGHT 480

#define YCBCR_WIDTH 1716

#define YCBCR_HEIGHT 525

 

#else /* CONFIG_PAL */

const struct system_code_type system_code_map[4] =

{

{ 0xFF0000AB, 0xFF0000B6 },

{ 0xFF000080, 0xFF00009D },

{ 0xFF0000EC, 0xFF0000F1 },

{ 0xFF0000C7, 0xFF0000DA }

};

#define FIELD1_VB_START 1

#define FIELD1_VB_END 22

#define FIELD1_AV_START 23

#define FIELD1_AV_END 310

#define FIELD2_VB_START 311

#define FIELD2_VB_END 335

#define FIELD2_AV_START 336

#define FIELD2_AV_END 623

#define FIELD2_VB2_START 624

#define FIELD2_VB2_END 625

#define HB_LENGTH 280

 

#define RGB_WIDTH 720

#define RGB_HEIGHT 576

#define YCBCR_WIDTH 1728

#define YCBCR_HEIGHT 625

#endif /* CONFIG_NTSL */

 

struct rgb_t{

unsigned char r,g,b;

} ;

 

struct ycrcb_t{

unsigned char Cb,y1,Cr,y2;

};

 

struct adv7179 {

unsigned char reg[128];

 

int norm;

int input;

int enable;

int bright;

int contrast;

int hue;

int sat;

};

 

#define I2C_ADV7179 0x54

#define RESET_ADV7179 0x4000

#define DELAY_RESET 40

 

 

=============================================

 

Here a copy of ad7179fb_main.c file:

/*

* linux/drivers/video/bfin_ad7179.c -- Analog Devices Blackfin + AD7179 video out chip

*

* Based on linux/drivers/video/bfin_ad7171_main.c

* Copyright 1999 Ben Pfaff <pfaffben@debian.org> and Petr Vandrovec <VANDROVE@vc.cvut.cz>

* Copyright 2004 Ashutosh Kumar Singh (ashutosh.singh@rrap-software.com)

* Copyright 2006 Sergio Trofino (sergio.trofino@rayvision.com.br)

* This file is subject to the terms and conditions of the GNU General

* Public License. See the file COPYING in the main directory of this

* archive for more details.

*/

 

#include <linux/module.h>

#include <linux/kernel.h>

#include <linux/errno.h>

#include <linux/string.h>

#include <linux/mm.h>

#include <linux/tty.h>

#include <linux/slab.h>

#include <linux/delay.h>

#include <linux/fb.h>

#include <linux/ioport.h>

#include <linux/init.h>

#include <linux/types.h>

#include <linux/interrupt.h>

#include <linux/sched.h>

#include <asm/blackfin.h>

#include <asm/irq.h>

#include <asm/dma.h>

#include <linux/dma-mapping.h>

 

#include "bfin_ad7179fb.h"

#define BFIN_FB_PHYS_LEN (RGB_WIDTH*RGB_HEIGHT*sizeof(struct rgb_t))

#define BFIN_FB_YCRCB_LEN (YCBCR_WIDTH*YCBCR_HEIGHT)

 

struct dma_descriptor {

 

unsigned int * next_desc;

 

unsigned int * start_addr;

} descriptor;

 

unsigned char * ycrcb_buffer1 = 0, * ycrcb_buffer2 = 0;

 

struct timer_list bfin_framebuffer_timer;

 

static int bfin_ad7179_fb_open(struct fb_info *info, int user);

static int bfin_ad7179_fb_release(struct fb_info *info, int user);

static int bfin_fb_mmap(struct fb_info *info, struct vm_area_struct * vma);

 

static void bfin_config_ppi(void);

static void bfin_config_dma(void *ycrcb_buffer1);

static void bfin_disable_dma(void);

static void bfin_enable_ppi(void);

static void bfin_disable_ppi(void);

static void bfin_framebuffer_init(void *ycrcb_buffer1, void *ycrcb_buffer2);

 

static void bfin_framebuffer_update(unsigned char *ycrcb_buffer1, unsigned char *ycrcb_buffer2);

 

static void bfin_framebuffer_timer_setup(void);

static void bfin_framebuffer_timerfn(unsigned long data);

//extern unsigned long l1_data_A_sram_alloc(unsigned long size);

//extern int l1_data_A_sram_free(unsigned long addr);

 

#include <linux/video_encoder.h>

#include <linux/videodev.h>

 

static char adv7179_name[] = "adv7179";

 

static char *norms[] = { "PAL", "NTSC" };

 

/*

* card parameters

*/

 

static struct fb_info bfin_ad7179_fb;

 

static struct bfin_ad7179_fb_par {

/* structure holding blackfin / ad7179 paramters when

screen is blanked */

struct {

unsigned char Mode; /* ntsc/pal/? */

} vga_state;

atomic_t ref_count;

} bfin_par;

 

/* --------------------------------------------------------------------- */

 

static struct fb_var_screeninfo bfin_ad7179_fb_defined = {

.xres = RGB_WIDTH,

.yres = RGB_HEIGHT,

.xres_virtual = RGB_WIDTH,

.yres_virtual = RGB_HEIGHT,

.bits_per_pixel = 16,

.activate = FB_ACTIVATE_TEST,

.height = -1,

.width = -1,

.left_margin = 0,

.right_margin = 0,

.upper_margin = 0,

.lower_margin = 0,

.vmode = FB_VMODE_INTERLACED,

};

 

static struct fb_fix_screeninfo bfin_ad7179_fb_fix __initdata = {

.id = "BFIN 7179",

.smem_len = BFIN_FB_PHYS_LEN,

.type = FB_TYPE_PACKED_PIXELS,

.visual = FB_VISUAL_TRUECOLOR,

.xpanstep = 0,

.ypanstep = 0,

.line_length = RGB_WIDTH*2,

.accel = FB_ACCEL_NONE

};

 

static struct fb_ops bfin_ad7179_fb_ops = {

.owner = THIS_MODULE,

.fb_open = bfin_ad7179_fb_open,

.fb_release = bfin_ad7179_fb_release,

.fb_mmap = bfin_fb_mmap,

};

 

static void bfin_framebuffer_timer_setup(void)

{

init_timer(&bfin_framebuffer_timer) ;

bfin_framebuffer_timer.function = bfin_framebuffer_timerfn ;

bfin_framebuffer_timer.expires = jiffies + 10 ;

add_timer(&bfin_framebuffer_timer);

}

 

static void bfin_framebuffer_timerfn(unsigned long data)

{

bfin_framebuffer_update(ycrcb_buffer1, ycrcb_buffer2);

bfin_framebuffer_timer_setup();

}

 

 

static int bfin_fb_mmap(struct fb_info *info, struct vm_area_struct * vma)

{

/* we really dont need any map ... not sure how the smem_start will

end up in the kernel

*/ int a;

a = ycrcb_buffer2;

*(ycrcb_buffer1 + 900900) = a>>24;

*(ycrcb_buffer1 + 900901) = a>>16;

*(ycrcb_buffer1 + 900902) = a>>8;

*(ycrcb_buffer1 + 900903) = a;

vma->vm_start = (int)ycrcb_buffer1;

return (int)ycrcb_buffer1;

}

 

static void bfin_framebuffer_init(void *ycrcb_buffer1, void *ycrcb_buffer2)

{

/*unsigned char * ycrcb_ptr = ycrcb_buffer;

int i, j;

for(j = 0; j < (RGB_WIDTH * YCBCR_HEIGHT); j++)

{

*ycrcb_ptr++=0x80;

*ycrcb_ptr++=0x10;

}*/

char *dest1 = (void *)ycrcb_buffer1;

char *dest2 = (void *)ycrcb_buffer2;

int lines;

 

for ( lines = 0; lines < YCBCR_HEIGHT; lines++ )

{

int offset = 0;

unsigned int code;

int i;

#ifdef CONFIG_NTSC

if((lines>=0 && lines<=2) || (lines>=265 && lines <=281))

offset = 0;

else if((lines>=3 && lines<=18) || (lines>=263 && lines<=264))

offset = 1;

else if(lines>=19 && lines<=262)

offset = 2;

else if(lines>=282 && lines<=524)

offset = 3;

#else // CONFIG_PAL

if((lines>=1 && lines<=22) || (lines>=311 && lines<=312))

offset = 0;

else if(lines>=23 && lines<=310)

offset = 1;

else if((lines>=313 && lines<=335) || (lines>=624 && lines <=625))

offset = 2;

else if(lines>=336 && lines<=623)

offset = 3;

#endif

else

printk("Frame buffer init error\n");

 

// Output EAV code

code = system_code_map[ offset ].eav;

*dest1++ = (char) (code >> 24) & 0xff;

*dest1++ = (char) (code >> 16) & 0xff;

*dest1++ = (char) (code >> 8) & 0xff;

*dest1++ = (char) (code) & 0xff;

*dest2++ = (char) (code >> 24) & 0xff;

*dest2++ = (char) (code >> 16) & 0xff;

*dest2++ = (char) (code >> 8) & 0xff;

*dest2++ = (char) (code) & 0xff;

 

// Output horizontal blanking

for ( i = 0; i < HB_LENGTH/2; ++i )

{

*dest1++ = 0x80;

*dest1++ = 0x10;

*dest2++ = 0x80;

*dest2++ = 0x10;

}

 

// Output SAV

code = system_code_map[ offset ].sav;

*dest1++ = (char) (code >> 24) & 0xff;

*dest1++ = (char) (code >> 16) & 0xff;

*dest1++ = (char) (code >> 8) & 0xff;

*dest1++ = (char) (code) & 0xff;

*dest2++ = (char) (code >> 24) & 0xff;

*dest2++ = (char) (code >> 16) & 0xff;

*dest2++ = (char) (code >> 8) & 0xff;

*dest2++ = (char) (code) & 0xff;

 

// Output empty horizontal data

for ( i = 0; i <RGB_WIDTH; ++i )

{

*dest1++ = 0x80;

*dest1++ = 0x10;

*dest2++ = 0x80;

*dest2++ = 0x10;

}

}

}

 

void bfin_framebuffer_update(unsigned char *ycrcb_buffer1, unsigned char *ycrcb_buffer2)

{

if (*(ycrcb_buffer1+900902))

{

*(ycrcb_buffer1+900902) = 0;

if (*(ycrcb_buffer1+900901) == 1)

descriptor.start_addr = (unsigned int *) ycrcb_buffer1;

else

descriptor.start_addr = (unsigned int *) ycrcb_buffer2;

}

}

 

static void bfin_config_dma(void *ycrcb_buffer1)

{

descriptor.next_desc = (unsigned int *) &descriptor;

 

descriptor.start_addr = (unsigned int *) ycrcb_buffer1;

bfin_write_DMA1_1_NEXT_DESC_PTR((unsigned int *)&descriptor);

bfin_write_DMA1_1_START_ADDR(ycrcb_buffer1);

bfin_write_DMA1_1_X_COUNT(YCBCR_WIDTH/4);

bfin_write_DMA1_1_X_MODIFY(0x0004);

bfin_write_DMA1_1_Y_COUNT(YCBCR_HEIGHT);

bfin_write_DMA1_1_Y_MODIFY(0x0004);

bfin_write_DMA1_1_CONFIG(0x7419);

 

#if 0

*pDMA1_1_START_ADDR = ycrcb_buffer;

*pDMA1_1_X_COUNT = YCBCR_WIDTH/2;

*pDMA1_1_X_MODIFY = 0x0002;

*pDMA1_1_Y_COUNT = YCBCR_HEIGHT;

*pDMA1_1_Y_MODIFY = 0x0002;

*pDMA1_1_CONFIG = 0x1015;

#endif

}

 

static void bfin_disable_dma(void)

{

bfin_write_DMA1_1_CONFIG(bfin_read_DMA1_1_CONFIG() & (~DMAEN));

#if 0

*pDMA1_1_CONFIG &= ~DMAEN;

#endif

}

 

static void bfin_config_ppi(void)

{

#ifdef CONFIG_BF537

*pPORTG_FER = 0xFFFF; /* PPI[15:0] */

*pPORTF_FER |= 0x8380; /* PF.15 - PPI_CLK */

*pPORT_MUX &= ~0x0E00;

*pPORT_MUX |= 0x0100;

#endif

bfin_write_PPI1_CONTROL(0x0182);

// bfin_write_PPI1_COUNT(720*2-1);

 

// bfin_write_PPI1_DELAY(122*2-1);

bfin_write_PPI1_FRAME(YCBCR_HEIGHT-1);

}

 

static void bfin_enable_ppi(void)

{

bfin_write_PPI1_CONTROL(bfin_read_PPI1_CONTROL() | PORT_EN);

#if 0

*pPPI1_CONTROL * matriz_y_i = malloc( sizeof(dma_img_dsc) * 2);|= PORT_EN;

#endif

}

 

static void bfin_disable_ppi(void)

{

bfin_write_PPI1_CONTROL(bfin_read_PPI1_CONTROL() & (~PORT_EN));

#if 0

*pPPI1_CONTROL &= ~PORT_EN;

#endif

}

 

static void Reset_ADV7179(void)

{

bfin_write_FIO0_DIR(bfin_read_FIO0_DIR() | RESET_ADV7179);

 

udelay(DELAY_RESET);

 

// generate reset pulse

 

bfin_write_FIO0_FLAG_C(RESET_ADV7179); // clear bit to reset ADV7179

 

udelay(DELAY_RESET);

 

bfin_write_FIO0_FLAG_S(RESET_ADV7179); // set bit to re-enable ADV7179

 

udelay(DELAY_RESET);

#if 0

*pFIO0_DIR |= RESET_ADV7179;

 

udelay(DELAY_RESET);

 

// generate reset pulse

 

*pFIO0_FLAG_C = RESET_ADV7179; // clear bit to reset ADV7179

 

udelay(DELAY_RESET);

 

*pFIO0_FLAG_S = RESET_ADV7179; // set bit to re-enable ADV7179

 

udelay(DELAY_RESET);

#endif

 

}

 

int __init bfin_ad7179_fb_init(void)

{

int ret = 0;

 

// configure RESET flag as output

 

Reset_ADV7179();

udelay(5 * (DELAY_RESET));

printk(KERN_NOTICE "bfin_ad7179_fb: initializing:\n");

ycrcb_buffer1 = (unsigned char *)kmalloc(BFIN_FB_YCRCB_LEN+4, GFP_KERNEL);

memset(ycrcb_buffer1, 0, BFIN_FB_YCRCB_LEN);

ycrcb_buffer2 = (unsigned char *)kmalloc(BFIN_FB_YCRCB_LEN, GFP_KERNEL);

memset(ycrcb_buffer2, 0, BFIN_FB_YCRCB_LEN);

 

bfin_ad7179_fb.screen_base = (void *)ycrcb_buffer1;

bfin_ad7179_fb_fix.smem_start = (int)ycrcb_buffer1;

if (!bfin_ad7179_fb.screen_base) {

printk("bfin_ad7179_fb: unable to map device\n");

ret = -ENOMEM;

}

bfin_ad7179_fb_defined.red.length = 8;

bfin_ad7179_fb_defined.green.length = 8;

bfin_ad7179_fb_defined.blue.length = 8;

 

bfin_ad7179_fb.fbops = &bfin_ad7179_fb_ops;

bfin_ad7179_fb.var = bfin_ad7179_fb_defined;

 

// our physical memory is dynamically allocated

bfin_ad7179_fb_fix.smem_start = (int)ycrcb_buffer1;

bfin_ad7179_fb.fix = bfin_ad7179_fb_fix;

bfin_ad7179_fb.par = &bfin_par;

bfin_ad7179_fb.flags = FBINFO_DEFAULT;

 

 

if (register_framebuffer(&bfin_ad7179_fb) < 0) {

printk(KERN_ERR "bfin_ad7179_fb: unable to register framebuffer\n");

ret = -EINVAL;

}

printk(KERN_INFO "fb%d: %s frame buffer device\n",

bfin_ad7179_fb.node, bfin_ad7179_fb.fix.id);

printk(KERN_INFO "fb memory address : 0x%p\n",ycrcb_buffer1);

 

return ret;

}

 

 

 

static int bfin_ad7179_fb_open(struct fb_info *info, int user)

{

bfin_ad7179_fb.screen_base = (void *)ycrcb_buffer1;

bfin_ad7179_fb_fix.smem_start = (int)ycrcb_buffer1;

if (!bfin_ad7179_fb.screen_base) {

printk("bfin_ad7179_fb: unable to map device\n");

return -ENOMEM;

}

 

bfin_framebuffer_init(ycrcb_buffer1, ycrcb_buffer2);

bfin_framebuffer_timer_setup();

bfin_config_ppi();

bfin_config_dma(ycrcb_buffer1);

bfin_enable_ppi();

return 0;

}

 

static int bfin_ad7179_fb_release(struct fb_info *info, int user)

{

del_timer(&bfin_framebuffer_timer);

bfin_disable_dma();

bfin_disable_ppi();

return 0;

}

 

static void __exit bfin_ad7179_fb_exit(void)

{

if(ycrcb_buffer1)

kfree(ycrcb_buffer1);

if(ycrcb_buffer2)

kfree(ycrcb_buffer2);

unregister_framebuffer(&bfin_ad7179_fb);

}

 

MODULE_LICENSE("GPL");

module_init(bfin_ad7179_fb_init);

module_exit(bfin_ad7179_fb_exit);

QuoteReplyEditDelete

 

 

2007-05-08 22:25:59     RE: video frame display with ADV7179

ZC L (SINGAPORE)

Message: 26065   

 

Hi Alex,

 

It has been a long time since my last post. I finally got the AD7183 raw image. I'm wondering how the AD7179fb driver can take the raw image and display on the TV monitor?

 

Thanks a lot.

 

zhichien

QuoteReplyEditDelete

 

 

2008-06-17 13:27:50     RE: video frame display with ADV7179

Justin Wetherell (UNITED STATES)

Message: 57418   

 

If anyone has more info on how to get an image from the ppi to the fb for the 561+Eval board, it'd be greatly appreciated.

Attachments

    Outcomes