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

ADXL362 AUTONOMOUS Motion SWITCH >> Help please

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



Joined: 22 Mar 2012
Posts: 70
Location: France (Paris)

View user's profile Send private message

ADXL362 AUTONOMOUS Motion SWITCH >> Help please
PostPosted: Sat Aug 27, 2016 9:23 am     Reply with quote

I try ADXL362 AUTONOMOUS in Motion Switch without succesfull
Embarassed
I'm sure on the hardware connections but not my software.
I was inspired by the datasheet
http://www.analog.com/media/en/technical-documentation/data-sheets/ADXL362.pdf >> PAGE 36 of 43.
I put a scope on the INT2 pin schema
but no activity is present, shaking ADXL362.
Here the software:
Code:

// Test_ADXL362.c
// 25/08/2016
//  ADXL362   AUTONOMOUS MOTION SWITCH
// compiler 5.062

#include <18F66K22.h>
#device adc=12
 
#include <stdlib.h>             
//#include <stdio.h>
#include <string.h>

//#FUSES DEBUG
#FUSES NOWDT                    //No Watch Dog Timer
//#FUSES VREGSLEEP_SW             // Ultra Low POWER regulator enable
//#FUSES INTRC_HP                 // Low POWER mode during Sleep
#FUSES NOXINST                  // Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES HSH //M                  // High speed Osc, medium power 4MHz-16MHz
#FUSES NOBROWNOUT               // No brownout reset 
#FUSES NOPLLEN               //4X HW PLL disabled, 4X PLL enabled in software
#FUSES WDT_NOSLEEP           //Watch Dog Timer, disabled during SLEEP
#FUSES VREGSLEEP_SW            //Ultra low-power regulator is enabled
//#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES BBSIZ1K                  //1K words Boot Block size
#use delay(clock=20000000)
//#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=PORT1)
#use rs232(UART1,stream =gps,baud=9600, xmit=PIN_C6,rcv=PIN_C7)     
#USE SPI (MASTER, SPI2, MODE=0, BITS=8, STREAM=SPI_1,)

#include <stdlib.h>       
#include <math.h> 
#include <string.h>


#define  CS PIN_D7   // chip select
 

#define  ID0        0x00
#define  STATUS     0x0B
#define  RESET      0x1F
#define  INTMAP1    0x2A
#define  INTMAP2    0x2B
#define  FILTER_CTL 0x2C
#define  POWER_CTL  0x2D

#define  WR_SPI     0x0A
#define  RD_SPI     0x0B

// SPI mode definitions.
#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)


 void main()
 {
    output_low(PIN_D3); // SWITCH power ON ! (S)
  //  output_high(PIN_D3);//   power OFF
  //  output_low(PIN_E0);// WAKE_UP
    delay_ms(10);
    output_high(PIN_D2); // SWITCH power ON ! (G)
    setup_spi2(SPI_MASTER | SPI_MODE_0 | SPI_CLK_DIV_16 ); // Clock 1.25 MHZ 
    int16 read;
    printf ("********* TEST ADXL362 ***********\r\n");;

  while (true)
  {
  //********* DEVICE CONFIGURATION ****************
   output_low(CS);
   delay_us(50);
   spi_write2(0x26,0x20);
   delay_us(50);   
   spi_write2(0x27);
   delay_us(50);
   spi_write2(0x29,0x28);
   delay_us(50);
   spi_write2(0x28);
   delay_us(50);
   spi_write2(0x29);
   delay_us(50);
   spi_write2(0x2A);
   delay_us(50);
   spi_write2(0x2B);
   delay_us(50);
   spi_write2(0x2C);
   delay_us(50);
   spi_write2(0x2D);
   delay_us(50);
   output_high(CS);
   
   //*********** AUTONOMOUS MOTION SWITCH *********
   output_low(CS);
   delay_us(50);
   spi_write2(0x20,0xFA);
   delay_us(50);
   spi_write2(0x23,0x96);
   delay_us(50);
   spi_write2(0x25,0x1E);
   delay_us(50);   
   spi_write2(0x27,0x3F);
   delay_us(50);
   spi_write2(0x2B,0x40);
   delay_us(50); 
   spi_write2(0x2D,0x1E);
   spi_xfer(SPI_1,0x0A);
   delay_us(50);
   output_high(CS);
   
   output_low(CS);
   delay_us(50);
   read =spi_read2 ( 0x20);// Value in register 0x20 ?
   delay_us(50); 
   output_high(CS);
   

   printf (" read = %X\r\n",read);
   delay_ms(50);
   output_toggle(PIN_G0);
   
  }

 }

Thanks in advance for your help

Cogitum
temtronic



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

