MEMS I2C integration.

This patch allows the MEMS driver to use the i2c driver.
Signed-off-by: Maria Laura Stefanizzi <laura28582@gmail.com>
This commit is contained in:
Maria Laura Stefanizzi 2013-11-20 14:22:27 +01:00
parent a9c0768fd6
commit 22f39ab4ff
3 changed files with 126 additions and 297 deletions

View File

@ -57,55 +57,53 @@ static int
active(void)
{
uint8_t reg;
if(!i2c_read_reg (kLIS3L02DQ_SLAVE_ADDR,CTRL_REG1, &reg, 1))
if(!MEMS_Read_Reg (kLIS3L02DQ_SLAVE_ADDR, CTRL_REG1, &reg, 1))
return FALSE;
return (reg & 0x40) ? TRUE : FALSE ;
}
/*---------------------------------------------------------------------------*/
static int
value(int type)
{
int8_t i2c_data = 0;
uint8_t reg_addr;
switch(type) {
case ACC_X_AXIS:
reg_addr = OUTX_H;
break;
case ACC_Y_AXIS:
reg_addr = OUTY_H;
break;
case ACC_Z_AXIS:
reg_addr = OUTZ_H;
break;
default:
return 0;
}
i2c_read_reg(kLIS3L02DQ_SLAVE_ADDR, reg_addr, (uint8_t *)&i2c_data, 1);
if(MEMS_GetFullScale()==ACC_HIGH_RANGE){
return ((int16_t)i2c_data)*HIGH_RANGE_SENSITIVITY;
}
else {
return ((int16_t)i2c_data)*LOW_RANGE_SENSITIVITY;
return 0;
}
MEMS_Read_Reg(kLIS3L02DQ_SLAVE_ADDR, reg_addr, (uint8_t *)&i2c_data, 1);
if(MEMS_GetFullScale()==ACC_HIGH_RANGE){
return ((int16_t)i2c_data) * HIGH_RANGE_SENSITIVITY;
}
else {
return ((int16_t)i2c_data) * LOW_RANGE_SENSITIVITY;
}
}
/*---------------------------------------------------------------------------*/
static int
configure(int type, int value)
{
switch(type) {
case SENSORS_HW_INIT:
return Mems_Init();
return MEMS_Init();
case SENSORS_ACTIVE:
if(value){
if(MEMS_On()){
@ -115,17 +113,18 @@ configure(int type, int value)
return 0;
}
else
return MEMS_Off();
return MEMS_Off();
case ACC_RANGE:
return MEMS_SetFullScale((boolean)value);
case ACC_HPF:
case ACC_HPF:
if(value < ACC_HPF_DISABLE){
return i2c_write_reg(kLIS3L02DQ_SLAVE_ADDR, CTRL_REG2, (1<<4) | (uint8_t)value);
return MEMS_Write_Reg(kLIS3L02DQ_SLAVE_ADDR, CTRL_REG2,
(1<<4) | (uint8_t)value);
}
else {
return i2c_write_reg(kLIS3L02DQ_SLAVE_ADDR, CTRL_REG2, 0x00);
return MEMS_Write_Reg(kLIS3L02DQ_SLAVE_ADDR, CTRL_REG2, 0x00);
}
}
return 0;
@ -135,18 +134,15 @@ static int
status(int type)
{
switch(type) {
case SENSORS_READY:
return active();
}
return 0;
}
/*---------------------------------------------------------------------------*/
SENSORS_SENSOR(acc_sensor, ACC_SENSOR,
value, configure, status);
SENSORS_SENSOR(acc_sensor, ACC_SENSOR, value, configure, status);
/** @} */

View File

@ -23,205 +23,19 @@
#include PLATFORM_HEADER
#include "mems.h"
#include "timer.h"
#include "i2c.h"
/* Private define -- ---------------------------------------------------------*/
#define TIMEOUT 20000
#define SUCCESS 1
#define FAIL 0
#define SEND_BYTE(data) do{ SC2_DATA=(data); SC2_TWICTRL1 |= SC_TWISEND; }while(0)
#define WAIT_CMD_FIN() { \
struct timer t; \
timer_set(&t, CLOCK_SECOND/100); \
while((SC2_TWISTAT&SC_TWICMDFIN)!=SC_TWICMDFIN){ \
if(timer_expired(&t)){ \
return FAIL; \
} \
} \
}
#define WAIT_TX_FIN() { \
struct timer t; \
timer_set(&t, CLOCK_SECOND/100); \
while((SC2_TWISTAT&SC_TWITXFIN)!=SC_TWITXFIN){ \
if(timer_expired(&t)){ \
return FAIL; \
} \
} \
}
#define WAIT_RX_FIN() { \
struct timer t; \
timer_set(&t, CLOCK_SECOND/100); \
while((SC2_TWISTAT&SC_TWIRXFIN)!=SC_TWIRXFIN){ \
if(timer_expired(&t)){ \
return FAIL; \
} \
} \
}
#define FAIL 0
/* Private variables ---------------------------------------------------------*/
static boolean fullscale_state;
/* Private functions ---------------------------------------------------------*/
static uint8_t I2C_MEMS_Init (void);
//extern void halInternalResetWatchDog(void);
static uint8_t I2C_Send_Frame (uint8_t DeviceAddress, uint8_t *pBuffer, uint8_t NoOfBytes);
uint8_t i2c_write_reg (uint8_t slave_addr, uint8_t reg_addr, uint8_t reg_value);
//static uint8_t I2C_MEMS_Read (t_mems_data *mems_data);
/* Functions -----------------------------------------------------------------*/
/*******************************************************************************
* Function Name : Mems_Init
* Description : It inits mems
* Input : None
* Output : status
* Return : None
*******************************************************************************/
uint8_t Mems_Init(void)
{
uint8_t ret = 0;
// GPIO assignments
// PA1: SC2SDA (Serial Data)
// PA2: SC2SCL (Serial Clock)
//-----SC2 I2C Master GPIO configuration
TIM2_CCER &= 0xFFFFEEEE;
SC2_MODE = SC2_MODE_I2C;
GPIO_PACFGL &= 0xFFFFF00F;
GPIO_PACFGL |= 0x00000DD0;
SC2_RATELIN = 14; // generates standard 100kbps or 400kbps
SC2_RATEEXP = 1; // 3 yields 100kbps; 1 yields 400kbps
SC2_TWICTRL1 = 0; // start from a clean state
SC2_TWICTRL2 = 0; // start from a clean state
ret = I2C_MEMS_Init();
fullscale_state = MEMS_LOW_RANGE;
//Add later if really needed
#ifdef ST_DBG
if (!ret)
I2C_DeInit(MEMS_I2C);
#endif
return ret;
}/* end Mems_Init */
/*******************************************************************************
* Function Name : Mems_GetValue
* Description : It returns the 3 mems acceleration values related to x,y,z
* axes in mems_data
* Input : mems_data
* Output : status
* Return : None
*******************************************************************************/
//uint8_t Mems_GetValue(t_mems_data *mems_data)
//{
// uint8_t i;
// i = I2C_MEMS_Read(mems_data);
// return i;
//}
/* Private Functions ---------------------------------------------------------*/
/*******************************************************************************
* Function Name : I2C_Send_Frame
* Description : It sends I2C frame
* Input : DeviceAddress is the destination device address
* pBUffer is the buffer data
* NoOfBytes is the number of bytes
* Output : None
* Return : 1 if the frame has been successfully sent, 0 otherwise.
*******************************************************************************/
static uint8_t I2C_Send_Frame (uint8_t DeviceAddress, uint8_t *pBuffer, uint8_t NoOfBytes)
{
uint8_t i, data;
SC2_TWICTRL1 |= SC_TWISTART; // send start
WAIT_CMD_FIN();
SEND_BYTE(DeviceAddress); // send the address low byte
WAIT_TX_FIN();
// loop sending the data
for (i=0; i<NoOfBytes; i++) {
halInternalResetWatchDog();
data = *(pBuffer+i);
SEND_BYTE(data);
WAIT_TX_FIN();
}
SC2_TWICTRL1 |= SC_TWISTOP;
WAIT_CMD_FIN();
return SUCCESS;
}/* end I2C_Send_Frame() */
/*******************************************************************************
* Function Name : I2C_Receive_Frame
* Description : It receives an I2C frame and stores it in pBUffer parameter
* Input : slave_addr is the slave address
* reg_addr is the register address
* NoOfBytes is the numenr of bytes to read starting from reg_addr
* Output : I2C frame in pBUffer
* Return : 1 if the frame has been successfully received, 0 otherwise.
*******************************************************************************/
static uint8_t I2C_Receive_Frame (uint8_t slave_addr, uint8_t reg_addr, uint8_t *pBuffer, uint8_t NoOfBytes)
{
uint8_t i, addr = reg_addr;
if (NoOfBytes > 1)
addr += REPETIR;
SC2_TWICTRL1 |= SC_TWISTART; // send start
WAIT_CMD_FIN();
SEND_BYTE(slave_addr | 0x00); // send the address low byte
WAIT_TX_FIN();
SEND_BYTE(addr);
WAIT_TX_FIN();
SC2_TWICTRL1 |= SC_TWISTART; // send start
WAIT_CMD_FIN();
SEND_BYTE(slave_addr | 0x01); // send the address low byte
WAIT_TX_FIN();
// loop receiving the data
for (i=0;i<NoOfBytes;i++){
halInternalResetWatchDog();
if (i < (NoOfBytes - 1))
SC2_TWICTRL2 |= SC_TWIACK; // ack on receipt of data
else
SC2_TWICTRL2 &= ~SC_TWIACK; // don't ack if last one
SC2_TWICTRL1 |= SC_TWIRECV; // set to receive
WAIT_RX_FIN();
*(pBuffer+i) = SC2_DATA; // receive data
}
SC2_TWICTRL1 |= SC_TWISTOP; // send STOP
WAIT_CMD_FIN();
return SUCCESS;
}/* end I2C_Receive_Frame() */
/*******************************************************************************
* Function Name : i2c_write_reg
* Function Name : MEMS_Write_Reg
* Description : It writes a register on the I2C target
* Input : slave addr is the I2C target device
* reg_addr is the address of the register to be written
@ -229,18 +43,27 @@ static uint8_t I2C_Receive_Frame (uint8_t slave_addr, uint8_t reg_addr, uint8_t
* Output : None
* Return : 1 if the register has been successfully written, 0 otherwise.
*******************************************************************************/
uint8_t i2c_write_reg (uint8_t slave_addr, uint8_t reg_addr, uint8_t reg_value)
uint8_t
MEMS_Write_Reg (uint8_t slave_addr, uint8_t reg_addr, uint8_t reg_value)
{
uint8_t i2c_buffer[2];
i2c_buffer[0] = reg_addr;
i2c_buffer[1] = reg_value;
i2c_start();
return I2C_Send_Frame (slave_addr, i2c_buffer, 2);
}/* end i2c_write_reg() */
/* send the address low byte */
i2c_write(slave_addr);
/* send register address */
i2c_write(reg_addr);
/* send register value */
i2c_write(reg_value);
i2c_stop();
return SUCCESS;
}/* end MEMS_Write_Reg() */
/*******************************************************************************
* Function Name : i2c_read_reg
* Function Name : MEMS_Read_Reg
* Description : It reads a register on the I2C target
* Input : slave addr is the I2C target device
* reg_addr is the address of the register to be read
@ -249,37 +72,66 @@ uint8_t i2c_write_reg (uint8_t slave_addr, uint8_t reg_addr, uint8_t reg_value)
* Output : I2C frame
* Return : 1 if the register has been successfully read, 0 otherwise.
*******************************************************************************/
uint8_t i2c_read_reg (uint8_t slave_addr, uint8_t reg_addr, uint8_t *pBuffer, uint8_t NoOfBytes)
uint8_t
MEMS_Read_Reg (uint8_t slave_addr, uint8_t reg_addr, uint8_t *pBuffer,
uint8_t NoOfBytes)
{
return I2C_Receive_Frame (slave_addr, reg_addr, pBuffer, NoOfBytes);
}/* end i2c_read_reg() */
uint8_t i, ack, addr = reg_addr;
if (NoOfBytes > 1)
addr += REPETIR;
i2c_start();
/* send the address low byte */
i2c_write(slave_addr | 0x00);
i2c_write(addr);
i2c_start();
/* send the address low byte */
i2c_write(slave_addr | 0x01);
/* loop receiving the data */
for (i = 0; i < NoOfBytes; i++){
if (i < (NoOfBytes - 1))
/* ack on receipt of data */
ack = 1;
else
/* don't ack if last one */
ack = 0;
/* receive data */
*(pBuffer+i) = i2c_read(ack);
}
i2c_stop();
return SUCCESS;
}/* end MEMS_Read_Reg() */
/*******************************************************************************
* Function Name : I2C_MEMS_Init
* Description : It performs basic MEMS register writes for initialization
* purposes
* Function Name : MEMS_Init
* Description : It inits mems
* Input : None
* Output : None
* Return : 1 if the device has been successfully initialized, 0 otherwise.
* Output : status
* Return : None
*******************************************************************************/
static uint8_t I2C_MEMS_Init (void)
uint8_t
MEMS_Init(void)
{
uint8_t i = 0;
i += i2c_write_reg (kLIS3L02DQ_SLAVE_ADDR, STATUS_REG, 0x00); //no flag
i += i2c_write_reg (kLIS3L02DQ_SLAVE_ADDR, FF_WU_CFG, 0x00); // all off
i += i2c_write_reg (kLIS3L02DQ_SLAVE_ADDR, DD_CFG, 0x00); // all off
//i += i2c_write_reg (kLIS3L02DQ_SLAVE_ADDR, CTRL_REG2, (1<<4) | (1<<1) | (1 << 0));
i += i2c_write_reg (kLIS3L02DQ_SLAVE_ADDR, CTRL_REG2, 0x00);
//i += i2c_write_reg (kLIS3L02DQ_SLAVE_ADDR, CTRL_REG1, 0xC7);
i += i2c_write_reg (kLIS3L02DQ_SLAVE_ADDR, CTRL_REG1, 0x87);
if (i != 5)
return 0;
TIM2_CCER &= 0xFFFFEEEE;
MEMS_Write_Reg (kLIS3L02DQ_SLAVE_ADDR, STATUS_REG, 0x00); //no flag
MEMS_Write_Reg (kLIS3L02DQ_SLAVE_ADDR, FF_WU_CFG, 0x00); // all off
MEMS_Write_Reg (kLIS3L02DQ_SLAVE_ADDR, DD_CFG, 0x00); // all off
MEMS_Write_Reg (kLIS3L02DQ_SLAVE_ADDR, CTRL_REG2, 0x00);
MEMS_Write_Reg (kLIS3L02DQ_SLAVE_ADDR, CTRL_REG1, 0x87);
fullscale_state = MEMS_LOW_RANGE;
return 1;
}/* end I2C_MEMS_Init() */
}/* end MEMS_Init */
/*******************************************************************************
* Function Name : I2C_MEMS_On
@ -288,21 +140,23 @@ static uint8_t I2C_MEMS_Init (void)
* Output : None
* Return : 1 if the device has been successfully set to normal mode, 0 otherwise.
*******************************************************************************/
uint8_t MEMS_On (void)
uint8_t
MEMS_On (void)
{
return i2c_write_reg (kLIS3L02DQ_SLAVE_ADDR, CTRL_REG1, 0xC7);
return MEMS_Write_Reg (kLIS3L02DQ_SLAVE_ADDR, CTRL_REG1, 0xC7);
}
/*******************************************************************************
* Function Name : I2C_MEMS_Off
* Function Name : MEMS_Off
* Description : It turn off the device.
* Input : None
* Output : None
* Return : 1 if the device has been successfully set to power-down mode, 0 otherwise.
*******************************************************************************/
uint8_t MEMS_Off (void)
uint8_t
MEMS_Off (void)
{
return i2c_write_reg (kLIS3L02DQ_SLAVE_ADDR, CTRL_REG1, 0x87);
return MEMS_Write_Reg (kLIS3L02DQ_SLAVE_ADDR, CTRL_REG1, 0x87);
}
/*******************************************************************************
@ -312,13 +166,13 @@ uint8_t MEMS_Off (void)
* Output : None
* Return : 1 if the device has been successfully set to full scale mode, 0 otherwise.
*******************************************************************************/
uint8_t MEMS_SetFullScale (boolean range)
uint8_t
MEMS_SetFullScale (boolean range)
{
uint8_t i2c_buffer;
if(!i2c_read_reg(kLIS3L02DQ_SLAVE_ADDR, CTRL_REG1, &i2c_buffer, 1))
return 0;
MEMS_Read_Reg(kLIS3L02DQ_SLAVE_ADDR, CTRL_REG1, &i2c_buffer, 1);
if(range==MEMS_HIGH_RANGE){
i2c_buffer |= 0x20;
}
@ -326,49 +180,26 @@ uint8_t MEMS_SetFullScale (boolean range)
i2c_buffer &= ~0x20;
}
if(!i2c_write_reg(kLIS3L02DQ_SLAVE_ADDR, CTRL_REG1, i2c_buffer))
return 0;
MEMS_Write_Reg(kLIS3L02DQ_SLAVE_ADDR, CTRL_REG1, i2c_buffer);
fullscale_state = range;
return 1;
}
/*******************************************************************************
* Function Name : I2C_MEMS_GetFullScale
* Function Name : MEMS_GetFullScale
* Description : It get the full-scale range of the device.
* Input : None
* Output : None
* Return : range HIGH for high scale selection, LOW for low range.
*******************************************************************************/
boolean MEMS_GetFullScale (void)
{
boolean
MEMS_GetFullScale (void)
{
return fullscale_state;
}
/*******************************************************************************
* Function Name : I2C_MEMS_Read
* Description : It reads 3 axes acceleration data from mems
* Input : None
* Output : mems_data
* Return : 1 if acceleration data has been successfully read, 0 otherwise
*******************************************************************************/
//static uint8_t I2C_MEMS_Read (t_mems_data *mems_data)
//{
// uint8_t i, i2c_buffer[8];
//
// i = i2c_read_reg (kLIS3L02DQ_SLAVE_ADDR, OUTX_L, i2c_buffer, 8);
//
// mems_data->outx_h = i2c_buffer[0];
// mems_data->outx_l = i2c_buffer[1];
// mems_data->outy_h = i2c_buffer[2];
// mems_data->outy_l = i2c_buffer[3];
// mems_data->outz_h = i2c_buffer[4];
// mems_data->outz_l = i2c_buffer[5];
//
// return i;
//}/* end I2C_MEMS_Read() */
/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/
/** @} */

View File

@ -49,17 +49,19 @@ typedef struct {
/* Functions -----------------------------------------------------------------*/
/* Mems Initialization function */
uint8_t Mems_Init(void);
uint8_t MEMS_Init(void);
uint8_t MEMS_On(void);
uint8_t MEMS_Off(void);
uint8_t MEMS_SetFullScale(boolean range);
boolean MEMS_GetFullScale(void);
/* Get mems acceleration values */
uint8_t Mems_GetValue(t_mems_data *mems_data);
uint8_t MEMS_Read_Reg (uint8_t slave_addr, uint8_t reg_addr, uint8_t *pBuffer,
uint8_t NoOfBytes);
uint8_t MEMS_Write_Reg (uint8_t slave_addr, uint8_t reg_addr,
uint8_t reg_value);
#endif /*MEMS_H_ */
/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/
/** @} */