iMX7D : NTSC Video Capture

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

iMX7D : NTSC Video Capture

Jump to solution
2,731 Views
dh29
Contributor IV

Linux Kernel: v4.9.11

 

In my on-going battle to get an AD7280M (csi-mipi) working on an i.MX7 I can now successfully capture/stream images from a PAL camera feed. The ADV7280M is capable of operating in both PROGRESSIVE and INTERLACED modes.

For my working PAL I have configured the active image sizes as:

  • PAL INTERLACED = 720 x 288
  • PAL PROGRESSIVE = 720 x 576

I have now moved on to trying a NTSC camera source, but I cannot get it to work properly. As interlaced NTSC can have difference image sizes for the ODD and EVEN fields, I have concentrated on progressive. On following the same line of thinking as for PAL I have tried the following active image size:

  • NTSC INTERLACED = 720 x 480

The image is clearly recognizable, BUT the image is scrolling diagonally.

I get this problem from both the NTSC camera feed and also if I configure the ADV7280M to output its internal NTSC test pattern, so the problem is nothing to do with the camera itself.

 

Anybody have any experience in getting NTSC stable with the MIPI CSI of an i.MX7 ??

Labels (4)
1 Solution
2,075 Views
dh29
Contributor IV

I have finally got NTSC capture working !!

First, some excellent support from Analogue Devices pointed me at some MIPI captures for the ADV7280x (https://ez.analog.com/servlet/JiveServlet/download/10612-25-31341/ADV728x%20MIPI%20free%20run.zip). This helped in my understanding of the expected NTSC video data when received via MIPI.

From this I concluded that NTSC differed from PAL in that the active video area for NTSC was 720x480, BUT the actual data received by the MIPI for NTSC has an additional 27 lines of 'data' (not blanking) lines at the top of the image.  Where-as PAL had the same value of 720x576 for both active and actual. (Remember I am using PROGRESSIVE formats to avoid any interlacing issues).

From this I concluded that my image size should be configured to 720x507.

However, it looks like when I request an image size of 720x507, somewhere in the V4L2 IOCTLs I get 720x508 returned. (Looks like it 'rounds the 507). This value of 720x508 is then used to configure the expected MIPI image size in register CSI_CSI_IMAG_PARA [see /drivers/media/platform/subdev/mx6s_capture.c function csi_set_imagepara()]. This value of 720x508 is incorrect!

My 'quick-fix' was to hard-code the correct image size of 720x507 into function csi_set_imagepara() and the image is stable! 

[I suspect there is a better/cleaner solution by setting something in the V4L2 calls, but for the moment I am happy that I have proved my hardware]

View solution in original post

4 Replies
2,076 Views
dh29
Contributor IV

I have finally got NTSC capture working !!

First, some excellent support from Analogue Devices pointed me at some MIPI captures for the ADV7280x (https://ez.analog.com/servlet/JiveServlet/download/10612-25-31341/ADV728x%20MIPI%20free%20run.zip). This helped in my understanding of the expected NTSC video data when received via MIPI.

From this I concluded that NTSC differed from PAL in that the active video area for NTSC was 720x480, BUT the actual data received by the MIPI for NTSC has an additional 27 lines of 'data' (not blanking) lines at the top of the image.  Where-as PAL had the same value of 720x576 for both active and actual. (Remember I am using PROGRESSIVE formats to avoid any interlacing issues).

From this I concluded that my image size should be configured to 720x507.

However, it looks like when I request an image size of 720x507, somewhere in the V4L2 IOCTLs I get 720x508 returned. (Looks like it 'rounds the 507). This value of 720x508 is then used to configure the expected MIPI image size in register CSI_CSI_IMAG_PARA [see /drivers/media/platform/subdev/mx6s_capture.c function csi_set_imagepara()]. This value of 720x508 is incorrect!

My 'quick-fix' was to hard-code the correct image size of 720x507 into function csi_set_imagepara() and the image is stable! 

[I suspect there is a better/cleaner solution by setting something in the V4L2 calls, but for the moment I am happy that I have proved my hardware]

2,075 Views
joanxie
NXP TechSupport
NXP TechSupport

could you tell me what you change from PAL to NTSC? what detailed register or angthing you change?

0 Kudos
2,075 Views
dh29
Contributor IV

Hi joanxie 

Sorry for the delay but I've been on annual leave.

I replied to your question of July 25th - 

Could you tell me what you change from PAL to NTSC? what detailed register or angthing you change?"

- but I have seen no further comments from you.

In my reply of July 26th I confirm:

The only register change I make between the working PAL and the non-working (scrolling) NTSC is to change register CSI_CSIIMAG_PARA (Addr: 3071_0034h) from ((720 << 16) | 576) for PAL, to ((720 << 16) | 480) for NTSC.

Should I be changing other registers for NTSC ???

0 Kudos
2,075 Views
dh29
Contributor IV

Hi joanxie 

The only register change I make between the working PAL and the non-working (scrolling) NTSC is to change register CSI_CSIIMAG_PARA (Addr: 3071_0034h) from ((720 << 16) | 576) for PAL, to ((720 << 16) | 480) for NTSC.

This change is made within module mx6s_capture.c (/drivers/media/platform/mxc/subdev). This register is first initialized to a default in function csi_init_interface()....

static void csi_init_interface(struct mx6s_csi_dev *csi_dev)
{
unsigned int val = 0;
unsigned int imag_para;

val |= BIT_SOF_POL;
val |= BIT_REDGE;
val |= BIT_GCLK_MODE;
val |= BIT_HSYNC_POL;
val |= BIT_FCC;
val |= 1 << SHIFT_MCLKDIV;
val |= BIT_MCLKEN;
__raw_writel(val, csi_dev->regbase + CSI_CSICR1);

// imag_para = (720 << 16) | 576; //PAL
imag_para = (720 << 16) | 480;    //NTSC

__raw_writel(imag_para, csi_dev->regbase + CSI_CSIIMAG_PARA);

val = BIT_DMA_REFLASH_RFF;
__raw_writel(val, csi_dev->regbase + CSI_CSICR3);
}

and is then set as part of the negotiated supported image format as per function csi_set_imagepara()....

static void csi_set_imagpara(struct mx6s_csi_dev *csi, int width, int height)
{
int imag_para = 0;
unsigned long cr3 = __raw_readl(csi->regbase + CSI_CSICR3);

#ifdef DH_DEBUG2
   printk("[MX6S_CAPTURE] %s : width = %d | height = %d\n", __func__, width, height);
#endif

imag_para = (width << 16) | height;
__raw_writel(imag_para, csi->regbase + CSI_CSIIMAG_PARA);

/* reflash the embeded DMA controller */
__raw_writel(cr3 | BIT_DMA_REFLASH_RFF, csi->regbase + CSI_CSICR3);
}

My DH_DEBUG2 printk(), above, confirms that the driver has set width=720 and height=480 for NTSC.

0 Kudos