Skip to content

Commit 42060d2

Browse files
author
betzrhodes
committed
Merge pull request #11 from dbns97/patch-1
Added FIFO buffer support
2 parents 802aae3 + 26dc43f commit 42060d2

File tree

2 files changed

+116
-3
lines changed

2 files changed

+116
-3
lines changed

LIS3DH.class.nut

+39-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
class LIS3DH {
2-
static version = [1,2,0];
2+
static version = [1,3,0];
33

44
// Registers
55
static TEMP_CFG_REG = 0x1F;
@@ -15,6 +15,8 @@ class LIS3DH {
1515
static OUT_Y_H = 0x2B;
1616
static OUT_Z_L = 0x2C;
1717
static OUT_Z_H = 0x2D;
18+
static FIFO_CTRL_REG = 0x2E;
19+
static FIFO_SRC_REG = 0x2F;
1820
static INT1_CFG = 0x30;
1921
static INT1_SRC = 0x31;
2022
static INT1_THS = 0x32;
@@ -53,6 +55,11 @@ class LIS3DH {
5355
static HPF_REFERENCE_SIGNAL = 0x40;
5456
static HPF_NORMAL_MODE = 0x80;
5557
static HPF_AUTORESET_ON_INTERRUPT = 0xC0;
58+
59+
static FIFO_BYPASS_MODE = 0x00;
60+
static FIFO_FIFO_MODE = 0x40;
61+
static FIFO_STREAM_MODE = 0x80;
62+
static FIFO_STREAM_TO_FIFO_MODE = 0xC0;
5663

5764
// Click Detection values
5865
static SINGLE_CLICK = 0x15;
@@ -94,6 +101,7 @@ class LIS3DH {
94101
_setReg(TIME_LIMIT, 0x00);
95102
_setReg(TIME_LATENCY, 0x00);
96103
_setReg(TIME_WINDOW, 0x00);
104+
_setReg(FIFO_CTRL_REG, 0x00);
97105

98106
// Read the range + set _range property
99107
getRange();
@@ -254,6 +262,24 @@ class LIS3DH {
254262

255263
//-------------------- INTERRUPTS --------------------//
256264

265+
// Enable/disable and configure FIFO buffer watermark interrupts
266+
function configureFifoInterrupt(state, fifomode = 0x80, watermark = 28) {
267+
268+
// Enable/disable the FIFO buffer
269+
_setRegBit(CTRL_REG5, 6, state ? 1 : 0);
270+
271+
if (state) {
272+
// Stream-to-FIFO mode, watermark of [28].
273+
_setReg(FIFO_CTRL_REG, (fifomode & 0xc0) | (watermark & 0x1F));
274+
} else {
275+
_setReg(FIFO_CTRL_REG, 0x00);
276+
}
277+
278+
// Enable/disable watermark interrupt
279+
_setRegBit(CTRL_REG3, 2, state ? 1 : 0);
280+
281+
}
282+
257283
// Enable/disable and configure inertial interrupts
258284
function configureInertialInterrupt(state, threshold = 2.0, duration = 5, options = null) {
259285
// Set default value for options (using statics, so can't set in ftcn declaration)
@@ -345,6 +371,16 @@ class LIS3DH {
345371
"doubleClick": (click & 0x20) != 0
346372
}
347373
}
374+
375+
function getFifoStats() {
376+
local stats = _getReg(FIFO_SRC_REG);
377+
return {
378+
"watermark": (stats & 0x80) != 0,
379+
"overrun": (stats & 0x40) != 0,
380+
"empty": (stats & 0x20) != 0,
381+
"unread": (stats & 0x1F) + ((stats & 0x40) ? 1 : 0)
382+
}
383+
}
348384

349385

350386
//-------------------- PRIVATE METHODS --------------------//
@@ -390,5 +426,7 @@ class LIS3DH {
390426
server.log(format("INT1_CFG 0x%02X", _getReg(INT1_CFG)));
391427
server.log(format("INT1_SRC 0x%02X", _getReg(INT1_SRC)));
392428
server.log(format("INT1_THS 0x%02X", _getReg(INT1_THS)));
429+
server.log(format("FIFO_CTRL_REG 0x%02X", _getReg(FIFO_CTRL_REG)));
430+
server.log(format("FIFO_SRC_REG 0x%02X", _getReg(FIFO_SRC_REG)));
393431
}
394432
}

README.md

+77-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ The [LIS3DH](http://www.st.com/st-web-ui/static/active/en/resource/technical/doc
44

55
The LPS25H can interface over I²C or SPI. This class addresses only I²C for the time being.
66

7-
**To add this library to your project, add** `#require "LIS3DH.class.nut:1.2.0"` **to the top of your device code**
7+
**To add this library to your project, add** `#require "LIS3DH.class.nut:1.3.0"` **to the top of your device code**
88

99
## Class Usage
1010

@@ -20,7 +20,7 @@ The class’ constructor takes one required parameter (a configured imp I²C
2020
&nbsp;<br>
2121

2222
```squirrel
23-
#require "LIS3DH.class.nut:1.2.0"
23+
#require "LIS3DH.class.nut:1.3.0"
2424
2525
i2c <- hardware.i2c89;
2626
i2c.configure(CLOCK_SPEED_400_KHZ);
@@ -127,6 +127,70 @@ The *getRange()* method returns the currently-set measurement range of the senso
127127
server.log(format("Current Sensor Range is +/- %dG", accel.getRange()));
128128
```
129129

130+
### configureFifoInterrupt(*state[, fifomode][, watermark]*)
131+
132+
This method configures an interrupt when the FIFO buffer reaches the set watermark:
133+
134+
| Parameter | Type | Default Value | Description |
135+
| --------- | ---- | ------------- | ----------- |
136+
| *state* | Boolean | N/A | `true` to enable, `false` to disable |
137+
| *fifomode* | bitfield | *FIFO_STREAM_MODE* | See table below |
138+
| *watermark* | Integer | 28 | Number of buffer slots filled to generate<br> interrupt (buffer has 32 slots) |
139+
140+
This example sets the FIFO buffer to Stream Mode and reads the data from
141+
the buffer whenever the watermark is reached:
142+
143+
```squirrel
144+
// Function to read from FIFO buffer
145+
function readBuffer() {
146+
147+
if (wakePin.read() == 0) return;
148+
149+
// Read buffer
150+
local stats = accel.getFifoStats();
151+
for (local i = 0; i < stats.unread; ++i) {
152+
local data = accel.getAccel();
153+
server.log(format("Accel (x,y,z): [%d, %d, %d]", data.x, data.y, data.z));
154+
}
155+
156+
// Check if we are now overrun
157+
local stats = accel.getFifoStats();
158+
if (stats.overrun) {
159+
server.error("Accelerometer buffer overrun")
160+
161+
// Set FIFO mode to bypass to clear the buffer and then return to stream mode
162+
accel.configureFifoInterrupt(true, accel.FIFO_BYPASS_MODE);
163+
accel.configureFifoInterrupt(true, accel.FIFO_STREAM_MODE, 30);
164+
}
165+
166+
}
167+
168+
i2c <- hardware.i2cAB;
169+
i2c.configure(CLOCK_SPEED_400_KHZ);
170+
accel <- LIS3DH(i2c);
171+
172+
// Configure interrupt pin
173+
wakePin <- hardware.pinW;
174+
wakePin.configure(DIGITAL_IN_PULLDOWN, readBuffer);
175+
176+
// Configure accelerometer
177+
accel.init();
178+
accel.setDataRate(100);
179+
180+
// Configure the FIFO buffer in Stream Mode and set interrupt generator to
181+
// generate an interrupt when there are 30 entries in the buffer
182+
accel.configureFifoInterrupt(true, accel.FIFO_STREAM_MODE, 30);
183+
```
184+
185+
#### FIFO modes
186+
187+
| Mode | Description |
188+
| ---- | ----------- |
189+
| *FIFO_BYPASS_MODE* | Disables the FIFO buffer (only the first address is used for each channel) |
190+
| *FIFO_FIFO_MODE* | When full, the FIFO buffer stops collecting data from the input channels |
191+
| *FIFO_STREAM_MODE* | When full, the FIFO buffer discards the older data as the new arrive |
192+
| *FIFO_STREAM_TO_FIFO_MODE* | When full, the FIFO buffer discards the older data as the new arrive.<br> Once trigger event occurs, the FIFO buffer starts operating in FIFO mode. |
193+
130194
### configureInertialInterrupt(*state[, threshold][, duration][, options]*)
131195

132196
This method configures the inertial interrupt generator:
@@ -353,6 +417,17 @@ switch(hardware.wakereason()) {
353417
}
354418
```
355419

420+
### getFifoStats()
421+
422+
This method returns information about the state of the FIFO buffer in a squirrel table:
423+
424+
| Value | Type | Description |
425+
| --- | --- | --- | --- |
426+
| *watermark* | Boolean | `true` if watermark has been set |
427+
| *overrun* | Boolean | `true` if data has been overwritten without being read |
428+
| *empty* | Boolean | `true` if buffer is empty |
429+
| *unread* | Integer | Number of unread slots in buffer |
430+
356431
### configureHighPassFilter(*filters[, cutoff][, mode]*)
357432

358433
This method configures the high-pass filter.

0 commit comments

Comments
 (0)