|
|
View previous topic :: View next topic |
Author |
Message |
Cogitum
Joined: 22 Mar 2012 Posts: 70 Location: France (Paris)
|
ADXL362 AUTONOMOUS Motion SWITCH >> Help please |
Posted: Sat Aug 27, 2016 9:23 am |
|
|
I try ADXL362 AUTONOMOUS in Motion Switch without succesfull
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
|
|
Posted: Sat Aug 27, 2016 10:12 am |
|
|
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
|
|
Posted: Sat Aug 27, 2016 6:25 pm |
|
|
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
|
|
Posted: Sun Aug 28, 2016 3:59 am |
|
|
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)
|
ADXL362 ON/OFF mode NEXT |
Posted: Sun Aug 28, 2016 8:03 am |
|
|
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 ....
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)
|
ADXL362 AUTONOMOUS Motion SWITCH WORKING NEXT ! |
Posted: Thu Sep 15, 2016 2:02 am |
|
|
HI ,
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
|
|
Posted: Thu Sep 15, 2016 3:00 am |
|
|
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)
|
Answer to Ttelmah |
Posted: Thu Sep 15, 2016 3:59 am |
|
|
HI Ttelmah,
Thank for your quick answer.
I have to try as soon as possible (actually no Resistor)
I will keep you informed.
Regards
Cogitum |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Thu Sep 15, 2016 6:48 am |
|
|
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)
|
:oops: |
Posted: Thu Sep 15, 2016 8:30 am |
|
|
OK thanks a lot
Cogitum |
|
|
|
|
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
|