-
Notifications
You must be signed in to change notification settings - Fork 0
/
LIS3LV02DL.c
164 lines (139 loc) · 4.77 KB
/
LIS3LV02DL.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
/**
* Written by Tim Johns.
*
* The function bodies in this file are specific to the LIS3LV02DL accelerometer.
*
* In the current circuit design, the accelerometer is using the USCI_B1 SPI
* bus, thus the functions spib_send() and spib_rec() are used.
*/
#ifndef _ACCELLIB_C
#define _ACCELLIB_C
#include <msp430f5310.h>
#include <stdint.h>
#include "spi.h"
#include "LIS3LV02DL.h"
/*----------------------------------------------------------------------------*/
/* Initialize accelerometer */
/*----------------------------------------------------------------------------*/
uint8_t init_accel(uint8_t range_accel, uint8_t bandwidth_accel) {
uint8_t tmp8;
/* Read WHO_AM_I (0x0F) (page 30)
Default value: 0x3A
*/
if (read_addr_accel(0x0F) != 0x3A) return 0;
/* Set CTRL_REG1 (20h) (page 31)
Normal mode
Data rate selection (default: 160 Hz)
All axes enabled
*/
tmp8 = (bandwidth_accel << 4) | 0xC7;
write_addr_accel(0x20, tmp8);
/* Set CTRL_REG2 (21h) (page 32) 0000 0100
Full scale (default: +/-2 g)
Block data update: continuous
Little endian
Interrupt enable: data ready signal
Data ready: enable
Data alignment selection: 16 bit left justified
*/
tmp8 = (range_accel << 7) | 0x05;
write_addr_accel(0x21, tmp8);
return 1;
}
/*----------------------------------------------------------------------------*/
/* Check if accelerometer is available */
/* Return 1 if accelerometer is not available, 0 if it is available. */
/*----------------------------------------------------------------------------*/
uint8_t accel_not_avail(void) {
if (read_addr_accel(0x0F) != 0x3A) {
return 1;
} else {
return 0;
}
}
/*----------------------------------------------------------------------------*/
/* Send command to put accelerometer into power down mode */
/*----------------------------------------------------------------------------*/
void power_down_accel(void) {
write_addr_accel(0x20, 0x00);
}
/*----------------------------------------------------------------------------*/
/* Read an address on accelerometer (send address, return response) */
/*----------------------------------------------------------------------------*/
uint8_t read_addr_accel(uint8_t address) {
uint8_t tmp;
CS_LOW_ACCEL(); // Chip select
spib_send(address | 0x80); // msb = 1 for read
tmp = spib_rec();
CS_HIGH_ACCEL(); // Chip deselect
return tmp;
}
/*----------------------------------------------------------------------------*/
/* Write to an address on accelerometer */
/*----------------------------------------------------------------------------*/
void write_addr_accel(uint8_t address, uint8_t d) {
CS_LOW_ACCEL(); // Chip select
spib_send(address & 0x7F); // msb = 0 for write
spib_send(d); // Send data
CS_HIGH_ACCEL(); // Chip deselect
}
/*----------------------------------------------------------------------------*/
/* Check accelerometer interrupt */
/* Return true iff LIS3LV02DL INT (P1.5) is high. */
/*----------------------------------------------------------------------------*/
uint8_t accel_int(void) {
return (P1IN & BIT5) != 0;
}
/*----------------------------------------------------------------------------*/
/* Return accelerometer range bits corresponding to range n */
/*----------------------------------------------------------------------------*/
uint8_t range_bits_accel(uint16_t n) {
if (n == 2) {
return 0; // 0: +/-2 g
} else if (n == 6) {
return 1; // 1: +/-6 g
} else {
return DEFAULT_RANGE_ACCEL;
}
}
/*----------------------------------------------------------------------------*/
/* Return accelerometer range in g corresponding to range bits */
/*----------------------------------------------------------------------------*/
uint8_t range_bits_to_g_accel(uint8_t n) {
if (n == 0) {
return 2;
} else {
return 6;
}
}
/*----------------------------------------------------------------------------*/
/* Return accelerometer bandwidth bits corresponding to bandwidth n */
/*----------------------------------------------------------------------------*/
uint8_t bandwidth_bits_accel(uint16_t n) {
if (n == 40) {
return 0; // 00: 40 Hz
} else if (n == 160) {
return 1; // 01: 160 Hz
} else if (n == 640) {
return 2; // 10: 640 Hz
} else if (n == 2560) {
return 3; // 11: 2560 Hz
} else {
return DEFAULT_BANDWIDTH_ACCEL;
}
}
/*----------------------------------------------------------------------------*/
/* Return accelerometer bandwidth in hz corresponding to bandwidth bits */
/*----------------------------------------------------------------------------*/
uint16_t bandwidth_bits_to_hz_accel(uint8_t n) {
if (n == 0) {
return 40;
} else if (n == 1) {
return 160;
} else if (n == 2) {
return 640;
} else if (n == 3) {
return 2560;
}
}
#endif