#include "xparameters.h"
#include "xil_cache.h"
#include "xscugic.h"
#include "xil_exception.h"
#include "scugic_header.h"
#include "xdevcfg.h"
#include "devcfg_header.h"
#include "xdmaps.h"
#include "dmaps_header.h"
#include "xiicps.h"
#include "iicps_header.h"
#include "xqspips.h"
#include "qspips_header.h"
#include "xcanps.h"
#include "canps_header.h"
#include "xscutimer.h"
#include "scutimer_header.h"
#include "xscuwdt.h"
#include "scuwdt_header.h"
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>
#include <time.h>
#include <stdlib.h>
#include <getopt.h>
#include <unistd.h>
#include <errno.h>
//Test code for the LIS2DS12 motion and temperature sensor on MiniZed
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <fcntl.h>
//#include <ioctl.h>
#include <string.h>
//#include <termios.h>
#define u8 unsigned char
#define u16 unsigned short
#define I2C_FILE_NAME "/dev/i2c-0"
// The following constant defines the address of the IIC device on the IIC bus. Note that since
// the address is only 7 bits, this constant is the address divided by 2.
//#define MAGNETOMETER_ADDRESS 0x1E /* LIS3MDL on Arduino shield */
#define MINIZED_MOTION_SENSOR_ADDRESS_SA0_LO 0x1E /* 0011110b for LIS2DS12 on MiniZed when SA0 is pulled low*/
#define MINIZED_MOTION_SENSOR_ADDRESS_SA0_HI 0x1D /* 0011101b for LIS2DS12 on MiniZed when SA0 is pulled high*/
#define LIS2DS12_ACC_WHO_AM_I 0x43
/************** Device Register *******************/
#define LIS2DS12_ACC_SENSORHUB_OUT1 0X06
#define LIS2DS12_ACC_SENSORHUB_OUT2 0X07
#define LIS2DS12_ACC_SENSORHUB_OUT3 0X08
#define LIS2DS12_ACC_SENSORHUB_OUT4 0X09
#define LIS2DS12_ACC_SENSORHUB_OUT5 0X0A
#define LIS2DS12_ACC_SENSORHUB_OUT6 0X0B
#define LIS2DS12_ACC_MODULE_8BIT 0X0C
#define LIS2DS12_ACC_WHO_AM_I_REG 0X0F
#define LIS2DS12_ACC_CTRL1 0X20
#define LIS2DS12_ACC_CTRL2 0X21
#define LIS2DS12_ACC_CTRL3 0X22
#define LIS2DS12_ACC_CTRL4 0X23
#define LIS2DS12_ACC_CTRL5 0X24
#define LIS2DS12_ACC_FIFO_CTRL 0X25
#define LIS2DS12_ACC_OUT_T 0X26
#define LIS2DS12_ACC_STATUS 0X27
#define LIS2DS12_ACC_OUT_X_L 0X28
#define LIS2DS12_ACC_OUT_X_H 0X29
#define LIS2DS12_ACC_OUT_Y_L 0X2A
#define LIS2DS12_ACC_OUT_Y_H 0X2B
#define LIS2DS12_ACC_OUT_Z_L 0X2C
#define LIS2DS12_ACC_OUT_Z_H 0X2D
#define LIS2DS12_ACC_FIFO_THS 0X2E
#define LIS2DS12_ACC_FIFO_SRC 0X2F
#define LIS2DS12_ACC_FIFO_SAMPLES 0X30
#define LIS2DS12_ACC_TAP_6D_THS 0X31
#define LIS2DS12_ACC_INT_DUR 0X32
#define LIS2DS12_ACC_WAKE_UP_THS 0X33
#define LIS2DS12_ACC_WAKE_UP_DUR 0X34
#define LIS2DS12_ACC_FREE_FALL 0X35
#define LIS2DS12_ACC_STATUS_DUP 0X36
#define LIS2DS12_ACC_WAKE_UP_SRC 0X37
#define LIS2DS12_ACC_TAP_SRC 0X38
#define LIS2DS12_ACC_6D_SRC 0X39
#define LIS2DS12_ACC_STEP_C_MINTHS 0X3A
#define LIS2DS12_ACC_STEP_C_L 0X3B
#define LIS2DS12_ACC_STEP_C_H 0X3C
#define LIS2DS12_ACC_FUNC_CK_GATE 0X3D
#define LIS2DS12_ACC_FUNC_SRC 0X3E
#define LIS2DS12_ACC_FUNC_CTRL 0X3F
u8 send_byte;
u8 write_data [256];
u8 read_data [256];
int i2c_file;
useconds_t delay = 2000; //2ms
u8 i2c_device_addr = MINIZED_MOTION_SENSOR_ADDRESS_SA0_HI; //by default
//Global variables for LIS2DS12 readings:
u16 accel_X;
u16 accel_Y;
u16 accel_Z;
//u8 chip_temperature;
//u8 ps_led_color;
uint8_t MiniZed_IP_address[4];
bool bMiniZed_IP_address_OK;
bool bMiniZed_internet_access_OK;
u16 ToMinizedReportCount;
bool exit_mainloop;
static int set_i2c_register(int file,
unsigned char addr,
unsigned char reg,
unsigned char value) {
unsigned char outbuf[2];
struct i2c_rdwr_ioctl_data packets;
struct i2c_msg messages[1];
messages[0].addr = addr;
messages[0].flags = 0;
messages[0].len = sizeof(outbuf);
messages[0].buf = outbuf;
/* The first byte indicates which register we'll write */
outbuf[0] = reg;
/*
* The second byte indicates the value to write. Note that for many
* devices, we can write multiple, sequential registers at once by
* simply making outbuf bigger.
*/
outbuf[1] = value;
/* Transfer the i2c packets to the kernel and verify it worked */
packets.msgs = messages;
packets.nmsgs = 1;
/*if(ioctl(file, I2C_RDWR, &packets) < 0) {
perror("Unable to send data");
return 1;
}*/
//print("sono dentro set_i2c_register\n");
return 0;
}
static int get_i2c_register(int file,
unsigned char addr,
unsigned char reg,
unsigned char *val) {
unsigned char inbuf, outbuf;
struct i2c_rdwr_ioctl_data packets;
struct i2c_msg messages[2];
/*
* In order to read a register, we first do a "dummy write" by writing
* 0 bytes to the register we want to read from. This is similar to
* the packet in set_i2c_register, except it's 1 byte rather than 2.
*/
outbuf = reg;
messages[0].addr = addr;
messages[0].flags = 0;
messages[0].len = sizeof(outbuf);
messages[0].buf = &outbuf;
/* The data will get returned in this structure */
messages[1].addr = addr;
messages[1].flags = I2C_M_RD/* | I2C_M_NOSTART*/;
messages[1].len = sizeof(inbuf);
messages[1].buf = &inbuf;
/* Send the request to the kernel and get the result back */
packets.msgs = messages;
packets.nmsgs = 2;
/*if(ioctl(file, I2C_RDWR, &packets) < 0) {
perror("Unable to send data");
return 1;
}*/
*val = inbuf;
return 0;
}
static u8 LIS2DS12_WriteReg(u8 Reg, u8 *Bufp, u16 len)
{
if(set_i2c_register(i2c_file, i2c_device_addr, Reg, (u8)(Bufp[0])))
{
printf("Unable to set register!\n");
return (1);
}
return(0);
}
static u8 LIS2DS12_ReadReg(u8 Reg, u8 *Bufp, u16 len)
{
if(get_i2c_register(i2c_file, i2c_device_addr, Reg, &Bufp[0]))
{
printf("Unable to get register!\n");
return (1);
}
return(0);
}
static void sensor_init(void)
{
u8 who_am_i = 0;
i2c_device_addr = MINIZED_MOTION_SENSOR_ADDRESS_SA0_HI; //default
LIS2DS12_ReadReg(LIS2DS12_ACC_WHO_AM_I_REG, &who_am_i, 1);
//printf("With I2C device address 0x%02x received WhoAmI = 0x%02x\r\n", i2c_device_addr, who_am_i);
if (who_am_i != LIS2DS12_ACC_WHO_AM_I)
{
//maybe the address bit was changed, try the other one:
i2c_device_addr = MINIZED_MOTION_SENSOR_ADDRESS_SA0_LO;
LIS2DS12_ReadReg(LIS2DS12_ACC_WHO_AM_I_REG, &who_am_i, 1);
//printf("With I2C device address 0x%02x received WhoAmI = 0x%02x\r\n", i2c_device_addr, who_am_i);
}
send_byte = 0x00; //No auto increment
LIS2DS12_WriteReg(LIS2DS12_ACC_CTRL2, &send_byte, 1);
//Write 60h in CTRL1 // Turn on the accelerometer. 14-bit mode, ODR = 400 Hz, FS = 2g
send_byte = 0x60;
LIS2DS12_WriteReg(LIS2DS12_ACC_CTRL1, &send_byte, 1);
printf("CTL1 = 0x60 written\r\n");
//Enable interrupt
send_byte = 0x00; //Acc data-ready interrupt on INT1
LIS2DS12_WriteReg(LIS2DS12_ACC_CTRL4, &send_byte, 1);
printf("CTL4 = 0x01 written\r\n");
}
int read_motion(void)
{
//int iacceleration_X;
//int iacceleration_Y;
//int iacceleration_Z;
u8 read_value_LSB;
u8 read_value_MSB;
//u16 accel_X;
//u16 accel_Y;
//u16 accel_Z;
u8 accel_status;
u8 data_ready;
data_ready = 0;
while (!data_ready)
{ //wait for DRDY
LIS2DS12_ReadReg(LIS2DS12_ACC_STATUS, &accel_status, 1);
data_ready = accel_status & 0x01; //bit 0 = DRDY
usleep(5);//micro seconds
} //wait for DRDY
//Read X:
LIS2DS12_ReadReg(LIS2DS12_ACC_OUT_X_L, &read_value_LSB, 1);
LIS2DS12_ReadReg(LIS2DS12_ACC_OUT_X_H, &read_value_MSB, 1);
accel_X = (read_value_MSB << 8) + read_value_LSB;
//Read Y:
LIS2DS12_ReadReg(LIS2DS12_ACC_OUT_Y_L, &read_value_LSB, 1);
LIS2DS12_ReadReg(LIS2DS12_ACC_OUT_Y_H, &read_value_MSB, 1);
accel_Y = (read_value_MSB << 8) + read_value_LSB;
//Read Z:
LIS2DS12_ReadReg(LIS2DS12_ACC_OUT_Z_L, &read_value_LSB, 1);
LIS2DS12_ReadReg(LIS2DS12_ACC_OUT_Z_H, &read_value_MSB, 1);
accel_Z = (read_value_MSB << 8) + read_value_LSB;
//print(" accel_X, accel_Y, accel_Z\n");
return accel_X;
}
int main() {
int x;
sensor_init();
while(1){
x=read_motion();
}
}