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 CCS Technical Support

ADXL355 accelerometer code

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
m4k



Joined: 27 Mar 2018
Posts: 29

View user's profile Send private message

ADXL355 accelerometer code
PostPosted: Tue Jan 12, 2021 10:57 am     Reply with quote

I am doing a project which monitors vibrations using an ADXL355 sensor. I have used the MPU-9250 sensor before.

I am not able to use spi function to read data in spi mode from the sensor. Can anyone who has worked previously with the sensor help me?

Previously i used i2c protocol Properly...but spi...
tnx alot
Ttelmah



Joined: 11 Mar 2010
Posts: 19496

View user's profile Send private message

PostPosted: Tue Jan 12, 2021 11:26 am     Reply with quote

Critical first question. What voltage PIC are you using?. This is a 3v
device, so really needs to be using a 3v PIC (3.6v max).
Second comment, the chip supports I2C as well as SPI. If you are
happy with I2C, why not use it?.
Using SPI, you need the SCK pin of the PIC to the SCLK of the device.
Then the SDO pin of the PIC to the MOSI of the device.
Then the SDI pin of the PIC to MISO on the device.
Then any pin of the PIC to the CS line on the device (chip select
used to start each transaction).
You then do really need the DRDY output of the device to an interrupt
input on the PIC. The device signals with this when it has a sample ready.
m4k



Joined: 27 Mar 2018
Posts: 29

View user's profile Send private message

PostPosted: Tue Jan 12, 2021 1:23 pm     Reply with quote

Ttelmah wrote:
Critical first question. What voltage PIC are you using?. This is a 3v
device, so really needs to be using a 3v PIC (3.6v max).
Second comment, the chip supports I2C as well as SPI. If you are
happy with I2C, why not use it?.
Using SPI, you need the SCK pin of the PIC to the SCLK of the device.
Then the SDO pin of the PIC to the MOSI of the device.
Then the SDI pin of the PIC to MISO on the device.
Then any pin of the PIC to the CS line on the device (chip select
used to start each transaction).
You then do really need the DRDY output of the device to an interrupt
input on the PIC. The device signals with this when it has a sample ready.


I use dspi33fj chip...i want to try spi function.
The hardware is ok ...my problem is how to start sequence ...write and read data.
For example:
In i2c function
Code:

i2c_start();
i2c_write(addr);
i2c_start();
i2c_write(addr);
i2c_read();
i2c_stop();


in spi mode how to read and write?
tnx
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Jan 12, 2021 1:50 pm     Reply with quote

This thread shows how to write to an ADXL chip using #use spi() and
spi_xfer(). This is the newer method of using SPI with CCS. It can support
hardware or software SPI in the PIC:
http://www.ccsinfo.com/forum/viewtopic.php?t=55439

This thread show how to do it using spi_setup(), spi_write() and spi_read().
This is the older method of using SPI with CCS. It's for hardware SPI only:
http://www.ccsinfo.com/forum/viewtopic.php?t=51309
m4k



Joined: 27 Mar 2018
Posts: 29

View user's profile Send private message

PostPosted: Tue Jan 12, 2021 2:01 pm     Reply with quote

PCM programmer wrote:
This thread shows how to write to an ADXL chip using #use spi() and
spi_xfer(). This is the newer method of using SPI with CCS. It can support
hardware or software SPI in the PIC:
http://www.ccsinfo.com/forum/viewtopic.php?t=55439

This thread show how to do it using spi_setup(), spi_write() and spi_read().
This is the older method of using SPI with CCS. It's for hardware SPI only:
http://www.ccsinfo.com/forum/viewtopic.php?t=51309


thank you
benoitstjean



Joined: 30 Oct 2007
Posts: 566
Location: Ottawa, Ontario, Canada

View user's profile Send private message

PostPosted: Wed Jan 13, 2021 7:09 am     Reply with quote

I haven't used that one but I use the ADXL345 and I believe that the default SPI configuration was different than the EEPROM tied on that bus and I just haven't taken the time to make both work the same way so that's why I call <setup_SPI3> at the beginning and the end of the function.

Here's my code and I've been using it for years on a PIC24 and my compiler is 5.026:


To set a register:

