AnsweredAssumed Answered

AD9956 SPI problem

Question asked by oktanto on Sep 6, 2010
Latest reply on Sep 29, 2010 by JLKeip

Dear All,

Because I could get driver ad9956 evaluation boards for win7, I must design program     microcontroller to control AD9956 evaluation boards. I am using     codevision as compiler and I used     Atmega8535 as microcontroller.

Design is, I create program on host OS, and all value of registry is     send to microcontroller using serial port and then from     microcontroller send to AD9956 evaluation boards using SPI protocol.     This is my program (code vision) :
ad9956.c :

#ifndef _DDS_AD9956
#define _DDS_AD9956

// Register Address
#define CFR1    0x00
#define CFR2    0x01
#define RDFTW   0x02
#define FDFTW   0x03
#define RSRR    0x04
#define FSRR    0x05
#define PCR0    0x06
#define PCR1    0x07
#define PCR2    0x08
#define PCR3    0x09
#define PCR4    0x0A
#define PCR5    0x0B
#define PCR6    0x0C
#define PCR7    0x0D

// Register Command
#define WRITE   0
#define READ    1

// Register size in Bit
#define CFR1_Size       32
#define CFR2_Size       40
#define RDFTW_Size      24
#define FDFTW_Size      24
#define RSRR_Size       16
#define FSRR_Size       16
#define PCR0_Size       64
#define PCR1_Size       64
#define PCR2_Size       64
#define PCR3_Size       64
#define PCR4_Size       64
#define PCR5_Size       64
#define PCR6_Size       64
#define PCR7_Size       64  
                      
#define CFR1_Byte       4
#define CFR2_Byte       5
#define DFTW_Byte       3
#define SRR_Byte        2
#define PCR_Byte        8

// Global Variable
unsigned char CFR1_Reg[CFR1_Byte];
unsigned char CFR2_Reg[CFR2_Byte];
unsigned char RDFTW_Reg[DFTW_Byte];
unsigned char FDFTW_Reg[DFTW_Byte];
unsigned char RSRR_Reg[SRR_Byte];
unsigned char FSRR_Reg[SRR_Byte];
unsigned char PCR0_Reg[PCR_Byte];
unsigned char PCR1_Reg[PCR_Byte];
unsigned char PCR2_Reg[PCR_Byte];
unsigned char PCR3_Reg[PCR_Byte];
unsigned char PCR4_Reg[PCR_Byte];
unsigned char PCR5_Reg[PCR_Byte];
unsigned char PCR6_Reg[PCR_Byte];
unsigned char PCR7_Reg[PCR_Byte];
       
#endif

spi_ad9956.c:

#include <mega8535.h>

// Standard Input/Output functions
#include <stdio.h>    

// Standard Library
#include <stdlib.h>     

// Delay Header
#include <delay.h>

// SPI functions
#include <spi.h>      

// AD9956 Parameters
#include <ad9956.c>

// External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void)
{
   // Place your code here
   #asm ("cli")       
   unsigned char random = 0;
  
   random = (int) (8.0*rand()/RAND_MAX);
  
   PORTC = random;
   #asm ("sei")
}                                

#define MOSI_HIGH       PORTB.5 = 1
#define SS_Deselect     PORTB.4 = 1
#define SS_Select       PORTB.4 = 0
#define DDS_IO_Update   PORTB.3 = 1
#define DDS_IO_Update_  PORTB.3 = 0
#define DDS_IO_Reset    PORTB.0 = 1
#define DDS_IO_Reset_   PORTB.0 = 0   

#define RXB8 1
#define TXB8 0
#define UPE 2
#define OVR 3
#define FE 4
#define UDRE 5
#define RXC 7

#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<OVR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)

// USART Receiver buffer
#define RX_BUFFER_SIZE 8
char rx_buffer[RX_BUFFER_SIZE];

#if RX_BUFFER_SIZE<256
unsigned char         rx_wr_index,rx_rd_index,rx_counter;
#else
unsigned int         rx_wr_index,rx_rd_index,rx_counter;
#endif