View user's profile Send private message

PostPosted: Sat Aug 27, 2016 10:12 am     Reply with quote

so first question...

Have you confirmed PIC is running with a '1Hz LED' program ??

2nd Q...
What voltage are you running the PIC and peripheral at ?


Jay
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Aug 27, 2016 6:25 pm     Reply with quote

Quote:
spi_write2(0x26,0x20);

Did you read the CCS manual on this ? It doesn't do what you think it's
doing. Don't invent. Read the manual.
http://www.ccsinfo.com/downloads/ccs_c_manual.pdf


Quote:
#USE SPI (MASTER, SPI2, MODE=0, BITS=8, STREAM=SPI_1,)
setup_spi2(SPI_MASTER | SPI_MODE_0 | SPI_CLK_DIV_16 ); // Clock 1.25 MHZ

You are using spi_write2() in your code. This function is associated with
setup_spi2(). You should not also be using #use spi(). These are two
different methods of setting up spi. You should not use both at the same time.


Quote:

spi_write2(0x2D,0x1E);
spi_xfer(SPI_1,0x0A);

Here you have mixed two different methods of talking to the SPI2 module.
Don't do that. Pick one or the other and stay with it.


Quote:
spi_write2(0x28);
delay_us(50);
spi_write2(0x29);
delay_us(50);
spi_write2(0x2A);
delay_us(50);
spi_write2(0x2B);

This is not a good way to write a driver. You have lots of magic numbers
and no one knows what they mean. The correct way is to create a list
of #define statements for those numbers. The #define symbol will have
some meaning, such as a register name. Example:

Put the define statements near the start of the program.
Code:
#define FIFO_SAMPLES_REG  0x29


Then within the program functions, write code like this:
Code:
spi_write2(FIFO_SAMPLES_REG);


It makes the program easier to understand.
Ttelmah



Joined: 11 Mar 2010
Posts: 19515

View user's profile Send private message

PostPosted: Sun Aug 28, 2016 3:59 am     Reply with quote

First, have a look at my replies in these two threads:

<http://www.ccsinfo.com/forum/viewtopic.php?t=55028&highlight=spixfer>
<http://www.ccsinfo.com/forum/viewtopic.php?t=54917&highlight=spixfer>

These explain the point about the two different methods of using SPI in CCS.
Use #USE SPI, and spi_xfer only. These work well, and are more flexible. As PCM_Programmer has pointed out, _do not mix the two methods_.

Then understand the first basic tool in debugging. Only try to do one thing at a time. Look first at Temtronic's post, and prove your chip is actually running, and at the right speed. Only once you have this going, try to move to SPI. Then don't try to get everything working at once. Start by reading the device ID. Once you know you can do this correctly, then write data. Once step at a time.

Hopefully you _are_ running your PIC at 3.3v.

Then if you are using spi_write2, read the manual. Does it say it can send multiple bytes?. It doesn't complain, because it can accept multiple bytes, but then the first byte is a 'flag' to say whether it is to wait for the chip. So you are not sending anything even remotely resembling what you expect....
The values being sent, also look silly. You send '0x26' (if it worked), followed by 0x20. The programming of the chip requires you to send 'instruction', followed by 'address'. The instructions supported are:

 0x0A: write register
 0x0B: read register
 0x0D: read FIFO

You are not sending anything resembling these.....

Are you using a bootloader?. If not, why have a boot block size enabled?.

So:
Code:

// Test_ADXL362.c
// 25/08/2016
//  ADXL362   AUTONOMOUS MOTION SWITCH
// compiler 5.062

#include <18F66K22.h>
#device adc=12
 
#include <stdlib.h>             
//#include <stdio.h>
#include <string.h>

//#FUSES DEBUG
#FUSES NOWDT                    //No Watch Dog Timer
//#FUSES VREGSLEEP_SW             // Ultra Low POWER regulator enable
//#FUSES INTRC_HP                 // Low POWER mode during Sleep
#FUSES NOXINST                  // Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES HSH //M                  // High speed Osc, medium power 4MHz-16MHz
#FUSES NOBROWNOUT               // No brownout reset
#FUSES NOPLLEN               //4X HW PLL disabled, 4X PLL enabled in software
#FUSES WDT_NOSLEEP           //Watch Dog Timer, disabled during SLEEP
#FUSES VREGSLEEP_SW            //Ultra low-power regulator is enabled
//#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES BBSIZ1K                  //1K words Boot Block size
#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,UART1,,bits=8,ERRORS, stream=GPS)
//You should always have errors with the hardware UART   
#USE SPI (MASTER, SPI2, MODE=0, BITS=8, STREAM=SPI_1, baud=1000000)
//recommend 1MHz to 8MHz.

