// arbitrary waveform generator
#define F_CPU 10E6
#include <avr/io.h>
#include <avr/interrupt.h>
#define outp(a, b) b = a
volatile int waveform = 1;
volatile int step = 0;
// sine
int si[] = 
{
128,131,134,137,141,144,147,150,153,156,159,162,165,168,171,174,
177,180,183,186,189,191,194,197,199,202,205,207,209,212,214,217,
219,221,223,225,227,229,231,233,235,236,238,240,241,243,244,245,
246,247,248,249,250,251,252,253,253,254,254,255,255,255,255,255,
255,255,255,255,255,254,254,254,253,253,252,251,250,249,248,247,
246,245,243,242,240,239,237,236,234,232,230,228,226,224,222,220,
218,215,213,211,208,206,203,201,198,195,193,190,187,184,181,179,
176,173,170,167,164,161,158,155,152,148,145,142,139,136,133,130,
126,123,120,117,114,111,108,104,101,98,95,92,89,86,83,80,
77,75,72,69,66,63,61,58,55,53,50,48,45,43,41,38,
36,34,32,30,28,26,24,22,20,19,17,16,14,13,11,10,
9,8,7,6,5,4,3,3,2,2,1,1,0,0,0,0,
0,0,0,1,1,1,2,2,3,4,4,5,6,7,8,10,
11,12,13,15,16,18,20,21,23,25,27,29,31,33,35,37,
39,42,44,47,49,51,54,57,59,62,65,67,70,73,76,79,
82,85,88,91,94,97,101,103,106,109,112,115,119,122,125
};
// triangle
int tr[]=
{
0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,
32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62,
64,66,68,70,72,74,76,78,80,82,84,86,88,90,92,94,
96,98,100,102,104,106,108,110,112,114,116,118,120,122,124,126,
128,130,132,134,136,138,140,142,144,146,148,150,152,154,156,158,
160,162,164,166,168,170,172,174,176,178,180,182,184,186,188,190,
192,194,196,198,200,202,204,206,208,210,212,214,216,218,220,222,
224,226,228,230,232,234,236,238,240,242,244,246,248,250,252,254,
255,254,252,250,248,246,244,242,240,238,236,234,232,230,228,226,
224,222,220,218,216,214,212,210,208,206,204,202,200,198,196,194,
192,190,188,186,184,182,180,178,176,174,172,170,168,166,164,162,
160,158,156,154,152,150,148,146,144,142,140,138,136,134,132,130,
128,126,124,122,120,118,116,114,112,110,108,106,104,102,100,98,
96,94,92,90,88,86,84,82,80,78,76,74,72,70,68,66,
64,62,60,58,56,54,52,50,48,46,44,42,40,38,36,34,
32,30,28,26,24,22,20,18,16,14,12,10,8,6,4,2
};
// sawtooth
int sa[]=
{
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,
26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,
70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,89,90,
91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,
110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,
127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,
146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,
165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,
184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,
203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,
222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,
241,242,243,244,245,246,247,248,249,250,251,252,253,254
};




	

//Interrupt Service Routines for the waveform select button (INT0_vect)
ISR(INT0_vect)
{
    cli();
    waveform=waveform+1;
	if (waveform>5)
	{waveform=1;}
    sei();
}

ISR(INT1_vect)
{
    cli();	
    step=step+1;
	if (step>100)
	{step=0;}
    sei();	
}

int main(void)
{	DDRB = 0b11111111;
	DDRD = 0b00000000;
	outp((1<<INT0)|(1<<INT1), GIMSK); // enable external int0, int1
	outp((1<<ISC01)|(1<<ISC00), MCUCR); // trigger int0 on rising flank
	outp((1<<ISC11)|(1<<ISC10), MCUCR); // trigger int1 on rising flank
	
	
	sei();
	
	while (1)
	{
		while (waveform==1)
		{	for (unsigned int i = 0; i<=254; i++)	
			{				
				PORTB = tr[i];							// 8-bit triangle wave
				for (unsigned int t=0; t<=step; t++) {}
			}			
		}
		
		while (waveform==2)
		{	for (unsigned int i = 0; i<=254; i++)	
			{				
				PORTB = si[i];							// 8-bit sine wave
				for (unsigned int t=0; t<=step; t++) {}
			}			
		}
		
		while (waveform==3)
		{	for (unsigned int i = 0; i<=254; i++)	
			{				
				PORTB = sa[i];							// 8-bit sawtooth wave
				for (unsigned int t=0; t<=step; t++) {}
			}			
		}
		
		while (waveform==4)
		{	PORTB=255;									// 8-bit square wave
			for (unsigned int t=0; t<=step*128; t++) {} 
			PORTB=0;
			for (unsigned int t=0; t<=step*128; t++) {}			
		}
		
		while (waveform==5)
		{	for (unsigned int i = 0; i<=254; i=i+8)	
			{				
				PORTB = tr[i];							// fast but inaccurate triangle wave
				for (unsigned int t=0; t<=step; t++) {}
			}			
		}
		
		while (waveform==6)
		{	for (unsigned int i = 0; i<=254; i=i+8)	
			{				
				PORTB = si[i];							// fast but inaccurate sine wave
				for (unsigned int t=0; t<=step; t++) {}
			}			
		}
		
		while (waveform==7)
		{	for (unsigned int i = 0; i<=254; i=i+8)	
			{				
				PORTB = tr[i];							// fast but inaccurate sawtooth wave
				for (unsigned int t=0; t<=step; t++) {}
			}			
		}
		
		while (waveform==8)
		{	PORTB=255;									// fast square wave
			for (unsigned int t=0; t<=step*16; t++) {} 
			PORTB=0;
			for (unsigned int t=0; t<=step*16; t++) {}			
		}
		
	}	
	
}
