#include <avr/io.h>
#include <stdio.h>
#include <avr/interrupt.h>
#include <math.h>
#define FOSC 8000000
#define BAUD 9600
#define MYUBRR 103
#define PAR_AXIS_XP 0
#define PAR_AXIS_XN 1
#define PAR_AXIS_YP 2
#define PAR_AXIS_YN 3
#define PAR_AXIS_ZP 4
#define PAR_AXIS_ZN 5
#define ACL_ERR_SUCCESS 0
#define ACL_ERR_ARG_RANGE_05 10
#define sbi(var, mask) ((var) |= (uint8_t)(1 << mask))
#define cbi(var, mask) ((var) &= (uint8_t)~(1 << mask))
//ADXL345
#define adxl 0 //PORTB
uint8_t recv1=0;
uint8_t byte=0;
uint16_t dX, dY, dZ;
uint8_t bAxisInfo;
uint8_t dX0=0,dX1=0, dY0=0,dY1=0, dZ0=0, dZ1=0;
//Define functions
//======================
void ioinit(uint8_t baud); //Initializes IO
void delay_ms(uint16_t x); //General purpose delay
static int uart_putchar(char c, FILE *stream);
uint8_t uart_getchar(void);
static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE);
void iniSPI(void);
void send_byte(uint8_t byte);
void send_dummy (void);
void resetCS(uint16_t delay);
uint8_t CalibrateOneAxisGravitational(uint8_t bAxisInfo);
//======================
void send_dummy(void)
{
SPDR = 0xAA;
while(!(SPSR & (1<<SPIF)));
}
void send_byte(uint8_t byte)
{
SPDR = byte;
while(!(SPSR & (1<<SPIF)));
}
void iniSPI(void)
{
// Set MOSI, SCK, and SS output, all others input
sbi(DDRB, adxl); //acc1 cs output
sbi(PORTB, adxl);
cbi(SPCR, CPHA);
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR1)|(1<<SPR0)|(1<<CPHA)|(1<<CPOL);
cbi(SPCR, SPR1);
sbi(SPCR, SPR0);
SPSR = (1<<SPI2X);
delay_ms(1);
}
void ioinit (uint8_t baud)
{
//1 = output, 0 = input
DDRB = 0b11101111; //All inputs
DDRC = 0b11111111; //All outputs
DDRD = 0b11001110; //PORTD (RX on PD0)
//DDRA = 0b11111111;
//CLKPR = (1 << CLKPCE);
//CLKPR = (3<<CLKPS);
UBRR0H = MYUBRR >> 8;
UBRR0L = MYUBRR;
UCSR0B = (1<<RXEN0)|(1<<TXEN0);
UCSR0A = (1<<U2X0);
//UCSR0C=(1<<UCSZ01)|(1<<UCSZ00);
stdout = &mystdout; //Required for printf init
}
static int uart_putchar(char c, FILE *stream)
{
if (c == '\n') uart_putchar('\r', stream);
loop_until_bit_is_set(UCSR0A, UDRE0);
UDR0 = c;
return 0;
}
uint8_t uart_putbyte(uint8_t mybyte)
{
while ( !( UCSR0A & (1<<UDRE0)) )
;
/* Put data into buffer, sends the data */
UDR0 = mybyte;
}
uint8_t uart_getchar(void)
{
while( !(UCSR0A & (1<<RXC0)) );
return(UDR0);
}
uint8_t SetPowerControlMeasureBit(uint8_t check){
if(!check){
while(byte != 0x20)
{
cbi(PORTB, adxl);
send_byte(0x2D);
send_byte(0x20);
sbi(PORTB, adxl);
delay_ms(5);
cbi(PORTB, adxl);
send_byte(0xAD);
send_byte(0x00);
byte = SPDR;
sbi(PORTB, adxl);
//printf("Power is: %x\n", byte);
delay_ms(1000);
}
}else{
while(byte != 0x28)
{
cbi(PORTB, adxl);
send_byte(0x2D);
send_byte(0x28);
sbi(PORTB, adxl);
delay_ms(5);
cbi(PORTB, adxl);
send_byte(0xAD);
send_byte(0x00);
byte = SPDR;
sbi(PORTB, adxl);
//printf("Power is: %x\n", byte);
delay_ms(1000);
}
}
}
uint8_t SetOffsetXG(uint8_t offsetx){
while(byte != offsetx)
{
cbi(PORTB, adxl);
send_byte(0x1E);
send_byte(offsetx);
sbi(PORTB, adxl);
delay_ms(5);
cbi(PORTB, adxl);
send_byte(0x9E);
send_byte(0x00);
byte = SPDR;
sbi(PORTB, adxl);
//printf("Power is: %x\n", byte);
delay_ms(1000);
}
}
uint8_t SetOffsetYG(uint8_t offsety){
while(byte != offsety)
{
cbi(PORTB, adxl);
send_byte(0x1F);
send_byte(offsety);
sbi(PORTB, adxl);
delay_ms(5);
cbi(PORTB, adxl);
send_byte(0x9F);
send_byte(0x00);
byte = SPDR;
sbi(PORTB, adxl);
//printf("Power is: %x\n", byte);
delay_ms(1000);
}
}
uint8_t SetOffsetZG(uint8_t offsetz){
while(byte != offsetz)
{
cbi(PORTB, adxl);
send_byte(0x20);
send_byte(offsetz);
sbi(PORTB, adxl);
delay_ms(5);
cbi(PORTB, adxl);
send_byte(0xA0);
send_byte(0x00);
byte = SPDR;
sbi(PORTB, adxl);
//printf("Power is: %x\n", byte);
delay_ms(1000);
}
}
uint16_t ReadAccelG(uint16_t x, uint16_t y, uint16_t z){
uint8_t data[6];
cbi(PORTB, adxl);
send_byte(0xF2);
for(uint8_t i=0; i<6; i++)
{
send_byte(0xFF);
data[i] = SPDR;
}
sbi(PORTB, adxl);
x = data[1] << 8 | data[0];
y = data[3] << 8 | data[2];
z = data[5] << 8 | data[4];
}
uint8_t ReadAccelGBits(){
uint8_t data[6];
cbi(PORTB, adxl);
send_byte(0xF2);
for(uint8_t i=0; i<6; i++)
{
send_byte(0xFF);
data[i] = SPDR;
}
sbi(PORTB, adxl);
dX0 = data[0];
dX1 = data[1];
dY0 = data[2];
dY1 = data[3];
dZ0 = data[4];
dZ1 = data[5];
}
uint8_t CalibrateOneAxisGravitational(uint8_t bAxisInfo)
{
uint8_t bResult;
if(bAxisInfo >= PAR_AXIS_XP && bAxisInfo <= PAR_AXIS_ZN)
{
// perform calibration
// set the offset registers to 0
//Put the device into standby mode to configure it.
SetPowerControlMeasureBit(0);
SetOffsetXG(0);
SetOffsetYG(0);
SetOffsetZG(0);
SetPowerControlMeasureBit(1);
switch (bAxisInfo)
{
case PAR_AXIS_XP:
dX = 1.0 - dX;
dY = 0.0 - dY;
dZ = 0.0 - dZ;
break;
case PAR_AXIS_XN:
dX = -1.0 - dX;
dY = 0.0 - dY;
dZ = 0.0 - dZ;
break;
case PAR_AXIS_YP:
dY = 1.0 - dY;
dX = 0.0 - dX;
dZ = 0.0 - dZ;
break;
case PAR_AXIS_YN:
dY = -1.0 - dY;
dX = 0.0 - dX;
dZ = 0.0 - dZ;
break;
case PAR_AXIS_ZP:
dZ = 1.0 - dZ;
dY = 0.0 - dY;
dX = 0.0 - dX;
break;
case PAR_AXIS_ZN:
dZ = -1.0 - dZ;
dY = 0.0 - dY;
dX = 0.0 - dX;
break;
}
//Put the device into standby mode to configure it.
SetPowerControlMeasureBit(0);
// set the offset data to registers
SetOffsetXG(dX);
SetOffsetYG(dY);
SetOffsetZG(dZ);
SetPowerControlMeasureBit(1);
bResult = ACL_ERR_SUCCESS;
}
else
{
bResult = ACL_ERR_ARG_RANGE_05;
}
return bResult;
}
//General short delays
void delay_ms(uint16_t x)
{
uint8_t y, z;
for ( ; x > 0 ; x--){
for ( y = 0 ; y < 90 ; y++){
for ( z = 0 ; z < 6 ; z++){
asm volatile ("nop");
}
}
}
}
int main (void)
{
ioinit(103);
iniSPI();
delay_ms(40000);//long delay
//waits for power register to respond correctly
//printf("Start\n");
CalibrateOneAxisGravitational(PAR_AXIS_ZP);
//SetPowerControlMeasureBit(1);
cbi(PORTB, adxl);
send_byte(0x31);
send_byte(0x08);
sbi(PORTB, adxl);
delay_ms(5);
cbi(PORTB, adxl);
send_byte(0xB1);
send_byte(0x00);
byte = SPDR;
sbi(PORTB, adxl);
// printf("Format is: %x\n", byte);
cbi(PORTB, adxl);
send_byte(0x38);
send_byte(0x80);
sbi(PORTB, adxl);
delay_ms(5);
cbi(PORTB, adxl);
send_byte(0xB8);
send_byte(0x00);
byte = SPDR;
sbi(PORTB, adxl);
delay_ms(5);
// printf("FIFO is: %x\n", byte);
// printf("data is: ");
// printf("x: %6d y: %6d z: %6d\n",dX,dY,dZ);
delay_ms(10000);
uart_putbyte(0x73);
delay_ms(10000);
while(1){
ReadAccelGBits(&dX0,&dX1,&dY0,&dY1,&dZ0,&dZ1);
//printf("%6d %6d %6d %6d %6d %6d\n",dX0,dX1,dY0,dY1,dZ0,dZ1);
uart_putbyte(dX0);
uart_putbyte(dX1);
uart_putbyte(dY0);
uart_putbyte(dY1);
uart_putbyte(dZ0);
uart_putbyte(dZ1);
/* x = data[1] << 8 | data[0];
y = data[3] << 8 | data[2];
z = data[5] << 8 | data[4];*/
/* uart_putbyte(0x61);
uart_putbyte(0x62);
uart_putbyte(0x63);
uart_putbyte(0x64);
uart_putbyte(0x65);
uart_putbyte(0x66);*/
// printf("%6d %6d %6d\n",(dX1<<8)|dX0,(dY1<<8)|dY0,(dZ1<<8)|dZ0);
/* uart_putbyte((dX1<<8)|dX0);
uart_putbyte((dY1<<8)|dY0);
uart_putbyte((dZ1<<8)|dZ0);
uart_putbyte(0x0A);*/
}
return(0);
}