// This flag is set on USART Receiver buffer         overflow
bit rx_buffer_overflow;

// USART Receiver interrupt service routine
interrupt [USART_RXC] void         usart_rx_isr(void)
{
char status,data;
status=UCSRA;
data=UDR;
if ((status & (FRAMING_ERROR |         PARITY_ERROR | DATA_OVERRUN))==0)
   {
   rx_buffer[rx_wr_index]=data;
   if (++rx_wr_index == RX_BUFFER_SIZE)         rx_wr_index=0;
   if (++rx_counter == RX_BUFFER_SIZE)
      {
      rx_counter=0;
      rx_buffer_overflow=1;
      };
   };
}

#ifndef _DEBUG_TERMINAL_IO_
// Get a character from the USART Receiver         buffer
#define _ALTERNATE_GETCHAR_
#pragma used+
char getchar(void)
{
char data;
while (rx_counter==0);
data=rx_buffer[rx_rd_index];
if (++rx_rd_index == RX_BUFFER_SIZE)         rx_rd_index=0;
#asm("cli")
--rx_counter;
#asm("sei")
return data;
}
#pragma used-
#endif

// USART Transmitter buffer
#define TX_BUFFER_SIZE 8
char tx_buffer[TX_BUFFER_SIZE];

#if TX_BUFFER_SIZE<256
unsigned char         tx_wr_index,tx_rd_index,tx_counter;
#else
unsigned int         tx_wr_index,tx_rd_index,tx_counter;
#endif

// USART Transmitter interrupt service         routine
interrupt [USART_TXC] void         usart_tx_isr(void)
{
if (tx_counter)
   {
   --tx_counter;
   UDR=tx_buffer[tx_rd_index];
   if (++tx_rd_index == TX_BUFFER_SIZE)         tx_rd_index=0;
   };
}

#ifndef _DEBUG_TERMINAL_IO_
// Write a character to the USART         Transmitter buffer
#define _ALTERNATE_PUTCHAR_
#pragma used+
void putchar(char c)
{
while (tx_counter == TX_BUFFER_SIZE);
#asm("cli")
if (tx_counter || ((UCSRA &         DATA_REGISTER_EMPTY)==0))
   {
   tx_buffer[tx_wr_index]=c;
   if (++tx_wr_index == TX_BUFFER_SIZE)         tx_wr_index=0;
   ++tx_counter;
   }
else
   UDR=c;
#asm("sei")
}
#pragma used-
#endif
       