#include <stdlib.h>       
#include <math.h>
#include <string.h>


#define  CS PIN_D7   // chip select

#define  ID0        0x00
#define  STATUS     0x0B
#define  RESET      0x1F
#define  INTMAP1    0x2A
#define  INTMAP2    0x2B
#define  FILTER_CTL 0x2C
#define  POWER_CTL  0x2D
#define THRESH_ACT_L 0x20

#define  WR_SPI     0x0A
#define  RD_SPI     0x0B

//write one register
void write_register(int8 regno, int8 value)
{
   int8 dummy;
   output_low(CS); //select chip
   spi_xfer(SPI_1,WR_SPI); //send write command
   spi_xfer(regno); //send address
   dummy=spi_xfer(value); //send byte
   //doing this ensures the transfer _completes_ before deselecting
   output_high(CS); //deselect
}
 
//read one register
int8 read_register(int8 regno)
{
   int8 dummy;
   output_low(CS);
   spi_xfer(SPI_1,RD_SPI); //read command
   spi_xfer(regno); //register to read
   dummy=spi_xfer(value); //get the reply
   //doing this ensures the transfer _completes_ before deselecting
   output_high(CS);
   return dummy; //return value read
}

//write array of data to successive registers
void write_block(int8 regno, int8 * data, int8 count)
{
   int8 dummy;
   output_low(CS); //select chip
   spi_xfer(SPI_1,WR_SPI); //send write command
   spi_xfer(regno); //send register address
   do
   {
       dummy=spi_xfer(*(data++)); //send one byte
   } while (--count); //while there is more data to send
   output_high(CS); //deselect
}


Then you need to work out the initialisation sequence, as perhaps an array of bytes, and send this as:

int8 init_sequence[] = { n, n2, n3, n4 };

write_block(THRES_ACT_L, init_sequence, sizeof(init_sequence));

With the register name you want to start with, and the sequence to be sent.
Cogitum



Joined: 22 Mar 2012
Posts: 70
Location: France (Paris)

View user's profile Send private message

ADXL362 ON/OFF mode NEXT
PostPosted: Sun Aug 28, 2016 8:03 am     Reply with quote

Msg TO Temtronic, PCM programmer and Ttelmah,

Hello,

First of all, I want to thank you all for 3 responses so quickly!
I'm back from vacation and I recognize that I have not been on top in the creation of my program .... Embarassed Embarassed
I apologize!
For information:
I have already completed a comprehensive product that uses a 345 ADXL with the I2C bus but with features measuring X, Y and Z.
Today, my goal is to reduce the overall consumption of my product.
A hardware solution I already reduced consumption standing at 400 nA and it suits me.
ADXL345 consumes too! So I chose ADXL 362 which can operate in Mode On / Off without using microcontroller
which in SLEEP mode consumes too.
The software that I submitted on the FORUM will allow me to validate the ON / OFF function with ADXL 362.
With my copy / paste I also copy lines that do not have their place in this program.

I will return to you as soon as my program will fulfill its function!
All comments or suggestions are welcome.

Thank you in advance for your help.

Cogitum

Note: power supply (DC / DC converter) = 3.3V for all the components. Sure debug LED blinks and
the MISO MOSI CLK and CS signals are present.
RS232 works and I can read the messages on HYPERTERMINAL.

I do not use loader but ICD-U64 from CCS.
Cogitum



Joined: 22 Mar 2012
Posts: 70
Location: France (Paris)

View user's profile Send private message

ADXL362 AUTONOMOUS Motion SWITCH WORKING NEXT !
PostPosted: Thu Sep 15, 2016 2:02 am     Reply with quote

HI ,
Very Happy
Compiler Version 5.062
ADXL 362 is working fine in ON/OFF mode !
PIN RC3 and RC4 arent used by I2C
For this reason I'm using PIN RD4,RD5,RD6 and RD7 for SPI2 where I making the link with ADXL 362.

Main parts of my code (18F66K22) are :
Code:

#use delay(clock=20000000)
 #use rs232(UART1,stream =gps,baud=9600,ERRORS, xmit=PIN_C6,rcv=PIN_C7)   
#USE SPI (MASTER, SPI2, MODE=0, BITS=8, STREAM=SPI_1, baud=5000000)

#define  CS_ADXL PIN_D7   // D7 chip select ADXL362
 
#define  ID0          0x00
#define  STATUS       0x0B
#define  RESET        0x1F
#define  INTMAP1      0x2A
#define  INTMAP2      0x2B
#define  FILTER_CTL   0x2C
#define  POWER_CTL    0x2D
#define  THRESH_ACT_L 0x20

