CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Problem SPI with Accelerometer ADIS16209
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
jo
Guest







Problem SPI with Accelerometer ADIS16209
PostPosted: Fri Oct 02, 2009 3:05 am     Reply with quote

Hello,

I'm trying to use an accelerometer from Analog Devices (ADIS16209).
But it doesn't work correctly.
Code:

void main()
{
   int8 dataA;int8 dataB;
   int16 data;
   setup_spi(SPI_MASTER|SPI_H_TO_L|SPI_CLK_DIV_4 );
   
   output_high(ADIS_RST);
   output_high(SPI_CS);
   delay_ms(500);
   
   while(true)
   {
       output_low(SPI_CS);
       delay_ms(100);
       
      spi_write(SUPPLY_OUT);
                
      dataA = spi_read(0);
      dataB = spi_read(0);
         
      data = make16(dataA, dataB);
      printf("Supply   = 0x%04x \r", data);
         
      output_high(SPI_CS);
      delay_ms(500);
   }
}

The program send me some different value... never the same.
Do you see something wrong ?

Thanks before
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Fri Oct 02, 2009 4:16 am     Reply with quote

You're not operating the interfacing according to the specification. As clarified in the datasheet, 16 Bits have to written and read in each cycle. The read data arrives in the next cycle. Also the 2 top most bits ND and EA are not belonging to the data word and should be masked off.
jo
Guest







PostPosted: Fri Oct 02, 2009 4:35 am     Reply with quote

ok,

So, after modification, I have this code for sending:
Code:

output_low(SPI_CS);
delay_us(1);
spi_write(SUPPLY_OUT); // 8 first bits
spi_write(0x00);       // 8 other bits for 16 bits           
delay_us(1);
output_high(SPI_CS);


and for receiving:
Code:

output_low(SPI_CS);   
delay_us(1);
dataA = spi_read(0);
dataB = spi_read(0);
delay_us(1);
output_high(SPI_CS);   
data = make16(dataA, dataB);
data = (data & 0x3fff); //mask for the two bits.
printf("Supply   = 0x%04x  \r\n", data);

But it's the same....
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Fri Oct 02, 2009 5:52 am     Reply with quote

The code is basically correct now. I don't know however, if the SPI functions are working as expected
with your PIC and compiler version, there may be also an unrevealed hardware problem.
Ttelmah
Guest







PostPosted: Fri Oct 02, 2009 7:29 am     Reply with quote

Note however that the device uses SPI mode3, which requires:
Code:
SPI_H_TO_L | SPI_XMIT_L_TO_H

Best Wishes
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Sat Oct 03, 2009 4:34 am     Reply with quote

Yes, you're right. It's a popular error with the confusing CCS SPI notation in my opinion.

