/* This is a program to control AD9102 arbitrary waveform oscillator */
/*** Libraries ***/
#define VtoD1 6.75
#define VtoD2 6.65
#define VtoD3 6.75
#define VtoD4 6.7
#include "ch1.h"
#include "ch2.h"
#include "ch3.h"
#include "ch4.h"
#include "control.h"
#include <SPI.h>
//Set pins for the output
int Pin_en_cvddx = 2; //Oscillator out control @ #2
int Pin_shdn_n_lt3472 = 4; //LT3472 enable pin @ #4
int PinTrigger = 6; //AD9102 trigger pin @ #6 originally 7
int PinDutReset = 8; //AD9102 Reset pin @ #8
int PinSpiCS0 = 46; //AD9102 SPI CS0 @Group 1 pin @ #46
int PinSpiCS1 = 32; //AD9102 SPI CS0 @Group 3 pin @ #32
int PinSpiCS2 = 40; //AD9102 SPI CS0 @Group 4 pin @ #40
int PinSpiCS3 = 25; //AD9102 SPI CS0 @Group 5 pin @ #25
char ext_clk = 'y';
char amp_out = 'n';
char Stop = 'n';
char Exit = 'n';
char wave;
char dummy;
int pulse_num;
int multi;
char Connected = 1;
/*** Function Declarations ***/
void AD9102_reg_reset( void );
void AD9102_update_regs1( unsigned int Data[] );
void AD9102_update_regs2( unsigned int Data[] );
void AD9102_update_regs3( unsigned int Data[] );
void AD9102_update_regs4( unsigned int Data[] );
void AD9102_update_sram1( int Data[] );
void AD9102_update_sram2( int Data[] );
void AD9102_update_sram3( int Data[] );
void AD9102_update_sram4( int Data[] );
void spi_write1( unsigned int addr, int Data );
void spi_write2( unsigned int addr, int Data );
void spi_write3( unsigned int addr, int Data );
void spi_write4( unsigned int addr, int Data );
int spi_read1( unsigned int addr );
int numeric_read( void );
void printf_menu( void );
void generate_wave1( void );
void generate_wave2( void );
void generate_wave3( void );
void generate_wave4( void );
void printf_prompt3( void );
void stop_wave( void );
void printf_prompt4( void );
/*** Main Function ***/
void setup()
{
pinMode(Pin_en_cvddx, OUTPUT); //DigitalOut instance for enable pin of on-board oscillator supply
pinMode(Pin_shdn_n_lt3472, OUTPUT); //DigitalOut instance for shutdown/enable pin of on-board amplifier supply
pinMode(PinSpiCS0, OUTPUT); //AD9102 SPI CS0 @ Group 1 pin46
pinMode(PinSpiCS1, OUTPUT); //AD9102 SPI CS0 @ Group 3 pin32
pinMode(PinSpiCS2, OUTPUT); //AD9102 SPI CS0 @ Group 4 pin40
pinMode(PinSpiCS3, OUTPUT); //AD9102 SPI CS0 @ Group 5 pin25
pinMode(PinTrigger, OUTPUT); //AD9102 trigger pin
pinMode(PinDutReset, OUTPUT); //AD9102 Reset pin
digitalWrite(PinDutReset, HIGH);
digitalWrite(PinTrigger, HIGH);
digitalWrite(Pin_en_cvddx, HIGH);
digitalWrite(Pin_shdn_n_lt3472, HIGH);
digitalWrite(PinSpiCS0, HIGH);
digitalWrite(PinSpiCS1, HIGH);
digitalWrite(PinSpiCS2, HIGH);
digitalWrite(PinSpiCS3, HIGH);
Serial.begin(38400);
SPI.begin();
SPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE0));
AD9102_reg_reset();
}
void loop()
{
printf_menu();
while( Serial.available() == 0 );
wave = Serial.read();
delay(20);
if(wave=='9')
{
printf("\r\n Press 'R' and CR to regenerate waves. \r\n" );
while( Serial.available() == 0 ){}
dummy = numeric_read();
digitalWrite(PinTrigger, LOW);
}else{
//printf("wave= %c \r\n", wave);
printf("\r\n Input repeat number: \r\n");
while(Serial.available() > 0)
{
dummy = Serial.read();
delay(10);
}
while( Serial.available() == 0 ){}
pulse_num = numeric_read();
while(Serial.available() > 0)
{
dummy = Serial.read();
delay(10);
}
printf("Repeat number = %d \r\n", pulse_num);
inp_multi:
printf("\r\n Input multiple of time base 1 to 16, basic time base = 6.4ns: \r\n");
printf(" Input 4 for 4 x 6.4ns, for example \r\n");
while(Serial.available() > 0)
{
dummy = Serial.read();
delay(10);
}
while( Serial.available() == 0 ){}
multi = numeric_read();
while(Serial.available() > 0)
{
dummy = Serial.read();
delay(10);
}
if(multi<1 | multi>16)
{
printf(" Input number is out of range, input again. \r\n");
goto inp_multi;
}
printf("Multiple of time base = %d \r\n", multi);
printf("\r\n Wait for data transfer completion. \r\n");
if(pulse_num==0)
{
wave1_regval[15] = 0x0000;
wave2_regval[15] = 0x0000;
wave3_regval[15] = 0x0000;
wave4_regval[15] = 0x0000;
}else{
wave1_regval[15] = 0x0001;
wave2_regval[15] = 0x0001;
wave3_regval[15] = 0x0001;
wave4_regval[15] = 0x0001;
wave1_regval[26] = 0x0100 + pulse_num;
wave2_regval[26] = 0x0100 + pulse_num;
wave3_regval[26] = 0x0100 + pulse_num;
wave4_regval[26] = 0x0100 + pulse_num;
}
//set time base
wave1_regval[23] = 0x0001 + (multi * 0x0100);
wave2_regval[23] = 0x0001 + (multi * 0x0100);
wave3_regval[23] = 0x0001 + (multi * 0x0100);
wave4_regval[23] = 0x0001 + (multi * 0x0100);
switch (wave) {
case '4':
generate_wave1();
generate_wave2();
generate_wave3();
generate_wave4();
printf("\r\n All data have been transfered. Input 'S' and CR to generate waves. \r\n" );
while( Serial.available() == 0 ){}
dummy = numeric_read();
digitalWrite(PinTrigger, LOW);
break;
case '9':
break;
default:
printf("***Invalid Entry**** \r\n");
break;
}
}
printf_prompt3();
while( Serial.available() == 0 );
while ( !(Stop == 'y') ){
Stop = Serial.read();
}
stop_wave();
printf_prompt4();
while( Serial.available() == 0 );
Exit = Serial.read();
if ( Exit == 'y' ){
Connected = 0;
printf("\r\n Exiting program...\r\n");
}else{
Stop = 'n';
}
}
void printf_menu()
{
printf("\r\r\n***** Wave Option *****\r\r\n");
printf(" 4 - 4 Waves\r\n");
printf(" 9 - Restart after soft reset only\r\n");
printf("Select option: 4 or 9 \r\n");
}
/*Function to play shape 1*/
void generate_wave1()
{
printf("\r\n Start Wave1 data transfer.\r\n");
delay(500);
AD9102_update_sram1( wave1 );
AD9102_update_regs1( wave1_regval );
printf("Wave1 data transfer completed.\r\n");
}
/*Function to play shape 7*/
void generate_wave2()
{
printf("\r\n Start Wave2 data transfer.\r\n");
delay(500);
AD9102_update_sram2( wave2 );
AD9102_update_regs2( wave2_regval );
printf("Wave2 data transfer completed.\r\n");
}
void generate_wave3()
{
printf("\r\n Start Wave3 data transfer.\r\n");
delay(500);
AD9102_update_sram3( wave3 );
AD9102_update_regs3( wave3_regval );
printf("Wave3 data transfer completed.\r\n");
}
void generate_wave4()
{
printf("\r\n Start Wave4 data transfer.\r\n");
delay(500);
AD9102_update_sram4( wave4 );
AD9102_update_regs4( wave4_regval );
printf("Wave4 data transfer completed.\r\n");
}
/*Function to reset AD9102 reg reset*/
void AD9102_reg_reset()
{
digitalWrite(PinDutReset, LOW);
delay( 10 );
digitalWrite(PinDutReset, HIGH);
}
/*
* @brief Write data to SRAM
* @param data[] - array of data to be written to SRAM
* @return none
*/
void AD9102_update_sram1( int Data[] )
{
spi_write1( 0x001E, 0x0004 );
float fData;
int16_t DACdata;
int data_shifted = 0;
unsigned int sram_add = 0x6000;
for ( int i=0; i<4096; i++ )
{
if(Data[i]>1200||Data[i]<-1200) printf("\r\n data is too large or too small \r\n");
if(Data[i]>1200||Data[i]<-1200) exit(0);
fData = VtoD1 * (float)Data[i];
DACdata = (int16_t)fData;
if(DACdata<0) DACdata=16384 + DACdata;
data_shifted = (int16_t)DACdata << 2;
spi_write1( sram_add+i, data_shifted );
//if(i<100) printf("data= %d data_shifted= %d \r\n", Data[i], data_shifted);
}
spi_write1( 0x001E, 0x0010 );
}
void AD9102_update_sram2( int Data[] )
{
spi_write2( 0x001E, 0x0004 );
float fData;
int16_t DACdata;
int data_shifted = 0;
unsigned int sram_add = 0x6000;
for ( int i=0; i<4096; i++ )
{
if(Data[i]>1200||Data[i]<-1200) printf("\r\n data is too large or too small \r\n");
if(Data[i]>1200||Data[i]<-1200) exit(0);
fData = VtoD2 * (float)Data[i];
DACdata = (int16_t)fData;
if(DACdata<0) DACdata=16384 + DACdata;
data_shifted = (int16_t)DACdata << 2;
spi_write2( sram_add+i, data_shifted );
}
spi_write2( 0x001E, 0x0010 );
}
void AD9102_update_sram3( int Data[] )
{
spi_write3( 0x001E, 0x0004 );
float fData;
int16_t DACdata;
int data_shifted = 0;
unsigned int sram_add = 0x6000;
for ( int i=0; i<4096; i++ )
{
if(Data[i]>1200||Data[i]<-1200) printf("\r\n data is too large or too small \r\n");
if(Data[i]>1200||Data[i]<-1200) exit(0);
fData = VtoD3 * (float)Data[i];
DACdata = (int16_t)fData;
if(DACdata<0) DACdata=16384 + DACdata;
data_shifted = (int16_t)DACdata << 2;
spi_write3( sram_add+i, data_shifted );
}
spi_write3( 0x001E, 0x0010 );
}
void AD9102_update_sram4( int Data[] )
{
spi_write4( 0x001E, 0x0004 );
float fData;
int16_t DACdata;
int data_shifted = 0;
unsigned int sram_add = 0x6000;
for ( int i=0; i<4096; i++ )
{
if(Data[i]>1200||Data[i]<-1200) printf("\r\n data is too large or too small \r\n");
if(Data[i]>1200||Data[i]<-1200) exit(0);
fData = VtoD4 * (float)Data[i];
DACdata = (int16_t)fData;
if(DACdata<0) DACdata=16384 + DACdata;
data_shifted = (int16_t)DACdata << 2;
spi_write4( sram_add+i, data_shifted );
}
spi_write4( 0x001E, 0x0010 );
}
/*
* @brief Write to SPI registers, and read and printf new register values
* @param data[] - array of data to written to SPI registers
* @return none
*/
void AD9102_update_regs1( uint16_t Data[] )
{
unsigned int data_display = 0;
for ( int i=0; i<66; i++ ){
spi_write1( reg_add[i], Data[i] );
}
}
void AD9102_update_regs2( uint16_t Data[] )
{
unsigned int data_display = 0;
for ( int i=0; i<66; i++ ){
spi_write2( reg_add[i], Data[i] );
}
}
void AD9102_update_regs3( uint16_t Data[] )
{
unsigned int data_display = 0;
for ( int i=0; i<66; i++ ){
spi_write3( reg_add[i], Data[i] );
}
}
void AD9102_update_regs4( uint16_t Data[] )
{
unsigned int data_display = 0;
for ( int i=0; i<66; i++ ){
spi_write4( reg_add[i], Data[i] );
}
}
/*
* @brief Write 16-bit data to AD910x SPI/SRAM register
* @param addr - SPI/SRAM address
* @param data - data to be written to register address
* @return none
*/
void spi_write1( unsigned int addr, int Data )
{
digitalWrite(PinSpiCS0, LOW);
SPI.transfer16( addr );
SPI.transfer16( Data );
digitalWrite(PinSpiCS0, HIGH);
delay( 10 );
}
void spi_write2( unsigned int addr, int Data )
{
digitalWrite(PinSpiCS1, LOW);
SPI.transfer16( addr );
SPI.transfer16( Data );
digitalWrite(PinSpiCS1, HIGH);
delay( 10 );
}
void spi_write3( unsigned int addr, int Data )
{
digitalWrite(PinSpiCS2, LOW);
SPI.transfer16( addr );
SPI.transfer16( Data );
digitalWrite(PinSpiCS2, HIGH);
delay( 10 );
}
void spi_write4( unsigned int addr, int Data )
{
digitalWrite(PinSpiCS3, LOW);
SPI.transfer16( addr );
SPI.transfer16( Data );
digitalWrite(PinSpiCS3, HIGH);
delay( 10 );
}
int spi_read1( unsigned int addr )
{
digitalWrite(PinSpiCS0, LOW);
unsigned int read_addr;
int reg_data;
read_addr = 0x8000 + addr;
reg_data = SPI.transfer16( read_addr );
digitalWrite(PinSpiCS0, HIGH);
delay( 10 );
return( reg_data );
}
int numeric_read()
{
char inBytes[10];
int vals[6];
Serial.readBytesUntil('\r\n', inBytes, sizeof(inBytes)/sizeof(char));
vals[0] = atoi(inBytes);
//printf("vals[0] = %d \r\n",vals[0]);
return(vals[0]);
}
/*Function to printf prompt/question to user to stop pattern*/
void printf_prompt3()
{
printf( "\r\n Stop pattern?\r\n" );
printf( "If yes, input 'y' and CR.\r\n" );
}
/*Function to stop pattern generation*/
void stop_wave()
{
digitalWrite(PinTrigger, HIGH);
printf( "\r\n Waves stopped.\r\n" );
}
/*Function to printf prompt/question to user to exit program*/
void printf_prompt4()
{
printf( "\r\n Restart program?\r\n" );
printf( "If yes, input 'y' and CR or press reset button.\r\n" );
}
现在有4个频道输出,数据放在ch1.h,ch2.h文件里,将代码改为由用户选择有几个频道输出,更多的文件处理,比如100个波形的数据