/*****************************************************************************/
/*                                                                           */
/* ad5932.c                                                                  */
/*                                                                           */
/* Routinen zur Ansteuerung des AD5932 DDS-Chips             				 */
/*                                                                           */
/* (2008) Universität Stuttgart / IZFM (Dipl.-Ing.(FH) Klaus Skibowski)      */
/*                                                                           */
/*			geändert auf ATMega88 und einen AD5932 							 */
/*																			 */
/*	Version: 	1															 */
/*	Datum: 		22.02.2010													 */	
/*	Name:		Martin Ernst												 */	
/*****************************************************************************/

#ifndef F_CPU
#define F_CPU	18432000UL
#endif

#include "ad5932.h"
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <avr\io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <math.h>
#include "lcd_lib.h"
//#include "entprell.h"

// Definition der Bits des Controllregister
#define D0  0x00
#define D1  0x01
#define D2  0x02
#define D3  0x03
#define D4  0x04
#define D5  0x05
#define D6  0x06
#define D7  0x07
#define D8  0x00
#define D9  0x01
#define D10 0x02
#define D11 0x03
#define D12 0x04
#define D13 0x05
#define D14 0x06
#define D15 0x07
 

#define FSYNC_HIGH  PORTB |=  (1<<PB1)  	//PB1
#define FSYNC_LOW   PORTB &= ~(1<<PB1)

#define CTRL_HIGH 	PORTD |=  (1<<PD3)		//PD0 jetzt PD3
#define CTRL_LOW    PORTD &= ~(1<<PD3)

#define INT_HIGH    PORTD |=  (1<<PD4)		//PD1 jetzt PD4
#define INT_LOW     PORTD &= ~(1<<PD4)

double mclk_faktor;
//double mclk;
	

void ad5932_init(void)
{
  // SPI-Init
  /* Set MOSI and SCK output, all others input */
    DDRB |= 0x20; // PB5 (SCK)   = Ausgang
    DDRB |= 0x08; // PB3 (MOSI)  = Ausgang
    DDRB |= 0x04; // PB2 (~SS)	 = Ausgang	
    DDRB |= 0x02; // PB1 (FSYNC) = Ausgang

	DDRB |= (1<<PB0); //PB0 = Ausgang
	PORTB &= ~(1<<PB0); //PB0 auf low setzen
		

    FSYNC_HIGH;

 
  SPCR = (1<<SPE) // SPE=1
  		|(1<<MSTR) //MSTR=1, 
		|(0<<CPOL)
		|(1<<CPHA)
		|(1<<SPR0); //fosc / 16
	  	
  //SPCR &= ~(1<<DORD);		//LSB zuerst
 	
	 INT_HIGH;
  	_delay_ms(1);
  	INT_LOW;
  	_delay_ms(1);
  	FSYNC_HIGH;
  	//CTRL_LOW;
  
  	mclk = 50000000; // Masterclock
  	mclk_faktor = 16777216.0/(double)mclk;

  	//waveform=WAVEFORM_TRIANGLE;
	//startfrequenz = 50.0;

	// Setzten der Controlbits
	control_reg |= (1<<D7) | (1<<D6) | (1<<D4) | (1<<D1) | (1<<D0) ; // reserved bits = 1
	control_reg |= AD5932_B24 | AD5932_DAC_ENABLE | AD5932_MSBOUTEN ;// | AD5932_MSBOUTEN;
	control_reg |= AD5932_TRIG_INC| AD5932_SYNCSEL | AD5932_SYNCOUTEN;
	ad5932_write(AD5932_CONTROL | control_reg);
	


	//ad5932_set_n_inc(n_inc);
	//ad5932_set_increment_interval(FIXED_CLOCK_PERIODS,t_int);
	//ad5932_set_delta_f(delta_f);
	//scandurchlauf = (1+n_inc)*(float)t_int*(float)tb_mult/mclk;	
	//startdelay=0;
	//sweep_status=0; // idle


}