Unfortunately SPI_XMIT_L_TO_H means just the opposite: transmit on clock transition H_TO_L, sample on clock transition L_TO_H. I know that there have been respective tables posted in the forum (e.g. http://www.ccsinfo.com/forum/viewtopic.php?t=29059), but they should be in the CCS manual.
mazen82



Joined: 10 Sep 2009
Posts: 22

View user's profile Send private message

PostPosted: Fri Oct 23, 2009 11:59 am     Reply with quote

Hi,

I am having the same issue, were you able to resolve it? One thing that I saw that is wrong is that to read the upper byte you need to write to the address register 0x03, then write another byte of 0's to make it 16 bit, then do a read. Then redo the same thing for the register 0x02 to get the lower byte.
Code:
 
    CS1 = 0;
     spi_write2(0x03);
     spi_write2(0x00);
     high_byte_x = spi_read2(0);
     spi_write2(0x02);
     spi_write2(0x00);     
     lo_byte_x = spi_read2(0);
     CS1 = 1;

But I still can't get it to read correct.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Oct 23, 2009 4:39 pm     Reply with quote

Quote:
I am having the same issue [with the ADIS16209].

Post your complete, compilable test program that reads a register and
displays it on a terminal window on a PC. The program should have
the #include, #fuses, #use delay, other #use statements, all variable
declarations, main(), setup_spi(), and your read code and a printf.
Don't include any CCS wizard code that is not needed in the program.

Test the program and verify the failure. Post what it displays.

Also post your compiler version.
mazen82



Joined: 10 Sep 2009
Posts: 22

View user's profile Send private message

PostPosted: Mon Oct 26, 2009 9:53 am     Reply with quote

Code:

#include "C:\Program Files\PICC\ethernet2\18F97J60.H"
#device ICD=TRUE
#device adc=10
#use delay(clock=25M)
#fuses HS
#fuses NOIESO
#fuses NOFCMEN
#fuses PRIMARY
#fuses ETHLED
#fuses NOWDT
#fuses NOPROTECT
#fuses DEBUG
#fuses NOSTVREN

#define SPI_MODE_0  (SPI_L_TO_H | SPI_XMIT_L_TO_H)
#define SPI_MODE_1  (SPI_L_TO_H)
#define SPI_MODE_2  (SPI_H_TO_L)
#define SPI_MODE_3  (SPI_H_TO_L | SPI_XMIT_L_TO_H)

int16 inclin_x_int16;
#bit CS1          = LATD .7

void main()
{

setup_spi2(SPI_SS_DISABLED);
setup_spi2(SPI_MASTER|SPI_MODE_3|SPI_CLK_DIV_16);
delay_ms(200);
while(1)
{
     CS1 = 0;    //chip select pin to ADIS16209
     spi_write2(0x03);     //to read upper byte
     spi_write2(0x00);
     delay_us(1);
     high_byte_x = spi_read2(0);  //upper byte
   
     spi_write2(0x02);     //to read lower byte
     spi_write2(0x00);
     delay_us(1);
     lo_byte_x = spi_read2(0);  //lower byte 

      inclin_x_int16 = high_byte_x;    //inclin_x_int16 is an int16 integer
      inclin_x_int16 = inclin_x_int16<<8;
      inclin_x_int16 = inclin_x_int16 + lo_byte_x;
      CS1 = 1;

}  // end of while(1)

} //end of main()

This is the code that I wrote. The readings for high_byte_x and lo_byte_x are 0.
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Mon Oct 26, 2009 10:17 am     Reply with quote

Code:
setup_spi2(SPI_SS_DISABLED);
setup_spi2(SPI_MASTER|SPI_MODE_3|SPI_CLK_DIV_16);
The second line is overriding the settings of the first line, so effectively the first line could be removed from the code.

My guess is you intended to disable a SPI unit, for this you have to configure it as:
Code:
setup_spi2(FALSE);
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Oct 26, 2009 11:48 am     Reply with quote

1. Post a list of the connections between your PIC and the ADIS chip.
(post the pin numbers).

2. Post your compiler version.

3. Your program doesn't compile. It's missing variable declarations
for high_byte_x, lo_byte_x, and LATD. The LATD line has a space in it.
mazen82



Joined: 10 Sep 2009
Posts: 22

View user's profile Send private message

PostPosted: Mon Oct 26, 2009 12:52 pm     Reply with quote

Compiler version is 4.09.

The pinout is as follows:
PIC18f97j60 ADIS16209
RD5 --> pin 2 Dout
RD4 --> pin 3 Din
RD6 --> pin 1 SCLK
RD7 --> pin 4 CS
Code:

int lo_byte_x,high_byte_x;

#byte LATD    =  0xF8C
#byte PORTD    =  0xF83

#bit RD0          = LATD .0
#bit RD1          = LATD .1
#bit RD2          = LATD .2
#bit RD3          = LATD .3
#bit ADIS_SDO     = LATD .4
#bit ADIS_SDI     = PORTD.5
#bit ADIS_CLK     = LATD .6
#bit CS1          = LATD .7
#define     DDIRD    0x20  //all outputs except D5 (SDI)
#define     INITD       0x00

Before while(1) I initialize the ports and load them with the INITx. I can see the data in and the clock signals on the scope, on the data out it keeps changing, bouncing between different values.

Thanks.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Oct 26, 2009 1:07 pm     Reply with quote

Quote:
Compiler version is 4.09.

That's not a full version number. These are version numbers.
http://www.ccsinfo.com/devices.php?page=versioninfo

If you don't give your correct version, I can't check it for bugs.
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Mon Oct 26, 2009 1:08 pm     Reply with quote

A few notes:
1) According to the timing diagrams (table 2) the time between individual CS activations should be a minimum of 100us. Your program has only a few us.
2) The maximum SPI clock frequency (in normal mode) is 1.0MHz. You are clocking at 25MHz / SPI_CLK_DIV_16 = 1.5MHz.
mazen82



Joined: 10 Sep 2009
Posts: 22

View user's profile Send private message

PostPosted: Mon Oct 26, 2009 1:13 pm     Reply with quote

version is 4.090.

I tried having the SPI_CLK_DIV_64 instead of SPI_CLK_DIV_16 but i wouldnt see anything happening on the bus using the o'scope.

which makes sense because the part is by defualt configured to fast mode per table 8, so my SPI frequency is fine with the SPI_CLK_DIV_16 which gives ~1.5MHz, which is less than the max 2.5 MHz.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group