The original concept for the new version of the closed-caption decoder was that everything would be interrupt-driven, and that there would be four interrupt sources:
- vertical sync from sync separator — would initialized timer 1 to count down horizontal lines
- timer 1 — would count horizontal lines and interrupt at the start of line 21. handler would capture the actual caption data
- uart receive
- uart transmit
However, I’d forgotten that the software has to drive an output low during the back porch of the video signal for the DC restore function. It doesn’t necessarily have to do this on every back porch, but it does have to do it on at least a handful of lines (perhaps six or so) leading up to line 21.
This means that there needs to be an interrupt on every horizontal sync pulse. The sync separator chip (Intersil EL4581) provides composite sync and vertical sync outputs but not a horizontal sync output. There is an EL4583 that does provide a horizontal sync output, and it is second-sourced by Zetex, but it’s probably more expensive.
On the older National Semiconductor LM1881 sync separator (for which the EL4581 is an improved-spec replacment), the burst output is open-collector and can be used for DC restore. But unfortunately one of the improvements in the EL4581 is that the burst output is push-pull, so it can’t be used for DC restore without also adding a schottky diode.
Anyhow, if I use composite sync for the interrupt, the software can do DC restore on every line, increment a line counter, and reset the line counter if vsync is active. Then it can do the sampling on line 21. Timer 1 won’t be used to count the lines after all.
Because the DC restore timing is fairly cricital, it isn’t acceptable for a UART interrupt to delay the composite sync interrupt. Therefore I’ve decided not to use UART interrupts at all, but rather to have the composite sync interrupt handler poll the UART (both receive and transmit) after it’s done with everything else (except on line 21). This means that the UART will usually be polled at a minimum interval of 127 us. So the maximum async serial data rate (8N1) is 78740 bps. I only need it to run at 19200 bps, so that’s fine.
The DC restore code just has to be careful to NOT drive the output low after a csync pulse during vertical sync, because there is no back porch and we don’t want to DC restore to the sync tip. This is easily handled by having the code sample the csync and not restoring if cysnc hasn’t gone high.
This does leave one other problem. Since the serial port doesn’t generate interrupts, if the video signal goes away, there won’t be any composite sync interrupts, so the serial port won’t get polled. This can be solved by using timer 1 to provide a timeout interrupt if the csync interrupt doesn’t happen often enough. The csync interrupt handler will reset timer 1.
Although things aren’t working out quite the way I originally envisioned, the code will still be much cleaner than the last two major versions.
(By the way, the reason any of this is relevant is that the caption decoder design, both hardware and software, is freely available (software is GPL’d). The new version under development isn’t yet ready for release, but probably will be within a week.