Interface for an LIS302 accelerometer, using the SPI interface

Dependents:   LIS302_HelloWorld mbed_line_camera

Committer:
simon
Date:
Tue Jun 08 13:34:48 2010 +0000
Revision:
1:fe7ccd3480e6

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
simon 1:fe7ccd3480e6 1 /* mbed LIS302 Accelerometer Library
simon 1:fe7ccd3480e6 2 * Copyright (c) 2008-2010, sford, cstyles, wreynolds
simon 1:fe7ccd3480e6 3 *
simon 1:fe7ccd3480e6 4 * Permission is hereby granted, free of charge, to any person obtaining a copy
simon 1:fe7ccd3480e6 5 * of this software and associated documentation files (the "Software"), to deal
simon 1:fe7ccd3480e6 6 * in the Software without restriction, including without limitation the rights
simon 1:fe7ccd3480e6 7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
simon 1:fe7ccd3480e6 8 * copies of the Software, and to permit persons to whom the Software is
simon 1:fe7ccd3480e6 9 * furnished to do so, subject to the following conditions:
simon 1:fe7ccd3480e6 10 *
simon 1:fe7ccd3480e6 11 * The above copyright notice and this permission notice shall be included in
simon 1:fe7ccd3480e6 12 * all copies or substantial portions of the Software.
simon 1:fe7ccd3480e6 13 *
simon 1:fe7ccd3480e6 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
simon 1:fe7ccd3480e6 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
simon 1:fe7ccd3480e6 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
simon 1:fe7ccd3480e6 17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
simon 1:fe7ccd3480e6 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
simon 1:fe7ccd3480e6 19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
simon 1:fe7ccd3480e6 20 * THE SOFTWARE.
simon 1:fe7ccd3480e6 21 */
simon 1:fe7ccd3480e6 22
simon 1:fe7ccd3480e6 23 #include "LIS302.h"
simon 1:fe7ccd3480e6 24 #include "mbed.h"
simon 1:fe7ccd3480e6 25
simon 1:fe7ccd3480e6 26 #define LIS302_WHOAMI 0x0F
simon 1:fe7ccd3480e6 27 #define LIS302_CTRL_REG1 0x20
simon 1:fe7ccd3480e6 28 #define LIS302_CTRL_REG2 0x21
simon 1:fe7ccd3480e6 29 #define LIS302_CTRL_REG3 0x22
simon 1:fe7ccd3480e6 30 #define LIS302_HP_FILTER_RST 0x23
simon 1:fe7ccd3480e6 31 #define LIS302_STATUS_REG 0x27
simon 1:fe7ccd3480e6 32 #define LIS302_OUTX 0x29
simon 1:fe7ccd3480e6 33 #define LIS302_OUTY 0x2B
simon 1:fe7ccd3480e6 34 #define LIS302_OUTZ 0x2D
simon 1:fe7ccd3480e6 35 #define LIS302_FF_WU_CFG1 0x30
simon 1:fe7ccd3480e6 36 #define LIS302_FF_WU_SRC_1 0x31
simon 1:fe7ccd3480e6 37 #define LIS302_FF_WU_THS_1 0x32
simon 1:fe7ccd3480e6 38 #define LIS302_FF_WU_DURATION_1 0x33
simon 1:fe7ccd3480e6 39 #define LIS302_FF_WU_CFG_2 0x34
simon 1:fe7ccd3480e6 40 #define LIS302_FF_WU_SRC_2 0x35
simon 1:fe7ccd3480e6 41 #define LIS302_FF_WU_THS_2 0x36
simon 1:fe7ccd3480e6 42 #define LIS302_FF_WU_DURATION_2 0x37
simon 1:fe7ccd3480e6 43 #define LIS302_CLICK_CFG 0x38
simon 1:fe7ccd3480e6 44 #define LIS302_CLICK_SRC 0x39
simon 1:fe7ccd3480e6 45 #define LIS302_CLICK_THSY_X 0x3B
simon 1:fe7ccd3480e6 46 #define LIS302_CLICK_THSZ 0x3C
simon 1:fe7ccd3480e6 47 #define LIS302_READ 0x80
simon 1:fe7ccd3480e6 48 #define LIS302_WRITE 0x00
simon 1:fe7ccd3480e6 49
simon 1:fe7ccd3480e6 50 #define LIS302_STATUS_X_AVAILABLE 0x1
simon 1:fe7ccd3480e6 51 #define LIS302_STATUS_Y_AVAILABLE 0x2
simon 1:fe7ccd3480e6 52 #define LIS302_STATUS_Z_AVAILABLE 0x4
simon 1:fe7ccd3480e6 53
simon 1:fe7ccd3480e6 54 #define FACTOR_2g 55.6
simon 1:fe7ccd3480e6 55 #define FACTOR_8g 13.9
simon 1:fe7ccd3480e6 56
simon 1:fe7ccd3480e6 57 LIS302::LIS302(PinName mosi, PinName miso, PinName clk, PinName ncs)
simon 1:fe7ccd3480e6 58 : _spi(mosi, miso, clk), _ncs(ncs) {
simon 1:fe7ccd3480e6 59
simon 1:fe7ccd3480e6 60 // Make sure CS is high
simon 1:fe7ccd3480e6 61 _ncs = 1;
simon 1:fe7ccd3480e6 62
simon 1:fe7ccd3480e6 63 // Set up the spi interface
simon 1:fe7ccd3480e6 64 _spi.format(8, 3);
simon 1:fe7ccd3480e6 65 _spi.frequency(1000000);
simon 1:fe7ccd3480e6 66
simon 1:fe7ccd3480e6 67 // Write to CTRL_REG1
simon 1:fe7ccd3480e6 68 _ncs = 0;
simon 1:fe7ccd3480e6 69 _spi.write(LIS302_WRITE | LIS302_CTRL_REG1);
simon 1:fe7ccd3480e6 70 _spi.write (0x47);
simon 1:fe7ccd3480e6 71 _ncs = 1;
simon 1:fe7ccd3480e6 72
simon 1:fe7ccd3480e6 73 // Write to CTRL_REG2
simon 1:fe7ccd3480e6 74 _ncs = 0;
simon 1:fe7ccd3480e6 75 _spi.write(LIS302_WRITE | LIS302_CTRL_REG2);
simon 1:fe7ccd3480e6 76 _spi.write (0x0); // This is default anyway
simon 1:fe7ccd3480e6 77 _ncs = 1;
simon 1:fe7ccd3480e6 78
simon 1:fe7ccd3480e6 79 // Write to CTRL_REG3
simon 1:fe7ccd3480e6 80 _ncs = 0;
simon 1:fe7ccd3480e6 81 _spi.write(LIS302_WRITE | LIS302_CTRL_REG3);
simon 1:fe7ccd3480e6 82 _spi.write (0x0); // This is default anyway
simon 1:fe7ccd3480e6 83 _ncs = 1;
simon 1:fe7ccd3480e6 84
simon 1:fe7ccd3480e6 85 range(0);
simon 1:fe7ccd3480e6 86 calibrate();
simon 1:fe7ccd3480e6 87 }
simon 1:fe7ccd3480e6 88
simon 1:fe7ccd3480e6 89 float LIS302::x() {
simon 1:fe7ccd3480e6 90 // wait for a new sample
simon 1:fe7ccd3480e6 91 while(!(status() & LIS302_STATUS_X_AVAILABLE));
simon 1:fe7ccd3480e6 92
simon 1:fe7ccd3480e6 93 _ncs = 0;
simon 1:fe7ccd3480e6 94 _spi.write(LIS302_READ | LIS302_OUTX);
simon 1:fe7ccd3480e6 95 signed char raw = _spi.write(0x00);
simon 1:fe7ccd3480e6 96 _ncs = 1;
simon 1:fe7ccd3480e6 97
simon 1:fe7ccd3480e6 98 float gradient = (2.0/(_maxx-_minx));
simon 1:fe7ccd3480e6 99 return (gradient*(float)(raw)/_factor)+((-gradient*_maxx)+1);
simon 1:fe7ccd3480e6 100 }
simon 1:fe7ccd3480e6 101
simon 1:fe7ccd3480e6 102 float LIS302::y() {
simon 1:fe7ccd3480e6 103 // wait for a new sample
simon 1:fe7ccd3480e6 104 while(!(status() & LIS302_STATUS_Y_AVAILABLE));
simon 1:fe7ccd3480e6 105
simon 1:fe7ccd3480e6 106 _ncs = 0;
simon 1:fe7ccd3480e6 107 _spi.write(LIS302_READ | LIS302_OUTY);
simon 1:fe7ccd3480e6 108 signed char raw = _spi.write(0x00);
simon 1:fe7ccd3480e6 109 _ncs = 1;
simon 1:fe7ccd3480e6 110
simon 1:fe7ccd3480e6 111 float gradient = (2.0/(_maxy-_miny));
simon 1:fe7ccd3480e6 112 return (gradient*(float)(raw)/_factor)+((-gradient*_maxy)+1);
simon 1:fe7ccd3480e6 113 }
simon 1:fe7ccd3480e6 114
simon 1:fe7ccd3480e6 115 float LIS302::z() {
simon 1:fe7ccd3480e6 116 // wait for a new sample
simon 1:fe7ccd3480e6 117 while(!(status() & LIS302_STATUS_Z_AVAILABLE));
simon 1:fe7ccd3480e6 118
simon 1:fe7ccd3480e6 119 _ncs = 0;
simon 1:fe7ccd3480e6 120 _spi.write(LIS302_READ | LIS302_OUTZ);
simon 1:fe7ccd3480e6 121 signed char raw = _spi.write(0x00);
simon 1:fe7ccd3480e6 122 _ncs = 1;
simon 1:fe7ccd3480e6 123
simon 1:fe7ccd3480e6 124 float gradient = (2.0/(_maxz-_minz));
simon 1:fe7ccd3480e6 125 return (gradient*(float)(raw)/_factor)+((-gradient*_maxz)+1);
simon 1:fe7ccd3480e6 126 }
simon 1:fe7ccd3480e6 127
simon 1:fe7ccd3480e6 128 void LIS302::range(int g) {
simon 1:fe7ccd3480e6 129
simon 1:fe7ccd3480e6 130 // fetch the current CRTL_REG1
simon 1:fe7ccd3480e6 131 _ncs = 0;
simon 1:fe7ccd3480e6 132 _spi.write(LIS302_READ | LIS302_CTRL_REG1);
simon 1:fe7ccd3480e6 133 int value = _spi.write(0x00);
simon 1:fe7ccd3480e6 134 _ncs = 1;
simon 1:fe7ccd3480e6 135
simon 1:fe7ccd3480e6 136 // set the range bit, and the calculation factor
simon 1:fe7ccd3480e6 137 if(g) {
simon 1:fe7ccd3480e6 138 value |= 0x20; // 8g
simon 1:fe7ccd3480e6 139 _factor = FACTOR_8g;
simon 1:fe7ccd3480e6 140 } else {
simon 1:fe7ccd3480e6 141 value &= ~0x20; // 2g
simon 1:fe7ccd3480e6 142 _factor = FACTOR_2g;
simon 1:fe7ccd3480e6 143 }
simon 1:fe7ccd3480e6 144
simon 1:fe7ccd3480e6 145 _ncs = 0;
simon 1:fe7ccd3480e6 146 _spi.write(LIS302_WRITE | LIS302_CTRL_REG1);
simon 1:fe7ccd3480e6 147 _spi.write(value);
simon 1:fe7ccd3480e6 148 _ncs = 1;
simon 1:fe7ccd3480e6 149 }
simon 1:fe7ccd3480e6 150
simon 1:fe7ccd3480e6 151 void LIS302::calibrate(float maxx, float minx, float maxy, float miny, float maxz, float minz) {
simon 1:fe7ccd3480e6 152 _maxx = maxx;
simon 1:fe7ccd3480e6 153 _minx = minx;
simon 1:fe7ccd3480e6 154 _maxy = maxy;
simon 1:fe7ccd3480e6 155 _miny = miny;
simon 1:fe7ccd3480e6 156 _maxz = maxz;
simon 1:fe7ccd3480e6 157 _minz = minz;
simon 1:fe7ccd3480e6 158 }
simon 1:fe7ccd3480e6 159
simon 1:fe7ccd3480e6 160 int LIS302::whoami() {
simon 1:fe7ccd3480e6 161 _ncs = 0;
simon 1:fe7ccd3480e6 162 _spi.write(LIS302_READ | LIS302_WHOAMI);
simon 1:fe7ccd3480e6 163 int value = _spi.write(0x00);
simon 1:fe7ccd3480e6 164 _ncs = 1;
simon 1:fe7ccd3480e6 165 return value;
simon 1:fe7ccd3480e6 166 }
simon 1:fe7ccd3480e6 167
simon 1:fe7ccd3480e6 168 int LIS302::status() {
simon 1:fe7ccd3480e6 169 _ncs = 0;
simon 1:fe7ccd3480e6 170 _spi.write(0xA7);
simon 1:fe7ccd3480e6 171 int value = _spi.write(LIS302_READ | LIS302_STATUS_REG);
simon 1:fe7ccd3480e6 172 _ncs = 1;
simon 1:fe7ccd3480e6 173 return value;
simon 1:fe7ccd3480e6 174 }