/*
void ad5932_set_increment_interval(unsigned char mode, unsigned int wert)
{
  if (mode==FIXED_WAVEFORM_CYCLES)
	  ad5932_write(AD5932_T_INT | ((unsigned long)(tb_multiplier<<11)) | (wert & 0x07FF));
	else
	  ad5932_write(AD5932_T_INT | 0x2000 | ((unsigned long)(tb_multiplier<<11)) | (wert & 0x07FF));
}
*/

void ad5932_set_waveform(unsigned short waveform)
{
	if (waveform==WAVEFORM_SINUS)
	  control_reg |= AD5932_SINE_TRI;
	if (waveform==WAVEFORM_TRIANGLE)
	  control_reg &= ~AD5932_SINE_TRI;
	ad5932_write(AD5932_CONTROL | control_reg);
}


void ad5932_set_frequency(double wert)
{
  	unsigned int high,low;
	unsigned long freq_word;
	
	CTRL_LOW;
	control_reg |= AD5932_TRIG_INC;
	ad5932_write(AD5932_CONTROL | control_reg);
	//_delay_ms(10);
	freq_word = (unsigned long)(wert*mclk_faktor);
	high = (unsigned int)(((freq_word>>12) & 0x0FFF));
	low  = (unsigned int)((freq_word & 0x00000FFF));
	ad5932_write(AD5932_FSTART_LOW | low);
	ad5932_write(AD5932_FSTART_HIGH | high);
	
	
	//_delay_ms(10);
	CTRL_HIGH;

}
/*
void ad5932_set_delta_f(double wert)
{
  unsigned int high,low;
	unsigned long freq_word;
	unsigned char sign;
	
	if (wert<0)
	  sign = 1;
	else
	  sign = 0;
		
  freq_word = (unsigned long)((abs(wert)*mclk_faktor));  //fabs(wert)
  high = (unsigned int)(((freq_word>>11) & 0x07FF));
	low  =   (unsigned int)((freq_word & 0x00000FFF));
	
	ad5932_write(AD5932_DELTA_F_LOW | low);
	if (sign)
	{ 
	  ad5932_write(AD5932_DELTA_F_HIGH | 0x0800 | high);
	}
	else
	{
	  ad5932_write(AD5932_DELTA_F_HIGH | high);
	}
}
*/

/*
void ad5932_set_n_inc(unsigned int wert)
{
  ad5932_write(AD5932_N_INC | (wert & 0x0FFF));
}
*/



void ad5932_write(unsigned int wert)
{
    FSYNC_LOW;  // AD5932 --> SPI aktivieren
    SPDR = (unsigned char)(wert>>8);  // höherwertiges Byte senden
    while ( !(SPSR & (1<<SPIF))) {};  // warten  bis Übertragung abgesschlossen
    SPDR = (unsigned char)(wert & 0x00FF); // niederwertiges Byte senden
    while ( !(SPSR & (1<<SPIF))) {}; // warten  bis Übertragung abgesschlossen
    FSYNC_HIGH ;    // AD5932 --> SPI deaktivieren
}

void ad5932_start(void)
{
		CTRL_LOW;
		_delay_ms(100);
     	CTRL_HIGH;
}

/*void ad5932_reset(void)
{

  	
	INT_HIGH;
	_delay_ms(10);
	INT_LOW;

	
}*/

int main(void)
{

DDRD |= (1<<PD2)|(1<<PD3)|(1<<DDD3)|(1<<PD4)|(1<<PD5)|(1<<PD6)|(1<<PD7);	// PD  -> Ausgang
//DDRB  |= (1<<PB5)|(1<<PB3)|(1<<PB2)|(1<<PB1)|(1<<PB0);
	
	
    PORTD &= ~(1<<PD2); //PD2 auf low setzen (STANDBY aus)       
	ad5932_init();
	ad5932_set_waveform(WAVEFORM_TRIANGLE);
	//ad5932_set_waveform(WAVEFORM_SINUS);
	ad5932_set_frequency(50);
	//ad5932_reset();
	//ad5932_start();
	
	/*while(1)
	{
	}*/
}

