Post Go back to editing

Luma dynamic range sometimes shrinks

Category: Software
Product Number: ADV7180

Hi,

So I'm trying to use ADV7180A to digitise an inherently unstable and noisy analog video. The source is CVBS, input network is as specified in the data sheet (24 and 51 Ohm resistor and 100 mF capacitor). I'm using the built-it linux driver (kernel version 6.12.25) with custom patch that is attached at the end (though I tried to change a few things over the course of experimentation). One major issue I'm constantly facing is all pixels pretty much becoming black or white sometimes. It happens precisely when the ADV7180 loses sync and the issue often goes away the same way. On the attached video you can see black-and-white content changed by a more rich picture after lock is lost and regained.

As you can see in the patch I return some information about the state of the chip and it shows that the automatic luma gain is more or less the same for the black-and white and the richer grayscale picture. So it's probably not AGC. Also was pretty important to disable peak white algorithm as it often darkened the picture significantly. So my only guess is something goes wrong with clamping? But there aren't many toggles to play with and you can't read the restored dc value so it feels like I'm stuck. Any help would be appreciated 



Patch in question:

339c339
< return -EINVAL;
---
> return ADV7180_STD_AD_PAL_BG_NTSC_J_SECAM;
383c383
< err = adv7180_set_video_standard(state,
---
> err = adv7180_set_video_standard(state,
385,386c385,386
< if (err)
< goto unlock;
---
> if (err)
> goto unlock;
388,389c388,389
< msleep(100);
< __adv7180_status(state, NULL, std);
---
> msleep(100);
> __adv7180_status(state, NULL, std);
446a447,475
>
> int y_average_higher = adv7180_read(state, 0x40e7);
> int y_average_lower = adv7180_read(state, 0x40e8);
> int ace_status = (adv7180_read(state, 0x40e8) >> 7) & 1;
> int status1 = adv7180_read(state, 0x10);
> int status2 = adv7180_read(state, 0x12);
> int status3 = adv7180_read(state, 0x13);
> int luma_higher = adv7180_read(state, 0x2f);
> int luma_lower = adv7180_read(state, 0x30);
> int i2p = (i2c_smbus_read_byte_data(state->vpp_client, 0x55) >> 7) & 1;
> int adv_timing = (i2c_smbus_read_byte_data(state->vpp_client, 0x5B) >> 7) & 1;
> int s1 = status1 & 1;
> int s2 = (status1 & 2) >> 1;
> int s3 = (status1 & 4) >> 2;
> int s4 = (status1 & 8) >> 3;
> int s5 = (status1 & 0x70) >> 4;
> int s6 = (status1 & 0x80) >> 7;
> int s7 = status3 & 1;
> int s8 = (status3 & 4) >> 2;
> int s9 = (status3 & 0x10) >> 4;
> int s10 = (status3 & 0x20) >> 5;
> int s11 = (status3 & 0x40) >> 6;
> int s12 = (status3 & 0x80) >> 7;
> int luma = luma_lower + ((luma_higher & 0xf) << 8);
> int y_average = (y_average_lower & 0x3) + (y_average_higher << 2);
>
> v4l_info(state->client, "IN_LOCK: %x; LOST_LOCK: %x; FSC_LOCK: %x; FOLLOW_PW: %x; STD: 0x%x; COL_KILL: %x; Status2: 0x%02x; INST_HLOCK: %x; SD_OP_50Hz: %x; FREE_RUN_ACT: %x; STD FLD LEN: %x; Interlaced: %x; PAL_SW_LOCK: %x; Luma: 0x%03x; Average y: 0x%03x; ACE ENABLED: %x; I2P ENABLED: %x; ADV TIMING: %x\n",
> s1, s2, s3, s4, s5, s6, status2, s7, s8, s9, s10, s11, s12, luma, y_average, ace_status, i2p, adv_timing);
>
505a535,537
> int err = mutex_lock_interruptible(&state->mutex);
> if (err)
> return err;
514c546,548
< if (state->curr_norm & V4L2_STD_525_60) {
---
> v4l2_std_id std;
> __adv7180_status(state, NULL, &std);
> if (std & V4L2_STD_525_60) {
521a556
> mutex_unlock(&state->mutex);
777a813,815
> int err = mutex_lock_interruptible(&state->mutex);
> if (err)
> return err;
785d822
< fmt->height = state->curr_norm & V4L2_STD_525_60 ? 480 : 576;
786a824,827
> v4l2_std_id std;
> __adv7180_status(state, NULL, &std);
> fmt->height = std & V4L2_STD_525_60 ? 507 : 576;
>
789a831
> mutex_unlock(&state->mutex);
930a973,975
> int err = mutex_lock_interruptible(&state->mutex);
> if (err)
> return err;
932c977,979
< if (state->curr_norm & V4L2_STD_525_60) {
---
> v4l2_std_id std;
> __adv7180_status(state, NULL, &std);
> if (std & V4L2_STD_525_60) {
939a987,988
> mutex_unlock(&state->mutex);
>
1088,1090c1137,1141
< if (state->chip_info->flags & ADV7180_FLAG_I2P)
< adv7180_write(state, ADV7180_REG_VPP_SLAVE_ADDR,
< ADV7180_DEFAULT_VPP_I2C_ADDR << 1);
---
> adv7180_write(state, ADV7180_REG_VPP_SLAVE_ADDR,
> ADV7180_DEFAULT_VPP_I2C_ADDR << 1);
> adv7180_vpp_write(state, 0xa3, 0x00);
> adv7180_vpp_write(state, 0x5b, 0x00);
> adv7180_vpp_write(state, 0x55, 0x80);
1091a1143,1147
> adv7180_write(state, 0x15, 0x40);
> adv7180_write(state, 0x2c, 0x9e);
> adv7180_write(state, 0x2f, 0x30);
> adv7180_write(state, 0x51, 0x64);
>
1542c1598
< state->curr_norm = V4L2_STD_NTSC;
---
> state->curr_norm = V4L2_STD_UNKNOWN;


Best regards,
Dima

Edit Notes

removed video
[edited by: dtt at 7:44 AM (GMT -5) on 22 Feb 2026]
  • Hi ,

       We are currently working your query and will get back to you shortly. In the meantime, could you please provide the detailed system setup for our analysis?

    Thanks,
    Ebin

  • Hi,

    I'm using a PCB design based on https://github.com/rniwase/sdtv2csi/tree/master with composite CVBS input on AV1. The exact characteristics of the input signal is dependent on environment and is hard to measure with an oscilloscope... but I can experiment with different settings of the chip live. For instance I'm pretty sure that high voltage peaks occur in the signal as when peak white algorithm is enabled picture tends to darken significantly sometimes, with my logs showing AGC following peak white in such cases. Firmware setup is hopefully clear from my initial post

    Thanks for your reply,
    Dima

  • Hi,


    1. Verify that the correct XTAL frequency (28.6363 MHz) is being provided.Ensure that your script is selecting the 28.63636 MHz crystal setting.
    2. Adjust the comb filter settings; this may help reduce the noise issue.
    3. Try adjusting the color control register (Address: 0x08 [7:0]); this may improve the picture quality.
    4. Review the Digital Noise Reduction (DNR) settings (Address: 0x4D [5]).
    5. The ADV7180 includes 10 MHz anti-aliasing filters (AAF) (Address: 0xF3 [2:0]) that remove EMI above the CVBS video frequency band—please ensure these settings are correctly configured.
    6. Check all power rails for potential noise.
    7. Verify the analog input source to ensure no external noise is being introduced.
    8. The ADV7180 contains luma and chroma digital fine clamp blocks that restore the dc level of the AC-coupled input video.For a detailed understanding of the precision clamp process, please refer to the SD Luma Path, SD Chroma Path, and Clamp Operation sections.Cross-check your configuration with the reference script for the required I²C settings.
    9. The DVDDIO supply appears to be noisy and may be coupling noise into the 28.63636 MHz oscillator, resulting in unstable output.Consider separating the power supplies for DVDDIO and the ADV7180.Refer to the ADV7180 reference schematics available on the Design Support Forum. These schematics are included in the Eval_Board_Docs.zip files for each version of the ADV7180.

    Thanks,
    Ebin

  • 1. I don't think you can select 28.63636 MHz as a setting. The crystal I soldered onto the PCB has frequency 28.63636 MHz in the data sheet but I haven't checked it with osciloscope; 
    2 - 5 are not very relevant; in my setting picture sometimes being very noisy is normal and expected, it can't be solved, only dealt with. I'll try different settings to improve noise filtering later on but for now brightness is my main concern;

    In my setup I can switch in real time to a test video which is a grey screen with some white moving stripes, so it's clear that the same signal is being shown by the chip with different brightness in different times:



    And I do think the issue related to clamping: I tried disabling analog voltage sources by writing 0x00 into user sub map's address 0x14 at the point in time where brightness is good. And it does make things better, there are no longer videos that are almost completely black like in the original post but brightness is still not consistent, as can be seen on two pictures above. Any insight into the workings of clamping circuit, how can it be affected by noise in the power supply and how exactly can I measure it would be appreciated.

    Thanks,
    Dima

  • Hi Dima,

        Thanks for the information. Please refer the CLAMP CIRCUITRY and clamp operation control portion in the specification and enable the Digital clamp Freeze (DCFE) and let us know the status.

    Thanks,
    Ebin

  • Ebin,

    Thanks for your suggestion. Freezing digital clamp operation helped a lot, now luma is really stable as verified by the test picture, and video quality is much better. I'm confused as to the reasons why clamping was having such a negative impact, and why unclamped video works well. Should I try to clamp the signal externally, and if so, are there any PCB design suggestions for this?

    Dima

  • Hi Dima,

        Thank you for the response. As per the expert suggestion "We do not recommend using an external clamp circuit." Please refer the below path ADV7180 Design Support Files - Documents - Video - EngineerZone . for the design support file of the ADV7180.

    Thanks,
    Ebin