Code:
void ADXL_SetRegister( unsigned int8 Address, unsigned int8 Data )
{
   // Configure SPI port to work with accelerometer.
   // *NOTE: Accelerometer shares its SPI port with the external EEPROM and
   //        both use a different configuration.
   setup_spi3( SPI_MASTER | SPI_XMIT_L_TO_H | SPI_H_TO_L | SPI_CLK_DIV_16 );
   
   output_low( MCU_PIN_ADXL_CS_SPI ); //PIN_F0
   
   spi_write3( Address );
   spi_write3( Data );

   output_high( MCU_PIN_ADXL_CS_SPI ); //PIN_F0
   
   // Make sure SPI port gets re-configured to work with the EEPROM
   setup_spi3( SPI_MASTER | SPI_XMIT_L_TO_H | SPI_CLK_DIV_16 );
}


To get a register:
Code:

void ADXL_GetRegister( unsigned int8 Address, unsigned int8 NbBytes, unsigned int8 *Data )
{
   unsigned int8 Counter = 0;

   // Configure SPI port to work with accelerometer.
   // *NOTE: Accelerometer shares its SPI port with the external EEPROM and
   //        both use a different configuration.
   setup_spi3( SPI_MASTER | SPI_XMIT_L_TO_H | SPI_H_TO_L | SPI_CLK_DIV_16 );

   output_low( MCU_PIN_ADXL_CS_SPI ); //PIN_F0
   
   if( NbBytes > 1 )
   {
      spi_write3( 0xC0 | Address );
   }
   else
   {
      spi_write3( 0x80 | Address );   
   }
   
   while( Counter != NbBytes )
   {
      Data[Counter] = spi_read3( 0x00 );
      Counter ++;
   }
   
   output_high( MCU_PIN_ADXL_CS_SPI ); //PIN_F0
 
   // Make sure SPI port gets re-configured to work with the EEPROM
   setup_spi3( SPI_MASTER | SPI_XMIT_L_TO_H | SPI_CLK_DIV_16 );

   return;

}



Good luck.

Ben
Ttelmah



Joined: 11 Mar 2010
Posts: 19496

View user's profile Send private message

PostPosted: Wed Jan 13, 2021 9:14 am     Reply with quote

It looks to me Benoitstjean, as if the chip there has a bit that needs to
be set for multi-byte reads. This one doesn't. It automatically performs
these on all the main registers, with auto increment, and on the FIFO
without. It does need bit 0 of the address set. It's register addressing uses
the same format as I2C device addressing, with the register address
having to be multiplied by 2, and ORed with a R/W flag.
m4k



Joined: 27 Mar 2018
Posts: 29

View user's profile Send private message

PostPosted: Fri Jan 15, 2021 4:58 am     Reply with quote

benoitstjean wrote:
I haven't used that one but I use the ADXL345 and I believe that the default SPI configuration was different than the EEPROM tied on that bus and I just haven't taken the time to make both work the same way so that's why I call <setup_SPI3> at the beginning and the end of the function.

Here's my code and I've been using it for years on a PIC24 and my compiler is 5.026:


To set a register:

Code:
void ADXL_SetRegister( unsigned int8 Address, unsigned int8 Data )
{
   // Configure SPI port to work with accelerometer.
   // *NOTE: Accelerometer shares its SPI port with the external EEPROM and
   //        both use a different configuration.
   setup_spi3( SPI_MASTER | SPI_XMIT_L_TO_H | SPI_H_TO_L | SPI_CLK_DIV_16 );
   
   output_low( MCU_PIN_ADXL_CS_SPI ); //PIN_F0
   
   spi_write3( Address );
   spi_write3( Data );

   output_high( MCU_PIN_ADXL_CS_SPI ); //PIN_F0
   
   // Make sure SPI port gets re-configured to work with the EEPROM
   setup_spi3( SPI_MASTER | SPI_XMIT_L_TO_H | SPI_CLK_DIV_16 );
}


To get a register:
Code:

void ADXL_GetRegister( unsigned int8 Address, unsigned int8 NbBytes, unsigned int8 *Data )
{
   unsigned int8 Counter = 0;

   // Configure SPI port to work with accelerometer.
   // *NOTE: Accelerometer shares its SPI port with the external EEPROM and
   //        both use a different configuration.
   setup_spi3( SPI_MASTER | SPI_XMIT_L_TO_H | SPI_H_TO_L | SPI_CLK_DIV_16 );

   output_low( MCU_PIN_ADXL_CS_SPI ); //PIN_F0
   
   if( NbBytes > 1 )
   {
      spi_write3( 0xC0 | Address );
   }
   else
   {
      spi_write3( 0x80 | Address );   
   }
   
   while( Counter != NbBytes )
   {
      Data[Counter] = spi_read3( 0x00 );
      Counter ++;
   }
   
   output_high( MCU_PIN_ADXL_CS_SPI ); //PIN_F0
 
   // Make sure SPI port gets re-configured to work with the EEPROM
   setup_spi3( SPI_MASTER | SPI_XMIT_L_TO_H | SPI_CLK_DIV_16 );

   return;

}