#define  WR_SPI       0x0A
#define  RD_SPI       0x0B



//write one register
void write_register(int8 regno, int8 value)
{
   int8 dummy;
   output_low(CS_ADXL); //select chip
   spi_xfer(SPI_1,WR_SPI); //send write command
   spi_xfer(regno); //send address     
   dummy=spi_xfer(value); //send byte   
   //doing this ensures the transfer _completes_ before deselecting
   output_high(CS_ADXL); //deselect
}
 
//read one register
int8 read_register(int8 regno)
{
   int8 dummy;
   output_low(CS_ADXL);
   spi_xfer(SPI_1,RD_SPI); //read command
   spi_xfer(regno);       //register to read
   dummy=spi_xfer(0x00); //get the reply
   //doing this ensures the transfer _completes_ before deselecting
   output_high(CS_ADXL);
   return dummy; //return value read
}
  void main()
 {
 
 int8 value ;
  int8 dummy;
 // int8 regno;

 
  output_low(PIN_D3); // SWITCH power ON ! (S)
  //  output_high(PIN_D3);//   power OFF
  //  output_low(PIN_E0);// WAKE_UP
    delay_ms(10);
  ///  output_high(PIN_D2); // SWITCH power ON ! (G)     
    fprintf (gps,"********* TEST ADXL362 ***********\r\n");


     write_register(0x20, 0xFA); // ACTIVITY THRESHOLD   250 mg
     write_register(0x21, 0x00); // INACTIVITY THRESHOLD 150 mg
     write_register(0x23, 0x96); // THRESH_INACT_L  600 mg
     write_register(0x24, 0x00); // THRESH_INACT_H
     write_register(0x25, 0x03); // 00x1E TIME_INACT_L >> 30 samples ou 5 secondes
     write_register(0x27, 0x3F); // 0x3F ACT_INACT_CTL
     write_register(INTMAP1, 0xC0); // INTMAP1  0xC0 HIGH ACTIVE
   //  write_register(INTMAP2, 0x40); // INTMAP2  0x40 LOW  ACTIVE
     write_register(FILTER_CTL, 0x00); // 0x00 FILTER_CTL
     write_register(POWER_CTL, 0x0A); // 0x0A POWER_CTL
     
     
  //    delay_ms(100);
//!       read_register(0x23);
     
     
 
  while (true)
  { 

 fprintf (gps," Value  = %X\r\n",value);
//!    fprintf (gps," Register  = %X\r\n",regno);
 fprintf (gps," Reg Value = %x\r\n",dummy);
   delay_ms(100);
 //  output_toggle(PIN_G0);
   
  }

 }

Note : first target OK (mode On/OFF running)

Now, I need to add 2nd device on the same port
Hardware : 3 wire in // except CS !
It seem do not accept an additional devices on the same SPI2 PORT
with for example using PIN_E2 as CS2

Why ?

Welcome to any help

Thanks in advance

Cogitum
Ttelmah



Joined: 11 Mar 2010
Posts: 19515

View user's profile Send private message

PostPosted: Thu Sep 15, 2016 3:00 am     Reply with quote

The obvious thing missing, is to pull both CS lines _high_ right at the start of your code. Currently it is pulled low to select the chip, and then taken high, but if a second chip is present, it may well be 'on', till the CS is taken high, and would then interfere with the first chip.
Cogitum



Joined: 22 Mar 2012
Posts: 70
Location: France (Paris)

View user's profile Send private message

Answer to Ttelmah
PostPosted: Thu Sep 15, 2016 3:59 am     Reply with quote

HI Ttelmah,

Thank for your quick answer.

I have to try as soon as possible (actually no Resistor)Embarassed

I will keep you informed.

Regards

Cogitum
Ttelmah



Joined: 11 Mar 2010
Posts: 19515

View user's profile Send private message

PostPosted: Thu Sep 15, 2016 6:48 am     Reply with quote

What do you mean 'no resistor'?. I don't mention a resistor.

I'm talking _code_. The first two lines in the code ought to be:

output_high(CS1);
output_high(CS2);

Before any attempt to configure the chips.

The lines are _floating_, till they are driven (PIC's wake up with all pins configured as inputs). Odds are they are sitting low. With one chip won't matter, but with two, when you go to configure the first one, the second chip would also be sitting enabled. Result both slave outputs would be trying to drive the wires at once....
Cogitum



Joined: 22 Mar 2012
Posts: 70
Location: France (Paris)

View user's profile Send private message

:oops:
PostPosted: Thu Sep 15, 2016 8:30 am     Reply with quote

Embarassed OK thanks a lot

Cogitum
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