summaryrefslogtreecommitdiff
path: root/ports/stm32/boards/STM32F4DISC/staccel.py
diff options
context:
space:
mode:
Diffstat (limited to 'ports/stm32/boards/STM32F4DISC/staccel.py')
-rw-r--r--ports/stm32/boards/STM32F4DISC/staccel.py98
1 files changed, 98 insertions, 0 deletions
diff --git a/ports/stm32/boards/STM32F4DISC/staccel.py b/ports/stm32/boards/STM32F4DISC/staccel.py
new file mode 100644
index 000000000..2f2561d1c
--- /dev/null
+++ b/ports/stm32/boards/STM32F4DISC/staccel.py
@@ -0,0 +1,98 @@
+"""
+Driver for accelerometer on STM32F4 Discover board.
+
+Sets accelerometer range at +-2g.
+Returns list containing X,Y,Z axis acceleration values in 'g' units (9.8m/s^2).
+
+See:
+ STM32Cube_FW_F4_V1.1.0/Drivers/BSP/Components/lis302dl/lis302dl.h
+ STM32Cube_FW_F4_V1.1.0/Drivers/BSP/Components/lis302dl/lis302dl.c
+ STM32Cube_FW_F4_V1.1.0/Drivers/BSP/STM32F4-Discovery/stm32f4_discovery.c
+ STM32Cube_FW_F4_V1.1.0/Drivers/BSP/STM32F4-Discovery/stm32f4_discovery.h
+ STM32Cube_FW_F4_V1.1.0/Drivers/BSP/STM32F4-Discovery/stm32f4_discovery_accelerometer.c
+ STM32Cube_FW_F4_V1.1.0/Drivers/BSP/STM32F4-Discovery/stm32f4_discovery_accelerometer.h
+ STM32Cube_FW_F4_V1.1.0/Projects/STM32F4-Discovery/Demonstrations/Src/main.c
+"""
+
+from micropython import const
+from pyb import Pin
+from pyb import SPI
+
+READWRITE_CMD = const(0x80)
+MULTIPLEBYTE_CMD = const(0x40)
+WHO_AM_I_ADDR = const(0x0f)
+OUT_X_ADDR = const(0x29)
+OUT_Y_ADDR = const(0x2b)
+OUT_Z_ADDR = const(0x2d)
+OUT_T_ADDR = const(0x0c)
+
+LIS302DL_WHO_AM_I_VAL = const(0x3b)
+LIS302DL_CTRL_REG1_ADDR = const(0x20)
+# Configuration for 100Hz sampling rate, +-2g range
+LIS302DL_CONF = const(0b01000111)
+
+LIS3DSH_WHO_AM_I_VAL = const(0x3f)
+LIS3DSH_CTRL_REG4_ADDR = const(0x20)
+LIS3DSH_CTRL_REG5_ADDR = const(0x24)
+# Configuration for 100Hz sampling rate, +-2g range
+LIS3DSH_CTRL_REG4_CONF = const(0b01100111)
+LIS3DSH_CTRL_REG5_CONF = const(0b00000000)
+
+class STAccel:
+ def __init__(self):
+ self.cs_pin = Pin('PE3', Pin.OUT_PP, Pin.PULL_NONE)
+ self.cs_pin.high()
+ self.spi = SPI(1, SPI.MASTER, baudrate=328125, polarity=0, phase=1, bits=8)
+
+ self.who_am_i = self.read_id()
+
+ if self.who_am_i == LIS302DL_WHO_AM_I_VAL:
+ self.write_bytes(LIS302DL_CTRL_REG1_ADDR, bytearray([LIS302DL_CONF]))
+ self.sensitivity = 18
+ elif self.who_am_i == LIS3DSH_WHO_AM_I_VAL:
+ self.write_bytes(LIS3DSH_CTRL_REG4_ADDR, bytearray([LIS3DSH_CTRL_REG4_CONF]))
+ self.write_bytes(LIS3DSH_CTRL_REG5_ADDR, bytearray([LIS3DSH_CTRL_REG5_CONF]))
+ self.sensitivity = 0.06 * 256
+ else:
+ raise Exception('LIS302DL or LIS3DSH accelerometer not present')
+
+ def convert_raw_to_g(self, x):
+ if x & 0x80:
+ x = x - 256
+ return x * self.sensitivity / 1000
+
+ def read_bytes(self, addr, nbytes):
+ if nbytes > 1:
+ addr |= READWRITE_CMD | MULTIPLEBYTE_CMD
+ else:
+ addr |= READWRITE_CMD
+ self.cs_pin.low()
+ self.spi.send(addr)
+ #buf = self.spi.send_recv(bytearray(nbytes * [0])) # read data, MSB first
+ buf = self.spi.recv(nbytes)
+ self.cs_pin.high()
+ return buf
+
+ def write_bytes(self, addr, buf):
+ if len(buf) > 1:
+ addr |= MULTIPLEBYTE_CMD
+ self.cs_pin.low()
+ self.spi.send(addr)
+ for b in buf:
+ self.spi.send(b)
+ self.cs_pin.high()
+
+ def read_id(self):
+ return self.read_bytes(WHO_AM_I_ADDR, 1)[0]
+
+ def x(self):
+ return self.convert_raw_to_g(self.read_bytes(OUT_X_ADDR, 1)[0])
+
+ def y(self):
+ return self.convert_raw_to_g(self.read_bytes(OUT_Y_ADDR, 1)[0])
+
+ def z(self):
+ return self.convert_raw_to_g(self.read_bytes(OUT_Z_ADDR, 1)[0])
+
+ def xyz(self):
+ return (self.x(), self.y(), self.z())