mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2024-11-30 08:24:11 +01:00
213 lines
5.8 KiB
C
213 lines
5.8 KiB
C
|
/**
|
||
|
******************************************************************************
|
||
|
* @addtogroup PIOS PIOS Core hardware abstraction layer
|
||
|
* @{
|
||
|
* @addtogroup PIOS_BMA180 BMA180 Functions
|
||
|
* @brief Deals with the hardware interface to the BMA180 3-axis accelerometer
|
||
|
* @{
|
||
|
*
|
||
|
* @file pios_bma180.h
|
||
|
* @author David "Buzz" Carlson (buzz@chebuzz.com)
|
||
|
* The OpenPilot Team, http://www.openpilot.org Copyright (C) 2011.
|
||
|
* @brief PiOS BMA180 digital accelerometer driver.
|
||
|
* - Driver for the BMA180 digital accelerometer on the SPI bus.
|
||
|
* @see The GNU Public License (GPL) Version 3
|
||
|
*
|
||
|
*****************************************************************************/
|
||
|
/*
|
||
|
* This program is free software; you can redistribute it and/or modify
|
||
|
* it under the terms of the GNU General Public License as published by
|
||
|
* the Free Software Foundation; either version 3 of the License, or
|
||
|
* (at your option) any later version.
|
||
|
*
|
||
|
* This program is distributed in the hope that it will be useful, but
|
||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||
|
* for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU General Public License along
|
||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||
|
*/
|
||
|
|
||
|
#include "pios.h"
|
||
|
|
||
|
static uint32_t PIOS_SPI_ACCEL;
|
||
|
static uint8_t EEPROM_WRITEABLE=0;
|
||
|
|
||
|
|
||
|
/**
|
||
|
* @brief Claim the SPI bus for the accel communications and select this chip
|
||
|
*/
|
||
|
void PIOS_BMA180_ClaimBus()
|
||
|
{
|
||
|
PIOS_SPI_ClaimBus(PIOS_SPI_ACCEL);
|
||
|
PIOS_BMA_ENABLE;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Release the SPI bus for the accel communications and end the transaction
|
||
|
*/
|
||
|
void PIOS_BMA180_ReleaseBus()
|
||
|
{
|
||
|
PIOS_BMA_DISABLE;
|
||
|
PIOS_SPI_ReleaseBus(PIOS_SPI_ACCEL);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Set the EEPROM write-enable bit. Must be set to 1 (unlocked) before writing control registers.
|
||
|
* @return none
|
||
|
* @param _we[in] bit to set, 1 to enable writes or 0 to disable writes
|
||
|
*/
|
||
|
void PIOS_BMA180_WriteEnable(uint8_t _we)
|
||
|
{
|
||
|
uint8_t addr_reg[2] = {BMA_WE_ADDR,0};
|
||
|
|
||
|
PIOS_BMA180_ClaimBus();
|
||
|
addr_reg[1] = PIOS_SPI_TransferByte(PIOS_SPI_ACCEL,(0x80 | BMA_WE_ADDR) );
|
||
|
addr_reg[1] &= 0xEF;
|
||
|
addr_reg[1] |= ( (0x01 & _we) << 4);
|
||
|
PIOS_SPI_TransferBlock(PIOS_SPI_ACCEL,addr_reg,NULL,sizeof(addr_reg),NULL);
|
||
|
PIOS_BMA180_ReleaseBus();
|
||
|
EEPROM_WRITEABLE=_we;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Read a register from BMA180
|
||
|
* @returns The register value
|
||
|
* @param reg[in] Register address to be read
|
||
|
*/
|
||
|
uint8_t PIOS_BMA180_GetReg(uint8_t reg)
|
||
|
{
|
||
|
uint8_t data;
|
||
|
PIOS_BMA180_ClaimBus();
|
||
|
data = PIOS_SPI_TransferByte(PIOS_SPI_ACCEL,(0x80 | reg) );
|
||
|
PIOS_BMA180_ReleaseBus();
|
||
|
return(data);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Write a BMA180 register. EEPROM must be unlocked before calling this function.
|
||
|
* @return none
|
||
|
* @param reg[in] address of register to be written
|
||
|
* @param data[in] data that is to be written to register
|
||
|
*/
|
||
|
void PIOS_BMA180_SetReg(uint8_t reg, uint8_t data)
|
||
|
{
|
||
|
uint8_t reg_data[2] = { (0x7F & reg), data};
|
||
|
PIOS_BMA180_ClaimBus();
|
||
|
PIOS_SPI_TransferBlock(PIOS_SPI_ACCEL,reg_data,NULL,2,NULL);
|
||
|
PIOS_BMA180_ReleaseBus();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Select the bandwidth the digital filter pass allows.
|
||
|
* @return none
|
||
|
* @param rate[in] Bandwidth setting to be used
|
||
|
*
|
||
|
* EEPROM must be write-enabled before calling this function.
|
||
|
*/
|
||
|
void PIOS_BMA180_SelectBW(uint8_t bw)
|
||
|
{
|
||
|
uint8_t addr_reg[2] = { BMA_BW_ADDR, 0};
|
||
|
|
||
|
PIOS_BMA180_ClaimBus();
|
||
|
addr_reg[1] = PIOS_SPI_TransferByte(PIOS_SPI_ACCEL,(0x80|BMA_BW_ADDR));
|
||
|
addr_reg[1] &= 0x0F;
|
||
|
addr_reg[1] |= (bw << 4);
|
||
|
PIOS_SPI_TransferBlock(PIOS_SPI_ACCEL,addr_reg,NULL,sizeof(addr_reg),NULL);
|
||
|
PIOS_BMA180_ReleaseBus();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Select the full scale acceleration range.
|
||
|
* @return none
|
||
|
* @param rate[in] Range setting to be used
|
||
|
*
|
||
|
*/
|
||
|
void PIOS_BMA180_SetRange(uint8_t range)
|
||
|
{
|
||
|
uint8_t addr_reg[2] = { BMA_RANGE_ADDR, 0};
|
||
|
|
||
|
PIOS_BMA180_ClaimBus();
|
||
|
addr_reg[1] = PIOS_SPI_TransferByte(PIOS_SPI_ACCEL,(0x80|BMA_RANGE_ADDR));
|
||
|
addr_reg[1] &= 0x0F;
|
||
|
addr_reg[1] |= (range << 4);
|
||
|
PIOS_SPI_TransferBlock(PIOS_SPI_ACCEL,addr_reg,NULL,sizeof(addr_reg),NULL);
|
||
|
PIOS_BMA180_ReleaseBus();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Connect to the correct SPI bus
|
||
|
*/
|
||
|
void PIOS_BMA180_Attach(uint32_t spi_id)
|
||
|
{
|
||
|
PIOS_SPI_ACCEL = spi_id;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Initialize with good default settings
|
||
|
*/
|
||
|
void PIOS_BMA180_Init()
|
||
|
{
|
||
|
/*
|
||
|
PIOS_BMA180_ReleaseBus();
|
||
|
PIOS_BMA180_WriteEnable(1);
|
||
|
PIOS_BMA180_SelectRate(BMA_RATE_3200);
|
||
|
PIOS_BMA180_SetRange(BMA_RANGE_8G);
|
||
|
PIOS_BMA180_FifoDepth(16);
|
||
|
PIOS_BMA180_SetMeasure(1);
|
||
|
PIOS_BMA180_WriteEnable(0);
|
||
|
*/
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Read a single set of values from the x y z channels
|
||
|
* @returns The number of samples remaining in the fifo
|
||
|
*/
|
||
|
uint8_t PIOS_BMA180_Read(struct pios_bma180_data * data)
|
||
|
{
|
||
|
// To save memory use same buffer for in and out but offset by
|
||
|
// a byte
|
||
|
uint8_t buf[7] = {0,0,0,0,0,0};
|
||
|
uint8_t rec[7] = {0,0,0,0,0,0};
|
||
|
buf[0] = BMA_X_LSB_ADDR | 0x80 ; // Multibyte read starting at X LSB
|
||
|
|
||
|
PIOS_BMA180_ClaimBus();
|
||
|
PIOS_SPI_TransferBlock(PIOS_SPI_ACCEL,&buf[0],&rec[0],7,NULL);
|
||
|
PIOS_BMA180_ReleaseBus();
|
||
|
|
||
|
// | MSB | LSB | 0 | new_data |
|
||
|
data->x = ( (rec[2] << 8) | rec[1] ) >> 2;
|
||
|
data->y = ( (rec[4] << 8) | rec[3] ) >> 2;
|
||
|
data->z = ( (rec[6] << 8) | rec[5] ) >> 2;
|
||
|
|
||
|
return 0; // return number of remaining entries
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Test SPI and chip functionality by reading chip ID register
|
||
|
* @return 0 if test failed, any other value signals test succeeded.
|
||
|
*
|
||
|
*/
|
||
|
uint8_t PIOS_BMA180_Test()
|
||
|
{
|
||
|
uint8_t data = 0;
|
||
|
uint8_t pass = 0;
|
||
|
PIOS_BMA180_ClaimBus();
|
||
|
data = PIOS_SPI_TransferByte(PIOS_SPI_ACCEL,(0x80 | BMA_CHIPID_ADDR) );
|
||
|
data &= 0x07;
|
||
|
if(0x03 == data)
|
||
|
pass = 1;
|
||
|
data = PIOS_SPI_TransferByte(PIOS_SPI_ACCEL,(0x80 | BMA_VERSION_ADDR) );
|
||
|
if(0x12 == data)
|
||
|
pass = 1 && pass; // Only passes if first and second test passS
|
||
|
PIOS_BMA180_ReleaseBus();
|
||
|
return pass;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @}
|
||
|
* @}
|
||
|
*/
|