Good luck.

Ben


tnx...the write address is 0x00...but what is the reading address? 0x80?
Ttelmah



Joined: 11 Mar 2010
Posts: 19496

View user's profile Send private message

PostPosted: Fri Jan 15, 2021 5:02 am     Reply with quote

The address, for you will be the register address from the data sheet,
shifted left one bit, and ored with a R/W flat into the low bit. The chip
benoitsjean is using, is different. Your chip uses a design similar
to I2C for the address byte sent.
m4k



Joined: 27 Mar 2018
Posts: 29

View user's profile Send private message

PostPosted: Fri Jan 15, 2021 5:11 am     Reply with quote

Ttelmah wrote:
The address, for you will be the register address from the data sheet,
shifted left one bit, and ored with a R/W flat into the low bit. The chip
benoitsjean is using, is different. Your chip uses a design similar
to I2C for the address byte sent.


tnx.....the data sheet say 0x00 for write addr ...shifted left is 0x01 for reading but in adxl345 write addr is 0x00 and read addr is 0x80
Ttelmah



Joined: 11 Mar 2010
Posts: 19496

View user's profile Send private message

PostPosted: Fri Jan 15, 2021 7:08 am     Reply with quote

On the 345, the R/W bit is bit 7. On your chip they instead use bit 0.
However you would not want to read register 0. Register 0, is just the
device ID register 0xAD (for Analog Devices).
You would need to start with register definitions like:
Code:

#define READ 1
#define WRITE 0

//Now the device register definitions. All twice the data sheet values. OR with READ
//or WRITE accordign to what you are doing
#define DEVID_AD 0
#define DEVID_MST 2
#define PARTID 4
#define REVID 6
#define STATUS 8
#define FIFO_ENTRIES 10
#define TEMP2 12
#define TEMP1 14
#define XDATA3 16
#define XDATA2 18
#define XDATA1 20
#define YDATA3 22
#define YDATA2 24
#define YDATA1 26
#define ZDATA3 28
#define ZDATA2 30
#define ZDATA1 32
#define FIFO_DATA 34
#define OFFSET_X_H 60
#define OFFSET_X_L 62
#define OFFSET_Y_H 64
#define OFFSET_Y_L 66
#define OFFSET_Z_H 68
#define OFFSET_Z_L 70
#define ACT_EN 72
#define ACT_THRESH_H 74
#define ACT_THRESH_L 76
#define AXT_COUNT 78
#define FILTER 80
#define FIFO_SAMPLES 82
#define INT_MAP 84
#define SYBC 86
#define RANGE 88
#define POWER_CTL 90
#define SELF_TEST 92
#define RESET 94
m4k



Joined: 27 Mar 2018
Posts: 29

View user's profile Send private message

PostPosted: Fri Jan 15, 2021 4:46 pm     Reply with quote

Ttelmah wrote:
On the 345, the R/W bit is bit 7. On your chip they instead use bit 0.
However you would not want to read register 0. Register 0, is just the
device ID register 0xAD (for Analog Devices).
You would need to start with register definitions like:
Code:

#define READ 1
#define WRITE 0

//Now the device register definitions. All twice the data sheet values. OR with READ
//or WRITE accordign to what you are doing
#define DEVID_AD 0
#define DEVID_MST 2
#define PARTID 4
#define REVID 6
#define STATUS 8
#define FIFO_ENTRIES 10
#define TEMP2 12
#define TEMP1 14
#define XDATA3 16
#define XDATA2 18
#define XDATA1 20
#define YDATA3 22
#define YDATA2 24
#define YDATA1 26
#define ZDATA3 28
#define ZDATA2 30
#define ZDATA1 32
#define FIFO_DATA 34
#define OFFSET_X_H 60
#define OFFSET_X_L 62
#define OFFSET_Y_H 64
#define OFFSET_Y_L 66
#define OFFSET_Z_H 68
#define OFFSET_Z_L 70
#define ACT_EN 72
#define ACT_THRESH_H 74
#define ACT_THRESH_L 76
#define AXT_COUNT 78
#define FILTER 80
#define FIFO_SAMPLES 82
#define INT_MAP 84
#define SYBC 86
#define RANGE 88
#define POWER_CTL 90
#define SELF_TEST 92
#define RESET 94


