375 lines
14 KiB
C
375 lines
14 KiB
C
/**
|
|
* \addtogroup mbxxx-platform
|
|
*
|
|
* @{
|
|
*/
|
|
/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
|
|
* File Name : hal_led.c
|
|
* Author : MCD Application Team
|
|
* Version : V1.0
|
|
* Date : September 2009
|
|
* Description : Driver for leds management on STM32W108 MBXXX boards
|
|
********************************************************************************
|
|
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
|
|
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
|
|
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
|
|
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
|
|
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
|
|
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
|
*******************************************************************************/
|
|
|
|
/* Includes ------------------------------------------------------------------*/
|
|
|
|
#include PLATFORM_HEADER
|
|
#include "mems.h"
|
|
#include "timer.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; \
|
|
} \
|
|
} \
|
|
}
|
|
|
|
/* 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
|
|
* 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
|
|
* reg_value is the value of the register to be written
|
|
* 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 i2c_buffer[2];
|
|
|
|
i2c_buffer[0] = reg_addr;
|
|
i2c_buffer[1] = reg_value;
|
|
|
|
return I2C_Send_Frame (slave_addr, i2c_buffer, 2);
|
|
}/* end i2c_write_reg() */
|
|
|
|
/*******************************************************************************
|
|
* Function Name : i2c_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
|
|
* pBuffer is the storage destination for the read data
|
|
* NoOfBytes is the amount of data to read
|
|
* 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)
|
|
{
|
|
return I2C_Receive_Frame (slave_addr, reg_addr, pBuffer, NoOfBytes);
|
|
}/* end i2c_read_reg() */
|
|
|
|
/*******************************************************************************
|
|
* Function Name : I2C_MEMS_Init
|
|
* Description : It performs basic MEMS register writes for initialization
|
|
* purposes
|
|
* Input : None
|
|
* Output : None
|
|
* Return : 1 if the device has been successfully initialized, 0 otherwise.
|
|
*******************************************************************************/
|
|
static uint8_t I2C_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;
|
|
|
|
return 1;
|
|
}/* end I2C_MEMS_Init() */
|
|
|
|
/*******************************************************************************
|
|
* Function Name : I2C_MEMS_On
|
|
* Description : It turn on the device.
|
|
* Input : None
|
|
* Output : None
|
|
* Return : 1 if the device has been successfully set to normal mode, 0 otherwise.
|
|
*******************************************************************************/
|
|
uint8_t MEMS_On (void)
|
|
{
|
|
return i2c_write_reg (kLIS3L02DQ_SLAVE_ADDR, CTRL_REG1, 0xC7);
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* Function Name : I2C_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)
|
|
{
|
|
return i2c_write_reg (kLIS3L02DQ_SLAVE_ADDR, CTRL_REG1, 0x87);
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* Function Name : I2C_MEMS_SetFullScale
|
|
* Description : It sets the full-scale range of the device.
|
|
* Input : range HIGH for high scale selection, LOW for low range.
|
|
* 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 i2c_buffer;
|
|
|
|
if(!i2c_read_reg(kLIS3L02DQ_SLAVE_ADDR, CTRL_REG1, &i2c_buffer, 1))
|
|
return 0;
|
|
|
|
if(range==MEMS_HIGH_RANGE){
|
|
i2c_buffer |= 0x20;
|
|
}
|
|
else {
|
|
i2c_buffer &= ~0x20;
|
|
}
|
|
|
|
if(!i2c_write_reg(kLIS3L02DQ_SLAVE_ADDR, CTRL_REG1, i2c_buffer))
|
|
return 0;
|
|
|
|
fullscale_state = range;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* Function Name : I2C_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)
|
|
{
|
|
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****/
|
|
/** @} */
|