TV SIGNAL GENERATION -------------------- the 18f PIC microcontrollers top out at 10-12 MIPS, with a universal synchronous serial port that can run at the instruction cycle clock. this makes generating monochrome video, and also doing something useful in addition, quite possible. D/A CONVERSION -------------- Impedance. I found two different schematics. One which respects the 75 ohm impedance, and another which doesn't. The latter uses the input impedance of the TV set in a voltage divider. It is easy to see that for short cables, respecting the impedance is really not necessary. The standard pixel sampling rate for video is 13.5 MHz. This makes the 'wavelength' of a pixel about 22m. As long as cable length is way below this, reflections are not going to be a problem. For a typical length of 1-2 m, impedance matching is thus not required. The levels necessary are 0.0 (sync), 0.3 (black) and 1.0 (white). The followin circuit can generate 3 color levels (black, grey, white) + sync. R = 450 A 0---/\/\/\/\---\ | 2R = 900 | B 0---/\/\/\/\---| | 0 RCA signal pin 0 | I = 75 \------/\/\/\/\---\ | GND (from http://www.rickard.gunee.com/projects/video/pic/howto.php ) What i need is one pin to switch between white and black level, so this can be attached to the universal serial port output. Both pins on gives 5 * 75/350 = 1V, and only the pin connected to 2R gives about 0.3V, making the pin connected with R the serial output signalling pin. PIXEL LOOP ---------- Now for timing. Starting with a CPU frequency of 40MHz, the maximal pixel clock is 10MHz, which is about 75% of standard PAL/NTSC sampling. This translates to about 64 characters 8 bits wide. Using the universal serial port to shift out bits, it is possible to get to the maximum frequency if 7 cycles are enough to feed the TXREG. Since interrupt overhead is at least 5 instruction cycles, it is necessary to generate a scanline from instruction timing. The following sequence takes 6 cycles: MOVFF POSTINC2 TBLPTRL TLBRD*+ MOVFF TABLAT TXREG it reads a character from ram, and stores it in TBLPTR. assume TBLPTRH contains the current scanline in the character rom, which is organized as a sequence of 256 byte blocks which contain pixel row data for the character set. either this loop can be unrolled for each character (i.e. 64 times) and filled with some extra unrolled payload to use the 2 cycle slot (i.e. an audio synth algo), or the 3 instructions can be followed by a jump to the beginning, creating a code-efficient infinite blitter loop which can be broken by timer interrupts. the simple infinite loop might be the most interesting, since it allows for drawing line based bar graph graphics. HORIZONTAL TIMING ----------------- so, on to PAL timing. see http://lipas.uwasa.fi/~f76998/video/modes/ http://www.rickard.gunee.com/projects/video/pic/howto.php a scanline is 64us long. at 40MHz osc frequency, a single instruction cycle takes 0.1us, giving 640 cycles/scanline. it's possible to use the 8 bit timer with 4x scaler and period 32 for generating the line interrupt. a line looks like ___/\/\/\/\/\/\ |_| 4 8 52 to get the number of cycles, multiply by 10. taking overscan into account, the period after the sync pulse is longer, so practically, the signal looks like this: _____/\/\/\/\__ |_| H L B R this can be separated into 4 phases. let's call these Hsync, Left, Blit, Right. it's probably easiest to do the line setup in the Hsync phase. i'm wondering whether the sync pulse can be generated using the PWM logic. even more interesting is to use the serial port to generate the sync pulses too.. can this be done using the wiring above? for example, using 44us active region takes away 4us on each side giving _____/\/\/\/\__ |_| 4 12 44 4 1 3 11 1 1 2 1 11 1 the 1/3 sequence could be generated as a serial byte, also the 1/1/2 sequence, leaving 4us to set up the line blitter loop. VERTICAL TIMING --------------- http://www.simtec.co.uk/appnotes/AN0013/ one frame. the idea is to generate non-interlaced pal: 312 lines at 50Hz, giving 15600 lines/sec. vertical sync doesn't seem to be so hard: 6 half lines eq, 5 half lines sync, 5 half lines eq. PIN ALLOCATION -------------- regarding the 2 output pins as a simple 2 bit D/A, we get 00 0.00 01 0.33 10 0.66 11 1.00 switching between 0.33 (black) and 1.00 (white) for the image data requires the serial out to be the most significant bit. in the 18f1220, this is pin RC7/RX/DT/SDO. since this line is also async serial RX, care needs to be taken. probably a 10k resistor will solve the problem. so we get 10k V1/RX/DT >------/\/\/\/\-------< host TX | | 470 |---/\/\/\/\----\ | 1k | V0 >------/\/\/\/\-------> video setting TRIS bit for RC7/TX/CK should disable the clock output. (???) int the 19f2550, a streaming parallel port could be used, so i'm going to leave that one out for now. in the 18f252, the SDO and async RX/TX lines are different, so it might be possible to use the MSSP/SPI module. indeed, writing to SSPBUF every 8 cycles should do exactly what we want. the other pin i'm connecting to RA5, so it can still be used as analog in. this seems to work. first experiments show that hsync jitter is bad, so best to run this from an interrupt. SEQUENCING ---------- - scanlines from interrupt at 15kHz. - vsync also from interrupt, maybe at double line rate? - blanking: just need to give 4us sync pulse during blanking and part of scanlines, the rest of the code can run. the slack after hsync pulse could be used to poll the serial port too for instance. other things that need to happen per scanline are: - increment line counter - set FSR2 to the correct line in text ram - set TBLPTRH to the correct font line CONCLUSION ---------- seems to work really well, except for the don't care bits in the SPI output, so probably a different approach is needed there. keeping the right edge of a character blank does seems to fix most problems.