i try to use to #use spi mode to transfer and get data from this sensor

hardware connection is :

dspic ---------- adxl355
ss2>>>>>>>cs --- pin 1
sck2>>>>>>sclk---- pin2
sdo2>>>>>>>mosi --pin3
sdi2>>>>>>>miso ---pin4


Code:

#include <33FJ256GP506.h>

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES CKSFSM                   //Clock Switching is enabled, fail Safe clock monitor is enabled
#FUSES NOJTAG                   //JTAG disabled

#device ICSP=1
#use delay(internal=20MHz)

#define led1   PIN_F1
#define led2   PIN_G1

#use rs232(xmit=PIN_G13, baud=9600, errors)
#USE SPI (MASTER, SPI2, MODE=0, BITS=8, baud=5000000,FORCE_HW)

#define CS  PIN_g9


#define READ 1
#define WRITE 0



//read one register
int8 read_register(int8 value)
{
   int8 dummy;
   output_low(CS);
   spi_xfer(READ);
   spi_xfer(value);     
   dummy=spi_xfer(0x00);
   output_high(CS);
   return dummy;
}




void main()
{
output_high(cs);
 //measure mode////write 0x00 into register 0x2d
    output_low(CS);
   spi_xfer(WRITE);
   spi_xfer(0x2d);     
   spi_xfer(0x00);
   output_high(CS);
   

int8 test=0;
   while(TRUE)
   {
 
test = read_register(0x0);

 
   printf("%lu\n\r",test);
      output_toggle(led1);
     
      delay_ms(10);
     
   }}


and i check the sdi and sdo and sck signal on scope and its true but in serial monitor when i read each register ,the output show 29...whats wrong?
tnx anlot
temtronic



Joined: 01 Jul 2010
Posts: 9221
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Jan 15, 2021 5:23 pm     Reply with quote

I don't use that PIC but..

SPI 'data' has always been 8 bits long, so a 'byte'. As a 'byte' of data, I think of it as an unsigned integer ( 0-255).

That PIC and//or compiler may default 'int8' to a signed 8 bit value.
Also 'test' is 8 bits wide but you print it as a 'Long Unsigned'.

I don't know if this is your problem but I have seen similar 'data defintion' problems.
m4k



Joined: 27 Mar 2018
Posts: 29

View user's profile Send private message

PostPosted: Sat Jan 16, 2021 12:33 am     Reply with quote

temtronic wrote:
I don't use that PIC but..

SPI 'data' has always been 8 bits long, so a 'byte'. As a 'byte' of data, I think of it as an unsigned integer ( 0-255).

That PIC and//or compiler may default 'int8' to a signed 8 bit value.
Also 'test' is 8 bits wide but you print it as a 'Long Unsigned'.

I don't know if this is your problem but I have seen similar 'data defintion' problems.


i check this but its not problem
Ttelmah



Joined: 11 Mar 2010
Posts: 19496

View user's profile Send private message

PostPosted: Sat Jan 16, 2021 3:01 am     Reply with quote

Code:

//read one register
int8 read_register(int8 value)
{
   int8 dummy;
   output_low(CS);
   //spi_xfer(READ); //This is saying to read register 0.
   //To read the register, you need:
   dummy=spi_xfer(value|READ);
   //Use 'dummy' here to force the transmission to complete before
   //advancing   
   dummy=spi_xfer(0x00); //This now reads the reply
   output_high(CS);
   return dummy;
}


The 'read' command and the register value are sent as _one_ transfer
not two.

Use the register names, then you know what value you are talking to.

test = read_register(DEVID_AD);

test should then be 173.

An spi_xfer, without an 'return value', writes the sent value to the output
register and returns immediately. Reading the return value, forces it
to instead complete the transfer before returning (since it waits for
the byte to be received). Hence always read the return if you want to
be sure the transmission has actually occurred.

The direction flag is sent _with_ the address value as one byte. Not two
bytes.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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