Update: new approach by André using DDS, see below.
This will be a record of my attempts to develop a colour graphical OSD for radio-controlled aircraft. An OSD system is a device which overlays flight information onto the video feed used by the pilot of an RC aircraft, so that they are able to see their altitude, airspeed, GPS co-ordinates, remaining battery power or fuel, or direction back home.
There are a number of OSD systems available. Many of these are based on the Minim OSD board. This was originally designed by 3D Robotics but released as an open hardware project so there are many variations available and it is inexpensive. However it is entirely text based. The MAX7456 chip at the heart of it was intended to display black and white text over security camera feeds.
Minim OSD board
MinimOSD output using custom firmware (MWOSD)
There have been projects to create true graphical OSD systems, such as AlceOSD. It is relatively straightforward to superimpose a black and white or greyscale image over a video feed using a modern microprocessor, doing the same with a colour image is much more challenging. The only widely available OSD capable of doing this is the EagleTree Vector. It is a closed-source commercial product. Edit: MyFlyDream Crosshair autopilot, another closed-source product, also features a colour OSD.
AlceOSD – grayscale graphics
PlayUAV – black and white, with graphics. Camera feed is not shown here.
Eagletree Vector OSD – full colour, true graphics
MyFlyDream Crosshair – full colour, true graphics
I am aiming to create something of comparable performance, for the FPV community, which will be fully open that anybody can build on or customize. At present I have two working solutions, one using the ADV7184 and ADV7341 digital encoder and decoder connected back to back, and one using the AD724 locked to an external subcarrier (Yes, Analog Devices are the last best maker of the buggy whip that is analog video technology). Neither solution is entirely satisfactory to me; the first uses too much current and the second too many components. So the search goes on. Please keep reading below to follow my progress, and if you have any ideas feel free to share them!
Artificial horizon, airspeed and altitude indicators
This is another guest post by André, after revising and improving his (to my knowledge) completely new and untried DDS technique, he is achieving splendid results.
Hi Batperson and fellow DIY’ers.
I have focused on two major areas in my efforts to improve the colour osd prototype.
Fixing the chroma inconsistency
The first task was to deal with the perceived chroma inconsistency, which manifests as colour variations rolling vertically up or down. After much back and forth with some ideas and coding, I found that a partial answer was lying just in front of me. However the issue still needs to be tackled on more than one front to be fully resolved. I realized that there were two major contributors:
MCU comparator timing variations
DDS square wave output.
The trigger point of the comparator varies due to factors such as power supply noise or video signal voltage variations, and this inconsistency of the comparator is responsible for some colour variation. However the DSPIC on the prototype has a comparator filter, which when enabled gives a more consistent trigger point at the expense of a reduced sampling rate. After much fiddling with parameters I settled on a 1:5 prescaler, as the comparator is sampled at 400Mhz, the filter samples at 80Mhz, and it takes 3 consecutive positive samples to produce a change in the comparator output. So in reality the filter has a sampling output of 26.666Mhz (curiously, or not, this frequency is suspiciously close to the 27Mhz sampling rate of modern video decoders). Even after many sessions adjusting the filter sampling rate the issue never disappeared and I only obtained small improvements. However, that lead me to another solution, this time more accidental.
The first time I tried to connect the DDS output to the voltage created by the mcu pin, the DDS was outputting its frequency signal as a sine wave. Unfortunately it didn’t have any effect, and I was convinced that the DDS DAC output was too weak to make any change to the voltage already set by the port pin 330Ω resistor to the 75Ω input load voltage divider as seen in my previous post.
The DDS DAC only outputs a maximum of around 0.680V for sine or triangular waves, depending on frequency. Because of that I changed to square wave output which is a 0V – 3.3V signal and in my excitement at finally getting a colour overlay I never looked back at this fact.
As I could not fix the Chroma inconsistency issue, I reflected on the causes of the abrupt variations of color, and I thought for a while that the quadrature decoder inside the video receiver (monitor or video digitizer) would not like to receive square waves, but that idea was not convicing me, as I tried to improve the chroma detection and the DDS resetting routine.
One day out of tiredness and hopelessness, I reverted the DDS to triangle wave output, and the improvement was better than I imagined.
Keep in mind two things: the video digitizer I used has a resolution of only 640×480 but the overall resolution looks even lower, and the DDS output is too weak to make a true 1V p-p sinewave so the digitizer’s automatic gain control boosts the signal making the image appear brighter. I will amplify the signal to proper levels later on.
This solution also made me modify the connection between the DDS output and the resistor divider output:
The 100pf capacitor is a simple AC coupling capacitor, nothing fancy.
Also there are signs of impedance mismatch as the overlay is switched on and off from the video signal, visible at the start of the overlay as a brightness change, and also at the end of the overlay as well if you look closely. As an interim solution I added a 75Ω resistor connected via a diode to the pixel signal pin, so that when the overlay is switched off the port pin that controls the switch is terminating the signal, when it is on the diode prevents the pin’s 3.3V from entering the video signal path and making all the overlay white, and potentially damaging the receiver input stage or camera output stage.
After I acquired a better video digitizer and changing the DDS to sine wave output the image became even better, IMHO.
As previously mentioned, brightness and color saturation were increased in the PC software due to the weak DDS DAC output. I intend to address this later.
The artifacts at the numbers are caused by the way the digitizer deals with interlacing, these numbers vary at double the frame rate of NTSC (I just now realized this so I will correct it ASAP). Curiously the old digitizer dealt better with interlaced signals, maybe the crappy resolution masked this.
The vertical color rolling effect is barely perceptible now, and the quality o the overlay is vastly improved.
So I conclude that if you are trying to make a color OSD, you want to generate your overlay using sine or triangle wave signals, as the abrupt transitions of a square wave lead to colour inconsistencies. This happens because square waves are composed of various odd frequencies besides the fundamental frequency and this will certainly end up confusing the receiver converter.
Improving the firmware
The second area I wished to improve was the synchronization with the incoming video as I needed a stable overlay to continue the improvement of the OSD code without constant overlay dropouts.
This took up the vast majority of the coding efforts of the past weeks, and even if it is not fully fixed it has improved by leaps and bounds.
The problem would manifest itself as a complete disappearance of the overlay in case of sharp brightness variations from one scanline to another. One of the reasons of this issue is the attempt by me to let go of the “more silicon syndrome” by avoiding the use of popular sync stripper chips such as the famous LM1881. However replacing a venerable chip like the LM1881 proved to be a gargantuan task, as it is an old but still effective chip, with lots of modern descendants.
The prototype uses an internal MCU comparator to achieve many of the tasks of a sync stripper, adjusting an internal DAC connected to the comparator. From the comparator signal a routine was created to firstly increase the DAC voltage until the sync signals are detected, and then to adjust the DAC signal until it is just slightly below sync level (the voltage just below Black level) and then hold this voltage.
The structure of interrupts of the code were as as seen in the next figure.
One disavantage of the “Comparator does all” approach, is that the composite video signal is a complex signal, having slow wave forms like the sync tip, and fast modulated signals, like the chroma and luma, and also variations of the image brightness will introduce variations on the sync level voltage, even with a clamping circuit. These variations are called APL, average picture level. This factor led me to introduce a “dynamic DAC voltage detection”. Simply put the MCU would use an ADC to read the sync tip voltage at interrupt 1.
The current DSPIC used in this prototype has a very useful ADC peripheral that besides being a 3.5Msps ADC, also has an oversampling or averaging filter.
Oversampling is not useful as the ADC resolution is a generous 12 bits, and it coincides with the 12 bits of the comparator DAC. Instead the ADC filter was used at 8X averaging. In this mode, the ADC when requested will automatically take 8 measurements and average them before presenting the value in a register. Using that value, the program extrapolates the sync level voltage, and ideally keeps it from going over the sync level threshold.
The solution proved to be insufficient. If the next line had a big brightness change like the sun appearing at full brightness, especially at the right edge of the image, right before the next sync tip, the APL would change up and interrupt 2 would be lost, and because it missed the 4 chroma burst raising edges, the interrupt would never fire. Consequently the overlay would disappear because this interrupt decides whether the line is a scanline or vertical sync line.
An interrupt rearrangement needed to be devised to give sufficient time, meaning more cycles, to implement the DAC dynamic adjustment before the chroma burst, as seen in the next image.
For this, interrupt 1 was modified to wait for the ADC filter result, decide if the sync tip was a new Scanline or a Vertical sync line and raise the DAC voltage for the chroma detection. And interrupt 2 was changed from CCP reading 4 raising edges (it has to be under 8 ideally), to a DMA interrupt that takes 6 or 7 (still deciding on this) chroma rising edges from the same CCP, giving more time between these two interrupts. It then resets the DDS, and lowers the DAC voltage to the previous sync detection level to avoid any scanline glitches causing an interrupt to fire in error.
Even at 8X averaging the ADC voltage readings would oscillate plus or minus 2 lsb’s, so to improve that, and also deal with extraneous noise induced by the MCU or video signal, a median filter was applied afterwards in the line rendering interrupt (call it phase 3) to filter out noise outliers and implemented before the next sync detection.
A median filter has the advantage of filtering out large measuring spikes by sorting a list of past values and then taking the value at the middle of the list. The list size is currently 23 values.
The interrupt structure change decouples line detection from the chroma burst detection, meaning that in case the chroma burst is missing, such as with a black and white composite video image, the overlay will still be rendered, although with unsynchronized colours.
The results can be seen at these videos. The brightness of the video changes dramatically, but the MCU remains locked to the incoming video sync.
Note: these videos were made with different cameras, which shows another benefit of the dynamic DAC ajustment: better camera compatibility.
Next up will be a general code cleanup, increasing the amplitude of the DDS-generated chroma, implementing a luma DAC using resistors, and finally a long-promised full schematic. There are still issues with the overlay ocasionally disappearing, but this only occurs now under extreme conditions.
Thanks to my wife, family and friends, including the nice host of this blog, Batperson, for letting me publish my efforts and ramblings.
This is a guest post by André who has come up with a novel approach using Direct Digital Synthesis of the chroma signal. The circuit is relatively simple and uses few components. It’s early days, but he’s already achieved promising results. Take a look at how he does it!
This is a report of my attempt at creating a simple, low component overlay system with colour, for use in remote controlled vehicles, in an attempt to change the current go to hardware for doing video overlay, namely the character only monochrome Max OSD chip.
After much research and discussion with fellow Batperson from the WekaOSD blog I set out to devise a solution for colour overlay that uses the smallest number of components possible.
In the first part of the project I set out to create a monochrome OSD using the DSPIC33CK, as it is the MCU that I’m most comfortable with, despite the buggy IDE, because of the sheer number of peripherals it has: comparators with DAC references, timers, capture and compare modules, ADC@3.5MSPS. That way I could integrate as many analog blocks as possible, avoiding noise issues and lowering part count. It is also a 100MIPS MCU, the majority of the instructions are single cycle, and interrupt latency is fixed if you obey some restrictions.
For sync detection I used an internal comparator fed by the video signal, where the reference voltage was controlled by the comparator dedicated DAC, to separate any unwanted signals the comparator input would present on the video feed. I used a solution inspired by the schematic of Dennis Frie’s DIY OSD. The diode is a standard 1N4148.
For rendering I chose an analog switch, namely the SN74LVC1G3157 SOT-23 (SPDT) single channel with typical frequency of 340 MHz, connected in such a way that in case of MCU malfunction the video feed would pass on via the normally closed input. Rendering is made by an MCU pin on the normally open input. This input receives 3.3 volts via a 330 ohms resistor to create a signal above 0.3v which gave me a nice dark grey overlay. (Voltage divider with the 75 ohm termination resistor inside a monitor).
Then came the daunting task of generating colour, and here I made some bold assumptions. Simply put, my idea was to generate a 3.579545 MHz waveform using a frequency generator, and try to synchronize this to the detected chroma burst in an interrupt. In this way I would have a chroma signal in sync with the video feed, circumventing the need for phase-frequency lock using obsolete parts or a multiple chip solution. So I set out to find a frequency generator chip that was both small and required only clock input from the MCU and some type of control SPI or I2C.
After some search on the web I decided to use a DDS chip, and following the constraints I imposed I settled on the AD9833 chip in TSSOP 10 pin format. To simplify prototyping I opted to buy a PCB module of the AD9833 and simply removed the 25Mhz crystal and fed it with a frequency generated by the MCU, so the DDS was configured to output the Chroma frequency, in square wave format to get the benefits of the 0 – 3.3v amplitude of the DDS output.
One particularity of this chip is that the best phase noise is achieved with a frequency output that is a whole divisor of the input clock, as in the first images I got the phase inconsistency was visible.
The solution was an undocumented register of the DSPIC – REFOTRIML, that allowed me to trim the frequency to about 7 times the chroma frequency, 25.056818Mhz. That solved the phase inconsistencies by using a multiple of the input clock of the DDS. That is also a slight overclock of the DDS (max 25Mhz).
The next step required me to mix the dark grey luma signal created by the resistor divider with the generated clock signal, so I used the technique often found on resistor DACs, feeding the clock output via another resistor, effectively creating a crude DAC.
In my code I opted to synchronize with the incoming video signal in 3 phases:
first phase was to detect the video sync tip falling edge. That is accomplished with the comparator interrupt. This would provide a reference for the start of the overlay signal, by enabling a timer interrupt that would fire in the visible part of the scanline, and at the same time the code enables an input compare interrupt to detect the chroma burst cycles.
Second phase, the input compare interrupt fires on 4 rising edges. The first of these is the sync rising edge and the next 3 are the rising edges of the chroma burst. Right at the start of the interrupt the code resets and restarts the DDS at a defined phase, ideally one that would correct any frequency drift due to mismatched frequencies between the video effective chroma frequency and the local generated frequency in each scanline. Next, by reading the first buffered rising edge (the rising edge of sync tip) it will determine if the signal is a scanline, short sync or long sync, and keep track of the current scanline number. Each of the options performs different actions. If it is in a scanline it hands off to the rendering interrupt, otherwise it resets the line counter and disables the render timer and render interrupt.
Third phase, the rendering timer interrupt, basically renders according to the line number. To transition to the different colours in the colour bars, it pauses the clock feeding the DDS for 10ns (ideally; in actuality it takes more like 20ns). That equates to 14 shades of colour, theoretically it should be 28. At the end of this phase before returning from the interrupt, the timer and timer interrupt are disabled, and the comparator interrupt is re-enabled.
At present I still think it is still a complicated scheme of interrupts that needs further simplification. However although the results leave room for improvement, they are very encouraging.
Each column represents a 10ns delay in code, but in reality enabling and disabling the clock input of the DDS takes 2 cycles as it is visible that the colour cycles in approximately 14 cycles (each chroma cycle takes ~28 cycles) and there are contiguous columns that are the same colour despite the phase shift. As can be seen, there is phase shift vertically in each column, in the form of a colour shift rolling up along the columns.
Further investigation on jitter leads me to suspect the random nature of the colour shifts, but further investigation will be carried out, I have not scoped the signal completely. In the next figure, for each column the DDS input clock was stopped and a line rendered, depending on whether the output DDS clock was on a high level (white) or a low level (black). In theory the columns should alternate between white and black, and the lines should also alternate regularly between white and black due to the 180 degree phase shift between lines (in NTSC, each line should contain exactly 227.5 chroma subcarrier cycles). However as can be seen this is not the case. I think that because of the software-only line rendering routine some jitter may come from IF…THEN, and other C code instructions. Even utilizing some ASM did not mitigate the jitter.
In the next weeks or months, if time permits I will restructure the code and try to solve other issues, and attempt to minimize the rendering interrupt jitter using DMA instead of bit-banging. I still haven’t ruled out EMI on the comparator input as a source of jitter, but the comparator has a Software Hysteresis setting of none, 15, 30 or 45 mV and a digital filter with prescaler. Adjusting both did not improve the jitter.
Some solutions I thought about is putting an XOR gate on the DDS input frequency line to do proper 10ns delays, and supporting greyscale by putting another XOR gate between the DDS and the resistor DAC. Another thought is to clock the MCU at 3x27Mhz, as modern video monitors sample the video signal at 27Mhz.
Final thoughts: The current approach of generating colour shifts by delaying the DDS input clock 10ns (in practice 20ns) is feasible as a proof of concept but it would require code to keep track of the delays if arbitrary colours are to be generated. However I want a complete rendering interrupt that will simply fire the DMA or DMA’s and return to main, so that other tasks can be performed at the same time like reading a UART and creating a rendering buffer, perhaps a double buffer.
Thanks to Batperson for the ideas shared, that gave me inspiration to create this prototype.
Thanks for Sónia for all the support and putting up with my nerdism.
Thanks to my family for everything.
Here is the schematic for the colour overlay prototype I have been breadboarding. The next logical step would be to design a proper circuit board. However I’m not happy with it for a number of reasons:
Too many ICs, too complex
Not able to support both video standards at the same time (need to select either a PAL or NTSC crystal)
Doesn’t work reliably with PAL, in any case because the PAL colourburst changes phase on each line and it is a 50/50 chance that the AD724 will change phase in the opposite direction to the incoming signal
The MC44144 is an obsolete part
I want to explore other alternatives. I have a few ideas. However for the time being I’m taking a break from analog video. My son needs an alarm clock so I’m going to build him one!
I clocked an SN74HC174 hex flip flop with the 4FSC clock signal, connected the flip flops in series with each other, and connected the pixel switch to the first input. Using the 5th flip flop output gives a delayed switch signal which is neither early nor late. So there is no more black band before or after the overlay.
Although some haloing left and right of the white bands is still present, I don’t think this is caused by the switch. The image is quite noisy, you can see a noise artefact in the magenta band. Some of the connections on the breadboard are a bit loose and the circuit is quite finnicky. I have to fiddle with it for several minutes to produce an output.
I now have a working OSD prototype, which works for NTSC only. I still haven’t come up with a method that supports both NTSC and PAL. Also, the circuit is quite complex: 7 ICs and supporting passive components.
The current draw is 143mA at 5V, which includes the STM32 discovery board with its on-board debugger, a much more economical usage of power than my previous attempt which drew 550mA.
I noticed a few things. Although the last 2 white bands are 2 pixels and 1 pixel wide, the 2-pixel band looks about 3 times as wide as the 1-pixel band. Also, colours don’t really show up in less than 2 pixels. I tried rendering the white bands in various colours, and the 1-pixel band was still mostly white. This seems to be a limitation of the AD724, as previously when using digital video ASICs I was still able to render single pixels in colour.
Currently I’m waiting on parts, so there is not much for me to do project-wise at the moment. In the meantime I’ve fixed the errors on the video timing board. The MC44144 and LM1881 are separately AC-coupled to the CVBS input, and I’ve removed the clamp circuit. I also replaced the too-small 1.27mm pinheaders with normal-sized 0.254mm DuPont headers.
There is a delay of several hundred nanoseconds (I estimate 250-300, it is probably a multiple of the 4FSC period) between the RGB inputs and the output of the AD724. But the pixel switch activates almost immediately, before the overlay pixels are rendered. This is visible as a black bar to the left of the patterns below. The left pattern should be white-black stripes, and the right pattern should be white stripes only.
I tried to eliminate this by putting an RC delay in front of the pixel switch. It does delay the switch, but the result is disappointing.
The worst problem is that the switch can’t toggle faster than the delay, which means overlays 1 or 2 pixels wide don’t even appear. I’m not sure what is causing the blue halo, it could be because the envelope for the switch signal is no longer a sharp square edge. Compare these 2 scope traces:
Switch signal, no delay and sharp edges
Switch signal, with RC delay
Note the sloping attack and decay. The last 2 peaks didn’t reach the threshold to activate the switch.
I need to find a way to delay the rise and fall of the switch signal equally, while preserving the sharp edges, even when the switch toggle time for 1 pixel (162ns) is less than the delay (250+ns).
Use one or more flip flops, clocked from the MC44144.
To which I added an idea of my own:
Delay the signal in the microcontroller. This could be done by setting up a second DMA transfer to a different GPIO port. Of that, only enable 1 pin which will be the switch. Drive the DMA from a timer with the same period as the pixel clock, but started an arbitrary number of ticks later.
Of these, I like 2 and 3 for simplicity. 3 has the advantage that the switching will be in the same clock domain as the pixels. This may turn out to be important, otherwise the switching may still be in and out of sync with the overlay image.
My own idea would be a great one (if I do say so myself), if not for the fact that I will now have 2 DMA transfers contending with the CPU for the bus. From my reading, there are is an issue with the DMA2 controller on the STM32F4 series when concurrently accessing peripherals. So adding an extra stream willy nilly is something to be avoided. The finished product will need at least 1 other DMA transfer (to receive data from a UART), or most likely more if I end up integrating it with a flight controller.
I think I will try the flip-flop approach, and it will be an added incentive to clock the microcontroller from the pixel clock, if this is possible on a Discovery board. I will also experiment with 2 DMA transfers.
Edit: André in Portugal has suggested another way: use a comparator to monitor the overlay video output. If it rises above black level, the comparator activates the switch. Thanks André! This would be a bit like the “blue screen” chroma keying used to show the weatherman in front of a computer-generated weather map back in the old days, except this would be luma keying. It would free up an extra bit (along with the other spare bit I’m not currently using) allowing for more colours. But it would mean sacrificing the ability to draw black in the overlay. Everything is a tradeoff…..
Over the weekend, I tracked down the problem with poor saturation. This was due to an incorrect connection to ground in my clamp circuit. After doing this I had the opposite problem: the strong overlay signal was causing the monitor’s AGC to dim the rest of the picture. I compensated for this by increasing the series resistance after the AD724 from 75 ohms to 150 ohms. This didn’t alter the brightness of the overlay but the source video is now less dim.
I also used an RC circuit to shift the phase of the subcarrier clock, in an attempt to correct the colours. I experimented with different capacitor values and discovered that 1nF and above caused the clock to disappear completely. 20pF caused a barely perceptible shift in colour, but a 10K resistor with a 470pF capacitor gave correct red, green and blue colour bars. Subjectively they appear exactly as they should, however I will experiment further to see if there is any more scope for improvement. The colours now appear solid where before there was banding, I’m not sure why this has disappeared unless it was clock jitter that the RC network somehow mitigated.
Here is the result.
RGB overlay – no fake, and full sats
Overlay trace. Note the switching artefact.
I have to say it’s looking a lot better than last week. The only issue still remaining is a switch artefact. Notice that there is a black vertical line before the red bar appears. This shows on the scope as a small bright spot just above sync level. Since there is no artefact when switching from overlay back to source video, I suspect it is the switch responding more quickly than the AD724, switching in a blank image before the colour signal has been generated. If so, I should be able to mitigate it by introducing a delay to the switch.
In fact the real image looks worse. The colours look more saturated in the photo than they do in real life.
Sync tip, colour burst, active video, overlay. The horizontal trace looks thick due to noise.
My test setup.
It’s a colour test pattern overlay, but there are a bunch of issues:
The colours are wrong. I had to change the order of the red, green and blue inputs to get even this result, because the phase delay from the MC44144 is 60 degrees. The colours are also poorly saturated, and look worse in real life than in the picture.
The image flickers, due to noise. This is most likely due to the use of a breadboard.
The source video appears washed out. I believe this may be partly the result of clamping which seems to compress the waveform by 200mV.
On the positive side, I did solve some problems:
I’m using an SN74LVC2G53 analog switch. This one is unbuffered. Since both the AD724 and the camera are both outputting at full-drive 2V p/p, there should be no need for buffering. The switch is very fast (<10ns) and seems to be performing as advertised.
Originally the 2 video signals were mismatched by around 200mV. This was enough to cause an unstable picture, as the overlay signal dropped below sync level. Worse, it even appeared to contaminate the source video in the LM1881, causing it to lose sync.
In order to continue with this approach, I will need to solve the subcarrier phase problem, and also find out why the colours look so terrible.
Another problem that has been bugging me is that the MC44144 often starts up without generating a subcarrier. It seems worse when using the USB power supply which is very noisy, although the filter on the board reduces it to < 5mV p/p. Both the chip and the crystal came from AliExpress, could it be a quality issue?
After resolving some DMA issues I now have a working testbed running on the STM32F413 mcu. It is using the signals from the timing board to drive an AD724. It is generating a good test pattern but connections are very finicky, since I have the AD724 on a breadboard. Noise is visible and jiggling the wires is sometimes necessary to get it to work. But it will do for the time being.
Rainbow test pattern, genlocked to incoming video
Scope trace. Horizontal sync is the short low pulse and the colourburst is the short sinewave following that.
In theory the output from this should be in phase with the video from my Runcam. To see if that is the case or not I need to have a working pixel switch. When I attempted to use the MAX4313 I didn’t see a picture, and when i checked the output with the scope I saw that the sync tips are being clipped off. It is attenuating the waveform when it drops below 0 volts. I will try clamping the sync tips to 1 volt to see whether it will pass the entire waveform through.
I would like WekaOSD have the capability to continue generating video if the signal from the camera is lost or a camera is not connected. For this, I will need to detect when
loss of sync occurs and have the MCU generate sync signals.
I have worked out a way I can do this. The sync input on the AD724 is driven by the CSYNC output of the LM1881. At the same time, CSYNC is connected to a pin on the MCU. During normal operation the MCU pin is configured as an input so the MCU can derive horizontal timing. If LOS occurs or there is no camera, the pin can be configured as an output. Since the LM1881 sync output appears to be open-drain, either the LM1881 or the MCU can pull the line low to generate a sync pulse. This means the MCU can easily generate its own sync signals with no risk of 2 pins driving the line at the same time.
I can detect LOS by monitoring the Burst Gate output from the LM1881 using a second MCU pin. When there is incoming video there will be a short pulse every 64 uS. If those pulses stop then there is no video, and the MCU can switch to generating sync pulses.
If I make the pixel switch pin open-drain with a pullup resistor, then when loss of sync occurs I can put the pin into input mode. This will have the effect of turning the pixel switch signal continuously on, regardless of the value for the current pixel.