/* 
   Vertical Bars Pattern PAL TV Signal Generator with Arduino 
   Use this code as you want
   2007 Javier Valcarce Garcia, <javier.valcarce@gmail.com>
*/


#include <avr/io.h>
#include <util/delay.h>

/////////////////////////////////////////////////////////////////////////////////////////////////
// Pins where the 2-bit DAC is connected

#define PINA0 6 // LSB, 1 kOhm resistor
#define PINA1 7 // MSB, 330 Ohm resistor

// PINA1 PINA0 OUTPUT 
// 0     0     0.0V   - Sync level
// 0     1     0.3V   - Black level
// 1     0     0.6V   - Gray level
// 1     1     1.0V   - White level

#define LEVEL_SYNC   PORTD &= ~(1 << PINA1); PORTD &= ~(1 << PINA0);
#define LEVEL_BLACK  PORTD &= ~(1 << PINA1); PORTD |=   1 << PINA0; 
#define LEVEL_GRAY   PORTD |=   1 << PINA1;  PORTD &= ~(1 << PINA0);
#define LEVEL_WHITE  PORTD |=   1 << PINA1;  PORTD |=   1 << PINA0;
/////////////////////////////////////////////////////////////////////////////////////////////////


/////////////////////////////////////////////////////////////////////////////////////////////////
inline void vsync_pulse()
{
      LEVEL_SYNC; 
      _delay_us(30); 
      LEVEL_BLACK; 
      _delay_us(2); 
}

/////////////////////////////////////////////////////////////////////////////////////////////////
inline void equal_pulse()
{
      LEVEL_SYNC; 
      _delay_us(2); 
      LEVEL_BLACK; 
      _delay_us(30);
}
/////////////////////////////////////////////////////////////////////////////////////////////////
inline void hsync_pulse()
{
      LEVEL_SYNC; 
      _delay_us(5); //4.7us
      LEVEL_BLACK; 
      _delay_us(7); //7.3us
}

/////////////////////////////////////////////////////////////////////////////////////////////////
int main()
{
      register unsigned int line;
	
      /* NOTE THAT THE SIGNAL GENERATED BY THIS PROGRAM HAS A NOT VERY ACURATE TIMMING SO 
	 IT IS POSIBLE THAT THE IMAGE BLINKS ON YOUR TV SCREEN OR DOESN'T SHOW AT ALL, 
	 THIS PROGRAM WRITTEN IN C (INTEAD OF ASSEMBLER) IS ONLY A PROFF OF CONCEPT */
	
      line = 0;
      DDRD = 0xFF; // PORTD, all pins are outputs

      while(1)
      {
	    
	    if (line == 626) 
	    {
		  line = 1;
	    }
	    else
	    {
		  line++;
	    }
		

	    switch(line)
	    {
	    case 1:
	    case 2:
	    case 314:
	    case 315:
		  vsync_pulse();
		  vsync_pulse();
		  break;
		  
	    case 3:
		  vsync_pulse();
		  equal_pulse();
		  break;
		  
	    case 4:
	    case 5:
	    case 311:
	    case 312:
	    case 316:
	    case 317:
	    case 623:
	    case 624:
	    case 625:  
		  equal_pulse();
		  equal_pulse();
		  break;
		  
	    case 313:
		  equal_pulse();
		  vsync_pulse();
		  break;
	    default:
		  // Image scanline (not a sync line)

		  hsync_pulse(); // Horizontal Sync, lenght = 12us   		  
		  
		  LEVEL_GRAY;   
		  _delay_us(8);
		  LEVEL_BLACK;
		  _delay_us(14);
		  LEVEL_WHITE;
		  _delay_us(8);
		  LEVEL_BLACK;
		  _delay_us(14);
		  LEVEL_GRAY;
		  _delay_us(8);
		  //52us in total
	    }
      }
}