void send_command(unsigned char command_reg)
{
   unsigned char address;
   int i;
   SS_Select;    
  
   delay_ms(3);
  
   SPDR = command_reg;
  
   //  Wait until Tx register empty.
   while ( !(SPSR & 0x80) );
  
   address = ( command_reg & 0x1F );
                 
        switch(address){
        case CFR1:   
                for (i = CFR1_Byte - 1; i         >= 0; i--){
                    SPDR = CFR1_Reg[i];     
                   
                    //  Wait until Tx         register empty.
                    while ( !(SPSR &         0x80) );  
                }
                break;
        case CFR2:
                for (i = CFR2_Byte - 1; i         >= 0; i--){
                    SPDR =         CFR2_Reg[i];        

                    //  Wait until Tx         register empty.
                    while ( !(SPSR &         0x80) );  
                }
                break;
        case RDFTW:
                for (i = DFTW_Byte - 1; i         >= 0; i--){
                    SPDR =         RDFTW_Reg[i];            
                   
                    //  Wait until Tx         register empty.
                    while ( !(SPSR &         0x80) );  
                }
                break;
        case FDFTW:
                for (i = DFTW_Byte - 1; i         >= 0; i--){
                    SPDR =         FDFTW_Reg[i];            
                   
                    //  Wait until Tx         register empty.
                    while ( !(SPSR &         0x80) );  
                }
                break;
        case RSRR:
                for (i = SRR_Byte - 1; i         >= 0; i--){
                    SPDR =         RSRR_Reg[i];            
                   
                    //  Wait until Tx         register empty.
                    while ( !(SPSR &         0x80) );  
                }
                break;
        case FSRR:
                for (i = SRR_Byte - 1; i         >= 0; i--){
                    SPDR =         FSRR_Reg[i];            
                   
                    //  Wait until Tx         register empty.
                    while ( !(SPSR &         0x80) );  
                }
                break;
        case PCR0:
                for (i = PCR_Byte - 1; i         >= 0; i--){
                    SPDR =         PCR0_Reg[i];            
                   
                    //  Wait until Tx         register empty.
                    while ( !(SPSR &         0x80) );  
                }
                break;
        case PCR1:
                for (i = PCR_Byte - 1; i         >= 0; i--){
                    SPDR =         PCR1_Reg[i];            
                   
                    //  Wait until Tx         register empty.
                    while ( !(SPSR &         0x80) );  
                }
                break;
        case PCR2:
                for (i = PCR_Byte - 1; i         >= 0; i--){
                    SPDR =         PCR2_Reg[i];            
                   
                    //  Wait until Tx         register empty.
                    while ( !(SPSR &         0x80) );  
                }
                break;
        case PCR3:
                for (i = PCR_Byte - 1; i         >= 0; i--){
                    SPDR =         PCR3_Reg[i];            
                   
                    //  Wait until Tx         register empty.
                    while ( !(SPSR &         0x80) );  
                }
                break;
        case PCR4:
                for (i = PCR_Byte - 1; i         >= 0; i--){
                    SPDR =         PCR4_Reg[i];            
                   
                    //  Wait until Tx         register empty.
                    while ( !(SPSR &         0x80) );  
                }
                break;
        case PCR5:
                for (i = PCR_Byte - 1; i         >= 0; i--){
                    SPDR = PCR5_Reg[i];
                   
                    //  Wait until Tx         register empty.
                    while ( !(SPSR &         0x80) );  
                }
                break;
        case PCR6:
                for (i = PCR_Byte - 1; i         >= 0; i--){
                    SPDR =         PCR6_Reg[i];            
                   
                    //  Wait until Tx         register empty.
                    while ( !(SPSR &         0x80) );  
                }
                break;
        case PCR7:
                for (i = PCR_Byte - 1; i         >= 0; i--){
                    SPDR =         PCR7_Reg[i];            
                   
                    //  Wait until Tx         register empty.
                    while ( !(SPSR &         0x80) );  
                }
                break;
        }             
           
   delay_ms(1);
  
   SS_Deselect; 
  
   delay_ms(2);
  
   DDS_IO_Update;

   delay_ms(2);

   DDS_IO_Update_;             
}

// Declare your global variables here

