Now you can download a copy of these docs so you can use them offline! Download now
ADXL345_SPI.cpp
00001 /*----------------------------------------------------------------------------*/ 00002 /* Copyright (c) FIRST 2008. All Rights Reserved. */ 00003 /* Open Source Software - may be modified and shared by FRC teams. The code */ 00004 /* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */ 00005 /*----------------------------------------------------------------------------*/ 00006 00007 #include "ADXL345_SPI.h" 00008 #include "DigitalInput.h" 00009 #include "DigitalOutput.h" 00010 #include "SPI.h" 00011 00012 const UINT8 ADXL345_SPI::kPowerCtlRegister; 00013 const UINT8 ADXL345_SPI::kDataFormatRegister; 00014 const UINT8 ADXL345_SPI::kDataRegister; 00015 const double ADXL345_SPI::kGsPerLSB; 00016 00026 ADXL345_SPI::ADXL345_SPI(DigitalOutput &clk, DigitalOutput &mosi, DigitalInput &miso, 00027 DigitalOutput &cs, DataFormat_Range range) 00028 : m_clk (NULL) 00029 , m_mosi (NULL) 00030 , m_miso (NULL) 00031 , m_cs (NULL) 00032 , m_spi (NULL) 00033 { 00034 Init(&clk, &mosi, &miso, &cs, range); 00035 } 00036 00046 ADXL345_SPI::ADXL345_SPI(DigitalOutput *clk, DigitalOutput *mosi, DigitalInput *miso, 00047 DigitalOutput *cs, DataFormat_Range range) 00048 : m_clk (NULL) 00049 , m_mosi (NULL) 00050 , m_miso (NULL) 00051 , m_cs (NULL) 00052 , m_spi (NULL) 00053 { 00054 Init(clk, mosi, miso, cs, range); 00055 } 00056 00067 ADXL345_SPI::ADXL345_SPI(UINT8 moduleNumber, UINT32 clk, UINT32 mosi, UINT32 miso, 00068 UINT32 cs, ADXL345_SPI::DataFormat_Range range) 00069 : m_clk (NULL) 00070 , m_mosi (NULL) 00071 , m_miso (NULL) 00072 , m_cs (NULL) 00073 , m_spi (NULL) 00074 { 00075 m_clk = new DigitalOutput(moduleNumber, clk); 00076 m_mosi = new DigitalOutput(moduleNumber, mosi); 00077 m_miso = new DigitalInput(moduleNumber, miso); 00078 m_cs = new DigitalOutput(moduleNumber, cs); 00079 Init(m_clk, m_mosi, m_miso, m_cs, range); 00080 } 00081 00085 void ADXL345_SPI::Init(DigitalOutput *clk, DigitalOutput *mosi, DigitalInput *miso, 00086 DigitalOutput *cs, DataFormat_Range range) 00087 { 00088 if (clk != NULL && mosi != NULL && miso != NULL && cs != NULL) 00089 { 00090 m_spi = new SPI(clk, mosi, miso); 00091 m_spi->SetMSBFirst(); 00092 m_spi->SetSampleDataOnRising(); 00093 m_spi->SetSlaveSelect(cs, SPI::kChipSelect, false); 00094 m_spi->SetClockActiveLow(); 00095 // 8-bit address and 8-bit data 00096 m_spi->SetBitsPerWord(16); 00097 m_spi->ApplyConfig(); 00098 m_spi->ClearReceivedData(); 00099 00100 // Turn on the measurements 00101 m_spi->Write((kPowerCtlRegister << 8) | kPowerCtl_Measure); 00102 m_spi->Read(); 00103 // Specify the data format to read 00104 m_spi->Write((kDataFormatRegister << 8) | kDataFormat_FullRes | (UINT8)(range & 0x03)); 00105 m_spi->Read(); 00106 00107 // 8-bit address and 16-bit data 00108 m_spi->SetBitsPerWord(24); 00109 m_spi->ApplyConfig(); 00110 } 00111 } 00112 00116 ADXL345_SPI::~ADXL345_SPI() 00117 { 00118 delete m_spi; 00119 m_spi = NULL; 00120 delete m_cs; 00121 m_cs = NULL; 00122 delete m_miso; 00123 m_miso = NULL; 00124 delete m_mosi; 00125 m_mosi = NULL; 00126 delete m_clk; 00127 m_clk = NULL; 00128 } 00129 00136 double ADXL345_SPI::GetAcceleration(ADXL345_SPI::Axes axis) 00137 { 00138 INT16 rawAccel = 0; 00139 if(m_spi) 00140 { 00141 m_spi->Write(((kAddress_Read | kAddress_MultiByte | kDataRegister) + (UINT8)axis) << 16); 00142 rawAccel = (UINT16)m_spi->Read(); 00143 00144 // Sensor is little endian... swap bytes 00145 rawAccel = ((rawAccel >> 8) & 0xFF) | (rawAccel << 8); 00146 } 00147 return rawAccel * kGsPerLSB; 00148 } 00149 00155 ADXL345_SPI::AllAxes ADXL345_SPI::GetAccelerations() 00156 { 00157 AllAxes data = {0.0}; 00158 INT16 rawData[3]; 00159 if (m_spi) 00160 { 00161 SPI::tFrameMode mode; 00162 bool activeLow; 00163 00164 // Backup original settings. 00165 DigitalOutput *cs = m_spi->GetSlaveSelect(&mode, &activeLow); 00166 UINT32 bitsPerWord = m_spi->GetBitsPerWord(); 00167 00168 // Initialize the chip select to inactive. 00169 cs->Set(activeLow); 00170 00171 // Control the chip select manually. 00172 m_spi->SetSlaveSelect(NULL); 00173 // 8-bit address 00174 m_spi->SetBitsPerWord(8); 00175 m_spi->ApplyConfig(); 00176 00177 // Assert chip select. 00178 cs->Set(!activeLow); 00179 00180 // Select the data address. 00181 m_spi->Write(kAddress_Read | kAddress_MultiByte | kDataRegister); 00182 m_spi->Read(); 00183 00184 // 16-bits for each axis 00185 m_spi->SetBitsPerWord(16); 00186 m_spi->ApplyConfig(); 00187 00188 for (INT32 i=0; i<3; i++) 00189 { 00190 // SPI Interface can't read enough data in a single transaction to read all axes at once. 00191 rawData[i] = (UINT16)m_spi->Read(true); 00192 // Sensor is little endian... swap bytes 00193 rawData[i] = ((rawData[i] >> 8) & 0xFF) | (rawData[i] << 8); 00194 } 00195 00196 // Deassert chip select. 00197 cs->Set(activeLow); 00198 00199 // Restore original settings. 00200 m_spi->SetSlaveSelect(cs, mode, activeLow); 00201 m_spi->SetBitsPerWord(bitsPerWord); 00202 m_spi->ApplyConfig(); 00203 00204 data.XAxis = rawData[0] * kGsPerLSB; 00205 data.YAxis = rawData[1] * kGsPerLSB; 00206 data.ZAxis = rawData[2] * kGsPerLSB; 00207 } 00208 return data; 00209 } 00210
Generated on Thu Jan 12 2012 22:35:17 for WPILibC++ by
1.7.1