void main(void)
{
// Declare your local variables here
unsigned char   received_command; 
unsigned char   address;
int i;

// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In         Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T         State3=T State2=T State1=T State0=T
PORTA=0x00;
DDRA=0x00;

// Port B initialization
// Func7=Out Func6=In Func5=Out Func4=Out         Func3=Out Func2=In Func1=In Func0=Out
// State7=0 State6=T State5=0 State4=1         State3=T State2=T State1=T State0=0
PORTB=0x10;
DDRB=0xB9;

// Port C initialization
// Func7=In Func6=In Func5=In Func4=In         Func3=In Func2=Out Func1=Out Func0=Out
// State7=T State6=T State5=T State4=T         State3=T State2=0 State1=0 State0=0
PORTC=0x00;
DDRC=0x07;

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In         Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T         State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=FFh
// OC0 output: Disconnected
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Rising Edge
// INT1: Off
// INT2: Off
GICR|=0x40;
MCUCR=0x03;
MCUCSR=0x00;
GIFR=0x40;

// Timer(s)/Counter(s) Interrupt(s)         initialization
TIMSK=0x00;

// USART initialization
// Communication Parameters: 8 Data, 1 Stop,         No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud rate: 115200 (Double Speed         Mode)
UCSRA=0x02;
UCSRB=0xD8;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x06;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by         Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

// SPI initialization
// SPI Type: Master
// SPI Clock Rate: 400,000 kHz
// Mode 3
// SPI Data Order: MSB First
SPCR=0x5D;
SPSR=0x00;

// Global enable interrupts
#asm("sei")
           
DDS_IO_Reset;
delay_ms(2);
DDS_IO_Reset_;       

while (1)
      {
      // Place your code here 
        MOSI_HIGH;
       
        received_command = getchar();
       
        address = ( received_command &         0x1F );
       
        switch(address){
        case CFR1:   
                for (i = CFR1_Byte - 1; i         >= 0; i--)
                    CFR1_Reg[i] = getchar();
                break;
        case CFR2:
                for (i = CFR2_Byte - 1; i         >= 0; i--)
                    CFR2_Reg[i] = getchar();
                break;
        case RDFTW:
                for (i = DFTW_Byte - 1; i         >= 0; i--)
                    RDFTW_Reg[i] =         getchar();
                break;
        case FDFTW:
                for (i = DFTW_Byte - 1; i         >= 0; i--)
                    FDFTW_Reg[i] =         getchar();
                break;
        case RSRR:
                for (i = SRR_Byte - 1; i         >= 0; i--)
                    RSRR_Reg[i] = getchar();
                break;
        case FSRR:
                for (i = SRR_Byte - 1; i         >= 0; i--)
                    FSRR_Reg[i] = getchar();
                break;
        case PCR0:
                for (i = PCR_Byte - 1; i         >= 0; i--)
                    PCR0_Reg[i] = getchar();
                break;
        case PCR1:
                for (i = PCR_Byte - 1; i         >= 0; i--)
                    PCR1_Reg[i] = getchar();
                break;
        case PCR2:
                for (i = PCR_Byte - 1; i         >= 0; i--)
                    PCR2_Reg[i] = getchar();
                break;
        case PCR3:
                for (i = PCR_Byte - 1; i         >= 0; i--)
                    PCR3_Reg[i] = getchar();
                break;
        case PCR4:
                for (i = PCR_Byte - 1; i         >= 0; i--)
                    PCR4_Reg[i] = getchar();
                break;
        case PCR5:
                for (i = PCR_Byte - 1; i         >= 0; i--)
                    PCR5_Reg[i] = getchar();
                break;
        case PCR6:
                for (i = PCR_Byte - 1; i         >= 0; i--)
                    PCR6_Reg[i] = getchar();
                break;
        case PCR7:
                for (i = PCR_Byte - 1; i         >= 0; i--)
                    PCR7_Reg[i] = getchar();
                break;
        }             
       
        send_command(received_command);
       
        MOSI_HIGH;
      };
}

 

 

All signal from microcontroller have been check using high speed     data acquisition, and compared with CY7C68013 on evaluation boards.     This is parameter on microcontroller :

 

SPI

 

1. Define as Master SPI

 

2. Pin Configurations

 

        * SS <active low> at PB4 configured with CS <active     low> at AD9956

 

        * MOSI at PB5 configured with SDI/O at AD9956

 

        * MISO at PB6 configured with SDO at AD9956

 

        * SCK at PB7 configured with SCK at AD9956

 

        * PB3 configured with I/O_Update at AD9956

 

        * PB0 configured with I/O_Reset at AD9956

 

3. Using MSB First <AD9956 using MSB as default>

 

4. SPI Mode 3

 

 

UART

 

1. Communications microcontroller and host PC

 

2. Baud Rate : 115.200

 

3. 8N1

 

4. Pin Configurations

 

        * PD0 (RxD)

 

        * PD1 (TxD)    

 

 

AD9956 Evaluation boards

 

1. Remove W2 and W3

 

2. Switch W4 from PC control to manual

 

 

Could you give me suggestions what a fault on design, why i still     couldn't drive AD9956 chip?

Outcomes